/**
 * Generated by scripts/gen-cordis-api.ts — do not edit by hand; run
 * `pnpm run gen-cordis-api` to regenerate (freshness-gated by
 * `pnpm run verify-cordis-api` in doc-sync).
 *
 * The machine-readable cordis API catalog `cordis_inspect` serves to the
 * model: harness services (summary + public method signatures/JSDoc),
 * harness events (mode + signature/JSDoc), and the inherited `ctx` surface. Produced by
 * the same AST walk as docs/cordis-catalog, so this data and the rendered
 * docs cannot diverge.
 *
 * @module @deepseek-ai/dsh-tool-cordis/api-catalog
 */

/** One public service method and its source-owned contract. */
export interface ServiceApiMethod {
  /** Public method signature with its body stripped. */
  signature: string
  /** Original method JSDoc, with only container indentation removed. */
  jsDoc: string
}

/** One harness `ctx.<key>` service: its one-line summary and public methods. */
export interface ServiceApiEntry {
  /** The `ctx.<key>` name, e.g. `tools`. */
  key: string
  /** First sentence of the service class JSDoc. */
  summary: string
  /** Public methods, bodies stripped, in source order. */
  methods: readonly ServiceApiMethod[]
}

/** One harness event: its dispatch mode, exact signature, and one-line summary. */
export interface EventApiEntry {
  /** The scoped event name, e.g. `agent/status`. */
  name: string
  /** The dispatch mode from the declaration's `@mode` tag. */
  mode: string
  /** The exact listener signature, whitespace-normalized. */
  signature: string
  /** Original event JSDoc, with only container indentation removed. */
  jsDoc: string
  /** First sentence of the event JSDoc. */
  summary: string
}

/** One inherited (cordis core + loader/hmr/timer) `ctx` member group with its summary. */
export interface InheritedApiEntry {
  /** The `ctx` member name(s), e.g. `ctx.on / ctx.once`. */
  name: string
  /** One-line summary of what the member does. */
  summary: string
}

/** One named type shape the service signatures reference. */
export interface TypeApiEntry {
  /** The exported type/interface name, e.g. `BashRunResult`. */
  name: string
  /** The full declaration text, comments stripped. */
  declaration: string
}

