zidane 6.6.4 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/dist/{acp-BQqhozmt.js → acp-Wr8l4IDI.js} +7 -180
  2. package/dist/acp-Wr8l4IDI.js.map +1 -0
  3. package/dist/acp-cli.js +6 -6
  4. package/dist/acp.d.ts +1 -1
  5. package/dist/acp.d.ts.map +1 -1
  6. package/dist/acp.js +2 -1
  7. package/dist/{agent-DTxH7RHW.js → agent-C-camKQW.js} +162 -12
  8. package/dist/agent-C-camKQW.js.map +1 -0
  9. package/dist/agent.d.ts +1 -1
  10. package/dist/agent.js +1 -1
  11. package/dist/{anthropic-DRNRnd6W.js → anthropic-BDOGzhtj.js} +3 -3
  12. package/dist/{anthropic-DRNRnd6W.js.map → anthropic-BDOGzhtj.js.map} +1 -1
  13. package/dist/{transcript-anchors-BjH-68k2.js → approvals-CqqxE5Vh.js} +4924 -275
  14. package/dist/approvals-CqqxE5Vh.js.map +1 -0
  15. package/dist/{auth-7rv6ZfWk.js → auth-BdwDROYg.js} +12 -8
  16. package/dist/{auth-7rv6ZfWk.js.map → auth-BdwDROYg.js.map} +1 -1
  17. package/dist/chat/pure.d.ts +221 -4
  18. package/dist/chat/pure.d.ts.map +1 -0
  19. package/dist/chat/pure.js +4 -2
  20. package/dist/chat.d.ts +6 -2911
  21. package/dist/chat.js +8 -261
  22. package/dist/{context-transport-D8yeGdpd.js → context-transport-BqYwzJYE.js} +2 -2
  23. package/dist/{context-transport-D8yeGdpd.js.map → context-transport-BqYwzJYE.js.map} +1 -1
  24. package/dist/contexts/daytona.d.ts +1 -1
  25. package/dist/contexts/daytona.js +1 -1
  26. package/dist/contexts/e2b.d.ts +1 -1
  27. package/dist/contexts/e2b.js +1 -1
  28. package/dist/daemon-cli.d.ts +1 -0
  29. package/dist/daemon-cli.js +90 -0
  30. package/dist/daemon-cli.js.map +1 -0
  31. package/dist/eval.d.ts +1 -1
  32. package/dist/eval.js +1 -1
  33. package/dist/extensions.d.ts +2 -2
  34. package/dist/extensions.js +2 -2
  35. package/dist/headless.d.ts +1 -1
  36. package/dist/headless.js +4 -4
  37. package/dist/{index-D0O-QO7Z.d.ts → index-B-FSaM3_.d.ts} +2863 -2375
  38. package/dist/index-B-FSaM3_.d.ts.map +1 -0
  39. package/dist/index-DgdzXRPH.d.ts +3590 -0
  40. package/dist/index-DgdzXRPH.d.ts.map +1 -0
  41. package/dist/index.d.ts +2 -2
  42. package/dist/index.js +14 -1179
  43. package/dist/ipc-CIv87xuH.js +331 -0
  44. package/dist/ipc-CIv87xuH.js.map +1 -0
  45. package/dist/ipc.d.ts +849 -0
  46. package/dist/ipc.d.ts.map +1 -0
  47. package/dist/ipc.js +4 -0
  48. package/dist/json-rpc-rSWMUh9b.js +192 -0
  49. package/dist/json-rpc-rSWMUh9b.js.map +1 -0
  50. package/dist/{logger-DBX9uYOw.js → logger--C1VQjwJ.js} +3 -13
  51. package/dist/logger--C1VQjwJ.js.map +1 -0
  52. package/dist/logs-view-CWG8aUAG.js +44 -0
  53. package/dist/logs-view-CWG8aUAG.js.map +1 -0
  54. package/dist/{mcp-CVtSQTWg.js → mcp-BIWa57eY.js} +3 -3
  55. package/dist/{mcp-CVtSQTWg.js.map → mcp-BIWa57eY.js.map} +1 -1
  56. package/dist/mcp.d.ts +1 -1
  57. package/dist/mcp.js +1 -1
  58. package/dist/{messages-CZMUuKzo.js → messages-21XfHxyF.js} +3 -3
  59. package/dist/{messages-CZMUuKzo.js.map → messages-21XfHxyF.js.map} +1 -1
  60. package/dist/{openai-compat-BoTi-9fd.js → openai-compat-DY-AKxCg.js} +2 -2
  61. package/dist/{openai-compat-BoTi-9fd.js.map → openai-compat-DY-AKxCg.js.map} +1 -1
  62. package/dist/output/stream-json.d.ts +1 -1
  63. package/dist/output/terminal.d.ts +1 -1
  64. package/dist/{plugins-onDvTHEm.js → plugins-B531Tz5b.js} +2 -2
  65. package/dist/{plugins-onDvTHEm.js.map → plugins-B531Tz5b.js.map} +1 -1
  66. package/dist/plugins.d.ts +1 -1
  67. package/dist/plugins.js +1 -1
  68. package/dist/presets.d.ts +1 -1
  69. package/dist/presets.js +1 -1
  70. package/dist/providers/anthropic.d.ts +1 -1
  71. package/dist/providers/anthropic.js +1 -1
  72. package/dist/providers/arcee.d.ts +1 -1
  73. package/dist/providers/arcee.js +1 -1
  74. package/dist/providers/baseten.d.ts +1 -1
  75. package/dist/providers/baseten.js +1 -1
  76. package/dist/providers/cerebras.d.ts +1 -1
  77. package/dist/providers/cerebras.js +1 -1
  78. package/dist/providers/local.d.ts +1 -1
  79. package/dist/providers/local.js +1 -1
  80. package/dist/providers/openai-compat.d.ts +1 -1
  81. package/dist/providers/openai-compat.js +1 -1
  82. package/dist/providers/openai.d.ts +1 -1
  83. package/dist/providers/openai.js +3 -3
  84. package/dist/providers/openrouter.d.ts +1 -1
  85. package/dist/providers/openrouter.js +1 -1
  86. package/dist/providers/xai.d.ts +1 -1
  87. package/dist/providers/xai.js +1 -1
  88. package/dist/{providers-CmhdtD7w.js → providers-DX91jwir.js} +2 -2
  89. package/dist/{providers-CmhdtD7w.js.map → providers-DX91jwir.js.map} +1 -1
  90. package/dist/providers.d.ts +1 -1
  91. package/dist/providers.js +3 -3
  92. package/dist/restate.d.ts +1 -1
  93. package/dist/restate.js +8 -8
  94. package/dist/restate.js.map +1 -1
  95. package/dist/server-DJqp9dIR.js +1317 -0
  96. package/dist/server-DJqp9dIR.js.map +1 -0
  97. package/dist/session/sqlite.d.ts +1 -1
  98. package/dist/session/sqlite.d.ts.map +1 -1
  99. package/dist/session/sqlite.js +42 -4
  100. package/dist/session/sqlite.js.map +1 -1
  101. package/dist/{session-CyRLSsVa.js → session-K3icbPH9.js} +8 -2
  102. package/dist/session-K3icbPH9.js.map +1 -0
  103. package/dist/session.d.ts +1 -1
  104. package/dist/session.js +2 -2
  105. package/dist/{skills-BMGH_KK1.js → skills-PJyiSRCp.js} +3 -21
  106. package/dist/skills-PJyiSRCp.js.map +1 -0
  107. package/dist/skills.d.ts +1 -1
  108. package/dist/skills.js +1 -1
  109. package/dist/src-DzzhE2YO.js +2461 -0
  110. package/dist/src-DzzhE2YO.js.map +1 -0
  111. package/dist/todo-edits-Dw2oO2ON.js +378 -0
  112. package/dist/todo-edits-Dw2oO2ON.js.map +1 -0
  113. package/dist/{tool-formatters-NrzD6Fkk.d.ts → tool-formatters-DO56YBBw.d.ts} +104 -4
  114. package/dist/tool-formatters-DO56YBBw.d.ts.map +1 -0
  115. package/dist/tools/fetch-url.d.ts +1 -1
  116. package/dist/tools/web-search.d.ts +1 -1
  117. package/dist/tools.d.ts +1 -1
  118. package/dist/tools.js +1 -1
  119. package/dist/{transcript-anchors-UhC58Tmj.d.ts → transcript-anchors-DXqWWGbq.d.ts} +53 -4
  120. package/dist/transcript-anchors-DXqWWGbq.d.ts.map +1 -0
  121. package/dist/tui.d.ts +94 -13
  122. package/dist/tui.d.ts.map +1 -1
  123. package/dist/tui.js +2241 -1009
  124. package/dist/tui.js.map +1 -1
  125. package/dist/{turn-operations-mMxDRgLY.js → turn-operations-CZLsNgw-.js} +896 -11
  126. package/dist/turn-operations-CZLsNgw-.js.map +1 -0
  127. package/dist/{turn-operations-Cuc9pwiB.d.ts → turn-operations-DKFYWP3O.d.ts} +501 -4
  128. package/dist/turn-operations-DKFYWP3O.d.ts.map +1 -0
  129. package/dist/{types-BIarq1qE.js → types-CWgENVLY.js} +24 -2
  130. package/dist/types-CWgENVLY.js.map +1 -0
  131. package/dist/types.d.ts +1 -1
  132. package/dist/types.js +1 -1
  133. package/dist/xml-D5HBhJle.js +22 -0
  134. package/dist/xml-D5HBhJle.js.map +1 -0
  135. package/docs/CHAT.md +39 -0
  136. package/docs/IPC.md +420 -0
  137. package/docs/TUI.md +62 -0
  138. package/package.json +8 -2
  139. package/dist/acp-BQqhozmt.js.map +0 -1
  140. package/dist/agent-DTxH7RHW.js.map +0 -1
  141. package/dist/chat.d.ts.map +0 -1
  142. package/dist/chat.js.map +0 -1
  143. package/dist/index-D0O-QO7Z.d.ts.map +0 -1
  144. package/dist/index.js.map +0 -1
  145. package/dist/inline-autocomplete-D0MPvBaS.js +0 -596
  146. package/dist/inline-autocomplete-D0MPvBaS.js.map +0 -1
  147. package/dist/logger-DBX9uYOw.js.map +0 -1
  148. package/dist/login-CB23LyI1.js +0 -707
  149. package/dist/login-CB23LyI1.js.map +0 -1
  150. package/dist/session-CyRLSsVa.js.map +0 -1
  151. package/dist/skills-BMGH_KK1.js.map +0 -1
  152. package/dist/tool-formatters-NrzD6Fkk.d.ts.map +0 -1
  153. package/dist/transcript-anchors-BjH-68k2.js.map +0 -1
  154. package/dist/transcript-anchors-UhC58Tmj.d.ts.map +0 -1
  155. package/dist/turn-operations-Cuc9pwiB.d.ts.map +0 -1
  156. package/dist/turn-operations-mMxDRgLY.js.map +0 -1
  157. package/dist/types-BIarq1qE.js.map +0 -1
