@goondocks/myco 0.21.0 → 0.21.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/myco-run +68 -7
- package/dist/{agent-eval-RJSQI5S2.js → agent-eval-2MQKTXX3.js} +7 -6
- package/dist/{agent-eval-RJSQI5S2.js.map → agent-eval-2MQKTXX3.js.map} +1 -1
- package/dist/{agent-run-2JSYFOKU.js → agent-run-XJBTSVJR.js} +5 -5
- package/dist/{agent-tasks-APFJIM2T.js → agent-tasks-7MWBZOC7.js} +5 -5
- package/dist/{chunk-75Z7UKDY.js → chunk-4D22KTXY.js} +2 -2
- package/dist/{chunk-P66DLD6G.js → chunk-6FBLL7MD.js} +8 -2
- package/dist/chunk-6FBLL7MD.js.map +1 -0
- package/dist/{chunk-JZS6GZ6T.js → chunk-AUIXX33A.js} +10 -3
- package/dist/chunk-AUIXX33A.js.map +1 -0
- package/dist/{chunk-F3OEQYLS.js → chunk-DBBO6FHE.js} +33 -30
- package/dist/{chunk-F3OEQYLS.js.map → chunk-DBBO6FHE.js.map} +1 -1
- package/dist/{chunk-CESKJD44.js → chunk-DMPCC7V6.js} +19 -11
- package/dist/chunk-DMPCC7V6.js.map +1 -0
- package/dist/{chunk-RL5R4CQU.js → chunk-DTWUHHFI.js} +39 -2
- package/dist/{chunk-RL5R4CQU.js.map → chunk-DTWUHHFI.js.map} +1 -1
- package/dist/{chunk-XL75KZGI.js → chunk-EKZG2MCD.js} +7 -3
- package/dist/chunk-EKZG2MCD.js.map +1 -0
- package/dist/{chunk-NGH7U6A3.js → chunk-HCT7RMM2.js} +487 -98
- package/dist/chunk-HCT7RMM2.js.map +1 -0
- package/dist/{chunk-G6QIBNZM.js → chunk-IMW5TJ3O.js} +7 -6
- package/dist/chunk-IMW5TJ3O.js.map +1 -0
- package/dist/chunk-LQIPXVDH.js +17 -0
- package/dist/chunk-LQIPXVDH.js.map +1 -0
- package/dist/{chunk-5ZG4RMUH.js → chunk-N2DGFACQ.js} +2 -2
- package/dist/{chunk-VHNRMM4O.js → chunk-OTQH5KZW.js} +87 -37
- package/dist/chunk-OTQH5KZW.js.map +1 -0
- package/dist/{chunk-6LB7XELY.js → chunk-QATYARI5.js} +15 -13
- package/dist/chunk-QATYARI5.js.map +1 -0
- package/dist/{chunk-LVIY7P35.js → chunk-QLLBJEM7.js} +5 -1
- package/dist/chunk-QLLBJEM7.js.map +1 -0
- package/dist/{chunk-DJ3IHNYO.js → chunk-TFRUDNLI.js} +2 -2
- package/dist/{chunk-R2JIJBCL.js → chunk-TMAXWERS.js} +87 -4
- package/dist/chunk-TMAXWERS.js.map +1 -0
- package/dist/chunk-TSM6VESW.js +25 -0
- package/dist/chunk-TSM6VESW.js.map +1 -0
- package/dist/{chunk-ILJPRYES.js → chunk-USVFEWYL.js} +2 -2
- package/dist/{chunk-JR54LTPP.js → chunk-W5L5IHP5.js} +3 -3
- package/dist/{chunk-BUTL6IFS.js → chunk-Z55WGA2J.js} +2 -2
- package/dist/{chunk-NGROSFOH.js → chunk-Z66IT5KL.js} +14 -9
- package/dist/chunk-Z66IT5KL.js.map +1 -0
- package/dist/{cli-LNYSTDQM.js → cli-DDHTHU2J.js} +37 -37
- package/dist/{client-NWE4TCNO.js → client-PQU53UQU.js} +5 -3
- package/dist/{detect-PXNM6TA7.js → detect-7NUD5B5R.js} +2 -2
- package/dist/{doctor-TI7EZ3RW.js → doctor-QK6KFY6H.js} +6 -6
- package/dist/{executor-F2YU7HXJ.js → executor-FJCMNSXM.js} +11 -10
- package/dist/{init-KG3TYVGE.js → init-GQPD6HHX.js} +9 -9
- package/dist/{installer-UMH7OJ5A.js → installer-N4UTEACX.js} +2 -2
- package/dist/{loader-NAVVZK63.js → loader-UDNUMEDA.js} +3 -2
- package/dist/{main-5PRQNEEE.js → main-4HKTZFIM.js} +469 -187
- package/dist/main-4HKTZFIM.js.map +1 -0
- package/dist/{open-5A27BCSB.js → open-3P3DDAOA.js} +5 -5
- package/dist/{post-compact-USAODKPQ.js → post-compact-QA5LME2J.js} +7 -7
- package/dist/{post-tool-use-GMMSYBII.js → post-tool-use-QRZMPNYL.js} +6 -6
- package/dist/{post-tool-use-failure-NZVSL2PO.js → post-tool-use-failure-XNHIKBZG.js} +7 -7
- package/dist/{pre-compact-LZ57DLUS.js → pre-compact-HDV6X5QM.js} +7 -7
- package/dist/{registry-M2Z5QBWH.js → registry-F3THYC5M.js} +4 -3
- package/dist/{remove-T3KE6C5N.js → remove-USQDLGTJ.js} +7 -7
- package/dist/{restart-YWDEVZUJ.js → restart-FQLZE2TW.js} +6 -6
- package/dist/{search-GKFDGELR.js → search-5COKV6TD.js} +6 -6
- package/dist/{server-AHUR6CWF.js → server-KRMBRW4T.js} +23 -7
- package/dist/{server-AHUR6CWF.js.map → server-KRMBRW4T.js.map} +1 -1
- package/dist/{session-2ZEPLWW6.js → session-NJCUW3OX.js} +5 -5
- package/dist/{session-end-LWJYQAXX.js → session-end-XD27GRYF.js} +6 -6
- package/dist/{session-start-WTA6GCOQ.js → session-start-RDTXUSYL.js} +11 -11
- package/dist/{setup-llm-E7UU5IO7.js → setup-llm-FYPPJI6W.js} +5 -5
- package/dist/src/agent/definitions/tasks/cortex-instructions.yaml +63 -41
- package/dist/src/agent/definitions/tasks/skill-evolve.yaml +178 -22
- package/dist/src/agent/definitions/tasks/skill-generate.yaml +20 -6
- package/dist/src/agent/definitions/tasks/vault-evolve.yaml +65 -55
- 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/src/symbionts/manifests/opencode.yaml +7 -0
- package/dist/src/symbionts/templates/agents-starter.md +1 -1
- package/dist/src/symbionts/templates/opencode/plugin.ts +41 -1
- package/dist/src/symbionts/templates/pi/plugin.ts +12 -1
- package/dist/{stats-DFG6S23S.js → stats-JCLZLA5G.js} +6 -6
- package/dist/{stop-WRBTXEVT.js → stop-B7XCXEM5.js} +6 -6
- package/dist/{stop-failure-32MGIG2Q.js → stop-failure-R6QZCUOZ.js} +7 -7
- package/dist/{subagent-start-VFGHQFVL.js → subagent-start-N7A622F3.js} +7 -7
- package/dist/{subagent-stop-663FXG3P.js → subagent-stop-SVOG5MZJ.js} +7 -7
- package/dist/{task-completed-ZCQYEFMZ.js → task-completed-3DL5LJXF.js} +7 -7
- package/dist/{team-JTI5CDUO.js → team-VJ3M263F.js} +3 -3
- package/dist/ui/assets/{index-DGf1h-Ha.js → index-O1kNWlWM.js} +119 -119
- package/dist/ui/assets/index-z2Jm8i4A.css +1 -0
- package/dist/ui/index.html +2 -2
- package/dist/{update-3NBQTG32.js → update-TVXAUJMZ.js} +45 -11
- package/dist/update-TVXAUJMZ.js.map +1 -0
- package/dist/{user-prompt-submit-ME2TBKOS.js → user-prompt-submit-KYO2VGLB.js} +10 -9
- package/dist/user-prompt-submit-KYO2VGLB.js.map +1 -0
- package/dist/{version-GQAFBBPX.js → version-LDFEALUJ.js} +2 -2
- package/package.json +1 -1
- package/skills/myco-rules/SKILL.md +94 -0
- package/skills/{rules → myco-rules}/references/rules-bad-example.md +1 -1
- package/skills/{rules → myco-rules}/references/rules-good-example.md +1 -1
- package/dist/chunk-6LB7XELY.js.map +0 -1
- package/dist/chunk-CESKJD44.js.map +0 -1
- package/dist/chunk-CUDIZJY7.js +0 -36
- package/dist/chunk-CUDIZJY7.js.map +0 -1
- package/dist/chunk-G6QIBNZM.js.map +0 -1
- package/dist/chunk-JZS6GZ6T.js.map +0 -1
- package/dist/chunk-LVIY7P35.js.map +0 -1
- package/dist/chunk-NGH7U6A3.js.map +0 -1
- package/dist/chunk-NGROSFOH.js.map +0 -1
- package/dist/chunk-P66DLD6G.js.map +0 -1
- package/dist/chunk-R2JIJBCL.js.map +0 -1
- package/dist/chunk-VHNRMM4O.js.map +0 -1
- package/dist/chunk-XL75KZGI.js.map +0 -1
- package/dist/main-5PRQNEEE.js.map +0 -1
- package/dist/ui/assets/index-_OP4ifzH.css +0 -1
- package/dist/update-3NBQTG32.js.map +0 -1
- package/dist/user-prompt-submit-ME2TBKOS.js.map +0 -1
- package/skills/myco-curate/SKILL.md +0 -86
- package/skills/rules/SKILL.md +0 -214
- /package/dist/{agent-run-2JSYFOKU.js.map → agent-run-XJBTSVJR.js.map} +0 -0
- /package/dist/{agent-tasks-APFJIM2T.js.map → agent-tasks-7MWBZOC7.js.map} +0 -0
- /package/dist/{chunk-75Z7UKDY.js.map → chunk-4D22KTXY.js.map} +0 -0
- /package/dist/{chunk-5ZG4RMUH.js.map → chunk-N2DGFACQ.js.map} +0 -0
- /package/dist/{chunk-DJ3IHNYO.js.map → chunk-TFRUDNLI.js.map} +0 -0
- /package/dist/{chunk-ILJPRYES.js.map → chunk-USVFEWYL.js.map} +0 -0
- /package/dist/{chunk-JR54LTPP.js.map → chunk-W5L5IHP5.js.map} +0 -0
- /package/dist/{chunk-BUTL6IFS.js.map → chunk-Z55WGA2J.js.map} +0 -0
- /package/dist/{cli-LNYSTDQM.js.map → cli-DDHTHU2J.js.map} +0 -0
- /package/dist/{client-NWE4TCNO.js.map → client-PQU53UQU.js.map} +0 -0
- /package/dist/{detect-PXNM6TA7.js.map → detect-7NUD5B5R.js.map} +0 -0
- /package/dist/{doctor-TI7EZ3RW.js.map → doctor-QK6KFY6H.js.map} +0 -0
- /package/dist/{executor-F2YU7HXJ.js.map → executor-FJCMNSXM.js.map} +0 -0
- /package/dist/{init-KG3TYVGE.js.map → init-GQPD6HHX.js.map} +0 -0
- /package/dist/{installer-UMH7OJ5A.js.map → installer-N4UTEACX.js.map} +0 -0
- /package/dist/{loader-NAVVZK63.js.map → loader-UDNUMEDA.js.map} +0 -0
- /package/dist/{open-5A27BCSB.js.map → open-3P3DDAOA.js.map} +0 -0
- /package/dist/{post-compact-USAODKPQ.js.map → post-compact-QA5LME2J.js.map} +0 -0
- /package/dist/{post-tool-use-GMMSYBII.js.map → post-tool-use-QRZMPNYL.js.map} +0 -0
- /package/dist/{post-tool-use-failure-NZVSL2PO.js.map → post-tool-use-failure-XNHIKBZG.js.map} +0 -0
- /package/dist/{pre-compact-LZ57DLUS.js.map → pre-compact-HDV6X5QM.js.map} +0 -0
- /package/dist/{registry-M2Z5QBWH.js.map → registry-F3THYC5M.js.map} +0 -0
- /package/dist/{remove-T3KE6C5N.js.map → remove-USQDLGTJ.js.map} +0 -0
- /package/dist/{restart-YWDEVZUJ.js.map → restart-FQLZE2TW.js.map} +0 -0
- /package/dist/{search-GKFDGELR.js.map → search-5COKV6TD.js.map} +0 -0
- /package/dist/{session-2ZEPLWW6.js.map → session-NJCUW3OX.js.map} +0 -0
- /package/dist/{session-end-LWJYQAXX.js.map → session-end-XD27GRYF.js.map} +0 -0
- /package/dist/{session-start-WTA6GCOQ.js.map → session-start-RDTXUSYL.js.map} +0 -0
- /package/dist/{setup-llm-E7UU5IO7.js.map → setup-llm-FYPPJI6W.js.map} +0 -0
- /package/dist/{stats-DFG6S23S.js.map → stats-JCLZLA5G.js.map} +0 -0
- /package/dist/{stop-WRBTXEVT.js.map → stop-B7XCXEM5.js.map} +0 -0
- /package/dist/{stop-failure-32MGIG2Q.js.map → stop-failure-R6QZCUOZ.js.map} +0 -0
- /package/dist/{subagent-start-VFGHQFVL.js.map → subagent-start-N7A622F3.js.map} +0 -0
- /package/dist/{subagent-stop-663FXG3P.js.map → subagent-stop-SVOG5MZJ.js.map} +0 -0
- /package/dist/{task-completed-ZCQYEFMZ.js.map → task-completed-3DL5LJXF.js.map} +0 -0
- /package/dist/{team-JTI5CDUO.js.map → team-VJ3M263F.js.map} +0 -0
- /package/dist/{version-GQAFBBPX.js.map → version-LDFEALUJ.js.map} +0 -0
package/bin/myco-run
CHANGED
|
@@ -1,15 +1,76 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// Self-locating MCP launcher with project-aware alias dispatch.
|
|
4
|
+
//
|
|
5
|
+
// Two dispatch modes, checked in order:
|
|
6
|
+
//
|
|
7
|
+
// 1. Alias mode — if the project (found by walking up from cwd) has a
|
|
8
|
+
// `.myco/runtime.command` file with a non-empty value, re-exec that
|
|
9
|
+
// binary with the same argv. Mirrors `.agents/myco-run.cjs`: one
|
|
10
|
+
// source of truth for "which myco binary answers for this project,"
|
|
11
|
+
// whether invoked from a hook or from MCP.
|
|
12
|
+
//
|
|
13
|
+
// A single env-var marker (MYCO_RUN_REDIRECTED=1) prevents infinite
|
|
14
|
+
// recursion if someone sets `runtime.command=myco-run` or creates
|
|
15
|
+
// any loop. It's a belt-and-suspenders cheaper than realpath
|
|
16
|
+
// comparisons and robust across symlink chains.
|
|
17
|
+
//
|
|
18
|
+
// If the aliased binary isn't on PATH (ENOENT), fall through to
|
|
19
|
+
// self-locate — the production binary still works when a project
|
|
20
|
+
// references a dev binary the current process can't reach.
|
|
21
|
+
//
|
|
22
|
+
// 2. Self-locate — resolve this launcher's own install via
|
|
23
|
+
// realpathSync(argv[1]) and exec `<install>/dist/src/cli.js`. This
|
|
24
|
+
// is the historical behavior: cwd-independent, immune to PATH
|
|
25
|
+
// pollution, correct for prod (homebrew) and dev (npm link) alike.
|
|
26
|
+
|
|
3
27
|
import fs from 'node:fs';
|
|
4
28
|
import path from 'node:path';
|
|
5
29
|
import { execFileSync } from 'node:child_process';
|
|
6
30
|
|
|
7
|
-
|
|
8
|
-
|
|
31
|
+
function resolveRuntimeCommand(startDir) {
|
|
32
|
+
let dir = path.resolve(startDir);
|
|
33
|
+
while (true) {
|
|
34
|
+
const candidate = path.join(dir, '.myco', 'runtime.command');
|
|
35
|
+
try {
|
|
36
|
+
const alias = fs.readFileSync(candidate, 'utf-8').trim();
|
|
37
|
+
return alias || null;
|
|
38
|
+
} catch { /* not here, try parent */ }
|
|
39
|
+
const parent = path.dirname(dir);
|
|
40
|
+
if (parent === dir) return null;
|
|
41
|
+
dir = parent;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function tryRedirectViaAlias(argv) {
|
|
46
|
+
if (process.env.MYCO_RUN_REDIRECTED === '1') return false;
|
|
47
|
+
const alias = resolveRuntimeCommand(process.cwd());
|
|
48
|
+
if (!alias) return false;
|
|
9
49
|
|
|
10
|
-
try {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
50
|
+
try {
|
|
51
|
+
execFileSync(alias, argv, {
|
|
52
|
+
stdio: 'inherit',
|
|
53
|
+
env: { ...process.env, MYCO_RUN_REDIRECTED: '1' },
|
|
54
|
+
});
|
|
55
|
+
process.exit(0);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
if (error.code === 'ENOENT') return false;
|
|
58
|
+
process.exit(error.status ?? 1);
|
|
59
|
+
}
|
|
15
60
|
}
|
|
61
|
+
|
|
62
|
+
function execSelfLocated(argv) {
|
|
63
|
+
const scriptPath = fs.realpathSync(process.argv[1]);
|
|
64
|
+
const cliEntry = path.resolve(path.dirname(scriptPath), '..', 'dist', 'src', 'cli.js');
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
execFileSync(process.execPath, [cliEntry, ...argv], { stdio: 'inherit' });
|
|
68
|
+
} catch (error) {
|
|
69
|
+
if (error.code === 'ENOENT') process.exit(0);
|
|
70
|
+
process.exit(error.status ?? 1);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const forwardArgs = process.argv.slice(2);
|
|
75
|
+
tryRedirectViaAlias(forwardArgs);
|
|
76
|
+
execSelfLocated(forwardArgs);
|
|
@@ -4,19 +4,20 @@ import {
|
|
|
4
4
|
} from "./chunk-54SXG5HF.js";
|
|
5
5
|
import {
|
|
6
6
|
runDurationMs
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-QATYARI5.js";
|
|
8
|
+
import "./chunk-LQIPXVDH.js";
|
|
8
9
|
import {
|
|
9
10
|
connectToDaemon
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-W5L5IHP5.js";
|
|
11
12
|
import "./chunk-SAKJMNSR.js";
|
|
12
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-OTQH5KZW.js";
|
|
13
14
|
import "./chunk-X3IGT5RV.js";
|
|
14
15
|
import "./chunk-53RPGOEN.js";
|
|
15
16
|
import "./chunk-OUJSQSKE.js";
|
|
16
17
|
import "./chunk-POEPHBQK.js";
|
|
17
18
|
import "./chunk-MYX5NCRH.js";
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-6FBLL7MD.js";
|
|
20
|
+
import "./chunk-Z55WGA2J.js";
|
|
20
21
|
import "./chunk-LPUQPDC2.js";
|
|
21
22
|
import "./chunk-6C6QZ4PM.js";
|
|
22
23
|
import "./chunk-UUHLLQXO.js";
|
|
@@ -352,4 +353,4 @@ export {
|
|
|
352
353
|
parsePhaseArg,
|
|
353
354
|
run
|
|
354
355
|
};
|
|
355
|
-
//# sourceMappingURL=agent-eval-
|
|
356
|
+
//# sourceMappingURL=agent-eval-2MQKTXX3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/agent-eval.ts"],"sourcesContent":["/**\n * CLI `agent eval` command — run an evaluation matrix across runtime/reasoning/model\n * variants via the daemon API.\n *\n * POSTs to /api/agent/evaluations (fire-and-forget) then polls\n * GET /api/agent/evaluations/:id until the evaluation completes or times out.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { connectToDaemon } from './shared.js';\nimport { enumerateMatrixCells, type EvaluationMatrixCell } from '../agent/evaluation-matrix.js';\nimport { runDurationMs } from '../agent/run-accounting.js';\nimport type { RuntimeId, ReasoningLevel } from '../agent/types.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Per-phase overrides applied to every cell in the matrix. A phase entry\n * can pin `reasoningLevel`, `model`, or both — the executor merges these\n * on top of the cell-level runtime/reasoning/model at phase-execute time.\n */\nexport type PhaseOverrideMap = Record<\n string,\n { reasoningLevel?: ReasoningLevel; model?: string }\n>;\n\ninterface EvalMatrix {\n runtimes?: RuntimeId[];\n reasoningLevels?: ReasoningLevel[];\n models?: string[];\n dryRun?: boolean;\n notes?: string;\n phases?: PhaseOverrideMap;\n}\n\ninterface ParsedArgs {\n taskId: string;\n matrix: EvalMatrix;\n notes?: string;\n pollInterval: number;\n timeout: number;\n noWait: boolean;\n}\n\n/**\n * One row in the comparison table. Task A persists the reasoning level and\n * full execution-override packet on each `agent_runs` row (and the daemon\n * serializes both into the API response), so the CLI reads per-cell\n * attribution directly from the run row — no client-side zip against the\n * enumerated matrix cells is required. `enumerateMatrixCells` is still\n * used for display metadata (cell count, phase overlay).\n */\ninterface TableRow {\n runtime: string;\n reasoning: string;\n model: string;\n dryRun: string;\n status: string;\n turns: string;\n tokens: string;\n cost: string;\n duration: string;\n /**\n * Compact summary of `matrix.phases` pins shared across all cells, e.g.\n * `\"extract=low, digest=high\"`. Rendered only when at least one row has\n * a non-empty value (i.e. the matrix had a `phases` overlay).\n */\n phaseOverrides?: string;\n}\n\ninterface RunRecord {\n id: string;\n runtime?: string | null;\n model?: string | null;\n reasoning_level?: string | null;\n status?: string | null;\n started_at?: number | null;\n completed_at?: number | null;\n tokens_used?: number | null;\n cost_usd?: number | null;\n dry_run?: number | boolean | null;\n error?: string | null;\n actions_taken?: number | null;\n}\n\n// ---------------------------------------------------------------------------\n// Help text\n// ---------------------------------------------------------------------------\n\nconst HELP = `Usage: myco agent eval [options]\n\nRun an evaluation matrix across runtime/reasoning/model variants.\n\nOptions:\n --task <taskId> Task to evaluate (required)\n --runtimes <r1,r2> Comma-separated runtimes: claude-sdk, openai-agents\n --reasoning <l1,l2> Comma-separated reasoning levels: low, default, high\n --models <m1,m2> Comma-separated model names\n --phase-reasoning <pairs> Per-phase reasoning pins: \"extract:low,digest:high\"\n --phase-model <pairs> Per-phase model pins: \"extract:claude-haiku-4-5,digest:claude-opus-4-6\"\n --dry-run Run in dry-run mode (writes intercepted, not applied)\n --notes \"<text>\" Optional notes for this evaluation\n --poll-interval <seconds> Polling interval (default: 10)\n --timeout <seconds> Max wait time in seconds (default: 3600)\n --no-wait Print evaluation id and exit without polling\n --help, -h Show this help message\n\nExamples:\n myco agent eval --task vault-evolve --dry-run --no-wait\n myco agent eval --task vault-evolve --runtimes claude-sdk,openai-agents --dry-run\n myco agent eval --task vault-evolve --reasoning low,high --models claude-opus-4-5\n`;\n\n// ---------------------------------------------------------------------------\n// Phase arg parser\n// ---------------------------------------------------------------------------\n\nconst VALID_REASONING: ReadonlySet<ReasoningLevel> = new Set(['low', 'default', 'high']);\n\n/**\n * Parse a comma-separated list of \"phase:value\" pairs into a phase-keyed\n * object. The value is injected into the entry under `field`.\n *\n * Merges into an existing accumulator so `--phase-reasoning` and\n * `--phase-model` can collide on the same phase and combine their fields.\n *\n * Throws with a human-readable message on a malformed pair (missing colon,\n * empty phase, or — when `field` is `reasoningLevel` — a value outside\n * `'low' | 'default' | 'high'`).\n */\nexport function parsePhaseArg(\n raw: string,\n field: 'reasoningLevel' | 'model',\n acc: PhaseOverrideMap = {},\n): PhaseOverrideMap {\n const pairs = raw.split(',').map((p) => p.trim()).filter(Boolean);\n if (pairs.length === 0) {\n throw new Error(`--phase-${field === 'reasoningLevel' ? 'reasoning' : 'model'} produced zero pairs after splitting`);\n }\n for (const pair of pairs) {\n const colonIdx = pair.indexOf(':');\n if (colonIdx < 1 || colonIdx === pair.length - 1) {\n throw new Error(`Malformed phase pair \"${pair}\" — expected \"<phase>:<value>\"`);\n }\n const phase = pair.slice(0, colonIdx).trim();\n const value = pair.slice(colonIdx + 1).trim();\n if (!phase || !value) {\n throw new Error(`Malformed phase pair \"${pair}\" — expected \"<phase>:<value>\"`);\n }\n if (field === 'reasoningLevel' && !VALID_REASONING.has(value as ReasoningLevel)) {\n throw new Error(\n `Invalid reasoning level \"${value}\" for phase \"${phase}\" — expected low, default, or high`,\n );\n }\n const existing = acc[phase] ?? {};\n acc[phase] = {\n ...existing,\n ...(field === 'reasoningLevel'\n ? { reasoningLevel: value as ReasoningLevel }\n : { model: value }),\n };\n }\n return acc;\n}\n\n// ---------------------------------------------------------------------------\n// Arg parser\n// ---------------------------------------------------------------------------\n\n/**\n * Parse CLI args into a typed structure. Throws with a human-readable message\n * on invalid input.\n */\nexport function parseArgs(args: string[]): ParsedArgs {\n if (args.includes('--help') || args.includes('-h')) {\n process.stdout.write(HELP);\n process.exit(0);\n }\n\n // Helper to get the value after a flag\n const getFlag = (flag: string): string | undefined => {\n const idx = args.indexOf(flag);\n if (idx === -1) return undefined;\n const val = args[idx + 1];\n if (!val || val.startsWith('--')) return undefined;\n return val;\n };\n\n const taskId = getFlag('--task');\n if (!taskId) {\n throw new Error('--task <taskId> is required');\n }\n\n const runtimesRaw = getFlag('--runtimes');\n const reasoningRaw = getFlag('--reasoning');\n const modelsRaw = getFlag('--models');\n const phaseReasoningRaw = getFlag('--phase-reasoning');\n const phaseModelRaw = getFlag('--phase-model');\n const notesRaw = getFlag('--notes');\n const pollIntervalRaw = getFlag('--poll-interval');\n const timeoutRaw = getFlag('--timeout');\n\n const dryRun = args.includes('--dry-run');\n const noWait = args.includes('--no-wait');\n\n const matrix: EvalMatrix = {};\n\n if (runtimesRaw !== undefined) {\n const runtimes = runtimesRaw\n .split(',')\n .map((r) => r.trim())\n .filter(Boolean) as RuntimeId[];\n if (runtimes.length === 0) {\n throw new Error('--runtimes produced zero values after splitting');\n }\n matrix.runtimes = runtimes;\n }\n\n if (reasoningRaw !== undefined) {\n const reasoningLevels = reasoningRaw\n .split(',')\n .map((r) => r.trim())\n .filter(Boolean) as ReasoningLevel[];\n if (reasoningLevels.length === 0) {\n throw new Error('--reasoning produced zero values after splitting');\n }\n matrix.reasoningLevels = reasoningLevels;\n }\n\n if (modelsRaw !== undefined) {\n const models = modelsRaw\n .split(',')\n .map((m) => m.trim())\n .filter(Boolean);\n if (models.length === 0) {\n throw new Error('--models produced zero values after splitting');\n }\n matrix.models = models;\n }\n\n if (dryRun) {\n matrix.dryRun = true;\n }\n\n if (notesRaw) {\n matrix.notes = notesRaw;\n }\n\n // `--phase-reasoning` and `--phase-model` can target the same phase; they\n // merge into a single entry with whichever fields were specified.\n let phases: PhaseOverrideMap | undefined;\n if (phaseReasoningRaw !== undefined) {\n phases = parsePhaseArg(phaseReasoningRaw, 'reasoningLevel', phases ?? {});\n }\n if (phaseModelRaw !== undefined) {\n phases = parsePhaseArg(phaseModelRaw, 'model', phases ?? {});\n }\n if (phases && Object.keys(phases).length > 0) {\n matrix.phases = phases;\n }\n\n const pollInterval = pollIntervalRaw ? parseInt(pollIntervalRaw, 10) : 10;\n if (isNaN(pollInterval) || pollInterval < 1) {\n throw new Error('--poll-interval must be a positive integer');\n }\n\n const timeout = timeoutRaw ? parseInt(timeoutRaw, 10) : 3600;\n if (isNaN(timeout) || timeout < 1) {\n throw new Error('--timeout must be a positive integer');\n }\n\n return {\n taskId,\n matrix,\n notes: notesRaw,\n pollInterval,\n timeout,\n noWait,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Matrix cell enumeration (display only)\n// ---------------------------------------------------------------------------\n\n/**\n * Thin re-export of the shared `enumerateMatrixCells` helper. The CLI used\n * to zip enumerated cells against child runs to derive per-cell\n * attribution, but each `agent_runs` row now persists its own runtime /\n * reasoning_level / execution_overrides (Task A + C), so per-row fields\n * come from the run row itself. This helper is retained solely for\n * display metadata (initial cell count, phase overlay rendering).\n */\nexport function enumerateCells(matrix: EvalMatrix): EvaluationMatrixCell[] {\n return enumerateMatrixCells(matrix);\n}\n\n// ---------------------------------------------------------------------------\n// Table formatter\n// ---------------------------------------------------------------------------\n\nconst TABLE_COLUMNS: Array<{ key: keyof TableRow; header: string }> = [\n { key: 'runtime', header: 'runtime' },\n { key: 'reasoning', header: 'reasoning' },\n { key: 'model', header: 'model' },\n { key: 'dryRun', header: 'dry-run' },\n { key: 'status', header: 'status' },\n { key: 'turns', header: 'turns' },\n { key: 'tokens', header: 'tokens' },\n { key: 'cost', header: 'cost' },\n { key: 'duration', header: 'duration' },\n];\n\n/**\n * Render `matrix.phases` as a compact summary like `\"extract=low,\n * digest=high\"`. When a phase entry has both `reasoningLevel` and `model`\n * pinned, only `reasoningLevel` is shown (model pins are usually long and\n * would blow out the table); the JSON report carries the full fidelity.\n *\n * Returns an empty string for missing / empty input so `formatTable` can\n * cheaply detect whether the column should appear at all.\n */\nexport function formatPhaseOverrides(phases: PhaseOverrideMap | undefined): string {\n if (!phases) return '';\n const entries = Object.entries(phases);\n if (entries.length === 0) return '';\n return entries\n .map(([phase, pin]) => {\n if (pin.reasoningLevel) return `${phase}=${pin.reasoningLevel}`;\n if (pin.model) return `${phase}=${pin.model}`;\n return phase;\n })\n .join(', ');\n}\n\n/**\n * Format rows into a plain-ASCII table with per-column width padding.\n * Returns the table as a string (no trailing newline).\n *\n * The \"phase overrides\" column is shown only when at least one row has a\n * non-empty `phaseOverrides` value; otherwise it's omitted entirely so\n * the common (no-phase-pins) output stays compact.\n */\nexport function formatTable(rows: TableRow[]): string {\n const includePhaseOverrides = rows.some((r) => (r.phaseOverrides ?? '').length > 0);\n const columns: Array<{ key: keyof TableRow; header: string }> = includePhaseOverrides\n ? [...TABLE_COLUMNS, { key: 'phaseOverrides', header: 'phase overrides' }]\n : TABLE_COLUMNS;\n\n // Compute column widths = max(header.length, max(cell.length)) for each col\n const widths = columns.map(({ key, header }) => {\n let max = header.length;\n for (const row of rows) {\n const cell = row[key] ?? '';\n if (cell.length > max) max = cell.length;\n }\n return max;\n });\n\n const sep = widths.map((w) => '-'.repeat(w)).join('-+-');\n const headerLine = columns.map(({ header }, i) => header.padEnd(widths[i])).join(' | ');\n\n const dataLines = rows.map((row) =>\n columns.map(({ key }, i) => (row[key] ?? '').padEnd(widths[i])).join(' | ')\n );\n\n return [headerLine, sep, ...dataLines].join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Elapsed-time formatter\n// ---------------------------------------------------------------------------\n\nfunction fmtElapsed(seconds: number): string {\n const mm = Math.floor(seconds / 60);\n const ss = String(seconds % 60).padStart(2, '0');\n return `${String(mm).padStart(2, '0')}:${ss}`;\n}\n\n// ---------------------------------------------------------------------------\n// JSON report writer\n// ---------------------------------------------------------------------------\n\nfunction writeReport(\n vaultDir: string,\n evaluationId: string,\n taskId: string,\n matrix: EvalMatrix,\n status: string,\n createdAt: number | undefined,\n completedAt: number | undefined,\n runs: RunRecord[],\n aggregate: Record<string, unknown>,\n): void {\n const reportDir = path.join(vaultDir, 'digest', 'evaluations');\n fs.mkdirSync(reportDir, { recursive: true });\n\n const reportCells = runs.map((run) => ({\n runId: run.id,\n runtime: run.runtime ?? null,\n reasoningLevel: run.reasoning_level ?? null,\n model: run.model ?? null,\n dryRun: run.dry_run === 1 || run.dry_run === true,\n status: run.status ?? null,\n turns: run.actions_taken ?? null,\n tokens: run.tokens_used ?? null,\n costUsd: run.cost_usd ?? null,\n durationMs: runDurationMs({\n started_at: run.started_at ?? null,\n completed_at: run.completed_at ?? null,\n }),\n error: run.error ?? null,\n }));\n\n const report = {\n evaluationId,\n taskId,\n matrix,\n status,\n createdAt: createdAt ?? null,\n completedAt: completedAt ?? null,\n cells: reportCells,\n aggregate,\n };\n\n const reportPath = path.join(reportDir, `${evaluationId}.json`);\n fs.writeFileSync(reportPath, JSON.stringify(report, null, 2), 'utf-8');\n console.log(`Report written to ${reportPath}`);\n}\n\n// ---------------------------------------------------------------------------\n// Main\n// ---------------------------------------------------------------------------\n\nexport async function run(args: string[], vaultDir: string): Promise<void> {\n let parsed: ParsedArgs;\n try {\n parsed = parseArgs(args);\n } catch (err) {\n console.error(`myco agent eval: ${(err as Error).message}`);\n process.stdout.write(HELP);\n process.exit(1);\n }\n\n const { taskId, matrix, notes, pollInterval, timeout, noWait } = parsed;\n\n const client = await connectToDaemon(vaultDir);\n\n // POST to create evaluation\n const createResult = await client.post('/api/agent/evaluations', {\n taskId,\n matrix,\n ...(notes ? { notes } : {}),\n });\n\n if (!createResult.ok || !createResult.data?.evaluationId) {\n console.error('Failed to create evaluation');\n if (createResult.data?.error) {\n console.error(` ${createResult.data.error}`);\n }\n process.exit(1);\n }\n\n const { evaluationId, cellCount } = createResult.data as {\n evaluationId: string;\n cellCount: number;\n };\n\n console.log(`Evaluation created: ${evaluationId}`);\n console.log(` task: ${taskId}`);\n console.log(` cells: ${cellCount}`);\n if (matrix.dryRun) console.log(' mode: dry-run');\n\n if (noWait) {\n process.exit(0);\n }\n\n // Poll until done or timeout. Per-row attribution comes from the run row\n // itself (runtime/reasoning_level/model) — no client-side zip required.\n const startTime = Date.now();\n let lastStatus = '';\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const elapsed = Math.floor((Date.now() - startTime) / 1000);\n if (elapsed >= timeout) {\n console.error(`\\nEvaluation timed out after ${timeout}s`);\n process.exit(2);\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollInterval * 1000));\n\n const getResult = await client.get(`/api/agent/evaluations/${evaluationId}`);\n if (!getResult.ok || !getResult.data) {\n console.error('Failed to poll evaluation status');\n continue;\n }\n\n const { evaluation, runs, aggregate } = getResult.data as {\n evaluation: {\n id: string;\n taskId: string;\n matrix: EvalMatrix;\n notes?: string;\n status: string;\n createdAt?: number;\n completedAt?: number;\n };\n runs: RunRecord[];\n aggregate: {\n total: number;\n completed: number;\n failed: number;\n skipped: number;\n totalTokens: number;\n totalCostUsd: number;\n };\n };\n\n const { completed, total } = aggregate;\n const elapsedStr = fmtElapsed(elapsed);\n const currentRun = runs.find((r) => r.status === 'running');\n const runningInfo = currentRun\n ? ` — running cell ${completed + 1} (${currentRun.runtime ?? 'default'}/${currentRun.reasoning_level ?? 'default'})`\n : '';\n\n const statusLine = `[${elapsedStr}] ${completed}/${total} cells complete${runningInfo}`;\n if (statusLine !== lastStatus) {\n console.log(statusLine);\n lastStatus = statusLine;\n }\n\n const done = evaluation.status === 'completed' || evaluation.status === 'failed';\n if (done) {\n console.log(`\\nEvaluation ${evaluation.status}: ${evaluationId}`);\n\n // Build comparison table from the run rows themselves — each row\n // carries runtime / reasoning_level / model / dry_run populated by\n // the executor, so no zip against enumerated matrix cells is needed.\n const phaseOverridesStr = formatPhaseOverrides(evaluation.matrix.phases);\n const tableRows: TableRow[] = runs.map((run) => {\n const durationMs = runDurationMs({\n started_at: run.started_at ?? null,\n completed_at: run.completed_at ?? null,\n });\n const durationStr = durationMs !== null ? `${(durationMs / 1000).toFixed(1)}s` : '-';\n const costStr = run.cost_usd !== null && run.cost_usd !== undefined\n ? `$${run.cost_usd.toFixed(4)}`\n : '-';\n return {\n runtime: run.runtime ?? '(default)',\n reasoning: run.reasoning_level ?? '(task default)',\n model: run.model ?? '(default)',\n dryRun: (run.dry_run === 1 || run.dry_run === true) ? 'yes' : 'no',\n status: run.status ?? 'unknown',\n turns: String(run.actions_taken ?? '-'),\n tokens: String(run.tokens_used ?? '-'),\n cost: costStr,\n duration: durationStr,\n ...(phaseOverridesStr ? { phaseOverrides: phaseOverridesStr } : {}),\n };\n });\n\n if (tableRows.length > 0) {\n console.log('\\n' + formatTable(tableRows));\n }\n\n // Summary line\n console.log(\n `\\nAggregate: ${aggregate.completed} completed, ${aggregate.failed} failed, ${aggregate.skipped} skipped` +\n ` | tokens: ${aggregate.totalTokens} | cost: $${aggregate.totalCostUsd.toFixed(4)}`\n );\n\n // Write JSON report\n writeReport(\n vaultDir,\n evaluationId,\n evaluation.taskId,\n evaluation.matrix,\n evaluation.status,\n evaluation.createdAt,\n evaluation.completedAt,\n runs,\n aggregate as Record<string, unknown>,\n );\n\n process.exit(evaluation.status === 'completed' ? 0 : 1);\n }\n }\n}\n"],"mappings":"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","names":["run"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/agent-eval.ts"],"sourcesContent":["/**\n * CLI `agent eval` command — run an evaluation matrix across runtime/reasoning/model\n * variants via the daemon API.\n *\n * POSTs to /api/agent/evaluations (fire-and-forget) then polls\n * GET /api/agent/evaluations/:id until the evaluation completes or times out.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { connectToDaemon } from './shared.js';\nimport { enumerateMatrixCells, type EvaluationMatrixCell } from '../agent/evaluation-matrix.js';\nimport { runDurationMs } from '../agent/run-accounting.js';\nimport type { RuntimeId, ReasoningLevel } from '../agent/types.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Per-phase overrides applied to every cell in the matrix. A phase entry\n * can pin `reasoningLevel`, `model`, or both — the executor merges these\n * on top of the cell-level runtime/reasoning/model at phase-execute time.\n */\nexport type PhaseOverrideMap = Record<\n string,\n { reasoningLevel?: ReasoningLevel; model?: string }\n>;\n\ninterface EvalMatrix {\n runtimes?: RuntimeId[];\n reasoningLevels?: ReasoningLevel[];\n models?: string[];\n dryRun?: boolean;\n notes?: string;\n phases?: PhaseOverrideMap;\n}\n\ninterface ParsedArgs {\n taskId: string;\n matrix: EvalMatrix;\n notes?: string;\n pollInterval: number;\n timeout: number;\n noWait: boolean;\n}\n\n/**\n * One row in the comparison table. Task A persists the reasoning level and\n * full execution-override packet on each `agent_runs` row (and the daemon\n * serializes both into the API response), so the CLI reads per-cell\n * attribution directly from the run row — no client-side zip against the\n * enumerated matrix cells is required. `enumerateMatrixCells` is still\n * used for display metadata (cell count, phase overlay).\n */\ninterface TableRow {\n runtime: string;\n reasoning: string;\n model: string;\n dryRun: string;\n status: string;\n turns: string;\n tokens: string;\n cost: string;\n duration: string;\n /**\n * Compact summary of `matrix.phases` pins shared across all cells, e.g.\n * `\"extract=low, digest=high\"`. Rendered only when at least one row has\n * a non-empty value (i.e. the matrix had a `phases` overlay).\n */\n phaseOverrides?: string;\n}\n\ninterface RunRecord {\n id: string;\n runtime?: string | null;\n model?: string | null;\n reasoning_level?: string | null;\n status?: string | null;\n started_at?: number | null;\n completed_at?: number | null;\n tokens_used?: number | null;\n cost_usd?: number | null;\n dry_run?: number | boolean | null;\n error?: string | null;\n actions_taken?: number | null;\n}\n\n// ---------------------------------------------------------------------------\n// Help text\n// ---------------------------------------------------------------------------\n\nconst HELP = `Usage: myco agent eval [options]\n\nRun an evaluation matrix across runtime/reasoning/model variants.\n\nOptions:\n --task <taskId> Task to evaluate (required)\n --runtimes <r1,r2> Comma-separated runtimes: claude-sdk, openai-agents\n --reasoning <l1,l2> Comma-separated reasoning levels: low, default, high\n --models <m1,m2> Comma-separated model names\n --phase-reasoning <pairs> Per-phase reasoning pins: \"extract:low,digest:high\"\n --phase-model <pairs> Per-phase model pins: \"extract:claude-haiku-4-5,digest:claude-opus-4-6\"\n --dry-run Run in dry-run mode (writes intercepted, not applied)\n --notes \"<text>\" Optional notes for this evaluation\n --poll-interval <seconds> Polling interval (default: 10)\n --timeout <seconds> Max wait time in seconds (default: 3600)\n --no-wait Print evaluation id and exit without polling\n --help, -h Show this help message\n\nExamples:\n myco agent eval --task vault-evolve --dry-run --no-wait\n myco agent eval --task vault-evolve --runtimes claude-sdk,openai-agents --dry-run\n myco agent eval --task vault-evolve --reasoning low,high --models claude-opus-4-5\n`;\n\n// ---------------------------------------------------------------------------\n// Phase arg parser\n// ---------------------------------------------------------------------------\n\nconst VALID_REASONING: ReadonlySet<ReasoningLevel> = new Set(['low', 'default', 'high']);\n\n/**\n * Parse a comma-separated list of \"phase:value\" pairs into a phase-keyed\n * object. The value is injected into the entry under `field`.\n *\n * Merges into an existing accumulator so `--phase-reasoning` and\n * `--phase-model` can collide on the same phase and combine their fields.\n *\n * Throws with a human-readable message on a malformed pair (missing colon,\n * empty phase, or — when `field` is `reasoningLevel` — a value outside\n * `'low' | 'default' | 'high'`).\n */\nexport function parsePhaseArg(\n raw: string,\n field: 'reasoningLevel' | 'model',\n acc: PhaseOverrideMap = {},\n): PhaseOverrideMap {\n const pairs = raw.split(',').map((p) => p.trim()).filter(Boolean);\n if (pairs.length === 0) {\n throw new Error(`--phase-${field === 'reasoningLevel' ? 'reasoning' : 'model'} produced zero pairs after splitting`);\n }\n for (const pair of pairs) {\n const colonIdx = pair.indexOf(':');\n if (colonIdx < 1 || colonIdx === pair.length - 1) {\n throw new Error(`Malformed phase pair \"${pair}\" — expected \"<phase>:<value>\"`);\n }\n const phase = pair.slice(0, colonIdx).trim();\n const value = pair.slice(colonIdx + 1).trim();\n if (!phase || !value) {\n throw new Error(`Malformed phase pair \"${pair}\" — expected \"<phase>:<value>\"`);\n }\n if (field === 'reasoningLevel' && !VALID_REASONING.has(value as ReasoningLevel)) {\n throw new Error(\n `Invalid reasoning level \"${value}\" for phase \"${phase}\" — expected low, default, or high`,\n );\n }\n const existing = acc[phase] ?? {};\n acc[phase] = {\n ...existing,\n ...(field === 'reasoningLevel'\n ? { reasoningLevel: value as ReasoningLevel }\n : { model: value }),\n };\n }\n return acc;\n}\n\n// ---------------------------------------------------------------------------\n// Arg parser\n// ---------------------------------------------------------------------------\n\n/**\n * Parse CLI args into a typed structure. Throws with a human-readable message\n * on invalid input.\n */\nexport function parseArgs(args: string[]): ParsedArgs {\n if (args.includes('--help') || args.includes('-h')) {\n process.stdout.write(HELP);\n process.exit(0);\n }\n\n // Helper to get the value after a flag\n const getFlag = (flag: string): string | undefined => {\n const idx = args.indexOf(flag);\n if (idx === -1) return undefined;\n const val = args[idx + 1];\n if (!val || val.startsWith('--')) return undefined;\n return val;\n };\n\n const taskId = getFlag('--task');\n if (!taskId) {\n throw new Error('--task <taskId> is required');\n }\n\n const runtimesRaw = getFlag('--runtimes');\n const reasoningRaw = getFlag('--reasoning');\n const modelsRaw = getFlag('--models');\n const phaseReasoningRaw = getFlag('--phase-reasoning');\n const phaseModelRaw = getFlag('--phase-model');\n const notesRaw = getFlag('--notes');\n const pollIntervalRaw = getFlag('--poll-interval');\n const timeoutRaw = getFlag('--timeout');\n\n const dryRun = args.includes('--dry-run');\n const noWait = args.includes('--no-wait');\n\n const matrix: EvalMatrix = {};\n\n if (runtimesRaw !== undefined) {\n const runtimes = runtimesRaw\n .split(',')\n .map((r) => r.trim())\n .filter(Boolean) as RuntimeId[];\n if (runtimes.length === 0) {\n throw new Error('--runtimes produced zero values after splitting');\n }\n matrix.runtimes = runtimes;\n }\n\n if (reasoningRaw !== undefined) {\n const reasoningLevels = reasoningRaw\n .split(',')\n .map((r) => r.trim())\n .filter(Boolean) as ReasoningLevel[];\n if (reasoningLevels.length === 0) {\n throw new Error('--reasoning produced zero values after splitting');\n }\n matrix.reasoningLevels = reasoningLevels;\n }\n\n if (modelsRaw !== undefined) {\n const models = modelsRaw\n .split(',')\n .map((m) => m.trim())\n .filter(Boolean);\n if (models.length === 0) {\n throw new Error('--models produced zero values after splitting');\n }\n matrix.models = models;\n }\n\n if (dryRun) {\n matrix.dryRun = true;\n }\n\n if (notesRaw) {\n matrix.notes = notesRaw;\n }\n\n // `--phase-reasoning` and `--phase-model` can target the same phase; they\n // merge into a single entry with whichever fields were specified.\n let phases: PhaseOverrideMap | undefined;\n if (phaseReasoningRaw !== undefined) {\n phases = parsePhaseArg(phaseReasoningRaw, 'reasoningLevel', phases ?? {});\n }\n if (phaseModelRaw !== undefined) {\n phases = parsePhaseArg(phaseModelRaw, 'model', phases ?? {});\n }\n if (phases && Object.keys(phases).length > 0) {\n matrix.phases = phases;\n }\n\n const pollInterval = pollIntervalRaw ? parseInt(pollIntervalRaw, 10) : 10;\n if (isNaN(pollInterval) || pollInterval < 1) {\n throw new Error('--poll-interval must be a positive integer');\n }\n\n const timeout = timeoutRaw ? parseInt(timeoutRaw, 10) : 3600;\n if (isNaN(timeout) || timeout < 1) {\n throw new Error('--timeout must be a positive integer');\n }\n\n return {\n taskId,\n matrix,\n notes: notesRaw,\n pollInterval,\n timeout,\n noWait,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Matrix cell enumeration (display only)\n// ---------------------------------------------------------------------------\n\n/**\n * Thin re-export of the shared `enumerateMatrixCells` helper. The CLI used\n * to zip enumerated cells against child runs to derive per-cell\n * attribution, but each `agent_runs` row now persists its own runtime /\n * reasoning_level / execution_overrides (Task A + C), so per-row fields\n * come from the run row itself. This helper is retained solely for\n * display metadata (initial cell count, phase overlay rendering).\n */\nexport function enumerateCells(matrix: EvalMatrix): EvaluationMatrixCell[] {\n return enumerateMatrixCells(matrix);\n}\n\n// ---------------------------------------------------------------------------\n// Table formatter\n// ---------------------------------------------------------------------------\n\nconst TABLE_COLUMNS: Array<{ key: keyof TableRow; header: string }> = [\n { key: 'runtime', header: 'runtime' },\n { key: 'reasoning', header: 'reasoning' },\n { key: 'model', header: 'model' },\n { key: 'dryRun', header: 'dry-run' },\n { key: 'status', header: 'status' },\n { key: 'turns', header: 'turns' },\n { key: 'tokens', header: 'tokens' },\n { key: 'cost', header: 'cost' },\n { key: 'duration', header: 'duration' },\n];\n\n/**\n * Render `matrix.phases` as a compact summary like `\"extract=low,\n * digest=high\"`. When a phase entry has both `reasoningLevel` and `model`\n * pinned, only `reasoningLevel` is shown (model pins are usually long and\n * would blow out the table); the JSON report carries the full fidelity.\n *\n * Returns an empty string for missing / empty input so `formatTable` can\n * cheaply detect whether the column should appear at all.\n */\nexport function formatPhaseOverrides(phases: PhaseOverrideMap | undefined): string {\n if (!phases) return '';\n const entries = Object.entries(phases);\n if (entries.length === 0) return '';\n return entries\n .map(([phase, pin]) => {\n if (pin.reasoningLevel) return `${phase}=${pin.reasoningLevel}`;\n if (pin.model) return `${phase}=${pin.model}`;\n return phase;\n })\n .join(', ');\n}\n\n/**\n * Format rows into a plain-ASCII table with per-column width padding.\n * Returns the table as a string (no trailing newline).\n *\n * The \"phase overrides\" column is shown only when at least one row has a\n * non-empty `phaseOverrides` value; otherwise it's omitted entirely so\n * the common (no-phase-pins) output stays compact.\n */\nexport function formatTable(rows: TableRow[]): string {\n const includePhaseOverrides = rows.some((r) => (r.phaseOverrides ?? '').length > 0);\n const columns: Array<{ key: keyof TableRow; header: string }> = includePhaseOverrides\n ? [...TABLE_COLUMNS, { key: 'phaseOverrides', header: 'phase overrides' }]\n : TABLE_COLUMNS;\n\n // Compute column widths = max(header.length, max(cell.length)) for each col\n const widths = columns.map(({ key, header }) => {\n let max = header.length;\n for (const row of rows) {\n const cell = row[key] ?? '';\n if (cell.length > max) max = cell.length;\n }\n return max;\n });\n\n const sep = widths.map((w) => '-'.repeat(w)).join('-+-');\n const headerLine = columns.map(({ header }, i) => header.padEnd(widths[i])).join(' | ');\n\n const dataLines = rows.map((row) =>\n columns.map(({ key }, i) => (row[key] ?? '').padEnd(widths[i])).join(' | ')\n );\n\n return [headerLine, sep, ...dataLines].join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Elapsed-time formatter\n// ---------------------------------------------------------------------------\n\nfunction fmtElapsed(seconds: number): string {\n const mm = Math.floor(seconds / 60);\n const ss = String(seconds % 60).padStart(2, '0');\n return `${String(mm).padStart(2, '0')}:${ss}`;\n}\n\n// ---------------------------------------------------------------------------\n// JSON report writer\n// ---------------------------------------------------------------------------\n\nfunction writeReport(\n vaultDir: string,\n evaluationId: string,\n taskId: string,\n matrix: EvalMatrix,\n status: string,\n createdAt: number | undefined,\n completedAt: number | undefined,\n runs: RunRecord[],\n aggregate: Record<string, unknown>,\n): void {\n const reportDir = path.join(vaultDir, 'digest', 'evaluations');\n fs.mkdirSync(reportDir, { recursive: true });\n\n const reportCells = runs.map((run) => ({\n runId: run.id,\n runtime: run.runtime ?? null,\n reasoningLevel: run.reasoning_level ?? null,\n model: run.model ?? null,\n dryRun: run.dry_run === 1 || run.dry_run === true,\n status: run.status ?? null,\n turns: run.actions_taken ?? null,\n tokens: run.tokens_used ?? null,\n costUsd: run.cost_usd ?? null,\n durationMs: runDurationMs({\n started_at: run.started_at ?? null,\n completed_at: run.completed_at ?? null,\n }),\n error: run.error ?? null,\n }));\n\n const report = {\n evaluationId,\n taskId,\n matrix,\n status,\n createdAt: createdAt ?? null,\n completedAt: completedAt ?? null,\n cells: reportCells,\n aggregate,\n };\n\n const reportPath = path.join(reportDir, `${evaluationId}.json`);\n fs.writeFileSync(reportPath, JSON.stringify(report, null, 2), 'utf-8');\n console.log(`Report written to ${reportPath}`);\n}\n\n// ---------------------------------------------------------------------------\n// Main\n// ---------------------------------------------------------------------------\n\nexport async function run(args: string[], vaultDir: string): Promise<void> {\n let parsed: ParsedArgs;\n try {\n parsed = parseArgs(args);\n } catch (err) {\n console.error(`myco agent eval: ${(err as Error).message}`);\n process.stdout.write(HELP);\n process.exit(1);\n }\n\n const { taskId, matrix, notes, pollInterval, timeout, noWait } = parsed;\n\n const client = await connectToDaemon(vaultDir);\n\n // POST to create evaluation\n const createResult = await client.post('/api/agent/evaluations', {\n taskId,\n matrix,\n ...(notes ? { notes } : {}),\n });\n\n if (!createResult.ok || !createResult.data?.evaluationId) {\n console.error('Failed to create evaluation');\n if (createResult.data?.error) {\n console.error(` ${createResult.data.error}`);\n }\n process.exit(1);\n }\n\n const { evaluationId, cellCount } = createResult.data as {\n evaluationId: string;\n cellCount: number;\n };\n\n console.log(`Evaluation created: ${evaluationId}`);\n console.log(` task: ${taskId}`);\n console.log(` cells: ${cellCount}`);\n if (matrix.dryRun) console.log(' mode: dry-run');\n\n if (noWait) {\n process.exit(0);\n }\n\n // Poll until done or timeout. Per-row attribution comes from the run row\n // itself (runtime/reasoning_level/model) — no client-side zip required.\n const startTime = Date.now();\n let lastStatus = '';\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const elapsed = Math.floor((Date.now() - startTime) / 1000);\n if (elapsed >= timeout) {\n console.error(`\\nEvaluation timed out after ${timeout}s`);\n process.exit(2);\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollInterval * 1000));\n\n const getResult = await client.get(`/api/agent/evaluations/${evaluationId}`);\n if (!getResult.ok || !getResult.data) {\n console.error('Failed to poll evaluation status');\n continue;\n }\n\n const { evaluation, runs, aggregate } = getResult.data as {\n evaluation: {\n id: string;\n taskId: string;\n matrix: EvalMatrix;\n notes?: string;\n status: string;\n createdAt?: number;\n completedAt?: number;\n };\n runs: RunRecord[];\n aggregate: {\n total: number;\n completed: number;\n failed: number;\n skipped: number;\n totalTokens: number;\n totalCostUsd: number;\n };\n };\n\n const { completed, total } = aggregate;\n const elapsedStr = fmtElapsed(elapsed);\n const currentRun = runs.find((r) => r.status === 'running');\n const runningInfo = currentRun\n ? ` — running cell ${completed + 1} (${currentRun.runtime ?? 'default'}/${currentRun.reasoning_level ?? 'default'})`\n : '';\n\n const statusLine = `[${elapsedStr}] ${completed}/${total} cells complete${runningInfo}`;\n if (statusLine !== lastStatus) {\n console.log(statusLine);\n lastStatus = statusLine;\n }\n\n const done = evaluation.status === 'completed' || evaluation.status === 'failed';\n if (done) {\n console.log(`\\nEvaluation ${evaluation.status}: ${evaluationId}`);\n\n // Build comparison table from the run rows themselves — each row\n // carries runtime / reasoning_level / model / dry_run populated by\n // the executor, so no zip against enumerated matrix cells is needed.\n const phaseOverridesStr = formatPhaseOverrides(evaluation.matrix.phases);\n const tableRows: TableRow[] = runs.map((run) => {\n const durationMs = runDurationMs({\n started_at: run.started_at ?? null,\n completed_at: run.completed_at ?? null,\n });\n const durationStr = durationMs !== null ? `${(durationMs / 1000).toFixed(1)}s` : '-';\n const costStr = run.cost_usd !== null && run.cost_usd !== undefined\n ? `$${run.cost_usd.toFixed(4)}`\n : '-';\n return {\n runtime: run.runtime ?? '(default)',\n reasoning: run.reasoning_level ?? '(task default)',\n model: run.model ?? '(default)',\n dryRun: (run.dry_run === 1 || run.dry_run === true) ? 'yes' : 'no',\n status: run.status ?? 'unknown',\n turns: String(run.actions_taken ?? '-'),\n tokens: String(run.tokens_used ?? '-'),\n cost: costStr,\n duration: durationStr,\n ...(phaseOverridesStr ? { phaseOverrides: phaseOverridesStr } : {}),\n };\n });\n\n if (tableRows.length > 0) {\n console.log('\\n' + formatTable(tableRows));\n }\n\n // Summary line\n console.log(\n `\\nAggregate: ${aggregate.completed} completed, ${aggregate.failed} failed, ${aggregate.skipped} skipped` +\n ` | tokens: ${aggregate.totalTokens} | cost: $${aggregate.totalCostUsd.toFixed(4)}`\n );\n\n // Write JSON report\n writeReport(\n vaultDir,\n evaluationId,\n evaluation.taskId,\n evaluation.matrix,\n evaluation.status,\n evaluation.createdAt,\n evaluation.completedAt,\n runs,\n aggregate as Record<string, unknown>,\n );\n\n process.exit(evaluation.status === 'completed' ? 0 : 1);\n }\n }\n}\n"],"mappings":"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","names":["run"]}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
connectToDaemon
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-W5L5IHP5.js";
|
|
5
5
|
import "./chunk-SAKJMNSR.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-OTQH5KZW.js";
|
|
7
7
|
import "./chunk-X3IGT5RV.js";
|
|
8
8
|
import "./chunk-53RPGOEN.js";
|
|
9
9
|
import "./chunk-OUJSQSKE.js";
|
|
10
10
|
import "./chunk-POEPHBQK.js";
|
|
11
11
|
import "./chunk-MYX5NCRH.js";
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-6FBLL7MD.js";
|
|
13
|
+
import "./chunk-Z55WGA2J.js";
|
|
14
14
|
import "./chunk-LPUQPDC2.js";
|
|
15
15
|
import "./chunk-6C6QZ4PM.js";
|
|
16
16
|
import "./chunk-UUHLLQXO.js";
|
|
@@ -38,4 +38,4 @@ async function run(args, vaultDir) {
|
|
|
38
38
|
export {
|
|
39
39
|
run
|
|
40
40
|
};
|
|
41
|
-
//# sourceMappingURL=agent-run-
|
|
41
|
+
//# sourceMappingURL=agent-run-XJBTSVJR.js.map
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
connectToDaemon
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-W5L5IHP5.js";
|
|
5
5
|
import "./chunk-SAKJMNSR.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-OTQH5KZW.js";
|
|
7
7
|
import "./chunk-X3IGT5RV.js";
|
|
8
8
|
import "./chunk-53RPGOEN.js";
|
|
9
9
|
import "./chunk-OUJSQSKE.js";
|
|
10
10
|
import "./chunk-POEPHBQK.js";
|
|
11
11
|
import "./chunk-MYX5NCRH.js";
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-6FBLL7MD.js";
|
|
13
|
+
import "./chunk-Z55WGA2J.js";
|
|
14
14
|
import "./chunk-LPUQPDC2.js";
|
|
15
15
|
import "./chunk-6C6QZ4PM.js";
|
|
16
16
|
import "./chunk-UUHLLQXO.js";
|
|
@@ -184,4 +184,4 @@ async function run(args, vaultDir) {
|
|
|
184
184
|
export {
|
|
185
185
|
run
|
|
186
186
|
};
|
|
187
|
-
//# sourceMappingURL=agent-tasks-
|
|
187
|
+
//# sourceMappingURL=agent-tasks-7MWBZOC7.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
isProcessAlive
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-W5L5IHP5.js";
|
|
5
5
|
import {
|
|
6
6
|
loadMergedConfig
|
|
7
7
|
} from "./chunk-53RPGOEN.js";
|
|
@@ -187,4 +187,4 @@ export {
|
|
|
187
187
|
getEmbeddingQueueDepth,
|
|
188
188
|
gatherStats
|
|
189
189
|
};
|
|
190
|
-
//# sourceMappingURL=chunk-
|
|
190
|
+
//# sourceMappingURL=chunk-4D22KTXY.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
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-Z55WGA2J.js";
|
|
5
5
|
import {
|
|
6
6
|
DAEMON_CLIENT_TIMEOUT_MS,
|
|
7
7
|
DAEMON_HEALTH_CHECK_TIMEOUT_MS,
|
|
@@ -23,6 +23,11 @@ async function parseErrorBody(res) {
|
|
|
23
23
|
return void 0;
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
+
function isIgnoredEventResponse(data) {
|
|
27
|
+
if (typeof data !== "object" || data === null) return false;
|
|
28
|
+
const ignored = data.ignored;
|
|
29
|
+
return typeof ignored === "string" && ignored.length > 0;
|
|
30
|
+
}
|
|
26
31
|
var DaemonClient = class {
|
|
27
32
|
vaultDir;
|
|
28
33
|
constructor(vaultDir) {
|
|
@@ -195,6 +200,7 @@ var DaemonClient = class {
|
|
|
195
200
|
|
|
196
201
|
export {
|
|
197
202
|
resolveCliEntryPath,
|
|
203
|
+
isIgnoredEventResponse,
|
|
198
204
|
DaemonClient
|
|
199
205
|
};
|
|
200
|
-
//# sourceMappingURL=chunk-
|
|
206
|
+
//# sourceMappingURL=chunk-6FBLL7MD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/client.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { spawn } from 'node:child_process';\nimport { DAEMON_CLIENT_TIMEOUT_MS, DAEMON_HEALTH_CHECK_TIMEOUT_MS, DAEMON_HEALTH_RETRY_DELAYS, DAEMON_STALE_GRACE_PERIOD_MS } from '../constants.js';\nimport { getPluginVersion } from '../version.js';\n\ninterface DaemonInfo {\n pid: number;\n port: number;\n}\n\n/**\n * Resolve the CLI entry point for spawning daemon processes.\n * Uses process.argv[1] so the daemon restarts from the same binary\n * (myco-dev vs global myco) that launched the current process.\n */\nexport function resolveCliEntryPath(): { execPath: string; cliEntry: string } {\n return { execPath: process.execPath, cliEntry: process.argv[1] };\n}\n\ninterface HealthResponse {\n myco: boolean;\n version?: string;\n}\n\ninterface ClientResult {\n ok: boolean;\n data?: any;\n}\n\n/**\n * Attempt to parse a non-ok response body as JSON so callers can surface\n * the daemon's structured error envelope (e.g. `{error: {code, message}}`).\n * Returns `undefined` if the body is empty, not JSON, or otherwise fails to\n * parse — callers that ignore `data` on failure still work unchanged.\n */\nasync function parseErrorBody(res: Response): Promise<unknown> {\n try {\n return await res.json();\n } catch {\n return undefined;\n }\n}\n\n/**\n * True when the daemon returned 200 but its body carries `{ ignored: reason }`.\n *\n * Callers that write to the event buffer on failure also buffer on this\n * signal — otherwise a capture-rule drop discards events silently even though\n * the HTTP call \"succeeded\". reconcileBufferBatches replays on next startup.\n */\nexport function isIgnoredEventResponse(data: unknown): boolean {\n if (typeof data !== 'object' || data === null) return false;\n const ignored = (data as Record<string, unknown>).ignored;\n return typeof ignored === 'string' && ignored.length > 0;\n}\n\nexport class DaemonClient {\n private vaultDir: string;\n\n constructor(vaultDir: string) {\n this.vaultDir = vaultDir;\n }\n\n async post(endpoint: string, body: unknown): Promise<ClientResult> {\n try {\n const info = this.readDaemonJson();\n if (!info) return { ok: false };\n\n const res = await fetch(`http://127.0.0.1:${info.port}${endpoint}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(DAEMON_CLIENT_TIMEOUT_MS),\n });\n\n if (!res.ok) return { ok: false, data: await parseErrorBody(res) };\n const data = await res.json();\n return { ok: true, data };\n } catch {\n return { ok: false };\n }\n }\n\n async put(endpoint: string, body: unknown): Promise<ClientResult> {\n try {\n const info = this.readDaemonJson();\n if (!info) return { ok: false };\n\n const res = await fetch(`http://127.0.0.1:${info.port}${endpoint}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(DAEMON_CLIENT_TIMEOUT_MS),\n });\n\n if (!res.ok) return { ok: false, data: await parseErrorBody(res) };\n const data = await res.json();\n return { ok: true, data };\n } catch {\n return { ok: false };\n }\n }\n\n async get(endpoint: string): Promise<ClientResult> {\n try {\n const info = this.readDaemonJson();\n if (!info) return { ok: false };\n\n const res = await fetch(`http://127.0.0.1:${info.port}${endpoint}`, {\n signal: AbortSignal.timeout(DAEMON_CLIENT_TIMEOUT_MS),\n });\n\n if (!res.ok) return { ok: false, data: await parseErrorBody(res) };\n const data = await res.json();\n return { ok: true, data };\n } catch {\n return { ok: false };\n }\n }\n\n async delete(endpoint: string, body?: unknown): Promise<ClientResult> {\n try {\n const info = this.readDaemonJson();\n if (!info) return { ok: false };\n\n const init: RequestInit = {\n method: 'DELETE',\n signal: AbortSignal.timeout(DAEMON_CLIENT_TIMEOUT_MS),\n };\n if (body !== undefined) {\n init.headers = { 'Content-Type': 'application/json' };\n init.body = JSON.stringify(body);\n }\n\n const res = await fetch(`http://127.0.0.1:${info.port}${endpoint}`, init);\n\n if (!res.ok) return { ok: false, data: await parseErrorBody(res) };\n const data = await res.json();\n return { ok: true, data };\n } catch {\n return { ok: false };\n }\n }\n\n async isHealthy(cachedInfo?: DaemonInfo | null): Promise<boolean> {\n try {\n const info = cachedInfo ?? this.readDaemonJson();\n if (!info) return false;\n\n const res = await fetch(`http://127.0.0.1:${info.port}/health`, {\n signal: AbortSignal.timeout(DAEMON_HEALTH_CHECK_TIMEOUT_MS),\n });\n if (!res.ok) return false;\n const data = await res.json() as HealthResponse;\n return data.myco === true;\n } catch {\n return false;\n }\n }\n\n /**\n * Check if the daemon is running a stale version.\n * Returns true if the daemon's version doesn't match the current plugin version.\n * Skips the check if daemon.json was written recently (grace period) to prevent\n * rapid restart loops from concurrent hooks or session reloads.\n */\n private async isStale(info: DaemonInfo): Promise<boolean> {\n try {\n const jsonPath = path.join(this.vaultDir, 'daemon.json');\n const stat = fs.statSync(jsonPath);\n if (Date.now() - stat.mtimeMs < DAEMON_STALE_GRACE_PERIOD_MS) {\n return false;\n }\n\n const res = await fetch(`http://127.0.0.1:${info.port}/health`, {\n signal: AbortSignal.timeout(DAEMON_HEALTH_CHECK_TIMEOUT_MS),\n });\n if (!res.ok) return false;\n const data = await res.json() as HealthResponse;\n if (!data.myco) return false;\n\n // No version in response = old daemon that predates this check\n if (!data.version) return true;\n\n return data.version !== getPluginVersion();\n } catch {\n return false;\n }\n }\n\n /**\n * Kill the running daemon process.\n */\n private killDaemon(info: DaemonInfo | null): void {\n try {\n if (!info) return;\n process.kill(info.pid, 'SIGTERM');\n } catch { /* already dead */ }\n try {\n fs.unlinkSync(path.join(this.vaultDir, 'daemon.json'));\n } catch { /* already gone */ }\n }\n\n /**\n * Ensure the daemon is running. Spawns it if unhealthy.\n * When checkStale is true (default), also restarts a healthy daemon if its\n * version doesn't match the current plugin version. Use checkStale: false\n * for hooks that just need the daemon alive (e.g., stop) without triggering\n * version-driven restarts.\n */\n async ensureRunning(opts?: { checkStale?: boolean }): Promise<boolean> {\n const checkStale = opts?.checkStale ?? true;\n const info = this.readDaemonJson();\n\n if (checkStale && info && await this.isStale(info)) {\n this.killDaemon(info);\n // Brief pause for port release\n await new Promise((r) => setTimeout(r, 200));\n } else if (await this.isHealthy(info)) {\n return true;\n }\n\n this.spawnDaemon();\n\n for (const delay of DAEMON_HEALTH_RETRY_DELAYS) {\n await new Promise((r) => setTimeout(r, delay));\n if (await this.isHealthy()) return true;\n }\n return false;\n }\n\n spawnDaemon(): void {\n const { execPath, cliEntry } = resolveCliEntryPath();\n const child = spawn(execPath, [cliEntry, 'daemon', '--vault', this.vaultDir], {\n detached: true,\n stdio: 'ignore',\n });\n child.unref();\n }\n\n private readDaemonJson(): DaemonInfo | null {\n try {\n const jsonPath = path.join(this.vaultDir, 'daemon.json');\n const content = fs.readFileSync(jsonPath, 'utf-8');\n const info = JSON.parse(content);\n if (typeof info.port !== 'number') return null;\n return info as DaemonInfo;\n } catch {\n return null;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
errorMessage
|
|
4
|
+
} from "./chunk-LQIPXVDH.js";
|
|
2
5
|
import {
|
|
3
6
|
AgentDefinitionSchema,
|
|
4
7
|
AgentTaskSchema
|
|
@@ -305,7 +308,11 @@ function resolveEffectiveConfig(definition, agentOverrides, taskOverrides) {
|
|
|
305
308
|
try {
|
|
306
309
|
const parsed = JSON.parse(agentOverrides.tool_access);
|
|
307
310
|
if (Array.isArray(parsed)) tools = parsed;
|
|
308
|
-
} catch {
|
|
311
|
+
} catch (err) {
|
|
312
|
+
const detail = errorMessage(err);
|
|
313
|
+
console.warn(
|
|
314
|
+
`[agent] Ignoring malformed tool_access JSON for agent "${agentId}": ${detail}`
|
|
315
|
+
);
|
|
309
316
|
}
|
|
310
317
|
}
|
|
311
318
|
}
|
|
@@ -388,7 +395,7 @@ async function registerBuiltInAgentsAndTasks(definitionsDir, vaultDir) {
|
|
|
388
395
|
).run(BUILT_IN_SOURCE, definition.name, ...validTaskIds);
|
|
389
396
|
}
|
|
390
397
|
if (vaultDir) {
|
|
391
|
-
const { loadAllTasks } = await import("./registry-
|
|
398
|
+
const { loadAllTasks } = await import("./registry-F3THYC5M.js");
|
|
392
399
|
const allTasks = loadAllTasks(definitionsDir, vaultDir);
|
|
393
400
|
for (const [name, task] of allTasks) {
|
|
394
401
|
if (task.source === USER_TASK_SOURCE) {
|
|
@@ -428,4 +435,4 @@ export {
|
|
|
428
435
|
resolveEffectiveConfig,
|
|
429
436
|
registerBuiltInAgentsAndTasks
|
|
430
437
|
};
|
|
431
|
-
//# sourceMappingURL=chunk-
|
|
438
|
+
//# sourceMappingURL=chunk-AUIXX33A.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agent/loader.ts","../src/db/queries/agents.ts","../src/db/queries/tasks.ts"],"sourcesContent":["/**\n * Agent definition and task YAML loader.\n *\n * Reads agent.yaml and tasks/*.yaml from the definitions directory,\n * validates their shape, and provides helpers for merging built-in\n * definitions with database overrides into an EffectiveConfig.\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 { errorMessage } from '@myco/utils/error-message.js';\nimport { parse as parseYaml } from 'yaml';\nimport { epochSeconds, DEFAULT_AGENT_ID, BUILT_IN_SOURCE, USER_TASK_SOURCE } from '@myco/constants.js';\nimport { getDatabase } from '@myco/db/client.js';\nimport { registerAgent } from '@myco/db/queries/agents.js';\nimport { upsertTask } from '@myco/db/queries/tasks.js';\nimport type { AgentRow } from '@myco/db/queries/agents.js';\nimport type { AgentDefinition, AgentTask, EffectiveConfig } from './types.js';\nimport { AgentDefinitionSchema, AgentTaskSchema } from './schemas.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Filename for the built-in agent definition. */\nconst AGENT_DEFINITION_FILE = 'agent.yaml';\n\n/** Subdirectory containing task YAML files. */\nconst TASKS_SUBDIRECTORY = 'tasks';\n\n// Package root resolution uses shared findPackageRoot from @myco/utils\n\n// BUILT_IN_SOURCE imported from @myco/constants.js\n\n// ---------------------------------------------------------------------------\n// Definitions directory resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the definitions directory at runtime.\n *\n * Strategy (same pattern as `src/prompts/index.ts`):\n * 1. Walk up from `import.meta.url` looking for `package.json`.\n * 2. From package root, try `dist/src/agent/definitions/` (tsup output).\n * 3. Fall back to `src/agent/definitions/` (dev mode / tsc output).\n * 4. Also check if the current file's directory already contains agent.yaml.\n */\nexport function resolveDefinitionsDir(): string {\n const scriptDir = path.dirname(fileURLToPath(import.meta.url));\n\n // Check if we're already adjacent to the definitions (tsc output or dev mode)\n const adjacentDefs = path.join(scriptDir, 'definitions');\n if (fs.existsSync(path.join(adjacentDefs, AGENT_DEFINITION_FILE))) {\n return adjacentDefs;\n }\n\n // Walk up to package root using shared utility\n const root = findPackageRoot(scriptDir);\n if (root) {\n // Try dist path first (tsup bundled output)\n const distPath = path.join(root, 'dist', 'src', 'agent', 'definitions');\n if (fs.existsSync(path.join(distPath, AGENT_DEFINITION_FILE))) {\n return distPath;\n }\n // Fall back to src path (dev mode)\n const srcPath = path.join(root, 'src', 'agent', 'definitions');\n if (fs.existsSync(path.join(srcPath, AGENT_DEFINITION_FILE))) {\n return srcPath;\n }\n }\n\n // Final fallback: adjacent to current file\n return adjacentDefs;\n}\n\n// ---------------------------------------------------------------------------\n// YAML loaders\n// ---------------------------------------------------------------------------\n\n/**\n * Load and parse the built-in agent definition from `agent.yaml`.\n *\n * @param definitionsDir — path to the definitions directory.\n * @returns the parsed AgentDefinition.\n * @throws if the file is missing or malformed.\n */\nexport function loadAgentDefinition(definitionsDir: string): AgentDefinition {\n const filePath = path.join(definitionsDir, AGENT_DEFINITION_FILE);\n const raw = fs.readFileSync(filePath, 'utf-8');\n const parsed = AgentDefinitionSchema.parse(parseYaml(raw));\n\n return {\n name: parsed.name,\n displayName: parsed.displayName,\n description: parsed.description.trim(),\n model: parsed.model,\n maxTurns: parsed.maxTurns,\n timeoutSeconds: parsed.timeoutSeconds,\n systemPromptPath: parsed.systemPromptPath,\n tools: parsed.tools,\n };\n}\n\n/**\n * Load and parse all task YAML files from `tasks/`.\n *\n * @param definitionsDir — path to the definitions directory.\n * @returns array of parsed AgentTask objects.\n */\nexport function loadAgentTasks(definitionsDir: string): AgentTask[] {\n const tasksDir = path.join(definitionsDir, TASKS_SUBDIRECTORY);\n if (!fs.existsSync(tasksDir)) return [];\n\n const files = fs.readdirSync(tasksDir).filter((f) => f.endsWith('.yaml'));\n return files.map((file) => {\n const raw = fs.readFileSync(path.join(tasksDir, file), 'utf-8');\n const parsed = AgentTaskSchema.parse(parseYaml(raw));\n\n return taskFromParsed(parsed);\n });\n}\n\n/**\n * Convert a Zod-parsed task schema result to an AgentTask object.\n *\n * Shared by loadAgentTasks (built-in) and registry (user tasks) to ensure\n * all optional fields are consistently spread. Adding a new optional field\n * to AgentTaskSchema only requires updating this one function.\n */\nexport function taskFromParsed(parsed: AgentTask): AgentTask {\n return {\n name: parsed.name,\n displayName: parsed.displayName,\n description: parsed.description.trim(),\n agent: parsed.agent,\n prompt: parsed.prompt.trim(),\n isDefault: parsed.isDefault,\n ...(parsed.toolOverrides ? { toolOverrides: parsed.toolOverrides } : {}),\n ...(parsed.model ? { model: parsed.model } : {}),\n ...(parsed.reasoningLevel ? { reasoningLevel: parsed.reasoningLevel } : {}),\n ...(parsed.maxTurns ? { maxTurns: parsed.maxTurns } : {}),\n ...(parsed.timeoutSeconds ? { timeoutSeconds: parsed.timeoutSeconds } : {}),\n ...(parsed.phases ? { phases: parsed.phases } : {}),\n ...(parsed.orchestrator ? { orchestrator: parsed.orchestrator } : {}),\n ...(parsed.contextQueries ? { contextQueries: parsed.contextQueries } : {}),\n ...(parsed.execution ? { execution: parsed.execution } : {}),\n ...(parsed.schemaVersion ? { schemaVersion: parsed.schemaVersion } : {}),\n ...(parsed.schedule ? { schedule: parsed.schedule } : {}),\n ...(parsed.params ? { params: parsed.params } : {}),\n };\n}\n\n/**\n * Load a system prompt markdown file.\n *\n * @param definitionsDir — path to the definitions directory.\n * @param relativePath — path relative to definitionsDir (from AgentDefinition.systemPromptPath).\n * @returns the prompt file content as a string.\n */\nexport function loadSystemPrompt(definitionsDir: string, relativePath: string): string {\n const filePath = path.resolve(definitionsDir, relativePath);\n return fs.readFileSync(filePath, 'utf-8').trim();\n}\n\n// ---------------------------------------------------------------------------\n// Config resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Merge a built-in AgentDefinition with optional database overrides and\n * task-specific configuration to produce the effective runtime config.\n *\n * Priority (highest wins):\n * 1. Task toolOverrides (replaces tool list entirely if present)\n * 2. AgentRow database overrides (model, maxTurns, timeoutSeconds, tool_access)\n * 3. Built-in AgentDefinition defaults\n *\n * @param definition — the built-in agent definition from YAML.\n * @param agentOverrides — optional database row with user-applied overrides.\n * @param taskOverrides — optional task definition (determines prompt and may override tools).\n * @returns the merged EffectiveConfig.\n */\nexport function resolveEffectiveConfig(\n definition: AgentDefinition,\n agentOverrides?: AgentRow | null,\n taskOverrides?: AgentTask,\n): EffectiveConfig {\n let runtime = taskOverrides?.execution?.runtime ?? taskOverrides?.execution?.provider?.runtime ?? 'claude-sdk';\n // Start with definition defaults\n let model = definition.model;\n let reasoningLevel = taskOverrides?.reasoningLevel;\n let maxTurns = definition.maxTurns;\n let timeoutSeconds = definition.timeoutSeconds;\n let tools = [...definition.tools];\n const agentId = agentOverrides?.id ?? DEFAULT_AGENT_ID;\n\n // Apply agent DB overrides\n if (agentOverrides) {\n if (agentOverrides.model) model = agentOverrides.model;\n if (agentOverrides.max_turns !== null) maxTurns = agentOverrides.max_turns;\n if (agentOverrides.timeout_seconds !== null) timeoutSeconds = agentOverrides.timeout_seconds;\n if (agentOverrides.tool_access) {\n try {\n const parsed = JSON.parse(agentOverrides.tool_access);\n if (Array.isArray(parsed)) tools = parsed as string[];\n } catch (err) {\n // Keep definition defaults but surface the error so operators can\n // tell why their per-agent tool override isn't taking effect.\n const detail = errorMessage(err);\n console.warn(\n `[agent] Ignoring malformed tool_access JSON for agent \"${agentId}\": ${detail}`,\n );\n }\n }\n }\n\n // Apply task overrides (model, turns, timeout, tool list)\n if (taskOverrides?.model) model = taskOverrides.model;\n if (taskOverrides?.reasoningLevel) reasoningLevel = taskOverrides.reasoningLevel;\n if (taskOverrides?.maxTurns) maxTurns = taskOverrides.maxTurns;\n if (taskOverrides?.timeoutSeconds) timeoutSeconds = taskOverrides.timeoutSeconds;\n if (taskOverrides?.toolOverrides) {\n tools = [...taskOverrides.toolOverrides];\n }\n\n // Apply execution config overrides (highest priority)\n // Precedence: execution.model > task.model > agent.model\n if (taskOverrides?.execution) {\n if (taskOverrides.execution.model) model = taskOverrides.execution.model;\n if (taskOverrides.execution.reasoningLevel) reasoningLevel = taskOverrides.execution.reasoningLevel;\n if (taskOverrides.execution.maxTurns) maxTurns = taskOverrides.execution.maxTurns;\n if (taskOverrides.execution.timeoutSeconds) timeoutSeconds = taskOverrides.execution.timeoutSeconds;\n }\n\n // Task prompt and display info (fall back to a generic prompt)\n const taskName = taskOverrides?.name ?? 'vault-evolve';\n const taskDisplayName = taskOverrides?.displayName ?? 'Vault Evolve';\n const taskPrompt = taskOverrides?.prompt ?? '';\n\n return {\n agentId,\n runtime,\n model,\n ...(reasoningLevel ? { reasoningLevel } : {}),\n maxTurns,\n timeoutSeconds,\n systemPromptPath: definition.systemPromptPath,\n tools,\n taskName,\n taskDisplayName,\n taskPrompt,\n ...(taskOverrides?.phases ? { phases: taskOverrides.phases } : {}),\n ...(taskOverrides?.orchestrator ? { orchestrator: taskOverrides.orchestrator } : {}),\n ...(taskOverrides?.contextQueries ? { contextQueries: taskOverrides.contextQueries } : {}),\n ...(taskOverrides?.execution ? { execution: taskOverrides.execution } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Database registration\n// ---------------------------------------------------------------------------\n\n/**\n * Register the built-in agent and all built-in tasks into the database.\n *\n * Idempotent: uses upsert (ON CONFLICT DO UPDATE) for both agent and tasks.\n * Safe to call on every daemon startup.\n *\n * @param definitionsDir — path to the definitions directory.\n */\nexport async function registerBuiltInAgentsAndTasks(definitionsDir: string, vaultDir?: string): Promise<void> {\n const definition = loadAgentDefinition(definitionsDir);\n const tasks = loadAgentTasks(definitionsDir);\n const now = epochSeconds();\n\n // Upsert the built-in agent\n registerAgent({\n id: definition.name,\n name: definition.displayName,\n model: definition.model,\n source: BUILT_IN_SOURCE,\n max_turns: definition.maxTurns,\n timeout_seconds: definition.timeoutSeconds,\n tool_access: JSON.stringify(definition.tools),\n created_at: now,\n updated_at: now,\n });\n\n // Upsert all built-in tasks\n for (const task of tasks) {\n upsertTask({\n id: task.name,\n agent_id: definition.name,\n source: BUILT_IN_SOURCE,\n display_name: task.displayName,\n description: task.description,\n prompt: task.prompt,\n is_default: task.isDefault ? 1 : 0,\n tool_overrides: task.toolOverrides ? JSON.stringify(task.toolOverrides) : null,\n config: JSON.stringify({\n phases: task.phases ?? null,\n execution: task.execution ?? null,\n contextQueries: task.contextQueries ?? null,\n schemaVersion: task.schemaVersion ?? 1,\n }),\n created_at: now,\n updated_at: now,\n });\n }\n\n // Remove built-in tasks that no longer have YAML definitions\n const validTaskIds = tasks.map(t => t.name);\n if (validTaskIds.length > 0) {\n const db = getDatabase();\n const placeholders = validTaskIds.map(() => '?').join(', ');\n db.prepare(\n `DELETE FROM agent_tasks\n WHERE source = ? AND agent_id = ? AND id NOT IN (${placeholders})`,\n ).run(BUILT_IN_SOURCE, definition.name, ...validTaskIds);\n }\n\n // Register user tasks from the vault (if vault dir provided)\n if (vaultDir) {\n const { loadAllTasks } = await import('./registry.js');\n const allTasks = loadAllTasks(definitionsDir, vaultDir);\n for (const [name, task] of allTasks) {\n if (task.source === USER_TASK_SOURCE) {\n upsertTask({\n id: name,\n agent_id: task.agent ?? definition.name,\n source: USER_TASK_SOURCE,\n display_name: task.displayName,\n description: task.description,\n prompt: task.prompt,\n is_default: task.isDefault ? 1 : 0,\n tool_overrides: task.toolOverrides ? JSON.stringify(task.toolOverrides) : null,\n config: JSON.stringify({\n phases: task.phases ?? null,\n execution: task.execution ?? null,\n contextQueries: task.contextQueries ?? null,\n schemaVersion: task.schemaVersion ?? 1,\n }),\n created_at: now,\n updated_at: now,\n });\n }\n }\n }\n}\n","/**\n * Agent CRUD 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/** Fields required (or optional) when registering an agent. */\nexport interface AgentInsert {\n id: string;\n name: string;\n created_at: number;\n provider?: string | null;\n model?: string | null;\n system_prompt_hash?: string | null;\n config?: string | null;\n source?: string;\n system_prompt?: string | null;\n max_turns?: number | null;\n timeout_seconds?: number | null;\n tool_access?: string | null;\n enabled?: number;\n updated_at?: number | null;\n}\n\n/** Row shape returned from agent queries (all columns). */\nexport interface AgentRow {\n id: string;\n name: string;\n provider: string | null;\n model: string | null;\n system_prompt_hash: string | null;\n config: string | null;\n source: string;\n system_prompt: string | null;\n max_turns: number | null;\n timeout_seconds: number | null;\n tool_access: string | null;\n enabled: number;\n created_at: number;\n updated_at: number | null;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Default agent source for new agents. */\nconst DEFAULT_SOURCE = 'built-in';\n\n/** Default enabled flag for new agents. */\nconst DEFAULT_ENABLED = 1;\n\n// ---------------------------------------------------------------------------\n// Column list\n// ---------------------------------------------------------------------------\n\nconst AGENT_COLUMNS = [\n 'id',\n 'name',\n 'provider',\n 'model',\n 'system_prompt_hash',\n 'config',\n 'source',\n 'system_prompt',\n 'max_turns',\n 'timeout_seconds',\n 'tool_access',\n 'enabled',\n 'created_at',\n 'updated_at',\n] as const;\n\nconst SELECT_COLUMNS = AGENT_COLUMNS.join(', ');\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Normalize a SQLite result row into a typed AgentRow. */\nfunction toAgentRow(row: Record<string, unknown>): AgentRow {\n return {\n id: row.id as string,\n name: row.name as string,\n provider: (row.provider as string) ?? null,\n model: (row.model as string) ?? null,\n system_prompt_hash: (row.system_prompt_hash as string) ?? null,\n config: (row.config as string) ?? null,\n source: (row.source as string) ?? DEFAULT_SOURCE,\n system_prompt: (row.system_prompt as string) ?? null,\n max_turns: (row.max_turns as number) ?? null,\n timeout_seconds: (row.timeout_seconds as number) ?? null,\n tool_access: (row.tool_access as string) ?? null,\n enabled: (row.enabled as number) ?? DEFAULT_ENABLED,\n created_at: row.created_at as number,\n updated_at: (row.updated_at as number) ?? null,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Register an agent or update it if the id already exists.\n *\n * On conflict the row is updated with the values from `data`.\n * This is the idempotent upsert — calling twice with the same data\n * produces the same result.\n */\nexport function registerAgent(data: AgentInsert): AgentRow {\n const db = getDatabase();\n\n db.prepare(\n `INSERT INTO agents (\n id, name, provider, model, system_prompt_hash, config,\n source, system_prompt, max_turns, timeout_seconds, tool_access,\n enabled, created_at, updated_at\n ) VALUES (\n ?, ?, ?, ?, ?, ?,\n ?, ?, ?, ?, ?,\n ?, ?, ?\n )\n ON CONFLICT (id) DO UPDATE SET\n name = EXCLUDED.name,\n provider = EXCLUDED.provider,\n model = EXCLUDED.model,\n system_prompt_hash = EXCLUDED.system_prompt_hash,\n config = EXCLUDED.config,\n source = EXCLUDED.source,\n system_prompt = EXCLUDED.system_prompt,\n max_turns = EXCLUDED.max_turns,\n timeout_seconds = EXCLUDED.timeout_seconds,\n tool_access = EXCLUDED.tool_access,\n enabled = EXCLUDED.enabled,\n updated_at = EXCLUDED.updated_at`,\n ).run(\n data.id,\n data.name,\n data.provider ?? null,\n data.model ?? null,\n data.system_prompt_hash ?? null,\n data.config ?? null,\n data.source ?? DEFAULT_SOURCE,\n data.system_prompt ?? null,\n data.max_turns ?? null,\n data.timeout_seconds ?? null,\n data.tool_access ?? null,\n data.enabled ?? DEFAULT_ENABLED,\n data.created_at,\n data.updated_at ?? null,\n );\n\n return toAgentRow(\n db.prepare(`SELECT ${SELECT_COLUMNS} FROM agents WHERE id = ?`).get(data.id) as Record<string, unknown>,\n );\n}\n\n/**\n * Retrieve a single agent by id.\n *\n * @returns the agent row, or null if not found.\n */\nexport function getAgent(id: string): AgentRow | null {\n const db = getDatabase();\n\n const row = db.prepare(\n `SELECT ${SELECT_COLUMNS} FROM agents WHERE id = ?`,\n ).get(id) as Record<string, unknown> | undefined;\n\n if (!row) return null;\n return toAgentRow(row);\n}\n\n/**\n * List all agents, ordered by created_at ASC.\n */\nexport function listAgents(): AgentRow[] {\n const db = getDatabase();\n\n const rows = db.prepare(\n `SELECT ${SELECT_COLUMNS}\n FROM agents\n ORDER BY created_at ASC`,\n ).all() as Record<string, unknown>[];\n\n return rows.map(toAgentRow);\n}\n","/**\n * Agent task CRUD 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';\nimport { BUILT_IN_SOURCE } from '@myco/constants.js';\nimport type { TaskConfig } from '@myco/agent/types.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Default number of tasks returned by listTasks when no limit given. */\nconst DEFAULT_LIST_LIMIT = 100;\n\n/** Default task source for new tasks. */\nconst DEFAULT_SOURCE = BUILT_IN_SOURCE;\n\n/** Default is_default flag for new tasks. */\nconst DEFAULT_IS_DEFAULT = 0;\n\n/** Value indicating a task is the default for its agent. */\nconst IS_DEFAULT_TRUE = 1;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Fields required (or optional) when upserting a task. */\nexport interface TaskInsert {\n id: string;\n agent_id: string;\n prompt: string;\n created_at: number;\n source?: string;\n display_name?: string | null;\n description?: string | null;\n is_default?: number;\n tool_overrides?: string | null;\n model?: string | null;\n config?: string | null;\n updated_at?: number | null;\n}\n\n/** Row shape returned from agent_tasks queries (all columns). */\nexport interface TaskRow {\n id: string;\n agent_id: string;\n source: string;\n display_name: string | null;\n description: string | null;\n prompt: string;\n is_default: number;\n tool_overrides: string | null;\n model: string | null;\n config: string | null;\n created_at: number;\n updated_at: number | null;\n}\n\n/** Filter options for `listTasks`. */\nexport interface ListTasksOptions {\n limit?: number;\n agent_id?: string;\n source?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Column list\n// ---------------------------------------------------------------------------\n\nconst TASK_COLUMNS = [\n 'id',\n 'agent_id',\n 'source',\n 'display_name',\n 'description',\n 'prompt',\n 'is_default',\n 'tool_overrides',\n 'model',\n 'config',\n 'created_at',\n 'updated_at',\n] as const;\n\nconst SELECT_COLUMNS = TASK_COLUMNS.join(', ');\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Normalize a SQLite result row into a typed TaskRow. */\nfunction toTaskRow(row: Record<string, unknown>): TaskRow {\n return {\n id: row.id as string,\n agent_id: row.agent_id as string,\n source: (row.source as string) ?? DEFAULT_SOURCE,\n display_name: (row.display_name as string) ?? null,\n description: (row.description as string) ?? null,\n prompt: row.prompt as string,\n is_default: (row.is_default as number) ?? DEFAULT_IS_DEFAULT,\n tool_overrides: (row.tool_overrides as string) ?? null,\n model: (row.model as string) ?? null,\n config: (row.config as string) ?? null,\n created_at: row.created_at as number,\n updated_at: (row.updated_at as number) ?? null,\n };\n}\n\n/** Serialize a TaskConfig to a JSON string for storage. */\nexport function serializeConfig(config: TaskConfig | null): string | null {\n if (!config) return null;\n return JSON.stringify(config);\n}\n\n/** Deserialize a TaskConfig from a stored JSON string. Returns null on failure. */\nexport function deserializeConfig(raw: string | null): TaskConfig | null {\n if (!raw) return null;\n try {\n return JSON.parse(raw) as TaskConfig;\n } catch {\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Upsert a task — insert or update on conflict.\n *\n * On conflict the row is updated with the values from `data`.\n * This is the idempotent upsert — calling twice with the same data\n * produces the same result.\n */\nexport function upsertTask(data: TaskInsert): TaskRow {\n const db = getDatabase();\n\n db.prepare(\n `INSERT INTO agent_tasks (\n id, agent_id, source, display_name, description,\n prompt, is_default, tool_overrides, model, config,\n created_at, updated_at\n ) VALUES (\n ?, ?, ?, ?, ?,\n ?, ?, ?, ?, ?,\n ?, ?\n )\n ON CONFLICT (id) DO UPDATE SET\n agent_id = EXCLUDED.agent_id,\n source = EXCLUDED.source,\n display_name = EXCLUDED.display_name,\n description = EXCLUDED.description,\n prompt = EXCLUDED.prompt,\n is_default = EXCLUDED.is_default,\n tool_overrides = EXCLUDED.tool_overrides,\n model = EXCLUDED.model,\n config = EXCLUDED.config,\n updated_at = EXCLUDED.updated_at`,\n ).run(\n data.id,\n data.agent_id,\n data.source ?? DEFAULT_SOURCE,\n data.display_name ?? null,\n data.description ?? null,\n data.prompt,\n data.is_default ?? DEFAULT_IS_DEFAULT,\n data.tool_overrides ?? null,\n data.model ?? null,\n data.config ?? null,\n data.created_at,\n data.updated_at ?? null,\n );\n\n return toTaskRow(\n db.prepare(`SELECT ${SELECT_COLUMNS} FROM agent_tasks WHERE id = ?`).get(data.id) as Record<string, unknown>,\n );\n}\n\n/**\n * Retrieve a single task by id.\n *\n * @returns the task row, or null if not found.\n */\nexport function getTask(id: string): TaskRow | null {\n const db = getDatabase();\n\n const row = db.prepare(\n `SELECT ${SELECT_COLUMNS} FROM agent_tasks WHERE id = ?`,\n ).get(id) as Record<string, unknown> | undefined;\n\n if (!row) return null;\n return toTaskRow(row);\n}\n\n/**\n * List tasks with optional filters, ordered by created_at ASC.\n */\nexport function listTasks(\n options: ListTasksOptions = {},\n): TaskRow[] {\n const db = getDatabase();\n\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (options.agent_id !== undefined) {\n conditions.push(`agent_id = ?`);\n params.push(options.agent_id);\n }\n\n if (options.source !== undefined) {\n conditions.push(`source = ?`);\n params.push(options.source);\n }\n\n const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n const limit = options.limit ?? DEFAULT_LIST_LIMIT;\n\n params.push(limit);\n\n const rows = db.prepare(\n `SELECT ${SELECT_COLUMNS}\n FROM agent_tasks\n ${where}\n ORDER BY created_at ASC\n LIMIT ?`,\n ).all(...params) as Record<string, unknown>[];\n\n return rows.map(toTaskRow);\n}\n\n/**\n * Get the default task for an agent.\n *\n * @returns the default task row, or null if no default exists.\n */\nexport function getDefaultTask(\n agentId: string,\n): TaskRow | null {\n const db = getDatabase();\n\n const row = db.prepare(\n `SELECT ${SELECT_COLUMNS}\n FROM agent_tasks\n WHERE agent_id = ? AND is_default = ?\n LIMIT 1`,\n ).get(agentId, IS_DEFAULT_TRUE) as Record<string, unknown> | undefined;\n\n if (!row) return null;\n return toTaskRow(row);\n}\n\n/**\n * List all tasks for an agent, ordered by display_name ASC.\n *\n * Rows with a null display_name sort before named tasks.\n */\nexport function listTasksByAgent(\n agentId: string,\n): TaskRow[] {\n const db = getDatabase();\n\n const rows = db.prepare(\n `SELECT ${SELECT_COLUMNS}\n FROM agent_tasks\n WHERE agent_id = ?\n ORDER BY display_name ASC`,\n ).all(agentId) as Record<string, unknown>[];\n\n return rows.map(toTaskRow);\n}\n\n/**\n * Delete a task by id.\n *\n * Built-in tasks (source = 'built-in') are protected and cannot be deleted.\n *\n * @returns true if the task was deleted, false if not found or protected.\n */\nexport function deleteTask(id: string): boolean {\n const db = getDatabase();\n const info = db.prepare(\n `DELETE FROM agent_tasks WHERE id = ? AND source != ?`,\n ).run(id, BUILT_IN_SOURCE);\n return info.changes > 0;\n}\n"],"mappings":"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","names":["DEFAULT_SOURCE","SELECT_COLUMNS","DEFAULT_SOURCE","SELECT_COLUMNS","SELECT_COLUMNS","parseYaml"]}
|