Single File Component (.aihu) compiler — Rust binary + JS glue.
_buildDeferredHydrationfunction _buildDeferredHydration(compiledCode: string, elementTag: string): string;Rewrite an interactive-island module so its `connectedCallback` waits for the element to scroll into view before mounting.
_buildStaticIslandfunction _buildStaticIsland(compiledCode: string, elementTag: string): string;Build a static-island shim for a compiled module.
_clearTransformMemofunction _clearTransformMemo(): void;Test/diagnostic hook — wipe the memo and its counters.
_compileViaBackendfunction _compileViaBackend(source: string, legacyArgs: string[], options: CompileEnvelopeOptions): EnvelopeReply;Run one compile through the active backend.
_deriveChildTagsfunction _deriveChildTags(compiledCode: string): string[];Derive the `__aihu_child_tags__` set from SERVER-TARGET compiled code: the tags the compiled string renderer will actually look up, read off the `__aihu_schild('<tag>'` call sites the Rust codegen emitted.
_errMessagefunction _errMessage(err: unknown): string;Best-effort message text for an unknown thrown value.
_foldCssEngineStylesfunction _foldCssEngineStyles(compiledCode: string, css: string): string;_foldCssEngineStylesGlobalfunction _foldCssEngineStylesGlobal(compiledCode: string, css: string, id: string): { code: string; virtualId: string; } | null;Bug 6 — `shadowMode === 'light'` branch.
_foldSsrCssExportfunction _foldSsrCssExport(compiledCode: string, css: string): string;Fold css-engine utility CSS into the SERVER target's `__aihu_css__` export.
_formatExtractCensusfunction _formatExtractCensus(census: ReadonlyMap<string, { read: string; call: string; }>): string[];GX Phase 1 (#437-GX) — format the per-value extract census (the DA-e census pattern from #437: every build PRINTS the posture distribution, so the default-vs-declared migration story stays visible rather than silent).
_getCompilerNativeStateKindfunction _getCompilerNativeStateKind(): CompilerNativeState['kind'];Returns the cached state kind (resolving if needed).
_globalizeAuthoredStylefunction _globalizeAuthoredStyle(code: string): string;Light-DOM (`shadowMode:'light'`) recipes: redirect the authored `@style` block's per-instance `host.adoptedStyleSheets = [__style__]` assignment to `document.adoptedStyleSheets` so the recipe's class-scoped CSS reaches the global cascade (a light-DOM host has no shadow root, making the original setter a silent no-op).
_hashIdForUtilityCssfunction _hashIdForUtilityCss(id: string): string;Stable short hash for keying the virtual-CSS module per source-SFC id.
_injectAutoWiringfunction _injectAutoWiring(code: string): string;Inject `_setMount(mount)` + `_setSignal(signal)` auto-wiring into a compiled `.aihu` module.
_injectLightScopeIdfunction _injectLightScopeId(code: string, lightScopeId: string): string;Fill the Rust codegen's `__AIHU_LIGHT_SCOPE_ID__` placeholder with the component's real light-DOM scope id (LDF §10 step 3).
_injectShadowModefunction _injectShadowMode(code: string, mode: 'light' | 'shadow', lightScopeId?: string): string;Inject `shadowMode: '...'` (and, for light mode, `lightScopeId: '...'` in the SAME options object) into the third argument of the emitted `defineElement('tag', defineComponent(...))` call — appending the options object when the call has two arguments, or merging the fields into an existing third argument (`$form` emits `, { formAssociated: true }`).
_isLayoutFilefunction _isLayoutFile(rawId: string, layoutsDir: string): boolean;Is `rawId` a layout SFC (a `.aihu` file under the configured layouts dir)?
_isViteMissingfunction _isViteMissing(err: unknown): boolean;Is this `import('vite')` rejection the ONE legitimate "there is no Vite here" case — a standalone `transform()` caller, a unit test, any non-Vite host?
_layoutTagfunction _layoutTag(stem: string): string;Layout custom-element tag for a filename stem.
_lightScopeIdfunction _lightScopeId(id: string): string;Deterministic 8-hex-char scope id for a light-DOM component's `data-a` attribute (light-DOM leaf flip, LDF §10 step 1 / step 3).
_parseComponentTagsMarkerfunction _parseComponentTagsMarker(compiledCode: string): string[];§22 — parse the `//
_parseExtractMarkerfunction _parseExtractMarker(code: string): { read: string; call: string; } | null;GX Phase 1 (#437-GX) — parse the `//
_parseIslandMarkerfunction _parseIslandMarker(compiledCode: string): 'static' | 'interactive';Read the compiler's AUTHORITATIVE island classification from the `//
_passivizeOutletfunction _passivizeOutlet(code: string): string;Collapse the reactive `<outlet>` boundary the Rust codegen emits into a passive `data-aihu-outlet` marker.
_resetCompileBackendfunction _resetCompileBackend(): void;Reset the cached backend (tests).
_resetCompilerNativefunction _resetCompilerNative(): void;Reset the cached state.
_resolveCompileBackendfunction _resolveCompileBackend(): CompileBackend;Resolve (once) which backend serves compiles for this process.
_stripFailurefunction _stripFailure(fn: 'transformWithOxc' | 'transformWithEsbuild', id: string, viteVersion: string, isServerEnv: boolean, err: unknown): string;The message for a strip that failed with Vite present — names the branch, the Vite version, the environment and the file, and says why it is fatal rather than swallowed.
_stripTypesfunction _stripTypes(vite: ViteStripApi, code: string, id: string, isServerEnv: boolean): Promise<StripTypesResult>;Strip TypeScript from compiler output using whichever transform the resolved Vite exposes.
_transformMemoStatsfunction _transformMemoStats(): { size: number; hits: number; misses: number; seeds: number; };Test/diagnostic hook — current memo size + hit/miss/seed counters.
aihuCompilerPluginfunction aihuCompilerPlugin(options?: AihuCompilerPluginOptions): VitePlugin;compileRouteMetafunction compileRouteMeta(source: string, id?: string): RouteMeta | null;compileSidecarfunction compileSidecar(source: string, id?: string, options?: { /** * #486 step 4 — emit the attribute/component-prop type layer * (`--strict-templates`). Default off: the surface stays byte-identical * to the pre-#486 sidecar. */ strictTemplates?: boolean; /** * Build target threaded to the compiler binary (`--target`), same flag * `transform()` passes. Defaults to the binary's own default * (`universal`) when omitted. * * This is NOT cosmetic: `--target` changes what `compile_full_with_options` * produces (packages/compiler/src/bin/main.rs), which `sidecar_ts` is * derived from — e.g. a `target: 'client'` build elides server-only * artifacts. A caller that never passes this always type-checks against * the `universal` surface regardless of the project's actual configured * target, which can pass tsc on code the real build would elide or * reject. `islands`/`shadowMode` are deliberately NOT parameters here: * both are applied as JS-side post-processing on the RUNTIME JS output * (see `transform()`), never touch `sidecar_ts`, and have no bearing on * type-check accuracy. */ target?: 'client' | 'server' | 'universal'; }): string;Compile an SFC to its TYPE-CHECK SURFACE and return it as a string — the `.aihu.ts` sidecar's content, without writing a file.
compileToAstfunction compileToAst(source: string, id?: string): SfcAst;kebabComponentTagfunction kebabComponentTag(raw: string): string;O1a (tag naming) — JS mirror of the Rust compiler's `tags::kebab_component_tag` (packages/compiler/src/tags.rs).
loadCompilerNativefunction loadCompilerNative(): CompilerNativeState;Resolve (and cache) the native compiler addon.
matchBracefunction matchBrace(s: string, i: number): number;Matching `}` for the `{` at `i` (string/comment aware).
matchParenfunction matchParen(s: string, i: number): number;Matching `)` for the `(` at `i` (string/comment/brace aware).
migratefunction migrate(source: string): MigrateResult;migrateStateWrappersfunction migrateStateWrappers(source: string, options?: StateWrapperOptions): StateWrapperResult;migrateTemplateGrammarfunction migrateTemplateGrammar(source: string): TemplateGrammarResult;Run every template-grammar-v2 pass over one `.aihu` source (or a markdown document containing `.aihu` snippets — the transforms are anchored to template-syntax shapes and leave prose alone).
transformfunction transform(source: string, id: string, options?: { sidecarOut?: string; target?: 'client' | 'server' | 'universal'; /** Override the registered custom-element tag (default: file stem). Used for layouts. */ tag?: string; /** * #486 step 4 — emit the sidecar's attribute/component-prop type layer * (`--strict-templates`). Affects only the type-check surface written to * `sidecarOut`; the compiled JS is identical either way. Default off. */ strictTemplates?: boolean; }): { code: string; map: null; };Compile a .aihu source string to TypeScript.
_MEMO_MAX_ENTRIESconst _MEMO_MAX_ENTRIESFIFO size bound.
resolveCompilerBinaryconst resolveCompilerBinaryVIRTUAL_UTILITY_PREFIXconst VIRTUAL_UTILITY_PREFIXVirtual-module prefix used by the `shadowMode === 'light'` branch to route per-SFC utility CSS through Vite's built-in CSS pipeline.
AihuCompilerPluginOptionsinterface AihuCompilerPluginOptions {
/**
* When `true` (default), components the compiler classified as `'static'`
* (read from the `// @aihu:island` marker via `_parseIslandMarker()`) are
* emitted with a minimal HTML-only registration shim that ships **zero**
* `@aihu/runtime` and `@aihu/signals` JS to the browser. Components
* classified as `'interactive'` retain the full runtime path.
*
* Setting `islands: false` opts every component back into the unified
* runtime path (Plan 3.2 baseline behaviour).
*/
islands?: boolean;
/**
* Project-wide rendering mode applied to every `.aihu` SFC compiled
* by this plugin instance. When set, the plugin post-processes the
* compiled JS to inject `, { shadowMode: '<mode>' }` as the third arg
* to the emitted `defineElement(tag, defineComponent(...))` call.
*
* BINARY vocabulary (DA4 #437):
* - `'shadow'` — shadow DOM (`attachShadow({ mode: 'open' })` internally;
* open is the only browser mode aihu's composition/hydration
* can use). `this.shadowRoot` is the non-null root.
* - `'light'` — **no shadow root.** The component mounts into its own
* element (`this.shadowRoot === null`). Required for global
* utility-class CSS frameworks like Tailwind, UnoCSS, Pico
* that rely on the cascade.
*
* Per-file override: the `$shadow: 'light' | 'shadow'` macro outranks this
* config. Unset, pages/layouts default to `'light'` and leaves to
* `'shadow'`.
*/
shadowMode?: 'light' | 'shadow';
/**
* Build target threaded to the compiler binary (`--target`). Defaults to the
* compiler's `universal` target (current behaviour). Set to `'client'` for a
* browser bundle that must NOT ship the server `__agentBinding` (policy) and
* instead gets the policy-free `@agent` opaque-ID dispatcher + the per-instance
* `_registerAgentDispatcher` wiring the capability bridge reads after mount.
* See `examples/agent-driven-demo`.
*/
target?: 'client' | 'server' | 'universal';
/**
* Directory (relative to the project root) holding layout SFCs. Default:
* `'src/layouts'`. Files under this directory are compiled in **layout mode**:
* their custom element is registered under the namespaced tag
* `aihu-layout-<stem>` (a layout stem like `app` is not a valid custom-element
* name on its own), and their `<outlet>` lowers to a **passive**
* `data-aihu-outlet` marker rather than the reactive route-driven boundary —
* because `@aihu/app`'s client renderer fills the marker imperatively and the
* reactive boundary would otherwise clear it on mount.
*
* Kept in sync with `@aihu/router`'s `layoutTagFor()` (`virtual:aihu-layouts`).
*/
layoutsDir?: string;
}Options for `aihuCompilerPlugin()` (Plan 3.3 — Islands).
CompileEnvelopeinterface CompileEnvelope {
envelope: number;
targets: Record<string, {
js?: string;
manifest?: string;
}>;
astJson?: string;
routeJson?: string;
diagnostics: unknown[];
}The wire shape of a compile envelope (Rust `Envelope`, camelCase).
CompileEnvelopeOptionsinterface CompileEnvelopeOptions {
tag?: string;
path?: string;
targets?: string[];
emits?: Array<'js' | 'ast' | 'route' | 'manifest'>;
strictTemplates?: boolean;
exprParser?: string;
}Options forwarded to the Rust envelope API (Rust `EnvelopeOptions`).
MigrateResultinterface MigrateResult {
readonly rewritten: string;
readonly warnings: readonly string[];
}macro-simplification codemod (B6.2) Transforms v1 `.aihu` source into v2 collection-form per `docs/superpowers/specs/2026-05-05-spec-macro-vocabulary-v2.md`.
RouteMetainterface RouteMeta {
pattern?: string;
name?: string;
layout?: string;
middleware?: string[];
ssr?: boolean;
params?: string[];
head?: unknown;
/**
* GX Phase 1 fan-out (#437-GX): the resolved `extract` policy — always
* present in the binary's route-json output since 0.1.12 (the default is
* recorded, never implied by absence). Typed loose here: consumers
* normalize fail-closed (`deriveReadPolicy` in `@aihu/server`).
*/
extract?: {
read?: unknown;
call?: unknown;
};
/**
* GX Phase 4 fan-out (#466): the `data:` governed-resource declaration
* (70-governed-data-access §2.1) — present only when the route declares one
* (0.1.14+). `type` keys the server registry's provider; `preview` lists
* the locked-state fields (omitted when none declared). Consumers: the
* server runtime's boot validation + generated loader, and the router Vite
* layer's C486 sibling-loader conflict check (§4.7).
*/
data?: {
type?: string;
preview?: string[];
};
}Structured `@route` metadata (the `.route.json` sidecar shape).
SfcAstinterface SfcAst {
/** Resolved custom-element tag name (meta.name → route.name → file stem). */
tag: string;
/** AST schema version — bumped on any breaking shape change (semver-tied). */
astVersion: 1;
/** The @style block, if the SFC declared one. */
style: SfcStyleBlock | null;
/** Parsed template tree. null when the SFC has no @template block. */
template: SfcNode[] | null;
/** SFC-level metadata. */
meta: SfcMeta;
/**
* The compiler-assigned light-DOM scope id for this component's `data-a`
* attribute, present only when it resolved to `shadowMode: 'light'`
* (light-DOM leaf flip, LDF §10 step 1). Absent (not just `undefined`, the
* key itself omitted on the wire) for shadow-mode components — additive,
* mirrors `aihu-css-core`'s `SfcAst.light_scope_id: Option<String>`.
*/
lightScopeId?: string;
}Top-level AST export — one per .aihu SFC.
SfcMetainterface SfcMeta {
/** From @meta { name } / @route { name } / file stem — never null after resolution. */
name: string;
}SfcStyleBlockinterface SfcStyleBlock {
/** Verbatim CSS body of the @style block (braces stripped, $global token removed). */
content: string;
/** 'scoped' (default) or 'global' (@style { $global ... }). */
scope: 'scoped' | 'global';
}StateWrapperOptionsinterface StateWrapperOptions {
/** Run only stage 1 ($-macros + bare typed decls). */
macrosOnly?: boolean;
/** Run only stage 2 (signal tuples + call sites). */
tuplesOnly?: boolean;
/**
* Binding names that must stay PLAIN even when the reactive heuristic says
* `state(…)` (e.g. a fixture guard depends on the plain-let lowering).
*/
keepPlain?: readonly string[];
}StateWrapperResultinterface StateWrapperResult {
readonly rewritten: string;
readonly warnings: readonly string[];
/** True when the file was left byte-untouched (nothing to do, or aborted). */
readonly skipped: boolean;
/** Which change classes were applied — drives the verification bucket. */
readonly changes: {
macros: boolean;
tuples: boolean;
bareTyped: boolean;
};
/** Tuple pairs migrated: authored setter name → state binding name. */
readonly renamedSetters: ReadonlyArray<{
getter: string;
setter: string;
}>;
}state-wrapper codemod (#487 §7 — waves 1 + 2, the app-corpus migration) Migrates an `.aihu` file's `@state` block from the retired forms to the ratified wrapper model (`docs/plans/state-model/40-spec.md`): Stage 1 — `$`-macros → wrappers / statement calls / directives (§2, §3): $prop: { x: { … } } → const|let x = prop<T>({ … }) $computed: { x: fn } → const x = derived(cfg?, fn) $action: { f: fn } → const f = action(cfg?, fn) $resource: { r: fn } → const r = resource(cfg?, fn) $controller: { c: {value} }→ const c = controller(cfg?, factory) $effect: fn / { name: fn } → effect(fn) / effect({ on: […] }, fn) $lifecycle: { mount, … } → onMount(fn), onDispose(fn), … $aria: { … } / $form: { … }→ aria({ … }) / form({ … }) $context: {provide,consume}→ provide('k', v) / const k = consume<T>('k') $route name → const name = route() $before/afterNavigate(fn) → beforeNavigate(fn) / afterNavigate(fn) $extends: X / $shadow: 'm' → base: X / shadow: 'm' bare typed decl `x: T = v` → let x = state(v) (reactive) | plain let/const (inert; §3 row 21 + W627) Stage 2 — signal tuples → `state` (§7 wave 2), INCLUDING call sites: const [x, setX] = signal(v) → let x = state(v) x() → x setX(v) → x = v (statement / handler) setX(p => expr) → x = expr[p→x] (updater desugar) Byte-identity contract: `$`-macro migrations lower onto the SAME IR, so a stage-1-only migration emits byte-identical JS (modulo the old parser's `strip_line_comments` artifact — authored `//` comments inside metadata-bag bodies were BLANKED in old emission and are preserved by the wrapper path).
StripTypesResultinterface StripTypesResult {
readonly code: string;
readonly map: null;
/** Rolldown-only hint; set ONLY on the last-resort no-transform branch. */
readonly moduleType?: 'ts';
}What the Vite plugin's `transform` hook hands back after the strip.
TemplateGrammarResultinterface TemplateGrammarResult {
readonly rewritten: string;
readonly changed: boolean;
}template-grammar-v2 codemod — migrate v1 template syntax to the prefix-less grammar (docs/plans/template-grammar/40-spec.md).
ViteStripApiinterface ViteStripApi {
readonly version?: string;
readonly transformWithOxc?: (code: string, id: string, ...rest: any[]) => Promise<{
code: string;
}>;
readonly transformWithEsbuild?: (code: string, id: string, ...rest: any[]) => Promise<{
code: string;
}>;
}The subset of the Vite module `_stripTypes` uses — the seam tests fake.
SfcAttrtype SfcAttr = {
kind: 'static';
name: string;
value: string;
} | {
kind: 'binding';
name: string;
expr: string;
} | {
kind: 'macro';
name: string;
value: SfcMacroValue;
};Discriminated union mirroring Rust `Attr` — the three class-forms key on `kind`.
SfcMacroValuetype SfcMacroValue = {
form: 'quoted';
value: string;
} | {
form: 'curly';
expr: string;
} | {
form: 'boolean';
};SfcNodetype SfcNode = {
kind: 'element';
tag: string;
attrs: SfcAttr[];
children: SfcNode[];
} | {
kind: 'macroElement';
name: string;
attrs: SfcAttr[];
children: SfcNode[];
} | {
kind: 'text';
value: string;
} | {
kind: 'interpolation';
expr: string;
} | {
kind: 'ifBlock';
branches: Array<{
cond: string;
body: SfcNode[];
}>;
} | {
kind: 'eachBlock';
list: string;
item: string;
idx: string | null;
key: string | null;
body: SfcNode[];
emptyBody: SfcNode[] | null;
} | {
kind: 'htmlBlock';
expr: string;
};Discriminated union mirroring Rust `TemplateNode`.