@@ -0,0 +1,378 @@
1
+ //#region src/chat/auth-rows.ts
2
+ /**
3
+ * Stored credentials, i.e. the ones a user can actually choose between.
4
+ *
5
+ * `env` is excluded: it is observed rather than stored, and is usually just the
6
+ * mirror `applyApiKeyEnv` wrote from the stored API key, so counting it would
7
+ * advertise a choice that does not exist.
8
+ */
9
+ function selectableSources(provider) {
10
+ return provider.methods.filter((m) => m.source !== "env");
11
+ }
12
+ /** A provider earns a chevron only when there is a real choice to reveal. */
13
+ function isExpandableProvider(provider) {
14
+ return selectableSources(provider).length > 1;
15
+ }
16
+ /**
17
+ * Flatten the provider list plus the expanded set into the visible-row list.
18
+ *
19
+ * - `providers` — filtered / ordered provider list (post-search).
20
+ * - `expanded` — keys of providers whose sources are open. Keys for
21
+ * providers that are no longer expandable are ignored rather
22
+ * than cleaned up, so stale expansion state (a credential
23
+ * removed while the modal is open) can't desync the cursor.
24
+ */
25
+ function buildVisibleAuthRows(providers, expanded) {
26
+ const out = [];
27
+ for (const provider of providers) {
28
+ const expandable = isExpandableProvider(provider);
29
+ out.push({
30
+ kind: "provider",
31
+ provider,
32
+ expandable
33
+ });
34
+ if (!expandable || !expanded.has(provider.key)) continue;
35
+ for (const method of selectableSources(provider)) out.push({
36
+ kind: "source",
37
+ providerKey: provider.key,
38
+ method
39
+ });
40
+ if (provider.envKey) {
41
+ const envMethod = provider.methods.find((m) => m.source === "env");
42
+ out.push({
43
+ kind: "source",
44
+ providerKey: provider.key,
45
+ method: envMethod ?? {
46
+ source: "env",
47
+ detail: provider.envKey,
48
+ active: false
49
+ }
50
+ });
51
+ }
52
+ }
53
+ return out;
54
+ }
55
+ /**
56
+ * Provider key a row "belongs to" — its own for a provider header, the parent's
57
+ * for a source row.
58
+ */
59
+ function parentProviderKey(row) {
60
+ return row.kind === "provider" ? row.provider.key : row.providerKey;
61
+ }
62
+ /**
63
+ * Index in `rows` of the header for the given provider key, or `-1`.
64
+ *
65
+ * Collapse handlers snap the cursor up to the parent BEFORE the row list
66
+ * shrinks; without that the cursor keeps its flat index and silently lands on
67
+ * whichever sibling row slid into that slot.
68
+ */
69
+ function indexOfProviderRow(rows, providerKey) {
70
+ return rows.findIndex((r) => r.kind === "provider" && r.provider.key === providerKey);
71
+ }
72
+ //#endregion
73
+ //#region src/chat/instruction-rows.ts
74
+ /**
75
+ * Upper bound on preview lines rendered for one expanded segment. Mirrors the
76
+ * Logs tab's render cap: the scrollbox can hold arbitrary height, but pasting a
77
+ * runaway 64KB instruction file into the layout pass is a waste of a frame.
78
+ * File-backed segments have `$EDITOR` as the escape hatch for the remainder.
79
+ */
80
+ const INSTRUCTION_PREVIEW_LINE_CAP = 400;
81
+ /**
82
+ * Filter segments by the active query and resolve each one's expanded state.
83
+ *
84
+ * Deliberately does NOT auto-expand matches the way the Extensions tab does:
85
+ * the search corpus includes each segment's full text, so a query typically
86
+ * matches deep inside a long document — auto-expanding every hit would dump
87
+ * thousands of lines into the viewport on a keystroke. The user expands the row
88
+ * they care about.
89
+ */
90
+ function buildVisibleInstructionRows(opts) {
91
+ const { segments, expanded, queryActive, matchSegment } = opts;
92
+ const out = [];
93
+ for (const segment of segments) {
94
+ if (queryActive && !matchSegment(segment)) continue;
95
+ out.push({
96
+ segment,
97
+ expanded: expanded.has(segment.id)
98
+ });
99
+ }
100
+ return out;
101
+ }
102
+ /**
103
+ * Split a segment's text into renderable preview lines, clamped to
104
+ * {@link INSTRUCTION_PREVIEW_LINE_CAP}.
105
+ *
106
+ * `hidden` is how many lines were dropped off the tail, so the view can render
107
+ * an honest "+N more lines" marker instead of silently truncating. Tabs are
108
+ * expanded to two spaces because the terminal text renderable doesn't
109
+ * interpret `\t`, and `\r` is stripped so CRLF files don't leave artefacts at
110
+ * every line end.
111
+ */
112
+ function instructionPreviewLines(text) {
113
+ const all = text.replace(/\r\n?/g, "\n").replace(/\t/g, " ").split("\n");
114
+ while (all.length > 0 && all[all.length - 1].trim() === "") all.pop();
115
+ if (all.length <= 400) return {
116
+ lines: all,
117
+ hidden: 0
118
+ };
119
+ return {
120
+ lines: all.slice(0, 400),
121
+ hidden: all.length - 400
122
+ };
123
+ }
124
+ /**
125
+ * Short badge for a segment's origin — the "where does this come from" column.
126
+ * `'file'` is intentionally the only one that reads like a location, since it's
127
+ * the only origin the user can act on.
128
+ */
129
+ function instructionOriginBadge(segment) {
130
+ switch (segment.origin) {
131
+ case "file": return "file";
132
+ case "generated": return "generated";
133
+ case "mcp": return "mcp server";
134
+ case "built-in": return "built-in";
135
+ }
136
+ }
137
+ //#endregion
138
+ //#region src/chat/mcp-form.ts
139
+ const MCP_TRANSPORTS = [
140
+ "stdio",
141
+ "streamable-http",
142
+ "sse"
143
+ ];
144
+ /**
145
+ * Validate + normalize the raw field values into a config entry.
146
+ * Returns the first problem in row order so the dialog can surface it.
147
+ */
148
+ function validateMcpForm(values) {
149
+ const name = values.name.trim();
150
+ if (name.length === 0) return {
151
+ ok: false,
152
+ error: "name is required"
153
+ };
154
+ if (!/^[\w.-]+$/.test(name)) return {
155
+ ok: false,
156
+ error: "name must be alphanumerics, dots, hyphens, underscores"
157
+ };
158
+ if (values.transport === "stdio") {
159
+ const tokens = splitCommandLine(values.commandLine);
160
+ if (tokens.length === 0) return {
161
+ ok: false,
162
+ error: "command is required for stdio servers"
163
+ };
164
+ const env = parseKeyValueLines(values.env, {
165
+ label: "env",
166
+ separators: ["="]
167
+ });
168
+ if (!env.ok) return {
169
+ ok: false,
170
+ error: env.error
171
+ };
172
+ return {
173
+ ok: true,
174
+ result: {
175
+ entry: {
176
+ name,
177
+ transport: "stdio",
178
+ command: tokens[0],
179
+ ...tokens.length > 1 ? { args: tokens.slice(1) } : {},
180
+ ...Object.keys(env.pairs).length > 0 ? { env: env.pairs } : {}
181
+ },
182
+ scope: values.scope
183
+ }
184
+ };
185
+ }
186
+ const url = values.url.trim();
187
+ if (url.length === 0) return {
188
+ ok: false,
189
+ error: "url is required for http/sse servers"
190
+ };
191
+ if (!/^https?:\/\//.test(url)) return {
192
+ ok: false,
193
+ error: "url must start with http:// or https://"
194
+ };
195
+ const headers = parseKeyValueLines(values.headers, {
196
+ label: "headers",
197
+ separators: [":", "="]
198
+ });
199
+ if (!headers.ok) return {
200
+ ok: false,
201
+ error: headers.error
202
+ };
203
+ return {
204
+ ok: true,
205
+ result: {
206
+ entry: {
207
+ name,
208
+ transport: values.transport,
209
+ url,
210
+ ...Object.keys(headers.pairs).length > 0 ? { headers: headers.pairs } : {}
211
+ },
212
+ scope: values.scope
213
+ }
214
+ };
215
+ }
216
+ /**
217
+ * Split a command line into tokens, honoring single/double quotes so
218
+ * `npx -y my-server --root "/path with spaces"` round-trips. No escape
219
+ * processing beyond quote grouping — this is a form field, not a shell.
220
+ */
221
+ function splitCommandLine(line) {
222
+ const out = [];
223
+ const re = /"([^"]*)"|'([^']*)'|(\S+)/g;
224
+ for (let m = re.exec(line); m !== null; m = re.exec(line)) out.push(m[1] ?? m[2] ?? m[3]);
225
+ return out;
226
+ }
227
+ /**
228
+ * Parse one key/value pair PER LINE. Line-based (not whitespace-split)
229
+ * because values legitimately contain spaces — `Authorization: Bearer
230
+ * abc123` is the canonical headers case, and env values like
231
+ * `GREETING=hello world` are equally valid. The first separator found
232
+ * (in `separators` priority order, `:` before `=` for headers) splits;
233
+ * the rest of the line is the value, trimmed. Blank lines skipped.
234
+ */
235
+ function parseKeyValueLines(raw, opts) {
236
+ const pairs = {};
237
+ for (const line of raw.split("\n")) {
238
+ const trimmed = line.trim();
239
+ if (trimmed.length === 0) continue;
240
+ let splitAt = -1;
241
+ for (const sep of opts.separators) {
242
+ const idx = trimmed.indexOf(sep);
243
+ if (idx > 0 && (splitAt === -1 || idx < splitAt)) splitAt = idx;
244
+ }
245
+ if (splitAt <= 0) {
246
+ const forms = opts.separators.map((s) => `KEY${s}VALUE`).join(" or ");
247
+ return {
248
+ ok: false,
249
+ error: `${opts.label} entries must be ${forms}, one per line (got "${trimmed}")`
250
+ };
251
+ }
252
+ const key = trimmed.slice(0, splitAt).trim();
253
+ const value = trimmed.slice(splitAt + 1).trim();
254
+ if (key.length === 0) return {
255
+ ok: false,
256
+ error: `${opts.label} entry has an empty key ("${trimmed}")`
257
+ };
258
+ pairs[key] = value;
259
+ }
260
+ return {
261
+ ok: true,
262
+ pairs
263
+ };
264
+ }
265
+ //#endregion
266
+ //#region src/chat/notice-format.ts
267
+ /** Leading glyph per severity. `info` is deliberately quiet — a middle dot. */
268
+ const NOTICE_GLYPH = {
269
+ info: "·",
270
+ warn: "!",
271
+ error: "✗"
272
+ };
273
+ //#endregion
274
+ //#region src/chat/todo-edits.ts
275
+ /**
276
+ * Prefix for ids minted here, distinguishing user-authored rows from the
277
+ * model's own ids in a session file. Purely diagnostic — nothing branches on
278
+ * it — but it makes "who added this" answerable after the fact.
279
+ */
280
+ const USER_TODO_ID_PREFIX = "user-";
281
+ /**
282
+ * Mint an id that cannot collide with an existing row.
283
+ *
284
+ * Counter-based rather than random: a stable, readable id keeps session diffs
285
+ * legible, and the collision check makes it safe against ids the model already
286
+ * used (including previous `user-*` ones after a reload).
287
+ */
288
+ function nextTodoId(items) {
289
+ const taken = new Set(items.map((i) => i.id));
290
+ for (let n = 1;; n++) {
291
+ const id = `${USER_TODO_ID_PREFIX}${n}`;
292
+ if (!taken.has(id)) return id;
293
+ }
294
+ }
295
+ /**
296
+ * Append a todo. Returns the list unchanged when `content` is blank — an empty
297
+ * row is never what the user meant, and rejecting it here means every caller
298
+ * (keyboard, click, future GUI) gets the same guard.
299
+ */
300
+ function addTodo(items, content) {
301
+ const trimmed = content.trim();
302
+ if (!trimmed) return [...items];
303
+ return [...items, {
304
+ id: nextTodoId(items),
305
+ content: trimmed,
306
+ status: "pending"
307
+ }];
308
+ }
309
+ /**
310
+ * Replace one todo's text. Blank content is rejected (see {@link addTodo}); an
311
+ * unknown id is a no-op rather than an error, because the list can be replaced
312
+ * by a `todowrite` between render and keypress.
313
+ */
314
+ function editTodo(items, id, content) {
315
+ const trimmed = content.trim();
316
+ if (!trimmed) return [...items];
317
+ return items.map((item) => item.id === id ? {
318
+ ...item,
319
+ content: trimmed
320
+ } : item);
321
+ }
322
+ /** Drop one todo. Unknown id is a no-op, same rationale as {@link editTodo}. */
323
+ function removeTodo(items, id) {
324
+ return items.filter((item) => item.id !== id);
325
+ }
326
+ /** Drop everything. Separate from `removeTodo` so the caller's intent is explicit at the call site. */
327
+ function clearTodos() {
328
+ return [];
329
+ }
330
+ /**
331
+ * Advance a todo's status one step: pending → in_progress → completed →
332
+ * pending. `cancelled` also lands on `pending`, so a dropped item can be
333
+ * revived without a dedicated key.
334
+ *
335
+ * Cycling INTO `in_progress` demotes any other in-progress row to `pending`:
336
+ * the list's whole purpose is "what is being worked on right now", and two
337
+ * live rows make that unanswerable — `TodoIndicator`'s successor
338
+ * (`todoProgressLabel`) reads the first one and would silently ignore the rest.
339
+ */
340
+ function cycleTodoStatus(items, id) {
341
+ const target = items.find((item) => item.id === id);
342
+ if (!target) return [...items];
343
+ const next = nextStatus(target.status);
344
+ return items.map((item) => {
345
+ if (item.id === id) return {
346
+ ...item,
347
+ status: next
348
+ };
349
+ if (next === "in_progress" && item.status === "in_progress") return {
350
+ ...item,
351
+ status: "pending"
352
+ };
353
+ return item;
354
+ });
355
+ }
356
+ function nextStatus(status) {
357
+ switch (status) {
358
+ case "pending": return "in_progress";
359
+ case "in_progress": return "completed";
360
+ default: return "pending";
361
+ }
362
+ }
363
+ /**
364
+ * Steering text for a "retry this todo" request.
365
+ *
366
+ * Quotes the content so a model reading it can match the row verbatim against
367
+ * its own list, and names the status because "retry" means different things
368
+ * for a row it believes is `completed` versus one it abandoned as `cancelled`.
369
+ * Shared by the TUI and GUI modals so both surfaces steer with byte-identical
370
+ * text; pinned by a test rather than living inside a JSX callback.
371
+ */
372
+ function buildTodoRetryMessage(item) {
373
+ return `Retry this todo (currently ${item.status}): "${item.content}"`;
374
+ }
375
+ //#endregion
376
+ export { buildVisibleAuthRows as _, editTodo as a, parentProviderKey as b, NOTICE_GLYPH as c, splitCommandLine as d, validateMcpForm as f, instructionPreviewLines as g, instructionOriginBadge as h, cycleTodoStatus as i, MCP_TRANSPORTS as l, buildVisibleInstructionRows as m, buildTodoRetryMessage as n, nextTodoId as o, INSTRUCTION_PREVIEW_LINE_CAP as p, clearTodos as r, removeTodo as s, addTodo as t, parseKeyValueLines as u, indexOfProviderRow as v, selectableSources as x, isExpandableProvider as y };
377
+
378
+ //# sourceMappingURL=todo-edits-Dw2oO2ON.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todo-edits-Dw2oO2ON.js","names":[],"sources":["../src/chat/auth-rows.ts","../src/chat/instruction-rows.ts","../src/chat/mcp-form.ts","../src/chat/notice-format.ts","../src/chat/todo-edits.ts"],"sourcesContent":["/**\n * Renderer-agnostic data model for the Authentication settings list when a\n * provider holds more than one credential source.\n *\n * Mirrors `chat/mcp-rows.ts` deliberately: a flat row list plus a single\n * integer cursor that walks both provider headers AND their nested source\n * rows, so a renderer iterates once and never needs separate \"which provider\n * am I on / which source inside it\" state.\n *\n * Lives in `chat/` rather than `tui/` for the same reason as the MCP model —\n * the flattening and cursor arithmetic are pure, and pure means they can be\n * asserted directly instead of through a rendered modal.\n *\n * A provider is only expandable when it has MORE THAN ONE source. Single-source\n * providers (the overwhelming majority) stay exactly as they were: one row, no\n * chevron, no expansion state. That keeps the list quiet and means this model\n * changes nothing for anyone who hasn't stacked two credentials.\n */\n\nimport type { AuthMethod, ProviderAuth } from './auth'\n\n/**\n * One row in the flattened Authentication list. Two kinds:\n *\n * - `'provider'` — provider header with label, configured badge, and (when\n * expandable) the chevron. Always present.\n * - `'source'` — one credential source belonging to the provider above.\n * Present only while that provider is expanded.\n */\nexport type VisibleAuthRow\n = | { kind: 'provider', provider: ProviderAuth, expandable: boolean }\n | { kind: 'source', providerKey: string, method: AuthMethod }\n\n/**\n * Stored credentials, i.e. the ones a user can actually choose between.\n *\n * `env` is excluded: it is observed rather than stored, and is usually just the\n * mirror `applyApiKeyEnv` wrote from the stored API key, so counting it would\n * advertise a choice that does not exist.\n */\nexport function selectableSources(provider: ProviderAuth): AuthMethod[] {\n return provider.methods.filter(m => m.source !== 'env')\n}\n\n/** A provider earns a chevron only when there is a real choice to reveal. */\nexport function isExpandableProvider(provider: ProviderAuth): boolean {\n return selectableSources(provider).length > 1\n}\n\n/**\n * Flatten the provider list plus the expanded set into the visible-row list.\n *\n * - `providers` — filtered / ordered provider list (post-search).\n * - `expanded` — keys of providers whose sources are open. Keys for\n * providers that are no longer expandable are ignored rather\n * than cleaned up, so stale expansion state (a credential\n * removed while the modal is open) can't desync the cursor.\n */\nexport function buildVisibleAuthRows(\n providers: readonly ProviderAuth[],\n expanded: ReadonlySet<string>,\n): VisibleAuthRow[] {\n const out: VisibleAuthRow[] = []\n for (const provider of providers) {\n const expandable = isExpandableProvider(provider)\n out.push({ kind: 'provider', provider, expandable })\n if (!expandable || !expanded.has(provider.key))\n continue\n for (const method of selectableSources(provider))\n out.push({ kind: 'source', providerKey: provider.key, method })\n // The env slot is listed for context whenever the provider declares one,\n // present or not. It disappears from `methods` the moment a stored OAuth\n // grant wins (`applyApiKeyEnv` clears the var so the refresh path reads the\n // file), and a row that vanishes on selection reads as a bug.\n if (provider.envKey) {\n const envMethod = provider.methods.find(m => m.source === 'env')\n out.push({\n kind: 'source',\n providerKey: provider.key,\n method: envMethod ?? { source: 'env', detail: provider.envKey, active: false },\n })\n }\n }\n return out\n}\n\n/**\n * Provider key a row \"belongs to\" — its own for a provider header, the parent's\n * for a source row.\n */\nexport function parentProviderKey(row: VisibleAuthRow): string {\n return row.kind === 'provider' ? row.provider.key : row.providerKey\n}\n\n/**\n * Index in `rows` of the header for the given provider key, or `-1`.\n *\n * Collapse handlers snap the cursor up to the parent BEFORE the row list\n * shrinks; without that the cursor keeps its flat index and silently lands on\n * whichever sibling row slid into that slot.\n */\nexport function indexOfProviderRow(rows: readonly VisibleAuthRow[], providerKey: string): number {\n return rows.findIndex(r => r.kind === 'provider' && r.provider.key === providerKey)\n}\n","/**\n * Renderer-agnostic visible-row model for the Settings → Instructions tab.\n *\n * Simpler than the MCP / extension row models next door: a segment's expanded\n * TEXT is rendered inside its own row box rather than as sibling rows, so the\n * cursor walks one slot per segment no matter how long the text is. Expanding a\n * 1500-line AGENTS.md must not turn ↓ into 1500 keypresses.\n *\n * Pure (no OpenTUI / React) so the filtering + preview clamping is\n * unit-testable.\n */\n\nimport type { ContextSegment } from './context-segments'\n\n/**\n * Upper bound on preview lines rendered for one expanded segment. Mirrors the\n * Logs tab's render cap: the scrollbox can hold arbitrary height, but pasting a\n * runaway 64KB instruction file into the layout pass is a waste of a frame.\n * File-backed segments have `$EDITOR` as the escape hatch for the remainder.\n */\nexport const INSTRUCTION_PREVIEW_LINE_CAP = 400\n\n/** One selectable row: a context segment, plus its resolved open state. */\nexport interface VisibleInstructionRow {\n segment: ContextSegment\n expanded: boolean\n}\n\nexport interface BuildVisibleInstructionRowsOptions {\n segments: readonly ContextSegment[]\n /** Segment ids the user has expanded. */\n expanded: ReadonlySet<string>\n /** True when a search query is active. */\n queryActive: boolean\n /** Whether a segment matches the query. Ignored when `queryActive` is false. */\n matchSegment: (segment: ContextSegment) => boolean\n}\n\n/**\n * Filter segments by the active query and resolve each one's expanded state.\n *\n * Deliberately does NOT auto-expand matches the way the Extensions tab does:\n * the search corpus includes each segment's full text, so a query typically\n * matches deep inside a long document — auto-expanding every hit would dump\n * thousands of lines into the viewport on a keystroke. The user expands the row\n * they care about.\n */\nexport function buildVisibleInstructionRows(\n opts: BuildVisibleInstructionRowsOptions,\n): VisibleInstructionRow[] {\n const { segments, expanded, queryActive, matchSegment } = opts\n const out: VisibleInstructionRow[] = []\n for (const segment of segments) {\n if (queryActive && !matchSegment(segment))\n continue\n out.push({ segment, expanded: expanded.has(segment.id) })\n }\n return out\n}\n\n/**\n * Split a segment's text into renderable preview lines, clamped to\n * {@link INSTRUCTION_PREVIEW_LINE_CAP}.\n *\n * `hidden` is how many lines were dropped off the tail, so the view can render\n * an honest \"+N more lines\" marker instead of silently truncating. Tabs are\n * expanded to two spaces because the terminal text renderable doesn't\n * interpret `\\t`, and `\\r` is stripped so CRLF files don't leave artefacts at\n * every line end.\n */\nexport function instructionPreviewLines(text: string): { lines: string[], hidden: number } {\n const all = text.replace(/\\r\\n?/g, '\\n').replace(/\\t/g, ' ').split('\\n')\n // Trailing blank lines carry no information in a preview and would render as\n // dead space under the last line of a file that ends with a newline.\n while (all.length > 0 && all[all.length - 1]!.trim() === '')\n all.pop()\n if (all.length <= INSTRUCTION_PREVIEW_LINE_CAP)\n return { lines: all, hidden: 0 }\n return {\n lines: all.slice(0, INSTRUCTION_PREVIEW_LINE_CAP),\n hidden: all.length - INSTRUCTION_PREVIEW_LINE_CAP,\n }\n}\n\n/**\n * Short badge for a segment's origin — the \"where does this come from\" column.\n * `'file'` is intentionally the only one that reads like a location, since it's\n * the only origin the user can act on.\n */\nexport function instructionOriginBadge(segment: ContextSegment): string {\n switch (segment.origin) {\n case 'file':\n return 'file'\n case 'generated':\n return 'generated'\n case 'mcp':\n return 'mcp server'\n case 'built-in':\n return 'built-in'\n }\n}\n","/**\n * Add-MCP form model — values, validation, and the two tokenizers it depends\n * on. Renderer-agnostic and node-free.\n *\n * Lives in `chat/` because BOTH clients render this form (the TUI's\n * `settings-form-dialog`, the GUI's `McpsPanel`). It used to exist as two\n * copies that had already diverged in formatting; validation is the one place\n * a divergence would matter, because it decides which MCP configs each surface\n * accepts. One implementation means the same `mcps.json` entry is accepted or\n * rejected identically everywhere.\n */\nimport type { McpServerConfig } from '../types'\n\n/** Where a written MCP entry lands. */\nexport type InstallScopeChoice = 'user' | 'project'\n\nexport type McpTransport = 'stdio' | 'streamable-http' | 'sse'\n\nexport const MCP_TRANSPORTS: readonly McpTransport[] = ['stdio', 'streamable-http', 'sse']\n\nexport interface McpFormValues {\n name: string\n transport: McpTransport\n /** stdio: full command line (first token = command, rest = args). */\n commandLine: string\n /** http/sse: server URL. */\n url: string\n /** One `KEY=VALUE` per line — stdio only. Values may contain spaces. */\n env: string\n /** One `Name: value` (or `Name=value`) per line — http/sse only. */\n headers: string\n scope: InstallScopeChoice\n}\n\nexport interface McpFormResult {\n entry: McpServerConfig\n scope: InstallScopeChoice\n}\n\n/**\n * Validate + normalize the raw field values into a config entry.\n * Returns the first problem in row order so the dialog can surface it.\n */\nexport function validateMcpForm(values: McpFormValues): { ok: true, result: McpFormResult } | { ok: false, error: string } {\n const name = values.name.trim()\n if (name.length === 0)\n return { ok: false, error: 'name is required' }\n if (!/^[\\w.-]+$/.test(name))\n return { ok: false, error: 'name must be alphanumerics, dots, hyphens, underscores' }\n\n if (values.transport === 'stdio') {\n const tokens = splitCommandLine(values.commandLine)\n if (tokens.length === 0)\n return { ok: false, error: 'command is required for stdio servers' }\n const env = parseKeyValueLines(values.env, { label: 'env', separators: ['='] })\n if (!env.ok)\n return { ok: false, error: env.error }\n const entry: McpServerConfig = {\n name,\n transport: 'stdio',\n command: tokens[0] as string,\n ...(tokens.length > 1 ? { args: tokens.slice(1) } : {}),\n ...(Object.keys(env.pairs).length > 0 ? { env: env.pairs } : {}),\n }\n return { ok: true, result: { entry, scope: values.scope } }\n }\n\n const url = values.url.trim()\n if (url.length === 0)\n return { ok: false, error: 'url is required for http/sse servers' }\n if (!/^https?:\\/\\//.test(url))\n return { ok: false, error: 'url must start with http:// or https://' }\n const headers = parseKeyValueLines(values.headers, { label: 'headers', separators: [':', '='] })\n if (!headers.ok)\n return { ok: false, error: headers.error }\n return {\n ok: true,\n result: {\n entry: {\n name,\n transport: values.transport,\n url,\n ...(Object.keys(headers.pairs).length > 0 ? { headers: headers.pairs } : {}),\n },\n scope: values.scope,\n },\n }\n}\n\n/**\n * Split a command line into tokens, honoring single/double quotes so\n * `npx -y my-server --root \"/path with spaces\"` round-trips. No escape\n * processing beyond quote grouping — this is a form field, not a shell.\n */\nexport function splitCommandLine(line: string): string[] {\n const out: string[] = []\n const re = /\"([^\"]*)\"|'([^']*)'|(\\S+)/g\n for (let m = re.exec(line); m !== null; m = re.exec(line))\n out.push((m[1] ?? m[2] ?? m[3]) as string)\n return out\n}\n\n/**\n * Parse one key/value pair PER LINE. Line-based (not whitespace-split)\n * because values legitimately contain spaces — `Authorization: Bearer\n * abc123` is the canonical headers case, and env values like\n * `GREETING=hello world` are equally valid. The first separator found\n * (in `separators` priority order, `:` before `=` for headers) splits;\n * the rest of the line is the value, trimmed. Blank lines skipped.\n */\nexport function parseKeyValueLines(\n raw: string,\n opts: { label: string, separators: readonly string[] },\n): { ok: true, pairs: Record<string, string> } | { ok: false, error: string } {\n const pairs: Record<string, string> = {}\n for (const line of raw.split('\\n')) {\n const trimmed = line.trim()\n if (trimmed.length === 0)\n continue\n let splitAt = -1\n for (const sep of opts.separators) {\n const idx = trimmed.indexOf(sep)\n if (idx > 0 && (splitAt === -1 || idx < splitAt))\n splitAt = idx\n }\n if (splitAt <= 0) {\n const forms = opts.separators.map(s => `KEY${s}VALUE`).join(' or ')\n return { ok: false, error: `${opts.label} entries must be ${forms}, one per line (got \"${trimmed}\")` }\n }\n const key = trimmed.slice(0, splitAt).trim()\n const value = trimmed.slice(splitAt + 1).trim()\n if (key.length === 0)\n return { ok: false, error: `${opts.label} entry has an empty key (\"${trimmed}\")` }\n pairs[key] = value\n }\n return { ok: true, pairs }\n}\n","/**\n * Presentation constants for structured transcript notices (`StreamEvent.notice`).\n *\n * Shared by the TUI transcript and the GUI timeline so a `warn` notice reads\n * with the same glyph on both, and so the label vocabulary (`model fallback`,\n * `output limit`, `repeat guard`, …) is recognisably the same row across\n * surfaces. Pure; re-exported from `zidane/chat/pure`.\n */\nimport type { StreamEvent } from './types'\n\nexport type NoticeSeverity = NonNullable<StreamEvent['notice']>['severity']\n\n/** Leading glyph per severity. `info` is deliberately quiet — a middle dot. */\nexport const NOTICE_GLYPH: Readonly<Record<NoticeSeverity, string>> = {\n info: '·',\n warn: '!',\n error: '✗',\n}\n","/**\n * User-initiated todo-list edits — pure transforms over `TodoItem[]`.\n *\n * The todo list is normally MODEL-owned: `todowrite` passes the full array on\n * every call, so a checkpoint replaces whatever was there. These transforms let\n * the TUI's `ctrl+t` panel edit the same list, with one consequence the UI must\n * surface rather than hide: **a user edit made during a live run is overwritten\n * by the agent's next checkpoint**. Nothing here can prevent that — it is the\n * tool's contract — so the modal warns while a run is in flight instead of\n * pretending the edit is durable.\n *\n * Kept pure and renderer-agnostic (no React, no node) so the reducers are\n * unit-testable and a GUI shell can drive the same edits.\n */\n\nimport type { TodoItem, TodoStatus } from './todos'\n\n/**\n * Prefix for ids minted here, distinguishing user-authored rows from the\n * model's own ids in a session file. Purely diagnostic — nothing branches on\n * it — but it makes \"who added this\" answerable after the fact.\n */\nconst USER_TODO_ID_PREFIX = 'user-'\n\n/**\n * Mint an id that cannot collide with an existing row.\n *\n * Counter-based rather than random: a stable, readable id keeps session diffs\n * legible, and the collision check makes it safe against ids the model already\n * used (including previous `user-*` ones after a reload).\n */\nexport function nextTodoId(items: readonly TodoItem[]): string {\n const taken = new Set(items.map(i => i.id))\n for (let n = 1; ; n++) {\n const id = `${USER_TODO_ID_PREFIX}${n}`\n if (!taken.has(id))\n return id\n }\n}\n\n/**\n * Append a todo. Returns the list unchanged when `content` is blank — an empty\n * row is never what the user meant, and rejecting it here means every caller\n * (keyboard, click, future GUI) gets the same guard.\n */\nexport function addTodo(items: readonly TodoItem[], content: string): TodoItem[] {\n const trimmed = content.trim()\n if (!trimmed)\n return [...items]\n return [...items, { id: nextTodoId(items), content: trimmed, status: 'pending' }]\n}\n\n/**\n * Replace one todo's text. Blank content is rejected (see {@link addTodo}); an\n * unknown id is a no-op rather than an error, because the list can be replaced\n * by a `todowrite` between render and keypress.\n */\nexport function editTodo(items: readonly TodoItem[], id: string, content: string): TodoItem[] {\n const trimmed = content.trim()\n if (!trimmed)\n return [...items]\n return items.map(item => item.id === id ? { ...item, content: trimmed } : item)\n}\n\n/** Drop one todo. Unknown id is a no-op, same rationale as {@link editTodo}. */\nexport function removeTodo(items: readonly TodoItem[], id: string): TodoItem[] {\n return items.filter(item => item.id !== id)\n}\n\n/** Drop everything. Separate from `removeTodo` so the caller's intent is explicit at the call site. */\nexport function clearTodos(): TodoItem[] {\n return []\n}\n\n/**\n * Advance a todo's status one step: pending → in_progress → completed →\n * pending. `cancelled` also lands on `pending`, so a dropped item can be\n * revived without a dedicated key.\n *\n * Cycling INTO `in_progress` demotes any other in-progress row to `pending`:\n * the list's whole purpose is \"what is being worked on right now\", and two\n * live rows make that unanswerable — `TodoIndicator`'s successor\n * (`todoProgressLabel`) reads the first one and would silently ignore the rest.\n */\nexport function cycleTodoStatus(items: readonly TodoItem[], id: string): TodoItem[] {\n const target = items.find(item => item.id === id)\n if (!target)\n return [...items]\n const next = nextStatus(target.status)\n return items.map((item) => {\n if (item.id === id)\n return { ...item, status: next }\n if (next === 'in_progress' && item.status === 'in_progress')\n return { ...item, status: 'pending' as TodoStatus }\n return item\n })\n}\n\nfunction nextStatus(status: TodoStatus): TodoStatus {\n switch (status) {\n case 'pending':\n return 'in_progress'\n case 'in_progress':\n return 'completed'\n case 'completed':\n case 'cancelled':\n default:\n return 'pending'\n }\n}\n\n/**\n * Steering text for a \"retry this todo\" request.\n *\n * Quotes the content so a model reading it can match the row verbatim against\n * its own list, and names the status because \"retry\" means different things\n * for a row it believes is `completed` versus one it abandoned as `cancelled`.\n * Shared by the TUI and GUI modals so both surfaces steer with byte-identical\n * text; pinned by a test rather than living inside a JSX callback.\n */\nexport function buildTodoRetryMessage(item: TodoItem): string {\n return `Retry this todo (currently ${item.status}): \"${item.content}\"`\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Ed as StreamEvent, Rd as ProviderAuth, Td as Settings, Ud as ModelInfo, bh as SessionTurn, wd as SessionMeta, zd as ProviderKey } from "./index-D0O-QO7Z.js";
1
+ import { Cd as ProviderKey, Cu as StreamEvent, Dd as ModelInfo, Sd as ProviderAuth, Sg as SessionTurn, Su as Settings, xu as SessionMeta } from "./index-B-FSaM3_.js";
2
2
  import { ReactNode } from "react";
