@goondocks/myco 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +0 -1
- package/README.md +5 -1
- package/dist/{agent-run-CGM75RS6.js → agent-run-5KYQJQTY.js} +6 -6
- package/dist/{agent-tasks-3RQKPRSW.js → agent-tasks-N7BDYKGB.js} +6 -6
- package/dist/{chunk-XLY3REL3.js → chunk-4VSNNMEU.js} +2 -2
- package/dist/{chunk-ZAHDA2PQ.js → chunk-7NBDELZB.js} +3 -3
- package/dist/{chunk-6LL2MQHP.js → chunk-D4ESHOOJ.js} +3 -3
- package/dist/{chunk-W6HI4CCS.js → chunk-D4M2AV65.js} +5 -4
- package/dist/chunk-D4M2AV65.js.map +1 -0
- package/dist/{chunk-YKOEMLJJ.js → chunk-DPJVKNNP.js} +3 -3
- package/dist/{chunk-IXOHLPH7.js → chunk-HAG2YDH6.js} +3 -3
- package/dist/{chunk-AEJS57ZK.js → chunk-J3L2RTYK.js} +2 -2
- package/dist/{chunk-MKKXCCQ5.js → chunk-JHLALJPB.js} +5 -5
- package/dist/{chunk-CUDM5YJY.js → chunk-JROOQQH6.js} +3 -3
- package/dist/{chunk-D6DXYAFK.js → chunk-LGPBVBFY.js} +3 -3
- package/dist/{chunk-5SDH75YC.js → chunk-LUQBT2Y4.js} +2 -2
- package/dist/{chunk-76ZO5RGT.js → chunk-PIRWYDOH.js} +30 -2
- package/dist/chunk-PIRWYDOH.js.map +1 -0
- package/dist/{chunk-WZZH3YXJ.js → chunk-PW5QVY44.js} +2 -2
- package/dist/{chunk-U7UUJ4FD.js → chunk-Q2AYS2QE.js} +3 -3
- package/dist/{chunk-FPMEIN2W.js → chunk-QL2RBFIC.js} +2 -2
- package/dist/{chunk-CHG652UO.js → chunk-RGRPAKEY.js} +3 -3
- package/dist/{chunk-K2UZNK25.js → chunk-RR75ZKEV.js} +2 -2
- package/dist/{chunk-5QERXFH7.js → chunk-SW62AX75.js} +2 -2
- package/dist/{chunk-FFQES5MC.js → chunk-TCGOSLW6.js} +3 -3
- package/dist/{chunk-JYXMRW3T.js → chunk-TY7A5OZ5.js} +2 -2
- package/dist/{chunk-LYFDTF7G.js → chunk-YRHSTVCZ.js} +3 -3
- package/dist/{chunk-C3AEZ3BZ.js → chunk-YRUJ5KGV.js} +3 -3
- package/dist/{cli-FL754H6S.js → cli-Y5QZJAHX.js} +37 -37
- package/dist/{client-4NP7ZMLV.js → client-UGM6MG55.js} +4 -4
- package/dist/{detect-providers-AZ6DEQU7.js → detect-providers-JFE3QLJI.js} +4 -4
- package/dist/{doctor-OFGWOYBC.js → doctor-NFWPX75B.js} +8 -8
- package/dist/{executor-SWXSN7ZC.js → executor-ESRLUCGU.js} +14 -14
- package/dist/executor-ESRLUCGU.js.map +1 -0
- package/dist/{init-JZJJKC4G.js → init-NMSG24BY.js} +11 -11
- package/dist/{init-wizard-4VHNOYFO.js → init-wizard-WIUCR4JE.js} +7 -7
- package/dist/{llm-XJFHRFHB.js → llm-O46QYWEM.js} +7 -7
- package/dist/{loader-DGWP4EFB.js → loader-BQ4X4K3F.js} +3 -3
- package/dist/{main-UBUZTMGV.js → main-3NTAT7ZD.js} +379 -75
- package/dist/main-3NTAT7ZD.js.map +1 -0
- package/dist/{openai-embeddings-ST3B6GW7.js → openai-embeddings-HWAKOGUM.js} +4 -4
- package/dist/{openrouter-HJHOO3EO.js → openrouter-GXZK7JXR.js} +4 -4
- package/dist/{post-compact-O7HMEFKP.js → post-compact-3DDK3OVZ.js} +6 -6
- package/dist/{post-tool-use-OVNMZ3UG.js → post-tool-use-LSG6N3W5.js} +5 -5
- package/dist/{post-tool-use-failure-HPXTFYBY.js → post-tool-use-failure-5V3OCLI6.js} +6 -6
- package/dist/{pre-compact-JD3D4PBB.js → pre-compact-F7Y7SDSZ.js} +6 -6
- package/dist/{provider-check-SOTDYLJE.js → provider-check-CKZW3GQX.js} +4 -4
- package/dist/{registry-33MEKDHT.js → registry-ZHUVXGPO.js} +4 -4
- package/dist/{remove-XDFMOYUL.js → remove-VCWRNG54.js} +6 -6
- package/dist/{resolution-events-UPHJJLDQ.js → resolution-events-WZHPQQMN.js} +4 -4
- package/dist/{restart-JBAMRKRJ.js → restart-YYJ7SH4K.js} +7 -7
- package/dist/{search-43TS5RGA.js → search-L7KTBURJ.js} +7 -7
- package/dist/{server-UBU7NALJ.js → server-GMRVF2PB.js} +4 -4
- package/dist/{session-CPBLMD7M.js → session-V3SNFG7J.js} +8 -8
- package/dist/{session-end-DUHUYE6J.js → session-end-V3V3GMP2.js} +5 -5
- package/dist/{session-start-I7XM3CME.js → session-start-OH7SBUIA.js} +9 -9
- package/dist/{setup-llm-TTHEUWDA.js → setup-llm-5AMWEAJ5.js} +6 -6
- package/dist/src/agent/definitions/tasks/full-intelligence.yaml +0 -1
- package/dist/src/agent/prompts/agent.md +1 -1
- 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-7CE6GEWE.js → stats-B2V7P45Y.js} +7 -7
- package/dist/{stop-BF3AWA7S.js → stop-D6L2KRHZ.js} +5 -5
- package/dist/{stop-failure-7Q2LQF2R.js → stop-failure-7OM2AYRX.js} +6 -6
- package/dist/{subagent-start-QG2J3AN4.js → subagent-start-MKL5I54S.js} +6 -6
- package/dist/{subagent-stop-WVA7RDIM.js → subagent-stop-2E7VKZW2.js} +6 -6
- package/dist/{task-completed-AQVQ7GFL.js → task-completed-5QHIT773.js} +6 -6
- package/dist/{team-LC3K7UXD.js → team-TBS5OILG.js} +2 -2
- package/dist/ui/assets/index-aMc07Ym5.js +804 -0
- package/dist/ui/index.html +1 -1
- package/dist/{update-3EKXZF3H.js → update-4NVFET56.js} +15 -10
- package/dist/update-4NVFET56.js.map +1 -0
- package/dist/{user-prompt-submit-22YQD4XM.js → user-prompt-submit-X4BCPMZ4.js} +5 -5
- package/dist/{verify-DVIWHZXA.js → verify-D7EDVXO5.js} +7 -7
- package/dist/{version-VPI6ERF7.js → version-GTFCEIJ2.js} +2 -2
- package/package.json +3 -2
- package/dist/chunk-76ZO5RGT.js.map +0 -1
- package/dist/chunk-W6HI4CCS.js.map +0 -1
- package/dist/executor-SWXSN7ZC.js.map +0 -1
- package/dist/main-UBUZTMGV.js.map +0 -1
- package/dist/ui/assets/index-UFE9l-Hb.js +0 -794
- package/dist/update-3EKXZF3H.js.map +0 -1
- package/hooks/hooks.json +0 -137
- /package/dist/{agent-run-CGM75RS6.js.map → agent-run-5KYQJQTY.js.map} +0 -0
- /package/dist/{agent-tasks-3RQKPRSW.js.map → agent-tasks-N7BDYKGB.js.map} +0 -0
- /package/dist/{chunk-XLY3REL3.js.map → chunk-4VSNNMEU.js.map} +0 -0
- /package/dist/{chunk-ZAHDA2PQ.js.map → chunk-7NBDELZB.js.map} +0 -0
- /package/dist/{chunk-6LL2MQHP.js.map → chunk-D4ESHOOJ.js.map} +0 -0
- /package/dist/{chunk-YKOEMLJJ.js.map → chunk-DPJVKNNP.js.map} +0 -0
- /package/dist/{chunk-IXOHLPH7.js.map → chunk-HAG2YDH6.js.map} +0 -0
- /package/dist/{chunk-AEJS57ZK.js.map → chunk-J3L2RTYK.js.map} +0 -0
- /package/dist/{chunk-MKKXCCQ5.js.map → chunk-JHLALJPB.js.map} +0 -0
- /package/dist/{chunk-CUDM5YJY.js.map → chunk-JROOQQH6.js.map} +0 -0
- /package/dist/{chunk-D6DXYAFK.js.map → chunk-LGPBVBFY.js.map} +0 -0
- /package/dist/{chunk-5SDH75YC.js.map → chunk-LUQBT2Y4.js.map} +0 -0
- /package/dist/{chunk-WZZH3YXJ.js.map → chunk-PW5QVY44.js.map} +0 -0
- /package/dist/{chunk-U7UUJ4FD.js.map → chunk-Q2AYS2QE.js.map} +0 -0
- /package/dist/{chunk-FPMEIN2W.js.map → chunk-QL2RBFIC.js.map} +0 -0
- /package/dist/{chunk-CHG652UO.js.map → chunk-RGRPAKEY.js.map} +0 -0
- /package/dist/{chunk-K2UZNK25.js.map → chunk-RR75ZKEV.js.map} +0 -0
- /package/dist/{chunk-5QERXFH7.js.map → chunk-SW62AX75.js.map} +0 -0
- /package/dist/{chunk-FFQES5MC.js.map → chunk-TCGOSLW6.js.map} +0 -0
- /package/dist/{chunk-JYXMRW3T.js.map → chunk-TY7A5OZ5.js.map} +0 -0
- /package/dist/{chunk-LYFDTF7G.js.map → chunk-YRHSTVCZ.js.map} +0 -0
- /package/dist/{chunk-C3AEZ3BZ.js.map → chunk-YRUJ5KGV.js.map} +0 -0
- /package/dist/{cli-FL754H6S.js.map → cli-Y5QZJAHX.js.map} +0 -0
- /package/dist/{client-4NP7ZMLV.js.map → client-UGM6MG55.js.map} +0 -0
- /package/dist/{detect-providers-AZ6DEQU7.js.map → detect-providers-JFE3QLJI.js.map} +0 -0
- /package/dist/{doctor-OFGWOYBC.js.map → doctor-NFWPX75B.js.map} +0 -0
- /package/dist/{init-JZJJKC4G.js.map → init-NMSG24BY.js.map} +0 -0
- /package/dist/{init-wizard-4VHNOYFO.js.map → init-wizard-WIUCR4JE.js.map} +0 -0
- /package/dist/{llm-XJFHRFHB.js.map → llm-O46QYWEM.js.map} +0 -0
- /package/dist/{loader-DGWP4EFB.js.map → loader-BQ4X4K3F.js.map} +0 -0
- /package/dist/{openai-embeddings-ST3B6GW7.js.map → openai-embeddings-HWAKOGUM.js.map} +0 -0
- /package/dist/{openrouter-HJHOO3EO.js.map → openrouter-GXZK7JXR.js.map} +0 -0
- /package/dist/{post-compact-O7HMEFKP.js.map → post-compact-3DDK3OVZ.js.map} +0 -0
- /package/dist/{post-tool-use-OVNMZ3UG.js.map → post-tool-use-LSG6N3W5.js.map} +0 -0
- /package/dist/{post-tool-use-failure-HPXTFYBY.js.map → post-tool-use-failure-5V3OCLI6.js.map} +0 -0
- /package/dist/{pre-compact-JD3D4PBB.js.map → pre-compact-F7Y7SDSZ.js.map} +0 -0
- /package/dist/{provider-check-SOTDYLJE.js.map → provider-check-CKZW3GQX.js.map} +0 -0
- /package/dist/{registry-33MEKDHT.js.map → registry-ZHUVXGPO.js.map} +0 -0
- /package/dist/{remove-XDFMOYUL.js.map → remove-VCWRNG54.js.map} +0 -0
- /package/dist/{resolution-events-UPHJJLDQ.js.map → resolution-events-WZHPQQMN.js.map} +0 -0
- /package/dist/{restart-JBAMRKRJ.js.map → restart-YYJ7SH4K.js.map} +0 -0
- /package/dist/{search-43TS5RGA.js.map → search-L7KTBURJ.js.map} +0 -0
- /package/dist/{server-UBU7NALJ.js.map → server-GMRVF2PB.js.map} +0 -0
- /package/dist/{session-CPBLMD7M.js.map → session-V3SNFG7J.js.map} +0 -0
- /package/dist/{session-end-DUHUYE6J.js.map → session-end-V3V3GMP2.js.map} +0 -0
- /package/dist/{session-start-I7XM3CME.js.map → session-start-OH7SBUIA.js.map} +0 -0
- /package/dist/{setup-llm-TTHEUWDA.js.map → setup-llm-5AMWEAJ5.js.map} +0 -0
- /package/dist/{stats-7CE6GEWE.js.map → stats-B2V7P45Y.js.map} +0 -0
- /package/dist/{stop-BF3AWA7S.js.map → stop-D6L2KRHZ.js.map} +0 -0
- /package/dist/{stop-failure-7Q2LQF2R.js.map → stop-failure-7OM2AYRX.js.map} +0 -0
- /package/dist/{subagent-start-QG2J3AN4.js.map → subagent-start-MKL5I54S.js.map} +0 -0
- /package/dist/{subagent-stop-WVA7RDIM.js.map → subagent-stop-2E7VKZW2.js.map} +0 -0
- /package/dist/{task-completed-AQVQ7GFL.js.map → task-completed-5QHIT773.js.map} +0 -0
- /package/dist/{team-LC3K7UXD.js.map → team-TBS5OILG.js.map} +0 -0
- /package/dist/{user-prompt-submit-22YQD4XM.js.map → user-prompt-submit-X4BCPMZ4.js.map} +0 -0
- /package/dist/{verify-DVIWHZXA.js.map → verify-D7EDVXO5.js.map} +0 -0
- /package/dist/{version-VPI6ERF7.js.map → version-GTFCEIJ2.js.map} +0 -0
package/dist/ui/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>Myco</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-aMc07Ym5.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-BGbil7f1.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
@@ -2,14 +2,14 @@ import { createRequire as __cr } from 'node:module'; const require = __cr(import
|
|
|
2
2
|
import {
|
|
3
3
|
VAULT_GITIGNORE,
|
|
4
4
|
registerSymbionts
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-YRHSTVCZ.js";
|
|
6
6
|
import "./chunk-SAKJMNSR.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-LUQBT2Y4.js";
|
|
8
8
|
import "./chunk-MYX5NCRH.js";
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-DPJVKNNP.js";
|
|
10
|
+
import "./chunk-PIRWYDOH.js";
|
|
11
11
|
import "./chunk-S6I62FAH.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-TY7A5OZ5.js";
|
|
13
13
|
import {
|
|
14
14
|
loadManifests,
|
|
15
15
|
resolvePackageRoot
|
|
@@ -27,7 +27,12 @@ import "./chunk-PZUWP5VK.js";
|
|
|
27
27
|
import fs from "fs";
|
|
28
28
|
import path from "path";
|
|
29
29
|
async function run(args) {
|
|
30
|
-
|
|
30
|
+
let projectRoot;
|
|
31
|
+
const projectIdx = args.indexOf("--project");
|
|
32
|
+
if (projectIdx !== -1 && args[projectIdx + 1]) {
|
|
33
|
+
projectRoot = args[projectIdx + 1];
|
|
34
|
+
}
|
|
35
|
+
const vaultDir = projectRoot ? path.join(projectRoot, ".myco") : resolveVaultDir();
|
|
31
36
|
if (!fs.existsSync(path.join(vaultDir, "myco.yaml"))) {
|
|
32
37
|
console.error(`No myco.yaml found in ${vaultDir}. Run 'myco init' first.`);
|
|
33
38
|
process.exit(1);
|
|
@@ -44,14 +49,14 @@ async function run(args) {
|
|
|
44
49
|
} else {
|
|
45
50
|
console.log(" \u2013 .gitignore is current");
|
|
46
51
|
}
|
|
47
|
-
const
|
|
52
|
+
const resolvedProjectRoot = projectRoot ?? path.dirname(vaultDir);
|
|
48
53
|
const allManifests = loadManifests();
|
|
49
54
|
const pkgRoot = resolvePackageRoot();
|
|
50
55
|
const configured = allManifests.filter(
|
|
51
|
-
(m) => fs.existsSync(path.join(
|
|
56
|
+
(m) => fs.existsSync(path.join(resolvedProjectRoot, m.configDir))
|
|
52
57
|
);
|
|
53
58
|
if (configured.length > 0) {
|
|
54
|
-
const registered = registerSymbionts(configured,
|
|
59
|
+
const registered = registerSymbionts(configured, resolvedProjectRoot, pkgRoot, "Updated");
|
|
55
60
|
updatedCount += registered;
|
|
56
61
|
} else {
|
|
57
62
|
console.log(" \u2013 No configured agents found");
|
|
@@ -67,4 +72,4 @@ async function run(args) {
|
|
|
67
72
|
export {
|
|
68
73
|
run
|
|
69
74
|
};
|
|
70
|
-
//# sourceMappingURL=update-
|
|
75
|
+
//# sourceMappingURL=update-4NVFET56.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/update.ts"],"sourcesContent":["import { resolveVaultDir } from '../vault/resolve.js';\nimport { VAULT_GITIGNORE, registerSymbionts } from './shared.js';\nimport { loadManifests, resolvePackageRoot } from '../symbionts/detect.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport async function run(args: string[]): Promise<void> {\n // Support --project <path> for detached update scripts\n let projectRoot: string | undefined;\n const projectIdx = args.indexOf('--project');\n if (projectIdx !== -1 && args[projectIdx + 1]) {\n projectRoot = args[projectIdx + 1];\n }\n\n const vaultDir = projectRoot\n ? path.join(projectRoot, '.myco')\n : resolveVaultDir();\n if (!fs.existsSync(path.join(vaultDir, 'myco.yaml'))) {\n console.error(`No myco.yaml found in ${vaultDir}. Run 'myco init' first.`);\n process.exit(1);\n }\n\n console.log(`Updating Myco vault at ${vaultDir}\\n`);\n\n let updatedCount = 0;\n\n // --- Update .gitignore to match current template ---\n\n const gitignorePath = path.join(vaultDir, '.gitignore');\n const currentGitignore = fs.existsSync(gitignorePath)\n ? fs.readFileSync(gitignorePath, 'utf-8')\n : '';\n\n if (currentGitignore !== VAULT_GITIGNORE) {\n fs.writeFileSync(gitignorePath, VAULT_GITIGNORE, 'utf-8');\n console.log(' \\u2713 Updated .gitignore');\n updatedCount++;\n } else {\n console.log(' \\u2013 .gitignore is current');\n }\n\n // --- Update symbiont registration (only agents already configured) ---\n\n const resolvedProjectRoot = projectRoot ?? path.dirname(vaultDir);\n const allManifests = loadManifests();\n const pkgRoot = resolvePackageRoot();\n // Only update agents whose config directory already exists in the project\n const configured = allManifests.filter((m) =>\n fs.existsSync(path.join(resolvedProjectRoot, m.configDir)),\n );\n\n if (configured.length > 0) {\n const registered = registerSymbionts(configured, resolvedProjectRoot, pkgRoot, 'Updated');\n updatedCount += registered;\n } else {\n console.log(' \\u2013 No configured agents found');\n }\n\n // --- Summary ---\n\n console.log('');\n if (updatedCount > 0) {\n console.log(`Updated ${updatedCount} item${updatedCount > 1 ? 's' : ''}.`);\n } else {\n console.log('Everything is up to date.');\n }\n console.log('Run `myco doctor` to verify setup health.');\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,OAAO,QAAQ;AACf,OAAO,UAAU;AAEjB,eAAsB,IAAI,MAA+B;AAEvD,MAAI;AACJ,QAAM,aAAa,KAAK,QAAQ,WAAW;AAC3C,MAAI,eAAe,MAAM,KAAK,aAAa,CAAC,GAAG;AAC7C,kBAAc,KAAK,aAAa,CAAC;AAAA,EACnC;AAEA,QAAM,WAAW,cACb,KAAK,KAAK,aAAa,OAAO,IAC9B,gBAAgB;AACpB,MAAI,CAAC,GAAG,WAAW,KAAK,KAAK,UAAU,WAAW,CAAC,GAAG;AACpD,YAAQ,MAAM,yBAAyB,QAAQ,0BAA0B;AACzE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,0BAA0B,QAAQ;AAAA,CAAI;AAElD,MAAI,eAAe;AAInB,QAAM,gBAAgB,KAAK,KAAK,UAAU,YAAY;AACtD,QAAM,mBAAmB,GAAG,WAAW,aAAa,IAChD,GAAG,aAAa,eAAe,OAAO,IACtC;AAEJ,MAAI,qBAAqB,iBAAiB;AACxC,OAAG,cAAc,eAAe,iBAAiB,OAAO;AACxD,YAAQ,IAAI,6BAA6B;AACzC;AAAA,EACF,OAAO;AACL,YAAQ,IAAI,gCAAgC;AAAA,EAC9C;AAIA,QAAM,sBAAsB,eAAe,KAAK,QAAQ,QAAQ;AAChE,QAAM,eAAe,cAAc;AACnC,QAAM,UAAU,mBAAmB;AAEnC,QAAM,aAAa,aAAa;AAAA,IAAO,CAAC,MACtC,GAAG,WAAW,KAAK,KAAK,qBAAqB,EAAE,SAAS,CAAC;AAAA,EAC3D;AAEA,MAAI,WAAW,SAAS,GAAG;AACzB,UAAM,aAAa,kBAAkB,YAAY,qBAAqB,SAAS,SAAS;AACxF,oBAAgB;AAAA,EAClB,OAAO;AACL,YAAQ,IAAI,qCAAqC;AAAA,EACnD;AAIA,UAAQ,IAAI,EAAE;AACd,MAAI,eAAe,GAAG;AACpB,YAAQ,IAAI,WAAW,YAAY,QAAQ,eAAe,IAAI,MAAM,EAAE,GAAG;AAAA,EAC3E,OAAO;AACL,YAAQ,IAAI,2BAA2B;AAAA,EACzC;AACA,UAAQ,IAAI,2CAA2C;AACzD;","names":[]}
|
|
@@ -5,13 +5,13 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
normalizeHookInput,
|
|
7
7
|
readStdin
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-RR75ZKEV.js";
|
|
9
9
|
import {
|
|
10
10
|
DaemonClient
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-DPJVKNNP.js";
|
|
12
|
+
import "./chunk-PIRWYDOH.js";
|
|
13
13
|
import "./chunk-S6I62FAH.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-TY7A5OZ5.js";
|
|
15
15
|
import "./chunk-QFMBZ72S.js";
|
|
16
16
|
import "./chunk-LPUQPDC2.js";
|
|
17
17
|
import "./chunk-D7TYRPRM.js";
|
|
@@ -63,4 +63,4 @@ ${sessionLine}` : sessionLine;
|
|
|
63
63
|
export {
|
|
64
64
|
main
|
|
65
65
|
};
|
|
66
|
-
//# sourceMappingURL=user-prompt-submit-
|
|
66
|
+
//# sourceMappingURL=user-prompt-submit-X4BCPMZ4.js.map
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
createEmbeddingProvider
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-JHLALJPB.js";
|
|
5
|
+
import "./chunk-J3L2RTYK.js";
|
|
6
|
+
import "./chunk-SW62AX75.js";
|
|
7
|
+
import "./chunk-QL2RBFIC.js";
|
|
8
|
+
import "./chunk-LUQBT2Y4.js";
|
|
9
9
|
import {
|
|
10
10
|
loadConfig
|
|
11
11
|
} from "./chunk-MAZOVVDU.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-PIRWYDOH.js";
|
|
13
13
|
import "./chunk-S6I62FAH.js";
|
|
14
14
|
import "./chunk-D7TYRPRM.js";
|
|
15
15
|
import "./chunk-E4VLWIJC.js";
|
|
@@ -42,4 +42,4 @@ async function run(_args, vaultDir) {
|
|
|
42
42
|
export {
|
|
43
43
|
run
|
|
44
44
|
};
|
|
45
|
-
//# sourceMappingURL=verify-
|
|
45
|
+
//# sourceMappingURL=verify-D7EDVXO5.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
getPluginVersion
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-TY7A5OZ5.js";
|
|
5
5
|
import "./chunk-LPUQPDC2.js";
|
|
6
6
|
import "./chunk-PZUWP5VK.js";
|
|
7
7
|
export {
|
|
8
8
|
getPluginVersion
|
|
9
9
|
};
|
|
10
|
-
//# sourceMappingURL=version-
|
|
10
|
+
//# sourceMappingURL=version-GTFCEIJ2.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goondocks/myco",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Collective agent intelligence — Claude Code plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
"dist/",
|
|
15
15
|
"commands/",
|
|
16
16
|
"skills/",
|
|
17
|
-
"hooks/",
|
|
18
17
|
"CONTRIBUTING.md"
|
|
19
18
|
],
|
|
20
19
|
"scripts": {
|
|
@@ -42,6 +41,7 @@
|
|
|
42
41
|
"better-sqlite3": "^12.8.0",
|
|
43
42
|
"chokidar": "^5.0.0",
|
|
44
43
|
"gray-matter": "^4.0.3",
|
|
44
|
+
"semver": "^7.7.4",
|
|
45
45
|
"sqlite-vec": "^0.1.7",
|
|
46
46
|
"yaml": "^2.4.0",
|
|
47
47
|
"zod": "^4.3.6"
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/better-sqlite3": "^7.6.13",
|
|
51
51
|
"@types/node": "^25.5.0",
|
|
52
|
+
"@types/semver": "^7.7.1",
|
|
52
53
|
"tsup": "^8.0.0",
|
|
53
54
|
"tsx": "^4.0.0",
|
|
54
55
|
"typescript": "^5.5.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Shared constants for the Myco codebase.\n * Per CLAUDE.md: \"No Magic Literals — Numeric and string constants\n * MUST NOT appear inline in logic.\"\n */\n\nexport { LOG_KINDS, type LogKind, kindToComponent } from './constants/log-kinds.js';\n\n// --- Agent phase prompt composition ---\n/**\n * Maximum chars per phase summary passed to subsequent phases.\n * Set to 4000 to ensure the digest-assess phase findings pass\n * untruncated to parallel tier phases.\n */\nexport const PHASE_SUMMARY_MAX_CHARS = 4000;\n\n// --- Token estimation ---\n/** Approximate characters per token for the chars/4 heuristic. */\nexport const CHARS_PER_TOKEN = 4;\n\n/** Estimate token count from character length using the CHARS_PER_TOKEN heuristic. */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\n// --- Time (primitives — must precede derived constants) ---\n/** Milliseconds per second. */\nexport const MS_PER_SECOND = 1000;\n\n// --- Embedding ---\n/** Max characters of text sent to the embedding model. */\nexport const EMBEDDING_INPUT_LIMIT = 8000;\n\n/** Max rows per embedding worker cycle. */\nexport const EMBEDDING_BATCH_SIZE = 10;\n\n/** Content hash algorithm for staleness detection. */\nexport const CONTENT_HASH_ALGORITHM = 'sha256';\n\n// --- Truncation limits (display/preview) ---\n/** Max chars for a user prompt preview in event summaries. */\nexport const PROMPT_PREVIEW_CHARS = 300;\n/** Max chars for an AI response preview in event summaries. */\nexport const AI_RESPONSE_PREVIEW_CHARS = 500;\n/** Max chars for a command string preview. */\nexport const COMMAND_PREVIEW_CHARS = 80;\n/** Max chars for a content snippet in search results. */\nexport const CONTENT_SNIPPET_CHARS = 120;\n/** Max chars for a tool output preview in hooks. */\nexport const TOOL_OUTPUT_PREVIEW_CHARS = 200;\n/** Max chars for a session summary preview in MCP tools. */\nexport const SESSION_SUMMARY_PREVIEW_CHARS = 300;\n/** Max chars for a recall summary preview. */\nexport const RECALL_SUMMARY_PREVIEW_CHARS = 200;\n/** Max chars for search result and hydrated context previews. */\nexport const SEARCH_PREVIEW_CHARS = 300;\n\n// --- Log preview limits (short previews for structured log fields) ---\n/** Max chars for a user prompt preview in log entries. */\nexport const LOG_PROMPT_PREVIEW_CHARS = 50;\n/** Max chars for an assistant message preview in log entries. */\nexport const LOG_MESSAGE_PREVIEW_CHARS = 80;\n/** Max chars for injected context preview in log entries. */\nexport const LOG_CONTEXT_PREVIEW_CHARS = 200;\n\n// --- Context injection layer budgets (chars, not tokens — used with .slice()) ---\nexport const CONTEXT_SESSION_PREVIEW_CHARS = 80;\nexport const CONTEXT_SPORE_PREVIEW_CHARS = 80;\n\n// --- Processor maxTokens budgets ---\n/** Response token budget for observation extraction. */\nexport const EXTRACTION_MAX_TOKENS = 2048;\n/** Response token budget for session summary. */\nexport const SUMMARY_MAX_TOKENS = 512;\n/** Response token budget for session title generation. */\nexport const TITLE_MAX_TOKENS = 32;\n\n// --- Timeouts ---\n/** Daemon client HTTP request timeout (ms). */\nexport const DAEMON_CLIENT_TIMEOUT_MS = 2000;\n/** Health check timeout (ms) — fail fast if daemon isn't responding. */\nexport const DAEMON_HEALTH_CHECK_TIMEOUT_MS = 500;\n/** LLM request timeout (ms). All LLM calls are background daemon work — no need to be aggressive. */\nexport const LLM_REQUEST_TIMEOUT_MS = 180_000;\n/** Embedding request timeout (ms). Embeddings run in background batch processing — generous timeout. */\nexport const EMBEDDING_REQUEST_TIMEOUT_MS = 60_000;\n/** Digest LLM request timeout (ms). Digest cycles use large context windows and may need model loading time. */\nexport const DIGEST_LLM_REQUEST_TIMEOUT_MS = 600_000;\n/** Stdin read timeout for hooks (ms). */\nexport const STDIN_TIMEOUT_MS = 100;\n/** Provider detection timeout for detect-providers CLI command (ms). */\nexport const PROVIDER_DETECT_TIMEOUT_MS = 3000;\n\n// --- Time ---\n/** Milliseconds in one day. */\nexport const MS_PER_DAY = 24 * 60 * 60 * 1000;\n\n/** Current Unix epoch in seconds. */\nexport function epochSeconds(): number {\n return Math.floor(Date.now() / MS_PER_SECOND);\n}\n\n// --- Buffer cleanup ---\n/** Max age for stale buffer files before cleanup (ms). */\nexport const STALE_BUFFER_MAX_AGE_MS = 1 * MS_PER_DAY;\n\n// --- Retry backoff ---\n/** Retry delays for daemon health check (ms). */\nexport const DAEMON_HEALTH_RETRY_DELAYS = [100, 200, 400, 800, 1500];\n\n/** Grace period after daemon.json is written before stale checks can trigger a restart (ms).\n * Prevents rapid restart loops from concurrent hooks or session reloads. */\nexport const DAEMON_STALE_GRACE_PERIOD_MS = 60_000;\n\n/** Grace period for SIGTERM before escalating to SIGKILL (ms).\n * Gives the old daemon a chance to shut down cleanly, but force-kills\n * to guarantee the configured port is reclaimed. */\nexport const DAEMON_EVICT_TIMEOUT_MS = 3000;\n/** Poll interval when waiting for an evicted daemon to die (ms). */\nexport const DAEMON_EVICT_POLL_MS = 100;\n\n// --- Slug limits ---\n/** Max length for slugified artifact IDs. */\n\n// --- Turn rendering ---\n/** Max file paths displayed per turn in session notes. */\nexport const TURN_MAX_FILES_DISPLAYED = 10;\n\n// --- Transcript mining ---\n/** Minimum content length to consider a transcript entry meaningful. */\nexport const MIN_TRANSCRIPT_CONTENT_LENGTH = 10;\n\n// --- Graph edge types (lineage — auto-created by daemon) ---\n/** Spore was extracted during this session. */\nexport const EDGE_TYPE_FROM_SESSION = 'FROM_SESSION';\n/** Spore was extracted from this prompt batch. */\nexport const EDGE_TYPE_EXTRACTED_FROM = 'EXTRACTED_FROM';\n/** Wisdom spore was derived from (consolidated) this source spore. */\nexport const EDGE_TYPE_DERIVED_FROM = 'DERIVED_FROM';\n/** Session contains this prompt batch. */\nexport const EDGE_TYPE_HAS_BATCH = 'HAS_BATCH';\n// --- Query defaults ---\n/** Default row limit for query module list operations. */\nexport const QUERY_DEFAULT_LIST_LIMIT = 100;\n/** Default confidence score for graph edges. */\nexport const GRAPH_EDGE_DEFAULT_CONFIDENCE = 1.0;\n\n// --- Query limits ---\n/** Max recent sessions to check for lineage heuristics. */\nexport const LINEAGE_RECENT_SESSIONS_LIMIT = 5;\n/** Max related spores to query for session notes. */\nexport const RELATED_SPORES_LIMIT = 50;\n\n// --- Context injection ---\n/** Max spores to inject per prompt. */\nexport const PROMPT_CONTEXT_MAX_SPORES = 3;\n/** Minimum similarity score for prompt context injection (0-1). */\nexport const PROMPT_CONTEXT_MIN_SIMILARITY = 0.3;\n/** Max token budget for session-start context injection. */\nexport const SESSION_CONTEXT_MAX_TOKENS = 500;\n/** Max token budget for per-prompt context injection. */\nexport const PROMPT_CONTEXT_MAX_TOKENS = 300;\n/** Minimum prompt length to trigger context search. */\nexport const PROMPT_CONTEXT_MIN_LENGTH = 10;\n\n/** Over-fetch multiplier for vector search to compensate for post-filtering. */\nexport const PROMPT_VECTOR_OVER_FETCH = 2;\n\n// --- Spore status filtering ---\n/** Spore statuses excluded from search results and context injection. */\nexport const EXCLUDED_SPORE_STATUSES = new Set(['superseded', 'archived']);\n\n// --- Agent identity ---\n/** Default agent ID for the built-in intelligence agent. */\nexport const DEFAULT_AGENT_ID = 'myco-agent';\n/** Agent ID for user-initiated MCP operations. */\nexport const USER_AGENT_ID = 'user';\n/** Agent name for user-initiated MCP operations. */\nexport const USER_AGENT_NAME = 'User (MCP)';\n\n// --- MCP tool defaults ---\n/** Default result limit for myco_search. */\nexport const MCP_SEARCH_DEFAULT_LIMIT = 10;\n/** Default result limit for myco_sessions. */\nexport const MCP_SESSIONS_DEFAULT_LIMIT = 20;\n/** Default result limit for myco_logs. */\nexport const MCP_LOGS_DEFAULT_LIMIT = 50;\n\n// --- Feed ---\n/** Default number of entries returned by the activity feed. */\nexport const FEED_DEFAULT_LIMIT = 50;\n\n// --- Digest — Tiers ---\n/** Available token-budget tiers for digest synthesis. */\nexport const DIGEST_TIERS = [1500, 5000, 10000] as const;\nexport type DigestTier = (typeof DIGEST_TIERS)[number];\n\n// --- Digest — Context window minimums per tier ---\n/** Minimum context window (tokens) required to run a digest at a given tier. */\nexport const DIGEST_TIER_MIN_CONTEXT: Record<number, number> = {\n 1500: 6500,\n 5000: 18500,\n 10000: 30500,\n};\n\n// --- Digest — Substrate ---\n/** Default minimum substrate notes required before a digest cycle runs. */\nexport const DIGEST_MIN_NOTES_FOR_CYCLE = 10;\n\n/** Scoring weights by note type when selecting substrate for synthesis. */\nexport const DIGEST_SUBSTRATE_TYPE_WEIGHTS: Record<string, number> = {\n session: 3,\n spore: 3,\n plan: 2,\n artifact: 1,\n team: 1,\n};\n\n// --- LLM reasoning control ---\n/** Reasoning mode for all Myco LLM calls. Suppresses chain-of-thought tokens from reasoning models. */\nexport const LLM_REASONING_MODE = 'off' as const;\n\n// --- Digest — System prompt overhead estimate ---\n\n// --- Vault intelligence ---\n/** Max candidate spores after post-filtering for supersession check. */\nexport const SUPERSESSION_CANDIDATE_LIMIT = 5;\n\n/** Over-fetch from vector index before post-filtering by status/type. */\nexport const SUPERSESSION_VECTOR_FETCH_LIMIT = 20;\n\n/** Max output tokens for supersession LLM evaluation. */\nexport const SUPERSESSION_MAX_TOKENS = 256;\n\n/** Similarity threshold for clustering related spores in batch agent processing. */\nexport const AGENT_CLUSTER_SIMILARITY = 0.75;\n\n// --- Search ---\n/** Default number of results returned by vector search and fullTextSearch. */\nexport const SEARCH_RESULTS_DEFAULT_LIMIT = 20;\n/** Minimum cosine similarity score for semantic search results (0-1). */\nexport const SEARCH_SIMILARITY_THRESHOLD = 0.3;\n\n// --- Pipeline processing ---\n/** Default page size for pipeline items API listing. */\nexport const PIPELINE_ITEMS_DEFAULT_LIMIT = 50;\n\n// --- Pipeline retry ---\n/** Max retries for parse (structural) pipeline failures — fail fast. */\nexport const PIPELINE_PARSE_MAX_RETRIES = 1;\n/** Exponential backoff multiplier for successive pipeline retries. */\nexport const PIPELINE_BACKOFF_MULTIPLIER = 4;\n\n// --- Pipeline stages (ordered) ---\nexport const PIPELINE_STAGES = ['capture', 'extraction', 'embedding', 'consolidation', 'digest'] as const;\nexport type PipelineStage = typeof PIPELINE_STAGES[number];\n\n// --- Pipeline statuses ---\nexport const PIPELINE_STATUSES = ['pending', 'processing', 'succeeded', 'failed', 'blocked', 'skipped', 'poisoned'] as const;\nexport type PipelineStatus = typeof PIPELINE_STATUSES[number];\n\n// --- Provider roles for circuit breakers ---\nexport const PIPELINE_PROVIDER_ROLES = ['llm', 'embedding', 'digest-llm'] as const;\nexport type PipelineProviderRole = typeof PIPELINE_PROVIDER_ROLES[number];\n\n// --- Stage to provider role mapping ---\nexport const STAGE_PROVIDER_MAP: Record<PipelineStage, PipelineProviderRole | null> = {\n capture: null,\n extraction: 'llm',\n embedding: 'embedding',\n consolidation: 'digest-llm',\n digest: 'digest-llm',\n};\n\n/**\n * Stages processed by the pipeline tick timer.\n * Capture is handled at registration time, digest is gated by the metabolism timer.\n */\nexport const PIPELINE_TICK_STAGES: PipelineStage[] = ['extraction', 'embedding', 'consolidation'];\n\n// --- Item type to applicable stages ---\n// Sessions skip consolidation — consolidation applies to the spores\n// extracted FROM sessions, not the session work item itself.\n// Lineage detection stays outside the pipeline (fire-and-forget, non-critical).\nexport const ITEM_STAGE_MAP: Record<string, PipelineStage[]> = {\n session: ['capture', 'extraction', 'embedding', 'digest'],\n spore: ['capture', 'embedding', 'consolidation', 'digest'],\n artifact: ['capture', 'embedding', 'digest'],\n};\n\n// --- User task registry ---\n/** Subdirectory within the vault for user-created task YAML files. */\nexport const USER_TASKS_DIR = 'tasks';\n\n/** Source label for user-created tasks. */\nexport const USER_TASK_SOURCE = 'user';\n\n/** Source label for built-in tasks shipped with the package. */\nexport const BUILT_IN_SOURCE = 'built-in';\n\n/** Task name validation pattern (lowercase, hyphens, digits). */\nexport const TASK_NAME_PATTERN = /^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/;\n\n/** Maximum length for task names. */\nexport const MAX_TASK_NAME_LENGTH = 50;\n\n// --- Automatic consolidation ---\n/** Minimum cluster size required before asking LLM to consolidate. */\nexport const CONSOLIDATION_MIN_CLUSTER_SIZE = 3;\n\n/** Over-fetch from vector index before post-filtering by status/type. */\nexport const CONSOLIDATION_VECTOR_FETCH_LIMIT = 20;\n\n/** Max output tokens for consolidation LLM synthesis.\n * Must be large enough for the full JSON response including content field. */\nexport const CONSOLIDATION_MAX_TOKENS = 2048;\n\n// --- Power management ---\n/** Time without activity before transitioning to idle (ms). */\nexport const POWER_IDLE_THRESHOLD_MS = 5 * 60 * MS_PER_SECOND;\n/** Time without activity before transitioning to sleep (ms). */\nexport const POWER_SLEEP_THRESHOLD_MS = 30 * 60 * MS_PER_SECOND;\n/** Time without activity before transitioning to deep sleep (ms). */\nexport const POWER_DEEP_SLEEP_THRESHOLD_MS = 90 * 60 * MS_PER_SECOND;\n/** Job cycle interval during active/idle states (ms). */\nexport const POWER_ACTIVE_INTERVAL_MS = 60 * MS_PER_SECOND;\n/** Job cycle interval during sleep state (ms). */\nexport const POWER_SLEEP_INTERVAL_MS = 5 * 60 * MS_PER_SECOND;\n\n// --- Session maintenance ---\n/** Time without new prompts before an active session is auto-completed (ms). */\nexport const STALE_SESSION_THRESHOLD_MS = 60 * 60 * MS_PER_SECOND;\n/** Max prompt count for a session to be considered dead and auto-deleted. */\nexport const DEAD_SESSION_MAX_PROMPTS = 1;\n\n// --- Init wizard ---\n/** Minimum Node.js major version required by Myco. */\nexport const MIN_NODE_MAJOR_VERSION = 22;\n\n/** Recommended context window for local intelligence models. */\nexport const RECOMMENDED_LOCAL_CONTEXT_WINDOW = 8192;\n\n/** Default Ollama embedding model recommended during init. */\nexport const DEFAULT_OLLAMA_EMBEDDING_MODEL = 'bge-m3';\n\n/** Default OpenAI embedding model recommended during init. */\nexport const DEFAULT_OPENAI_EMBEDDING_MODEL = 'text-embedding-3-small';\n\n// --- Sync protocol ---\n/** Protocol version for backup and team sync wire format. */\nexport const SYNC_PROTOCOL_VERSION = 1;\n\n// --- Team sync ---\n/** Default machine ID for rows created before multi-machine support. */\nexport const DEFAULT_MACHINE_ID = 'local';\n/** Prefix for team search result source attribution. */\nexport const TEAM_SOURCE_PREFIX = 'team:';\n/** Timeout for team search requests (ms). */\nexport const TEAM_SEARCH_TIMEOUT_MS = 3000;\n/** Timeout for team health check requests (ms). */\nexport const TEAM_HEALTH_TIMEOUT_MS = 5000;\n/** Secrets key for the team API key in secrets.env. */\nexport const TEAM_API_KEY_SECRET = 'MYCO_TEAM_API_KEY';\n/** Timeout for wrangler CLI commands (ms). */\nexport const WRANGLER_COMMAND_TIMEOUT_MS = 60_000;\n"],"mappings":";;;AAcO,IAAM,0BAA0B;AAIhC,IAAM,kBAAkB;AAGxB,SAAS,eAAe,MAAsB;AACnD,SAAO,KAAK,KAAK,KAAK,SAAS,eAAe;AAChD;AAIO,IAAM,gBAAgB;AAOtB,IAAM,uBAAuB;AAG7B,IAAM,yBAAyB;AAI/B,IAAM,uBAAuB;AAM7B,IAAM,wBAAwB;AAE9B,IAAM,4BAA4B;AAMlC,IAAM,uBAAuB;AAI7B,IAAM,2BAA2B;AAEjC,IAAM,4BAA4B;AAElC,IAAM,4BAA4B;AAGlC,IAAM,gCAAgC;AACtC,IAAM,8BAA8B;AAYpC,IAAM,2BAA2B;AAEjC,IAAM,iCAAiC;AAEvC,IAAM,yBAAyB;AAE/B,IAAM,+BAA+B;AAIrC,IAAM,mBAAmB;AAEzB,IAAM,6BAA6B;AAInC,IAAM,aAAa,KAAK,KAAK,KAAK;AAGlC,SAAS,eAAuB;AACrC,SAAO,KAAK,MAAM,KAAK,IAAI,IAAI,aAAa;AAC9C;AAIO,IAAM,0BAA0B,IAAI;AAIpC,IAAM,6BAA6B,CAAC,KAAK,KAAK,KAAK,KAAK,IAAI;AAI5D,IAAM,+BAA+B;AAKrC,IAAM,0BAA0B;AAEhC,IAAM,uBAAuB;AAe7B,IAAM,yBAAyB;AAE/B,IAAM,2BAA2B;AAEjC,IAAM,yBAAyB;AAE/B,IAAM,sBAAsB;AAG5B,IAAM,2BAA2B;AAEjC,IAAM,gCAAgC;AAYtC,IAAM,gCAAgC;AAItC,IAAM,4BAA4B;AAElC,IAAM,4BAA4B;AAGlC,IAAM,2BAA2B;AAIjC,IAAM,0BAA0B,oBAAI,IAAI,CAAC,cAAc,UAAU,CAAC;AAIlE,IAAM,mBAAmB;AAEzB,IAAM,gBAAgB;AAEtB,IAAM,kBAAkB;AAIxB,IAAM,2BAA2B;AAEjC,IAAM,6BAA6B;AAMnC,IAAM,qBAAqB;AAI3B,IAAM,eAAe,CAAC,MAAM,KAAM,GAAK;AA6CvC,IAAM,+BAA+B;AAErC,IAAM,8BAA8B;AAmDpC,IAAM,iBAAiB;AAGvB,IAAM,mBAAmB;AAGzB,IAAM,kBAAkB;AAGxB,IAAM,oBAAoB;AAG1B,IAAM,uBAAuB;AAe7B,IAAM,0BAA0B,IAAI,KAAK;AAEzC,IAAM,2BAA2B,KAAK,KAAK;AAE3C,IAAM,gCAAgC,KAAK,KAAK;AAEhD,IAAM,2BAA2B,KAAK;AAEtC,IAAM,0BAA0B,IAAI,KAAK;AAIzC,IAAM,6BAA6B,KAAK,KAAK;AAE7C,IAAM,2BAA2B;AAOjC,IAAM,mCAAmC;AAGzC,IAAM,iCAAiC;AAGvC,IAAM,iCAAiC;AAIvC,IAAM,wBAAwB;AAI9B,IAAM,qBAAqB;AAE3B,IAAM,qBAAqB;AAE3B,IAAM,yBAAyB;AAE/B,IAAM,yBAAyB;AAE/B,IAAM,sBAAsB;AAE5B,IAAM,8BAA8B;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/db/queries/search.ts"],"sourcesContent":["/**\n * Full-text search using SQLite FTS5.\n *\n * Searches prompt_batches and activities via their FTS5 virtual tables.\n * Semantic search (vector similarity) is handled by the external VectorStore —\n * this module covers text-based retrieval only.\n *\n * All queries use parameterized placeholders throughout.\n */\n\nimport { getDatabase } from '@myco/db/client.js';\nimport {\n SEARCH_RESULTS_DEFAULT_LIMIT,\n SEARCH_PREVIEW_CHARS,\n} from '@myco/constants.js';\nimport type { VectorSearchResult } from '@myco/daemon/embedding/types.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** All result types that can appear in search results. */\nexport type SearchResultType =\n | 'session'\n | 'spore'\n | 'plan'\n | 'artifact'\n | 'prompt_batch'\n | 'activity';\n\n/** A single result returned from full-text or semantic search. */\nexport interface SearchResult {\n id: string;\n type: SearchResultType;\n title: string;\n preview: string;\n score: number;\n session_id?: string;\n}\n\n/** Options for fullTextSearch. */\nexport interface SearchOptions {\n /** Restrict results to a single type. */\n type?: string;\n /** Maximum number of results to return (default: SEARCH_RESULTS_DEFAULT_LIMIT). */\n limit?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Full-text search across capture tables using SQLite FTS5.\n *\n * Searches prompt_batches (indexed on user_prompt) and activities (indexed\n * on tool_name, tool_input, file_path). The raw query string is passed\n * directly to FTS5 MATCH — callers should sanitize if needed.\n *\n * FTS5 `rank` values are negative (lower = better match). This function\n * converts them to positive scores via `Math.abs()` so higher = better\n * in the returned results.\n *\n * When `options.type` is specified, only the matching table branch is queried.\n *\n * @param query — search string (FTS5 MATCH syntax)\n * @param options — optional type filter and result limit\n * @returns SearchResult[] ordered by score DESC\n */\nexport function fullTextSearch(\n query: string,\n options: SearchOptions = {},\n): SearchResult[] {\n const db = getDatabase();\n const limit = options.limit ?? SEARCH_RESULTS_DEFAULT_LIMIT;\n const typeFilter = options.type;\n\n const results: SearchResult[] = [];\n\n // -- prompt_batches branch ------------------------------------------------\n if (typeFilter === undefined || typeFilter === 'prompt_batch') {\n const batchRows = db.prepare(\n `SELECT pb.id, pb.prompt_number, pb.session_id,\n substr(COALESCE(pb.user_prompt, ''), 1, ?) AS preview,\n fts.rank\n FROM prompt_batches_fts fts\n JOIN prompt_batches pb ON pb.id = fts.rowid\n WHERE prompt_batches_fts MATCH ?\n ORDER BY fts.rank\n LIMIT ?`\n ).all(SEARCH_PREVIEW_CHARS, query, limit) as Array<{\n id: number;\n prompt_number: number | null;\n session_id: string | null;\n preview: string;\n rank: number;\n }>;\n\n for (const row of batchRows) {\n results.push({\n id: String(row.id),\n type: 'prompt_batch',\n title: row.prompt_number != null\n ? `Batch #${row.prompt_number}`\n : `Batch ${row.id}`,\n preview: row.preview,\n score: Math.abs(row.rank),\n ...(row.session_id != null ? { session_id: row.session_id } : {}),\n });\n }\n }\n\n // -- activities branch ----------------------------------------------------\n if (typeFilter === undefined || typeFilter === 'activity') {\n const activityRows = db.prepare(\n `SELECT a.id, a.tool_name, a.tool_input, a.file_path, a.session_id,\n fts.rank\n FROM activities_fts fts\n JOIN activities a ON a.id = fts.rowid\n WHERE activities_fts MATCH ?\n ORDER BY fts.rank\n LIMIT ?`\n ).all(query, limit) as Array<{\n id: number;\n tool_name: string;\n tool_input: string | null;\n file_path: string | null;\n session_id: string | null;\n rank: number;\n }>;\n\n for (const row of activityRows) {\n const preview = (row.tool_input ?? row.file_path ?? '').slice(0, SEARCH_PREVIEW_CHARS);\n results.push({\n id: String(row.id),\n type: 'activity',\n title: row.tool_name,\n preview,\n score: Math.abs(row.rank),\n ...(row.session_id != null ? { session_id: row.session_id } : {}),\n });\n }\n }\n\n // Sort combined results by score DESC and apply limit.\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, limit);\n}\n\n// ---------------------------------------------------------------------------\n// Hydration — convert VectorSearchResults into SearchResults\n// ---------------------------------------------------------------------------\n\n/** Row shape returned from sessions table for hydration. */\ninterface SessionRow {\n id: string;\n title: string | null;\n summary: string | null;\n session_id?: undefined;\n}\n\n/** Row shape returned from spores table for hydration. */\ninterface SporeRow {\n id: string;\n observation_type: string;\n content: string;\n session_id: string | null;\n}\n\n/** Row shape returned from plans table for hydration. */\ninterface PlanRow {\n id: string;\n title: string | null;\n content: string | null;\n}\n\n/** Row shape returned from artifacts table for hydration. */\ninterface ArtifactRow {\n id: string;\n title: string;\n content: string | null;\n}\n\n/**\n * Hydrate vector search results into SearchResults by fetching full records\n * from the record store.\n *\n * Groups results by namespace, queries each table for the relevant IDs, then\n * maps them into SearchResult format with titles and previews.\n */\nexport function hydrateSearchResults(\n vectorResults: VectorSearchResult[],\n): SearchResult[] {\n if (vectorResults.length === 0) return [];\n\n const db = getDatabase();\n const results: SearchResult[] = [];\n\n // Group result IDs by namespace\n const byNamespace = new Map<string, VectorSearchResult[]>();\n for (const vr of vectorResults) {\n const group = byNamespace.get(vr.namespace) ?? [];\n group.push(vr);\n byNamespace.set(vr.namespace, group);\n }\n\n // Use json_each so the statement text is stable and SQLite can cache the plan.\n const sessionStmt = db.prepare(\n `SELECT id, title, summary FROM sessions WHERE id IN (SELECT value FROM json_each(?))`,\n );\n const sporeStmt = db.prepare(\n `SELECT id, observation_type, content, session_id FROM spores WHERE id IN (SELECT value FROM json_each(?))`,\n );\n const planStmt = db.prepare(\n `SELECT id, title, content FROM plans WHERE id IN (SELECT value FROM json_each(?))`,\n );\n const artifactStmt = db.prepare(\n `SELECT id, title, content FROM artifacts WHERE id IN (SELECT value FROM json_each(?))`,\n );\n\n // --- sessions ---\n const sessionResults = byNamespace.get('sessions');\n if (sessionResults && sessionResults.length > 0) {\n const ids = sessionResults.map((r) => r.id);\n const rows = sessionStmt.all(JSON.stringify(ids)) as SessionRow[];\n\n const rowMap = new Map(rows.map((r) => [r.id, r]));\n for (const vr of sessionResults) {\n const row = rowMap.get(vr.id);\n if (!row) continue;\n results.push({\n id: row.id,\n type: 'session',\n title: row.title ?? `Session ${row.id.slice(-6)}`,\n preview: (row.summary ?? '').slice(0, SEARCH_PREVIEW_CHARS),\n score: vr.similarity,\n });\n }\n }\n\n // --- spores ---\n const sporeResults = byNamespace.get('spores');\n if (sporeResults && sporeResults.length > 0) {\n const ids = sporeResults.map((r) => r.id);\n const rows = sporeStmt.all(JSON.stringify(ids)) as SporeRow[];\n\n const rowMap = new Map(rows.map((r) => [r.id, r]));\n for (const vr of sporeResults) {\n const row = rowMap.get(vr.id);\n if (!row) continue;\n results.push({\n id: row.id,\n type: 'spore',\n title: row.observation_type,\n preview: row.content.slice(0, SEARCH_PREVIEW_CHARS),\n score: vr.similarity,\n ...(row.session_id != null ? { session_id: row.session_id } : {}),\n });\n }\n }\n\n // --- plans ---\n const planResults = byNamespace.get('plans');\n if (planResults && planResults.length > 0) {\n const ids = planResults.map((r) => r.id);\n const rows = planStmt.all(JSON.stringify(ids)) as PlanRow[];\n\n const rowMap = new Map(rows.map((r) => [r.id, r]));\n for (const vr of planResults) {\n const row = rowMap.get(vr.id);\n if (!row) continue;\n results.push({\n id: row.id,\n type: 'plan',\n title: row.title ?? `Plan ${row.id.slice(-6)}`,\n preview: (row.content ?? '').slice(0, SEARCH_PREVIEW_CHARS),\n score: vr.similarity,\n });\n }\n }\n\n // --- artifacts ---\n const artifactResults = byNamespace.get('artifacts');\n if (artifactResults && artifactResults.length > 0) {\n const ids = artifactResults.map((r) => r.id);\n const rows = artifactStmt.all(JSON.stringify(ids)) as ArtifactRow[];\n\n const rowMap = new Map(rows.map((r) => [r.id, r]));\n for (const vr of artifactResults) {\n const row = rowMap.get(vr.id);\n if (!row) continue;\n results.push({\n id: row.id,\n type: 'artifact',\n title: row.title,\n preview: (row.content ?? '').slice(0, SEARCH_PREVIEW_CHARS),\n score: vr.similarity,\n });\n }\n }\n\n // Preserve the original similarity-based ordering from vector search\n results.sort((a, b) => b.score - a.score);\n return results;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/agent/executor.ts","../src/agent/tools.ts","../src/db/queries/agent-state.ts","../src/agent/context.ts","../src/agent/orchestrator.ts","../src/intelligence/response.ts","../src/agent/context-queries.ts","../src/agent/provider.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 { 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 } from '@myco/db/client.js';\nimport { createSchema } from '@myco/db/schema.js';\nimport { getAgent } from '@myco/db/queries/agents.js';\nimport { getTask, getDefaultTask } from '@myco/db/queries/tasks.js';\nimport {\n insertRun,\n updateRunStatus,\n getRunningRun,\n STATUS_RUNNING,\n STATUS_COMPLETED,\n STATUS_FAILED,\n} from '@myco/db/queries/runs.js';\nimport {\n resolveDefinitionsDir,\n loadAgentDefinition,\n loadSystemPrompt,\n resolveEffectiveConfig,\n} from './loader.js';\nimport { loadAllTasks } from './registry.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 { loadConfig } from '@myco/config/loader.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// ---------------------------------------------------------------------------\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// 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// Ollama model pre-loading\n// ---------------------------------------------------------------------------\n\n/** Timeout for Ollama model pre-load request (ms). */\nconst OLLAMA_PRELOAD_TIMEOUT_MS = 30_000;\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 *\n * Returns the variant model name to use.\n */\nasync function ensureOllamaContextVariant(\n model: string,\n contextLength: number,\n): Promise<string> {\n const { execFileSync } = await import('node:child_process');\n const { writeFileSync, unlinkSync } = await import('node:fs');\n const { tmpdir } = await import('node:os');\n const { join } = await import('node:path');\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// Wave computation (Kahn's algorithm)\n// ---------------------------------------------------------------------------\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 */\nfunction 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\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 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 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 === '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.required && phaseTurns === 0) {\n console.warn(`[agent] Required phase \"${phase.name}\" produced 0 turns`);\n }\n\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): Promise<{ tokensUsed: number; costUsd: number }> {\n const { query } = await import('@anthropic-ai/claude-agent-sdk');\n const toolServer = createVaultToolServer(agentId, runId, embeddingManager);\n const env = buildPhaseEnv(provider);\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 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): 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 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 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 runningTurnCount + (indexInWave * effectiveMaxTurns),\n embeddingManager,\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 env = buildPhaseEnv(phaseProvider);\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 — check before expensive config loading\n const running = getRunningRun(agentId);\n if (running) {\n return {\n runId: running.id,\n status: STATUS_SKIPPED,\n reason: SKIP_REASON_ALREADY_RUNNING,\n };\n }\n\n // 3. Resolve config\n const definitionsDir = resolveDefinitionsDir();\n const definition = loadAgentDefinition(definitionsDir);\n\n // Load agent and task — both are sync DB lookups\n const agentRow = getAgent(agentId);\n const taskRow = options?.task\n ? getTask(options.task)\n : getDefaultTask(agentId);\n\n // Structural fields (phases, execution, contextQueries) come from the registry\n // (built-in YAML merged with user vault tasks) rather than the DB flat columns.\n const allTasks = loadAllTasks(definitionsDir, vaultDir);\n const taskName = taskRow?.id ?? options?.task;\n const yamlTask = taskName ? allTasks.get(taskName) : undefined;\n\n const taskOverrides = taskRow\n ? {\n name: taskRow.id,\n displayName: taskRow.display_name ?? taskRow.id,\n description: taskRow.description ?? '',\n agent: taskRow.agent_id,\n prompt: taskRow.prompt,\n isDefault: taskRow.is_default === 1,\n ...(taskRow.tool_overrides\n ? { toolOverrides: JSON.parse(taskRow.tool_overrides) as string[] }\n : {}),\n // Scalar config from YAML (model, turns, timeout) — DB doesn't store these\n ...(yamlTask?.model ? { model: yamlTask.model } : {}),\n ...(yamlTask?.maxTurns ? { maxTurns: yamlTask.maxTurns } : {}),\n ...(yamlTask?.timeoutSeconds ? { timeoutSeconds: yamlTask.timeoutSeconds } : {}),\n // Structural config from YAML\n ...(yamlTask?.phases ? { phases: yamlTask.phases } : {}),\n ...(yamlTask?.execution ? { execution: yamlTask.execution } : {}),\n ...(yamlTask?.contextQueries ? { contextQueries: yamlTask.contextQueries } : {}),\n ...(yamlTask?.orchestrator ? { orchestrator: yamlTask.orchestrator } : {}),\n }\n : undefined;\n\n const config = resolveEffectiveConfig(definition, agentRow, taskOverrides);\n\n // Load myco.yaml for provider overrides (global, per-task, per-phase)\n let taskProviderOverride: ProviderConfig | undefined;\n let phaseProviderOverrides: Record<string, { provider?: ProviderConfig; maxTurns?: number }> = {};\n try {\n const mycoConfig = loadConfig(vaultDir);\n\n // Helper to convert myco.yaml snake_case provider to runtime camelCase\n // API keys are NOT stored in myco.yaml — they flow via env vars (settings.json → hooks → daemon)\n const toProviderConfig = (p: { type: 'cloud' | 'ollama' | 'lmstudio'; base_url?: string; model?: string; context_length?: number }): ProviderConfig => ({\n type: p.type, baseUrl: p.base_url, model: p.model, contextLength: p.context_length,\n });\n\n // Per-task override takes priority over global\n const taskConfig = taskName ? mycoConfig.agent.tasks?.[taskName] : undefined;\n const globalProvider = mycoConfig.agent.provider;\n\n if (taskConfig?.provider) {\n taskProviderOverride = toProviderConfig(taskConfig.provider);\n } else if (globalProvider) {\n taskProviderOverride = toProviderConfig(globalProvider);\n }\n\n // Per-phase overrides from myco.yaml\n if (taskConfig?.phases) {\n for (const [phaseName, phaseConfig] of Object.entries(taskConfig.phases)) {\n phaseProviderOverrides[phaseName] = {\n ...(phaseConfig.provider ? { provider: toProviderConfig(phaseConfig.provider) } : {}),\n ...(phaseConfig.maxTurns != null ? { maxTurns: phaseConfig.maxTurns } : {}),\n };\n }\n }\n } catch {\n // Config load failure is non-fatal — proceed without overrides\n }\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 ?? 'cloud',\n ...(effectiveProvider?.baseUrl ? { baseUrl: effectiveProvider.baseUrl } : {}),\n };\n\n // 7. Ensure Ollama model has correct context length (creates variant if needed)\n if (effectiveProvider?.type === 'ollama' && effectiveProvider.contextLength && effectiveProvider.model) {\n const variantModel = await ensureOllamaContextVariant(\n effectiveProvider.model,\n effectiveProvider.contextLength,\n );\n // Override the model name so the SDK uses the context-aware variant\n taskProviderOverride = { ...taskProviderOverride!, model: variantModel };\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 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 );\n tokensUsed = result.tokensUsed;\n costUsd = result.costUsd;\n phaseResults = result.phases;\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 );\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 return {\n runId,\n status: STATUS_FAILED,\n error: errorMessage,\n ...(phaseResults ? { phases: phaseResults } : {}),\n };\n }\n}\n","/**\n * Vault MCP tool server for the agent.\n *\n * Creates 18 tools that expose SQLite query helpers to the agent\n * via the Claude Agent SDK. Tools are grouped into:\n * - Read tools: vault_unprocessed, vault_spores, vault_sessions, vault_search_fts,\n * vault_search_semantic, vault_state, vault_entities, vault_edges,\n * vault_read_digest\n * - Write tools: vault_create_spore, vault_create_entity, vault_create_edge,\n * vault_resolve_spore, vault_update_session, vault_set_state,\n * vault_write_digest, vault_mark_processed\n * - Observability: vault_report\n *\n * `agentId` and `runId` are captured in closures — tools inject them\n * automatically so the agent cannot impersonate another agent.\n */\n\nimport crypto from 'node:crypto';\nimport { z } from 'zod/v4';\nimport { tool, createSdkMcpServer } from '@anthropic-ai/claude-agent-sdk';\nimport { epochSeconds, SEARCH_SIMILARITY_THRESHOLD, TEAM_SOURCE_PREFIX } from '@myco/constants.js';\nimport { getPluginVersion } from '@myco/version.js';\nimport { getUnprocessedBatches, markBatchProcessed } from '@myco/db/queries/batches.js';\nimport { listSpores, insertSpore, updateSporeStatus, DEFAULT_IMPORTANCE } from '@myco/db/queries/spores.js';\nimport { listSessions, updateSession } from '@myco/db/queries/sessions.js';\nimport { getStatesForAgent, setState } from '@myco/db/queries/agent-state.js';\nimport { insertReport } from '@myco/db/queries/reports.js';\nimport { insertTurn } from '@myco/db/queries/turns.js';\nimport { EMBEDDABLE_TABLES, type EmbeddableTable } from '@myco/db/queries/embeddings.js';\nimport { fullTextSearch } from '@myco/db/queries/search.js';\nimport { insertEntity, listEntities } from '@myco/db/queries/entities.js';\nimport { insertGraphEdge, listGraphEdges } 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 type { EmbeddingManager } from '@myco/daemon/embedding/index.js';\nimport type { TeamSyncClient } from '@myco/daemon/team-sync.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 embeddable table for search. */\nconst DEFAULT_SEARCH_TABLE: EmbeddableTable = 'spores';\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// Helpers\n// ---------------------------------------------------------------------------\n\n/** Format a value as a JSON text content block for tool output. */\nfunction textResult(data: unknown): { content: Array<{ type: 'text'; text: string }> } {\n return { content: [{ type: 'text' as const, text: JSON.stringify(data) }] };\n}\n\n// ---------------------------------------------------------------------------\n// Tool definitions factory\n// ---------------------------------------------------------------------------\n\n/** Total number of vault tools defined. */\nexport const VAULT_TOOL_COUNT = 18;\n\n/**\n * Create the 18 vault tool definitions for the agent.\n *\n * Exposed for testing (call handler directly) and for the MCP server factory.\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 array of SdkMcpToolDefinition objects.\n */\nexport function createVaultTools(agentId: string, runId: string, turnOffset = 0, embeddingManager?: EmbeddingManager, teamClient?: TeamSyncClient | null, machineId?: string) {\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 // -------------------------------------------------------------------------\n // Read tools\n // -------------------------------------------------------------------------\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 prompt batches and activities using FTS5. Best for finding specific text, keywords, or session content. Does NOT search spores or entities.',\n {\n query: z.string().describe('Search query text'),\n type: z.string().optional().describe('Restrict to a result type (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). 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'),\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 } },\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 // -------------------------------------------------------------------------\n // Write tools\n // -------------------------------------------------------------------------\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 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 recordTurn('vault_create_spore', args);\n return textResult(spore);\n },\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 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 );\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 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 );\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 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 );\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 );\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 );\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 recordTurn('vault_write_digest', args);\n return textResult(extract);\n },\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 );\n\n // -------------------------------------------------------------------------\n // Observability tool\n // -------------------------------------------------------------------------\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 );\n\n // -------------------------------------------------------------------------\n // Assemble and return\n // -------------------------------------------------------------------------\n\n return [\n vaultUnprocessed,\n vaultSpores,\n vaultSessions,\n vaultSearchFts,\n vaultSearchSemantic,\n vaultState,\n vaultEntities,\n vaultEdges,\n vaultCreateSpore,\n vaultCreateEntity,\n vaultCreateEdge,\n vaultResolveSpore,\n vaultUpdateSession,\n vaultSetState,\n vaultReadDigest,\n vaultWriteDigest,\n vaultMarkProcessed,\n vaultReport,\n ];\n}\n\n// ---------------------------------------------------------------------------\n// MCP server factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create a vault MCP tool server with 18 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, embeddingManager?: EmbeddingManager) {\n const tools = createVaultTools(agentId, runId, 0, embeddingManager);\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 turnOffset = 0,\n embeddingManager?: EmbeddingManager,\n) {\n const allTools = createVaultTools(agentId, runId, turnOffset, embeddingManager);\n const nameSet = new Set(toolNames);\n const scopedTools = allTools.filter((t) => nameSet.has(t.name));\n\n return createSdkMcpServer({\n name: 'myco-vault',\n version: getPluginVersion(),\n tools: scopedTools,\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 * 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 === 'cloud') 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 'cloud':\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"],"mappings":"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","names":["crypto","tool","crypto","errorMessage"]}
|