@illuminis/comprism 0.1.2 → 0.1.4
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 +98 -36
- package/out/agent/command.d.ts +75 -4
- package/out/agent/command.js +220 -25
- package/out/agent/render.d.ts +17 -2
- package/out/agent/render.js +157 -14
- package/out/agent/session.d.ts +141 -2
- package/out/agent/session.js +735 -149
- package/out/commands/agents.d.ts +2 -0
- package/out/commands/agents.js +79 -0
- package/out/commands/ask.d.ts +1 -1
- package/out/commands/ask.js +78 -11
- package/out/commands/commands-thin.js +79 -17
- package/out/commands/config.d.ts +1 -0
- package/out/commands/config.js +138 -0
- package/out/commands/cost.d.ts +1 -0
- package/out/commands/cost.js +167 -0
- package/out/commands/hooks.d.ts +1 -0
- package/out/commands/hooks.js +83 -0
- package/out/commands/install.d.ts +44 -1
- package/out/commands/install.js +198 -4
- package/out/commands/instructions.d.ts +1 -0
- package/out/commands/instructions.js +113 -0
- package/out/commands/integrations.d.ts +3 -0
- package/out/commands/integrations.js +215 -0
- package/out/commands/jobs.d.ts +5 -0
- package/out/commands/jobs.js +157 -0
- package/out/commands/login.js +188 -36
- package/out/commands/memory.d.ts +3 -0
- package/out/commands/memory.js +113 -0
- package/out/commands/permissions.d.ts +1 -0
- package/out/commands/permissions.js +94 -0
- package/out/commands/plugins.d.ts +4 -0
- package/out/commands/plugins.js +192 -0
- package/out/commands/privacy.d.ts +1 -0
- package/out/commands/privacy.js +57 -0
- package/out/commands/providerKey.d.ts +32 -0
- package/out/commands/providerKey.js +108 -0
- package/out/commands/repl.d.ts +8 -1
- package/out/commands/repl.js +1207 -118
- package/out/commands/report.d.ts +39 -0
- package/out/commands/report.js +115 -0
- package/out/commands/review.d.ts +5 -0
- package/out/commands/review.js +223 -0
- package/out/commands/sessions.d.ts +23 -0
- package/out/commands/sessions.js +115 -0
- package/out/commands/settings.d.ts +3 -1
- package/out/commands/settings.js +18 -16
- package/out/commands/skills.d.ts +21 -0
- package/out/commands/skills.js +207 -0
- package/out/commands/unattended.d.ts +7 -0
- package/out/commands/unattended.js +351 -0
- package/out/commands/update.d.ts +1 -0
- package/out/commands/update.js +123 -0
- package/out/commands/worktrees.d.ts +5 -0
- package/out/commands/worktrees.js +186 -0
- package/out/executor/browser.d.ts +14 -0
- package/out/executor/browser.js +270 -0
- package/out/executor/diagnostics.d.ts +2 -0
- package/out/executor/diagnostics.js +181 -0
- package/out/executor/files.js +270 -40
- package/out/executor/git.js +42 -29
- package/out/executor/hooks.d.ts +42 -58
- package/out/executor/hooks.js +89 -182
- package/out/executor/index.d.ts +21 -5
- package/out/executor/index.js +160 -14
- package/out/executor/paths.d.ts +6 -1
- package/out/executor/paths.js +34 -6
- package/out/executor/sandbox.d.ts +40 -0
- package/out/executor/sandbox.js +299 -0
- package/out/executor/shell.d.ts +49 -4
- package/out/executor/shell.js +302 -56
- package/out/executor/toolservers.d.ts +20 -0
- package/out/executor/toolservers.js +189 -0
- package/out/executor/worktree.d.ts +9 -0
- package/out/executor/worktree.js +119 -0
- package/out/graph/read-python.js +2 -1
- package/out/lib/attach.d.ts +56 -12
- package/out/lib/attach.js +230 -63
- package/out/lib/clipboard.d.ts +23 -0
- package/out/lib/clipboard.js +182 -0
- package/out/lib/commandlist.d.ts +20 -0
- package/out/lib/commandlist.js +58 -0
- package/out/lib/decision.d.ts +22 -0
- package/out/lib/decision.js +50 -0
- package/out/lib/fingerprint.d.ts +25 -0
- package/out/lib/fingerprint.js +58 -0
- package/out/lib/gateway.d.ts +186 -2
- package/out/lib/gateway.js +59 -4
- package/out/lib/history.d.ts +24 -0
- package/out/lib/history.js +137 -0
- package/out/lib/ide.d.ts +19 -0
- package/out/lib/ide.js +131 -0
- package/out/lib/keyboard.d.ts +95 -0
- package/out/lib/keyboard.js +383 -0
- package/out/lib/machine.d.ts +21 -0
- package/out/lib/machine.js +91 -0
- package/out/lib/notify.d.ts +4 -0
- package/out/lib/notify.js +52 -0
- package/out/lib/output.d.ts +48 -0
- package/out/lib/output.js +108 -0
- package/out/lib/project-ops.d.ts +19 -0
- package/out/lib/project-ops.js +146 -0
- package/out/lib/project.d.ts +28 -0
- package/out/lib/project.js +114 -0
- package/out/lib/prompt.js +15 -2
- package/out/lib/queue.d.ts +13 -0
- package/out/lib/queue.js +116 -0
- package/out/lib/readiness.d.ts +19 -0
- package/out/lib/readiness.js +170 -1
- package/out/lib/self.d.ts +23 -0
- package/out/lib/self.js +124 -0
- package/out/lib/sessions.d.ts +19 -0
- package/out/lib/sessions.js +221 -0
- package/out/lib/stdin.d.ts +32 -0
- package/out/lib/stdin.js +117 -0
- package/out/lib/store.d.ts +40 -0
- package/out/lib/store.js +138 -0
- package/out/lib/sync.d.ts +18 -0
- package/out/lib/sync.js +81 -0
- package/out/lib/ui.d.ts +2 -4
- package/out/lib/ui.js +31 -25
- package/out/lib/voice.js +24 -0
- package/out/postinstall.js +42 -14
- package/out/providers/anthropic.d.ts +22 -0
- package/out/providers/anthropic.js +80 -0
- package/out/providers/index.d.ts +8 -0
- package/out/providers/index.js +83 -0
- package/out/providers/openai.d.ts +11 -0
- package/out/providers/openai.js +57 -0
- package/out/thin.js +609 -21
- package/package.json +9 -49
package/out/agent/render.js
CHANGED
|
@@ -22,23 +22,29 @@
|
|
|
22
22
|
* symbol as well as a color.
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.gray = exports.yellow = exports.green = exports.red = exports.bold = exports.dim = void 0;
|
|
25
|
+
exports.violet = exports.gray = exports.yellow = exports.green = exports.red = exports.bold = exports.dim = void 0;
|
|
26
|
+
exports.modelName = modelName;
|
|
26
27
|
exports.money = money;
|
|
27
28
|
exports.duration = duration;
|
|
28
29
|
exports.action = action;
|
|
30
|
+
exports.actionName = actionName;
|
|
29
31
|
exports.reusePct = reusePct;
|
|
30
32
|
exports.step = step;
|
|
31
33
|
exports.todos = todos;
|
|
34
|
+
exports.question = question;
|
|
32
35
|
exports.diff = diff;
|
|
36
|
+
exports.stoppedLines = stoppedLines;
|
|
37
|
+
exports.ending = ending;
|
|
33
38
|
exports.outcome = outcome;
|
|
34
39
|
exports.receipt = receipt;
|
|
35
40
|
exports.plain = plain;
|
|
36
41
|
/** Built from a character code rather than written as a literal escape, so this
|
|
37
42
|
* file contains no control characters and stays safe to grep, diff and paste. */
|
|
38
43
|
const CSI = String.fromCharCode(27) + "[";
|
|
39
|
-
|
|
44
|
+
/** Decided when drawn, so plain mode set at start up applies (manual 6.12). */
|
|
45
|
+
const supportsColour = () => process.stdout.isTTY && !process.env.NO_COLOR;
|
|
40
46
|
function paint(code, text) {
|
|
41
|
-
return supportsColour ? CSI + code + "m" + text + CSI + "0m" : text;
|
|
47
|
+
return supportsColour() ? CSI + code + "m" + text + CSI + "0m" : text;
|
|
42
48
|
}
|
|
43
49
|
const dim = (t) => paint("2", t);
|
|
44
50
|
exports.dim = dim;
|
|
@@ -52,6 +58,34 @@ const yellow = (t) => paint("33", t);
|
|
|
52
58
|
exports.yellow = yellow;
|
|
53
59
|
const gray = (t) => paint("90", t);
|
|
54
60
|
exports.gray = gray;
|
|
61
|
+
/** The brand's violet, for model names and the receipt's label. */
|
|
62
|
+
const violet = (t) => paint("38;5;141", t);
|
|
63
|
+
exports.violet = violet;
|
|
64
|
+
/** The rail down the left of a job's steps, as the website draws it. */
|
|
65
|
+
const rail = () => (0, exports.dim)("\u2502");
|
|
66
|
+
const TICK = "\u2713";
|
|
67
|
+
const CROSS = "\u2717";
|
|
68
|
+
/** What a person sees, with color and link escapes taken out, so lines can be
|
|
69
|
+
* measured and padded. */
|
|
70
|
+
function visible(text) {
|
|
71
|
+
const esc = String.fromCharCode(27);
|
|
72
|
+
return text
|
|
73
|
+
.replace(new RegExp(`${esc}\\][^${String.fromCharCode(7)}${esc}]*(?:${String.fromCharCode(7)}|${esc}\\\\)`, "g"), "")
|
|
74
|
+
.replace(new RegExp(`${esc}\\[[0-9;]*m`, "g"), "");
|
|
75
|
+
}
|
|
76
|
+
function width() {
|
|
77
|
+
return Math.max(60, Math.min(process.stdout.columns || 100, 110));
|
|
78
|
+
}
|
|
79
|
+
/** `claude-haiku-4-5` as a person says it, `Claude Haiku 4.5`. Other vendors'
|
|
80
|
+
* ids are shown as they arrive: a wrong guess at a name is worse than the id. */
|
|
81
|
+
function modelName(id) {
|
|
82
|
+
const m = /^claude-([a-z]+)-(\d+)(?:-(\d+))?$/.exec(id);
|
|
83
|
+
if (!m)
|
|
84
|
+
return id;
|
|
85
|
+
const word = m[1] ?? "";
|
|
86
|
+
const family = word.charAt(0).toUpperCase() + word.slice(1);
|
|
87
|
+
return `Claude ${family} ${m[2]}${m[3] ? `.${m[3]}` : ""}`;
|
|
88
|
+
}
|
|
55
89
|
/** Money, at the precision a person can act on.
|
|
56
90
|
*
|
|
57
91
|
* Four decimal places below a cent, because a coding step often costs less
|
|
@@ -70,9 +104,16 @@ function duration(ms) {
|
|
|
70
104
|
/** One action, as it happens. A word as well as a color, so this still reads
|
|
71
105
|
* when piped to a file. */
|
|
72
106
|
function action(name, target, ok, ms) {
|
|
73
|
-
|
|
107
|
+
// A tick or a cross on the rail, as the website draws a job. A failure also
|
|
108
|
+
// says so in words, so it still reads in a log with no color.
|
|
109
|
+
const mark = ok ? (0, exports.green)(TICK) : (0, exports.red)(`${CROSS} failed`);
|
|
74
110
|
const tail = ms ? (0, exports.dim)(` ${duration(ms)}`) : "";
|
|
75
|
-
return ` ${mark} ${(0, exports.bold)(name)} ${(0, exports.dim)(target)}${tail}`;
|
|
111
|
+
return ` ${rail()} ${mark} ${(0, exports.bold)(actionName(name))} ${(0, exports.dim)(target)}${tail}`;
|
|
112
|
+
}
|
|
113
|
+
/** A connected tool as people write it, `server.tool` (manual 9.10). */
|
|
114
|
+
function actionName(name) {
|
|
115
|
+
const m = /^connected__(.+?)__(.+)$/.exec(name);
|
|
116
|
+
return m ? `${m[1]}.${m[2]}` : name;
|
|
76
117
|
}
|
|
77
118
|
/** The share of a step's context the provider served from its cache, or null
|
|
78
119
|
* when it reported no counts. Anthropic counts cached tokens OUTSIDE the input
|
|
@@ -89,9 +130,16 @@ function reusePct(tokensIn, cacheRead, cacheWrite) {
|
|
|
89
130
|
* provider had already seen. The last figure is the one study 005 found
|
|
90
131
|
* missing from our receipt: without it nobody could tell a warm step from a
|
|
91
132
|
* cold one, and every step was cold. */
|
|
92
|
-
function step(index, model, usd, ms, reused = null) {
|
|
133
|
+
function step(index, model, usd, ms, reused = null, reason = "") {
|
|
93
134
|
const warm = reused === null ? "" : ` cached ${reused}%`;
|
|
94
|
-
|
|
135
|
+
// The model that ran and why, in the service's words (manual 4.16).
|
|
136
|
+
const why = reason ? ` chosen: ${reason}` : "";
|
|
137
|
+
// The step and why its model was chosen on the left, the model on the right,
|
|
138
|
+
// as the website draws a job; the cost and timing follow, quieter.
|
|
139
|
+
const left = ` ${rail()} ${(0, exports.dim)(`step ${index}${why}`)}`;
|
|
140
|
+
const right = `${(0, exports.violet)(modelName(model || "?"))}${(0, exports.dim)(` ${money(usd)} ${duration(ms)}${warm}`)}`;
|
|
141
|
+
const gap = Math.max(2, width() - visible(left).length - visible(right).length - 2);
|
|
142
|
+
return `${left}${" ".repeat(gap)}${right}`;
|
|
95
143
|
}
|
|
96
144
|
/** The task list, reprinted whenever it changes.
|
|
97
145
|
*
|
|
@@ -99,24 +147,33 @@ function step(index, model, usd, ms, reused = null) {
|
|
|
99
147
|
* is worth keeping, and it is often the fastest way to see where a job went off
|
|
100
148
|
* course. */
|
|
101
149
|
function todos(items) {
|
|
150
|
+
// Drawn as manual 4.4 shows it: [x] done, [>] in progress, [ ] not yet.
|
|
102
151
|
if (!items.length)
|
|
103
152
|
return "";
|
|
104
153
|
const rows = items.map((t) => {
|
|
105
|
-
const mark = t.status === "completed" ? (0, exports.green)("
|
|
106
|
-
: t.status === "in_progress" ? (0, exports.yellow)("
|
|
154
|
+
const mark = t.status === "completed" ? (0, exports.green)("[x]")
|
|
155
|
+
: t.status === "in_progress" ? (0, exports.yellow)("[>]") : (0, exports.dim)("[ ]");
|
|
107
156
|
const text = t.status === "completed" ? (0, exports.dim)(t.content) : t.content;
|
|
108
|
-
return `
|
|
157
|
+
return ` ${mark} ${text}`;
|
|
109
158
|
});
|
|
110
|
-
return
|
|
159
|
+
return `${rows.join("\n")}\n`;
|
|
160
|
+
}
|
|
161
|
+
/** A question from the agent, or the plan question (manual 4.2, 4.3). The
|
|
162
|
+
* wording is the service's; this only lays it out. */
|
|
163
|
+
function question(q, options) {
|
|
164
|
+
const lines = [` ${(0, exports.bold)("Question:")} ${q}`];
|
|
165
|
+
options.forEach((o, i) => lines.push(` ${i + 1} ${o}`));
|
|
166
|
+
return `\n${lines.join("\n")}\n`;
|
|
111
167
|
}
|
|
112
168
|
/** A change, before it is made.
|
|
113
169
|
*
|
|
114
170
|
* Full text for a small edit and a summary for a large one. Pasting four
|
|
115
171
|
* hundred lines into a terminal is not review, it is a wall somebody presses
|
|
116
172
|
* through, and an approval people press through protects nobody. */
|
|
117
|
-
function diff(name, input) {
|
|
173
|
+
function diff(name, input, withHead = true) {
|
|
118
174
|
const target = String(input.path ?? input.to ?? "");
|
|
119
|
-
|
|
175
|
+
// Without the heading under an action line that already names the file.
|
|
176
|
+
const head = withHead ? `\n ${(0, exports.bold)(name)} ${target}\n` : "";
|
|
120
177
|
const show = (from, to) => {
|
|
121
178
|
const before = from.split("\n"), after = to.split("\n");
|
|
122
179
|
if (before.length + after.length > 60) {
|
|
@@ -142,6 +199,12 @@ function diff(name, input) {
|
|
|
142
199
|
}
|
|
143
200
|
return head + ` ${(0, exports.dim)(`${lines.length} lines, ${bodyText.length.toLocaleString()} characters`)}\n`;
|
|
144
201
|
}
|
|
202
|
+
if (name === "git_commit") {
|
|
203
|
+
// What will be committed, shown before it is (manual 5.17).
|
|
204
|
+
const files = input.paths ?? [];
|
|
205
|
+
return `\n ${(0, exports.bold)("git_commit")}\n files ${files.join(", ") || (0, exports.dim)("none")}\n`
|
|
206
|
+
+ ` message ${String(input.message ?? "").split("\n")[0]}\n`;
|
|
207
|
+
}
|
|
145
208
|
if (name === "run_command" || name === "run_background") {
|
|
146
209
|
return `\n ${(0, exports.bold)("run")} ${String(input.command ?? "")}\n`;
|
|
147
210
|
}
|
|
@@ -154,6 +217,22 @@ function diff(name, input) {
|
|
|
154
217
|
}
|
|
155
218
|
return head;
|
|
156
219
|
}
|
|
220
|
+
/** What was stopped when a session ended, one line each (manual 5.13). */
|
|
221
|
+
function stoppedLines(stopped) {
|
|
222
|
+
if (!stopped.length)
|
|
223
|
+
return "";
|
|
224
|
+
return (0, exports.dim)(` stopped the background process${stopped.length === 1 ? "" : "es"} this session started:\n`)
|
|
225
|
+
+ stopped.map((l) => (0, exports.dim)(` ${l}\n`)).join("");
|
|
226
|
+
}
|
|
227
|
+
/** The first line of a finished job, as the service wrote it (manual 5.15).
|
|
228
|
+
* Colored by its first word only; the words are the service's. */
|
|
229
|
+
function ending(line, detail) {
|
|
230
|
+
const paint = /^Done$/.test(line) ? exports.green : /^Done,/.test(line) ? exports.yellow
|
|
231
|
+
: /^(Stopped|Incomplete)/.test(line) ? exports.red : (t) => t;
|
|
232
|
+
// The service may put the same words in both; they are said once.
|
|
233
|
+
const extra = detail && detail !== line ? (0, exports.dim)(` ${detail}`) : "";
|
|
234
|
+
return `\n${paint(line)}${extra}\n`;
|
|
235
|
+
}
|
|
157
236
|
/** How the job ended, in the words a person reads. */
|
|
158
237
|
function outcome(o, detail) {
|
|
159
238
|
const word = {
|
|
@@ -163,6 +242,8 @@ function outcome(o, detail) {
|
|
|
163
242
|
spend_limit: (0, exports.yellow)("Stopped at the spending limit"),
|
|
164
243
|
failed: (0, exports.red)("Could not finish"),
|
|
165
244
|
refused: (0, exports.red)("Refused"),
|
|
245
|
+
busy: (0, exports.yellow)("Busy"),
|
|
246
|
+
unknown: (0, exports.yellow)("Outcome unknown"),
|
|
166
247
|
};
|
|
167
248
|
return `\n${word[o] ?? o}${detail ? (0, exports.dim)(` ${detail}`) : ""}\n`;
|
|
168
249
|
}
|
|
@@ -224,7 +305,69 @@ function receipt(text, models = [], testsPassed) {
|
|
|
224
305
|
if (testsPassed !== undefined) {
|
|
225
306
|
lines.push(testsPassed ? (0, exports.green)(" tests passed") : (0, exports.red)(" tests failed"));
|
|
226
307
|
}
|
|
227
|
-
|
|
308
|
+
if (!lines.length)
|
|
309
|
+
return "";
|
|
310
|
+
// On a screen, the receipt is a highlighted box, as on the website. Piped to
|
|
311
|
+
// a file or another program it stays plain lines, which is what a log wants.
|
|
312
|
+
return process.stdout.isTTY ? boxed(text, models, testsPassed) : `${lines.join("\n")}\n`;
|
|
313
|
+
}
|
|
314
|
+
/** Words wrapped to a width, never breaking a word. */
|
|
315
|
+
function wrap(text, room) {
|
|
316
|
+
const out = [];
|
|
317
|
+
let line = "";
|
|
318
|
+
for (const word of text.split(/\s+/).filter(Boolean)) {
|
|
319
|
+
if (line && line.length + 1 + word.length > room) {
|
|
320
|
+
out.push(line);
|
|
321
|
+
line = word;
|
|
322
|
+
}
|
|
323
|
+
else
|
|
324
|
+
line = line ? `${line} ${word}` : word;
|
|
325
|
+
}
|
|
326
|
+
if (line)
|
|
327
|
+
out.push(line);
|
|
328
|
+
return out;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* The receipt in a rounded box: `receipt` as its label, the saving in green,
|
|
332
|
+
* everything else quiet. The server's words are unchanged; each clause it
|
|
333
|
+
* separated with `|` gets its own line, and its link goes last, clickable.
|
|
334
|
+
*/
|
|
335
|
+
function boxed(text, models, testsPassed) {
|
|
336
|
+
// Room for the border, the padding and the `receipt` label on the first line.
|
|
337
|
+
const inner = width() - 16;
|
|
338
|
+
const rows = [];
|
|
339
|
+
const links = [];
|
|
340
|
+
for (const raw of String(text || "").split("\n")) {
|
|
341
|
+
const withoutLinks = raw.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_m, label, url) => {
|
|
342
|
+
links.push({ label: String(label), url: String(url) });
|
|
343
|
+
return "";
|
|
344
|
+
});
|
|
345
|
+
for (const clause of withoutLinks.split("|").map((c) => c.trim()).filter(Boolean)) {
|
|
346
|
+
const paintIt = /\bsaved\b/i.test(clause) ? exports.green : exports.dim;
|
|
347
|
+
for (const piece of wrap(clause, inner))
|
|
348
|
+
rows.push(paintIt(piece));
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
const priced = models.filter((m) => m.model);
|
|
352
|
+
if (priced.length > 1) {
|
|
353
|
+
const order = [...priced].sort((a, b) => (a.usd ?? 0) - (b.usd ?? 0));
|
|
354
|
+
const w = Math.max(...order.map((m) => modelName(String(m.model)).length));
|
|
355
|
+
for (const m of order) {
|
|
356
|
+
const steps = `${m.steps} step${m.steps === 1 ? "" : "s"}`;
|
|
357
|
+
const cost = m.usd === null || m.usd === undefined ? "not priced" : money(m.usd);
|
|
358
|
+
rows.push(`${(0, exports.violet)(modelName(String(m.model)).padEnd(w))}${(0, exports.dim)(` ${steps.padEnd(9)} ${cost}`)}`);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (testsPassed !== undefined)
|
|
362
|
+
rows.push(testsPassed ? (0, exports.green)("tests passed") : (0, exports.red)("tests failed"));
|
|
363
|
+
for (const l of links)
|
|
364
|
+
rows.push((0, exports.dim)(link(l.label, l.url)));
|
|
365
|
+
if (rows.length)
|
|
366
|
+
rows[0] = `${(0, exports.violet)("receipt")} ${rows[0]}`;
|
|
367
|
+
const widest = Math.max(...rows.map((r) => visible(r).length));
|
|
368
|
+
const bar = "\u2500".repeat(widest + 2);
|
|
369
|
+
const body = rows.map((r) => ` ${(0, exports.violet)("\u2502")} ${r}${" ".repeat(widest - visible(r).length)} ${(0, exports.violet)("\u2502")}`);
|
|
370
|
+
return [` ${(0, exports.violet)(`\u256d${bar}\u256e`)}`, ...body, ` ${(0, exports.violet)(`\u2570${bar}\u256f`)}`].join("\n") + "\n";
|
|
228
371
|
}
|
|
229
372
|
/**
|
|
230
373
|
* Plain text, from a model that writes markdown.
|
package/out/agent/session.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ProjectFacts } from "../lib/project";
|
|
1
2
|
import * as ui from "./render";
|
|
2
3
|
export interface SessionOptions {
|
|
3
4
|
/** Where the workspace lives, and the URL of the server that owns it. */
|
|
@@ -5,6 +6,9 @@ export interface SessionOptions {
|
|
|
5
6
|
/** The workspace credential the device flow minted. Never a decodable token. */
|
|
6
7
|
credential: string;
|
|
7
8
|
root: string;
|
|
9
|
+
/** The project, start folder, branch and added folders (manual 2.1 to 2.3).
|
|
10
|
+
* `root` is the project root when this is present. */
|
|
11
|
+
project?: ProjectFacts;
|
|
8
12
|
/** read_only, approve_writes, auto_edit or full_auto. Named, not numbered. */
|
|
9
13
|
permissionMode?: string;
|
|
10
14
|
/** Investigate and propose, change nothing. */
|
|
@@ -23,6 +27,25 @@ export interface SessionOptions {
|
|
|
23
27
|
* corpus study, which has to measure each model as itself. */
|
|
24
28
|
pinModel?: boolean;
|
|
25
29
|
maxSpendUsd?: number;
|
|
30
|
+
/** Stop after this many steps (manual 4.13). */
|
|
31
|
+
maxSteps?: number;
|
|
32
|
+
/** Reasoning effort asked for: low, medium or high (manual 4.18). */
|
|
33
|
+
effort?: string;
|
|
34
|
+
/** Commands run in the operating system's sandbox (manual 4.12). */
|
|
35
|
+
sandbox?: boolean;
|
|
36
|
+
/** Seconds each command may run (manual 5.12); the service applies it. */
|
|
37
|
+
commandTimeoutS?: number;
|
|
38
|
+
/** Background processes outlive the job; the session stops them (5.13). */
|
|
39
|
+
keepProcesses?: boolean;
|
|
40
|
+
/** Start from this GitHub issue (manual 5.20). */
|
|
41
|
+
issue?: number;
|
|
42
|
+
/** Lead this team (manual 5.27). */
|
|
43
|
+
team?: string;
|
|
44
|
+
/** A review job (manual 5.19). */
|
|
45
|
+
review?: {
|
|
46
|
+
pr?: number;
|
|
47
|
+
post?: boolean;
|
|
48
|
+
};
|
|
26
49
|
/** Commands the person has approved in advance, matched exactly.
|
|
27
50
|
*
|
|
28
51
|
* The one thing a run with nobody watching cannot otherwise do is verify its
|
|
@@ -35,6 +58,8 @@ export interface SessionOptions {
|
|
|
35
58
|
* Ids only: the server holds the text for half an hour and nothing here has
|
|
36
59
|
* ever seen the contents. */
|
|
37
60
|
attachmentIds?: string[];
|
|
61
|
+
/** Files named that could not be attached. Names only (manual 3.10). */
|
|
62
|
+
leftOut?: string[];
|
|
38
63
|
/** Nobody is at the keyboard. Approvals cannot be asked for, so the
|
|
39
64
|
* permission mode has to have settled them in advance. */
|
|
40
65
|
headless?: boolean;
|
|
@@ -47,6 +72,10 @@ export interface SessionOptions {
|
|
|
47
72
|
* process owns the keyboard and lends it here. Absent, this class opens its
|
|
48
73
|
* own reader as before, which is the standalone command's case. */
|
|
49
74
|
confirm?: (question: string) => Promise<boolean>;
|
|
75
|
+
/** Ask the person for a line of text on the same lent keyboard: the plan
|
|
76
|
+
* question and the agent's questions (manual 4.2, 4.3). Resolves null when
|
|
77
|
+
* the person pressed Ctrl+C, which stops the job. */
|
|
78
|
+
prompt?: (question: string) => Promise<string | null>;
|
|
50
79
|
/** Continue a job that already exists, rather than starting one. */
|
|
51
80
|
resumeJobId?: string;
|
|
52
81
|
/** The job this question follows on from. The server loads that job's
|
|
@@ -55,6 +84,27 @@ export interface SessionOptions {
|
|
|
55
84
|
continuesJob?: string;
|
|
56
85
|
/** Go without the code map for this job. See `command.ts`. */
|
|
57
86
|
withoutMap?: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Which conversation this job belongs to.
|
|
89
|
+
*
|
|
90
|
+
* Sent because the server cannot work it out. With no conversation id it
|
|
91
|
+
* files the work under a person's DAY on one client, so three separate
|
|
92
|
+
* sessions in one afternoon were stored as one row called "cli, 2026-09-21"
|
|
93
|
+
* and the terminal's own session list disagreed with the Sessions screen.
|
|
94
|
+
* The terminal has always known which session it was in; it simply never
|
|
95
|
+
* said.
|
|
96
|
+
*/
|
|
97
|
+
conversationId?: string;
|
|
98
|
+
/** `--max-minutes` (manual 10.7), held by the service. */
|
|
99
|
+
maxMinutes?: number;
|
|
100
|
+
/** `--schema`, `--config`, `--no-personal` (manual 10.5, 10.8), sent as read. */
|
|
101
|
+
answerSchema?: Record<string, unknown>;
|
|
102
|
+
settingsConfig?: Record<string, unknown>;
|
|
103
|
+
noPersonal?: boolean;
|
|
104
|
+
/** A queued job this run carries out (manual 10.17 to 10.19). */
|
|
105
|
+
queuedJob?: string;
|
|
106
|
+
/** `--output stream`: handed the service's stream lines as they arrive. */
|
|
107
|
+
onStream?: (items: Array<Record<string, unknown>>) => void;
|
|
58
108
|
}
|
|
59
109
|
export interface JobResult {
|
|
60
110
|
outcome: string;
|
|
@@ -77,10 +127,37 @@ export interface JobResult {
|
|
|
77
127
|
models: ui.ModelShare[];
|
|
78
128
|
text: string;
|
|
79
129
|
testsPassed?: boolean;
|
|
130
|
+
/** How the job ended, in the service's words (manual 5.15): the first line,
|
|
131
|
+
* the proof lines and the exit status. Absent from an older service. */
|
|
132
|
+
ending?: {
|
|
133
|
+
line: string | null;
|
|
134
|
+
proof: string[];
|
|
135
|
+
exit: number | null;
|
|
136
|
+
reason?: string;
|
|
137
|
+
};
|
|
138
|
+
/** The result object a script reads (manual 10.3), exactly as the service
|
|
139
|
+
* built it. Printed with --output json; never assembled here. */
|
|
140
|
+
result?: Record<string, unknown>;
|
|
141
|
+
/** Reason word to exit number, as the service sent it (Appendix B). */
|
|
142
|
+
exitStatus?: Record<string, number>;
|
|
143
|
+
/** Why the job was refused before it started, as a reason word: the
|
|
144
|
+
* service's own, or what the reply showed (no sign in, no connection). */
|
|
145
|
+
refusalReason?: string;
|
|
80
146
|
/** Share of everything the job sent that the provider served from cache. */
|
|
81
147
|
reusedPct?: number | null;
|
|
148
|
+
/** The agent's checklist as it ended (manual 4.4). */
|
|
149
|
+
todos: Array<{
|
|
150
|
+
content: string;
|
|
151
|
+
status: string;
|
|
152
|
+
}>;
|
|
153
|
+
/** The full reason for the last step's model, for `why` (manual 4.16). */
|
|
154
|
+
why?: string[];
|
|
155
|
+
/** Notes typed after the last step, to be sent as new requests (6.8). */
|
|
156
|
+
lateNotes: string[];
|
|
82
157
|
}
|
|
83
158
|
export declare class TerminalSession {
|
|
159
|
+
/** The VS Code window this terminal is inside, when there is one (VS Code manual 9.12). */
|
|
160
|
+
private editor;
|
|
84
161
|
private socket;
|
|
85
162
|
private readonly executor;
|
|
86
163
|
private readonly opts;
|
|
@@ -122,8 +199,13 @@ export declare class TerminalSession {
|
|
|
122
199
|
* the run frame already sends as the workspace. One expression, so the map
|
|
123
200
|
* and the job record can never be about two different projects. */
|
|
124
201
|
private project;
|
|
202
|
+
/** Connections lost during this job, so reconnecting gives up in the end. */
|
|
203
|
+
private drops;
|
|
125
204
|
/** Why the one service would not start this job, in its own words. */
|
|
126
205
|
private refusal;
|
|
206
|
+
private refusalReason;
|
|
207
|
+
private refusalResult;
|
|
208
|
+
private refusalTable;
|
|
127
209
|
/** The workspace does not carry the permission question yet, so fall back. */
|
|
128
210
|
private olderWorkspace;
|
|
129
211
|
/** Set while one is actually running, so two never overlap. */
|
|
@@ -152,11 +234,64 @@ export declare class TerminalSession {
|
|
|
152
234
|
private remap;
|
|
153
235
|
/** Run one request to its end. Resolves with how it went. */
|
|
154
236
|
run(request: string): Promise<JobResult>;
|
|
155
|
-
/**
|
|
237
|
+
/**
|
|
238
|
+
* A pass to rejoin this job after a dropped connection, trying for about
|
|
239
|
+
* half a minute, inside the service's window (manual 8.9). Null when the
|
|
240
|
+
* service could not be reached again, or refused.
|
|
241
|
+
*/
|
|
242
|
+
private reconnect;
|
|
243
|
+
/** Stop the running job. Takes effect mid action, not at the end of the run:
|
|
244
|
+
* a command already running on this machine is stopped too (manual 6.7). */
|
|
156
245
|
cancel(): void;
|
|
157
|
-
/** Something typed while it works. Joins the conversation at the next step
|
|
246
|
+
/** Something typed while it works. Joins the conversation at the next step;
|
|
247
|
+
* the service says so in the `note` event it sends back (6.8). */
|
|
158
248
|
steer(text: string): void;
|
|
249
|
+
/** Esc: finish the current action, then wait (manual 6.7). */
|
|
250
|
+
pause(): void;
|
|
251
|
+
/** Carry on after Esc, with a correction or without one. */
|
|
252
|
+
carryOn(text: string): void;
|
|
253
|
+
/** This job's id, once the service has issued it (`transcript`, 6.9). */
|
|
254
|
+
jobId: string | undefined;
|
|
255
|
+
/** Set from Esc until the job carries on or stops. */
|
|
256
|
+
paused: boolean;
|
|
257
|
+
/** Helpers running now, from the service's own events (manual 5.25). */
|
|
258
|
+
readonly helpers: Map<string, {
|
|
259
|
+
id: string;
|
|
260
|
+
question: string;
|
|
261
|
+
agent?: string | null;
|
|
262
|
+
}>;
|
|
263
|
+
/** `stop h2` (5.25): the service stops that one helper. */
|
|
264
|
+
stopHelper(id: string): void;
|
|
265
|
+
/** `queue` and `queue clear` (6.8): the service answers with the notes. */
|
|
266
|
+
queue(clear: boolean): void;
|
|
267
|
+
/** Ctrl+O: each action's full input and output, or the short line (6.9). */
|
|
268
|
+
full: boolean;
|
|
159
269
|
private announce;
|
|
270
|
+
/** The allowance and plan notes, printed under the first line so it stays first. */
|
|
271
|
+
private allowanceLine;
|
|
272
|
+
/** A running command's output on screen (manual 5.12): the first lines as
|
|
273
|
+
* they arrive, then held, and at the end either the rest or the last lines
|
|
274
|
+
* with a count of what was left out. How many is the service's number. */
|
|
275
|
+
private screen;
|
|
276
|
+
private stream;
|
|
277
|
+
private flushScreen;
|
|
278
|
+
/** Changes already put in front of the person to approve, so they are not
|
|
279
|
+
* shown twice. Every other change is shown as it is made (5.6 to 5.8). */
|
|
280
|
+
private asked;
|
|
281
|
+
/** The sandbox this machine offers, worked out once (manual 4.12). */
|
|
282
|
+
private sandboxChecked;
|
|
283
|
+
private sandboxSystem;
|
|
284
|
+
/** The full reason for the last step, as the service wrote it (4.16). */
|
|
285
|
+
lastWhy: string[];
|
|
286
|
+
/** An unattended run refused an action that needed approval (Appendix B, 4). */
|
|
287
|
+
refusedUnattended: boolean;
|
|
288
|
+
/** Approved actions by call, and what exactly was approved (manual 4.8). */
|
|
289
|
+
private approvedCalls;
|
|
290
|
+
/** Approvals waiting here that the browser may answer first (web manual 6.15). */
|
|
291
|
+
private answeredElsewhere;
|
|
292
|
+
/** An action as approved: its name, its arguments and the real folder it
|
|
293
|
+
* runs in, so a changed argument or a moved folder is caught. */
|
|
294
|
+
private fingerprint;
|
|
160
295
|
private narrate;
|
|
161
296
|
private targetOf;
|
|
162
297
|
/** Put a change in front of the person and wait.
|
|
@@ -171,5 +306,9 @@ export declare class TerminalSession {
|
|
|
171
306
|
* a script that needs to change files says so by choosing a mode that allows
|
|
172
307
|
* it, up front. */
|
|
173
308
|
private ask;
|
|
309
|
+
/** The plan question or one of the agent's questions (manual 4.2, 4.3).
|
|
310
|
+
* Returns what the person typed, or null for Ctrl+C. The meaning of the
|
|
311
|
+
* answer (y, n, a number, words) is decided by the service. */
|
|
312
|
+
private question;
|
|
174
313
|
private report;
|
|
175
314
|
}
|