zelari-code 2.0.1 → 2.1.1

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 (123) hide show
  1. package/README.md +5 -5
  2. package/dist/cli/hooks/useChatTurn.js +2 -1
  3. package/dist/cli/hooks/useChatTurn.js.map +1 -1
  4. package/dist/cli/kraken/candidateRegistry.js +15 -1
  5. package/dist/cli/kraken/candidateRegistry.js.map +1 -1
  6. package/dist/cli/kraken/verificationBridge.js +125 -14
  7. package/dist/cli/kraken/verificationBridge.js.map +1 -1
  8. package/dist/cli/kraken/verifierLifecycle.js +88 -0
  9. package/dist/cli/kraken/verifierLifecycle.js.map +1 -0
  10. package/dist/cli/kraken/verifyReport.js.map +1 -1
  11. package/dist/cli/main.bundled.js +272 -89
  12. package/dist/cli/main.bundled.js.map +4 -4
  13. package/dist/cli/runHeadless.js +44 -93
  14. package/dist/cli/runHeadless.js.map +1 -1
  15. package/dist/cli/tools/taskTool.js +49 -3
  16. package/dist/cli/tools/taskTool.js.map +1 -1
  17. package/package.json +8 -5
  18. package/dist/cli/ast/engine.test.js +0 -101
  19. package/dist/cli/ast/engine.test.js.map +0 -1
  20. package/dist/cli/ast/tools.test.js +0 -124
  21. package/dist/cli/ast/tools.test.js.map +0 -1
  22. package/dist/cli/headless.test.js +0 -107
  23. package/dist/cli/headless.test.js.map +0 -1
  24. package/dist/cli/headlessE2eSession.test.js +0 -189
  25. package/dist/cli/headlessE2eSession.test.js.map +0 -1
  26. package/dist/cli/headlessHistorySeed.test.js +0 -158
  27. package/dist/cli/headlessHistorySeed.test.js.map +0 -1
  28. package/dist/cli/headlessSessionEvent.test.js +0 -83
  29. package/dist/cli/headlessSessionEvent.test.js.map +0 -1
  30. package/dist/cli/headlessSpine.test.js +0 -153
  31. package/dist/cli/headlessSpine.test.js.map +0 -1
  32. package/dist/cli/hooks/observationStore.test.js +0 -135
  33. package/dist/cli/hooks/observationStore.test.js.map +0 -1
  34. package/dist/cli/hooks/sessionSurface.test.js +0 -112
  35. package/dist/cli/hooks/sessionSurface.test.js.map +0 -1
  36. package/dist/cli/kraken/candidateRegistry.test.js +0 -211
  37. package/dist/cli/kraken/candidateRegistry.test.js.map +0 -1
  38. package/dist/cli/kraken/completionGate.test.js +0 -172
  39. package/dist/cli/kraken/completionGate.test.js.map +0 -1
  40. package/dist/cli/kraken/evidenceAnchoring.test.js +0 -92
  41. package/dist/cli/kraken/evidenceAnchoring.test.js.map +0 -1
  42. package/dist/cli/kraken/executor.workbench.test.js +0 -134
  43. package/dist/cli/kraken/executor.workbench.test.js.map +0 -1
  44. package/dist/cli/kraken/metrics.test.js +0 -145
  45. package/dist/cli/kraken/metrics.test.js.map +0 -1
  46. package/dist/cli/kraken/nativeVerification.test.js +0 -207
  47. package/dist/cli/kraken/nativeVerification.test.js.map +0 -1
  48. package/dist/cli/kraken/planner.test.js +0 -43
  49. package/dist/cli/kraken/planner.test.js.map +0 -1
  50. package/dist/cli/kraken/scriptPlanner.test.js +0 -152
  51. package/dist/cli/kraken/scriptPlanner.test.js.map +0 -1
  52. package/dist/cli/kraken/selectionPlaybook.test.js +0 -55
  53. package/dist/cli/kraken/selectionPlaybook.test.js.map +0 -1
  54. package/dist/cli/kraken/skillSuggest.test.js +0 -157
  55. package/dist/cli/kraken/skillSuggest.test.js.map +0 -1
  56. package/dist/cli/kraken/strictDefaults.test.js +0 -149
  57. package/dist/cli/kraken/strictDefaults.test.js.map +0 -1
  58. package/dist/cli/kraken/turnRuntime.test.js +0 -377
  59. package/dist/cli/kraken/turnRuntime.test.js.map +0 -1
  60. package/dist/cli/kraken/verificationBridge.session.test.js +0 -104
  61. package/dist/cli/kraken/verificationBridge.session.test.js.map +0 -1
  62. package/dist/cli/kraken/verificationBridge.test.js +0 -177
  63. package/dist/cli/kraken/verificationBridge.test.js.map +0 -1
  64. package/dist/cli/kraken/verifier.test.js +0 -232
  65. package/dist/cli/kraken/verifier.test.js.map +0 -1
  66. package/dist/cli/kraken/verifierAdvisoryLock.test.js +0 -154
  67. package/dist/cli/kraken/verifierAdvisoryLock.test.js.map +0 -1
  68. package/dist/cli/kraken/verifierRoundTrip.test.js +0 -166
  69. package/dist/cli/kraken/verifierRoundTrip.test.js.map +0 -1
  70. package/dist/cli/kraken/verifierSettings.test.js +0 -237
  71. package/dist/cli/kraken/verifierSettings.test.js.map +0 -1
  72. package/dist/cli/kraken/verifyReport.test.js +0 -111
  73. package/dist/cli/kraken/verifyReport.test.js.map +0 -1
  74. package/dist/cli/kraken/weaknessMeter.test.js +0 -212
  75. package/dist/cli/kraken/weaknessMeter.test.js.map +0 -1
  76. package/dist/cli/kraken/workbench.test.js +0 -253
  77. package/dist/cli/kraken/workbench.test.js.map +0 -1
  78. package/dist/cli/kraken/workbenchView.test.js +0 -130
  79. package/dist/cli/kraken/workbenchView.test.js.map +0 -1
  80. package/dist/cli/legacyContextIsolation.test.js +0 -65
  81. package/dist/cli/legacyContextIsolation.test.js.map +0 -1
  82. package/dist/cli/lsp/tools.test.js +0 -90
  83. package/dist/cli/lsp/tools.test.js.map +0 -1
  84. package/dist/cli/missionContinuation.test.js +0 -117
  85. package/dist/cli/missionContinuation.test.js.map +0 -1
  86. package/dist/cli/profileMatrix.test.js +0 -130
  87. package/dist/cli/profileMatrix.test.js.map +0 -1
  88. package/dist/cli/provider/capabilities.test.js +0 -46
  89. package/dist/cli/provider/capabilities.test.js.map +0 -1
  90. package/dist/cli/provider/openai-compatible.timeout.test.js +0 -72
  91. package/dist/cli/provider/openai-compatible.timeout.test.js.map +0 -1
  92. package/dist/cli/providerConfig.test.js +0 -85
  93. package/dist/cli/providerConfig.test.js.map +0 -1
  94. package/dist/cli/sessionReplayInvariant.test.js +0 -187
  95. package/dist/cli/sessionReplayInvariant.test.js.map +0 -1
  96. package/dist/cli/sessionSpine.test.js +0 -171
  97. package/dist/cli/sessionSpine.test.js.map +0 -1
  98. package/dist/cli/thinking.test.js +0 -214
  99. package/dist/cli/thinking.test.js.map +0 -1
  100. package/dist/cli/tools/inspectCommand.schema.test.js +0 -82
  101. package/dist/cli/tools/inspectCommand.schema.test.js.map +0 -1
  102. package/dist/cli/tools/inspectCommand.test.js +0 -311
  103. package/dist/cli/tools/inspectCommand.test.js.map +0 -1
  104. package/dist/cli/tools/krakenCsvFanout.test.js +0 -200
  105. package/dist/cli/tools/krakenCsvFanout.test.js.map +0 -1
  106. package/dist/cli/tools/krakenSelectTool.test.js +0 -246
  107. package/dist/cli/tools/krakenSelectTool.test.js.map +0 -1
  108. package/dist/cli/tools/observeBatch.test.js +0 -329
  109. package/dist/cli/tools/observeBatch.test.js.map +0 -1
  110. package/dist/cli/tools/taskTool.dynamicChecks.test.js +0 -156
  111. package/dist/cli/tools/taskTool.dynamicChecks.test.js.map +0 -1
  112. package/dist/cli/tools/taskTool.planSafety.test.js +0 -280
  113. package/dist/cli/tools/taskTool.planSafety.test.js.map +0 -1
  114. package/dist/cli/tools/taskTool.verifyReport.test.js +0 -140
  115. package/dist/cli/tools/taskTool.verifyReport.test.js.map +0 -1
  116. package/dist/cli/utils/contextGrowthSummary.test.js +0 -74
  117. package/dist/cli/utils/contextGrowthSummary.test.js.map +0 -1
  118. package/dist/cli/workspace/planDriftCheck.test.js +0 -146
  119. package/dist/cli/workspace/planDriftCheck.test.js.map +0 -1
  120. package/dist/cli/workspace/planStore.test.js +0 -295
  121. package/dist/cli/workspace/planStore.test.js.map +0 -1
  122. package/dist/cli/zelariMission.test.js +0 -44
  123. package/dist/cli/zelariMission.test.js.map +0 -1