3
3
 
4
4
  //#region src/chat/turn-selection.d.ts
@@ -67,6 +67,38 @@ declare function isUserBashEvent(event: Pick<StreamEvent, 'tool' | 'callId'>): b
67
67
  * can cheaply skip a re-render.
68
68
  */
69
69
  declare function retagUserPromptEvents(events: readonly StreamEvent[], appendedTurns: readonly SessionTurn[]): readonly StreamEvent[];
70
+ /**
71
+ * Reduce persisted turns to the prompt refs the retag needs, dropping
72
+ * non-prompt turns (assistant, tool results) entirely.
73
+ *
74
+ * Shared by the in-process path and the daemon broadcast so both select the
75
+ * same turns as "prompts" — a divergence here would make a prompt selectable
76
+ * on one surface and not the other.
77
+ */
78
+ declare function promptTurnRefs(turns: readonly SessionTurn[]): PromptTurnRef[];
79
+ /**
80
+ * The minimum a prompt turn must carry to be matched against its live echo.
81
+ *
82
+ * Exists because the daemon has to send this over a wire: a full `SessionTurn`
83
+ * carries every content block, including base64 image and document payloads,
84
+ * which would be megabytes per prompt to ship for the sake of attaching an id.
85
+ */
86
+ interface PromptTurnRef {
87
+ id: string;
88
+ /** Text blocks plus the `display` override, if any. */
89
+ texts: readonly string[];
90
+ attachmentOnly: boolean;
91
+ }
92
+ /**
93
+ * Attach persisted turn ids to the live `user-prompt` events they correspond
94
+ * to, so a just-sent prompt becomes selectable (hover, click, edit, delete)
95
+ * without waiting for a session reload.
96
+ *
97
+ * Matching is newest-first and one-to-one: identical prompt text sent twice
98
+ * must bind to two different turns, so each ref consumes exactly one untagged
99
+ * event.
100
+ */
101
+ declare function retagUserPromptEventsFromRefs(events: readonly StreamEvent[], refs: readonly PromptTurnRef[]): readonly StreamEvent[];
70
102
  /**
71
103
  * Per-event visibility — filters honor user toggles and the
72
104
  * `hideSubagentOutput` setting. When subagent output is hidden:
@@ -143,6 +175,33 @@ declare function isTurnHighlighted(event: Pick<StreamEvent, 'turnId'>, selectedT
143
175
  */
