tandem-mode 0.5.0 → 0.5.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.
- package/README.md +10 -2
- package/dist/agent/clipboard.js +37 -37
- package/dist/agent/clipboard.js.map +1 -1
- package/dist/agent/loop.js +41 -15
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/session.js +2 -2
- package/dist/agent/session.js.map +1 -1
- package/dist/agent/tools/edit.js +1 -1
- package/dist/agent/tools/edit.js.map +1 -1
- package/dist/agent/tools/listDir.js +49 -6
- package/dist/agent/tools/listDir.js.map +1 -1
- package/dist/agent/tools/safeCommand.js +70 -0
- package/dist/agent/tools/safeCommand.js.map +1 -0
- package/dist/agent/tools/search.js +5 -6
- package/dist/agent/tools/search.js.map +1 -1
- package/dist/agent/tools/searchFallback.js +162 -0
- package/dist/agent/tools/searchFallback.js.map +1 -0
- package/dist/agent/tools/shell.js +3 -13
- package/dist/agent/tools/shell.js.map +1 -1
- package/dist/agent/tools/viewImage.js +2 -2
- package/dist/agent/tools/viewImage.js.map +1 -1
- package/dist/agent/tools/webSearch.js +2 -2
- package/dist/agent/tools/webSearch.js.map +1 -1
- package/dist/agent/usage.js +2 -2
- package/dist/agent/usage.js.map +1 -1
- package/dist/benchmark/runner.js +8 -8
- package/dist/benchmark/runner.js.map +1 -1
- package/dist/cli.js +31 -17
- package/dist/cli.js.map +1 -1
- package/dist/config/credentials.js +37 -37
- package/dist/config/credentials.js.map +1 -1
- package/dist/config/env.js +1 -1
- package/dist/config/store.js +1 -1
- package/dist/config/store.js.map +1 -1
- package/dist/deepseek/client.js +7 -2
- package/dist/deepseek/client.js.map +1 -1
- package/dist/deepseek/errors.js +101 -0
- package/dist/deepseek/errors.js.map +1 -0
- package/dist/deepseek/webSearch.js +3 -3
- package/dist/deepseek/webSearch.js.map +1 -1
- package/dist/i18n/en.js +2 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/sr.js +2 -0
- package/dist/i18n/sr.js.map +1 -1
- package/dist/orchestrator/planner.js +14 -14
- package/dist/orchestrator/repoMap.js +1 -1
- package/dist/orchestrator/reviewer.js +14 -14
- package/dist/orchestrator/reviewer.js.map +1 -1
- package/dist/ui/status.js +1 -1
- package/dist/ui/status.js.map +1 -1
- package/dist/ui/toolFormat.js +13 -7
- package/dist/ui/toolFormat.js.map +1 -1
- package/package.json +49 -49
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { open, readdir, readFile, stat } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Built-in content search, used when ripgrep (`rg`) is not installed. It covers what the agent
|
|
5
|
+
* needs (regex, glob filter, case folding, line numbers) with no external dependency, but it is
|
|
6
|
+
* simpler than ripgrep: only a fixed list of folders is skipped, `.gitignore` is not read.
|
|
7
|
+
*/
|
|
8
|
+
const SKIP_DIRS = new Set([".git", "node_modules", "bin", "obj", "dist", ".vs", ".idea", ".tandem", "packages", ".next", "build"]);
|
|
9
|
+
const MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
10
|
+
const MAX_MATCHES_PER_FILE = 200;
|
|
11
|
+
const MAX_MATCHES_TOTAL = 500;
|
|
12
|
+
const MAX_LINE_CHARS = 300;
|
|
13
|
+
const DEADLINE_MS = 25_000;
|
|
14
|
+
/** Expands `{a,b}` groups (not nested), so `*.{ts,tsx}` becomes two patterns. */
|
|
15
|
+
function expandBraces(glob) {
|
|
16
|
+
const m = /\{([^{}]*)\}/.exec(glob);
|
|
17
|
+
if (!m)
|
|
18
|
+
return [glob];
|
|
19
|
+
const [whole, inner] = [m[0], m[1] ?? ""];
|
|
20
|
+
return inner.split(",").flatMap((alt) => expandBraces(glob.replace(whole, alt)));
|
|
21
|
+
}
|
|
22
|
+
function globToRegExp(glob) {
|
|
23
|
+
let re = "";
|
|
24
|
+
for (let i = 0; i < glob.length; i++) {
|
|
25
|
+
const c = glob[i];
|
|
26
|
+
if (c === "*") {
|
|
27
|
+
if (glob[i + 1] === "*") {
|
|
28
|
+
// `**/` matches any number of folders, including none; a bare `**` matches anything.
|
|
29
|
+
if (glob[i + 2] === "/") {
|
|
30
|
+
re += "(?:.*/)?";
|
|
31
|
+
i += 2;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
re += ".*";
|
|
35
|
+
i += 1;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
re += "[^/]*";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (c === "?") {
|
|
43
|
+
re += "[^/]";
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
re += c.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return new RegExp(`^${re}$`, "i");
|
|
50
|
+
}
|
|
51
|
+
/** A glob without a slash matches the file name anywhere (like ripgrep); one with a slash matches the relative path. */
|
|
52
|
+
function buildGlobMatcher(glob) {
|
|
53
|
+
if (!glob)
|
|
54
|
+
return () => true;
|
|
55
|
+
const matchers = expandBraces(glob).map((g) => ({ re: globToRegExp(g.replace(/^\.\//, "")), hasSlash: g.includes("/") }));
|
|
56
|
+
return (relPath) => {
|
|
57
|
+
const base = relPath.slice(relPath.lastIndexOf("/") + 1);
|
|
58
|
+
return matchers.some((m) => m.re.test(m.hasSlash ? relPath : base));
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
async function looksBinary(file) {
|
|
62
|
+
const handle = await open(file, "r");
|
|
63
|
+
try {
|
|
64
|
+
const buf = Buffer.alloc(8000);
|
|
65
|
+
const { bytesRead } = await handle.read(buf, 0, buf.length, 0);
|
|
66
|
+
return buf.subarray(0, bytesRead).includes(0);
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
await handle.close();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export async function searchFallback(opts) {
|
|
73
|
+
let regex;
|
|
74
|
+
try {
|
|
75
|
+
regex = new RegExp(opts.pattern, opts.caseInsensitive ? "i" : "");
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
return { output: `Invalid regex: ${err.message}`, isError: true };
|
|
79
|
+
}
|
|
80
|
+
const root = path.resolve(opts.cwd, opts.searchPath);
|
|
81
|
+
let rootStat;
|
|
82
|
+
try {
|
|
83
|
+
rootStat = await stat(root);
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
return { output: `Search error: ${err.message}`, isError: true };
|
|
87
|
+
}
|
|
88
|
+
const matchesGlob = buildGlobMatcher(opts.glob);
|
|
89
|
+
const deadline = Date.now() + DEADLINE_MS;
|
|
90
|
+
const out = [];
|
|
91
|
+
let timedOut = false;
|
|
92
|
+
let capped = false;
|
|
93
|
+
const rel = (file) => path.relative(opts.cwd, file).split(path.sep).join("/");
|
|
94
|
+
async function searchFile(file) {
|
|
95
|
+
const relPath = rel(file);
|
|
96
|
+
if (!matchesGlob(relPath))
|
|
97
|
+
return;
|
|
98
|
+
try {
|
|
99
|
+
const size = (await stat(file)).size;
|
|
100
|
+
if (size > MAX_FILE_BYTES || (await looksBinary(file)))
|
|
101
|
+
return;
|
|
102
|
+
const text = await readFile(file, "utf8");
|
|
103
|
+
const lines = text.split(/\r\n|\n/);
|
|
104
|
+
let inFile = 0;
|
|
105
|
+
for (let i = 0; i < lines.length; i++) {
|
|
106
|
+
if (!regex.test(lines[i]))
|
|
107
|
+
continue;
|
|
108
|
+
const line = lines[i].trim();
|
|
109
|
+
out.push(`${relPath}:${i + 1}:${line.length > MAX_LINE_CHARS ? `${line.slice(0, MAX_LINE_CHARS)}…` : line}`);
|
|
110
|
+
if (++inFile >= MAX_MATCHES_PER_FILE)
|
|
111
|
+
break;
|
|
112
|
+
if (out.length >= MAX_MATCHES_TOTAL) {
|
|
113
|
+
capped = true;
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// Unreadable or vanished file: skip it, the same as ripgrep does.
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async function walk(dir) {
|
|
123
|
+
if (capped || timedOut)
|
|
124
|
+
return;
|
|
125
|
+
let entries;
|
|
126
|
+
try {
|
|
127
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
133
|
+
for (const e of entries) {
|
|
134
|
+
if (opts.signal?.aborted || capped)
|
|
135
|
+
return;
|
|
136
|
+
if (Date.now() > deadline) {
|
|
137
|
+
timedOut = true;
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const full = path.join(dir, e.name);
|
|
141
|
+
if (e.isDirectory()) {
|
|
142
|
+
if (!SKIP_DIRS.has(e.name))
|
|
143
|
+
await walk(full);
|
|
144
|
+
}
|
|
145
|
+
else if (e.isFile()) {
|
|
146
|
+
await searchFile(full);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (rootStat.isFile())
|
|
151
|
+
await searchFile(root);
|
|
152
|
+
else
|
|
153
|
+
await walk(root);
|
|
154
|
+
const notes = [
|
|
155
|
+
"(ripgrep is not installed; used the built-in search: .gitignore is not applied)",
|
|
156
|
+
...(capped ? [`(stopped after ${MAX_MATCHES_TOTAL} matches; narrow the pattern, path or glob)`] : []),
|
|
157
|
+
...(timedOut ? ["(stopped after 25s; narrow the path or glob)"] : []),
|
|
158
|
+
];
|
|
159
|
+
const body = out.length > 0 ? out.join("\n") : "(no matches)";
|
|
160
|
+
return { output: `${body}\n${notes.join("\n")}`, isError: false };
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=searchFallback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"searchFallback.js","sourceRoot":"","sources":["../../../src/agent/tools/searchFallback.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +1,8 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
+
import { isReadOnlyCommand } from "./safeCommand.js";
|
|
2
3
|
const MAX_OUTPUT_CHARS = 20_000;
|
|
3
4
|
const HARD_MAX_BUFFER_CHARS = 5_000_000;
|
|
4
5
|
const TIMEOUT_MS = 120_000;
|
|
5
|
-
// Konzervativna bela lista — read-only komande koje ne traže odobrenje.
|
|
6
|
-
// Sve što ne poklopi ovde se tretira kao destruktivno; bolje suvišno
|
|
7
|
-
// pitati nego tiho izvršiti nešto nepovratno.
|
|
8
|
-
const SAFE_COMMAND_PATTERNS = [
|
|
9
|
-
/^git\s+(status|log|diff|show|branch|remote(\s+-v)?)\b/i,
|
|
10
|
-
/^(ls|dir)\b/i,
|
|
11
|
-
/^pwd$/i,
|
|
12
|
-
/^(cat|type)\s+\S/i,
|
|
13
|
-
/^echo\s+/i,
|
|
14
|
-
/^(php|node|npm|pnpm|npx|python|python3)\s+(-v|--version|-l)\b/i,
|
|
15
|
-
/^(which|where)\s+\S/i,
|
|
16
|
-
];
|
|
17
6
|
/**
|
|
18
7
|
* `child.kill()` only stops the shell itself; a command it started (node, curl, ...)
|
|
19
8
|
* keeps running and keeps the pipes open, which holds the whole CLI process open
|
|
@@ -102,7 +91,8 @@ export const shellTool = {
|
|
|
102
91
|
},
|
|
103
92
|
isDestructive(args) {
|
|
104
93
|
const command = String(args["command"] ?? "").trim();
|
|
105
|
-
|
|
94
|
+
// Conservative: only a command made entirely of known read-only parts skips the approval prompt.
|
|
95
|
+
return !isReadOnlyCommand(command);
|
|
106
96
|
},
|
|
107
97
|
async execute(args, ctx) {
|
|
108
98
|
const command = String(args["command"] ?? "");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../../src/agent/tools/shell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../../src/agent/tools/shell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAChC,MAAM,qBAAqB,GAAG,SAAS,CAAC;AACxC,MAAM,UAAU,GAAG,OAAO,CAAC;AAQ3B;;;;;GAKG;AACH,SAAS,SAAS,CAAC,KAAmB;IACpC,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC5D,KAAK,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACxG,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,EAAE,CAAC;IACf,CAAC;IACD,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IACxB,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,OAAe,EACf,GAAW,EACX,MAAoB,EACpB,UAA2B,EAAE;IAE7B,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;IAC/C,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC;IACrD,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAClG,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC;IAElD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC7G,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,SAAS,CAAC,KAAK,CAAC,CAAC;YACjB,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,SAAS,GAAG,IAAI,cAAc,CAAC,CAAC,CAAC;QAC7E,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,MAAM,OAAO,GAAG,GAAS,EAAE;YACzB,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,SAAS,CAAC,KAAK,CAAC,CAAC;YACjB,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;YACvD,UAAU,CAAC,IAAI,GAAG,YAAY,CAAC;YAC/B,MAAM,CAAC,UAAU,CAAC,CAAC;QACrB,CAAC,CAAC;QACF,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,CAAC,KAAa,EAAQ,EAAE;YACrC,IAAI,OAAO;gBAAE,OAAO;YACpB,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,MAAM,CAAC,MAAM,GAAG,qBAAqB,EAAE,CAAC;gBAC1C,OAAO,GAAG,IAAI,CAAC;gBACf,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC9C,SAAS,CAAC,KAAK,CAAC,CAAC;gBACjB,MAAM,CACJ,IAAI,KAAK,CACP,+CAA+C,qBAAqB,oEAAoE,CACzI,CACF,CAAC;YACJ,CAAC;QACH,CAAC,CAAC;QACF,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE;YAC7B,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAmB;IACvC,IAAI,EAAE,OAAO;IACb,WAAW,EACT,wGAAwG;IAC1G,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE;SAC5D;QACD,QAAQ,EAAE,CAAC,SAAS,CAAC;KACtB;IACD,aAAa,CAAC,IAAI;QAChB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACrD,iGAAiG;QACjG,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG;QACrB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YAC1E,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAC;YACtH,OAAO;gBACL,MAAM,EAAE,cAAc,QAAQ,MAAM,SAAS,IAAI,aAAa,EAAE;gBAChE,OAAO,EAAE,QAAQ,KAAK,CAAC;aACxB,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,0BAA2B,GAAa,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACvF,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -21,8 +21,8 @@ export const viewImageTool = {
|
|
|
21
21
|
const resolved = path.resolve(ctx.cwd, imagePath);
|
|
22
22
|
try {
|
|
23
23
|
const { text, usage } = await describeImage(ctx.env, resolved, question, ctx.signal);
|
|
24
|
-
// vision-exp
|
|
25
|
-
//
|
|
24
|
+
// vision-exp has no published price list; the cost is reported at the Flash
|
|
25
|
+
// rate as the best available estimate (the actual token counts are exact).
|
|
26
26
|
ctx.usage.add("deepseek-v4-flash", usage);
|
|
27
27
|
return { output: text, isError: false };
|
|
28
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewImage.js","sourceRoot":"","sources":["../../../src/agent/tools/viewImage.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGzD,MAAM,CAAC,MAAM,aAAa,GAAmB;IAC3C,IAAI,EAAE,YAAY;IAClB,WAAW,EACT,+NAA+N;IACjO,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE;YAC3D,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,0GAA0G;aACxH;SACF;QACD,QAAQ,EAAE,CAAC,MAAM,CAAC;KACnB;IACD,aAAa,EAAE,GAAG,EAAE,CAAC,KAAK;IAC1B,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG;QACrB,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAElD,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YACrF,
|
|
1
|
+
{"version":3,"file":"viewImage.js","sourceRoot":"","sources":["../../../src/agent/tools/viewImage.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGzD,MAAM,CAAC,MAAM,aAAa,GAAmB;IAC3C,IAAI,EAAE,YAAY;IAClB,WAAW,EACT,+NAA+N;IACjO,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE;YAC3D,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,0GAA0G;aACxH;SACF;QACD,QAAQ,EAAE,CAAC,MAAM,CAAC;KACnB;IACD,aAAa,EAAE,GAAG,EAAE,CAAC,KAAK;IAC1B,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG;QACrB,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAElD,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YACrF,4EAA4E;YAC5E,2EAA2E;YAC3E,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;YAC1C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,yBAA0B,GAAa,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACtF,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -14,8 +14,8 @@ export const webSearchTool = {
|
|
|
14
14
|
const query = String(args["query"] ?? "");
|
|
15
15
|
try {
|
|
16
16
|
const { text, usage } = await runWebSearch(ctx.env, query, ctx.signal);
|
|
17
|
-
// Responses API
|
|
18
|
-
//
|
|
17
|
+
// The Responses API has no separate published price list; the cost is reported at
|
|
18
|
+
// the Flash rate as the best available estimate (the actual token counts are exact).
|
|
19
19
|
ctx.usage.add("deepseek-v4-flash", usage);
|
|
20
20
|
return { output: text, isError: false };
|
|
21
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webSearch.js","sourceRoot":"","sources":["../../../src/agent/tools/webSearch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAG3D,MAAM,CAAC,MAAM,aAAa,GAAmB;IAC3C,IAAI,EAAE,YAAY;IAClB,WAAW,EACT,uKAAuK;IACzK,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE;SACxD;QACD,QAAQ,EAAE,CAAC,OAAO,CAAC;KACpB;IACD,aAAa,EAAE,GAAG,EAAE,CAAC,KAAK;IAC1B,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG;QACrB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YACvE,
|
|
1
|
+
{"version":3,"file":"webSearch.js","sourceRoot":"","sources":["../../../src/agent/tools/webSearch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAG3D,MAAM,CAAC,MAAM,aAAa,GAAmB;IAC3C,IAAI,EAAE,YAAY;IAClB,WAAW,EACT,uKAAuK;IACzK,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE;SACxD;QACD,QAAQ,EAAE,CAAC,OAAO,CAAC;KACpB;IACD,aAAa,EAAE,GAAG,EAAE,CAAC,KAAK;IAC1B,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG;QACrB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YACvE,kFAAkF;YAClF,qFAAqF;YACrF,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;YAC1C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,iBAAkB,GAAa,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC9E,CAAC;IACH,CAAC;CACF,CAAC"}
|
package/dist/agent/usage.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { estimateCallCost, isPeakHour } from "./pricing.js";
|
|
2
|
-
/**
|
|
2
|
+
/** Strictly from the API `usage` field; never a client-side token estimate. */
|
|
3
3
|
export class UsageAccumulator {
|
|
4
4
|
entries = [];
|
|
5
5
|
add(model, usage) {
|
|
@@ -28,7 +28,7 @@ export class UsageAccumulator {
|
|
|
28
28
|
estimatedCostUsd() {
|
|
29
29
|
return this.entries.reduce((sum, e) => sum + estimateCallCost(e.model, e.usage, e.isPeak), 0);
|
|
30
30
|
}
|
|
31
|
-
/**
|
|
31
|
+
/** What this session would have cost had every call fallen into the off-peak window. */
|
|
32
32
|
offPeakEquivalentCostUsd() {
|
|
33
33
|
return this.entries.reduce((sum, e) => sum + estimateCallCost(e.model, e.usage, false), 0);
|
|
34
34
|
}
|
package/dist/agent/usage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/agent/usage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAQ5D
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/agent/usage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAQ5D,+EAA+E;AAC/E,MAAM,OAAO,gBAAgB;IACnB,OAAO,GAAiB,EAAE,CAAC;IAEnC,GAAG,CAAC,KAA8C,EAAE,KAAgB;QAClE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CACxB,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,YAAY,EAAE,GAAG,CAAC,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,YAAY;YACrD,gBAAgB,EAAE,GAAG,CAAC,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,gBAAgB;YACjE,WAAW,EAAE,GAAG,CAAC,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW;YAClD,oBAAoB,EAAE,GAAG,CAAC,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,oBAAoB;YAC7E,qBAAqB,EAAE,GAAG,CAAC,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,qBAAqB;YAChF,eAAe,EAAE,GAAG,CAAC,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,eAAe;SAC/D,CAAC,EACF;YACE,YAAY,EAAE,CAAC;YACf,gBAAgB,EAAE,CAAC;YACnB,WAAW,EAAE,CAAC;YACd,oBAAoB,EAAE,CAAC;YACvB,qBAAqB,EAAE,CAAC;YACxB,eAAe,EAAE,CAAC;SACnB,CACF,CAAC;IACJ,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAChG,CAAC;IAED,wFAAwF;IACxF,wBAAwB;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7F,CAAC;CACF"}
|
package/dist/benchmark/runner.js
CHANGED
|
@@ -6,9 +6,9 @@ import { runOrchestration } from "../orchestrator/orchestrate.js";
|
|
|
6
6
|
import { createSession, appendSessionMessage } from "../agent/session.js";
|
|
7
7
|
import { UsageAccumulator } from "../agent/usage.js";
|
|
8
8
|
const execFileAsync = promisify(execFile);
|
|
9
|
-
const SYSTEM_PROMPT = `You are a coding agent fixing a reported bug in a WordPress/WooCommerce
|
|
10
|
-
plugin. Use the available tools (read_file, list_dir, search, edit, git_diff,
|
|
11
|
-
shell) to find and fix exactly the bug described. When you are done, reply
|
|
9
|
+
const SYSTEM_PROMPT = `You are a coding agent fixing a reported bug in a WordPress/WooCommerce
|
|
10
|
+
plugin. Use the available tools (read_file, list_dir, search, edit, git_diff,
|
|
11
|
+
shell) to find and fix exactly the bug described. When you are done, reply
|
|
12
12
|
concisely without further tool calls.`;
|
|
13
13
|
async function resetRepo(repoPath, baselineRef) {
|
|
14
14
|
await execFileAsync("git", ["reset", "--hard", baselineRef], { cwd: repoPath });
|
|
@@ -65,9 +65,9 @@ export async function runOneAttempt(env, config, task, repoPath, baselineRef) {
|
|
|
65
65
|
usage,
|
|
66
66
|
runWorkerTurn: (turn) => runHeadlessTurn(turn.messages, turn.model, turn.thinking, env, repoPath, session, usage, stats),
|
|
67
67
|
});
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
//
|
|
68
|
+
// Orchestration has no single "final" signal like the plain loop: "completed" here
|
|
69
|
+
// means the pipeline ran to the end without an exception, not that the reviewer
|
|
70
|
+
// approved (that is covered by the "correct" dimension via the verify script).
|
|
71
71
|
stats.completed = true;
|
|
72
72
|
}
|
|
73
73
|
else {
|
|
@@ -164,8 +164,8 @@ export async function runBenchmark(env, tasks, configs, repoPath, baselineRef, o
|
|
|
164
164
|
durationMs: 0,
|
|
165
165
|
error: message,
|
|
166
166
|
});
|
|
167
|
-
//
|
|
168
|
-
//
|
|
167
|
+
// Put the repo back in a clean state even after a failure mid-attempt, so the
|
|
168
|
+
// next task/config does not inherit a half-modified working tree.
|
|
169
169
|
await resetRepo(repoPath, baselineRef).catch(() => { });
|
|
170
170
|
}
|
|
171
171
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/benchmark/runner.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/benchmark/runner.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -22,7 +22,8 @@ import { notifyCompletion } from "./orchestrator/notify.js";
|
|
|
22
22
|
import { appendSessionMessage, createSession, findLatestSession, loadSessionMessages } from "./agent/session.js";
|
|
23
23
|
import { formatToolCall, formatToolResult } from "./ui/toolFormat.js";
|
|
24
24
|
import { formatStatusLine } from "./ui/status.js";
|
|
25
|
-
|
|
25
|
+
import { describeError } from "./deepseek/errors.js";
|
|
26
|
+
/** Pseudo-tool used to ask "continue after the iteration limit?" through the same y/n/a mechanism. */
|
|
26
27
|
const CONTINUE_TOOL = "__continue__";
|
|
27
28
|
function approvalText(toolName, args) {
|
|
28
29
|
if (toolName === CONTINUE_TOOL) {
|
|
@@ -36,9 +37,9 @@ function diffColor(kind) {
|
|
|
36
37
|
function diffPrefix(kind) {
|
|
37
38
|
return kind === "removed" ? "- " : kind === "added" ? "+ " : " ";
|
|
38
39
|
}
|
|
39
|
-
//
|
|
40
|
-
// "Thinking…" preview,
|
|
41
|
-
//
|
|
40
|
+
// Only the last N characters are shown while the model is thinking: enough for the
|
|
41
|
+
// "Thinking…" preview, and it stops Ink from re-rendering/re-laying-out the whole
|
|
42
|
+
// (potentially huge) growing string on every token, which is an O(n²) cost and can exhaust the heap.
|
|
42
43
|
const REASONING_DISPLAY_CAP = 4_000;
|
|
43
44
|
function TurnView({ state, turn, askApproval, onDone, }) {
|
|
44
45
|
const { exit } = useApp();
|
|
@@ -50,6 +51,7 @@ function TurnView({ state, turn, askApproval, onDone, }) {
|
|
|
50
51
|
const [error, setError] = useState(null);
|
|
51
52
|
const [notice, setNotice] = useState(null);
|
|
52
53
|
const [iter, setIter] = useState(null);
|
|
54
|
+
const [retryNote, setRetryNote] = useState(null);
|
|
53
55
|
useEffect(() => {
|
|
54
56
|
async function run() {
|
|
55
57
|
const approve = async (toolName, args) => {
|
|
@@ -76,7 +78,7 @@ function TurnView({ state, turn, askApproval, onDone, }) {
|
|
|
76
78
|
maxIterations: state.maxIterations,
|
|
77
79
|
onIterationLimit: async ({ iterations }) => {
|
|
78
80
|
const chunk = state.maxIterations;
|
|
79
|
-
//
|
|
81
|
+
// Auto-continue only with a budget: the budget hard-stops the loop before the next call.
|
|
80
82
|
if (state.autoContinue && turn.budgetUsd !== undefined) {
|
|
81
83
|
setNotice(t("autoContinued", {
|
|
82
84
|
n: iterations,
|
|
@@ -87,7 +89,7 @@ function TurnView({ state, turn, askApproval, onDone, }) {
|
|
|
87
89
|
}
|
|
88
90
|
if (state.alwaysApprovedTools.has(CONTINUE_TOOL))
|
|
89
91
|
return true;
|
|
90
|
-
// --yes
|
|
92
|
+
// --yes means "no questions" (scripts/CI): nobody can answer, so do not wait on stdin.
|
|
91
93
|
if (state.autoApprove) {
|
|
92
94
|
setNotice(t("continueStopped"));
|
|
93
95
|
return false;
|
|
@@ -108,15 +110,18 @@ function TurnView({ state, turn, askApproval, onDone, }) {
|
|
|
108
110
|
function handleEvent(event) {
|
|
109
111
|
switch (event.type) {
|
|
110
112
|
case "reasoning_delta":
|
|
113
|
+
setRetryNote(null);
|
|
111
114
|
setReasoning((prev) => {
|
|
112
115
|
const next = prev + event.delta;
|
|
113
116
|
return next.length > REASONING_DISPLAY_CAP ? next.slice(-REASONING_DISPLAY_CAP) : next;
|
|
114
117
|
});
|
|
115
118
|
break;
|
|
116
119
|
case "content_delta":
|
|
120
|
+
setRetryNote(null);
|
|
117
121
|
setContent((prev) => prev + event.delta);
|
|
118
122
|
break;
|
|
119
123
|
case "tool_call_start":
|
|
124
|
+
setRetryNote(null);
|
|
120
125
|
setToolLog((prev) => [...prev, { id: event.id, name: event.name, args: event.args, status: "running" }]);
|
|
121
126
|
break;
|
|
122
127
|
case "tool_call_result":
|
|
@@ -136,6 +141,14 @@ function TurnView({ state, turn, askApproval, onDone, }) {
|
|
|
136
141
|
case "iteration":
|
|
137
142
|
setIter({ n: event.n, max: event.max });
|
|
138
143
|
break;
|
|
144
|
+
case "retrying":
|
|
145
|
+
setRetryNote(t("retrying", {
|
|
146
|
+
attempt: event.attempt,
|
|
147
|
+
max: event.max,
|
|
148
|
+
seconds: Math.max(1, Math.round(event.delayMs / 1000)),
|
|
149
|
+
reason: event.reason,
|
|
150
|
+
}));
|
|
151
|
+
break;
|
|
139
152
|
case "max_iterations_reached":
|
|
140
153
|
setNotice((prev) => prev ?? t("maxIterations"));
|
|
141
154
|
break;
|
|
@@ -150,7 +163,8 @@ function TurnView({ state, turn, askApproval, onDone, }) {
|
|
|
150
163
|
}
|
|
151
164
|
run()
|
|
152
165
|
.catch((err) => {
|
|
153
|
-
setError(
|
|
166
|
+
setError(describeError(err));
|
|
167
|
+
setNotice(t("errorSessionSaved"));
|
|
154
168
|
})
|
|
155
169
|
.finally(() => {
|
|
156
170
|
exit();
|
|
@@ -168,7 +182,7 @@ function TurnView({ state, turn, askApproval, onDone, }) {
|
|
|
168
182
|
const color = diffColor(line.kind);
|
|
169
183
|
return (_jsxs(Text, { ...(color ? { color } : { dimColor: true }), children: [" ", diffPrefix(line.kind), line.text] }, i));
|
|
170
184
|
}), summary ? (_jsxs(Text, { dimColor: true, children: [" ⎿ ", summary] })) : (preview && (_jsxs(Text, { dimColor: true, ...(entry.isError ? { color: "red" } : {}), children: [" ⎿ ", preview.slice(0, 400), more || preview.length > 400 ? t("toolMoreLines", { count: lines.length }) : ""] })))] }, entry.id));
|
|
171
|
-
}), pending && pending.toolName === CONTINUE_TOOL && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [_jsx(Text, { color: "yellow", bold: true, children: t("continueAsk", { n: Number(pending.args["iterations"] ?? 0) }) }), _jsx(Text, { dimColor: true, children: t("continueHint", { chunk: Number(pending.args["chunk"] ?? 0) }) })] })), pending && pending.toolName !== CONTINUE_TOOL && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [_jsx(Text, { color: "yellow", bold: true, children: t("destructiveAction", { call: `${pending.toolName}(${JSON.stringify(pending.args)})` }) }), _jsx(Text, { dimColor: true, children: t("approvalHint") })] })), content.length > 0 && _jsx(Text, { children: content }), usageLine && _jsx(Text, { color: "gray", children: usageLine }), notice && _jsx(Text, { color: "yellow", children: notice }), error && _jsx(Text, { color: "red", children: t("errorPrefix", { message: error }) }), _jsx(StatusBar, { state: state, turn: turn, iter: iter })] }));
|
|
185
|
+
}), pending && pending.toolName === CONTINUE_TOOL && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [_jsx(Text, { color: "yellow", bold: true, children: t("continueAsk", { n: Number(pending.args["iterations"] ?? 0) }) }), _jsx(Text, { dimColor: true, children: t("continueHint", { chunk: Number(pending.args["chunk"] ?? 0) }) })] })), pending && pending.toolName !== CONTINUE_TOOL && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [_jsx(Text, { color: "yellow", bold: true, children: t("destructiveAction", { call: `${pending.toolName}(${JSON.stringify(pending.args)})` }) }), _jsx(Text, { dimColor: true, children: t("approvalHint") })] })), content.length > 0 && _jsx(Text, { children: content }), usageLine && _jsx(Text, { color: "gray", children: usageLine }), retryNote && _jsx(Text, { color: "yellow", children: retryNote }), notice && _jsx(Text, { color: "yellow", children: notice }), error && _jsx(Text, { color: "red", children: t("errorPrefix", { message: error }) }), _jsx(StatusBar, { state: state, turn: turn, iter: iter })] }));
|
|
172
186
|
}
|
|
173
187
|
function StatusBar({ state, turn, iter, }) {
|
|
174
188
|
const status = formatStatusLine({
|
|
@@ -237,7 +251,7 @@ async function runPlanTask(state, task, askApproval, signal) {
|
|
|
237
251
|
console.log(t("orchestrationInterrupted"));
|
|
238
252
|
}
|
|
239
253
|
else {
|
|
240
|
-
const message =
|
|
254
|
+
const message = describeError(err);
|
|
241
255
|
console.error(t("orchestrationError", { message }));
|
|
242
256
|
await notifyCompletion(state.notifyCommand, state.cwd, {
|
|
243
257
|
outcome: "error",
|
|
@@ -258,7 +272,7 @@ function parseApprovalAnswer(raw) {
|
|
|
258
272
|
return { approved: true, always: true };
|
|
259
273
|
return { approved: lower === "y", always: false };
|
|
260
274
|
}
|
|
261
|
-
/**
|
|
275
|
+
/** For single-shot turns: its own for-await line reader, only for y/n/a approvals. */
|
|
262
276
|
function createLineApprover() {
|
|
263
277
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
264
278
|
const resolveRef = { current: null };
|
|
@@ -280,10 +294,10 @@ function createLineApprover() {
|
|
|
280
294
|
return { approve, close: () => rl.close() };
|
|
281
295
|
}
|
|
282
296
|
/**
|
|
283
|
-
* `.question()`
|
|
284
|
-
* (
|
|
285
|
-
*
|
|
286
|
-
*
|
|
297
|
+
* `.question()` is unreliable on piped/non-TTY stdin after the first call
|
|
298
|
+
* (a known Node quirk: the second call never resolves). So lines are read
|
|
299
|
+
* exclusively through `for await...of rl`, which delivers every line reliably,
|
|
300
|
+
* with a manual state machine for approvals instead of a nested
|
|
287
301
|
* `.question()`.
|
|
288
302
|
*/
|
|
289
303
|
async function runRepl(state) {
|
|
@@ -310,8 +324,8 @@ async function runRepl(state) {
|
|
|
310
324
|
approvalRef.current = resolve;
|
|
311
325
|
});
|
|
312
326
|
};
|
|
313
|
-
// ESC
|
|
314
|
-
//
|
|
327
|
+
// ESC interrupts the current turn. Works only on a real TTY: piped/scripted
|
|
328
|
+
// input generates no keypress events, so the interrupt is a silent no-op there.
|
|
315
329
|
const abortRef = { current: null };
|
|
316
330
|
readline.emitKeypressEvents(process.stdin);
|
|
317
331
|
process.stdin.on("keypress", (_str, key) => {
|
|
@@ -565,7 +579,7 @@ async function main() {
|
|
|
565
579
|
}
|
|
566
580
|
}
|
|
567
581
|
main().catch((err) => {
|
|
568
|
-
console.error(
|
|
582
|
+
console.error(describeError(err));
|
|
569
583
|
process.exitCode = 1;
|
|
570
584
|
});
|
|
571
585
|
//# sourceMappingURL=cli.js.map
|