@wrongstack/tui 0.272.2 → 0.273.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +11 -3
- package/dist/index.js +2101 -511
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export { buildGoalPreamble } from '@wrongstack/core';
|
|
|
3
3
|
import { Box as Box$1, useInput, useStdin, useStdout, Text as Text$1, render, useApp, measureElement, Static } from 'ink';
|
|
4
4
|
import { randomUUID } from 'crypto';
|
|
5
5
|
import * as path5 from 'path';
|
|
6
|
-
import React5, { forwardRef, useState, useEffect, useMemo, memo, useRef, useCallback, useReducer, useLayoutEffect } from 'react';
|
|
6
|
+
import React5, { forwardRef, useState, useEffect, useMemo, memo, useRef, useCallback, useReducer, useLayoutEffect, isValidElement, Fragment as Fragment$1 } from 'react';
|
|
7
7
|
import * as fs3 from 'fs/promises';
|
|
8
8
|
import { expectDefined, toErrorMessage, resolveWstackPaths as resolveWstackPaths$1 } from '@wrongstack/core/utils';
|
|
9
9
|
import { routeImagesForModel } from '@wrongstack/runtime/vision';
|
|
@@ -140,6 +140,11 @@ function isStreamChipVisible(key, dataIsPresent, hiddenSet, visibleChips) {
|
|
|
140
140
|
if (chipExpired(meta)) return false;
|
|
141
141
|
return true;
|
|
142
142
|
}
|
|
143
|
+
function hasMailboxActivity(mailbox) {
|
|
144
|
+
if (!mailbox) return false;
|
|
145
|
+
const peerClientCount = Math.max(0, mailbox.onlineClients.tui - 1) + mailbox.onlineClients.webui + mailbox.onlineClients.repl;
|
|
146
|
+
return mailbox.unread > 0 || mailbox.onlineAgents > 1 || peerClientCount > 0 || Boolean(mailbox.lastSubject || mailbox.lastFrom);
|
|
147
|
+
}
|
|
143
148
|
var MODE_ICONS = {
|
|
144
149
|
teach: "\u{1F9D1}\u200D\u{1F3EB}",
|
|
145
150
|
brief: "\u26A1",
|
|
@@ -166,6 +171,68 @@ function formatSuggestionLabel(label, maxLen = 28) {
|
|
|
166
171
|
const lastSpace = shortened.lastIndexOf(" ");
|
|
167
172
|
return lastSpace > 10 ? `${shortened.slice(0, lastSpace)}\u2026` : `${shortened}\u2026`;
|
|
168
173
|
}
|
|
174
|
+
function countdownColor(secs, warn, danger) {
|
|
175
|
+
if (secs > warn) return "green";
|
|
176
|
+
if (secs > danger) return "yellow";
|
|
177
|
+
return "red";
|
|
178
|
+
}
|
|
179
|
+
function joinChips(chips) {
|
|
180
|
+
const out = [];
|
|
181
|
+
chips.forEach((chip, i) => {
|
|
182
|
+
if (i > 0) {
|
|
183
|
+
out.push(
|
|
184
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }, `sep-${i}`)
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
out.push(/* @__PURE__ */ jsx(Fragment$1, { children: chip }, `chip-${i}`));
|
|
188
|
+
});
|
|
189
|
+
return out;
|
|
190
|
+
}
|
|
191
|
+
function truncateChip(text, max) {
|
|
192
|
+
return text.length > max ? `${text.slice(0, max - 1)}\u2026` : text;
|
|
193
|
+
}
|
|
194
|
+
function nodeText(node) {
|
|
195
|
+
if (node == null || typeof node === "boolean") return "";
|
|
196
|
+
if (typeof node === "string") return node;
|
|
197
|
+
if (typeof node === "number") return String(node);
|
|
198
|
+
if (Array.isArray(node)) return node.map(nodeText).join("");
|
|
199
|
+
if (isValidElement(node)) {
|
|
200
|
+
return nodeText(node.props.children);
|
|
201
|
+
}
|
|
202
|
+
return "";
|
|
203
|
+
}
|
|
204
|
+
var SB_SEP_COST = 5;
|
|
205
|
+
function planChipFit(widths, budget, sepCost = SB_SEP_COST) {
|
|
206
|
+
let used = 0;
|
|
207
|
+
let keep = 0;
|
|
208
|
+
for (const w of widths) {
|
|
209
|
+
const cost = w + (keep > 0 ? sepCost : 0);
|
|
210
|
+
if (keep > 0 && used + cost > budget) break;
|
|
211
|
+
used += cost;
|
|
212
|
+
keep += 1;
|
|
213
|
+
}
|
|
214
|
+
return keep;
|
|
215
|
+
}
|
|
216
|
+
function renderChipLine(chips, budget) {
|
|
217
|
+
const keep = planChipFit(
|
|
218
|
+
chips.map((c) => nodeText(c).length),
|
|
219
|
+
budget
|
|
220
|
+
);
|
|
221
|
+
const nodes = joinChips(chips.slice(0, keep));
|
|
222
|
+
const dropped = chips.length - keep;
|
|
223
|
+
if (dropped > 0) {
|
|
224
|
+
nodes.push(
|
|
225
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }, "ovf-sep")
|
|
226
|
+
);
|
|
227
|
+
nodes.push(
|
|
228
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
229
|
+
"+",
|
|
230
|
+
dropped
|
|
231
|
+
] }, "ovf")
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
return nodes;
|
|
235
|
+
}
|
|
169
236
|
var COMPACT_THRESHOLD = 50;
|
|
170
237
|
var COMFORTABLE_THRESHOLD = 90;
|
|
171
238
|
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
@@ -237,19 +304,22 @@ function StatusBar({
|
|
|
237
304
|
}, [stdout]);
|
|
238
305
|
const isCompact = termWidth < COMPACT_THRESHOLD;
|
|
239
306
|
const isComfortable = termWidth >= COMFORTABLE_THRESHOLD;
|
|
240
|
-
const hiddenSet = new Set(hiddenItems);
|
|
307
|
+
const hiddenSet = useMemo(() => new Set(hiddenItems), [hiddenItems]);
|
|
308
|
+
const showChip = (item) => !hiddenSet.has(item);
|
|
241
309
|
const tokenData = useTokenCounterRefresh(tokenCounter, events);
|
|
242
310
|
const usage = tokenData?.usage;
|
|
243
311
|
const displayTokens = tokenDisplayTotals(usage, tokenData?.currentRequest);
|
|
244
312
|
const showTokenDisplay = hasTokenDisplay(displayTokens);
|
|
245
313
|
const cost = tokenData?.cost;
|
|
246
314
|
const cache2 = tokenData?.cacheStats;
|
|
315
|
+
const elapsedHidden = hiddenSet.has("elapsed");
|
|
247
316
|
const [elapsedMs, setElapsedMs] = useState(startedAt ? Date.now() - startedAt : 0);
|
|
248
317
|
useEffect(() => {
|
|
249
|
-
if (startedAt == null) return;
|
|
318
|
+
if (startedAt == null || elapsedHidden) return;
|
|
319
|
+
setElapsedMs(Date.now() - startedAt);
|
|
250
320
|
const t = setInterval(() => setElapsedMs(Date.now() - startedAt), 1e3);
|
|
251
321
|
return () => clearInterval(t);
|
|
252
|
-
}, [startedAt]);
|
|
322
|
+
}, [startedAt, elapsedHidden]);
|
|
253
323
|
const [spinnerIdx, setSpinnerIdx] = useState(0);
|
|
254
324
|
useEffect(() => {
|
|
255
325
|
if (state === "idle" || state === "aborting") return;
|
|
@@ -264,21 +334,22 @@ function StatusBar({
|
|
|
264
334
|
const statePrefix = state === "idle" || state === "aborting" ? "\u25CF" : spinner;
|
|
265
335
|
const thinking = state === "running" || state === "streaming";
|
|
266
336
|
const hasAutoProceed = autoProceedCountdown != null && autoProceedCountdown > 0;
|
|
267
|
-
const hasSecondLine = yolo || autonomy && autonomy !== "off" || startedAt != null || git !== null && git !== void 0 || projectName !== void 0 && projectName.length > 0 || workingDir !== void 0 && workingDir.length > 0 || goalSummary !== null && goalSummary !== void 0 || !!modeLabel || hasAutoProceed || tokenSavingMode || typeof toolCount === "number" && toolCount > 0;
|
|
337
|
+
const hasSecondLine = yolo && showChip("yolo") || autonomy && autonomy !== "off" && showChip("autonomy") || eternalStage != null && showChip("eternal_stage") || startedAt != null && showChip("elapsed") || git !== null && git !== void 0 && showChip("git") || projectName !== void 0 && projectName.length > 0 && showChip("project") || workingDir !== void 0 && workingDir.length > 0 && showChip("working_dir") || goalSummary !== null && goalSummary !== void 0 && showChip("goal") || !!modeLabel && showChip("mode") || hasAutoProceed && showChip("auto_proceed") || tokenSavingMode && showChip("token_saving") || typeof toolCount === "number" && toolCount > 0 && showChip("tools") || sessionCount != null && sessionCount > 0 && showChip("sessions");
|
|
268
338
|
const fleetHasActivity = fleet && (fleet.running > 0 || fleet.idle > 0 || fleet.pending > 0 || fleet.completed > 0) || subagentCount > 0;
|
|
269
|
-
const showBrain = isStreamChipVisible("brain", brain, hiddenSet
|
|
270
|
-
const showDebugStream = isStreamChipVisible("debug_stream", debugStreamStats, hiddenSet
|
|
271
|
-
const showEnhance = isStreamChipVisible("enhance", enhanceCountdown, hiddenSet
|
|
339
|
+
const showBrain = isStreamChipVisible("brain", brain, hiddenSet, visibleChips);
|
|
340
|
+
const showDebugStream = isStreamChipVisible("debug_stream", debugStreamStats, hiddenSet, visibleChips);
|
|
341
|
+
const showEnhance = isStreamChipVisible("enhance", enhanceCountdown, hiddenSet, visibleChips);
|
|
342
|
+
const showMailbox = showChip("mailbox") && hasMailboxActivity(mailbox);
|
|
272
343
|
const hasNextStepsAutoSubmit = nextStepsAutoSubmitCountdown != null && nextStepsAutoSubmitCountdown > 0;
|
|
273
|
-
const
|
|
344
|
+
const nextStepsColor = nextStepsAutoSubmitCountdown != null ? countdownColor(nextStepsAutoSubmitCountdown, 20, 10) : "green";
|
|
274
345
|
const hasTaskActivity = tasks && (tasks.pending > 0 || tasks.inProgress > 0 || tasks.completed > 0 || tasks.blocked > 0 || tasks.failed > 0);
|
|
275
|
-
const hasThirdLine = todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) &&
|
|
346
|
+
const hasThirdLine = todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) && showChip("todos") || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) && showChip("plan") || hasTaskActivity && showChip("tasks") || fleetHasActivity && showChip("fleet") || showBrain || showDebugStream || showEnhance || hasNextStepsAutoSubmit && showChip("next_steps");
|
|
276
347
|
const minimalWorkParts = [
|
|
277
|
-
queueCount > 0 ? `q${queueCount}` : "",
|
|
278
|
-
todos &&
|
|
279
|
-
hasTaskActivity &&
|
|
280
|
-
fleetHasActivity &&
|
|
281
|
-
typeof processCount === "number" && processCount > 0 ? `proc ${processCount}` : ""
|
|
348
|
+
queueCount > 0 && showChip("queue") ? `q${queueCount}` : "",
|
|
349
|
+
todos && showChip("todos") && todos.inProgress + todos.pending > 0 ? `todo ${todos.inProgress}/${todos.pending}` : "",
|
|
350
|
+
hasTaskActivity && showChip("tasks") ? `task ${tasks.inProgress}/${tasks.pending}` : "",
|
|
351
|
+
fleetHasActivity && showChip("fleet") ? fleet ? `agent \u25B6${fleet.running} \xB7${fleet.idle}` : `agent ${subagentCount}` : "",
|
|
352
|
+
typeof processCount === "number" && processCount > 0 && showChip("processes") ? `proc ${processCount}` : ""
|
|
282
353
|
].filter(Boolean);
|
|
283
354
|
if (mode === "minimum") {
|
|
284
355
|
const ctxMax = context?.max;
|
|
@@ -296,22 +367,22 @@ function StatusBar({
|
|
|
296
367
|
borderLeft: false,
|
|
297
368
|
borderRight: false,
|
|
298
369
|
children: /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
299
|
-
version ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
370
|
+
version && showChip("version") ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
300
371
|
/* @__PURE__ */ jsx(Text, { color: "blue", bold: true, children: "WS" }),
|
|
301
372
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
302
373
|
" v",
|
|
303
374
|
version
|
|
304
375
|
] })
|
|
305
376
|
] }) : null,
|
|
306
|
-
version ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
307
|
-
thinking ? /* @__PURE__ */ jsx(WaveText, { text: `${statePrefix} ${stateLabel}`, phase: spinnerIdx }) : /* @__PURE__ */ jsxs(Text, { color: stateColor, children: [
|
|
377
|
+
version && showChip("version") && (showChip("state") || showChip("model")) ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
378
|
+
showChip("state") && thinking ? /* @__PURE__ */ jsx(WaveText, { text: `${statePrefix} ${stateLabel}`, phase: spinnerIdx }) : showChip("state") ? /* @__PURE__ */ jsxs(Text, { color: stateColor, children: [
|
|
308
379
|
statePrefix,
|
|
309
380
|
" ",
|
|
310
381
|
stateLabel
|
|
311
|
-
] }),
|
|
312
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
313
|
-
/* @__PURE__ */ jsx(Text, { color: "magenta", children: model }),
|
|
314
|
-
ctxClampedRatio !== void 0 && ctxPctText && ctxMax !== void 0 &&
|
|
382
|
+
] }) : null,
|
|
383
|
+
showChip("state") && showChip("model") ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
384
|
+
showChip("model") ? /* @__PURE__ */ jsx(Text, { color: "magenta", children: model }) : null,
|
|
385
|
+
ctxClampedRatio !== void 0 && ctxPctText && ctxMax !== void 0 && showChip("context") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
315
386
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
316
387
|
/* @__PURE__ */ jsxs(Text, { color: ctxClampedRatio < 0.6 ? "green" : ctxClampedRatio < 0.75 ? "yellow" : "red", children: [
|
|
317
388
|
"ctx ",
|
|
@@ -320,7 +391,7 @@ function StatusBar({
|
|
|
320
391
|
fmtTok(ctxMax)
|
|
321
392
|
] })
|
|
322
393
|
] }) : null,
|
|
323
|
-
showTokenDisplay ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
394
|
+
showTokenDisplay && showChip("tokens") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
324
395
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
325
396
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
326
397
|
"\u2191 ",
|
|
@@ -330,7 +401,7 @@ function StatusBar({
|
|
|
330
401
|
/* @__PURE__ */ jsx(Text, { color: "cyan", children: fmtTok(displayTokens.output) })
|
|
331
402
|
] })
|
|
332
403
|
] }) : null,
|
|
333
|
-
cost && cost.total > 0 &&
|
|
404
|
+
cost && cost.total > 0 && showChip("cost") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
334
405
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
335
406
|
/* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
336
407
|
"$",
|
|
@@ -359,17 +430,17 @@ function StatusBar({
|
|
|
359
430
|
/* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 2, children: isCompact ? (
|
|
360
431
|
// Ultra-compact: state · model
|
|
361
432
|
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
362
|
-
thinking ? /* @__PURE__ */ jsx(WaveText, { text: `${statePrefix}${stateLabel}`, phase: spinnerIdx }) : /* @__PURE__ */ jsxs(Text, { color: stateColor, children: [
|
|
433
|
+
showChip("state") && thinking ? /* @__PURE__ */ jsx(WaveText, { text: `${statePrefix}${stateLabel}`, phase: spinnerIdx }) : showChip("state") ? /* @__PURE__ */ jsxs(Text, { color: stateColor, children: [
|
|
363
434
|
statePrefix,
|
|
364
435
|
stateLabel
|
|
365
|
-
] }),
|
|
366
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
367
|
-
/* @__PURE__ */ jsx(Text, { color: "magenta", children: model })
|
|
436
|
+
] }) : null,
|
|
437
|
+
showChip("state") && showChip("model") ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }) : null,
|
|
438
|
+
showChip("model") ? /* @__PURE__ */ jsx(Text, { color: "magenta", children: model }) : null
|
|
368
439
|
] })
|
|
369
440
|
) : (
|
|
370
441
|
// Full mode: version · state · model · context · tokens · cost · queue · processes · hint
|
|
371
442
|
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
372
|
-
version ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
443
|
+
version && showChip("version") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
373
444
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
374
445
|
/* @__PURE__ */ jsx(Text, { color: "blue", bold: true, children: "WS" }),
|
|
375
446
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
@@ -379,14 +450,16 @@ function StatusBar({
|
|
|
379
450
|
] }),
|
|
380
451
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" })
|
|
381
452
|
] }) : null,
|
|
382
|
-
thinking ? /* @__PURE__ */ jsx(WaveText, { text: `${statePrefix} ${stateLabel}`, phase: spinnerIdx }) : /* @__PURE__ */ jsxs(Text, { color: stateColor, children: [
|
|
453
|
+
showChip("state") && thinking ? /* @__PURE__ */ jsx(WaveText, { text: `${statePrefix} ${stateLabel}`, phase: spinnerIdx }) : showChip("state") ? /* @__PURE__ */ jsxs(Text, { color: stateColor, children: [
|
|
383
454
|
statePrefix,
|
|
384
455
|
" ",
|
|
385
456
|
stateLabel
|
|
386
|
-
] }),
|
|
387
|
-
/* @__PURE__ */
|
|
388
|
-
|
|
389
|
-
|
|
457
|
+
] }) : null,
|
|
458
|
+
showChip("model") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
459
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
460
|
+
/* @__PURE__ */ jsx(Text, { color: "magenta", children: model })
|
|
461
|
+
] }) : null,
|
|
462
|
+
context && showChip("context") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
390
463
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
391
464
|
(() => {
|
|
392
465
|
const ratio = context.used / context.max;
|
|
@@ -407,7 +480,7 @@ function StatusBar({
|
|
|
407
480
|
] });
|
|
408
481
|
})()
|
|
409
482
|
] }) : null,
|
|
410
|
-
showTokenDisplay ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
483
|
+
showTokenDisplay && showChip("tokens") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
411
484
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
412
485
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
413
486
|
"\u2191 ",
|
|
@@ -417,7 +490,7 @@ function StatusBar({
|
|
|
417
490
|
/* @__PURE__ */ jsx(Text, { color: "cyan", children: fmtTok(displayTokens.output) })
|
|
418
491
|
] })
|
|
419
492
|
] }) : null,
|
|
420
|
-
cache2 && cache2.hitRatio > 0 && isComfortable ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
493
|
+
cache2 && cache2.hitRatio > 0 && isComfortable && showChip("cache") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
421
494
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
422
495
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
423
496
|
"cache ",
|
|
@@ -425,21 +498,21 @@ function StatusBar({
|
|
|
425
498
|
"%"
|
|
426
499
|
] })
|
|
427
500
|
] }) : null,
|
|
428
|
-
cost && cost.total > 0 &&
|
|
501
|
+
cost && cost.total > 0 && showChip("cost") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
429
502
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
430
503
|
/* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
431
504
|
"$",
|
|
432
505
|
cost.total.toFixed(4)
|
|
433
506
|
] })
|
|
434
507
|
] }) : null,
|
|
435
|
-
queueCount > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
508
|
+
queueCount > 0 && showChip("queue") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
436
509
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
437
510
|
/* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
438
511
|
"\u231B queued: ",
|
|
439
512
|
queueCount
|
|
440
513
|
] })
|
|
441
514
|
] }) : null,
|
|
442
|
-
typeof processCount === "number" && processCount > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
515
|
+
typeof processCount === "number" && processCount > 0 && showChip("processes") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
443
516
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
444
517
|
/* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
445
518
|
"\u26A1 ",
|
|
@@ -448,11 +521,11 @@ function StatusBar({
|
|
|
448
521
|
processCount === 1 ? "" : "es"
|
|
449
522
|
] })
|
|
450
523
|
] }) : null,
|
|
451
|
-
hint ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
524
|
+
hint && showChip("hint") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
452
525
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
453
526
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: hint })
|
|
454
527
|
] }) : null,
|
|
455
|
-
indexState?.indexing ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
528
|
+
indexState?.indexing && showChip("index") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
456
529
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
457
530
|
/* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
458
531
|
"\u2699 indexing ",
|
|
@@ -460,11 +533,11 @@ function StatusBar({
|
|
|
460
533
|
"/",
|
|
461
534
|
indexState.totalFiles
|
|
462
535
|
] })
|
|
463
|
-
] }) : indexState?.circuit?.state === "open" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
536
|
+
] }) : indexState?.circuit?.state === "open" && showChip("index") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
464
537
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
465
538
|
/* @__PURE__ */ jsx(Text, { color: "red", children: "\u2699 index paused (/reindex)" })
|
|
466
539
|
] }) : null,
|
|
467
|
-
breakerCountdown ? (() => {
|
|
540
|
+
breakerCountdown && showChip("breaker") ? (() => {
|
|
468
541
|
const secs = Math.ceil(breakerCountdown.remainingMs / 1e3);
|
|
469
542
|
const ratio = breakerCountdown.totalMs > 0 ? breakerCountdown.remainingMs / breakerCountdown.totalMs : 0;
|
|
470
543
|
const c = secs > 20 ? "green" : secs > 10 ? "yellow" : "red";
|
|
@@ -480,11 +553,10 @@ function StatusBar({
|
|
|
480
553
|
})() : null
|
|
481
554
|
] })
|
|
482
555
|
) }),
|
|
483
|
-
hasSecondLine ? /* @__PURE__ */
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
/* @__PURE__ */ jsxs(
|
|
556
|
+
hasSecondLine ? /* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 2, children: renderChipLine(
|
|
557
|
+
[
|
|
558
|
+
yolo && showChip("yolo") ? /* @__PURE__ */ jsx(Text, { color: "red", bold: true, children: "\u26A0 YOLO" }) : null,
|
|
559
|
+
autonomy && autonomy !== "off" && showChip("autonomy") ? /* @__PURE__ */ jsxs(
|
|
488
560
|
Text,
|
|
489
561
|
{
|
|
490
562
|
color: autonomy === "eternal" ? "red" : autonomy === "auto" ? "yellow" : "cyan",
|
|
@@ -494,36 +566,21 @@ function StatusBar({
|
|
|
494
566
|
autonomy.toUpperCase()
|
|
495
567
|
]
|
|
496
568
|
}
|
|
497
|
-
)
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
yolo || autonomy && autonomy !== "off" ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
501
|
-
/* @__PURE__ */ jsx(EternalStageChip, { stage: eternalStage })
|
|
502
|
-
] }) : null,
|
|
503
|
-
elapsedMs !== void 0 && !hiddenSet.has("elapsed") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
504
|
-
yolo || autonomy && autonomy !== "off" || eternalStage ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
505
|
-
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
569
|
+
) : null,
|
|
570
|
+
eternalStage && showChip("eternal_stage") ? /* @__PURE__ */ jsx(EternalStageChip, { stage: eternalStage }) : null,
|
|
571
|
+
elapsedMs !== void 0 && showChip("elapsed") ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
506
572
|
"\u23F1 ",
|
|
507
573
|
fmtElapsed(elapsedMs)
|
|
508
|
-
] })
|
|
509
|
-
|
|
510
|
-
projectName ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
511
|
-
yolo || startedAt != null ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
512
|
-
/* @__PURE__ */ jsxs(Text, { color: "blue", children: [
|
|
574
|
+
] }) : null,
|
|
575
|
+
projectName && showChip("project") ? /* @__PURE__ */ jsxs(Text, { color: "blue", children: [
|
|
513
576
|
"\u{1F4C1} ",
|
|
514
|
-
projectName
|
|
515
|
-
] })
|
|
516
|
-
|
|
517
|
-
workingDir && !hiddenSet.has("working_dir") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
518
|
-
yolo || startedAt != null || projectName || goalSummary ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
519
|
-
/* @__PURE__ */ jsxs(Text, { color: "blue", children: [
|
|
577
|
+
truncateChip(projectName, 24)
|
|
578
|
+
] }) : null,
|
|
579
|
+
workingDir && showChip("working_dir") ? /* @__PURE__ */ jsxs(Text, { color: "blue", children: [
|
|
520
580
|
"\u{1F4C2} ",
|
|
521
|
-
workingDir
|
|
522
|
-
] })
|
|
523
|
-
|
|
524
|
-
goalSummary ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
525
|
-
yolo || startedAt != null || projectName || workingDir ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
526
|
-
/* @__PURE__ */ jsxs(
|
|
581
|
+
truncateChip(workingDir, 28)
|
|
582
|
+
] }) : null,
|
|
583
|
+
goalSummary && showChip("goal") ? /* @__PURE__ */ jsxs(
|
|
527
584
|
Text,
|
|
528
585
|
{
|
|
529
586
|
color: goalSummary.goalState === "active" ? "green" : goalSummary.goalState === "paused" ? "yellow" : goalSummary.goalState === "completed" ? "green" : "dim",
|
|
@@ -539,26 +596,17 @@ function StatusBar({
|
|
|
539
596
|
")"
|
|
540
597
|
]
|
|
541
598
|
}
|
|
542
|
-
)
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
yolo || autonomy && autonomy !== "off" || eternalStage || startedAt != null || projectName || workingDir || goalSummary ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
546
|
-
/* @__PURE__ */ jsx(Text, { color: "cyan", children: modeIcon(modeLabel) })
|
|
547
|
-
] }) : null,
|
|
548
|
-
hasAutoProceed ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
549
|
-
yolo || autonomy && autonomy !== "off" || eternalStage || startedAt != null || projectName || workingDir || goalSummary || modeLabel ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
550
|
-
/* @__PURE__ */ jsxs(Text, { color: autoProceedCountdown != null && autoProceedCountdown <= 5 ? "yellow" : "cyan", children: [
|
|
599
|
+
) : null,
|
|
600
|
+
modeLabel && showChip("mode") ? /* @__PURE__ */ jsx(Text, { color: "cyan", children: modeIcon(modeLabel) }) : null,
|
|
601
|
+
hasAutoProceed && showChip("auto_proceed") ? /* @__PURE__ */ jsxs(Text, { color: autoProceedCountdown != null && autoProceedCountdown <= 5 ? "yellow" : "cyan", children: [
|
|
551
602
|
"\u23F3 auto in ",
|
|
552
603
|
autoProceedCountdown,
|
|
553
604
|
"s"
|
|
554
|
-
] })
|
|
555
|
-
|
|
556
|
-
git && !hiddenSet.has("git") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
557
|
-
yolo || startedAt != null || projectName || workingDir ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
558
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
605
|
+
] }) : null,
|
|
606
|
+
git && showChip("git") ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
559
607
|
/* @__PURE__ */ jsxs(Text, { color: "magenta", children: [
|
|
560
608
|
"\u2387 ",
|
|
561
|
-
git.branch
|
|
609
|
+
truncateChip(git.branch, 24)
|
|
562
610
|
] }),
|
|
563
611
|
git.deleted > 0 ? /* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
564
612
|
" -",
|
|
@@ -568,52 +616,43 @@ function StatusBar({
|
|
|
568
616
|
" ?",
|
|
569
617
|
git.untracked
|
|
570
618
|
] }) : null
|
|
571
|
-
] })
|
|
572
|
-
|
|
573
|
-
sessionCount != null && sessionCount > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
574
|
-
yolo || startedAt != null || projectName || workingDir || git && !hiddenSet.has("git") ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
575
|
-
/* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
619
|
+
] }) : null,
|
|
620
|
+
sessionCount != null && sessionCount > 0 && showChip("sessions") ? /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
576
621
|
"\u29C9 ",
|
|
577
622
|
sessionCount,
|
|
578
623
|
" session",
|
|
579
624
|
sessionCount === 1 ? "" : "s"
|
|
580
|
-
] })
|
|
581
|
-
|
|
582
|
-
toolCount != null ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
583
|
-
yolo || startedAt != null || projectName || workingDir || git && !hiddenSet.has("git") || sessionCount ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
584
|
-
/* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
625
|
+
] }) : null,
|
|
626
|
+
toolCount != null && showChip("tools") ? /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
585
627
|
"\u{1F527} ",
|
|
586
628
|
toolCount,
|
|
587
629
|
" tool",
|
|
588
630
|
toolCount === 1 ? "" : "s"
|
|
589
|
-
] })
|
|
590
|
-
] }) : null,
|
|
591
|
-
tokenSavingMode ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
592
|
-
yolo || startedAt != null || projectName || workingDir || git && !hiddenSet.has("git") || sessionCount || toolCount ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
593
|
-
/* @__PURE__ */ jsx(Text, { color: "yellow", bold: true, children: "\u{1F4BE} save" })
|
|
594
|
-
] }) : null
|
|
595
|
-
] }) : /* @__PURE__ */ jsx(Box, { height: 1, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
|
|
596
|
-
hasThirdLine ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
597
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) && !hiddenSet.has("todos") ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
598
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "todos " }),
|
|
599
|
-
todos.inProgress > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
600
|
-
"\u231B",
|
|
601
|
-
todos.inProgress
|
|
602
631
|
] }) : null,
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
632
|
+
tokenSavingMode && showChip("token_saving") ? /* @__PURE__ */ jsx(Text, { color: "yellow", bold: true, children: "\u{1F4BE} save" }) : null
|
|
633
|
+
].filter((c) => c !== null),
|
|
634
|
+
termWidth - 6
|
|
635
|
+
) }) : /* @__PURE__ */ jsx(Box, { height: 1, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
|
|
636
|
+
hasThirdLine ? /* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 2, children: renderChipLine(
|
|
637
|
+
[
|
|
638
|
+
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) && showChip("todos") ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
639
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "todos " }),
|
|
640
|
+
todos.inProgress > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
641
|
+
"\u231B",
|
|
642
|
+
todos.inProgress
|
|
643
|
+
] }) : null,
|
|
644
|
+
todos.inProgress > 0 && (todos.pending > 0 || todos.completed > 0) ? " " : "",
|
|
645
|
+
todos.pending > 0 ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
646
|
+
"\u2610",
|
|
647
|
+
todos.pending
|
|
648
|
+
] }) : null,
|
|
649
|
+
todos.pending > 0 && todos.completed > 0 ? " " : "",
|
|
650
|
+
todos.completed > 0 ? /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
651
|
+
"\u2713",
|
|
652
|
+
todos.completed
|
|
653
|
+
] }) : null
|
|
607
654
|
] }) : null,
|
|
608
|
-
|
|
609
|
-
todos.completed > 0 ? /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
610
|
-
"\u2713",
|
|
611
|
-
todos.completed
|
|
612
|
-
] }) : null
|
|
613
|
-
] }) : null,
|
|
614
|
-
plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) && !hiddenSet.has("plan") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
615
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) && !hiddenSet.has("todos") ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
616
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
655
|
+
plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) && showChip("plan") ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
617
656
|
/* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u{1F4CB} " }),
|
|
618
657
|
plan.inProgress > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
619
658
|
"\u231B",
|
|
@@ -634,11 +673,8 @@ function StatusBar({
|
|
|
634
673
|
plan.scope,
|
|
635
674
|
"]"
|
|
636
675
|
] }) : null
|
|
637
|
-
] })
|
|
638
|
-
|
|
639
|
-
hasTaskActivity && !hiddenSet.has("tasks") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
640
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) && !hiddenSet.has("todos") || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) && !hiddenSet.has("plan") ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
641
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
676
|
+
] }) : null,
|
|
677
|
+
hasTaskActivity && showChip("tasks") ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
642
678
|
/* @__PURE__ */ jsx(Text, { color: "magenta", children: "\u26A1 " }),
|
|
643
679
|
tasks.inProgress > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
644
680
|
"\u231B",
|
|
@@ -669,11 +705,8 @@ function StatusBar({
|
|
|
669
705
|
tasks.scope,
|
|
670
706
|
"]"
|
|
671
707
|
] }) : null
|
|
672
|
-
] })
|
|
673
|
-
|
|
674
|
-
fleetHasActivity && !hiddenSet.has("fleet") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
675
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) && !hiddenSet.has("todos") || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) && !hiddenSet.has("plan") ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
676
|
-
fleet ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
708
|
+
] }) : null,
|
|
709
|
+
fleetHasActivity && showChip("fleet") ? fleet ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
677
710
|
/* @__PURE__ */ jsx(Text, { color: "blue", children: "\u{1F310} " }),
|
|
678
711
|
fleet.running > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
679
712
|
"\u25B6",
|
|
@@ -700,15 +733,9 @@ function StatusBar({
|
|
|
700
733
|
subagentCount,
|
|
701
734
|
" agent",
|
|
702
735
|
subagentCount === 1 ? "" : "s"
|
|
703
|
-
] })
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) && !hiddenSet.has("todos") || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) && !hiddenSet.has("plan") || hasTaskActivity && !hiddenSet.has("tasks") || fleetHasActivity && !hiddenSet.has("fleet") ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
707
|
-
/* @__PURE__ */ jsx(BrainChip, { brain })
|
|
708
|
-
] }) : null,
|
|
709
|
-
showDebugStream ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
710
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) && !hiddenSet.has("todos") || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) && !hiddenSet.has("plan") || hasTaskActivity && !hiddenSet.has("tasks") || fleetHasActivity && !hiddenSet.has("fleet") || showBrain ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
711
|
-
/* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
736
|
+
] }) : null,
|
|
737
|
+
showBrain ? /* @__PURE__ */ jsx(BrainChip, { brain }) : null,
|
|
738
|
+
showDebugStream ? /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
712
739
|
/* @__PURE__ */ jsx(Text, { bold: true, children: "\u{1F41B} stream" }),
|
|
713
740
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
714
741
|
" #",
|
|
@@ -728,31 +755,28 @@ function StatusBar({
|
|
|
728
755
|
" \xB7 ",
|
|
729
756
|
fmtDebugBytes(debugStreamStats.totalBytes)
|
|
730
757
|
] })
|
|
731
|
-
] })
|
|
732
|
-
|
|
733
|
-
showEnhance ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
734
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) && !hiddenSet.has("todos") || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) && !hiddenSet.has("plan") || hasTaskActivity && !hiddenSet.has("tasks") || fleetHasActivity && !hiddenSet.has("fleet") || showBrain || showDebugStream ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
735
|
-
/* @__PURE__ */ jsxs(Text, { color: enhanceCountdown > 15 ? "green" : enhanceCountdown > 5 ? "yellow" : "red", children: [
|
|
758
|
+
] }) : null,
|
|
759
|
+
showEnhance ? /* @__PURE__ */ jsxs(Text, { color: countdownColor(enhanceCountdown, 15, 5), children: [
|
|
736
760
|
"\u23F3 auto-send in ",
|
|
737
761
|
enhanceCountdown,
|
|
738
762
|
"s"
|
|
739
|
-
] })
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
mailbox &&
|
|
763
|
+
] }) : null,
|
|
764
|
+
hasNextStepsAutoSubmit && nextStepsAutoSubmitCountdown != null && showChip("next_steps") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
765
|
+
/* @__PURE__ */ jsxs(Text, { color: nextStepsColor, bold: true, children: [
|
|
766
|
+
"\u23F3 ",
|
|
767
|
+
nextStepsAutoSubmitCountdown,
|
|
768
|
+
"s"
|
|
769
|
+
] }),
|
|
770
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
771
|
+
" ",
|
|
772
|
+
nextStepsAutoSubmitLabel ? formatSuggestionLabel(nextStepsAutoSubmitLabel) : "",
|
|
773
|
+
" \xB7 \u21E5 edit"
|
|
774
|
+
] })
|
|
775
|
+
] }) : null
|
|
776
|
+
].filter((c) => c !== null),
|
|
777
|
+
termWidth - 6
|
|
778
|
+
) }) : /* @__PURE__ */ jsx(Box, { height: 1, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
|
|
779
|
+
mailbox && showMailbox ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
756
780
|
mailbox.unread > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", bold: true, children: [
|
|
757
781
|
"\u2709 ",
|
|
758
782
|
mailbox.unread,
|
|
@@ -786,37 +810,9 @@ function StatusBar({
|
|
|
786
810
|
mailbox.lastSubject.length > 40 ? `${mailbox.lastSubject.slice(0, 37)}\u2026` : mailbox.lastSubject
|
|
787
811
|
] })
|
|
788
812
|
] }) : null,
|
|
789
|
-
fleetAgents && fleetAgents.length > 0 ? fleetAgents.map((a, i) => (
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
793
|
-
" ",
|
|
794
|
-
/* @__PURE__ */ jsx(Text, { color: a.color, bold: true, children: a.label }),
|
|
795
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }),
|
|
796
|
-
/* @__PURE__ */ jsx(Text, { dimColor: !a.running, ...a.running ? { color: "yellow" } : {}, children: a.running ? "\u25B6" : "\xB7" }),
|
|
797
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }),
|
|
798
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: fmtElapsed(a.elapsedMs) }),
|
|
799
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \xB7 " }),
|
|
800
|
-
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
801
|
-
a.toolCalls,
|
|
802
|
-
"t"
|
|
803
|
-
] }),
|
|
804
|
-
a.tool ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
805
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \xB7 " }),
|
|
806
|
-
/* @__PURE__ */ jsx(Text, { color: "cyan", children: a.tool })
|
|
807
|
-
] }) : null,
|
|
808
|
-
a.extensions && a.extensions > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
809
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \xB7 " }),
|
|
810
|
-
/* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
811
|
-
"\u26A1\xD7",
|
|
812
|
-
a.extensions
|
|
813
|
-
] })
|
|
814
|
-
] }) : null
|
|
815
|
-
] }, i)
|
|
816
|
-
)) : null
|
|
817
|
-
] }) : fleetAgents && fleetAgents.length > 0 ? /* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 2, children: fleetAgents.map((a, i) => (
|
|
818
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: agent list is stable per render
|
|
819
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
813
|
+
fleetAgents && fleetAgents.length > 0 && showChip("fleet_agents") ? fleetAgents.map((a, i) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
814
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
815
|
+
" ",
|
|
820
816
|
/* @__PURE__ */ jsx(Text, { color: a.color, bold: true, children: a.label }),
|
|
821
817
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }),
|
|
822
818
|
/* @__PURE__ */ jsx(Text, { dimColor: !a.running, ...a.running ? { color: "yellow" } : {}, children: a.running ? "\u25B6" : "\xB7" }),
|
|
@@ -838,8 +834,30 @@ function StatusBar({
|
|
|
838
834
|
a.extensions
|
|
839
835
|
] })
|
|
840
836
|
] }) : null
|
|
841
|
-
] }, i)
|
|
842
|
-
|
|
837
|
+
] }, i)) : null
|
|
838
|
+
] }) : fleetAgents && fleetAgents.length > 0 && showChip("fleet_agents") ? /* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 2, children: fleetAgents.map((a, i) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
839
|
+
/* @__PURE__ */ jsx(Text, { color: a.color, bold: true, children: a.label }),
|
|
840
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }),
|
|
841
|
+
/* @__PURE__ */ jsx(Text, { dimColor: !a.running, ...a.running ? { color: "yellow" } : {}, children: a.running ? "\u25B6" : "\xB7" }),
|
|
842
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }),
|
|
843
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: fmtElapsed(a.elapsedMs) }),
|
|
844
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \xB7 " }),
|
|
845
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
846
|
+
a.toolCalls,
|
|
847
|
+
"t"
|
|
848
|
+
] }),
|
|
849
|
+
a.tool ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
850
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \xB7 " }),
|
|
851
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: a.tool })
|
|
852
|
+
] }) : null,
|
|
853
|
+
a.extensions && a.extensions > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
854
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \xB7 " }),
|
|
855
|
+
/* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
856
|
+
"\u26A1\xD7",
|
|
857
|
+
a.extensions
|
|
858
|
+
] })
|
|
859
|
+
] }) : null
|
|
860
|
+
] }, i)) }) : /* @__PURE__ */ jsx(Box, { height: 1, children: /* @__PURE__ */ jsx(Text, { children: " " }) })
|
|
843
861
|
]
|
|
844
862
|
}
|
|
845
863
|
);
|
|
@@ -981,10 +999,7 @@ var WAVE_COLORS = [
|
|
|
981
999
|
// flamingo
|
|
982
1000
|
];
|
|
983
1001
|
function WaveText({ text, phase }) {
|
|
984
|
-
return /* @__PURE__ */ jsx(Text, { bold: true, children: Array.from(text).map((ch, i) => (
|
|
985
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: glyph order is positional and re-rendered each tick
|
|
986
|
-
/* @__PURE__ */ jsx(Text, { color: WAVE_COLORS[(i + phase) % WAVE_COLORS.length] ?? "#ffffff", children: ch }, i)
|
|
987
|
-
)) });
|
|
1002
|
+
return /* @__PURE__ */ jsx(Text, { bold: true, children: Array.from(text).map((ch, i) => /* @__PURE__ */ jsx(Text, { color: WAVE_COLORS[(i + phase) % WAVE_COLORS.length] ?? "#ffffff", children: ch }, i)) });
|
|
988
1003
|
}
|
|
989
1004
|
var FILLED = "\u2588";
|
|
990
1005
|
var EMPTY = "\u2591";
|
|
@@ -1183,14 +1198,11 @@ function FleetMonitor({
|
|
|
1183
1198
|
/* @__PURE__ */ jsx(Text, { bold: true, color: VERDICT_COLOR[collabSession.overallVerdict] ?? "white", children: collabSession.overallVerdict })
|
|
1184
1199
|
] }) : null
|
|
1185
1200
|
] }),
|
|
1186
|
-
collabSession.timeline.length > 0 ? /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: 0, children: collabSession.timeline.slice(0, 6).map((ev, i) => (
|
|
1187
|
-
|
|
1188
|
-
/* @__PURE__ */
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ev.text })
|
|
1192
|
-
] }, i)
|
|
1193
|
-
)) }) : null
|
|
1201
|
+
collabSession.timeline.length > 0 ? /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: 0, children: collabSession.timeline.slice(0, 6).map((ev, i) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
1202
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: `${fmtElapsed(Math.max(0, nowTick - ev.at))} ago`.padEnd(10) }),
|
|
1203
|
+
/* @__PURE__ */ jsx(Text, { ...ev.color ? { color: ev.color } : {}, children: ev.icon }),
|
|
1204
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ev.text })
|
|
1205
|
+
] }, i)) }) : null
|
|
1194
1206
|
] }) : null,
|
|
1195
1207
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
1196
1208
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "concurrency" }),
|
|
@@ -1228,7 +1240,7 @@ function FleetMonitor({
|
|
|
1228
1240
|
const s2 = STATUS[e.status];
|
|
1229
1241
|
const elapsed = e.status === "running" ? fmtElapsed(Math.max(0, nowTick - e.startedAt)) : fmtElapsed(Math.max(0, nowTick - e.lastEventAt)) + " ago";
|
|
1230
1242
|
const model = fmtModelLabel(e.provider, e.model) || "\u2014";
|
|
1231
|
-
const ltCtx = e.ctxPct !== void 0 ? `L${e.iterations} ${e.toolCalls}t ${Math.round(e.ctxPct * 100)}%` : `L${e.iterations} ${e.toolCalls}t`;
|
|
1243
|
+
const ltCtx = e.ctxPct !== void 0 ? `L${e.iterations} ${e.toolCalls}t ${Math.min(100, Math.max(0, Math.round(e.ctxPct * 100)))}%` : `L${e.iterations} ${e.toolCalls}t`;
|
|
1232
1244
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
1233
1245
|
/* @__PURE__ */ jsx(Text, { color: s2.color, children: s2.icon }),
|
|
1234
1246
|
/* @__PURE__ */ jsx(Text, { children: e.name.padEnd(14).slice(0, 14) }),
|
|
@@ -1248,14 +1260,11 @@ function FleetMonitor({
|
|
|
1248
1260
|
] }) : null,
|
|
1249
1261
|
timeline.length > 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
1250
1262
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "timeline" }),
|
|
1251
|
-
timeline.map((ev, i) => (
|
|
1252
|
-
|
|
1253
|
-
/* @__PURE__ */
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ev.text })
|
|
1257
|
-
] }, i)
|
|
1258
|
-
))
|
|
1263
|
+
timeline.map((ev, i) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
1264
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: `${fmtElapsed(Math.max(0, nowTick - ev.at))} ago`.padEnd(10) }),
|
|
1265
|
+
/* @__PURE__ */ jsx(Text, { color: ev.color, children: ev.icon }),
|
|
1266
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ev.text })
|
|
1267
|
+
] }, i))
|
|
1259
1268
|
] }) : null
|
|
1260
1269
|
] });
|
|
1261
1270
|
}
|
|
@@ -1421,6 +1430,10 @@ function ContextBar({
|
|
|
1421
1430
|
tokenText
|
|
1422
1431
|
] });
|
|
1423
1432
|
}
|
|
1433
|
+
function pctTextFromRatio(pct) {
|
|
1434
|
+
if (typeof pct !== "number" || !Number.isFinite(pct)) return "0%";
|
|
1435
|
+
return `${Math.min(100, Math.max(0, Math.round(pct * 100)))}%`;
|
|
1436
|
+
}
|
|
1424
1437
|
function AgentRow({
|
|
1425
1438
|
entry,
|
|
1426
1439
|
now,
|
|
@@ -1570,10 +1583,7 @@ function AgentDetail({
|
|
|
1570
1583
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "recent" }),
|
|
1571
1584
|
entry.recentTools.slice(-4).map((tool, i) => {
|
|
1572
1585
|
const visual = getToolVisual(tool.name);
|
|
1573
|
-
return (
|
|
1574
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: recent tool entries do not carry stable ids.
|
|
1575
|
-
/* @__PURE__ */ jsx(Text, { color: tool.ok === false ? "red" : visual.color, children: `\u2039${visual.glyph} ${formatRecentToolChip(tool)}\u203A` }, `${tool.name}-${tool.at}-${i}`)
|
|
1576
|
-
);
|
|
1586
|
+
return /* @__PURE__ */ jsx(Text, { color: tool.ok === false ? "red" : visual.color, children: `\u2039${visual.glyph} ${formatRecentToolChip(tool)}\u203A` }, `${tool.name}-${tool.at}-${i}`);
|
|
1577
1587
|
})
|
|
1578
1588
|
] }) : null,
|
|
1579
1589
|
entry.status === "running" && streamTail ? /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
@@ -1678,14 +1688,13 @@ function AgentsMonitor({
|
|
|
1678
1688
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "pulse" }),
|
|
1679
1689
|
/* @__PURE__ */ jsxs(Text, { color: pressure >= 0.9 ? "red" : pressure >= 0.75 ? "yellow" : "green", children: [
|
|
1680
1690
|
"max ctx ",
|
|
1681
|
-
|
|
1682
|
-
"%"
|
|
1691
|
+
pctTextFromRatio(pressure)
|
|
1683
1692
|
] }),
|
|
1684
1693
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 hot" }),
|
|
1685
1694
|
hotAgent ? /* @__PURE__ */ jsxs(Text, { color: riskMeta(agentRisk(hotAgent)).color, children: [
|
|
1686
1695
|
hotAgent.name,
|
|
1687
1696
|
" ",
|
|
1688
|
-
hotAgent.ctxPct !== void 0 ?
|
|
1697
|
+
hotAgent.ctxPct !== void 0 ? pctTextFromRatio(hotAgent.ctxPct) : ""
|
|
1689
1698
|
] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "none" }),
|
|
1690
1699
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 throughput" }),
|
|
1691
1700
|
/* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
@@ -1853,10 +1862,7 @@ function BrainDecisionPrompt({
|
|
|
1853
1862
|
/* @__PURE__ */ jsx(Text, { color: "white", children: question }),
|
|
1854
1863
|
ctx.length > 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
1855
1864
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Context:" }),
|
|
1856
|
-
ctx.map((line, index) => (
|
|
1857
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: context lines are static for this prompt render
|
|
1858
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: line }, index)
|
|
1859
|
-
))
|
|
1865
|
+
ctx.map((line, index) => /* @__PURE__ */ jsx(Text, { dimColor: true, children: line }, index))
|
|
1860
1866
|
] }) : null,
|
|
1861
1867
|
options.length > 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
1862
1868
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Options:" }),
|
|
@@ -3507,10 +3513,7 @@ function MarkdownView({
|
|
|
3507
3513
|
/[\u2500-\u257F]/.test(qContent) ? (
|
|
3508
3514
|
// Box-drawing characters inside blockquotes also need transparent
|
|
3509
3515
|
// background to avoid inheriting the message panel background.
|
|
3510
|
-
/* @__PURE__ */ jsx(Box, { flexDirection: "row", backgroundColor: "transparent", children: [...qContent].slice(0, (contentWidth ?? termWidth) - 2).map((ch, ci) => (
|
|
3511
|
-
/* biome-ignore lint/suspicious/noArrayIndexKey: characters are not reorderable */
|
|
3512
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ch }, ci)
|
|
3513
|
-
)) })
|
|
3516
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "row", backgroundColor: "transparent", children: [...qContent].slice(0, (contentWidth ?? termWidth) - 2).map((ch, ci) => /* @__PURE__ */ jsx(Text, { dimColor: true, children: ch }, ci)) })
|
|
3514
3517
|
) : /* @__PURE__ */ jsx(InlineLine, { tokens: parseInline(qContent), dim: true })
|
|
3515
3518
|
] }, `q${key++}`)
|
|
3516
3519
|
);
|
|
@@ -3540,10 +3543,7 @@ function MarkdownView({
|
|
|
3540
3543
|
const maxW = contentWidth ?? termWidth;
|
|
3541
3544
|
const chars = [...line].slice(0, maxW);
|
|
3542
3545
|
rows.push(
|
|
3543
|
-
/* @__PURE__ */ jsx(Box, { width: maxW, backgroundColor: "transparent", flexDirection: "row", children: chars.map((ch, ci) => (
|
|
3544
|
-
/* biome-ignore lint/suspicious/noArrayIndexKey: characters are not reorderable */
|
|
3545
|
-
/* @__PURE__ */ jsx(Text, { children: ch }, ci)
|
|
3546
|
-
)) }, `bx${key++}`)
|
|
3546
|
+
/* @__PURE__ */ jsx(Box, { width: maxW, backgroundColor: "transparent", flexDirection: "row", children: chars.map((ch, ci) => /* @__PURE__ */ jsx(Text, { children: ch }, ci)) }, `bx${key++}`)
|
|
3547
3547
|
);
|
|
3548
3548
|
continue;
|
|
3549
3549
|
}
|
|
@@ -3633,6 +3633,19 @@ function formatMatchHit(hit) {
|
|
|
3633
3633
|
return void 0;
|
|
3634
3634
|
}
|
|
3635
3635
|
var ARG_BUDGET = 60;
|
|
3636
|
+
function stringArrayOf(v) {
|
|
3637
|
+
return Array.isArray(v) ? v.filter((item) => typeof item === "string") : void 0;
|
|
3638
|
+
}
|
|
3639
|
+
function fileScopeSummary(files, fallback) {
|
|
3640
|
+
const list = stringArrayOf(files);
|
|
3641
|
+
if (list && list.length > 0) {
|
|
3642
|
+
const first = list[0] ?? "";
|
|
3643
|
+
const more = list.length > 1 ? ` (+${list.length - 1})` : "";
|
|
3644
|
+
return first ? `${shortenPath(first, 42)}${more}` : `${list.length} files`;
|
|
3645
|
+
}
|
|
3646
|
+
const scalar = typeof files === "string" ? files : fallback;
|
|
3647
|
+
return scalar ? shortenPath(scalar, 44) : "";
|
|
3648
|
+
}
|
|
3636
3649
|
function formatToolArgs(toolName, input) {
|
|
3637
3650
|
if (!input || typeof input !== "object") return "";
|
|
3638
3651
|
const obj = input;
|
|
@@ -3641,13 +3654,18 @@ function formatToolArgs(toolName, input) {
|
|
|
3641
3654
|
case "write":
|
|
3642
3655
|
case "edit":
|
|
3643
3656
|
case "patch":
|
|
3644
|
-
case "document":
|
|
3645
3657
|
case "list_dir":
|
|
3646
3658
|
case "ls":
|
|
3647
3659
|
case "tree": {
|
|
3648
3660
|
const p = stringOf(obj["path"]) ?? stringOf(obj["file"]);
|
|
3649
3661
|
return p ? shortenPath(p, ARG_BUDGET) : "";
|
|
3650
3662
|
}
|
|
3663
|
+
case "document": {
|
|
3664
|
+
const target = stringOf(obj["target"]) ?? "all";
|
|
3665
|
+
const scope = fileScopeSummary(obj["files"], stringOf(obj["path"]));
|
|
3666
|
+
const style = stringOf(obj["style"]);
|
|
3667
|
+
return [target, scope, style].filter(Boolean).join(" \xB7 ");
|
|
3668
|
+
}
|
|
3651
3669
|
case "grep":
|
|
3652
3670
|
case "search":
|
|
3653
3671
|
case "replace": {
|
|
@@ -3663,12 +3681,19 @@ function formatToolArgs(toolName, input) {
|
|
|
3663
3681
|
}
|
|
3664
3682
|
case "bash":
|
|
3665
3683
|
case "shell":
|
|
3666
|
-
case "exec":
|
|
3667
3684
|
case "install":
|
|
3668
3685
|
case "git": {
|
|
3669
3686
|
const cmd = stringOf(obj["command"]) ?? stringOf(obj["args"]);
|
|
3670
3687
|
return cmd ? truncMid(cmd, ARG_BUDGET) : "";
|
|
3671
3688
|
}
|
|
3689
|
+
case "exec": {
|
|
3690
|
+
const command = stringOf(obj["command"]);
|
|
3691
|
+
const args = stringArrayOf(obj["args"]) ?? [];
|
|
3692
|
+
const cwd = stringOf(obj["cwd"]);
|
|
3693
|
+
const cmd = [command, ...args].filter(Boolean).join(" ");
|
|
3694
|
+
const head = cmd ? truncMid(cmd, cwd ? 44 : ARG_BUDGET) : "";
|
|
3695
|
+
return cwd ? `${head} in ${shortenPath(cwd, 14)}` : head;
|
|
3696
|
+
}
|
|
3672
3697
|
case "diff": {
|
|
3673
3698
|
const files = Array.isArray(obj["files"]) ? obj["files"] : void 0;
|
|
3674
3699
|
if (files && files.length > 0) {
|
|
@@ -3690,6 +3715,19 @@ function formatToolArgs(toolName, input) {
|
|
|
3690
3715
|
if (Array.isArray(list)) return `${list.length} item${list.length === 1 ? "" : "s"}`;
|
|
3691
3716
|
return "";
|
|
3692
3717
|
}
|
|
3718
|
+
case "plan": {
|
|
3719
|
+
const action = stringOf(obj["action"]) ?? "show";
|
|
3720
|
+
const target = stringOf(obj["target"]) ?? stringOf(obj["title"]) ?? stringOf(obj["template"]) ?? "";
|
|
3721
|
+
const scope = stringOf(obj["scope"]);
|
|
3722
|
+
return [action, target ? truncMid(target, 34) : "", scope].filter(Boolean).join(" \xB7 ");
|
|
3723
|
+
}
|
|
3724
|
+
case "task": {
|
|
3725
|
+
const action = stringOf(obj["action"]) ?? "show";
|
|
3726
|
+
const task = obj["task"] && typeof obj["task"] === "object" ? obj["task"] : void 0;
|
|
3727
|
+
const target = stringOf(obj["target"]) ?? stringOf(obj["id"]) ?? stringOf(task?.["title"]) ?? (Array.isArray(obj["tasks"]) ? `${obj["tasks"].length} tasks` : "");
|
|
3728
|
+
const status = stringOf(obj["status"]);
|
|
3729
|
+
return [action, target ? truncMid(target, 32) : "", status].filter(Boolean).join(" \xB7 ");
|
|
3730
|
+
}
|
|
3693
3731
|
case "lint":
|
|
3694
3732
|
case "format":
|
|
3695
3733
|
case "typecheck":
|
|
@@ -3717,19 +3755,79 @@ function formatToolArgs(toolName, input) {
|
|
|
3717
3755
|
if (tmpl && name) return `${tmpl} \u2192 ${truncMid(name, ARG_BUDGET - tmpl.length - 4)}`;
|
|
3718
3756
|
return name ?? tmpl ?? "";
|
|
3719
3757
|
}
|
|
3720
|
-
case "remember":
|
|
3721
|
-
|
|
3758
|
+
case "remember": {
|
|
3759
|
+
const scope = stringOf(obj["scope"]);
|
|
3760
|
+
const type = stringOf(obj["type"]);
|
|
3761
|
+
const text = stringOf(obj["text"]);
|
|
3762
|
+
return [scope, type, text ? truncMid(text, 34) : ""].filter(Boolean).join(" \xB7 ");
|
|
3763
|
+
}
|
|
3764
|
+
case "forget": {
|
|
3765
|
+
const query = stringOf(obj["query"]);
|
|
3766
|
+
const scope = stringOf(obj["scope"]);
|
|
3767
|
+
return [query ? `"${truncMid(query, 36)}"` : "", scope].filter(Boolean).join(" \xB7 ");
|
|
3768
|
+
}
|
|
3769
|
+
case "search_memory":
|
|
3770
|
+
case "find_related_memories": {
|
|
3771
|
+
const query = stringOf(obj["query"]) ?? stringOf(obj["text"]);
|
|
3772
|
+
const scope = stringOf(obj["scope"]);
|
|
3773
|
+
return [query ? `"${truncMid(query, 36)}"` : "", scope].filter(Boolean).join(" \xB7 ");
|
|
3774
|
+
}
|
|
3722
3775
|
case "memory": {
|
|
3723
3776
|
const key = stringOf(obj["key"]) ?? stringOf(obj["name"]);
|
|
3724
3777
|
return key ? truncMid(key, ARG_BUDGET) : "";
|
|
3725
3778
|
}
|
|
3726
3779
|
case "mode": {
|
|
3780
|
+
const action = stringOf(obj["action"]);
|
|
3727
3781
|
const m = stringOf(obj["mode"]) ?? stringOf(obj["name"]);
|
|
3728
|
-
return m
|
|
3782
|
+
return [action, m].filter(Boolean).join(" \xB7 ");
|
|
3729
3783
|
}
|
|
3730
3784
|
case "logs": {
|
|
3731
3785
|
const target = stringOf(obj["target"]) ?? stringOf(obj["service"]) ?? stringOf(obj["path"]);
|
|
3732
|
-
|
|
3786
|
+
const filter = stringOf(obj["filter"]);
|
|
3787
|
+
const since = stringOf(obj["since"]);
|
|
3788
|
+
const lines = typeof obj["lines"] === "number" ? `${obj["lines"]} lines` : "";
|
|
3789
|
+
return [target ? shortenPath(target, 34) : "", filter ? `/${truncMid(filter, 16)}/` : "", since, lines].filter(Boolean).join(" \xB7 ");
|
|
3790
|
+
}
|
|
3791
|
+
case "tool_help": {
|
|
3792
|
+
const tool = stringOf(obj["tool"]) ?? "all";
|
|
3793
|
+
const format = stringOf(obj["format"]);
|
|
3794
|
+
return [tool, format].filter(Boolean).join(" \xB7 ");
|
|
3795
|
+
}
|
|
3796
|
+
case "tool_search": {
|
|
3797
|
+
const query = stringOf(obj["query"]);
|
|
3798
|
+
const tags = stringArrayOf(obj["tags"]);
|
|
3799
|
+
const filters = [
|
|
3800
|
+
query ? `"${truncMid(query, 28)}"` : "",
|
|
3801
|
+
tags && tags.length > 0 ? tags.join(",") : "",
|
|
3802
|
+
stringOf(obj["permission"]),
|
|
3803
|
+
typeof obj["mutating"] === "boolean" ? obj["mutating"] ? "mutating" : "read-only" : ""
|
|
3804
|
+
].filter(Boolean);
|
|
3805
|
+
return filters.join(" \xB7 ");
|
|
3806
|
+
}
|
|
3807
|
+
case "tool_use": {
|
|
3808
|
+
const tool = stringOf(obj["tool"]);
|
|
3809
|
+
return tool ? `call ${tool}` : "";
|
|
3810
|
+
}
|
|
3811
|
+
case "batch_tool_use": {
|
|
3812
|
+
const calls = Array.isArray(obj["calls"]) ? obj["calls"] : [];
|
|
3813
|
+
const mode = obj["parallel"] === false ? "sequential" : "parallel";
|
|
3814
|
+
return `${calls.length} call${calls.length === 1 ? "" : "s"} \xB7 ${mode}`;
|
|
3815
|
+
}
|
|
3816
|
+
case "codebase-index": {
|
|
3817
|
+
const langs = stringArrayOf(obj["langs"]);
|
|
3818
|
+
const force = obj["force"] === true ? "force" : "";
|
|
3819
|
+
return [force, langs && langs.length > 0 ? langs.join(",") : "incremental"].filter(Boolean).join(" \xB7 ");
|
|
3820
|
+
}
|
|
3821
|
+
case "codebase-search": {
|
|
3822
|
+
const query = stringOf(obj["query"]);
|
|
3823
|
+
const filters = [stringOf(obj["kind"]), stringOf(obj["lang"]), stringOf(obj["file"]) ? `in ${shortenPath(String(obj["file"]), 24)}` : ""].filter(Boolean).join(" \xB7 ");
|
|
3824
|
+
return [query ? `"${truncMid(query, 30)}"` : "", filters].filter(Boolean).join(" \xB7 ");
|
|
3825
|
+
}
|
|
3826
|
+
case "codebase-stats":
|
|
3827
|
+
return "index health";
|
|
3828
|
+
case "set_working_dir": {
|
|
3829
|
+
const p = stringOf(obj["path"]);
|
|
3830
|
+
return p ? shortenPath(p, ARG_BUDGET) : "current";
|
|
3733
3831
|
}
|
|
3734
3832
|
}
|
|
3735
3833
|
for (const key of ["path", "file", "url", "name", "query", "pattern", "command"]) {
|
|
@@ -4102,6 +4200,716 @@ function formatToolOutput(toolName, output, ok, _outputBytes, outputLines) {
|
|
|
4102
4200
|
const collapsed = text.replace(/\s+/g, " ").trim();
|
|
4103
4201
|
return [truncMid(collapsed, GENERIC_BUDGET)];
|
|
4104
4202
|
}
|
|
4203
|
+
var VISUAL_MAX_LINES = 7;
|
|
4204
|
+
var VISUAL_TEXT_BUDGET = 92;
|
|
4205
|
+
function formatToolVisualOutput(toolName, output, ok, input) {
|
|
4206
|
+
if (!output) return void 0;
|
|
4207
|
+
const text = output.trim();
|
|
4208
|
+
if (!text) return void 0;
|
|
4209
|
+
if (toolName === "read") return visualRead(text);
|
|
4210
|
+
if (toolName === "grep" || toolName === "search") return visualSearch(toolName, text);
|
|
4211
|
+
if (toolName === "glob") return visualPathList(toolName, text);
|
|
4212
|
+
if (toolName === "tree") return visualTree(text);
|
|
4213
|
+
if (toolName === "bash" || toolName === "shell" || toolName === "git" || toolName === "exec" || toolName === "install") {
|
|
4214
|
+
return visualCommand(toolName, text, ok);
|
|
4215
|
+
}
|
|
4216
|
+
if (toolName === "test" || toolName === "lint" || toolName === "typecheck" || toolName === "format") {
|
|
4217
|
+
return visualVerifier(toolName, text, ok);
|
|
4218
|
+
}
|
|
4219
|
+
if (toolName === "fetch" || toolName === "webfetch" || toolName === "web_fetch") {
|
|
4220
|
+
return visualFetch(text);
|
|
4221
|
+
}
|
|
4222
|
+
if (toolName === "json") return visualJson(text);
|
|
4223
|
+
if (toolName === "outdated") return visualOutdated(text);
|
|
4224
|
+
if (toolName === "audit") return visualAudit(text);
|
|
4225
|
+
if (toolName === "scaffold") return visualScaffold(text);
|
|
4226
|
+
if (toolName === "todo") return visualTodo(text);
|
|
4227
|
+
if (toolName === "task" || toolName === "plan") return visualWorkBoard(toolName, text, ok);
|
|
4228
|
+
if (toolName === "remember" || toolName === "forget" || toolName === "search_memory" || toolName === "find_related_memories") {
|
|
4229
|
+
return visualMemory(toolName, text, ok);
|
|
4230
|
+
}
|
|
4231
|
+
if (toolName === "logs") return visualLogs(text);
|
|
4232
|
+
if (toolName === "document") return visualDocument(text);
|
|
4233
|
+
if (toolName === "tool_help" || toolName === "tool_search") return visualToolCatalog(toolName, text);
|
|
4234
|
+
if (toolName === "tool_use" || toolName === "batch_tool_use") return visualMetaExecution(toolName, text, ok);
|
|
4235
|
+
if (toolName === "codebase-index" || toolName === "codebase-search" || toolName === "codebase-stats") {
|
|
4236
|
+
return visualCodebase(toolName, text, ok);
|
|
4237
|
+
}
|
|
4238
|
+
if (toolName === "set_working_dir") return visualWorkingDir(text, ok);
|
|
4239
|
+
if (toolName === "mode") return visualMode(text, ok);
|
|
4240
|
+
return void 0;
|
|
4241
|
+
}
|
|
4242
|
+
function ToolOutputLines({ lines, hasFollowingBlock }) {
|
|
4243
|
+
return /* @__PURE__ */ jsx(Fragment, { children: lines.map((line, i) => {
|
|
4244
|
+
const branch = i === lines.length - 1 && !hasFollowingBlock ? " \u2514\u2500 " : " \u251C\u2500 ";
|
|
4245
|
+
const color = colorForVisualKind(line.kind);
|
|
4246
|
+
return /* @__PURE__ */ jsxs(Text, { children: [
|
|
4247
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: branch }),
|
|
4248
|
+
line.marker ? /* @__PURE__ */ jsx(Text, { color, bold: true, children: line.marker }) : null,
|
|
4249
|
+
line.path ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4250
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: shortenPath(line.path, 56) }),
|
|
4251
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " })
|
|
4252
|
+
] }) : null,
|
|
4253
|
+
line.lineNo ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4254
|
+
/* @__PURE__ */ jsx(Text, { color: "yellow", children: String(line.lineNo).padStart(4, " ") }),
|
|
4255
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \u2502 " })
|
|
4256
|
+
] }) : null,
|
|
4257
|
+
/* @__PURE__ */ jsx(Text, { color, dimColor: line.kind === "meta" || line.kind === "stdout", children: truncMid(line.text, VISUAL_TEXT_BUDGET) })
|
|
4258
|
+
] }, `${line.kind}-${i}`);
|
|
4259
|
+
}) });
|
|
4260
|
+
}
|
|
4261
|
+
function colorForVisualKind(kind) {
|
|
4262
|
+
switch (kind) {
|
|
4263
|
+
case "ok":
|
|
4264
|
+
return "green";
|
|
4265
|
+
case "warn":
|
|
4266
|
+
return "yellow";
|
|
4267
|
+
case "error":
|
|
4268
|
+
case "stderr":
|
|
4269
|
+
return "red";
|
|
4270
|
+
case "path":
|
|
4271
|
+
case "match":
|
|
4272
|
+
return "cyan";
|
|
4273
|
+
case "code":
|
|
4274
|
+
return "white";
|
|
4275
|
+
case "stdout":
|
|
4276
|
+
case "meta":
|
|
4277
|
+
return void 0;
|
|
4278
|
+
}
|
|
4279
|
+
}
|
|
4280
|
+
function visualRead(text) {
|
|
4281
|
+
const lines = bodyLines(text);
|
|
4282
|
+
const numbered = lines.map((line) => line.match(/^\s*(\d+)→(.*)$/)).filter((match) => Boolean(match?.[1]));
|
|
4283
|
+
if (numbered.length === 0) {
|
|
4284
|
+
const first = firstNonEmpty(lines.join("\n"));
|
|
4285
|
+
return first ? [{ kind: "meta", text: first }] : void 0;
|
|
4286
|
+
}
|
|
4287
|
+
const rows = numbered.slice(0, 5).map((match) => ({
|
|
4288
|
+
kind: "code",
|
|
4289
|
+
lineNo: match[1],
|
|
4290
|
+
text: match[2] ?? ""
|
|
4291
|
+
}));
|
|
4292
|
+
if (numbered.length > rows.length) {
|
|
4293
|
+
rows.push({ kind: "meta", text: `${numbered.length - rows.length} more read line(s)` });
|
|
4294
|
+
}
|
|
4295
|
+
return rows;
|
|
4296
|
+
}
|
|
4297
|
+
function visualSearch(toolName, text) {
|
|
4298
|
+
const json = tryParseJson(text);
|
|
4299
|
+
if (json && typeof json === "object") {
|
|
4300
|
+
const obj = json;
|
|
4301
|
+
const matches = Array.isArray(obj["matches"]) ? obj["matches"] : Array.isArray(obj["results"]) ? obj["results"] : [];
|
|
4302
|
+
return visualSearchMatches(matches, numOf(obj["count"]) ?? matches.length);
|
|
4303
|
+
}
|
|
4304
|
+
const lines = bodyLines(text);
|
|
4305
|
+
if (lines.length === 0 || lines[0] === "(no matches)") return void 0;
|
|
4306
|
+
const rows = [];
|
|
4307
|
+
let currentPath;
|
|
4308
|
+
let consumed = 0;
|
|
4309
|
+
for (const line of lines) {
|
|
4310
|
+
if (consumed >= VISUAL_MAX_LINES) break;
|
|
4311
|
+
const fileHeader = line.match(/^(.+?) \((\d+) match\(es\), showing \d+\)$/);
|
|
4312
|
+
if (fileHeader?.[1]) {
|
|
4313
|
+
currentPath = fileHeader[1];
|
|
4314
|
+
rows.push({ kind: "path", path: currentPath, text: `${fileHeader[2] ?? "?"} match(es)` });
|
|
4315
|
+
consumed++;
|
|
4316
|
+
continue;
|
|
4317
|
+
}
|
|
4318
|
+
const direct = line.match(/^(.+?):(\d+):(.*)$/);
|
|
4319
|
+
const grouped = line.match(/^(\d+):(.*)$/);
|
|
4320
|
+
if (direct?.[1] && direct[2]) {
|
|
4321
|
+
rows.push({ kind: "match", path: direct[1], lineNo: direct[2], text: direct[3] ?? "" });
|
|
4322
|
+
consumed++;
|
|
4323
|
+
} else if (grouped?.[1]) {
|
|
4324
|
+
rows.push({ kind: "match", path: currentPath, lineNo: grouped[1], text: grouped[2] ?? "" });
|
|
4325
|
+
consumed++;
|
|
4326
|
+
} else if (line.trim() && !line.startsWith(`${toolName}:`)) {
|
|
4327
|
+
rows.push({ kind: "meta", text: line.trim() });
|
|
4328
|
+
consumed++;
|
|
4329
|
+
}
|
|
4330
|
+
}
|
|
4331
|
+
if (lines.length > consumed) rows.push({ kind: "meta", text: `${lines.length - consumed} more result line(s)` });
|
|
4332
|
+
return rows.length > 0 ? rows : void 0;
|
|
4333
|
+
}
|
|
4334
|
+
function visualSearchMatches(matches, count) {
|
|
4335
|
+
if (count === 0) return [{ kind: "ok", marker: "ok ", text: "no matches" }];
|
|
4336
|
+
const rows = [];
|
|
4337
|
+
for (const match of matches.slice(0, VISUAL_MAX_LINES)) {
|
|
4338
|
+
const hit = parseMatchHit(match);
|
|
4339
|
+
if (hit) rows.push({ kind: "match", path: hit.path, lineNo: hit.line, text: hit.text });
|
|
4340
|
+
}
|
|
4341
|
+
if (rows.length === 0) return count > 0 ? [{ kind: "meta", text: `${count} result${count === 1 ? "" : "s"}` }] : void 0;
|
|
4342
|
+
if (count > rows.length) rows.push({ kind: "meta", text: `${count - rows.length} more result(s)` });
|
|
4343
|
+
return rows;
|
|
4344
|
+
}
|
|
4345
|
+
function parseMatchHit(hit) {
|
|
4346
|
+
if (typeof hit === "string") {
|
|
4347
|
+
const m = hit.match(/^(.+?):(\d+):(.*)$/);
|
|
4348
|
+
return m?.[1] && m[2] ? { path: m[1], line: m[2], text: m[3] ?? "" } : { text: hit };
|
|
4349
|
+
}
|
|
4350
|
+
if (hit && typeof hit === "object") {
|
|
4351
|
+
const o = hit;
|
|
4352
|
+
const path7 = stringOf(o["file"]) ?? stringOf(o["path"]) ?? stringOf(o["url"]);
|
|
4353
|
+
const line = numOf(o["line"]) ?? numOf(o["lineNumber"]);
|
|
4354
|
+
const title = stringOf(o["title"]);
|
|
4355
|
+
const snippet2 = stringOf(o["snippet"]);
|
|
4356
|
+
const text = stringOf(o["text"]) ?? stringOf(o["match"]) ?? stringOf(o["preview"]) ?? [title, snippet2].filter(Boolean).join(" \u2014 ");
|
|
4357
|
+
return { path: path7, line: line === void 0 ? void 0 : String(line), text };
|
|
4358
|
+
}
|
|
4359
|
+
return void 0;
|
|
4360
|
+
}
|
|
4361
|
+
function visualPathList(toolName, text) {
|
|
4362
|
+
const json = tryParseJson(text);
|
|
4363
|
+
const files = json && typeof json === "object" && Array.isArray(json["files"]) ? json["files"].filter((v) => typeof v === "string") : bodyLines(text).filter((line) => line.trim() && !line.startsWith(`${toolName}:`));
|
|
4364
|
+
if (files.length === 0) return void 0;
|
|
4365
|
+
const rows = files.slice(0, VISUAL_MAX_LINES).map((file) => ({
|
|
4366
|
+
kind: "path",
|
|
4367
|
+
path: file,
|
|
4368
|
+
text: ""
|
|
4369
|
+
}));
|
|
4370
|
+
if (files.length > rows.length) rows.push({ kind: "meta", text: `${files.length - rows.length} more path(s)` });
|
|
4371
|
+
return rows;
|
|
4372
|
+
}
|
|
4373
|
+
function visualTree(text) {
|
|
4374
|
+
const lines = bodyLines(text).filter((line) => line.trim());
|
|
4375
|
+
if (lines.length === 0) return void 0;
|
|
4376
|
+
const rows = lines.slice(0, VISUAL_MAX_LINES).map((line) => ({
|
|
4377
|
+
kind: line.includes("\u2500\u2500") || line.includes("|--") ? "path" : "meta",
|
|
4378
|
+
text: line
|
|
4379
|
+
}));
|
|
4380
|
+
if (lines.length > rows.length) rows.push({ kind: "meta", text: `${lines.length - rows.length} more tree line(s)` });
|
|
4381
|
+
return rows;
|
|
4382
|
+
}
|
|
4383
|
+
function visualCommand(toolName, text, ok) {
|
|
4384
|
+
const json = tryParseJson(text);
|
|
4385
|
+
if (json && typeof json === "object") {
|
|
4386
|
+
const obj = json;
|
|
4387
|
+
return commandRows({
|
|
4388
|
+
exit: numOf(obj["exit_code"]) ?? numOf(obj["exitCode"]),
|
|
4389
|
+
timedOut: obj["timed_out"] === true || obj["timedOut"] === true,
|
|
4390
|
+
stdout: stringOf(obj["stdout"]) ?? stringOf(obj["output"]),
|
|
4391
|
+
stderr: stringOf(obj["stderr"]) ?? stringOf(obj["error"]),
|
|
4392
|
+
ok
|
|
4393
|
+
});
|
|
4394
|
+
}
|
|
4395
|
+
const header = parseHeaderLine(text);
|
|
4396
|
+
const sections = parseNamedSections(text);
|
|
4397
|
+
return commandRows({
|
|
4398
|
+
exit: numberFromParsedField(header.fields, "exit_code") ?? numberFromParsedField(header.fields, "exitCode"),
|
|
4399
|
+
timedOut: header.fields["timed_out"] === "true" || header.fields["timedOut"] === "true",
|
|
4400
|
+
stdout: sections.get("stdout") ?? sections.get("output"),
|
|
4401
|
+
stderr: sections.get("stderr") ?? sections.get("error"),
|
|
4402
|
+
ok,
|
|
4403
|
+
label: toolName
|
|
4404
|
+
});
|
|
4405
|
+
}
|
|
4406
|
+
function commandRows(opts) {
|
|
4407
|
+
const rows = [];
|
|
4408
|
+
const statusKind = opts.timedOut ? "warn" : opts.ok && (opts.exit ?? 0) === 0 ? "ok" : "error";
|
|
4409
|
+
const status = opts.timedOut ? "timed out" : opts.exit !== void 0 ? `exit ${opts.exit}` : opts.ok ? "completed" : "failed";
|
|
4410
|
+
rows.push({ kind: statusKind, marker: statusKind === "ok" ? "ok " : statusKind === "warn" ? "! " : "x ", text: opts.label ? `${opts.label} ${status}` : status });
|
|
4411
|
+
appendOutputPreview(rows, opts.stdout, "stdout");
|
|
4412
|
+
appendOutputPreview(rows, opts.stderr, "stderr");
|
|
4413
|
+
return rows.length > 0 ? rows.slice(0, VISUAL_MAX_LINES) : void 0;
|
|
4414
|
+
}
|
|
4415
|
+
function visualVerifier(toolName, text, ok) {
|
|
4416
|
+
const json = tryParseJson(text);
|
|
4417
|
+
if (json && typeof json === "object") {
|
|
4418
|
+
const obj = json;
|
|
4419
|
+
const errors = numOf(obj["errors"]) ?? numOf(obj["failed"]) ?? 0;
|
|
4420
|
+
const warnings = numOf(obj["warnings"]) ?? 0;
|
|
4421
|
+
const changed2 = numOf(obj["files_changed"]) ?? 0;
|
|
4422
|
+
const statusKind2 = !ok || errors > 0 ? "error" : changed2 > 0 ? "warn" : "ok";
|
|
4423
|
+
const parts = [
|
|
4424
|
+
toolName,
|
|
4425
|
+
errors > 0 ? `${errors} error${errors === 1 ? "" : "s"}` : void 0,
|
|
4426
|
+
warnings > 0 ? `${warnings} warning${warnings === 1 ? "" : "s"}` : void 0,
|
|
4427
|
+
changed2 > 0 ? `${changed2} changed` : void 0,
|
|
4428
|
+
toolName === "test" ? `${numOf(obj["passed"]) ?? 0}/${numOf(obj["tests_run"]) ?? 0} passed` : void 0
|
|
4429
|
+
].filter(Boolean);
|
|
4430
|
+
return [{ kind: statusKind2, marker: statusKind2 === "ok" ? "ok " : statusKind2 === "warn" ? "! " : "x ", text: parts.join(" \xB7 ") || toolName }];
|
|
4431
|
+
}
|
|
4432
|
+
const header = parseHeaderLine(text);
|
|
4433
|
+
const sections = parseNamedSections(text);
|
|
4434
|
+
const report = sections.get("report") ?? "";
|
|
4435
|
+
const errorContext = sections.get("error_context");
|
|
4436
|
+
const fields = { ...header.fields, ...parseKeyValueLines(report) };
|
|
4437
|
+
const status = fields["status"];
|
|
4438
|
+
const errorCount = numberFromParsedField(fields, "errors") ?? numberFromParsedField(fields, "failed") ?? 0;
|
|
4439
|
+
const warningCount = numberFromParsedField(fields, "warnings") ?? 0;
|
|
4440
|
+
const changed = numberFromParsedField(fields, "files_changed") ?? 0;
|
|
4441
|
+
const statusKind = !ok || errorContext || errorCount > 0 ? "error" : status === "changed" || changed > 0 ? "warn" : "ok";
|
|
4442
|
+
const rows = [{
|
|
4443
|
+
kind: statusKind,
|
|
4444
|
+
marker: statusKind === "ok" ? "ok " : statusKind === "warn" ? "! " : "x ",
|
|
4445
|
+
text: [
|
|
4446
|
+
toolName,
|
|
4447
|
+
status ? `status=${status}` : void 0,
|
|
4448
|
+
errorCount > 0 ? `${errorCount} error${errorCount === 1 ? "" : "s"}` : void 0,
|
|
4449
|
+
warningCount > 0 ? `${warningCount} warning${warningCount === 1 ? "" : "s"}` : void 0,
|
|
4450
|
+
changed > 0 ? `${changed} changed` : void 0
|
|
4451
|
+
].filter(Boolean).join(" \xB7 ")
|
|
4452
|
+
}];
|
|
4453
|
+
appendOutputPreview(rows, errorContext, "stderr");
|
|
4454
|
+
return rows.slice(0, VISUAL_MAX_LINES);
|
|
4455
|
+
}
|
|
4456
|
+
function visualFetch(text) {
|
|
4457
|
+
const json = tryParseJson(text);
|
|
4458
|
+
if (json && typeof json === "object") {
|
|
4459
|
+
const obj = json;
|
|
4460
|
+
const status = numOf(obj["status"]);
|
|
4461
|
+
const ct = stringOf(obj["content_type"]);
|
|
4462
|
+
const content = stringOf(obj["content"]);
|
|
4463
|
+
return fetchRows(status, ct, content);
|
|
4464
|
+
}
|
|
4465
|
+
const header = parseHeaderLine(text);
|
|
4466
|
+
return fetchRows(
|
|
4467
|
+
numberFromParsedField(header.fields, "status"),
|
|
4468
|
+
header.fields["content_type"],
|
|
4469
|
+
bodyLines(text).join("\n")
|
|
4470
|
+
);
|
|
4471
|
+
}
|
|
4472
|
+
function fetchRows(status, contentType, content) {
|
|
4473
|
+
const kind = status === void 0 ? "meta" : status >= 200 && status < 300 ? "ok" : status >= 300 && status < 400 ? "warn" : "error";
|
|
4474
|
+
const rows = [{
|
|
4475
|
+
kind,
|
|
4476
|
+
marker: kind === "ok" ? "ok " : kind === "warn" ? "! " : kind === "error" ? "x " : void 0,
|
|
4477
|
+
text: [status !== void 0 ? `HTTP ${status}` : "HTTP", contentType?.split(";")[0]].filter(Boolean).join(" \xB7 ")
|
|
4478
|
+
}];
|
|
4479
|
+
const preview = firstNonEmpty(content ?? "");
|
|
4480
|
+
if (preview) rows.push({ kind: "stdout", text: preview });
|
|
4481
|
+
return rows;
|
|
4482
|
+
}
|
|
4483
|
+
function visualJson(text) {
|
|
4484
|
+
const json = tryParseJson(text);
|
|
4485
|
+
if (!json || typeof json !== "object" || Array.isArray(json)) return void 0;
|
|
4486
|
+
const obj = json;
|
|
4487
|
+
const err = stringOf(obj["error"]);
|
|
4488
|
+
if (err) return [{ kind: "error", marker: "x ", text: err }];
|
|
4489
|
+
const type = stringOf(obj["type"]);
|
|
4490
|
+
const keys = Array.isArray(obj["keys"]) ? obj["keys"].length : void 0;
|
|
4491
|
+
return [{ kind: "ok", marker: "ok ", text: [type ?? "json", keys !== void 0 ? `${keys} key${keys === 1 ? "" : "s"}` : void 0].filter(Boolean).join(" \xB7 ") }];
|
|
4492
|
+
}
|
|
4493
|
+
function visualOutdated(text) {
|
|
4494
|
+
const lines = bodyLines(text).filter((line) => line.trim() && !line.startsWith("outdated"));
|
|
4495
|
+
if (lines.length === 0) return void 0;
|
|
4496
|
+
return lines.slice(0, VISUAL_MAX_LINES).map((line) => ({ kind: "warn", marker: "! ", text: line }));
|
|
4497
|
+
}
|
|
4498
|
+
function visualAudit(text) {
|
|
4499
|
+
const lines = bodyLines(text).filter((line) => line.trim() && !line.startsWith("audit"));
|
|
4500
|
+
if (lines.length === 0) return void 0;
|
|
4501
|
+
return lines.slice(0, VISUAL_MAX_LINES).map((line) => ({
|
|
4502
|
+
kind: /^critical|^high/i.test(line) ? "error" : /^moderate|^medium/i.test(line) ? "warn" : "meta",
|
|
4503
|
+
marker: /^critical|^high/i.test(line) ? "x " : /^moderate|^medium/i.test(line) ? "! " : void 0,
|
|
4504
|
+
text: line
|
|
4505
|
+
}));
|
|
4506
|
+
}
|
|
4507
|
+
function visualScaffold(text) {
|
|
4508
|
+
const json = tryParseJson(text);
|
|
4509
|
+
if (!json || typeof json !== "object") return void 0;
|
|
4510
|
+
const obj = json;
|
|
4511
|
+
const created = Array.isArray(obj["created"]) ? obj["created"] : [];
|
|
4512
|
+
const skipped = Array.isArray(obj["skipped"]) ? obj["skipped"] : [];
|
|
4513
|
+
const rows = [];
|
|
4514
|
+
for (const file of created.slice(0, 5)) {
|
|
4515
|
+
if (typeof file === "string") rows.push({ kind: "ok", marker: "+ ", path: file, text: "" });
|
|
4516
|
+
}
|
|
4517
|
+
if (skipped.length > 0) rows.push({ kind: "warn", marker: "! ", text: `${skipped.length} skipped` });
|
|
4518
|
+
return rows.length > 0 ? rows : void 0;
|
|
4519
|
+
}
|
|
4520
|
+
function visualTodo(text) {
|
|
4521
|
+
const json = tryParseJson(text);
|
|
4522
|
+
const fields = json && typeof json === "object" && !Array.isArray(json) ? recordToStringFields(json) : parseHeaderLine(text).fields;
|
|
4523
|
+
const count = numberFromParsedField(fields, "count") ?? 0;
|
|
4524
|
+
const inProgress = numberFromParsedField(fields, "in_progress") ?? 0;
|
|
4525
|
+
return [{
|
|
4526
|
+
kind: count > 0 ? "ok" : "meta",
|
|
4527
|
+
marker: count > 0 ? "ok " : void 0,
|
|
4528
|
+
text: `${count} todo${count === 1 ? "" : "s"}${inProgress > 0 ? ` \xB7 ${inProgress} in progress` : ""}`
|
|
4529
|
+
}];
|
|
4530
|
+
}
|
|
4531
|
+
function visualWorkBoard(toolName, text, ok) {
|
|
4532
|
+
const json = tryParseJson(text);
|
|
4533
|
+
if (json && typeof json === "object" && !Array.isArray(json)) {
|
|
4534
|
+
const obj = json;
|
|
4535
|
+
const rows2 = boardSummaryRows(toolName, recordToStringFields(obj), ok);
|
|
4536
|
+
appendBoardPreview(rows2, stringOf(obj["message"]));
|
|
4537
|
+
appendBoardPreview(rows2, stringOf(obj["plan"]));
|
|
4538
|
+
const todos = Array.isArray(obj["todos"]) ? obj["todos"] : [];
|
|
4539
|
+
for (const todo of todos.slice(0, 3)) {
|
|
4540
|
+
if (todo && typeof todo === "object") {
|
|
4541
|
+
const o = todo;
|
|
4542
|
+
rows2.push({ kind: "path", marker: "+ ", text: stringOf(o["content"]) ?? stringOf(o["id"]) ?? "todo" });
|
|
4543
|
+
}
|
|
4544
|
+
}
|
|
4545
|
+
return rows2.slice(0, VISUAL_MAX_LINES);
|
|
4546
|
+
}
|
|
4547
|
+
const header = parseHeaderLine(text);
|
|
4548
|
+
const sections = parseNamedSections(text);
|
|
4549
|
+
const rows = boardSummaryRows(toolName, header.fields, ok);
|
|
4550
|
+
appendBoardPreview(rows, sections.get("message") ?? sections.get("plan") ?? bodyLines(text).join("\n"));
|
|
4551
|
+
return rows.slice(0, VISUAL_MAX_LINES);
|
|
4552
|
+
}
|
|
4553
|
+
function boardSummaryRows(toolName, fields, ok) {
|
|
4554
|
+
const success = fields["ok"] !== "false" && ok;
|
|
4555
|
+
const count = numberFromParsedField(fields, "count");
|
|
4556
|
+
const open = numberFromParsedField(fields, "open");
|
|
4557
|
+
const completed = numberFromParsedField(fields, "completed");
|
|
4558
|
+
const inProgress = numberFromParsedField(fields, "inProgress") ?? numberFromParsedField(fields, "in_progress");
|
|
4559
|
+
const parts = [
|
|
4560
|
+
toolName,
|
|
4561
|
+
count !== void 0 ? `${count} item${count === 1 ? "" : "s"}` : void 0,
|
|
4562
|
+
open !== void 0 ? `${open} open` : void 0,
|
|
4563
|
+
completed !== void 0 ? `${completed} done` : void 0,
|
|
4564
|
+
inProgress !== void 0 && inProgress > 0 ? `${inProgress} in progress` : void 0
|
|
4565
|
+
].filter(Boolean);
|
|
4566
|
+
return [{
|
|
4567
|
+
kind: success ? "ok" : "error",
|
|
4568
|
+
marker: success ? "ok " : "x ",
|
|
4569
|
+
text: parts.join(" \xB7 ") || toolName
|
|
4570
|
+
}];
|
|
4571
|
+
}
|
|
4572
|
+
function appendBoardPreview(rows, text) {
|
|
4573
|
+
if (!text) return;
|
|
4574
|
+
const lines = text.split(/\r?\n/).map((line) => line.replace(/^[\s│├└─>*-]+/, "").trim()).filter((line) => line && !line.startsWith("{") && !line.startsWith("["));
|
|
4575
|
+
for (const line of lines.slice(0, 4)) {
|
|
4576
|
+
rows.push({ kind: line.includes("failed") || line.includes("not configured") ? "error" : "meta", text: line });
|
|
4577
|
+
}
|
|
4578
|
+
}
|
|
4579
|
+
function visualMemory(toolName, text, ok) {
|
|
4580
|
+
const json = tryParseJson(text);
|
|
4581
|
+
if (json && typeof json === "object" && !Array.isArray(json)) {
|
|
4582
|
+
const obj = json;
|
|
4583
|
+
if (toolName === "search_memory" || toolName === "find_related_memories") {
|
|
4584
|
+
return memoryResultRows(Array.isArray(obj["results"]) ? obj["results"] : []);
|
|
4585
|
+
}
|
|
4586
|
+
const fields = recordToStringFields(obj);
|
|
4587
|
+
return [memoryStatusRow(toolName, fields, ok)];
|
|
4588
|
+
}
|
|
4589
|
+
const header = parseHeaderLine(text);
|
|
4590
|
+
if (toolName === "search_memory" || toolName === "find_related_memories") {
|
|
4591
|
+
return memoryResultRows(bodyLines(text));
|
|
4592
|
+
}
|
|
4593
|
+
return [memoryStatusRow(toolName, header.fields, ok)];
|
|
4594
|
+
}
|
|
4595
|
+
function memoryStatusRow(toolName, fields, ok) {
|
|
4596
|
+
const scope = fields["scope"];
|
|
4597
|
+
const removed = numberFromParsedField(fields, "removed");
|
|
4598
|
+
const text = toolName === "forget" ? `${removed ?? 0} removed${scope ? ` \xB7 ${scope}` : ""}` : `${toolName}${scope ? ` \xB7 ${scope}` : ""}`;
|
|
4599
|
+
return { kind: ok ? "ok" : "error", marker: ok ? "ok " : "x ", text };
|
|
4600
|
+
}
|
|
4601
|
+
function memoryResultRows(results) {
|
|
4602
|
+
if (results.length === 0) return [{ kind: "meta", text: "no memories" }];
|
|
4603
|
+
const rows = [];
|
|
4604
|
+
for (const result of results.slice(0, VISUAL_MAX_LINES)) {
|
|
4605
|
+
if (typeof result === "string") {
|
|
4606
|
+
const parsed = tryParseJson(result);
|
|
4607
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
4608
|
+
const o = parsed;
|
|
4609
|
+
rows.push({ kind: "meta", marker: tagMarker(stringOf(o["priority"])), text: memoryText(o) });
|
|
4610
|
+
} else {
|
|
4611
|
+
rows.push({ kind: "meta", text: result });
|
|
4612
|
+
}
|
|
4613
|
+
} else if (result && typeof result === "object") {
|
|
4614
|
+
const o = result;
|
|
4615
|
+
rows.push({ kind: "meta", marker: tagMarker(stringOf(o["priority"])), text: memoryText(o) });
|
|
4616
|
+
}
|
|
4617
|
+
}
|
|
4618
|
+
if (results.length > rows.length) rows.push({ kind: "meta", text: `${results.length - rows.length} more memory result(s)` });
|
|
4619
|
+
return rows;
|
|
4620
|
+
}
|
|
4621
|
+
function memoryText(o) {
|
|
4622
|
+
const type = stringOf(o["type"]);
|
|
4623
|
+
const scope = stringOf(o["scope"]);
|
|
4624
|
+
const text = stringOf(o["text"]) ?? "";
|
|
4625
|
+
return [type ? `[${type}]` : void 0, scope, text].filter(Boolean).join(" ");
|
|
4626
|
+
}
|
|
4627
|
+
function tagMarker(priority) {
|
|
4628
|
+
if (priority === "critical" || priority === "high") return "! ";
|
|
4629
|
+
return void 0;
|
|
4630
|
+
}
|
|
4631
|
+
function visualLogs(text) {
|
|
4632
|
+
const json = tryParseJson(text);
|
|
4633
|
+
if (json && typeof json === "object" && !Array.isArray(json)) {
|
|
4634
|
+
const obj = json;
|
|
4635
|
+
const rows2 = [{
|
|
4636
|
+
kind: "meta",
|
|
4637
|
+
text: `${stringOf(obj["source"]) ?? "logs"} \xB7 ${numOf(obj["total"]) ?? 0} entries${obj["truncated"] === true ? " \xB7 truncated" : ""}`
|
|
4638
|
+
}];
|
|
4639
|
+
const entries = Array.isArray(obj["entries"]) ? obj["entries"] : [];
|
|
4640
|
+
appendLogEntries(rows2, entries);
|
|
4641
|
+
return rows2;
|
|
4642
|
+
}
|
|
4643
|
+
const header = parseHeaderLine(text);
|
|
4644
|
+
const rows = [{ kind: "meta", text: `${header.label}${header.fields["total"] ? ` \xB7 ${header.fields["total"]} entries` : ""}` }];
|
|
4645
|
+
appendLogEntries(rows, bodyLines(text));
|
|
4646
|
+
return rows.slice(0, VISUAL_MAX_LINES);
|
|
4647
|
+
}
|
|
4648
|
+
function appendLogEntries(rows, entries) {
|
|
4649
|
+
for (const entry of entries.slice(0, 5)) {
|
|
4650
|
+
if (typeof entry === "string") {
|
|
4651
|
+
rows.push(logLine(entry));
|
|
4652
|
+
} else if (entry && typeof entry === "object") {
|
|
4653
|
+
const o = entry;
|
|
4654
|
+
rows.push(logLine([stringOf(o["timestamp"]), stringOf(o["level"]), stringOf(o["source"]), stringOf(o["message"])].filter(Boolean).join(" ")));
|
|
4655
|
+
}
|
|
4656
|
+
}
|
|
4657
|
+
if (entries.length > 5) rows.push({ kind: "meta", text: `${entries.length - 5} more log line(s)` });
|
|
4658
|
+
}
|
|
4659
|
+
function logLine(line) {
|
|
4660
|
+
const kind = /\b(error|fatal|panic)\b/i.test(line) ? "error" : /\b(warn|warning)\b/i.test(line) ? "warn" : "stdout";
|
|
4661
|
+
return { kind, marker: kind === "error" ? "x " : kind === "warn" ? "! " : void 0, text: line };
|
|
4662
|
+
}
|
|
4663
|
+
function visualDocument(text) {
|
|
4664
|
+
const json = tryParseJson(text);
|
|
4665
|
+
const rows = [];
|
|
4666
|
+
if (json && typeof json === "object" && !Array.isArray(json)) {
|
|
4667
|
+
const obj = json;
|
|
4668
|
+
rows.push({
|
|
4669
|
+
kind: "ok",
|
|
4670
|
+
marker: "ok ",
|
|
4671
|
+
text: `${numOf(obj["items_documented"]) ?? 0} documented \xB7 ${numOf(obj["files_processed"]) ?? 0} files \xB7 ${stringOf(obj["style"]) ?? "style"}`
|
|
4672
|
+
});
|
|
4673
|
+
appendDocumentResults(rows, Array.isArray(obj["results"]) ? obj["results"] : []);
|
|
4674
|
+
return rows.slice(0, VISUAL_MAX_LINES);
|
|
4675
|
+
}
|
|
4676
|
+
const header = parseHeaderLine(text);
|
|
4677
|
+
rows.push({
|
|
4678
|
+
kind: "ok",
|
|
4679
|
+
marker: "ok ",
|
|
4680
|
+
text: `${header.fields["items_documented"] ?? "0"} documented \xB7 ${header.fields["files_processed"] ?? "0"} files`
|
|
4681
|
+
});
|
|
4682
|
+
appendDocumentResults(rows, bodyLines(text));
|
|
4683
|
+
return rows.slice(0, VISUAL_MAX_LINES);
|
|
4684
|
+
}
|
|
4685
|
+
function appendDocumentResults(rows, results) {
|
|
4686
|
+
for (const result of results.slice(0, 5)) {
|
|
4687
|
+
const obj = typeof result === "string" ? tryParseJson(result) : result;
|
|
4688
|
+
if (obj && typeof obj === "object" && !Array.isArray(obj)) {
|
|
4689
|
+
const o = obj;
|
|
4690
|
+
const status = stringOf(o["status"]) ?? "item";
|
|
4691
|
+
rows.push({
|
|
4692
|
+
kind: status === "error" ? "error" : status === "skipped" ? "warn" : "path",
|
|
4693
|
+
marker: status === "error" ? "x " : status === "skipped" ? "! " : "+ ",
|
|
4694
|
+
path: stringOf(o["path"]),
|
|
4695
|
+
text: stringOf(o["name"]) ?? stringOf(o["signature"]) ?? status
|
|
4696
|
+
});
|
|
4697
|
+
} else if (typeof result === "string" && result.trim()) {
|
|
4698
|
+
rows.push({ kind: "meta", text: result.trim() });
|
|
4699
|
+
}
|
|
4700
|
+
}
|
|
4701
|
+
}
|
|
4702
|
+
function visualToolCatalog(toolName, text) {
|
|
4703
|
+
const json = tryParseJson(text);
|
|
4704
|
+
const rows = [];
|
|
4705
|
+
if (json && typeof json === "object" && !Array.isArray(json)) {
|
|
4706
|
+
const obj = json;
|
|
4707
|
+
const total = numOf(obj["total"]) ?? 0;
|
|
4708
|
+
rows.push({ kind: total > 0 ? "ok" : "warn", marker: total > 0 ? "ok " : "! ", text: `${toolName} \xB7 ${total} result${total === 1 ? "" : "s"}` });
|
|
4709
|
+
const tools = Array.isArray(obj["tools"]) ? obj["tools"] : [];
|
|
4710
|
+
for (const tool of tools.slice(0, 5)) {
|
|
4711
|
+
if (tool && typeof tool === "object") {
|
|
4712
|
+
const o = tool;
|
|
4713
|
+
rows.push({
|
|
4714
|
+
kind: o["mutating"] === true ? "warn" : "path",
|
|
4715
|
+
marker: o["mutating"] === true ? "! " : void 0,
|
|
4716
|
+
text: [stringOf(o["name"]), stringOf(o["permission"]), stringOf(o["description"])].filter(Boolean).join(" \xB7 ")
|
|
4717
|
+
});
|
|
4718
|
+
}
|
|
4719
|
+
}
|
|
4720
|
+
return rows.slice(0, VISUAL_MAX_LINES);
|
|
4721
|
+
}
|
|
4722
|
+
const header = parseHeaderLine(text);
|
|
4723
|
+
return [{ kind: "meta", text: header.label || toolName }];
|
|
4724
|
+
}
|
|
4725
|
+
function visualMetaExecution(toolName, text, ok) {
|
|
4726
|
+
const json = tryParseJson(text);
|
|
4727
|
+
if (!json || typeof json !== "object" || Array.isArray(json)) {
|
|
4728
|
+
const header = parseHeaderLine(text);
|
|
4729
|
+
return [{ kind: ok ? "ok" : "error", marker: ok ? "ok " : "x ", text: header.label || toolName }];
|
|
4730
|
+
}
|
|
4731
|
+
const obj = json;
|
|
4732
|
+
if (toolName === "tool_use") {
|
|
4733
|
+
const success = obj["success"] !== false && ok;
|
|
4734
|
+
const target = stringOf(obj["tool"]) ?? "tool";
|
|
4735
|
+
return [{
|
|
4736
|
+
kind: success ? "ok" : "error",
|
|
4737
|
+
marker: success ? "ok " : "x ",
|
|
4738
|
+
text: `${target} \xB7 ${numOf(obj["executionMs"]) ?? 0}ms${success ? "" : ` \xB7 ${stringOf(obj["error"]) ?? "failed"}`}`
|
|
4739
|
+
}];
|
|
4740
|
+
}
|
|
4741
|
+
const total = numOf(obj["total"]) ?? 0;
|
|
4742
|
+
const succeeded = numOf(obj["succeeded"]) ?? 0;
|
|
4743
|
+
const failed = numOf(obj["failed"]) ?? 0;
|
|
4744
|
+
const rows = [{
|
|
4745
|
+
kind: failed > 0 || !ok ? "error" : "ok",
|
|
4746
|
+
marker: failed > 0 || !ok ? "x " : "ok ",
|
|
4747
|
+
text: `${succeeded}/${total} succeeded${failed > 0 ? ` \xB7 ${failed} failed` : ""}`
|
|
4748
|
+
}];
|
|
4749
|
+
const results = Array.isArray(obj["results"]) ? obj["results"] : [];
|
|
4750
|
+
for (const result of results.slice(0, 5)) {
|
|
4751
|
+
if (result && typeof result === "object") {
|
|
4752
|
+
const r = result;
|
|
4753
|
+
const success = r["success"] !== false;
|
|
4754
|
+
rows.push({
|
|
4755
|
+
kind: success ? "ok" : "error",
|
|
4756
|
+
marker: success ? "ok " : "x ",
|
|
4757
|
+
text: `${stringOf(r["tool"]) ?? "tool"} \xB7 ${numOf(r["executionMs"]) ?? 0}ms${success ? "" : ` \xB7 ${stringOf(r["error"]) ?? "failed"}`}`
|
|
4758
|
+
});
|
|
4759
|
+
}
|
|
4760
|
+
}
|
|
4761
|
+
return rows.slice(0, VISUAL_MAX_LINES);
|
|
4762
|
+
}
|
|
4763
|
+
function visualCodebase(toolName, text, ok) {
|
|
4764
|
+
const json = tryParseJson(text);
|
|
4765
|
+
if (!json || typeof json !== "object" || Array.isArray(json)) {
|
|
4766
|
+
const header = parseHeaderLine(text);
|
|
4767
|
+
return [{ kind: ok ? "ok" : "warn", marker: ok ? "ok " : "! ", text: header.label || toolName }];
|
|
4768
|
+
}
|
|
4769
|
+
const obj = json;
|
|
4770
|
+
if (toolName === "codebase-search") {
|
|
4771
|
+
const status2 = stringOf(obj["indexStatus"]);
|
|
4772
|
+
const total = numOf(obj["total"]) ?? 0;
|
|
4773
|
+
const rows = [{
|
|
4774
|
+
kind: status2 ? "warn" : "ok",
|
|
4775
|
+
marker: status2 ? "! " : "ok ",
|
|
4776
|
+
text: status2 ?? `${total} symbol result${total === 1 ? "" : "s"} for "${stringOf(obj["query"]) ?? ""}"`
|
|
4777
|
+
}];
|
|
4778
|
+
const results = Array.isArray(obj["results"]) ? obj["results"] : [];
|
|
4779
|
+
for (const result of results.slice(0, 5)) {
|
|
4780
|
+
if (result && typeof result === "object") {
|
|
4781
|
+
const r = result;
|
|
4782
|
+
rows.push({
|
|
4783
|
+
kind: "match",
|
|
4784
|
+
path: stringOf(r["file"]),
|
|
4785
|
+
lineNo: numOf(r["line"])?.toString(),
|
|
4786
|
+
text: [stringOf(r["kind"]), stringOf(r["name"]), stringOf(r["signature"])].filter(Boolean).join(" \xB7 ")
|
|
4787
|
+
});
|
|
4788
|
+
}
|
|
4789
|
+
}
|
|
4790
|
+
return rows.slice(0, VISUAL_MAX_LINES);
|
|
4791
|
+
}
|
|
4792
|
+
if (toolName === "codebase-index") {
|
|
4793
|
+
const errors = Array.isArray(obj["errors"]) ? obj["errors"] : [];
|
|
4794
|
+
return [{
|
|
4795
|
+
kind: errors.length > 0 || !ok ? "error" : stringOf(obj["note"]) ? "warn" : "ok",
|
|
4796
|
+
marker: errors.length > 0 || !ok ? "x " : stringOf(obj["note"]) ? "! " : "ok ",
|
|
4797
|
+
text: stringOf(obj["note"]) ?? `${numOf(obj["filesIndexed"]) ?? 0} files \xB7 ${numOf(obj["symbolsIndexed"]) ?? 0} symbols \xB7 ${fmtDuration(numOf(obj["durationMs"]) ?? 0)}`
|
|
4798
|
+
}];
|
|
4799
|
+
}
|
|
4800
|
+
const status = stringOf(obj["indexStatus"]);
|
|
4801
|
+
return [{
|
|
4802
|
+
kind: status ? "warn" : "ok",
|
|
4803
|
+
marker: status ? "! " : "ok ",
|
|
4804
|
+
text: status ?? `${numOf(obj["totalSymbols"]) ?? 0} symbols \xB7 ${numOf(obj["totalFiles"]) ?? 0} files \xB7 ${fmtBytes(numOf(obj["sizeBytes"]) ?? 0)}`
|
|
4805
|
+
}];
|
|
4806
|
+
}
|
|
4807
|
+
function visualWorkingDir(text, ok) {
|
|
4808
|
+
const json = tryParseJson(text);
|
|
4809
|
+
const obj = json && typeof json === "object" && !Array.isArray(json) ? json : void 0;
|
|
4810
|
+
if (!obj) return void 0;
|
|
4811
|
+
const err = stringOf(obj["error"]);
|
|
4812
|
+
return [{
|
|
4813
|
+
kind: err || !ok ? "error" : "ok",
|
|
4814
|
+
marker: err || !ok ? "x " : "ok ",
|
|
4815
|
+
path: stringOf(obj["current"]),
|
|
4816
|
+
text: err ?? stringOf(obj["message"]) ?? "working directory"
|
|
4817
|
+
}];
|
|
4818
|
+
}
|
|
4819
|
+
function visualMode(text, ok) {
|
|
4820
|
+
const json = tryParseJson(text);
|
|
4821
|
+
const obj = json && typeof json === "object" && !Array.isArray(json) ? json : void 0;
|
|
4822
|
+
if (!obj) return void 0;
|
|
4823
|
+
if (Array.isArray(obj["modes"])) {
|
|
4824
|
+
const modes = obj["modes"];
|
|
4825
|
+
const rows = [{ kind: "ok", marker: "ok ", text: `${modes.length} mode${modes.length === 1 ? "" : "s"}` }];
|
|
4826
|
+
for (const mode of modes.slice(0, 5)) {
|
|
4827
|
+
if (mode && typeof mode === "object") {
|
|
4828
|
+
const m = mode;
|
|
4829
|
+
rows.push({ kind: "path", text: [stringOf(m["id"]), stringOf(m["name"]), stringOf(m["description"])].filter(Boolean).join(" \xB7 ") });
|
|
4830
|
+
}
|
|
4831
|
+
}
|
|
4832
|
+
return rows;
|
|
4833
|
+
}
|
|
4834
|
+
const success = obj["success"] !== false && ok;
|
|
4835
|
+
return [{
|
|
4836
|
+
kind: success ? "ok" : "error",
|
|
4837
|
+
marker: success ? "ok " : "x ",
|
|
4838
|
+
text: [stringOf(obj["action"]) ?? "mode", stringOf(obj["currentMode"]), stringOf(obj["message"])].filter(Boolean).join(" \xB7 ")
|
|
4839
|
+
}];
|
|
4840
|
+
}
|
|
4841
|
+
function recordToStringFields(obj) {
|
|
4842
|
+
const out = {};
|
|
4843
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
4844
|
+
if (value === void 0 || value === null) continue;
|
|
4845
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
4846
|
+
out[key] = String(value);
|
|
4847
|
+
}
|
|
4848
|
+
}
|
|
4849
|
+
return out;
|
|
4850
|
+
}
|
|
4851
|
+
function appendOutputPreview(rows, output, kind) {
|
|
4852
|
+
if (!output) return;
|
|
4853
|
+
const lines = output.split(/\r?\n/).filter((line) => line.trim());
|
|
4854
|
+
for (const line of lines.slice(0, 3)) rows.push({ kind, text: line.trim() });
|
|
4855
|
+
if (lines.length > 3) rows.push({ kind: "meta", text: `${lines.length - 3} more ${kind} line(s)` });
|
|
4856
|
+
}
|
|
4857
|
+
function bodyLines(text) {
|
|
4858
|
+
const lines = text.replace(/\r/g, "").split("\n");
|
|
4859
|
+
if (lines.length > 0 && /^[^\n]+(?:\s+\([^)]*\))?$/.test(lines[0] ?? "")) {
|
|
4860
|
+
return lines.slice(1);
|
|
4861
|
+
}
|
|
4862
|
+
return lines;
|
|
4863
|
+
}
|
|
4864
|
+
function parseHeaderLine(text) {
|
|
4865
|
+
const first = text.split(/\r?\n/, 1)[0] ?? "";
|
|
4866
|
+
const match = first.match(/^(.+?)(?: \((.*)\))?$/);
|
|
4867
|
+
const label = match?.[1] ?? first;
|
|
4868
|
+
const rawFields = match?.[2] ?? "";
|
|
4869
|
+
return { label, fields: parseInlineFields(rawFields) };
|
|
4870
|
+
}
|
|
4871
|
+
function parseInlineFields(raw) {
|
|
4872
|
+
const fields = {};
|
|
4873
|
+
for (const match of raw.matchAll(/([A-Za-z_][A-Za-z0-9_]*)=([^ ]+)/g)) {
|
|
4874
|
+
if (match[1] && match[2]) fields[match[1]] = match[2];
|
|
4875
|
+
}
|
|
4876
|
+
return fields;
|
|
4877
|
+
}
|
|
4878
|
+
function parseNamedSections(text) {
|
|
4879
|
+
const sections = /* @__PURE__ */ new Map();
|
|
4880
|
+
const lines = text.replace(/\r/g, "").split("\n");
|
|
4881
|
+
let current;
|
|
4882
|
+
const buf = [];
|
|
4883
|
+
const flush = () => {
|
|
4884
|
+
if (current) sections.set(current, buf.join("\n").trim());
|
|
4885
|
+
buf.length = 0;
|
|
4886
|
+
};
|
|
4887
|
+
for (const line of lines.slice(1)) {
|
|
4888
|
+
const m = line.match(/^([a-z_]+):$/);
|
|
4889
|
+
if (m?.[1]) {
|
|
4890
|
+
flush();
|
|
4891
|
+
current = m[1];
|
|
4892
|
+
continue;
|
|
4893
|
+
}
|
|
4894
|
+
if (current) buf.push(line);
|
|
4895
|
+
}
|
|
4896
|
+
flush();
|
|
4897
|
+
return sections;
|
|
4898
|
+
}
|
|
4899
|
+
function parseKeyValueLines(text) {
|
|
4900
|
+
const out = {};
|
|
4901
|
+
for (const line of text.split(/\r?\n/)) {
|
|
4902
|
+
const m = line.match(/^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);
|
|
4903
|
+
if (m?.[1]) out[m[1]] = m[2] ?? "";
|
|
4904
|
+
}
|
|
4905
|
+
return out;
|
|
4906
|
+
}
|
|
4907
|
+
function numberFromParsedField(fields, key) {
|
|
4908
|
+
const raw = fields[key];
|
|
4909
|
+
if (raw === void 0) return void 0;
|
|
4910
|
+
const n = Number.parseInt(raw, 10);
|
|
4911
|
+
return Number.isFinite(n) ? n : void 0;
|
|
4912
|
+
}
|
|
4105
4913
|
var MAX_STREAM_DISPLAY_CHARS = 480;
|
|
4106
4914
|
var MAX_STREAM_LINES = 8;
|
|
4107
4915
|
function streamBoxRows(text, maxLines, contentWidth) {
|
|
@@ -4146,10 +4954,7 @@ var ToolStreamBox = React5.memo(function ToolStreamBox2({
|
|
|
4146
4954
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u23F1 ${fmtDuration(elapsedMs)}` }),
|
|
4147
4955
|
hidden > 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` (${totalLines} lines, showing last ${MAX_STREAM_LINES})` }) : null
|
|
4148
4956
|
] }),
|
|
4149
|
-
/* @__PURE__ */ jsx(Box, { flexDirection: "column", marginLeft: 2, children: rows.map((r, i) => (
|
|
4150
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: fixed-height block, index is the row
|
|
4151
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, italic: Boolean(r.italic), children: r.text || " " }, i)
|
|
4152
|
-
)) })
|
|
4957
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", marginLeft: 2, children: rows.map((r, i) => /* @__PURE__ */ jsx(Text, { dimColor: true, italic: Boolean(r.italic), children: r.text || " " }, i)) })
|
|
4153
4958
|
] });
|
|
4154
4959
|
});
|
|
4155
4960
|
function tailForDisplay(text, maxChars) {
|
|
@@ -4162,7 +4967,7 @@ function tailForDisplay(text, maxChars) {
|
|
|
4162
4967
|
return `\u2026 ${text.slice(cut)}`;
|
|
4163
4968
|
}
|
|
4164
4969
|
var MAX_CODE_LINES = 80;
|
|
4165
|
-
var DIFF_MAX_LINES =
|
|
4970
|
+
var DIFF_MAX_LINES = 12;
|
|
4166
4971
|
function CodeBlock({
|
|
4167
4972
|
code,
|
|
4168
4973
|
lang,
|
|
@@ -4194,58 +4999,83 @@ function CodeBlock({
|
|
|
4194
4999
|
paddingX: 1,
|
|
4195
5000
|
children: [
|
|
4196
5001
|
lang !== "plain" ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: lang }) : null,
|
|
4197
|
-
rows.map((tokens, i) => (
|
|
4198
|
-
|
|
4199
|
-
/* @__PURE__ */
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
))
|
|
4211
|
-
] }, i)
|
|
4212
|
-
)),
|
|
5002
|
+
rows.map((tokens, i) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
5003
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: `${String(i + 1).padStart(gutterW, " ")} ` }),
|
|
5004
|
+
tokens.length === 0 ? " " : tokens.map((t, j) => /* @__PURE__ */ jsx(
|
|
5005
|
+
Text,
|
|
5006
|
+
{
|
|
5007
|
+
dimColor: Boolean(t.dim),
|
|
5008
|
+
bold: Boolean(t.bold),
|
|
5009
|
+
...t.color ? { color: t.color } : {},
|
|
5010
|
+
children: t.text
|
|
5011
|
+
},
|
|
5012
|
+
j
|
|
5013
|
+
))
|
|
5014
|
+
] }, i)),
|
|
4213
5015
|
hidden > 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, italic: true, children: `\u2026 +${hidden} more line${hidden === 1 ? "" : "s"}` }) : null
|
|
4214
5016
|
]
|
|
4215
5017
|
}
|
|
4216
5018
|
);
|
|
4217
5019
|
}
|
|
4218
|
-
function DiffBlock({
|
|
5020
|
+
function DiffBlock({
|
|
5021
|
+
rows,
|
|
5022
|
+
hidden,
|
|
5023
|
+
hiddenAdded = 0,
|
|
5024
|
+
hiddenRemoved = 0
|
|
5025
|
+
}) {
|
|
4219
5026
|
let gutterWidth = 1;
|
|
4220
5027
|
for (const r of rows) {
|
|
4221
|
-
const n
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
5028
|
+
for (const n of [r.oldLine, r.newLine]) {
|
|
5029
|
+
if (typeof n === "number") {
|
|
5030
|
+
const w = String(n).length;
|
|
5031
|
+
if (w > gutterWidth) gutterWidth = w;
|
|
5032
|
+
}
|
|
4225
5033
|
}
|
|
4226
5034
|
}
|
|
4227
5035
|
const blank = " ".repeat(gutterWidth);
|
|
5036
|
+
const gutterPad = `${blank} ${blank}`;
|
|
5037
|
+
const footerStats = [
|
|
5038
|
+
hiddenAdded > 0 ? `+${hiddenAdded}` : "",
|
|
5039
|
+
hiddenRemoved > 0 ? `-${hiddenRemoved}` : ""
|
|
5040
|
+
].filter(Boolean);
|
|
5041
|
+
const markerFor = (kind) => {
|
|
5042
|
+
if (kind === "add") return "+";
|
|
5043
|
+
if (kind === "del") return "-";
|
|
5044
|
+
return " ";
|
|
5045
|
+
};
|
|
5046
|
+
const textForDisplay = (row) => {
|
|
5047
|
+
if ((row.kind === "add" || row.kind === "del" || row.kind === "ctx") && row.text.length > 0) {
|
|
5048
|
+
return row.text.slice(1) || " ";
|
|
5049
|
+
}
|
|
5050
|
+
return row.text || " ";
|
|
5051
|
+
};
|
|
4228
5052
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 4, marginTop: 0, children: [
|
|
4229
5053
|
rows.map((row, i) => {
|
|
4230
5054
|
const key = i;
|
|
4231
5055
|
if (row.kind === "hunk") {
|
|
4232
|
-
return /* @__PURE__ */ jsx(Text, { color: "cyan", dimColor: true, children: row.text }, key);
|
|
5056
|
+
return /* @__PURE__ */ jsx(Text, { color: "cyan", dimColor: true, children: `${gutterPad} ${row.text}` }, key);
|
|
4233
5057
|
}
|
|
4234
5058
|
if (row.kind === "meta") {
|
|
4235
|
-
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: `${
|
|
5059
|
+
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: `${gutterPad} ${row.text}` }, key);
|
|
4236
5060
|
}
|
|
4237
|
-
const
|
|
4238
|
-
const
|
|
5061
|
+
const oldLn = typeof row.oldLine === "number" ? String(row.oldLine).padStart(gutterWidth, " ") : blank;
|
|
5062
|
+
const newLn = typeof row.newLine === "number" ? String(row.newLine).padStart(gutterWidth, " ") : blank;
|
|
4239
5063
|
if (row.kind === "ctx") {
|
|
4240
|
-
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: `${
|
|
5064
|
+
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: `${oldLn} ${newLn} ${textForDisplay(row)}` }, key);
|
|
4241
5065
|
}
|
|
4242
5066
|
const bg = row.kind === "add" ? theme.diffAddBg : theme.diffDelBg;
|
|
5067
|
+
const lineColor = row.kind === "add" ? theme.success : theme.error;
|
|
5068
|
+
const marker = markerFor(row.kind);
|
|
4243
5069
|
return /* @__PURE__ */ jsxs(Text, { children: [
|
|
4244
|
-
/* @__PURE__ */ jsx(Text, { dimColor:
|
|
4245
|
-
/* @__PURE__ */ jsx(Text, {
|
|
5070
|
+
/* @__PURE__ */ jsx(Text, { color: row.kind === "del" ? lineColor : void 0, dimColor: row.kind !== "del", children: oldLn }),
|
|
5071
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }),
|
|
5072
|
+
/* @__PURE__ */ jsx(Text, { color: row.kind === "add" ? lineColor : void 0, dimColor: row.kind !== "add", children: newLn }),
|
|
5073
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
5074
|
+
/* @__PURE__ */ jsx(Text, { color: lineColor, bold: true, children: marker }),
|
|
5075
|
+
/* @__PURE__ */ jsx(Text, { backgroundColor: bg, color: "black", children: textForDisplay(row) })
|
|
4246
5076
|
] }, key);
|
|
4247
5077
|
}),
|
|
4248
|
-
hidden > 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, italic: true, children: `${
|
|
5078
|
+
hidden > 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, italic: true, children: `${gutterPad} \u2026 ${hidden} more line${hidden === 1 ? "" : "s"}${footerStats.length > 0 ? ` (${footerStats.join(" ")})` : ""}` }) : null
|
|
4249
5079
|
] });
|
|
4250
5080
|
}
|
|
4251
5081
|
function parseUnifiedDiff(diff, maxLines) {
|
|
@@ -4284,19 +5114,35 @@ function parseUnifiedDiff(diff, maxLines) {
|
|
|
4284
5114
|
oldLn++;
|
|
4285
5115
|
newLn++;
|
|
4286
5116
|
}
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
5117
|
+
const added = all.filter((row) => row.kind === "add").length;
|
|
5118
|
+
const removed = all.filter((row) => row.kind === "del").length;
|
|
5119
|
+
if (all.length === 0) {
|
|
5120
|
+
return { rows: [], hidden: 0, added: 0, removed: 0, hiddenAdded: 0, hiddenRemoved: 0 };
|
|
5121
|
+
}
|
|
5122
|
+
if (all.length <= maxLines) {
|
|
5123
|
+
return { rows: all, hidden: 0, added, removed, hiddenAdded: 0, hiddenRemoved: 0 };
|
|
5124
|
+
}
|
|
5125
|
+
const rows = all.slice(0, maxLines);
|
|
5126
|
+
const hiddenRows = all.slice(maxLines);
|
|
5127
|
+
return {
|
|
5128
|
+
rows,
|
|
5129
|
+
hidden: hiddenRows.length,
|
|
5130
|
+
added,
|
|
5131
|
+
removed,
|
|
5132
|
+
hiddenAdded: hiddenRows.filter((row) => row.kind === "add").length,
|
|
5133
|
+
hiddenRemoved: hiddenRows.filter((row) => row.kind === "del").length
|
|
5134
|
+
};
|
|
4290
5135
|
}
|
|
4291
|
-
function extractDiffPreview(toolName, output) {
|
|
5136
|
+
function extractDiffPreview(toolName, output, input) {
|
|
4292
5137
|
if (!output) return void 0;
|
|
4293
5138
|
const text = output.trim();
|
|
4294
5139
|
if (!text) return void 0;
|
|
4295
5140
|
let diff;
|
|
4296
|
-
if (toolName === "edit" || toolName === "diff") {
|
|
5141
|
+
if (toolName === "edit" || toolName === "diff" || toolName === "write") {
|
|
4297
5142
|
const parsed = tryParseJson(text);
|
|
4298
5143
|
if (parsed && typeof parsed === "object") {
|
|
4299
|
-
|
|
5144
|
+
const obj = parsed;
|
|
5145
|
+
diff = toolName === "write" && obj["created"] === true ? newFileDiffFromWriteInput(obj, input) ?? stringOf(obj["diff"]) : stringOf(obj["diff"]);
|
|
4300
5146
|
}
|
|
4301
5147
|
} else if (toolName === "patch") {
|
|
4302
5148
|
const parsed = tryParseJson(text);
|
|
@@ -4305,9 +5151,32 @@ function extractDiffPreview(toolName, output) {
|
|
|
4305
5151
|
} else if (text.includes("@@") || text.startsWith("---")) {
|
|
4306
5152
|
diff = text;
|
|
4307
5153
|
}
|
|
5154
|
+
} else if (toolName === "replace") {
|
|
5155
|
+
const parsed = tryParseJson(text);
|
|
5156
|
+
if (parsed && typeof parsed === "object") {
|
|
5157
|
+
diff = collectReplaceDiffs(parsed);
|
|
5158
|
+
}
|
|
4308
5159
|
}
|
|
4309
|
-
if (!diff
|
|
4310
|
-
|
|
5160
|
+
if (!diff?.trim() || diff.startsWith("(no-op")) return void 0;
|
|
5161
|
+
const preview = parseUnifiedDiff(diff, DIFF_MAX_LINES);
|
|
5162
|
+
return preview.rows.length > 0 ? preview : void 0;
|
|
5163
|
+
}
|
|
5164
|
+
function collectReplaceDiffs(obj) {
|
|
5165
|
+
const results = Array.isArray(obj["results"]) ? obj["results"] : [];
|
|
5166
|
+
const diffs = results.map(
|
|
5167
|
+
(result) => result && typeof result === "object" ? stringOf(result["diff"]) : void 0
|
|
5168
|
+
).filter((diff) => Boolean(diff?.trim()));
|
|
5169
|
+
return diffs.length > 0 ? diffs.join("\n") : void 0;
|
|
5170
|
+
}
|
|
5171
|
+
function newFileDiffFromWriteInput(output, input) {
|
|
5172
|
+
if (!input || typeof input !== "object") return void 0;
|
|
5173
|
+
const obj = input;
|
|
5174
|
+
const content = stringOf(obj["content"]);
|
|
5175
|
+
if (content === void 0) return void 0;
|
|
5176
|
+
const path7 = stringOf(output["path"]) ?? stringOf(obj["path"]) ?? "new file";
|
|
5177
|
+
const lines = content === "" ? [] : content.replace(/\n$/, "").split("\n");
|
|
5178
|
+
const header = [`+++ ${path7}`, `@@ -0,0 +1,${lines.length} @@`];
|
|
5179
|
+
return [...header, ...lines.map((line) => `+${line}`)].join("\n");
|
|
4311
5180
|
}
|
|
4312
5181
|
var MESSAGE_PANEL_CHROME_WIDTH = 2;
|
|
4313
5182
|
function assistantContentWidth(termWidth) {
|
|
@@ -4354,20 +5223,14 @@ function AssistantBody({
|
|
|
4354
5223
|
const segments = splitFencedBlocks(text);
|
|
4355
5224
|
const inner = contentWidth ?? termWidth;
|
|
4356
5225
|
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: segments.map(
|
|
4357
|
-
(seg, i) => seg.type === "code" ? (
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
text: seg.text,
|
|
4366
|
-
termWidth: inner,
|
|
4367
|
-
tableWidth: termWidth - MESSAGE_PANEL_CHROME_WIDTH
|
|
4368
|
-
},
|
|
4369
|
-
i
|
|
4370
|
-
)
|
|
5226
|
+
(seg, i) => seg.type === "code" ? /* @__PURE__ */ jsx(CodeBlock, { code: seg.text, lang: seg.lang ?? "plain", contentWidth: inner }, i) : /* @__PURE__ */ jsx(
|
|
5227
|
+
MarkdownView,
|
|
5228
|
+
{
|
|
5229
|
+
text: seg.text,
|
|
5230
|
+
termWidth: inner,
|
|
5231
|
+
tableWidth: termWidth - MESSAGE_PANEL_CHROME_WIDTH
|
|
5232
|
+
},
|
|
5233
|
+
i
|
|
4371
5234
|
)
|
|
4372
5235
|
) });
|
|
4373
5236
|
}
|
|
@@ -4403,10 +5266,7 @@ function AssistantTail({
|
|
|
4403
5266
|
/* @__PURE__ */ jsx(Text, { bold: true, color: theme.assistant, children: "ASSISTANT" }),
|
|
4404
5267
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " (streaming\u2026)" })
|
|
4405
5268
|
] }),
|
|
4406
|
-
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: rows.map((r, i) => (
|
|
4407
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: fixed-height block, index is the row
|
|
4408
|
-
/* @__PURE__ */ jsx(Text, { color: "white", children: r || " " }, i)
|
|
4409
|
-
)) })
|
|
5269
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: rows.map((r, i) => /* @__PURE__ */ jsx(Text, { color: "white", children: r || " " }, i)) })
|
|
4410
5270
|
]
|
|
4411
5271
|
}
|
|
4412
5272
|
);
|
|
@@ -4706,7 +5566,8 @@ var Entry = React5.memo(function Entry2({
|
|
|
4706
5566
|
entry.outputBytes,
|
|
4707
5567
|
entry.outputLines
|
|
4708
5568
|
);
|
|
4709
|
-
const
|
|
5569
|
+
const visualLines = formatToolVisualOutput(entry.name, entry.output, entry.ok, entry.input);
|
|
5570
|
+
const diff = entry.ok ? extractDiffPreview(entry.name, entry.output, entry.input) : void 0;
|
|
4710
5571
|
const sizeChip = (() => {
|
|
4711
5572
|
if (!entry.ok) return "";
|
|
4712
5573
|
const parts = [];
|
|
@@ -4733,21 +5594,26 @@ var Entry = React5.memo(function Entry2({
|
|
|
4733
5594
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \xB7 ${fmtDuration(entry.durationMs)}` }),
|
|
4734
5595
|
sizeChip ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \xB7 ${sizeChip}` }) : null
|
|
4735
5596
|
] }),
|
|
4736
|
-
outLines.map((line, i) => (
|
|
4737
|
-
|
|
4738
|
-
/* @__PURE__ */
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
{
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
5597
|
+
visualLines ? /* @__PURE__ */ jsx(ToolOutputLines, { lines: visualLines, hasFollowingBlock: Boolean(diff) }) : outLines.map((line, i) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
5598
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: i === outLines.length - 1 && !diff ? " \u2514\u2500 " : " \u251C\u2500 " }),
|
|
5599
|
+
/* @__PURE__ */ jsx(
|
|
5600
|
+
Text,
|
|
5601
|
+
{
|
|
5602
|
+
dimColor: entry.ok && !line.startsWith("!"),
|
|
5603
|
+
...!entry.ok || line.startsWith("!") ? { color: "red" } : {},
|
|
5604
|
+
children: line
|
|
5605
|
+
}
|
|
5606
|
+
)
|
|
5607
|
+
] }, i)),
|
|
5608
|
+
diff ? /* @__PURE__ */ jsx(
|
|
5609
|
+
DiffBlock,
|
|
5610
|
+
{
|
|
5611
|
+
rows: diff.rows,
|
|
5612
|
+
hidden: diff.hidden,
|
|
5613
|
+
hiddenAdded: diff.hiddenAdded,
|
|
5614
|
+
hiddenRemoved: diff.hiddenRemoved
|
|
5615
|
+
}
|
|
5616
|
+
) : null
|
|
4751
5617
|
] });
|
|
4752
5618
|
}
|
|
4753
5619
|
case "info": {
|
|
@@ -4851,13 +5717,10 @@ var Entry = React5.memo(function Entry2({
|
|
|
4851
5717
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: entry.detail })
|
|
4852
5718
|
] }) : null
|
|
4853
5719
|
] }),
|
|
4854
|
-
lines.slice(1).map((line, i) => (
|
|
4855
|
-
|
|
4856
|
-
/* @__PURE__ */
|
|
4857
|
-
|
|
4858
|
-
/* @__PURE__ */ jsx(Text, { children: line })
|
|
4859
|
-
] }, i)
|
|
4860
|
-
))
|
|
5720
|
+
lines.slice(1).map((line, i) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
5721
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }),
|
|
5722
|
+
/* @__PURE__ */ jsx(Text, { children: line })
|
|
5723
|
+
] }, i))
|
|
4861
5724
|
] });
|
|
4862
5725
|
}
|
|
4863
5726
|
}
|
|
@@ -5507,13 +6370,7 @@ var Input = memo(function Input2({
|
|
|
5507
6370
|
}
|
|
5508
6371
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
5509
6372
|
rows.map(
|
|
5510
|
-
(row, i) => row.length === 0 ? (
|
|
5511
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: rows are positional and re-laid out every render
|
|
5512
|
-
/* @__PURE__ */ jsx(Text, { children: " " }, i)
|
|
5513
|
-
) : (
|
|
5514
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: rows are positional and re-laid out every render
|
|
5515
|
-
/* @__PURE__ */ jsx(Text, { children: renderRow2(row, `r${i}`, promptColor) }, i)
|
|
5516
|
-
)
|
|
6373
|
+
(row, i) => row.length === 0 ? /* @__PURE__ */ jsx(Text, { children: " " }, i) : /* @__PURE__ */ jsx(Text, { children: renderRow2(row, `r${i}`, promptColor) }, i)
|
|
5517
6374
|
),
|
|
5518
6375
|
hint ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: hint }) : null
|
|
5519
6376
|
] });
|
|
@@ -5673,30 +6530,181 @@ function PhaseMonitor({
|
|
|
5673
6530
|
const isRunning = runningPhaseIds.includes(phaseKey);
|
|
5674
6531
|
const elapsed = phase.startedAt ? fmtElapsed2(nowTick - phase.startedAt) : "\u2014";
|
|
5675
6532
|
const progress = phase.totalTasks > 0 ? `${phase.completedTasks}/${phase.totalTasks}` : "\u2014";
|
|
5676
|
-
return /* @__PURE__ */
|
|
5677
|
-
/* @__PURE__ */
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
/* @__PURE__ */ jsx(Text, { color: s2.color, children: s2.label }),
|
|
5681
|
-
isRunning ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5682
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
5683
|
-
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5684
|
-
"elapsed ",
|
|
5685
|
-
elapsed
|
|
5686
|
-
] })
|
|
5687
|
-
] }) : null,
|
|
5688
|
-
phase.totalTasks > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6533
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
6534
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
6535
|
+
/* @__PURE__ */ jsx(Text, { color: s2.color, bold: true, children: s2.icon }),
|
|
6536
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: phase.name }),
|
|
5689
6537
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
5690
|
-
/* @__PURE__ */
|
|
5691
|
-
|
|
5692
|
-
|
|
6538
|
+
/* @__PURE__ */ jsx(Text, { color: s2.color, children: s2.label }),
|
|
6539
|
+
isRunning ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6540
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
6541
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
6542
|
+
"elapsed ",
|
|
6543
|
+
elapsed
|
|
6544
|
+
] })
|
|
6545
|
+
] }) : null,
|
|
6546
|
+
phase.totalTasks > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6547
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
6548
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
6549
|
+
"tasks ",
|
|
6550
|
+
progress
|
|
6551
|
+
] })
|
|
5693
6552
|
] })
|
|
5694
|
-
] })
|
|
5695
|
-
|
|
6553
|
+
] }),
|
|
6554
|
+
(phase.activeTasks ?? []).map((t) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, marginLeft: 2, children: [
|
|
6555
|
+
/* @__PURE__ */ jsx(Text, { color: "yellow", children: "\u25CF" }),
|
|
6556
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: t.agent ?? "agent" }),
|
|
6557
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2192" }),
|
|
6558
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: t.title || "(task)" })
|
|
6559
|
+
] }, t.taskId))
|
|
6560
|
+
] }, phaseKey);
|
|
5696
6561
|
}),
|
|
5697
6562
|
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 navigate phases" }) })
|
|
5698
6563
|
] });
|
|
5699
6564
|
}
|
|
6565
|
+
var STATUS3 = {
|
|
6566
|
+
pending: { icon: "\u25CB", color: "gray" },
|
|
6567
|
+
queued: { icon: "\u25D4", color: "cyan" },
|
|
6568
|
+
in_progress: { icon: "\u25B6", color: "yellow" },
|
|
6569
|
+
blocked: { icon: "\u2298", color: "magenta" },
|
|
6570
|
+
review: { icon: "\u25C6", color: "blue" },
|
|
6571
|
+
failed: { icon: "\u2717", color: "red" },
|
|
6572
|
+
completed: { icon: "\u2713", color: "green" },
|
|
6573
|
+
cancelled: { icon: "\u229D", color: "gray" }
|
|
6574
|
+
};
|
|
6575
|
+
var RUN_STATUS = {
|
|
6576
|
+
running: "yellow",
|
|
6577
|
+
paused: "magenta",
|
|
6578
|
+
completed: "green",
|
|
6579
|
+
failed: "red",
|
|
6580
|
+
deadlocked: "red",
|
|
6581
|
+
idle: "gray"
|
|
6582
|
+
};
|
|
6583
|
+
var PRIORITY = {
|
|
6584
|
+
critical: "red",
|
|
6585
|
+
high: "yellow",
|
|
6586
|
+
medium: "cyan",
|
|
6587
|
+
low: "gray"
|
|
6588
|
+
};
|
|
6589
|
+
var FEED_KIND = {
|
|
6590
|
+
started: { icon: "\u25B6", color: "yellow" },
|
|
6591
|
+
completed: { icon: "\u2713", color: "green" },
|
|
6592
|
+
failed: { icon: "\u2717", color: "red" },
|
|
6593
|
+
retrying: { icon: "\u21BB", color: "yellow" },
|
|
6594
|
+
wave: { icon: "\u224B", color: "magenta" },
|
|
6595
|
+
deadlock: { icon: "\u26A0", color: "red" },
|
|
6596
|
+
verification_failed: { icon: "\u26CA", color: "red" },
|
|
6597
|
+
conflict: { icon: "\u2442", color: "yellow" },
|
|
6598
|
+
split: { icon: "\u22D4", color: "cyan" },
|
|
6599
|
+
supervisor: { icon: "\u2726", color: "magenta" }
|
|
6600
|
+
};
|
|
6601
|
+
function clip(s2, n) {
|
|
6602
|
+
return s2.length > n ? `${s2.slice(0, n - 1)}\u2026` : s2;
|
|
6603
|
+
}
|
|
6604
|
+
function TaskCard({ task }) {
|
|
6605
|
+
const st2 = STATUS3[task.displayStatus] ?? { icon: "?", color: "white" };
|
|
6606
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, width: 26, children: [
|
|
6607
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
6608
|
+
/* @__PURE__ */ jsx(Text, { color: st2.color, bold: true, children: st2.icon }),
|
|
6609
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: task.shortId }),
|
|
6610
|
+
/* @__PURE__ */ jsx(Text, { color: PRIORITY[task.priority] ?? "gray", children: task.priority[0]?.toUpperCase() })
|
|
6611
|
+
] }),
|
|
6612
|
+
/* @__PURE__ */ jsx(Text, { wrap: "truncate-end", children: clip(task.title, 24) }),
|
|
6613
|
+
task.deps.length > 0 ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
6614
|
+
"\u2190 ",
|
|
6615
|
+
clip(task.deps.join(", "), 22)
|
|
6616
|
+
] }) : null,
|
|
6617
|
+
task.agentName ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
6618
|
+
/* @__PURE__ */ jsx(Text, { color: task.displayStatus === "in_progress" ? "yellow" : "gray", children: "\u25CF" }),
|
|
6619
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: clip(task.agentName, 14) }),
|
|
6620
|
+
task.retries > 0 ? /* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
6621
|
+
"\u21BB",
|
|
6622
|
+
task.retries
|
|
6623
|
+
] }) : null
|
|
6624
|
+
] }) : null,
|
|
6625
|
+
task.worktreeBranch ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
6626
|
+
"\u2325 ",
|
|
6627
|
+
clip(task.worktreeBranch, 22)
|
|
6628
|
+
] }) : null
|
|
6629
|
+
] });
|
|
6630
|
+
}
|
|
6631
|
+
function SddBoardOverlay({
|
|
6632
|
+
snapshot,
|
|
6633
|
+
focusColumn = null
|
|
6634
|
+
}) {
|
|
6635
|
+
const byShort = new Map(snapshot.tasks.map((t) => [t.shortId, t]));
|
|
6636
|
+
const p = snapshot.progress;
|
|
6637
|
+
const chains = snapshot.diagnostics?.deadlockChains ?? [];
|
|
6638
|
+
const recentFeed = (snapshot.feed ?? []).slice(0, 6);
|
|
6639
|
+
const focused = typeof focusColumn === "number" && focusColumn >= 0 && focusColumn < snapshot.columns.length ? focusColumn : null;
|
|
6640
|
+
const columns = focused === null ? snapshot.columns : [snapshot.columns[focused]];
|
|
6641
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
|
|
6642
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, marginBottom: 1, children: [
|
|
6643
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "SDD BOARD" }),
|
|
6644
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
6645
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: clip(snapshot.title, 32) }),
|
|
6646
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
6647
|
+
/* @__PURE__ */ jsx(Text, { color: RUN_STATUS[snapshot.status] ?? "white", children: snapshot.status }),
|
|
6648
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
6649
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
6650
|
+
"wave ",
|
|
6651
|
+
snapshot.wave + 1
|
|
6652
|
+
] }),
|
|
6653
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
6654
|
+
/* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
6655
|
+
"\u2713",
|
|
6656
|
+
p.completed
|
|
6657
|
+
] }),
|
|
6658
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "/" }),
|
|
6659
|
+
/* @__PURE__ */ jsx(Text, { children: p.total }),
|
|
6660
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
6661
|
+
"(",
|
|
6662
|
+
p.percentComplete,
|
|
6663
|
+
"%)"
|
|
6664
|
+
] }),
|
|
6665
|
+
p.inProgress > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
6666
|
+
"\u25B6",
|
|
6667
|
+
p.inProgress
|
|
6668
|
+
] }) : null,
|
|
6669
|
+
p.failed > 0 ? /* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
6670
|
+
"\u2717",
|
|
6671
|
+
p.failed
|
|
6672
|
+
] }) : null,
|
|
6673
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 Ctrl+B close \xB7 c clean wt \xB7 z rollback" }),
|
|
6674
|
+
focused !== null ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
6675
|
+
"\u2502 column ",
|
|
6676
|
+
focused + 1,
|
|
6677
|
+
"/",
|
|
6678
|
+
snapshot.columns.length
|
|
6679
|
+
] }) : null
|
|
6680
|
+
] }),
|
|
6681
|
+
chains.length > 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
6682
|
+
/* @__PURE__ */ jsx(Text, { color: "red", bold: true, children: "\u26A0 Deadlock \u2014 blocked by failed tasks:" }),
|
|
6683
|
+
chains.map((c) => /* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
6684
|
+
" ",
|
|
6685
|
+
c.blocked,
|
|
6686
|
+
" \u2190 ",
|
|
6687
|
+
c.blockedBy.join(", ")
|
|
6688
|
+
] }, c.blocked))
|
|
6689
|
+
] }) : null,
|
|
6690
|
+
snapshot.tasks.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No active SDD run. Start one with /sdd execute." }) : /* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 2, children: columns.map((col) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginRight: 1, children: [
|
|
6691
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: col.label }),
|
|
6692
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500".repeat(12) }),
|
|
6693
|
+
col.taskIds.map((sid) => byShort.get(sid)).filter((t) => Boolean(t)).map((t) => /* @__PURE__ */ jsx(TaskCard, { task: t }, t.id))
|
|
6694
|
+
] }, col.label)) }),
|
|
6695
|
+
recentFeed.length > 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
6696
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "Recent activity" }),
|
|
6697
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500".repeat(12) }),
|
|
6698
|
+
recentFeed.map((f, i) => {
|
|
6699
|
+
const k = FEED_KIND[f.kind] ?? FEED_KIND.started;
|
|
6700
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
6701
|
+
/* @__PURE__ */ jsx(Text, { color: k?.color ?? "white", children: k?.icon ?? "\u2022" }),
|
|
6702
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: clip(f.text, 70) })
|
|
6703
|
+
] }, `${f.ts}-${i}`);
|
|
6704
|
+
})
|
|
6705
|
+
] }) : null
|
|
6706
|
+
] });
|
|
6707
|
+
}
|
|
5700
6708
|
var fmtElapsed3 = (ms) => {
|
|
5701
6709
|
const s2 = Math.floor(ms / 1e3);
|
|
5702
6710
|
const m = Math.floor(s2 / 60);
|
|
@@ -5705,7 +6713,7 @@ var fmtElapsed3 = (ms) => {
|
|
|
5705
6713
|
if (m > 0) return `${m}:${String(s2 % 60).padStart(2, "0")}`;
|
|
5706
6714
|
return `${s2}s`;
|
|
5707
6715
|
};
|
|
5708
|
-
var
|
|
6716
|
+
var STATUS4 = {
|
|
5709
6717
|
pending: { icon: "\u25CB", color: "gray" },
|
|
5710
6718
|
ready: { icon: "\u25D0", color: "cyan" },
|
|
5711
6719
|
running: { icon: "\u25CF", color: "yellow" },
|
|
@@ -5715,7 +6723,7 @@ var STATUS3 = {
|
|
|
5715
6723
|
skipped: { icon: "\u2298", color: "gray" }
|
|
5716
6724
|
};
|
|
5717
6725
|
function s(entry) {
|
|
5718
|
-
return
|
|
6726
|
+
return STATUS4[entry] ?? { icon: "?", color: "white" };
|
|
5719
6727
|
}
|
|
5720
6728
|
function PhasePanel({ phases, nowTick }) {
|
|
5721
6729
|
const list = Object.values(phases);
|
|
@@ -6033,7 +7041,7 @@ function GoalPanel({
|
|
|
6033
7041
|
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: coordinatorRunning ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6034
7042
|
/* @__PURE__ */ jsx(Text, { color: "green", children: "\u25CF Coordinator running " }),
|
|
6035
7043
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "[S] Stop coordinator" })
|
|
6036
|
-
] }) : /* @__PURE__ */ jsx(
|
|
7044
|
+
] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "[C] Start coordinator" }) })
|
|
6037
7045
|
] });
|
|
6038
7046
|
}
|
|
6039
7047
|
const displayGoal = goal.refinedGoal || goal.goal;
|
|
@@ -6071,15 +7079,12 @@ function GoalPanel({
|
|
|
6071
7079
|
] }) }),
|
|
6072
7080
|
goal.deliverables.map((d, i) => {
|
|
6073
7081
|
const done = /^\[[x✓]\]|✅|\(done\)/i.test(d);
|
|
6074
|
-
return (
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
d
|
|
6081
|
-
] }) }, i)
|
|
6082
|
-
);
|
|
7082
|
+
return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { ...done ? { color: "green" } : {}, dimColor: !done, children: [
|
|
7083
|
+
" ",
|
|
7084
|
+
done ? "\u2713" : "\u25CB",
|
|
7085
|
+
" ",
|
|
7086
|
+
d
|
|
7087
|
+
] }) }, i);
|
|
6083
7088
|
})
|
|
6084
7089
|
] }),
|
|
6085
7090
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
@@ -6103,7 +7108,7 @@ function GoalPanel({
|
|
|
6103
7108
|
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: coordinatorRunning ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6104
7109
|
/* @__PURE__ */ jsx(Text, { color: "green", children: "\u25CF Coordinator running " }),
|
|
6105
7110
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "[S] Stop coordinator" })
|
|
6106
|
-
] }) : /* @__PURE__ */ jsx(
|
|
7111
|
+
] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "[C] Start coordinator" }) })
|
|
6107
7112
|
] })
|
|
6108
7113
|
] });
|
|
6109
7114
|
}
|
|
@@ -6598,9 +7603,9 @@ var STATUSLINE_MODE_DESCS = {
|
|
|
6598
7603
|
detailed: "Full multi-line statusline (default)"
|
|
6599
7604
|
};
|
|
6600
7605
|
var MAX_ITERATIONS_PRESETS = [100, 200, 500, 1e3, 0];
|
|
6601
|
-
var MAX_CONCURRENT_PRESETS = [1, 3, 5, 10, 25, 50, 0];
|
|
7606
|
+
var MAX_CONCURRENT_PRESETS = [1, 3, 4, 5, 10, 25, 50, 0];
|
|
6602
7607
|
var AUTO_PROCEED_MAX_PRESETS = [10, 25, 50, 100, 250, 0];
|
|
6603
|
-
var ENHANCE_DELAY_PRESETS = [3e4, 45e3, 6e4, 9e4, 12e4];
|
|
7608
|
+
var ENHANCE_DELAY_PRESETS = [15e3, 3e4, 45e3, 6e4, 9e4, 12e4];
|
|
6604
7609
|
var ENHANCE_LANGUAGES = ["original", "english"];
|
|
6605
7610
|
var TOKEN_SAVING_TIERS = ["off", "minimal", "light", "medium", "aggressive"];
|
|
6606
7611
|
var TOKEN_SAVING_TIER_DESCS = {
|
|
@@ -6762,7 +7767,7 @@ function SettingsPicker({
|
|
|
6762
7767
|
{
|
|
6763
7768
|
label: "Refine preview countdown",
|
|
6764
7769
|
value: formatEnhanceDelay(enhanceDelayMs),
|
|
6765
|
-
detail: "Timeout for prompt refinement preview (
|
|
7770
|
+
detail: "Timeout for prompt refinement preview (15s\u2013120s)"
|
|
6766
7771
|
},
|
|
6767
7772
|
{
|
|
6768
7773
|
label: "Refine",
|
|
@@ -6827,8 +7832,8 @@ function SettingsPicker({
|
|
|
6827
7832
|
{ section: "Fleet" },
|
|
6828
7833
|
{
|
|
6829
7834
|
label: "Max concurrent",
|
|
6830
|
-
value: maxConcurrent === 0 ? "
|
|
6831
|
-
detail: "Max subagents (0 =
|
|
7835
|
+
value: maxConcurrent === 0 ? "default" : String(maxConcurrent),
|
|
7836
|
+
detail: "Max subagents (0 = default)"
|
|
6832
7837
|
},
|
|
6833
7838
|
// ── Logging ──
|
|
6834
7839
|
{ section: "Logging" },
|
|
@@ -6892,7 +7897,7 @@ function SettingsPicker({
|
|
|
6892
7897
|
};
|
|
6893
7898
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
6894
7899
|
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u2501\u2501 Settings \u2501\u2501" }),
|
|
6895
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 field \xB7 \u2190/\u2192 change
|
|
7900
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 field \xB7 \u2190/\u2192 change + autosave \xB7 F5 to close" }),
|
|
6896
7901
|
hasAbove ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u2191 ${windowStart} field${windowStart === 1 ? "" : "s"} above` }) : null,
|
|
6897
7902
|
rows.map((row, i) => {
|
|
6898
7903
|
const fieldAtRow = fieldRowIndex.indexOf(i);
|
|
@@ -6916,7 +7921,7 @@ function SettingsPicker({
|
|
|
6916
7921
|
] }, `row-${row.label ?? fieldAtRow}`);
|
|
6917
7922
|
}),
|
|
6918
7923
|
hasBelow ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u2193 ${totalFields - windowEnd} field${totalFields - windowEnd === 1 ? "" : "s"} below` }) : null,
|
|
6919
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Persisted to ~/.wrongstack/config.json" }),
|
|
7924
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: configScope === "project" ? "Persisted to <project>/.wrongstack/config.json" : "Persisted to ~/.wrongstack/config.json" }),
|
|
6920
7925
|
hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
|
|
6921
7926
|
] });
|
|
6922
7927
|
}
|
|
@@ -6926,54 +7931,120 @@ function isChipExpired(meta, now = Date.now()) {
|
|
|
6926
7931
|
return now >= meta.shownAt + meta.expiresIn * 60 * 1e3;
|
|
6927
7932
|
}
|
|
6928
7933
|
var ITEM_DESCRIPTIONS = {
|
|
7934
|
+
version: "WrongStack version chip",
|
|
7935
|
+
state: "Agent run state / thinking spinner",
|
|
7936
|
+
model: "Current provider/model id",
|
|
7937
|
+
tokens: "Input/output token counters",
|
|
7938
|
+
cache: "Prompt cache hit ratio",
|
|
7939
|
+
queue: "Queued prompt count",
|
|
7940
|
+
processes: "Tracked shell/process count",
|
|
7941
|
+
hint: "Transient status hint text",
|
|
7942
|
+
index: "Codebase indexing status",
|
|
7943
|
+
breaker: "Process breaker countdown",
|
|
6929
7944
|
todos: "Todo items (pending/in-progress/done)",
|
|
6930
7945
|
plan: "Plan board items",
|
|
6931
7946
|
tasks: "Task board items",
|
|
6932
7947
|
fleet: "Fleet agent status",
|
|
7948
|
+
fleet_agents: "Per-agent live detail row",
|
|
6933
7949
|
git: "Git branch name",
|
|
6934
7950
|
elapsed: "Session elapsed time",
|
|
6935
7951
|
context: "Context window usage %",
|
|
6936
7952
|
cost: "Token cost estimate",
|
|
6937
7953
|
working_dir: "Current working directory",
|
|
7954
|
+
project: "Project name",
|
|
7955
|
+
yolo: "YOLO permission mode",
|
|
7956
|
+
autonomy: "Autonomy mode",
|
|
7957
|
+
eternal_stage: "Autonomy stage",
|
|
7958
|
+
goal: "Active goal summary",
|
|
7959
|
+
mode: "Active agent mode label",
|
|
7960
|
+
auto_proceed: "Auto-proceed countdown",
|
|
7961
|
+
sessions: "Live session count",
|
|
7962
|
+
tools: "Registered tool count",
|
|
7963
|
+
token_saving: "Token-saving mode indicator",
|
|
6938
7964
|
brain: "Brain arbiter decisions",
|
|
6939
7965
|
mailbox: "Mailbox unread messages",
|
|
6940
7966
|
enhance: "Prompt-enhance countdown",
|
|
6941
|
-
debug_stream: "Stream debug telemetry"
|
|
7967
|
+
debug_stream: "Stream debug telemetry",
|
|
7968
|
+
next_steps: "Next-step auto-submit countdown"
|
|
6942
7969
|
};
|
|
6943
7970
|
var ITEM_LINE = {
|
|
7971
|
+
breaker: 1,
|
|
7972
|
+
cache: 1,
|
|
6944
7973
|
context: 1,
|
|
6945
7974
|
cost: 1,
|
|
7975
|
+
hint: 1,
|
|
7976
|
+
index: 1,
|
|
7977
|
+
model: 1,
|
|
7978
|
+
processes: 1,
|
|
7979
|
+
queue: 1,
|
|
7980
|
+
state: 1,
|
|
7981
|
+
tokens: 1,
|
|
7982
|
+
version: 1,
|
|
7983
|
+
auto_proceed: 2,
|
|
7984
|
+
autonomy: 2,
|
|
6946
7985
|
elapsed: 2,
|
|
6947
|
-
|
|
7986
|
+
eternal_stage: 2,
|
|
6948
7987
|
git: 2,
|
|
7988
|
+
goal: 2,
|
|
7989
|
+
mode: 2,
|
|
7990
|
+
project: 2,
|
|
7991
|
+
sessions: 2,
|
|
7992
|
+
token_saving: 2,
|
|
7993
|
+
tools: 2,
|
|
7994
|
+
working_dir: 2,
|
|
7995
|
+
yolo: 2,
|
|
7996
|
+
brain: 3,
|
|
7997
|
+
debug_stream: 3,
|
|
7998
|
+
enhance: 3,
|
|
7999
|
+
fleet: 3,
|
|
8000
|
+
next_steps: 3,
|
|
6949
8001
|
todos: 3,
|
|
6950
8002
|
plan: 3,
|
|
6951
8003
|
tasks: 3,
|
|
6952
|
-
|
|
6953
|
-
|
|
6954
|
-
mailbox: 3,
|
|
6955
|
-
enhance: 3,
|
|
6956
|
-
debug_stream: 3
|
|
8004
|
+
fleet_agents: 4,
|
|
8005
|
+
mailbox: 4
|
|
6957
8006
|
};
|
|
6958
|
-
Object.keys(ITEM_LINE).length;
|
|
8007
|
+
var STATUSLINE_FIELD_COUNT = Object.keys(ITEM_LINE).length;
|
|
6959
8008
|
var STATUSLINE_ITEMS = [
|
|
6960
8009
|
// Line 1
|
|
8010
|
+
"breaker",
|
|
8011
|
+
"cache",
|
|
6961
8012
|
"context",
|
|
6962
8013
|
"cost",
|
|
8014
|
+
"hint",
|
|
8015
|
+
"index",
|
|
8016
|
+
"model",
|
|
8017
|
+
"processes",
|
|
8018
|
+
"queue",
|
|
8019
|
+
"state",
|
|
8020
|
+
"tokens",
|
|
8021
|
+
"version",
|
|
6963
8022
|
// Line 2
|
|
8023
|
+
"auto_proceed",
|
|
8024
|
+
"autonomy",
|
|
6964
8025
|
"elapsed",
|
|
8026
|
+
"eternal_stage",
|
|
6965
8027
|
"git",
|
|
8028
|
+
"goal",
|
|
8029
|
+
"mode",
|
|
8030
|
+
"project",
|
|
8031
|
+
"sessions",
|
|
8032
|
+
"token_saving",
|
|
8033
|
+
"tools",
|
|
6966
8034
|
"working_dir",
|
|
8035
|
+
"yolo",
|
|
6967
8036
|
// Line 3
|
|
6968
8037
|
"brain",
|
|
6969
8038
|
"debug_stream",
|
|
6970
8039
|
"enhance",
|
|
6971
|
-
"
|
|
8040
|
+
"fleet",
|
|
8041
|
+
"next_steps",
|
|
6972
8042
|
"plan",
|
|
6973
8043
|
"tasks",
|
|
6974
8044
|
"todos",
|
|
6975
8045
|
// Line 4
|
|
6976
|
-
"
|
|
8046
|
+
"fleet_agents",
|
|
8047
|
+
"mailbox"
|
|
6977
8048
|
];
|
|
6978
8049
|
var STREAM_CHIP_KEYS = ["brain", "mailbox", "enhance", "debug_stream"];
|
|
6979
8050
|
function groupByLine(items) {
|
|
@@ -7012,10 +8083,10 @@ function StatuslinePicker({
|
|
|
7012
8083
|
if (hiddenSet.has(item)) return "off";
|
|
7013
8084
|
if (STREAM_CHIP_KEYS.includes(item)) {
|
|
7014
8085
|
const meta = visibleChipsMap.get(item);
|
|
7015
|
-
if (!meta) return "
|
|
8086
|
+
if (!meta) return "auto";
|
|
7016
8087
|
if (meta.expiresIn == null) return "on ";
|
|
7017
8088
|
const remainingMs = meta.shownAt + meta.expiresIn * 6e4 - Date.now();
|
|
7018
|
-
if (remainingMs <= 0) return "
|
|
8089
|
+
if (remainingMs <= 0) return "auto";
|
|
7019
8090
|
const remainingMin = Math.max(1, Math.ceil(remainingMs / 6e4));
|
|
7020
8091
|
return `~${remainingMin}m`;
|
|
7021
8092
|
}
|
|
@@ -7025,8 +8096,8 @@ function StatuslinePicker({
|
|
|
7025
8096
|
if (hiddenSet.has(item)) return "red";
|
|
7026
8097
|
if (STREAM_CHIP_KEYS.includes(item)) {
|
|
7027
8098
|
const meta = visibleChipsMap.get(item);
|
|
7028
|
-
if (!meta) return "
|
|
7029
|
-
if (isChipExpired(meta)) return "
|
|
8099
|
+
if (!meta) return "cyan";
|
|
8100
|
+
if (isChipExpired(meta)) return "cyan";
|
|
7030
8101
|
return "yellow";
|
|
7031
8102
|
}
|
|
7032
8103
|
return "green";
|
|
@@ -7055,7 +8126,7 @@ function StatuslinePicker({
|
|
|
7055
8126
|
] }, `row-${item}`);
|
|
7056
8127
|
}),
|
|
7057
8128
|
hasBelow ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u2193 ${totalFields - windowEnd} item${totalFields - windowEnd === 1 ? "" : "s"} below` }) : null,
|
|
7058
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Changes apply instantly \xB7 persisted to ~/.wrongstack/statusline.json \xB7 auto chips
|
|
8129
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Changes apply instantly \xB7 persisted to ~/.wrongstack/statusline.json \xB7 auto chips show when data exists" }),
|
|
7059
8130
|
hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
|
|
7060
8131
|
] });
|
|
7061
8132
|
}
|
|
@@ -7106,6 +8177,10 @@ function SlashMenu({ query, matches, selected }) {
|
|
|
7106
8177
|
" ",
|
|
7107
8178
|
m.argsHint
|
|
7108
8179
|
] }) : null,
|
|
8180
|
+
m.matchedAlias ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
8181
|
+
" alias /",
|
|
8182
|
+
m.matchedAlias
|
|
8183
|
+
] }) : null,
|
|
7109
8184
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
7110
8185
|
" \u2014 ",
|
|
7111
8186
|
m.description
|
|
@@ -7187,13 +8262,10 @@ function hintsFor(ctx) {
|
|
|
7187
8262
|
}
|
|
7188
8263
|
function KeyHintBar({ context }) {
|
|
7189
8264
|
const hints = hintsFor(context);
|
|
7190
|
-
return /* @__PURE__ */ jsx(Box, { flexDirection: "row", paddingX: 1, children: hints.map((h, i) => (
|
|
7191
|
-
|
|
7192
|
-
/* @__PURE__ */
|
|
7193
|
-
|
|
7194
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ` ${h.label}` })
|
|
7195
|
-
] }, i)
|
|
7196
|
-
)) });
|
|
8265
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "row", paddingX: 1, children: hints.map((h, i) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", marginRight: 2, children: [
|
|
8266
|
+
/* @__PURE__ */ jsx(Text, { color: h.discovery ? theme.monitor.agents : theme.accent, children: h.key }),
|
|
8267
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ` ${h.label}` })
|
|
8268
|
+
] }, i)) });
|
|
7197
8269
|
}
|
|
7198
8270
|
function TodosMonitor({ todos }) {
|
|
7199
8271
|
const { stdout } = useStdout();
|
|
@@ -7426,7 +8498,7 @@ var fmtElapsed6 = (ms) => {
|
|
|
7426
8498
|
if (m > 0) return `${m}:${String(s2 % 60).padStart(2, "0")}`;
|
|
7427
8499
|
return `${s2}s`;
|
|
7428
8500
|
};
|
|
7429
|
-
var
|
|
8501
|
+
var STATUS5 = {
|
|
7430
8502
|
allocating: { icon: "\u25CB", color: "gray" },
|
|
7431
8503
|
active: { icon: "\u25CF", color: "yellow" },
|
|
7432
8504
|
committing: { icon: "\u25D0", color: "cyan" },
|
|
@@ -7436,7 +8508,7 @@ var STATUS4 = {
|
|
|
7436
8508
|
failed: { icon: "\u2717", color: "red" }
|
|
7437
8509
|
};
|
|
7438
8510
|
function st(status) {
|
|
7439
|
-
return
|
|
8511
|
+
return STATUS5[status] ?? { icon: "?", color: "white" };
|
|
7440
8512
|
}
|
|
7441
8513
|
function WorktreePanel({
|
|
7442
8514
|
worktrees,
|
|
@@ -8386,16 +9458,56 @@ function useAutoPhaseEvents(subscribeAutoPhase, dispatch, stateRef) {
|
|
|
8386
9458
|
});
|
|
8387
9459
|
break;
|
|
8388
9460
|
}
|
|
8389
|
-
case "phase.statusChange": {
|
|
9461
|
+
case "phase.statusChange": {
|
|
9462
|
+
const p = payload;
|
|
9463
|
+
const status = p.to === "running" ? "running" : p.to;
|
|
9464
|
+
dispatch({
|
|
9465
|
+
type: "autoPhasePhaseUpdate",
|
|
9466
|
+
phaseId: p.phaseId,
|
|
9467
|
+
name: p.name,
|
|
9468
|
+
status,
|
|
9469
|
+
completedTasks: 0,
|
|
9470
|
+
totalTasks: 0
|
|
9471
|
+
});
|
|
9472
|
+
break;
|
|
9473
|
+
}
|
|
9474
|
+
case "phase.taskStarted": {
|
|
9475
|
+
const p = payload;
|
|
9476
|
+
dispatch({
|
|
9477
|
+
type: "autoPhaseTaskActive",
|
|
9478
|
+
phaseId: p.phaseId,
|
|
9479
|
+
taskId: p.taskId,
|
|
9480
|
+
title: p.taskTitle,
|
|
9481
|
+
agent: p.agentName,
|
|
9482
|
+
active: true
|
|
9483
|
+
});
|
|
9484
|
+
break;
|
|
9485
|
+
}
|
|
9486
|
+
case "phase.taskAssigned": {
|
|
9487
|
+
const p = payload;
|
|
9488
|
+
const active = stateRef.current.autoPhase?.phases[p.phaseId]?.activeTasks?.find(
|
|
9489
|
+
(t) => t.taskId === p.taskId
|
|
9490
|
+
);
|
|
9491
|
+
if (active) {
|
|
9492
|
+
dispatch({
|
|
9493
|
+
type: "autoPhaseTaskActive",
|
|
9494
|
+
phaseId: p.phaseId,
|
|
9495
|
+
taskId: p.taskId,
|
|
9496
|
+
title: active.title,
|
|
9497
|
+
agent: p.agentName,
|
|
9498
|
+
active: true
|
|
9499
|
+
});
|
|
9500
|
+
}
|
|
9501
|
+
break;
|
|
9502
|
+
}
|
|
9503
|
+
case "phase.taskFailed": {
|
|
8390
9504
|
const p = payload;
|
|
8391
|
-
const status = p.to === "running" ? "running" : p.to;
|
|
8392
9505
|
dispatch({
|
|
8393
|
-
type: "
|
|
9506
|
+
type: "autoPhaseTaskActive",
|
|
8394
9507
|
phaseId: p.phaseId,
|
|
8395
|
-
|
|
8396
|
-
|
|
8397
|
-
|
|
8398
|
-
totalTasks: 0
|
|
9508
|
+
taskId: p.taskId,
|
|
9509
|
+
title: "",
|
|
9510
|
+
active: false
|
|
8399
9511
|
});
|
|
8400
9512
|
break;
|
|
8401
9513
|
}
|
|
@@ -8412,6 +9524,13 @@ function useAutoPhaseEvents(subscribeAutoPhase, dispatch, stateRef) {
|
|
|
8412
9524
|
totalTasks: existing.totalTasks
|
|
8413
9525
|
});
|
|
8414
9526
|
}
|
|
9527
|
+
dispatch({
|
|
9528
|
+
type: "autoPhaseTaskActive",
|
|
9529
|
+
phaseId: p.phaseId,
|
|
9530
|
+
taskId: p.taskId,
|
|
9531
|
+
title: "",
|
|
9532
|
+
active: false
|
|
9533
|
+
});
|
|
8415
9534
|
break;
|
|
8416
9535
|
}
|
|
8417
9536
|
case "autonomous.tick": {
|
|
@@ -8430,6 +9549,11 @@ function useAutoPhaseEvents(subscribeAutoPhase, dispatch, stateRef) {
|
|
|
8430
9549
|
dispatch({ type: "autoPhaseReset" });
|
|
8431
9550
|
break;
|
|
8432
9551
|
}
|
|
9552
|
+
case "sdd.board.snapshot": {
|
|
9553
|
+
const p = payload;
|
|
9554
|
+
if (p.snapshot) dispatch({ type: "sddBoardSnapshot", snapshot: p.snapshot });
|
|
9555
|
+
break;
|
|
9556
|
+
}
|
|
8433
9557
|
case "worktree.allocated": {
|
|
8434
9558
|
const p = payload;
|
|
8435
9559
|
dispatch({
|
|
@@ -8713,6 +9837,79 @@ function oneLine(s2, max) {
|
|
|
8713
9837
|
return collapsed.length <= max ? collapsed : `${collapsed.slice(0, max - 1)}\u2026`;
|
|
8714
9838
|
}
|
|
8715
9839
|
|
|
9840
|
+
// src/slash-command-search.ts
|
|
9841
|
+
var CATEGORY_ORDER = ["Run", "Session", "Inspect", "Agent", "Config", "App"];
|
|
9842
|
+
function buildSlashCommandMatches(entries, rawQuery) {
|
|
9843
|
+
const query = normalizeSlashQuery(rawQuery);
|
|
9844
|
+
const matches = [];
|
|
9845
|
+
for (const entry of entries) {
|
|
9846
|
+
const ranked = rankSlashCommand(entry, query);
|
|
9847
|
+
if (!ranked) continue;
|
|
9848
|
+
matches.push(ranked);
|
|
9849
|
+
}
|
|
9850
|
+
return matches.sort((a, b) => {
|
|
9851
|
+
if (a.rank !== b.rank) return a.rank - b.rank;
|
|
9852
|
+
const catDiff = CATEGORY_ORDER.indexOf(a.category) - CATEGORY_ORDER.indexOf(b.category);
|
|
9853
|
+
if (catDiff !== 0) return catDiff;
|
|
9854
|
+
return a.name.localeCompare(b.name);
|
|
9855
|
+
}).map(({ rank: _rank, ...match }) => match);
|
|
9856
|
+
}
|
|
9857
|
+
function normalizeSlashQuery(raw) {
|
|
9858
|
+
return raw.trim().replace(/^\/+/, "").toLowerCase();
|
|
9859
|
+
}
|
|
9860
|
+
function rankSlashCommand(entry, query) {
|
|
9861
|
+
const { cmd, owner } = entry;
|
|
9862
|
+
if (query === "" && cmd.hidden) return null;
|
|
9863
|
+
const name = displayName(entry);
|
|
9864
|
+
const lowerName = name.toLowerCase();
|
|
9865
|
+
const aliases = aliasCandidates(entry);
|
|
9866
|
+
const category = cmd.category ?? "App";
|
|
9867
|
+
let rank = null;
|
|
9868
|
+
let matchedAlias;
|
|
9869
|
+
if (query === "") {
|
|
9870
|
+
rank = 100;
|
|
9871
|
+
} else if (lowerName === query) {
|
|
9872
|
+
rank = 0;
|
|
9873
|
+
} else if (aliases.find((alias) => alias.toLowerCase() === query)) {
|
|
9874
|
+
rank = 5;
|
|
9875
|
+
matchedAlias = aliases.find((alias) => alias.toLowerCase() === query);
|
|
9876
|
+
} else if (lowerName.startsWith(query)) {
|
|
9877
|
+
rank = 10;
|
|
9878
|
+
} else {
|
|
9879
|
+
const prefixAlias = aliases.find((alias) => alias.toLowerCase().startsWith(query));
|
|
9880
|
+
if (prefixAlias) {
|
|
9881
|
+
rank = 20;
|
|
9882
|
+
matchedAlias = prefixAlias;
|
|
9883
|
+
}
|
|
9884
|
+
}
|
|
9885
|
+
if (rank == null) return null;
|
|
9886
|
+
return {
|
|
9887
|
+
name,
|
|
9888
|
+
description: cmd.description,
|
|
9889
|
+
argsHint: cmd.argsHint,
|
|
9890
|
+
isBuiltin: owner === "core",
|
|
9891
|
+
category,
|
|
9892
|
+
...matchedAlias ? { matchedAlias } : {},
|
|
9893
|
+
rank
|
|
9894
|
+
};
|
|
9895
|
+
}
|
|
9896
|
+
function displayName({ cmd, owner, fullName }) {
|
|
9897
|
+
if (owner === "core") return cmd.name;
|
|
9898
|
+
return fullName.includes(":") ? fullName : cmd.name;
|
|
9899
|
+
}
|
|
9900
|
+
function aliasCandidates({ cmd, owner, fullName }) {
|
|
9901
|
+
const aliases = cmd.aliases ?? [];
|
|
9902
|
+
if (owner === "core") return aliases;
|
|
9903
|
+
const out = [...aliases];
|
|
9904
|
+
for (const alias of aliases) {
|
|
9905
|
+
out.push(`${owner}:${alias}`);
|
|
9906
|
+
}
|
|
9907
|
+
if (fullName.includes(":")) {
|
|
9908
|
+
return out.filter((alias) => alias.includes(":"));
|
|
9909
|
+
}
|
|
9910
|
+
return out;
|
|
9911
|
+
}
|
|
9912
|
+
|
|
8716
9913
|
// src/steering-preamble.ts
|
|
8717
9914
|
function buildSteeringPreamble(snapshot, newDirection) {
|
|
8718
9915
|
const lines = ["[STEERING \u2014 I pressed Esc to interrupt you mid-task on purpose.", ""];
|
|
@@ -8764,10 +9961,15 @@ function closePanels(state) {
|
|
|
8764
9961
|
projectPicker: { ...state.projectPicker, open: false },
|
|
8765
9962
|
fKeyPicker: { ...state.fKeyPicker, open: false },
|
|
8766
9963
|
autoPhase: state.autoPhase ? { ...state.autoPhase, monitorOpen: false } : state.autoPhase,
|
|
9964
|
+
sddBoard: state.sddBoard ? { ...state.sddBoard, monitorOpen: false } : state.sddBoard,
|
|
8767
9965
|
worktreeMonitorOpen: false,
|
|
8768
9966
|
coordinator: { ...state.coordinator, monitorOpen: false }
|
|
8769
9967
|
};
|
|
8770
9968
|
}
|
|
9969
|
+
function clampContextLoad(load) {
|
|
9970
|
+
if (!Number.isFinite(load)) return 0;
|
|
9971
|
+
return Math.max(0, Math.min(1, load));
|
|
9972
|
+
}
|
|
8771
9973
|
var MAX_TOOL_STREAM_RETAINED_CHARS = 1e5;
|
|
8772
9974
|
var MAX_RETAINED_INPUT_CHARS = 2048;
|
|
8773
9975
|
var MAX_RETAINED_INPUT_DEPTH = 4;
|
|
@@ -9149,12 +10351,26 @@ function reducer(state, action) {
|
|
|
9149
10351
|
return {
|
|
9150
10352
|
...state,
|
|
9151
10353
|
...closePanels(state),
|
|
9152
|
-
resumePicker: {
|
|
10354
|
+
resumePicker: {
|
|
10355
|
+
open: true,
|
|
10356
|
+
sessions: action.sessions,
|
|
10357
|
+
selected: 0,
|
|
10358
|
+
busy: false,
|
|
10359
|
+
hint: void 0,
|
|
10360
|
+
error: void 0
|
|
10361
|
+
}
|
|
9153
10362
|
};
|
|
9154
10363
|
case "resumePickerClose":
|
|
9155
10364
|
return {
|
|
9156
10365
|
...state,
|
|
9157
|
-
resumePicker: {
|
|
10366
|
+
resumePicker: {
|
|
10367
|
+
open: false,
|
|
10368
|
+
sessions: [],
|
|
10369
|
+
selected: 0,
|
|
10370
|
+
busy: false,
|
|
10371
|
+
hint: void 0,
|
|
10372
|
+
error: void 0
|
|
10373
|
+
}
|
|
9158
10374
|
};
|
|
9159
10375
|
case "resumePickerMove": {
|
|
9160
10376
|
const nr = state.resumePicker.sessions.length;
|
|
@@ -9173,7 +10389,12 @@ function reducer(state, action) {
|
|
|
9173
10389
|
const maxBannerId = banners.length > 0 ? Math.max(...banners.map((b) => b.id)) : 0;
|
|
9174
10390
|
const shifted = action.entries.map((e, i) => ({ ...e, id: maxBannerId + 1 + i }));
|
|
9175
10391
|
const nextId = maxBannerId + 1 + shifted.length;
|
|
9176
|
-
return {
|
|
10392
|
+
return {
|
|
10393
|
+
...state,
|
|
10394
|
+
entries: [...banners, ...shifted],
|
|
10395
|
+
nextId,
|
|
10396
|
+
historyGen: state.historyGen + 1
|
|
10397
|
+
};
|
|
9177
10398
|
}
|
|
9178
10399
|
case "settingsOpen":
|
|
9179
10400
|
return {
|
|
@@ -9244,121 +10465,295 @@ function reducer(state, action) {
|
|
|
9244
10465
|
const i = SETTINGS_MODES.indexOf(sp.mode);
|
|
9245
10466
|
const base = i < 0 ? 0 : i;
|
|
9246
10467
|
const next = (base + action.delta + SETTINGS_MODES.length) % SETTINGS_MODES.length;
|
|
9247
|
-
return {
|
|
10468
|
+
return {
|
|
10469
|
+
...state,
|
|
10470
|
+
settingsPicker: { ...sp, mode: expectDefined$1(SETTINGS_MODES[next]), hint: void 0 }
|
|
10471
|
+
};
|
|
9248
10472
|
}
|
|
9249
10473
|
if (f === 1) {
|
|
9250
10474
|
const j = DELAY_PRESETS_MS.indexOf(sp.delayMs);
|
|
9251
10475
|
const base = j < 0 ? 0 : j;
|
|
9252
10476
|
const next = (base + action.delta + DELAY_PRESETS_MS.length) % DELAY_PRESETS_MS.length;
|
|
9253
|
-
return {
|
|
10477
|
+
return {
|
|
10478
|
+
...state,
|
|
10479
|
+
settingsPicker: {
|
|
10480
|
+
...sp,
|
|
10481
|
+
delayMs: expectDefined$1(DELAY_PRESETS_MS[next]),
|
|
10482
|
+
hint: void 0
|
|
10483
|
+
}
|
|
10484
|
+
};
|
|
9254
10485
|
}
|
|
9255
|
-
if (f === 2)
|
|
10486
|
+
if (f === 2)
|
|
10487
|
+
return {
|
|
10488
|
+
...state,
|
|
10489
|
+
settingsPicker: { ...sp, titleAnimation: !sp.titleAnimation, hint: void 0 }
|
|
10490
|
+
};
|
|
9256
10491
|
if (f === 3) return { ...state, settingsPicker: { ...sp, yolo: !sp.yolo, hint: void 0 } };
|
|
9257
|
-
if (f === 4)
|
|
9258
|
-
|
|
9259
|
-
|
|
9260
|
-
|
|
9261
|
-
|
|
9262
|
-
if (f ===
|
|
9263
|
-
|
|
9264
|
-
if (f ===
|
|
9265
|
-
|
|
10492
|
+
if (f === 4)
|
|
10493
|
+
return {
|
|
10494
|
+
...state,
|
|
10495
|
+
settingsPicker: { ...sp, streamFleet: !sp.streamFleet, hint: void 0 }
|
|
10496
|
+
};
|
|
10497
|
+
if (f === 5)
|
|
10498
|
+
return { ...state, settingsPicker: { ...sp, chime: !sp.chime, hint: void 0 } };
|
|
10499
|
+
if (f === 6)
|
|
10500
|
+
return {
|
|
10501
|
+
...state,
|
|
10502
|
+
settingsPicker: { ...sp, confirmExit: !sp.confirmExit, hint: void 0 }
|
|
10503
|
+
};
|
|
10504
|
+
if (f === 7)
|
|
10505
|
+
return {
|
|
10506
|
+
...state,
|
|
10507
|
+
settingsPicker: { ...sp, nextPrediction: !sp.nextPrediction, hint: void 0 }
|
|
10508
|
+
};
|
|
10509
|
+
if (f === 8)
|
|
10510
|
+
return { ...state, settingsPicker: { ...sp, featureMcp: !sp.featureMcp, hint: bootHint } };
|
|
10511
|
+
if (f === 9)
|
|
10512
|
+
return {
|
|
10513
|
+
...state,
|
|
10514
|
+
settingsPicker: { ...sp, featurePlugins: !sp.featurePlugins, hint: bootHint }
|
|
10515
|
+
};
|
|
10516
|
+
if (f === 10)
|
|
10517
|
+
return {
|
|
10518
|
+
...state,
|
|
10519
|
+
settingsPicker: { ...sp, featureMemory: !sp.featureMemory, hint: bootHint }
|
|
10520
|
+
};
|
|
10521
|
+
if (f === 11)
|
|
10522
|
+
return {
|
|
10523
|
+
...state,
|
|
10524
|
+
settingsPicker: { ...sp, featureSkills: !sp.featureSkills, hint: bootHint }
|
|
10525
|
+
};
|
|
10526
|
+
if (f === 12)
|
|
10527
|
+
return {
|
|
10528
|
+
...state,
|
|
10529
|
+
settingsPicker: {
|
|
10530
|
+
...sp,
|
|
10531
|
+
featureModelsRegistry: !sp.featureModelsRegistry,
|
|
10532
|
+
hint: bootHint
|
|
10533
|
+
}
|
|
10534
|
+
};
|
|
9266
10535
|
if (f === 13) {
|
|
9267
|
-
const i = TOKEN_SAVING_TIERS.indexOf(
|
|
10536
|
+
const i = TOKEN_SAVING_TIERS.indexOf(
|
|
10537
|
+
sp.tokenSavingTier
|
|
10538
|
+
);
|
|
9268
10539
|
const base = i < 0 ? 0 : i;
|
|
9269
10540
|
const next = (base + action.delta + TOKEN_SAVING_TIERS.length) % TOKEN_SAVING_TIERS.length;
|
|
9270
|
-
return {
|
|
10541
|
+
return {
|
|
10542
|
+
...state,
|
|
10543
|
+
settingsPicker: {
|
|
10544
|
+
...sp,
|
|
10545
|
+
tokenSavingTier: TOKEN_SAVING_TIERS[next] ?? "off",
|
|
10546
|
+
hint: bootHint
|
|
10547
|
+
}
|
|
10548
|
+
};
|
|
9271
10549
|
}
|
|
9272
|
-
if (f === 14)
|
|
10550
|
+
if (f === 14)
|
|
10551
|
+
return {
|
|
10552
|
+
...state,
|
|
10553
|
+
settingsPicker: {
|
|
10554
|
+
...sp,
|
|
10555
|
+
allowOutsideProjectRoot: !sp.allowOutsideProjectRoot,
|
|
10556
|
+
hint: void 0
|
|
10557
|
+
}
|
|
10558
|
+
};
|
|
9273
10559
|
if (f === 15) {
|
|
9274
10560
|
const j = MAX_ITERATIONS_PRESETS.indexOf(sp.maxIterations);
|
|
9275
10561
|
const base = j < 0 ? 0 : j;
|
|
9276
10562
|
const next = (base + action.delta + MAX_ITERATIONS_PRESETS.length) % MAX_ITERATIONS_PRESETS.length;
|
|
9277
|
-
return {
|
|
10563
|
+
return {
|
|
10564
|
+
...state,
|
|
10565
|
+
settingsPicker: {
|
|
10566
|
+
...sp,
|
|
10567
|
+
maxIterations: expectDefined$1(MAX_ITERATIONS_PRESETS[next]),
|
|
10568
|
+
hint: void 0
|
|
10569
|
+
}
|
|
10570
|
+
};
|
|
9278
10571
|
}
|
|
9279
10572
|
if (f === 16) {
|
|
9280
10573
|
const aj = AUTO_PROCEED_MAX_PRESETS.indexOf(sp.autoProceedMaxIterations);
|
|
9281
10574
|
const abase = aj < 0 ? 0 : aj;
|
|
9282
10575
|
const anext = (abase + action.delta + AUTO_PROCEED_MAX_PRESETS.length) % AUTO_PROCEED_MAX_PRESETS.length;
|
|
9283
|
-
return {
|
|
10576
|
+
return {
|
|
10577
|
+
...state,
|
|
10578
|
+
settingsPicker: {
|
|
10579
|
+
...sp,
|
|
10580
|
+
autoProceedMaxIterations: expectDefined$1(AUTO_PROCEED_MAX_PRESETS[anext]),
|
|
10581
|
+
hint: void 0
|
|
10582
|
+
}
|
|
10583
|
+
};
|
|
9284
10584
|
}
|
|
9285
10585
|
if (f === 17) {
|
|
9286
10586
|
const ej = ENHANCE_DELAY_PRESETS.indexOf(sp.enhanceDelayMs);
|
|
9287
10587
|
const ebase = ej < 0 ? 0 : ej;
|
|
9288
10588
|
const enext = (ebase + action.delta + ENHANCE_DELAY_PRESETS.length) % ENHANCE_DELAY_PRESETS.length;
|
|
9289
|
-
return {
|
|
10589
|
+
return {
|
|
10590
|
+
...state,
|
|
10591
|
+
settingsPicker: {
|
|
10592
|
+
...sp,
|
|
10593
|
+
enhanceDelayMs: expectDefined$1(ENHANCE_DELAY_PRESETS[enext]),
|
|
10594
|
+
hint: void 0
|
|
10595
|
+
}
|
|
10596
|
+
};
|
|
9290
10597
|
}
|
|
9291
|
-
if (f === 18)
|
|
10598
|
+
if (f === 18)
|
|
10599
|
+
return {
|
|
10600
|
+
...state,
|
|
10601
|
+
settingsPicker: { ...sp, enhanceEnabled: !sp.enhanceEnabled, hint: void 0 }
|
|
10602
|
+
};
|
|
9292
10603
|
if (f === 19) {
|
|
9293
10604
|
const i = ENHANCE_LANGUAGES.indexOf(sp.enhanceLanguage);
|
|
9294
10605
|
const base = i < 0 ? 0 : i;
|
|
9295
10606
|
const next = (base + action.delta + ENHANCE_LANGUAGES.length) % ENHANCE_LANGUAGES.length;
|
|
9296
|
-
return {
|
|
10607
|
+
return {
|
|
10608
|
+
...state,
|
|
10609
|
+
settingsPicker: {
|
|
10610
|
+
...sp,
|
|
10611
|
+
enhanceLanguage: expectDefined$1(ENHANCE_LANGUAGES[next]),
|
|
10612
|
+
hint: void 0
|
|
10613
|
+
}
|
|
10614
|
+
};
|
|
9297
10615
|
}
|
|
9298
|
-
if (f === 20)
|
|
10616
|
+
if (f === 20)
|
|
10617
|
+
return {
|
|
10618
|
+
...state,
|
|
10619
|
+
settingsPicker: { ...sp, indexOnStart: !sp.indexOnStart, hint: bootHint }
|
|
10620
|
+
};
|
|
9299
10621
|
if (f === 21) return state;
|
|
9300
10622
|
if (f === 22) {
|
|
9301
10623
|
const i = REASONING_MODES.indexOf(sp.reasoningMode);
|
|
9302
10624
|
const base = i < 0 ? 0 : i;
|
|
9303
10625
|
const next = (base + action.delta + REASONING_MODES.length) % REASONING_MODES.length;
|
|
9304
|
-
return {
|
|
10626
|
+
return {
|
|
10627
|
+
...state,
|
|
10628
|
+
settingsPicker: {
|
|
10629
|
+
...sp,
|
|
10630
|
+
reasoningMode: expectDefined$1(REASONING_MODES[next]),
|
|
10631
|
+
hint: void 0
|
|
10632
|
+
}
|
|
10633
|
+
};
|
|
9305
10634
|
}
|
|
9306
10635
|
if (f === 23) {
|
|
9307
|
-
const i = REASONING_EFFORTS.indexOf(
|
|
10636
|
+
const i = REASONING_EFFORTS.indexOf(
|
|
10637
|
+
sp.reasoningEffort
|
|
10638
|
+
);
|
|
9308
10639
|
const base = i < 0 ? REASONING_EFFORTS.indexOf("high") : i;
|
|
9309
10640
|
const next = (base + action.delta + REASONING_EFFORTS.length) % REASONING_EFFORTS.length;
|
|
9310
|
-
return {
|
|
10641
|
+
return {
|
|
10642
|
+
...state,
|
|
10643
|
+
settingsPicker: {
|
|
10644
|
+
...sp,
|
|
10645
|
+
reasoningEffort: expectDefined$1(REASONING_EFFORTS[next]),
|
|
10646
|
+
hint: void 0
|
|
10647
|
+
}
|
|
10648
|
+
};
|
|
9311
10649
|
}
|
|
9312
|
-
if (f === 24)
|
|
10650
|
+
if (f === 24)
|
|
10651
|
+
return {
|
|
10652
|
+
...state,
|
|
10653
|
+
settingsPicker: { ...sp, reasoningPreserve: !sp.reasoningPreserve, hint: void 0 }
|
|
10654
|
+
};
|
|
9313
10655
|
if (f === 25) {
|
|
9314
10656
|
const i = CACHE_TTLS.indexOf(sp.cacheTtl);
|
|
9315
10657
|
const base = i < 0 ? 0 : i;
|
|
9316
10658
|
const next = (base + action.delta + CACHE_TTLS.length) % CACHE_TTLS.length;
|
|
9317
|
-
return {
|
|
10659
|
+
return {
|
|
10660
|
+
...state,
|
|
10661
|
+
settingsPicker: { ...sp, cacheTtl: expectDefined$1(CACHE_TTLS[next]), hint: void 0 }
|
|
10662
|
+
};
|
|
9318
10663
|
}
|
|
9319
|
-
if (f === 26)
|
|
10664
|
+
if (f === 26)
|
|
10665
|
+
return {
|
|
10666
|
+
...state,
|
|
10667
|
+
settingsPicker: { ...sp, contextAutoCompact: !sp.contextAutoCompact, hint: void 0 }
|
|
10668
|
+
};
|
|
9320
10669
|
if (f === 27) {
|
|
9321
10670
|
const i = COMPACTOR_STRATEGIES.indexOf(sp.contextStrategy);
|
|
9322
10671
|
const base = i < 0 ? 0 : i;
|
|
9323
10672
|
const next = (base + action.delta + COMPACTOR_STRATEGIES.length) % COMPACTOR_STRATEGIES.length;
|
|
9324
|
-
return {
|
|
10673
|
+
return {
|
|
10674
|
+
...state,
|
|
10675
|
+
settingsPicker: {
|
|
10676
|
+
...sp,
|
|
10677
|
+
contextStrategy: expectDefined$1(COMPACTOR_STRATEGIES[next]),
|
|
10678
|
+
hint: bootHint
|
|
10679
|
+
}
|
|
10680
|
+
};
|
|
9325
10681
|
}
|
|
9326
10682
|
if (f === 28) {
|
|
9327
10683
|
const i = CONTEXT_MODES.indexOf(sp.contextMode);
|
|
9328
10684
|
const base = i < 0 ? 0 : i;
|
|
9329
10685
|
const next = (base + action.delta + CONTEXT_MODES.length) % CONTEXT_MODES.length;
|
|
9330
|
-
return {
|
|
10686
|
+
return {
|
|
10687
|
+
...state,
|
|
10688
|
+
settingsPicker: {
|
|
10689
|
+
...sp,
|
|
10690
|
+
contextMode: expectDefined$1(CONTEXT_MODES[next]),
|
|
10691
|
+
hint: bootHint
|
|
10692
|
+
}
|
|
10693
|
+
};
|
|
9331
10694
|
}
|
|
9332
10695
|
if (f === 29) {
|
|
9333
10696
|
const j = MAX_CONCURRENT_PRESETS.indexOf(sp.maxConcurrent);
|
|
9334
10697
|
const base = j < 0 ? 0 : j;
|
|
9335
10698
|
const next = (base + action.delta + MAX_CONCURRENT_PRESETS.length) % MAX_CONCURRENT_PRESETS.length;
|
|
9336
|
-
|
|
10699
|
+
const maxConcurrent = expectDefined$1(MAX_CONCURRENT_PRESETS[next]);
|
|
10700
|
+
return {
|
|
10701
|
+
...state,
|
|
10702
|
+
settingsPicker: {
|
|
10703
|
+
...sp,
|
|
10704
|
+
maxConcurrent,
|
|
10705
|
+
hint: maxConcurrent === 0 ? bootHint : void 0
|
|
10706
|
+
}
|
|
10707
|
+
};
|
|
9337
10708
|
}
|
|
9338
10709
|
if (f === 30) {
|
|
9339
10710
|
const i = LOG_LEVELS.indexOf(sp.logLevel);
|
|
9340
10711
|
const base = i < 0 ? 0 : i;
|
|
9341
10712
|
const next = (base + action.delta + LOG_LEVELS.length) % LOG_LEVELS.length;
|
|
9342
|
-
return {
|
|
10713
|
+
return {
|
|
10714
|
+
...state,
|
|
10715
|
+
settingsPicker: { ...sp, logLevel: expectDefined$1(LOG_LEVELS[next]), hint: void 0 }
|
|
10716
|
+
};
|
|
9343
10717
|
}
|
|
9344
10718
|
if (f === 31) {
|
|
9345
10719
|
const i = AUDIT_LEVELS.indexOf(sp.auditLevel);
|
|
9346
10720
|
const base = i < 0 ? 0 : i;
|
|
9347
10721
|
const next = (base + action.delta + AUDIT_LEVELS.length) % AUDIT_LEVELS.length;
|
|
9348
|
-
return {
|
|
10722
|
+
return {
|
|
10723
|
+
...state,
|
|
10724
|
+
settingsPicker: { ...sp, auditLevel: expectDefined$1(AUDIT_LEVELS[next]), hint: void 0 }
|
|
10725
|
+
};
|
|
9349
10726
|
}
|
|
9350
|
-
if (f === 32)
|
|
10727
|
+
if (f === 32)
|
|
10728
|
+
return {
|
|
10729
|
+
...state,
|
|
10730
|
+
settingsPicker: { ...sp, debugStream: !sp.debugStream, hint: void 0 }
|
|
10731
|
+
};
|
|
9351
10732
|
if (f === 33) {
|
|
9352
10733
|
const i = STATUSLINE_MODES.indexOf(sp.statuslineMode);
|
|
9353
10734
|
const base = i < 0 ? STATUSLINE_MODES.indexOf("detailed") : i;
|
|
9354
10735
|
const next = (base + action.delta + STATUSLINE_MODES.length) % STATUSLINE_MODES.length;
|
|
9355
|
-
return {
|
|
10736
|
+
return {
|
|
10737
|
+
...state,
|
|
10738
|
+
settingsPicker: {
|
|
10739
|
+
...sp,
|
|
10740
|
+
statuslineMode: expectDefined$1(STATUSLINE_MODES[next]),
|
|
10741
|
+
hint: void 0
|
|
10742
|
+
}
|
|
10743
|
+
};
|
|
9356
10744
|
}
|
|
9357
10745
|
if (f === 34) {
|
|
9358
10746
|
const i = CONFIG_SCOPES.indexOf(sp.configScope);
|
|
9359
10747
|
const base = i < 0 ? 0 : i;
|
|
9360
10748
|
const next = (base + action.delta + CONFIG_SCOPES.length) % CONFIG_SCOPES.length;
|
|
9361
|
-
return {
|
|
10749
|
+
return {
|
|
10750
|
+
...state,
|
|
10751
|
+
settingsPicker: {
|
|
10752
|
+
...sp,
|
|
10753
|
+
configScope: expectDefined$1(CONFIG_SCOPES[next]),
|
|
10754
|
+
hint: void 0
|
|
10755
|
+
}
|
|
10756
|
+
};
|
|
9362
10757
|
}
|
|
9363
10758
|
return state;
|
|
9364
10759
|
}
|
|
@@ -9369,17 +10764,29 @@ function reducer(state, action) {
|
|
|
9369
10764
|
return {
|
|
9370
10765
|
...state,
|
|
9371
10766
|
...closePanels(state),
|
|
9372
|
-
statuslinePicker: {
|
|
10767
|
+
statuslinePicker: {
|
|
10768
|
+
open: true,
|
|
10769
|
+
field: 0,
|
|
10770
|
+
hiddenItems: action.hiddenItems,
|
|
10771
|
+
visibleChips: state.statuslinePicker.visibleChips,
|
|
10772
|
+
hint: void 0
|
|
10773
|
+
}
|
|
9373
10774
|
};
|
|
9374
10775
|
case "statuslineClose":
|
|
9375
|
-
return {
|
|
10776
|
+
return {
|
|
10777
|
+
...state,
|
|
10778
|
+
statuslinePicker: { ...state.statuslinePicker, open: false, hint: void 0 }
|
|
10779
|
+
};
|
|
9376
10780
|
case "statuslineFieldMove": {
|
|
9377
|
-
const totalFields =
|
|
10781
|
+
const totalFields = STATUSLINE_FIELD_COUNT;
|
|
9378
10782
|
const next = (state.statuslinePicker.field + action.delta + totalFields) % totalFields;
|
|
9379
|
-
return {
|
|
10783
|
+
return {
|
|
10784
|
+
...state,
|
|
10785
|
+
statuslinePicker: { ...state.statuslinePicker, field: next, hint: void 0 }
|
|
10786
|
+
};
|
|
9380
10787
|
}
|
|
9381
10788
|
case "statuslineFieldSet": {
|
|
9382
|
-
const totalFields =
|
|
10789
|
+
const totalFields = STATUSLINE_FIELD_COUNT;
|
|
9383
10790
|
const field = action.field >= 0 && action.field < totalFields ? action.field : 0;
|
|
9384
10791
|
return { ...state, statuslinePicker: { ...state.statuslinePicker, field, hint: void 0 } };
|
|
9385
10792
|
}
|
|
@@ -9391,7 +10798,10 @@ function reducer(state, action) {
|
|
|
9391
10798
|
} else {
|
|
9392
10799
|
hiddenSet.add(action.item);
|
|
9393
10800
|
}
|
|
9394
|
-
return {
|
|
10801
|
+
return {
|
|
10802
|
+
...state,
|
|
10803
|
+
statuslinePicker: { ...cur, hiddenItems: [...hiddenSet] }
|
|
10804
|
+
};
|
|
9395
10805
|
}
|
|
9396
10806
|
case "statuslineHint":
|
|
9397
10807
|
return { ...state, statuslinePicker: { ...state.statuslinePicker, hint: action.text } };
|
|
@@ -9437,7 +10847,14 @@ function reducer(state, action) {
|
|
|
9437
10847
|
case "projectPickerClose":
|
|
9438
10848
|
return {
|
|
9439
10849
|
...state,
|
|
9440
|
-
projectPicker: {
|
|
10850
|
+
projectPicker: {
|
|
10851
|
+
open: false,
|
|
10852
|
+
allItems: [],
|
|
10853
|
+
items: [],
|
|
10854
|
+
selected: 0,
|
|
10855
|
+
filter: "",
|
|
10856
|
+
hint: void 0
|
|
10857
|
+
}
|
|
9441
10858
|
};
|
|
9442
10859
|
case "projectPickerMove": {
|
|
9443
10860
|
const cur = state.projectPicker;
|
|
@@ -9705,13 +11122,14 @@ function reducer(state, action) {
|
|
|
9705
11122
|
case "fleetCtxPct": {
|
|
9706
11123
|
const cur = state.fleet[action.id];
|
|
9707
11124
|
if (!cur) return state;
|
|
11125
|
+
const ctxPct = clampContextLoad(action.load);
|
|
9708
11126
|
return {
|
|
9709
11127
|
...state,
|
|
9710
11128
|
fleet: {
|
|
9711
11129
|
...state.fleet,
|
|
9712
11130
|
[action.id]: {
|
|
9713
11131
|
...cur,
|
|
9714
|
-
ctxPct
|
|
11132
|
+
ctxPct,
|
|
9715
11133
|
ctxTokens: action.tokens,
|
|
9716
11134
|
ctxMaxTokens: action.maxContext,
|
|
9717
11135
|
ctxCost: action.ctxCost,
|
|
@@ -9794,11 +11212,12 @@ function reducer(state, action) {
|
|
|
9794
11212
|
};
|
|
9795
11213
|
}
|
|
9796
11214
|
case "leaderCtxPct": {
|
|
11215
|
+
const ctxPct = clampContextLoad(action.load);
|
|
9797
11216
|
return {
|
|
9798
11217
|
...state,
|
|
9799
11218
|
leader: {
|
|
9800
11219
|
...state.leader,
|
|
9801
|
-
ctxPct
|
|
11220
|
+
ctxPct,
|
|
9802
11221
|
ctxTokens: action.tokens,
|
|
9803
11222
|
ctxMaxTokens: action.maxContext,
|
|
9804
11223
|
lastEventAt: Date.now()
|
|
@@ -9905,12 +11324,31 @@ function reducer(state, action) {
|
|
|
9905
11324
|
status: action.status,
|
|
9906
11325
|
completedTasks: action.completedTasks,
|
|
9907
11326
|
totalTasks: action.totalTasks,
|
|
9908
|
-
startedAt: action.startedAt
|
|
11327
|
+
startedAt: action.startedAt,
|
|
11328
|
+
// Preserve the live worker list across status/count updates.
|
|
11329
|
+
activeTasks: existing.phases[action.phaseId]?.activeTasks
|
|
9909
11330
|
}
|
|
9910
11331
|
}
|
|
9911
11332
|
}
|
|
9912
11333
|
};
|
|
9913
11334
|
}
|
|
11335
|
+
case "autoPhaseTaskActive": {
|
|
11336
|
+
if (!state.autoPhase) return state;
|
|
11337
|
+
const phase = state.autoPhase.phases[action.phaseId];
|
|
11338
|
+
if (!phase) return state;
|
|
11339
|
+
const without = (phase.activeTasks ?? []).filter((t) => t.taskId !== action.taskId);
|
|
11340
|
+
const activeTasks = action.active ? [...without, { taskId: action.taskId, title: action.title, agent: action.agent }] : without;
|
|
11341
|
+
return {
|
|
11342
|
+
...state,
|
|
11343
|
+
autoPhase: {
|
|
11344
|
+
...state.autoPhase,
|
|
11345
|
+
phases: {
|
|
11346
|
+
...state.autoPhase.phases,
|
|
11347
|
+
[action.phaseId]: { ...phase, activeTasks }
|
|
11348
|
+
}
|
|
11349
|
+
}
|
|
11350
|
+
};
|
|
11351
|
+
}
|
|
9914
11352
|
case "autoPhaseRunningPhases": {
|
|
9915
11353
|
if (!state.autoPhase) return state;
|
|
9916
11354
|
return {
|
|
@@ -9937,6 +11375,41 @@ function reducer(state, action) {
|
|
|
9937
11375
|
case "autoPhaseReset": {
|
|
9938
11376
|
return { ...state, autoPhase: null };
|
|
9939
11377
|
}
|
|
11378
|
+
case "sddBoardSnapshot": {
|
|
11379
|
+
const monitorOpen = state.sddBoard?.monitorOpen ?? false;
|
|
11380
|
+
const prevFocus = state.sddBoard?.focusColumn;
|
|
11381
|
+
const focusColumn = typeof prevFocus === "number" && prevFocus >= 0 && prevFocus < action.snapshot.columns.length ? prevFocus : void 0;
|
|
11382
|
+
return { ...state, sddBoard: { snapshot: action.snapshot, monitorOpen, focusColumn } };
|
|
11383
|
+
}
|
|
11384
|
+
case "toggleSddBoardMonitor": {
|
|
11385
|
+
if (!state.sddBoard) return state;
|
|
11386
|
+
const opening = !state.sddBoard.monitorOpen;
|
|
11387
|
+
return opening ? {
|
|
11388
|
+
...state,
|
|
11389
|
+
...closePanels(state),
|
|
11390
|
+
sddBoard: { ...state.sddBoard, monitorOpen: true }
|
|
11391
|
+
} : {
|
|
11392
|
+
...state,
|
|
11393
|
+
sddBoard: { ...state.sddBoard, monitorOpen: false, focusColumn: void 0 }
|
|
11394
|
+
};
|
|
11395
|
+
}
|
|
11396
|
+
case "sddBoardFocusNext": {
|
|
11397
|
+
if (!state.sddBoard) return state;
|
|
11398
|
+
if (!state.sddBoard.monitorOpen) return state;
|
|
11399
|
+
const max = state.sddBoard.snapshot.columns.length - 1;
|
|
11400
|
+
if (max < 0) return state;
|
|
11401
|
+
const current = state.sddBoard.focusColumn;
|
|
11402
|
+
const next = typeof current === "number" ? Math.min(max, current + 1) : 0;
|
|
11403
|
+
return { ...state, sddBoard: { ...state.sddBoard, focusColumn: next } };
|
|
11404
|
+
}
|
|
11405
|
+
case "sddBoardFocusPrev": {
|
|
11406
|
+
if (!state.sddBoard) return state;
|
|
11407
|
+
if (!state.sddBoard.monitorOpen) return state;
|
|
11408
|
+
const current = state.sddBoard.focusColumn;
|
|
11409
|
+
if (typeof current !== "number") return state;
|
|
11410
|
+
const next = current <= 0 ? void 0 : current - 1;
|
|
11411
|
+
return { ...state, sddBoard: { ...state.sddBoard, focusColumn: next } };
|
|
11412
|
+
}
|
|
9940
11413
|
case "worktreeUpsert": {
|
|
9941
11414
|
const prev = state.worktrees[action.handleId];
|
|
9942
11415
|
const merged = {
|
|
@@ -10314,32 +11787,56 @@ function nextInputWordStart(buffer, cursor) {
|
|
|
10314
11787
|
}
|
|
10315
11788
|
function rehydrateHistory(messages, startId, toolCalls) {
|
|
10316
11789
|
const entries = [];
|
|
11790
|
+
const toolCallsById = /* @__PURE__ */ new Map();
|
|
11791
|
+
if (toolCalls) {
|
|
11792
|
+
for (const tc of toolCalls) {
|
|
11793
|
+
if (!toolCallsById.has(tc.id)) toolCallsById.set(tc.id, tc);
|
|
11794
|
+
}
|
|
11795
|
+
}
|
|
11796
|
+
const consumed = /* @__PURE__ */ new Set();
|
|
11797
|
+
const fallback = [];
|
|
10317
11798
|
let nextId = startId;
|
|
11799
|
+
const textOf = (msg) => {
|
|
11800
|
+
if (typeof msg.content === "string") return msg.content;
|
|
11801
|
+
return msg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
11802
|
+
};
|
|
11803
|
+
const toolEntryFor = (tc) => ({
|
|
11804
|
+
id: nextId++,
|
|
11805
|
+
kind: "tool",
|
|
11806
|
+
name: tc.name,
|
|
11807
|
+
durationMs: tc.durationMs,
|
|
11808
|
+
ok: tc.ok,
|
|
11809
|
+
outputBytes: tc.outputBytes,
|
|
11810
|
+
outputTokens: tc.outputTokens,
|
|
11811
|
+
outputLines: tc.outputLines
|
|
11812
|
+
});
|
|
10318
11813
|
for (const msg of messages) {
|
|
10319
11814
|
if (msg.role === "system") continue;
|
|
10320
|
-
const text =
|
|
10321
|
-
|
|
10322
|
-
if (!trimmed) continue;
|
|
11815
|
+
const text = textOf(msg).trim();
|
|
11816
|
+
if (!text) continue;
|
|
10323
11817
|
if (msg.role === "user") {
|
|
10324
|
-
entries.push({ id: nextId++, kind: "user", text
|
|
10325
|
-
|
|
10326
|
-
|
|
11818
|
+
entries.push({ id: nextId++, kind: "user", text });
|
|
11819
|
+
continue;
|
|
11820
|
+
}
|
|
11821
|
+
if (msg.role === "assistant") {
|
|
11822
|
+
entries.push({ id: nextId++, kind: "assistant", text });
|
|
11823
|
+
if (Array.isArray(msg.content)) {
|
|
11824
|
+
for (const block of msg.content) {
|
|
11825
|
+
if (block.type !== "tool_use") continue;
|
|
11826
|
+
const tc = toolCallsById.get(block.id);
|
|
11827
|
+
if (!tc) continue;
|
|
11828
|
+
entries.push(toolEntryFor(tc));
|
|
11829
|
+
consumed.add(block.id);
|
|
11830
|
+
}
|
|
11831
|
+
}
|
|
10327
11832
|
}
|
|
10328
11833
|
}
|
|
10329
|
-
if (toolCalls
|
|
11834
|
+
if (toolCalls) {
|
|
10330
11835
|
for (const tc of toolCalls) {
|
|
10331
|
-
|
|
10332
|
-
id: nextId++,
|
|
10333
|
-
kind: "tool",
|
|
10334
|
-
name: tc.name,
|
|
10335
|
-
durationMs: tc.durationMs,
|
|
10336
|
-
ok: tc.ok,
|
|
10337
|
-
outputBytes: tc.outputBytes,
|
|
10338
|
-
outputTokens: tc.outputTokens,
|
|
10339
|
-
outputLines: tc.outputLines
|
|
10340
|
-
});
|
|
11836
|
+
if (!consumed.has(tc.id)) fallback.push(toolEntryFor(tc));
|
|
10341
11837
|
}
|
|
10342
11838
|
}
|
|
11839
|
+
entries.push(...fallback);
|
|
10343
11840
|
return entries;
|
|
10344
11841
|
}
|
|
10345
11842
|
var PASTE_THRESHOLD_CHARS = 200;
|
|
@@ -10369,6 +11866,7 @@ function App({
|
|
|
10369
11866
|
getAutonomy,
|
|
10370
11867
|
getEternalEngine,
|
|
10371
11868
|
getParallelEngine,
|
|
11869
|
+
getSddRun,
|
|
10372
11870
|
subscribeEternalIteration,
|
|
10373
11871
|
subscribeEternalStage,
|
|
10374
11872
|
subscribeAutoPhase,
|
|
@@ -10396,6 +11894,7 @@ function App({
|
|
|
10396
11894
|
director,
|
|
10397
11895
|
fleetRoster,
|
|
10398
11896
|
onClearHistory,
|
|
11897
|
+
clearTerminal,
|
|
10399
11898
|
listSessions,
|
|
10400
11899
|
onResumeSession,
|
|
10401
11900
|
fleetStreamController,
|
|
@@ -10627,6 +12126,7 @@ function App({
|
|
|
10627
12126
|
eternalStage: null,
|
|
10628
12127
|
goalSummary: null,
|
|
10629
12128
|
autoPhase: null,
|
|
12129
|
+
sddBoard: null,
|
|
10630
12130
|
worktrees: {},
|
|
10631
12131
|
worktreeMonitorOpen: false,
|
|
10632
12132
|
coordinator: {
|
|
@@ -10738,8 +12238,22 @@ function App({
|
|
|
10738
12238
|
stateRef.current = state;
|
|
10739
12239
|
const draftRef = useRef({ buffer: state.buffer, cursor: state.cursor });
|
|
10740
12240
|
draftRef.current = { buffer: state.buffer, cursor: state.cursor };
|
|
12241
|
+
const statuslineHiddenForPicker = useCallback(() => {
|
|
12242
|
+
const hookHidden = hiddenItemsRef.current;
|
|
12243
|
+
const hookHiddenSet = new Set(hookHidden);
|
|
12244
|
+
const reducerOnlyHidden = stateRef.current.statuslinePicker.hiddenItems.filter(
|
|
12245
|
+
(item) => !hookHiddenSet.has(item)
|
|
12246
|
+
);
|
|
12247
|
+
return [...hookHidden, ...reducerOnlyHidden];
|
|
12248
|
+
}, []);
|
|
12249
|
+
const openStatuslinePicker = useCallback((field) => {
|
|
12250
|
+
if (field !== void 0) {
|
|
12251
|
+
dispatch({ type: "statuslineFieldSet", field });
|
|
12252
|
+
}
|
|
12253
|
+
dispatch({ type: "statuslineOpen", hiddenItems: statuslineHiddenForPicker() });
|
|
12254
|
+
}, [statuslineHiddenForPicker]);
|
|
10741
12255
|
const [mouseMode, setMouseMode] = useState(mouse);
|
|
10742
|
-
const pickerOverlayOpen = state.modelPicker.open || state.autonomyPicker.open || state.settingsPicker.open || state.projectPicker.open || state.slashPicker.open || state.picker.open;
|
|
12256
|
+
const pickerOverlayOpen = state.modelPicker.open || state.autonomyPicker.open || state.settingsPicker.open || state.projectPicker.open || state.slashPicker.open || state.statuslinePicker.open || state.fKeyPicker.open || state.picker.open;
|
|
10743
12257
|
const mouseTrackingOn = mouseMode || pickerOverlayOpen;
|
|
10744
12258
|
const mouseWrittenRef = useRef(false);
|
|
10745
12259
|
useEffect(() => {
|
|
@@ -10893,7 +12407,7 @@ function App({
|
|
|
10893
12407
|
readGitInfo(agent.ctx.cwd).then((info) => {
|
|
10894
12408
|
if (cancelled) return;
|
|
10895
12409
|
setGitInfo(info);
|
|
10896
|
-
if (info
|
|
12410
|
+
if (info?.branch) {
|
|
10897
12411
|
const prev = prevBranchRef.current;
|
|
10898
12412
|
if (prev !== null && prev !== info.branch) {
|
|
10899
12413
|
const msg = {
|
|
@@ -11371,24 +12885,7 @@ function App({
|
|
|
11371
12885
|
return;
|
|
11372
12886
|
}
|
|
11373
12887
|
const query = trimmed.slice(1).toLowerCase();
|
|
11374
|
-
const
|
|
11375
|
-
const CATEGORY_ORDER = ["Run", "Session", "Inspect", "Agent", "Config", "App"];
|
|
11376
|
-
const matches = allCommands.filter(({ cmd }) => {
|
|
11377
|
-
if (query === "" && cmd.hidden) return false;
|
|
11378
|
-
const name = cmd.name.toLowerCase();
|
|
11379
|
-
const aliases = cmd.aliases ?? [];
|
|
11380
|
-
return name.includes(query) || aliases.some((a) => a.toLowerCase().includes(query));
|
|
11381
|
-
}).map(({ cmd, owner }) => ({
|
|
11382
|
-
name: cmd.name,
|
|
11383
|
-
description: cmd.description,
|
|
11384
|
-
argsHint: cmd.argsHint,
|
|
11385
|
-
isBuiltin: owner === "core",
|
|
11386
|
-
category: cmd.category ?? "App"
|
|
11387
|
-
})).sort((a, b) => {
|
|
11388
|
-
const catDiff = CATEGORY_ORDER.indexOf(a.category) - CATEGORY_ORDER.indexOf(b.category);
|
|
11389
|
-
if (catDiff !== 0) return catDiff;
|
|
11390
|
-
return a.name.localeCompare(b.name);
|
|
11391
|
-
});
|
|
12888
|
+
const matches = buildSlashCommandMatches(slashRegistry.listWithOwner(), query);
|
|
11392
12889
|
if (!state.slashPicker.open) {
|
|
11393
12890
|
dispatch({ type: "slashPickerOpen", query, matches });
|
|
11394
12891
|
} else if (state.slashPicker.query !== query) {
|
|
@@ -11962,12 +13459,41 @@ function App({
|
|
|
11962
13459
|
aliases: ["sl"],
|
|
11963
13460
|
description: "Customize status bar chips: /statusline (interactive) or /statusline <item> [on|off]",
|
|
11964
13461
|
async run(args) {
|
|
11965
|
-
|
|
11966
|
-
|
|
11967
|
-
|
|
11968
|
-
|
|
11969
|
-
|
|
11970
|
-
|
|
13462
|
+
const trimmed = args.trim();
|
|
13463
|
+
if (trimmed) {
|
|
13464
|
+
const [rawItem, rawAction] = trimmed.split(/\s+/);
|
|
13465
|
+
const item = rawItem;
|
|
13466
|
+
const action = rawAction?.toLowerCase();
|
|
13467
|
+
const applyHidden = (items) => {
|
|
13468
|
+
const deduped = [...new Set(items)];
|
|
13469
|
+
hiddenItemsRef.current = deduped;
|
|
13470
|
+
setHiddenItems(deduped);
|
|
13471
|
+
};
|
|
13472
|
+
if (item === "reset") {
|
|
13473
|
+
applyHidden([]);
|
|
13474
|
+
return { message: "StatusBar config reset to defaults." };
|
|
13475
|
+
}
|
|
13476
|
+
if (item === "all") {
|
|
13477
|
+
if (action !== "on" && action !== "off") {
|
|
13478
|
+
return { message: "Usage: /statusline all on|off" };
|
|
13479
|
+
}
|
|
13480
|
+
applyHidden(action === "off" ? [...STATUSLINE_ITEMS] : []);
|
|
13481
|
+
return { message: `statusline all: ${action === "on" ? "showing all chips" : "hiding all chips"}` };
|
|
13482
|
+
}
|
|
13483
|
+
if (!item || !STATUSLINE_ITEMS.includes(item)) {
|
|
13484
|
+
return { message: `Unknown item "${rawItem ?? ""}". Run /statusline to see available items.` };
|
|
13485
|
+
}
|
|
13486
|
+
if (action !== void 0 && action !== "on" && action !== "off") {
|
|
13487
|
+
return { message: `Usage: /statusline ${item} on|off` };
|
|
13488
|
+
}
|
|
13489
|
+
const hidden = new Set(hiddenItemsRef.current);
|
|
13490
|
+
const nextVisible = action ? action === "on" : hidden.has(item);
|
|
13491
|
+
if (nextVisible) hidden.delete(item);
|
|
13492
|
+
else hidden.add(item);
|
|
13493
|
+
applyHidden([...hidden]);
|
|
13494
|
+
return { message: `statusline ${item}: ${nextVisible ? "on" : "off"}` };
|
|
13495
|
+
}
|
|
13496
|
+
openStatuslinePicker();
|
|
11971
13497
|
return { message: void 0 };
|
|
11972
13498
|
}
|
|
11973
13499
|
};
|
|
@@ -11975,7 +13501,7 @@ function App({
|
|
|
11975
13501
|
return () => {
|
|
11976
13502
|
slashRegistry.unregister("statusline");
|
|
11977
13503
|
};
|
|
11978
|
-
}, [slashRegistry]);
|
|
13504
|
+
}, [slashRegistry, openStatuslinePicker, setHiddenItems]);
|
|
11979
13505
|
useEffect(() => {
|
|
11980
13506
|
const cmd = {
|
|
11981
13507
|
name: "mailbox",
|
|
@@ -12395,9 +13921,12 @@ function App({
|
|
|
12395
13921
|
(e) => e.status === "running"
|
|
12396
13922
|
).length;
|
|
12397
13923
|
const autonomyRunning = eternalLoopRunningRef.current || parallelLoopRunningRef.current || getEternalEngine?.()?.currentState === "running" || getParallelEngine?.()?.currentState === "running";
|
|
12398
|
-
|
|
13924
|
+
const sddRun = getSddRun?.();
|
|
13925
|
+
const sddRunning = sddRun?.isRunning() ?? false;
|
|
13926
|
+
if (autonomyRunning || fleetRunning > 0 || sddRunning) {
|
|
12399
13927
|
getEternalEngine?.()?.stop();
|
|
12400
13928
|
getParallelEngine?.()?.stop();
|
|
13929
|
+
if (sddRunning) sddRun?.stop();
|
|
12401
13930
|
if (autonomyRunning) switchAutonomy?.("off");
|
|
12402
13931
|
if (director) {
|
|
12403
13932
|
const cap = new Promise((resolve) => {
|
|
@@ -12409,6 +13938,7 @@ function App({
|
|
|
12409
13938
|
const killed2 = getProcessRegistry().killAll();
|
|
12410
13939
|
const bits = [];
|
|
12411
13940
|
if (autonomyRunning) bits.push("autonomy stopped");
|
|
13941
|
+
if (sddRunning) bits.push("SDD run stopped");
|
|
12412
13942
|
if (fleetRunning > 0)
|
|
12413
13943
|
bits.push(`${fleetRunning} agent${fleetRunning === 1 ? "" : "s"} terminated`);
|
|
12414
13944
|
if (killed2.length > 0)
|
|
@@ -12434,7 +13964,7 @@ function App({
|
|
|
12434
13964
|
return () => {
|
|
12435
13965
|
process.off("SIGINT", onSigint);
|
|
12436
13966
|
};
|
|
12437
|
-
}, [director, getEternalEngine, getParallelEngine, switchAutonomy, onExit, exit]);
|
|
13967
|
+
}, [director, getEternalEngine, getParallelEngine, getSddRun, switchAutonomy, onExit, exit]);
|
|
12438
13968
|
const commitPaste = async (full) => {
|
|
12439
13969
|
const builder = builderRef.current;
|
|
12440
13970
|
if (!builder || !full) return;
|
|
@@ -12949,7 +14479,7 @@ function App({
|
|
|
12949
14479
|
openProjectPicker();
|
|
12950
14480
|
return;
|
|
12951
14481
|
}
|
|
12952
|
-
const action = actionForFKeyPanel(entry,
|
|
14482
|
+
const action = actionForFKeyPanel(entry, statuslineHiddenForPicker());
|
|
12953
14483
|
if (action) dispatch(action);
|
|
12954
14484
|
return;
|
|
12955
14485
|
}
|
|
@@ -13120,6 +14650,50 @@ function App({
|
|
|
13120
14650
|
toggleWorktreeOverlay();
|
|
13121
14651
|
return;
|
|
13122
14652
|
}
|
|
14653
|
+
if (key.ctrl && input === "b") {
|
|
14654
|
+
dispatch({ type: "toggleSddBoardMonitor" });
|
|
14655
|
+
return;
|
|
14656
|
+
}
|
|
14657
|
+
if (state.sddBoard?.monitorOpen && !key.ctrl && !key.meta) {
|
|
14658
|
+
if (key.rightArrow) {
|
|
14659
|
+
dispatch({ type: "sddBoardFocusNext" });
|
|
14660
|
+
return;
|
|
14661
|
+
}
|
|
14662
|
+
if (key.leftArrow) {
|
|
14663
|
+
dispatch({ type: "sddBoardFocusPrev" });
|
|
14664
|
+
return;
|
|
14665
|
+
}
|
|
14666
|
+
if (input === "c") {
|
|
14667
|
+
const run = getSddRun?.();
|
|
14668
|
+
if (run) {
|
|
14669
|
+
void run.cleanupWorktrees().then((n) => {
|
|
14670
|
+
dispatch({
|
|
14671
|
+
type: "addEntry",
|
|
14672
|
+
entry: {
|
|
14673
|
+
kind: n > 0 ? "info" : "warn",
|
|
14674
|
+
text: n > 0 ? `Cleaned ${n} SDD worktree${n === 1 ? "" : "s"}.` : "No SDD worktrees to clean (stop the run first if it is live)."
|
|
14675
|
+
}
|
|
14676
|
+
});
|
|
14677
|
+
});
|
|
14678
|
+
}
|
|
14679
|
+
return;
|
|
14680
|
+
}
|
|
14681
|
+
if (input === "z") {
|
|
14682
|
+
const run = getSddRun?.();
|
|
14683
|
+
if (run) {
|
|
14684
|
+
void run.rollback().then((r) => {
|
|
14685
|
+
dispatch({
|
|
14686
|
+
type: "addEntry",
|
|
14687
|
+
entry: {
|
|
14688
|
+
kind: r.ok ? "info" : "warn",
|
|
14689
|
+
text: r.ok ? r.reverted > 0 ? `Rolled back ${r.reverted} run commit${r.reverted === 1 ? "" : "s"} (revert commits added).` : "Nothing to roll back." : `Rollback failed: ${r.reason ?? "unknown error"}`
|
|
14690
|
+
}
|
|
14691
|
+
});
|
|
14692
|
+
});
|
|
14693
|
+
}
|
|
14694
|
+
return;
|
|
14695
|
+
}
|
|
14696
|
+
}
|
|
13123
14697
|
if (key.fn === 5) {
|
|
13124
14698
|
if (state.planPanelOpen) {
|
|
13125
14699
|
dispatch({ type: "togglePlanPanel" });
|
|
@@ -13211,7 +14785,7 @@ function App({
|
|
|
13211
14785
|
return;
|
|
13212
14786
|
}
|
|
13213
14787
|
if (key.fn === 12) {
|
|
13214
|
-
|
|
14788
|
+
openStatuslinePicker();
|
|
13215
14789
|
return;
|
|
13216
14790
|
}
|
|
13217
14791
|
if (state.settingsPicker.open) {
|
|
@@ -13270,7 +14844,7 @@ function App({
|
|
|
13270
14844
|
featureMemory: cfg.featureMemory ?? true,
|
|
13271
14845
|
featureSkills: cfg.featureSkills ?? true,
|
|
13272
14846
|
featureModelsRegistry: cfg.featureModelsRegistry ?? true,
|
|
13273
|
-
tokenSavingTier: cfg.
|
|
14847
|
+
tokenSavingTier: cfg.featureTokenSaving ?? "off",
|
|
13274
14848
|
allowOutsideProjectRoot: cfg.allowOutsideProjectRoot ?? true,
|
|
13275
14849
|
contextAutoCompact: cfg.contextAutoCompact ?? true,
|
|
13276
14850
|
contextStrategy: cfg.contextStrategy ?? "hybrid",
|
|
@@ -13547,6 +15121,10 @@ function App({
|
|
|
13547
15121
|
version: appVersion,
|
|
13548
15122
|
state: state.status,
|
|
13549
15123
|
fleetRunning: fleetCounts?.running ?? 0,
|
|
15124
|
+
// Must match the rendered state label width — while streaming the bar
|
|
15125
|
+
// shows the configured thinking word, so the span shifts with it.
|
|
15126
|
+
// Omitting this made the model chip un-clickable mid-stream.
|
|
15127
|
+
thinkingWord: liveThinkingWord,
|
|
13550
15128
|
model: `${liveProvider}/${liveModel}`
|
|
13551
15129
|
});
|
|
13552
15130
|
if (inSpan(span)) {
|
|
@@ -13564,27 +15142,24 @@ function App({
|
|
|
13564
15142
|
dispatch({ type: "toggleTodosMonitor" });
|
|
13565
15143
|
return;
|
|
13566
15144
|
}
|
|
13567
|
-
const hiddenSet = new Set(
|
|
15145
|
+
const hiddenSet = new Set(statuslineHiddenForPicker());
|
|
13568
15146
|
if (my === rowFor(2)) {
|
|
13569
15147
|
const mxLocal = mx - SB_PADX2 - 1;
|
|
13570
15148
|
if (!hiddenSet.has("todos") && mxLocal >= 0 && mxLocal < 20) {
|
|
13571
|
-
|
|
13572
|
-
dispatch({ type: "statuslineOpen", hiddenItems: state.statuslinePicker.hiddenItems });
|
|
15149
|
+
openStatuslinePicker(STATUSLINE_ITEMS.indexOf("todos"));
|
|
13573
15150
|
return;
|
|
13574
15151
|
}
|
|
13575
15152
|
if (!hiddenSet.has("plan")) {
|
|
13576
15153
|
const planStart = 21;
|
|
13577
15154
|
if (mxLocal >= planStart && mxLocal < planStart + 22) {
|
|
13578
|
-
|
|
13579
|
-
dispatch({ type: "statuslineOpen", hiddenItems: state.statuslinePicker.hiddenItems });
|
|
15155
|
+
openStatuslinePicker(STATUSLINE_ITEMS.indexOf("plan"));
|
|
13580
15156
|
return;
|
|
13581
15157
|
}
|
|
13582
15158
|
}
|
|
13583
15159
|
if (!hiddenSet.has("tasks")) {
|
|
13584
15160
|
const tasksStart = 44;
|
|
13585
15161
|
if (mxLocal >= tasksStart && mxLocal < tasksStart + 26) {
|
|
13586
|
-
|
|
13587
|
-
dispatch({ type: "statuslineOpen", hiddenItems: state.statuslinePicker.hiddenItems });
|
|
15162
|
+
openStatuslinePicker(STATUSLINE_ITEMS.indexOf("tasks"));
|
|
13588
15163
|
return;
|
|
13589
15164
|
}
|
|
13590
15165
|
}
|
|
@@ -13593,8 +15168,7 @@ function App({
|
|
|
13593
15168
|
const mxLocal = mx - SB_PADX2 - 1;
|
|
13594
15169
|
const fleetStart = 0;
|
|
13595
15170
|
if (mxLocal >= fleetStart && mxLocal < fleetStart + 22) {
|
|
13596
|
-
|
|
13597
|
-
dispatch({ type: "statuslineOpen", hiddenItems: state.statuslinePicker.hiddenItems });
|
|
15171
|
+
openStatuslinePicker(STATUSLINE_ITEMS.indexOf("fleet"));
|
|
13598
15172
|
return;
|
|
13599
15173
|
}
|
|
13600
15174
|
}
|
|
@@ -14037,6 +15611,7 @@ ${content}
|
|
|
14037
15611
|
}
|
|
14038
15612
|
const cmd = trimmed.slice(1).split(/\s+/, 1)[0];
|
|
14039
15613
|
if (cmd === "clear") {
|
|
15614
|
+
clearTerminal?.();
|
|
14040
15615
|
onClearHistory?.(dispatch);
|
|
14041
15616
|
tokenCounter?.reset();
|
|
14042
15617
|
}
|
|
@@ -14153,7 +15728,7 @@ User message:
|
|
|
14153
15728
|
pushSubmittedHistory();
|
|
14154
15729
|
clearDraft();
|
|
14155
15730
|
const blocks = await builder.submit();
|
|
14156
|
-
if (state.status !== "idle") {
|
|
15731
|
+
if (state.status !== "idle" && !steering) {
|
|
14157
15732
|
if (autonomyLive === "auto" && nextStepsAutoSubmitTimerRef.current != null) {
|
|
14158
15733
|
switchAutonomy?.("off");
|
|
14159
15734
|
}
|
|
@@ -14573,6 +16148,12 @@ User message:
|
|
|
14573
16148
|
elapsedMs: state.autoPhase.elapsedMs,
|
|
14574
16149
|
nowTick
|
|
14575
16150
|
}
|
|
16151
|
+
) : state.sddBoard?.monitorOpen ? /* @__PURE__ */ jsx(
|
|
16152
|
+
SddBoardOverlay,
|
|
16153
|
+
{
|
|
16154
|
+
snapshot: state.sddBoard.snapshot,
|
|
16155
|
+
focusColumn: state.sddBoard.focusColumn ?? null
|
|
16156
|
+
}
|
|
14576
16157
|
) : state.worktreeMonitorOpen ? /* @__PURE__ */ jsx(
|
|
14577
16158
|
WorktreeMonitor,
|
|
14578
16159
|
{
|
|
@@ -14973,6 +16554,13 @@ async function runTui(opts) {
|
|
|
14973
16554
|
};
|
|
14974
16555
|
opts.requestExit = requestExit;
|
|
14975
16556
|
let instance;
|
|
16557
|
+
const clearTerminal = () => {
|
|
16558
|
+
try {
|
|
16559
|
+
instance?.clear();
|
|
16560
|
+
stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
16561
|
+
} catch {
|
|
16562
|
+
}
|
|
16563
|
+
};
|
|
14976
16564
|
try {
|
|
14977
16565
|
instance = render(
|
|
14978
16566
|
React5.createElement(App, {
|
|
@@ -14992,6 +16580,7 @@ async function runTui(opts) {
|
|
|
14992
16580
|
getAutonomy: opts.getAutonomy,
|
|
14993
16581
|
getEternalEngine: opts.getEternalEngine,
|
|
14994
16582
|
getParallelEngine: opts.getParallelEngine,
|
|
16583
|
+
getSddRun: opts.getSddRun,
|
|
14995
16584
|
subscribeEternalIteration: opts.subscribeEternalIteration,
|
|
14996
16585
|
subscribeEternalStage: opts.subscribeEternalStage,
|
|
14997
16586
|
subscribeAutoPhase: opts.subscribeAutoPhase,
|
|
@@ -15007,6 +16596,7 @@ async function runTui(opts) {
|
|
|
15007
16596
|
director: opts.director ?? null,
|
|
15008
16597
|
fleetRoster: opts.fleetRoster,
|
|
15009
16598
|
onClearHistory: opts.onClearHistory ? (dispatch) => opts.onClearHistory?.(dispatch) : void 0,
|
|
16599
|
+
clearTerminal,
|
|
15010
16600
|
fleetStreamController: opts.fleetStreamController,
|
|
15011
16601
|
interruptController: opts.interruptController,
|
|
15012
16602
|
enhanceController: opts.enhanceController,
|