144
176
  declare function selectableTurnIds(events: readonly StreamEvent[], settings?: Settings, visible?: (event: StreamEvent) => boolean): string[];
145
177
  //#endregion
178
+ //#region src/chat/daemon-health.d.ts
179
+ /**
180
+ * Daemon connection health — the one model behind the status dot in both
181
+ * clients' footers.
182
+ *
183
+ * Three states, because "connected: boolean" cannot express the one users
184
+ * actually want to see: a daemon that is being spawned or reconnected is not
185
+ * DOWN, and painting it red for the seconds that takes teaches people to
186
+ * ignore red. So:
187
+ *
188
+ * - `connected` — handshake done, signals live. green (accent)
189
+ * - `connecting` — spawning / reconnecting / first attempt. amber (warn)
190
+ * - `disconnected` — reachable daemon absent, last attempt failed. red (error)
191
+ *
192
+ * Tones are theme SLOTS, not colors, so the dot recolors with the palette on
193
+ * both surfaces. Node-free; re-exported from `zidane/chat/pure`.
194
+ */
195
+ type DaemonHealth = 'connected' | 'connecting' | 'disconnected';
196
+ type DaemonHealthTone = 'accent' | 'warn' | 'error';
197
+ interface DaemonHealthStyle {
198
+ tone: DaemonHealthTone;
199
+ /** Tooltip / accessibility text. The dot itself carries no words. */
200
+ label: string;
201
+ }
202
+ declare const DAEMON_HEALTH_GLYPH = "\u25CF";
203
+ declare const DAEMON_HEALTH_STYLE: Readonly<Record<DaemonHealth, DaemonHealthStyle>>;
204
+ //#endregion
146
205
  //#region src/chat/safe-mode-context.d.ts
