skills/.system/jwebmp-client/SKILL.md
Client SPI library for JWebMP — defines AJAX pipeline contracts (AjaxCall/AjaxResponse), page contracts (IPage/IPageConfigurator), component model interfaces, and interceptor SPIs. Use when working with JWebMP client interfaces, AJAX interception, page configuration SPIs, component model interfaces, or extending JWebMP with custom interceptors and configurators.
npx skillsauth add guicedee/ai-rules jwebmp-clientInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Client SPI library defining contracts, AJAX pipeline, and component model interfaces for JWebMP.
Provides compile-time contracts and runtime SPI discovery for JWebMP ecosystem without circular dependencies. All JWebMP modules program against these interfaces.
Core DTO objects for browser ↔ server communication:
// AjaxCall - Incoming request (CallScope-scoped)
public class AjaxCall<J extends AjaxCall<J>> {
Map<String, String> getParameters();
String getEventType();
String getComponentId();
HeadersDTO getHeaders();
}
// AjaxResponse - Outgoing response
public class AjaxResponse<J extends AjaxResponse<J>> {
J addComponent(IComponentHierarchyBase<?, ?> component);
J addReaction(AjaxResponseReaction<?> reaction);
Map<String, Object> getDataReturns();
}
// DOM update descriptor
public class AjaxComponentUpdates {
AjaxComponentInsertType insertType; // replace, append, prepend, etc.
String htmlContent;
String componentId;
}
// Client-side reaction
public class AjaxResponseReaction<J> {
ReactionType reactionType; // redirect, dialog, etc.
Object value;
}
// 1. Site-level (first page load)
public interface SiteCallIntercepter<J extends SiteCallIntercepter<J>>
extends IDefaultService<J> {
void intercept(AjaxCall<?> call, AjaxResponse<?> response);
}
// 2. AJAX event calls
public interface AjaxCallIntercepter<J extends AjaxCallIntercepter<J>>
extends SiteCallIntercepter<J> {
// Same intercept() method
}
// 3. Startup data calls
public interface DataCallIntercepter<J extends DataCallIntercepter<J>>
extends SiteCallIntercepter<J> {
// Same intercept() method
}
public class AuditInterceptor implements AjaxCallIntercepter<AuditInterceptor> {
@Override
public void intercept(AjaxCall<?> call, AjaxResponse<?> response) {
log.info("AJAX event: {}", call.getEventType());
}
@Override
public Integer sortOrder() {
return 10; // Lower = earlier
}
}
Register via module-info.java:
provides com.jwebmp.interception.services.AjaxCallIntercepter
with my.app.AuditInterceptor;
public interface IPage<J extends IPage<J>> {
IBody<?> getBody();
IHead<?> getHead();
PageOptions getOptions();
J addJavaScriptReference(JavascriptReference ref);
J addCssReference(CSSReference ref);
}
public interface IPageConfigurator<J extends IPageConfigurator<J>>
extends IDefaultService<J>, IServiceEnablement<J> {
IPage<?> configure(IPage<?> page);
Integer sortOrder(); // Determines execution order
}
public class AnalyticsConfigurator implements IPageConfigurator<AnalyticsConfigurator> {
@Override
public IPage<?> configure(IPage<?> page) {
page.addJavaScriptReference(
new JavascriptReference("analytics", 1.0, "analytics.js")
);
return page;
}
@Override
public Integer sortOrder() {
return 100;
}
}
11-layer interface hierarchy (CRTP):
IComponentBase // ID, name, properties, JSON serialization
└─ IComponentHierarchyBase // parent/child tree, CSS/JS references
└─ IComponentHTMLBase // tag rendering, text, raw HTML
└─ IComponentHTMLAttributeBase // HTML attributes (typed enums)
└─ IComponentHTMLOptionsBase // JavaScript options (JavaScriptPart)
└─ IComponentStyleBase // inline CSS via CSS builder
└─ IComponentThemeBase // theme support
└─ IComponentDataBindingBase // data-bind hooks
└─ IComponentDependencyBase // CSS/JS dependency refs
└─ IComponentFeatureBase // Feature attachment
└─ IComponentEventBase // Event attachment
| SPI | When It Fires |
|---|---|
| IOnDataBind | Component's data-bind is processed |
| IOnDataBindCloak | Cloaked data-bind components |
| IOnComponentAdded | Child added to component |
| IOnComponentConfigured | After component configuration |
| IOnComponentHtmlRender | During component HTML rendering |
| IAfterRenderComplete | After full render completes |
| IClientVariableWatcher | Client-side variable changes |
| SPI | Purpose |
|---|---|
| RenderBeforeLinks | Before CSS <link> tags |
| RenderAfterLinks | After CSS <link> tags |
| RenderBeforeScripts | Before <script> tags |
| RenderAfterScripts | After <script> tags |
| RenderBeforeDynamicScripts | Before dynamic/inline scripts |
| RenderAfterDynamicScripts | After dynamic/inline scripts |
public class ComponentLogger implements IOnComponentAdded<ComponentLogger> {
@Override
public void onComponentAdded(IComponentHierarchyBase<?, ?> parent,
IComponentHierarchyBase<?, ?> added) {
log.info("Added {} to {}", added.getID(), parent.getID());
}
}
All component options extend JavaScriptPart for JSON serialization:
public class MyComponentOptions extends JavaScriptPart<MyComponentOptions> {
private String color;
private Integer size;
public MyComponentOptions setColor(String color) {
this.color = color;
return this;
}
public MyComponentOptions setSize(Integer size) {
this.size = size;
return this;
}
}
Automatic Jackson serialization to JSON.
public class CSSReference extends WebReference<CSSReference> {
public CSSReference(String name, Double version, String url) {
super(name, version, url);
}
}
public class JavascriptReference extends WebReference<JavascriptReference> {
public JavascriptReference(String name, Double version, String url) {
super(name, version, url);
}
}
@ComponentInformation(
name = "My Component",
description = "Component description",
url = "https://example.com"
)
public class MyComponent { }
@PluginInformation(
pluginName = "My Plugin",
pluginUniqueName = "my-plugin",
pluginVersion = "1.0.0"
)
public class MyPlugin { }
@FeatureInformation(
name = "My Feature",
description = "Feature description"
)
public class MyFeature { }
@PageConfiguration(url = "/dashboard")
public class DashboardPage extends Page<DashboardPage> { }
Type-safe parent/child relationships:
| Interface | Purpose |
|---|---|
| GlobalChildren | Elements accepting any flow/phrasing content |
| GlobalFeatures | Global HTML features |
| HTMLFeatures | HTML-specific features |
| FormChildren | Elements valid inside <form> |
| NoClosingTag | Void elements (<br>, <img>) |
| NoIDTag | Elements without id attribute |
| NoClassAttribute | Elements without class attribute |
InvalidRequestException // Malformed AJAX request
MissingComponentException // Component not found in tree
NullComponentException // Null component where required
NoServletFoundException // No handler for request path
UserSecurityException // Security violation
Browsers // Enum of known browsers
BrowserGroups // Grouping by engine/vendor
CSSVersions // CSS specification levels
HTMLVersions // HTML specification levels
HttpMethodTypes // HTTP methods (GET, POST, etc.)
JWebMPClientConfiguration enables:
| Setting | Value | Purpose |
|---|---|---|
| classpathScanning | true | Scan for SPI implementations |
| annotationScanning | true | Enable annotation discovery |
| fieldInfo | true | Collect field metadata |
| methodInfo | true | Collect method metadata |
| allowPaths | true | Path-based scanning |
module com.jwebmp.client {
requires transitive com.guicedee.client;
requires transitive com.guicedee.jsonrepresentation;
requires net.sf.uadetector.core;
exports com.jwebmp.core.base.ajax;
exports com.jwebmp.core.base.interfaces;
exports com.jwebmp.core.services;
exports com.jwebmp.interception.services;
provides IGuiceModule with JWebMPClientBinder;
provides IGuiceConfigurator with JWebMPClientConfiguration;
uses AjaxCallIntercepter;
uses DataCallIntercepter;
uses SiteCallIntercepter;
}
AjaxCall — Incoming AJAX request payload (CallScope-scoped)AjaxResponse — Outgoing AJAX response with updates/reactionsJavaScriptPart — Base for all JSON-serializable optionsJWebMPClientBinder — Guice module binding interceptors and AJAX pipelineHeadersDTO — Typed HTTP header wrapper// Security interceptor (runs first)
public class SecurityInterceptor implements SiteCallIntercepter<SecurityInterceptor> {
@Override
public void intercept(AjaxCall<?> call, AjaxResponse<?> response) {
if (!authenticated(call)) {
throw new UserSecurityException("Unauthorized");
}
}
@Override
public Integer sortOrder() {
return 1; // Run early
}
}
// Logging interceptor (runs later)
public class LoggingInterceptor implements AjaxCallIntercepter<LoggingInterceptor> {
@Override
public void intercept(AjaxCall<?> call, AjaxResponse<?> response) {
log.info("Processing event: {}", call.getEventType());
}
@Override
public Integer sortOrder() {
return 100;
}
}
public class InlineScript implements ScriptProvider {
@Override
public IComponentHierarchyBase<?, ?> produceScript() {
Script<?> script = new Script<>();
script.setText("console.log('Dynamic script loaded');");
return script;
}
}
<dependency>
<groupId>com.jwebmp</groupId>
<artifactId>jwebmp-client</artifactId>
</dependency>
com.jwebmp.clientdevelopment
Install Codex skills into $CODEX_HOME/skills from a curated list or a GitHub repo path. Use when a user asks to list installable skills, install a curated skill, or install a skill from another repo (including private repos).
tools
Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Codex's capabilities with specialized knowledge, workflows, or tool integrations.
development
WebAwesome icon integration for JWebMP — modern, open-source icon library. Provides 1,500+ icons with solid/regular styles, sizing, rotation, animation, and CSS utilities. Drop-in FontAwesome alternative with fresh designs. Use when working with WebAwesome icons, modern icon designs, or as FontAwesome alternative in JWebMP applications.
development
WebAwesome Pro integration for JWebMP with premium icons and features. Extends jwebmp-webawesome with additional styles, premium icons, and advanced features. Use when working with WebAwesome Pro icons or premium WebAwesome features in JWebMP applications.