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,158 +0,0 @@
1
- /**
2
- * headlessHistorySeed — Exit-1/E1.2 canonical model-context path.
3
- *
4
- * Proves: legacy `--history` is imported one-shot into a fresh spine log,
5
- * prior turns are then derived from events (never re-imported), resume
6
- * ignores fresh legacy input, and a disabled spine falls back to the
7
- * filtered legacy seed (declared discrete fallback).
8
- */
9
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
10
- import { promises as fs } from 'node:fs';
11
- import path from 'node:path';
12
- import os from 'node:os';
13
- import { openHeadlessSpine, seedHeadlessModelHistory } from './headlessSpine.js';
14
- import { readSessionLog, resolveSessionsDir } from '@zelari/core/session';
15
- let tmp;
16
- beforeEach(async () => {
17
- tmp = await fs.mkdtemp(path.join(os.tmpdir(), 'zelari-history-seed-'));
18
- });
19
- afterEach(async () => {
20
- delete process.env.ZELARI_SESSION_SPINE;
21
- await fs.rm(tmp, { recursive: true, force: true });
22
- });
23
- const legacy = [
24
- { role: 'user', content: 'build the login form' },
25
- {
26
- role: 'assistant',
27
- content: '<think>plan</think>Done — see ---QUESTION---\ncontinue?',
28
- },
29
- { role: 'system', content: 'stale system' },
30
- { role: 'tool', content: '{"ok":true}' },
31
- ];
32
- function eventsPath(sessionId) {
33
- return path.join(resolveSessionsDir({ baseDir: tmp }), sessionId, 'events.jsonl');
34
- }
35
- describe('seedHeadlessModelHistory', () => {
36
- it('imports legacy --history one-shot and returns the derived seed', async () => {
37
- const handle = await openHeadlessSpine({
38
- sessionId: 'seed-1',
39
- baseDir: tmp,
40
- quiet: true,
41
- });
42
- const seed = await seedHeadlessModelHistory(handle, legacy);
43
- expect(seed.source).toBe('spine-import');
44
- expect(seed.importedCount).toBe(2);
45
- // system/tool dropped; <think> + ---QUESTION--- preserved (binding policy)
46
- expect(seed.history).toHaveLength(2);
47
- expect(seed.history[0]).toEqual({ role: 'user', content: 'build the login form' });
48
- expect(seed.history[1]?.role).toBe('assistant');
49
- expect(seed.history[1]?.content).toContain('<think>plan</think>');
50
- expect(seed.history[1]?.content).toContain('---QUESTION---');
51
- // The imported turns are in the log — model-visible ⟺ logged (P1).
52
- const report = await readSessionLog(eventsPath('seed-1'));
53
- const texts = report.events
54
- .filter((e) => e.kind === 'user.message' || e.kind === 'assistant.message')
55
- .map((e) => e.data.text);
56
- expect(texts).toEqual(['build the login form', seed.history[1].content]);
57
- const imported = report.events.find((e) => e.kind === 'assistant.message');
58
- expect((imported?.data).imported).toBe('legacy-history');
59
- await handle.close('test-end');
60
- });
61
- it('derives from the log on resume and ignores new legacy input', async () => {
62
- const first = await openHeadlessSpine({
63
- sessionId: 'seed-2',
64
- baseDir: tmp,
65
- quiet: true,
66
- });
67
- const s1 = await seedHeadlessModelHistory(first, [
68
- { role: 'user', content: 'u-first' },
69
- { role: 'assistant', content: 'a-first' },
70
- ]);
71
- expect(s1.source).toBe('spine-import');
72
- await first.close('test-end');
73
- const resumed = await openHeadlessSpine({
74
- sessionId: 'seed-2',
75
- baseDir: tmp,
76
- quiet: true,
77
- });
78
- const s2 = await seedHeadlessModelHistory(resumed, [
79
- { role: 'user', content: 'u-second-should-be-ignored' },
80
- ]);
81
- expect(s2.source).toBe('spine');
82
- expect(s2.importedCount).toBe(0);
83
- expect(s2.history.map((m) => m.content)).toEqual(['u-first', 'a-first']);
84
- await resumed.close('test-end');
85
- });
86
- it('falls back to the filtered legacy seed when the spine is disabled', async () => {
87
- process.env.ZELARI_SESSION_SPINE = '0';
88
- const handle = await openHeadlessSpine({
89
- sessionId: 'seed-3',
90
- baseDir: tmp,
91
- quiet: true,
92
- });
93
- const seed = await seedHeadlessModelHistory(handle, legacy);
94
- expect(seed.source).toBe('legacy-fallback');
95
- expect(seed.importedCount).toBe(0);
96
- expect(seed.history.map((m) => m.role)).toEqual(['user', 'assistant']);
97
- await handle.close('test-end');
98
- });
99
- it('returns an empty seed for a fresh log with no legacy history', async () => {
100
- const handle = await openHeadlessSpine({
101
- sessionId: 'seed-4',
102
- baseDir: tmp,
103
- quiet: true,
104
- });
105
- const seed = await seedHeadlessModelHistory(handle);
106
- expect(seed).toEqual({ history: [], importedCount: 0, source: 'spine' });
107
- await handle.close('test-end');
108
- });
109
- it('keeps model-surface events in conversation order (invariant)', async () => {
110
- const handle = await openHeadlessSpine({
111
- sessionId: 'seed-5',
112
- baseDir: tmp,
113
- quiet: true,
114
- });
115
- const plain = [
116
- { role: 'user', content: 'plain user' },
117
- { role: 'assistant', content: 'plain assistant' },
118
- ];
119
- const seed = await seedHeadlessModelHistory(handle, plain);
120
- expect(seed.source).toBe('spine-import');
121
- const report = await readSessionLog(eventsPath('seed-5'));
122
- const kinds = report.events.map((e) => e.kind);
123
- expect(kinds.indexOf('user.message')).toBeLessThan(kinds.indexOf('assistant.message'));
124
- // Clean text round-trips byte-identical through import → derive.
125
- expect(seed.history).toEqual(plain);
126
- await handle.close('test-end');
127
- });
128
- it('derivedModelSeed: compacted → user, tool results dropped (shared policy)', async () => {
129
- const handle = await openHeadlessSpine({
130
- sessionId: 'seed-6',
131
- baseDir: tmp,
132
- quiet: true,
133
- });
134
- await seedHeadlessModelHistory(handle, [{ role: 'user', content: 'u1' }]);
135
- // A compaction event lands on the spine (TUI /compact or budget policy).
136
- handle.spine.mirrorBrainEvent({
137
- type: 'session_compacted',
138
- summary: 'sum-of-old-turns',
139
- });
140
- await handle.spine.flush();
141
- const afterCompact = await seedHeadlessModelHistory(handle, []);
142
- expect(afterCompact.source).toBe('spine');
143
- expect(afterCompact.history.map((m) => `${m.role}:${m.content}`)).toContain('user:sum-of-old-turns');
144
- // Tool results derive as orphans (no assistant tool_calls block) and
145
- // must NOT reach the model seed.
146
- handle.spine.mirrorBrainEvent({
147
- type: 'tool_execution_end',
148
- toolCallId: 'call-1',
149
- result: 'raw tool output',
150
- isError: false,
151
- });
152
- await handle.spine.flush();
153
- const afterTool = await seedHeadlessModelHistory(handle, []);
154
- expect(afterTool.history.some((m) => m.role === 'tool')).toBe(false);
155
- await handle.close('test-end');
156
- });
157
- });
158
- //# sourceMappingURL=headlessHistorySeed.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"headlessHistorySeed.test.js","sourceRoot":"","sources":["../../src/cli/headlessHistorySeed.test.ts"],"names":[],"mappings":"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"}
@@ -1,83 +0,0 @@
1
- /**
2
- * headlessSessionEvent — Exit-1/E1.4 desktop resume-from-spine contract.
3
- *
4
- * Proves the `session_started` NDJSON event advertised by every headless
5
- * dispatch mode carries the spine session id hosts (Desktop) must replay
6
- * via `--resume`: turn 1 announces a fresh id, turn 2 resumes the SAME id
7
- * (seq continues), and the kill-switch announces `disabled` so hosts know
8
- * the spine will not back the conversation.
9
- */
10
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
11
- import { promises as fs } from 'node:fs';
12
- import path from 'node:path';
13
- import os from 'node:os';
14
- import { openHeadlessSpine, sessionStartedEvent, } from './headlessSpine.js';
15
- import { readSessionLog, resolveSessionsDir } from '@zelari/core/session';
16
- let tmp;
17
- beforeEach(async () => {
18
- tmp = await fs.mkdtemp(path.join(os.tmpdir(), 'zelari-session-event-'));
19
- });
20
- afterEach(async () => {
21
- delete process.env.ZELARI_SESSION_SPINE;
22
- await fs.rm(tmp, { recursive: true, force: true });
23
- });
24
- function eventsPath(sessionId) {
25
- return path.join(resolveSessionsDir({ baseDir: tmp }), sessionId, 'events.jsonl');
26
- }
27
- describe('sessionStartedEvent (E1.4)', () => {
28
- it('advertises the spine session id with status ok', async () => {
29
- const handle = await openHeadlessSpine({
30
- sessionId: 'desk-turn-1',
31
- baseDir: tmp,
32
- quiet: true,
33
- });
34
- expect(sessionStartedEvent(handle)).toEqual({
35
- type: 'session_started',
36
- sessionId: 'desk-turn-1',
37
- spine: 'active',
38
- });
39
- });
40
- it('round-trips: resuming the advertised id continues the same log (seq)', async () => {
41
- // Turn 1: host captures the advertised session id.
42
- const turn1 = await openHeadlessSpine({
43
- sessionId: 'desk-conversation',
44
- baseDir: tmp,
45
- quiet: true,
46
- });
47
- const announced = sessionStartedEvent(turn1);
48
- turn1.userMessage('build the login form');
49
- await turn1.close('turn-1-done');
50
- // Turn 2: host replays the same id (--resume semantics: adopt, not new).
51
- const turn2 = await openHeadlessSpine({
52
- sessionId: announced.sessionId,
53
- baseDir: tmp,
54
- quiet: true,
55
- });
56
- expect(sessionStartedEvent(turn2).sessionId).toBe(announced.sessionId);
57
- turn2.userMessage('procedi');
58
- await turn2.close('turn-2-done');
59
- // The spine log is ONE conversation: user turns in order, seq continues.
60
- const report = await readSessionLog(eventsPath(announced.sessionId));
61
- const events = report.events;
62
- const userTurns = events
63
- .filter((e) => e.kind === 'user.message')
64
- .map((e) => e.data.text);
65
- expect(userTurns).toEqual(['build the login form', 'procedi']);
66
- const seqs = events.map((e) => e.seq);
67
- expect(seqs).toEqual([...seqs].sort((a, b) => a - b));
68
- });
69
- it('announces disabled under the kill-switch (host keeps history fallback)', async () => {
70
- process.env.ZELARI_SESSION_SPINE = '0';
71
- const handle = await openHeadlessSpine({
72
- sessionId: 'desk-killswitch',
73
- baseDir: tmp,
74
- quiet: true,
75
- });
76
- expect(sessionStartedEvent(handle)).toEqual({
77
- type: 'session_started',
78
- sessionId: 'desk-killswitch',
79
- spine: 'disabled',
80
- });
81
- });
82
- });
83
- //# sourceMappingURL=headlessSessionEvent.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"headlessSessionEvent.test.js","sourceRoot":"","sources":["../../src/cli/headlessSessionEvent.test.ts"],"names":[],"mappings":"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"}
@@ -1,153 +0,0 @@
1
- /**
2
- * headlessSpine + parseHeadlessFlags 2.0 host wiring.
3
- *
4
- * Covers: profile defaults, flag parse/validation, dual-write user.message,
5
- * interrupt without session.ended, resume seq continuation, portable export.
6
- */
7
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
8
- import { promises as fs } from 'node:fs';
9
- import path from 'node:path';
10
- import os from 'node:os';
11
- import { parseHeadlessFlags, defaultProfileForMode } from './headless.js';
12
- import { openHeadlessSpine, resolveHeadlessProfileId, exportSessionById, missionStateFromSpine, } from './headlessSpine.js';
13
- import { readSessionLog } from '@zelari/core/session';
14
- let tmp;
15
- beforeEach(async () => {
16
- tmp = await fs.mkdtemp(path.join(os.tmpdir(), 'zelari-headless-spine-'));
17
- });
18
- afterEach(async () => {
19
- await fs.rm(tmp, { recursive: true, force: true });
20
- });
21
- describe('defaultProfileForMode / resolveHeadlessProfileId', () => {
22
- it('maps mode → profile and lets an explicit id win', () => {
23
- expect(defaultProfileForMode('kraken')).toBe('kraken/v1');
24
- expect(defaultProfileForMode('council')).toBe('council/v1');
25
- expect(defaultProfileForMode('zelari')).toBe('mission/v1');
26
- expect(resolveHeadlessProfileId('kraken')).toBe('kraken/v1');
27
- expect(resolveHeadlessProfileId('kraken', 'minimal/v1')).toBe('minimal/v1');
28
- });
29
- it('throws on an unknown explicit profile', () => {
30
- expect(() => resolveHeadlessProfileId('kraken', 'nope/v9')).toThrow(/Unknown profile/);
31
- });
32
- });
33
- describe('parseHeadlessFlags 2.0 flags', () => {
34
- it('accepts --profile / --resume / --export-session / --strict-done', () => {
35
- const res = parseHeadlessFlags([
36
- '--headless',
37
- '--task',
38
- 'do the thing',
39
- '--profile',
40
- 'minimal/v1',
41
- '--resume',
42
- 'sess-abc',
43
- '--export-session',
44
- '-',
45
- '--strict-done',
46
- ]);
47
- expect(res.error).toBeUndefined();
48
- expect(res.options).toMatchObject({
49
- task: 'do the thing',
50
- profile: 'minimal/v1',
51
- resumeSessionId: 'sess-abc',
52
- exportSessionPath: '-',
53
- strictDone: true,
54
- });
55
- });
56
- it('rejects an unknown --profile at parse time', () => {
57
- const res = parseHeadlessFlags(['--headless', '--task', 'x', '--profile', 'ghost/v1']);
58
- expect(res.options).toBeNull();
59
- expect(res.error).toMatch(/Unknown profile/);
60
- });
61
- it('--resume without an id is a user error', () => {
62
- const res = parseHeadlessFlags(['--headless', '--task', 'x', '--resume']);
63
- expect(res.options).toBeNull();
64
- expect(res.error).toMatch(/--resume requires/);
65
- });
66
- });
67
- describe('openHeadlessSpine', () => {
68
- it('records profile + user.message and closes with session.ended', async () => {
69
- const handle = await openHeadlessSpine({
70
- sessionId: 'h-a',
71
- mode: 'kraken',
72
- profile: 'minimal/v1',
73
- workspace: tmp,
74
- baseDir: tmp,
75
- quiet: true,
76
- });
77
- expect(handle.profileId).toBe('minimal/v1');
78
- handle.userMessage('write a test');
79
- handle.observe({
80
- type: 'message_delta',
81
- messageId: 'm1',
82
- delta: 'ok',
83
- id: 'e1',
84
- ts: 1,
85
- sessionId: 'h-a',
86
- });
87
- handle.observe({
88
- type: 'message_end',
89
- messageId: 'm1',
90
- totalLength: 2,
91
- finishReason: 'stop',
92
- id: 'e2',
93
- ts: 2,
94
- sessionId: 'h-a',
95
- });
96
- await handle.close('completed');
97
- const report = await readSessionLog(path.join(tmp, 'h-a', 'events.jsonl'));
98
- const kinds = report.events.map((e) => e.kind);
99
- expect(kinds[0]).toBe('session.started');
100
- expect(kinds).toContain('user.message');
101
- expect(kinds).toContain('assistant.message');
102
- expect(kinds.at(-1)).toBe('session.ended');
103
- expect(report.events[0].data.profile).toBe('minimal/v1');
104
- });
105
- it('interrupt releases the lock WITHOUT session.ended (resumable)', async () => {
106
- const handle = await openHeadlessSpine({
107
- sessionId: 'h-b',
108
- mode: 'zelari',
109
- baseDir: tmp,
110
- quiet: true,
111
- });
112
- handle.userMessage('long mission');
113
- handle.missionPhase('build', 'impl-1');
114
- await handle.interrupt('SIGINT');
115
- const report = await readSessionLog(path.join(tmp, 'h-b', 'events.jsonl'));
116
- expect(report.events.some((e) => e.kind === 'session.ended')).toBe(false);
117
- expect(report.events.some((e) => e.kind === 'mission.phase')).toBe(true);
118
- const state = await missionStateFromSpine('h-b', tmp);
119
- expect(state).not.toBeNull();
120
- expect(state.interrupted).toBe(true);
121
- expect(state.phase).toBe('build');
122
- const resumed = await openHeadlessSpine({
123
- sessionId: 'h-b',
124
- mode: 'zelari',
125
- baseDir: tmp,
126
- quiet: true,
127
- });
128
- resumed.userMessage('continue');
129
- await resumed.close('completed');
130
- const again = await readSessionLog(path.join(tmp, 'h-b', 'events.jsonl'));
131
- expect(again.events.some((e) => e.kind === 'session.resumed')).toBe(true);
132
- again.events.forEach((e, i) => expect(e.seq).toBe(i + 1));
133
- });
134
- it('exportSessionById produces zelari-session-export/1', async () => {
135
- const handle = await openHeadlessSpine({
136
- sessionId: 'h-c',
137
- mode: 'council',
138
- baseDir: tmp,
139
- quiet: true,
140
- });
141
- handle.userMessage('design this');
142
- await handle.close('completed');
143
- const exported = await exportSessionById('h-c', tmp);
144
- expect(exported.ok).toBe(true);
145
- if (!exported.ok)
146
- return;
147
- const parsed = JSON.parse(exported.json);
148
- expect(parsed.format).toBe('zelari-session-export');
149
- expect(parsed.version).toBe(1);
150
- expect(parsed.sessionId).toBe('h-c');
151
- });
152
- });
153
- //# sourceMappingURL=headlessSpine.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"headlessSpine.test.js","sourceRoot":"","sources":["../../src/cli/headlessSpine.test.ts"],"names":[],"mappings":"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"}
@@ -1,135 +0,0 @@
1
- /**
2
- * observationStore + retrieve_observation — Fase 2 acceptance.
3
- */
4
- import { afterEach, describe, expect, it } from 'vitest';
5
- import { promises as fs } from 'node:fs';
6
- import os from 'node:os';
7
- import path from 'node:path';
8
- import { SessionJsonlWriter } from '@zelari/core/harness';
9
- import { createBrainEvent } from '@zelari/core/events';
10
- import { getObservationBySeq, getSeqForToolCallId, indexEventsForTests, ingestLiveEvent, invalidateObservationIndex, loadObservationIndex, } from './observationStore.js';
11
- import { formatObservationStub } from './sessionSurface.js';
12
- import { createRetrieveObservationTool, parseSeqRef } from '../tools/retrieveObservation.js';
13
- const abort = new AbortController().signal;
14
- function ctx(sessionId) {
15
- return {
16
- signal: abort,
17
- cwd: process.cwd(),
18
- sessionId,
19
- audit: () => undefined,
20
- };
21
- }
22
- describe('parseSeqRef', () => {
23
- it('accepts number, #N and ref=#N', () => {
24
- expect(parseSeqRef(12)).toBe(12);
25
- expect(parseSeqRef('#12')).toBe(12);
26
- expect(parseSeqRef('ref=#12')).toBe(12);
27
- expect(parseSeqRef('OBSERVATION ref=#3')).toBe(3);
28
- expect(parseSeqRef('nope')).toBeNull();
29
- expect(parseSeqRef(0)).toBeNull();
30
- });
31
- });
32
- describe('observationStore from JSONL', () => {
33
- let dir;
34
- afterEach(async () => {
35
- invalidateObservationIndex();
36
- if (dir)
37
- await fs.rm(dir, { recursive: true, force: true });
38
- });
39
- it('assigns monotonic 1-based seq in file order and rematerializes', async () => {
40
- dir = await fs.mkdtemp(path.join(os.tmpdir(), 'zelari-obs-'));
41
- const sid = 'sess-a';
42
- const w = new SessionJsonlWriter(sid, { baseDir: dir, flushIntervalMs: 60_000 });
43
- const start1 = createBrainEvent('tool_execution_start', sid, {
44
- toolCallId: 'c1',
45
- toolName: 'read_file',
46
- args: { path: 'a.ts' },
47
- });
48
- const end1 = createBrainEvent('tool_execution_end', sid, {
49
- toolCallId: 'c1',
50
- result: 'FILE-ONE-BODY',
51
- isError: false,
52
- durationMs: 11,
53
- });
54
- const start2 = createBrainEvent('tool_execution_start', sid, {
55
- toolCallId: 'c2',
56
- toolName: 'grep_content',
57
- args: { pattern: 'x' },
58
- });
59
- const end2 = createBrainEvent('tool_execution_end', sid, {
60
- toolCallId: 'c2',
61
- result: 'FILE-TWO-BODY',
62
- isError: false,
63
- durationMs: 22,
64
- });
65
- void w.append(start1);
66
- void w.append(end1);
67
- void w.append(start2);
68
- void w.append(end2);
69
- await w.flush();
70
- const index = await loadObservationIndex(sid, dir);
71
- expect(index.bySeq.size).toBe(2);
72
- expect(await getSeqForToolCallId(sid, 'c2', dir)).toBe(2);
73
- const rec = await getObservationBySeq(sid, 1, dir);
74
- expect(rec?.result).toBe('FILE-ONE-BODY');
75
- expect(rec?.toolName).toBe('read_file');
76
- const tool = createRetrieveObservationTool({ sessionId: sid, baseDir: dir });
77
- const hit = await tool.execute({ seq: '#2' }, ctx(sid));
78
- expect(hit.ok).toBe(true);
79
- if (hit.ok) {
80
- expect(hit.value.result).toBe('FILE-TWO-BODY');
81
- expect(hit.value.tool).toBe('grep_content');
82
- expect(hit.value.seq).toBe(2);
83
- }
84
- const miss = await tool.execute({ seq: 99 }, ctx(sid));
85
- expect(miss.ok).toBe(false);
86
- await w.close();
87
- });
88
- it('ingestLiveEvent is idempotent and retrieve works before flush', async () => {
89
- const sid = 'live-sess';
90
- const start = createBrainEvent('tool_execution_start', sid, {
91
- toolCallId: 'live-1',
92
- toolName: 'list_files',
93
- args: {},
94
- });
95
- const end = createBrainEvent('tool_execution_end', sid, {
96
- toolCallId: 'live-1',
97
- result: 'LIVE-BODY',
98
- isError: false,
99
- durationMs: 5,
100
- });
101
- ingestLiveEvent(sid, start);
102
- ingestLiveEvent(sid, end);
103
- ingestLiveEvent(sid, end); // idempotent
104
- const rec = await getObservationBySeq(sid, 1);
105
- expect(rec?.result).toBe('LIVE-BODY');
106
- expect(await getSeqForToolCallId(sid, 'live-1')).toBe(1);
107
- });
108
- it('refuses to rematerialize a stub that leaked into the log', async () => {
109
- const sid = 'stub-sess';
110
- const stub = formatObservationStub({ seq: 1, tool: 'read_file', bytes: 10 });
111
- indexEventsForTests(sid, [
112
- createBrainEvent('tool_execution_end', sid, {
113
- toolCallId: 's1',
114
- result: stub,
115
- isError: false,
116
- durationMs: 1,
117
- }),
118
- ]);
119
- const tool = createRetrieveObservationTool({ sessionId: sid, baseDir: os.tmpdir() });
120
- const res = await tool.execute({ seq: 1 }, ctx(sid));
121
- expect(res.ok).toBe(false);
122
- if (!res.ok)
123
- expect(res.meta?.warnings).toContain('STUB_IN_LOG');
124
- });
125
- });
126
- describe('retrieve_observation session guard', () => {
127
- it('fails clearly without a real session id', async () => {
128
- const tool = createRetrieveObservationTool();
129
- const res = await tool.execute({ seq: 1 }, ctx('cli'));
130
- expect(res.ok).toBe(false);
131
- if (!res.ok)
132
- expect(res.meta?.warnings).toContain('NO_SESSION');
133
- });
134
- });
135
- //# sourceMappingURL=observationStore.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"observationStore.test.js","sourceRoot":"","sources":["../../../src/cli/hooks/observationStore.test.ts"],"names":[],"mappings":"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"}