zelari-code 1.1.1 → 1.2.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.
- package/dist/cli/app.js +2 -2
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/checkpoint/checkpointManager.js +198 -0
- package/dist/cli/checkpoint/checkpointManager.js.map +1 -0
- package/dist/cli/components/StatusBar.js +9 -1
- package/dist/cli/components/StatusBar.js.map +1 -1
- package/dist/cli/diagnostics/engine.js +256 -0
- package/dist/cli/diagnostics/engine.js.map +1 -0
- package/dist/cli/hooks/chatStats.js +5 -1
- package/dist/cli/hooks/chatStats.js.map +1 -1
- package/dist/cli/hooks/useChatTurn.js.map +1 -1
- package/dist/cli/hooks/useSlashDispatch.js +17 -0
- package/dist/cli/hooks/useSlashDispatch.js.map +1 -1
- package/dist/cli/main.bundled.js +1067 -339
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/modelPricing.js +29 -5
- package/dist/cli/modelPricing.js.map +1 -1
- package/dist/cli/provider/openai-compatible.js +37 -1
- package/dist/cli/provider/openai-compatible.js.map +1 -1
- package/dist/cli/slashCommands.js +24 -1
- package/dist/cli/slashCommands.js.map +1 -1
- package/dist/cli/slashHandlers/checkpoint.js +42 -0
- package/dist/cli/slashHandlers/checkpoint.js.map +1 -0
- package/dist/cli/toolRegistry.js +126 -19
- package/dist/cli/toolRegistry.js.map +1 -1
- package/dist/cli/tools/taskTool.js +145 -0
- package/dist/cli/tools/taskTool.js.map +1 -0
- package/dist/cli/zelariMission.js +10 -0
- package/dist/cli/zelariMission.js.map +1 -1
- package/package.json +2 -2
package/dist/cli/app.js
CHANGED
|
@@ -62,7 +62,7 @@ export function App() {
|
|
|
62
62
|
const [input, setInput] = useState('');
|
|
63
63
|
const [busy, setBusy] = useState(false);
|
|
64
64
|
const [providerConfig, setProviderConfig] = useState(() => getProviderConfig());
|
|
65
|
-
const [sessionStats, setSessionStats] = useState({ totalTokens: 0, totalCostUsd: 0 });
|
|
65
|
+
const [sessionStats, setSessionStats] = useState({ totalTokens: 0, totalCostUsd: 0, cachedTokens: 0 });
|
|
66
66
|
// v0.7.0: bump on /clear to remount <Static> (resets its internal "already
|
|
67
67
|
// printed" index so the ANSI-cleared scrollback stays in sync). Also bumped
|
|
68
68
|
// implicitly by a sessionId change (/new).
|
|
@@ -208,7 +208,7 @@ export function App() {
|
|
|
208
208
|
React.createElement(Box, { flexDirection: "column", flexGrow: 1, paddingX: 1 },
|
|
209
209
|
React.createElement(LiveRegion, { live: session.live, busy: busy, elapsedMs: timer.elapsedMs }),
|
|
210
210
|
picker ? (React.createElement(SelectList, { title: picker.title, items: picker.items, onSelect: onPickerSelect, onCancel: onPickerCancel, maxVisible: Math.max(4, Math.min(10, size.rows - 10)) })) : (React.createElement(InputBar, { value: input, onChange: setInput, onSubmit: handleSubmit, disabled: busy })),
|
|
211
|
-
React.createElement(StatusBar, { model: activeModel, provider: activeProviderSpec.id, sessionId: session.sessionId ? session.sessionId.slice(0, 8) : '...', sessionActive: session.sessionActive, queueCount: chatTurn.queueCount, busy: busy, mode: mode, cwd: cwd, elapsedMs: timer.elapsedMs, lastMs: timer.lastMs })),
|
|
211
|
+
React.createElement(StatusBar, { model: activeModel, provider: activeProviderSpec.id, sessionId: session.sessionId ? session.sessionId.slice(0, 8) : '...', sessionActive: session.sessionActive, queueCount: chatTurn.queueCount, busy: busy, mode: mode, cwd: cwd, elapsedMs: timer.elapsedMs, lastMs: timer.lastMs, costUsd: sessionStats.totalCostUsd, cachedTokens: sessionStats.cachedTokens })),
|
|
212
212
|
showSidebar && (React.createElement(Sidebar, { version: VERSION, changes: gitChanges, rows: size.rows })))));
|
|
213
213
|
}
|
|
214
214
|
// Re-export so legacy imports keep working (Task v0.4.2 audit split).
|
package/dist/cli/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/cli/app.tsx"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,+EAA+E;AAC/E,yEAAyE;AACzE,wCAAwC;AACxC,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAU,MAAM,OAAO,CAAC;AACjF,OAAO,EAAE,GAAG,EAAQ,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAiB,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAErE,OAAO,EAAE,0BAA0B,EAAE,kBAAkB,EAA0C,MAAM,qBAAqB,CAAC;AAC7H,OAAO,EAAE,aAAa,EAAoB,MAAM,4BAA4B,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,uCAAuC,CAAC;AAC/C,OAAO,kCAAkC,CAAC;AAC1C,OAAO,qCAAqC,CAAC;AAC7C,OAAO,sCAAsC,CAAC;AAC9C,OAAO,yCAAyC,CAAC;AACjD,OAAO,oCAAoC,CAAC;AAC5C,OAAO,qCAAqC,CAAC;AAC7C,OAAO,EACL,iBAAiB,EACjB,iBAAiB,IAAI,qBAAqB,GAC3C,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAG7D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,QAAQ,CAAC;AACnD,MAAM,QAAQ,GAAG,mBAAmB,CAAC;AAErC;;;GAGG;AACH,MAAM,gBAAgB,GAA2B;IAC/C,mBAAmB,EAAE,QAAQ;IAC7B,MAAM,EAAE,QAAQ;IAChB,SAAS,EAAE,qBAAqB;IAChC,KAAK,EAAE,SAAS;IAChB,UAAU,EAAE,iBAAiB;CAC9B,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,GAAG;IACjB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAChF,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/cli/app.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* checkpointManager — workspace snapshots + atomic rollback.
|
|
3
|
+
*
|
|
4
|
+
* A safety net for multi-file changes, especially autonomous Zelari missions:
|
|
5
|
+
* take a snapshot of the working tree BEFORE a risky change, and restore the
|
|
6
|
+
* tree exactly if it goes wrong.
|
|
7
|
+
*
|
|
8
|
+
* Design (git plumbing, zero side effects on the user's state):
|
|
9
|
+
* - snapshot: build a throwaway index (GIT_INDEX_FILE) seeded from HEAD,
|
|
10
|
+
* `git add -A` into it (captures tracked + untracked, honoring .gitignore),
|
|
11
|
+
* `write-tree` → tree, `commit-tree` → commit, and pin it under
|
|
12
|
+
* `refs/zelari/checkpoints/<id>` so git GC can't collect it. The user's
|
|
13
|
+
* real index, HEAD, branch, and stash list are never touched.
|
|
14
|
+
* - restore: point the real index at the snapshot tree, `checkout-index -a -f`
|
|
15
|
+
* to rewrite the working tree, then delete any files created since the
|
|
16
|
+
* snapshot. Result: working tree + index match the checkpoint exactly.
|
|
17
|
+
* HEAD/branch are left alone (a checkpoint is a working-tree state, not a
|
|
18
|
+
* commit on your history).
|
|
19
|
+
*
|
|
20
|
+
* The git refs ARE the persistence — no separate metadata file to drift.
|
|
21
|
+
* Every git call is best-effort; failures surface as `{ error }`, never throws.
|
|
22
|
+
*/
|
|
23
|
+
import { execFile } from 'node:child_process';
|
|
24
|
+
import { promisify } from 'node:util';
|
|
25
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
26
|
+
import { tmpdir } from 'node:os';
|
|
27
|
+
import path from 'node:path';
|
|
28
|
+
import { randomUUID } from 'node:crypto';
|
|
29
|
+
const execFileAsync = promisify(execFile);
|
|
30
|
+
const REF_PREFIX = 'refs/zelari/checkpoints/';
|
|
31
|
+
/** Run `git -C <cwd> <args>` with an optional env overlay. Throws on failure. */
|
|
32
|
+
async function git(cwd, args, env) {
|
|
33
|
+
const { stdout } = await execFileAsync('git', ['-C', cwd, ...args], {
|
|
34
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
35
|
+
env: env ? { ...process.env, ...env } : process.env,
|
|
36
|
+
});
|
|
37
|
+
return stdout;
|
|
38
|
+
}
|
|
39
|
+
/** Best-effort variant: returns trimmed stdout or null on any error. */
|
|
40
|
+
async function gitSafe(cwd, args, env) {
|
|
41
|
+
try {
|
|
42
|
+
return (await git(cwd, args, env)).trim();
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** True if `cwd` is inside a git working tree. */
|
|
49
|
+
export async function isGitRepo(cwd) {
|
|
50
|
+
return (await gitSafe(cwd, ['rev-parse', '--is-inside-work-tree'])) === 'true';
|
|
51
|
+
}
|
|
52
|
+
/** Run a block with a fresh throwaway index file, always cleaned up. */
|
|
53
|
+
async function withTempIndex(fn) {
|
|
54
|
+
const dir = mkdtempSync(path.join(tmpdir(), 'zelari-ckpt-'));
|
|
55
|
+
const indexFile = path.join(dir, 'index');
|
|
56
|
+
try {
|
|
57
|
+
return await fn(indexFile);
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
rmSync(dir, { recursive: true, force: true });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Capture the current working tree as a git tree object, using a throwaway
|
|
65
|
+
* index so the real index is untouched. Returns { tree, head }.
|
|
66
|
+
*/
|
|
67
|
+
async function snapshotTree(cwd) {
|
|
68
|
+
const head = await gitSafe(cwd, ['rev-parse', 'HEAD']);
|
|
69
|
+
return withTempIndex(async (indexFile) => {
|
|
70
|
+
const env = { GIT_INDEX_FILE: indexFile };
|
|
71
|
+
// Seed the temp index from HEAD when the repo has commits; skip for an
|
|
72
|
+
// empty repo (no HEAD) — `add -A` then captures everything from scratch.
|
|
73
|
+
if (head)
|
|
74
|
+
await git(cwd, ['read-tree', 'HEAD'], env);
|
|
75
|
+
await git(cwd, ['add', '-A'], env);
|
|
76
|
+
const tree = (await git(cwd, ['write-tree'], env)).trim();
|
|
77
|
+
return { tree, head };
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Create a checkpoint of the current working tree. Best-effort — returns
|
|
82
|
+
* `{ ok:false, error }` if this is not a git repo or a git call fails.
|
|
83
|
+
*/
|
|
84
|
+
export async function createCheckpoint(cwd, label = 'checkpoint') {
|
|
85
|
+
if (!(await isGitRepo(cwd))) {
|
|
86
|
+
return { ok: false, error: 'not a git repository — checkpoints require git' };
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const { tree, head } = await snapshotTree(cwd);
|
|
90
|
+
const id = randomUUID().slice(0, 8);
|
|
91
|
+
const createdAt = Date.now();
|
|
92
|
+
const message = `zelari-checkpoint ${id}: ${label}`;
|
|
93
|
+
// commit-tree with a parent when HEAD exists, else a root commit.
|
|
94
|
+
const commitArgs = ['commit-tree', tree, '-m', message];
|
|
95
|
+
if (head)
|
|
96
|
+
commitArgs.push('-p', head);
|
|
97
|
+
const commit = (await git(cwd, commitArgs)).trim();
|
|
98
|
+
await git(cwd, ['update-ref', `${REF_PREFIX}${id}`, commit]);
|
|
99
|
+
return { ok: true, value: { id, label, tree, head, commit, createdAt } };
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** List existing checkpoints, newest first. */
|
|
106
|
+
export async function listCheckpoints(cwd) {
|
|
107
|
+
const out = await gitSafe(cwd, [
|
|
108
|
+
'for-each-ref',
|
|
109
|
+
'--sort=-creatordate',
|
|
110
|
+
'--format=%(refname) %(objectname) %(creatordate:unix) %(contents:subject)',
|
|
111
|
+
REF_PREFIX,
|
|
112
|
+
]);
|
|
113
|
+
if (!out)
|
|
114
|
+
return [];
|
|
115
|
+
const checkpoints = [];
|
|
116
|
+
for (const line of out.split('\n')) {
|
|
117
|
+
if (!line.trim())
|
|
118
|
+
continue;
|
|
119
|
+
const [refname, commit, unix, ...subjectParts] = line.split(' ');
|
|
120
|
+
if (!refname?.startsWith(REF_PREFIX))
|
|
121
|
+
continue;
|
|
122
|
+
const id = refname.slice(REF_PREFIX.length);
|
|
123
|
+
const subject = subjectParts.join(' ');
|
|
124
|
+
// Parse "zelari-checkpoint <id>: <label>" back into the label.
|
|
125
|
+
const label = subject.replace(/^zelari-checkpoint\s+\S+:\s*/, '') || 'checkpoint';
|
|
126
|
+
const tree = (await gitSafe(cwd, ['rev-parse', `${commit}^{tree}`])) ?? '';
|
|
127
|
+
checkpoints.push({
|
|
128
|
+
id,
|
|
129
|
+
label,
|
|
130
|
+
tree,
|
|
131
|
+
head: null,
|
|
132
|
+
commit: commit ?? '',
|
|
133
|
+
createdAt: (Number(unix) || 0) * 1000,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
return checkpoints;
|
|
137
|
+
}
|
|
138
|
+
/** Return the most recent checkpoint, or null if there are none. */
|
|
139
|
+
export async function latestCheckpoint(cwd) {
|
|
140
|
+
return (await listCheckpoints(cwd))[0] ?? null;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Restore the working tree (and index) to a checkpoint. Files modified or
|
|
144
|
+
* deleted since the snapshot are reverted to the snapshot content; files
|
|
145
|
+
* created since the snapshot are removed. HEAD/branch are left untouched.
|
|
146
|
+
*
|
|
147
|
+
* Best-effort — returns `{ ok:false, error }` on a missing checkpoint or any
|
|
148
|
+
* git failure. Pass `id` to target a specific checkpoint; omit to use the
|
|
149
|
+
* most recent one.
|
|
150
|
+
*/
|
|
151
|
+
export async function restoreCheckpoint(cwd, id) {
|
|
152
|
+
if (!(await isGitRepo(cwd))) {
|
|
153
|
+
return { ok: false, error: 'not a git repository — checkpoints require git' };
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
const target = id
|
|
157
|
+
? (await listCheckpoints(cwd)).find((c) => c.id === id)
|
|
158
|
+
: await latestCheckpoint(cwd);
|
|
159
|
+
if (!target) {
|
|
160
|
+
return { ok: false, error: id ? `checkpoint "${id}" not found` : 'no checkpoints to restore' };
|
|
161
|
+
}
|
|
162
|
+
const snapTree = target.tree || (await gitSafe(cwd, ['rev-parse', `${target.commit}^{tree}`]));
|
|
163
|
+
if (!snapTree)
|
|
164
|
+
return { ok: false, error: 'could not resolve checkpoint tree' };
|
|
165
|
+
// Files created since the snapshot (present now, absent in the snapshot)
|
|
166
|
+
// must be deleted so the restore is exact. Compare the snapshot tree
|
|
167
|
+
// against the current working-tree state.
|
|
168
|
+
const current = await snapshotTree(cwd);
|
|
169
|
+
const addedOut = await gitSafe(cwd, [
|
|
170
|
+
'diff', '--name-only', '--diff-filter=A', snapTree, current.tree,
|
|
171
|
+
]);
|
|
172
|
+
const added = addedOut ? addedOut.split('\n').filter((l) => l.trim()) : [];
|
|
173
|
+
// Point the real index at the snapshot and rewrite the working tree to
|
|
174
|
+
// match it (restores modified + recreates deleted files).
|
|
175
|
+
await git(cwd, ['read-tree', snapTree]);
|
|
176
|
+
await git(cwd, ['checkout-index', '-a', '-f']);
|
|
177
|
+
// Remove files created after the snapshot.
|
|
178
|
+
const deleted = [];
|
|
179
|
+
for (const rel of added) {
|
|
180
|
+
try {
|
|
181
|
+
rmSync(path.join(cwd, rel), { force: true });
|
|
182
|
+
deleted.push(rel);
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
// Leave it; a partial cleanup is still better than a failed restore.
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return { ok: true, value: { id: target.id, deleted } };
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/** Delete a checkpoint ref (its objects are reclaimed by a later git gc). */
|
|
195
|
+
export async function dropCheckpoint(cwd, id) {
|
|
196
|
+
return (await gitSafe(cwd, ['update-ref', '-d', `${REF_PREFIX}${id}`])) !== null;
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=checkpointManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpointManager.js","sourceRoot":"","sources":["../../../src/cli/checkpoint/checkpointManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
3
|
import { formatDuration } from '../utils/duration.js';
|
|
4
|
+
import { formatCost, formatTokens } from '../modelPricing.js';
|
|
4
5
|
import { Spinner } from './Spinner.js';
|
|
5
6
|
/**
|
|
6
7
|
* StatusBar — single one-line status bar rendered below the input box.
|
|
@@ -15,7 +16,7 @@ import { Spinner } from './Spinner.js';
|
|
|
15
16
|
* region as short as possible. A single status line + the input bar + the
|
|
16
17
|
* streaming tail is always well under a screen, so no full repaint.
|
|
17
18
|
*/
|
|
18
|
-
export function StatusBar({ model, provider, sessionId, sessionActive, queueCount = 0, busy = false, mode = 'agent', cwd, elapsedMs = null, lastMs = null, }) {
|
|
19
|
+
export function StatusBar({ model, provider, sessionId, sessionActive, queueCount = 0, busy = false, mode = 'agent', cwd, elapsedMs = null, lastMs = null, costUsd = 0, cachedTokens = 0, }) {
|
|
19
20
|
return (React.createElement(Box, { paddingX: 1, width: "100%", justifyContent: "space-between", gap: 2 },
|
|
20
21
|
React.createElement(Box, { flexShrink: 2 },
|
|
21
22
|
React.createElement(Text, { wrap: "truncate" },
|
|
@@ -47,6 +48,13 @@ export function StatusBar({ model, provider, sessionId, sessionActive, queueCoun
|
|
|
47
48
|
"queue ",
|
|
48
49
|
queueCount),
|
|
49
50
|
React.createElement(Text, { dimColor: true }, " \u00B7 "))) : null,
|
|
51
|
+
costUsd > 0 ? (React.createElement(React.Fragment, null,
|
|
52
|
+
React.createElement(Text, { color: "green" }, formatCost(costUsd)),
|
|
53
|
+
cachedTokens > 0 ? (React.createElement(Text, { dimColor: true },
|
|
54
|
+
" (",
|
|
55
|
+
formatTokens(cachedTokens),
|
|
56
|
+
" cached)")) : null,
|
|
57
|
+
React.createElement(Text, { dimColor: true }, " \u00B7 "))) : null,
|
|
50
58
|
React.createElement(Text, { dimColor: true },
|
|
51
59
|
"session ",
|
|
52
60
|
sessionId)))));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../../src/cli/components/StatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../../src/cli/components/StatusBar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* diagnostics/engine — fast, file-scoped compiler/linter diagnostics.
|
|
3
|
+
*
|
|
4
|
+
* The "diagnostics loop": after the agent edits a file, we run a FAST,
|
|
5
|
+
* file-scoped checker on just that file and feed the errors/warnings back
|
|
6
|
+
* into the same turn (see `wrapWithDiagnostics` in toolRegistry.ts). This
|
|
7
|
+
* turns blind string edits into compiler-verified edits — the single biggest
|
|
8
|
+
* quality lever for a coding agent.
|
|
9
|
+
*
|
|
10
|
+
* Why not `tsc`? A full `tsc --noEmit` needs whole-project context and takes
|
|
11
|
+
* seconds — far too slow to run after every edit. The per-edit loop uses
|
|
12
|
+
* checkers that are genuinely fast and file-scoped:
|
|
13
|
+
* - ESLint (js/ts/jsx/tsx/mjs/cjs) — `eslint --format json <file>`
|
|
14
|
+
* - Ruff (py) — `ruff check --output-format json <file>`
|
|
15
|
+
* Project-wide `tsc` stays available on demand via the `/check` command.
|
|
16
|
+
*
|
|
17
|
+
* Everything here is best-effort and NEVER throws: a missing binary, a
|
|
18
|
+
* timeout, or unparseable output all yield `[]` (no diagnostics) so a
|
|
19
|
+
* broken/absent linter can never break the edit itself. The spawn is
|
|
20
|
+
* injectable (`runner`) so the parsers + selection logic are unit-testable
|
|
21
|
+
* without any linter installed.
|
|
22
|
+
*/
|
|
23
|
+
import { spawn } from 'node:child_process';
|
|
24
|
+
import { existsSync } from 'node:fs';
|
|
25
|
+
import path from 'node:path';
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Parsers (pure — the well-tested core)
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/** Parse `eslint --format json` output (array of file result objects). */
|
|
30
|
+
export function parseEslintJson(stdout, _file) {
|
|
31
|
+
const json = safeJson(stdout);
|
|
32
|
+
if (!Array.isArray(json))
|
|
33
|
+
return [];
|
|
34
|
+
const out = [];
|
|
35
|
+
for (const fileResult of json) {
|
|
36
|
+
if (!fileResult || typeof fileResult !== 'object')
|
|
37
|
+
continue;
|
|
38
|
+
const fr = fileResult;
|
|
39
|
+
const filePath = typeof fr.filePath === 'string' ? fr.filePath : _file;
|
|
40
|
+
if (!Array.isArray(fr.messages))
|
|
41
|
+
continue;
|
|
42
|
+
for (const m of fr.messages) {
|
|
43
|
+
if (!m || typeof m !== 'object')
|
|
44
|
+
continue;
|
|
45
|
+
const msg = m;
|
|
46
|
+
out.push({
|
|
47
|
+
file: filePath,
|
|
48
|
+
line: typeof msg.line === 'number' ? msg.line : 0,
|
|
49
|
+
...(typeof msg.column === 'number' ? { column: msg.column } : {}),
|
|
50
|
+
// ESLint severity: 2 = error, 1 = warning.
|
|
51
|
+
severity: msg.severity === 2 ? 'error' : 'warning',
|
|
52
|
+
message: typeof msg.message === 'string' ? msg.message : '(no message)',
|
|
53
|
+
...(typeof msg.ruleId === 'string' && msg.ruleId ? { code: msg.ruleId } : {}),
|
|
54
|
+
source: 'eslint',
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
/** Parse `ruff check --output-format json` output (array of issue objects). */
|
|
61
|
+
export function parseRuffJson(stdout, _file) {
|
|
62
|
+
const json = safeJson(stdout);
|
|
63
|
+
if (!Array.isArray(json))
|
|
64
|
+
return [];
|
|
65
|
+
const out = [];
|
|
66
|
+
for (const issue of json) {
|
|
67
|
+
if (!issue || typeof issue !== 'object')
|
|
68
|
+
continue;
|
|
69
|
+
const it = issue;
|
|
70
|
+
const code = typeof it.code === 'string' ? it.code : undefined;
|
|
71
|
+
out.push({
|
|
72
|
+
file: typeof it.filename === 'string' ? it.filename : _file,
|
|
73
|
+
line: typeof it.location?.row === 'number' ? it.location.row : 0,
|
|
74
|
+
...(typeof it.location?.column === 'number' ? { column: it.location.column } : {}),
|
|
75
|
+
// Ruff has no severity field; E999 is a syntax error, everything else
|
|
76
|
+
// is a lint warning.
|
|
77
|
+
severity: code === 'E999' ? 'error' : 'warning',
|
|
78
|
+
message: typeof it.message === 'string' ? it.message : '(no message)',
|
|
79
|
+
...(code ? { code } : {}),
|
|
80
|
+
source: 'ruff',
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
function safeJson(s) {
|
|
86
|
+
const trimmed = s.trim();
|
|
87
|
+
if (!trimmed)
|
|
88
|
+
return null;
|
|
89
|
+
try {
|
|
90
|
+
return JSON.parse(trimmed);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// Providers
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
export const DEFAULT_PROVIDERS = [
|
|
100
|
+
{
|
|
101
|
+
name: 'eslint',
|
|
102
|
+
bin: 'eslint',
|
|
103
|
+
extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs'],
|
|
104
|
+
args: (file) => ['--format', 'json', file],
|
|
105
|
+
parse: parseEslintJson,
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'ruff',
|
|
109
|
+
bin: 'ruff',
|
|
110
|
+
extensions: ['.py'],
|
|
111
|
+
args: (file) => ['check', '--output-format', 'json', file],
|
|
112
|
+
parse: parseRuffJson,
|
|
113
|
+
},
|
|
114
|
+
];
|
|
115
|
+
/** Pick the provider that handles a file's extension, or null. */
|
|
116
|
+
export function providerForFile(file, providers = DEFAULT_PROVIDERS) {
|
|
117
|
+
const ext = path.extname(file).toLowerCase();
|
|
118
|
+
return providers.find((p) => p.extensions.includes(ext)) ?? null;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Resolve a checker binary to the project-local `node_modules/.bin/<bin>`
|
|
122
|
+
* when it exists (the common case — eslint/ruff are project deps, not on the
|
|
123
|
+
* global PATH), falling back to the bare name for PATH resolution. Walks up
|
|
124
|
+
* from `cwd` so it works from subdirectories of a workspace too.
|
|
125
|
+
*/
|
|
126
|
+
export function resolveBin(bin, cwd) {
|
|
127
|
+
const suffixes = process.platform === 'win32' ? ['.cmd', '.exe', ''] : [''];
|
|
128
|
+
let dir = cwd;
|
|
129
|
+
for (let i = 0; i < 6; i += 1) {
|
|
130
|
+
for (const suffix of suffixes) {
|
|
131
|
+
const candidate = path.join(dir, 'node_modules', '.bin', `${bin}${suffix}`);
|
|
132
|
+
if (existsSync(candidate))
|
|
133
|
+
return candidate;
|
|
134
|
+
}
|
|
135
|
+
const parent = path.dirname(dir);
|
|
136
|
+
if (parent === dir)
|
|
137
|
+
break;
|
|
138
|
+
dir = parent;
|
|
139
|
+
}
|
|
140
|
+
return bin;
|
|
141
|
+
}
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
// Runner
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
const defaultRunner = (cmd, args, opts) => new Promise((resolve) => {
|
|
146
|
+
let stdout = '';
|
|
147
|
+
let stderr = '';
|
|
148
|
+
let settled = false;
|
|
149
|
+
const done = (r) => {
|
|
150
|
+
if (settled)
|
|
151
|
+
return;
|
|
152
|
+
settled = true;
|
|
153
|
+
resolve(r);
|
|
154
|
+
};
|
|
155
|
+
let child;
|
|
156
|
+
try {
|
|
157
|
+
// shell:true on win32 so `.cmd` shims (eslint.cmd) resolve; POSIX runs
|
|
158
|
+
// the binary directly.
|
|
159
|
+
child =
|
|
160
|
+
process.platform === 'win32'
|
|
161
|
+
? spawn(`${cmd} ${args.join(' ')}`, { cwd: opts.cwd, shell: true })
|
|
162
|
+
: spawn(cmd, args, { cwd: opts.cwd });
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// Binary genuinely not launchable — treat as "no diagnostics".
|
|
166
|
+
done({ code: null, stdout: '', stderr: '' });
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const timer = setTimeout(() => {
|
|
170
|
+
try {
|
|
171
|
+
child.kill();
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
/* ignore */
|
|
175
|
+
}
|
|
176
|
+
done({ code: null, stdout, stderr });
|
|
177
|
+
}, opts.timeoutMs);
|
|
178
|
+
child.stdout?.on('data', (c) => {
|
|
179
|
+
stdout += c.toString();
|
|
180
|
+
});
|
|
181
|
+
child.stderr?.on('data', (c) => {
|
|
182
|
+
stderr += c.toString();
|
|
183
|
+
});
|
|
184
|
+
child.on('error', () => {
|
|
185
|
+
clearTimeout(timer);
|
|
186
|
+
done({ code: null, stdout: '', stderr: '' });
|
|
187
|
+
});
|
|
188
|
+
child.on('close', (code) => {
|
|
189
|
+
clearTimeout(timer);
|
|
190
|
+
done({ code, stdout, stderr });
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
/**
|
|
194
|
+
* Run the appropriate fast checker on a single file and return its
|
|
195
|
+
* diagnostics. Best-effort: returns `[]` for unsupported file types, a
|
|
196
|
+
* missing binary, a timeout, or unparseable output. Never throws.
|
|
197
|
+
*/
|
|
198
|
+
export async function runDiagnosticsForFile(file, options = {}) {
|
|
199
|
+
const provider = providerForFile(file, options.providers);
|
|
200
|
+
if (!provider)
|
|
201
|
+
return [];
|
|
202
|
+
const cwd = options.cwd ?? process.cwd();
|
|
203
|
+
const timeoutMs = options.timeoutMs ?? 5000;
|
|
204
|
+
const runner = options.runner ?? defaultRunner;
|
|
205
|
+
try {
|
|
206
|
+
// Prefer the project-local binary (node_modules/.bin) over PATH — only
|
|
207
|
+
// matters for the real runner; injected test runners ignore the bin.
|
|
208
|
+
const bin = options.runner ? provider.bin : resolveBin(provider.bin, cwd);
|
|
209
|
+
const result = await runner(bin, provider.args(file), { cwd, timeoutMs });
|
|
210
|
+
// A missing binary surfaces as code=null with empty stdout — nothing to
|
|
211
|
+
// parse, so this naturally yields [].
|
|
212
|
+
return provider.parse(result.stdout, file);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// ---------------------------------------------------------------------------
|
|
219
|
+
// Formatting
|
|
220
|
+
// ---------------------------------------------------------------------------
|
|
221
|
+
/**
|
|
222
|
+
* Render diagnostics as a compact block for injection into a tool result.
|
|
223
|
+
* Errors first, then warnings; capped at `maxLines` with an overflow note.
|
|
224
|
+
* Returns '' when there are no diagnostics (caller should inject nothing).
|
|
225
|
+
*/
|
|
226
|
+
export function formatDiagnostics(diagnostics, opts = {}) {
|
|
227
|
+
if (diagnostics.length === 0)
|
|
228
|
+
return '';
|
|
229
|
+
const maxLines = opts.maxLines ?? 20;
|
|
230
|
+
const rank = { error: 0, warning: 1, info: 2 };
|
|
231
|
+
const sorted = [...diagnostics].sort((a, b) => rank[a.severity] - rank[b.severity] || a.line - b.line);
|
|
232
|
+
const errors = sorted.filter((d) => d.severity === 'error').length;
|
|
233
|
+
const warnings = sorted.filter((d) => d.severity === 'warning').length;
|
|
234
|
+
const header = `⚠ ${diagnostics.length} diagnostic${diagnostics.length === 1 ? '' : 's'}` +
|
|
235
|
+
` (${errors} error${errors === 1 ? '' : 's'}, ${warnings} warning${warnings === 1 ? '' : 's'})` +
|
|
236
|
+
` — fix before continuing:`;
|
|
237
|
+
const shown = sorted.slice(0, maxLines).map((d) => {
|
|
238
|
+
const loc = opts.relativeTo ? relative(opts.relativeTo, d.file) : d.file;
|
|
239
|
+
const pos = d.column ? `${d.line}:${d.column}` : `${d.line}`;
|
|
240
|
+
const tag = d.severity === 'error' ? 'error' : d.severity === 'warning' ? 'warn' : 'info';
|
|
241
|
+
const code = d.code ? ` [${d.code}]` : '';
|
|
242
|
+
return ` ${loc}:${pos} ${tag}${code}: ${d.message} (${d.source})`;
|
|
243
|
+
});
|
|
244
|
+
const overflow = sorted.length > maxLines ? [` … and ${sorted.length - maxLines} more`] : [];
|
|
245
|
+
return [header, ...shown, ...overflow].join('\n');
|
|
246
|
+
}
|
|
247
|
+
function relative(from, to) {
|
|
248
|
+
try {
|
|
249
|
+
const rel = path.relative(from, to);
|
|
250
|
+
return rel && !rel.startsWith('..') ? rel : to;
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
return to;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/cli/diagnostics/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,10 +19,14 @@ export function computeSessionStatsDelta(realUsage, userText, assistantContent,
|
|
|
19
19
|
const completionTokens = realUsage
|
|
20
20
|
? realUsage.completionTokens
|
|
21
21
|
: Math.ceil(assistantContent.length / 4);
|
|
22
|
-
|
|
22
|
+
// Cached prompt tokens are only known from real provider usage; the
|
|
23
|
+
// char/4 fallback can't distinguish them, so assume 0 there.
|
|
24
|
+
const cachedPromptTokens = realUsage?.cachedPromptTokens ?? 0;
|
|
25
|
+
const turnCost = calculateCost(model, promptTokens, completionTokens, cachedPromptTokens);
|
|
23
26
|
return {
|
|
24
27
|
totalTokens: prev.totalTokens + promptTokens + completionTokens,
|
|
25
28
|
totalCostUsd: prev.totalCostUsd + turnCost,
|
|
29
|
+
cachedTokens: (prev.cachedTokens ?? 0) + cachedPromptTokens,
|
|
26
30
|
};
|
|
27
31
|
}
|
|
28
32
|
//# sourceMappingURL=chatStats.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chatStats.js","sourceRoot":"","sources":["../../../src/cli/hooks/chatStats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,wBAAwB,CACtC,
|
|
1
|
+
{"version":3,"file":"chatStats.js","sourceRoot":"","sources":["../../../src/cli/hooks/chatStats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,wBAAwB,CACtC,SAKQ,EACR,QAAgB,EAChB,gBAAwB,EACxB,KAAa,EACb,IAA0E;IAE1E,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzF,MAAM,gBAAgB,GAAG,SAAS;QAChC,CAAC,CAAC,SAAS,CAAC,gBAAgB;QAC5B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3C,oEAAoE;IACpE,6DAA6D;IAC7D,MAAM,kBAAkB,GAAG,SAAS,EAAE,kBAAkB,IAAI,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;IAC1F,OAAO;QACL,WAAW,EAAE,IAAI,CAAC,WAAW,GAAG,YAAY,GAAG,gBAAgB;QAC/D,YAAY,EAAE,IAAI,CAAC,YAAY,GAAG,QAAQ;QAC1C,YAAY,EAAE,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,kBAAkB;KAC5D,CAAC;AACJ,CAAC"}
|