zelari-code 2.52.0 → 2.54.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 (69) hide show
  1. package/dist/cli/acp/command.js +5 -3
  2. package/dist/cli/acp/command.js.map +1 -1
  3. package/dist/cli/acp/framing.js +151 -19
  4. package/dist/cli/acp/framing.js.map +1 -1
  5. package/dist/cli/acp/invariants.js +183 -0
  6. package/dist/cli/acp/invariants.js.map +1 -0
  7. package/dist/cli/acp/protocol.js +40 -5
  8. package/dist/cli/acp/protocol.js.map +1 -1
  9. package/dist/cli/acp/server.js +57 -17
  10. package/dist/cli/acp/server.js.map +1 -1
  11. package/dist/cli/acp/turnAdapter.js +2 -1
  12. package/dist/cli/acp/turnAdapter.js.map +1 -1
  13. package/dist/cli/app.js +2 -2
  14. package/dist/cli/app.js.map +1 -1
  15. package/dist/cli/budget/cacheHitReport.js +94 -0
  16. package/dist/cli/budget/cacheHitReport.js.map +1 -0
  17. package/dist/cli/budget/messageUsage.js +77 -0
  18. package/dist/cli/budget/messageUsage.js.map +1 -0
  19. package/dist/cli/companion/framePolicy.js +116 -0
  20. package/dist/cli/companion/framePolicy.js.map +1 -0
  21. package/dist/cli/components/SelectList.js +51 -14
  22. package/dist/cli/components/SelectList.js.map +1 -1
  23. package/dist/cli/components/StatusBar.js +6 -2
  24. package/dist/cli/components/StatusBar.js.map +1 -1
  25. package/dist/cli/components/fuzzyMatch.js +108 -0
  26. package/dist/cli/components/fuzzyMatch.js.map +1 -0
  27. package/dist/cli/components/statusChips.js +47 -0
  28. package/dist/cli/components/statusChips.js.map +1 -1
  29. package/dist/cli/headless/protocol.js +39 -2
  30. package/dist/cli/headless/protocol.js.map +1 -1
  31. package/dist/cli/headless/runOneTurn.js +68 -18
  32. package/dist/cli/headless/runOneTurn.js.map +1 -1
  33. package/dist/cli/hooks/useChatTurn.js +76 -16
  34. package/dist/cli/hooks/useChatTurn.js.map +1 -1
  35. package/dist/cli/hooks/useSlashDispatch.js +5 -2
  36. package/dist/cli/hooks/useSlashDispatch.js.map +1 -1
  37. package/dist/cli/inbox.js +220 -0
  38. package/dist/cli/inbox.js.map +1 -0
  39. package/dist/cli/main.bundled.js +3959 -2560
  40. package/dist/cli/main.bundled.js.map +4 -4
  41. package/dist/cli/main.js +22 -0
  42. package/dist/cli/main.js.map +1 -1
  43. package/dist/cli/metrics.js.map +1 -1
  44. package/dist/cli/provider/anthropic.js +42 -6
  45. package/dist/cli/provider/anthropic.js.map +1 -1
  46. package/dist/cli/provider/chatgpt.js +4 -0
  47. package/dist/cli/provider/chatgpt.js.map +1 -1
  48. package/dist/cli/provider/openai-compatible.js +25 -3
  49. package/dist/cli/provider/openai-compatible.js.map +1 -1
  50. package/dist/cli/provider/responsesApi.js +4 -0
  51. package/dist/cli/provider/responsesApi.js.map +1 -1
  52. package/dist/cli/serve/harnessServer.js +7 -0
  53. package/dist/cli/serve/harnessServer.js.map +1 -1
  54. package/dist/cli/sessionManager.js +9 -2
  55. package/dist/cli/sessionManager.js.map +1 -1
  56. package/dist/cli/skillsCheck.js +209 -0
  57. package/dist/cli/skillsCheck.js.map +1 -0
  58. package/dist/cli/slashCommands.js +9 -0
  59. package/dist/cli/slashCommands.js.map +1 -1
  60. package/dist/cli/slashHandlers/provider.js.map +1 -1
  61. package/dist/cli/slashHandlers/sessions.js +131 -0
  62. package/dist/cli/slashHandlers/sessions.js.map +1 -0
  63. package/dist/cli/statusline/statuslineItems.js +22 -3
  64. package/dist/cli/statusline/statuslineItems.js.map +1 -1
  65. package/dist/cli/statusline/verdictFeed.js +245 -0
  66. package/dist/cli/statusline/verdictFeed.js.map +1 -0
  67. package/dist/cli/utils/doctor.js +30 -0
  68. package/dist/cli/utils/doctor.js.map +1 -1
  69. package/package.json +2 -2
