@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.
Files changed (131) hide show
  1. package/README.md +98 -36
  2. package/out/agent/command.d.ts +75 -4
  3. package/out/agent/command.js +220 -25
  4. package/out/agent/render.d.ts +17 -2
  5. package/out/agent/render.js +157 -14
  6. package/out/agent/session.d.ts +141 -2
  7. package/out/agent/session.js +735 -149
  8. package/out/commands/agents.d.ts +2 -0
  9. package/out/commands/agents.js +79 -0
  10. package/out/commands/ask.d.ts +1 -1
  11. package/out/commands/ask.js +78 -11
  12. package/out/commands/commands-thin.js +79 -17
  13. package/out/commands/config.d.ts +1 -0
  14. package/out/commands/config.js +138 -0
  15. package/out/commands/cost.d.ts +1 -0
  16. package/out/commands/cost.js +167 -0
  17. package/out/commands/hooks.d.ts +1 -0
  18. package/out/commands/hooks.js +83 -0
  19. package/out/commands/install.d.ts +44 -1
  20. package/out/commands/install.js +198 -4
  21. package/out/commands/instructions.d.ts +1 -0
  22. package/out/commands/instructions.js +113 -0
  23. package/out/commands/integrations.d.ts +3 -0
  24. package/out/commands/integrations.js +215 -0
  25. package/out/commands/jobs.d.ts +5 -0
  26. package/out/commands/jobs.js +157 -0
  27. package/out/commands/login.js +188 -36
  28. package/out/commands/memory.d.ts +3 -0
  29. package/out/commands/memory.js +113 -0
  30. package/out/commands/permissions.d.ts +1 -0
  31. package/out/commands/permissions.js +94 -0
  32. package/out/commands/plugins.d.ts +4 -0
  33. package/out/commands/plugins.js +192 -0
  34. package/out/commands/privacy.d.ts +1 -0
  35. package/out/commands/privacy.js +57 -0
  36. package/out/commands/providerKey.d.ts +32 -0
  37. package/out/commands/providerKey.js +108 -0
  38. package/out/commands/repl.d.ts +8 -1
  39. package/out/commands/repl.js +1207 -118
  40. package/out/commands/report.d.ts +39 -0
  41. package/out/commands/report.js +115 -0
  42. package/out/commands/review.d.ts +5 -0
  43. package/out/commands/review.js +223 -0
  44. package/out/commands/sessions.d.ts +23 -0
  45. package/out/commands/sessions.js +115 -0
  46. package/out/commands/settings.d.ts +3 -1
  47. package/out/commands/settings.js +18 -16
  48. package/out/commands/skills.d.ts +21 -0
  49. package/out/commands/skills.js +207 -0
  50. package/out/commands/unattended.d.ts +7 -0
  51. package/out/commands/unattended.js +351 -0
  52. package/out/commands/update.d.ts +1 -0
  53. package/out/commands/update.js +123 -0
  54. package/out/commands/worktrees.d.ts +5 -0
  55. package/out/commands/worktrees.js +186 -0
  56. package/out/executor/browser.d.ts +14 -0
  57. package/out/executor/browser.js +270 -0
  58. package/out/executor/diagnostics.d.ts +2 -0
  59. package/out/executor/diagnostics.js +181 -0
  60. package/out/executor/files.js +270 -40
  61. package/out/executor/git.js +42 -29
  62. package/out/executor/hooks.d.ts +42 -58
  63. package/out/executor/hooks.js +89 -182
  64. package/out/executor/index.d.ts +21 -5
  65. package/out/executor/index.js +160 -14
  66. package/out/executor/paths.d.ts +6 -1
  67. package/out/executor/paths.js +34 -6
  68. package/out/executor/sandbox.d.ts +40 -0
  69. package/out/executor/sandbox.js +299 -0
  70. package/out/executor/shell.d.ts +49 -4
  71. package/out/executor/shell.js +302 -56
  72. package/out/executor/toolservers.d.ts +20 -0
  73. package/out/executor/toolservers.js +189 -0
  74. package/out/executor/worktree.d.ts +9 -0
  75. package/out/executor/worktree.js +119 -0
  76. package/out/graph/read-python.js +2 -1
  77. package/out/lib/attach.d.ts +56 -12
  78. package/out/lib/attach.js +230 -63
  79. package/out/lib/clipboard.d.ts +23 -0
  80. package/out/lib/clipboard.js +182 -0
  81. package/out/lib/commandlist.d.ts +20 -0
  82. package/out/lib/commandlist.js +58 -0
  83. package/out/lib/decision.d.ts +22 -0
  84. package/out/lib/decision.js +50 -0
  85. package/out/lib/fingerprint.d.ts +25 -0
  86. package/out/lib/fingerprint.js +58 -0
  87. package/out/lib/gateway.d.ts +186 -2
  88. package/out/lib/gateway.js +59 -4
  89. package/out/lib/history.d.ts +24 -0
  90. package/out/lib/history.js +137 -0
  91. package/out/lib/ide.d.ts +19 -0
  92. package/out/lib/ide.js +131 -0
  93. package/out/lib/keyboard.d.ts +95 -0
  94. package/out/lib/keyboard.js +383 -0
  95. package/out/lib/machine.d.ts +21 -0
  96. package/out/lib/machine.js +91 -0
  97. package/out/lib/notify.d.ts +4 -0
  98. package/out/lib/notify.js +52 -0
  99. package/out/lib/output.d.ts +48 -0
  100. package/out/lib/output.js +108 -0
  101. package/out/lib/project-ops.d.ts +19 -0
  102. package/out/lib/project-ops.js +146 -0
  103. package/out/lib/project.d.ts +28 -0
  104. package/out/lib/project.js +114 -0
  105. package/out/lib/prompt.js +15 -2
  106. package/out/lib/queue.d.ts +13 -0
  107. package/out/lib/queue.js +116 -0
  108. package/out/lib/readiness.d.ts +19 -0
  109. package/out/lib/readiness.js +170 -1
  110. package/out/lib/self.d.ts +23 -0
  111. package/out/lib/self.js +124 -0
  112. package/out/lib/sessions.d.ts +19 -0
  113. package/out/lib/sessions.js +221 -0
  114. package/out/lib/stdin.d.ts +32 -0
  115. package/out/lib/stdin.js +117 -0
  116. package/out/lib/store.d.ts +40 -0
  117. package/out/lib/store.js +138 -0
  118. package/out/lib/sync.d.ts +18 -0
  119. package/out/lib/sync.js +81 -0
  120. package/out/lib/ui.d.ts +2 -4
  121. package/out/lib/ui.js +31 -25
  122. package/out/lib/voice.js +24 -0
  123. package/out/postinstall.js +42 -14
  124. package/out/providers/anthropic.d.ts +22 -0
  125. package/out/providers/anthropic.js +80 -0
  126. package/out/providers/index.d.ts +8 -0
  127. package/out/providers/index.js +83 -0
  128. package/out/providers/openai.d.ts +11 -0
  129. package/out/providers/openai.js +57 -0
  130. package/out/thin.js +609 -21
  131. package/package.json +9 -49
@@ -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
- const supportsColour = process.stdout.isTTY && process.env.NO_COLOR === undefined;
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
- const mark = ok ? (0, exports.green)("ok ") : (0, exports.red)("fail");
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
- return (0, exports.dim)(` step ${index} ${model || "?"} ${money(usd)} ${duration(ms)}${warm}`);
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)("done")
106
- : t.status === "in_progress" ? (0, exports.yellow)("now ") : (0, exports.dim)("todo");
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 ` ${mark} ${text}`;
157
+ return ` ${mark} ${text}`;
109
158
  });
110
- return `\n ${(0, exports.bold)("Plan")}\n${rows.join("\n")}\n`;
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
- const head = `\n ${(0, exports.bold)(name)} ${target}\n`;
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
- return lines.length > 0 ? `${lines.join("\n")}\n` : "";
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.
@@ -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
- /** Stop the running job. Takes effect mid action, not at the end of the run. */
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
  }