@wrongstack/tui 0.273.0 → 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.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 ?? /* @__PURE__ */ new Set(), visibleChips);
270
- const showDebugStream = isStreamChipVisible("debug_stream", debugStreamStats, hiddenSet ?? /* @__PURE__ */ new Set(), visibleChips);
271
- const showEnhance = isStreamChipVisible("enhance", enhanceCountdown, hiddenSet ?? /* @__PURE__ */ new Set(), visibleChips);
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 countdownColor = nextStepsAutoSubmitCountdown != null ? nextStepsAutoSubmitCountdown > 20 ? "green" : nextStepsAutoSubmitCountdown > 10 ? "yellow" : "red" : "green";
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) && !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 || showEnhance || hasNextStepsAutoSubmit;
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 && !hiddenSet.has("todos") && todos.inProgress + todos.pending > 0 ? `todo ${todos.inProgress}/${todos.pending}` : "",
279
- hasTaskActivity && !hiddenSet.has("tasks") ? `task ${tasks.inProgress}/${tasks.pending}` : "",
280
- fleetHasActivity && !hiddenSet.has("fleet") ? fleet ? `agent \u25B6${fleet.running} \xB7${fleet.idle}` : `agent ${subagentCount}` : "",
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 && !hiddenSet.has("context") ? /* @__PURE__ */ jsxs(Fragment, { children: [
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 && !hiddenSet.has("cost") ? /* @__PURE__ */ jsxs(Fragment, { children: [
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__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
388
- /* @__PURE__ */ jsx(Text, { color: "magenta", children: model }),
389
- context && !hiddenSet.has("context") ? /* @__PURE__ */ jsxs(Fragment, { children: [
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 && !hiddenSet.has("cost") ? /* @__PURE__ */ jsxs(Fragment, { children: [
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__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
484
- yolo ? /* @__PURE__ */ jsx(Text, { color: "red", bold: true, children: "\u26A0 YOLO" }) : null,
485
- autonomy && autonomy !== "off" ? /* @__PURE__ */ jsxs(Fragment, { children: [
486
- yolo ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
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
- ] }) : null,
499
- eternalStage ? /* @__PURE__ */ jsxs(Fragment, { children: [
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
- ] }) : null,
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
- ] }) : null,
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
- ] }) : null,
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
- ] }) : null,
544
- modeLabel ? /* @__PURE__ */ jsxs(Fragment, { children: [
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
- ] }) : null,
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
- ] }) : null,
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
- ] }) : null,
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
- todos.inProgress > 0 && (todos.pending > 0 || todos.completed > 0) ? " " : "",
604
- todos.pending > 0 ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
605
- "\u2610",
606
- todos.pending
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
- todos.pending > 0 && todos.completed > 0 ? " " : "",
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
- ] }) : null,
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
- ] }) : null,
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
- ] }) : null,
705
- showBrain ? /* @__PURE__ */ jsxs(Fragment, { children: [
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
- ] }) : null,
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
- ] }) : null,
741
- hasNextStepsAutoSubmit && nextStepsAutoSubmitCountdown != null ? /* @__PURE__ */ jsxs(Fragment, { children: [
742
- 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 || showEnhance ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
743
- /* @__PURE__ */ jsxs(Text, { color: countdownColor, bold: true, children: [
744
- "\u23F3 ",
745
- nextStepsAutoSubmitCountdown,
746
- "s"
747
- ] }),
748
- /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
749
- " ",
750
- nextStepsAutoSubmitLabel ? formatSuggestionLabel(nextStepsAutoSubmitLabel) : "",
751
- " \xB7 \u21E5 edit"
752
- ] })
753
- ] }) : null
754
- ] }) : /* @__PURE__ */ jsx(Box, { height: 1, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
755
- mailbox && !hiddenSet.has("mailbox") ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
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,7 +810,7 @@ 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) => /* @__PURE__ */ jsxs(Text, { children: [
813
+ fleetAgents && fleetAgents.length > 0 && showChip("fleet_agents") ? fleetAgents.map((a, i) => /* @__PURE__ */ jsxs(Text, { children: [
790
814
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
791
815
  " ",
792
816
  /* @__PURE__ */ jsx(Text, { color: a.color, bold: true, children: a.label }),
@@ -811,7 +835,7 @@ function StatusBar({
811
835
  ] })
812
836
  ] }) : null
813
837
  ] }, i)) : null