/** Every harness `ctx.<key>` service, sorted by key. */
export const SERVICE_API: readonly ServiceApiEntry[] = [
  {
    key: 'agentLoop',
    summary: 'Concrete agent factory and driver service.',
    methods: [
      {
        signature: 'create(id: SessionId, options: AgentOptions = {}, meta: Pick<SessionHeader, \'cwd\'> = {}): Agent',
        jsDoc: '/**\n * Create an agent and session under one caller-supplied identity, owned by\n * the accessing fiber. Constructor-driven config calls mint a fresh combined\n * id before entering this boundary.\n * @param id - shared agent/session identity.\n * @param options - concrete loop options.\n * @param meta - optional fresh-session workspace metadata.\n * @returns the published running agent.\n */',
      },
      {
        signature: 'async createAgent(ownerCtx: Context, options: CreateAgentOptions): Promise<AgentHandle>',
        jsDoc: '/**\n * Create an owned agent on a caller-supplied session id.\n * @param ownerCtx - caller context that structurally owns the lifecycle.\n * @param options - identities, session seed/metadata, loop options, setup, and cancellation.\n * @returns the published handle.\n */',
      },
      {
        signature: 'async resume(ownerCtx: Context, options: ResumeAgentOptions): Promise<AgentHandle>',
        jsDoc: '/**\n * Resume an owned agent from the configured persistence service.\n * @param ownerCtx - caller context that owns load, setup, and the live lifecycle.\n * @param options - persisted identity, loop options, setup, and cancellation.\n * @returns the published handle.\n */',
      },
    ],
  },
  {
    key: 'agents',
    summary: 'Agent service (`ctx.agents`): tracks live agents and carries the initiating Agent through one process-local asynchronous driver chain.',
    methods: [
      {
        signature: 'currentInitiator(): Agent | undefined',
        jsDoc: '/**\n * Read the Agent that initiated the inherited asynchronous driver chain.\n * Use this optional form for logging, tracing, metrics, or host attribution\n * that also supports agentless calls. When a parent creates a child, setup\n * reports the causal parent while `agentCtx.agent` identifies the child.\n * @returns the inherited Agent, or `undefined` outside an initiator boundary\n *   and inside an explicit clearing boundary.\n * @throws when this service instance has been disposed.\n */',
      },
      {
        signature: 'requireInitiator(): Agent',
        jsDoc: '/**\n * Read the initiating Agent and fail when no initiator boundary is active.\n * Use this for private helpers contractually below a driver, or for a\n * deployment-owned outbound request whose contract forbids agentless calls.\n * Generic or direct-call seams use optional lookup or explicit request fields.\n * @returns the inherited Agent.\n * @throws when no initiator is active or this service instance has been disposed.\n */',
      },
      {
        signature: 'withInitiator<T>(agent: Agent, operation: () => T): T',
        jsDoc: '/**\n * Run an operation with one exact Agent as its process-local initiator. The\n * exact synchronous value or Promise returned by the operation is preserved.\n * Custom drivers and test harnesses wrap their complete returned foreground\n * lifetime.\n * A queue or wire receiver may establish this boundary only after validating\n * explicit identity and resolving the exact live Agent; this method does neither.\n * Detached work remains owned by the subsystem that starts it.\n * @param agent - initiating Agent to inherit; presence is neither liveness proof nor authorization.\n * @param operation - synchronous or asynchronous operation to invoke.\n * @returns the exact value returned by `operation`.\n * @throws when the initiator scope is closing/disposed, or when `operation` throws.\n */',
      },
      {
        signature: 'withoutInitiator<T>(operation: () => T): T',
        jsDoc: '/**\n * Run an operation inside a boundary that hides any inherited initiating\n * Agent. The exact synchronous value or Promise is preserved.\n * Use this while creating lazy shared timers, queue pumps, pool maintenance,\n * watchers, or exporters so they do not inherit the first Agent that happens\n * to initialize them. It clears only initiator attribution, not explicit\n * fields, and does not own or drain detached resources.\n * @param operation - synchronous or asynchronous operation to invoke without an initiator.\n * @returns the exact value returned by `operation`.\n * @throws when the initiator scope is closing/disposed, or when `operation` throws.\n */',
      },
      {
        signature: 'setFactory(factory: AgentFactory): () => void',
        jsDoc: '/**\n * Register the agent-creation factory (the loop calls this on construction,\n * effect-scoped). A traced Cordis service is canonicalized to its concrete\n * target; each create/resume call is then traced through that caller\'s\n * context so ownership follows the caller without stacking proxy layers.\n * Throws if a factory is already registered. Returns the disposer; on\n * dispose the factory slot is cleared.\n * @param factory - the loop-owned factory {@link create}/{@link resume} delegate to.\n * @returns the disposer that clears the factory slot. The exact\n *   Cordis effect disposer (single-shot): composite (generator) effects may\n *   yield it directly — exact identity nests the teardown in order.\n */',
      },
      {
        signature: 'async create(options: CreateAgentOptions): Promise<AgentHandle>',
        jsDoc: '/**\n * Create and publish a new agent through the registered factory.\n * Distinct from {@link register} (which records an already-constructed\n * agent): this constructs the agent and its session. Rejects if no factory is\n * registered or creation/setup fails. The resolved {@link AgentHandle} lets\n * the owner tear down exactly this agent.\n * @param options - shared identity, session seed/metadata, and agent options.\n * @returns the handle after setup, rollback-covered publication, and loop start complete.\n */',
      },
      {
        signature: 'async resume(options: ResumeAgentOptions): Promise<AgentHandle>',
        jsDoc: '/**\n * Load a persisted session and resume an agent on it through the registered\n * factory. Rejects if no factory is registered; the factory rejects if\n * session persistence is not configured or persistence/setup fails.\n * @param options - persisted identity, configuration, and optional setup.\n * @returns the handle after setup, rollback-covered publication, and loop start complete.\n */',
      },
      {
        signature: 'register(agent: Agent): () => void',
        jsDoc: '/**\n * Register a live agent. Throws if an agent with the same id is already\n * registered. Emits `agent/created` on registration and `agent/disposed`\n * when the calling fiber is disposed — both with the agent\'s scope carrier\n * (`scopeTarget(agent, agent)`): the subject is the agent in hand, so the\n * emits are scope-filtered regardless of which context invoked `register`\n * (calling through `agent.ctx` scopes EFFECTS; dispatch scoping always\n * requires passing the carrier). Returns the disposer.\n * @param agent - the already-constructed agent to record in the store.\n * @returns the EXACT Cordis effect disposer (single-shot; a repeat call\n *   returns undefined without awaiting an in-flight teardown). Exact\n *   identity is load-bearing: a composite (generator) effect that owns a\n *   teardown ORDER — the agent factory\'s lifecycle chain — must yield THIS\n *   function so Cordis nests the unregistration at that yield position;\n *   yielding a wrapper would leave it disposing as a concurrent sibling on\n *   owner unload, unregistering the agent (and emitting `agent/disposed`)\n *   while its final turn is still draining.\n */',
      },
      {
        signature: 'enter(agent: Agent, owner: Agent | undefined): () => void',
        jsDoc: '/**\n * Insert an already-constructed agent without announcing it. This is the\n * advanced ordered-lifecycle primitive used by the async agent factory: it\n * first completes setup while the agent is unpublished, then assigns the\n * returned detach closure into its pre-installed composite teardown before\n * calling {@link announce}. Ordinary callers use {@link register}.\n * @param agent - the prepared, unpublished agent.\n * @param owner - live agent whose scoped context created this agent, or\n *   undefined for a top-level runtime root. This is runtime ownership, not\n *   the resumed session\'s durable parent lineage.\n * @returns an idempotent closure that removes this exact entry and emits\n *   `agent/disposed` with listener failures contained. When called from a\n *   synchronous `agent/created` listener, removal and disposal wait until\n *   that creation dispatch unwinds.\n */',
      },
      {
        signature: 'announce(agent: Agent): void',
        jsDoc: '/**\n * Announce an agent previously inserted with {@link enter}.\n * @param agent - the live inserted agent to announce.\n * @throws if `agent` is not the exact live registry entry for its id, or its\n *   creation announcement already began (including a reentrant call from a\n *   creation listener).\n */',
      },
      {
        signature: 'get(id: SessionId): Agent | undefined',
        jsDoc: '/**\n * Look up a live agent.\n * @param id - the shared agent/session id to look up.\n * @returns the agent, or undefined when no live agent has that id.\n */',
      },
      {
        signature: 'isOwnedBy(id: SessionId, owner: Agent): boolean',
        jsDoc: '/**\n * Test whether a live agent was created through one exact parent agent\'s\n * scoped context. Runtime ownership is independent of durable session\n * lineage and remains unambiguous when unrelated providers reuse an id.\n * @param id - the candidate child agent\'s shared agent/session id.\n * @param owner - the expected runtime creator agent.\n * @returns true only while the exact child entry is live under that owner.\n */',
      },
      {
        signature: 'list(): Agent[]',
        jsDoc: '/**\n * All live agents, in registration order.\n * @returns a fresh array; mutating it does not affect the registry.\n */',
      },
      {
        signature: 'roots(): Agent[]',
        jsDoc: '/**\n * All live top-level agents in registration order. A top-level agent was\n * created without an owning agent context; durable session lineage does not\n * affect this runtime relation, so a resumed fork may still be a root.\n * @returns a fresh array; mutating it does not affect the registry.\n */',
      },
    ],
  },
  {
    key: 'approval',
    summary: 'Approval service that applies session policy before answerers and logs every ask/outcome pair to the requesting session.',
    methods: [
      {
        signature: 'async request(req: ApprovalRequest): Promise<ApprovalOutcome>',
        jsDoc: '/**\n * Ask the composed answerers to decide one readonly same-process request.\n * The service borrows the request, agent, session, and live signal directly.\n * The request requires an open turn because the audit pair must be enclosed\n * by the durable log\'s commit/replay boundary; an idle ask rejects before\n * appending anything. The answerer phase always produces an outcome: an\n * aborted signal yields `\'cancelled\'`, a missing or throwing answerer yields\n * `\'unavailable\'` (fail closed), and a rogue non-vocabulary return value is\n * normalized to `\'unavailable\'`. A failure that prevents either audit append\n * from committing still rejects because returning an unlogged decision would\n * violate the pair. Session contains post-commit observer failures, so an\n * authoritative append cannot reject the request or suppress its matching\n * audit event.\n * @param req - the pending decision (agent, tool identity, reason, signal).\n * @returns the closed outcome; `\'allowed-once\'` is the only grant.\n * @throws when no turn is open or either audit event fails before the session\n *   append commit point.\n */',
      },
      {
        signature: 'overrideOf(session: Session): ApprovalPolicy | undefined',
        jsDoc: '/**\n * Read the session override without applying the configured default.\n * @param session - session whose log supplies the override.\n * @returns the last logged policy, or `undefined` without one.\n */',
      },
    ],
  },
  {
    key: 'bash',
    summary: 'Abstract bash execution service.',
    methods: [
      {
        signature: 'abstract resolve(request: BashExecRequest): BashExecSpec',
        jsDoc: '/**\n * Apply implementation-owned defaults and caps to a request before execution.\n * @param request - the caller\'s request; omitted fields get this\n *   implementation\'s defaults, capped fields are clamped.\n * @returns the fully-specified spec to hand to {@link run}/{@link start}.\n */',
      },
      {
        signature: 'abstract run(spec: BashExecSpec): Promise<BashRunResult>',
        jsDoc: '/**\n * Run a command in the foreground; resolves when it finishes.\n * @param spec - a resolved spec from {@link resolve}, never a raw request.\n * @returns the outcome; nonzero exits, timeout kills, and abort kills\n *   resolve with a descriptive result rather than reject.\n */',
      },
      {
        signature: 'abstract start(spec: BashExecSpec): BashProcess',
        jsDoc: '/**\n * Start a background process and return its handle immediately.\n * @param spec - a resolved spec from {@link resolve}, never a raw request.\n * @returns the live process handle (reads, kill, quiescence promise).\n */',
      },
    ],
  },
  {
    key: 'bashEnv',
    summary: 'Registry (`ctx.bashEnv`) for trusted, per-execution `DSH_*` variables.',
    methods: [
      {
        signature: 'register(contributor: BashEnvContributor): () => void',
        jsDoc: '/**\n * Register one environment contributor. Names and keys are unique; built-in\n * keys are reserved. Registration is disposed with the calling plugin fiber.\n * @param contributor - declared key ownership and per-execution resolver.\n * @returns the disposer that unregisters the contribution.\n */',
      },
      {
        signature: 'collect(execution: ToolExecution): DshEnvironment',
        jsDoc: '/**\n * Build the trusted `DSH_*` snapshot for one bash tool execution.\n * @param execution - the current tool execution.\n * @returns an immutable environment overlay containing built-ins and current contributions.\n */',
      },
      {
        signature: 'list(): BashEnvVariableInfo[]',
        jsDoc: '/**\n * Enumerate plugin-contributed variables without executing their resolvers.\n * @returns declarations sorted by environment variable name.\n */',
      },
    ],
  },
  {
    key: 'clientModuleHost',
    summary: 'The web plugin table service: incremental dshClient scan + wire composition + bundle route + index tap.',
    methods: [
      {
        signature: 'graph(): WebBootGraph',
        jsDoc: '/**\n * Current composed entry graph (stable object between changes).\n * @returns the graph served as `window.__DSH_BOOT__`.\n */',
      },
      {
        signature: 'clientPath(id: string): string | undefined',
        jsDoc: '/**\n * Absolute path of an entry\'s client bundle.\n * @param id - entry id (package name).\n * @returns the path, or undefined for an unknown id.\n */',
      },
      {
        signature: 'rebuilt(id: string): string | undefined',
        jsDoc: '/**\n * Re-hash one bundle (the HMR watch\'s registration hook — the only entry\n * point through which bundle content changes reach the graph).\n * @param id - entry id (package name).\n * @returns the new rev, or undefined for an unknown id.\n */',
      },
      {
        signature: 'onRebuilt(listener: (id: string, rev: string) => void): () => void',
        jsDoc: '/**\n * Subscribe to bundle rebuilds; fires only when the re-hash changed the rev.\n * @param listener - receives the entry id and its new bundle rev.\n * @returns the unsubscriber.\n */',
      },
      {
        signature: 'onGraphChanged(listener: () => void): () => void',
        jsDoc: '/**\n * Fires after any flush that recomposed the graph (row added/removed, or a\n * rebuilt rev change). Pull model: listeners re-read {@link graph}.\n * @param listener - notified with no payload.\n * @returns the unsubscriber.\n */',
      },
    ],
  },
  {
    key: 'codeRuntime',
    summary: 'Registers one `ctx.codeRuntime` implementation.',
    methods: [
      {
        signature: 'abstract run(request: CodeRunRequest): Promise<CodeRunResult>',
        jsDoc: '/**\n * Execute one program against the request\'s bindings and capture what it\n * emitted. See the class doc for the resolution contract (error is a result\n * field; rejection means seam misuse only).\n * @param request - the program, its bindings, and the abort signal; the\n *   request carries everything the runtime acts on, with no hidden defaults.\n * @returns the run\'s outcome: completion value (when transferable), the\n *   ordered log capture, and the failure (if any).\n */',
      },
    ],
  },
  {
    key: 'commands',
    summary: 'Human-command registry.',
    methods: [
      {
        signature: 'register(definition: CommandDefinition): () => void',
        jsDoc: '/**\n * Register a global or calling-agent-scoped command.\n * @param definition - discovery metadata and direct UI handler.\n * @returns the exact effect disposer that unregisters this definition.\n */',
      },
      {
        signature: 'list(agent: Agent): readonly CommandDescriptor[]',
        jsDoc: '/**\n * List the effective immutable command descriptors for one agent.\n * @param agent - exact receiving agent and scoped-layer key.\n * @returns name-sorted descriptors after scoped shadowing.\n */',
      },
      {
        signature: 'find(agent: Agent, name: string): CommandDefinition | undefined',
        jsDoc: '/**\n * Resolve one effective command definition.\n * @param agent - exact receiving agent and scoped-layer key.\n * @param name - command name without a slash.\n * @returns the scoped shadow or global definition.\n */',
      },
      {
        signature: 'async execute( agent: Agent, line: string, signal: AbortSignal, ): Promise<CommandExecution | undefined>',
        jsDoc: '/**\n * Parse and execute a known command without sending it to the model.\n *\n * A resolved command\'s lifecycle is logged: `command/run` is appended\n * before the handler is invoked and `command/done` after settlement (a\n * thrown or aborted handler settles as `kind: \'error\'`). Both are direct\n * log-only appends — no turn wraps them, and persistence drains them at\n * ordinary checkpoints. Admission misses (syntax or unknown name) log\n * nothing — they never entered a handler. A `command/run` append failure\n * fails the execution loud; a `command/done` append failure on the\n * handler-failure path is contained so the handler\'s own error stays the\n * reported failure.\n *\n * @param agent - exact receiving agent.\n * @param line - complete slash-command line.\n * @param signal - cancellation signal owned by the UI request.\n * @returns the settled execution (result + lifecycle pairing id), or\n *   `undefined` when syntax or name does not resolve.\n */',
      },
    ],
  },
  {
    key: 'compact',
    summary: 'Abstract compaction service.',
    methods: [
      {
        signature: 'abstract compactIfNeeded( agent: CompactAgentContext, trigger: CompactionTrigger, signal: AbortSignal, ): Promise<CompactionResult | null>',
        jsDoc: '/**\n * Consider automatic compaction for one explicit trigger. Pressure policy\n * uses the latest durable routed request, while context-overflow policy may\n * force a useful balanced reduction even below the normal threshold. Return\n * `null` when no safe range can be compacted. A single oversized retained\n * unit or request envelope cannot be repaired through surface compaction.\n *\n * @param agent - agent context owning the session surface and routing options.\n * @param trigger - normal pressure or provider-confirmed context overflow.\n * @param signal - cancellation signal; model-backed implementations must forward it.\n * @returns the compaction result, or `null` if no compaction was needed.\n */',
      },
      {
        signature: 'abstract compactRegion( start: number, end: number, agent: CompactAgentContext, signal?: AbortSignal, ): Promise<CompactionResult>',
        jsDoc: '/**\n * Forcibly compact a range of surface nodes into a single summary node.\n * `start` and `end` name an inclusive span by surface position, not numeric seq\n * order; replacements can make visible seqs non-monotonic. Both edges must be\n * balanced so assistant tool calls remain paired with their results. A model-\n * backed implementation forwards cancellation and rejects active, missing,\n * reversed, or unbalanced ranges. The target session is `agent.session`.\n * Its replacement user message must use {@link COMPACT_CHECKPOINT_SOURCE}.\n * Use {@link toolPairingBalancedBefore} and {@link toolPairingBalancedAfter}\n * for the edge checks.\n *\n * @param start - first surface seq, inclusive.\n * @param end - last surface seq, inclusive.\n * @param agent - context whose session is mutated and whose routing options guide summarization.\n * @param signal - optional cancellation; model-backed implementations must forward it.\n * @throws when compaction is active or the range is missing, reversed, or unbalanced.\n * @returns the appended event seqs, summary, replaced range, and token accounting.\n */',
      },
    ],
  },
  {
    key: 'fs',
    summary: 'Abstract filesystem provider.',
    methods: [
      {
        signature: 'abstract resolve(path: string, opts?: { cwd?: string; signal?: AbortSignal }): Promise<FsTarget>',
        jsDoc: '/**\n * Resolve a model/plugin-supplied path into a stable {@link FsTarget}. May perform I/O (a\n * remote/sandboxed backend may need a round-trip to map a path to a stable identity), hence\n * async even though the local backend only normalizes + realpaths.\n *\n * @param path - the path to resolve; relative paths resolve against `opts.cwd`.\n * @param opts - optional cwd override and cancellation signal.\n * @returns the stable target; the same file yields the same `targetKey`.\n */',
      },
      {
        signature: 'abstract stat(target: FsTarget, signal?: AbortSignal): Promise<FsInfo | undefined>',
        jsDoc: '/**\n * Return target metadata, or `undefined` when the target does not exist.\n * @param target - the resolved target to stat.\n * @param signal - aborts the metadata round-trip.\n * @returns metadata only, never content; undefined for an absent target.\n */',
      },
      {
        signature: 'abstract lstat(path: string, opts?: { cwd?: string }, signal?: AbortSignal): Promise<FsPathInfo | undefined>',
        jsDoc: '/**\n * Return path metadata without following the final path component when it is a\n * symbolic link. This is intentionally path-shaped, not target-shaped:\n * {@link resolve} follows symlinks to produce the stable identity used by\n * normal reads/writes, while `lstat` lets a consumer reject the path itself\n * before that follow happens.\n *\n * `opts.cwd` follows {@link resolve}\'s cwd rules. `undefined` means the path is\n * absent.\n * @param path - the path to inspect; relative paths resolve against `opts.cwd`.\n * @param opts - `cwd` overrides the backend\'s default base for relative paths.\n * @param signal - aborts the metadata round-trip.\n * @returns metadata only, never content; undefined for an absent path.\n */',
      },
      {
        signature: 'abstract readText(target: FsTarget, signal?: AbortSignal): Promise<string>',
        jsDoc: '/**\n * Read the whole regular text file as a single decoded string.\n * @param target - the resolved target to read.\n * @param signal - aborts the read.\n * @returns the full decoded UTF-8 content.\n */',
      },
      {
        signature: 'abstract streamText(target: FsTarget, signal?: AbortSignal): Promise<AsyncIterable<string>>',
        jsDoc: '/**\n * Stream the whole regular text file as decoded text chunks (same text\n * semantics as {@link readText}, for large files). The backend owns\n * cross-chunk UTF-8 decoding and binary rejection so the policy layer never\n * touches raw bytes.\n * @param target - the resolved target to read.\n * @param signal - aborts the stream, including between chunks.\n * @returns the chunk iterable, decoded and validated like {@link readText}.\n */',
      },
      {
        signature: 'abstract listDir(target: FsTarget, signal?: AbortSignal): Promise<FsDirEntry[]>',
        jsDoc: '/**\n * List direct children of a directory in stable name order. Returns resolved\n * child targets plus cheap metadata only; never reads file contents.\n * @param target - the resolved directory target.\n * @param signal - aborts the listing.\n * @returns one entry per direct child, in stable name order.\n */',
      },
      {
        signature: 'abstract writeText( target: FsTarget, content: string, expected?: FsWriteIntent, signal?: AbortSignal, sandboxPolicy?: SandboxExecutionPolicy, ): Promise<FsWriteOutcome>',
        jsDoc: '/**\n * Atomically create or replace UTF-8 text. `expected` guards intent and\n * staleness; omission allows unconditional overwrite.\n * @param target - the resolved target to write.\n * @param content - the full new file content.\n * @param expected - the write intent guarding the write; omit for unconditional.\n * @param signal - aborts before the atomic rename takes effect.\n * @param sandboxPolicy - the per-call mode and workspace root this write\n *   runs under; a sandboxing backend fences the write by it, the bare backend\n *   ignores it. Omit to leave the backend its own default.\n * @returns the outcome, including the version the write produced.\n */',
      },
      {
        signature: 'abstract editText( target: FsTarget, edit: FsEditRequest, expected?: { version: FsVersion }, signal?: AbortSignal, sandboxPolicy?: SandboxExecutionPolicy, ): Promise<FsEditOutcome>',
        jsDoc: '/**\n * Atomically edit literal text. When supplied, the version guard is checked\n * before matching so stale content reports `FS_STALE_VERSION`; omission edits\n * the current content without a freshness precondition.\n * @param target - the resolved target to edit.\n * @param edit - the literal search/replace request.\n * @param expected - the version guard; omit for an unconditional edit.\n * @param signal - aborts before the atomic rename takes effect.\n * @param sandboxPolicy - the per-call mode and workspace root this edit runs\n *   under; a sandboxing backend fences the edit by it, the bare backend\n *   ignores it. Omit to leave the backend its own default.\n * @returns the outcome, including the version the edit produced.\n */',
      },
    ],
  },
  {
    key: 'goals',
    summary: 'Goal service (`ctx.goals`) backed exclusively by the owning session log.',
    methods: [
      {
        signature: 'get(agent: Agent): GoalView | undefined',
        jsDoc: '/**\n * Read the current goal for one exact live agent.\n * @param agent - owning live agent.\n * @returns a fresh view or `undefined` when no goal is current.\n * @throws {@link GoalError} when the agent is not the registry\'s live instance.\n */',
      },
      {
        signature: 'disarm(agent: Agent): GoalView | undefined',
        jsDoc: '/**\n * Remove process-local continuation authority without changing durable goal\n * phase or revision. Lifecycle owners use this before unloading a driver;\n * a later human-authorized {@link resume} records the new activation edge.\n * @param agent - owning live agent.\n * @returns a fresh disarmed view, or `undefined` when no goal is current.\n */',
      },
      {
        signature: 'create(agent: Agent, request: CreateGoalRequest): GoalView',
        jsDoc: '/**\n * Create and arm a goal. A completed goal may be replaced; every other\n * current phase must be cleared or resumed instead.\n * @param agent - owning live agent.\n * @param request - objective and optional round cap.\n * @returns the created live view.\n */',
      },
      {
        signature: 'edit(agent: Agent, ref: GoalRef, request: EditGoalRequest): GoalView',
        jsDoc: '/**\n * Edit objective and/or round cap without changing phase.\n * @param agent - owning live agent.\n * @param ref - expected current revision.\n * @param request - at least one replacement field.\n * @returns the edited view.\n */',
      },
      {
        signature: 'pause(agent: Agent, ref: GoalRef): GoalView',
        jsDoc: '/**\n * Pause an active goal and disarm automatic continuation.\n * @param agent - owning live agent.\n * @param ref - expected current revision.\n * @returns the paused view.\n */',
      },
      {
        signature: 'resume(agent: Agent, ref: GoalRef): GoalView',
        jsDoc: '/**\n * Resume and arm a stopped goal, or rearm an active goal after a\n * session-start edge, while its round budget still has capacity.\n * @param agent - owning live agent.\n * @param ref - expected current revision.\n * @returns the active view.\n */',
      },
      {
        signature: 'complete(agent: Agent, ref: GoalRef): GoalView',
        jsDoc: '/**\n * Mark a current non-complete goal complete and disarm it.\n * @param agent - owning live agent.\n * @param ref - expected current revision.\n * @returns the completed view.\n */',
      },
      {
        signature: 'block(agent: Agent, ref: GoalRef, reason: GoalBlockReason): GoalView',
        jsDoc: '/**\n * Mark an active goal blocked and disarm it.\n * @param agent - owning live agent.\n * @param ref - expected current revision.\n * @param reason - policy-owned stable code and human-readable explanation.\n * @returns the blocked view with its durable reason.\n */',
      },
      {
        signature: 'clear(agent: Agent, ref: GoalRef): GoalRef',
        jsDoc: '/**\n * Clear the current goal while retaining a durable tombstone and history.\n * @param agent - owning live agent.\n * @param ref - expected current revision.\n * @returns the tombstone ref whose revision is one past the cleared snapshot.\n */',
      },
    ],
  },
  {
    key: 'httpServer',
    summary: 'The web-shape HTTP carrier service.',
    methods: [
      {
        signature: 'register(route: WebRoute): () => void',
        jsDoc: '/**\n * Register a named route. Duplicate (kind, path) throws — route patterns are\n * a composition-level contract, so a collision is a misconfiguration.\n * @param route - kind, path, and the owning handler.\n * @returns the disposer removing the route.\n */',
      },
      {
        signature: 'tapIndex(transform: (html: string) => string): () => void',
        jsDoc: '/**\n * Register an index.html transform, applied to every index response in\n * registration order.\n * @param transform - pure html-to-html function.\n * @returns the disposer removing the transform.\n */',
      },
    ],
  },
  {
    key: 'invariants',
    summary: 'Package-owned invariant registry with global and regex-based selection.',
    methods: [
      {
        signature: 'register(packageName: string, installer: InvariantInstaller): () => void',
        jsDoc: '/**\n * Register one package\'s invariant installer. The package name is reserved\n * even when filtering disables its checks. Enabled installers run in a child\n * fiber; failure disposes that fiber and releases the reservation.\n * @param packageName - full npm package name that owns the contribution.\n * @param installer - listener or startup-check installer for the child context.\n * @returns an effect-scoped disposer for the registration.\n */',
      },
    ],
  },
  {
    key: 'llm',
    summary: 'The abstract `llm` service: an adapter registry plus a streaming model-call surface, interceptable via the `llm/stream` waterfall.',
    methods: [
      {
        signature: 'registerAdapter(providers: string[], adapter: LlmAdapter): () => void',
        jsDoc: '/**\n * Register an adapter for the given provider routes. Throws `LlmError` with code\n * `DUPLICATE_ADAPTER` if any provider already has an adapter (all-or-nothing).\n * Disposed with the fiber.\n * @param providers - every provider route this adapter should serve.\n * @param adapter - the adapter that streams calls for those providers.\n * @returns the disposer that unregisters all of them.\n */',
      },
      {
        signature: 'listProviders(): LlmProviderInfo[]',
        jsDoc: '/**\n * Describe provider routes with a registered adapter.\n * @returns detached provider metadata in registration order.\n */',
      },
      {
        signature: 'providerRetryPolicy(provider: string): ResolvedRetryPolicy',
        jsDoc: '/**\n * Resolve the retry policy captured when one provider route was registered.\n * @param provider - registered provider route to inspect.\n * @returns the provider-owned policy, with normal defaults already resolved.\n */',
      },
      {
        signature: 'async listModels(provider: string): Promise<LlmModelInfo[]>',
        jsDoc: '/**\n * Discover models advertised by one registered provider. Catalog membership\n * is advisory and never changes routing or request validation.\n * @param provider - registered provider route to inspect.\n * @returns detached model metadata in adapter-preferred order.\n */',
      },
      {
        signature: 'async resolveModelInfo( provider: string, model: string, signal?: AbortSignal, ): Promise<LlmResolvedModelInfo>',
        jsDoc: '/**\n * Resolve and validate all metadata from the adapter that owns one exact\n * route. The result is detached from adapter-owned objects; catalog\n * membership remains advisory and does not control request routing.\n * @param provider - registered provider route to inspect.\n * @param model - exact model id passed to the adapter.\n * @param signal - optional cancellation for adapter-owned asynchronous lookup.\n * @returns exact model identity plus available context and reasoning metadata.\n */',
      },
      {
        signature: 'async resolveCallConfig(config: LlmCallConfig, signal?: AbortSignal): Promise<LlmCallConfig>',
        jsDoc: '/**\n * Validate a conversation call config against its exact model capability and\n * materialize an adapter-configured default. Unsupported explicit efforts\n * reject before provider I/O; no clamping or aliasing is performed. This\n * standalone query does not bind a later dispatch; use {@link prepareCall}\n * when logging and streaming must share one adapter registration.\n * @param config - provider/model route and optional request controls.\n * @param signal - optional cancellation for adapter-owned capability lookup.\n * @returns a detached config only when a default must be materialized.\n */',
      },
      {
        signature: 'async prepareCall(config: LlmCallConfig, signal?: AbortSignal): Promise<PreparedLlmCall>',
        jsDoc: '/**\n * Resolve one call under its current adapter registration. The returned\n * one-shot handle keeps that registration across header logging and dispatch,\n * so HMR cannot combine one adapter\'s capability result with another adapter.\n * @param config - provider/model route and optional request controls.\n * @param signal - optional cancellation for adapter-owned capability lookup.\n * @returns a prepared config and its registration-bound stream entry point.\n */',
      },
      {
        signature: 'stream(options: GenerateOptions): AsyncIterable<StreamChunk>',
        jsDoc: '/**\n * Stream one model call as raw chunks (token-level deltas). Throws\n * `LlmError` with code `NO_ADAPTER` if no adapter is registered for\n * `options.provider`. Replay state is retained only when the same adapter\n * instance owns its historical provider and the target provider. Final\n * adapter selection remains fixed through asynchronous exact-model resolution\n * and dispatch. Selection, dispatch, and iteration failures retain their\n * original Error identity and are tagged in a call-local scope for narrow\n * agent-loop request recovery; middleware and nested-call failures remain\n * untagged for the outer call.\n * @param options - the full request; `options.provider` selects the adapter.\n * @returns the chunk stream, possibly wrapped by `llm/stream` listeners.\n */',
      },
    ],
  },
  {
    key: 'permission',
    summary: 'Owns the deployment\'s permission presets and their write path.',
    methods: [
      {
        signature: 'current(events: readonly SessionEvent[]): string',
        jsDoc: '/**\n * Resolve the preset matching the effective knob values. A still-matching\n * last selection wins shared-bundle ties; otherwise the first table match\n * wins, or {@link CUSTOM_PRESET} when no entry matches.\n * @param events - the session\'s events in log order.\n * @returns the effective preset name, or `custom` when nothing matches.\n */',
      },
      {
        signature: 'resolve(name: string): PresetSpec',
        jsDoc: '/**\n * Resolve a preset\'s knob bundle.\n * @param name - the preset name to resolve.\n * @returns the configured bundle.\n * @throws when `name` is not in the table.\n */',
      },
      {
        signature: 'optionOf(name: string): PresetOption',
        jsDoc: '/**\n * Build the client option for a table entry or {@link CUSTOM_PRESET}. A\n * missing label falls back to the table key.\n * @param name - a table key, or `custom`.\n * @returns the option a client renders.\n * @throws when `name` is neither a table key nor `custom`.\n */',
      },
      {
        signature: 'set(session: Session, name: string): void',
        jsDoc: '/**\n * Record a changed preset, then update each changed knob through its own\n * setter. Selecting the effective preset again appends nothing.\n * @param session - the session the switch belongs to.\n * @param name - the preset to switch to; unknown names throw.\n */',
      },
    ],
  },
  {
    key: 'planMode',
    summary: '`ctx.planMode`: owns logged plan state, boundary application and narration, the `plan:policy` section, the `/plan` command, and the stable exit tool.',
    methods: [
      {
        signature: 'get(agent: Agent): { active: boolean; pending?: boolean }',
        jsDoc: '/**\n * Read the logged plan state and any selected state awaiting a boundary.\n *\n * @param agent The agent to read.\n * @returns Current logged state plus a pending selection, when present.\n */',
      },
      {
        signature: 'set(agent: Agent, active: boolean): \'committed\' | \'queued\' | \'cancelled\' | \'noop\'',
        jsDoc: '/**\n * Select whether plan mode should be active. Between turns the change\n * commits immediately — no request boundary would arrive until the next\n * prompt, so a queued intent would hang (the open-turn fold is the idle\n * signal: agent status stays `running` through post-turn checkpointing,\n * where a boundary equally never comes). During an open turn the\n * selection is held as pending intent for the next in-turn request\n * boundary. Repeated selection of the current or already-pending state is\n * a no-op.\n *\n * @param agent The agent to switch.\n * @param active Whether plan mode should be active.\n * @returns what happened: `committed` (logged now), `queued` (awaiting the\n * next boundary), `cancelled` (an opposite pending selection was cleared;\n * the logged state already matches), or `noop` (already in that state).\n */',
      },
    ],
  },
  {
    key: 'pty',
    summary: 'In-process registry for replaceable PTY backends and exact-Agent sessions.',
    methods: [
      {
        signature: 'registerBackend(backend: PtyBackend): () => void',
        jsDoc: '/**\n * Register one backend type for this effect scope.\n * @param backend - provider with a non-empty unique type.\n * @returns disposer that removes exactly this contribution.\n */',
      },
      {
        signature: 'listBackends(): string[]',
        jsDoc: '/**\n * List registered backend types in registration order.\n * @returns fresh backend type names.\n */',
      },
      {
        signature: 'async spawn(owner: Agent, request: PtySpawnRequest, signal?: AbortSignal): Promise<PtySpawnResult>',
        jsDoc: '/**\n * Create and publish one owner-scoped session after backend setup succeeds.\n * @param owner - exact registered Agent that owns access and cleanup.\n * @param request - backend type plus optional owner-local name and cwd.\n * @param signal - cancellation of unpublished setup.\n * @returns published identity, metadata, status, and MOTD.\n */',
      },
      {
        signature: 'hasOwnerActivity(owner: Agent): boolean',
        jsDoc: '/**\n * Test whether an exact owner has a published session or unpublished spawn.\n * @param owner - exact live owner to inspect.\n * @returns true across the entire spawn-to-close interval, with no publication gap.\n */',
      },
      {
        signature: 'startSend(owner: Agent, id: PtySessionId, request: PtySendRequest): PtySendOperation',
        jsDoc: '/**\n * Start one exclusive interactive send.\n * @param owner - exact session owner.\n * @param id - target PTY identity.\n * @param request - explicit text, submit behavior, and cancellation.\n * @returns live operation handle for foreground await or task registration.\n */',
      },
      {
        signature: 'read(owner: Agent, id: PtySessionId, request: PtyReadRequest = {}): PtyReadResult',
        jsDoc: '/**\n * Read one bounded scrollback page from an owned session.\n * @param owner - exact session owner.\n * @param id - target PTY identity.\n * @param request - optional newest-relative offset and line count.\n * @returns bounded retained text and pagination metadata.\n */',
      },
      {
        signature: 'signal(owner: Agent, id: PtySessionId, signal: PtySignal): Promise<PtySignalResult>',
        jsDoc: '/**\n * Deliver an allowed signal through an owned backend session.\n * @param owner - exact session owner.\n * @param id - target PTY identity.\n * @param signal - allowed POSIX signal name.\n * @returns delivered foreground process-group identity.\n */',
      },
      {
        signature: 'async kill(owner: Agent, id: PtySessionId, reason = \'model request\'): Promise<boolean>',
        jsDoc: '/**\n * Close one owned session and remove it only after quiescent backend cleanup.\n * @param owner - exact session owner.\n * @param id - target PTY identity.\n * @param reason - diagnostic cleanup reason.\n * @returns true for a newly closed session, false when the same close is already in flight.\n */',
      },
      {
        signature: 'list(owner: Agent): PtySessionSnapshot[]',
        jsDoc: '/**\n * List fresh snapshots for exactly one owner.\n * @param owner - exact owner whose sessions are visible.\n * @returns owner-visible snapshots in publication order.\n */',
      },
    ],
  },
  {
    key: 'sandbox',
    summary: 'Abstract process-sandbox service.',
    methods: [
      {
        signature: 'abstract confine(argv: readonly string[], policy: SandboxPolicy): ConfinedArgv',
        jsDoc: '/**\n * Wrap `argv` so it executes confined under `policy` on this host; the\n * caller spawns the returned argv in place of its own.\n * @param argv - the exact argv the caller is about to spawn (program plus\n *   arguments), NOT a shell string — a shell-shaped consumer passes\n *   `[\'bash\', \'-c\', command]`.\n * @param policy - the file-effect policy this execution runs under,\n *   carried per call (see {@link SandboxPolicy}).\n * @returns the argv to spawn instead, plus the enforcement completeness\n *   the selected backend achieves for it.\n */',
      },
    ],
  },
  {
    key: 'sandboxPolicy',
    summary: 'The sandbox-policy service (`ctx.sandboxPolicy`).',
    methods: [
      {
        signature: 'resolve(request: SandboxPolicyRequest = {}): SandboxExecutionPolicy',
        jsDoc: '/**\n * Resolve the complete policy for one capability call. An approved explicit\n * mode outranks the session\'s last `sandbox/mode` event, which outranks the\n * deployment default. A session cwd is its workspace-write boundary; the\n * configured root is the fallback for agentless calls and sessions without a\n * cwd.\n * @param request - optional session and approved mode override.\n * @returns the fully resolved per-call mode and absolute workspace root.\n */',
      },
      {
        signature: 'overrideOf(session: Session): SandboxMode | undefined',
        jsDoc: '/**\n * Read the session override without applying the deployment default.\n * @param session - session whose log supplies the override.\n * @returns the last logged mode, or `undefined` without one.\n */',
      },
    ],
  },
  {
    key: 'sessionPersistence',
    summary: 'Durable append-only session storage.',
    methods: [
      {
        signature: 'abstract locate(meta: SessionHeader): SessionLocation | undefined',
        jsDoc: '/**\n * Resolve this backend\'s independent local artifact for a session without\n * reading, creating, flushing, or otherwise materializing it. Backends such\n * as SQLite that do not own one artifact per session return `undefined`.\n * @param meta - the immutable session header whose artifact is requested.\n * @returns the backend-specific absolute location, when one exists.\n */',
      },
      {
        signature: 'abstract create(meta: SessionHeader): Promise<void>',
        jsDoc: '/**\n * Register a new session\'s metadata. A backend MAY defer the physical write\n * until the first {@link append} (lazy materialization), in which case a\n * created-but-never-appended session is absent from {@link list}\n * — abandoned sessions leave nothing behind.\n * @param meta - the immutable header (id, version, cwd, lineage) to record.\n */',
      },
      {
        signature: 'abstract append(id: SessionId, events: readonly SessionEvent[]): Promise<void>',
        jsDoc: '/**\n * Durably persist a batch of events. Honors the append-only and contiguous-\n * seq contracts: the first event\'s `seq` MUST equal the stored next-seq\n * (after `load` has durably closed any interrupted turn). Rejects non-JSON-\n * serializable `event.data` with an error naming the offending event type.\n * @param id - the session the batch belongs to.\n * @param events - the contiguous batch to persist, in seq order.\n */',
      },
      {
        signature: 'abstract load(id: SessionId): Promise<{ meta: SessionHeader; events: SessionEvent[] }>',
        jsDoc: '/**\n * Load a header and balanced contiguous log. A complete interrupted final\n * turn is preserved and durably closed with missing tool errors plus any open\n * step and turn boundaries; only a torn final record is discarded. Unknown\n * versions and corruption in the committed prefix reject. Implementations\n * MUST NOT crash-repair an identity still bound to a live Session: a balanced\n * live log may return with its stored header as a durable snapshot, while an\n * open live turn rejects.\n * A coordinator-backed cold load reserves the identity across storage awaits,\n * so concurrent publication of a same-id live Session rejects.\n * Returned events are detached, and every identified message is deeply\n * frozen. Coordinator-backed implementations upgrade supported pre-identity\n * message events before validation; other malformed messages reject before\n * any stored event is returned.\n * @param id - the persisted session to reload.\n * @returns the header and a log ending on a balanced `turn/end`.\n */',
      },
      {
        signature: 'abstract inspect(id: SessionId, signal?: AbortSignal): Promise<{ meta: SessionHeader; events: SessionEvent[] }>',
        jsDoc: '/**\n * Inspect a header and its valid contiguous stored prefix without repairing\n * a torn tail, closing an interrupted turn, or publishing coordinator state.\n * This read is serialized with writes for the same id and returns detached\n * values with upgraded, deeply frozen identified messages, so observers\n * cannot mutate message identity/content or backend-owned state. Other\n * malformed messages reject.\n * @param id - the persisted session to inspect.\n * @param signal - optional cancellation for queued and backend read work.\n * @returns the header and valid stored event prefix exactly as observed.\n */',
      },
      {
        signature: 'abstract readFrom(id: SessionId, fromSeq: number, signal?: AbortSignal): Promise<{ meta: SessionHeader; events: SessionEvent[] }>',
        jsDoc: '/**\n * Read the stored events from `fromSeq` onward — the read-from-seq\n * primitive for read models that resume from a watermark (e.g. a persisted\n * projection cache folding only the tail past its checkpoint). Like\n * {@link inspect} it is non-mutating and detached: no torn-tail truncation,\n * no synthetic closers, no coordinator-state publication; only events from\n * the valid contiguous stored prefix are returned, so a torn fragment never\n * reaches the caller. `fromSeq` at or beyond the stored prefix returns an\n * empty event list (never an error). Backends whose medium can seek by seq\n * (SQLite) read only the suffix; sequential media (JSONL, both encodings)\n * still parse the whole artifact and skip forward — the primitive bounds\n * what is RETURNED and refolded, not every backend\'s physical read.\n * @param id - the persisted session to read.\n * @param fromSeq - first event seq to include; a non-negative safe integer.\n * @param signal - optional cancellation for queued and backend read work.\n * @returns the header and the stored events with `seq >= fromSeq`.\n */',
      },
      {
        signature: 'abstract list(signal?: AbortSignal): Promise<SessionHeader[]>',
        jsDoc: '/**\n * Lightweight listing from metadata, without a full-log parse.\n * @param signal - optional cancellation for backend listing work.\n * @returns one header per materialized session.\n */',
      },
      {
        signature: 'abstract listSnapshots(signal?: AbortSignal): Promise<SessionPersistenceSnapshot[]>',
        jsDoc: '/**\n * List materialized sessions with cheap per-log change tokens.\n *\n * Repeated observations of an unchanged log return the same revision. A\n * successful mutating {@link load} repair changes the next listed revision.\n * Revisions also distinguish independently backed stores so backend-local\n * counters cannot compare equal across different persistence sources.\n * @param signal - optional cancellation for backend snapshot-listing work.\n * @returns one header and opaque revision per materialized session without loading full logs.\n */',
      },
    ],
  },
  {
    key: 'sessionProjectionCache',
    summary: 'The persisted projection cache service.',
    methods: [
      {
        signature: 'cachedSnapshot(meta: SessionHeader): ProjectionSnapshot | undefined',
        jsDoc: '/**\n * The zero-I/O listing read: whole values viewed straight from the stored\n * rows (version-matching keys only), each cut carried with its watermark\n * so a client value store can seed under its higher-seq-wins rule — as\n * stale as the last durable checkpoint but never wrong, and never from an\n * unrelated log (the caller\'s header is the identity witness). Fresher\n * paths (the history tail baseline, {@link coldSnapshot}) supersede these\n * values whenever a session is actually opened.\n * @param meta - the listed session\'s header (identity witness; no log read).\n * @returns the cut (`asOfSeq` = lowest served-row watermark), or\n *   `undefined` when no usable row exists for this lifecycle.\n */',
      },
      {
        signature: 'async write(session: Session): Promise<void>',
        jsDoc: '/**\n * Durably checkpoint one live session NOW (both mandatory points call\n * this; tests and carriers may too). The registry cut is snapshotted at\n * this boundary (states are live references), then the whole record is\n * replaced. NOT fail-soft — callers on the fail-soft paths contain it.\n * @param session - the live session to checkpoint.\n * @returns resolution after durability and event emission.\n */',
      },
      {
        signature: 'async coldSnapshot(id: SessionId, signal?: AbortSignal): Promise<ProjectionSnapshot>',
        jsDoc: '/**\n * Cold-read one persisted session\'s projections with zero full-log load:\n * cached rows + a persistence `readFrom` tail from the registry\'s restore\n * floor, refolded by the registry and written back (fail-soft) so the next\n * cold read starts closer. A cache row invalidated by a shrunk log\n * (crash-repair truncation) triggers one full re-read from seq 0 — the\n * ladder\'s slow rung, still no crash. Rejects when the session has no\n * persisted log (`not found` from the persistence seam).\n * @param id - the persisted session to read.\n * @param signal - optional cancellation for the persistence reads.\n * @returns the snapshot cut at the stored log end.\n */',
      },
    ],
  },
  {
    key: 'sessionProjections',
    summary: '`ctx.sessionProjections`: the projection unit table and its drive.',
    methods: [
      {
        signature: 'register<K extends keyof SessionProjectionMap, S>(definition: ProjectionDefinition<K, S>): () => void',
        jsDoc: '/**\n * Register one domain\'s unit. The registration is an effect on the calling\n * context\'s fiber: disposing the fiber (or calling the returned disposer)\n * removes the key — and the unit\'s cached cells — from subsequent drives\n * and snapshots.\n * @param definition - key, boundary schema, pure unit functions, and stateVersion.\n * @returns the exact disposer that unregisters this unit.\n */',
      },
      {
        signature: 'onChanged(listener: ProjectionChangeListener): () => void',
        jsDoc: '/**\n * Subscribe to the change feed. The registration is an effect on the\n * calling context\'s fiber.\n * @param listener - called once per unit whose state reference changed, per committed event.\n * @returns the exact disposer that unsubscribes.\n */',
      },
      {
        signature: 'snapshot(session: Session): ProjectionSnapshot',
        jsDoc: '/**\n * One consistent cut over every registered unit for one session, read from\n * the watermark cache (missing cells fold lazily over the in-memory log).\n * Fully synchronous — every value and `asOfSeq` reflect the same log\n * position. Each value passes its unit\'s schema before leaving.\n * @param session - the session whose projection values are read.\n * @returns the snapshot; `values` is empty when no unit is registered.\n */',
      },
      {
        signature: 'checkpoint(session: Session): ProjectionCheckpoint',
        jsDoc: '/**\n * State-level checkpoint of every registered unit for one session, read\n * from the watermark cache (missing cells fold lazily over the in-memory\n * log). This is the write side of the persisted projection cache: the\n * returned rows are the `(key → {ver, seq, val})` part of the durable\n * `(sessionId, key, ver, seq, val)`\n * rows. Every `val` is a DETACHED structured clone — never the live\n * cell reference: the watermark cache is this registry\'s authoritative\n * mutable state, and a caller reaching the live reference could corrupt\n * every subsequent snapshot and frame through it (plain JSON by the unit\n * contract, so the clone is total).\n * @param session - the session whose unit states are checkpointed.\n * @returns one row per registered key; empty when no unit is registered.\n */',
      },
      {
        signature: 'restoreFloor(checkpoint: ProjectionCheckpoint): number | undefined',
        jsDoc: '/**\n * The stored seq a {@link restore} tail read over `checkpoint` must start\n * at: one event BELOW the lowest usable watermark (a row is usable when\n * its `ver` matches the live unit\'s `stateVersion`; an absent or mismatched row\n * pulls the floor to `0` — that key must refold the full log). The\n * one-below anchor is load-bearing: the tail then proves how far the\n * stored log still extends, so {@link restore} can detect a log that\n * shrank below a row\'s watermark (crash-repair truncation) instead of\n * serving the stale row as current — an empty tail read from the anchor\n * yields an end below every watermark and the restore rejects for a full\n * re-read.\n * @param checkpoint - persisted rows for one session (possibly stale or empty).\n * @returns the seq to hand the persistence `readFrom`, or `undefined`\n *   when no unit is registered (no read needed — {@link restore} would\n *   serve empty values regardless).\n */',
      },
      {
        signature: 'viewCheckpoint(checkpoint: ProjectionCheckpoint): Partial<SessionProjectionMap>',
        jsDoc: '/**\n * View a checkpoint\'s rows without any log read: for every registered\n * unit whose row\'s `ver` matches, serve the schema-validated\n * `view` of the stored state; mismatched or absent rows leave their key\n * absent (a cold or listing consumer treats it as not-yet-available and a\n * fuller read path refolds it). The zero-I/O rung of the read ladder —\n * values are as stale as their rows, never wrong.\n * @param checkpoint - persisted rows for one session (possibly stale or empty).\n * @returns whole values per key with a usable row; empty when none.\n */',
      },
      {
        signature: 'restore(checkpoint: ProjectionCheckpoint, events: readonly SessionEvent[], baseSeq: number): { snapshot: ProjectionSnapshot; checkpoint: ProjectionCheckpoint }',
        jsDoc: '/**\n * Cold read: fold every registered unit over a stored log suffix, seeding\n * each from its checkpoint row when usable — the one read recipe (cached\n * state + forward tail replay + `view`) applied without a live `Session`.\n * Call with the events returned by a persistence\n * `readFrom(id, restoreFloor(checkpoint))` and that same floor as\n * `baseSeq`; the floor\'s one-below anchor makes the supplied end honest,\n * so a shrunk log is detected here. A row is usable iff its\n * `ver` matches the live unit\'s `stateVersion`, it does not predate `baseSeq`\n * (`seq >= baseSeq - 1`), and it does not claim events past the\n * supplied end (`seq <= endSeq`); an unusable row is discarded\n * and its key refolds from `init` — which is only sound over the full\n * log, so a discarded row with `baseSeq > 0` throws (the caller re-reads\n * from seq 0, e.g. after a crash-repair truncation shrank the log below\n * a row\'s watermark).\n * @param checkpoint - persisted rows for one session (possibly stale or empty).\n * @param events - the stored events with `seq >= baseSeq`, in seq order.\n * @param baseSeq - the seq `events` starts at (its first event\'s seq when non-empty).\n * @returns the snapshot cut at the supplied log end (`asOfSeq` is the last\n *   supplied event\'s seq, `baseSeq - 1` for an empty tail) plus the\n *   refreshed checkpoint rows at that cut, ready for a durable write-back.\n */',
      },
    ],
  },
  {
    key: 'sessionQuery',
    summary: 'Unified live-preferred session query service.',
    methods: [
      {
        signature: 'abstract searchSessions( request: SessionSearchRequest, exec?: SessionSearchExecContext, ): Promise<SessionSearchPage<SessionSearchHit>>',
        jsDoc: '/**\n * Search the live-preferred logical corpus and group by session.\n * @param request - query text, metadata filters, page size, and cursor.\n * @param exec - optional cancellation control.\n * @returns session hits ranked by their strongest matching event.\n */',
      },
      {
        signature: 'abstract searchEvents( request: SessionEventSearchRequest, exec?: SessionSearchExecContext, ): Promise<SessionEventSearchPage>',
        jsDoc: '/**\n * Search events within one live-preferred logical session.\n * @param request - target session, query text, filters, page size, and cursor.\n * @param exec - optional cancellation control.\n * @returns matching event hits and their target header from one indexed generation.\n */',
      },
      {
        signature: 'listSessions(signal?: AbortSignal): Promise<SessionRecord[]>',
        jsDoc: '/**\n * List the complete logical corpus using live-preferred records.\n * @param signal - optional cancellation for persistence listing.\n * @returns deterministic newest-first cloned session records.\n */',
      },
      {
        signature: 'async readSession(sessionId: SessionId): Promise<SessionLogSnapshot>',
        jsDoc: '/**\n * Read and replay-validate one complete logical session log without making it live.\n * @param sessionId - live or persisted session id to read.\n * @returns cloned header and complete raw event log from one observation.\n * @throws when persistence, header compatibility, or replay validation fails.\n */',
      },
      {
        signature: 'async filterSessions( filters: readonly SessionResultFilter[], signal?: AbortSignal, ): Promise<SessionRecord[]>',
        jsDoc: '/**\n * Filter the complete logical corpus with provider-independent predicates.\n * @param filters - ANDed session metadata and availability clauses.\n * @param signal - optional cancellation for persistence listing.\n * @returns matching cloned records in deterministic newest-first order.\n */',
      },
      {
        signature: 'async readTitle( sessionId: SessionId, signal?: AbortSignal, ): Promise<SessionTitleSnapshot | undefined>',
        jsDoc: '/**\n * Fold the latest log-backed title from one live-preferred logical session.\n * @param sessionId - live or persisted session id to read.\n * @param signal - optional cancellation for source resolution and title folding.\n * @returns latest title snapshot, or `undefined` when the log has no title event.\n */',
      },
      {
        signature: 'async readTitleSnapshot( sessionId: SessionId, signal?: AbortSignal, ): Promise<SessionTitleObservation>',
        jsDoc: '/**\n * Fold the latest title and return its source header from one corpus observation.\n * @param sessionId - live or persisted session id to read.\n * @param signal - optional cancellation for source resolution and title folding.\n * @returns cloned source header and optional latest title snapshot.\n */',
      },
      {
        signature: 'async readTitleSnapshots( sessionIds: readonly SessionId[], signal?: AbortSignal, ): Promise<SessionTitleObservationResult[]>',
        jsDoc: '/**\n * Fold titles for unique sessions from one cancellable corpus observation.\n *\n * Results preserve first-occurrence input order. Operational failures stay\n * isolated per session, while cancellation rejects the complete operation.\n * @param sessionIds - live or persisted session ids to observe.\n * @param signal - optional cancellation shared by all source reads.\n * @returns one fulfilled or rejected result per unique requested id.\n */',
      },
      {
        signature: 'async listEvents(sessionId: SessionId): Promise<SessionEventRecord[]>',
        jsDoc: '/**\n * List lightweight raw-log event records for one logical session.\n * @param sessionId - live-preferred session id to read.\n * @returns event records in ascending seq order.\n */',
      },
      {
        signature: 'async filterEvents( sessionId: SessionId, filters: readonly SessionEventResultFilter[], ): Promise<SessionEventSearchDocument[]>',
        jsDoc: '/**\n * Scan first-party semantic event documents with provider-independent filters.\n * @param sessionId - live-preferred session id to scan.\n * @param filters - ANDed metadata and literal-text predicates.\n * @returns matching semantic documents in ascending seq order.\n */',
      },
      {
        signature: 'async readSurface(sessionId: SessionId): Promise<SessionSurfaceSnapshot>',
        jsDoc: '/**\n * Read one session\'s complete current model surface from one corpus observation.\n * @param sessionId - live-preferred session id to read.\n * @returns cloned header, current surface, and raw-log capture boundary.\n * @throws when source resolution fails or the session surface is invalid.\n */',
      },
      {
        signature: 'async traceSession(sessionId: SessionId, signal?: AbortSignal): Promise<SessionLineageTrace>',
        jsDoc: '/**\n * Trace known ancestry and descendants from one corpus observation.\n * @param sessionId - logical session id to trace.\n * @param signal - optional cancellation for persistence listing.\n * @returns a complete lineage or an explicit unresolved parent boundary.\n * @throws when corpus resolution fails, the target is absent, or its known ancestry cycles.\n */',
      },
      {
        signature: 'async traceEvent(request: SessionEventTraceRequest, signal?: AbortSignal): Promise<SessionEventTraceObservation>',
        jsDoc: '/**\n * Trace one event\'s direct positional and provenance relationships.\n * @param request - target session id and event seq.\n * @param signal - optional cancellation for persisted source resolution.\n * @returns source header, direct links, and the target\'s positional replacement chain.\n * @throws when source resolution fails, the target is absent, or surface/provenance validation fails.\n */',
      },
      {
        signature: 'async readEvent(request: SessionEventReadRequest, signal?: AbortSignal): Promise<SessionEventWindow>',
        jsDoc: '/**\n * Read one full event plus a bounded raw-log context window.\n * @param request - target session/seq and context sizes.\n * @param signal - optional cancellation for persisted source resolution.\n * @returns cloned target and neighboring events.\n */',
      },
    ],
  },
  {
    key: 'sessionReferences',
    summary: 'Exact-read consumer that prepares immutable cross-session message context.',
    methods: [
      {
        signature: 'async listCandidates( agent: Agent, query = \'\', limit = this.config.candidateLimit, signal?: AbortSignal, ): Promise<SessionReferenceCandidate[]>',
        jsDoc: '/**\n * List reference candidates, ranked by working-directory affinity.\n * @param agent - target agent; self is excluded and its cwd drives ranking.\n * @param query - optional case-insensitive session-id/cwd/title substring.\n * @param limit - optional positive result cap.\n * @param signal - optional cancellation boundary for host autocomplete teardown.\n * @returns candidates labeled by latest title or, when absent, session id.\n */',
      },
      {
        signature: 'async prepare( agent: Agent, content: ContentBlock[], references: SessionReferenceInput[], signal?: AbortSignal, ): Promise<PreparedReferencedMessage>',
        jsDoc: '/**\n * Snapshot all references before enqueue and return one aggregated durable context.\n * @param agent - target agent; references to it are rejected.\n * @param content - already host-normalized readable message content.\n * @param references - structured source sessions in mention order.\n * @param signal - optional cancellation boundary for host request teardown.\n * @returns detached content and optional referenced-session context.\n */',
      },
    ],
  },
  {
    key: 'sessions',
    summary: 'In-memory session store (`ctx.sessions`).',
    methods: [
      {
        signature: 'create(id?: SessionId, options?: CreateSessionOptions): Session',
        jsDoc: '/**\n * Create a session owned by the calling fiber: disposing that fiber stops\n * event notification and removes the session from the store. `options.seed`\n * populates the session with a copy of those events (replay/fork);\n * `options.meta` attaches creation metadata (validated absolute `cwd`, seed\n * and parent lineage, and delegation depth) as the immutable\n * {@link SessionHeader} (the store fills `version`/`id`/`createdAt`).\n *\n * For an agent whose session must be torn down IN ORDER with its loop (so the\n * loop\'s final flush is captured before the store attachment ends), do NOT use this\n * — fold the session lifecycle into the agent\'s own effect via\n * {@link prepare} + {@link enter} + {@link announce} (see\n * `dsh-agent-loop`\'s creation transaction).\n *\n * @param id - the session id; omitted, the store mints `session-<n>`.\n * @param options - seed events and/or creation metadata for the header.\n * @returns the live session, already entered and announced.\n * @throws if a session with `id` already exists, metadata is not a plain\n *   lossless-JSON record with valid scalar fields, or `meta.cwd` is a\n *   non-absolute path (storage backends key directories off it).\n */',
      },
      {
        signature: 'prepare(id?: SessionId, options?: CreateSessionOptions): Session',
        jsDoc: '/**\n * Build a session WITHOUT entering it into the store — validate the id/cwd and\n * construct the {@link Session} (with its immutable {@link SessionHeader}).\n * Pairs with {@link enter} + {@link announce}: a caller that owns a composite\n * `ctx.effect` (the agent factory) folds the session lifecycle into that ONE\n * effect so a fiber unload tears the session + agent down as a single ORDERED\n * chain rather than as racing sibling effects — which would remove the publication hooks\n * before the loop\'s closing `session/flush`, dropping the closing events.\n *\n * @param id - the session id; omitted, the store mints `session-<n>`.\n * @param options - seed events and/or creation metadata for the header.\n * @returns the constructed session, NOT yet in the store.\n * @throws if a session with `id` already exists, metadata is not a plain\n *   lossless-JSON record with valid scalar fields, or `meta.cwd` is a\n *   non-absolute path.\n */',
      },
      {
        signature: 'enter(session: Session): () => void',
        jsDoc: '/**\n * Enter a {@link prepare}d session into the store: install the module-private\n * append publication hooks and add it to the store. Returns the DETACH\n * disposer (hooks + store removal). Does NOT emit `session/created` —\n * the caller yields this disposer inside its effect and THEN calls\n * {@link announce}, so a throwing `session/created` listener rolls the attach\n * back instead of leaking it.\n *\n * Re-checks the id for a duplicate: `prepare` and `enter` are public\n * cross-package primitives and a caller may interleave arbitrary work (or\n * another create) between them, so a stale prepared session must NOT overwrite\n * a live store entry of the same id — its detach disposer would later delete\n * the REAL session. The {@link create} convenience and the agent factory call\n * the two back-to-back so they never trip this, but the public seam cannot\n * assume that.\n *\n * @param session - a {@link prepare}d session not yet in the store.\n * @returns the detach disposer (publication hooks + store removal). When called from\n *   a synchronous `session/created` listener, removal and disposal wait until\n *   that creation dispatch unwinds.\n * @throws if a session with this id is already in the store.\n */',
      },
      {
        signature: 'announce(session: Session): void',
        jsDoc: '/** Emit `session/created` exactly once for an {@link enter}ed session (with\n * the carrier {@link enter} captured). Separate from {@link enter} so the\n * caller can yield the detach disposer first (rollback safety — see\n * {@link enter}).\n * @param session - the entered session to announce to listeners.\n * @throws if the session is not live or its announcement already began,\n *   including a reentrant call from a creation listener. */',
      },
      {
        signature: 'async flush(session: Session): Promise<void>',
        jsDoc: '/**\n * Dispatch the awaited `session/flush` durability checkpoint for `session`,\n * with the carrier captured at {@link enter}. THE flush entry point: the\n * store owns the carrier, so callers (the loop\'s turn-end checkpoint, idle\n * injection, teardown drains) must come through here rather than dispatch a\n * raw `ctx.parallel(\'session/flush\', …)` — one owner, one spelling, and the\n * scoped-dispatch invariant can pin it.\n * @param session - the session whose buffered events must reach durable storage.\n * @returns resolves when every flush listener has settled; after all settle,\n *   rejects with the first registered listener failure if any listener failed.\n */',
      },
      {
        signature: 'get(id: SessionId): Session | undefined',
        jsDoc: '/**\n * Look up a live session.\n * @param id - the session id to look up.\n * @returns the session, or undefined when no live session has that id.\n */',
      },
      {
        signature: 'list(): Session[]',
        jsDoc: '/**\n * All live sessions, in creation order.\n * @returns a fresh array; mutating it does not affect the store.\n */',
      },
      {
        signature: 'fork(source: SessionForkSource, boundary?: number, childSessionId?: SessionId): Session',
        jsDoc: '/**\n * Create a live child session from a stable prefix of a live source.\n * `boundary` is an inclusive source event seq; omitted means the source\'s\n * current last event. The selected slice may end with a between-turn event\n * but must not end inside an open turn.\n *\n * @param source - Live source session object or id.\n * @param boundary - Inclusive source event seq to fork through; omitted means\n *   the source\'s current last event, and omitted on an empty source forks an\n *   empty child.\n * @param childSessionId - Optional child session id; omitted delegates to\n *   `SessionStore`\'s id policy.\n * @returns The created live child session.\n */',
      },
    ],
  },
  {
    key: 'sessionTitle',
    summary: 'Log-backed title fold plus asynchronous fallback generation.',
    methods: [
      {
        signature: 'get(session: Session): SessionTitleSnapshot | undefined',
        jsDoc: '/**\n * Read the latest folded title from one live or replayed session.\n * @param session - session whose log is the title source of truth.\n * @returns latest title snapshot, or `undefined` before eligible input.\n */',
      },
      {
        signature: 'async refresh(session: Session, signal?: AbortSignal): Promise<SessionTitleSnapshot | undefined>',
        jsDoc: '/**\n * Explicitly retry the registered provider, or materialize the built-in\n * fallback when no provider is registered.\n * @param session - exact live session to refresh.\n * @param signal - optional caller cancellation.\n * @returns latest accepted title, or `undefined` when no eligible text exists.\n */',
      },
      {
        signature: 'register(provider: SessionTitleProvider): () => Promise<void>',
        jsDoc: '/**\n * Register the sole optional title provider. Disposal aborts its pending and\n * active work before another provider may register.\n * @param provider - provider identity, cadence, and generation function.\n * @returns exact Cordis effect disposer, which settles after active calls quiesce.\n */',
      },
    ],
  },
  {
    key: 'skills',
    summary: 'Registry of skill providers.',
    methods: [
      {
        signature: 'registerProvider(provider: SkillProvider): () => void',
        jsDoc: '/**\n * Register a borrowed same-process provider synchronously during plugin apply. Duplicate and\n * reserved names throw; remote initialization belongs in `list()`. Fiber disposal unregisters\n * the provider and invalidates catalog caches.\n * @param provider - the provider to register by `provider.name`.\n * @returns the exact Cordis effect disposer that unregisters this provider;\n *   composite effects may yield it directly to preserve teardown ordering.\n */',
      },
      {
        signature: 'register(skill: SkillRegistration): () => void',
        jsDoc: '/**\n * Register a borrowed readonly runtime skill. Project entries outrank runtime entries, which\n * outrank user entries. Same-name runtime entries are first-wins; a duplicate logs a warning and\n * receives a no-op disposer so it cannot remove the winner.\n * @param skill - the complete skill definition to expose for discovery.\n * @returns the exact Cordis effect disposer, preserving composite teardown order and invalidating caches.\n */',
      },
      {
        signature: 'async list(options: SkillLookupOptions = {}): Promise<SkillSummary[]>',
        jsDoc: '/**\n * List model-invocable skill summaries for a workspace. Lookup options and\n * provider candidates are readonly same-process values borrowed throughout\n * discovery.\n * @param options - lookup options; `cwd` selects project roots and `signal` cancels discovery.\n * @returns sorted summaries, excluding skills disabled for model invocation.\n */',
      },
      {
        signature: 'async get(name: string, options: SkillLookupOptions = {}): Promise<SkillDefinition | undefined>',
        jsDoc: '/**\n * Load and validate the winning candidate, passing its opaque discovery locator back to the\n * provider. Cancellation is rechecked after selection, including cache hits, and raced against\n * loading so an uncooperative provider cannot hang the caller.\n * @param name - kebab-case skill name.\n * @param options - lookup options; `cwd` selects workspace-sensitive skills and `signal` cancels work.\n * @returns the full skill, including body content, or `undefined`.\n */',
      },
    ],
  },
  {
    key: 'spillStore',
    summary: 'Abstract spill storage service.',
    methods: [
      {
        signature: 'abstract saveText(input: SaveTextSpill): Promise<SpillRef>',
        jsDoc: '/**\n * Persist `input.content` to a session-scoped spill artifact.\n * @param input - the owner, provenance, suggested name, and full text to save.\n * @returns the saved artifact\'s {@link SpillRef}; rejects on a storage failure.\n */',
      },
    ],
  },
  {
    key: 'storage',
    summary: 'The storage hub service.',
    methods: [
      {
        signature: 'mount<K extends keyof StorageForms>(form: K, facility: StorageForms[K]): () => void',
        jsDoc: '/**\n * Mount a data-form facility on the hub. Mounting is an effect: the\n * returned disposer unmounts the form.\n * @param form - Form key declared in {@link StorageForms}.\n * @param facility - The facility instance to expose.\n * @returns the disposer that unmounts the form.\n */',
      },
      {
        signature: 'form<K extends keyof StorageForms>(form: K): StorageForms[K]',
        jsDoc: '/**\n * Resolve a mounted data form.\n * @param form - Form key declared in {@link StorageForms}.\n * @returns the mounted facility.\n */',
      },
    ],
  },
  {
    key: 'storageDomain',
    summary: 'The mounted domain facility.',
    methods: [
      {
        signature: 'async open<S extends DomainSpec>(spec: S): Promise<Domain<S>>',
        jsDoc: '/**\n * Open one declared domain. Steps, each failing the whole call: reject a\n * name that is already open (`already-open`); resolve the backend route\n * (`backend-not-found` passes through from the hub); require its `kv` facet\n * (`facet-unsupported`); open the unit projected from the spec (backend\n * `version-mismatch`/`malformed-medium` pass through); load and validate\n * every stored record against the spec\'s zod schemas (`invalid-record`\n * with the offending table and key); construct the domain.\n *\n * Lifecycle: the CALLER owns the returned handle and closes it via\n * `Domain.close()` (typically as its own `ctx.effect` disposer) — the\n * facility does not tie the domain to any consumer fiber. Domains still\n * open when the facility unmounts are closed by the plugin disposer.\n * @param spec - The domain declaration, typically from `defineDomain`.\n * @returns the opened domain handle, typed by the spec.\n */',
      },
      {
        signature: 'get(name: string): DomainImpl | undefined',
        jsDoc: '/**\n * Look up an open domain by name, untyped. Diagnostic surface (the package\n * invariant cross-checks change events against live domain state); typed\n * consumers hold the handle returned by {@link open}.\n * @param name - Domain name.\n * @returns the open domain runtime, or `undefined` when not open.\n */',
      },
      {
        signature: 'async closeAll(): Promise<void>',
        jsDoc: '/**\n * Close every domain still open on this facility. The unmount path for\n * consumers that never called `Domain.close()` themselves; closing is\n * idempotent, so double-closing an already-closed domain is harmless.\n * @returns resolution after every unit is released.\n */',
      },
    ],
  },
  {
    key: 'subagents',
    summary: 'Named provider registry and capability-checked start surface.',
    methods: [
      {
        signature: 'registerProvider(provider: SubagentProvider): () => void',
        jsDoc: '/**\n * Register a provider under its name. Registration is effect-scoped and HMR\n * safe; removing a provider blocks new starts but does not revoke runs that\n * were already returned to their holders.\n * @param provider - the trusted provider implementation.\n * @returns the exact Cordis effect disposer.\n */',
      },
      {
        signature: 'getProvider(name: string): SubagentProvider | undefined',
        jsDoc: '/**\n * Look up a provider by name.\n * @param name - the provider name.\n * @returns the provider, or undefined when absent.\n */',
      },
      {
        signature: 'list(): string[]',
        jsDoc: '/**\n * List registered provider names in insertion order.\n * @returns the registered names.\n */',
      },
      {
        signature: 'async start(name: string, request: SubagentStartRequest): Promise<SubagentRun>',
        jsDoc: '/**\n * Establish a ready child on the named provider. Capability and semantic\n * checks run before delegation. Provider ownership lasts until its promise\n * fulfills; a rejection therefore has no run for the caller to dispose and\n * emits no run lifecycle events.\n * @param name - the provider to use.\n * @param request - child prompt, parent, signal, and optional capabilities.\n * @returns the ready holder-owned run.\n */',
      },
    ],
  },
  {
    key: 'subprocess',
    summary: 'Abstract subprocess service.',
    methods: [
      {
        signature: 'abstract spawn(spec: SubprocessSpawnSpec): SubprocessHandle',
        jsDoc: '/**\n * Start one managed child process from a fully-specified spec; this seam\n * applies no defaults.\n * @param spec - argv, directory, stdio dispositions, grace, cancellation, and environment.\n * @returns the live process handle (streams/readers, signalling, outcome promise).\n */',
      },
    ],
  },
  {
    key: 'systemPrompt',
    summary: 'Registry service for the prompt inputs assembled before each model step.',
    methods: [
      {
        signature: 'section(section: PromptSection): () => void',
        jsDoc: '/**\n * Register an ordered prompt section in the calling context\'s scope. A scoped\n * section shadows a global section with the same name; duplicates within one\n * layer and non-finite orders throw. Registration and disposal emit\n * `system-prompt/change`.\n * @param section - the section to register.\n * @returns the exact Cordis effect disposer.\n */',
      },
      {
        signature: 'tools(provider: (context: AssembleContext) => ToolProviderResult): () => void',
        jsDoc: '/**\n * Register a tool-schema provider in the calling context\'s scope. Global and\n * matching scoped providers both contribute; returning the reserved\n * {@link TOOL_ORDER_REST} name makes assembly fail.\n * @param provider - evaluated for each assembly with its context.\n * @returns the exact Cordis effect disposer.\n */',
      },
      {
        signature: 'variable(name: string, provider: (context: AssembleContext) => string | undefined): () => void',
        jsDoc: '/**\n * Register a prompt variable in the calling context\'s scope. Scoped values\n * shadow globals; invalid or duplicate names throw. A provider may return\n * `undefined`, but rendering a section that references that value then fails.\n * @param name - the `[a-z][a-z0-9_]*` reference name.\n * @param provider - evaluated for each assembly.\n * @returns the exact Cordis effect disposer.\n */',
      },
      {
        signature: 'async assemble(context: AssembleContext = {}): Promise<PromptAssembly>',
        jsDoc: '/**\n * Assemble global and scoped providers, detach tool parameters, apply\n * canonical ordering, then run the assembly waterfall. Scoped sections and\n * variables shadow globals; the returned waterfall value is authoritative.\n * @param context - the optional scope and plugin-defined assembly fields.\n * @returns the authoritative post-waterfall assembly.\n */',
      },
    ],
  },
  {
    key: 'tasks',
    summary: 'Abstract background task registry.',
    methods: [
      {
        signature: 'abstract start(spec: TaskStart): TaskId',
        jsDoc: '/**\n * Preflight access, validation, and owner cleanup before starting and\n * atomically registering work. A throwing starter leaves nothing registered;\n * after it returns, registration cannot fail. Settlement records the outcome,\n * notifies listeners, and releases waiters.\n * @param spec - task identity, owner, and synchronous starter.\n * @returns the registry-issued `<kind>-N` id.\n */',
      },
      {
        signature: 'abstract list(caller?: Agent): TaskSnapshot[]',
        jsDoc: '/**\n * List caller-owned and unowned tasks in registration order without exposing\n * another session\'s labels.\n * @param caller - reading agent; a non-agent caller sees only unowned tasks.\n * @returns fresh snapshots.\n */',
      },
      {
        signature: 'abstract get(id: TaskId, caller?: Agent): TaskSnapshot',
        jsDoc: '/**\n * Return a non-consuming snapshot without changing its read cursor or notice\n * state. Throws for an unknown or foreign task.\n * @param id - task to look up.\n * @param caller - reading agent checked against the owner.\n * @returns a fresh snapshot.\n */',
      },
      {
        signature: 'abstract read(id: TaskId, caller?: Agent): TaskRead',
        jsDoc: '/**\n * Read the next stream delta, or the idempotent final output after settlement.\n * A terminal read marks the task reported. Throws for an unknown or foreign\n * task.\n * @param id - task to read.\n * @param caller - reading agent checked against the owner.\n * @returns output text and the post-read snapshot.\n */',
      },
      {
        signature: 'abstract kill(id: TaskId, caller?: Agent, reason?: string): \'requested\' | \'already-finished\'',
        jsDoc: '/**\n * Request cancellation, then mark the task stopping and reported. A producer\n * throw propagates without changing task state. Throws for an unknown or\n * foreign task.\n * @param id - task to cancel.\n * @param caller - killing agent checked against the owner.\n * @param reason - logged reason forwarded to the producer.\n * @returns `requested` for live work, otherwise `already-finished`.\n */',
      },
      {
        signature: 'abstract wait(id: TaskId, timeoutMs: number, caller?: Agent, signal?: AbortSignal): Promise<TaskSnapshot>',
        jsDoc: '/**\n * Wait for settlement or timeout without cancelling the task. Caller abort\n * rejects only while the task is live; after settlement the terminal\n * snapshot wins so a notice suppressed for this waiter is still delivered.\n * Throws for invalid, unknown, or foreign input.\n * @param id - task to wait for.\n * @param timeoutMs - positive finite wait bound in milliseconds.\n * @param caller - waiting agent checked against the owner.\n * @param signal - optional cancellation of the wait itself.\n * @returns snapshot at settlement or timeout.\n */',
      },
      {
        signature: 'abstract onTaskDone(listener: TaskDoneListener): () => void',
        jsDoc: '/**\n * Register an effect-scoped completion listener. Each listener is contained;\n * returned promises are observed but not awaited. No listener runs after\n * service disposal.\n * @param listener - receives each terminal snapshot and its exact owner.\n * @returns disposer that unregisters the listener.\n */',
      },
      {
        signature: 'abstract attachSurface(name: string): () => void',
        jsDoc: '/**\n * Attach an effect-scoped surface that can read and stop tasks. {@link start}\n * refuses work while none is attached.\n * @param name - diagnostic label; duplicate names remain independent.\n * @returns disposer that detaches this surface.\n */',
      },
    ],
  },
  {
    key: 'telemetry',
    summary: 'The backend contract in its loadable form: one implementation per context — the cordis `Service` registration under the `telemetry` key throws on a duplicate, cordis\' standard behavior.',
    methods: [
      {
        signature: 'abstract emit(record: TelemetryRecord): void',
        jsDoc: '/**\n * See {@link TelemetryBackend.emit} — the seam declaration is the contract\'s one home.\n * @param record - the logical record to report; owned by the backend after the call.\n */',
      },
      {
        signature: 'flush?(): void',
        jsDoc: '/** See {@link TelemetryBackend.flush}. */',
      },
      {
        signature: 'abstract shutdown(): Promise<void>',
        jsDoc: '/**\n * See {@link TelemetryBackend.shutdown}.\n * @returns resolves when the backend\'s pipeline has quiesced.\n */',
      },
    ],
  },
  {
    key: 'tokenMeter',
    summary: 'Replay owner for one service-wide estimator and isolated per-session folds.',
    methods: [
      {
        signature: 'measure(session: Session, requestHeader?: EpochHeader): TokenMeasurement',
        jsDoc: '/**\n * Measure current request pressure and surface through the durable tail.\n *\n * Provider usage is reused only when the latest successful call\'s canonical\n * request envelope matches `requestHeader` and its total is no lower than\n * that call\'s full heuristic anchor; otherwise the complete envelope and\n * surface are heuristically repriced.\n *\n * `requestHeader` affects request pressure only; surface fields always\n * describe the current session surface. Every call clones those positional\n * nodes, so measurement is O(surface).\n *\n * @param session - session to replay through its current durable tail.\n * @param requestHeader - optional effective request envelope replacing the latest logged header.\n * @returns a detached deeply immutable pressure and surface measurement.\n */',
      },
      {
        signature: 'estimateMessage(message: Message): number',
        jsDoc: '/**\n * Heuristically price one model-visible message.\n * @param message - message to price without mutation.\n * @returns content and role-framing tokens under the fixed service heuristic.\n */',
      },
    ],
  },
  {
    key: 'toolResultPrune',
    summary: 'Deterministic head/middle/tail pruning for current tool-result surface nodes.',
    methods: [
      {
        signature: 'measureContent(blocks: readonly ContentBlock[]): number',
        jsDoc: '/**\n * Measure text content in Unicode code points; non-text blocks cost zero.\n * @param blocks - tool-result content to measure.\n * @returns total Unicode code points across text blocks.\n */',
      },
      {
        signature: 'pruneContent(blocks: readonly ContentBlock[]): ContentBlock[] | null',
        jsDoc: '/**\n * Replace an over-budget text middle while retaining rich-block order.\n * Text slicing is by Unicode code point, not UTF-16 code unit, so a retained\n * boundary cannot split a surrogate pair. Grapheme clusters may still split.\n * @param blocks - original tool-result content.\n * @returns pruned content, or `null` when the text is within budget.\n */',
      },
      {
        signature: 'pruneSession(session: Session): PruneResult',
        jsDoc: '/**\n * Prune every over-budget tool result from one stable current-surface snapshot.\n * Each replacement preserves the complete event data except for `content`,\n * and points at the shadowed node for durable provenance and replay.\n * @param session - session whose current surface is rewritten.\n * @returns landed replacements and aggregate Unicode-code-point savings.\n * @throws when the session rejects a replacement; replacements committed\n * earlier in the pass remain durable.\n */',
      },
    ],
  },
  {
    key: 'tools',
    summary: 'Tool registry and execution pipeline.',
    methods: [
      {
        signature: 'register(definition: ToolDefinition): () => void',
        jsDoc: '/**\n * Register globally or in the calling agent scope. Scoped tools shadow\n * globals; duplicates within one layer and the reserved `run_code` name fail.\n * @param definition - tool schema, execution, and optional finalization/presentation callbacks.\n * @returns the exact disposer that unregisters the tool.\n */',
      },
      {
        signature: 'restrict(filter: ToolRestriction): () => void',
        jsDoc: '/**\n * Restrict global tools for the calling agent scope. Empty filters, unknown\n * names, scope-local names, and reserved transport names fail. Restrictions\n * intersect; scoped registrations remain visible.\n * @param filter - global-surface mask: `allow` (keep only) and/or `deny` (remove).\n * @returns the exact disposer that lifts this restriction.\n */',
      },
      {
        signature: 'guard(guard: ToolGuard): () => void',
        jsDoc: '/**\n * Register a monotonic guard after the extensible `tools/pre-execute`\n * waterfall. A plain-context guard applies globally; one registered through\n * `agent.ctx` applies only to that agent. Any matching guard may deny by\n * returning a reason, while no guard can force-allow a call another guard\n * denied. The exact effect disposer is returned for ordered ownership and\n * HMR cleanup.\n * @param guard - synchronous check; a returned string denies the execution.\n * @returns the exact disposer that unregisters the guard.\n */',
      },
      {
        signature: 'get(name: string, scope?: ScopeKey): ToolDefinition | undefined',
        jsDoc: '/**\n * Look up a tool as one scope sees it (scoped\n * shadows global; a restricted-away global reads as absent). Presenters pass\n * the calling agent so the rendered card matches the definition that\n * actually executed.\n * @param name - the tool name as registered.\n * @param scope - the viewing scope (the agent); omitted = the global view.\n * @returns the definition the scope resolves, or undefined when none is visible.\n */',
      },
      {
        signature: 'schemas(scope?: ScopeKey): ToolSchema[]',
        jsDoc: '/**\n * Project visible definitions onto the allowlisted model-facing schema fields,\n * excluding execution and presentation callbacks.\n * @param scope - the viewing scope (the agent); omitted = the global view.\n * @returns one deep-cloned schema per visible tool.\n */',
      },
      {
        signature: 'executionMode(exec: ToolExecutionInput): ToolExecutionMode',
        jsDoc: '/**\n * Classify a pending call through the caller\'s visible tool definition. Only\n * an exact `true` is parallel; unknown, hidden, undeclared, invalid, or\n * throwing classifiers are exclusive.\n * @param exec - call name, parsed arguments, and optional agent scope.\n * @returns the fail-closed scheduling mode.\n */',
      },
      {
        signature: 'async execute(exec: ToolExecutionInput): Promise<ToolExecutionResult>',
        jsDoc: '/**\n * Execute through pre-policy, guards, around-dispatch, post-policy,\n * definition-owned content finalization, and final notification. Tool and\n * listener failures resolve as materialized error results; an invisible tool\n * reports `UNKNOWN_TOOL`. The returned outcome is the same lossless, frozen\n * snapshot final observers receive. Cancellation\n * arriving after entry and before final result materialization skips a\n * not-yet-started body with `ABORTED_BEFORE_DISPATCH` or replaces a\n * successful started outcome with `ABORTED`; already-started work is still\n * drained and may retain a tool-owned structured error.\n * @param exec - the typed same-process call input. The registry assigns its\n *   correlation token before policy begins.\n * @returns the materialized final result.\n */',
      },
    ],
  },
  {
    key: 'tui',
    summary: 'Optional terminal-local interaction service provided by one mounted TUI.',
    methods: [
      {
        signature: 'abstract openOverlay(request: TuiOverlayRequest): TuiOverlaySession',
        jsDoc: '/**\n * Queue an interactive overlay owned by the calling plugin fiber.\n *\n * The TUI displays one overlay at a time in FIFO order. Disposing the caller\n * removes a queued overlay or closes an active one before plugin teardown\n * settles. This live presentation is neither logged nor replayed.\n *\n * @param request - component factory, layout constraints, and cancellation.\n * @returns the effect-owned overlay session.\n * @throws when the TUI has begun shutting down.\n */',
      },
    ],
  },
  {
    key: 'userInteraction',
    summary: '`ctx.userInteraction`: one active UI provider plus an `ask()` surface.',
    methods: [
      {
        signature: 'registerProvider(provider: UserInteractionProvider): () => void',
        jsDoc: '/**\n * Register the UI provider. Only one provider may be active in a context.\n *\n * @param provider UI-side implementation that collects answers.\n * @returns Disposer that unregisters this provider.\n */',
      },
      {
        signature: 'async ask(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>',
        jsDoc: '/**\n * Ask the active UI provider and wait for the user\'s answer.\n *\n * @param request Questions, owner agent, and abort signal.\n * @returns The answer chosen or typed by the human.\n */',
      },
    ],
  },
  {
    key: 'web',
    summary: 'The web access service.',
    methods: [
      {
        signature: 'registerSearchProvider(provider: WebSearchProvider): () => void',
        jsDoc: '/**\n * Register a search provider. Throws {@link WebError} `WEB_DUPLICATE_PROVIDER`\n * if its id is already registered for search. Returns a disposer; disposed\n * with the calling fiber.\n * @param provider - the provider; its `id` is the registry key.\n * @returns the disposer that unregisters the provider.\n */',
      },
      {
        signature: 'registerFetchProvider(provider: WebFetchProvider): () => void',
        jsDoc: '/**\n * Register a fetch provider. Throws {@link WebError} `WEB_DUPLICATE_PROVIDER`\n * if its id is already registered for fetch. Returns a disposer; disposed\n * with the calling fiber.\n * @param provider - the provider; its `id` is the registry key.\n * @returns the disposer that unregisters the provider.\n */',
      },
      {
        signature: 'async search(request: WebSearchRequest, signal?: AbortSignal): Promise<WebSearchResult>',
        jsDoc: '/**\n * Run one search through the selected provider. Resolves the provider at call\n * time with the selection rules above; throws {@link WebError} when the\n * capability cannot run. The seam enforces `request.maxResults` on the result:\n * if the provider over-returns, `sources[]` is truncated and `truncated` set.\n * @param request - the query plus result-shaping options.\n * @param signal - optional cancellation signal forwarded to the provider.\n * @returns the provider\'s results, capped to `request.maxResults`.\n */',
      },
      {
        signature: 'async fetch(request: WebFetchRequest, signal?: AbortSignal): Promise<WebFetchResult>',
        jsDoc: '/**\n * Retrieve one URL through the selected provider. Resolves the provider at\n * call time with the selection rules above; throws {@link WebError} when the\n * capability cannot run. A non-2xx response is a result, not a throw.\n * @param request - the URL plus retrieval options.\n * @param signal - optional cancellation signal forwarded to the provider.\n * @returns the retrieval outcome; non-2xx responses resolve descriptively.\n */',
      },
    ],
  },
  {
    key: 'workflows',
    summary: 'Workflow execution seam.',
    methods: [
      {
        signature: 'abstract start(request: WorkflowStartRequest): WorkflowRun',
        jsDoc: '/**\n * Parse and execute a workflow script.\n * @param request - the script, its `args`, the parent agent, and an\n *   optional cancel signal.\n * @returns the live run; its `result` resolves when the script settles.\n */',
      },
    ],
  },
  {
    key: 'workspace',
    summary: 'Durable workspace registry.',
    methods: [
      {
        signature: 'async create(path: string, title?: string): Promise<Workspace>',
        jsDoc: '/**\n * Create or reuse a workspace for an existing directory. The path is\n * canonicalized through `fs.realpath`; a nonexistent path rejects with the\n * original error and a non-directory rejects. Repeated calls for the same\n * canonical path return the existing entity without changing its title.\n * A newly created workspace is prepended to the durable registry order.\n * A different canonical path cannot create a duplicate display title.\n * @param path - Existing directory to own, in any path spelling.\n * @param title - Display title used only when a new record is created.\n * @returns the existing or newly durable workspace.\n */',
      },
      {
        signature: 'get(id: WorkspaceId): Workspace | undefined',
        jsDoc: '/**\n * Look up a workspace by id.\n * @param id - Workspace id.\n * @returns the workspace, or `undefined` when unknown.\n */',
      },
      {
        signature: 'list(): Workspace[]',
        jsDoc: '/**\n * Synchronous workspace projection in durable registry order. Every\n * entity\'s `sessionIds` getter is already filtered by the startup/live\n * canonical-cwd header index; this method performs no persistence reads.\n * @returns a fresh ordered array of workspace entities.\n */',
      },
      {
        signature: 'delete(id: WorkspaceId): Promise<boolean>',
        jsDoc: '/**\n * Delete one workspace registration while retaining its directory and every\n * session log. The durable order is updated before the table deletion; a\n * failed table write restores the prior order and keeps the entity\n * published. Unknown ids are an idempotent no-op for domain callers.\n * @param id - Workspace registration to remove.\n * @returns `true` when a record was deleted, `false` when it was unknown.\n */',
      },
      {
        signature: 'async resolveByPath(path: string): Promise<Workspace | undefined>',
        jsDoc: '/**\n * Resolve by canonical directory path without creating or mutating a\n * workspace. A missing path rejects during `realpath`; an existing unowned\n * directory returns `undefined`.\n * @param path - Existing directory path in any spelling.\n * @returns the workspace owning the canonical path, when one exists.\n */',
      },
    ],
  },
]

