API / @aihu/server

@aihu/server

App & routing

Server runtime + native renderer (napi-rs) for aihu SSR.

version
0.3.0
exports
110
values
42
types
68
01

_buildStateScript

function
function _buildStateScript(root: unknown, opts: SsrOptions | undefined): string

Build the `__aihu_state__` script for one finished render, or `''` when there is no state to ship (so a state-free page's HTML is byte-identical to today and the client's no-script hydration path is exercised).

02

_getNativeStateKind

function
function _getNativeStateKind(): NativeState['kind']

Returns the resolved native loader state kind.

03

_resetNativeState

function
function _resetNativeState(): void

Reset the cached native state.

04

_setContextFns

function
function _setContextFns(set: (map: Map<symbol, unknown>) => void, clear: () => void): void

Inject context activation/deactivation functions from

05

_setStoreSerializer

function
function _setStoreSerializer(fn: (() => Record<string, unknown>) | undefined): void

Inject the store snapshot function from

06

attachSsrString

function
function attachSsrString<T extends () => unknown>( component: T, ssrString: unknown, props: unknown, ): T

Carry a compiled string renderer across a props-binding wrapper.

07

badRequest

function
function badRequest(message?: string): Response
08

checkEntitlement

function
function checkEntitlement( registry: EntitlementsHandle, principal: EntitledPrincipal, scope: string, memo?: EntitlementMemo, url?: URL, ): Promise<EntitlementVerdict>

THE single live check, both axes (§4.6) — a named alias over the registry's `check` so call sites read as the spec does.

09

composeMiddleware

function
function composeMiddleware(middlewares: ReadonlyArray<Middleware>): Middleware

Compose middleware in array order (index 0 = outermost).

10

createGovernedRegistry

functionagent
function createGovernedRegistry(): GovernedRegistry

Create the governed registry (§2.2).

11

createRequestRouter

function
function createRequestRouter( manifest: RouteManifest, options?: RouterOptions, ): (req: Request) => Promise<Response>

Create a fetch-API compatible request handler.

12

defineAihuConfig

function
function defineAihuConfig(config: AihuConfig): AihuConfig

Define the aihu application configuration.

13

defineApiRoute

function
function defineApiRoute(method: HttpMethod, pattern: string, handler: ApiHandler): Route

The router enforces the method: a request to the matching pattern with a non-matching method receives `405 Method Not Allowed` with an `Allow` header listing all registered methods for that pattern.

14

defineGovernedFetch

functionagent
function defineGovernedFetch<T>(p: DataProvider<T>): DefinedGovernedFetch<T>

The escape hatch (§4.7): hand-written data logic on a governed route.

15

defineLoader

function
function defineLoader<T>(fn: LoaderFn<T>): DefinedLoader<T>

Loaders run before the route handler.

16

defineMiddleware

function
function defineMiddleware(handler: Middleware): Middleware
17

defineRoute

function
function defineRoute<T = never>( pattern: string, handlerOrSubroutes: | RouteHandler | ((req: Request, ctx: LoadedRouteContext<T>) => Response | Promise<Response>) | ReadonlyArray<SubrouteTuple>, options?: RouteOptions<T>, ): Route | Route[]
18

defineRoutes

function
function defineRoutes(inputs: ReadonlyArray<RouteInput>): Route[]

Register multiple routes in a single call.

19

defineStreamRoute

function
function defineStreamRoute(handler: StreamRouteHandler): Route

Define a route that streams text/plain chunks to the client.

20

deriveReadPolicy

function
function deriveReadPolicy(read: unknown): ReadDerivation

Derive every compliance-tier output signal from one `read` value.

21

extractReadValue

function
function extractReadValue(extract: unknown): unknown

Pull the `read` member off a compiled `extract` object without trusting its shape.

22

governedHttpStatus

functionagent
function governedHttpStatus<T>(emission: GovernedEmission<T>): 200 | 401 | 403 | 500 | 503

The HTTP status a governed emission serves with (read axis, §4.3 ladder).

23

isCallAdvertised

functionagent
function isCallAdvertised(extract: unknown): boolean

Is this surface's agent surface advertisable at all — i.e.

24

isGovernedFetch

functionagent
function isGovernedFetch(x: unknown): x is DefinedGovernedFetch<unknown>

Is this module export the branded governed-fetch escape hatch?

25

json

function
function json(data: unknown, status?: number): Response
26

materializeGeneratedLoader