814
- ] }) : fleetAgents && fleetAgents.length > 0 ? /* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 2, children: fleetAgents.map((a, i) => /* @__PURE__ */ jsxs(Text, { children: [
838
+ ] }) : fleetAgents && fleetAgents.length > 0 && showChip("fleet_agents") ? /* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 2, children: fleetAgents.map((a, i) => /* @__PURE__ */ jsxs(Text, { children: [
815
839
  /* @__PURE__ */ jsx(Text, { color: a.color, bold: true, children: a.label }),
816
840
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }),
817
841
  /* @__PURE__ */ jsx(Text, { dimColor: !a.running, ...a.running ? { color: "yellow" } : {}, children: a.running ? "\u25B6" : "\xB7" }),
@@ -1216,7 +1240,7 @@ function FleetMonitor({
1216
1240
  const s2 = STATUS[e.status];
1217
1241
  const elapsed = e.status === "running" ? fmtElapsed(Math.max(0, nowTick - e.startedAt)) : fmtElapsed(Math.max(0, nowTick - e.lastEventAt)) + " ago";
1218
1242
  const model = fmtModelLabel(e.provider, e.model) || "\u2014";
1219
- 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`;
1220
1244
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
1221
1245
  /* @__PURE__ */ jsx(Text, { color: s2.color, children: s2.icon }),
1222
1246
  /* @__PURE__ */ jsx(Text, { children: e.name.padEnd(14).slice(0, 14) }),
@@ -1406,6 +1430,10 @@ function ContextBar({
1406
1430
  tokenText
1407
1431
  ] });
1408
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
+ }
1409
1437
  function AgentRow({
1410
1438
  entry,
1411
1439
  now,
@@ -1660,14 +1688,13 @@ function AgentsMonitor({
1660
1688
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: "pulse" }),
1661
1689
  /* @__PURE__ */ jsxs(Text, { color: pressure >= 0.9 ? "red" : pressure >= 0.75 ? "yellow" : "green", children: [
1662
1690
  "max ctx ",
1663
- Math.round(pressure * 100),
1664
- "%"
1691
+ pctTextFromRatio(pressure)
1665
1692
  ] }),
1666
1693
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 hot" }),
1667
1694
  hotAgent ? /* @__PURE__ */ jsxs(Text, { color: riskMeta(agentRisk(hotAgent)).color, children: [
1668
1695
  hotAgent.name,
1669
1696
  " ",
1670
- hotAgent.ctxPct !== void 0 ? `${Math.round(hotAgent.ctxPct * 100)}%` : ""
1697
+ hotAgent.ctxPct !== void 0 ? pctTextFromRatio(hotAgent.ctxPct) : ""
1671
1698
  ] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "none" }),
1672
1699
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 throughput" }),
1673
1700
  /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
@@ -6602,12 +6629,15 @@ function TaskCard({ task }) {
6602
6629
  ] });
6603
6630
  }
6604
6631
  function SddBoardOverlay({
6605
- snapshot
6632
+ snapshot,
6633
+ focusColumn = null
6606
6634
  }) {
6607
6635
  const byShort = new Map(snapshot.tasks.map((t) => [t.shortId, t]));
6608
6636
  const p = snapshot.progress;
6609
6637
  const chains = snapshot.diagnostics?.deadlockChains ?? [];
6610
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]];
6611
6641
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
6612
6642
  /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, marginBottom: 1, children: [
6613
6643
  /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "SDD BOARD" }),
@@ -6640,7 +6670,13 @@ function SddBoardOverlay({
6640
6670
  "\u2717",
6641
6671
  p.failed
6642
6672
  ] }) : null,
6643
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 Ctrl+B close \xB7 c clean wt \xB7 z rollback" })
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
6644
6680
  ] }),
6645
6681
  chains.length > 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
6646
6682
  /* @__PURE__ */ jsx(Text, { color: "red", bold: true, children: "\u26A0 Deadlock \u2014 blocked by failed tasks:" }),
@@ -6651,7 +6687,7 @@ function SddBoardOverlay({
6651
6687
  c.blockedBy.join(", ")
6652
6688
  ] }, c.blocked))
6653
6689
  ] }) : null,
6654
- 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: snapshot.columns.map((col) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginRight: 1, children: [
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: [
6655
6691
  /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: col.label }),
6656
6692
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500".repeat(12) }),
6657
6693
  col.taskIds.map((sid) => byShort.get(sid)).filter((t) => Boolean(t)).map((t) => /* @__PURE__ */ jsx(TaskCard, { task: t }, t.id))
@@ -7567,9 +7603,9 @@ var STATUSLINE_MODE_DESCS = {
7567
7603
  detailed: "Full multi-line statusline (default)"
7568
7604
  };
7569
7605
  var MAX_ITERATIONS_PRESETS = [100, 200, 500, 1e3, 0];
7570
- var MAX_CONCURRENT_PRESETS = [1, 3, 5, 10, 25, 50, 0];
7606
+ var MAX_CONCURRENT_PRESETS = [1, 3, 4, 5, 10, 25, 50, 0];
7571
7607
  var AUTO_PROCEED_MAX_PRESETS = [10, 25, 50, 100, 250, 0];
7572
- var ENHANCE_DELAY_PRESETS = [3e4, 45e3, 6e4, 9e4, 12e4];
7608
+ var ENHANCE_DELAY_PRESETS = [15e3, 3e4, 45e3, 6e4, 9e4, 12e4];
7573
7609
  var ENHANCE_LANGUAGES = ["original", "english"];
7574
7610
  var TOKEN_SAVING_TIERS = ["off", "minimal", "light", "medium", "aggressive"];
7575
7611
  var TOKEN_SAVING_TIER_DESCS = {
@@ -7731,7 +7767,7 @@ function SettingsPicker({
7731
7767
  {
7732
7768
  label: "Refine preview countdown",
7733
7769
  value: formatEnhanceDelay(enhanceDelayMs),
7734
- detail: "Timeout for prompt refinement preview (30s\u2013120s)"
7770
+ detail: "Timeout for prompt refinement preview (15s\u2013120s)"
7735
7771
  },
7736
7772
  {
7737
7773
  label: "Refine",
@@ -7796,8 +7832,8 @@ function SettingsPicker({
7796
7832
  { section: "Fleet" },
7797
7833
  {
7798
7834
  label: "Max concurrent",
7799
- value: maxConcurrent === 0 ? "unlimited" : String(maxConcurrent),
7800
- detail: "Max subagents (0 = unlimited)"
7835
+ value: maxConcurrent === 0 ? "default" : String(maxConcurrent),
7836
+ detail: "Max subagents (0 = default)"
7801
7837
  },
7802
7838
  // ── Logging ──
7803
7839
  { section: "Logging" },
@@ -7861,7 +7897,7 @@ function SettingsPicker({
7861
7897
  };
7862
7898
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
7863
7899
  /* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u2501\u2501 Settings \u2501\u2501" }),
7864
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 field \xB7 \u2190/\u2192 change (instant apply) \xB7 F5 to close" }),
7900
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 field \xB7 \u2190/\u2192 change + autosave \xB7 F5 to close" }),
7865
7901
  hasAbove ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u2191 ${windowStart} field${windowStart === 1 ? "" : "s"} above` }) : null,
7866
7902
  rows.map((row, i) => {
7867
7903
  const fieldAtRow = fieldRowIndex.indexOf(i);
@@ -7885,7 +7921,7 @@ function SettingsPicker({
7885
7921
  ] }, `row-${row.label ?? fieldAtRow}`);
7886
7922
  }),