147
206
  /**
148
207
  * Outcome of an approval prompt. Four bulk decisions match the original
@@ -178,9 +237,17 @@ interface ApprovalRequest {
178
237
  resolve: (decision: ApprovalDecision) => void;
179
238
  /** Caller attribution. Absent ≡ `{ kind: 'parent' }`. */
180
239
  originator?: ApprovalOriginator;
240
+ /**
241
+ * Cross-window correlation id (the daemon's approval request id) for
242
+ * entries surfaced by the daemon runtime. Lets `dropByCorrelation`
243
+ * retract this entry when ANOTHER window resolves the same shared
244
+ * approval, without re-sending a decision. Absent for local-runtime
245
+ * approvals.
246
+ */
247
+ correlationId?: string;
181
248
  }
182
249
  /** Function signature consumed by `tool:gate` handlers + the child-tool wrap. */
183
- type RequestApproval = (tool: string, input: Record<string, unknown>, originator?: ApprovalOriginator) => Promise<ApprovalDecision>;
250
+ type RequestApproval = (tool: string, input: Record<string, unknown>, originator?: ApprovalOriginator, correlationId?: string) => Promise<ApprovalDecision>;
184
251
  interface SafeModeActions {
185
252
  /** Request a decision; resolves once the user picks. */
186
253
  requestApproval: RequestApproval;
@@ -188,6 +255,11 @@ interface SafeModeActions {
188
255
  resolveHead: (decision: ApprovalDecision) => void;
189
256
  /** Resolve all pending with `deny`. Used on abort / hard exit. */
190
257
  denyAll: () => void;
258
+ /**
259
+ * Remove the entry whose `correlationId` matches, WITHOUT resolving it
260
+ * (the daemon already did, in another window). No-op when absent.
261
+ */
262
+ dropByCorrelation: (correlationId: string) => void;
191
263
  }
192
264
  /**
193
265
  * Owns the queue + actions. Splits the value across two contexts so a queue
@@ -436,6 +508,21 @@ declare function indexOfEntry(catalog: readonly CatalogEntry[], target: {
436
508
  providerKey: ProviderKey;
437
509
  modelId: string;
438
510
  } | null | undefined): number;
511
+ /**
512
+ * Read a query that matched nothing as "use this model id anyway".
513
+ *
514
+ * A bare id is meaningless without a provider, so the first term is checked
515
+ * against every provider's key and label (case-insensitive): `xai grok-9` and
516
+ * `Anthropic claude-next` name their provider explicitly, anything else is
517
+ * attributed to `fallbackProviderKey` (the picker's current pick). Returns
518
+ * `null` when nothing usable is left, including when the whole query is just a
519
+ * provider name.
520
+ */
521
+ declare function parseCustomModelQuery(query: string, providers: readonly Pick<ProviderAuth, 'key' | 'label'>[], fallbackProviderKey: ProviderKey | null): {
522
+ providerKey: ProviderKey;
523
+ providerLabel: string;
524
+ modelId: string;
525
+ } | null;
439
526
  //#endregion
440
527
  //#region src/chat/prompt-segments.d.ts
441
528
  /**
@@ -529,6 +616,19 @@ interface ToolFormatLine {
529
616
  * or any short suffix that adds context without bloating the line.
530
617
  */
531
618
  meta?: readonly string[];
619
+ /**
620
+ * Optional SECOND line — the payload behind the action (a prompt sent to
621
+ * another session). Renderers paint it dimmed under the header and clamp
622
+ * it (two lines in the GUI, one terminal row in the TUI); it is never
623
+ * squeezed into the header line, which stays single-line.
624
+ */
625
+ detail?: string;
626
+ /**
627
+ * The session this call targets, when the tool addresses one. `target`
628
+ * carries the short id as a fallback; a renderer with the session list in
629
+ * scope shows the session's TITLE instead.
630
+ */
631
+ sessionId?: string;
532
632
  }