@@ -0,0 +1,220 @@
1
+ /**
2
+ * inbox — `/inbox`: what is waiting on YOU, derived from the LOCAL spine.
3
+ *
4
+ * DERIVE-ONLY (ADR-0016/0024): this module READS
5
+ * `<sessionsDir>/<id>/events.jsonl` and never writes, mutates or injects
6
+ * anything (feeding a model is gated separately by ADR-0031 context.projection).
7
+ *
8
+ * WHAT IT LOOKS FOR ON THE SPINE — grounded on how ask_user is recorded today
9
+ * (`src/cli/sessionSpine.ts` maps BrainEvents; there is NO dedicated ask_user
10
+ * spine kind — the companion/serve `ask_user.request|settled` frames are
11
+ * transport frames, not session events):
12
+ * - the QUESTION: `tool.call` with `data.tool === 'ask_user'`
13
+ * (`data.callId`, `data.args.question`, `data.args.choices`);
14
+ * - the SETTLEMENT: `tool.result` with the SAME `data.callId` — an answer, a
15
+ * cancel or a timeout all mean the ask is no longer waiting on you;
16
+ * - a DEAD RUN: `tool.interrupted` with the same `callId` (crash recovery
17
+ * classified the dangling call). The question was never settled, but the
18
+ * session that asked is gone ⇒ listed with `available: false`.
19
+ *
20
+ * TOLERANT BY CONTRACT: an unreadable/corrupt/empty spine is skipped and
21
+ * counted, never thrown; a call without a `callId` is skipped too — it could
22
+ * never be proven settled, so claiming it as pending would be a guess.
23
+ *
24
+ * Kill switch: `ZELARI_INBOX=0` ⇒ `renderInbox()` answers "disabled" (an
25
+ * env-gated command reports its state, it does not vanish silently).
26
+ */
27
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
28
+ import path from 'node:path';
29
+ import { parseSessionLogText, resolveSessionsDir } from '@zelari/core/session';
30
+ /** Most-recent questions kept (per scan, across all sessions). */
31
+ export const INBOX_LIMIT = 20;
32
+ /** Default-ON kill switch: only the exact `0` disables `/inbox`. */
33
+ export function inboxEnabled(env = process.env) {
34
+ return env.ZELARI_INBOX !== '0';
35
+ }
36
+ function asRecord(v) {
37
+ return v && typeof v === 'object' && !Array.isArray(v) ? v : null;
38
+ }
39
+ /** Collapse to one short line — inbox rows stay readable. */
40
+ function oneLine(text, max = 100) {
41
+ const flat = text.replace(/\s+/g, ' ').trim();
42
+ return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;
43
+ }
44
+ /** `data.args`, tolerating a JSON string (some hosts serialize tool args). */
45
+ function argsOf(data) {
46
+ if (typeof data.args === 'string') {
47
+ try {
48
+ return asRecord(JSON.parse(data.args));
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ }
54
+ return asRecord(data.args);
55
+ }
56
+ /** The `ask_user` question of one `tool.call`, or null when there is none. */
57
+ function askOf(ev) {
58
+ if (ev.kind !== 'tool.call')
59
+ return null;
60
+ const data = asRecord(ev.data);
61
+ if (!data || data.tool !== 'ask_user')
62
+ return null;
63
+ const callId = typeof data.callId === 'string' ? data.callId : '';
64
+ if (callId.length === 0)
65
+ return null; // unattributable: never claimed as pending
66
+ const args = argsOf(data);
67
+ const question = typeof args?.question === 'string' ? args.question.replace(/\s+/g, ' ').trim() : '';
68
+ if (question.length === 0)
69
+ return null; // no question text recorded ⇒ nothing to answer
70
+ const choices = Array.isArray(args?.choices)
71
+ ? args.choices.filter((c) => typeof c === 'string' && c.trim().length > 0)
72
+ : [];
73
+ return { callId, question, choices, seq: ev.seq, ts: ev.ts };
74
+ }
75
+ /** callIds named by `kind` events (settlement / interruption). */
76
+ function callIdsOf(events, kind) {
77
+ const ids = new Set();
78
+ for (const ev of events) {
79
+ if (ev.kind !== kind)
80
+ continue;
81
+ const callId = asRecord(ev.data)?.callId;
82
+ if (typeof callId === 'string' && callId.length > 0)
83
+ ids.add(callId);
84
+ }
85
+ return ids;
86
+ }
87
+ /** First user prompt of the session — the human handle for `/resume`. */
88
+ function destinationOf(events) {
89
+ for (const ev of events) {
90
+ if (ev.kind !== 'user.message')
91
+ continue;
92
+ const text = asRecord(ev.data)?.text;
93
+ if (typeof text === 'string' && text.trim().length > 0)
94
+ return oneLine(text, 72);
95
+ }
96
+ return '';
97
+ }
98
+ /**
99
+ * Pending questions of ONE session, from its recorded events only: every
100
+ * `ask_user` call with a callId and a question, minus the callIds a
101
+ * `tool.result` settled. Pure — no I/O, no clock.
102
+ */
103
+ export function deriveInboxQuestions(events, opts) {
104
+ const settled = callIdsOf(events, 'tool.result');
105
+ const interrupted = callIdsOf(events, 'tool.interrupted');
106
+ const available = opts.available !== false;
107
+ const out = [];
108
+ for (const ev of events) {
109
+ const ask = askOf(ev);
110
+ if (!ask || settled.has(ask.callId))
111
+ continue;
112
+ out.push({
113
+ sessionId: opts.sessionId,
114
+ destination: opts.destination ?? '',
115
+ question: ask.question,
116
+ choices: ask.choices,
117
+ callId: ask.callId,
118
+ seq: ask.seq,
119
+ ts: ask.ts,
120
+ available: available && !interrupted.has(ask.callId),
121
+ });
122
+ }
123
+ return out;
124
+ }
125
+ /**
126
+ * Scan every local session spine for unanswered `ask_user` questions. Most
127
+ * recent first, capped at `INBOX_LIMIT`; a broken session is skipped and
128
+ * counted — this command is diagnostics, never a gate.
129
+ */
130
+ export function scanInbox(opts = {}) {
131
+ const env = opts.env ?? process.env;
132
+ const sessionsDir = opts.sessionsDir ?? resolveSessionsDir({ workspaceRoot: opts.cwd, env });
133
+ const limit = opts.limit ?? INBOX_LIMIT;
134
+ const found = [];
135
+ let sessions = 0;
136
+ let skipped = 0;
137
+ let names;
138
+ try {
139
+ names = readdirSync(sessionsDir, { withFileTypes: true })
140
+ .filter((d) => d.isDirectory())
141
+ .map((d) => d.name);
142
+ }
143
+ catch {
144
+ return { sessionsDir, sessions: 0, skipped: 0, entries: [], truncated: false };
145
+ }
146
+ for (const name of names) {
147
+ const file = path.join(sessionsDir, name, 'events.jsonl');
148
+ try {
149
+ if (!existsSync(file))
150
+ continue; // not a spine session dir
151
+ const report = parseSessionLogText(file, readFileSync(file, 'utf-8'));
152
+ if (report.events.length === 0) {
153
+ skipped += 1; // empty or unreadable content: unknown, never "answered"
154
+ continue;
155
+ }
156
+ sessions += 1;
157
+ found.push(...deriveInboxQuestions(report.events, { sessionId: name, destination: destinationOf(report.events) }));
158
+ }
159
+ catch {
160
+ skipped += 1;
161
+ }
162
+ }
163
+ found.sort((a, b) => b.ts - a.ts || b.seq - a.seq);
164
+ const entries = found.slice(0, Math.max(0, limit));
165
+ return { sessionsDir, sessions, skipped, entries, truncated: found.length > entries.length };
166
+ }
167
+ /** `2026-10-02 14:03` — minute precision is enough to judge staleness. */
168
+ function askedAt(ts) {
169
+ try {
170
+ return new Date(ts).toISOString().replace('T', ' ').slice(0, 16);
171
+ }
172
+ catch {
173
+ return '';
174
+ }
175
+ }
176
+ /** One inbox row: destination, question, and how to get back to it. */
177
+ function formatEntry(entry, index) {
178
+ const handle = entry.destination
179
+ ? `${entry.sessionId.slice(0, 8)}… · "${oneLine(entry.destination, 60)}"`
180
+ : `${entry.sessionId.slice(0, 8)}…`;
181
+ const lines = [` ${index}. ${handle}`, ` Q: ${oneLine(entry.question)}`];
182
+ const when = askedAt(entry.ts);
183
+ const resume = entry.available
184
+ ? ` → /resume ${entry.sessionId}`
185
+ : ` → /resume ${entry.sessionId} (the run that asked was interrupted — re-ask after resuming)`;
186
+ lines.push(when ? `${resume} (asked ${when})` : resume);
187
+ return lines;
188
+ }
189
+ /** Pure text rendering of a scan (no I/O). `total` 0 ⇒ the friendly empty state. */
190
+ export function formatInbox(scan) {
191
+ if (scan.sessions === 0) {
192
+ return `[inbox] no local sessions under ${scan.sessionsDir} — nothing waiting on you.`;
193
+ }
194
+ const notes = [];
195
+ if (scan.skipped > 0)
196
+ notes.push(`note: ${scan.skipped} unreadable/empty session spine(s) skipped`);
197
+ if (scan.truncated)
198
+ notes.push(`note: showing the ${scan.entries.length} most recent`);
199
+ if (scan.entries.length === 0) {
200
+ const head = `[inbox] nothing waiting on you — no unanswered ask_user question in ${scan.sessions} session(s).`;
201
+ return [head, ...notes.map((n) => ` ${n}`)].join('\n');
202
+ }
203
+ const lines = [
204
+ `[inbox] ${scan.entries.length} question(s) waiting on you (${scan.sessions} session(s) scanned)`,
205
+ '',
206
+ ];
207
+ scan.entries.forEach((entry, i) => lines.push(...formatEntry(entry, i + 1)));
208
+ if (notes.length > 0)
209
+ lines.push('', ...notes.map((n) => ` ${n}`));
210
+ return lines.join('\n');
211
+ }
212
+ /** `/inbox` — kill switch, scan, render. Never throws. */
213
+ export function renderInbox(opts = {}) {
214
+ const env = opts.env ?? process.env;
215
+ if (!inboxEnabled(env)) {
216
+ return '[inbox] disabled — ZELARI_INBOX=0 (unset it to list the questions waiting on you).';
217
+ }
218
+ return formatInbox(scanInbox(opts));
219
+ }
220
+ //# sourceMappingURL=inbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/cli/inbox.ts"],"names":[],"mappings":"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"}