zelari-code 1.48.1 → 1.49.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 (55) hide show
  1. package/dist/cli/desktopConfig.js +51 -4
  2. package/dist/cli/desktopConfig.js.map +1 -1
  3. package/dist/cli/hooks/useChatTurn.js +80 -0
  4. package/dist/cli/hooks/useChatTurn.js.map +1 -1
  5. package/dist/cli/kraken/candidateRegistry.js +195 -0
  6. package/dist/cli/kraken/candidateRegistry.js.map +1 -0
  7. package/dist/cli/kraken/candidateRegistry.test.js +211 -0
  8. package/dist/cli/kraken/candidateRegistry.test.js.map +1 -0
  9. package/dist/cli/kraken/completionGate.js +116 -0
  10. package/dist/cli/kraken/completionGate.js.map +1 -0
  11. package/dist/cli/kraken/completionGate.test.js +172 -0
  12. package/dist/cli/kraken/completionGate.test.js.map +1 -0
  13. package/dist/cli/kraken/metrics.js +96 -0
  14. package/dist/cli/kraken/metrics.js.map +1 -0
  15. package/dist/cli/kraken/metrics.test.js +145 -0
  16. package/dist/cli/kraken/metrics.test.js.map +1 -0
  17. package/dist/cli/kraken/selectionPlaybook.js +23 -0
  18. package/dist/cli/kraken/selectionPlaybook.js.map +1 -0
  19. package/dist/cli/kraken/selectionPlaybook.test.js +55 -0
  20. package/dist/cli/kraken/selectionPlaybook.test.js.map +1 -0
  21. package/dist/cli/kraken/turnRuntime.js +207 -0
  22. package/dist/cli/kraken/turnRuntime.js.map +1 -0
  23. package/dist/cli/kraken/turnRuntime.test.js +377 -0
  24. package/dist/cli/kraken/turnRuntime.test.js.map +1 -0
  25. package/dist/cli/kraken/verifier.js +233 -0
  26. package/dist/cli/kraken/verifier.js.map +1 -0
  27. package/dist/cli/kraken/verifier.test.js +232 -0
  28. package/dist/cli/kraken/verifier.test.js.map +1 -0
  29. package/dist/cli/kraken/verifierSettings.test.js +237 -0
  30. package/dist/cli/kraken/verifierSettings.test.js.map +1 -0
  31. package/dist/cli/kraken/verifyReport.js +115 -0
  32. package/dist/cli/kraken/verifyReport.js.map +1 -0
  33. package/dist/cli/kraken/verifyReport.test.js +111 -0
  34. package/dist/cli/kraken/verifyReport.test.js.map +1 -0
  35. package/dist/cli/main.bundled.js +1343 -107
  36. package/dist/cli/main.bundled.js.map +4 -4
  37. package/dist/cli/providerConfig.js +46 -0
  38. package/dist/cli/providerConfig.js.map +1 -1
  39. package/dist/cli/runHeadless.js +85 -0
  40. package/dist/cli/runHeadless.js.map +1 -1
  41. package/dist/cli/toolRegistry.js +50 -6
  42. package/dist/cli/toolRegistry.js.map +1 -1
  43. package/dist/cli/tools/krakenSelectTool.js +165 -0
  44. package/dist/cli/tools/krakenSelectTool.js.map +1 -0
  45. package/dist/cli/tools/krakenSelectTool.test.js +246 -0
  46. package/dist/cli/tools/krakenSelectTool.test.js.map +1 -0
  47. package/dist/cli/tools/taskTool.dynamicChecks.test.js +156 -0
  48. package/dist/cli/tools/taskTool.dynamicChecks.test.js.map +1 -0
  49. package/dist/cli/tools/taskTool.js +174 -6
  50. package/dist/cli/tools/taskTool.js.map +1 -1
  51. package/dist/cli/tools/taskTool.planSafety.test.js +280 -0
  52. package/dist/cli/tools/taskTool.planSafety.test.js.map +1 -0
  53. package/dist/cli/tools/taskTool.verifyReport.test.js +140 -0
  54. package/dist/cli/tools/taskTool.verifyReport.test.js.map +1 -0
  55. package/package.json +1 -1
