cohorte 2.10.1 → 3.0.0-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/README.md +7 -0
  2. package/assets/manifest.json +193 -0
  3. package/assets/migrations/config/README.md +12 -0
  4. package/assets/migrations/state/0001_init.sql +154 -0
  5. package/assets/prompts/README.md +11 -0
  6. package/assets/prompts/agents/fixer.md +7 -0
  7. package/assets/prompts/agents/implementer.md +12 -0
  8. package/assets/prompts/agents/reviewer.md +8 -0
  9. package/assets/prompts/agents/security-reviewer.md +7 -0
  10. package/assets/prompts/phases/build.md +5 -0
  11. package/assets/prompts/phases/review.md +5 -0
  12. package/assets/prompts/phases/test.md +5 -0
  13. package/assets/prompts/system.md +11 -0
  14. package/assets/schemas/agent-output.schema.json +225 -0
  15. package/assets/schemas/auth-status.schema.json +87 -0
  16. package/assets/schemas/command-result.schema.json +192 -0
  17. package/assets/schemas/commands.schema.json +952 -0
  18. package/assets/schemas/config.schema.json +2259 -0
  19. package/assets/schemas/doctor-report.schema.json +104 -0
  20. package/assets/schemas/events.schema.json +8514 -0
  21. package/assets/schemas/fake-script.schema.json +549 -0
  22. package/assets/schemas/inspect.schema.json +3133 -0
  23. package/assets/schemas/manifest.schema.json +79 -0
  24. package/assets/schemas/ownership.schema.json +52 -0
  25. package/assets/schemas/policy-verdict.schema.json +282 -0
  26. package/assets/schemas/project-model.schema.json +783 -0
  27. package/assets/schemas/project-status.schema.json +217 -0
  28. package/assets/schemas/reconcile-plan.schema.json +155 -0
  29. package/assets/schemas/run-diff.schema.json +177 -0
  30. package/assets/schemas/run-snapshot-manifest.schema.json +2104 -0
  31. package/assets/schemas/run-state.schema.json +1755 -0
  32. package/assets/schemas/runtime-capabilities.schema.json +1545 -0
  33. package/assets/schemas/sandbox-capabilities.schema.json +116 -0
  34. package/assets/schemas/skill.schema.json +87 -0
  35. package/assets/schemas/spec.schema.json +202 -0
  36. package/assets/schemas/tool-catalogue.schema.json +655 -0
  37. package/assets/schemas/trust-record.schema.json +38 -0
  38. package/assets/skills/README.md +9 -0
  39. package/assets/skills/inspect-surface.md +4 -0
  40. package/dist/agent-host.mjs +50 -0
  41. package/dist/agent-host.mjs.map +1 -0
  42. package/dist/bundle-manifest.json +102 -0
  43. package/dist/chunks/__host-DgGPyco9.mjs +18 -0
  44. package/dist/chunks/__host-DgGPyco9.mjs.map +1 -0
  45. package/dist/chunks/approve-Cv135UqI.mjs +19 -0
  46. package/dist/chunks/approve-Cv135UqI.mjs.map +1 -0
  47. package/dist/chunks/auth-BT5oVp76.mjs +132 -0
  48. package/dist/chunks/auth-BT5oVp76.mjs.map +1 -0
  49. package/dist/chunks/auth-D8rCVY33.mjs +84 -0
  50. package/dist/chunks/auth-D8rCVY33.mjs.map +1 -0
  51. package/dist/chunks/brainstorm-CU10T1tm.mjs +7 -0
  52. package/dist/chunks/brainstorm-CU10T1tm.mjs.map +1 -0
  53. package/dist/chunks/cancel-KV_cpsqS.mjs +15 -0
  54. package/dist/chunks/cancel-KV_cpsqS.mjs.map +1 -0
  55. package/dist/chunks/canonical-C8UxeEmB.mjs +57 -0
  56. package/dist/chunks/canonical-C8UxeEmB.mjs.map +1 -0
  57. package/dist/chunks/catalogue-BvwSrM_j.mjs +1549 -0
  58. package/dist/chunks/catalogue-BvwSrM_j.mjs.map +1 -0
  59. package/dist/chunks/compose-Cr0hP0qm.mjs +7303 -0
  60. package/dist/chunks/compose-Cr0hP0qm.mjs.map +1 -0
  61. package/dist/chunks/config-DefHA2Lw.mjs +96 -0
  62. package/dist/chunks/config-DefHA2Lw.mjs.map +1 -0
  63. package/dist/chunks/contract-B0ra2-bm.mjs +295 -0
  64. package/dist/chunks/contract-B0ra2-bm.mjs.map +1 -0
  65. package/dist/chunks/contract-vYbwYr0Y.mjs +123 -0
  66. package/dist/chunks/contract-vYbwYr0Y.mjs.map +1 -0
  67. package/dist/chunks/deny-ClTxSvHJ.mjs +15 -0
  68. package/dist/chunks/deny-ClTxSvHJ.mjs.map +1 -0
  69. package/dist/chunks/diff-Qw0II0sj.mjs +101 -0
  70. package/dist/chunks/diff-Qw0II0sj.mjs.map +1 -0
  71. package/dist/chunks/discover-30Ciya_0.mjs +20 -0
  72. package/dist/chunks/discover-30Ciya_0.mjs.map +1 -0
  73. package/dist/chunks/doctor-DfCrKpfT.mjs +222 -0
  74. package/dist/chunks/doctor-DfCrKpfT.mjs.map +1 -0
  75. package/dist/chunks/fix-D4Tj8RVA.mjs +18 -0
  76. package/dist/chunks/fix-D4Tj8RVA.mjs.map +1 -0
  77. package/dist/chunks/gc-BBXlBF5w.mjs +161 -0
  78. package/dist/chunks/gc-BBXlBF5w.mjs.map +1 -0
  79. package/dist/chunks/init-Okz4mlhW.mjs +30 -0
  80. package/dist/chunks/init-Okz4mlhW.mjs.map +1 -0
  81. package/dist/chunks/inspect-Buby4cQD.mjs +22 -0
  82. package/dist/chunks/inspect-Buby4cQD.mjs.map +1 -0
  83. package/dist/chunks/logs-Giq5sUau.mjs +25 -0
  84. package/dist/chunks/logs-Giq5sUau.mjs.map +1 -0
  85. package/dist/chunks/migrate-DRoFUg53.mjs +19 -0
  86. package/dist/chunks/migrate-DRoFUg53.mjs.map +1 -0
  87. package/dist/chunks/models-Btp6X2YZ.mjs +24 -0
  88. package/dist/chunks/models-Btp6X2YZ.mjs.map +1 -0
  89. package/dist/chunks/pause-BASBfKLO.mjs +16 -0
  90. package/dist/chunks/pause-BASBfKLO.mjs.map +1 -0
  91. package/dist/chunks/policy-DUIgzF3W.mjs +139 -0
  92. package/dist/chunks/policy-DUIgzF3W.mjs.map +1 -0
  93. package/dist/chunks/providers-Dx78imKj.mjs +19 -0
  94. package/dist/chunks/providers-Dx78imKj.mjs.map +1 -0
  95. package/dist/chunks/reconcile-BfD785gd.mjs +26 -0
  96. package/dist/chunks/reconcile-BfD785gd.mjs.map +1 -0
  97. package/dist/chunks/render-DyZr5Lgi.mjs +53 -0
  98. package/dist/chunks/render-DyZr5Lgi.mjs.map +1 -0
  99. package/dist/chunks/resume-GJQRb2Eb.mjs +15 -0
  100. package/dist/chunks/resume-GJQRb2Eb.mjs.map +1 -0
  101. package/dist/chunks/retry-CLrUem1H.mjs +15 -0
  102. package/dist/chunks/retry-CLrUem1H.mjs.map +1 -0
  103. package/dist/chunks/review-BDdjb6kB.mjs +17 -0
  104. package/dist/chunks/review-BDdjb6kB.mjs.map +1 -0
  105. package/dist/chunks/run-CgTWYlcd.mjs +82 -0
  106. package/dist/chunks/run-CgTWYlcd.mjs.map +1 -0
  107. package/dist/chunks/run-tool-C3rAv4XF.mjs +26 -0
  108. package/dist/chunks/run-tool-C3rAv4XF.mjs.map +1 -0
  109. package/dist/chunks/schema-C9QbUW4H.mjs +578 -0
  110. package/dist/chunks/schema-C9QbUW4H.mjs.map +1 -0
  111. package/dist/chunks/send-BdnJ85Nz.mjs +19 -0
  112. package/dist/chunks/send-BdnJ85Nz.mjs.map +1 -0
  113. package/dist/chunks/ship-DTuLGoaJ.mjs +19 -0
  114. package/dist/chunks/ship-DTuLGoaJ.mjs.map +1 -0
  115. package/dist/chunks/shutdown-BM92Iyv2.mjs +15 -0
  116. package/dist/chunks/shutdown-BM92Iyv2.mjs.map +1 -0
  117. package/dist/chunks/skip-DZG5kpcH.mjs +18 -0
  118. package/dist/chunks/skip-DZG5kpcH.mjs.map +1 -0
  119. package/dist/chunks/spec-Bq0P3jVh.mjs +20 -0
  120. package/dist/chunks/spec-Bq0P3jVh.mjs.map +1 -0
  121. package/dist/chunks/src-CId6kMsY.mjs +1689 -0
  122. package/dist/chunks/src-CId6kMsY.mjs.map +1 -0
  123. package/dist/chunks/src-CfAOde7C.mjs +5403 -0
  124. package/dist/chunks/src-CfAOde7C.mjs.map +1 -0
  125. package/dist/chunks/src-Cu3TxNob.mjs +783 -0
  126. package/dist/chunks/src-Cu3TxNob.mjs.map +1 -0
  127. package/dist/chunks/src-DcU4IXMe.mjs +117 -0
  128. package/dist/chunks/src-DcU4IXMe.mjs.map +1 -0
  129. package/dist/chunks/src-JxawBQBn.mjs +446 -0
  130. package/dist/chunks/src-JxawBQBn.mjs.map +1 -0
  131. package/dist/chunks/src-s7YRvk0t.mjs +2116 -0
  132. package/dist/chunks/src-s7YRvk0t.mjs.map +1 -0
  133. package/dist/chunks/status-SMjiOMYy.mjs +29 -0
  134. package/dist/chunks/status-SMjiOMYy.mjs.map +1 -0
  135. package/dist/chunks/tail-BuhT-2PH.mjs +25 -0
  136. package/dist/chunks/tail-BuhT-2PH.mjs.map +1 -0
  137. package/dist/chunks/update-BXIppsbi.mjs +16 -0
  138. package/dist/chunks/update-BXIppsbi.mjs.map +1 -0
  139. package/dist/cli.mjs +175 -0
  140. package/dist/cli.mjs.map +1 -0
  141. package/package.json +17 -32
  142. package/CHANGELOG.md +0 -1461
  143. package/bin/cli.js +0 -817
  144. package/bin/report.js +0 -141
  145. package/core/adapter/render.js +0 -415
  146. package/core/agents/implementer.template.md +0 -142
  147. package/core/agents/profile-reader.md +0 -50
  148. package/core/agents/release.md +0 -58
  149. package/core/agents/review.md +0 -179
  150. package/core/commands/cohorte-align-ds.md +0 -33
  151. package/core/commands/cohorte-audit.md +0 -58
  152. package/core/commands/cohorte-brainstorm.md +0 -70
  153. package/core/commands/cohorte-build.md +0 -219
  154. package/core/commands/cohorte-doctor.md +0 -194
  155. package/core/commands/cohorte-fix.md +0 -80
  156. package/core/commands/cohorte-fleet.md +0 -103
  157. package/core/commands/cohorte-init-pipeline.md +0 -31
  158. package/core/commands/cohorte-intake.md +0 -92
  159. package/core/commands/cohorte-patch.md +0 -118
  160. package/core/commands/cohorte-refactor.md +0 -59
  161. package/core/commands/cohorte-retro.md +0 -85
  162. package/core/commands/cohorte-review.md +0 -270
  163. package/core/commands/cohorte-ship.md +0 -122
  164. package/core/commands/cohorte-spec.md +0 -101
  165. package/core/commands/cohorte-update-pipeline.md +0 -165
  166. package/core/hooks/gate.py +0 -588
  167. package/core/runtimes/claude.json +0 -74
  168. package/core/runtimes/codex.json +0 -85
  169. package/core/runtimes/cursor.json +0 -76
  170. package/core/runtimes/gemini.json +0 -76
  171. package/core/runtimes/opencode.json +0 -73
  172. package/core/templates/agent-handoff.md +0 -34
  173. package/core/templates/brainstorm-return.md +0 -36
  174. package/core/templates/decisions.template.md +0 -42
  175. package/core/templates/design-brief.md +0 -44
  176. package/core/templates/patch.template.md +0 -86
  177. package/core/templates/pr-body.md +0 -25
  178. package/core/templates/review-feedback.md +0 -38
  179. package/core/templates/spec.template.md +0 -87
  180. package/core/templates/steps/init-pipeline/01-detect-stack.md +0 -44
  181. package/core/templates/steps/init-pipeline/02-interview-gaps.md +0 -55
  182. package/core/templates/steps/init-pipeline/03-draft-profile.md +0 -10
  183. package/core/templates/steps/init-pipeline/04-write-render.md +0 -145
  184. package/core/templates/steps/init-pipeline/05-report.md +0 -12
  185. package/core/workflows/audit.js +0 -240
  186. package/core/workflows/loop.js +0 -641
  187. package/core/workflows/refactor.js +0 -276
  188. package/core/workflows/review.js +0 -456
  189. package/install.ps1 +0 -103
  190. package/install.sh +0 -114
  191. package/lib/doctor.js +0 -534
  192. package/lib/runtime.js +0 -139
  193. package/lib/versions.js +0 -149
  194. package/lib/yaml.js +0 -129
  195. package/profile/PIPELINE.template.md +0 -259
  196. package/profile/SCHEMA.md +0 -735
  197. package/profile/cohorte.config.template.yaml +0 -43
  198. package/scripts/assert-gate-hook.mjs +0 -75
  199. package/scripts/kanban-move.sh +0 -313
  200. package/scripts/metrics/collect.mjs +0 -531
  201. package/scripts/metrics/prices.json +0 -42
  202. package/scripts/new-feature.sh.template +0 -98
  203. package/scripts/preflight.sh +0 -124
  204. package/scripts/remove-feature.sh.template +0 -56
  205. package/scripts/test-adapter.mjs +0 -437
  206. package/scripts/test-gate.mjs +0 -443
  207. package/scripts/test-kanban.mjs +0 -304
  208. package/scripts/test-lib.mjs +0 -356
  209. package/scripts/test-metrics.mjs +0 -156
  210. package/scripts/test-workflows.mjs +0 -758
  211. package/scripts/validate-core.mjs +0 -325