/** Every harness event, sorted by name. */
export const EVENT_API: readonly EventApiEntry[] = [
  {
    name: 'agent-loop/config-start-failed',
    mode: 'emit',
    signature: '\'agent-loop/config-start-failed\'(sessionId: SessionId, error: unknown): void',
    jsDoc: '/**\n * A declarative agent entry failed before it could publish a live agent.\n * Consumers that buffer work for the configured identity use this\n * transient signal to reject that work instead of waiting forever. Normal\n * factory teardown suppresses failures from the cancelled startup attempt.\n * @param sessionId - exact shared agent/session identity that failed startup.\n * @param error - persistence, setup, or publication failure.\n * @mode emit\n */',
    summary: 'A declarative agent entry failed before it could publish a live agent.',
  },
  {
    name: 'agent/cancel-requested',
    mode: 'emit',
    signature: '\'agent/cancel-requested\'(this: Scoped<Agent>, agent: Agent, cause: AgentCancelCause): void',
    jsDoc: '/**\n * Effective broad cancellation was requested, before queued/outbox work\n * is cleared or the active turn is aborted. This observe-only notification\n * cannot veto cancellation; listener failures are contained.\n * @param agent - the agent whose current work is being cancelled.\n * @param cause - the explicit typed cancellation cause.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode emit\n */',
    summary: 'Effective broad cancellation was requested, before queued/outbox work is cleared or the active turn is aborted.',
  },
  {
    name: 'agent/created',
    mode: 'emit',
    signature: '\'agent/created\'(this: Scoped<Agent>, agent: Agent): void',
    jsDoc: '/**\n * A fully configured agent and live session were published. Setup is\n * composition-only; `agent/session-start` is the first startup-driving seam.\n * Synchronous listener failure vetoes publication, while returned-promise\n * rejection is reported. Detach requested during dispatch waits until every\n * creation listener has observed the stable entry.\n * @param agent - the newly registered agent with its live session and completed setup.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode emit\n */',
    summary: 'A fully configured agent and live session were published.',
  },
  {
    name: 'agent/disposed',
    mode: 'emit',
    signature: '\'agent/disposed\'(this: Scoped<Agent>, agent: Agent): void',
    jsDoc: '/**\n * An agent left the registry; AgentLoop emits this after driver quiescence\n * and scoped-registration unwind, but before session detachment. Custom\n * registry users own their driver-ordering contract.\n * @param agent - the exact agent removed from the registry.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode emit\n */',
    summary: 'An agent left the registry; AgentLoop emits this after driver quiescence and scoped-registration unwind, but before session detachment.',
  },
  {
    name: 'agent/error',
    mode: 'emit',
    signature: '\'agent/error\'(this: Scoped<Agent>, agent: Agent, turn: number, step: number, error: unknown): void',
    jsDoc: '/**\n * A step or turn errored. The machine reports a failure here (plus the\n * logger) even when the error has no in-turn position for a durable record.\n * @param agent - the agent whose turn errored.\n * @param turn - the turn in which the failure surfaced.\n * @param step - the step at which the failure surfaced.\n * @param error - the failure, verbatim.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode emit\n */',
    summary: 'A step or turn errored.',
  },
  {
    name: 'agent/inbox/dequeue',
    mode: 'emit',
    signature: '\'agent/inbox/dequeue\'( this: Scoped<Agent>, agent: Agent, message: UserMessage, placement: InboxPlacement, ): void',
    jsDoc: '/**\n * The driver claimed one item out of the inbox: a queued item at a turn\n * boundary, or steering drained between steps. Fires after the item leaves\n * its FIFO and before it becomes a durable message.\n * @param agent - the agent whose inbox item was claimed.\n * @param message - the claimed message.\n * @param placement - the FIFO that claimed this occurrence; together with\n *   `message.id`, it matches the earliest outstanding enqueue in that FIFO.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode emit\n */',
    summary: 'The driver claimed one item out of the inbox: a queued item at a turn boundary, or steering drained between steps.',
  },
  {
    name: 'agent/inbox/discard',
    mode: 'emit',
    signature: '\'agent/inbox/discard\'(this: Scoped<Agent>, agent: Agent, messages: UserMessage[]): void',
    jsDoc: '/**\n * Pending inbox items were dropped without delivering them, so every\n * enqueue occurrence receives exactly one terminal `agent/inbox/dequeue` OR\n * `agent/inbox/discard`. `cancel()` without `keepInbox`, including disposal,\n * emits this after `agent/cancel-requested` when applicable and before\n * aborting the active work. Fires once per drop with every dropped item.\n * @param agent - the agent whose inbox items were dropped.\n * @param messages - the discarded messages in FIFO order (queued then steering); never empty.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode emit\n */',
    summary: 'Pending inbox items were dropped without delivering them, so every enqueue occurrence receives exactly one terminal `agent/inbox/dequeue` OR `agent/inbox/discard`.',
  },
  {
    name: 'agent/inbox/enqueue',
    mode: 'emit',
    signature: '\'agent/inbox/enqueue\'(this: Scoped<Agent>, agent: Agent, message: UserMessage, placement: InboxPlacement): void',
    jsDoc: '/**\n * An item entered the queued or steering inbox. `placement` is the\n * acceptance-time routing result; listeners must not reconstruct it from\n * later agent or session state.\n * @param agent - the owning agent.\n * @param message - accepted content, source, and correlation identity.\n * @param placement - resolved queued or steering placement.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode emit\n */',
    summary: 'An item entered the queued or steering inbox.',
  },
  {
    name: 'agent/prompt-submit',
    mode: 'waterfall',
    signature: '\'agent/prompt-submit\'(this: Scoped<Agent>, agent: Agent, message: UserMessage, signal: AbortSignal, next: () => Promise<PromptDecision>): Promise<PromptDecision>',
    jsDoc: '/**\n * Allow, rewrite, or block one claimed prompt before it becomes a user\n * message or opens a turn. Call `next()` for the unchanged default. The\n * signal controls only this admission attempt; listeners may cooperate with\n * it but must not retain it for a later attempt or turn.\n * @param agent - the agent whose turn claimed the message.\n * @param message - the frozen claimed message, including identity and source.\n * @param signal - the current turn\'s explicit abort signal.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode waterfall\n */',
    summary: 'Allow, rewrite, or block one claimed prompt before it becomes a user message or opens a turn.',
  },
  {
    name: 'agent/request',
    mode: 'waterfall',
    signature: '\'agent/request\'(this: Scoped<Agent>, agent: Agent, turn: number, step: number, signal: AbortSignal, next: () => Promise<LlmCallConfig>): Promise<LlmCallConfig>',
    jsDoc: '/**\n * Replace the frozen call configuration. `await next()` yields the config\n * the machine would use (agent options on the first request, the logged\n * header afterwards); return a replacement to switch. Model-visible\n * content must use logged channels; this seam cannot mutate messages.\n * @param agent - the agent making the model call.\n * @param turn - the open turn number.\n * @param step - the step whose request this is.\n * @param signal - the current turn\'s explicit abort signal.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode waterfall\n*/',
    summary: 'Replace the frozen call configuration.',
  },
  {
    name: 'agent/request-error',
    mode: 'waterfall',
    signature: '\'agent/request-error\'(this: Scoped<Agent>, agent: Agent, turn: number, step: number, error: RequestError, failure: LlmFailure, priorFailures: readonly LlmFailure[], retryPolicy: ResolvedRetryPolicy | undefined, signal: AbortSignal, next: () => Promise<RequestErrorAction>): Promise<RequestErrorAction>',
    jsDoc: '/**\n * Handle a model-request failure after its failed step has closed but\n * before the failed turn closes. A listener returns `{ kind: \'retry\' }`\n * without calling `next()` when it owns the error, or calls `next()` to\n * delegate. The default `undefined` leaves the failure terminal.\n * @param agent - the agent whose request failed.\n * @param turn - the open turn number.\n * @param step - the failed step number.\n * @param error - the original model-request failure.\n * @param failure - serializable facts normalized at the final adapter boundary.\n * @param priorFailures - immutable failures that already authorized another\n * retry turn in this consecutive sequence.\n * @param retryPolicy - immutable policy of the adapter registration that served\n * the failed request, or `undefined` if no final adapter served it.\n * @param signal - the turn abort signal.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode waterfall\n */',
    summary: 'Handle a model-request failure after its failed step has closed but before the failed turn closes.',
  },
  {
    name: 'agent/session-start',
    mode: 'emit',
    signature: '\'agent/session-start\'(this: Scoped<Agent>, agent: Agent, source: SessionStartSource): void',
    jsDoc: '/**\n * The session lifecycle began, once before the first turn. Use\n * `agent.inject()` to seed model-facing context. This is a notification, not\n * a veto; disposal requested by a lifecycle owner is rechecked before the\n * driver starts.\n * @param agent - the agent whose session lifecycle began.\n * @param source - why the session started (fresh startup, resume, …).\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode emit\n */',
    summary: 'The session lifecycle began, once before the first turn.',
  },
  {
    name: 'agent/settled',
    mode: 'emit',
    signature: '\'agent/settled\'(this: Scoped<Agent>, agent: Agent, turn: number, reason: SettleReason): void',
    jsDoc: '/**\n * One drain chain reached its terminal turn: that turn\'s `turn/end` is\n * already committed. Automatically recovered failed turns do not emit this\n * notification, and neither does a run that aborts or fails before its\n * `turn/start` commits — there is no durable turn to settle against.\n * `reason` says why; model-request recovery is exhausted when an error\n * reaches it.\n * @param agent - the agent whose turn closed.\n * @param turn - the terminal turn number.\n * @param reason - why the terminal turn ended, with live error facts when it failed.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode emit\n */',
    summary: 'One drain chain reached its terminal turn: that turn\'s `turn/end` is already committed.',
  },
  {
    name: 'agent/status',
    mode: 'emit',
    signature: '\'agent/status\'(this: Scoped<Agent>, agent: Agent, status: AgentStatus): void',
    jsDoc: '/**\n * Agent status changed (`idle` ⇄ `running`). `send()` does not enter\n * `running` synchronously; drive lifecycle from this event.\n * @param agent - the agent whose status flipped.\n * @param status - the status just entered (the transition\'s destination).\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode emit\n */',
    summary: 'Agent status changed (`idle` ⇄ `running`).',
  },
  {
    name: 'agent/step',
    mode: 'serial',
    signature: '\'agent/step\'(this: Scoped<Agent>, agent: Agent, turn: number, step: number, signal: AbortSignal): Promise<void> | void',
    jsDoc: '/**\n * Awaited serial checkpoint before EVERY request of a turn is built (the\n * first as well as each post-tools continuation). The single "between\n * steps" extension point: inject context, steer, or edit the session log\n * here — the request\'s history derives from the log right after this settles.\n * @param agent - the agent about to send a request.\n * @param turn - the open turn number.\n * @param step - the step number about to open.\n * @param signal - the turn abort signal.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode serial\n */',
    summary: 'Awaited serial checkpoint before EVERY request of a turn is built (the first as well as each post-tools continuation).',
  },
  {
    name: 'agent/turn-stopping',
    mode: 'serial',
    signature: '\'agent/turn-stopping\'(this: Scoped<Agent>, agent: Agent, turn: number, signal: AbortSignal): Promise<void> | void',
    jsDoc: '/**\n * The turn is about to close: the model owes no response (no live tool\n * calls, no fresh steering). Awaited before the boundary commits — a\n * listener that objects steers (`agent.steer(...)`) and the machine\n * re-reads its inbox: fresh steering runs another step, none closes the\n * turn. Data decides, so listener order cannot change the outcome. The\n * inverse control (stop a tool loop early) is data too: a tool result\n * carrying `concludesTurn` ends the turn at its step.\n * @param agent - the agent whose turn is at its stop boundary.\n * @param turn - the turn about to close.\n * @param signal - the current turn\'s explicit abort signal.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @mode serial\n */',
    summary: 'The turn is about to close: the model owes no response (no live tool calls, no fresh steering).',
  },
  {
    name: 'approval/request',
    mode: 'waterfall',
    signature: '\'approval/request\'(this: Scoped<ApprovalService>, req: ApprovalRequest, next: () => Promise<ApprovalOutcome>): Promise<ApprovalOutcome>',
    jsDoc: '/**\n * Ask composed answerers for one decision. Return an outcome to claim the\n * request or call `next()`; failure yields the fail-closed default.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @param req - the pending decision (agent, tool identity, reason, signal).\n * @mode waterfall\n */',
    summary: 'Ask composed answerers for one decision.',
  },
  {
    name: 'commands/change',
    mode: 'emit',
    signature: '\'commands/change\'(): void',
    jsDoc: '/**\n * A command was registered or unregistered. This is an unfiltered registry\n * notification because a global or scoped change may affect any UI view.\n * Observer failures are contained and cannot veto the registry mutation.\n * @mode emit\n */',
    summary: 'A command was registered or unregistered.',
  },
  {
    name: 'domain/changed',
    mode: 'emit',
    signature: '\'domain/changed\'(change: DomainChanged): void',
    jsDoc: '/**\n * A domain record or the global singleton changed, emitted once per write\n * strictly after the backend acknowledged durability. Events of one\n * domain arrive in its write-chain order.\n * @param change - domain, table (`\'\'` for global), key (`\'\'` for global),\n * operation discriminant, and on `put` the new snapshot.\n * @mode emit\n */',
    summary: 'A domain record or the global singleton changed, emitted once per write strictly after the backend acknowledged durability.',
  },
  {
    name: 'fs/edit-intent',
    mode: 'waterfall',
    signature: '\'fs/edit-intent\'(target: FsTarget, actor: object | undefined, next: () => { version: FsVersion } | undefined | Promise<{ version: FsVersion } | undefined>): Promise<{ version: FsVersion } | undefined>',
    jsDoc: '/**\n * Single-slot decision for the next {@link FileSystem.editText}. Calling\n * `next()` yields an unconditional edit; the first returned guard wins.\n * @param target - the resolved target about to be edited.\n * @param actor - the opaque tool-execution context the decider keys off.\n * @mode waterfall\n */',
    summary: 'Single-slot decision for the next FileSystem.editText.',
  },
  {
    name: 'fs/observed',
    mode: 'emit',
    signature: '\'fs/observed\'(target: FsTarget, version: FsVersion, actor: object | undefined): void',
    jsDoc: '/**\n * Record a successful observation. Listeners must be synchronous recorders:\n * throws fail the tool call and returned promises are not awaited.\n * @param target - the target that was read/written/edited.\n * @param version - the version the actor now holds as its observation.\n * @param actor - the observing tool-execution context; undefined records nothing useful.\n * @mode emit\n */',
    summary: 'Record a successful observation.',
  },
  {
    name: 'fs/write-intent',
    mode: 'waterfall',
    signature: '\'fs/write-intent\'(target: FsTarget, actor: object | undefined, next: () => FsWriteIntent | undefined | Promise<FsWriteIntent | undefined>): Promise<FsWriteIntent | undefined>',
    jsDoc: '/**\n * Single-slot decision for the next {@link FileSystem.writeText}. Calling\n * `next()` yields the bare provider\'s unconditional write; the first listener\n * that returns an intent owns the decision rather than composing with peers.\n * @param target - the resolved target about to be written.\n * @param actor - the opaque tool-execution context the decider keys off.\n * @mode waterfall\n */',
    summary: 'Single-slot decision for the next FileSystem.writeText.',
  },
  {
    name: 'goal/changed',
    mode: 'emit',
    signature: '\'goal/changed\'(this: import(\'@deepseek-ai/dsh-scope\').Scoped<Agent>, agent: Agent, change: GoalChanged): void',
    jsDoc: '/**\n * Goal mutation accepted by one live agent. The matching context event is\n * already appended or queued in that agent\'s active tool-batch FIFO.\n * Listener failures are contained.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.\n * @param agent - agent whose session owns the goal.\n * @param change - fresh current projection or clear tombstone.\n * @mode emit\n */',
    summary: 'Goal mutation accepted by one live agent.',
  },
  {
    name: 'llm/stream',
    mode: 'waterfall',
    signature: '\'llm/stream\'(this: LlmService, options: GenerateOptions, next: () => AsyncIterable<StreamChunk>): AsyncIterable<StreamChunk>',
    jsDoc: '/**\n * Waterfall around every streaming model call (retry, replay, routing).\n * Bound to the {@link LlmService}; call `next()` to reach the resolved\n * adapter\'s stream, or yield your own chunks to short-circuit.\n * @param options - the full request. A LOOP-built request carries the\n *   process-local {@link markAgentLoopRequest} identity and arrives deep-frozen\n *   (mutation throws): its content is a pure function of the session log (the\n *   reconstructability Agent Note), so listeners read it, never rewrite it.\n *   Hand-built calls do not carry that marker; their messages already obey\n *   the immutable creation contract.\n * @mode waterfall\n */',
    summary: 'Waterfall around every streaming model call (retry, replay, routing).',
  },
  {
    name: 'session/created',
    mode: 'emit',
    signature: '\'session/created\'(this: Scoped<Session>, session: Session): void',
    jsDoc: '/**\n * Creation announcement during session publication. A synchronous throw vetoes and rolls\n * back with a paired disposal; detach requested during dispatch is deferred.\n * A returned-promise rejection is logged but cannot retroactively veto this\n * synchronous boundary.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners\n * receive only sessions entered through that agent\'s context.\n * @param session - the session just entered and announced.\n * @dshScopeScan unsupported\n * @mode emit\n */',
    summary: 'Creation announcement during session publication.',
  },
  {
    name: 'session/disposed',
    mode: 'emit',
    signature: '\'session/disposed\'(this: Scoped<Session>, session: Session): void',
    jsDoc: '/**\n * Emitted once when an announced session leaves the store, including\n * publication rollback, but never for an entry whose creation announcement\n * did not begin. Listener failures are logged and contained.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`) reuses the owner scope.\n * @param session - the session that is no longer live in the store.\n * @dshScopeScan unsupported\n * @mode emit\n */',
    summary: 'Emitted once when an announced session leaves the store, including publication rollback, but never for an entry whose creation announcement did not begin.',
  },
  {
    name: 'session/event',
    mode: 'emit',
    signature: '\'session/event\'(this: Scoped<Session>, session: Session, event: SessionEvent): void',
    jsDoc: '/**\n * Post-commit, fire-and-forget append feed. The listener snapshot resolves\n * before the log push, but callbacks run after it; observer failures are\n * logged and contained without making the committed append fail.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners\n * receive only events from sessions entered through that agent\'s context.\n * @param session - the session whose log grew.\n * @param event - the appended event, exactly as recorded.\n * @dshScopeScan unsupported\n * @mode emit\n */',
    summary: 'Post-commit, fire-and-forget append feed.',
  },
  {
    name: 'session/flush',
    mode: 'parallel',
    signature: '\'session/flush\'(this: Scoped<Session>, session: Session): Promise<void> | void',
    jsDoc: '/**\n * Awaited parallel durability checkpoint: every listener runs and the\n * caller awaits all of them, with no waterfall veto. Dispatch through\n * {@link SessionStore.flush}. Scope-filtered dispatch\n * (`@deepseek-ai/dsh-scope`) reuses the session\'s owner scope.\n * @param session - the session whose buffered events must reach durable storage.\n * @dshScopeScan unsupported\n * @mode parallel\n */',
    summary: 'Awaited parallel durability checkpoint: every listener runs and the caller awaits all of them, with no waterfall veto.',
  },
  {
    name: 'slash/input-begin-command',
    mode: 'bail',
    signature: '\'slash/input-begin-command\'(request: BeginCommandRequest): true | undefined',
    jsDoc: '/**\n * Applies one command claim to the scoped Input. Dispatched with the\n * session\'s scope carrier; the owning session\'s input listener returns\n * `true` only after the phase and span CAS checks pass and the machine\n * actually mutated — producers treat anything else as "not applied".\n * @param request - Claim and menu-time span CAS.\n * @mode bail\n */',
    summary: 'Applies one command claim to the scoped Input.',
  },
  {
    name: 'slash/input-consume-token',
    mode: 'bail',
    signature: '\'slash/input-consume-token\'(request: ConsumeTokenRequest): true | undefined',
    jsDoc: '/**\n * Consumes one command token after business success (popup settle /\n * menu-pick execute). Same carrier routing and applied-truth contract.\n * @param request - Exact span or bare-token guard.\n * @mode bail\n */',
    summary: 'Consumes one command token after business success (popup settle / menu-pick execute).',
  },
  {
    name: 'slash/input-insert-reference',
    mode: 'bail',
    signature: '\'slash/input-insert-reference\'(request: InsertReferenceRequest): true | undefined',
    jsDoc: '/**\n * Inserts one reference into the scoped Input (same carrier routing and\n * applied-truth contract as begin-command).\n * @param request - Reference and menu-time span CAS.\n * @mode bail\n */',
    summary: 'Inserts one reference into the scoped Input (same carrier routing and applied-truth contract as begin-command).',
  },
  {
    name: 'slash/input-insert-text',
    mode: 'bail',
    signature: '\'slash/input-insert-text\'(request: InsertTextRequest): true | undefined',
    jsDoc: '/**\n * Replaces the trigger token span with literal text — the plain-text\n * reference path (decision 21). Same carrier routing and applied-truth\n * contract; the draft gains ordinary characters, no occurrence entry.\n * @param request - Replacement text and menu-time span CAS.\n * @mode bail\n */',
    summary: 'Replaces the trigger token span with literal text — the plain-text reference path (decision 21).',
  },
  {
    name: 'subagent/end',
    mode: 'emit',
    signature: '\'subagent/end\'(this: Scoped<SubagentService>, info: SubagentRunEndInfo): void',
    jsDoc: '/**\n * A ready child settled. Scope-filtered dispatch uses the same delegating\n * parent carrier as `subagent/start`, so the lifecycle pair reaches the\n * same scoped audience.\n * @param info - the run identity and terminal outcome.\n * @dshScopeScan unsupported\n * @mode emit\n */',
    summary: 'A ready child settled.',
  },
  {
    name: 'subagent/provider-added',
    mode: 'emit',
    signature: '\'subagent/provider-added\'(provider: SubagentProvider): void',
    jsDoc: '/**\n * A provider became resolvable in the registry.\n * @param provider - the registered provider.\n * @mode emit\n */',
    summary: 'A provider became resolvable in the registry.',
  },
  {
    name: 'subagent/provider-removed',
    mode: 'emit',
    signature: '\'subagent/provider-removed\'(name: string): void',
    jsDoc: '/**\n * A provider left the registry. Accepted runs remain holder-owned.\n * @param name - the provider name that no longer resolves.\n * @mode emit\n */',
    summary: 'A provider left the registry.',
  },
  {
    name: 'subagent/start',
    mode: 'emit',
    signature: '\'subagent/start\'(this: Scoped<SubagentService>, info: SubagentRunInfo): void',
    jsDoc: '/**\n * A provider established a ready child. For in-process providers,\n * `ctx.agents.get(info.id)` resolves during this notification.\n * Scope-filtered dispatch keys the carrier by the delegating parent, so a\n * parent-scoped listener observes only its own delegations. Paired with\n * `subagent/end`.\n * @param info - the provider and ready child identity.\n * @dshScopeScan unsupported\n * @mode emit\n */',
    summary: 'A provider established a ready child.',
  },
  {
    name: 'system-prompt/assemble',
    mode: 'waterfall',
    signature: '\'system-prompt/assemble\'(this: Scoped<SystemPrompt>, assembly: PromptAssembly, context: AssembleContext, next: () => Promise<PromptAssembly>): Promise<PromptAssembly>',
    jsDoc: '/**\n * Expert waterfall over the assembled sections, tools, and variables.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): scoped listeners\n * receive only that scope\'s assemblies. The returned value is authoritative.\n * A supplied signal controls only this explicit assembly request and must not\n * be retained to control later turns.\n * @param assembly - the mutable assembly built from registered providers.\n * @param context - the caller\'s per-assembly context.\n * @mode waterfall\n */',
    summary: 'Expert waterfall over the assembled sections, tools, and variables.',
  },
  {
    name: 'system-prompt/change',
    mode: 'emit',
    signature: '\'system-prompt/change\'(): void',
    jsDoc: '/**\n * Emitted when any prompt provider changes. This registry notification is\n * unfiltered because a global change affects every scope.\n * @mode emit\n */',
    summary: 'Emitted when any prompt provider changes.',
  },
  {
    name: 'telemetry/record',
    mode: 'waterfall',
    signature: '\'telemetry/record\'(record: TelemetryRecord, next: () => TelemetryRecord): TelemetryRecord',
    jsDoc: '/**\n * Transform one outbound record before it reaches the backend. This\n * waterfall is the seam\'s redaction extension point. It ships NO rules\n * of its own: the\n * innermost `next()` passes the record through unchanged, and with no\n * listener mounted records reach the backend as captured, so exported\n * data is exactly as clean as the rules a deployment mounts. Listeners\n * stack by transforming `next()`\'s return value; returning without\n * `next()` replaces everything beneath. Dispatched synchronously on the\n * capture hot path inside the coordinator\'s containment: a throwing\n * listener withholds that one record (fail-closed) and never reaches the\n * agent loop. Redaction applies to the exported copy only; the canonical\n * session log is never rewritten.\n * @param record - the candidate record, already the coordinator\'s own deep\n *   copy; listeners return a (possibly new) record and must not mutate it.\n * @mode waterfall\n */',
    summary: 'Transform one outbound record before it reaches the backend.',
  },
  {
    name: 'tools/change',
    mode: 'emit',
    signature: '\'tools/change\'(): void',
    jsDoc: '/**\n * A tool was registered or unregistered, or a scoped restriction changed\n * (the available tool set changed — possibly for one scope only). An\n * UNFILTERED registry-subject notification, deliberately not scope-filtered\n * dispatch: a global change concerns every agent\'s next assembly, so a\n * scoped listener subscribing here sees every change, not just its own\n * scope\'s.\n * @mode emit\n */',
    summary: 'A tool was registered or unregistered, or a scoped restriction changed (the available tool set changed — possibly for one scope only).',
  },
  {
    name: 'tools/code-dispatch-log',
    mode: 'waterfall',
    signature: '\'tools/code-dispatch-log\'(this: Scoped<ToolRegistry>, dispatch: CodeDispatchLog, next: () => Promise<ContentBlock[]>): Promise<ContentBlock[]>',
    jsDoc: '/**\n * Shape the DURABLE LOG COPY of one `run_code` sub-dispatch outcome before\n * the bridge appends its `tool/code-dispatch` event. `next()` keeps the\n * content unchanged; a listener may return replacement blocks (e.g. the\n * spill policy\'s preview + locator for an oversized text result). Only the\n * logged copy is affected — the program already received the complete\n * value, and the model sees neither. A throwing listener is contained:\n * the bridge falls back to logging the unshaped content.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent\'s dispatches.\n * @param dispatch - the parent execution, sub-call identity, and the settled content to log.\n * @mode waterfall\n */',
    summary: 'Shape the DURABLE LOG COPY of one `run_code` sub-dispatch outcome before the bridge appends its `tool/code-dispatch` event.',
  },
  {
    name: 'tools/execute',
    mode: 'waterfall',
    signature: '\'tools/execute\'(this: Scoped<ToolRegistry>, exec: ToolDispatchExecution, next: () => Promise<ToolExecutionResult>): Promise<ToolExecutionResult>',
    jsDoc: '/**\n * Around-dispatch waterfall for timeout, retry, or metrics. `next()` returns\n * a normalized result; wrappers may change only `exec.signal`, while call\n * identity remains immutable. The registry re-fuses the original caller\n * signal before the body, so replacement cannot detach caller cancellation;\n * wrappers must still restore their signal and reach quiescence.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent\'s calls.\n * @param exec - the allowed call about to dispatch (name, parsed arguments, caller agent, signal).\n * @mode waterfall\n */',
    summary: 'Around-dispatch waterfall for timeout, retry, or metrics.',
  },
  {
    name: 'tools/post-execute',
    mode: 'waterfall',
    signature: '\'tools/post-execute\'(this: Scoped<ToolRegistry>, exec: ToolExecution, result: Readonly<ToolExecutionResult>, next: () => Promise<PostToolDecision>): Promise<PostToolDecision>',
    jsDoc: '/**\n * Accept, replace, enrich, or block a normalized dispatch result. `next()`\n * accepts it unchanged; thrown tools still reach this seam as errors. Async\n * listeners must observe `exec.signal`; after they settle, caller\n * cancellation replaces only a successful accepted outcome with the code\n * selected by whether the tool body was invoked.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent\'s calls.\n * @param exec - the call that just ran (name, parsed arguments, caller agent).\n * @param result - the dispatch outcome a listener may accept, replace, or block.\n * @mode waterfall\n */',
    summary: 'Accept, replace, enrich, or block a normalized dispatch result.',
  },
  {
    name: 'tools/pre-execute',
    mode: 'waterfall',
    signature: '\'tools/pre-execute\'(this: Scoped<ToolRegistry>, exec: ToolExecution, next: () => Promise<PreToolDecision>): Promise<PreToolDecision>',
    jsDoc: '/**\n * Allow, deny, or ask before dispatch. `next()` delegates to allow; missing\n * approval support turns `ask` into denial. Async gates must observe\n * `exec.signal`; the registry rechecks cancellation after they settle but\n * never abandons their promise.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent\'s calls.\n * @param exec - the pending call (name, parsed arguments, caller agent).\n * @mode waterfall\n */',
    summary: 'Allow, deny, or ask before dispatch.',
  },
  {
    name: 'tools/result',
    mode: 'emit',
    signature: '\'tools/result\'(this: Scoped<ToolRegistry>, exec: Readonly<ToolExecution>, result: Readonly<ToolExecutionResult>): undefined',
    jsDoc: '/**\n * Observe the frozen, lossless-JSON final outcome. Listener failures are contained.\n * Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): keyed by `exec.agent`.\n * @param exec - the execution object that traversed the pipeline.\n * @param result - a deep-frozen snapshot of the final returned result.\n * @mode emit\n */',
    summary: 'Observe the frozen, lossless-JSON final outcome.',
  },
  {
    name: 'workflow/agent-end',
    mode: 'emit',
    signature: '\'workflow/agent-end\'(info: WorkflowRunInfo, agent: WorkflowAgentEndInfo): void',
    jsDoc: '/**\n * One `agent()` call settled (clean result, child failure, or run\n * cancellation). Paired with {@link Events[\'workflow/agent-start\']} by\n * `agent.seq`, exactly once per started call on every stop path — on an\n * engine termination path (a worker killed past its grace) the end is\n * engine-synthesized with outcome `\'cancelled\'`.\n * @param info - the run\'s identity snapshot.\n * @param agent - the call identity plus its outcome.\n * @mode emit\n */',
    summary: 'One `agent()` call settled (clean result, child failure, or run cancellation).',
  },
  {
    name: 'workflow/agent-start',
    mode: 'emit',
    signature: '\'workflow/agent-start\'(info: WorkflowRunInfo, agent: WorkflowAgentInfo): void',
    jsDoc: '/**\n * One `agent()` call established a ready child run. Paired with\n * {@link Events[\'workflow/agent-end\']} by `agent.seq`. A call that never\n * receives a ready run from the provider emits neither\n * event in this pair.\n * @param info - the run\'s identity snapshot.\n * @param agent - the call\'s sequence number, label, phase, and child id.\n * @mode emit\n */',
    summary: 'One `agent()` call established a ready child run.',
  },
  {
    name: 'workflow/end',
    mode: 'emit',
    signature: '\'workflow/end\'(info: WorkflowRunInfo, result: WorkflowResultInfo): void',
    jsDoc: '/**\n * A workflow run settled (any stop reason). Fired when\n * {@link WorkflowRun.result} resolves. Paired with\n * {@link Events[\'workflow/start\']}.\n * @param info - the run\'s identity snapshot.\n * @param result - the outcome data (stop reason, error, agent count) —\n *   deliberately WITHOUT the result value (see {@link WorkflowResultInfo}).\n * @mode emit\n */',
    summary: 'A workflow run settled (any stop reason).',
  },
  {
    name: 'workflow/log',
    mode: 'emit',
    signature: '\'workflow/log\'(info: WorkflowRunInfo, message: string): void',
    jsDoc: '/**\n * The script emitted a narration line (a `log(message)` call).\n * @param info - the run\'s identity snapshot.\n * @param message - the logged message, verbatim.\n * @mode emit\n */',
    summary: 'The script emitted a narration line (a `log(message)` call).',
  },
  {
    name: 'workflow/phase',
    mode: 'emit',
    signature: '\'workflow/phase\'(info: WorkflowRunInfo, title: string): void',
    jsDoc: '/**\n * The script entered a phase (a `phase(title)` call) — progress grouping\n * for observers; no execution semantics.\n * @param info - the run\'s identity snapshot.\n * @param title - the phase title, verbatim.\n * @mode emit\n */',
    summary: 'The script entered a phase (a `phase(title)` call) — progress grouping for observers; no execution semantics.',
  },
  {
    name: 'workflow/start',
    mode: 'emit',
    signature: '\'workflow/start\'(info: WorkflowRunInfo): void',
    jsDoc: '/**\n * A workflow run started — the script\'s meta block validated, the body\n * about to execute. Paired with {@link Events[\'workflow/end\']}.\n * @param info - the run\'s identity snapshot (id + meta).\n * @mode emit\n */',
    summary: 'A workflow run started — the script\'s meta block validated, the body about to execute.',
  },
]

