negotium 0.19.2 → 0.20.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.
Files changed (96) hide show
  1. package/dist/agent-helpers.js +1146 -212
  2. package/dist/agent-helpers.js.map +27 -19
  3. package/dist/background-bash.js.map +1 -1
  4. package/dist/browser-runtime.js.map +1 -1
  5. package/dist/{chunk-kkftbxh2.js → chunk-7he9nzfa.js} +1 -1
  6. package/dist/{chunk-55dd0xw7.js → chunk-ad6xqvqy.js} +2 -2
  7. package/dist/{chunk-55dd0xw7.js.map → chunk-ad6xqvqy.js.map} +2 -2
  8. package/dist/{chunk-exqz8bez.js → chunk-hh3f0yr7.js} +3 -3
  9. package/dist/{chunk-exqz8bez.js.map → chunk-hh3f0yr7.js.map} +2 -2
  10. package/dist/{chunk-aqqmzmft.js → chunk-nm59q3em.js} +1 -1
  11. package/dist/{chunk-cv7vdsrn.js → chunk-w3c6fc0p.js} +286 -9
  12. package/dist/{chunk-cv7vdsrn.js.map → chunk-w3c6fc0p.js.map} +10 -7
  13. package/dist/hosted-agent.js +290 -12
  14. package/dist/hosted-agent.js.map +10 -7
  15. package/dist/main.js +4599 -2724
  16. package/dist/main.js.map +49 -38
  17. package/dist/mcp-factories.js +1166 -162
  18. package/dist/mcp-factories.js.map +27 -19
  19. package/dist/media.js.map +1 -1
  20. package/dist/prompts.js.map +1 -1
  21. package/dist/query-runtime.js.map +3 -3
  22. package/dist/registry.js +3 -3
  23. package/dist/rollout.js +2 -2
  24. package/dist/runtime/src/agents/explicit-agent-switch.ts +101 -0
  25. package/dist/runtime/src/agents/mcp-tools/spawn-subagent.ts +126 -43
  26. package/dist/runtime/src/agents/public-helpers.ts +5 -0
  27. package/dist/runtime/src/agents/self-config-core.ts +28 -58
  28. package/dist/runtime/src/application/submit-runtime-gateway-turn.ts +34 -8
  29. package/dist/runtime/src/index.ts +75 -0
  30. package/dist/runtime/src/mcp/peer-bridge.ts +6 -1
  31. package/dist/runtime/src/mcp/runtime-spec.ts +145 -10
  32. package/dist/runtime/src/mcp/session-comm/actor-policy.ts +87 -0
  33. package/dist/runtime/src/mcp/session-comm/context.ts +42 -1
  34. package/dist/runtime/src/mcp/session-comm/default-host.ts +178 -2
  35. package/dist/runtime/src/mcp/session-comm/hub-remote-session.ts +553 -0
  36. package/dist/runtime/src/mcp/session-comm/limits.ts +8 -0
  37. package/dist/runtime/src/mcp/session-comm/peer-forward.ts +78 -3
  38. package/dist/runtime/src/mcp/session-comm/server.ts +167 -4
  39. package/dist/runtime/src/mcp/session-comm/topic-catalog.ts +7 -0
  40. package/dist/runtime/src/mcp/session-comm/topics.ts +32 -10
  41. package/dist/runtime/src/mcp-runtime-host.ts +2 -1
  42. package/dist/runtime/src/node-host.ts +26 -0
  43. package/dist/runtime/src/platform/mcp-config.ts +56 -2
  44. package/dist/runtime/src/query/active-rooms.ts +6 -0
  45. package/dist/runtime/src/runtime/actor-topic-reach.ts +85 -0
  46. package/dist/runtime/src/runtime/actor-topic-scope.ts +175 -0
  47. package/dist/runtime/src/runtime/ask-callbacks.ts +73 -20
  48. package/dist/runtime/src/runtime/gateway-capabilities.ts +22 -0
  49. package/dist/runtime/src/runtime/remote-session-grant.ts +221 -0
  50. package/dist/runtime/src/runtime/remote-session-inbox.ts +476 -0
  51. package/dist/runtime/src/runtime/remote-session-reply-outbox.ts +156 -0
  52. package/dist/runtime/src/runtime/turn-runner.ts +157 -33
  53. package/dist/runtime/src/runtime-gateway.ts +20 -0
  54. package/dist/runtime/src/storage/api-topics.ts +22 -3
  55. package/dist/runtime/src/storage/remote-session.ts +526 -0
  56. package/dist/runtime/src/storage/runtime-turn-requests.ts +75 -2
  57. package/dist/runtime/src/topics/derive.ts +3 -0
  58. package/dist/runtime/src/types/api.ts +6 -0
  59. package/dist/runtime/src/types.ts +42 -0
  60. package/dist/runtime/src/version.ts +1 -1
  61. package/dist/runtime-gateway.js.map +2 -2
  62. package/dist/runtime-helpers.js.map +1 -1
  63. package/dist/storage.js +16 -4
  64. package/dist/storage.js.map +4 -4
  65. package/dist/types/packages/core/src/agents/explicit-agent-switch.d.ts +26 -0
  66. package/dist/types/packages/core/src/agents/mcp-tools/spawn-subagent.d.ts +12 -2
  67. package/dist/types/packages/core/src/agents/public-helpers.d.ts +1 -0
  68. package/dist/types/packages/core/src/agents/self-config-core.d.ts +15 -1
  69. package/dist/types/packages/core/src/mcp/peer-bridge.d.ts +6 -1
  70. package/dist/types/packages/core/src/mcp/runtime-spec.d.ts +69 -2
  71. package/dist/types/packages/core/src/mcp/session-comm/context.d.ts +17 -1
  72. package/dist/types/packages/core/src/mcp/session-comm/hub-remote-session.d.ts +149 -0
  73. package/dist/types/packages/core/src/mcp/session-comm/limits.d.ts +8 -0
  74. package/dist/types/packages/core/src/mcp/session-comm/peer-forward.d.ts +23 -2
  75. package/dist/types/packages/core/src/mcp/session-comm/topic-catalog.d.ts +6 -0
  76. package/dist/types/packages/core/src/platform/mcp-config.d.ts +10 -1
  77. package/dist/types/packages/core/src/query/active-rooms.d.ts +6 -0
  78. package/dist/types/packages/core/src/runtime/actor-topic-reach.d.ts +49 -0
  79. package/dist/types/packages/core/src/runtime/actor-topic-scope.d.ts +91 -0
  80. package/dist/types/packages/core/src/runtime/ask-callbacks.d.ts +8 -2
  81. package/dist/types/packages/core/src/runtime/remote-session-grant.d.ts +91 -0
  82. package/dist/types/packages/core/src/runtime/remote-session-inbox.d.ts +83 -0
  83. package/dist/types/packages/core/src/runtime/remote-session-reply-outbox.d.ts +37 -0
  84. package/dist/types/packages/core/src/runtime/turn-runner.d.ts +22 -3
  85. package/dist/types/packages/core/src/runtime-gateway.d.ts +20 -0
  86. package/dist/types/packages/core/src/storage/api-topics.d.ts +3 -0
  87. package/dist/types/packages/core/src/storage/remote-session.d.ts +135 -0
  88. package/dist/types/packages/core/src/storage/runtime-turn-requests.d.ts +12 -1
  89. package/dist/types/packages/core/src/topics/derive.d.ts +2 -0
  90. package/dist/types/packages/core/src/types/api.d.ts +6 -0
  91. package/dist/types/packages/core/src/types.d.ts +40 -0
  92. package/dist/types/packages/core/src/version.d.ts +1 -1
  93. package/dist/vault.js.map +1 -1
  94. package/package.json +1 -1
  95. /package/dist/{chunk-kkftbxh2.js.map → chunk-7he9nzfa.js.map} +0 -0
  96. /package/dist/{chunk-aqqmzmft.js.map → chunk-nm59q3em.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../packages/core/src/agents/claude-provider.ts", "../../../packages/core/src/agents/rollout/shared.ts", "../../../packages/core/src/platform/paths.ts", "../../../packages/core/src/platform/jsonl.ts", "../../../packages/core/src/platform/file-utils.ts", "../../../packages/core/src/agents/claude-registry.ts", "../../../packages/core/src/agents/deep-map.ts", "../../../packages/core/src/agents/execution-host.ts", "../../../packages/core/src/security/sensitive-path.ts", "../../../packages/core/src/agents/vault-tool-policy.ts", "../../../packages/core/src/mcp/runtime-spec.ts", "../../../packages/core/src/mcp/session-comm/bridge-ipc-config.ts", "../../../packages/core/src/platform/background-bash/manager.ts", "../../../packages/core/src/platform/delay.ts", "../../../packages/core/src/platform/background-bash/context.ts", "../../../packages/core/src/platform/mcp-catalog-policy.ts", "../../../packages/core/src/platform/playwright/capability.ts", "../../../packages/core/src/platform/playwright/mcp-transport.ts", "../../../packages/core/src/runtime/cron-sessions.ts", "../../../packages/core/src/platform/constants.ts", "../../../packages/core/src/storage/storage-host.ts", "../../../packages/core/src/storage/sqlite.ts", "../../../packages/core/src/storage/forum-db.ts", "../../../packages/core/src/storage/api-topics.ts", "../../../packages/core/src/platform/mcp-config.ts", "../../../packages/core/src/storage/vault.ts", "../../../packages/core/src/storage/vault-crypto-core.ts", "../../../packages/core/src/storage/vault-crypto.ts", "../../../packages/core/src/media/file-events.ts", "../../../packages/core/src/platform/error.ts", "../../../packages/core/src/runtime/context-warning.ts", "../../../packages/core/src/agents/codex-provider.ts", "../../../packages/core/src/agents/codex-native-multi-agent.ts", "../../../packages/core/src/version.ts", "../../../packages/core/src/agents/codex-tree-kill.ts", "../../../packages/core/src/agents/codex-tree-manager.ts", "../../../packages/core/src/agents/codex-vault-hook-bridge.ts", "../../../packages/core/src/agents/codex-windows-wrapper.ts", "../../../packages/core/src/platform/ipc.ts", "../../../packages/core/src/agents/rollout/codex.ts", "../../../packages/core/src/agents/tool-format.ts", "../../../packages/core/src/platform/maestro-bootstrap-env.ts", "../../../packages/core/src/agents/maestro-provider.ts", "../../../packages/core/src/agents/claude-runtime-inspection.ts", "../../../packages/core/src/agents/hosted-agent.ts"],
3
+ "sources": ["../../../packages/core/src/agents/claude-provider.ts", "../../../packages/core/src/agents/rollout/shared.ts", "../../../packages/core/src/platform/paths.ts", "../../../packages/core/src/platform/jsonl.ts", "../../../packages/core/src/platform/file-utils.ts", "../../../packages/core/src/agents/claude-registry.ts", "../../../packages/core/src/agents/deep-map.ts", "../../../packages/core/src/agents/execution-host.ts", "../../../packages/core/src/security/sensitive-path.ts", "../../../packages/core/src/agents/vault-tool-policy.ts", "../../../packages/core/src/agents/explicit-agent-switch.ts", "../../../packages/core/src/mcp/runtime-spec.ts", "../../../packages/core/src/runtime/actor-topic-scope.ts", "../../../packages/core/src/runtime/remote-session-grant.ts", "../../../packages/core/src/mcp/session-comm/bridge-ipc-config.ts", "../../../packages/core/src/platform/background-bash/manager.ts", "../../../packages/core/src/platform/delay.ts", "../../../packages/core/src/platform/background-bash/context.ts", "../../../packages/core/src/platform/mcp-catalog-policy.ts", "../../../packages/core/src/platform/playwright/capability.ts", "../../../packages/core/src/platform/playwright/mcp-transport.ts", "../../../packages/core/src/runtime/cron-sessions.ts", "../../../packages/core/src/platform/constants.ts", "../../../packages/core/src/storage/storage-host.ts", "../../../packages/core/src/storage/sqlite.ts", "../../../packages/core/src/storage/forum-db.ts", "../../../packages/core/src/storage/api-topics.ts", "../../../packages/core/src/platform/mcp-config.ts", "../../../packages/core/src/storage/vault.ts", "../../../packages/core/src/storage/vault-crypto-core.ts", "../../../packages/core/src/storage/vault-crypto.ts", "../../../packages/core/src/media/file-events.ts", "../../../packages/core/src/platform/error.ts", "../../../packages/core/src/runtime/context-warning.ts", "../../../packages/core/src/agents/codex-provider.ts", "../../../packages/core/src/agents/codex-native-multi-agent.ts", "../../../packages/core/src/version.ts", "../../../packages/core/src/agents/codex-tree-kill.ts", "../../../packages/core/src/agents/codex-tree-manager.ts", "../../../packages/core/src/agents/codex-vault-hook-bridge.ts", "../../../packages/core/src/agents/codex-windows-wrapper.ts", "../../../packages/core/src/platform/ipc.ts", "../../../packages/core/src/agents/rollout/codex.ts", "../../../packages/core/src/agents/tool-format.ts", "../../../packages/core/src/platform/maestro-bootstrap-env.ts", "../../../packages/core/src/agents/maestro-provider.ts", "../../../packages/core/src/agents/claude-runtime-inspection.ts", "../../../packages/core/src/agents/hosted-agent.ts"],
4
4
  "sourcesContent": [
5
5
  "import { spawn } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport type {\n HookInput,\n Options,\n PostToolUseHookInput,\n PreToolUseHookInput,\n SDKAssistantMessage,\n SDKPartialAssistantMessage,\n SDKResultMessage,\n SDKSystemMessage,\n SDKToolProgressMessage,\n SDKToolUseSummaryMessage,\n SDKUserMessage,\n SDKUserMessageReplay,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport { query } from \"@anthropic-ai/claude-agent-sdk\";\nimport type {\n ContentBlockParam,\n ImageBlockParam,\n} from \"@anthropic-ai/sdk/resources/messages/messages.mjs\";\nimport { claudeRegistry } from \"#agents/claude-registry\";\nimport { deepMapStrings } from \"#agents/deep-map\";\nimport {\n hostedClaudeCodeExecutablePath,\n hostedMcpServers,\n redactHostedSecrets,\n referencesHostedSecretStorage,\n substituteHostedSecrets,\n} from \"#agents/execution-host\";\nimport { shouldSubstituteVaultToolInput } from \"#agents/vault-tool-policy\";\nimport { extractFileEvents } from \"#media/file-events\";\nimport { errMsg } from \"#platform/error\";\nimport { logger } from \"#platform/logger\";\nimport { claudeRequestContextTokens } from \"#runtime/context-warning\";\nimport type { AgentInputAttachment, AgentQueryOptions, EffortLevel, UnifiedEvent } from \"#types\";\n\nconst CLAUDE_DEFAULT_DISALLOWED_TOOLS = [\n \"AskUserQuestion\",\n \"Workflow\",\n \"TodoWrite\",\n \"TaskCreate\",\n \"TaskUpdate\",\n \"TaskList\",\n \"TaskGet\",\n // Monitor spawns a long-running background watcher tied to the CLI's own\n // interactive session/notification loop, which our headless spawned turns\n // don't have — it doesn't reliably deliver events back into a Negotium\n // topic. Use the background-bash MCP tools (run/watch) instead.\n \"Monitor\",\n // Native scheduling/cron tools duplicate Negotium's own runtime MCP surface\n // (`mcp__runtime__schedule_self`, the `cron-manager` server) and bypass its\n // persistence/host wiring if used directly.\n \"ScheduleWakeup\",\n \"CronCreate\",\n \"CronList\",\n \"CronDelete\",\n // Claude Code's cloud Routines surface is another scheduler. Keep scheduled\n // work in Negotium so it remains attached to the canonical topic and host.\n \"RemoteTrigger\",\n] as const;\n\nconst CLAUDE_NATIVE_AGENT_TOOLS = [\n \"Task\",\n \"Agent\",\n \"TaskOutput\",\n \"TaskStop\",\n // Claude Code 2.1.224 added cross-session discovery and messaging. Those\n // sessions do not share Negotium's topic identity, authorization, inbox, or\n // transcript, so allowing them alongside session-comm makes \"send/tell\"\n // ambiguous and can route messages outside the canonical runtime.\n \"ListAgents\",\n \"SendMessage\",\n // Older agent-team builds exposed explicit lifecycle tools. Keep the names\n // denied for compatibility even though current builds launch named\n // teammates through Agent.\n \"TeamCreate\",\n \"TeamDelete\",\n] as const;\n\nexport function claudeBuiltInTools(\n opts: Pick<AgentQueryOptions, \"toolPolicy\">,\n): string[] | undefined {\n return opts.toolPolicy ? [] : undefined;\n}\n\nexport function substituteClaudeToolInput(\n userId: string,\n toolName: string,\n input: unknown,\n): unknown {\n if (!shouldSubstituteVaultToolInput(toolName)) return input;\n return deepMapStrings(input, (value) => substituteHostedSecrets(userId, value));\n}\n\nexport function buildClaudeDisallowedTools(\n extra: readonly string[] | undefined = undefined,\n): string[] {\n return [\n ...new Set([\n ...CLAUDE_DEFAULT_DISALLOWED_TOOLS,\n ...CLAUDE_NATIVE_AGENT_TOOLS,\n ...(extra ?? []),\n ]),\n ];\n}\n\n/**\n * Narrow our shared `EffortLevel` to the subset claude-agent-sdk accepts.\n * Claude SDK rejects \"minimal\" (codex-only); we drop it silently rather than\n * coercing, matching our policy for unrecognized model strings.\n */\ntype ClaudeEffort = Exclude<EffortLevel, \"minimal\">;\nfunction toClaudeEffort(e: EffortLevel | undefined): ClaudeEffort | undefined {\n if (!e || !claudeRegistry.validateEffort(e)) return undefined;\n return e as ClaudeEffort;\n}\n\ntype ClaudeImageMimeType = \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\";\n\nconst CLAUDE_IMAGE_MAX_BYTES = 10 * 1024 * 1024;\nconst CLAUDE_IMAGE_MIME_TYPES = new Set<string>([\n \"image/jpeg\",\n \"image/png\",\n \"image/gif\",\n \"image/webp\",\n]);\n\nfunction isClaudeImageAttachment(\n attachment: AgentInputAttachment,\n): attachment is AgentInputAttachment & { mimeType: ClaudeImageMimeType } {\n return attachment.type === \"image\" && CLAUDE_IMAGE_MIME_TYPES.has(attachment.mimeType);\n}\n\nasync function* singleUserMessage(message: SDKUserMessage): AsyncGenerator<SDKUserMessage> {\n yield message;\n}\n\nfunction buildClaudePrompt(opts: AgentQueryOptions): string | AsyncIterable<SDKUserMessage> {\n const attachments = opts.attachments ?? [];\n if (attachments.length === 0) return opts.prompt;\n\n const imageBlocks: ImageBlockParam[] = [];\n for (const attachment of attachments) {\n if (!isClaudeImageAttachment(attachment)) continue;\n if (attachment.sizeBytes > CLAUDE_IMAGE_MAX_BYTES) {\n logger.info(\n {\n path: attachment.path,\n mimeType: attachment.mimeType,\n sizeBytes: attachment.sizeBytes,\n maxBytes: CLAUDE_IMAGE_MAX_BYTES,\n },\n \"claudeProvider: skipping oversized image attachment content block\",\n );\n continue;\n }\n\n try {\n imageBlocks.push({\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: attachment.mimeType,\n data: readFileSync(attachment.path).toString(\"base64\"),\n },\n });\n } catch (err) {\n logger.warn(\n {\n path: attachment.path,\n mimeType: attachment.mimeType,\n err,\n },\n \"claudeProvider: failed to read image attachment for content block\",\n );\n }\n }\n\n if (imageBlocks.length === 0) return opts.prompt;\n\n const content: ContentBlockParam[] = [{ type: \"text\", text: opts.prompt }, ...imageBlocks];\n return singleUserMessage({\n type: \"user\",\n message: {\n role: \"user\",\n content,\n },\n parent_tool_use_id: null,\n });\n}\n\n// --- Stream event sub-types (from @anthropic-ai/sdk, not directly importable) ---\ninterface ContentBlockDelta {\n type: \"content_block_delta\";\n delta: { type: string; partial_json?: string; text?: string };\n}\ntype StreamEvent = ContentBlockDelta | { type: string };\n\n// --- Assistant message content block types (from BetaMessage.content) ---\ninterface TextBlock {\n type: \"text\";\n text: string;\n}\ninterface ToolUseBlock {\n type: \"tool_use\";\n id: string;\n name: string;\n input: Record<string, unknown>;\n}\ninterface ToolResultBlock {\n type: \"tool_result\";\n tool_use_id: string;\n content: string | unknown;\n is_error?: boolean;\n}\ntype ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock | { type: string };\n\n// --- Process tree kill on abort ---\n//\n// The Claude Agent SDK spawns a `claude` CLI subprocess, which in turn spawns\n// MCP servers (playwright-mcp, background workers, …) which themselves spawn\n// browsers / interpreters. The SDK's default abort path only signals the\n// direct child, leaving grandchildren orphaned — over time they accumulate as\n// zombies, holding ports (Playwright DevTools 9222) and leaking memory\n// (Chrome ~hundreds of MB per orphan). Single-user Mac deployments notice\n// this within a day of repeated /abort.\n//\n// We override `spawnClaudeCodeProcess` to:\n// 1. spawn with `detached: true` → child becomes the leader of a new\n// process group with the same pgid as its pid;\n// 2. on abort, send the signal to `-pid` (the whole group) instead of the\n// single pid, so all transitive descendants receive it;\n// 3. escalate to SIGKILL after a 2.5s grace if SIGTERM didn't take.\n\ntype SpawnClaudeCodeProcess = NonNullable<Options[\"spawnClaudeCodeProcess\"]>;\ntype SpawnClaudeCodeOptions = Parameters<SpawnClaudeCodeProcess>[0];\ntype SpawnClaudeCodeResult = ReturnType<SpawnClaudeCodeProcess>;\n\nconst CLAUDE_ABORT_SIGKILL_DELAY_MS = 2500;\n\ntype ClaudeProcessExit = { code: number | null; signal: NodeJS.Signals | null };\n\n// The Agent SDK can keep its stdout reader open for several minutes after its\n// CLI child has gone away (CLAUDE_CODE_STREAM_CLOSE_TIMEOUT defaults to five\n// minutes in our host environment). Keep a per-query hook so the provider\n// can abort that stuck reader and emit a normal terminal error instead of\n// leaving the room lease occupied indefinitely.\nconst claudeProcessExitListeners = new WeakMap<\n AbortSignal,\n Set<(exit: ClaudeProcessExit) => void>\n>();\n\nfunction watchClaudeProcessExit(signal: AbortSignal): {\n exited: Promise<ClaudeProcessExit>;\n dispose: () => void;\n} {\n let listener: ((exit: ClaudeProcessExit) => void) | undefined;\n const exited = new Promise<ClaudeProcessExit>((resolve) => {\n listener = resolve;\n const listeners = claudeProcessExitListeners.get(signal) ?? new Set();\n listeners.add(listener);\n claudeProcessExitListeners.set(signal, listeners);\n });\n return {\n exited,\n dispose: () => {\n if (!listener) return;\n const listeners = claudeProcessExitListeners.get(signal);\n listeners?.delete(listener);\n if (listeners?.size === 0) claudeProcessExitListeners.delete(signal);\n listener = undefined;\n },\n };\n}\n\nfunction notifyClaudeProcessExit(signal: AbortSignal, exit: ClaudeProcessExit): void {\n const listeners = claudeProcessExitListeners.get(signal);\n if (!listeners) return;\n claudeProcessExitListeners.delete(signal);\n for (const listener of listeners) listener(exit);\n}\n\nfunction signalProcessTree(pid: number, signal: NodeJS.Signals): boolean {\n // Negative pid = \"signal every process in this process group\". Falls back\n // to single-pid signaling if the group call fails (e.g. on platforms where\n // `detached` didn't materialize a new group).\n try {\n process.kill(-pid, signal);\n return true;\n } catch (groupErr) {\n try {\n process.kill(pid, signal);\n return true;\n } catch (pidErr) {\n logger.debug({ groupErr, pidErr, pid, signal }, \"Failed to signal Claude process tree\");\n return false;\n }\n }\n}\n\nexport function spawnClaudeCodeProcessWithTreeKill(\n options: SpawnClaudeCodeOptions,\n): SpawnClaudeCodeResult {\n const child = spawn(options.command, options.args, {\n cwd: options.cwd,\n detached: true,\n env: options.env as NodeJS.ProcessEnv,\n stdio: [\"pipe\", \"pipe\", \"inherit\"],\n // Windows gives every console child its own window unless told otherwise,\n // so without this each turn blinks a black box over whatever the user is\n // looking at. Ignored on POSIX.\n windowsHide: true,\n });\n if (!child.stdin || !child.stdout) {\n child.kill(\"SIGKILL\");\n throw new Error(\"Failed to spawn Claude Code process with piped stdin/stdout\");\n }\n\n let exited = false;\n let killTimer: NodeJS.Timeout | undefined;\n const clearKillTimer = () => {\n if (killTimer) clearTimeout(killTimer);\n killTimer = undefined;\n };\n\n const kill = (signal: NodeJS.Signals): boolean => {\n if (!child.pid) return child.kill(signal);\n const ok = signalProcessTree(child.pid, signal);\n if (signal !== \"SIGKILL\") {\n // Soft signal: schedule a SIGKILL fallback so a stuck process tree\n // can't survive abort indefinitely.\n clearKillTimer();\n killTimer = setTimeout(() => {\n if (!exited && child.pid) {\n logger.warn({ pid: child.pid }, \"Claude process tree still alive after SIGTERM; SIGKILL\");\n signalProcessTree(child.pid, \"SIGKILL\");\n }\n }, CLAUDE_ABORT_SIGKILL_DELAY_MS);\n killTimer.unref?.();\n }\n return ok;\n };\n\n const onAbort = () => {\n logger.warn({ pid: child.pid, command: options.command }, \"Aborting Claude Code process tree\");\n kill(\"SIGTERM\");\n };\n\n if (options.signal.aborted) onAbort();\n else options.signal.addEventListener(\"abort\", onAbort, { once: true });\n\n child.once(\"exit\", (code, signal) => {\n exited = true;\n clearKillTimer();\n options.signal.removeEventListener(\"abort\", onAbort);\n logger.debug({ pid: child.pid, code, signal }, \"Claude Code process exited\");\n notifyClaudeProcessExit(options.signal, { code, signal });\n });\n\n // Consume the child's 'error' event. Without a listener, a spawn-level error\n // propagates into the SDK's readline-over-stdout teardown and crashes the\n // whole process with \"this.input.pause is not a function\" (node:readline\n // close→pause on a stream that never initialized). Handling it here keeps the\n // failure local and surfaces a clean diagnostic.\n child.once(\"error\", (err) => {\n exited = true;\n clearKillTimer();\n options.signal.removeEventListener(\"abort\", onAbort);\n logger.error(\n {\n pid: child.pid,\n command: options.command,\n err: err instanceof Error ? err.message : String(err),\n },\n \"Claude Code process error event\",\n );\n notifyClaudeProcessExit(options.signal, { code: null, signal: null });\n });\n\n return {\n stdin: child.stdin,\n stdout: child.stdout,\n get killed() {\n return child.killed || exited;\n },\n get exitCode() {\n return child.exitCode;\n },\n kill,\n on(event, listener) {\n child.on(event, listener);\n },\n once(event, listener) {\n child.once(event, listener);\n },\n off(event, listener) {\n child.off(event, listener);\n },\n };\n}\n\n/**\n * Recognize the multiple shapes Node + WHATWG fetch use when a request is\n * cancelled via `AbortController`. Mirrors `isAbortError` in maestro/provider\n * — both files keep their own copy so neither has to import the other (the\n * agent providers are deliberately siblings, no shared error helpers).\n */\nfunction isAbortError(err: unknown): boolean {\n if (!err || typeof err !== \"object\") return false;\n const e = err as { name?: unknown; code?: unknown };\n if (e.name === \"AbortError\") return true;\n if (e.code === 20 || e.code === \"ABORT_ERR\") return true;\n return false;\n}\n\n/**\n * Core Claude provider.\n * Wraps the @anthropic-ai/claude-agent-sdk into a UnifiedEvent stream so any\n * caller can consume it identically to other providers such as codexProvider.\n * The dispatch entry point is `runAgent` in agents/index.ts.\n *\n * Failure handling: any throw escaping the SDK iteration (missing Claude CLI\n * binary, OAuth not configured, transient network) is caught and yielded as\n * a `{type:\"error\"}` UnifiedEvent so the dispatcher never sees a synthetic\n * crash and event-processor's `error` case classifies it with the right\n * provider name. Matches the graceful pattern maestroProvider already uses.\n * Abort signals are swallowed silently (the user moved on) so they don't\n * surface as ghost error messages.\n */\nexport async function* claudeProvider(opts: AgentQueryOptions): AsyncGenerator<UnifiedEvent> {\n const claudeExecutable = hostedClaudeCodeExecutablePath();\n // The default host returns undefined so the Agent SDK selects its bundled,\n // version-matched Claude Code binary. If a host explicitly overrides the\n // executable, validate it up front and return an actionable error instead\n // of letting process spawn fail mid-stream with an opaque ENOENT.\n if (claudeExecutable && !existsSync(claudeExecutable)) {\n yield {\n type: \"error\",\n content: `Claude CLI not found at ${claudeExecutable}. Install Claude Code or configure the executable path.`,\n };\n return;\n }\n\n const cleanEnv = { ...process.env };\n delete cleanEnv.NEGOTIUM_PEER_SESSION_BRIDGE_URL;\n delete cleanEnv.NEGOTIUM_PEER_SESSION_BRIDGE_TOKEN;\n delete cleanEnv.CLAUDECODE;\n cleanEnv.CLAUDE_CODE_STREAM_CLOSE_TIMEOUT ??= \"300000\";\n // Workflow is a feature flag, not a disallowedTools-addressable tool name.\n // The env var is the version-robust kill switch (works on any CLI the SDK\n // spawns); the `settings` flag layer below covers it a second time.\n cleanEnv.CLAUDE_CODE_DISABLE_WORKFLOWS = \"1\";\n\n // Use a private signal for the SDK. A premature CLI exit must wake its\n // reader, but must not look like a user-initiated abort to the turn runner.\n const sdkAbortController = new AbortController();\n const onCallerAbort = () => sdkAbortController.abort();\n if (opts.abortController?.signal.aborted) sdkAbortController.abort();\n else opts.abortController?.signal.addEventListener(\"abort\", onCallerAbort, { once: true });\n const processExitWatch = watchClaudeProcessExit(sdkAbortController.signal);\n let unexpectedProcessExit: ClaudeProcessExit | undefined;\n void processExitWatch.exited.then((exit) => {\n // An exit caused by an explicit stop/supersede is expected. Its caller\n // signal is the authoritative distinction from a CLI crash.\n if (opts.abortController?.signal.aborted) return;\n unexpectedProcessExit = exit;\n sdkAbortController.abort();\n });\n\n const queryOptions: Options = {\n ...(claudeExecutable ? { pathToClaudeCodeExecutable: claudeExecutable } : {}),\n spawnClaudeCodeProcess: spawnClaudeCodeProcessWithTreeKill,\n cwd: opts.cwd,\n permissionMode: \"bypassPermissions\",\n allowDangerouslySkipPermissions: true,\n includePartialMessages: true,\n env: cleanEnv,\n mcpServers: hostedMcpServers(opts) as Options[\"mcpServers\"],\n ...(claudeBuiltInTools(opts) ? { tools: claudeBuiltInTools(opts) } : {}),\n abortController: sdkAbortController,\n // `AskUserQuestion` is Claude Code's built-in clarification tool, but it\n // expects the SDK CLI to render a TUI prompt and read stdin for the\n // answer — neither exists in this headless Telegram bridge. Without\n // disallowing it, the model would call AskUserQuestion, the SDK would\n // wait for a TUI response that never comes, and the turn would hang\n // until abort. Forbidding the tool nudges the model to ask the same\n // clarification as plain text (see topic-system prompt), which routes\n // through the normal next-user-message path and the user just answers\n // in the topic.\n //\n // Claude Code's private task store, Workflow, and native subagent tools are\n // not Negotium state. They stay disabled even when a caller supplies custom\n // agent definitions: delegation must go through runtime.spawn_subagent and\n // task state must go through the required shared task MCP.\n disallowedTools: buildClaudeDisallowedTools(opts.disallowedTools),\n ...(opts.model ? { model: opts.model } : {}),\n ...(opts.maxBudgetUsd ? { maxBudgetUsd: opts.maxBudgetUsd } : {}),\n ...(opts.agents\n ? {\n agents: Object.fromEntries(\n Object.entries(opts.agents).map(([name, def]) => {\n const { effort, ...rest } = def;\n const narrowed = typeof effort === \"string\" ? toClaudeEffort(effort) : effort;\n return [name, narrowed !== undefined ? { ...rest, effort: narrowed } : rest];\n }),\n ),\n }\n : {}),\n ...(toClaudeEffort(opts.effort) ? { effort: toClaudeEffort(opts.effort) } : {}),\n hooks: {\n PreToolUse: [\n {\n hooks: [\n async (input: HookInput) => {\n const { tool_name, tool_input } = input as PreToolUseHookInput;\n if (referencesHostedSecretStorage(tool_input)) {\n return {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\" as const,\n permissionDecision: \"deny\" as const,\n permissionDecisionReason: \"Runtime secret storage access is not permitted\",\n },\n };\n }\n\n // Block built-in run_in_background: the bash runs inside the CLI\n // subprocess and dies when the turn ends (SIGTERM on IPC close).\n // Direct the model to the MCP tool that survives across turns and\n // auto-injects a completion notification via session-inbox.\n if (\n tool_name === \"Bash\" &&\n (tool_input as Record<string, unknown>)?.run_in_background === true\n ) {\n return {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\" as const,\n permissionDecision: \"deny\" as const,\n permissionDecisionReason:\n \"run_in_background is not supported in headless mode — the bash process dies when the agent turn ends. Use mcp__background-bash__background_bash_run instead: it survives across turns and automatically injects the result into the session when done.\",\n },\n };\n }\n\n // Resolve Vault placeholders only for explicitly allowlisted\n // transient execution tools. Messaging and persistence tools\n // must retain {{KEY}} verbatim.\n const userId = opts.vaultUserId ?? opts.userId ?? \"\";\n const withVault = substituteClaudeToolInput(userId, tool_name, tool_input);\n if (JSON.stringify(withVault) === JSON.stringify(tool_input)) {\n return { continue: true };\n }\n return {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\" as const,\n updatedInput: withVault as Record<string, unknown>,\n },\n };\n },\n ],\n },\n ],\n PostToolUse: [\n {\n hooks: [\n async (input: HookInput) => {\n const { tool_response } = input as PostToolUseHookInput;\n const userId = opts.vaultUserId ?? opts.userId ?? \"\";\n const redacted = deepMapStrings(tool_response, (value) =>\n redactHostedSecrets(userId, value),\n );\n if (JSON.stringify(redacted) === JSON.stringify(tool_response)) {\n return { continue: true };\n }\n return {\n hookSpecificOutput: {\n hookEventName: \"PostToolUse\" as const,\n updatedToolOutput: redacted,\n },\n };\n },\n ],\n },\n ],\n },\n settingSources: [\"project\"] as Options[\"settingSources\"],\n // Disable the multi-agent Workflow feature: a headless backend query has\n // no business fanning out orchestration subagents, and the \"ultracode\"\n // keyword trigger would let user-authored message text opt into it.\n settings: {\n disableWorkflows: true,\n workflowKeywordTriggerEnabled: false,\n },\n systemPrompt: opts.systemPrompt,\n };\n\n if (opts.sessionId) {\n queryOptions.resume = opts.sessionId;\n }\n\n // Wrap the SDK iteration so init failures (missing claude CLI, OAuth not\n // configured, transient network errors before the first event) surface as\n // a normal error UnifiedEvent. Without this, an unconfigured Claude\n // install would crash the dispatcher with a synthetic exception and the\n // user-facing classifyError would still fire — but only via the handler\n // catch path, which means cleanup ordering differed from maestro/codex.\n // Keeping the failure shape consistent across providers simplifies the\n // upstream error code.\n // Thinking heartbeat: long extended-thinking stretches (minutes on fable /\n // high effort) emit no text or tool events, so the room UI goes silent and\n // the user can't tell whether the turn is still alive. The SDK does stream\n // thinking signals (`thinking_delta` content deltas, `system/thinking_tokens`\n // pings during redacted thinking) — digest them into a throttled\n // `tool_progress` heartbeat that the client already renders as a live status\n // chip (its handler also re-asserts the typing indicator).\n const THINKING_BEAT_MS = 5000;\n let thinkingStart: number | null = null;\n let lastThinkingBeat = 0;\n let lastContextTokens: number | undefined;\n let lastContextModel: string | undefined;\n const thinkingBeat = (): { type: \"tool_progress\"; toolName: string; elapsed: number } | null => {\n const now = Date.now();\n if (thinkingStart === null) {\n thinkingStart = now;\n lastThinkingBeat = now;\n return { type: \"tool_progress\", toolName: \"thinking\", elapsed: 0 };\n }\n if (now - lastThinkingBeat < THINKING_BEAT_MS) return null;\n lastThinkingBeat = now;\n return { type: \"tool_progress\", toolName: \"thinking\", elapsed: (now - thinkingStart) / 1000 };\n };\n\n try {\n const prompt = buildClaudePrompt(opts);\n for await (const message of query({\n prompt,\n options: queryOptions,\n })) {\n // --- Thinking heartbeat (see above) ---\n // A thinking \"stretch\" ends at the first non-thinking signal so elapsed\n // restarts cleanly on the next thinking phase within the same turn.\n if (\n message.type === \"system\" &&\n (message as { subtype?: string }).subtype === \"thinking_tokens\"\n ) {\n const beat = thinkingBeat();\n if (beat) yield beat;\n continue;\n }\n\n // --- Stream events (token-by-token) ---\n // tool_use is NOT emitted from the stream path: the completed assistant\n // message below carries the same block with its input already parsed,\n // and tools only start executing after the message completes — so the\n // stream copy added no timeliness, only a duplicate tool_use per turn\n // in the unified log (doubling `<!-- Tool: ... -->` comments when\n // bridging to another agent).\n if (message.type === \"stream_event\") {\n const streamMsg = message as SDKPartialAssistantMessage;\n const evt = (streamMsg as { event?: StreamEvent }).event;\n if (!evt) continue;\n\n if (evt.type === \"content_block_delta\") {\n const delta = evt as ContentBlockDelta;\n if (delta.delta.type === \"thinking_delta\") {\n const beat = thinkingBeat();\n if (beat) yield beat;\n } else if (delta.delta.type === \"text_delta\" && delta.delta.text) {\n // Claude only exposes tool_use blocks on the completed assistant\n // message below. Forwarding text deltas here would place all text\n // before those tools, making the original block order impossible\n // for consumers to reconstruct. The completed message emits text\n // and tool blocks in their canonical order.\n thinkingStart = null;\n } else {\n // Tool-args streaming (partial_json) etc. — thinking stretch over.\n thinkingStart = null;\n }\n }\n\n continue;\n }\n\n // Any completed message (assistant text, tool events, results) ends the\n // current thinking stretch.\n thinkingStart = null;\n\n // --- Tool progress ---\n if (message.type === \"tool_progress\") {\n const m = message as SDKToolProgressMessage;\n yield {\n type: \"tool_progress\",\n toolName: m.tool_name,\n elapsed: m.elapsed_time_seconds,\n };\n continue;\n }\n\n // --- Tool use summary ---\n if (message.type === \"tool_use_summary\") {\n const m = message as SDKToolUseSummaryMessage;\n yield { type: \"tool_use_summary\", summary: m.summary };\n continue;\n }\n\n // --- System init ---\n if (message.type === \"system\") {\n const m = message as SDKSystemMessage;\n if (m.subtype === \"init\") {\n yield { type: \"session\", sessionId: m.session_id };\n } else {\n // Log all other system messages (task_updated, task_progress,\n // task_notification, etc.) so we can observe lifecycle events.\n logger.debug(\n { subtype: m.subtype, msg: m },\n \"claudeProvider: system message (unhandled subtype)\",\n );\n }\n continue;\n }\n\n // --- Result (terminal) ---\n // SDK occasionally yields stray messages after a `result`; consuming them\n // surfaces as ghost messages in the topic (\"어? 뭐가 더 나오네?\"). Close\n // the generator immediately on terminal so the SDK stream is dropped and\n // any trailing payloads can't leak through.\n if (message.type === \"result\") {\n const m = message as SDKResultMessage;\n if (m.subtype === \"success\") {\n const contextWindow =\n (lastContextModel ? m.modelUsage?.[lastContextModel]?.contextWindow : undefined) ??\n Object.values(m.modelUsage ?? {})[0]?.contextWindow;\n yield {\n type: \"result\",\n content: m.result,\n stopReason: m.stop_reason ?? \"end_turn\",\n usage: m.usage\n ? {\n inputTokens: m.usage.input_tokens,\n outputTokens: m.usage.output_tokens,\n cacheCreationInputTokens: m.usage.cache_creation_input_tokens ?? undefined,\n cacheReadInputTokens: m.usage.cache_read_input_tokens ?? undefined,\n costUsd: m.total_cost_usd,\n ...(lastContextTokens !== undefined && contextWindow\n ? { contextTokens: lastContextTokens, contextWindow }\n : {}),\n }\n : undefined,\n };\n yield* extractFileEvents(m.result, \"result\");\n return;\n }\n // Error result\n const budgetExceeded = m.subtype === \"error_max_budget_usd\";\n const errorMsg = budgetExceeded\n ? \"The job reached its cost limit\"\n : m.errors?.join(\"; \") || \"Unknown error\";\n yield {\n type: \"error\",\n content: errorMsg,\n ...(budgetExceeded ? { code: \"budget_exceeded\" as const } : {}),\n ...(m.usage\n ? {\n usage: {\n inputTokens: m.usage.input_tokens,\n outputTokens: m.usage.output_tokens,\n cacheCreationInputTokens: m.usage.cache_creation_input_tokens ?? undefined,\n cacheReadInputTokens: m.usage.cache_read_input_tokens ?? undefined,\n costUsd: m.total_cost_usd,\n },\n }\n : {}),\n };\n return;\n }\n\n // --- Assistant message ---\n if (message.type === \"assistant\") {\n const m = message as SDKAssistantMessage;\n const content = (m.message?.content ?? []) as ContentBlock[];\n const usage = m.message?.usage;\n if (usage) {\n lastContextTokens = claudeRequestContextTokens(usage) ?? undefined;\n lastContextModel = m.message.model;\n }\n\n for (const block of content) {\n if (block.type === \"text\") {\n const textBlock = block as TextBlock;\n yield { type: \"text\", content: textBlock.text };\n // Surface mid-turn [FILE:/abs/path] tags right away, matching codex/\n // maestro providers — without this, a model that narrates a file\n // before its next tool call (rather than emitting the tag in the\n // final `result` text) wouldn't trigger send-file at all. The file\n // event handler dedups on normalized path so the same tag appearing\n // again in `result` won't double-send.\n yield* extractFileEvents(textBlock.text, \"text\");\n } else if (block.type === \"tool_use\") {\n const tb = block as ToolUseBlock;\n yield {\n type: \"tool_use\",\n name: tb.name,\n input: tb.input || {},\n toolUseId: tb.id,\n };\n }\n }\n continue;\n }\n\n // --- User message (tool results ride on user-role messages) ---\n // The Anthropic message protocol puts tool_result blocks in USER\n // messages, never assistant ones — without this branch the unified log\n // records tool calls but no results, losing information codex topics\n // keep (visible when bridging a claude topic to another agent).\n if (message.type === \"user\") {\n const um = message as SDKUserMessage | SDKUserMessageReplay;\n // Replays re-deliver transcript history on resume; mapping them would\n // duplicate every past tool_result into the unified log.\n if (\"isReplay\" in um && um.isReplay) continue;\n const content = um.message?.content;\n if (!Array.isArray(content)) continue;\n for (const block of content as ContentBlock[]) {\n if (block.type !== \"tool_result\") continue;\n const trBlock = block as ToolResultBlock;\n const trContent =\n typeof trBlock.content === \"string\" ? trBlock.content.slice(0, 200) : \"\";\n yield {\n type: \"tool_result\",\n toolUseId: trBlock.tool_use_id || \"\",\n content: trContent,\n ...(trBlock.is_error ? { isError: true } : {}),\n };\n }\n }\n }\n if (unexpectedProcessExit) {\n const detail = unexpectedProcessExit.signal\n ? `signal ${unexpectedProcessExit.signal}`\n : unexpectedProcessExit.code === null\n ? \"before it could start\"\n : `exit code ${unexpectedProcessExit.code}`;\n logger.error({ detail }, \"claudeProvider: CLI exited before terminal SDK event\");\n yield { type: \"error\", content: `Claude CLI exited unexpectedly (${detail}).` };\n }\n } catch (e) {\n // Abort = user moved on; don't surface as an error message. The handler\n // catches the abort signal separately via abortReason, so swallowing\n // here matches both maestro and codex behavior.\n if (unexpectedProcessExit) {\n const detail = unexpectedProcessExit.signal\n ? `signal ${unexpectedProcessExit.signal}`\n : unexpectedProcessExit.code === null\n ? \"before it could start\"\n : `exit code ${unexpectedProcessExit.code}`;\n logger.error({ err: e, detail }, \"claudeProvider: CLI exited before terminal SDK event\");\n yield { type: \"error\", content: `Claude CLI exited unexpectedly (${detail}).` };\n return;\n }\n if (isAbortError(e) || opts.abortController?.signal.aborted) return;\n logger.error({ err: e }, \"claudeProvider: SDK iteration failed\");\n yield { type: \"error\", content: errMsg(e) };\n } finally {\n processExitWatch.dispose();\n opts.abortController?.signal.removeEventListener(\"abort\", onCallerAbort);\n }\n}\n",
6
6
  "/**\n * Helpers shared by every agent's rollout encoder.\n *\n * Each rollout file under `agents/rollout/<agent>.ts` materializes a\n * synthetic SDK-native JSONL from a provider-agnostic `ConversationEntry`\n * stream. The cwd validation, UUID shape check, and chat-pair extraction\n * are identical regardless of agent, so they live here.\n */\n\nimport { mkdirSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport {\n DM_WORKSPACE_DIR,\n PROJECT_ROOT,\n SESSION_WORKSPACE_DIR,\n TOPIC_WORKSPACE_DIR,\n WORKSPACE_DIR,\n} from \"#platform/config\";\nimport { logger } from \"#platform/logger\";\nimport { isInsideDir } from \"#platform/paths\";\nimport { renderUserPromptBatch } from \"#runtime/user-turn-envelope\";\nimport type { ConversationEntry } from \"#storage/conversations\";\nimport type { UnifiedEvent } from \"#types\";\n\nexport interface RolloutHostOptions {\n /** Absolute workspace roots under which synthetic provider sessions may be written. */\n workspaceRoots?: readonly string[];\n /** Directory containing the provider rollout fixture JSONL files. */\n fixturesDir?: string;\n}\n\nlet trustedWorkspaceRoots = [\n WORKSPACE_DIR,\n DM_WORKSPACE_DIR,\n SESSION_WORKSPACE_DIR,\n TOPIC_WORKSPACE_DIR,\n].map((root) => resolve(root));\n\n/** Configure the embedding host's trusted workspace roots. */\nexport function configureRolloutHost(options: RolloutHostOptions): () => void {\n if (!options.workspaceRoots && !options.fixturesDir) {\n throw new Error(\"configureRolloutHost requires workspaceRoots or fixturesDir\");\n }\n if (options.workspaceRoots?.length === 0) {\n throw new Error(\"configureRolloutHost requires at least one workspace root\");\n }\n const previousRoots = trustedWorkspaceRoots;\n const previousFixturesDir = FIXTURES_DIR;\n if (options.workspaceRoots) {\n trustedWorkspaceRoots = options.workspaceRoots.map((root) => resolve(root));\n }\n if (options.fixturesDir) FIXTURES_DIR = resolve(options.fixturesDir);\n let disposed = false;\n return () => {\n if (disposed) return;\n disposed = true;\n trustedWorkspaceRoots = previousRoots;\n FIXTURES_DIR = previousFixturesDir;\n };\n}\n\n/**\n * Captured fixture snapshots — `claude-attachments.jsonl`, `codex-shell.jsonl`,\n * etc. — live one level above the per-agent rollout files (under\n * `agents/fixtures/`) so each agent can pull from the same directory without\n * duplicating fixtures.\n *\n * To refresh fixtures: run any live Codex/Claude session, copy the first few\n * non-conversational entries from the resulting rollout file, and update\n * `src/agents/fixtures/{codex-shell,claude-attachments}.jsonl`.\n */\nexport let FIXTURES_DIR = resolve(PROJECT_ROOT, \"src\", \"agents\", \"fixtures\");\n\n/** Deep-clone to avoid mutating cached fixture objects. */\nexport function clone<T>(obj: T): T {\n return structuredClone(obj);\n}\n\n/**\n * UUID v4/v7 shape — both 36 chars with the standard 8-4-4-4-12 hex layout.\n * We do not enforce the version nibble because randomUUID (v4) and uuidv7\n * coexist; the only requirement for our caller is that the value is safe to\n * embed in a path component and that the SDK accepts it as a session/thread\n * identifier.\n */\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nexport function assertUuidLike(label: string, value: string): void {\n if (!UUID_RE.test(value)) {\n throw new Error(`rollout: ${label} is not a UUID-shaped string: ${value}`);\n }\n}\n\n/**\n * Reject cwds that escape Otium-managed workspace roots. We use `path.resolve`\n * to normalize `..` traversal; symlink-based escapes are out of scope (the\n * workspace roots are not expected to contain attacker-controlled symlinks).\n */\nfunction assertCwdInWorkspace(cwd: string): void {\n const abs = resolve(cwd);\n // Synthetic rollouts for spawn/fork must be written under the same root as\n // live topic turns or provider resume looks in a different cwd hash than the\n // one we generated.\n const ok = trustedWorkspaceRoots.some((root) => isInsideDir(abs, root));\n if (!ok) {\n throw new Error(`rollout: cwd outside trusted workspace roots: ${cwd} (resolved=${abs})`);\n }\n}\n\n/** Best-effort guarantee that the resumed cwd will exist when the SDK stats it. */\nexport function ensureCwdExists(cwd: string): void {\n assertCwdInWorkspace(cwd);\n try {\n mkdirSync(cwd, { recursive: true });\n } catch (err) {\n logger.warn({ err, cwd }, \"rollout: ensureCwdExists failed — caller should pre-create cwd\");\n }\n}\n\n/**\n * Length-bound a string by Unicode code points rather than UTF-16 units, so a\n * truncation never lands in the middle of a multi-byte sequence and produces\n * a malformed character. Used for in-line tool annotations where we only need\n * a rough preview, not the full payload.\n */\nfunction truncate(text: string, n: number): string {\n const cps = Array.from(text);\n return cps.length > n ? `${cps.slice(0, n).join(\"\")}…` : text;\n}\n\n/**\n * Reduce a UnifiedEvent stream to user/assistant message pairs. Tool calls and\n * tool results are inlined as bracketed annotations on the surrounding\n * assistant turn so the historical narrative is preserved when synthesizing a\n * native rollout for a different SDK. Streaming text deltas are folded into\n * their final consolidated `text` event to avoid double-counting partial\n * tokens.\n */\nexport type ChatPair = { userText: string; assistantText: string };\n\nexport interface ExtractOptions {\n includeToolAnnotations: boolean;\n formatToolUse?: (event: Extract<UnifiedEvent, { type: \"tool_use\" }>) => string;\n formatToolResult?: (event: Extract<UnifiedEvent, { type: \"tool_result\" }>) => string;\n}\n\nexport function extractChatPairs(\n entries: ConversationEntry[],\n opts: ExtractOptions = { includeToolAnnotations: true },\n): ChatPair[] {\n const pairs: ChatPair[] = [];\n let pendingUsers: string[] = [];\n let pendingBatchSize: number | null = null;\n let pendingBatchNextIndex = 0;\n let pendingAssistantParts: string[] = [];\n let toolBuffer: string[] = [];\n\n const flushAssistant = () => {\n if (pendingUsers.length === 0) return;\n const tools =\n opts.includeToolAnnotations && toolBuffer.length > 0 ? `\\n\\n${toolBuffer.join(\"\\n\")}` : \"\";\n const assistantText = pendingAssistantParts.join(\"\").trim() + tools;\n if (assistantText.trim()) {\n pairs.push({ userText: renderUserPromptBatch(pendingUsers), assistantText });\n }\n pendingUsers = [];\n pendingBatchSize = null;\n pendingBatchNextIndex = 0;\n pendingAssistantParts = [];\n toolBuffer = [];\n };\n\n for (const entry of entries) {\n const ev = entry.event;\n switch (ev.type) {\n case \"user_message\": {\n const userEvent = ev as {\n content: string;\n consecutiveBatchSize?: number;\n consecutiveBatchIndex?: number;\n };\n if (pendingAssistantParts.length > 0 || toolBuffer.length > 0) {\n flushAssistant();\n }\n const batchSize = userEvent.consecutiveBatchSize;\n const batchIndex = userEvent.consecutiveBatchIndex;\n const marked =\n Number.isInteger(batchSize) &&\n Number.isInteger(batchIndex) &&\n (batchSize ?? 0) > 1 &&\n (batchIndex ?? -1) >= 0 &&\n (batchIndex ?? 0) < (batchSize ?? 0);\n if (!marked) {\n if (pendingUsers.length > 0) flushAssistant();\n pendingUsers.push(userEvent.content);\n pendingBatchSize = null;\n pendingBatchNextIndex = 0;\n break;\n }\n if (batchIndex === 0) {\n if (pendingUsers.length > 0) flushAssistant();\n pendingBatchSize = batchSize ?? null;\n pendingBatchNextIndex = 0;\n } else if (\n !(\n (pendingBatchSize !== null &&\n (batchSize ?? 0) >= pendingBatchSize &&\n pendingBatchNextIndex === batchIndex) ||\n (pendingBatchSize === null && pendingUsers.length === batchIndex)\n )\n ) {\n flushAssistant();\n }\n pendingUsers.push(userEvent.content);\n pendingBatchSize = batchSize ?? null;\n pendingBatchNextIndex = (batchIndex ?? 0) + 1;\n break;\n }\n case \"session\":\n // Session-id metadata. Provider sessions can change mid-conversation\n // (e.g. agent flip after rollout reconstruction), but the SDK normally\n // emits this *during* a turn — after the user prompt was already\n // recorded, before the assistant text arrives. Only flush when there\n // is actual assistant content in flight; otherwise we'd discard the\n // staged user prompt and the next text event would synthesize a bogus\n // \"(continued)\" pair.\n if (pendingAssistantParts.length > 0 || toolBuffer.length > 0) {\n flushAssistant();\n }\n break;\n case \"text\": {\n // Per-block assistant text. claudeProvider emits one of these per text\n // content block, so a single turn can yield multiple `text` events\n // interleaved with tool_use. Accumulate (do NOT flush yet) — the\n // turn's `result` event below carries the final concatenation and\n // is the proper boundary.\n if (pendingUsers.length === 0) {\n pendingUsers = [\"(continued)\"];\n }\n pendingAssistantParts.push((ev as { content: string }).content);\n break;\n }\n case \"result\": {\n // End-of-turn marker. `result.content` is the canonical final answer\n // produced by the provider, so prefer it over the accumulated `text`\n // chunks (which may be partial or out of order across SDKs).\n if (pendingUsers.length === 0) {\n pendingUsers = [\"(continued)\"];\n }\n pendingAssistantParts = [(ev as { content: string }).content];\n flushAssistant();\n break;\n }\n case \"text_delta\":\n // Skip — final `text`/`result` event carries the complete content.\n break;\n case \"tool_use\": {\n const u = ev as Extract<UnifiedEvent, { type: \"tool_use\" }>;\n toolBuffer.push(\n opts.formatToolUse?.(u) ??\n `<!-- Tool: ${u.name} ${truncate(JSON.stringify(u.input), 200)} -->`,\n );\n break;\n }\n case \"tool_result\": {\n const u = ev as Extract<UnifiedEvent, { type: \"tool_result\" }>;\n toolBuffer.push(\n opts.formatToolResult?.(u) ?? `<!-- Tool result: ${truncate(u.content, 200)} -->`,\n );\n break;\n }\n case \"error\": {\n const u = ev as { content: string };\n toolBuffer.push(`[Error: ${truncate(u.content, 200)}]`);\n break;\n }\n // Other UnifiedEvent variants (`tool_progress`, `tool_use_summary`,\n // `file`, `text_delta` already handled above) carry no conversational\n // content, so they do not contribute to a chat pair. We intentionally\n // omit a default branch — the explicit user_message variant introduced\n // by the recorder makes the previous \"treat unrecognized as user\" hack\n // unnecessary, and adding new UnifiedEvent variants in the future\n // should require an explicit decision here, not silent inheritance.\n case \"tool_progress\":\n case \"tool_use_summary\":\n case \"file\":\n case \"status\":\n break;\n }\n }\n flushAssistant();\n return pairs;\n}\n",
@@ -12,7 +12,10 @@
12
12
  "import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { dirname } from \"node:path\";\nimport { referencesRuntimeSecretStorage as defaultReferencesRuntimeSecretStorage } from \"#agents/vault-tool-policy\";\nimport { CLAUDE_EXECUTABLE, codexAuthFilePath } from \"#platform/config\";\nimport { getMcpServersForQuery as defaultGetMcpServersForQuery } from \"#platform/mcp-config\";\nimport {\n redactVaultSecrets as defaultRedactVaultSecrets,\n vaultSubstituteDetailed as defaultVaultSubstituteDetailed,\n} from \"#storage/vault\";\nimport type { AgentQueryOptions } from \"#types\";\n\n/**\n * Host-owned services used by the provider execution layer.\n *\n * The default implementation preserves standalone Negotium behaviour. An\n * embedding host may replace these callbacks once during process bootstrap so\n * providers use that host's MCP catalog and device-local secret store without\n * importing any host-specific runtime code into Negotium.\n */\nexport interface AgentExecutionHost {\n getMcpServersForQuery(opts: AgentQueryOptions): Record<string, unknown>;\n redactVaultSecrets(userId: string, value: string): string;\n substituteVaultSecrets(userId: string, value: string): string;\n referencesRuntimeSecretStorage(value: unknown): boolean;\n claudeCodeExecutablePath(): string | undefined;\n codexAuthFilePath(): string;\n transformQueryOptions?(opts: AgentQueryOptions): AgentQueryOptions;\n}\n\nconst defaultHost: AgentExecutionHost = {\n getMcpServersForQuery: defaultGetMcpServersForQuery,\n redactVaultSecrets: defaultRedactVaultSecrets,\n substituteVaultSecrets: (userId, value) => defaultVaultSubstituteDetailed(userId, value).text,\n referencesRuntimeSecretStorage: defaultReferencesRuntimeSecretStorage,\n claudeCodeExecutablePath: () => CLAUDE_EXECUTABLE,\n codexAuthFilePath,\n};\n\nconst hostRegistrations: Array<{\n id: symbol;\n overrides: Partial<AgentExecutionHost>;\n}> = [];\n\nconst scopedHost = new AsyncLocalStorage<AgentExecutionHost>();\n\nfunction activeHost(): AgentExecutionHost {\n const scoped = scopedHost.getStore();\n if (scoped) return scoped;\n const host = { ...defaultHost };\n for (const registration of hostRegistrations) Object.assign(host, registration.overrides);\n return host;\n}\n\n/** Resolve call-local overrides against the currently configured process host. */\nexport function resolveAgentExecutionHost(\n overrides: Partial<AgentExecutionHost> = {},\n): AgentExecutionHost {\n return { ...activeHost(), ...overrides };\n}\n\n/** Run one async provider operation with an isolated call-local host. */\nexport function withAgentExecutionHost<T>(\n host: AgentExecutionHost,\n operation: () => Promise<T>,\n): Promise<T> {\n return scopedHost.run(host, operation);\n}\n\n/** Configure provider host services. Returns a disposer useful for tests. */\nexport function configureAgentExecutionHost(overrides: Partial<AgentExecutionHost>): () => void {\n const registration = { id: Symbol(\"agent-execution-host\"), overrides };\n hostRegistrations.push(registration);\n let disposed = false;\n return () => {\n if (disposed) return;\n disposed = true;\n const index = hostRegistrations.findIndex((entry) => entry.id === registration.id);\n if (index >= 0) hostRegistrations.splice(index, 1);\n };\n}\n\nexport function hostedMcpServers(opts: AgentQueryOptions): Record<string, unknown> {\n if (opts.toolPolicy === \"none\") return {};\n if (opts.toolPolicy === \"compaction-log\") {\n const compactLog = opts.mcpExtra?.compact_log;\n return compactLog ? { compact_log: compactLog } : {};\n }\n return activeHost().getMcpServersForQuery(opts);\n}\n\nexport function redactHostedSecrets(userId: string, value: string): string {\n return activeHost().redactVaultSecrets(userId, value);\n}\n\nexport function substituteHostedSecrets(userId: string, value: string): string {\n return activeHost().substituteVaultSecrets(userId, value);\n}\n\nexport function referencesHostedSecretStorage(value: unknown): boolean {\n return activeHost().referencesRuntimeSecretStorage(value);\n}\n\nexport function transformHostedQueryOptions(opts: AgentQueryOptions): AgentQueryOptions {\n return activeHost().transformQueryOptions?.(opts) ?? opts;\n}\n\nexport function hostedClaudeCodeExecutablePath(): string | undefined {\n return activeHost().claudeCodeExecutablePath();\n}\n\nexport function hostedCodexAuthFilePath(): string {\n return activeHost().codexAuthFilePath();\n}\n\n/** The one Codex state root used by auth, rollouts, native forks, and SDK resume. */\nexport function hostedCodexHomePath(): string {\n return dirname(hostedCodexAuthFilePath());\n}\n",
13
13
  "import { realpathSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { toDisplayPath } from \"#platform/paths\";\n\n// --- Sensitive path blacklist ---\n\nconst SENSITIVE_PATH_PATTERNS = [\n /\\/\\.env(\\.|$)/i,\n /\\/\\.ssh\\//i,\n /\\/\\.aws\\//i,\n /\\/\\.gnupg\\//i,\n /\\/\\.netrc$/i,\n /\\/\\.npmrc$/i,\n /\\/(id_rsa|id_ed25519|id_ecdsa|id_dsa)(\\.pub)?$/i,\n /\\.(pem|key|p12|pfx|cer|crt)$/i,\n /\\/Library\\/Keychains\\//i,\n // Runtime-owned stores and key material. Vault values are encrypted, but\n // exposing ciphertext or its master key to an agent defeats that boundary.\n /\\/vault\\.db(-wal|-shm|-journal)?$/i,\n /\\/vault-master-key$/i,\n /\\/runtime-mcp-secret$/i,\n /\\/sessions\\.db(-wal|-shm|-journal)?$/i,\n];\n\nexport function isSensitivePath(filePath: string): boolean {\n const normalized = resolve(filePath);\n // Every pattern above anchors on \"/\". `resolve` returns the host separator,\n // so on Windows each one silently stopped matching and the whole blacklist\n // became inert. Compare against a \"/\"-separated rendering instead; on POSIX\n // `toDisplayPath` is the identity, so matching there is unchanged.\n if (SENSITIVE_PATH_PATTERNS.some((p) => p.test(toDisplayPath(normalized)))) return true;\n try {\n const real = realpathSync(normalized);\n if (real !== normalized) {\n return SENSITIVE_PATH_PATTERNS.some((p) => p.test(toDisplayPath(real)));\n }\n } catch {\n // File doesn't exist — no symlink concern\n }\n return false;\n}\n",
14
14
  "import { isSensitivePath } from \"#security/sensitive-path\";\n\nconst SENSITIVE_RUNTIME_NAMES = [\n \"vault.db\",\n \"vault-master-key\",\n \"runtime-mcp-secret\",\n \"sessions.db\",\n] as const;\n\n// Direct substitution is deliberately default-deny. These provider-owned\n// execution tools consume credentials transiently; persistence and messaging\n// tools must keep placeholders unresolved.\nconst DIRECT_VAULT_EXECUTION_TOOLS = new Set([\"Bash\", \"WebFetch\"]);\n\nfunction leafToolName(toolName: string): string {\n const parts = toolName.split(\"__\");\n return parts.at(-1) ?? toolName;\n}\n\nexport function shouldSubstituteVaultToolInput(toolName: string): boolean {\n const leaf = leafToolName(toolName);\n return leaf.startsWith(\"browser_\") || DIRECT_VAULT_EXECUTION_TOOLS.has(leaf);\n}\n\nexport function referencesRuntimeSecretStorage(value: unknown): boolean {\n if (typeof value === \"string\") {\n const lower = value.toLowerCase();\n if (SENSITIVE_RUNTIME_NAMES.some((name) => lower.includes(name))) return true;\n return value.startsWith(\"/\") && isSensitivePath(value);\n }\n if (Array.isArray(value)) return value.some(referencesRuntimeSecretStorage);\n if (value && typeof value === \"object\") {\n return Object.values(value as Record<string, unknown>).some(referencesRuntimeSecretStorage);\n }\n return false;\n}\n",
15
- "/**\n * Runtime-MCP wiring shared between core (which injects the MCP into agent\n * sessions) and @negotium/mcp (which serves the endpoint).\n *\n * The runtime process exposes one HTTP MCP endpoint; every agent turn gets a\n * per-turn signed token carrying its full execution context, so the MCP layer\n * never trusts the agent to say who it is. Ported from otium runtime-api\n * `mcp/runtime-server.ts` (transport-agnostic parts only).\n */\n\nimport { createHash, createHmac, timingSafeEqual } from \"node:crypto\";\nimport { NEGOTIUM_PORT, RUNTIME_MCP_SECRET } from \"#platform/config\";\nimport { type AgentKind, isAgentKind, type PeerRuntimeBridgeContext } from \"#types\";\n\nexport const RUNTIME_MCP_KEY = \"runtime\";\n\nexport const RUNTIME_MCP_BASE_PATH = \"/mcp/runtime\";\nexport const HOSTED_MCP_SURFACES = [\n \"task\",\n \"decision\",\n \"token-stats\",\n \"system-health\",\n \"vault\",\n \"wiki\",\n \"skills\",\n \"session-comm\",\n \"agent-health\",\n] as const;\nexport type HostedMcpSurface = (typeof HOSTED_MCP_SURFACES)[number];\nconst TOKEN_TTL_MS = 4 * 60 * 60 * 1000;\nconst CLAUDE_MCP_TOOL_TIMEOUT_MS = 600_000;\n\nexport interface RuntimeMcpContext {\n /** Canonical principal authorized against this node's topic roster. */\n userId: string;\n /** Product-side human actor when it differs from the execution principal. */\n actorUserId?: string;\n topicId: string;\n topicTitle: string;\n queryId?: string;\n cwd: string;\n agent: AgentKind;\n model?: string;\n currentUserPrompt?: string;\n autoContinue?: boolean;\n /** Capability minted by the adapter. Visual tools are absent unless true. */\n visualTools?: boolean;\n /** Capability minted by the adapter. File-delivery tools are absent unless true. */\n fileDeliveryTools?: boolean;\n /**\n * Thread this turn is answering inside, when it is answering in one.\n *\n * The runtime MCP is built per turn from a signed token, so unlike the\n * session — which spans the whole topic — this context can carry a value\n * that changes from one turn to the next. That is what lets `thread_read`\n * default to \"the thread I am in\" with no argument.\n */\n threadRootId?: string;\n peerBridge?: PeerRuntimeBridgeContext;\n}\n\n/** Signed identity/capability context shared by hosted built-in MCP surfaces. */\nexport interface HostedMcpContext {\n userId: string;\n topicTitle: string;\n topicId?: string;\n queryId?: string;\n wikiTopicId?: string;\n subagentParentTopicId?: string;\n cwd: string;\n agent: AgentKind;\n model?: string;\n depth?: number;\n silent?: boolean;\n /**\n * Thread the calling turn is answering inside.\n *\n * Present on the hosted surface as well as the stdio one: `session-comm` is\n * served both ways, and the hosted path — the default — carries its context\n * in a signed per-turn token rather than in argv.\n */\n threadRootId?: string;\n peerBridge?: PeerRuntimeBridgeContext;\n}\n\ntype RuntimeTokenPayload = {\n v: 1;\n exp: number;\n ctx: RuntimeMcpContext;\n};\n\ntype HostedTokenPayload = {\n v: 2;\n exp: number;\n aud: HostedMcpSurface;\n ctx: HostedMcpContext;\n};\n\nlet runtimePort = NEGOTIUM_PORT;\n\n/** The runtime host calls this once it knows which port it actually bound. */\nexport function setRuntimeMcpPort(port: number): void {\n runtimePort = port;\n}\n\nexport function getRuntimeMcpPort(): number {\n return runtimePort;\n}\n\nfunction encodeTokenPart(value: unknown): string {\n return Buffer.from(JSON.stringify(value), \"utf-8\").toString(\"base64url\");\n}\n\nfunction decodeTokenPart(part: string): unknown {\n return JSON.parse(Buffer.from(part, \"base64url\").toString(\"utf-8\")) as unknown;\n}\n\nfunction signTokenPayload(payloadPart: string): string {\n return createHmac(\"sha256\", RUNTIME_MCP_SECRET).update(payloadPart).digest(\"base64url\");\n}\n\nfunction safeEqual(a: string, b: string): boolean {\n const aa = Buffer.from(a);\n const bb = Buffer.from(b);\n return aa.length === bb.length && timingSafeEqual(aa, bb);\n}\n\nfunction isRuntimeMcpContext(value: unknown): value is RuntimeMcpContext {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const ctx = value as Partial<RuntimeMcpContext>;\n return (\n typeof ctx.userId === \"string\" &&\n typeof ctx.topicId === \"string\" &&\n typeof ctx.topicTitle === \"string\" &&\n typeof ctx.cwd === \"string\" &&\n typeof ctx.agent === \"string\" &&\n isAgentKind(ctx.agent) &&\n (ctx.actorUserId === undefined || typeof ctx.actorUserId === \"string\") &&\n (ctx.queryId === undefined || typeof ctx.queryId === \"string\") &&\n (ctx.model === undefined || typeof ctx.model === \"string\") &&\n (ctx.currentUserPrompt === undefined || typeof ctx.currentUserPrompt === \"string\") &&\n (ctx.autoContinue === undefined || typeof ctx.autoContinue === \"boolean\") &&\n (ctx.visualTools === undefined || typeof ctx.visualTools === \"boolean\") &&\n (ctx.fileDeliveryTools === undefined || typeof ctx.fileDeliveryTools === \"boolean\") &&\n (ctx.peerBridge === undefined ||\n (typeof ctx.peerBridge.hubCellId === \"string\" &&\n typeof ctx.peerBridge.hostTopicId === \"string\" &&\n typeof ctx.peerBridge.hostQueryId === \"string\" &&\n typeof ctx.peerBridge.canSpawnSubagents === \"boolean\"))\n );\n}\n\nexport function isHostedMcpSurface(value: string): value is HostedMcpSurface {\n return (HOSTED_MCP_SURFACES as readonly string[]).includes(value);\n}\n\nfunction isHostedMcpContext(value: unknown): value is HostedMcpContext {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const ctx = value as Partial<HostedMcpContext>;\n return (\n typeof ctx.userId === \"string\" &&\n typeof ctx.topicTitle === \"string\" &&\n typeof ctx.cwd === \"string\" &&\n typeof ctx.agent === \"string\" &&\n isAgentKind(ctx.agent) &&\n (ctx.topicId === undefined || typeof ctx.topicId === \"string\") &&\n (ctx.queryId === undefined || typeof ctx.queryId === \"string\") &&\n (ctx.wikiTopicId === undefined || typeof ctx.wikiTopicId === \"string\") &&\n (ctx.subagentParentTopicId === undefined || typeof ctx.subagentParentTopicId === \"string\") &&\n (ctx.model === undefined || typeof ctx.model === \"string\") &&\n (ctx.depth === undefined || (Number.isInteger(ctx.depth) && ctx.depth >= 0)) &&\n (ctx.silent === undefined || typeof ctx.silent === \"boolean\") &&\n (ctx.peerBridge === undefined ||\n (typeof ctx.peerBridge.hubCellId === \"string\" &&\n typeof ctx.peerBridge.hostTopicId === \"string\" &&\n typeof ctx.peerBridge.hostQueryId === \"string\" &&\n typeof ctx.peerBridge.canSpawnSubagents === \"boolean\"))\n );\n}\n\nexport function issueRuntimeMcpToken(ctx: RuntimeMcpContext): string {\n const payloadPart = encodeTokenPart({\n v: 1,\n exp: Date.now() + TOKEN_TTL_MS,\n ctx,\n } satisfies RuntimeTokenPayload);\n return `${payloadPart}.${signTokenPayload(payloadPart)}`;\n}\n\nexport function resolveRuntimeMcpToken(token: string | null): RuntimeMcpContext | null {\n if (!token) return null;\n const [payloadPart, signature, extra] = token.split(\".\");\n if (!payloadPart || !signature || extra !== undefined) return null;\n if (!safeEqual(signature, signTokenPayload(payloadPart))) return null;\n\n try {\n const payload = decodeTokenPart(payloadPart) as Partial<RuntimeTokenPayload>;\n if (payload.v !== 1 || typeof payload.exp !== \"number\" || payload.exp <= Date.now())\n return null;\n if (!isRuntimeMcpContext(payload.ctx)) return null;\n return payload.ctx;\n } catch {\n return null;\n }\n}\n\nexport function issueHostedMcpToken(surface: HostedMcpSurface, ctx: HostedMcpContext): string {\n const payloadPart = encodeTokenPart({\n v: 2,\n exp: Date.now() + TOKEN_TTL_MS,\n aud: surface,\n ctx,\n } satisfies HostedTokenPayload);\n return `${payloadPart}.${signTokenPayload(payloadPart)}`;\n}\n\nexport function resolveHostedMcpToken(\n token: string | null,\n surface: HostedMcpSurface,\n): HostedMcpContext | null {\n if (!token) return null;\n const [payloadPart, signature, extra] = token.split(\".\");\n if (!payloadPart || !signature || extra !== undefined) return null;\n if (!safeEqual(signature, signTokenPayload(payloadPart))) return null;\n\n try {\n const payload = decodeTokenPart(payloadPart) as Partial<HostedTokenPayload>;\n if (\n payload.v !== 2 ||\n payload.aud !== surface ||\n typeof payload.exp !== \"number\" ||\n payload.exp <= Date.now()\n ) {\n return null;\n }\n return isHostedMcpContext(payload.ctx) ? payload.ctx : null;\n } catch {\n return null;\n }\n}\n\n/**\n * MCP server spec injected into an agent session's MCP config so the agent\n * connects back to this node's runtime endpoint with its per-turn token.\n */\nexport function buildRuntimeMcpSpec(\n agent: AgentKind,\n ctx: RuntimeMcpContext,\n): Record<string, unknown> {\n const token = issueRuntimeMcpToken(ctx);\n const base = `http://127.0.0.1:${runtimePort}${RUNTIME_MCP_BASE_PATH}`;\n const query = `token=${encodeURIComponent(token)}`;\n if (agent === \"codex\") return { url: `${base}/mcp?${query}` };\n return {\n type: \"sse\" as const,\n url: `${base}/sse?${query}`,\n timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS,\n ...(agent === \"maestro\" ? { lifecycle: \"turn\" as const } : {}),\n };\n}\n\nfunction hostedMcpCacheIdentity(surface: HostedMcpSurface, ctx: HostedMcpContext): string {\n let semanticContext: unknown;\n switch (surface) {\n case \"system-health\":\n semanticContext = {};\n break;\n case \"token-stats\":\n case \"agent-health\":\n semanticContext = { userId: ctx.userId };\n break;\n case \"task\":\n semanticContext = {\n userId: ctx.userId,\n topicTitle: ctx.topicTitle,\n topicId: ctx.topicId ?? null,\n };\n break;\n case \"wiki\":\n case \"skills\":\n semanticContext = {\n userId: ctx.userId,\n topicId: ctx.wikiTopicId ?? ctx.topicId ?? null,\n };\n break;\n case \"vault\":\n semanticContext = { userId: ctx.userId, cwd: ctx.cwd, agent: ctx.agent };\n break;\n case \"session-comm\":\n semanticContext = {\n userId: ctx.userId,\n topicTitle: ctx.topicTitle,\n topicId: ctx.topicId ?? null,\n subagentParentTopicId: ctx.subagentParentTopicId ?? null,\n depth: ctx.depth ?? 0,\n silent: ctx.silent ?? false,\n agent: ctx.agent,\n // Part of the identity, not a detail: a server cached for a channel\n // turn would otherwise be reused for a thread turn and record the ask\n // against the wrong conversation.\n threadRootId: ctx.threadRootId ?? null,\n peerBridge: ctx.peerBridge ?? null,\n };\n break;\n }\n const digest = createHash(\"sha256\")\n .update(JSON.stringify([surface, semanticContext]))\n .digest(\"hex\")\n .slice(0, 24);\n return `hosted:${surface}:${digest}`;\n}\n\n/** Build an agent transport spec for one logical MCP surface on the shared runtime process. */\nexport function buildHostedMcpSpec(\n agent: AgentKind,\n surface: HostedMcpSurface,\n ctx: HostedMcpContext,\n): Record<string, unknown> {\n const token = issueHostedMcpToken(surface, ctx);\n const base = `http://127.0.0.1:${runtimePort}${RUNTIME_MCP_BASE_PATH}/${surface}`;\n const query = `token=${encodeURIComponent(token)}`;\n if (agent === \"codex\") return { url: `${base}/mcp?${query}` };\n const queryBound =\n surface === \"session-comm\" && (ctx.silent === true || ctx.peerBridge !== undefined);\n const lifecycle = queryBound ? \"turn\" : surface === \"session-comm\" ? \"session\" : \"process\";\n return {\n type: \"sse\" as const,\n url: `${base}/sse?${query}`,\n timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS,\n ...(agent === \"maestro\"\n ? {\n lifecycle,\n cacheKey: hostedMcpCacheIdentity(surface, ctx),\n }\n : {}),\n };\n}\n",
15
+ "/**\n * The explicit-switch gate behind `set_agent`: an agent may move a topic to\n * another backend only when the *person's* current message asked for it.\n *\n * The decision is derived here, once, from the full prompt on the node that\n * mints the per-turn runtime MCP token, and the token then carries only the\n * result ({@link explicitAgentSwitchTargets}) — a bounded list of agent kinds\n * — instead of the prompt itself. That keeps the token small whatever the\n * prompt's length and means a long message cannot push the phrase past a\n * cap and turn a request the user made into a refusal.\n */\nimport { type AgentKind, SUPPORTED_AGENTS } from \"#types\";\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction agentAliases(agent: AgentKind): string[] {\n switch (agent) {\n case \"codex\":\n return [\n \"codex\",\n \"코덱스\",\n \"gpt-6-luna\",\n \"gpt-6-sol\",\n \"gpt-5.6-luna\",\n \"gpt-5.6-terra\",\n \"gpt-5.6-sol\",\n \"gpt-6-astra\",\n ];\n case \"claude\":\n return [\"claude\", \"클로드\", \"sonnet\", \"opus\", \"fable\"];\n case \"maestro\":\n return [\n \"maestro\",\n \"마에스트로\",\n \"메스트로\",\n \"deepseek\",\n \"deepseek-pro\",\n \"kimi\",\n \"kimi-pro\",\n \"kimi-k3\",\n \"kimi-code\",\n \"kimi-k2.7-code\",\n \"딥시크\",\n \"키미\",\n ];\n }\n}\n\n/** Whether `prompt` explicitly asks to switch this topic to `agent`. */\nexport function hasExplicitAgentSwitchRequest(\n prompt: string | undefined,\n agent: AgentKind,\n): boolean {\n if (!prompt?.trim()) return false;\n const text = prompt.toLowerCase().replace(/\\s+/g, \" \").trim();\n const target = `(?:${agentAliases(agent).map(escapeRegExp).join(\"|\")})`;\n const switchVerb =\n \"(?:바꿔|바꿔줘|변경|변경해|전환|전환해|설정|설정해|써줘|사용|가|switch|change|set|use)\";\n const switchSubject = \"(?:agent|runtime|model|에이전트|런타임|모델)\";\n\n return [\n new RegExp(`^/(?:agent|runtime)\\\\s+${target}(?:\\\\s|$)`, \"iu\"),\n new RegExp(`${target}\\\\s*(?:로|으로)\\\\s*.{0,16}${switchVerb}`, \"iu\"),\n new RegExp(`${switchSubject}.{0,24}${target}.{0,24}${switchVerb}`, \"iu\"),\n new RegExp(`${switchVerb}.{0,24}${switchSubject}.{0,24}${target}`, \"iu\"),\n new RegExp(`(?:switch|change|set|use).{0,24}${target}`, \"iu\"),\n ].some((pattern) => pattern.test(text));\n}\n\n/**\n * The agents `prompt` explicitly asks to switch to, in {@link SUPPORTED_AGENTS}\n * order — the same test as {@link hasExplicitAgentSwitchRequest}, evaluated for\n * every agent kind over the whole prompt. Empty when nothing was asked for.\n */\nexport function explicitAgentSwitchTargets(prompt: string | undefined): AgentKind[] {\n if (!prompt?.trim()) return [];\n return SUPPORTED_AGENTS.filter((agent) => hasExplicitAgentSwitchRequest(prompt, agent));\n}\n\n/**\n * Shape check for the derived field where it crosses a trust boundary (the\n * signed token): a de-duplicated list of known agent kinds. It cannot hold\n * more entries than there are agents, so its size is fixed.\n */\nexport function isExplicitAgentSwitchTargets(value: unknown): value is AgentKind[] {\n return (\n Array.isArray(value) &&\n value.length <= SUPPORTED_AGENTS.length &&\n value.every((item, index) => isAgentKindUnique(value, item, index))\n );\n}\n\nfunction isAgentKindUnique(list: unknown[], item: unknown, index: number): boolean {\n return (\n typeof item === \"string\" &&\n (SUPPORTED_AGENTS as readonly string[]).includes(item) &&\n list.indexOf(item) === index\n );\n}\n",
16
+ "/**\n * Runtime-MCP wiring shared between core (which injects the MCP into agent\n * sessions) and @negotium/mcp (which serves the endpoint).\n *\n * The runtime process exposes one HTTP MCP endpoint; every agent turn gets a\n * per-turn signed token carrying its full execution context, so the MCP layer\n * never trusts the agent to say who it is. Ported from otium runtime-api\n * `mcp/runtime-server.ts` (transport-agnostic parts only).\n */\n\nimport { createHash, createHmac, timingSafeEqual } from \"node:crypto\";\nimport { isExplicitAgentSwitchTargets } from \"#agents/explicit-agent-switch\";\nimport { NEGOTIUM_PORT, RUNTIME_MCP_SECRET } from \"#platform/config\";\nimport { logger } from \"#platform/logger\";\nimport { isActorTopicScope } from \"#runtime/actor-topic-scope\";\nimport { isRemoteSessionGrant } from \"#runtime/remote-session-grant\";\nimport {\n type ActorTopicScope,\n type AgentKind,\n isAgentKind,\n type PeerRuntimeBridgeContext,\n type RemoteSessionGrant,\n} from \"#types\";\n\nexport const RUNTIME_MCP_KEY = \"runtime\";\n\nexport const RUNTIME_MCP_BASE_PATH = \"/mcp/runtime\";\nexport const HOSTED_MCP_SURFACES = [\n \"task\",\n \"decision\",\n \"token-stats\",\n \"system-health\",\n \"vault\",\n \"wiki\",\n \"skills\",\n \"session-comm\",\n \"agent-health\",\n] as const;\nexport type HostedMcpSurface = (typeof HOSTED_MCP_SURFACES)[number];\nconst TOKEN_TTL_MS = 4 * 60 * 60 * 1000;\nconst CLAUDE_MCP_TOOL_TIMEOUT_MS = 600_000;\n\n/**\n * Hard ceiling on the length of a built-in MCP URL (path plus `?token=...`).\n *\n * The signed per-turn token rides the URL query of an `http://127.0.0.1`\n * request, and `Bun.serve` answers 431 once the request line is too long:\n * measured on Bun 1.3.14 with a plain `fetch`, a 16,205-character URL is\n * served (200) and a 16,305-character one is refused (431). The budget stays\n * 1,869 characters under the last known-good length so the server, the\n * agent's own client and a slightly different Bun release all have room.\n *\n * Real sizes (UUID ids, base64url growth of 4/3 on the JSON payload):\n * - runtime token, no assertion, every optional field set (peer bridge,\n * thread, 64-char title, workspace cwd, all three explicit-switch\n * targets): ~1,150-character URL;\n * - the same with the largest assertion `validateActorTopicScope` admits\n * (8,159 bytes of JSON = 208 UUIDs): 12,052–12,055 characters, under this\n * budget with ~2,280 characters to spare for an unusually long cwd or title;\n * the hosted tokens (`buildHostedMcpSpec`) with the same assertion measure\n * 12,100–12,118, so neither variant is the \"small\" one.\n * The token has no free-text field: the user's prompt never rides it. It used\n * to, and an uncapped prompt made the assertion cap meaningless (3,000 Korean\n * characters on top of the maximal assertion gave a 24,009-character URL and\n * 10,000 gave 52,009 — every built-in MCP unreachable for that turn), while a\n * capped one broke `set_agent` for any request phrased after the cap. The\n * prompt's only consumer was that gate, so the node now derives the gate's\n * answer from the full prompt when it mints the token\n * (`explicitAgentSwitchTargets`, at most three agent names) and signs that.\n *\n * Over budget, {@link buildRuntimeMcpSpec} throws\n * {@link McpUrlBudgetExceededError} rather than minting a URL that will 431.\n * Nothing is dropped or trimmed to fit: every remaining field either\n * authorizes (ids, assertion, switch targets) or changes behaviour (thread,\n * capabilities, bridge), and a token missing one would widen or alter the\n * turn, not narrow it.\n */\nexport const MCP_URL_BUDGET_CHARS = 14 * 1024;\n\nexport class McpUrlBudgetExceededError extends Error {\n constructor(\n readonly surface: string,\n readonly urlLength: number,\n ) {\n super(\n `built-in MCP URL for \"${surface}\" is ${urlLength} characters; the transport allows at most ${MCP_URL_BUDGET_CHARS}`,\n );\n this.name = \"McpUrlBudgetExceededError\";\n }\n}\n\nexport interface RuntimeMcpContext {\n /** Canonical principal authorized against this node's topic roster. */\n userId: string;\n /** Product-side human actor when it differs from the execution principal. */\n actorUserId?: string;\n /**\n * Hub-asserted rooms `actorUserId` may reach on this node. Signed with the\n * rest of the context and authoritative when present (no lineage is added);\n * absent means the tools reach only the current room plus its own subagent\n * lineage.\n */\n actorTopicScope?: ActorTopicScope;\n topicId: string;\n topicTitle: string;\n queryId?: string;\n cwd: string;\n agent: AgentKind;\n model?: string;\n /**\n * Agents the current user message explicitly asked to switch to, derived\n * from the full prompt at mint time (`explicitAgentSwitchTargets`). Signed\n * with the rest of the context, so the agent cannot grant itself a switch;\n * absent or empty means `set_agent` is refused this turn.\n */\n explicitAgentSwitchTargets?: AgentKind[];\n autoContinue?: boolean;\n /** Capability minted by the adapter. Visual tools are absent unless true. */\n visualTools?: boolean;\n /** Capability minted by the adapter. File-delivery tools are absent unless true. */\n fileDeliveryTools?: boolean;\n /**\n * Thread this turn is answering inside, when it is answering in one.\n *\n * The runtime MCP is built per turn from a signed token, so unlike the\n * session — which spans the whole topic — this context can carry a value\n * that changes from one turn to the next. That is what lets `thread_read`\n * default to \"the thread I am in\" with no argument.\n */\n threadRootId?: string;\n peerBridge?: PeerRuntimeBridgeContext;\n}\n\n/** Signed identity/capability context shared by hosted built-in MCP surfaces. */\nexport interface HostedMcpContext {\n userId: string;\n /** Product-side human actor when it differs from the execution principal. */\n actorUserId?: string;\n /** Hub-asserted rooms `actorUserId` may reach; see {@link RuntimeMcpContext}. */\n actorTopicScope?: ActorTopicScope;\n /**\n * Hub-issued per-turn authority for remote (`node/topic`) session-comm.\n * Carried by the `session-comm` audience only. Signed with the rest of the\n * context so the agent cannot mint or swap one; the capability inside is a\n * bearer for the hub, which the node cannot verify (it holds no key) and\n * only ever decodes for the untrusted `e` expiry it uses to order grants\n * when several requests fold into one turn.\n */\n remoteSession?: RemoteSessionGrant;\n topicTitle: string;\n topicId?: string;\n queryId?: string;\n wikiTopicId?: string;\n subagentParentTopicId?: string;\n cwd: string;\n agent: AgentKind;\n model?: string;\n depth?: number;\n silent?: boolean;\n /**\n * Thread the calling turn is answering inside.\n *\n * Present on the hosted surface as well as the stdio one: `session-comm` is\n * served both ways, and the hosted path — the default — carries its context\n * in a signed per-turn token rather than in argv.\n */\n threadRootId?: string;\n peerBridge?: PeerRuntimeBridgeContext;\n}\n\ntype RuntimeTokenPayload = {\n v: 1;\n exp: number;\n ctx: RuntimeMcpContext;\n};\n\ntype HostedTokenPayload = {\n v: 2;\n exp: number;\n aud: HostedMcpSurface;\n ctx: HostedMcpContext;\n};\n\nlet runtimePort = NEGOTIUM_PORT;\n\n/** The runtime host calls this once it knows which port it actually bound. */\nexport function setRuntimeMcpPort(port: number): void {\n runtimePort = port;\n}\n\nexport function getRuntimeMcpPort(): number {\n return runtimePort;\n}\n\nfunction encodeTokenPart(value: unknown): string {\n return Buffer.from(JSON.stringify(value), \"utf-8\").toString(\"base64url\");\n}\n\nfunction decodeTokenPart(part: string): unknown {\n return JSON.parse(Buffer.from(part, \"base64url\").toString(\"utf-8\")) as unknown;\n}\n\nfunction signTokenPayload(payloadPart: string): string {\n return createHmac(\"sha256\", RUNTIME_MCP_SECRET).update(payloadPart).digest(\"base64url\");\n}\n\nfunction safeEqual(a: string, b: string): boolean {\n const aa = Buffer.from(a);\n const bb = Buffer.from(b);\n return aa.length === bb.length && timingSafeEqual(aa, bb);\n}\n\nfunction isRuntimeMcpContext(value: unknown): value is RuntimeMcpContext {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const ctx = value as Partial<RuntimeMcpContext>;\n return (\n typeof ctx.userId === \"string\" &&\n typeof ctx.topicId === \"string\" &&\n typeof ctx.topicTitle === \"string\" &&\n typeof ctx.cwd === \"string\" &&\n typeof ctx.agent === \"string\" &&\n isAgentKind(ctx.agent) &&\n (ctx.actorUserId === undefined || typeof ctx.actorUserId === \"string\") &&\n (ctx.actorTopicScope === undefined || isActorTopicScope(ctx.actorTopicScope)) &&\n (ctx.queryId === undefined || typeof ctx.queryId === \"string\") &&\n (ctx.model === undefined || typeof ctx.model === \"string\") &&\n (ctx.explicitAgentSwitchTargets === undefined ||\n isExplicitAgentSwitchTargets(ctx.explicitAgentSwitchTargets)) &&\n (ctx.autoContinue === undefined || typeof ctx.autoContinue === \"boolean\") &&\n (ctx.visualTools === undefined || typeof ctx.visualTools === \"boolean\") &&\n (ctx.fileDeliveryTools === undefined || typeof ctx.fileDeliveryTools === \"boolean\") &&\n (ctx.peerBridge === undefined ||\n (typeof ctx.peerBridge.hubCellId === \"string\" &&\n typeof ctx.peerBridge.hostTopicId === \"string\" &&\n typeof ctx.peerBridge.hostQueryId === \"string\" &&\n typeof ctx.peerBridge.canSpawnSubagents === \"boolean\"))\n );\n}\n\nexport function isHostedMcpSurface(value: string): value is HostedMcpSurface {\n return (HOSTED_MCP_SURFACES as readonly string[]).includes(value);\n}\n\nfunction isHostedMcpContext(value: unknown): value is HostedMcpContext {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const ctx = value as Partial<HostedMcpContext>;\n return (\n typeof ctx.userId === \"string\" &&\n typeof ctx.topicTitle === \"string\" &&\n typeof ctx.cwd === \"string\" &&\n typeof ctx.agent === \"string\" &&\n isAgentKind(ctx.agent) &&\n (ctx.actorUserId === undefined || typeof ctx.actorUserId === \"string\") &&\n (ctx.actorTopicScope === undefined || isActorTopicScope(ctx.actorTopicScope)) &&\n (ctx.remoteSession === undefined || isRemoteSessionGrant(ctx.remoteSession)) &&\n (ctx.topicId === undefined || typeof ctx.topicId === \"string\") &&\n (ctx.queryId === undefined || typeof ctx.queryId === \"string\") &&\n (ctx.wikiTopicId === undefined || typeof ctx.wikiTopicId === \"string\") &&\n (ctx.subagentParentTopicId === undefined || typeof ctx.subagentParentTopicId === \"string\") &&\n (ctx.model === undefined || typeof ctx.model === \"string\") &&\n (ctx.depth === undefined || (Number.isInteger(ctx.depth) && ctx.depth >= 0)) &&\n (ctx.silent === undefined || typeof ctx.silent === \"boolean\") &&\n (ctx.peerBridge === undefined ||\n (typeof ctx.peerBridge.hubCellId === \"string\" &&\n typeof ctx.peerBridge.hostTopicId === \"string\" &&\n typeof ctx.peerBridge.hostQueryId === \"string\" &&\n typeof ctx.peerBridge.canSpawnSubagents === \"boolean\"))\n );\n}\n\nexport function issueRuntimeMcpToken(ctx: RuntimeMcpContext): string {\n const payloadPart = encodeTokenPart({\n v: 1,\n exp: Date.now() + TOKEN_TTL_MS,\n ctx,\n } satisfies RuntimeTokenPayload);\n return `${payloadPart}.${signTokenPayload(payloadPart)}`;\n}\n\nexport function resolveRuntimeMcpToken(token: string | null): RuntimeMcpContext | null {\n if (!token) return null;\n const [payloadPart, signature, extra] = token.split(\".\");\n if (!payloadPart || !signature || extra !== undefined) return null;\n if (!safeEqual(signature, signTokenPayload(payloadPart))) return null;\n\n try {\n const payload = decodeTokenPart(payloadPart) as Partial<RuntimeTokenPayload>;\n if (payload.v !== 1 || typeof payload.exp !== \"number\" || payload.exp <= Date.now())\n return null;\n if (!isRuntimeMcpContext(payload.ctx)) return null;\n return payload.ctx;\n } catch {\n return null;\n }\n}\n\nexport function issueHostedMcpToken(surface: HostedMcpSurface, ctx: HostedMcpContext): string {\n const payloadPart = encodeTokenPart({\n v: 2,\n exp: Date.now() + TOKEN_TTL_MS,\n aud: surface,\n ctx,\n } satisfies HostedTokenPayload);\n return `${payloadPart}.${signTokenPayload(payloadPart)}`;\n}\n\nexport function resolveHostedMcpToken(\n token: string | null,\n surface: HostedMcpSurface,\n): HostedMcpContext | null {\n if (!token) return null;\n const [payloadPart, signature, extra] = token.split(\".\");\n if (!payloadPart || !signature || extra !== undefined) return null;\n if (!safeEqual(signature, signTokenPayload(payloadPart))) return null;\n\n try {\n const payload = decodeTokenPart(payloadPart) as Partial<HostedTokenPayload>;\n if (\n payload.v !== 2 ||\n payload.aud !== surface ||\n typeof payload.exp !== \"number\" ||\n payload.exp <= Date.now()\n ) {\n return null;\n }\n return isHostedMcpContext(payload.ctx) ? payload.ctx : null;\n } catch {\n return null;\n }\n}\n\n/**\n * MCP server spec injected into an agent session's MCP config so the agent\n * connects back to this node's runtime endpoint with its per-turn token.\n */\nexport function buildRuntimeMcpSpec(\n agent: AgentKind,\n ctx: RuntimeMcpContext,\n): Record<string, unknown> {\n const base = `http://127.0.0.1:${runtimePort}${RUNTIME_MCP_BASE_PATH}`;\n const query = `token=${encodeURIComponent(issueRuntimeMcpToken(ctx))}`;\n const url = agent === \"codex\" ? `${base}/mcp?${query}` : `${base}/sse?${query}`;\n assertMcpUrlWithinBudget(RUNTIME_MCP_KEY, url, ctx.topicId);\n if (agent === \"codex\") return { url };\n return {\n type: \"sse\" as const,\n url,\n timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS,\n ...(agent === \"maestro\" ? { lifecycle: \"turn\" as const } : {}),\n };\n}\n\n/**\n * Refuse loudly rather than hand the agent a URL the server will 431. This\n * fails the turn's MCP setup, which is the safe outcome: the alternative —\n * minting the token without the fields that do not fit — would silently\n * widen the turn whenever the field that did not fit was the assertion.\n */\nfunction assertMcpUrlWithinBudget(surface: string, url: string, topicId: string | undefined) {\n if (url.length <= MCP_URL_BUDGET_CHARS) return;\n const error = new McpUrlBudgetExceededError(surface, url.length);\n logger.error(\n { topicId, surface, urlLength: url.length, budget: MCP_URL_BUDGET_CHARS },\n \"built-in MCP URL exceeds the transport budget; refusing to mint the token\",\n );\n throw error;\n}\n\nfunction hostedMcpCacheIdentity(surface: HostedMcpSurface, ctx: HostedMcpContext): string {\n let semanticContext: unknown;\n switch (surface) {\n case \"system-health\":\n semanticContext = {};\n break;\n case \"token-stats\":\n case \"agent-health\":\n semanticContext = { userId: ctx.userId };\n break;\n case \"task\":\n semanticContext = {\n userId: ctx.userId,\n topicTitle: ctx.topicTitle,\n topicId: ctx.topicId ?? null,\n };\n break;\n case \"wiki\":\n case \"skills\":\n semanticContext = {\n userId: ctx.userId,\n topicId: ctx.wikiTopicId ?? ctx.topicId ?? null,\n };\n break;\n case \"vault\":\n semanticContext = { userId: ctx.userId, cwd: ctx.cwd, agent: ctx.agent };\n break;\n case \"session-comm\":\n semanticContext = {\n userId: ctx.userId,\n // Who may reach what changes per turn (a different person, or a hub\n // that has since changed a roster), so a cached server must not carry\n // an earlier turn's reach into this one.\n actorUserId: ctx.actorUserId ?? null,\n actorTopicScope: ctx.actorTopicScope ?? null,\n // The grant is per turn (bound to this turn's request id), so a\n // server cached with one must not answer a later turn with it.\n remoteSession: ctx.remoteSession ?? null,\n topicTitle: ctx.topicTitle,\n topicId: ctx.topicId ?? null,\n subagentParentTopicId: ctx.subagentParentTopicId ?? null,\n depth: ctx.depth ?? 0,\n silent: ctx.silent ?? false,\n agent: ctx.agent,\n // Part of the identity, not a detail: a server cached for a channel\n // turn would otherwise be reused for a thread turn and record the ask\n // against the wrong conversation.\n threadRootId: ctx.threadRootId ?? null,\n peerBridge: ctx.peerBridge ?? null,\n };\n break;\n }\n const digest = createHash(\"sha256\")\n .update(JSON.stringify([surface, semanticContext]))\n .digest(\"hex\")\n .slice(0, 24);\n return `hosted:${surface}:${digest}`;\n}\n\n/** Build an agent transport spec for one logical MCP surface on the shared runtime process. */\nexport function buildHostedMcpSpec(\n agent: AgentKind,\n surface: HostedMcpSurface,\n ctx: HostedMcpContext,\n): Record<string, unknown> {\n const token = issueHostedMcpToken(surface, ctx);\n const base = `http://127.0.0.1:${runtimePort}${RUNTIME_MCP_BASE_PATH}/${surface}`;\n const query = `token=${encodeURIComponent(token)}`;\n const url = agent === \"codex\" ? `${base}/mcp?${query}` : `${base}/sse?${query}`;\n // A hosted context has no free-text field either. Measured with the\n // maximal assertion (208 UUIDs, 8,159 bytes) and every optional field set,\n // the hosted URL is marginally *longer* than the runtime one — ~12,118\n // characters for `session-comm`, 12,100–12,109 for the other surfaces,\n // against 12,052–12,055 for the runtime token — because the surface name\n // and lifecycle fields outweigh the runtime token's switch-target list.\n // All stay ≥ 2,200 characters under budget. The session-comm token may\n // additionally carry a remote-session grant. Measured in\n // `hosted-runtime-spec.test.ts`: the hub's real grant (≈440-character\n // capability, short hub URL) adds 682 characters — 12,800 beside the\n // maximal assertion, ~1,500 to spare. A grant at both caps (512-char URL,\n // 2 KiB capability) adds ≈3,475 and fits alone (4,689) but not beside the\n // maximal assertion (15,593); the hard check below refuses that mint, so\n // the caps bound the grant while the budget bounds the token — the largest\n // capability that fits beside a maximal assertion is ≈1,590 characters.\n // The check is the same on purpose, so a field added later cannot quietly\n // push it past the transport.\n assertMcpUrlWithinBudget(surface, url, ctx.topicId);\n if (agent === \"codex\") return { url };\n const queryBound =\n surface === \"session-comm\" &&\n (ctx.silent === true || ctx.peerBridge !== undefined || ctx.remoteSession !== undefined);\n const lifecycle = queryBound ? \"turn\" : surface === \"session-comm\" ? \"session\" : \"process\";\n return {\n type: \"sse\" as const,\n url,\n timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS,\n ...(agent === \"maestro\"\n ? {\n lifecycle,\n cacheKey: hostedMcpCacheIdentity(surface, ctx),\n }\n : {}),\n };\n}\n",
17
+ "import type { ActorTopicScope } from \"#types\";\n\n/**\n * Hard caps on a hub-supplied room assertion.\n *\n * The assertion is not stored and forgotten: it rides the signed per-turn MCP\n * token, which every hosted built-in MCP server receives in the URL query\n * (`?token=`) of an `http://127.0.0.1` request, and — with\n * `NEGOTIUM_BUILTIN_MCP_TRANSPORT=stdio` — one base64url argv entry of the\n * session-comm child. The transport, not the database, is the tight bound:\n *\n * - `Bun.serve` answers 431 once the request line is too long (Bun 1.3.14:\n * a 16,205-character URL is served, 16,305 is refused). These caps alone\n * do not bound the URL — the token carries other fields — so the whole URL\n * is budgeted at `MCP_URL_BUDGET_CHARS` (14 KiB) in `runtime-spec.ts`,\n * where the numbers live. The 8 KiB assertion below becomes 10,924\n * base64url characters at most; with every other runtime-token field at\n * its largest (the prompt itself is not in the token — only the derived\n * `explicitAgentSwitchTargets`, at most three agent names) the URL is\n * ≤ ~13.4 KB.\n * - argv: `encodeActorTopicScopeArg` is the assertion alone, ≤ 10,924\n * characters, far below Linux `MAX_ARG_STRLEN` (128 KiB) for one argument\n * and macOS `ARG_MAX` (1 MiB) overall. The encoder re-validates before it\n * encodes, so an in-process caller that bypassed the gateway parser cannot\n * put an unbounded object into argv either.\n *\n * With UUID room ids (39 bytes each serialized) the byte cap admits roughly\n * 208 ids across both lists; the per-list count cap bounds the work done on\n * an assertion before its size is known, and the id length cap keeps a single\n * id from being the whole budget. Raising these means moving the assertion\n * out of the token (server-side per-turn context), not editing the numbers.\n */\nexport const ACTOR_TOPIC_SCOPE_LIMITS = Object.freeze({\n /** Ids per list, counted before de-duplication. */\n maxIdsPerList: 200,\n /** Characters per id, after trimming. */\n maxIdLength: 128,\n /** UTF-8 bytes of the normalized assertion as JSON. */\n maxSerializedBytes: 8 * 1024,\n});\n\nconst SCOPE_KEYS = [\"visibleNodeTopicIds\", \"ownedNodeTopicIds\"] as const;\n\nexport type ActorTopicScopeValidation =\n | { ok: true; scope: ActorTopicScope | undefined }\n | { ok: false; error: string };\n\nfunction idList(value: unknown, name: string): string[] | string {\n if (!Array.isArray(value)) return `${name} must be an array of topic ids`;\n if (value.length > ACTOR_TOPIC_SCOPE_LIMITS.maxIdsPerList) {\n return `${name} has ${value.length} ids; at most ${ACTOR_TOPIC_SCOPE_LIMITS.maxIdsPerList} are allowed`;\n }\n const ids = new Set<string>();\n for (const item of value) {\n if (typeof item !== \"string\") return `${name} must contain only strings`;\n const id = item.trim();\n if (!id) return `${name} must not contain empty ids`;\n if (id.length > ACTOR_TOPIC_SCOPE_LIMITS.maxIdLength) {\n return `${name} contains an id longer than ${ACTOR_TOPIC_SCOPE_LIMITS.maxIdLength} characters`;\n }\n ids.add(id);\n }\n return [...ids];\n}\n\n/**\n * Validate a hub-supplied room assertion and say why it failed.\n *\n * `undefined` in means `undefined` out (no assertion, fail-closed downstream);\n * anything else must be exactly `{ visibleNodeTopicIds, ownedNodeTopicIds }`\n * — a plain object with those two own keys and nothing else (so a stray\n * `__proto__` or `constructor` key is a rejection, not a property), each a\n * list of non-empty strings within {@link ACTOR_TOPIC_SCOPE_LIMITS} — or it is\n * rejected, so a malformed assertion can never be read as \"everything\".\n */\nexport function validateActorTopicScope(value: unknown): ActorTopicScopeValidation {\n if (value === undefined) return { ok: true, scope: undefined };\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return {\n ok: false,\n error:\n \"actorTopicScope must be { visibleNodeTopicIds: string[], ownedNodeTopicIds: string[] }\",\n };\n }\n const proto = Object.getPrototypeOf(value);\n if (proto !== Object.prototype && proto !== null) {\n return { ok: false, error: \"actorTopicScope must be a plain object\" };\n }\n const keys = Object.keys(value);\n const unknown = keys.filter((key) => !(SCOPE_KEYS as readonly string[]).includes(key));\n if (unknown.length || keys.length !== SCOPE_KEYS.length) {\n return {\n ok: false,\n error: unknown.length\n ? `actorTopicScope has unexpected key(s): ${unknown.join(\", \")}`\n : \"actorTopicScope must have both visibleNodeTopicIds and ownedNodeTopicIds\",\n };\n }\n const record = value as Record<string, unknown>;\n const visible = idList(record.visibleNodeTopicIds, \"actorTopicScope.visibleNodeTopicIds\");\n if (typeof visible === \"string\") return { ok: false, error: visible };\n const owned = idList(record.ownedNodeTopicIds, \"actorTopicScope.ownedNodeTopicIds\");\n if (typeof owned === \"string\") return { ok: false, error: owned };\n const scope: ActorTopicScope = { visibleNodeTopicIds: visible, ownedNodeTopicIds: owned };\n const bytes = Buffer.byteLength(JSON.stringify(scope), \"utf-8\");\n if (bytes > ACTOR_TOPIC_SCOPE_LIMITS.maxSerializedBytes) {\n return {\n ok: false,\n error: `actorTopicScope is ${bytes} bytes serialized; at most ${ACTOR_TOPIC_SCOPE_LIMITS.maxSerializedBytes} are allowed`,\n };\n }\n return { ok: true, scope };\n}\n\n/**\n * Validate a hub-supplied room assertion.\n *\n * `undefined` in means `undefined` out (no assertion, fail-closed downstream);\n * anything else must pass {@link validateActorTopicScope} or it is rejected\n * with `null`. Every path an assertion can enter by — the gateway body, the\n * signed MCP tokens, the stdio argv — goes through this one parser, so the\n * limits cannot drift between them.\n */\nexport function parseActorTopicScope(value: unknown): ActorTopicScope | undefined | null {\n const validated = validateActorTopicScope(value);\n return validated.ok ? validated.scope : null;\n}\n\nexport function isActorTopicScope(value: unknown): value is ActorTopicScope {\n return parseActorTopicScope(value) != null;\n}\n\n/**\n * Read a validated assertion out of a persisted or signed context. Anything\n * that does not validate collapses to \"no assertion\" rather than throwing, so\n * a stale row cannot break a turn — it only narrows it to what a turn without\n * an assertion reaches: the current room plus its own subagent lineage.\n */\nexport function actorTopicScopeFrom(value: unknown): ActorTopicScope | undefined {\n return parseActorTopicScope(value) ?? undefined;\n}\n\n/**\n * The strictest assertion two requests agree on: an id is kept only when both\n * assert it, and a request without an assertion leaves the result without one\n * (fail-closed). Used when several pending requests of one actor fold into a\n * single turn, so the merged turn never reaches a room one of them could not.\n */\nexport function intersectActorTopicScopes(\n scopes: ReadonlyArray<ActorTopicScope | undefined>,\n): ActorTopicScope | undefined {\n if (scopes.length === 0 || scopes.some((scope) => scope === undefined)) return undefined;\n const [first, ...rest] = scopes as ActorTopicScope[];\n const keep = (key: keyof ActorTopicScope) =>\n first[key].filter((id) => rest.every((scope) => scope[key].includes(id)));\n return {\n visibleNodeTopicIds: keep(\"visibleNodeTopicIds\"),\n ownedNodeTopicIds: keep(\"ownedNodeTopicIds\"),\n };\n}\n\n/**\n * Argv-safe encoding for the stdio session-comm server (`--actor-topic-scope=`).\n * Bounded by {@link ACTOR_TOPIC_SCOPE_LIMITS}: 8,192 bytes of JSON become at\n * most 10,924 base64url characters, see there. The input is put through\n * {@link validateActorTopicScope} first and an invalid or oversized assertion\n * throws — it is never truncated (which would narrow the turn silently) nor\n * passed on (which would let a typed in-process caller overflow argv).\n */\nexport function encodeActorTopicScopeArg(scope: ActorTopicScope): string {\n const validated = validateActorTopicScope(scope);\n if (!validated.ok) throw new Error(validated.error);\n if (!validated.scope) throw new Error(\"actorTopicScope is required\");\n return Buffer.from(JSON.stringify(validated.scope), \"utf-8\").toString(\"base64url\");\n}\n",
18
+ "import type { RemoteSessionGrant } from \"#types\";\n\n/**\n * Hard caps on a hub-supplied remote-session grant.\n *\n * Like the actor room assertion (`actor-topic-scope.ts`), the grant rides the\n * signed per-turn `session-comm` MCP token in a URL query and — with\n * `NEGOTIUM_BUILTIN_MCP_TRANSPORT=stdio` — one base64url argv entry, so the\n * transport bounds it, not the database. A capability is ≈330–440 characters\n * (`rsc1.<base64url JSON>.<base64url HMAC>`) and adds ≈680 URL characters\n * beside the maximal 8 KiB assertion (12,800 of the 14,336 budget, measured\n * in `hosted-runtime-spec.test.ts`). The caps below leave a hub room to grow\n * the payload, but a grant at both caps (≈3,475 URL characters) does not fit\n * beside the *maximal* assertion — `MCP_URL_BUDGET_CHARS` is the backstop and\n * refuses that mint loudly rather than dropping a field. A capability up to\n * ≈1,590 characters always fits.\n */\nexport const REMOTE_SESSION_GRANT_LIMITS = Object.freeze({\n /** Characters of `hubUrl`, after trimming. */\n maxHubUrlLength: 512,\n /** Characters of `capability`, after trimming. */\n maxCapabilityLength: 2 * 1024,\n /** The only capability format this node forwards. */\n capabilityPrefix: \"rsc1.\",\n});\n\nconst GRANT_KEYS = [\"hubUrl\", \"capability\"] as const;\nconst LOOPBACK_HOSTS = new Set([\"127.0.0.1\", \"::1\", \"[::1]\", \"localhost\"]);\n\nexport type RemoteSessionGrantValidation =\n | { ok: true; grant: RemoteSessionGrant | undefined }\n | { ok: false; error: string };\n\n/**\n * Normalize a hub URL the node may present a bearer to: loopback `http://`\n * or any `https://` origin, ≤ 512 characters, no credentials, no query or\n * fragment. Returns the canonical string (trailing slash dropped) or the\n * reason it is refused. The one rule for every hub URL the node stores — the\n * turn grant's `hubUrl` and an ask's `remoteReply.hubUrl` alike — so a\n * bearer can never be steered to an attacker-chosen host.\n */\nexport function normalizeHubUrl(\n raw: string,\n name = \"remoteSession.hubUrl\",\n): { url: string } | { error: string } {\n if (raw.length > REMOTE_SESSION_GRANT_LIMITS.maxHubUrlLength) {\n return {\n error: `${name} is longer than ${REMOTE_SESSION_GRANT_LIMITS.maxHubUrlLength} characters`,\n };\n }\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n return { error: `${name} must be an absolute URL` };\n }\n if (url.username || url.password) {\n return { error: `${name} must not carry credentials` };\n }\n if (url.search || url.hash || raw.includes(\"?\") || raw.includes(\"#\")) {\n return { error: `${name} must not carry a query or fragment` };\n }\n if (url.protocol === \"http:\") {\n if (!LOOPBACK_HOSTS.has(url.hostname)) {\n return { error: `${name} must be https:// or a loopback http:// origin` };\n }\n } else if (url.protocol !== \"https:\") {\n return { error: `${name} must be https:// or a loopback http:// origin` };\n }\n return { url: url.toString().replace(/\\/+$/, \"\") };\n}\n\n/** Shape of the hub's one-shot `rsr1` reply token; the node never verifies it. */\nexport const REMOTE_SESSION_REPLY_TOKEN_PATTERN = /^rsr1\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/;\n/** Same cap as the capability: the hub's tokens are ≈200 characters. */\nexport const MAX_REMOTE_SESSION_REPLY_TOKEN_LENGTH =\n REMOTE_SESSION_GRANT_LIMITS.maxCapabilityLength;\n\n/**\n * Validate a hub-supplied remote-session grant and say why it failed.\n *\n * `undefined` in means `undefined` out (no grant: remote session-comm stays\n * fail-closed on `otium`); anything else must be exactly\n * `{ hubUrl, capability }` — a plain object with those two own keys — with a\n * callable hub URL and an opaque `rsc1.` capability within\n * {@link REMOTE_SESSION_GRANT_LIMITS}. The node never decodes or verifies the\n * capability: it is a bearer the hub issued and only the hub can check.\n */\nexport function validateRemoteSessionGrant(value: unknown): RemoteSessionGrantValidation {\n if (value === undefined) return { ok: true, grant: undefined };\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return { ok: false, error: \"remoteSession must be { hubUrl: string, capability: string }\" };\n }\n const proto = Object.getPrototypeOf(value);\n if (proto !== Object.prototype && proto !== null) {\n return { ok: false, error: \"remoteSession must be a plain object\" };\n }\n const keys = Object.keys(value);\n const unknown = keys.filter((key) => !(GRANT_KEYS as readonly string[]).includes(key));\n if (unknown.length || keys.length !== GRANT_KEYS.length) {\n return {\n ok: false,\n error: unknown.length\n ? `remoteSession has unexpected key(s): ${unknown.join(\", \")}`\n : \"remoteSession must have both hubUrl and capability\",\n };\n }\n const record = value as Record<string, unknown>;\n if (typeof record.hubUrl !== \"string\" || !record.hubUrl.trim()) {\n return { ok: false, error: \"remoteSession.hubUrl must be a non-empty string\" };\n }\n const hubUrl = normalizeHubUrl(record.hubUrl.trim());\n if (\"error\" in hubUrl) return { ok: false, error: hubUrl.error };\n if (typeof record.capability !== \"string\" || !record.capability.trim()) {\n return { ok: false, error: \"remoteSession.capability must be a non-empty string\" };\n }\n const capability = record.capability.trim();\n if (capability.length > REMOTE_SESSION_GRANT_LIMITS.maxCapabilityLength) {\n return {\n ok: false,\n error: `remoteSession.capability is ${capability.length} characters; at most ${REMOTE_SESSION_GRANT_LIMITS.maxCapabilityLength} are allowed`,\n };\n }\n if (!capability.startsWith(REMOTE_SESSION_GRANT_LIMITS.capabilityPrefix)) {\n return {\n ok: false,\n error: `remoteSession.capability must start with \"${REMOTE_SESSION_GRANT_LIMITS.capabilityPrefix}\"`,\n };\n }\n // Three dot-separated base64url parts and nothing else, so a value that\n // is not even shaped like a capability never reaches the hub.\n if (!/^rsc1\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/.test(capability)) {\n return { ok: false, error: \"remoteSession.capability is malformed\" };\n }\n return { ok: true, grant: { hubUrl: hubUrl.url, capability } };\n}\n\n/** {@link validateRemoteSessionGrant} collapsed to `null` on failure. */\nexport function parseRemoteSessionGrant(value: unknown): RemoteSessionGrant | undefined | null {\n const validated = validateRemoteSessionGrant(value);\n return validated.ok ? validated.grant : null;\n}\n\nexport function isRemoteSessionGrant(value: unknown): value is RemoteSessionGrant {\n return parseRemoteSessionGrant(value) != null;\n}\n\n/**\n * Read a validated grant out of a persisted or signed context. Anything that\n * does not validate collapses to \"no grant\" rather than throwing: a stale row\n * only loses remote reach, it never breaks the turn.\n */\nexport function remoteSessionGrantFrom(value: unknown): RemoteSessionGrant | undefined {\n return parseRemoteSessionGrant(value) ?? undefined;\n}\n\n/**\n * Best-effort peek at the capability's expiry (`e`, epoch seconds), used only\n * to order grants when several requests fold into one turn. Untrusted: the\n * node never decides validity from it — the hub does.\n */\nexport function remoteSessionGrantExpiry(grant: RemoteSessionGrant): number | null {\n const payload = grant.capability.split(\".\")[1];\n if (!payload) return null;\n try {\n const decoded = JSON.parse(Buffer.from(payload, \"base64url\").toString(\"utf-8\")) as unknown;\n const exp = (decoded as { e?: unknown } | null)?.e;\n return typeof exp === \"number\" && Number.isFinite(exp) ? exp : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The grant a merged turn runs with: symmetric to `intersectActorTopicScopes`\n * — a request without a grant leaves the batch without one (fail-closed), and\n * a batch of grants for one hub keeps the one that expires last so the merged\n * turn is not cut short by the oldest message's capability. Grants naming\n * different hubs never merge (the batch runs with none). The caller has\n * already ensured the folded requests speak for the same actor.\n */\nexport function mergeRemoteSessionGrants(\n grants: ReadonlyArray<RemoteSessionGrant | undefined>,\n): RemoteSessionGrant | undefined {\n if (grants.length === 0 || grants.some((grant) => grant === undefined)) return undefined;\n const present = grants as RemoteSessionGrant[];\n const hubUrl = present[0]!.hubUrl;\n if (present.some((grant) => grant.hubUrl !== hubUrl)) return undefined;\n let chosen = present[present.length - 1]!;\n let chosenExpiry = remoteSessionGrantExpiry(chosen);\n for (const grant of present) {\n const expiry = remoteSessionGrantExpiry(grant);\n if (expiry !== null && (chosenExpiry === null || expiry > chosenExpiry)) {\n chosen = grant;\n chosenExpiry = expiry;\n }\n }\n return chosen;\n}\n\n/**\n * Argv-safe encoding for the stdio session-comm server\n * (`--remote-session-grant=`). Re-validated before encoding, so an in-process\n * caller cannot put an unbounded or malformed grant into argv.\n */\nexport function encodeRemoteSessionGrantArg(grant: RemoteSessionGrant): string {\n const validated = validateRemoteSessionGrant(grant);\n if (!validated.ok) throw new Error(validated.error);\n if (!validated.grant) throw new Error(\"remoteSession is required\");\n return Buffer.from(JSON.stringify(validated.grant), \"utf-8\").toString(\"base64url\");\n}\n\n/** Inverse of {@link encodeRemoteSessionGrantArg}; `null` when malformed. */\nexport function decodeRemoteSessionGrantArg(value: string): RemoteSessionGrant | null {\n try {\n const decoded = JSON.parse(Buffer.from(value, \"base64url\").toString(\"utf-8\")) as unknown;\n return parseRemoteSessionGrant(decoded) ?? null;\n } catch {\n return null;\n }\n}\n",
16
19
  "export interface PeerSessionBridgeIpcConfig {\n url: string;\n token: string;\n}\n\nconst registrations: Array<{ id: symbol; config: PeerSessionBridgeIpcConfig }> = [];\n\nexport function registerPeerSessionBridgeIpcConfig(config: PeerSessionBridgeIpcConfig): () => void {\n const registration = { id: Symbol(\"peer-session-bridge-ipc\"), config: { ...config } };\n registrations.push(registration);\n let disposed = false;\n return () => {\n if (disposed) return;\n disposed = true;\n const index = registrations.findIndex((entry) => entry.id === registration.id);\n if (index >= 0) registrations.splice(index, 1);\n };\n}\n\nexport function peerSessionBridgeIpcEnv(): Record<string, string> | undefined {\n const active = registrations.at(-1)?.config;\n if (!active) return undefined;\n return {\n NEGOTIUM_PEER_SESSION_BRIDGE_URL: active.url,\n NEGOTIUM_PEER_SESSION_BRIDGE_TOKEN: active.token,\n };\n}\n",
17
20
  "import { type ChildProcess, execFileSync, spawn } from \"node:child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport {\n BASH_RS_BIN,\n BASH_RS_VERSION,\n BASHRS_SPILL_ROOT,\n BG_BASH_BASE_PORT,\n BG_BASH_MAX_PORT,\n} from \"#platform/config\";\nimport { delay } from \"#platform/delay\";\nimport { logger } from \"#platform/logger\";\nimport { deriveBgBashContextCapability } from \"./context\";\n\nexport function makeBgBashKey(_userId: string, _topic: string): string {\n return \"runtime\";\n}\n\ninterface BgBashInstance {\n process: ChildProcess;\n port: number;\n startedAt: number;\n lastUsedAt: number;\n}\n\nexport interface BackgroundBashManager {\n contextCapability(userId: string, topic: string): string;\n ensure(userId: string, topic: string): Promise<number>;\n clear(userId: string, topic: string): void;\n clearUser(userId: string): void;\n killAll(): Promise<void>;\n}\n\nexport interface BackgroundBashManagerOptions {\n /**\n * bash-rs executable. Defaults to the installed binary; injectable so a test\n * can drive the manager's bookkeeping with a fake `spawn` on a host that has\n * no binary at all.\n */\n bashRsBin?: string;\n basePort?: number;\n maxPort?: number;\n capability?: string;\n serverId?: string;\n env?: NodeJS.ProcessEnv;\n fetch?: typeof globalThis.fetch;\n now?: () => number;\n delay?: (milliseconds: number) => Promise<void>;\n portPids?: (port: number) => readonly number[];\n spawn?: (\n command: string,\n args: readonly string[],\n options: Parameters<typeof spawn>[2],\n ) => ChildProcess;\n}\n\nfunction defaultPortPids(port: number): number[] {\n try {\n return execFileSync(\"lsof\", [\"-i\", `:${port}`, \"-t\"], { stdio: \"pipe\" })\n .toString()\n .trim()\n .split(\"\\n\")\n .map((pid) => Number.parseInt(pid, 10))\n .filter((pid) => !Number.isNaN(pid));\n } catch {\n return [];\n }\n}\n\n/** Create a fully isolated manager. All mutable process/port/context state belongs to the caller. */\nexport function createBackgroundBashManager(\n options: BackgroundBashManagerOptions = {},\n): BackgroundBashManager {\n const instances = new Map<string, BgBashInstance>();\n const usedPorts = new Set<number>();\n const spawning = new Map<string, Promise<number>>();\n const knownContexts = new Map<string, { userId: string; topic: string }>();\n const runtimeCapability = options.capability ?? randomBytes(32).toString(\"hex\");\n const runtimeServerId = options.serverId ?? randomBytes(16).toString(\"hex\");\n const bashRsBin = options.bashRsBin ?? BASH_RS_BIN;\n const basePort = options.basePort ?? BG_BASH_BASE_PORT;\n const maxPort = options.maxPort ?? BG_BASH_MAX_PORT;\n const fetchImpl = options.fetch ?? globalThis.fetch;\n const now = options.now ?? Date.now;\n const wait = options.delay ?? delay;\n const portPids = options.portPids ?? defaultPortPids;\n const spawnImpl =\n options.spawn ?? ((command, args, spawnOptions) => spawn(command, [...args], spawnOptions));\n\n function contextKey(userId: string, topic: string): string {\n return `${userId}\\0${topic}`;\n }\n\n function contextCapability(userId: string, topic: string): string {\n return deriveBgBashContextCapability(runtimeCapability, userId, topic);\n }\n\n async function allocatePort(excludedPorts: ReadonlySet<number> = new Set()): Promise<number> {\n for (let port = basePort; port <= maxPort; port++) {\n if (usedPorts.has(port) || excludedPorts.has(port)) continue;\n usedPorts.add(port);\n if (portPids(port).length > 0) {\n usedPorts.delete(port);\n continue;\n }\n return port;\n }\n throw new Error(\n `No available ports for background-bash (range ${basePort}-${maxPort}, ${instances.size} active)`,\n );\n }\n\n async function isHealthy(port: number): Promise<boolean> {\n try {\n const response = await fetchImpl(`http://127.0.0.1:${port}/health`, {\n signal: AbortSignal.timeout(2000),\n });\n if (!response.ok) return false;\n // Confirm this port answers for *our* spawned process rather than a\n // stale one left behind by a previous manager instance.\n const body = await response.text();\n try {\n const parsed = JSON.parse(body);\n return (\n Boolean(parsed) && typeof parsed === \"object\" && parsed.instance_id === runtimeServerId\n );\n } catch {\n return false;\n }\n } catch {\n return false;\n }\n }\n\n function killRuntime(): void {\n const key = \"runtime\";\n const instance = instances.get(key);\n if (!instance) return;\n try {\n instance.process.kill(\"SIGTERM\");\n } catch {}\n usedPorts.delete(instance.port);\n instances.delete(key);\n logger.info({ key, port: instance.port }, \"background-bash server killed\");\n }\n\n async function spawnServer(\n key: string,\n reservedPort?: number,\n excludedPorts: ReadonlySet<number> = new Set(),\n ): Promise<number> {\n // bash-rs is the only implementation. A TS server used to stand in when the\n // binary was absent, but the two agreed on the HTTP protocol while exposing\n // different MCP tool names (bash_run vs background_bash_run), so which one\n // spawned silently changed the tool surface an agent saw. Failing loudly\n // beats serving a different API than the caller was told to expect.\n //\n // Checked before allocating: the caller retries once per turn, and a port\n // reserved by a throw is never released, so allocating first leaked one\n // port per attempt until the range was exhausted and the real cause was\n // buried under \"No available ports\".\n if (!bashRsBin) {\n throw new Error(\n `background-bash requires the bash-rs ${BASH_RS_VERSION} binary; run install-bash-rs.mjs (or set NEGOTIUM_BASH_RS_BIN)`,\n );\n }\n const port = reservedPort ?? (await allocatePort(excludedPorts));\n const process = spawnImpl(bashRsBin, [String(port)], {\n stdio: \"ignore\",\n detached: false,\n // Long-lived background server — no console window on Windows. Ignored\n // on POSIX.\n windowsHide: true,\n env: {\n ...(options.env ?? globalThis.process.env),\n NEGOTIUM_BG_BASH_CAPABILITY: runtimeCapability,\n NEGOTIUM_BG_BASH_SERVER_ID: runtimeServerId,\n BASHRS_HTTP_CAPABILITY: runtimeCapability,\n BASHRS_INSTANCE_ID: runtimeServerId,\n BASHRS_SPILL_ROOT,\n },\n });\n\n process.once(\"error\", (error) => {\n logger.error({ err: error, key }, \"background-bash server error\");\n if (instances.get(key)?.process === process) {\n usedPorts.delete(port);\n instances.delete(key);\n }\n });\n process.once(\"exit\", (code) => {\n logger.info({ key, code }, \"background-bash server exited\");\n if (instances.get(key)?.process === process) {\n usedPorts.delete(port);\n instances.delete(key);\n }\n });\n\n const timestamp = now();\n instances.set(key, { process, port, startedAt: timestamp, lastUsedAt: timestamp });\n const started = now();\n while (now() - started < 8_000) {\n if (process.exitCode !== null) {\n const nextExcluded = new Set(excludedPorts);\n nextExcluded.add(port);\n return spawnServer(key, undefined, nextExcluded);\n }\n if (await isHealthy(port)) return port;\n await wait(200);\n }\n killRuntime();\n throw new Error(`background-bash server failed health check after spawn on port ${port}`);\n }\n\n async function ensure(userId: string, topic: string): Promise<number> {\n const key = makeBgBashKey(userId, topic);\n knownContexts.set(contextKey(userId, topic), { userId, topic });\n const inProgress = spawning.get(key);\n if (inProgress) return inProgress;\n\n const promise = (async () => {\n const existing = instances.get(key);\n if (existing && !existing.process.killed && existing.process.exitCode === null) {\n if (await isHealthy(existing.port)) {\n existing.lastUsedAt = now();\n return existing.port;\n }\n killRuntime();\n } else if (existing) {\n usedPorts.delete(existing.port);\n instances.delete(key);\n }\n return spawnServer(key);\n })().finally(() => spawning.delete(key));\n spawning.set(key, promise);\n return promise;\n }\n\n function clear(userId: string, topic: string): void {\n knownContexts.delete(contextKey(userId, topic));\n const instance = instances.get(\"runtime\");\n if (!instance) return;\n const query = new URLSearchParams({\n user: userId,\n topic,\n capability: contextCapability(userId, topic),\n });\n void fetchImpl(`http://127.0.0.1:${instance.port}/contexts?${query}`, {\n method: \"DELETE\",\n }).catch(() => {});\n }\n\n function clearUser(userId: string): void {\n for (const context of [...knownContexts.values()]) {\n if (context.userId === userId) clear(context.userId, context.topic);\n }\n }\n\n async function killAll(): Promise<void> {\n const entries = [...instances.values()];\n for (const instance of entries) {\n try {\n instance.process.kill(\"SIGTERM\");\n } catch {}\n }\n instances.clear();\n usedPorts.clear();\n knownContexts.clear();\n const deadline = now() + 3000;\n await Promise.all(\n entries.map(\n (instance) =>\n new Promise<void>((resolve) => {\n if (instance.process.exitCode !== null || instance.process.killed) return resolve();\n instance.process.once(\"exit\", resolve);\n instance.process.once(\"error\", resolve);\n const timer = setTimeout(resolve, Math.max(0, deadline - now()));\n timer.unref?.();\n }),\n ),\n );\n }\n\n return { contextCapability, ensure, clear, clearUser, killAll };\n}\n\nconst defaultManager = createBackgroundBashManager();\n\nexport const bgBashContextCapability = defaultManager.contextCapability;\nexport const ensureBgBash = defaultManager.ensure;\nexport const killBgBash = defaultManager.clear;\nexport const killBgBashForUser = defaultManager.clearUser;\nexport const killAllBgBash = defaultManager.killAll;\n",
18
21
  "export const delay = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));\n",
@@ -25,8 +28,8 @@
25
28
  "import { mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { closeDatabase, Database } from \"#storage/sqlite\";\nimport type { StorageDatabase, StorageHostConfig } from \"#storage/storage-contract\";\n\nexport type {\n StorageDatabase,\n StorageDatabaseAdapter,\n StorageDatabaseInput,\n StorageHostConfig,\n StorageHostOptions,\n StorageStatement,\n StorageTransaction,\n} from \"#storage/storage-contract\";\n\ntype InternalStorageDatabase = InstanceType<typeof Database>;\ntype OwnedStorageDatabase = InternalStorageDatabase & { close(): void };\n\ninterface StorageHostFrame {\n active: boolean;\n patch: Readonly<StorageHostConfig>;\n}\n\ntype StorageSchemaInitializer = (database: InternalStorageDatabase) => void;\ninterface RegisteredSchemaInitializer {\n initialize: StorageSchemaInitializer;\n priority: number;\n}\n\ninterface StorageHostState {\n configuredHost: Readonly<StorageHostConfig>;\n fallbackDatabase: OwnedStorageDatabase | null;\n fallbackDatabasePath: string | null;\n frames: StorageHostFrame[];\n schemaInitializers: RegisteredSchemaInitializer[];\n initializedSchemas: WeakMap<InternalStorageDatabase, Set<StorageSchemaInitializer>>;\n initializingDatabases: WeakSet<InternalStorageDatabase>;\n}\n\n/**\n * Which database an embedded Negotium uses is a property of the *process*, so\n * the state deciding it is keyed off a registered symbol rather than held in\n * module scope.\n *\n * Module scope would be equivalent only if every caller resolved to the same\n * module instance, and in the published package they do not:\n * `build-negotium-package.ts` emits most public entrypoints as independent\n * graphs, so each gets a private copy of this file. A host that configured\n * `negotium/storage` therefore left `negotium/agent-helpers` unconfigured, and\n * that copy opened a second database under the default state directory — with\n * no error, since both files are valid and writable.\n *\n * Merging those entrypoints into one graph looks tidier and does cut ~3MB from\n * `dist`, but Bun 1.2.15 (the pinned version) emits a shared chunk's export\n * list twice and the result is invalid ESM — \"Cannot export a duplicate name\".\n * That is bundler output with no counterpart in this source, so there is\n * nothing to de-duplicate here; it is fixed in Bun 1.3.14. Until the floor\n * moves, correctness cannot depend on how the package is chunked.\n */\nconst STORAGE_HOST_STATE = Symbol.for(\"negotium.storage-host.state.v1\");\n\nfunction storageState(): StorageHostState {\n const holder = globalThis as typeof globalThis & { [STORAGE_HOST_STATE]?: StorageHostState };\n const existing = holder[STORAGE_HOST_STATE];\n if (existing) return existing;\n const created: StorageHostState = {\n configuredHost: {},\n fallbackDatabase: null,\n fallbackDatabasePath: null,\n frames: [],\n schemaInitializers: [],\n initializedSchemas: new WeakMap(),\n initializingDatabases: new WeakSet(),\n };\n Object.defineProperty(holder, STORAGE_HOST_STATE, {\n value: created,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n return created;\n}\n\nfunction envPath(name: string, fallback: string): string {\n const value = process.env[name]?.trim();\n return resolve(value || fallback);\n}\n\nfunction defaultStateDir(): string {\n return envPath(\"NEGOTIUM_STATE_DIR\", join(homedir(), \".negotium\"));\n}\n\nfunction defaultDataDir(): string {\n return envPath(\"NEGOTIUM_DATA_DIR\", join(defaultStateDir(), \"data\"));\n}\n\nfunction defaultLogDir(): string {\n return envPath(\"NEGOTIUM_LOG_DIR\", join(defaultStateDir(), \"logs\"));\n}\n\nfunction defaultWorkspaceDir(): string {\n return envPath(\"NEGOTIUM_WORKSPACE_DIR\", join(defaultStateDir(), \"workspace\"));\n}\n\nfunction defaultSessionAsksDir(): string {\n const runDir = envPath(\"NEGOTIUM_RUN_DIR\", join(defaultStateDir(), \"runtime\"));\n return join(runDir, \"session-asks\");\n}\n\nfunction defaultSessionsDatabasePath(): string {\n return envPath(\"SESSIONS_DB_PATH\", join(resolveStorageDataDir(), \"sessions.db\"));\n}\n\nconst SQLITE_INIT_RETRY_MS = 25;\nconst SQLITE_INIT_TIMEOUT_MS = 5_000;\nconst SQLITE_INIT_SLEEP = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));\n\nfunction isSqliteBusy(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error);\n return /database is (?:locked|busy)|SQLITE_(?:BUSY|LOCKED)/i.test(message);\n}\n\nfunction execWithBusyRetry(\n database: InternalStorageDatabase,\n sql: string,\n timeoutMs = SQLITE_INIT_TIMEOUT_MS,\n): void {\n const deadline = Date.now() + timeoutMs;\n while (true) {\n try {\n database.exec(sql);\n return;\n } catch (error) {\n if (!isSqliteBusy(error) || Date.now() >= deadline) throw error;\n Atomics.wait(SQLITE_INIT_SLEEP, 0, 0, Math.min(SQLITE_INIT_RETRY_MS, deadline - Date.now()));\n }\n }\n}\n\nexport function initializeDatabase(database: InternalStorageDatabase): void {\n // busy_timeout FIRST. Switching to WAL needs a brief exclusive lock, so when\n // two processes open the same database at the same moment — the node daemon\n // and an adapter, or two MCP servers — one of them hits SQLITE_BUSY. With the\n // timeout configured afterwards there was no retry budget in effect for the\n // statement that needed it most. Older Bun releases can still surface\n // SQLITE_BUSY immediately for journal_mode, so keep a bounded host-level\n // retry around that one exclusive transition as well.\n database.exec(\"PRAGMA busy_timeout = 5000\");\n execWithBusyRetry(database, \"PRAGMA journal_mode = WAL\");\n database.exec(\"PRAGMA foreign_keys = ON\");\n database.exec(\"PRAGMA wal_autocheckpoint = 1000\");\n try {\n database.exec(\"PRAGMA wal_checkpoint(TRUNCATE)\");\n } catch {\n // Non-fatal; a concurrent writer may hold the WAL briefly.\n }\n}\n\nfunction defaultDatabase(): InternalStorageDatabase {\n const path = defaultSessionsDatabasePath();\n const state = storageState();\n if (state.fallbackDatabase && state.fallbackDatabasePath === path) return state.fallbackDatabase;\n if (state.fallbackDatabase) closeDatabase(state.fallbackDatabase);\n mkdirSync(dirname(path), { recursive: true });\n state.fallbackDatabase = new Database(path, { create: true }) as unknown as OwnedStorageDatabase;\n state.fallbackDatabasePath = path;\n initializeDatabase(state.fallbackDatabase);\n return state.fallbackDatabase;\n}\n\nexport function resolveStorageDatabase(): InternalStorageDatabase {\n return (storageState().configuredHost.database ?? defaultDatabase()) as InternalStorageDatabase;\n}\n\n/**\n * The host-injected connection, or null when Negotium owns its own store.\n *\n * Unlike {@link resolveStorageDatabase} this never opens anything. Callers that\n * manage their own short-lived connections need to know whether a host store\n * exists *before* deciding to open one by path: opening it anyway is how an\n * embedded Negotium ends up writing half its state into the host's database and\n * the other half into `~/.negotium`, with nothing reporting an error.\n */\nexport function configuredStorageDatabase(): InternalStorageDatabase | null {\n return (storageState().configuredHost.database as InternalStorageDatabase | undefined) ?? null;\n}\n\nexport function resolveStorageDataDir(): string {\n return storageState().configuredHost.dataDir ?? defaultDataDir();\n}\n\nexport function resolveStorageLogDir(): string {\n return storageState().configuredHost.logDir ?? defaultLogDir();\n}\n\nexport function resolveStorageSessionAsksDir(): string {\n return storageState().configuredHost.sessionAsksDir ?? defaultSessionAsksDir();\n}\n\nexport function resolveStorageWorkspaceDir(): string {\n return storageState().configuredHost.workspaceDir ?? defaultWorkspaceDir();\n}\n\nexport function resolveStorageSharedWikiDir(): string {\n return storageState().configuredHost.sharedWikiDir ?? join(resolveStorageWorkspaceDir(), \"wiki\");\n}\n\nexport function resolveStorageUsersLogDir(): string {\n return storageState().configuredHost.usersLogDir ?? join(resolveStorageDataDir(), \"users\");\n}\n\nconst STORAGE_PATH_KEYS = [\n \"dataDir\",\n \"logDir\",\n \"sessionAsksDir\",\n \"workspaceDir\",\n \"sharedWikiDir\",\n \"usersLogDir\",\n] as const;\n\nfunction normalizeStorageHostPatch(options: StorageHostConfig): Readonly<StorageHostConfig> {\n const patch: StorageHostConfig = {};\n if (options.database !== undefined) {\n options.database.exec(\"PRAGMA foreign_keys = ON\");\n patch.database = options.database;\n }\n for (const key of STORAGE_PATH_KEYS) {\n const value = options[key];\n if (value === undefined) continue;\n if (!value.trim()) throw new TypeError(`${key} must not be empty`);\n patch[key] = resolve(value);\n }\n return Object.freeze(patch);\n}\n\nfunction refreshConfiguredHost(): void {\n const state = storageState();\n state.configuredHost = Object.freeze(\n Object.assign({}, ...state.frames.filter((frame) => frame.active).map((frame) => frame.patch)),\n );\n}\n\n/**\n * Configure the process-local storage boundary for an embedding host.\n *\n * Resolution is lazy: importing `negotium/storage` never opens a database or\n * touches a filesystem path. The returned disposer restores the exact prior\n * host, which keeps tests and nested embeddings isolated.\n */\nexport function configureStorageHost(options: StorageHostConfig): () => void {\n const frame: StorageHostFrame = { active: true, patch: normalizeStorageHostPatch(options) };\n storageState().frames.push(frame);\n refreshConfiguredHost();\n return () => {\n if (!frame.active) return;\n frame.active = false;\n const frames = storageState().frames;\n const index = frames.indexOf(frame);\n if (index >= 0) frames.splice(index, 1);\n refreshConfiguredHost();\n };\n}\n\n/** Remove every configured host layer and restore standalone fallbacks. */\nexport function resetStorageHost(): void {\n const frames = storageState().frames;\n for (const frame of frames) frame.active = false;\n frames.length = 0;\n refreshConfiguredHost();\n}\n\n/** Close only Negotium's fallback connection. Injected connections are borrowed. */\nexport function closeStorageDatabase(): void {\n const state = storageState();\n if (!state.fallbackDatabase) return;\n closeDatabase(state.fallbackDatabase);\n state.fallbackDatabase = null;\n state.fallbackDatabasePath = null;\n}\n\nexport function registerStorageSchemaInitializer(\n initialize: StorageSchemaInitializer,\n priority = 100,\n): void {\n const initializers = storageState().schemaInitializers;\n initializers.push({ initialize, priority });\n initializers.sort((a, b) => a.priority - b.priority);\n}\n\nexport function ensureStorageSchemas(\n database: InternalStorageDatabase = resolveStorageDatabase(),\n): void {\n const state = storageState();\n if (state.initializingDatabases.has(database)) return;\n let initialized = state.initializedSchemas.get(database);\n if (!initialized) {\n initialized = new Set();\n state.initializedSchemas.set(database, initialized);\n }\n state.initializingDatabases.add(database);\n try {\n for (const entry of state.schemaInitializers) {\n if (initialized.has(entry.initialize)) continue;\n // Mark first so a migration that calls through the public db proxy does\n // not recursively invoke itself. Remove on failure so the next call can retry.\n initialized.add(entry.initialize);\n try {\n entry.initialize(database);\n } catch (error) {\n initialized.delete(entry.initialize);\n throw error;\n }\n }\n } finally {\n state.initializingDatabases.delete(database);\n }\n}\n\n/** Stable proxy identity used by legacy imports and embedding hosts. */\nexport const internalStorageDatabase = new Proxy({} as InternalStorageDatabase, {\n get(_target, property) {\n const database = resolveStorageDatabase();\n ensureStorageSchemas(database);\n const value = Reflect.get(database as object, property, database);\n return typeof value === \"function\" ? value.bind(database) : value;\n },\n set(_target, property, value) {\n const database = resolveStorageDatabase();\n ensureStorageSchemas(database);\n return Reflect.set(database as object, property, value, database);\n },\n});\n\n/** Structurally typed view intended for embedding hosts. */\nexport const storageDatabase = internalStorageDatabase as unknown as StorageDatabase;\n",
26
29
  "// Runtime-adaptive SQLite façade.\n//\n// Why this exists: Otium normally runs on bun and uses `bun:sqlite` (native,\n// fast, zero-build). But the `codex` agent's MCP servers must run on pure node\n// — codex 0.135's rmcp stdio client can't handshake with bun-spawned servers\n// (see serverLaunch in platform/mcp-config.ts). `bun:sqlite` doesn't exist\n// under node, so any MCP server that touches the DB would crash on import.\n//\n// This module picks the backend at runtime and re-exports it as `Database`:\n// - under bun → the real `bun:sqlite` Database (unchanged behavior)\n// - under node → a thin shim over node:sqlite's DatabaseSync exposing the\n// exact subset Otium uses: new Database(path, {readonly?,create?}),\n// .query()/.prepare() → statement, .exec(), .run(), .transaction(fn),\n// .close(); statements support positional `?` params via .run()/.get()/\n// .all(). (No named-object params / .values()/.iterate()/.as() are used in\n// this codebase, so the shim intentionally omits them.)\n//\n// The TYPE of the exported `Database` is bun:sqlite's own class type (imported\n// type-only, so it's erased at runtime and never resolved under node). That\n// keeps every existing call site — including generic `.query<Row, Params>()`\n// usages — type-checking exactly as before with zero changes.\n//\n// The bun branch uses a dynamic import so node never resolves the `bun:sqlite`\n// specifier (dead code under node), and the node branch's `node:sqlite` import\n// never runs under bun.\n\nimport type { Database as BunDatabase } from \"bun:sqlite\";\n\n// `mock.module()` can replace the Bun global while a test graph is being\n// evaluated. The runtime version flag is stable and is also the documented\n// cross-runtime discriminator.\nconst isBun = typeof process.versions.bun === \"string\";\n\ntype DatabaseCtor = typeof BunDatabase;\n\nlet Database: DatabaseCtor;\n\nif (isBun) {\n ({ Database } = await import(\"bun:sqlite\"));\n} else {\n // node:sqlite has no type declarations under our tsconfig (`types: bun-types`\n // only), and `bun-types` doesn't ship them — so type the dynamic import\n // locally and use a `string` specifier to keep tsc from trying to resolve it.\n type NodeStatement = {\n run(...params: unknown[]): unknown;\n get(...params: unknown[]): unknown;\n all(...params: unknown[]): unknown[];\n };\n type NodeDatabaseSync = {\n prepare(sql: string): NodeStatement;\n exec(sql: string): void;\n close(): void;\n };\n type NodeSqliteModule = {\n DatabaseSync: new (path: string, options?: { readOnly?: boolean }) => NodeDatabaseSync;\n };\n // Keep Bun's resolver from eagerly resolving the Node-only builtin even\n // though this branch is dead there (notably under `bun test` + mock.module).\n const nodeSqliteSpecifier = [\"node\", \"sqlite\"].join(\":\");\n const { DatabaseSync } = (await import(nodeSqliteSpecifier)) as NodeSqliteModule;\n\n type DbOptions = { readonly?: boolean; create?: boolean };\n\n class NodeDatabase {\n #db: NodeDatabaseSync;\n\n constructor(path: string, options: DbOptions = {}) {\n // node:sqlite opens read-write and creates-if-missing by default, which\n // matches bun's `{create:true}`. For readonly we must not create.\n this.#db = options.readonly\n ? new DatabaseSync(path, { readOnly: true })\n : new DatabaseSync(path);\n }\n\n query(sql: string) {\n return this.#db.prepare(sql);\n }\n\n prepare(sql: string) {\n return this.#db.prepare(sql);\n }\n\n exec(sql: string): void {\n this.#db.exec(sql);\n }\n\n run(sql: string, ...params: unknown[]) {\n return this.#db.prepare(sql).run(...params);\n }\n\n transaction<Args extends unknown[], R>(fn: (...args: Args) => R): (...args: Args) => R {\n // bun's db.transaction(fn) returns a function that runs fn inside a\n // transaction when called. node:sqlite has no helper, so emulate with\n // BEGIN/COMMIT/ROLLBACK. It also exposes deferred/immediate/exclusive\n // variants; mirror those so Node-launched MCP servers can share call\n // sites with Bun.\n const run =\n (begin: \"BEGIN\" | \"BEGIN DEFERRED\" | \"BEGIN IMMEDIATE\" | \"BEGIN EXCLUSIVE\") =>\n (...args: Args): R => {\n this.#db.exec(begin);\n try {\n const result = fn(...args);\n this.#db.exec(\"COMMIT\");\n return result;\n } catch (err) {\n this.#db.exec(\"ROLLBACK\");\n throw err;\n }\n };\n const tx = run(\"BEGIN\") as ((...args: Args) => R) & {\n deferred: (...args: Args) => R;\n immediate: (...args: Args) => R;\n exclusive: (...args: Args) => R;\n };\n tx.deferred = run(\"BEGIN DEFERRED\");\n tx.immediate = run(\"BEGIN IMMEDIATE\");\n tx.exclusive = run(\"BEGIN EXCLUSIVE\");\n return tx;\n }\n\n close(): void {\n this.#db.close();\n }\n }\n\n Database = NodeDatabase as unknown as DatabaseCtor;\n}\n\nexport { Database };\n\n/**\n * Close a database and release its underlying file handle.\n *\n * `bun:sqlite`'s no-argument `close()` does not finalize prepared statements\n * that are still reachable, so the file stays open. POSIX hides this — the\n * path can be unlinked while a handle remains — but Windows refuses to delete\n * or rename the file at all (`EBUSY`), which is how the leak surfaces. Passing\n * `true` finalizes eagerly and drops the handle.\n *\n * The node shim's `close()` ignores the argument, so one call covers both\n * backends; the fallback only matters for a backend that rejects the extra\n * parameter outright.\n */\nexport function closeDatabase(database: { close(throwOnError?: boolean): void }): void {\n try {\n database.close(true);\n } catch {\n try {\n database.close();\n } catch {\n // Already closed: nothing left to release.\n }\n }\n}\n",
27
30
  "import type { StorageDatabase } from \"#storage/storage-contract\";\nimport { internalStorageDatabase } from \"#storage/storage-host\";\n\nexport const db = internalStorageDatabase as unknown as StorageDatabase;\n",
28
- "// Persistent topic store backed by shared SQLite.\n\nimport { resolveFallbackAgent } from \"#platform/config-helpers\";\nimport { GENERAL_TOPIC_ID } from \"#platform/constants\";\nimport { logger } from \"#platform/logger\";\nimport { db } from \"#storage/forum-db\";\nimport { registerStorageSchemaInitializer } from \"#storage/storage-host\";\nimport type { AgentKind, EffortLevel } from \"#types\";\nimport type {\n AiMode,\n ParticipantDto,\n SubagentReportMode,\n TopicDto,\n TopicKind,\n TopicSurface,\n TopicVisibility,\n} from \"#types/api\";\n\n/**\n * Surface used when a caller does not name one — and the value every existing\n * row is backfilled with on first boot after the surface migration.\n *\n * Hosts that only ever serve one surface declare it once in their environment\n * (`NEGOTIUM_DEFAULT_SURFACE=otium` on the Otium hub and worker); a developer\n * Mac leaves it unset and gets `terminal`, with the telegram adapter\n * reclassifying its own mapped rooms afterwards.\n */\nexport function defaultTopicSurface(): TopicSurface {\n return normalizeTopicSurface(process.env.NEGOTIUM_DEFAULT_SURFACE);\n}\n\nexport function normalizeTopicSurface(value: unknown): TopicSurface {\n return value === \"telegram\" || value === \"otium\" || value === \"terminal\" ? value : \"terminal\";\n}\n\n/**\n * The surface instance new rooms are filed under when the caller names none.\n *\n * `surface` alone is not enough once a node may be attached to several Otium\n * workspaces (M-2): two workspaces are two independent namespaces on the same\n * surface. The adapter that owns the attachment installs the active scope at\n * mount time; `terminal` and `telegram` are singletons and stay null.\n *\n * Kept as process state rather than an argument threaded through every creation\n * path because the value is a property of *this process's attachment*, not of\n * any individual call — the same reason `defaultTopicSurface()` exists.\n */\nlet activeSurfaceScope: string | null = null;\n\nexport function normalizeSurfaceScope(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n return trimmed ? trimmed : null;\n}\n\nexport function defaultSurfaceScope(): string | null {\n return activeSurfaceScope ?? normalizeSurfaceScope(process.env.NEGOTIUM_SURFACE_SCOPE);\n}\n\n/** Install (or clear) the scope new rooms inherit. Returns the previous value. */\nexport function setDefaultSurfaceScope(scope: string | null): string | null {\n const previous = activeSurfaceScope;\n activeSurfaceScope = normalizeSurfaceScope(scope);\n return previous;\n}\n\n/**\n * Whether an Otium room must name a workspace to be created at all (M-3).\n *\n * Off by default, and off for every single-workspace host: an unscoped room is\n * then legacy, reachable, and perfectly usable. The adapter turns it on only\n * while several workspaces are attached, because there an unscoped room is\n * reachable from none of them (M-10) — a room nobody can see is worse than a\n * refusal that says so.\n */\nlet surfaceScopeRequired = false;\n\nexport function setSurfaceScopeRequired(required: boolean): void {\n surfaceScopeRequired = required;\n}\n\nexport function isSurfaceScopeRequired(): boolean {\n return surfaceScopeRequired;\n}\n\nfunction tableColumns(table: string): Set<string> {\n const rows = db.query(`PRAGMA table_info(${table})`).all() as Array<{ name: string }>;\n return new Set(rows.map((row) => row.name));\n}\n\n/** Persist the authoritative agent and, when supplied, its normalized base defaults. */\nexport function setApiTopicAgent(\n topicId: string,\n agent: AgentKind,\n defaults?: { model: string; effort?: EffortLevel },\n): void {\n if (!defaults) {\n db.query(\"UPDATE api_topics SET agent = ? WHERE id = ?\").run(agent, topicId);\n return;\n }\n db.query(\"UPDATE api_topics SET agent = ?, base_model = ?, base_effort = ? WHERE id = ?\").run(\n agent,\n defaults.model,\n defaults.effort ?? null,\n topicId,\n );\n}\n\nfunction initializeApiTopicsSchema(): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS api_topics (\n id TEXT PRIMARY KEY,\n title TEXT NOT NULL,\n kind TEXT NOT NULL DEFAULT 'channel',\n description TEXT,\n agent TEXT,\n default_model TEXT,\n default_effort TEXT,\n participants TEXT,\n created_at TEXT NOT NULL,\n last_message_at TEXT,\n is_archived INTEGER NOT NULL DEFAULT 0,\n ai_mention INTEGER NOT NULL DEFAULT 0,\n ai_mode TEXT\n )\n`);\n\n const initialTopicColumns = tableColumns(\"api_topics\");\n const legacyTopicSchema = !initialTopicColumns.has(\"response_policy\");\n const needsCanonicalTopicRebuild = legacyTopicSchema || !initialTopicColumns.has(\"agent\");\n if (legacyTopicSchema) {\n // Rename the legacy column once; new databases are created with `agent`.\n try {\n db.exec(\"ALTER TABLE api_topics RENAME COLUMN default_agent TO agent\");\n } catch {\n // Already migrated or freshly created.\n }\n\n // Migrate existing DBs that predate the ai_mention column (team-mode topics).\n try {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN ai_mention INTEGER NOT NULL DEFAULT 0\");\n } catch {\n // Column already exists — nothing to do.\n }\n\n // Migrate for spawn/fork tracking (R1).\n try {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN parent_topic_id TEXT\");\n } catch {}\n try {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN is_fork INTEGER NOT NULL DEFAULT 0\");\n } catch {}\n\n // Migrate for agent-spawned subagent worker rooms.\n try {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN is_subagent INTEGER NOT NULL DEFAULT 0\");\n } catch {}\n\n // Migrate for session persistence.\n try {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN session_id TEXT\");\n } catch {}\n\n try {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN kind TEXT NOT NULL DEFAULT 'channel'\");\n } catch {}\n\n try {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN ai_mode TEXT\");\n } catch {}\n\n db.exec(`\n CREATE TABLE IF NOT EXISTS api_schema_migrations (\n key TEXT PRIMARY KEY,\n applied_at TEXT NOT NULL\n )\n`);\n\n const ALWAYS_RESPOND_MIGRATION = \"api_topics_ai_invited_default_always_respond_20260623\";\n const alwaysRespondMigration = db\n .query(\"SELECT key FROM api_schema_migrations WHERE key = ?\")\n .get(ALWAYS_RESPOND_MIGRATION);\n if (!alwaysRespondMigration) {\n db.transaction(() => {\n db.query(\"UPDATE api_topics SET ai_mention = 0 WHERE agent IS NOT NULL\").run();\n db.query(\"INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)\").run(\n ALWAYS_RESPOND_MIGRATION,\n new Date().toISOString(),\n );\n })();\n }\n\n const GENERAL_AGENT_KIND_MIGRATION = \"api_topics_general_agent_kind_20260704\";\n const generalAgentKindMigration = db\n .query(\"SELECT key FROM api_schema_migrations WHERE key = ?\")\n .get(GENERAL_AGENT_KIND_MIGRATION);\n if (!generalAgentKindMigration) {\n db.transaction(() => {\n db.query(\"UPDATE api_topics SET kind = 'agent', ai_mention = 0 WHERE id = ?\").run(\n GENERAL_TOPIC_ID,\n );\n db.query(\"INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)\").run(\n GENERAL_AGENT_KIND_MIGRATION,\n new Date().toISOString(),\n );\n })();\n }\n\n const AI_MODE_MIGRATION = \"api_topics_ai_mode_20260704\";\n const aiModeMigration = db\n .query(\"SELECT key FROM api_schema_migrations WHERE key = ?\")\n .get(AI_MODE_MIGRATION);\n if (!aiModeMigration) {\n db.transaction(() => {\n db.query(\n `UPDATE api_topics\n SET\n kind = CASE\n WHEN id = ? THEN 'agent'\n WHEN kind = 'channel' AND agent IS NOT NULL AND ai_mention = 0 THEN 'agent'\n ELSE kind\n END,\n ai_mode = CASE\n WHEN id = ? THEN 'always'\n WHEN agent IS NULL THEN 'off'\n WHEN kind = 'agent' THEN 'always'\n WHEN kind = 'channel' AND ai_mention != 0 THEN 'mention'\n WHEN kind = 'channel' AND ai_mention = 0 THEN 'always'\n WHEN ai_mention != 0 THEN 'mention'\n ELSE 'always'\n END`,\n ).run(GENERAL_TOPIC_ID, GENERAL_TOPIC_ID);\n db.query(\"INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)\").run(\n AI_MODE_MIGRATION,\n new Date().toISOString(),\n );\n })();\n }\n\n const GENERAL_MANAGER_KIND_MIGRATION = \"api_topics_general_manager_kind_20260704\";\n const generalManagerKindMigration = db\n .query(\"SELECT key FROM api_schema_migrations WHERE key = ?\")\n .get(GENERAL_MANAGER_KIND_MIGRATION);\n if (!generalManagerKindMigration) {\n db.transaction(() => {\n db.query(\n \"UPDATE api_topics SET kind = 'manager', ai_mention = 0, ai_mode = 'always' WHERE id = ?\",\n ).run(GENERAL_TOPIC_ID);\n db.query(\"INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)\").run(\n GENERAL_MANAGER_KIND_MIGRATION,\n new Date().toISOString(),\n );\n })();\n }\n }\n\n function createCanonicalTopicsTable(name: string): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS ${name} (\n id TEXT PRIMARY KEY,\n title TEXT NOT NULL,\n kind TEXT NOT NULL CHECK (kind IN ('channel','agent','manager')),\n description TEXT,\n agent TEXT CHECK (agent IS NULL OR agent IN ('maestro','claude','codex')),\n base_model TEXT,\n base_effort TEXT CHECK (base_effort IS NULL OR base_effort IN ('low','medium','high','xhigh','max')),\n response_policy TEXT NOT NULL CHECK (response_policy IN ('off','mention','always')),\n created_at TEXT NOT NULL,\n last_message_at TEXT,\n parent_topic_id TEXT,\n memory_topic_id TEXT,\n memory_key TEXT,\n is_fork INTEGER NOT NULL DEFAULT 0 CHECK (is_fork IN (0,1)),\n is_subagent INTEGER NOT NULL DEFAULT 0 CHECK (is_subagent IN (0,1)),\n visibility TEXT NOT NULL DEFAULT 'visible' CHECK (visibility IN ('visible','hidden')),\n surface TEXT NOT NULL DEFAULT 'terminal' CHECK (surface IN ('terminal','telegram','otium')),\n surface_scope TEXT,\n browser_profile TEXT NOT NULL DEFAULT 'default',\n browser_profile_owner TEXT,\n session_id TEXT,\n CHECK (\n (kind = 'channel' AND response_policy = 'off' AND agent IS NULL) OR\n (kind = 'channel' AND response_policy = 'mention' AND agent IS NOT NULL) OR\n (kind IN ('agent','manager') AND response_policy = 'always' AND agent IS NOT NULL)\n )\n )\n `);\n }\n\n function createTopicMembersTable(): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS topic_members (\n topic_id TEXT NOT NULL REFERENCES api_topics(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL,\n role TEXT NOT NULL CHECK (role IN ('owner','member')),\n PRIMARY KEY (topic_id, user_id)\n )\n `);\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_topic_members_user ON topic_members(user_id)\");\n }\n\n if (needsCanonicalTopicRebuild) {\n const legacyRows = db.query(\"SELECT * FROM api_topics\").all() as Array<Record<string, unknown>>;\n const existingMemberRows = tableColumns(\"topic_members\").has(\"topic_id\")\n ? (db.query(\"SELECT topic_id, user_id, role FROM topic_members\").all() as Array<{\n topic_id: string;\n user_id: string;\n role: string;\n }>)\n : [];\n const configColumns = tableColumns(\"api_topic_config\");\n const legacyAgentOverrides = configColumns.has(\"agent\")\n ? new Map(\n (\n db\n .query(\"SELECT topic_id, agent FROM api_topic_config WHERE agent IS NOT NULL\")\n .all() as Array<{ topic_id: string; agent: AgentKind }>\n ).map((row) => [row.topic_id, row.agent]),\n )\n : new Map<string, AgentKind>();\n const previousForeignKeys = db\n .query<{ foreign_keys: number }, []>(\"PRAGMA foreign_keys\")\n .get()?.foreign_keys;\n db.exec(\"PRAGMA foreign_keys = OFF\");\n try {\n db.transaction(() => {\n createCanonicalTopicsTable(\"api_topics_next\");\n for (const row of legacyRows) {\n const selectedAgent = (legacyAgentOverrides.get(String(row.id)) ??\n row.agent ??\n row.runtime_agent ??\n row.default_agent ??\n undefined) as AgentKind | undefined;\n const normalized = normalizeTopicState({\n id: String(row.id),\n kind: normalizeTopicKind(row.kind),\n agent: selectedAgent,\n aiMode: normalizeAiMode(row.response_policy ?? row.ai_mode),\n aiMention: Number(row.ai_mention ?? 0) !== 0,\n });\n const legacyBaseModel = row.base_model ?? row.default_model;\n const legacyBaseEffort = row.base_effort ?? row.default_effort;\n db.query(\n `INSERT INTO api_topics_next\n (id,title,kind,description,agent,base_model,base_effort,response_policy,\n created_at,last_message_at,parent_topic_id,memory_topic_id,memory_key,is_fork,is_subagent,visibility,surface,surface_scope,session_id)\n VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,\n ).run(\n String(row.id),\n String(row.title),\n normalized.kind,\n typeof row.description === \"string\" ? row.description : null,\n normalized.agent ?? null,\n typeof legacyBaseModel === \"string\" ? legacyBaseModel : null,\n typeof legacyBaseEffort === \"string\" ? legacyBaseEffort : null,\n normalized.aiMode,\n String(row.created_at),\n typeof row.last_message_at === \"string\" ? row.last_message_at : null,\n typeof row.parent_topic_id === \"string\" ? row.parent_topic_id : null,\n typeof row.memory_topic_id === \"string\" ? row.memory_topic_id : null,\n typeof row.memory_key === \"string\" ? row.memory_key : null,\n Number(row.is_fork ?? 0) !== 0 ? 1 : 0,\n Number(row.is_subagent ?? 0) !== 0 ? 1 : 0,\n row.visibility === \"hidden\" ? \"hidden\" : \"visible\",\n row.surface === undefined ? defaultTopicSurface() : normalizeTopicSurface(row.surface),\n normalizeSurfaceScope(row.surface_scope),\n typeof row.session_id === \"string\" ? row.session_id : null,\n );\n }\n db.exec(\"DROP TABLE IF EXISTS topic_members\");\n db.exec(\"DROP TABLE api_topics\");\n db.exec(\"ALTER TABLE api_topics_next RENAME TO api_topics\");\n createTopicMembersTable();\n if (existingMemberRows.length > 0) {\n for (const member of existingMemberRows) {\n db.query(\n \"INSERT OR REPLACE INTO topic_members (topic_id,user_id,role) VALUES (?,?,?)\",\n ).run(member.topic_id, member.user_id, member.role === \"owner\" ? \"owner\" : \"member\");\n }\n } else {\n for (const row of legacyRows) {\n let participants: ParticipantDto[] = [];\n try {\n const parsed = JSON.parse(String(row.participants ?? \"[]\"));\n if (Array.isArray(parsed)) participants = parsed as ParticipantDto[];\n } catch {\n participants = [];\n }\n for (const participant of participants) {\n if (!participant?.userId) continue;\n db.query(\n \"INSERT OR REPLACE INTO topic_members (topic_id,user_id,role) VALUES (?,?,?)\",\n ).run(\n String(row.id),\n participant.userId,\n participant.role === \"owner\" ? \"owner\" : \"member\",\n );\n }\n }\n }\n })();\n } finally {\n db.exec(`PRAGMA foreign_keys = ${previousForeignKeys ? \"ON\" : \"OFF\"}`);\n }\n } else {\n createCanonicalTopicsTable(\"api_topics\");\n createTopicMembersTable();\n }\n\n db.exec(`\n CREATE TABLE IF NOT EXISTS subagent_tell_grants (\n subagent_topic_id TEXT NOT NULL REFERENCES api_topics(id) ON DELETE CASCADE,\n target_topic_id TEXT NOT NULL REFERENCES api_topics(id) ON DELETE CASCADE,\n granted_by_topic_id TEXT NOT NULL REFERENCES api_topics(id) ON DELETE CASCADE,\n created_at TEXT NOT NULL,\n PRIMARY KEY (subagent_topic_id, target_topic_id)\n )\n `);\n db.exec(`\n DELETE FROM subagent_tell_grants\n WHERE subagent_topic_id NOT IN (SELECT id FROM api_topics)\n OR target_topic_id NOT IN (SELECT id FROM api_topics)\n OR granted_by_topic_id NOT IN (SELECT id FROM api_topics)\n `);\n db.exec(\"DELETE FROM topic_members WHERE topic_id NOT IN (SELECT id FROM api_topics)\");\n\n // Canonical databases created before explicit adapter visibility need a\n // lightweight additive migration; fresh/rebuilt databases already have it.\n if (!tableColumns(\"api_topics\").has(\"visibility\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN visibility TEXT NOT NULL DEFAULT 'visible'\");\n }\n if (!tableColumns(\"api_topics\").has(\"surface\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN surface TEXT NOT NULL DEFAULT 'terminal'\");\n }\n if (!tableColumns(\"api_topics\").has(\"surface_scope\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN surface_scope TEXT\");\n }\n // `access_mode` was replaced by `surface`: a topic is reachable from Otium\n // because it lives there, not because a flag was flipped (S-4). Dropping the\n // column removes the second, now-contradictory source of truth.\n if (tableColumns(\"api_topics\").has(\"access_mode\")) {\n try {\n db.exec(\"ALTER TABLE api_topics DROP COLUMN access_mode\");\n } catch (err) {\n logger.warn({ err }, \"api_topics: could not drop the retired access_mode column\");\n }\n }\n if (!tableColumns(\"api_topics\").has(\"browser_profile\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN browser_profile TEXT NOT NULL DEFAULT 'default'\");\n }\n if (!tableColumns(\"api_topics\").has(\"browser_profile_owner\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN browser_profile_owner TEXT\");\n }\n if (!tableColumns(\"api_topics\").has(\"subagent_report_mode\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN subagent_report_mode TEXT NOT NULL DEFAULT 'auto'\");\n }\n if (!tableColumns(\"api_topics\").has(\"memory_topic_id\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN memory_topic_id TEXT\");\n }\n if (!tableColumns(\"api_topics\").has(\"memory_key\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN memory_key TEXT\");\n }\n db.exec(`\n UPDATE api_topics\n SET browser_profile_owner = (\n SELECT m.user_id FROM topic_members m\n WHERE m.topic_id = api_topics.id AND m.role = 'owner'\n ORDER BY m.rowid\n LIMIT 1\n )\n WHERE browser_profile_owner IS NULL\n`);\n backfillTopicSurfaces();\n db.exec(\n \"CREATE INDEX IF NOT EXISTS idx_api_topics_last_message ON api_topics(last_message_at DESC)\",\n );\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_api_topics_surface ON api_topics(surface)\");\n db.exec(\n \"CREATE INDEX IF NOT EXISTS idx_api_topics_surface_scope ON api_topics(surface, surface_scope)\",\n );\n}\n\nconst SURFACE_SCOPE_STAMP_MIGRATION = \"api_topics_surface_scope_stamp_20260809\";\n\n/**\n * M-9 — file every pre-existing Otium room under the workspace attached now.\n *\n * Deliberately *not* a schema-init step. The scope is only knowable after the\n * first successful Central contact (M-3), which happens long after the store\n * opens; a boot-time migration would see no scope, record itself as applied and\n * leave every room unstamped forever. The Otium runtime calls this instead, once,\n * as soon as it has resolved its workspace.\n *\n * Runs at most once per store: rooms created after this point are stamped at\n * creation, and a second workspace joined later must not swallow the first\n * one's rooms. Unlike the surface migration this can never rename anything —\n * the scope enters the uniqueness key in the same release, so nothing can start\n * colliding because of it.\n */\nexport function stampUnscopedOtiumTopics(scope: string): number {\n const normalized = normalizeSurfaceScope(scope);\n if (!normalized) return 0;\n db.exec(`\n CREATE TABLE IF NOT EXISTS api_schema_migrations (\n key TEXT PRIMARY KEY,\n applied_at TEXT NOT NULL\n )\n`);\n const applied = db\n .query(\"SELECT key FROM api_schema_migrations WHERE key = ?\")\n .get(SURFACE_SCOPE_STAMP_MIGRATION);\n if (applied) return 0;\n\n let stamped = 0;\n db.transaction(() => {\n stamped = Number(\n db\n .query(\n \"UPDATE api_topics SET surface_scope = ? WHERE surface = 'otium' AND surface_scope IS NULL\",\n )\n .run(normalized).changes ?? 0,\n );\n db.query(\"INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)\").run(\n SURFACE_SCOPE_STAMP_MIGRATION,\n new Date().toISOString(),\n );\n })();\n if (stamped > 0) {\n logger.info({ scope: normalized, stamped }, \"api_topics: surface scope stamped\");\n }\n return stamped;\n}\n\nconst SURFACE_BACKFILL_MIGRATION = \"api_topics_surface_backfill_20260808\";\n\n/**\n * One-time classification of pre-surface topics.\n *\n * Every row predates the column, so there is no per-row evidence in this store\n * to distinguish surfaces — the host declares it (`NEGOTIUM_DEFAULT_SURFACE`).\n * The telegram adapter owns the second pass: its chat↔topic mapping lives in a\n * different database file, so only it can reclassify the rooms it created.\n *\n * Names are unique per surface from now on, so collapsing three namespaces into\n * one can produce duplicates. Rather than failing the boot, the oldest room\n * keeps the name and the rest are suffixed — a rename is recoverable, a node\n * that refuses to start is not.\n */\nfunction backfillTopicSurfaces(): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS api_schema_migrations (\n key TEXT PRIMARY KEY,\n applied_at TEXT NOT NULL\n )\n`);\n const applied = db\n .query(\"SELECT key FROM api_schema_migrations WHERE key = ?\")\n .get(SURFACE_BACKFILL_MIGRATION);\n if (applied) return;\n\n const surface = defaultTopicSurface();\n db.transaction(() => {\n db.query(\"UPDATE api_topics SET surface = ?\").run(surface);\n renameSurfaceTitleCollisions();\n db.query(\"INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)\").run(\n SURFACE_BACKFILL_MIGRATION,\n new Date().toISOString(),\n );\n })();\n logger.info({ surface }, \"api_topics: surface backfilled\");\n}\n\n/**\n * Suffix duplicate `(surface, kind, title)` rows so the new uniqueness rule holds.\n *\n * Manager rooms are excluded: they are one per user, so on a multi-user host\n * every member has a personal room with the same title and none of them is a\n * duplicate. Renaming those relabels real rooms belonging to other people.\n */\nfunction renameSurfaceTitleCollisions(): void {\n const rows = db\n .query<{ id: string; title: string; kind: string; surface: string }, []>(\n \"SELECT id, title, kind, surface FROM api_topics WHERE kind != 'manager' ORDER BY created_at ASC, rowid ASC\",\n )\n .all();\n const keyOf = (surface: string, kind: string, title: string) =>\n [surface, kind, normalizedTitle(title)].join(\"\\u0000\");\n // Every original title is reserved up front. Allocating only against the\n // titles seen so far would let an earlier duplicate claim \"Foo (2)\" while a\n // real room already named \"Foo (2)\" sits later in the scan — that room would\n // then be pushed to \"Foo (2) (2)\" for no reason.\n const reserved = new Set(rows.map((row) => keyOf(row.surface, row.kind, row.title)));\n const used = new Set<string>();\n const update = db.query(\"UPDATE api_topics SET title = ? WHERE id = ?\");\n for (const row of rows) {\n const key = (title: string) => keyOf(row.surface, row.kind, title);\n if (!used.has(key(row.title))) {\n used.add(key(row.title));\n continue;\n }\n let suffix = 2;\n let candidate = `${row.title} (${suffix})`;\n while (reserved.has(key(candidate)) || used.has(key(candidate))) {\n suffix += 1;\n candidate = `${row.title} (${suffix})`;\n }\n used.add(key(candidate));\n update.run(candidate, row.id);\n logger.warn(\n { topicId: row.id, surface: row.surface, from: row.title, to: candidate },\n \"api_topics: renamed a duplicate title for surface-scoped uniqueness\",\n );\n }\n}\n\nregisterStorageSchemaInitializer(initializeApiTopicsSchema, 20);\n\nexport interface TopicRow {\n id: string;\n title: string;\n kind: string | null;\n description: string | null;\n agent: string | null;\n base_model: string | null;\n base_effort: string | null;\n response_policy: string;\n created_at: string;\n last_message_at: string | null;\n parent_topic_id: string | null;\n memory_topic_id: string | null;\n memory_key: string | null;\n is_fork: number;\n is_subagent: number;\n subagent_report_mode: string | null;\n visibility: string | null;\n surface: string | null;\n surface_scope: string | null;\n browser_profile_owner: string | null;\n session_id: string | null;\n}\n\nexport interface TopicSessionLogContext {\n reason?: string;\n queryId?: string;\n agent?: AgentKind;\n}\n\nfunction shortSessionId(sessionId: string | null | undefined): string | null {\n return sessionId ? sessionId.slice(0, 8) : null;\n}\n\nfunction getTopicParticipants(topicId: string): ParticipantDto[] {\n return db\n .query<{ user_id: string; role: \"owner\" | \"member\" }, string>(\n \"SELECT user_id, role FROM topic_members WHERE topic_id = ? ORDER BY rowid\",\n )\n .all(topicId)\n .map((row) => ({ userId: row.user_id, role: row.role }));\n}\n\nfunction getAllTopicParticipants(): Map<string, ParticipantDto[]> {\n const grouped = new Map<string, ParticipantDto[]>();\n const rows = db\n .query<{ topic_id: string; user_id: string; role: \"owner\" | \"member\" }, []>(\n \"SELECT topic_id, user_id, role FROM topic_members ORDER BY rowid\",\n )\n .all();\n for (const row of rows) {\n const participants = grouped.get(row.topic_id) ?? [];\n participants.push({ userId: row.user_id, role: row.role });\n grouped.set(row.topic_id, participants);\n }\n return grouped;\n}\n\nfunction getAllSubagentTellTargets(): Map<string, string[]> {\n const rows = db\n .query(\n \"SELECT subagent_topic_id, target_topic_id FROM subagent_tell_grants ORDER BY created_at\",\n )\n .all() as Array<{ subagent_topic_id: string; target_topic_id: string }>;\n const grouped = new Map<string, string[]>();\n for (const row of rows) {\n const targets = grouped.get(row.subagent_topic_id) ?? [];\n targets.push(row.target_topic_id);\n grouped.set(row.subagent_topic_id, targets);\n }\n return grouped;\n}\n\nfunction rowToDto(\n r: TopicRow,\n participants = getTopicParticipants(r.id),\n tellTargets?: Map<string, string[]>,\n): TopicDto {\n const normalized = normalizeTopicState({\n id: r.id,\n kind: normalizeTopicKind(r.kind),\n agent: (r.agent as AgentKind | null) ?? undefined,\n aiMode: normalizeAiMode(r.response_policy),\n });\n return {\n id: r.id,\n title: r.title,\n kind: normalized.kind,\n description: r.description ?? undefined,\n agent: normalized.agent,\n defaultModel: r.base_model ?? \"deepseek-pro\",\n defaultEffort: (r.base_effort as EffortLevel) ?? undefined,\n aiMode: normalized.aiMode,\n aiMention: aiMentionFromMode(normalized.aiMode),\n participants,\n createdAt: r.created_at,\n lastMessageAt: r.last_message_at ?? new Date().toISOString(),\n parentTopicId: r.parent_topic_id ?? undefined,\n memoryTopicId: r.memory_topic_id ?? undefined,\n memoryKey: r.memory_key ?? undefined,\n isFork: r.is_fork !== 0,\n ...(r.is_subagent !== 0 ? { isSubagent: true } : {}),\n ...(r.is_subagent !== 0\n ? {\n subagentTellTargetIds: tellTargets\n ? (tellTargets.get(r.id) ?? [])\n : listSubagentTellTargetIds(r.id),\n }\n : {}),\n ...(r.is_subagent !== 0\n ? {\n subagentReportMode: (r.subagent_report_mode === \"tell\" ||\n r.subagent_report_mode === \"status-only\"\n ? r.subagent_report_mode\n : \"auto\") as SubagentReportMode,\n }\n : {}),\n visibility: normalizeTopicVisibility(r.visibility),\n surface: normalizeTopicSurface(r.surface),\n surfaceScope: normalizeSurfaceScope(r.surface_scope),\n };\n}\n\nexport function normalizeTopicVisibility(value: unknown): TopicVisibility {\n return value === \"hidden\" ? \"hidden\" : \"visible\";\n}\n\n/** Discovery boundary shared by user-facing adapters. */\nexport function isTopicVisible(topic: Pick<TopicDto, \"visibility\">): boolean {\n return topic.visibility !== \"hidden\";\n}\n\nexport function normalizeTopicKind(value: unknown): TopicKind | null {\n return value === \"channel\" || value === \"agent\" || value === \"manager\" ? value : null;\n}\n\nexport function normalizeAiMode(value: unknown): AiMode | null {\n return value === \"off\" || value === \"mention\" || value === \"always\" ? value : null;\n}\n\nexport function aiMentionFromMode(mode: AiMode): boolean {\n return mode === \"mention\";\n}\n\nexport function inferTopicKind(input: {\n agent?: string | null;\n aiMention?: boolean | null;\n}): TopicKind {\n return input.agent && input.aiMention !== true ? \"agent\" : \"channel\";\n}\n\nexport function inferAiMode(input: {\n kind?: TopicKind | null;\n agent?: string | null;\n aiMode?: AiMode | null;\n aiMention?: boolean | null;\n}): AiMode {\n if (input.kind === \"manager\") return \"always\";\n if (input.kind === \"agent\") return \"always\";\n if (input.kind === \"channel\") {\n if (!input.agent) return \"off\";\n if (input.aiMode === \"mention\") return \"mention\";\n if (input.aiMention === true) return \"mention\";\n return \"mention\";\n }\n if (!input.agent) return \"off\";\n if (input.aiMode) return input.aiMode;\n return input.aiMention === true ? \"mention\" : \"always\";\n}\n\nexport function normalizeTopicState(input: {\n id?: string;\n kind?: TopicKind | null;\n agent?: AgentKind | null;\n aiMode?: AiMode | null;\n aiMention?: boolean | null;\n}): { kind: TopicKind; aiMode: AiMode; agent?: AgentKind } {\n if (input.kind === \"manager\" || input.id === GENERAL_TOPIC_ID) {\n return {\n kind: \"manager\",\n aiMode: \"always\",\n agent: input.agent ?? resolveFallbackAgent(),\n };\n }\n\n const requestedKind = input.kind;\n const kind =\n requestedKind ??\n (input.aiMode === \"always\"\n ? \"agent\"\n : input.aiMode === \"mention\" || input.aiMode === \"off\"\n ? \"channel\"\n : input.agent && input.aiMention !== true\n ? \"agent\"\n : \"channel\");\n\n if (kind === \"agent\") {\n return {\n kind: \"agent\",\n aiMode: \"always\",\n agent: input.agent ?? resolveFallbackAgent(),\n };\n }\n\n const agent = input.aiMode === \"off\" ? undefined : (input.agent ?? undefined);\n return {\n kind: \"channel\",\n aiMode: agent ? \"mention\" : \"off\",\n agent,\n };\n}\n\nfunction normalizedTitle(title: string): string {\n return title.trim().toLowerCase();\n}\n\n/**\n * The workspace a written row belongs to.\n *\n * `surfaceScope` partitions one surface into independent namespaces. Otium\n * uses a workspace scope and Telegram uses a forum-group scope. Terminal is\n * normally unscoped. An explicit value always wins; only Otium has a\n * process-level default because its workspace attachment is host state.\n */\nfunction surfaceScopeForWrite(t: TopicDto): string | null {\n if (t.surfaceScope !== undefined) return normalizeSurfaceScope(t.surfaceScope);\n return normalizeTopicSurface(t.surface ?? defaultTopicSurface()) === \"otium\"\n ? defaultSurfaceScope()\n : null;\n}\n\nexport function upsertTopic(t: TopicDto): void {\n const normalized = normalizeTopicState({\n id: t.id,\n kind: normalizeTopicKind(t.kind),\n agent: t.agent ?? undefined,\n aiMode: normalizeAiMode(t.aiMode),\n aiMention: t.aiMention,\n });\n db.transaction(() => {\n db.query(\n `INSERT INTO api_topics\n (id,title,kind,description,agent,base_model,base_effort,response_policy,\n created_at,last_message_at,parent_topic_id,memory_topic_id,memory_key,is_fork,is_subagent,visibility,surface,\n surface_scope,subagent_report_mode)\n VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)\n ON CONFLICT(id) DO UPDATE SET\n title = excluded.title,\n kind = excluded.kind,\n description = excluded.description,\n agent = excluded.agent,\n base_model = excluded.base_model,\n base_effort = excluded.base_effort,\n response_policy = excluded.response_policy,\n created_at = excluded.created_at,\n last_message_at = excluded.last_message_at,\n parent_topic_id = excluded.parent_topic_id,\n memory_topic_id = excluded.memory_topic_id,\n memory_key = excluded.memory_key,\n is_fork = excluded.is_fork,\n is_subagent = excluded.is_subagent,\n visibility = excluded.visibility,\n surface = excluded.surface,\n -- A room's workspace is fixed at creation (M-1). COALESCE, not\n -- assignment: an update may fill in a scope that was unknown when the\n -- room was created, but may never move a room to another workspace.\n surface_scope = COALESCE(api_topics.surface_scope, excluded.surface_scope),\n subagent_report_mode = excluded.subagent_report_mode`,\n ).run(\n t.id,\n t.title,\n normalized.kind,\n t.description ?? null,\n normalized.agent ?? null,\n t.defaultModel ?? null,\n t.defaultEffort ?? null,\n normalized.aiMode,\n t.createdAt,\n t.lastMessageAt ?? null,\n t.parentTopicId ?? null,\n t.memoryTopicId ?? null,\n t.memoryKey ?? null,\n t.isFork ? 1 : 0,\n t.isSubagent ? 1 : 0,\n normalizeTopicVisibility(t.visibility),\n // A DTO without a surface means \"wherever this host puts rooms\", not\n // \"terminal\": embedding hosts (Otium) build topic literals by hand and\n // never name one, so defaulting to the literal would file every hub room\n // on the wrong surface.\n normalizeTopicSurface(t.surface ?? defaultTopicSurface()),\n surfaceScopeForWrite(t),\n t.subagentReportMode ?? \"auto\",\n );\n db.query(\"DELETE FROM topic_members WHERE topic_id = ?\").run(t.id);\n for (const participant of t.participants) {\n db.query(\"INSERT INTO topic_members (topic_id,user_id,role) VALUES (?,?,?)\").run(\n t.id,\n participant.userId,\n participant.role,\n );\n }\n const initialBrowserProfileOwner = t.participants.find(\n (participant) => participant.role === \"owner\",\n )?.userId;\n if (initialBrowserProfileOwner) {\n db.query(\n `UPDATE api_topics\n SET browser_profile_owner = COALESCE(browser_profile_owner, ?)\n WHERE id = ?`,\n ).run(initialBrowserProfileOwner, t.id);\n }\n })();\n}\n\n/**\n * List topics, optionally restricted to one surface.\n *\n * The filter lives here rather than in each adapter so a forgotten call site\n * cannot leak a telegram room into the terminal picker; adapters pass their own\n * surface and get a closed world back.\n */\nexport function listTopics(\n opts: { surface?: TopicSurface; surfaceScope?: string | null } = {},\n): TopicDto[] {\n // `surfaceScope: null` is a real filter (\"the unscoped rooms\"), so presence —\n // not truthiness — decides whether the scope narrows the query at all.\n const scoped = Object.hasOwn(opts, \"surfaceScope\");\n const rows = (\n opts.surface\n ? db\n .query(\n `SELECT * FROM api_topics WHERE surface = ?${scoped ? \" AND surface_scope IS ?\" : \"\"} ORDER BY last_message_at DESC`,\n )\n .all(\n ...(scoped\n ? [normalizeTopicSurface(opts.surface), normalizeSurfaceScope(opts.surfaceScope)]\n : [normalizeTopicSurface(opts.surface)]),\n )\n : db.query(\"SELECT * FROM api_topics ORDER BY last_message_at DESC\").all()\n ) as TopicRow[];\n const participants = getAllTopicParticipants();\n // Batch-load tell grants once: per-row queries would make every listTopics()\n // call O(N) extra statements as subagent counts grow.\n const tellTargets = rows.some((row) => row.is_subagent !== 0)\n ? getAllSubagentTellTargets()\n : undefined;\n return rows.map((row) => rowToDto(row, participants.get(row.id) ?? [], tellTargets));\n}\n\nexport function getTopic(id: string): TopicDto | null {\n const r = db.query(\"SELECT * FROM api_topics WHERE id = ?\").get(id) as TopicRow | undefined;\n return r ? rowToDto(r) : null;\n}\n\n/** Return the private manager room owned by a user, excluding the retired shared General row. */\n/**\n * The user's own manager room, optionally on one surface.\n *\n * A manager room is one per user **per surface**: Terminal and Telegram each\n * give the same person their own personal room, and returning one surface's\n * room to the other adapter lets that adapter bind to — and reclassify — a room\n * belonging to a different surface. Callers that represent an adapter pass\n * theirs; unscoped lookups stay for maintenance paths that work by user alone.\n */\nexport function getManagerTopicForUser(\n userId: string,\n surface?: TopicSurface,\n opts: { surfaceScope?: string | null } = {},\n): TopicDto | null {\n const scoped = Object.hasOwn(opts, \"surfaceScope\");\n const sql = `SELECT t.* FROM api_topics t\n JOIN topic_members m ON m.topic_id = t.id\n WHERE t.kind = 'manager'\n AND t.id != ?\n AND m.user_id = ?\n AND m.role = 'owner'\n ${surface ? \"AND t.surface = ?\" : \"\"}\n ${scoped ? \"AND t.surface_scope IS ?\" : \"\"}\n ORDER BY t.created_at ASC\n LIMIT 1`;\n const params: Array<string | null> = [GENERAL_TOPIC_ID, userId];\n if (surface) params.push(surface);\n if (scoped) params.push(normalizeSurfaceScope(opts.surfaceScope));\n const row = db.query<TopicRow, Array<string | null>>(sql).get(...params);\n return row ? rowToDto(row) : null;\n}\n\n/**\n * Resolve the topic whose wiki memory should be used for this topic.\n *\n * Derived rooms keep `parentTopicId` as an immediate UI link. Memory normally\n * follows the chain to its original root, while `memoryTopicId` can redirect a\n * subagent to another accessible topic's accumulated knowledge.\n */\nexport function getTopicMemoryOrigin(id: string): TopicDto | null {\n let current = getTopic(id);\n if (!current) return null;\n\n const seen = new Set<string>([current.id]);\n while (true) {\n const nextId = current.memoryTopicId ?? current.parentTopicId;\n if (!nextId || seen.has(nextId)) break;\n const next = getTopic(nextId);\n if (!next) {\n // An explicitly selected memory topic that no longer resolves must not\n // silently fall back to the parent chain — that would leak the parent\n // room's memory to a subagent that asked for something else. Stop at the\n // current topic instead so the broken source is visible.\n if (current.memoryTopicId) {\n console.warn(\n `[topics] memory topic ${current.memoryTopicId} for ${current.id} is unresolvable; using the topic's own memory`,\n );\n }\n break;\n }\n current = next;\n seen.add(current.id);\n }\n\n return current;\n}\n\n/** Look up a topic by its user-visible title (case-insensitive exact match). */\nexport function getTopicByName(title: string): TopicDto | null {\n const r = db.query(\"SELECT * FROM api_topics WHERE LOWER(title) = LOWER(?)\").get(title) as\n | TopicRow\n | undefined;\n return r ? rowToDto(r) : null;\n}\n\nexport function getTopicByNameAndKind(title: string, kind: TopicKind): TopicDto | null {\n const r = db\n .query(\"SELECT * FROM api_topics WHERE LOWER(title) = LOWER(?) AND kind = ?\")\n .get(title, kind) as TopicRow | undefined;\n return r ? rowToDto(r) : null;\n}\n\n/**\n * Titles are unique **per surface namespace**, not per node: the same title may\n * exist on terminal, in multiple Telegram groups, and in each attached Otium\n * workspace. Independent namespaces never see each other, so a name taken in\n * one says nothing about another.\n */\nexport function findTopicTitleConflict(\n title: string,\n kind: TopicKind,\n opts: { excludeTopicId?: string; surface?: TopicSurface; surfaceScope?: string | null } = {},\n): TopicDto | null {\n const wanted = normalizedTitle(title);\n const surface = normalizeTopicSurface(opts.surface ?? defaultTopicSurface());\n const surfaceScope = Object.hasOwn(opts, \"surfaceScope\")\n ? normalizeSurfaceScope(opts.surfaceScope)\n : surface === \"otium\"\n ? defaultSurfaceScope()\n : null;\n const generalTitleRequested = wanted === normalizedTitle(GENERAL_TOPIC_ID);\n if (generalTitleRequested && opts.excludeTopicId !== GENERAL_TOPIC_ID) {\n const general = db.query(\"SELECT * FROM api_topics WHERE id = ?\").get(GENERAL_TOPIC_ID) as\n | TopicRow\n | undefined;\n if (general) return rowToDto(general);\n }\n\n // Manager rooms are one-per-user and system-created, so several of them\n // legitimately share a title (every member's personal \"General\"). Comparing\n // them against each other is not a conflict, it is the design — on a\n // multi-user host it renamed real rooms out from under their owners.\n if (kind === \"manager\") return null;\n\n const params: Array<string | null> = [wanted, surface, surfaceScope, kind, GENERAL_TOPIC_ID];\n let sql =\n \"SELECT * FROM api_topics WHERE LOWER(TRIM(title)) = ? AND surface = ? AND surface_scope IS ? AND (kind = ? OR id = ?)\";\n if (opts.excludeTopicId) {\n sql += \" AND id != ?\";\n params.push(opts.excludeTopicId);\n }\n sql += \" LIMIT 1\";\n const row = db.query<TopicRow, string[]>(sql).get(...params);\n return row ? rowToDto(row) : null;\n}\n\n/**\n * Move topics onto a surface. Used by adapters that own a classification the\n * canonical store cannot derive on its own (the telegram chat↔topic mapping\n * lives in that adapter's database, not this one).\n */\nexport function setTopicSurfaces(topicIds: readonly string[], surface: TopicSurface): number {\n if (topicIds.length === 0) return 0;\n const normalized = normalizeTopicSurface(surface);\n let changed = 0;\n db.transaction(() => {\n const update = db.query(\"UPDATE api_topics SET surface = ? WHERE id = ? AND surface != ?\");\n for (const topicId of topicIds) {\n changed += Number(update.run(normalized, topicId, normalized).changes ?? 0);\n }\n })();\n return changed;\n}\n\n/**\n * File an existing topic into one surface namespace without changing its id.\n * Adapter-owned migrations use this when their local mapping store is the only\n * authority capable of deriving the namespace (for example Telegram chat id).\n */\nexport function setTopicSurfaceScope(\n topicId: string,\n surface: TopicSurface,\n surfaceScope: string | null,\n): boolean {\n const normalizedSurface = normalizeTopicSurface(surface);\n const normalizedScope = normalizeSurfaceScope(surfaceScope);\n const result = db\n .query(\n `UPDATE api_topics SET surface = ?, surface_scope = ?\n WHERE id = ? AND (surface IS NOT ? OR surface_scope IS NOT ?)`,\n )\n .run(normalizedSurface, normalizedScope, topicId, normalizedSurface, normalizedScope);\n return Number(result.changes ?? 0) > 0;\n}\n\n/**\n * How wide a title lookup is allowed to reach.\n *\n * `surface` is required rather than optional. It used to default to \"search\n * every surface\", which contradicted S-6's promise that a missed call site\n * \"cannot leak a topic across surfaces\" — the guarantee only held where a\n * caller remembered to opt in, and four did not: Telegram's `/load` and `/del`\n * (the latter could delete a terminal room), the runtime MCP id path, the cron\n * id path, and the session inbox. Every one of those was a silent leak with a\n * correct-looking call. Making the parameter explicit turns each future\n * omission into a compile error instead.\n *\n * `{ scope: \"all\" }` is the deliberate way to search every surface. It exists\n * for operator tooling — the CLI manages jobs across surfaces on purpose — and\n * reads as a decision at the call site rather than as an oversight.\n */\nexport type TopicNameLookupScope =\n | { surface: TopicSurface; surfaceScope?: string | null }\n | { scope: \"all\" };\n\n/**\n * Look up a topic by title, restricted to topics where `userId` participates.\n *\n * Answers only on a single match: a title is unique per surface (S-3), so an\n * `{ scope: \"all\" }` lookup of a name used on two surfaces resolves to null\n * rather than picking one.\n */\nexport function getTopicByNameForUser(\n title: string,\n userId: string,\n lookupScope: TopicNameLookupScope,\n): TopicDto | null {\n const opts: { surface?: TopicSurface; surfaceScope?: string | null } =\n \"scope\" in lookupScope ? {} : lookupScope;\n const trimmed = title.trim();\n const qualified = /^(agent|channel|manager):(.+)$/i.exec(trimmed);\n const requestedKind = qualified ? normalizeTopicKind(qualified[1]?.toLowerCase()) : null;\n const requestedTitle = qualified ? qualified[2]!.trim() : trimmed;\n const scoped = Object.hasOwn(opts, \"surfaceScope\");\n const rows = db\n .query(\n `SELECT t.* FROM api_topics t\n WHERE LOWER(t.title) = LOWER(?)\n AND t.id != ?\n AND t.visibility != 'hidden'\n AND (? IS NULL OR t.surface = ?)\n ${scoped ? \"AND t.surface_scope IS ?\" : \"\"}\n AND EXISTS (\n SELECT 1 FROM topic_members m WHERE m.topic_id = t.id AND m.user_id = ?\n )`,\n )\n .all(\n requestedTitle,\n GENERAL_TOPIC_ID,\n opts.surface ?? null,\n opts.surface ?? null,\n ...(scoped ? [normalizeSurfaceScope(opts.surfaceScope)] : []),\n userId,\n ) as TopicRow[];\n const matches = requestedKind ? rows.filter((row) => row.kind === requestedKind) : rows;\n return matches.length === 1 ? rowToDto(matches[0]!) : null;\n}\n\n/** Persist the agent session ID for a topic after a successful turn. */\nexport function setTopicSessionId(\n topicId: string,\n sessionId: string,\n context: TopicSessionLogContext = {},\n): void {\n const previous = getTopicSessionId(topicId);\n const result = db\n .query(\"UPDATE api_topics SET session_id = ? WHERE id = ?\")\n .run(sessionId, topicId);\n const changes = Number(result.changes ?? 0);\n const logContext = {\n topicId,\n previousSessionId: shortSessionId(previous),\n sessionId: shortSessionId(sessionId),\n reason: context.reason,\n queryId: context.queryId,\n agent: context.agent,\n };\n if (changes === 0) {\n logger.warn(logContext, \"api-topic session_id update missed topic\");\n } else if (previous !== sessionId) {\n logger.debug(logContext, \"api-topic session_id updated\");\n } else {\n logger.debug(logContext, \"api-topic session_id unchanged\");\n }\n}\n\n/** Clear the session ID (e.g. on topic reset). */\nexport function clearTopicSessionId(topicId: string, reason = \"unspecified\"): void {\n const previous = getTopicSessionId(topicId);\n const result = db.query(\"UPDATE api_topics SET session_id = NULL WHERE id = ?\").run(topicId);\n const changes = Number(result.changes ?? 0);\n const logContext = { topicId, previousSessionId: shortSessionId(previous), reason };\n if (changes === 0) {\n logger.warn(logContext, \"api-topic session_id clear missed topic\");\n } else if (previous) {\n logger.info(logContext, \"api-topic session_id cleared\");\n } else {\n logger.debug(logContext, \"api-topic session_id already clear\");\n }\n}\n\n/** Read the persisted session ID for a topic, or null if none. */\nexport function getTopicSessionId(topicId: string): string | null {\n const r = db\n .query<{ session_id: string | null }, string>(\"SELECT session_id FROM api_topics WHERE id = ?\")\n .get(topicId);\n return r?.session_id ?? null;\n}\n\n/**\n * Hard-delete a topic row. Irreversible — the caller is responsible for also\n * deleting the topic's messages (see `deleteMessagesForTopic`). Returns false\n * if the topic didn't exist.\n */\nexport function deleteTopic(id: string, options: { allowManager?: boolean } = {}): boolean {\n const r = db\n .query<{ id: string; kind: string }, string>(\"SELECT id, kind FROM api_topics WHERE id = ?\")\n .get(id);\n if (!r) return false;\n if (id === GENERAL_TOPIC_ID || (r.kind === \"manager\" && !options.allowManager)) return false;\n db.query(\n `DELETE FROM subagent_tell_grants\n WHERE subagent_topic_id = ? OR target_topic_id = ? OR granted_by_topic_id = ?`,\n ).run(id, id, id);\n db.query(\"DELETE FROM topic_members WHERE topic_id = ?\").run(id);\n db.query(\"DELETE FROM api_topics WHERE id = ?\").run(id);\n return true;\n}\n\nexport function listSubagentTellTargetIds(subagentTopicId: string): string[] {\n return db\n .query<{ target_topic_id: string }, string>(\n \"SELECT target_topic_id FROM subagent_tell_grants WHERE subagent_topic_id = ? ORDER BY created_at\",\n )\n .all(subagentTopicId)\n .map((row) => row.target_topic_id);\n}\n\nexport function grantSubagentTellTarget(\n subagentTopicId: string,\n targetTopicId: string,\n grantedByTopicId: string,\n): void {\n db.query(\n `INSERT INTO subagent_tell_grants\n (subagent_topic_id,target_topic_id,granted_by_topic_id,created_at)\n VALUES (?,?,?,?)\n ON CONFLICT(subagent_topic_id,target_topic_id) DO UPDATE SET\n granted_by_topic_id = excluded.granted_by_topic_id`,\n ).run(subagentTopicId, targetTopicId, grantedByTopicId, new Date().toISOString());\n}\n\nexport function revokeSubagentTellTarget(subagentTopicId: string, targetTopicId: string): boolean {\n return (\n db\n .query(\"DELETE FROM subagent_tell_grants WHERE subagent_topic_id = ? AND target_topic_id = ?\")\n .run(subagentTopicId, targetTopicId).changes > 0\n );\n}\n\n/**\n * Preserve a derived-topic chain when an intermediate parent is deleted.\n * Direct children move to the deleted topic's parent (or become roots) rather\n * than retaining a dangling parent id that would break memory-origin lookup.\n */\nexport function reparentTopicChildren(\n deletedTopicId: string,\n replacementParentTopicId: string | null,\n): string[] {\n const rows = db\n .query<{ id: string }, string>(\"SELECT id FROM api_topics WHERE parent_topic_id = ?\")\n .all(deletedTopicId);\n if (rows.length === 0) return [];\n db.query(\"UPDATE api_topics SET parent_topic_id = ? WHERE parent_topic_id = ?\").run(\n replacementParentTopicId,\n deletedTopicId,\n );\n // Reparenting can move a topic out of the subtree whose manager granted its\n // tell edges; purge involved grants (fail closed) — an ancestor can re-grant.\n for (const row of rows) {\n db.query(\n \"DELETE FROM subagent_tell_grants WHERE subagent_topic_id = ? OR target_topic_id = ?\",\n ).run(row.id, row.id);\n }\n return rows.map((row) => row.id);\n}\n\nexport function addParticipantToDB(\n topicId: string,\n userId: string,\n role: \"member\" | \"owner\",\n): boolean {\n if (!db.query(\"SELECT 1 FROM api_topics WHERE id = ?\").get(topicId)) return false;\n db.query(\"INSERT OR IGNORE INTO topic_members (topic_id,user_id,role) VALUES (?,?,?)\").run(\n topicId,\n userId,\n role,\n );\n return true;\n}\n\nexport function removeParticipantFromDB(topicId: string, userId: string): boolean {\n if (!db.query(\"SELECT 1 FROM api_topics WHERE id = ?\").get(topicId)) return false;\n db.query(\"DELETE FROM topic_members WHERE topic_id = ? AND user_id = ?\").run(topicId, userId);\n return true;\n}\n",
29
- "import { accessSync, constants as fsConstants } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { canonicalMcpBridgeEnv } from \"#mcp/canonical-bridge-config\";\nimport {\n buildHostedMcpSpec,\n buildRuntimeMcpSpec,\n type HostedMcpSurface,\n RUNTIME_MCP_KEY,\n} from \"#mcp/runtime-spec\";\nimport { peerSessionBridgeIpcEnv } from \"#mcp/session-comm/bridge-ipc-config\";\nimport { bgBashContextCapability } from \"#platform/background-bash/manager\";\nimport {\n AGENT_HEALTH_SERVER,\n CANONICAL_MCP_PROXY_SERVER,\n DECISION_SERVER,\n envText,\n FALLBACK_AGENT,\n resolveTopicWorkspaceDir,\n SESSION_COMM_SERVER,\n SYSTEM_HEALTH_SERVER,\n TASK_SERVER,\n TOKEN_STATS_SERVER,\n TSCONFIG_PATH,\n TSX_LOADER,\n VAULT_SERVER,\n WIKI_SERVER,\n} from \"#platform/config\";\nimport { logger } from \"#platform/logger\";\nimport {\n classifyForumMcpServers,\n commonRuntimeMcpPolicy,\n type RuntimeMcpScope,\n} from \"#platform/mcp-catalog-policy\";\nimport { browserOwnerCapability } from \"#platform/playwright/capability\";\nimport {\n buildPlaywrightMcpTransport,\n CODEX_BROWSER_CAPABILITY_ENV,\n} from \"#platform/playwright/mcp-transport\";\nimport { getRegisteredCronSession } from \"#runtime/cron-sessions\";\nimport type { HostMcpServerSpec } from \"#runtime-gateway\";\nimport { getTopic } from \"#storage/api-topics\";\nimport type { AgentKind, AgentQueryOptions, PeerRuntimeBridgeContext } from \"#types\";\n\nexport type { RuntimeMcpScope } from \"#platform/mcp-catalog-policy\";\n\n/**\n * Build the stdio transport spec for a Otium MCP server entry.\n *\n * claude/maestro launch the .ts server directly with `bun run` (fast, native\n * TypeScript + bun:sqlite). codex CANNOT — codex 0.135's rmcp stdio client\n * fails to handshake with bun-spawned servers (initialize is dropped/raced, so\n * no tools reach the model), while pure-node servers connect reliably. So for\n * the `codex` agent we launch the SAME server file via node + tsx, passing the\n * tsconfig explicitly (servers run with cwd ≠ PROJECT_ROOT, so tsx can't find\n * it on its own) so `@/*` path aliases resolve. Per-turn agent-aware config\n * means switching agents mid-topic just works: each turn re-spawns with the\n * right runtime.\n */\nexport function buildStdioMcpServer(\n agent: AgentKind | undefined,\n serverFile: string,\n serverArgs: string[],\n env?: Record<string, string>,\n): Record<string, unknown> {\n if (agent === \"codex\") {\n return {\n command: \"node\",\n args: [\"--import\", TSX_LOADER, serverFile, ...serverArgs],\n // Merged onto codex's inherited env (not a replacement) — verified.\n env: { TSX_TSCONFIG_PATH: TSCONFIG_PATH, ...env },\n };\n }\n return {\n command: \"bun\",\n args: [\"run\", serverFile, ...serverArgs],\n ...(env ? { env } : {}),\n };\n}\n\nfunction useHostedBuiltinMcp(): boolean {\n return envText(\"NEGOTIUM_BUILTIN_MCP_TRANSPORT\") !== \"stdio\";\n}\n\nfunction buildBuiltinMcpServer(\n surface: HostedMcpSurface,\n ctx: RuntimeMcpBuildContext,\n stdio: () => Record<string, unknown>,\n): Record<string, unknown> {\n if (!useHostedBuiltinMcp()) return stdio();\n const agent = ctx.agent ?? FALLBACK_AGENT;\n return buildHostedMcpSpec(agent, surface, {\n userId: ctx.userId,\n topicTitle: ctx.session,\n ...(ctx.topicId ? { topicId: ctx.topicId } : {}),\n ...(ctx.queryId ? { queryId: ctx.queryId } : {}),\n ...(ctx.wikiTopicId ? { wikiTopicId: ctx.wikiTopicId } : {}),\n ...(ctx.subagentParentTopicId ? { subagentParentTopicId: ctx.subagentParentTopicId } : {}),\n ...(ctx.threadRootId ? { threadRootId: ctx.threadRootId } : {}),\n cwd: ctx.cwd ?? (ctx.topicId ? resolveTopicWorkspaceDir(ctx.topicId) : process.cwd()),\n agent,\n ...(ctx.model ? { model: ctx.model } : {}),\n ...(ctx.depth !== undefined ? { depth: ctx.depth } : {}),\n ...(ctx.silent !== undefined ? { silent: ctx.silent } : {}),\n ...(ctx.peerBridge ? { peerBridge: ctx.peerBridge } : {}),\n });\n}\n\n// --- Playwright unavailable notifier + per-turn state ---\n//\n// When the playwright manager fails to allocate a long-lived MCP port,\n// the catalog used to fall back to a per-turn stdio chromium that ran as\n// a child of the agent CLI subprocess — which meant Chromium was bound\n// to the agent's process tree and died on cascade-kill. We now skip the\n// browser entry entirely (the playwright entry is omitted from the\n// catalog for that turn) AND surface the gap two ways:\n//\n// 1. `notifyPlaywrightUnavailable` — fire-and-forget callback for the host\n// (telegram bot) to push an alert to the current topic. Throttled\n// per (userId, topic) with a 5-minute cooldown so a flaky\n// manager doesn't spam the chat. Per-process state — restart clears.\n//\n// 2. `consumePlaywrightUnavailable` — the system-prompt builder reads\n// this flag to add an explicit \"Playwright unavailable this turn\"\n// reminder to the agent's user message, so the model knows to\n// route around browser tools instead of hallucinating a call to a\n// tool that was silently removed from the schema list.\n\ntype PlaywrightUnavailableContext = {\n userId: string;\n topic: string | undefined;\n agent: AgentKind | undefined;\n};\n\ntype PlaywrightUnavailableNotifier = (ctx: PlaywrightUnavailableContext) => void;\n\nlet _playwrightUnavailableNotifier: PlaywrightUnavailableNotifier | undefined;\nconst _playwrightUnavailableLastNotifiedAt = new Map<string, number>();\nconst _PLAYWRIGHT_UNAVAILABLE_COOLDOWN_MS = 5 * 60_000;\n\nconst _playwrightUnavailableThisTurn = new Set<string>();\n\nfunction _playwrightUnavailableKey(userId: string, topic: string | undefined): string {\n return `${userId}:${topic ?? \"\"}`;\n}\n\n/**\n * Register the host's \"playwright unavailable\" alert sink. Called once at bot\n * startup. Idempotent — last writer wins.\n */\nexport function setPlaywrightUnavailableNotifier(cb: PlaywrightUnavailableNotifier): void {\n _playwrightUnavailableNotifier = cb;\n}\n\n/**\n * Mark the current turn as missing long-lived Playwright and notify the host.\n * The playwright catalog entry calls this when it is built without a port, but\n * route-level callers can call it earlier after ensurePlaywright fails so the\n * system prompt for the same turn can include the unavailable reminder.\n */\nexport function markPlaywrightUnavailable(ctx: PlaywrightUnavailableContext): void {\n _markPlaywrightUnavailable(ctx);\n}\n\nfunction _markPlaywrightUnavailable(ctx: PlaywrightUnavailableContext): void {\n // Mark unavailable for the next system-prompt build, regardless of\n // notifier presence (the model-side reminder must always fire so the\n // agent doesn't try to call a missing tool).\n _playwrightUnavailableThisTurn.add(_playwrightUnavailableKey(ctx.userId, ctx.topic));\n\n if (!_playwrightUnavailableNotifier) return;\n const key = _playwrightUnavailableKey(ctx.userId, ctx.topic);\n const now = Date.now();\n const last = _playwrightUnavailableLastNotifiedAt.get(key) ?? 0;\n if (now - last < _PLAYWRIGHT_UNAVAILABLE_COOLDOWN_MS) return;\n _playwrightUnavailableLastNotifiedAt.set(key, now);\n try {\n _playwrightUnavailableNotifier(ctx);\n } catch (err) {\n logger.warn({ err }, \"playwright unavailable notifier threw\");\n }\n}\n\n/**\n * Read + clear the \"playwright unavailable this turn\" flag for a\n * (user, group, topic). Used by the system-prompt builder right before\n * the agent query starts. Single consumer pattern — calling more than\n * once per turn returns `false` for the second caller (intended; the\n * reminder only needs to ride one prompt).\n */\nexport function consumePlaywrightUnavailable(userId: string, topic: string | undefined): boolean {\n const key = _playwrightUnavailableKey(userId, topic);\n if (!_playwrightUnavailableThisTurn.has(key)) return false;\n _playwrightUnavailableThisTurn.delete(key);\n return true;\n}\n\n/**\n * Single source of truth for MCP server registration.\n *\n * Each entry declares which scopes it participates in (`dm`, `forum`, `fork`, `cron`)\n * and how to build its spawn config given a context. Public helpers\n * (`getDmMcpServers`, `getForumMcpServers`, `getForkMcpServers`) and the\n * derived forum-name views read from this catalog plus the node-assigned\n * manifest overlay installed below. Adding a built-in MCP server remains a\n * one-line append here instead of touching three places.\n *\n * Conventions:\n * - `scopes` lists every scope the server should appear in by default.\n * - `forumRequired: true` keeps the server even when a forum topic\n * restricts the enabled list via `configure_mcp` (forum scope only).\n * - `build(ctx)` returns the raw transport config (Claude-SDK shape).\n * Codex callers funnel through `toCodexMcpServers` separately.\n *\n * Insertion order is preserved by `Object.entries`, which determines the\n * order of server names in user-facing displays.\n */\n\nexport interface RuntimeMcpBuildContext {\n userId: string;\n /** Product actor identity when it differs from the execution principal. */\n actorUserId?: string;\n /** Vault namespace when credentials belong to a different principal. */\n vaultUserId?: string;\n /** \"dm\" for DM scope, topic/session name for forum/fork. */\n session: string;\n /** REST/WS topic id when known. Prefer for authorization/scope checks. */\n topicId?: string;\n /** Direct parent topic id when the current topic is a subagent room. */\n subagentParentTopicId?: string;\n /** REST/WS query id when known. */\n queryId?: string;\n /** Topic id whose wiki memory should be read/written. */\n wikiTopicId?: string;\n agent?: AgentKind;\n cwd?: string;\n model?: string;\n currentUserPrompt?: string;\n depth?: number;\n playwrightPort?: number;\n playwrightCapability?: string;\n bgBashPort?: number;\n autoContinue?: boolean;\n visualTools?: boolean;\n fileDeliveryTools?: boolean;\n silent?: boolean;\n /** Thread this turn answers inside; forwarded to the runtime MCP context. */\n threadRootId?: string;\n peerBridge?: PeerRuntimeBridgeContext;\n}\n\nexport interface RuntimeMcpCatalogEntry {\n scopes: readonly RuntimeMcpScope[];\n /** Forum scope only: cannot be removed via the enabled whitelist. */\n forumRequired?: boolean;\n /**\n * Returns the raw transport spec (Claude-SDK shape), or `null` to\n * signal \"this server is unavailable for this turn — omit it from the\n * catalog entirely.\" Used by the playwright entry when the manager\n * cannot provide a long-lived port.\n */\n build(ctx: RuntimeMcpBuildContext): Record<string, unknown> | null;\n}\n\n// --- Playwright transport builders ---\n\nexport { browserOwnerCapability, buildPlaywrightMcpTransport, CODEX_BROWSER_CAPABILITY_ENV };\n\nexport function browserOwnerForContext(ctx: {\n userId?: string;\n session?: string;\n topicId?: string;\n}): string | undefined {\n if (ctx.topicId) return `topic:${ctx.topicId}`;\n if (ctx.userId && ctx.session) return `user:${ctx.userId}:${ctx.session}`;\n return undefined;\n}\n\nfunction longLivedHttpMcp(agent: AgentKind | undefined, port: number) {\n return agent === \"codex\"\n ? { url: `http://127.0.0.1:${port}/mcp` }\n : { type: \"sse\" as const, url: `http://127.0.0.1:${port}/sse` };\n}\n\n// cua-rs implements Streamable HTTP only; unlike browser-rs, it does not\n// expose the legacy SSE endpoint. The port is installed by the node-owned\n// process manager once its singleton is ready.\nlet cuaRsMcpPort: number | undefined;\n// cua-rs 0.8.0 requires `Authorization: Bearer` on /mcp, because loopback is not\n// an authorization boundary -- any local process, a web page included, could\n// otherwise drive the whole desktop. The node picks the token, hands it to the\n// child as CUA_HTTP_TOKEN, and publishes it here so turns can present it. Kept\n// beside the port because they are one fact: without both, the URL is useless.\nlet cuaRsMcpToken: string | undefined;\n\nexport function setCuaRsMcpPort(port: number | undefined, token?: string): void {\n if (port !== undefined && (!Number.isInteger(port) || port < 1 || port > 65_535)) {\n throw new Error(`invalid cua-rs MCP port: ${port}`);\n }\n cuaRsMcpPort = port;\n cuaRsMcpToken = port === undefined ? undefined : token;\n}\n\nfunction cuaRsHttpMcp(agent: AgentKind | undefined, port: number, token: string | undefined) {\n const url = `http://127.0.0.1:${port}/mcp`;\n // No token means an older cua-rs that does not ask for one. Sending the header\n // anyway would be harmless, but omitting it keeps the config honest about what\n // the running server actually requires.\n const headers = token ? { Authorization: `Bearer ${token}` } : undefined;\n // The shape is otherwise unchanged from before the token existed, including\n // `type` for codex: only the header field is added, and only when there is a\n // token to put in it. Codex spells that field `http_headers`.\n const base = { type: \"http\" as const, url };\n if (!headers) return base;\n return agent === \"codex\" ? { ...base, http_headers: headers } : { ...base, headers };\n}\n\nfunction backgroundBashTransport(\n agent: AgentKind | undefined,\n port: number,\n userId: string,\n topic: string,\n) {\n const capability = bgBashContextCapability(userId, topic);\n const headers = {\n \"X-Background-Bash-User\": userId,\n \"X-Background-Bash-Topic\": topic,\n \"X-Background-Bash-Capability\": capability,\n };\n if (agent === \"codex\") return { url: `http://127.0.0.1:${port}/mcp`, http_headers: headers };\n if (agent === \"maestro\") {\n const query = new URLSearchParams({ user: userId, topic, capability });\n return { type: \"sse\" as const, url: `http://127.0.0.1:${port}/sse?${query}` };\n }\n return { type: \"sse\" as const, url: `http://127.0.0.1:${port}/sse`, headers };\n}\n\n// --- Catalog ---\n\nconst MCP_CATALOG: Record<string, RuntimeMcpCatalogEntry> = {\n playwright: {\n ...commonRuntimeMcpPolicy(\"playwright\"),\n build({ userId, session, topicId, playwrightPort, playwrightCapability, agent }) {\n // Codex and Maestro use Streamable HTTP while Claude uses SSE. Both\n // transports terminate at the same long-lived browser/profile server.\n if (playwrightPort && playwrightCapability) {\n const owner = browserOwnerForContext({ userId, session, topicId });\n if (!owner) return null;\n return buildPlaywrightMcpTransport(playwrightPort, owner, playwrightCapability, agent);\n }\n // No port available — the playwright manager could not allocate one\n // for this turn. The previous behavior was to fall back to a per-turn\n // stdio chromium, but that made Chromium a child of the agent CLI\n // process tree, so cascade-kill on agent exit took the browser down\n // with it (visible in pm2 as \"Chromium died with claude\"). We now\n // omit the playwright entry from this turn's catalog AND fire two\n // side-effects:\n // 1. notify the host so it can push an alert into the current\n // topic (rate-limited 5min per scope key);\n // 2. mark the (user, topic) as \"playwright unavailable\n // this turn\" so the system-prompt builder can tell the model\n // explicitly, instead of letting the model hallucinate a call\n // to a tool whose schema silently vanished.\n _markPlaywrightUnavailable({\n userId,\n topic: session,\n agent,\n });\n return null;\n },\n },\n [RUNTIME_MCP_KEY]: {\n ...commonRuntimeMcpPolicy(\"runtime\"),\n build({\n userId,\n actorUserId,\n session,\n topicId,\n queryId,\n agent,\n cwd,\n model,\n currentUserPrompt,\n autoContinue,\n visualTools,\n fileDeliveryTools,\n threadRootId,\n peerBridge,\n }) {\n if (!topicId || !agent) return null;\n return buildRuntimeMcpSpec(agent, {\n // Runtime tools mutate node-owned state, so authorization stays bound\n // to the canonical execution principal. Keep the product-side human\n // actor separately for attribution instead of replacing the identity\n // that appears in this node's topic participant roster.\n userId,\n ...(actorUserId ? { actorUserId } : {}),\n topicId,\n topicTitle: session,\n queryId,\n cwd: cwd ?? resolveTopicWorkspaceDir(topicId),\n agent,\n model,\n currentUserPrompt,\n autoContinue,\n visualTools,\n fileDeliveryTools,\n ...(threadRootId ? { threadRootId } : {}),\n peerBridge,\n });\n },\n },\n \"token-stats\": {\n ...commonRuntimeMcpPolicy(\"token-stats\"),\n build(ctx) {\n return buildBuiltinMcpServer(\"token-stats\", ctx, () =>\n buildStdioMcpServer(ctx.agent, TOKEN_STATS_SERVER, [`--user-id=${ctx.userId}`]),\n );\n },\n },\n // Otium-owned shared task system. This is the only authoritative task/todo\n // surface across claude/codex/maestro; provider-native task stores are\n // blocked or ignored because they do not survive agent switches.\n task: {\n ...commonRuntimeMcpPolicy(\"task\"),\n build(ctx) {\n const { userId, session, topicId, queryId, agent, peerBridge } = ctx;\n if (peerBridge) {\n if (!topicId || !queryId) return null;\n const env = canonicalMcpBridgeEnv({\n surface: \"task\",\n userId,\n topicId,\n queryId,\n peerBridge,\n });\n return env\n ? buildStdioMcpServer(agent, CANONICAL_MCP_PROXY_SERVER, [\"--surface=task\"], env)\n : null;\n }\n const args = [`--user-id=${userId}`, `--topic=${session}`];\n if (topicId) args.push(`--topic-id=${topicId}`);\n return buildBuiltinMcpServer(\"task\", ctx, () =>\n buildStdioMcpServer(agent, TASK_SERVER, args),\n );\n },\n },\n decision: {\n ...commonRuntimeMcpPolicy(\"decision\"),\n build(ctx) {\n const { userId, session, topicId, queryId, agent, model, peerBridge } = ctx;\n if (peerBridge) {\n if (!topicId || !queryId) return null;\n const env = canonicalMcpBridgeEnv({\n surface: \"decision\",\n userId,\n topicId,\n queryId,\n peerBridge,\n });\n return env\n ? buildStdioMcpServer(agent, CANONICAL_MCP_PROXY_SERVER, [\"--surface=decision\"], env)\n : null;\n }\n const args = [\n `--user-id=${userId}`,\n `--topic=${session}`,\n `--agent=${agent ?? FALLBACK_AGENT}`,\n ];\n if (topicId) args.push(`--topic-id=${topicId}`);\n if (model) args.push(`--model=${model}`);\n return buildBuiltinMcpServer(\"decision\", ctx, () =>\n buildStdioMcpServer(agent, DECISION_SERVER, args),\n );\n },\n },\n \"session-comm\": {\n // Exposed in `manager` scope as well so the General-topic manager agent\n // can wake fresh-created topics via tell_session/ask_session right after\n // create_topic. Without this, a newly-created topic would stay in the\n // \"fresh-start ready\" state until the user manually visits it.\n ...commonRuntimeMcpPolicy(\"session-comm\"),\n build(ctx) {\n const {\n userId,\n session,\n topicId,\n subagentParentTopicId,\n agent,\n depth = 0,\n silent,\n threadRootId,\n peerBridge,\n } = ctx;\n const effectiveAgent = agent ?? FALLBACK_AGENT;\n const cronSessionId = topicId\n ? getRegisteredCronSession(topicId, effectiveAgent)?.sessionId\n : undefined;\n const args = [\n `--user-id=${userId}`,\n `--topic=${session}`,\n ...(topicId ? [`--topic-id=${topicId}`] : []),\n ...(subagentParentTopicId ? [`--subagent-parent-topic-id=${subagentParentTopicId}`] : []),\n `--depth=${depth}`,\n `--agent=${effectiveAgent}`,\n ...(cronSessionId ? [`--cron-session-id=${cronSessionId}`] : []),\n ...(silent ? [\"--reply-only=true\"] : []),\n // Turn-scoped, like `--peer-host-query-id`: this config is rebuilt for\n // every turn, so an `ask_session` raised inside a thread can record\n // where its answer belongs.\n ...(threadRootId ? [`--thread-root-id=${threadRootId}`] : []),\n ...(peerBridge ? [`--peer-host-query-id=${peerBridge.hostQueryId}`] : []),\n ];\n return buildBuiltinMcpServer(\"session-comm\", ctx, () =>\n buildStdioMcpServer(\n effectiveAgent,\n SESSION_COMM_SERVER,\n args,\n peerBridge ? peerSessionBridgeIpcEnv() : undefined,\n ),\n );\n },\n },\n wiki: {\n ...commonRuntimeMcpPolicy(\"wiki\"),\n build(ctx) {\n const { userId, session, topicId, queryId, wikiTopicId, agent, peerBridge } = ctx;\n if (peerBridge) {\n if (!topicId || !queryId) return null;\n const env = canonicalMcpBridgeEnv({\n surface: \"wiki\",\n userId,\n topicId,\n queryId,\n peerBridge,\n });\n return env\n ? buildStdioMcpServer(agent, CANONICAL_MCP_PROXY_SERVER, [\"--surface=wiki\"], env)\n : null;\n }\n const args = [`--user-id=${userId}`];\n if (topicId) args.push(`--current-topic-id=${topicId}`);\n // Prefer the REST topic id so wiki_write writes filenames and SQLite\n // briefs keyed the same way the topic wiki API reads them.\n const resolvedWikiTopicId =\n wikiTopicId ?? topicId ?? (session !== \"dm\" ? session : undefined);\n if (resolvedWikiTopicId) args.push(`--topic-id=${resolvedWikiTopicId}`);\n args.push(\"--surface=wiki\");\n return buildBuiltinMcpServer(\"wiki\", { ...ctx, wikiTopicId: resolvedWikiTopicId }, () =>\n buildStdioMcpServer(agent, WIKI_SERVER, args),\n );\n },\n },\n skills: {\n ...commonRuntimeMcpPolicy(\"skills\"),\n build(ctx) {\n const { userId, topicId, agent } = ctx;\n const args = [`--user-id=${userId}`, \"--surface=skills\"];\n if (topicId) args.push(`--topic-id=${topicId}`);\n return buildBuiltinMcpServer(\"skills\", ctx, () =>\n buildStdioMcpServer(agent, WIKI_SERVER, args),\n );\n },\n },\n \"system-health\": {\n ...commonRuntimeMcpPolicy(\"system-health\"),\n build(ctx) {\n return buildBuiltinMcpServer(\"system-health\", ctx, () =>\n buildStdioMcpServer(ctx.agent, SYSTEM_HEALTH_SERVER, []),\n );\n },\n },\n \"background-bash\": {\n ...commonRuntimeMcpPolicy(\"background-bash\"),\n build({ agent, bgBashPort, userId, topicId }) {\n // Key the whole pipeline by the canonical topic id: it flows through the\n // capability, the request context, and the completion inbox filename\n // (sessionInboxPath) so the exiting process's output is routed back to\n // the exact originating topic. A title/session fallback would be encoded\n // as if it were an id and the inbox worker would fail to resolve it, so\n // background-bash is simply unavailable without a topic id.\n if (bgBashPort === undefined || !topicId) return null;\n return backgroundBashTransport(agent, bgBashPort, userId, topicId);\n },\n },\n \"agent-health\": {\n ...commonRuntimeMcpPolicy(\"agent-health\"),\n build(ctx) {\n const { userId, agent } = ctx;\n const args = [`--user-id=${userId}`];\n return buildBuiltinMcpServer(\"agent-health\", ctx, () =>\n buildStdioMcpServer(agent, AGENT_HEALTH_SERVER, args),\n );\n },\n },\n vault: {\n ...commonRuntimeMcpPolicy(\"vault\"),\n build(ctx) {\n const { userId, vaultUserId, agent } = ctx;\n // Normal turns use {{KEY}} directly in tool inputs. Keep the Vault MCP\n // surface focused on key discovery; broker tools remain available from\n // the public factory for compatibility but are no longer the default UX.\n const args = [`--user-id=${vaultUserId ?? userId}`];\n if (agent !== \"codex\") args.push(\"--list-only=true\");\n return buildBuiltinMcpServer(\"vault\", { ...ctx, userId: vaultUserId ?? userId }, () =>\n buildStdioMcpServer(agent, VAULT_SERVER, args),\n );\n },\n },\n // macOS desktop control, delegated to maestrojeong/cua-rs rather than\n // reimplemented. The node owns one persistent Streamable HTTP process;\n // turns only receive its loopback URL and must never spawn a stdio copy.\n \"cua-rs\": {\n ...commonRuntimeMcpPolicy(\"cua-rs\"),\n build({ agent }) {\n return cuaRsMcpPort ? cuaRsHttpMcp(agent, cuaRsMcpPort, cuaRsMcpToken) : null;\n },\n },\n};\n\n/**\n * Locate the `cua-rs` binary, or `null` when it is not installed.\n *\n * Checked in order of specificity: an explicit env override for anyone running\n * a local build, then the installer's default target, then `/usr/local/bin`\n * for a `--bin-dir` install. PATH is deliberately not consulted -- the server\n * is spawned by a supervised host process whose PATH is not the user's shell\n * PATH, so a PATH lookup would succeed in a terminal and fail under pm2.\n */\nexport function resolveCuaRsBinary(platform: NodeJS.Platform = process.platform): string | null {\n if (platform !== \"darwin\") return null;\n const candidates = [\n envText(\"NEGOTIUM_CUA_RS_BIN\"),\n join(homedir(), \".local\", \"bin\", \"cua-rs\"),\n \"/usr/local/bin/cua-rs\",\n ].filter((p): p is string => Boolean(p));\n for (const candidate of candidates) {\n try {\n accessSync(candidate, fsConstants.X_OK);\n return candidate;\n } catch {\n // Not there, or not executable. Try the next one.\n }\n }\n return null;\n}\n\n// --- Derived catalog views ---\n\nexport type NodeMcpEntry =\n | { key: string; kind: \"http\"; port: number }\n | {\n key: string;\n kind: \"http-instance\";\n ensurePort: (instanceKey: string) => Promise<number>;\n }\n | { key: string; kind: \"stdio\"; command: string; args?: string[]; env?: Record<string, string> };\n\nlet nodeMcpEntries: NodeMcpEntry[] = [];\nconst resolvedNodeMcpPorts = new WeakMap<\n Extract<NodeMcpEntry, { kind: \"http-instance\" }>,\n Map<string, number>\n>();\n\n/** All forum-eligible MCP server names, in display order. */\nconst allForumMcpServerNames: string[] = [];\nexport const ALL_FORUM_MCP_SERVER_NAMES: readonly string[] = allForumMcpServerNames;\n\n/** Forum servers that cannot be removed via the enabled whitelist. */\nconst requiredForumMcpServers: string[] = [];\nexport const REQUIRED_FORUM_MCP_SERVERS: readonly string[] = requiredForumMcpServers;\n\n/** Forum servers that can be toggled via the enabled whitelist (not required). */\nconst optionalForumMcpServers: string[] = [];\nexport const OPTIONAL_FORUM_MCP_SERVERS: readonly string[] = optionalForumMcpServers;\n\nfunction refreshForumCatalogViews(): void {\n const { all, required, optional } = classifyForumMcpServers(MCP_CATALOG);\n const nodeNames = nodeMcpEntries.map((entry) => entry.key);\n const allWithNodeEntries = [...new Set([...all, ...nodeNames])];\n const optionalWithNodeEntries = [...new Set([...optional, ...nodeNames])];\n allForumMcpServerNames.splice(0, allForumMcpServerNames.length, ...allWithNodeEntries);\n requiredForumMcpServers.splice(0, requiredForumMcpServers.length, ...required);\n optionalForumMcpServers.splice(0, optionalForumMcpServers.length, ...optionalWithNodeEntries);\n}\n\nrefreshForumCatalogViews();\n\n/**\n * Mount one MCP capability supplied by an optional node module.\n *\n * Registration happens once at node startup, never in the per-event hot path.\n * The returned cleanup closure only removes the exact entry installed by this\n * call, making module stop/restart safe.\n */\nexport function registerRuntimeMcpServer(name: string, entry: RuntimeMcpCatalogEntry): () => void {\n const key = name.trim();\n if (!key || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(key)) {\n throw new Error(`invalid runtime MCP server name: ${name}`);\n }\n if (MCP_CATALOG[key]) throw new Error(`runtime MCP server already registered: ${key}`);\n MCP_CATALOG[key] = entry;\n refreshForumCatalogViews();\n return () => {\n if (MCP_CATALOG[key] !== entry) return;\n delete MCP_CATALOG[key];\n refreshForumCatalogViews();\n };\n}\n\n/**\n * Format the active MCP config for display (used by get_mcp_config /\n * get_topic_mcp / configure_mcp response).\n *\n * In whitelist mode the DB stores only the user-chosen optional servers;\n * required servers are always active but never written to the whitelist.\n * This helper surfaces that split so the model never confuses \"not in\n * whitelist\" with \"not active\".\n */\nexport function formatMcpStatus(config: {\n enabled: string[] | null;\n extra?: Record<string, unknown>;\n}): string[] {\n const extraNames = Object.keys(config.extra ?? {});\n\n if (config.enabled === null) {\n const total = ALL_FORUM_MCP_SERVER_NAMES.length + extraNames.length;\n return [\n `설정 방식: 기본값 (전체 활성)`,\n `활성 서버 (${total}개): ${[...ALL_FORUM_MCP_SERVER_NAMES, ...extraNames].join(\", \")}`,\n `추가 서버: ${extraNames.length > 0 ? extraNames.join(\", \") : \"없음\"}`,\n ];\n }\n\n // whitelist mode: stored list may or may not include required servers\n // (old entries might have them; new entries won't). Either way, split\n // by required vs optional for display.\n const availableOptional = new Set(OPTIONAL_FORUM_MCP_SERVERS);\n const optionalActive = [...new Set(config.enabled)].filter((name) => availableOptional.has(name));\n const total = REQUIRED_FORUM_MCP_SERVERS.length + optionalActive.length + extraNames.length;\n return [\n `설정 방식: whitelist`,\n `필수 서버 (항상 활성, ${REQUIRED_FORUM_MCP_SERVERS.length}개): ${REQUIRED_FORUM_MCP_SERVERS.join(\", \")}`,\n `선택 서버 (whitelist, ${optionalActive.length}개): ${optionalActive.length > 0 ? optionalActive.join(\", \") : \"없음\"}`,\n `실제 활성 합계: ${total}개`,\n `추가 서버: ${extraNames.length > 0 ? extraNames.join(\", \") : \"없음\"}`,\n ``,\n `선택 가능 서버 전체 (${OPTIONAL_FORUM_MCP_SERVERS.length}개): ${OPTIONAL_FORUM_MCP_SERVERS.join(\", \")}`,\n ];\n}\n\n// --- Builders for each scope ---\n\n// ── Node-assigned MCP servers (mcp-host manifest) ───────────────────\n//\n// The per-node MCP manifest (`negotium mcp add`) lives in @negotium/mcp-host,\n// which depends on core — so core cannot read it directly. Instead the host\n// process resolves the manifest at node start (ensuring long-lived http\n// servers are running and have ports) and installs the result here. Entries\n// then ride every eligible scope's catalog, subject to the same per-topic\n// `enabled` whitelist as optional built-ins.\n\n/** Install the node's assigned MCP servers. Last writer wins (host restart-safe). */\nexport function setNodeMcpServers(entries: NodeMcpEntry[]): void {\n nodeMcpEntries = entries.filter((entry) => !(entry.key in MCP_CATALOG));\n const dropped = entries.length - nodeMcpEntries.length;\n if (dropped > 0) {\n logger.warn({ dropped }, \"setNodeMcpServers: entries shadowing built-in catalog keys ignored\");\n }\n refreshForumCatalogViews();\n}\n\nexport function getNodeMcpServers(): readonly NodeMcpEntry[] {\n return nodeMcpEntries;\n}\n\n/** Prevent host grants from replacing node-owned MCP servers. */\nexport function isReservedRuntimeMcpServerName(name: string): boolean {\n return Object.hasOwn(MCP_CATALOG, name) || nodeMcpEntries.some((entry) => entry.key === name);\n}\n\nfunction mergeHostMcpServers(\n base: Record<string, unknown>,\n hostMcpServers: Record<string, HostMcpServerSpec> | undefined,\n): Record<string, unknown> {\n if (!hostMcpServers) return base;\n for (const name of Object.keys(hostMcpServers)) {\n if (Object.hasOwn(base, name) || isReservedRuntimeMcpServerName(name)) {\n throw new Error(`host MCP server name conflicts with node catalog: ${name}`);\n }\n }\n return { ...base, ...hostMcpServers };\n}\n\nfunction buildNodeMcpSpecs(\n agent: AgentKind | undefined,\n filter: (name: string) => boolean,\n ctx: Pick<RuntimeMcpBuildContext, \"topicId\" | \"userId\" | \"session\">,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const entry of nodeMcpEntries) {\n if (!filter(entry.key)) continue;\n if (entry.kind === \"http\") {\n out[entry.key] = longLivedHttpMcp(agent, entry.port);\n continue;\n }\n if (entry.kind === \"http-instance\") {\n const port = resolvedNodeMcpPorts.get(entry)?.get(nodeMcpInstanceKey(ctx));\n if (port !== undefined) out[entry.key] = longLivedHttpMcp(agent, port);\n continue;\n }\n out[entry.key] = {\n command: entry.command,\n args: entry.args ?? [],\n ...(entry.env ? { env: entry.env } : {}),\n };\n }\n return out;\n}\n\nfunction nodeMcpInstanceKey(\n ctx: Pick<RuntimeMcpBuildContext, \"topicId\" | \"userId\" | \"session\">,\n): string {\n return ctx.topicId ?? `user:${ctx.userId}:session:${ctx.session}`;\n}\n\n/**\n * Lazily prepare per-topic HTTP manifest entries before a provider resolves\n * its otherwise-synchronous MCP config. One failed custom server is omitted\n * from that turn without taking down the rest of the runtime catalog.\n */\nexport async function prepareNodeMcpServersForQuery(opts: AgentQueryOptions): Promise<void> {\n if (\n opts.toolPolicy ||\n opts.sessionType === \"cron\" ||\n nodeMcpEntries.every((entry) => entry.kind !== \"http-instance\")\n ) {\n return;\n }\n\n const forum = ![\"dm\", \"ephemeral\", \"manager\"].includes(opts.sessionType ?? \"forum\");\n const enabled = opts.mcpEnabled ?? null;\n const instanceKey = nodeMcpInstanceKey({\n topicId: opts.topicId,\n userId: opts.userId || \"local\",\n session: opts.session || \"default\",\n });\n\n await Promise.all(\n nodeMcpEntries.map(async (entry) => {\n if (entry.kind !== \"http-instance\") return;\n if (forum && enabled !== null && !enabled.includes(entry.key)) return;\n let ports = resolvedNodeMcpPorts.get(entry);\n if (!ports) {\n ports = new Map();\n resolvedNodeMcpPorts.set(entry, ports);\n }\n try {\n const port = await entry.ensurePort(instanceKey);\n if (!Number.isInteger(port) || port < 1 || port > 65_535) {\n throw new Error(`invalid port ${port}`);\n }\n ports.set(instanceKey, port);\n } catch (err) {\n ports.delete(instanceKey);\n logger.warn(\n { err, key: entry.key, instanceKey },\n \"node mcp: failed to prepare instance-scoped server\",\n );\n }\n }),\n );\n}\n\nfunction buildScope(\n scope: RuntimeMcpScope,\n ctx: RuntimeMcpBuildContext,\n filter: (name: string) => boolean = () => true,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [name, entry] of Object.entries(MCP_CATALOG)) {\n if (!entry.scopes.includes(scope)) continue;\n if (!filter(name)) continue;\n // `null` from build() means \"skip this server for this turn\" —\n // currently used by the playwright entry when no long-lived port\n // is available.\n const spec = entry.build(ctx);\n if (spec === null) continue;\n out[name] = spec;\n }\n // Node-assigned MCPs join every scope except cron (scheduled runs keep the\n // deliberately narrow built-in set).\n if (scope !== \"cron\") {\n Object.assign(out, buildNodeMcpSpecs(ctx.agent, filter, ctx));\n }\n return out;\n}\n\n/** DM session: catalog entries with `dm` scope, no whitelist. */\nexport function getDmMcpServers(opts: {\n userId: string;\n session?: string;\n topicId?: string;\n agent?: AgentKind;\n playwrightPort?: number;\n playwrightCapability?: string;\n}) {\n return buildScope(\"dm\", {\n userId: opts.userId,\n session: opts.session ?? \"dm\",\n topicId: opts.topicId,\n agent: opts.agent,\n playwrightPort: opts.playwrightPort,\n playwrightCapability: opts.playwrightCapability,\n });\n}\n\n/**\n * Manager session: lives in the caller's private General API topic. Owns topic CRUD,\n * invite/user admin, and cross-topic MCP toggling through `topic-admin`,\n * plus general utilities. Browser-heavy work belongs in dedicated topics, so\n * Playwright is intentionally excluded here.\n * No whitelist — manager-scope catalog entries are loaded as-is.\n */\nexport function getManagerMcpServers(opts: {\n userId: string;\n session?: string;\n topicId?: string;\n queryId?: string;\n wikiTopicId?: string;\n agent?: AgentKind;\n cwd?: string;\n model?: string;\n currentUserPrompt?: string;\n playwrightPort?: number;\n playwrightCapability?: string;\n autoContinue?: boolean;\n visualTools?: boolean;\n fileDeliveryTools?: boolean;\n}) {\n if (!opts.topicId) {\n throw new Error(\"getManagerMcpServers: private General topicId is required\");\n }\n const topicId = opts.topicId;\n return buildScope(\"manager\", {\n userId: opts.userId,\n session: opts.session ?? \"General\",\n topicId,\n queryId: opts.queryId,\n wikiTopicId: opts.wikiTopicId ?? topicId,\n agent: opts.agent,\n cwd: opts.cwd,\n model: opts.model,\n currentUserPrompt: opts.currentUserPrompt,\n playwrightPort: opts.playwrightPort,\n playwrightCapability: opts.playwrightCapability,\n autoContinue: opts.autoContinue,\n visualTools: opts.visualTools,\n fileDeliveryTools: opts.fileDeliveryTools,\n });\n}\n\n/**\n * Forum session: catalog entries with `forum` scope.\n * - `enabled === null` → all forum servers.\n * - `enabled` is an array → whitelist; required servers are always included.\n * - `extra` is merged on top, allowing one-off injections per topic.\n */\nexport function getForumMcpServers(opts: {\n userId: string;\n actorUserId?: string;\n vaultUserId?: string;\n session: string;\n topicId?: string;\n subagentParentTopicId?: string;\n queryId?: string;\n wikiTopicId?: string;\n agent: AgentKind;\n cwd?: string;\n model?: string;\n currentUserPrompt?: string;\n playwrightPort?: number;\n playwrightCapability?: string;\n bgBashPort?: number;\n autoContinue?: boolean;\n visualTools?: boolean;\n fileDeliveryTools?: boolean;\n threadRootId?: string;\n depth?: number;\n enabled?: string[] | null;\n extra?: Record<string, unknown>;\n silent?: boolean;\n peerBridge?: PeerRuntimeBridgeContext;\n}) {\n const {\n userId,\n actorUserId,\n vaultUserId,\n session,\n topicId,\n subagentParentTopicId,\n queryId,\n wikiTopicId,\n agent,\n cwd,\n model,\n currentUserPrompt,\n playwrightPort,\n playwrightCapability,\n depth = 0,\n enabled = null,\n extra = {},\n silent = false,\n bgBashPort,\n autoContinue,\n visualTools,\n fileDeliveryTools,\n threadRootId,\n peerBridge,\n } = opts;\n\n const filter = (name: string) => {\n if (silent && (name === \"task\" || name === \"decision\")) return false;\n if (enabled === null) return true;\n return (\n enabled.includes(name) || (REQUIRED_FORUM_MCP_SERVERS as readonly string[]).includes(name)\n );\n };\n\n const base = buildScope(\n \"forum\",\n {\n userId,\n actorUserId,\n vaultUserId,\n session,\n topicId,\n subagentParentTopicId,\n queryId,\n wikiTopicId,\n agent,\n cwd,\n model,\n currentUserPrompt,\n depth,\n playwrightPort,\n playwrightCapability,\n bgBashPort,\n autoContinue,\n visualTools,\n fileDeliveryTools,\n threadRootId,\n silent,\n peerBridge,\n },\n filter,\n );\n\n return { ...base, ...extra };\n}\n\n/**\n * Cron session: scheduled background run for a concrete API topic. Keep the\n * catalog narrower than forum scope: runtime delivery, topic memory/status,\n * vault utilities and a caller-provided disposable Playwright port.\n */\nexport function getCronMcpServers(opts: {\n userId: string;\n session: string;\n topicId: string;\n queryId?: string;\n wikiTopicId?: string;\n agent: AgentKind;\n cwd?: string;\n model?: string;\n currentUserPrompt?: string;\n playwrightPort?: number;\n playwrightCapability?: string;\n visualTools?: boolean;\n fileDeliveryTools?: boolean;\n}) {\n return buildScope(\"cron\", {\n userId: opts.userId,\n session: opts.session,\n topicId: opts.topicId,\n queryId: opts.queryId,\n wikiTopicId: opts.wikiTopicId ?? opts.topicId,\n agent: opts.agent,\n cwd: opts.cwd,\n model: opts.model,\n currentUserPrompt: opts.currentUserPrompt,\n playwrightPort: opts.playwrightPort,\n playwrightCapability: opts.playwrightCapability,\n autoContinue: false,\n visualTools: opts.visualTools,\n fileDeliveryTools: opts.fileDeliveryTools,\n });\n}\n\n/**\n * Pick the right MCP server bundle for an agent query. DM/ephemeral sessions\n * get the DM bundle; forum sessions get the forum bundle with full options\n * forwarded. Returned shape is the Claude-SDK shape; Codex callers funnel it\n * through their own translator (`toCodexMcpServers`).\n */\nexport function getMcpServersForQuery(opts: AgentQueryOptions): Record<string, unknown> {\n if (opts.toolPolicy === \"none\") return {};\n if (opts.toolPolicy === \"compaction-log\") {\n const compactLog = opts.mcpExtra?.compact_log;\n return compactLog ? { compact_log: compactLog } : {};\n }\n if (opts.sessionType === \"cron\") {\n if (!opts.topicId) throw new Error(\"getMcpServersForQuery: cron sessionType requires topicId\");\n return hideProviderIntrospectionForOtium(\n getCronMcpServers({\n userId: opts.userId || \"local\",\n session: opts.session || \"cron\",\n topicId: opts.topicId,\n queryId: opts.queryId,\n wikiTopicId: opts.wikiTopicId,\n agent: opts.agent,\n cwd: opts.cwd,\n model: opts.model,\n currentUserPrompt: opts.prompt,\n playwrightPort: opts.playwrightPort,\n playwrightCapability: opts.playwrightCapability,\n visualTools: opts.visualTools,\n fileDeliveryTools: opts.fileDeliveryTools,\n }),\n opts.topicId,\n );\n }\n if (opts.sessionType === \"dm\" || opts.sessionType === \"ephemeral\") {\n return getDmMcpServers({\n userId: opts.userId || \"local\",\n session: opts.session,\n topicId: opts.topicId,\n agent: opts.agent,\n playwrightPort: opts.playwrightPort,\n playwrightCapability: opts.playwrightCapability,\n });\n }\n if (opts.sessionType === \"manager\") {\n return hideProviderIntrospectionForOtium(\n mergeHostMcpServers(\n getManagerMcpServers({\n userId: opts.userId || \"local\",\n session: opts.session,\n topicId: opts.topicId,\n queryId: opts.queryId,\n wikiTopicId: opts.wikiTopicId,\n agent: opts.agent,\n cwd: opts.cwd,\n model: opts.model,\n currentUserPrompt: opts.prompt,\n playwrightPort: opts.playwrightPort,\n playwrightCapability: opts.playwrightCapability,\n autoContinue: opts.autoContinue,\n visualTools: opts.visualTools,\n fileDeliveryTools: opts.fileDeliveryTools,\n }),\n opts.hostMcpServers,\n ),\n opts.topicId,\n );\n }\n return hideProviderIntrospectionForOtium(\n getForumMcpServers({\n userId: opts.userId || \"local\",\n actorUserId: opts.actorUserId,\n vaultUserId: opts.vaultUserId,\n session: opts.session || \"default\",\n topicId: opts.topicId,\n subagentParentTopicId: opts.subagentParentTopicId,\n queryId: opts.queryId,\n wikiTopicId: opts.wikiTopicId,\n agent: opts.agent,\n cwd: opts.cwd,\n model: opts.model,\n currentUserPrompt: opts.prompt,\n playwrightPort: opts.playwrightPort,\n playwrightCapability: opts.playwrightCapability,\n bgBashPort: opts.bgBashPort,\n autoContinue: opts.autoContinue,\n visualTools: opts.visualTools,\n fileDeliveryTools: opts.fileDeliveryTools,\n threadRootId: opts.threadRootId,\n depth: opts.depth,\n enabled: opts.mcpEnabled,\n extra: opts.mcpExtra,\n silent: opts.silent,\n peerBridge: opts.peerBridge,\n }),\n opts.topicId,\n );\n}\n\nfunction hideProviderIntrospectionForOtium(\n servers: Record<string, unknown>,\n topicId: string | undefined,\n): Record<string, unknown> {\n if (!topicId || getTopic(topicId)?.surface !== \"otium\") return servers;\n const filtered = { ...servers };\n delete filtered[\"agent-health\"];\n delete filtered[\"token-stats\"];\n return filtered;\n}\n",
31
+ "// Persistent topic store backed by shared SQLite.\n\nimport { resolveFallbackAgent } from \"#platform/config-helpers\";\nimport { GENERAL_TOPIC_ID } from \"#platform/constants\";\nimport { logger } from \"#platform/logger\";\nimport { db } from \"#storage/forum-db\";\nimport { registerStorageSchemaInitializer } from \"#storage/storage-host\";\nimport type { AgentKind, EffortLevel } from \"#types\";\nimport type {\n AiMode,\n ParticipantDto,\n SubagentReportMode,\n TopicDto,\n TopicKind,\n TopicSurface,\n TopicVisibility,\n} from \"#types/api\";\n\n/**\n * Surface used when a caller does not name one — and the value every existing\n * row is backfilled with on first boot after the surface migration.\n *\n * Hosts that only ever serve one surface declare it once in their environment\n * (`NEGOTIUM_DEFAULT_SURFACE=otium` on the Otium hub and worker); a developer\n * Mac leaves it unset and gets `terminal`, with the telegram adapter\n * reclassifying its own mapped rooms afterwards.\n */\nexport function defaultTopicSurface(): TopicSurface {\n return normalizeTopicSurface(process.env.NEGOTIUM_DEFAULT_SURFACE);\n}\n\nexport function normalizeTopicSurface(value: unknown): TopicSurface {\n return value === \"telegram\" || value === \"otium\" || value === \"terminal\" ? value : \"terminal\";\n}\n\n/**\n * The surface instance new rooms are filed under when the caller names none.\n *\n * `surface` alone is not enough once a node may be attached to several Otium\n * workspaces (M-2): two workspaces are two independent namespaces on the same\n * surface. The adapter that owns the attachment installs the active scope at\n * mount time; `terminal` and `telegram` are singletons and stay null.\n *\n * Kept as process state rather than an argument threaded through every creation\n * path because the value is a property of *this process's attachment*, not of\n * any individual call — the same reason `defaultTopicSurface()` exists.\n */\nlet activeSurfaceScope: string | null = null;\n\nexport function normalizeSurfaceScope(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n return trimmed ? trimmed : null;\n}\n\nexport function defaultSurfaceScope(): string | null {\n return activeSurfaceScope ?? normalizeSurfaceScope(process.env.NEGOTIUM_SURFACE_SCOPE);\n}\n\n/** Install (or clear) the scope new rooms inherit. Returns the previous value. */\nexport function setDefaultSurfaceScope(scope: string | null): string | null {\n const previous = activeSurfaceScope;\n activeSurfaceScope = normalizeSurfaceScope(scope);\n return previous;\n}\n\n/**\n * Whether an Otium room must name a workspace to be created at all (M-3).\n *\n * Off by default, and off for every single-workspace host: an unscoped room is\n * then legacy, reachable, and perfectly usable. The adapter turns it on only\n * while several workspaces are attached, because there an unscoped room is\n * reachable from none of them (M-10) — a room nobody can see is worse than a\n * refusal that says so.\n */\nlet surfaceScopeRequired = false;\n\nexport function setSurfaceScopeRequired(required: boolean): void {\n surfaceScopeRequired = required;\n}\n\nexport function isSurfaceScopeRequired(): boolean {\n return surfaceScopeRequired;\n}\n\nfunction tableColumns(table: string): Set<string> {\n const rows = db.query(`PRAGMA table_info(${table})`).all() as Array<{ name: string }>;\n return new Set(rows.map((row) => row.name));\n}\n\n/** Persist the authoritative agent and, when supplied, its normalized base defaults. */\nexport function setApiTopicAgent(\n topicId: string,\n agent: AgentKind,\n defaults?: { model: string; effort?: EffortLevel },\n): void {\n if (!defaults) {\n db.query(\"UPDATE api_topics SET agent = ? WHERE id = ?\").run(agent, topicId);\n return;\n }\n db.query(\"UPDATE api_topics SET agent = ?, base_model = ?, base_effort = ? WHERE id = ?\").run(\n agent,\n defaults.model,\n defaults.effort ?? null,\n topicId,\n );\n}\n\nfunction initializeApiTopicsSchema(): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS api_topics (\n id TEXT PRIMARY KEY,\n title TEXT NOT NULL,\n kind TEXT NOT NULL DEFAULT 'channel',\n description TEXT,\n agent TEXT,\n default_model TEXT,\n default_effort TEXT,\n participants TEXT,\n created_at TEXT NOT NULL,\n last_message_at TEXT,\n is_archived INTEGER NOT NULL DEFAULT 0,\n ai_mention INTEGER NOT NULL DEFAULT 0,\n ai_mode TEXT\n )\n`);\n\n const initialTopicColumns = tableColumns(\"api_topics\");\n const legacyTopicSchema = !initialTopicColumns.has(\"response_policy\");\n const needsCanonicalTopicRebuild = legacyTopicSchema || !initialTopicColumns.has(\"agent\");\n if (legacyTopicSchema) {\n // Rename the legacy column once; new databases are created with `agent`.\n try {\n db.exec(\"ALTER TABLE api_topics RENAME COLUMN default_agent TO agent\");\n } catch {\n // Already migrated or freshly created.\n }\n\n // Migrate existing DBs that predate the ai_mention column (team-mode topics).\n try {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN ai_mention INTEGER NOT NULL DEFAULT 0\");\n } catch {\n // Column already exists — nothing to do.\n }\n\n // Migrate for spawn/fork tracking (R1).\n try {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN parent_topic_id TEXT\");\n } catch {}\n try {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN is_fork INTEGER NOT NULL DEFAULT 0\");\n } catch {}\n\n // Migrate for agent-spawned subagent worker rooms.\n try {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN is_subagent INTEGER NOT NULL DEFAULT 0\");\n } catch {}\n\n // Migrate for session persistence.\n try {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN session_id TEXT\");\n } catch {}\n\n try {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN kind TEXT NOT NULL DEFAULT 'channel'\");\n } catch {}\n\n try {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN ai_mode TEXT\");\n } catch {}\n\n db.exec(`\n CREATE TABLE IF NOT EXISTS api_schema_migrations (\n key TEXT PRIMARY KEY,\n applied_at TEXT NOT NULL\n )\n`);\n\n const ALWAYS_RESPOND_MIGRATION = \"api_topics_ai_invited_default_always_respond_20260623\";\n const alwaysRespondMigration = db\n .query(\"SELECT key FROM api_schema_migrations WHERE key = ?\")\n .get(ALWAYS_RESPOND_MIGRATION);\n if (!alwaysRespondMigration) {\n db.transaction(() => {\n db.query(\"UPDATE api_topics SET ai_mention = 0 WHERE agent IS NOT NULL\").run();\n db.query(\"INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)\").run(\n ALWAYS_RESPOND_MIGRATION,\n new Date().toISOString(),\n );\n })();\n }\n\n const GENERAL_AGENT_KIND_MIGRATION = \"api_topics_general_agent_kind_20260704\";\n const generalAgentKindMigration = db\n .query(\"SELECT key FROM api_schema_migrations WHERE key = ?\")\n .get(GENERAL_AGENT_KIND_MIGRATION);\n if (!generalAgentKindMigration) {\n db.transaction(() => {\n db.query(\"UPDATE api_topics SET kind = 'agent', ai_mention = 0 WHERE id = ?\").run(\n GENERAL_TOPIC_ID,\n );\n db.query(\"INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)\").run(\n GENERAL_AGENT_KIND_MIGRATION,\n new Date().toISOString(),\n );\n })();\n }\n\n const AI_MODE_MIGRATION = \"api_topics_ai_mode_20260704\";\n const aiModeMigration = db\n .query(\"SELECT key FROM api_schema_migrations WHERE key = ?\")\n .get(AI_MODE_MIGRATION);\n if (!aiModeMigration) {\n db.transaction(() => {\n db.query(\n `UPDATE api_topics\n SET\n kind = CASE\n WHEN id = ? THEN 'agent'\n WHEN kind = 'channel' AND agent IS NOT NULL AND ai_mention = 0 THEN 'agent'\n ELSE kind\n END,\n ai_mode = CASE\n WHEN id = ? THEN 'always'\n WHEN agent IS NULL THEN 'off'\n WHEN kind = 'agent' THEN 'always'\n WHEN kind = 'channel' AND ai_mention != 0 THEN 'mention'\n WHEN kind = 'channel' AND ai_mention = 0 THEN 'always'\n WHEN ai_mention != 0 THEN 'mention'\n ELSE 'always'\n END`,\n ).run(GENERAL_TOPIC_ID, GENERAL_TOPIC_ID);\n db.query(\"INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)\").run(\n AI_MODE_MIGRATION,\n new Date().toISOString(),\n );\n })();\n }\n\n const GENERAL_MANAGER_KIND_MIGRATION = \"api_topics_general_manager_kind_20260704\";\n const generalManagerKindMigration = db\n .query(\"SELECT key FROM api_schema_migrations WHERE key = ?\")\n .get(GENERAL_MANAGER_KIND_MIGRATION);\n if (!generalManagerKindMigration) {\n db.transaction(() => {\n db.query(\n \"UPDATE api_topics SET kind = 'manager', ai_mention = 0, ai_mode = 'always' WHERE id = ?\",\n ).run(GENERAL_TOPIC_ID);\n db.query(\"INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)\").run(\n GENERAL_MANAGER_KIND_MIGRATION,\n new Date().toISOString(),\n );\n })();\n }\n }\n\n function createCanonicalTopicsTable(name: string): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS ${name} (\n id TEXT PRIMARY KEY,\n title TEXT NOT NULL,\n kind TEXT NOT NULL CHECK (kind IN ('channel','agent','manager')),\n description TEXT,\n agent TEXT CHECK (agent IS NULL OR agent IN ('maestro','claude','codex')),\n base_model TEXT,\n base_effort TEXT CHECK (base_effort IS NULL OR base_effort IN ('low','medium','high','xhigh','max')),\n response_policy TEXT NOT NULL CHECK (response_policy IN ('off','mention','always')),\n created_at TEXT NOT NULL,\n last_message_at TEXT,\n parent_topic_id TEXT,\n memory_topic_id TEXT,\n memory_key TEXT,\n is_fork INTEGER NOT NULL DEFAULT 0 CHECK (is_fork IN (0,1)),\n is_subagent INTEGER NOT NULL DEFAULT 0 CHECK (is_subagent IN (0,1)),\n visibility TEXT NOT NULL DEFAULT 'visible' CHECK (visibility IN ('visible','hidden')),\n surface TEXT NOT NULL DEFAULT 'terminal' CHECK (surface IN ('terminal','telegram','otium')),\n surface_scope TEXT,\n browser_profile TEXT NOT NULL DEFAULT 'default',\n browser_profile_owner TEXT,\n session_id TEXT,\n CHECK (\n (kind = 'channel' AND response_policy = 'off' AND agent IS NULL) OR\n (kind = 'channel' AND response_policy = 'mention' AND agent IS NOT NULL) OR\n (kind IN ('agent','manager') AND response_policy = 'always' AND agent IS NOT NULL)\n )\n )\n `);\n }\n\n function createTopicMembersTable(): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS topic_members (\n topic_id TEXT NOT NULL REFERENCES api_topics(id) ON DELETE CASCADE,\n user_id TEXT NOT NULL,\n role TEXT NOT NULL CHECK (role IN ('owner','member')),\n PRIMARY KEY (topic_id, user_id)\n )\n `);\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_topic_members_user ON topic_members(user_id)\");\n }\n\n if (needsCanonicalTopicRebuild) {\n const legacyRows = db.query(\"SELECT * FROM api_topics\").all() as Array<Record<string, unknown>>;\n const existingMemberRows = tableColumns(\"topic_members\").has(\"topic_id\")\n ? (db.query(\"SELECT topic_id, user_id, role FROM topic_members\").all() as Array<{\n topic_id: string;\n user_id: string;\n role: string;\n }>)\n : [];\n const configColumns = tableColumns(\"api_topic_config\");\n const legacyAgentOverrides = configColumns.has(\"agent\")\n ? new Map(\n (\n db\n .query(\"SELECT topic_id, agent FROM api_topic_config WHERE agent IS NOT NULL\")\n .all() as Array<{ topic_id: string; agent: AgentKind }>\n ).map((row) => [row.topic_id, row.agent]),\n )\n : new Map<string, AgentKind>();\n const previousForeignKeys = db\n .query<{ foreign_keys: number }, []>(\"PRAGMA foreign_keys\")\n .get()?.foreign_keys;\n db.exec(\"PRAGMA foreign_keys = OFF\");\n try {\n db.transaction(() => {\n createCanonicalTopicsTable(\"api_topics_next\");\n for (const row of legacyRows) {\n const selectedAgent = (legacyAgentOverrides.get(String(row.id)) ??\n row.agent ??\n row.runtime_agent ??\n row.default_agent ??\n undefined) as AgentKind | undefined;\n const normalized = normalizeTopicState({\n id: String(row.id),\n kind: normalizeTopicKind(row.kind),\n agent: selectedAgent,\n aiMode: normalizeAiMode(row.response_policy ?? row.ai_mode),\n aiMention: Number(row.ai_mention ?? 0) !== 0,\n });\n const legacyBaseModel = row.base_model ?? row.default_model;\n const legacyBaseEffort = row.base_effort ?? row.default_effort;\n db.query(\n `INSERT INTO api_topics_next\n (id,title,kind,description,agent,base_model,base_effort,response_policy,\n created_at,last_message_at,parent_topic_id,memory_topic_id,memory_key,is_fork,is_subagent,visibility,surface,surface_scope,session_id)\n VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,\n ).run(\n String(row.id),\n String(row.title),\n normalized.kind,\n typeof row.description === \"string\" ? row.description : null,\n normalized.agent ?? null,\n typeof legacyBaseModel === \"string\" ? legacyBaseModel : null,\n typeof legacyBaseEffort === \"string\" ? legacyBaseEffort : null,\n normalized.aiMode,\n String(row.created_at),\n typeof row.last_message_at === \"string\" ? row.last_message_at : null,\n typeof row.parent_topic_id === \"string\" ? row.parent_topic_id : null,\n typeof row.memory_topic_id === \"string\" ? row.memory_topic_id : null,\n typeof row.memory_key === \"string\" ? row.memory_key : null,\n Number(row.is_fork ?? 0) !== 0 ? 1 : 0,\n Number(row.is_subagent ?? 0) !== 0 ? 1 : 0,\n row.visibility === \"hidden\" ? \"hidden\" : \"visible\",\n row.surface === undefined ? defaultTopicSurface() : normalizeTopicSurface(row.surface),\n normalizeSurfaceScope(row.surface_scope),\n typeof row.session_id === \"string\" ? row.session_id : null,\n );\n }\n db.exec(\"DROP TABLE IF EXISTS topic_members\");\n db.exec(\"DROP TABLE api_topics\");\n db.exec(\"ALTER TABLE api_topics_next RENAME TO api_topics\");\n createTopicMembersTable();\n if (existingMemberRows.length > 0) {\n for (const member of existingMemberRows) {\n db.query(\n \"INSERT OR REPLACE INTO topic_members (topic_id,user_id,role) VALUES (?,?,?)\",\n ).run(member.topic_id, member.user_id, member.role === \"owner\" ? \"owner\" : \"member\");\n }\n } else {\n for (const row of legacyRows) {\n let participants: ParticipantDto[] = [];\n try {\n const parsed = JSON.parse(String(row.participants ?? \"[]\"));\n if (Array.isArray(parsed)) participants = parsed as ParticipantDto[];\n } catch {\n participants = [];\n }\n for (const participant of participants) {\n if (!participant?.userId) continue;\n db.query(\n \"INSERT OR REPLACE INTO topic_members (topic_id,user_id,role) VALUES (?,?,?)\",\n ).run(\n String(row.id),\n participant.userId,\n participant.role === \"owner\" ? \"owner\" : \"member\",\n );\n }\n }\n }\n })();\n } finally {\n db.exec(`PRAGMA foreign_keys = ${previousForeignKeys ? \"ON\" : \"OFF\"}`);\n }\n } else {\n createCanonicalTopicsTable(\"api_topics\");\n createTopicMembersTable();\n }\n\n db.exec(`\n CREATE TABLE IF NOT EXISTS subagent_tell_grants (\n subagent_topic_id TEXT NOT NULL REFERENCES api_topics(id) ON DELETE CASCADE,\n target_topic_id TEXT NOT NULL REFERENCES api_topics(id) ON DELETE CASCADE,\n granted_by_topic_id TEXT NOT NULL REFERENCES api_topics(id) ON DELETE CASCADE,\n created_at TEXT NOT NULL,\n PRIMARY KEY (subagent_topic_id, target_topic_id)\n )\n `);\n db.exec(`\n DELETE FROM subagent_tell_grants\n WHERE subagent_topic_id NOT IN (SELECT id FROM api_topics)\n OR target_topic_id NOT IN (SELECT id FROM api_topics)\n OR granted_by_topic_id NOT IN (SELECT id FROM api_topics)\n `);\n db.exec(\"DELETE FROM topic_members WHERE topic_id NOT IN (SELECT id FROM api_topics)\");\n\n // Canonical databases created before explicit adapter visibility need a\n // lightweight additive migration; fresh/rebuilt databases already have it.\n if (!tableColumns(\"api_topics\").has(\"visibility\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN visibility TEXT NOT NULL DEFAULT 'visible'\");\n }\n if (!tableColumns(\"api_topics\").has(\"surface\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN surface TEXT NOT NULL DEFAULT 'terminal'\");\n }\n if (!tableColumns(\"api_topics\").has(\"surface_scope\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN surface_scope TEXT\");\n }\n // `access_mode` was replaced by `surface`: a topic is reachable from Otium\n // because it lives there, not because a flag was flipped (S-4). Dropping the\n // column removes the second, now-contradictory source of truth.\n if (tableColumns(\"api_topics\").has(\"access_mode\")) {\n try {\n db.exec(\"ALTER TABLE api_topics DROP COLUMN access_mode\");\n } catch (err) {\n logger.warn({ err }, \"api_topics: could not drop the retired access_mode column\");\n }\n }\n if (!tableColumns(\"api_topics\").has(\"browser_profile\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN browser_profile TEXT NOT NULL DEFAULT 'default'\");\n }\n if (!tableColumns(\"api_topics\").has(\"browser_profile_owner\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN browser_profile_owner TEXT\");\n }\n if (!tableColumns(\"api_topics\").has(\"subagent_report_mode\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN subagent_report_mode TEXT NOT NULL DEFAULT 'auto'\");\n }\n if (!tableColumns(\"api_topics\").has(\"derived_by_user_id\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN derived_by_user_id TEXT\");\n }\n if (!tableColumns(\"api_topics\").has(\"memory_topic_id\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN memory_topic_id TEXT\");\n }\n if (!tableColumns(\"api_topics\").has(\"memory_key\")) {\n db.exec(\"ALTER TABLE api_topics ADD COLUMN memory_key TEXT\");\n }\n db.exec(`\n UPDATE api_topics\n SET browser_profile_owner = (\n SELECT m.user_id FROM topic_members m\n WHERE m.topic_id = api_topics.id AND m.role = 'owner'\n ORDER BY m.rowid\n LIMIT 1\n )\n WHERE browser_profile_owner IS NULL\n`);\n backfillTopicSurfaces();\n db.exec(\n \"CREATE INDEX IF NOT EXISTS idx_api_topics_last_message ON api_topics(last_message_at DESC)\",\n );\n db.exec(\"CREATE INDEX IF NOT EXISTS idx_api_topics_surface ON api_topics(surface)\");\n db.exec(\n \"CREATE INDEX IF NOT EXISTS idx_api_topics_surface_scope ON api_topics(surface, surface_scope)\",\n );\n}\n\nconst SURFACE_SCOPE_STAMP_MIGRATION = \"api_topics_surface_scope_stamp_20260809\";\n\n/**\n * M-9 — file every pre-existing Otium room under the workspace attached now.\n *\n * Deliberately *not* a schema-init step. The scope is only knowable after the\n * first successful Central contact (M-3), which happens long after the store\n * opens; a boot-time migration would see no scope, record itself as applied and\n * leave every room unstamped forever. The Otium runtime calls this instead, once,\n * as soon as it has resolved its workspace.\n *\n * Runs at most once per store: rooms created after this point are stamped at\n * creation, and a second workspace joined later must not swallow the first\n * one's rooms. Unlike the surface migration this can never rename anything —\n * the scope enters the uniqueness key in the same release, so nothing can start\n * colliding because of it.\n */\nexport function stampUnscopedOtiumTopics(scope: string): number {\n const normalized = normalizeSurfaceScope(scope);\n if (!normalized) return 0;\n db.exec(`\n CREATE TABLE IF NOT EXISTS api_schema_migrations (\n key TEXT PRIMARY KEY,\n applied_at TEXT NOT NULL\n )\n`);\n const applied = db\n .query(\"SELECT key FROM api_schema_migrations WHERE key = ?\")\n .get(SURFACE_SCOPE_STAMP_MIGRATION);\n if (applied) return 0;\n\n let stamped = 0;\n db.transaction(() => {\n stamped = Number(\n db\n .query(\n \"UPDATE api_topics SET surface_scope = ? WHERE surface = 'otium' AND surface_scope IS NULL\",\n )\n .run(normalized).changes ?? 0,\n );\n db.query(\"INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)\").run(\n SURFACE_SCOPE_STAMP_MIGRATION,\n new Date().toISOString(),\n );\n })();\n if (stamped > 0) {\n logger.info({ scope: normalized, stamped }, \"api_topics: surface scope stamped\");\n }\n return stamped;\n}\n\nconst SURFACE_BACKFILL_MIGRATION = \"api_topics_surface_backfill_20260808\";\n\n/**\n * One-time classification of pre-surface topics.\n *\n * Every row predates the column, so there is no per-row evidence in this store\n * to distinguish surfaces — the host declares it (`NEGOTIUM_DEFAULT_SURFACE`).\n * The telegram adapter owns the second pass: its chat↔topic mapping lives in a\n * different database file, so only it can reclassify the rooms it created.\n *\n * Names are unique per surface from now on, so collapsing three namespaces into\n * one can produce duplicates. Rather than failing the boot, the oldest room\n * keeps the name and the rest are suffixed — a rename is recoverable, a node\n * that refuses to start is not.\n */\nfunction backfillTopicSurfaces(): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS api_schema_migrations (\n key TEXT PRIMARY KEY,\n applied_at TEXT NOT NULL\n )\n`);\n const applied = db\n .query(\"SELECT key FROM api_schema_migrations WHERE key = ?\")\n .get(SURFACE_BACKFILL_MIGRATION);\n if (applied) return;\n\n const surface = defaultTopicSurface();\n db.transaction(() => {\n db.query(\"UPDATE api_topics SET surface = ?\").run(surface);\n renameSurfaceTitleCollisions();\n db.query(\"INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)\").run(\n SURFACE_BACKFILL_MIGRATION,\n new Date().toISOString(),\n );\n })();\n logger.info({ surface }, \"api_topics: surface backfilled\");\n}\n\n/**\n * Suffix duplicate `(surface, kind, title)` rows so the new uniqueness rule holds.\n *\n * Manager rooms are excluded: they are one per user, so on a multi-user host\n * every member has a personal room with the same title and none of them is a\n * duplicate. Renaming those relabels real rooms belonging to other people.\n */\nfunction renameSurfaceTitleCollisions(): void {\n const rows = db\n .query<{ id: string; title: string; kind: string; surface: string }, []>(\n \"SELECT id, title, kind, surface FROM api_topics WHERE kind != 'manager' ORDER BY created_at ASC, rowid ASC\",\n )\n .all();\n const keyOf = (surface: string, kind: string, title: string) =>\n [surface, kind, normalizedTitle(title)].join(\"\\u0000\");\n // Every original title is reserved up front. Allocating only against the\n // titles seen so far would let an earlier duplicate claim \"Foo (2)\" while a\n // real room already named \"Foo (2)\" sits later in the scan — that room would\n // then be pushed to \"Foo (2) (2)\" for no reason.\n const reserved = new Set(rows.map((row) => keyOf(row.surface, row.kind, row.title)));\n const used = new Set<string>();\n const update = db.query(\"UPDATE api_topics SET title = ? WHERE id = ?\");\n for (const row of rows) {\n const key = (title: string) => keyOf(row.surface, row.kind, title);\n if (!used.has(key(row.title))) {\n used.add(key(row.title));\n continue;\n }\n let suffix = 2;\n let candidate = `${row.title} (${suffix})`;\n while (reserved.has(key(candidate)) || used.has(key(candidate))) {\n suffix += 1;\n candidate = `${row.title} (${suffix})`;\n }\n used.add(key(candidate));\n update.run(candidate, row.id);\n logger.warn(\n { topicId: row.id, surface: row.surface, from: row.title, to: candidate },\n \"api_topics: renamed a duplicate title for surface-scoped uniqueness\",\n );\n }\n}\n\nregisterStorageSchemaInitializer(initializeApiTopicsSchema, 20);\n\nexport interface TopicRow {\n id: string;\n title: string;\n kind: string | null;\n description: string | null;\n agent: string | null;\n base_model: string | null;\n base_effort: string | null;\n response_policy: string;\n created_at: string;\n last_message_at: string | null;\n parent_topic_id: string | null;\n memory_topic_id: string | null;\n memory_key: string | null;\n is_fork: number;\n is_subagent: number;\n subagent_report_mode: string | null;\n derived_by_user_id: string | null;\n visibility: string | null;\n surface: string | null;\n surface_scope: string | null;\n browser_profile_owner: string | null;\n session_id: string | null;\n}\n\nexport interface TopicSessionLogContext {\n reason?: string;\n queryId?: string;\n agent?: AgentKind;\n}\n\nfunction shortSessionId(sessionId: string | null | undefined): string | null {\n return sessionId ? sessionId.slice(0, 8) : null;\n}\n\nfunction getTopicParticipants(topicId: string): ParticipantDto[] {\n return db\n .query<{ user_id: string; role: \"owner\" | \"member\" }, string>(\n \"SELECT user_id, role FROM topic_members WHERE topic_id = ? ORDER BY rowid\",\n )\n .all(topicId)\n .map((row) => ({ userId: row.user_id, role: row.role }));\n}\n\nfunction getAllTopicParticipants(): Map<string, ParticipantDto[]> {\n const grouped = new Map<string, ParticipantDto[]>();\n const rows = db\n .query<{ topic_id: string; user_id: string; role: \"owner\" | \"member\" }, []>(\n \"SELECT topic_id, user_id, role FROM topic_members ORDER BY rowid\",\n )\n .all();\n for (const row of rows) {\n const participants = grouped.get(row.topic_id) ?? [];\n participants.push({ userId: row.user_id, role: row.role });\n grouped.set(row.topic_id, participants);\n }\n return grouped;\n}\n\nfunction getAllSubagentTellTargets(): Map<string, string[]> {\n const rows = db\n .query(\n \"SELECT subagent_topic_id, target_topic_id FROM subagent_tell_grants ORDER BY created_at\",\n )\n .all() as Array<{ subagent_topic_id: string; target_topic_id: string }>;\n const grouped = new Map<string, string[]>();\n for (const row of rows) {\n const targets = grouped.get(row.subagent_topic_id) ?? [];\n targets.push(row.target_topic_id);\n grouped.set(row.subagent_topic_id, targets);\n }\n return grouped;\n}\n\nfunction rowToDto(\n r: TopicRow,\n participants = getTopicParticipants(r.id),\n tellTargets?: Map<string, string[]>,\n): TopicDto {\n const normalized = normalizeTopicState({\n id: r.id,\n kind: normalizeTopicKind(r.kind),\n agent: (r.agent as AgentKind | null) ?? undefined,\n aiMode: normalizeAiMode(r.response_policy),\n });\n return {\n id: r.id,\n title: r.title,\n kind: normalized.kind,\n description: r.description ?? undefined,\n agent: normalized.agent,\n defaultModel: r.base_model ?? \"deepseek-pro\",\n defaultEffort: (r.base_effort as EffortLevel) ?? undefined,\n aiMode: normalized.aiMode,\n aiMention: aiMentionFromMode(normalized.aiMode),\n participants,\n createdAt: r.created_at,\n lastMessageAt: r.last_message_at ?? new Date().toISOString(),\n parentTopicId: r.parent_topic_id ?? undefined,\n memoryTopicId: r.memory_topic_id ?? undefined,\n memoryKey: r.memory_key ?? undefined,\n isFork: r.is_fork !== 0,\n ...(r.derived_by_user_id ? { derivedByUserId: r.derived_by_user_id } : {}),\n ...(r.is_subagent !== 0 ? { isSubagent: true } : {}),\n ...(r.is_subagent !== 0\n ? {\n subagentTellTargetIds: tellTargets\n ? (tellTargets.get(r.id) ?? [])\n : listSubagentTellTargetIds(r.id),\n }\n : {}),\n ...(r.is_subagent !== 0\n ? {\n subagentReportMode: (r.subagent_report_mode === \"tell\" ||\n r.subagent_report_mode === \"status-only\"\n ? r.subagent_report_mode\n : \"auto\") as SubagentReportMode,\n }\n : {}),\n visibility: normalizeTopicVisibility(r.visibility),\n surface: normalizeTopicSurface(r.surface),\n surfaceScope: normalizeSurfaceScope(r.surface_scope),\n };\n}\n\nexport function normalizeTopicVisibility(value: unknown): TopicVisibility {\n return value === \"hidden\" ? \"hidden\" : \"visible\";\n}\n\n/** Discovery boundary shared by user-facing adapters. */\nexport function isTopicVisible(topic: Pick<TopicDto, \"visibility\">): boolean {\n return topic.visibility !== \"hidden\";\n}\n\nexport function normalizeTopicKind(value: unknown): TopicKind | null {\n return value === \"channel\" || value === \"agent\" || value === \"manager\" ? value : null;\n}\n\nexport function normalizeAiMode(value: unknown): AiMode | null {\n return value === \"off\" || value === \"mention\" || value === \"always\" ? value : null;\n}\n\nexport function aiMentionFromMode(mode: AiMode): boolean {\n return mode === \"mention\";\n}\n\nexport function inferTopicKind(input: {\n agent?: string | null;\n aiMention?: boolean | null;\n}): TopicKind {\n return input.agent && input.aiMention !== true ? \"agent\" : \"channel\";\n}\n\nexport function inferAiMode(input: {\n kind?: TopicKind | null;\n agent?: string | null;\n aiMode?: AiMode | null;\n aiMention?: boolean | null;\n}): AiMode {\n if (input.kind === \"manager\") return \"always\";\n if (input.kind === \"agent\") return \"always\";\n if (input.kind === \"channel\") {\n if (!input.agent) return \"off\";\n if (input.aiMode === \"mention\") return \"mention\";\n if (input.aiMention === true) return \"mention\";\n return \"mention\";\n }\n if (!input.agent) return \"off\";\n if (input.aiMode) return input.aiMode;\n return input.aiMention === true ? \"mention\" : \"always\";\n}\n\nexport function normalizeTopicState(input: {\n id?: string;\n kind?: TopicKind | null;\n agent?: AgentKind | null;\n aiMode?: AiMode | null;\n aiMention?: boolean | null;\n}): { kind: TopicKind; aiMode: AiMode; agent?: AgentKind } {\n if (input.kind === \"manager\" || input.id === GENERAL_TOPIC_ID) {\n return {\n kind: \"manager\",\n aiMode: \"always\",\n agent: input.agent ?? resolveFallbackAgent(),\n };\n }\n\n const requestedKind = input.kind;\n const kind =\n requestedKind ??\n (input.aiMode === \"always\"\n ? \"agent\"\n : input.aiMode === \"mention\" || input.aiMode === \"off\"\n ? \"channel\"\n : input.agent && input.aiMention !== true\n ? \"agent\"\n : \"channel\");\n\n if (kind === \"agent\") {\n return {\n kind: \"agent\",\n aiMode: \"always\",\n agent: input.agent ?? resolveFallbackAgent(),\n };\n }\n\n const agent = input.aiMode === \"off\" ? undefined : (input.agent ?? undefined);\n return {\n kind: \"channel\",\n aiMode: agent ? \"mention\" : \"off\",\n agent,\n };\n}\n\nfunction normalizedTitle(title: string): string {\n return title.trim().toLowerCase();\n}\n\n/**\n * The workspace a written row belongs to.\n *\n * `surfaceScope` partitions one surface into independent namespaces. Otium\n * uses a workspace scope and Telegram uses a forum-group scope. Terminal is\n * normally unscoped. An explicit value always wins; only Otium has a\n * process-level default because its workspace attachment is host state.\n */\nfunction surfaceScopeForWrite(t: TopicDto): string | null {\n if (t.surfaceScope !== undefined) return normalizeSurfaceScope(t.surfaceScope);\n return normalizeTopicSurface(t.surface ?? defaultTopicSurface()) === \"otium\"\n ? defaultSurfaceScope()\n : null;\n}\n\nexport function upsertTopic(t: TopicDto): void {\n const normalized = normalizeTopicState({\n id: t.id,\n kind: normalizeTopicKind(t.kind),\n agent: t.agent ?? undefined,\n aiMode: normalizeAiMode(t.aiMode),\n aiMention: t.aiMention,\n });\n db.transaction(() => {\n db.query(\n `INSERT INTO api_topics\n (id,title,kind,description,agent,base_model,base_effort,response_policy,\n created_at,last_message_at,parent_topic_id,memory_topic_id,memory_key,is_fork,is_subagent,visibility,surface,\n surface_scope,subagent_report_mode,derived_by_user_id)\n VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)\n ON CONFLICT(id) DO UPDATE SET\n title = excluded.title,\n kind = excluded.kind,\n description = excluded.description,\n agent = excluded.agent,\n base_model = excluded.base_model,\n base_effort = excluded.base_effort,\n response_policy = excluded.response_policy,\n created_at = excluded.created_at,\n last_message_at = excluded.last_message_at,\n parent_topic_id = excluded.parent_topic_id,\n memory_topic_id = excluded.memory_topic_id,\n memory_key = excluded.memory_key,\n is_fork = excluded.is_fork,\n is_subagent = excluded.is_subagent,\n visibility = excluded.visibility,\n surface = excluded.surface,\n -- A room's workspace is fixed at creation (M-1). COALESCE, not\n -- assignment: an update may fill in a scope that was unknown when the\n -- room was created, but may never move a room to another workspace.\n surface_scope = COALESCE(api_topics.surface_scope, excluded.surface_scope),\n subagent_report_mode = excluded.subagent_report_mode,\n -- Who asked for the derive is a fact about creation; a later update\n -- that omits it must not erase it.\n derived_by_user_id = COALESCE(excluded.derived_by_user_id, api_topics.derived_by_user_id)`,\n ).run(\n t.id,\n t.title,\n normalized.kind,\n t.description ?? null,\n normalized.agent ?? null,\n t.defaultModel ?? null,\n t.defaultEffort ?? null,\n normalized.aiMode,\n t.createdAt,\n t.lastMessageAt ?? null,\n t.parentTopicId ?? null,\n t.memoryTopicId ?? null,\n t.memoryKey ?? null,\n t.isFork ? 1 : 0,\n t.isSubagent ? 1 : 0,\n normalizeTopicVisibility(t.visibility),\n // A DTO without a surface means \"wherever this host puts rooms\", not\n // \"terminal\": embedding hosts (Otium) build topic literals by hand and\n // never name one, so defaulting to the literal would file every hub room\n // on the wrong surface.\n normalizeTopicSurface(t.surface ?? defaultTopicSurface()),\n surfaceScopeForWrite(t),\n t.subagentReportMode ?? \"auto\",\n t.derivedByUserId ?? null,\n );\n db.query(\"DELETE FROM topic_members WHERE topic_id = ?\").run(t.id);\n for (const participant of t.participants) {\n db.query(\"INSERT INTO topic_members (topic_id,user_id,role) VALUES (?,?,?)\").run(\n t.id,\n participant.userId,\n participant.role,\n );\n }\n const initialBrowserProfileOwner = t.participants.find(\n (participant) => participant.role === \"owner\",\n )?.userId;\n if (initialBrowserProfileOwner) {\n db.query(\n `UPDATE api_topics\n SET browser_profile_owner = COALESCE(browser_profile_owner, ?)\n WHERE id = ?`,\n ).run(initialBrowserProfileOwner, t.id);\n }\n })();\n}\n\n/**\n * List topics, optionally restricted to one surface.\n *\n * The filter lives here rather than in each adapter so a forgotten call site\n * cannot leak a telegram room into the terminal picker; adapters pass their own\n * surface and get a closed world back.\n */\nexport function listTopics(\n opts: { surface?: TopicSurface; surfaceScope?: string | null } = {},\n): TopicDto[] {\n // `surfaceScope: null` is a real filter (\"the unscoped rooms\"), so presence —\n // not truthiness — decides whether the scope narrows the query at all.\n const scoped = Object.hasOwn(opts, \"surfaceScope\");\n const rows = (\n opts.surface\n ? db\n .query(\n `SELECT * FROM api_topics WHERE surface = ?${scoped ? \" AND surface_scope IS ?\" : \"\"} ORDER BY last_message_at DESC`,\n )\n .all(\n ...(scoped\n ? [normalizeTopicSurface(opts.surface), normalizeSurfaceScope(opts.surfaceScope)]\n : [normalizeTopicSurface(opts.surface)]),\n )\n : db.query(\"SELECT * FROM api_topics ORDER BY last_message_at DESC\").all()\n ) as TopicRow[];\n const participants = getAllTopicParticipants();\n // Batch-load tell grants once: per-row queries would make every listTopics()\n // call O(N) extra statements as subagent counts grow.\n const tellTargets = rows.some((row) => row.is_subagent !== 0)\n ? getAllSubagentTellTargets()\n : undefined;\n return rows.map((row) => rowToDto(row, participants.get(row.id) ?? [], tellTargets));\n}\n\nexport function getTopic(id: string): TopicDto | null {\n const r = db.query(\"SELECT * FROM api_topics WHERE id = ?\").get(id) as TopicRow | undefined;\n return r ? rowToDto(r) : null;\n}\n\n/** Return the private manager room owned by a user, excluding the retired shared General row. */\n/**\n * The user's own manager room, optionally on one surface.\n *\n * A manager room is one per user **per surface**: Terminal and Telegram each\n * give the same person their own personal room, and returning one surface's\n * room to the other adapter lets that adapter bind to — and reclassify — a room\n * belonging to a different surface. Callers that represent an adapter pass\n * theirs; unscoped lookups stay for maintenance paths that work by user alone.\n */\nexport function getManagerTopicForUser(\n userId: string,\n surface?: TopicSurface,\n opts: { surfaceScope?: string | null } = {},\n): TopicDto | null {\n const scoped = Object.hasOwn(opts, \"surfaceScope\");\n const sql = `SELECT t.* FROM api_topics t\n JOIN topic_members m ON m.topic_id = t.id\n WHERE t.kind = 'manager'\n AND t.id != ?\n AND m.user_id = ?\n AND m.role = 'owner'\n ${surface ? \"AND t.surface = ?\" : \"\"}\n ${scoped ? \"AND t.surface_scope IS ?\" : \"\"}\n ORDER BY t.created_at ASC\n LIMIT 1`;\n const params: Array<string | null> = [GENERAL_TOPIC_ID, userId];\n if (surface) params.push(surface);\n if (scoped) params.push(normalizeSurfaceScope(opts.surfaceScope));\n const row = db.query<TopicRow, Array<string | null>>(sql).get(...params);\n return row ? rowToDto(row) : null;\n}\n\n/**\n * Resolve the topic whose wiki memory should be used for this topic.\n *\n * Derived rooms keep `parentTopicId` as an immediate UI link. Memory normally\n * follows the chain to its original root, while `memoryTopicId` can redirect a\n * subagent to another accessible topic's accumulated knowledge.\n */\nexport function getTopicMemoryOrigin(id: string): TopicDto | null {\n let current = getTopic(id);\n if (!current) return null;\n\n const seen = new Set<string>([current.id]);\n while (true) {\n const nextId = current.memoryTopicId ?? current.parentTopicId;\n if (!nextId || seen.has(nextId)) break;\n const next = getTopic(nextId);\n if (!next) {\n // An explicitly selected memory topic that no longer resolves must not\n // silently fall back to the parent chain — that would leak the parent\n // room's memory to a subagent that asked for something else. Stop at the\n // current topic instead so the broken source is visible.\n if (current.memoryTopicId) {\n console.warn(\n `[topics] memory topic ${current.memoryTopicId} for ${current.id} is unresolvable; using the topic's own memory`,\n );\n }\n break;\n }\n current = next;\n seen.add(current.id);\n }\n\n return current;\n}\n\n/** Look up a topic by its user-visible title (case-insensitive exact match). */\nexport function getTopicByName(title: string): TopicDto | null {\n const r = db.query(\"SELECT * FROM api_topics WHERE LOWER(title) = LOWER(?)\").get(title) as\n | TopicRow\n | undefined;\n return r ? rowToDto(r) : null;\n}\n\nexport function getTopicByNameAndKind(title: string, kind: TopicKind): TopicDto | null {\n const r = db\n .query(\"SELECT * FROM api_topics WHERE LOWER(title) = LOWER(?) AND kind = ?\")\n .get(title, kind) as TopicRow | undefined;\n return r ? rowToDto(r) : null;\n}\n\n/**\n * Titles are unique **per surface namespace**, not per node: the same title may\n * exist on terminal, in multiple Telegram groups, and in each attached Otium\n * workspace. Independent namespaces never see each other, so a name taken in\n * one says nothing about another.\n */\nexport function findTopicTitleConflict(\n title: string,\n kind: TopicKind,\n opts: { excludeTopicId?: string; surface?: TopicSurface; surfaceScope?: string | null } = {},\n): TopicDto | null {\n const wanted = normalizedTitle(title);\n const surface = normalizeTopicSurface(opts.surface ?? defaultTopicSurface());\n const surfaceScope = Object.hasOwn(opts, \"surfaceScope\")\n ? normalizeSurfaceScope(opts.surfaceScope)\n : surface === \"otium\"\n ? defaultSurfaceScope()\n : null;\n const generalTitleRequested = wanted === normalizedTitle(GENERAL_TOPIC_ID);\n if (generalTitleRequested && opts.excludeTopicId !== GENERAL_TOPIC_ID) {\n const general = db.query(\"SELECT * FROM api_topics WHERE id = ?\").get(GENERAL_TOPIC_ID) as\n | TopicRow\n | undefined;\n if (general) return rowToDto(general);\n }\n\n // Manager rooms are one-per-user and system-created, so several of them\n // legitimately share a title (every member's personal \"General\"). Comparing\n // them against each other is not a conflict, it is the design — on a\n // multi-user host it renamed real rooms out from under their owners.\n if (kind === \"manager\") return null;\n\n const params: Array<string | null> = [wanted, surface, surfaceScope, kind, GENERAL_TOPIC_ID];\n let sql =\n \"SELECT * FROM api_topics WHERE LOWER(TRIM(title)) = ? AND surface = ? AND surface_scope IS ? AND (kind = ? OR id = ?)\";\n if (opts.excludeTopicId) {\n sql += \" AND id != ?\";\n params.push(opts.excludeTopicId);\n }\n sql += \" LIMIT 1\";\n const row = db.query<TopicRow, string[]>(sql).get(...params);\n return row ? rowToDto(row) : null;\n}\n\n/**\n * Move topics onto a surface. Used by adapters that own a classification the\n * canonical store cannot derive on its own (the telegram chat↔topic mapping\n * lives in that adapter's database, not this one).\n */\nexport function setTopicSurfaces(topicIds: readonly string[], surface: TopicSurface): number {\n if (topicIds.length === 0) return 0;\n const normalized = normalizeTopicSurface(surface);\n let changed = 0;\n db.transaction(() => {\n const update = db.query(\"UPDATE api_topics SET surface = ? WHERE id = ? AND surface != ?\");\n for (const topicId of topicIds) {\n changed += Number(update.run(normalized, topicId, normalized).changes ?? 0);\n }\n })();\n return changed;\n}\n\n/**\n * File an existing topic into one surface namespace without changing its id.\n * Adapter-owned migrations use this when their local mapping store is the only\n * authority capable of deriving the namespace (for example Telegram chat id).\n */\nexport function setTopicSurfaceScope(\n topicId: string,\n surface: TopicSurface,\n surfaceScope: string | null,\n): boolean {\n const normalizedSurface = normalizeTopicSurface(surface);\n const normalizedScope = normalizeSurfaceScope(surfaceScope);\n const result = db\n .query(\n `UPDATE api_topics SET surface = ?, surface_scope = ?\n WHERE id = ? AND (surface IS NOT ? OR surface_scope IS NOT ?)`,\n )\n .run(normalizedSurface, normalizedScope, topicId, normalizedSurface, normalizedScope);\n return Number(result.changes ?? 0) > 0;\n}\n\n/**\n * How wide a title lookup is allowed to reach.\n *\n * `surface` is required rather than optional. It used to default to \"search\n * every surface\", which contradicted S-6's promise that a missed call site\n * \"cannot leak a topic across surfaces\" — the guarantee only held where a\n * caller remembered to opt in, and four did not: Telegram's `/load` and `/del`\n * (the latter could delete a terminal room), the runtime MCP id path, the cron\n * id path, and the session inbox. Every one of those was a silent leak with a\n * correct-looking call. Making the parameter explicit turns each future\n * omission into a compile error instead.\n *\n * `{ scope: \"all\" }` is the deliberate way to search every surface. It exists\n * for operator tooling — the CLI manages jobs across surfaces on purpose — and\n * reads as a decision at the call site rather than as an oversight.\n */\nexport type TopicNameLookupScope =\n | { surface: TopicSurface; surfaceScope?: string | null }\n | { scope: \"all\" };\n\n/**\n * Look up a topic by title, restricted to topics where `userId` participates.\n *\n * Answers only on a single match: a title is unique per surface (S-3), so an\n * `{ scope: \"all\" }` lookup of a name used on two surfaces resolves to null\n * rather than picking one.\n */\nexport function getTopicByNameForUser(\n title: string,\n userId: string,\n lookupScope: TopicNameLookupScope,\n): TopicDto | null {\n const opts: { surface?: TopicSurface; surfaceScope?: string | null } =\n \"scope\" in lookupScope ? {} : lookupScope;\n const trimmed = title.trim();\n const qualified = /^(agent|channel|manager):(.+)$/i.exec(trimmed);\n const requestedKind = qualified ? normalizeTopicKind(qualified[1]?.toLowerCase()) : null;\n const requestedTitle = qualified ? qualified[2]!.trim() : trimmed;\n const scoped = Object.hasOwn(opts, \"surfaceScope\");\n const rows = db\n .query(\n `SELECT t.* FROM api_topics t\n WHERE LOWER(t.title) = LOWER(?)\n AND t.id != ?\n AND t.visibility != 'hidden'\n AND (? IS NULL OR t.surface = ?)\n ${scoped ? \"AND t.surface_scope IS ?\" : \"\"}\n AND EXISTS (\n SELECT 1 FROM topic_members m WHERE m.topic_id = t.id AND m.user_id = ?\n )`,\n )\n .all(\n requestedTitle,\n GENERAL_TOPIC_ID,\n opts.surface ?? null,\n opts.surface ?? null,\n ...(scoped ? [normalizeSurfaceScope(opts.surfaceScope)] : []),\n userId,\n ) as TopicRow[];\n const matches = requestedKind ? rows.filter((row) => row.kind === requestedKind) : rows;\n return matches.length === 1 ? rowToDto(matches[0]!) : null;\n}\n\n/** Persist the agent session ID for a topic after a successful turn. */\nexport function setTopicSessionId(\n topicId: string,\n sessionId: string,\n context: TopicSessionLogContext = {},\n): void {\n const previous = getTopicSessionId(topicId);\n const result = db\n .query(\"UPDATE api_topics SET session_id = ? WHERE id = ?\")\n .run(sessionId, topicId);\n const changes = Number(result.changes ?? 0);\n const logContext = {\n topicId,\n previousSessionId: shortSessionId(previous),\n sessionId: shortSessionId(sessionId),\n reason: context.reason,\n queryId: context.queryId,\n agent: context.agent,\n };\n if (changes === 0) {\n logger.warn(logContext, \"api-topic session_id update missed topic\");\n } else if (previous !== sessionId) {\n logger.debug(logContext, \"api-topic session_id updated\");\n } else {\n logger.debug(logContext, \"api-topic session_id unchanged\");\n }\n}\n\n/** Clear the session ID (e.g. on topic reset). */\nexport function clearTopicSessionId(topicId: string, reason = \"unspecified\"): void {\n const previous = getTopicSessionId(topicId);\n const result = db.query(\"UPDATE api_topics SET session_id = NULL WHERE id = ?\").run(topicId);\n const changes = Number(result.changes ?? 0);\n const logContext = { topicId, previousSessionId: shortSessionId(previous), reason };\n if (changes === 0) {\n logger.warn(logContext, \"api-topic session_id clear missed topic\");\n } else if (previous) {\n logger.info(logContext, \"api-topic session_id cleared\");\n } else {\n logger.debug(logContext, \"api-topic session_id already clear\");\n }\n}\n\n/** Read the persisted session ID for a topic, or null if none. */\nexport function getTopicSessionId(topicId: string): string | null {\n const r = db\n .query<{ session_id: string | null }, string>(\"SELECT session_id FROM api_topics WHERE id = ?\")\n .get(topicId);\n return r?.session_id ?? null;\n}\n\n/**\n * Hard-delete a topic row. Irreversible — the caller is responsible for also\n * deleting the topic's messages (see `deleteMessagesForTopic`). Returns false\n * if the topic didn't exist.\n */\nexport function deleteTopic(id: string, options: { allowManager?: boolean } = {}): boolean {\n const r = db\n .query<{ id: string; kind: string }, string>(\"SELECT id, kind FROM api_topics WHERE id = ?\")\n .get(id);\n if (!r) return false;\n if (id === GENERAL_TOPIC_ID || (r.kind === \"manager\" && !options.allowManager)) return false;\n db.query(\n `DELETE FROM subagent_tell_grants\n WHERE subagent_topic_id = ? OR target_topic_id = ? OR granted_by_topic_id = ?`,\n ).run(id, id, id);\n db.query(\"DELETE FROM topic_members WHERE topic_id = ?\").run(id);\n db.query(\"DELETE FROM api_topics WHERE id = ?\").run(id);\n return true;\n}\n\nexport function listSubagentTellTargetIds(subagentTopicId: string): string[] {\n return db\n .query<{ target_topic_id: string }, string>(\n \"SELECT target_topic_id FROM subagent_tell_grants WHERE subagent_topic_id = ? ORDER BY created_at\",\n )\n .all(subagentTopicId)\n .map((row) => row.target_topic_id);\n}\n\nexport function grantSubagentTellTarget(\n subagentTopicId: string,\n targetTopicId: string,\n grantedByTopicId: string,\n): void {\n db.query(\n `INSERT INTO subagent_tell_grants\n (subagent_topic_id,target_topic_id,granted_by_topic_id,created_at)\n VALUES (?,?,?,?)\n ON CONFLICT(subagent_topic_id,target_topic_id) DO UPDATE SET\n granted_by_topic_id = excluded.granted_by_topic_id`,\n ).run(subagentTopicId, targetTopicId, grantedByTopicId, new Date().toISOString());\n}\n\nexport function revokeSubagentTellTarget(subagentTopicId: string, targetTopicId: string): boolean {\n return (\n db\n .query(\"DELETE FROM subagent_tell_grants WHERE subagent_topic_id = ? AND target_topic_id = ?\")\n .run(subagentTopicId, targetTopicId).changes > 0\n );\n}\n\n/**\n * Preserve a derived-topic chain when an intermediate parent is deleted.\n * Direct children move to the deleted topic's parent (or become roots) rather\n * than retaining a dangling parent id that would break memory-origin lookup.\n */\n/** Ids of the subagent worker rooms spawned directly from `parentTopicId`. */\nexport function listSubagentChildTopicIds(parentTopicId: string): string[] {\n return db\n .query<{ id: string }, string>(\n \"SELECT id FROM api_topics WHERE parent_topic_id = ? AND is_subagent = 1 ORDER BY created_at\",\n )\n .all(parentTopicId)\n .map((row) => row.id);\n}\n\nexport function reparentTopicChildren(\n deletedTopicId: string,\n replacementParentTopicId: string | null,\n): string[] {\n const rows = db\n .query<{ id: string }, string>(\"SELECT id FROM api_topics WHERE parent_topic_id = ?\")\n .all(deletedTopicId);\n if (rows.length === 0) return [];\n db.query(\"UPDATE api_topics SET parent_topic_id = ? WHERE parent_topic_id = ?\").run(\n replacementParentTopicId,\n deletedTopicId,\n );\n // Reparenting can move a topic out of the subtree whose manager granted its\n // tell edges; purge involved grants (fail closed) — an ancestor can re-grant.\n for (const row of rows) {\n db.query(\n \"DELETE FROM subagent_tell_grants WHERE subagent_topic_id = ? OR target_topic_id = ?\",\n ).run(row.id, row.id);\n }\n return rows.map((row) => row.id);\n}\n\nexport function addParticipantToDB(\n topicId: string,\n userId: string,\n role: \"member\" | \"owner\",\n): boolean {\n if (!db.query(\"SELECT 1 FROM api_topics WHERE id = ?\").get(topicId)) return false;\n db.query(\"INSERT OR IGNORE INTO topic_members (topic_id,user_id,role) VALUES (?,?,?)\").run(\n topicId,\n userId,\n role,\n );\n return true;\n}\n\nexport function removeParticipantFromDB(topicId: string, userId: string): boolean {\n if (!db.query(\"SELECT 1 FROM api_topics WHERE id = ?\").get(topicId)) return false;\n db.query(\"DELETE FROM topic_members WHERE topic_id = ? AND user_id = ?\").run(topicId, userId);\n return true;\n}\n",
32
+ "import { accessSync, constants as fsConstants } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { explicitAgentSwitchTargets } from \"#agents/explicit-agent-switch\";\n\nimport { canonicalMcpBridgeEnv } from \"#mcp/canonical-bridge-config\";\nimport {\n buildHostedMcpSpec,\n buildRuntimeMcpSpec,\n type HostedMcpSurface,\n RUNTIME_MCP_KEY,\n} from \"#mcp/runtime-spec\";\nimport { peerSessionBridgeIpcEnv } from \"#mcp/session-comm/bridge-ipc-config\";\nimport { bgBashContextCapability } from \"#platform/background-bash/manager\";\nimport {\n AGENT_HEALTH_SERVER,\n CANONICAL_MCP_PROXY_SERVER,\n DECISION_SERVER,\n envText,\n FALLBACK_AGENT,\n resolveTopicWorkspaceDir,\n SESSION_COMM_SERVER,\n SYSTEM_HEALTH_SERVER,\n TASK_SERVER,\n TOKEN_STATS_SERVER,\n TSCONFIG_PATH,\n TSX_LOADER,\n VAULT_SERVER,\n WIKI_SERVER,\n} from \"#platform/config\";\nimport { logger } from \"#platform/logger\";\nimport {\n classifyForumMcpServers,\n commonRuntimeMcpPolicy,\n type RuntimeMcpScope,\n} from \"#platform/mcp-catalog-policy\";\nimport { browserOwnerCapability } from \"#platform/playwright/capability\";\nimport {\n buildPlaywrightMcpTransport,\n CODEX_BROWSER_CAPABILITY_ENV,\n} from \"#platform/playwright/mcp-transport\";\nimport { encodeActorTopicScopeArg } from \"#runtime/actor-topic-scope\";\nimport { getRegisteredCronSession } from \"#runtime/cron-sessions\";\nimport { encodeRemoteSessionGrantArg } from \"#runtime/remote-session-grant\";\nimport type { HostMcpServerSpec } from \"#runtime-gateway\";\nimport { getTopic } from \"#storage/api-topics\";\nimport type {\n ActorTopicScope,\n AgentKind,\n AgentQueryOptions,\n PeerRuntimeBridgeContext,\n RemoteSessionGrant,\n} from \"#types\";\n\nexport type { RuntimeMcpScope } from \"#platform/mcp-catalog-policy\";\n\n/**\n * Build the stdio transport spec for a Otium MCP server entry.\n *\n * claude/maestro launch the .ts server directly with `bun run` (fast, native\n * TypeScript + bun:sqlite). codex CANNOT — codex 0.135's rmcp stdio client\n * fails to handshake with bun-spawned servers (initialize is dropped/raced, so\n * no tools reach the model), while pure-node servers connect reliably. So for\n * the `codex` agent we launch the SAME server file via node + tsx, passing the\n * tsconfig explicitly (servers run with cwd ≠ PROJECT_ROOT, so tsx can't find\n * it on its own) so `@/*` path aliases resolve. Per-turn agent-aware config\n * means switching agents mid-topic just works: each turn re-spawns with the\n * right runtime.\n */\nexport function buildStdioMcpServer(\n agent: AgentKind | undefined,\n serverFile: string,\n serverArgs: string[],\n env?: Record<string, string>,\n): Record<string, unknown> {\n if (agent === \"codex\") {\n return {\n command: \"node\",\n args: [\"--import\", TSX_LOADER, serverFile, ...serverArgs],\n // Merged onto codex's inherited env (not a replacement) — verified.\n env: { TSX_TSCONFIG_PATH: TSCONFIG_PATH, ...env },\n };\n }\n return {\n command: \"bun\",\n args: [\"run\", serverFile, ...serverArgs],\n ...(env ? { env } : {}),\n };\n}\n\nfunction useHostedBuiltinMcp(): boolean {\n return envText(\"NEGOTIUM_BUILTIN_MCP_TRANSPORT\") !== \"stdio\";\n}\n\nfunction buildBuiltinMcpServer(\n surface: HostedMcpSurface,\n ctx: RuntimeMcpBuildContext,\n stdio: () => Record<string, unknown>,\n): Record<string, unknown> {\n if (!useHostedBuiltinMcp()) return stdio();\n const agent = ctx.agent ?? FALLBACK_AGENT;\n return buildHostedMcpSpec(agent, surface, {\n userId: ctx.userId,\n ...(ctx.actorUserId ? { actorUserId: ctx.actorUserId } : {}),\n ...(ctx.actorTopicScope ? { actorTopicScope: ctx.actorTopicScope } : {}),\n // Only the session-comm surface addresses remote rooms; the other hosted\n // tokens (and the runtime token) never carry the grant, so it costs them\n // no URL budget.\n ...(surface === \"session-comm\" && ctx.remoteSession\n ? { remoteSession: ctx.remoteSession }\n : {}),\n topicTitle: ctx.session,\n ...(ctx.topicId ? { topicId: ctx.topicId } : {}),\n ...(ctx.queryId ? { queryId: ctx.queryId } : {}),\n ...(ctx.wikiTopicId ? { wikiTopicId: ctx.wikiTopicId } : {}),\n ...(ctx.subagentParentTopicId ? { subagentParentTopicId: ctx.subagentParentTopicId } : {}),\n ...(ctx.threadRootId ? { threadRootId: ctx.threadRootId } : {}),\n cwd: ctx.cwd ?? (ctx.topicId ? resolveTopicWorkspaceDir(ctx.topicId) : process.cwd()),\n agent,\n ...(ctx.model ? { model: ctx.model } : {}),\n ...(ctx.depth !== undefined ? { depth: ctx.depth } : {}),\n ...(ctx.silent !== undefined ? { silent: ctx.silent } : {}),\n ...(ctx.peerBridge ? { peerBridge: ctx.peerBridge } : {}),\n });\n}\n\n// --- Playwright unavailable notifier + per-turn state ---\n//\n// When the playwright manager fails to allocate a long-lived MCP port,\n// the catalog used to fall back to a per-turn stdio chromium that ran as\n// a child of the agent CLI subprocess — which meant Chromium was bound\n// to the agent's process tree and died on cascade-kill. We now skip the\n// browser entry entirely (the playwright entry is omitted from the\n// catalog for that turn) AND surface the gap two ways:\n//\n// 1. `notifyPlaywrightUnavailable` — fire-and-forget callback for the host\n// (telegram bot) to push an alert to the current topic. Throttled\n// per (userId, topic) with a 5-minute cooldown so a flaky\n// manager doesn't spam the chat. Per-process state — restart clears.\n//\n// 2. `consumePlaywrightUnavailable` — the system-prompt builder reads\n// this flag to add an explicit \"Playwright unavailable this turn\"\n// reminder to the agent's user message, so the model knows to\n// route around browser tools instead of hallucinating a call to a\n// tool that was silently removed from the schema list.\n\ntype PlaywrightUnavailableContext = {\n userId: string;\n topic: string | undefined;\n agent: AgentKind | undefined;\n};\n\ntype PlaywrightUnavailableNotifier = (ctx: PlaywrightUnavailableContext) => void;\n\nlet _playwrightUnavailableNotifier: PlaywrightUnavailableNotifier | undefined;\nconst _playwrightUnavailableLastNotifiedAt = new Map<string, number>();\nconst _PLAYWRIGHT_UNAVAILABLE_COOLDOWN_MS = 5 * 60_000;\n\nconst _playwrightUnavailableThisTurn = new Set<string>();\n\nfunction _playwrightUnavailableKey(userId: string, topic: string | undefined): string {\n return `${userId}:${topic ?? \"\"}`;\n}\n\n/**\n * Register the host's \"playwright unavailable\" alert sink. Called once at bot\n * startup. Idempotent — last writer wins.\n */\nexport function setPlaywrightUnavailableNotifier(cb: PlaywrightUnavailableNotifier): void {\n _playwrightUnavailableNotifier = cb;\n}\n\n/**\n * Mark the current turn as missing long-lived Playwright and notify the host.\n * The playwright catalog entry calls this when it is built without a port, but\n * route-level callers can call it earlier after ensurePlaywright fails so the\n * system prompt for the same turn can include the unavailable reminder.\n */\nexport function markPlaywrightUnavailable(ctx: PlaywrightUnavailableContext): void {\n _markPlaywrightUnavailable(ctx);\n}\n\nfunction _markPlaywrightUnavailable(ctx: PlaywrightUnavailableContext): void {\n // Mark unavailable for the next system-prompt build, regardless of\n // notifier presence (the model-side reminder must always fire so the\n // agent doesn't try to call a missing tool).\n _playwrightUnavailableThisTurn.add(_playwrightUnavailableKey(ctx.userId, ctx.topic));\n\n if (!_playwrightUnavailableNotifier) return;\n const key = _playwrightUnavailableKey(ctx.userId, ctx.topic);\n const now = Date.now();\n const last = _playwrightUnavailableLastNotifiedAt.get(key) ?? 0;\n if (now - last < _PLAYWRIGHT_UNAVAILABLE_COOLDOWN_MS) return;\n _playwrightUnavailableLastNotifiedAt.set(key, now);\n try {\n _playwrightUnavailableNotifier(ctx);\n } catch (err) {\n logger.warn({ err }, \"playwright unavailable notifier threw\");\n }\n}\n\n/**\n * Read + clear the \"playwright unavailable this turn\" flag for a\n * (user, group, topic). Used by the system-prompt builder right before\n * the agent query starts. Single consumer pattern — calling more than\n * once per turn returns `false` for the second caller (intended; the\n * reminder only needs to ride one prompt).\n */\nexport function consumePlaywrightUnavailable(userId: string, topic: string | undefined): boolean {\n const key = _playwrightUnavailableKey(userId, topic);\n if (!_playwrightUnavailableThisTurn.has(key)) return false;\n _playwrightUnavailableThisTurn.delete(key);\n return true;\n}\n\n/**\n * Single source of truth for MCP server registration.\n *\n * Each entry declares which scopes it participates in (`dm`, `forum`, `fork`, `cron`)\n * and how to build its spawn config given a context. Public helpers\n * (`getDmMcpServers`, `getForumMcpServers`, `getForkMcpServers`) and the\n * derived forum-name views read from this catalog plus the node-assigned\n * manifest overlay installed below. Adding a built-in MCP server remains a\n * one-line append here instead of touching three places.\n *\n * Conventions:\n * - `scopes` lists every scope the server should appear in by default.\n * - `forumRequired: true` keeps the server even when a forum topic\n * restricts the enabled list via `configure_mcp` (forum scope only).\n * - `build(ctx)` returns the raw transport config (Claude-SDK shape).\n * Codex callers funnel through `toCodexMcpServers` separately.\n *\n * Insertion order is preserved by `Object.entries`, which determines the\n * order of server names in user-facing displays.\n */\n\nexport interface RuntimeMcpBuildContext {\n userId: string;\n /** Product actor identity when it differs from the execution principal. */\n actorUserId?: string;\n /** Hub-asserted rooms the product actor may reach; forwarded into signed tokens. */\n actorTopicScope?: ActorTopicScope;\n /** Hub-issued per-turn remote session-comm grant; session-comm only. */\n remoteSession?: RemoteSessionGrant;\n /** Vault namespace when credentials belong to a different principal. */\n vaultUserId?: string;\n /** \"dm\" for DM scope, topic/session name for forum/fork. */\n session: string;\n /** REST/WS topic id when known. Prefer for authorization/scope checks. */\n topicId?: string;\n /** Direct parent topic id when the current topic is a subagent room. */\n subagentParentTopicId?: string;\n /** REST/WS query id when known. */\n queryId?: string;\n /** Topic id whose wiki memory should be read/written. */\n wikiTopicId?: string;\n agent?: AgentKind;\n cwd?: string;\n model?: string;\n currentUserPrompt?: string;\n depth?: number;\n playwrightPort?: number;\n playwrightCapability?: string;\n bgBashPort?: number;\n autoContinue?: boolean;\n visualTools?: boolean;\n fileDeliveryTools?: boolean;\n silent?: boolean;\n /** Thread this turn answers inside; forwarded to the runtime MCP context. */\n threadRootId?: string;\n peerBridge?: PeerRuntimeBridgeContext;\n}\n\nexport interface RuntimeMcpCatalogEntry {\n scopes: readonly RuntimeMcpScope[];\n /** Forum scope only: cannot be removed via the enabled whitelist. */\n forumRequired?: boolean;\n /**\n * Returns the raw transport spec (Claude-SDK shape), or `null` to\n * signal \"this server is unavailable for this turn — omit it from the\n * catalog entirely.\" Used by the playwright entry when the manager\n * cannot provide a long-lived port.\n */\n build(ctx: RuntimeMcpBuildContext): Record<string, unknown> | null;\n}\n\n// --- Playwright transport builders ---\n\nexport { browserOwnerCapability, buildPlaywrightMcpTransport, CODEX_BROWSER_CAPABILITY_ENV };\n\nexport function browserOwnerForContext(ctx: {\n userId?: string;\n session?: string;\n topicId?: string;\n}): string | undefined {\n if (ctx.topicId) return `topic:${ctx.topicId}`;\n if (ctx.userId && ctx.session) return `user:${ctx.userId}:${ctx.session}`;\n return undefined;\n}\n\nfunction longLivedHttpMcp(agent: AgentKind | undefined, port: number) {\n return agent === \"codex\"\n ? { url: `http://127.0.0.1:${port}/mcp` }\n : { type: \"sse\" as const, url: `http://127.0.0.1:${port}/sse` };\n}\n\n// cua-rs implements Streamable HTTP only; unlike browser-rs, it does not\n// expose the legacy SSE endpoint. The port is installed by the node-owned\n// process manager once its singleton is ready.\nlet cuaRsMcpPort: number | undefined;\n// cua-rs 0.8.0 requires `Authorization: Bearer` on /mcp, because loopback is not\n// an authorization boundary -- any local process, a web page included, could\n// otherwise drive the whole desktop. The node picks the token, hands it to the\n// child as CUA_HTTP_TOKEN, and publishes it here so turns can present it. Kept\n// beside the port because they are one fact: without both, the URL is useless.\nlet cuaRsMcpToken: string | undefined;\n\nexport function setCuaRsMcpPort(port: number | undefined, token?: string): void {\n if (port !== undefined && (!Number.isInteger(port) || port < 1 || port > 65_535)) {\n throw new Error(`invalid cua-rs MCP port: ${port}`);\n }\n cuaRsMcpPort = port;\n cuaRsMcpToken = port === undefined ? undefined : token;\n}\n\nfunction cuaRsHttpMcp(agent: AgentKind | undefined, port: number, token: string | undefined) {\n const url = `http://127.0.0.1:${port}/mcp`;\n // No token means an older cua-rs that does not ask for one. Sending the header\n // anyway would be harmless, but omitting it keeps the config honest about what\n // the running server actually requires.\n const headers = token ? { Authorization: `Bearer ${token}` } : undefined;\n // The shape is otherwise unchanged from before the token existed, including\n // `type` for codex: only the header field is added, and only when there is a\n // token to put in it. Codex spells that field `http_headers`.\n const base = { type: \"http\" as const, url };\n if (!headers) return base;\n return agent === \"codex\" ? { ...base, http_headers: headers } : { ...base, headers };\n}\n\nfunction backgroundBashTransport(\n agent: AgentKind | undefined,\n port: number,\n userId: string,\n topic: string,\n) {\n const capability = bgBashContextCapability(userId, topic);\n const headers = {\n \"X-Background-Bash-User\": userId,\n \"X-Background-Bash-Topic\": topic,\n \"X-Background-Bash-Capability\": capability,\n };\n if (agent === \"codex\") return { url: `http://127.0.0.1:${port}/mcp`, http_headers: headers };\n if (agent === \"maestro\") {\n const query = new URLSearchParams({ user: userId, topic, capability });\n return { type: \"sse\" as const, url: `http://127.0.0.1:${port}/sse?${query}` };\n }\n return { type: \"sse\" as const, url: `http://127.0.0.1:${port}/sse`, headers };\n}\n\n// --- Catalog ---\n\nconst MCP_CATALOG: Record<string, RuntimeMcpCatalogEntry> = {\n playwright: {\n ...commonRuntimeMcpPolicy(\"playwright\"),\n build({ userId, session, topicId, playwrightPort, playwrightCapability, agent }) {\n // Codex and Maestro use Streamable HTTP while Claude uses SSE. Both\n // transports terminate at the same long-lived browser/profile server.\n if (playwrightPort && playwrightCapability) {\n const owner = browserOwnerForContext({ userId, session, topicId });\n if (!owner) return null;\n return buildPlaywrightMcpTransport(playwrightPort, owner, playwrightCapability, agent);\n }\n // No port available — the playwright manager could not allocate one\n // for this turn. The previous behavior was to fall back to a per-turn\n // stdio chromium, but that made Chromium a child of the agent CLI\n // process tree, so cascade-kill on agent exit took the browser down\n // with it (visible in pm2 as \"Chromium died with claude\"). We now\n // omit the playwright entry from this turn's catalog AND fire two\n // side-effects:\n // 1. notify the host so it can push an alert into the current\n // topic (rate-limited 5min per scope key);\n // 2. mark the (user, topic) as \"playwright unavailable\n // this turn\" so the system-prompt builder can tell the model\n // explicitly, instead of letting the model hallucinate a call\n // to a tool whose schema silently vanished.\n _markPlaywrightUnavailable({\n userId,\n topic: session,\n agent,\n });\n return null;\n },\n },\n [RUNTIME_MCP_KEY]: {\n ...commonRuntimeMcpPolicy(\"runtime\"),\n build({\n userId,\n actorUserId,\n actorTopicScope,\n session,\n topicId,\n queryId,\n agent,\n cwd,\n model,\n currentUserPrompt,\n autoContinue,\n visualTools,\n fileDeliveryTools,\n threadRootId,\n peerBridge,\n }) {\n if (!topicId || !agent) return null;\n const switchTargets = explicitAgentSwitchTargets(currentUserPrompt);\n return buildRuntimeMcpSpec(agent, {\n // Runtime tools mutate node-owned state, so authorization stays bound\n // to the canonical execution principal. Keep the product-side human\n // actor separately for attribution instead of replacing the identity\n // that appears in this node's topic participant roster.\n userId,\n ...(actorUserId ? { actorUserId } : {}),\n ...(actorTopicScope ? { actorTopicScope } : {}),\n topicId,\n topicTitle: session,\n queryId,\n cwd: cwd ?? resolveTopicWorkspaceDir(topicId),\n agent,\n model,\n // Derived here, from the full prompt, so the signed token carries the\n // gate's answer (bounded) instead of the prompt (unbounded); see\n // `explicitAgentSwitchTargets`.\n ...(switchTargets.length ? { explicitAgentSwitchTargets: switchTargets } : {}),\n autoContinue,\n visualTools,\n fileDeliveryTools,\n ...(threadRootId ? { threadRootId } : {}),\n peerBridge,\n });\n },\n },\n \"token-stats\": {\n ...commonRuntimeMcpPolicy(\"token-stats\"),\n build(ctx) {\n return buildBuiltinMcpServer(\"token-stats\", ctx, () =>\n buildStdioMcpServer(ctx.agent, TOKEN_STATS_SERVER, [`--user-id=${ctx.userId}`]),\n );\n },\n },\n // Otium-owned shared task system. This is the only authoritative task/todo\n // surface across claude/codex/maestro; provider-native task stores are\n // blocked or ignored because they do not survive agent switches.\n task: {\n ...commonRuntimeMcpPolicy(\"task\"),\n build(ctx) {\n const { userId, session, topicId, queryId, agent, peerBridge } = ctx;\n if (peerBridge) {\n if (!topicId || !queryId) return null;\n const env = canonicalMcpBridgeEnv({\n surface: \"task\",\n userId,\n topicId,\n queryId,\n peerBridge,\n });\n return env\n ? buildStdioMcpServer(agent, CANONICAL_MCP_PROXY_SERVER, [\"--surface=task\"], env)\n : null;\n }\n const args = [`--user-id=${userId}`, `--topic=${session}`];\n if (topicId) args.push(`--topic-id=${topicId}`);\n return buildBuiltinMcpServer(\"task\", ctx, () =>\n buildStdioMcpServer(agent, TASK_SERVER, args),\n );\n },\n },\n decision: {\n ...commonRuntimeMcpPolicy(\"decision\"),\n build(ctx) {\n const { userId, session, topicId, queryId, agent, model, peerBridge } = ctx;\n if (peerBridge) {\n if (!topicId || !queryId) return null;\n const env = canonicalMcpBridgeEnv({\n surface: \"decision\",\n userId,\n topicId,\n queryId,\n peerBridge,\n });\n return env\n ? buildStdioMcpServer(agent, CANONICAL_MCP_PROXY_SERVER, [\"--surface=decision\"], env)\n : null;\n }\n const args = [\n `--user-id=${userId}`,\n `--topic=${session}`,\n `--agent=${agent ?? FALLBACK_AGENT}`,\n ];\n if (topicId) args.push(`--topic-id=${topicId}`);\n if (model) args.push(`--model=${model}`);\n return buildBuiltinMcpServer(\"decision\", ctx, () =>\n buildStdioMcpServer(agent, DECISION_SERVER, args),\n );\n },\n },\n \"session-comm\": {\n // Exposed in `manager` scope as well so the General-topic manager agent\n // can wake fresh-created topics via tell_session/ask_session right after\n // create_topic. Without this, a newly-created topic would stay in the\n // \"fresh-start ready\" state until the user manually visits it.\n ...commonRuntimeMcpPolicy(\"session-comm\"),\n build(ctx) {\n const {\n userId,\n actorUserId,\n actorTopicScope,\n remoteSession,\n session,\n topicId,\n subagentParentTopicId,\n agent,\n depth = 0,\n silent,\n threadRootId,\n peerBridge,\n } = ctx;\n const effectiveAgent = agent ?? FALLBACK_AGENT;\n const cronSessionId = topicId\n ? getRegisteredCronSession(topicId, effectiveAgent)?.sessionId\n : undefined;\n const args = [\n `--user-id=${userId}`,\n ...(actorUserId ? [`--actor-user-id=${actorUserId}`] : []),\n ...(actorTopicScope\n ? [`--actor-topic-scope=${encodeActorTopicScopeArg(actorTopicScope)}`]\n : []),\n ...(remoteSession\n ? [`--remote-session-grant=${encodeRemoteSessionGrantArg(remoteSession)}`]\n : []),\n `--topic=${session}`,\n ...(topicId ? [`--topic-id=${topicId}`] : []),\n ...(subagentParentTopicId ? [`--subagent-parent-topic-id=${subagentParentTopicId}`] : []),\n `--depth=${depth}`,\n `--agent=${effectiveAgent}`,\n ...(cronSessionId ? [`--cron-session-id=${cronSessionId}`] : []),\n ...(silent ? [\"--reply-only=true\"] : []),\n // Turn-scoped, like `--peer-host-query-id`: this config is rebuilt for\n // every turn, so an `ask_session` raised inside a thread can record\n // where its answer belongs.\n ...(threadRootId ? [`--thread-root-id=${threadRootId}`] : []),\n ...(peerBridge ? [`--peer-host-query-id=${peerBridge.hostQueryId}`] : []),\n ];\n return buildBuiltinMcpServer(\"session-comm\", ctx, () =>\n buildStdioMcpServer(\n effectiveAgent,\n SESSION_COMM_SERVER,\n args,\n peerBridge ? peerSessionBridgeIpcEnv() : undefined,\n ),\n );\n },\n },\n wiki: {\n ...commonRuntimeMcpPolicy(\"wiki\"),\n build(ctx) {\n const { userId, session, topicId, queryId, wikiTopicId, agent, peerBridge } = ctx;\n if (peerBridge) {\n if (!topicId || !queryId) return null;\n const env = canonicalMcpBridgeEnv({\n surface: \"wiki\",\n userId,\n topicId,\n queryId,\n peerBridge,\n });\n return env\n ? buildStdioMcpServer(agent, CANONICAL_MCP_PROXY_SERVER, [\"--surface=wiki\"], env)\n : null;\n }\n const args = [`--user-id=${userId}`];\n if (topicId) args.push(`--current-topic-id=${topicId}`);\n // Prefer the REST topic id so wiki_write writes filenames and SQLite\n // briefs keyed the same way the topic wiki API reads them.\n const resolvedWikiTopicId =\n wikiTopicId ?? topicId ?? (session !== \"dm\" ? session : undefined);\n if (resolvedWikiTopicId) args.push(`--topic-id=${resolvedWikiTopicId}`);\n args.push(\"--surface=wiki\");\n return buildBuiltinMcpServer(\"wiki\", { ...ctx, wikiTopicId: resolvedWikiTopicId }, () =>\n buildStdioMcpServer(agent, WIKI_SERVER, args),\n );\n },\n },\n skills: {\n ...commonRuntimeMcpPolicy(\"skills\"),\n build(ctx) {\n const { userId, topicId, agent } = ctx;\n const args = [`--user-id=${userId}`, \"--surface=skills\"];\n if (topicId) args.push(`--topic-id=${topicId}`);\n return buildBuiltinMcpServer(\"skills\", ctx, () =>\n buildStdioMcpServer(agent, WIKI_SERVER, args),\n );\n },\n },\n \"system-health\": {\n ...commonRuntimeMcpPolicy(\"system-health\"),\n build(ctx) {\n return buildBuiltinMcpServer(\"system-health\", ctx, () =>\n buildStdioMcpServer(ctx.agent, SYSTEM_HEALTH_SERVER, []),\n );\n },\n },\n \"background-bash\": {\n ...commonRuntimeMcpPolicy(\"background-bash\"),\n build({ agent, bgBashPort, userId, topicId }) {\n // Key the whole pipeline by the canonical topic id: it flows through the\n // capability, the request context, and the completion inbox filename\n // (sessionInboxPath) so the exiting process's output is routed back to\n // the exact originating topic. A title/session fallback would be encoded\n // as if it were an id and the inbox worker would fail to resolve it, so\n // background-bash is simply unavailable without a topic id.\n if (bgBashPort === undefined || !topicId) return null;\n return backgroundBashTransport(agent, bgBashPort, userId, topicId);\n },\n },\n \"agent-health\": {\n ...commonRuntimeMcpPolicy(\"agent-health\"),\n build(ctx) {\n const { userId, agent } = ctx;\n const args = [`--user-id=${userId}`];\n return buildBuiltinMcpServer(\"agent-health\", ctx, () =>\n buildStdioMcpServer(agent, AGENT_HEALTH_SERVER, args),\n );\n },\n },\n vault: {\n ...commonRuntimeMcpPolicy(\"vault\"),\n build(ctx) {\n const { userId, vaultUserId, agent } = ctx;\n // Normal turns use {{KEY}} directly in tool inputs. Keep the Vault MCP\n // surface focused on key discovery; broker tools remain available from\n // the public factory for compatibility but are no longer the default UX.\n const args = [`--user-id=${vaultUserId ?? userId}`];\n if (agent !== \"codex\") args.push(\"--list-only=true\");\n return buildBuiltinMcpServer(\"vault\", { ...ctx, userId: vaultUserId ?? userId }, () =>\n buildStdioMcpServer(agent, VAULT_SERVER, args),\n );\n },\n },\n // macOS desktop control, delegated to maestrojeong/cua-rs rather than\n // reimplemented. The node owns one persistent Streamable HTTP process;\n // turns only receive its loopback URL and must never spawn a stdio copy.\n \"cua-rs\": {\n ...commonRuntimeMcpPolicy(\"cua-rs\"),\n build({ agent }) {\n return cuaRsMcpPort ? cuaRsHttpMcp(agent, cuaRsMcpPort, cuaRsMcpToken) : null;\n },\n },\n};\n\n/**\n * Locate the `cua-rs` binary, or `null` when it is not installed.\n *\n * Checked in order of specificity: an explicit env override for anyone running\n * a local build, then the installer's default target, then `/usr/local/bin`\n * for a `--bin-dir` install. PATH is deliberately not consulted -- the server\n * is spawned by a supervised host process whose PATH is not the user's shell\n * PATH, so a PATH lookup would succeed in a terminal and fail under pm2.\n */\nexport function resolveCuaRsBinary(platform: NodeJS.Platform = process.platform): string | null {\n if (platform !== \"darwin\") return null;\n const candidates = [\n envText(\"NEGOTIUM_CUA_RS_BIN\"),\n join(homedir(), \".local\", \"bin\", \"cua-rs\"),\n \"/usr/local/bin/cua-rs\",\n ].filter((p): p is string => Boolean(p));\n for (const candidate of candidates) {\n try {\n accessSync(candidate, fsConstants.X_OK);\n return candidate;\n } catch {\n // Not there, or not executable. Try the next one.\n }\n }\n return null;\n}\n\n// --- Derived catalog views ---\n\nexport type NodeMcpEntry =\n | { key: string; kind: \"http\"; port: number }\n | {\n key: string;\n kind: \"http-instance\";\n ensurePort: (instanceKey: string) => Promise<number>;\n }\n | { key: string; kind: \"stdio\"; command: string; args?: string[]; env?: Record<string, string> };\n\nlet nodeMcpEntries: NodeMcpEntry[] = [];\nconst resolvedNodeMcpPorts = new WeakMap<\n Extract<NodeMcpEntry, { kind: \"http-instance\" }>,\n Map<string, number>\n>();\n\n/** All forum-eligible MCP server names, in display order. */\nconst allForumMcpServerNames: string[] = [];\nexport const ALL_FORUM_MCP_SERVER_NAMES: readonly string[] = allForumMcpServerNames;\n\n/** Forum servers that cannot be removed via the enabled whitelist. */\nconst requiredForumMcpServers: string[] = [];\nexport const REQUIRED_FORUM_MCP_SERVERS: readonly string[] = requiredForumMcpServers;\n\n/** Forum servers that can be toggled via the enabled whitelist (not required). */\nconst optionalForumMcpServers: string[] = [];\nexport const OPTIONAL_FORUM_MCP_SERVERS: readonly string[] = optionalForumMcpServers;\n\nfunction refreshForumCatalogViews(): void {\n const { all, required, optional } = classifyForumMcpServers(MCP_CATALOG);\n const nodeNames = nodeMcpEntries.map((entry) => entry.key);\n const allWithNodeEntries = [...new Set([...all, ...nodeNames])];\n const optionalWithNodeEntries = [...new Set([...optional, ...nodeNames])];\n allForumMcpServerNames.splice(0, allForumMcpServerNames.length, ...allWithNodeEntries);\n requiredForumMcpServers.splice(0, requiredForumMcpServers.length, ...required);\n optionalForumMcpServers.splice(0, optionalForumMcpServers.length, ...optionalWithNodeEntries);\n}\n\nrefreshForumCatalogViews();\n\n/**\n * Mount one MCP capability supplied by an optional node module.\n *\n * Registration happens once at node startup, never in the per-event hot path.\n * The returned cleanup closure only removes the exact entry installed by this\n * call, making module stop/restart safe.\n */\nexport function registerRuntimeMcpServer(name: string, entry: RuntimeMcpCatalogEntry): () => void {\n const key = name.trim();\n if (!key || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(key)) {\n throw new Error(`invalid runtime MCP server name: ${name}`);\n }\n if (MCP_CATALOG[key]) throw new Error(`runtime MCP server already registered: ${key}`);\n MCP_CATALOG[key] = entry;\n refreshForumCatalogViews();\n return () => {\n if (MCP_CATALOG[key] !== entry) return;\n delete MCP_CATALOG[key];\n refreshForumCatalogViews();\n };\n}\n\n/**\n * Format the active MCP config for display (used by get_mcp_config /\n * get_topic_mcp / configure_mcp response).\n *\n * In whitelist mode the DB stores only the user-chosen optional servers;\n * required servers are always active but never written to the whitelist.\n * This helper surfaces that split so the model never confuses \"not in\n * whitelist\" with \"not active\".\n */\nexport function formatMcpStatus(config: {\n enabled: string[] | null;\n extra?: Record<string, unknown>;\n}): string[] {\n const extraNames = Object.keys(config.extra ?? {});\n\n if (config.enabled === null) {\n const total = ALL_FORUM_MCP_SERVER_NAMES.length + extraNames.length;\n return [\n `설정 방식: 기본값 (전체 활성)`,\n `활성 서버 (${total}개): ${[...ALL_FORUM_MCP_SERVER_NAMES, ...extraNames].join(\", \")}`,\n `추가 서버: ${extraNames.length > 0 ? extraNames.join(\", \") : \"없음\"}`,\n ];\n }\n\n // whitelist mode: stored list may or may not include required servers\n // (old entries might have them; new entries won't). Either way, split\n // by required vs optional for display.\n const availableOptional = new Set(OPTIONAL_FORUM_MCP_SERVERS);\n const optionalActive = [...new Set(config.enabled)].filter((name) => availableOptional.has(name));\n const total = REQUIRED_FORUM_MCP_SERVERS.length + optionalActive.length + extraNames.length;\n return [\n `설정 방식: whitelist`,\n `필수 서버 (항상 활성, ${REQUIRED_FORUM_MCP_SERVERS.length}개): ${REQUIRED_FORUM_MCP_SERVERS.join(\", \")}`,\n `선택 서버 (whitelist, ${optionalActive.length}개): ${optionalActive.length > 0 ? optionalActive.join(\", \") : \"없음\"}`,\n `실제 활성 합계: ${total}개`,\n `추가 서버: ${extraNames.length > 0 ? extraNames.join(\", \") : \"없음\"}`,\n ``,\n `선택 가능 서버 전체 (${OPTIONAL_FORUM_MCP_SERVERS.length}개): ${OPTIONAL_FORUM_MCP_SERVERS.join(\", \")}`,\n ];\n}\n\n// --- Builders for each scope ---\n\n// ── Node-assigned MCP servers (mcp-host manifest) ───────────────────\n//\n// The per-node MCP manifest (`negotium mcp add`) lives in @negotium/mcp-host,\n// which depends on core — so core cannot read it directly. Instead the host\n// process resolves the manifest at node start (ensuring long-lived http\n// servers are running and have ports) and installs the result here. Entries\n// then ride every eligible scope's catalog, subject to the same per-topic\n// `enabled` whitelist as optional built-ins.\n\n/** Install the node's assigned MCP servers. Last writer wins (host restart-safe). */\nexport function setNodeMcpServers(entries: NodeMcpEntry[]): void {\n nodeMcpEntries = entries.filter((entry) => !(entry.key in MCP_CATALOG));\n const dropped = entries.length - nodeMcpEntries.length;\n if (dropped > 0) {\n logger.warn({ dropped }, \"setNodeMcpServers: entries shadowing built-in catalog keys ignored\");\n }\n refreshForumCatalogViews();\n}\n\nexport function getNodeMcpServers(): readonly NodeMcpEntry[] {\n return nodeMcpEntries;\n}\n\n/** Prevent host grants from replacing node-owned MCP servers. */\nexport function isReservedRuntimeMcpServerName(name: string): boolean {\n return Object.hasOwn(MCP_CATALOG, name) || nodeMcpEntries.some((entry) => entry.key === name);\n}\n\nfunction mergeHostMcpServers(\n base: Record<string, unknown>,\n hostMcpServers: Record<string, HostMcpServerSpec> | undefined,\n): Record<string, unknown> {\n if (!hostMcpServers) return base;\n for (const name of Object.keys(hostMcpServers)) {\n if (Object.hasOwn(base, name) || isReservedRuntimeMcpServerName(name)) {\n throw new Error(`host MCP server name conflicts with node catalog: ${name}`);\n }\n }\n return { ...base, ...hostMcpServers };\n}\n\nfunction buildNodeMcpSpecs(\n agent: AgentKind | undefined,\n filter: (name: string) => boolean,\n ctx: Pick<RuntimeMcpBuildContext, \"topicId\" | \"userId\" | \"session\">,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const entry of nodeMcpEntries) {\n if (!filter(entry.key)) continue;\n if (entry.kind === \"http\") {\n out[entry.key] = longLivedHttpMcp(agent, entry.port);\n continue;\n }\n if (entry.kind === \"http-instance\") {\n const port = resolvedNodeMcpPorts.get(entry)?.get(nodeMcpInstanceKey(ctx));\n if (port !== undefined) out[entry.key] = longLivedHttpMcp(agent, port);\n continue;\n }\n out[entry.key] = {\n command: entry.command,\n args: entry.args ?? [],\n ...(entry.env ? { env: entry.env } : {}),\n };\n }\n return out;\n}\n\nfunction nodeMcpInstanceKey(\n ctx: Pick<RuntimeMcpBuildContext, \"topicId\" | \"userId\" | \"session\">,\n): string {\n return ctx.topicId ?? `user:${ctx.userId}:session:${ctx.session}`;\n}\n\n/**\n * Lazily prepare per-topic HTTP manifest entries before a provider resolves\n * its otherwise-synchronous MCP config. One failed custom server is omitted\n * from that turn without taking down the rest of the runtime catalog.\n */\nexport async function prepareNodeMcpServersForQuery(opts: AgentQueryOptions): Promise<void> {\n if (\n opts.toolPolicy ||\n opts.sessionType === \"cron\" ||\n nodeMcpEntries.every((entry) => entry.kind !== \"http-instance\")\n ) {\n return;\n }\n\n const forum = ![\"dm\", \"ephemeral\", \"manager\"].includes(opts.sessionType ?? \"forum\");\n const enabled = opts.mcpEnabled ?? null;\n const instanceKey = nodeMcpInstanceKey({\n topicId: opts.topicId,\n userId: opts.userId || \"local\",\n session: opts.session || \"default\",\n });\n\n await Promise.all(\n nodeMcpEntries.map(async (entry) => {\n if (entry.kind !== \"http-instance\") return;\n if (forum && enabled !== null && !enabled.includes(entry.key)) return;\n let ports = resolvedNodeMcpPorts.get(entry);\n if (!ports) {\n ports = new Map();\n resolvedNodeMcpPorts.set(entry, ports);\n }\n try {\n const port = await entry.ensurePort(instanceKey);\n if (!Number.isInteger(port) || port < 1 || port > 65_535) {\n throw new Error(`invalid port ${port}`);\n }\n ports.set(instanceKey, port);\n } catch (err) {\n ports.delete(instanceKey);\n logger.warn(\n { err, key: entry.key, instanceKey },\n \"node mcp: failed to prepare instance-scoped server\",\n );\n }\n }),\n );\n}\n\nfunction buildScope(\n scope: RuntimeMcpScope,\n ctx: RuntimeMcpBuildContext,\n filter: (name: string) => boolean = () => true,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [name, entry] of Object.entries(MCP_CATALOG)) {\n if (!entry.scopes.includes(scope)) continue;\n if (!filter(name)) continue;\n // `null` from build() means \"skip this server for this turn\" —\n // currently used by the playwright entry when no long-lived port\n // is available.\n const spec = entry.build(ctx);\n if (spec === null) continue;\n out[name] = spec;\n }\n // Node-assigned MCPs join every scope except cron (scheduled runs keep the\n // deliberately narrow built-in set).\n if (scope !== \"cron\") {\n Object.assign(out, buildNodeMcpSpecs(ctx.agent, filter, ctx));\n }\n return out;\n}\n\n/** DM session: catalog entries with `dm` scope, no whitelist. */\nexport function getDmMcpServers(opts: {\n userId: string;\n session?: string;\n topicId?: string;\n agent?: AgentKind;\n playwrightPort?: number;\n playwrightCapability?: string;\n}) {\n return buildScope(\"dm\", {\n userId: opts.userId,\n session: opts.session ?? \"dm\",\n topicId: opts.topicId,\n agent: opts.agent,\n playwrightPort: opts.playwrightPort,\n playwrightCapability: opts.playwrightCapability,\n });\n}\n\n/**\n * Manager session: lives in the caller's private General API topic. Owns topic CRUD,\n * invite/user admin, and cross-topic MCP toggling through `topic-admin`,\n * plus general utilities. Browser-heavy work belongs in dedicated topics, so\n * Playwright is intentionally excluded here.\n * No whitelist — manager-scope catalog entries are loaded as-is.\n */\nexport function getManagerMcpServers(opts: {\n userId: string;\n actorUserId?: string;\n actorTopicScope?: ActorTopicScope;\n remoteSession?: RemoteSessionGrant;\n session?: string;\n topicId?: string;\n queryId?: string;\n wikiTopicId?: string;\n agent?: AgentKind;\n cwd?: string;\n model?: string;\n currentUserPrompt?: string;\n playwrightPort?: number;\n playwrightCapability?: string;\n autoContinue?: boolean;\n visualTools?: boolean;\n fileDeliveryTools?: boolean;\n}) {\n if (!opts.topicId) {\n throw new Error(\"getManagerMcpServers: private General topicId is required\");\n }\n const topicId = opts.topicId;\n return buildScope(\"manager\", {\n userId: opts.userId,\n actorUserId: opts.actorUserId,\n actorTopicScope: opts.actorTopicScope,\n remoteSession: opts.remoteSession,\n session: opts.session ?? \"General\",\n topicId,\n queryId: opts.queryId,\n wikiTopicId: opts.wikiTopicId ?? topicId,\n agent: opts.agent,\n cwd: opts.cwd,\n model: opts.model,\n currentUserPrompt: opts.currentUserPrompt,\n playwrightPort: opts.playwrightPort,\n playwrightCapability: opts.playwrightCapability,\n autoContinue: opts.autoContinue,\n visualTools: opts.visualTools,\n fileDeliveryTools: opts.fileDeliveryTools,\n });\n}\n\n/**\n * Forum session: catalog entries with `forum` scope.\n * - `enabled === null` → all forum servers.\n * - `enabled` is an array → whitelist; required servers are always included.\n * - `extra` is merged on top, allowing one-off injections per topic.\n */\nexport function getForumMcpServers(opts: {\n userId: string;\n actorUserId?: string;\n actorTopicScope?: ActorTopicScope;\n remoteSession?: RemoteSessionGrant;\n vaultUserId?: string;\n session: string;\n topicId?: string;\n subagentParentTopicId?: string;\n queryId?: string;\n wikiTopicId?: string;\n agent: AgentKind;\n cwd?: string;\n model?: string;\n currentUserPrompt?: string;\n playwrightPort?: number;\n playwrightCapability?: string;\n bgBashPort?: number;\n autoContinue?: boolean;\n visualTools?: boolean;\n fileDeliveryTools?: boolean;\n threadRootId?: string;\n depth?: number;\n enabled?: string[] | null;\n extra?: Record<string, unknown>;\n silent?: boolean;\n peerBridge?: PeerRuntimeBridgeContext;\n}) {\n const {\n userId,\n actorUserId,\n actorTopicScope,\n remoteSession,\n vaultUserId,\n session,\n topicId,\n subagentParentTopicId,\n queryId,\n wikiTopicId,\n agent,\n cwd,\n model,\n currentUserPrompt,\n playwrightPort,\n playwrightCapability,\n depth = 0,\n enabled = null,\n extra = {},\n silent = false,\n bgBashPort,\n autoContinue,\n visualTools,\n fileDeliveryTools,\n threadRootId,\n peerBridge,\n } = opts;\n\n const filter = (name: string) => {\n if (silent && (name === \"task\" || name === \"decision\")) return false;\n if (enabled === null) return true;\n return (\n enabled.includes(name) || (REQUIRED_FORUM_MCP_SERVERS as readonly string[]).includes(name)\n );\n };\n\n const base = buildScope(\n \"forum\",\n {\n userId,\n actorUserId,\n actorTopicScope,\n remoteSession,\n vaultUserId,\n session,\n topicId,\n subagentParentTopicId,\n queryId,\n wikiTopicId,\n agent,\n cwd,\n model,\n currentUserPrompt,\n depth,\n playwrightPort,\n playwrightCapability,\n bgBashPort,\n autoContinue,\n visualTools,\n fileDeliveryTools,\n threadRootId,\n silent,\n peerBridge,\n },\n filter,\n );\n\n return { ...base, ...extra };\n}\n\n/**\n * Cron session: scheduled background run for a concrete API topic. Keep the\n * catalog narrower than forum scope: runtime delivery, topic memory/status,\n * vault utilities and a caller-provided disposable Playwright port.\n */\nexport function getCronMcpServers(opts: {\n userId: string;\n session: string;\n topicId: string;\n queryId?: string;\n wikiTopicId?: string;\n agent: AgentKind;\n cwd?: string;\n model?: string;\n currentUserPrompt?: string;\n playwrightPort?: number;\n playwrightCapability?: string;\n visualTools?: boolean;\n fileDeliveryTools?: boolean;\n}) {\n return buildScope(\"cron\", {\n userId: opts.userId,\n session: opts.session,\n topicId: opts.topicId,\n queryId: opts.queryId,\n wikiTopicId: opts.wikiTopicId ?? opts.topicId,\n agent: opts.agent,\n cwd: opts.cwd,\n model: opts.model,\n currentUserPrompt: opts.currentUserPrompt,\n playwrightPort: opts.playwrightPort,\n playwrightCapability: opts.playwrightCapability,\n autoContinue: false,\n visualTools: opts.visualTools,\n fileDeliveryTools: opts.fileDeliveryTools,\n });\n}\n\n/**\n * Pick the right MCP server bundle for an agent query. DM/ephemeral sessions\n * get the DM bundle; forum sessions get the forum bundle with full options\n * forwarded. Returned shape is the Claude-SDK shape; Codex callers funnel it\n * through their own translator (`toCodexMcpServers`).\n */\nexport function getMcpServersForQuery(opts: AgentQueryOptions): Record<string, unknown> {\n if (opts.toolPolicy === \"none\") return {};\n if (opts.toolPolicy === \"compaction-log\") {\n const compactLog = opts.mcpExtra?.compact_log;\n return compactLog ? { compact_log: compactLog } : {};\n }\n if (opts.sessionType === \"cron\") {\n if (!opts.topicId) throw new Error(\"getMcpServersForQuery: cron sessionType requires topicId\");\n return hideProviderIntrospectionForOtium(\n getCronMcpServers({\n userId: opts.userId || \"local\",\n session: opts.session || \"cron\",\n topicId: opts.topicId,\n queryId: opts.queryId,\n wikiTopicId: opts.wikiTopicId,\n agent: opts.agent,\n cwd: opts.cwd,\n model: opts.model,\n currentUserPrompt: opts.prompt,\n playwrightPort: opts.playwrightPort,\n playwrightCapability: opts.playwrightCapability,\n visualTools: opts.visualTools,\n fileDeliveryTools: opts.fileDeliveryTools,\n }),\n opts.topicId,\n );\n }\n if (opts.sessionType === \"dm\" || opts.sessionType === \"ephemeral\") {\n return getDmMcpServers({\n userId: opts.userId || \"local\",\n session: opts.session,\n topicId: opts.topicId,\n agent: opts.agent,\n playwrightPort: opts.playwrightPort,\n playwrightCapability: opts.playwrightCapability,\n });\n }\n if (opts.sessionType === \"manager\") {\n return hideProviderIntrospectionForOtium(\n mergeHostMcpServers(\n getManagerMcpServers({\n userId: opts.userId || \"local\",\n actorUserId: opts.actorUserId,\n actorTopicScope: opts.actorTopicScope,\n remoteSession: opts.remoteSession,\n session: opts.session,\n topicId: opts.topicId,\n queryId: opts.queryId,\n wikiTopicId: opts.wikiTopicId,\n agent: opts.agent,\n cwd: opts.cwd,\n model: opts.model,\n currentUserPrompt: opts.prompt,\n playwrightPort: opts.playwrightPort,\n playwrightCapability: opts.playwrightCapability,\n autoContinue: opts.autoContinue,\n visualTools: opts.visualTools,\n fileDeliveryTools: opts.fileDeliveryTools,\n }),\n opts.hostMcpServers,\n ),\n opts.topicId,\n );\n }\n return hideProviderIntrospectionForOtium(\n getForumMcpServers({\n userId: opts.userId || \"local\",\n actorUserId: opts.actorUserId,\n actorTopicScope: opts.actorTopicScope,\n remoteSession: opts.remoteSession,\n vaultUserId: opts.vaultUserId,\n session: opts.session || \"default\",\n topicId: opts.topicId,\n subagentParentTopicId: opts.subagentParentTopicId,\n queryId: opts.queryId,\n wikiTopicId: opts.wikiTopicId,\n agent: opts.agent,\n cwd: opts.cwd,\n model: opts.model,\n currentUserPrompt: opts.prompt,\n playwrightPort: opts.playwrightPort,\n playwrightCapability: opts.playwrightCapability,\n bgBashPort: opts.bgBashPort,\n autoContinue: opts.autoContinue,\n visualTools: opts.visualTools,\n fileDeliveryTools: opts.fileDeliveryTools,\n threadRootId: opts.threadRootId,\n depth: opts.depth,\n enabled: opts.mcpEnabled,\n extra: opts.mcpExtra,\n silent: opts.silent,\n peerBridge: opts.peerBridge,\n }),\n opts.topicId,\n );\n}\n\nfunction hideProviderIntrospectionForOtium(\n servers: Record<string, unknown>,\n topicId: string | undefined,\n): Record<string, unknown> {\n if (!topicId || getTopic(topicId)?.surface !== \"otium\") return servers;\n const filtered = { ...servers };\n delete filtered[\"agent-health\"];\n delete filtered[\"token-stats\"];\n return filtered;\n}\n",
30
33
  "import { chmodSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { VAULT_MASTER_KEY } from \"#platform/config\";\nimport { closeDatabase, Database } from \"#storage/sqlite\";\nimport { resolveStorageDataDir } from \"#storage/storage-host\";\nimport { decryptVaultValue, encryptVaultValue, isEncryptedVaultValue } from \"#storage/vault-crypto\";\n\nexport type VaultDatabase = Pick<InstanceType<typeof Database>, \"exec\" | \"prepare\">;\n\nexport interface VaultStorageOptions {\n database?: VaultDatabase;\n dataDir?: string;\n masterKey?: string;\n /** Prior keys rows may still be encrypted under; migrated onto `masterKey`. */\n legacyMasterKeys?: readonly string[];\n}\n\nlet vaultDb: VaultDatabase | undefined;\nlet vaultMasterKey = VAULT_MASTER_KEY;\n\nfunction initializeVaultDatabase(database: VaultDatabase): void {\n database.exec(\"PRAGMA journal_mode = WAL\");\n database.exec(\"PRAGMA busy_timeout = 5000\");\n database.exec(`\n CREATE TABLE IF NOT EXISTS vault (\n user_id TEXT NOT NULL,\n key TEXT NOT NULL,\n value TEXT NOT NULL,\n description TEXT NOT NULL DEFAULT '',\n PRIMARY KEY (user_id, key)\n )\n `);\n\n // Migrate legacy schema where user_id was INTEGER (Telegram numeric ids only).\n // The Otium API authenticates with string user ids (\"otium-user-…\"), so user_id\n // is now TEXT for every channel. Rebuild + CAST existing rows so old Telegram\n // secrets survive; idempotent (no-op once user_id is already TEXT).\n {\n const cols = database.prepare(\"PRAGMA table_info(vault)\").all() as {\n name: string;\n type: string;\n }[];\n const uid = cols.find((c) => c.name === \"user_id\");\n if (uid && uid.type.toUpperCase() === \"INTEGER\") {\n database.exec(\"BEGIN\");\n database.exec(`\n CREATE TABLE vault_migrated (\n user_id TEXT NOT NULL,\n key TEXT NOT NULL,\n value TEXT NOT NULL,\n description TEXT NOT NULL DEFAULT '',\n PRIMARY KEY (user_id, key)\n )\n `);\n database.exec(\n \"INSERT INTO vault_migrated SELECT CAST(user_id AS TEXT), key, value, description FROM vault\",\n );\n database.exec(\"DROP TABLE vault\");\n database.exec(\"ALTER TABLE vault_migrated RENAME TO vault\");\n database.exec(\"COMMIT\");\n }\n }\n}\n\nfunction openVaultDatabase(dataDir: string): VaultDatabase {\n const vaultDir = join(dataDir, \"vault\");\n const path = join(vaultDir, \"vault.db\");\n mkdirSync(vaultDir, { recursive: true, mode: 0o700 });\n const database = new Database(path, { create: true });\n // Defense in depth: the database and its sidecars are owner-only, while each\n // value is also encrypted independently by vault-crypto.\n chmodSync(path, 0o600);\n initializeVaultDatabase(database);\n return database;\n}\n\nfunction activeVaultDatabase(): VaultDatabase {\n if (!vaultDb) {\n // `resolveStorageDataDir()`, not the import-time `DATA_DIR` constant: an\n // embedding host configures its data directory during bootstrap, and any\n // vault access that happens before `configureVaultStorage()` runs would\n // otherwise pin the vault to Negotium's own state directory for the life of\n // the process — silently, since both paths are valid and writable.\n vaultDb = openVaultDatabase(resolveStorageDataDir());\n }\n return vaultDb;\n}\n\n/** Re-encrypts rows only readable under `legacyKeys` onto `targetKey`, atomically. */\nfunction migrateLegacyMasterKeys(\n database: VaultDatabase,\n targetKey: string,\n legacyKeys: readonly string[],\n): void {\n if (legacyKeys.length === 0) return;\n const rows = database.prepare(\"SELECT user_id, key, value FROM vault\").all() as {\n user_id: string;\n key: string;\n value: string;\n }[];\n\n const rewrites: { userId: string; key: string; newValue: string }[] = [];\n for (const row of rows) {\n if (!isEncryptedVaultValue(row.value)) continue; // plaintext rows are handled by decryptRow()\n try {\n decryptVaultValue(row.user_id, row.key, row.value, targetKey);\n continue; // already readable under the target key\n } catch {\n // fall through to legacy recovery below\n }\n let recovered: string | undefined;\n for (const legacyKey of legacyKeys) {\n try {\n recovered = decryptVaultValue(row.user_id, row.key, row.value, legacyKey).value;\n break;\n } catch {\n // try the next legacy key\n }\n }\n if (recovered === undefined) {\n throw new Error(\n `vault migration: row \"${row.key}\" cannot be authenticated with the target master key or any legacy key`,\n );\n }\n rewrites.push({\n userId: row.user_id,\n key: row.key,\n newValue: encryptVaultValue(row.user_id, row.key, recovered, targetKey),\n });\n }\n if (rewrites.length === 0) return;\n\n database.exec(\"BEGIN IMMEDIATE\");\n try {\n const update = database.prepare(\"UPDATE vault SET value = ? WHERE user_id = ? AND key = ?\");\n for (const rewrite of rewrites) update.run(rewrite.newValue, rewrite.userId, rewrite.key);\n database.exec(\"COMMIT\");\n } catch (error) {\n database.exec(\"ROLLBACK\");\n throw error;\n }\n}\n\n/** Configure process-wide vault storage during embedding-host bootstrap. */\nexport function configureVaultStorage(options: VaultStorageOptions): () => void {\n if (options.database && options.dataDir) {\n throw new Error(\"configureVaultStorage accepts either database or dataDir, not both\");\n }\n const previousDb = vaultDb;\n const previousMasterKey = vaultMasterKey;\n const configuredDb =\n options.database ?? openVaultDatabase(options.dataDir ?? resolveStorageDataDir());\n const targetKey = options.masterKey ?? VAULT_MASTER_KEY;\n try {\n if (options.database) initializeVaultDatabase(configuredDb);\n if (options.legacyMasterKeys && options.legacyMasterKeys.length > 0) {\n migrateLegacyMasterKeys(configuredDb, targetKey, options.legacyMasterKeys);\n }\n } catch (error) {\n // A failed migration must not leak the connection this call opened: there\n // is no dispose to hand back, so nothing else can ever close it. Only a\n // database we opened ourselves is ours to close — an injected one is\n // borrowed.\n if (!options.database) {\n closeDatabase(configuredDb as VaultDatabase & { close(throwOnError?: boolean): void });\n }\n throw error;\n }\n vaultDb = configuredDb;\n vaultMasterKey = targetKey;\n let disposed = false;\n return () => {\n if (disposed) return;\n disposed = true;\n if (!options.database && \"close\" in configuredDb) {\n closeDatabase(configuredDb as VaultDatabase & { close(throwOnError?: boolean): void });\n }\n vaultDb = previousDb;\n vaultMasterKey = previousMasterKey;\n };\n}\n\nexport interface VaultEntry {\n key: string;\n description: string;\n}\n\nexport interface VaultEntryWithValue extends VaultEntry {\n value: string;\n}\n\nexport const VAULT_KEY_PATTERN = /^[A-Z][A-Z0-9_]{0,127}$/;\nexport const VAULT_VALUE_MIN_BYTES = 4;\nexport const VAULT_VALUE_MAX_BYTES = 64 * 1024;\nexport const VAULT_DESCRIPTION_MAX_LENGTH = 500;\n\nexport function normalizeVaultKey(key: string): string {\n return key.trim().toUpperCase();\n}\n\nexport function validateVaultKey(key: string): boolean {\n return VAULT_KEY_PATTERN.test(normalizeVaultKey(key));\n}\n\nfunction decryptRow(userId: string, key: string, storedValue: string): string {\n const database = activeVaultDatabase();\n const decoded = decryptVaultValue(userId, key, storedValue, vaultMasterKey);\n if (decoded.legacyPlaintext) {\n database\n .prepare(\"UPDATE vault SET value = ? WHERE user_id = ? AND key = ? AND value = ?\")\n .run(encryptVaultValue(userId, key, decoded.value, vaultMasterKey), userId, key, storedValue);\n }\n return decoded.value;\n}\n\nexport function vaultListWithValues(userId: string): VaultEntryWithValue[] {\n const rows = activeVaultDatabase()\n .prepare(\"SELECT key, description, value FROM vault WHERE user_id = ? ORDER BY key\")\n .all(userId) as VaultEntryWithValue[];\n return rows.map((row) => ({\n key: row.key,\n description: row.description,\n value: decryptRow(userId, row.key, row.value),\n }));\n}\n\n/**\n * Return only rows that can still be authenticated with the active master key.\n *\n * This is intentionally limited to redaction indexes: one damaged credential\n * must not disable unrelated tools, while direct access to that credential\n * continues to fail closed through vaultGetValue().\n */\nexport function vaultListDecryptableValues(userId: string): VaultEntryWithValue[] {\n const rows = activeVaultDatabase()\n .prepare(\"SELECT key, description, value FROM vault WHERE user_id = ? ORDER BY key\")\n .all(userId) as VaultEntryWithValue[];\n const entries: VaultEntryWithValue[] = [];\n for (const row of rows) {\n try {\n entries.push({\n key: row.key,\n description: row.description,\n value: decryptRow(userId, row.key, row.value),\n });\n } catch {\n // A value that cannot be authenticated cannot be exposed by substitution,\n // so there is no plaintext form available to add to the redaction index.\n }\n }\n return entries;\n}\n\nexport function vaultSet(userId: string, key: string, value: string, description = \"\"): void {\n const normalizedKey = normalizeVaultKey(key);\n activeVaultDatabase()\n .prepare(\n `INSERT INTO vault (user_id, key, value, description) VALUES (?, ?, ?, ?)\n ON CONFLICT (user_id, key) DO UPDATE\n SET value = excluded.value, description = excluded.description`,\n )\n .run(\n userId,\n normalizedKey,\n encryptVaultValue(userId, normalizedKey, value, vaultMasterKey),\n description,\n );\n}\n\nexport function vaultHasKey(userId: string, key: string): boolean {\n const row = activeVaultDatabase()\n .prepare(\"SELECT 1 FROM vault WHERE user_id = ? AND key = ?\")\n .get(userId, normalizeVaultKey(key));\n return row != null;\n}\n\nexport function vaultDel(userId: string, key: string): boolean {\n const result = activeVaultDatabase()\n .prepare(\"DELETE FROM vault WHERE user_id = ? AND key = ?\")\n .run(userId, normalizeVaultKey(key)) as { changes: number };\n return result.changes > 0;\n}\n\nexport function vaultDeleteAllForUser(userId: string): number {\n const result = activeVaultDatabase()\n .prepare(\"DELETE FROM vault WHERE user_id = ?\")\n .run(userId) as {\n changes: number;\n };\n return result.changes;\n}\n\nexport function vaultList(userId: string): VaultEntry[] {\n return activeVaultDatabase()\n .prepare(\"SELECT key, description FROM vault WHERE user_id = ? ORDER BY key\")\n .all(userId) as VaultEntry[];\n}\n\nexport function vaultGetValue(userId: string, key: string): string | undefined {\n const normalizedKey = normalizeVaultKey(key);\n const row = activeVaultDatabase()\n .prepare(\"SELECT key, value FROM vault WHERE user_id = ? AND key = ?\")\n .get(userId, normalizedKey) as { key: string; value: string } | undefined;\n return row ? decryptRow(userId, row.key, row.value) : undefined;\n}\n\nexport interface VaultSubstitutionResult {\n text: string;\n usedKeys: string[];\n}\n\n/** Replace {{KEY}} placeholders and report which credentials were consumed. */\nexport function vaultSubstituteDetailed(userId: string, text: string): VaultSubstitutionResult {\n const entries = new Map<string, string | undefined>();\n const usedKeys = new Set<string>();\n const substituted = text.replace(/\\{\\{([^}]+)\\}\\}/g, (match, rawKey: string) => {\n const key = normalizeVaultKey(rawKey);\n if (!entries.has(key)) entries.set(key, vaultGetValue(userId, key));\n const value = entries.get(key);\n if (value === undefined) return match;\n usedKeys.add(key);\n return value;\n });\n return { text: substituted, usedKeys: [...usedKeys] };\n}\n\n/** Detect real {{KEY}} references without decrypting any Vault values. */\nexport function valueReferencesVaultKey(userId: string, value: unknown): boolean {\n const keys = new Set(vaultList(userId).map((entry) => entry.key));\n const visit = (candidate: unknown): boolean => {\n if (typeof candidate === \"string\") {\n for (const match of candidate.matchAll(/\\{\\{([^}]+)\\}\\}/g)) {\n if (keys.has(normalizeVaultKey(match[1] ?? \"\"))) return true;\n }\n return false;\n }\n if (Array.isArray(candidate)) return candidate.some(visit);\n if (candidate && typeof candidate === \"object\") {\n return Object.values(candidate as Record<string, unknown>).some(visit);\n }\n return false;\n };\n return visit(value);\n}\n\nfunction encodedSecretForms(value: string): string[] {\n const forms = new Set<string>([\n value,\n encodeURIComponent(value),\n Buffer.from(value, \"utf8\").toString(\"base64\"),\n Buffer.from(value, \"utf8\").toString(\"base64url\"),\n Buffer.from(value, \"utf8\").toString(\"hex\"),\n ]);\n forms.delete(\"\");\n return [...forms].sort((a, b) => b.length - a.length);\n}\n\n/** Scrub raw and common encoded forms before tool output reaches a model. */\nexport function redactVaultSecrets(userId: string, text: string): string {\n const candidates = vaultListDecryptableValues(userId)\n .flatMap((entry) => encodedSecretForms(entry.value).map((form) => ({ form, key: entry.key })))\n .sort((a, b) => b.form.length - a.form.length || a.key.localeCompare(b.key));\n if (candidates.length === 0) return text;\n const candidatesByFirstCharacter = new Map<string, typeof candidates>();\n for (const candidate of candidates) {\n const first = candidate.form[0];\n if (!first) continue;\n const bucket = candidatesByFirstCharacter.get(first) ?? [];\n bucket.push(candidate);\n candidatesByFirstCharacter.set(first, bucket);\n }\n\n let redacted = \"\";\n let offset = 0;\n while (offset < text.length) {\n const match = candidatesByFirstCharacter\n .get(text[offset] ?? \"\")\n ?.find((candidate) => text.startsWith(candidate.form, offset));\n if (!match) {\n redacted += text[offset];\n offset += 1;\n continue;\n }\n redacted += `[REDACTED:${match.key}]`;\n offset += match.form.length;\n }\n return redacted;\n}\n",
31
34
  "import { createCipheriv, createDecipheriv, createHash, randomBytes } from \"node:crypto\";\n\nconst ENVELOPE_PREFIX = \"otium-vault:v1:\";\nconst IV_BYTES = 12;\nconst KEY_BYTES = 32;\n\nfunction encryptionKey(masterKey: string): Buffer {\n return createHash(\"sha256\")\n .update(\"otium-vault-value-v1\\0\", \"utf8\")\n .update(masterKey, \"utf8\")\n .digest()\n .subarray(0, KEY_BYTES);\n}\n\nfunction aad(userId: string, key: string): Buffer {\n return Buffer.from(`${userId}\\0${key.toUpperCase()}`, \"utf8\");\n}\n\nexport function isEncryptedVaultValue(value: string): boolean {\n return value.startsWith(ENVELOPE_PREFIX);\n}\n\nexport function encryptVaultValueWithKey(\n userId: string,\n key: string,\n value: string,\n masterKey: string,\n): string {\n const iv = randomBytes(IV_BYTES);\n const cipher = createCipheriv(\"aes-256-gcm\", encryptionKey(masterKey), iv);\n cipher.setAAD(aad(userId, key));\n const ciphertext = Buffer.concat([cipher.update(value, \"utf8\"), cipher.final()]);\n const tag = cipher.getAuthTag();\n return `${ENVELOPE_PREFIX}${iv.toString(\"base64url\")}.${ciphertext.toString(\"base64url\")}.${tag.toString(\"base64url\")}`;\n}\n\nexport function decryptVaultValueWithKey(\n userId: string,\n key: string,\n storedValue: string,\n masterKey: string,\n): { value: string; legacyPlaintext: boolean } {\n if (!isEncryptedVaultValue(storedValue)) {\n return { value: storedValue, legacyPlaintext: true };\n }\n\n const encoded = storedValue.slice(ENVELOPE_PREFIX.length);\n const [ivPart, ciphertextPart, tagPart, ...extra] = encoded.split(\".\");\n if (!ivPart || ciphertextPart === undefined || !tagPart || extra.length > 0) {\n throw new Error(\"Invalid encrypted vault value\");\n }\n\n const iv = Buffer.from(ivPart, \"base64url\");\n const ciphertext = Buffer.from(ciphertextPart, \"base64url\");\n const tag = Buffer.from(tagPart, \"base64url\");\n if (iv.length !== IV_BYTES || tag.length !== 16) {\n throw new Error(\"Invalid encrypted vault value\");\n }\n\n const decipher = createDecipheriv(\"aes-256-gcm\", encryptionKey(masterKey), iv);\n decipher.setAAD(aad(userId, key));\n decipher.setAuthTag(tag);\n const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);\n return { value: plaintext.toString(\"utf8\"), legacyPlaintext: false };\n}\n",
32
35
  "import { VAULT_MASTER_KEY } from \"#platform/config\";\nimport {\n decryptVaultValueWithKey,\n encryptVaultValueWithKey,\n isEncryptedVaultValue,\n} from \"#storage/vault-crypto-core\";\n\nexport { isEncryptedVaultValue };\n\n/** Encrypt one vault row. The user/key binding prevents ciphertext row swapping. */\nexport function encryptVaultValue(\n userId: string,\n key: string,\n value: string,\n masterKey = VAULT_MASTER_KEY,\n): string {\n return encryptVaultValueWithKey(userId, key, value, masterKey);\n}\n\n/**\n * Decrypt a stored value. Plaintext rows are accepted for rolling upgrades and\n * are re-encrypted by the storage layer immediately after a successful read.\n */\nexport function decryptVaultValue(\n userId: string,\n key: string,\n storedValue: string,\n masterKey = VAULT_MASTER_KEY,\n): { value: string; legacyPlaintext: boolean } {\n return decryptVaultValueWithKey(userId, key, storedValue, masterKey);\n}\n",
@@ -35,7 +38,7 @@
35
38
  "/** Default latest-request context occupancy that triggers a warning. */\nexport const DEFAULT_CONTEXT_WARNING_RATIO = 0.8;\n\n/** Provider-neutral context occupancy input for public consumers. */\nexport interface ContextOccupancy {\n contextTokens?: number | null;\n contextWindow?: number | null;\n}\n\n/** Minimal Claude request usage shape; intentionally independent of the Anthropic SDK types. */\nexport interface ClaudeRequestTokenUsage {\n input_tokens?: number | null;\n output_tokens?: number | null;\n cache_creation_input_tokens?: number | null;\n cache_read_input_tokens?: number | null;\n}\n\nexport interface ContextWarningTextOptions {\n topicTitle: string;\n usage: ContextOccupancy;\n /** Whether this consumer implements the compact command. Defaults to true. */\n supportsCompact?: boolean;\n compactCommand?: string;\n newCommand?: string;\n}\n\nexport interface ContextWarningOptions extends ContextWarningTextOptions {\n /** Caller-owned dedupe key, normally scoped to one user/topic session. */\n key: string;\n thresholdRatio?: number;\n}\n\n/** Caller-owned state. Create one per runtime/store boundary to avoid global key collisions. */\nexport interface ContextWarningState {\n readonly warnedKeys: Set<string>;\n}\n\nexport function createContextWarningState(\n warnedKeys: Set<string> = new Set(),\n): ContextWarningState {\n return { warnedKeys };\n}\n\n/** Latest-request context occupancy, or null when the provider did not report valid values. */\nexport function contextUsageRatio(usage: ContextOccupancy): number | null {\n const used = usage.contextTokens;\n const window = usage.contextWindow;\n if (\n used === undefined ||\n used === null ||\n window === undefined ||\n window === null ||\n !Number.isFinite(used) ||\n !Number.isFinite(window) ||\n used < 0 ||\n window <= 0\n ) {\n return null;\n }\n return used / window;\n}\n\nexport function shouldWarnForContext(\n usage: ContextOccupancy,\n thresholdRatio = DEFAULT_CONTEXT_WARNING_RATIO,\n): boolean {\n if (!Number.isFinite(thresholdRatio) || thresholdRatio < 0) return false;\n const ratio = contextUsageRatio(usage);\n return ratio !== null && ratio >= thresholdRatio;\n}\n\nexport function formatContextTokenCount(value: number): string {\n if (!Number.isFinite(value) || value < 0) return \"0K\";\n return value >= 1_000_000 ? `${(value / 1_000_000).toFixed(1)}M` : `${Math.round(value / 1000)}K`;\n}\n\n/** Build the shared warning copy while adapting command guidance to consumer capabilities. */\nexport function buildContextWarningText(options: ContextWarningTextOptions): string {\n const ratio = contextUsageRatio(options.usage) ?? 0;\n const used = options.usage.contextTokens ?? 0;\n const window = options.usage.contextWindow ?? 0;\n const compactCommand = options.compactCommand ?? \"/compact\";\n const newCommand = options.newCommand ?? \"/new\";\n const supportsCompact = options.supportsCompact ?? true;\n const guidance = supportsCompact\n ? `이 토픽에서 ${compactCommand} 를 입력하면 핵심 맥락을 요약해 이어가면서 context를 줄입니다. 완전히 새로 시작하려면 ${newCommand} 를 사용하세요.\\n\\n두 명령 모두 지금까지 주고받은 보이는 대화 내역은 그대로 유지합니다.`\n : `완전히 새 context로 시작하려면 ${newCommand} 를 사용하세요. 지금까지 주고받은 보이는 대화 내역은 그대로 유지합니다.`;\n\n return (\n `⚠️ \"${options.topicTitle}\" context가 ${Math.round(ratio * 100)}% 찼어요 ` +\n `(${formatContextTokenCount(used)} / ${formatContextTokenCount(window)} 토큰)\\n\\n` +\n guidance\n );\n}\n\n/**\n * Return and dedupe the next warning using state owned by the caller.\n * The key is marked only when the threshold is actually reached.\n */\nexport function nextContextWarning(\n state: ContextWarningState,\n options: ContextWarningOptions,\n): string | null {\n if (!shouldWarnForContext(options.usage, options.thresholdRatio)) return null;\n if (state.warnedKeys.has(options.key)) return null;\n state.warnedKeys.add(options.key);\n return buildContextWarningText(options);\n}\n\nexport function clearContextWarning(state: ContextWarningState, key: string): void {\n state.warnedKeys.delete(key);\n}\n\n/** Latest Claude request context tokens using the same fields Negotium providers receive. */\nexport function claudeRequestContextTokens(usage: ClaudeRequestTokenUsage): number | null {\n const values = [\n usage.input_tokens,\n usage.cache_creation_input_tokens,\n usage.cache_read_input_tokens,\n usage.output_tokens,\n ];\n if (values.every((value) => value === undefined || value === null)) return null;\n if (\n values.some(\n (value) => value !== undefined && value !== null && (!Number.isFinite(value) || value < 0),\n )\n ) {\n return null;\n }\n return values.reduce<number>((sum, value) => sum + (value ?? 0), 0);\n}\n",
36
39
  "import { execFileSync } from \"node:child_process\";\nimport { existsSync, readFileSync, realpathSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, isAbsolute, join, relative, resolve } from \"node:path\";\nimport type {\n FileChangeItem,\n McpToolCallItem,\n ModelReasoningEffort,\n SandboxMode,\n ThreadOptions,\n} from \"@openai/codex-sdk\";\nimport { Codex } from \"@openai/codex-sdk\";\nimport {\n ensureCodexModelCache,\n writeCodexCatalogWithNativeMultiAgentDisabled,\n} from \"#agents/codex-native-multi-agent\";\nimport {\n acquireCodexSpawnLock,\n findNewCodexChildren,\n killCodexTrees,\n registerOwnedCodexPids,\n snapshotCodexChildren,\n unregisterOwnedCodexPids,\n} from \"#agents/codex-tree-kill\";\nimport { createCodexVaultHookBridge } from \"#agents/codex-vault-hook-bridge\";\nimport { deepMapStrings } from \"#agents/deep-map\";\nimport {\n hostedCodexAuthFilePath,\n hostedCodexHomePath,\n hostedMcpServers,\n redactHostedSecrets,\n} from \"#agents/execution-host\";\nimport {\n type CodexTokenTotals,\n migrateCodexRolloutNativeMultiAgentMetadata,\n readCodexPatchCallIds,\n readLatestCodexContextUsage,\n readLatestCodexPatchPreview,\n readLatestCodexTokenTotals,\n} from \"#agents/rollout/codex\";\nimport { buildNumberedDiffSummary } from \"#agents/tool-format\";\nimport { extractFileEvents } from \"#media/file-events\";\nimport { errMsg } from \"#platform/error\";\nimport { logger } from \"#platform/logger\";\nimport {\n browserOwnerCapability,\n browserOwnerForContext,\n CODEX_BROWSER_CAPABILITY_ENV,\n} from \"#platform/mcp-config\";\nimport type { AgentQueryOptions, EffortLevel, UnifiedEvent } from \"#types\";\n\ntype CodexEventUsage = {\n input_tokens: number;\n output_tokens: number;\n cached_input_tokens?: number;\n cache_write_input_tokens?: number;\n};\n\nconst CODEX_HOOK_TRUST_BYPASS_NOTICE =\n \"`--dangerously-bypass-hook-trust` is enabled. Enabled hooks may run without review for this invocation.\";\n\nfunction sameCodexUsage(usage: CodexEventUsage, total: CodexTokenTotals): boolean {\n return (\n usage.input_tokens === total.inputTokens &&\n usage.output_tokens === total.outputTokens &&\n (usage.cached_input_tokens ?? 0) === total.cachedInputTokens &&\n (usage.cache_write_input_tokens ?? 0) === total.cacheWriteInputTokens\n );\n}\n\n/**\n * Some Codex CLI builds expose the thread-lifetime counter on turn.completed\n * despite the SDK declaring turn-local usage. Only subtract a rollout baseline\n * when the event exactly matches the rollout's cumulative counter.\n */\nexport function normalizeCodexTurnUsage(\n usage: CodexEventUsage,\n baseline: CodexTokenTotals | undefined,\n rolloutTotal: CodexTokenTotals | undefined,\n): CodexEventUsage {\n if (!baseline || !rolloutTotal || !sameCodexUsage(usage, rolloutTotal)) return usage;\n const delta = (current: number, previous: number) =>\n current >= previous ? current - previous : current;\n return {\n input_tokens: delta(rolloutTotal.inputTokens, baseline.inputTokens),\n output_tokens: delta(rolloutTotal.outputTokens, baseline.outputTokens),\n cached_input_tokens: delta(rolloutTotal.cachedInputTokens, baseline.cachedInputTokens),\n cache_write_input_tokens: delta(\n rolloutTotal.cacheWriteInputTokens,\n baseline.cacheWriteInputTokens,\n ),\n };\n}\n\n/**\n * Pass Otium's EffortLevel through to Codex's ModelReasoningEffort.\n *\n * Storage validation (`getRegistry(\"codex\").validateEffort` in the repository\n * setters) guarantees that any effort persisted on a codex topic is one of\n * codex's accepted set (`low | medium | high | xhigh`), so the SDK shape and\n * the stored shape are identical for codex topics. A `max` or `minimal`\n * reaching this function means storage validation was bypassed — we throw\n * instead of silently demoting so the bug surfaces rather than masking itself.\n */\nfunction mapEffort(effort?: EffortLevel): ModelReasoningEffort | undefined {\n if (!effort) return undefined;\n if (effort === \"max\" || (effort as string) === \"minimal\") {\n throw new Error(\n `codexProvider received effort='${effort}', which codex does not support — storage validation was bypassed`,\n );\n }\n return effort as ModelReasoningEffort;\n}\n\n/**\n * Convert Otium's mcp-config output (Claude SDK shape) to Codex's\n * `config.mcp_servers` shape. Codex supports two transports:\n * - stdio: `{ command, args?, env? }`\n * - streamable HTTP: `{ url }` (verified via `codex mcp add --url`)\n *\n * Entries with the SSE transport shape (`{ type: \"sse\", url }`) are dropped:\n * codex doesn't speak SSE. Callers must produce the streamable HTTP shape\n * for codex by passing `agent: \"codex\"` into the `playwright.build()` arm\n * in `mcp-config.ts` (which switches `/sse` → `/mcp`).\n */\ntype CodexMcpTimeouts = {\n enabled?: boolean;\n startup_timeout_sec?: number;\n tool_timeout_sec?: number;\n};\ntype CodexStdioServer = {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n} & CodexMcpTimeouts;\ntype CodexHttpServer = {\n url: string;\n http_headers?: Record<string, string>;\n env_http_headers?: Record<string, string>;\n} & CodexMcpTimeouts;\ntype CodexMcpServer = CodexStdioServer | CodexHttpServer;\n\nconst CODEX_MCP_SERVER_NAME_OVERRIDES: Record<string, string> = {\n // Codex merges per-turn `--config mcp_servers.<name>.*` overrides with the\n // user's global ~/.codex/config.toml. `playwright` is a common global stdio\n // server name, and adding Otium's per-topic HTTP `url` to that same table\n // makes Codex fail config parsing with \"url is not supported for stdio\".\n playwright: \"otium_playwright\",\n // Disable any global `cua-rs` stdio entry below, while keeping Negotium's\n // node-owned Streamable HTTP server independently addressable.\n \"cua-rs\": \"otium_cua_rs\",\n};\n\nfunction codexMcpServerName(name: string): string {\n return CODEX_MCP_SERVER_NAME_OVERRIDES[name] ?? name;\n}\n\nfunction globalCodexMcpServerNames(authFilePath: string): string[] {\n const configPath = join(dirname(authFilePath), \"config.toml\");\n if (!existsSync(configPath)) return [];\n try {\n const names = new Set<string>();\n for (const line of readFileSync(configPath, \"utf8\").split(\"\\n\")) {\n const match = line.match(\n /^\\s*\\[\\s*mcp_servers\\.((?:\"(?:\\\\.|[^\"])*\")|(?:'[^']*')|[^.\\]\\s]+)(?:[.\\]])/,\n );\n const raw = match?.[1];\n if (!raw) continue;\n if (raw.startsWith('\"')) {\n try {\n names.add(JSON.parse(raw));\n } catch {\n // Ignore malformed TOML; Codex itself will report the config error.\n }\n } else if (raw.startsWith(\"'\")) {\n names.add(raw.slice(1, -1));\n } else {\n names.add(raw);\n }\n }\n return [...names];\n } catch (error) {\n logger.warn({ err: error, configPath }, \"codexProvider: failed to inspect global MCP config\");\n return [];\n }\n}\n\nfunction parsePositiveInt(value: string | undefined, fallback: number): number {\n if (!value) return fallback;\n const parsed = Number.parseInt(value, 10);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback;\n}\n\nfunction withCodexMcpServerOverrides(_name: string, server: CodexMcpServer): CodexMcpServer {\n // For codex, Otium launches MCP servers via node + tsx (see serverLaunch in\n // mcp-config.ts), which transpiles the .ts on the fly — cold start is slower\n // than `bun run`, so give the handshake a generous startup window. codex's\n // default startup timeout is short enough that a heavier server can miss it.\n return {\n startup_timeout_sec: parsePositiveInt(process.env.CODEX_MCP_STARTUP_TIMEOUT_SEC, 30),\n ...server,\n };\n}\n\nexport function toCodexMcpServers(\n claudeShape: Record<string, unknown>,\n): Record<string, CodexMcpServer> {\n // Codex merges turn config with ~/.codex/config.toml instead of replacing it.\n // Disable the global stdio entries a user may have for servers Negotium owns\n // as one long-lived process, so their state can only flow through that\n // process: browsers, and cua-rs, whose per-turn stdio copy would be a second\n // instance competing for the same desktop.\n const disabledStdio = (): CodexStdioServer => ({\n command: process.execPath,\n args: [\"-e\", \"process.exit(0)\"],\n enabled: false,\n });\n const out: Record<string, CodexMcpServer> = {\n playwright: disabledStdio(),\n \"browser-rs\": disabledStdio(),\n patchright: disabledStdio(),\n \"cua-rs\": disabledStdio(),\n };\n for (const [name, srv] of Object.entries(claudeShape)) {\n if (!srv || typeof srv !== \"object\") continue;\n const s = srv as Record<string, unknown>;\n const codexName = codexMcpServerName(name);\n if (typeof s.command === \"string\") {\n out[codexName] = withCodexMcpServerOverrides(name, {\n command: s.command,\n ...(Array.isArray(s.args) ? { args: s.args as string[] } : {}),\n ...(s.env && typeof s.env === \"object\" ? { env: s.env as Record<string, string> } : {}),\n });\n continue;\n }\n if (typeof s.url === \"string\" && s.type !== \"sse\") {\n out[codexName] = withCodexMcpServerOverrides(name, {\n url: s.url,\n ...((s.http_headers && typeof s.http_headers === \"object\") ||\n (s.headers && typeof s.headers === \"object\")\n ? {\n http_headers: (s.http_headers ?? s.headers) as Record<string, string>,\n }\n : {}),\n ...(s.env_http_headers && typeof s.env_http_headers === \"object\"\n ? { env_http_headers: s.env_http_headers as Record<string, string> }\n : {}),\n ...(typeof s.timeout === \"number\"\n ? { tool_timeout_sec: Math.max(1, Math.ceil(s.timeout / 1000)) }\n : {}),\n });\n }\n }\n return out;\n}\n\nfunction isMissingCodexRolloutError(err: unknown): boolean {\n const msg = errMsg(err);\n return /no rollout found|thread\\/resume failed/i.test(msg);\n}\n\n/**\n * Render an `mcp_tool_call` item's terminal payload into a short string for\n * the unified `tool_result` event. The SDK shape is\n * `result?: { content: ContentBlock[]; structured_content: unknown }` on\n * success, or `error?: { message: string }` on failure — neither is a raw\n * string, which is why the previous `typeof result === \"string\"` branch was\n * unreachable. Truncate to 200 chars to match command_execution behavior.\n */\nfunction summarizeMcpToolCallResult(item: McpToolCallItem): string {\n if (item.error) return item.error.message.slice(0, 200);\n if (!item.result) return \"\";\n const blocks = Array.isArray(item.result.content) ? item.result.content : [];\n const text = blocks\n .map((b) => {\n if (b && typeof b === \"object\" && \"type\" in b && b.type === \"text\" && \"text\" in b) {\n return String((b as { text?: unknown }).text ?? \"\");\n }\n return \"\";\n })\n .filter(Boolean)\n .join(\"\\n\");\n if (text) return text.slice(0, 200);\n // Fall back to a JSON dump of structured_content for non-text content blocks.\n return JSON.stringify(item.result.structured_content ?? \"\").slice(0, 200);\n}\n\nconst CODEX_DIFF_FILE_LIMIT = 512 * 1024;\nconst CODEX_DIFF_BASELINE_FILE_LIMIT = 200;\nconst CODEX_DIFF_BASELINE_BYTE_LIMIT = 16 * 1024 * 1024;\n\nfunction canonicalPath(path: string): string {\n try {\n return realpathSync(resolve(path));\n } catch {\n return resolve(path);\n }\n}\n\nfunction textFile(path: string, maxBytes = CODEX_DIFF_FILE_LIMIT): string | null | undefined {\n if (!existsSync(path)) return null;\n try {\n const byteLimit = Math.min(CODEX_DIFF_FILE_LIMIT, Math.max(0, maxBytes));\n if (statSync(path).size > byteLimit) return undefined;\n const content = readFileSync(path);\n if (content.byteLength > byteLimit || content.includes(0)) return undefined;\n return content.toString(\"utf8\");\n } catch {\n return undefined;\n }\n}\n\ninterface CodexFilePreview {\n before?: string;\n after?: string;\n diff_preview?: string;\n}\n\n/**\n * Codex's SDK exposes only path + change kind, not the patch body. Capture the\n * dirty worktree at turn start and compare each completed file_change against\n * that moving baseline. This preserves user edits that already existed before\n * the turn and gives repeated edits to the same file their own +/- preview.\n */\nclass CodexFilePreviewTracker {\n readonly #cwd: string;\n readonly #root: string | null;\n readonly #baseline = new Map<string, string | null | undefined>();\n #baselineAvailable = false;\n\n constructor(cwd: string) {\n this.#cwd = canonicalPath(cwd);\n const root = this.#git([\"rev-parse\", \"--show-toplevel\"], this.#cwd)?.trim();\n this.#root = root ? canonicalPath(root) : null;\n if (!this.#root) return;\n const status = this.#git([\"status\", \"--porcelain=v1\", \"-z\", \"--untracked-files=all\"]);\n if (status === undefined) return;\n this.#baselineAvailable = true;\n let loadedFiles = 0;\n let loadedBytes = 0;\n const records = status.split(\"\\0\");\n for (let index = 0; index < records.length; index += 1) {\n const record = records[index];\n if (!record || record.length < 4) continue;\n const code = record.slice(0, 2);\n const path = record.slice(3);\n const remainingBytes = CODEX_DIFF_BASELINE_BYTE_LIMIT - loadedBytes;\n const content =\n loadedFiles < CODEX_DIFF_BASELINE_FILE_LIMIT && remainingBytes > 0\n ? textFile(resolve(this.#root, path), remainingBytes)\n : undefined;\n this.#baseline.set(path, content);\n if (typeof content === \"string\") {\n loadedFiles += 1;\n loadedBytes += Buffer.byteLength(content);\n }\n if (/[RC]/.test(code)) index += 1;\n }\n }\n\n preview(path: string, succeeded: boolean): CodexFilePreview {\n if (!this.#root || !this.#baselineAvailable || !succeeded) return {};\n const absolute = canonicalPath(isAbsolute(path) ? path : resolve(this.#cwd, path));\n const relativePath = relative(this.#root, absolute);\n if (!relativePath || relativePath.startsWith(\"..\") || isAbsolute(relativePath)) return {};\n\n const before = this.#baseline.has(relativePath)\n ? this.#baseline.get(relativePath)\n : this.#headFile(relativePath);\n const after = textFile(absolute);\n this.#baseline.set(relativePath, after);\n if (before === undefined || after === undefined) return {};\n\n const diff = buildNumberedDiffSummary(before ?? \"\", after ?? \"\");\n return {\n ...(diff.before !== undefined ? { before: diff.before } : {}),\n ...(diff.after !== undefined ? { after: diff.after } : {}),\n ...(diff.diffPreview !== undefined ? { diff_preview: diff.diffPreview } : {}),\n };\n }\n\n #headFile(path: string): string | null | undefined {\n const content = this.#git([\"show\", `HEAD:${path}`]);\n if (content === undefined) return null;\n return Buffer.byteLength(content) > CODEX_DIFF_FILE_LIMIT || content.includes(\"\\0\")\n ? undefined\n : content;\n }\n\n #git(args: string[], cwd = this.#root ?? undefined): string | undefined {\n try {\n return execFileSync(\"git\", [\"-C\", cwd ?? \".\", ...args], {\n encoding: \"utf8\",\n maxBuffer: CODEX_DIFF_FILE_LIMIT * 4,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n // Runs per diff read; no console window for it. Ignored on POSIX.\n windowsHide: true,\n });\n } catch {\n return undefined;\n }\n }\n}\n\n// Codex emits file_change only after the patch finishes, so surface the\n// completed changes immediately as paired tool_use/tool_result events.\nasync function fileChangeEvents(\n item: FileChangeItem,\n previews: CodexFilePreviewTracker,\n cwd: string,\n threadId: string | null | undefined,\n consumedPatchCallIds: Set<string>,\n): Promise<UnifiedEvent[]> {\n const expectedPaths = item.changes.map((change) =>\n isAbsolute(change.path) ? change.path : resolve(cwd, change.path),\n );\n let nativePreview: ReturnType<typeof readLatestCodexPatchPreview>;\n // The SDK can emit item.completed a few milliseconds before Codex flushes\n // patch_apply_end to its rollout. Give that write a brief head start before\n // the first lookup, which also avoids matching an older patch for the same\n // path on resumed threads.\n if (threadId && item.status === \"completed\") {\n await new Promise((resolveDelay) => setTimeout(resolveDelay, 20));\n nativePreview = readLatestCodexPatchPreview(threadId, expectedPaths, consumedPatchCallIds);\n }\n for (const delayMs of [20, 40, 80, 120]) {\n if (nativePreview || !threadId || item.status !== \"completed\") break;\n await new Promise((resolveDelay) => setTimeout(resolveDelay, delayMs));\n nativePreview = readLatestCodexPatchPreview(threadId, expectedPaths, consumedPatchCallIds);\n }\n if (nativePreview) consumedPatchCallIds.add(nativePreview.callId);\n\n return item.changes.flatMap((change, index) => {\n const name = change.kind === \"add\" ? \"Write\" : change.kind === \"delete\" ? \"Delete\" : \"Edit\";\n const toolUseId = `${item.id}:${index}`;\n const success = item.status === \"completed\";\n const nativeChange = nativePreview?.changes[index];\n // Keep the moving filesystem baseline current even when the native patch\n // supplies the display preview. A later edit to the same file may need the\n // filesystem fallback, which must compare against this edit—not turn start.\n const fallbackPreview = previews.preview(change.path, success);\n const preview =\n success && nativeChange\n ? {\n ...(nativeChange.before !== undefined ? { before: nativeChange.before } : {}),\n ...(nativeChange.after !== undefined ? { after: nativeChange.after } : {}),\n ...(nativeChange.diffPreview !== undefined\n ? { diff_preview: nativeChange.diffPreview }\n : {}),\n }\n : fallbackPreview;\n return [\n {\n type: \"tool_use\" as const,\n name,\n input: { file_path: change.path, change_kind: change.kind, ...preview },\n toolUseId,\n },\n {\n type: \"tool_result\" as const,\n toolUseId,\n content: success\n ? `${change.kind} applied: ${change.path}`\n : `${change.kind} failed: ${change.path}`,\n // Explicit failure flag so clients don't have to parse the content\n // string to tell a failed file change from an applied one.\n ...(success ? {} : { isError: true as const }),\n },\n ];\n });\n}\n\nfunction promptForThread(opts: AgentQueryOptions, includeSystemPrompt: boolean): string {\n return includeSystemPrompt && opts.systemPrompt\n ? `[System Instructions]\\n${opts.systemPrompt}\\n\\n${opts.prompt}`\n : opts.prompt;\n}\n\n/**\n * Start a streamed turn and identify the codex PIDs we spawned, holding the\n * global spawn lock across the full window from baseline → first event.\n *\n * Why hold the lock across iteration: `@openai/codex-sdk`'s `runStreamed()`\n * returns a lazy async generator object. The actual `child_process.spawn()`\n * call happens on the first `iterator.next()`, not when `runStreamed()` is\n * awaited (see `node_modules/@openai/codex-sdk/dist/index.js:51-93,238`).\n * If we released the lock after `await runStreamed(...)`, a concurrent\n * codex caller's baseline would race against our actual spawn and one\n * caller would mis-attribute the other's PID.\n *\n * Returns the iterator (positioned just past the first event) plus the\n * first event itself, so the streaming loop can re-emit it before\n * resuming `iterator.next()`.\n */\ntype StartResult = {\n iter: AsyncIterator<unknown>;\n firstEvent: unknown;\n done: boolean;\n};\n\nasync function closeIterator(iter: AsyncIterator<unknown>): Promise<void> {\n try {\n await iter.return?.();\n } catch (err) {\n logger.warn({ err }, \"codexProvider: failed to close codex event iterator\");\n }\n}\n\n/**\n * Bound the spawn→first-event window. `thread.started` normally arrives within\n * a few seconds, so if NOTHING comes back in this window the codex turn is\n * genuinely stuck at startup (the bare-`/codex` hang symptom). We surface a\n * clear error fast instead of waiting out the much longer mid-stream heartbeat\n * (8 min) — a stuck startup never recovers, and retrying it is futile. Once the\n * first event arrives, the normal heartbeat governs long-running work.\n */\nconst CODEX_STARTUP_TIMEOUT_MS = 90_000;\n\nasync function startStreamedWithTracking(\n thread: ReturnType<Codex[\"startThread\"]>,\n prompt: string,\n abortSignal: AbortSignal | undefined,\n trackedPids: { pids: number[] },\n): Promise<StartResult> {\n const release = await acquireCodexSpawnLock();\n try {\n const baseline = snapshotCodexChildren();\n const runResult = await thread.runStreamed(prompt, {\n ...(abortSignal ? { signal: abortSignal } : {}),\n });\n const iter = (runResult.events as AsyncIterable<unknown>)[Symbol.asyncIterator]();\n // Force the first iterator step — this is when the SDK actually\n // child_process.spawn()s codex. After this awaits, the codex PID is\n // visible to pgrep as a child of our process.\n let first: IteratorResult<unknown>;\n // Startup watchdog: race the first event against CODEX_STARTUP_TIMEOUT_MS so\n // a codex that spawns but never emits anything can't hang the turn. On\n // timeout the iter.next() promise loses the race and we fall into the catch\n // below, which kills the spawned tree, closes the iterator, and rethrows the\n // clear error — surfaced to the user as an `error` event (no infinite wait).\n let startupTimer: ReturnType<typeof setTimeout> | undefined;\n try {\n const startupTimeout = new Promise<never>((_, reject) => {\n startupTimer = setTimeout(\n () =>\n reject(\n new Error(\n `Codex가 ${CODEX_STARTUP_TIMEOUT_MS / 1000}초 내 응답을 시작하지 않아 중단했습니다. 다시 시도해주세요.`,\n ),\n ),\n CODEX_STARTUP_TIMEOUT_MS,\n );\n });\n // Swallow a late rejection from the losing promise: if the startup\n // timeout wins the race, this dangling next() may settle later with\n // nobody awaiting it (would surface as an unhandledRejection).\n const nextP = iter.next();\n nextP.catch(() => {});\n first = await Promise.race([nextP, startupTimeout]);\n } catch (err) {\n // Abort OR startup-timeout after the SDK spawned codex but before the\n // first event resolves: the normal abort listener still sees no tracked\n // PID, so diff the baseline here and kill anything attributable before\n // propagating.\n const novel = findNewCodexChildren(baseline);\n if (novel.length > 0) {\n killCodexTrees(novel);\n }\n await closeIterator(iter);\n throw err;\n } finally {\n if (startupTimer) clearTimeout(startupTimer);\n }\n const novel = findNewCodexChildren(baseline);\n trackedPids.pids = novel;\n registerOwnedCodexPids(novel);\n return { iter, firstEvent: first.value, done: !!first.done };\n } finally {\n release();\n }\n}\n\n/**\n * Wrap an iterator into an AsyncIterable that first yields a pre-captured\n * `firstEvent` and then drains the underlying iterator. Lets the streaming\n * `for await` loop keep its existing switch over events without special-casing\n * the first iteration we already consumed during PID tracking.\n */\nfunction prependFirstEvent(\n iter: AsyncIterator<unknown>,\n firstEvent: unknown,\n alreadyDone: boolean,\n): AsyncIterable<unknown> {\n return {\n [Symbol.asyncIterator]() {\n let emittedFirst = false;\n let exhausted = alreadyDone;\n return {\n async next(): Promise<IteratorResult<unknown>> {\n if (!emittedFirst) {\n emittedFirst = true;\n if (alreadyDone) return { value: undefined, done: true };\n return { value: firstEvent, done: false };\n }\n if (exhausted) return { value: undefined, done: true };\n const r = await iter.next();\n if (r.done) exhausted = true;\n return r;\n },\n async return(value?: unknown): Promise<IteratorResult<unknown>> {\n exhausted = true;\n if (iter.return) return iter.return(value);\n return { value, done: true };\n },\n };\n },\n };\n}\n\n/**\n * Core Codex provider.\n * Same UnifiedEvent contract as claudeProvider. Uses @openai/codex-sdk.\n *\n * Notes:\n * - Codex has no `systemPrompt` option; prepend the current topic/system\n * instructions on every invocation, including resumed synthetic threads.\n * - Per-turn MCP isolation is achieved via CodexOptions.config.mcp_servers,\n * so the global ~/.codex/config.toml stays untouched.\n * - Streaming token-by-token text deltas are not exposed by the SDK; only\n * final agent_message and per-item updates. Callers that rely on\n * text_delta should still work because we yield a single text/result\n * event when the assistant message completes.\n */\nexport async function* codexProvider(opts: AgentQueryOptions): AsyncGenerator<UnifiedEvent> {\n const filePreviews = new CodexFilePreviewTracker(opts.cwd);\n // A resumed rollout may already contain patches for the same file. Mark\n // those calls consumed before this turn starts so a delayed new flush can\n // never be mistaken for the previous turn's edit.\n const consumedPatchCallIds = new Set(opts.sessionId ? readCodexPatchCallIds(opts.sessionId) : []);\n // Up-front auth file check — gives the user an actionable message\n // (\"`codex login` 으로 다시 로그인해주세요\") immediately instead of waiting\n // for the @openai/codex-sdk to spawn the codex binary and surface an\n // opaque OAuth failure on the first turn. Path is the default codex\n // location unless NEGOTIUM_CODEX_AUTH_FILE relocates it for this host.\n const codexAuthPath = hostedCodexAuthFilePath();\n if (!existsSync(codexAuthPath)) {\n yield {\n type: \"error\",\n content: `Codex auth file not found at ${codexAuthPath}. Run \\`codex login\\` to authenticate.`,\n };\n return;\n }\n\n let codexModelCatalogPath: string;\n try {\n const codexModelCachePath = await ensureCodexModelCache(codexAuthPath);\n codexModelCatalogPath = writeCodexCatalogWithNativeMultiAgentDisabled(\n codexAuthPath,\n codexModelCachePath,\n );\n if (opts.sessionId) migrateCodexRolloutNativeMultiAgentMetadata(opts.sessionId);\n } catch (err) {\n yield {\n type: \"error\",\n content: `Failed to enforce the Codex native multi-agent policy: ${errMsg(err)}`,\n };\n return;\n }\n\n const codexMcpServers = toCodexMcpServers(hostedMcpServers(opts));\n if (opts.toolPolicy) {\n const allowed = new Set(Object.keys(codexMcpServers));\n for (const name of globalCodexMcpServerNames(codexAuthPath)) {\n if (allowed.has(name)) continue;\n codexMcpServers[name] = {\n command: process.execPath,\n args: [\"-e\", \"process.exit(0)\"],\n enabled: false,\n };\n }\n }\n const browserOwner = browserOwnerForContext(opts);\n const scopedBrowserCapability =\n opts.playwrightCapability && browserOwner\n ? browserOwnerCapability(opts.playwrightCapability, browserOwner)\n : undefined;\n\n // Startup trace: codexProvider was otherwise silent until its first error or\n // heartbeat (8 min), so a stuck turn left \"0 lines of codex\" in the logs and\n // was impossible to localize (bug B). Record the resolved model/effort/cwd +\n // whether this is a fresh thread or a resume, so a future hang is pinpointed\n // to setup vs. the first stream step.\n logger.info(\n {\n model: opts.model ?? \"(sdk default)\",\n effort: opts.effort ?? \"(off)\",\n cwd: opts.cwd,\n cwdExists: existsSync(opts.cwd),\n resume: Boolean(opts.sessionId),\n mcpServerCount: Object.keys(codexMcpServers).length,\n },\n \"codexProvider: starting turn\",\n );\n\n const hostedCodexHome = hostedCodexHomePath();\n const inheritedCodexHome = process.env.CODEX_HOME || join(homedir(), \".codex\");\n const codexEnvironment =\n scopedBrowserCapability || resolve(hostedCodexHome) !== resolve(inheritedCodexHome)\n ? {\n ...Object.fromEntries(\n Object.entries(process.env).filter(\n (entry): entry is [string, string] => typeof entry[1] === \"string\",\n ),\n ),\n CODEX_HOME: hostedCodexHome,\n ...(scopedBrowserCapability\n ? { [CODEX_BROWSER_CAPABILITY_ENV]: scopedBrowserCapability }\n : {}),\n }\n : undefined;\n let vaultHook: Awaited<ReturnType<typeof createCodexVaultHookBridge>>;\n try {\n vaultHook = await createCodexVaultHookBridge(opts.vaultUserId ?? opts.userId ?? \"\");\n } catch (err) {\n yield { type: \"error\", content: `Failed to initialize Codex Vault hooks: ${errMsg(err)}` };\n return;\n }\n const codex = new Codex({\n codexPathOverride: vaultHook.codexPathOverride,\n ...(codexEnvironment ? { env: codexEnvironment } : {}),\n config: {\n // Negotium exposes delegation through runtime.spawn_subagent so child work\n // gets its own room/card and its result is routed back to the parent.\n // Codex enables its provider-native collaboration tools from the user's\n // global config by default; explicitly turn that feature off so v1 tools\n // (spawn_agent/send_input/resume_agent/wait_agent/close_agent) and v2\n // tools (spawn_agent/send_message/followup_task/wait_agent) cannot bypass\n // Negotium's orchestration or recursively fan out from subagent rooms.\n // Codex model metadata can override these flags. The authoritative\n // catalog above sets multi_agent_version=disabled as the hard stop; keep\n // all feature switches off as a second layer and use the documented\n // agents.enabled setting as a third, version-independent layer.\n agents: { enabled: false },\n // Persisted goals own their own task state and automatic continuation,\n // which conflicts with Negotium's shared task store and turn scheduler.\n features: {\n hooks: true,\n goals: false,\n multi_agent: false,\n multi_agent_v2: false,\n enable_fanout: false,\n },\n hooks: vaultHook.hooks,\n model_catalog_json: codexModelCatalogPath,\n mcp_servers: codexMcpServers,\n ...(opts.toolPolicy ? { sandbox_permissions: [] } : {}),\n },\n });\n\n const threadOptions: ThreadOptions = {\n workingDirectory: opts.cwd,\n skipGitRepoCheck: true,\n // Codex sandbox is intentionally disabled: Otium already assigns a managed\n // workspace cwd for the turn, and the bot is expected to act on it freely on\n // the user's behalf. SDK-level sandboxing would only constrain reach inside\n // that already-owned directory, which is not the threat model.\n sandboxMode: (opts.toolPolicy ? \"read-only\" : \"danger-full-access\") as SandboxMode,\n approvalPolicy: \"never\",\n ...(opts.toolPolicy\n ? {\n networkAccessEnabled: false,\n webSearchMode: \"disabled\" as const,\n webSearchEnabled: false,\n }\n : {}),\n ...(opts.model ? { model: opts.model } : {}),\n ...(opts.effort ? { modelReasoningEffort: mapEffort(opts.effort) } : {}),\n };\n\n let currentSessionId = opts.sessionId;\n let usageBaseline = currentSessionId ? readLatestCodexTokenTotals(currentSessionId) : undefined;\n\n // Codex SDK has no systemPrompt option. A resumed thread may have been\n // synthesized from a captured shell, so always refresh the current runtime\n // instructions instead of trusting historical developer/environment data.\n let thread = currentSessionId\n ? codex.resumeThread(currentSessionId, threadOptions)\n : codex.startThread(threadOptions);\n let prompt = promptForThread(opts, true);\n\n let agentTextSoFar = \"\";\n let currentAgentMessageId: string | undefined;\n let finalText = \"\";\n let stopReason = \"end_turn\";\n\n // Tree-kill instrumentation. The codex SDK spawns the `codex` binary as a\n // direct child of our process but does not expose the PID or place it in\n // its own process group. We identify our PIDs by diffing pgrep snapshots\n // around the SDK's first iterator step (when codex is actually spawned),\n // and SIGTERM the whole tree on abort with SIGKILL fallback inside\n // killCodexTrees().\n const trackedPids: { pids: number[] } = { pids: [] };\n const abortSignal = opts.abortController?.signal;\n const onAbortKill = () => {\n if (trackedPids.pids.length > 0) {\n killCodexTrees(trackedPids.pids);\n }\n };\n abortSignal?.addEventListener(\"abort\", onAbortKill, { once: true });\n\n // Heartbeat: if the Codex API emits no events within the window, abort the\n // current stream and resume the thread with a short continuation prompt.\n // The interval doubles each attempt (up to HEARTBEAT_MAX_MS) to avoid\n // interrupting genuinely long-running work on the first timeout.\n let heartbeatMs = 8 * 60 * 1000;\n let heartbeatAttempts = 0;\n const HEARTBEAT_MAX_MS = 16 * 60 * 1000;\n const HEARTBEAT_MAX_ATTEMPTS = 2;\n const HEARTBEAT_CONTINUATION = \"계속 진행해줘.\";\n\n try {\n while (true) {\n if (abortSignal?.aborted) return;\n\n // Per-attempt abort controller: lets the heartbeat timer abort only\n // this attempt's stream without touching the user-facing outer signal.\n const attemptAbort = new AbortController();\n const propagateOuter = () => attemptAbort.abort();\n abortSignal?.addEventListener(\"abort\", propagateOuter, { once: true });\n\n trackedPids.pids = [];\n let heartbeatTriggered = false;\n let attemptCompleted = false;\n let heartbeatTimer: ReturnType<typeof setTimeout> | null = null;\n\n const scheduleHeartbeat = () => {\n if (heartbeatTimer !== null) clearTimeout(heartbeatTimer);\n if (abortSignal?.aborted || attemptAbort.signal.aborted) return;\n heartbeatTimer = setTimeout(() => {\n heartbeatTriggered = true;\n if (trackedPids.pids.length > 0) killCodexTrees(trackedPids.pids);\n attemptAbort.abort();\n }, heartbeatMs);\n };\n\n try {\n scheduleHeartbeat();\n\n let startResult!: StartResult;\n try {\n startResult = await startStreamedWithTracking(\n thread,\n prompt,\n attemptAbort.signal,\n trackedPids,\n );\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") throw err;\n if (!currentSessionId || !isMissingCodexRolloutError(err)) throw err;\n if (opts.userId && opts.session) throw err;\n logger.warn(\n { staleSessionId: currentSessionId, err: errMsg(err) },\n \"codexProvider: stale/missing rollout, restarting fresh thread\",\n );\n thread = codex.startThread(threadOptions);\n prompt = promptForThread(opts, true);\n currentSessionId = undefined;\n usageBaseline = undefined;\n startResult = await startStreamedWithTracking(\n thread,\n prompt,\n attemptAbort.signal,\n trackedPids,\n );\n }\n\n // Cover the narrow window where abort fired between PID registration\n // and the abort listener actually running.\n if (attemptAbort.signal.aborted) {\n killCodexTrees(trackedPids.pids);\n await closeIterator(startResult.iter);\n throw Object.assign(new Error(\"heartbeat abort\"), { name: \"AbortError\" });\n }\n\n const eventStream = prependFirstEvent(\n startResult.iter,\n startResult.firstEvent,\n startResult.done,\n );\n\n for await (const rawEvent of eventStream) {\n scheduleHeartbeat();\n\n const event = rawEvent as {\n type: string;\n thread_id?: string;\n item?: {\n type: string;\n command?: string;\n tool?: string;\n arguments?: unknown;\n text?: string;\n id?: string;\n aggregated_output?: string;\n exit_code?: number;\n message?: string;\n status?: \"in_progress\" | \"completed\" | \"failed\";\n error?: { message?: string };\n };\n usage?: {\n input_tokens: number;\n output_tokens: number;\n cached_input_tokens?: number;\n cache_write_input_tokens?: number;\n };\n error?: { message?: string };\n };\n\n switch (event.type) {\n case \"thread.started\": {\n if (event.thread_id) {\n currentSessionId = event.thread_id;\n yield { type: \"session\", sessionId: event.thread_id };\n }\n break;\n }\n\n case \"item.started\": {\n const item = event.item;\n if (!item) break;\n if (item.type === \"command_execution\") {\n const command = redactHostedSecrets(\n opts.vaultUserId ?? opts.userId ?? \"\",\n String(item.command ?? \"\"),\n );\n yield {\n type: \"tool_use\",\n name: \"Bash\",\n input: { command },\n toolUseId: String(item.id ?? \"\"),\n };\n } else if (item.type === \"mcp_tool_call\") {\n const input =\n item.arguments && typeof item.arguments === \"object\"\n ? (item.arguments as Record<string, unknown>)\n : {};\n yield {\n type: \"tool_use\",\n name: String(item.tool ?? \"unknown\"),\n input: deepMapStrings(input, (value) =>\n redactHostedSecrets(opts.vaultUserId ?? opts.userId ?? \"\", value),\n ) as Record<string, unknown>,\n toolUseId: String(item.id ?? \"\"),\n };\n }\n break;\n }\n\n case \"item.updated\": {\n const item = event.item;\n if (!item) break;\n if (item.type === \"agent_message\") {\n const messageId = item.id != null ? String(item.id) : undefined;\n if (messageId !== currentAgentMessageId) {\n currentAgentMessageId = messageId;\n agentTextSoFar = \"\";\n }\n const text = String(item.text ?? \"\");\n const newChars = text.slice(agentTextSoFar.length);\n if (newChars) {\n yield { type: \"text_delta\", content: newChars };\n agentTextSoFar = text;\n }\n }\n break;\n }\n\n case \"item.completed\": {\n const item = event.item;\n if (!item) break;\n if (item.type === \"agent_message\") {\n finalText = String(item.text ?? \"\");\n agentTextSoFar = finalText;\n yield { type: \"text\", content: finalText };\n yield* extractFileEvents(finalText, \"text\");\n } else if (item.type === \"reasoning\") {\n const reasoning = String(item.text ?? \"\").trim();\n if (reasoning) yield { type: \"reasoning\", content: reasoning };\n } else if (item.type === \"mcp_tool_call\") {\n const isError = item.status === \"failed\" || Boolean(item.error);\n yield {\n type: \"tool_result\",\n toolUseId: String(item.id ?? \"\"),\n content: redactHostedSecrets(\n opts.vaultUserId ?? opts.userId ?? \"\",\n summarizeMcpToolCallResult(item as unknown as McpToolCallItem),\n ),\n ...(isError ? { isError: true } : {}),\n };\n } else if (item.type === \"command_execution\") {\n const isError =\n item.status === \"failed\" ||\n (typeof item.exit_code === \"number\" && item.exit_code !== 0);\n yield {\n type: \"tool_result\",\n toolUseId: String(item.id ?? \"\"),\n content: redactHostedSecrets(\n opts.vaultUserId ?? opts.userId ?? \"\",\n String(item.aggregated_output ?? \"\").slice(0, 200),\n ),\n ...(isError ? { isError: true } : {}),\n };\n } else if (item.type === \"file_change\") {\n const fileEvents = await fileChangeEvents(\n item as unknown as FileChangeItem,\n filePreviews,\n opts.cwd,\n currentSessionId,\n consumedPatchCallIds,\n );\n for (const fileEvent of fileEvents) {\n yield fileEvent;\n }\n } else if (item.type === \"error\") {\n const message = String(item.message ?? \"\");\n if (message !== CODEX_HOOK_TRUST_BYPASS_NOTICE) {\n yield { type: \"error\", content: message };\n }\n }\n break;\n }\n\n case \"turn.completed\": {\n const rawUsage = event.usage;\n if (!rawUsage) break;\n attemptCompleted = true;\n const usage = normalizeCodexTurnUsage(\n rawUsage,\n usageBaseline,\n currentSessionId ? readLatestCodexTokenTotals(currentSessionId) : undefined,\n );\n const contextUsage = currentSessionId\n ? readLatestCodexContextUsage(currentSessionId)\n : undefined;\n yield {\n type: \"result\",\n content: finalText,\n stopReason,\n usage: {\n inputTokens: usage.input_tokens,\n outputTokens: usage.output_tokens,\n cacheCreationInputTokens: usage.cache_write_input_tokens,\n cacheReadInputTokens: usage.cached_input_tokens,\n ...contextUsage,\n },\n };\n if (finalText) yield* extractFileEvents(finalText, \"result\");\n break;\n }\n\n case \"turn.failed\": {\n stopReason = \"error\";\n yield {\n type: \"error\",\n content: event.error?.message || \"Codex turn failed\",\n };\n break;\n }\n\n default:\n break;\n }\n }\n } catch (err) {\n if (abortSignal?.aborted) return;\n if (err instanceof Error && err.name === \"AbortError\") {\n if (!heartbeatTriggered) return;\n // Heartbeat abort — fall through to retry logic below\n } else {\n logger.error({ err }, \"codexProvider: attempt failed\");\n yield { type: \"error\", content: errMsg(err) };\n break;\n }\n } finally {\n if (heartbeatTimer !== null) clearTimeout(heartbeatTimer);\n abortSignal?.removeEventListener(\"abort\", propagateOuter);\n if (trackedPids.pids.length > 0) unregisterOwnedCodexPids(trackedPids.pids);\n }\n\n if (attemptCompleted || abortSignal?.aborted) break;\n if (!heartbeatTriggered) break;\n\n heartbeatAttempts++;\n if (heartbeatAttempts > HEARTBEAT_MAX_ATTEMPTS) {\n logger.warn(\n { attempts: heartbeatAttempts },\n \"codexProvider: max heartbeat attempts reached\",\n );\n yield {\n type: \"error\",\n content: `Codex가 ${HEARTBEAT_MAX_ATTEMPTS}회 재시도 후에도 응답하지 않았습니다.`,\n };\n break;\n }\n\n heartbeatMs = Math.min(heartbeatMs * 2, HEARTBEAT_MAX_MS);\n logger.info(\n { attempt: heartbeatAttempts, nextIntervalMs: heartbeatMs },\n \"codexProvider: heartbeat fired, resuming thread with continuation prompt\",\n );\n\n // The resumed turn's agent_message grows from \"\" again. Stale lengths\n // from the aborted attempt would mis-slice deltas (silence until the new\n // text outgrows the old, then an arbitrary mid-string fragment), and a\n // resumed turn that ends without an agent_message would ship the\n // previous attempt's finalText as its result.\n agentTextSoFar = \"\";\n finalText = \"\";\n\n thread = currentSessionId\n ? codex.resumeThread(currentSessionId, threadOptions)\n : codex.startThread(threadOptions);\n prompt = currentSessionId ? HEARTBEAT_CONTINUATION : promptForThread(opts, true);\n }\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") return;\n if (abortSignal?.aborted) return;\n logger.error({ err }, \"codexProvider: setup failed\");\n yield { type: \"error\", content: errMsg(err) };\n } finally {\n abortSignal?.removeEventListener(\"abort\", onAbortKill);\n if (trackedPids.pids.length > 0) unregisterOwnedCodexPids(trackedPids.pids);\n await vaultHook.close();\n }\n}\n",
37
40
  "import { type ChildProcess, spawn } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport {\n chmodSync,\n copyFileSync,\n existsSync,\n mkdtempSync,\n readFileSync,\n renameSync,\n rmSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { NEGOTIUM_VERSION } from \"#version\";\n\ntype CodexModel = Record<string, unknown>;\ntype CodexModelCache = {\n client_version?: unknown;\n models?: unknown;\n};\n\nconst moduleRequire = createRequire(import.meta.url);\nconst codexSdkPackagePath = moduleRequire.resolve(\"@openai/codex-sdk/package.json\");\nconst codexSdkRequire = createRequire(codexSdkPackagePath);\nconst bundledCodexPackagePath = codexSdkRequire.resolve(\"@openai/codex/package.json\");\n\nfunction readPackageVersion(packageJsonPath: string): string {\n const parsed = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as { version?: unknown };\n if (typeof parsed.version !== \"string\" || !parsed.version.trim()) {\n throw new Error(`Codex package has no valid version: ${packageJsonPath}`);\n }\n return parsed.version;\n}\n\nexport const BUNDLED_CODEX_VERSION = readPackageVersion(bundledCodexPackagePath);\nconst SAFE_BUNDLED_CODEX_VERSION = BUNDLED_CODEX_VERSION.replace(/[^a-zA-Z0-9._-]/g, \"_\");\nconst NEGOTIUM_MODEL_CACHE = `negotium-models-cache-${SAFE_BUNDLED_CODEX_VERSION}.json`;\nconst NEGOTIUM_MODEL_CATALOG = `negotium-model-catalog-${SAFE_BUNDLED_CODEX_VERSION}.json`;\n\nexport function codexCliScriptPath(): string {\n return join(dirname(bundledCodexPackagePath), \"bin\", \"codex.js\");\n}\n\nfunction parseCodexModelCache(contents: string, sourcePath: string): CodexModelCache {\n let parsed: CodexModelCache;\n try {\n parsed = JSON.parse(contents) as CodexModelCache;\n } catch (error) {\n throw new Error(`Codex model cache is invalid JSON: ${sourcePath}`, { cause: error });\n }\n if (!Array.isArray(parsed.models) || parsed.models.length === 0) {\n throw new Error(`Codex model cache has no models: ${sourcePath}`);\n }\n return parsed;\n}\n\nfunction readCodexModelCache(cachePath: string): {\n contents: string;\n parsed: CodexModelCache;\n} {\n const contents = readFileSync(cachePath, \"utf8\");\n return { contents, parsed: parseCodexModelCache(contents, cachePath) };\n}\n\nfunction readCompatibleCodexModelCache(cachePath: string): {\n contents: string;\n parsed: CodexModelCache;\n} {\n const cache = readCodexModelCache(cachePath);\n if (cache.parsed.client_version !== BUNDLED_CODEX_VERSION) {\n const found =\n typeof cache.parsed.client_version === \"string\"\n ? cache.parsed.client_version\n : \"missing or invalid\";\n throw new Error(\n `Codex model cache version ${found} does not match Negotium's bundled Codex ${BUNDLED_CODEX_VERSION}: ${cachePath}`,\n );\n }\n return cache;\n}\n\nfunction writePrivateFileAtomic(path: string, contents: string): void {\n if (existsSync(path) && readFileSync(path, \"utf8\") === contents) return;\n\n const tempPath = `${path}.${process.pid}.${randomUUID()}.tmp`;\n try {\n writeFileSync(tempPath, contents, { encoding: \"utf8\", mode: 0o600 });\n renameSync(tempPath, path);\n chmodSync(path, 0o600);\n } finally {\n try {\n unlinkSync(tempPath);\n } catch {\n // renameSync normally consumed the temporary file.\n }\n }\n}\n\nexport function bundledCodexModelCachePath(authFilePath: string): string {\n return join(dirname(authFilePath), NEGOTIUM_MODEL_CACHE);\n}\n\nasync function bootstrapCodexModelCache(codexHome: string, cachePath: string): Promise<void> {\n const child = spawn(process.execPath, [codexCliScriptPath(), \"app-server\", \"--stdio\"], {\n env: { ...process.env, CODEX_HOME: codexHome },\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n // Background stdio server — no console window on Windows. Ignored on POSIX.\n windowsHide: true,\n });\n\n const refreshed = new Promise<void>((resolve, reject) => {\n let settled = false;\n let stdoutBuffer = \"\";\n let stderr = \"\";\n const timer = setTimeout(\n () => finish(new Error(\"timed out while refreshing the Codex model catalog\")),\n 15_000,\n );\n\n const finish = (error?: Error) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n try {\n child.stdin.end();\n child.kill();\n } catch {\n // The app server may already have exited after stdin closed.\n }\n if (error) reject(error);\n else if (!existsSync(cachePath)) reject(new Error(\"Codex did not create its model cache\"));\n else resolve();\n };\n\n const send = (message: Record<string, unknown>) => {\n child.stdin.write(`${JSON.stringify(message)}\\n`);\n };\n\n child.stderr.on(\"data\", (chunk) => {\n if (stderr.length < 4_096) stderr += String(chunk);\n });\n child.on(\"error\", (error) => finish(error));\n child.on(\"exit\", (code, signal) => {\n if (!settled) {\n finish(\n new Error(\n `Codex model catalog refresh exited with ${signal ? `signal ${signal}` : `code ${code ?? 1}`}${stderr.trim() ? `: ${stderr.trim()}` : \"\"}`,\n ),\n );\n }\n });\n child.stdout.on(\"data\", (chunk) => {\n stdoutBuffer += String(chunk);\n for (;;) {\n const newline = stdoutBuffer.indexOf(\"\\n\");\n if (newline < 0) break;\n const line = stdoutBuffer.slice(0, newline);\n stdoutBuffer = stdoutBuffer.slice(newline + 1);\n let message: { id?: number; error?: { message?: string } };\n try {\n message = JSON.parse(line) as typeof message;\n } catch {\n continue;\n }\n if (message.id === 1) {\n if (message.error) {\n finish(new Error(message.error.message || \"Codex initialization failed\"));\n return;\n }\n send({ method: \"initialized\" });\n send({ id: 2, method: \"model/list\", params: { includeHidden: true } });\n } else if (message.id === 2) {\n if (message.error) {\n finish(new Error(message.error.message || \"Codex model listing failed\"));\n } else {\n finish();\n }\n return;\n }\n }\n });\n\n send({\n id: 1,\n method: \"initialize\",\n params: {\n clientInfo: { name: \"negotium\", version: NEGOTIUM_VERSION },\n capabilities: { experimentalApi: true },\n },\n });\n });\n\n try {\n await refreshed;\n } finally {\n // `child.kill()` only signals. The caller deletes CODEX_HOME right after we\n // return, and Windows cannot delete a directory the child still holds open\n // (EBUSY), so wait for the process to actually exit first.\n await waitForChildExit(child, CODEX_BOOTSTRAP_EXIT_WAIT_MS);\n }\n}\n\nconst CODEX_BOOTSTRAP_EXIT_WAIT_MS = 3_000;\n\nfunction waitForChildExit(child: ChildProcess, timeoutMs: number): Promise<void> {\n if (child.exitCode !== null || child.signalCode !== null) return Promise.resolve();\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, timeoutMs);\n timer.unref?.();\n child.once(\"exit\", () => {\n clearTimeout(timer);\n resolve();\n });\n });\n}\n\n/**\n * Remove the temporary CODEX_HOME. On Windows a just-exited child (or an\n * antivirus scan of the files it wrote) can keep the directory busy for a\n * moment, so retry, and never let cleanup of a throwaway directory fail a turn\n * whose result was already read. POSIX keeps the original behaviour: unlinking\n * open files works there, and a genuine failure still surfaces.\n */\nfunction removeIsolatedCodexHome(dir: string): void {\n if (process.platform !== \"win32\") {\n rmSync(dir, { recursive: true, force: true });\n return;\n }\n try {\n rmSync(dir, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 });\n } catch {\n // Best effort: the OS temp cleaner will reclaim it.\n }\n}\n\nasync function bootstrapIsolatedCodexModelCache(\n authFilePath: string,\n bootstrap: (codexHome: string, cachePath: string) => Promise<void>,\n): Promise<string> {\n const sourceHome = dirname(authFilePath);\n const isolatedHome = mkdtempSync(join(tmpdir(), \"negotium-codex-models-\"));\n const isolatedCachePath = join(isolatedHome, \"models_cache.json\");\n\n try {\n const isolatedAuthPath = join(isolatedHome, \"auth.json\");\n copyFileSync(authFilePath, isolatedAuthPath);\n chmodSync(isolatedAuthPath, 0o600);\n\n // Preserve custom provider configuration while keeping the bundled CLI's\n // cache write completely outside the user's shared CODEX_HOME.\n const sourceConfigPath = join(sourceHome, \"config.toml\");\n if (existsSync(sourceConfigPath)) {\n const isolatedConfigPath = join(isolatedHome, \"config.toml\");\n copyFileSync(sourceConfigPath, isolatedConfigPath);\n chmodSync(isolatedConfigPath, 0o600);\n }\n\n await bootstrap(isolatedHome, isolatedCachePath);\n return readCompatibleCodexModelCache(isolatedCachePath).contents;\n } finally {\n removeIsolatedCodexHome(isolatedHome);\n }\n}\n\nexport async function ensureCodexModelCache(\n authFilePath: string,\n bootstrap: (codexHome: string, cachePath: string) => Promise<void> = bootstrapCodexModelCache,\n): Promise<string> {\n const codexHome = dirname(authFilePath);\n const configuredCachePath = process.env.NEGOTIUM_CODEX_MODELS_CACHE_FILE;\n if (configuredCachePath) {\n if (!existsSync(configuredCachePath)) {\n throw new Error(`Configured Codex model cache does not exist: ${configuredCachePath}`);\n }\n readCompatibleCodexModelCache(configuredCachePath);\n return configuredCachePath;\n }\n\n // The global Codex CLI owns models_cache.json and may update it to a schema\n // newer than the SDK bundled by Negotium. Snapshot a cache generated for our\n // exact bundled version so later global CLI updates cannot break turns.\n const bundledCachePath = bundledCodexModelCachePath(authFilePath);\n const sharedCachePath = join(codexHome, \"models_cache.json\");\n if (existsSync(sharedCachePath)) {\n try {\n const shared = readCompatibleCodexModelCache(sharedCachePath);\n // Keep model metadata fresh while the global CLI remains compatible.\n writePrivateFileAtomic(bundledCachePath, shared.contents);\n return bundledCachePath;\n } catch {\n // A compatible private snapshot is safer than failing because another\n // process briefly exposed an incomplete shared-cache write.\n }\n }\n\n if (existsSync(bundledCachePath)) {\n try {\n readCompatibleCodexModelCache(bundledCachePath);\n return bundledCachePath;\n } catch {\n // Re-bootstrap below instead of passing a corrupt or version-mismatched\n // private snapshot into this SDK version.\n }\n }\n\n const refreshedContents = await bootstrapIsolatedCodexModelCache(authFilePath, bootstrap);\n writePrivateFileAtomic(bundledCachePath, refreshedContents);\n return bundledCachePath;\n}\n\n/**\n * Codex can resolve model metadata before `features.multi_agent=false`, so a\n * model-advertised v1/v2 value may still register native collaboration tools.\n * Feed Codex an authoritative copy of its own catalog with only that field\n * disabled. Runtime MCP delegation remains available independently.\n */\nexport function writeCodexCatalogWithNativeMultiAgentDisabled(\n authFilePath: string,\n sourcePath: string,\n): string {\n const codexHome = dirname(authFilePath);\n const outputPath = join(codexHome, NEGOTIUM_MODEL_CATALOG);\n\n const parsed = readCodexModelCache(sourcePath).parsed;\n\n const models = (parsed.models as unknown[]).map((model, index): CodexModel => {\n if (!model || typeof model !== \"object\" || Array.isArray(model)) {\n throw new Error(`Codex model cache entry ${index} is invalid: ${sourcePath}`);\n }\n return { ...(model as CodexModel), multi_agent_version: \"disabled\" };\n });\n const contents = `${JSON.stringify({ models }, null, 2)}\\n`;\n writePrivateFileAtomic(outputPath, contents);\n return outputPath;\n}\n",
38
- "export const NEGOTIUM_VERSION = \"0.19.2\";\n",
41
+ "export const NEGOTIUM_VERSION = \"0.20.0\";\n",
39
42
  "import { execFileSync } from \"node:child_process\";\nimport { type CodexTreeHost, createCodexTreeManager } from \"#agents/codex-tree-manager\";\nimport { logger } from \"#platform/logger\";\n\nfunction execText(command: string, args: string[]): string {\n try {\n return execFileSync(command, args, {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n // Process bookkeeping, not something to flash a console for. Ignored on\n // POSIX.\n windowsHide: true,\n }).trim();\n } catch {\n return \"\";\n }\n}\n\nconst posixHost: CodexTreeHost = {\n parentPid: process.pid,\n getDirectChildren(parentPid) {\n const output = execText(\"pgrep\", [\"-P\", String(parentPid)]);\n if (!output) return [];\n return output\n .split(\"\\n\")\n .map(Number)\n .filter((pid) => Number.isFinite(pid) && pid > 0);\n },\n getProcessName: (pid) => execText(\"ps\", [\"-p\", String(pid), \"-o\", \"comm=\"]),\n getProcessStart: (pid) => execText(\"ps\", [\"-p\", String(pid), \"-o\", \"lstart=\"]),\n kill: (pid, signal) => process.kill(pid, signal),\n logger,\n};\n\nconst manager = createCodexTreeManager(posixHost);\n\nexport type CodexProcStamp = { pid: number; lstart: string };\n\nexport const snapshotCodexChildren = manager.snapshotChildren;\nexport const findNewCodexChildren = manager.findNewChildren;\nexport const registerOwnedCodexPids = manager.registerOwnedPids;\nexport const unregisterOwnedCodexPids = manager.unregisterOwnedPids;\nexport const acquireCodexSpawnLock = manager.acquireSpawnLock;\nexport const withCodexSpawnSerial = manager.withSpawnSerial;\nexport const killCodexTrees = manager.killTrees;\nexport const killOwnedCodexTreesForShutdown = manager.killOwnedTreesForShutdown;\n\nexport {\n type CodexTreeHost,\n type CodexTreeLogger,\n type CodexTreeManager,\n type CodexTreeManagerOptions,\n createCodexTreeManager,\n} from \"#agents/codex-tree-manager\";\n",
40
43
  "export interface CodexTreeLogger {\n warn(fields: Record<string, unknown>, message: string): void;\n}\n\nexport interface CodexTreeHost {\n parentPid: number;\n getDirectChildren(parentPid: number): number[];\n getProcessName(pid: number): string;\n getProcessStart(pid: number): string;\n kill(pid: number, signal: 0 | \"SIGTERM\" | \"SIGKILL\"): void;\n logger: CodexTreeLogger;\n}\n\nexport interface CodexTreeManagerOptions {\n sigkillDelayMs?: number;\n treeDepthCap?: number;\n processNamePattern?: RegExp;\n}\n\nexport interface CodexTreeManager {\n snapshotChildren(): Map<number, string>;\n findNewChildren(baseline: Map<number, string>): number[];\n registerOwnedPids(pids: Iterable<number>): void;\n unregisterOwnedPids(pids: Iterable<number>): void;\n acquireSpawnLock(): Promise<() => void>;\n withSpawnSerial<T>(fn: () => Promise<T>): Promise<T>;\n killTrees(rootPids: number[]): void;\n killOwnedTreesForShutdown(graceMs?: number): Promise<void>;\n}\n\ntype KillPlan = {\n rootPids: number[];\n targets: Map<number, string>;\n};\n\n/** Caller-owned Codex process tracker and tree reaper. */\nexport function createCodexTreeManager(\n host: CodexTreeHost,\n options: CodexTreeManagerOptions = {},\n): CodexTreeManager {\n const sigkillDelayMs = options.sigkillDelayMs ?? 5_000;\n const treeDepthCap = options.treeDepthCap ?? 16;\n const processNamePattern = options.processNamePattern ?? /codex/i;\n const ownedPids = new Set<number>();\n let spawnChain: Promise<void> = Promise.resolve();\n\n function collectTree(rootPid: number, out = new Set<number>(), depth = 0): Set<number> {\n if (out.has(rootPid)) return out;\n out.add(rootPid);\n if (depth >= treeDepthCap) {\n host.logger.warn(\n { rootPid, depth, cap: treeDepthCap },\n \"codex-tree-kill: tree depth cap reached, descendants beyond this point not collected\",\n );\n return out;\n }\n for (const child of host.getDirectChildren(rootPid)) {\n collectTree(child, out, depth + 1);\n }\n return out;\n }\n\n function snapshotChildren(): Map<number, string> {\n const snapshot = new Map<number, string>();\n for (const pid of host.getDirectChildren(host.parentPid)) {\n const name = host.getProcessName(pid);\n if (!name || !processNamePattern.test(name)) continue;\n snapshot.set(pid, host.getProcessStart(pid));\n }\n return snapshot;\n }\n\n function registerOwnedPids(pids: Iterable<number>): void {\n for (const pid of pids) ownedPids.add(pid);\n }\n\n function unregisterOwnedPids(pids: Iterable<number>): void {\n for (const pid of pids) ownedPids.delete(pid);\n }\n\n function findNewChildren(baseline: Map<number, string>): number[] {\n const novel: number[] = [];\n for (const [pid, start] of snapshotChildren()) {\n const previousStart = baseline.get(pid);\n if (previousStart !== undefined && previousStart === start) continue;\n if (!ownedPids.has(pid)) novel.push(pid);\n }\n return novel;\n }\n\n async function acquireSpawnLock(): Promise<() => void> {\n const previous = spawnChain;\n let release!: () => void;\n let released = false;\n spawnChain = new Promise<void>((resolve) => {\n release = () => {\n if (released) return;\n released = true;\n resolve();\n };\n });\n await previous;\n return release;\n }\n\n async function withSpawnSerial<T>(fn: () => Promise<T>): Promise<T> {\n const release = await acquireSpawnLock();\n try {\n return await fn();\n } finally {\n release();\n }\n }\n\n function isAlive(pid: number): boolean {\n try {\n host.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n }\n\n function isSameProcess(pid: number, start: string): boolean {\n return start !== \"\" && isAlive(pid) && host.getProcessStart(pid) === start;\n }\n\n function signalTrees(rootPids: number[]): KillPlan | null {\n if (rootPids.length === 0) return null;\n const targets = new Map<number, string>();\n for (const rootPid of rootPids) {\n for (const pid of collectTree(rootPid)) {\n if (!targets.has(pid)) targets.set(pid, host.getProcessStart(pid));\n }\n }\n host.logger.warn(\n { rootPids, totalPids: targets.size },\n \"codex-tree-kill: SIGTERM process tree\",\n );\n for (const pid of targets.keys()) {\n try {\n host.kill(pid, \"SIGTERM\");\n } catch {\n // The process already exited or is no longer signalable.\n }\n }\n return { rootPids, targets };\n }\n\n function hasSurvivors(targets: Map<number, string>): boolean {\n for (const [pid, start] of targets) {\n if (isSameProcess(pid, start)) return true;\n }\n return false;\n }\n\n function killStragglers(plan: KillPlan): void {\n const aliveTargets: number[] = [];\n let droppedAsPossibleReuse = 0;\n for (const [pid, start] of plan.targets) {\n if (isSameProcess(pid, start)) aliveTargets.push(pid);\n else if (isAlive(pid)) droppedAsPossibleReuse++;\n }\n if (aliveTargets.length === 0) return;\n\n const reachable = new Set(aliveTargets);\n for (const rootPid of plan.rootPids) {\n const start = plan.targets.get(rootPid);\n if (start && isSameProcess(rootPid, start)) {\n for (const pid of collectTree(rootPid)) reachable.add(pid);\n }\n }\n const stragglers: number[] = [];\n for (const pid of reachable) {\n const start = plan.targets.get(pid);\n if (start && isSameProcess(pid, start)) stragglers.push(pid);\n else if (isAlive(pid)) droppedAsPossibleReuse++;\n }\n host.logger.warn(\n {\n aliveRoots: plan.rootPids.filter((pid) => {\n const start = plan.targets.get(pid);\n return start ? isSameProcess(pid, start) : false;\n }),\n totalStragglers: stragglers.length,\n droppedAsPossibleReuse,\n },\n \"codex-tree-kill: SIGKILL fallback after SIGTERM timeout\",\n );\n for (const pid of stragglers) {\n try {\n host.kill(pid, \"SIGKILL\");\n } catch {\n // The process exited during the survivor check.\n }\n }\n }\n\n function killTrees(rootPids: number[]): void {\n const plan = signalTrees(rootPids);\n if (!plan) return;\n const timer = setTimeout(() => killStragglers(plan), sigkillDelayMs);\n timer.unref?.();\n }\n\n async function killOwnedTreesForShutdown(graceMs = 3_000): Promise<void> {\n const roots = new Set(ownedPids);\n for (const pid of snapshotChildren().keys()) roots.add(pid);\n const plan = signalTrees([...roots]);\n if (!plan) return;\n const deadline = Date.now() + Math.max(0, graceMs);\n while (Date.now() < deadline && hasSurvivors(plan.targets)) {\n await new Promise<void>((resolve) =>\n setTimeout(resolve, Math.min(100, Math.max(1, deadline - Date.now()))),\n );\n }\n killStragglers(plan);\n }\n\n return {\n snapshotChildren,\n findNewChildren,\n registerOwnedPids,\n unregisterOwnedPids,\n acquireSpawnLock,\n withSpawnSerial,\n killTrees,\n killOwnedTreesForShutdown,\n };\n}\n",
41
44
  "import { randomBytes } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { chmod, copyFile, mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport type { Socket } from \"node:net\";\nimport { createServer } from \"node:net\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { codexCliScriptPath } from \"#agents/codex-native-multi-agent\";\nimport { ensureCodexWindowsWrapperExe } from \"#agents/codex-windows-wrapper\";\nimport { deepMapStrings } from \"#agents/deep-map\";\nimport { referencesHostedSecretStorage, substituteHostedSecrets } from \"#agents/execution-host\";\nimport { shouldSubstituteVaultToolInput } from \"#agents/vault-tool-policy\";\nimport { ipcEndpoint, restrictIpcEndpoint } from \"#platform/ipc\";\n\nconst MAX_HOOK_REQUEST_BYTES = 1024 * 1024;\nconst SENSITIVE_STORAGE_DENIAL = \"Runtime secret storage access is not permitted\";\nconst HOOK_SOCKET_ENV = \"NEGOTIUM_CODEX_VAULT_HOOK_SOCKET\";\nconst HOOK_TOKEN_ENV = \"NEGOTIUM_CODEX_VAULT_HOOK_TOKEN\";\n\nexport interface CodexPreToolUseInput {\n hook_event_name?: string;\n tool_name: string;\n tool_input: unknown;\n}\n\nexport type CodexPreToolUseOutput = Record<string, unknown>;\n\nexport interface CodexVaultHookOperations {\n referencesSensitiveStorage(value: unknown): boolean;\n substitute(userId: string, value: string): string;\n}\n\nexport function evaluateCodexVaultPreToolUse(\n input: CodexPreToolUseInput,\n userId: string,\n operations: CodexVaultHookOperations,\n): CodexPreToolUseOutput {\n if (operations.referencesSensitiveStorage(input.tool_input)) {\n return {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n permissionDecision: \"deny\",\n permissionDecisionReason: SENSITIVE_STORAGE_DENIAL,\n },\n };\n }\n\n if (!shouldSubstituteVaultToolInput(input.tool_name)) return {};\n const updatedInput = deepMapStrings(input.tool_input, (value) =>\n operations.substitute(userId, value),\n );\n if (JSON.stringify(updatedInput) === JSON.stringify(input.tool_input)) return {};\n return {\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n permissionDecision: \"allow\",\n updatedInput,\n },\n };\n}\n\nfunction shellQuote(value: string): string {\n return `'${value.replaceAll(\"'\", `'\"'\"'`)}'`;\n}\n\nfunction hookClientPath(): string {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const adjacent = resolve(moduleDir, \"codex-vault-hook.mjs\");\n if (existsSync(adjacent)) return adjacent;\n const packaged = resolve(moduleDir, \"runtime/src/agents/codex-vault-hook.mjs\");\n if (existsSync(packaged)) return packaged;\n throw new Error(\"Codex Vault hook client is missing from this installation\");\n}\n\nfunction privateCodexWrapper(codexScript: string, socketPath: string, token: string): string {\n return [\n \"#!/bin/sh\",\n `export ${HOOK_SOCKET_ENV}=${shellQuote(socketPath)}`,\n `export ${HOOK_TOKEN_ENV}=${shellQuote(token)}`,\n 'if [ \"$1\" = \"exec\" ]; then',\n \" shift\",\n ` exec ${shellQuote(process.execPath)} ${shellQuote(codexScript)} exec --dangerously-bypass-hook-trust \"$@\"`,\n \"fi\",\n `exec ${shellQuote(process.execPath)} ${shellQuote(codexScript)} \"$@\"`,\n \"\",\n ].join(\"\\n\");\n}\n\nexport interface CodexVaultHookBridge {\n codexPathOverride: string;\n environment: Record<string, string>;\n hooks: {\n PreToolUse: Array<{\n matcher: string;\n hooks: Array<{\n type: string;\n command: string;\n timeout: number;\n statusMessage: string;\n }>;\n }>;\n };\n close(): Promise<void>;\n}\n\n/**\n * Why the Windows wrapper is an `.exe`, not a script.\n *\n * The hook only runs if codex is invoked with `--dangerously-bypass-hook-trust`\n * -- an argv-only flag with no config-file or environment equivalent -- and the\n * SDK builds its own argv, so the flag can only be injected by a wrapper\n * standing in for the codex executable. On POSIX that wrapper is the\n * `#!/bin/sh` script above. Windows cannot use a script: `@openai/codex-sdk`\n * spawns `codexPathOverride` through `child_process.spawn` with no `shell`\n * option, and Node refuses to spawn a `.cmd`/`.bat` that way (EINVAL). So on\n * Windows the wrapper is a small compiled executable (see\n * `codex-windows-wrapper.ts`) that reads a private per-bridge config file.\n *\n * A bridge failure is still fatal for the turn (`codexProvider`), so a Codex\n * turn never runs with the Vault substitution and sensitive-storage denial\n * silently absent.\n */\nconst IS_WINDOWS = process.platform === \"win32\";\n\nfunction windowsQuote(value: string): string {\n return `\"${value.replaceAll('\"', '\\\\\"')}\"`;\n}\n\nexport async function createCodexVaultHookBridge(userId: string): Promise<CodexVaultHookBridge> {\n const root = await mkdtemp(join(tmpdir(), \"negotium-codex-vault-\"));\n await chmod(root, 0o700);\n // Windows listens on a named pipe instead; the digest in `ipcEndpoint` is\n // taken over this whole path, so the per-bridge mkdtemp above still supplies\n // the uniqueness that the constant basename does not.\n const socketPath = ipcEndpoint(join(root, \"hook.sock\"));\n const wrapperPath = join(root, IS_WINDOWS ? \"codex-with-hooks.exe\" : \"codex-with-hooks\");\n const token = randomBytes(32).toString(\"hex\");\n const connections = new Set<Socket>();\n const server = createServer((socket) => {\n connections.add(socket);\n socket.once(\"close\", () => connections.delete(socket));\n socket.setEncoding(\"utf8\");\n let request = \"\";\n let handled = false;\n const handleRequest = () => {\n if (handled) return;\n handled = true;\n try {\n const parsed = JSON.parse(request.trimEnd()) as {\n token?: unknown;\n input?: CodexPreToolUseInput;\n };\n if (parsed.token !== token) throw new Error(\"invalid hook capability\");\n if (\n !parsed.input ||\n typeof parsed.input !== \"object\" ||\n typeof parsed.input.tool_name !== \"string\"\n ) {\n throw new Error(\"invalid PreToolUse payload\");\n }\n const output = evaluateCodexVaultPreToolUse(parsed.input, userId, {\n referencesSensitiveStorage: referencesHostedSecretStorage,\n substitute: substituteHostedSecrets,\n });\n socket.end(JSON.stringify({ ok: true, output }));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n socket.end(JSON.stringify({ ok: false, error: message }));\n }\n };\n socket.on(\"data\", (chunk: string) => {\n request += chunk;\n if (Buffer.byteLength(request) > MAX_HOOK_REQUEST_BYTES) socket.destroy();\n else if (request.endsWith(\"\\n\")) handleRequest();\n });\n socket.on(\"end\", handleRequest);\n });\n\n try {\n await new Promise<void>((resolveListen, reject) => {\n server.once(\"error\", reject);\n server.listen(socketPath, () => {\n server.off(\"error\", reject);\n resolveListen();\n });\n });\n restrictIpcEndpoint(socketPath);\n if (IS_WINDOWS) {\n const { BINARIES_DIR } = await import(\"#platform/config\");\n const cached = await ensureCodexWindowsWrapperExe(join(BINARIES_DIR, \"codex-hook-wrapper\"));\n await copyFile(cached, wrapperPath);\n // Same private per-bridge dir as the POSIX wrapper; the exe reads this\n // file (runtime, codex script, hook socket, hook token, one per line).\n await writeFile(\n join(root, \"codex-with-hooks.cfg\"),\n [process.execPath, codexCliScriptPath(), socketPath, token].join(\"\\n\"),\n { encoding: \"utf8\", mode: 0o600 },\n );\n } else {\n await writeFile(wrapperPath, privateCodexWrapper(codexCliScriptPath(), socketPath, token), {\n mode: 0o700,\n });\n }\n\n // Keep the capability out of the process list and reviewed hook command.\n // The private wrapper explicitly authorizes this runtime-owned hook for\n // headless Codex turns.\n const quote = IS_WINDOWS ? windowsQuote : shellQuote;\n const command = [quote(process.execPath), quote(hookClientPath())].join(\" \");\n return {\n codexPathOverride: wrapperPath,\n environment: { [HOOK_SOCKET_ENV]: socketPath, [HOOK_TOKEN_ENV]: token },\n hooks: {\n PreToolUse: [\n {\n matcher: \"*\",\n hooks: [\n {\n type: \"command\",\n command,\n timeout: 30,\n statusMessage: \"Resolving Vault placeholders\",\n },\n ],\n },\n ],\n },\n async close() {\n for (const socket of connections) socket.destroy();\n await new Promise<void>((resolveClose) => server.close(() => resolveClose()));\n await rm(root, { recursive: true, force: true });\n },\n };\n } catch (error) {\n server.close();\n await rm(root, { recursive: true, force: true });\n throw error;\n }\n}\n",
@@ -48,7 +51,7 @@
48
51
  "import { readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\n\nexport type BundledClaudeRuntime =\n | { ok: true; sdkVersion: string; claudeCodeVersion: string }\n | { ok: false; error: string };\n\nlet cached: BundledClaudeRuntime | undefined;\n\nexport function inspectBundledClaudeRuntime(): BundledClaudeRuntime {\n if (cached) return cached;\n try {\n const require = createRequire(import.meta.url);\n const sdkDir = dirname(require.resolve(\"@anthropic-ai/claude-agent-sdk\"));\n const sdkPackage = JSON.parse(readFileSync(join(sdkDir, \"package.json\"), \"utf8\")) as {\n version?: unknown;\n };\n const manifest = JSON.parse(readFileSync(join(sdkDir, \"manifest.json\"), \"utf8\")) as {\n version?: unknown;\n };\n const sdkVersion = typeof sdkPackage.version === \"string\" ? sdkPackage.version : \"\";\n const claudeCodeVersion = typeof manifest.version === \"string\" ? manifest.version : \"\";\n if (!sdkVersion || !claudeCodeVersion) {\n cached = { ok: false, error: \"Claude Agent SDK runtime version metadata is incomplete\" };\n } else if (sdkVersion.split(\".\").at(-1) !== claudeCodeVersion.split(\".\").at(-1)) {\n cached = {\n ok: false,\n error: `Claude Agent SDK ${sdkVersion} does not match bundled Claude Code ${claudeCodeVersion}`,\n };\n } else {\n cached = { ok: true, sdkVersion, claudeCodeVersion };\n }\n } catch (error) {\n cached = {\n ok: false,\n error: `Failed to inspect bundled Claude runtime: ${\n error instanceof Error ? error.message : String(error)\n }`,\n };\n }\n return cached;\n}\n",
49
52
  "import { claudeProvider } from \"#agents/claude-provider\";\nimport { codexProvider } from \"#agents/codex-provider\";\nimport {\n type AgentExecutionHost,\n configureAgentExecutionHost,\n resolveAgentExecutionHost,\n transformHostedQueryOptions,\n withAgentExecutionHost,\n} from \"#agents/execution-host\";\nimport { maestroProvider } from \"#agents/maestro-provider\";\nimport { revokeCanonicalMcpBridgeTurn } from \"#mcp/canonical-bridge-config\";\nimport type { AgentQueryOptions, UnifiedEvent } from \"#types\";\n\nexport {\n buildClaudeDisallowedTools,\n claudeProvider,\n spawnClaudeCodeProcessWithTreeKill,\n} from \"#agents/claude-provider\";\nexport {\n type BundledClaudeRuntime,\n inspectBundledClaudeRuntime,\n} from \"#agents/claude-runtime-inspection\";\nexport { codexProvider, toCodexMcpServers } from \"#agents/codex-provider\";\nexport {\n buildMaestroDisallowedTools,\n buildMaestroToolHooks,\n maestroProvider,\n} from \"#agents/maestro-provider\";\nexport type { AgentQueryOptions, UnifiedEvent };\nexport { type AgentExecutionHost, configureAgentExecutionHost };\n\n/**\n * Provider-only execution entry point for embedding hosts.\n *\n * Conversation persistence, authorization, placement, and topic lifecycle are\n * deliberately not handled here; those remain the embedding host's concern.\n */\nexport async function* runHostedAgent(\n input: AgentQueryOptions,\n host?: Partial<AgentExecutionHost>,\n): AsyncGenerator<UnifiedEvent> {\n const executionHost = resolveAgentExecutionHost(host);\n const opts = await withAgentExecutionHost(executionHost, async () =>\n transformHostedQueryOptions({ ...input }),\n );\n try {\n let events: AsyncGenerator<UnifiedEvent>;\n switch (opts.agent) {\n case \"claude\":\n events = claudeProvider(opts);\n break;\n case \"codex\":\n events = codexProvider(opts);\n break;\n case \"maestro\":\n events = maestroProvider(opts);\n break;\n default: {\n const exhaustive: never = opts.agent;\n throw new Error(`runHostedAgent: unknown agent '${exhaustive}'`);\n }\n }\n while (true) {\n const next = await withAgentExecutionHost(executionHost, () => events.next());\n if (next.done) return;\n yield next.value;\n }\n } finally {\n if (opts.userId && opts.topicId && opts.queryId && opts.peerBridge) {\n revokeCanonicalMcpBridgeTurn({\n userId: opts.userId,\n topicId: opts.topicId,\n queryId: opts.queryId,\n peerBridge: opts.peerBridge,\n });\n }\n }\n}\n"
50
53
  ],
51
- "mappings": "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",
52
- "debugId": "AE528B367B6FEEB064756E2164756E21",
54
+ "mappings": "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",
55
+ "debugId": "977679FF27CBA61D64756E2164756E21",
53
56
  "names": []
54
57
  }