@skaile/workspaces 0.52.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/{asset-feeds-OEGJ6NOF.js → asset-feeds-677S5NX7.js} +7 -7
- package/dist/{asset-feeds-OEGJ6NOF.js.map → asset-feeds-677S5NX7.js.map} +1 -1
- package/dist/asset-manager/index.js +5 -5
- package/dist/asset-manager/installer.js +4 -4
- package/dist/{chunk-6K4RVXAM.js → chunk-43JDPQJ4.js} +3 -3
- package/dist/{chunk-6K4RVXAM.js.map → chunk-43JDPQJ4.js.map} +1 -1
- package/dist/{chunk-EOINYN5T.js → chunk-DW5MIJK3.js} +3 -3
- package/dist/{chunk-EOINYN5T.js.map → chunk-DW5MIJK3.js.map} +1 -1
- package/dist/{chunk-VE2UIJ7Y.js → chunk-EXNTTJGP.js} +3 -43
- package/dist/chunk-EXNTTJGP.js.map +1 -0
- package/dist/{chunk-7ZWLZ5H3.js → chunk-FLRHP3UC.js} +3 -3
- package/dist/{chunk-7ZWLZ5H3.js.map → chunk-FLRHP3UC.js.map} +1 -1
- package/dist/{chunk-MGB657EG.js → chunk-K5JIAHDV.js} +16 -7
- package/dist/chunk-K5JIAHDV.js.map +1 -0
- package/dist/{chunk-3IHBGDCG.js → chunk-KSISPZV3.js} +2 -2
- package/dist/{chunk-3IHBGDCG.js.map → chunk-KSISPZV3.js.map} +1 -1
- package/dist/{chunk-WD2NRI3T.js → chunk-PLQVAEM2.js} +2 -2
- package/dist/{chunk-WD2NRI3T.js.map → chunk-PLQVAEM2.js.map} +1 -1
- package/dist/{chunk-TCNYSHPM.js → chunk-SFVEHSCI.js} +4 -4
- package/dist/{chunk-TCNYSHPM.js.map → chunk-SFVEHSCI.js.map} +1 -1
- package/dist/{chunk-QLLFCQU5.js → chunk-WSQ5J7CE.js} +403 -1469
- package/dist/chunk-WSQ5J7CE.js.map +1 -0
- package/dist/{chunk-BXC5547R.js → chunk-XD7GYMAU.js} +3 -3
- package/dist/{chunk-BXC5547R.js.map → chunk-XD7GYMAU.js.map} +1 -1
- package/dist/cli/index.js +30 -32
- package/dist/cli/index.js.map +1 -1
- package/dist/connectors/config.js +4 -4
- package/dist/connectors/index.js +5 -7
- package/dist/connectors/src/config.d.ts +1 -74
- package/dist/connectors/src/config.d.ts.map +1 -1
- package/dist/connectors/src/connector-manager.d.ts +13 -137
- package/dist/connectors/src/connector-manager.d.ts.map +1 -1
- package/dist/connectors/src/connector-types.d.ts +3 -25
- package/dist/connectors/src/connector-types.d.ts.map +1 -1
- package/dist/connectors/src/fleet-utils.d.ts +2 -30
- package/dist/connectors/src/fleet-utils.d.ts.map +1 -1
- package/dist/connectors/src/fs-utils.d.ts +1 -2
- package/dist/connectors/src/fs-utils.d.ts.map +1 -1
- package/dist/connectors/src/index.d.ts +2 -12
- package/dist/connectors/src/index.d.ts.map +1 -1
- package/dist/connectors/src/watcher.d.ts +1 -5
- package/dist/connectors/src/watcher.d.ts.map +1 -1
- package/dist/core/index.js +3 -3
- package/dist/deploy/index.js +3 -3
- package/dist/{ensure-sources-GJOXWVWO.js → ensure-sources-OCMHK7LT.js} +5 -5
- package/dist/{ensure-sources-GJOXWVWO.js.map → ensure-sources-OCMHK7LT.js.map} +1 -1
- package/dist/factory-assets/connectors/deploy.js +5 -7
- package/dist/factory-assets/connectors/devserver.js +5 -7
- package/dist/factory-assets/connectors/flow/adapter.js +5 -7
- package/dist/factory-assets/connectors/flow/engine.js +3 -3
- package/dist/factory-assets/connectors/flow/run-flow.js +6 -8
- package/dist/factory-assets/connectors/flow.js +5 -7
- package/dist/factory-assets/connectors/git.js +5 -7
- package/dist/factory-assets/connectors/gmail.js +5 -7
- package/dist/factory-assets/connectors/googledrive/CONNECTOR.md +14 -128
- package/dist/factory-assets/connectors/googledrive/driver.d.ts +6 -13
- package/dist/factory-assets/connectors/googledrive/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/googledrive.js +5 -7
- package/dist/factory-assets/connectors/local.js +5 -7
- package/dist/factory-assets/connectors/mattermost.js +5 -7
- package/dist/factory-assets/connectors/memory.js +5 -7
- package/dist/factory-assets/connectors/minio.js +5 -7
- package/dist/factory-assets/connectors/postgres.js +5 -7
- package/dist/factory-assets/connectors/s3.js +5 -7
- package/dist/factory-assets/connectors/sharepoint/CONNECTOR.md +13 -159
- package/dist/factory-assets/connectors/sharepoint/driver.d.ts +6 -12
- package/dist/factory-assets/connectors/sharepoint/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/sharepoint.js +5 -7
- package/dist/factory-assets/connectors/sqlite.js +5 -7
- package/dist/factory-assets/connectors/static-server.js +5 -7
- package/dist/factory-assets/connectors/tunnel.js +5 -7
- package/dist/factory-assets/connectors/webdav/CONNECTOR.md +13 -118
- package/dist/factory-assets/connectors/webdav/driver.d.ts +6 -15
- package/dist/factory-assets/connectors/webdav/driver.d.ts.map +1 -1
- package/dist/factory-assets/connectors/webdav.js +5 -7
- package/dist/factory-assets/connectors/xstate-store.js +5 -7
- package/dist/factory-assets/connectors/xstate.js +5 -7
- package/dist/{flows-AGPIE6JM.js → flows-36PZESON.js} +4 -4
- package/dist/{flows-AGPIE6JM.js.map → flows-36PZESON.js.map} +1 -1
- package/dist/library/index.js +4 -4
- package/dist/library/install.js +3 -3
- package/dist/{open-library-ERKRGH4B.js → open-library-WRFYABFP.js} +7 -7
- package/dist/{open-library-ERKRGH4B.js.map → open-library-WRFYABFP.js.map} +1 -1
- package/dist/{paths-D6RUQ522.js → paths-EUNVMONC.js} +5 -5
- package/dist/{paths-D6RUQ522.js.map → paths-EUNVMONC.js.map} +1 -1
- package/dist/{plugin-store-SGNJTBYS.js → plugin-store-35KIMX6W.js} +5 -5
- package/dist/{plugin-store-SGNJTBYS.js.map → plugin-store-35KIMX6W.js.map} +1 -1
- package/dist/runner/index.js +7 -9
- package/dist/runner/src/serve.d.ts +6 -4
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +5 -5
- package/dist/sdk/core.js +3 -3
- package/dist/sdk/flow.js +3 -3
- package/dist/sdk/index.js +7 -9
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/runner.js +7 -9
- package/dist/{setup-IV2JFW3T.js → setup-HM6HATAC.js} +5 -5
- package/dist/{setup-IV2JFW3T.js.map → setup-HM6HATAC.js.map} +1 -1
- package/dist/{source-FGOMQMZT.js → source-EZ5Y3CKP.js} +8 -8
- package/dist/{source-FGOMQMZT.js.map → source-EZ5Y3CKP.js.map} +1 -1
- package/dist/{store-client-GJT2XQ5Z.js → store-client-BUUF7BPK.js} +5 -5
- package/dist/{store-client-GJT2XQ5Z.js.map → store-client-BUUF7BPK.js.map} +1 -1
- package/dist/tui/index.js +7 -9
- package/dist/tui/index.js.map +1 -1
- package/dist/workspace-plugin/adapters/mcp.js +3 -3
- package/dist/workspace-plugin/adapters/omp.js +3 -3
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +1 -13
- package/dist/chunk-MGB657EG.js.map +0 -1
- package/dist/chunk-OVRSNIKJ.js +0 -72
- package/dist/chunk-OVRSNIKJ.js.map +0 -1
- package/dist/chunk-QLLFCQU5.js.map +0 -1
- package/dist/chunk-RAIRWFAN.js +0 -843
- package/dist/chunk-RAIRWFAN.js.map +0 -1
- package/dist/chunk-VE2UIJ7Y.js.map +0 -1
- package/dist/connectors/rclone-config.d.ts +0 -2
- package/dist/connectors/rclone-config.js +0 -4
- package/dist/connectors/rclone-config.js.map +0 -1
- package/dist/connectors/rclone.d.ts +0 -2
- package/dist/connectors/rclone.js +0 -5
- package/dist/connectors/rclone.js.map +0 -1
- package/dist/connectors/src/fleet-health-gate.d.ts +0 -105
- package/dist/connectors/src/fleet-health-gate.d.ts.map +0 -1
- package/dist/connectors/src/mount-placeholder.d.ts +0 -131
- package/dist/connectors/src/mount-placeholder.d.ts.map +0 -1
- package/dist/connectors/src/rclone-config/googledrive.d.ts +0 -59
- package/dist/connectors/src/rclone-config/googledrive.d.ts.map +0 -1
- package/dist/connectors/src/rclone-config/index.d.ts +0 -9
- package/dist/connectors/src/rclone-config/index.d.ts.map +0 -1
- package/dist/connectors/src/rclone-config/onedrive.d.ts +0 -48
- package/dist/connectors/src/rclone-config/onedrive.d.ts.map +0 -1
- package/dist/connectors/src/rclone-config/sanitize.d.ts +0 -9
- package/dist/connectors/src/rclone-config/sanitize.d.ts.map +0 -1
- package/dist/connectors/src/rclone-config/webdav.d.ts +0 -50
- package/dist/connectors/src/rclone-config/webdav.d.ts.map +0 -1
- package/dist/connectors/src/rclone-process-manager.d.ts +0 -316
- package/dist/connectors/src/rclone-process-manager.d.ts.map +0 -1
- package/dist/connectors/src/rclone-token-refresh.d.ts +0 -84
- package/dist/connectors/src/rclone-token-refresh.d.ts.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../runner/src/logging-bootstrap.ts","../runner/src/markdown-stream.ts","../runner/src/define-capability.ts","../runner/src/mixin-resolver.ts","../runner/src/composition/types.ts","../runner/src/composition/compile.ts","../runner/src/composition/resolve.ts","../runner/src/composition/bootstrap.ts","../runner/src/context.ts","../runner/src/environment.ts","../runner/src/manifest.ts","../runner/src/file-changed-coalescer.ts","../runner/src/recipe-resolver.ts","../runner/src/recipe-templating.ts","../runner/src/external-mcp.ts","../runner/src/mcp-prompt.ts","../runner/src/resources.ts","../runner/src/session-builder.ts","../runner/src/agent.ts","../runner/src/builtin-capabilities.ts","../runner/src/capability-registry.ts","../runner/src/capability-roundtrip.ts","../runner/src/resource-handler.ts","../runner/src/ai-credential-retry.ts","../runner/src/ai-credential-refresh.ts","../runner/src/credential-rotated.ts","../runner/src/runtime-session-emit.ts","../runner/src/compaction/prompt.ts","../runner/src/compaction/strategy.ts","../runner/src/compaction/orchestrator.ts","../runner/src/file-changed-rewriter.ts","../runner/src/lifecycle-handler.ts","../runner/src/session-resource-handlers.ts","../runner/src/mcp-runtime-handlers.ts","../runner/src/fleet-health-flag-dispatcher.ts","../runner/src/refresh-flag-dispatcher.ts","../runner/src/runner-capabilities.ts","../runner/src/serve-credentials.ts","../runner/src/session-stimulus.ts","../runner/src/serve.ts","../runner/src/session.ts"],"names":["z","path","resolve","fs","content","createHash","z2","parseYaml","existsSync","resolvePath","readFileSync","z4","readdirSync","statSync","join","relative","homedir","dirname","mkdirSync","writeFileSync","buildClientCapabilityHandler","secretProvider","wsConfig","_z","fsWatch"],"mappings":"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","file":"chunk-MGB657EG.js","sourcesContent":["import {\n createLogStoreFromConfig,\n getLogStore,\n type LogStore,\n OnLogBridgeSink,\n registerLogStore,\n resetLogStore,\n resolveLogStoreConfig,\n WsLogSink,\n} from \"@skaile/workspaces/core/logging\";\nimport type {\n LogEntry,\n LogEntryEvent,\n LogQuery,\n LogQueryResult,\n LogSink,\n} from \"@skaile/workspaces/types\";\n\n/**\n * Pre-init log sink. Active before the LogStore boots — i.e. during the\n * window between process start and `session_init` processing.\n *\n * Writes every entry to `process.stdout` (so early-boot operators / container\n * log shippers still see it). Entries are also captured in a bounded\n * in-memory ring (default cap 200 entries) so that, once the LogStore boots,\n * subscribers can read them via {@link entries} for diagnostic purposes.\n *\n * NOTE: backfilling the buffered entries into the LogStore's SQLite trail is\n * not done in v3.0 because `LogStore.record()` re-stamps id/timestamp/\n * sessionId, which would corrupt the original entries. A follow-up\n * (`AF-PV3 / F-LOG-BACKFILL`) will add a `replay()` API to LogStore so the\n * boot logs land in the persistent trail alongside the live stream.\n *\n * Spec: `_devlog/specs/2026-05-10-deterministic-session-bootstrap.md` §\n * Pre-init logging.\n */\nexport class PreInitRingSink implements LogSink {\n private readonly ring: LogEntry[] = [];\n private readonly cap: number;\n\n constructor(cap = 200) {\n this.cap = cap;\n }\n\n write(entry: LogEntry): void {\n process.stdout.write(formatForStdout(entry));\n this.ring.push(entry);\n if (this.ring.length > this.cap) this.ring.shift();\n }\n\n writeBatch(entries: LogEntry[]): void {\n for (const entry of entries) this.write(entry);\n }\n\n /** Optional query (no-op) — satisfies the LogSink contract. */\n query(_q: LogQuery): LogQueryResult {\n return { entries: this.ring.slice() };\n }\n\n /** Close hook — clears the ring so subsequent writes are dropped. */\n close(): void {\n this.ring.length = 0;\n }\n\n /** Number of entries currently buffered (capped at {@link cap}). */\n size(): number {\n return this.ring.length;\n }\n\n /** Snapshot of the currently-buffered entries. Used for diagnostics. */\n entries(): readonly LogEntry[] {\n return this.ring.slice();\n }\n\n /** Discard all buffered entries. Called by `bootstrapRunnerLogStore`. */\n clear(): void {\n this.ring.length = 0;\n }\n}\n\nfunction formatForStdout(entry: LogEntry): string {\n const ts = entry.timestamp ?? new Date().toISOString();\n const where = [entry.source?.kind, entry.source?.subkind, entry.source?.instance]\n .filter(Boolean)\n .join(\":\");\n const dataStr = entry.data ? ` ${JSON.stringify(entry.data)}` : \"\";\n return `[${ts}] [${entry.level}] [${where}] ${entry.message}${dataStr}\\n`;\n}\n\nlet activePreInitSink: PreInitRingSink | null = null;\n\n/**\n * Install (or return the existing) process-wide pre-init sink. Idempotent\n * so the first import wins; later calls reuse the same ring.\n *\n * Called from the top of every runner entry point (CLI, serve.ts) before\n * any other code emits structured logs.\n */\nexport function installPreInitRingSink(cap = 200): PreInitRingSink {\n if (activePreInitSink) return activePreInitSink;\n activePreInitSink = new PreInitRingSink(cap);\n return activePreInitSink;\n}\n\n/** Currently-installed pre-init sink, or `null` if none has been installed. */\nexport function getPreInitRingSink(): PreInitRingSink | null {\n return activePreInitSink;\n}\n\n/** Drop the reference to the installed sink. Used in tests + on dispose. */\nexport function clearPreInitRingSink(): void {\n activePreInitSink = null;\n}\n\n/**\n * Options for {@link bootstrapRunnerLogStore}.\n *\n * @docLink packages/runner/logging#bootstrap-options\n */\nexport interface BootstrapOptions {\n sessionId: string;\n projectDir: string;\n /** `skaile.yaml`'s `logging:` block, if pre-loaded. */\n yamlBlock?: unknown;\n /** Back-compat callback — every entry mirrored as a formatted line. */\n onLog?: (line: string) => void;\n /**\n * Transport send callback. When provided, a `WsLogSink` is installed so\n * every recorded LogEntry flows to the connected client as a `log_entry`\n * AgentEvent. Drops silently when the transport is disconnected — that\n * gating happens inside the transport's `send()`.\n */\n transportSend?: (event: LogEntryEvent) => void;\n}\n\n/**\n * Result from {@link bootstrapRunnerLogStore}.\n *\n * @docLink packages/runner/logging#bootstrap-result\n */\nexport interface BootstrapResult {\n store: LogStore;\n dispose: () => void;\n}\n\nlet currentSessionId: string | null = null;\n\n/**\n * Idempotent bootstrap. If the same sessionId is re-used, returns the existing\n * registered store. If a different sessionId arrives, the previous store is\n * closed and replaced.\n * @docLink packages/runner/logging#bootstrap-runner-log-store\n */\nexport function bootstrapRunnerLogStore(opts: BootstrapOptions): BootstrapResult {\n const existing = getLogStore();\n if (existing && currentSessionId === opts.sessionId) {\n return { store: existing, dispose: () => disposeStore(existing) };\n }\n\n const cfg = resolveLogStoreConfig({\n sessionId: opts.sessionId,\n workspacePath: opts.projectDir,\n // The skaile.yaml `logging:` block is loosely typed at the workspace-config\n // layer; the resolver validates `mode` / `level` strings at runtime.\n yamlBlock: opts.yamlBlock as Parameters<typeof resolveLogStoreConfig>[0][\"yamlBlock\"],\n });\n const store = createLogStoreFromConfig(cfg);\n\n if (opts.onLog) {\n store.addSink(new OnLogBridgeSink(opts.onLog));\n }\n\n if (opts.transportSend) {\n store.addSink(new WsLogSink({ send: opts.transportSend }));\n }\n\n if (existing) disposeStore(existing);\n registerLogStore(store);\n currentSessionId = opts.sessionId;\n\n // Clear any entries buffered during the pre-init window (between process\n // start and session_init processing). The entries are still visible on\n // stdout (the PreInitRingSink wrote them there as they happened);\n // backfilling them into LogStore.SQLite needs a LogStore.replay()\n // upgrade tracked under follow-up `AF-PV3 / F-LOG-BACKFILL`.\n const preInit = getPreInitRingSink();\n if (preInit) preInit.clear();\n\n return {\n store,\n dispose: () => {\n disposeStore(store);\n currentSessionId = null;\n },\n };\n}\n\n/**\n * Reset the runner's process-singleton LogStore.\n *\n * @docLink packages/runner/logging#reset-runner-log-store\n */\nexport function resetRunnerLogStore(): void {\n const s = getLogStore();\n if (s) disposeStore(s);\n resetLogStore();\n currentSessionId = null;\n}\n\nfunction disposeStore(store: LogStore): void {\n try {\n store.flush();\n store.close();\n } catch {\n /* swallow */\n }\n}\n","import { Marked } from \"marked\";\n// @ts-expect-error — no type declarations for marked-terminal\nimport { markedTerminal } from \"marked-terminal\";\n\nconst marked = new Marked(markedTerminal());\n\n/**\n * Accumulates streamed markdown text and renders it to the terminal\n * with ANSI formatting (bold, italic, code blocks, etc.).\n *\n * Strategy: accumulate full text, re-render on each write, output only\n * the newly rendered portion. Completed blocks (separated by double\n * newlines) are \"committed\" so re-rendering only processes the tail.\n * @docLink packages/runner/dev-guide#agent-chat-single-shot\n */\nexport class MarkdownStreamer {\n private buffer = \"\";\n private committedSource = \"\";\n // biome-ignore lint/correctness/noUnusedPrivateClassMembers: write-only accumulator kept for future diff-based rendering\n private committedRender = \"\";\n private output: NodeJS.WriteStream;\n\n constructor(output: NodeJS.WriteStream = process.stdout) {\n this.output = output;\n }\n\n write(chunk: string): void {\n this.buffer += chunk;\n this.flush();\n }\n\n /** Render any remaining content and reset state. */\n end(): void {\n if (this.buffer.length > this.committedSource.length) {\n const tail = this.buffer.slice(this.committedSource.length);\n if (tail.trim()) {\n const rendered = this.render(tail);\n this.output.write(rendered);\n }\n }\n this.buffer = \"\";\n this.committedRender = \"\";\n this.committedSource = \"\";\n }\n\n private flush(): void {\n // Find the last double-newline boundary — everything before it is\n // structurally complete markdown that won't change with more input.\n const uncommitted = this.buffer.slice(this.committedSource.length);\n const boundary = uncommitted.lastIndexOf(\"\\n\\n\");\n if (boundary === -1) return;\n\n const complete = uncommitted.slice(0, boundary + 2);\n const rendered = this.render(complete);\n this.output.write(rendered);\n\n this.committedSource += complete;\n this.committedRender += rendered;\n }\n\n private render(src: string): string {\n try {\n const result = marked.parse(src);\n if (typeof result === \"string\") return result;\n // marked v15 can return a Promise if async extensions are used,\n // but with marked-terminal it is always synchronous.\n return String(result);\n } catch {\n // Fallback: output raw text if rendering fails\n return src;\n }\n }\n}\n","/**\n * `defineCapability` — author-friendly factory that builds a {@link DefinedCapability}\n * from a Zod-typed input/output schema.\n *\n * Authors declare a capability with Zod schemas; this factory derives the\n * wire-format `inputSchema` / `outputSchema` (JSON Schema) and packages the\n * handler so it can be invoked uniformly through {@link CapabilityRegistry}.\n *\n * The runtime per-handler logger (`ctx.log`) is wired by the registry at\n * invocation time — handlers MUST NOT construct their own logger; all output\n * goes through `ctx.log` so it lands under the\n * `capability:<origin>:<name>` slice (see protocol-v2 carry-forward L2).\n *\n * @category Capabilities\n * @since 2.0.0\n */\n\nimport type {\n Capability,\n CapabilityAudience,\n CapabilityOrigin,\n Logger,\n RenderSpec,\n} from \"@skaile/workspaces/types\";\nimport * as z from \"zod\";\n\n/**\n * Per-invocation context passed to a capability handler. The registry builds\n * a fresh context for each call and fills in `log` from\n * `createLogger({kind: 'capability', subkind: <origin.kind>, instance: <name>})`.\n *\n * Additional runtime hooks (cancellation signal, store accessors, etc.) can\n * be threaded in by the bridge layer in later phases; the minimum contract is\n * `sessionId` + `log`.\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/runner/capabilities#handlercontext-log-convention-carry-forward-l2\n */\nexport type HandlerContext = {\n /** Session this invocation belongs to. */\n sessionId: string;\n /**\n * Per-capability logger pre-configured as\n * `createLogger({kind: 'capability', subkind: <origin.kind>, instance: <name>})`.\n * Handlers MUST emit through this logger so invocations land under the\n * `capability:<origin>:<name>` slice and stay queryable from the debug\n * panel and `skaile session logs`.\n */\n log: Logger;\n};\n\n/**\n * Arguments to {@link defineCapability}. Mirrors the wire-format\n * {@link Capability} fields plus the Zod schemas (input + optional output)\n * and the handler.\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/runner/capabilities#registry-surface\n */\nexport type DefineCapabilityArgs<\n T extends z.ZodTypeAny,\n R extends z.ZodTypeAny | undefined = undefined,\n> = {\n /** Stable, session-unique name. Convention: `<namespace>.<verb>`. */\n name: string;\n /**\n * Human-readable label for user-facing surfaces (cmdK action palette,\n * debug panels). Falls back to `name` when omitted.\n */\n displayName?: string;\n /** Human/LLM-readable summary; shown to the LLM at tool registration. */\n description: string;\n /** Zod schema validating `args` at invocation time. Converted to JSON Schema. */\n input: T;\n /** Optional Zod schema for the return value. Converted to JSON Schema when present. */\n output?: R;\n /** Where the handler runs. */\n side: \"client\" | \"agent\";\n /** Discriminated tag identifying who registered the capability. */\n origin: CapabilityOrigin;\n /** Lifetime: `session` survives the whole session, `turn` is dropped at end-of-turn. */\n scope?: \"session\" | \"turn\";\n /** When true, the bridge auto-resolves with `{}` immediately and runs the handler in the background. */\n fireAndForget?: boolean;\n /** When true, the platform shows a confirm UI before dispatch. */\n requiresApproval?: boolean;\n /** Documentation hint: side-effect, render, or pure query. */\n kind?: \"effect\" | \"render\" | \"query\";\n /**\n * Whether this capability should be exposed in user-facing surfaces\n * (cmdK / capability menus). Defers to `isUserInvokable` inference rules\n * when omitted. See `@skaile/workspaces/types#isUserInvokable`.\n *\n * @deprecated Set {@link audience} instead. Kept for v2.x compatibility\n * with skill authors that haven't migrated.\n */\n userInvokable?: boolean;\n /**\n * Audience scoping for this capability. When omitted, consumers treat\n * the capability as `['llm', 'user']` (v2.x default). Host RPCs and\n * `runner.*` capabilities MUST set this to `['runtime']` so they never\n * reach the LLM tool list or the user-facing command palette.\n *\n * @since 3.0.0\n */\n audience?: CapabilityAudience[];\n /** Appended to the system prompt's `<CAPABILITIES>` section. */\n promptFragment?: string;\n /**\n * Per-capability override for the runner's `capability_result` round-trip\n * timeout. Omit to use `DEFAULT_CAPABILITY_CALL_TIMEOUT_MS` (60s). Set a\n * larger value for capabilities that block longer than a normal tool call\n * (e.g. `platform.ask_session`).\n */\n callTimeoutMs?: number;\n /** Render contract for capabilities that produce a UI surface. */\n render?: RenderSpec;\n /**\n * The handler. Receives validated input plus a {@link HandlerContext}.\n * When `output` is declared, the return type is inferred from the schema;\n * otherwise the handler may return any value (including `void` for pure\n * effects).\n */\n handler: (\n args: z.infer<T>,\n ctx: HandlerContext,\n ) => Promise<R extends z.ZodTypeAny ? z.infer<R> : unknown>;\n};\n\n/**\n * A registered capability. Carries the wire-format {@link Capability} fields\n * plus the original Zod schemas and the type-erased handler. The registry\n * stores `DefinedCapability`s; serialization to the wire (for replay or\n * remote registration) drops the runtime fields.\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/runner/capabilities#registry-surface\n */\nexport type DefinedCapability = Capability & {\n /** Original Zod schema for runtime input validation. Not serialized to the wire. */\n readonly inputZod: z.ZodTypeAny;\n /** Original Zod schema for the optional output, if declared. Not serialized. */\n readonly outputZod?: z.ZodTypeAny;\n /** Type-erased handler invoked through {@link CapabilityRegistry.invoke}. */\n handler: (args: unknown, ctx: HandlerContext) => Promise<unknown>;\n};\n\n/**\n * Build a {@link DefinedCapability} from author-friendly Zod-typed args.\n *\n * The resulting `inputSchema` / `outputSchema` on the capability are JSON\n * Schema records (per the wire contract); the original Zod schemas are kept\n * on `inputZod` / `outputZod` for runtime validation in\n * {@link CapabilityRegistry.invoke}.\n *\n * @example\n * ```ts\n * const reactCap = defineCapability({\n * name: 'platform.react',\n * description: 'Acknowledge a user message with a Unicode emoji.',\n * side: 'client',\n * origin: { kind: 'client' },\n * fireAndForget: true,\n * input: z.object({ emoji: z.string(), targetSeq: z.number().optional() }),\n * handler: async ({ emoji }, ctx) => { ctx.log.info('reacted', { emoji }) },\n * });\n * ```\n *\n * @category Capabilities\n * @since 2.0.0\n * @docLink packages/runner/capabilities#registry-surface\n */\nexport function defineCapability<\n T extends z.ZodTypeAny,\n R extends z.ZodTypeAny | undefined = undefined,\n>(args: DefineCapabilityArgs<T, R>): DefinedCapability {\n const inputSchema = z.toJSONSchema(args.input, {\n target: \"draft-07\",\n io: \"input\",\n }) as Record<string, unknown>;\n const outputSchema = args.output\n ? (z.toJSONSchema(args.output, {\n target: \"draft-07\",\n io: \"output\",\n }) as Record<string, unknown>)\n : undefined;\n\n return {\n name: args.name,\n displayName: args.displayName,\n description: args.description,\n inputSchema,\n outputSchema,\n side: args.side,\n origin: args.origin,\n scope: args.scope,\n fireAndForget: args.fireAndForget,\n requiresApproval: args.requiresApproval,\n kind: args.kind,\n userInvokable: args.userInvokable,\n audience: args.audience,\n promptFragment: args.promptFragment,\n callTimeoutMs: args.callTimeoutMs,\n render: args.render,\n inputZod: args.input,\n outputZod: args.output,\n handler: args.handler as (args: unknown, ctx: HandlerContext) => Promise<unknown>,\n };\n}\n","/**\n * mixin-resolver.ts\n *\n * Resolves agent composition mixin refs (persona, ruleset, knowledge) to text\n * for rendering into the agent definition at install time.\n *\n * Three ref forms:\n * Local path — \"./extra-rules.md\" or \"/abs/path/rules.md\"\n * Read directly relative to agentDir (or absolute).\n * Bare name — \"skaile-base\"\n * Resolved from repos as `${defaultKind}:skaile-base`\n * Qualified — \"persona:researcher@ext-repo#v2.0\"\n * Full AssetRef syntax; repo qualifier searches specific repo only.\n *\n * Knowledge bundles (kind=\"knowledge\") resolve to a directory — all *.md files\n * inside are loaded in priority order (same priority-based loadKnowledge logic used by the asset-manager).\n */\n\nimport { readdirSync } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { AgentManifest, CatalogEntry } from \"@skaile/workspaces/core\";\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\n/**\n * A resolved mixin with its content loaded from disk.\n *\n * @docLink packages/runner/dev-guide#key-conventions\n */\nexport interface ResolvedMixin {\n /** Text content ready for system prompt injection. */\n content: string;\n /** Absolute path to the source file, for debugging. */\n source: string;\n}\n\n/**\n * Pre-built repo catalog map: repoName → CatalogEntry[].\n * Built by the caller (session-builder) from wsConfig.repositories using\n * ensureRepo() + scanRepo() from @skaile/workspaces/core/repo-manager.\n * Local repos are scanned directly; remote repos use the global cache.\n * @docLink packages/runner/dev-guide#key-conventions\n */\nexport type RepoMap = Record<string, CatalogEntry[]>;\n\n/**\n * Content of an agent mixin, loaded from `CONVENTIONS.md` or `RULES.md`.\n *\n * @docLink packages/runner/dev-guide#key-conventions\n */\nexport interface AgentMixinContent {\n personas: ResolvedMixin[];\n rules: ResolvedMixin[];\n knowledge: ResolvedMixin[];\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Resolve a single mixin ref to its text content.\n * Returns null if the ref cannot be resolved (missing file or unknown catalog name).\n * Never throws — callers filter nulls.\n * @docLink packages/runner/dev-guide#key-conventions\n */\nexport async function resolveMixin(\n ref: string,\n defaultKind: string,\n agentDir: string,\n repos: RepoMap,\n): Promise<ResolvedMixin | null> {\n // ── Local path ────────────────────────────────────────────────────────────\n if (ref.startsWith(\".\") || ref.startsWith(\"/\")) {\n const absPath = ref.startsWith(\"/\") ? ref : path.join(agentDir, ref);\n if (defaultKind === \"knowledge\") {\n return loadKnowledgeDir(absPath);\n }\n const content = await readFileSafe(absPath);\n if (!content) return null;\n return { content: stripFrontmatter(content).trim(), source: absPath };\n }\n\n // ── Catalog ref ───────────────────────────────────────────────────────────\n const { kind, name, repoQualifier } = parseRef(ref, defaultKind);\n const entry = findInRepos(repos, kind, name, repoQualifier);\n if (!entry) return null;\n\n if (entry.kind === \"knowledge\") {\n // knowledge.yaml source — load the sibling directory\n return loadKnowledgeDir(path.dirname(entry.source));\n }\n\n // persona, ruleset, skill, contract — read manifest file, strip frontmatter\n const raw = await readFileSafe(entry.source);\n if (!raw) return null;\n return { content: stripFrontmatter(raw).trim(), source: entry.source };\n}\n\n/**\n * Resolve all mixin arrays from a manifest.\n * All three kinds resolve concurrently. Unresolvable refs are silently skipped.\n * @docLink packages/runner/dev-guide#key-conventions\n */\nexport async function resolveAgentMixins(\n manifest: Pick<AgentManifest, \"persona\" | \"rules\" | \"knowledge\">,\n agentDir: string,\n repos: RepoMap,\n): Promise<AgentMixinContent> {\n const resolve = (\n refs: string[] | undefined,\n kind: \"persona\" | \"ruleset\" | \"knowledge\",\n ): Promise<(ResolvedMixin | null)[]> =>\n Promise.all((refs ?? []).map((r) => resolveMixin(r, kind, agentDir, repos)));\n\n const [personaResults, rulesResults, knowledgeResults] = await Promise.all([\n resolve(manifest.persona, \"persona\"),\n resolve(manifest.rules, \"ruleset\"),\n resolve(manifest.knowledge, \"knowledge\"),\n ]);\n\n return {\n personas: personaResults.filter((r): r is ResolvedMixin => r !== null),\n rules: rulesResults.filter((r): r is ResolvedMixin => r !== null),\n knowledge: knowledgeResults.filter((r): r is ResolvedMixin => r !== null),\n };\n}\n\n// ── Internal helpers ──────────────────────────────────────────────────────────\n\n/** Read a file, return empty string on any error. */\nasync function readFileSafe(filePath: string): Promise<string> {\n try {\n return await fs.readFile(filePath, \"utf-8\");\n } catch {\n return \"\";\n }\n}\n\n/** Strip YAML frontmatter (--- delimited) from markdown content. */\nfunction stripFrontmatter(text: string): string {\n return text.replace(/^---\\s*\\n[\\s\\S]*?\\n---\\s*\\n?/, \"\");\n}\n\n/**\n * Parse a mixin ref string into kind, name, and optional repo qualifier.\n * Handles: \"skaile-base\", \"persona:skaile-base\", \"ruleset:safety@skaile-ai#v2\"\n */\nfunction parseRef(\n ref: string,\n defaultKind: string,\n): { kind: string; name: string; repoQualifier: string | undefined } {\n let rest = ref.trim();\n let kind = defaultKind;\n\n // Extract kind: prefix\n const colonIdx = rest.indexOf(\":\");\n if (colonIdx !== -1) {\n kind = rest.slice(0, colonIdx).trim();\n rest = rest.slice(colonIdx + 1).trim();\n }\n\n // Extract #pin suffix (drop it — we use whatever's installed)\n const hashIdx = rest.indexOf(\"#\");\n if (hashIdx !== -1) rest = rest.slice(0, hashIdx).trim();\n\n // Extract @repo qualifier\n let repoQualifier: string | undefined;\n const atIdx = rest.indexOf(\"@\");\n if (atIdx !== -1) {\n repoQualifier = rest.slice(atIdx + 1).trim() || undefined;\n rest = rest.slice(0, atIdx).trim();\n }\n\n return { kind, name: rest, repoQualifier };\n}\n\n/** Find a CatalogEntry by kind + name across all repos (or a specific repo). */\nfunction findInRepos(\n repos: RepoMap,\n kind: string,\n name: string,\n repoQualifier: string | undefined,\n): CatalogEntry | undefined {\n const searchRepos = repoQualifier\n ? repos[repoQualifier]\n ? [repos[repoQualifier]]\n : []\n : Object.values(repos);\n\n for (const entries of searchRepos) {\n const found = entries.find((e) => e.kind === kind && e.name === name);\n if (found) return found;\n }\n return undefined;\n}\n\n/**\n * Load all *.md files from a knowledge directory, in priority order.\n * Reads index.yaml (same priority-based loadKnowledge format used by the asset-manager) when present.\n * Returns combined content joined with \\n\\n---\\n\\n.\n */\nasync function loadKnowledgeDir(dir: string): Promise<ResolvedMixin | null> {\n let entries: string[];\n try {\n entries = readdirSync(dir).filter((e) => e.endsWith(\".md\"));\n } catch {\n return null;\n }\n\n // Parse index.yaml for priority ordering\n const priorityMap: Record<string, number> = {};\n const indexContent = await readFileSafe(path.join(dir, \"index.yaml\"));\n if (indexContent) {\n const pathMatches = [...indexContent.matchAll(/path:\\s*(\\S+)/g)];\n const priorityMatches = [...indexContent.matchAll(/priority:\\s*(\\d+)/g)];\n pathMatches.forEach((m, i) => {\n const filename = m[1];\n if (!filename) return;\n const priority = priorityMatches[i] ? parseInt(priorityMatches[i][1] ?? \"99\", 10) : 99;\n priorityMap[filename] = priority;\n });\n }\n\n const docs = await Promise.all(\n entries.map(async (filename) => ({\n filename,\n priority: priorityMap[filename] ?? 99,\n content: (await readFileSafe(path.join(dir, filename))).trim(),\n })),\n );\n\n const sorted = docs\n .filter((d) => d.content)\n .sort((a, b) => a.priority - b.priority || a.filename.localeCompare(b.filename));\n\n if (sorted.length === 0) return null;\n\n return {\n content: sorted.map((d) => d.content).join(\"\\n\\n---\\n\\n\"),\n source: dir,\n };\n}\n","/**\n * composition/types.ts\n *\n * Shared types for the agent composition module (Task 1.7).\n *\n * Defines the binding system, compile manifest schema, and the\n * resolved composition result that the runner consumes at session start.\n */\n\nimport type { AgentComposeItem, Binding } from \"@skaile/workspaces/types/manifests\";\n\n// ---------------------------------------------------------------------------\n// Re-export from types\n// ---------------------------------------------------------------------------\n\nexport type { AgentComposeItem, Binding };\n\n// ---------------------------------------------------------------------------\n// Kind-to-binding defaults\n// ---------------------------------------------------------------------------\n\n/**\n * Default binding by asset kind.\n *\n * Per the spec: soul -> inline-snapshot, ruleset -> inline-live,\n * everything else (skill, knowledge, connector, mount, etc.) -> discoverable.\n */\nconst KIND_BINDING_DEFAULTS: Record<string, Binding> = {\n soul: \"inline-snapshot\",\n persona: \"inline-snapshot\",\n ruleset: \"inline-live\",\n skill: \"discoverable\",\n knowledge: \"discoverable\",\n connector: \"discoverable\",\n mount: \"discoverable\",\n prompt: \"inline-live\",\n flow: \"discoverable\",\n \"mcp-server\": \"discoverable\",\n contract: \"inline-live\",\n};\n\n/**\n * Resolve the effective binding for a composition item.\n * Uses explicit `binding` if set, otherwise falls back to kind default.\n *\n * @param item - A single entry from an agent manifest's `composes:` list.\n * @returns The effective {@link Binding} — explicit value when set, otherwise\n * the kind-specific default (e.g. `soul` → `inline-snapshot`, `skill` → `discoverable`).\n * @docLink packages/runner/capabilities#resolve-binding\n */\nexport function resolveBinding(item: AgentComposeItem): Binding {\n if (item.binding) return item.binding;\n return KIND_BINDING_DEFAULTS[item.kind] ?? \"discoverable\";\n}\n\n// ---------------------------------------------------------------------------\n// Compile manifest (written to <agent>/compile_manifest.json)\n// ---------------------------------------------------------------------------\n\n/**\n * Single entry in the agent's `compile_manifest.json`. Records the resolved\n * version, content hash, and effective binding for one composition item at\n * the time of the last `skaile rebuild` run.\n *\n * @docLink packages/runner/capabilities#compile-manifest-entry\n */\nexport interface CompileManifestEntry {\n /** Asset ref (e.g. '@skaile/sales-soul@1.2') */\n asset_ref: string;\n /** Resolved version (e.g. '1.2.3') */\n version: string | null;\n /** SHA256 of the resolved content */\n hash: string;\n /** Effective binding */\n binding: Binding;\n /** ISO timestamp when this entry was resolved */\n resolved_at: string;\n}\n\n/**\n * Root structure of `compile_manifest.json` written by `skaile rebuild`.\n * Tracks the prompt version counter and all resolved composition entries.\n * The runner reads this at session start to verify inline-snapshot content\n * against its stored hash.\n *\n * @docLink packages/runner/capabilities#compile-manifest\n */\nexport interface CompileManifest {\n /** Compile manifest schema version */\n schema_version: 1;\n /** Prompt version — bumped on every rebuild */\n prompt_version: number;\n /** Entries for each composition item */\n entries: CompileManifestEntry[];\n /** ISO timestamp of the last rebuild */\n compiled_at: string;\n}\n\n// ---------------------------------------------------------------------------\n// Resolved composition result (consumed by runner at session start)\n// ---------------------------------------------------------------------------\n\n/**\n * A resolved inline content block for system prompt injection.\n *\n * @docLink packages/runner/capabilities#inline-block\n */\nexport interface InlineBlock {\n /** Source ref for debugging */\n ref: string;\n /** Asset kind */\n kind: string;\n /** The text content to inject */\n content: string;\n /** Binding mode that produced this block */\n binding: \"inline-live\" | \"inline-snapshot\";\n}\n\n/**\n * A resolved discoverable item (becomes a tool-list entry).\n *\n * @docLink packages/runner/capabilities#discoverable-entry\n */\nexport interface DiscoverableEntry {\n /** Source ref */\n ref: string;\n /** Asset kind */\n kind: string;\n /** Tool name for capability registry */\n name: string;\n /** One-line description */\n description: string;\n /** Full content (loaded on demand when the tool is invoked) */\n content: string;\n}\n\n/**\n * The full result of resolving an agent's composes: field.\n *\n * @docLink packages/runner/capabilities#resolved-composition\n */\nexport interface ResolvedComposition {\n /** Blocks to inline into the system prompt (inline-live + inline-snapshot) */\n inlineBlocks: InlineBlock[];\n /** Items to register as discoverable capabilities */\n discoverableEntries: DiscoverableEntry[];\n /** Warnings (non-fatal — e.g. missing assets) */\n warnings: string[];\n}\n","/**\n * composition/compile.ts\n *\n * Implements `skaile rebuild <agent>` — re-snapshots all inline-snapshot items,\n * bumps the prompt version, and writes `<agent>/compile_manifest.json`.\n *\n * The compile manifest records what was resolved and when, so the runner can\n * verify content hasn't drifted without a rebuild.\n */\n\nimport { createHash } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { AgentComposeItem } from \"@skaile/workspaces/types/manifests\";\nimport { type CompileManifest, type CompileManifestEntry, resolveBinding } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Filename for the agent compile manifest written by `skaile rebuild`.\n *\n * @docLink packages/runner/capabilities#compile-composition\n */\nexport const COMPILE_MANIFEST_FILENAME = \"compile_manifest.json\";\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/**\n * Options for {@link compileComposition}.\n *\n * @docLink packages/runner/capabilities#compile-composition\n */\nexport interface CompileOpts {\n /** Path to the agent directory (where agent.yaml and compile_manifest.json live) */\n agentDir: string;\n /** The agent's composes: items */\n items: AgentComposeItem[];\n /**\n * Content loader — given an asset ref + kind, returns the content text.\n * Returns null if the content cannot be loaded.\n */\n loadContent: (ref: string, kind: string) => Promise<string | null>;\n /**\n * Version extractor — given an asset ref, returns the resolved version string.\n * Returns null if unknown.\n */\n resolveVersion?: (ref: string) => Promise<string | null>;\n}\n\n/**\n * Result returned by {@link compileComposition}.\n *\n * @docLink packages/runner/capabilities#compile-composition\n */\nexport interface CompileResult {\n /** The written compile manifest */\n manifest: CompileManifest;\n /** Path to the written file */\n manifestPath: string;\n /** Number of entries that were successfully resolved */\n resolvedCount: number;\n /** Warnings for unresolvable items */\n warnings: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compile (rebuild) the agent's composition.\n *\n * 1. Reads existing compile_manifest.json (if present) for version continuity\n * 2. Re-resolves ALL items (both snapshot and non-snapshot get recorded)\n * 3. Bumps prompt_version\n * 4. Writes compile_manifest.json\n *\n * @param opts - Compile options including agentDir, items, and content loader.\n * @returns A {@link CompileResult} with the written manifest and any warnings.\n * @docLink packages/runner/capabilities#compile-composition\n */\nexport async function compileComposition(opts: CompileOpts): Promise<CompileResult> {\n const { agentDir, items, loadContent, resolveVersion } = opts;\n const manifestPath = path.join(agentDir, COMPILE_MANIFEST_FILENAME);\n const warnings: string[] = [];\n\n // Read existing manifest for version continuity\n const existing = await loadCompileManifest(manifestPath);\n const nextVersion = (existing?.prompt_version ?? 0) + 1;\n\n // Resolve all items\n const entries: CompileManifestEntry[] = [];\n for (const item of items) {\n const binding = resolveBinding(item);\n const content = await loadContent(item.ref, item.kind);\n\n if (!content) {\n warnings.push(`\"${item.ref}\" (${item.kind}): content not found — skipped`);\n continue;\n }\n\n const hash = createHash(\"sha256\").update(content).digest(\"hex\");\n const version = resolveVersion ? await resolveVersion(item.ref) : null;\n\n entries.push({\n asset_ref: item.ref,\n version,\n hash,\n binding,\n resolved_at: new Date().toISOString(),\n });\n }\n\n const manifest: CompileManifest = {\n schema_version: 1,\n prompt_version: nextVersion,\n entries,\n compiled_at: new Date().toISOString(),\n };\n\n // Write atomically: temp file + rename to avoid corruption on interrupt\n const tmpPath = `${manifestPath}.tmp`;\n await fs.writeFile(tmpPath, `${JSON.stringify(manifest, null, 2)}\\n`, \"utf-8\");\n await fs.rename(tmpPath, manifestPath);\n\n return {\n manifest,\n manifestPath,\n resolvedCount: entries.length,\n warnings,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Load an existing compile_manifest.json, or return undefined if not found.\n *\n * @param manifestPath - Absolute path to the manifest file.\n * @returns The parsed {@link CompileManifest} or `undefined` when missing or malformed.\n * @docLink packages/runner/capabilities#load-compile-manifest\n */\nexport async function loadCompileManifest(\n manifestPath: string,\n): Promise<CompileManifest | undefined> {\n try {\n const raw = await fs.readFile(manifestPath, \"utf-8\");\n const parsed = JSON.parse(raw);\n if (parsed?.schema_version === 1 && typeof parsed.prompt_version === \"number\") {\n return parsed as CompileManifest;\n }\n return undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Load compile manifest from an agent directory, reading the file from\n * `<agentDir>/compile_manifest.json`.\n *\n * @param agentDir - Absolute path to the agent definition directory.\n * @returns The parsed {@link CompileManifest} or `undefined` when missing or malformed.\n * @docLink packages/runner/capabilities#load-compile-manifest-from-dir\n */\nexport async function loadCompileManifestFromDir(\n agentDir: string,\n): Promise<CompileManifest | undefined> {\n return loadCompileManifest(path.join(agentDir, COMPILE_MANIFEST_FILENAME));\n}\n","/**\n * composition/resolve.ts\n *\n * Resolves an agent's `composes:` items against the Library into a\n * ResolvedComposition — prompt blocks for inline items and discoverable\n * entries for tool-list items.\n *\n * Three resolution paths per binding:\n * - `inline-snapshot`: reads frozen content from compile_manifest.json\n * - `inline-live`: reads current content from Library (per invocation)\n * - `discoverable`: registers as a capability (name + description + content)\n *\n * This module is pure logic — no IO beyond the IAssetIndex calls.\n */\n\nimport { createHash } from \"node:crypto\";\nimport type { IAssetIndex } from \"@skaile/workspaces/library\";\nimport type { AgentComposeItem } from \"@skaile/workspaces/types/manifests\";\nimport { type CompileManifest, type ResolvedComposition, resolveBinding } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/**\n * Options for {@link resolveComposition}.\n *\n * @docLink packages/runner/capabilities#resolve-composition\n */\nexport interface ResolveCompositionOpts {\n /** The agent's composes: items */\n items: AgentComposeItem[];\n /** Library for asset resolution */\n library: IAssetIndex;\n /**\n * Pre-loaded compile manifest for inline-snapshot items.\n * If absent, inline-snapshot items fall back to live resolution with a warning.\n */\n compileManifest?: CompileManifest;\n /**\n * Content loader — given an asset ref, returns the asset's prompt-injectable content.\n * For skill: the SKILL.md body. For persona/ruleset: the manifest body text.\n * Returns null if the content cannot be loaded.\n */\n loadContent: (ref: string, kind: string) => Promise<string | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve all composition items for an agent.\n *\n * Returns:\n * - inlineBlocks: content to inject into the system prompt\n * - discoverableEntries: items to register as LLM-visible capabilities\n * - warnings: non-fatal issues encountered during resolution\n *\n * @param opts - Resolution options with items, library, optional compile manifest and content loader.\n * @returns A {@link ResolvedComposition} with inline blocks, discoverable entries, and warnings.\n * @docLink packages/runner/capabilities#resolve-composition\n */\nexport async function resolveComposition(\n opts: ResolveCompositionOpts,\n): Promise<ResolvedComposition> {\n const { items, library, compileManifest, loadContent } = opts;\n const result: ResolvedComposition = {\n inlineBlocks: [],\n discoverableEntries: [],\n warnings: [],\n };\n\n for (const item of items) {\n const binding = resolveBinding(item);\n\n try {\n switch (binding) {\n case \"inline-snapshot\":\n await resolveInlineSnapshot(item, binding, compileManifest, loadContent, result);\n break;\n case \"inline-live\":\n await resolveInlineLive(item, binding, loadContent, result);\n break;\n case \"discoverable\":\n await resolveDiscoverable(item, library, loadContent, result);\n break;\n }\n } catch (err) {\n result.warnings.push(\n `Failed to resolve \"${item.ref}\" (${item.kind}): ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Internal: per-binding resolution\n// ---------------------------------------------------------------------------\n\nasync function resolveInlineSnapshot(\n item: AgentComposeItem,\n binding: \"inline-snapshot\",\n compileManifest: CompileManifest | undefined,\n loadContent: (ref: string, kind: string) => Promise<string | null>,\n result: ResolvedComposition,\n): Promise<void> {\n // Try to find frozen content in the compile manifest\n if (compileManifest) {\n const entry = compileManifest.entries.find(\n (e) => e.asset_ref === item.ref && e.binding === \"inline-snapshot\",\n );\n if (entry) {\n const content = await loadContent(item.ref, item.kind);\n if (content) {\n // Verify content hasn't drifted since last rebuild\n const hash = createHash(\"sha256\").update(content).digest(\"hex\");\n if (hash !== entry.hash) {\n result.warnings.push(\n `\"${item.ref}\" (${item.kind}) content has changed since last rebuild (expected ${entry.hash.slice(0, 8)}…, got ${hash.slice(0, 8)}…). Run \"skaile rebuild\" to update the snapshot.`,\n );\n }\n result.inlineBlocks.push({ ref: item.ref, kind: item.kind, content, binding });\n return;\n }\n }\n }\n\n // Fallback: resolve live (with warning that rebuild is recommended)\n const content = await loadContent(item.ref, item.kind);\n if (content) {\n result.warnings.push(\n `\"${item.ref}\" (${item.kind}) is binding=inline-snapshot but no compile_manifest.json found — using live content. Run \"skaile rebuild\" to freeze.`,\n );\n result.inlineBlocks.push({ ref: item.ref, kind: item.kind, content, binding });\n } else {\n result.warnings.push(`\"${item.ref}\" (${item.kind}): content not found`);\n }\n}\n\nasync function resolveInlineLive(\n item: AgentComposeItem,\n binding: \"inline-live\",\n loadContent: (ref: string, kind: string) => Promise<string | null>,\n result: ResolvedComposition,\n): Promise<void> {\n const content = await loadContent(item.ref, item.kind);\n if (content) {\n result.inlineBlocks.push({ ref: item.ref, kind: item.kind, content, binding });\n } else {\n result.warnings.push(`\"${item.ref}\" (${item.kind}): content not found`);\n }\n}\n\nasync function resolveDiscoverable(\n item: AgentComposeItem,\n library: IAssetIndex,\n loadContent: (ref: string, kind: string) => Promise<string | null>,\n result: ResolvedComposition,\n): Promise<void> {\n // Look up the asset definition for metadata. This is optional enrichment —\n // a library failure (missing/corrupt/migrating index DB) must never drop the\n // entry, so swallow the error and fall back to the default description.\n let assetDef: Awaited<ReturnType<IAssetIndex[\"getAssetDef\"]>> = null;\n try {\n assetDef = await library.getAssetDef(item.ref);\n } catch (err) {\n assetDef = null;\n result.warnings.push(\n `\"${item.ref}\" (${item.kind}): library lookup failed (${err instanceof Error ? err.message : String(err)}) — using fallback description`,\n );\n }\n\n // Build the tool name from the ref\n const name = buildToolName(item);\n const description = assetDef?.description ?? `${item.kind}: ${item.ref}`;\n\n // Load full content for on-demand usage\n const content = await loadContent(item.ref, item.kind);\n if (content) {\n result.discoverableEntries.push({\n ref: item.ref,\n kind: item.kind,\n name,\n description,\n content,\n });\n } else {\n result.warnings.push(`\"${item.ref}\" (${item.kind}): content not found for discoverable entry`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Build a capability tool name from a compose item ref.\n * e.g. '@skaile/gmail@^1' -> 'skaile__gmail'\n * e.g. '@acme/sales-research@^3' -> 'acme__sales-research'\n * e.g. '@skaile/gmail' (no version) -> 'skaile__gmail'\n */\nfunction buildToolName(item: AgentComposeItem): string {\n // Strip version pin: only strip @<version> if it appears after the name\n // (i.e. after the last /). Scoped refs like @skaile/gmail have the @\n // as the publisher prefix — we must not strip that.\n const lastSlash = item.ref.lastIndexOf(\"/\");\n let refNoVersion: string;\n if (lastSlash !== -1) {\n const afterSlash = item.ref.slice(lastSlash + 1);\n const versionAt = afterSlash.indexOf(\"@\");\n refNoVersion = versionAt !== -1 ? item.ref.slice(0, lastSlash + 1 + versionAt) : item.ref;\n } else {\n // No slash — bare ref like 'gmail@^1'\n const versionAt = item.ref.indexOf(\"@\");\n refNoVersion = versionAt !== -1 ? item.ref.slice(0, versionAt) : item.ref;\n }\n // Strip leading @\n const cleaned = refNoVersion.replace(/^@/, \"\");\n // Replace / with __ for flat tool namespace\n return cleaned.replace(/\\//g, \"__\");\n}\n","/**\n * composition/bootstrap.ts\n *\n * Wires the composition resolver into the agent session lifecycle.\n *\n * This module provides:\n * - `resolveAgentComposition()` — called by session-builder.ts to produce\n * inline blocks (→ system prompt) and discoverable entries (→ capability\n * registry)\n * - `registerCompositionCapabilities()` — called by serve.ts to register\n * discoverable entries as Protocol v2 capabilities\n *\n * Phase 1 limitation: the content loader uses `resolveMixin()` which only\n * resolves local-path refs (./file.md, /abs/path). Scoped catalog refs\n * (@publisher/name) require a populated RepoMap from workspace config, which\n * Phase 2 / Library integration will provide. Unresolvable refs produce\n * warnings but do not block session start.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { AgentManifest } from \"@skaile/workspaces/core\";\nimport type { IAssetIndex } from \"@skaile/workspaces/library\";\nimport type { Logger } from \"@skaile/workspaces/types\";\nimport * as z from \"zod\";\nimport type { CapabilityRegistry } from \"../capability-registry.js\";\nimport { defineCapability } from \"../define-capability.js\";\nimport { type RepoMap, resolveMixin } from \"../mixin-resolver.js\";\nimport { loadCompileManifestFromDir } from \"./compile.js\";\nimport { resolveComposition } from \"./resolve.js\";\nimport type { DiscoverableEntry, ResolvedComposition } from \"./types.js\";\n\n// Re-export for downstream convenience\nexport type { ResolvedComposition };\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/**\n * Options for {@link resolveAgentComposition}.\n *\n * @docLink packages/runner/capabilities#resolve-agent-composition\n */\nexport interface ResolveAgentCompositionOpts {\n /** Path to the agent definition directory (where agent.yaml lives) */\n agentDir: string;\n /** Parsed agent manifest (must have `composes` field) */\n manifest: AgentManifest;\n /**\n * Project root — reserved for Phase 2 workspace config resolution.\n * In Phase 1 this is unused but accepted so the call site doesn't\n * need updating when Library integration lands.\n */\n projectDir: string;\n /** Pre-built repo map for catalog resolution. Empty in Phase 1. */\n repos?: RepoMap;\n /** Logger for composition resolution warnings */\n log?: Logger;\n}\n\n// ---------------------------------------------------------------------------\n// Public API: Resolve\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve an agent's `composes:` items into inline blocks and discoverable\n * entries. Called by session-builder.ts during the session creation pipeline.\n *\n * Returns null when the manifest has no `composes:` items.\n *\n * @param opts - Resolution options including agentDir, manifest, and optional repos/log.\n * @returns A {@link ResolvedComposition} or `null` when there are no composition items.\n * @docLink packages/runner/capabilities#resolve-agent-composition\n */\nexport async function resolveAgentComposition(\n opts: ResolveAgentCompositionOpts,\n): Promise<ResolvedComposition | null> {\n const { agentDir, manifest, repos = {}, log } = opts;\n\n const items = manifest.composes;\n if (!items || items.length === 0) return null;\n\n // Load compile manifest for inline-snapshot verification\n const compileManifest = await loadCompileManifestFromDir(agentDir);\n\n // Build a content loader using the existing mixin resolver.\n // Phase 1: only local-path refs resolve successfully. Scoped catalog refs\n // (@publisher/name) require a populated RepoMap which Phase 2 provides.\n // Non-matching kinds simply return null (surfaces as a compose warning).\n const loadContent = async (ref: string, kind: string): Promise<string | null> => {\n try {\n const resolved = await resolveMixin(ref, kind, agentDir, repos);\n return resolved?.content ?? null;\n } catch {\n return null;\n }\n };\n\n // Try to open the real LocalIndex for asset description enrichment.\n // Falls back to a null-returning stub when the library DB doesn't exist\n // (user hasn't run `skaile source add` + `skaile source sync` yet).\n const library = await openLocalIndexIfAvailable(log);\n\n const result = await resolveComposition({\n items,\n library,\n compileManifest,\n loadContent,\n });\n\n // Log warnings so they surface in session debug logs\n if (log && result.warnings.length > 0) {\n for (const warning of result.warnings) {\n log.warn(warning);\n }\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Public API: Register Capabilities\n// ---------------------------------------------------------------------------\n\n/**\n * Register discoverable composition entries as Protocol v2 capabilities.\n *\n * Each discoverable entry becomes a tool the LLM can invoke to \"activate\"\n * that asset. When invoked, the handler returns the asset's full content\n * (e.g. a SKILL.md body for skills, connection instructions for connectors).\n *\n * The LLM sees a lean tool list (name + description only) and loads full\n * content on demand — this keeps the context window efficient for agents\n * that compose many assets.\n *\n * @param registry - The session capability registry to register capabilities onto.\n * @param entries - Discoverable entries from a prior {@link resolveAgentComposition} call.\n * @docLink packages/runner/capabilities#register-composition-capabilities\n */\nexport function registerCompositionCapabilities(\n registry: CapabilityRegistry,\n entries: DiscoverableEntry[],\n): void {\n for (const entry of entries) {\n const cap = defineCapability({\n name: entry.name,\n displayName: `${entry.kind}: ${entry.ref}`,\n description: entry.description,\n side: \"agent\",\n origin: { kind: \"skill\", skillId: entry.ref },\n scope: \"session\",\n kind: \"query\",\n userInvokable: false,\n input: z.strictObject({}),\n handler: async (_args, ctx) => {\n ctx.log.info(\"loading composed asset content\", {\n ref: entry.ref,\n kind: entry.kind,\n });\n return { content: entry.content, ref: entry.ref, kind: entry.kind };\n },\n });\n registry.register(cap, \"agent\");\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal: Library resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Null-returning IAssetIndex stub used when no real Library is available.\n * All query methods return empty; write methods are no-ops.\n */\nconst STUB_LIBRARY: IAssetIndex = {\n getAssetDef: async () => null,\n listAssetDefs: async () => [],\n createInstance: async () => ({}) as any,\n getInstance: async () => null,\n listInstances: async () => [],\n updateInstance: async () => ({}) as any,\n deleteInstance: async () => {},\n assign: async () => ({}) as any,\n unassign: async () => {},\n listAssignments: async () => [],\n getConsumptionGraph: async () => [],\n};\n\n/**\n * Try to open the LocalIndex SQLite store if it exists.\n * Returns a stub when the library DB is missing (user hasn't synced yet)\n * or when opening fails (e.g. corrupt DB).\n */\nasync function openLocalIndexIfAvailable(log?: Logger): Promise<IAssetIndex> {\n // Probe for the index file at the canonical 2026-05-27 location plus the\n // two legacy ones (lib.db inside libraries/ or library/). Migration to the\n // canonical path is handled by `createLibraryDb`; here we only need to know\n // whether *some* index file is present before constructing LocalIndex.\n const indexPath = process.env.SKAILE_INDEX_PATH ?? join(homedir(), \".skaile\", \"index.db\");\n const librariesDir = process.env.SKAILE_LIBRARIES_DIR ?? join(homedir(), \".skaile\", \"libraries\");\n const legacyHome = join(homedir(), \".skaile\", \"library\");\n const probes = [\n indexPath,\n join(librariesDir, \"index.db\"),\n join(librariesDir, \"lib.db\"),\n join(legacyHome, \"lib.db\"),\n ];\n\n if (!probes.some((p) => existsSync(p))) {\n return STUB_LIBRARY;\n }\n\n try {\n // Deferred import so the runner does not eagerly pull in the library\n // subpath when no local library DB exists.\n const { LocalIndex } = await import(\"@skaile/workspaces/library\");\n return new LocalIndex() as IAssetIndex;\n } catch (err) {\n log?.debug(`Could not open LocalIndex at ${indexPath}: ${(err as Error).message}`);\n return STUB_LIBRARY;\n }\n}\n","/**\n * Build a markdown section describing the platform context in which the\n * agent is running. Rendered into the system prompt alongside resource and environment sections.\n */\n\nimport type { AgentContextConfig } from \"@skaile/workspaces/core\";\n\nconst PLATFORM_DESCRIPTIONS: Record<string, string> = {\n skaile:\n \"You are an AI assistant operating within the Skaile platform, an enterprise AI workspace. Users interact with you through a chat interface in their browser.\",\n};\n\n/**\n * Build a markdown section describing the platform context in which the\n * agent is running. Rendered into the system prompt alongside resource\n * and environment sections.\n *\n * @param context - Platform context configuration (platform, multi_user, session_model)\n * @returns Markdown section string, or undefined when no context is configured\n * @docLink packages/runner/dev-guide#flow-execution-turn-based-model\n */\nexport function buildContextSection(context: AgentContextConfig | undefined): string | undefined {\n if (!context) return undefined;\n const hasAny =\n context.platform !== undefined ||\n context.multi_user !== undefined ||\n context.session_model !== undefined;\n if (!hasAny) return undefined;\n\n const lines: string[] = [\"## Platform\", \"\"];\n\n if (context.platform) {\n const description = PLATFORM_DESCRIPTIONS[context.platform];\n if (description) {\n lines.push(description);\n } else {\n lines.push(`You are running inside the ${context.platform} platform.`);\n }\n lines.push(\"\");\n }\n\n if (context.multi_user === true) {\n lines.push(\n \"Multiple users may participate in the same session. Be aware that messages in this conversation may come from different users.\",\n );\n lines.push(\"\");\n } else if (context.multi_user === false) {\n lines.push(\"This is a single-user session.\");\n lines.push(\"\");\n }\n\n if (context.session_model === \"persistent\") {\n lines.push(\n \"Your work persists across interactions. Files you create or modify in the workspace are saved and available in future sessions.\",\n );\n lines.push(\"\");\n } else if (context.session_model === \"ephemeral\") {\n lines.push(\n \"This session is ephemeral. Work you do does not persist beyond the current interaction.\",\n );\n lines.push(\"\");\n }\n\n // Trim trailing empty line\n while (lines.length > 0 && lines[lines.length - 1] === \"\") lines.pop();\n\n return lines.join(\"\\n\");\n}\n","/**\n * Probe the runtime environment for available tools and runtimes, and build\n * a markdown section describing them for the system prompt.\n *\n * Runs once at session start. All probes execute in parallel with a per-probe\n * timeout so the total wall time is bounded by the slowest single probe.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nconst PROBE_TIMEOUT_MS = 1500;\n\ninterface VersionProbe {\n label: string;\n bin: string;\n args: string[];\n /** Extract version from stdout (first line by default). */\n extract?: (output: string) => string;\n}\n\nconst VERSION_PROBES: VersionProbe[] = [\n { label: \"Python\", bin: \"python3\", args: [\"--version\"] },\n { label: \"Node.js\", bin: \"node\", args: [\"--version\"] },\n { label: \"Bun\", bin: \"bun\", args: [\"--version\"] },\n { label: \"Git\", bin: \"git\", args: [\"--version\"] },\n { label: \"npm\", bin: \"npm\", args: [\"--version\"] },\n {\n label: \"pip\",\n bin: \"pip\",\n args: [\"--version\"],\n extract: (out) => out.split(\" \").slice(0, 2).join(\" \"),\n },\n];\n\nconst PRESENCE_PROBES = [\"curl\", \"jq\", \"ssh\", \"wget\", \"rg\"];\n\nasync function runProbe(bin: string, args: string[]): Promise<string | null> {\n try {\n const { stdout } = await execFileAsync(bin, args, { timeout: PROBE_TIMEOUT_MS });\n return stdout.trim().split(\"\\n\")[0] ?? null;\n } catch {\n return null;\n }\n}\n\nasync function checkPresence(bin: string): Promise<boolean> {\n try {\n await execFileAsync(\"which\", [bin], { timeout: PROBE_TIMEOUT_MS });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Probe the runtime environment for available tools and runtimes at\n * session start, and build a markdown section describing them for the\n * system prompt.\n *\n * All probes execute in parallel with a per-probe timeout so total wall\n * time is bounded by the slowest single probe.\n *\n * @param projectDir - The project working directory\n * @returns Markdown section string, or undefined when no tools are found\n * @docLink packages/runner/dev-guide#environment-variables\n */\nexport async function buildEnvironmentSection(projectDir: string): Promise<string | undefined> {\n const versionResults = await Promise.allSettled(\n VERSION_PROBES.map(async (probe) => {\n const raw = await runProbe(probe.bin, probe.args);\n if (!raw) return null;\n const version = probe.extract ? probe.extract(raw) : raw;\n return { label: probe.label, version };\n }),\n );\n\n const presenceResults = await Promise.allSettled(PRESENCE_PROBES.map(checkPresence));\n\n const runtimes: string[] = [];\n for (const result of versionResults) {\n if (result.status === \"fulfilled\" && result.value) {\n runtimes.push(`${result.value.label} (${result.value.version})`);\n }\n }\n\n const tools: string[] = [];\n for (let i = 0; i < PRESENCE_PROBES.length; i++) {\n const result = presenceResults[i];\n if (result?.status === \"fulfilled\" && result.value) {\n tools.push(PRESENCE_PROBES[i]!);\n }\n }\n\n if (runtimes.length === 0 && tools.length === 0) return undefined;\n\n const lines: string[] = [\n \"## Environment\",\n \"\",\n \"You are running inside an isolated container with the following tools available:\",\n \"\",\n ];\n\n if (runtimes.length > 0) {\n lines.push(\"**Runtimes:**\");\n for (const r of runtimes) lines.push(`- ${r}`);\n lines.push(\"\");\n }\n\n if (tools.length > 0) {\n lines.push(`**Tools:** ${tools.join(\", \")}`);\n lines.push(\"\");\n }\n\n const shell = process.env.SHELL ?? \"sh\";\n lines.push(`**Shell:** ${shell}`);\n lines.push(`**Working directory:** ${projectDir}`);\n\n return lines.join(\"\\n\");\n}\n","/**\n * manifest.ts\n *\n * Parses the agent definition manifest (agent.yaml) from a GitAgent directory.\n * This is the sole responsibility of this module — system prompt assembly for\n * SOUL/RULES/knowledge is handled by the renderers at install time and the\n * backend drivers at runtime (native identity).\n */\n\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { AgentManifest } from \"@skaile/workspaces/core\";\nimport { parse as parseYaml } from \"yaml\";\n\n/** True if the given directory contains a valid GitAgent definition (agent.yaml present). */\n/**\n * Check whether an agent definition directory contains a valid agent.yaml.\n *\n * @param agentDir - Path to the agent definition directory\n * @returns true when agent.yaml exists at the given path\n * @docLink packages/runner/dev-guide#manifest-loading\n */\nexport async function agentDefinitionExists(agentDir: string): Promise<boolean> {\n try {\n await fs.access(path.join(agentDir, \"agent.yaml\"));\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Load and parse the agent manifest from `agent.yaml` in the given directory.\n *\n * Returns `undefined` when:\n * - The file does not exist\n * - The file is empty or whitespace-only\n * - The YAML is malformed\n *\n * This replaces the old `buildAgentImprint()` for the manifest-extraction use case.\n * The system prompt assembly that `buildAgentImprint()` used to do is no longer\n * a runtime concern — it is handled by the renderers at install time.\n * @docLink packages/runner/dev-guide#manifest-loading\n */\nexport async function loadAgentManifest(agentDir: string): Promise<AgentManifest | undefined> {\n const agentYamlPath = path.join(agentDir, \"agent.yaml\");\n let content: string;\n try {\n content = await fs.readFile(agentYamlPath, \"utf-8\");\n } catch {\n return undefined;\n }\n if (!content.trim()) return undefined;\n try {\n return parseYaml(content) as AgentManifest;\n } catch {\n return undefined;\n }\n}\n","// Burst coalescer for file_changed: collapses bulk-git-op storms per directory.\n// Design: packages/workspaces/_devlog/notes/2026-06-20-file-changed-coalescer-design.md\n\nimport type { ConnectorChangeEvent } from \"@skaile/workspaces/connectors\";\n\n/** Tuning for {@link FileChangedCoalescer}. */\nexport interface CoalesceOptions {\n /**\n * Burst window in ms. Events within this gap of each other (per mount) are\n * considered part of the same burst. Default: 1000.\n */\n windowMs?: number;\n /**\n * Number of events within a window that flips a mount into \"burst mode\".\n * At/under this count events pass through individually; above it the rest of\n * the burst is coalesced by directory. Default: 50.\n */\n threshold?: number;\n /**\n * Cap on the number of per-directory representative events emitted per burst.\n * If a burst touches more distinct directories than this, the representatives\n * for the first `maxDirs` directories are emitted plus a single root-level\n * fallback event so nothing is silently missed. Default: 256.\n */\n maxDirs?: number;\n}\n\nconst DEFAULT_WINDOW_MS = 1000;\nconst DEFAULT_THRESHOLD = 50;\nconst DEFAULT_MAX_DIRS = 256;\n\n/** Connector wire actions that change a directory's listing (add/remove entry). */\nfunction isStructuralAction(action: ConnectorChangeEvent[\"action\"]): boolean {\n return action === \"create\" || action === \"delete\";\n}\n\n/** Parent directory of a mount-relative path; top-level entries parent to root (\"\"). */\nfunction parentDirOf(path: string): string {\n return path.includes(\"/\") ? path.slice(0, path.lastIndexOf(\"/\")) : \"\";\n}\n\n/**\n * Representative chosen for a single affected directory during a burst. We keep\n * the first event seen for the dir, and — if any structural change occurred in\n * that dir — separately remember a structural event so the emitted\n * representative carries a structural action (real path inside the dir). This\n * keeps the backend filter forwarding it to expanded-folder watchers and makes\n * the frontend refetch the grandparent too.\n */\ninterface DirRepresentative {\n first: ConnectorChangeEvent;\n structural: ConnectorChangeEvent | null;\n}\n\ninterface MountBurstState {\n /** Timestamp of the most recent event. */\n lastEvent: number;\n /** Events seen in the current window. */\n count: number;\n /** True once `count` has exceeded the threshold — burst mode. */\n bursting: boolean;\n /** One representative per distinct parent directory touched while bursting. */\n dirs: Map<string, DirRepresentative>;\n /** True once `dirs` overflowed `maxDirs` — emit a coarse root fallback on flush. */\n dirCapHit: boolean;\n /** Pending flush timer that emits the representatives once the burst quiesces. */\n timer: ReturnType<typeof setTimeout> | null;\n}\n\n/**\n * Per-mount burst detector. Feed it watcher events via {@link push}; it calls\n * `emit` either with the original event (normal traffic) or with one\n * representative event per affected directory (when a burst is detected).\n * Quiescence is detected with a timer so representatives fire shortly after the\n * last file in the burst settles.\n *\n * Stateful and not thread-safe — one instance per `startWatching` lifetime.\n */\nexport class FileChangedCoalescer {\n private readonly windowMs: number;\n private readonly threshold: number;\n private readonly maxDirs: number;\n private readonly emit: (mountId: string, event: ConnectorChangeEvent) => void;\n private readonly now: () => number;\n private readonly log: (msg: string) => void;\n private readonly states = new Map<string, MountBurstState>();\n\n constructor(\n emit: (mountId: string, event: ConnectorChangeEvent) => void,\n options?: CoalesceOptions,\n // Injectable clock for deterministic tests.\n now: () => number = Date.now,\n // Injectable logger for the cap-hit warning.\n log: (msg: string) => void = (m) => console.warn(m),\n ) {\n this.emit = emit;\n this.windowMs = options?.windowMs ?? DEFAULT_WINDOW_MS;\n this.threshold = options?.threshold ?? DEFAULT_THRESHOLD;\n this.maxDirs = options?.maxDirs ?? DEFAULT_MAX_DIRS;\n this.now = now;\n this.log = log;\n }\n\n push(mountId: string, event: ConnectorChangeEvent): void {\n const t = this.now();\n let state = this.states.get(mountId);\n if (!state) {\n state = {\n lastEvent: t,\n count: 0,\n bursting: false,\n dirs: new Map(),\n dirCapHit: false,\n timer: null,\n };\n this.states.set(mountId, state);\n }\n\n // A gap longer than the window ends the previous burst and starts fresh.\n if (t - state.lastEvent > this.windowMs) {\n this.flush(mountId, state); // also resets bursting/dirs\n state.count = 0;\n }\n state.lastEvent = t;\n state.count += 1;\n\n if (state.bursting) {\n this.recordDir(state, event);\n this.armFlush(mountId, state);\n return;\n }\n\n if (state.count > this.threshold) {\n // Crossing the threshold: enter burst mode. Everything from here until\n // quiescence collapses by directory. The already-forwarded sub-threshold\n // events are harmless (each is a real change); the per-dir representatives\n // cover the rest of the burst.\n state.bursting = true;\n this.recordDir(state, event);\n this.armFlush(mountId, state);\n return;\n }\n\n // Below threshold — stream through unchanged.\n this.emit(mountId, event);\n }\n\n /** Cancel timers and emit any pending representatives. Call on watcher teardown. */\n dispose(): void {\n for (const [mountId, state] of this.states) this.flush(mountId, state);\n this.states.clear();\n }\n\n private recordDir(state: MountBurstState, event: ConnectorChangeEvent): void {\n const dir = parentDirOf(event.path);\n let rep = state.dirs.get(dir);\n if (!rep) {\n if (state.dirs.size >= this.maxDirs) {\n // Too many distinct dirs to represent individually; the root fallback\n // emitted on flush covers the overflow.\n state.dirCapHit = true;\n return;\n }\n rep = { first: event, structural: null };\n state.dirs.set(dir, rep);\n }\n if (!rep.structural && isStructuralAction(event.action)) {\n rep.structural = event;\n }\n }\n\n private armFlush(mountId: string, state: MountBurstState): void {\n if (state.timer) clearTimeout(state.timer);\n state.timer = setTimeout(() => {\n const s = this.states.get(mountId);\n if (s) this.flush(mountId, s);\n }, this.windowMs);\n // Don't keep the process alive for a pending flush.\n (state.timer as { unref?: () => void }).unref?.();\n }\n\n private flush(mountId: string, state: MountBurstState): void {\n if (state.timer) {\n clearTimeout(state.timer);\n state.timer = null;\n }\n if (state.bursting && state.dirs.size > 0) {\n // Prefer a structural representative per dir (so the backend forwards it to\n // expanded-folder watchers and the frontend refetches the grandparent too);\n // otherwise the first event seen for the dir (an edit) is fine.\n for (const rep of state.dirs.values()) {\n this.emit(mountId, rep.structural ?? rep.first);\n }\n if (state.dirCapHit) {\n this.log(\n `[file-changed-coalescer] mount ${mountId}: burst touched more than ${this.maxDirs} directories; emitted ${this.maxDirs} per-dir events + a root fallback`,\n );\n // Coarse fallback: a root-relative event so a consumer at least refreshes\n // the mount root for the dirs we couldn't represent individually.\n this.emit(mountId, { path: \"\", action: \"edit\", source: \"filesystem\" });\n }\n }\n state.bursting = false;\n state.dirs.clear();\n state.dirCapHit = false;\n }\n}\n","/**\n * Resolves Nix flake attribute paths to /nix/store out-paths via\n * `nix path-info --offline <flakeRef>#<attr>`.\n *\n * Used by the MCP wiring path (and Phase 3+ connector/mount paths) to\n * turn `${recipe:<id>:<sub>}` markers into absolute store paths before\n * subprocess spawn.\n */\nimport { spawnSync } from \"node:child_process\";\nimport { readFileSync, statSync } from \"node:fs\";\nimport { validateAssetRecipeAttr } from \"@skaile/workspaces/core\";\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\n\nexport class RecipeUnavailableError extends Error {\n constructor(\n public readonly flakeRef: string,\n public readonly attr: string,\n cause?: unknown,\n ) {\n super(\n `Recipe unavailable: ${flakeRef}#${attr}${cause instanceof Error ? ` - ${cause.message}` : \"\"}`,\n );\n this.name = \"RecipeUnavailableError\";\n }\n}\n\n/**\n * Per-resolve-pass cache. Created fresh by each call to\n * `loadMcpServerDeclarations` integration so values don't go stale across\n * sessions but multiple recipes within one pass dedupe.\n */\nexport type RecipeResolutionCache = Map<string, string>;\n\nexport function createRecipeCache(): RecipeResolutionCache {\n return new Map();\n}\n\nconst DEFAULT_RECIPE_MAP_PATH = \"/etc/skaile/mcps-out-paths.json\";\n\n/** Resolves the prebuilt attr->storePath map file path (env override). */\nfunction recipeMapPath(): string {\n return process.env.SKAILE_NIX_RECIPE_MAP || DEFAULT_RECIPE_MAP_PATH;\n}\n\ninterface RecipeMapMemo {\n path: string;\n mtimeMs: number;\n map: Record<string, unknown> | null;\n}\n\nlet recipeMapMemo: RecipeMapMemo | null = null;\n\n/** Test-only: clears the (path, mtime) recipe-map memo so module-level state does not leak between cases. */\nexport function __resetRecipeMapMemoForTest(): void {\n recipeMapMemo = null;\n}\n\n/**\n * Loads the prebuilt attr->storePath map, memoized by (file path + mtime).\n * Re-reads when the file's mtime changes so a live restage of\n * `/etc/skaile/mcps-out-paths.json` is picked up without a process restart.\n * Returns null (and falls through to nix) when the file is missing or its\n * JSON is malformed; a malformed map warns once per distinct (path, mtime)\n * version — re-reading the same corrupt file is served from memo without\n * re-warning, but a later corrupt version (new mtime) warns again.\n */\nfunction loadRecipeMap(): Record<string, unknown> | null {\n const path = recipeMapPath();\n\n let mtimeMs: number;\n try {\n mtimeMs = statSync(path).mtimeMs;\n } catch {\n // File missing — memo the absence keyed to this path, fall through. We\n // intentionally re-stat on every call (the memo never short-circuits the\n // statSync above) so a map staged later is detected and picked up live.\n recipeMapMemo = { path, mtimeMs: -1, map: null };\n return null;\n }\n\n if (recipeMapMemo && recipeMapMemo.path === path && recipeMapMemo.mtimeMs === mtimeMs) {\n // Same version already seen (valid or malformed); do not re-warn.\n return recipeMapMemo.map;\n }\n\n let map: Record<string, unknown> | null = null;\n try {\n const parsed: unknown = JSON.parse(readFileSync(path, \"utf8\"));\n map = parsed && typeof parsed === \"object\" ? (parsed as Record<string, unknown>) : null;\n } catch (err) {\n // Reached only on a NEW (path, mtime) — the memo short-circuits an unchanged\n // version above, so a corrupt map warns once per distinct file version, and\n // a later valid->corrupt->fixed->corrupt sequence warns on each corrupt one.\n createLogger({ kind: \"mcp\", subkind: \"recipe-resolve\" }).warn(\n \"recipe map malformed — falling back to nix path-info\",\n { path, error: err instanceof Error ? err.message : String(err) },\n );\n map = null;\n }\n\n recipeMapMemo = { path, mtimeMs, map };\n return map;\n}\n\n/** A pluggable strategy mapping a flake/asset ref + attr to an absolute store path. */\nexport interface RecipeProducer {\n /**\n * Returns the resolved store path, or `null` to defer to the next producer.\n * A producer may instead THROW (e.g. `NixRecipeProducer` throws\n * `RecipeUnavailableError`) to signal a terminal failure — `resolveViaProducers`\n * does not catch mid-chain, so a throw skips any producers registered after it.\n * Put deferring producers (those that return `null` on a miss) BEFORE any\n * throwing producer in the chain.\n */\n resolve(ref: string, attr: string): string | null;\n readonly kind: string;\n}\n\n/** Content-addressed store-path map producer. Nix is one PRODUCER of this map,\n * not the only one. Generic; no nix knowledge. */\nexport class MapRecipeProducer implements RecipeProducer {\n readonly kind = \"map\";\n constructor(private readonly load: () => Record<string, unknown> | null = loadRecipeMap) {}\n resolve(_ref: string, attr: string): string | null {\n const map = this.load();\n if (!map) return null;\n const hit = attr\n .split(\".\")\n .reduce<unknown>(\n (o, k) => (o && typeof o === \"object\" ? (o as Record<string, unknown>)[k] : undefined),\n map,\n );\n return typeof hit === \"string\" && hit.startsWith(\"/nix/store/\") ? hit : null;\n }\n}\n\n/** Nix flake producer — locates/builds the closure via `nix path-info --offline`. */\nexport class NixRecipeProducer implements RecipeProducer {\n readonly kind = \"nix\";\n resolve(ref: string, attr: string): string | null {\n const result = spawnSync(\"nix\", [\"path-info\", \"--offline\", `${ref}#${attr}`], {\n encoding: \"utf8\",\n });\n if (result.error) throw new RecipeUnavailableError(ref, attr, result.error);\n if (result.status !== 0) {\n throw new RecipeUnavailableError(\n ref,\n attr,\n new Error(`nix path-info exited ${result.status}: ${result.stderr.trim()}`),\n );\n }\n const outPath = result.stdout.trim().split(\"\\n\")[0];\n if (!outPath?.startsWith(\"/nix/store/\")) {\n throw new RecipeUnavailableError(ref, attr, new Error(`Unexpected output: ${result.stdout}`));\n }\n return outPath;\n }\n}\n\n/** Default chain: content-addressed map first, then nix build. */\nexport function defaultRecipeProducers(): RecipeProducer[] {\n return [new MapRecipeProducer(), new NixRecipeProducer()];\n}\n\n/** Try each producer in order; cache the first non-null by `ref#attr`. */\nexport function resolveViaProducers(\n ref: string,\n attr: string,\n cache: RecipeResolutionCache,\n producers: RecipeProducer[] = defaultRecipeProducers(),\n): string {\n const key = `${ref}#${attr}`;\n const cached = cache.get(key);\n if (cached) return cached;\n\n // Validate attr before it reaches the nix spawnSync arg — defense-in-depth\n // for Phase 3+ community catalogs where attr may be untrusted.\n try {\n validateAssetRecipeAttr(attr);\n } catch (err) {\n throw new RecipeUnavailableError(\n ref,\n attr,\n err instanceof Error ? err : new Error(String(err)),\n );\n }\n\n const log = createLogger({ kind: \"mcp\", subkind: \"recipe-resolve\" });\n log.debug(\"resolving recipe\", { flakeRef: ref, attr });\n\n for (const producer of producers) {\n const out = producer.resolve(ref, attr);\n if (out) {\n cache.set(key, out);\n log.info(\"resolved recipe\", { flakeRef: ref, attr, outPath: out, producer: producer.kind });\n return out;\n }\n }\n throw new RecipeUnavailableError(ref, attr, new Error(\"no producer resolved the recipe\"));\n}\n\n/**\n * Resolves a flake attribute to its /nix/store out-path.\n * Throws RecipeUnavailableError on missing closure / nix failure.\n *\n * Thin back-compat wrapper over the default producer chain (map → nix).\n */\nexport function resolveRecipePath(\n flakeRef: string,\n attr: string,\n cache: RecipeResolutionCache,\n): string {\n return resolveViaProducers(flakeRef, attr, cache);\n}\n","/**\n * Substitutes `${recipe:<id>}`, `${recipe:<id>:<sub>}`, `${recipe:<id>:bin}`,\n * and `${recipe:<id>:lib}` markers with absolute /nix/store paths.\n *\n * Matching rules:\n * ${recipe:excel} -> /nix/store/.../bin\n * ${recipe:excel:bin} -> /nix/store/.../bin\n * ${recipe:excel:lib} -> /nix/store/.../lib\n * ${recipe:excel:share} -> /nix/store/.../share (any sub path)\n *\n * The bare ${recipe:<id>} form is treated as `${recipe:<id>:bin}` for\n * ergonomic command-line use; explicit subpaths win.\n */\nimport { existsSync } from \"node:fs\";\n\n// Case-sensitive by design: markers must be lowercase to match the declaration\n// id map keys. Uppercase markers survive as literal text and are caught by the\n// unresolved-marker scan in resources.ts, which skips the declaration cleanly.\nconst RECIPE_MARKER = /\\$\\{recipe:([a-z0-9_-]+)(?::([a-z0-9_/.-]+))?\\}/g;\n\nexport function substituteRecipeTemplating(\n value: string,\n recipeOutPaths: ReadonlyMap<string, string>,\n): string {\n return value.replace(RECIPE_MARKER, (_match, id: string, sub: string | undefined) => {\n const outPath = recipeOutPaths.get(id);\n if (!outPath) {\n // Leave the marker in place so the caller can decide policy. The\n // wiring layer surfaces unresolved markers as a structured error\n // before subprocess spawn.\n return _match;\n }\n if (!sub) return `${outPath}/bin`;\n return `${outPath}/${sub}`;\n });\n}\n\nexport function substituteRecipeMap(\n obj: Record<string, string> | undefined,\n recipeOutPaths: ReadonlyMap<string, string>,\n): Record<string, string> | undefined {\n if (!obj) return obj;\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(obj)) {\n out[k] = substituteRecipeTemplating(v, recipeOutPaths);\n }\n return out;\n}\n\n// `${workspace}` resolves to the session workspace root (the dir holding\n// `.skaile/`). Applied to ALL MCP declarations (recipe and command-shape alike),\n// unlike `${recipe:…}` which only applies to recipe-launcher decls.\nconst WORKSPACE_MARKER = /\\$\\{workspace\\}/g;\n\nexport function substituteWorkspaceToken(value: string, workspaceDir: string): string {\n return value.replace(WORKSPACE_MARKER, workspaceDir);\n}\n\nexport function substituteWorkspaceTokenMap(\n obj: Record<string, string> | undefined,\n workspaceDir: string,\n): Record<string, string> | undefined {\n if (!obj) return obj;\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(obj)) {\n out[k] = substituteWorkspaceToken(v, workspaceDir);\n }\n return out;\n}\n\nexport interface MissingSubstitutedPath {\n field: string;\n path: string;\n error: string;\n}\n\n/**\n * Checks that the resolved binary path (command and args[0]) produced by\n * recipe substitution actually exists on the filesystem.\n *\n * Only checks `command` and `args[0]` — these are the fields where ENOENT\n * is most user-visible (subprocess spawn fails immediately). Other args and\n * env values are not checked to keep this focused.\n *\n * Returns an array of missing-path entries; an empty array means all checks\n * passed. The caller in resources.ts skips the declaration when non-empty.\n */\nexport function validateSubstitutedPaths(\n command: string | undefined,\n args: string[] | undefined,\n): MissingSubstitutedPath[] {\n const missing: MissingSubstitutedPath[] = [];\n\n if (command?.startsWith(\"/nix/store/\") && !existsSync(command)) {\n missing.push({\n field: \"command\",\n path: command,\n error: `resolved path does not exist: ${command}`,\n });\n }\n\n const firstArg = args?.[0];\n if (firstArg?.startsWith(\"/nix/store/\") && !existsSync(firstArg)) {\n missing.push({\n field: \"args[0]\",\n path: firstArg,\n error: `resolved path does not exist: ${firstArg}`,\n });\n }\n\n return missing;\n}\n","/**\n * external-mcp.ts\n *\n * Runner-managed external MCP servers (stdio first; sse/http too).\n *\n * Historically external MCP servers declared in `skaile.yaml` (`mcp_servers:`,\n * including recipe-backed ones like excel / ppt) were handed to the claude-sdk\n * driver as `{type:\"stdio\"}` entries on the SDK's `mcpServers` query option, so\n * the **SDK** owned spawning the subprocess. That coupled external MCP support\n * to one driver (only claude-sdk consumes `mcpServers`) and to the\n * claude-agent-sdk version (external stdio servers via the query option require\n * the 0.3.x line).\n *\n * This module moves spawning + connection into the RUNNER: it spawns the MCP\n * subprocess itself via `@modelcontextprotocol/sdk`'s {@link Client} +\n * transport, runs `initialize` + `tools/list`, and registers each tool into the\n * v2 {@link CapabilityRegistry} as an `mcp`-origin capability named\n * `mcp__<server>__<tool>`. Invocations dispatch through the normal capability\n * path, so every driver (claude-sdk, omp, codex) reaches the tools through the\n * single surface they already consume — no dependence on the claude-agent-sdk\n * `mcpServers` option.\n *\n * Static imports only: the runner ships as `bun build --compile`, which cannot\n * follow dynamic imports. See `bridge/CLAUDE.md` § \"Static-import-or-die\".\n *\n * @docLink packages/runner/capabilities#runner-managed-external-mcp\n */\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { SSEClientTransport } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport {\n getDefaultEnvironment,\n StdioClientTransport,\n} from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport { loadMcpServerDeclarations, type McpServerDeclaration } from \"@skaile/workspaces/core\";\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\nimport type { ZodTypeAny } from \"zod\";\nimport type { CapabilityRegistry } from \"./capability-registry.js\";\nimport type { DefinedCapability } from \"./define-capability.js\";\nimport { createRecipeCache, resolveRecipePath } from \"./recipe-resolver.js\";\nimport {\n substituteRecipeMap,\n substituteRecipeTemplating,\n substituteWorkspaceToken,\n substituteWorkspaceTokenMap,\n validateSubstitutedPaths,\n} from \"./recipe-templating.js\";\n\n// ---------------------------------------------------------------------------\n// Typed error for duplicate MCP server registration\n// ---------------------------------------------------------------------------\n\n/** Thrown by {@link ExternalMcpManager.addServer} when the id is already registered. */\nexport class McpServerAlreadyRegisteredError extends Error {\n constructor(public readonly id: string) {\n super(`MCP server '${id}' is already registered`);\n this.name = \"McpServerAlreadyRegisteredError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Secret resolution (shared with resources.ts' legacy SDK-delegation path)\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal interface for secret resolution — avoids a hard import of\n * `@skaile/workspaces/connectors` just for the SecretProvider type.\n */\nexport interface SecretProviderLike {\n resolve(ref: string): string | undefined;\n}\n\n/**\n * Resolve secret references (`env:VAR`, `forge:KEY`, etc.) in a string-keyed\n * record. Returns a new record with resolved values; entries that fail to\n * resolve are passed through unchanged.\n */\nexport function resolveRecordSecrets(\n record: Record<string, string>,\n secrets: SecretProviderLike | undefined,\n): Record<string, string> {\n if (!secrets) return record;\n const resolved: Record<string, string> = {};\n for (const [k, v] of Object.entries(record)) {\n resolved[k] = secrets.resolve(v) ?? v;\n }\n return resolved;\n}\n\n// ---------------------------------------------------------------------------\n// Declaration resolution (recipe substitution → ready-to-spawn declarations)\n// ---------------------------------------------------------------------------\n\n/** IDs reserved for built-in MCP servers. Declarative servers must not shadow these. */\nconst RESERVED_MCP_SERVER_IDS = new Set([\n \"skaile-connectors\",\n \"skaile-workspace\",\n \"skaile-capabilities\",\n]);\n\n/**\n * Load the declarative MCP servers from `skaile.yaml` and resolve any\n * `recipe:` bindings into absolute `/nix/store` paths, substituting\n * `${recipe:<id>...}` markers in `command`, `args`, and `env`.\n *\n * Mirrors the resilience of the original wiring: a single broken declaration\n * (reserved id, recipe resolution failure, unresolved/invalid substituted\n * path) is logged and dropped — it never aborts the caller. Secret references\n * in `env` / `headers` are NOT resolved here; the spawn path resolves them at\n * transport-construction time so resolved secrets never sit in the returned\n * declaration objects.\n *\n * @returns The recipe-substituted declarations ready for spawn (or SDK\n * delegation in the legacy fallback path).\n */\nexport function resolveExternalMcpDeclarations(\n projectDir: string,\n sessionId?: string,\n): McpServerDeclaration[] {\n const mcpLog = createLogger({\n kind: \"mcp\",\n subkind: \"wiring\",\n instance: sessionId ?? \"no-session\",\n });\n\n const mcpDeclarations = loadMcpServerDeclarations(projectDir);\n mcpLog.debug(\"loaded MCP declarations\", { count: mcpDeclarations.length });\n\n // One cache per pass — dedupes nix path-info shell-outs for multiple\n // declarations that share the same flake attr.\n const recipeCache = createRecipeCache();\n const nixFlakeRef = process.env.SKAILE_NIX_FLAKE_REF ?? \"/etc/skaile/flake\";\n\n const resolved: McpServerDeclaration[] = [];\n\n for (const decl of mcpDeclarations) {\n if (RESERVED_MCP_SERVER_IDS.has(decl.id)) {\n mcpLog.warn(\"MCP server skipped: reserved id\", { id: decl.id });\n continue;\n }\n\n // An explicit launcher wins over a stale `recipe:` binding: `package-runner`\n // / `path` always pass through as command-shapes, even if a leftover\n // `recipe:` block is present. Only `launcher: recipe` (or an unset launcher\n // with a recipe binding — the back-compat default) triggers resolution.\n const wantsRecipe =\n decl.launcher === \"recipe\" || (decl.launcher == null && decl.recipe != null);\n if (!wantsRecipe) {\n resolved.push(decl); // package-runner / path / remote: command-shape pass-through\n continue;\n }\n if (!decl.recipe) {\n mcpLog.warn(\"MCP server skipped: launcher 'recipe' without a recipe binding\", {\n id: decl.id,\n });\n continue;\n }\n\n const resolvedDecl = resolveRecipeDeclaration(decl, nixFlakeRef, recipeCache);\n // `undefined` signals a logged skip (reserved-id-style \"drop and continue\").\n if (resolvedDecl) resolved.push(resolvedDecl);\n }\n\n // `${workspace}` → workspace root, applied to EVERY decl's command/args/env\n // (recipe + command-shape alike). url/headers are remote-transport config,\n // intentionally excluded.\n return resolved.map((decl) => ({\n ...decl,\n command: decl.command ? substituteWorkspaceToken(decl.command, projectDir) : decl.command,\n args: decl.args?.map((a) => substituteWorkspaceToken(a, projectDir)),\n env: substituteWorkspaceTokenMap(decl.env, projectDir),\n }));\n}\n\n/**\n * Resolve one declaration's `recipe:` binding into absolute `/nix/store` paths,\n * substituting `${recipe:<id>...}` markers in `command`, `args`, and `env`.\n *\n * Returns the substituted declaration, or `undefined` when the declaration must\n * be dropped — a substituted path that does not exist, or any thrown error\n * during resolution. The drop is logged here (mirroring the original inline\n * behavior) so the caller can simply skip a `undefined` result.\n *\n * Pre: `decl.recipe` is defined.\n */\nfunction resolveRecipeDeclaration(\n decl: McpServerDeclaration,\n nixFlakeRef: string,\n recipeCache: ReturnType<typeof createRecipeCache>,\n): McpServerDeclaration | undefined {\n // biome-ignore lint/style/noNonNullAssertion: caller guarantees decl.recipe is defined.\n const recipe = decl.recipe!;\n // For BYO-flake recipes `attr` is the in-flake target (\"default\") and may\n // be absent; `flake` is the meaningful log key. Hoisted above the try so\n // the catch can log it too.\n const recipeLogKey = recipe.flake ? { flake: recipe.flake } : { attr: recipe.attr };\n const recipeLog = createLogger({ kind: \"mcp\", subkind: decl.id, instance: \"recipe-resolve\" });\n try {\n // Legacy platform-flake recipes resolve by their `attr` (e.g.\n // `mcps.excel`); BYO-flake recipes all build `#default`, so resolve by\n // `mcps.<id>` — the key the host-side builder writes into the map.\n const recipeKey = recipe.flake ? `mcps.${decl.id}` : (recipe.attr ?? `mcps.${decl.id}`);\n const outPath = resolveRecipePath(nixFlakeRef, recipeKey, recipeCache);\n const outPaths: ReadonlyMap<string, string> = new Map([[decl.id, outPath]]);\n\n const resolvedCommand = decl.command\n ? substituteRecipeTemplating(decl.command, outPaths)\n : decl.command;\n const resolvedArgs = decl.args?.map((a) => substituteRecipeTemplating(a, outPaths));\n const resolvedEnv = substituteRecipeMap(decl.env, outPaths);\n\n const resolvedDecl: McpServerDeclaration = {\n ...decl,\n command: resolvedCommand,\n args: resolvedArgs,\n env: resolvedEnv,\n };\n\n warnUnresolvedRecipeMarkers(recipeLog, decl.id, resolvedCommand, resolvedArgs, resolvedEnv);\n\n // Verify substituted /nix/store paths exist (catches recipes without bin/).\n const missingPaths = validateSubstitutedPaths(resolvedCommand, resolvedArgs);\n if (missingPaths.length > 0) {\n recipeLog.error(\"MCP server skipped: substituted path does not exist\", undefined, {\n id: decl.id,\n ...recipeLogKey,\n missing: missingPaths,\n });\n return undefined;\n }\n\n recipeLog.info(\"recipe substitution complete\", { ...recipeLogKey, outPath });\n return resolvedDecl;\n } catch (err) {\n // Catch ALL errors — a single broken declaration cannot abort resolution\n // for the whole session. Log the full error and skip this declaration.\n recipeLog.error(\"MCP server skipped: recipe resolution failed\", err, {\n id: decl.id,\n ...recipeLogKey,\n flakeRef: nixFlakeRef,\n });\n return undefined;\n }\n}\n\n/** Warn on any `${recipe:...}` markers that survived substitution (id mismatch). */\nfunction warnUnresolvedRecipeMarkers(\n recipeLog: ReturnType<typeof createLogger>,\n declId: string,\n resolvedCommand: string | undefined,\n resolvedArgs: string[] | undefined,\n resolvedEnv: Record<string, string> | undefined,\n): void {\n const allResolved = [\n resolvedCommand ?? \"\",\n ...(resolvedArgs ?? []),\n ...Object.values(resolvedEnv ?? {}),\n ];\n for (const v of allResolved) {\n if (v.includes(\"${recipe:\")) {\n recipeLog.warn(\"unresolved recipe marker after substitution\", {\n value: v,\n declId,\n });\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Runner-managed spawn + capability registration\n// ---------------------------------------------------------------------------\n\n// Passthrough sentinel (mirrors capability-registry's HYDRATED_PASSTHROUGH_ZOD):\n// MCP tools advertise their own JSON Schema, registered verbatim as the wire\n// `inputSchema`; the MCP server does the real validation. Avoids a runtime zod dep.\nconst PASSTHROUGH_INPUT_ZOD: ZodTypeAny = {\n parse: (v: unknown) => v,\n} as unknown as ZodTypeAny;\n\n/** A single tool advertised by an MCP server's `tools/list`. */\nexport interface McpToolDescriptor {\n name: string;\n description?: string;\n inputSchema?: unknown;\n}\n\n/**\n * Minimal MCP client surface the manager depends on. The real\n * `@modelcontextprotocol/sdk` {@link Client} satisfies this structurally; tests\n * inject a fake via the {@link ExternalMcpManager} constructor's `connect`\n * argument so they need no live subprocess and run under both Bun and Node.\n */\nexport interface McpClientLike {\n listTools(): Promise<{ tools: McpToolDescriptor[] }>;\n callTool(params: {\n name: string;\n arguments?: Record<string, unknown>;\n }): Promise<{ content?: Array<{ type?: string; text?: string }>; isError?: boolean }>;\n close(): Promise<void>;\n}\n\n/** Connects (spawns/handshakes) the MCP client for one declaration. */\nexport type McpClientConnector = (decl: McpServerDeclaration) => Promise<McpClientLike>;\n\n/**\n * Re-mints the backend-issued bearer for one `auth: backend` MCP server and\n * rewrites its provisioned `MCP__<id>__AUTH` secret in place. Returns `true`\n * when a fresh token was provisioned (the manager then rebuilds the transport\n * and reconnects), `false` when re-mint was impossible (the manager gives up\n * and propagates the original 401). Injected by the runner; absent in CLI mode.\n */\nexport type McpReauthorizer = (decl: McpServerDeclaration) => Promise<boolean>;\n\n/**\n * True when an MCP **transport** error looks like an auth rejection. Remote\n * transports surface a 401 either as a `code: 401` (or `status: 401`) on the\n * thrown error or as a message carrying the HTTP `401` / a `WWW-Authenticate`\n * OAuth error code (`invalid_token` / `invalid_grant`). The bare word\n * \"unauthorized\" is intentionally NOT matched on its own — a tool's\n * business-logic error (\"user unauthorized to access document\") must not\n * trigger a pointless re-mint; real transport 401s carry the numeric status.\n */\nexport function isMcpAuthError(err: unknown): boolean {\n if (!err || typeof err !== \"object\") return false;\n const code =\n (err as { code?: unknown; status?: unknown }).code ?? (err as { status?: unknown }).status;\n if (code === 401 || code === \"401\") return true;\n const message = (err as { message?: unknown }).message;\n if (typeof message !== \"string\") return false;\n return /\\b401\\b|invalid[_ ]token|invalid[_ ]grant/i.test(message);\n}\n\n/** Normalize an unknown thrown value to a log-safe message string. */\nfunction errMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/**\n * Build the transport for a declaration. For stdio the subprocess env is a safe\n * base (`getDefaultEnvironment()` — PATH/HOME/TMPDIR) merged under the asset's\n * declared env: the SDK's StdioClientTransport uses ONLY the passed env when\n * set, so without the base the child loses PATH. See the 2026-06-04 devlog note.\n */\nfunction buildTransport(\n decl: McpServerDeclaration,\n secrets: SecretProviderLike | undefined,\n): Transport {\n const transport = decl.transport ?? \"stdio\";\n\n if (transport === \"stdio\") {\n if (!decl.command) {\n throw new Error(`stdio MCP server '${decl.id}' is missing 'command'`);\n }\n const env = {\n ...getDefaultEnvironment(),\n ...resolveRecordSecrets(decl.env ?? {}, secrets),\n };\n return new StdioClientTransport({\n command: decl.command,\n args: decl.args ?? [],\n env,\n stderr: \"pipe\",\n });\n }\n\n if (transport === \"sse\") {\n if (!decl.url) throw new Error(`sse MCP server '${decl.id}' is missing 'url'`);\n const headers = resolveRecordSecrets(decl.headers ?? {}, secrets);\n return new SSEClientTransport(new URL(decl.url), { requestInit: { headers } });\n }\n\n if (transport === \"http\") {\n if (!decl.url) throw new Error(`http MCP server '${decl.id}' is missing 'url'`);\n const headers = resolveRecordSecrets(decl.headers ?? {}, secrets);\n return new StreamableHTTPClientTransport(new URL(decl.url), { requestInit: { headers } });\n }\n\n throw new Error(`Unknown MCP transport '${transport}' for server '${decl.id}'`);\n}\n\n/**\n * Default connector: build the transport, construct the real SDK {@link Client},\n * and connect it (which spawns the stdio subprocess and runs `initialize`).\n */\nfunction defaultMcpClientConnector(secrets: SecretProviderLike | undefined): McpClientConnector {\n return async (decl) => {\n const transport = buildTransport(decl, secrets);\n const client = new Client({ name: \"skaile-runner\", version: \"1.0.0\" }, { capabilities: {} });\n await client.connect(transport);\n return client as unknown as McpClientLike;\n };\n}\n\ninterface RunningMcpServer {\n id: string;\n /** The declaration — needed to rebuild the transport on a 401 reconnect. */\n decl: McpServerDeclaration;\n /** Live client. Swapped in place by a 401 reconnect; tool handlers read it lazily. */\n client: McpClientLike;\n /** Capability names registered for this server — deregistered on dispose. */\n toolNames: string[];\n /** In-flight re-mint+reconnect, shared by concurrent 401s for this server. */\n reauthInFlight?: Promise<boolean>;\n}\n\n/**\n * Spawns and owns the lifecycle of every external MCP server for a session,\n * registering each server's tools into the {@link CapabilityRegistry}.\n *\n * One instance per session (one per `buildAgentResources` pass). Spawn after\n * recipe resolution; the subprocesses stay alive for the session and are killed\n * by {@link dispose} at session end. A spawn / connect failure for one server is\n * logged and skipped — it never aborts session startup (mirrors the\n * recipe-resolution \"drop the server, continue\" behavior).\n *\n * @category Runtime\n * @since 3.5.0\n */\nexport class ExternalMcpManager {\n private readonly servers: RunningMcpServer[] = [];\n private readonly log;\n private readonly connect: McpClientConnector;\n private readonly reauthorize?: McpReauthorizer;\n\n /**\n * @param registry Session capability registry to register MCP tools into.\n * @param secrets Secret provider for resolving `env:` / `forge:` refs in the\n * stdio subprocess env and sse/http headers.\n * @param sessionId Used for the logger instance slice.\n * @param connect Optional connector override (tests inject a fake client so\n * no live subprocess is spawned). Defaults to the real SDK\n * client + transport.\n * @param reauthorize Optional re-mint callback for `auth: backend` remote\n * servers. When present, a 401 from a tool call (or the\n * initial connect) triggers a re-mint + reconnect.\n */\n constructor(\n private readonly registry: CapabilityRegistry,\n secrets: SecretProviderLike | undefined,\n sessionId?: string,\n connect?: McpClientConnector,\n reauthorize?: McpReauthorizer,\n ) {\n this.connect = connect ?? defaultMcpClientConnector(secrets);\n this.reauthorize = reauthorize;\n this.log = createLogger({\n kind: \"mcp\",\n subkind: \"runner-managed\",\n instance: sessionId ?? \"no-session\",\n });\n }\n\n /** True when at least one external server connected and registered tools. */\n hasServers(): boolean {\n return this.servers.length > 0;\n }\n\n /**\n * Connect every declaration and register its tools. Per-server failures are\n * logged and skipped so a single bad server never blocks the session.\n */\n async start(declarations: McpServerDeclaration[]): Promise<void> {\n for (const decl of declarations) {\n try {\n await this.addServer(decl);\n } catch (err) {\n // Never abort the session on a single broken server.\n this.log.error(\"MCP server spawn failed; skipping\", err, {\n id: decl.id,\n transport: decl.transport ?? \"stdio\",\n });\n }\n }\n }\n\n /**\n * Connect one MCP server and register its tools into the capability registry.\n * Returns the server id and the registered tool capability names.\n * Throws if the id is already registered or if connect/listTools fails.\n */\n async addServer(decl: McpServerDeclaration): Promise<{ id: string; toolNames: string[] }> {\n if (this.servers.some((s) => s.id === decl.id)) {\n throw new McpServerAlreadyRegisteredError(decl.id);\n }\n\n const client = await this.connectWithReauth(decl);\n\n // Register the server record first so tool handlers read the LIVE client\n // (a 401 reconnect swaps server.client under the same capability).\n const server: RunningMcpServer = { id: decl.id, decl, client, toolNames: [] };\n const toolNames: string[] = [];\n try {\n const { tools } = await client.listTools();\n for (const tool of tools) {\n const cap = this.buildToolCapability(server, tool);\n this.registry.register(cap, \"agent\");\n toolNames.push(cap.name);\n }\n } catch (err) {\n // Connected but failed to enumerate/register — roll back any tools already\n // registered (they aren't tracked in `this.servers`, so dispose can't reach\n // them) and close the client so we don't leak the subprocess.\n for (const name of toolNames) this.registry.deregister(name);\n try {\n await client.close();\n } catch {\n /* best-effort */\n }\n throw err;\n }\n\n server.toolNames = toolNames;\n this.servers.push(server);\n this.log.info(\"MCP server registered (runner-managed)\", {\n id: decl.id,\n transport: decl.transport ?? \"stdio\",\n toolCount: toolNames.length,\n tools: toolNames,\n });\n\n return { id: decl.id, toolNames };\n }\n\n /**\n * Deregister a running MCP server's tools and close its client.\n * No-op when the id is not found.\n *\n * Drains any in-flight reauth first: a doReauthAndReconnect resolving after\n * splice would swap server.client to a freshly-connected client that nothing\n * then closes, leaking the transport/subprocess.\n */\n async removeServer(id: string): Promise<void> {\n const idx = this.servers.findIndex((s) => s.id === id);\n if (idx === -1) return;\n const server = this.servers[idx];\n // Drain the in-flight reauth before deregistering so we close the LATEST client.\n if (server.reauthInFlight) await server.reauthInFlight.catch(() => {});\n this.servers.splice(idx, 1);\n for (const name of server.toolNames) {\n this.registry.deregister(name);\n }\n try {\n await server.client.close();\n } catch {\n /* best-effort — close errors must not surface to the caller */\n }\n this.log.info(\"MCP server removed (runner-managed)\", { id });\n }\n\n /** Summary of every currently-connected MCP server. */\n listServers(): Array<{ id: string; transport: \"stdio\" | \"sse\" | \"http\"; toolCount: number }> {\n return this.servers.map((s) => ({\n id: s.id,\n transport: (s.decl.transport ?? \"stdio\") as \"stdio\" | \"sse\" | \"http\",\n toolCount: s.toolNames.length,\n }));\n }\n\n /**\n * Connect, re-minting once on an initial-connect 401: the provisioned bearer\n * may already be stale by the time the server is reached. Only retries for\n * `auth: backend` servers with a reauthorizer wired.\n */\n private async connectWithReauth(decl: McpServerDeclaration): Promise<McpClientLike> {\n try {\n return await this.connect(decl);\n } catch (err) {\n if (isMcpAuthError(err) && this.reauthorize && decl.auth === \"backend\") {\n this.log.warn(\"MCP initial connect 401 — re-minting and retrying\", { id: decl.id });\n if (await this.reauthorize(decl)) {\n return this.connect(decl);\n }\n }\n throw err;\n }\n }\n\n /**\n * Re-mint the bearer and reconnect one server in place after a 401. Concurrent\n * 401s for the same server share a single round-trip via `reauthInFlight`.\n * Returns `true` once `server.client` points at a freshly-authed connection.\n */\n private reauthAndReconnect(server: RunningMcpServer): Promise<boolean> {\n server.reauthInFlight ??= this.doReauthAndReconnect(server).finally(() => {\n server.reauthInFlight = undefined;\n });\n return server.reauthInFlight;\n }\n\n private async doReauthAndReconnect(server: RunningMcpServer): Promise<boolean> {\n if (!this.reauthorize || server.decl.auth !== \"backend\") return false;\n let provisioned: boolean;\n try {\n provisioned = await this.reauthorize(server.decl);\n } catch (err) {\n this.log.warn(\"MCP re-mint failed after 401\", { id: server.id, error: errMessage(err) });\n return false;\n }\n if (!provisioned) return false;\n\n // The dead bearer is baked into the old transport's headers — only a fresh\n // client (rebuilt transport) picks up the rewritten MCP__<id>__AUTH secret.\n let next: McpClientLike;\n try {\n next = await this.connect(server.decl);\n await next.listTools(); // confirm the fresh token actually authenticates\n } catch (err) {\n this.log.warn(\"MCP reconnect after 401 failed\", { id: server.id, error: errMessage(err) });\n return false;\n }\n const old = server.client;\n server.client = next;\n try {\n await old.close();\n } catch {\n /* best-effort — the old transport is being discarded */\n }\n this.log.info(\"MCP server reconnected after 401 re-mint\", { id: server.id });\n return true;\n }\n\n /**\n * Wrap a single MCP tool as a {@link DefinedCapability}. The capability name\n * is `mcp__<server>__<tool>` (the naming claude-sdk wildcards and prompts\n * depend on). The handler proxies the call to the server's LIVE client (read\n * lazily so a 401 reconnect is transparent); a tool error (`isError`) is\n * rethrown so the capability dispatch path surfaces it to the LLM, and a 401\n * triggers a re-mint + reconnect followed by a single retry.\n */\n private buildToolCapability(\n server: RunningMcpServer,\n tool: McpToolDescriptor,\n ): DefinedCapability {\n const serverId = server.id;\n const name = `mcp__${serverId}__${tool.name}`;\n const inputSchema =\n tool.inputSchema && typeof tool.inputSchema === \"object\"\n ? (tool.inputSchema as Record<string, unknown>)\n : { type: \"object\" };\n\n return {\n name,\n description: tool.description ?? `MCP tool ${tool.name} from server ${serverId}`,\n inputSchema,\n side: \"agent\",\n origin: { kind: \"mcp\", serverId },\n scope: \"session\",\n kind: \"effect\",\n // LLM-only — these are agent tools, not user command-palette actions.\n audience: [\"llm\"],\n inputZod: PASSTHROUGH_INPUT_ZOD,\n handler: async (input, ctx) => {\n const call = { name: tool.name, arguments: (input ?? {}) as Record<string, unknown> };\n let result: { content?: Array<{ type?: string; text?: string }>; isError?: boolean };\n try {\n result = (await server.client.callTool(call)) as typeof result;\n } catch (err) {\n // A 401 mid-session means the provisioned bearer expired/was revoked.\n // Re-mint + reconnect once, then retry on the fresh client.\n if (isMcpAuthError(err) && (await this.reauthAndReconnect(server))) {\n ctx.log.info(\"mcp tool retried after 401 re-mint\", { tool: name });\n result = (await server.client.callTool(call)) as typeof result;\n } else {\n throw err;\n }\n }\n\n const content = result.content ?? [];\n const text = content\n .filter((c) => c.type === \"text\" && typeof c.text === \"string\")\n .map((c) => c.text)\n .join(\"\\n\");\n\n if (result.isError) {\n throw new Error(text || `MCP tool ${name} returned an error`);\n }\n\n ctx.log.debug(\"mcp tool ok\", { tool: name, hasText: text.length > 0 });\n // Prefer the concatenated text payload; fall back to the structured\n // content array for non-text results (images, resources, etc.).\n return text.length > 0 ? text : content;\n },\n };\n }\n\n /**\n * Deregister every tool and close every client (kills the subprocesses).\n * Best-effort: a failed close on one server does not prevent the rest.\n *\n * Drains any in-flight 401 reconnect first: a `doReauthAndReconnect` resolving\n * after teardown would set `server.client` to a freshly-connected client that\n * nothing then closes (leak). Awaiting `reauthInFlight` guarantees we close the\n * LATEST client.\n */\n async dispose(): Promise<void> {\n await Promise.allSettled(this.servers.map((s) => s.reauthInFlight).filter(Boolean));\n for (const server of this.servers) {\n for (const toolName of server.toolNames) {\n this.registry.deregister(toolName);\n }\n try {\n await server.client.close();\n } catch (err) {\n this.log.warn(\"MCP server close failed\", {\n id: server.id,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n this.servers.length = 0;\n }\n}\n","/** Build a `## MCP server guidance` system-prompt section from MCP declarations\n * that carry preset custom instructions (the materialized MCP.md body). Returns\n * \"\" when no declaration has instructions, so an empty body adds nothing. */\nexport function buildMcpPromptSection(\n declarations: { id: string; instructions?: string }[],\n): string {\n const withGuidance = declarations.filter(\n (d): d is { id: string; instructions: string } =>\n !!d.instructions && d.instructions.trim().length > 0,\n );\n if (withGuidance.length === 0) return \"\";\n const lines: string[] = [\"## MCP server guidance\", \"\"];\n for (const d of withGuidance) {\n lines.push(`Guidance for \\`${d.id}\\`:`);\n lines.push(d.instructions.trim());\n lines.push(\"\");\n }\n return lines.join(\"\\n\").trimEnd();\n}\n","/**\n * resources.ts\n *\n * Shared connector lifecycle for agent sessions — connect, watch, and build\n * tool injection for all connector types (filesystem-face and tool-face).\n *\n * Used by agent.ts (REPL), factory-assets/connectors/flow/run-flow.ts (flow), and serve.ts (WebSocket server).\n * Extracted from duplicated inline blocks in each of those files.\n */\n\nimport {\n buildConnectorPromptSection,\n buildSdkConnectorTools,\n type ConnectorChangeEvent,\n ConnectorManager,\n ConnectorStartupError,\n findMissingPackages,\n installNpmPackages,\n loadConnectorDeclarations,\n type PreMintedSecretProvider,\n registerBuiltinConnectors,\n type SecretProvider,\n SecretProviderChain,\n type SyncStatusPayload,\n type TokenMediator,\n} from \"@skaile/workspaces/connectors\";\nimport {\n type McpServerDeclaration,\n type RuntimeAssetsResult,\n resolveRuntimeAssets,\n} from \"@skaile/workspaces/core\";\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\nimport type { ConnectorStatusEvent } from \"@skaile/workspaces/types\";\nimport { WorkspacePlugin } from \"@skaile/workspaces/workspace-plugin\";\nimport { z } from \"zod\";\nimport type { CapabilityRegistry } from \"./capability-registry.js\";\nimport { FileChangedCoalescer } from \"./file-changed-coalescer.js\";\nimport {\n ExternalMcpManager,\n type McpReauthorizer,\n resolveExternalMcpDeclarations,\n resolveRecordSecrets,\n type SecretProviderLike,\n} from \"./external-mcp.js\";\nimport { buildMcpPromptSection } from \"./mcp-prompt.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Result of {@link buildAgentResources}.\n *\n * @docLink packages/runner/dev-guide#flow-execution-turn-based-model\n */\nexport interface AgentResourcesResult {\n /** Connected ConnectorManager instance — null if no connectors declared or package missing. */\n resourceManager: any | null;\n /** Markdown section to append to the system prompt — empty string if no resources. */\n resourcePromptSection: string;\n /**\n * In-process MCP server map to pass as `mcpServers` in `AgentConfig`.\n * Populated only for the `claude-sdk` driver; undefined for all others.\n */\n mcpServers: Record<string, unknown> | undefined;\n /**\n * Resolved runtime assets — catalog entries, implicit refs, npm deps, warnings.\n * Held by the session so live-update paths (add_resource, configure)\n * can call `runtimeAssets.refresh()` and consume the same shared view.\n * `null` only when @skaile/workspaces/connectors or skaile.yaml parsing failed.\n */\n runtimeAssets: RuntimeAssetsResult | null;\n /** Disconnect all connectors, unmount all mounts, and stop watchers. */\n dispose: () => Promise<void>;\n /**\n * Start filesystem and connector watchers. Call AFTER the transport is\n * listening — watching can be slow on large directory trees and must not\n * block session startup.\n */\n startWatching: () => void;\n /**\n * Lazily construct (once) and return the session's external MCP manager —\n * the live target for `runner.add_mcp_server`. Reassigns the same local that\n * `dispose()` reads, so a runtime-created manager is torn down on teardown.\n * Serve mode only (requires a capability registry); throws otherwise.\n */\n getOrCreateExternalMcpManager: () => ExternalMcpManager;\n /** The external MCP manager if constructed (boot or lazy), else null. */\n getExternalMcpManager: () => ExternalMcpManager | null;\n /**\n * Markdown section for the agent system prompt with per-server guidance\n * built from the materialized MCP.md bodies. Empty string when no server\n * has preset custom instructions.\n */\n mcpPromptSection: string;\n}\n\n/**\n * Callback hooks for filesystem and connector lifecycle events.\n *\n * @docLink packages/runner/dev-guide#flow-execution-turn-based-model\n */\nexport interface ResourceWatchCallbacks {\n /**\n * Called by mountable adapters to report incremental sync progress.\n * Used by serve.ts to forward sync_status events to the frontend.\n */\n onSyncStatus?: (connectorId: string, status: SyncStatusPayload) => void;\n /**\n * Called when a watched connector detects an in-process change.\n * Used by serve.ts to forward file_changed events to the frontend.\n * Change events are deduplicated within `dedupTtlMs` per path.\n */\n onFileChanged?: (connectorId: string, event: ConnectorChangeEvent) => void;\n /** Dedup window for file_changed events in milliseconds. Default: 500. */\n dedupTtlMs?: number;\n /**\n * Called whenever a connector's connection state changes\n * (`connecting` → `connected` | `error`, plus `disconnected`). Used by\n * serve.ts to forward `connector_status` events to the platform — the\n * channel deferred (background) filesystem mounts report progress through.\n */\n onConnectorStatus?: (event: ConnectorStatusEvent) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Set up all connectors declared in `skaile.yaml` for an agent session.\n *\n * Steps:\n * 1. Register built-in connectors\n * 2. Load connector declarations from skaile.yaml\n * 3. Connect all connectors via ConnectorManager (filesystem + tool faces)\n * 4. Optionally start filesystem/connector watchers (serve.ts use case)\n * 5. Build the system prompt section (mount paths + connector tools)\n * 6. Build in-process MCP server (claude-sdk only)\n *\n * @param projectDir Workspace root — where skaile.yaml lives\n * @param driverType Active bridge driver ID: \"omp\" | \"claude-sdk\"\n * @param onLog Optional log callback; silently ignored if omitted\n * @param watch Optional watch callbacks; watching is skipped if omitted\n * @param secretProvider Optional secret provider chain for connector field\n * resolution and `env:NAME` lookups\n * @param sessionMeta Provider/model/sessionId metadata used for logging\n * @param tokenMediator Optional callback for `auth: backend` connectors to\n * mint short-lived tokens. Threaded into `ConnectorManager`.\n * @param preMintedSecrets Optional v3 pre-minted credential provider — when\n * supplied, `auth: backend` connectors find their initial\n * token in-process instead of paying a\n * `request_access_token` round-trip at connect time.\n * @param deferFilesystemMounts When true, rclone-backed filesystem-face\n * connectors (marked `deferMount`) are brought up in the\n * background instead of being awaited — so a slow remote\n * can't gate session bootstrap. Their mount path is still\n * rendered immediately; progress rides `onConnectorStatus`.\n * @param capabilityRegistry When supplied, external (declarative / recipe-backed)\n * MCP servers are spawned and connected BY THE RUNNER and\n * their tools registered into this registry as\n * `mcp`-origin capabilities — the bridge-agnostic path\n * that works on every driver. When omitted, the legacy\n * claude-sdk-only path is used (external stdio servers are\n * delegated to the SDK's `mcpServers` query option).\n * @docLink packages/runner/dev-guide#flow-execution-turn-based-model\n */\nexport async function buildAgentResources(\n projectDir: string,\n driverType: string,\n _onLog?: (line: string) => void,\n watch?: ResourceWatchCallbacks,\n secretProvider?: unknown,\n sessionMeta?: { provider?: string; model?: string; sessionId?: string },\n tokenMediator?: TokenMediator,\n preMintedSecrets?: PreMintedSecretProvider,\n deferFilesystemMounts?: boolean,\n capabilityRegistry?: CapabilityRegistry,\n): Promise<AgentResourcesResult> {\n const resLog = createLogger({\n kind: \"runner\",\n subkind: \"resources\",\n instance: sessionMeta?.sessionId ?? \"no-session\",\n });\n // `_onLog` is preserved in the public signature for back-compat with external\n // callers, but is unused internally — structured emission via `resLog` and the\n // per-source loggers below reaches the caller through the OnLogBridgeSink that\n // the runner bootstrap installs at the LogStore level.\n const noopResult: AgentResourcesResult = {\n resourceManager: null,\n resourcePromptSection: \"\",\n mcpServers: undefined,\n runtimeAssets: null,\n dispose: async () => {},\n startWatching: () => {},\n getOrCreateExternalMcpManager: () => {\n throw new Error(\"external MCP manager unavailable — no capability registry (CLI/flow mode)\");\n },\n getExternalMcpManager: () => null,\n mcpPromptSection: \"\",\n };\n\n try {\n registerBuiltinConnectors();\n\n // Resolve catalog entries + implicit refs from skaile.yaml + factory-assets repo.\n // Held on the session result so live-update paths can call refresh().\n const runtimeAssets = await resolveRuntimeAssets(projectDir);\n for (const w of runtimeAssets.warnings) {\n resLog.warn(\"runtime asset warning\", { code: w.code, message: w.message });\n }\n\n // Optional: install missing npm peer deps before mountAll/connectAll runs.\n await maybeInstallNpmPeerDeps(runtimeAssets, projectDir, resLog);\n\n // --- Mounts ---\n // --- Connectors (filesystem + tool faces) ---\n // The unified ConnectorManager owns the full lifecycle for every connector\n // declared in skaile.yaml — mountable (filesystem-face) and tool-face alike.\n const connectorDeclarations = loadConnectorDeclarations(projectDir);\n let resourceManager: ConnectorManager | null = null;\n\n if (connectorDeclarations.length > 0) {\n resourceManager = await connectAllConnectors(\n connectorDeclarations,\n projectDir,\n runtimeAssets,\n secretProvider,\n tokenMediator,\n preMintedSecrets,\n deferFilesystemMounts,\n watch,\n resLog,\n );\n }\n\n // Build the system prompt section (mount paths + connector tools).\n const resourcePromptSection = resourceManager\n ? buildConnectorPromptSection(resourceManager)\n : \"\";\n\n // ── MCP servers ─────────────────────────────────────────────────────────\n let mcpServers: Record<string, unknown> | undefined;\n let workspacePluginToShutdown: { shutdown(): Promise<void> } | null = null;\n let externalMcpManager: ExternalMcpManager | null = null;\n // Lazily resolved when we actually need MCP declarations (serve mode or\n // claude-sdk). Stays undefined for other drivers without a capability\n // registry so we do not emit unexpected mcp:* log entries.\n let externalMcpDeclarations: import(\"@skaile/workspaces/core\").McpServerDeclaration[] | undefined;\n\n // The runtime add path stages `mcp:<id>` bearers on `preMintedSecrets`; boot\n // decls resolve `env:`/`forge:` refs via `secretProvider`. Chain both so one\n // manager serves both — prefixed refs route to the owning provider, so adding\n // preMintedSecrets is harmless for boot. Avoid a chain with undefined members.\n const mcpSecretChain: unknown = preMintedSecrets\n ? new SecretProviderChain(\n [preMintedSecrets, secretProvider as SecretProvider | undefined].filter(\n Boolean,\n ) as SecretProvider[],\n )\n : secretProvider;\n\n const getOrCreateExternalMcpManager = (): ExternalMcpManager => {\n if (!capabilityRegistry) {\n throw new Error(\n \"external MCP manager unavailable — no capability registry (CLI/flow mode)\",\n );\n }\n if (!externalMcpManager) {\n externalMcpManager = createExternalMcpManager(\n capabilityRegistry,\n mcpSecretChain,\n sessionMeta,\n );\n }\n return externalMcpManager;\n };\n\n // In-process MCP servers (connector tools + workspace plugin) stay on the\n // claude-sdk `mcpServers` path: they are SDK server *instances*, not external\n // subprocesses, so the bridge-agnostic capability path below does not apply\n // to them.\n if (driverType === \"claude-sdk\") {\n const inProcess = await buildInProcessMcpServers(\n resourceManager,\n projectDir,\n driverType,\n sessionMeta,\n );\n mcpServers = inProcess.mcpServers;\n workspacePluginToShutdown = inProcess.workspacePluginToShutdown;\n }\n\n // ── External (declarative / recipe-backed) MCP servers ──────────────────\n // e.g. excel / ppt — `mcp_servers:` entries from skaile.yaml, including\n // recipe-backed ones. When a capability registry is available (serve mode),\n // the RUNNER spawns these subprocesses itself and registers each tool as an\n // `mcp`-origin capability — the bridge-agnostic surface every driver\n // consumes, with no dependence on the claude-agent-sdk `mcpServers` option.\n // Without a registry (CLI / flow), fall back to the legacy claude-sdk-only\n // delegation where the SDK spawns the stdio subprocess.\n if (capabilityRegistry) {\n externalMcpDeclarations = resolveExternalMcpDeclarations(\n projectDir,\n sessionMeta?.sessionId,\n );\n externalMcpManager = await startExternalMcpServers(\n capabilityRegistry,\n externalMcpDeclarations,\n mcpSecretChain,\n sessionMeta,\n );\n } else if (driverType === \"claude-sdk\") {\n externalMcpDeclarations = resolveExternalMcpDeclarations(\n projectDir,\n sessionMeta?.sessionId,\n );\n mcpServers = wireExternalMcpServersForSdk(\n mcpServers,\n externalMcpDeclarations,\n secretProvider,\n sessionMeta,\n );\n }\n\n // If neither connectors nor workspace-plugin nor runner-managed MCP servers\n // produced anything useful for a non-claude-sdk driver, return noop to avoid\n // overhead. A connected external MCP manager is \"something useful\" — fall\n // through so its dispose() (which kills the subprocesses) is wired up.\n // Skip this short-circuit in serve mode (capabilityRegistry present): the\n // real result carries getOrCreateExternalMcpManager so hot-plug adds work.\n if (\n !resourceManager &&\n driverType !== \"claude-sdk\" &&\n !externalMcpManager?.hasServers() &&\n !capabilityRegistry\n )\n return noopResult;\n\n // Deferred watch setup — called by the consumer after the transport is listening\n // so that slow filesystem scans (e.g. large node_modules over Docker bind mounts)\n // don't block session startup.\n let coalescer: FileChangedCoalescer | null = null;\n const startWatching = () => {\n if (resourceManager && watch?.onFileChanged) {\n const dedupTtlMs = watch.dedupTtlMs ?? 500;\n const recentlyEmitted = new Map<string, number>();\n\n // Sits after per-path dedup: bulk git ops touch many distinct paths so dedup\n // doesn't fire, but the coalescer collapses by directory into one rep each.\n coalescer = new FileChangedCoalescer(\n (mountId, event) => watch.onFileChanged!(mountId, event),\n undefined,\n Date.now,\n (m) => resLog.warn(m),\n );\n\n resourceManager.watchAll((connectorId: string, event: ConnectorChangeEvent) => {\n const dedupKey = `${connectorId}:${event.path}`;\n const now = Date.now();\n const lastEmit = recentlyEmitted.get(dedupKey);\n if (lastEmit && now - lastEmit < dedupTtlMs) return;\n recentlyEmitted.set(dedupKey, now);\n\n if (recentlyEmitted.size > 200) {\n for (const [key, ts] of recentlyEmitted) {\n if (now - ts > dedupTtlMs) recentlyEmitted.delete(key);\n }\n }\n\n coalescer!.push(connectorId, event);\n });\n }\n };\n\n const dispose = async () => {\n coalescer?.dispose();\n // Kill runner-spawned MCP subprocesses + deregister their capabilities.\n try {\n await externalMcpManager?.dispose();\n } catch {\n /* best-effort */\n }\n if (workspacePluginToShutdown) {\n try {\n await workspacePluginToShutdown.shutdown();\n } catch {\n /* best-effort */\n }\n }\n try {\n await resourceManager?.disconnectAll();\n } catch {\n /* best-effort */\n }\n };\n\n const mcpPromptSection = buildMcpPromptSection(externalMcpDeclarations ?? []);\n\n return {\n resourceManager,\n resourcePromptSection,\n mcpServers,\n runtimeAssets,\n dispose,\n startWatching,\n getOrCreateExternalMcpManager,\n getExternalMcpManager: () => externalMcpManager,\n mcpPromptSection,\n };\n } catch {\n // @skaile/workspaces/connectors not installed or skaile.yaml parse error — resources disabled\n return noopResult;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\ntype ResourcesLogger = ReturnType<typeof createLogger>;\n\n/**\n * Install missing npm peer deps before mountAll/connectAll runs.\n *\n * Disabled by default for serve mode (no network or write access in\n * production agent containers); enable via SKAILE_AUTO_INSTALL_DEPS=true.\n * Asset-manager.install() is the canonical preflight install path.\n */\nasync function maybeInstallNpmPeerDeps(\n runtimeAssets: RuntimeAssetsResult,\n projectDir: string,\n resLog: ResourcesLogger,\n): Promise<void> {\n if (process.env.SKAILE_AUTO_INSTALL_DEPS === \"true\") {\n const required = runtimeAssets.requiredNpmDeps.required;\n if (required.length > 0) {\n const missing = findMissingPackages(required, projectDir);\n if (missing.length > 0) {\n resLog.info(\"installing missing npm peer deps\", { packages: missing });\n const r = await installNpmPackages(missing, projectDir);\n if (!r.success) resLog.error(\"npm install failed\", undefined, { output: r.output });\n }\n }\n }\n}\n\n/** Log the per-connector status carried on a connect report. */\nfunction logConnectorReport(\n results: Array<{ connected: boolean; id: string; mountPath?: string; error?: unknown }>,\n resLog: ResourcesLogger,\n): void {\n for (const r of results) {\n if (r.connected) {\n resLog.info(\"connector ok\", { id: r.id, mountPath: r.mountPath });\n } else {\n resLog.error(\"connector failed\", undefined, { id: r.id, error: r.error });\n }\n }\n}\n\n/**\n * Create the unified ConnectorManager and connect every declared connector\n * (filesystem + tool faces). The manager owns the full lifecycle.\n */\nasync function connectAllConnectors(\n connectorDeclarations: Parameters<ConnectorManager[\"connectAll\"]>[0],\n projectDir: string,\n runtimeAssets: RuntimeAssetsResult,\n secretProvider: unknown,\n tokenMediator: TokenMediator | undefined,\n preMintedSecrets: PreMintedSecretProvider | undefined,\n deferFilesystemMounts: boolean | undefined,\n watch: ResourceWatchCallbacks | undefined,\n resLog: ResourcesLogger,\n): Promise<ConnectorManager> {\n const resourceManager = new ConnectorManager(projectDir, {\n secrets: secretProvider as any,\n catalogEntries: runtimeAssets.catalogEntries,\n tokenMediator,\n preMintedSecrets,\n onStatusChange: watch?.onConnectorStatus,\n });\n // failOnReadWriteError: a read-write mountable-connector failure means\n // the agent workspace is unusable (e.g. expired SharePoint token leaves\n // the workspace empty). Surface as a session-start error rather than\n // silently degrading to \"agent sees no files.\" Deferred (rclone-backed)\n // mounts are exempt — they degrade to \"still syncing\" via status events.\n try {\n const report = await resourceManager.connectAll(connectorDeclarations, {\n failOnReadWriteError: true,\n deferMounts: deferFilesystemMounts,\n });\n logConnectorReport(report.results, resLog);\n } catch (err) {\n // Log the full per-connector status from the report carried on the\n // error before re-throwing so operators can see which connected.\n if (err instanceof ConnectorStartupError) {\n logConnectorReport(err.report.results, resLog);\n }\n throw err;\n }\n return resourceManager;\n}\n\n/**\n * Build the in-process MCP servers (connector tools + workspace plugin) for the\n * claude-sdk `mcpServers` path. They are SDK server *instances*, not external\n * subprocesses, so the bridge-agnostic capability path does not apply to them.\n */\nasync function buildInProcessMcpServers(\n resourceManager: ConnectorManager | null,\n projectDir: string,\n driverType: string,\n sessionMeta: { provider?: string; model?: string; sessionId?: string } | undefined,\n): Promise<{\n mcpServers: Record<string, unknown> | undefined;\n workspacePluginToShutdown: { shutdown(): Promise<void> } | null;\n}> {\n let mcpServers: Record<string, unknown> | undefined;\n\n // Connector tools (only if connectors exist)\n if (resourceManager) {\n const connectorsLog = createLogger({ kind: \"mcp\", subkind: \"skaile-connectors\" });\n try {\n const server = await buildSdkConnectorTools(resourceManager, { z });\n if (server) {\n mcpServers = { \"skaile-connectors\": server };\n connectorsLog.info(\"server constructed\", {\n connectorCount: resourceManager.listConnectors().length,\n });\n } else {\n connectorsLog.debug(\"server skipped (no tools to expose)\");\n }\n } catch (err) {\n connectorsLog.error(\"server construction failed\", err);\n throw err;\n }\n }\n\n // Workspace plugin — always inject for claude-sdk.\n // `onLog` is intentionally NOT passed: structured emission via\n // `WorkspacePlugin.log` already reaches the caller's `onLog` through the\n // OnLogBridgeSink installed by the runner bootstrap. Passing `onLog` here\n // would cause double-emit for plugin lifecycle events (booted, warning).\n const workspacePlugin = new WorkspacePlugin({\n projectDir,\n connectorManager: resourceManager ?? undefined,\n driver: driverType,\n provider: sessionMeta?.provider,\n model: sessionMeta?.model,\n });\n const wsServer = await workspacePlugin.buildWorkspaceMcpServer();\n if (wsServer) {\n mcpServers = { ...(mcpServers ?? {}), \"skaile-workspace\": wsServer };\n }\n return { mcpServers, workspacePluginToShutdown: workspacePlugin };\n}\n\n/**\n * Spawn external (declarative / recipe-backed) MCP servers and register each\n * tool as an `mcp`-origin capability — the bridge-agnostic surface every driver\n * consumes. Returns the manager (with running subprocesses), or null when no\n * external declarations were resolved.\n */\nasync function startExternalMcpServers(\n capabilityRegistry: CapabilityRegistry,\n resolvedDecls: import(\"@skaile/workspaces/core\").McpServerDeclaration[],\n secretProvider: unknown,\n sessionMeta: { provider?: string; model?: string; sessionId?: string } | undefined,\n): Promise<ExternalMcpManager | null> {\n if (resolvedDecls.length === 0) return null;\n const mgr = createExternalMcpManager(capabilityRegistry, secretProvider, sessionMeta);\n await mgr.start(resolvedDecls);\n return mgr;\n}\n\n/**\n * Construct (do not start) an `ExternalMcpManager` with the 401 reauthorizer\n * wired. Shared by the boot path ({@link startExternalMcpServers}) and the lazy\n * runtime path (`runner.add_mcp_server`).\n */\nfunction createExternalMcpManager(\n capabilityRegistry: CapabilityRegistry,\n secretProvider: unknown,\n sessionMeta: { provider?: string; model?: string; sessionId?: string } | undefined,\n): ExternalMcpManager {\n return new ExternalMcpManager(\n capabilityRegistry,\n secretProvider as SecretProviderLike | undefined,\n sessionMeta?.sessionId,\n undefined,\n buildMcpReauthorizer(capabilityRegistry, secretProvider, sessionMeta?.sessionId),\n );\n}\n\n/** `MCP__<sanitized id>__AUTH` — cross-repo contract: must mirror the platform's bearer-provisioning key. */\nexport function mcpAuthSecretKey(id: string): string {\n return `MCP__${id.replace(/[^A-Za-z0-9_]/g, \"_\")}__AUTH`;\n}\n\n/**\n * Build the 401 re-mint callback for `auth: backend` remote MCP servers: ask the\n * platform mediator for a fresh bearer (`host.refresh_credential`), then rewrite\n * the provisioned `MCP__<id>__AUTH` secret in place so the manager's reconnect\n * picks it up. Returns `undefined` when the secret store is immutable (CLI mode)\n * — without a writable store there is nothing to rewrite, so no re-mint applies.\n */\nfunction buildMcpReauthorizer(\n capabilityRegistry: CapabilityRegistry,\n secretProvider: unknown,\n sessionId: string | undefined,\n): McpReauthorizer | undefined {\n const provider = secretProvider as\n | { provision?: (s: Record<string, string>) => void }\n | undefined;\n const provision = provider?.provision?.bind(provider);\n if (!provision) return undefined;\n const log = createLogger({ kind: \"mcp\", subkind: \"reauth\", instance: sessionId ?? \"no-session\" });\n return async (decl) => {\n if (!decl.providerLinkId || decl.auth !== \"backend\") return false;\n let mint: { ok?: boolean; token?: string };\n try {\n mint = (await capabilityRegistry.invokeRemote(\"host.refresh_credential\", {\n kind: \"mcp-server\",\n id: decl.providerLinkId,\n reason: \"retry-401\",\n })) as { ok?: boolean; token?: string };\n } catch (err) {\n log.warn(\"MCP credential re-mint round-trip failed\", {\n id: decl.id,\n error: err instanceof Error ? err.message : String(err),\n });\n return false;\n }\n if (!mint?.ok || !mint.token) return false;\n provision({ [mcpAuthSecretKey(decl.id)]: `Bearer ${mint.token}` });\n return true;\n };\n}\n\n/**\n * Legacy claude-sdk-only delegation: translate external MCP declarations into\n * the SDK's `mcpServers` config so the SDK spawns the stdio subprocess itself.\n * Returns the (possibly extended) `mcpServers` map.\n */\nfunction wireExternalMcpServersForSdk(\n mcpServers: Record<string, unknown> | undefined,\n resolvedDecls: import(\"@skaile/workspaces/core\").McpServerDeclaration[],\n secretProvider: unknown,\n sessionMeta: { provider?: string; model?: string; sessionId?: string } | undefined,\n): Record<string, unknown> | undefined {\n const mcpLog = createLogger({\n kind: \"mcp\",\n subkind: \"wiring\",\n instance: sessionMeta?.sessionId ?? \"no-session\",\n });\n for (const decl of resolvedDecls) {\n const serverConfig = toSdkMcpServerConfig(\n decl,\n secretProvider as SecretProviderLike | undefined,\n );\n if (serverConfig) {\n mcpServers = { ...(mcpServers ?? {}), [decl.id]: serverConfig };\n createLogger({ kind: \"mcp\", subkind: decl.id }).info(\"MCP server registered\", {\n transport: decl.transport ?? \"stdio\",\n ...(decl.transport === \"stdio\" || !decl.transport\n ? { command: decl.command, args: decl.args }\n : { url: decl.url }),\n });\n } else {\n mcpLog.error(\"MCP server config invalid (translation returned null)\", undefined, {\n id: decl.id,\n transport: decl.transport,\n });\n }\n }\n return mcpServers;\n}\n\n/**\n * Convert a `McpServerDeclaration` from `skaile.yaml` into the SDK's\n * `McpServerConfig` shape accepted by `AgentConfig.mcpServers`.\n *\n * Secret references in `env` and `headers` values (e.g. `env:MY_TOKEN`) are\n * resolved through the session's `SecretProvider` chain when available.\n *\n * Returns `null` when the declaration is missing required fields for its\n * transport type (e.g. no `command` for a stdio server).\n */\nfunction toSdkMcpServerConfig(\n decl: McpServerDeclaration,\n secrets?: SecretProviderLike,\n): Record<string, unknown> | null {\n const transport = decl.transport ?? \"stdio\";\n\n if (transport === \"stdio\") {\n if (!decl.command) return null;\n const cfg: Record<string, unknown> = { type: \"stdio\", command: decl.command };\n if (decl.args?.length) cfg.args = decl.args;\n if (decl.env && Object.keys(decl.env).length > 0) {\n cfg.env = resolveRecordSecrets(decl.env, secrets);\n }\n return cfg;\n }\n\n if (transport === \"sse\" || transport === \"http\") {\n if (!decl.url) return null;\n const cfg: Record<string, unknown> = { type: transport, url: decl.url };\n if (decl.headers && Object.keys(decl.headers).length > 0) {\n cfg.headers = resolveRecordSecrets(decl.headers, secrets);\n }\n return cfg;\n }\n\n return null;\n}\n","/**\n * session-builder.ts\n *\n * Shared `createAgentSession()` factory — extracts the common agent\n * initialisation sequence from agent.ts (REPL), run-flow.ts (flow), and\n * serve.ts (WebSocket server) into a single reusable module.\n *\n * The shared setup pipeline:\n * 1. resolveSettings → driverType, provider, model, apiKey\n * 2. loadAgentManifest → manifest (model, maxTurns, tools, name)\n * 3. buildAgentResources → resourceManager, resourcePromptSection, mcpServers, dispose\n * 4. Load workspace config, build contextSection + environmentSection, load prompt-extensions\n * 5. assembleSystemPrompt (context + env + resources + extensions + additional sections)\n * 6. Resolve maxTurns (config override wins over manifest)\n * 7. createDriver (NOT started — caller calls driver.start() when ready)\n *\n * Agent identity (SOUL.md, RULES.md, knowledge/) is never assembled here.\n * It is rendered at install time by the renderers in asset-manager and read\n * natively by each backend driver at runtime.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { resolve as resolvePath } from \"node:path\";\nimport type { AgentDriver, BridgeCapabilityHooks } from \"@skaile/workspaces/bridge\";\nimport { createDriver } from \"@skaile/workspaces/bridge\";\nimport type {\n AgentManifest,\n RuntimeAssetsResult,\n SkWorkspaceConfig,\n} from \"@skaile/workspaces/core\";\nimport { resolveApiKey, resolveSettings, resolveSkWorkspaceConfig } from \"@skaile/workspaces/core\";\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\nimport type { TelemetryProvider, Trace } from \"@skaile/workspaces/telemetry\";\nimport type { SystemPromptSection } from \"@skaile/workspaces/types\";\nimport type { CapabilityRegistry } from \"./capability-registry.js\";\nimport { type ResolvedComposition, resolveAgentComposition } from \"./composition/bootstrap.js\";\nimport { buildContextSection } from \"./context.js\";\nimport { buildEnvironmentSection } from \"./environment.js\";\nimport { loadAgentManifest } from \"./manifest.js\";\nimport { assembleSystemPrompt } from \"./prompt-assembly.js\";\nimport { buildAgentResources, type ResourceWatchCallbacks } from \"./resources.js\";\n\nexport type { ResourceWatchCallbacks };\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Configuration for creating an agent session.\n *\n * Controls the driver backend, LLM provider and model, agent identity,\n * workspace layout, resource lifecycle, and protocol v2 capability hooks.\n *\n * @docLink packages/runner/dev-guide#flow-execution-turn-based-model\n */\nexport interface AgentSessionConfig {\n projectDir: string;\n /**\n * Agent working directory — where the agent reads/writes files.\n * Defaults to `projectDir` when omitted. Use this to separate the config\n * root (`projectDir` with `skaile.yaml`) from the actual working directory\n * (e.g. when the user is in a subdirectory or has no `skaile.yaml` in their CWD).\n */\n cwd?: string;\n agentDir?: string;\n driver?: string;\n model?: string;\n provider?: string;\n promptsDir?: string;\n projectClaudeMd?: string;\n sessionId?: string;\n resumeSessionId?: string;\n /**\n * Path to a file whose contents are prepended to the system prompt.\n * @deprecated Use `agent.prompt-extensions` in skaile.yaml instead. The runner\n * no longer injects this file's contents.\n */\n externalPromptFile?: string;\n /**\n * Pre-resolved workspace config. Avoids re-reading skaile.yaml when the caller\n * already has it. Optional — falls back to `resolveSkWorkspaceConfig(projectDir)`.\n */\n wsConfig?: SkWorkspaceConfig;\n /**\n * Platform-level maxTurns override. Takes precedence over manifest.runtime.max_turns.\n * Flow/REPL modes omit this field — they use the manifest value only.\n */\n maxTurns?: number;\n /** Thinking mode override. */\n thinking?: \"adaptive\" | \"enabled\" | \"disabled\";\n /** Reasoning effort level override. */\n effort?: \"low\" | \"medium\" | \"high\" | \"max\";\n /** Watch callbacks for filesystem/sync events (serve mode only). */\n watch?: ResourceWatchCallbacks;\n /**\n * When true, rclone-backed filesystem-face connectors are mounted in the\n * background instead of awaited, so a slow remote can't delay session\n * bootstrap (notably the platform's `session_init_ack` deadline). Serve mode\n * sets this; CLI/flow/REPL paths leave it unset (mount eagerly).\n */\n deferFilesystemMounts?: boolean;\n /** Secret provider for connector credential resolution. */\n secretProvider?: unknown;\n /**\n * Pre-resolved API key for the active provider. When supplied, it takes\n * precedence over the env-var lookup performed inside `resolveApiKey()`.\n * Used by `serve.ts` to feed the value from `provision_secrets` straight\n * into `AgentConfig.apiKeys` without writing it to `process.env`.\n */\n apiKey?: string;\n /**\n * Optional callback used by `auth: backend` git connectors to request\n * short-lived access tokens from the platform's credential mediator.\n * Threaded into the `ConnectorManager` constructor so all git connectors in\n * this session share the same mediator.\n */\n tokenMediator?: import(\"@skaile/workspaces/connectors\").TokenMediator;\n /**\n * Pre-minted credential provider populated from the v3 `session_init`\n * envelope's `credentials` map. Threaded into ConnectorManager so that\n * connectors with `auth: backend` find their token in-process instead of\n * paying a `request_access_token` round-trip at mount time.\n *\n * @since 3.0.0\n */\n preMintedSecrets?: import(\"@skaile/workspaces/connectors\").PreMintedSecretProvider;\n /**\n * Platform `AIProviderConfig.id` for the AI credential provisioned into\n * this session. Threaded into `AgentConfig.aiProviderConfigId` so that\n * driver recreates (tier-1 native SDK resume, subagents, etc.) preserve\n * the link to the platform mediator. The driver itself does not consume\n * this field; only the runner's 401-mediation handler reads it.\n */\n aiProviderConfigId?: string;\n /**\n * Optional auth-refresh callback threaded into the bridge driver. Invoked\n * by the driver when the underlying agent surfaces an\n * `authentication_error`; in v3 the runner mediates a fresh credential\n * via the `host.refresh_credential` capability and returns a typed\n * {@link CredentialMint}. The driver branches on the discriminator:\n * `ok: true` triggers a one-shot retry of the in-flight prompt;\n * `ok: false` surfaces the original auth error to the caller.\n *\n * Centralising auth-retry inside the driver removes the need to wrap\n * every `driver.prompt(...)` call site (compaction, flow turns, serve\n * handler) with a runner-side retry helper. Standalone CLI / forge\n * sessions leave it undefined.\n *\n * Spec: `_devlog/specs/2026-05-10-deterministic-session-bootstrap.md`\n * § \"Refresh-on-401 routes through host.refresh_credential\".\n */\n onAuthError?: (args: {\n configId: string;\n }) => Promise<import(\"@skaile/workspaces/types\").CredentialMint>;\n /**\n * Additional sections to append to the assembled system prompt.\n * Used by serve mode to inject the component catalog (AVAILABLE_COMPONENTS)\n * without modifying the session builder's core assembly logic.\n */\n additionalPromptSections?: string[];\n onLog?: (line: string) => void;\n /** Telemetry provider for observability. Optional — omit to disable tracing. */\n telemetry?: TelemetryProvider;\n /** Active trace to attach to this session's driver. */\n trace?: Trace;\n /**\n * Protocol v2 capability dispatch hooks built from the runner's\n * CapabilityRegistry. When present, the driver routes registered tool\n * calls through `hooks.invoke()` instead of the legacy in-driver dispatch.\n *\n * @since 2.0.0\n */\n capabilities?: BridgeCapabilityHooks;\n /**\n * The session's Protocol v2 capability registry. When supplied, external\n * (declarative / recipe-backed) MCP servers are spawned and connected BY THE\n * RUNNER during `buildAgentResources`, with each tool registered into this\n * registry as an `mcp`-origin capability — the bridge-agnostic surface every\n * driver consumes. Omit (CLI / flow) to fall back to the legacy\n * claude-sdk-only SDK delegation for external stdio servers.\n *\n * @since 3.5.0\n */\n capabilityRegistry?: CapabilityRegistry;\n}\n\n/**\n * A configured agent session returned by {@link createAgentSession}.\n *\n * Carries a driver instance (not yet started), connected resource and\n * mount managers, resolved runtime assets, and the parsed agent manifest.\n *\n * @docLink packages/runner/dev-guide#flow-execution-turn-based-model\n */\nexport interface AgentSession {\n /** Driver configured but NOT started. Caller must call driver.start(). */\n driver: AgentDriver;\n /** Connected ConnectorManager — null if no connectors declared. any intentional (optional dep). */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n resourceManager: any | null;\n /**\n * Resolved runtime assets — catalog entries, implicit refs, npm deps,\n * warnings, plus refresh() / findEntry() helpers. Live-update paths\n * (add_resource, configure) hold this reference and call refresh() when\n * a new repository is cloned or driver installed mid-session.\n */\n runtimeAssets: RuntimeAssetsResult | null;\n /**\n * Resolved composition — inline blocks (already injected into systemPrompt)\n * and discoverable entries (caller registers these with CapabilityRegistry).\n * Null when the agent has no `composes:` field.\n */\n composition: ResolvedComposition | null;\n /** Parsed agent.yaml manifest — model, maxTurns, tools, name. */\n manifest: AgentManifest | undefined;\n /** Active driver type string ('omp' | 'claude-sdk'). */\n driverType: string;\n provider: string | undefined;\n model: string | undefined;\n /** Disconnect all connectors, unmount all mounts, and stop watchers. */\n dispose: () => Promise<void>;\n /** Start filesystem and connector watchers. Call after transport is listening. */\n startWatching: () => void;\n /**\n * Lazily construct (once) and return the session's external MCP manager —\n * the live target for `runner.add_mcp_server`. Serve mode only; throws when\n * no capability registry was supplied (CLI/flow).\n */\n getOrCreateExternalMcpManager: () => import(\"./external-mcp.js\").ExternalMcpManager;\n /** The external MCP manager if constructed (boot or lazy), else null. */\n getExternalMcpManager: () => import(\"./external-mcp.js\").ExternalMcpManager | null;\n /** Telemetry provider for this session (noop if not configured). */\n telemetry?: TelemetryProvider;\n /**\n * Labeled per-section breakdown of the system prompt, in the same\n * order assembleSystemPrompt consumed them. Multi-entry sections\n * (prompt-extensions, composition, additional) appear as repeated\n * entries with `source` set.\n *\n * Consumed by serve.ts's emitSystemPromptComposed helper to emit\n * `system_prompt_composed` events to the platform.\n * @since 2026-05\n */\n systemPromptSections: SystemPromptSection[];\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create an agent session by resolving settings, loading the agent\n * manifest, building resources (connectors, mounts, MCP servers),\n * and creating the driver.\n *\n * The returned driver is NOT started — the caller must call\n * `driver.start()` after optionally attaching event handlers.\n *\n * @param config - Session configuration\n * @returns A fully configured AgentSession ready for start()\n * @docLink packages/runner/dev-guide#flow-execution-turn-based-model\n */\nexport async function createAgentSession(config: AgentSessionConfig): Promise<AgentSession> {\n const {\n projectDir,\n cwd: cwdOverride,\n agentDir,\n driver: driverOverride,\n model: modelOverride,\n provider: providerOverride,\n sessionId,\n resumeSessionId,\n externalPromptFile,\n wsConfig: wsConfigOverride,\n maxTurns: maxTurnsOverride,\n watch,\n secretProvider,\n onLog,\n telemetry,\n trace,\n } = config;\n\n // Agent working directory — defaults to projectDir when not explicitly set.\n const agentCwd = cwdOverride ?? projectDir;\n\n const sessionLog = createLogger({\n kind: \"runner\",\n subkind: \"session\",\n instance: sessionId ?? \"no-session\",\n });\n\n // Step 1: resolve driver/model/provider/apiKey\n const settings = await resolveSettings(projectDir, {\n driver: driverOverride,\n provider: providerOverride,\n model: modelOverride,\n });\n const driverType = settings.driver ?? \"omp\";\n const provider = settings.provider;\n const model = settings.model;\n // Explicit `config.apiKey` wins over the env/settings cascade — used by\n // serve.ts to inject the platform-provisioned key without leaking it into\n // `process.env`.\n const apiKey = config.apiKey ?? resolveApiKey(provider ?? \"anthropic\", settings);\n\n // Step 2: load agent manifest (model, maxTurns, tools, name)\n const manifest = agentDir ? await loadAgentManifest(agentDir) : undefined;\n\n // Step 3: build resources (mounts + connectors lifecycle)\n const {\n resourceManager,\n resourcePromptSection,\n mcpServers,\n runtimeAssets,\n dispose,\n startWatching,\n getOrCreateExternalMcpManager,\n getExternalMcpManager,\n mcpPromptSection,\n } = await buildAgentResources(\n projectDir,\n driverType,\n onLog,\n watch,\n secretProvider,\n {\n provider,\n model,\n sessionId,\n },\n config.tokenMediator,\n config.preMintedSecrets,\n config.deferFilesystemMounts,\n config.capabilityRegistry,\n );\n\n // Step 4: resolve workspace config + build context/environment sections + load extensions\n const wsConfig = wsConfigOverride ?? resolveSkWorkspaceConfig(projectDir);\n const contextSection = buildContextSection(wsConfig.agent?.context);\n // Free-form user-authored prompt — placed immediately after the platform\n // context section. Empty / undefined values are dropped by assembleSystemPrompt\n // (filters falsies via `!!p`) so we skip an explicit guard here.\n const userPromptSection = wsConfig.agent?.prompt?.trim();\n const environmentSection = await buildEnvironmentSection(projectDir);\n const promptExtensions = loadPromptExtensions(\n wsConfig.agent?.[\"prompt-extensions\"],\n projectDir,\n sessionLog,\n );\n\n if (externalPromptFile) {\n sessionLog.warn(\n \"externalPromptFile is deprecated and no longer injected; use agent.prompt-extensions in skaile.yaml instead\",\n );\n }\n\n // Step 4.5: resolve agent composition (composes: field)\n // Produces inline blocks (injected into system prompt below) and discoverable\n // entries (caller registers these with CapabilityRegistry in serve.ts).\n const composition = await resolveSessionComposition(agentDir, manifest, projectDir, sessionLog);\n\n // Step 5: assemble systemPrompt — context + prompt + env + resources + extensions + composition + additional\n // Agent identity (SOUL/RULES/knowledge) is NOT included here — it is rendered at install time\n // by the renderers in asset-manager and read natively by each backend driver at runtime.\n // Composition inline blocks ARE included here — they are the v2 equivalent of identity injection\n // for agents that use `composes:` (replaces the legacy persona/rules/knowledge fields).\n // The userPromptSection (free-form `agent.prompt`) sits between context and environment per\n // the platform-agent-prompt design spec (2026-05-13).\n const compositionBlocks = composition?.inlineBlocks ?? [];\n const additionalSections = config.additionalPromptSections ?? [];\n\n // Labeled per-section breakdown — order matches the assembleSystemPrompt input.\n // assembleSystemPrompt filters falsies; we mirror that here so only non-empty\n // sections appear in the breakdown emitted to the platform.\n const systemPromptSections = buildSystemPromptSections({\n contextSection,\n userPromptSection,\n environmentSection,\n resourcePromptSection,\n mcpPromptSection,\n promptExtensions,\n compositionBlocks,\n additionalSections,\n });\n\n const systemPrompt = assembleSystemPrompt([\n contextSection,\n userPromptSection,\n environmentSection,\n resourcePromptSection,\n mcpPromptSection,\n ...promptExtensions.map((e) => e.value),\n ...compositionBlocks.map((b) => b.content),\n ...additionalSections,\n ]);\n\n logAssembledSystemPrompt(systemPrompt, sessionLog);\n\n // Step 5b: resolve thinking/effort — explicit config wins over workspace config\n const thinking =\n config.thinking ?? (wsConfig.agent_config?.default?.thinking as AgentSessionConfig[\"thinking\"]);\n const effort =\n config.effort ?? (wsConfig.agent_config?.default?.effort as AgentSessionConfig[\"effort\"]);\n\n // Step 6: resolve maxTurns — platform override wins over manifest\n const maxTurns = maxTurnsOverride ?? manifest?.runtime?.max_turns;\n\n // Step 7: create driver (NOT started)\n // Driver CWD is the agent working directory (may differ from config root).\n const driver = await createSessionDriver({\n config,\n driverType,\n agentCwd,\n provider,\n model,\n manifest,\n maxTurns,\n apiKey,\n systemPrompt,\n thinking,\n effort,\n sessionId,\n resumeSessionId,\n mcpServers,\n agentDir,\n });\n\n // Attach telemetry to driver if provided\n if (telemetry && trace) {\n driver.setTelemetry(telemetry, trace);\n }\n\n return {\n driver,\n resourceManager,\n runtimeAssets,\n composition,\n manifest,\n driverType,\n provider,\n model,\n dispose,\n startWatching,\n getOrCreateExternalMcpManager,\n getExternalMcpManager,\n telemetry,\n systemPromptSections,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * One loaded prompt-extension file. `source` carries the original relative\n * path from `skaile.yaml` so labeled breakdowns (system_prompt_composed event)\n * can attribute each section to a specific file.\n */\ntype LoadedPromptExtension = { value: string; source: string };\n\n/**\n * Load markdown files declared under `agent.prompt-extensions` in skaile.yaml.\n * Paths are resolved relative to the project root. Missing files are skipped\n * with a warning. Empty files are filtered out.\n */\nfunction loadPromptExtensions(\n paths: string[] | undefined,\n projectDir: string,\n log: ReturnType<typeof createLogger>,\n): LoadedPromptExtension[] {\n if (!paths?.length) return [];\n const result: LoadedPromptExtension[] = [];\n for (const relPath of paths) {\n const absPath = resolvePath(projectDir, relPath);\n if (!existsSync(absPath)) {\n log.warn(\"prompt-extension file not found\", { relPath });\n continue;\n }\n try {\n const content = readFileSync(absPath, \"utf-8\").trim();\n if (content.length > 0) result.push({ value: content, source: relPath });\n } catch (err) {\n log.warn(\"could not read prompt-extension\", {\n relPath,\n error: (err as Error).message,\n });\n }\n }\n return result;\n}\n\n/**\n * Resolve the agent composition (`composes:` field) when an agentDir is\n * available. Returns inline blocks (injected into the system prompt) and\n * discoverable entries (registered with the CapabilityRegistry by the caller).\n * Returns null when the agent has no composition or no agentDir is available.\n */\nasync function resolveSessionComposition(\n agentDir: string | undefined,\n manifest: AgentManifest | undefined,\n projectDir: string,\n log: ReturnType<typeof createLogger>,\n): Promise<ResolvedComposition | null> {\n if (agentDir && manifest?.composes?.length) {\n return resolveAgentComposition({\n agentDir,\n manifest,\n projectDir,\n log,\n });\n }\n if (manifest?.composes?.length && !agentDir) {\n log.debug(\"skipping composition resolution — no agentDir available\");\n }\n return null;\n}\n\n/**\n * Build the labeled per-section breakdown of the system prompt. Order matches\n * the assembleSystemPrompt input; assembleSystemPrompt filters falsies, so we\n * mirror that here and only emit non-empty sections.\n */\nfunction buildSystemPromptSections(parts: {\n contextSection: string | undefined;\n userPromptSection: string | undefined;\n environmentSection: string | undefined;\n resourcePromptSection: string | undefined;\n mcpPromptSection: string | undefined;\n promptExtensions: LoadedPromptExtension[];\n compositionBlocks: ResolvedComposition[\"inlineBlocks\"];\n additionalSections: string[];\n}): SystemPromptSection[] {\n const {\n contextSection,\n userPromptSection,\n environmentSection,\n resourcePromptSection,\n mcpPromptSection,\n promptExtensions,\n compositionBlocks,\n additionalSections,\n } = parts;\n const systemPromptSections: SystemPromptSection[] = [];\n if (contextSection) systemPromptSections.push({ label: \"context\", value: contextSection });\n if (userPromptSection) systemPromptSections.push({ label: \"prompt\", value: userPromptSection });\n if (environmentSection)\n systemPromptSections.push({ label: \"environment\", value: environmentSection });\n if (resourcePromptSection)\n systemPromptSections.push({ label: \"resources\", value: resourcePromptSection });\n if (mcpPromptSection)\n systemPromptSections.push({ label: \"mcp-guidance\", value: mcpPromptSection });\n for (const ext of promptExtensions) {\n systemPromptSections.push({\n label: \"prompt-extensions\",\n value: ext.value,\n source: ext.source,\n });\n }\n for (const block of compositionBlocks) {\n // InlineBlock (composition/types.ts) carries `ref` as the identifying field\n // (asset ref string like \"skill:foo\" or \"agent:bar\"); no separate `id`/`source` field.\n systemPromptSections.push({\n label: \"composition\",\n value: block.content,\n source: block.ref,\n });\n }\n additionalSections.forEach((value, idx) => {\n // additionalPromptSections is string[] today — no per-entry source label\n // available, so we synthesize a stable index-based descriptor.\n systemPromptSections.push({\n label: \"additional\",\n value,\n source: `additional[${idx}]`,\n });\n });\n return systemPromptSections;\n}\n\n/**\n * Log the assembled system prompt so it can be inspected via container logs.\n * No secrets flow through this string: API keys live in `apiKeys`, connector\n * credentials are resolved by the secret provider. Set SKAILE_LOG_SYSTEM_PROMPT=0\n * to suppress.\n */\nfunction logAssembledSystemPrompt(\n systemPrompt: string | undefined,\n log: ReturnType<typeof createLogger>,\n): void {\n if (process.env.SKAILE_LOG_SYSTEM_PROMPT !== \"0\") {\n const length = systemPrompt?.length ?? 0;\n log.debug(\"assembled system prompt\", { length });\n log.debug(\"system prompt content\", { content: systemPrompt ?? \"(empty)\" });\n }\n}\n\n/**\n * Create the agent driver (NOT started). Driver CWD is the agent working\n * directory (may differ from the config root). Forwards the resolved\n * provider/model/turns/identity plus optional protocol-v2 capability hooks.\n */\nfunction createSessionDriver(args: {\n config: AgentSessionConfig;\n driverType: string;\n agentCwd: string;\n provider: string | undefined;\n model: string | undefined;\n manifest: AgentManifest | undefined;\n maxTurns: number | undefined;\n apiKey: string | undefined;\n systemPrompt: string | undefined;\n thinking: AgentSessionConfig[\"thinking\"];\n effort: AgentSessionConfig[\"effort\"];\n sessionId: string | undefined;\n resumeSessionId: string | undefined;\n mcpServers: Record<string, unknown> | undefined;\n agentDir: string | undefined;\n}): ReturnType<typeof createDriver> {\n const {\n config,\n driverType,\n agentCwd,\n provider,\n model,\n manifest,\n maxTurns,\n apiKey,\n systemPrompt,\n thinking,\n effort,\n sessionId,\n resumeSessionId,\n mcpServers,\n agentDir,\n } = args;\n return createDriver(driverType, {\n cwd: agentCwd,\n provider,\n model: model ?? manifest?.model?.preferred,\n maxTurns,\n apiKeys: apiKey ? { [provider ?? \"anthropic\"]: apiKey } : undefined,\n systemPrompt,\n tools: manifest?.tools,\n ...(thinking ? { thinking } : {}),\n ...(effort ? { effort } : {}),\n ...(sessionId ? { sessionId } : {}),\n ...(resumeSessionId ? { resumeSessionId } : {}),\n ...(mcpServers ? { mcpServers } : {}),\n // Protocol v2 capability dispatch hooks. When provided, the driver builds\n // a synthetic `skaile-capabilities` MCP server alongside any existing\n // mcpServers so capability invocations route through the registry's\n // `invoke()` (which logs + validates + handles fire-and-forget / render).\n ...(config.capabilities ? { capabilities: config.capabilities } : {}),\n ...(config.aiProviderConfigId ? { aiProviderConfigId: config.aiProviderConfigId } : {}),\n ...(config.onAuthError ? { onAuthError: config.onAuthError } : {}),\n // Always forward agentDir/agentName for native identity handling\n ...(agentDir ? { agentDir, agentName: manifest?.name } : {}),\n });\n}\n","/**\n * agent.ts\n *\n * Single-shot agent chat — runs a driver session without a flow.\n * Useful for ad-hoc tasks and skill invocations.\n *\n * The interactive REPL lives at @skaile/workspaces/tui (startRepl).\n */\n\nimport type { AgentEvent, AgentMessage } from \"@skaile/workspaces/bridge\";\nimport { resolveAgentDir } from \"@skaile/workspaces/core\";\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\nimport pc from \"picocolors\";\nimport { bootstrapRunnerLogStore } from \"./logging-bootstrap.js\";\nimport { MarkdownStreamer } from \"./markdown-stream.js\";\nimport { type AgentSession, createAgentSession } from \"./session-builder.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Options for the agent REPL session (legacy).\n *\n * @docLink packages/runner/dev-guide#agent-chat-single-shot\n */\nexport interface AgentReplOptions {\n /** GitAgent definition directory (SOUL.md, RULES.md, knowledge/) */\n agentDir?: string;\n /** Project working directory for the agent */\n projectDir: string;\n /** Bridge driver: 'omp' | 'claude-sdk' | 'codex' (default: 'omp') */\n driver?: string;\n /** LLM model override */\n model?: string;\n /** LLM provider override */\n provider?: string;\n /** Path to settings.json for API key resolution */\n settingsFile?: string;\n /** Called for every raw agent event */\n onEvent?: (event: AgentEvent) => void;\n /** Called for log lines */\n onLog?: (line: string) => void;\n /** Prompts directory for deployed command files */\n promptsDir?: string;\n}\n\n/**\n * Options for a single-shot agent chat session.\n *\n * @docLink packages/runner/dev-guide#agent-chat-single-shot\n */\nexport interface AgentChatOptions extends AgentReplOptions {\n /** The message to send */\n message: string;\n /** Optional skill ID — if provided, the skill prompt is prepended */\n skill?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Extract printable text from an AgentMessage content field. */\nfunction _extractText(msg: AgentMessage | undefined): string {\n if (!msg) return \"\";\n if (typeof msg.content === \"string\") return msg.content;\n if (Array.isArray(msg.content)) {\n return msg.content\n .filter((b) => b.type === \"text\" && b.text)\n .map((b) => b.text!)\n .join(\"\");\n }\n return \"\";\n}\n\n// ---------------------------------------------------------------------------\n// Styling\n// ---------------------------------------------------------------------------\n\nconst PROMPT_AGENT = `${pc.magenta(pc.bold(\"agent\"))} ${pc.dim(\"▶\")} `;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Send a single message to an agent and wait for the response.\n * Prints agent output to stdout, then exits.\n * @docLink packages/runner/dev-guide#agent-chat-single-shot\n */\nexport async function runAgentChat(opts: AgentChatOptions): Promise<void> {\n const sessionId = `chat-${Date.now().toString(36)}`;\n const { dispose: disposeLogStore } = bootstrapRunnerLogStore({\n sessionId,\n projectDir: opts.projectDir,\n onLog: opts.onLog,\n });\n const chatLog = createLogger({\n kind: \"runner\",\n subkind: \"session\",\n instance: sessionId,\n });\n // Diagnostic emission goes through chatLog. The user-facing markdown stream\n // and PROMPT_AGENT prefix continue to write directly to stdout — they are\n // agent output, not diagnostics.\n const agentSession = await buildDriver(opts);\n const driver = agentSession.driver;\n\n await driver.start();\n\n let firstChunk = true;\n const mdStream = new MarkdownStreamer();\n driver.on(\"agent-event\", (event: AgentEvent) => {\n opts.onEvent?.(event);\n if (event.type === \"message_update\") {\n const delta = (event as any)._textDelta;\n if (delta) {\n if (firstChunk) {\n process.stdout.write(PROMPT_AGENT);\n firstChunk = false;\n }\n mdStream.write(delta);\n }\n }\n });\n\n let message = opts.message;\n if (opts.skill) {\n message = `Skill: ${opts.skill}\\n\\n${message}`;\n }\n\n try {\n await new Promise<void>((resolve, reject) => {\n const onEvent = (event: AgentEvent) => {\n if (event.type === \"agent_end\") {\n driver.off(\"agent-event\", onEvent);\n mdStream.end();\n process.stdout.write(\"\\n\");\n driver.kill();\n resolve();\n } else if (event.type === \"error\") {\n driver.off(\"agent-event\", onEvent);\n const err = new Error(String((event as any).error));\n chatLog.error(\"agent emitted error event\", err);\n driver.kill();\n reject(err);\n }\n };\n driver.on(\"agent-event\", onEvent);\n driver.prompt(message).catch((err: Error) => {\n driver.off(\"agent-event\", onEvent);\n chatLog.error(\"prompt failed\", err);\n driver.kill();\n reject(err);\n });\n });\n } finally {\n await agentSession.dispose();\n disposeLogStore();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal\n// ---------------------------------------------------------------------------\n\n// buildDriver is a thin wrapper — all setup logic lives in createAgentSession.\n// agentDir/agentName are always forwarded to the driver for native identity handling\n// (omp: PI_CODING_AGENT_DIR, claude-sdk: agent option).\nasync function buildDriver(opts: AgentReplOptions): Promise<AgentSession> {\n const agentDir = opts.agentDir ?? resolveAgentDir(opts.projectDir);\n return createAgentSession({\n projectDir: opts.projectDir,\n agentDir,\n driver: opts.driver,\n model: opts.model,\n provider: opts.provider,\n promptsDir: opts.promptsDir,\n onLog: opts.onLog,\n });\n}\n","/**\n * Built-in framework capabilities. The runner registers these at boot via\n * {@link bootstrapCapabilityRegistry} so the LLM always has a discovery\n * surface for what is available in the session.\n *\n * All built-ins are agent-side, `origin: { kind: 'framework' }`, and\n * synchronous queries against the registry — they have no side-effects\n * outside the registry itself.\n *\n * @category Runtime\n * @since 2.0.0\n */\n\nimport type { Capability } from \"@skaile/workspaces/types\";\nimport * as z from \"zod\";\nimport type { CapabilityRegistry } from \"./capability-registry.js\";\nimport { type DefinedCapability, defineCapability } from \"./define-capability.js\";\n\n/**\n * Tokenize a free-text query and rank capabilities by case-insensitive\n * substring match count across `name`, `description`, and `promptFragment`.\n * Returns the top `limit` results, descending by score.\n */\nfunction keywordSearch(capabilities: Capability[], query: string, limit: number): Capability[] {\n const tokens = query\n .toLowerCase()\n .split(/\\s+/)\n .filter((t) => t.length > 0);\n if (tokens.length === 0) return capabilities.slice(0, limit);\n\n const scored = capabilities\n .map((cap) => {\n const haystack = [cap.name, cap.description, cap.promptFragment ?? \"\"]\n .join(\" \")\n .toLowerCase();\n let score = 0;\n for (const token of tokens) {\n if (haystack.includes(token)) score += 1;\n }\n return { cap, score };\n })\n .filter((x) => x.score > 0)\n .sort((a, b) => b.score - a.score);\n\n return scored.slice(0, limit).map((x) => x.cap);\n}\n\n/**\n * Build the three built-in discovery capabilities. They close over the\n * registry so the handlers stay in sync with mid-session register /\n * deregister events.\n *\n * @category Runtime\n * @since 2.0.0\n * @docLink packages/runner/capabilities#built-in-discovery-capabilities\n */\nexport function builtinCapabilities(registry: CapabilityRegistry): DefinedCapability[] {\n const listFilterSchema = z.strictObject({\n side: z.enum([\"client\", \"agent\"]).optional(),\n originKind: z\n .enum([\"framework\", \"client\", \"agent\", \"flow\", \"skill\", \"mcp\", \"connector\", \"mount\"])\n .optional(),\n scope: z.enum([\"session\", \"turn\"]).optional(),\n });\n return [\n defineCapability({\n name: \"__capabilities.list\",\n displayName: \"List capabilities\",\n description:\n \"List available capabilities in this session. Optionally filter by side, origin kind, or scope.\",\n side: \"agent\",\n origin: { kind: \"framework\" },\n kind: \"query\",\n userInvokable: false,\n input: listFilterSchema,\n handler: async (args) =>\n registry.list({\n side: args.side,\n origin: args.originKind,\n scope: args.scope,\n }),\n }),\n defineCapability({\n name: \"__capabilities.search\",\n displayName: \"Search capabilities\",\n description:\n \"Keyword search across capability names, descriptions, and prompt fragments. Returns the top matches by score (substring match count).\",\n side: \"agent\",\n origin: { kind: \"framework\" },\n kind: \"query\",\n userInvokable: false,\n input: z.strictObject({\n query: z.string(),\n limit: z.number().int().positive().optional(),\n }),\n handler: async ({ query, limit }) => keywordSearch(registry.list(), query, limit ?? 10),\n }),\n defineCapability({\n name: \"__capabilities.describe\",\n displayName: \"Describe capability\",\n description: \"Return the full Capability descriptor for a single capability by name.\",\n side: \"agent\",\n origin: { kind: \"framework\" },\n kind: \"query\",\n userInvokable: false,\n input: z.strictObject({ name: z.string() }),\n handler: async ({ name }) => {\n const cap = registry.resolve(name);\n if (!cap) return null;\n // Strip runtime-only fields by going through the wire-format `list`\n // and finding-by-name; cheaper than another method on the registry.\n const wire = registry.list().find((c) => c.name === name);\n return wire ?? null;\n },\n }),\n ];\n}\n\n/**\n * Register all framework built-ins onto a registry. Idempotent — the\n * registry's `register` is keyed by name and overwrites prior entries with\n * the same name.\n *\n * @category Runtime\n * @since 2.0.0\n * @docLink packages/runner/capabilities#built-in-discovery-capabilities\n */\nexport function bootstrapCapabilityRegistry(registry: CapabilityRegistry): void {\n for (const cap of builtinCapabilities(registry)) {\n registry.register(cap, \"agent\");\n }\n}\n","/**\n * `CapabilityRegistry` — single per-session registry of {@link Capability}s.\n *\n * The registry is the source of truth for everything the LLM can invoke\n * during a session. Both the platform (via `ConfigureCommand.capabilities`\n * and {@link CapabilityRegisterCommand}) and the runtime (skill loaders,\n * flow adapters, MCP/connector/mount surfaces) call {@link register}; the\n * bridge driver pulls the LLM tool list via {@link composeLLMTools}.\n *\n * Trust enforcement: each call to {@link register} carries the registering\n * `source` (`'client'` or `'agent'`); the registry rejects mismatches such\n * as the agent claiming a `'client'` origin or vice-versa, logging a warning\n * and dropping the capability.\n *\n * Per-invocation logging: {@link invoke} constructs a\n * `createLogger({kind: 'capability', subkind: origin.kind, instance: name})`\n * and threads it through {@link HandlerContext} so handler output lands under\n * the `capability:<origin>:<name>` slice.\n *\n * Hibernation: {@link serialize} / {@link hydrate} round-trip the wire-format\n * capabilities. Agent-side capabilities (skill / flow / mcp / connector /\n * mount) are expected to re-register from their original sources on wake;\n * client-side capabilities are pushed back via\n * {@link ConfigureCommandV2 ConfigureCommand} from the platform.\n *\n * @category Runtime\n * @since 2.0.0\n */\nimport { createHash } from \"node:crypto\";\nimport { createLogger } from \"@skaile/workspaces/core/logging\";\nimport type {\n Capability,\n CapabilityAudience,\n CapabilityOrigin,\n Logger,\n} from \"@skaile/workspaces/types\";\nimport type { DefinedCapability, HandlerContext } from \"./define-capability.js\";\n\n/**\n * Default audience scope applied when a {@link Capability} omits `audience`.\n * Matches the v2.x behaviour where every registered capability appears in\n * both the LLM tool list and the command palette.\n */\nconst DEFAULT_AUDIENCE: readonly CapabilityAudience[] = [\"llm\", \"user\"];\n\nfunction audienceOf(cap: Capability): readonly CapabilityAudience[] {\n return cap.audience ?? DEFAULT_AUDIENCE;\n}\n\nfunction hasAudience(cap: Capability, target: CapabilityAudience): boolean {\n return audienceOf(cap).includes(target);\n}\n\n/**\n * Function shape for the platform-bound capability invoker.\n *\n * The runner uses this to dispatch `host.*` capability invocations (e.g.\n * `host.refresh_credential`, `host.audit`, `host.notify_user`) over the\n * transport and await the matching `CapabilityResultCommand`. Implementations\n * own the wire serialization and the per-call pending map.\n *\n * The result value is the capability's domain payload (already\n * deserialised; for `host.refresh_credential` this is a `CredentialMint`).\n * Capability-dispatch infrastructure failures (timeout, schema validation,\n * transport disconnect) are thrown as `Error` so callers can distinguish\n * them from domain failures encoded in the payload.\n *\n * @category Runtime\n * @since 3.0.0\n * @docLink packages/runner/capabilities#remote-invoker\n */\nexport type RemoteCapabilityInvoker = (\n name: string,\n input: unknown,\n timeoutMs?: number,\n) => Promise<unknown>;\n\n/**\n * Minimal LLM tool descriptor consumed by bridge drivers. Drivers translate\n * this into the provider-specific tool spec (Claude tool definition, OpenAI\n * function spec, etc.) at registration time.\n *\n * Only the fields needed for tool registration are surfaced here; runtime\n * dispatch flows through {@link CapabilityRegistry.invoke}.\n *\n * @category Runtime\n * @since 2.0.0\n * @docLink packages/runner/capabilities#registry-surface\n */\nexport type LLMTool = {\n /** Capability name; used as the LLM-visible tool name. */\n name: string;\n /** Human/LLM-readable description. */\n description: string;\n /** JSON Schema for the tool's input parameters. */\n parameters: Record<string, unknown>;\n};\n\n/**\n * Filter shape accepted by {@link CapabilityRegistry.list}. All fields are\n * optional and match exactly when present.\n *\n * @category Runtime\n * @since 2.0.0\n * @docLink packages/runner/capabilities#registry-surface\n */\nexport type CapabilityListFilter = {\n side?: \"client\" | \"agent\";\n origin?: CapabilityOrigin[\"kind\"];\n scope?: \"session\" | \"turn\";\n};\n\n/**\n * Side-tag declaring who is registering a capability. The registry uses\n * this to enforce origin trust — a client cannot register an `agent`-side\n * origin, and the agent cannot register `client` / external-origin\n * capabilities.\n *\n * @category Runtime\n * @since 2.0.0\n * @docLink packages/runner/capabilities#registry-surface\n */\nexport type RegisterSource = \"client\" | \"agent\";\n\nconst ORIGIN_PROMPT_ORDER: CapabilityOrigin[\"kind\"][] = [\n \"framework\",\n \"client\",\n \"agent\",\n \"flow\",\n \"skill\",\n \"mcp\",\n \"connector\",\n \"mount\",\n];\n\n/**\n * Per-session registry of capabilities. Construct one per\n * `startAgentServer` invocation; the runner threads it through serve mode's\n * command handlers and the bridge.\n *\n * @category Runtime\n * @since 2.0.0\n * @docLink packages/runner/capabilities#registry-surface\n */\nexport class CapabilityRegistry {\n private readonly byName = new Map<string, DefinedCapability>();\n private readonly logger: Logger;\n private remoteInvoker?: RemoteCapabilityInvoker;\n\n constructor(logger?: Logger) {\n this.logger = logger ?? createLogger({ kind: \"runner\", subkind: \"capability-registry\" });\n }\n\n /**\n * Install the platform-bound invoker used by {@link invokeRemote}.\n *\n * The runner wires this up after the transport is connected and the\n * per-session pending-call map is in place. Idempotent — repeated calls\n * replace the prior invoker.\n *\n * @category Runtime\n * @since 3.0.0\n */\n setRemoteInvoker(invoker: RemoteCapabilityInvoker | undefined): void {\n this.remoteInvoker = invoker;\n }\n\n /**\n * Invoke a `host.*` (or other peer-side) capability on the platform.\n *\n * Composes a `capability_invoked` event under the hood and resolves with\n * the matching `capability_result` payload. Infrastructure failures\n * (timeout, schema mismatch, transport disconnect) reject with `Error`;\n * domain failures (e.g. `{ ok: false, code }` for credential mints) ride\n * in the resolved payload.\n *\n * @category Runtime\n * @since 3.0.0\n */\n async invokeRemote(name: string, input: unknown): Promise<unknown> {\n if (!this.remoteInvoker) {\n throw new Error(\n `Capability '${name}' invoked remotely but no remote invoker is wired. ` +\n `Call CapabilityRegistry.setRemoteInvoker(...) before dispatch.`,\n );\n }\n // Honour a per-capability callTimeoutMs for outbound host.* calls,\n // mirroring the inbound resolveCapabilityCallTimeoutMs path.\n return this.remoteInvoker(name, input, this.byName.get(name)?.callTimeoutMs);\n }\n\n /**\n * Register a capability. Validates that the registering `source` is\n * permitted to declare the capability's `origin.kind`; mismatches are\n * dropped with a warning so untrusted callers cannot impersonate other\n * registration sources.\n *\n * Allowed combinations:\n * - source `'agent'`: origins `framework | agent | flow | skill | mcp | connector | mount`\n * - source `'client'`: origin `client` only\n *\n * @param cap - capability to register (typically built via {@link defineCapability})\n * @param source - which side is doing the registration\n */\n register(cap: DefinedCapability, source: RegisterSource): void {\n if (!this.isOriginAllowed(source, cap.origin)) {\n this.logger.warn(\"capability registration rejected (origin mismatch)\", {\n name: cap.name,\n source,\n originKind: cap.origin.kind,\n });\n return;\n }\n this.byName.set(cap.name, cap);\n this.logger.info(\"capability registered\", {\n name: cap.name,\n side: cap.side,\n originKind: cap.origin.kind,\n });\n }\n\n /**\n * Remove a capability by name. No-op when the name is unknown.\n *\n * @param name - capability name\n */\n deregister(name: string): void {\n if (this.byName.delete(name)) {\n this.logger.info(\"capability deregistered\", { name });\n }\n }\n\n /**\n * List capabilities, optionally filtering by `side`, `origin` kind, or\n * `scope`. Returns the wire-format {@link Capability} shape (no internal\n * Zod schemas or handlers).\n */\n list(filter?: CapabilityListFilter): Capability[] {\n const all = Array.from(this.byName.values());\n const matching = filter\n ? all.filter(\n (c) =>\n (filter.side === undefined || c.side === filter.side) &&\n (filter.origin === undefined || c.origin.kind === filter.origin) &&\n (filter.scope === undefined || c.scope === filter.scope),\n )\n : all;\n return matching.map((c) => this.toWire(c));\n }\n\n /**\n * Resolve a capability by name. Returns the full {@link DefinedCapability}\n * (including the original Zod schemas + handler) for use by the bridge.\n *\n * @returns the capability or `null` when the name is not registered\n */\n resolve(name: string): DefinedCapability | null {\n return this.byName.get(name) ?? null;\n }\n\n /**\n * Build LLM tool descriptors for every registered capability whose\n * audience includes `'llm'` (the default when {@link Capability.audience}\n * is omitted). Bridge drivers consume this output directly when\n * assembling the tool list passed to the underlying LLM SDK.\n *\n * Capabilities scoped to `'runtime'` only (e.g. `host.refresh_credential`,\n * `runner.add_mount`) are filtered out so they never reach the model.\n */\n composeLLMTools(): LLMTool[] {\n return Array.from(this.byName.values())\n .filter((c) => hasAudience(c, \"llm\"))\n .map((c) => ({\n name: c.name,\n description: c.description,\n parameters: c.inputSchema,\n }));\n }\n\n /**\n * Compose a deterministic prompt section from every registered\n * capability whose audience includes `'llm'`. Ordering matches\n * `ORIGIN_PROMPT_ORDER` (framework first, then client, then agent-side\n * surfaces) so the agent sees a stable layout. Capabilities without a\n * `promptFragment` are skipped.\n */\n composePromptSection(): string {\n const groups = new Map<CapabilityOrigin[\"kind\"], string[]>();\n for (const cap of this.byName.values()) {\n if (!cap.promptFragment) continue;\n if (!hasAudience(cap, \"llm\")) continue;\n const arr = groups.get(cap.origin.kind) ?? [];\n arr.push(cap.promptFragment);\n groups.set(cap.origin.kind, arr);\n }\n const lines: string[] = [];\n for (const kind of ORIGIN_PROMPT_ORDER) {\n const fragments = groups.get(kind);\n if (!fragments?.length) continue;\n for (const fragment of fragments) {\n lines.push(fragment);\n }\n }\n return lines.join(\"\\n\\n\");\n }\n\n /**\n * Serialize the registry to wire-format capabilities for hibernation. The\n * runtime fields (`inputZod`, `outputZod`, `handler`) are dropped; only\n * the wire shape is kept.\n */\n serialize(): Capability[] {\n return Array.from(this.byName.values()).map((c) => this.toWire(c));\n }\n\n /**\n * Replay a wire snapshot taken via {@link serialize}. Wire-only capabilities\n * (no handler) are stored so {@link list} / {@link composeLLMTools} return\n * a complete picture; agent-side surfaces are expected to re-register\n * fully (with handlers) from their original sources on wake.\n *\n * Per the v2 design, only `client`-side capabilities are persisted across\n * hibernation by this method — agent-side ones come back via the\n * skill / flow / connector / mount adapters. Snapshot entries from other\n * origins are skipped on hydrate.\n */\n hydrate(snapshot: Capability[]): void {\n for (const cap of snapshot) {\n if (cap.origin.kind !== \"client\") continue;\n const stub: DefinedCapability = {\n ...cap,\n inputZod: HYDRATED_PASSTHROUGH_ZOD,\n outputZod: undefined,\n handler: HYDRATED_REJECT_HANDLER,\n };\n this.byName.set(cap.name, stub);\n }\n this.logger.info(\"capability registry hydrated\", { count: snapshot.length });\n }\n\n /**\n * Invoke a registered capability. Validates the input against the Zod\n * schema, builds the per-handler logger, and runs the handler. Logs\n * `info \"invoking\"` and `info \"ok\"` (or `error \"failed\"`) under the\n * `capability:<origin>:<name>` slice for every call.\n *\n * @throws when the capability is unknown or the input fails validation\n */\n async invoke(\n name: string,\n input: unknown,\n baseCtx: Omit<HandlerContext, \"log\">,\n ): Promise<unknown> {\n const cap = this.resolve(name);\n if (!cap) {\n throw new Error(`Unknown capability: ${name}`);\n }\n const log = createLogger({\n kind: \"capability\",\n subkind: cap.origin.kind,\n instance: cap.name,\n });\n log.info(\"invoking\", { input });\n try {\n const validated = cap.inputZod.parse(input);\n const result = await cap.handler(validated, { ...baseCtx, log });\n log.info(\"ok\", { output: result });\n return result;\n } catch (err) {\n log.error(\"failed\", err);\n throw err;\n }\n }\n\n /** True when `source` is allowed to register the given `origin`. */\n private isOriginAllowed(source: RegisterSource, origin: CapabilityOrigin): boolean {\n if (source === \"client\") {\n return origin.kind === \"client\";\n }\n // source === 'agent'\n return origin.kind !== \"client\";\n }\n\n /** Strip the runtime-only fields from a {@link DefinedCapability}. */\n private toWire(cap: DefinedCapability): Capability {\n return {\n name: cap.name,\n displayName: cap.displayName,\n description: cap.description,\n inputSchema: cap.inputSchema,\n outputSchema: cap.outputSchema,\n side: cap.side,\n origin: cap.origin,\n scope: cap.scope,\n fireAndForget: cap.fireAndForget,\n requiresApproval: cap.requiresApproval,\n kind: cap.kind,\n userInvokable: cap.userInvokable,\n audience: cap.audience,\n promptFragment: cap.promptFragment,\n callTimeoutMs: cap.callTimeoutMs,\n render: cap.render,\n };\n }\n}\n\n/**\n * Compute a deterministic signature over a registry's wire-format\n * capabilities. Used by the session-resume cascade (tier-1 native SDK\n * resume) to detect toolset drift between hibernate and wake.\n *\n * The signature hashes a canonicalized projection of each capability:\n * `name + origin.kind + sha256(inputSchema)`. Capabilities are sorted\n * by `name` so registration order does not affect the result.\n *\n * Excluded from the hash:\n * - `displayName` and `userInvokable` — UI metadata only; do not affect\n * what the LLM can call.\n * - `description` and `outputSchema` — text/shape changes that don't\n * alter the call surface.\n *\n * Spec: `_devlog/specs/2026-05-05-session-resume-restart-design.md`\n * § \"Capability signature\".\n *\n * @param caps - Wire-format capabilities from {@link CapabilityRegistry.list}.\n * @returns A hex SHA-256 string that uniquely identifies the toolset.\n * @category Resume\n * @since 3.2.0\n * @docLink packages/runner/capabilities#compute-capability-signature\n */\nexport function computeCapabilitySignature(caps: readonly Capability[]): string {\n const canonical = caps\n .slice()\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((c) => ({\n name: c.name,\n origin: c.origin.kind,\n schemaSha256: sha256(JSON.stringify(c.inputSchema ?? {})),\n }));\n return sha256(JSON.stringify(canonical));\n}\n\nfunction sha256(input: string): string {\n return createHash(\"sha256\").update(input).digest(\"hex\");\n}\n\n// Sentinel Zod schema used by `hydrate()` to keep the wire-format snapshot\n// usable for `list`/`composeLLMTools` without forcing real handler reattach\n// at hibernate-restore time. Actual invocation must go through a re-registered\n// capability that comes back via `ConfigureCommand.capabilities` on wake.\nconst HYDRATED_PASSTHROUGH_ZOD: import(\"zod\").ZodTypeAny = {\n parse: (v: unknown) => v,\n // The full Zod surface is not required here — `parse` is the only method\n // used by `invoke`, and hydrated stubs are not expected to be invoked\n // before the platform resends the live capability via configure.\n} as unknown as import(\"zod\").ZodTypeAny;\n\nconst HYDRATED_REJECT_HANDLER = async (): Promise<never> => {\n throw new Error(\n \"Hydrated capability stub cannot be invoked — re-register via ConfigureCommand on wake.\",\n );\n};\n","/**\n * Client-side capability round-trip helpers.\n *\n * When the LLM invokes a `side: 'client'` capability, the runner does NOT\n * execute the handler in-process. Instead it:\n *\n * 1. Generates a `callId`.\n * 2. Emits a {@link CapabilityInvokedEvent} over the transport.\n * 3. Registers a pending promise keyed by `callId`.\n * 4. Awaits a {@link CapabilityResultCommand} from the platform; resolves\n * with `result` or rejects with `result.error`.\n *\n * `fireAndForget` short-circuits step 3 — the handler resolves with `{}`\n * immediately after emitting the invoke event. The bridge-level dispatch\n * also short-circuits before calling `hooks.invoke()`, so this is a\n * defence-in-depth guard.\n *\n * The helpers below are extracted for unit testing; the actual wiring\n * lives in `serve.ts` where the transport / pending map are owned.\n *\n * @category Capabilities\n * @since 2.0.0\n */\nimport type { AgentEvent, Capability, CapabilityResultCommand } from \"@skaile/workspaces/types\";\n\n/**\n * Registry of in-flight capability calls. The serve loop owns the map; this\n * type is exported so tests can pass a real `Map` instance and assert the\n * pending state across the round-trip.\n * @docLink packages/runner/capabilities#registry-surface\n */\nexport type PendingCallEntry = {\n resolve: (value: unknown) => void;\n reject: (err: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n};\n\n/**\n * Default timeout (60s) for waiting on a capability result from the platform.\n * Mirrors the value used in `serve.ts`.\n *\n * @docLink packages/runner/capabilities#registry-surface\n */\nexport const DEFAULT_CAPABILITY_CALL_TIMEOUT_MS = 60_000;\n\n/**\n * Resolve the round-trip timeout for a wire-format client capability.\n *\n * Precedence:\n * 1. An explicit per-capability `callTimeoutMs` — set for capabilities that\n * legitimately block far longer than a normal tool call (e.g.\n * `platform.ask_session`, which suspends the caller's turn until a peer\n * session answers).\n * 2. `approvalTimeoutMs` when the capability is `requiresApproval` — human\n * approvals routinely take minutes.\n * 3. `DEFAULT_CAPABILITY_CALL_TIMEOUT_MS` (60s) otherwise.\n *\n * Extracted as a pure function so the precedence is unit-testable without\n * spinning up `startAgentServer`.\n *\n * @docLink packages/runner/capabilities#registry-surface\n */\nexport function resolveCapabilityCallTimeoutMs(\n cap: Pick<Capability, \"callTimeoutMs\" | \"requiresApproval\">,\n approvalTimeoutMs: number,\n): number {\n if (typeof cap.callTimeoutMs === \"number\") return cap.callTimeoutMs;\n if (cap.requiresApproval) return approvalTimeoutMs;\n return DEFAULT_CAPABILITY_CALL_TIMEOUT_MS;\n}\n\n/**\n * Build the runner-side handler for a wire-format client capability. The\n * returned function emits `capability_invoked` and waits for a matching\n * `capability_result` command via the supplied pending-calls map.\n *\n * Decoupled from `serve.ts` so it can be exercised in isolation without\n * spinning up `startAgentServer`.\n * @docLink packages/runner/capabilities#registry-surface\n */\nexport function buildClientCapabilityHandler(args: {\n wire: Capability;\n pending: Map<string, PendingCallEntry>;\n emit: (event: AgentEvent) => void;\n timeoutMs?: number;\n /** Override the callId factory for deterministic tests. */\n generateCallId?: () => string;\n}): (input: unknown) => Promise<unknown> {\n const timeoutMs = args.timeoutMs ?? DEFAULT_CAPABILITY_CALL_TIMEOUT_MS;\n const gen = args.generateCallId ?? (() => `cap-${Date.now()}-${Math.floor(Math.random() * 1e9)}`);\n return async (input: unknown) => {\n const callId = gen();\n if (args.wire.fireAndForget) {\n args.emit({\n type: \"capability_invoked\",\n callId,\n name: args.wire.name,\n input,\n invokedBy: \"agent\",\n });\n return {};\n }\n return new Promise<unknown>((resolve, reject) => {\n const timer = setTimeout(() => {\n args.pending.delete(callId);\n reject(\n new Error(\n `Capability ${args.wire.name} (callId=${callId}) timed out after ${timeoutMs}ms`,\n ),\n );\n }, timeoutMs);\n args.pending.set(callId, { resolve, reject, timer });\n args.emit({\n type: \"capability_invoked\",\n callId,\n name: args.wire.name,\n input,\n invokedBy: \"agent\",\n });\n });\n };\n}\n\n/**\n * Handle a platform→runner `capability_invoked` command: invoke the named\n * capability through the registry and emit a single `capability_result`\n * reply. The inbound mirror of {@link buildClientCapabilityHandler} (the\n * runner→platform direction). A thrown error — unknown capability or Zod\n * validation failure — rides back as `{ error }` so the gateway rejects the\n * caller; a handler's own structured `{ ok: false }` result rides back\n * verbatim (the gateway resolves it). Decoupled from `startAgentServer` for\n * unit testability — the serve loop calls this with `invoke = registry.invoke`\n * and `emit = sendEvent`.\n */\nexport async function dispatchRunnerCapabilityInvocation(\n cmd: { callId: string; name: string; input: unknown },\n deps: {\n invoke: (name: string, input: unknown) => Promise<unknown>;\n emit: (event: { type: \"capability_result\"; callId: string; result: unknown }) => void;\n },\n): Promise<void> {\n try {\n const result = await deps.invoke(cmd.name, cmd.input);\n deps.emit({ type: \"capability_result\", callId: cmd.callId, result });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n deps.emit({ type: \"capability_result\", callId: cmd.callId, result: { error: message } });\n }\n}\n\n/**\n * Resolve / reject a pending capability call based on a `capability_result`\n * command from the platform. Returns `true` when the callId matched a\n * pending entry, `false` otherwise (for telemetry / debug logging).\n * @docLink packages/runner/capabilities#registry-surface\n */\nexport function resolveCapabilityResult(\n pending: Map<string, PendingCallEntry>,\n cmd: CapabilityResultCommand,\n): boolean {\n const entry = pending.get(cmd.callId);\n if (!entry) return false;\n clearTimeout(entry.timer);\n pending.delete(cmd.callId);\n const result = cmd.result;\n if (result && typeof result === \"object\" && \"error\" in result) {\n entry.reject(new Error(String((result as { error: unknown }).error)));\n } else {\n entry.resolve(result);\n }\n return true;\n}\n\n/**\n * Reject a pending capability call when the platform sends a\n * `capability_approve` with `decision: 'rejected'`. Used by capabilities\n * declared `requiresApproval: true` — the platform shows a confirm UI on\n * `capability_invoked`; on user denial it forwards the rejection back to the\n * runner via this command instead of dispatching the handler.\n *\n * Returns `true` when the callId matched a pending entry, `false` otherwise\n * (e.g. the call was already resolved via `capability_result`).\n *\n * Approvals (`decision: 'approved'`) are no-ops at this level — the platform\n * still drives dispatch and replies via `capability_result`. This function\n * only handles the rejection short-circuit.\n *\n * @param pending - Map of in-flight capability calls keyed by `callId`.\n * @param callId - ID of the call being denied.\n * @param feedback - Optional user-facing feedback message passed to the rejection error.\n * @returns `true` when the call was found and rejected; `false` when already resolved.\n * @category Capabilities\n * @since 2.1.0\n * @docLink packages/runner/capabilities#reject-capability-on-approval-deny\n */\nexport function rejectCapabilityOnApprovalDeny(\n pending: Map<string, PendingCallEntry>,\n callId: string,\n feedback?: string,\n): boolean {\n const entry = pending.get(callId);\n if (!entry) return false;\n clearTimeout(entry.timer);\n pending.delete(callId);\n entry.reject(new Error(feedback ?? \"declined by user\"));\n return true;\n}\n","/**\n * resource-handler.ts — handles resource_request commands from the frontend.\n *\n * Dispatches list/read/write/delete/search operations to the ConnectorManager.\n * Tool-face connectors are served through the manager's CRUD dispatch;\n * filesystem-face (mountable) connectors are served directly from their\n * projected mount directory. Emits resource_response events back through the\n * transport.\n */\n\nimport {\n mkdirSync,\n readdirSync,\n readFileSync,\n rmSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { basename, dirname, isAbsolute, join, relative, resolve, sep } from \"node:path\";\nimport type { AuthoritativeSizeProvider, ConnectorManager } from \"@skaile/workspaces/connectors\";\nimport type {\n AgentEvent,\n ConnectorContent,\n ConnectorRequestCommand,\n} from \"@skaile/workspaces/types\";\nimport mime from \"mime\";\n\n// ---------------------------------------------------------------------------\n// Connector resource handler\n// ---------------------------------------------------------------------------\n\n/**\n * Handle a resource_request command by dispatching to the ConnectorManager\n * and emitting a resource_response event.\n * @docLink packages/runner/dev-guide#flow-execution-turn-based-model\n */\nexport async function handleResourceRequest(\n command: ConnectorRequestCommand,\n manager: ConnectorManager,\n emit: (event: AgentEvent) => void,\n): Promise<void> {\n const { requestId, connectorId, operation, path, options, content } = command;\n\n try {\n let data: unknown;\n switch (operation) {\n case \"list\":\n data = await manager.list(\n connectorId,\n path,\n options as import(\"@skaile/workspaces/connectors\").ListOptions | undefined,\n );\n break;\n case \"read\":\n data = await manager.read(connectorId, path!);\n break;\n case \"write\":\n await manager.write(connectorId, path!, content!);\n data = true;\n break;\n case \"delete\":\n data = await manager.delete(connectorId, path!);\n break;\n case \"search\":\n data = await manager.search(\n connectorId,\n path!,\n options as import(\"@skaile/workspaces/connectors\").SearchOptions | undefined,\n );\n break;\n }\n emit({ type: \"resource_response\", requestId, resourceId: connectorId, operation, data });\n } catch (err) {\n emit({\n type: \"resource_response\",\n requestId,\n resourceId: connectorId,\n operation,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Mountable-connector resource handler — serves list/read/write from the\n// projected mount directory of a filesystem-face connector.\n// ---------------------------------------------------------------------------\n\n/** Resolve MIME type for a filename. Falls back to application/octet-stream. */\nfunction getMimeType(filename: string): string {\n return mime.getType(filename) ?? \"application/octet-stream\";\n}\n\n/**\n * Returns true if the buffer should be served as base64-encoded binary.\n *\n * Uses a byte-level heuristic: checks the first 8KB for null bytes. This\n * correctly handles all code/config formats regardless of MIME type.\n */\nfunction isBinaryBuffer(buf: Buffer): boolean {\n const limit = Math.min(buf.length, 8192);\n for (let i = 0; i < limit; i++) {\n if (buf[i] === 0) return true;\n }\n return false;\n}\n\n/**\n * Resolve the optional authoritative-size hook a filesystem-face connector may\n * attach to its `handle.state` (rclone-backed mounts wire it to\n * `RcloneProcessManager.statSize`). Returns `undefined` when the mount does not\n * expose one — local mounts, fleet-managed mounts without an in-container rc\n * server, etc. — so the read path stays fully synchronous for those.\n */\nfunction getAuthoritativeSize(\n state: unknown,\n): ((relPath: string) => Promise<number | null>) | undefined {\n const provider = state as Partial<AuthoritativeSizeProvider> | null | undefined;\n return typeof provider?.authoritativeSize === \"function\"\n ? (relPath) => provider.authoritativeSize!(relPath)\n : undefined;\n}\n\n/**\n * Handle a resource request against a filesystem-face (mountable) connector.\n *\n * @docLink packages/runner/dev-guide#flow-execution-turn-based-model\n */\nexport async function handleMountResourceRequest(\n command: ConnectorRequestCommand,\n manager: ConnectorManager,\n emit: (event: AgentEvent) => void,\n): Promise<void> {\n const { requestId, connectorId: mountId, operation, path: reqPath, options, content } = command;\n\n try {\n const entry = manager.get(mountId);\n const mountPath = entry.handle.mountPath;\n if (!mountPath) {\n throw new Error(`Connector \"${mountId}\" has no projected mount directory`);\n }\n const targetPath = reqPath ? resolve(mountPath, reqPath) : mountPath;\n\n // Safety: prevent path traversal outside mount. A prefix check would let a\n // sibling sharing a string prefix (mount /data/mount vs /data/mount-secrets)\n // escape, so use a boundary-aware path.relative() check.\n const rel = relative(mountPath, targetPath);\n if (rel === \"..\" || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {\n throw new Error(\"Path traversal outside mount\");\n }\n\n let data: unknown;\n switch (operation) {\n case \"list\": {\n // Honor `options.recursive`: the platform's folder-rename copies a folder\n // by listing it recursively then copying each file. Without recursion the\n // mount would report only top-level entries and nested subfolders would be\n // silently dropped from the copy.\n const recursive = Boolean((options as { recursive?: boolean } | undefined)?.recursive);\n const collected: Record<string, unknown>[] = [];\n const walk = (absDir: string, relDir: string): void => {\n for (const e of readdirSync(absDir, { withFileTypes: true })) {\n if (e.name.startsWith(\".\")) continue;\n const entryRel = relDir ? `${relDir}/${e.name}` : e.name;\n const isDir = e.isDirectory();\n const result: Record<string, unknown> = {\n name: e.name,\n path: entryRel,\n type: isDir ? \"directory\" : \"file\",\n };\n if (!isDir) {\n try {\n result.size = statSync(join(absDir, e.name)).size;\n } catch {\n /* best-effort */\n }\n }\n collected.push(result);\n if (isDir && recursive) walk(join(absDir, e.name), entryRel);\n }\n };\n walk(targetPath, reqPath ?? \"\");\n data = collected;\n break;\n }\n case \"read\": {\n const contentType = getMimeType(basename(targetPath));\n const buf = readFileSync(targetPath);\n\n // Defeat the rclone VFS non-truncated stale tail: when a remote file is\n // replaced by a shorter version, rclone can serve `[new bytes][leftover\n // tail]` and report the inflated size, so the on-disk length is not\n // trustworthy. When the mount exposes an authoritative remote size\n // (via operations/stat), gate the served bytes to it. Slicing a Buffer\n // is byte-correct; decoding to utf-8 must happen *after* the slice.\n let bytes = buf;\n const sizeFn = getAuthoritativeSize(entry.handle.state);\n if (sizeFn) {\n const authSize = await sizeFn(reqPath ?? \"\");\n if (authSize !== null && authSize >= 0 && authSize < buf.length) {\n bytes = buf.subarray(0, authSize);\n }\n }\n\n if (isBinaryBuffer(bytes)) {\n data = {\n data: bytes.toString(\"base64\"),\n contentType,\n encoding: \"binary\",\n };\n } else {\n data = {\n data: bytes.toString(\"utf-8\"),\n contentType,\n encoding: \"utf-8\",\n };\n }\n break;\n }\n case \"write\": {\n mkdirSync(dirname(targetPath), { recursive: true });\n const writeContent =\n typeof content === \"string\"\n ? content\n : ((content as ConnectorContent | undefined)?.data ?? \"\");\n const encoding =\n typeof content === \"string\"\n ? undefined\n : (content as ConnectorContent | undefined)?.encoding;\n if (encoding === \"binary\") {\n writeFileSync(targetPath, Buffer.from(writeContent, \"base64\"));\n } else {\n writeFileSync(targetPath, writeContent, \"utf-8\");\n }\n data = true;\n break;\n }\n case \"delete\": {\n // unlinkSync throws EISDIR on directories; the platform renames folders\n // by copy-then-delete, so the delete op must remove directories too.\n if (statSync(targetPath).isDirectory()) {\n rmSync(targetPath, { recursive: true, force: true });\n } else {\n unlinkSync(targetPath);\n }\n data = true;\n break;\n }\n default:\n throw new Error(`Unsupported operation for mount: ${operation}`);\n }\n emit({ type: \"resource_response\", requestId, resourceId: mountId, operation, data });\n } catch (err) {\n emit({\n type: \"resource_response\",\n requestId,\n resourceId: mountId,\n operation,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n","/**\n * Shared classification + bounded-retry policy for AI-credential mint failures.\n * The single place that decides transient (`backend-error`) vs terminal\n * (`revoked` / `not-configured` / `provider-error`), consumed by both the\n * reactive 401 path and the proactive scheduler so they never drift. Rationale\n * (shared-seat non-amplification) in `runner/CLAUDE.md` § AI Credential Mediation.\n *\n * @docLink packages/runner/dev-guide#ai-credential-mediation\n */\n\nimport { createHash } from \"node:crypto\";\n\nimport type { CredentialMint } from \"@skaile/workspaces/types\";\n\n/** The discriminated failure codes a {@link CredentialMint} can carry. */\nexport type MintFailureCode = Extract<CredentialMint, { ok: false }>[\"code\"];\n\n/**\n * Maximum total mint attempts (initial try + retries) on the transient path.\n * Three attempts spanning the backoff below ride out a ~7s backend redeploy.\n */\nexport const MINT_RETRY_MAX_ATTEMPTS = 3;\n\nconst MINT_RETRY_BASE_DELAY_MS = 2_000;\nconst MINT_RETRY_MAX_DELAY_MS = 5_000;\n\n/**\n * Whether a failed mint should be retried. Only `backend-error` (internal\n * mediator outage) is transient; `not-configured`, `revoked`, and\n * `provider-error` are terminal credential/account states where a retry\n * cannot help.\n */\nexport function isTransientMintFailure(code: MintFailureCode): boolean {\n return code === \"backend-error\";\n}\n\n/**\n * Backoff before the Nth retry (`retryNumber = 1` is the delay before the 2nd\n * attempt). Exponential from a 2s base, capped at 5s, so three attempts span\n * roughly 6s — enough to ride a backend redeploy without unbounded waiting.\n */\nexport function mintRetryDelayMs(retryNumber: number): number {\n const delay = MINT_RETRY_BASE_DELAY_MS * 2 ** Math.max(0, retryNumber - 1);\n return Math.min(delay, MINT_RETRY_MAX_DELAY_MS);\n}\n\n/**\n * Run `attempt` up to {@link MINT_RETRY_MAX_ATTEMPTS} times, sleeping\n * {@link mintRetryDelayMs} between tries, stopping early on success or a\n * terminal failure. Returns the final mint: ok, a terminal failure, or the\n * last transient failure once the cap is reached. `sleep` is injected so tests\n * stay deterministic.\n */\nexport async function retryTransientMint(\n attempt: () => Promise<CredentialMint>,\n deps: {\n sleep: (ms: number) => Promise<void>;\n maxAttempts?: number;\n onRetry?: (info: { attempt: number; nextDelayMs: number; code: MintFailureCode }) => void;\n },\n): Promise<CredentialMint> {\n const maxAttempts = deps.maxAttempts ?? MINT_RETRY_MAX_ATTEMPTS;\n let result = await attempt();\n for (let n = 1; n < maxAttempts; n++) {\n if (result.ok || !isTransientMintFailure(result.code)) return result;\n const nextDelayMs = mintRetryDelayMs(n);\n deps.onRetry?.({ attempt: n, nextDelayMs, code: result.code });\n await deps.sleep(nextDelayMs);\n result = await attempt();\n }\n return result;\n}\n\n/**\n * Truncated SHA-256 of the just-rejected access token. Sent as the OPTIONAL\n * `rejectedFingerprint` on a retry-401 `host.refresh_credential` so the platform\n * can coalesce concurrent rotations of the same dead token (single-flight). It\n * is non-reversible and carries no secret material (16 hex chars = 64 bits,\n * collision-safe for coalescing). Returns `undefined` for an empty/missing\n * token so the field is simply omitted.\n */\nexport function computeRejectedFingerprint(\n accessToken: string | null | undefined,\n): string | undefined {\n if (!accessToken) return undefined;\n return createHash(\"sha256\").update(accessToken).digest(\"hex\").slice(0, 16);\n}\n\n/** The wire input for a `host.refresh_credential` invocation (ai-credentials). */\nexport interface RefreshCredentialInput {\n kind: \"ai-credentials\";\n id: string;\n reason: \"refresh\" | \"retry-401\";\n /** Truncated fingerprint of the just-rejected token; only on retry-401. */\n rejectedFingerprint?: string;\n}\n\n/**\n * Build the `host.refresh_credential` input. The optional\n * `rejectedFingerprint` is attached ONLY on a `retry-401` (where a token was\n * just rejected) and ONLY when a current token is on disk to fingerprint — on a\n * proactive `refresh` there is no rejected token, so the field is omitted.\n * Today's platform ignores the unknown field; the single-flight mediator uses\n * it to coalesce concurrent rotations of the same dead token.\n */\nexport function buildRefreshCredentialInput(args: {\n configId: string;\n reason: \"refresh\" | \"retry-401\";\n rejectedToken?: string | null;\n}): RefreshCredentialInput {\n const base: RefreshCredentialInput = {\n kind: \"ai-credentials\",\n id: args.configId,\n reason: args.reason,\n };\n if (args.reason !== \"retry-401\") return base;\n const rejectedFingerprint = computeRejectedFingerprint(args.rejectedToken);\n return rejectedFingerprint ? { ...base, rejectedFingerprint } : base;\n}\n","/**\n * Proactive AI-credential refresh scheduler. Holds a single timer that fires\n * `PROACTIVE_AI_REFRESH_MARGIN_MS` before the token expires and re-arms against\n * the new expiry via the caller-supplied `refresh`. Pure logic — the caller\n * threads the `host.refresh_credential` side-effect. Resilience model\n * (transient bounded-retry, terminal stop, stale-guard, non-amplification on a\n * shared seat) is documented in `runner/CLAUDE.md` § AI Credential Mediation.\n *\n * @docLink packages/runner/dev-guide#ai-credential-mediation\n */\n\nimport { MINT_RETRY_MAX_ATTEMPTS, mintRetryDelayMs } from \"./ai-credential-retry.js\";\n\n/**\n * Safety margin between the scheduled refresh and the token's declared\n * expiry. Default 5 minutes: long enough that any in-flight prompt at\n * fire time still has a usable token, short enough that a server clock\n * skew of a few seconds does not push the fire-time past expiry.\n */\nexport const PROACTIVE_AI_REFRESH_MARGIN_MS = 5 * 60 * 1000;\n\n/**\n * Stale-schedule guard window. After the bounded transient retries are\n * exhausted the scheduler arms a single long timer this far out so a blip\n * during a proactive fire cannot leave refresh idle indefinitely — the\n * worst case becomes one degraded window, after which a fresh refresh is\n * attempted. Also the threshold {@link AiCredentialRefreshScheduler.ensureArmed}\n * uses to decide a previously-armed scheduler has gone stale.\n */\nexport const STALE_REARM_MS = 9 * 60 * 60 * 1000;\n\n/**\n * Outcome of a proactive refresh attempt, returned by the caller-supplied\n * {@link AiCredentialRefreshDeps.refresh}:\n *\n * - `ok` — a fresh credential was minted; `expiresAt` is its ISO expiry, or\n * `null` for a static token (no further refresh needed).\n * - `transient` — a mediator/transport blip; the scheduler re-arms a bounded\n * retry and ultimately a stale-schedule guard.\n * - `terminal` — the credential/account is genuinely unusable; the scheduler\n * stops re-arming and leaves the reactive 401 path as the safety net.\n */\nexport type AiRefreshOutcome =\n | { status: \"ok\"; expiresAt: string | null }\n | { status: \"transient\" }\n | { status: \"terminal\" };\n\n/**\n * Caller-supplied side effects the scheduler invokes.\n *\n * - `refresh()` runs the actual mint round-trip and classifies the result\n * into an {@link AiRefreshOutcome}.\n * - `log()` receives operator-facing single-line strings (info level).\n * - `logError()` receives failure strings that MUST surface at error level\n * (visible in `skaile session logs` and the debug panel). Defaults to\n * `log` when omitted.\n * - `now()` is dependency-injected for deterministic timer tests; defaults\n * to `Date.now`.\n * - `setTimeoutImpl` / `clearTimeoutImpl` are injected for fake-timer\n * tests; default to the host's `setTimeout` / `clearTimeout`.\n */\nexport interface AiCredentialRefreshDeps {\n refresh: () => Promise<AiRefreshOutcome>;\n log: (line: string) => void;\n logError?: (line: string) => void;\n now?: () => number;\n setTimeoutImpl?: (handler: () => void, ms: number) => { unref?: () => void };\n clearTimeoutImpl?: (handle: { unref?: () => void }) => void;\n marginMs?: number;\n}\n\nexport interface AiCredentialRefreshScheduler {\n /**\n * Arm the timer for `expiresAtIso - marginMs`. Cancels any prior pending\n * fire. `null` / `undefined` cancels without re-arming (static PAT\n * semantics) and marks the credential static. If the fire-time has\n * already passed, runs `refresh()` on the next tick. Records the\n * credential as healthy (resets the transient-retry counter and the\n * stale clock).\n */\n schedule(expiresAtIso: string | null | undefined): void;\n /**\n * Re-arm hook for the configure/wake path. Kicks a fresh refresh on the next\n * tick when the scheduler is idle (prior terminal failure), stale (no\n * successful fire in {@link STALE_REARM_MS}), or currently parked on the long\n * stale-schedule guard — so a container waking during a degraded window\n * recovers eagerly instead of waiting out the guard. No-op when a healthy\n * refresh timer is already pending or the credential is a static PAT.\n */\n ensureArmed(): void;\n /** Cancel any pending fire. Idempotent. */\n cancel(): void;\n /**\n * Whether a timer is currently armed. Exposed for tests; production\n * callers should not need this.\n */\n isPending(): boolean;\n}\n\n/**\n * Build a scheduler bound to the supplied dependencies. One scheduler\n * per session — the runner constructs it once at session_init and\n * disposes via `cancel()` during cleanup.\n */\nexport function createAiCredentialRefreshScheduler(\n deps: AiCredentialRefreshDeps,\n): AiCredentialRefreshScheduler {\n const now = deps.now ?? (() => Date.now());\n const setTimeoutImpl =\n deps.setTimeoutImpl ??\n ((handler: () => void, ms: number) => {\n const handle = setTimeout(handler, ms);\n // Node + Bun timers expose `unref` so this scheduler does not pin\n // the event loop alive.\n return handle as unknown as { unref?: () => void };\n });\n const clearTimeoutImpl =\n deps.clearTimeoutImpl ??\n ((handle: { unref?: () => void }) => {\n clearTimeout(handle as unknown as ReturnType<typeof setTimeout>);\n });\n const marginMs = deps.marginMs ?? PROACTIVE_AI_REFRESH_MARGIN_MS;\n const logError = deps.logError ?? deps.log;\n\n let timer: { unref?: () => void } | null = null;\n // Consecutive transient retries already armed since the last success.\n let transientRetryCount = 0;\n // `now()` of the last known-good credential, or null when none confirmed.\n let lastSuccessAt: number | null = null;\n // True when the active credential is a static PAT (no expiry to refresh).\n let isStatic = false;\n // True while the long stale-schedule guard is the pending timer — so\n // `ensureArmed()` can revive eagerly on wake instead of waiting it out.\n let inStaleGuard = false;\n\n function cancel(): void {\n if (timer !== null) {\n clearTimeoutImpl(timer);\n timer = null;\n }\n }\n\n function armTimer(handler: () => void, ms: number): void {\n cancel();\n timer = setTimeoutImpl(handler, ms);\n timer.unref?.();\n }\n\n function isStale(): boolean {\n return lastSuccessAt !== null && now() - lastSuccessAt > STALE_REARM_MS;\n }\n\n async function fire(): Promise<void> {\n timer = null;\n let outcome: AiRefreshOutcome;\n try {\n outcome = await deps.refresh();\n } catch (err) {\n // A throw is a transport/network blip — treat as transient, not fatal.\n logError(\n `[ai-credential-refresh] refresh threw: ${err instanceof Error ? err.message : String(err)}; treating as transient`,\n );\n outcome = { status: \"transient\" };\n }\n\n if (outcome.status === \"ok\") {\n schedule(outcome.expiresAt);\n return;\n }\n\n if (outcome.status === \"terminal\") {\n transientRetryCount = 0;\n inStaleGuard = false;\n logError(\n \"[ai-credential-refresh] proactive refresh hit a terminal failure; not re-arming (reactive 401 path remains the safety net)\",\n );\n return;\n }\n\n // Transient: re-arm a bounded retry, then a long stale-schedule guard.\n if (transientRetryCount < MINT_RETRY_MAX_ATTEMPTS - 1) {\n transientRetryCount += 1;\n inStaleGuard = false;\n const delayMs = mintRetryDelayMs(transientRetryCount);\n logError(\n `[ai-credential-refresh] proactive refresh transient failure; bounded retry ${transientRetryCount}/${MINT_RETRY_MAX_ATTEMPTS - 1} in ${Math.round(delayMs / 1000)}s`,\n );\n armTimer(() => void fire(), delayMs);\n return;\n }\n\n transientRetryCount = 0;\n inStaleGuard = true;\n logError(\n `[ai-credential-refresh] proactive refresh failed after ${MINT_RETRY_MAX_ATTEMPTS} attempts; reactive 401 path is the fallback, re-checking in ${Math.round(STALE_REARM_MS / 3_600_000)}h`,\n );\n armTimer(() => void fire(), STALE_REARM_MS);\n }\n\n function schedule(expiresAtIso: string | null | undefined): void {\n cancel();\n inStaleGuard = false;\n if (!expiresAtIso) {\n // Static token (PAT) or unknown expiry — nothing to schedule. A null\n // expiry still represents a working credential, so reset health state.\n isStatic = true;\n transientRetryCount = 0;\n lastSuccessAt = now();\n return;\n }\n const expiresAtMs = Date.parse(expiresAtIso);\n if (!Number.isFinite(expiresAtMs)) return;\n // A parseable future expiry is a known-good credential.\n isStatic = false;\n transientRetryCount = 0;\n lastSuccessAt = now();\n const delayMs = expiresAtMs - now() - marginMs;\n if (delayMs <= 0) {\n deps.log(\n `[ai-credential-refresh] token within ${marginMs / 1000}s of expiry; refreshing now`,\n );\n armTimer(() => void fire(), 0);\n } else {\n deps.log(\n `[ai-credential-refresh] scheduled in ${Math.round(delayMs / 1000)}s (expiresAt=${expiresAtIso})`,\n );\n armTimer(() => void fire(), delayMs);\n }\n }\n\n function ensureArmed(): void {\n // Static PAT: nothing to refresh.\n if (isStatic) return;\n // Healthy refresh timer pending (not the long stale guard, not stale):\n // leave it alone.\n if (timer !== null && !inStaleGuard && !isStale()) return;\n // Idle (terminal failure), stale, or parked on the stale guard: kick a\n // fresh refresh on the next tick so a waking container recovers eagerly.\n deps.log(\"[ai-credential-refresh] ensureArmed: reviving idle/stale schedule\");\n transientRetryCount = 0;\n inStaleGuard = false;\n armTimer(() => void fire(), 0);\n }\n\n return {\n schedule,\n ensureArmed,\n cancel,\n isPending: () => timer !== null,\n };\n}\n","/**\n * Inbound `credentialRotated` broadcast handler — the runner's receive side of\n * the platform single-flight mediator's rotation broadcast (re-pull instead of\n * each container force-refreshing). Dormant until the platform ships it. Wire\n * shape + delivery-channel contract in root `MIGRATION.md`.\n * @docLink packages/runner/dev-guide#ai-credential-mediation\n */\n\nimport type { CredentialMint } from \"@skaile/workspaces/types\";\n\n/** `LogSource.subkind` the platform tags its credential-rotation broadcast with. */\nexport const AI_PROVIDER_CREDENTIAL_SUBKIND = \"ai-provider-credential\";\n\n/**\n * Whether an inbound message is the platform's credential-rotation broadcast.\n * Pure predicate — tolerant of unknown shapes so a malformed message is simply\n * not matched rather than throwing on the command ingress path.\n */\nexport function isCredentialRotatedSignal(msg: unknown): boolean {\n if (!msg || typeof msg !== \"object\") return false;\n const m = msg as {\n type?: unknown;\n entry?: { source?: { subkind?: unknown }; data?: { credentialRotated?: unknown } };\n };\n if (m.type !== \"log_entry\") return false;\n const entry = m.entry;\n if (!entry || typeof entry !== \"object\") return false;\n return (\n entry.source?.subkind === AI_PROVIDER_CREDENTIAL_SUBKIND &&\n entry.data?.credentialRotated === true\n );\n}\n\n/**\n * Handle a credential-rotation broadcast: re-pull the fresh token through the\n * supplied `repull` (a `host.refresh_credential { reason: 'refresh' }` round\n * trip that rewrites `.credentials.json`). Idempotent and best-effort — a\n * failed re-pull is logged at error level and the reactive 401 path remains the\n * safety net; it never throws to the caller.\n *\n * The serve.ts wiring passes `mintAndPersistAiCredential` as `repull`, whose\n * success path also re-arms the proactive refresh scheduler against the fresh\n * expiry — so a re-pull both rewrites the file and re-schedules in one step.\n */\nexport async function handleCredentialRotatedSignal(deps: {\n repull: () => Promise<CredentialMint>;\n log: (line: string) => void;\n logError: (line: string) => void;\n}): Promise<void> {\n deps.log(\"[serve] credentialRotated broadcast received; re-pulling ai-credentials\");\n try {\n const result = await deps.repull();\n if (result.ok) {\n deps.log(\"[serve] credentialRotated: re-pulled fresh token and rewrote .credentials.json\");\n } else {\n deps.logError(`[serve] credentialRotated: re-pull failed (code=${result.code})`);\n }\n } catch (err) {\n deps.logError(\n `[serve] credentialRotated: re-pull threw: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n}\n","import type { RuntimeSessionEvent } from \"@skaile/workspaces/types\";\n\n/**\n * Snapshot of the tier-1 resume state last surfaced to the platform via a\n * `runtime_session` event.\n */\nexport type RuntimeSessionSnapshot = {\n driverSessionId: string;\n model: string | null;\n capabilitySignature: string;\n};\n\n/**\n * Decide whether to emit a `runtime_session` event after a turn completes.\n *\n * The runner surfaces the driver's SDK session id (the tier-1 native-resume\n * token) plus the model and capability signature so the platform can persist\n * them on the Session independently of compaction. We emit whenever ANY of the\n * three changes since the last emission — not only on a session-id change — so\n * a mid-session shift (e.g. a live skill add that changes capabilities without\n * recreating the driver, or a model reconfigure) keeps the platform's stored\n * wake-time guards fresh. A stale signature/model would otherwise make the\n * wake-time guard drop a still-valid session to lossy tier-2 resume.\n *\n * The caller MUST short-circuit on a missing `driverSessionId` BEFORE computing\n * the capability signature, so the early no-session turns do not pay for the\n * hash needlessly; once a session id exists the per-turn compute is what\n * detects signature drift.\n *\n * Pure so the emit-on-change rule is unit-testable without booting serve.\n *\n * @returns the event to emit, or `null` when there is no session id yet or\n * nothing changed since `lastEmitted`.\n */\nexport function planRuntimeSessionEmit(input: {\n driverSessionId: string | undefined;\n model: string | null;\n capabilitySignature: string;\n lastEmitted: RuntimeSessionSnapshot | undefined;\n}): RuntimeSessionEvent | null {\n const { driverSessionId, model, capabilitySignature, lastEmitted } = input;\n if (!driverSessionId) {\n return null;\n }\n if (\n lastEmitted &&\n lastEmitted.driverSessionId === driverSessionId &&\n lastEmitted.model === model &&\n lastEmitted.capabilitySignature === capabilitySignature\n ) {\n return null;\n }\n return { type: \"runtime_session\", driverSessionId, model, capabilitySignature };\n}\n","const DEFAULT_COMPACTION_PROMPT = `You are being asked to compact this conversation into a structured summary.\nThis summary will replace the full conversation history when the session\nis restored. Produce a summary that lets you continue working effectively\nwithout access to the original messages.\n\n## Rules\n\nPRESERVE (include verbatim):\n- Current task/goal and its status\n- All file paths that were read, created, or modified\n- Function/class/variable names that are relevant to ongoing work\n- Key decisions made and the reasoning behind them\n- Errors encountered and how they were resolved\n- Active flow node and state (if any)\n- Unresolved questions or pending user input\n- User names and who said/requested what (multi-user sessions)\n- Test commands and verification criteria\n- Any explicit user instructions about preferences or constraints\n\nCOMPRESS (summarize in one line each):\n- Tool call / tool result pairs\n- Intermediate reasoning steps\n- Exploration paths that informed a decision\n\nDROP (omit entirely):\n- Full file contents (can be re-read from disk)\n- Verbose command output (build logs, test suite output)\n- Exploration that led nowhere and didn't inform decisions\n- Redundant back-and-forth (corrections already applied)\n- Transient UI state\n\n## Format\n\nWrite a structured summary using these sections. Omit any section that\nhas no content.\n\n### Goal\nWhat the user is trying to accomplish.\n\n### Progress\nWhat has been done so far, organized by sub-task.\n\n### Key Decisions\nDecisions made and why, as a bulleted list.\n\n### Active State\nCurrent work in progress -- what was happening when compaction triggered.\n\n### Files\nAll relevant file paths with a one-line note on each.\n\n### Pending\nWhat still needs to be done or is waiting on user input.\n\n### Context\nUser preferences, constraints, or instructions that must carry forward.`;\n\n/**\n * Assemble the final compaction prompt from layered sources.\n *\n * Resolution order:\n * base = agentPrompt ?? DEFAULT_COMPACTION_PROMPT\n * final = base + skillDirectives + focus\n * @docLink packages/runner/dev-guide#compaction\n */\nexport function buildCompactionPrompt(opts: {\n agentPrompt?: string;\n skillDirectives?: string[];\n mcpDirectives?: string[];\n focus?: string;\n}): string {\n const base = opts.agentPrompt ?? DEFAULT_COMPACTION_PROMPT;\n const parts = [base];\n\n const allDirectives = [...(opts.skillDirectives ?? []), ...(opts.mcpDirectives ?? [])];\n\n if (allDirectives.length > 0) {\n parts.push(\n `\\n\\n## Additional Compaction Directives\\n${allDirectives.map((d) => `- ${d}`).join(\"\\n\")}`,\n );\n }\n\n if (opts.focus) {\n parts.push(`\\n\\n## Focus\\n${opts.focus}`);\n }\n\n return parts.join(\"\");\n}\n","/**\n * Runtime context data supplied to a {@link CompactionStrategy}\n * when deciding whether to compact the context window.\n *\n * @docLink packages/runner/dev-guide#compaction\n */\nexport interface CompactionContext {\n estimatedTokens: number;\n contextWindow: number;\n messageCount: number;\n lastCompactionSeq: number | null;\n timeSinceLastCompaction: number | null;\n}\n\n/**\n * Strategy for deciding when the context window should be compacted.\n *\n * Implementations receive the current {@link CompactionContext} and\n * return true when compaction should proceed.\n *\n * @docLink packages/runner/dev-guide#compaction\n */\nexport interface CompactionStrategy {\n shouldCompact(context: CompactionContext): boolean;\n}\n\n/**\n * Compaction strategy that triggers when estimated token usage\n * exceeds a percentage of the context window. A cooldown period\n * prevents thrashing.\n *\n * @docLink packages/runner/dev-guide#compaction\n */\nexport class TokenThresholdStrategy implements CompactionStrategy {\n private readonly thresholdPercent: number;\n private readonly minCooldownMs: number;\n\n constructor(opts: { thresholdPercent: number; minCooldownMs: number }) {\n this.thresholdPercent = opts.thresholdPercent;\n this.minCooldownMs = opts.minCooldownMs;\n }\n\n shouldCompact(context: CompactionContext): boolean {\n const fillPercent = (context.estimatedTokens / context.contextWindow) * 100;\n if (fillPercent < this.thresholdPercent) return false;\n\n // Respect cooldown\n if (\n context.timeSinceLastCompaction !== null &&\n context.timeSinceLastCompaction < this.minCooldownMs\n ) {\n return false;\n }\n\n return true;\n }\n}\n","import type { AgentDriver } from \"@skaile/workspaces/bridge\";\nimport { classifyClaudeSdkError } from \"@skaile/workspaces/bridge\";\nimport type { CompactionConfig } from \"@skaile/workspaces/core\";\nimport { COMPACTION_DEFAULTS } from \"@skaile/workspaces/core\";\nimport type {\n CompactionAttemptEvent,\n CompactionTrigger,\n SnapshotEvent,\n} from \"@skaile/workspaces/types\";\nimport { buildCompactionPrompt } from \"./prompt.js\";\nimport { type CompactionStrategy, TokenThresholdStrategy } from \"./strategy.js\";\n\n/**\n * Fields shared across every {@link CompactionAttemptEvent} emitted within a\n * single `_doCompact` call — captured once at the start so all three branches\n * (thrown failure / validation failure / success) agree on the same values.\n * Each branch supplies the remaining status-specific fields.\n */\ntype CompactionAttemptBase = Omit<\n CompactionAttemptEvent,\n \"type\" | \"status\" | \"errorCode\" | \"summary\" | \"outputTokens\" | \"validatedAt\"\n>;\n\n/**\n * Minimum character length the LLM must produce to count as a meaningful summary.\n * Below this we mark the attempt `failed`/`too_short`. Tunable: 200 chars is roughly\n * 50 tokens, the floor for \"the model said anything substantive\".\n */\nconst MIN_SUMMARY_CHARS = 200;\n\n/**\n * Maximum compression ratio (outputTokens / tokensBefore) we accept as a successful\n * compaction. Above this the LLM essentially returned the input back; mark `poor_ratio`.\n */\nconst MAX_COMPRESSION_RATIO = 0.9;\n\n/**\n * Maximum length under which a captured response is still considered a candidate\n * for being a rate-limit error message rather than a real summary. Real\n * compactions are typically thousands of characters; rate-limit relays are\n * short.\n */\nconst RATE_LIMIT_TEXT_MAX_CHARS = 1500;\n\n/**\n * Phrases that strongly indicate the captured text is the LLM relaying a\n * rate-limit / quota error to the user rather than producing a summary.\n * Conservative on purpose — a real summary that mentions rate limits in\n * passing would only match if it is also short, see\n * {@link detectRateLimitInSummary}.\n */\nconst RATE_LIMIT_TEXT_PATTERNS: RegExp[] = [\n /you('?| ha)ve hit your (rate |usage )?limit/i,\n /you('?| ha)ve reached your (usage |rate )?limit/i,\n /you('?| ha)ve been rate[\\s-]?limited/i,\n /rate limit (exceeded|reached|hit)/i,\n /usage limit (exceeded|reached)/i,\n /quota (exceeded|reached)/i,\n /claude (ai )?usage limit reached/i,\n];\n\n/**\n * Detect whether the captured response from a compaction `prompt()` call is\n * actually a rate-limit error message returned as text (instead of as a\n * thrown error). Persisting such a \"summary\" would corrupt context\n * restoration on the next wake — the snapshot prompt would inject the error\n * text as if it were the conversation summary.\n *\n * Conservative: requires both a strong signal phrase AND a short response.\n * Real summaries are routinely 2k+ chars; rate-limit relays are short.\n *\n * Issue: I-29.\n */\nexport function detectRateLimitInSummary(text: string): boolean {\n if (text.length > RATE_LIMIT_TEXT_MAX_CHARS) return false;\n return RATE_LIMIT_TEXT_PATTERNS.some((p) => p.test(text));\n}\n\n/**\n * Validation of a compaction output's structural shape, run BEFORE we persist\n * it as a `success`. Cheap synchronous checks only — no LLM calls.\n *\n * Failed validation does NOT throw; it returns a structured verdict so the\n * orchestrator can record a `failed` Compaction row with the right errorCode.\n *\n * @param text The captured summary text from the driver.\n * @param tokensBefore Estimated input token count (from `driver.getTokenUsage()` before the call).\n * @param tokensAfter Output token count of the summary (from driver or chars/4 heuristic).\n * @returns `{ ok: true }` on pass, otherwise `{ ok: false, errorCode }` with one of:\n * `\"empty\"` | `\"too_short\"` | `\"poor_ratio\"` | `\"rate_limit\"`.\n *\n * Spec: `_devlog/specs/2026-05-05-session-resume-restart-design.md` § Validation at write time.\n * @docLink packages/runner/capabilities#validate-compaction-output\n */\nexport function validateCompactionOutput(\n text: string,\n tokensBefore: number,\n tokensAfter: number,\n): { ok: true } | { ok: false; errorCode: string } {\n if (!text.trim()) return { ok: false, errorCode: \"empty\" };\n if (detectRateLimitInSummary(text)) return { ok: false, errorCode: \"rate_limit\" };\n if (text.length < MIN_SUMMARY_CHARS) return { ok: false, errorCode: \"too_short\" };\n if (tokensBefore > 0 && tokensAfter / tokensBefore > MAX_COMPRESSION_RATIO) {\n return { ok: false, errorCode: \"poor_ratio\" };\n }\n return { ok: true };\n}\n\n/**\n * Options for the {@link CompactionOrchestrator}.\n *\n * @docLink packages/runner/dev-guide#compaction\n */\nexport interface CompactionOrchestratorOptions {\n driver: AgentDriver;\n config?: CompactionConfig;\n skillDirectives?: string[];\n mcpDirectives?: string[];\n agentCompactionPrompt?: string;\n onCompactionStart?: (trigger: CompactionTrigger) => void;\n onSnapshot?: (snapshot: SnapshotEvent) => void;\n /**\n * Emitted on EVERY compaction attempt, success or failure. Phase 1 sink for\n * the new `Compaction` table observability surface; the host's serve.ts wires\n * this to forward events on the agent transport.\n */\n onCompactionAttempt?: (event: CompactionAttemptEvent) => void;\n onCompactionEnd?: () => void;\n onLog?: (line: string) => void;\n /**\n * Phase 3 (resume cascade): supplies the current capability registry\n * signature at compaction time so it lands on the\n * {@link CompactionAttemptEvent}. The wake selector compares this against\n * the runner's current signature to decide tier-1 native SDK resume\n * eligibility.\n *\n * Returns `null` when the host cannot compute a signature (legacy boot\n * path, registry not yet bootstrapped); the orchestrator records `null`\n * in that case and the resulting compaction is tier-1 ineligible.\n */\n getCurrentCapabilitySignature?: () => string | null;\n}\n\n/**\n * Orchestrates context window compaction for a running agent session.\n *\n * Monitors token usage against the configured thresholds and triggers\n * compaction via snapshots when the strategy fires.\n *\n * @docLink packages/runner/dev-guide#compaction\n */\nexport class CompactionOrchestrator {\n private readonly driver: AgentDriver;\n private readonly strategy: CompactionStrategy;\n private readonly config: Required<CompactionConfig>;\n private readonly opts: CompactionOrchestratorOptions;\n\n private _isCompacting = false;\n private lastCompactionSeq: number | null = null;\n private lastCompactionTime: number | null = null;\n private currentSeq = 0;\n private messagesSinceCompaction = 0;\n\n constructor(opts: CompactionOrchestratorOptions) {\n this.driver = opts.driver;\n this.opts = opts;\n this.config = { ...COMPACTION_DEFAULTS, ...opts.config };\n this.strategy = new TokenThresholdStrategy({\n thresholdPercent: this.config.thresholdPercent,\n minCooldownMs: this.config.minCooldownMs,\n });\n }\n\n trackMessage(seq: number): void {\n this.currentSeq = seq;\n this.messagesSinceCompaction++;\n }\n\n shouldCompact(): boolean {\n if (!this.config.enabled) return false;\n const usage = this.driver.getTokenUsage();\n const contextWindow = this.driver.getContextWindow();\n if (!usage || !contextWindow || usage.inputTokens === undefined) return false;\n\n return this.strategy.shouldCompact({\n estimatedTokens: usage.inputTokens,\n contextWindow,\n messageCount: this.messagesSinceCompaction,\n lastCompactionSeq: this.lastCompactionSeq,\n timeSinceLastCompaction:\n this.lastCompactionTime !== null ? Date.now() - this.lastCompactionTime : null,\n });\n }\n\n async compact(trigger: CompactionTrigger, focus?: string): Promise<SnapshotEvent | null> {\n if (this._isCompacting) return null;\n this._isCompacting = true;\n try {\n return await this._doCompact(trigger, focus);\n } finally {\n this._isCompacting = false;\n }\n }\n\n private async _doCompact(\n trigger: CompactionTrigger,\n focus?: string,\n ): Promise<SnapshotEvent | null> {\n const tokensBefore = this.driver.getTokenUsage()?.inputTokens ?? 0;\n const driverSessionId = this.driver.runtimeSessionId ?? null;\n const driverModel = this.driver.getModel() ?? null;\n const driverProvider = this.driver.driverInfo?.id ?? null;\n const coversFromSeq = this.lastCompactionSeq ?? 0;\n // Phase 3: capture the registry signature once at the start of the call\n // so all attempt-event branches (failed/validation-failed/success) share\n // the same value.\n const capabilitySignatureAtCompaction = this.opts.getCurrentCapabilitySignature?.() ?? null;\n\n // Shared fields on every CompactionAttemptEvent emitted from this call.\n const attemptBase = {\n trigger,\n model: driverModel,\n provider: driverProvider,\n inputTokens: tokensBefore,\n coversFromSeq,\n coversToSeq: this.currentSeq,\n driverSessionIdAtCompaction: driverSessionId,\n modelAtCompaction: driverModel,\n capabilitySignatureAtCompaction,\n };\n\n this.opts.onCompactionStart?.(trigger);\n this.opts.onLog?.(`[compaction] Starting (trigger=${trigger}, tokens=${tokensBefore})`);\n\n const prompt = buildCompactionPrompt({\n agentPrompt: this.opts.agentCompactionPrompt,\n skillDirectives: this.opts.skillDirectives,\n mcpDirectives: this.opts.mcpDirectives,\n focus,\n });\n\n const { summaryText, promptError } = await this._runCompactionPrompt(prompt);\n\n // ── Failure path: prompt() threw ──────────────────────────────────────\n if (promptError !== null) {\n this._emitThrownFailure(attemptBase, promptError);\n return null;\n }\n\n // ── Validation path: prompt succeeded but output may be malformed ────\n // Use actual output token count from the driver; fall back to heuristic.\n const actualUsage = this.driver.getTokenUsage();\n const tokensAfter = actualUsage?.outputTokens ?? Math.ceil(summaryText.length / 4);\n\n const validation = validateCompactionOutput(summaryText, tokensBefore, tokensAfter);\n if (!validation.ok) {\n this._emitValidationFailure(attemptBase, validation.errorCode, tokensAfter);\n return null;\n }\n\n // ── Success path ──────────────────────────────────────────────────────\n return await this._completeCompaction(\n attemptBase,\n trigger,\n summaryText,\n tokensBefore,\n tokensAfter,\n coversFromSeq,\n );\n }\n\n /**\n * Drive the compaction `prompt()` call, capturing summary text from the\n * driver's raw bridge-level events and any thrown error. The listener is\n * always removed in `finally`.\n */\n private async _runCompactionPrompt(\n prompt: string,\n ): Promise<{ summaryText: string; promptError: unknown }> {\n let summaryText = \"\";\n // The driver emits raw bridge-level events (message_update, message_start,\n // message_end) that are NOT in the AgentEvent union — those are normalized\n // by EventNormalizer in serve.ts. Since the compaction handler attaches\n // directly to the driver, we type the parameter loosely.\n const captureHandler = (raw: unknown) => {\n const event = raw as { type: string; [k: string]: unknown };\n // Normalized events (from EventNormalizer or other drivers)\n if (event.type === \"text\") {\n summaryText += (event.content as string) ?? \"\";\n return;\n }\n // Raw SDK driver events — message_update carries _textDelta, bypassing\n // the EventNormalizer which isn't in the compaction capture path.\n if (event.type === \"message_update\") {\n const delta = event._textDelta as string | undefined;\n if (delta) summaryText += delta;\n return;\n }\n // Fallback: non-streaming drivers may emit message_start/message_end\n // with the full text in the message content blocks.\n if (event.type === \"message_start\" || event.type === \"message_end\") {\n const msg = event.message as { content?: { type: string; text?: string }[] } | undefined;\n if (!msg?.content) return;\n const blocks = Array.isArray(msg.content) ? msg.content : [];\n for (const b of blocks) {\n if (b.type === \"text\" && b.text) summaryText += b.text;\n }\n }\n };\n\n let promptError: unknown = null;\n try {\n this.driver.on(\"agent-event\", captureHandler);\n await this.driver.prompt(prompt);\n } catch (err) {\n promptError = err;\n } finally {\n this.driver.removeListener(\"agent-event\", captureHandler);\n }\n\n return { summaryText, promptError };\n }\n\n /**\n * Record a `failed` attempt for a thrown `prompt()` error: classify the\n * error, map it to an error code, log, emit the attempt event, and signal\n * compaction end.\n */\n private _emitThrownFailure(attemptBase: CompactionAttemptBase, promptError: unknown): void {\n const classified = classifyClaudeSdkError(\n promptError instanceof Error ? promptError.message : String(promptError),\n );\n // Map classifier categories to our error codes per spec.\n // `auth` covers both real credential failures AND payment-blocked OAuth\n // subscriptions that Anthropic mislabels as auth errors (see\n // bridge/error-classifier.ts docstring) — owners investigate further.\n const errorCode =\n classified.category === \"rate_limit\"\n ? \"rate_limit\"\n : classified.category === \"auth\"\n ? \"auth\"\n : classified.category === \"network\"\n ? \"timeout\"\n : classified.category === \"validation\"\n ? \"parse_error\"\n : classified.category;\n\n this.opts.onLog?.(`[compaction] Failed: ${classified.message} (${errorCode})`);\n this.opts.onCompactionAttempt?.({\n type: \"compaction_attempt\",\n status: \"failed\",\n errorCode,\n summary: \"\",\n outputTokens: 0,\n validatedAt: null,\n ...attemptBase,\n });\n this.opts.onCompactionEnd?.();\n }\n\n /**\n * Record a `failed` attempt for output that passed `prompt()` but failed\n * structural validation. Logs, emits the attempt event, and signals\n * compaction end.\n */\n private _emitValidationFailure(\n attemptBase: CompactionAttemptBase,\n errorCode: string,\n tokensAfter: number,\n ): void {\n this.opts.onLog?.(\n `[compaction] Output failed validation (${errorCode}); recording failed attempt`,\n );\n this.opts.onCompactionAttempt?.({\n type: \"compaction_attempt\",\n status: \"failed\",\n errorCode,\n summary: \"\",\n outputTokens: tokensAfter,\n validatedAt: null,\n ...attemptBase,\n });\n this.opts.onCompactionEnd?.();\n }\n\n /**\n * Success path: emit the attempt + snapshot events, update internal state,\n * and (unless hibernating) reset the driver and inject the snapshot.\n */\n private async _completeCompaction(\n attemptBase: CompactionAttemptBase,\n trigger: CompactionTrigger,\n summaryText: string,\n tokensBefore: number,\n tokensAfter: number,\n coversFromSeq: number,\n ): Promise<SnapshotEvent> {\n const validatedAt = new Date().toISOString();\n\n const snapshot: SnapshotEvent = {\n type: \"snapshot\",\n summary: summaryText,\n trigger,\n coversFromSeq,\n coversToSeq: this.currentSeq,\n tokensBefore,\n tokensAfter,\n };\n\n // 1. Emit the new attempt event AND the legacy snapshot event.\n // Both ride alongside each other through Phase 4 (back-compat).\n this.opts.onCompactionAttempt?.({\n type: \"compaction_attempt\",\n status: \"success\",\n errorCode: null,\n summary: summaryText,\n outputTokens: tokensAfter,\n validatedAt,\n ...attemptBase,\n });\n this.opts.onSnapshot?.(snapshot);\n\n // 2. Update internal state\n this.lastCompactionSeq = this.currentSeq + 1;\n this.lastCompactionTime = Date.now();\n this.messagesSinceCompaction = 0;\n\n // 3. Clear compacting flag so the injection turn's events flow normally\n this.opts.onCompactionEnd?.();\n\n // 4. Reset driver and inject snapshot (skip for hibernate -- container shuts down)\n if (trigger !== \"hibernate\") {\n this.opts.onLog?.(\"[compaction] Resetting driver session\");\n await this.driver.resetSession();\n await this.driver.prompt(\n `<session_snapshot>\\n${summaryText}\\n</session_snapshot>\\n\\nThe conversation has been compacted. The above snapshot contains the full context of our work so far. Continue from where we left off.`,\n );\n }\n\n // 5. Log completion\n this.opts.onLog?.(\n `[compaction] Complete (${tokensBefore} -> ${tokensAfter} tokens, ratio=${((tokensAfter / Math.max(tokensBefore, 1)) * 100).toFixed(1)}%)`,\n );\n return snapshot;\n }\n}\n","/**\n * Rewrite file_changed event paths to mounts-relative form.\n *\n * The bridge normalizer forwards tool filePaths verbatim — for Claude SDK\n * Write/Edit they are cwd-relative (e.g. \"workspace/foo/bar.py\" when cwd\n * is /skaile and the file lives at /skaile/workspace/foo/bar.py). The\n * frontend's file-change listener treats the path as relative to the\n * currently-selected mount, which double-prefixes when the workspace\n * mount sits under cwd.\n *\n * This helper resolves the path against cwd, locates the mount it falls\n * inside, and re-expresses the path relative to that mount with the\n * matching mountId attached.\n *\n * Events that already carry a mountId (watcher-originated) and events\n * whose path resolves outside every mount are passed through unchanged.\n */\n\nimport { relative, resolve } from \"node:path\";\nimport type { AgentEvent } from \"@skaile/workspaces/types\";\n\n/**\n * Describes a filesystem mount point for path rewriting.\n *\n * @docLink packages/runner/dev-guide#flow-execution-turn-based-model\n */\nexport interface MountPoint {\n id: string;\n /** Absolute mount path on the agent's filesystem. */\n mountPath: string;\n}\n\n/**\n * Rewrite a single file_changed event. Non-file_changed events and events\n * already tagged with a mountId are returned unchanged.\n * @docLink packages/runner/dev-guide#flow-execution-turn-based-model\n */\nexport function rewriteFileChangedPath(\n event: AgentEvent,\n cwd: string,\n mounts: readonly MountPoint[],\n): AgentEvent {\n if (event.type !== \"file_changed\") return event;\n if ((event as { mountId?: string }).mountId) return event;\n const rawPath = event.path;\n if (!rawPath) return event;\n\n const absPath = resolve(cwd, rawPath);\n for (const mount of mounts) {\n const rel = relative(mount.mountPath, absPath);\n // rel starts with \"..\" → outside the mount\n // rel === \"\" → the mount itself (not a child)\n // rel is absolute (starts with \"/\") → different filesystem root\n if (rel === \"\" || rel.startsWith(\"..\") || rel.startsWith(\"/\")) continue;\n return { ...event, path: rel, mountId: mount.id };\n }\n return event;\n}\n","// Builds the `runner.lifecycle` capability handler. No serve.ts import keeps the\n// dependency direction acyclic; getters (not values) because serve.ts lazily\n// (re)assigns resourceManager + rebuilds the orchestrator on driver recreate.\nimport type { ConnectorManager } from \"@skaile/workspaces/connectors\";\nimport type { CompactionOrchestrator } from \"./compaction/index.js\";\nimport type { RunnerCapabilityHandlers } from \"./runner-capabilities.js\";\n\nexport interface LifecycleHandlerDeps {\n /** The current compaction orchestrator, or null before the driver is built. */\n getCompactionOrchestrator: () => CompactionOrchestrator | null;\n /** The live unified connector manager, or null before the session is built. */\n getResourceManager: () => ConnectorManager | null;\n log: (msg: string) => void;\n}\n\n/**\n * Build the `runner.lifecycle` handler. Each phase is best-effort: a missing\n * dependency (orchestrator/manager not yet built) logs and no-ops rather than\n * throwing, so the platform's lifecycle invoke always resolves cleanly.\n */\nexport function buildLifecycleHandler(\n deps: LifecycleHandlerDeps,\n): NonNullable<RunnerCapabilityHandlers[\"lifecycle\"]> {\n const { getCompactionOrchestrator, getResourceManager, log } = deps;\n\n return async ({ phase }) => {\n switch (phase) {\n case \"compact\": {\n const orchestrator = getCompactionOrchestrator();\n // 'manual' (not 'threshold') — this is a platform-driven compaction.\n if (orchestrator) await orchestrator.compact(\"manual\");\n else log(\"[lifecycle] compact: no compaction orchestrator — skipped\");\n break;\n }\n case \"hibernate\": {\n const manager = getResourceManager();\n if (manager) await manager.hibernateAll();\n else log(\"[lifecycle] hibernate: no resource manager — skipped\");\n break;\n }\n case \"close\": {\n const manager = getResourceManager();\n if (manager) await manager.closeAll();\n else log(\"[lifecycle] close: no resource manager — skipped\");\n break;\n }\n }\n return { ok: true };\n };\n}\n","/**\n * Wires the resource-mutation `runner.*` capabilities to the live session's\n * `ConnectorManager` + `PreMintedSecretProvider`. Kept free of any `serve.ts`\n * import so the dependency direction stays acyclic (same rule as\n * `runner-capabilities.ts`). The caller passes getters (not values) because\n * `serve.ts` lazily (re)assigns `resourceManager` / `preMintedSecrets`.\n *\n * @category Runtime\n * @since 0.38.0\n */\nimport { join } from \"node:path\";\nimport {\n type ConnectorDeclaration,\n type ConnectorManager,\n deriveSingleMaterializedConnectorDeclaration,\n type PreMintedCredential,\n type PreMintedSecretProvider,\n} from \"@skaile/workspaces/connectors\";\nimport type { RunnerCapabilityHandlers } from \"./runner-capabilities.js\";\n\nexport interface SessionResourceHandlerDeps {\n /** The live unified connector manager, or null before the session is built. */\n getResourceManager: () => ConnectorManager | null;\n /** The in-process pre-minted credential store, or undefined before init. */\n getPreMintedSecrets: () => PreMintedSecretProvider | undefined;\n /** Re-emit `resources_available` so the frontend reflects the live change. */\n emitResourcesAvailable: () => void;\n log: (msg: string) => void;\n /**\n * Absolute path to the session project directory. Required by\n * `attachConnectorInstance` for the materialized-asset lookup under\n * `<projectDir>/.skaile/assets/connector/<name>`.\n */\n getProjectDir?: () => string;\n}\n\ntype AddResult = { ok: true; id: string } | { ok: false; code: string; message: string };\ntype MutateResult = { ok: true } | { ok: false; code: string; message: string };\n\n/** Attach-by-ref result — shape parity with the MCP `attachInstance` return. */\ntype AttachResult =\n | { ok: true; id: string; live: boolean; toolCount: number }\n | { ok: false; code: string; message: string };\n\n/** A connector/mount declaration is usable only if it carries id + driver. */\nfunction asDeclaration(declaration: unknown): ConnectorDeclaration | null {\n if (\n declaration !== null &&\n typeof declaration === \"object\" &&\n typeof (declaration as { id?: unknown }).id === \"string\" &&\n typeof (declaration as { driver?: unknown }).driver === \"string\"\n ) {\n return declaration as ConnectorDeclaration;\n }\n return null;\n}\n\nexport function toPreMinted(token: {\n token: string;\n expiresAt?: string | null;\n}): PreMintedCredential {\n return { ok: true, token: token.token, expiresAt: token.expiresAt ?? null };\n}\n\nexport function buildSessionResourceHandlers(deps: SessionResourceHandlerDeps): Pick<\n RunnerCapabilityHandlers,\n \"addConnector\" | \"addMount\" | \"removeResource\" | \"updateCredential\"\n> & {\n attachConnectorInstance: (\n name: string,\n preMintedToken?: { token: string; expiresAt?: string | null },\n ) => Promise<AttachResult>;\n} {\n const { getResourceManager, getPreMintedSecrets, emitResourcesAvailable, log, getProjectDir } =\n deps;\n\n async function add(\n kind: \"mount\" | \"connector\",\n input: {\n declaration: unknown;\n preMintedToken?: { token: string; expiresAt?: string | null };\n },\n ): Promise<AddResult> {\n const rm = getResourceManager();\n if (!rm) return { ok: false, code: \"no_session\", message: \"session resources not ready\" };\n const decl = asDeclaration(input.declaration);\n if (!decl) {\n return { ok: false, code: \"invalid_declaration\", message: \"declaration missing id/driver\" };\n }\n // Stage the credential before connect — ConnectorManager consults the\n // provider for the `auth: backend` initial-mint path inside connect().\n if (input.preMintedToken) {\n const ps = getPreMintedSecrets();\n if (ps) ps.set(kind, decl.id, toPreMinted(input.preMintedToken));\n // Without the store the credential is silently dropped and connect() will\n // fail its backend-auth mint with no trace — log the lost token.\n else\n log(\n `[session-resource] preMintedToken provided but secret store not ready — ${kind}:${decl.id}`,\n );\n }\n try {\n await rm.connect(decl);\n } catch (err) {\n if (input.preMintedToken) {\n getPreMintedSecrets()?.unset(kind, decl.id);\n }\n const message = err instanceof Error ? err.message : String(err);\n log(`[session-resource] runner.add_${kind} failed for ${decl.id}: ${message}`);\n return { ok: false, code: \"connect_failed\", message };\n }\n emitResourcesAvailable();\n log(`[session-resource] runner.add_${kind} connected ${decl.id}`);\n return { ok: true, id: decl.id };\n }\n\n /**\n * Materialize-then-attach-by-ref for `kind: connector`. The platform has\n * written `<projectDir>/.skaile/assets/connector/<name>/CONNECTOR.md`; the\n * runner self-derives the declaration, stages the wire-delivered credential\n * (no secret on disk), and connects it live via `ConnectorManager.connect`.\n * Mirrors the MCP `attachInstance` + `add()` paths.\n */\n async function attachConnectorInstance(\n name: string,\n preMintedToken?: { token: string; expiresAt?: string | null },\n ): Promise<AttachResult> {\n if (!name) {\n return { ok: false, code: \"invalid_input\", message: \"name is required\" };\n }\n if (name.includes(\"/\") || name.includes(\"\\\\\") || name.includes(\"..\")) {\n return {\n ok: false,\n code: \"invalid_input\",\n message: \"name must not contain path separators or traversal segments\",\n };\n }\n const projectDir = getProjectDir?.();\n if (!projectDir) {\n return { ok: false, code: \"no_project_dir\", message: \"getProjectDir not configured\" };\n }\n const root = join(projectDir, \".skaile/assets/connector\");\n const decl = deriveSingleMaterializedConnectorDeclaration(root, name);\n if (!decl) {\n return {\n ok: false,\n code: \"not_materialized\",\n message: `no materialized connector at ${join(root, name)}`,\n };\n }\n const rm = getResourceManager();\n if (!rm) return { ok: false, code: \"no_session\", message: \"session resources not ready\" };\n // Stage the wire-delivered credential before connect — off-disk by design\n // (Phase 2.5b); ConnectorManager consults the provider for the\n // `auth: backend` initial-mint path inside connect().\n if (preMintedToken) {\n const ps = getPreMintedSecrets();\n if (ps) ps.set(\"connector\", decl.id, toPreMinted(preMintedToken));\n // Without the store the credential is silently dropped and connect() will\n // fail its backend-auth mint with no trace — log the lost token.\n else\n log(\n `[session-resource] preMintedToken provided but secret store not ready — connector:${decl.id}`,\n );\n }\n try {\n await rm.connect(decl);\n } catch (err) {\n if (preMintedToken) {\n getPreMintedSecrets()?.unset(\"connector\", decl.id);\n }\n const message = err instanceof Error ? err.message : String(err);\n log(`[session-resource] runner.attach_instance connector failed for ${decl.id}: ${message}`);\n return { ok: false, code: \"connector_connect_failed\", message };\n }\n emitResourcesAvailable();\n log(`[session-resource] runner.attach_instance connected connector ${decl.id}`);\n return { ok: true, id: decl.id, live: true, toolCount: 0 };\n }\n\n return {\n addConnector: (input) => add(\"connector\", input),\n addMount: (input) => add(\"mount\", input),\n attachConnectorInstance,\n\n removeResource: async (input): Promise<MutateResult> => {\n const rm = getResourceManager();\n if (!rm) return { ok: false, code: \"no_session\", message: \"session resources not ready\" };\n if (!rm.has(input.id)) {\n return { ok: false, code: \"not_found\", message: `no resource with id ${input.id}` };\n }\n try {\n await rm.disconnect(input.id);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n log(`[session-resource] runner.remove_resource failed for ${input.id}: ${message}`);\n return { ok: false, code: \"disconnect_failed\", message };\n }\n // Drop the staged credential under both namespaces — the id space is\n // shared, so we don't know which kind owned it.\n // TODO(mcp-detach): removeResource covers connector/mount only; mcp: namespace cleanup lands with runner.remove_mcp_server.\n const ps = getPreMintedSecrets();\n ps?.unset(\"connector\", input.id);\n ps?.unset(\"mount\", input.id);\n emitResourcesAvailable();\n log(`[session-resource] runner.remove_resource removed ${input.id}`);\n return { ok: true };\n },\n\n updateCredential: async (input): Promise<MutateResult> => {\n const ps = getPreMintedSecrets();\n if (!ps) return { ok: false, code: \"no_session\", message: \"session resources not ready\" };\n const rm = getResourceManager();\n if (rm && !rm.has(input.id)) {\n return { ok: false, code: \"not_found\", message: `no resource with id ${input.id}` };\n }\n // CredentialMint's success branch is structurally a PreMintedCredential;\n // staging it lets the next token resolution pick up the rotated value\n // without a reconnect (full propagation to live rclone/git = Sprint 3).\n ps.set(input.kind, input.id, input.mint as unknown as PreMintedCredential);\n log(`[session-resource] runner.update_credential staged ${input.kind}:${input.id}`);\n return { ok: true };\n },\n };\n}\n","/**\n * Wires the `runner.add_mcp_server` and `runner.attach_instance` capabilities\n * to the live session's `ExternalMcpManager` + `PreMintedSecretProvider`. Free\n * of `serve.ts` imports — the dependency direction stays acyclic. The caller\n * passes getters because `serve.ts` lazily constructs the manager and secrets\n * provider.\n *\n * @category Runtime\n * @since 3.6.0\n */\nimport { join } from \"node:path\";\nimport {\n deriveSingleMaterializedMcpDeclaration,\n type McpServerDeclaration,\n} from \"@skaile/workspaces/core\";\nimport type { PreMintedSecretProvider } from \"@skaile/workspaces/connectors\";\nimport { McpServerAlreadyRegisteredError } from \"./external-mcp.js\";\nimport type { ExternalMcpManager } from \"./external-mcp.js\";\nimport { toPreMinted } from \"./session-resource-handlers.js\";\n\nexport interface McpRuntimeHandlerDeps {\n /** Returns `null` during the brief session-recreate gap; guard before use. */\n getOrCreateMcpManager: () => ExternalMcpManager | null;\n /** `null` when the session has no pre-minted secret store yet (CLI mode). */\n getPreMintedSecrets: () => PreMintedSecretProvider | null;\n /** True when the active driver picks up newly-registered capabilities without a session restart. */\n driverPicksUpToolsLive: () => boolean;\n emitResourcesAvailable: () => void;\n log: (msg: string) => void;\n /**\n * Absolute path to the session project directory (used by `attachInstance`\n * for materialized asset lookup). Required when `attachInstance` is invoked.\n */\n getProjectDir?: () => string;\n}\n\nexport interface McpRuntimeHandlers {\n addMcpServer?: (input: {\n declaration: McpServerDeclaration;\n preMintedToken?: { token: string; expiresAt?: string | null };\n }) => Promise<\n | { ok: true; id: string; live: boolean; toolCount: number }\n | { ok: false; code: string; message: string }\n >;\n\n /**\n * Materialize-then-attach-by-ref: the platform has already written\n * `<projectDir>/.skaile/assets/mcp-server/<name>/MCP.md` (+ optional\n * `.instance.json` with `resolvedSecrets`). The runner self-derives the\n * declaration from disk and attaches it live via `ExternalMcpManager.addServer`.\n * Connectors return `unsupported_kind` (deferred — Phase 2.5).\n */\n attachInstance?: (input: {\n kind: string;\n name: string;\n preMintedToken?: { token: string; expiresAt?: string | null };\n }) => Promise<\n | { ok: true; id: string; live: boolean; toolCount: number }\n | { ok: false; code: string; message: string }\n >;\n}\n\nexport function buildMcpRuntimeHandlers(deps: McpRuntimeHandlerDeps): McpRuntimeHandlers {\n return {\n addMcpServer: async (input) => {\n const decl = input.declaration;\n if (!decl?.id) {\n return { ok: false, code: \"invalid_declaration\", message: \"declaration.id is required\" };\n }\n const mgr = deps.getOrCreateMcpManager();\n if (!mgr) return { ok: false, code: \"no_session\", message: \"session resources not ready\" };\n // Stage the pre-minted bearer under mcp:<id> so transport construction resolves it.\n // toPreMinted adds ok:true — without it, resolve() silently returns undefined.\n if (input.preMintedToken) {\n deps.getPreMintedSecrets()?.set(\"mcp\", decl.id, toPreMinted(input.preMintedToken));\n }\n try {\n const { toolNames } = await mgr.addServer(decl);\n deps.emitResourcesAvailable();\n deps.log(\n `[mcp-runtime] runner.add_mcp_server connected ${decl.id} (${toolNames.length} tools)`,\n );\n return {\n ok: true,\n id: decl.id,\n live: deps.driverPicksUpToolsLive(),\n toolCount: toolNames.length,\n };\n } catch (err) {\n // Roll back the staged bearer so a later retry can re-stage cleanly.\n deps.getPreMintedSecrets()?.unset(\"mcp\", decl.id);\n const message = err instanceof Error ? err.message : String(err);\n const code =\n err instanceof McpServerAlreadyRegisteredError\n ? \"mcp_already_registered\"\n : \"mcp_connect_failed\";\n return { ok: false, code, message };\n }\n },\n\n attachInstance: async (input) => {\n if (input.kind !== \"mcp-server\") {\n return {\n ok: false,\n code: \"unsupported_kind\",\n message: `attach_instance supports mcp-server only; '${input.kind}' is not yet supported`,\n };\n }\n if (!input.name) {\n return { ok: false, code: \"invalid_input\", message: \"name is required\" };\n }\n if (input.name.includes(\"/\") || input.name.includes(\"\\\\\") || input.name.includes(\"..\")) {\n return {\n ok: false,\n code: \"invalid_input\",\n message: \"name must not contain path separators or traversal segments\",\n };\n }\n if (!deps.getProjectDir) {\n return { ok: false, code: \"no_project_dir\", message: \"getProjectDir not configured\" };\n }\n const subDir = join(deps.getProjectDir(), \".skaile/assets/mcp-server\", input.name);\n const decl = deriveSingleMaterializedMcpDeclaration(subDir, input.name);\n if (!decl) {\n return {\n ok: false,\n code: \"not_materialized\",\n message: `no materialized mcp-server at ${subDir}`,\n };\n }\n const mgr = deps.getOrCreateMcpManager();\n if (!mgr) return { ok: false, code: \"no_session\", message: \"session resources not ready\" };\n // Stage the pre-minted bearer under mcp:<id> so transport construction resolves it.\n // toPreMinted adds ok:true — without it, resolve() silently returns undefined.\n if (input.preMintedToken) {\n deps.getPreMintedSecrets()?.set(\"mcp\", decl.id, toPreMinted(input.preMintedToken));\n }\n try {\n const { toolNames } = await mgr.addServer(decl);\n deps.emitResourcesAvailable();\n deps.log(\n `[mcp-runtime] runner.attach_instance connected ${decl.id} (${toolNames.length} tools)`,\n );\n return {\n ok: true,\n id: decl.id,\n live: deps.driverPicksUpToolsLive(),\n toolCount: toolNames.length,\n };\n } catch (err) {\n // Roll back the staged bearer so a later retry can re-stage cleanly.\n if (input.preMintedToken) deps.getPreMintedSecrets()?.unset(\"mcp\", decl.id);\n const message = err instanceof Error ? err.message : String(err);\n const code =\n err instanceof McpServerAlreadyRegisteredError\n ? \"mcp_already_registered\"\n : \"mcp_connect_failed\";\n return { ok: false, code, message };\n }\n },\n };\n}\n","/**\n * Fleet-health flag dispatcher — consume side of the platform fleet-health signal.\n *\n * A fleet-managed mount is bound live by the host fleet rclone, so it is excluded\n * from the boot-time no-phantom-workspace barrier. The in-container manager runs a\n * local `stat`/`readdir` probe that catches directly-detectable failures (EIO /\n * dead bind), but a *silently-empty-but-writable* degraded fleet mount is only\n * visible to the host, which knows `core/stats.errors`.\n *\n * The platform fleet-health poll writes its verdict for connector `<id>` into\n * `<workspace>/.skaile/fleet-health/<id>` (body: `healthy` | `degraded` |\n * `error`). The runner watches that directory and forwards each verdict to the\n * ConnectorManager's `reportFleetHealth`, which trips/lifts the read-only gate\n * with hysteresis.\n *\n * Contract:\n * - dir: `<workspace>/.skaile/fleet-health/`\n * - file: one per connectorId; basename === connectorId.\n * - body: trimmed, lowercased; `healthy` → healthy, `degraded` → degraded\n * (live + readable but writes failing ⇒ read-only-readable surface),\n * anything else (`error` | unreadable | empty) → error (fail-closed).\n *\n * Extracted so the watcher logic can be unit-tested without the WebSocket server.\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { FleetHealthVerdict } from \"@skaile/workspaces/connectors\";\nimport type { Logger } from \"@skaile/workspaces/types\";\n\n/** Minimal ConnectorManager surface the dispatcher needs (structural for tests). */\nexport interface FleetHealthReporter {\n reportFleetHealth(connectorId: string, verdict: FleetHealthVerdict): Promise<void>;\n}\n\n/** Map a flag-file body to a verdict. Fail-closed: unknown/empty ⇒ `error`. */\nexport function parseFleetHealthBody(body: string): FleetHealthVerdict {\n const trimmed = body.trim().toLowerCase();\n if (trimmed === \"healthy\") return \"healthy\";\n // `degraded` = live + readable but writes failing → read-only-readable, not a\n // full mask. Distinct from `error` so visible content is not wrongly hidden.\n if (trimmed === \"degraded\") return \"degraded\";\n return \"error\";\n}\n\n/**\n * Read the verdict for one changed flag file and forward it to the manager.\n *\n * @param dir - the fleet-health flag directory.\n * @param fileName - the changed entry's basename (=== connectorId).\n * @param manager - the active connector manager, or `null` to short-circuit.\n */\nexport async function dispatchFleetHealthFlag(\n dir: string,\n fileName: string,\n manager: FleetHealthReporter | null,\n log: Logger,\n): Promise<void> {\n if (!manager) return;\n // fs.watch already yields a basename (entry name within the watched dir), so\n // no further basename() normalisation is needed.\n const connectorId = fileName;\n if (!connectorId || connectorId.startsWith(\".\")) return;\n let verdict: FleetHealthVerdict;\n try {\n verdict = parseFleetHealthBody(await readFile(join(dir, connectorId), \"utf8\"));\n } catch {\n // Unreadable flag — fail-closed to `error` so a vanished/locked file does not\n // silently leave a possibly-unhealthy mount writable.\n verdict = \"error\";\n }\n try {\n await manager.reportFleetHealth(connectorId, verdict);\n log.debug(\"fleet-health flag dispatched\", { connectorId, verdict });\n } catch (err) {\n log.warn(\"fleet-health flag dispatch failed\", {\n connectorId,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n","/**\n * Refresh-flag dispatcher — wake-mid-401 hardening for Tier-2 git connectors.\n *\n * The Tier-2 git credential-helper script (rendered by\n * `connectors/credential-helper-script.ts`) touches a workspace-level\n * refresh-flag file when it detects a stale credentials file. The runner\n * watches that flag via `fs.watch` and on `change` invokes the dispatcher\n * here, which:\n *\n * 1. Lists git connectors whose `exposeAccessToken === true` AND\n * `auth === 'backend'` (Tier-2 backend-mediated only — PAT connectors\n * can't be refreshed runtime-side).\n * 2. For each eligible connector, calls the GitConnector's\n * `refreshExposedCredential(connectorId, handle)` — which mediates a\n * fresh access token via the runner-supplied `tokenMediator` and\n * rewrites the credentials file via `atomicReplaceCredential`.\n *\n * Extracted into its own module so the watcher logic can be unit-tested\n * without spinning up the full WebSocket server.\n *\n * Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md` Step 9a.\n */\n\nimport type { Logger } from \"@skaile/workspaces/types\";\n\n/**\n * Minimal connector-manager surface the dispatcher needs. Matches the public\n * interface of `ConnectorManager` (`listGitConnectors`, `get`) but stays\n * structural so tests can pass mocks without importing the full class.\n */\nexport interface DispatchConnectorManager {\n listGitConnectors(): Array<{\n id: string;\n source: string;\n exposeAccessToken: boolean;\n auth?: string;\n }>;\n get(id: string): {\n connector: {\n refreshExposedCredential?: (connectorId: string, handle: unknown) => Promise<void>;\n };\n handle: unknown;\n };\n}\n\n/**\n * Iterate every currently connected git connector and refresh the credential\n * for those eligible (Tier-2 backend-mediated). Failures on one connector do\n * not abort the rest.\n *\n * @param manager - The active connector manager. Pass `null` to short-circuit\n * (used during the brief window between session boot and provisioning).\n * @param log - Logger. The dispatcher emits `info` on success and `warn` on\n * per-connector failure.\n */\nexport async function dispatchRefreshToExposedGitMounts(\n manager: DispatchConnectorManager | null,\n log: Logger,\n): Promise<void> {\n if (!manager) return;\n\n let gitConnectors: ReturnType<DispatchConnectorManager[\"listGitConnectors\"]>;\n try {\n gitConnectors = manager.listGitConnectors();\n } catch (err) {\n log.warn(\"listGitConnectors failed during refresh-flag dispatch\", {\n error: err instanceof Error ? err.message : String(err),\n });\n return;\n }\n\n const eligible = gitConnectors.filter(\n (m) => m.exposeAccessToken === true && m.auth === \"backend\",\n );\n if (eligible.length === 0) {\n log.debug(\"refresh-flag fired but no eligible git connectors (Tier-2 backend) found\");\n return;\n }\n\n log.info(\"refresh-flag fired -- dispatching backend mediation\", {\n connectorIds: eligible.map((m) => m.id),\n });\n\n await Promise.all(\n eligible.map(async (m) => {\n try {\n const entry = manager.get(m.id);\n if (typeof entry.connector.refreshExposedCredential !== \"function\") {\n log.debug(\"connector lacks refreshExposedCredential -- skipping\", {\n connectorId: m.id,\n });\n return;\n }\n await entry.connector.refreshExposedCredential(m.id, entry.handle);\n } catch (err) {\n log.warn(\"refresh-flag dispatch failed for connector\", {\n connectorId: m.id,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }),\n );\n}\n","/**\n * Runner-side capabilities (Protocol v3). Replaces the deleted v2\n * `AgentCommand` types `add_resource` / `remove_resource` /\n * `set_log_level` / `state_action` / lifecycle by exposing them as named\n * capabilities the platform invokes through the bidirectional\n * capability registry — the same wire pattern as agent->platform calls,\n * just in reverse.\n *\n * All seven caps are `audience: ['runtime']` so they never leak to the\n * LLM tool list or to the user-facing command palette (cmdK). They run\n * with `side: 'agent'` (handler lives in the agent runtime) and\n * `origin: { kind: 'framework' }` — `CapabilityOrigin` (as of\n * `@skaile/workspaces/types@4.0.0`) does not include a `runner` kind, and\n * per the v3 spec \"origin tag stays separate (origin.kind); audience\n * determines visibility\". The `runner.<verb>` naming convention lives\n * in the capability `name`, not in the origin tag.\n *\n * The factory takes a {@link RunnerCapabilityHandlers} bag so the\n * caller (typically `serve.ts`) wires each cap to its own state-\n * mutation helpers without this file having to import `serve.ts` —\n * keeping the dependency direction acyclic.\n *\n * @category Runtime\n * @since 3.0.0\n */\n\nimport type { McpServerDeclaration } from \"@skaile/workspaces/core\";\nimport { getLogStore } from \"@skaile/workspaces/core/logging\";\nimport type { CredentialMint, LogLevel } from \"@skaile/workspaces/types\";\nimport * as z from \"zod\";\nimport { type DefinedCapability, defineCapability } from \"./define-capability.js\";\n\n/**\n * Per-session handlers that runner-side capabilities delegate into. The\n * caller (typically `serve.ts`) wires these to its own state-mutation\n * helpers. Each method is optional; capabilities whose handler is\n * undefined return a structured `not_implemented` error.\n *\n * @category Runtime\n * @since 3.0.0\n */\nexport interface RunnerCapabilityHandlers {\n /**\n * Add a mount to the live session. Implementations typically delegate\n * to `VolumeManager.mount()` after staging the `preMintedToken` into\n * the secrets provider chain.\n */\n addMount?: (input: {\n declaration: unknown;\n preMintedToken?: { token: string; expiresAt?: string | null };\n }) => Promise<{ ok: true; id: string } | { ok: false; code: string; message: string }>;\n\n /**\n * Add a connector to the live session. Implementations typically\n * delegate to `ConnectorManager.connect()` after staging the\n * `preMintedToken`.\n */\n addConnector?: (input: {\n declaration: unknown;\n preMintedToken?: { token: string; expiresAt?: string | null };\n }) => Promise<{ ok: true; id: string } | { ok: false; code: string; message: string }>;\n\n /**\n * Remove a mount or connector by id. The id namespace is shared — the\n * handler resolves whichever manager owns it.\n */\n removeResource?: (input: {\n id: string;\n }) => Promise<{ ok: true } | { ok: false; code: string; message: string }>;\n\n /**\n * Replace the pre-minted credential on an existing mount or\n * connector. Used for proactive rotation before TTL expiry, so the\n * resource can keep running without a reconnect.\n */\n updateCredential?: (input: {\n kind: \"mount\" | \"connector\";\n id: string;\n mint: CredentialMint;\n }) => Promise<{ ok: true } | { ok: false; code: string; message: string }>;\n\n /**\n * Set the in-container LogStore minimum level. When omitted, the\n * cap falls back to calling `getLogStore()?.setLevel(level)` itself\n * (the default behaviour matches the legacy `set_log_level` command).\n */\n setLogLevel?: (input: { level: string }) => Promise<{ ok: true }>;\n\n /**\n * Write into the shared state store. Shape matches the legacy\n * `state_action` v2 command body so existing platform-side senders\n * can be migrated mechanically.\n */\n setState?: (input: { store: string; key: string; value: unknown }) => Promise<{ ok: true }>;\n\n /** Trigger a session lifecycle transition. */\n lifecycle?: (input: { phase: \"hibernate\" | \"close\" | \"compact\" }) => Promise<{ ok: true }>;\n\n /**\n * Live-attach a remote MCP server to the running session. Stages the\n * pre-minted bearer then delegates to `ExternalMcpManager.addServer`.\n */\n addMcpServer?: (input: {\n declaration: McpServerDeclaration;\n preMintedToken?: { token: string; expiresAt?: string | null };\n }) => Promise<\n | { ok: true; id: string; live: boolean; toolCount: number }\n | { ok: false; code: string; message: string }\n >;\n\n /**\n * Materialize-then-attach-by-ref: the platform writes the asset to\n * `.skaile/assets/mcp-server/<name>/` then invokes this cap; the runner\n * self-derives the declaration from disk and attaches it live.\n */\n attachInstance?: (input: {\n kind: string;\n name: string;\n preMintedToken?: { token: string; expiresAt?: string | null };\n }) => Promise<\n | { ok: true; id: string; live: boolean; toolCount: number }\n | { ok: false; code: string; message: string }\n >;\n}\n\n/** Common origin tag used by all runner-side caps. */\nconst RUNNER_CAP_ORIGIN = { kind: \"framework\" } as const;\n\n/**\n * Build the standard `not_implemented` reply for a cap whose handler\n * was not wired by the caller. The shape mirrors the success/error\n * union the wired handlers return, so callers consuming the result\n * uniformly only need one discriminator (`ok`).\n */\nfunction notImplemented(name: string): { ok: false; code: \"not_implemented\"; message: string } {\n return {\n ok: false,\n code: \"not_implemented\",\n message: `${name} handler not configured`,\n };\n}\n\n// Input schemas. `declaration` and `value` use `z.unknown()` with an\n// explicit `.refine(() => true)` so the inferred type is `unknown`\n// (required) rather than `unknown | undefined` (optional) — Zod's\n// default treatment of `z.unknown()` is optional even at the top of\n// an object, which would break the handler-input contract.\nconst requiredUnknown = z.unknown().refine(() => true);\n\nconst preMintedTokenSchema = z\n .object({\n token: z.string(),\n expiresAt: z.string().nullable().optional(),\n })\n .optional();\n\nconst mountDeclarationInput = z.strictObject({\n declaration: requiredUnknown,\n preMintedToken: preMintedTokenSchema,\n // The platform attaches a workspace-migration directive on add_mount; the\n // handler ignores it for now (replace-workspace hot-migration is a follow-up).\n // Accepted here so a real platform add_mount payload validates.\n migration: z.unknown().optional(),\n});\n\nconst connectorDeclarationInput = z.strictObject({\n declaration: requiredUnknown,\n preMintedToken: preMintedTokenSchema,\n});\n\n/**\n * Wire-contract input schema for `runner.add_mcp_server`. Exported so the\n * wire-contract fixture can assert the shape without importing the handler.\n */\nexport const addMcpServerInputSchema = z.strictObject({\n declaration: requiredUnknown,\n preMintedToken: preMintedTokenSchema,\n});\n\n/**\n * Wire-contract input schema for `runner.attach_instance`. Exported so the\n * wire-contract fixture can assert the shape without importing the handler.\n */\nexport const attachInstanceInputSchema = z.strictObject({\n kind: z.string(),\n name: z.string(),\n preMintedToken: preMintedTokenSchema,\n});\n\nconst removeResourceInput = z.strictObject({\n id: z.string(),\n});\n\nconst updateCredentialInput = z.strictObject({\n kind: z.enum([\"mount\", \"connector\"]),\n id: z.string(),\n // `CredentialMint` is a discriminated union from `@skaile/workspaces/types`.\n // We accept it as `z.unknown()` here because Zod can't easily mirror\n // a discriminated TypeScript union without duplicating the schema —\n // the platform side has already validated the shape before sending.\n mint: requiredUnknown,\n});\n\nconst setLogLevelInput = z.strictObject({\n level: z.enum([\"silent\", \"error\", \"warn\", \"info\", \"debug\", \"trace\"]),\n});\n\nconst setStateInput = z.strictObject({\n store: z.string(),\n key: z.string(),\n value: requiredUnknown,\n});\n\n// Canonical session-lifecycle contract. The platform invokes `runner.lifecycle`\n// with exactly this `{ phase }` shape (5 sites in the platform's\n// session-lifecycle.service.ts). `compact` is the platform-driven compaction\n// signal (manual + pre-hibernate); `shutdown` was never sent and is dropped.\nconst lifecycleInput = z.strictObject({\n phase: z.enum([\"hibernate\", \"close\", \"compact\"]),\n});\n\n/** Levels accepted by the underlying `LogStore.setLevel`. */\nconst VALID_LOG_STORE_LEVELS = new Set<LogLevel>([\"debug\", \"info\", \"warn\", \"error\"]);\n\n/**\n * Build the seven `runner.*` capabilities. Caller registers each with\n * `capabilityRegistry.register(cap, \"agent\")`.\n *\n * The returned capabilities are independent — the caller can also\n * register a subset, e.g. for a stub runner used in tests.\n *\n * @category Runtime\n * @since 3.0.0\n */\nexport function buildRunnerCapabilities(handlers: RunnerCapabilityHandlers): DefinedCapability[] {\n return [\n defineCapability({\n name: \"runner.add_mount\",\n displayName: \"Add mount\",\n description:\n \"Mount a volume into the live session. Used by the platform to attach data sources mid-session.\",\n side: \"agent\",\n origin: RUNNER_CAP_ORIGIN,\n audience: [\"runtime\"],\n kind: \"effect\",\n input: mountDeclarationInput,\n handler: async (input) => {\n if (!handlers.addMount) return notImplemented(\"runner.add_mount\");\n return handlers.addMount({\n declaration: input.declaration,\n preMintedToken: input.preMintedToken,\n });\n },\n }),\n defineCapability({\n name: \"runner.add_connector\",\n displayName: \"Add connector\",\n description:\n \"Connect a tool-providing connector into the live session. Used by the platform to attach databases, APIs, etc. mid-session.\",\n side: \"agent\",\n origin: RUNNER_CAP_ORIGIN,\n audience: [\"runtime\"],\n kind: \"effect\",\n input: connectorDeclarationInput,\n handler: async (input) => {\n if (!handlers.addConnector) return notImplemented(\"runner.add_connector\");\n return handlers.addConnector({\n declaration: input.declaration,\n preMintedToken: input.preMintedToken,\n });\n },\n }),\n // TODO(mcp-detach): no runner.remove_mcp_server yet — live MCP detach + mcp: credential cleanup deferred with the attach-by-ref rework.\n defineCapability({\n name: \"runner.add_mcp_server\",\n displayName: \"Add MCP server\",\n description:\n \"Live-attach a remote MCP server to the running session. Used by the platform to connect additional MCP tool servers mid-session.\",\n side: \"agent\",\n origin: RUNNER_CAP_ORIGIN,\n audience: [\"runtime\"],\n kind: \"effect\",\n input: addMcpServerInputSchema,\n handler: async (input) => {\n if (!handlers.addMcpServer) return notImplemented(\"runner.add_mcp_server\");\n // `requiredUnknown` keeps the wire schema dep-free; the handler narrows.\n return handlers.addMcpServer({\n declaration: input.declaration as McpServerDeclaration,\n preMintedToken: input.preMintedToken,\n });\n },\n }),\n defineCapability({\n name: \"runner.attach_instance\",\n displayName: \"Attach instance\",\n description:\n \"Materialize-then-attach-by-ref: the platform writes the asset to .skaile/assets/ then invokes this cap; the runner self-derives the declaration from disk and attaches it live.\",\n side: \"agent\",\n origin: RUNNER_CAP_ORIGIN,\n audience: [\"runtime\"],\n kind: \"effect\",\n input: attachInstanceInputSchema,\n handler: async (input) => {\n if (!handlers.attachInstance) return notImplemented(\"runner.attach_instance\");\n return handlers.attachInstance({\n kind: input.kind,\n name: input.name,\n preMintedToken: input.preMintedToken,\n });\n },\n }),\n defineCapability({\n name: \"runner.remove_resource\",\n displayName: \"Remove resource\",\n description:\n \"Detach a mount or connector by id. The id namespace is shared across both kinds.\",\n side: \"agent\",\n origin: RUNNER_CAP_ORIGIN,\n audience: [\"runtime\"],\n kind: \"effect\",\n input: removeResourceInput,\n handler: async (input) => {\n if (!handlers.removeResource) return notImplemented(\"runner.remove_resource\");\n return handlers.removeResource(input);\n },\n }),\n defineCapability({\n name: \"runner.update_credential\",\n displayName: \"Update credential\",\n description:\n \"Replace the pre-minted credential on an existing mount or connector. Used for proactive rotation before TTL expiry.\",\n side: \"agent\",\n origin: RUNNER_CAP_ORIGIN,\n audience: [\"runtime\"],\n kind: \"effect\",\n input: updateCredentialInput,\n handler: async (input) => {\n if (!handlers.updateCredential) return notImplemented(\"runner.update_credential\");\n return handlers.updateCredential({\n kind: input.kind,\n id: input.id,\n mint: input.mint as CredentialMint,\n });\n },\n }),\n defineCapability({\n name: \"runner.set_log_level\",\n displayName: \"Set log level\",\n description:\n \"Live-update the in-container LogStore minimum level without restarting the session.\",\n side: \"agent\",\n origin: RUNNER_CAP_ORIGIN,\n audience: [\"runtime\"],\n kind: \"effect\",\n input: setLogLevelInput,\n handler: async (input) => {\n if (handlers.setLogLevel) {\n return handlers.setLogLevel(input);\n }\n // Default behaviour matches the legacy `set_log_level` command:\n // adjust the process-singleton LogStore directly. The cap input\n // accepts 6 levels per the v3 spec for forward-compatibility with\n // `silent` / `trace`, but `LogStore.setLevel` only knows the four\n // canonical ones — drop unknown values silently.\n const candidate = input.level as LogLevel;\n if (VALID_LOG_STORE_LEVELS.has(candidate)) {\n getLogStore()?.setLevel(candidate);\n }\n return { ok: true };\n },\n }),\n defineCapability({\n name: \"runner.set_state\",\n displayName: \"Set state\",\n description:\n \"Write into the session shared state store. Shape matches the legacy state_action command body.\",\n side: \"agent\",\n origin: RUNNER_CAP_ORIGIN,\n audience: [\"runtime\"],\n kind: \"effect\",\n input: setStateInput,\n handler: async (input) => {\n if (!handlers.setState) {\n // Honour the protocol contract by returning a structured\n // not_implemented error; callers can detect the gap without\n // a thrown exception. Cast through unknown because the cap's\n // declared output is `{ ok: true }` per the legacy shape.\n return notImplemented(\"runner.set_state\") as unknown as { ok: true };\n }\n return handlers.setState({\n store: input.store,\n key: input.key,\n value: input.value,\n });\n },\n }),\n defineCapability({\n name: \"runner.lifecycle\",\n displayName: \"Session lifecycle\",\n description:\n \"Transition the session lifecycle: hibernate (connectors persist state), close (connectors finalize), or compact conversation history.\",\n side: \"agent\",\n origin: RUNNER_CAP_ORIGIN,\n audience: [\"runtime\"],\n kind: \"effect\",\n input: lifecycleInput,\n handler: async (input) => {\n if (!handlers.lifecycle) {\n return notImplemented(\"runner.lifecycle\") as unknown as { ok: true };\n }\n return handlers.lifecycle(input);\n },\n }),\n ];\n}\n","/**\n * Credentials-file helpers used by `serve.ts` for Claude Code subscription\n * credentials. Extracted so other modules (e.g. AI 401 mediation) can reuse\n * the atomic rewrite without importing from the much larger `serve.ts`.\n *\n * @category Credentials\n * @since 3.3.0\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { mkdir, rename, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\n/**\n * Well-known platform key for the Claude Code OAuth credentials JSON blob\n * forwarded by `provision_secrets`. The runner writes it to\n * `<home>/.claude/.credentials.json` instead of the secret provider since\n * the SDK reads it as a file.\n *\n * @docLink packages/runner/dev-guide#environment-variables\n */\nexport const CLAUDE_CODE_CREDENTIALS_KEY = \"CLAUDE_CODE_CREDENTIALS_JSON\";\n\n/**\n * Writes the Claude Code credentials JSON blob to the Claude user config dir\n * at the current canonical Linux path, `~/.claude/.credentials.json`, with\n * mode `0600`. Creates the parent directory with mode `0700` if needed.\n *\n * Atomic via tmp-file + rename within the same directory.\n *\n * Exported for unit tests + the AI 401 mediation helper.\n *\n * @docLink packages/runner/dev-guide#environment-variables\n */\nexport async function writeClaudeCodeCredentialsFile(home: string, json: string): Promise<string> {\n const claudeDir = join(home, \".claude\");\n await mkdir(claudeDir, { recursive: true, mode: 0o700 });\n const finalPath = join(claudeDir, \".credentials.json\");\n const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}`;\n await writeFile(tmpPath, json, { mode: 0o600 });\n await rename(tmpPath, finalPath); // POSIX atomic on same fs\n return finalPath;\n}\n\n/**\n * Atomically merge a fresh `accessToken` into the credentials JSON at\n * `<home>/.claude/.credentials.json`, preserving any other top-level fields\n * and the nested `claudeAiOauth` shape the platform writes at provision time.\n *\n * Read-modify-write under {@link writeClaudeCodeCredentialsFile}'s atomic-\n * rename semantics. Used by the runner's `onAuthError` callback (in\n * `serve.ts`) when the bridge driver asks for a credential refresh after\n * a 401 from the underlying agent.\n *\n * @param home - The home directory under which `.claude/.credentials.json`\n * lives.\n * @param accessToken - The fresh access token to persist.\n * @param expiresAt - Optional ISO timestamp for the rotated token.\n * @returns The path to the rewritten credentials file.\n *\n * Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`\n * § \"Runner-side handling on 401\" (now bridge-side).\n */\nexport async function mergeAndRewriteCredentialsFile(\n home: string,\n accessToken: string,\n expiresAt?: string | null,\n): Promise<string> {\n const credPath = join(home, \".claude\", \".credentials.json\");\n let merged: Record<string, unknown> = {};\n if (existsSync(credPath)) {\n try {\n merged = JSON.parse(readFileSync(credPath, \"utf-8\")) as Record<string, unknown>;\n } catch {\n merged = {};\n }\n }\n const oauthBlock = ((merged as { claudeAiOauth?: Record<string, unknown> }).claudeAiOauth ??\n {}) as Record<string, unknown>;\n oauthBlock.accessToken = accessToken;\n if (expiresAt) oauthBlock.expiresAt = expiresAt;\n (merged as { claudeAiOauth?: Record<string, unknown> }).claudeAiOauth = oauthBlock;\n // Top-level accessToken too, for SDK builds that read the flat shape.\n (merged as { accessToken?: string }).accessToken = accessToken;\n return writeClaudeCodeCredentialsFile(home, JSON.stringify(merged));\n}\n\n/**\n * Extract the access-token expiry from a raw Claude Code credentials JSON\n * blob. Supports both the nested `claudeAiOauth.expiresAt` shape the\n * platform writes at provision time and an optional top-level `expiresAt`\n * field used by some SDK builds.\n *\n * Returns `null` when the field is missing, empty, or not a parseable\n * date — callers treat `null` as \"static token, don't schedule a\n * proactive refresh\". Tolerates both ISO-8601 strings and millisecond\n * epochs (some Claude Code builds emit the epoch; normalise to ISO so\n * downstream code has one format to reason about).\n *\n * Used by the runner's proactive AI-credential refresh scheduler in\n * `serve.ts` to compute the next refresh fire time after a fresh\n * credential lands (initial provision OR `host.refresh_credential`\n * response). The runner never mutates the credentials blob; this is a\n * pure read.\n *\n * @docLink packages/runner/dev-guide#ai-credential-mediation\n */\nexport function extractClaudeAiOauthExpiresAt(json: string): string | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch {\n return null;\n }\n if (!parsed || typeof parsed !== \"object\") return null;\n const obj = parsed as Record<string, unknown>;\n const oauth = obj.claudeAiOauth as Record<string, unknown> | undefined;\n const raw = oauth?.expiresAt ?? obj.expiresAt;\n if (raw == null) return null;\n if (typeof raw === \"string\") {\n const t = Date.parse(raw);\n return Number.isFinite(t) ? new Date(t).toISOString() : null;\n }\n if (typeof raw === \"number\" && Number.isFinite(raw)) {\n // Epoch milliseconds (Claude Code subscription tokens encode it this way).\n return new Date(raw).toISOString();\n }\n return null;\n}\n\n/**\n * Read the current access token from the on-disk credentials file at\n * `<home>/.claude/.credentials.json`. Supports both the nested\n * `claudeAiOauth.accessToken` shape the platform writes and the flat\n * top-level `accessToken` some SDK builds use.\n *\n * Used by the 401-mediation path to fingerprint the just-rejected token (the\n * one currently on disk) before asking the platform to rotate it, so the\n * platform can coalesce concurrent rotations of the same dead token. Returns\n * `null` when the file is absent, unreadable, or carries no token.\n *\n * @docLink packages/runner/dev-guide#ai-credential-mediation\n */\nexport function readCurrentClaudeAccessToken(home: string): string | null {\n const credPath = join(home, \".claude\", \".credentials.json\");\n if (!existsSync(credPath)) return null;\n let parsed: unknown;\n try {\n parsed = JSON.parse(readFileSync(credPath, \"utf-8\"));\n } catch {\n return null;\n }\n if (!parsed || typeof parsed !== \"object\") return null;\n const obj = parsed as { claudeAiOauth?: { accessToken?: unknown }; accessToken?: unknown };\n const raw = obj.claudeAiOauth?.accessToken ?? obj.accessToken;\n return typeof raw === \"string\" && raw.length > 0 ? raw : null;\n}\n","/**\n * Session stimulus bus — generic trailing-edge coalescing turn driver.\n *\n * Connectors that observe state changes (FlowAdapter, future alert/inbox/\n * file-watch connectors) call `bus.signal(connectorId, { promptFragment, meta })`\n * to request that the agent be woken with a fresh turn. Multiple signals from\n * the same connector arriving within `coalesceMs` are folded into one turn,\n * with their `promptFragment`s concatenated by `\\n\\n` and their `meta` objects\n * collected into an array.\n *\n * Per-`connectorId` queues — concurrent connectors NEVER coalesce together;\n * each runs its own pending timer and turn pipeline.\n *\n * If `signal()` is called for a connector whose driveTurn is already in flight,\n * the new signal queues for the next cycle (a fresh timer starts only after\n * the in-flight turn settles).\n *\n * Distinct from `refresh-flag-dispatcher.ts`'s leading-edge debounce: that one\n * fires immediately and drops within a 2 s window. The stimulus bus is trailing-\n * edge collapse with a returned promise, so callers can `await` completion of\n * the turn that drained their signal.\n *\n * @docLink runner#session-stimulus-bus\n * @since 2.2.0\n */\n\nimport type { Logger } from \"@skaile/workspaces/types\";\n\n/**\n * One stimulus from a connector. The bus collapses contiguous signals from the\n * same connector into a single turn whose prompt is built by joining the\n * `promptFragment`s with `\\n\\n`.\n */\nexport interface StimulusSignal {\n /** Fragment the connector wants prepended to the next turn prompt. */\n promptFragment: string;\n /** Optional event metadata for tracing. Connector-defined. */\n meta?: Record<string, unknown>;\n /**\n * Trailing-edge coalesce window — multiple signals from the same connector\n * arriving within this many ms are folded into one turn with their\n * fragments concatenated. Default: 50 ms (a tick to let near-simultaneous\n * signals settle without perceptible delay).\n */\n coalesceMs?: number;\n}\n\n/**\n * Public surface returned by `createSessionStimulusBus`. Connectors hold a\n * reference to this and call `signal(...)` whenever they want to wake the\n * agent.\n */\nexport interface SessionStimulusBus {\n /**\n * Request a turn kick for `connectorId`. Resolves once the resulting turn\n * has drained (the supplied `driveTurn` resolved). Multiple parallel calls\n * within `coalesceMs` collapse into one turn and share a single resolution.\n */\n signal(connectorId: string, sig: StimulusSignal): Promise<void>;\n}\n\n/**\n * Drives one agent turn given a concatenated prompt fragment. The runner\n * supplies this when constructing the bus — typically wraps `driver.prompt`\n * + waits for `agent_end`. The bus calls it with all coalesced fragments\n * joined by newline.\n */\nexport type TurnDriver = (\n promptFragment: string,\n batchedMeta: Array<Record<string, unknown>>,\n) => Promise<void>;\n\nexport interface CreateStimulusBusOptions {\n driveTurn: TurnDriver;\n /** Default coalesce window when a signal omits its own. */\n defaultCoalesceMs?: number;\n log?: Logger;\n}\n\n/** Default coalesce window — kept consistent with the spec's stated default. */\nexport const DEFAULT_COALESCE_MS = 50;\n\ninterface PendingEntry {\n signal: StimulusSignal;\n resolve: () => void;\n reject: (err: unknown) => void;\n}\n\ninterface ConnectorQueue {\n /** Buffered entries waiting for the current timer to fire. */\n pending: PendingEntry[];\n /** The timer that will fire `flushQueue`. `null` when no timer is active. */\n timer: ReturnType<typeof setTimeout> | null;\n /**\n * `true` when `driveTurn` is currently running for this connector. New\n * signals arriving while this is set queue up but do NOT start their timer\n * until the in-flight turn settles.\n */\n inFlight: boolean;\n}\n\n/**\n * Construct a fresh stimulus bus. The caller (typically `serve.ts` or\n * `run-flow.ts`) provides `driveTurn`, which kicks one agent turn given a\n * joined prompt + batched meta, and resolves once the turn drains.\n */\nexport function createSessionStimulusBus(opts: CreateStimulusBusOptions): SessionStimulusBus {\n const { driveTurn, defaultCoalesceMs = DEFAULT_COALESCE_MS, log } = opts;\n const queues = new Map<string, ConnectorQueue>();\n\n function getQueue(connectorId: string): ConnectorQueue {\n let q = queues.get(connectorId);\n if (!q) {\n q = { pending: [], timer: null, inFlight: false };\n queues.set(connectorId, q);\n }\n return q;\n }\n\n function startTimerIfNeeded(connectorId: string, q: ConnectorQueue, coalesceMs: number) {\n if (q.timer != null) return;\n if (q.inFlight) return; // wait until the in-flight turn settles\n q.timer = setTimeout(() => {\n q.timer = null;\n void flushQueue(connectorId, q);\n }, coalesceMs);\n }\n\n async function flushQueue(connectorId: string, q: ConnectorQueue): Promise<void> {\n if (q.pending.length === 0) return;\n const batch = q.pending;\n q.pending = [];\n q.inFlight = true;\n\n const fragments = batch.map((e) => e.signal.promptFragment);\n const metas = batch\n .map((e) => e.signal.meta)\n .filter((m): m is Record<string, unknown> => m !== undefined);\n const joined = fragments.join(\"\\n\\n\");\n\n log?.debug(\"turn driving\", {\n connectorId,\n count: batch.length,\n fragmentLength: joined.length,\n });\n\n try {\n await driveTurn(joined, metas);\n log?.debug(\"turn drained\", {\n connectorId,\n count: batch.length,\n fragmentLength: joined.length,\n });\n for (const entry of batch) entry.resolve();\n } catch (err) {\n log?.debug(\"turn failed\", {\n connectorId,\n count: batch.length,\n fragmentLength: joined.length,\n error: err instanceof Error ? err.message : String(err),\n });\n for (const entry of batch) entry.reject(err);\n } finally {\n q.inFlight = false;\n // If signals arrived while the turn was in flight, kick a fresh timer\n // for the next cycle so the next batch drains.\n if (q.pending.length > 0) {\n // Use the most recent signal's coalesceMs as the next window — it's\n // the simplest predictable choice when callers may have heterogeneous\n // windows.\n const nextWindow = q.pending[q.pending.length - 1]?.signal.coalesceMs ?? defaultCoalesceMs;\n startTimerIfNeeded(connectorId, q, nextWindow);\n }\n }\n }\n\n return {\n signal(connectorId: string, sig: StimulusSignal): Promise<void> {\n const coalesceMs = sig.coalesceMs ?? defaultCoalesceMs;\n log?.debug(\"stimulus signaled\", {\n connectorId,\n fragmentLength: sig.promptFragment.length,\n });\n return new Promise<void>((resolve, reject) => {\n const q = getQueue(connectorId);\n q.pending.push({ signal: sig, resolve, reject });\n startTimerIfNeeded(connectorId, q, coalesceMs);\n });\n },\n };\n}\n","/**\n * serve.ts — WebSocket agent server.\n *\n * Exposes the agent runtime over a pluggable transport. Accepts AgentCommand\n * messages and streams AgentEvent responses. Uses WebSocketServerTransport for\n * the default transport (pass opts.transport to override for testing/stdio).\n *\n * Usage:\n * skaile serve --project-dir /project --port 8080\n *\n * The platform's session manager connects via AgentClient + WebSocketClientTransport\n * to drive agent execution inside a local subprocess or Docker container.\n *\n * ─── Session Startup Pattern ───────────────────────────────────────────────────\n *\n * All three runner modes (REPL, flow, serve) follow the same 5-step setup:\n * 1. resolveSettings() → driver, model, provider, API key\n * 2. loadAgentManifest() → manifest (model/maxTurns/tools); optionally systemPrompt\n * 3. buildAgentResources() → ConnectorManager, resourcePromptSection, mcpServers\n * 4. createDriver() → AgentDriver with assembled systemPrompt\n * 5. driver.start() → subprocess spawn / SDK import\n *\n * Differences between modes:\n * REPL — identity native (agentDir/agentName); systemPrompt = resource docs only; eager start\n * Flow — identity injected (full SOUL+RULES+knowledge); no transport; single orchestrator prompt\n * Serve — identity injected + external (SKAILE_SYSTEM_PROMPT_FILE); lazy start (first prompt cmd);\n * adds EventNormalizer, resource watch callbacks, lifecycle command handling\n *\n * The shared `createAgentSession(opts)` helper in session-builder.ts extracts the\n * common setup sequence. serve.ts retains: EventNormalizer, lazy start (driverStarted flag),\n * transport setup, and lifecycle command handling.\n */\n\nimport {\n existsSync,\n type FSWatcher,\n watch as fsWatch,\n chmodSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport {\n deployCatalogEntry,\n undeployCatalogEntry,\n} from \"@skaile/workspaces/asset-manager/catalog-deployer\";\nimport { type AgentEvent as BridgeAgentEvent, EventNormalizer } from \"@skaile/workspaces/bridge\";\nimport {\n buildSdkConnectorTools,\n type ConnectorHandle,\n ConnectorManager,\n type FlowAdapter,\n InMemorySecretProvider,\n PreMintedSecretProvider,\n registerBuiltinConnectors,\n type TokenMediator,\n type TokenMediatorResult,\n} from \"@skaile/workspaces/connectors\";\nimport {\n type CatalogEntry,\n parseAssetRef,\n providerEnvKey,\n resolveAgentDir,\n resolveDriverPaths,\n resolveSkWorkspaceConfig,\n stageMaterializedSkills,\n} from \"@skaile/workspaces/core\";\nimport { createLogger, WsLogSink } from \"@skaile/workspaces/core/logging\";\nimport type { FlowDefinition } from \"@skaile/workspaces/factory-assets/connectors/flow/engine\";\nimport {\n buildOrchestratorPrompt,\n renderStimulusPrompt,\n type TurnStimulus,\n} from \"@skaile/workspaces/factory-assets/connectors/flow/prompt-fragments\";\nimport { WebSocketServerTransport } from \"@skaile/workspaces/transport\";\nimport type {\n AgentCommand,\n AgentEvent,\n ConnectorInfo,\n ConnectorsAvailableEvent,\n FlowExecution,\n MountInfo,\n ServerTransport,\n} from \"@skaile/workspaces/types\";\nimport { PROTOCOL_VERSION } from \"@skaile/workspaces/types\";\n// Static import so bun --compile bundles zod into the binary. Without this,\n// dynamic import(\"zod\") fails at runtime inside the /$bunfs/ virtual filesystem.\nimport { z as _z } from \"zod\";\nimport { createAiCredentialRefreshScheduler } from \"./ai-credential-refresh.js\";\nimport {\n buildRefreshCredentialInput,\n isTransientMintFailure,\n retryTransientMint,\n} from \"./ai-credential-retry.js\";\nimport { handleCredentialRotatedSignal, isCredentialRotatedSignal } from \"./credential-rotated.js\";\nimport { planRuntimeSessionEmit, type RuntimeSessionSnapshot } from \"./runtime-session-emit.js\";\nimport { bootstrapCapabilityRegistry } from \"./builtin-capabilities.js\";\nimport { CapabilityRegistry, computeCapabilitySignature } from \"./capability-registry.js\";\nimport {\n buildClientCapabilityHandler as buildClientCapabilityRoundtripHandler,\n DEFAULT_CAPABILITY_CALL_TIMEOUT_MS,\n dispatchRunnerCapabilityInvocation,\n type PendingCallEntry,\n rejectCapabilityOnApprovalDeny,\n resolveCapabilityCallTimeoutMs,\n resolveCapabilityResult,\n} from \"./capability-roundtrip.js\";\nimport { CompactionOrchestrator } from \"./compaction/index.js\";\nimport { registerCompositionCapabilities } from \"./composition/bootstrap.js\";\nimport { type MountPoint, rewriteFileChangedPath } from \"./file-changed-rewriter.js\";\nimport { bootstrapRunnerLogStore } from \"./logging-bootstrap.js\";\nimport { buildCapabilitiesPromptSection } from \"./prompt-assembly.js\";\nimport { buildLifecycleHandler } from \"./lifecycle-handler.js\";\nimport { buildMcpRuntimeHandlers } from \"./mcp-runtime-handlers.js\";\nimport { dispatchFleetHealthFlag } from \"./fleet-health-flag-dispatcher.js\";\nimport { dispatchRefreshToExposedGitMounts } from \"./refresh-flag-dispatcher.js\";\nimport { handleMountResourceRequest, handleResourceRequest } from \"./resource-handler.js\";\nimport { buildRunnerCapabilities } from \"./runner-capabilities.js\";\nimport {\n CLAUDE_CODE_CREDENTIALS_KEY,\n extractClaudeAiOauthExpiresAt,\n mergeAndRewriteCredentialsFile,\n readCurrentClaudeAccessToken,\n writeClaudeCodeCredentialsFile,\n} from \"./serve-credentials.js\";\nimport {\n type AgentSession,\n type AgentSessionConfig,\n createAgentSession,\n} from \"./session-builder.js\";\nimport { buildSessionResourceHandlers } from \"./session-resource-handlers.js\";\nimport { createSessionStimulusBus, type SessionStimulusBus } from \"./session-stimulus.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Pull catalog entries from the active session's runtime assets, with a safe\n * fallback to empty when the session was not yet created or the resolver\n * failed. The session-builder caches the same `RuntimeAssetsResult` across\n * the session lifetime so live-update paths see a stable view.\n */\nfunction getSessionCatalogEntries(session: AgentSession | undefined): CatalogEntry[] {\n return session?.runtimeAssets?.catalogEntries ?? [];\n}\n\n/**\n * Emit a `system_prompt_composed` event carrying the labeled section\n * breakdown from the freshly-built {@link AgentSession}. Called from every\n * `createAgentSession` consumer in serve.ts (initial bootstrap, configure\n * re-runs, add_resource flow-connector path, aiResources skill changes,\n * session_init provisioned path) so the platform's debug panel always sees\n * the prompt the agent is actually receiving.\n *\n * Keeping the emission centralised in serve.ts (rather than inside\n * session-builder.ts) preserves the builder's transport-agnostic contract —\n * forge apps and the CLI consume the same builder without a transport.\n *\n * Spec: `docs/superpowers/specs/2026-05-13-platform-agent-prompt-design.md`\n * § 3.3.2 Re-emission requirement.\n * @since 2026-05\n */\nexport function emitSystemPromptComposed(\n agentSession: AgentSession,\n sendEvent: (e: AgentEvent) => void,\n): void {\n sendEvent({\n type: \"system_prompt_composed\",\n sections: agentSession.systemPromptSections,\n composedAt: new Date().toISOString(),\n });\n}\n\n/** Collect installed @skaile/* package versions. Cached per process. */\nconst FRAMEWORK_PACKAGES = [\n \"@skaile/workspaces/runner\",\n \"@skaile/workspaces/bridge\",\n \"@skaile/workspaces/core\",\n \"@skaile/workspaces/types\",\n \"@skaile/workspaces/factory-assets\",\n \"@skaile/workspaces/connectors\",\n \"@skaile/workspaces/resolver\",\n \"@skaile/workspaces/transport\",\n \"@skaile/workspaces/workspace-plugin\",\n] as const;\n\nlet _frameworkVersions: Record<string, string> | null = null;\nfunction getFrameworkVersions(): Record<string, string> {\n if (_frameworkVersions) return _frameworkVersions;\n const versions: Record<string, string> = {};\n for (const pkg of FRAMEWORK_PACKAGES) {\n try {\n const pjPath = require.resolve(`${pkg}/package.json`);\n const pj = JSON.parse(readFileSync(pjPath, \"utf-8\"));\n versions[pkg.replace(\"@skaile/\", \"\")] = pj.version;\n } catch {\n // not installed\n }\n }\n _frameworkVersions = versions;\n return versions;\n}\n\n// ---------------------------------------------------------------------------\n// Resource lifecycle helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Split a unified `ConnectorManager`'s connectors into the wire-shape\n * `mounts` / `connectors` arrays the `resources_available` event expects.\n *\n * Filesystem-face connectors (those with a `mountPath`) are reported as\n * mounts; the rest are reported as connectors. The unified manager owns both,\n * so this is purely a wire-format projection.\n */\nfunction splitConnectorsForWire(manager: ConnectorManager | null): {\n mounts: MountInfo[];\n connectors: ConnectorInfo[];\n} {\n const mounts: MountInfo[] = [];\n const connectors: ConnectorInfo[] = [];\n if (!manager) return { mounts, connectors };\n for (const c of manager.listConnectors()) {\n if (typeof c.mountPath === \"string\") {\n let source = \"\";\n try {\n source = manager.get(c.id).declaration.mount?.source ?? \"\";\n } catch {\n /* connector vanished between list and get — best-effort */\n }\n mounts.push({\n id: c.id,\n driver: c.driver,\n ...(c.label ? { label: c.label } : {}),\n access: c.access,\n mountPath: c.mountPath,\n // A deferred (background) mount is pre-registered with its path but\n // status \"connecting\" — report it as not-yet-mounted; the platform\n // flips it on the subsequent connector_status \"connected\" event.\n mounted: c.status === \"connected\",\n source,\n });\n } else {\n connectors.push({\n id: c.id,\n driver: c.driver,\n ...(c.label ? { label: c.label } : {}),\n access: c.access,\n operations: manager.getOperations(c.id).map((op) => op.name),\n });\n }\n }\n return { mounts, connectors };\n}\n\n/** Minimal view of `ExternalMcpManager` needed to render the wire payload. */\nexport type McpServerLister = {\n listServers(): Array<{ id: string; transport: \"stdio\" | \"sse\" | \"http\"; toolCount: number }>;\n};\n\n/**\n * Build the `resources_available` wire payload: connector/mount split plus the\n * live MCP server list. Each MCP server is stamped with `live` — whether the\n * active driver already sees its tools without a session restart.\n *\n * A server is live when `driverLive` (bridge drivers recompose tools per turn)\n * OR it was baked into the current driver at its (re)creation (`bakedServerIds`,\n * declared/cold-start). Only a server hot-added to an unrecreated claude-sdk\n * driver is `live: false`. A server not in `bakedServerIds` gets `live:\n * driverLive`; omitting the argument is equivalent to an empty set.\n *\n * Exported for unit testing.\n */\nexport function buildResourcesAvailablePayload(\n manager: ConnectorManager | null,\n mcpManager: McpServerLister | null,\n driverLive: boolean,\n bakedServerIds?: ReadonlySet<string>,\n): ConnectorsAvailableEvent {\n const { mounts, connectors } = splitConnectorsForWire(manager);\n const mcp_servers = (mcpManager?.listServers() ?? []).map((s) => ({\n ...s,\n live: driverLive || (bakedServerIds?.has(s.id) ?? false),\n }));\n return { type: \"resources_available\", mounts, connectors, mcp_servers };\n}\n\n/** Walk upward from a directory looking for an ai-assets/ folder. */\nfunction findAiAssetsRoot(startDir: string): string | null {\n let dir = startDir;\n for (let i = 0; i < 6; i++) {\n const candidate = join(dir, \"ai-assets\");\n if (existsSync(candidate)) return candidate;\n dir = join(dir, \"..\");\n }\n return null;\n}\n\n/**\n * Phase 4.8 — Claude Code subscription credentials provisioning.\n *\n * The constant + the atomic rewrite helper now live in `./serve-credentials.ts`\n * so the AI 401 mediation helper can reuse them without importing from this\n * (large) module. Re-exported here for back-compat with existing test\n * imports of `serve.js`.\n *\n * @docLink packages/runner/dev-guide#environment-variables\n */\nexport {\n CLAUDE_CODE_CREDENTIALS_KEY,\n extractClaudeAiOauthExpiresAt,\n writeClaudeCodeCredentialsFile,\n};\n\n/**\n * Idempotently ensure `~/.gitconfig` includes the runner-managed gitconfig\n * via `[include] path = <managedGitconfigPath>`. Fallback path for shells\n * that strip `GIT_CONFIG_GLOBAL`. The function is idempotent — running it\n * twice produces the same file content.\n *\n * Exported for unit tests.\n * @docLink packages/runner/capabilities#ensure-git-config-include\n */\nexport function ensureGitConfigInclude(managedGitconfigPath: string): void {\n const home = process.env.HOME ?? homedir();\n if (!home) return;\n const gitconfigPath = join(home, \".gitconfig\");\n let existing = \"\";\n try {\n existing = readFileSync(gitconfigPath, \"utf-8\");\n } catch {\n // file doesn't exist — fall through and create\n }\n // Bail if any include block already references our managed file. Walk the\n // gitconfig line-by-line tracking the current section header so a stray\n // `path = …` key inside an unrelated section (e.g. `[some-other] path = …`)\n // does not trigger a false-positive match. Git only honours `path` keys\n // under `[include]` and `[includeIf \"<cond>\"]`; mirror that contract here.\n const sectionRe = /^\\s*\\[([^\\]\\s]+)(?:\\s+\"[^\"]*\")?\\]\\s*$/;\n const pathKeyRe = /^\\s*path\\s*=\\s*(.+?)\\s*$/;\n let currentSection: string | null = null;\n for (const line of existing.split(/\\r?\\n/)) {\n const sectionMatch = line.match(sectionRe);\n if (sectionMatch) {\n currentSection = sectionMatch[1]?.toLowerCase() ?? null;\n continue;\n }\n if (currentSection !== \"include\" && currentSection !== \"includeif\") continue;\n const pathMatch = line.match(pathKeyRe);\n if (pathMatch?.[1] === managedGitconfigPath) return;\n }\n if (!existsSync(dirname(gitconfigPath))) {\n mkdirSync(dirname(gitconfigPath), { recursive: true });\n }\n const block =\n `${existing.trimEnd()}\\n` +\n `# skaile-runner: managed-gitconfig include\\n` +\n `[include]\\n\\tpath = ${managedGitconfigPath}\\n`;\n writeFileSync(gitconfigPath, block, { mode: 0o644 });\n}\n\n// v3 protocol — handleRemountMount removed alongside the RemountMountCommand\n// wire type. Hot remounting is now reachable through the runner.add_mount\n// capability (the platform's invokeRunnerCapability dispatch path), which\n// handles the disconnect+connect semantics via the ConnectorManager surface.\n\n/**\n * Tier-2 managed-gitconfig env propagation (git credential tiers, Step 1A).\n *\n * The runner owns one path — `<projectDir>/.skaile/managed-gitconfig` — and\n * exposes it to every spawned agent shell via `GIT_CONFIG_GLOBAL`. The git\n * mount driver writes per-mount tagged blocks into this file when (and only\n * when) `exposeAccessToken: true` is set on the mount declaration. Bridge\n * drivers inherit the runner's env when spawning agent processes, so no\n * change is required on their side.\n *\n * Belt-and-suspenders: also write `[include] path = …` into `~/.gitconfig`\n * so shells that strip `GIT_CONFIG_GLOBAL` still pick the file up. The\n * include is idempotent — a second run will not append a duplicate line.\n *\n * Spec: `_devlog/specs/2026-05-05-git-credential-tiers.md`.\n */\nfunction setupManagedGitconfig(\n projectDir: string,\n serverLog: ReturnType<typeof createLogger>,\n): void {\n const managedGitconfigPath = join(projectDir, \".skaile\", \"managed-gitconfig\");\n process.env.GIT_CONFIG_GLOBAL = managedGitconfigPath;\n try {\n ensureGitConfigInclude(managedGitconfigPath);\n } catch (err) {\n serverLog.warn(\"failed to write ~/.gitconfig include — relying on env only\", {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Configuration for {@link startAgentServer}.\n * @docLink packages/runner/dev-guide#flow-execution-turn-based-model\n */\nexport interface ServeOptions {\n /**\n * WebSocket server port. Defaults to `8080`.\n * Ignored when a custom {@link transport} is provided.\n */\n port?: number;\n /** Absolute path to the project working directory. */\n projectDir: string;\n /**\n * GitAgent definition directory (`agent.yaml`, `SOUL.md`, `RULES.md`,\n * `knowledge/`). When omitted, resolved from `skaile.yaml` via\n * `resolveAgentDir`. If unresolvable, no agent definition is loaded and the\n * agent starts without an identity prompt.\n */\n agentDir?: string;\n /** Agent driver backend override (e.g. `\"omp\"`, `\"claude-sdk\"`). */\n driver?: string;\n /** LLM model name override. */\n model?: string;\n /** LLM provider override (e.g. `\"anthropic\"`, `\"openrouter\"`). */\n provider?: string;\n /** Directory of deployed prompt/command files appended to the system prompt. */\n promptsDir?: string;\n /** Stable session ID for conversation continuity across agent turns. */\n sessionId?: string;\n /**\n * OMP driver session ID to resume. When set, OMP is spawned with\n * `--session <id>` to restore its native conversation context without\n * needing `<conversation_history>` injection. For OMP driver only.\n */\n resumeSessionId?: string;\n /** Called for each diagnostic log line. Defaults to `console.log`. */\n onLog?: (line: string) => void;\n /**\n * Pre-built transport to use instead of the default\n * `WebSocketServerTransport`. Useful for testing (in-process transport,\n * stdio transport) or embedding the server in another process.\n */\n transport?: ServerTransport;\n /**\n * Bearer token the default WebSocket server requires from connecting clients.\n * Falls back to `SKAILE_WS_AUTH_TOKEN`. When neither is set the server accepts\n * unauthenticated connections (back-compatible default). Ignored when a custom\n * {@link transport} is provided.\n */\n authToken?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Server\n// ---------------------------------------------------------------------------\n\n/**\n * Map a connector driver to the platform `host.refresh_credential` `kind`, or\n * `null` when the driver has no backend refresh path. Today only git mounts are\n * refreshable through the platform handler (it dispatches `git-mount`); the\n * rclone-backed mounts (sharepoint/webdav/googledrive) are fleet/host-managed\n * and the handler rejects their kinds, so they get no in-container refresh.\n */\nexport function connectorRefreshKind(driver?: string): string | null {\n return driver === \"git\" ? \"git-mount\" : null;\n}\n\n/**\n * Build the connector token-refresh mediator. The `ConnectorManager`'s pre-mint\n * wrapper serves `reason:\"initial\"` from the pre-minted credentials and forwards\n * every `refresh` / `retry-401` here, so a backend-auth git mount rotates its\n * token through `host.refresh_credential` instead of going stale. The platform\n * handler resolves the credential by **provider link id**, so this passes\n * `id: providerLinkId` (NOT the connector id). Returns a structured\n * `not-configured` mint — never throwing — when there is no transport, the\n * driver has no backend refresh path, or the declaration carries no\n * `providerLinkId` (standalone/CLI and non-git connectors degrade as before).\n */\nexport function buildConnectorTokenMediator(deps: {\n isConnected: () => boolean;\n invokeRemote: (name: string, input: unknown) => Promise<unknown>;\n log: (line: string) => void;\n}): TokenMediator {\n return async ({ connectorId, reason, driver, providerLinkId }) => {\n if (!deps.isConnected()) {\n return {\n ok: false,\n code: \"not-configured\",\n message: \"standalone runner cannot mediate connector refresh\",\n };\n }\n const kind = connectorRefreshKind(driver);\n if (!kind) {\n return {\n ok: false,\n code: \"not-configured\",\n message: `connector '${connectorId}' (driver=${driver ?? \"unknown\"}) has no backend refresh path`,\n };\n }\n if (!providerLinkId) {\n return {\n ok: false,\n code: \"not-configured\",\n message: `connector '${connectorId}' is missing a providerLinkId; cannot refresh`,\n };\n }\n try {\n const raw = (await deps.invokeRemote(\"host.refresh_credential\", {\n kind,\n id: providerLinkId,\n reason,\n })) as TokenMediatorResult | null | undefined;\n // Validate the discriminator before handing the result to the git driver:\n // a malformed `{ ok: true, token: null }` would otherwise surface as a\n // confusing failure deep in the credential helper.\n if (typeof raw?.ok !== \"boolean\" || (raw.ok && typeof raw.token !== \"string\")) {\n deps.log(\n `[serve] connector refresh returned a malformed mint (id=${connectorId}, kind=${kind})`,\n );\n return { ok: false, code: \"backend-error\", message: \"malformed mint from host\" };\n }\n if (!raw.ok) {\n deps.log(\n `[serve] connector refresh failed (id=${connectorId}, kind=${kind}, code=${raw.code})`,\n );\n }\n return raw;\n } catch (err) {\n const m = err instanceof Error ? err.message : String(err);\n return { ok: false, code: \"backend-error\", message: m };\n }\n };\n}\n\n/**\n * Start a WebSocket agent server that the Skaile platform connects to for\n * host-driven agent execution inside a local subprocess or Docker container.\n *\n * The server accepts {@link AgentCommand} messages over a\n * {@link ServerTransport} (default: `WebSocketServerTransport` on `opts.port`)\n * and streams {@link AgentEvent} responses back to the connected client.\n *\n * Handled commands:\n * - `provision_secrets` — injects API keys and Claude Code credentials; in\n * `provisioned` secrets mode, triggers deferred session creation.\n * - `configure` — registers shared state stores and applies mid-session skill\n * catalog changes. Phase 4 of the flow-connector extraction (Protocol 2.2)\n * removed the implicit `activeFlows` rehydration; hosts now issue an\n * explicit `connector_mutate { id: \"flow\", op: \"hydrate\" }` per flow.\n * - `prompt` — routes free-chat messages through the SessionStimulusBus when\n * a flow is active, otherwise forwards directly to the driver; **driver is\n * lazily started on the first `prompt` command**.\n * - `connector_mutate` / `connector_query` — generic connector dispatch.\n * Replaces the 6 typed flow commands removed in Protocol 2.2 (`start_flow`,\n * `approve_flow_node`, `provide_flow_input`, `cancel_flow`,\n * `set_flow_autonomous_mode`, `retry_flow_node`); see\n * `MIGRATION-flow-connector.md` for the per-op mapping table.\n * - `add_resource` / `remove_resource` — mount/unmount mounts or\n * connect/disconnect connectors mid-session. When the added connector's\n * driver is `flow`, the runner injects the per-session stimulus bus into\n * the connect options.\n *\n * The function resolves after the transport starts listening. It does not\n * resolve until the process exits — shutdown is driven by SIGINT/SIGTERM or\n * a `shutdown` command from the connected client.\n *\n * @param opts - Server configuration.\n * @docLink packages/runner/dev-guide#flow-execution-turn-based-model\n */\nexport async function startAgentServer(opts: ServeOptions): Promise<void> {\n const port = opts.port ?? 8080;\n const sessionId = opts.sessionId ?? process.env.SKAILE_SESSION_ID ?? \"session-unknown\";\n const resumeSessionId = opts.resumeSessionId ?? process.env.SKAILE_RESUME_SESSION_ID;\n\n // Read platform maxTurns from workspace config (before createAgentSession)\n const wsConfig = resolveSkWorkspaceConfig(opts.projectDir);\n\n // Bootstrap structured logging — registers a process-singleton LogStore.\n // OnLogBridgeSink mirrors entries to opts.onLog when caller provides it,\n // preserving back-compat with hosts that consume plain text lines.\n const { store: logStore, dispose: disposeLogStore } = bootstrapRunnerLogStore({\n sessionId,\n projectDir: opts.projectDir,\n yamlBlock: (wsConfig as { logging?: unknown }).logging,\n onLog: opts.onLog,\n });\n const serverLog = createLogger({\n kind: \"runner\",\n subkind: \"session\",\n instance: sessionId,\n });\n // Back-compat: keep `log()` as a string alias so existing call sites continue\n // to work; new diagnostics should call serverLog.{info,warn,error,debug} directly.\n const log = (line: string) => serverLog.info(line);\n const profile = wsConfig.agent_config?.default;\n const maxTurns =\n wsConfig.agent?.permissions?.max_turns ??\n ((profile as Record<string, unknown> | undefined)?.max_turns as number | undefined);\n\n setupManagedGitconfig(opts.projectDir, serverLog);\n\n // Resolve the agent definition directory. CLI flag wins; otherwise fall back\n // to skaile.yaml `agent.definition` via resolveAgentDir. Without this, the\n // agent identity (SOUL+RULES+knowledge) is rendered at install time, not loaded at runtime.\n const agentDir = opts.agentDir ?? resolveAgentDir(opts.projectDir);\n if (agentDir) {\n serverLog.info(\"agent dir resolved\", { agentDir });\n } else {\n serverLog.warn(\"no agent definition found in skaile.yaml\");\n }\n\n // ---------------------------------------------------------------------------\n // Transport setup (must be before resource init — sync callbacks use sendEvent)\n // ---------------------------------------------------------------------------\n\n const authToken = opts.authToken ?? process.env.SKAILE_WS_AUTH_TOKEN;\n const transport: ServerTransport =\n opts.transport ??\n new WebSocketServerTransport({ port, onLog: log, ...(authToken ? { authToken } : {}) });\n\n // Wire structured log forwarding: every LogEntry recorded by the in-container\n // LogStore is emitted as a `log_entry` AgentEvent over the same transport\n // the gateway already subscribes to. The transport drops sends when no client\n // is connected, so no buffering is needed here.\n logStore.addSink(\n new WsLogSink({\n send: (event) => {\n if (transport.connected) transport.send(event);\n },\n }),\n );\n\n // Forward agent events to the connected client\n function sendEvent(event: AgentEvent) {\n if (transport.connected) {\n transport.send(event);\n }\n }\n\n // ---------------------------------------------------------------------------\n // Capability registry (Protocol v2)\n // ---------------------------------------------------------------------------\n //\n // Single per-session registry. Built-in `__capabilities.list/search/describe`\n // are registered at boot. Client-side capabilities arrive via\n // ConfigureCommandV2.capabilities in the v2 configure handler below.\n //\n // The registry is constructed eagerly (before session creation) so the\n // bridge can pull tool definitions through `BridgeCapabilityHooks` on its\n // first turn. Built-ins are registered immediately; downstream registrations\n // (skills/connectors/mounts/client) happen at their own lifecycles.\n\n const capabilityRegistry = new CapabilityRegistry(\n createLogger({\n kind: \"runner\",\n subkind: \"capability-registry\",\n instance: sessionId,\n }),\n );\n bootstrapCapabilityRegistry(capabilityRegistry);\n\n // ---------------------------------------------------------------------------\n // Client-side capability round-trip (Protocol v2)\n // ---------------------------------------------------------------------------\n //\n // When the LLM invokes a `side: 'client'` capability, the bridge calls the\n // registry's invoke() which delegates to the per-capability handler. For\n // client-side caps the handler emits a `capability_invoked` event over the\n // transport, registers a pending promise keyed by `callId`, and waits for\n // a `capability_result` command from the platform. `fireAndForget` caps\n // bypass the pending map (the bridge also short-circuits in\n // `dispatchCapability`, so this is defence-in-depth).\n const pendingCapabilityCalls = new Map<string, PendingCallEntry>();\n\n // ---------------------------------------------------------------------------\n // Outbound capability invocation (Protocol v3)\n // ---------------------------------------------------------------------------\n //\n // The runner invokes `host.*` capabilities on the platform through the same\n // `capability_invoked` / `capability_result` round-trip already used for\n // client-side capabilities — just in the opposite direction. The pending\n // map is shared (`pendingCapabilityCalls`) since the wire shape is identical.\n //\n // Spec: `_devlog/specs/2026-05-10-deterministic-session-bootstrap.md`\n // § \"Bidirectional capability registry as RPC backbone\".\n const remoteCapabilityInvoker = (\n name: string,\n input: unknown,\n timeoutMs?: number,\n ): Promise<unknown> => {\n const callId =\n typeof crypto?.randomUUID === \"function\"\n ? crypto.randomUUID()\n : `rcap-${Date.now()}-${Math.floor(Math.random() * 1e9)}`;\n return new Promise<unknown>((resolve, reject) => {\n if (!transport.connected) {\n reject(new Error(`Transport disconnected; cannot invoke remote capability ${name}`));\n return;\n }\n const timer = setTimeout(() => {\n pendingCapabilityCalls.delete(callId);\n reject(new Error(`Remote capability ${name} (callId=${callId}) timed out`));\n }, timeoutMs ?? DEFAULT_CAPABILITY_CALL_TIMEOUT_MS);\n pendingCapabilityCalls.set(callId, { resolve, reject, timer });\n transport.send({\n type: \"capability_invoked\",\n callId,\n name,\n input,\n invokedBy: \"agent\",\n });\n });\n };\n\n /**\n * Per-session AI provider config id, threaded in via `ConfigureCommandV2.config.aiProviderConfigId`.\n * Read by the auth-error retry handler to fill `request_access_token { kind: 'ai-credentials', configId }`.\n * Standalone runners (CLI / forge / Claude plugin) never see a configure\n * command with this field, so it stays `undefined` and the auth-error\n * handler falls back to surfacing the error.\n *\n * Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`\n * § \"Wire `aiProviderConfigId` end-to-end\".\n */\n let aiProviderConfigId: string | undefined;\n\n // Backoff sleep for the reactive 401 bounded retry. `unref` so a pending\n // retry never pins the event loop alive during shutdown.\n const sleep = (ms: number): Promise<void> =>\n new Promise((resolve) => {\n const t = setTimeout(resolve, ms);\n (t as unknown as { unref?: () => void }).unref?.();\n });\n\n /**\n * Inner credential-mediation helper shared by the reactive\n * `onAuthError` callback and the proactive refresh timer. Acquires a\n * fresh access token through `host.refresh_credential`, rewrites\n * `<home>/.claude/.credentials.json`, and returns the typed mint.\n * Successful mints re-arm the proactive scheduler against the freshly\n * issued token's expiry.\n *\n * Declared before `aiCredentialRefreshScheduler` even though the\n * scheduler's `refresh` callback references this — keeps the textual\n * order matching the call graph (mint → schedule re-arm) instead of\n * relying on hoisting semantics that would break under a future\n * arrow-function refactor.\n */\n async function mintAndPersistAiCredential(args: {\n configId?: string;\n reason: \"refresh\" | \"retry-401\";\n }): Promise<import(\"@skaile/workspaces/types\").CredentialMint> {\n if (!transport.connected || aiProviderConfigId === undefined) {\n return {\n ok: false,\n code: \"not-configured\",\n message: \"no transport or aiProviderConfigId; standalone runner cannot mediate refresh\",\n };\n }\n const targetConfigId = args.configId || aiProviderConfigId;\n try {\n // `||` (not `??`) so an empty `HOME` falls back to homedir() rather than\n // being used as \"\". Inside the try so a homedir() throw becomes a\n // backend-error mint rather than an unhandled rejection.\n const home = process.env.HOME || homedir();\n // On a retry-401 the credential currently on disk is the one the provider\n // just rejected. Fingerprint it (truncated SHA-256, non-reversible) so the\n // platform single-flight mediator can coalesce concurrent rotations of the\n // same dead token. Older platforms ignore the optional field.\n const refreshInput = buildRefreshCredentialInput({\n configId: targetConfigId,\n reason: args.reason,\n rejectedToken: args.reason === \"retry-401\" ? readCurrentClaudeAccessToken(home) : null,\n });\n const result = (await capabilityRegistry.invokeRemote(\n \"host.refresh_credential\",\n refreshInput,\n )) as import(\"@skaile/workspaces/types\").CredentialMint;\n if (!result?.ok) {\n return result ?? { ok: false, code: \"backend-error\", message: \"no result from host\" };\n }\n await mergeAndRewriteCredentialsFile(home, result.token, result.expiresAt ?? null);\n // Re-arm proactive timer for the freshly issued token. The reactive\n // (retry-401) path calls into here too, so retry success also chains\n // the next proactive fire.\n aiCredentialRefreshScheduler.schedule(result.expiresAt ?? null);\n return result;\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n return { ok: false, code: \"backend-error\", message: errMsg };\n }\n }\n\n // Connector token-refresh mediator (the previously-missing wire). Routes a\n // backend git mount's `refresh`/`retry-401` through `host.refresh_credential`.\n const connectorTokenMediator: TokenMediator = buildConnectorTokenMediator({\n isConnected: () => transport.connected,\n invokeRemote: (name, input) => capabilityRegistry.invokeRemote(name, input),\n log,\n });\n\n /**\n * Proactive AI-credential refresh scheduler. Holds a single timer that\n * fires `PROACTIVE_AI_REFRESH_MARGIN_MS` before the current token\n * expires, calls `host.refresh_credential { reason: 'refresh' }`, and\n * re-arms against the new expiry. Pairs with the bridge-side\n * `failTurn` deferral that suppresses downstream auth-error events\n * when a self-heal is about to run: this timer is the primary\n * prevention of in-container 401s, the reactive 401 path is the\n * safety net.\n *\n * Schedule is re-armed on every fresh credential (initial provision,\n * a reactive retry-401 success, or a previous proactive fire). Tokens\n * with `expiresAt === null` (static PATs) do not schedule.\n *\n * Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`\n * § \"Proactive refresh\" (added 2026-05-20).\n */\n const aiCredentialRefreshScheduler = createAiCredentialRefreshScheduler({\n refresh: async () => {\n const result = await mintAndPersistAiCredential({ reason: \"refresh\" });\n if (result.ok) {\n return { status: \"ok\", expiresAt: result.expiresAt ?? null };\n }\n // A `backend-error` is a transient mediator blip (bounded retry); any\n // other code is a terminal credential/account state (stop re-arming).\n return isTransientMintFailure(result.code) ? { status: \"transient\" } : { status: \"terminal\" };\n },\n log,\n // Scheduler/refresh failures must be visible in `skaile session logs` and\n // the debug panel, so route them through the error-level structured logger.\n logError: (line: string) => serverLog.error(line),\n });\n\n /**\n * Auth-refresh callback handed to the bridge driver via\n * `AgentConfig.onAuthError`. Invoked when the underlying agent surfaces\n * an `authentication_error`. In v3, the runner mediates the fresh\n * credential through `host.refresh_credential` (a `runtime`-audience\n * capability the platform registered at session_init) and returns the\n * typed `CredentialMint` to the driver so it can branch on the\n * discriminator.\n *\n * Standalone CLI / forge sessions never register `host.refresh_credential`\n * (no platform peer), so the invocation fails synchronously and we\n * surface a structured `not_available` mint — preserving the legacy\n * \"no mediator -> surface AuthError\" behaviour.\n *\n * Spec: `_devlog/specs/2026-05-10-deterministic-session-bootstrap.md`\n * § \"Refresh-on-401 routes through host.refresh_credential\".\n */\n const onAuthError = async (args: {\n configId: string;\n }): Promise<import(\"@skaile/workspaces/types\").CredentialMint> => {\n log(\"[serve] auth error: invoking host.refresh_credential capability\");\n // A single mediation run used to hard-fail the user on one `backend-error`\n // (e.g. the platform backend mid-redeploy, a ~7s window). Bounded-retry the\n // transient failure with backoff before surfacing; terminal codes\n // (not-configured / revoked / provider-error) surface immediately. The\n // retry is of a FAILED (non-rotating) mint, so it adds no rotations.\n const result = await retryTransientMint(\n () => mintAndPersistAiCredential({ configId: args.configId, reason: \"retry-401\" }),\n {\n sleep,\n onRetry: ({ attempt, nextDelayMs, code }) =>\n serverLog.error(\n `[serve] auth error: transient mint failure (code=${code}); retry ${attempt} in ${Math.round(nextDelayMs / 1000)}s`,\n ),\n },\n );\n if (!result.ok) {\n log(`[serve] auth error: mint failed (code=${result.code}); surfacing`);\n } else {\n log(\"[serve] auth error: rewrote .credentials.json with mediated accessToken\");\n }\n return result;\n };\n\n /**\n * Approval-required client caps (Protocol v2.1) park on the platform until\n * a human responds. Human approvals routinely take minutes, so the default\n * 60-second timeout would cause the runner to abandon the pending call\n * while the platform later still dispatches the side effect. Use a long\n * (15-minute) timeout for `requiresApproval: true` capabilities so the\n * platform's parked-approval lifetime stays inside the runner's window.\n */\n const APPROVAL_REQUIRED_CAPABILITY_TIMEOUT_MS = 15 * 60 * 1000;\n\n function buildClientCapabilityHandler(\n wire: import(\"@skaile/workspaces/types\").Capability,\n ): (input: unknown) => Promise<unknown> {\n // Precedence: an explicit per-capability `callTimeoutMs` wins (e.g.\n // `platform.ask_session` blocks for minutes); otherwise approval-required\n // caps get the long 15-minute window; everything else uses the default.\n const timeoutMs = resolveCapabilityCallTimeoutMs(wire, APPROVAL_REQUIRED_CAPABILITY_TIMEOUT_MS);\n return buildClientCapabilityRoundtripHandler({\n wire,\n pending: pendingCapabilityCalls,\n emit: (event) => sendEvent(event),\n timeoutMs,\n });\n }\n\n /**\n * Build the bridge-facing capability hooks. Drivers consume this through\n * `AgentConfig.capabilities`. The runner owns:\n * - tool list composition (registry.composeLLMTools)\n * - per-handler logging + Zod validation (registry.invoke)\n * - render-event forwarding to the WebSocket client\n * - text fallback emission for clients without a render layer\n */\n function buildCapabilityHooks(): import(\"@skaile/workspaces/bridge\").BridgeCapabilityHooks {\n return {\n sessionId,\n composeTools: () => capabilityRegistry.composeLLMTools(),\n resolve: (name) => {\n const cap = capabilityRegistry.resolve(name);\n if (!cap) return null;\n // Strip runtime-only fields by going through the wire-format `list`.\n return capabilityRegistry.list().find((c) => c.name === name) ?? null;\n },\n invoke: (name, input) => capabilityRegistry.invoke(name, input, { sessionId }),\n emitRender: (event) => sendEvent(event),\n emitText: (text) =>\n sendEvent({\n type: \"text\",\n content: text,\n }),\n };\n }\n\n // ---------------------------------------------------------------------------\n // Composition → capability registration helper\n // ---------------------------------------------------------------------------\n\n /**\n * Register discoverable composition entries from a freshly created session\n * into the capability registry. Inline blocks are already injected into the\n * system prompt by session-builder; this handles only the tool-list entries.\n */\n function registerSessionComposition(session: AgentSession): void {\n if (session.composition?.discoverableEntries.length) {\n registerCompositionCapabilities(capabilityRegistry, session.composition.discoverableEntries);\n log(\n `[serve] registered ${session.composition.discoverableEntries.length} composition capabilities`,\n );\n }\n }\n\n // ---------------------------------------------------------------------------\n // Secret provisioning mode\n // ---------------------------------------------------------------------------\n\n const secretsMode = wsConfig.secrets?.provider ?? \"env\";\n const secretsTimeoutMs = wsConfig.secrets?.timeoutMs ?? 30_000;\n\n // Build the session config factory (secretProvider injected after provisioning)\n function buildSessionConfig(secretProvider?: unknown, apiKey?: string): AgentSessionConfig {\n return {\n projectDir: opts.projectDir,\n agentDir,\n driver: opts.driver,\n model: opts.model,\n provider: opts.provider,\n promptsDir: opts.promptsDir,\n sessionId,\n resumeSessionId,\n maxTurns,\n wsConfig,\n externalPromptFile: process.env.SKAILE_SYSTEM_PROMPT_FILE,\n secretProvider,\n onAuthError,\n ...(apiKey ? { apiKey } : {}),\n // Protocol v2 `<CAPABILITIES>` block — joins each registered capability's\n // `promptFragment` (framework first, then client, then agent-side\n // surfaces). Built lazily inside `buildSessionConfig` so newly registered\n // capabilities (e.g. via mid-session `capability_register` commands) are\n // reflected on the next session rebuild.\n additionalPromptSections: (() => {\n const sections: string[] = [];\n const capSection = buildCapabilitiesPromptSection(capabilityRegistry);\n if (capSection) sections.push(capSection);\n return sections.length > 0 ? sections : undefined;\n })(),\n watch: {\n onSyncStatus: (mountId, status) => {\n sendEvent({\n type: \"sync_status\",\n mountId,\n ...status,\n phase: status.phase as\n | \"enumerating\"\n | \"stubs_ready\"\n | \"downloading\"\n | \"initial_sync_complete\"\n | \"error\",\n });\n if (status.phase === \"stubs_ready\") {\n log(\n `[serve] ${mountId}: file tree ready (${status.totalFiles} files, ${status.stubFiles} stubs)`,\n );\n } else if (status.phase === \"initial_sync_complete\") {\n log(\n `[serve] ${mountId}: sync complete (${status.downloadedFiles}/${status.totalFiles} downloaded)`,\n );\n }\n },\n onFileChanged: (connectorId, event) => {\n sendEvent({\n type: \"file_changed\",\n path: event.path,\n action: event.action,\n mountId: connectorId,\n });\n },\n // Forward connector lifecycle transitions to the platform. This is the\n // channel deferred (rclone-backed) filesystem mounts report progress on\n // after session_init_ack — a wedged remote shows as \"still syncing\".\n onConnectorStatus: (event) => {\n sendEvent(event);\n },\n },\n // Bring rclone-backed filesystem mounts up in the background so a slow\n // remote can't blow the platform's session_init_ack deadline and trigger\n // the container restart loop.\n deferFilesystemMounts: true,\n onLog: (line) => log(`[serve] ${line}`),\n capabilities: buildCapabilityHooks(),\n // Hand the registry to the session builder so external (declarative /\n // recipe-backed) MCP servers are spawned by the RUNNER and their tools\n // registered as `mcp`-origin capabilities — works on every driver, no\n // dependence on the claude-agent-sdk `mcpServers` query option.\n capabilityRegistry,\n // v3: pre-minted credentials satisfy the initial mint of `auth: backend`\n // connectors in-process; connector refresh (refresh / retry-401) now routes\n // through `host.refresh_credential` via this mediator.\n tokenMediator: connectorTokenMediator,\n ...(preMintedSecrets ? { preMintedSecrets } : {}),\n ...(aiProviderConfigId ? { aiProviderConfigId } : {}),\n };\n }\n\n // Session-readiness gate — other command handlers await this promise before\n // accessing agentSession, driver, resourceManager, etc. In env mode it\n // resolves synchronously; in provisioned mode it resolves after\n // createAgentSession completes (which may involve slow mount operations).\n let resolveSessionReady!: () => void;\n let rejectSessionReady!: (err: Error) => void;\n const sessionReady = new Promise<void>((resolve, reject) => {\n resolveSessionReady = resolve;\n rejectSessionReady = reject;\n });\n\n // In provisioned mode we defer session creation until secrets arrive.\n // In env mode we create the session immediately (existing behavior).\n let sessionConfig: AgentSessionConfig;\n let agentSession: AgentSession;\n let secretProvider: unknown;\n\n // v3 protocol — populated by the `session_init` handler. Used for the\n // identity-mismatch shutdown on successive inits and for capability\n // handlers that resolve project-scoped state.\n let runtimeIdentity:\n | import(\"@skaile/workspaces/types\").SessionInitCommand[\"identity\"]\n | undefined;\n\n // v3 protocol — pre-minted credentials delivered with `session_init`.\n // Wired into ConnectorManager via the `preMintedSecrets` option so the\n // initial mint of `auth: backend` connectors is satisfied in-process.\n let preMintedSecrets: PreMintedSecretProvider | undefined;\n\n // Dir names already staged into the driver's skills dir, so a late-materialized\n // skill triggers a driver restart exactly once. Never cleared: a dir that\n // vanishes then reappears (re-publish) won't re-trigger — fine for the static\n // declared/builtin set this serves.\n const stagedSkillDirs = new Set<string>();\n\n // Stage materialized skills BEFORE the session/driver is built so they are on\n // disk no matter when the driver discovers them (claude-sdk reads .claude/skills/\n // lazily today, but a future eager-discovery driver must still see them).\n await restageMaterializedSkills(false);\n\n /**\n * Stage each skaile.yaml-declared materialized skill from `.skaile/assets/skill/`\n * into the driver's skills dir — at boot AND per prompt, so a skill the platform\n * materializes after the container booted still loads. Idempotent; never throws.\n */\n async function restageMaterializedSkills(allowRestart: boolean): Promise<void> {\n try {\n const { skillsDir } = resolveDriverPaths({\n driver: opts.driver ?? wsConfig.agent_config?.default?.driver ?? \"claude-sdk\",\n });\n // Canonical-contract invariant: the runner activates ONLY skaile.yaml-\n // declared skills — undeclared on-disk (\"ghost\") skills are never staged.\n const declared = (wsConfig.dependencies ?? []).flatMap((dep) => {\n try {\n const ref = parseAssetRef(dep);\n return ref.kind === \"skill\" ? [ref.name] : [];\n } catch {\n return [];\n }\n });\n if (declared.length === 0) return;\n const staged = stageMaterializedSkills(opts.projectDir, skillsDir, { declared });\n // Prompts are processed serially, so this read-then-add never races itself.\n const newlyStaged = staged.filter((s) => !stagedSkillDirs.has(s));\n for (const s of staged) stagedSkillDirs.add(s);\n if (newlyStaged.length === 0) return;\n log(`[serve] staged ${newlyStaged.length} materialized skill(s): ${newlyStaged.join(\", \")}`);\n // allowRestart is false at boot — the driver isn't up yet (and `driverStarted`\n // is still in its TDZ), so `&&` short-circuits and skills load on first start.\n // A skill landing after the driver started needs a restart to be discovered.\n if (allowRestart && driverStarted) {\n await restartDriverForSkillChanges(\n newlyStaged.map((s) => ({ name: s, action: \"add\" as const })),\n );\n }\n } catch (err) {\n // Never crash the container or block a turn, but surface it: a driver\n // restart failure (session dispose+recreate) is a real operational event.\n log(\n `[serve] restageMaterializedSkills failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n // MCP server ids baked into the driver at its last (re)creation. The claude-sdk\n // driver fixes its tool set at creation, so these are live; only servers\n // hot-added afterwards are `live:false` until the next restart re-bakes them.\n let bakedMcpServerIds: ReadonlySet<string> = new Set();\n const captureBakedMcpServers = (): void => {\n const servers = agentSession?.getExternalMcpManager()?.listServers() ?? [];\n bakedMcpServerIds = new Set(servers.map((s) => s.id));\n };\n\n if (secretsMode === \"provisioned\") {\n log(\"[serve] secrets mode: provisioned — waiting for provision_secrets command\");\n } else {\n sessionConfig = buildSessionConfig();\n agentSession = await createAgentSession(sessionConfig);\n emitSystemPromptComposed(agentSession, sendEvent);\n\n registerSessionComposition(agentSession);\n resolveSessionReady();\n // env mode builds its session here (not via session_init), so snapshot the\n // declared MCP set now or emitAvailability would report live:false.\n captureBakedMcpServers();\n }\n\n // Mutable references — updated after provisioning in provisioned mode\n let resourceManager: any | null = secretsMode === \"env\" ? agentSession!.resourceManager : null;\n\n if (secretsMode === \"env\") {\n if (!agentSession!.provider) {\n log(\n `[serve] WARNING: no API key found for ${agentSession!.provider ?? \"anthropic\"} — agent calls will fail`,\n );\n log(`[serve] Pass via env var (e.g. ANTHROPIC_API_KEY) or .skaile/settings.json`);\n }\n\n if (resourceManager) {\n const watched: string[] = resourceManager.watchedResources ?? [];\n if (watched.length > 0) {\n log(`[serve] watching ${watched.length} resource(s): ${watched.join(\", \")}`);\n }\n }\n }\n\n // Surface runtime-asset resolution warnings (missing drivers, unavailable\n // repositories) as validation_warning events so the platform frontend can\n // show actionable hints. Same event shape as the legacy skill validator.\n // Skip in provisioned mode — the session does not exist yet at this point;\n // warnings will be emitted after createAgentSession runs in the\n // provision_secrets handler.\n if (secretsMode === \"env\" && agentSession!.runtimeAssets) {\n emitRuntimeAssetWarnings(agentSession!.runtimeAssets);\n }\n\n // Validate top-level skaile.yaml dependencies against deployed skills\n // (graceful degradation). The legacy ai_resources[] block is gone — deps are\n // a flat top-level list of canonical refs now.\n validateSkaileYamlDependencies();\n\n /**\n * Emit `validation_warning` events for each runtime-asset resolution warning\n * (missing drivers, unavailable repositories). Same event shape as the\n * legacy skill validator.\n */\n function emitRuntimeAssetWarnings(\n runtimeAssets: NonNullable<AgentSession[\"runtimeAssets\"]>,\n ): void {\n for (const w of runtimeAssets.warnings) {\n const asset =\n w.code === \"missing_driver\" && w.declarationId\n ? `${w.declarationId} → ${w.name ?? \"unknown\"}`\n : (w.name ?? w.code);\n log(`[serve] validation_warning: ${w.code}: ${w.message}`);\n sendEvent({\n type: \"validation_warning\",\n asset,\n reason: w.code,\n suggestion: w.message,\n });\n }\n }\n\n /**\n * Validate top-level skaile.yaml dependencies against deployed skills,\n * emitting a `validation_warning` for each declared skill dependency that is\n * not present on disk. Graceful degradation — non-fatal; validation failure\n * should never crash the container.\n */\n function validateSkaileYamlDependencies(): void {\n try {\n const wsConfig = resolveSkWorkspaceConfig(opts.projectDir);\n for (const dep of wsConfig.dependencies ?? []) {\n let ref: string | undefined;\n try {\n const parsed = parseAssetRef(dep);\n if (parsed.kind !== \"skill\") continue;\n ref = parsed.name;\n } catch {\n continue;\n }\n const skillDir = join(opts.projectDir, \".claude\", \"skills\", ref);\n if (!existsSync(skillDir)) {\n log(`[serve] validation_warning: dependency \"${dep}\" not found — continuing without it`);\n sendEvent({\n type: \"validation_warning\",\n asset: dep,\n reason: \"not_found\",\n suggestion: \"Sync the catalog and re-add this asset\",\n });\n }\n }\n } catch {\n // Non-fatal — validation failure should never crash the container\n }\n }\n\n // EventNormalizer deduplicates and normalizes events from the driver (e.g. subagent detection).\n // Only applied in serve mode — REPL and flow modes receive raw events.\n // TODO: candidate to move into createAgentSession() if REPL/flow are found to need normalisation.\n const normalizer = new EventNormalizer();\n\n /**\n * Forward a normalized agent event, rewriting file_changed paths so they\n * are mounts-relative and tagged with their mountId.\n *\n * See file-changed-rewriter.ts for the reasoning — the short version is\n * that Claude SDK Write/Edit tool results carry cwd-relative filePaths,\n * and the frontend's file-change listener assumes they are mounts-relative.\n */\n // Protocol v2 — `[CUSTOM:type:json]`, `[REACT:emoji]`, `[PASS]` text-marker\n // parsing and the AAP raw-JSON-events-as-text robustness path are removed.\n // The agent now invokes `platform.react`, `platform.pass`, and\n // `platform.custom_message` capability tools instead.\n\n function forwardNormalizedEvent(event: AgentEvent): void {\n // Suppress event forwarding during compaction turns -- the orchestrator's\n // captureHandler captures text independently and the host should not see\n // the compaction turn's intermediate events.\n if (compacting) return;\n\n // Track durable events for compaction seq counter\n const isTransient =\n event.type === \"status\" ||\n event.type === \"sync_status\" ||\n event.type === \"resources_available\" ||\n event.type === \"resource_response\" ||\n event.type === \"commands_available\";\n if (!isTransient) {\n eventSeq++;\n compactionOrchestrator?.trackMessage(eventSeq);\n }\n\n if (event.type === \"finished\") {\n // Check auto-compaction after turn completes (skip if already compacting)\n if (!compacting && compactionOrchestrator?.shouldCompact()) {\n compactionOrchestrator.compact(\"threshold\").catch((err: unknown) => {\n log(\n `[serve] auto-compaction failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n });\n }\n // Surface the SDK session id (tier-1 resume token) + model + capability\n // signature so the platform can persist them on the Session independently\n // of compaction. Re-emitted whenever any of the three drifts. Short-\n // circuit on a missing session id BEFORE hashing the signature so early\n // no-session turns don't pay for the compute.\n const driverSessionId = driver?.runtimeSessionId;\n if (driverSessionId) {\n const runtimeSessionEvent = planRuntimeSessionEmit({\n driverSessionId,\n model: driver?.getModel?.() ?? null,\n capabilitySignature: computeCapabilitySignature(capabilityRegistry.list()),\n lastEmitted: lastEmittedRuntimeSession,\n });\n if (runtimeSessionEvent) {\n lastEmittedRuntimeSession = {\n driverSessionId: runtimeSessionEvent.driverSessionId,\n model: runtimeSessionEvent.model,\n capabilitySignature: runtimeSessionEvent.capabilitySignature,\n };\n sendEvent(runtimeSessionEvent);\n }\n }\n }\n\n if (!resourceManager) {\n sendEvent(event);\n return;\n }\n // Filesystem-face connectors expose a `mountPath`; tool-only connectors do not.\n const mounts: MountPoint[] = (\n resourceManager.listConnectors() as Array<{ id: string; mountPath?: string }>\n )\n .filter((info) => typeof info.mountPath === \"string\")\n .map((info) => ({\n id: info.id,\n mountPath: info.mountPath as string,\n }));\n sendEvent(rewriteFileChangedPath(event, opts.projectDir, mounts));\n }\n let driverStarted = false; // Lazy start — driver initializes on first prompt command\n let driver = secretsMode === \"env\" ? agentSession!.driver : (undefined as any);\n let secretsProvisioned = secretsMode === \"env\"; // env mode starts ready\n\n // ---------------------------------------------------------------------------\n // Compaction orchestrator\n // ---------------------------------------------------------------------------\n\n /** Local seq counter for durable events. */\n let eventSeq = 0;\n /**\n * Last tier-1 resume snapshot (driver session id + model + capability\n * signature) emitted via a `runtime_session` event. Tracks all three so we\n * re-emit on any drift, but not every turn. See RuntimeSessionEvent.\n */\n let lastEmittedRuntimeSession: RuntimeSessionSnapshot | undefined;\n /** True while a compaction turn is in progress -- suppresses event forwarding. */\n let compacting = false;\n let compactionOrchestrator: CompactionOrchestrator | null = null;\n\n const compactionConfig = wsConfig.compaction;\n\n /** Build (or rebuild) the compaction orchestrator for the current driver. */\n function rebuildCompactionOrchestrator(): void {\n if (!driver) return;\n compactionOrchestrator = new CompactionOrchestrator({\n driver,\n config: compactionConfig,\n onCompactionStart: (trigger) => {\n compacting = true;\n sendEvent({ type: \"status\", phase: \"compacting\" } as AgentEvent);\n log(`[serve] compaction started (trigger=${trigger})`);\n },\n onSnapshot: (snapshot) => {\n sendEvent(snapshot as AgentEvent);\n },\n onCompactionAttempt: (event) => {\n sendEvent(event as AgentEvent);\n },\n onCompactionEnd: () => {\n compacting = false;\n sendEvent({ type: \"status\", phase: \"idle\" } as AgentEvent);\n },\n onLog: (line) => log(`[serve] ${line}`),\n // Phase 3: stamp every CompactionAttemptEvent with the registry's\n // current signature so wake-time tier-1 selection has the input it\n // needs. The registry exists for the entire serve lifetime, so this\n // closure is safe across orchestrator rebuilds.\n getCurrentCapabilitySignature: () => computeCapabilitySignature(capabilityRegistry.list()),\n });\n }\n\n if (secretsMode === \"env\" && driver) {\n rebuildCompactionOrchestrator();\n }\n\n // ---------------------------------------------------------------------------\n // Active flow executions (Phase 4 of the flow-connector extraction)\n // ---------------------------------------------------------------------------\n //\n // MVP allows one active flow per session (decision F14). Each entry holds\n // the FlowAdapter handle + the connectorId used as the bus's queue key.\n // Phase 4 dropped the FlowOrchestrator: SessionStimulusBus is the sole\n // turn driver now, with FlowAdapter signalling on every mutation through\n // its `useBusForStimulus: true` wiring (see `factory-assets/connectors/flow/\n // adapter.ts`).\n\n interface ActiveFlow {\n runId: string;\n flowDef: FlowDefinition;\n adapter: FlowAdapter;\n handle: ConnectorHandle;\n /** Bus queue key — matches `connectorId` passed to `flowAdapter.connect`. */\n connectorId: string;\n }\n\n const activeFlows = new Map<string, ActiveFlow>();\n\n /**\n * Per-session stimulus bus — built lazily on the first flow start so the\n * driver is guaranteed to exist by the time we wire `driveTurn`. The\n * adapter calls `bus.signal(connectorId, ...)` on every mutation; the\n * bus coalesces and invokes `driveTurn` to run one agent turn.\n */\n let stimulusBus: SessionStimulusBus | null = null;\n /** Runner-side default per-flow turn timeout (4 hours). */\n const FLOW_TURN_TIMEOUT_MS = 4 * 60 * 60 * 1000;\n\n /** Shorthand for the single MVP active flow. Returns null if none. */\n function getOnlyActiveFlow(): ActiveFlow | null {\n const iter = activeFlows.values().next();\n return iter.done ? null : iter.value;\n }\n\n /**\n * Build (or rebuild) the per-session SessionStimulusBus. The bus's\n * `driveTurn` callback wraps the active driver's `prompt(...)` and waits\n * for `agent_end`. It also rebuilds the full orchestrator prompt around\n * the bus-emitted stimulus fragment so the agent sees the same five-\n * section flow context the legacy orchestrator produced.\n *\n * The bus is created on first use and reused across flows in the same\n * session. When the driver is recreated (mid-session skill deploy or\n * resume), the bus's closure over `driver` updates because we mutate the\n * `driver` binding in place — hence the late-binding `driver` access\n * below rather than capturing the current reference.\n */\n function getOrCreateStimulusBus(): SessionStimulusBus {\n if (stimulusBus) return stimulusBus;\n stimulusBus = createSessionStimulusBus({\n driveTurn: async (promptFragment: string, metas: Array<Record<string, unknown>>) => {\n // Locate the targeted flow from the metas so we can rebuild the\n // full prompt with the correct flow definition + state. The bus\n // queue is keyed by connectorId, so all metas in one batch share\n // the same flow.\n const lastMeta = metas[metas.length - 1] ?? {};\n const runId = typeof lastMeta.runId === \"string\" ? lastMeta.runId : null;\n const entry = runId ? activeFlows.get(runId) : getOnlyActiveFlow();\n if (!entry) {\n serverLog.warn(\"driveTurn fired with no active flow\", { runId });\n return;\n }\n\n // Reconstruct the typed stimulus from the meta. The adapter sets\n // `meta.kind` to a `TurnStimulus[\"kind\"]`; we promote it back to\n // the structured form for `buildOrchestratorPrompt`. Fall back to\n // `state_changed` for unknown / batched kinds.\n const lastKind = lastMeta.kind;\n let stimulus: TurnStimulus;\n if (lastKind === \"flow_started\") {\n stimulus = { kind: \"flow_started\" };\n } else if (lastKind === \"user_message\" && typeof lastMeta.text === \"string\") {\n stimulus = {\n kind: \"user_message\",\n text: String(lastMeta.text),\n senderId: String(lastMeta.senderId ?? \"user\"),\n };\n } else {\n stimulus = { kind: \"state_changed\" };\n }\n // The fragment passed in is the adapter's `renderStimulusPrompt(stim)`.\n // We discard it and rebuild the full orchestrator prompt below; the\n // structured stimulus already encodes everything the fragment did.\n void promptFragment;\n\n const fullPrompt = buildOrchestratorPrompt(\n entry.flowDef,\n entry.adapter.getExecution(entry.handle),\n stimulus,\n );\n\n if (!driverStarted) {\n await driver.start();\n driverStarted = true;\n driver.on(\"agent-event\", (event: unknown) => {\n const normalized = normalizer.normalize(event as never);\n for (const e of normalized) forwardNormalizedEvent(e);\n });\n driver.on(\"error\", (err: Error) => {\n log(`[serve] driver error: ${err.message}`);\n sendEvent({ type: \"error\", message: err.message, fatal: true });\n });\n }\n\n await awaitFlowAgentEnd(fullPrompt, FLOW_TURN_TIMEOUT_MS);\n },\n log: serverLog,\n });\n return stimulusBus;\n }\n\n /**\n * Send a prompt to the active driver and resolve when the agent emits\n * `agent_end` (or reject on `error`). Used by the stimulus bus's\n * `driveTurn` callback. Mirrors the legacy orchestrator's wait helper\n * but uses a scoped per-turn listener so the persistent forwarding\n * listener installed at driver-start time is left intact.\n */\n function awaitFlowAgentEnd(prompt: string, timeoutMs: number): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n const onEvent = (event: BridgeAgentEvent) => {\n if (event.type === \"agent_end\") done();\n else if (event.type === \"error\") {\n const msg =\n (event as { error?: string; message?: string }).error ??\n (event as { message?: string }).message ??\n \"Agent error\";\n done(new Error(msg));\n }\n };\n const done = (err?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n // EventEmitter.removeListener / .off — bridge drivers extend\n // node:events EventEmitter so this is always available.\n (driver as { off?: (e: string, h: (...a: unknown[]) => void) => void }).off?.(\n \"agent-event\",\n onEvent as unknown as (...a: unknown[]) => void,\n ) ??\n (\n driver as {\n removeListener: (e: string, h: (...a: unknown[]) => void) => void;\n }\n ).removeListener(\"agent-event\", onEvent as unknown as (...a: unknown[]) => void);\n if (err) reject(err);\n else resolve();\n };\n const timer = setTimeout(\n () => done(new Error(`Flow turn timed out after ${timeoutMs / 1000}s`)),\n timeoutMs,\n );\n driver.on(\"agent-event\", onEvent);\n driver.prompt(prompt).catch(done);\n });\n }\n\n /**\n * Instantiate a FlowAdapter for a flow definition and register it as the\n * active flow. Wires the adapter's onChange to emit state_changed via\n * `sendEvent`, and connects it to the per-session stimulus bus so every\n * mutation kicks an agent turn (Phase 4 of the flow-connector extraction).\n */\n async function createActiveFlow(\n flowDef: FlowDefinition,\n seedOrExecution:\n | { seed: { runId: string; startedBy: string; autonomousMode?: boolean } }\n | { execution: FlowExecution },\n ): Promise<ActiveFlow> {\n if (!resourceManager) {\n // Lazy-create a ConnectorManager if one does not exist yet — the\n // session may have no connectors in skaile.yaml, but we still\n // need a home for the FlowAdapter instance.\n registerBuiltinConnectors();\n resourceManager = new ConnectorManager(opts.projectDir, {\n catalogEntries: getSessionCatalogEntries(agentSession),\n tokenMediator: connectorTokenMediator,\n });\n log(\"[serve] created ConnectorManager for flow execution (no other connectors declared)\");\n }\n\n const bus = getOrCreateStimulusBus();\n const baseOptions = {\n stimulusBus: bus,\n useBusForStimulus: true,\n };\n const options =\n \"execution\" in seedOrExecution\n ? { flow: flowDef, execution: seedOrExecution.execution, ...baseOptions }\n : { flow: flowDef, seed: seedOrExecution.seed, ...baseOptions };\n const seedRunId =\n \"execution\" in seedOrExecution ? seedOrExecution.execution.runId : seedOrExecution.seed.runId;\n const connectorId = `flow:${seedRunId}`;\n\n // Connect via ConnectorManager so the FlowAdapter's tools become\n // visible to buildSdkConnectorTools below. Direct `new FlowAdapter()`\n // would leave the adapter outside the manager's connectors map and\n // the SDK driver would never see the flow tools.\n const handle = await resourceManager.connect({\n id: connectorId,\n driver: \"flow\",\n access: \"read-write\" as const,\n options,\n });\n const adapter = resourceManager.get(connectorId).connector as unknown as FlowAdapter;\n\n const runId = adapter.getExecution(handle).runId;\n\n // Wire the adapter's onChange so the host's flow-state mirror stays in sync.\n adapter.onStateChange(handle, (state) => {\n sendEvent({\n type: \"state_changed\",\n store: `flow:${state.runId}`,\n state: state as unknown as Record<string, unknown>,\n });\n });\n\n // Rebuild the SDK MCP server tools so the agent can call the new flow\n // connector's tools. If the driver has already started (e.g. the user\n // chatted before clicking Start), restart it via the same dispose +\n // recreate-with-resumeSessionId dance the mid-session skill deploy\n // path uses (see the `aiResources` configure handler) so the agent\n // sees the updated tool list with conversation history preserved.\n if (agentSession?.driverType === \"claude-sdk\") {\n try {\n const server = await buildSdkConnectorTools(resourceManager, { z: _z });\n if (server) {\n if (driverStarted) {\n const prevSessionId = driver.runtimeSessionId;\n log(\n `[serve] restarting driver to register flow connector tools (resume=${prevSessionId ?? \"none\"})`,\n );\n await agentSession.dispose();\n agentSession = await createAgentSession({\n ...sessionConfig,\n resumeSessionId: prevSessionId,\n });\n emitSystemPromptComposed(agentSession, sendEvent);\n driver = agentSession.driver;\n normalizer.reset();\n driverStarted = false;\n rebuildCompactionOrchestrator();\n // Re-bake: a server that was hot-added before this restart (and\n // persisted to skaile.yaml / a materialized asset) is now part of\n // the fresh driver, so it self-heals to live on the next emit.\n captureBakedMcpServers();\n }\n (driver as any).config.mcpServers = { \"skaile-connectors\": server };\n log(`[serve] rebuilt MCP connector tools for flow ${connectorId}`);\n } else {\n log(`[serve] buildSdkConnectorTools returned null for flow ${connectorId}`);\n }\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n log(`[serve] failed to rebuild MCP tools for flow: ${errMsg}`);\n }\n }\n\n const entry: ActiveFlow = { runId, flowDef, adapter, handle, connectorId };\n activeFlows.set(runId, entry);\n return entry;\n }\n\n // Phase 4: `destroyActiveFlow` was the legacy `cancel_flow` typed handler's\n // tear-down helper. With Protocol 2.2, hosts cancel via\n // `connector_mutate { id: \"flow\", op: \"cancel\" }` which transitions the\n // adapter's state to `cancelled` without disconnecting the connector. The\n // connector is reusable across runs (the adapter's `start` op replaces the\n // execution in-place); the host issues `remove_resource` if and when the\n // connector should go away.\n\n // ---------------------------------------------------------------------------\n // Refresh-flag watcher (Step 9a — wake-mid-401 hardening)\n // ---------------------------------------------------------------------------\n //\n // The Tier-2 git credential-helper script touches\n // `<projectDir>/.skaile/refresh-request` when it detects a stale credentials\n // file (mtime > triggerAgeSec). The runner watches that path via `fs.watch`\n // and dispatches `request_access_token { reason: 'retry-401' }` for every\n // git mount with `exposeAccessToken: true` AND `auth: 'backend'`. The mount\n // driver's `refreshExposedCredential` method does the actual mediation +\n // file rewrite via `atomicReplaceCredential`, mirroring the proactive 5-min\n // pre-expiry refresh timer.\n //\n // Pre-create the flag file: `fs.watch` on a non-existent path throws on\n // Linux (ENOENT) and silently misses events on macOS until the file is\n // created. Mode 0660 — owner+group rw so the helper script (running as\n // the agent uid in the skaile group) can `: > \"$FLAG_FILE\"` it.\n //\n // Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md` Step 9a.\n\n const refreshFlagPath = join(opts.projectDir, \".skaile\", \"refresh-request\");\n try {\n mkdirSync(join(opts.projectDir, \".skaile\"), { recursive: true });\n if (!existsSync(refreshFlagPath)) {\n writeFileSync(refreshFlagPath, \"\", { mode: 0o660, flag: \"a\" });\n }\n } catch (err) {\n serverLog.warn(\"failed to pre-create refresh-flag — wake-mid-401 disabled\", {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n\n let lastRefreshAt = 0;\n const REFRESH_DEBOUNCE_MS = 2_000;\n\n let refreshFlagWatcher: FSWatcher | null = null;\n try {\n refreshFlagWatcher = fsWatch(refreshFlagPath, (event) => {\n if (event !== \"change\") return;\n const now = Date.now();\n if (now - lastRefreshAt < REFRESH_DEBOUNCE_MS) return;\n lastRefreshAt = now;\n // Dispatch is extracted into `refresh-flag-dispatcher.ts` so the logic\n // can be unit-tested without spinning up the full WebSocket server.\n void dispatchRefreshToExposedGitMounts(resourceManager, serverLog);\n });\n } catch (err) {\n serverLog.warn(\"fs.watch on refresh-flag failed — wake-mid-401 disabled\", {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n\n // ---------------------------------------------------------------------------\n // Fleet-health flag watcher (fleet read-only health gate, consume side)\n // ---------------------------------------------------------------------------\n //\n // The platform fleet-health poll writes its verdict per connector into\n // `<projectDir>/.skaile/fleet-health/<connectorId>` (body: healthy | degraded |\n // error). The runner watches that directory and forwards each verdict to the\n // ConnectorManager's `reportFleetHealth`, which trips/lifts the read-only gate\n // on the live fleet bind (catching the *silently-empty* degradation the local\n // probe cannot). Mirrors the refresh-flag watcher above.\n\n const fleetHealthDir = join(opts.projectDir, \".skaile\", \"fleet-health\");\n try {\n // Group-writable + setgid (0o2770) so the platform backend (different uid,\n // same `skaile` gid) can WRITE the verdict flag the runner READS. chmod also\n // repairs a 0o755 dir left by an older runner; mkdir's mode is umask-masked.\n mkdirSync(fleetHealthDir, { recursive: true, mode: 0o2770 });\n chmodSync(fleetHealthDir, 0o2770);\n } catch (err) {\n serverLog.warn(\n \"failed to pre-create/chmod fleet-health dir — platform health signal may be degraded\",\n {\n error: err instanceof Error ? err.message : String(err),\n },\n );\n }\n\n let fleetHealthWatcher: FSWatcher | null = null;\n try {\n fleetHealthWatcher = fsWatch(fleetHealthDir, (_event, fileName) => {\n // Accept both `change` and `rename`: on Linux the FIRST write to a new\n // flag file fires `rename` (inotify IN_CREATE), not `change`, so filtering\n // to `change` would drop the platform's initial verdict on a newly-degraded\n // mount — exactly the silent-degradation case this signal exists to catch.\n // dispatchFleetHealthFlag is idempotent and the gate dedups, so re-reading\n // the same file on either event is safe.\n if (!fileName) return;\n void dispatchFleetHealthFlag(fleetHealthDir, fileName.toString(), resourceManager, serverLog);\n });\n } catch (err) {\n serverLog.warn(\"fs.watch on fleet-health dir failed — platform health signal disabled\", {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n\n // ---------------------------------------------------------------------------\n // Cleanup\n // ---------------------------------------------------------------------------\n\n async function cleanup() {\n // Bound the wait on sessionReady — in provisioned mode the session may\n // never be built (no platform has connected yet), and in env mode it has\n // already resolved. Either way we must not block shutdown on it.\n try {\n await Promise.race([\n sessionReady,\n new Promise<void>((resolve) => {\n const t = setTimeout(resolve, 2000);\n t.unref?.();\n }),\n ]);\n } catch {\n /* session may have failed to build */\n }\n try {\n driver?.kill();\n } catch {}\n aiCredentialRefreshScheduler.cancel();\n // Reject any pending capability round-trips so the bridge surfaces tool\n // errors instead of hanging forever after the session shuts down.\n for (const [callId, pending] of pendingCapabilityCalls) {\n clearTimeout(pending.timer);\n pending.reject(new Error(`Session terminated before capability_result (callId=${callId})`));\n }\n pendingCapabilityCalls.clear();\n try {\n refreshFlagWatcher?.close();\n } catch {\n /* best-effort — watcher may already be closed */\n }\n refreshFlagWatcher = null;\n try {\n fleetHealthWatcher?.close();\n } catch {\n /* best-effort — watcher may already be closed */\n }\n fleetHealthWatcher = null;\n if (agentSession) {\n try {\n await agentSession.dispose();\n } catch {\n /* best-effort — mount unmount/connector disconnect can fail */\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Command handling\n // ---------------------------------------------------------------------------\n\n /**\n * The command envelope `handleCommand` accepts. Narrowed per-case below so\n * each extracted `handle<Command>` helper takes its own command variant.\n */\n type CommandEnvelope = AgentCommand | import(\"@skaile/workspaces/types\").SessionInitCommand;\n\n /**\n * Await session readiness, emitting a fatal `error` event and returning\n * `false` when the session failed to build. Returning `true` means callers\n * may safely touch `driver` / `resourceManager` / `agentSession`. Shared by\n * every command handler that previously inlined the same try/await/catch.\n */\n async function awaitSessionReadyOrFail(): Promise<boolean> {\n try {\n await sessionReady;\n return true;\n } catch (err) {\n sendEvent({\n type: \"error\",\n message: `Session not available: ${(err as Error).message}`,\n fatal: true,\n });\n return false;\n }\n }\n\n type SessionInitCommand = import(\"@skaile/workspaces/types\").SessionInitCommand;\n\n /**\n * Register the client-side capabilities carried in a `session_init`\n * envelope (was step 3 of the inline handler). Pure-runtime audience caps\n * (host.*) are filtered out — they are invoked outbound via\n * `capabilityRegistry.invokeRemote()`, not stored as LLM-callable stubs.\n */\n function registerInitClientCapabilities(\n incoming: NonNullable<SessionInitCommand[\"capabilities\"]>,\n ): void {\n for (const wire of incoming) {\n // Audience-scoped runtime caps (host.*) are not registered as\n // client capabilities — they are invoked outbound via\n // capabilityRegistry.invokeRemote(). Filter them out here so the\n // registry doesn't store them as LLM-callable stubs.\n if (wire.audience && !wire.audience.includes(\"llm\") && !wire.audience.includes(\"user\")) {\n // Pure runtime audience — keep around in a separate map for\n // outbound invocation (handled by registry.setRemoteInvoker\n // wiring, not by `register`).\n continue;\n }\n const stub = {\n ...wire,\n inputZod: { parse: (v: unknown) => v } as unknown as import(\"zod\").ZodTypeAny,\n outputZod: undefined,\n handler: buildClientCapabilityHandler(wire),\n };\n capabilityRegistry.register(stub, \"client\");\n }\n }\n\n /**\n * Provision the long-lived secrets carried in a `session_init` envelope\n * (was step 5). The Claude Code credentials JSON goes to disk; everything\n * else lands in an `InMemorySecretProvider` (assigned to `secretProvider`,\n * flipping `secretsProvisioned`). Returns the parsed AI-credential\n * `expiresAt` (or null) so the caller can arm the proactive refresh timer.\n */\n async function provisionInitSecrets(\n secrets: SessionInitCommand[\"secrets\"],\n ): Promise<string | null> {\n let initialAiCredentialExpiresAt: string | null = null;\n if (secrets) {\n const ccdValue = secrets[CLAUDE_CODE_CREDENTIALS_KEY];\n if (ccdValue) {\n const home = process.env.HOME ?? homedir();\n if (home) {\n try {\n await writeClaudeCodeCredentialsFile(home, ccdValue);\n log(\n `[serve] wrote Claude Code credentials file to ${home}/.claude/.credentials.json (mode 0600)`,\n );\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n log(`[serve] failed to write Claude Code credentials file: ${errMsg}`);\n }\n }\n // Parse the expiry so the proactive refresh timer can prevent\n // the next 401 instead of relying on the reactive retry path.\n // Scheduling happens once aiProviderConfigId is stashed below.\n initialAiCredentialExpiresAt = extractClaudeAiOauthExpiresAt(ccdValue);\n }\n const otherSecrets = Object.fromEntries(\n Object.entries(secrets).filter(([k]) => k !== CLAUDE_CODE_CREDENTIALS_KEY),\n );\n const provider = new InMemorySecretProvider();\n provider.provision(otherSecrets);\n secretProvider = provider;\n secretsProvisioned = true;\n }\n return initialAiCredentialExpiresAt;\n }\n\n /**\n * Build the agent session from a `session_init` envelope (was step 6).\n * Replaces the v2 provision_secrets + configure handshake: resolves the\n * provider API key from the envelope secrets, builds `sessionConfig`,\n * creates the session (only when one does not yet exist), and wires the\n * outbound capability invoker and the runner.* capabilities.\n *\n * This is the slow, connector/MCP-heavy part of init. The caller\n * (`handleSessionInit`) runs it in the background AFTER emitting\n * `session_init_ack`, and owns the session-ready gate — on success it\n * resolves `sessionReady` once the post-build configure has also run; on\n * failure it rejects the gate. This function therefore neither resolves nor\n * rejects the gate itself; it throws on error so the caller can reject.\n */\n async function buildSessionFromInit(secrets: SessionInitCommand[\"secrets\"]): Promise<void> {\n const effectiveProvider = opts.provider ?? \"anthropic\";\n const envKey = providerEnvKey(effectiveProvider);\n const apiKeyFromSecrets = secrets?.[envKey];\n sessionConfig = buildSessionConfig(secretProvider, apiKeyFromSecrets);\n if (!agentSession) {\n agentSession = await createAgentSession(sessionConfig);\n emitSystemPromptComposed(agentSession, sendEvent);\n resourceManager = agentSession.resourceManager;\n driver = agentSession.driver;\n rebuildCompactionOrchestrator();\n registerSessionComposition(agentSession);\n\n // claude-sdk bakes its tool set at driver creation; bridge drivers\n // recompose tools per turn, so they pick up a hot-plugged MCP server live.\n const driverPicksUpToolsLive = () => agentSession?.driverType !== \"claude-sdk\";\n const emitResourcesAvailable = () =>\n sendEvent(\n buildResourcesAvailablePayload(\n resourceManager,\n agentSession?.getExternalMcpManager(),\n driverPicksUpToolsLive(),\n bakedMcpServerIds,\n ),\n );\n\n // Snapshot the declared/cold-start MCP set before the first emit so those\n // servers report live even on claude-sdk (they're baked into the driver).\n captureBakedMcpServers();\n emitResourcesAvailable();\n agentSession.startWatching();\n\n // 6a. Wire the outbound capability invoker so handlers can call\n // `capabilityRegistry.invokeRemote('host.*', ...)` against the\n // platform peer. Done after the transport is connected (which\n // happens before session_init is processed) so the round-trip\n // map is ready to park calls.\n capabilityRegistry.setRemoteInvoker(remoteCapabilityInvoker);\n\n // 6b. Register the runner.* capabilities (audience: runtime) so the\n // platform can dispatch lifecycle / resource / mcp mutations through\n // invokeRunnerCapability. Merge the connector/mount + MCP handler bags\n // into ONE buildRunnerCapabilities call — registering separately would\n // re-declare the connector caps as notImplemented (double-registration).\n // Resource hot-plug handlers, wired to the live session's\n // ConnectorManager + PreMintedSecretProvider via getters because\n // both are lazily (re)assigned in this scope.\n // Destructure attachConnectorInstance out — it is NOT a\n // RunnerCapabilityHandlers key, so spreading the whole bag into\n // buildRunnerCapabilities would leak an undeclared key past the type.\n const { attachConnectorInstance, ...resourceCaps } = buildSessionResourceHandlers({\n getResourceManager: () => resourceManager,\n getPreMintedSecrets: () => preMintedSecrets,\n emitResourcesAvailable,\n log,\n getProjectDir: () => opts.projectDir,\n });\n // runner.add_mcp_server + runner.attach_instance — wired to the live\n // session's lazily-created ExternalMcpManager + PreMintedSecretProvider.\n const mcpHandlers = buildMcpRuntimeHandlers({\n getOrCreateMcpManager: () => agentSession?.getOrCreateExternalMcpManager() ?? null,\n getPreMintedSecrets: () => preMintedSecrets ?? null,\n driverPicksUpToolsLive,\n emitResourcesAvailable,\n log,\n getProjectDir: () => opts.projectDir,\n });\n const runnerCaps = buildRunnerCapabilities({\n ...resourceCaps,\n ...mcpHandlers,\n // attach_instance routes by kind: skills stage-then-fast-restart,\n // connectors materialize-then-connect; everything else stays on the\n // MCP attach path.\n attachInstance: async (input) => {\n if (input.kind === \"skill\") {\n return attachSkillInstance(input.name);\n }\n if (input.kind === \"connector\") {\n return attachConnectorInstance(input.name, input.preMintedToken);\n }\n return mcpHandlers.attachInstance\n ? mcpHandlers.attachInstance(input)\n : {\n ok: false,\n code: \"not_implemented\",\n message: \"attach_instance handler not configured\",\n };\n },\n // setLogLevel left undefined (the cap self-falls-back to getLogStore);\n // setState remains a stub (not resource hot-plug).\n lifecycle: buildLifecycleHandler({\n getCompactionOrchestrator: () => compactionOrchestrator,\n getResourceManager: () => resourceManager,\n log,\n }),\n });\n for (const cap of runnerCaps) {\n capabilityRegistry.register(cap, \"agent\");\n }\n\n log(\"[serve] session built from session_init envelope\");\n }\n }\n\n /**\n * Dispose + recreate the agent session during `session_init`, threading the\n * staged tier-1 resume hint (when present) into the new driver so the SDK\n * conversation resumes. Shared by the tier-1 resume and subagents-recreate\n * branches so a later branch cannot clobber the resume hint.\n */\n async function recreateSessionForInit(pendingResumeSessionId: string | undefined): Promise<void> {\n await agentSession.dispose();\n agentSession = await createAgentSession({\n ...sessionConfig,\n ...(aiProviderConfigId ? { aiProviderConfigId } : {}),\n ...(pendingResumeSessionId ? { resumeSessionId: pendingResumeSessionId } : {}),\n });\n emitSystemPromptComposed(agentSession, sendEvent);\n driver = agentSession.driver;\n normalizer.reset();\n driverStarted = false;\n rebuildCompactionOrchestrator();\n captureBakedMcpServers();\n // Repoint reads at the recreated session: the resource-capability getters\n // and readResource close over this outer var, so without this they hit the\n // disposed manager. Resume watching, then re-announce so the gateway learns\n // the live resources (it never re-subscribes on its own after a recreate).\n resourceManager = agentSession.resourceManager;\n agentSession.startWatching();\n emitAvailability();\n }\n\n /**\n * Register the `session_init` shared-state stores as hot-plug connectors\n * (was the `cfg.sharedState` block). Lazily creates a ConnectorManager when\n * none exists. Returns `false` when ConnectorManager creation failed and the\n * caller should return early (after the `configured` event was emitted);\n * `true` otherwise.\n */\n async function applyInitSharedState(\n sharedState: NonNullable<SessionInitCommand[\"sharedState\"]>,\n ): Promise<boolean> {\n if (!ensureResourceManagerForSharedState()) {\n sendEvent({ type: \"configured\" });\n return false;\n }\n // Register each shared state store as a hot-plug connector and wire\n // its change callback to forward state_changed events to the client.\n let storesRegistered = 0;\n for (const stateConfig of sharedState) {\n if (await registerSharedStateStore(stateConfig)) storesRegistered++;\n }\n await rebuildMcpToolsForNewStores(storesRegistered);\n return true;\n }\n\n /**\n * Lazy-create a ConnectorManager for sharedState when one doesn't exist yet\n * (the session may have no connectors in skaile.yaml, but the platform still\n * needs to register shared state stores). Returns `false` on creation\n * failure; the caller emits `configured` and bails.\n */\n function ensureResourceManagerForSharedState(): boolean {\n if (resourceManager) return true;\n try {\n registerBuiltinConnectors();\n resourceManager = new ConnectorManager(opts.projectDir, {\n catalogEntries: getSessionCatalogEntries(agentSession),\n tokenMediator: connectorTokenMediator,\n });\n log(\"[serve] created ConnectorManager for sharedState (no connectors were declared)\");\n return true;\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n log(`[serve] failed to create ConnectorManager: ${errMsg}`);\n return false;\n }\n }\n\n /**\n * Register one shared-state store as a hot-plug connector and wire its change\n * callback to forward state_changed events. Returns `true` when a NEW store\n * was registered (so the caller can count it toward the MCP-tools rebuild);\n * `false` when the store already existed or registration failed.\n */\n async function registerSharedStateStore(\n stateConfig: NonNullable<SessionInitCommand[\"sharedState\"]>[number],\n ): Promise<boolean> {\n try {\n if (resourceManager.has(stateConfig.id)) {\n // Store already exists (e.g. backend reconnected after restart).\n // Re-emit current state so the backend's stateCache is repopulated.\n try {\n const snapshot = await resourceManager.executeOp(stateConfig.id, \"get\", {});\n const state = snapshot ? JSON.parse(snapshot) : {};\n sendEvent({\n type: \"state_changed\",\n store: stateConfig.id,\n state,\n });\n log(\n `[serve] sharedState ${stateConfig.id} already registered — re-emitted current state`,\n );\n } catch {\n log(\n `[serve] sharedState ${stateConfig.id} already registered — skipping (could not read state)`,\n );\n }\n return false;\n }\n const handle = await resourceManager.connect({\n id: stateConfig.id,\n driver: stateConfig.adapter,\n access: \"read-write\" as const,\n options: {\n ...((stateConfig.definition as Record<string, unknown> | undefined) ?? {}),\n initial: stateConfig.initialState ?? {},\n },\n });\n // Wire onStoreChange (xstate-store specific) to emit state_changed events\n const entry = resourceManager.get(stateConfig.id);\n if (typeof entry.connector.onStoreChange === \"function\") {\n entry.connector.onStoreChange(handle, (snapshot: Record<string, unknown>) => {\n sendEvent({\n type: \"state_changed\",\n store: stateConfig.id,\n state: snapshot,\n });\n });\n }\n log(`[serve] sharedState registered: ${stateConfig.id} (${stateConfig.adapter})`);\n // Emit initial state immediately so subscribers don't have to wait for the first mutation.\n sendEvent({\n type: \"state_changed\",\n store: stateConfig.id,\n state: stateConfig.initialState ?? {},\n });\n return true;\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n log(`[serve] sharedState registration failed for ${stateConfig.id}: ${errMsg}`);\n sendEvent({\n type: \"error\",\n message: `sharedState ${stateConfig.id}: ${errMsg}`,\n fatal: false,\n });\n return false;\n }\n }\n\n /**\n * Rebuild MCP connector tools so the agent can access newly registered\n * stores. This must happen before the driver starts (lazy start on first\n * prompt). No-op when no new stores were added, the driver already started,\n * or the driver is not claude-sdk.\n */\n async function rebuildMcpToolsForNewStores(storesRegistered: number): Promise<void> {\n if (!(storesRegistered > 0 && !driverStarted && agentSession?.driverType === \"claude-sdk\")) {\n return;\n }\n try {\n const server = await buildSdkConnectorTools(resourceManager, { z: _z });\n if (server) {\n (driver as any).config.mcpServers = { \"skaile-connectors\": server };\n log(`[serve] rebuilt MCP connector tools (${storesRegistered} new store(s))`);\n } else {\n log(`[serve] buildSdkConnectorTools returned null`);\n }\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n log(`[serve] failed to rebuild MCP tools: ${errMsg}`);\n }\n }\n\n /**\n * Apply mid-session skill catalog changes from a `session_init` envelope\n * (was the `cfg.aiResources` block). Deploys / removes catalog entries on\n * disk, then restarts the driver (with conversation resume) so the SDK\n * re-discovers `.claude/skills/` and emits `skills_changed`.\n */\n async function applyInitAiResources(\n aiResources: NonNullable<SessionInitCommand[\"resolvedConfig\"][\"aiResources\"]>,\n ): Promise<void> {\n const catalogActions = aiResources.filter((a) => a.action);\n if (catalogActions.length === 0) return;\n log(`[serve] aiResources catalog actions: ${catalogActions.length}`);\n try {\n const skillsDir = join(sessionConfig.projectDir ?? process.cwd(), \".claude\", \"skills\");\n\n // Resolve ai-assets root from runner's own environment\n const assetsRoot =\n process.env.SKAILE_ASSETS_ROOT ??\n findAiAssetsRoot(sessionConfig.projectDir ?? process.cwd()) ??\n \"/app/ai-assets\";\n\n for (const res of catalogActions) {\n applyCatalogAction(res, { assetsRoot, skillsDir });\n }\n\n await restartDriverForSkillChanges(catalogActions);\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n log(`[serve] aiResources handling failed: ${errMsg}`);\n sendEvent({\n type: \"error\",\n message: `aiResources: ${errMsg}`,\n fatal: false,\n });\n }\n }\n\n /**\n * Deploy or remove a single catalog entry on disk (one `aiResources` action\n * from a `session_init` envelope). Mirrors the deploy/remove branches of the\n * former inline loop; logs the outcome.\n */\n function applyCatalogAction(\n res: NonNullable<SessionInitCommand[\"resolvedConfig\"][\"aiResources\"]>[number],\n paths: { assetsRoot: string; skillsDir: string },\n ): void {\n if (res.action === \"add\" && res.entry) {\n const entry = res.entry as Record<string, unknown>;\n const result = deployCatalogEntry(entry as any, {\n assetsRoot: paths.assetsRoot,\n skillsDir: paths.skillsDir,\n context: res.context,\n });\n if (result.success) {\n log(`[serve] deployed skill: ${(entry.name as string) ?? res.name}`);\n } else {\n log(\n `[serve] failed to deploy skill ${(entry.name as string) ?? res.name}: ${result.error}`,\n );\n }\n } else if (res.action === \"remove\") {\n const removed = undeployCatalogEntry(res.name, paths.skillsDir);\n log(`[serve] ${removed ? \"removed\" : \"not found\"} skill: ${res.name}`);\n }\n }\n\n /**\n * Live-attach a single SKILL asset enabled mid-session. The platform has\n * already materialized it to `<projectDir>/.skaile/assets/skill/<name>/`; we\n * stage that one skill into `.claude/skills/` (the same path cold boot uses)\n * and fast-restart the driver so the SDK rediscovers it. Mirrors the\n * mcp-server / connector live-attach branches. Best-effort — never throws;\n * `skill_attach_failed` covers both the path-resolve and staging phases.\n */\n async function attachSkillInstance(\n name: string,\n ): Promise<\n | { ok: true; id: string; live: boolean; toolCount: number }\n | { ok: false; code: string; message: string }\n > {\n try {\n const { skillsDir } = resolveDriverPaths({\n driver: opts.driver ?? wsConfig.agent_config?.default?.driver ?? \"claude-sdk\",\n });\n // `declared: [name]` is an explicit single-skill allowlist — a principled\n // per-attach bypass of the skaile.yaml-derived strict gate (the staging\n // filter IS the gate; survives strict mode). Rationale: PR #170 thread.\n const staged = stageMaterializedSkills(opts.projectDir, skillsDir, {\n declared: [name],\n });\n if (staged.length === 0) {\n return {\n ok: false,\n code: \"skill_not_materialized\",\n message: `no materialized skill matching \"${name}\" under .skaile/assets/skill`,\n };\n }\n log(`[serve] runner.attach_instance staged skill(s): ${staged.join(\", \")}`);\n // Capture before the restart: when the driver hasn't started yet the\n // restart is a no-op and the skill is discovered on the first prompt\n // (not live yet), so `live` must reflect the pre-restart driver state.\n const live = driverStarted;\n await restartDriverForSkillChanges(staged.map((s) => ({ name: s, action: \"add\" as const })));\n // toolCount: skills are system-prompt fragments, not tool-bearing servers.\n return { ok: true, id: name, live, toolCount: 0 };\n } catch (err) {\n return {\n ok: false,\n code: \"skill_attach_failed\",\n message: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n /**\n * Restart the driver so the SDK re-discovers skills from `.claude/skills/`\n * after catalog changes, resuming with conversation history, then emit\n * `skills_changed`. No-op (logs only) when the driver has not started yet —\n * skills are discovered on the first prompt. Accepts the minimal\n * `{ name, action }` shape so both the `session_init` aiResources path and the\n * live `runner.attach_instance` skill path can drive it.\n */\n async function restartDriverForSkillChanges(\n catalogActions: ReadonlyArray<{ name: string; action?: \"add\" | \"remove\"; entry?: unknown }>,\n ): Promise<void> {\n if (!driverStarted) {\n log(\"[serve] aiResources applied before driver start — skills discovered on first prompt\");\n return;\n }\n // Capture the current session ID so we can resume with conversation history.\n const prevSessionId = driver.runtimeSessionId;\n log(`[serve] restarting driver to pick up skill changes (resume=${prevSessionId ?? \"none\"})`);\n await agentSession.dispose();\n agentSession = await createAgentSession({\n ...sessionConfig,\n resumeSessionId: prevSessionId,\n });\n emitSystemPromptComposed(agentSession, sendEvent);\n driver = agentSession.driver;\n normalizer.reset();\n driverStarted = false;\n rebuildCompactionOrchestrator();\n captureBakedMcpServers();\n\n sendEvent({\n type: \"skills_changed\",\n skills: catalogActions.map((a) => ({\n name: ((a.entry as Record<string, unknown>)?.name as string) ?? a.name,\n action: a.action ?? \"add\",\n })),\n });\n }\n\n /** Protocol v3 deterministic boot envelope handler (was the `session_init` case). */\n async function handleSessionInit(\n cmd: Extract<CommandEnvelope, { type: \"session_init\" }>,\n ): Promise<void> {\n // Protocol v3 deterministic boot envelope. Replaces the v2\n // configure + provision_secrets + initial request_access_token round\n // trips with one upfront message carrying identity, resolved config,\n // pre-minted credentials, secrets, capabilities, shared state,\n // active flows, resume hints, and logging config.\n //\n // Spec: _devlog/specs/2026-05-10-deterministic-session-bootstrap.md.\n\n // 1. Protocol major-equality\n if (cmd.protocolVersion.major !== PROTOCOL_VERSION.major) {\n log(\n `[serve] incompatible protocol: agent=${PROTOCOL_VERSION.major} platform=${cmd.protocolVersion.major}`,\n );\n sendEvent({\n type: \"incompatible_protocol\",\n agentVersion: PROTOCOL_VERSION,\n platformVersion: cmd.protocolVersion,\n });\n await cleanup();\n disposeLogStore();\n return;\n }\n\n // 2. Identity. Future successive session_init calls must match this\n // containerId; mismatch shuts the runner down.\n if (runtimeIdentity && runtimeIdentity.containerId !== cmd.identity.containerId) {\n log(\n `[serve] session_init_mismatch: expected=${runtimeIdentity.containerId} received=${cmd.identity.containerId}`,\n );\n sendEvent({\n type: \"session_init_mismatch\",\n expectedContainerId: runtimeIdentity.containerId,\n receivedContainerId: cmd.identity.containerId,\n });\n await cleanup();\n disposeLogStore();\n return;\n }\n runtimeIdentity = cmd.identity;\n\n // 3. Register client-side capabilities from the envelope.\n registerInitClientCapabilities(cmd.capabilities ?? []);\n sendEvent({ type: \"protocol_info\", version: PROTOCOL_VERSION });\n\n // 4. Pre-minted credentials → in-process PreMintedSecretProvider.\n preMintedSecrets = new PreMintedSecretProvider(cmd.credentials);\n\n // 5. Long-lived secrets → in-memory secret provider (replaces\n // provision_secrets). The Claude Code credentials JSON is handled\n // separately — it goes to disk, not the secret provider.\n const initialAiCredentialExpiresAt = await provisionInitSecrets(cmd.secrets);\n\n // 5a. Stash aiProviderConfigId for the auth-error retry handler. Cheap;\n // kept on the fast path (before the ack) so the refresh timer is armed\n // even while the heavy build is still in flight.\n if (cmd.resolvedConfig.aiProviderConfigId) {\n aiProviderConfigId = cmd.resolvedConfig.aiProviderConfigId;\n log(`[serve] stashed aiProviderConfigId=${aiProviderConfigId}`);\n }\n\n // 5b. Arm the proactive AI-credential refresh timer. Needs\n // aiProviderConfigId in scope (set above) AND an `expiresAt`\n // parsed from the initial credentials blob (step 5). Static PATs\n // and standalone sessions short-circuit to no-op inside the\n // scheduler.\n if (aiProviderConfigId && initialAiCredentialExpiresAt) {\n aiCredentialRefreshScheduler.schedule(initialAiCredentialExpiresAt);\n }\n\n // 6. Ack before the slow connector/MCP bring-up (step 7) so a cold container can't\n // blow the platform's session_init_ack budget; the deferred build resolves the\n // `sessionReady` gate every session-dependent command awaits. Ack signature is informational.\n sendEvent({\n type: \"session_init_ack\",\n capabilitySignature: computeCapabilitySignature(capabilityRegistry.list()),\n });\n\n // 7. Kick off the heavy build + post-build configure in the background.\n // Success resolves `sessionReady`; any failure surfaces a fatal `error`\n // event and rejects `sessionReady` so awaiting commands fail fast instead\n // of wedging.\n const buildSession = async (): Promise<void> => {\n // Build session using the resolved config. Replaces the v2\n // provision_secrets + configure handshake.\n await buildSessionFromInit(cmd.secrets);\n\n // 8. Adapt the rest of the configure logic onto envelope fields.\n const cfg = {\n aiResources: cmd.resolvedConfig.aiResources,\n subagents: cmd.resolvedConfig.subagents,\n sharedState: cmd.sharedState,\n resumeSessionId: cmd.resume?.sessionId,\n expectedCapabilitySignature: cmd.resume?.expectedCapabilitySignature,\n aiProviderConfigId: cmd.resolvedConfig.aiProviderConfigId,\n };\n log(\n `[serve] configure cfg keys=${Object.keys(cfg).join(\",\")} sharedState=${cfg.sharedState ? cfg.sharedState.length : \"undefined\"} resourceManager=${resourceManager ? \"set\" : \"null\"}`,\n );\n\n // `aiProviderConfigId` was already stashed in step 7 above. The legacy\n // configure-handler block re-stashed `cfg.aiProviderConfigId` here for\n // the standalone configure path; on session_init the field is sourced\n // from the same `cmd.resolvedConfig.aiProviderConfigId` so the second\n // assignment was redundant and has been removed.\n //\n // Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`\n // § \"Wire `aiProviderConfigId` end-to-end\".\n\n // Configure/wake re-arm. The fast-path armed the proactive timer at step\n // 5b; this revives it if a prior fire died (terminal failure / exhausted\n // retry cap) or went stale, so a re-connecting (or never-hibernated)\n // container does not arm exactly once and then stop refreshing. Idempotent\n // and a no-op for static PATs / a healthy pending timer.\n if (aiProviderConfigId) {\n aiCredentialRefreshScheduler.ensureArmed();\n }\n\n // ── Tier-1 native SDK resume (Phase 3 of the resume cascade) ──────\n //\n // The platform sets `cfg.resumeSessionId` (and optionally\n // `cfg.expectedCapabilitySignature`) when wake-time tier selection\n // chose tier 1. We:\n // 1. Compute the current registry signature post-cap-registration.\n // 2. If a signature was supplied and it doesn't match — drop the\n // resume hint and emit `resume_failed { signature_mismatch }`.\n // 3. Otherwise, dispose + recreate the driver with the supplied\n // session id so the first prompt resumes the SDK conversation.\n //\n // Spec: `_devlog/specs/2026-05-05-session-resume-restart-design.md`\n // The resume hint is staged here and merged into any subsequent\n // driver recreate within this configure call. Without staging, a\n // later branch (e.g. `cfg.subagents`) would clobber the resume by\n // recreating the driver from `sessionConfig` without the hint.\n let pendingResumeSessionId: string | undefined;\n const cfgResumeSessionId = cfg.resumeSessionId;\n const cfgExpectedSig = cfg.expectedCapabilitySignature;\n if (cfgResumeSessionId) {\n const currentSig = computeCapabilitySignature(capabilityRegistry.list());\n if (cfgExpectedSig && cfgExpectedSig !== currentSig) {\n log(\n `[serve] tier-1 resume rejected: signature mismatch (expected=${cfgExpectedSig.slice(0, 12)} current=${currentSig.slice(0, 12)})`,\n );\n sendEvent({\n type: \"resume_failed\",\n resumeSessionId: cfgResumeSessionId,\n reason: \"signature_mismatch\",\n });\n } else {\n log(`[serve] tier-1 resume attempted: resumeSessionId=${cfgResumeSessionId}`);\n sendEvent({\n type: \"resume_attempted\",\n resumeSessionId: cfgResumeSessionId,\n capabilitySignature: currentSig,\n });\n pendingResumeSessionId = cfgResumeSessionId;\n }\n }\n\n // Apply tier-1 resume + any subagents recreate in a single dispose\n // + recreate. Either branch alone, both together, or neither. When\n // both are set, the subagents `cfg.subagents` is already in\n // `sessionConfig.wsConfig` via `buildSessionConfig`, so `cfg.subagents`\n // here is informational only — we still need to recreate so the\n // driver picks up the new config. Threading\n // `pendingResumeSessionId` into the same recreate prevents the\n // tier-1 hint from being clobbered.\n if (pendingResumeSessionId || cfg.subagents) {\n await recreateSessionForInit(pendingResumeSessionId);\n }\n if (cfg.sharedState) {\n const handled = await applyInitSharedState(cfg.sharedState);\n // Runs inside the background build closure, so a bare `return` would leave\n // `sessionReady` unresolved forever — throw so the catch below rejects the\n // gate and emits a fatal error.\n if (!handled) throw new Error(\"session_init: shared-state setup failed\");\n }\n\n // Phase 4 of flow-connector extraction (Protocol 2.2): the implicit\n // `configure.activeFlows` rehydration was removed. Hosts now issue an\n // explicit `connector_mutate { id: \"flow\", op: \"hydrate\" }` per flow\n // after `configure` completes. See `MIGRATION-flow-connector.md`.\n\n // Handle aiResources (mid-session skill changes via catalog)\n if (cfg.aiResources) {\n await applyInitAiResources(cfg.aiResources);\n }\n\n // Build complete (including the slow connector/MCP bring-up and the\n // post-build configure). Release the readiness gate so queued prompts\n // and resource ops proceed against a fully-built session.\n resolveSessionReady();\n };\n\n void buildSession().catch((err: unknown) => {\n const errMsg = err instanceof Error ? err.message : String(err);\n log(`[serve] session_init failed to build session: ${errMsg}`);\n sendEvent({ type: \"error\", message: errMsg, fatal: true });\n rejectSessionReady(err instanceof Error ? err : new Error(errMsg));\n });\n }\n\n /** Free-chat prompt handler (was the `prompt` case). Lazy-starts the driver. */\n async function handlePrompt(cmd: Extract<CommandEnvelope, { type: \"prompt\" }>): Promise<void> {\n if (!(await awaitSessionReadyOrFail())) return;\n if (!secretsProvisioned) {\n log(\"[serve] prompt received before secrets provisioned — rejecting\");\n sendEvent({\n type: \"error\",\n message: \"Secrets not yet provisioned — send provision_secrets first\",\n fatal: false,\n });\n return;\n }\n log(`[serve] prompt: ${cmd.prompt.slice(0, 80)}...`);\n\n // Pick up any declared skill the platform materialized after boot (a\n // freshly-provisioned session whose first materialize landed late) and\n // restart the driver for newly-appeared skills before this turn runs.\n await restageMaterializedSkills(true);\n\n // Route free-chat user messages through the SessionStimulusBus\n // when a flow is active — every turn then includes the flow\n // context, and the agent decides whether to advance the flow\n // or just answer the user. The original prompt path below\n // runs only when no flow is active. Sender attribution comes\n // from the envelope layer in hosts that track it; the bare\n // prompt command carries none today so we use a placeholder.\n const activeFlow = getOnlyActiveFlow();\n if (activeFlow) {\n sendEvent({ type: \"status\", phase: \"thinking\" });\n try {\n const bus = getOrCreateStimulusBus();\n const userStimulus: TurnStimulus = {\n kind: \"user_message\",\n text: cmd.prompt,\n senderId: \"user\",\n };\n await bus.signal(activeFlow.connectorId, {\n promptFragment: renderStimulusPrompt(userStimulus),\n meta: {\n kind: \"user_message\",\n runId: activeFlow.runId,\n text: cmd.prompt,\n senderId: \"user\",\n },\n });\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n log(`[serve] flow user-message turn failed: ${errMsg}`);\n sendEvent({ type: \"error\", message: `Flow turn failed: ${errMsg}`, fatal: false });\n }\n return;\n }\n\n if (!driverStarted) {\n try {\n await driver.start();\n driverStarted = true;\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n log(`[serve] driver start failed: ${errMsg}`);\n sendEvent({ type: \"error\", message: `Driver start failed: ${errMsg}`, fatal: true });\n return;\n }\n\n // Wire event forwarding through normalizer\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n driver.on(\"agent-event\", (event: any) => {\n const normalized = normalizer.normalize(event);\n for (const e of normalized) {\n forwardNormalizedEvent(e);\n }\n });\n\n driver.on(\"error\", (err: Error) => {\n log(`[serve] driver error: ${err.message}`);\n sendEvent({ type: \"error\", message: err.message, fatal: true });\n });\n }\n\n sendEvent({ type: \"status\", phase: \"thinking\" });\n\n try {\n await driver.prompt(cmd.prompt);\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n log(`[serve] prompt failed: ${errMsg}`);\n sendEvent({ type: \"error\", message: `Prompt failed: ${errMsg}`, fatal: true });\n }\n }\n\n /** Reply-to-question handler (was the `reply` case). */\n async function handleReply(cmd: Extract<CommandEnvelope, { type: \"reply\" }>): Promise<void> {\n if (!(await awaitSessionReadyOrFail())) return;\n log(`[serve] reply: ${cmd.answer.slice(0, 80)}...`);\n\n // When the driver is paused on an interactive question (e.g. the Claude SDK\n // AskUserQuestion tool), deliver the answer into that paused turn instead of\n // starting a new prompt. Routing it as a fresh prompt is what made the\n // onboarding assistant re-ask the same question: the SDK never received the\n // structured answer, so the question stayed unanswered. answerQuestion\n // resumes the in-flight turn (it does not await a new one), so we return.\n if (driver.hasPendingQuestion() && driver.answerQuestion(cmd.answer)) return;\n\n try {\n await driver.prompt(cmd.answer);\n } catch (err) {\n sendEvent({\n type: \"error\",\n message: `Reply failed: ${err instanceof Error ? err.message : String(err)}`,\n fatal: false,\n });\n }\n }\n\n /** Cancel/abort handler (was the `cancel` case). */\n async function handleCancel(): Promise<void> {\n if (!(await awaitSessionReadyOrFail())) return;\n log(\"[serve] cancel\");\n try {\n await driver.abort();\n } catch (err) {\n log(`[serve] cancel failed: ${err}`);\n }\n }\n\n /** Resource request handler (was the `resource_request` case). */\n async function handleResourceRequestCommand(\n cmd: Extract<CommandEnvelope, { type: \"resource_request\" }>,\n ): Promise<void> {\n if (!(await awaitSessionReadyOrFail())) return;\n // Route to mounts handler if the ID matches a mounted mount\n if (resourceManager?.has(cmd.connectorId)) {\n await handleMountResourceRequest(cmd, resourceManager, sendEvent);\n return;\n }\n if (!resourceManager) {\n sendEvent({\n type: \"resource_response\",\n requestId: cmd.requestId,\n resourceId: cmd.connectorId,\n operation: cmd.operation,\n error: \"No resources available — no mounts or connectors configured\",\n });\n return;\n }\n void handleResourceRequest(cmd, resourceManager, sendEvent);\n }\n\n /** Generic connector mutation dispatch (was the `connector_mutate` case). */\n async function handleConnectorMutate(\n cmd: Extract<CommandEnvelope, { type: \"connector_mutate\" }>,\n ): Promise<void> {\n // session_init acks before the connector/MCP bring-up finishes, so this can\n // arrive before resourceManager exists. Gate on the readiness promise; a build\n // failure surfaces a fatal error instead of a confusing \"before resources ready\" throw.\n try {\n await sessionReady;\n } catch (err) {\n sendEvent({\n type: \"error\",\n message: `Session not available: ${(err as Error).message}`,\n fatal: true,\n });\n return;\n }\n try {\n if (!resourceManager) throw new Error(\"connector_mutate before resources ready\");\n // Phase 4: when the host issues `start` against the `flow` connector,\n // route through `createActiveFlow` so the activeFlows map and bus\n // wiring stay in sync with the adapter's new run. The path also\n // ensures the SDK driver's MCP tool surface picks up the flow tools\n // (legacy parity with the removed `start_flow` typed handler).\n //\n // For all other ops we fall through to the generic dispatch — the\n // adapter's mutate() pipeline emits state_changed via onChange and\n // wakes the next turn through the stimulus bus.\n //\n // Hosts address the flow connector by its bare driver id (\"flow\")\n // per MIGRATION-flow-connector.md. createActiveFlow registers the\n // per-run connector at id `flow:${runId}`, so we (a) treat a bare\n // \"flow\" id with no existing entry as a request to create one\n // (start path, below) and (b) rewrite a bare \"flow\" id to the\n // singleton active run's connectorId for non-start ops so the\n // ConnectorManager lookup succeeds.\n const targetEntry = resourceManager.has?.(cmd.id) ? resourceManager.get(cmd.id) : null;\n const isExistingFlow =\n (targetEntry?.connector as { name?: string } | undefined)?.name === \"flow\";\n const isBareFlowId = cmd.id === \"flow\";\n if (cmd.op === \"start\") {\n if (isExistingFlow || isBareFlowId) {\n const payload = (cmd.payload ?? {}) as Record<string, unknown>;\n const flowDef = payload.flow as FlowDefinition | undefined;\n const seed = payload.seed as\n | { runId: string; startedBy: string; autonomousMode?: boolean }\n | undefined;\n if (flowDef?.id && seed?.runId && seed?.startedBy) {\n if (activeFlows.size > 0) {\n serverLog.warn(\"connector_mutate flow.start: another flow already active\", {\n activeRunIds: Array.from(activeFlows.keys()),\n });\n return;\n }\n const entry = await createActiveFlow(flowDef, { seed });\n serverLog.info(\"connector_mutate flow.start\", {\n runId: entry.runId,\n flowId: flowDef.id,\n });\n return;\n }\n }\n }\n // Non-start ops: rewrite bare \"flow\" id to the active run's\n // connectorId. The runner enforces a singleton active flow at\n // `start` time, so picking the only entry is safe.\n let dispatchId = cmd.id;\n if (!targetEntry && isBareFlowId) {\n const onlyActive = getOnlyActiveFlow();\n if (onlyActive) {\n dispatchId = onlyActive.connectorId;\n }\n }\n await resourceManager.executeOp(dispatchId, cmd.op, cmd.payload ?? {});\n } catch (err) {\n serverLog.warn(\"connector_mutate failed\", {\n id: cmd.id,\n op: cmd.op,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n /** Generic connector query dispatch (was the `connector_query` case). */\n async function handleConnectorQuery(\n cmd: Extract<CommandEnvelope, { type: \"connector_query\" }>,\n ): Promise<void> {\n // Gate on session readiness — see handleConnectorMutate.\n try {\n await sessionReady;\n } catch (err) {\n sendEvent({\n type: \"error\",\n message: `Session not available: ${(err as Error).message}`,\n fatal: true,\n });\n return;\n }\n let ok = true;\n let result: string | undefined;\n let error: string | undefined;\n try {\n if (!resourceManager) throw new Error(\"connector_query before resources ready\");\n // Same bare-\"flow\"-id rewrite as connector_mutate so hosts can\n // address the flow connector by its driver id without knowing\n // the per-run connectorId format.\n let dispatchId = cmd.id;\n if (!resourceManager.has?.(cmd.id) && cmd.id === \"flow\") {\n const onlyActive = getOnlyActiveFlow();\n if (onlyActive) {\n dispatchId = onlyActive.connectorId;\n }\n }\n result = await resourceManager.executeOp(dispatchId, cmd.op, cmd.payload ?? {});\n } catch (err) {\n ok = false;\n error = err instanceof Error ? err.message : String(err);\n }\n sendEvent({\n type: \"connector_query_response\",\n requestId: cmd.requestId,\n ok,\n ...(result !== undefined ? { result } : {}),\n ...(error !== undefined ? { error } : {}),\n });\n }\n\n /**\n * Compute the `debug_result` payload for a `debug` query (was the inner\n * switch of `handleDebug`). Pure introspection over the live driver /\n * session / resource manager — never throws the per-case work; the caller\n * wraps the whole call in a try/catch for defence in depth.\n */\n async function computeDebugResult(\n cmd: Extract<CommandEnvelope, { type: \"debug\" }>,\n ): Promise<unknown> {\n switch (cmd.query) {\n case \"tools\": {\n const mcpServers = Object.keys((driver as any)?.config?.mcpServers ?? {});\n const allowedTools = (driver as any)?.config?.allowedTools ?? null;\n return { mcpServers, allowedTools, driverStarted };\n }\n case \"connectors\": {\n return resourceManager?.listConnectors?.() ?? [];\n }\n case \"mcp\": {\n const servers = Object.entries((driver as any)?.config?.mcpServers ?? {}).map(([name]) => ({\n name,\n }));\n return { servers };\n }\n case \"config\": {\n // Read model from the live driver so changes via\n // reconfigure_agent are reflected in the debug panel.\n const liveModel = driver?.getModel() ?? agentSession?.model;\n return {\n driver: agentSession?.driverType,\n model: liveModel,\n provider: agentSession?.provider,\n maxTurns,\n secretsMode,\n driverStarted,\n projectDir: opts.projectDir,\n versions: getFrameworkVersions(),\n };\n }\n case \"state\": {\n const storeId = cmd.args?.store as string | undefined;\n if (storeId) {\n try {\n const snapshot = await resourceManager?.executeOp(storeId, \"get\", {});\n return snapshot ? JSON.parse(snapshot) : null;\n } catch (err) {\n return { error: err instanceof Error ? err.message : String(err) };\n }\n }\n const all = resourceManager?.listConnectors?.() ?? [];\n return { stores: all.map((c: { id: string }) => c.id) };\n }\n case \"commands\": {\n const commands = driver?.getSlashCommands?.() ?? [];\n return { commands, driverType: agentSession?.driverType };\n }\n default:\n return { error: `Unknown debug query: ${(cmd as any).query}` };\n }\n }\n\n /** Debug introspection handler (was the `debug` case). */\n async function handleDebug(cmd: Extract<CommandEnvelope, { type: \"debug\" }>): Promise<void> {\n if (!(await awaitSessionReadyOrFail())) return;\n log(`[serve] debug query=${cmd.query}`);\n let result: unknown;\n try {\n result = await computeDebugResult(cmd);\n } catch (err) {\n result = { error: err instanceof Error ? err.message : String(err) };\n }\n sendEvent({ type: \"debug_result\", query: cmd.query, data: result });\n }\n\n /** Graceful shutdown handler (was the `shutdown` case). Never returns. */\n async function handleShutdown(): Promise<void> {\n log(\"[serve] shutdown requested\");\n await cleanup();\n await transport.close();\n disposeLogStore();\n process.exit(0);\n }\n\n /** Capability round-trip result handler (was the `capability_result` case). */\n function handleCapabilityResult(\n cmd: Extract<CommandEnvelope, { type: \"capability_result\" }>,\n ): void {\n const matched = resolveCapabilityResult(pendingCapabilityCalls, cmd);\n if (!matched) {\n log(\n `[serve] capability_result for unknown callId=${cmd.callId} (timed out or already resolved); dropping`,\n );\n }\n }\n\n /** Mid-session capability registration handler (was the `capability_register` case). */\n function handleCapabilityRegister(\n cmd: Extract<CommandEnvelope, { type: \"capability_register\" }>,\n ): void {\n for (const raw of cmd.capabilities) {\n const wire = raw;\n capabilityRegistry.register(\n {\n ...wire,\n inputZod: { parse: (v: unknown) => v } as unknown as import(\"zod\").ZodTypeAny,\n outputZod: undefined,\n handler: buildClientCapabilityHandler(wire),\n },\n \"client\",\n );\n }\n }\n\n /** Mid-session capability deregistration handler (was the `capability_deregister` case). */\n function handleCapabilityDeregister(\n cmd: Extract<CommandEnvelope, { type: \"capability_deregister\" }>,\n ): void {\n for (const name of cmd.names) {\n capabilityRegistry.deregister(name);\n }\n }\n\n /** Capability approval-decision handler (was the `capability_approve` case). */\n function handleCapabilityApprove(\n cmd: Extract<CommandEnvelope, { type: \"capability_approve\" }>,\n ): void {\n // Protocol v2.1 — the platform forwards the user's decision for any\n // capability declared `requiresApproval: true`. The platform itself\n // gates dispatch (it parks the `capability_invoked` until the user\n // responds), so:\n //\n // - `approved`: the platform proceeds to dispatch and replies with\n // `capability_result` through the normal path. We only audit-log\n // here; rejecting/resolving the pending call would race the\n // subsequent result.\n // - `rejected`: the platform did NOT dispatch. Reject the pending\n // call so the LLM sees a tool error explaining the user denied\n // the action.\n if (cmd.decision === \"rejected\") {\n const matched = rejectCapabilityOnApprovalDeny(\n pendingCapabilityCalls,\n cmd.callId,\n cmd.feedback,\n );\n if (!matched) {\n log(\n `[serve] capability_approve(rejected) for unknown callId=${cmd.callId} (already resolved or timed out); dropping`,\n );\n } else {\n log(\n `[serve] capability_approve(rejected) callId=${cmd.callId} decidedBy=${cmd.decidedBy}${cmd.feedback ? ` feedback=${JSON.stringify(cmd.feedback)}` : \"\"}`,\n );\n }\n } else {\n log(\n `[serve] capability_approve(approved) callId=${cmd.callId} decidedBy=${cmd.decidedBy} (awaiting capability_result)`,\n );\n }\n }\n\n async function handleCommand(cmd: CommandEnvelope) {\n // v3: the access_token_response ingress is removed — refresh-on-401\n // rides on the host.refresh_credential capability invocation now.\n // SessionInitCommand is delivered alongside AgentCommand on the same\n // transport — type the parameter as the envelope union so the switch\n // can handle both.\n\n // Protocol v3 — inbound runner-cap invocation from the platform.\n // `capability_invoked` is modelled as an agent→client event, so it is not\n // in the AgentCommand union; the platform sends it as a command to drive an\n // audience:'runtime' cap. Mirror of the runner→platform invoker.\n const inbound = cmd as { type?: string; callId?: string; name?: string; input?: unknown };\n\n // Dormant until the platform single-flight mediator ships: a broadcast that\n // a sibling already rotated the shared credential. Re-pull the fresh token\n // from the host instead of each container force-refreshing (the storm).\n if (isCredentialRotatedSignal(cmd)) {\n await handleCredentialRotatedSignal({\n repull: () => mintAndPersistAiCredential({ reason: \"refresh\" }),\n log,\n logError: (line: string) => serverLog.error(line),\n });\n return;\n }\n\n if (inbound.type === \"capability_invoked\") {\n await dispatchRunnerCapabilityInvocation(\n { callId: inbound.callId ?? \"\", name: inbound.name ?? \"\", input: inbound.input },\n {\n invoke: (name, input) => capabilityRegistry.invoke(name, input, { sessionId }),\n emit: (event) => sendEvent(event as unknown as AgentEvent),\n },\n );\n return;\n }\n switch (cmd.type) {\n case \"session_init\":\n await handleSessionInit(cmd);\n break;\n case \"prompt\":\n await handlePrompt(cmd);\n break;\n case \"reply\":\n await handleReply(cmd);\n break;\n case \"cancel\":\n await handleCancel();\n break;\n // v3: compact + lifecycle removed — reachable via runner.lifecycle capability\n // (the v3 `runner.lifecycle` cap takes `{ phase: 'hibernate' | 'close' | 'compact' }`).\n case \"resource_request\":\n await handleResourceRequestCommand(cmd);\n break;\n // v3: state_action removed — reachable via the runner.set_state capability.\n\n // ── Generic connector dispatch (Protocol 2.2) ──────────────────────\n // The 6 typed flow commands (`start_flow`, `approve_flow_node`,\n // `provide_flow_input`, `cancel_flow`, `set_flow_autonomous_mode`,\n // `retry_flow_node`) were removed in Phase 4 of the flow-connector\n // extraction. Hosts now drive flow execution exclusively through\n // `connector_mutate` against the `flow` connector. See\n // `MIGRATION-flow-connector.md` for the per-op mapping table.\n case \"connector_mutate\":\n await handleConnectorMutate(cmd);\n break;\n case \"connector_query\":\n await handleConnectorQuery(cmd);\n break;\n case \"debug\":\n await handleDebug(cmd);\n break;\n\n // -----------------------------------------------------------------------\n // -----------------------------------------------------------------------\n\n // v3: add_resource, remove_resource, remount_mount, set_log_level,\n // reconfigure_agent removed from AgentCommand union.\n // Reachable now via the `runner.set_log_level` and `runner.reconfigure`\n // capability invocations (audience: ['runtime']) — the platform calls\n // them through invokeRunnerCapability on the gateway. Handler bodies\n // live in the runner.* capability registrations.\n\n case \"shutdown\":\n await handleShutdown();\n break;\n\n // Protocol v2 — capability round-trip results from the platform.\n case \"capability_result\":\n handleCapabilityResult(cmd);\n break;\n\n // Protocol v2 — additional capability lifecycle commands. The platform\n // can register / deregister capabilities mid-session (e.g. when a user\n // installs an extension after `configure`). Approval routing is reserved\n // for a later phase; we accept the command shape for forward\n // compatibility and log it.\n case \"capability_register\":\n handleCapabilityRegister(cmd);\n break;\n case \"capability_deregister\":\n handleCapabilityDeregister(cmd);\n break;\n case \"capability_approve\":\n handleCapabilityApprove(cmd);\n break;\n }\n }\n\n // Wire transport commands to handler\n transport.onCommand((cmd) => {\n void handleCommand(cmd);\n });\n\n // Start listening (no-op for transports with no startup phase).\n await transport.listen();\n\n // Start filesystem/connector watchers AFTER the transport is listening.\n // Watching can be slow on large directory trees (e.g. node_modules over\n // Docker bind mounts) and must not block the WebSocket readiness check.\n if (secretsMode === \"env\" && agentSession!) {\n agentSession!.startWatching();\n }\n\n // Emit available resources + cached slash commands to connected clients.\n // Fired on each client connect (the platform connects after the server\n // starts listening) and again after a session recreate, whose new\n // resourceManager would otherwise never be announced to the gateway.\n function emitAvailability(): void {\n if (resourceManager || agentSession?.getExternalMcpManager()) {\n const driverLive = agentSession?.driverType !== \"claude-sdk\";\n const payload = buildResourcesAvailablePayload(\n resourceManager,\n agentSession?.getExternalMcpManager() ?? null,\n driverLive,\n bakedMcpServerIds,\n );\n log(\n `[serve] emitting resources_available: ${payload.mounts.length} mount(s), ${payload.connectors.length} connector(s)`,\n );\n sendEvent(payload);\n }\n // Re-emit cached slash commands if the driver has already discovered them\n const commands = driver?.getSlashCommands?.() ?? [];\n if (commands.length > 0) {\n log(`[serve] emitting commands_available: ${commands.length} command(s)`);\n sendEvent({ type: \"commands_available\", commands });\n }\n }\n // Fires on client connect for WebSocket and the in-memory test pair; the\n // in-process transport registers the handler but never invokes it.\n transport.onConnect(emitAvailability);\n\n if (secretsMode === \"env\") {\n log(\n `[serve] driver=${agentSession!.driverType} model=${agentSession!.model ?? \"(default)\"} provider=${agentSession!.provider ?? \"(default)\"} maxTurns=${maxTurns ?? \"(default)\"}`,\n );\n } else {\n log(`[serve] secrets=provisioned — session will initialize after provision_secrets`);\n }\n log(`[serve] project=${opts.projectDir}`);\n\n installProcessHandlers();\n\n /**\n * Register process-level safety nets and graceful-shutdown signal handlers.\n * Extracted from the tail of {@link startAgentServer} to keep the setup body\n * flat; the nested {@link initiateShutdown} closes over `cleanup` /\n * `transport` / `log` / `disposeLogStore` exactly as before.\n *\n * Signal handling must be safe against:\n * - Shutdown while session is still initializing (cleanup bounds its own wait).\n * - Hanging mount unmount / connector disconnect / driver kill (deadline timer force-exits).\n * - User impatience (second SIGINT/SIGTERM force-exits immediately).\n */\n function installProcessHandlers(): void {\n // Last-resort safety net: a single bad watcher event or stray async error\n // should never take the session down. Log and keep serving.\n process.on(\"uncaughtException\", (err) => {\n log(\n `[serve] uncaughtException (non-fatal): ${err instanceof Error ? (err.stack ?? err.message) : String(err)}`,\n );\n });\n process.on(\"unhandledRejection\", (reason) => {\n log(\n `[serve] unhandledRejection (non-fatal): ${reason instanceof Error ? (reason.stack ?? reason.message) : String(reason)}`,\n );\n });\n\n const GRACEFUL_SHUTDOWN_TIMEOUT_MS = 5000;\n let shuttingDown = false;\n\n async function initiateShutdown(signal: \"SIGINT\" | \"SIGTERM\"): Promise<void> {\n if (shuttingDown) {\n log(`[serve] ${signal} received again — forcing exit`);\n process.exit(130);\n }\n shuttingDown = true;\n log(`[serve] ${signal} received — shutting down (press Ctrl-C again to force)`);\n\n const forceExitTimer = setTimeout(() => {\n log(`[serve] graceful shutdown exceeded ${GRACEFUL_SHUTDOWN_TIMEOUT_MS}ms — forcing exit`);\n process.exit(130);\n }, GRACEFUL_SHUTDOWN_TIMEOUT_MS);\n forceExitTimer.unref?.();\n\n try {\n await cleanup();\n } catch (err) {\n log(`[serve] cleanup error: ${(err as Error).message}`);\n }\n try {\n await transport.close();\n } catch (err) {\n log(`[serve] transport close error: ${(err as Error).message}`);\n }\n\n clearTimeout(forceExitTimer);\n log(\"[serve] shutdown complete\");\n disposeLogStore();\n process.exit(0);\n }\n\n process.on(\"SIGTERM\", () => {\n void initiateShutdown(\"SIGTERM\");\n });\n process.on(\"SIGINT\", () => {\n void initiateShutdown(\"SIGINT\");\n });\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nconst SESSION_DIR = \".skaile\";\nconst SESSIONS_SUBDIR = \"sessions\";\nconst CURRENT_FILE = \"current\";\nconst LEGACY_FILE = \"session.json\";\n\n/**\n * Runner session metadata.\n *\n * Holds only what the runner needs to resume the agent driver across\n * process restarts — notably `driverSessionId` for SDK session resume.\n *\n * Flow execution state (per-node status, approvals, outputs) moved out\n * of the session file in Phase 2 of the flow-execution plan. It now\n * lives in the FlowAdapter's in-memory snapshot and, for hosts that\n * persist it, in whatever durable store they provide (the Skaile\n * platform uses the `FlowExecution` Prisma table). The runner does\n * not read or write flow state from disk.\n * @docLink packages/runner/session#session-state\n */\nexport interface SessionState {\n /** Unique identifier for this session run (UUID). */\n runId: string;\n /** ID of the flow definition being executed. */\n flowId: string;\n /** Absolute path to the project directory. */\n projectDir: string;\n /**\n * Absolute path to the agent definition directory (`agent.yaml`,\n * `SOUL.md`, `RULES.md`, `knowledge/`). Resolved from `skaile.yaml`\n * via `resolveAgentDir` when absent at session creation time.\n */\n agentDir?: string;\n /** Agent driver backend used for this session (e.g. `\"omp\"`, `\"claude-sdk\"`). */\n driver: string;\n /** LLM provider (if set), e.g. `\"anthropic\"` or `\"openrouter\"`. */\n provider?: string;\n /** Model name (if set), e.g. `\"claude-opus-4-5\"`. */\n model?: string;\n /** Provider-native session/thread identifier for resume support. */\n driverSessionId?: string;\n /** ISO 8601 timestamp when the session was created. */\n startedAt: string;\n /** ISO 8601 timestamp of the last state change. */\n updatedAt: string;\n /** Optional human-readable label for the session */\n label?: string;\n /** Session lifecycle status. */\n status?: \"running\" | \"complete\" | \"failed\" | \"paused\";\n}\n\n// ---------------------------------------------------------------------------\n// Path helpers\n// ---------------------------------------------------------------------------\n\nfunction sessionsDir(projectDir: string): string {\n return path.join(projectDir, SESSION_DIR, SESSIONS_SUBDIR);\n}\n\nfunction sessionFilePath(projectDir: string, runId: string): string {\n return path.join(sessionsDir(projectDir), `${runId}.json`);\n}\n\nfunction currentPointerPath(projectDir: string): string {\n return path.join(projectDir, SESSION_DIR, CURRENT_FILE);\n}\n\nfunction legacySessionPath(projectDir: string): string {\n return path.join(projectDir, SESSION_DIR, LEGACY_FILE);\n}\n\n// ---------------------------------------------------------------------------\n// Migration\n// ---------------------------------------------------------------------------\n\n/**\n * Migrate legacy session.json to sessions/<runId>.json if it exists.\n * Safe to call multiple times — no-op if already migrated.\n */\nasync function migrateLegacySession(projectDir: string): Promise<void> {\n const legacyPath = legacySessionPath(projectDir);\n try {\n const raw = await fs.readFile(legacyPath, \"utf-8\");\n const state = JSON.parse(raw) as SessionState;\n // Write to new location\n await fs.mkdir(sessionsDir(projectDir), { recursive: true });\n await fs.writeFile(\n sessionFilePath(projectDir, state.runId),\n JSON.stringify(state, null, 2),\n \"utf-8\",\n );\n // Write current pointer\n await fs.writeFile(currentPointerPath(projectDir), state.runId, \"utf-8\");\n // Remove legacy file\n await fs.rm(legacyPath);\n } catch {\n // No legacy file or already migrated — ignore\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Load the current (most recently active) session for a project.\n *\n * Reads the `<projectDir>/.skaile/current` pointer file and loads the\n * corresponding session. Auto-migrates the legacy flat `session.json`\n * format to the per-run `sessions/<runId>.json` layout on first call.\n *\n * @param projectDir - Absolute path to the project directory.\n * @returns The current session or `null` if no session exists.\n * @docLink packages/runner/session#load-session\n */\nexport async function loadSession(projectDir: string): Promise<SessionState | null> {\n await migrateLegacySession(projectDir);\n try {\n const runId = (await fs.readFile(currentPointerPath(projectDir), \"utf-8\")).trim();\n if (!runId) return null;\n return await loadSessionById(projectDir, runId);\n } catch {\n return null;\n }\n}\n\n/**\n * Load a specific session by its run ID.\n *\n * @param projectDir - Absolute path to the project directory.\n * @param runId - The UUID of the session to load.\n * @returns The session state or `null` if not found.\n * @docLink packages/runner/session#load-session-by-id\n */\nexport async function loadSessionById(\n projectDir: string,\n runId: string,\n): Promise<SessionState | null> {\n try {\n const raw = await fs.readFile(sessionFilePath(projectDir, runId), \"utf-8\");\n return JSON.parse(raw) as SessionState;\n } catch {\n return null;\n }\n}\n\n/**\n * List all sessions for a project.\n *\n * Auto-migrates the legacy flat `session.json` format on first call.\n * Corrupt or unreadable session files are silently skipped.\n *\n * @param projectDir - Absolute path to the project directory.\n * @returns All sessions sorted by `updatedAt` descending (newest first).\n * @docLink packages/runner/session#list-sessions\n */\nexport async function listSessions(projectDir: string): Promise<SessionState[]> {\n await migrateLegacySession(projectDir);\n const dir = sessionsDir(projectDir);\n try {\n const files = await fs.readdir(dir);\n const sessions: SessionState[] = [];\n for (const file of files) {\n if (!file.endsWith(\".json\")) continue;\n try {\n const raw = await fs.readFile(path.join(dir, file), \"utf-8\");\n sessions.push(JSON.parse(raw) as SessionState);\n } catch {\n /* skip corrupt files */\n }\n }\n return sessions.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));\n } catch {\n return [];\n }\n}\n\n/**\n * Persist a session to `<projectDir>/.skaile/sessions/<runId>.json`.\n *\n * @param projectDir - Absolute path to the project directory.\n * @param state - Session state to write.\n * @param setCurrent - When `true` (default), updates the `current` pointer\n * file so subsequent {@link loadSession} calls return this session.\n * @docLink packages/runner/session#save-session\n */\nexport async function saveSession(\n projectDir: string,\n state: SessionState,\n setCurrent = true,\n): Promise<void> {\n await fs.mkdir(sessionsDir(projectDir), { recursive: true });\n await fs.writeFile(\n sessionFilePath(projectDir, state.runId),\n JSON.stringify(state, null, 2),\n \"utf-8\",\n );\n if (setCurrent) {\n await fs.writeFile(currentPointerPath(projectDir), state.runId, \"utf-8\");\n }\n}\n\n/**\n * Set the current session pointer to an existing session.\n *\n * @param projectDir - Absolute path to the project directory.\n * @param runId - The UUID of the session to make current.\n * @throws {Error} When no session with the given `runId` exists.\n * @docLink packages/runner/session#set-current-session\n */\nexport async function setCurrentSession(projectDir: string, runId: string): Promise<void> {\n const exists = await loadSessionById(projectDir, runId);\n if (!exists) throw new Error(`Session not found: ${runId}`);\n await fs.mkdir(path.join(projectDir, SESSION_DIR), { recursive: true });\n await fs.writeFile(currentPointerPath(projectDir), runId, \"utf-8\");\n}\n\n/**\n * Delete a session file by run ID.\n *\n * If the deleted session was the current session, the `current` pointer\n * file is also removed. Missing session files are silently ignored.\n *\n * @param projectDir - Absolute path to the project directory.\n * @param runId - The UUID of the session to delete.\n * @docLink packages/runner/session#delete-session\n */\nexport async function deleteSession(projectDir: string, runId: string): Promise<void> {\n try {\n await fs.rm(sessionFilePath(projectDir, runId));\n } catch {\n /* ignore missing */\n }\n // Clear current pointer if it pointed to this session\n try {\n const current = (await fs.readFile(currentPointerPath(projectDir), \"utf-8\")).trim();\n if (current === runId) {\n await fs.rm(currentPointerPath(projectDir));\n }\n } catch {\n /* ignore */\n }\n}\n\n/**\n * Unset the current session pointer without deleting the session file.\n *\n * After calling this, {@link loadSession} returns `null` until a new\n * session is saved or {@link setCurrentSession} is called.\n *\n * @param projectDir - Absolute path to the project directory.\n * @docLink packages/runner/session#clear-session\n */\nexport async function clearSession(projectDir: string): Promise<void> {\n try {\n await fs.rm(currentPointerPath(projectDir));\n } catch {\n /* ignore missing */\n }\n}\n\n/**\n * Create a new {@link SessionState} with a fresh UUID and current timestamps.\n *\n * The returned session has `status: \"running\"` and both `startedAt` and\n * `updatedAt` set to the current ISO 8601 time. Caller is responsible for\n * persisting it via {@link saveSession}.\n *\n * @param opts - All session fields except `runId`, `startedAt`, `updatedAt`,\n * and `status` (which are generated automatically).\n * @returns A fully initialized session state ready to be saved.\n * @docLink packages/runner/session#new-session\n */\nexport function newSession(\n opts: Omit<SessionState, \"runId\" | \"startedAt\" | \"updatedAt\" | \"status\">,\n): SessionState {\n const now = new Date().toISOString();\n return { ...opts, runId: randomUUID(), startedAt: now, updatedAt: now, status: \"running\" };\n}\n\n/**\n * Update a session's `updatedAt` timestamp without changing any other field.\n * Used by callers that persist a session mid-run to refresh the staleness clock.\n *\n * @param state - Current session state\n * @returns New session state with updated timestamp\n * @docLink packages/runner/session#touch-session\n */\nexport function touchSession(state: SessionState): SessionState {\n return { ...state, updatedAt: new Date().toISOString() };\n}\n"]}
|