zelari-code 2.25.0 → 2.27.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 (35) hide show
  1. package/README.md +4 -4
  2. package/dist/cli/app.js +2 -1
  3. package/dist/cli/app.js.map +1 -1
  4. package/dist/cli/components/StatusBar.js +7 -1
  5. package/dist/cli/components/StatusBar.js.map +1 -1
  6. package/dist/cli/gitOps.js +22 -0
  7. package/dist/cli/gitOps.js.map +1 -1
  8. package/dist/cli/hooks/useChatTurn.js +5 -1
  9. package/dist/cli/hooks/useChatTurn.js.map +1 -1
  10. package/dist/cli/kraken/verifyStatus.js +113 -0
  11. package/dist/cli/kraken/verifyStatus.js.map +1 -0
  12. package/dist/cli/main.bundled.js +30718 -30254
  13. package/dist/cli/main.bundled.js.map +4 -4
  14. package/dist/cli/toolRegistry.js +17 -1
  15. package/dist/cli/toolRegistry.js.map +1 -1
  16. package/dist/cli/tools/krakenLive.js +9 -1
  17. package/dist/cli/tools/krakenLive.js.map +1 -1
  18. package/dist/cli/tools/krakenRadio.js.map +1 -1
  19. package/dist/cli/tools/planTaskTools.js +76 -4
  20. package/dist/cli/tools/planTaskTools.js.map +1 -1
  21. package/dist/cli/utils/doctor.js +47 -1
  22. package/dist/cli/utils/doctor.js.map +1 -1
  23. package/dist/cli/wizard/index.js +10 -0
  24. package/dist/cli/wizard/index.js.map +1 -1
  25. package/dist/cli/workspace/planStore.js +19 -0
  26. package/dist/cli/workspace/planStore.js.map +1 -1
  27. package/dist/cli/workspace/stubs.js +3 -0
  28. package/dist/cli/workspace/stubs.js.map +1 -1
  29. package/dist/cli/workspace/taskOverlap.js +78 -0
  30. package/dist/cli/workspace/taskOverlap.js.map +1 -0
  31. package/dist/cli/workspace/taskStaleness.js +100 -0
  32. package/dist/cli/workspace/taskStaleness.js.map +1 -0
  33. package/dist/cli/workspace/taskTouchGuard.js +181 -0
  34. package/dist/cli/workspace/taskTouchGuard.js.map +1 -0
  35. package/package.json +4 -3