/** Shapes of every exported type the SERVICE_API signatures reference (transitively), sorted by name. */
export const TYPE_API: readonly TypeApiEntry[] = [
  {
    name: 'Agent',
    declaration: 'export interface Agent {\n    readonly id: SessionId;\n    readonly options: AgentOptions;\n    readonly session: Session;\n    readonly status: AgentStatus;\n    readonly acceptsNextStep: boolean;\n    readonly ctx: Context;\n    send(message: UserMessage, options: SendOptions): void;\n    cancel(cause: AgentCancelCause, options?: CancelOptions): void;\n    whenIdle(): Promise<void>;\n    followup(message: UserMessage): void;\n    steer(message: UserMessage): void;\n    inject(message: UserMessage): void;\n}',
  },
  {
    name: 'AgentCancelCause',
    declaration: 'export type AgentCancelCause = {\n    readonly kind: \'user\';\n} | {\n    readonly kind: \'parent\';\n};',
  },
  {
    name: 'AgentFactory',
    declaration: 'export interface AgentFactory {\n    createAgent(ownerCtx: Context, options: CreateAgentOptions): Promise<AgentHandle>;\n    resume(ownerCtx: Context, options: ResumeAgentOptions): Promise<AgentHandle>;\n}',
  },
  {
    name: 'AgentHandle',
    declaration: 'export interface AgentHandle {\n    agent: Agent;\n    dispose(): Promise<void>;\n}',
  },
  {
    name: 'AgentOptions',
    declaration: 'export interface AgentOptions {\n    provider?: string;\n    model?: string;\n    maxTokens?: number;\n}',
  },
  {
    name: 'AgentStatus',
    declaration: 'export type AgentStatus = \'idle\' | \'running\';',
  },
  {
    name: 'ApprovalOutcome',
    declaration: 'export type ApprovalOutcome = \'allowed-once\' | \'rejected\' | \'cancelled\' | \'unavailable\';',
  },
  {
    name: 'ApprovalPolicy',
    declaration: 'export type ApprovalPolicy = \'ask\' | \'never\';',
  },
  {
    name: 'ApprovalRequest',
    declaration: 'export interface ApprovalRequest {\n    readonly agent: Agent;\n    readonly toolName: string;\n    readonly callId?: CallId;\n    readonly reason?: string;\n    readonly signal?: AbortSignal;\n}',
  },
  {
    name: 'AskUserQuestionAnswer',
    declaration: 'export interface AskUserQuestionAnswer {\n    answers: AskUserQuestionAnswerItem[];\n}',
  },
  {
    name: 'AskUserQuestionAnswerItem',
    declaration: 'export interface AskUserQuestionAnswerItem {\n    id: string;\n    selected: string[];\n    custom?: string;\n}',
  },
  {
    name: 'AskUserQuestionItem',
    declaration: 'export interface AskUserQuestionItem {\n    id: string;\n    question: string;\n    detail?: string;\n    header?: string;\n    options?: AskUserQuestionOption[];\n    multiSelect?: boolean;\n}',
  },
  {
    name: 'AskUserQuestionOption',
    declaration: 'export interface AskUserQuestionOption {\n    label: string;\n    description?: string;\n}',
  },
  {
    name: 'AskUserQuestionRequest',
    declaration: 'export interface AskUserQuestionRequest {\n    questions: AskUserQuestionItem[];\n    agent?: Agent;\n    signal?: AbortSignal;\n}',
  },
  {
    name: 'AssembleContext',
    declaration: 'export interface AssembleContext {\n    scope?: ScopeKey;\n    signal?: AbortSignal;\n}',
  },
  {
    name: 'AssembledSection',
    declaration: 'export interface AssembledSection {\n    name: string;\n    text: string;\n}',
  },
  {
    name: 'AssistantMessage',
    declaration: 'export interface AssistantMessage extends Message {\n    readonly role: \'assistant\';\n    readonly source: ModelMessageSource;\n}',
  },
  {
    name: 'AssistantProvenance',
    declaration: 'export interface AssistantProvenance {\n    provider: string;\n    model: string;\n    replayState?: unknown;\n}',
  },
  {
    name: 'BashEnvContributor',
    declaration: 'export interface BashEnvContributor {\n    name: string;\n    variables: Readonly<Record<DshEnvironmentKey, BashEnvVariable>>;\n    resolve(execution: ToolExecution): Readonly<Partial<Record<DshEnvironmentKey, string>>>;\n}',
  },
  {
    name: 'BashEnvVariable',
    declaration: 'export interface BashEnvVariable {\n    description: string;\n}',
  },
  {
    name: 'BashEnvVariableInfo',
    declaration: 'export interface BashEnvVariableInfo extends BashEnvVariable {\n    contributor: string;\n    key: DshEnvironmentKey;\n}',
  },
  {
    name: 'BashExecRequest',
    declaration: 'export interface BashExecRequest {\n    command: string;\n    workdir?: string | undefined;\n    timeoutMs?: number | undefined;\n    stdoutMaxBytes?: number | undefined;\n    signal?: AbortSignal | undefined;\n    stdin?: string | undefined;\n    env?: Record<string, string> | undefined;\n    dshEnv?: DshEnvironment | undefined;\n    sandboxPolicy?: SandboxExecutionPolicy | undefined;\n}',
  },
  {
    name: 'BashExecSpec',
    declaration: 'export interface BashExecSpec {\n    command: string;\n    workdir: string;\n    timeoutMs: number;\n    stdoutMaxBytes: number;\n    signal?: AbortSignal | undefined;\n    stdin?: string | undefined;\n    env?: Record<string, string> | undefined;\n    dshEnv?: DshEnvironment | undefined;\n    sandboxPolicy: SandboxExecutionPolicy | undefined;\n}',
  },
  {
    name: 'BashProcess',
    declaration: 'export interface BashProcess {\n    status: BashProcessStatus;\n    exitCode: number | null;\n    signal: NodeJS.Signals | null;\n    readonly done: Promise<void>;\n    sandbox?: BashSandboxInfo;\n    readOutput(): BashProcessRead;\n    kill(): boolean;\n}',
  },
  {
    name: 'BashProcessRead',
    declaration: 'export interface BashProcessRead {\n    delta: string;\n    lossy: boolean;\n    stdoutSpillPath?: string;\n    stderrSpillPath?: string;\n}',
  },
  {
    name: 'BashProcessStatus',
    declaration: 'export type BashProcessStatus = \'running\' | \'completed\' | \'killed\';',
  },
  {
    name: 'BashRunResult',
    declaration: 'export interface BashRunResult {\n    exitCode: number | null;\n    signal: NodeJS.Signals | null;\n    timedOut: boolean;\n    aborted: boolean;\n    timeoutMs: number;\n    stdout: CollectedOutput;\n    stderr: CollectedOutput;\n    sandbox?: BashSandboxInfo;\n}',
  },
  {
    name: 'BashSandboxInfo',
    declaration: 'export interface BashSandboxInfo {\n    mode: SandboxMode;\n    denied: boolean;\n    enforcement?: SandboxEnforcement;\n    runnerFailed?: boolean;\n}',
  },
  {
    name: 'Branded',
    declaration: 'export type Branded<B extends string> = string & {\n    readonly [BRAND]: B;\n};',
  },
  {
    name: 'CallId',
    declaration: 'export type CallId = Branded<\'CallId\'>;',
  },
  {
    name: 'CancelOptions',
    declaration: 'export interface CancelOptions {\n    keepInbox?: boolean;\n}',
  },
  {
    name: 'CodeBindingErrorClass',
    declaration: 'export interface CodeBindingErrorClass {\n    name: string;\n    memberNameProperty: string;\n}',
  },
  {
    name: 'CodeBindingFunction',
    declaration: 'export type CodeBindingFunction = (args: unknown) => Promise<CodeJsonValue>;',
  },
  {
    name: 'CodeBindingNamespace',
    declaration: 'export interface CodeBindingNamespace {\n    global: string;\n    functions: Record<string, CodeBindingFunction>;\n    errorClass?: CodeBindingErrorClass;\n}',
  },
  {
    name: 'CodeJsonValue',
    declaration: 'export type CodeJsonValue = null | boolean | number | string | CodeJsonValue[] | {\n    [key: string]: CodeJsonValue;\n};',
  },
  {
    name: 'CodeRunFailure',
    declaration: 'export interface CodeRunFailure {\n    kind: \'exception\' | \'timeout\' | \'abort\' | \'worker-exit\' | \'invalid-output\' | \'output-limit\';\n    message: string;\n}',
  },
  {
    name: 'CodeRunRequest',
    declaration: 'export interface CodeRunRequest {\n    program: string;\n    bindings: CodeBindingNamespace[];\n    signal?: AbortSignal;\n}',
  },
  {
    name: 'CodeRunResult',
    declaration: 'export interface CodeRunResult {\n    value?: CodeJsonValue;\n    logs: string[];\n    error?: CodeRunFailure;\n}',
  },
  {
    name: 'CollectedOutput',
    declaration: 'export interface CollectedOutput {\n    text: string;\n    truncated: boolean;\n    spillPath?: string;\n}',
  },
  {
    name: 'CommandDefinition',
    declaration: 'export interface CommandDefinition {\n    readonly name: string;\n    readonly description: string;\n    readonly input?: CommandInputDescriptor;\n    readonly handler: (invocation: CommandInvocation) => CommandResult | Promise<CommandResult>;\n}',
  },
  {
    name: 'CommandDescriptor',
    declaration: 'export interface CommandDescriptor {\n    readonly name: string;\n    readonly description: string;\n    readonly input?: CommandInputDescriptor;\n}',
  },
  {
    name: 'CommandExecution',
    declaration: 'export interface CommandExecution {\n    readonly commandId: CommandId;\n    readonly result: CommandResult;\n}',
  },
  {
    name: 'CommandId',
    declaration: 'export type CommandId = Branded<\'CommandId\'>;',
  },
  {
    name: 'CommandInputDescriptor',
    declaration: 'export interface CommandInputDescriptor {\n    readonly hint: string;\n}',
  },
  {
    name: 'CommandInvocation',
    declaration: 'export interface CommandInvocation {\n    readonly agent: Agent;\n    readonly rawInput: string;\n    readonly signal: AbortSignal;\n}',
  },
  {
    name: 'CommandResult',
    declaration: 'export type CommandResult = {\n    readonly kind: \'success\';\n    readonly text?: string;\n} | {\n    readonly kind: \'error\';\n    readonly text: string;\n};',
  },
  {
    name: 'CompactAgentContext',
    declaration: 'export interface CompactAgentContext {\n    session: Session;\n    options: {\n        provider?: string;\n        model?: string;\n    };\n}',
  },
  {
    name: 'CompactionResult',
    declaration: 'export interface CompactionResult {\n    startSeq: number;\n    summarySeq: number;\n    endSeq: number;\n    summary: ContentBlock[];\n    shadowedRange: {\n        start: number;\n        end: number;\n    };\n    shadowedSeqs: number[];\n    shadowedTokenCount: number;\n}',
  },
  {
    name: 'CompactionTrigger',
    declaration: 'export type CompactionTrigger = \'pressure\' | \'context-overflow\';',
  },
  {
    name: 'ConfinedArgv',
    declaration: 'export interface ConfinedArgv {\n    argv: string[];\n    enforcement: SandboxEnforcement;\n    denialSignatures: readonly string[];\n    runnerFailureSignatures: readonly string[];\n}',
  },
  {
    name: 'ConfinedSandboxMode',
    declaration: 'export type ConfinedSandboxMode = Exclude<SandboxMode, \'danger-full-access\'>;',
  },
  {
    name: 'ContentBlockMap',
    declaration: 'export interface ContentBlockMap {\n    \'text\': TextBlock;\n    \'reasoning\': ReasoningBlock;\n    \'tool-call\': ToolCallBlock;\n    \'tool-result\': ToolResultBlock;\n}',
  },
  {
    name: 'ContentBlockType',
    declaration: 'export type ContentBlockType = keyof ContentBlockMap;',
  },
  {
    name: 'CreateAgentOptions',
    declaration: 'export interface CreateAgentOptions {\n    readonly sessionId: SessionId;\n    readonly meta?: {\n        readonly cwd?: string;\n        readonly parentSession?: SessionId;\n        readonly seedLength?: number;\n        readonly delegationDepth?: number;\n    };\n    readonly seed?: readonly SessionEvent[];\n    readonly agentOptions?: AgentOptions;\n    readonly signal?: AbortSignal;\n    readonly setup?: (agentCtx: Context) => Promise<void> | void;\n}',
  },
  {
    name: 'CreateGoalRequest',
    declaration: 'export interface CreateGoalRequest {\n    readonly objective: string;\n    readonly maxGoalRounds?: number;\n}',
  },
  {
    name: 'CreateSessionOptions',
    declaration: 'export interface CreateSessionOptions {\n    readonly seed?: readonly SessionEvent[];\n    readonly meta?: {\n        readonly cwd?: string;\n        readonly parentSession?: SessionId;\n        readonly createdAt?: number;\n        readonly seedLength?: number;\n        readonly delegationDepth?: number;\n    };\n}',
  },
  {
    name: 'DiffCallView',
    declaration: 'export interface DiffCallView {\n    card: \'diff\';\n    title: string;\n    diffs: FileDiff[];\n    locations?: FileLocation[];\n}',
  },
  {
    name: 'DiffResultView',
    declaration: 'export interface DiffResultView {\n    card: \'diff\';\n    title?: string;\n    diffs: FileDiff[];\n}',
  },
  {
    name: 'Domain',
    declaration: 'export interface Domain<S extends DomainSpec> {\n    readonly name: string;\n    readonly global: DomainGlobalHandleOf<S>;\n    table<N extends keyof S[\'tables\'] & string>(name: N): KvTable<TableKeyOf<S, N>, TableValueOf<S, N>>;\n    close(): Promise<void>;\n}',
  },
  {
    name: 'DomainGlobal',
    declaration: 'export interface DomainGlobal<G> {\n    get(): G;\n    set(value: G): Promise<void>;\n}',
  },
  {
    name: 'DomainGlobalHandleOf',
    declaration: 'export type DomainGlobalHandleOf<S extends DomainSpec> = S extends {\n    readonly global: DomainGlobalSpec<infer G>;\n} ? DomainGlobal<G> : never;',
  },
  {
    name: 'DomainGlobalSpec',
    declaration: 'export interface DomainGlobalSpec<G> {\n    readonly schema: ZodType<G>;\n    readonly initial: G;\n}',
  },
  {
    name: 'DomainImpl',
    declaration: 'export class DomainImpl {\n    readonly name: string;\n    constructor(private readonly ctx: Context, spec: DomainSpec, private readonly unit: KvUnit, records: Map<string, Map<string, unknown>>, globalValue: unknown, private readonly onClosed: () => void);\n    get global(): DomainGlobal<unknown>;\n    table(name: string): KvTable<string, unknown>;\n    close(): Promise<void>;\n}',
  },
  {
    name: 'DomainSpec',
    declaration: 'export interface DomainSpec {\n    readonly name: string;\n    readonly version: number;\n    readonly global?: DomainGlobalSpec<unknown>;\n    readonly tables: Record<string, DomainTableSpec>;\n}',
  },
  {
    name: 'DomainTableSpec',
    declaration: 'export interface DomainTableSpec<K extends string = string, V = unknown> {\n    readonly valueSchema: ZodType<V>;\n    readonly __key?: K;\n}',
  },
  {
    name: 'DshEnvironment',
    declaration: 'export type DshEnvironment = Readonly<Record<DshEnvironmentKey, string>>;',
  },
  {
    name: 'DshEnvironmentKey',
    declaration: 'export type DshEnvironmentKey = `${typeof DSH_ENV_PREFIX}${string}`;',
  },
  {
    name: 'EditGoalRequest',
    declaration: 'export interface EditGoalRequest {\n    readonly objective?: string;\n    readonly maxGoalRounds?: number;\n}',
  },
  {
    name: 'EpochHeader',
    declaration: 'export interface EpochHeader {\n    config: LlmCallConfig;\n    system?: string;\n    tools?: ToolSchema[];\n}',
  },
  {
    name: 'FileDiff',
    declaration: 'export interface FileDiff {\n    path: string;\n    oldText: string | null;\n    newText: string;\n}',
  },
  {
    name: 'FileLocation',
    declaration: 'export interface FileLocation {\n    path: string;\n    line?: number;\n}',
  },
  {
    name: 'FinishReason',
    declaration: 'export type FinishReason = FinishReasonMap[keyof FinishReasonMap];',
  },
  {
    name: 'FinishReasonMap',
    declaration: 'export interface FinishReasonMap {\n    \'stop\': {\n        kind: \'stop\';\n    };\n    \'tool-calls\': {\n        kind: \'tool-calls\';\n    };\n    \'max-tokens\': {\n        kind: \'max-tokens\';\n    };\n    \'aborted\': {\n        kind: \'aborted\';\n        failure: LlmFailure;\n    };\n    \'error\': {\n        kind: \'error\';\n        failure: LlmFailure;\n    };\n}',
  },
  {
    name: 'FsDirEntry',
    declaration: 'export interface FsDirEntry {\n    name: string;\n    type: \'file\' | \'directory\' | \'other\';\n    target: FsTarget;\n    version?: FsVersion;\n    size?: number;\n}',
  },
  {
    name: 'FsEditOutcome',
    declaration: 'export interface FsEditOutcome {\n    version: FsVersion;\n    before: string;\n    after: string;\n}',
  },
  {
    name: 'FsEditRequest',
    declaration: 'export interface FsEditRequest {\n    oldString: string;\n    newString: string;\n    replaceAll: boolean;\n}',
  },
  {
    name: 'FsInfo',
    declaration: 'export interface FsInfo {\n    version: FsVersion;\n    type: \'file\' | \'directory\' | \'other\';\n    size?: number;\n}',
  },
  {
    name: 'FsPathInfo',
    declaration: 'export interface FsPathInfo {\n    version: FsVersion;\n    type: \'file\' | \'directory\' | \'symlink\' | \'other\';\n    size?: number;\n}',
  },
  {
    name: 'FsTarget',
    declaration: 'export interface FsTarget {\n    targetKey: FsTargetKey;\n    displayPath: string;\n}',
  },
  {
    name: 'FsTargetKey',
    declaration: 'export type FsTargetKey = Branded<\'FsTargetKey\'>;',
  },
  {
    name: 'FsVersion',
    declaration: 'export type FsVersion = Branded<\'FsVersion\'>;',
  },
  {
    name: 'FsWriteIntent',
    declaration: 'export type FsWriteIntent = {\n    kind: \'createIfAbsent\';\n} | {\n    kind: \'replaceIfVersion\';\n    version: FsVersion;\n};',
  },
  {
    name: 'FsWriteOutcome',
    declaration: 'export interface FsWriteOutcome {\n    operation: \'create\' | \'update\';\n    version: FsVersion;\n    before: string | null;\n    after: string;\n}',
  },
  {
    name: 'GenerateOptions',
    declaration: 'export interface GenerateOptions {\n    provider: string;\n    model: string;\n    reasoningEffort?: ReasoningEffortId;\n    messages: Message[];\n    system?: string;\n    tools?: ToolSchema[];\n    temperature?: number;\n    maxTokens?: number;\n    stop?: string[];\n    signal?: AbortSignal;\n    sessionId?: Branded<\'SessionId\'>;\n    purpose?: \'compaction\' | \'session-title\';\n}',
  },
  {
    name: 'GenericCallView',
    declaration: 'export interface GenericCallView {\n    card: \'generic\';\n    title: string;\n    kind?: ToolCallKind;\n    rawInput?: unknown;\n    content?: ContentBlock[];\n    locations?: FileLocation[];\n}',
  },
  {
    name: 'GenericResultView',
    declaration: 'export interface GenericResultView {\n    card: \'generic\';\n    title?: string;\n    content?: ContentBlock[];\n}',
  },
  {
    name: 'GoalActivation',
    declaration: 'export type GoalActivation = \'armed\' | \'disarmed\';',
  },
  {
    name: 'GoalBlockReason',
    declaration: 'export interface GoalBlockReason {\n    readonly code: string;\n    readonly message: string;\n}',
  },
  {
    name: 'GoalId',
    declaration: 'export type GoalId = Branded<\'GoalId\'>;',
  },
  {
    name: 'GoalPhase',
    declaration: 'export type GoalPhase = \'active\' | \'paused\' | \'blocked\' | \'complete\';',
  },
  {
    name: 'GoalRef',
    declaration: 'export interface GoalRef {\n    readonly id: GoalId;\n    readonly revision: number;\n}',
  },
  {
    name: 'GoalSnapshot',
    declaration: 'export interface GoalSnapshot extends GoalRef {\n    readonly objective: string;\n    readonly phase: GoalPhase;\n    readonly blockedReason?: GoalBlockReason;\n    readonly maxGoalRounds: number;\n}',
  },
  {
    name: 'GoalView',
    declaration: 'export interface GoalView extends GoalSnapshot {\n    readonly roundsStarted: number;\n    readonly createdAt: number;\n    readonly updatedAt: number;\n    readonly activation: GoalActivation;\n}',
  },
  {
    name: 'InvariantFailure',
    declaration: 'export type InvariantFailure = (message: string) => never;',
  },
  {
    name: 'InvariantInstaller',
    declaration: 'export interface InvariantInstaller {\n    (ctx: Context, fail: InvariantFailure): void | Promise<void>;\n    readonly inject?: Inject;\n}',
  },
  {
    name: 'JsonSchemaNode',
    declaration: 'export interface JsonSchemaNode {\n    type?: JsonSchemaType;\n    oneOf?: JsonSchemaNode[];\n    properties?: Record<string, JsonSchemaNode>;\n    required?: string[];\n    additionalProperties?: boolean;\n    items?: JsonSchemaNode;\n    enum?: JsonSchemaScalar[];\n    const?: JsonSchemaScalar;\n    description?: string;\n    title?: string;\n    default?: JsonValue;\n    examples?: JsonValue;\n}',
  },
  {
    name: 'JsonSchemaScalar',
    declaration: 'export type JsonSchemaScalar = string | number | boolean | null;',
  },
  {
    name: 'JsonSchemaType',
    declaration: 'export type JsonSchemaType = \'object\' | \'array\' | \'string\' | \'number\' | \'integer\' | \'boolean\' | \'null\';',
  },
  {
    name: 'JsonValue',
    declaration: 'export type JsonValue = null | boolean | number | string | JsonValue[] | {\n    [key: string]: JsonValue;\n};',
  },
  {
    name: 'KvTable',
    declaration: 'export interface KvTable<K extends string, V> {\n    get(key: K): V | undefined;\n    entries(): IterableIterator<[\n        K,\n        V\n    ]>;\n    keys(): IterableIterator<K>;\n    readonly size: number;\n    put(key: K, value: V): Promise<void>;\n    delete(key: K): Promise<boolean>;\n    update(key: K, fn: (current: V) => V): Promise<V>;\n}',
  },
  {
    name: 'KvUnit',
    declaration: 'export interface KvUnit {\n    loadAll(): Promise<{\n        tables: Record<string, Record<string, unknown>>;\n        global: unknown;\n    }>;\n    putRecord(table: string, key: string, value: unknown): Promise<void>;\n    deleteRecord(table: string, key: string): Promise<void>;\n    setGlobal(value: unknown): Promise<void>;\n    close(): Promise<void>;\n}',
  },
  {
    name: 'LlmAdapter',
    declaration: 'export abstract class LlmAdapter {\n    providerInfo(provider: string): LlmProviderInfo;\n    providerRetryPolicy(_provider: string): ResolvedRetryPolicy | undefined;\n    listModels(_provider: string): Promise<readonly LlmModelInfo[]>;\n    resolveModel(provider: string, model: string, _signal?: AbortSignal): Promise<LlmResolvedModelInfo>;\n    abstract stream(options: GenerateOptions): AsyncIterable<StreamChunk>;\n}',
  },
  {
    name: 'LlmCallConfig',
    declaration: 'export interface LlmCallConfig {\n    provider: string;\n    model: string;\n    reasoningEffort?: ReasoningEffortId;\n    temperature?: number;\n    maxTokens?: number;\n    stop?: string[];\n}',
  },
  {
    name: 'LlmFailure',
    declaration: 'export interface LlmFailure {\n    readonly message: string;\n    readonly code: string;\n    readonly status?: number;\n    readonly providerRetryAfterMs?: number;\n    readonly requestId?: ProviderRequestId;\n}',
  },
  {
    name: 'LlmModelContext',
    declaration: 'export interface LlmModelContext {\n    contextWindow: number;\n}',
  },
  {
    name: 'LlmModelInfo',
    declaration: 'export interface LlmModelInfo {\n    provider: string;\n    id: string;\n    name: string;\n    description?: string;\n}',
  },
  {
    name: 'LlmModelReasoningInfo',
    declaration: 'export interface LlmModelReasoningInfo {\n    efforts: readonly LlmReasoningEffortInfo[];\n    defaultEffort?: ReasoningEffortId;\n}',
  },
  {
    name: 'LlmProviderInfo',
    declaration: 'export interface LlmProviderInfo {\n    id: string;\n    name: string;\n}',
  },
  {
    name: 'LlmReasoningEffortInfo',
    declaration: 'export interface LlmReasoningEffortInfo {\n    id: ReasoningEffortId;\n    name: string;\n    description?: string;\n}',
  },
  {
    name: 'LlmResolvedModelInfo',
    declaration: 'export interface LlmResolvedModelInfo extends LlmModelInfo {\n    context?: LlmModelContext;\n    reasoning?: LlmModelReasoningInfo;\n}',
  },
  {
    name: 'Message',
    declaration: 'export interface Message {\n    readonly id: MessageId;\n    readonly role: \'system\' | \'user\' | \'assistant\';\n    readonly content: ContentBlock[];\n    readonly source: MessageSource;\n}',
  },
  {
    name: 'MessageId',
    declaration: 'export type MessageId = Branded<\'MessageId\'>;',
  },
  {
    name: 'MessageSource',
    declaration: 'export type MessageSource = MessageSourceMap[keyof MessageSourceMap];',
  },
  {
    name: 'MessageSourceMap',
    declaration: 'export interface MessageSourceMap {\n    user: {\n        kind: \'user\';\n    };\n    plugin: {\n        kind: \'plugin\';\n        plugin: string;\n    };\n    model: ModelMessageSource;\n    tool: ToolMessageSource;\n}',
  },
  {
    name: 'ModelMessageSource',
    declaration: 'export interface ModelMessageSource extends AssistantProvenance {\n    kind: \'model\';\n}',
  },
  {
    name: 'ObjectJsonSchema',
    declaration: 'export type ObjectJsonSchema = JsonSchemaNode & {\n    type: \'object\';\n};',
  },
  {
    name: 'PreparedLlmCall',
    declaration: 'export interface PreparedLlmCall {\n    readonly config: LlmCallConfig;\n    stream(options: GenerateOptions): AsyncIterable<StreamChunk>;\n}',
  },
  {
    name: 'PreparedReferencedMessage',
    declaration: 'export interface PreparedReferencedMessage {\n    content: ContentBlock[];\n    additionalContext?: UserMessage;\n}',
  },
  {
    name: 'PresetOption',
    declaration: 'export interface PresetOption {\n    value: string;\n    name: string;\n    description?: string;\n}',
  },
  {
    name: 'PresetSpec',
    declaration: 'export interface PresetSpec {\n    sandbox: SandboxMode;\n    approval: ApprovalPolicy;\n    name?: string;\n    description?: string;\n}',
  },
  {
    name: 'ProjectionChangeListener',
    declaration: 'export type ProjectionChangeListener = (session: Session, key: Extract<keyof SessionProjectionMap, string>, value: unknown, seq: number) => void;',
  },
  {
    name: 'ProjectionCheckpoint',
    declaration: 'export type ProjectionCheckpoint = Record<string, ProjectionCheckpointRow>;',
  },
  {
    name: 'ProjectionCheckpointRow',
    declaration: 'export interface ProjectionCheckpointRow {\n    ver: number;\n    seq: number;\n    val: unknown;\n}',
  },
  {
    name: 'ProjectionDefinition',
    declaration: 'export interface ProjectionDefinition<K extends keyof SessionProjectionMap, S> {\n    key: K;\n    schema: ZodType<SessionProjectionMap[K]>;\n    init(): S;\n    apply(state: S, event: SessionEvent): S;\n    view(state: S): SessionProjectionMap[K];\n    stateVersion: number;\n}',
  },
  {
    name: 'ProjectionSnapshot',
    declaration: 'export interface ProjectionSnapshot {\n    asOfSeq: number;\n    values: Partial<SessionProjectionMap>;\n}',
  },
  {
    name: 'PromptAssembly',
    declaration: 'export interface PromptAssembly {\n    sections: AssembledSection[];\n    tools: ToolSchema[];\n    variables: Record<string, string | undefined>;\n}',
  },
  {
    name: 'PromptSection',
    declaration: 'export interface PromptSection {\n    readonly name: string;\n    readonly order: number;\n    readonly text: string | ((context: AssembleContext) => string);\n}',
  },
  {
    name: 'ProviderRequestId',
    declaration: 'export type ProviderRequestId = Branded<\'ProviderRequestId\'>;',
  },
  {
    name: 'PrunedEntry',
    declaration: 'export interface PrunedEntry {\n    readonly originalSeq: number;\n    readonly replacementSeq: number;\n    readonly callId: CallId;\n    readonly charsBefore: number;\n    readonly charsAfter: number;\n}',
  },
  {
    name: 'PruneResult',
    declaration: 'export interface PruneResult {\n    readonly pruned: readonly PrunedEntry[];\n    readonly charsRemoved: number;\n}',
  },
  {
    name: 'PtyBackend',
    declaration: 'export interface PtyBackend {\n    readonly type: string;\n    spawn(spec: PtyBackendSpawnSpec): Promise<PtyBackendSession>;\n}',
  },
  {
    name: 'PtyBackendSession',
    declaration: 'export interface PtyBackendSession {\n    readonly motd: string;\n    readonly pid?: number;\n    startSend(request: PtySendRequest): PtySendOperation;\n    read(request: PtyReadRequest): PtyReadResult;\n    signal(signal: PtySignal): Promise<PtySignalResult>;\n    status(): PtySessionStatus;\n    close(reason: string): Promise<void>;\n}',
  },
  {
    name: 'PtyBackendSpawnSpec',
    declaration: 'export interface PtyBackendSpawnSpec extends PtySpawnRequest {\n    sessionId: PtySessionIdValue;\n    owner: Agent;\n    signal?: AbortSignal;\n}',
  },
  {
    name: 'PtyReadRequest',
    declaration: 'export interface PtyReadRequest {\n    offset?: number;\n    count?: number;\n}',
  },
  {
    name: 'PtyReadResult',
    declaration: 'export interface PtyReadResult {\n    text: string;\n    totalLines: number;\n    lineBegin: number;\n    lineEnd: number;\n    truncated: boolean;\n}',
  },
  {
    name: 'PtySendOperation',
    declaration: 'export interface PtySendOperation {\n    done: Promise<PtySendResult>;\n    readOutput(): PtySendRead;\n    cancel(): boolean;\n}',
  },
  {
    name: 'PtySendRead',
    declaration: 'export interface PtySendRead {\n    delta: string;\n    truncated: boolean;\n}',
  },
  {
    name: 'PtySendRequest',
    declaration: 'export interface PtySendRequest {\n    text: string;\n    submit: boolean;\n    signal?: AbortSignal;\n}',
  },
  {
    name: 'PtySendResult',
    declaration: 'export interface PtySendResult {\n    viewport: string;\n    waitReason: PtyWaitReason;\n    sessionStatus: PtySessionStatus;\n    truncated: boolean;\n}',
  },
  {
    name: 'PtySessionId',
    declaration: 'export type PtySessionId = PtySessionIdValue;',
  },
  {
    name: 'PtySessionIdValue',
    declaration: 'export type PtySessionIdValue = Branded<\'PtySessionId\'>;',
  },
  {
    name: 'PtySessionSnapshot',
    declaration: 'export interface PtySessionSnapshot {\n    sessionId: PtySessionIdValue;\n    name?: string;\n    type: string;\n    pid?: number;\n    status: PtySessionStatus;\n}',
  },
  {
    name: 'PtySessionStatus',
    declaration: 'export type PtySessionStatus = {\n    kind: \'running\';\n} | {\n    kind: \'exited\';\n    exitCode: number | null;\n    signal: NodeJS.Signals | null;\n};',
  },
  {
    name: 'PtySignal',
    declaration: 'export type PtySignal = \'SIGINT\' | \'SIGTERM\' | \'SIGKILL\' | \'SIGTSTP\' | \'SIGHUP\';',
  },
  {
    name: 'PtySignalResult',
    declaration: 'export interface PtySignalResult {\n    delivered: true;\n    targetPgid: number;\n}',
  },
  {
    name: 'PtySpawnRequest',
    declaration: 'export interface PtySpawnRequest {\n    type: string;\n    name?: string;\n    cwd?: string;\n}',
  },
  {
    name: 'PtySpawnResult',
    declaration: 'export interface PtySpawnResult extends PtySessionSnapshot {\n    motd: string;\n}',
  },
  {
    name: 'PtyWaitReason',
    declaration: 'export type PtyWaitReason = \'stdin_read\' | \'inferred_idle\' | \'timeout\' | \'session_exit\';',
  },
  {
    name: 'ReasoningBlock',
    declaration: 'export interface ReasoningBlock {\n    type: \'reasoning\';\n    text: string;\n}',
  },
  {
    name: 'ReasoningEffortId',
    declaration: 'export type ReasoningEffortId = Branded<\'ReasoningEffortId\'>;',
  },
  {
    name: 'RequestHeaderReason',
    declaration: 'export type RequestHeaderReason = \'initial\' | \'resume\' | \'change\';',
  },
  {
    name: 'ResolvedAlwaysRetryPolicy',
    declaration: 'export interface ResolvedAlwaysRetryPolicy extends ResolvedRetryBackoff {\n    readonly mode: \'always\';\n}',
  },
  {
    name: 'ResolvedNormalRetryPolicy',
    declaration: 'export interface ResolvedNormalRetryPolicy extends ResolvedRetryBackoff {\n    readonly mode: \'normal\';\n    readonly maxRetries: number;\n    readonly retryableCodes: readonly string[];\n}',
  },
  {
    name: 'ResolvedRetryBackoff',
    declaration: 'export interface ResolvedRetryBackoff {\n    readonly initialDelayMs: number;\n    readonly maxDelayMs: number;\n    readonly jitterRatio: number;\n}',
  },
  {
    name: 'ResolvedRetryPolicy',
    declaration: 'export type ResolvedRetryPolicy = ResolvedNormalRetryPolicy | ResolvedAlwaysRetryPolicy;',
  },
  {
    name: 'ResumeAgentOptions',
    declaration: 'export interface ResumeAgentOptions {\n    readonly resumeSessionId: SessionId;\n    readonly agentOptions?: AgentOptions;\n    readonly signal?: AbortSignal;\n    readonly setup?: (agentCtx: Context) => Promise<void> | void;\n}',
  },
  {
    name: 'SandboxEnforcement',
    declaration: 'export type SandboxEnforcement = \'full\' | \'partial\';',
  },
  {
    name: 'SandboxExecutionPolicy',
    declaration: 'export interface SandboxExecutionPolicy {\n    mode: SandboxMode;\n    workspaceRoot: string;\n}',
  },
  {
    name: 'SandboxMode',
    declaration: 'export type SandboxMode = \'read-only\' | \'workspace-write\' | \'danger-full-access\';',
  },
  {
    name: 'SandboxPolicy',
    declaration: 'export interface SandboxPolicy extends SandboxExecutionPolicy {\n    mode: ConfinedSandboxMode;\n}',
  },
  {
    name: 'SandboxPolicyRequest',
    declaration: 'export interface SandboxPolicyRequest {\n    session?: Session;\n    mode?: SandboxMode;\n}',
  },
  {
    name: 'SaveTextSpill',
    declaration: 'export interface SaveTextSpill {\n    owner: SpillOwner;\n    source: SpillSource;\n    suggestedName: string;\n    content: string;\n}',
  },
  {
    name: 'ScopeKey',
    declaration: 'export type ScopeKey = object;',
  },
  {
    name: 'SendOptions',
    declaration: 'export interface SendOptions {\n    target: SendTarget;\n    wakeup: boolean;\n}',
  },
  {
    name: 'SendTarget',
    declaration: 'export type SendTarget = \'next-turn\' | \'next-step\';',
  },
  {
    name: 'Session',
    declaration: 'export class Session {\n    get surface(): SessionSurface;\n    readonly header: SessionHeader;\n    get id(): SessionId;\n    readonly firstLiveSeq: number;\n    constructor(id: SessionId, seed?: readonly SessionEvent[], header?: SessionHeader);\n    get events(): readonly SessionEvent[];\n    get seq(): number;\n    append<T extends SessionEventType>(type: T, data: SessionEventMap[T], ...opts: T extends SurfaceEventType ? [\n        opts: SurfaceIntent\n    ] : [\n    ]): SessionEvent<T>;\n    requestHeader(): EpochHeader | undefined;\n    deriveMessages(): Message[];\n    deriveEventMessage(event: SessionEvent): Message | null;\n}',
  },
  {
    name: 'SessionAvailability',
    declaration: 'export type SessionAvailability = \'live\' | \'persisted\';',
  },
  {
    name: 'SessionEvent',
    declaration: 'export type SessionEvent<T extends SessionEventType = SessionEventType> = {\n    [K in SessionEventType]: {\n        type: K;\n        seq: number;\n        time: number;\n        data: SessionEventMap[K];\n    } & (K extends SurfaceEventType ? {\n        sourceEventSeqs?: number[];\n        surfaceOp?: SurfaceOp;\n    } : object);\n}[T];',
  },
  {
    name: 'SessionEventMap',
    declaration: 'export interface SessionEventMap {\n    \'turn/start\': {\n        turn: number;\n        trigger: TurnTrigger;\n    };\n    \'turn/end\': {\n        turn: number;\n        reason: TurnEndReason;\n    };\n    \'step/start\': {\n        turn: number;\n        step: number;\n    };\n    \'step/end\': {\n        turn: number;\n        step: number;\n    };\n    \'user/message\': UserMessage;\n    \'assistant/chunk\': {\n        turn: number;\n        step: number;\n        chunk: StreamChunk;\n    };\n    \'assistant/message\': {\n        turn: number;\n        step: number;\n        message: AssistantMessage;\n        usage?: TokenUsage;\n    };\n    \'tool/call\': {\n        turn: number;\n        step: number;\n        callId: CallId;\n        name: string;\n        arguments: string;\n    };\n    \'tool/result\': {\n        turn: number;\n        step: number;\n        message: ToolResultMessage;\n        error?: {\n            name: string;\n            code: string;\n        };\n        meta?: JsonValue;\n    };\n    \'steering/message\': {\n        turn: number;\n        message: UserMessage;\n    };\n    \'todo/write\': {\n        todos: TodoItem[];\n    };\n    \'request/header\': {\n        header: EpochHeader;\n        reason: RequestHeaderReason;\n    };\n}',
  },
  {
    name: 'SessionEventMetadataFilter',
    declaration: 'export type SessionEventMetadataFilter = Exclude<SessionEventResultFilter, {\n    kind: \'text\';\n}>;',
  },
  {
    name: 'SessionEventReadRequest',
    declaration: 'export interface SessionEventReadRequest {\n    sessionId: SessionId;\n    seq: number;\n    before?: number;\n    after?: number;\n}',
  },
  {
    name: 'SessionEventRecord',
    declaration: 'export interface SessionEventRecord {\n    sessionId: SessionId;\n    seq: number;\n    type: SessionEventType;\n    time: number;\n    surface: SessionEventSurface;\n}',
  },
  {
    name: 'SessionEventResultFilter',
    declaration: 'export type SessionEventResultFilter = ({\n    kind: \'seq\';\n} & SessionResultRange) | ({\n    kind: \'time\';\n} & SessionResultRange) | {\n    kind: \'type\';\n    values: readonly SessionEventType[];\n} | {\n    kind: \'surface\';\n    values: readonly SessionEventSurface[];\n} | {\n    kind: \'text\';\n    text: string;\n};',
  },
  {
    name: 'SessionEventSearchDocument',
    declaration: 'export interface SessionEventSearchDocument extends SessionEventRecord {\n    text: string;\n}',
  },
  {
    name: 'SessionEventSearchHit',
    declaration: 'export interface SessionEventSearchHit extends SessionEventRecord {\n    snippet: string;\n}',
  },
  {
    name: 'SessionEventSearchPage',
    declaration: 'export interface SessionEventSearchPage extends SessionSearchPage<SessionEventSearchHit> {\n    session: SessionHeader;\n}',
  },
  {
    name: 'SessionEventSearchRequest',
    declaration: 'export interface SessionEventSearchRequest {\n    sessionId: SessionId;\n    query: string;\n    filters?: readonly SessionEventMetadataFilter[];\n    limit?: number;\n    cursor?: SessionSearchCursor;\n}',
  },
  {
    name: 'SessionEventSurface',
    declaration: 'export type SessionEventSurface = \'current\' | \'shadowed\' | \'log-only\';',
  },
  {
    name: 'SessionEventTrace',
    declaration: 'export interface SessionEventTrace {\n    target: SessionEventRecord;\n    replacedBy?: number;\n    replacementChain: number[];\n    replacedEventSeqs: number[];\n    sourceEventSeqs: number[];\n    derivedEventSeqs: number[];\n}',
  },
  {
    name: 'SessionEventTraceObservation',
    declaration: 'export interface SessionEventTraceObservation extends SessionEventTrace {\n    session: SessionHeader;\n}',
  },
  {
    name: 'SessionEventTraceRequest',
    declaration: 'export interface SessionEventTraceRequest {\n    sessionId: SessionId;\n    seq: number;\n}',
  },
  {
    name: 'SessionEventType',
    declaration: 'export type SessionEventType = keyof SessionEventMap;',
  },
  {
    name: 'SessionEventWindow',
    declaration: 'export interface SessionEventWindow {\n    session: SessionHeader;\n    target: SessionEvent;\n    events: SessionEvent[];\n    startSeq: number;\n    endSeq: number;\n}',
  },
  {
    name: 'SessionForkSource',
    declaration: 'export type SessionForkSource = Session | SessionId;',
  },
  {
    name: 'SessionHeader',
    declaration: 'export interface SessionHeader {\n    readonly version: number;\n    readonly id: SessionId;\n    readonly createdAt: number;\n    readonly cwd?: string;\n    readonly parentSession?: SessionId;\n    readonly seedLength?: number;\n    readonly delegationDepth?: number;\n}',
  },
  {
    name: 'SessionId',
    declaration: 'export type SessionId = Branded<\'SessionId\'>;',
  },
  {
    name: 'SessionLineageNode',
    declaration: 'export interface SessionLineageNode {\n    session: SessionRecord;\n    descendants: SessionLineageNode[];\n}',
  },
  {
    name: 'SessionLineageTrace',
    declaration: 'export type SessionLineageTrace = {\n    target: SessionRecord;\n    ancestors: SessionRecord[];\n    descendants: SessionLineageNode[];\n} & ({\n    complete: true;\n    root: SessionRecord;\n} | {\n    complete: false;\n    unresolvedParentId: SessionId;\n});',
  },
  {
    name: 'SessionLocation',
    declaration: 'export interface SessionLocation {\n    readonly kind: string;\n    readonly path: string;\n}',
  },
  {
    name: 'SessionLogSnapshot',
    declaration: 'export interface SessionLogSnapshot {\n    session: SessionHeader;\n    events: SessionEvent[];\n}',
  },
  {
    name: 'SessionPersistenceRevision',
    declaration: 'export type SessionPersistenceRevision = Branded<\'SessionPersistenceRevision\'>;',
  },
  {
    name: 'SessionPersistenceSnapshot',
    declaration: 'export interface SessionPersistenceSnapshot {\n    header: SessionHeader;\n    revision: SessionPersistenceRevision;\n}',
  },
  {
    name: 'SessionProjectionMap',
    declaration: 'export interface SessionProjectionMap {\n}',
  },
  {
    name: 'SessionRecord',
    declaration: 'export interface SessionRecord {\n    header: SessionHeader;\n    live: boolean;\n    persisted: boolean;\n}',
  },
  {
    name: 'SessionReferenceCandidate',
    declaration: 'export interface SessionReferenceCandidate {\n    sessionId: SessionId;\n    label: string;\n    cwd?: string;\n    createdAt: number;\n}',
  },
  {
    name: 'SessionReferenceInput',
    declaration: 'export interface SessionReferenceInput {\n    sessionId: SessionId;\n    label?: string;\n}',
  },
  {
    name: 'SessionResultFilter',
    declaration: 'export type SessionResultFilter = {\n    kind: \'id\';\n    values: readonly SessionId[];\n} | {\n    kind: \'cwd\';\n    values: readonly (string | null)[];\n} | ({\n    kind: \'created-at\';\n} & SessionResultRange) | {\n    kind: \'parent\';\n    values: readonly (SessionId | null)[];\n} | {\n    kind: \'availability\';\n    values: readonly SessionAvailability[];\n};',
  },
  {
    name: 'SessionResultRange',
    declaration: 'export interface SessionResultRange {\n    from?: number;\n    to?: number;\n}',
  },
  {
    name: 'SessionSearchCursor',
    declaration: 'export type SessionSearchCursor = Branded<\'SessionSearchCursor\'>;',
  },
  {
    name: 'SessionSearchExecContext',
    declaration: 'export interface SessionSearchExecContext {\n    signal?: AbortSignal;\n}',
  },
  {
    name: 'SessionSearchHit',
    declaration: 'export interface SessionSearchHit extends SessionRecord {\n    bestMatch: SessionEventSearchHit;\n}',
  },
  {
    name: 'SessionSearchPage',
    declaration: 'export interface SessionSearchPage<T> {\n    items: readonly T[];\n    nextCursor?: SessionSearchCursor;\n}',
  },
  {
    name: 'SessionSearchRequest',
    declaration: 'export interface SessionSearchRequest {\n    query: string;\n    sessionFilters?: readonly SessionResultFilter[];\n    eventFilters?: readonly SessionEventMetadataFilter[];\n    limit?: number;\n    cursor?: SessionSearchCursor;\n}',
  },
  {
    name: 'SessionSurface',
    declaration: 'export interface SessionSurface {\n    readonly nodes: readonly number[];\n    readonly replaceGeneration: number;\n}',
  },
  {
    name: 'SessionSurfaceSnapshot',
    declaration: 'export interface SessionSurfaceSnapshot {\n    session: SessionHeader;\n    capturedThroughSeq: number | null;\n    events: SurfaceEvent[];\n}',
  },
  {
    name: 'SessionTitleAutomaticMode',
    declaration: 'export type SessionTitleAutomaticMode = \'first-message\' | \'all-user-messages\';',
  },
  {
    name: 'SessionTitleEventData',
    declaration: 'export interface SessionTitleEventData {\n    readonly title: string;\n    readonly messageSeqs: number[];\n    readonly source: SessionTitleSource;\n}',
  },
  {
    name: 'SessionTitleModelProvenance',
    declaration: 'export interface SessionTitleModelProvenance {\n    readonly provider: string;\n    readonly model: string;\n}',
  },
  {
    name: 'SessionTitleObservation',
    declaration: 'export interface SessionTitleObservation {\n    session: SessionHeader;\n    title?: SessionTitleSnapshot;\n}',
  },
  {
    name: 'SessionTitleObservationResult',
    declaration: 'export type SessionTitleObservationResult = {\n    sessionId: SessionId;\n    status: \'fulfilled\';\n    value: SessionTitleObservation;\n} | {\n    sessionId: SessionId;\n    status: \'rejected\';\n    reason: unknown;\n};',
  },
  {
    name: 'SessionTitleProvider',
    declaration: 'export interface SessionTitleProvider {\n    readonly id: SessionTitleProviderId;\n    readonly automatic: SessionTitleAutomaticMode;\n    generate(request: SessionTitleProviderRequest): Promise<SessionTitleProviderResult>;\n}',
  },
  {
    name: 'SessionTitleProviderId',
    declaration: 'export type SessionTitleProviderId = Branded<\'SessionTitleProviderId\'>;',
  },
  {
    name: 'SessionTitleProviderRequest',
    declaration: 'export interface SessionTitleProviderRequest {\n    readonly session: Session;\n    readonly messages: readonly SessionTitleUserMessage[];\n    readonly route?: SessionTitleModelProvenance;\n    readonly signal: AbortSignal;\n}',
  },
  {
    name: 'SessionTitleProviderResult',
    declaration: 'export interface SessionTitleProviderResult {\n    readonly title: string;\n    readonly messageSeqs: readonly number[];\n    readonly model?: SessionTitleModelProvenance;\n}',
  },
  {
    name: 'SessionTitleSnapshot',
    declaration: 'export interface SessionTitleSnapshot extends SessionTitleEventData {\n    readonly eventSeq: number;\n    readonly updatedAt: number;\n}',
  },
  {
    name: 'SessionTitleSource',
    declaration: 'export type SessionTitleSource = {\n    readonly kind: \'fallback\';\n} | {\n    readonly kind: \'provider\';\n    readonly provider: SessionTitleProviderId;\n    readonly model?: SessionTitleModelProvenance;\n};',
  },
  {
    name: 'SessionTitleUserMessage',
    declaration: 'export interface SessionTitleUserMessage {\n    readonly seq: number;\n    readonly text: string;\n}',
  },
  {
    name: 'SkillCandidate',
    declaration: 'export interface SkillCandidate extends SkillSummary {\n    readonly rank: number;\n    readonly locator: unknown;\n    readonly path?: string;\n    readonly metadata?: Readonly<Record<string, unknown>>;\n}',
  },
  {
    name: 'SkillDefinition',
    declaration: 'export interface SkillDefinition extends SkillSummary {\n    readonly content: string;\n    readonly path?: string;\n    readonly metadata?: Readonly<Record<string, unknown>>;\n}',
  },
  {
    name: 'SkillLookupOptions',
    declaration: 'export interface SkillLookupOptions {\n    readonly cwd?: string | undefined;\n    readonly signal?: AbortSignal | undefined;\n}',
  },
  {
    name: 'SkillProvider',
    declaration: 'export interface SkillProvider {\n    readonly name: string;\n    readonly list: (options: SkillLookupOptions) => Promise<readonly SkillCandidate[]>;\n    readonly get: (candidate: SkillCandidate, options: SkillLookupOptions) => Promise<SkillDefinition | undefined>;\n}',
  },
  {
    name: 'SkillRegistration',
    declaration: 'export type SkillRegistration = Omit<SkillDefinition, \'provider\'> & {\n    readonly provider?: string;\n};',
  },
  {
    name: 'SkillResourceBase',
    declaration: 'export type SkillResourceBase = {\n    readonly kind: \'directory\';\n    readonly path: string;\n} | {\n    readonly kind: \'url\';\n    readonly url: string;\n} | {\n    readonly kind: \'opaque\';\n    readonly description: string;\n};',
  },
  {
    name: 'SkillSource',
    declaration: 'export type SkillSource = \'project-dsh\' | \'project-agents\' | \'runtime\' | \'user-dsh\' | \'user-agents\' | \'custom\' | \'bundled\' | (string & {});',
  },
  {
    name: 'SkillSummary',
    declaration: 'export interface SkillSummary {\n    readonly name: string;\n    readonly description: string;\n    readonly whenToUse?: string;\n    readonly disableModelInvocation?: boolean;\n    readonly source: SkillSource;\n    readonly provider: string;\n    readonly resourceBase?: SkillResourceBase;\n}',
  },
  {
    name: 'SpillLocator',
    declaration: 'export type SpillLocator = Branded<\'SpillLocator\'>;',
  },
  {
    name: 'SpillOwner',
    declaration: 'export interface SpillOwner {\n    sessionId: SessionId;\n}',
  },
  {
    name: 'SpillRef',
    declaration: 'export interface SpillRef {\n    locator: SpillLocator;\n    bytes: number;\n    retrievalHint: string;\n}',
  },
  {
    name: 'SpillSource',
    declaration: 'export interface SpillSource {\n    toolName: string;\n    callId: CallId;\n    label: string;\n}',
  },
  {
    name: 'StorageForms',
    declaration: 'export interface StorageForms {\n}',
  },
  {
    name: 'StreamChunk',
    declaration: 'export type StreamChunk = {\n    type: \'block-start\';\n    index: number;\n    blockType: ContentBlockType;\n} | {\n    type: \'text-delta\';\n    index: number;\n    text: string;\n} | {\n    type: \'reasoning-delta\';\n    index: number;\n    text: string;\n} | {\n    type: \'tool-call-delta\';\n    index: number;\n    id: CallId;\n    name?: string;\n    argumentsDelta: string;\n} | {\n    type: \'block-end\';\n    index: number;\n    block: ContentBlock;\n} | {\n    type: \'usage\';\n    usage: TokenUsage;\n} | {\n    type: \'finish\';\n    reason: FinishReason;\n    replayState?: unknown;\n};',
  },
  {
    name: 'SubagentCapabilities',
    declaration: 'export interface SubagentCapabilities {\n    readonly outputSchema: boolean;\n    readonly depthLimit: boolean;\n    readonly toolFilter: boolean;\n    readonly persona: boolean;\n}',
  },
  {
    name: 'SubagentProvider',
    declaration: 'export interface SubagentProvider {\n    readonly name: string;\n    readonly capabilities: SubagentCapabilities;\n    readonly inheritsParentContext: boolean;\n    start(request: SubagentStartRequest): Promise<SubagentRun>;\n}',
  },
  {
    name: 'SubagentResult',
    declaration: 'export interface SubagentResult {\n    readonly output: ContentBlock[];\n    readonly structured?: unknown;\n    readonly stopReason: SubagentStopReason;\n}',
  },
  {
    name: 'SubagentRun',
    declaration: 'export interface SubagentRun {\n    readonly id: SessionId;\n    readonly localAgent: Agent | undefined;\n    readonly result: Promise<SubagentResult>;\n    dispose(): Promise<void>;\n    sendMessage?(content: ContentBlock[]): void;\n    resume?(content: ContentBlock[]): Promise<SubagentRun>;\n}',
  },
  {
    name: 'SubagentStartRequest',
    declaration: 'export interface SubagentStartRequest {\n    readonly prompt: ContentBlock[];\n    readonly parent: Agent;\n    readonly signal: AbortSignal;\n    readonly agentOptions?: AgentOptions;\n    readonly outputSchema?: ObjectJsonSchema;\n    readonly maxDepth?: number;\n    readonly toolFilter?: ToolRestriction;\n    readonly persona?: string;\n}',
  },
  {
    name: 'SubagentStopReason',
    declaration: 'export type SubagentStopReason = SubagentStopReasonMap[keyof SubagentStopReasonMap];',
  },
  {
    name: 'SubagentStopReasonMap',
    declaration: 'export interface SubagentStopReasonMap {\n    completed: \'completed\';\n    aborted: \'aborted\';\n    error: \'error\';\n    \'max-tokens\': \'max-tokens\';\n    refusal: \'refusal\';\n}',
  },
  {
    name: 'SubprocessCollect',
    declaration: 'export interface SubprocessCollect {\n    maxBytes: number;\n    spill?: {\n        maxBytes: number;\n    };\n}',
  },
  {
    name: 'SubprocessCollectedOutputs',
    declaration: 'export interface SubprocessCollectedOutputs {\n    readonly stdout?: SubprocessOutputReader;\n    readonly stderr?: SubprocessOutputReader;\n}',
  },
  {
    name: 'SubprocessHandle',
    declaration: 'export interface SubprocessHandle {\n    readonly pid: number;\n    readonly stdin: Writable | undefined;\n    readonly stdout: Readable | undefined;\n    readonly stderr: Readable | undefined;\n    readonly collected: SubprocessCollectedOutputs;\n    readonly done: Promise<SubprocessOutcome>;\n    terminate(): void;\n    waitForExit(signal?: AbortSignal): Promise<boolean>;\n}',
  },
  {
    name: 'SubprocessOutcome',
    declaration: 'export interface SubprocessOutcome {\n    exitCode: number | null;\n    signal: NodeJS.Signals | null;\n}',
  },
  {
    name: 'SubprocessOutputMode',
    declaration: 'export type SubprocessOutputMode = \'pipe\' | \'inherit\' | SubprocessCollect;',
  },
  {
    name: 'SubprocessOutputRead',
    declaration: 'export interface SubprocessOutputRead {\n    text: string;\n    nextOffset: number;\n    lossy: boolean;\n    spillPath?: string;\n}',
  },
  {
    name: 'SubprocessOutputReader',
    declaration: 'export interface SubprocessOutputReader {\n    readFrom(fromByte: number): SubprocessOutputRead;\n}',
  },
  {
    name: 'SubprocessSpawnSpec',
    declaration: 'export interface SubprocessSpawnSpec {\n    argv: readonly string[];\n    cwd: string;\n    stdio: SubprocessStdio;\n    graceMs: number;\n    signal?: AbortSignal | undefined;\n    env?: Record<string, string> | undefined;\n}',
  },
  {
    name: 'SubprocessStdinMode',
    declaration: 'export type SubprocessStdinMode = \'ignore\' | \'pipe\' | {\n    readonly data: string;\n};',
  },
  {
    name: 'SubprocessStdio',
    declaration: 'export interface SubprocessStdio {\n    stdin: SubprocessStdinMode;\n    stdout: SubprocessOutputMode;\n    stderr: SubprocessOutputMode;\n}',
  },
  {
    name: 'SurfaceEvent',
    declaration: 'export type SurfaceEvent = SessionEvent<SurfaceEventType> & {\n    surfaceOp: SurfaceOp;\n};',
  },
  {
    name: 'SurfaceEventType',
    declaration: 'export type SurfaceEventType = \'user/message\' | \'assistant/message\' | \'tool/result\' | \'steering/message\';',
  },
  {
    name: 'SurfaceIntent',
    declaration: 'export interface SurfaceIntent {\n    surfaceOp: SurfaceOp;\n    sourceEventSeqs?: number[];\n}',
  },
  {
    name: 'SurfaceOp',
    declaration: 'export type SurfaceOp = \'append\' | {\n    op: \'replace\';\n    start: number;\n    end: number;\n};',
  },
  {
    name: 'TableKeyOf',
    declaration: 'export type TableKeyOf<S extends DomainSpec, N extends keyof S[\'tables\']> = S[\'tables\'][N] extends DomainTableSpec<infer K> ? K : never;',
  },
  {
    name: 'TableValueOf',
    declaration: 'export type TableValueOf<S extends DomainSpec, N extends keyof S[\'tables\']> = S[\'tables\'][N] extends DomainTableSpec<string, infer V> ? V : never;',
  },
  {
    name: 'TaskDoneListener',
    declaration: 'export type TaskDoneListener = (snapshot: TaskSnapshot, owner: Agent | undefined) => void | PromiseLike<void>;',
  },
  {
    name: 'TaskHooks',
    declaration: 'export interface TaskHooks {\n    cancel(reason?: string): void;\n    done: Promise<TaskOutcome>;\n    readOutput?(): string;\n}',
  },
  {
    name: 'TaskId',
    declaration: 'export type TaskId = Branded<\'TaskId\'>;',
  },
  {
    name: 'TaskKind',
    declaration: 'export type TaskKind = TaskKindMap[keyof TaskKindMap];',
  },
  {
    name: 'TaskKindMap',
    declaration: 'export interface TaskKindMap {\n    bash: \'bash\';\n    subagent: \'subagent\';\n}',
  },
  {
    name: 'TaskOutcome',
    declaration: 'export interface TaskOutcome {\n    status: \'completed\' | \'killed\' | \'failed\';\n    detail?: string;\n    output?: string;\n}',
  },
  {
    name: 'TaskRead',
    declaration: 'export interface TaskRead {\n    text: string;\n    snapshot: TaskSnapshot;\n}',
  },
  {
    name: 'TaskSnapshot',
    declaration: 'export interface TaskSnapshot {\n    id: TaskId;\n    kind: TaskKind;\n    label: string;\n    outputLimitBytes?: number;\n    ownerSession?: SessionId;\n    status: TaskStatus;\n    detail?: string;\n    startedAt: number;\n    finishedAt?: number;\n    reported: boolean;\n}',
  },
  {
    name: 'TaskStart',
    declaration: 'export interface TaskStart {\n    kind: TaskKind;\n    label: string;\n    outputLimitBytes?: number;\n    owner?: Agent;\n    run(): TaskHooks;\n}',
  },
  {
    name: 'TaskStatus',
    declaration: 'export type TaskStatus = \'running\' | \'stopping\' | \'completed\' | \'killed\' | \'failed\';',
  },
  {
    name: 'TelemetryRecord',
    declaration: 'export interface TelemetryRecord {\n    channel: \'ledger\' | \'ops\';\n    time: number;\n    severity: TelemetrySeverity;\n    attributes: Record<string, string | number>;\n    body: unknown;\n}',
  },
  {
    name: 'TelemetrySeverity',
    declaration: 'export type TelemetrySeverity = \'info\' | \'warn\' | \'error\';',
  },
  {
    name: 'TerminalCallView',
    declaration: 'export interface TerminalCallView {\n    card: \'terminal\';\n    title: string;\n    description?: string;\n    cwd?: string;\n}',
  },
  {
    name: 'TerminalResultView',
    declaration: 'export interface TerminalResultView {\n    card: \'terminal\';\n    title?: string;\n    output?: string;\n    exitCode?: number;\n    signal?: string;\n}',
  },
  {
    name: 'TodoItem',
    declaration: 'export interface TodoItem {\n    content: string;\n    status: \'pending\' | \'in_progress\' | \'completed\';\n}',
  },
  {
    name: 'TokenMeasurement',
    declaration: 'export interface TokenMeasurement {\n    readonly logRevision: number;\n    readonly baseline: TokenMeasurementBaseline;\n    readonly surfaceDeltaTokens: number;\n    readonly totalTokens: number;\n    readonly surfaceTokens: number;\n    readonly nodes: readonly TokenSurfaceNode[];\n}',
  },
  {
    name: 'TokenMeasurementBaseline',
    declaration: 'export type TokenMeasurementBaseline = {\n    readonly kind: \'none\';\n    readonly tokens: 0;\n} | {\n    readonly kind: \'estimated\';\n    readonly tokens: number;\n} | {\n    readonly kind: \'usage\';\n    readonly tokens: number;\n    readonly usage: Readonly<TokenUsage>;\n};',
  },
  {
    name: 'TokenSurfaceNode',
    declaration: 'export interface TokenSurfaceNode {\n    readonly seq: number;\n    readonly tokens: number;\n}',
  },
  {
    name: 'TokenUsage',
    declaration: 'export interface TokenUsage {\n    inputTokens: number;\n    outputTokens: number;\n    cacheReadTokens?: number;\n    cacheWriteTokens?: number;\n    reasoningTokens?: number;\n}',
  },
  {
    name: 'ToolCallBlock',
    declaration: 'export interface ToolCallBlock {\n    type: \'tool-call\';\n    id: CallId;\n    name: string;\n    arguments: string;\n}',
  },
  {
    name: 'ToolCallKind',
    declaration: 'export type ToolCallKind = \'read\' | \'edit\' | \'delete\' | \'move\' | \'search\' | \'execute\' | \'fetch\' | \'other\';',
  },
  {
    name: 'ToolCallView',
    declaration: 'export type ToolCallView = GenericCallView | TerminalCallView | DiffCallView;',
  },
  {
    name: 'ToolDefinition',
    declaration: 'export interface ToolDefinition extends ToolSchema {\n    readonly output: ToolOutputDefinition;\n    execute(args: unknown, exec: ToolRunContext): Promise<unknown>;\n    finalizeContent?(exec: Readonly<ToolExecution>, result: Readonly<ToolExecutionResult>): ContentBlock[] | undefined;\n    timeoutMs?: number;\n    isConcurrencySafe?(args: unknown): boolean;\n    presentCall?(args: unknown): ToolCallView | undefined;\n    presentResult?(args: unknown, result: ToolResult): ToolResultView | undefined;\n}',
  },
  {
    name: 'ToolErrorInfo',
    declaration: 'export interface ToolErrorInfo {\n    name: string;\n    code: string;\n}',
  },
  {
    name: 'ToolExecution',
    declaration: 'export interface ToolExecution extends ToolExecutionInput {\n    readonly token: ToolExecutionToken;\n}',
  },
  {
    name: 'ToolExecutionFailure',
    declaration: 'export interface ToolExecutionFailure {\n    readonly isError: true;\n    readonly error: ToolFailure;\n    readonly value?: never;\n    readonly content: ContentBlock[];\n    readonly meta?: JsonValue;\n    readonly additionalContexts?: UserMessage[];\n    readonly concludesTurn?: never;\n}',
  },
  {
    name: 'ToolExecutionInput',
    declaration: 'export interface ToolExecutionInput {\n    readonly callId: CallId;\n    readonly name: string;\n    readonly arguments: unknown;\n    readonly agent?: Agent;\n    readonly parent?: ToolExecutionToken;\n    readonly signal: AbortSignal;\n}',
  },
  {
    name: 'ToolExecutionMode',
    declaration: 'export type ToolExecutionMode = {\n    kind: \'parallel\';\n} | {\n    kind: \'exclusive\';\n};',
  },
  {
    name: 'ToolExecutionResult',
    declaration: 'export type ToolExecutionResult = ToolExecutionSuccess | ToolExecutionFailure;',
  },
  {
    name: 'ToolExecutionSuccess',
    declaration: 'export interface ToolExecutionSuccess {\n    readonly isError: false;\n    readonly value: JsonValue;\n    readonly content: ContentBlock[];\n    readonly error?: never;\n    readonly meta?: JsonValue;\n    readonly additionalContexts?: UserMessage[];\n    readonly concludesTurn?: true;\n}',
  },
  {
    name: 'ToolExecutionToken',
    declaration: 'export type ToolExecutionToken = symbol & {\n    readonly [toolExecutionTokenBrand]: true;\n};',
  },
  {
    name: 'ToolFailure',
    declaration: 'export interface ToolFailure {\n    message: string;\n    info?: ToolErrorInfo;\n}',
  },
  {
    name: 'ToolGuard',
    declaration: 'export type ToolGuard = (execution: Readonly<ToolExecution>) => string | undefined;',
  },
  {
    name: 'ToolMessageSource',
    declaration: 'export interface ToolMessageSource {\n    kind: \'tool\';\n    callId: CallId;\n}',
  },
  {
    name: 'ToolOutputDefinition',
    declaration: 'export interface ToolOutputDefinition {\n    readonly schema: JsonSchemaNode;\n    render(args: unknown, value: JsonValue): ContentBlock[];\n    presentationMeta?(args: unknown, value: JsonValue): JsonValue;\n}',
  },
  {
    name: 'ToolProviderResult',
    declaration: 'export interface ToolProviderResult {\n    readonly schemas: readonly ToolSchema[];\n    readonly knownNames?: readonly string[];\n}',
  },
  {
    name: 'ToolRestriction',
    declaration: 'export interface ToolRestriction {\n    readonly allow?: readonly string[];\n    readonly deny?: readonly string[];\n}',
  },
  {
    name: 'ToolResult',
    declaration: 'export interface ToolResult {\n    content: ContentBlock[];\n    isError: boolean;\n    meta?: JsonValue;\n}',
  },
  {
    name: 'ToolResultBlock',
    declaration: 'export interface ToolResultBlock {\n    type: \'tool-result\';\n    toolCallId: CallId;\n    content: ContentBlock[];\n    isError?: boolean;\n}',
  },
  {
    name: 'ToolResultMessage',
    declaration: 'export interface ToolResultMessage extends Message {\n    readonly role: \'user\';\n    readonly content: [\n        ToolResultBlock\n    ];\n    readonly source: ToolMessageSource;\n}',
  },
  {
    name: 'ToolResultView',
    declaration: 'export type ToolResultView = GenericResultView | TerminalResultView | DiffResultView;',
  },
  {
    name: 'ToolRunContext',
    declaration: 'export interface ToolRunContext extends ToolExecution {\n    deferContext(context: UserMessage): void;\n    concludeTurn(): void;\n}',
  },
  {
    name: 'ToolSchema',
    declaration: 'export interface ToolSchema {\n    name: string;\n    description: string;\n    parameters: Record<string, unknown>;\n}',
  },
  {
    name: 'TurnEndReason',
    declaration: 'export type TurnEndReason = TurnEndReasonMap[keyof TurnEndReasonMap];',
  },
  {
    name: 'TurnEndReasonMap',
    declaration: 'export interface TurnEndReasonMap {\n    completed: {\n        kind: \'completed\';\n    };\n    aborted: {\n        kind: \'aborted\';\n    };\n    error: {\n        kind: \'error\';\n        step: number;\n    } & ({\n        failure: LlmFailure;\n        message?: never;\n        code?: never;\n    } | {\n        message: string;\n        code?: string;\n        failure?: never;\n    });\n    disposed: {\n        kind: \'disposed\';\n    };\n    \'max-tokens\': {\n        kind: \'max-tokens\';\n    };\n    interrupted: {\n        kind: \'interrupted\';\n    };\n}',
  },
  {
    name: 'TurnTrigger',
    declaration: 'export type TurnTrigger = TurnTriggerMap[keyof TurnTriggerMap];',
  },
  {
    name: 'TurnTriggerMap',
    declaration: 'export interface TurnTriggerMap {\n    message: {\n        kind: \'message\';\n        source: MessageSource;\n    };\n    retry: {\n        kind: \'retry\';\n    };\n    injection: {\n        kind: \'injection\';\n        source: MessageSource;\n    };\n}',
  },
  {
    name: 'UserInteractionProvider',
    declaration: 'export interface UserInteractionProvider {\n    ask(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>;\n}',
  },
  {
    name: 'UserMessage',
    declaration: 'export interface UserMessage extends Message {\n    readonly role: \'user\';\n}',
  },
  {
    name: 'WebFetchBody',
    declaration: 'export type WebFetchBody = {\n    readonly kind: \'html\';\n    readonly content: string;\n} | {\n    readonly kind: \'text\';\n    readonly content: string;\n};',
  },
  {
    name: 'WebFetchProvider',
    declaration: 'export interface WebFetchProvider {\n    readonly id: string;\n    available(): boolean;\n    fetch(request: WebFetchRequest, signal?: AbortSignal): Promise<WebFetchResult>;\n}',
  },
  {
    name: 'WebFetchRequest',
    declaration: 'export interface WebFetchRequest {\n    readonly url: string;\n}',
  },
  {
    name: 'WebFetchResult',
    declaration: 'export interface WebFetchResult {\n    readonly url: string;\n    readonly statusCode: number;\n    readonly body: WebFetchBody;\n    readonly truncated: boolean;\n}',
  },
  {
    name: 'WebRoute',
    declaration: 'export interface WebRoute {\n    kind: WebRouteKind;\n    path: string;\n    handler: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;\n}',
  },
  {
    name: 'WebRouteKind',
    declaration: 'export type WebRouteKind = \'exact\' | \'prefix\';',
  },
  {
    name: 'WebSearchProvider',
    declaration: 'export interface WebSearchProvider {\n    readonly id: string;\n    available(): boolean;\n    search(request: WebSearchRequest, signal?: AbortSignal): Promise<WebSearchResult>;\n}',
  },
  {
    name: 'WebSearchRequest',
    declaration: 'export interface WebSearchRequest {\n    readonly query: string;\n    readonly maxResults?: number;\n}',
  },
  {
    name: 'WebSearchResult',
    declaration: 'export interface WebSearchResult {\n    readonly content?: string;\n    readonly sources: readonly WebSearchSource[];\n    readonly truncated: boolean;\n}',
  },
  {
    name: 'WebSearchSource',
    declaration: 'export interface WebSearchSource {\n    readonly url: string;\n    readonly title?: string;\n    readonly snippet?: string;\n    readonly publishedAt?: string;\n}',
  },
  {
    name: 'WorkflowMeta',
    declaration: 'export interface WorkflowMeta {\n    name: string;\n    description: string;\n    whenToUse?: string;\n    phases?: WorkflowPhase[];\n}',
  },
  {
    name: 'WorkflowPhase',
    declaration: 'export interface WorkflowPhase {\n    title: string;\n    detail?: string;\n    provider?: string;\n    model?: string;\n}',
  },
  {
    name: 'WorkflowResult',
    declaration: 'export interface WorkflowResult {\n    value: unknown;\n    stopReason: WorkflowStopReason;\n    error?: string;\n    agentsStarted: number;\n}',
  },
  {
    name: 'WorkflowRun',
    declaration: 'export interface WorkflowRun {\n    readonly id: WorkflowRunId;\n    readonly meta: WorkflowMeta;\n    readonly result: Promise<WorkflowResult>;\n    cancel(reason?: string): void;\n    dispose(): Promise<void>;\n}',
  },
  {
    name: 'WorkflowRunId',
    declaration: 'export type WorkflowRunId = Branded<\'WorkflowRunId\'>;',
  },
  {
    name: 'WorkflowStartRequest',
    declaration: 'export interface WorkflowStartRequest {\n    script: string;\n    meta: WorkflowMeta;\n    args?: unknown;\n    subagentProvider?: string;\n    maxTotalAgents?: number;\n    parent: Agent;\n    signal?: AbortSignal;\n}',
  },
  {
    name: 'WorkflowStopReason',
    declaration: 'export type WorkflowStopReason = \'completed\' | \'cancelled\' | \'error\';',
  },
  {
    name: 'Workspace',
    declaration: 'export interface Workspace {\n    readonly id: WorkspaceId;\n    readonly path: string;\n    readonly title: string;\n    readonly createdAt: string;\n    readonly updatedAt: string;\n    readonly sessionIds: readonly SessionId[];\n    setTitle(title: string): Promise<void>;\n    attachSession(sessionId: SessionId): Promise<void>;\n    insertSessionBefore(sessionId: SessionId, beforeSessionId?: SessionId): Promise<void>;\n    detachSession(sessionId: SessionId): Promise<void>;\n    status(): Promise<\'ok\' | \'missing-dir\'>;\n}',
  },
]