functionagent
function materializeGeneratedLoader<T>( registry: GovernedRegistry, decl: GovernedRouteDataDecl, readValue: unknown, override?: DataProvider<T>, ): GeneratedLoader<T>

Materialize the generated loader for one governed route (§3, §4.7): `data:` present and no sibling loader → registry provider; the `defineGovernedFetch` escape hatch supplies `override` — replacing step 4 ONLY.

27

methodNotAllowed

function
function methodNotAllowed(allowed: ReadonlyArray<HttpMethod>): Response
28

normalizeGovernedData

function
function normalizeGovernedData(data: unknown): GovernedRouteDataDecl | 'malformed' | null

Normalize a `.route.json` `data` field fail-closed: `null` when absent, `'malformed'` when present but unparseable (a corrupted declaration is refused at boot, never rounded to ungoverned — the same posture as `deriveReadPolicy`'s `'malformed'`).

29

notFound

function
function notFound(): Response
30

passesRouteRead

function
function passesRouteRead(principal: Principal, readValue: unknown): boolean

Route-level read decision for the T4 fallback path (a hard-`read` route with a plain `defineLoader` and no `data:`): may this principal receive the route's loader output at all?

31

renderToStream

function
function renderToStream( component: ComponentDescription, opts?: StreamOptions, ): ReadableStream<string>
32

renderToString

function
async function renderToString( component: ComponentDescription, opts?: SsrOptions, ): Promise<string>

Render a component to an HTML string.

33

renderToStringNative

function
async function renderToStringNative( component: ComponentDescription, opts?: SsrOptions, ): Promise<string>

Render via the native (Rust) renderer when available, falling back to the TS implementation for edge / unsupported platforms.

34

resolveNativeState

function
function resolveNativeState(): NativeState

Resolve (and cache) the native loader state.

35

resolveRequestPrincipal

functionagent
async function resolveRequestPrincipal( req: Request, auth?: GovernedRequestAuth, ): Promise<Principal>

Step 1 for the SSR/E3 transports: settle THE principal for one request from its credential material (Authorization bearer, User-Agent, host-verified session).

36

routeHeadToSsrHead

function
function routeHeadToSsrHead( head: RouteHead | undefined, opts: RouteHeadLowerOptions = {}, ): HeadConfig

Lower a route's head metadata into a renderable `HeadConfig`, merged with an optional global head.

37

serverError

function
function serverError(err?: unknown): Response

SECURITY: In production (`__DEV__ === false`), the error message MUST NOT appear in the response body.

38

throwIfNativeFailed

function
function throwIfNativeFailed(state: NativeState): void

Convert a `native-failed-loud` state into the formatted AihuNativeError and throw it.

39

validateGovernedBoot

function
function validateGovernedBoot( registry: GovernedRegistry | undefined, routes: readonly GovernedRouteCensusEntry[], opts?: { strict?: boolean }, ): void

Validate the registry against the compiled route census at `createServerRouter` construction (§2.3).

40

DEFAULT_ENTITLEMENT_TIMEOUT_MS

const
const DEFAULT_ENTITLEMENT_TIMEOUT_MS

Default live-resolver deadline (ms) — ratified Q1 (§7).

41

GOVERNED_RETRY_AFTER_SECONDS

constagent
const GOVERNED_RETRY_AFTER_SECONDS

`Retry-After` seconds on `'unavailable'` responses (503).

42

AihuNativeError

class
class AihuNativeError extends Error
43

AgentReadinessConfig

interfaceagent
interface AgentReadinessConfig {
  // ── Identity ─────────────────────────────────────────────────────────
  readonly name: string
  readonly version?: string
  readonly summary?: string

  // ── MCP endpoint ─────────────────────────────────────────────────────
  /** When present: MCP card generated at `/.well-known/mcp/server-card.json`. */
  readonly endpoint?: string

  // ── Auth (opt-in, default: no-auth) ──────────────────────────────────
  readonly auth?: {
    readonly type: 'oauth2'
    readonly authorizationUrl: string
    readonly tokenUrl: string
    readonly scopes?: ReadonlyArray<string>
    readonly resourceUri?: string
  }

  // ── llms.txt ─────────────────────────────────────────────────────────
  readonly llmsSections?: ReadonlyArray<{
    readonly title: string
    readonly links: ReadonlyArray<{
      readonly title: string
      readonly url: string
      readonly description?: string
    }>
  }>
  readonly llmsOptional?: ReadonlyArray<{
    readonly title: string
    readonly url: string
    readonly description?: string
  }>

  // ── robots.txt ───────────────────────────────────────────────────────
  /**
   * AI-agent crawl policy. Default: `'allow-agents'` (tiered, since
   * @aihu-plugin/agent-readiness 2.1.0 / #430) — user-delegated fetchers
   * (ChatGPT-User, OAI-SearchBot, DuckAssistBot, Applebot) are allowed;
   * training/scraping crawlers (GPTBot, CCBot, Bytespider, …) are disallowed
   * and must be opted in explicitly via `'allow-all'` or rules.
   * Any other string value throws at robots.txt generation time.
   */
  readonly aiAgents?:
    | 'allow-agents'
    | 'allow-all'
    | 'deny-all'
    | ReadonlyArray<{
        readonly userAgent: string | ReadonlyArray<string>
        readonly allow?: ReadonlyArray<string>
        readonly disallow?: ReadonlyArray<string>
        readonly crawlDelay?: number
      }>
  readonly standardBots?: ReadonlyArray<{
    readonly userAgent: string | ReadonlyArray<string>
    readonly allow?: ReadonlyArray<string>
    readonly disallow?: ReadonlyArray<string>
    readonly crawlDelay?: number
  }>
  /**
   * GX Phase 3 (#437-GX): the COMPILED route table — structurally,
   * `@aihu/router`'s `RouteDefinition[]` (e.g. `import routes from
   * 'virtual:aihu-routes'`, the same array handed to `createServerRouter`).
   * Each route's compiled `extract` declaration derives its robots.txt
   * per-path directives and its presence in the agent-facing discovery
   * documents (llms.txt). This is a conduit for compiled output, never a
   * place to hand-author policy — the `.aihu` `extract:` declaration is the
   * one source (spec §8). Omitted → global-policy-only robots.txt and no
   * derived route listing, byte-identical to pre-GX output.
   */
  readonly routes?: ReadonlyArray<{
    readonly pattern: string
    readonly extract?: { readonly read?: unknown; readonly call?: unknown }
  }>
  readonly sitemap?: string
  /**
   * robots.txt always ends with a `User-agent: * / Allow: /` block for
   * predictable output. Set `false` to suppress it. (It is also skipped
   * automatically when one of your own rules already targets `*`.)
   */
  readonly wildcard?: boolean

  // ── Skills ───────────────────────────────────────────────────────────
  /** Manually declared MCP skills, merged with auto-derived from AgentMetadata.actions. */
  readonly skills?: ReadonlyArray<{
    readonly id: string
    readonly name: string
    readonly description: string
    readonly inputSchema?: Record<string, unknown>
  }>

  // ── Site identity ─────────────────────────────────────────────────────
  /** Canonical base URL (e.g. 'https://aihu.dev'). Used by A2A card, MCP discovery, and JSON-LD. */
  readonly siteUrl?: string

  // ── A2A Agent Card ────────────────────────────────────────────────────
  /**
   * Generate /.well-known/agent.json (Google A2A protocol).
   * `true` derives name/description/url/version from top-level config fields.
   * Object form overrides streaming/pushNotifications capabilities.
   */
  readonly a2aCard?:
    | true
    | {
        readonly capabilities?: {
          readonly streaming?: boolean
          readonly pushNotifications?: boolean
        }
        readonly skills?: ReadonlyArray<{
          readonly id: string
          readonly name: string
          readonly description?: string
        }>
      }

  // ── MCP Discovery ─────────────────────────────────────────────────────
  /**
   * Generate /.well-known/mcp.json.
   * When true and `endpoint` is set, points to the endpoint URL.
   * When true and `endpoint` is absent, falls back to /.well-known/mcp/server-card.json.
   */
  readonly mcpDiscovery?: boolean

  // ── Sitemap pages ─────────────────────────────────────────────────────
  /**
   * Pages to include in /sitemap.xml.
   * When provided, the Vite plugin emits sitemap.xml at build time.
   * The existing `sitemap` field (URL string) is used for robots.txt Sitemap: reference.
   */
  readonly sitemapPages?: ReadonlyArray<{
    readonly url: string
    readonly lastmod?: string
    readonly changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'
    readonly priority?: number
  }>

  // ── JSON-LD structured data ───────────────────────────────────────────
  /**
   * JSON-LD objects injected into <head> via <script type="application/ld+json">.
   * If absent but `siteUrl` is set, a SoftwareApplication schema is auto-generated.
   * Set `false` to disable auto-generation.
   */
  readonly jsonLd?: ReadonlyArray<Record<string, unknown>> | false
}

Canonical `AgentReadinessConfig` — the type of `AihuConfig.agent`.

44

AihuConfig

interface
interface AihuConfig {
  readonly server?: ServerConfig
  readonly agent?: import('./agent-readiness-config.ts').AgentReadinessConfig
  readonly routes?: RouteConfig
  /**
   * Plugins registered in this aihu project.
   *
   * Per Plugin Contract Spec §7.1-§7.2: plugins MUST be explicitly imported
   * and registered here. Auto-discovery is forbidden.
   *
   * v0.2.1: type contract + registration plumbing only. The compiler
   * dispatcher is a no-op until v0.3+ wires block parsers, macro lowerings,
   * and hook execution. Admitting the field now lets plugin authors begin
   * shaping `definePlugin({...})` calls against a stable type surface.
   */
  readonly plugins?: ReadonlyArray<Plugin>
  /**
   * v0.6.5: Build target configuration.
   * Controls whether aihu emits a client bundle, server bundle, or both.
   * This field is read by the compiler/build tooling; it has no runtime effect.
   */
  readonly build?: BuildConfig
  /**
   * Runtime rendering strategy. Defaults to SSR with hydration enabled —
   * the agent-ready posture that gives LLMs, crawlers, and the aihu MCP
   * server access to content without JavaScript execution.
   */
  readonly rendering?: RenderingConfig
  /**
   * v1: `@aihu/ui` styled-recipe registry configuration.
   * BUILD-TIME ONLY — consumed by the `aihu add` CLI and the css-engine
   * scanner; it has no runtime/edge effect (matching the `build`/`plugins`
   * field posture). Defaults are resolved by the CLI at read-time, so omitting
   * `ui` entirely is valid.
   */
  readonly ui?: UiConfig
}
45

BuildConfig

interface
interface BuildConfig {
  /** Build target. Default: 'universal' */
  target?: BuildTarget
}
46

CorsConfig

interface
interface CorsConfig {
  readonly origin: string | ReadonlyArray<string> | '*'
  readonly methods?: ReadonlyArray<import('./types.ts').HttpMethod>
  readonly headers?: ReadonlyArray<string>
  readonly credentials?: boolean
  readonly maxAge?: number
}
47

DataProvider

interfaceagent
interface DataProvider<T> {
  /** The one data-source access. Runs ONLY after grant. Server-only, never bundled. */
  fetch(ctx: GovernedFetchContext): Promise<T>
  /** Optional: data for the declared `preview:` fields of the withheld state. */
  preview?(ctx: GovernedFetchContext): Promise<Partial<T>>
}

WHERE a governed type's data comes from.

48

DataSource

interfaceagent
interface DataSource<T> {
  /** Current resolution state. */
  readonly status: 'pending' | 'ready' | 'error'

  /** The resolved value. Defined only when status === 'ready'. */
  readonly value?: T

  /** The rejection reason. Defined only when status === 'error'. */
  readonly error?: unknown

  /**
   * Register a callback to be invoked exactly once when status transitions
   * to 'ready' or 'error'. Returns a dispose function that cancels the
   * registration if called before the transition fires.
   */
  onReady(cb: () => void): () => void
}

Describes an async data boundary that renderToStream can suspend on.

49

DefinedGovernedFetch

interface
interface DefinedGovernedFetch<T> extends DataProvider<T> {
  readonly _brand: 'DefinedGovernedFetch'
}

The branded route-local provider — replaces step 4 ONLY, never the gate.

50

DefinedLoader

interface
interface DefinedLoader<T> {
  readonly _brand: 'DefinedLoader'
  /** @internal */
  readonly fn: LoaderFn<T>
}
51

EntitlementContext

interface
interface EntitlementContext {
  /** Static meet already passed — never anonymous (§4.2). */
  readonly principal: EntitledPrincipal
  readonly scope: string
  /** Never the raw credential. */
  readonly request: { readonly url: URL }
  /**
   * Aborted when the registered `timeoutMs` (default 2000) elapses (§4.3).
   * Deadline exhaustion is indistinguishable from a throw: `'unavailable'`.
   */
  readonly signal: AbortSignal
}

The live per-request entitlement check's context (§3.1, §4.3).

52

EntitlementRegistration

interface
interface EntitlementRegistration {
  /** The LIVE per-request check. `true` = entitled now. Throw/timeout ⇒ withhold. */
  resolve(ctx: EntitlementContext): Promise<boolean>
  /** Resolver deadline in ms; default {@link DEFAULT_ENTITLEMENT_TIMEOUT_MS}. */
  timeoutMs?: number
  /** Positive-verdict TTL cache, per (scope, principal.sub). Negatives are NEVER cached (Q2). */
  cache?: { ttlMs: number }
}

Whether a principal may have the scope's authority RIGHT NOW.

53

ExtractDeclarationLike

interfaceagent
interface ExtractDeclarationLike {
  readonly read?: unknown
  readonly call?: unknown
}

A compiled `extract` declaration as it appears on `.route.json` / agent-meta artifacts.

54

GovernedFetchContext

interfaceagent
interface GovernedFetchContext {
  readonly params: Record<string, string>
  readonly url: URL
  /**
   * The SETTLED principal (§4.7): a hand-written fetch may further narrow on
   * it, never widen. On the granted path this is always a verified principal;
   * on the `preview` path it may be anonymous.
   */
  readonly principal: Principal
}

The context a provider's `fetch`/`preview` receives.

55

GovernedLoadContext

interfaceagent
interface GovernedLoadContext {
  readonly params: Record<string, string>
  readonly url: URL
  /** Settled by `resolvePrincipal` in `handle` — step 1, once per request. */
  readonly principal: Principal
  /** The per-request memo (§4.4 layer 1). */
  readonly entitlements: EntitlementMemo
}

The context the generated loader runs in (principal settled by `handle`).

56

GovernedRegistry

interfaceagent
interface GovernedRegistry extends EntitlementsHandle {
  /** Register the data-source provider for a governed resource type. */
  provider<T>(type: string, p: DataProvider<T>): GovernedRegistry
  /**
   * Register the live entitlement resolver for a scope — or declare the scope
   * explicitly static with `'token-only'` (required in strict mode, §2.3).
   * Registering a resolver makes EVERY use of the scope — both axes — live.
   */
  entitlement(scope: string, r: EntitlementRegistration | 'token-only'): GovernedRegistry
  /**
   * Revocation composition hook (§4.4.3): purge every cached entitlement
   * entry for `sub`, so "revoke this delegation" also drops cached
   * entitlement warmth immediately (in-process; a shared cache store is an
   * operator upgrade, not a framework default).
   */
  onRevoke(sub: string): void
  /** @internal Provider lookup for the generated loader / boot validation. */
  providerFor(type: string): DataProvider<unknown> | undefined
  /** @internal How a scope is registered — drives strict-mode boot validation. */
  entitlementKind(scope: string): 'live' | 'token-only' | 'unregistered'
  /** @internal Telemetry counters (G7d/G7e assertions). */
  stats(): GovernedRegistryStats
}

The single server-init registration surface (§4.1): a builder passed to `createServerRouter(routes, { governed })` and (same instance) to `AgentServiceOptions.entitlements`.

57

GovernedRegistryStats

interfaceagent
interface GovernedRegistryStats {
  /** Live resolver invocations (post-memo, post-cache). */
  readonly resolves: number
  /** Cross-request TTL cache consults. */
  readonly cacheReads: number
  /** Cross-request TTL cache hits (positive, unexpired). */
  readonly cacheHits: number
}
58

GovernedRequestAuth

interfaceagent
interface GovernedRequestAuth extends PrincipalGateDeps {
  /**
   * Resolve a HOST-VERIFIED session from the request (e.g. `getAuthState`
   * over the cookie). Same injection posture as `PrincipalSource.session`:
   * never pass unverified cookie contents.
   */
  readonly resolveSession?: (
    req: Request,
  ) =>
    | { readonly sub: string; readonly scopes: readonly string[] }
    | null
    | undefined
    | Promise<{ readonly sub: string; readonly scopes: readonly string[] } | null | undefined>
}

The host-injected auth material for principal resolution on the SSR path.

59

GovernedRouteCensusEntry

interfaceagent
interface GovernedRouteCensusEntry {
  readonly pattern: string
  readonly data?: unknown
  readonly extract?: { readonly read?: unknown; readonly call?: unknown } | undefined
}

One row of the compiled route census the boot check reads.

60

GovernedRouteDataDecl

interfaceagent
interface GovernedRouteDataDecl {
  /** Names the governed resource type — the provider key. */
  readonly type: string
  /** Fields renderable in the locked state (declared public-tier, §4.5). */
  readonly preview?: readonly string[]
}

The normalized `data:` route declaration.

61

HeadConfig

interface
interface HeadConfig {
  readonly title?: string
  readonly meta?: ReadonlyArray<MetaTag>
  readonly links?: ReadonlyArray<LinkTag>
  readonly lang?: string
  /**
   * Inline `<script>` elements (e.g. JSON-LD structured data). Backward
   * compatible: omitted means no script tags are emitted, matching prior
   * `buildHead` behavior.
   */
  readonly scripts?: ReadonlyArray<ScriptTag>
}
62

LinkTag

interface
interface LinkTag {
  readonly rel: string
  readonly href: string
  readonly [attr: string]: string | undefined
}
63

LoadedRouteContext

interface
interface LoadedRouteContext<T> extends RouteContext {
  readonly loaderData: LoaderResult<T>
}
64

LoaderResult

interface
interface LoaderResult<T> {
  readonly data: T
  readonly error?: Error
  readonly status: number
}
65

MetaTag

interface
interface MetaTag {
  readonly name?: string
  readonly property?: string
  readonly content: string
  readonly [attr: string]: string | undefined
}
66

NativeAddon

interface
interface NativeAddon {
  renderTree(treeJson: string, hydratable: boolean): string
  renderDocument(treeJson: string, headJson: string, hydratable: boolean): string
}
67

PlatformDescriptor

interface
interface PlatformDescriptor {
  readonly platformId: string
  readonly packageName: string
  readonly nodeFile: string
}
68

ReadDerivation

interfaceagent
interface ReadDerivation {
  readonly value: NormalizedReadValue
  /**
   * `'compliance'` for the anonymous values (`'all'`/`'agents'`/`'search'`/
   * `'none'`), `'hard'` for the verified values — the spec §2.1 tier break.
   * NOTE: the tier names what full enforcement WOULD be; this module only
   * emits the compliance-tier signals either way (see module docblock).
   */
  readonly tier: 'compliance' | 'hard'
  /**
   * Which declared crawler tiers the value admits. Meaningful for compliance
   * values; all-false for hard values (no anonymous crawl access at all).
   */
  readonly crawl: CrawlerTierAccess
  /**
   * Should robots.txt carry per-path directives for this surface?
   * Compliance values: yes (`read:'none'` routes are served to humans, so
   * their existence is not a secret — they DO get Disallow lines, spec §8).
   * Hard values: NO — the path is simply absent from robots.txt. A Disallow
   * line naming a governed path would advertise its existence (spec §8
   * existence-advertising; the A-5 self-contradiction).
   */
  readonly advertiseInRobots: boolean
  /**
   * Should the served response carry a noindex signal (`X-Robots-Tag:
   * noindex`)? True for `read:'none'` and every hard/malformed value.
   */
  readonly noindex: boolean
  /**
   * Listed in agent-facing discovery (llms.txt, MCP server-card tools)?
   * Requires user-fetcher access: a surface that refuses user-directed AI
   * fetchers must not be advertised to them.
   */
  readonly agentDiscovery: boolean
  /** Listed in search-facing surfaces (sitemap)? Requires searcher access. */
  readonly searchDiscovery: boolean
}

Everything the derived surfaces need to know about one `read` value.

69

RenderingConfig

interface
interface RenderingConfig {
  /**
   * Default rendering mode for all routes.
   * Default: 'ssr' — server-renders every page with hydration markers enabled.
   */
  readonly mode?: RenderingMode
  /**
   * Emit `data-aihu-path` hydration markers on SSR output by default.
   * Only applies when mode is 'ssr' or 'hybrid'.
   * Default: true — enabling client-side takeover after first paint.
   */
  readonly hydratable?: boolean
}
70

Route

interface
interface Route {
  readonly pattern: string
  readonly handler: RouteHandler
  readonly middleware?: ReadonlyArray<Middleware>
}
71

RouteConfig

interface
interface RouteConfig {
  /** Default: `./routes.gen.ts`. */
  readonly manifestPath?: string
}
72

RouteContext

interface
interface RouteContext {
  readonly params: Record<string, string>
  readonly url: URL
  readonly env?: unknown
}
73

RouteHead

interface
interface RouteHead {
  readonly title?: string
  readonly description?: string
  readonly canonical?: string
  readonly og?: {
    readonly title?: string
    readonly description?: string
    readonly image?: string
    readonly type?: string
    readonly url?: string
  }
  readonly twitter?: {
    readonly card?: string
    readonly title?: string
    readonly description?: string
    readonly image?: string
    readonly site?: string
  }
  /**
   * JSON-LD structured data. The compiler captures the `@route` `jsonld` block
   * VERBATIM as a raw JSON string, so this is typically a `string`. A
   * pre-parsed object/value is also accepted and will be `JSON.stringify`'d.
   */
  readonly jsonld?: unknown
}

Per-route head metadata, as emitted by the compiler into `.route.json` and (post-B2) re-exported from `@aihu/router`.

74

RouteHeadLowerOptions

interface
interface RouteHeadLowerOptions {
  /**
   * Absolute site base URL (e.g. `https://example.com`) used to resolve
   * relative `canonical` / `og.image` / `og.url` values into absolute URLs.
   * Supplied by the wiring Builder (from `AihuConfig.site.url`). When absent,
   * relative values are emitted as-is (documented, non-throwing).
   */
  readonly siteUrl?: string
  /**
   * Global head defaults (typically from `app.head`). Route fields override
   * global per field; `meta`/`links`/`scripts` arrays are key-merged with the
   * route winning on conflicts.
   */
  readonly globalHead?: HeadConfig
}
75

RouteInput

interface
interface RouteInput {
  readonly pattern: string
  readonly handler: RouteHandler
  readonly options?: RouteOptions<never>
}

A route config object for use with `defineRoutes`.

76

RouteManifest

interface
interface RouteManifest {
  readonly routes: ReadonlyArray<Route | ReadonlyArray<Route>>
  readonly layouts?: Readonly<Record<string, ReadonlyArray<string>>>
}

Route manifest produced by the file-based routing Vite plugin at build time.

77

RouteOptions

interface
interface RouteOptions<T = never> {
  readonly loader?: DefinedLoader<T>
  readonly middleware?: ReadonlyArray<Middleware>
}
78

RouterOptions

interface
interface RouterOptions {
  readonly middleware?: ReadonlyArray<Middleware>
  readonly notFound?: RouteHandler
  readonly env?: unknown
}
79

ScriptTag

interface
interface ScriptTag {
  readonly type: string
  readonly content: string
}

A `<script>` element in the document head.

80

ServerConfig

interface
interface ServerConfig {
  readonly basePath?: string
  readonly cors?: CorsConfig
  /** Default: 1_048_576 (1 MB). */
  readonly maxBodySize?: number
}
81

SsrOptions

interface
interface SsrOptions {
  /**
   * When provided: output is a full HTML document.
   * When absent: output is the component's inner HTML fragment only.
   */
  readonly head?: HeadConfig

  /**
   * When true: rendered HTML includes hydration markers as data attributes.
   * Default: false.
   */
  readonly hydratable?: boolean

  /**
   * Injected signal serializer (an arbor `MountScope.serialize`-shaped
   * snapshot: path key → value). When provided it REPLACES the default
   * post-render signal collection and its result rides the `signals` key of
   * the `__aihu_state__` envelope. When it throws, the error is swallowed
   * and the `signals` channel is omitted.
   */
  readonly serializer?: () => Record<string, unknown>

  /**
   * Optional per-render context setup hook. When provided alongside a prior call
   * to _setContextFns, ssr.ts will:
   *   1. Call contextSetup(activateFn, deactivateFn) so the caller can do
   *      per-request setup (e.g. pre-populate the context map).
   *   2. Activate a fresh context Map before the tree walk.
   *   3. Clear it in a finally block after the walk.
   *
   * ssr.ts never imports @aihu/context — the hard boundary is preserved.
   * The activate/deactivate functions are wired via _setContextFns at startup.
   *
   * Minimal usage:
   *   import { setSsrContextMap, clearSsrContextMap } from '@aihu/context/ssr'
   *   import { _setContextFns, renderToString } from '@aihu/server'
   *   _setContextFns(setSsrContextMap, clearSsrContextMap)
   *   await renderToString(component, { contextSetup: () => {} })
   */
  readonly contextSetup?: (
    activate: (map: Map<symbol, unknown>) => void,
    deactivate: () => void,
  ) => void

  /**
   * GX Phase 4 (#466) — the P5/I2s guard: mark this render as a GOVERNED
   * tree. Governed trees are never streamed — encountering a `pending`
   * `dataSource` boundary in a governed render is refused fail-closed
   * (`GOVERNED_UNGATED` posture, 40-spec §10) rather than suspended, because
   * a streamed governed subtree would be an emission path the generated
   * loader never gated. Set by the router's governed `handle` path.
   */
  readonly governed?: boolean
}
82

StreamOptions

interface
interface StreamOptions extends SsrOptions {}

Options for renderToStream.

83

UiConfig

interface
interface UiConfig {
  /** Source registry to pull recipes from. v1: the '@aihu/ui' package specifier. Default: '@aihu/ui'. */
  readonly registry?: string
  /** Directory `aihu add` copies recipe sources into. Default: './src/components/ui'. */
  readonly target?: string
  /** Active style pack name. Default: 'aihu-default'. */
  readonly style?: string
  /** Custom-element tag prefix for copied recipes. Default: 'aihu'. */
  readonly prefix?: string
  /** RESERVED for v2 multi-registry support — schema slot only, unimplemented. */
  readonly registries?: Readonly<Record<string, string>>
}

Configuration for the `@aihu/ui` styled-recipe registry, consumed by the `aihu add` / `aihu list` CLI subcommands and the css-engine scanner.

84

ApiHandler

type
type ApiHandler = (
  req: Request,
  ctx: import('./types.ts').RouteContext,
) => Response | Promise<Response>
85

BuildTarget

type
type BuildTarget = 'client' | 'server' | 'universal'

Build target for the aihu application.

86

ComponentDescription

type
type ComponentDescription = (() => unknown) | { toHtml(): string }

Accepts: 1.

87

CrawlerTier

type
type CrawlerTier = 'searcher' | 'user-fetcher' | 'training-crawler'

The three declared-crawler tiers of the unified bot registry.

88

CrawlerTierAccess

type
type CrawlerTierAccess = Readonly<Record<CrawlerTier, boolean>>

Per-tier crawl access derived from a `read` value.

89

Entitled

type
type Entitled<T> = T & { readonly $gx: { readonly entitled: true } }

The granted shape: the declared type plus the reserved `$gx` discriminant.

90

EntitledPrincipal

type
type EntitledPrincipal
91

EntitlementMemo

type
type EntitlementMemo
92

EntitlementsHandle

type
type EntitlementsHandle
93

EntitlementVerdict

type
type EntitlementVerdict
94

GeneratedLoader

typeagent
type GeneratedLoader<T> = (ctx: GovernedLoadContext) => Promise<GovernedEmission<T>>

The generated loader — what the framework materializes per governed route.

95

GovernedEmission

typeagent
type GovernedEmission<T> =
  | { readonly kind: 'granted'; readonly data: Entitled<T> }
  | {
      readonly kind: 'withheld'
      readonly data: Withheld<T>
      readonly decision: EmissionDecision
    }
  /** Provider failed AFTER grant (§4.3): an error state, never a locked state. */
  | { readonly kind: 'error'; readonly status: 500 }

What the generated loader emits (§3.1).

96

HttpMethod

type
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'
97

LoaderFn

type
type LoaderFn<T> = (ctx: RouteContext) => Promise<T>
98

Middleware

type
type Middleware = (req: Request, next: Next) => Response | Promise<Response>
99

NativeState

type
type NativeState =
  | { kind: 'native-loaded'; addon: NativeAddon; descriptor: PlatformDescriptor }
  | { kind: 'edge-skipped' }
  | { kind: 'native-failed-loud'; descriptor: PlatformDescriptor; error: Error }
  | { kind: 'unsupported-platform' }
100

Next

type
type Next = () => Promise<Response>
101

NormalizedReadValue

type
type NormalizedReadValue =
  | 'all'
  | 'agents'
  | 'search'
  | 'none'
  | 'verified'
  | 'human'
  | { readonly scope: string }
  | 'malformed'

The normalized `read` value.

102

Principal

type
type Principal
103

PrincipalGateDeps

type
type PrincipalGateDeps
104

PrincipalSource

type
type PrincipalSource
105

RenderingMode

type
type RenderingMode = 'ssr' | 'spa' | 'hybrid'

Runtime rendering strategy for the application.

106

RouteHandler

type
type RouteHandler = (req: Request, ctx: RouteContext) => Response | Promise<Response>
107

StreamRouteHandler

type
type StreamRouteHandler = (req: Request) => Promise<ReadableStream<string>>
108

SubrouteTuple

type
type SubrouteTuple =
  | readonly [string, RouteHandler]
  | readonly [string, RouteHandler, RouteOptions<never>]

A subroute tuple for use with the prefix-group overload of `defineRoute`.

109

Withheld

type
type Withheld<T> = {
  readonly $gx: {
    readonly entitled: false
    readonly reason: WithheldReason
  }
  readonly preview?: Partial<T>
}

The withheld shape: NO field of `T` beyond the declared `preview:` subset.

110

WithheldReason

type
type WithheldReason = 'auth' | 'scope' | 'entitlement' | 'unavailable'

Why a withheld response is withheld — the template's "sign in" vs "upgrade" vs "try later".