@@ -0,0 +1,181 @@
1
+ /**
2
+ * taskTouchGuard — declared-vs-observed hygiene guard (t58, plan P1.5).
3
+ *
4
+ * Watches post-result write events (t57 ToolRegistry post-result seam) and
5
+ * flags `completed` tasks whose declared `files` globs are touched by a
6
+ * LATER session (cross-session rule: sessionStartedAt > completedAt, so the
7
+ * session that completes a task never auto-flags itself).
8
+ *
9
+ * On a match (best-effort, total fail-open — this code must never break a
10
+ * tool call):
11
+ * - one `task_reopened` radio event per task per session
12
+ * (`.zelari/radio/<sessionId>.jsonl`, agent `task-guard`);
13
+ * - flags.push('reopened') + an appendNote on the plan task, through
14
+ * withPlanStore so the shared workspace mutex keeps it consistent with
15
+ * concurrent `task_update` calls.
16
+ *
17
+ * Supported glob vocabulary (documented, minimal — no new deps):
18
+ * - exact root-relative path: src/cli/foo.ts
19
+ * - directory subtree (recursive): src followed by double-star
20
+ * - extension suffix (any depth): *.ts (leading double-star prefix also ok)
21
+ *
22
+ * Excluded, never matched: .zelari, node_modules, dist, build subtrees
23
+ * (plan.json itself changes constantly by design).
24
+ *
25
+ * @since v2.26.0 (t58)
26
+ */
27
+ import { existsSync } from 'node:fs';
28
+ import path from 'node:path';
29
+ import { appendKrakenRadio } from '../tools/krakenRadio.js';
30
+ import { PLAN_NOTES_MAX, planJsonPathFor, withPlanStore } from './planStore.js';
31
+ /** Native mutating tools (catalog names) + MCP filesystem variants. */
32
+ const NATIVE_WRITE_TOOLS = new Set([
33
+ 'write_file',
34
+ 'edit',
35
+ 'edit_file',
36
+ 'apply_diff',
37
+ ]);
38
+ const MCP_FS_WRITE_RE = /^mcp_filesystem_(write_file|edit_file|move_file|create_directory)$/;
39
+ const EXCLUDED_DIR_PREFIXES = ['.zelari/', 'node_modules/', 'dist/', 'build/'];
40
+ export function isMutatingToolName(name) {
41
+ return NATIVE_WRITE_TOOLS.has(name) || MCP_FS_WRITE_RE.test(name);
42
+ }
43
+ /**
44
+ * Normalize a tool-supplied path to a root-relative POSIX path.
45
+ * Absolute paths outside `projectRoot` (and Windows drive crossings) → null.
46
+ */
47
+ export function toPosixRel(projectRoot, p) {
48
+ const raw = p.trim().replace(/\\/g, '/');
49
+ if (raw.startsWith('/') || /^[a-zA-Z]:\//.test(raw)) {
50
+ let rel;
51
+ try {
52
+ rel = path.relative(projectRoot, p);
53
+ }
54
+ catch {
55
+ return null;
56
+ }
57
+ if (!rel || rel.startsWith('..') || path.isAbsolute(rel))
58
+ return null;
59
+ return rel.replace(/\\/g, '/');
60
+ }
61
+ return raw.replace(/^\.\//, '');
62
+ }
63
+ /** Pull the mutated path out of a mutating tool's args (MCP uses `file_path`). */
64
+ export function extractWriteTarget(toolName, toolInput) {
65
+ if (!isMutatingToolName(toolName))
66
+ return null;
67
+ const args = (toolInput ?? {});
68
+ for (const key of ['path', 'file_path', 'source', 'destination']) {
69
+ const v = args[key];
70
+ if (typeof v === 'string' && v.trim())
71
+ return v.trim();
72
+ }
73
+ return null;
74
+ }
75
+ function normalizePattern(raw) {
76
+ return raw.replace(/\\/g, '/').replace(/^\.\//, '').replace(/^\*\*\//, '');
77
+ }
78
+ /**
79
+ * Match a root-relative path against declared task globs.
80
+ * Excluded dirs (.zelari, node_modules, dist, build) never match.
81
+ */
82
+ export function matchTaskFiles(patterns, relPath) {
83
+ if (EXCLUDED_DIR_PREFIXES.some((p) => relPath.startsWith(p)))
84
+ return false;
85
+ for (const raw of patterns) {
86
+ const pat = normalizePattern(raw);
87
+ if (!pat)
88
+ continue;
89
+ if (pat === relPath)
90
+ return true;
91
+ if (pat.endsWith('/**')) {
92
+ if (relPath.startsWith(pat.slice(0, -2)))
93
+ return true;
94
+ }
95
+ else if (pat.includes('*')) {
96
+ const star = pat.indexOf('*');
97
+ const suffix = pat.slice(star + 1);
98
+ if (suffix && !suffix.includes('*') && relPath.endsWith(suffix))
99
+ return true;
100
+ }
101
+ }
102
+ return false;
103
+ }
104
+ /**
105
+ * Build the t57 listener. Every inspection is chained onto an internal
106
+ * promise queue so tests (and shutdown paths) can drain() it; the listener
107
+ * itself stays synchronous and never throws (total fail-open).
108
+ */
109
+ export function createTaskTouchGuard(opts) {
110
+ const root = opts.projectRoot;
111
+ const sessionId = opts.sessionId;
112
+ const sessionStartedAt = (opts.now ?? Date.now)();
113
+ const flagged = new Set();
114
+ let chain = Promise.resolve();
115
+ const listener = (event) => {
116
+ try {
117
+ if (!event.ok)
118
+ return;
119
+ const target = extractWriteTarget(event.toolName, event.toolInput);
120
+ if (!target)
121
+ return;
122
+ const rel = toPosixRel(root, target);
123
+ if (!rel)
124
+ return;
125
+ chain = chain.then(() => inspectWrite(rel)).catch(() => undefined);
126
+ }
127
+ catch {
128
+ // fail-open: the guard must never break a tool result
129
+ }
130
+ };
131
+ listener.drain = () => chain;
132
+ return listener;
133
+ async function inspectWrite(rel) {
134
+ try {
135
+ const planPath = planJsonPathFor(root);
136
+ if (!existsSync(planPath))
137
+ return;
138
+ const tasks = await withPlanStore(root, (store) => store.tasks);
139
+ for (const task of tasks) {
140
+ if (task.status !== 'completed' || !task.files?.length || !task.completedAt)
141
+ continue;
142
+ if (flagged.has(task.id))
143
+ continue;
144
+ const doneAt = Date.parse(task.completedAt);
145
+ if (!Number.isFinite(doneAt) || sessionStartedAt <= doneAt)
146
+ continue;
147
+ if (!matchTaskFiles(task.files, rel))
148
+ continue;
149
+ flagged.add(task.id);
150
+ appendKrakenRadio(root, sessionId, {
151
+ kind: 'task_reopened',
152
+ agent: 'task-guard',
153
+ description: `completed task ${task.id} file touched after completion`,
154
+ contestedFile: rel,
155
+ ok: true,
156
+ detail: `${task.title} — ${rel}`,
157
+ });
158
+ try {
159
+ await withPlanStore(root, (store) => {
160
+ const live = store.tasks.find((t) => t.id === task.id);
161
+ if (!live)
162
+ return;
163
+ const flags = Array.isArray(live.flags) ? [...live.flags] : [];
164
+ if (!flags.includes('reopened'))
165
+ live.flags = [...flags, 'reopened'];
166
+ const stamp = new Date(sessionStartedAt).toISOString();
167
+ const note = `[task-guard ${stamp}] ${rel} modified after completion (reopened)`;
168
+ live.notes = `${live.notes ? `${live.notes}\n` : ''}${note}`.slice(0, PLAN_NOTES_MAX);
169
+ });
170
+ }
171
+ catch {
172
+ // flag/note are best-effort; the radio event already went out
173
+ }
174
+ }
175
+ }
176
+ catch {
177
+ // fail-open (missing/corrupt plan.json, radio io, …)
178
+ }
179
+ }
180
+ }
181
+ //# sourceMappingURL=taskTouchGuard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taskTouchGuard.js","sourceRoot":"","sources":["../../../src/cli/workspace/taskTouchGuard.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zelari-code",
3
- "version": "2.25.0",
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.",
3
+ "version": "2.27.0",
4
+ "description": "Zelari Code — open-source coding orchestrator CLI. You choose the model; the proof is mandatory. Kraken by default, council when the work earns it: plan/build phases, provider-agnostic LLM streaming, self-update.",
5
5
  "author": "Anathema Studio <https://anathema-studio.com/>",
6
6
  "license": "Apache-2.0",
7
7
  "type": "module",
@@ -53,6 +53,7 @@
53
53
  "evolve:propose": "node --experimental-strip-types tools/eval/runEvolvePropose.ts",
54
54
  "evolve:decide": "node --experimental-strip-types tools/eval/runEvolveDecide.ts",
55
55
  "evolve:validate": "node --experimental-strip-types tools/eval/runEvolveValidate.ts",
56
+ "edit:bench": "node --experimental-strip-types tools/eval/runEditBench.ts",
56
57
  "test:eval": "vitest run tools/eval",
57
58
  "test:memory": "vitest run packages/core/src/memory/scoring.test.ts tests/unit/core-agentHarness-memory.test.ts tests/unit/cli-sqliteMemoryV2.test.ts tests/unit/cli-memorySemantic.test.ts tests/unit/cli-memoryMigration.test.ts tests/unit/cli-memoryMcp.test.ts tests/unit/cli-memoryJsonApi.test.ts tests/unit/cli-memoryCommands.test.ts tests/unit/cli-memoryPerformance.test.ts tests/unit/cli-kraken-sharedMemory.test.ts tests/unit/cli-semantic.test.ts tools/eval/memoryMetrics.test.ts"
58
59
  },
@@ -65,7 +66,7 @@
65
66
  },
66
67
  "devDependencies": {
67
68
  "@testing-library/react": "^16.3.2",
68
- "@zelari/core": "2.25.0",
69
+ "@zelari/core": "2.27.0",
69
70
  "@types/node": "^25.3.0",
70
71
  "@types/react": "^19.0.10",
71
72
  "esbuild": "^0.25.0",