@wrongstack/tui 0.264.0 → 0.267.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +35 -3
- package/dist/index.js +1178 -103
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { writeErr, resolveProjectDir, wstackGlobalRoot, GlobalMailbox, resolveWstackPaths, loadGoal, InputBuilder, DefaultSessionRewinder, writeOut, formatTodosList, buildGoalPreamble, expectDefined as expectDefined$1, shouldEnhance, enhanceUserPrompt, recentTextTurns, normalizedEqual, buildChildEnv } from '@wrongstack/core';
|
|
1
|
+
import { writeErr, resolveProjectDir, wstackGlobalRoot, GlobalMailbox, resolveWstackPaths, loadGoal, InputBuilder, DefaultSessionRewinder, writeOut, formatTodosList, buildGoalPreamble, expectDefined as expectDefined$1, projectSlug, shouldEnhance, enhanceUserPrompt, recentTextTurns, normalizedEqual, buildChildEnv } from '@wrongstack/core';
|
|
2
2
|
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
|
-
import * as
|
|
5
|
+
import * as path5 from 'path';
|
|
6
6
|
import React5, { forwardRef, useState, useEffect, useMemo, memo, useRef, useCallback, useReducer, useLayoutEffect } from 'react';
|
|
7
|
-
import * as
|
|
8
|
-
import { expectDefined, toErrorMessage } from '@wrongstack/core/utils';
|
|
7
|
+
import * as fs3 from 'fs/promises';
|
|
8
|
+
import { expectDefined, toErrorMessage, resolveWstackPaths as resolveWstackPaths$1 } from '@wrongstack/core/utils';
|
|
9
9
|
import { routeImagesForModel } from '@wrongstack/runtime/vision';
|
|
10
10
|
import { getIndexState, onIndexStateChange, getProcessRegistry } from '@wrongstack/tools';
|
|
11
11
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
12
12
|
import { readClipboardText, readClipboardImage } from '@wrongstack/runtime/clipboard';
|
|
13
|
+
import { getToolIcon, TOOL_ICON_CONFIG } from '@wrongstack/tools/tool-icons';
|
|
13
14
|
import * as v8 from 'v8';
|
|
14
15
|
import { spawn } from 'child_process';
|
|
15
16
|
|
|
@@ -108,6 +109,18 @@ function useTokenCounterRefresh(tokenCounter, events) {
|
|
|
108
109
|
}, [tokenCounter, events]);
|
|
109
110
|
return data;
|
|
110
111
|
}
|
|
112
|
+
function chipExpired(meta, now = Date.now()) {
|
|
113
|
+
if (meta.expiresIn == null) return false;
|
|
114
|
+
return now >= meta.shownAt + meta.expiresIn * 6e4;
|
|
115
|
+
}
|
|
116
|
+
function isStreamChipVisible(key, dataIsPresent, hiddenSet, visibleChips) {
|
|
117
|
+
if (!dataIsPresent) return false;
|
|
118
|
+
if (hiddenSet.has(key)) return false;
|
|
119
|
+
const meta = visibleChips.find((c) => c.key === key);
|
|
120
|
+
if (!meta) return false;
|
|
121
|
+
if (chipExpired(meta)) return false;
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
111
124
|
var MODE_ICONS = {
|
|
112
125
|
teach: "\u{1F9D1}\u200D\u{1F3EB}",
|
|
113
126
|
brief: "\u26A1",
|
|
@@ -166,6 +179,7 @@ function StatusBar({
|
|
|
166
179
|
eternalStage,
|
|
167
180
|
goalSummary,
|
|
168
181
|
indexState,
|
|
182
|
+
breakerCountdown,
|
|
169
183
|
modeLabel,
|
|
170
184
|
debugStreamStats,
|
|
171
185
|
enhanceCountdown,
|
|
@@ -175,7 +189,8 @@ function StatusBar({
|
|
|
175
189
|
sessionCount,
|
|
176
190
|
mailbox,
|
|
177
191
|
tokenSavingMode,
|
|
178
|
-
toolCount
|
|
192
|
+
toolCount,
|
|
193
|
+
visibleChips = []
|
|
179
194
|
}) {
|
|
180
195
|
const { stdout } = useStdout();
|
|
181
196
|
const [termWidth, setTermWidth] = useState(stdout?.columns ?? 90);
|
|
@@ -216,13 +231,13 @@ function StatusBar({
|
|
|
216
231
|
const hasAutoProceed = autoProceedCountdown != null && autoProceedCountdown > 0;
|
|
217
232
|
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;
|
|
218
233
|
const fleetHasActivity = fleet && (fleet.running > 0 || fleet.idle > 0 || fleet.pending > 0 || fleet.completed > 0) || subagentCount > 0;
|
|
219
|
-
const
|
|
220
|
-
const
|
|
221
|
-
const
|
|
234
|
+
const showBrain = isStreamChipVisible("brain", brain, hiddenSet ?? /* @__PURE__ */ new Set(), visibleChips);
|
|
235
|
+
const showDebugStream = isStreamChipVisible("debug_stream", debugStreamStats, hiddenSet ?? /* @__PURE__ */ new Set(), visibleChips);
|
|
236
|
+
const showEnhance = isStreamChipVisible("enhance", enhanceCountdown, hiddenSet ?? /* @__PURE__ */ new Set(), visibleChips);
|
|
222
237
|
const hasNextStepsAutoSubmit = nextStepsAutoSubmitCountdown != null && nextStepsAutoSubmitCountdown > 0;
|
|
223
238
|
const countdownColor = nextStepsAutoSubmitCountdown != null ? nextStepsAutoSubmitCountdown > 20 ? "green" : nextStepsAutoSubmitCountdown > 10 ? "yellow" : "red" : "green";
|
|
224
239
|
const hasTaskActivity = tasks && (tasks.pending > 0 || tasks.inProgress > 0 || tasks.completed > 0 || tasks.blocked > 0 || tasks.failed > 0);
|
|
225
|
-
const hasThirdLine = todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || hasTaskActivity || fleetHasActivity ||
|
|
240
|
+
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;
|
|
226
241
|
return /* @__PURE__ */ jsxs(
|
|
227
242
|
Box,
|
|
228
243
|
{
|
|
@@ -302,7 +317,7 @@ function StatusBar({
|
|
|
302
317
|
"%"
|
|
303
318
|
] })
|
|
304
319
|
] }) : null,
|
|
305
|
-
cost && cost.total > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
320
|
+
cost && cost.total > 0 && !hiddenSet.has("cost") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
306
321
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
307
322
|
/* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
308
323
|
"$",
|
|
@@ -340,7 +355,21 @@ function StatusBar({
|
|
|
340
355
|
] }) : indexState?.circuit?.state === "open" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
341
356
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
342
357
|
/* @__PURE__ */ jsx(Text, { color: "red", children: "\u2699 index paused (/reindex)" })
|
|
343
|
-
] }) : null
|
|
358
|
+
] }) : null,
|
|
359
|
+
breakerCountdown ? (() => {
|
|
360
|
+
const secs = Math.ceil(breakerCountdown.remainingMs / 1e3);
|
|
361
|
+
const ratio = breakerCountdown.totalMs > 0 ? breakerCountdown.remainingMs / breakerCountdown.totalMs : 0;
|
|
362
|
+
const c = secs > 20 ? "green" : secs > 10 ? "yellow" : "red";
|
|
363
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
364
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
365
|
+
/* @__PURE__ */ jsxs(Text, { color: c, bold: true, children: [
|
|
366
|
+
"\u26A1 kill/reset in ",
|
|
367
|
+
secs,
|
|
368
|
+
"s",
|
|
369
|
+
ratio <= 0.25 ? "!" : ""
|
|
370
|
+
] })
|
|
371
|
+
] });
|
|
372
|
+
})() : null
|
|
344
373
|
] })
|
|
345
374
|
) }),
|
|
346
375
|
hasSecondLine ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
@@ -416,7 +445,7 @@ function StatusBar({
|
|
|
416
445
|
"s"
|
|
417
446
|
] })
|
|
418
447
|
] }) : null,
|
|
419
|
-
git ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
448
|
+
git && !hiddenSet.has("git") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
420
449
|
yolo || startedAt != null || projectName || workingDir ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
421
450
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
422
451
|
/* @__PURE__ */ jsxs(Text, { color: "magenta", children: [
|
|
@@ -434,7 +463,7 @@ function StatusBar({
|
|
|
434
463
|
] })
|
|
435
464
|
] }) : null,
|
|
436
465
|
sessionCount != null && sessionCount > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
437
|
-
yolo || startedAt != null || projectName || workingDir || git ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
466
|
+
yolo || startedAt != null || projectName || workingDir || git && !hiddenSet.has("git") ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
438
467
|
/* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
439
468
|
"\u29C9 ",
|
|
440
469
|
sessionCount,
|
|
@@ -443,7 +472,7 @@ function StatusBar({
|
|
|
443
472
|
] })
|
|
444
473
|
] }) : null,
|
|
445
474
|
toolCount != null ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
446
|
-
yolo || startedAt != null || projectName || workingDir || git || sessionCount ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
475
|
+
yolo || startedAt != null || projectName || workingDir || git && !hiddenSet.has("git") || sessionCount ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
447
476
|
/* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
448
477
|
"\u{1F527} ",
|
|
449
478
|
toolCount,
|
|
@@ -452,12 +481,12 @@ function StatusBar({
|
|
|
452
481
|
] })
|
|
453
482
|
] }) : null,
|
|
454
483
|
tokenSavingMode ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
455
|
-
yolo || startedAt != null || projectName || workingDir || git || sessionCount || toolCount ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
484
|
+
yolo || startedAt != null || projectName || workingDir || git && !hiddenSet.has("git") || sessionCount || toolCount ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
456
485
|
/* @__PURE__ */ jsx(Text, { color: "yellow", bold: true, children: "\u{1F4BE} save" })
|
|
457
486
|
] }) : null
|
|
458
487
|
] }) : /* @__PURE__ */ jsx(Box, { height: 1, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
|
|
459
488
|
hasThirdLine ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
460
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
489
|
+
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) && !hiddenSet.has("todos") ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
461
490
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "todos " }),
|
|
462
491
|
todos.inProgress > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
463
492
|
"\u231B",
|
|
@@ -474,8 +503,8 @@ function StatusBar({
|
|
|
474
503
|
todos.completed
|
|
475
504
|
] }) : null
|
|
476
505
|
] }) : null,
|
|
477
|
-
plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
478
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
506
|
+
plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) && !hiddenSet.has("plan") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
507
|
+
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) && !hiddenSet.has("todos") ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
479
508
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
480
509
|
/* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u{1F4CB} " }),
|
|
481
510
|
plan.inProgress > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
@@ -491,11 +520,16 @@ function StatusBar({
|
|
|
491
520
|
plan.done > 0 ? /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
492
521
|
"\u2713",
|
|
493
522
|
plan.done
|
|
523
|
+
] }) : null,
|
|
524
|
+
plan.scope ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
525
|
+
" [",
|
|
526
|
+
plan.scope,
|
|
527
|
+
"]"
|
|
494
528
|
] }) : null
|
|
495
529
|
] })
|
|
496
530
|
] }) : null,
|
|
497
|
-
hasTaskActivity ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
498
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
531
|
+
hasTaskActivity && !hiddenSet.has("tasks") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
532
|
+
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,
|
|
499
533
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
500
534
|
/* @__PURE__ */ jsx(Text, { color: "magenta", children: "\u26A1 " }),
|
|
501
535
|
tasks.inProgress > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
@@ -521,11 +555,16 @@ function StatusBar({
|
|
|
521
555
|
tasks.failed > 0 ? /* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
522
556
|
"\u2717",
|
|
523
557
|
tasks.failed
|
|
558
|
+
] }) : null,
|
|
559
|
+
tasks.scope ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
560
|
+
" [",
|
|
561
|
+
tasks.scope,
|
|
562
|
+
"]"
|
|
524
563
|
] }) : null
|
|
525
564
|
] })
|
|
526
565
|
] }) : null,
|
|
527
|
-
fleetHasActivity ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
528
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
566
|
+
fleetHasActivity && !hiddenSet.has("fleet") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
567
|
+
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,
|
|
529
568
|
fleet ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
530
569
|
/* @__PURE__ */ jsx(Text, { color: "blue", children: "\u{1F310} " }),
|
|
531
570
|
fleet.running > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
@@ -555,12 +594,12 @@ function StatusBar({
|
|
|
555
594
|
subagentCount === 1 ? "" : "s"
|
|
556
595
|
] })
|
|
557
596
|
] }) : null,
|
|
558
|
-
|
|
559
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || fleetHasActivity ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
597
|
+
showBrain ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
598
|
+
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,
|
|
560
599
|
/* @__PURE__ */ jsx(BrainChip, { brain })
|
|
561
600
|
] }) : null,
|
|
562
|
-
|
|
563
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || fleetHasActivity ||
|
|
601
|
+
showDebugStream ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
602
|
+
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,
|
|
564
603
|
/* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
565
604
|
/* @__PURE__ */ jsx(Text, { bold: true, children: "\u{1F41B} stream" }),
|
|
566
605
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
@@ -583,8 +622,8 @@ function StatusBar({
|
|
|
583
622
|
] })
|
|
584
623
|
] })
|
|
585
624
|
] }) : null,
|
|
586
|
-
|
|
587
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || fleetHasActivity ||
|
|
625
|
+
showEnhance ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
626
|
+
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,
|
|
588
627
|
/* @__PURE__ */ jsxs(Text, { color: enhanceCountdown > 15 ? "green" : enhanceCountdown > 5 ? "yellow" : "red", children: [
|
|
589
628
|
"\u23F3 auto-send in ",
|
|
590
629
|
enhanceCountdown,
|
|
@@ -592,7 +631,7 @@ function StatusBar({
|
|
|
592
631
|
] })
|
|
593
632
|
] }) : null,
|
|
594
633
|
hasNextStepsAutoSubmit && nextStepsAutoSubmitCountdown != null ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
595
|
-
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || fleetHasActivity ||
|
|
634
|
+
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,
|
|
596
635
|
/* @__PURE__ */ jsxs(Text, { color: countdownColor, bold: true, children: [
|
|
597
636
|
"\u23F3 ",
|
|
598
637
|
nextStepsAutoSubmitCountdown,
|
|
@@ -605,7 +644,7 @@ function StatusBar({
|
|
|
605
644
|
] })
|
|
606
645
|
] }) : null
|
|
607
646
|
] }) : /* @__PURE__ */ jsx(Box, { height: 1, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
|
|
608
|
-
mailbox ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
647
|
+
mailbox && !hiddenSet.has("mailbox") ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
609
648
|
mailbox.unread > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", bold: true, children: [
|
|
610
649
|
"\u2709 ",
|
|
611
650
|
mailbox.unread,
|
|
@@ -1765,8 +1804,8 @@ function FilePicker({ query, matches, selected }) {
|
|
|
1765
1804
|
] }, m))
|
|
1766
1805
|
] });
|
|
1767
1806
|
}
|
|
1768
|
-
function highlight(
|
|
1769
|
-
return
|
|
1807
|
+
function highlight(path7, _query) {
|
|
1808
|
+
return path7;
|
|
1770
1809
|
}
|
|
1771
1810
|
function FleetPanel({
|
|
1772
1811
|
entries,
|
|
@@ -1833,6 +1872,43 @@ function FleetPanel({
|
|
|
1833
1872
|
] }) : null
|
|
1834
1873
|
] });
|
|
1835
1874
|
}
|
|
1875
|
+
var F_KEY_ENTRIES = [
|
|
1876
|
+
{ key: 1, label: "Project switcher", action: "projectPickerOpen" },
|
|
1877
|
+
{ key: 2, label: "Fleet orchestration monitor", action: "toggleMonitor" },
|
|
1878
|
+
{ key: 3, label: "Agents live monitor", action: "toggleAgentsMonitor" },
|
|
1879
|
+
{ key: 4, label: "Worktree monitor", action: "toggleWorktreeMonitor" },
|
|
1880
|
+
{ key: 5, label: "Autonomy settings", action: "togglePlanPanel" },
|
|
1881
|
+
{ key: 6, label: "Todos monitor overlay", action: "toggleTodosMonitor" },
|
|
1882
|
+
{ key: 7, label: "Queue panel", action: "toggleQueuePanel" },
|
|
1883
|
+
{ key: 8, label: "Process list overlay", action: "toggleProcessList" },
|
|
1884
|
+
{ key: 9, label: "Goal panel", action: "toggleGoalPanel" },
|
|
1885
|
+
{ key: 10, label: "Live sessions panel", action: "toggleSessionsPanel" },
|
|
1886
|
+
{ key: 11, label: "Coordinator monitor", action: "toggleCoordinatorMonitor" },
|
|
1887
|
+
{ key: 12, label: "Status line picker", action: "statuslineOpen" }
|
|
1888
|
+
];
|
|
1889
|
+
function FKeyPicker({ selected }) {
|
|
1890
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, flexShrink: 0, children: [
|
|
1891
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u2501\u2501 F-Key Panels \u2501\u2501" }),
|
|
1892
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191\u2193 navigate \xB7 Enter open \xB7 Esc close" }),
|
|
1893
|
+
F_KEY_ENTRIES.map((entry) => {
|
|
1894
|
+
const idx = entry.key - 1;
|
|
1895
|
+
const isSelected = idx === selected;
|
|
1896
|
+
const marker = isSelected ? "\u25B8" : " ";
|
|
1897
|
+
const labelColor = isSelected ? "cyan" : void 0;
|
|
1898
|
+
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
1899
|
+
/* @__PURE__ */ jsx(Box, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx(Text, { color: "dimColor", children: marker }) }),
|
|
1900
|
+
/* @__PURE__ */ jsxs(Text, { color: "dimColor", children: [
|
|
1901
|
+
"F",
|
|
1902
|
+
entry.key
|
|
1903
|
+
] }),
|
|
1904
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
1905
|
+
/* @__PURE__ */ jsx(Text, { color: labelColor, children: entry.label })
|
|
1906
|
+
] }, entry.key);
|
|
1907
|
+
}),
|
|
1908
|
+
selected > 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191 Scroll up" }) : null,
|
|
1909
|
+
selected < 11 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2193 Scroll down" }) : null
|
|
1910
|
+
] });
|
|
1911
|
+
}
|
|
1836
1912
|
function fmtTime(iso) {
|
|
1837
1913
|
const d = new Date(iso);
|
|
1838
1914
|
const now = Date.now();
|
|
@@ -1930,6 +2006,36 @@ function MailboxPanel({
|
|
|
1930
2006
|
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "/mailbox \u2014 Esc to close" }) })
|
|
1931
2007
|
] });
|
|
1932
2008
|
}
|
|
2009
|
+
var TOOL_GLYPHS = {
|
|
2010
|
+
file: "\u25A4",
|
|
2011
|
+
edit: "\u270E",
|
|
2012
|
+
search: "\u2315",
|
|
2013
|
+
folder: "\u25A3",
|
|
2014
|
+
terminal: "\u2318",
|
|
2015
|
+
web: "\u25C8",
|
|
2016
|
+
git: "\u2387",
|
|
2017
|
+
tree: "\u2630",
|
|
2018
|
+
code: "\u2699",
|
|
2019
|
+
test: "\u2697",
|
|
2020
|
+
package: "\u2B22",
|
|
2021
|
+
document: "\u2637",
|
|
2022
|
+
scaffold: "\u2731",
|
|
2023
|
+
todo: "\u2610",
|
|
2024
|
+
plan: "\u2756",
|
|
2025
|
+
task: "\u25AA",
|
|
2026
|
+
meta: "\u274F",
|
|
2027
|
+
index: "\u229B",
|
|
2028
|
+
json: "\u2317",
|
|
2029
|
+
diff: "\u2206",
|
|
2030
|
+
logs: "\u2261",
|
|
2031
|
+
settings: "\u2699",
|
|
2032
|
+
brain: "\u2726",
|
|
2033
|
+
fallback: "\u2022"
|
|
2034
|
+
};
|
|
2035
|
+
function getToolVisual(name) {
|
|
2036
|
+
const id = getToolIcon(name);
|
|
2037
|
+
return { glyph: TOOL_GLYPHS[id], color: TOOL_ICON_CONFIG[id].color };
|
|
2038
|
+
}
|
|
1933
2039
|
function helpSections() {
|
|
1934
2040
|
const nav = [];
|
|
1935
2041
|
nav.push(
|
|
@@ -1976,31 +2082,133 @@ function helpSections() {
|
|
|
1976
2082
|
{ keys: "/settings", desc: "autonomy defaults (also Ctrl+S)" },
|
|
1977
2083
|
{ keys: "/clear", desc: "clear the conversation" }
|
|
1978
2084
|
]
|
|
2085
|
+
},
|
|
2086
|
+
{
|
|
2087
|
+
title: "Tool Colors",
|
|
2088
|
+
entries: toolColorLegend()
|
|
1979
2089
|
}
|
|
1980
2090
|
];
|
|
1981
2091
|
}
|
|
2092
|
+
function toolColorLegend() {
|
|
2093
|
+
const tools = [
|
|
2094
|
+
// File operations (most common)
|
|
2095
|
+
{ name: "read/write", tool: "read", desc: "file I/O" },
|
|
2096
|
+
{ name: "write", tool: "write", desc: "create file" },
|
|
2097
|
+
{ name: "edit", tool: "edit", desc: "edit file" },
|
|
2098
|
+
{ name: "patch", tool: "patch", desc: "diff/patch" },
|
|
2099
|
+
// Search
|
|
2100
|
+
{ name: "search", tool: "grep", desc: "search" },
|
|
2101
|
+
{ name: "glob", tool: "glob", desc: "glob/pattern" },
|
|
2102
|
+
// Shell & web
|
|
2103
|
+
{ name: "terminal", tool: "bash", desc: "shell" },
|
|
2104
|
+
{ name: "web", tool: "fetch", desc: "web" },
|
|
2105
|
+
// Navigation & tree
|
|
2106
|
+
{ name: "folder", tool: "ls", desc: "navigate" },
|
|
2107
|
+
{ name: "tree", tool: "tree", desc: "tree view" },
|
|
2108
|
+
// VCS
|
|
2109
|
+
{ name: "git", tool: "git", desc: "git" },
|
|
2110
|
+
// Code quality
|
|
2111
|
+
{ name: "lint", tool: "lint", desc: "lint" },
|
|
2112
|
+
{ name: "format", tool: "format", desc: "format" },
|
|
2113
|
+
{ name: "typecheck", tool: "typecheck", desc: "typecheck" },
|
|
2114
|
+
// Testing & packages
|
|
2115
|
+
{ name: "test", tool: "test", desc: "test" },
|
|
2116
|
+
{ name: "package", tool: "install", desc: "packages" },
|
|
2117
|
+
{ name: "audit", tool: "audit", desc: "audit" },
|
|
2118
|
+
// Planning & tracking
|
|
2119
|
+
{ name: "todo", tool: "todo", desc: "todos" },
|
|
2120
|
+
{ name: "plan", tool: "plan", desc: "planning" },
|
|
2121
|
+
{ name: "task", tool: "task", desc: "tasks" },
|
|
2122
|
+
// Docs & scaffolding
|
|
2123
|
+
{ name: "document", tool: "document", desc: "docs" },
|
|
2124
|
+
{ name: "scaffold", tool: "scaffold", desc: "scaffold" },
|
|
2125
|
+
// Data & logs
|
|
2126
|
+
{ name: "json", tool: "json", desc: "JSON" },
|
|
2127
|
+
{ name: "logs", tool: "logs", desc: "logs" },
|
|
2128
|
+
// Memory & meta
|
|
2129
|
+
{ name: "brain", tool: "remember", desc: "memory" },
|
|
2130
|
+
{ name: "tool_use", tool: "tool_use", desc: "tool chain" }
|
|
2131
|
+
];
|
|
2132
|
+
return tools.map(({ name, tool, desc }) => {
|
|
2133
|
+
const { glyph, color } = getToolVisual(tool);
|
|
2134
|
+
return {
|
|
2135
|
+
keys: `${glyph} ${name}`,
|
|
2136
|
+
desc: `${desc} (${color})`
|
|
2137
|
+
};
|
|
2138
|
+
});
|
|
2139
|
+
}
|
|
2140
|
+
function splitIntoColumns(entries) {
|
|
2141
|
+
const left = [];
|
|
2142
|
+
const right = [];
|
|
2143
|
+
for (const entry of entries) {
|
|
2144
|
+
if (left.length <= right.length) {
|
|
2145
|
+
left.push(entry);
|
|
2146
|
+
} else {
|
|
2147
|
+
right.push(entry);
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
return [left, right];
|
|
2151
|
+
}
|
|
1982
2152
|
function HelpOverlay() {
|
|
1983
2153
|
const sections = helpSections();
|
|
1984
|
-
const
|
|
2154
|
+
const otherSections = sections.filter((s2) => s2.title !== "Tool Colors");
|
|
2155
|
+
const otherKeyWidth = Math.max(
|
|
2156
|
+
...otherSections.flatMap((s2) => s2.entries.map((e) => e.keys.length)),
|
|
2157
|
+
0
|
|
2158
|
+
);
|
|
2159
|
+
const toolSection = sections.find((s2) => s2.title === "Tool Colors");
|
|
2160
|
+
const toolKeyWidth = toolSection ? Math.max(...toolSection.entries.map((e) => e.keys.length), 0) : 0;
|
|
1985
2161
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
1986
2162
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
1987
2163
|
/* @__PURE__ */ jsx(Text, { bold: true, color: theme.accent, children: "Keyboard shortcuts" }),
|
|
1988
2164
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 Esc to close" })
|
|
1989
2165
|
] }),
|
|
1990
|
-
sections.map((sec) =>
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
Box,
|
|
1994
|
-
|
|
1995
|
-
flexDirection: "row",
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2166
|
+
sections.map((sec) => {
|
|
2167
|
+
if (sec.title === "Tool Colors") {
|
|
2168
|
+
const [leftCol, rightCol] = splitIntoColumns(sec.entries);
|
|
2169
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
2170
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: theme.brand, children: sec.title }),
|
|
2171
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
2172
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: leftCol.map((e, i) => /* @__PURE__ */ jsxs(
|
|
2173
|
+
Box,
|
|
2174
|
+
{
|
|
2175
|
+
flexDirection: "row",
|
|
2176
|
+
children: [
|
|
2177
|
+
/* @__PURE__ */ jsx(Text, { color: theme.accent, children: e.keys.padEnd(toolKeyWidth + 2) }),
|
|
2178
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: e.desc })
|
|
2179
|
+
]
|
|
2180
|
+
},
|
|
2181
|
+
i
|
|
2182
|
+
)) }),
|
|
2183
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: rightCol.map((e, i) => /* @__PURE__ */ jsxs(
|
|
2184
|
+
Box,
|
|
2185
|
+
{
|
|
2186
|
+
flexDirection: "row",
|
|
2187
|
+
children: [
|
|
2188
|
+
/* @__PURE__ */ jsx(Text, { color: theme.accent, children: e.keys.padEnd(toolKeyWidth + 2) }),
|
|
2189
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: e.desc })
|
|
2190
|
+
]
|
|
2191
|
+
},
|
|
2192
|
+
i
|
|
2193
|
+
)) })
|
|
2194
|
+
] })
|
|
2195
|
+
] }, sec.title);
|
|
2196
|
+
}
|
|
2197
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
2198
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: theme.brand, children: sec.title }),
|
|
2199
|
+
sec.entries.map((e, i) => /* @__PURE__ */ jsxs(
|
|
2200
|
+
Box,
|
|
2201
|
+
{
|
|
2202
|
+
flexDirection: "row",
|
|
2203
|
+
children: [
|
|
2204
|
+
/* @__PURE__ */ jsx(Text, { color: theme.accent, children: e.keys.padEnd(otherKeyWidth + 2) }),
|
|
2205
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: e.desc })
|
|
2206
|
+
]
|
|
2207
|
+
},
|
|
2208
|
+
i
|
|
2209
|
+
))
|
|
2210
|
+
] }, sec.title);
|
|
2211
|
+
})
|
|
2004
2212
|
] });
|
|
2005
2213
|
}
|
|
2006
2214
|
|
|
@@ -3525,6 +3733,7 @@ var ToolStreamBox = React5.memo(function ToolStreamBox2({
|
|
|
3525
3733
|
startedAt,
|
|
3526
3734
|
termWidth
|
|
3527
3735
|
}) {
|
|
3736
|
+
const { glyph, color } = getToolVisual(name);
|
|
3528
3737
|
const [tick, setTick] = useState(0);
|
|
3529
3738
|
useEffect(() => {
|
|
3530
3739
|
const t = setInterval(() => setTick((n) => n + 1), 500);
|
|
@@ -3537,8 +3746,11 @@ var ToolStreamBox = React5.memo(function ToolStreamBox2({
|
|
|
3537
3746
|
const rows = streamBoxRows(text, MAX_STREAM_LINES, contentWidth);
|
|
3538
3747
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 0, children: [
|
|
3539
3748
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
|
|
3540
|
-
/* @__PURE__ */
|
|
3541
|
-
|
|
3749
|
+
/* @__PURE__ */ jsxs(Text, { color, children: [
|
|
3750
|
+
glyph,
|
|
3751
|
+
" "
|
|
3752
|
+
] }),
|
|
3753
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color, children: name }),
|
|
3542
3754
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u23F1 ${fmtDuration(elapsedMs)}` }),
|
|
3543
3755
|
hidden > 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` (${totalLines} lines, showing last ${MAX_STREAM_LINES})` }) : null
|
|
3544
3756
|
] }),
|
|
@@ -3811,7 +4023,7 @@ function Banner({
|
|
|
3811
4023
|
entry
|
|
3812
4024
|
}) {
|
|
3813
4025
|
const cwdShort = shortenPath(entry.cwd, 48);
|
|
3814
|
-
const projectLabel =
|
|
4026
|
+
const projectLabel = path5.basename(entry.cwd);
|
|
3815
4027
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 2, paddingY: 0, children: [
|
|
3816
4028
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
3817
4029
|
/* @__PURE__ */ jsx(Text, { color: "magenta", bold: true, children: " \u259F\u259B " }),
|
|
@@ -4093,6 +4305,7 @@ var Entry = React5.memo(function Entry2({
|
|
|
4093
4305
|
] });
|
|
4094
4306
|
}
|
|
4095
4307
|
case "tool": {
|
|
4308
|
+
const { glyph, color } = getToolVisual(entry.name);
|
|
4096
4309
|
const argSummary = formatToolArgs(entry.name, entry.input);
|
|
4097
4310
|
const outLines = formatToolOutput(
|
|
4098
4311
|
entry.name,
|
|
@@ -4118,9 +4331,9 @@ var Entry = React5.memo(function Entry2({
|
|
|
4118
4331
|
})();
|
|
4119
4332
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
4120
4333
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
4121
|
-
/* @__PURE__ */ jsx(Text, { color
|
|
4122
|
-
" ",
|
|
4123
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color
|
|
4334
|
+
/* @__PURE__ */ jsx(Text, { color, children: glyph }),
|
|
4335
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
4336
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color, children: entry.name }),
|
|
4124
4337
|
argSummary ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4125
4338
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
4126
4339
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: argSummary })
|
|
@@ -4387,7 +4600,7 @@ function ScrollableHistory({
|
|
|
4387
4600
|
}
|
|
4388
4601
|
var MB = 1024 * 1024;
|
|
4389
4602
|
function defaultHeapLogPath() {
|
|
4390
|
-
return
|
|
4603
|
+
return path5.join(wstackGlobalRoot(), "logs", "heap.jsonl");
|
|
4391
4604
|
}
|
|
4392
4605
|
function takeHeapSample() {
|
|
4393
4606
|
const m = process.memoryUsage();
|
|
@@ -4417,10 +4630,10 @@ function startHeapWatchdog(opts = {}) {
|
|
|
4417
4630
|
const append = (line) => {
|
|
4418
4631
|
writeChain = writeChain.then(async () => {
|
|
4419
4632
|
if (!dirReady) {
|
|
4420
|
-
await
|
|
4633
|
+
await fs3.mkdir(path5.dirname(logPath), { recursive: true });
|
|
4421
4634
|
dirReady = true;
|
|
4422
4635
|
}
|
|
4423
|
-
await
|
|
4636
|
+
await fs3.appendFile(logPath, `${line}
|
|
4424
4637
|
`, "utf8");
|
|
4425
4638
|
}).catch(() => void 0);
|
|
4426
4639
|
};
|
|
@@ -4593,6 +4806,52 @@ function layoutInputRows(prompt, value, cursor, width) {
|
|
|
4593
4806
|
if (row.length > 0 || rows.length === 0) rows.push(row);
|
|
4594
4807
|
return rows;
|
|
4595
4808
|
}
|
|
4809
|
+
function inputIndexAtRowCol(prompt, value, width, row, col) {
|
|
4810
|
+
const w = Math.max(1, Math.floor(width));
|
|
4811
|
+
const flat = [];
|
|
4812
|
+
for (let i = 0; i < prompt.length; i++) flat.push({ ch: prompt[i], buf: -1 });
|
|
4813
|
+
for (let i = 0; i < value.length; i++) flat.push({ ch: value[i], buf: i });
|
|
4814
|
+
const rows = [];
|
|
4815
|
+
const starts = [];
|
|
4816
|
+
let cur = [];
|
|
4817
|
+
let curStart = 0;
|
|
4818
|
+
for (const cell of flat) {
|
|
4819
|
+
if (cell.ch === "\n") {
|
|
4820
|
+
rows.push(cur);
|
|
4821
|
+
starts.push(curStart);
|
|
4822
|
+
cur = [];
|
|
4823
|
+
curStart = cell.buf + 1;
|
|
4824
|
+
continue;
|
|
4825
|
+
}
|
|
4826
|
+
if (cur.length === 0 && cell.buf >= 0) curStart = cell.buf;
|
|
4827
|
+
cur.push({ buf: cell.buf });
|
|
4828
|
+
if (cur.length >= w) {
|
|
4829
|
+
rows.push(cur);
|
|
4830
|
+
starts.push(curStart);
|
|
4831
|
+
cur = [];
|
|
4832
|
+
curStart = -1;
|
|
4833
|
+
}
|
|
4834
|
+
}
|
|
4835
|
+
if (cur.length > 0 || rows.length === 0) {
|
|
4836
|
+
rows.push(cur);
|
|
4837
|
+
starts.push(curStart);
|
|
4838
|
+
}
|
|
4839
|
+
const clamp = (n) => Math.max(0, Math.min(value.length, n));
|
|
4840
|
+
if (row < 0) return 0;
|
|
4841
|
+
if (row >= rows.length) return value.length;
|
|
4842
|
+
const r = rows[row];
|
|
4843
|
+
const c = Math.max(0, col);
|
|
4844
|
+
if (c < r.length) {
|
|
4845
|
+
const b = r[c].buf;
|
|
4846
|
+
return b < 0 ? 0 : clamp(b);
|
|
4847
|
+
}
|
|
4848
|
+
for (let k = r.length - 1; k >= 0; k--) {
|
|
4849
|
+
const b = r[k].buf;
|
|
4850
|
+
if (b >= 0) return clamp(b + 1);
|
|
4851
|
+
}
|
|
4852
|
+
const start = starts[row];
|
|
4853
|
+
return clamp(start !== void 0 && start >= 0 ? start : value.length);
|
|
4854
|
+
}
|
|
4596
4855
|
|
|
4597
4856
|
// src/mouse.ts
|
|
4598
4857
|
var ESC = String.fromCharCode(27);
|
|
@@ -5224,21 +5483,33 @@ function ProcessListMonitor() {
|
|
|
5224
5483
|
const all = registry.list();
|
|
5225
5484
|
const stats = registry.stats();
|
|
5226
5485
|
const safeIndex = Math.min(selectedIndex, Math.max(0, all.length - 1));
|
|
5486
|
+
if (safeIndex !== selectedIndex) {
|
|
5487
|
+
setSelectedIndex(safeIndex);
|
|
5488
|
+
}
|
|
5227
5489
|
const selected = all[safeIndex];
|
|
5228
5490
|
const now = Date.now();
|
|
5229
5491
|
const running = all.filter((p) => !p.killed).length;
|
|
5230
5492
|
const b = stats.breaker;
|
|
5231
5493
|
const breakerState = b.state === "closed" ? "\u{1F7E2} closed" : b.state === "half-open" ? "\u{1F7E1} half-open" : "\u{1F534} open";
|
|
5494
|
+
const pageSize = Math.max(1, Math.floor(all.length / 2));
|
|
5232
5495
|
useInput((input, key) => {
|
|
5233
5496
|
if (key.upArrow) {
|
|
5234
5497
|
setSelectedIndex((prev) => Math.max(0, prev - 1));
|
|
5235
5498
|
} else if (key.downArrow) {
|
|
5236
5499
|
setSelectedIndex((prev) => Math.min(all.length - 1, prev + 1));
|
|
5500
|
+
} else if (key.pageUp) {
|
|
5501
|
+
setSelectedIndex((prev) => Math.max(0, prev - pageSize));
|
|
5502
|
+
} else if (key.pageDown) {
|
|
5503
|
+
setSelectedIndex((prev) => Math.min(all.length - 1, prev + pageSize));
|
|
5504
|
+
} else if (key.home || key.ctrl && input === "a" || input === "g") {
|
|
5505
|
+
setSelectedIndex(0);
|
|
5506
|
+
} else if (key.end || key.ctrl && input === "e" || input === "G") {
|
|
5507
|
+
setSelectedIndex(Math.max(0, all.length - 1));
|
|
5237
5508
|
} else if (key.return && selected) {
|
|
5238
5509
|
getProcessRegistry().kill(selected.pid);
|
|
5239
5510
|
} else if (key.delete && selected) {
|
|
5240
5511
|
getProcessRegistry().kill(selected.pid, { force: true });
|
|
5241
|
-
} else if (input === "a") {
|
|
5512
|
+
} else if (input === "a" && !key.ctrl) {
|
|
5242
5513
|
getProcessRegistry().killAll();
|
|
5243
5514
|
} else if (input === "A") {
|
|
5244
5515
|
getProcessRegistry().killAll({ force: true });
|
|
@@ -5284,6 +5555,13 @@ function ProcessListMonitor() {
|
|
|
5284
5555
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, marginTop: 1, children: [
|
|
5285
5556
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191\u2193 nav" }),
|
|
5286
5557
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
5558
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "PgUp/PgDn page" }),
|
|
5559
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
5560
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Home/Ctrl+A/g first" }),
|
|
5561
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
5562
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "End/Ctrl+E/G last" })
|
|
5563
|
+
] }),
|
|
5564
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
5287
5565
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Enter kill (SIGTERM)" }),
|
|
5288
5566
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
5289
5567
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Del force kill (SIGKILL)" }),
|
|
@@ -5294,7 +5572,25 @@ function ProcessListMonitor() {
|
|
|
5294
5572
|
] })
|
|
5295
5573
|
] });
|
|
5296
5574
|
}
|
|
5297
|
-
function GoalPanel({
|
|
5575
|
+
function GoalPanel({
|
|
5576
|
+
goal,
|
|
5577
|
+
onCoordinatorStart,
|
|
5578
|
+
onCoordinatorStop,
|
|
5579
|
+
coordinatorRunning
|
|
5580
|
+
}) {
|
|
5581
|
+
useInput((input) => {
|
|
5582
|
+
if (input === "c" || input === "C") {
|
|
5583
|
+
if (onCoordinatorStart && goal) {
|
|
5584
|
+
const goalText = goal.refinedGoal || goal.goal;
|
|
5585
|
+
onCoordinatorStart(goalText);
|
|
5586
|
+
}
|
|
5587
|
+
}
|
|
5588
|
+
if (input === "S") {
|
|
5589
|
+
if (onCoordinatorStop) {
|
|
5590
|
+
onCoordinatorStop();
|
|
5591
|
+
}
|
|
5592
|
+
}
|
|
5593
|
+
});
|
|
5298
5594
|
if (!goal) {
|
|
5299
5595
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", padding: 1, children: [
|
|
5300
5596
|
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: theme.accent, children: "\u{1F3AF} Goal" }) }),
|
|
@@ -5306,7 +5602,11 @@ function GoalPanel({ goal }) {
|
|
|
5306
5602
|
] }),
|
|
5307
5603
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " to create one." })
|
|
5308
5604
|
] }),
|
|
5309
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press F9 to close." }) })
|
|
5605
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press F9 to close." }) }),
|
|
5606
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: coordinatorRunning ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5607
|
+
/* @__PURE__ */ jsx(Text, { color: "green", children: "\u25CF Coordinator running " }),
|
|
5608
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "[S] Stop coordinator" })
|
|
5609
|
+
] }) : /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "[C] Start coordinator" }) }) })
|
|
5310
5610
|
] });
|
|
5311
5611
|
}
|
|
5312
5612
|
const displayGoal = goal.refinedGoal || goal.goal;
|
|
@@ -5372,7 +5672,11 @@ function GoalPanel({ goal }) {
|
|
|
5372
5672
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Last task: " }),
|
|
5373
5673
|
/* @__PURE__ */ jsx(Text, { children: goal.lastTask.length > 50 ? goal.lastTask.slice(0, 47) + "\u2026" : goal.lastTask })
|
|
5374
5674
|
] }),
|
|
5375
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press F9 to close." }) })
|
|
5675
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press F9 to close." }) }),
|
|
5676
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: coordinatorRunning ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5677
|
+
/* @__PURE__ */ jsx(Text, { color: "green", children: "\u25CF Coordinator running " }),
|
|
5678
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "[S] Stop coordinator" })
|
|
5679
|
+
] }) : /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "[C] Start coordinator" }) }) })
|
|
5376
5680
|
] })
|
|
5377
5681
|
] });
|
|
5378
5682
|
}
|
|
@@ -5397,6 +5701,152 @@ function renderProgressBar(progress, trend) {
|
|
|
5397
5701
|
] })
|
|
5398
5702
|
] });
|
|
5399
5703
|
}
|
|
5704
|
+
var STATUS_COLOR = {
|
|
5705
|
+
open: "gray",
|
|
5706
|
+
in_progress: "yellow",
|
|
5707
|
+
done: "green"
|
|
5708
|
+
};
|
|
5709
|
+
var STATUS_ICON = {
|
|
5710
|
+
open: "\u25CB",
|
|
5711
|
+
in_progress: "\u25D0",
|
|
5712
|
+
done: "\u2713"
|
|
5713
|
+
};
|
|
5714
|
+
function planFilePath(projectRoot, sessionId, scope) {
|
|
5715
|
+
const base = resolveWstackPaths$1({ projectRoot }).projectSessions;
|
|
5716
|
+
if (scope === "project") {
|
|
5717
|
+
return path5.join(base, "backlog.plan.json");
|
|
5718
|
+
}
|
|
5719
|
+
if (sessionId) {
|
|
5720
|
+
return path5.join(base, `${sessionId}.plan.json`);
|
|
5721
|
+
}
|
|
5722
|
+
return path5.join(base, "backlog.plan.json");
|
|
5723
|
+
}
|
|
5724
|
+
function PlanPanel({ projectRoot, sessionId, onClose: _onClose }) {
|
|
5725
|
+
const [items, setItems] = useState([]);
|
|
5726
|
+
const [title, setTitle2] = useState(void 0);
|
|
5727
|
+
const [scope, setScope] = useState("session");
|
|
5728
|
+
const [loading, setLoading] = useState(true);
|
|
5729
|
+
const [error, setError] = useState(null);
|
|
5730
|
+
async function load(scope_) {
|
|
5731
|
+
setLoading(true);
|
|
5732
|
+
setError(null);
|
|
5733
|
+
try {
|
|
5734
|
+
const filePath = planFilePath(projectRoot, sessionId, scope_);
|
|
5735
|
+
let content;
|
|
5736
|
+
try {
|
|
5737
|
+
content = await fs3.readFile(filePath, "utf-8");
|
|
5738
|
+
} catch {
|
|
5739
|
+
setItems([]);
|
|
5740
|
+
setTitle2(void 0);
|
|
5741
|
+
setScope(scope_);
|
|
5742
|
+
setLoading(false);
|
|
5743
|
+
return;
|
|
5744
|
+
}
|
|
5745
|
+
const parsed = JSON.parse(content);
|
|
5746
|
+
setItems(parsed.items ?? []);
|
|
5747
|
+
setTitle2(parsed.title);
|
|
5748
|
+
setScope(scope_);
|
|
5749
|
+
} catch (err) {
|
|
5750
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
5751
|
+
} finally {
|
|
5752
|
+
setLoading(false);
|
|
5753
|
+
}
|
|
5754
|
+
}
|
|
5755
|
+
useEffect(() => {
|
|
5756
|
+
void load("session");
|
|
5757
|
+
}, []);
|
|
5758
|
+
async function handleScopeSwitch(newScope) {
|
|
5759
|
+
await load(newScope);
|
|
5760
|
+
}
|
|
5761
|
+
useInput((input) => {
|
|
5762
|
+
if (input === "s" || input === "S") {
|
|
5763
|
+
void handleScopeSwitch(scope === "session" ? "project" : "session");
|
|
5764
|
+
}
|
|
5765
|
+
});
|
|
5766
|
+
const open = items.filter((i) => i.status === "open");
|
|
5767
|
+
const inProgress = items.filter((i) => i.status === "in_progress");
|
|
5768
|
+
const done = items.filter((i) => i.status === "done");
|
|
5769
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
|
|
5770
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, marginBottom: 1, children: [
|
|
5771
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u{1F4CB} PLAN" }),
|
|
5772
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
5773
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: scope === "session" ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "session-scoped" }) : /* @__PURE__ */ jsx(Text, { color: "yellow", children: "project-scoped" }) }),
|
|
5774
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
5775
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5776
|
+
items.length,
|
|
5777
|
+
" item",
|
|
5778
|
+
items.length !== 1 ? "s" : ""
|
|
5779
|
+
] }),
|
|
5780
|
+
title ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5781
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
5782
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: title })
|
|
5783
|
+
] }) : null,
|
|
5784
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 F5/Esc to close" })
|
|
5785
|
+
] }),
|
|
5786
|
+
loading ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Loading plan..." }) : error ? /* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
5787
|
+
"Error: ",
|
|
5788
|
+
error
|
|
5789
|
+
] }) : items.length === 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 0, children: [
|
|
5790
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "No plan items yet." }),
|
|
5791
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5792
|
+
"Use ",
|
|
5793
|
+
/* @__PURE__ */ jsx(Text, { color: theme.accent, children: "/plan add <title>" }),
|
|
5794
|
+
" to create one."
|
|
5795
|
+
] })
|
|
5796
|
+
] }) : /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 0, children: [
|
|
5797
|
+
inProgress.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
5798
|
+
/* @__PURE__ */ jsxs(Text, { color: "yellow", bold: true, children: [
|
|
5799
|
+
"In Progress (",
|
|
5800
|
+
inProgress.length,
|
|
5801
|
+
")"
|
|
5802
|
+
] }),
|
|
5803
|
+
inProgress.map((item) => /* @__PURE__ */ jsx(PlanRow, { item }, item.id))
|
|
5804
|
+
] }),
|
|
5805
|
+
open.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
5806
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, bold: true, children: [
|
|
5807
|
+
"Open (",
|
|
5808
|
+
open.length,
|
|
5809
|
+
")"
|
|
5810
|
+
] }),
|
|
5811
|
+
open.map((item) => /* @__PURE__ */ jsx(PlanRow, { item }, item.id))
|
|
5812
|
+
] }),
|
|
5813
|
+
done.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
5814
|
+
/* @__PURE__ */ jsxs(Text, { color: "green", bold: true, children: [
|
|
5815
|
+
"Done (",
|
|
5816
|
+
done.length,
|
|
5817
|
+
")"
|
|
5818
|
+
] }),
|
|
5819
|
+
done.map((item) => /* @__PURE__ */ jsx(PlanRow, { item }, item.id))
|
|
5820
|
+
] })
|
|
5821
|
+
] }),
|
|
5822
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5823
|
+
"[",
|
|
5824
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: "S" }),
|
|
5825
|
+
"] Switch scope to",
|
|
5826
|
+
" ",
|
|
5827
|
+
scope === "session" ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: "project" }) : /* @__PURE__ */ jsx(Text, { color: "cyan", children: "session" }),
|
|
5828
|
+
" ",
|
|
5829
|
+
"\xB7 Use ",
|
|
5830
|
+
/* @__PURE__ */ jsx(Text, { color: theme.accent, children: "/plan add" }),
|
|
5831
|
+
" to add items \xB7",
|
|
5832
|
+
" ",
|
|
5833
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "F5/Esc to close" })
|
|
5834
|
+
] }) })
|
|
5835
|
+
] });
|
|
5836
|
+
}
|
|
5837
|
+
function PlanRow({ item }) {
|
|
5838
|
+
const icon = STATUS_ICON[item.status] ?? "?";
|
|
5839
|
+
const color = STATUS_COLOR[item.status] ?? "white";
|
|
5840
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
5841
|
+
/* @__PURE__ */ jsx(Text, { color, children: icon }),
|
|
5842
|
+
/* @__PURE__ */ jsx(Text, { color, children: item.title }),
|
|
5843
|
+
item.details ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5844
|
+
" \u2014 ",
|
|
5845
|
+
item.details.slice(0, 60),
|
|
5846
|
+
item.details.length > 60 ? "\u2026" : ""
|
|
5847
|
+
] }) : null
|
|
5848
|
+
] });
|
|
5849
|
+
}
|
|
5400
5850
|
var KIND_COLOR = {
|
|
5401
5851
|
goal: "cyan",
|
|
5402
5852
|
task: "yellow",
|
|
@@ -5705,10 +6155,26 @@ var SETTINGS_MODES = ["off", "suggest", "auto"];
|
|
|
5705
6155
|
var LOG_LEVELS = ["error", "warn", "info", "debug", "trace"];
|
|
5706
6156
|
var AUDIT_LEVELS = ["minimal", "standard", "full"];
|
|
5707
6157
|
var COMPACTOR_STRATEGIES = ["hybrid", "intelligent", "selective"];
|
|
6158
|
+
var CONTEXT_MODES = ["balanced", "frugal", "deep", "archival"];
|
|
6159
|
+
var CONTEXT_MODE_DESCS = {
|
|
6160
|
+
balanced: "Normal context usage (default)",
|
|
6161
|
+
frugal: "Conservative token use",
|
|
6162
|
+
deep: "Larger context for complex tasks",
|
|
6163
|
+
archival: "Maximize context retention"
|
|
6164
|
+
};
|
|
5708
6165
|
var MAX_ITERATIONS_PRESETS = [100, 200, 500, 1e3, 0];
|
|
6166
|
+
var MAX_CONCURRENT_PRESETS = [1, 3, 5, 10, 25, 50, 0];
|
|
5709
6167
|
var AUTO_PROCEED_MAX_PRESETS = [10, 25, 50, 100, 250, 0];
|
|
5710
6168
|
var ENHANCE_DELAY_PRESETS = [3e4, 45e3, 6e4, 9e4, 12e4];
|
|
5711
6169
|
var ENHANCE_LANGUAGES = ["original", "english"];
|
|
6170
|
+
var TOKEN_SAVING_TIERS = ["off", "minimal", "light", "medium", "aggressive"];
|
|
6171
|
+
var TOKEN_SAVING_TIER_DESCS = {
|
|
6172
|
+
off: "All tools enabled (full prompt)",
|
|
6173
|
+
minimal: "~3\u20134k tokens \u2014 core tools only",
|
|
6174
|
+
light: "~2\u20133k tokens \u2014 core + patterns",
|
|
6175
|
+
medium: "~1.5\u20132k tokens \u2014 most tools enabled",
|
|
6176
|
+
aggressive: "~4\u20135k tokens \u2014 trimmed prompt"
|
|
6177
|
+
};
|
|
5712
6178
|
function formatSettingsDelay(ms) {
|
|
5713
6179
|
if (ms === 0) return "disabled";
|
|
5714
6180
|
if (ms >= 6e4) return `${Math.round(ms / 6e4)}m`;
|
|
@@ -5726,7 +6192,7 @@ var MODE_DESC = {
|
|
|
5726
6192
|
suggest: "Shows next-step suggestions after each turn",
|
|
5727
6193
|
auto: "Self-driving \u2014 agent continues automatically"
|
|
5728
6194
|
};
|
|
5729
|
-
var SETTINGS_FIELD_COUNT =
|
|
6195
|
+
var SETTINGS_FIELD_COUNT = 29;
|
|
5730
6196
|
var CONFIG_SCOPES = ["global", "project"];
|
|
5731
6197
|
function SettingsPicker({
|
|
5732
6198
|
field,
|
|
@@ -5743,10 +6209,12 @@ function SettingsPicker({
|
|
|
5743
6209
|
featureMemory,
|
|
5744
6210
|
featureSkills,
|
|
5745
6211
|
featureModelsRegistry,
|
|
5746
|
-
|
|
6212
|
+
tokenSavingTier,
|
|
5747
6213
|
allowOutsideProjectRoot,
|
|
5748
6214
|
contextAutoCompact,
|
|
5749
6215
|
contextStrategy,
|
|
6216
|
+
contextMode,
|
|
6217
|
+
maxConcurrent,
|
|
5750
6218
|
logLevel,
|
|
5751
6219
|
auditLevel,
|
|
5752
6220
|
indexOnStart,
|
|
@@ -5830,8 +6298,8 @@ function SettingsPicker({
|
|
|
5830
6298
|
},
|
|
5831
6299
|
{
|
|
5832
6300
|
label: "Token-saving mode",
|
|
5833
|
-
value:
|
|
5834
|
-
detail:
|
|
6301
|
+
value: tokenSavingTier,
|
|
6302
|
+
detail: TOKEN_SAVING_TIER_DESCS[tokenSavingTier]
|
|
5835
6303
|
},
|
|
5836
6304
|
{
|
|
5837
6305
|
label: "Allow outside project",
|
|
@@ -5850,6 +6318,18 @@ function SettingsPicker({
|
|
|
5850
6318
|
value: contextStrategy,
|
|
5851
6319
|
detail: "hybrid (fast) | intelligent (LLM) | selective"
|
|
5852
6320
|
},
|
|
6321
|
+
{
|
|
6322
|
+
label: "Context mode",
|
|
6323
|
+
value: contextMode,
|
|
6324
|
+
detail: CONTEXT_MODE_DESCS[contextMode]
|
|
6325
|
+
},
|
|
6326
|
+
// ── Fleet ──
|
|
6327
|
+
{ section: "Fleet" },
|
|
6328
|
+
{
|
|
6329
|
+
label: "Max concurrent",
|
|
6330
|
+
value: maxConcurrent === 0 ? "unlimited" : String(maxConcurrent),
|
|
6331
|
+
detail: "Max subagents (0 = unlimited)"
|
|
6332
|
+
},
|
|
5853
6333
|
// ── Logging ──
|
|
5854
6334
|
{ section: "Logging" },
|
|
5855
6335
|
{
|
|
@@ -5971,6 +6451,145 @@ function SettingsPicker({
|
|
|
5971
6451
|
hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
|
|
5972
6452
|
] });
|
|
5973
6453
|
}
|
|
6454
|
+
function isChipExpired(meta, now = Date.now()) {
|
|
6455
|
+
if (meta.expiresIn == null || meta.expiresIn === 0) return false;
|
|
6456
|
+
if (meta.shownAt == null || meta.shownAt === 0) return false;
|
|
6457
|
+
return now >= meta.shownAt + meta.expiresIn * 60 * 1e3;
|
|
6458
|
+
}
|
|
6459
|
+
var ITEM_DESCRIPTIONS = {
|
|
6460
|
+
todos: "Todo items (pending/in-progress/done)",
|
|
6461
|
+
plan: "Plan board items",
|
|
6462
|
+
tasks: "Task board items",
|
|
6463
|
+
fleet: "Fleet agent status",
|
|
6464
|
+
git: "Git branch name",
|
|
6465
|
+
elapsed: "Session elapsed time",
|
|
6466
|
+
context: "Context window usage %",
|
|
6467
|
+
cost: "Token cost estimate",
|
|
6468
|
+
working_dir: "Current working directory",
|
|
6469
|
+
brain: "Brain arbiter decisions",
|
|
6470
|
+
mailbox: "Mailbox unread messages",
|
|
6471
|
+
enhance: "Prompt-enhance countdown",
|
|
6472
|
+
debug_stream: "Stream debug telemetry"
|
|
6473
|
+
};
|
|
6474
|
+
var ITEM_LINE = {
|
|
6475
|
+
context: 1,
|
|
6476
|
+
cost: 1,
|
|
6477
|
+
elapsed: 2,
|
|
6478
|
+
working_dir: 2,
|
|
6479
|
+
git: 2,
|
|
6480
|
+
todos: 3,
|
|
6481
|
+
plan: 3,
|
|
6482
|
+
tasks: 3,
|
|
6483
|
+
fleet: 4,
|
|
6484
|
+
brain: 3,
|
|
6485
|
+
mailbox: 3,
|
|
6486
|
+
enhance: 3,
|
|
6487
|
+
debug_stream: 3
|
|
6488
|
+
};
|
|
6489
|
+
Object.keys(ITEM_LINE).length;
|
|
6490
|
+
var STATUSLINE_ITEMS = [
|
|
6491
|
+
// Line 1
|
|
6492
|
+
"context",
|
|
6493
|
+
"cost",
|
|
6494
|
+
// Line 2
|
|
6495
|
+
"elapsed",
|
|
6496
|
+
"git",
|
|
6497
|
+
"working_dir",
|
|
6498
|
+
// Line 3
|
|
6499
|
+
"brain",
|
|
6500
|
+
"debug_stream",
|
|
6501
|
+
"enhance",
|
|
6502
|
+
"mailbox",
|
|
6503
|
+
"plan",
|
|
6504
|
+
"tasks",
|
|
6505
|
+
"todos",
|
|
6506
|
+
// Line 4
|
|
6507
|
+
"fleet"
|
|
6508
|
+
];
|
|
6509
|
+
var STREAM_CHIP_KEYS = ["brain", "mailbox", "enhance", "debug_stream"];
|
|
6510
|
+
function groupByLine(items) {
|
|
6511
|
+
const map = /* @__PURE__ */ new Map();
|
|
6512
|
+
for (const item of items) {
|
|
6513
|
+
const line = ITEM_LINE[item];
|
|
6514
|
+
if (!map.has(line)) map.set(line, []);
|
|
6515
|
+
map.get(line).push(item);
|
|
6516
|
+
}
|
|
6517
|
+
return map;
|
|
6518
|
+
}
|
|
6519
|
+
function StatuslinePicker({
|
|
6520
|
+
field,
|
|
6521
|
+
hiddenItems,
|
|
6522
|
+
visibleChips = [],
|
|
6523
|
+
hint
|
|
6524
|
+
}) {
|
|
6525
|
+
const hiddenSet = new Set(hiddenItems);
|
|
6526
|
+
const visibleChipsMap = new Map(visibleChips.map((c) => [c.key, c]));
|
|
6527
|
+
const totalFields = STATUSLINE_ITEMS.length;
|
|
6528
|
+
const byLine = groupByLine(STATUSLINE_ITEMS);
|
|
6529
|
+
const rows = [];
|
|
6530
|
+
for (const [line, items] of [...byLine.entries()].sort((a, b) => a[0] - b[0])) {
|
|
6531
|
+
rows.push({ section: `Line ${line}` });
|
|
6532
|
+
for (const item of items) {
|
|
6533
|
+
const fieldIdx = STATUSLINE_ITEMS.indexOf(item);
|
|
6534
|
+
rows.push({ item, fieldIdx });
|
|
6535
|
+
}
|
|
6536
|
+
}
|
|
6537
|
+
const VISIBLE_FIELDS = 7;
|
|
6538
|
+
const windowStart = Math.max(0, Math.min(field - Math.floor(VISIBLE_FIELDS / 2), totalFields - VISIBLE_FIELDS));
|
|
6539
|
+
const windowEnd = Math.min(windowStart + VISIBLE_FIELDS, totalFields);
|
|
6540
|
+
const hasAbove = windowStart > 0;
|
|
6541
|
+
const hasBelow = windowEnd < totalFields;
|
|
6542
|
+
const boolVal = (item) => {
|
|
6543
|
+
if (hiddenSet.has(item)) return "off";
|
|
6544
|
+
if (STREAM_CHIP_KEYS.includes(item)) {
|
|
6545
|
+
const meta = visibleChipsMap.get(item);
|
|
6546
|
+
if (!meta) return "off";
|
|
6547
|
+
if (meta.expiresIn == null) return "on ";
|
|
6548
|
+
const remainingMs = meta.shownAt + meta.expiresIn * 6e4 - Date.now();
|
|
6549
|
+
if (remainingMs <= 0) return "exp";
|
|
6550
|
+
const remainingMin = Math.max(1, Math.ceil(remainingMs / 6e4));
|
|
6551
|
+
return `~${remainingMin}m`;
|
|
6552
|
+
}
|
|
6553
|
+
return "on ";
|
|
6554
|
+
};
|
|
6555
|
+
const valColor = (item) => {
|
|
6556
|
+
if (hiddenSet.has(item)) return "red";
|
|
6557
|
+
if (STREAM_CHIP_KEYS.includes(item)) {
|
|
6558
|
+
const meta = visibleChipsMap.get(item);
|
|
6559
|
+
if (!meta) return "red";
|
|
6560
|
+
if (isChipExpired(meta)) return "red";
|
|
6561
|
+
return "yellow";
|
|
6562
|
+
}
|
|
6563
|
+
return "green";
|
|
6564
|
+
};
|
|
6565
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
6566
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u2501\u2501 Statusline \u2501\u2501" }),
|
|
6567
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 move \xB7 \u2190/\u2192 toggle \xB7 Esc to close" }),
|
|
6568
|
+
hasAbove ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u2191 ${windowStart} item${windowStart === 1 ? "" : "s"} above` }) : null,
|
|
6569
|
+
rows.map((row) => {
|
|
6570
|
+
if (row.section) {
|
|
6571
|
+
return /* @__PURE__ */ jsxs(Text, { bold: true, color: "green", children: [
|
|
6572
|
+
"\u2500\u2500 ",
|
|
6573
|
+
row.section,
|
|
6574
|
+
" \u2500\u2500"
|
|
6575
|
+
] }, `section-${row.section}`);
|
|
6576
|
+
}
|
|
6577
|
+
const item = row.item;
|
|
6578
|
+
const fieldIdx = row.fieldIdx;
|
|
6579
|
+
const selected = fieldIdx === field;
|
|
6580
|
+
return /* @__PURE__ */ jsxs(Text, { inverse: selected, ...selected ? { color: "yellow" } : {}, children: [
|
|
6581
|
+
selected ? "\u203A " : " ",
|
|
6582
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: item.padEnd(12) }),
|
|
6583
|
+
/* @__PURE__ */ jsx(Text, { color: valColor(item), children: boolVal(item).padEnd(4) }),
|
|
6584
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ITEM_DESCRIPTIONS[item] }),
|
|
6585
|
+
selected ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: " \u2190/\u2192 toggle" }) : null
|
|
6586
|
+
] }, `row-${item}`);
|
|
6587
|
+
}),
|
|
6588
|
+
hasBelow ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u2193 ${totalFields - windowEnd} item${totalFields - windowEnd === 1 ? "" : "s"} below` }) : null,
|
|
6589
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Changes apply instantly \xB7 persisted to ~/.wrongstack/statusline.json \xB7 auto chips expire after ~5m" }),
|
|
6590
|
+
hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
|
|
6591
|
+
] });
|
|
6592
|
+
}
|
|
5974
6593
|
var MAX_VISIBLE_ITEMS = 8;
|
|
5975
6594
|
function SlashMenu({ query, matches, selected }) {
|
|
5976
6595
|
const placeholder = query ? `/${query}` : "/";
|
|
@@ -6448,10 +7067,10 @@ async function loadIndex(root) {
|
|
|
6448
7067
|
async function walk(root, rel, depth, out) {
|
|
6449
7068
|
if (out.length >= MAX_FILES_INDEXED) return;
|
|
6450
7069
|
if (depth > MAX_DEPTH) return;
|
|
6451
|
-
const dir = rel ?
|
|
7070
|
+
const dir = rel ? path5.join(root, rel) : root;
|
|
6452
7071
|
let entries;
|
|
6453
7072
|
try {
|
|
6454
|
-
entries = await
|
|
7073
|
+
entries = await fs3.readdir(dir, { withFileTypes: true });
|
|
6455
7074
|
} catch {
|
|
6456
7075
|
return;
|
|
6457
7076
|
}
|
|
@@ -6990,7 +7609,8 @@ function useTuiControllers({
|
|
|
6990
7609
|
agentsMonitorOpen,
|
|
6991
7610
|
fleetStreamController,
|
|
6992
7611
|
enhanceController,
|
|
6993
|
-
agentsMonitorController
|
|
7612
|
+
agentsMonitorController,
|
|
7613
|
+
onPanelOpen
|
|
6994
7614
|
}) {
|
|
6995
7615
|
useEffect(() => {
|
|
6996
7616
|
if (!fleetStreamController) return;
|
|
@@ -7036,6 +7656,16 @@ function useTuiControllers({
|
|
|
7036
7656
|
useEffect(() => {
|
|
7037
7657
|
if (agentsMonitorController) agentsMonitorController.visible = agentsMonitorOpen;
|
|
7038
7658
|
}, [agentsMonitorController, agentsMonitorOpen]);
|
|
7659
|
+
useEffect(() => {
|
|
7660
|
+
if (!onPanelOpen) return;
|
|
7661
|
+
onPanelOpen.current = (action) => {
|
|
7662
|
+
dispatch({ type: action });
|
|
7663
|
+
return true;
|
|
7664
|
+
};
|
|
7665
|
+
return () => {
|
|
7666
|
+
onPanelOpen.current = null;
|
|
7667
|
+
};
|
|
7668
|
+
}, [onPanelOpen, dispatch]);
|
|
7039
7669
|
}
|
|
7040
7670
|
function useBrainEvents(events, dispatch) {
|
|
7041
7671
|
useEffect(() => {
|
|
@@ -8055,10 +8685,12 @@ function reducer(state, action) {
|
|
|
8055
8685
|
featureMemory: action.featureMemory,
|
|
8056
8686
|
featureSkills: action.featureSkills,
|
|
8057
8687
|
featureModelsRegistry: action.featureModelsRegistry,
|
|
8058
|
-
|
|
8688
|
+
tokenSavingTier: action.tokenSavingTier,
|
|
8059
8689
|
allowOutsideProjectRoot: action.allowOutsideProjectRoot,
|
|
8060
8690
|
contextAutoCompact: action.contextAutoCompact,
|
|
8061
8691
|
contextStrategy: action.contextStrategy,
|
|
8692
|
+
contextMode: action.contextMode,
|
|
8693
|
+
maxConcurrent: action.maxConcurrent,
|
|
8062
8694
|
logLevel: action.logLevel,
|
|
8063
8695
|
auditLevel: action.auditLevel,
|
|
8064
8696
|
indexOnStart: action.indexOnStart,
|
|
@@ -8115,7 +8747,12 @@ function reducer(state, action) {
|
|
|
8115
8747
|
if (f === 10) return { ...state, settingsPicker: { ...sp, featureMemory: !sp.featureMemory, hint: bootHint } };
|
|
8116
8748
|
if (f === 11) return { ...state, settingsPicker: { ...sp, featureSkills: !sp.featureSkills, hint: bootHint } };
|
|
8117
8749
|
if (f === 12) return { ...state, settingsPicker: { ...sp, featureModelsRegistry: !sp.featureModelsRegistry, hint: bootHint } };
|
|
8118
|
-
if (f === 13)
|
|
8750
|
+
if (f === 13) {
|
|
8751
|
+
const i = TOKEN_SAVING_TIERS.indexOf(sp.tokenSavingTier);
|
|
8752
|
+
const base = i < 0 ? 0 : i;
|
|
8753
|
+
const next = (base + action.delta + TOKEN_SAVING_TIERS.length) % TOKEN_SAVING_TIERS.length;
|
|
8754
|
+
return { ...state, settingsPicker: { ...sp, tokenSavingTier: TOKEN_SAVING_TIERS[next] ?? "off", hint: bootHint } };
|
|
8755
|
+
}
|
|
8119
8756
|
if (f === 14) return { ...state, settingsPicker: { ...sp, allowOutsideProjectRoot: !sp.allowOutsideProjectRoot, hint: void 0 } };
|
|
8120
8757
|
if (f === 15) return { ...state, settingsPicker: { ...sp, contextAutoCompact: !sp.contextAutoCompact, hint: void 0 } };
|
|
8121
8758
|
if (f === 16) {
|
|
@@ -8125,45 +8762,57 @@ function reducer(state, action) {
|
|
|
8125
8762
|
return { ...state, settingsPicker: { ...sp, contextStrategy: expectDefined$1(COMPACTOR_STRATEGIES[next]), hint: bootHint } };
|
|
8126
8763
|
}
|
|
8127
8764
|
if (f === 17) {
|
|
8765
|
+
const i = CONTEXT_MODES.indexOf(sp.contextMode);
|
|
8766
|
+
const base = i < 0 ? 0 : i;
|
|
8767
|
+
const next = (base + action.delta + CONTEXT_MODES.length) % CONTEXT_MODES.length;
|
|
8768
|
+
return { ...state, settingsPicker: { ...sp, contextMode: expectDefined$1(CONTEXT_MODES[next]), hint: bootHint } };
|
|
8769
|
+
}
|
|
8770
|
+
if (f === 18) {
|
|
8771
|
+
const j = MAX_CONCURRENT_PRESETS.indexOf(sp.maxConcurrent);
|
|
8772
|
+
const base = j < 0 ? 0 : j;
|
|
8773
|
+
const next = (base + action.delta + MAX_CONCURRENT_PRESETS.length) % MAX_CONCURRENT_PRESETS.length;
|
|
8774
|
+
return { ...state, settingsPicker: { ...sp, maxConcurrent: expectDefined$1(MAX_CONCURRENT_PRESETS[next]), hint: void 0 } };
|
|
8775
|
+
}
|
|
8776
|
+
if (f === 19) {
|
|
8128
8777
|
const i = LOG_LEVELS.indexOf(sp.logLevel);
|
|
8129
8778
|
const base = i < 0 ? 0 : i;
|
|
8130
8779
|
const next = (base + action.delta + LOG_LEVELS.length) % LOG_LEVELS.length;
|
|
8131
8780
|
return { ...state, settingsPicker: { ...sp, logLevel: expectDefined$1(LOG_LEVELS[next]), hint: void 0 } };
|
|
8132
8781
|
}
|
|
8133
|
-
if (f ===
|
|
8782
|
+
if (f === 20) {
|
|
8134
8783
|
const i = AUDIT_LEVELS.indexOf(sp.auditLevel);
|
|
8135
8784
|
const base = i < 0 ? 0 : i;
|
|
8136
8785
|
const next = (base + action.delta + AUDIT_LEVELS.length) % AUDIT_LEVELS.length;
|
|
8137
8786
|
return { ...state, settingsPicker: { ...sp, auditLevel: expectDefined$1(AUDIT_LEVELS[next]), hint: void 0 } };
|
|
8138
8787
|
}
|
|
8139
|
-
if (f ===
|
|
8140
|
-
if (f ===
|
|
8788
|
+
if (f === 21) return { ...state, settingsPicker: { ...sp, indexOnStart: !sp.indexOnStart, hint: bootHint } };
|
|
8789
|
+
if (f === 22) {
|
|
8141
8790
|
const j = MAX_ITERATIONS_PRESETS.indexOf(sp.maxIterations);
|
|
8142
8791
|
const base = j < 0 ? 0 : j;
|
|
8143
8792
|
const next = (base + action.delta + MAX_ITERATIONS_PRESETS.length) % MAX_ITERATIONS_PRESETS.length;
|
|
8144
8793
|
return { ...state, settingsPicker: { ...sp, maxIterations: expectDefined$1(MAX_ITERATIONS_PRESETS[next]), hint: void 0 } };
|
|
8145
8794
|
}
|
|
8146
|
-
if (f ===
|
|
8795
|
+
if (f === 23) {
|
|
8147
8796
|
const aj = AUTO_PROCEED_MAX_PRESETS.indexOf(sp.autoProceedMaxIterations);
|
|
8148
8797
|
const abase = aj < 0 ? 0 : aj;
|
|
8149
8798
|
const anext = (abase + action.delta + AUTO_PROCEED_MAX_PRESETS.length) % AUTO_PROCEED_MAX_PRESETS.length;
|
|
8150
8799
|
return { ...state, settingsPicker: { ...sp, autoProceedMaxIterations: expectDefined$1(AUTO_PROCEED_MAX_PRESETS[anext]), hint: void 0 } };
|
|
8151
8800
|
}
|
|
8152
|
-
if (f ===
|
|
8801
|
+
if (f === 24) {
|
|
8153
8802
|
const ej = ENHANCE_DELAY_PRESETS.indexOf(sp.enhanceDelayMs);
|
|
8154
8803
|
const ebase = ej < 0 ? 0 : ej;
|
|
8155
8804
|
const enext = (ebase + action.delta + ENHANCE_DELAY_PRESETS.length) % ENHANCE_DELAY_PRESETS.length;
|
|
8156
8805
|
return { ...state, settingsPicker: { ...sp, enhanceDelayMs: expectDefined$1(ENHANCE_DELAY_PRESETS[enext]), hint: void 0 } };
|
|
8157
8806
|
}
|
|
8158
|
-
if (f ===
|
|
8159
|
-
if (f ===
|
|
8807
|
+
if (f === 25) return { ...state, settingsPicker: { ...sp, enhanceEnabled: !sp.enhanceEnabled, hint: void 0 } };
|
|
8808
|
+
if (f === 26) {
|
|
8160
8809
|
const i = ENHANCE_LANGUAGES.indexOf(sp.enhanceLanguage);
|
|
8161
8810
|
const base = i < 0 ? 0 : i;
|
|
8162
8811
|
const next = (base + action.delta + ENHANCE_LANGUAGES.length) % ENHANCE_LANGUAGES.length;
|
|
8163
8812
|
return { ...state, settingsPicker: { ...sp, enhanceLanguage: expectDefined$1(ENHANCE_LANGUAGES[next]), hint: void 0 } };
|
|
8164
8813
|
}
|
|
8165
|
-
if (f ===
|
|
8166
|
-
if (f ===
|
|
8814
|
+
if (f === 27) return { ...state, settingsPicker: { ...sp, debugStream: !sp.debugStream, hint: void 0 } };
|
|
8815
|
+
if (f === 28) {
|
|
8167
8816
|
const i = CONFIG_SCOPES.indexOf(sp.configScope);
|
|
8168
8817
|
const base = i < 0 ? 0 : i;
|
|
8169
8818
|
const next = (base + action.delta + CONFIG_SCOPES.length) % CONFIG_SCOPES.length;
|
|
@@ -8173,6 +8822,62 @@ function reducer(state, action) {
|
|
|
8173
8822
|
}
|
|
8174
8823
|
case "settingsHint":
|
|
8175
8824
|
return { ...state, settingsPicker: { ...state.settingsPicker, hint: action.text } };
|
|
8825
|
+
// ── Statusline picker ───────────────────────────────────────────────
|
|
8826
|
+
case "statuslineOpen":
|
|
8827
|
+
return {
|
|
8828
|
+
...state,
|
|
8829
|
+
statuslinePicker: { open: true, field: 0, hiddenItems: action.hiddenItems, visibleChips: state.statuslinePicker.visibleChips, hint: void 0 }
|
|
8830
|
+
};
|
|
8831
|
+
case "statuslineClose":
|
|
8832
|
+
return { ...state, statuslinePicker: { ...state.statuslinePicker, open: false, hint: void 0 } };
|
|
8833
|
+
case "statuslineFieldMove": {
|
|
8834
|
+
const totalFields = 13;
|
|
8835
|
+
const next = (state.statuslinePicker.field + action.delta + totalFields) % totalFields;
|
|
8836
|
+
return { ...state, statuslinePicker: { ...state.statuslinePicker, field: next, hint: void 0 } };
|
|
8837
|
+
}
|
|
8838
|
+
case "statuslineFieldSet": {
|
|
8839
|
+
const totalFields = 13;
|
|
8840
|
+
const field = action.field >= 0 && action.field < totalFields ? action.field : 0;
|
|
8841
|
+
return { ...state, statuslinePicker: { ...state.statuslinePicker, field, hint: void 0 } };
|
|
8842
|
+
}
|
|
8843
|
+
case "statuslineToggle": {
|
|
8844
|
+
const cur = state.statuslinePicker;
|
|
8845
|
+
const hiddenSet = new Set(cur.hiddenItems);
|
|
8846
|
+
if (hiddenSet.has(action.item)) {
|
|
8847
|
+
hiddenSet.delete(action.item);
|
|
8848
|
+
} else {
|
|
8849
|
+
hiddenSet.add(action.item);
|
|
8850
|
+
}
|
|
8851
|
+
return { ...state, statuslinePicker: { ...cur, hiddenItems: [...hiddenSet] } };
|
|
8852
|
+
}
|
|
8853
|
+
case "statuslineHint":
|
|
8854
|
+
return { ...state, statuslinePicker: { ...state.statuslinePicker, hint: action.text } };
|
|
8855
|
+
case "statuslineChipShow": {
|
|
8856
|
+
const cur = state.statuslinePicker;
|
|
8857
|
+
const existing = cur.visibleChips.findIndex((c) => c.key === action.key);
|
|
8858
|
+
const meta = action.expiresIn != null ? { key: action.key, shownAt: Date.now(), expiresIn: action.expiresIn } : { key: action.key, shownAt: Date.now() };
|
|
8859
|
+
if (existing >= 0) {
|
|
8860
|
+
const updated = [...cur.visibleChips];
|
|
8861
|
+
updated[existing] = meta;
|
|
8862
|
+
return { ...state, statuslinePicker: { ...cur, visibleChips: updated } };
|
|
8863
|
+
}
|
|
8864
|
+
return { ...state, statuslinePicker: { ...cur, visibleChips: [...cur.visibleChips, meta] } };
|
|
8865
|
+
}
|
|
8866
|
+
case "statuslineChipExpire": {
|
|
8867
|
+
const cur = state.statuslinePicker;
|
|
8868
|
+
return {
|
|
8869
|
+
...state,
|
|
8870
|
+
statuslinePicker: {
|
|
8871
|
+
...cur,
|
|
8872
|
+
visibleChips: cur.visibleChips.filter((c) => c.key !== action.key)
|
|
8873
|
+
}
|
|
8874
|
+
};
|
|
8875
|
+
}
|
|
8876
|
+
case "statuslineVisibleChipsSync":
|
|
8877
|
+
return {
|
|
8878
|
+
...state,
|
|
8879
|
+
statuslinePicker: { ...state.statuslinePicker, visibleChips: action.visibleChips }
|
|
8880
|
+
};
|
|
8176
8881
|
case "projectPickerOpen":
|
|
8177
8882
|
return {
|
|
8178
8883
|
...state,
|
|
@@ -8215,6 +8920,15 @@ function reducer(state, action) {
|
|
|
8215
8920
|
}
|
|
8216
8921
|
case "projectPickerHint":
|
|
8217
8922
|
return { ...state, projectPicker: { ...state.projectPicker, hint: action.text } };
|
|
8923
|
+
case "fKeyPickerOpen":
|
|
8924
|
+
return { ...state, fKeyPicker: { open: true, selected: 0 } };
|
|
8925
|
+
case "fKeyPickerClose":
|
|
8926
|
+
return { ...state, fKeyPicker: { open: false, selected: 0 } };
|
|
8927
|
+
case "fKeyPickerMove": {
|
|
8928
|
+
const count = 12;
|
|
8929
|
+
const next = (state.fKeyPicker.selected + action.delta + count) % count;
|
|
8930
|
+
return { ...state, fKeyPicker: { ...state.fKeyPicker, selected: next } };
|
|
8931
|
+
}
|
|
8218
8932
|
case "confirmOpen":
|
|
8219
8933
|
return { ...state, confirmQueue: [...state.confirmQueue, action.info] };
|
|
8220
8934
|
case "confirmClose":
|
|
@@ -8574,6 +9288,10 @@ function reducer(state, action) {
|
|
|
8574
9288
|
const opening = !state.processListOpen;
|
|
8575
9289
|
return opening ? { ...state, processListOpen: true, monitorOpen: false, agentsMonitorOpen: false, helpOpen: false, todosMonitorOpen: false, queuePanelOpen: false, goalPanelOpen: false } : { ...state, processListOpen: false };
|
|
8576
9290
|
}
|
|
9291
|
+
case "togglePlanPanel": {
|
|
9292
|
+
const opening = !state.planPanelOpen;
|
|
9293
|
+
return opening ? { ...state, planPanelOpen: true, monitorOpen: false, agentsMonitorOpen: false, helpOpen: false, todosMonitorOpen: false, queuePanelOpen: false, processListOpen: false, goalPanelOpen: false } : { ...state, planPanelOpen: false };
|
|
9294
|
+
}
|
|
8577
9295
|
case "toggleGoalPanel": {
|
|
8578
9296
|
const opening = !state.goalPanelOpen;
|
|
8579
9297
|
return opening ? { ...state, goalPanelOpen: true, monitorOpen: false, agentsMonitorOpen: false, helpOpen: false, todosMonitorOpen: false, queuePanelOpen: false, processListOpen: false } : { ...state, goalPanelOpen: false };
|
|
@@ -9046,6 +9764,7 @@ function rehydrateHistory(messages, startId, toolCalls) {
|
|
|
9046
9764
|
return entries;
|
|
9047
9765
|
}
|
|
9048
9766
|
var PASTE_THRESHOLD_CHARS = 200;
|
|
9767
|
+
var SB_PADX2 = 2;
|
|
9049
9768
|
function App({
|
|
9050
9769
|
agent,
|
|
9051
9770
|
slashRegistry,
|
|
@@ -9103,6 +9822,7 @@ function App({
|
|
|
9103
9822
|
interruptController,
|
|
9104
9823
|
statuslineHiddenItems,
|
|
9105
9824
|
setStatuslineHiddenItems,
|
|
9825
|
+
saveStatuslineHiddenItems,
|
|
9106
9826
|
agentsMonitorController,
|
|
9107
9827
|
initialGoal,
|
|
9108
9828
|
initialAsk,
|
|
@@ -9118,7 +9838,12 @@ function App({
|
|
|
9118
9838
|
getLiveSessions,
|
|
9119
9839
|
onSwitchToSession,
|
|
9120
9840
|
initialAgentsMonitorOpen,
|
|
9121
|
-
|
|
9841
|
+
onPanelOpen,
|
|
9842
|
+
subscribeCoordinatorEvents,
|
|
9843
|
+
onCoordinatorStart,
|
|
9844
|
+
onCoordinatorStop,
|
|
9845
|
+
coordinatorRunning = false,
|
|
9846
|
+
clientId
|
|
9122
9847
|
}) {
|
|
9123
9848
|
const { exit } = useApp();
|
|
9124
9849
|
const { stdout } = useStdout();
|
|
@@ -9148,18 +9873,45 @@ function App({
|
|
|
9148
9873
|
modeLabel,
|
|
9149
9874
|
statuslineHiddenItems
|
|
9150
9875
|
});
|
|
9876
|
+
const hiddenItemsRef = useRef(hiddenItems);
|
|
9877
|
+
hiddenItemsRef.current = hiddenItems;
|
|
9151
9878
|
const prevBranchRef = useRef(null);
|
|
9152
9879
|
const [indexState, setIndexState] = useState(() => getIndexState());
|
|
9153
9880
|
useEffect(() => {
|
|
9154
9881
|
setIndexState(getIndexState());
|
|
9155
9882
|
return onIndexStateChange((next) => setIndexState(next));
|
|
9156
9883
|
}, []);
|
|
9884
|
+
const [breakerCountdown, setBreakerCountdown] = useState(
|
|
9885
|
+
() => getProcessRegistry().getBreakerCountdown()
|
|
9886
|
+
);
|
|
9887
|
+
useEffect(() => {
|
|
9888
|
+
const s2 = getSettings?.();
|
|
9889
|
+
if (s2) {
|
|
9890
|
+
getProcessRegistry().setBreakerConfig({
|
|
9891
|
+
enabled: s2.breakerEnabled ?? false,
|
|
9892
|
+
autoKillResetMs: s2.breakerAutoKillResetMs ?? 6e4
|
|
9893
|
+
});
|
|
9894
|
+
}
|
|
9895
|
+
return getProcessRegistry().onBreakerCountdownChange((snap) => setBreakerCountdown(snap));
|
|
9896
|
+
}, [getSettings]);
|
|
9897
|
+
const breakerArmed = breakerCountdown !== null;
|
|
9898
|
+
useEffect(() => {
|
|
9899
|
+
if (!breakerArmed) return;
|
|
9900
|
+
const t = setInterval(
|
|
9901
|
+
() => setBreakerCountdown(getProcessRegistry().getBreakerCountdown()),
|
|
9902
|
+
1e3
|
|
9903
|
+
);
|
|
9904
|
+
return () => clearInterval(t);
|
|
9905
|
+
}, [breakerArmed]);
|
|
9157
9906
|
useEffect(() => {
|
|
9158
9907
|
setHiddenItems([...statuslineHiddenItems]);
|
|
9159
9908
|
}, [statuslineHiddenItems]);
|
|
9160
9909
|
useEffect(() => {
|
|
9161
9910
|
setStatuslineHiddenItems(hiddenItems);
|
|
9162
|
-
|
|
9911
|
+
saveStatuslineHiddenItems(hiddenItems).catch?.((err) => {
|
|
9912
|
+
console.error("[statusline] failed to persist hidden items:", err);
|
|
9913
|
+
});
|
|
9914
|
+
}, [setStatuslineHiddenItems, saveStatuslineHiddenItems, hiddenItems]);
|
|
9163
9915
|
const projectRoot = agent.ctx.projectRoot;
|
|
9164
9916
|
const refreshGoalSummary = useCallback(() => {
|
|
9165
9917
|
if (!projectRoot) return;
|
|
@@ -9251,8 +10003,10 @@ function App({
|
|
|
9251
10003
|
},
|
|
9252
10004
|
autonomyPicker: { open: false, options: [], selected: 0 },
|
|
9253
10005
|
resumePicker: { open: false, sessions: [], selected: 0, busy: false, hint: void 0, error: void 0 },
|
|
9254
|
-
settingsPicker: { open: false, field: 0, mode: "off", delayMs: 0, titleAnimation: true, yolo: false, streamFleet: true, chime: false, confirmExit: true, nextPrediction: false, featureMcp: true, featurePlugins: true, featureMemory: true, featureSkills: true, featureModelsRegistry: true,
|
|
10006
|
+
settingsPicker: { open: false, field: 0, mode: "off", delayMs: 0, titleAnimation: true, yolo: false, streamFleet: true, chime: false, confirmExit: true, nextPrediction: false, featureMcp: true, featurePlugins: true, featureMemory: true, featureSkills: true, featureModelsRegistry: true, tokenSavingTier: "off", allowOutsideProjectRoot: true, contextAutoCompact: true, contextStrategy: "hybrid", contextMode: "balanced", maxConcurrent: 10, logLevel: "info", auditLevel: "standard", indexOnStart: true, maxIterations: 500, autoProceedMaxIterations: 50, enhanceDelayMs: 6e4, enhanceEnabled: true, enhanceLanguage: "original", debugStream: false, configScope: "global" },
|
|
10007
|
+
statuslinePicker: { open: false, field: 0, hiddenItems: [], visibleChips: [], hint: void 0 },
|
|
9255
10008
|
projectPicker: { open: false, allItems: [], items: [], selected: 0, filter: "", hint: void 0 },
|
|
10009
|
+
fKeyPicker: { open: false, selected: 0 },
|
|
9256
10010
|
confirmQueue: [],
|
|
9257
10011
|
enhance: null,
|
|
9258
10012
|
enhanceEnabled,
|
|
@@ -9279,6 +10033,7 @@ function App({
|
|
|
9279
10033
|
todosMonitorOpen: false,
|
|
9280
10034
|
queuePanelOpen: false,
|
|
9281
10035
|
processListOpen: false,
|
|
10036
|
+
planPanelOpen: false,
|
|
9282
10037
|
goalPanelOpen: false,
|
|
9283
10038
|
sessionsPanelOpen: false,
|
|
9284
10039
|
sessionsPanel: { sessions: [], busy: false, selected: -1 },
|
|
@@ -9305,6 +10060,52 @@ function App({
|
|
|
9305
10060
|
debugStreamStats: null,
|
|
9306
10061
|
countdown: null
|
|
9307
10062
|
});
|
|
10063
|
+
useEffect(() => {
|
|
10064
|
+
if (state.statuslinePicker.open) {
|
|
10065
|
+
const pickerHidden = state.statuslinePicker.hiddenItems;
|
|
10066
|
+
const currentHidden = new Set(hiddenItems);
|
|
10067
|
+
const pickerHiddenSet = new Set(pickerHidden);
|
|
10068
|
+
const differs = currentHidden.size !== pickerHiddenSet.size || pickerHidden.some((item) => !currentHidden.has(item)) || hiddenItems.some((item) => !pickerHiddenSet.has(item));
|
|
10069
|
+
if (differs) {
|
|
10070
|
+
setHiddenItems([...pickerHidden]);
|
|
10071
|
+
}
|
|
10072
|
+
}
|
|
10073
|
+
}, [state.statuslinePicker.hiddenItems, state.statuslinePicker.open, setHiddenItems, hiddenItems]);
|
|
10074
|
+
const prevBrainPromptRef = useRef(state.brainPrompt);
|
|
10075
|
+
const prevEnhanceRef = useRef(state.enhance);
|
|
10076
|
+
useEffect(() => {
|
|
10077
|
+
if (state.brainPrompt && !prevBrainPromptRef.current) {
|
|
10078
|
+
dispatch({ type: "statuslineChipShow", key: "brain", expiresIn: 5 });
|
|
10079
|
+
} else if (!state.brainPrompt && prevBrainPromptRef.current) {
|
|
10080
|
+
if (state.statuslinePicker.visibleChips.some((c) => c.key === "brain")) {
|
|
10081
|
+
dispatch({ type: "statuslineChipExpire", key: "brain" });
|
|
10082
|
+
}
|
|
10083
|
+
}
|
|
10084
|
+
prevBrainPromptRef.current = state.brainPrompt;
|
|
10085
|
+
if (state.enhance && !prevEnhanceRef.current) {
|
|
10086
|
+
dispatch({ type: "statuslineChipShow", key: "enhance", expiresIn: 5 });
|
|
10087
|
+
} else if (!state.enhance && prevEnhanceRef.current) {
|
|
10088
|
+
if (state.statuslinePicker.visibleChips.some((c) => c.key === "enhance")) {
|
|
10089
|
+
dispatch({ type: "statuslineChipExpire", key: "enhance" });
|
|
10090
|
+
}
|
|
10091
|
+
}
|
|
10092
|
+
prevEnhanceRef.current = state.enhance;
|
|
10093
|
+
}, [
|
|
10094
|
+
state.brainPrompt,
|
|
10095
|
+
state.enhance,
|
|
10096
|
+
state.statuslinePicker.visibleChips,
|
|
10097
|
+
dispatch
|
|
10098
|
+
]);
|
|
10099
|
+
useEffect(() => {
|
|
10100
|
+
const interval = setInterval(() => {
|
|
10101
|
+
const now = Date.now();
|
|
10102
|
+
const expired = state.statuslinePicker.visibleChips.filter((c) => isChipExpired(c, now));
|
|
10103
|
+
for (const chip of expired) {
|
|
10104
|
+
dispatch({ type: "statuslineChipExpire", key: chip.key });
|
|
10105
|
+
}
|
|
10106
|
+
}, 3e4);
|
|
10107
|
+
return () => clearInterval(interval);
|
|
10108
|
+
}, [state.statuslinePicker.visibleChips, dispatch]);
|
|
9308
10109
|
useAutonomousCoordinator(subscribeCoordinatorEvents, dispatch);
|
|
9309
10110
|
const builderRef = useRef(null);
|
|
9310
10111
|
if (builderRef.current === null) {
|
|
@@ -9318,20 +10119,20 @@ function App({
|
|
|
9318
10119
|
const lastEnterAtRef = useRef(0);
|
|
9319
10120
|
const tokenPreviewsRef = useRef(/* @__PURE__ */ new Map());
|
|
9320
10121
|
const projectName = React5.useMemo(() => {
|
|
9321
|
-
const base =
|
|
9322
|
-
return base && base !==
|
|
10122
|
+
const base = path5.basename(projectRoot);
|
|
10123
|
+
return base && base !== path5.sep ? base : void 0;
|
|
9323
10124
|
}, [projectRoot]);
|
|
9324
10125
|
const [workingDirChip, setWorkingDirChip] = React5.useState(() => {
|
|
9325
10126
|
const ctx = agent.ctx;
|
|
9326
10127
|
if (ctx.workingDir && ctx.workingDir !== projectRoot) {
|
|
9327
|
-
return
|
|
10128
|
+
return path5.relative(projectRoot, ctx.workingDir) || ".";
|
|
9328
10129
|
}
|
|
9329
10130
|
return void 0;
|
|
9330
10131
|
});
|
|
9331
10132
|
React5.useEffect(() => {
|
|
9332
10133
|
const ctx = agent.ctx;
|
|
9333
10134
|
return ctx.onWorkingDirChanged((newDir) => {
|
|
9334
|
-
const rel =
|
|
10135
|
+
const rel = path5.relative(projectRoot, newDir) || ".";
|
|
9335
10136
|
setWorkingDirChip(rel === "." ? void 0 : rel);
|
|
9336
10137
|
});
|
|
9337
10138
|
}, [agent.ctx, projectRoot]);
|
|
@@ -9728,7 +10529,7 @@ function App({
|
|
|
9728
10529
|
let cancelled = false;
|
|
9729
10530
|
const poll = async () => {
|
|
9730
10531
|
try {
|
|
9731
|
-
const data = await
|
|
10532
|
+
const data = await fs3.readFile(planPath, "utf8");
|
|
9732
10533
|
const parsed = JSON.parse(data);
|
|
9733
10534
|
if (cancelled) return;
|
|
9734
10535
|
if (!Array.isArray(parsed.items)) {
|
|
@@ -9762,7 +10563,7 @@ function App({
|
|
|
9762
10563
|
let cancelled = false;
|
|
9763
10564
|
const poll = async () => {
|
|
9764
10565
|
try {
|
|
9765
|
-
const data = await
|
|
10566
|
+
const data = await fs3.readFile(taskPath, "utf8");
|
|
9766
10567
|
const parsed = JSON.parse(data);
|
|
9767
10568
|
if (cancelled) return;
|
|
9768
10569
|
if (!Array.isArray(parsed.tasks)) {
|
|
@@ -9874,6 +10675,7 @@ function App({
|
|
|
9874
10675
|
if (stateRef.current.todosMonitorOpen) dispatch({ type: "toggleTodosMonitor" });
|
|
9875
10676
|
if (stateRef.current.queuePanelOpen) dispatch({ type: "toggleQueuePanel" });
|
|
9876
10677
|
if (stateRef.current.processListOpen) dispatch({ type: "toggleProcessList" });
|
|
10678
|
+
if (stateRef.current.planPanelOpen) dispatch({ type: "togglePlanPanel" });
|
|
9877
10679
|
if (stateRef.current.goalPanelOpen) dispatch({ type: "toggleGoalPanel" });
|
|
9878
10680
|
if (stateRef.current.sessionsPanelOpen) dispatch({ type: "toggleSessionsPanel" });
|
|
9879
10681
|
eraseLiveRegion();
|
|
@@ -9899,10 +10701,12 @@ function App({
|
|
|
9899
10701
|
featureMemory: sp.featureMemory,
|
|
9900
10702
|
featureSkills: sp.featureSkills,
|
|
9901
10703
|
featureModelsRegistry: sp.featureModelsRegistry,
|
|
9902
|
-
|
|
10704
|
+
tokenSavingTier: sp.tokenSavingTier,
|
|
9903
10705
|
allowOutsideProjectRoot: sp.allowOutsideProjectRoot,
|
|
9904
10706
|
contextAutoCompact: sp.contextAutoCompact,
|
|
9905
10707
|
contextStrategy: sp.contextStrategy,
|
|
10708
|
+
contextMode: sp.contextMode,
|
|
10709
|
+
maxConcurrent: sp.maxConcurrent,
|
|
9906
10710
|
logLevel: sp.logLevel,
|
|
9907
10711
|
auditLevel: sp.auditLevel,
|
|
9908
10712
|
indexOnStart: sp.indexOnStart,
|
|
@@ -9979,6 +10783,7 @@ function App({
|
|
|
9979
10783
|
const allCommands = slashRegistry.listWithOwner();
|
|
9980
10784
|
const CATEGORY_ORDER = ["Run", "Session", "Inspect", "Agent", "Config", "App"];
|
|
9981
10785
|
const matches = allCommands.filter(({ cmd }) => {
|
|
10786
|
+
if (query === "" && cmd.hidden) return false;
|
|
9982
10787
|
const name = cmd.name.toLowerCase();
|
|
9983
10788
|
const aliases = cmd.aliases ?? [];
|
|
9984
10789
|
return name.includes(query) || aliases.some((a) => a.toLowerCase().includes(query));
|
|
@@ -10061,9 +10866,9 @@ function App({
|
|
|
10061
10866
|
dispatch({ type: "pickerClose" });
|
|
10062
10867
|
return;
|
|
10063
10868
|
}
|
|
10064
|
-
const absPath =
|
|
10869
|
+
const absPath = path5.isAbsolute(picked) ? picked : path5.join(projectRoot, picked);
|
|
10065
10870
|
try {
|
|
10066
|
-
const data = await
|
|
10871
|
+
const data = await fs3.readFile(absPath, "utf8");
|
|
10067
10872
|
const token = await builder.registerFile({
|
|
10068
10873
|
kind: "file",
|
|
10069
10874
|
data,
|
|
@@ -10265,6 +11070,9 @@ function App({
|
|
|
10265
11070
|
const items = await getProjectPickerItems();
|
|
10266
11071
|
dispatch({ type: "projectPickerOpen", items });
|
|
10267
11072
|
}, [getProjectPickerItems]);
|
|
11073
|
+
const openFKeyPicker = React5.useCallback(() => {
|
|
11074
|
+
dispatch({ type: "fKeyPickerOpen" });
|
|
11075
|
+
}, [dispatch]);
|
|
10268
11076
|
const loadLiveSessions = React5.useCallback(async () => {
|
|
10269
11077
|
if (!getLiveSessions) {
|
|
10270
11078
|
dispatch({ type: "sessionsPanelSet", sessions: [] });
|
|
@@ -10303,10 +11111,12 @@ function App({
|
|
|
10303
11111
|
featureMemory: s2.featureMemory ?? true,
|
|
10304
11112
|
featureSkills: s2.featureSkills ?? true,
|
|
10305
11113
|
featureModelsRegistry: s2.featureModelsRegistry ?? true,
|
|
10306
|
-
|
|
11114
|
+
tokenSavingTier: s2.featureTokenSaving ?? "off",
|
|
10307
11115
|
allowOutsideProjectRoot: s2.allowOutsideProjectRoot ?? true,
|
|
10308
11116
|
contextAutoCompact: s2.contextAutoCompact ?? true,
|
|
10309
11117
|
contextStrategy: s2.contextStrategy ?? "hybrid",
|
|
11118
|
+
contextMode: s2.contextMode ?? "balanced",
|
|
11119
|
+
maxConcurrent: s2.maxConcurrent ?? 10,
|
|
10310
11120
|
logLevel: s2.logLevel ?? "info",
|
|
10311
11121
|
auditLevel: s2.auditLevel ?? "standard",
|
|
10312
11122
|
indexOnStart: s2.indexOnStart ?? true,
|
|
@@ -10439,10 +11249,12 @@ function App({
|
|
|
10439
11249
|
featureMemory: sp.featureMemory,
|
|
10440
11250
|
featureSkills: sp.featureSkills,
|
|
10441
11251
|
featureModelsRegistry: sp.featureModelsRegistry,
|
|
10442
|
-
featureTokenSaving: sp.
|
|
11252
|
+
featureTokenSaving: sp.tokenSavingTier,
|
|
10443
11253
|
allowOutsideProjectRoot: sp.allowOutsideProjectRoot,
|
|
10444
11254
|
contextAutoCompact: sp.contextAutoCompact,
|
|
10445
11255
|
contextStrategy: sp.contextStrategy,
|
|
11256
|
+
contextMode: sp.contextMode,
|
|
11257
|
+
maxConcurrent: sp.maxConcurrent,
|
|
10446
11258
|
logLevel: sp.logLevel,
|
|
10447
11259
|
auditLevel: sp.auditLevel,
|
|
10448
11260
|
indexOnStart: sp.indexOnStart,
|
|
@@ -10471,10 +11283,12 @@ function App({
|
|
|
10471
11283
|
state.settingsPicker.featureMemory,
|
|
10472
11284
|
state.settingsPicker.featureSkills,
|
|
10473
11285
|
state.settingsPicker.featureModelsRegistry,
|
|
10474
|
-
state.settingsPicker.
|
|
11286
|
+
state.settingsPicker.tokenSavingTier,
|
|
10475
11287
|
state.settingsPicker.allowOutsideProjectRoot,
|
|
10476
11288
|
state.settingsPicker.contextAutoCompact,
|
|
10477
11289
|
state.settingsPicker.contextStrategy,
|
|
11290
|
+
state.settingsPicker.contextMode,
|
|
11291
|
+
state.settingsPicker.maxConcurrent,
|
|
10478
11292
|
state.settingsPicker.logLevel,
|
|
10479
11293
|
state.settingsPicker.auditLevel,
|
|
10480
11294
|
state.settingsPicker.indexOnStart,
|
|
@@ -10502,6 +11316,20 @@ function App({
|
|
|
10502
11316
|
slashRegistry.unregister("model");
|
|
10503
11317
|
};
|
|
10504
11318
|
}, [slashRegistry, getPickableProviders, switchProviderAndModel, openModelPicker]);
|
|
11319
|
+
useEffect(() => {
|
|
11320
|
+
const cmd = {
|
|
11321
|
+
name: "f",
|
|
11322
|
+
description: "Open F-key panel picker. Arrow keys to navigate, Enter to open, Esc to close.",
|
|
11323
|
+
async run() {
|
|
11324
|
+
openFKeyPicker();
|
|
11325
|
+
return { message: void 0 };
|
|
11326
|
+
}
|
|
11327
|
+
};
|
|
11328
|
+
slashRegistry.register(cmd, "tui", { official: true });
|
|
11329
|
+
return () => {
|
|
11330
|
+
slashRegistry.unregister("f");
|
|
11331
|
+
};
|
|
11332
|
+
}, [slashRegistry, openFKeyPicker]);
|
|
10505
11333
|
useEffect(() => {
|
|
10506
11334
|
if (!getSettings || !saveSettings) return;
|
|
10507
11335
|
const cmd = {
|
|
@@ -10518,6 +11346,26 @@ function App({
|
|
|
10518
11346
|
slashRegistry.unregister("settings");
|
|
10519
11347
|
};
|
|
10520
11348
|
}, [slashRegistry, getSettings, saveSettings, openSettings]);
|
|
11349
|
+
useEffect(() => {
|
|
11350
|
+
const cmd = {
|
|
11351
|
+
name: "statusline",
|
|
11352
|
+
aliases: ["sl"],
|
|
11353
|
+
description: "Customize status bar chips: /statusline (interactive) or /statusline <item> [on|off]",
|
|
11354
|
+
async run(args) {
|
|
11355
|
+
if (args.trim()) return { message: void 0 };
|
|
11356
|
+
const hookHidden = hiddenItemsRef.current;
|
|
11357
|
+
const reducerStreamHidden = stateRef.current.statuslinePicker.hiddenItems.filter(
|
|
11358
|
+
(item) => !hookHidden.includes(item)
|
|
11359
|
+
);
|
|
11360
|
+
dispatch({ type: "statuslineOpen", hiddenItems: [...hookHidden, ...reducerStreamHidden] });
|
|
11361
|
+
return { message: void 0 };
|
|
11362
|
+
}
|
|
11363
|
+
};
|
|
11364
|
+
slashRegistry.register(cmd, "tui", { official: true });
|
|
11365
|
+
return () => {
|
|
11366
|
+
slashRegistry.unregister("statusline");
|
|
11367
|
+
};
|
|
11368
|
+
}, [slashRegistry]);
|
|
10521
11369
|
useEffect(() => {
|
|
10522
11370
|
const cmd = {
|
|
10523
11371
|
name: "mailbox",
|
|
@@ -10746,6 +11594,47 @@ function App({
|
|
|
10746
11594
|
if (flushTimerRef.current) clearTimeout(flushTimerRef.current);
|
|
10747
11595
|
};
|
|
10748
11596
|
}, [events, agent.ctx.todos]);
|
|
11597
|
+
useEffect(() => {
|
|
11598
|
+
if (!clientId || !events) return;
|
|
11599
|
+
let toolCalls = 0;
|
|
11600
|
+
const emitStatus = () => {
|
|
11601
|
+
const usage = tokenCounter?.total();
|
|
11602
|
+
const cost = tokenCounter?.estimateCost();
|
|
11603
|
+
const mode = getAutonomy?.() ?? "off";
|
|
11604
|
+
events.emit("client.status", {
|
|
11605
|
+
clientType: "tui",
|
|
11606
|
+
clientId,
|
|
11607
|
+
projectHash: agent.ctx.projectRoot ? projectSlug(agent.ctx.projectRoot) : "unknown",
|
|
11608
|
+
agentCount: 1,
|
|
11609
|
+
// TUI is a single leader agent
|
|
11610
|
+
model: agent.ctx.model,
|
|
11611
|
+
mode,
|
|
11612
|
+
toolCalls,
|
|
11613
|
+
inputTokens: usage?.input ?? 0,
|
|
11614
|
+
outputTokens: usage?.output ?? 0,
|
|
11615
|
+
cacheTokens: (usage?.cacheRead ?? 0) + (usage?.cacheWrite ?? 0),
|
|
11616
|
+
costUsd: cost?.total ?? 0,
|
|
11617
|
+
timestamp: Date.now(),
|
|
11618
|
+
projectSlug: agent.ctx.projectRoot ? projectSlug(agent.ctx.projectRoot) : "unknown"
|
|
11619
|
+
});
|
|
11620
|
+
};
|
|
11621
|
+
const offTool = events.on("tool.executed", () => {
|
|
11622
|
+
toolCalls++;
|
|
11623
|
+
emitStatus();
|
|
11624
|
+
});
|
|
11625
|
+
const offProviderResp = events.on("provider.response", () => {
|
|
11626
|
+
emitStatus();
|
|
11627
|
+
});
|
|
11628
|
+
const offIterCompleted = events.on("iteration.completed", () => {
|
|
11629
|
+
emitStatus();
|
|
11630
|
+
});
|
|
11631
|
+
emitStatus();
|
|
11632
|
+
return () => {
|
|
11633
|
+
offTool();
|
|
11634
|
+
offProviderResp();
|
|
11635
|
+
offIterCompleted();
|
|
11636
|
+
};
|
|
11637
|
+
}, [events, clientId, tokenCounter, getAutonomy, agent.ctx.model, agent.ctx.projectRoot]);
|
|
10749
11638
|
useEffect(() => {
|
|
10750
11639
|
if (!registerDebugStreamCallback) return;
|
|
10751
11640
|
let cancelled = false;
|
|
@@ -10798,7 +11687,8 @@ function App({
|
|
|
10798
11687
|
agentsMonitorOpen: state.agentsMonitorOpen,
|
|
10799
11688
|
fleetStreamController,
|
|
10800
11689
|
enhanceController,
|
|
10801
|
-
agentsMonitorController
|
|
11690
|
+
agentsMonitorController,
|
|
11691
|
+
onPanelOpen
|
|
10802
11692
|
});
|
|
10803
11693
|
useEffect(() => {
|
|
10804
11694
|
if (!interruptController) return;
|
|
@@ -11210,6 +12100,32 @@ function App({
|
|
|
11210
12100
|
}
|
|
11211
12101
|
return;
|
|
11212
12102
|
}
|
|
12103
|
+
if (state.statuslinePicker.open) {
|
|
12104
|
+
if (key.escape) {
|
|
12105
|
+
dispatch({ type: "statuslineClose" });
|
|
12106
|
+
return;
|
|
12107
|
+
}
|
|
12108
|
+
if (key.mouse?.kind === "wheel") {
|
|
12109
|
+
dispatch({ type: "statuslineFieldMove", delta: key.mouse.wheel > 0 ? -1 : 1 });
|
|
12110
|
+
return;
|
|
12111
|
+
}
|
|
12112
|
+
if (key.upArrow) {
|
|
12113
|
+
dispatch({ type: "statuslineFieldMove", delta: -1 });
|
|
12114
|
+
return;
|
|
12115
|
+
}
|
|
12116
|
+
if (key.downArrow) {
|
|
12117
|
+
dispatch({ type: "statuslineFieldMove", delta: 1 });
|
|
12118
|
+
return;
|
|
12119
|
+
}
|
|
12120
|
+
if (key.leftArrow || key.rightArrow) {
|
|
12121
|
+
const focused = STATUSLINE_ITEMS[state.statuslinePicker.field];
|
|
12122
|
+
if (focused) {
|
|
12123
|
+
dispatch({ type: "statuslineToggle", item: focused });
|
|
12124
|
+
}
|
|
12125
|
+
return;
|
|
12126
|
+
}
|
|
12127
|
+
return;
|
|
12128
|
+
}
|
|
11213
12129
|
if (state.projectPicker.open) {
|
|
11214
12130
|
if (key.escape) {
|
|
11215
12131
|
if (state.projectPicker.filter) {
|
|
@@ -11401,6 +12317,29 @@ function App({
|
|
|
11401
12317
|
return;
|
|
11402
12318
|
}
|
|
11403
12319
|
}
|
|
12320
|
+
if (state.fKeyPicker.open) {
|
|
12321
|
+
if (key.escape) {
|
|
12322
|
+
dispatch({ type: "fKeyPickerClose" });
|
|
12323
|
+
return;
|
|
12324
|
+
}
|
|
12325
|
+
if (key.upArrow) {
|
|
12326
|
+
dispatch({ type: "fKeyPickerMove", delta: -1 });
|
|
12327
|
+
return;
|
|
12328
|
+
}
|
|
12329
|
+
if (key.downArrow) {
|
|
12330
|
+
dispatch({ type: "fKeyPickerMove", delta: 1 });
|
|
12331
|
+
return;
|
|
12332
|
+
}
|
|
12333
|
+
if (isEnter) {
|
|
12334
|
+
const selected = state.fKeyPicker.selected;
|
|
12335
|
+
const entry = F_KEY_ENTRIES[selected];
|
|
12336
|
+
if (!entry) return;
|
|
12337
|
+
dispatch({ type: "fKeyPickerClose" });
|
|
12338
|
+
dispatch({ type: entry.action });
|
|
12339
|
+
return;
|
|
12340
|
+
}
|
|
12341
|
+
return;
|
|
12342
|
+
}
|
|
11404
12343
|
if (state.picker.open) {
|
|
11405
12344
|
if (key.escape) {
|
|
11406
12345
|
dispatch({ type: "pickerClose" });
|
|
@@ -11566,6 +12505,21 @@ function App({
|
|
|
11566
12505
|
toggleWorktreeOverlay();
|
|
11567
12506
|
return;
|
|
11568
12507
|
}
|
|
12508
|
+
if (key.fn === 5) {
|
|
12509
|
+
if (state.planPanelOpen) {
|
|
12510
|
+
dispatch({ type: "togglePlanPanel" });
|
|
12511
|
+
} else {
|
|
12512
|
+
if (state.agentsMonitorOpen) dispatch({ type: "toggleAgentsMonitor" });
|
|
12513
|
+
if (state.monitorOpen) dispatch({ type: "toggleMonitor" });
|
|
12514
|
+
if (state.worktreeMonitorOpen) dispatch({ type: "worktreeMonitorToggle" });
|
|
12515
|
+
if (state.todosMonitorOpen) dispatch({ type: "toggleTodosMonitor" });
|
|
12516
|
+
if (state.autoPhase?.monitorOpen) dispatch({ type: "autoPhaseMonitorToggle" });
|
|
12517
|
+
if (state.settingsPicker.open) dispatch({ type: "settingsClose" });
|
|
12518
|
+
if (state.helpOpen) dispatch({ type: "toggleHelp" });
|
|
12519
|
+
dispatch({ type: "togglePlanPanel" });
|
|
12520
|
+
}
|
|
12521
|
+
return;
|
|
12522
|
+
}
|
|
11569
12523
|
if (key.fn === 6) {
|
|
11570
12524
|
toggleTodosOverlay();
|
|
11571
12525
|
return;
|
|
@@ -11668,10 +12622,12 @@ function App({
|
|
|
11668
12622
|
featureMemory: cfg.featureMemory ?? true,
|
|
11669
12623
|
featureSkills: cfg.featureSkills ?? true,
|
|
11670
12624
|
featureModelsRegistry: cfg.featureModelsRegistry ?? true,
|
|
11671
|
-
|
|
12625
|
+
tokenSavingTier: cfg.tokenSavingTier ?? "off",
|
|
11672
12626
|
allowOutsideProjectRoot: cfg.allowOutsideProjectRoot ?? true,
|
|
11673
12627
|
contextAutoCompact: cfg.contextAutoCompact ?? true,
|
|
11674
12628
|
contextStrategy: cfg.contextStrategy ?? "hybrid",
|
|
12629
|
+
contextMode: cfg.contextMode ?? "balanced",
|
|
12630
|
+
maxConcurrent: cfg.maxConcurrent ?? 10,
|
|
11675
12631
|
logLevel: cfg.logLevel ?? "info",
|
|
11676
12632
|
auditLevel: cfg.auditLevel ?? "standard",
|
|
11677
12633
|
indexOnStart: cfg.indexOnStart ?? true,
|
|
@@ -11735,7 +12691,8 @@ function App({
|
|
|
11735
12691
|
if (state.processListOpen) {
|
|
11736
12692
|
return;
|
|
11737
12693
|
}
|
|
11738
|
-
|
|
12694
|
+
const overlayOpen = state.monitorOpen || state.agentsMonitorOpen || state.worktreeMonitorOpen || state.todosMonitorOpen || state.queuePanelOpen || state.processListOpen || state.goalPanelOpen || state.sessionsPanelOpen || state.coordinator.monitorOpen || state.helpOpen || (state.autoPhase?.monitorOpen ?? false) || state.rewindOverlay !== null;
|
|
12695
|
+
if (input === "?" && !key.ctrl && !key.meta && draftRef.current.buffer === "" && !overlayOpen) {
|
|
11739
12696
|
dispatch({ type: "toggleHelp" });
|
|
11740
12697
|
return;
|
|
11741
12698
|
}
|
|
@@ -11851,7 +12808,57 @@ function App({
|
|
|
11851
12808
|
setDraft(buffer, buffer.length);
|
|
11852
12809
|
return;
|
|
11853
12810
|
}
|
|
11854
|
-
|
|
12811
|
+
if (!overlayOpen && (key.upArrow || key.downArrow || key.pageUp || key.pageDown)) {
|
|
12812
|
+
const width = stdout?.columns ?? 80;
|
|
12813
|
+
const rows = layoutInputRows(INPUT_PROMPT, buffer, cursor, width);
|
|
12814
|
+
if (rows.length <= 1) ; else {
|
|
12815
|
+
let row = 0, col = 0, offset = 0;
|
|
12816
|
+
outer: for (let r = 0; r < rows.length; r++) {
|
|
12817
|
+
const cells = rows[r];
|
|
12818
|
+
for (let c = 0; c < cells.length; c++) {
|
|
12819
|
+
if (offset === cursor) {
|
|
12820
|
+
row = r;
|
|
12821
|
+
col = c;
|
|
12822
|
+
break outer;
|
|
12823
|
+
}
|
|
12824
|
+
offset++;
|
|
12825
|
+
}
|
|
12826
|
+
if (cells.length < width) offset++;
|
|
12827
|
+
}
|
|
12828
|
+
if (key.upArrow) {
|
|
12829
|
+
if (row > 0) {
|
|
12830
|
+
const prevRowLen = rows[row - 1].filter((cell) => !cell.prompt && !cell.chip).length;
|
|
12831
|
+
const targetCol = Math.min(col, prevRowLen);
|
|
12832
|
+
const target = inputIndexAtRowCol(INPUT_PROMPT, buffer, width, row - 1, targetCol);
|
|
12833
|
+
setDraft(buffer, target);
|
|
12834
|
+
return;
|
|
12835
|
+
}
|
|
12836
|
+
return;
|
|
12837
|
+
}
|
|
12838
|
+
if (key.downArrow) {
|
|
12839
|
+
if (row < rows.length - 1) {
|
|
12840
|
+
const nextRowLen = rows[row + 1].filter((cell) => !cell.prompt && !cell.chip).length;
|
|
12841
|
+
const targetCol = Math.min(col, nextRowLen);
|
|
12842
|
+
const target = inputIndexAtRowCol(INPUT_PROMPT, buffer, width, row + 1, targetCol);
|
|
12843
|
+
setDraft(buffer, target);
|
|
12844
|
+
return;
|
|
12845
|
+
}
|
|
12846
|
+
return;
|
|
12847
|
+
}
|
|
12848
|
+
if (key.pageUp || key.pageDown) {
|
|
12849
|
+
const pageSize = Math.max(1, Math.floor((stdout?.rows ?? 24) / 2));
|
|
12850
|
+
const delta = key.pageUp ? -pageSize : pageSize;
|
|
12851
|
+
const targetRow = Math.max(0, Math.min(rows.length - 1, row + delta));
|
|
12852
|
+
if (targetRow !== row) {
|
|
12853
|
+
const targetRowLen = rows[targetRow].filter((cell) => !cell.prompt && !cell.chip).length;
|
|
12854
|
+
const targetCol = Math.min(col, targetRowLen);
|
|
12855
|
+
const target = inputIndexAtRowCol(INPUT_PROMPT, buffer, width, targetRow, targetCol);
|
|
12856
|
+
setDraft(buffer, target);
|
|
12857
|
+
}
|
|
12858
|
+
return;
|
|
12859
|
+
}
|
|
12860
|
+
}
|
|
12861
|
+
}
|
|
11855
12862
|
if (mouseMode && !overlayOpen) {
|
|
11856
12863
|
if (key.mouse?.kind === "wheel") {
|
|
11857
12864
|
if (key.mouse.shift) dispatch({ type: "scrollPage", dir: key.mouse.wheel > 0 ? "up" : "down" });
|
|
@@ -11902,6 +12909,40 @@ function App({
|
|
|
11902
12909
|
dispatch({ type: "toggleTodosMonitor" });
|
|
11903
12910
|
return;
|
|
11904
12911
|
}
|
|
12912
|
+
const hiddenSet = new Set(state.statuslinePicker.hiddenItems);
|
|
12913
|
+
if (my === rowFor(2)) {
|
|
12914
|
+
const mxLocal = mx - SB_PADX2 - 1;
|
|
12915
|
+
if (!hiddenSet.has("todos") && mxLocal >= 0 && mxLocal < 20) {
|
|
12916
|
+
dispatch({ type: "statuslineFieldSet", field: 11 });
|
|
12917
|
+
dispatch({ type: "statuslineOpen", hiddenItems: state.statuslinePicker.hiddenItems });
|
|
12918
|
+
return;
|
|
12919
|
+
}
|
|
12920
|
+
if (!hiddenSet.has("plan")) {
|
|
12921
|
+
const planStart = 21;
|
|
12922
|
+
if (mxLocal >= planStart && mxLocal < planStart + 22) {
|
|
12923
|
+
dispatch({ type: "statuslineFieldSet", field: 9 });
|
|
12924
|
+
dispatch({ type: "statuslineOpen", hiddenItems: state.statuslinePicker.hiddenItems });
|
|
12925
|
+
return;
|
|
12926
|
+
}
|
|
12927
|
+
}
|
|
12928
|
+
if (!hiddenSet.has("tasks")) {
|
|
12929
|
+
const tasksStart = 44;
|
|
12930
|
+
if (mxLocal >= tasksStart && mxLocal < tasksStart + 26) {
|
|
12931
|
+
dispatch({ type: "statuslineFieldSet", field: 10 });
|
|
12932
|
+
dispatch({ type: "statuslineOpen", hiddenItems: state.statuslinePicker.hiddenItems });
|
|
12933
|
+
return;
|
|
12934
|
+
}
|
|
12935
|
+
}
|
|
12936
|
+
}
|
|
12937
|
+
if (my === rowFor(3) && !hiddenSet.has("fleet")) {
|
|
12938
|
+
const mxLocal = mx - SB_PADX2 - 1;
|
|
12939
|
+
const fleetStart = 0;
|
|
12940
|
+
if (mxLocal >= fleetStart && mxLocal < fleetStart + 22) {
|
|
12941
|
+
dispatch({ type: "statuslineFieldSet", field: 12 });
|
|
12942
|
+
dispatch({ type: "statuslineOpen", hiddenItems: state.statuslinePicker.hiddenItems });
|
|
12943
|
+
return;
|
|
12944
|
+
}
|
|
12945
|
+
}
|
|
11905
12946
|
}
|
|
11906
12947
|
if (key.pageUp) {
|
|
11907
12948
|
dispatch({ type: "scrollPage", dir: "up" });
|
|
@@ -12626,10 +13667,12 @@ User message:
|
|
|
12626
13667
|
featureMemory: state.settingsPicker.featureMemory,
|
|
12627
13668
|
featureSkills: state.settingsPicker.featureSkills,
|
|
12628
13669
|
featureModelsRegistry: state.settingsPicker.featureModelsRegistry,
|
|
12629
|
-
|
|
13670
|
+
tokenSavingTier: state.settingsPicker.tokenSavingTier,
|
|
12630
13671
|
allowOutsideProjectRoot: state.settingsPicker.allowOutsideProjectRoot,
|
|
12631
13672
|
contextAutoCompact: state.settingsPicker.contextAutoCompact,
|
|
12632
13673
|
contextStrategy: state.settingsPicker.contextStrategy,
|
|
13674
|
+
contextMode: state.settingsPicker.contextMode,
|
|
13675
|
+
maxConcurrent: state.settingsPicker.maxConcurrent,
|
|
12633
13676
|
logLevel: state.settingsPicker.logLevel,
|
|
12634
13677
|
auditLevel: state.settingsPicker.auditLevel,
|
|
12635
13678
|
indexOnStart: state.settingsPicker.indexOnStart,
|
|
@@ -12643,6 +13686,15 @@ User message:
|
|
|
12643
13686
|
hint: state.settingsPicker.hint
|
|
12644
13687
|
}
|
|
12645
13688
|
) : null,
|
|
13689
|
+
state.statuslinePicker.open ? /* @__PURE__ */ jsx(
|
|
13690
|
+
StatuslinePicker,
|
|
13691
|
+
{
|
|
13692
|
+
field: state.statuslinePicker.field,
|
|
13693
|
+
hiddenItems: state.statuslinePicker.hiddenItems,
|
|
13694
|
+
visibleChips: state.statuslinePicker.visibleChips,
|
|
13695
|
+
hint: state.statuslinePicker.hint
|
|
13696
|
+
}
|
|
13697
|
+
) : null,
|
|
12646
13698
|
state.projectPicker.open ? /* @__PURE__ */ jsx(
|
|
12647
13699
|
ProjectPicker,
|
|
12648
13700
|
{
|
|
@@ -12652,6 +13704,7 @@ User message:
|
|
|
12652
13704
|
hint: state.projectPicker.hint
|
|
12653
13705
|
}
|
|
12654
13706
|
) : null,
|
|
13707
|
+
state.fKeyPicker.open ? /* @__PURE__ */ jsx(FKeyPicker, { selected: state.fKeyPicker.selected }) : null,
|
|
12655
13708
|
state.sessionsPanelOpen ? /* @__PURE__ */ jsx(
|
|
12656
13709
|
SessionsPanel,
|
|
12657
13710
|
{
|
|
@@ -12807,10 +13860,12 @@ User message:
|
|
|
12807
13860
|
subagentCount: Object.keys(state.fleet).length,
|
|
12808
13861
|
processCount: getProcessRegistry().activeCount,
|
|
12809
13862
|
hiddenItems,
|
|
13863
|
+
visibleChips: state.statuslinePicker.visibleChips,
|
|
12810
13864
|
events,
|
|
12811
13865
|
eternalStage: state.eternalStage,
|
|
12812
13866
|
goalSummary: state.goalSummary,
|
|
12813
13867
|
indexState,
|
|
13868
|
+
breakerCountdown,
|
|
12814
13869
|
modeLabel: liveModeLabel || void 0,
|
|
12815
13870
|
debugStreamStats: state.debugStreamStats,
|
|
12816
13871
|
enhanceCountdown,
|
|
@@ -12819,7 +13874,7 @@ User message:
|
|
|
12819
13874
|
autoProceedCountdown: state.countdown?.remainingSeconds ?? null,
|
|
12820
13875
|
sessionCount,
|
|
12821
13876
|
mailbox: mailboxStatus,
|
|
12822
|
-
tokenSavingMode: getSettings ? getSettings().featureTokenSaving : tokenSavingMode,
|
|
13877
|
+
tokenSavingMode: getSettings ? getSettings().featureTokenSaving !== "off" : tokenSavingMode,
|
|
12823
13878
|
toolCount
|
|
12824
13879
|
}
|
|
12825
13880
|
) }),
|
|
@@ -12889,7 +13944,23 @@ User message:
|
|
|
12889
13944
|
Object.keys(state.worktrees).length > 0 && !state.worktreeMonitorOpen && !state.monitorOpen ? /* @__PURE__ */ jsx(WorktreePanel, { worktrees: state.worktrees, nowTick }) : null,
|
|
12890
13945
|
state.queuePanelOpen ? /* @__PURE__ */ jsx(QueuePanel, { items: state.queue }) : null,
|
|
12891
13946
|
state.processListOpen ? /* @__PURE__ */ jsx(ProcessListMonitor, {}) : null,
|
|
12892
|
-
state.
|
|
13947
|
+
state.planPanelOpen ? /* @__PURE__ */ jsx(
|
|
13948
|
+
PlanPanel,
|
|
13949
|
+
{
|
|
13950
|
+
projectRoot,
|
|
13951
|
+
sessionId: agent.ctx.session?.id ?? null,
|
|
13952
|
+
onClose: () => dispatch({ type: "togglePlanPanel" })
|
|
13953
|
+
}
|
|
13954
|
+
) : null,
|
|
13955
|
+
state.goalPanelOpen ? /* @__PURE__ */ jsx(
|
|
13956
|
+
GoalPanel,
|
|
13957
|
+
{
|
|
13958
|
+
goal: state.goalSummary,
|
|
13959
|
+
onCoordinatorStart: onCoordinatorStart ?? void 0,
|
|
13960
|
+
onCoordinatorStop: onCoordinatorStop ?? void 0,
|
|
13961
|
+
coordinatorRunning
|
|
13962
|
+
}
|
|
13963
|
+
) : null,
|
|
12893
13964
|
(() => {
|
|
12894
13965
|
const anyMonitorOpen = state.agentsMonitorOpen || (state.autoPhase?.monitorOpen ?? false) || state.worktreeMonitorOpen || state.todosMonitorOpen || state.monitorOpen || state.processListOpen || state.queuePanelOpen || state.goalPanelOpen;
|
|
12895
13966
|
let nextPanelHint;
|
|
@@ -13072,7 +14143,7 @@ async function runTui(opts) {
|
|
|
13072
14143
|
stdout,
|
|
13073
14144
|
events: opts.events,
|
|
13074
14145
|
model: opts.model,
|
|
13075
|
-
appName: opts.projectRoot ?
|
|
14146
|
+
appName: opts.projectRoot ? path5.basename(opts.projectRoot) : void 0
|
|
13076
14147
|
});
|
|
13077
14148
|
};
|
|
13078
14149
|
const stopTitle = () => {
|
|
@@ -13142,7 +14213,7 @@ async function runTui(opts) {
|
|
|
13142
14213
|
await mailbox.registerClient({
|
|
13143
14214
|
clientId,
|
|
13144
14215
|
sessionId: opts.projectRoot,
|
|
13145
|
-
name: `TUI [${
|
|
14216
|
+
name: `TUI [${path5.basename(opts.projectRoot)}]`,
|
|
13146
14217
|
source: "tui",
|
|
13147
14218
|
pid: process.pid
|
|
13148
14219
|
});
|
|
@@ -13250,6 +14321,7 @@ async function runTui(opts) {
|
|
|
13250
14321
|
enhanceEnabled: opts.enhanceController?.enabled ?? true,
|
|
13251
14322
|
statuslineHiddenItems: opts.statuslineHiddenItems,
|
|
13252
14323
|
setStatuslineHiddenItems: opts.setStatuslineHiddenItems,
|
|
14324
|
+
saveStatuslineHiddenItems: opts.saveStatuslineHiddenItems,
|
|
13253
14325
|
agentsMonitorController: opts.agentsMonitorController,
|
|
13254
14326
|
initialGoal: opts.initialGoal,
|
|
13255
14327
|
initialAsk: opts.initialAsk,
|
|
@@ -13285,7 +14357,10 @@ async function runTui(opts) {
|
|
|
13285
14357
|
getLiveSessions: opts.getLiveSessions,
|
|
13286
14358
|
onSwitchToSession: opts.onSwitchToSession,
|
|
13287
14359
|
initialAgentsMonitorOpen: opts.initialAgentsMonitorOpen,
|
|
13288
|
-
subscribeCoordinatorEvents: opts.subscribeCoordinatorEvents
|
|
14360
|
+
subscribeCoordinatorEvents: opts.subscribeCoordinatorEvents,
|
|
14361
|
+
onPanelOpen: opts.onPanelOpen,
|
|
14362
|
+
onCoordinatorStart: opts.onCoordinatorStart,
|
|
14363
|
+
onCoordinatorStop: opts.onCoordinatorStop
|
|
13289
14364
|
}),
|
|
13290
14365
|
{ exitOnCtrlC: false, stdin: inkStdin }
|
|
13291
14366
|
);
|