7887
7923
  hasBelow ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u2193 ${totalFields - windowEnd} field${totalFields - windowEnd === 1 ? "" : "s"} below` }) : null,
7888
- /* @__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" }),
7889
7925
  hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
7890
7926
  ] });
7891
7927
  }
@@ -7895,54 +7931,120 @@ function isChipExpired(meta, now = Date.now()) {
7895
7931
  return now >= meta.shownAt + meta.expiresIn * 60 * 1e3;
7896
7932
  }
7897
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",
7898
7944
  todos: "Todo items (pending/in-progress/done)",
7899
7945
  plan: "Plan board items",
7900
7946
  tasks: "Task board items",
7901
7947
  fleet: "Fleet agent status",
7948
+ fleet_agents: "Per-agent live detail row",
7902
7949
  git: "Git branch name",
7903
7950
  elapsed: "Session elapsed time",
7904
7951
  context: "Context window usage %",
7905
7952
  cost: "Token cost estimate",
7906
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",
7907
7964
  brain: "Brain arbiter decisions",
7908
7965
  mailbox: "Mailbox unread messages",
7909
7966
  enhance: "Prompt-enhance countdown",
7910
- debug_stream: "Stream debug telemetry"
7967
+ debug_stream: "Stream debug telemetry",
7968
+ next_steps: "Next-step auto-submit countdown"
7911
7969
  };
7912
7970
  var ITEM_LINE = {
7971
+ breaker: 1,
7972
+ cache: 1,
7913
7973
  context: 1,
7914
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,
7915
7985
  elapsed: 2,
7916
- working_dir: 2,
7986
+ eternal_stage: 2,
7917
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,
7918
8001
  todos: 3,
7919
8002
  plan: 3,
7920
8003
  tasks: 3,
7921
- fleet: 4,
7922
- brain: 3,
7923
- mailbox: 3,
7924
- enhance: 3,
7925
- debug_stream: 3
8004
+ fleet_agents: 4,
8005
+ mailbox: 4
7926
8006
  };
7927
- Object.keys(ITEM_LINE).length;
8007
+ var STATUSLINE_FIELD_COUNT = Object.keys(ITEM_LINE).length;
7928
8008
  var STATUSLINE_ITEMS = [
7929
8009
  // Line 1
8010
+ "breaker",
8011
+ "cache",
7930
8012
  "context",
7931
8013
  "cost",
8014
+ "hint",
8015
+ "index",
8016
+ "model",
8017
+ "processes",
8018
+ "queue",
8019
+ "state",
8020
+ "tokens",
8021
+ "version",
7932
8022
  // Line 2
8023
+ "auto_proceed",
8024
+ "autonomy",
7933
8025
  "elapsed",
8026
+ "eternal_stage",
7934
8027
  "git",
8028
+ "goal",
8029
+ "mode",
8030
+ "project",
8031
+ "sessions",
8032
+ "token_saving",
8033
+ "tools",
7935
8034
  "working_dir",
8035
+ "yolo",
7936
8036
  // Line 3
7937
8037
  "brain",
7938
8038
  "debug_stream",
7939
8039
  "enhance",
7940
- "mailbox",
8040
+ "fleet",
8041
+ "next_steps",
7941
8042
  "plan",
7942
8043
  "tasks",
7943
8044
  "todos",
7944
8045
  // Line 4
7945
- "fleet"
8046
+ "fleet_agents",
8047
+ "mailbox"
7946
8048
  ];
7947
8049
  var STREAM_CHIP_KEYS = ["brain", "mailbox", "enhance", "debug_stream"];
7948
8050
  function groupByLine(items) {
@@ -7981,10 +8083,10 @@ function StatuslinePicker({
7981
8083
  if (hiddenSet.has(item)) return "off";
7982
8084
  if (STREAM_CHIP_KEYS.includes(item)) {
7983
8085
  const meta = visibleChipsMap.get(item);
7984
- if (!meta) return "off";
8086
+ if (!meta) return "auto";
7985
8087
  if (meta.expiresIn == null) return "on ";
7986
8088
  const remainingMs = meta.shownAt + meta.expiresIn * 6e4 - Date.now();
7987
- if (remainingMs <= 0) return "exp";
8089
+ if (remainingMs <= 0) return "auto";
7988
8090
  const remainingMin = Math.max(1, Math.ceil(remainingMs / 6e4));
7989
8091
  return `~${remainingMin}m`;
7990
8092
  }
@@ -7994,8 +8096,8 @@ function StatuslinePicker({
7994
8096
  if (hiddenSet.has(item)) return "red";
7995
8097
  if (STREAM_CHIP_KEYS.includes(item)) {
7996
8098
  const meta = visibleChipsMap.get(item);
7997
- if (!meta) return "red";
7998
- if (isChipExpired(meta)) return "red";
8099
+ if (!meta) return "cyan";
8100
+ if (isChipExpired(meta)) return "cyan";
7999
8101
  return "yellow";
8000
8102
  }
8001
8103
  return "green";
@@ -8024,7 +8126,7 @@ function StatuslinePicker({
8024
8126
  ] }, `row-${item}`);
8025
8127
  }),
8026
8128
  hasBelow ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u2193 ${totalFields - windowEnd} item${totalFields - windowEnd === 1 ? "" : "s"} below` }) : null,
8027
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Changes apply instantly \xB7 persisted to ~/.wrongstack/statusline.json \xB7 auto chips expire after ~5m" }),
8129
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Changes apply instantly \xB7 persisted to ~/.wrongstack/statusline.json \xB7 auto chips show when data exists" }),
8028
8130
  hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
8029
8131
  ] });
8030
8132
  }
@@ -8075,6 +8177,10 @@ function SlashMenu({ query, matches, selected }) {
8075
8177
  " ",
8076
8178
  m.argsHint
8077
8179
  ] }) : null,
8180
+ m.matchedAlias ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
8181
+ " alias /",
8182
+ m.matchedAlias
8183
+ ] }) : null,
8078
8184
  /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
8079
8185
  " \u2014 ",
8080
8186
  m.description
@@ -9731,6 +9837,79 @@ function oneLine(s2, max) {
9731
9837
  return collapsed.length <= max ? collapsed : `${collapsed.slice(0, max - 1)}\u2026`;
9732
9838
  }
9733
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
+
9734
9913
  // src/steering-preamble.ts
9735
9914
  function buildSteeringPreamble(snapshot, newDirection) {
9736
9915
  const lines = ["[STEERING \u2014 I pressed Esc to interrupt you mid-task on purpose.", ""];
@@ -9787,6 +9966,10 @@ function closePanels(state) {
9787
9966
  coordinator: { ...state.coordinator, monitorOpen: false }
9788
9967
  };
9789
9968
  }
9969
+ function clampContextLoad(load) {
9970
+ if (!Number.isFinite(load)) return 0;
9971
+ return Math.max(0, Math.min(1, load));
9972
+ }
9790
9973
  var MAX_TOOL_STREAM_RETAINED_CHARS = 1e5;
9791
9974
  var MAX_RETAINED_INPUT_CHARS = 2048;
9792
9975
  var MAX_RETAINED_INPUT_DEPTH = 4;