533
633
  interface ToolDisplayMeta {
534
634
  /**
@@ -573,5 +673,5 @@ declare function displayNameFor(name: string, input?: Record<string, unknown>):
573
673
  */
574
674
  declare function formatToolCall(name: string, input: Record<string, unknown>): ToolFormatLine | null;
575
675
  //#endregion
576
- export { retagUserPromptEvents as $, highlightSegments as A, ApprovalDecision as B, SearchTurnResult as C, buildSessionSearchIndex as D, SessionSearchIndex as E, searchSessionIndex as F, useSafeModeActions as G, RequestApproval as H, searchSessionIndexAsync as I, EDIT_TOOL_NAMES as J, useSafeModeQueue as K, searchSessionTurns as L, searchSessionHistory as M, searchSessionHistoryIndex as N, buildSessionSearchIndexAsync as O, searchSessionHistoryIndexAsync as P, isVisible as Q, searchTurns as R, SearchSessionResult as S, SessionSearchExcerpt as T, SafeModeActions as U, ApprovalRequest as V, SafeModeProvider as W, isTurnHighlighted as X, isEditErrorResult as Y, isUserBashEvent as Z, splitMarkdownCodeBlocks as _, formatToolCall as a, IndexedSearchTurn as b, splitPromptSegments as c, filterModelCatalog as d, selectableTurnIds as et, indexOfEntry as f, normalizeMarkdownCodeFences as g, chunkMarkdownForRender as h, displayNameFor as i, searchHighlightRanges as j, filterSessionSearchCatalog as k, CatalogEntry as l, MarkdownSegment as m, ToolDisplayMeta as n, turnSelectionOwnership as nt, PromptSegment as o, MARKDOWN_RENDER_CHUNK_TARGET_BYTES as p, BASH_CALL_ID_PREFIX as q, ToolFormatLine as r, PromptSegmentRef as s, TOOL_DISPLAY as t, selectionAfterTurnRemoval as tt, buildModelCatalog as u, HighlightRange as v, SessionHistoryMatch as w, SearchExcerpt as x, HighlightSegment as y, searchableTurnText as z };
577
- //# sourceMappingURL=tool-formatters-NrzD6Fkk.d.ts.map
676
+ export { BASH_CALL_ID_PREFIX as $, filterSessionSearchCatalog as A, searchableTurnText as B, SearchSessionResult as C, SessionSearchIndex as D, SessionSearchExcerpt as E, searchSessionHistoryIndexAsync as F, SafeModeProvider as G, ApprovalRequest as H, searchSessionIndex as I, DAEMON_HEALTH_GLYPH as J, useSafeModeActions as K, searchSessionIndexAsync as L, searchHighlightRanges as M, searchSessionHistory as N, buildSessionSearchIndex as O, searchSessionHistoryIndex as P, DaemonHealthTone as Q, searchSessionTurns as R, SearchExcerpt as S, SessionHistoryMatch as T, RequestApproval as U, ApprovalDecision as V, SafeModeActions as W, DaemonHealth as X, DAEMON_HEALTH_STYLE as Y, DaemonHealthStyle as Z, normalizeMarkdownCodeFences as _, formatToolCall as a, isVisible as at, HighlightSegment as b, splitPromptSegments as c, retagUserPromptEventsFromRefs as ct, filterModelCatalog as d, turnSelectionOwnership as dt, EDIT_TOOL_NAMES as et, indexOfEntry as f, chunkMarkdownForRender as g, MarkdownSegment as h, displayNameFor as i, isUserBashEvent as it, highlightSegments as j, buildSessionSearchIndexAsync as k, CatalogEntry as l, selectableTurnIds as lt, MARKDOWN_RENDER_CHUNK_TARGET_BYTES as m, ToolDisplayMeta as n, isEditErrorResult as nt, PromptSegment as o, promptTurnRefs as ot, parseCustomModelQuery as p, useSafeModeQueue as q, ToolFormatLine as r, isTurnHighlighted as rt, PromptSegmentRef as s, retagUserPromptEvents as st, TOOL_DISPLAY as t, PromptTurnRef as tt, buildModelCatalog as u, selectionAfterTurnRemoval as ut, splitMarkdownCodeBlocks as v, SearchTurnResult as w, IndexedSearchTurn as x, HighlightRange as y, searchTurns as z };
677
+ //# sourceMappingURL=tool-formatters-DO56YBBw.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-formatters-DO56YBBw.d.ts","names":[],"sources":["../src/chat/turn-selection.ts","../src/chat/daemon-health.ts","../src/chat/safe-mode-context.tsx","../src/chat/history-search.ts","../src/chat/markdown-segments.ts","../src/chat/model-catalog.ts","../src/chat/prompt-segments.ts","../src/chat/tool-formatters.ts"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Gh as ToolDef } from "../index-D0O-QO7Z.js";
1
+ import { qg as ToolDef } from "../index-B-FSaM3_.js";
2
2
 
3
3
  //#region src/tools/fetch-url.d.ts
4
4
  declare function isBlockedAddress(ip: string): boolean;
@@ -1,4 +1,4 @@
1
- import { Gh as ToolDef } from "../index-D0O-QO7Z.js";
1
+ import { qg as ToolDef } from "../index-B-FSaM3_.js";
2
2
 
3
3
  //#region src/tools/web-search.d.ts
4
4
  declare const webSearch: ToolDef;
package/dist/tools.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { $h as hydrateReadStateFromSessionAsync, Ar as createSkillsReadTool, As as SpawnTaskInput, Br as grep, Bs as SpawnModelEntry, Cr as ToolSearchToolOptions, Dr as SkillsRunScriptToolOptions, Er as createSkillsUseTool, Fr as readFile, Fs as SubagentDef, Gh as ToolDef, Hr as edit, Hs as formatModelLine, Ir as multiEdit, Is as SubagentOverride, Jh as ReadStateEntry, Kh as ToolMap, Lr as listFiles, Ls as SubagentRegistry, Mr as CreateShellToolOptions, Ms as SpawnTool, Nr as createShellTool, Ns as SpawnToolOptions, Or as createSkillsRunScriptTool, Os as ChildAgent, Pr as shell, Ps as SpawnToolState, Qh as hydrateReadStateFromSession, Rr as InteractionToolOptions, Rs as createSpawnTool, Sr as LazyToolEntry, Tr as SkillsUseToolOptions, Us as matchModelEntries, Vr as glob, Vs as createModelSearchTool, Wh as ToolContext, Xh as getReadState, Yh as ReadStateMap, Zh as hashContent, _r as waitTask, br as TailTruncateOptions, eg as readStateKey, gr as WAIT_TASK_TIMED_OUT_PREFIX, hr as writeFile, jr as shellKill, js as SpawnTaskOutcome, kr as SkillsReadToolOptions, ks as ExtensionSubagentDef, qh as HydrateReadStateOptions, tg as resolveReadStateMap, vr as ValidationResult, wr as createToolSearchTool, xr as tailTruncate, yr as validateToolArgs, zr as createInteractionTool, zs as isSpawnTool } from "./index-D0O-QO7Z.js";
1
+ import { $g as hashContent, Ar as createSkillsReadTool, Br as grep, Bs as SpawnTaskOutcome, Cr as ToolSearchToolOptions, Dr as SkillsRunScriptToolOptions, Er as createSkillsUseTool, Fr as readFile, Gs as SubagentOverride, Hr as edit, Hs as SpawnToolOptions, Ir as multiEdit, Jg as ToolMap, Js as isSpawnTool, Kg as ToolContext, Ks as SubagentRegistry, Lr as listFiles, Ls as ChildAgent, Mr as CreateShellToolOptions, Nr as createShellTool, Or as createSkillsRunScriptTool, Pr as shell, Qg as getReadState, Qs as matchModelEntries, Rr as InteractionToolOptions, Rs as ExtensionSubagentDef, Sr as LazyToolEntry, Tr as SkillsUseToolOptions, Us as SpawnToolState, Vr as glob, Vs as SpawnTool, Ws as SubagentDef, Xg as ReadStateEntry, Xs as createModelSearchTool, Yg as HydrateReadStateOptions, Ys as SpawnModelEntry, Zg as ReadStateMap, Zs as formatModelLine, _r as waitTask, br as TailTruncateOptions, e_ as hydrateReadStateFromSession, gr as WAIT_TASK_TIMED_OUT_PREFIX, hr as writeFile, jr as shellKill, kr as SkillsReadToolOptions, n_ as readStateKey, qg as ToolDef, qs as createSpawnTool, r_ as resolveReadStateMap, t_ as hydrateReadStateFromSessionAsync, vr as ValidationResult, wr as createToolSearchTool, xr as tailTruncate, yr as validateToolArgs, zr as createInteractionTool, zs as SpawnTaskInput } from "./index-B-FSaM3_.js";
2
2
  export { type ChildAgent, type CreateShellToolOptions, type ExtensionSubagentDef, type HydrateReadStateOptions, type InteractionToolOptions, type LazyToolEntry, type ReadStateEntry, type ReadStateMap, type SkillsReadToolOptions, type SkillsRunScriptToolOptions, type SkillsUseToolOptions, type SpawnModelEntry, type SpawnTaskInput, type SpawnTaskOutcome, type SpawnTool, type SpawnToolOptions, type SpawnToolState, type SubagentDef, type SubagentOverride, type SubagentRegistry, type TailTruncateOptions, type ToolContext, type ToolDef, type ToolMap, type ToolSearchToolOptions, type ValidationResult, WAIT_TASK_TIMED_OUT_PREFIX, createInteractionTool, createModelSearchTool, createShellTool, createSkillsReadTool, createSkillsRunScriptTool, createSkillsUseTool, createSpawnTool, createToolSearchTool, edit, formatModelLine, getReadState, glob, grep, hashContent, hydrateReadStateFromSession, hydrateReadStateFromSessionAsync, isSpawnTool, listFiles, matchModelEntries, multiEdit, readFile, readStateKey, resolveReadStateMap, shell, shellKill, tailTruncate, validateToolArgs, waitTask, writeFile };
package/dist/tools.js CHANGED
@@ -1,2 +1,2 @@
1
- import { At as createSkillsReadTool, Bn as hydrateReadStateFromSession, Bt as matchModelEntries, Ct as waitTask, Et as isSpawnTool, Ft as readFile, Gt as edit, Hn as readStateKey, Ht as createInteractionTool, Kt as validateToolArgs, Lt as multiEdit, Mt as createShellTool, Nt as shell, Ot as createSkillsUseTool, Pt as tailTruncate, Rn as getReadState, Rt as createModelSearchTool, St as WAIT_TASK_TIMED_OUT_PREFIX, Tt as createSpawnTool, Un as resolveReadStateMap, Ut as grep, Vn as hydrateReadStateFromSessionAsync, Vt as listFiles, Wt as glob, jt as shellKill, kt as createSkillsRunScriptTool, wt as createToolSearchTool, xt as writeFile, zn as hashContent, zt as formatModelLine } from "./agent-DTxH7RHW.js";
1
+ import { At as createSkillsReadTool, Bt as matchModelEntries, Ct as waitTask, Et as isSpawnTool, Ft as readFile, Gn as readStateKey, Gt as edit, Hn as hashContent, Ht as createInteractionTool, Kn as resolveReadStateMap, Kt as validateToolArgs, Lt as multiEdit, Mt as createShellTool, Nt as shell, Ot as createSkillsUseTool, Pt as tailTruncate, Rt as createModelSearchTool, St as WAIT_TASK_TIMED_OUT_PREFIX, Tt as createSpawnTool, Un as hydrateReadStateFromSession, Ut as grep, Vn as getReadState, Vt as listFiles, Wn as hydrateReadStateFromSessionAsync, Wt as glob, jt as shellKill, kt as createSkillsRunScriptTool, wt as createToolSearchTool, xt as writeFile, zt as formatModelLine } from "./agent-C-camKQW.js";
2
2
  export { WAIT_TASK_TIMED_OUT_PREFIX, createInteractionTool, createModelSearchTool, createShellTool, createSkillsReadTool, createSkillsRunScriptTool, createSkillsUseTool, createSpawnTool, createToolSearchTool, edit, formatModelLine, getReadState, glob, grep, hashContent, hydrateReadStateFromSession, hydrateReadStateFromSessionAsync, isSpawnTool, listFiles, matchModelEntries, multiEdit, readFile, readStateKey, resolveReadStateMap, shell, shellKill, tailTruncate, validateToolArgs, waitTask, writeFile };