@goondocks/myco 0.17.1 → 0.17.2
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/README.md +1 -1
- package/dist/{agent-run-BGW4TY3D.js → agent-run-7AYHXIEF.js} +6 -6
- package/dist/{agent-tasks-XUJ6FTPL.js → agent-tasks-UUIFKBD4.js} +6 -6
- package/dist/{chunk-VGVRBSLC.js → chunk-25WHTV4N.js} +2 -2
- package/dist/{chunk-ZUSTCXHT.js → chunk-3NCVCGUZ.js} +3 -3
- package/dist/chunk-5NFJTZ64.js +14 -0
- package/dist/chunk-5NFJTZ64.js.map +1 -0
- package/dist/{chunk-2WRXLYG6.js → chunk-5ZISXCDC.js} +2 -2
- package/dist/{chunk-6SDC6V3N.js → chunk-7DAH5GLC.js} +1 -5
- package/dist/{chunk-6SDC6V3N.js.map → chunk-7DAH5GLC.js.map} +1 -1
- package/dist/{chunk-KOTFMGL5.js → chunk-BZDZORVP.js} +4 -4
- package/dist/{chunk-KKEMVH6D.js → chunk-C3C5QVLK.js} +2 -2
- package/dist/{chunk-XQHL4GMO.js → chunk-CTF7TQMJ.js} +3 -3
- package/dist/{chunk-CPL76CYD.js → chunk-DT42247G.js} +3 -3
- package/dist/{chunk-VQQ57UPG.js → chunk-F6C4IC6R.js} +4 -4
- package/dist/{chunk-VQQ57UPG.js.map → chunk-F6C4IC6R.js.map} +1 -1
- package/dist/{chunk-SODRR3HE.js → chunk-GFR542SM.js} +1 -1
- package/dist/chunk-GFR542SM.js.map +1 -0
- package/dist/{chunk-QQ7CXA7Q.js → chunk-HPZ7YAMA.js} +95 -10
- package/dist/{chunk-QQ7CXA7Q.js.map → chunk-HPZ7YAMA.js.map} +1 -1
- package/dist/{chunk-GBYLHPML.js → chunk-IGBHLFV5.js} +2 -2
- package/dist/{chunk-DKSQMH5X.js → chunk-ML6GTPZU.js} +2 -2
- package/dist/{chunk-KQOII5RU.js → chunk-NUSTG3BH.js} +3 -3
- package/dist/{chunk-2IJ6C63F.js → chunk-RKPTMHED.js} +2 -2
- package/dist/{chunk-YTOD6L6N.js → chunk-RMJPQZGF.js} +97 -7
- package/dist/chunk-RMJPQZGF.js.map +1 -0
- package/dist/{chunk-LA7NDX3J.js → chunk-SI5BBQAT.js} +2 -2
- package/dist/{chunk-OGNEW5CN.js → chunk-UTLWSKDV.js} +2 -2
- package/dist/{chunk-FEX6ALLH.js → chunk-XD3NEN3Q.js} +29 -3
- package/dist/chunk-XD3NEN3Q.js.map +1 -0
- package/dist/{chunk-N6JNOSBQ.js → chunk-XZWFMMJR.js} +3 -3
- package/dist/{chunk-UDBCAFXS.js → chunk-ZSJPI5MS.js} +2 -2
- package/dist/{cli-353VNZIY.js → cli-WJVYP2QT.js} +39 -39
- package/dist/{client-7KJ453V4.js → client-LZ3ZR4HC.js} +4 -4
- package/dist/{config-K3CJEFFO.js → config-ZQIMG3FB.js} +4 -4
- package/dist/{detect-providers-OE6HWW3M.js → detect-providers-C64L3QET.js} +4 -4
- package/dist/{doctor-RYFP7ABA.js → doctor-XEPBNHM3.js} +11 -11
- package/dist/doctor-XEPBNHM3.js.map +1 -0
- package/dist/{executor-YOKYS7OT.js → executor-NXKJU5KW.js} +25 -106
- package/dist/executor-NXKJU5KW.js.map +1 -0
- package/dist/{init-XR2JZWY2.js → init-BHVQAQ27.js} +54 -72
- package/dist/init-BHVQAQ27.js.map +1 -0
- package/dist/{llm-PGETQHZ2.js → llm-KTD6SR55.js} +4 -7
- package/dist/{loader-J56KP27U.js → loader-NEX3UF6U.js} +3 -3
- package/dist/{loader-AVWL7PNO.js → loader-SHRKUKOS.js} +3 -3
- package/dist/{main-6DGPZXRF.js → main-YFVBIRRK.js} +87 -57
- package/dist/main-YFVBIRRK.js.map +1 -0
- package/dist/{open-P7YEH7UJ.js → open-2U7ZRGA3.js} +10 -9
- package/dist/open-2U7ZRGA3.js.map +1 -0
- package/dist/open-browser-EBKBAYSM.js +9 -0
- package/dist/{post-compact-WPS4SONO.js → post-compact-QIBMEWL3.js} +6 -6
- package/dist/{post-tool-use-5WLLRGZ5.js → post-tool-use-ICGFXDVY.js} +5 -5
- package/dist/{post-tool-use-failure-6C6HSBHI.js → post-tool-use-failure-C7TLH3XQ.js} +6 -6
- package/dist/{pre-compact-Z4E4JLAK.js → pre-compact-IF7K4TQK.js} +6 -6
- package/dist/{provider-check-CESRPIY5.js → provider-check-LTLQ6BUZ.js} +4 -4
- package/dist/{registry-SPKP2WLI.js → registry-TFQ22Z7N.js} +4 -4
- package/dist/{remove-B2PFVQXK.js → remove-FBGM2QVJ.js} +7 -7
- package/dist/{resolution-events-CLDXZF67.js → resolution-events-HGKIJOTA.js} +4 -4
- package/dist/{restart-XAJDOL3E.js → restart-TQEECRNW.js} +7 -7
- package/dist/{search-ERTCTAQ3.js → search-NN5FC4Z6.js} +7 -7
- package/dist/{server-LXUA7XUQ.js → server-XMWJ4GF7.js} +4 -4
- package/dist/{session-433T6V3C.js → session-GLPAFYPO.js} +8 -8
- package/dist/{session-end-4Y5VY4OI.js → session-end-TI3ILRBC.js} +5 -5
- package/dist/{session-start-3STH4HFL.js → session-start-PJLJDVJJ.js} +10 -10
- package/dist/{setup-llm-UBBSQWX5.js → setup-llm-AQSWLXCZ.js} +8 -8
- package/dist/src/cli.js +1 -1
- package/dist/src/daemon/main.js +1 -1
- package/dist/src/hooks/post-tool-use.js +1 -1
- package/dist/src/hooks/session-end.js +1 -1
- package/dist/src/hooks/session-start.js +1 -1
- package/dist/src/hooks/stop.js +1 -1
- package/dist/src/hooks/user-prompt-submit.js +1 -1
- package/dist/src/mcp/server.js +1 -1
- package/dist/{stats-3NW7PGQK.js → stats-BISBIBXZ.js} +8 -8
- package/dist/{stop-L7BLMHUD.js → stop-47BJ42EO.js} +5 -5
- package/dist/{stop-failure-P5MYHGAZ.js → stop-failure-VU5BTLWX.js} +6 -6
- package/dist/{subagent-start-AIEFG4HA.js → subagent-start-SPTKQRHU.js} +6 -6
- package/dist/{subagent-stop-TZ62BSNI.js → subagent-stop-UU75BYLC.js} +6 -6
- package/dist/{task-completed-ZKVCUBCP.js → task-completed-MVDO7TZF.js} +6 -6
- package/dist/{team-WHZW6IFU.js → team-7X64J4Y6.js} +4 -4
- package/dist/ui/assets/index-CRmkSi63.css +1 -0
- package/dist/ui/assets/index-rpmSpJpm.js +842 -0
- package/dist/ui/index.html +2 -2
- package/dist/{update-P7GIQLIV.js → update-DA7VEXOS.js} +7 -7
- package/dist/{user-prompt-submit-4J7ZW6X3.js → user-prompt-submit-ADZ4NTVO.js} +5 -5
- package/dist/{verify-PSERIZPF.js → verify-QYSERHF7.js} +5 -8
- package/dist/{verify-PSERIZPF.js.map → verify-QYSERHF7.js.map} +1 -1
- package/dist/{version-OHJ5ZLHX.js → version-A72TAL2J.js} +2 -2
- package/package.json +6 -2
- package/dist/chunk-FEX6ALLH.js.map +0 -1
- package/dist/chunk-KGL5QSDN.js +0 -66
- package/dist/chunk-KGL5QSDN.js.map +0 -1
- package/dist/chunk-SODRR3HE.js.map +0 -1
- package/dist/chunk-U3SSOSIR.js +0 -26
- package/dist/chunk-U3SSOSIR.js.map +0 -1
- package/dist/chunk-Y7QCKCEJ.js +0 -26
- package/dist/chunk-Y7QCKCEJ.js.map +0 -1
- package/dist/chunk-YTOD6L6N.js.map +0 -1
- package/dist/doctor-RYFP7ABA.js.map +0 -1
- package/dist/executor-YOKYS7OT.js.map +0 -1
- package/dist/init-XR2JZWY2.js.map +0 -1
- package/dist/init-wizard-5CH2FD76.js +0 -294
- package/dist/init-wizard-5CH2FD76.js.map +0 -1
- package/dist/main-6DGPZXRF.js.map +0 -1
- package/dist/open-P7YEH7UJ.js.map +0 -1
- package/dist/openai-embeddings-LZKY6RV5.js +0 -14
- package/dist/openrouter-UTOZG6Z5.js +0 -14
- package/dist/ui/assets/index-2UyTdjlV.js +0 -842
- package/dist/ui/assets/index-Cts1wLEW.css +0 -1
- package/dist/version-OHJ5ZLHX.js.map +0 -1
- /package/dist/{agent-run-BGW4TY3D.js.map → agent-run-7AYHXIEF.js.map} +0 -0
- /package/dist/{agent-tasks-XUJ6FTPL.js.map → agent-tasks-UUIFKBD4.js.map} +0 -0
- /package/dist/{chunk-VGVRBSLC.js.map → chunk-25WHTV4N.js.map} +0 -0
- /package/dist/{chunk-ZUSTCXHT.js.map → chunk-3NCVCGUZ.js.map} +0 -0
- /package/dist/{chunk-2WRXLYG6.js.map → chunk-5ZISXCDC.js.map} +0 -0
- /package/dist/{chunk-KOTFMGL5.js.map → chunk-BZDZORVP.js.map} +0 -0
- /package/dist/{chunk-KKEMVH6D.js.map → chunk-C3C5QVLK.js.map} +0 -0
- /package/dist/{chunk-XQHL4GMO.js.map → chunk-CTF7TQMJ.js.map} +0 -0
- /package/dist/{chunk-CPL76CYD.js.map → chunk-DT42247G.js.map} +0 -0
- /package/dist/{chunk-GBYLHPML.js.map → chunk-IGBHLFV5.js.map} +0 -0
- /package/dist/{chunk-DKSQMH5X.js.map → chunk-ML6GTPZU.js.map} +0 -0
- /package/dist/{chunk-KQOII5RU.js.map → chunk-NUSTG3BH.js.map} +0 -0
- /package/dist/{chunk-2IJ6C63F.js.map → chunk-RKPTMHED.js.map} +0 -0
- /package/dist/{chunk-LA7NDX3J.js.map → chunk-SI5BBQAT.js.map} +0 -0
- /package/dist/{chunk-OGNEW5CN.js.map → chunk-UTLWSKDV.js.map} +0 -0
- /package/dist/{chunk-N6JNOSBQ.js.map → chunk-XZWFMMJR.js.map} +0 -0
- /package/dist/{chunk-UDBCAFXS.js.map → chunk-ZSJPI5MS.js.map} +0 -0
- /package/dist/{cli-353VNZIY.js.map → cli-WJVYP2QT.js.map} +0 -0
- /package/dist/{client-7KJ453V4.js.map → client-LZ3ZR4HC.js.map} +0 -0
- /package/dist/{config-K3CJEFFO.js.map → config-ZQIMG3FB.js.map} +0 -0
- /package/dist/{detect-providers-OE6HWW3M.js.map → detect-providers-C64L3QET.js.map} +0 -0
- /package/dist/{llm-PGETQHZ2.js.map → llm-KTD6SR55.js.map} +0 -0
- /package/dist/{loader-AVWL7PNO.js.map → loader-NEX3UF6U.js.map} +0 -0
- /package/dist/{loader-J56KP27U.js.map → loader-SHRKUKOS.js.map} +0 -0
- /package/dist/{openai-embeddings-LZKY6RV5.js.map → open-browser-EBKBAYSM.js.map} +0 -0
- /package/dist/{post-compact-WPS4SONO.js.map → post-compact-QIBMEWL3.js.map} +0 -0
- /package/dist/{post-tool-use-5WLLRGZ5.js.map → post-tool-use-ICGFXDVY.js.map} +0 -0
- /package/dist/{post-tool-use-failure-6C6HSBHI.js.map → post-tool-use-failure-C7TLH3XQ.js.map} +0 -0
- /package/dist/{pre-compact-Z4E4JLAK.js.map → pre-compact-IF7K4TQK.js.map} +0 -0
- /package/dist/{openrouter-UTOZG6Z5.js.map → provider-check-LTLQ6BUZ.js.map} +0 -0
- /package/dist/{provider-check-CESRPIY5.js.map → registry-TFQ22Z7N.js.map} +0 -0
- /package/dist/{remove-B2PFVQXK.js.map → remove-FBGM2QVJ.js.map} +0 -0
- /package/dist/{registry-SPKP2WLI.js.map → resolution-events-HGKIJOTA.js.map} +0 -0
- /package/dist/{restart-XAJDOL3E.js.map → restart-TQEECRNW.js.map} +0 -0
- /package/dist/{search-ERTCTAQ3.js.map → search-NN5FC4Z6.js.map} +0 -0
- /package/dist/{server-LXUA7XUQ.js.map → server-XMWJ4GF7.js.map} +0 -0
- /package/dist/{session-433T6V3C.js.map → session-GLPAFYPO.js.map} +0 -0
- /package/dist/{session-end-4Y5VY4OI.js.map → session-end-TI3ILRBC.js.map} +0 -0
- /package/dist/{session-start-3STH4HFL.js.map → session-start-PJLJDVJJ.js.map} +0 -0
- /package/dist/{setup-llm-UBBSQWX5.js.map → setup-llm-AQSWLXCZ.js.map} +0 -0
- /package/dist/{stats-3NW7PGQK.js.map → stats-BISBIBXZ.js.map} +0 -0
- /package/dist/{stop-L7BLMHUD.js.map → stop-47BJ42EO.js.map} +0 -0
- /package/dist/{stop-failure-P5MYHGAZ.js.map → stop-failure-VU5BTLWX.js.map} +0 -0
- /package/dist/{subagent-start-AIEFG4HA.js.map → subagent-start-SPTKQRHU.js.map} +0 -0
- /package/dist/{subagent-stop-TZ62BSNI.js.map → subagent-stop-UU75BYLC.js.map} +0 -0
- /package/dist/{task-completed-ZKVCUBCP.js.map → task-completed-MVDO7TZF.js.map} +0 -0
- /package/dist/{team-WHZW6IFU.js.map → team-7X64J4Y6.js.map} +0 -0
- /package/dist/{update-P7GIQLIV.js.map → update-DA7VEXOS.js.map} +0 -0
- /package/dist/{user-prompt-submit-4J7ZW6X3.js.map → user-prompt-submit-ADZ4NTVO.js.map} +0 -0
- /package/dist/{resolution-events-CLDXZF67.js.map → version-A72TAL2J.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agent/executor.ts","../src/agent/tools.ts","../src/agent/tools/read-tools.ts","../src/db/queries/agent-state.ts","../src/agent/tools/types.ts","../src/agent/tools/write-tools.ts","../src/agent/tools/observability-tools.ts","../src/agent/tools/skill-tools.ts","../src/agent/tools/skill-validator.ts","../src/agent/context.ts","../src/agent/orchestrator.ts","../src/intelligence/response.ts","../src/agent/context-queries.ts","../src/agent/provider.ts","../src/agent/ollama-context.ts","../src/agent/wave-computation.ts"],"sourcesContent":["/**\n * Agent executor.\n *\n * Orchestrates a single agent run:\n * 1. Initializes the database for the vault.\n * 2. Resolves effective config (definition + agent DB overrides + task).\n * 3. Guards against concurrent runs for the same agent.\n * 4. Creates a run record in the database.\n * 5. Builds the task prompt (vault context + task + optional instruction).\n * 6. Executes the Claude Agent SDK query — single call for flat tasks,\n * wave-based parallel execution for phased tasks.\n * 7. Records cost/token data and marks the run completed or failed.\n */\n\nimport crypto from 'node:crypto';\nimport { resolve } from 'node:path';\nimport { epochSeconds, DEFAULT_AGENT_ID, MS_PER_SECOND, PHASE_SUMMARY_MAX_CHARS } from '@myco/constants.js';\nimport { errorMessage as toErrorMessage } from '@myco/utils/error-message.js';\nimport { initDatabase, vaultDbPath, getDatabase } from '@myco/db/client.js';\nimport { createSchema } from '@myco/db/schema.js';\nimport { getDefaultTask } from '@myco/db/queries/tasks.js';\nimport {\n insertRun,\n updateRunStatus,\n getRunningRunForTask,\n STATUS_RUNNING,\n STATUS_COMPLETED,\n STATUS_FAILED,\n} from '@myco/db/queries/runs.js';\nimport { loadSystemPrompt } from './loader.js';\nimport { createVaultToolServer, createScopedVaultToolServer } from './tools.js';\nimport { buildVaultContext } from './context.js';\nimport { composeOrchestratorPrompt, parseOrchestratorPlan, applyDirectives, DEFAULT_ORCHESTRATOR_MAX_TURNS } from './orchestrator.js';\nimport { executeContextQueries } from './context-queries.js';\nimport { buildPhaseEnv } from './provider.js';\nimport { resolveRunConfig } from './config-resolver.js';\nimport { resolveOllamaContextVariants } from './ollama-context.js';\nimport { computeWaves, phaseSessionId } from './wave-computation.js';\nimport { SKILL_GENERATE_TASK } from './instruction-builders.js';\nimport type { ContextQueryResult } from './context-queries.js';\nimport type { ProviderConfig } from './types.js';\nimport type {\n RunOptions,\n AgentRunResult,\n EffectiveConfig,\n PhaseDefinition,\n PhaseResult,\n} from './types.js';\n\n// Re-export computeWaves for backward compatibility (tests import from executor)\nexport { computeWaves } from './wave-computation.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Run status returned when a concurrent run is already active. */\nconst STATUS_SKIPPED = 'skipped';\n\n/** Reason string when skipping due to concurrency guard. */\nconst SKIP_REASON_ALREADY_RUNNING = 'already_running';\n\n/** Section header for vault context in the composed prompt. */\nconst PROMPT_SECTION_TASK = '## Task: ';\n\n/** Section header for user instruction in the composed prompt. */\nconst PROMPT_SECTION_INSTRUCTION = '## User Instruction';\n\n/** Separator between prompt sections. */\nconst PROMPT_SECTION_SEPARATOR = '\\n\\n';\n\n/** MCP server name for the vault tool server. */\nconst MCP_SERVER_NAME = 'myco-vault';\n\n/** Whether to persist the agent session to disk. */\nconst PERSIST_SESSION = true;\n\n/** Header for prior phase context in phased prompts. */\nconst PROMPT_SECTION_PRIOR_PHASES = '## Prior Phase Results';\n\n/** Header for the current phase in phased prompts. */\nconst PROMPT_SECTION_CURRENT_PHASE = '## Current Phase: ';\n\n// ---------------------------------------------------------------------------\n// Per-turn tool-call debug logging\n// ---------------------------------------------------------------------------\n//\n// When MYCO_AGENT_DEBUG=1, every tool_use and tool_result inside a phase is\n// logged to stdout with a short input/output preview. This is intended for\n// diagnosing turn-budget exhaustion: it surfaces rejection loops, malformed\n// tool-call retries, and unexpected exploration that the per-phase\n// `num_turns` summary alone cannot explain.\n//\n// The daemon sets this env var automatically when log_level is \"debug\"\n// (see src/daemon/main.ts). It can also be set manually for ad-hoc runs.\n\nconst DEBUG_TOOL_CALLS = process.env.MYCO_AGENT_DEBUG === '1';\n\n/** Max chars to print from tool input/output payloads. */\nconst TOOL_DEBUG_PREVIEW_CHARS = 240;\n\ninterface SdkContentBlock {\n type: string;\n name?: string;\n input?: unknown;\n tool_use_id?: string;\n content?: unknown;\n is_error?: boolean;\n}\n\ninterface SdkMessageWithContent {\n message?: { content?: SdkContentBlock[] };\n}\n\nfunction previewPayload(value: unknown): string {\n const str = typeof value === 'string' ? value : JSON.stringify(value);\n if (str === undefined) return '';\n return str.length > TOOL_DEBUG_PREVIEW_CHARS\n ? `${str.slice(0, TOOL_DEBUG_PREVIEW_CHARS)}…(${str.length - TOOL_DEBUG_PREVIEW_CHARS} more chars)`\n : str;\n}\n\nfunction logToolUseBlocks(phaseName: string, message: unknown): void {\n if (!DEBUG_TOOL_CALLS) return;\n const blocks = (message as SdkMessageWithContent).message?.content;\n if (!Array.isArray(blocks)) return;\n for (const block of blocks) {\n if (block.type === 'tool_use') {\n console.log(\n `[agent:debug] ${phaseName} tool_use: ${block.name ?? 'unknown'} input=${previewPayload(block.input)}`,\n );\n }\n }\n}\n\nfunction logToolResultBlocks(phaseName: string, message: unknown): void {\n if (!DEBUG_TOOL_CALLS) return;\n const blocks = (message as SdkMessageWithContent).message?.content;\n if (!Array.isArray(blocks)) return;\n for (const block of blocks) {\n if (block.type === 'tool_result') {\n const flag = block.is_error ? ' [ERROR]' : '';\n console.log(\n `[agent:debug] ${phaseName} tool_result${flag}: ${previewPayload(block.content)}`,\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Prompt composition\n// ---------------------------------------------------------------------------\n\n/**\n * Build the full task prompt from vault context, task definition, and\n * optional user instruction.\n *\n * Task prompts support template variables:\n * - `{{session_id}}` — replaced with the session ID from instruction (if present)\n * - `{{instruction}}` — the raw user instruction text\n */\nexport function composeTaskPrompt(\n vaultContext: string,\n taskDisplayName: string,\n taskPrompt: string,\n instruction?: string,\n): string {\n // Extract session_id from instruction if it contains one (UUID pattern)\n const sessionIdMatch = instruction?.match(/\\b([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\b/i);\n const sessionId = sessionIdMatch?.[1] ?? '';\n\n // Template variable substitution in task prompt\n let resolvedPrompt = taskPrompt;\n resolvedPrompt = resolvedPrompt.replace(/\\{\\{session_id\\}\\}/g, sessionId);\n resolvedPrompt = resolvedPrompt.replace(/\\{\\{instruction\\}\\}/g, instruction ?? '');\n\n const parts = [\n vaultContext,\n `${PROMPT_SECTION_TASK}${taskDisplayName}\\n${resolvedPrompt}`,\n ];\n\n if (instruction) {\n parts.push(`${PROMPT_SECTION_INSTRUCTION}\\n${instruction}`);\n }\n\n return parts.join(PROMPT_SECTION_SEPARATOR);\n}\n\n/**\n * Build the prompt for a single phase in a phased execution.\n *\n * Includes vault context, the task overview, prior phase summaries,\n * and the current phase instructions.\n */\nexport function composePhasePrompt(\n vaultContext: string,\n taskDisplayName: string,\n taskOverview: string,\n phase: PhaseDefinition,\n priorPhaseResults: PhaseResult[],\n instruction?: string,\n): string {\n const parts = [\n vaultContext,\n `${PROMPT_SECTION_TASK}${taskDisplayName}\\n${taskOverview}`,\n ];\n\n if (instruction) {\n parts.push(`${PROMPT_SECTION_INSTRUCTION}\\n${instruction}`);\n }\n\n // Include prior phase results as context (unless the phase opts out)\n if (priorPhaseResults.length > 0 && !phase.skipPriorContext) {\n const summaries = priorPhaseResults.map((pr) => {\n const truncated = pr.summary.length > PHASE_SUMMARY_MAX_CHARS\n ? pr.summary.slice(0, PHASE_SUMMARY_MAX_CHARS) + '...'\n : pr.summary;\n return `### ${pr.name} (${pr.status})\\n${truncated}`;\n });\n parts.push(`${PROMPT_SECTION_PRIOR_PHASES}\\n${summaries.join('\\n\\n')}`);\n }\n\n // Current phase instructions\n parts.push(`${PROMPT_SECTION_CURRENT_PHASE}${phase.name}\\n${phase.prompt}`);\n\n return parts.join(PROMPT_SECTION_SEPARATOR);\n}\n\n// ---------------------------------------------------------------------------\n// Single-phase execution helper\n// ---------------------------------------------------------------------------\n\n/**\n * Execute a single phase query.\n *\n * Isolated helper that runs one query() call with scoped tools,\n * provider env, and phase-specific config.\n */\nasync function executePhase(\n query: typeof import('@anthropic-ai/claude-agent-sdk').query,\n phasePrompt: string,\n phaseModel: string,\n systemPrompt: string,\n toolServer: ReturnType<typeof createScopedVaultToolServer>,\n phase: PhaseDefinition,\n env: Record<string, string | undefined> | undefined,\n sessionId?: string,\n abortController?: AbortController,\n): Promise<PhaseResult> {\n let phaseCost = 0;\n let phaseTokens = 0;\n let phaseTurns = 0;\n let agenticTurns = 0;\n let phaseSummary = '';\n\n try {\n for await (const message of query({\n prompt: phasePrompt,\n options: {\n model: phaseModel,\n systemPrompt,\n mcpServers: { [MCP_SERVER_NAME]: toolServer },\n strictMcpConfig: true,\n maxTurns: phase.maxTurns,\n permissionMode: 'bypassPermissions',\n allowDangerouslySkipPermissions: true,\n persistSession: PERSIST_SESSION,\n env,\n tools: [],\n ...(sessionId ? { sessionId } : {}),\n ...(abortController ? { abortController } : {}),\n },\n })) {\n if (message.type === 'assistant') {\n agenticTurns++;\n logToolUseBlocks(phase.name, message);\n }\n if (message.type === 'user') {\n logToolResultBlocks(phase.name, message);\n }\n if (message.type === 'result') {\n phaseCost = message.total_cost_usd ?? 0;\n phaseTokens =\n (message.usage.input_tokens ?? 0) + (message.usage.output_tokens ?? 0);\n phaseTurns = message.num_turns ?? 0;\n if ('result' in message && typeof message.result === 'string') {\n phaseSummary = message.result;\n }\n }\n }\n\n if (phase.maxTurns) {\n console.log(\n `[agent] Phase \"${phase.name}\": num_turns=${phaseTurns}, assistant_msgs=${agenticTurns}, budget=${phase.maxTurns}`,\n );\n }\n\n if (phase.required && phaseTurns === 0) {\n console.warn(`[agent] Required phase \"${phase.name}\" produced 0 turns`);\n }\n\n // Use SDK's num_turns — it's what the SDK enforces against.\n // agenticTurns (assistant message count) is logged for diagnostics\n // but not reliable as the primary metric.\n return {\n name: phase.name,\n status: 'completed',\n turnsUsed: phaseTurns,\n tokensUsed: phaseTokens,\n costUsd: phaseCost,\n summary: phaseSummary,\n };\n } catch (err) {\n return {\n name: phase.name,\n status: 'failed',\n turnsUsed: phaseTurns,\n tokensUsed: phaseTokens,\n costUsd: phaseCost,\n summary: `Error: ${toErrorMessage(err)}`,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Single-query execution (non-phased tasks)\n// ---------------------------------------------------------------------------\n\n/**\n * Execute a single query() call for non-phased tasks.\n *\n * @returns tokens used, cost, and status.\n */\nasync function executeSingleQuery(\n config: EffectiveConfig,\n systemPrompt: string,\n taskPrompt: string,\n agentId: string,\n runId: string,\n provider?: ProviderConfig,\n embeddingManager?: RunOptions['embeddingManager'],\n abortController?: AbortController,\n vaultDir?: string,\n): Promise<{ tokensUsed: number; costUsd: number }> {\n const { query } = await import('@anthropic-ai/claude-agent-sdk');\n const toolServer = createVaultToolServer(agentId, runId, { embeddingManager, vaultDir });\n const baseEnv = buildPhaseEnv(provider);\n const env = { ...(baseEnv ?? process.env), MYCO_AGENT_SESSION: '1' };\n // Model priority: provider model override → task YAML model\n const effectiveModel = provider?.model ?? config.model;\n\n let resultCostUsd = 0;\n let resultTokens = 0;\n\n for await (const message of query({\n prompt: taskPrompt,\n options: {\n model: effectiveModel,\n systemPrompt,\n mcpServers: { [MCP_SERVER_NAME]: toolServer },\n strictMcpConfig: true,\n maxTurns: config.maxTurns,\n permissionMode: 'bypassPermissions',\n allowDangerouslySkipPermissions: true,\n persistSession: PERSIST_SESSION,\n env,\n tools: [],\n ...(abortController ? { abortController } : {}),\n },\n })) {\n if (message.type === 'result') {\n resultCostUsd = message.total_cost_usd ?? 0;\n resultTokens =\n (message.usage.input_tokens ?? 0) + (message.usage.output_tokens ?? 0);\n }\n }\n\n return { tokensUsed: resultTokens, costUsd: resultCostUsd };\n}\n\n// ---------------------------------------------------------------------------\n// Phased execution (wave-based parallel)\n// ---------------------------------------------------------------------------\n\n/**\n * Execute a phased task — wave-based parallel query() calls.\n *\n * Phases are sorted into waves via `computeWaves()`. Phases within the same\n * wave execute concurrently via `Promise.allSettled()`. Each phase gets:\n * - Scoped tools (only the tools listed in the phase definition)\n * - Its own turn budget (maxTurns)\n * - Optional model override (falls back to task/agent model)\n * - Isolated provider env (via SDK `env` option — no process.env mutation)\n * - Context from prior wave results\n * - Deterministic session ID derived from run ID + phase name\n *\n * The executor controls the loop — the LLM cannot skip phases.\n */\nasync function executePhasedQuery(\n config: EffectiveConfig,\n systemPrompt: string,\n vaultContext: string,\n agentId: string,\n runId: string,\n taskProviderOverride?: ProviderConfig,\n phaseProviderOverrides?: Record<string, { provider?: ProviderConfig; maxTurns?: number }>,\n instruction?: string,\n embeddingManager?: RunOptions['embeddingManager'],\n abortController?: AbortController,\n projectRoot?: string,\n vaultDir?: string,\n): Promise<{ tokensUsed: number; costUsd: number; phases: PhaseResult[] }> {\n const { query } = await import('@anthropic-ai/claude-agent-sdk');\n\n const phases = config.phases!;\n const phaseResults: PhaseResult[] = [];\n let totalTokens = 0;\n let totalCost = 0;\n let runningTurnCount = 0;\n\n // ---------------------------------------------------------------------------\n // Orchestrator planning (opt-in via config.orchestrator.enabled)\n // ---------------------------------------------------------------------------\n\n let effectivePhases = [...phases];\n\n if (config.orchestrator?.enabled) {\n // 1. Run context queries (if any)\n const contextQueries = config.contextQueries\n ? Object.values(config.contextQueries).flat()\n : [];\n const contextResults: ContextQueryResult[] = contextQueries.length > 0\n ? await executeContextQueries(agentId, contextQueries)\n : [];\n\n // 2. Compose orchestrator prompt\n const orchestratorPrompt = composeOrchestratorPrompt(vaultContext, phases, contextResults);\n const orchestratorModel = config.orchestrator.model ?? config.model;\n const orchestratorMaxTurns = config.orchestrator.maxTurns ?? DEFAULT_ORCHESTRATOR_MAX_TURNS;\n\n // 3. Call orchestrator (no tools — planning only)\n const orchestratorEnv = { ...(buildPhaseEnv(taskProviderOverride) ?? process.env), MYCO_AGENT_SESSION: '1' };\n let planResponse = '';\n for await (const message of query({\n prompt: orchestratorPrompt,\n options: {\n model: orchestratorModel,\n maxTurns: orchestratorMaxTurns,\n permissionMode: 'bypassPermissions',\n allowDangerouslySkipPermissions: true,\n persistSession: PERSIST_SESSION,\n strictMcpConfig: true,\n env: orchestratorEnv,\n tools: [],\n },\n })) {\n if (message.type === 'result' && 'result' in message && typeof message.result === 'string') {\n planResponse = message.result;\n }\n }\n\n // 4. Parse plan and apply directives\n const plan = parseOrchestratorPlan(planResponse, phases);\n effectivePhases = applyDirectives(phases, plan.phases);\n }\n\n // ---------------------------------------------------------------------------\n // Wave-based phase execution\n // ---------------------------------------------------------------------------\n\n // Build a map from phase name to its YAML declaration order for stable output\n const declarationOrder = new Map(phases.map((p, i) => [p.name, i]));\n\n const waves = computeWaves(effectivePhases);\n\n for (const wave of waves) {\n const executions = wave.map((phase, indexInWave) => {\n const phasePrompt = composePhasePrompt(\n vaultContext,\n config.taskDisplayName,\n config.taskPrompt,\n phase,\n phaseResults,\n instruction,\n );\n\n // Apply myco.yaml per-phase overrides (maxTurns, provider)\n const phaseOverride = phaseProviderOverrides?.[phase.name];\n const effectiveMaxTurns = phaseOverride?.maxTurns ?? phase.maxTurns;\n\n // Model priority: phase YAML → myco.yaml phase provider → myco.yaml task provider → task YAML\n const phaseModel = phase.model ?? phaseOverride?.provider?.model ?? taskProviderOverride?.model ?? config.model;\n const toolServer = createScopedVaultToolServer(\n agentId,\n runId,\n phase.tools,\n {\n turnOffset: runningTurnCount + (indexInWave * effectiveMaxTurns),\n embeddingManager,\n projectRoot,\n vaultDir,\n readOnly: phase.readOnly,\n },\n );\n\n // Provider priority: phase YAML → myco.yaml phase → myco.yaml task → task YAML execution → default\n const phaseProvider = phase.provider ?? phaseOverride?.provider ?? taskProviderOverride ?? config.execution?.provider;\n const baseEnv = buildPhaseEnv(phaseProvider);\n const env = { ...(baseEnv ?? process.env), MYCO_AGENT_SESSION: '1' };\n const sessionId = phaseSessionId(runId, phase.name);\n\n // Pass effective maxTurns to executePhase via a modified phase object\n const effectivePhase = effectiveMaxTurns !== phase.maxTurns\n ? { ...phase, maxTurns: effectiveMaxTurns }\n : phase;\n\n return executePhase(query, phasePrompt, phaseModel, systemPrompt, toolServer, effectivePhase, env, sessionId, abortController);\n });\n\n const settled = await Promise.allSettled(executions);\n\n // Map settled results to PhaseResult[]\n const waveResults: PhaseResult[] = settled.map((outcome, i) => {\n if (outcome.status === 'fulfilled') {\n return outcome.value;\n }\n // Promise.allSettled rejected — shouldn't happen since executePhase catches,\n // but handle defensively\n return {\n name: wave[i].name,\n status: 'failed' as const,\n turnsUsed: 0,\n tokensUsed: 0,\n costUsd: 0,\n summary: `Error: ${toErrorMessage(outcome.reason)}`,\n };\n });\n\n // Sort by YAML declaration order for stable output\n waveResults.sort((a, b) =>\n (declarationOrder.get(a.name) ?? 0) - (declarationOrder.get(b.name) ?? 0),\n );\n\n // Accumulate results and totals\n for (const result of waveResults) {\n phaseResults.push(result);\n totalTokens += result.tokensUsed;\n totalCost += result.costUsd;\n runningTurnCount += result.turnsUsed;\n }\n\n // If any required phase in this wave failed, stop the pipeline\n const shouldStop = wave.some((phase, i) => {\n if (!phase.required) return false;\n const outcome = settled[i];\n if (outcome.status === 'rejected') return true;\n return outcome.value.status === 'failed';\n });\n\n if (shouldStop) {\n break;\n }\n }\n\n return { tokensUsed: totalTokens, costUsd: totalCost, phases: phaseResults };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Run an agent against a vault.\n *\n * For tasks with a `phases` array, uses wave-based parallel execution\n * (phases sorted into dependency waves via Kahn's algorithm). For tasks\n * without phases, uses a single query() call.\n *\n * @param vaultDir — absolute path to the vault directory.\n * @param options — optional overrides for agent, task, and instruction.\n * @returns the run result with status, token usage, and cost.\n */\nexport async function runAgent(\n vaultDir: string,\n options?: RunOptions,\n): Promise<AgentRunResult> {\n // 1. Init DB (idempotent — returns existing instance if already open)\n const db = initDatabase(vaultDbPath(vaultDir));\n createSchema(db);\n\n const agentId = options?.agentId ?? DEFAULT_AGENT_ID;\n\n // 2. Concurrency guard — block duplicate runs of the SAME task, not all tasks.\n // Different tasks (e.g., full-intelligence and skill-generate) can run concurrently.\n // When no task is specified, resolve the effective task name first so the guard applies.\n const requestedTask = options?.task;\n {\n const effectiveTask = requestedTask\n ?? getDefaultTask(agentId)?.id;\n if (effectiveTask) {\n const runningId = getRunningRunForTask(agentId, effectiveTask);\n if (runningId) {\n return {\n runId: runningId,\n status: STATUS_SKIPPED,\n reason: SKIP_REASON_ALREADY_RUNNING,\n };\n }\n }\n }\n\n // 3. Resolve config from all sources\n const {\n config,\n definitionsDir,\n taskProviderOverride: resolvedTaskProvider,\n phaseProviderOverrides: resolvedPhaseOverrides,\n } = resolveRunConfig(agentId, requestedTask, vaultDir);\n\n // Both are mutated by the Ollama variant resolver below — it rewrites\n // provider.model to the variant name and may reconcile context conflicts.\n let taskProviderOverride = resolvedTaskProvider;\n let phaseProviderOverrides = resolvedPhaseOverrides;\n\n // 4. Create run record\n const runId = options?.resumeRunId ?? crypto.randomUUID();\n const now = epochSeconds();\n\n if (!options?.resumeRunId) {\n insertRun({\n id: runId,\n agent_id: agentId,\n task: config.taskName,\n instruction: options?.instruction ?? null,\n status: STATUS_RUNNING,\n started_at: now,\n });\n }\n\n // 5. Build prompt components\n const systemPrompt = loadSystemPrompt(definitionsDir, config.systemPromptPath);\n const vaultContext = buildVaultContext(agentId);\n\n // 6. Build run metadata for audit trail\n const effectiveProvider = taskProviderOverride ?? config.execution?.provider;\n const effectiveModel = effectiveProvider?.model ?? config.model;\n const runMeta = {\n model: effectiveModel,\n provider: effectiveProvider?.type ?? 'anthropic',\n ...(effectiveProvider?.baseUrl ? { baseUrl: effectiveProvider.baseUrl } : {}),\n };\n\n // 7. Resolve Ollama context variants across task + phase scopes.\n // Applies DEFAULT_OLLAMA_CONTEXT_LENGTH when no value is set, and\n // reconciles same-model-different-context conflicts to one variant\n // per model (max wins) so Ollama loads each model at most once.\n // Non-ollama providers are passed through unchanged.\n {\n const resolved = await resolveOllamaContextVariants(\n taskProviderOverride,\n phaseProviderOverrides,\n );\n taskProviderOverride = resolved.taskProvider;\n phaseProviderOverrides = resolved.phaseOverrides;\n for (const conflict of resolved.conflicts) {\n console.warn(\n `[agent] Ollama model \"${conflict.model}\" referenced with conflicting ` +\n `context_length values [${conflict.values.join(', ')}] — reconciled to ` +\n `${conflict.resolved} to avoid loading multiple variants. Configure one ` +\n `value per model to silence this warning.`,\n );\n }\n }\n\n // 8. Execute — phased or single query\n // Create abort controller for task-level timeout enforcement\n const taskAbortController = new AbortController();\n const timeoutMs = config.timeoutSeconds * MS_PER_SECOND;\n const timeoutId = setTimeout(() => {\n console.warn(`[agent] Run ${runId} exceeded timeout (${config.timeoutSeconds}s), aborting`);\n taskAbortController.abort();\n }, timeoutMs);\n timeoutId.unref?.();\n\n let phaseResults: PhaseResult[] | undefined;\n try {\n let tokensUsed: number;\n let costUsd: number;\n\n if (config.phases && config.phases.length > 0) {\n // Phased execution: wave-based parallel query() per phase with scoped tools\n const projectRoot = resolve(vaultDir, '..');\n const result = await executePhasedQuery(\n config,\n systemPrompt,\n vaultContext,\n agentId,\n runId,\n taskProviderOverride,\n phaseProviderOverrides,\n options?.instruction,\n options?.embeddingManager,\n taskAbortController,\n projectRoot,\n vaultDir,\n );\n tokensUsed = result.tokensUsed;\n costUsd = result.costUsd;\n phaseResults = result.phases;\n\n // A required-phase failure stops the pipeline (executePhasedQuery breaks\n // the wave loop) but returns normally. Surface it as a run-level failure\n // by throwing — the catch block writes STATUS_FAILED while preserving\n // the accumulated phase results in the DB row.\n const requiredPhaseNames = new Set(\n config.phases!.filter((p) => p.required).map((p) => p.name),\n );\n const failedRequired = phaseResults.find(\n (p) => p.status === 'failed' && requiredPhaseNames.has(p.name),\n );\n if (failedRequired) {\n throw new Error(\n `Required phase \"${failedRequired.name}\" failed: ${failedRequired.summary}`,\n );\n }\n } else {\n // Single-query execution (backward compatible)\n const taskPrompt = composeTaskPrompt(\n vaultContext,\n config.taskDisplayName,\n config.taskPrompt,\n options?.instruction,\n );\n\n // Provider priority for single-query: myco.yaml task override → task execution config → default\n const singleProvider = taskProviderOverride ?? config.execution?.provider;\n\n const result = await executeSingleQuery(\n config,\n systemPrompt,\n taskPrompt,\n agentId,\n runId,\n singleProvider,\n options?.embeddingManager,\n taskAbortController,\n vaultDir,\n );\n tokensUsed = result.tokensUsed;\n costUsd = result.costUsd;\n }\n\n clearTimeout(timeoutId);\n const completedAt = epochSeconds();\n updateRunStatus(runId, STATUS_COMPLETED, {\n completed_at: completedAt,\n tokens_used: tokensUsed,\n cost_usd: costUsd,\n actions_taken: JSON.stringify({ ...runMeta, ...(phaseResults ? { phases: phaseResults } : {}) }),\n });\n\n return {\n runId,\n status: STATUS_COMPLETED,\n tokensUsed,\n costUsd,\n ...(phaseResults ? { phases: phaseResults } : {}),\n };\n } catch (err) {\n clearTimeout(timeoutId);\n // 7. Error handling — mark run as failed, preserve phase results\n // Aggressively extract error info — the SDK may throw non-Error objects\n let errorMessage: string;\n if (err instanceof Error) {\n errorMessage = err.message || err.constructor.name || 'Error (no message)';\n if (err.stack) errorMessage += `\\n${err.stack.split('\\n').slice(0, 3).join('\\n')}`;\n } else if (typeof err === 'string') {\n errorMessage = err || 'Empty string error';\n } else {\n try { errorMessage = JSON.stringify(err); } catch { errorMessage = 'Unserializable error'; }\n }\n const failedAt = epochSeconds();\n\n // Log to stderr (daemon may capture) and to structured log\n console.error(`[agent] Run ${runId} failed: ${errorMessage}`);\n\n try {\n updateRunStatus(runId, STATUS_FAILED, {\n completed_at: failedAt,\n error: errorMessage,\n // Preserve phase results collected before the failure\n actions_taken: JSON.stringify({ ...runMeta, ...(phaseResults ? { phases: phaseResults } : {}) }),\n });\n } catch (dbErr) {\n // DB failure in error path — log it but don't mask the original error\n console.error(`[agent] Failed to save error to DB:`, dbErr);\n }\n\n await cleanupOnTaskFailure({\n taskName: config.taskName,\n vaultDir,\n runContext: options?.runContext,\n });\n\n return {\n runId,\n status: STATUS_FAILED,\n error: errorMessage,\n ...(phaseResults ? { phases: phaseResults } : {}),\n };\n }\n}\n\n/**\n * Task-specific cleanup fired when a run ends in failure. Exported\n * for direct unit testing — the real executor call site lives in\n * runAgent's catch block.\n *\n * skill-generate: the draft phase stages SKILL.md + manifest to\n * .myco/staging/skills/<candidate_id>/ via vault_stage_skill. If the\n * validate phase (or any later required phase) fails, the staged\n * content must be removed so the next generate cycle doesn't find an\n * orphan draft. The daemon periodic sweep is the belt-and-suspenders\n * backup for anything this hook misses.\n */\nexport async function cleanupOnTaskFailure(args: {\n taskName: string | undefined;\n vaultDir: string | undefined;\n runContext: RunOptions['runContext'];\n}): Promise<void> {\n if (args.taskName !== SKILL_GENERATE_TASK) return;\n if (!args.vaultDir) return;\n const candidateId = args.runContext?.candidate_id;\n if (!candidateId) return;\n\n try {\n const { cleanupStagedSkill } = await import('./tools/skill-staging.js');\n cleanupStagedSkill(args.vaultDir, candidateId);\n console.warn(\n `[agent] skill-generate failed — cleaned up staging for candidate ${candidateId}`,\n );\n } catch (cleanupErr) {\n console.warn(\n `[agent] Failed to clean staging for candidate ${candidateId}:`,\n cleanupErr instanceof Error ? cleanupErr.message : cleanupErr,\n );\n }\n}\n","/**\n * Vault MCP tool server for the agent.\n *\n * Creates 21 tools that expose SQLite query helpers to the agent\n * via the Claude Agent SDK. Tools are grouped into:\n * - Read tools (8): vault_unprocessed, vault_spores, vault_sessions, vault_search_fts,\n * vault_search_semantic, vault_state, vault_entities, vault_edges\n * - Write tools (9): vault_create_spore, vault_create_entity, vault_create_edge,\n * vault_resolve_spore, vault_update_session, vault_set_state,\n * vault_read_digest, vault_write_digest, vault_mark_processed\n * - Observability (1): vault_report\n * - Skill tools (3): vault_skill_candidates, vault_skill_records, vault_write_skill\n *\n * `agentId` and `runId` are captured in closures — tools inject them\n * automatically so the agent cannot impersonate another agent.\n */\n\nimport { createSdkMcpServer } from '@anthropic-ai/claude-agent-sdk';\nimport { epochSeconds } from '@myco/constants.js';\nimport { getPluginVersion } from '@myco/version.js';\nimport { insertTurn } from '@myco/db/queries/turns.js';\nimport { createReadTools } from './tools/read-tools.js';\nimport { createWriteTools } from './tools/write-tools.js';\nimport { createObservabilityTools } from './tools/observability-tools.js';\nimport { createSkillTools } from './tools/skill-tools.js';\nimport type { VaultToolDeps } from './tools/types.js';\nimport type { EmbeddingManager } from '@myco/daemon/embedding/index.js';\nimport type { TeamSyncClient } from '@myco/daemon/team-sync.js';\n\n// Re-exports for backward compatibility\nexport { validateSkillContent, MAX_SKILL_LINES, REQUIRED_FRONTMATTER_FIELDS } from './tools/skill-validator.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Options for createVaultTools beyond the required agentId and runId. */\nexport interface VaultToolOptions {\n turnOffset?: number;\n embeddingManager?: EmbeddingManager;\n teamClient?: TeamSyncClient | null;\n machineId?: string;\n projectRoot?: string;\n vaultDir?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Tool definitions factory\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Tool group membership — used to skip factory calls for unneeded groups\n// ---------------------------------------------------------------------------\n\nconst READ_TOOL_NAMES = new Set([\n 'vault_unprocessed', 'vault_spores', 'vault_sessions', 'vault_search_fts',\n 'vault_search_semantic', 'vault_state', 'vault_entities', 'vault_edges',\n]);\n\nconst WRITE_TOOL_NAMES = new Set([\n 'vault_create_spore', 'vault_create_entity', 'vault_create_edge',\n 'vault_resolve_spore', 'vault_update_session', 'vault_set_state',\n 'vault_read_digest', 'vault_write_digest', 'vault_mark_processed',\n]);\n\nconst OBSERVABILITY_TOOL_NAMES = new Set(['vault_report']);\n\nconst SKILL_TOOL_NAMES = new Set([\n 'vault_skill_candidates', 'vault_skill_records', 'vault_write_skill',\n 'vault_stage_skill', 'vault_finalize_skill',\n]);\n\n/**\n * Total number of vault tools defined. Derived from the union of the\n * four tool-group sets above so this constant can never drift from the\n * actual factory output — adding a tool to a group bumps the count\n * automatically. Each set is disjoint so the straight sum is correct.\n */\nexport const VAULT_TOOL_COUNT =\n READ_TOOL_NAMES.size +\n WRITE_TOOL_NAMES.size +\n OBSERVABILITY_TOOL_NAMES.size +\n SKILL_TOOL_NAMES.size;\n\nfunction setsOverlap(a: Set<string>, b: Set<string>): boolean {\n for (const item of a) { if (b.has(item)) return true; }\n return false;\n}\n\n/**\n * Create vault tool definitions for the agent.\n *\n * When `onlyNames` is provided, only tool groups that contain at least one\n * requested name are instantiated — avoids building all 21 closures when\n * a phase only needs 2-3 tools.\n *\n * Exposed for testing (call handler directly) and for the MCP server factory.\n */\nexport function createVaultTools(agentId: string, runId: string, options?: VaultToolOptions & { onlyNames?: Set<string> }) {\n const { turnOffset = 0, embeddingManager, teamClient, machineId, projectRoot, vaultDir, onlyNames } = options ?? {};\n\n /** Turn number counter — incremented per tool call (read and write) within a run. */\n let turnCounter = turnOffset;\n\n /**\n * Record a turn in the audit trail.\n * Called for ALL tool invocations (read and write) for full visibility.\n * Fire-and-forget — does not block the tool response.\n */\n function recordTurn(toolName: string, toolInput: unknown): void {\n turnCounter++;\n try {\n insertTurn({\n run_id: runId,\n agent_id: agentId,\n turn_number: turnCounter,\n tool_name: toolName,\n tool_input: JSON.stringify(toolInput),\n started_at: epochSeconds(),\n });\n } catch {\n /* audit trail is best-effort */\n }\n }\n\n const deps: VaultToolDeps = {\n agentId,\n runId,\n embeddingManager,\n teamClient,\n machineId,\n projectRoot,\n vaultDir,\n recordTurn,\n };\n\n // When onlyNames is provided, skip factory calls for groups with no overlap\n const needsAll = !onlyNames;\n return [\n ...(needsAll || setsOverlap(onlyNames!, READ_TOOL_NAMES) ? createReadTools(deps) : []),\n ...(needsAll || setsOverlap(onlyNames!, WRITE_TOOL_NAMES) ? createWriteTools(deps) : []),\n ...(needsAll || setsOverlap(onlyNames!, OBSERVABILITY_TOOL_NAMES) ? createObservabilityTools(deps) : []),\n ...(needsAll || setsOverlap(onlyNames!, SKILL_TOOL_NAMES) ? createSkillTools(deps) : []),\n ];\n}\n\n// ---------------------------------------------------------------------------\n// MCP server factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create a vault MCP tool server with 21 tools for the agent.\n *\n * Wraps `createVaultTools()` with `createSdkMcpServer()` from the\n * Claude Agent SDK.\n *\n * @param agentId — the agent identity, injected into all write operations.\n * @param runId — the current agent run ID, injected into reports and turns.\n * @returns an MCP server config with instance, suitable for the SDK.\n */\nexport function createVaultToolServer(agentId: string, runId: string, options?: Pick<VaultToolOptions, 'embeddingManager' | 'vaultDir'>) {\n const tools = createVaultTools(agentId, runId, options);\n\n return createSdkMcpServer({\n name: 'myco-vault',\n version: getPluginVersion(),\n tools,\n });\n}\n\n/**\n * Create a vault MCP tool server scoped to a subset of tools.\n *\n * Used by the phased executor to restrict each phase to only the tools\n * it needs. Tools not in `toolNames` are excluded from the server.\n *\n * @param agentId — the agent identity, injected into all write operations.\n * @param runId — the current agent run ID, injected into reports and turns.\n * @param toolNames — tool names to include (e.g., ['vault_unprocessed', 'vault_create_spore']).\n * @returns an MCP server config with only the specified tools.\n */\nexport function createScopedVaultToolServer(\n agentId: string,\n runId: string,\n toolNames: string[],\n options?: Pick<VaultToolOptions, 'turnOffset' | 'embeddingManager' | 'projectRoot' | 'vaultDir'> & { readOnly?: boolean },\n) {\n const nameSet = new Set(toolNames);\n const allTools = createVaultTools(agentId, runId, { ...options, onlyNames: nameSet });\n // readOnly gate first — structural enforcement before name scoping,\n // so a write tool in the name list can never pass the readOnly filter.\n const eligible = options?.readOnly\n ? allTools.filter((t) => t.annotations?.readOnlyHint === true)\n : allTools;\n const scopedTools = eligible.filter((t) => nameSet.has(t.name));\n\n return createSdkMcpServer({\n name: 'myco-vault',\n version: getPluginVersion(),\n tools: scopedTools,\n });\n}\n","/**\n * Read-only vault tools.\n *\n * 8 tools: vault_unprocessed, vault_spores, vault_sessions, vault_search_fts,\n * vault_search_semantic, vault_state, vault_entities, vault_edges\n */\n\nimport { z } from 'zod/v4';\nimport { tool } from '@anthropic-ai/claude-agent-sdk';\nimport { SEARCH_SIMILARITY_THRESHOLD, TEAM_SOURCE_PREFIX } from '@myco/constants.js';\nimport { getUnprocessedBatches } from '@myco/db/queries/batches.js';\nimport { listSpores } from '@myco/db/queries/spores.js';\nimport { listSessions } from '@myco/db/queries/sessions.js';\nimport { getStatesForAgent } from '@myco/db/queries/agent-state.js';\nimport { fullTextSearch } from '@myco/db/queries/search.js';\nimport { listEntities } from '@myco/db/queries/entities.js';\nimport { listGraphEdges } from '@myco/db/queries/graph-edges.js';\nimport { textResult, type VaultToolDeps } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Default limit for unprocessed batches query. */\nconst DEFAULT_UNPROCESSED_LIMIT = 50;\n\n/** Default limit for spore listing. */\nconst DEFAULT_SPORES_LIMIT = 50;\n\n/** Default limit for session listing. */\nconst DEFAULT_SESSIONS_LIMIT = 20;\n\n/** Default limit for similarity search results. */\nconst DEFAULT_SEARCH_LIMIT = 10;\n\n/** Default limit for entity listing. */\nconst DEFAULT_ENTITIES_LIMIT = 50;\n\n/** Default limit for edge listing. */\nconst DEFAULT_EDGES_LIMIT = 50;\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createReadTools(deps: VaultToolDeps) {\n const { agentId, embeddingManager, teamClient, machineId, recordTurn } = deps;\n\n const vaultUnprocessed = tool(\n 'vault_unprocessed',\n 'Get unprocessed prompt batches, ordered by id ASC. Supports cursor-based pagination.',\n {\n after_id: z.number().optional().describe('Return batches with id greater than this'),\n limit: z.number().optional().describe('Maximum number of batches to return'),\n },\n async (args) => {\n recordTurn('vault_unprocessed', args);\n const batches = getUnprocessedBatches({\n after_id: args.after_id,\n limit: args.limit ?? DEFAULT_UNPROCESSED_LIMIT,\n });\n return textResult(batches);\n },\n { annotations: { readOnlyHint: true } },\n );\n\n const vaultSpores = tool(\n 'vault_spores',\n 'List spores with optional filters (agent, observation type, status, session).',\n {\n agent_id: z.string().optional().describe('Filter by agent ID'),\n observation_type: z.string().optional().describe('Filter by observation type (e.g., gotcha, decision)'),\n status: z.enum(['active', 'superseded', 'archived']).optional().describe('Filter by status'),\n session_id: z.string().optional().describe('Filter by session ID'),\n limit: z.number().optional().describe('Maximum number of spores to return'),\n },\n async (args) => {\n recordTurn('vault_spores', args);\n const spores = listSpores({\n agent_id: args.agent_id,\n observation_type: args.observation_type,\n status: args.status,\n session_id: args.session_id,\n limit: args.limit ?? DEFAULT_SPORES_LIMIT,\n });\n return textResult(spores);\n },\n { annotations: { readOnlyHint: true } },\n );\n\n const vaultSessions = tool(\n 'vault_sessions',\n 'List sessions with optional status filter, ordered by created_at DESC.',\n {\n limit: z.number().optional().describe('Maximum number of sessions to return'),\n status: z.string().optional().describe('Filter by status (active, completed)'),\n },\n async (args) => {\n recordTurn('vault_sessions', args);\n const sessions = listSessions({\n limit: args.limit ?? DEFAULT_SESSIONS_LIMIT,\n status: args.status,\n });\n return textResult(sessions);\n },\n { annotations: { readOnlyHint: true } },\n );\n\n const vaultSearchFts = tool(\n 'vault_search_fts',\n 'Full-text search across sessions, spores, prompt batches, and activities using FTS5. Best for finding exact keywords, file paths, function names, and specific text. Searches: session titles/summaries, spore content, user prompts, AI response summaries, tool calls.',\n {\n query: z.string().describe('Search query text'),\n type: z.string().optional().describe('Restrict to a result type (session, spore, prompt_batch, activity)'),\n limit: z.number().optional().describe('Maximum number of results to return'),\n },\n async (args) => {\n recordTurn('vault_search_fts', args);\n try {\n const results = fullTextSearch(args.query, {\n type: args.type,\n limit: args.limit ?? DEFAULT_SEARCH_LIMIT,\n });\n return textResult({ results });\n } catch {\n return textResult({ results: [], message: 'Search unavailable' });\n }\n },\n { annotations: { readOnlyHint: true } },\n );\n\n const vaultSearchSemantic = tool(\n 'vault_search_semantic',\n 'Semantic similarity search across embedded vault content (spores, sessions, plans, artifacts). Best for finding conceptually related content. Returns results ranked by similarity score.',\n {\n query: z.string().describe('Search query text'),\n namespace: z.string().optional().describe('Restrict to a content type: spores, sessions, plans, artifacts. Omit to search all.'),\n limit: z.number().optional().describe('Maximum results to return'),\n },\n async (args) => {\n recordTurn('vault_search_semantic', args);\n if (!embeddingManager) {\n return textResult({ results: [], message: 'Embedding provider unavailable' });\n }\n try {\n const queryVector = await embeddingManager.embedQuery(args.query);\n if (!queryVector) {\n return textResult({ results: [], message: 'Embedding provider unavailable' });\n }\n const searchLimit = args.limit ?? DEFAULT_SEARCH_LIMIT;\n\n // Fire local and team search in parallel\n const [localResults, teamResults] = await Promise.all([\n Promise.resolve(\n embeddingManager.searchVectors(queryVector, {\n namespace: args.namespace,\n limit: searchLimit,\n threshold: SEARCH_SIMILARITY_THRESHOLD,\n }).map((r) => ({ ...r, source: 'local' as const })),\n ),\n teamClient\n ? teamClient.search(args.query, { limit: searchLimit })\n .then((res) => res.results.map((r) => ({ ...r, source: `${TEAM_SOURCE_PREFIX}${r.machine_id}` })))\n .catch(() => [] as Array<Record<string, unknown>>)\n : Promise.resolve([] as Array<Record<string, unknown>>),\n ]);\n\n // Deduplicate: skip team results from this machine (we already have them locally)\n const dedupedTeam = machineId\n ? teamResults.filter((r) => (r as Record<string, unknown>).machine_id !== machineId)\n : teamResults;\n\n // Merge by similarity/score (normalize to common key), slice to limit\n const merged = [\n ...localResults.map((r) => ({ ...r, score: r.similarity })),\n ...dedupedTeam,\n ]\n .sort((a, b) => ((b.score as number) ?? 0) - ((a.score as number) ?? 0))\n .slice(0, searchLimit);\n\n return textResult({ results: merged });\n } catch {\n return textResult({ results: [], message: 'Semantic search unavailable' });\n }\n },\n { annotations: { readOnlyHint: true, openWorldHint: true } },\n );\n\n const vaultState = tool(\n 'vault_state',\n 'Get all state key-value pairs for the current agent.',\n {},\n async () => {\n recordTurn('vault_state', {});\n const states = getStatesForAgent(agentId);\n return textResult(states);\n },\n { annotations: { readOnlyHint: true } },\n );\n\n const vaultEntities = tool(\n 'vault_entities',\n 'List knowledge graph entities with optional filters.',\n {\n type: z.enum(['component', 'concept', 'person']).optional().describe('Filter by entity type'),\n name: z.string().optional().describe('Filter by entity name (exact match)'),\n limit: z.number().optional().describe('Maximum entities to return'),\n },\n async (args) => {\n recordTurn('vault_entities', args);\n const entities = listEntities({\n agent_id: agentId,\n type: args.type,\n name: args.name,\n limit: args.limit ?? DEFAULT_ENTITIES_LIMIT,\n });\n return textResult(entities);\n },\n { annotations: { readOnlyHint: true } },\n );\n\n const vaultEdges = tool(\n 'vault_edges',\n 'List knowledge graph edges with optional filters. Use to check existing relationships before creating new ones.',\n {\n source_id: z.string().optional().describe('Filter by source node ID'),\n target_id: z.string().optional().describe('Filter by target node ID'),\n type: z.string().optional().describe('Filter by edge type (REFERENCES, DEPENDS_ON, AFFECTS, etc.)'),\n limit: z.number().optional().describe('Maximum edges to return'),\n },\n async (args) => {\n recordTurn('vault_edges', args);\n const edges = listGraphEdges({\n sourceId: args.source_id,\n targetId: args.target_id,\n type: args.type,\n agentId: agentId,\n limit: args.limit ?? DEFAULT_EDGES_LIMIT,\n });\n return textResult(edges);\n },\n { annotations: { readOnlyHint: true } },\n );\n\n return [\n vaultUnprocessed,\n vaultSpores,\n vaultSessions,\n vaultSearchFts,\n vaultSearchSemantic,\n vaultState,\n vaultEntities,\n vaultEdges,\n ];\n}\n","/**\n * Agent state key-value query helpers.\n *\n * All functions obtain the SQLite instance internally via `getDatabase()`.\n * Queries use positional `?` placeholders throughout (better-sqlite3).\n */\n\nimport { getDatabase } from '@myco/db/client.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Row shape returned from agent_state queries. */\nexport interface AgentStateRow {\n agent_id: string;\n key: string;\n value: string;\n updated_at: number;\n}\n\n// ---------------------------------------------------------------------------\n// Column list\n// ---------------------------------------------------------------------------\n\nconst STATE_COLUMNS = [\n 'agent_id',\n 'key',\n 'value',\n 'updated_at',\n] as const;\n\nconst SELECT_COLUMNS = STATE_COLUMNS.join(', ');\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Normalize a SQLite result row into a typed AgentStateRow. */\nfunction toAgentStateRow(row: Record<string, unknown>): AgentStateRow {\n return {\n agent_id: row.agent_id as string,\n key: row.key as string,\n value: row.value as string,\n updated_at: row.updated_at as number,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Get a single state value for an agent by key.\n *\n * @returns the state row, or null if not found.\n */\nexport function getState(\n agentId: string,\n key: string,\n): AgentStateRow | null {\n const db = getDatabase();\n\n const row = db.prepare(\n `SELECT ${SELECT_COLUMNS} FROM agent_state WHERE agent_id = ? AND key = ?`,\n ).get(agentId, key) as Record<string, unknown> | undefined;\n\n if (!row) return null;\n return toAgentStateRow(row);\n}\n\n/**\n * Set a state value for an agent. Inserts or updates on conflict.\n *\n * The composite primary key (agent_id, key) ensures each agent\n * has at most one value per key. On conflict, the value and updated_at\n * are overwritten.\n */\nexport function setState(\n agentId: string,\n key: string,\n value: string,\n updatedAt: number,\n): AgentStateRow {\n const db = getDatabase();\n\n db.prepare(\n `INSERT INTO agent_state (agent_id, key, value, updated_at)\n VALUES (?, ?, ?, ?)\n ON CONFLICT (agent_id, key) DO UPDATE SET\n value = EXCLUDED.value,\n updated_at = EXCLUDED.updated_at`,\n ).run(agentId, key, value, updatedAt);\n\n return toAgentStateRow(\n db.prepare(`SELECT ${SELECT_COLUMNS} FROM agent_state WHERE agent_id = ? AND key = ?`).get(agentId, key) as Record<string, unknown>,\n );\n}\n\n/**\n * Get all state key-value pairs for an agent, ordered by key ASC.\n */\nexport function getStatesForAgent(\n agentId: string,\n): AgentStateRow[] {\n const db = getDatabase();\n\n const rows = db.prepare(\n `SELECT ${SELECT_COLUMNS}\n FROM agent_state\n WHERE agent_id = ?\n ORDER BY key ASC`,\n ).all(agentId) as Record<string, unknown>[];\n\n return rows.map(toAgentStateRow);\n}\n","/**\n * Shared types and helpers for vault tool modules.\n */\n\nimport type { SdkMcpToolDefinition } from '@anthropic-ai/claude-agent-sdk';\nimport type { EmbeddingManager } from '@myco/daemon/embedding/index.js';\nimport type { TeamSyncClient } from '@myco/daemon/team-sync.js';\n\n// Re-export for convenience\nexport type { SdkMcpToolDefinition };\n\n/** MCP tool response helper -- wraps data as text content for the agent. */\nexport function textResult(data: unknown): { content: Array<{ type: 'text'; text: string }> } {\n return { content: [{ type: 'text' as const, text: JSON.stringify(data) }] };\n}\n\n/** Dependencies shared by all vault tool factories. */\nexport interface VaultToolDeps {\n agentId: string;\n runId: string;\n embeddingManager?: EmbeddingManager;\n teamClient?: TeamSyncClient | null;\n machineId?: string;\n projectRoot?: string;\n vaultDir?: string;\n /** Record a turn in the audit trail. Fire-and-forget. */\n recordTurn: (toolName: string, toolInput: unknown) => void;\n}\n","/**\n * Write vault tools.\n *\n * 9 tools: vault_create_spore, vault_create_entity, vault_create_edge,\n * vault_resolve_spore, vault_update_session, vault_set_state,\n * vault_read_digest, vault_write_digest, vault_mark_processed\n */\n\nimport crypto from 'node:crypto';\nimport { z } from 'zod/v4';\nimport { tool } from '@anthropic-ai/claude-agent-sdk';\nimport { epochSeconds } from '@myco/constants.js';\nimport { insertSpore, updateSporeStatus, DEFAULT_IMPORTANCE } from '@myco/db/queries/spores.js';\nimport { updateSession } from '@myco/db/queries/sessions.js';\nimport { setState } from '@myco/db/queries/agent-state.js';\nimport { markBatchProcessed } from '@myco/db/queries/batches.js';\nimport { insertEntity } from '@myco/db/queries/entities.js';\nimport { insertGraphEdge } from '@myco/db/queries/graph-edges.js';\nimport { createSporeLineage } from '@myco/db/queries/lineage.js';\nimport { insertResolutionEvent } from '@myco/db/queries/resolution-events.js';\nimport { upsertDigestExtract, listDigestExtracts } from '@myco/db/queries/digest-extracts.js';\nimport { textResult, type VaultToolDeps } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createWriteTools(deps: VaultToolDeps) {\n const { agentId, embeddingManager, machineId, recordTurn } = deps;\n\n const vaultCreateSpore = tool(\n 'vault_create_spore',\n 'Create a new spore (observation) in the vault. The agent_id is set automatically.',\n {\n observation_type: z.string().describe('Type of observation (gotcha, decision, discovery, trade-off, bug_fix, etc.)'),\n content: z.string().describe('The observation content in markdown'),\n session_id: z.string().optional().describe('Associated session ID'),\n prompt_batch_id: z.number().optional().describe('Associated prompt batch ID'),\n importance: z.number().optional().describe('Importance score 1-10 (default 5)'),\n tags: z.array(z.string()).optional().describe('Tags for categorization'),\n context: z.string().optional().describe('Additional context about the observation'),\n file_path: z.string().optional().describe('Related file path'),\n properties: z.string().optional().describe('JSON metadata (e.g., {\"consolidated_from\": [...]} for wisdom spores)'),\n },\n async (args) => {\n const id = crypto.randomUUID();\n const now = epochSeconds();\n\n const spore = insertSpore({\n id,\n agent_id: agentId,\n machine_id: machineId,\n observation_type: args.observation_type,\n content: args.content,\n session_id: args.session_id ?? null,\n prompt_batch_id: args.prompt_batch_id ?? null,\n importance: args.importance ?? DEFAULT_IMPORTANCE,\n tags: args.tags ? JSON.stringify(args.tags) : null,\n context: args.context ?? null,\n file_path: args.file_path ?? null,\n properties: args.properties ?? null,\n created_at: now,\n });\n\n // Best-effort: structural lineage edges (FROM_SESSION, EXTRACTED_FROM, DERIVED_FROM)\n try { createSporeLineage(spore); } catch { /* lineage best-effort */ }\n\n embeddingManager?.onContentWritten('spores', spore.id, args.content, {\n status: 'active',\n observation_type: args.observation_type,\n session_id: args.session_id,\n }).catch(() => {});\n\n // Spore notifications are batched post-run (daemon emits summary after agent completes)\n recordTurn('vault_create_spore', args);\n return textResult(spore);\n },\n { annotations: { openWorldHint: true } },\n );\n\n const vaultCreateEntity = tool(\n 'vault_create_entity',\n 'Create or update an entity in the knowledge graph. Uses UPSERT on (agent_id, type, name).',\n {\n type: z.enum(['component', 'concept', 'person']).describe('Entity type'),\n name: z.string().describe('Entity name (unique within agent + type)'),\n properties: z.record(z.string(), z.unknown()).optional().describe('Additional properties as key-value pairs'),\n },\n async (args) => {\n const id = crypto.randomUUID();\n const now = epochSeconds();\n const props = args.properties ? JSON.stringify(args.properties) : null;\n\n const entity = insertEntity({\n id,\n agent_id: agentId,\n machine_id: machineId,\n type: args.type,\n name: args.name,\n properties: props,\n first_seen: now,\n last_seen: now,\n });\n\n recordTurn('vault_create_entity', args);\n return textResult(entity);\n },\n { annotations: { idempotentHint: true } },\n );\n\n const vaultCreateEdge = tool(\n 'vault_create_edge',\n 'Create a semantic edge in the knowledge graph. Lineage edges (FROM_SESSION, EXTRACTED_FROM, HAS_BATCH, DERIVED_FROM) are created automatically — do NOT create those.',\n {\n source_id: z.string().describe('Source node ID'),\n source_type: z.enum(['session', 'batch', 'spore', 'entity']).describe('Source node type'),\n target_id: z.string().describe('Target node ID'),\n target_type: z.enum(['session', 'batch', 'spore', 'entity']).describe('Target node type'),\n type: z.enum(['RELATES_TO', 'SUPERSEDED_BY', 'REFERENCES', 'DEPENDS_ON', 'AFFECTS']).describe('Semantic edge type'),\n session_id: z.string().optional().describe('Session where this relationship was observed'),\n confidence: z.number().optional().describe('Confidence score 0-1 (default 1.0)'),\n properties: z.record(z.string(), z.unknown()).optional().describe('Additional properties as key-value pairs'),\n },\n async (args) => {\n const now = epochSeconds();\n const props = args.properties ? JSON.stringify(args.properties) : undefined;\n\n const edge = insertGraphEdge({\n agent_id: agentId,\n machine_id: machineId,\n source_id: args.source_id,\n source_type: args.source_type,\n target_id: args.target_id,\n target_type: args.target_type,\n type: args.type,\n session_id: args.session_id,\n confidence: args.confidence,\n properties: props,\n created_at: now,\n });\n\n recordTurn('vault_create_edge', args);\n return textResult(edge);\n },\n { annotations: { idempotentHint: true } },\n );\n\n const vaultResolveSpore = tool(\n 'vault_resolve_spore',\n 'Resolve a spore by updating its status and recording a resolution event.',\n {\n spore_id: z.string().describe('ID of the spore to resolve'),\n action: z.enum(['supersede', 'archive', 'merge', 'split', 'consolidate']).describe('Resolution action'),\n new_spore_id: z.string().optional().describe('ID of the replacement spore (for supersede/merge)'),\n reason: z.string().optional().describe('Explanation for the resolution'),\n session_id: z.string().optional().describe('Session where this resolution occurred'),\n },\n async (args) => {\n const now = epochSeconds();\n\n // Update spore status\n const statusMap: Record<string, string> = {\n supersede: 'superseded',\n archive: 'archived',\n merge: 'merged',\n split: 'split',\n consolidate: 'consolidated',\n };\n const newStatus = statusMap[args.action] ?? args.action;\n const updatedSpore = updateSporeStatus(args.spore_id, newStatus, now);\n\n // Record resolution event\n const eventId = crypto.randomUUID();\n insertResolutionEvent({\n id: eventId,\n agent_id: agentId,\n machine_id: machineId,\n spore_id: args.spore_id,\n action: args.action,\n new_spore_id: args.new_spore_id ?? null,\n reason: args.reason ?? null,\n session_id: args.session_id ?? null,\n created_at: now,\n });\n\n if (newStatus !== 'active') {\n try { embeddingManager?.onStatusChanged('spores', args.spore_id, newStatus); } catch { /* best-effort */ }\n }\n\n recordTurn('vault_resolve_spore', args);\n return textResult({ spore: updatedSpore, resolution_event_id: eventId });\n },\n { annotations: { destructiveHint: true } },\n );\n\n const vaultUpdateSession = tool(\n 'vault_update_session',\n 'Update a session title and/or summary. When generating for the first time, provide BOTH title and summary. Title should be under 80 characters and reflect the full session scope.',\n {\n session_id: z.string().describe('Session ID to update'),\n title: z.string().optional().describe('New session title'),\n summary: z.string().optional().describe('New session summary'),\n },\n async (args) => {\n const updates: Record<string, unknown> = {};\n if (args.title !== undefined) updates.title = args.title;\n if (args.summary !== undefined) updates.summary = args.summary;\n\n const session = updateSession(args.session_id, updates);\n\n if (args.summary) {\n embeddingManager?.onContentWritten('sessions', args.session_id, args.summary, {}).catch(() => {});\n }\n\n recordTurn('vault_update_session', args);\n return textResult(session);\n },\n { annotations: { idempotentHint: true } },\n );\n\n const vaultSetState = tool(\n 'vault_set_state',\n 'Set a key-value state pair for the current agent. Used for bookmarks, cursors, and preferences.',\n {\n key: z.string().describe('State key (e.g., last_processed_batch_id, cursor)'),\n value: z.string().describe('State value (stored as text)'),\n },\n async (args) => {\n const now = epochSeconds();\n const state = setState(agentId, args.key, args.value, now);\n\n recordTurn('vault_set_state', args);\n return textResult(state);\n },\n { annotations: { idempotentHint: true } },\n );\n\n const vaultReadDigest = tool(\n 'vault_read_digest',\n 'Read current digest extracts. Without a tier parameter, returns a summary of all tiers (content length, generation time). With a tier parameter, returns the full content for that specific tier.',\n {\n tier: z.number().optional().describe('Specific tier to read in full (e.g., 1500, 5000, 10000). Omit to get summary of all tiers.'),\n },\n async (args) => {\n recordTurn('vault_read_digest', args);\n const extracts = listDigestExtracts(agentId);\n\n if (args.tier !== undefined) {\n const extract = extracts.find(e => e.tier === args.tier);\n if (!extract) return textResult({ tier: args.tier, content: null, message: 'No digest at this tier' });\n return textResult({ tier: extract.tier, content: extract.content, generated_at: extract.generated_at });\n }\n\n // Summary mode -- return metadata for all tiers\n return textResult(extracts.map(e => ({\n tier: e.tier,\n content_length: e.content.length,\n generated_at: e.generated_at,\n })));\n },\n { annotations: { readOnlyHint: true } },\n );\n\n const vaultWriteDigest = tool(\n 'vault_write_digest',\n 'Write or update a digest extract at a specific token tier. Uses UPSERT on (agent_id, tier).',\n {\n tier: z.number().describe('Token budget tier (e.g., 1500, 5000, 10000)'),\n content: z.string().describe('The digest extract content in markdown'),\n },\n async (args) => {\n const now = epochSeconds();\n\n const extract = upsertDigestExtract({\n agent_id: agentId,\n tier: args.tier,\n content: args.content,\n generated_at: now,\n });\n\n // Digest notifications are batched post-run (daemon emits summary after agent completes)\n recordTurn('vault_write_digest', args);\n return textResult(extract);\n },\n { annotations: { idempotentHint: true } },\n );\n\n const vaultMarkProcessed = tool(\n 'vault_mark_processed',\n 'Mark a prompt batch as processed so it is not returned by vault_unprocessed.',\n {\n batch_id: z.number().describe('ID of the prompt batch to mark as processed'),\n },\n async (args) => {\n const batch = markBatchProcessed(args.batch_id);\n\n recordTurn('vault_mark_processed', args);\n return textResult(batch);\n },\n { annotations: { destructiveHint: true } },\n );\n\n return [\n vaultCreateSpore,\n vaultCreateEntity,\n vaultCreateEdge,\n vaultResolveSpore,\n vaultUpdateSession,\n vaultSetState,\n vaultReadDigest,\n vaultWriteDigest,\n vaultMarkProcessed,\n ];\n}\n","/**\n * Observability vault tools.\n *\n * 1 tool: vault_report\n */\n\nimport { z } from 'zod/v4';\nimport { tool } from '@anthropic-ai/claude-agent-sdk';\nimport { epochSeconds } from '@myco/constants.js';\nimport { insertReport } from '@myco/db/queries/reports.js';\nimport { textResult, type VaultToolDeps } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createObservabilityTools(deps: VaultToolDeps) {\n const { runId, agentId, recordTurn } = deps;\n\n const vaultReport = tool(\n 'vault_report',\n 'Record an observability report for the current run. Use action \"skip\" when skipping expected operations (e.g., not updating a session summary) with reasoning in the summary field.',\n {\n action: z.string().describe('Action name (e.g., extract, consolidate, digest, skip)'),\n summary: z.string().describe('Human-readable summary of what was done'),\n details: z.record(z.string(), z.unknown()).optional().describe('Structured details as key-value pairs'),\n },\n async (args) => {\n recordTurn('vault_report', args);\n const now = epochSeconds();\n\n const report = insertReport({\n run_id: runId,\n agent_id: agentId,\n action: args.action,\n summary: args.summary,\n details: args.details ? JSON.stringify(args.details) : null,\n created_at: now,\n });\n\n return textResult(report);\n },\n { annotations: {} },\n );\n\n return [vaultReport];\n}\n","/**\n * Skill lifecycle vault tools.\n *\n * 5 tools:\n * - vault_skill_candidates: CRUD over skill candidate rows. The agent\n * can only set 'identified' or 'dismissed' on updates; human-only\n * 'approved' transitions go through the UI / MCP approve action, and\n * 'generated' is set internally by vault_finalize_skill.\n * - vault_skill_records: read/update/delete live skill records.\n * - vault_write_skill: one-shot create-or-evolve write path used by\n * skill-evolve and any non-staged skill authoring.\n * - vault_stage_skill: provisional write used by skill-generate's draft\n * phase. Stages SKILL.md + manifest.json under .myco/staging/skills/\n * without touching the live DB or .agents/skills/ directory.\n * - vault_finalize_skill: promotes a staged skill. Only commit point;\n * re-runs dedup + validation as defense in depth, then atomically\n * inserts the skill_records row, lineage, candidate transition to\n * 'generated', disk file, and symlinks. Cleans up staging on success.\n */\n\nimport crypto from 'node:crypto';\nimport { readFileSync, writeFileSync, mkdirSync, rmSync, existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { z } from 'zod/v4';\nimport { tool } from '@anthropic-ai/claude-agent-sdk';\nimport { epochSeconds, DEFAULT_LIST_LIMIT } from '@myco/constants.js';\nimport { getDatabase } from '@myco/db/client.js';\nimport {\n insertCandidate, getCandidate, listCandidates, updateCandidate, deleteCandidate,\n} from '@myco/db/queries/skill-candidates.js';\nimport {\n insertSkillRecord, getSkillRecord, getSkillRecordByName,\n listSkillRecords, updateSkillRecord, deleteSkillRecordCascade,\n} from '@myco/db/queries/skill-records.js';\nimport { insertLineage } from '@myco/db/queries/skill-lineage.js';\nimport { notify } from '@myco/notifications/notify.js';\nimport {\n CANDIDATE_STATUS,\n AGENT_SETTABLE_STATUSES,\n} from '@myco/constants/skill-candidate-status.js';\nimport {\n validateSkillContent,\n checkFrontmatterPreservation,\n descriptionSimilarity,\n topicOverlapSimilarity,\n DESCRIPTION_DUPLICATE_THRESHOLD,\n TOPIC_OVERLAP_THRESHOLD,\n} from './skill-validator.js';\nimport {\n writeStagedSkill,\n readStagedSkill,\n writeStagedManifest,\n readStagedManifest,\n cleanupStagedSkill,\n type StagedManifest,\n} from './skill-staging.js';\nimport { textResult, type VaultToolDeps } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createSkillTools(deps: VaultToolDeps) {\n const { agentId, machineId, projectRoot, vaultDir, recordTurn } = deps;\n\n /**\n * Find the best-matching existing candidate (if any) whose topic\n * overlaps the proposed new topic. Uses a two-path check:\n *\n * 1. Jaccard (`descriptionSimilarity` >= DESCRIPTION_DUPLICATE_THRESHOLD)\n * — catches classic near-duplicates with similar token counts.\n * 2. Overlap coefficient (`topicOverlapSimilarity` >= TOPIC_OVERLAP_THRESHOLD)\n * — catches asymmetric kebab-case vs. natural-language duplicates\n * where a short topic's significant tokens are mostly a subset of\n * the longer one. Jaccard misses these because the inflated union\n * pushes the score below 0.4 even when the overlap is strong.\n *\n * Returns the candidate with the highest matching score under either\n * metric. Reported `score` is the max of the two so the rejection\n * message surfaces the stronger signal.\n */\n function findOverlappingCandidate(\n newTopic: string,\n existing: ReturnType<typeof listCandidates>,\n ): { candidate: typeof existing[number]; score: number } | null {\n let best: { candidate: typeof existing[number]; score: number } | null = null;\n for (const candidate of existing) {\n const jaccard = descriptionSimilarity(newTopic, candidate.topic);\n const overlap = topicOverlapSimilarity(newTopic, candidate.topic);\n const hitsJaccard = jaccard >= DESCRIPTION_DUPLICATE_THRESHOLD;\n const hitsOverlap = overlap >= TOPIC_OVERLAP_THRESHOLD;\n if (!hitsJaccard && !hitsOverlap) continue;\n const score = Math.max(jaccard, overlap);\n if (!best || score > best.score) {\n best = { candidate, score };\n }\n }\n return best;\n }\n\n /**\n * Build a status-aware rejection message. Each status gets guidance\n * that matches the lifecycle: dismissed → stay away; generated →\n * already fulfilled; approved → already queued; identified → update\n * the existing entry instead of duplicating.\n */\n function candidateOverlapError(match: { status: string; topic: string }): string {\n const common = `already has an existing candidate with a similar topic: \"${match.topic}\"`;\n switch (match.status) {\n case CANDIDATE_STATUS.DISMISSED:\n return `Candidate rejected: the vault ${common} that was previously dismissed. Do not re-identify dismissed topics.`;\n case CANDIDATE_STATUS.GENERATED:\n return `Candidate rejected: the vault ${common} that was already fulfilled by a generated skill. Do not re-identify.`;\n case CANDIDATE_STATUS.APPROVED:\n return `Candidate rejected: the vault ${common} that is already queued in approved state. Wait for the generate task to process it.`;\n case CANDIDATE_STATUS.IDENTIFIED:\n return `Candidate rejected: the vault ${common} already in the review queue. Update the existing candidate with new evidence (action: update) instead of creating a duplicate.`;\n default:\n return `Candidate rejected: the vault ${common} in status '${match.status}'.`;\n }\n }\n\n /**\n * Structural gate enforcing the skill lifecycle invariant: ONLY\n * candidates in 'approved' state can be materialized into skills.\n * Used by vault_stage_skill, vault_finalize_skill, and\n * vault_write_skill's create path.\n */\n function requireApprovedCandidate(\n candidateId: string,\n ): Record<string, unknown> | null {\n const candidate = getCandidate(candidateId);\n if (!candidate) {\n return {\n error:\n `Candidate ${candidateId} not found. Skill writes require a ` +\n 'candidate in the approved state.',\n };\n }\n if (candidate.status !== CANDIDATE_STATUS.APPROVED) {\n return {\n error:\n `Candidate ${candidateId} is in '${candidate.status}' state. ` +\n \"Skills can only be generated from candidates in 'approved' \" +\n 'state — the human review step. If a candidate in an earlier ' +\n 'state needs to become a skill, route it through the normal ' +\n 'approval flow first.',\n candidate_status: candidate.status,\n };\n }\n return null;\n }\n\n /**\n * Self-contained dedup gate for skill create paths. Returns `null`\n * when the write is allowed, or an error payload object ready for\n * textResult() when it should be rejected.\n *\n * The gate is a no-op on the evolve path (same name as an existing\n * active skill) — the caller does not need to guard the call.\n *\n * Three checks, in order:\n * (1) Same-name exists: delegate to the evolve path. Return null\n * so vault_write_skill's existing-record branch can handle it;\n * callers that only want create (vault_stage_skill,\n * vault_finalize_skill) opt in via `rejectSameName: true`.\n * (2) Candidate-already-fulfilled: if the candidate is already\n * linked to a different-named active skill.\n * (3) Description similarity: Jaccard on significant-word tokens\n * against all active skills for this agent.\n */\n function checkDedupGates(args: {\n candidate_id?: string;\n name: string;\n description: string;\n /**\n * When true, treat an existing skill with the same name as a\n * rejection (create-only callers). When false, same-name passes\n * through silently so the caller can dispatch the evolve path.\n */\n rejectSameName?: boolean;\n }): Record<string, unknown> | null {\n // (1) Same-name check\n const existingSameName = getSkillRecordByName(args.name);\n if (existingSameName) {\n if (args.rejectSameName) {\n return {\n error:\n `Skill \"${args.name}\" already exists. This path is create-only. ` +\n 'Use vault_write_skill to evolve the existing skill (it bumps the generation), ' +\n 'or mark the current record stale via vault_skill_records first.',\n existing_skill: {\n id: existingSameName.id,\n name: existingSameName.name,\n path: existingSameName.path,\n },\n };\n }\n return null;\n }\n\n // (2) Candidate-already-fulfilled check\n if (args.candidate_id) {\n const candidate = getCandidate(args.candidate_id);\n if (candidate?.skill_id) {\n const linkedSkill = getSkillRecord(candidate.skill_id);\n if (linkedSkill && linkedSkill.name !== args.name) {\n return {\n error:\n `Candidate ${args.candidate_id} is already fulfilled by skill \"${linkedSkill.name}\". ` +\n 'Do not create a sibling skill. If the existing skill needs changes, ' +\n 'write to the same name to evolve it (this bumps its generation), or ' +\n 'mark it stale via vault_skill_records before replacing.',\n existing_skill: {\n id: linkedSkill.id,\n name: linkedSkill.name,\n description: linkedSkill.description,\n path: linkedSkill.path,\n },\n };\n }\n }\n }\n\n // (3) Description similarity check\n const activeSkills = listSkillRecords({ agent_id: agentId, status: 'active', limit: 200 });\n let bestMatch: { skill: typeof activeSkills[number]; score: number } | null = null;\n for (const skill of activeSkills) {\n const score = descriptionSimilarity(args.description, skill.description);\n if (score >= DESCRIPTION_DUPLICATE_THRESHOLD && (!bestMatch || score > bestMatch.score)) {\n bestMatch = { skill, score };\n }\n }\n if (bestMatch) {\n return {\n error:\n `Description overlaps with existing active skill \"${bestMatch.skill.name}\" ` +\n `(Jaccard ${bestMatch.score.toFixed(2)}, threshold ${DESCRIPTION_DUPLICATE_THRESHOLD}). ` +\n 'Do not create a duplicate. Either evolve the existing skill by writing to ' +\n `its name (\"${bestMatch.skill.name}\"), or reframe this skill so its description ` +\n 'describes a distinct procedure.',\n overlapping_skill: {\n id: bestMatch.skill.id,\n name: bestMatch.skill.name,\n description: bestMatch.skill.description,\n path: bestMatch.skill.path,\n },\n similarity: bestMatch.score,\n };\n }\n\n return null;\n }\n\n /**\n * Shared create-path promotion: write SKILL.md to the live\n * .agents/skills/<name>/ directory, create symbiont symlinks, then\n * insert the skill_records row + lineage entry in one DB transaction.\n * If the transaction throws, the disk write is reversed so no orphan\n * file survives.\n *\n * Used by both vault_write_skill's create branch and\n * vault_finalize_skill. Evolve (generation > 1) stays inline in\n * vault_write_skill because its rollback semantics differ — it\n * restores prior content rather than deleting the whole directory.\n *\n * `linkCandidate` runs inside the same transaction after the record\n * is inserted. Callers use it for their own candidate-linking policy:\n * vault_write_skill does an exact/prefix search over approved\n * candidates; vault_finalize_skill sets the candidate directly from\n * the staged manifest.\n */\n async function promoteNewSkill(params: {\n name: string;\n display_name: string;\n description: string;\n content: string;\n source_ids?: string;\n candidate_id?: string | null;\n rationale?: string;\n linkCandidate?: (recordId: string, now: number) => void;\n label: string;\n }): Promise<\n | { id: string; name: string; path: string; generation: number }\n | { error: string }\n > {\n const root = projectRoot ?? process.cwd();\n const skillDir = resolve(root, '.agents', 'skills', params.name);\n const skillPath = resolve(skillDir, 'SKILL.md');\n // If the directory already exists for a create, it's an orphan\n // from a prior failed run — we overwrite the file and only remove\n // the file itself on rollback (not the whole directory) to avoid\n // clobbering anything else that may share the dir.\n const skillDirPreexisted = existsSync(skillDir);\n\n async function cleanupCreatedSkillArtifactsOnRollback(): Promise<void> {\n try {\n if (!skillDirPreexisted) {\n rmSync(skillDir, { recursive: true, force: true });\n } else {\n rmSync(skillPath, { force: true });\n }\n } catch (rollbackErr) {\n console.warn(\n `[${params.label}] file rollback after DB failure also failed:`,\n rollbackErr instanceof Error ? rollbackErr.message : rollbackErr,\n );\n }\n\n try {\n const { syncSkillSymlinks } = await import('@myco/symbionts/installer.js');\n syncSkillSymlinks(root, params.name, { remove: true });\n } catch (rollbackErr) {\n console.warn(\n `[${params.label}] symlink rollback after DB failure also failed:`,\n rollbackErr instanceof Error ? rollbackErr.message : rollbackErr,\n );\n }\n }\n\n try {\n mkdirSync(skillDir, { recursive: true });\n writeFileSync(skillPath, params.content, 'utf-8');\n } catch (err) {\n return {\n error: `Failed to write skill file: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n try {\n const { syncSkillSymlinks } = await import('@myco/symbionts/installer.js');\n syncSkillSymlinks(root, params.name);\n } catch (err) {\n console.warn(\n `[${params.label}] syncSkillSymlinks failed:`,\n err instanceof Error ? err.message : err,\n );\n }\n\n const now = epochSeconds();\n const relativePath = `.agents/skills/${params.name}/SKILL.md`;\n const recordId = crypto.randomUUID();\n const generation = 1;\n\n const txDb = getDatabase();\n try {\n txDb.transaction(() => {\n insertSkillRecord({\n id: recordId,\n agent_id: agentId,\n machine_id: machineId,\n name: params.name,\n display_name: params.display_name,\n description: params.description,\n candidate_id: params.candidate_id ?? null,\n source_ids: params.source_ids,\n path: relativePath,\n created_at: now,\n updated_at: now,\n });\n\n insertLineage({\n id: crypto.randomUUID(),\n skill_id: recordId,\n generation,\n action: 'created',\n rationale: params.rationale ?? 'Initial skill creation',\n source_ids_added: params.source_ids,\n content_snapshot: params.content,\n created_at: now,\n });\n\n params.linkCandidate?.(recordId, now);\n })();\n } catch (err) {\n await cleanupCreatedSkillArtifactsOnRollback();\n return {\n error: `Skill write aborted: database transaction failed and on-disk state was rolled back. ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n return {\n id: recordId,\n name: params.name,\n path: relativePath,\n generation,\n };\n }\n\n /** Emit the standard notification after a successful create or evolve. */\n function emitSkillNotification(\n kind: 'created' | 'evolved',\n opts: { name: string; display_name: string; description: string; recordId: string; generation: number },\n ) {\n notify(vaultDir, {\n domain: 'skills',\n type: kind === 'created' ? 'skill.created' : 'skill.evolved',\n title: `Skill ${kind}: ${opts.display_name}`,\n message: opts.description.slice(0, 120),\n link: `/skills?skill=${encodeURIComponent(opts.name)}`,\n metadata: { skillId: opts.recordId, name: opts.name, generation: opts.generation },\n });\n }\n\n const vaultSkillCandidates = tool(\n 'vault_skill_candidates',\n 'Manage skill candidates (identified topics that may become skills). Supports list, get, create, and update actions.',\n {\n action: z.enum(['list', 'get', 'create', 'update', 'delete']).describe('Action to perform'),\n id: z.string().optional().describe('Candidate ID (required for get/update)'),\n topic: z.string().optional().describe('Skill topic (required for create)'),\n rationale: z.string().optional().describe('Why this should be a skill (required for create)'),\n confidence: z.number().optional().describe('Confidence score 0-1'),\n status: z.enum(AGENT_SETTABLE_STATUSES as readonly [string, ...string[]]).optional().describe(\n \"Candidate status — agent-settable values only. 'identified' is \" +\n \"the initial state; 'dismissed' retires a candidate. 'approved' \" +\n \"and 'generated' are lifecycle transitions owned by the human UI \" +\n 'and vault_finalize_skill respectively.',\n ),\n source_ids: z.string().optional().describe('JSON array of source spore/entity IDs'),\n skill_id: z.string().optional().describe('Associated skill record ID (after materialization)'),\n limit: z.number().optional().describe('Maximum candidates to return (for list)'),\n },\n async (args) => {\n recordTurn('vault_skill_candidates', args);\n\n switch (args.action) {\n case 'list': {\n const candidates = listCandidates({\n agent_id: agentId,\n status: args.status,\n limit: args.limit ?? DEFAULT_LIST_LIMIT,\n });\n return textResult(candidates);\n }\n\n case 'get': {\n if (!args.id) return textResult({ error: 'id is required for get action' });\n const candidate = getCandidate(args.id);\n if (!candidate) return textResult({ error: `Candidate not found: ${args.id}` });\n return textResult(candidate);\n }\n\n case 'create': {\n if (!args.topic || !args.rationale) {\n return textResult({ error: 'topic and rationale are required for create action' });\n }\n\n // Guard 1: reject if an active skill already covers this topic.\n // Checks whether all significant words from a skill name appear in the topic.\n const activeSkills = listSkillRecords({ agent_id: agentId, status: 'active', limit: 100 });\n const topicLower = args.topic.toLowerCase();\n const overlapping = activeSkills.filter((s) => {\n const nameWords = s.name.split('-').filter((w: string) => w.length > 2);\n if (nameWords.length < 2) return false;\n return nameWords.every((w: string) => topicLower.includes(w));\n });\n if (overlapping.length > 0) {\n return textResult({\n error: 'Candidate rejected: active skill(s) already cover this topic. Update the existing skill via vault_skill_records instead.',\n overlapping_skills: overlapping.map((s) => ({ name: s.name, display_name: s.display_name, description: s.description })),\n });\n }\n\n // Guard 2: reject if an existing candidate (any status) has an\n // overlapping topic. The skill-survey prompt tells the agent to\n // check dismissed/generated candidates before re-identifying,\n // but self-grading is unreliable so the check is enforced here.\n const allExisting = listCandidates({ agent_id: agentId, limit: 500 });\n const match = findOverlappingCandidate(args.topic, allExisting);\n if (match) {\n return textResult({\n error: candidateOverlapError(match.candidate),\n existing_candidate: {\n id: match.candidate.id,\n status: match.candidate.status,\n topic: match.candidate.topic,\n },\n similarity: match.score,\n });\n }\n\n const now = epochSeconds();\n const candidate = insertCandidate({\n id: crypto.randomUUID(),\n agent_id: agentId,\n machine_id: machineId,\n topic: args.topic,\n rationale: args.rationale,\n confidence: args.confidence,\n status: args.status,\n source_ids: args.source_ids,\n created_at: now,\n updated_at: now,\n });\n notify(vaultDir, {\n domain: 'skills',\n type: 'skill.surveyed',\n title: `Skill candidate: ${args.topic}`,\n message: args.rationale.slice(0, 120),\n link: '/skills?tab=candidates',\n metadata: { candidateId: candidate.id, topic: args.topic },\n });\n return textResult(candidate);\n }\n\n case 'update': {\n if (!args.id) return textResult({ error: 'id is required for update action' });\n const now = epochSeconds();\n const updated = updateCandidate(args.id, {\n ...(args.topic !== undefined ? { topic: args.topic } : {}),\n ...(args.rationale !== undefined ? { rationale: args.rationale } : {}),\n ...(args.confidence !== undefined ? { confidence: args.confidence } : {}),\n ...(args.status !== undefined ? { status: args.status } : {}),\n ...(args.source_ids !== undefined ? { source_ids: args.source_ids } : {}),\n ...(args.skill_id !== undefined ? { skill_id: args.skill_id } : {}),\n updated_at: now,\n });\n if (!updated) return textResult({ error: `Candidate not found: ${args.id}` });\n return textResult(updated);\n }\n\n case 'delete': {\n if (!args.id) return textResult({ error: 'id is required for delete action' });\n const deleted = deleteCandidate(args.id);\n if (!deleted) return textResult({ error: `Candidate not found: ${args.id}` });\n return textResult({ deleted: true, id: args.id });\n }\n\n default:\n return textResult({ error: `Unknown action: ${args.action}` });\n }\n },\n { annotations: {} },\n );\n\n const vaultSkillRecords = tool(\n 'vault_skill_records',\n 'Read, update, and delete skill records (materialized skills on disk). Supports list, get, update, and delete actions.',\n {\n action: z.enum(['list', 'get', 'update', 'delete']).describe('Action to perform'),\n id: z.string().optional().describe('Skill record ID or name (required for get/update/delete)'),\n status: z.enum(['active', 'stale', 'retired']).optional().describe('Filter by status'),\n generation: z.number().optional().describe('New generation number (for update)'),\n source_ids: z.string().optional().describe('JSON array of source IDs (for update)'),\n description: z.string().optional().describe('Updated description (for update)'),\n limit: z.number().optional().describe('Maximum records to return (for list)'),\n },\n async (args) => {\n recordTurn('vault_skill_records', args);\n\n switch (args.action) {\n case 'list': {\n const records = listSkillRecords({\n agent_id: agentId,\n status: args.status,\n limit: args.limit ?? DEFAULT_LIST_LIMIT,\n });\n return textResult(records);\n }\n\n case 'get': {\n if (!args.id) return textResult({ error: 'id is required for get action' });\n const record = getSkillRecord(args.id) ?? getSkillRecordByName(args.id);\n if (!record) return textResult({ error: `Skill record not found: ${args.id}` });\n return textResult(record);\n }\n\n case 'update': {\n if (!args.id) return textResult({ error: 'id is required for update action' });\n // Resolve by id or name\n const existing = getSkillRecord(args.id) ?? getSkillRecordByName(args.id);\n if (!existing) return textResult({ error: `Skill record not found: ${args.id}` });\n\n const now = epochSeconds();\n const updated = updateSkillRecord(existing.id, {\n ...(args.status !== undefined ? { status: args.status } : {}),\n ...(args.generation !== undefined ? { generation: args.generation } : {}),\n ...(args.source_ids !== undefined ? { source_ids: args.source_ids } : {}),\n ...(args.description !== undefined ? { description: args.description } : {}),\n updated_at: now,\n });\n if (!updated) return textResult({ error: `Failed to update skill record: ${existing.id}` });\n return textResult(updated);\n }\n\n case 'delete': {\n if (!args.id) return textResult({ error: 'id is required for delete action' });\n const result = deleteSkillRecordCascade(args.id);\n if (!result) return textResult({ error: `Skill record not found: ${args.id}` });\n // Disk + symlink cleanup (best-effort)\n const root = projectRoot ?? process.cwd();\n if (!/[/\\\\]|\\.\\./.test(result.name)) {\n const skillDir = resolve(root, '.agents', 'skills', result.name);\n try { rmSync(skillDir, { recursive: true, force: true }); } catch (err) {\n console.warn('[vault_skill_records] Failed to remove skill directory:', err instanceof Error ? err.message : err);\n }\n try {\n const { syncSkillSymlinks } = await import('@myco/symbionts/installer.js');\n syncSkillSymlinks(root, result.name, { remove: true });\n } catch (err) {\n console.warn('[vault_skill_records] Failed to remove symlinks:', err instanceof Error ? err.message : err);\n }\n }\n return textResult({ deleted: true, id: result.id, name: result.name });\n }\n\n default:\n return textResult({ error: `Unknown action: ${args.action}` });\n }\n },\n { annotations: {} },\n );\n\n const vaultWriteSkill = tool(\n 'vault_write_skill',\n 'Write a SKILL.md file to disk and create or update the corresponding skill record and lineage entry.',\n {\n name: z.string().describe('Skill directory name (kebab-case, NO colon). The myco: prefix goes in the SKILL.md frontmatter name field, not here.'),\n display_name: z.string().describe('Human-readable display name'),\n description: z.string().describe('Short description of what the skill does'),\n content: z.string().describe('Full SKILL.md content in markdown'),\n source_ids: z.string().optional().describe('JSON array of source spore/entity IDs'),\n candidate_id: z.string().optional().describe('Candidate ID that prompted this skill creation'),\n rationale: z.string().optional().describe('Why this skill was created or updated'),\n },\n async (args) => {\n // Validate skill content before writing -- reject malformed skills\n const validationErrors = validateSkillContent(args.content, args.name);\n if (validationErrors.length > 0) {\n recordTurn('vault_write_skill', args);\n return textResult({\n error: 'Skill validation failed. Fix these issues and try again.',\n issues: validationErrors,\n });\n }\n\n // Path traversal guard -- reject names containing path separators or dot-dot sequences\n if (!args.name || /[/\\\\]|\\.\\./.test(args.name)) {\n recordTurn('vault_write_skill', args);\n return textResult({\n error: 'Invalid skill name: must be a simple directory name without path separators or \"..\"',\n });\n }\n\n // Dedup gate is self-gating: returns null when same-name exists\n // (the evolve path) so the caller falls through.\n const dedupError = checkDedupGates({\n candidate_id: args.candidate_id,\n name: args.name,\n description: args.description,\n });\n if (dedupError) {\n recordTurn('vault_write_skill', args);\n return textResult(dedupError);\n }\n const existing = getSkillRecordByName(args.name);\n\n const root = projectRoot ?? process.cwd();\n const skillPath = resolve(root, '.agents', 'skills', args.name, 'SKILL.md');\n\n // Frontmatter preservation guard — when updating an existing skill,\n // reject writes that change protected fields (user-invocable, allowed-tools).\n if (existsSync(skillPath)) {\n const existingContent = readFileSync(skillPath, 'utf-8');\n const violations = checkFrontmatterPreservation(existingContent, args.content);\n if (violations.length > 0) {\n recordTurn('vault_write_skill', args);\n return textResult({\n error: 'Skill update rejected: protected frontmatter fields were changed. Read the existing skill and preserve these values exactly.',\n violations,\n });\n }\n }\n\n // Create path: delegate to the shared promoteNewSkill helper.\n // Candidate linking uses exact-then-prefix matching since the\n // agent may pass a truncated UUID in the instruction.\n if (!existing) {\n // Structural gate: if the caller passed a candidate_id, the\n // candidate must be in 'approved' state. Evolve path (above)\n // skips this because the caller is updating an existing skill,\n // not materializing a fresh candidate.\n if (args.candidate_id) {\n const candidateError = requireApprovedCandidate(args.candidate_id);\n if (candidateError) {\n recordTurn('vault_write_skill', args);\n return textResult(candidateError);\n }\n }\n\n const linkCandidate = (recordId: string, now: number) => {\n if (!args.candidate_id) return;\n const exact = updateCandidate(args.candidate_id, {\n status: CANDIDATE_STATUS.GENERATED, skill_id: recordId, updated_at: now,\n });\n if (exact) return;\n const approvedCandidates = listCandidates({ status: CANDIDATE_STATUS.APPROVED, limit: 10 });\n const prefixMatch = approvedCandidates.find((c) => c.id.startsWith(args.candidate_id!));\n if (prefixMatch) {\n updateCandidate(prefixMatch.id, {\n status: CANDIDATE_STATUS.GENERATED, skill_id: recordId, updated_at: now,\n });\n }\n };\n\n const result = await promoteNewSkill({\n name: args.name,\n display_name: args.display_name,\n description: args.description,\n content: args.content,\n source_ids: args.source_ids,\n candidate_id: args.candidate_id,\n rationale: args.rationale,\n linkCandidate,\n label: 'vault_write_skill',\n });\n recordTurn('vault_write_skill', args);\n if ('error' in result) return textResult(result);\n emitSkillNotification('created', {\n name: result.name,\n display_name: args.display_name,\n description: args.description,\n recordId: result.id,\n generation: result.generation,\n });\n return textResult(result);\n }\n\n // Evolve path: update existing record, bump generation, preserve\n // prior SKILL.md content on rollback. This branch stays inline\n // because its rollback semantics (restore prior content) differ\n // from the create helper.\n const priorSkillContent = readFileSync(skillPath, 'utf-8');\n\n try {\n writeFileSync(skillPath, args.content, 'utf-8');\n } catch (err) {\n return textResult({ error: `Failed to write skill file: ${err instanceof Error ? err.message : String(err)}` });\n }\n\n try {\n const { syncSkillSymlinks } = await import('@myco/symbionts/installer.js');\n syncSkillSymlinks(root, args.name);\n } catch (err) {\n console.warn('[vault_write_skill] syncSkillSymlinks failed:', err instanceof Error ? err.message : err);\n }\n\n const now = epochSeconds();\n const relativePath = `.agents/skills/${args.name}/SKILL.md`;\n const generation = existing.generation + 1;\n const recordId = existing.id;\n\n const txDb = getDatabase();\n try {\n txDb.transaction(() => {\n updateSkillRecord(existing.id, {\n display_name: args.display_name,\n description: args.description,\n generation,\n ...(args.source_ids !== undefined ? { source_ids: args.source_ids } : {}),\n path: relativePath,\n updated_at: now,\n });\n\n insertLineage({\n id: crypto.randomUUID(),\n skill_id: existing.id,\n generation,\n action: 'updated',\n rationale: args.rationale ?? 'Skill content updated',\n source_ids_added: args.source_ids,\n content_snapshot: args.content,\n created_at: now,\n });\n })();\n } catch (err) {\n try {\n writeFileSync(skillPath, priorSkillContent, 'utf-8');\n } catch (rollbackErr) {\n console.warn(\n '[vault_write_skill] file rollback after DB failure also failed:',\n rollbackErr instanceof Error ? rollbackErr.message : rollbackErr,\n );\n }\n recordTurn('vault_write_skill', args);\n return textResult({\n error: `Skill write aborted: database transaction failed and on-disk state was rolled back. ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n\n emitSkillNotification('evolved', {\n name: args.name,\n display_name: args.display_name,\n description: args.description,\n recordId,\n generation,\n });\n\n recordTurn('vault_write_skill', args);\n return textResult({\n id: recordId,\n name: args.name,\n path: relativePath,\n generation,\n });\n },\n { annotations: { openWorldHint: true } },\n );\n\n const vaultStageSkill = tool(\n 'vault_stage_skill',\n \"Stage a provisional SKILL.md under .myco/staging/skills/<candidate_id>/ for later promotion by vault_finalize_skill. Use this from the skill-generate draft phase. The write is NOT live — the skill does not appear under .agents/skills/ and no DB rows are created until vault_finalize_skill is called with the same candidate_id.\",\n {\n candidate_id: z.string().describe(\n 'Candidate ID from the instruction. Required — staging is keyed by candidate so the validate phase (and on-failure cleanup) can find the staged content.',\n ),\n name: z.string().describe('Final skill directory name (kebab-case, no colon). Stored in the manifest for finalize.'),\n display_name: z.string().describe('Human-readable display name'),\n description: z.string().describe('Short description — used for the dedup gate and the final skill record'),\n content: z.string().describe('Full SKILL.md content in markdown including frontmatter'),\n source_ids: z.string().optional().describe('JSON array of source spore/entity IDs'),\n rationale: z.string().optional().describe('Why this skill is being created — stored in lineage after finalize'),\n },\n async (args) => {\n recordTurn('vault_stage_skill', args);\n\n if (!vaultDir) {\n return textResult({\n error: 'vault_stage_skill requires vaultDir on the tool deps — staging has no location otherwise',\n });\n }\n\n // Static validation — same rules as vault_write_skill\n const validationErrors = validateSkillContent(args.content, args.name);\n if (validationErrors.length > 0) {\n return textResult({\n error: 'Skill validation failed. Fix these issues and re-stage.',\n issues: validationErrors,\n });\n }\n\n // Path traversal guard for the skill name (which becomes a directory)\n if (!args.name || /[/\\\\]|\\.\\./.test(args.name)) {\n return textResult({\n error: 'Invalid skill name: must be a simple directory name without path separators or \"..\"',\n });\n }\n\n // Structural gate: candidate must exist and be in 'approved' state.\n const candidateError = requireApprovedCandidate(args.candidate_id);\n if (candidateError) return textResult(candidateError);\n\n // Dedup gate — create-only, so rejectSameName surfaces the\n // evolve path as an explicit error. Finalize re-runs the same\n // gate as defense in depth.\n const dedupError = checkDedupGates({\n candidate_id: args.candidate_id,\n name: args.name,\n description: args.description,\n rejectSameName: true,\n });\n if (dedupError) return textResult(dedupError);\n\n // Write staging content + manifest\n let stagingFilePath: string;\n try {\n stagingFilePath = writeStagedSkill(vaultDir, args.candidate_id, args.content);\n const manifest: StagedManifest = {\n candidate_id: args.candidate_id,\n name: args.name,\n display_name: args.display_name,\n description: args.description,\n source_ids: args.source_ids ?? '[]',\n rationale: args.rationale ?? 'Initial draft',\n };\n writeStagedManifest(vaultDir, args.candidate_id, manifest);\n } catch (err) {\n return textResult({\n error: `Failed to write staged skill: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n\n return textResult({\n candidate_id: args.candidate_id,\n staging_path: stagingFilePath,\n status: 'staged',\n });\n },\n { annotations: { openWorldHint: true } },\n );\n\n const vaultFinalizeSkill = tool(\n 'vault_finalize_skill',\n 'Promote a staged skill to live at .agents/skills/<name>/ and insert the skill_records / lineage rows. Call this from skill-generate validate phase after your quality checks pass. Requires vault_stage_skill to have been called earlier with the same candidate_id; reads the staged SKILL.md + manifest rather than taking duplicate metadata.',\n {\n candidate_id: z.string().describe('Candidate ID whose staged skill should be promoted. Must match a previous vault_stage_skill call.'),\n },\n async (args) => {\n recordTurn('vault_finalize_skill', args);\n\n if (!vaultDir) {\n return textResult({\n error: 'vault_finalize_skill requires vaultDir on the tool deps',\n });\n }\n\n // Read staged content + manifest\n const stagedContent = readStagedSkill(vaultDir, args.candidate_id);\n const manifest = readStagedManifest(vaultDir, args.candidate_id);\n if (!stagedContent || !manifest) {\n return textResult({\n error:\n `No staged skill found for candidate ${args.candidate_id}. ` +\n 'Call vault_stage_skill first.',\n });\n }\n\n // Defense-in-depth: candidate must still be 'approved' at\n // finalize time. If a human (or another tool) dismissed the\n // candidate between stage and finalize, the finalize should\n // refuse rather than promote the now-rescinded skill.\n const candidateError = requireApprovedCandidate(args.candidate_id);\n if (candidateError) return textResult(candidateError);\n\n // Defense-in-depth: re-run validation against the staged content.\n // The staging write already validated once, but the file on disk\n // could have been mutated (tests do this explicitly to check the\n // guard; a crash between stage and finalize could too).\n const validationErrors = validateSkillContent(stagedContent, manifest.name);\n if (validationErrors.length > 0) {\n return textResult({\n error: 'Staged skill failed validation on finalize. Re-stage with valid content.',\n issues: validationErrors,\n });\n }\n\n // Defense-in-depth: re-run dedup against the manifest-declared\n // description. Catches the \"agent staged a fresh description,\n // then tampered the manifest to collide with a live skill\" case,\n // and also trips if a concurrent evolve landed a same-named skill\n // between stage and finalize.\n const dedupError = checkDedupGates({\n candidate_id: args.candidate_id,\n name: manifest.name,\n description: manifest.description,\n rejectSameName: true,\n });\n if (dedupError) return textResult(dedupError);\n\n // Promote via the shared helper. Candidate link is direct — the\n // staged manifest guarantees candidate_id exists, so no search.\n // updateCandidate moves the candidate OUT of 'approved' so its\n // approved_at audit timestamp is preserved by construction.\n const result = await promoteNewSkill({\n name: manifest.name,\n display_name: manifest.display_name,\n description: manifest.description,\n content: stagedContent,\n source_ids: manifest.source_ids,\n candidate_id: manifest.candidate_id,\n rationale: manifest.rationale,\n linkCandidate: (recordId, now) => {\n updateCandidate(manifest.candidate_id, {\n status: CANDIDATE_STATUS.GENERATED,\n skill_id: recordId,\n updated_at: now,\n });\n },\n label: 'vault_finalize_skill',\n });\n if ('error' in result) return textResult(result);\n\n // Success — clean up staging and notify.\n cleanupStagedSkill(vaultDir, args.candidate_id);\n emitSkillNotification('created', {\n name: manifest.name,\n display_name: manifest.display_name,\n description: manifest.description,\n recordId: result.id,\n generation: result.generation,\n });\n\n return textResult(result);\n },\n { annotations: { openWorldHint: true } },\n );\n\n return [\n vaultSkillCandidates,\n vaultSkillRecords,\n vaultWriteSkill,\n vaultStageSkill,\n vaultFinalizeSkill,\n ];\n}\n","/**\n * Skill content validation.\n *\n * Deterministic quality gate -- the agent must fix all issues before\n * a skill is accepted.\n */\n\n/** Maximum lines for a generated skill. */\nexport const MAX_SKILL_LINES = 500;\n\n/** Required frontmatter fields for Myco-managed skills. */\nexport const REQUIRED_FRONTMATTER_FIELDS = ['name', 'description', 'managed_by', 'user-invocable', 'allowed-tools'] as const;\n\n/** Frontmatter fields that must not change when updating an existing skill. */\nexport const PROTECTED_FRONTMATTER_FIELDS = ['user-invocable', 'allowed-tools'] as const;\n\n/**\n * Whitelist of Claude Code tool names that may appear in `allowed-tools`.\n * Myco-managed skills run in developer Claude Code sessions — anything not\n * on this list is almost certainly a model confabulation (e.g. \"[None]\",\n * \"ReadFile\", \"search\", or a vault_* tool copied from the agent's own context).\n *\n * Kept intentionally narrow: add entries when a legitimate tool is rejected.\n */\nexport const ALLOWED_CLAUDE_CODE_TOOLS: ReadonlySet<string> = new Set([\n 'Read', 'Edit', 'Write', 'MultiEdit', 'Bash', 'Grep', 'Glob',\n 'NotebookRead', 'NotebookEdit', 'WebFetch', 'WebSearch',\n 'Task', 'TodoWrite',\n]);\n\n/**\n * Extract a frontmatter field value from SKILL.md content.\n * Returns the raw value string, or undefined if not found.\n */\nexport function extractFrontmatterField(content: string, field: string): string | undefined {\n const fmMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!fmMatch) return undefined;\n const match = fmMatch[1].match(new RegExp(`^${field}:\\\\s*(.+)$`, 'm'));\n return match?.[1].trim();\n}\n\n/**\n * Parse the `allowed-tools` frontmatter value into a list of tool names.\n *\n * Accepts either of these YAML shapes:\n * allowed-tools: Read, Edit, Write\n * allowed-tools: [Read, Edit, Write]\n *\n * Returns null if the value is absent, empty, or clearly malformed\n * (e.g. a bare word like `None`, or a list containing `None` / `null`).\n * Caller treats null as a validation failure.\n */\nexport function parseAllowedTools(rawValue: string | undefined): string[] | null {\n if (!rawValue) return null;\n let stripped = rawValue.trim();\n if (stripped.length === 0) return null;\n\n // Strip YAML inline-list brackets if present: [Read, Edit] -> Read, Edit\n if (stripped.startsWith('[') && stripped.endsWith(']')) {\n stripped = stripped.slice(1, -1).trim();\n }\n if (stripped.length === 0) return null;\n\n const parts = stripped\n .split(',')\n .map((s) => s.trim().replace(/^['\"]|['\"]$/g, '')) // strip quotes\n .filter((s) => s.length > 0);\n\n if (parts.length === 0) return null;\n\n // Reject literal \"None\" / \"null\" / \"~\" — common model confabulations\n // when the model means \"no tools needed.\"\n const sentinels = new Set(['None', 'none', 'null', 'Null', '~']);\n if (parts.some((p) => sentinels.has(p))) return null;\n\n return parts;\n}\n\n/**\n * Light English stemmer applied to every significant token before set\n * comparison. Collapses common suffix variants so that `task`/`tasks`,\n * `gate`/`gates`, `model`/`models`, `configure`/`configuring`, and\n * `implement`/`implemented` all share a stem.\n *\n * The order matters: strip -ing / -ed before trailing -s so \"parking\"\n * doesn't become \"parkin\" then \"parki\"; strip trailing -e last so\n * \"validate\" and \"validating\" both land on \"validat\".\n *\n * Length guards prevent degenerate stems on short words (e.g. \"ring\"\n * must not become empty, \"cod\" must not become \"c\").\n */\nfunction stemToken(word: string): string {\n let w = word;\n if (w.length > 5 && w.endsWith('ing')) w = w.slice(0, -3);\n else if (w.length > 5 && w.endsWith('ed')) w = w.slice(0, -2);\n if (w.length > 4 && w.endsWith('s')) w = w.slice(0, -1);\n if (w.length > 4 && w.endsWith('e')) w = w.slice(0, -1);\n return w;\n}\n\n/**\n * Lowercase-word token set from a string, excluding stopwords and\n * short/noise tokens, with light stemming applied. Used for all\n * similarity metrics in this file.\n */\nfunction tokenSet(text: string): Set<string> {\n const stopwords = new Set([\n 'the', 'a', 'an', 'and', 'or', 'but', 'is', 'are', 'was', 'were',\n 'be', 'been', 'being', 'have', 'has', 'had', 'do', 'does', 'did',\n 'will', 'would', 'should', 'could', 'may', 'might', 'must', 'can',\n 'this', 'that', 'these', 'those', 'with', 'from', 'into', 'onto',\n 'for', 'when', 'where', 'which', 'what', 'who', 'how', 'why',\n 'use', 'uses', 'used', 'using', 'not', 'also', 'than', 'then',\n 'ensure', 'ensures', 'make', 'makes',\n ]);\n return new Set(\n text\n .toLowerCase()\n .replace(/[^a-z0-9_\\s]/g, ' ')\n .split(/\\s+/)\n .filter((w) => w.length >= 4 && !stopwords.has(w))\n .map(stemToken),\n );\n}\n\n/** Internal helper: count shared stems between two token sets. */\nfunction intersectionSize(a: Set<string>, b: Set<string>): number {\n let count = 0;\n for (const token of a) {\n if (b.has(token)) count++;\n }\n return count;\n}\n\n/**\n * Jaccard similarity between two text strings on their significant-word\n * token sets. Returns a value in [0, 1].\n *\n * Purpose: detect near-duplicate skill descriptions so `vault_write_skill`\n * can refuse to create sibling skills covering the same topic. This is a\n * deterministic gate — unlike asking the model to self-check for conflicts,\n * which is known to hallucinate \"no overlap\" on visibly overlapping pairs.\n */\nexport function descriptionSimilarity(a: string, b: string): number {\n const aTokens = tokenSet(a);\n const bTokens = tokenSet(b);\n if (aTokens.size === 0 || bTokens.size === 0) return 0;\n\n const intersection = intersectionSize(aTokens, bTokens);\n const union = aTokens.size + bTokens.size - intersection;\n return union === 0 ? 0 : intersection / union;\n}\n\n/**\n * Overlap coefficient (Szymkiewicz–Simpson) between two topic strings:\n * `|A ∩ B| / min(|A|, |B|)`. Returns 0 when either side has fewer than\n * `minTokens` significant tokens — 1-2 token topics are dominated by\n * single-token collisions under this metric and must fall back to\n * Jaccard for duplicate detection.\n *\n * Why this exists alongside `descriptionSimilarity`: candidate topics are\n * often short kebab-case labels like `add-idle-skip-watermark-to-agent-task`\n * (5 tokens) paired against longer natural-language topics like\n * `Implementing DB Watermark Prefilters for Incremental Agent Tasks`\n * (6 tokens). The asymmetric token-count inflates Jaccard's union and\n * pushes real duplicates below the 0.4 threshold. Overlap coefficient is\n * robust to that asymmetry because the denominator is the smaller set.\n *\n * The 3-token minimum is calibrated to catch cases like\n * `publish-npm-package-with-oidc-in-ci` (3 significant tokens) against\n * `npm OIDC Trusted Publishing in GitHub Actions` (5 tokens) while\n * leaving 2-token topic pairs to the Jaccard path. Two-token topics\n * with a single shared word would score 0.5 under naive overlap —\n * noisy — so they are deliberately excluded.\n */\nexport function topicOverlapSimilarity(\n a: string,\n b: string,\n minTokens: number = 3,\n): number {\n const aTokens = tokenSet(a);\n const bTokens = tokenSet(b);\n if (aTokens.size < minTokens || bTokens.size < minTokens) return 0;\n\n const intersection = intersectionSize(aTokens, bTokens);\n const smaller = Math.min(aTokens.size, bTokens.size);\n return smaller === 0 ? 0 : intersection / smaller;\n}\n\n/**\n * Similarity threshold above which two descriptions are treated as\n * covering the same topic. Chosen empirically from the unifi-mcp incident\n * that motivated this gate: the real duplicate pair\n * (`unifi-validator-coercion-pattern` vs `unifi-validator-registry-coercion`)\n * scored ~0.42 on this metric — lower than intuition suggests because each\n * description reframes roughly half its content with different wording.\n * Clearly-distinct skill pairs score under 0.2 on the same metric, so 0.4\n * is a comfortable middle that catches real duplicates without flagging\n * incidentally-adjacent topics.\n *\n * Tuning note: the cost of a false positive here is \"agent must reframe\n * its description and try again\" (low); the cost of a false negative is\n * \"sibling skill on disk for the same topic\" (high). Lean aggressive.\n */\nexport const DESCRIPTION_DUPLICATE_THRESHOLD = 0.4;\n\n/**\n * Threshold for the overlap-coefficient topic dedup path. At 0.6 and\n * with a 4-token minimum, this catches recent false negatives where\n * short kebab-case topics were re-identifying dismissed natural-language\n * candidates (watermark/agent/task overlap, structural/enforcement/gate\n * overlap, configure/local/model overlap) while leaving genuinely-new\n * candidates like `implement-spa-sub-navigation-with-browser-history`\n * unaffected.\n */\nexport const TOPIC_OVERLAP_THRESHOLD = 0.6;\n\n/**\n * Compare protected frontmatter fields between existing and new content.\n * Returns an array of violation descriptions (empty = all preserved).\n *\n * Also guards against description shortening — the description is the\n * primary triggering mechanism for skills, so losing content degrades\n * skill activation quality.\n */\nexport function checkFrontmatterPreservation(existing: string, incoming: string): string[] {\n const violations: string[] = [];\n for (const field of PROTECTED_FRONTMATTER_FIELDS) {\n const oldValue = extractFrontmatterField(existing, field);\n const newValue = extractFrontmatterField(incoming, field);\n if (oldValue !== undefined && newValue !== undefined && oldValue !== newValue) {\n violations.push(`${field}: was \"${oldValue}\", changed to \"${newValue}\"`);\n }\n }\n\n // Guard against description shortening — descriptions drive skill triggering.\n // Lengthening is allowed (adding context), shortening is not (losing trigger keywords).\n const oldDesc = extractFrontmatterField(existing, 'description');\n const newDesc = extractFrontmatterField(incoming, 'description');\n if (oldDesc && newDesc && newDesc.length < oldDesc.length * 0.9) {\n violations.push(\n `description shortened from ${oldDesc.length} to ${newDesc.length} chars (${Math.round((1 - newDesc.length / oldDesc.length) * 100)}% reduction). ` +\n 'Descriptions are the primary triggering mechanism — do not shorten them.',\n );\n }\n\n return violations;\n}\n\n/**\n * Validate skill content before writing. Returns an array of issues\n * (empty = valid). This is a deterministic quality gate -- the agent\n * must fix all issues before the skill is accepted.\n */\nexport function validateSkillContent(content: string, dirName: string): string[] {\n const issues: string[] = [];\n\n // Check for frontmatter delimiters\n const fmMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!fmMatch) {\n issues.push('Missing YAML frontmatter (must start with --- and end with ---)');\n return issues; // Can't check fields without frontmatter\n }\n\n const frontmatter = fmMatch[1];\n\n // Check required fields\n for (const field of REQUIRED_FRONTMATTER_FIELDS) {\n if (!frontmatter.includes(`${field}:`)) {\n issues.push(`Missing required frontmatter field: ${field}`);\n }\n }\n\n // Check myco: prefix on name\n const nameMatch = frontmatter.match(/^name:\\s*(.+)$/m);\n if (nameMatch && !nameMatch[1].trim().startsWith('myco:')) {\n issues.push(`Skill name must start with \"myco:\" prefix. Got: \"${nameMatch[1].trim()}\"`);\n }\n\n // Check managed_by: myco\n const managedMatch = frontmatter.match(/^managed_by:\\s*(.+)$/m);\n if (managedMatch && managedMatch[1].trim() !== 'myco') {\n issues.push(`managed_by must be \"myco\". Got: \"${managedMatch[1].trim()}\"`);\n }\n\n // Check allowed-tools values -- must be Claude Code tool names, not vault agent tools.\n // These skills run in developer Claude Code sessions, not the agent pipeline.\n const allowedToolsMatch = frontmatter.match(/^allowed-tools:\\s*(.+)$/m);\n if (allowedToolsMatch) {\n const rawValue = allowedToolsMatch[1].trim();\n // Reject vault_* tool names first — most informative message for the\n // common LLM mistake of copying its own agent tool context into the skill.\n if (rawValue.includes('vault_')) {\n issues.push(\n 'allowed-tools contains vault agent tool names (vault_*). ' +\n 'Skills run in Claude Code sessions -- use Claude Code tool names instead: ' +\n 'Read, Edit, Write, Bash, Grep, Glob',\n );\n } else {\n // Positive whitelist check — catches \"[None]\", \"None\", invented tool\n // names, and other confabulations that the vault_* reject misses.\n const parsed = parseAllowedTools(rawValue);\n if (parsed === null) {\n issues.push(\n `allowed-tools value is malformed or empty: \"${rawValue}\". ` +\n 'Provide a comma-separated list of Claude Code tools, e.g. ' +\n '\"Read, Edit, Write, Bash, Grep, Glob\". Use the narrowest set ' +\n 'the skill actually needs.',\n );\n } else {\n const unknown = parsed.filter((t) => !ALLOWED_CLAUDE_CODE_TOOLS.has(t));\n if (unknown.length > 0) {\n issues.push(\n `allowed-tools contains unknown tool name(s): ${unknown.join(', ')}. ` +\n `Valid Claude Code tools: ${[...ALLOWED_CLAUDE_CODE_TOOLS].join(', ')}.`,\n );\n }\n }\n }\n }\n // Also check YAML list format (- vault_search_fts etc.)\n const listToolLines = frontmatter.match(/^\\s+-\\s+vault_\\w+/gm);\n if (listToolLines) {\n issues.push(\n 'allowed-tools contains vault agent tool names (vault_*). ' +\n 'Skills run in Claude Code sessions -- use Claude Code tool names instead: ' +\n 'Read, Edit, Write, Bash, Grep, Glob',\n );\n }\n\n // Check line count\n const lineCount = content.split('\\n').length;\n if (lineCount > MAX_SKILL_LINES) {\n issues.push(`Skill is ${lineCount} lines (max ${MAX_SKILL_LINES})`);\n }\n\n return issues;\n}\n","/**\n * Vault context builder for agent task prompt injection.\n *\n * Queries SQLite for aggregate vault metrics and agent state,\n * then formats them as a markdown block suitable for inclusion\n * in the agent's task prompt.\n */\n\nimport { getDatabase } from '@myco/db/client.js';\nimport { getStatesForAgent } from '@myco/db/queries/agent-state.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Default value for unset state entries. */\nconst STATE_UNSET = '(unset)';\n\n/** Key used by the agent to store its last processed batch ID. */\nconst STATE_KEY_LAST_PROCESSED_BATCH = 'last_processed_batch_id';\n\n/** Status value for active spores. */\nconst SPORE_STATUS_ACTIVE = 'active';\n\n// ---------------------------------------------------------------------------\n// Count helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Count rows in a table with optional WHERE clause.\n *\n * The table name is validated by the caller (always a literal from this module).\n * Parameterized `conditions` protect against SQL injection for dynamic values.\n */\nfunction countRows(\n table: string,\n conditions: Array<{ clause: string; value: unknown }> = [],\n): number {\n const db = getDatabase();\n\n const whereParts: string[] = [];\n const params: unknown[] = [];\n\n for (const { clause, value } of conditions) {\n whereParts.push(clause);\n params.push(value);\n }\n\n const whereClause = whereParts.length > 0 ? `WHERE ${whereParts.join(' AND ')}` : '';\n\n const row = db.prepare(\n `SELECT count(*) AS count FROM ${table} ${whereClause}`,\n ).get(...params) as { count: number };\n\n return Number(row.count);\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Build a markdown context block describing the current vault state\n * for a specific agent.\n *\n * Includes:\n * - Agent state key-value pairs (cursor position, preferences)\n * - Aggregate counts (sessions, spores, entities, edges, unprocessed batches)\n * - Last digest timestamp (if any)\n *\n * @param agentId — the agent to build context for.\n * @returns a markdown-formatted string.\n */\nexport function buildVaultContext(agentId: string): string {\n // All queries are synchronous\n const states = getStatesForAgent(agentId);\n const totalSessions = countRows('sessions');\n const totalActiveSpores = countRows('spores', [{ clause: 'status = ?', value: SPORE_STATUS_ACTIVE }]);\n const totalEntities = countRows('entities');\n const totalEdges = countRows('graph_edges');\n const unprocessedBatches = countRows('prompt_batches', [{ clause: 'processed = ?', value: 0 }]);\n const lastDigestAt = getLastDigestTimestamp(agentId);\n\n const stateMap = new Map(states.map((s) => [s.key, s.value]));\n\n const lastProcessedBatchId = stateMap.get(STATE_KEY_LAST_PROCESSED_BATCH) ?? STATE_UNSET;\n\n const lines = [\n '## Current Vault State',\n `agent_id: ${agentId}`,\n `last_processed_batch_id: ${lastProcessedBatchId}`,\n `unprocessed_batches: ${unprocessedBatches}`,\n `total_sessions: ${totalSessions}`,\n `total_active_spores: ${totalActiveSpores}`,\n `total_entities: ${totalEntities}`,\n `total_edges: ${totalEdges}`,\n `last_digest_at: ${lastDigestAt}`,\n ];\n\n return lines.join('\\n');\n}\n\n/**\n * Get the most recent digest generation timestamp for an agent.\n *\n * @returns epoch seconds of the last digest, or 0 if no digests exist.\n */\nfunction getLastDigestTimestamp(agentId: string): number {\n const db = getDatabase();\n\n const row = db.prepare(\n `SELECT MAX(generated_at) AS max_at\n FROM digest_extracts\n WHERE agent_id = ?`,\n ).get(agentId) as { max_at: number | null } | undefined;\n\n return row?.max_at ?? 0;\n}\n","/**\n * Orchestrator planning call.\n *\n * Composes the orchestrator prompt, parses the LLM response into a structured\n * plan, and applies phase directives to PhaseDefinition objects.\n *\n * This module is pure logic — no SDK calls. SDK invocation happens in the\n * executor integration (Task 5).\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { findPackageRoot } from '@myco/utils/find-package-root.js';\nimport { extractJson } from '@myco/intelligence/response.js';\nimport type { PhaseDefinition, OrchestratorPlan, OrchestratorPhaseDirective } from './types.js';\nimport type { ContextQueryResult } from './context-queries.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Default max turns for the orchestrator's own LLM call. */\nexport const DEFAULT_ORCHESTRATOR_MAX_TURNS = 3;\n\n/** Filename of the orchestrator prompt template. */\nconst ORCHESTRATOR_PROMPT_FILE = 'orchestrator.md';\n\n/** Number of characters to show from a phase's prompt as a preview. */\nconst PHASE_PROMPT_PREVIEW_CHARS = 100;\n\n/** Section header injected into a phase prompt when contextNotes are present. */\nconst ORCHESTRATOR_GUIDANCE_HEADER = '## Orchestrator Guidance';\n\n/** Placeholder substituted when no context query results are available. */\nconst NO_CONTEXT_QUERIES_TEXT = 'No context queries configured.';\n\n/** Fallback reasoning string used when JSON parsing fails. */\nconst FALLBACK_REASONING_PARSE_ERROR = 'Orchestrator response could not be parsed — running all phases with defaults.';\n\n/** Fallback reasoning string used when the parsed plan has no phases array. */\nconst FALLBACK_REASONING_MISSING_PHASES = 'Orchestrator plan missing phases array — running all phases with defaults.';\n\n// ---------------------------------------------------------------------------\n// Template placeholder names\n// ---------------------------------------------------------------------------\n\nconst PLACEHOLDER_VAULT_STATE = '{{vault_state}}';\nconst PLACEHOLDER_PHASE_DEFINITIONS = '{{phase_definitions}}';\nconst PLACEHOLDER_CONTEXT_RESULTS = '{{context_results}}';\n\n// ---------------------------------------------------------------------------\n// Prompt template loading\n// ---------------------------------------------------------------------------\n\n/**\n * Load the orchestrator prompt template from disk.\n *\n * Resolves the path relative to this file so it works in both dev and built\n * (tsup) environments. The `prompts/` directory is a sibling of this file.\n */\n/** Cached prompt template — loaded once, reused across calls. */\nlet cachedPromptTemplate: string | undefined;\n\nfunction loadPromptTemplate(): string {\n if (!cachedPromptTemplate) {\n const scriptDir = path.dirname(fileURLToPath(import.meta.url));\n\n // Check sibling prompts/ directory first (tsc output or dev mode)\n const adjacentPath = path.join(scriptDir, 'prompts', ORCHESTRATOR_PROMPT_FILE);\n if (fs.existsSync(adjacentPath)) {\n cachedPromptTemplate = fs.readFileSync(adjacentPath, 'utf-8');\n return cachedPromptTemplate;\n }\n\n // tsup bundles into dist/chunk-XXXX.js — walk up to package root\n const root = findPackageRoot(scriptDir);\n if (root) {\n const distPath = path.join(root, 'dist', 'src', 'agent', 'prompts', ORCHESTRATOR_PROMPT_FILE);\n if (fs.existsSync(distPath)) {\n cachedPromptTemplate = fs.readFileSync(distPath, 'utf-8');\n return cachedPromptTemplate;\n }\n const srcPath = path.join(root, 'src', 'agent', 'prompts', ORCHESTRATOR_PROMPT_FILE);\n cachedPromptTemplate = fs.readFileSync(srcPath, 'utf-8');\n return cachedPromptTemplate;\n }\n\n // Final fallback\n cachedPromptTemplate = fs.readFileSync(adjacentPath, 'utf-8');\n }\n return cachedPromptTemplate;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Compose the orchestrator prompt by substituting runtime data into the\n * template.\n *\n * @param vaultState - Free-form summary of current vault state.\n * @param phases - Phase definitions available for this task.\n * @param contextResults - Results from pre-execution context queries.\n * @returns The fully composed prompt string.\n */\nexport function composeOrchestratorPrompt(\n vaultState: string,\n phases: PhaseDefinition[],\n contextResults: ContextQueryResult[],\n): string {\n const template = loadPromptTemplate();\n\n const phaseList = formatPhaseList(phases);\n const contextSection = formatContextResults(contextResults);\n\n return template\n .replace(PLACEHOLDER_VAULT_STATE, vaultState)\n .replace(PLACEHOLDER_PHASE_DEFINITIONS, phaseList)\n .replace(PLACEHOLDER_CONTEXT_RESULTS, contextSection);\n}\n\n/**\n * Parse the orchestrator's LLM response into a structured plan.\n *\n * Accepts JSON that is either raw or wrapped in a ```json code block.\n * Validates that the parsed value has a `phases` array.\n *\n * On any failure — malformed JSON, missing array, empty input — returns a\n * safe fallback plan that runs all phases with no modifications.\n *\n * Never throws.\n *\n * @param response - Raw LLM response text.\n * @param phases - Phase definitions; used to construct the fallback plan.\n * @returns A valid OrchestratorPlan.\n */\nexport function parseOrchestratorPlan(\n response: string,\n phases: PhaseDefinition[],\n): OrchestratorPlan {\n const trimmed = response.trim();\n\n if (!trimmed) {\n return buildRunAllPlan(phases, FALLBACK_REASONING_PARSE_ERROR);\n }\n\n try {\n const parsed = extractJson(trimmed);\n\n if (!isOrchestratorPlanShape(parsed)) {\n return buildRunAllPlan(phases, FALLBACK_REASONING_MISSING_PHASES);\n }\n\n return parsed;\n } catch {\n return buildRunAllPlan(phases, FALLBACK_REASONING_PARSE_ERROR);\n }\n}\n\n/**\n * Apply orchestrator directives to a set of phase definitions.\n *\n * For each phase:\n * - If the directive says `skip: true` and the phase is not required, it is\n * excluded from the result.\n * - If the directive says `skip: true` but the phase IS required, it is kept\n * and a warning is logged.\n * - If the directive provides `maxTurns`, the phase's turn limit is overridden.\n * - If the directive provides `contextNotes`, they are appended to the phase\n * prompt under `## Orchestrator Guidance`.\n *\n * Phase order is preserved. Phases with no matching directive pass through\n * unchanged.\n *\n * @param phases - Original phase definitions.\n * @param directives - Directives from the orchestrator's plan.\n * @returns Modified phase definitions.\n */\nexport function applyDirectives(\n phases: PhaseDefinition[],\n directives: OrchestratorPhaseDirective[],\n): PhaseDefinition[] {\n const directiveMap = new Map<string, OrchestratorPhaseDirective>(\n directives.map((d) => [d.name, d]),\n );\n\n const result: PhaseDefinition[] = [];\n\n for (const phase of phases) {\n const directive = directiveMap.get(phase.name);\n\n if (!directive) {\n result.push(phase);\n continue;\n }\n\n if (directive.skip) {\n if (phase.required) {\n console.warn(\n `[orchestrator] Cannot skip required phase \"${phase.name}\" — keeping it. Reason: ${directive.skipReason ?? 'none given'}`,\n );\n result.push(applyNonSkipDirective(phase, directive));\n }\n // Non-required phases with skip: true are simply excluded.\n continue;\n }\n\n result.push(applyNonSkipDirective(phase, directive));\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Private helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Apply non-skip directive fields (maxTurns, contextNotes) to a phase.\n */\nfunction applyNonSkipDirective(\n phase: PhaseDefinition,\n directive: OrchestratorPhaseDirective,\n): PhaseDefinition {\n let updated = { ...phase };\n\n if (directive.maxTurns !== undefined) {\n updated = { ...updated, maxTurns: directive.maxTurns };\n }\n\n if (directive.contextNotes) {\n updated = {\n ...updated,\n prompt: `${updated.prompt}\\n\\n${ORCHESTRATOR_GUIDANCE_HEADER}\\n\\n${directive.contextNotes}`,\n };\n }\n\n return updated;\n}\n\n/**\n * Format phases as a bulleted list for the prompt template.\n */\nfunction formatPhaseList(phases: PhaseDefinition[]): string {\n if (phases.length === 0) {\n return '(no phases defined)';\n }\n\n return phases\n .map((p) => {\n const preview = p.prompt.slice(0, PHASE_PROMPT_PREVIEW_CHARS);\n const ellipsis = p.prompt.length > PHASE_PROMPT_PREVIEW_CHARS ? '...' : '';\n return `- **${p.name}** (maxTurns: ${p.maxTurns}, required: ${p.required}): ${preview}${ellipsis}`;\n })\n .join('\\n');\n}\n\n/**\n * Format context query results as sections for the prompt template.\n */\nfunction formatContextResults(results: ContextQueryResult[]): string {\n if (results.length === 0) {\n return NO_CONTEXT_QUERIES_TEXT;\n }\n\n return results\n .map((r) => {\n const dataSection = r.error\n ? `Error: ${r.error}`\n : JSON.stringify(r.data, null, 2);\n return `### ${r.tool}\\nPurpose: ${r.purpose}\\n\\n${dataSection}`;\n })\n .join('\\n\\n');\n}\n\n/**\n * Type guard: check that a parsed value has the OrchestratorPlan shape.\n */\nfunction isOrchestratorPlanShape(value: unknown): value is OrchestratorPlan {\n if (typeof value !== 'object' || value === null) return false;\n const obj = value as Record<string, unknown>;\n return Array.isArray(obj['phases']);\n}\n\n/**\n * Build a fallback \"run everything\" plan from the available phases.\n */\nfunction buildRunAllPlan(phases: PhaseDefinition[], reasoning: string): OrchestratorPlan {\n return {\n phases: phases.map((p) => ({ name: p.name, skip: false })),\n reasoning,\n };\n}\n","/**\n * Clean LLM response text before parsing.\n *\n * Reasoning models (DeepSeek, Qwen, GLM, etc.) embed chain-of-thought\n * in the response using special tags. These must be stripped before\n * JSON parsing or value extraction.\n */\n\n// Patterns for reasoning model chain-of-thought tokens.\n// Order matters: most specific patterns first.\nconst REASONING_PATTERNS = [\n // <think>...</think>answer (DeepSeek, Qwen, GLM, many others)\n /<think>[\\s\\S]*?<\\/think>\\s*/gi,\n // Implicit opening: reasoning...</think>answer (GLM-4.7 observed)\n /^[\\s\\S]*?<\\/think>\\s*/i,\n // <reasoning>...</reasoning>answer\n /<reasoning>[\\s\\S]*?<\\/reasoning>\\s*/gi,\n // <|thinking|>...<|/thinking|>answer\n /<\\|thinking\\|>[\\s\\S]*?<\\|\\/thinking\\|>\\s*/gi,\n // Plain-text \"Thinking Process:\" block followed by actual content\n // (Qwen 3.5 via LM Studio without native thinking mode)\n // Matches from \"Thinking Process:\" up to the last numbered step, then the synthesis follows\n /^Thinking Process:[\\s\\S]*?(?=\\n(?:## |# |\\*\\*[A-Z]))/i,\n];\n\n/**\n * Strip reasoning/chain-of-thought tokens from LLM response text.\n * Returns the final answer without the thinking process.\n */\nexport function stripReasoningTokens(text: string): string {\n if (!text) return text;\n\n for (const pattern of REASONING_PATTERNS) {\n const stripped = text.replace(pattern, '').trim();\n if (stripped && stripped !== text.trim()) {\n return stripped;\n }\n }\n\n return text;\n}\n\n/**\n * Extract JSON from an LLM response that may contain markdown fences,\n * reasoning tokens, or other wrapper text.\n *\n * Tries in order:\n * 1. Strip reasoning tokens\n * 2. Extract from ```json ... ``` code fences\n * 3. Find bare {...} JSON object\n * 4. Parse the cleaned text directly\n */\nexport function extractJson(text: string): unknown {\n const cleaned = stripReasoningTokens(text);\n\n // Try code fence extraction\n const fenceMatch = cleaned.match(/```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?```/);\n if (fenceMatch) {\n return JSON.parse(fenceMatch[1].trim());\n }\n\n // Try bare JSON object\n const objectMatch = cleaned.match(/\\{[\\s\\S]*\\}/);\n if (objectMatch) {\n return JSON.parse(objectMatch[0]);\n }\n\n // Try direct parse\n return JSON.parse(cleaned);\n}\n\n/**\n * Extract a numeric value from an LLM response that may contain\n * reasoning tokens or extra text around the number.\n */\nexport function extractNumber(text: string): number {\n const cleaned = stripReasoningTokens(text).trim();\n const match = cleaned.match(/(\\d+\\.?\\d*)/);\n if (match) return parseFloat(match[1]);\n return parseFloat(cleaned);\n}\n","/**\n * Context query execution for pre-phase vault lookups.\n *\n * Executes lightweight vault queries before the orchestrator makes planning\n * decisions. Uses the same DB query functions as the vault tools but bypasses\n * the MCP layer entirely.\n */\n\nimport type { ContextQuery } from './types.js';\nimport { errorMessage as toErrorMessage } from '@myco/utils/error-message.js';\nimport { getUnprocessedBatches } from '@myco/db/queries/batches.js';\nimport { listSpores } from '@myco/db/queries/spores.js';\nimport { listSessions } from '@myco/db/queries/sessions.js';\nimport { getStatesForAgent } from '@myco/db/queries/agent-state.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Default limit for context query results when none specified. */\nconst DEFAULT_CONTEXT_QUERY_LIMIT = 10;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Result of a single context query execution. */\nexport interface ContextQueryResult {\n tool: string;\n purpose: string;\n data: unknown;\n error?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Execute a list of context queries against the vault database.\n *\n * Each query is routed to the appropriate DB function based on `query.tool`.\n * On failure:\n * - Required queries throw — the caller should abort.\n * - Optional queries return a result with `error` set and `data: null`.\n *\n * Unknown tool names always throw, regardless of `required`.\n *\n * @param agentId - The agent ID to scope agent-specific queries.\n * @param queries - The list of context queries to execute.\n * @returns Resolved results in the same order as the input queries.\n */\nexport async function executeContextQueries(\n agentId: string,\n queries: ContextQuery[],\n): Promise<ContextQueryResult[]> {\n // Validate all tool names upfront — unknown tools are a programming error.\n for (const query of queries) {\n validateTool(query.tool);\n }\n\n // Execute all queries in parallel — they hit independent DB tables.\n const settled = await Promise.allSettled(\n queries.map(async (query) => {\n const limit = query.limit ?? DEFAULT_CONTEXT_QUERY_LIMIT;\n const data = await executeQuery(agentId, query.tool, limit);\n return { tool: query.tool, purpose: query.purpose, data } satisfies ContextQueryResult;\n }),\n );\n\n // Map settled results, throwing for required failures.\n const results: ContextQueryResult[] = [];\n for (let i = 0; i < settled.length; i++) {\n const outcome = settled[i];\n const query = queries[i];\n\n if (outcome.status === 'fulfilled') {\n results.push(outcome.value);\n } else {\n const message = toErrorMessage(outcome.reason);\n\n if (query.required) {\n throw new Error(\n `Required context query \"${query.tool}\" failed: ${message}`,\n );\n }\n\n results.push({\n tool: query.tool,\n purpose: query.purpose,\n data: null,\n error: message,\n });\n }\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Private helpers\n// ---------------------------------------------------------------------------\n\n/** Set of recognized context query tool names. */\nconst KNOWN_CONTEXT_QUERY_TOOLS = new Set([\n 'vault_unprocessed',\n 'vault_spores',\n 'vault_sessions',\n 'vault_state',\n]);\n\n/**\n * Guard against unknown tool names.\n *\n * Unknown tools are a programming error (misconfigured task YAML), so they\n * always throw — even if the query is not marked required.\n */\nfunction validateTool(tool: string): void {\n if (!KNOWN_CONTEXT_QUERY_TOOLS.has(tool)) {\n throw new Error(`Unknown context query tool: \"${tool}\"`);\n }\n}\n\n/**\n * Route a single query to the appropriate DB function.\n */\nasync function executeQuery(\n agentId: string,\n tool: string,\n limit: number,\n): Promise<unknown> {\n switch (tool) {\n case 'vault_unprocessed':\n return getUnprocessedBatches({ limit });\n\n case 'vault_spores':\n return listSpores({ agent_id: agentId, limit });\n\n case 'vault_sessions':\n return listSessions({ limit });\n\n case 'vault_state':\n return getStatesForAgent(agentId);\n\n default:\n throw new Error(`Unknown context query tool: \"${tool}\"`);\n }\n}\n","import type { ProviderConfig } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Named constants — env var names and default values\n// ---------------------------------------------------------------------------\n\nconst ENV_ANTHROPIC_BASE_URL = 'ANTHROPIC_BASE_URL';\nconst ENV_ANTHROPIC_AUTH_TOKEN = 'ANTHROPIC_AUTH_TOKEN';\nconst ENV_ANTHROPIC_API_KEY = 'ANTHROPIC_API_KEY';\nconst ENV_OLLAMA_NUM_CTX = 'OLLAMA_NUM_CTX';\nconst DEFAULT_OLLAMA_URL = 'http://localhost:11434';\nconst DEFAULT_LMSTUDIO_URL = 'http://localhost:1234';\nconst OLLAMA_AUTH_TOKEN = 'ollama';\nconst LMSTUDIO_AUTH_TOKEN = 'lmstudio';\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Build an env object for a phase's query() call.\n *\n * Returns `undefined` when no provider override is needed (SDK defaults to\n * `process.env`). Only creates a new object when overrides are required,\n * avoiding unnecessary copies of the full process.env.\n */\nexport function buildPhaseEnv(provider?: ProviderConfig): Record<string, string | undefined> | undefined {\n if (!provider || provider.type === 'anthropic') return undefined;\n return { ...process.env, ...getProviderEnvVars(provider) };\n}\n\n/**\n * Get env vars for a provider config.\n */\nexport function getProviderEnvVars(provider: ProviderConfig): Record<string, string> {\n switch (provider.type) {\n case 'anthropic':\n return {};\n case 'ollama':\n return {\n [ENV_ANTHROPIC_BASE_URL]: provider.baseUrl ?? DEFAULT_OLLAMA_URL,\n [ENV_ANTHROPIC_AUTH_TOKEN]: OLLAMA_AUTH_TOKEN,\n [ENV_ANTHROPIC_API_KEY]: '',\n ...(provider.contextLength ? { [ENV_OLLAMA_NUM_CTX]: String(provider.contextLength) } : {}),\n };\n case 'lmstudio':\n return {\n [ENV_ANTHROPIC_BASE_URL]: provider.baseUrl ?? DEFAULT_LMSTUDIO_URL,\n [ENV_ANTHROPIC_AUTH_TOKEN]: provider.apiKey ?? LMSTUDIO_AUTH_TOKEN,\n [ENV_ANTHROPIC_API_KEY]: '',\n };\n default:\n return {};\n }\n}\n","/**\n * Ollama model context window management.\n */\n\nimport { execFileSync } from 'node:child_process';\nimport { writeFileSync, unlinkSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport type { ProviderConfig } from './types.js';\n\n/** Timeout for Ollama model pre-load request (ms). */\nconst OLLAMA_PRELOAD_TIMEOUT_MS = 30_000;\n\n/**\n * Default context window for Ollama models when no `context_length` is\n * configured. 32K is comfortably larger than any current agent task prompt\n * (skill-generate's source-material payload is the worst case and stays\n * well under 16K) and dramatically smaller than the 128K–256K native\n * defaults modern Ollama models ship with — which would otherwise allocate\n * tens of GB of KV cache for context that is never filled.\n *\n * Override by setting `context_length` on the provider config, either\n * globally, per-task, or per-phase (all scopes are reconciled to a single\n * variant per model — see `resolveOllamaContextVariants`).\n */\nexport const DEFAULT_OLLAMA_CONTEXT_LENGTH = 32768;\n\n/**\n * Ensure an Ollama model variant exists with the desired context length.\n *\n * The Anthropic-compatible endpoint (/v1/messages) always loads models at\n * default context — it ignores /api/chat preloads and API-created params.\n * The only reliable way is `ollama create` with a Modelfile containing\n * `PARAMETER num_ctx`. Creates a variant named `{model}-ctx{contextLength}`.\n */\nexport async function ensureOllamaContextVariant(\n model: string,\n contextLength: number,\n): Promise<string> {\n\n const baseName = model.replace(/:latest$/, '');\n const variantName = `${baseName}-ctx${contextLength}`;\n\n try {\n // Check if variant already exists\n execFileSync('ollama', ['show', variantName], { stdio: 'ignore' });\n return variantName;\n } catch {\n // Doesn't exist — create it\n }\n\n try {\n const modelfilePath = join(tmpdir(), `myco-modelfile-${Date.now()}`);\n writeFileSync(modelfilePath, `FROM ${model}\\nPARAMETER num_ctx ${contextLength}\\n`);\n execFileSync('ollama', ['create', variantName, '-f', modelfilePath], {\n stdio: 'ignore',\n timeout: OLLAMA_PRELOAD_TIMEOUT_MS,\n });\n try { unlinkSync(modelfilePath); } catch { /* cleanup best-effort */ }\n return variantName;\n } catch {\n return model; // Fall back to original\n }\n}\n\n// ---------------------------------------------------------------------------\n// Unified variant resolution for task + phase scopes\n// ---------------------------------------------------------------------------\n\n/**\n * Per-phase provider override shape. Mirrors the record passed through\n * `runAgent` → `executePhasedQuery`; kept here so the ollama-context module\n * doesn't have to import executor-internal types.\n */\nexport interface PhaseProviderOverride {\n provider?: ProviderConfig;\n maxTurns?: number;\n}\n\n/**\n * Resolve every Ollama model referenced by a task run into a single variant\n * per (model) pair and return rewritten providers that point at those\n * variants.\n *\n * Why this exists at all:\n * - The runtime default for gemma4:26b and similar modern Ollama models\n * is 128K–256K tokens, which allocates tens of GB of KV cache for\n * context we never come close to filling. Applying a sensible default\n * (32K) on behalf of users who haven't set `context_length` recovers\n * that VRAM without changing anything else.\n * - Historically the variant-creation call only ran at the task scope,\n * so a phase override that pointed at a different Ollama model bypassed\n * the variant logic entirely and loaded at native default.\n * - If the same model is referenced at multiple scopes with different\n * `context_length` values, creating a variant per scope would load the\n * same base model multiple times. That's the failure mode this function\n * prevents — one (model) → one variant → one Ollama load per run.\n *\n * Reconciliation rule: when the same model appears with different\n * `context_length` values across scopes, the MAX is used. This guarantees\n * every call site has at least as much context as it asked for, at the cost\n * of slightly more VRAM than the smallest-asking scope requested. Users who\n * want scope-specific contexts should use different *models*, not different\n * context values on the same model.\n *\n * Providers that aren't Ollama (cloud, lmstudio) and providers without a\n * resolved model name pass through unchanged.\n */\nexport async function resolveOllamaContextVariants(\n taskProvider: ProviderConfig | undefined,\n phaseOverrides: Record<string, PhaseProviderOverride>,\n // Injected variant creator for testability. Defaults to the real\n // `ensureOllamaContextVariant` which shells out to `ollama`; tests pass\n // a pure stub so the logic can be exercised without the CLI.\n createVariant: (model: string, contextLength: number) => Promise<string> = ensureOllamaContextVariant,\n): Promise<{\n taskProvider: ProviderConfig | undefined;\n phaseOverrides: Record<string, PhaseProviderOverride>;\n conflicts: Array<{ model: string; values: number[]; resolved: number }>;\n}> {\n // --- Pass 1: collect ---------------------------------------------------\n // For each Ollama model we find, track every distinct context value we\n // saw for it. We need the full set (not just a running max) so we can\n // report conflicts afterwards.\n const seen = new Map<string, Set<number>>();\n\n const recordOllama = (p: ProviderConfig | undefined): void => {\n if (p?.type !== 'ollama' || !p.model) return;\n const ctx = p.contextLength ?? DEFAULT_OLLAMA_CONTEXT_LENGTH;\n const set = seen.get(p.model) ?? new Set<number>();\n set.add(ctx);\n seen.set(p.model, set);\n };\n\n recordOllama(taskProvider);\n for (const override of Object.values(phaseOverrides)) {\n recordOllama(override.provider);\n }\n\n // No Ollama providers at all — pass through unchanged.\n if (seen.size === 0) {\n return { taskProvider, phaseOverrides, conflicts: [] };\n }\n\n // --- Pass 2: reconcile -------------------------------------------------\n const resolvedContext = new Map<string, number>();\n const conflicts: Array<{ model: string; values: number[]; resolved: number }> = [];\n for (const [model, values] of seen) {\n const sorted = [...values].sort((a, b) => a - b);\n const max = sorted[sorted.length - 1];\n resolvedContext.set(model, max);\n if (sorted.length > 1) {\n conflicts.push({ model, values: sorted, resolved: max });\n }\n }\n\n // --- Pass 3: create variants in parallel -------------------------------\n const variantEntries = await Promise.all(\n [...resolvedContext.entries()].map(async ([model, ctx]) => {\n const variant = await createVariant(model, ctx);\n return [model, variant] as const;\n }),\n );\n const variantByModel = new Map(variantEntries);\n\n // --- Pass 4: rewrite providers -----------------------------------------\n const rewriteProvider = (p: ProviderConfig | undefined): ProviderConfig | undefined => {\n if (!p) return p;\n if (p.type !== 'ollama' || !p.model) return p;\n const variant = variantByModel.get(p.model);\n const resolvedCtx = resolvedContext.get(p.model);\n if (!variant) return p;\n // Preserve the resolved context_length on the rewritten provider so\n // downstream code (env var builders, diagnostics) sees the effective\n // value rather than undefined. Update the model to the variant name.\n return { ...p, model: variant, contextLength: resolvedCtx };\n };\n\n const rewrittenPhaseOverrides: Record<string, PhaseProviderOverride> = {};\n for (const [name, override] of Object.entries(phaseOverrides)) {\n rewrittenPhaseOverrides[name] = {\n ...override,\n ...(override.provider ? { provider: rewriteProvider(override.provider) } : {}),\n };\n }\n\n return {\n taskProvider: rewriteProvider(taskProvider),\n phaseOverrides: rewrittenPhaseOverrides,\n conflicts,\n };\n}\n","/**\n * Wave computation for phased task execution.\n *\n * Uses Kahn's algorithm to topologically sort phases into dependency waves.\n * Phases in the same wave have no dependencies on each other and can\n * execute in parallel via Promise.allSettled().\n *\n * Also provides deterministic session ID generation for phases.\n */\n\nimport crypto from 'node:crypto';\nimport type { PhaseDefinition } from './types.js';\n\n/**\n * Compute execution waves from phase dependency graph.\n *\n * Uses Kahn's algorithm to topologically sort phases into waves.\n * Phases in the same wave have no dependencies on each other and\n * can execute in parallel via Promise.allSettled().\n *\n * @throws Error if circular dependencies are detected.\n */\nexport function computeWaves(phases: PhaseDefinition[]): PhaseDefinition[][] {\n const nameToPhase = new Map(phases.map(p => [p.name, p]));\n const inDegree = new Map<string, number>();\n const dependents = new Map<string, string[]>(); // dependency → phases that depend on it\n\n // Initialize\n for (const phase of phases) {\n inDegree.set(phase.name, 0);\n dependents.set(phase.name, []);\n }\n\n // Build adjacency — skip dependencies on phases not in the set\n // (they may have been removed by orchestrator directives)\n for (const phase of phases) {\n const deps = phase.dependsOn ?? [];\n for (const dep of deps) {\n if (!nameToPhase.has(dep)) continue; // skipped/removed phase — treat as satisfied\n inDegree.set(phase.name, (inDegree.get(phase.name) ?? 0) + 1);\n dependents.get(dep)!.push(phase.name);\n }\n }\n\n // Collect waves\n const waves: PhaseDefinition[][] = [];\n const completed = new Set<string>();\n\n while (completed.size < phases.length) {\n // Find all phases with zero unsatisfied deps\n const wave: PhaseDefinition[] = [];\n for (const phase of phases) {\n if (completed.has(phase.name)) continue;\n if ((inDegree.get(phase.name) ?? 0) === 0) {\n wave.push(phase);\n }\n }\n\n if (wave.length === 0) {\n const remaining = phases.filter(p => !completed.has(p.name)).map(p => p.name);\n throw new Error(`Circular dependency detected among phases: ${remaining.join(', ')}`);\n }\n\n waves.push(wave);\n\n // Mark wave as completed and decrement dependents' in-degrees\n for (const phase of wave) {\n completed.add(phase.name);\n for (const dependent of (dependents.get(phase.name) ?? [])) {\n inDegree.set(dependent, (inDegree.get(dependent) ?? 0) - 1);\n }\n }\n }\n\n return waves;\n}\n\n// ---------------------------------------------------------------------------\n// Session ID generation\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a deterministic session ID (UUID format) for a phase.\n * Derived from run ID + phase name so the same run always produces\n * the same session IDs.\n */\nexport function phaseSessionId(runId: string, phaseName: string): string {\n const hash = crypto.createHash('sha256').update(`${runId}-${phaseName}`).digest('hex');\n // Format as UUID: 8-4-4-4-12\n return [\n hash.slice(0, 8),\n hash.slice(8, 12),\n hash.slice(12, 16),\n hash.slice(16, 20),\n hash.slice(20, 32),\n ].join('-');\n}\n"],"mappings":"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","names":["crypto","resolve","tool","tool","tool","tool","crypto","tool","crypto","tool","recordId","now","tool","writeFileSync","crypto","crypto","resolve","errorMessage","cleanupStagedSkill"]}
|