@@ -1,212 +0,0 @@
1
- /**
2
- * Tests for the LLM weakness meter wiring.
3
- *
4
- * These tests exercise the parsing + env-gating only — they never call
5
- * a real provider. A small `fetchImpl` stub stands in for the network.
6
- *
7
- * @since v1.31.x
8
- */
9
- import { afterEach, describe, expect, it, vi } from 'vitest';
10
- import { _resetWeaknessMeterCacheForTests, isWeaknessMeterEnabled, measureWeaknessViaLLM, parseMeterContent, } from './weaknessMeter.js';
11
- afterEach(() => {
12
- _resetWeaknessMeterForTests();
13
- vi.restoreAllMocks();
14
- });
15
- function _resetWeaknessMeterForTests() {
16
- _resetWeaknessMeterCacheForTests();
17
- }
18
- describe('isWeaknessMeterEnabled', () => {
19
- it('defaults to false', () => {
20
- expect(isWeaknessMeterEnabled({})).toBe(false);
21
- });
22
- it('treats "1", "true", "yes" as enabled', () => {
23
- expect(isWeaknessMeterEnabled({ ZELARI_KRAKEN_WEAKNESS_METER: '1' })).toBe(true);
24
- expect(isWeaknessMeterEnabled({ ZELARI_KRAKEN_WEAKNESS_METER: 'true' })).toBe(true);
25
- expect(isWeaknessMeterEnabled({ ZELARI_KRAKEN_WEAKNESS_METER: 'yes' })).toBe(true);
26
- });
27
- it('treats other truthy values as disabled (avoid surprise)', () => {
28
- expect(isWeaknessMeterEnabled({ ZELARI_KRAKEN_WEAKNESS_METER: 'enabled' })).toBe(false);
29
- expect(isWeaknessMeterEnabled({ ZELARI_KRAKEN_WEAKNESS_METER: 'on' })).toBe(false);
30
- });
31
- it('memoizes the env read for the process', () => {
32
- expect(isWeaknessMeterEnabled({ ZELARI_KRAKEN_WEAKNESS_METER: '1' })).toBe(true);
33
- // Even if we re-call without the var, the cache wins until reset.
34
- expect(isWeaknessMeterEnabled({})).toBe(true);
35
- _resetWeaknessMeterForTests();
36
- expect(isWeaknessMeterEnabled({})).toBe(false);
37
- });
38
- });
39
- describe('measureWeaknessViaLLM (gating)', () => {
40
- it('returns null when the meter is disabled (default)', async () => {
41
- const out = await measureWeaknessViaLLM('hello', {
42
- env: {},
43
- providerOverride: {
44
- providerId: 'openai-compatible',
45
- model: 'gpt-4o-mini',
46
- endpoint: 'https://example.invalid',
47
- apiKey: 'k',
48
- },
49
- fetchImpl: vi.fn(),
50
- });
51
- expect(out).toBeNull();
52
- });
53
- it('returns null on empty / whitespace text even when enabled', async () => {
54
- const out = await measureWeaknessViaLLM(' \n ', {
55
- env: { ZELARI_KRAKEN_WEAKNESS_METER: '1' },
56
- providerOverride: {
57
- providerId: 'openai-compatible',
58
- model: 'gpt-4o-mini',
59
- endpoint: 'https://example.invalid',
60
- apiKey: 'k',
61
- },
62
- fetchImpl: vi.fn(),
63
- });
64
- expect(out).toBeNull();
65
- });
66
- });
67
- describe('measureWeaknessViaLLM (HTTP path)', () => {
68
- function goodFetch() {
69
- return vi.fn(async () => {
70
- return new Response(JSON.stringify({
71
- choices: [
72
- {
73
- message: {
74
- content: JSON.stringify({
75
- specificity: 0.42,
76
- assumptions: ['the file is at /x', 'version is 1.2.3'],
77
- }),
78
- },
79
- },
80
- ],
81
- }), { status: 200, headers: { 'content-type': 'application/json' } });
82
- });
83
- }
84
- it('parses a clean JSON payload', async () => {
85
- const out = await measureWeaknessViaLLM('I MUST always EXACTLY at line 42 version 1.2.3.', {
86
- env: { ZELARI_KRAKEN_WEAKNESS_METER: '1' },
87
- providerOverride: {
88
- providerId: 'openai-compatible',
89
- model: 'gpt-4o-mini',
90
- endpoint: 'https://example.invalid',
91
- apiKey: 'k',
92
- },
93
- fetchImpl: goodFetch(),
94
- });
95
- expect(out).not.toBeNull();
96
- expect(out.meter.specificity).toBe(0.42);
97
- expect(out.meter.assumptions).toHaveLength(2);
98
- expect(out.weakness).toBeCloseTo(0.58, 5);
99
- expect(out.model).toBe('gpt-4o-mini');
100
- });
101
- it('parses a ```json fenced payload', async () => {
102
- const fetchImpl = vi.fn(async () => {
103
- return new Response(JSON.stringify({
104
- choices: [
105
- {
106
- message: {
107
- content: '```json\n{"specificity": 0.9, "assumptions": []}\n```',
108
- },
109
- },
110
- ],
111
- }), { status: 200 });
112
- });
113
- const out = await measureWeaknessViaLLM('Looks good.', {
114
- env: { ZELARI_KRAKEN_WEAKNESS_METER: '1' },
115
- providerOverride: {
116
- providerId: 'openai-compatible',
117
- model: 'gpt-4o-mini',
118
- endpoint: 'https://example.invalid',
119
- apiKey: 'k',
120
- },
121
- fetchImpl,
122
- });
123
- expect(out).not.toBeNull();
124
- expect(out.weakness).toBeCloseTo(0.1, 5);
125
- });
126
- it('returns null on HTTP non-2xx', async () => {
127
- const fetchImpl = vi.fn(async () => {
128
- return new Response('rate limited', { status: 429 });
129
- });
130
- const out = await measureWeaknessViaLLM('Whatever.', {
131
- env: { ZELARI_KRAKEN_WEAKNESS_METER: '1' },
132
- providerOverride: {
133
- providerId: 'openai-compatible',
134
- model: 'gpt-4o-mini',
135
- endpoint: 'https://example.invalid',
136
- apiKey: 'k',
137
- },
138
- fetchImpl,
139
- });
140
- expect(out).toBeNull();
141
- });
142
- it('returns null on malformed JSON (silent failure)', async () => {
143
- const fetchImpl = vi.fn(async () => {
144
- return new Response(JSON.stringify({ choices: [{ message: { content: '{not valid' } }] }), { status: 200 });
145
- });
146
- const out = await measureWeaknessViaLLM('Whatever.', {
147
- env: { ZELARI_KRAKEN_WEAKNESS_METER: '1' },
148
- providerOverride: {
149
- providerId: 'openai-compatible',
150
- model: 'gpt-4o-mini',
151
- endpoint: 'https://example.invalid',
152
- apiKey: 'k',
153
- },
154
- fetchImpl,
155
- });
156
- expect(out).toBeNull();
157
- });
158
- it('returns null when the payload fails zod validation', async () => {
159
- const fetchImpl = vi.fn(async () => {
160
- // specificity out of range — zod should reject.
161
- return new Response(JSON.stringify({
162
- choices: [{ message: { content: JSON.stringify({ specificity: 1.7, assumptions: [] }) } }],
163
- }), { status: 200 });
164
- });
165
- const out = await measureWeaknessViaLLM('Whatever.', {
166
- env: { ZELARI_KRAKEN_WEAKNESS_METER: '1' },
167
- providerOverride: {
168
- providerId: 'openai-compatible',
169
- model: 'gpt-4o-mini',
170
- endpoint: 'https://example.invalid',
171
- apiKey: 'k',
172
- },
173
- fetchImpl,
174
- });
175
- expect(out).toBeNull();
176
- });
177
- it('returns null on a fetch rejection (network / timeout)', async () => {
178
- const fetchImpl = vi.fn(async () => {
179
- throw new Error('socket hang up');
180
- });
181
- const out = await measureWeaknessViaLLM('Whatever.', {
182
- env: { ZELARI_KRAKEN_WEAKNESS_METER: '1' },
183
- providerOverride: {
184
- providerId: 'openai-compatible',
185
- model: 'gpt-4o-mini',
186
- endpoint: 'https://example.invalid',
187
- apiKey: 'k',
188
- },
189
- fetchImpl,
190
- });
191
- expect(out).toBeNull();
192
- });
193
- });
194
- describe('parseMeterContent (unit)', () => {
195
- it('accepts raw JSON', () => {
196
- const out = parseMeterContent(JSON.stringify({ specificity: 0.2, assumptions: ['a'] }), 'm', 42);
197
- expect(out).not.toBeNull();
198
- expect(out.meter.specificity).toBe(0.2);
199
- expect(out.durationMs).toBe(42);
200
- });
201
- it('accepts a ```json fenced payload', () => {
202
- const out = parseMeterContent('```json\n{"specificity": 0.5, "assumptions": []}\n```', 'm', 0);
203
- expect(out).not.toBeNull();
204
- expect(out.meter.specificity).toBe(0.5);
205
- });
206
- it('returns null on a too-many-assumptions payload (>12)', () => {
207
- const tooMany = Array.from({ length: 13 }, (_, i) => `a${i}`);
208
- const out = parseMeterContent(JSON.stringify({ specificity: 0.5, assumptions: tooMany }), 'm', 0);
209
- expect(out).toBeNull();
210
- });
211
- });
212
- //# sourceMappingURL=weaknessMeter.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"weaknessMeter.test.js","sourceRoot":"","sources":["../../../src/cli/kraken/weaknessMeter.test.ts"],"names":[],"mappings":"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"}
@@ -1,253 +0,0 @@
1
- /**
2
- * Kraken workbench writer — tests.
3
- *
4
- * Covers:
5
- * - `flush()` writes a Markdown file to `.zelari/radio/workbench-<id>.md`
6
- * - The file is rewritten atomically (no partial state on tail)
7
- * - `setNodes` + `markStart` + `markEnd` produce the expected table
8
- * - Events are capped at MAX_EVENTS (30)
9
- * - `ZELARI_KRAKEN_WORKBENCH=0` disables the writer
10
- * - Disabled writer is a no-op (no file, no error)
11
- */
12
- import { describe, it, expect, beforeEach } from 'vitest';
13
- import { promises as fs } from 'node:fs';
14
- import os from 'node:os';
15
- import path from 'node:path';
16
- import { WorkbenchWriter, isWorkbenchEnabled } from './workbench.js';
17
- let tmp = '';
18
- let counter = 0;
19
- async function freshTmp() {
20
- const t = await fs.mkdtemp(path.join(os.tmpdir(), 'kraken-workbench-'));
21
- counter += 1;
22
- return t;
23
- }
24
- describe('isWorkbenchEnabled', () => {
25
- it('defaults to true', () => {
26
- expect(isWorkbenchEnabled({})).toBe(true);
27
- });
28
- it('respects ZELARI_KRAKEN_WORKBENCH=0', () => {
29
- expect(isWorkbenchEnabled({ ZELARI_KRAKEN_WORKBENCH: '0' })).toBe(false);
30
- });
31
- it('treats "no", "false", "off" as disabled', () => {
32
- expect(isWorkbenchEnabled({ ZELARI_KRAKEN_WORKBENCH: 'no' })).toBe(false);
33
- expect(isWorkbenchEnabled({ ZELARI_KRAKEN_WORKBENCH: 'false' })).toBe(false);
34
- expect(isWorkbenchEnabled({ ZELARI_KRAKEN_WORKBENCH: 'off' })).toBe(false);
35
- });
36
- });
37
- describe('WorkbenchWriter', () => {
38
- beforeEach(async () => {
39
- tmp = await freshTmp();
40
- });
41
- it('writes a Markdown file with the expected header', async () => {
42
- const w = new WorkbenchWriter({ cwd: tmp, graphId: 'g-1', goal: 'refactor auth' });
43
- w.setNodes([{ id: 't0001', kind: 'explore', label: 'map', status: 'pending' }]);
44
- const out = await w.flush();
45
- expect(out).toBe(path.join(tmp, '.zelari', 'radio', 'workbench-g-1.md'));
46
- const body = await fs.readFile(out, 'utf8');
47
- expect(body).toContain('# Kraken workbench');
48
- expect(body).toContain('**Goal:** refactor auth');
49
- expect(body).toContain('**Graph id:** `g-1`');
50
- expect(body).toContain('| t0001 | map | explore |');
51
- });
52
- it('updates the table on markStart / markEnd', async () => {
53
- const w = new WorkbenchWriter({ cwd: tmp, graphId: 'g-2', goal: 'x' });
54
- w.setNodes([{ id: 't0001', kind: 'general', label: 'do it', status: 'pending', scope: ['src/auth'] }]);
55
- w.markStart('t0001', { model: 'grok-3-mini' });
56
- w.markEnd('t0001', { status: 'done', durationMs: 1234 });
57
- const out = await w.flush();
58
- const body = await fs.readFile(out, 'utf8');
59
- expect(body).toContain('✓'); // done emoji
60
- expect(body).toContain('1.2s'); // formatted duration
61
- expect(body).toContain('grok-3-mini');
62
- expect(body).toContain('src/auth');
63
- });
64
- it('captures events in the latest-30 list', async () => {
65
- const w = new WorkbenchWriter({ cwd: tmp, graphId: 'g-3', goal: 'x' });
66
- for (let i = 0; i < 50; i++)
67
- w.logEvent(`event ${i}`);
68
- const out = await w.flush();
69
- const body = await fs.readFile(out, 'utf8');
70
- // The first 20 events are dropped; the last 30 survive.
71
- expect(body).not.toContain('event 0 ');
72
- expect(body).not.toContain('event 19 ');
73
- expect(body).toContain('event 20');
74
- expect(body).toContain('event 49');
75
- });
76
- it('marks a node as error and surfaces the message', async () => {
77
- const w = new WorkbenchWriter({ cwd: tmp, graphId: 'g-4', goal: 'x' });
78
- w.setNodes([{ id: 't0001', kind: 'general', label: 'do', status: 'pending' }]);
79
- w.markStart('t0001');
80
- w.markEnd('t0001', { status: 'error', error: 'kaboom', durationMs: 100 });
81
- const out = await w.flush();
82
- const body = await fs.readFile(out, 'utf8');
83
- expect(body).toContain('✗');
84
- expect(body).toContain('kaboom');
85
- });
86
- it('parses the persona verdict and Bennett weakness score from findings', async () => {
87
- // Simulate a verify/spec/conformance node whose findings include the
88
- // standard trailer. The workbench must surface the verdict + weakness
89
- // in the Wave table so a `tail -f` reader sees whether a PASS was
90
- // earned by a tightly-asserted or loosely-claimed reviewer.
91
- const w = new WorkbenchWriter({ cwd: tmp, graphId: 'g-err', goal: 'x' });
92
- w.setNodes([{ id: 'v-001', kind: 'verify', label: 'review', status: 'pending' }]);
93
- w.markStart('v-001');
94
- w.markEnd('v-001', {
95
- status: 'done',
96
- durationMs: 100,
97
- findings: 'All requirements are met. The function returns the right shape.\n\nVERDICT: PASS',
98
- });
99
- const out = await w.flush();
100
- const body = await fs.readFile(out, 'utf8');
101
- expect(body).toContain('| v-001 |');
102
- // Header columns for deps + verdict + weakness are present.
103
- // (v1.31.x+ renders the deps column between kind and scope.)
104
- expect(body).toMatch(/\|\s*id\s*\|\s*label\s*\|\s*kind\s*\|\s*deps\s*\|\s*scope\s*\|\s*status\s*\|\s*verdict\s*\|\s*weakness\s*\|/);
105
- // Verdict cell shows pass.
106
- expect(body).toMatch(/\|\s*v-001\s*\|[^|]+\|\s*verify\s*\|[^|]+\|[^|]+\|[^|]+\|\s*pass\s*\|/);
107
- // Weakness is a 2-decimal number in [0, 1].
108
- expect(body).toMatch(/\|\s*pass\s*\|\s*(0\.\d{2}|1\.00)\s*\|/);
109
- });
110
- it('records a high weakness (loosely claimed) PASS when findings are vague', async () => {
111
- // Loosely-claimed reviewer: "looks good" → high weakness (close to 1).
112
- const writer = new WorkbenchWriter({ cwd: tmp, graphId: 'g-loose', goal: 'x' });
113
- writer.setNodes([{ id: 'v-002', kind: 'verify', label: 'r', status: 'pending' }]);
114
- writer.markStart('v-002');
115
- writer.markEnd('v-002', {
116
- status: 'done',
117
- durationMs: 50,
118
- findings: 'Looks good.\n\nVERDICT: PASS',
119
- });
120
- const out = await writer.flush();
121
- const body = await fs.readFile(out, 'utf8');
122
- const weaknessCell = body.match(/\|\s*pass\s*\|\s*(\d\.\d{2})\s*\|/);
123
- expect(weaknessCell).not.toBeNull();
124
- const weaknessValue = parseFloat(weaknessCell[1]);
125
- expect(weaknessValue).toBeGreaterThan(0.6);
126
- });
127
- it('records a low weakness (tightly asserted) PASS when findings pin specifics', async () => {
128
- // Tightly-asserted reviewer: pins paths + line + version → low weakness.
129
- const findings = [
130
- 'The function MUST always return EXACTLY the value at line 42, version 1.2.3.',
131
- 'I GUARANTEED the file is at /src/util.ts.',
132
- '',
133
- 'VERDICT: PASS',
134
- ].join('\n');
135
- const writer = new WorkbenchWriter({ cwd: tmp, graphId: 'g-tight', goal: 'x' });
136
- writer.setNodes([{ id: 'v-003', kind: 'spec', label: 'r', status: 'pending' }]);
137
- writer.markStart('v-003');
138
- writer.markEnd('v-003', { status: 'done', durationMs: 50, findings });
139
- const out = await writer.flush();
140
- const body = await fs.readFile(out, 'utf8');
141
- const weaknessCell = body.match(/\|\s*pass\s*\|\s*(\d\.\d{2})\s*\|/);
142
- expect(weaknessCell).not.toBeNull();
143
- const weaknessValue = parseFloat(weaknessCell[1]);
144
- expect(weaknessValue).toBeLessThan(0.5);
145
- });
146
- it('surfaces a deps column in the Wave table (root nodes show empty)', async () => {
147
- const writer = new WorkbenchWriter({ cwd: tmp, graphId: 'g-deps', goal: 'x' });
148
- writer.setNodes([
149
- { id: 't-001', kind: 'explore', label: 'a', status: 'pending' },
150
- { id: 't-002', kind: 'general', label: 'b', status: 'pending' },
151
- ]);
152
- writer.markStart('t-001');
153
- writer.markEnd('t-001', { status: 'done', durationMs: 10 });
154
- writer.markStart('t-002');
155
- writer.markEnd('t-002', {
156
- status: 'done',
157
- durationMs: 20,
158
- deps: ['t-001'],
159
- });
160
- const out = await writer.flush();
161
- const body = await fs.readFile(out, 'utf8');
162
- // Header has the new deps column.
163
- expect(body).toMatch(/\|\s*id\s*\|\s*label\s*\|\s*kind\s*\|\s*deps\s*\|/);
164
- // Root node: empty deps cell.
165
- expect(body).toMatch(/\|\s*t-001\s*\|[^|]+\|\s*explore\s*\|\s*\|/);
166
- // Dependent node: deps cell lists upstream id.
167
- expect(body).toMatch(/\|\s*t-002\s*\|[^|]+\|\s*general\s*\|\s*t-001\s*\|/);
168
- });
169
- it('lists multi-dep nodes comma-separated', async () => {
170
- const writer = new WorkbenchWriter({ cwd: tmp, graphId: 'g-mdep', goal: 'x' });
171
- writer.setNodes([
172
- { id: 'a', kind: 'explore', label: 'a', status: 'pending' },
173
- { id: 'b', kind: 'explore', label: 'b', status: 'pending' },
174
- { id: 'c', kind: 'general', label: 'c', status: 'pending' },
175
- ]);
176
- writer.markStart('a');
177
- writer.markEnd('a', { status: 'done', durationMs: 5 });
178
- writer.markStart('b');
179
- writer.markEnd('b', { status: 'done', durationMs: 5 });
180
- writer.markStart('c');
181
- writer.markEnd('c', { status: 'done', durationMs: 5, deps: ['a', 'b'] });
182
- const out = await writer.flush();
183
- const body = await fs.readFile(out, 'utf8');
184
- expect(body).toMatch(/\|\s*c\s*\|[^|]+\|\s*general\s*\|\s*a,\s*b\s*\|/);
185
- });
186
- it('marks a parallel wave', async () => {
187
- const w = new WorkbenchWriter({ cwd: tmp, graphId: 'g-5', goal: 'x' });
188
- w.markWave(['t0001', 't0002', 't0003']);
189
- const out = await w.flush();
190
- const body = await fs.readFile(out, 'utf8');
191
- expect(body).toMatch(/wave: t0001, t0002, t0003/);
192
- });
193
- it('preserves running status across setNodes (does NOT reset to pending)', async () => {
194
- const w = new WorkbenchWriter({ cwd: tmp, graphId: 'g-6', goal: 'x' });
195
- w.setNodes([{ id: 't0001', kind: 'general', label: 'do', status: 'pending' }]);
196
- w.markStart('t0001');
197
- // A second setNodes call shouldn't reset the running state.
198
- w.setNodes([{ id: 't0001', kind: 'general', label: 'do', status: 'pending' }]);
199
- const out = await w.flush();
200
- const body = await fs.readFile(out, 'utf8');
201
- expect(body).toContain('↑'); // running emoji
202
- });
203
- it('is a no-op when disabled', async () => {
204
- const w = new WorkbenchWriter({ cwd: tmp, graphId: 'g-7', goal: 'x', enabled: false });
205
- w.setNodes([{ id: 't0001', kind: 'explore', label: 'x', status: 'pending' }]);
206
- w.markStart('t0001');
207
- const out = await w.flush();
208
- expect(out).toBeNull();
209
- // No file was written.
210
- const file = path.join(tmp, '.zelari', 'radio', 'workbench-g-7.md');
211
- await expect(fs.access(file)).rejects.toThrow();
212
- });
213
- it('rewrites atomically (no partial state observable on tail)', async () => {
214
- const w = new WorkbenchWriter({ cwd: tmp, graphId: 'g-8', goal: 'x', debounceMs: 0 });
215
- w.setNodes([{ id: 't0001', kind: 'explore', label: 'a', status: 'pending' }]);
216
- await w.flush();
217
- w.markStart('t0001');
218
- w.markEnd('t0001', { status: 'done', durationMs: 50 });
219
- // Two flushes in quick succession: each must produce a complete file.
220
- await w.flush();
221
- const body = await fs.readFile(path.join(tmp, '.zelari', 'radio', 'workbench-g-8.md'), 'utf8');
222
- expect(body).toMatch(/✓/); // last write's status
223
- // No .tmp files left over.
224
- const dir = path.join(tmp, '.zelari', 'radio');
225
- const files = await fs.readdir(dir);
226
- const tmps = files.filter((f) => f.endsWith('.tmp'));
227
- expect(tmps).toEqual([]);
228
- });
229
- it('close() cancels the pending debounced write', async () => {
230
- const w = new WorkbenchWriter({ cwd: tmp, graphId: 'g-9', goal: 'x', debounceMs: 1000 });
231
- w.logEvent('will never land');
232
- w.close();
233
- await new Promise((r) => setTimeout(r, 1100));
234
- const file = path.join(tmp, '.zelari', 'radio', 'workbench-g-9.md');
235
- await expect(fs.access(file)).rejects.toThrow();
236
- });
237
- it('handles a graph with many nodes by truncating the table', async () => {
238
- const w = new WorkbenchWriter({ cwd: tmp, graphId: 'g-10', goal: 'x' });
239
- const nodes = [];
240
- for (let i = 0; i < 250; i++) {
241
- nodes.push({ id: `t${String(i).padStart(4, '0')}`, kind: 'explore', label: `n${i}`, status: 'pending' });
242
- }
243
- w.setNodes(nodes);
244
- const out = await w.flush();
245
- const body = await fs.readFile(out, 'utf8');
246
- // The table caps at 200 rows. (We don't assert exact count, just that
247
- // it's not 250 — the truncated set is present and the rest is gone.)
248
- const tableRows = body.split('\n').filter((l) => l.startsWith('| t')).length;
249
- expect(tableRows).toBeLessThanOrEqual(200);
250
- expect(tableRows).toBeGreaterThan(0);
251
- });
252
- });
253
- //# sourceMappingURL=workbench.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"workbench.test.js","sourceRoot":"","sources":["../../../src/cli/kraken/workbench.test.ts"],"names":[],"mappings":"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"}
@@ -1,130 +0,0 @@
1
- /**
2
- * Kraken workbench view — tests.
3
- *
4
- * Covers:
5
- * - `parseWorkbench` round-trips a workbench file produced by the writer
6
- * - Tolerant: partial / truncated input does not throw
7
- * - `formatWorkbenchForTerminal` produces a readable text block
8
- */
9
- import { describe, it, expect } from 'vitest';
10
- import { parseWorkbench, formatWorkbenchForTerminal } from './workbenchView.js';
11
- import { WorkbenchWriter } from './workbench.js';
12
- import { promises as fs } from 'node:fs';
13
- import os from 'node:os';
14
- import path from 'node:path';
15
- const SAMPLE = `# Kraken workbench
16
-
17
- **Goal:** refactor auth
18
- **Graph id:** \`g-abc\`
19
- **Started:** 2026-08-08T11:00:00.000Z · **Elapsed:** 00:01:23
20
-
21
- ## Progress: 2/5 · 1↑ · 0✗
22
-
23
- ## Wave
24
-
25
- | id | label | kind | scope | status | model | duration |
26
- |----|-------|------|-------|--------|-------|----------|
27
- | t0001 | map auth | explore | src/auth | ✓ | grok-3-mini | 4.0s |
28
- | t0002 | refactor | general | src/auth | ✓ | grok-4.5 | 12.3s |
29
- | t0003 | test | general | tests/auth | ↑ | grok-4.5 | |
30
- | t0004 | judge | verify | | pending | | |
31
- | t0005 | merge | merge | | pending | | |
32
-
33
- ## Events (latest 30)
34
-
35
- - 11:00:01 node_start t0001 map auth
36
- - 11:00:05 node_end t0001 done (4000ms)
37
- - 11:00:06 node_start t0002 refactor
38
- - 11:00:18 node_end t0002 done (12300ms)
39
- - 11:00:18 node_start t0003 test
40
- `;
41
- describe('parseWorkbench', () => {
42
- it('parses a full workbench file', () => {
43
- const p = parseWorkbench(SAMPLE);
44
- expect(p.goal).toBe('refactor auth');
45
- expect(p.graphId).toBe('g-abc');
46
- expect(p.started).toContain('2026-08-08');
47
- expect(p.progress).toContain('2/5');
48
- expect(p.nodes).toHaveLength(5);
49
- expect(p.nodes[0]).toMatchObject({
50
- id: 't0001',
51
- label: 'map auth',
52
- kind: 'explore',
53
- scope: 'src/auth',
54
- status: '✓',
55
- model: 'grok-3-mini',
56
- duration: '4.0s',
57
- });
58
- expect(p.events).toHaveLength(5);
59
- expect(p.events[0]).toEqual({ ts: '11:00:01', text: 'node_start t0001 map auth' });
60
- });
61
- it('returns empty for empty / null input', () => {
62
- expect(parseWorkbench('')).toEqual({
63
- goal: '', graphId: '', started: '', elapsed: '', progress: '',
64
- nodes: [], events: [],
65
- });
66
- expect(parseWorkbench(undefined)).toEqual({
67
- goal: '', graphId: '', started: '', elapsed: '', progress: '',
68
- nodes: [], events: [],
69
- });
70
- expect(parseWorkbench(null)).toEqual({
71
- goal: '', graphId: '', started: '', elapsed: '', progress: '',
72
- nodes: [], events: [],
73
- });
74
- });
75
- it('tolerates a truncated file (only header, no sections)', () => {
76
- const p = parseWorkbench('# Kraken workbench\n\n**Goal:** x\n');
77
- expect(p.goal).toBe('x');
78
- expect(p.nodes).toEqual([]);
79
- expect(p.events).toEqual([]);
80
- });
81
- it('tolerates a partial events section', () => {
82
- const p = parseWorkbench('# Kraken workbench\n\n## Events (latest 30)\n\n- 11:00:01 hello\n');
83
- expect(p.events).toHaveLength(1);
84
- expect(p.events[0].text).toBe('hello');
85
- });
86
- it('ignores rows that do not have enough cells', () => {
87
- const content = `
88
- ## Wave
89
-
90
- | id | label | kind | scope | status | model | duration |
91
- |----|-------|------|-------|--------|-------|----------|
92
- | t0001 ok
93
- `;
94
- const p = parseWorkbench(content);
95
- expect(p.nodes).toEqual([]); // row has only 1 cell, dropped
96
- });
97
- it('round-trips with the writer', async () => {
98
- const tmp = await fs.mkdtemp(path.join(os.tmpdir(), 'kraken-wb-view-'));
99
- const w = new WorkbenchWriter({ cwd: tmp, graphId: 'g-rt', goal: 'rt test', debounceMs: 0 });
100
- w.setNodes([
101
- { id: 't0001', kind: 'explore', label: 'a', status: 'done', model: 'm1', durationMs: 100 },
102
- { id: 't0002', kind: 'general', label: 'b', status: 'running', scope: ['src/x'] },
103
- ]);
104
- w.logEvent('event 1');
105
- w.logEvent('event 2');
106
- const out = await w.flush();
107
- const content = await fs.readFile(out, 'utf8');
108
- const parsed = parseWorkbench(content);
109
- expect(parsed.goal).toBe('rt test');
110
- expect(parsed.graphId).toBe('g-rt');
111
- expect(parsed.nodes).toHaveLength(2);
112
- expect(parsed.events.length).toBeGreaterThanOrEqual(2);
113
- });
114
- });
115
- describe('formatWorkbenchForTerminal', () => {
116
- it('includes the goal, progress, and recent events', () => {
117
- const out = formatWorkbenchForTerminal(parseWorkbench(SAMPLE));
118
- expect(out).toContain('[kraken] refactor auth');
119
- expect(out).toContain('[kraken] progress: 2/5');
120
- expect(out).toContain('[kraken] wave:');
121
- expect(out).toContain('t0001 map auth');
122
- expect(out).toContain('11:00:01 node_start t0001');
123
- });
124
- it('produces a readable block for an empty workbench', () => {
125
- const out = formatWorkbenchForTerminal(parseWorkbench(''));
126
- // Empty workbench → empty render (nothing to show).
127
- expect(out.trim()).toBe('');
128
- });
129
- });
130
- //# sourceMappingURL=workbenchView.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"workbenchView.test.js","sourceRoot":"","sources":["../../../src/cli/kraken/workbenchView.test.ts"],"names":[],"mappings":"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"}