/** The inherited `ctx` surface (cordis core + loader/hmr/timer), in curated order. */
export const INHERITED_CTX_API: readonly InheritedApiEntry[] = [
  { name: 'ctx.on / ctx.once', summary: 'Register an event listener (disposable).' },
  { name: 'ctx.emit / ctx.parallel / ctx.serial / ctx.bail / ctx.waterfall', summary: 'Dispatch an event (sync / awaited / first-bail / veto-chain).' },
  { name: 'ctx.plugin / ctx.inject', summary: 'Load a plugin / declare required services.' },
  { name: 'ctx.effect', summary: 'Register a disposable side effect tied to the fiber.' },
  { name: 'ctx.get / ctx.set / ctx.provide / ctx.accessor / ctx.mixin', summary: 'Low-level service-store access and binding.' },
  { name: 'ctx.extend / ctx.isolate / ctx.intercept', summary: 'Derive a child context (scoped services / isolation / interception).' },
  { name: 'ctx.root / ctx.scope / ctx.fiber / ctx.registry / ctx.reflect / ctx.events / ctx.logger', summary: 'Ambient handles onto the running context graph.' },
  { name: 'ctx.timer (+ interval / timeout / throttle / debounce / setTimeout / setInterval)', summary: 'Disposable timer helpers. The `timer` key is provided at runtime; the six helpers are mixed onto ctx directly (declared via Pick).' },
  { name: 'ctx.loader', summary: 'The config Loader that booted the app (present under the loader).' },
  { name: 'ctx.hmr', summary: 'The hot-module-reload watcher (present under the hmr plugin).' },
]