@@ -10168,12 +10351,26 @@ function reducer(state, action) {
10168
10351
  return {
10169
10352
  ...state,
10170
10353
  ...closePanels(state),
10171
- resumePicker: { open: true, sessions: action.sessions, selected: 0, busy: false, hint: void 0, error: void 0 }
10354
+ resumePicker: {
10355
+ open: true,
10356
+ sessions: action.sessions,
10357
+ selected: 0,
10358
+ busy: false,
10359
+ hint: void 0,
10360
+ error: void 0
10361
+ }
10172
10362
  };
10173
10363
  case "resumePickerClose":
10174
10364
  return {
10175
10365
  ...state,
10176
- resumePicker: { open: false, sessions: [], selected: 0, busy: false, hint: void 0, error: void 0 }
10366
+ resumePicker: {
10367
+ open: false,
10368
+ sessions: [],
10369
+ selected: 0,
10370
+ busy: false,
10371
+ hint: void 0,
10372
+ error: void 0
10373
+ }
10177
10374
  };
10178
10375
  case "resumePickerMove": {
10179
10376
  const nr = state.resumePicker.sessions.length;
@@ -10192,7 +10389,12 @@ function reducer(state, action) {
10192
10389
  const maxBannerId = banners.length > 0 ? Math.max(...banners.map((b) => b.id)) : 0;
10193
10390
  const shifted = action.entries.map((e, i) => ({ ...e, id: maxBannerId + 1 + i }));
10194
10391
  const nextId = maxBannerId + 1 + shifted.length;
10195
- return { ...state, entries: [...banners, ...shifted], nextId, historyGen: state.historyGen + 1 };
10392
+ return {
10393
+ ...state,
10394
+ entries: [...banners, ...shifted],
10395
+ nextId,
10396
+ historyGen: state.historyGen + 1
10397
+ };
10196
10398
  }
10197
10399
  case "settingsOpen":
10198
10400
  return {
@@ -10263,121 +10465,295 @@ function reducer(state, action) {
10263
10465
  const i = SETTINGS_MODES.indexOf(sp.mode);
10264
10466
  const base = i < 0 ? 0 : i;
10265
10467
  const next = (base + action.delta + SETTINGS_MODES.length) % SETTINGS_MODES.length;
10266
- return { ...state, settingsPicker: { ...sp, mode: expectDefined$1(SETTINGS_MODES[next]), hint: void 0 } };
10468
+ return {
10469
+ ...state,
10470
+ settingsPicker: { ...sp, mode: expectDefined$1(SETTINGS_MODES[next]), hint: void 0 }
10471
+ };
10267
10472
  }
10268
10473
  if (f === 1) {
10269
10474
  const j = DELAY_PRESETS_MS.indexOf(sp.delayMs);
10270
10475
  const base = j < 0 ? 0 : j;
10271
10476
  const next = (base + action.delta + DELAY_PRESETS_MS.length) % DELAY_PRESETS_MS.length;
10272
- return { ...state, settingsPicker: { ...sp, delayMs: expectDefined$1(DELAY_PRESETS_MS[next]), hint: void 0 } };
10477
+ return {
10478
+ ...state,
10479
+ settingsPicker: {
10480
+ ...sp,
10481
+ delayMs: expectDefined$1(DELAY_PRESETS_MS[next]),
10482
+ hint: void 0
10483
+ }
10484
+ };
10273
10485
  }
10274
- if (f === 2) return { ...state, settingsPicker: { ...sp, titleAnimation: !sp.titleAnimation, hint: void 0 } };
10486
+ if (f === 2)
10487
+ return {
10488
+ ...state,
10489
+ settingsPicker: { ...sp, titleAnimation: !sp.titleAnimation, hint: void 0 }
10490
+ };
10275
10491
  if (f === 3) return { ...state, settingsPicker: { ...sp, yolo: !sp.yolo, hint: void 0 } };
10276
- if (f === 4) return { ...state, settingsPicker: { ...sp, streamFleet: !sp.streamFleet, hint: void 0 } };
10277
- if (f === 5) return { ...state, settingsPicker: { ...sp, chime: !sp.chime, hint: void 0 } };
10278
- if (f === 6) return { ...state, settingsPicker: { ...sp, confirmExit: !sp.confirmExit, hint: void 0 } };
10279
- if (f === 7) return { ...state, settingsPicker: { ...sp, nextPrediction: !sp.nextPrediction, hint: void 0 } };
10280
- if (f === 8) return { ...state, settingsPicker: { ...sp, featureMcp: !sp.featureMcp, hint: bootHint } };
10281
- if (f === 9) return { ...state, settingsPicker: { ...sp, featurePlugins: !sp.featurePlugins, hint: bootHint } };
10282
- if (f === 10) return { ...state, settingsPicker: { ...sp, featureMemory: !sp.featureMemory, hint: bootHint } };
10283
- if (f === 11) return { ...state, settingsPicker: { ...sp, featureSkills: !sp.featureSkills, hint: bootHint } };
10284
- if (f === 12) return { ...state, settingsPicker: { ...sp, featureModelsRegistry: !sp.featureModelsRegistry, hint: bootHint } };
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
+ };
10285
10535
  if (f === 13) {
10286
- const i = TOKEN_SAVING_TIERS.indexOf(sp.tokenSavingTier);
10536
+ const i = TOKEN_SAVING_TIERS.indexOf(
10537
+ sp.tokenSavingTier
10538
+ );
10287
10539
  const base = i < 0 ? 0 : i;
10288
10540
  const next = (base + action.delta + TOKEN_SAVING_TIERS.length) % TOKEN_SAVING_TIERS.length;
10289
- return { ...state, settingsPicker: { ...sp, tokenSavingTier: TOKEN_SAVING_TIERS[next] ?? "off", hint: bootHint } };
10541
+ return {
10542
+ ...state,
10543
+ settingsPicker: {
10544
+ ...sp,
10545
+ tokenSavingTier: TOKEN_SAVING_TIERS[next] ?? "off",
10546
+ hint: bootHint
10547
+ }
10548
+ };
10290
10549
  }
10291
- if (f === 14) return { ...state, settingsPicker: { ...sp, allowOutsideProjectRoot: !sp.allowOutsideProjectRoot, hint: void 0 } };
10550
+ if (f === 14)
10551
+ return {
10552
+ ...state,
10553
+ settingsPicker: {
10554
+ ...sp,
10555
+ allowOutsideProjectRoot: !sp.allowOutsideProjectRoot,
10556
+ hint: void 0
10557
+ }
10558
+ };
10292
10559
  if (f === 15) {
10293
10560
  const j = MAX_ITERATIONS_PRESETS.indexOf(sp.maxIterations);
10294
10561
  const base = j < 0 ? 0 : j;
10295
10562
  const next = (base + action.delta + MAX_ITERATIONS_PRESETS.length) % MAX_ITERATIONS_PRESETS.length;
10296
- return { ...state, settingsPicker: { ...sp, maxIterations: expectDefined$1(MAX_ITERATIONS_PRESETS[next]), hint: void 0 } };
10563
+ return {
10564
+ ...state,
10565
+ settingsPicker: {
10566
+ ...sp,
10567
+ maxIterations: expectDefined$1(MAX_ITERATIONS_PRESETS[next]),
10568
+ hint: void 0
10569
+ }
10570
+ };
10297
10571
  }
10298
10572
  if (f === 16) {
10299
10573
  const aj = AUTO_PROCEED_MAX_PRESETS.indexOf(sp.autoProceedMaxIterations);
10300
10574
  const abase = aj < 0 ? 0 : aj;
10301
10575
  const anext = (abase + action.delta + AUTO_PROCEED_MAX_PRESETS.length) % AUTO_PROCEED_MAX_PRESETS.length;
10302
- return { ...state, settingsPicker: { ...sp, autoProceedMaxIterations: expectDefined$1(AUTO_PROCEED_MAX_PRESETS[anext]), hint: void 0 } };
10576
+ return {
10577
+ ...state,
10578
+ settingsPicker: {
10579
+ ...sp,
10580
+ autoProceedMaxIterations: expectDefined$1(AUTO_PROCEED_MAX_PRESETS[anext]),
10581
+ hint: void 0
10582
+ }
10583
+ };
10303
10584
  }
10304
10585
  if (f === 17) {
10305
10586
  const ej = ENHANCE_DELAY_PRESETS.indexOf(sp.enhanceDelayMs);
10306
10587
  const ebase = ej < 0 ? 0 : ej;
10307
10588
  const enext = (ebase + action.delta + ENHANCE_DELAY_PRESETS.length) % ENHANCE_DELAY_PRESETS.length;
10308
- return { ...state, settingsPicker: { ...sp, enhanceDelayMs: expectDefined$1(ENHANCE_DELAY_PRESETS[enext]), hint: void 0 } };
10589
+ return {
10590
+ ...state,
10591
+ settingsPicker: {
10592
+ ...sp,
10593
+ enhanceDelayMs: expectDefined$1(ENHANCE_DELAY_PRESETS[enext]),
10594
+ hint: void 0
10595
+ }
10596
+ };
10309
10597
  }
10310
- if (f === 18) return { ...state, settingsPicker: { ...sp, enhanceEnabled: !sp.enhanceEnabled, hint: void 0 } };
10598
+ if (f === 18)
10599
+ return {
10600
+ ...state,
10601
+ settingsPicker: { ...sp, enhanceEnabled: !sp.enhanceEnabled, hint: void 0 }
10602
+ };
10311
10603
  if (f === 19) {
10312
10604
  const i = ENHANCE_LANGUAGES.indexOf(sp.enhanceLanguage);
10313
10605
  const base = i < 0 ? 0 : i;
10314
10606
  const next = (base + action.delta + ENHANCE_LANGUAGES.length) % ENHANCE_LANGUAGES.length;
10315
- return { ...state, settingsPicker: { ...sp, enhanceLanguage: expectDefined$1(ENHANCE_LANGUAGES[next]), hint: void 0 } };
10607
+ return {
10608
+ ...state,
10609
+ settingsPicker: {
10610
+ ...sp,
10611
+ enhanceLanguage: expectDefined$1(ENHANCE_LANGUAGES[next]),
10612
+ hint: void 0
10613
+ }
10614
+ };
10316
10615
  }
10317
- if (f === 20) return { ...state, settingsPicker: { ...sp, indexOnStart: !sp.indexOnStart, hint: bootHint } };
10616
+ if (f === 20)
10617
+ return {
10618
+ ...state,
10619
+ settingsPicker: { ...sp, indexOnStart: !sp.indexOnStart, hint: bootHint }
10620
+ };
10318
10621
  if (f === 21) return state;
10319
10622
  if (f === 22) {
10320
10623
  const i = REASONING_MODES.indexOf(sp.reasoningMode);
10321
10624
  const base = i < 0 ? 0 : i;
10322
10625
  const next = (base + action.delta + REASONING_MODES.length) % REASONING_MODES.length;
10323
- return { ...state, settingsPicker: { ...sp, reasoningMode: expectDefined$1(REASONING_MODES[next]), hint: void 0 } };
10626
+ return {
10627
+ ...state,
10628
+ settingsPicker: {
10629
+ ...sp,
10630
+ reasoningMode: expectDefined$1(REASONING_MODES[next]),
10631
+ hint: void 0
10632
+ }
10633
+ };
10324
10634
  }
10325
10635
  if (f === 23) {
10326
- const i = REASONING_EFFORTS.indexOf(sp.reasoningEffort);
10636
+ const i = REASONING_EFFORTS.indexOf(
10637
+ sp.reasoningEffort
10638
+ );
10327
10639
  const base = i < 0 ? REASONING_EFFORTS.indexOf("high") : i;
10328
10640
  const next = (base + action.delta + REASONING_EFFORTS.length) % REASONING_EFFORTS.length;
10329
- return { ...state, settingsPicker: { ...sp, reasoningEffort: expectDefined$1(REASONING_EFFORTS[next]), hint: void 0 } };
10641
+ return {
10642
+ ...state,
10643
+ settingsPicker: {
10644
+ ...sp,
10645
+ reasoningEffort: expectDefined$1(REASONING_EFFORTS[next]),
10646
+ hint: void 0
10647
+ }
10648
+ };
10330
10649
  }
10331
- if (f === 24) return { ...state, settingsPicker: { ...sp, reasoningPreserve: !sp.reasoningPreserve, hint: void 0 } };
10650
+ if (f === 24)
10651
+ return {
10652
+ ...state,
10653
+ settingsPicker: { ...sp, reasoningPreserve: !sp.reasoningPreserve, hint: void 0 }
10654
+ };
10332
10655
  if (f === 25) {
10333
10656
  const i = CACHE_TTLS.indexOf(sp.cacheTtl);
10334
10657
  const base = i < 0 ? 0 : i;
10335
10658
  const next = (base + action.delta + CACHE_TTLS.length) % CACHE_TTLS.length;
10336
- return { ...state, settingsPicker: { ...sp, cacheTtl: expectDefined$1(CACHE_TTLS[next]), hint: void 0 } };
10659
+ return {
10660
+ ...state,
10661
+ settingsPicker: { ...sp, cacheTtl: expectDefined$1(CACHE_TTLS[next]), hint: void 0 }
10662
+ };
10337
10663
  }
10338
- if (f === 26) return { ...state, settingsPicker: { ...sp, contextAutoCompact: !sp.contextAutoCompact, hint: void 0 } };
10664
+ if (f === 26)
10665
+ return {
10666
+ ...state,
10667
+ settingsPicker: { ...sp, contextAutoCompact: !sp.contextAutoCompact, hint: void 0 }
10668
+ };
10339
10669
  if (f === 27) {
10340
10670
  const i = COMPACTOR_STRATEGIES.indexOf(sp.contextStrategy);
10341
10671
  const base = i < 0 ? 0 : i;
10342
10672
  const next = (base + action.delta + COMPACTOR_STRATEGIES.length) % COMPACTOR_STRATEGIES.length;
10343
- return { ...state, settingsPicker: { ...sp, contextStrategy: expectDefined$1(COMPACTOR_STRATEGIES[next]), hint: bootHint } };
10673
+ return {
10674
+ ...state,
10675
+ settingsPicker: {
10676
+ ...sp,
10677
+ contextStrategy: expectDefined$1(COMPACTOR_STRATEGIES[next]),
10678
+ hint: bootHint
10679
+ }
10680
+ };
10344
10681
  }
10345
10682
  if (f === 28) {
10346
10683
  const i = CONTEXT_MODES.indexOf(sp.contextMode);
10347
10684
  const base = i < 0 ? 0 : i;
10348
10685
  const next = (base + action.delta + CONTEXT_MODES.length) % CONTEXT_MODES.length;
10349
- return { ...state, settingsPicker: { ...sp, contextMode: expectDefined$1(CONTEXT_MODES[next]), hint: bootHint } };
10686
+ return {
10687
+ ...state,
10688
+ settingsPicker: {
10689
+ ...sp,
10690
+ contextMode: expectDefined$1(CONTEXT_MODES[next]),
10691
+ hint: bootHint
10692
+ }
10693
+ };
10350
10694
  }
10351
10695
  if (f === 29) {
10352
10696
  const j = MAX_CONCURRENT_PRESETS.indexOf(sp.maxConcurrent);
10353
10697
  const base = j < 0 ? 0 : j;
10354
10698
  const next = (base + action.delta + MAX_CONCURRENT_PRESETS.length) % MAX_CONCURRENT_PRESETS.length;
10355
- return { ...state, settingsPicker: { ...sp, maxConcurrent: expectDefined$1(MAX_CONCURRENT_PRESETS[next]), hint: void 0 } };
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
+ };
10356
10708
  }
10357
10709
  if (f === 30) {
10358
10710
  const i = LOG_LEVELS.indexOf(sp.logLevel);
10359
10711
  const base = i < 0 ? 0 : i;
10360
10712
  const next = (base + action.delta + LOG_LEVELS.length) % LOG_LEVELS.length;
10361
- return { ...state, settingsPicker: { ...sp, logLevel: expectDefined$1(LOG_LEVELS[next]), hint: void 0 } };
10713
+ return {
10714
+ ...state,
10715
+ settingsPicker: { ...sp, logLevel: expectDefined$1(LOG_LEVELS[next]), hint: void 0 }
10716
+ };
10362
10717
  }
10363
10718
  if (f === 31) {
10364
10719
  const i = AUDIT_LEVELS.indexOf(sp.auditLevel);
10365
10720
  const base = i < 0 ? 0 : i;
10366
10721
  const next = (base + action.delta + AUDIT_LEVELS.length) % AUDIT_LEVELS.length;
10367
- return { ...state, settingsPicker: { ...sp, auditLevel: expectDefined$1(AUDIT_LEVELS[next]), hint: void 0 } };
10722
+ return {
10723
+ ...state,
10724
+ settingsPicker: { ...sp, auditLevel: expectDefined$1(AUDIT_LEVELS[next]), hint: void 0 }
10725
+ };
10368
10726
  }
10369
- if (f === 32) return { ...state, settingsPicker: { ...sp, debugStream: !sp.debugStream, hint: void 0 } };
10727
+ if (f === 32)
10728
+ return {
10729
+ ...state,
10730
+ settingsPicker: { ...sp, debugStream: !sp.debugStream, hint: void 0 }
10731
+ };
10370
10732
  if (f === 33) {
10371
10733
  const i = STATUSLINE_MODES.indexOf(sp.statuslineMode);
10372
10734
  const base = i < 0 ? STATUSLINE_MODES.indexOf("detailed") : i;
10373
10735
  const next = (base + action.delta + STATUSLINE_MODES.length) % STATUSLINE_MODES.length;
10374
- return { ...state, settingsPicker: { ...sp, statuslineMode: expectDefined$1(STATUSLINE_MODES[next]), hint: void 0 } };
10736
+ return {
10737
+ ...state,
10738
+ settingsPicker: {
10739
+ ...sp,
10740
+ statuslineMode: expectDefined$1(STATUSLINE_MODES[next]),
10741
+ hint: void 0
10742
+ }
10743
+ };
10375
10744
  }
10376
10745
  if (f === 34) {
10377
10746
  const i = CONFIG_SCOPES.indexOf(sp.configScope);
10378
10747
  const base = i < 0 ? 0 : i;
10379
10748
  const next = (base + action.delta + CONFIG_SCOPES.length) % CONFIG_SCOPES.length;
10380
- return { ...state, settingsPicker: { ...sp, configScope: expectDefined$1(CONFIG_SCOPES[next]), hint: void 0 } };
10749
+ return {
10750
+ ...state,
10751
+ settingsPicker: {
10752
+ ...sp,
10753
+ configScope: expectDefined$1(CONFIG_SCOPES[next]),
10754
+ hint: void 0
10755
+ }
10756
+ };
10381
10757
  }
10382
10758
  return state;
10383
10759
  }