@@ -0,0 +1,280 @@
1
+ /**
2
+ * taskTool.planSafety.test — Fase 1 / ADR-0020 (Kraken Verified Selection).
3
+ *
4
+ * DoD della Fase 1:
5
+ * - PLAN può spawnare explore (task registrato, policy explore-only)
6
+ * - PLAN non può spawnare general né verify
7
+ * - PLAN non espone write/bash (read-only invariato)
8
+ * - BUILD task continua a comportarsi come prima
9
+ * - Cancel parent cancella il tentacolo (signal propagato a runTentacle)
10
+ */
11
+ import { describe, expect, it, beforeEach } from 'vitest';
12
+ import { tmpdir } from 'node:os';
13
+ import path from 'node:path';
14
+ import fs from 'node:fs';
15
+ import { fileURLToPath } from 'node:url';
16
+ import { ToolRegistry } from '@zelari/core/harness/tools/registry';
17
+ import { createBuiltinToolRegistry } from '../toolRegistry.js';
18
+ import { createTaskTool, resetTaskSpawnCount, } from './taskTool.js';
19
+ import { isKrakenSelectionEnabled, krakenCandidates, resetKrakenCandidates, } from '../kraken/candidateRegistry.js';
20
+ import { AuditLogger } from '../safety/auditLogger.js';
21
+ import { defaultPermissionPolicy } from '../safety/toolPermissions.js';
22
+ const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', '..');
23
+ function tmpRoot() {
24
+ return fs.mkdtempSync(path.join(tmpdir(), 'zelari-plan-safe-'));
25
+ }
26
+ function makeRegistry(extra = {}) {
27
+ return createBuiltinToolRegistry({
28
+ root: repoRoot,
29
+ lspProvider: null,
30
+ audit: new AuditLogger(path.join(tmpdir(), `zelari-plansafe-${Date.now()}-${Math.random().toString(36).slice(2)}.log`)),
31
+ permissionPolicy: defaultPermissionPolicy({ auto: true }),
32
+ ...extra,
33
+ });
34
+ }
35
+ function makeCtx(cwd = tmpRoot()) {
36
+ return {
37
+ signal: new AbortController().signal,
38
+ cwd,
39
+ audit: () => undefined,
40
+ sessionId: 'plan-safety-test',
41
+ };
42
+ }
43
+ /** Deps fake: null context = "no provider" path, enough to observe the gate. */
44
+ function probeDeps() {
45
+ const calls = [];
46
+ const deps = {
47
+ createSubAgentContext: async ({ agent }) => {
48
+ calls.push(agent);
49
+ return null;
50
+ },
51
+ allowWorktree: false,
52
+ };
53
+ return { deps, calls };
54
+ }
55
+ /** Deps fake with a valid context + scripted harness (signal tests). */
56
+ function scriptedDeps() {
57
+ let started = 0;
58
+ const deps = {
59
+ createSubAgentContext: async ({ agent }) => {
60
+ const ctx = {
61
+ providerStream: (() => {
62
+ throw new Error('not invoked by the scripted harness');
63
+ }),
64
+ model: 'test-model',
65
+ provider: 'test-provider',
66
+ registry: new ToolRegistry(),
67
+ tools: [],
68
+ agent,
69
+ };
70
+ return ctx;
71
+ },
72
+ harnessFactory: () => ({
73
+ run: async function* () {
74
+ started++;
75
+ yield { type: 'message_start' };
76
+ yield { type: 'message_delta', delta: 'tentacle conclusion' };
77
+ yield { type: 'message_end' };
78
+ },
79
+ }),
80
+ allowWorktree: false,
81
+ };
82
+ return { deps, harnessStarted: () => started };
83
+ }
84
+ describe('registry gating (ADR-0020 Fase 1)', () => {
85
+ it('planMode registry registers task AND stays read-only', () => {
86
+ const { tools } = makeRegistry({ planMode: true });
87
+ const names = tools.map((t) => t.name);
88
+ expect(names).toContain('task');
89
+ expect(names).not.toContain('write_file');
90
+ expect(names).not.toContain('edit_file');
91
+ expect(names).not.toContain('apply_diff');
92
+ expect(names).not.toContain('bash');
93
+ });
94
+ it('planMode task is wired explore-only (restricted schema + description)', () => {
95
+ const { registry } = makeRegistry({ planMode: true });
96
+ const task = registry.get('task');
97
+ expect(task).toBeTruthy();
98
+ expect(task?.description).toContain('RESTRICTED in this mode');
99
+ // zod enum narrowed: general is not a valid value anymore
100
+ const bad = task?.inputSchema
101
+ ?.safeParse({ description: 'd', prompt: 'p', agent: 'general' });
102
+ expect(bad?.success).toBe(false);
103
+ const good = task?.inputSchema
104
+ ?.safeParse({ description: 'd', prompt: 'p', agent: 'explore' });
105
+ expect(good?.success).toBe(true);
106
+ });
107
+ it('planExploreTask=false restores the pre-ADR-0020 behaviour (no task in plan)', () => {
108
+ const { tools } = makeRegistry({ planMode: true, planExploreTask: false });
109
+ expect(tools.map((t) => t.name)).not.toContain('task');
110
+ });
111
+ it('full BUILD registry keeps task unrestricted (regression)', () => {
112
+ const { registry, tools } = makeRegistry();
113
+ expect(tools.map((t) => t.name)).toContain('task');
114
+ expect(registry.get('task')?.description).not.toContain('RESTRICTED in this mode');
115
+ });
116
+ it('explicit readOnly registry omits task (sub-agent anti-recursion, regression)', () => {
117
+ const { tools } = makeRegistry({ readOnly: true });
118
+ expect(tools.map((t) => t.name)).not.toContain('task');
119
+ });
120
+ it('explore sub-profile omits task (no nesting, regression)', () => {
121
+ const { tools } = makeRegistry({ profile: 'explore' });
122
+ expect(tools.map((t) => t.name)).not.toContain('task');
123
+ });
124
+ });
125
+ describe('task policy (ADR-0020 Fase 1)', () => {
126
+ beforeEach(() => {
127
+ resetTaskSpawnCount();
128
+ });
129
+ it('explore-only policy rejects agent=general BEFORE spawning or consuming budget', async () => {
130
+ const { deps, calls } = probeDeps();
131
+ const tool = createTaskTool(deps, { allowedAgents: ['explore'] });
132
+ const res = await tool.execute({ description: 'd', prompt: 'p', agent: 'general' }, makeCtx());
133
+ expect(res.ok).toBe(false);
134
+ if (!res.ok) {
135
+ expect(res.error).toMatch(/not allowed in this mode/i);
136
+ expect(res.error).toContain('explore');
137
+ }
138
+ expect(calls).toHaveLength(0);
139
+ // budget NOT consumed: the very next spawn is still allowed
140
+ const next = await tool.execute({ description: 'd', prompt: 'p', agent: 'verify' }, makeCtx());
141
+ expect(next.ok).toBe(false);
142
+ if (!next.ok)
143
+ expect(next.error).toMatch(/not allowed in this mode/i);
144
+ expect(calls).toHaveLength(0);
145
+ });
146
+ it('explore-only policy accepts the default agent (explore reaches the context factory)', async () => {
147
+ const { deps, calls } = probeDeps();
148
+ const tool = createTaskTool(deps, { allowedAgents: ['explore'] });
149
+ const res = await tool.execute({ description: 'd', prompt: 'p' }, makeCtx());
150
+ expect(calls).toEqual(['explore']);
151
+ // fake context is null → "no provider", which PROVES we got past the gate
152
+ expect(res.ok).toBe(false);
153
+ if (!res.ok)
154
+ expect(res.error).toMatch(/no provider/);
155
+ });
156
+ it('unrestricted BUILD tool still accepts general (regression)', async () => {
157
+ const { deps, calls } = probeDeps();
158
+ const tool = createTaskTool(deps);
159
+ const res = await tool.execute({ description: 'd', prompt: 'p', agent: 'general' }, makeCtx());
160
+ expect(calls).toEqual(['general']);
161
+ expect(res.ok).toBe(false);
162
+ if (!res.ok)
163
+ expect(res.error).toMatch(/no provider/);
164
+ });
165
+ });
166
+ describe('cancellation propagation (ADR-0020 Fase 1)', () => {
167
+ beforeEach(() => {
168
+ resetTaskSpawnCount();
169
+ });
170
+ it('an already-aborted parent signal cancels the tentacle instead of running it', async () => {
171
+ const { deps, harnessStarted } = scriptedDeps();
172
+ const tool = createTaskTool(deps);
173
+ const controller = new AbortController();
174
+ controller.abort();
175
+ const res = await tool.execute({ description: 'd', prompt: 'p', agent: 'explore' }, { ...makeCtx(), signal: controller.signal });
176
+ expect(res.ok).toBe(false);
177
+ if (!res.ok)
178
+ expect(res.error).toMatch(/cancelled/i);
179
+ expect(harnessStarted()).toBe(0);
180
+ });
181
+ it('a live signal does not break the normal tentacle run (regression)', async () => {
182
+ const { deps, harnessStarted } = scriptedDeps();
183
+ const tool = createTaskTool(deps);
184
+ const res = await tool.execute({ description: 'd', prompt: 'p', agent: 'explore' }, makeCtx());
185
+ expect(res.ok).toBe(true);
186
+ if (res.ok)
187
+ expect(res.value.result).toContain('tentacle conclusion');
188
+ expect(harnessStarted()).toBe(1);
189
+ });
190
+ });
191
+ describe('candidate contract (ADR-0020 Fase 3)', () => {
192
+ const ctx = makeCtx();
193
+ beforeEach(() => {
194
+ resetTaskSpawnCount();
195
+ resetKrakenCandidates();
196
+ });
197
+ it('purpose=candidate is refused while the alpha flag is OFF', async () => {
198
+ const prev = process.env.ZELARI_KRAKEN_SELECTION;
199
+ delete process.env.ZELARI_KRAKEN_SELECTION;
200
+ try {
201
+ const { deps, calls } = probeDeps();
202
+ const tool = createTaskTool(deps);
203
+ const res = await tool.execute({ description: 'd', prompt: 'p', purpose: 'candidate' }, ctx);
204
+ expect(res.ok).toBe(false);
205
+ if (!res.ok)
206
+ expect(res.error).toMatch(/ZELARI_KRAKEN_SELECTION=1/);
207
+ expect(calls).toHaveLength(0);
208
+ expect(krakenCandidates()).toHaveLength(0);
209
+ }
210
+ finally {
211
+ if (prev === undefined)
212
+ delete process.env.ZELARI_KRAKEN_SELECTION;
213
+ else
214
+ process.env.ZELARI_KRAKEN_SELECTION = prev;
215
+ }
216
+ });
217
+ it('candidate forces agent=explore (general rejected without spawning)', async () => {
218
+ process.env.ZELARI_KRAKEN_SELECTION = '1';
219
+ try {
220
+ const { deps, calls } = probeDeps();
221
+ const tool = createTaskTool(deps);
222
+ const res = await tool.execute({ description: 'd', prompt: 'p', agent: 'general', purpose: 'candidate' }, ctx);
223
+ expect(res.ok).toBe(false);
224
+ if (!res.ok)
225
+ expect(res.error).toMatch(/forces agent=explore/);
226
+ expect(calls).toHaveLength(0);
227
+ expect(isKrakenSelectionEnabled()).toBe(true);
228
+ }
229
+ finally {
230
+ delete process.env.ZELARI_KRAKEN_SELECTION;
231
+ }
232
+ });
233
+ it('candidate failures are registered as malformed (slot consumed, evidence preserved)', async () => {
234
+ process.env.ZELARI_KRAKEN_SELECTION = '1';
235
+ try {
236
+ // probeDeps returns a null context → tentacle fails with no provider
237
+ const { deps } = probeDeps();
238
+ const tool = createTaskTool(deps);
239
+ const res = await tool.execute({ description: 'd', prompt: 'p', purpose: 'candidate' }, ctx);
240
+ expect(res.ok).toBe(false);
241
+ const all = krakenCandidates();
242
+ expect(all).toHaveLength(1);
243
+ expect(all[0].status).toBe('malformed');
244
+ }
245
+ finally {
246
+ delete process.env.ZELARI_KRAKEN_SELECTION;
247
+ }
248
+ });
249
+ });
250
+ describe('kraken_select gating (ADR-0020 Fase 4)', () => {
251
+ it('absent by default (flag off → registry unchanged)', () => {
252
+ const { tools } = makeRegistry();
253
+ expect(tools.find((t) => t.name === 'kraken_select')).toBeUndefined();
254
+ });
255
+ it('registered on the parent full registry when krakenSelect=true', () => {
256
+ const { tools, registry } = makeRegistry({ krakenSelect: true });
257
+ const summary = tools.find((t) => t.name === 'kraken_select');
258
+ expect(summary).toBeDefined();
259
+ expect(summary?.permissions).toContain('read');
260
+ expect(registry.get('kraken_select')).toBeDefined();
261
+ });
262
+ it('stays available in PLAN mode (selection is plan-safe)', () => {
263
+ const { tools } = makeRegistry({ krakenSelect: true, planMode: true });
264
+ expect(tools.find((t) => t.name === 'kraken_select')).toBeDefined();
265
+ });
266
+ it('NEVER registered on read-only sub-agent profiles (tentacles)', () => {
267
+ const { tools, registry } = makeRegistry({ krakenSelect: true, readOnly: true });
268
+ expect(tools.find((t) => t.name === 'kraken_select')).toBeUndefined();
269
+ expect(registry.get('kraken_select')).toBeUndefined();
270
+ });
271
+ it('execute is safe without deps wiring (no candidates → typedOk no-op)', async () => {
272
+ resetKrakenCandidates();
273
+ const { registry } = makeRegistry({ krakenSelect: true });
274
+ const tool = registry.get('kraken_select');
275
+ expect(tool).toBeDefined();
276
+ const res = await tool.execute({}, makeCtx());
277
+ expect(res.ok).toBe(true);
278
+ });
279
+ });
280
+ //# sourceMappingURL=taskTool.planSafety.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taskTool.planSafety.test.js","sourceRoot":"","sources":["../../../src/cli/tools/taskTool.planSafety.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * taskTool.verifyReport.test — Fase 7 / ADR-0020 (Kraken Verified Selection).
3
+ *
4
+ * Structured verification wiring inside the task tool:
5
+ * - verify tentacle conclusion with `<verify-report>` blocks → results
6
+ * registered in the turn registry (checksPassed counts only `pass`)
7
+ * - failed verify tentacle → ALL checks unknown (degraded ≠ proof)
8
+ * - no selection this turn → nothing registered
9
+ * - explore tentacle never registers check results
10
+ */
11
+ import { describe, expect, it, beforeEach, afterEach } from 'vitest';
12
+ import { tmpdir } from 'node:os';
13
+ import path from 'node:path';
14
+ import fs from 'node:fs';
15
+ import { ToolRegistry } from '@zelari/core/harness/tools/registry';
16
+ import { createTaskTool, resetTaskSpawnCount, } from './taskTool.js';
17
+ import { getKrakenCheckResults, krakenChecksPassed, resetKrakenCandidates, setKrakenSelection, } from '../kraken/candidateRegistry.js';
18
+ function tmpRoot() {
19
+ return fs.mkdtempSync(path.join(tmpdir(), 'zelari-verify-report-'));
20
+ }
21
+ function makeCtx(cwd = tmpRoot()) {
22
+ return {
23
+ signal: new AbortController().signal,
24
+ cwd,
25
+ audit: () => undefined,
26
+ sessionId: 'verify-report-test',
27
+ };
28
+ }
29
+ /**
30
+ * Deps fake whose scripted harness returns a fixed conclusion text.
31
+ * An empty conclusion simulates a tentacle that produced no output.
32
+ */
33
+ function scriptedDeps(conclusion) {
34
+ return {
35
+ createSubAgentContext: async ({ agent }) => {
36
+ const ctx = {
37
+ providerStream: (() => {
38
+ throw new Error('not invoked by the scripted harness');
39
+ }),
40
+ model: 'test-model',
41
+ provider: 'test-provider',
42
+ registry: new ToolRegistry(),
43
+ tools: [],
44
+ agent,
45
+ };
46
+ return ctx;
47
+ },
48
+ harnessFactory: () => ({
49
+ run: async function* () {
50
+ if (conclusion === '')
51
+ return;
52
+ yield { type: 'message_start' };
53
+ yield { type: 'message_delta', delta: conclusion };
54
+ yield { type: 'message_end' };
55
+ },
56
+ }),
57
+ allowWorktree: false,
58
+ };
59
+ }
60
+ const CHECKS = [
61
+ 'unit test for session refresh passes',
62
+ 'no Set-Cookie regression on logout',
63
+ ];
64
+ function selectedVerdict() {
65
+ return {
66
+ status: 'selected',
67
+ winnerIndex: 1,
68
+ rationale: 'grounded in evidence',
69
+ requiredChecks: CHECKS,
70
+ degraded: false,
71
+ verifier: { provider: 'p', model: 'm' },
72
+ judgedBy: 'llm',
73
+ };
74
+ }
75
+ const GOOD_CONCLUSION = [
76
+ 'Ran the targeted suite.',
77
+ '<verify-report>',
78
+ `check: ${CHECKS[0]}`,
79
+ 'status: pass',
80
+ 'note: vitest src/auth 41/41 green',
81
+ '</verify-report>',
82
+ '<verify-report>',
83
+ `check: ${CHECKS[1]}`,
84
+ 'status: fail',
85
+ 'note: logout still emits double Set-Cookie',
86
+ '</verify-report>',
87
+ ].join('\n');
88
+ async function spawn(deps, agent) {
89
+ const tool = createTaskTool(deps);
90
+ const res = await tool.execute({
91
+ description: 'verify the fix',
92
+ prompt: 'Verify the implementation.',
93
+ agent,
94
+ }, makeCtx());
95
+ return { ok: res.ok };
96
+ }
97
+ describe('structured verification registration (ADR-0020 Fase 7)', () => {
98
+ beforeEach(() => {
99
+ resetTaskSpawnCount();
100
+ resetKrakenCandidates();
101
+ });
102
+ afterEach(() => {
103
+ resetKrakenCandidates();
104
+ });
105
+ it('verify conclusion with blocks → per-check results registered, unknown ≠ pass', async () => {
106
+ setKrakenSelection(selectedVerdict());
107
+ const { ok } = await spawn(scriptedDeps(GOOD_CONCLUSION), 'verify');
108
+ expect(ok).toBe(true);
109
+ const results = getKrakenCheckResults();
110
+ expect(results).not.toBeNull();
111
+ expect(results?.map((r) => r.status)).toEqual(['pass', 'fail']);
112
+ expect(krakenChecksPassed()).toBe(1);
113
+ });
114
+ it('failed verify tentacle → all checks unknown, zero passed', async () => {
115
+ setKrakenSelection(selectedVerdict());
116
+ const { ok } = await spawn(scriptedDeps(''), 'verify');
117
+ expect(ok).toBe(false);
118
+ const results = getKrakenCheckResults();
119
+ expect(results?.map((r) => r.status)).toEqual(['unknown', 'unknown']);
120
+ expect(krakenChecksPassed()).toBe(0);
121
+ });
122
+ it('verify without report blocks → every check unknown (no report ≠ pass)', async () => {
123
+ setKrakenSelection(selectedVerdict());
124
+ await spawn(scriptedDeps('looks good to me, suite green'), 'verify');
125
+ expect(getKrakenCheckResults()?.map((r) => r.status)).toEqual(['unknown', 'unknown']);
126
+ expect(krakenChecksPassed()).toBe(0);
127
+ });
128
+ it('no selection this turn → nothing registered', async () => {
129
+ const { ok } = await spawn(scriptedDeps(GOOD_CONCLUSION), 'verify');
130
+ expect(ok).toBe(true);
131
+ expect(getKrakenCheckResults()).toBeNull();
132
+ expect(krakenChecksPassed()).toBeUndefined();
133
+ });
134
+ it('explore tentacle never registers check results', async () => {
135
+ setKrakenSelection(selectedVerdict());
136
+ await spawn(scriptedDeps(GOOD_CONCLUSION), 'explore');
137
+ expect(getKrakenCheckResults()).toBeNull();
138
+ });
139
+ });
140
+ //# sourceMappingURL=taskTool.verifyReport.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taskTool.verifyReport.test.js","sourceRoot":"","sources":["../../../src/cli/tools/taskTool.verifyReport.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zelari-code",
3
- "version": "1.48.1",
3
+ "version": "1.49.0",
4
4
  "description": "Zelari Code — AI Council coding agent CLI. Multi-agent orchestration (Caronte, Nettuno, Gerione, Plutone, Minosse, Lucifero) with slash commands, provider-agnostic LLM streaming, and self-update.",
5
5
  "author": "Anathema Studio <https://anathema-studio.com/>",
6
6
  "license": "Apache-2.0",