@@ -1,156 +0,0 @@
1
- #!/usr/bin/env node
2
- // test-metrics.mjs — end-to-end checks for scripts/metrics/collect.mjs.
3
- //
4
- // Builds a throwaway repo plus a synthetic ~/.claude/projects transcript, runs the real
5
- // collector against it via --json, and asserts the numbers. The cases are the ones that
6
- // silently produce plausible-but-wrong output rather than crashing:
7
- //
8
- // 1. one API response written as several transcript lines, each repeating `usage`
9
- // 2. a <task-notification> arriving mid-command (must not split the run)
10
- // 3. subagent spend, which lives in a separate file tree
11
- // 4. <synthetic> harness messages, which carry usage but cost nothing
12
- // 5. the cache-tier pricing arithmetic itself
13
- //
14
- // Run: node scripts/test-metrics.mjs
15
-
16
- import fs from 'node:fs';
17
- import os from 'node:os';
18
- import path from 'node:path';
19
- import { execFileSync, spawnSync } from 'node:child_process';
20
- import { fileURLToPath } from 'node:url';
21
-
22
- const HERE = path.dirname(fileURLToPath(import.meta.url));
23
- const COLLECT = path.join(HERE, 'metrics', 'collect.mjs');
24
-
25
- let failures = 0;
26
- const ok = (label) => console.log(` ✓ ${label}`);
27
- function check(label, actual, expected) {
28
- const a = JSON.stringify(actual), e = JSON.stringify(expected);
29
- if (a === e) return ok(label);
30
- failures += 1;
31
- console.log(` ✗ ${label}\n expected ${e}\n actual ${a}`);
32
- }
33
-
34
- const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'cohorte-metrics-'));
35
- const repo = path.join(tmp, 'repo');
36
- const cfg = path.join(tmp, 'claude');
37
- const SESSION = 'sess-test-0001';
38
- const projectDir = path.join(cfg, 'projects', 'test-slug');
39
- fs.mkdirSync(path.join(projectDir, SESSION, 'subagents'), { recursive: true });
40
- fs.mkdirSync(repo, { recursive: true });
41
- execFileSync('git', ['init', '-q'], { cwd: repo, stdio: 'ignore' });
42
-
43
- const T0 = Date.parse('2026-07-30T10:00:00.000Z');
44
- const at = (s) => new Date(T0 + s * 1000).toISOString();
45
-
46
- const assistant = (id, tsS, model, usage, content = [{ type: 'text', text: 'x' }]) => ({
47
- type: 'assistant', timestamp: at(tsS), cwd: repo, sessionId: SESSION,
48
- message: { id, model, content, usage },
49
- });
50
- const user = (tsS, text) => ({
51
- type: 'user', timestamp: at(tsS), cwd: repo, sessionId: SESSION,
52
- message: { role: 'user', content: text },
53
- });
54
-
55
- const usageOpus = {
56
- input_tokens: 100, output_tokens: 1000,
57
- cache_creation_input_tokens: 1000, cache_read_input_tokens: 10000,
58
- cache_creation: { ephemeral_5m_input_tokens: 1000, ephemeral_1h_input_tokens: 0 },
59
- };
60
-
61
- const lines = [
62
- user(0, '<command-message>build</command-message>\n<command-name>/cohorte-build</command-name>'),
63
- // Case 1: one response, three lines, identical usage on each. Only one should be billed.
64
- assistant('m1', 5, 'claude-opus-5', usageOpus, [{ type: 'thinking', thinking: '...' }]),
65
- assistant('m1', 5, 'claude-opus-5', usageOpus, [{ type: 'text', text: 'hello' }]),
66
- assistant('m1', 6, 'claude-opus-5', usageOpus, [{ type: 'tool_use', id: 'toolu_A', name: 'Task', input: {} }]),
67
- // Case 2: a background agent finished mid-run. This is not the human starting anything.
68
- user(10, '<task-notification>\n<task-id>a1</task-id>\n</task-notification>'),
69
- // Case 4: harness-authored message, has usage, costs nothing.
70
- assistant('m2', 12, '<synthetic>', { input_tokens: 0, output_tokens: 999999 }),
71
- assistant('m3', 20, 'claude-opus-5', { input_tokens: 0, output_tokens: 500 }),
72
- // A second, genuinely separate run — long enough not to read as a steering turn.
73
- user(600, 'unrelated question about the repository layout and its conventions'),
74
- assistant('m4', 605, 'claude-opus-5', { input_tokens: 0, output_tokens: 40 }),
75
- // Case 6: a command named inside ordinary prose. The harness emits no <command-name>
76
- // for this, but it is the way commands actually get invoked in practice.
77
- user(1200, 'move on branding-ramp and /cohorte-review'),
78
- assistant('m5', 1205, 'claude-opus-5', { input_tokens: 0, output_tokens: 60 }),
79
- // Case 7: a short steer continues the /cohorte-review rather than opening an anonymous run.
80
- user(1260, 'continue'),
81
- assistant('m6', 1265, 'claude-opus-5', { input_tokens: 0, output_tokens: 70 }),
82
- // Case 8: a slash token that is not a command must not invent one.
83
- user(1800, 'look at the /usr/local/share directory and report what you find there'),
84
- assistant('m7', 1805, 'claude-opus-5', { input_tokens: 0, output_tokens: 10 }),
85
- // Case 9: a long prompt that merely DISCUSSES a command is not an invocation of it.
86
- // Without the length gate, writing about /cohorte-review bills the conversation to /cohorte-review —
87
- // which is what happened in cohorte's own repo while the pipeline was being designed.
88
- user(2400, 'I want to talk through how /cohorte-review behaves when a surface has no findings at '
89
- + 'all, because the verdict logic there is what produced the false green we saw last week '
90
- + 'and I am not convinced the fix covers the case where every reviewer dies at once.'),
91
- assistant('m8', 2405, 'claude-opus-5', { input_tokens: 0, output_tokens: 20 }),
92
- // Case 10: a RETIRED command name still attributes to itself. 2.0.0 prefixed every
93
- // command, so months of existing transcripts say `/build` — and the collector reads its
94
- // known names off the shipped core, where `build.md` no longer exists. Without the
95
- // retired list every one of those runs silently reclassifies to (chat), rewriting spend
96
- // history and inflating the catch-all. This is the largest instance of that bug class,
97
- // so it gets pinned rather than trusted to a comment.
98
- user(3000, '/build branding-ramp'),
99
- assistant('m9', 3005, 'claude-opus-5', { input_tokens: 0, output_tokens: 90 }),
100
- ];
101
- fs.writeFileSync(path.join(projectDir, `${SESSION}.jsonl`),
102
- lines.map((l) => JSON.stringify(l)).join('\n') + '\n');
103
-
104
- // Case 3: subagent spend, linked back to /cohorte-build by the Task tool_use id.
105
- const agentDir = path.join(projectDir, SESSION, 'subagents');
106
- fs.writeFileSync(path.join(agentDir, 'agent-a1.meta.json'),
107
- JSON.stringify({ agentType: 'core', description: 'Build core surface', toolUseId: 'toolu_A', spawnDepth: 1 }));
108
- fs.writeFileSync(path.join(agentDir, 'agent-a1.jsonl'),
109
- JSON.stringify(assistant('s1', 8, 'claude-sonnet-5', { input_tokens: 0, output_tokens: 2000 })) + '\n');
110
-
111
- const run = spawnSync(process.execPath, [COLLECT, repo, '--json', '--runs'], {
112
- encoding: 'utf8',
113
- env: { ...process.env, CLAUDE_CONFIG_DIR: cfg },
114
- });
115
- if (run.status !== 0) {
116
- console.error('collector failed:\n' + (run.stderr || run.stdout));
117
- process.exit(1);
118
- }
119
- const out = JSON.parse(run.stdout);
120
- const build = out.commands.find((c) => c.command === '/cohorte-build');
121
- const chat = out.commands.find((c) => c.command === '(chat)');
122
- const retired = out.commands.find((c) => c.command === '/build');
123
- const review = out.commands.find((c) => c.command === '/cohorte-review');
124
-
125
- console.log('test-metrics');
126
- check('the mid-command task-notification did not split the run', out.totals.runs, 6);
127
- check('/cohorte-build is one run, not three', build.runs, 1);
128
- check('duplicate lines of one response are billed once', build.tokens.output, 1000 + 500 + 2000);
129
- check('the <synthetic> message contributed no tokens', build.tokens.output < 999999, true);
130
- check('cache-write tokens are kept on their own tier', build.tokens.cacheWrite5m, 1000);
131
- check('cache-read tokens are kept on their own tier', build.tokens.cacheRead, 10000);
132
- check('the subagent was attributed to the command that spawned it', build.agents.total, 1);
133
- check('the second prompt is a separate (chat) run', chat.runs, 3);
134
- check('a command named inside prose is attributed to that command', review && review.runs, 1);
135
- check('a short steer continues the run instead of opening a new one', review.continuations, 1);
136
- check('the continued turn counts toward the command it continued', review.tokens.output, 60 + 70);
137
- check('a non-command slash token does not invent a command', chat.tokens.output, 40 + 10 + 20);
138
- check('a long prompt that discusses a command is not counted as running it',
139
- review.runs, 1);
140
- check('a retired unprefixed command stays attributed to itself, not (chat)',
141
- retired && retired.runs, 1);
142
- check('…and keeps its own spend', retired && retired.tokens.output, 90);
143
-
144
- // opus-5 $5 in / $25 out per MTok; 5m cache write 1.25x input, cache read 0.1x input.
145
- // m1 100*5 + 1000*25 + 1000*6.25 + 10000*0.5 = 36750
146
- // m3 500*25 = 12500
147
- // s1 sonnet-5 2000*10 = 20000 (subagent, $2/$10 since 2026-08)
148
- check('cost sums the cache tiers at their own rates', Number(build.cost.total.toFixed(6)), 0.06925);
149
- check('the unpriced list stays empty for known models', build.unpriced, []);
150
-
151
- const detail = out.runs.find((r) => r.command === '/cohorte-build');
152
- check('per-run detail carries the subagent', detail.agents.map((a) => a.type), ['core']);
153
-
154
- fs.rmSync(tmp, { recursive: true, force: true });
155
- console.log(failures ? `\ntest-metrics: ${failures} FAILED` : '\ntest-metrics: OK');
156
- process.exit(failures ? 1 : 0);