@wrongstack/core 0.285.0 → 0.287.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/autophase/phase-orchestrator.d.ts.map +1 -1
- package/dist/boot.d.ts.map +1 -1
- package/dist/coordination/agent-monitor.d.ts +29 -0
- package/dist/coordination/agent-monitor.d.ts.map +1 -1
- package/dist/coordination/autonomous-brain.d.ts +0 -2
- package/dist/coordination/autonomous-brain.d.ts.map +1 -1
- package/dist/coordination/autonomous-coordinator.d.ts +4 -0
- package/dist/coordination/autonomous-coordinator.d.ts.map +1 -1
- package/dist/coordination/brain-ledger.d.ts +142 -0
- package/dist/coordination/brain-ledger.d.ts.map +1 -0
- package/dist/coordination/brain-monitor.d.ts +46 -2
- package/dist/coordination/brain-monitor.d.ts.map +1 -1
- package/dist/coordination/brain.d.ts +43 -0
- package/dist/coordination/brain.d.ts.map +1 -1
- package/dist/coordination/delegate-tool.d.ts +8 -14
- package/dist/coordination/delegate-tool.d.ts.map +1 -1
- package/dist/coordination/director/director-btw-notes.d.ts +20 -0
- package/dist/coordination/director/director-btw-notes.d.ts.map +1 -0
- package/dist/coordination/director/director-collab.d.ts +40 -0
- package/dist/coordination/director/director-collab.d.ts.map +1 -0
- package/dist/coordination/director.d.ts +28 -9
- package/dist/coordination/director.d.ts.map +1 -1
- package/dist/coordination/fleet-manager.d.ts +21 -0
- package/dist/coordination/fleet-manager.d.ts.map +1 -1
- package/dist/coordination/fleet.d.ts +6 -7
- package/dist/coordination/fleet.d.ts.map +1 -1
- package/dist/coordination/global-mailbox.d.ts +96 -21
- package/dist/coordination/global-mailbox.d.ts.map +1 -1
- package/dist/coordination/icoordinator.d.ts +1 -3
- package/dist/coordination/icoordinator.d.ts.map +1 -1
- package/dist/coordination/index.d.ts +2 -1
- package/dist/coordination/index.d.ts.map +1 -1
- package/dist/coordination/index.js +2176 -806
- package/dist/coordination/index.js.map +4 -4
- package/dist/coordination/knowledge-graph.d.ts +13 -1
- package/dist/coordination/knowledge-graph.d.ts.map +1 -1
- package/dist/coordination/mail-tools.d.ts.map +1 -1
- package/dist/coordination/mailbox-actions.d.ts +12 -13
- package/dist/coordination/mailbox-actions.d.ts.map +1 -1
- package/dist/coordination/mailbox-constants.d.ts +64 -0
- package/dist/coordination/mailbox-constants.d.ts.map +1 -0
- package/dist/coordination/mailbox-events.d.ts +32 -0
- package/dist/coordination/mailbox-events.d.ts.map +1 -0
- package/dist/coordination/mailbox-message-codec.d.ts +28 -0
- package/dist/coordination/mailbox-message-codec.d.ts.map +1 -0
- package/dist/coordination/mailbox-types.d.ts +130 -5
- package/dist/coordination/mailbox-types.d.ts.map +1 -1
- package/dist/coordination/mailbox.d.ts +21 -2
- package/dist/coordination/mailbox.d.ts.map +1 -1
- package/dist/coordination/package-author-tracker.d.ts.map +1 -1
- package/dist/coordination/subagent-result-tool.d.ts.map +1 -1
- package/dist/core/agent-loop.d.ts.map +1 -1
- package/dist/core/agent-response.d.ts +10 -1
- package/dist/core/agent-response.d.ts.map +1 -1
- package/dist/core/agent-tools.d.ts.map +1 -1
- package/dist/core/agent.d.ts +8 -0
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/context.d.ts +25 -0
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/conversation-state.d.ts +6 -0
- package/dist/core/conversation-state.d.ts.map +1 -1
- package/dist/core/fallback-model.d.ts.map +1 -1
- package/dist/core/mailbox-loop.d.ts +12 -5
- package/dist/core/mailbox-loop.d.ts.map +1 -1
- package/dist/core/system-prompt-builder.d.ts +14 -6
- package/dist/core/system-prompt-builder.d.ts.map +1 -1
- package/dist/defaults/index.d.ts +0 -1
- package/dist/defaults/index.d.ts.map +1 -1
- package/dist/defaults/index.js +1690 -1998
- package/dist/defaults/index.js.map +4 -4
- package/dist/execution/auto-compaction-middleware.d.ts +8 -1
- package/dist/execution/auto-compaction-middleware.d.ts.map +1 -1
- package/dist/execution/autonomous-runner.d.ts +7 -1
- package/dist/execution/autonomous-runner.d.ts.map +1 -1
- package/dist/execution/autonomy-brain.d.ts +72 -11
- package/dist/execution/autonomy-brain.d.ts.map +1 -1
- package/dist/execution/brain-chain.d.ts +53 -0
- package/dist/execution/brain-chain.d.ts.map +1 -0
- package/dist/execution/brain-evaluation.d.ts +66 -0
- package/dist/execution/brain-evaluation.d.ts.map +1 -0
- package/dist/execution/brain-runtime.d.ts +171 -0
- package/dist/execution/brain-runtime.d.ts.map +1 -0
- package/dist/execution/compaction-core.d.ts.map +1 -1
- package/dist/execution/council-brain.d.ts +79 -0
- package/dist/execution/council-brain.d.ts.map +1 -0
- package/dist/execution/council-orchestrator.d.ts +32 -0
- package/dist/execution/council-orchestrator.d.ts.map +1 -0
- package/dist/execution/council-personas.d.ts +19 -0
- package/dist/execution/council-personas.d.ts.map +1 -0
- package/dist/execution/council-profiles.d.ts +34 -0
- package/dist/execution/council-profiles.d.ts.map +1 -0
- package/dist/execution/council-prompts.d.ts +21 -0
- package/dist/execution/council-prompts.d.ts.map +1 -0
- package/dist/execution/council-resolution.d.ts +57 -0
- package/dist/execution/council-resolution.d.ts.map +1 -0
- package/dist/execution/design-kit-loader.d.ts.map +1 -1
- package/dist/execution/enhance-recovery.d.ts +35 -0
- package/dist/execution/enhance-recovery.d.ts.map +1 -0
- package/dist/execution/error-handler.d.ts.map +1 -1
- package/dist/execution/eternal-autonomy.d.ts +12 -0
- package/dist/execution/eternal-autonomy.d.ts.map +1 -1
- package/dist/execution/index.d.ts +11 -1
- package/dist/execution/index.d.ts.map +1 -1
- package/dist/execution/index.js +3076 -526
- package/dist/execution/index.js.map +4 -4
- package/dist/execution/intelligent-compactor.d.ts +18 -7
- package/dist/execution/intelligent-compactor.d.ts.map +1 -1
- package/dist/execution/one-shot-llm.d.ts +52 -0
- package/dist/execution/one-shot-llm.d.ts.map +1 -0
- package/dist/execution/parallel-eternal-engine.d.ts +12 -0
- package/dist/execution/parallel-eternal-engine.d.ts.map +1 -1
- package/dist/execution/prompt-enhancer.d.ts +23 -4
- package/dist/execution/prompt-enhancer.d.ts.map +1 -1
- package/dist/execution/prompt-enhancer.js +24 -6
- package/dist/execution/prompt-enhancer.js.map +2 -2
- package/dist/execution/selective-compactor.d.ts +4 -4
- package/dist/execution/strategy-compactor.d.ts +7 -0
- package/dist/execution/strategy-compactor.d.ts.map +1 -1
- package/dist/execution/tool-executor.d.ts +19 -5
- package/dist/execution/tool-executor.d.ts.map +1 -1
- package/dist/hooks/registry.d.ts.map +1 -1
- package/dist/hooks/runner.d.ts.map +1 -1
- package/dist/hooks/shell-executor.d.ts.map +1 -1
- package/dist/hq/alerts.d.ts +5 -0
- package/dist/hq/alerts.d.ts.map +1 -1
- package/dist/hq/auth-store.d.ts +38 -10
- package/dist/hq/auth-store.d.ts.map +1 -1
- package/dist/hq/commands.d.ts +8 -4
- package/dist/hq/commands.d.ts.map +1 -1
- package/dist/hq/cost-bridge.d.ts +5 -3
- package/dist/hq/cost-bridge.d.ts.map +1 -1
- package/dist/hq/factory.d.ts +3 -0
- package/dist/hq/factory.d.ts.map +1 -1
- package/dist/hq/fleet-bridge.d.ts.map +1 -1
- package/dist/hq/index.d.ts +0 -1
- package/dist/hq/index.d.ts.map +1 -1
- package/dist/hq/index.js +1016 -283
- package/dist/hq/index.js.map +4 -4
- package/dist/hq/persistence.d.ts +42 -0
- package/dist/hq/persistence.d.ts.map +1 -1
- package/dist/hq/protocol/brain.d.ts +24 -0
- package/dist/hq/protocol/brain.d.ts.map +1 -0
- package/dist/hq/protocol/browser.d.ts +12 -0
- package/dist/hq/protocol/browser.d.ts.map +1 -0
- package/dist/hq/protocol/client.d.ts +69 -0
- package/dist/hq/protocol/client.d.ts.map +1 -0
- package/dist/hq/protocol/core.d.ts +130 -0
- package/dist/hq/protocol/core.d.ts.map +1 -0
- package/dist/hq/protocol/fleet.d.ts +73 -0
- package/dist/hq/protocol/fleet.d.ts.map +1 -0
- package/dist/hq/protocol/mailbox.d.ts +76 -0
- package/dist/hq/protocol/mailbox.d.ts.map +1 -0
- package/dist/hq/protocol/mcp.d.ts +51 -0
- package/dist/hq/protocol/mcp.d.ts.map +1 -0
- package/dist/hq/protocol/project.d.ts +26 -0
- package/dist/hq/protocol/project.d.ts.map +1 -0
- package/dist/hq/protocol/session.d.ts +153 -0
- package/dist/hq/protocol/session.d.ts.map +1 -0
- package/dist/hq/protocol/tool.d.ts +31 -0
- package/dist/hq/protocol/tool.d.ts.map +1 -0
- package/dist/hq/protocol.d.ts +10 -559
- package/dist/hq/protocol.d.ts.map +1 -1
- package/dist/hq/publisher.d.ts +4 -0
- package/dist/hq/publisher.d.ts.map +1 -1
- package/dist/index.d.ts +24 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7676 -3432
- package/dist/index.js.map +4 -4
- package/dist/infrastructure/index.js +13 -11
- package/dist/infrastructure/index.js.map +2 -2
- package/dist/infrastructure/token-counter.d.ts.map +1 -1
- package/dist/kernel/events/agent-events.d.ts +283 -0
- package/dist/kernel/events/agent-events.d.ts.map +1 -0
- package/dist/kernel/events/brain-events.d.ts +176 -0
- package/dist/kernel/events/brain-events.d.ts.map +1 -0
- package/dist/kernel/events/fleet-events.d.ts +39 -0
- package/dist/kernel/events/fleet-events.d.ts.map +1 -0
- package/dist/kernel/events/memory-events.d.ts +165 -0
- package/dist/kernel/events/memory-events.d.ts.map +1 -0
- package/dist/kernel/events/provider-events.d.ts +98 -0
- package/dist/kernel/events/provider-events.d.ts.map +1 -0
- package/dist/kernel/events/sdd-events.d.ts +118 -0
- package/dist/kernel/events/sdd-events.d.ts.map +1 -0
- package/dist/kernel/events/session-events.d.ts +227 -0
- package/dist/kernel/events/session-events.d.ts.map +1 -0
- package/dist/kernel/events/tool-events.d.ts +185 -0
- package/dist/kernel/events/tool-events.d.ts.map +1 -0
- package/dist/kernel/events/worktree-events.d.ts +58 -0
- package/dist/kernel/events/worktree-events.d.ts.map +1 -0
- package/dist/kernel/events.d.ts +12 -1282
- package/dist/kernel/events.d.ts.map +1 -1
- package/dist/kernel/index.js +22 -2
- package/dist/kernel/index.js.map +2 -2
- package/dist/kernel/run-controller.d.ts +15 -0
- package/dist/kernel/run-controller.d.ts.map +1 -1
- package/dist/mailbox-attach.d.ts.map +1 -1
- package/dist/models/index.js +19 -6
- package/dist/models/index.js.map +2 -2
- package/dist/models/llm-selector.d.ts +7 -0
- package/dist/models/llm-selector.d.ts.map +1 -1
- package/dist/observability/index.js +16 -15
- package/dist/observability/index.js.map +2 -2
- package/dist/plugins/auto-review-plugin.d.ts +36 -0
- package/dist/plugins/auto-review-plugin.d.ts.map +1 -0
- package/dist/plugins/chimera-plugin.d.ts +8 -0
- package/dist/plugins/chimera-plugin.d.ts.map +1 -1
- package/dist/security/index.d.ts +1 -0
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +260 -23
- package/dist/security/index.js.map +4 -4
- package/dist/security/permission-policy-schema.d.ts +77 -0
- package/dist/security/permission-policy-schema.d.ts.map +1 -0
- package/dist/security/permission-policy.d.ts +5 -0
- package/dist/security/permission-policy.d.ts.map +1 -1
- package/dist/security/secret-scrubber.d.ts.map +1 -1
- package/dist/security/secret-vault.d.ts +9 -0
- package/dist/security/secret-vault.d.ts.map +1 -1
- package/dist/session-registry.d.ts.map +1 -1
- package/dist/skills/index.js.map +2 -2
- package/dist/storage/config-loader.d.ts +10 -0
- package/dist/storage/config-loader.d.ts.map +1 -1
- package/dist/storage/goal-kanban.d.ts +69 -0
- package/dist/storage/goal-kanban.d.ts.map +1 -0
- package/dist/storage/goal-store.d.ts +1 -1
- package/dist/storage/goal-store.d.ts.map +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +572 -879
- package/dist/storage/index.js.map +4 -4
- package/dist/storage/memory-consolidator.d.ts +9 -1
- package/dist/storage/memory-consolidator.d.ts.map +1 -1
- package/dist/storage/plan-store.d.ts +1 -1
- package/dist/storage/plan-store.d.ts.map +1 -1
- package/dist/storage/queue-store.d.ts +4 -0
- package/dist/storage/queue-store.d.ts.map +1 -1
- package/dist/storage/session-store.d.ts +9 -0
- package/dist/storage/session-store.d.ts.map +1 -1
- package/dist/storage/task-store.d.ts +1 -1
- package/dist/storage/task-store.d.ts.map +1 -1
- package/dist/storage/todos-checkpoint.d.ts +2 -2
- package/dist/storage/todos-checkpoint.d.ts.map +1 -1
- package/dist/tools/council-tool.d.ts +25 -0
- package/dist/tools/council-tool.d.ts.map +1 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1884 -12
- package/dist/tools/index.js.map +4 -4
- package/dist/tools/one-shot-llm-tool.d.ts +51 -0
- package/dist/tools/one-shot-llm-tool.d.ts.map +1 -0
- package/dist/types/config.d.ts +236 -4
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/context-window.d.ts.map +1 -1
- package/dist/types/council.d.ts +134 -0
- package/dist/types/council.d.ts.map +1 -0
- package/dist/types/default-config.d.ts +3 -3
- package/dist/types/hooks.d.ts +14 -0
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +40 -8
- package/dist/types/index.js.map +3 -3
- package/dist/types/multi-agent.d.ts +8 -0
- package/dist/types/multi-agent.d.ts.map +1 -1
- package/dist/types/observability.d.ts +5 -0
- package/dist/types/observability.d.ts.map +1 -1
- package/dist/types/one-shot-llm.d.ts +128 -0
- package/dist/types/one-shot-llm.d.ts.map +1 -0
- package/dist/types/plugin.d.ts +6 -0
- package/dist/types/plugin.d.ts.map +1 -1
- package/dist/types/provider.d.ts +17 -0
- package/dist/types/provider.d.ts.map +1 -1
- package/dist/types/system-prompt.d.ts +2 -1
- package/dist/types/system-prompt.d.ts.map +1 -1
- package/dist/types/tool-executor.d.ts +10 -0
- package/dist/types/tool-executor.d.ts.map +1 -1
- package/dist/types/tool.d.ts +7 -0
- package/dist/types/tool.d.ts.map +1 -1
- package/dist/utils/atomic-write.d.ts.map +1 -1
- package/dist/utils/glob-expand.d.ts.map +1 -1
- package/dist/utils/incoming-images.d.ts +39 -0
- package/dist/utils/incoming-images.d.ts.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +156 -11
- package/dist/utils/index.js.map +4 -4
- package/dist/utils/tool-wire-compact.d.ts +1 -0
- package/dist/utils/tool-wire-compact.d.ts.map +1 -1
- package/dist/utils/wstack-paths.d.ts +20 -4
- package/dist/utils/wstack-paths.d.ts.map +1 -1
- package/dist/worktree/worktree-manager.d.ts +13 -4
- package/dist/worktree/worktree-manager.d.ts.map +1 -1
- package/instructions/agents/browser.md +25 -16
- package/instructions/cli/next-task-predictor.md +5 -3
- package/instructions/coordination/subagent-baseline.md +17 -2
- package/instructions/leader-after-task.md +19 -8
- package/instructions/llm/council-judge.md +19 -0
- package/instructions/llm/council-voter.md +22 -0
- package/instructions/modes/architect.md +14 -9
- package/instructions/modes/audit-lite.md +9 -7
- package/instructions/modes/brief-system.md +12 -12
- package/instructions/modes/brief.md +7 -5
- package/instructions/modes/code-auditor.md +13 -8
- package/instructions/modes/code-reviewer.md +13 -8
- package/instructions/modes/debug-lite.md +7 -6
- package/instructions/modes/debugger.md +13 -9
- package/instructions/modes/devops.md +13 -9
- package/instructions/modes/plan-lite.md +7 -6
- package/instructions/modes/refactor-lite.md +7 -6
- package/instructions/modes/refactorer.md +14 -9
- package/instructions/modes/research-lite.md +8 -6
- package/instructions/modes/research-web.md +18 -55
- package/instructions/modes/review-lite.md +7 -6
- package/instructions/modes/teach-system.md +15 -15
- package/instructions/modes/teach.md +13 -12
- package/instructions/modes/test-lite.md +6 -5
- package/instructions/modes/tester.md +13 -9
- package/instructions/modes/ui-design.md +14 -8
- package/instructions/sections/tool/commit-hygiene.md +1 -7
- package/instructions/sections/tool/common-patterns.md +7 -1
- package/instructions/sections/tool/delegation-full.md +3 -31
- package/instructions/sections/tool/mailbox-compact.md +1 -1
- package/instructions/sections/tool/mailbox-full.md +6 -22
- package/instructions/system.md +294 -8
- package/package.json +2 -2
- package/skills/docker-deploy/SKILL.md +1 -1
- package/skills/mailbox-bridge/SKILL.md +16 -7
- package/skills/output-standards/SKILL.md +16 -16
- package/skills/wrongstack-mailbox/SKILL.md +57 -12
- package/dist/coordination/director-construction.d.ts +0 -90
- package/dist/coordination/director-construction.d.ts.map +0 -1
- package/dist/hq/agent-bridge.d.ts +0 -27
- package/dist/hq/agent-bridge.d.ts.map +0 -1
- package/dist/plugins/git-plugin.d.ts +0 -15
- package/dist/plugins/git-plugin.d.ts.map +0 -1
- package/dist/plugins/observability-plugin.d.ts +0 -19
- package/dist/plugins/observability-plugin.d.ts.map +0 -1
- package/dist/plugins/plan-plugin.d.ts +0 -16
- package/dist/plugins/plan-plugin.d.ts.map +0 -1
- package/dist/storage/memory-store.d.ts +0 -119
- package/dist/storage/memory-store.d.ts.map +0 -1
package/dist/tools/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../src/utils/expect-defined.ts", "../../src/utils/error.ts", "../../src/security/capabilities.ts", "../../src/infrastructure/mcp-servers.ts", "../../src/utils/config-json.ts", "../../src/utils/atomic-write.ts", "../../src/tools/mcp-control.ts"],
|
|
4
|
-
"sourcesContent": ["/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n", "/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n", "/**\n * Well-known tool capabilities used for authorization decisions.\n *\n * These are the preferred values for `Tool.capabilities`.\n * New capabilities should be added here with clear documentation.\n *\n * Philosophy (2026-06+):\n * - Prefer capabilities over exact tool name matching.\n * - Subagent guards and future policies should primarily key off capabilities.\n * - Name-based denylists are legacy and will be phased down.\n */\nexport const ToolCapabilities = {\n /** Can execute arbitrary commands in the user's shell (the `bash` tool). */\n SHELL_ARBITRARY: 'shell.arbitrary',\n\n /** Can execute a restricted set of commands (the `exec` tool). */\n SHELL_RESTRICTED: 'shell.restricted',\n\n /** Can run a restricted project formatter/linter-style command. */\n SHELL_EXEC: 'shell.exec',\n\n /** Can read files inside the project (and possibly outside via symlinks if not guarded). */\n FS_READ: 'fs.read',\n\n /** Can write / modify / delete files inside the project. */\n FS_WRITE: 'fs.write',\n\n /** Can write files outside the current project root (very high risk). */\n FS_WRITE_OUTSIDE_PROJECT: 'fs.write.outside-project',\n\n /** Can perform outbound network requests. */\n NET_OUTBOUND: 'net.outbound',\n\n /** Can mutate in-memory session todos only. */\n SESSION_TODO: 'session.todo',\n\n /** Can mutate in-memory session mode only. */\n SESSION_MODE: 'session.mode',\n\n /** Can inspect registered tool metadata. */\n TOOL_META: 'tool.meta',\n\n /** Can invoke arbitrary registered tools through a meta-tool. */\n TOOL_MUTATE_ANY: 'tool.mutate.any',\n\n /** Can read persistent memory. */\n MEMORY_READ: 'memory.read',\n\n /** Can write persistent memory. */\n MEMORY_WRITE: 'memory.write',\n\n /** Can delete persistent memory. */\n MEMORY_DELETE: 'memory.delete',\n\n /** Proxies tools from external MCP servers (unknown capability). */\n MCP_PROXY: 'mcp.proxy',\n\n /** Can spawn or manage subagents / multi-agent tasks. */\n SUBAGENT_SPAWN: 'subagent.spawn',\n\n /** Can inspect fleet/subagent coordination state without mutating it. */\n COORDINATION_FLEET_READ: 'coordination.fleet.read',\n\n /** Can publish attributed, schema-checked events onto the fleet bus. */\n COORDINATION_FLEET_EMIT: 'coordination.fleet.emit',\n\n /** Can submit a task-local structured result to the parent Director. */\n COORDINATION_RESULT_SUBMIT: 'coordination.result.submit',\n\n /** Can read or write inter-agent mailbox messages. */\n COORDINATION_MAIL: 'coordination.mail',\n\n /** Can schedule, inspect, or cancel in-session cron jobs. */\n COORDINATION_CRON: 'coordination.cron',\n\n /** Can mutate global or session configuration / trust state. */\n CONFIG_MUTATE: 'config.mutate',\n\n /** Can install packages or run package managers with side effects. */\n PACKAGE_INSTALL: 'package.install',\n} as const;\n\nexport type ToolCapability = (typeof ToolCapabilities)[keyof typeof ToolCapabilities];\n\n/**\n * Set of capabilities that are considered dangerous for subagents by default.\n * Subagents should not receive these capabilities unless the leader explicitly\n * allows the specific tool at spawn time.\n */\nexport const DANGEROUS_FOR_SUBAGENTS: readonly ToolCapability[] = [\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ToolCapabilities.SHELL_EXEC,\n ToolCapabilities.FS_WRITE,\n ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,\n ToolCapabilities.TOOL_MUTATE_ANY,\n ToolCapabilities.MEMORY_WRITE,\n ToolCapabilities.MEMORY_DELETE,\n ToolCapabilities.MCP_PROXY,\n ToolCapabilities.SUBAGENT_SPAWN,\n ToolCapabilities.CONFIG_MUTATE,\n ToolCapabilities.PACKAGE_INSTALL,\n];\n\n/**\n * Wide capability allowlist for subagents that the user has authorized to act\n * with full developer power (the CLI fleet host applies this to any subagent\n * that isn't given an explicit, narrower grant). It covers everything needed to\n * do real work end-to-end \u2014 read, write/edit inside the project, outbound\n * network, all shell/build/install capabilities, session todos, tool metadata, and read-only\n * memory lookup \u2014 so a delegated coding or build agent runs the same toolchain\n * the leader would, without per-tool confirmation it cannot answer.\n *\n * Deliberately EXCLUDED (require an explicit per-spawn `allowedCapabilities`\n * grant, because they escape the task's blast radius rather than perform it):\n * - `fs.write.outside-project` \u2014 writing outside the repo (e.g. ~/.ssh).\n * - `tool.mutate.any` \u2014 arbitrary meta-tool dispatch.\n * - `memory.write` / `memory.delete` \u2014 persistent memory mutation.\n * - `mcp.proxy` \u2014 third-party MCP tools (also hard-blocked by name).\n * - `subagent.spawn` \u2014 recursive delegation (the baseline prompt forbids it).\n * - `config.mutate` \u2014 rewriting trust/config is privilege escalation, not work.\n */\nexport const WIDE_SUBAGENT_CAPABILITIES: readonly ToolCapability[] = [\n ToolCapabilities.FS_READ,\n ToolCapabilities.FS_WRITE,\n ToolCapabilities.NET_OUTBOUND,\n ToolCapabilities.SESSION_TODO,\n ToolCapabilities.TOOL_META,\n ToolCapabilities.MEMORY_READ,\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ToolCapabilities.SHELL_EXEC,\n ToolCapabilities.PACKAGE_INSTALL,\n // Read-only fleet visibility (fleet_status) \u2014 peer awareness has no blast\n // radius and every fleet worker should coordinate around its peers.\n ToolCapabilities.COORDINATION_FLEET_READ,\n ToolCapabilities.COORDINATION_RESULT_SUBMIT,\n];\n\n/**\n * Check if a tool (or its capabilities array) includes any dangerous capability\n * for subagent execution.\n */\nexport function hasDangerousCapabilityForSubagents(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n): boolean {\n if (!toolOrCaps) return false;\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n return caps.some((c) => DANGEROUS_FOR_SUBAGENTS.includes(c as ToolCapability));\n}\n\n/**\n * Check if a tool declares a specific capability (or any of the provided ones).\n */\nexport function hasCapability(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n capability: ToolCapability | ToolCapability[],\n): boolean {\n if (!toolOrCaps) return false;\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n const toCheck = Array.isArray(capability) ? capability : [capability];\n return toCheck.some((c) => caps.includes(c));\n}\n\n/**\n * Returns the intersection of a tool's capabilities with the dangerous set.\n * Useful for logging and audit trails.\n */\nexport function getDangerousCapabilities(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n): ToolCapability[] {\n if (!toolOrCaps) return [];\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n return caps.filter((c): c is ToolCapability =>\n DANGEROUS_FOR_SUBAGENTS.includes(c as ToolCapability),\n );\n}\n", "import type { MCPServerConfig } from '../types/config.js';\n\n/**\n * Built-in MCP server presets available to all WrongStack users out of the box.\n * These servers must be explicitly enabled in config (disabled by default).\n *\n * To enable: set `mcpServers: { serverName: { enabled: true } }` in your config.\n *\n * Some servers require environment variables or additional config \u2014 see notes below.\n *\n * Transport types:\n * stdio \u2014 spawns a local npm package binary via child_process\n * sse \u2014 HTTP SSE endpoint (client POSTs requests)\n * streamable-http \u2014 session-based HTTP with NDJSON responses\n */\n\n/** Filesystem access: read, write, list, search, tree. Good for exploring projects. */\nexport const filesystemServer = (): MCPServerConfig => ({\n name: 'filesystem',\n description: 'Read, write, and navigate the local filesystem (read-heavy tools)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem', '.'],\n permission: 'confirm',\n});\n\n/** GitHub API: issues, PRs, repos, search, file operations. Requires GITHUB_PERSONAL_ACCESS_TOKEN. */\nexport const githubServer = (): MCPServerConfig => ({\n name: 'github',\n description:\n 'GitHub API \u2014 issues, PRs, repos, search, file ops (requires GITHUB_PERSONAL_ACCESS_TOKEN)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-github'],\n passthroughEnv: ['GITHUB_PERSONAL_ACCESS_TOKEN', 'GITHUB_TOKEN'],\n permission: 'confirm',\n});\n\n/**\n * Context7 \u2014 codebase-aware documentation and Q&A using context from your code.\n * Live documentation for any library, grounded in your actual versions.\n */\nexport const context7Server = (): MCPServerConfig => ({\n name: 'context7',\n description: 'Codebase-aware documentation and Q&A (context7.ai)',\n transport: 'streamable-http',\n url: 'https://mcp.context7.com/mcp',\n permission: 'confirm',\n});\n\n/**\n * Brave Search \u2014 web search via Brave Browser's API.\n * Requires BRAVE_SEARCH_API_KEY. Free tier: 2,000 queries/month.\n * Sign up at https://api.search.brave.com/\n */\nexport const braveSearchServer = (): MCPServerConfig => ({\n name: 'brave-search',\n description: 'Web search (Brave). Requires BRAVE_SEARCH_API_KEY \u2014 free tier 2k queries/month',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-brave-search'],\n passthroughEnv: ['BRAVE_SEARCH_API_KEY'],\n permission: 'confirm',\n});\n\n/**\n * Block (Block, Inc.) \u2014 Postgres database access via SQL.\n * Useful for running queries against a connected database during development.\n */\nexport const blockServer = (): MCPServerConfig => ({\n name: 'block',\n description: 'Postgres database access via SQL (Block MCP server)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-block'],\n permission: 'confirm',\n});\n\n/**\n * EverArt \u2014 AI image generation via various providers.\n * Requires EVERART_API_KEY.\n */\nexport const everArtServer = (): MCPServerConfig => ({\n name: 'everart',\n description: 'AI image generation (EverArt). Requires EVERART_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-everart'],\n passthroughEnv: ['EVERART_API_KEY'],\n permission: 'confirm',\n});\n\n/**\n * Slack \u2014 messaging, channels, search.\n * Requires SLACK_BOT_TOKEN and either SLACK_TEAM_ID or SLACK_USER_TOKEN.\n */\nexport const slackServer = (): MCPServerConfig => ({\n name: 'slack',\n description: 'Slack \u2014 messaging, channels, search. Requires SLACK_BOT_TOKEN + SLACK_TEAM_ID',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-slack'],\n passthroughEnv: ['SLACK_BOT_TOKEN', 'SLACK_TEAM_ID'],\n permission: 'confirm',\n});\n\n/**\n * AWS knowledge base \u2014 EC2, S3, Lambda, IAM, CloudFormation, cost management.\n * Requires AWS access key + secret in environment.\n */\nexport const awsServer = (): MCPServerConfig => ({\n name: 'aws',\n description: 'AWS \u2014 EC2, S3, Lambda, IAM, CloudFormation, costs. Requires AWS credentials',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-aws'],\n passthroughEnv: ['AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AWS_REGION', 'AWS_SESSION_TOKEN'],\n permission: 'confirm',\n});\n\n/**\n * Google Maps \u2014 directions, distance matrix, geocoding, places.\n * Requires GOOGLE_MAPS_API_KEY.\n */\nexport const googleMapsServer = (): MCPServerConfig => ({\n name: 'google-maps',\n description: 'Google Maps \u2014 directions, geocoding, places. Requires GOOGLE_MAPS_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-google-maps'],\n passthroughEnv: ['GOOGLE_MAPS_API_KEY'],\n permission: 'confirm',\n});\n\n/** Sentinel \u2014 security vulnerability scanning (sentinel-labs). */\nexport const sentinelServer = (): MCPServerConfig => ({\n name: 'sentinel',\n description: 'Security vulnerability scanning (Sentinel)',\n transport: 'streamable-http',\n url: 'https://mcp.sentinel.ai',\n permission: 'deny', // security tool \u2014 require explicit confirmation\n});\n\n/**\n * Z.AI Vision MCP \u2014 image understanding fallback for text-only models.\n * Requires Z_AI_API_KEY. Tools are read-only and safe to run automatically.\n */\nexport const zaiVisionServer = (): MCPServerConfig => ({\n name: 'zai-vision',\n description: 'Z.AI Vision MCP \u2014 image analysis and screenshot understanding',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@z_ai/mcp-server@latest'],\n env: { Z_AI_MODE: 'ZAI' },\n passthroughEnv: ['Z_AI_API_KEY'],\n allowedTools: [\n 'image_analysis',\n 'extract_text_from_screenshot',\n 'diagnose_error_screenshot',\n 'understand_technical_diagram',\n 'analyze_data_visualization',\n 'ui_diff_check',\n ],\n permission: 'auto',\n});\n\n/**\n * Playwright \u2014 browser automation: navigate, click, type, screenshot, evaluate JS.\n * Spawns a headless Chromium browser via @modelcontextprotocol/server-playwright.\n * Tools can read and interact with live web pages \u2014 permission defaults to\n * `confirm` because form submission / DOM mutation is possible.\n */\nexport const playwrightServer = (): MCPServerConfig => ({\n name: 'playwright',\n description:\n 'Browser automation \u2014 navigate, screenshot, click, type, evaluate JS (headless Chromium)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-playwright'],\n permission: 'confirm',\n});\n\n/**\n * MiniMax Token Plan MCP \u2014 search + understand_image.\n * This preset exposes only the read-only image understanding tool by default.\n * Requires MINIMAX_API_KEY and uvx on PATH.\n */\nexport const miniMaxVisionServer = (): MCPServerConfig => ({\n name: 'minimax-vision',\n description: 'MiniMax MCP \u2014 image understanding via understand_image',\n transport: 'stdio',\n command: 'uvx',\n args: ['minimax-coding-plan-mcp', '-y'],\n env: {\n MINIMAX_MCP_BASE_PATH: './.wrongstack/minimax-output',\n MINIMAX_API_HOST: 'https://api.minimax.io',\n MINIMAX_API_RESOURCE_MODE: 'url',\n },\n passthroughEnv: ['MINIMAX_API_KEY'],\n allowedTools: ['understand_image'],\n permission: 'auto',\n});\n\n/**\n * SSH Manager \u2014 remote SSH execution, file transfer, tunnels, health checks, and deployment ops.\n * Server credentials are intentionally NOT embedded here. Configure hosts via mcp-ssh-manager's\n * env/TOML config (for example SSH_SERVER_<NAME>_HOST, USER, KEYPATH/PASSWORD) or ssh-agent.\n */\nexport const sshManagerServer = (): MCPServerConfig => ({\n name: 'ssh',\n description:\n 'Remote SSH management \u2014 execute commands, transfer files, tunnels, health checks (mcp-ssh-manager)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', 'mcp-ssh-manager'],\n env: {\n MCP_SSH_COMPACT_JSON: 'true',\n MCP_SSH_DEFAULT_TIMEOUT: '120000',\n },\n permission: 'confirm',\n requestTimeoutMs: 180_000,\n});\n\n/** Everything bundled \u2014 full set of built-in servers. Useful for `wstack mcp add --all`. */\nexport const allServers = (): Record<string, MCPServerConfig> => ({\n filesystem: { ...filesystemServer(), enabled: false },\n github: { ...githubServer(), enabled: false },\n context7: { ...context7Server(), enabled: false },\n 'brave-search': { ...braveSearchServer(), enabled: false },\n block: { ...blockServer(), enabled: false },\n everart: { ...everArtServer(), enabled: false },\n slack: { ...slackServer(), enabled: false },\n aws: { ...awsServer(), enabled: false },\n 'google-maps': { ...googleMapsServer(), enabled: false },\n sentinel: { ...sentinelServer(), enabled: false },\n 'zai-vision': { ...zaiVisionServer(), enabled: false },\n 'minimax-vision': { ...miniMaxVisionServer(), enabled: false },\n playwright: { ...playwrightServer(), enabled: false },\n ssh: { ...sshManagerServer(), enabled: false },\n});\n", "import * as fs from 'node:fs/promises';\nimport { atomicWrite } from './atomic-write.js';\n\nexport type JsonObject = Record<string, unknown>;\nexport type JsonPathSegment = string | number;\nexport type JsonPath = readonly JsonPathSegment[];\n\nexport async function readJsonObjectFile(filePath: string): Promise<JsonObject> {\n try {\n const parsed = JSON.parse(await fs.readFile(filePath, 'utf8')) as unknown;\n return isJsonObject(parsed) ? parsed : {};\n } catch {\n return {};\n }\n}\n\nexport async function jsonObjectFileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function writeJsonObjectFile(filePath: string, value: JsonObject): Promise<void> {\n await atomicWrite(filePath, JSON.stringify(value, null, 2), { mode: 0o600 });\n}\n\nexport async function updateJsonObjectFile(\n filePath: string,\n mutator: (config: JsonObject) => void | JsonObject | Promise<void | JsonObject>,\n): Promise<JsonObject> {\n const config = await readJsonObjectFile(filePath);\n const maybeNext = await mutator(config);\n const next = maybeNext && isJsonObject(maybeNext) ? maybeNext : config;\n await writeJsonObjectFile(filePath, next);\n return next;\n}\n\nexport function getJsonPath(root: unknown, path: JsonPath): unknown {\n let current = root;\n for (const segment of path) {\n if (typeof segment === 'number') {\n if (!Array.isArray(current)) return undefined;\n current = current[segment];\n continue;\n }\n if (!isJsonObject(current)) return undefined;\n current = current[segment];\n }\n return current;\n}\n\nexport function setJsonPath(root: JsonObject, path: JsonPath, value: unknown): JsonObject {\n if (path.length === 0) {\n if (!isJsonObject(value)) throw new Error('Root config value must be an object');\n return value;\n }\n const parent = ensureJsonParent(root, path);\n const leaf = lastPathSegment(path);\n if (typeof leaf === 'number') {\n if (!Array.isArray(parent)) throw new Error(`Cannot set numeric segment ${leaf} on non-array parent`);\n parent[leaf] = value;\n } else {\n if (!isJsonObject(parent)) throw new Error(`Cannot set property ${leaf} on non-object parent`);\n parent[leaf] = value;\n }\n return root;\n}\n\nexport function removeJsonPath(root: JsonObject, path: JsonPath): boolean {\n if (path.length === 0) return false;\n const parent = getJsonPath(root, path.slice(0, -1));\n const leaf = lastPathSegment(path);\n if (typeof leaf === 'number') {\n if (!Array.isArray(parent) || leaf < 0 || leaf >= parent.length) return false;\n parent.splice(leaf, 1);\n return true;\n }\n if (!isJsonObject(parent) || !(leaf in parent)) return false;\n delete parent[leaf];\n return true;\n}\n\nexport async function setJsonPathInFile(filePath: string, path: JsonPath, value: unknown): Promise<JsonObject> {\n return updateJsonObjectFile(filePath, (config) => setJsonPath(config, path, value));\n}\n\nexport async function removeJsonPathInFile(filePath: string, path: JsonPath): Promise<JsonObject> {\n return updateJsonObjectFile(filePath, (config) => {\n removeJsonPath(config, path);\n });\n}\n\nexport function isJsonObject(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction lastPathSegment(path: JsonPath): JsonPathSegment {\n const segment = path[path.length - 1];\n /* v8 ignore next -- defensive: callers guard path.length === 0 before here */\n if (segment === undefined) throw new Error('Invalid empty JSON path');\n return segment;\n}\n\nfunction ensureJsonParent(root: JsonObject, path: JsonPath): JsonObject | unknown[] {\n let current: JsonObject | unknown[] = root;\n for (let i = 0; i < path.length - 1; i += 1) {\n const segment = path[i];\n const nextSegment = path[i + 1];\n /* v8 ignore next -- defensive: sparse-array paths are never produced by callers */\n if (segment === undefined) throw new Error('Invalid empty JSON path segment');\n const nextContainer = typeof nextSegment === 'number' ? [] : {};\n\n if (typeof segment === 'number') {\n if (!Array.isArray(current)) throw new Error(`Cannot traverse numeric segment ${segment} on non-array parent`);\n if (!isJsonObject(current[segment]) && !Array.isArray(current[segment])) current[segment] = nextContainer;\n current = current[segment] as JsonObject | unknown[];\n } else {\n if (!isJsonObject(current)) throw new Error(`Cannot traverse property ${segment} on non-object parent`);\n if (!isJsonObject(current[segment]) && !Array.isArray(current[segment])) current[segment] = nextContainer;\n current = current[segment] as JsonObject | unknown[];\n }\n }\n return current;\n}\n", "import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { FsError } from '../types/errors.js';\n\nexport interface AtomicWriteOptions {\n mode?: number | undefined;\n encoding?: BufferEncoding | undefined;\n}\n\nexport interface FileLockOptions {\n timeoutMs?: number | undefined;\n staleMs?: number | undefined;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array,\n opts: AtomicWriteOptions = {},\n): Promise<void> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString('hex')}.tmp`);\n\n // Write content to tmp first; 'wx' ensures exclusive creation (fails if\n // tmp already exists \u2014 extremely unlikely with 6-byte random suffix).\n try {\n if (typeof content === 'string') {\n await fs.writeFile(tmp, content, { flag: 'wx', encoding: opts.encoding ?? 'utf8' });\n } else {\n await fs.writeFile(tmp, content, { flag: 'wx' });\n }\n try {\n const fh = await fs.open(tmp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync best-effort\n }\n // Now safely read mode from target (if it exists) and apply to tmp before rename.\n // Prefer opts.mode for new files; for existing files preserve their mode.\n let mode: number | undefined;\n try {\n const stat = await fs.stat(targetPath);\n mode = stat.mode & 0o777;\n } catch {\n mode = opts.mode;\n }\n if (mode !== undefined) {\n await fs.chmod(tmp, mode);\n }\n await renameWithRetry(tmp, targetPath);\n // P3 #20 (before-release.md): on Windows, fs.rename (MoveFileExW) does\n // not preserve Unix permission bits \u2014 the chmod above applies to the tmp\n // file, but the rename may reset the destination's mode to the Windows\n // default. Re-apply the mode after rename on win32 so an edited file\n // keeps its executable bit (or any non-default permission). On POSIX,\n // rename preserves metadata so this is a no-op (chmod is idempotent and\n // cheap), but we gate it on win32 to avoid the extra stat+chmod on the\n // common path.\n if (mode !== undefined && process.platform === 'win32') {\n try {\n await fs.chmod(targetPath, mode);\n } catch {\n // Best-effort: a transient EPERM (antivirus lock) should not fail\n // the write \u2014 the content is already on disk.\n }\n }\n } catch (err) {\n try {\n await fs.unlink(tmp);\n } catch {\n // ignore cleanup error\n }\n throw err;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function withFileLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts: FileLockOptions = {},\n): Promise<T> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);\n const timeoutMs = opts.timeoutMs ?? 5_000;\n const staleMs = opts.staleMs ?? 30_000;\n const started = Date.now();\n let handle: fs.FileHandle | undefined;\n\n for (;;) {\n try {\n handle = await fs.open(lockPath, 'wx');\n await handle.writeFile(`${process.pid}:${Date.now()}`);\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n // ENOENT means the directory was deleted (e.g. by concurrent cleanup).\n // Recreate it and retry acquiring the lock.\n if (code === 'ENOENT') {\n await fs.mkdir(dir, { recursive: true });\n continue;\n }\n if (code !== 'EEXIST') throw err;\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.unlink(lockPath);\n continue;\n }\n } catch {\n continue;\n }\n if (Date.now() - started >= timeoutMs) {\n throw new FsError({\n message: `Timed out waiting for file lock: ${targetPath}`,\n code: 'FS_ATOMIC_WRITE_FAILED',\n path: targetPath,\n context: { timeoutMs },\n });\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n try {\n return await fn();\n } finally {\n try {\n await handle?.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(lockPath);\n } catch {\n // ignore\n }\n }\n}\n\n// On Windows, fs.rename over an existing file can fail with EPERM/EBUSY/EACCES\n// when antivirus, file indexers, editor file watchers, or a concurrent writer\n// briefly hold a handle on the destination. These are transient \u2014 retry with a\n// short backoff before giving up. POSIX renames are atomic and won't hit this.\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);\n\nasync function renameWithRetry(from: string, to: string): Promise<void> {\n if (process.platform !== 'win32') {\n await fs.rename(from, to);\n return;\n }\n const delays = [10, 25, 60, 120, 250];\n let lastErr: unknown;\n for (let i = 0; i <= delays.length; i++) {\n try {\n await fs.rename(from, to);\n return;\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException)?.code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {\n throw err;\n }\n await new Promise((resolve) => setTimeout(resolve, delays[i]));\n }\n }\n throw lastErr;\n}\n", "import { expectDefined } from '../utils/expect-defined.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { ToolCapabilities } from '../security/capabilities.js';\n/**\n * `mcp_control` \u2014 LLM-driven MCP server lifecycle management.\n *\n * The model calls this tool to:\n * list \u2014 see all known servers (running or not) without starting any\n * search \u2014 filter the server catalog by name or description keyword\n * enable \u2014 start a server and register its tools\n * disable \u2014 stop a server and unregister its tools\n * restart \u2014 stop then re-start a running server\n *\n * This is the primary mechanism by which the LLM autonomously extends its\n * own capabilities at runtime \u2014 e.g. \"I need GitHub access, let me enable it.\"\n */\nimport { allServers } from '../infrastructure/mcp-servers.js';\nimport { readJsonObjectFile, setJsonPath, updateJsonObjectFile } from '../utils/config-json.js';\nimport type { Config, JSONSchema, MCPServerConfig, Tool } from '../index.js';\nexport interface MCPRegistryHandle {\n start(cfg: MCPServerConfig): Promise<void>;\n stop(name: string): Promise<void>;\n restart(name: string): Promise<void>;\n describe(): {\n name: string;\n state: string;\n toolCount: number;\n enabled: boolean;\n tools?: string[];\n }[];\n list(): { name: string; state: string; toolCount: number; tools?: string[] }[];\n /**\n * Register all cached tools for a server without restarting it.\n * No-op if the server is not connected or tools are already active.\n * Used in token-saving mode to temporarily expose MCP tools.\n */\n activateServer?(name: string): void;\n /**\n * Unregister all tools for a server without disconnecting it.\n * Returns the number of tools that were deactivated.\n * Used in token-saving mode to hide MCP tools after use.\n */\n deactivateServer?(name: string): number;\n /**\n * Check whether a server's tools are currently registered.\n */\n isActivated?(name: string): boolean;\n}\n\nexport interface CreateMcpControlToolOptions {\n /**\n * Read the current config object. The tool never mutates this directly \u2014\n * writes go to the global config file via `configPath`.\n */\n getConfig: () => Config;\n /**\n * Path to ~/.wrongstack/config.json (or equivalent) for atomic config writes.\n */\n configPath: string;\n /**\n * Live MCP registry for runtime start/stop/restart. The tool calls these\n * immediately so the LLM sees the result of its action in the same turn.\n */\n registry: MCPRegistryHandle;\n}\n\nexport function createMcpControlTool(opts: CreateMcpControlToolOptions): Tool {\n const { getConfig, configPath, registry } = opts;\n\n const inputSchema: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'search', 'enable', 'disable', 'restart', 'activate', 'deactivate'],\n description: 'The management action to perform. activate/deactivate toggle tool registration ephemerally without disconnecting.',\n },\n /** Filter for `search`. Matches server name or description case-insensitively. */\n query: {\n type: 'string',\n description: 'Search term for `search` action. Matches server name or description.',\n },\n /** Target server name for `enable`, `disable`, `restart`, `activate`, `deactivate`. */\n server: {\n type: 'string',\n description: 'Server name (e.g. \"github\", \"filesystem\", \"brave-search\").',\n },\n },\n required: ['action'],\n };\n\n return {\n name: 'mcp_control',\n description:\n 'Manage MCP server lifecycle: list available servers, search by name or capability, enable or disable servers at runtime, restart running servers. Use activate/deactivate to ephemerally toggle tool registration without disconnecting \u2014 ideal for token-saving mode where MCP tools are lazy-loaded on demand. NOTE: `enable`/`restart` start a server process, which for the built-in stdio presets runs `npx -y <package>` \u2014 i.e. it fetches and executes an npm package from the network. Treat it as code execution.',\n category: 'mcp',\n permission: 'confirm',\n mutating: true,\n // `enable`/`restart` spawn a server process that, for the stdio presets,\n // fetches and runs an npm package (`npx -y <pkg>`) \u2014 effectively remote\n // code execution. Marking the tool destructive preserves risk metadata for\n // UI/audit surfaces; YOLO itself still auto-approves unless an explicit\n // deny rule blocks the call. Read-only actions (list/search) ride the same\n // tool but are cheap to confirm/trust once when YOLO is off.\n riskTier: 'destructive',\n capabilities: [ToolCapabilities.CONFIG_MUTATE],\n inputSchema,\n async execute(raw) {\n const input = raw as { action: string; query?: string | undefined; server?: string | undefined };\n return mcpControlDispatch(input, { getConfig, configPath, registry });\n },\n };\n}\n\n// \u2500\u2500 Dispatch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function mcpControlDispatch(\n input: { action: string; query?: string | undefined; server?: string | undefined },\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n const { action, query, server } = input;\n\n switch (action) {\n case 'list': return renderList(deps);\n case 'search': return renderSearch(query ?? '', deps);\n case 'enable': return server ? runEnable(server, deps) : '`server` is required for enable.';\n case 'disable': return server ? runDisable(server, deps) : '`server` is required for disable.';\n case 'restart': return server ? runRestart(server, deps) : '`server` is required for restart.';\n case 'activate': return server ? runActivate(server, deps) : '`server` is required for activate.';\n case 'deactivate': return server ? runDeactivate(server, deps) : '`server` is required for deactivate.';\n default:\n return `Unknown action \"${action}\". Use one of: list, search, enable, disable, restart, activate, deactivate.`;\n }\n}\n\n// \u2500\u2500 Actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function renderList(deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle }): Promise<string> {\n const configured = await getConfiguredMcpServers(deps);\n const live = deps.registry.describe();\n\n if (Object.keys(configured).length === 0) {\n return [\n 'No MCP servers configured.',\n ' Use `mcp_control({ action: \"search\" })` to see available presets,',\n ' then `mcp_control({ action: \"enable\", server: \"<name>\" })` to add one.',\n ].join('\\n');\n }\n\n const lines: string[] = [];\n const liveMap = new Map(live.map((s) => [s.name, s]));\n\n for (const [name, cfg] of Object.entries(configured)) {\n const liveInfo = liveMap.get(name);\n const toolCount = liveInfo ? ` (${liveInfo.toolCount} tools)` : '';\n const stateStr = liveInfo ? badge(liveInfo.state) : dim('\u25CB not loaded');\n const enabled = cfg.enabled === false\n ? `${dim('disabled')} `\n : `${green('\u25CF enabled')} `;\n lines.push(` ${bold(name)} ${enabled}${stateStr}${toolCount}`);\n if (cfg.description) lines.push(` ${dim(cfg.description)}`);\n }\n\n lines.push('');\n lines.push(dim(' Use `mcp_control({ action: \"search\", query: \"<keyword>\" })` to find servers.'));\n lines.push(dim(' Use `mcp_control({ action: \"enable\", server: \"<name>\" })` to start a server.'));\n return lines.join('\\n');\n}\n\nasync function renderSearch(\n query: string,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n const configured = await getConfiguredMcpServers(deps);\n const all = allServers();\n const q = query.toLowerCase();\n\n const configuredNames = new Set(Object.keys(configured));\n\n // Match against configured servers first, then remaining presets\n const configuredEntries = Object.entries(configured).filter(\n ([name, cfg]) =>\n name.toLowerCase().includes(q) ||\n (cfg.description ?? '').toLowerCase().includes(q),\n );\n\n const unconfiguredEntries = Object.entries(all)\n .filter(([name]) => !configuredNames.has(name))\n .filter(\n ([name, cfg]) =>\n name.toLowerCase().includes(q) ||\n (cfg.description ?? '').toLowerCase().includes(q),\n );\n\n const lines: string[] = [];\n\n if (configuredEntries.length > 0) {\n lines.push(bold('Configured servers matching \"') + query + '\":');\n for (const [name, cfg] of configuredEntries) {\n lines.push(` ${bold(name)} ${cfg.description ?? cfg.transport}`);\n }\n lines.push('');\n }\n\n if (unconfiguredEntries.length > 0) {\n lines.push(bold('Available presets matching \"') + query + '\":');\n for (const [name, cfg] of unconfiguredEntries) {\n const warn = cfg.permission === 'deny' ? red(' \u26A0 confirm required') : '';\n lines.push(` ${bold(name)} ${cfg.description ?? cfg.transport}${warn}`);\n }\n lines.push('');\n }\n\n if (configuredEntries.length === 0 && unconfiguredEntries.length === 0) {\n return `No servers match \"${query}\". Try a shorter keyword or \\`mcp_control({ action: \"list\" })\\`.`;\n }\n\n const total = configuredEntries.length + unconfiguredEntries.length;\n lines.push(dim(` ${total} server${total !== 1 ? 's' : ''} shown. Run \\`enable\\` on one to activate it.`));\n return lines.join('\\n');\n}\n\nasync function runEnable(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for enable. Example: { action: \"enable\", server: \"github\" }';\n\n const all = allServers();\n const configured = deps.getConfig().mcpServers ?? {};\n\n // Resolve the target config \u2014 it may be a preset not yet in config\n const cfg = configured[name] ?? all[name];\n if (!cfg) {\n const known = Object.keys(all).join(', ');\n return `Unknown server \"${name}\". Available presets: ${known}`;\n }\n\n // Write to config (add or update) using the shared JSON path helper.\n await updateJsonObjectFile(deps.configPath, (full) => {\n const current = isMcpServerRecord(full.mcpServers) ? full.mcpServers : {};\n setJsonPath(full, ['mcpServers', name], { ...current[name], ...cfg, enabled: true });\n });\n\n // Start the server in the registry\n try {\n const live = deps.registry.describe().find((s) => s.name === name);\n if (live && live.state === 'connected') {\n return `${green('\u25CF')} Server \"${name}\" is already running (${live.toolCount} tools registered).`;\n }\n await deps.registry.start({ ...cfg, enabled: true });\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Enabled and started')} \"${name}\"${updated ? ` (${updated.toolCount} tools registered).` : '.'}`;\n } catch (err) {\n return `${red('\u2717 Failed to start')} \"${name}\": ${toErrorMessage(err)}`;\n }\n}\n\nasync function runDisable(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for disable. Example: { action: \"disable\", server: \"github\" }';\n\n const configured = deps.getConfig().mcpServers ?? {};\n if (!configured[name]) {\n return `Server \"${name}\" is not in config. Add it with \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\`.`;\n }\n\n // Write to config using the shared JSON path helper.\n await updateJsonObjectFile(deps.configPath, (full) => {\n const current = isMcpServerRecord(full.mcpServers) ? full.mcpServers : {};\n const existing = expectDefined(current[name]);\n setJsonPath(full, ['mcpServers', name], { ...existing, enabled: false });\n });\n\n // Stop the running server\n try {\n await deps.registry.stop(name);\n return `${yellow('\u25CB Disabled')} \"${name}\". It will not be started on next boot.`;\n } catch {\n return `${yellow('\u25CB Disabled')} \"${name}\" (it was not running). Config updated.`;\n }\n}\n\nasync function runRestart(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for restart. Example: { action: \"restart\", server: \"github\" }';\n\n const configured = deps.getConfig().mcpServers ?? {};\n if (!configured[name]) {\n return `Server \"${name}\" is not configured. Use \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\` first.`;\n }\n\n try {\n await deps.registry.restart(name);\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Restarted')} \"${name}\"${updated ? ` (${updated.toolCount} tools registered).` : '.'}`;\n } catch (err) {\n return `${red('\u2717 Restart failed')} for \"${name}\": ${toErrorMessage(err)}`;\n }\n}\n\n/**\n * Ephemerally activate a server's tools without writing to config or\n * restarting the connection. The server must already be connected (lazy mode).\n * Calls `registry.activateServer()` when available; falls back to a message\n * if the registry doesn't support ephemeral activation.\n */\nasync function runActivate(\n name: string | undefined,\n deps: { registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for activate.';\n if (!deps.registry.activateServer) {\n return `Registry does not support ephemeral activation. Use \\`enable\\` to start \"${name}\" instead.`;\n }\n const live = deps.registry.describe().find((s) => s.name === name);\n if (!live) {\n return `Server \"${name}\" is not registered. Use \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\` first.`;\n }\n if (live.state !== 'connected') {\n return `Server \"${name}\" is not connected (state: ${live.state}). Use \\`enable\\` to start it first.`;\n }\n if (deps.registry.isActivated?.(name)) {\n return `${green('\u25CF')} Server \"${name}\" tools are already active. Use \\`deactivate\\` to hide them.`;\n }\n deps.registry.activateServer(name);\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Activated')} \"${name}\" \u2014 ${updated?.toolCount ?? 0} tool(s) now registered. Use \\`mcp_control({ action: \"deactivate\", server: \"${name}\" })\\` to hide them when done.`;\n}\n\n/**\n * Ephemerally deactivate a server's tools without disconnecting.\n * Calls `registry.deactivateServer()` when available.\n */\nasync function runDeactivate(\n name: string | undefined,\n deps: { registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for deactivate.';\n if (!deps.registry.deactivateServer) {\n return `Registry does not support ephemeral deactivation. Use \\`disable\\` to stop \"${name}\" instead.`;\n }\n if (!deps.registry.isActivated?.(name)) {\n return `Server \"${name}\" tools are not currently active.`;\n }\n const count = deps.registry.deactivateServer(name);\n return `${yellow('\u25CB Deactivated')} \"${name}\" \u2014 ${count} tool(s) unregistered. Server stays connected.`;\n}\n\n// \u2500\u2500 Config helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function getConfiguredMcpServers(deps: { getConfig: () => Config; configPath: string }): Promise<Record<string, MCPServerConfig>> {\n const diskConfig = await readJsonObjectFile(deps.configPath);\n if (isMcpServerRecord(diskConfig.mcpServers)) return diskConfig.mcpServers;\n return deps.getConfig().mcpServers ?? {};\n}\n\nfunction isMcpServerRecord(value: unknown): value is Record<string, MCPServerConfig> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\n// \u2500\u2500 Colour helpers (no dep on core color \u2014 inline) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bold(s: string) { return `\\x1b[1m${s}\\x1b[0m`; }\nfunction dim(s: string) { return `\\x1b[2m${s}\\x1b[0m`; }\nfunction green(s: string) { return `\\x1b[32m${s}\\x1b[0m`; }\nfunction yellow(s: string){ return `\\x1b[33m${s}\\x1b[0m`; }\nfunction red(s: string) { return `\\x1b[31m${s}\\x1b[0m`; }\n\nfunction badge(state: string): string {\n switch (state) {\n case 'connected': return green('\u25CF connected');\n case 'connecting': return `\\x1b[36m\u25D0 connecting\\x1b[0m`;\n case 'reconnecting': return `\\x1b[36m\u25D1 reconnecting\\x1b[0m`;\n case 'disconnected': return dim('\u25CB disconnected');\n case 'failed': return red('\u2717 failed');\n default: return dim(state);\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["fs", "stat", "path", "path"]
|
|
3
|
+
"sources": ["../../src/utils/expect-defined.ts", "../../src/utils/error.ts", "../../src/security/capabilities.ts", "../../src/infrastructure/mcp-servers.ts", "../../src/utils/config-json.ts", "../../src/utils/atomic-write.ts", "../../src/utils/string.ts", "../../src/types/errors.ts", "../../src/tools/mcp-control.ts", "../../src/execution/council-personas.ts", "../../src/execution/council-profiles.ts", "../../src/utils/instruction-file.ts", "../../src/execution/council-prompts.ts", "../../src/execution/council-resolution.ts", "../../src/execution/council-orchestrator.ts", "../../src/tools/council-tool.ts", "../../src/types/blocks.ts", "../../src/types/provider.ts", "../../src/core/fallback-model.ts", "../../src/execution/one-shot-llm.ts", "../../src/tools/one-shot-llm-tool.ts"],
|
|
4
|
+
"sourcesContent": ["/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n", "/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n", "/**\n * Well-known tool capabilities used for authorization decisions.\n *\n * These are the preferred values for `Tool.capabilities`.\n * New capabilities should be added here with clear documentation.\n *\n * Philosophy (2026-06+):\n * - Prefer capabilities over exact tool name matching.\n * - Subagent guards and future policies should primarily key off capabilities.\n * - Name-based denylists are legacy and will be phased down.\n */\nexport const ToolCapabilities = {\n /** Can execute arbitrary commands in the user's shell (the `bash` tool). */\n SHELL_ARBITRARY: 'shell.arbitrary',\n\n /** Can execute a restricted set of commands (the `exec` tool). */\n SHELL_RESTRICTED: 'shell.restricted',\n\n /** Can run a restricted project formatter/linter-style command. */\n SHELL_EXEC: 'shell.exec',\n\n /** Can read files inside the project (and possibly outside via symlinks if not guarded). */\n FS_READ: 'fs.read',\n\n /** Can write / modify / delete files inside the project. */\n FS_WRITE: 'fs.write',\n\n /** Can write files outside the current project root (very high risk). */\n FS_WRITE_OUTSIDE_PROJECT: 'fs.write.outside-project',\n\n /** Can perform outbound network requests. */\n NET_OUTBOUND: 'net.outbound',\n\n /** Can mutate in-memory session todos only. */\n SESSION_TODO: 'session.todo',\n\n /** Can mutate in-memory session mode only. */\n SESSION_MODE: 'session.mode',\n\n /** Can inspect registered tool metadata. */\n TOOL_META: 'tool.meta',\n\n /** Can invoke arbitrary registered tools through a meta-tool. */\n TOOL_MUTATE_ANY: 'tool.mutate.any',\n\n /** Can read persistent memory. */\n MEMORY_READ: 'memory.read',\n\n /** Can write persistent memory. */\n MEMORY_WRITE: 'memory.write',\n\n /** Can delete persistent memory. */\n MEMORY_DELETE: 'memory.delete',\n\n /** Proxies tools from external MCP servers (unknown capability). */\n MCP_PROXY: 'mcp.proxy',\n\n /** Can spawn or manage subagents / multi-agent tasks. */\n SUBAGENT_SPAWN: 'subagent.spawn',\n\n /** Can inspect fleet/subagent coordination state without mutating it. */\n COORDINATION_FLEET_READ: 'coordination.fleet.read',\n\n /** Can publish attributed, schema-checked events onto the fleet bus. */\n COORDINATION_FLEET_EMIT: 'coordination.fleet.emit',\n\n /** Can submit a task-local structured result to the parent Director. */\n COORDINATION_RESULT_SUBMIT: 'coordination.result.submit',\n\n /** Can read or write inter-agent mailbox messages. */\n COORDINATION_MAIL: 'coordination.mail',\n\n /** Can schedule, inspect, or cancel in-session cron jobs. */\n COORDINATION_CRON: 'coordination.cron',\n\n /** Can mutate global or session configuration / trust state. */\n CONFIG_MUTATE: 'config.mutate',\n\n /** Can install packages or run package managers with side effects. */\n PACKAGE_INSTALL: 'package.install',\n} as const;\n\nexport type ToolCapability = (typeof ToolCapabilities)[keyof typeof ToolCapabilities];\n\n/**\n * Set of capabilities that are considered dangerous for subagents by default.\n * Subagents should not receive these capabilities unless the leader explicitly\n * allows the specific tool at spawn time.\n */\nexport const DANGEROUS_FOR_SUBAGENTS: readonly ToolCapability[] = [\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ToolCapabilities.SHELL_EXEC,\n ToolCapabilities.FS_WRITE,\n ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,\n ToolCapabilities.TOOL_MUTATE_ANY,\n ToolCapabilities.MEMORY_WRITE,\n ToolCapabilities.MEMORY_DELETE,\n ToolCapabilities.MCP_PROXY,\n ToolCapabilities.SUBAGENT_SPAWN,\n ToolCapabilities.CONFIG_MUTATE,\n ToolCapabilities.PACKAGE_INSTALL,\n];\n\n/**\n * Wide capability allowlist for subagents that the user has authorized to act\n * with full developer power (the CLI fleet host applies this to any subagent\n * that isn't given an explicit, narrower grant). It covers everything needed to\n * do real work end-to-end \u2014 read, write/edit inside the project, outbound\n * network, all shell/build/install capabilities, session todos, tool metadata, and read-only\n * memory lookup \u2014 so a delegated coding or build agent runs the same toolchain\n * the leader would, without per-tool confirmation it cannot answer.\n *\n * Deliberately EXCLUDED (require an explicit per-spawn `allowedCapabilities`\n * grant, because they escape the task's blast radius rather than perform it):\n * - `fs.write.outside-project` \u2014 writing outside the repo (e.g. ~/.ssh).\n * - `tool.mutate.any` \u2014 arbitrary meta-tool dispatch.\n * - `memory.write` / `memory.delete` \u2014 persistent memory mutation.\n * - `mcp.proxy` \u2014 third-party MCP tools (also hard-blocked by name).\n * - `subagent.spawn` \u2014 recursive delegation (the baseline prompt forbids it).\n * - `config.mutate` \u2014 rewriting trust/config is privilege escalation, not work.\n */\nexport const WIDE_SUBAGENT_CAPABILITIES: readonly ToolCapability[] = [\n ToolCapabilities.FS_READ,\n ToolCapabilities.FS_WRITE,\n ToolCapabilities.NET_OUTBOUND,\n ToolCapabilities.SESSION_TODO,\n ToolCapabilities.TOOL_META,\n ToolCapabilities.MEMORY_READ,\n ToolCapabilities.SHELL_ARBITRARY,\n ToolCapabilities.SHELL_RESTRICTED,\n ToolCapabilities.SHELL_EXEC,\n ToolCapabilities.PACKAGE_INSTALL,\n // Read-only fleet visibility (fleet_status) \u2014 peer awareness has no blast\n // radius and every fleet worker should coordinate around its peers.\n ToolCapabilities.COORDINATION_FLEET_READ,\n ToolCapabilities.COORDINATION_RESULT_SUBMIT,\n];\n\n/**\n * Check if a tool (or its capabilities array) includes any dangerous capability\n * for subagent execution.\n */\nexport function hasDangerousCapabilityForSubagents(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n): boolean {\n if (!toolOrCaps) return false;\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n return caps.some((c) => DANGEROUS_FOR_SUBAGENTS.includes(c as ToolCapability));\n}\n\n/**\n * Check if a tool declares a specific capability (or any of the provided ones).\n */\nexport function hasCapability(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n capability: ToolCapability | ToolCapability[],\n): boolean {\n if (!toolOrCaps) return false;\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n const toCheck = Array.isArray(capability) ? capability : [capability];\n return toCheck.some((c) => caps.includes(c));\n}\n\n/**\n * Returns the intersection of a tool's capabilities with the dangerous set.\n * Useful for logging and audit trails.\n */\nexport function getDangerousCapabilities(\n toolOrCaps: { capabilities?: readonly string[] | undefined } | readonly string[] | undefined,\n): ToolCapability[] {\n if (!toolOrCaps) return [];\n const input = toolOrCaps as never as { capabilities?: readonly string[] | undefined };\n const caps: readonly string[] = Array.isArray(toolOrCaps) ? toolOrCaps : (input.capabilities ?? []);\n return caps.filter((c): c is ToolCapability =>\n DANGEROUS_FOR_SUBAGENTS.includes(c as ToolCapability),\n );\n}\n", "import type { MCPServerConfig } from '../types/config.js';\n\n/**\n * Built-in MCP server presets available to all WrongStack users out of the box.\n * These servers must be explicitly enabled in config (disabled by default).\n *\n * To enable: set `mcpServers: { serverName: { enabled: true } }` in your config.\n *\n * Some servers require environment variables or additional config \u2014 see notes below.\n *\n * Transport types:\n * stdio \u2014 spawns a local npm package binary via child_process\n * sse \u2014 HTTP SSE endpoint (client POSTs requests)\n * streamable-http \u2014 session-based HTTP with NDJSON responses\n */\n\n/** Filesystem access: read, write, list, search, tree. Good for exploring projects. */\nexport const filesystemServer = (): MCPServerConfig => ({\n name: 'filesystem',\n description: 'Read, write, and navigate the local filesystem (read-heavy tools)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem', '.'],\n permission: 'confirm',\n});\n\n/** GitHub API: issues, PRs, repos, search, file operations. Requires GITHUB_PERSONAL_ACCESS_TOKEN. */\nexport const githubServer = (): MCPServerConfig => ({\n name: 'github',\n description:\n 'GitHub API \u2014 issues, PRs, repos, search, file ops (requires GITHUB_PERSONAL_ACCESS_TOKEN)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-github'],\n passthroughEnv: ['GITHUB_PERSONAL_ACCESS_TOKEN', 'GITHUB_TOKEN'],\n permission: 'confirm',\n});\n\n/**\n * Context7 \u2014 codebase-aware documentation and Q&A using context from your code.\n * Live documentation for any library, grounded in your actual versions.\n */\nexport const context7Server = (): MCPServerConfig => ({\n name: 'context7',\n description: 'Codebase-aware documentation and Q&A (context7.ai)',\n transport: 'streamable-http',\n url: 'https://mcp.context7.com/mcp',\n permission: 'confirm',\n});\n\n/**\n * Brave Search \u2014 web search via Brave Browser's API.\n * Requires BRAVE_SEARCH_API_KEY. Free tier: 2,000 queries/month.\n * Sign up at https://api.search.brave.com/\n */\nexport const braveSearchServer = (): MCPServerConfig => ({\n name: 'brave-search',\n description: 'Web search (Brave). Requires BRAVE_SEARCH_API_KEY \u2014 free tier 2k queries/month',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-brave-search'],\n passthroughEnv: ['BRAVE_SEARCH_API_KEY'],\n permission: 'confirm',\n});\n\n/**\n * Block (Block, Inc.) \u2014 Postgres database access via SQL.\n * Useful for running queries against a connected database during development.\n */\nexport const blockServer = (): MCPServerConfig => ({\n name: 'block',\n description: 'Postgres database access via SQL (Block MCP server)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-block'],\n permission: 'confirm',\n});\n\n/**\n * EverArt \u2014 AI image generation via various providers.\n * Requires EVERART_API_KEY.\n */\nexport const everArtServer = (): MCPServerConfig => ({\n name: 'everart',\n description: 'AI image generation (EverArt). Requires EVERART_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-everart'],\n passthroughEnv: ['EVERART_API_KEY'],\n permission: 'confirm',\n});\n\n/**\n * Slack \u2014 messaging, channels, search.\n * Requires SLACK_BOT_TOKEN and either SLACK_TEAM_ID or SLACK_USER_TOKEN.\n */\nexport const slackServer = (): MCPServerConfig => ({\n name: 'slack',\n description: 'Slack \u2014 messaging, channels, search. Requires SLACK_BOT_TOKEN + SLACK_TEAM_ID',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-slack'],\n passthroughEnv: ['SLACK_BOT_TOKEN', 'SLACK_TEAM_ID'],\n permission: 'confirm',\n});\n\n/**\n * AWS knowledge base \u2014 EC2, S3, Lambda, IAM, CloudFormation, cost management.\n * Requires AWS access key + secret in environment.\n */\nexport const awsServer = (): MCPServerConfig => ({\n name: 'aws',\n description: 'AWS \u2014 EC2, S3, Lambda, IAM, CloudFormation, costs. Requires AWS credentials',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-aws'],\n passthroughEnv: ['AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AWS_REGION', 'AWS_SESSION_TOKEN'],\n permission: 'confirm',\n});\n\n/**\n * Google Maps \u2014 directions, distance matrix, geocoding, places.\n * Requires GOOGLE_MAPS_API_KEY.\n */\nexport const googleMapsServer = (): MCPServerConfig => ({\n name: 'google-maps',\n description: 'Google Maps \u2014 directions, geocoding, places. Requires GOOGLE_MAPS_API_KEY',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-google-maps'],\n passthroughEnv: ['GOOGLE_MAPS_API_KEY'],\n permission: 'confirm',\n});\n\n/** Sentinel \u2014 security vulnerability scanning (sentinel-labs). */\nexport const sentinelServer = (): MCPServerConfig => ({\n name: 'sentinel',\n description: 'Security vulnerability scanning (Sentinel)',\n transport: 'streamable-http',\n url: 'https://mcp.sentinel.ai',\n permission: 'deny', // security tool \u2014 require explicit confirmation\n});\n\n/**\n * Z.AI Vision MCP \u2014 image understanding fallback for text-only models.\n * Requires Z_AI_API_KEY. Tools are read-only and safe to run automatically.\n */\nexport const zaiVisionServer = (): MCPServerConfig => ({\n name: 'zai-vision',\n description: 'Z.AI Vision MCP \u2014 image analysis and screenshot understanding',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@z_ai/mcp-server@latest'],\n env: { Z_AI_MODE: 'ZAI' },\n passthroughEnv: ['Z_AI_API_KEY'],\n allowedTools: [\n 'image_analysis',\n 'extract_text_from_screenshot',\n 'diagnose_error_screenshot',\n 'understand_technical_diagram',\n 'analyze_data_visualization',\n 'ui_diff_check',\n ],\n permission: 'auto',\n});\n\n/**\n * Playwright \u2014 browser automation: navigate, click, type, screenshot, evaluate JS.\n * Spawns a headless Chromium browser via @modelcontextprotocol/server-playwright.\n * Tools can read and interact with live web pages \u2014 permission defaults to\n * `confirm` because form submission / DOM mutation is possible.\n */\nexport const playwrightServer = (): MCPServerConfig => ({\n name: 'playwright',\n description:\n 'Browser automation \u2014 navigate, screenshot, click, type, evaluate JS (headless Chromium)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-playwright'],\n permission: 'confirm',\n});\n\n/**\n * MiniMax Token Plan MCP \u2014 search + understand_image.\n * This preset exposes only the read-only image understanding tool by default.\n * Requires MINIMAX_API_KEY and uvx on PATH.\n */\nexport const miniMaxVisionServer = (): MCPServerConfig => ({\n name: 'minimax-vision',\n description: 'MiniMax MCP \u2014 image understanding via understand_image',\n transport: 'stdio',\n command: 'uvx',\n args: ['minimax-coding-plan-mcp', '-y'],\n env: {\n MINIMAX_MCP_BASE_PATH: './.wrongstack/minimax-output',\n MINIMAX_API_HOST: 'https://api.minimax.io',\n MINIMAX_API_RESOURCE_MODE: 'url',\n },\n passthroughEnv: ['MINIMAX_API_KEY'],\n allowedTools: ['understand_image'],\n permission: 'auto',\n});\n\n/**\n * SSH Manager \u2014 remote SSH execution, file transfer, tunnels, health checks, and deployment ops.\n * Server credentials are intentionally NOT embedded here. Configure hosts via mcp-ssh-manager's\n * env/TOML config (for example SSH_SERVER_<NAME>_HOST, USER, KEYPATH/PASSWORD) or ssh-agent.\n */\nexport const sshManagerServer = (): MCPServerConfig => ({\n name: 'ssh',\n description:\n 'Remote SSH management \u2014 execute commands, transfer files, tunnels, health checks (mcp-ssh-manager)',\n transport: 'stdio',\n command: 'npx',\n args: ['-y', 'mcp-ssh-manager'],\n env: {\n MCP_SSH_COMPACT_JSON: 'true',\n MCP_SSH_DEFAULT_TIMEOUT: '120000',\n },\n permission: 'confirm',\n requestTimeoutMs: 180_000,\n});\n\n/** Everything bundled \u2014 full set of built-in servers. Useful for `wstack mcp add --all`. */\nexport const allServers = (): Record<string, MCPServerConfig> => ({\n filesystem: { ...filesystemServer(), enabled: false },\n github: { ...githubServer(), enabled: false },\n context7: { ...context7Server(), enabled: false },\n 'brave-search': { ...braveSearchServer(), enabled: false },\n block: { ...blockServer(), enabled: false },\n everart: { ...everArtServer(), enabled: false },\n slack: { ...slackServer(), enabled: false },\n aws: { ...awsServer(), enabled: false },\n 'google-maps': { ...googleMapsServer(), enabled: false },\n sentinel: { ...sentinelServer(), enabled: false },\n 'zai-vision': { ...zaiVisionServer(), enabled: false },\n 'minimax-vision': { ...miniMaxVisionServer(), enabled: false },\n playwright: { ...playwrightServer(), enabled: false },\n ssh: { ...sshManagerServer(), enabled: false },\n});\n", "import * as fs from 'node:fs/promises';\nimport { atomicWrite } from './atomic-write.js';\n\nexport type JsonObject = Record<string, unknown>;\nexport type JsonPathSegment = string | number;\nexport type JsonPath = readonly JsonPathSegment[];\n\nexport async function readJsonObjectFile(filePath: string): Promise<JsonObject> {\n try {\n const parsed = JSON.parse(await fs.readFile(filePath, 'utf8')) as unknown;\n return isJsonObject(parsed) ? parsed : {};\n } catch {\n return {};\n }\n}\n\nexport async function jsonObjectFileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function writeJsonObjectFile(filePath: string, value: JsonObject): Promise<void> {\n await atomicWrite(filePath, JSON.stringify(value, null, 2), { mode: 0o600 });\n}\n\nexport async function updateJsonObjectFile(\n filePath: string,\n mutator: (config: JsonObject) => void | JsonObject | Promise<void | JsonObject>,\n): Promise<JsonObject> {\n const config = await readJsonObjectFile(filePath);\n const maybeNext = await mutator(config);\n const next = maybeNext && isJsonObject(maybeNext) ? maybeNext : config;\n await writeJsonObjectFile(filePath, next);\n return next;\n}\n\nexport function getJsonPath(root: unknown, path: JsonPath): unknown {\n let current = root;\n for (const segment of path) {\n if (typeof segment === 'number') {\n if (!Array.isArray(current)) return undefined;\n current = current[segment];\n continue;\n }\n if (!isJsonObject(current)) return undefined;\n current = current[segment];\n }\n return current;\n}\n\nexport function setJsonPath(root: JsonObject, path: JsonPath, value: unknown): JsonObject {\n if (path.length === 0) {\n if (!isJsonObject(value)) throw new Error('Root config value must be an object');\n return value;\n }\n const parent = ensureJsonParent(root, path);\n const leaf = lastPathSegment(path);\n if (typeof leaf === 'number') {\n if (!Array.isArray(parent)) throw new Error(`Cannot set numeric segment ${leaf} on non-array parent`);\n parent[leaf] = value;\n } else {\n if (!isJsonObject(parent)) throw new Error(`Cannot set property ${leaf} on non-object parent`);\n parent[leaf] = value;\n }\n return root;\n}\n\nexport function removeJsonPath(root: JsonObject, path: JsonPath): boolean {\n if (path.length === 0) return false;\n const parent = getJsonPath(root, path.slice(0, -1));\n const leaf = lastPathSegment(path);\n if (typeof leaf === 'number') {\n if (!Array.isArray(parent) || leaf < 0 || leaf >= parent.length) return false;\n parent.splice(leaf, 1);\n return true;\n }\n if (!isJsonObject(parent) || !(leaf in parent)) return false;\n delete parent[leaf];\n return true;\n}\n\nexport async function setJsonPathInFile(filePath: string, path: JsonPath, value: unknown): Promise<JsonObject> {\n return updateJsonObjectFile(filePath, (config) => setJsonPath(config, path, value));\n}\n\nexport async function removeJsonPathInFile(filePath: string, path: JsonPath): Promise<JsonObject> {\n return updateJsonObjectFile(filePath, (config) => {\n removeJsonPath(config, path);\n });\n}\n\nexport function isJsonObject(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction lastPathSegment(path: JsonPath): JsonPathSegment {\n const segment = path[path.length - 1];\n /* v8 ignore next -- defensive: callers guard path.length === 0 before here */\n if (segment === undefined) throw new Error('Invalid empty JSON path');\n return segment;\n}\n\nfunction ensureJsonParent(root: JsonObject, path: JsonPath): JsonObject | unknown[] {\n let current: JsonObject | unknown[] = root;\n for (let i = 0; i < path.length - 1; i += 1) {\n const segment = path[i];\n const nextSegment = path[i + 1];\n /* v8 ignore next -- defensive: sparse-array paths are never produced by callers */\n if (segment === undefined) throw new Error('Invalid empty JSON path segment');\n const nextContainer = typeof nextSegment === 'number' ? [] : {};\n\n if (typeof segment === 'number') {\n if (!Array.isArray(current)) throw new Error(`Cannot traverse numeric segment ${segment} on non-array parent`);\n if (!isJsonObject(current[segment]) && !Array.isArray(current[segment])) current[segment] = nextContainer;\n current = current[segment] as JsonObject | unknown[];\n } else {\n if (!isJsonObject(current)) throw new Error(`Cannot traverse property ${segment} on non-object parent`);\n if (!isJsonObject(current[segment]) && !Array.isArray(current[segment])) current[segment] = nextContainer;\n current = current[segment] as JsonObject | unknown[];\n }\n }\n return current;\n}\n", "import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport { watch as watchDir } from 'node:fs';\nimport type { FSWatcher } from 'node:fs';\nimport * as path from 'node:path';\nimport { FsError } from '../types/errors.js';\n\nexport interface AtomicWriteOptions {\n mode?: number | undefined;\n encoding?: BufferEncoding | undefined;\n}\n\nexport interface FileLockOptions {\n timeoutMs?: number | undefined;\n staleMs?: number | undefined;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array,\n opts: AtomicWriteOptions = {},\n): Promise<void> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString('hex')}.tmp`);\n\n // Write content to tmp first; 'wx' ensures exclusive creation (fails if\n // tmp already exists \u2014 extremely unlikely with 6-byte random suffix).\n try {\n if (typeof content === 'string') {\n await fs.writeFile(tmp, content, { flag: 'wx', encoding: opts.encoding ?? 'utf8' });\n } else {\n await fs.writeFile(tmp, content, { flag: 'wx' });\n }\n try {\n const fh = await fs.open(tmp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync best-effort\n }\n // Now safely read mode from target (if it exists) and apply to tmp before rename.\n // Prefer opts.mode for new files; for existing files preserve their mode.\n let mode: number | undefined;\n try {\n const stat = await fs.stat(targetPath);\n mode = stat.mode & 0o777;\n } catch {\n mode = opts.mode;\n }\n if (mode !== undefined) {\n await fs.chmod(tmp, mode);\n }\n await renameWithRetry(tmp, targetPath);\n // P3 #20 (before-release.md): on Windows, fs.rename (MoveFileExW) does\n // not preserve Unix permission bits \u2014 the chmod above applies to the tmp\n // file, but the rename may reset the destination's mode to the Windows\n // default. Re-apply the mode after rename on win32 so an edited file\n // keeps its executable bit (or any non-default permission). On POSIX,\n // rename preserves metadata so this is a no-op (chmod is idempotent and\n // cheap), but we gate it on win32 to avoid the extra stat+chmod on the\n // common path.\n if (mode !== undefined && process.platform === 'win32') {\n try {\n await fs.chmod(targetPath, mode);\n } catch {\n // Best-effort: a transient EPERM (antivirus lock) should not fail\n // the write \u2014 the content is already on disk.\n }\n }\n } catch (err) {\n try {\n await fs.unlink(tmp);\n } catch {\n // ignore cleanup error\n }\n throw err;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function withFileLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts: FileLockOptions = {},\n): Promise<T> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);\n const timeoutMs = opts.timeoutMs ?? 5_000;\n const staleMs = opts.staleMs ?? 30_000;\n const started = Date.now();\n let handle: fs.FileHandle | undefined;\n\n for (;;) {\n try {\n handle = await fs.open(lockPath, 'wx');\n await handle.writeFile(`${process.pid}:${Date.now()}`);\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n // ENOENT means the directory was deleted (e.g. by concurrent cleanup).\n // Recreate it and retry acquiring the lock.\n if (code === 'ENOENT') {\n await fs.mkdir(dir, { recursive: true });\n continue;\n }\n if (code !== 'EEXIST' && code !== 'EPERM') throw err;\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.unlink(lockPath);\n continue;\n }\n } catch {\n continue;\n }\n const elapsed = Date.now() - started;\n if (elapsed >= timeoutMs) {\n throw new FsError({\n message: `Timed out waiting for file lock: ${targetPath}`,\n code: 'FS_ATOMIC_WRITE_FAILED',\n path: targetPath,\n context: { timeoutMs },\n });\n }\n // Wait for the lock to be released, using a filesystem watcher for\n // nearly-instant wake-up instead of polling. The watcher is best-effort:\n // a safety timeout fires at most every 100ms so we don't busy-wait.\n await waitForLockRelease(lockPath, timeoutMs - elapsed);\n }\n }\n\n try {\n return await fn();\n } finally {\n try {\n await handle?.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(lockPath);\n } catch {\n // ignore\n }\n }\n}\n\n/**\n * Watch a lock file's parent directory for the file being removed (unlinked),\n * which signals that the lock holder has released it. A safety timeout caps\n * the wait so the overall `withFileLock` timeout is always respected.\n *\n * Uses a bounded safety interval (up to 100ms) so even if `fs.watch` is\n * unavailable or misses the event, we never busy-wait at 25ms fixed polling.\n */\nasync function waitForLockRelease(lockPath: string, remainingMs: number): Promise<void> {\n const parentDir = path.dirname(lockPath);\n const lockName = path.basename(lockPath);\n const intervalMs = Math.min(remainingMs, 100);\n\n return new Promise<void>((resolve) => {\n let settled = false;\n let watcher: FSWatcher | null = null;\n\n // Safety timer \u2014 always fires, even if fs.watch is unavailable.\n const timer = setTimeout(() => {\n settled = true;\n watcher?.close();\n resolve();\n }, intervalMs);\n\n try {\n watcher = watchDir(parentDir, (eventType, filename) => {\n if (settled) return;\n // 'rename' fires on unlink on most platforms; 'change' is a\n // conservative fallback for environments that only emit 'change'.\n if (filename === lockName && (eventType === 'rename' || eventType === 'change')) {\n settled = true;\n clearTimeout(timer);\n watcher?.close();\n resolve();\n }\n });\n } catch {\n // fs.watch not supported (e.g. some container environments, network\n // filesystems). Clear the safety timer and fall back to a single\n // short delay \u2014 the caller's loop will retry on the next iteration.\n clearTimeout(timer);\n if (!settled) {\n settled = true;\n setTimeout(resolve, Math.min(remainingMs, 25));\n }\n return;\n }\n\n // Re-check lock existence after setting up the watch to close the race\n // where the lock was released between our last EEXIST check and now.\n fs.access(lockPath).then(\n () => {\n // Lock still exists \u2014 the watch (or safety timer) will resolve.\n },\n () => {\n // Lock was already released \u2014 respond immediately.\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n watcher?.close();\n resolve();\n }\n },\n );\n });\n}\n\n// On Windows, fs.rename over an existing file can fail with EPERM/EBUSY/EACCES\n// when antivirus, file indexers, editor file watchers, or a concurrent writer\n// briefly hold a handle on the destination. These are transient \u2014 retry with a\n// short backoff before giving up. POSIX renames are atomic and won't hit this.\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);\n\nasync function renameWithRetry(from: string, to: string): Promise<void> {\n if (process.platform !== 'win32') {\n await fs.rename(from, to);\n return;\n }\n const delays = [10, 25, 60, 120, 250];\n let lastErr: unknown;\n for (let i = 0; i <= delays.length; i++) {\n try {\n await fs.rename(from, to);\n return;\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException)?.code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {\n throw err;\n }\n await new Promise((resolve) => setTimeout(resolve, delays[i]));\n }\n }\n throw lastErr;\n}\n", "/**\n * String utilities shared across the WrongStack codebase.\n */\n\n/**\n * Truncate a string to at most `max` characters, appending an ellipsis if it\n * was longer. Returns the original string unchanged when it fits.\n */\nexport function truncate(s: string, max: number): string {\n return s.length <= max ? s : `${s.slice(0, max - 1)}\u2026`;\n}\n", "import { toErrorMessage } from '../utils/index.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// \u2500\u2500 Error codes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n PARSE_FAILED: 'PARSE_FAILED',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` \u2014 no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// \u2500\u2500 Base error class \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// \u2500\u2500 Specific error classes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Tool execution errors \u2014 thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors \u2014 thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors \u2014 spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n/**\n * HTTP fetch error \u2014 thrown when a network request returns a non-OK status.\n * Carries the response status so {@link classifyToolError} can branch on it\n * (429 \u2192 transient, 404 \u2192 not_found, 401 \u2192 permission) without duck-typing\n * the error via `'response' in err`.\n *\n * P3 #18 (before-release.md): the previous `'response' in err` check caught\n * any Error with a `response` property, including custom errors, proxy\n * objects, or mocked errors in tests. `instanceof FetchError` is reliable.\n *\n * Tools and providers that make HTTP requests and need the executor to\n * classify their failures should throw `new FetchError({ status, message })`\n * instead of a bare `Error` with an ad-hoc `response` field.\n */\nexport class FetchError extends WrongStackError {\n readonly status: number;\n\n constructor(opts: {\n message: string;\n status: number;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: opts.status === 429 || opts.status >= 500,\n context: { status: opts.status, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FetchError';\n this.status = opts.status;\n }\n}\n\n/**\n * Tool input validation error \u2014 thrown when a tool's input fails a validation\n * check that the JSON Schema cannot express (e.g. `old_string === new_string`\n * in edit, or a cross-field invariant). Use this instead of a bare\n * `throw new Error('...validation...')` so {@link classifyToolError} can\n * match on `instanceof` rather than a locale-dependent message substring.\n *\n * P2 #6 (before-release.md): the previous `err.message.includes('validation')`\n * check misclassified any error whose message happened to contain \"validation\"\n * (e.g. a third-party \"input validation timeout\") as a VALIDATION error.\n *\n * Named `ToolValidationError` (not `ValidationError`) to avoid colliding with\n * the existing `ValidationError` interface exported by json-schema-validate.ts\n * (a validation-result shape, not an Error subclass).\n */\nexport class ToolValidationError extends WrongStackError {\n constructor(opts: {\n message: string;\n /** Field path or tool name that failed validation, for diagnostics. */\n field?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { field: opts.field, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolValidationError';\n }\n}\n\n/**\n * Response / payload parse error \u2014 thrown when an upstream HTTP response,\n * file, or data structure is well-formed at the transport layer (HTTP 200,\n * valid JSON) but is missing required fields or has an unexpected shape.\n *\n * Distinct from `ConfigError(CONFIG_PARSE_FAILED)` (which is specifically\n * for config-file parsing) and `FetchError` (which covers HTTP non-OK\n * responses). `ParseError` fills the gap: the request succeeded but the\n * response body couldn't be interpreted.\n *\n * Common sites: OAuth token responses missing `access_token`, device-code\n * responses missing `device_code`, registry responses with unexpected\n * schemas.\n */\nexport class ParseError extends WrongStackError {\n readonly source?: string | undefined;\n\n constructor(opts: {\n message: string;\n /**\n * What was being parsed \u2014 e.g. `'oauth-token-response'`,\n * `'device-code-response'`. Lets consumers distinguish parse failures\n * from different upstream APIs without parsing the message.\n */\n source?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.PARSE_FAILED,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { source: opts.source, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ParseError';\n this.source = opts.source;\n }\n}\n\n// \u2500\u2500 Type guards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isToolValidationError(err: unknown): err is ToolValidationError {\n return err instanceof ToolValidationError;\n}\n\nexport function isFetchError(err: unknown): err is FetchError {\n return err instanceof FetchError;\n}\n\nexport function isParseError(err: unknown): err is ParseError {\n return err instanceof ParseError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n", "import { expectDefined } from '../utils/expect-defined.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { ToolCapabilities } from '../security/capabilities.js';\n/**\n * `mcp_control` \u2014 LLM-driven MCP server lifecycle management.\n *\n * The model calls this tool to:\n * list \u2014 see all known servers (running or not) without starting any\n * search \u2014 filter the server catalog by name or description keyword\n * enable \u2014 start a server and register its tools\n * disable \u2014 stop a server and unregister its tools\n * restart \u2014 stop then re-start a running server\n *\n * This is the primary mechanism by which the LLM autonomously extends its\n * own capabilities at runtime \u2014 e.g. \"I need GitHub access, let me enable it.\"\n */\nimport { allServers } from '../infrastructure/mcp-servers.js';\nimport { readJsonObjectFile, setJsonPath, updateJsonObjectFile } from '../utils/config-json.js';\nimport type { Config, JSONSchema, MCPServerConfig, Tool } from '../index.js';\nexport interface MCPRegistryHandle {\n start(cfg: MCPServerConfig): Promise<void>;\n stop(name: string): Promise<void>;\n restart(name: string): Promise<void>;\n describe(): {\n name: string;\n state: string;\n toolCount: number;\n enabled: boolean;\n tools?: string[];\n }[];\n list(): { name: string; state: string; toolCount: number; tools?: string[] }[];\n /**\n * Register all cached tools for a server without restarting it.\n * No-op if the server is not connected or tools are already active.\n * Used in token-saving mode to temporarily expose MCP tools.\n */\n activateServer?(name: string): void;\n /**\n * Unregister all tools for a server without disconnecting it.\n * Returns the number of tools that were deactivated.\n * Used in token-saving mode to hide MCP tools after use.\n */\n deactivateServer?(name: string): number;\n /**\n * Check whether a server's tools are currently registered.\n */\n isActivated?(name: string): boolean;\n}\n\nexport interface CreateMcpControlToolOptions {\n /**\n * Read the current config object. The tool never mutates this directly \u2014\n * writes go to the global config file via `configPath`.\n */\n getConfig: () => Config;\n /**\n * Path to ~/.wrongstack/config.json (or equivalent) for atomic config writes.\n */\n configPath: string;\n /**\n * Live MCP registry for runtime start/stop/restart. The tool calls these\n * immediately so the LLM sees the result of its action in the same turn.\n */\n registry: MCPRegistryHandle;\n}\n\nexport function createMcpControlTool(opts: CreateMcpControlToolOptions): Tool {\n const { getConfig, configPath, registry } = opts;\n\n const inputSchema: JSONSchema = {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'search', 'enable', 'disable', 'restart', 'activate', 'deactivate'],\n description: 'The management action to perform. activate/deactivate toggle tool registration ephemerally without disconnecting.',\n },\n /** Filter for `search`. Matches server name or description case-insensitively. */\n query: {\n type: 'string',\n description: 'Search term for `search` action. Matches server name or description.',\n },\n /** Target server name for `enable`, `disable`, `restart`, `activate`, `deactivate`. */\n server: {\n type: 'string',\n description: 'Server name (e.g. \"github\", \"filesystem\", \"brave-search\").',\n },\n },\n required: ['action'],\n };\n\n return {\n name: 'mcp_control',\n description:\n 'Manage MCP server lifecycle: list available servers, search by name or capability, enable or disable servers at runtime, restart running servers. Use activate/deactivate to ephemerally toggle tool registration without disconnecting \u2014 ideal for token-saving mode where MCP tools are lazy-loaded on demand. NOTE: `enable`/`restart` start a server process, which for the built-in stdio presets runs `npx -y <package>` \u2014 i.e. it fetches and executes an npm package from the network. Treat it as code execution.',\n category: 'mcp',\n permission: 'confirm',\n mutating: true,\n // `enable`/`restart` spawn a server process that, for the stdio presets,\n // fetches and runs an npm package (`npx -y <pkg>`) \u2014 effectively remote\n // code execution. Marking the tool destructive preserves risk metadata for\n // UI/audit surfaces; YOLO itself still auto-approves unless an explicit\n // deny rule blocks the call. Read-only actions (list/search) ride the same\n // tool but are cheap to confirm/trust once when YOLO is off.\n riskTier: 'destructive',\n capabilities: [ToolCapabilities.CONFIG_MUTATE],\n inputSchema,\n async execute(raw) {\n const input = raw as { action: string; query?: string | undefined; server?: string | undefined };\n return mcpControlDispatch(input, { getConfig, configPath, registry });\n },\n };\n}\n\n// \u2500\u2500 Dispatch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function mcpControlDispatch(\n input: { action: string; query?: string | undefined; server?: string | undefined },\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n const { action, query, server } = input;\n\n switch (action) {\n case 'list': return renderList(deps);\n case 'search': return renderSearch(query ?? '', deps);\n case 'enable': return server ? runEnable(server, deps) : '`server` is required for enable.';\n case 'disable': return server ? runDisable(server, deps) : '`server` is required for disable.';\n case 'restart': return server ? runRestart(server, deps) : '`server` is required for restart.';\n case 'activate': return server ? runActivate(server, deps) : '`server` is required for activate.';\n case 'deactivate': return server ? runDeactivate(server, deps) : '`server` is required for deactivate.';\n default:\n return `Unknown action \"${action}\". Use one of: list, search, enable, disable, restart, activate, deactivate.`;\n }\n}\n\n// \u2500\u2500 Actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function renderList(deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle }): Promise<string> {\n const configured = await getConfiguredMcpServers(deps);\n const live = deps.registry.describe();\n\n if (Object.keys(configured).length === 0) {\n return [\n 'No MCP servers configured.',\n ' Use `mcp_control({ action: \"search\" })` to see available presets,',\n ' then `mcp_control({ action: \"enable\", server: \"<name>\" })` to add one.',\n ].join('\\n');\n }\n\n const lines: string[] = [];\n const liveMap = new Map(live.map((s) => [s.name, s]));\n\n for (const [name, cfg] of Object.entries(configured)) {\n const liveInfo = liveMap.get(name);\n const toolCount = liveInfo ? ` (${liveInfo.toolCount} tools)` : '';\n const stateStr = liveInfo ? badge(liveInfo.state) : dim('\u25CB not loaded');\n const enabled = cfg.enabled === false\n ? `${dim('disabled')} `\n : `${green('\u25CF enabled')} `;\n lines.push(` ${bold(name)} ${enabled}${stateStr}${toolCount}`);\n if (cfg.description) lines.push(` ${dim(cfg.description)}`);\n }\n\n lines.push('');\n lines.push(dim(' Use `mcp_control({ action: \"search\", query: \"<keyword>\" })` to find servers.'));\n lines.push(dim(' Use `mcp_control({ action: \"enable\", server: \"<name>\" })` to start a server.'));\n return lines.join('\\n');\n}\n\nasync function renderSearch(\n query: string,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n const configured = await getConfiguredMcpServers(deps);\n const all = allServers();\n const q = query.toLowerCase();\n\n const configuredNames = new Set(Object.keys(configured));\n\n // Match against configured servers first, then remaining presets\n const configuredEntries = Object.entries(configured).filter(\n ([name, cfg]) =>\n name.toLowerCase().includes(q) ||\n (cfg.description ?? '').toLowerCase().includes(q),\n );\n\n const unconfiguredEntries = Object.entries(all)\n .filter(([name]) => !configuredNames.has(name))\n .filter(\n ([name, cfg]) =>\n name.toLowerCase().includes(q) ||\n (cfg.description ?? '').toLowerCase().includes(q),\n );\n\n const lines: string[] = [];\n\n if (configuredEntries.length > 0) {\n lines.push(bold('Configured servers matching \"') + query + '\":');\n for (const [name, cfg] of configuredEntries) {\n lines.push(` ${bold(name)} ${cfg.description ?? cfg.transport}`);\n }\n lines.push('');\n }\n\n if (unconfiguredEntries.length > 0) {\n lines.push(bold('Available presets matching \"') + query + '\":');\n for (const [name, cfg] of unconfiguredEntries) {\n const warn = cfg.permission === 'deny' ? red(' \u26A0 confirm required') : '';\n lines.push(` ${bold(name)} ${cfg.description ?? cfg.transport}${warn}`);\n }\n lines.push('');\n }\n\n if (configuredEntries.length === 0 && unconfiguredEntries.length === 0) {\n return `No servers match \"${query}\". Try a shorter keyword or \\`mcp_control({ action: \"list\" })\\`.`;\n }\n\n const total = configuredEntries.length + unconfiguredEntries.length;\n lines.push(dim(` ${total} server${total !== 1 ? 's' : ''} shown. Run \\`enable\\` on one to activate it.`));\n return lines.join('\\n');\n}\n\nasync function runEnable(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for enable. Example: { action: \"enable\", server: \"github\" }';\n\n const all = allServers();\n const configured = deps.getConfig().mcpServers ?? {};\n\n // Resolve the target config \u2014 it may be a preset not yet in config\n const cfg = configured[name] ?? all[name];\n if (!cfg) {\n const known = Object.keys(all).join(', ');\n return `Unknown server \"${name}\". Available presets: ${known}`;\n }\n\n // Write to config (add or update) using the shared JSON path helper.\n await updateJsonObjectFile(deps.configPath, (full) => {\n const current = isMcpServerRecord(full.mcpServers) ? full.mcpServers : {};\n setJsonPath(full, ['mcpServers', name], { ...current[name], ...cfg, enabled: true });\n });\n\n // Start the server in the registry\n try {\n const live = deps.registry.describe().find((s) => s.name === name);\n if (live && live.state === 'connected') {\n return `${green('\u25CF')} Server \"${name}\" is already running (${live.toolCount} tools registered).`;\n }\n await deps.registry.start({ ...cfg, enabled: true });\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Enabled and started')} \"${name}\"${updated ? ` (${updated.toolCount} tools registered).` : '.'}`;\n } catch (err) {\n return `${red('\u2717 Failed to start')} \"${name}\": ${toErrorMessage(err)}`;\n }\n}\n\nasync function runDisable(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for disable. Example: { action: \"disable\", server: \"github\" }';\n\n const configured = deps.getConfig().mcpServers ?? {};\n if (!configured[name]) {\n return `Server \"${name}\" is not in config. Add it with \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\`.`;\n }\n\n // Write to config using the shared JSON path helper.\n await updateJsonObjectFile(deps.configPath, (full) => {\n const current = isMcpServerRecord(full.mcpServers) ? full.mcpServers : {};\n const existing = expectDefined(current[name]);\n setJsonPath(full, ['mcpServers', name], { ...existing, enabled: false });\n });\n\n // Stop the running server\n try {\n await deps.registry.stop(name);\n return `${yellow('\u25CB Disabled')} \"${name}\". It will not be started on next boot.`;\n } catch {\n return `${yellow('\u25CB Disabled')} \"${name}\" (it was not running). Config updated.`;\n }\n}\n\nasync function runRestart(\n name: string | undefined,\n deps: { getConfig: () => Config; configPath: string; registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for restart. Example: { action: \"restart\", server: \"github\" }';\n\n const configured = deps.getConfig().mcpServers ?? {};\n if (!configured[name]) {\n return `Server \"${name}\" is not configured. Use \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\` first.`;\n }\n\n try {\n await deps.registry.restart(name);\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Restarted')} \"${name}\"${updated ? ` (${updated.toolCount} tools registered).` : '.'}`;\n } catch (err) {\n return `${red('\u2717 Restart failed')} for \"${name}\": ${toErrorMessage(err)}`;\n }\n}\n\n/**\n * Ephemerally activate a server's tools without writing to config or\n * restarting the connection. The server must already be connected (lazy mode).\n * Calls `registry.activateServer()` when available; falls back to a message\n * if the registry doesn't support ephemeral activation.\n */\nasync function runActivate(\n name: string | undefined,\n deps: { registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for activate.';\n if (!deps.registry.activateServer) {\n return `Registry does not support ephemeral activation. Use \\`enable\\` to start \"${name}\" instead.`;\n }\n const live = deps.registry.describe().find((s) => s.name === name);\n if (!live) {\n return `Server \"${name}\" is not registered. Use \\`mcp_control({ action: \"enable\", server: \"${name}\" })\\` first.`;\n }\n if (live.state !== 'connected') {\n return `Server \"${name}\" is not connected (state: ${live.state}). Use \\`enable\\` to start it first.`;\n }\n if (deps.registry.isActivated?.(name)) {\n return `${green('\u25CF')} Server \"${name}\" tools are already active. Use \\`deactivate\\` to hide them.`;\n }\n deps.registry.activateServer(name);\n const updated = deps.registry.describe().find((s) => s.name === name);\n return `${green('\u2713 Activated')} \"${name}\" \u2014 ${updated?.toolCount ?? 0} tool(s) now registered. Use \\`mcp_control({ action: \"deactivate\", server: \"${name}\" })\\` to hide them when done.`;\n}\n\n/**\n * Ephemerally deactivate a server's tools without disconnecting.\n * Calls `registry.deactivateServer()` when available.\n */\nasync function runDeactivate(\n name: string | undefined,\n deps: { registry: MCPRegistryHandle },\n): Promise<string> {\n if (!name) return '`server` is required for deactivate.';\n if (!deps.registry.deactivateServer) {\n return `Registry does not support ephemeral deactivation. Use \\`disable\\` to stop \"${name}\" instead.`;\n }\n if (!deps.registry.isActivated?.(name)) {\n return `Server \"${name}\" tools are not currently active.`;\n }\n const count = deps.registry.deactivateServer(name);\n return `${yellow('\u25CB Deactivated')} \"${name}\" \u2014 ${count} tool(s) unregistered. Server stays connected.`;\n}\n\n// \u2500\u2500 Config helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nasync function getConfiguredMcpServers(deps: { getConfig: () => Config; configPath: string }): Promise<Record<string, MCPServerConfig>> {\n const diskConfig = await readJsonObjectFile(deps.configPath);\n if (isMcpServerRecord(diskConfig.mcpServers)) return diskConfig.mcpServers;\n return deps.getConfig().mcpServers ?? {};\n}\n\nfunction isMcpServerRecord(value: unknown): value is Record<string, MCPServerConfig> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\n// \u2500\u2500 Colour helpers (no dep on core color \u2014 inline) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction bold(s: string) { return `\\x1b[1m${s}\\x1b[0m`; }\nfunction dim(s: string) { return `\\x1b[2m${s}\\x1b[0m`; }\nfunction green(s: string) { return `\\x1b[32m${s}\\x1b[0m`; }\nfunction yellow(s: string){ return `\\x1b[33m${s}\\x1b[0m`; }\nfunction red(s: string) { return `\\x1b[31m${s}\\x1b[0m`; }\n\nfunction badge(state: string): string {\n switch (state) {\n case 'connected': return green('\u25CF connected');\n case 'connecting': return `\\x1b[36m\u25D0 connecting\\x1b[0m`;\n case 'reconnecting': return `\\x1b[36m\u25D1 reconnecting\\x1b[0m`;\n case 'disconnected': return dim('\u25CB disconnected');\n case 'failed': return red('\u2717 failed');\n default: return dim(state);\n }\n}\n", "import type { CouncilPersona } from '../types/council.js';\n\nconst PERSONA_ID_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\n/** Provider-neutral personas shipped with every Council installation. */\nexport const BUILTIN_COUNCIL_PERSONAS: readonly CouncilPersona[] = Object.freeze([\n freezePersona({\n id: 'executor',\n name: 'Executor',\n description: 'Tests whether a proposal is practical and keeps useful work moving.',\n instruction:\n 'Evaluate operational feasibility, concrete progress, and the cost of delay. Favor decisive action when evidence supports it, but reject action whose prerequisites are missing.',\n tags: ['delivery', 'feasibility', 'progress'],\n }),\n freezePersona({\n id: 'skeptic',\n name: 'Skeptic',\n description: 'Challenges assumptions and looks for concrete failure modes.',\n instruction:\n 'Identify unsupported assumptions, unsafe premises, irreversible consequences, and credible failure modes. Oppose or refuse only when you can name a concrete reason.',\n defaultVeto: true,\n tags: ['risk', 'assumptions', 'failure-modes'],\n }),\n freezePersona({\n id: 'auditor',\n name: 'Auditor',\n description: 'Evaluates cost, waste, evidence quality, and expected value.',\n instruction:\n 'Compare resource cost, opportunity cost, evidence quality, reversibility, and expected value. Prefer the option that achieves the objective with the least avoidable waste.',\n tags: ['cost', 'evidence', 'efficiency'],\n }),\n freezePersona({\n id: 'security',\n name: 'Security Reviewer',\n description: 'Examines trust boundaries, abuse cases, and security impact.',\n instruction:\n 'Evaluate trust boundaries, attacker-controlled inputs, privilege changes, data exposure, abuse cases, and recovery options. Treat unmitigated high-impact security risk as grounds to refuse.',\n defaultVeto: true,\n tags: ['security', 'trust', 'abuse-cases'],\n }),\n freezePersona({\n id: 'maintainer',\n name: 'Maintainer',\n description: 'Evaluates complexity, compatibility, and long-term ownership.',\n instruction:\n 'Evaluate behavioral compatibility, conceptual complexity, testability, migration cost, and future maintenance. Prefer the smallest design that remains clear and extensible.',\n tags: ['maintenance', 'compatibility', 'simplicity'],\n }),\n freezePersona({\n id: 'user-advocate',\n name: 'User Advocate',\n description: 'Evaluates the decision from the affected user\u2019s perspective.',\n instruction:\n 'Evaluate usability, surprise, accessibility, failure recovery, and whether the outcome solves the user\u2019s stated need. Prefer understandable behavior with safe recovery paths.',\n tags: ['users', 'usability', 'accessibility'],\n }),\n]);\n\n/** Immutable registry of trusted Council persona definitions. */\nexport class CouncilPersonaRegistry {\n private readonly byId: ReadonlyMap<string, CouncilPersona>;\n\n constructor(personas: readonly CouncilPersona[] = []) {\n const entries = new Map<string, CouncilPersona>();\n for (const persona of personas) {\n const normalized = freezePersona(persona);\n if (entries.has(normalized.id)) {\n throw new Error(`CouncilPersonaRegistry: duplicate persona id \"${normalized.id}\".`);\n }\n entries.set(normalized.id, normalized);\n }\n this.byId = entries;\n }\n\n has(id: string): boolean {\n return this.byId.has(id);\n }\n\n get(id: string): CouncilPersona | undefined {\n return this.byId.get(id);\n }\n\n require(id: string): CouncilPersona {\n const persona = this.get(id);\n if (!persona) throw new Error(`CouncilPersonaRegistry: unknown persona \"${id}\".`);\n return persona;\n }\n\n list(): readonly CouncilPersona[] {\n return Object.freeze([...this.byId.values()]);\n }\n\n /** Return a new registry; the current registry is never mutated. */\n with(persona: CouncilPersona, opts: { replace?: boolean | undefined } = {}): CouncilPersonaRegistry {\n const normalized = freezePersona(persona);\n if (this.has(normalized.id) && opts.replace !== true) {\n throw new Error(`CouncilPersonaRegistry: persona \"${normalized.id}\" already exists.`);\n }\n return new CouncilPersonaRegistry([\n ...this.list().filter((entry) => entry.id !== normalized.id),\n normalized,\n ]);\n }\n}\n\nexport const DEFAULT_COUNCIL_PERSONA_REGISTRY = new CouncilPersonaRegistry(\n BUILTIN_COUNCIL_PERSONAS,\n);\n\nexport function createCouncilPersonaRegistry(\n additional: readonly CouncilPersona[] = [],\n): CouncilPersonaRegistry {\n let registry = DEFAULT_COUNCIL_PERSONA_REGISTRY;\n for (const persona of additional) registry = registry.with(persona);\n return registry;\n}\n\nfunction freezePersona(persona: CouncilPersona): CouncilPersona {\n const id = persona.id.trim();\n const name = persona.name.trim();\n const description = persona.description.trim();\n const instruction = persona.instruction.trim();\n if (!PERSONA_ID_RE.test(id)) {\n throw new Error(`CouncilPersonaRegistry: invalid persona id \"${persona.id}\".`);\n }\n if (!name) throw new Error(`CouncilPersonaRegistry: persona \"${id}\" requires a name.`);\n if (!description) {\n throw new Error(`CouncilPersonaRegistry: persona \"${id}\" requires a description.`);\n }\n if (!instruction) {\n throw new Error(`CouncilPersonaRegistry: persona \"${id}\" requires an instruction.`);\n }\n if (\n persona.defaultWeight !== undefined &&\n (!Number.isFinite(persona.defaultWeight) || persona.defaultWeight <= 0)\n ) {\n throw new Error(`CouncilPersonaRegistry: persona \"${id}\" has an invalid default weight.`);\n }\n const tags = Object.freeze(\n [...new Set((persona.tags ?? []).map((tag) => tag.trim()).filter(Boolean))],\n );\n return Object.freeze({\n id,\n name,\n description,\n instruction,\n ...(persona.defaultWeight !== undefined ? { defaultWeight: persona.defaultWeight } : {}),\n ...(persona.defaultVeto !== undefined ? { defaultVeto: persona.defaultVeto } : {}),\n ...(tags.length > 0 ? { tags } : {}),\n });\n}\n", "import type {\n CouncilDistinctness,\n CouncilModelTarget,\n CouncilProfileConfig,\n ResolvedCouncilProfile,\n ResolvedCouncilSeat,\n} from '../types/council.js';\nimport {\n type CouncilPersonaRegistry,\n DEFAULT_COUNCIL_PERSONA_REGISTRY,\n} from './council-personas.js';\n\nconst PROFILE_ID_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nconst DISTINCTNESS_VALUES: ReadonlySet<CouncilDistinctness> = new Set([\n 'none',\n 'model',\n 'provider',\n]);\n\nexport const DEFAULT_COUNCIL_QUORUM_FRACTION = 0.5;\nexport const DEFAULT_COUNCIL_APPROVAL_FRACTION = 0.5;\nexport const DEFAULT_COUNCIL_VOTER_MAX_TOKENS = 300;\nexport const DEFAULT_COUNCIL_JUDGE_MAX_TOKENS = 500;\nexport const DEFAULT_COUNCIL_PER_CALL_TIMEOUT_MS = 30_000;\nexport const DEFAULT_COUNCIL_OVERALL_TIMEOUT_MS = 90_000;\n\n/** Model-agnostic profiles. Roles are routing hints, never provider/model pins. */\nexport const BUILTIN_COUNCIL_PROFILES: readonly CouncilProfileConfig[] = Object.freeze([\n Object.freeze({\n id: 'balanced',\n name: 'Balanced',\n description: 'Three complementary lenses plus an independent judge for general decisions.',\n seats: Object.freeze([\n Object.freeze({ persona: 'executor', target: Object.freeze({ role: 'planner' }) }),\n Object.freeze({ persona: 'skeptic', target: Object.freeze({ role: 'critic' }) }),\n Object.freeze({ persona: 'auditor', target: Object.freeze({ role: 'analyst' }) }),\n ]),\n judge: Object.freeze({ role: 'reviewer' }),\n quorumFraction: 0.5,\n approvalFraction: 0.5,\n distinctness: 'model',\n }),\n Object.freeze({\n id: 'fast',\n name: 'Fast',\n description: 'Two-seat panel without a judge for quick, low-cost decisions.',\n seats: Object.freeze([\n Object.freeze({ persona: 'executor', target: Object.freeze({ role: 'planner' }) }),\n Object.freeze({ persona: 'skeptic', target: Object.freeze({ role: 'critic' }) }),\n ]),\n judge: false,\n quorumFraction: 0.5,\n approvalFraction: 0.5,\n distinctness: 'none',\n voterMaxTokens: 200,\n perCallTimeoutMs: 20_000,\n overallTimeoutMs: 30_000,\n }),\n Object.freeze({\n id: 'risk-review',\n name: 'Risk Review',\n description: 'Security, assumptions, maintenance, and cost review for high-impact choices.',\n seats: Object.freeze([\n Object.freeze({ persona: 'skeptic', target: Object.freeze({ role: 'critic' }) }),\n Object.freeze({ persona: 'security', target: Object.freeze({ role: 'security-reviewer' }) }),\n Object.freeze({ persona: 'maintainer', target: Object.freeze({ role: 'reviewer' }) }),\n Object.freeze({ persona: 'auditor', target: Object.freeze({ role: 'analyst' }) }),\n ]),\n judge: Object.freeze({ role: 'architect' }),\n quorumFraction: 0.75,\n approvalFraction: 0.5,\n distinctness: 'provider',\n judgeMaxTokens: 700,\n overallTimeoutMs: 120_000,\n }),\n]);\n\n/** Immutable registry of normalized Council profiles. */\nexport class CouncilProfileRegistry {\n private readonly byId: ReadonlyMap<string, ResolvedCouncilProfile>;\n private readonly personas: CouncilPersonaRegistry;\n\n constructor(\n profiles: readonly CouncilProfileConfig[] = [],\n personas: CouncilPersonaRegistry = DEFAULT_COUNCIL_PERSONA_REGISTRY,\n ) {\n this.personas = personas;\n const entries = new Map<string, ResolvedCouncilProfile>();\n for (const profile of profiles) {\n const normalized = normalizeCouncilProfile(profile, personas);\n if (entries.has(normalized.id)) {\n throw new Error(`CouncilProfileRegistry: duplicate profile id \"${normalized.id}\".`);\n }\n entries.set(normalized.id, normalized);\n }\n this.byId = entries;\n }\n\n has(id: string): boolean {\n return this.byId.has(id);\n }\n\n get(id: string): ResolvedCouncilProfile | undefined {\n return this.byId.get(id);\n }\n\n require(id: string): ResolvedCouncilProfile {\n const profile = this.get(id);\n if (!profile) throw new Error(`CouncilProfileRegistry: unknown profile \"${id}\".`);\n return profile;\n }\n\n list(): readonly ResolvedCouncilProfile[] {\n return Object.freeze([...this.byId.values()]);\n }\n\n /** Return a new registry; the current registry is never mutated. */\n with(\n profile: CouncilProfileConfig,\n opts: {\n replace?: boolean | undefined;\n personas?: CouncilPersonaRegistry | undefined;\n } = {},\n ): CouncilProfileRegistry {\n const personas = opts.personas ?? this.personas;\n const normalized = normalizeCouncilProfile(profile, personas);\n if (this.has(normalized.id) && opts.replace !== true) {\n throw new Error(`CouncilProfileRegistry: profile \"${normalized.id}\" already exists.`);\n }\n return new CouncilProfileRegistry(\n [\n ...this.list().filter((entry) => entry.id !== normalized.id),\n profile,\n ],\n personas,\n );\n }\n}\n\nexport const DEFAULT_COUNCIL_PROFILE_REGISTRY = new CouncilProfileRegistry(\n BUILTIN_COUNCIL_PROFILES,\n);\n\nexport function createCouncilProfileRegistry(\n additional: readonly CouncilProfileConfig[] = [],\n personas: CouncilPersonaRegistry = DEFAULT_COUNCIL_PERSONA_REGISTRY,\n): CouncilProfileRegistry {\n return new CouncilProfileRegistry([...BUILTIN_COUNCIL_PROFILES, ...additional], personas);\n}\n\nexport function resolveCouncilProfile(\n profile: string | CouncilProfileConfig | undefined,\n opts: {\n registry?: CouncilProfileRegistry | undefined;\n personas?: CouncilPersonaRegistry | undefined;\n defaultProfile?: string | undefined;\n } = {},\n): ResolvedCouncilProfile {\n const personas = opts.personas ?? DEFAULT_COUNCIL_PERSONA_REGISTRY;\n if (profile && typeof profile !== 'string') return normalizeCouncilProfile(profile, personas);\n const id = profile ?? opts.defaultProfile ?? 'balanced';\n return (opts.registry ?? DEFAULT_COUNCIL_PROFILE_REGISTRY).require(id);\n}\n\nexport function normalizeCouncilProfile(\n profile: CouncilProfileConfig,\n personas: CouncilPersonaRegistry = DEFAULT_COUNCIL_PERSONA_REGISTRY,\n): ResolvedCouncilProfile {\n const id = profile.id.trim();\n if (!PROFILE_ID_RE.test(id)) {\n throw new Error(`CouncilProfileRegistry: invalid profile id \"${profile.id}\".`);\n }\n if (profile.seats.length === 0) {\n throw new Error(`CouncilProfileRegistry: profile \"${id}\" requires at least one seat.`);\n }\n\n const usedIds = new Set<string>();\n const seats = profile.seats.map((seat) => {\n const persona = personas.require(seat.persona.trim());\n const explicitSeatId = seat.id?.trim();\n if (explicitSeatId && usedIds.has(explicitSeatId)) {\n throw new Error(`CouncilProfileRegistry: duplicate seat id \"${explicitSeatId}\".`);\n }\n const seatId = uniqueSeatId(explicitSeatId || persona.id, usedIds);\n const label = seat.label?.trim() || persona.name;\n const weight = seat.weight ?? persona.defaultWeight ?? 1;\n if (!Number.isFinite(weight) || weight <= 0) {\n throw new Error(`CouncilProfileRegistry: seat \"${seatId}\" has an invalid weight.`);\n }\n return Object.freeze({\n id: seatId,\n label,\n persona: persona.id,\n ...(seat.target ? { target: freezeTarget(seat.target, `seat \"${seatId}\"`) } : {}),\n weight,\n veto: seat.veto ?? persona.defaultVeto ?? false,\n }) satisfies ResolvedCouncilSeat;\n });\n\n const quorumFraction = fraction(\n profile.quorumFraction ?? DEFAULT_COUNCIL_QUORUM_FRACTION,\n 'quorumFraction',\n id,\n );\n const approvalFraction = fraction(\n profile.approvalFraction ?? DEFAULT_COUNCIL_APPROVAL_FRACTION,\n 'approvalFraction',\n id,\n );\n const distinctness = profile.distinctness ?? 'model';\n if (!DISTINCTNESS_VALUES.has(distinctness)) {\n throw new Error(`CouncilProfileRegistry: profile \"${id}\" has invalid distinctness.`);\n }\n const voterMaxTokens = positiveInteger(\n profile.voterMaxTokens ?? DEFAULT_COUNCIL_VOTER_MAX_TOKENS,\n 'voterMaxTokens',\n id,\n );\n const judgeMaxTokens = positiveInteger(\n profile.judgeMaxTokens ?? DEFAULT_COUNCIL_JUDGE_MAX_TOKENS,\n 'judgeMaxTokens',\n id,\n );\n const perCallTimeoutMs = positiveInteger(\n profile.perCallTimeoutMs ?? DEFAULT_COUNCIL_PER_CALL_TIMEOUT_MS,\n 'perCallTimeoutMs',\n id,\n );\n const overallTimeoutMs = positiveInteger(\n profile.overallTimeoutMs ?? DEFAULT_COUNCIL_OVERALL_TIMEOUT_MS,\n 'overallTimeoutMs',\n id,\n );\n if (overallTimeoutMs < perCallTimeoutMs) {\n throw new Error(\n `CouncilProfileRegistry: profile \"${id}\" overallTimeoutMs must be at least perCallTimeoutMs.`,\n );\n }\n\n return Object.freeze({\n id,\n name: profile.name?.trim() || id,\n description: profile.description?.trim() || '',\n seats: Object.freeze(seats),\n judge: profile.judge ? freezeTarget(profile.judge, 'judge') : false,\n quorumFraction,\n approvalFraction,\n distinctness,\n voterMaxTokens,\n judgeMaxTokens,\n perCallTimeoutMs,\n overallTimeoutMs,\n });\n}\n\nfunction uniqueSeatId(base: string, used: Set<string>): string {\n if (!PROFILE_ID_RE.test(base)) {\n throw new Error(`CouncilProfileRegistry: invalid seat id \"${base}\".`);\n }\n let id = base;\n let suffix = 2;\n while (used.has(id)) id = `${base}-${suffix++}`;\n used.add(id);\n return id;\n}\n\nfunction freezeTarget(target: CouncilModelTarget, label: string): CouncilModelTarget {\n const providerId = optionalText(target.providerId);\n const model = optionalText(target.model);\n const role = optionalText(target.role);\n const fallbackProfile = optionalText(target.fallbackProfile);\n const fallbackModels = Object.freeze(\n [...new Set((target.fallbackModels ?? []).map((ref) => ref.trim()).filter(Boolean))],\n );\n if (\n !providerId &&\n !model &&\n !role &&\n !fallbackProfile &&\n fallbackModels.length === 0\n ) {\n throw new Error(`CouncilProfileRegistry: ${label} target is empty.`);\n }\n return Object.freeze({\n ...(providerId ? { providerId } : {}),\n ...(model ? { model } : {}),\n ...(role ? { role } : {}),\n ...(fallbackProfile ? { fallbackProfile } : {}),\n ...(fallbackModels.length > 0 ? { fallbackModels } : {}),\n });\n}\n\nfunction optionalText(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed || undefined;\n}\n\nfunction fraction(value: number, field: string, profileId: string): number {\n if (!Number.isFinite(value) || value <= 0 || value > 1) {\n throw new Error(`CouncilProfileRegistry: profile \"${profileId}\" ${field} must be in (0, 1].`);\n }\n return value;\n}\n\nfunction positiveInteger(value: number, field: string, profileId: string): number {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw new Error(\n `CouncilProfileRegistry: profile \"${profileId}\" ${field} must be a positive integer.`,\n );\n }\n return value;\n}\n", "import { readFileSync, statSync } from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Cache of resolved instruction text, keyed by the relative path. Bundled\n * instruction files are immutable for the process lifetime, so re-reading them\n * on every call (some callers do so per LLM request) is wasted disk I/O.\n */\nconst textCache = new Map<string, string>();\n\n/** Resolved once \u2014 the candidate roots only depend on this module's location. */\nlet rootCandidates: string[] | undefined;\n\nexport function readBundledInstructionText(relativePath: string): string {\n const cached = textCache.get(relativePath);\n if (cached !== undefined) return cached;\n\n let resolved = '';\n for (const root of instructionRootCandidates()) {\n try {\n resolved = readFileSync(path.join(root, relativePath), 'utf8').trimEnd();\n break;\n } catch {\n // try next candidate\n }\n }\n textCache.set(relativePath, resolved);\n return resolved;\n}\n\nexport function renderInstructionTemplate(\n template: string,\n values: Record<string, string>,\n): string {\n return template.replace(/\\{\\{\\s*([a-zA-Z0-9_.-]+)\\s*\\}\\}/g, (match, key: string) =>\n Object.hasOwn(values, key) ? (values[key] ?? '') : match,\n );\n}\n\nfunction instructionRootCandidates(): string[] {\n if (rootCandidates !== undefined) return rootCandidates;\n const here = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(here, '../../instructions'),\n path.resolve(here, '../instructions'),\n path.resolve(here, 'instructions'),\n ];\n rootCandidates = candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));\n return rootCandidates;\n}\n\nfunction isDirectory(candidate: string): boolean {\n try {\n return statSync(candidate).isDirectory();\n } catch {\n return false;\n }\n}\n", "import type {\n CouncilOption,\n CouncilPersona,\n CouncilQuestion,\n CouncilVoteResult,\n ResolvedCouncilSeat,\n} from '../types/council.js';\nimport {\n readBundledInstructionText,\n renderInstructionTemplate,\n} from '../utils/instruction-file.js';\n\nexport const COUNCIL_VOTER_PROMPT_PATH = 'llm/council-voter.md';\nexport const COUNCIL_JUDGE_PROMPT_PATH = 'llm/council-judge.md';\n\n/** Build the trusted system instruction for one independent seat. */\nexport function buildCouncilVoterSystemPrompt(persona: CouncilPersona): string {\n const template = requiredInstruction(COUNCIL_VOTER_PROMPT_PATH);\n return renderInstructionTemplate(template, {\n personaInstruction: persona.instruction,\n });\n}\n\n/** Build the trusted system instruction for the final judge. */\nexport function buildCouncilJudgeSystemPrompt(): string {\n return requiredInstruction(COUNCIL_JUDGE_PROMPT_PATH);\n}\n\n/** Render the original question as delimited, untrusted user data. */\nexport function buildCouncilQuestionPrompt(\n question: CouncilQuestion,\n opts: { refusalOptionId?: string | undefined } = {},\n): string {\n const text = question.question.trim();\n if (!text) throw new Error('buildCouncilQuestionPrompt: question must not be empty.');\n const options = normalizeOptions(question.options);\n return [\n '<council-question>',\n `Question: ${text}`,\n question.context?.trim() ? `Context:\\n${question.context.trim()}` : '',\n options.length > 0 ? `Options (JSON):\\n${JSON.stringify(options)}` : 'Options: none',\n opts.refusalOptionId\n ? `Refusal option id: ${opts.refusalOptionId}`\n : 'Refusal option id: not supplied',\n '</council-question>',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/** Build the voter user prompt. Persona instructions stay in the system prompt. */\nexport function buildCouncilVoterUserPrompt(\n question: CouncilQuestion,\n seat: ResolvedCouncilSeat,\n opts: { refusalOptionId?: string | undefined } = {},\n): string {\n return [\n buildCouncilQuestionPrompt(question, opts),\n '<seat-metadata>',\n `Seat id: ${seat.id}`,\n `Seat label: ${seat.label}`,\n `Persona id: ${seat.persona}`,\n '</seat-metadata>',\n ].join('\\n');\n}\n\n/** Build the judge user prompt with seat outputs serialized as untrusted JSON. */\nexport function buildCouncilJudgeUserPrompt(\n question: CouncilQuestion,\n votes: readonly CouncilVoteResult[],\n opts: {\n reason?: string | undefined;\n refusalOptionId?: string | undefined;\n } = {},\n): string {\n const ballots = votes.map((vote) => ({\n seatId: vote.seatId,\n persona: vote.persona,\n status: vote.status,\n ...(vote.optionId ? { optionId: vote.optionId } : {}),\n ...(vote.stance ? { stance: vote.stance } : {}),\n ...(vote.rationale ? { rationale: vote.rationale } : {}),\n }));\n return [\n buildCouncilQuestionPrompt(question, { refusalOptionId: opts.refusalOptionId }),\n '<council-ballots>',\n opts.reason?.trim() ? `Reason judging is required: ${opts.reason.trim()}` : '',\n JSON.stringify(ballots),\n '</council-ballots>',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\nfunction normalizeOptions(options: readonly CouncilOption[] | undefined): CouncilOption[] {\n if (!options) return [];\n const seen = new Set<string>();\n return options.map((option) => {\n const id = option.id.trim();\n const label = option.label.trim();\n if (!id) throw new Error('buildCouncilQuestionPrompt: option id must not be empty.');\n if (!label) throw new Error(`buildCouncilQuestionPrompt: option \"${id}\" needs a label.`);\n if (seen.has(id)) throw new Error(`buildCouncilQuestionPrompt: duplicate option id \"${id}\".`);\n seen.add(id);\n return {\n id,\n label,\n ...(option.consequence?.trim() ? { consequence: option.consequence.trim() } : {}),\n };\n });\n}\n\nfunction requiredInstruction(path: string): string {\n const text = readBundledInstructionText(path);\n if (!text) throw new Error(`Council instruction file is unavailable: ${path}`);\n return text;\n}\n", "/**\n * Provider- and Brain-independent council vote resolution.\n *\n * This module contains only deterministic quorum, veto, weighted-majority,\n * refusal, and judge-escalation rules. LLM calls, prompts, parsing, and host\n * decision types belong in adapters such as `council-brain.ts`.\n */\n\nexport interface CouncilResolutionSeat {\n id: string;\n /** Vote weight in the tally. Default 1. */\n weight?: number | undefined;\n /** A refusal from this seat immediately denies the proposal. */\n veto?: boolean | undefined;\n}\n\nexport interface CouncilResolutionVote {\n seatId: string;\n optionId: string;\n}\n\nexport interface CouncilResolutionInput {\n seats: readonly CouncilResolutionSeat[];\n votes: readonly CouncilResolutionVote[];\n refusalOptionId: string;\n /** Fraction of configured seats required to return a vote. */\n quorumFraction: number;\n /** Winning weight must exceed this fraction of cast weight. */\n approvalFraction: number;\n}\n\nexport type CouncilResolution =\n | {\n status: 'abstained';\n reason: 'quorum_not_met';\n validVoteCount: number;\n seatCount: number;\n }\n | {\n status: 'denied';\n method: 'veto';\n optionId: string;\n seatId: string;\n }\n | {\n status: 'denied';\n method: 'refusal';\n optionId: string;\n winningWeight: number;\n castWeight: number;\n }\n | {\n status: 'decided';\n method: 'majority';\n optionId: string;\n winningWeight: number;\n castWeight: number;\n }\n | {\n status: 'needs_judge';\n reason: 'tie' | 'approval_threshold_not_met';\n castWeight: number;\n };\n\n/** Resolve already-parsed council votes without performing any I/O. */\nexport function resolveCouncilVotes(input: CouncilResolutionInput): CouncilResolution {\n validateInput(input);\n\n const seatById = new Map(input.seats.map((seat) => [seat.id, seat] as const));\n const validVotes: CouncilResolutionVote[] = [];\n const votedSeatIds = new Set<string>();\n for (const vote of input.votes) {\n if (!seatById.has(vote.seatId) || votedSeatIds.has(vote.seatId)) continue;\n votedSeatIds.add(vote.seatId);\n validVotes.push(vote);\n }\n\n if (validVotes.length / input.seats.length < input.quorumFraction) {\n return {\n status: 'abstained',\n reason: 'quorum_not_met',\n validVoteCount: validVotes.length,\n seatCount: input.seats.length,\n };\n }\n\n const veto = validVotes.find(\n (vote) =>\n vote.optionId === input.refusalOptionId && seatById.get(vote.seatId)?.veto === true,\n );\n if (veto) {\n return {\n status: 'denied',\n method: 'veto',\n optionId: veto.optionId,\n seatId: veto.seatId,\n };\n }\n\n const weightByOption = new Map<string, number>();\n let castWeight = 0;\n for (const vote of validVotes) {\n const weight = seatById.get(vote.seatId)?.weight ?? 1;\n castWeight += weight;\n weightByOption.set(vote.optionId, (weightByOption.get(vote.optionId) ?? 0) + weight);\n }\n\n let winner: { optionId: string; weight: number } | undefined;\n let contested = false;\n for (const [optionId, weight] of weightByOption) {\n if (!winner || weight > winner.weight) {\n winner = { optionId, weight };\n contested = false;\n } else if (weight === winner.weight) {\n contested = true;\n }\n }\n\n const decisive =\n winner !== undefined &&\n !contested &&\n winner.weight > input.approvalFraction * castWeight;\n\n if (!decisive || !winner) {\n return {\n status: 'needs_judge',\n reason: contested ? 'tie' : 'approval_threshold_not_met',\n castWeight,\n };\n }\n\n if (winner.optionId === input.refusalOptionId) {\n return {\n status: 'denied',\n method: 'refusal',\n optionId: winner.optionId,\n winningWeight: winner.weight,\n castWeight,\n };\n }\n\n return {\n status: 'decided',\n method: 'majority',\n optionId: winner.optionId,\n winningWeight: winner.weight,\n castWeight,\n };\n}\n\nfunction validateInput(input: CouncilResolutionInput): void {\n if (input.seats.length === 0) {\n throw new Error('resolveCouncilVotes: at least one seat is required.');\n }\n requireFraction(input.quorumFraction, 'quorumFraction');\n requireFraction(input.approvalFraction, 'approvalFraction');\n\n const seatIds = new Set<string>();\n for (const seat of input.seats) {\n if (!seat.id.trim()) throw new Error('resolveCouncilVotes: seat id must not be empty.');\n if (seatIds.has(seat.id)) {\n throw new Error(`resolveCouncilVotes: duplicate seat id \"${seat.id}\".`);\n }\n seatIds.add(seat.id);\n if (seat.weight !== undefined && (!Number.isFinite(seat.weight) || seat.weight <= 0)) {\n throw new Error(`resolveCouncilVotes: invalid weight for seat \"${seat.id}\".`);\n }\n }\n}\n\nfunction requireFraction(value: number, label: string): void {\n if (!Number.isFinite(value) || value <= 0 || value > 1) {\n throw new Error(`resolveCouncilVotes: ${label} must be in (0, 1].`);\n }\n}\n", "import type {\n CouncilLLMCaller,\n CouncilModelTarget,\n CouncilQuestion,\n CouncilResult,\n CouncilUsage,\n CouncilVoteResult,\n ResolvedCouncilProfile,\n ResolvedCouncilSeat,\n} from '../types/council.js';\nimport type { OneShotLLMResult } from '../types/one-shot-llm.js';\nimport {\n DEFAULT_COUNCIL_PERSONA_REGISTRY,\n type CouncilPersonaRegistry,\n} from './council-personas.js';\nimport {\n DEFAULT_COUNCIL_PROFILE_REGISTRY,\n type CouncilProfileRegistry,\n resolveCouncilProfile,\n} from './council-profiles.js';\nimport {\n buildCouncilJudgeSystemPrompt,\n buildCouncilJudgeUserPrompt,\n buildCouncilVoterSystemPrompt,\n buildCouncilVoterUserPrompt,\n} from './council-prompts.js';\nimport { resolveCouncilVotes } from './council-resolution.js';\n\n/** Synthetic ballot entry for \"refuse every real option\". */\nexport const COUNCIL_REFUSAL_OPTION_ID = 'council_refuse';\nexport const DEFAULT_COUNCIL_MAX_CONCURRENCY = 3;\nexport const MAX_COUNCIL_CONCURRENCY = 8;\n\nexport interface CouncilOrchestratorOptions {\n caller: CouncilLLMCaller;\n personas?: CouncilPersonaRegistry | undefined;\n profiles?: CouncilProfileRegistry | undefined;\n defaultProfile?: string | undefined;\n maxConcurrency?: number | undefined;\n refusalOptionId?: string | undefined;\n}\n\ninterface ParsedVote {\n optionId?: string | undefined;\n stance?: string | undefined;\n rationale?: string | undefined;\n}\n\ninterface ParsedJudge {\n optionId?: string | undefined;\n answer?: string | undefined;\n rationale?: string | undefined;\n}\n\ninterface UsageAccumulator {\n calls: number;\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n}\n\n/** Provider-neutral Council runner backed by an injected one-shot LLM caller. */\nexport class CouncilOrchestrator {\n private readonly caller: CouncilLLMCaller;\n private readonly personas: CouncilPersonaRegistry;\n private readonly profiles: CouncilProfileRegistry;\n private readonly defaultProfile: string | undefined;\n private readonly maxConcurrency: number;\n private readonly refusalOptionId: string;\n\n constructor(opts: CouncilOrchestratorOptions) {\n this.caller = opts.caller;\n this.personas = opts.personas ?? DEFAULT_COUNCIL_PERSONA_REGISTRY;\n this.profiles = opts.profiles ?? DEFAULT_COUNCIL_PROFILE_REGISTRY;\n this.defaultProfile = opts.defaultProfile;\n this.maxConcurrency = validateConcurrency(\n opts.maxConcurrency ?? DEFAULT_COUNCIL_MAX_CONCURRENCY,\n );\n this.refusalOptionId = opts.refusalOptionId?.trim() || COUNCIL_REFUSAL_OPTION_ID;\n }\n\n async ask(question: CouncilQuestion): Promise<CouncilResult> {\n const startedAt = Date.now();\n const profile = resolveCouncilProfile(question.profile, {\n registry: this.profiles,\n personas: this.personas,\n defaultProfile: this.defaultProfile,\n });\n validateRefusalCollision(question, this.refusalOptionId);\n\n const timeoutSignal = AbortSignal.timeout(profile.overallTimeoutMs);\n const signal = question.signal\n ? AbortSignal.any([question.signal, timeoutSignal])\n : timeoutSignal;\n const usage: UsageAccumulator = {\n calls: 0,\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n };\n\n const votes = await mapConcurrent(\n profile.seats,\n Math.min(this.maxConcurrency, profile.seats.length),\n async (seat) => {\n try {\n return await this.callSeat(question, profile, seat, signal, usage);\n } catch (error) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: signal.aborted ? 'cancelled' : 'failed',\n error: errorMessage(error),\n } satisfies CouncilVoteResult;\n }\n },\n );\n const warnings = distinctnessWarnings(votes, profile);\n const errors = votes\n .filter((vote) => vote.status === 'failed' || vote.status === 'invalid')\n .map((vote) => `${vote.seatId}: ${vote.error ?? vote.status}`);\n\n if (question.signal?.aborted) {\n return resultEnvelope({\n status: 'cancelled',\n reason: 'Council call cancelled.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (timeoutSignal.aborted) {\n return resultEnvelope({\n status: 'failed',\n reason: 'Council overall timeout exceeded.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors: [...errors, 'Council overall timeout exceeded.'],\n });\n }\n\n if (!question.options || question.options.length === 0) {\n return this.resolveOpenQuestion(\n question,\n profile,\n votes,\n signal,\n usage,\n startedAt,\n warnings,\n errors,\n );\n }\n return this.resolveOptionQuestion(\n question,\n profile,\n votes,\n signal,\n usage,\n startedAt,\n warnings,\n errors,\n );\n }\n\n private async callSeat(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n seat: ResolvedCouncilSeat,\n signal: AbortSignal,\n usage: UsageAccumulator,\n ): Promise<CouncilVoteResult> {\n if (signal.aborted) return cancelledVote(seat);\n let persona;\n try {\n persona = this.personas.require(seat.persona);\n } catch (error) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: 'failed',\n error: errorMessage(error),\n };\n }\n const result = await this.safeCall({\n system: buildCouncilVoterSystemPrompt(persona),\n userPrompt: buildCouncilVoterUserPrompt(question, seat, {\n refusalOptionId: question.options?.length ? this.refusalOptionId : undefined,\n }),\n target: seat.target,\n maxTokens: profile.voterMaxTokens,\n timeoutMs: profile.perCallTimeoutMs,\n signal,\n usage,\n });\n\n const metadata = callMetadata(result);\n if (result.error) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: signal.aborted ? 'cancelled' : 'failed',\n ...metadata,\n error: result.error,\n };\n }\n const parsed = parseVote(result.text, question, this.refusalOptionId);\n if (!parsed.ok) {\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: 'invalid',\n ...metadata,\n error: parsed.error,\n };\n }\n return {\n seatId: seat.id,\n persona: seat.persona,\n status: 'valid',\n ...parsed.vote,\n ...metadata,\n };\n }\n\n private async resolveOptionQuestion(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n votes: CouncilVoteResult[],\n signal: AbortSignal,\n usage: UsageAccumulator,\n startedAt: number,\n warnings: string[],\n errors: string[],\n ): Promise<CouncilResult> {\n const validVotes = votes.filter(\n (vote): vote is CouncilVoteResult & { optionId: string } =>\n vote.status === 'valid' && typeof vote.optionId === 'string',\n );\n const resolution = resolveCouncilVotes({\n seats: profile.seats.map((seat) => ({\n id: seat.id,\n weight: seat.weight,\n veto: seat.veto,\n })),\n votes: validVotes.map((vote) => ({ seatId: vote.seatId, optionId: vote.optionId })),\n refusalOptionId: this.refusalOptionId,\n quorumFraction: profile.quorumFraction,\n approvalFraction: profile.approvalFraction,\n });\n\n if (resolution.status === 'abstained') {\n return resultEnvelope({\n status: 'abstained',\n reason: 'Council quorum was not met.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (resolution.status === 'denied') {\n return resultEnvelope({\n status: 'denied',\n optionId: resolution.optionId,\n reason: `Council denied the proposal via ${resolution.method}.`,\n resolution: resolution.method,\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (resolution.status === 'decided') {\n return resultEnvelope({\n status: 'decided',\n optionId: resolution.optionId,\n answer: optionLabel(question, resolution.optionId),\n resolution: 'majority',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (!profile.judge) {\n return resultEnvelope({\n status: 'abstained',\n reason: `Council requires a judge (${resolution.reason}), but this profile has none.`,\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n\n const judged = await this.callJudge(\n question,\n profile,\n votes,\n profile.judge,\n resolution.reason,\n signal,\n usage,\n );\n if (!judged.ok) {\n return resultEnvelope({\n status: signal.aborted ? 'cancelled' : 'abstained',\n reason: judged.error,\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors: [...errors, judged.error],\n judgeUsed: true,\n });\n }\n if (judged.value.optionId === this.refusalOptionId) {\n return resultEnvelope({\n status: 'denied',\n optionId: this.refusalOptionId,\n reason: judged.value.rationale ?? 'Council judge refused all options.',\n resolution: 'judge',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n judgeUsed: true,\n });\n }\n return resultEnvelope({\n status: 'decided',\n optionId: judged.value.optionId,\n answer: optionLabel(question, judged.value.optionId),\n reason: judged.value.rationale,\n resolution: 'judge',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n judgeUsed: true,\n });\n }\n\n private async resolveOpenQuestion(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n votes: CouncilVoteResult[],\n signal: AbortSignal,\n usage: UsageAccumulator,\n startedAt: number,\n warnings: string[],\n errors: string[],\n ): Promise<CouncilResult> {\n const valid = votes.filter(\n (vote): vote is CouncilVoteResult & { stance: string } =>\n vote.status === 'valid' && typeof vote.stance === 'string',\n );\n if (valid.length / profile.seats.length < profile.quorumFraction) {\n return resultEnvelope({\n status: 'abstained',\n reason: 'Council quorum was not met.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n if (!profile.judge) {\n const first = valid[0];\n if (!first) {\n return resultEnvelope({\n status: 'failed',\n reason: 'Council produced no valid stance.',\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n return resultEnvelope({\n status: 'decided',\n answer: first.stance,\n reason: first.rationale,\n resolution: 'first_stance',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n });\n }\n\n const judged = await this.callJudge(\n question,\n profile,\n votes,\n profile.judge,\n 'open_question_synthesis',\n signal,\n usage,\n );\n if (!judged.ok) {\n return resultEnvelope({\n status: signal.aborted ? 'cancelled' : 'failed',\n reason: judged.error,\n resolution: 'none',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors: [...errors, judged.error],\n judgeUsed: true,\n });\n }\n return resultEnvelope({\n status: 'decided',\n answer: judged.value.answer,\n reason: judged.value.rationale,\n resolution: 'judge',\n votes,\n profile,\n usage,\n startedAt,\n warnings,\n errors,\n judgeUsed: true,\n });\n }\n\n private async callJudge(\n question: CouncilQuestion,\n profile: ResolvedCouncilProfile,\n votes: CouncilVoteResult[],\n target: CouncilModelTarget,\n reason: string,\n signal: AbortSignal,\n usage: UsageAccumulator,\n ): Promise<{ ok: true; value: ParsedJudge } | { ok: false; error: string }> {\n const result = await this.safeCall({\n system: buildCouncilJudgeSystemPrompt(),\n userPrompt: buildCouncilJudgeUserPrompt(question, votes, {\n reason,\n refusalOptionId: question.options?.length ? this.refusalOptionId : undefined,\n }),\n target,\n maxTokens: profile.judgeMaxTokens,\n timeoutMs: profile.perCallTimeoutMs,\n signal,\n usage,\n });\n if (result.error) return { ok: false, error: result.error };\n return parseJudge(result.text, question, this.refusalOptionId);\n }\n\n private async safeCall(input: {\n system: string;\n userPrompt: string;\n target?: CouncilModelTarget | undefined;\n maxTokens: number;\n timeoutMs: number;\n signal: AbortSignal;\n usage: UsageAccumulator;\n }): Promise<OneShotLLMResult> {\n try {\n const result = await this.caller.call({\n system: input.system,\n userPrompt: input.userPrompt,\n responseFormat: { type: 'json_object' },\n maxTokens: input.maxTokens,\n timeoutMs: input.timeoutMs,\n signal: input.signal,\n ...(input.target?.providerId ? { providerId: input.target.providerId } : {}),\n ...(input.target?.model ? { model: input.target.model } : {}),\n ...(input.target?.role ? { role: input.target.role } : {}),\n ...(input.target?.fallbackProfile\n ? { fallbackProfile: input.target.fallbackProfile }\n : {}),\n ...(input.target?.fallbackModels\n ? { fallbackModels: [...input.target.fallbackModels] }\n : {}),\n });\n addUsage(input.usage, result);\n return result;\n } catch (error) {\n input.usage.calls += 1;\n return emptyCallResult(errorMessage(error));\n }\n }\n}\n\nfunction parseVote(\n text: string,\n question: CouncilQuestion,\n refusalOptionId: string,\n): { ok: true; vote: ParsedVote } | { ok: false; error: string } {\n const parsed = parseObject(text);\n if (!parsed.ok) return parsed;\n const rationale = optionalString(parsed.value['rationale']);\n if (question.options && question.options.length > 0) {\n const optionId = optionalString(parsed.value['optionId']);\n const allowed = new Set([...question.options.map((option) => option.id.trim()), refusalOptionId]);\n if (!optionId || !allowed.has(optionId)) {\n return { ok: false, error: 'Voter returned an unknown or missing optionId.' };\n }\n return { ok: true, vote: { optionId, ...(rationale ? { rationale } : {}) } };\n }\n const stance = optionalString(parsed.value['stance']);\n if (!stance) return { ok: false, error: 'Voter returned an empty or missing stance.' };\n return { ok: true, vote: { stance, ...(rationale ? { rationale } : {}) } };\n}\n\nfunction parseJudge(\n text: string,\n question: CouncilQuestion,\n refusalOptionId: string,\n): { ok: true; value: ParsedJudge } | { ok: false; error: string } {\n const parsed = parseObject(text);\n if (!parsed.ok) return parsed;\n const rationale = optionalString(parsed.value['rationale']);\n if (question.options && question.options.length > 0) {\n const optionId = optionalString(parsed.value['optionId']);\n const allowed = new Set([...question.options.map((option) => option.id.trim()), refusalOptionId]);\n if (!optionId || !allowed.has(optionId)) {\n return { ok: false, error: 'Judge returned an unknown or missing optionId.' };\n }\n return { ok: true, value: { optionId, ...(rationale ? { rationale } : {}) } };\n }\n const answer = optionalString(parsed.value['answer']);\n if (!answer) return { ok: false, error: 'Judge returned an empty or missing answer.' };\n return { ok: true, value: { answer, ...(rationale ? { rationale } : {}) } };\n}\n\nfunction parseObject(\n text: string,\n): { ok: true; value: Record<string, unknown> } | { ok: false; error: string } {\n const trimmed = text.trim();\n const first = trimmed.indexOf('{');\n const last = trimmed.lastIndexOf('}');\n if (first < 0 || last < first) return { ok: false, error: 'LLM response did not contain JSON.' };\n try {\n const value: unknown = JSON.parse(trimmed.slice(first, last + 1));\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return { ok: false, error: 'LLM response JSON must be an object.' };\n }\n return { ok: true, value: value as Record<string, unknown> };\n } catch (error) {\n return { ok: false, error: `Invalid LLM response JSON: ${errorMessage(error)}` };\n }\n}\n\nfunction resultEnvelope(input: {\n status: CouncilResult['status'];\n answer?: string | undefined;\n optionId?: string | undefined;\n reason?: string | undefined;\n resolution: CouncilResult['resolution'];\n votes: CouncilVoteResult[];\n profile: ResolvedCouncilProfile;\n usage: UsageAccumulator;\n startedAt: number;\n warnings: string[];\n errors: string[];\n judgeUsed?: boolean | undefined;\n}): CouncilResult {\n const validVoteCount = input.votes.filter((vote) => vote.status === 'valid').length;\n return {\n status: input.status,\n ...(input.answer ? { answer: input.answer } : {}),\n ...(input.optionId ? { optionId: input.optionId } : {}),\n ...(input.reason ? { reason: input.reason } : {}),\n resolution: input.resolution,\n votes: Object.freeze([...input.votes]),\n configuredSeatCount: input.profile.seats.length,\n validVoteCount,\n distinctTargetCount: distinctTargetCount(input.votes, input.profile),\n judgeUsed: input.judgeUsed ?? false,\n usage: usageResult(input.usage, input.startedAt),\n ...(input.warnings.length > 0 ? { warnings: Object.freeze([...input.warnings]) } : {}),\n ...(input.errors.length > 0 ? { errors: Object.freeze([...input.errors]) } : {}),\n };\n}\n\nfunction callMetadata(result: OneShotLLMResult): Omit<CouncilVoteResult, 'seatId' | 'persona' | 'status'> {\n return {\n ...(result.provider ? { provider: result.provider } : {}),\n ...(result.model ? { model: result.model } : {}),\n ...(result.fromFallback ? { fromFallback: true } : {}),\n durationMs: result.durationMs,\n };\n}\n\nfunction addUsage(usage: UsageAccumulator, result: OneShotLLMResult): void {\n usage.calls += 1;\n usage.inputTokens += result.tokens.input;\n usage.outputTokens += result.tokens.output;\n usage.totalTokens += result.tokens.total;\n}\n\nfunction usageResult(usage: UsageAccumulator, startedAt: number): CouncilUsage {\n return Object.freeze({ ...usage, durationMs: Math.max(0, Date.now() - startedAt) });\n}\n\nfunction cancelledVote(seat: ResolvedCouncilSeat): CouncilVoteResult {\n return { seatId: seat.id, persona: seat.persona, status: 'cancelled', error: 'Cancelled.' };\n}\n\nfunction distinctTargetCount(\n votes: readonly CouncilVoteResult[],\n profile: ResolvedCouncilProfile,\n): number {\n const keys = votes\n .filter((vote) => vote.status === 'valid')\n .map((vote) =>\n profile.distinctness === 'provider'\n ? vote.provider\n : `${vote.provider ?? ''}/${vote.model ?? ''}`,\n )\n .filter(Boolean);\n return new Set(keys).size;\n}\n\nfunction distinctnessWarnings(\n votes: readonly CouncilVoteResult[],\n profile: ResolvedCouncilProfile,\n): string[] {\n if (profile.distinctness === 'none') return [];\n const valid = votes.filter((vote) => vote.status === 'valid');\n const distinct = distinctTargetCount(valid, profile);\n if (valid.length > 1 && distinct < valid.length) {\n return [\n `Council distinctness policy \"${profile.distinctness}\" was not met: ${distinct} distinct target(s) served ${valid.length} valid vote(s).`,\n ];\n }\n return [];\n}\n\nfunction optionLabel(question: CouncilQuestion, optionId: string | undefined): string | undefined {\n if (!optionId) return undefined;\n return question.options?.find((option) => option.id.trim() === optionId)?.label.trim();\n}\n\nfunction validateRefusalCollision(question: CouncilQuestion, refusalOptionId: string): void {\n if (question.options?.some((option) => option.id.trim() === refusalOptionId)) {\n throw new Error(`CouncilOrchestrator: option id \"${refusalOptionId}\" is reserved.`);\n }\n}\n\nfunction validateConcurrency(value: number): number {\n if (!Number.isSafeInteger(value) || value <= 0 || value > MAX_COUNCIL_CONCURRENCY) {\n throw new Error(\n `CouncilOrchestrator: maxConcurrency must be an integer in [1, ${MAX_COUNCIL_CONCURRENCY}].`,\n );\n }\n return value;\n}\n\nasync function mapConcurrent<T, R>(\n items: readonly T[],\n concurrency: number,\n worker: (item: T, index: number) => Promise<R>,\n): Promise<R[]> {\n const results = new Array<R>(items.length);\n let next = 0;\n const run = async (): Promise<void> => {\n while (true) {\n const index = next++;\n if (index >= items.length) return;\n const item = items[index];\n if (item !== undefined) results[index] = await worker(item, index);\n }\n };\n await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => run()));\n return results;\n}\n\nfunction emptyCallResult(error: string): OneShotLLMResult {\n return {\n text: '',\n model: '',\n provider: '',\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: 0,\n fromFallback: false,\n error,\n };\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n", "import { CouncilOrchestrator } from '../execution/council-orchestrator.js';\nimport type {\n CouncilLLMCaller,\n CouncilOption,\n CouncilProfileConfig,\n CouncilQuestion,\n CouncilResult,\n} from '../types/council.js';\nimport type { JSONSchema, Tool } from '../types/tool.js';\nimport type { CouncilPersonaRegistry } from '../execution/council-personas.js';\nimport type { CouncilProfileRegistry } from '../execution/council-profiles.js';\n\nexport const COUNCIL_TOOL_NAME = 'council';\nexport const MAX_COUNCIL_TOOL_OPTIONS = 12;\nexport const MAX_COUNCIL_QUESTION_CHARS = 20_000;\nexport const MAX_COUNCIL_CONTEXT_CHARS = 80_000;\n\nexport interface CouncilToolInput {\n question: string;\n context?: string | undefined;\n options?: CouncilOption[] | undefined;\n profile?: string | CouncilProfileConfig | undefined;\n}\n\nexport interface CreateCouncilToolOptions {\n caller: CouncilLLMCaller;\n personas?: CouncilPersonaRegistry | undefined;\n profiles?: CouncilProfileRegistry | undefined;\n defaultProfile?: string | undefined;\n maxConcurrency?: number | undefined;\n refusalOptionId?: string | undefined;\n}\n\nconst INPUT_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n question: {\n type: 'string',\n description: 'The decision or open question for the Council.',\n maxLength: MAX_COUNCIL_QUESTION_CHARS,\n },\n context: {\n type: 'string',\n description: 'Optional evidence and constraints. Treated as untrusted quoted data.',\n maxLength: MAX_COUNCIL_CONTEXT_CHARS,\n },\n options: {\n type: 'array',\n maxItems: MAX_COUNCIL_TOOL_OPTIONS,\n items: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Stable option id.' },\n label: { type: 'string', description: 'Human-readable option label.' },\n consequence: { type: 'string', description: 'Optional consequence or trade-off.' },\n },\n required: ['id', 'label'],\n additionalProperties: false,\n },\n description: 'Optional bounded list of choices. Omit for an open-ended Council answer.',\n },\n profile: {\n type: 'string',\n description: 'Registered Council profile id. Defaults to the host-configured profile.',\n },\n },\n required: ['question'],\n additionalProperties: false,\n};\n\n/** Create a read-only, bounded agent-callable Council tool. */\nexport function createCouncilTool(\n opts: CreateCouncilToolOptions,\n): Tool<CouncilToolInput, CouncilResult> {\n const orchestrator = new CouncilOrchestrator(opts);\n return {\n name: COUNCIL_TOOL_NAME,\n description:\n 'Ask an independent, multi-persona Council to evaluate a decision or synthesize an answer. ' +\n 'Uses bounded parallel voters, quorum/veto/weighted resolution, optional judging, model routing, fallback chains, and cancellation.',\n usageHint:\n 'Use for consequential or disputed decisions that benefit from independent lenses. ' +\n 'Provide `options` for a vote or omit them for an open answer. ' +\n 'Keep context evidence-focused; the Council treats it as untrusted data.',\n category: 'meta',\n inputSchema: INPUT_SCHEMA,\n permission: 'auto',\n mutating: false,\n riskTier: 'safe',\n managesOwnTimeout: true,\n maxOutputBytes: 256_000,\n async execute(input, _ctx, { signal }) {\n const question: CouncilQuestion = {\n question: input.question,\n ...(input.context ? { context: input.context } : {}),\n ...(input.options ? { options: input.options } : {}),\n ...(input.profile ? { profile: input.profile } : {}),\n signal,\n };\n return orchestrator.ask(question);\n },\n validate: validateCouncilToolInput,\n };\n}\n\nfunction validateCouncilToolInput(input: CouncilToolInput): string[] {\n const errors: string[] = [];\n const question = input.question?.trim() ?? '';\n if (!question) errors.push('`question` must not be empty.');\n if (question.length > MAX_COUNCIL_QUESTION_CHARS) {\n errors.push(`\\`question\\` must not exceed ${MAX_COUNCIL_QUESTION_CHARS} characters.`);\n }\n if ((input.context?.length ?? 0) > MAX_COUNCIL_CONTEXT_CHARS) {\n errors.push(`\\`context\\` must not exceed ${MAX_COUNCIL_CONTEXT_CHARS} characters.`);\n }\n if ((input.options?.length ?? 0) > MAX_COUNCIL_TOOL_OPTIONS) {\n errors.push(`\\`options\\` must not contain more than ${MAX_COUNCIL_TOOL_OPTIONS} items.`);\n }\n const ids = new Set<string>();\n for (const option of input.options ?? []) {\n const id = option.id.trim();\n if (!id) errors.push('Every option must have a non-empty `id`.');\n if (!option.label.trim()) errors.push(`Option \"${id || '<empty>'}\" must have a label.`);\n if (ids.has(id)) errors.push(`Duplicate option id \"${id}\".`);\n ids.add(id);\n }\n return errors;\n}\n", "export interface TextBlock {\n type: 'text';\n text: string;\n cache_control?: { type: 'ephemeral' | undefined };\n}\n\nexport interface ToolUseBlock {\n type: 'tool_use';\n id: string;\n name: string;\n input: Record<string, unknown>;\n /**\n * Provider-specific opaque metadata captured from the wire response.\n * Echoed back verbatim in the next request so providers that bind\n * extra state to function calls keep working. Example: Gemini's\n * `thoughtSignature` \u2014 required for tool-use turns with thinking\n * models, otherwise the next request fails with 400 \"Function call\n * is missing a thought_signature in functionCall parts\".\n *\n * Keys are namespaced by intent so multiple wires can coexist:\n * - `google.thoughtSignature` \u2014 Gemini signed-thought blob\n * Other providers can add their own keys without colliding.\n */\n providerMeta?: Record<string, unknown>;\n}\n\nexport interface ToolResultBlock {\n type: 'tool_result';\n tool_use_id: string;\n /**\n * The original tool name. Useful for providers like Google Gemini that\n * need the tool name in `functionResponse.name` \u2014 the tool_use_id is\n * only a session-local identifier and is not stable across replays.\n * Always set by ToolExecutor; may be absent on manually-constructed blocks.\n */\n name?: string | undefined;\n content: string;\n is_error?: boolean | undefined;\n}\n\nexport interface ImageBlock {\n type: 'image';\n source: {\n type: 'base64' | 'url';\n media_type?: string | undefined;\n data?: string | undefined;\n url?: string | undefined;\n };\n}\n\n/**\n * Chain-of-thought / extended-thinking content emitted by the model.\n *\n * Both Anthropic extended thinking (`{type:'thinking', thinking, signature}`)\n * and DeepSeek reasoning mode (top-level `reasoning_content` on the assistant\n * message) require this content to be echoed back verbatim on the next\n * request, otherwise the provider returns 400:\n * - Anthropic: \"The `content[].thinking` in the thinking mode must be passed back\"\n * - DeepSeek: \"The `reasoning_content` in the thinking mode must be passed back\"\n *\n * `signature` is Anthropic-specific (an opaque integrity blob). DeepSeek\n * doesn't issue a signature \u2014 the field is absent for that provider.\n *\n * Per Anthropic, thinking blocks MUST appear before any text/tool_use blocks\n * in an assistant message. Stream builders preserve that order.\n */\nexport interface ThinkingBlock {\n type: 'thinking';\n thinking: string;\n signature?: string | undefined;\n providerMeta?: Record<string, unknown>;\n}\n\nexport type ContentBlock = TextBlock | ToolUseBlock | ToolResultBlock | ImageBlock | ThinkingBlock;\n\nexport function isTextBlock(b: ContentBlock): b is TextBlock {\n return b.type === 'text';\n}\nexport function isToolUseBlock(b: ContentBlock): b is ToolUseBlock {\n return b.type === 'tool_use';\n}\nexport function isToolResultBlock(b: ContentBlock): b is ToolResultBlock {\n return b.type === 'tool_result';\n}\nexport function isImageBlock(b: ContentBlock): b is ImageBlock {\n return b.type === 'image';\n}\n", "import type { ContentBlock, TextBlock } from './blocks.js';\nimport type { ErrorCode } from './errors.js';\nimport { WrongStackError, ERROR_CODES } from './errors.js';\nimport type { Message } from './messages.js';\nimport type { Tool } from './tool.js';\nimport { truncate } from '../utils/string.js';\n\n/**\n * Token usage for a single provider call, normalized across providers.\n *\n * Disjoint semantics: the four fields never overlap. `input` is the count\n * of FRESH input tokens (billed at the full input rate); `cacheRead` and\n * `cacheWrite` are separate cached subsets each priced at their own rate.\n * The total context the model loaded for this turn is\n * `input + (cacheRead ?? 0) + (cacheWrite ?? 0)`.\n *\n * Provider quirks normalized at the adapter layer:\n * - Anthropic: returns `input_tokens` already disjoint from cache fields.\n * - OpenAI / OpenAI-compatible: `prompt_tokens` is the TOTAL including\n * cached portion; the adapter subtracts `cached_tokens` to stay disjoint.\n * - Google: `promptTokenCount` likewise includes cache; adapter subtracts\n * `cachedContentTokenCount`.\n *\n * Cost math and the context-fullness chip both depend on the disjoint\n * invariant \u2014 a TOTAL `input` plus a separate `cacheRead` count would bill\n * cached tokens twice and skew cache-hit-ratio reporting.\n */\nexport type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';\nexport type CacheTtl = '5m' | '1h';\n\n/**\n * Provider-agnostic response-format directive.\n *\n * - `{ type: 'text' }` \u2014 free-form text (default).\n * - `{ type: 'json_object' }` \u2014 valid JSON without a schema constraint.\n * - `{ type: 'json_schema', jsonSchema: { name, schema, strict? } }` \u2014 JSON\n * constrained to the supplied JSON Schema. The `strict` flag is\n * OpenAI-specific; Gemini ignores it in favour of `responseMimeType`.\n *\n * Each provider adapter maps this into its own wire format:\n * OpenAI \u2192 `response_format`\n * Gemini \u2192 `responseMimeType` + `responseSchema`\n * Anthropic \u2192 (not yet supported; uses tools for structured output)\n */\nexport interface JsonSchemaSpec {\n name: string;\n /** OpenAI-specific: enable strict schema adherence. */\n strict?: boolean | undefined;\n /** The JSON Schema object describing the expected shape. */\n schema: Record<string, unknown>;\n /** Optional human-readable description (OpenAI). */\n description?: string | undefined;\n}\n\nexport type ResponseFormat =\n | { type: 'text' }\n | { type: 'json_object' }\n | { type: 'json_schema'; jsonSchema: JsonSchemaSpec };\n\n/**\n * Safety category threshold pair used by Google Gemini's `safetySettings`.\n *\n * Categories: `HARM_CATEGORY_HARASSMENT`, `HARM_CATEGORY_HATE_SPEECH`,\n * `HARM_CATEGORY_SEXUALLY_EXPLICIT`, `HARM_CATEGORY_DANGEROUS_CONTENT`.\n *\n * Thresholds: `BLOCK_NONE`, `BLOCK_ONLY_HIGH`, `BLOCK_MEDIUM_AND_ABOVE`,\n * `BLOCK_LOW_AND_ABOVE`.\n */\nexport interface SafetySetting {\n category: string;\n threshold: string;\n}\n\nexport interface Usage {\n input: number;\n output: number;\n cacheRead?: number | undefined;\n /** Back-compat aggregate of all cache-write tokens. Prefer TTL-specific fields when present. */\n cacheWrite?: number | undefined;\n cacheWrite5m?: number | undefined;\n cacheWrite1h?: number | undefined;\n}\n\n/**\n * Effective prompt tokens loaded by the model for one request.\n *\n * Provider adapters normalize `Usage` to disjoint fields: `input` is fresh\n * full-rate tokens, `cacheRead` is cached prefix tokens, and `cacheWrite` is\n * the cache-written prefix segment. Context-window pressure cares about the\n * full prompt the model saw, not only the bill-at-full-rate slice.\n */\nexport function effectiveInputTokens(usage: Usage): number {\n return usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);\n}\n\nexport interface ReasoningRequest {\n enabled?: boolean | undefined;\n effort?: ReasoningEffort | undefined;\n preserve?: boolean | undefined;\n display?: 'summarized' | 'omitted' | undefined;\n}\n\nexport interface RequestCacheControl {\n ttl?: CacheTtl | undefined;\n}\n\nexport interface ReasoningConfig {\n default: 'enabled' | 'disabled' | 'adaptive' | 'always_on';\n disableSupported: boolean;\n effortSupported: boolean;\n effortLevels: ReasoningEffort[];\n preserveThinking: 'unsupported' | 'optional' | 'always_on';\n}\n\nexport interface Capabilities {\n tools: boolean;\n parallelTools: boolean;\n vision: boolean;\n streaming: boolean;\n promptCache: boolean;\n systemPrompt: boolean;\n jsonMode: boolean;\n reasoning: boolean;\n maxContext: number;\n /**\n * Maximum output tokens the model can produce in a single response.\n * Used as the default for `Request.maxTokens` when the caller doesn't\n * supply an explicit value \u2014 letting subagents run up to the model's\n * native ceiling instead of a fixed 8192 cap. Omit (undefined) to fall\n * back to a conservative default; populate per family in\n * `family-capabilities.ts` once you know the spec.\n */\n maxOutput?: number | undefined;\n cacheControl: 'native' | 'auto' | 'none';\n\n // \u2500\u2500 Extended parameter support (optional; family defaults in CAPABILITIES_BY_FAMILY) \u2500\u2500\n\n /** Model accepts `top_k` / `topK` sampling parameter. */\n topK?: boolean | undefined;\n /** Model accepts `frequency_penalty` / `frequencyPenalty` parameter. */\n frequencyPenalty?: boolean | undefined;\n /** Model accepts `presence_penalty` / `presencePenalty` parameter. */\n presencePenalty?: boolean | undefined;\n /** Model accepts `seed` parameter for deterministic generation. */\n seed?: boolean | undefined;\n /**\n * Model accepts JSON Schema / structured-output constraints\n * (OpenAI `response_format.json_schema`, Gemini `responseMimeType`+`responseSchema`).\n * Distinct from `jsonMode` (which is just a system-prompt hint).\n */\n structuredOutput?: boolean | undefined;\n /** Model supports log-probability output (`logprobs`, `top_logprobs`). */\n logprobs?: boolean | undefined;\n /** Model supports audio input/output modality. */\n audio?: boolean | undefined;\n /** Model supports the `n` parameter for multiple completions. */\n multipleCompletions?: boolean | undefined;\n}\n\nexport interface Request {\n model: string;\n system?: TextBlock[] | undefined;\n messages: Message[];\n tools?: Tool[] | undefined;\n /**\n * Cap on output tokens for this single response. Optional \u2014 when\n * omitted, the provider adapter falls back to its own\n * `capabilities.maxOutput` (which the catalog populates from\n * `ModelsDevModel.limit.output`). If neither is available, the\n * adapter applies a conservative 8192 safety net. Letting this stay\n * undefined at the call site means callers like Chimera can hand the\n * model its native output ceiling without hard-coding a number.\n */\n maxTokens?: number | undefined;\n temperature?: number | undefined;\n topP?: number | undefined;\n topK?: number | undefined;\n frequencyPenalty?: number | undefined;\n presencePenalty?: number | undefined;\n seed?: number | undefined;\n /**\n * End-user identifier for abuse monitoring and per-user rate limiting.\n * - Anthropic \u2192 `metadata.user_id`\n * - OpenAI \u2192 `user`\n * - Gemini \u2192 (not supported)\n */\n user?: string | undefined;\n /**\n * Number of response candidates to generate. Google Gemini supports\n * this via `generationConfig.candidateCount`. OpenAI does not have\n * an equivalent (`n` is conceptually similar but distinct).\n */\n candidateCount?: number | undefined;\n /**\n * Whether to return log probabilities for output tokens.\n * - OpenAI \u2192 `logprobs: boolean` (+ `topLogprobs: number`)\n * - Gemini \u2192 `generationConfig.logprobs: number` (how many top candidates)\n * Default undefined = no logprobs requested.\n */\n logprobs?: boolean | undefined;\n /**\n * Number of most probable tokens to return log probabilities for\n * (OpenAI `top_logprobs`). Only meaningful when `logprobs` is true.\n * Range: 0-20. Gemini ignores this (uses `logprobs` as the count).\n */\n topLogprobs?: number | undefined;\n stopSequences?: string[] | undefined;\n toolChoice?: 'auto' | 'required' | 'none' | { type: 'tool' | undefined; name: string };\n reasoning?: ReasoningRequest | undefined;\n cache?: RequestCacheControl | undefined;\n /**\n * Structured-output / response-format directive.\n * When set, the provider adapter maps this to its native response-format\n * parameter (OpenAI `response_format`, Gemini `responseMimeType`, etc.).\n * The model must advertise `capabilities.structuredOutput` for this to be\n * honoured; unsupported models will likely 400 or ignore it.\n */\n responseFormat?: ResponseFormat | undefined;\n /**\n * Safety category thresholds for filtering harmful content.\n * - Gemini \u2192 top-level `safetySettings` array with `{ category, threshold }`\n * - OpenAI \u2192 not supported (uses server-side moderation)\n * - Anthropic \u2192 not supported\n */\n safetySettings?: SafetySetting[] | undefined;\n}\n\nexport type StopReason = 'end_turn' | 'tool_use' | 'max_tokens' | 'stop_sequence' | 'refusal';\n\nexport interface Response {\n content: ContentBlock[];\n stopReason: StopReason;\n usage: Usage;\n model: string;\n}\n\nexport type StreamEvent =\n | { type: 'message_start'; model: string }\n | {\n type: 'content_block_start';\n kind: 'text' | 'tool_use' | 'thinking';\n id?: string | undefined;\n name?: string | undefined;\n }\n | { type: 'content_block_stop'; index: number }\n | { type: 'text_delta'; text: string }\n | { type: 'tool_use_start'; id: string; name: string }\n | { type: 'tool_use_input_delta'; id: string; partial: string }\n | { type: 'tool_use_stop'; id: string; input: unknown; providerMeta?: Record<string, unknown> }\n | { type: 'thinking_start'; providerMeta?: Record<string, unknown> }\n | { type: 'thinking_delta'; text: string }\n | { type: 'thinking_signature'; signature: string }\n | { type: 'thinking_stop' }\n | { type: 'message_stop'; stopReason: StopReason; usage: Usage };\n\nexport interface Provider {\n readonly id: string;\n readonly capabilities: Capabilities;\n /** Canonical streaming entry point. `complete()` defaults to a wrapper that\n * aggregates this stream \u2014 providers may override for non-streaming wires. */\n stream(req: Request, opts: { signal: AbortSignal }): AsyncIterable<StreamEvent>;\n complete(req: Request, opts: { signal: AbortSignal }): Promise<Response>;\n}\n\n/**\n * Structured body parsed from a provider's HTTP error response. Populated\n * best-effort: providers return JSON shaped differently (Anthropic uses\n * `{error: {type, message}}`, OpenAI uses `{error: {message, code}}`,\n * Google uses `{error: {status, message}}`), so the fields here are the\n * intersection that's usable for rendering and routing.\n */\nexport interface ProviderErrorBody {\n /** Provider-specific kind, e.g. \"overloaded_error\", \"rate_limit_error\", \"invalid_request_error\". */\n type?: string | undefined;\n /** Human-readable explanation from the provider. */\n message?: string | undefined;\n /** Provider request id, when present in the body or headers. */\n requestId?: string | undefined;\n /** Parsed Retry-After header (or equivalent body hint) in milliseconds. */\n retryAfterMs?: number | undefined;\n /** The raw response body (truncated to ~2 KB), kept for debugging. */\n raw?: string | undefined;\n /** True when `raw` was truncated; check `rawLength` for the original size. */\n truncated?: boolean | undefined;\n /** Original length of the response body in bytes, when `truncated` is true. */\n rawLength?: number | undefined;\n}\n\n/**\n * Canonical provider-failure taxonomy. Computed ONCE at error-construction\n * time (`classifyProviderError`) and carried on `ProviderError.kind` so\n * every downstream consumer \u2014 retry policy, cross-provider fallback,\n * recovery strategies, the subagent error classifier \u2014 branches on the\n * same classification instead of re-deriving it from status codes and\n * message regexes. When a new provider's error format needs special\n * handling, this module is the only place to teach it.\n */\nexport type ProviderErrorKind =\n | 'rate_limit' // 429 / rate_limit_error \u2014 back off (honour Retry-After), then failover\n | 'overloaded' // 529 / overloaded_error \u2014 retry with backoff, then failover\n | 'server' // other 5xx \u2014 retry same provider\n | 'timeout' // 408 request timeout\n | 'network' // status 0 \u2014 connection/DNS failure before a response arrived\n | 'stream_hang' // 599 sentinel \u2014 stream stalled mid-response (StreamHangError)\n | 'auth' // 401/403 \u2014 key invalid/expired; retrying without action is pointless\n | 'context_overflow' // 413 or an overflow-shaped 4xx \u2014 compact, don't retry as-is\n | 'content_filter' // provider refused on policy grounds \u2014 a sibling model may pass, but the `content_filter_reroute` recovery strategy owns that hop, NOT the fallback engine (which surfaces this kind)\n | 'invalid_request' // other 4xx \u2014 request is malformed; retrying won't help\n | 'unknown';\n\n/**\n * Overflow-shaped provider messages. Union of the patterns previously\n * scattered across `error-handler.ts` and `coordinator/error-classifier.ts`\n * (which had drifted apart) \u2014 keep additions here, nowhere else.\n */\nconst CONTEXT_OVERFLOW_RE =\n /context.length|context.window|max.*tokens?.*exceeded|prompt is too long|too long|exceeds the context|\\btokens\\b.*exceed|context_length_exceeded/i;\n\n/** Content-policy refusals surfaced as HTTP errors (Azure/OpenAI `content_filter`, etc.). */\nconst CONTENT_FILTER_RE = /content.(filter|policy|moderation)|safety (system|filter)/i;\n\n/**\n * Classify a provider HTTP failure into the canonical taxonomy from its\n * status code plus the parsed error body (and, for message-only errors\n * without a structured body, the error message itself). Pure and total \u2014\n * always returns a kind, never throws.\n */\nexport function classifyProviderError(\n status: number,\n body?: ProviderErrorBody,\n message?: string,\n): ProviderErrorKind {\n const type = body?.type;\n if (status === 0) return 'network';\n if (status === 408) return 'timeout';\n if (status === 599) return 'stream_hang';\n if (type === 'rate_limit_error' || status === 429) return 'rate_limit';\n if (type === 'overloaded_error' || status === 529) return 'overloaded';\n if (status >= 500) return 'server';\n if (\n type === 'authentication_error' ||\n type === 'permission_error' ||\n status === 401 ||\n status === 403\n ) {\n return 'auth';\n }\n const text = [message, body?.message, type, body?.raw].filter(Boolean).join('\\n');\n if (type === 'content_filter' || CONTENT_FILTER_RE.test(text)) return 'content_filter';\n if (status === 413 || (status >= 400 && CONTEXT_OVERFLOW_RE.test(text))) {\n return 'context_overflow';\n }\n if (status >= 400) return 'invalid_request';\n return 'unknown';\n}\n\n/**\n * Whether a kind is worth retrying against the SAME provider/model.\n * `context_overflow` is deliberately false \u2014 the request must shrink first;\n * `auth`/`invalid_request`/`content_filter` won't improve on replay.\n *\n * Exhaustive by construction (`Record<ProviderErrorKind, \u2026>`): adding a new\n * kind refuses to compile until it is classified here. Every kind\u2192X mapping\n * in the codebase follows this drift-guard pattern \u2014 see also KIND_TO_CODE\n * below, DefaultRetryPolicy.maxAttempts, fallback-model shouldFallback, and\n * the coordinator's providerErrorToSubagentError.\n */\nexport function isRetryableKind(kind: ProviderErrorKind): boolean {\n return RETRYABLE_BY_KIND[kind];\n}\n\nconst RETRYABLE_BY_KIND: Record<ProviderErrorKind, boolean> = {\n rate_limit: true,\n overloaded: true,\n server: true,\n timeout: true,\n network: true,\n stream_hang: true,\n auth: false,\n context_overflow: false,\n content_filter: false,\n invalid_request: false,\n unknown: false,\n};\n\n/**\n * Whether a kind is worth HOPPING to a different provider/model \u2014 the gate for\n * the cross-provider fallback engine (agent-loop extension AND the one-shot\n * orchestrator both branch on this ONE table, so their behavior can't drift).\n *\n * A distinct question from {@link isRetryableKind} (retry the SAME model):\n * a hop only helps for capacity/transport failures. Request-shaped failures\n * surface instead \u2014 `context_overflow` needs compaction, `content_filter` is\n * owned by the `content_filter_reroute` recovery strategy, and `auth` /\n * `invalid_request` are user-actionable and would fail identically on a hop.\n * The value set is currently identical to the retryable set, but it is kept as\n * its own table on purpose: the two answer different questions and may diverge.\n *\n * Exhaustive by construction (`Record<ProviderErrorKind, \u2026>`) \u2014 a new kind\n * refuses to compile until it is classified here.\n */\nexport function isFallbackWorthy(kind: ProviderErrorKind): boolean {\n return FALLBACK_WORTHY_BY_KIND[kind];\n}\n\nconst FALLBACK_WORTHY_BY_KIND: Record<ProviderErrorKind, boolean> = {\n rate_limit: true,\n overloaded: true,\n server: true,\n timeout: true,\n network: true,\n stream_hang: true,\n auth: false,\n context_overflow: false,\n content_filter: false,\n invalid_request: false,\n unknown: false,\n};\n\nexport class ProviderError extends WrongStackError {\n public readonly status: number;\n public readonly retryable: boolean;\n public readonly providerId: string;\n /** Canonical failure classification \u2014 see {@link ProviderErrorKind}. */\n public readonly kind: ProviderErrorKind;\n public readonly body?: ProviderErrorBody | undefined;\n\n constructor(\n message: string,\n status: number,\n retryable: boolean,\n providerId: string,\n opts: {\n body?: ProviderErrorBody | undefined;\n cause?: unknown | undefined;\n /** Override the computed classification (rarely needed \u2014 tests, custom wires). */\n kind?: ProviderErrorKind | undefined;\n } = {},\n ) {\n const kind = opts.kind ?? classifyProviderError(status, opts.body, message);\n super({\n message,\n code: kindToCode(kind),\n subsystem: 'provider',\n severity: status >= 500 ? 'error' : 'warning',\n recoverable: retryable,\n context: { providerId, status },\n cause: opts.cause,\n });\n this.name = 'ProviderError';\n this.status = status;\n this.retryable = retryable;\n this.providerId = providerId;\n this.kind = kind;\n this.body = opts.body;\n }\n\n /**\n * Render a one-line, user-facing description. Designed for the CLI/TUI\n * status line and the agent's retry warning. Avoids dumping raw JSON\n * (which is what users see today when a 529 lands and the log message\n * includes the full `{\"type\":\"error\",...}` body).\n *\n * Examples:\n * \"minimax-coding-plan overloaded (529): High traffic detected. Upgrade for highspeed model. [req 06534785201de9c0\u2026]\"\n * \"openai rate limited (429): Retry after 12s\"\n * \"anthropic invalid request (400): messages.0.role must be one of 'user'|'assistant'\"\n * \"groq HTTP 500 (server error)\"\n */\n override describe(): string {\n const kind = describeStatus(this.status, this.body?.type);\n const head = `${this.providerId} ${kind}`;\n const detail = this.body?.message?.trim();\n const reqId = this.body?.requestId\n ? ` [req ${this.body.requestId.slice(0, 16)}${this.body.requestId.length > 16 ? '\u2026' : ''}]`\n : '';\n if (detail && detail.length > 0) {\n return `${head}: ${truncate(detail, 240)}${reqId}`;\n }\n return `${head}${reqId}`;\n }\n}\n\nfunction describeStatus(status: number, type?: string): string {\n if (status === 0) return 'network error';\n if (status === 599) return `stream hang (${status})`;\n if (type === 'overloaded_error' || status === 529) return `overloaded (${status})`;\n if (type === 'rate_limit_error' || status === 429) return `rate limited (${status})`;\n if (type === 'authentication_error' || status === 401) return `auth failed (${status})`;\n if (type === 'permission_error' || status === 403) return `forbidden (${status})`;\n if (type === 'not_found_error' || status === 404) return `not found (${status})`;\n if (type === 'content_filter') return `content filtered (${status})`;\n if (type === 'invalid_request_error' || status === 400) return `invalid request (${status})`;\n if (status === 408) return `timeout (${status})`;\n if (status >= 500 && status < 600) return `HTTP ${status} (server error)`;\n if (type) return `${type} (${status})`;\n return `HTTP ${status}`;\n}\n\n/**\n * Thrown when the provider stream stops delivering data mid-response.\n * This is distinct from a network error (TCP reset, DNS failure) \u2014 the\n * connection is established and the response started, but chunks stopped\n * arriving before the stream completed.\n *\n * Status 599 is used as a sentinel to distinguish stream hangs from\n * regular HTTP errors while still flowing through ProviderError-based\n * retry and fallback infrastructure.\n */\nexport class StreamHangError extends ProviderError {\n /** Name of the provider that hung, e.g. \"zai\", \"anthropic\". */\n public readonly hungProviderId: string;\n /** Model that was being called when the hang occurred. */\n public readonly hungModel: string;\n /** How long (ms) we waited for the next chunk before declaring a hang. */\n public readonly hangTimeoutMs: number;\n /** How many bytes were received before the hang. */\n public readonly bytesReceived: number;\n /** Elapsed time (ms) from the start of the stream until the hang. */\n public readonly elapsedMs: number;\n\n constructor(opts: {\n providerId: string;\n model: string;\n hangTimeoutMs: number;\n bytesReceived: number;\n elapsedMs: number;\n cause?: unknown | undefined;\n }) {\n super(\n `Stream hang: ${opts.providerId}/${opts.model} \u2014 no data for ${opts.hangTimeoutMs}ms after ${opts.bytesReceived} bytes (${opts.elapsedMs}ms elapsed)`,\n 599,\n true, // always retryable\n opts.providerId,\n {\n body: {\n message: `Stream stalled after ${opts.elapsedMs}ms, ${opts.bytesReceived} bytes received`,\n },\n cause: opts.cause,\n },\n );\n this.name = 'StreamHangError';\n this.hungProviderId = opts.providerId;\n this.hungModel = opts.model;\n this.hangTimeoutMs = opts.hangTimeoutMs;\n this.bytesReceived = opts.bytesReceived;\n this.elapsedMs = opts.elapsedMs;\n }\n}\n\n/** Exhaustive kind \u2192 ErrorCode mapping \u2014 new kinds must be added here or the\n * file stops compiling (same drift-guard pattern as RETRYABLE_BY_KIND). */\nconst KIND_TO_CODE: Record<ProviderErrorKind, ErrorCode> = {\n network: ERROR_CODES.PROVIDER_NETWORK_ERROR,\n timeout: ERROR_CODES.PROVIDER_NETWORK_ERROR,\n rate_limit: ERROR_CODES.PROVIDER_RATE_LIMITED,\n auth: ERROR_CODES.PROVIDER_AUTH_FAILED,\n overloaded: ERROR_CODES.PROVIDER_OVERLOADED,\n context_overflow: ERROR_CODES.PROVIDER_CONTEXT_OVERFLOW,\n server: ERROR_CODES.PROVIDER_SERVER_ERROR,\n stream_hang: ERROR_CODES.PROVIDER_SERVER_ERROR,\n content_filter: ERROR_CODES.PROVIDER_INVALID_REQUEST,\n invalid_request: ERROR_CODES.PROVIDER_INVALID_REQUEST,\n unknown: ERROR_CODES.PROVIDER_INVALID_REQUEST,\n};\n\nfunction kindToCode(kind: ProviderErrorKind): ErrorCode {\n return KIND_TO_CODE[kind];\n}\n", "/**\n * Cross-provider fallback model extension.\n *\n * Lives in core so EVERY agent surface can reuse it: the CLI leader, the CLI\n * director/host subagent factory, and the runtime light subagent factory (used\n * by standalone SDD runs). It wraps the provider runner and, when the active\n * model 429s / overloads / stream-hangs, rotates through a fallback chain. The\n * chain is recomputed from live config every turn, so changes take effect\n * without a restart; an empty chain makes the wrapper a no-op.\n *\n * Moved here from `@wrongstack/cli` (it only ever depended on core types) so the\n * runtime light factory can wire fallbacks for SDD worker subagents.\n */\nimport type { AgentExtension } from '../extension/extension-points.js';\nimport type { EventBus } from '../kernel/events.js';\nimport type { Config, ProviderConfig } from '../types/config.js';\n\nfunction visibleProviderModels(config: Config, providerId: string, providerModels: string[]): string[] {\n const entry = config.providers?.[providerId];\n return entry?.models !== undefined ? [...entry.models] : providerModels;\n}\nimport type { Logger } from '../types/logger.js';\nimport { isFallbackWorthy, type Provider, ProviderError } from '../types/provider.js';\n\nexport interface FallbackModelDeps {\n /** Returns the live config (re-read each turn so `/model` switches are honored). */\n getConfig: () => Config;\n /**\n * Builds a credential-resolved Provider for a provider id (alias-resolved),\n * WITHOUT persisting anything to config/configStore. Supplied by the boot\n * path, which shares this with the `/model` switch logic. May be async \u2014 the\n * subagent host resolves a provider's real context window asynchronously.\n */\n buildProvider: (providerId: string, modelId?: string | undefined) => Provider | Promise<Provider>;\n /**\n * Called after the active model changes (a fallback hop or the primary\n * restore) so the host can refresh the auto-compaction / context-window\n * denominator \u2014 important when a fallback crosses to a smaller-window model.\n */\n onModelSwitch?: (providerId: string, modelId: string) => void | Promise<void>;\n events: EventBus;\n /** Optional \u2014 warnings about un-buildable fallback providers. */\n logger?: Logger | undefined;\n /**\n * Base cooldown after the configured primary fails with a fallback-worthy\n * error. While active, `beforeRun` leaves the context on the working fallback\n * instead of retrying the primary at the start of every turn. Default: 60s.\n * Set 0 to preserve the legacy \"probe primary every turn\" behavior.\n */\n primaryCooldownMs?: number | undefined;\n /**\n * Maximum exponential cooldown for repeated failed primary probes. Default:\n * 10 minutes. Ignored when `primaryCooldownMs` is 0.\n */\n primaryCooldownMaxMs?: number | undefined;\n /** Test hook for deterministic cooldown assertions. */\n now?: (() => number) | undefined;\n}\n\ninterface ModelRef {\n provider?: string | undefined;\n model: string;\n}\n\n/** Parse a fallback entry: `model`, `provider/model`, or `provider model`. */\nexport function parseModelRef(ref: string): ModelRef {\n const trimmed = ref.trim();\n const slash = trimmed.indexOf('/');\n if (slash !== -1) {\n // An empty provider (leading slash, e.g. \"/gpt\") means \"use the primary\n // provider\" \u2014 collapse to undefined so the `?? cfg.provider` fallback fires.\n return {\n provider: trimmed.slice(0, slash) || undefined,\n model: trimmed.slice(slash + 1).trim(),\n };\n }\n const parts = trimmed.split(/\\s+/);\n if (parts.length >= 2) {\n return { provider: parts[0], model: parts.slice(1).join(' ') };\n }\n return { model: trimmed };\n}\n\nexport function formatModelRef(ref: ModelRef, defaultProvider?: string | undefined): string {\n const provider = ref.provider ?? defaultProvider;\n return provider ? `${provider}/${ref.model}` : ref.model;\n}\n\nexport function normalizeModelRef(ref: string, defaultProvider?: string | undefined): string {\n const parsed = parseModelRef(ref);\n return formatModelRef(parsed, defaultProvider);\n}\n\nexport function fallbackProfileChain(config: Config, profileName: string | undefined): string[] {\n if (!profileName) return [];\n const chain = config.fallbackProfiles?.[profileName];\n return Array.isArray(chain) ? chain.filter((ref) => parseModelRef(ref).model) : [];\n}\n\n/**\n * Check if an error should trigger a fallback. Returns the status for\n * logging, or null if the error doesn't warrant a fallback attempt.\n *\n * Branches on the canonical `ProviderError.kind`: capacity/availability\n * failures (rate limit, overload, server error, stream hang, timeout,\n * network) are worth trying on another provider; request-shaped failures\n * (auth, invalid request, context overflow, content filter) would fail\n * identically anywhere \u2014 or need a different remedy (compaction, key fix) \u2014\n * so they surface instead.\n */\nfunction shouldFallback(err: unknown): number | null {\n if (!(err instanceof ProviderError)) return null;\n return isFallbackWorthy(err.kind) ? err.status : null;\n}\n\n/** A provider is usable as a fallback target when it has a stored key, a key\n * list, or a populated env var. Mirrors `setmodel.providerHasKey`. */\nfunction providerHasKey(entry: ProviderConfig | undefined): boolean {\n if (!entry) return false;\n if (typeof entry.apiKey === 'string' && entry.apiKey.length > 0) return true;\n if (Array.isArray(entry.apiKeys) && entry.apiKeys.some((k) => k?.apiKey)) return true;\n if (Array.isArray(entry.envVars) && entry.envVars.some((v) => !!process.env[v])) return true;\n return false;\n}\n\n/** Hard ceiling on the auto-derived chain so we don't burn through a dozen\n * models on a transient blip. */\nconst SMART_DEFAULT_MAX = 4;\n\n/**\n * Derive a fallback chain from the configured providers when the user has not\n * set an explicit `fallbackModels` list. Picks declared models from every\n * keyed provider \u2014 same-provider alternatives first (same key, cheapest\n * failover), then cross-provider \u2014 excluding the active leader model. Returns\n * `[]` when nothing usable is configured (e.g. providers with no `models`\n * list), in which case the extension is a no-op.\n */\nexport function smartDefaultFallbackChain(config: Config): string[] {\n const leaderProvider = config.provider;\n const leaderModel = config.model;\n const providers = config.providers ?? {};\n const favoriteSet = new Set(\n (config.favoriteModels ?? []).map((ref) => normalizeModelRef(ref, leaderProvider)),\n );\n const hasFavorites = favoriteSet.size > 0;\n const favoritesOnly = config.favoriteModelsOnly === true;\n const seen = new Set<string>();\n const favoriteRefs: string[] = [];\n const sameProvider: string[] = [];\n const crossProvider: string[] = [];\n\n // Leader provider first so its other models lead the chain.\n const ids = Object.keys(providers).sort((a, b) =>\n a === leaderProvider ? -1 : b === leaderProvider ? 1 : a.localeCompare(b),\n );\n\n for (const id of ids) {\n const entry = providers[id];\n if (!providerHasKey(entry)) continue;\n const models = visibleProviderModels(config, id, entry?.models ?? []);\n for (const model of models) {\n if (id === leaderProvider && model === leaderModel) continue;\n const ref = `${id}/${model}`;\n if (seen.has(ref)) continue;\n seen.add(ref);\n if (favoriteSet.has(ref)) {\n favoriteRefs.push(ref);\n continue;\n }\n if (favoritesOnly && hasFavorites) continue;\n (id === leaderProvider ? sameProvider : crossProvider).push(ref);\n }\n }\n return [...favoriteRefs, ...sameProvider, ...crossProvider].slice(0, SMART_DEFAULT_MAX);\n}\n\n/**\n * The effective fallback chain for a turn: the explicit `fallbackModels` list\n * when non-empty, otherwise the smart default (unless `fallbackAuto` is off).\n */\nexport function effectiveFallbackChain(config: Config): string[] {\n const explicit = config.fallbackModels ?? [];\n const filteredExplicit = explicit.filter((ref) => {\n const parsed = parseModelRef(ref);\n if (!parsed.model) return false;\n const providerId = parsed.provider ?? config.provider;\n const entry = config.providers?.[providerId];\n if (!entry?.models) return true;\n return entry.models.includes(parsed.model);\n });\n if (filteredExplicit.length > 0) return filteredExplicit;\n if (config.fallbackAuto === false) return [];\n return smartDefaultFallbackChain(config);\n}\n\nconst DEFAULT_PRIMARY_COOLDOWN_MS = 60_000;\nconst DEFAULT_PRIMARY_COOLDOWN_MAX_MS = 10 * 60_000;\n\nfunction sameTarget(\n a: { providerId: string; model: string } | undefined,\n b: { providerId: string; model: string },\n): boolean {\n return !!a && a.providerId === b.providerId && a.model === b.model;\n}\n\nfunction fallbackCandidates(config: Config, current: { providerId: string; model: string }): string[] {\n const chain = effectiveFallbackChain(config);\n const configuredPrimary = primaryTarget(config);\n const manualTarget = sameTarget(configuredPrimary, current)\n ? []\n : [formatModelRef({ provider: configuredPrimary.providerId, model: configuredPrimary.model })];\n const seen = new Set<string>();\n return [...manualTarget, ...chain].filter((ref) => {\n const normalized = normalizeModelRef(ref, config.provider);\n if (seen.has(normalized)) return false;\n seen.add(normalized);\n return true;\n });\n}\n\nconst primaryTarget = (cfg: Config) => ({ providerId: cfg.provider, model: cfg.model });\n\nfunction maxContextOf(provider: Provider): number {\n const max = provider.capabilities.maxContext;\n return typeof max === 'number' && Number.isFinite(max) ? max : 0;\n}\n\nfunction contextWindowWarning(\n currentProvider: Provider,\n nextProvider: Provider,\n currentTokens: unknown,\n): { fromMaxContext: number; toMaxContext: number; currentTokens?: number | undefined } | undefined {\n const fromMaxContext = maxContextOf(currentProvider);\n const toMaxContext = maxContextOf(nextProvider);\n if (fromMaxContext <= 0 || toMaxContext <= 0 || toMaxContext >= fromMaxContext) return undefined;\n return {\n fromMaxContext,\n toMaxContext,\n ...(typeof currentTokens === 'number' && currentTokens > 0 ? { currentTokens } : {}),\n };\n}\n\n/**\n * Build the cross-provider fallback extension. Always returns an extension \u2014\n * the effective chain (`effectiveFallbackChain`) is recomputed every turn from\n * the live config, so a chain that is empty at boot but populated later (via\n * `/fallback add` or the smart default kicking in once a key is added) takes\n * effect WITHOUT a restart. An empty chain makes the wrapper a no-op (it just\n * rethrows the original error).\n *\n * Mechanism (see plan): wraps the provider runner. The inner runner already\n * applies the per-model retry policy (backoff, up to 5 tries for 429), so the\n * fallback only engages AFTER the active model's own retries are exhausted.\n * Because the wrapper resolves within a single provider call, it does not\n * consume the agent loop's `recoveryRetries` budget \u2014 chains longer than two\n * entries work. `beforeRun` keeps the last working fallback while the primary\n * is cooling down, then restores the configured primary for a half-open probe.\n */\nexport function createFallbackModelExtension(deps: FallbackModelDeps): AgentExtension {\n // True when a prior turn left the live context on a fallback model.\n let dirty = false;\n let primaryFailureStreak = 0;\n let blockedPrimary: { providerId: string; model: string } | undefined;\n let primaryBlockedUntil = 0;\n\n const now = () => deps.now?.() ?? Date.now();\n const cooldownBase = () => Math.max(0, deps.primaryCooldownMs ?? DEFAULT_PRIMARY_COOLDOWN_MS);\n const cooldownMax = () => Math.max(cooldownBase(), deps.primaryCooldownMaxMs ?? DEFAULT_PRIMARY_COOLDOWN_MAX_MS);\n const primaryInCooldown = (cfg: Config) =>\n sameTarget(blockedPrimary, primaryTarget(cfg)) && now() < primaryBlockedUntil;\n\n const markPrimaryFailure = (cfg: Config) => {\n const primary = primaryTarget(cfg);\n primaryFailureStreak = sameTarget(blockedPrimary, primary) ? primaryFailureStreak + 1 : 1;\n blockedPrimary = primary;\n const base = cooldownBase();\n if (base <= 0) {\n primaryBlockedUntil = 0;\n return;\n }\n const multiplier = 2 ** Math.max(0, primaryFailureStreak - 1);\n primaryBlockedUntil = now() + Math.min(cooldownMax(), base * multiplier);\n };\n\n const resetPrimaryLadder = (cfg: Config) => {\n if (!sameTarget(blockedPrimary, primaryTarget(cfg))) return;\n primaryFailureStreak = 0;\n blockedPrimary = undefined;\n primaryBlockedUntil = 0;\n };\n\n return {\n name: 'fallback-model',\n\n beforeRun: async (ctx) => {\n if (!dirty) return;\n const cfg = deps.getConfig();\n if (primaryInCooldown(cfg)) return;\n try {\n ctx.provider = await deps.buildProvider(cfg.provider, cfg.model);\n ctx.model = cfg.model;\n await deps.onModelSwitch?.(cfg.provider, cfg.model);\n // The next provider call is the half-open primary probe. If it\n // succeeds, the wrapper resets the ladder; if it fails, the catch path\n // marks a longer cooldown and rotates back through the chain.\n primaryBlockedUntil = 0;\n } catch (err) {\n deps.logger?.warn(\n `fallback-model: could not restore primary \"${cfg.provider}/${cfg.model}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n markPrimaryFailure(cfg);\n return;\n }\n dirty = false;\n },\n\n wrapProviderRunner: async (ctx, request, inner) => {\n try {\n const response = await inner(ctx, request);\n const cfg = deps.getConfig();\n if (ctx.provider.id === cfg.provider && ctx.model === cfg.model) {\n resetPrimaryLadder(cfg);\n }\n return response;\n } catch (firstErr) {\n let lastErr: unknown = firstErr;\n const cfg = deps.getConfig();\n const current = { providerId: ctx.provider.id, model: ctx.model };\n const chain = fallbackCandidates(cfg, current);\n if (shouldFallback(firstErr) !== null && ctx.provider.id === cfg.provider && ctx.model === cfg.model) {\n markPrimaryFailure(cfg);\n }\n\n for (const ref of chain) {\n const status = shouldFallback(lastErr);\n if (status === null) break; // not a fallback-worthy error\n\n const parsed = parseModelRef(ref);\n if (!parsed.model) continue;\n const targetProviderId = parsed.provider ?? cfg.provider;\n if (targetProviderId === ctx.provider.id && parsed.model === ctx.model) continue;\n if (\n primaryInCooldown(cfg) &&\n targetProviderId === cfg.provider &&\n parsed.model === cfg.model\n ) {\n continue;\n }\n\n const from = { providerId: ctx.provider.id, model: ctx.model };\n\n let nextProvider: Provider;\n try {\n nextProvider = await deps.buildProvider(targetProviderId, parsed.model);\n } catch (err) {\n deps.logger?.warn(\n `fallback-model: skipping \"${ref}\" \u2014 cannot build provider \"${targetProviderId}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n continue;\n }\n\n const providerSwitched = nextProvider.id !== from.providerId;\n const warning = contextWindowWarning(ctx.provider, nextProvider, ctx.lastRequestTokens);\n ctx.provider = nextProvider;\n ctx.model = parsed.model;\n request.model = parsed.model;\n dirty = true;\n await deps.onModelSwitch?.(targetProviderId, parsed.model);\n\n deps.events.emit('provider.fallback', {\n sessionId: ctx.session?.id,\n from,\n to: { providerId: nextProvider.id, model: parsed.model },\n status,\n providerSwitched,\n ...(warning ? { contextWindowWarning: warning } : {}),\n });\n\n try {\n return await inner(ctx, request);\n } catch (err) {\n lastErr = err;\n }\n }\n\n throw lastErr;\n }\n },\n };\n}\n", "import { isTextBlock } from '../types/blocks.js';\nimport type { Message } from '../types/messages.js';\nimport type { OneShotLLMInput, OneShotLLMResult, OneShotOrchestratorOptions } from '../types/one-shot-llm.js';\nimport {\n isFallbackWorthy,\n type Provider,\n ProviderError,\n type Request,\n type Response,\n} from '../types/provider.js';\nimport { effectiveFallbackChain, fallbackProfileChain, parseModelRef } from '../core/fallback-model.js';\n\n/**\n * Default timeout for one-shot LLM calls when the caller doesn't specify one.\n */\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/**\n * Default max output tokens when the caller doesn't specify.\n */\nconst DEFAULT_MAX_TOKENS = 1024;\n\ntype CallAttempt =\n | { response: Response; error?: never; fallbackEligible: false }\n | { response?: never; error: unknown; fallbackEligible: boolean };\n\n/**\n * OneShotOrchestrator \u2014 a stateless, reusable utility for making single\n * LLM calls with provider resolution, fallback chains, and structured results.\n *\n * Usage:\n * ```ts\n * const oneShot = new OneShotOrchestrator({ buildProvider, getConfig });\n * const result = await oneShot.call({\n * system: 'You are a helpful assistant.',\n * userPrompt: 'Summarize this conversation.',\n * model: 'deepseek-chat',\n * fallbackProfile: 'summary',\n * });\n * console.log(result.text);\n * ```\n *\n * Every method is stateless \u2014 a single instance can be shared across\n * the entire process lifetime.\n */\nexport class OneShotOrchestrator {\n private readonly opts: OneShotOrchestratorOptions;\n\n constructor(opts: OneShotOrchestratorOptions) {\n this.opts = opts;\n }\n\n /**\n * Make a one-shot LLM call. Resolves provider+model, applies fallback\n * chain on transient errors, and returns a structured result.\n *\n * Never throws \u2014 all errors are captured in `OneShotLLMResult.error`.\n */\n async call(input: OneShotLLMInput): Promise<OneShotLLMResult> {\n const startedAt = performance.now();\n const config = this.opts.getConfig();\n\n // \u2500\u2500 1. Resolve target provider + model \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const target = this.resolveTarget(input, config);\n if (!target) {\n return {\n text: '',\n model: input.model ?? config.model ?? 'unknown',\n provider: input.providerId ?? config.provider ?? 'unknown',\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: Math.round(performance.now() - startedAt),\n fromFallback: false,\n error: 'No provider or model could be resolved. Check your config.',\n };\n }\n\n let provider: Provider;\n try {\n provider = await this.opts.buildProvider(target.providerId, target.model);\n } catch (err) {\n return {\n text: '',\n model: target.model,\n provider: target.providerId,\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: Math.round(performance.now() - startedAt),\n fromFallback: false,\n error: `Cannot build provider \"${target.providerId}\": ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n // \u2500\u2500 2. Build the request \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const request = this.buildRequest(input, target.model);\n const signal = this.resolveSignal(input);\n\n // \u2500\u2500 3. Build fallback chain \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const chain = this.resolveFallbackChain(input, config, target);\n\n // \u2500\u2500 4. Attempt the call with fallback rotation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n let servingProviderId = provider.id;\n let servingModel = target.model;\n let fromFallback = false;\n\n const primaryAttempt = await this.tryCall(provider, request, signal);\n let result = primaryAttempt.response;\n let lastError = primaryAttempt.error;\n let fallbackEligible = primaryAttempt.fallbackEligible;\n\n if (!result && fallbackEligible && chain.length > 0) {\n for (const ref of chain) {\n const parsed = parseModelRef(ref);\n if (!parsed.model) continue;\n const fbProviderId = parsed.provider ?? config.provider;\n if (fbProviderId === provider.id && parsed.model === target.model) continue;\n\n servingProviderId = fbProviderId;\n servingModel = parsed.model;\n\n let fbProvider: Provider;\n try {\n fbProvider = await this.opts.buildProvider(fbProviderId, parsed.model);\n } catch (err) {\n lastError = err;\n continue;\n }\n\n servingProviderId = fbProvider.id;\n const attempt = await this.tryCall(\n fbProvider,\n this.buildRequest(input, parsed.model),\n signal,\n );\n if (attempt.response) {\n result = attempt.response;\n fromFallback = true;\n break;\n }\n\n lastError = attempt.error;\n fallbackEligible = attempt.fallbackEligible;\n if (!fallbackEligible) break;\n }\n }\n\n // \u2500\u2500 5. Build the final result \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const elapsed = Math.round(performance.now() - startedAt);\n\n if (result) {\n const textBlocks = result.content.filter(isTextBlock);\n const text = textBlocks.map((b) => b.text).join('\\n').trim();\n\n return {\n text: text || '(empty response)',\n model: result.model ?? servingModel,\n provider: servingProviderId,\n tokens: {\n input: result.usage?.input ?? 0,\n output: result.usage?.output ?? 0,\n total: (result.usage?.input ?? 0) + (result.usage?.output ?? 0),\n },\n durationMs: elapsed,\n fromFallback,\n stopReason: result.stopReason,\n };\n }\n\n // Total failure \u2014 all providers exhausted or non-retryable error.\n return {\n text: '',\n model: servingModel,\n provider: servingProviderId,\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: elapsed,\n fromFallback,\n error: lastError instanceof Error ? lastError.message : String(lastError ?? 'Unknown error'),\n };\n }\n\n // \u2500\u2500 Private helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /**\n * Resolve the target provider + model from input + config.\n * Priority: role-based routing > explicit providerId+model > defaults.\n */\n private resolveTarget(\n input: OneShotLLMInput,\n config: import('../types/config.js').Config,\n ): { providerId: string; model: string } | undefined {\n // Role-based routing via ModelRouter (highest priority)\n if (input.role && this.opts.modelRouter) {\n const pick = this.opts.modelRouter.pickForTask(input.role, '');\n if (pick) {\n return { providerId: pick.provider, model: pick.model };\n }\n }\n\n // Explicit providerId + model\n if (input.providerId && input.model) {\n return { providerId: input.providerId, model: input.model };\n }\n\n // Model only \u2014 use default provider\n if (input.model) {\n return { providerId: config.provider, model: input.model };\n }\n\n // Provider only \u2014 use default model\n if (input.providerId) {\n return { providerId: input.providerId, model: config.model };\n }\n\n // Neither \u2014 use session defaults\n if (config.provider && config.model) {\n return { providerId: config.provider, model: config.model };\n }\n\n return undefined;\n }\n\n /**\n * Build a Provider Request from the input.\n */\n private buildRequest(input: OneShotLLMInput, model: string): Request {\n const messages: Message[] = [...(input.messages ?? [])];\n if (input.userPrompt) {\n messages.push({ role: 'user', content: input.userPrompt });\n }\n\n const system = asTextBlocks(input.system);\n\n return {\n model,\n ...(system.length > 0 ? { system } : {}),\n messages,\n maxTokens: input.maxTokens ?? DEFAULT_MAX_TOKENS,\n ...(input.temperature !== undefined ? { temperature: input.temperature } : {}),\n ...(input.responseFormat ? { responseFormat: input.responseFormat } : {}),\n };\n }\n\n /**\n * Resolve the abort signal. Provider calls always receive the per-call\n * timeout, composed with external cancellation when the caller supplies it.\n */\n private resolveSignal(input: OneShotLLMInput): AbortSignal {\n const timeoutSignal = AbortSignal.timeout(input.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n return input.signal ? AbortSignal.any([input.signal, timeoutSignal]) : timeoutSignal;\n }\n\n /**\n * Build the fallback model chain from input + config + current target.\n */\n private resolveFallbackChain(\n input: OneShotLLMInput,\n config: import('../types/config.js').Config,\n target: { providerId: string; model: string },\n ): string[] {\n // Explicit chain wins\n if (input.fallbackModels && input.fallbackModels.length > 0) {\n return input.fallbackModels;\n }\n\n // Named profile\n if (input.fallbackProfile) {\n const profile = fallbackProfileChain(config, input.fallbackProfile);\n if (profile.length > 0) return profile;\n }\n\n // Smart default from config (same logic as fallback-model.ts)\n if (config.fallbackAuto !== false) {\n return effectiveFallbackChain(config).filter((ref) => {\n const parsed = parseModelRef(ref);\n const fbProvider = parsed.provider ?? config.provider;\n return !(fbProvider === target.providerId && parsed.model === target.model);\n });\n }\n\n return [];\n }\n\n /** Attempt a provider call while preserving the actual failure for callers. */\n private async tryCall(\n provider: Provider,\n request: Request,\n signal: AbortSignal,\n ): Promise<CallAttempt> {\n try {\n return {\n response: await provider.complete(request, { signal }),\n fallbackEligible: false,\n };\n } catch (err) {\n return {\n error: err,\n fallbackEligible:\n !signal.aborted &&\n (!(err instanceof ProviderError) || isFallbackWorthy(err.kind)),\n };\n }\n }\n}\n\n/**\n * Normalize system prompt to TextBlock[].\n */\nfunction asTextBlocks(system: string | import('../types/blocks.js').TextBlock[] | undefined): import('../types/blocks.js').TextBlock[] {\n if (!system) return [];\n if (Array.isArray(system)) return system;\n return [{ type: 'text', text: system }];\n}\n", "import type { JSONSchema, Tool } from '../types/tool.js';\nimport type { OneShotLLMInput, OneShotLLMResult, OneShotOrchestratorOptions } from '../types/one-shot-llm.js';\nimport { OneShotOrchestrator } from '../execution/one-shot-llm.js';\n\n/**\n * Tool name for the one-shot LLM tool.\n * Register in ToolRegistry as `llm` so any agent can call it.\n */\nexport const ONE_SHOT_LLM_TOOL_NAME = 'llm';\n\n/**\n * Options for creating the LLM tool.\n * Mirrors OneShotOrchestratorOptions \u2014 the tool wraps an internal orchestrator.\n * When `defaultProvider` and `defaultModel` are not set, callers MUST\n * provide `providerId` and `model` explicitly.\n */\nexport interface CreateOneShotLLMToolOptions {\n buildProvider: OneShotOrchestratorOptions['buildProvider'];\n getConfig: OneShotOrchestratorOptions['getConfig'];\n modelRouter?: OneShotOrchestratorOptions['modelRouter'];\n logger?: OneShotOrchestratorOptions['logger'];\n /**\n * Default provider to use when the caller doesn't specify one.\n * When absent, callers MUST provide `providerId` explicitly.\n */\n defaultProvider?: string | undefined;\n /**\n * Default model to use when the caller doesn't specify one.\n * When absent, callers MUST provide `model` explicitly.\n */\n defaultModel?: string | undefined;\n}\n\n/**\n * JSON Schema for the llm tool input.\n */\nconst INPUT_SCHEMA: JSONSchema = {\n type: 'object',\n properties: {\n system: {\n type: 'string',\n description: 'System prompt guiding the LLM behaviour.',\n },\n userPrompt: {\n type: 'string',\n description: 'Single user turn \u2014 appended as a user-role message.',\n },\n messages: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n role: {\n type: 'string',\n enum: ['system', 'user', 'assistant', 'tool'],\n description: 'Message author role.',\n },\n content: {\n type: 'string',\n description: 'Message text content.',\n },\n },\n required: ['role', 'content'],\n additionalProperties: true,\n },\n description: 'Conversation messages for few-shot examples or multi-turn context. Appended before userPrompt when both are set.',\n },\n model: {\n type: 'string',\n description: 'Model id (e.g. \"deepseek-chat\", \"gpt-4o-mini\"). Defaults to session model.',\n },\n providerId: {\n type: 'string',\n description: 'Provider id (e.g. \"anthropic\", \"openai\"). Defaults to session provider.',\n },\n role: {\n type: 'string',\n description: 'Roster role for model-matrix routing. Overrides model/providerId.',\n },\n fallbackProfile: {\n type: 'string',\n description: 'Named fallback profile from config.fallbackProfiles.',\n },\n fallbackModels: {\n type: 'array',\n items: { type: 'string' },\n description: 'Explicit fallback model chain (e.g. [\"anthropic/claude-haiku\", \"openai/gpt-4o-mini\"]).',\n },\n maxTokens: {\n type: 'number',\n description: 'Maximum output tokens (default 1024).',\n },\n responseFormat: {\n oneOf: [\n { type: 'string', enum: ['text', 'json_object'], description: 'Simple response format.' },\n {\n type: 'object',\n properties: {\n type: { type: 'string', enum: ['json_schema'], description: 'Structured JSON output.' },\n json_schema: {\n type: 'object',\n description: 'JSON Schema definition for the structured output.',\n },\n },\n required: ['type'],\n additionalProperties: false,\n },\n ],\n description: 'Response format: \"text\" (default), \"json_object\", or { type: \"json_schema\", json_schema: {...} }.',\n },\n temperature: {\n type: 'number',\n description: 'Sampling temperature.',\n },\n timeoutMs: {\n type: 'number',\n description: 'Hard timeout in ms (default 30s).',\n },\n },\n};\n\n/**\n * Create the `llm` tool \u2014 a general-purpose one-shot LLM invocation tool\n * that any agent can call. Wraps OneShotOrchestrator internally for\n * provider resolution, fallback chain support, and structured results.\n *\n * Usage from an agent:\n * ```\n * llm({\n * system: \"You are a helpful assistant.\",\n * userPrompt: \"Summarize this conversation.\",\n * model: \"deepseek-chat\",\n * maxTokens: 1024,\n * })\n * ```\n *\n * Register with the ToolRegistry and it becomes available everywhere:\n * ```ts\n * toolRegistry.register(createOneShotLLMTool({ buildProvider, getConfig }));\n * ```\n */\nexport function createOneShotLLMTool(opts: CreateOneShotLLMToolOptions): Tool<OneShotLLMInput, OneShotLLMResult> {\n const orchestrator = new OneShotOrchestrator({\n buildProvider: opts.buildProvider,\n getConfig: opts.getConfig,\n modelRouter: opts.modelRouter,\n logger: opts.logger,\n });\n\n return {\n name: ONE_SHOT_LLM_TOOL_NAME,\n description:\n 'Make a one-shot LLM call with a system prompt and user input. ' +\n 'Supports provider selection, model routing by role, fallback chains, and timeout. ' +\n 'Returns the response text, model info, token usage, and whether a fallback was used. ' +\n 'Use this for summarization, classification, extraction, and any single-turn LLM task.',\n usageHint:\n 'Provide `system` for the instruction and `userPrompt` for the input. ' +\n 'Either set `model`+`providerId`, or have defaults configured on the tool. ' +\n 'Set `fallbackProfile` or `fallbackModels` for resilience. ' +\n 'Check `error` on the result for failure details.',\n inputSchema: INPUT_SCHEMA,\n permission: 'auto',\n mutating: false,\n\n async execute(\n input: OneShotLLMInput,\n _ctx,\n { signal }: { signal: AbortSignal },\n ): Promise<OneShotLLMResult> {\n // If the caller didn't provide model/providerId, check for tool-level defaults.\n // This prevents silent fallback to session config which may not be intended.\n if (!input.model && !input.providerId && !opts.defaultModel && !opts.defaultProvider) {\n return {\n text: '',\n model: '',\n provider: '',\n tokens: { input: 0, output: 0, total: 0 },\n durationMs: 0,\n fromFallback: false,\n error:\n 'Either provide `model` and `providerId` in the call, or configure ' +\n 'defaultProvider/defaultModel when creating the tool. The `llm` tool ' +\n 'does not infer provider/model from the session by default.',\n };\n }\n\n // Apply defaults when caller omits model/providerId but defaults are configured.\n const effectiveInput: OneShotLLMInput = {\n ...input,\n signal: input.signal ? AbortSignal.any([input.signal, signal]) : signal,\n model: input.model ?? opts.defaultModel,\n providerId: input.providerId ?? opts.defaultProvider,\n };\n\n return orchestrator.call(effectiveInput);\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["fs", "stat", "resolve", "path", "path", "path", "path", "INPUT_SCHEMA"]
|
|
7
7
|
}
|