Use this skill when the task needs ext/html/, ext/js/, x-extension, x-component, x-context, or layered override behavior.
HTML Extension Rules
- Declare structural seams with
<x-extension id="some/path">.
- Matching HTML files live at
mod/<author>/<repo>/ext/html/some/path/*.html.
- HTML callers name only the seam; the runtime resolves
ext/html/ automatically.
- Keep extension files thin. They should usually mount a real component with
<x-component path="/mod/...">.
_core/framework also creates _core/framework/head/end in document.head during bootstrap when a layer needs head-side HTML or inline bootstrap code without editing page shells.
- Use framework
x-inject="selector" instead of raw Alpine x-teleport when route-owned markup targets a shell seam that may mount later; it mirrors teleport semantics for <template> roots, waits for the selector, and disconnects its observer when the source template unmounts.
- Dynamic discovery watches the whole document tree, so
head seams and the x-component nodes they insert are loaded the same way as body content.
- The routed shell header owns Home itself and points it at the empty route
#/; _core/onscreen_menu/bar_start and _core/onscreen_menu/bar_end are the left and right shell-control seams, and feature modules add non-Home dropdown menu-action buttons under _core/onscreen_menu/items with numeric data-order values such as 100, 200, 300, and 400; _core/onscreen_menu sorts contributed controls or items automatically and keeps only the auth exit action after the dropdown seam.
Example:
<x-extension id="page/router/overlay/end"></x-extension>
<x-component path="/mod/_core/onscreen_agent/panel.html"></x-component>
JS Hook Rules
- Use
space.extend(import.meta, async function name(...) { ... }) for behavioral seams.
- JS hook files live at
mod/<author>/<repo>/ext/js/<extension-point>/*.js or *.mjs.
- The runtime resolves
/start and /end hooks around the wrapped function automatically.
space.extend() requires a valid module ref and a standalone named function or explicit extension point name.
- Framework-backed pages expose
_core/framework/initializer.js/initialize; use _core/framework/head/end when the work can stay declarative, and keep the initializer /end hook for once-per-page shell setup that must stay imperative.
- If a feature needs onscreen-agent-specific prompt shaping or execution validation for its own helpers, add an
ext/js/_core/onscreen_agent/... hook from that feature instead of editing _core/onscreen_agent directly.
Extension Metadata Rules
- Modules may also store lightweight metadata assets under other
ext/ folders when those files should follow the same readable-layer permissions and same-path override rules as HTML and JS extensions.
- The current first-party example is
ext/panels/*.yaml, which the dashboard panel index discovers through file_paths, batch-reads through fileRead(...), and collapses to one effective manifest per modulePath + manifestName.
- Keep those metadata files display-oriented. They are extension-resolved module assets, not general writable storage.
Component Loader Rules
<x-component> may load a full HTML document or a fragment.
- The loader mounts styles, module scripts, and body nodes, then recursively resolves nested
<x-component> tags.
- Concurrent scans of the same
<x-component> target reuse the in-flight load; they must not bail out in a way that leaves late-mounted components partially hydrated.
- Mutation-driven
x-component discovery watches document.documentElement, not only body, so head-side components hydrate too.
- Keep component HTML declarative and bind behavior through stores.
- Import the owning store module in the component that owns the feature, not in an unrelated parent shell.
Context Helper Rules
- Framework bootstrap also injects one hidden runtime
<x-context> with data-runtime="browser" on normal web sessions or data-runtime="app" in the packaged desktop runtime; packaged app routes derive that from the desktop bridge before falling back to launcher runtime info or frontend config, and that same element also exposes runtime-browser or runtime-app through data-tags.
- Modules may export additional live skill-filter tags with hidden
<x-context> elements anywhere in mounted DOM.
- Set one or more tags with
data-tags="a, b, c".
- Alpine-bound attributes on
<x-context> are the normal way to keep tags synced with route or store state.
- Import
/mod/_core/framework/js/context.js when code needs to inspect current <x-context> elements directly; the stable helpers are getContexts(...), getAttributeValues(...), getTags(...), and getContents(...).
- Shared skill discovery reads those tags through that framework helper each time it builds the catalog, auto-loaded skill context, or an explicit skill load.
Layered Override Behavior
- Module and extension resolution follow the readable
L0 -> L1 -> L2 inheritance chain.
- Identical module-relative extension file paths override lower-ranked entries.
- Different filenames under the same extension point compose together.
- Prefer additive composition before exact-path replacement.
maxLayer constrains module and extension resolution but not logical app-file paths.
- Uncached HTML
<x-extension> lookups batch before they call /api/extensions_load; the default flush is the next animation frame, and frontend constant HTML_EXTENSIONS_LOAD_BATCH_WAIT_MS in app/L0/_all/mod/_core/framework/js/extensions.js adds an extra wait window in milliseconds before that frame-aligned flush.
extensions_load keeps maxLayer at the call level; grouped lookups send ordered patterns arrays and receive ordered results with matching patterns plus resolved extensions.
- JS hook lookups do not use that wait window; they resolve immediately because hook callers await them directly.
Practical Guidance
- Add a new seam in the owner when downstream customization is realistic.
- Do not bypass an existing seam by reaching into another module's private DOM or internals.
- After adding a new
ext/html/... or ext/js/... file, the running page often needs a refresh before discovery catches up.
Mandatory Doc Follow-Up
- If extension lookup, component loading, hook behavior, or override semantics change, update the framework docs and the
development skill subtree in the same session.
1---2name: extensions-and-components3description: Use HTML adapters, JS hook seams, and component loading correctly in the layered module system.4---56Use this skill when the task needs `ext/html/`, `ext/js/`, `x-extension`, `x-component`, `x-context`, or layered override behavior.78## HTML Extension Rules910- Declare structural seams with `<x-extension id="some/path">`.11- Matching HTML files live at `mod/<author>/<repo>/ext/html/some/path/*.html`.12- HTML callers name only the seam; the runtime resolves `ext/html/` automatically.13- Keep extension files thin. They should usually mount a real component with `<x-component path="/mod/...">`.14- `_core/framework` also creates `_core/framework/head/end` in `document.head` during bootstrap when a layer needs head-side HTML or inline bootstrap code without editing page shells.15- Use framework `x-inject="selector"` instead of raw Alpine `x-teleport` when route-owned markup targets a shell seam that may mount later; it mirrors teleport semantics for `<template>` roots, waits for the selector, and disconnects its observer when the source template unmounts.16- Dynamic discovery watches the whole document tree, so `head` seams and the `x-component` nodes they insert are loaded the same way as body content.17- The routed shell header owns Home itself and points it at the empty route `#/`; `_core/onscreen_menu/bar_start` and `_core/onscreen_menu/bar_end` are the left and right shell-control seams, and feature modules add non-Home dropdown menu-action buttons under `_core/onscreen_menu/items` with numeric `data-order` values such as `100`, `200`, `300`, and `400`; `_core/onscreen_menu` sorts contributed controls or items automatically and keeps only the auth exit action after the dropdown seam.1819Example:2021```html22<x-extension id="page/router/overlay/end"></x-extension>23```2425```html26<x-component path="/mod/_core/onscreen_agent/panel.html"></x-component>27```2829## JS Hook Rules3031- Use `space.extend(import.meta, async function name(...) { ... })` for behavioral seams.32- JS hook files live at `mod/<author>/<repo>/ext/js/<extension-point>/*.js` or `*.mjs`.33- The runtime resolves `/start` and `/end` hooks around the wrapped function automatically.34- `space.extend()` requires a valid module ref and a standalone named function or explicit extension point name.35- Framework-backed pages expose `_core/framework/initializer.js/initialize`; use `_core/framework/head/end` when the work can stay declarative, and keep the initializer `/end` hook for once-per-page shell setup that must stay imperative.36- If a feature needs onscreen-agent-specific prompt shaping or execution validation for its own helpers, add an `ext/js/_core/onscreen_agent/...` hook from that feature instead of editing `_core/onscreen_agent` directly.3738## Extension Metadata Rules3940- Modules may also store lightweight metadata assets under other `ext/` folders when those files should follow the same readable-layer permissions and same-path override rules as HTML and JS extensions.41- The current first-party example is `ext/panels/*.yaml`, which the dashboard panel index discovers through `file_paths`, batch-reads through `fileRead(...)`, and collapses to one effective manifest per `modulePath + manifestName`.42- Keep those metadata files display-oriented. They are extension-resolved module assets, not general writable storage.4344## Component Loader Rules4546- `<x-component>` may load a full HTML document or a fragment.47- The loader mounts styles, module scripts, and body nodes, then recursively resolves nested `<x-component>` tags.48- Concurrent scans of the same `<x-component>` target reuse the in-flight load; they must not bail out in a way that leaves late-mounted components partially hydrated.49- Mutation-driven `x-component` discovery watches `document.documentElement`, not only `body`, so head-side components hydrate too.50- Keep component HTML declarative and bind behavior through stores.51- Import the owning store module in the component that owns the feature, not in an unrelated parent shell.5253## Context Helper Rules5455- Framework bootstrap also injects one hidden runtime `<x-context>` with `data-runtime="browser"` on normal web sessions or `data-runtime="app"` in the packaged desktop runtime; packaged app routes derive that from the desktop bridge before falling back to launcher runtime info or frontend config, and that same element also exposes `runtime-browser` or `runtime-app` through `data-tags`.56- Modules may export additional live skill-filter tags with hidden `<x-context>` elements anywhere in mounted DOM.57- Set one or more tags with `data-tags="a, b, c"`.58- Alpine-bound attributes on `<x-context>` are the normal way to keep tags synced with route or store state.59- Import `/mod/_core/framework/js/context.js` when code needs to inspect current `<x-context>` elements directly; the stable helpers are `getContexts(...)`, `getAttributeValues(...)`, `getTags(...)`, and `getContents(...)`.60- Shared skill discovery reads those tags through that framework helper each time it builds the catalog, auto-loaded skill context, or an explicit skill load.6162## Layered Override Behavior6364- Module and extension resolution follow the readable `L0 -> L1 -> L2` inheritance chain.65- Identical module-relative extension file paths override lower-ranked entries.66- Different filenames under the same extension point compose together.67- Prefer additive composition before exact-path replacement.68- `maxLayer` constrains module and extension resolution but not logical app-file paths.69- Uncached HTML `<x-extension>` lookups batch before they call `/api/extensions_load`; the default flush is the next animation frame, and frontend constant `HTML_EXTENSIONS_LOAD_BATCH_WAIT_MS` in `app/L0/_all/mod/_core/framework/js/extensions.js` adds an extra wait window in milliseconds before that frame-aligned flush.70- `extensions_load` keeps `maxLayer` at the call level; grouped lookups send ordered `patterns` arrays and receive ordered results with matching `patterns` plus resolved `extensions`.71- JS hook lookups do not use that wait window; they resolve immediately because hook callers await them directly.7273## Practical Guidance7475- Add a new seam in the owner when downstream customization is realistic.76- Do not bypass an existing seam by reaching into another module's private DOM or internals.77- After adding a new `ext/html/...` or `ext/js/...` file, the running page often needs a refresh before discovery catches up.7879## Mandatory Doc Follow-Up8081- If extension lookup, component loading, hook behavior, or override semantics change, update the framework docs and the `development` skill subtree in the same session.