@@ -10388,17 +10764,29 @@ function reducer(state, action) {
10388
10764
  return {
10389
10765
  ...state,
10390
10766
  ...closePanels(state),
10391
- statuslinePicker: { open: true, field: 0, hiddenItems: action.hiddenItems, visibleChips: state.statuslinePicker.visibleChips, hint: void 0 }
10767
+ statuslinePicker: {
10768
+ open: true,
10769
+ field: 0,
10770
+ hiddenItems: action.hiddenItems,
10771
+ visibleChips: state.statuslinePicker.visibleChips,
10772
+ hint: void 0
10773
+ }
10392
10774
  };
10393
10775
  case "statuslineClose":
10394
- return { ...state, statuslinePicker: { ...state.statuslinePicker, open: false, hint: void 0 } };
10776
+ return {
10777
+ ...state,
10778
+ statuslinePicker: { ...state.statuslinePicker, open: false, hint: void 0 }
10779
+ };
10395
10780
  case "statuslineFieldMove": {
10396
- const totalFields = 13;
10781
+ const totalFields = STATUSLINE_FIELD_COUNT;
10397
10782
  const next = (state.statuslinePicker.field + action.delta + totalFields) % totalFields;
10398
- return { ...state, statuslinePicker: { ...state.statuslinePicker, field: next, hint: void 0 } };
10783
+ return {
10784
+ ...state,
10785
+ statuslinePicker: { ...state.statuslinePicker, field: next, hint: void 0 }
10786
+ };
10399
10787
  }
10400
10788
  case "statuslineFieldSet": {
10401
- const totalFields = 13;
10789
+ const totalFields = STATUSLINE_FIELD_COUNT;
10402
10790
  const field = action.field >= 0 && action.field < totalFields ? action.field : 0;
10403
10791
  return { ...state, statuslinePicker: { ...state.statuslinePicker, field, hint: void 0 } };
10404
10792
  }
@@ -10410,7 +10798,10 @@ function reducer(state, action) {
10410
10798
  } else {
10411
10799
  hiddenSet.add(action.item);
10412
10800
  }
10413
- return { ...state, statuslinePicker: { ...cur, hiddenItems: [...hiddenSet] } };
10801
+ return {
10802
+ ...state,
10803
+ statuslinePicker: { ...cur, hiddenItems: [...hiddenSet] }
10804
+ };
10414
10805
  }
10415
10806
  case "statuslineHint":
10416
10807
  return { ...state, statuslinePicker: { ...state.statuslinePicker, hint: action.text } };
@@ -10456,7 +10847,14 @@ function reducer(state, action) {
10456
10847
  case "projectPickerClose":
10457
10848
  return {
10458
10849
  ...state,
10459
- projectPicker: { open: false, allItems: [], items: [], selected: 0, filter: "", hint: void 0 }
10850
+ projectPicker: {
10851
+ open: false,
10852
+ allItems: [],
10853
+ items: [],
10854
+ selected: 0,
10855
+ filter: "",
10856
+ hint: void 0
10857
+ }
10460
10858
  };
10461
10859
  case "projectPickerMove": {
10462
10860
  const cur = state.projectPicker;
@@ -10724,13 +11122,14 @@ function reducer(state, action) {
10724
11122
  case "fleetCtxPct": {
10725
11123
  const cur = state.fleet[action.id];
10726
11124
  if (!cur) return state;
11125
+ const ctxPct = clampContextLoad(action.load);
10727
11126
  return {
10728
11127
  ...state,
10729
11128
  fleet: {
10730
11129
  ...state.fleet,
10731
11130
  [action.id]: {
10732
11131
  ...cur,
10733
- ctxPct: action.load,
11132
+ ctxPct,
10734
11133
  ctxTokens: action.tokens,
10735
11134
  ctxMaxTokens: action.maxContext,
10736
11135
  ctxCost: action.ctxCost,
@@ -10813,11 +11212,12 @@ function reducer(state, action) {
10813
11212
  };
10814
11213
  }
10815
11214
  case "leaderCtxPct": {
11215
+ const ctxPct = clampContextLoad(action.load);
10816
11216
  return {
10817
11217
  ...state,
10818
11218
  leader: {
10819
11219
  ...state.leader,
10820
- ctxPct: action.load,
11220
+ ctxPct,
10821
11221
  ctxTokens: action.tokens,
10822
11222
  ctxMaxTokens: action.maxContext,
10823
11223
  lastEventAt: Date.now()
@@ -10977,7 +11377,9 @@ function reducer(state, action) {
10977
11377
  }
10978
11378
  case "sddBoardSnapshot": {
10979
11379
  const monitorOpen = state.sddBoard?.monitorOpen ?? false;
10980
- return { ...state, sddBoard: { snapshot: action.snapshot, monitorOpen } };
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 } };
10981
11383
  }
10982
11384
  case "toggleSddBoardMonitor": {
10983
11385
  if (!state.sddBoard) return state;
@@ -10988,9 +11390,26 @@ function reducer(state, action) {
10988
11390
  sddBoard: { ...state.sddBoard, monitorOpen: true }
10989
11391
  } : {
10990
11392
  ...state,
10991
- sddBoard: { ...state.sddBoard, monitorOpen: false }
11393
+ sddBoard: { ...state.sddBoard, monitorOpen: false, focusColumn: void 0 }
10992
11394
  };
10993
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
+ }
10994
11413
  case "worktreeUpsert": {
10995
11414
  const prev = state.worktrees[action.handleId];
10996
11415
  const merged = {
@@ -11368,32 +11787,56 @@ function nextInputWordStart(buffer, cursor) {
11368
11787
  }
11369
11788
  function rehydrateHistory(messages, startId, toolCalls) {
11370
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 = [];
11371
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
+ });
11372
11813
  for (const msg of messages) {
11373
11814
  if (msg.role === "system") continue;
11374
- const text = typeof msg.content === "string" ? msg.content : msg.content.filter((b) => b.type === "text").map((b) => b.text).join("");
11375
- const trimmed = text.trim();
11376
- if (!trimmed) continue;
11815
+ const text = textOf(msg).trim();
11816
+ if (!text) continue;
11377
11817
  if (msg.role === "user") {
11378
- entries.push({ id: nextId++, kind: "user", text: trimmed });
11379
- } else if (msg.role === "assistant") {
11380
- entries.push({ id: nextId++, kind: "assistant", text: trimmed });
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
+ }
11381
11832
  }
11382
11833
  }
11383
- if (toolCalls && toolCalls.length > 0) {
11834
+ if (toolCalls) {
11384
11835
  for (const tc of toolCalls) {
11385
- entries.push({
11386
- id: nextId++,
11387
- kind: "tool",
11388
- name: tc.name,
11389
- durationMs: tc.durationMs,
11390
- ok: tc.ok,
11391
- outputBytes: tc.outputBytes,
11392
- outputTokens: tc.outputTokens,
11393
- outputLines: tc.outputLines
11394
- });
11836
+ if (!consumed.has(tc.id)) fallback.push(toolEntryFor(tc));
11395
11837
  }
11396
11838
  }
11839
+ entries.push(...fallback);
11397
11840
  return entries;
11398
11841
  }
11399
11842
  var PASTE_THRESHOLD_CHARS = 200;
@@ -11451,6 +11894,7 @@ function App({
11451
11894
  director,
11452
11895
  fleetRoster,
11453
11896
  onClearHistory,
11897
+ clearTerminal,
11454
11898
  listSessions,
11455
11899
  onResumeSession,
11456
11900
  fleetStreamController,
@@ -11794,8 +12238,22 @@ function App({
11794
12238
  stateRef.current = state;
11795
12239
  const draftRef = useRef({ buffer: state.buffer, cursor: state.cursor });
11796
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]);
11797
12255
  const [mouseMode, setMouseMode] = useState(mouse);
11798
- 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;
11799
12257
  const mouseTrackingOn = mouseMode || pickerOverlayOpen;
11800
12258
  const mouseWrittenRef = useRef(false);
11801
12259
  useEffect(() => {
@@ -12427,24 +12885,7 @@ function App({
12427
12885
  return;
12428
12886
  }
12429
12887
  const query = trimmed.slice(1).toLowerCase();
12430
- const allCommands = slashRegistry.listWithOwner();
12431
- const CATEGORY_ORDER = ["Run", "Session", "Inspect", "Agent", "Config", "App"];
12432
- const matches = allCommands.filter(({ cmd }) => {
12433
- if (query === "" && cmd.hidden) return false;
12434
- const name = cmd.name.toLowerCase();
12435
- const aliases = cmd.aliases ?? [];
12436
- return name.includes(query) || aliases.some((a) => a.toLowerCase().includes(query));
12437
- }).map(({ cmd, owner }) => ({
12438
- name: cmd.name,
12439
- description: cmd.description,
12440
- argsHint: cmd.argsHint,
12441
- isBuiltin: owner === "core",
12442
- category: cmd.category ?? "App"
12443
- })).sort((a, b) => {
12444
- const catDiff = CATEGORY_ORDER.indexOf(a.category) - CATEGORY_ORDER.indexOf(b.category);
12445
- if (catDiff !== 0) return catDiff;
12446
- return a.name.localeCompare(b.name);
12447
- });
12888
+ const matches = buildSlashCommandMatches(slashRegistry.listWithOwner(), query);
12448
12889
  if (!state.slashPicker.open) {
12449
12890
  dispatch({ type: "slashPickerOpen", query, matches });
12450
12891
  } else if (state.slashPicker.query !== query) {
@@ -13018,12 +13459,41 @@ function App({
13018
13459
  aliases: ["sl"],
13019
13460
  description: "Customize status bar chips: /statusline (interactive) or /statusline <item> [on|off]",
13020
13461
  async run(args) {
13021
- if (args.trim()) return { message: void 0 };
13022
- const hookHidden = hiddenItemsRef.current;
13023
- const reducerStreamHidden = stateRef.current.statuslinePicker.hiddenItems.filter(
13024
- (item) => !hookHidden.includes(item)
13025
- );
13026
- dispatch({ type: "statuslineOpen", hiddenItems: [...hookHidden, ...reducerStreamHidden] });
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();
13027
13497
  return { message: void 0 };
13028
13498
  }
13029
13499
  };
@@ -13031,7 +13501,7 @@ function App({
13031
13501
  return () => {
13032
13502
  slashRegistry.unregister("statusline");
13033
13503
  };
13034
- }, [slashRegistry]);
13504
+ }, [slashRegistry, openStatuslinePicker, setHiddenItems]);
13035
13505
  useEffect(() => {
13036
13506
  const cmd = {
13037
13507
  name: "mailbox",
@@ -14009,7 +14479,7 @@ function App({
14009
14479
  openProjectPicker();
14010
14480
  return;
14011
14481
  }
14012
- const action = actionForFKeyPanel(entry, state.statuslinePicker.hiddenItems);
14482
+ const action = actionForFKeyPanel(entry, statuslineHiddenForPicker());
14013
14483
  if (action) dispatch(action);
14014
14484
  return;
14015
14485
  }
@@ -14185,6 +14655,14 @@ function App({
14185
14655
  return;
14186
14656
  }
14187
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
+ }
14188
14666
  if (input === "c") {
14189
14667
  const run = getSddRun?.();
14190
14668
  if (run) {
@@ -14307,7 +14785,7 @@ function App({
14307
14785
  return;
14308
14786
  }
14309
14787
  if (key.fn === 12) {
14310
- dispatch({ type: "statuslineOpen", hiddenItems: state.statuslinePicker.hiddenItems });
14788
+ openStatuslinePicker();
14311
14789
  return;
14312
14790
  }
14313
14791
  if (state.settingsPicker.open) {
@@ -14643,6 +15121,10 @@ function App({
14643
15121
  version: appVersion,
14644
15122
  state: state.status,
14645
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,
14646
15128
  model: `${liveProvider}/${liveModel}`
14647
15129
  });
14648
15130
  if (inSpan(span)) {
@@ -14660,27 +15142,24 @@ function App({
14660
15142
  dispatch({ type: "toggleTodosMonitor" });
14661
15143
  return;
14662
15144
  }
14663
- const hiddenSet = new Set(state.statuslinePicker.hiddenItems);
15145
+ const hiddenSet = new Set(statuslineHiddenForPicker());
14664
15146
  if (my === rowFor(2)) {
14665
15147
  const mxLocal = mx - SB_PADX2 - 1;
14666
15148
  if (!hiddenSet.has("todos") && mxLocal >= 0 && mxLocal < 20) {
14667
- dispatch({ type: "statuslineFieldSet", field: 11 });
14668
- dispatch({ type: "statuslineOpen", hiddenItems: state.statuslinePicker.hiddenItems });
15149
+ openStatuslinePicker(STATUSLINE_ITEMS.indexOf("todos"));
14669
15150
  return;
14670
15151
  }
14671
15152
  if (!hiddenSet.has("plan")) {
14672
15153
  const planStart = 21;
14673
15154
  if (mxLocal >= planStart && mxLocal < planStart + 22) {
14674
- dispatch({ type: "statuslineFieldSet", field: 9 });
14675
- dispatch({ type: "statuslineOpen", hiddenItems: state.statuslinePicker.hiddenItems });
15155
+ openStatuslinePicker(STATUSLINE_ITEMS.indexOf("plan"));
14676
15156
  return;
14677
15157
  }
14678
15158
  }
14679
15159
  if (!hiddenSet.has("tasks")) {
14680
15160
  const tasksStart = 44;
14681
15161
  if (mxLocal >= tasksStart && mxLocal < tasksStart + 26) {
14682
- dispatch({ type: "statuslineFieldSet", field: 10 });
14683
- dispatch({ type: "statuslineOpen", hiddenItems: state.statuslinePicker.hiddenItems });
15162
+ openStatuslinePicker(STATUSLINE_ITEMS.indexOf("tasks"));
14684
15163
  return;
14685
15164
  }
14686
15165
  }
@@ -14689,8 +15168,7 @@ function App({
14689
15168
  const mxLocal = mx - SB_PADX2 - 1;
14690
15169
  const fleetStart = 0;
14691
15170
  if (mxLocal >= fleetStart && mxLocal < fleetStart + 22) {
14692
- dispatch({ type: "statuslineFieldSet", field: 12 });
14693
- dispatch({ type: "statuslineOpen", hiddenItems: state.statuslinePicker.hiddenItems });
15171
+ openStatuslinePicker(STATUSLINE_ITEMS.indexOf("fleet"));
14694
15172
  return;
14695
15173
  }
14696
15174
  }
@@ -15133,6 +15611,7 @@ ${content}
15133
15611
  }
15134
15612
  const cmd = trimmed.slice(1).split(/\s+/, 1)[0];
15135
15613
  if (cmd === "clear") {
15614
+ clearTerminal?.();
15136
15615
  onClearHistory?.(dispatch);
15137
15616
  tokenCounter?.reset();
15138
15617
  }
@@ -15249,7 +15728,7 @@ User message:
15249
15728
  pushSubmittedHistory();
15250
15729
  clearDraft();
15251
15730
  const blocks = await builder.submit();
15252
- if (state.status !== "idle") {
15731
+ if (state.status !== "idle" && !steering) {
15253
15732
  if (autonomyLive === "auto" && nextStepsAutoSubmitTimerRef.current != null) {
15254
15733
  switchAutonomy?.("off");
15255
15734
  }
@@ -15669,7 +16148,13 @@ User message:
15669
16148
  elapsedMs: state.autoPhase.elapsedMs,
15670
16149
  nowTick
15671
16150
  }
15672
- ) : state.sddBoard?.monitorOpen ? /* @__PURE__ */ jsx(SddBoardOverlay, { snapshot: state.sddBoard.snapshot }) : state.worktreeMonitorOpen ? /* @__PURE__ */ jsx(
16151
+ ) : state.sddBoard?.monitorOpen ? /* @__PURE__ */ jsx(
16152
+ SddBoardOverlay,
16153
+ {
16154
+ snapshot: state.sddBoard.snapshot,
16155
+ focusColumn: state.sddBoard.focusColumn ?? null
16156
+ }
16157
+ ) : state.worktreeMonitorOpen ? /* @__PURE__ */ jsx(
15673
16158
  WorktreeMonitor,
15674
16159
  {
15675
16160
  worktrees: state.worktrees,
@@ -16069,6 +16554,13 @@ async function runTui(opts) {
16069
16554
  };
16070
16555
  opts.requestExit = requestExit;
16071
16556
  let instance;
16557
+ const clearTerminal = () => {
16558
+ try {
16559
+ instance?.clear();
16560
+ stdout.write("\x1B[2J\x1B[3J\x1B[H");
16561
+ } catch {
16562
+ }
16563
+ };
16072
16564
  try {
16073
16565
  instance = render(
16074
16566
  React5.createElement(App, {
@@ -16104,6 +16596,7 @@ async function runTui(opts) {
16104
16596
  director: opts.director ?? null,
16105
16597
  fleetRoster: opts.fleetRoster,
16106
16598
  onClearHistory: opts.onClearHistory ? (dispatch) => opts.onClearHistory?.(dispatch) : void 0,
16599
+ clearTerminal,
16107
16600
  fleetStreamController: opts.fleetStreamController,
16108
16601
  interruptController: opts.interruptController,
16109
16602
  enhanceController: opts.enhanceController,