@wrongstack/tui 0.155.0 → 0.236.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 +272 -2
- package/dist/index.js +2501 -266
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -1,17 +1,91 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { writeErr, resolveWstackPaths, loadGoal, InputBuilder, DefaultSessionRewinder, writeOut, formatTodosList, buildGoalPreamble, expectDefined as expectDefined$1, wstackGlobalRoot, shouldEnhance, enhanceUserPrompt, recentTextTurns, normalizedEqual, buildChildEnv } from '@wrongstack/core';
|
|
2
2
|
export { buildGoalPreamble } from '@wrongstack/core';
|
|
3
|
-
import { Box
|
|
4
|
-
import * as
|
|
5
|
-
import React5, { useState, useEffect, useMemo, memo, useRef, useCallback, useReducer } from 'react';
|
|
3
|
+
import { Box as Box$1, useInput, useStdin, useStdout, Text as Text$1, render, useApp, measureElement, Static } from 'ink';
|
|
4
|
+
import * as path4 from 'path';
|
|
5
|
+
import React5, { forwardRef, useState, useEffect, useMemo, memo, useRef, useCallback, useReducer, useLayoutEffect } from 'react';
|
|
6
6
|
import * as fs2 from 'fs/promises';
|
|
7
7
|
import { routeImagesForModel } from '@wrongstack/runtime/vision';
|
|
8
8
|
import { getIndexState, onIndexStateChange, getProcessRegistry } from '@wrongstack/tools';
|
|
9
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
9
10
|
import { readClipboardImage } from '@wrongstack/runtime/clipboard';
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
11
|
+
import { expectDefined } from '@wrongstack/core/utils';
|
|
12
|
+
import * as v8 from 'v8';
|
|
12
13
|
import { spawn } from 'child_process';
|
|
13
14
|
|
|
14
15
|
// src/run-tui.ts
|
|
16
|
+
|
|
17
|
+
// src/theme.ts
|
|
18
|
+
var pastel = Object.freeze({
|
|
19
|
+
// Base 8
|
|
20
|
+
black: "#11111b",
|
|
21
|
+
red: "#f38ba8",
|
|
22
|
+
green: "#a6e3a1",
|
|
23
|
+
yellow: "#f9e2af",
|
|
24
|
+
blue: "#89b4fa",
|
|
25
|
+
magenta: "#cba6f7",
|
|
26
|
+
cyan: "#94e2d5",
|
|
27
|
+
white: "#cdd6f4",
|
|
28
|
+
// Greys
|
|
29
|
+
gray: "#7f849c",
|
|
30
|
+
grey: "#7f849c",
|
|
31
|
+
// Bright variants — a touch lighter / shifted within the same family
|
|
32
|
+
blackBright: "#585b70",
|
|
33
|
+
redBright: "#eba0ac",
|
|
34
|
+
greenBright: "#b8e8b0",
|
|
35
|
+
yellowBright: "#f5e6b8",
|
|
36
|
+
blueBright: "#89dceb",
|
|
37
|
+
magentaBright: "#b4befe",
|
|
38
|
+
cyanBright: "#99e6da",
|
|
39
|
+
whiteBright: "#ffffff"
|
|
40
|
+
});
|
|
41
|
+
function softColor(color) {
|
|
42
|
+
if (!color) return color;
|
|
43
|
+
return pastel[color] ?? color;
|
|
44
|
+
}
|
|
45
|
+
var theme = Object.freeze({
|
|
46
|
+
accent: pastel.cyan,
|
|
47
|
+
user: pastel.yellow,
|
|
48
|
+
assistant: pastel.cyan,
|
|
49
|
+
tool: pastel.cyan,
|
|
50
|
+
success: pastel.green,
|
|
51
|
+
warn: pastel.yellow,
|
|
52
|
+
error: pastel.red,
|
|
53
|
+
dim: true,
|
|
54
|
+
// Subtle slate border — present but never harsh.
|
|
55
|
+
borderDefault: pastel.blackBright,
|
|
56
|
+
borderActive: pastel.yellow,
|
|
57
|
+
brand: pastel.magenta,
|
|
58
|
+
monitor: {
|
|
59
|
+
fleet: pastel.cyan,
|
|
60
|
+
agents: pastel.magenta,
|
|
61
|
+
worktree: pastel.green,
|
|
62
|
+
phase: pastel.cyan
|
|
63
|
+
},
|
|
64
|
+
// Diff blocks render dark text on a pastel wash (see DiffBlock).
|
|
65
|
+
diffAddBg: pastel.green,
|
|
66
|
+
diffDelBg: pastel.red
|
|
67
|
+
});
|
|
68
|
+
var colorProps = (color, backgroundColor) => {
|
|
69
|
+
const c = softColor(color);
|
|
70
|
+
const bg = softColor(backgroundColor);
|
|
71
|
+
return { ...c ? { color: c } : {}, ...bg ? { backgroundColor: bg } : {} };
|
|
72
|
+
};
|
|
73
|
+
function Text({ color, backgroundColor, ...rest }) {
|
|
74
|
+
return /* @__PURE__ */ jsx(Text$1, { ...rest, ...colorProps(color, backgroundColor) });
|
|
75
|
+
}
|
|
76
|
+
var Box = forwardRef(function Box2({ borderColor, backgroundColor, ...rest }, ref) {
|
|
77
|
+
const bc = softColor(borderColor);
|
|
78
|
+
const bg = softColor(backgroundColor);
|
|
79
|
+
return /* @__PURE__ */ jsx(
|
|
80
|
+
Box$1,
|
|
81
|
+
{
|
|
82
|
+
ref,
|
|
83
|
+
...rest,
|
|
84
|
+
...bc ? { borderColor: bc } : {},
|
|
85
|
+
...bg ? { backgroundColor: bg } : {}
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
});
|
|
15
89
|
var MODE_ICONS = {
|
|
16
90
|
teach: "\u{1F9D1}\u200D\u{1F3EB}",
|
|
17
91
|
brief: "\u26A1",
|
|
@@ -46,12 +120,14 @@ function StatusBar({
|
|
|
46
120
|
startedAt,
|
|
47
121
|
todos,
|
|
48
122
|
plan,
|
|
123
|
+
tasks,
|
|
49
124
|
fleet,
|
|
50
125
|
fleetAgents,
|
|
51
126
|
git,
|
|
52
127
|
subagentCount = 0,
|
|
53
128
|
brain,
|
|
54
129
|
projectName,
|
|
130
|
+
workingDir,
|
|
55
131
|
processCount,
|
|
56
132
|
context,
|
|
57
133
|
hiddenItems,
|
|
@@ -61,7 +137,10 @@ function StatusBar({
|
|
|
61
137
|
modeLabel,
|
|
62
138
|
debugStreamStats,
|
|
63
139
|
enhanceCountdown,
|
|
64
|
-
|
|
140
|
+
nextStepsAutoSubmitCountdown,
|
|
141
|
+
autoProceedCountdown,
|
|
142
|
+
sessionCount,
|
|
143
|
+
mailbox
|
|
65
144
|
}) {
|
|
66
145
|
const { stdout } = useStdout();
|
|
67
146
|
const [termWidth, setTermWidth] = useState(stdout?.columns ?? 90);
|
|
@@ -94,17 +173,19 @@ function StatusBar({
|
|
|
94
173
|
);
|
|
95
174
|
return () => clearInterval(t);
|
|
96
175
|
}, [state]);
|
|
97
|
-
const spinner = expectDefined(SPINNER_FRAMES[spinnerIdx]);
|
|
176
|
+
const spinner = expectDefined$1(SPINNER_FRAMES[spinnerIdx]);
|
|
98
177
|
const { label: stateLabel, color: stateColor } = stateChip(state, fleet?.running ?? 0);
|
|
99
178
|
const statePrefix = state === "idle" || state === "aborting" ? "\u25CF" : spinner;
|
|
100
179
|
const thinking = state === "running" || state === "streaming";
|
|
101
180
|
const hasAutoProceed = autoProceedCountdown != null && autoProceedCountdown > 0;
|
|
102
|
-
const hasSecondLine = yolo || autonomy && autonomy !== "off" || startedAt != null || git !== null && git !== void 0 || projectName !== void 0 && projectName.length > 0 || goalSummary !== null && goalSummary !== void 0 || !!modeLabel || hasAutoProceed;
|
|
181
|
+
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;
|
|
103
182
|
const fleetHasActivity = fleet && (fleet.running > 0 || fleet.idle > 0 || fleet.pending > 0 || fleet.completed > 0) || subagentCount > 0;
|
|
104
183
|
const hasBrainActivity = !!brain && brain.state !== "idle";
|
|
105
184
|
const hasDebugStream = !!debugStreamStats;
|
|
106
185
|
const hasEnhanceCountdown = enhanceCountdown != null && enhanceCountdown > 0;
|
|
107
|
-
const
|
|
186
|
+
const hasNextStepsAutoSubmit = nextStepsAutoSubmitCountdown != null && nextStepsAutoSubmitCountdown > 0;
|
|
187
|
+
const hasTaskActivity = tasks && (tasks.pending > 0 || tasks.inProgress > 0 || tasks.completed > 0 || tasks.blocked > 0 || tasks.failed > 0);
|
|
188
|
+
const hasThirdLine = todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || hasTaskActivity || fleetHasActivity || hasBrainActivity || hasDebugStream || hasEnhanceCountdown || hasNextStepsAutoSubmit;
|
|
108
189
|
return /* @__PURE__ */ jsxs(
|
|
109
190
|
Box,
|
|
110
191
|
{
|
|
@@ -148,13 +229,17 @@ function StatusBar({
|
|
|
148
229
|
/* @__PURE__ */ jsx(Text, { color: "magenta", children: model }),
|
|
149
230
|
context && !hiddenSet.has("context") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
150
231
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
232
|
+
(() => {
|
|
233
|
+
const ratio = context.used / context.max;
|
|
234
|
+
const clampedRatio = Math.min(ratio, 1);
|
|
235
|
+
const pctText = `${Math.min(Math.round(ratio * 100), 100)}%`;
|
|
236
|
+
return /* @__PURE__ */ jsxs(Text, { color: clampedRatio < 0.6 ? "green" : clampedRatio < 0.75 ? "yellow" : "red", children: [
|
|
237
|
+
"ctx ",
|
|
238
|
+
renderMeter(clampedRatio, 8),
|
|
239
|
+
" ",
|
|
240
|
+
pctText
|
|
241
|
+
] });
|
|
242
|
+
})()
|
|
158
243
|
] }) : null,
|
|
159
244
|
usage && isComfortable ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
160
245
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
@@ -247,8 +332,15 @@ function StatusBar({
|
|
|
247
332
|
projectName
|
|
248
333
|
] })
|
|
249
334
|
] }) : null,
|
|
335
|
+
workingDir && !hiddenSet.has("working_dir") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
336
|
+
yolo || startedAt != null || projectName || goalSummary ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
337
|
+
/* @__PURE__ */ jsxs(Text, { color: "blue", children: [
|
|
338
|
+
"\u{1F4C2} ",
|
|
339
|
+
workingDir
|
|
340
|
+
] })
|
|
341
|
+
] }) : null,
|
|
250
342
|
goalSummary ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
251
|
-
yolo || startedAt != null || projectName ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
343
|
+
yolo || startedAt != null || projectName || workingDir ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
252
344
|
/* @__PURE__ */ jsxs(
|
|
253
345
|
Text,
|
|
254
346
|
{
|
|
@@ -268,11 +360,11 @@ function StatusBar({
|
|
|
268
360
|
)
|
|
269
361
|
] }) : null,
|
|
270
362
|
modeLabel ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
271
|
-
yolo || autonomy && autonomy !== "off" || eternalStage || startedAt != null || projectName || goalSummary ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
363
|
+
yolo || autonomy && autonomy !== "off" || eternalStage || startedAt != null || projectName || workingDir || goalSummary ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
272
364
|
/* @__PURE__ */ jsx(Text, { color: "cyan", children: modeIcon(modeLabel) })
|
|
273
365
|
] }) : null,
|
|
274
366
|
hasAutoProceed ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
275
|
-
yolo || autonomy && autonomy !== "off" || eternalStage || startedAt != null || projectName || goalSummary || modeLabel ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
367
|
+
yolo || autonomy && autonomy !== "off" || eternalStage || startedAt != null || projectName || workingDir || goalSummary || modeLabel ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
276
368
|
/* @__PURE__ */ jsxs(Text, { color: autoProceedCountdown != null && autoProceedCountdown <= 5 ? "yellow" : "cyan", children: [
|
|
277
369
|
"\u23F3 auto in ",
|
|
278
370
|
autoProceedCountdown,
|
|
@@ -280,16 +372,12 @@ function StatusBar({
|
|
|
280
372
|
] })
|
|
281
373
|
] }) : null,
|
|
282
374
|
git ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
283
|
-
yolo || startedAt != null || projectName ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
375
|
+
yolo || startedAt != null || projectName || workingDir ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
284
376
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
285
377
|
/* @__PURE__ */ jsxs(Text, { color: "magenta", children: [
|
|
286
378
|
"\u2387 ",
|
|
287
379
|
git.branch
|
|
288
380
|
] }),
|
|
289
|
-
git.added > 0 ? /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
290
|
-
" +",
|
|
291
|
-
git.added
|
|
292
|
-
] }) : null,
|
|
293
381
|
git.deleted > 0 ? /* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
294
382
|
" -",
|
|
295
383
|
git.deleted
|
|
@@ -299,6 +387,15 @@ function StatusBar({
|
|
|
299
387
|
git.untracked
|
|
300
388
|
] }) : null
|
|
301
389
|
] })
|
|
390
|
+
] }) : null,
|
|
391
|
+
sessionCount != null && sessionCount > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
392
|
+
yolo || startedAt != null || projectName || workingDir || git ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
393
|
+
/* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
394
|
+
"\u29C9 ",
|
|
395
|
+
sessionCount,
|
|
396
|
+
" session",
|
|
397
|
+
sessionCount === 1 ? "" : "s"
|
|
398
|
+
] })
|
|
302
399
|
] }) : null
|
|
303
400
|
] }) : /* @__PURE__ */ jsx(Box, { height: 1, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
|
|
304
401
|
hasThirdLine ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
@@ -339,6 +436,36 @@ function StatusBar({
|
|
|
339
436
|
] }) : null
|
|
340
437
|
] })
|
|
341
438
|
] }) : null,
|
|
439
|
+
hasTaskActivity ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
440
|
+
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,
|
|
441
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
442
|
+
/* @__PURE__ */ jsx(Text, { color: "magenta", children: "\u26A1 " }),
|
|
443
|
+
tasks.inProgress > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
444
|
+
"\u231B",
|
|
445
|
+
tasks.inProgress
|
|
446
|
+
] }) : null,
|
|
447
|
+
tasks.inProgress > 0 && (tasks.pending > 0 || tasks.blocked > 0) ? " " : "",
|
|
448
|
+
tasks.pending > 0 ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
449
|
+
"\u2610",
|
|
450
|
+
tasks.pending
|
|
451
|
+
] }) : null,
|
|
452
|
+
tasks.pending > 0 && tasks.blocked > 0 ? " " : "",
|
|
453
|
+
tasks.blocked > 0 ? /* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
454
|
+
"\u2298",
|
|
455
|
+
tasks.blocked
|
|
456
|
+
] }) : null,
|
|
457
|
+
(tasks.pending > 0 || tasks.blocked > 0) && (tasks.completed > 0 || tasks.failed > 0) ? " " : "",
|
|
458
|
+
tasks.completed > 0 ? /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
459
|
+
"\u2713",
|
|
460
|
+
tasks.completed
|
|
461
|
+
] }) : null,
|
|
462
|
+
tasks.completed > 0 && tasks.failed > 0 ? " " : "",
|
|
463
|
+
tasks.failed > 0 ? /* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
464
|
+
"\u2717",
|
|
465
|
+
tasks.failed
|
|
466
|
+
] }) : null
|
|
467
|
+
] })
|
|
468
|
+
] }) : null,
|
|
342
469
|
fleetHasActivity ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
343
470
|
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,
|
|
344
471
|
fleet ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
@@ -405,9 +532,64 @@ function StatusBar({
|
|
|
405
532
|
enhanceCountdown,
|
|
406
533
|
"s"
|
|
407
534
|
] })
|
|
535
|
+
] }) : null,
|
|
536
|
+
hasNextStepsAutoSubmit && nextStepsAutoSubmitCountdown != null ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
537
|
+
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || fleetHasActivity || hasBrainActivity || hasDebugStream || hasEnhanceCountdown ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
538
|
+
/* @__PURE__ */ jsxs(Text, { color: nextStepsAutoSubmitCountdown <= 3 ? "yellow" : "cyan", children: [
|
|
539
|
+
"\u23F3 next step in ",
|
|
540
|
+
nextStepsAutoSubmitCountdown,
|
|
541
|
+
"s"
|
|
542
|
+
] })
|
|
408
543
|
] }) : null
|
|
409
544
|
] }) : /* @__PURE__ */ jsx(Box, { height: 1, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
|
|
410
|
-
|
|
545
|
+
mailbox ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
546
|
+
mailbox.unread > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", bold: true, children: [
|
|
547
|
+
"\u2709 ",
|
|
548
|
+
mailbox.unread,
|
|
549
|
+
" new"
|
|
550
|
+
] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2709 0" }),
|
|
551
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
552
|
+
/* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
553
|
+
"\u{1F465} ",
|
|
554
|
+
mailbox.onlineAgents,
|
|
555
|
+
" online"
|
|
556
|
+
] }),
|
|
557
|
+
mailbox.lastSubject ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
558
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
559
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
560
|
+
mailbox.lastFrom ? `${mailbox.lastFrom}: ` : "",
|
|
561
|
+
mailbox.lastSubject.length > 40 ? `${mailbox.lastSubject.slice(0, 37)}\u2026` : mailbox.lastSubject
|
|
562
|
+
] })
|
|
563
|
+
] }) : null,
|
|
564
|
+
fleetAgents && fleetAgents.length > 0 ? fleetAgents.map((a, i) => (
|
|
565
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: agent list is stable per render
|
|
566
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
567
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
568
|
+
" ",
|
|
569
|
+
/* @__PURE__ */ jsx(Text, { color: a.color, bold: true, children: a.label }),
|
|
570
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }),
|
|
571
|
+
/* @__PURE__ */ jsx(Text, { dimColor: !a.running, ...a.running ? { color: "yellow" } : {}, children: a.running ? "\u25B6" : "\xB7" }),
|
|
572
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }),
|
|
573
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: fmtElapsed(a.elapsedMs) }),
|
|
574
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \xB7 " }),
|
|
575
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
576
|
+
a.toolCalls,
|
|
577
|
+
"t"
|
|
578
|
+
] }),
|
|
579
|
+
a.tool ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
580
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \xB7 " }),
|
|
581
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: a.tool })
|
|
582
|
+
] }) : null,
|
|
583
|
+
a.extensions && a.extensions > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
584
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \xB7 " }),
|
|
585
|
+
/* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
586
|
+
"\u26A1\xD7",
|
|
587
|
+
a.extensions
|
|
588
|
+
] })
|
|
589
|
+
] }) : null
|
|
590
|
+
] }, i)
|
|
591
|
+
)) : null
|
|
592
|
+
] }) : fleetAgents && fleetAgents.length > 0 ? /* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 2, children: fleetAgents.map((a, i) => (
|
|
411
593
|
// biome-ignore lint/suspicious/noArrayIndexKey: agent list is stable per render
|
|
412
594
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
413
595
|
/* @__PURE__ */ jsx(Text, { color: a.color, bold: true, children: a.label }),
|
|
@@ -513,6 +695,32 @@ function EternalStageChip({
|
|
|
513
695
|
] });
|
|
514
696
|
}
|
|
515
697
|
}
|
|
698
|
+
var SB_GAP = 2;
|
|
699
|
+
var SB_PADX = 1;
|
|
700
|
+
function statusBarModelSpan(opts) {
|
|
701
|
+
let col = SB_PADX;
|
|
702
|
+
if (opts.version) {
|
|
703
|
+
col += `WS v${opts.version}`.length + SB_GAP;
|
|
704
|
+
col += 1 + SB_GAP;
|
|
705
|
+
}
|
|
706
|
+
const { label } = stateChip(opts.state, opts.fleetRunning ?? 0);
|
|
707
|
+
col += 2 + label.length + SB_GAP;
|
|
708
|
+
col += 1 + SB_GAP;
|
|
709
|
+
return { start: col, len: opts.model.length };
|
|
710
|
+
}
|
|
711
|
+
function statusBarAutonomySpan(opts) {
|
|
712
|
+
if (!opts.autonomy || opts.autonomy === "off") return null;
|
|
713
|
+
let col = SB_PADX;
|
|
714
|
+
if (opts.yolo) {
|
|
715
|
+
col += "\u26A0 YOLO".length + SB_GAP;
|
|
716
|
+
col += 1 + SB_GAP;
|
|
717
|
+
}
|
|
718
|
+
return { start: col, len: 2 + opts.autonomy.toUpperCase().length };
|
|
719
|
+
}
|
|
720
|
+
function statusBarTodosSpan() {
|
|
721
|
+
const LABEL_MAX = 20;
|
|
722
|
+
return { start: SB_PADX, len: LABEL_MAX };
|
|
723
|
+
}
|
|
516
724
|
function stateChip(state, fleetRunning) {
|
|
517
725
|
if (state === "idle" && fleetRunning > 0) {
|
|
518
726
|
return { label: `agents \u25B6${fleetRunning}`, color: "magenta" };
|
|
@@ -522,18 +730,30 @@ function stateChip(state, fleetRunning) {
|
|
|
522
730
|
return { label: "thinking\u2026", color: "green" };
|
|
523
731
|
}
|
|
524
732
|
var WAVE_COLORS = [
|
|
525
|
-
"#
|
|
526
|
-
|
|
527
|
-
"#
|
|
528
|
-
|
|
529
|
-
"#
|
|
530
|
-
|
|
531
|
-
"#
|
|
532
|
-
|
|
533
|
-
"#
|
|
534
|
-
|
|
535
|
-
"#
|
|
536
|
-
|
|
733
|
+
"#f38ba8",
|
|
734
|
+
// red
|
|
735
|
+
"#eba0ac",
|
|
736
|
+
// maroon
|
|
737
|
+
"#fab387",
|
|
738
|
+
// peach
|
|
739
|
+
"#f9e2af",
|
|
740
|
+
// yellow
|
|
741
|
+
"#a6e3a1",
|
|
742
|
+
// green
|
|
743
|
+
"#94e2d5",
|
|
744
|
+
// teal
|
|
745
|
+
"#89dceb",
|
|
746
|
+
// sky
|
|
747
|
+
"#89b4fa",
|
|
748
|
+
// blue
|
|
749
|
+
"#b4befe",
|
|
750
|
+
// lavender
|
|
751
|
+
"#cba6f7",
|
|
752
|
+
// mauve
|
|
753
|
+
"#f5c2e7",
|
|
754
|
+
// pink
|
|
755
|
+
"#f2cdcd"
|
|
756
|
+
// flamingo
|
|
537
757
|
];
|
|
538
758
|
function WaveText({ text, phase }) {
|
|
539
759
|
return /* @__PURE__ */ jsx(Text, { bold: true, children: Array.from(text).map((ch, i) => (
|
|
@@ -854,12 +1074,12 @@ function ContextBar({
|
|
|
854
1074
|
tokens,
|
|
855
1075
|
maxTokens
|
|
856
1076
|
}) {
|
|
857
|
-
const clamped = Math.max(0, Math.min(
|
|
1077
|
+
const clamped = Math.max(0, Math.min(1, pct));
|
|
858
1078
|
const totalBars = 10;
|
|
859
1079
|
const filled = Math.round(clamped * totalBars);
|
|
860
1080
|
const empty = totalBars - filled;
|
|
861
|
-
const color =
|
|
862
|
-
const pctText =
|
|
1081
|
+
const color = clamped < 0.6 ? "green" : clamped < 0.75 ? "yellow" : "red";
|
|
1082
|
+
const pctText = `${Math.min(Math.round(pct * 100), 100)}%`;
|
|
863
1083
|
const tokenText = tokens ? ` ${fmtTokens2(tokens)}/${fmtTokens2(maxTokens ?? 2e5)}` : "";
|
|
864
1084
|
return /* @__PURE__ */ jsxs(Text, { color, children: [
|
|
865
1085
|
"\u2588".repeat(filled),
|
|
@@ -1467,8 +1687,8 @@ function FilePicker({ query, matches, selected }) {
|
|
|
1467
1687
|
] }, m))
|
|
1468
1688
|
] });
|
|
1469
1689
|
}
|
|
1470
|
-
function highlight(
|
|
1471
|
-
return
|
|
1690
|
+
function highlight(path6, _query) {
|
|
1691
|
+
return path6;
|
|
1472
1692
|
}
|
|
1473
1693
|
function FleetPanel({
|
|
1474
1694
|
entries,
|
|
@@ -1535,29 +1755,103 @@ function FleetPanel({
|
|
|
1535
1755
|
] }) : null
|
|
1536
1756
|
] });
|
|
1537
1757
|
}
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
},
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
}
|
|
1758
|
+
function fmtTime(iso) {
|
|
1759
|
+
const d = new Date(iso);
|
|
1760
|
+
const now = Date.now();
|
|
1761
|
+
const diff = now - d.getTime();
|
|
1762
|
+
if (diff < 6e4) return "just now";
|
|
1763
|
+
if (diff < 36e5) return `${Math.round(diff / 6e4)}m ago`;
|
|
1764
|
+
if (diff < 864e5) return `${Math.round(diff / 36e5)}h ago`;
|
|
1765
|
+
return d.toLocaleDateString();
|
|
1766
|
+
}
|
|
1767
|
+
function fmtBody(body, maxLen) {
|
|
1768
|
+
const oneLine2 = body.replace(/\n/g, " ");
|
|
1769
|
+
return oneLine2.length > maxLen ? `${oneLine2.slice(0, maxLen - 1)}\u2026` : oneLine2;
|
|
1770
|
+
}
|
|
1771
|
+
var TYPE_ICONS = {
|
|
1772
|
+
note: "\u{1F4DD}",
|
|
1773
|
+
ask: "\u2753",
|
|
1774
|
+
assign: "\u{1F4CB}",
|
|
1775
|
+
steer: "\u{1F504}",
|
|
1776
|
+
btw: "\u{1F4AC}",
|
|
1777
|
+
broadcast: "\u{1F4E2}",
|
|
1778
|
+
status: "\u{1F7E2}",
|
|
1779
|
+
result: "\u2705"
|
|
1780
|
+
};
|
|
1781
|
+
function MailboxPanel({
|
|
1782
|
+
messages,
|
|
1783
|
+
agents,
|
|
1784
|
+
unreadCount,
|
|
1785
|
+
open
|
|
1786
|
+
}) {
|
|
1787
|
+
const { stdout } = useStdout();
|
|
1788
|
+
const [termWidth, setTermWidth] = useState(stdout?.columns ?? 90);
|
|
1789
|
+
useEffect(() => {
|
|
1790
|
+
const handleResize = () => setTermWidth(stdout?.columns ?? 90);
|
|
1791
|
+
handleResize();
|
|
1792
|
+
process.stdout.on("resize", handleResize);
|
|
1793
|
+
return () => {
|
|
1794
|
+
process.stdout.off("resize", handleResize);
|
|
1795
|
+
};
|
|
1796
|
+
}, [stdout]);
|
|
1797
|
+
if (!open) return null;
|
|
1798
|
+
const showMessages = messages.slice(0, 6);
|
|
1799
|
+
const showAgents = agents.slice(0, 8);
|
|
1800
|
+
const maxSubjectLen = Math.max(15, Math.min(30, termWidth - 55));
|
|
1801
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginY: 1, flexShrink: 0, children: [
|
|
1802
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
1803
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u{1F4EC} Mailbox" }),
|
|
1804
|
+
unreadCount > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", bold: true, children: [
|
|
1805
|
+
unreadCount,
|
|
1806
|
+
" unread"
|
|
1807
|
+
] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "0 unread" }),
|
|
1808
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
1809
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1810
|
+
agents.length,
|
|
1811
|
+
" agent",
|
|
1812
|
+
agents.length === 1 ? "" : "s",
|
|
1813
|
+
" online"
|
|
1814
|
+
] })
|
|
1815
|
+
] }),
|
|
1816
|
+
showMessages.length > 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
1817
|
+
/* @__PURE__ */ jsx(Text, { bold: true, dimColor: true, children: "Messages" }),
|
|
1818
|
+
showMessages.map((m) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
1819
|
+
/* @__PURE__ */ jsx(Text, { children: TYPE_ICONS[m.type] ?? "\u{1F4E8}" }),
|
|
1820
|
+
/* @__PURE__ */ jsx(Text, { color: m.readByMe ? void 0 : "yellow", bold: !m.readByMe, children: m.from }),
|
|
1821
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: m.subject.length > maxSubjectLen ? `${m.subject.slice(0, maxSubjectLen - 1)}\u2026` : m.subject }),
|
|
1822
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: fmtBody(m.body, 40) }),
|
|
1823
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: fmtTime(m.timestamp) }),
|
|
1824
|
+
m.readByCount > 0 ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1825
|
+
"\u{1F441} ",
|
|
1826
|
+
m.readByCount
|
|
1827
|
+
] }) : /* @__PURE__ */ jsx(Text, { color: "yellow", bold: true, children: "\u2709 new" }),
|
|
1828
|
+
m.completed ? /* @__PURE__ */ jsx(Text, { color: "green", children: "\u2713" }) : null
|
|
1829
|
+
] }, m.id))
|
|
1830
|
+
] }) : /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No messages yet." }) }),
|
|
1831
|
+
showAgents.length > 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
1832
|
+
/* @__PURE__ */ jsx(Text, { bold: true, dimColor: true, children: "Online agents" }),
|
|
1833
|
+
showAgents.map((a) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
1834
|
+
/* @__PURE__ */ jsx(Text, { color: a.online ? "green" : "dim", children: a.online ? "\u25CF" : "\u25CB" }),
|
|
1835
|
+
/* @__PURE__ */ jsx(Text, { children: a.name }),
|
|
1836
|
+
a.role ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1837
|
+
"(",
|
|
1838
|
+
a.role,
|
|
1839
|
+
")"
|
|
1840
|
+
] }) : null,
|
|
1841
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: a.status }),
|
|
1842
|
+
a.currentTool ? /* @__PURE__ */ jsx(Text, { color: "cyan", children: a.currentTool }) : null,
|
|
1843
|
+
a.currentTask ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: a.currentTask.length > 25 ? `${a.currentTask.slice(0, 24)}\u2026` : a.currentTask }) : null,
|
|
1844
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: fmtTime(a.lastSeenAt) }),
|
|
1845
|
+
a.source ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1846
|
+
"[",
|
|
1847
|
+
a.source,
|
|
1848
|
+
"]"
|
|
1849
|
+
] }) : null
|
|
1850
|
+
] }, a.agentId))
|
|
1851
|
+
] }) : null,
|
|
1852
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "/mailbox \u2014 Esc to close" }) })
|
|
1853
|
+
] });
|
|
1854
|
+
}
|
|
1561
1855
|
function helpSections() {
|
|
1562
1856
|
const nav = [];
|
|
1563
1857
|
nav.push(
|
|
@@ -1569,12 +1863,16 @@ function helpSections() {
|
|
|
1569
1863
|
{
|
|
1570
1864
|
title: "Monitors",
|
|
1571
1865
|
entries: [
|
|
1866
|
+
{ keys: "F1", desc: "project switcher (also /project)" },
|
|
1572
1867
|
{ keys: "Ctrl+F / F2", desc: "fleet orchestration monitor" },
|
|
1573
1868
|
{ keys: "Ctrl+G / F3", desc: "agents live monitor" },
|
|
1574
1869
|
{ keys: "Ctrl+T / F4", desc: "worktree monitor" },
|
|
1575
1870
|
{ keys: "F5", desc: "autonomy settings (also Ctrl+S)" },
|
|
1576
1871
|
{ keys: "F6", desc: "todos monitor overlay" },
|
|
1577
1872
|
{ keys: "F7", desc: "queue panel" },
|
|
1873
|
+
{ keys: "F8", desc: "process list overlay" },
|
|
1874
|
+
{ keys: "F9", desc: "goal panel" },
|
|
1875
|
+
{ keys: "F10", desc: "live sessions panel" },
|
|
1578
1876
|
{ keys: "Esc", desc: "close the open monitor / overlay" }
|
|
1579
1877
|
]
|
|
1580
1878
|
},
|
|
@@ -1591,6 +1889,7 @@ function helpSections() {
|
|
|
1591
1889
|
{
|
|
1592
1890
|
title: "Commands",
|
|
1593
1891
|
entries: [
|
|
1892
|
+
{ keys: "/project", desc: "switch projects (also F1)" },
|
|
1594
1893
|
{ keys: "/help", desc: "list all slash commands" },
|
|
1595
1894
|
{ keys: "/model", desc: "switch the active model" },
|
|
1596
1895
|
{ keys: "/fleet", desc: "multi-agent fleet controls" },
|
|
@@ -2148,14 +2447,14 @@ function computeWidths(allRows, cols, maxWidth, sepWidths) {
|
|
|
2148
2447
|
const cell = row[c] ?? "";
|
|
2149
2448
|
const stripped = stripInlineMarkers(cell);
|
|
2150
2449
|
const total = strWidth(stripped);
|
|
2151
|
-
natural[c] = Math.max(expectDefined
|
|
2450
|
+
natural[c] = Math.max(expectDefined(natural[c]), total);
|
|
2152
2451
|
}
|
|
2153
2452
|
}
|
|
2154
2453
|
if (sepWidths) {
|
|
2155
2454
|
for (let c = 0; c < cols && c < sepWidths.length; c++) {
|
|
2156
2455
|
const sepW = sepWidths[c];
|
|
2157
2456
|
if (sepW != null) {
|
|
2158
|
-
natural[c] = Math.max(expectDefined
|
|
2457
|
+
natural[c] = Math.max(expectDefined(natural[c]), sepW);
|
|
2159
2458
|
}
|
|
2160
2459
|
}
|
|
2161
2460
|
}
|
|
@@ -2167,7 +2466,7 @@ function computeWidths(allRows, cols, maxWidth, sepWidths) {
|
|
|
2167
2466
|
let maxIdx = -1;
|
|
2168
2467
|
let maxVal = MIN_COL_WIDTH;
|
|
2169
2468
|
for (let i = 0; i < cols; i++) {
|
|
2170
|
-
const w = expectDefined
|
|
2469
|
+
const w = expectDefined(widths[i]);
|
|
2171
2470
|
if (w > maxVal) {
|
|
2172
2471
|
maxVal = w;
|
|
2173
2472
|
maxIdx = i;
|
|
@@ -2227,7 +2526,7 @@ function strWidth(s2) {
|
|
|
2227
2526
|
if (i < len) i++;
|
|
2228
2527
|
continue;
|
|
2229
2528
|
}
|
|
2230
|
-
const code = expectDefined
|
|
2529
|
+
const code = expectDefined(s2.codePointAt(i));
|
|
2231
2530
|
const cpLen = code > 65535 ? 2 : 1;
|
|
2232
2531
|
if (code === 8205 || // ZWJ — Zero Width Joiner (emoji sequences)
|
|
2233
2532
|
code === 8203 || // ZWSP — Zero Width Space
|
|
@@ -2299,7 +2598,7 @@ function stripInlineMarkers(text) {
|
|
|
2299
2598
|
}
|
|
2300
2599
|
var ANSI_BOLD = "\x1B[1m";
|
|
2301
2600
|
var ANSI_DIM = "\x1B[2m";
|
|
2302
|
-
var ANSI_CYAN = "\x1B[
|
|
2601
|
+
var ANSI_CYAN = "\x1B[38;2;148;226;213m";
|
|
2303
2602
|
var ANSI_STRIKE = "\x1B[9m";
|
|
2304
2603
|
var ANSI_RESET_ALL = "\x1B[0m";
|
|
2305
2604
|
function applyInlineAnsi(text) {
|
|
@@ -2404,7 +2703,11 @@ function padCell(text, width, align) {
|
|
|
2404
2703
|
}
|
|
2405
2704
|
return displayText + " ".repeat(pad);
|
|
2406
2705
|
}
|
|
2706
|
+
var _parseCache = /* @__PURE__ */ new Map();
|
|
2707
|
+
var _PARSE_CACHE_MAX = 5e3;
|
|
2407
2708
|
function parseInline(text) {
|
|
2709
|
+
const cached = _parseCache.get(text);
|
|
2710
|
+
if (cached) return cached;
|
|
2408
2711
|
const tokens = [];
|
|
2409
2712
|
let plain = "";
|
|
2410
2713
|
let i = 0;
|
|
@@ -2457,6 +2760,15 @@ function parseInline(text) {
|
|
|
2457
2760
|
i += 1;
|
|
2458
2761
|
}
|
|
2459
2762
|
flush();
|
|
2763
|
+
if (_parseCache.size >= _PARSE_CACHE_MAX) {
|
|
2764
|
+
let dropped = 0;
|
|
2765
|
+
const target = Math.floor(_PARSE_CACHE_MAX / 4);
|
|
2766
|
+
for (const key of _parseCache.keys()) {
|
|
2767
|
+
_parseCache.delete(key);
|
|
2768
|
+
if (++dropped >= target) break;
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
_parseCache.set(text, tokens);
|
|
2460
2772
|
return tokens;
|
|
2461
2773
|
}
|
|
2462
2774
|
function InlineLine({ tokens, dim }) {
|
|
@@ -3123,7 +3435,7 @@ function streamBoxRows(text, maxLines, contentWidth) {
|
|
|
3123
3435
|
}
|
|
3124
3436
|
return rows;
|
|
3125
3437
|
}
|
|
3126
|
-
React5.memo(function ToolStreamBox2({
|
|
3438
|
+
var ToolStreamBox = React5.memo(function ToolStreamBox2({
|
|
3127
3439
|
name,
|
|
3128
3440
|
text,
|
|
3129
3441
|
startedAt,
|
|
@@ -3408,7 +3720,7 @@ function Banner({
|
|
|
3408
3720
|
entry
|
|
3409
3721
|
}) {
|
|
3410
3722
|
const cwdShort = shortenPath(entry.cwd, 48);
|
|
3411
|
-
const projectLabel =
|
|
3723
|
+
const projectLabel = path4.basename(entry.cwd);
|
|
3412
3724
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 2, paddingY: 0, children: [
|
|
3413
3725
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
3414
3726
|
/* @__PURE__ */ jsx(Text, { color: "magenta", bold: true, children: " \u259F\u259B " }),
|
|
@@ -3440,7 +3752,7 @@ function Banner({
|
|
|
3440
3752
|
] }),
|
|
3441
3753
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
3442
3754
|
/* @__PURE__ */ jsx(Text, { color: "cyan", children: " hints " }),
|
|
3443
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "/help \xB7
|
|
3755
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "/help \xB7 F1 projects \xB7 F10 sessions \xB7 /exit" })
|
|
3444
3756
|
] })
|
|
3445
3757
|
] });
|
|
3446
3758
|
}
|
|
@@ -3468,6 +3780,8 @@ function brainStatusStyle(status) {
|
|
|
3468
3780
|
return { icon: "?", color: "yellow" };
|
|
3469
3781
|
case "denied":
|
|
3470
3782
|
return { icon: "\xD7", color: "red" };
|
|
3783
|
+
case "intervention":
|
|
3784
|
+
return { icon: "\u26A1", color: "yellow" };
|
|
3471
3785
|
}
|
|
3472
3786
|
}
|
|
3473
3787
|
function brainRiskColor(risk) {
|
|
@@ -3618,8 +3932,10 @@ var Entry = React5.memo(function Entry2({
|
|
|
3618
3932
|
diff ? /* @__PURE__ */ jsx(DiffBlock, { rows: diff.rows, hidden: diff.hidden }) : null
|
|
3619
3933
|
] });
|
|
3620
3934
|
}
|
|
3621
|
-
case "info":
|
|
3622
|
-
|
|
3935
|
+
case "info": {
|
|
3936
|
+
const hasAnsi = /\x1b\[/.test(entry.text);
|
|
3937
|
+
return /* @__PURE__ */ jsx(Text, { dimColor: !hasAnsi, children: entry.text });
|
|
3938
|
+
}
|
|
3623
3939
|
case "warn":
|
|
3624
3940
|
return /* @__PURE__ */ jsx(
|
|
3625
3941
|
Box,
|
|
@@ -3728,7 +4044,7 @@ var Entry = React5.memo(function Entry2({
|
|
|
3728
4044
|
}
|
|
3729
4045
|
}
|
|
3730
4046
|
});
|
|
3731
|
-
function History({ entries, streamingText, toolStream }) {
|
|
4047
|
+
function History({ entries, generation, streamingText, toolStream }) {
|
|
3732
4048
|
const { stdout } = useStdout();
|
|
3733
4049
|
const [termSize, setTermSize] = useState({
|
|
3734
4050
|
columns: stdout?.columns ?? 80,
|
|
@@ -3746,10 +4062,209 @@ function History({ entries, streamingText, toolStream }) {
|
|
|
3746
4062
|
const termWidth = termSize.columns;
|
|
3747
4063
|
const tail = streamingText ? tailForDisplay(streamingText, MAX_STREAM_DISPLAY_CHARS) : "";
|
|
3748
4064
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3749
|
-
/* @__PURE__ */ jsx(Static, { items: entries, children: (entry) => /* @__PURE__ */ jsx(Box, { marginBottom: entry.kind === "turn-summary" ? 1 : 0, children: /* @__PURE__ */ jsx(Entry, { entry, termWidth }) }, entry.id) }),
|
|
4065
|
+
/* @__PURE__ */ jsx(Static, { items: entries, children: (entry) => /* @__PURE__ */ jsx(Box, { marginBottom: entry.kind === "turn-summary" ? 1 : 0, children: /* @__PURE__ */ jsx(Entry, { entry, termWidth }) }, entry.id) }, generation ?? 0),
|
|
3750
4066
|
/* @__PURE__ */ jsx(Box, { flexGrow: 1, children: tail ? /* @__PURE__ */ jsx(AssistantTail, { text: tail, termWidth }) : null })
|
|
3751
4067
|
] });
|
|
3752
4068
|
}
|
|
4069
|
+
var MAX_MOUNTED = 500;
|
|
4070
|
+
function scrollbarThumb(rows, offset, total) {
|
|
4071
|
+
const scrollable = total > rows;
|
|
4072
|
+
if (!scrollable) return { top: 0, size: rows, scrollable: false };
|
|
4073
|
+
const windowTop = Math.max(0, total - rows - offset);
|
|
4074
|
+
const size = Math.max(1, Math.round(rows / total * rows));
|
|
4075
|
+
const rawTop = Math.round(windowTop / total * rows);
|
|
4076
|
+
const top = Math.max(0, Math.min(rawTop, rows - size));
|
|
4077
|
+
return { top, size, scrollable: true };
|
|
4078
|
+
}
|
|
4079
|
+
function scrollOffsetForTrackRow(rows, total, cell) {
|
|
4080
|
+
if (total <= rows) return 0;
|
|
4081
|
+
const maxOffset = total - rows;
|
|
4082
|
+
const clampedCell = Math.max(0, Math.min(rows - 1, cell));
|
|
4083
|
+
const windowTop = Math.round(clampedCell / Math.max(1, rows - 1) * maxOffset);
|
|
4084
|
+
return Math.max(0, Math.min(maxOffset, maxOffset - windowTop));
|
|
4085
|
+
}
|
|
4086
|
+
function Scrollbar({
|
|
4087
|
+
rows,
|
|
4088
|
+
offset,
|
|
4089
|
+
total
|
|
4090
|
+
}) {
|
|
4091
|
+
const { top: thumbTop, size: thumbSize, scrollable } = scrollbarThumb(rows, offset, total);
|
|
4092
|
+
const cells = [];
|
|
4093
|
+
for (let i = 0; i < rows; i++) {
|
|
4094
|
+
cells.push(i >= thumbTop && i < thumbTop + thumbSize ? "\u2588" : "\u2502");
|
|
4095
|
+
}
|
|
4096
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginLeft: 1, flexShrink: 0, children: cells.map((c, i) => /* @__PURE__ */ jsx(
|
|
4097
|
+
Text,
|
|
4098
|
+
{
|
|
4099
|
+
...scrollable ? { color: theme.accent } : {},
|
|
4100
|
+
dimColor: !scrollable || c === "\u2502",
|
|
4101
|
+
children: c
|
|
4102
|
+
},
|
|
4103
|
+
i
|
|
4104
|
+
)) });
|
|
4105
|
+
}
|
|
4106
|
+
function ScrollableHistory({
|
|
4107
|
+
entries,
|
|
4108
|
+
streamingText,
|
|
4109
|
+
toolStream,
|
|
4110
|
+
scrollOffset,
|
|
4111
|
+
viewportRows,
|
|
4112
|
+
totalLines,
|
|
4113
|
+
onMeasure,
|
|
4114
|
+
maxWidth
|
|
4115
|
+
}) {
|
|
4116
|
+
const { stdout } = useStdout();
|
|
4117
|
+
const rawWidth = stdout?.columns ?? 80;
|
|
4118
|
+
const termWidth = maxWidth ? Math.min(rawWidth, maxWidth) : rawWidth;
|
|
4119
|
+
const tail = streamingText ? tailForDisplay(streamingText, MAX_STREAM_DISPLAY_CHARS) : "";
|
|
4120
|
+
const toolTail = toolStream?.text ? tailForDisplay(toolStream.text, MAX_STREAM_DISPLAY_CHARS) : "";
|
|
4121
|
+
const hiddenCount = Math.max(0, entries.length - MAX_MOUNTED);
|
|
4122
|
+
const shown = hiddenCount > 0 ? entries.slice(-MAX_MOUNTED) : entries;
|
|
4123
|
+
const contentRef = useRef(null);
|
|
4124
|
+
const lastReported = useRef(-1);
|
|
4125
|
+
useLayoutEffect(() => {
|
|
4126
|
+
const node = contentRef.current;
|
|
4127
|
+
if (!node) return;
|
|
4128
|
+
const { height } = measureElement(node);
|
|
4129
|
+
if (height !== lastReported.current) {
|
|
4130
|
+
lastReported.current = height;
|
|
4131
|
+
onMeasure(height);
|
|
4132
|
+
}
|
|
4133
|
+
}, [onMeasure]);
|
|
4134
|
+
const vp = Math.max(1, viewportRows);
|
|
4135
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
|
|
4136
|
+
/* @__PURE__ */ jsx(
|
|
4137
|
+
Box,
|
|
4138
|
+
{
|
|
4139
|
+
flexDirection: "column",
|
|
4140
|
+
flexGrow: 1,
|
|
4141
|
+
height: vp,
|
|
4142
|
+
overflowY: "hidden",
|
|
4143
|
+
justifyContent: "flex-end",
|
|
4144
|
+
children: /* @__PURE__ */ jsxs(
|
|
4145
|
+
Box,
|
|
4146
|
+
{
|
|
4147
|
+
ref: contentRef,
|
|
4148
|
+
flexDirection: "column",
|
|
4149
|
+
marginBottom: Math.max(0, scrollOffset),
|
|
4150
|
+
flexShrink: 0,
|
|
4151
|
+
children: [
|
|
4152
|
+
hiddenCount > 0 ? /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsx(Text, { dimColor: true, italic: true, children: ` \u2191 ${hiddenCount} earlier ${hiddenCount === 1 ? "entry" : "entries"} (scroll lives in this session; full log on disk)` }) }) : null,
|
|
4153
|
+
shown.map((entry) => /* @__PURE__ */ jsx(Box, { marginBottom: entry.kind === "turn-summary" ? 1 : 0, flexShrink: 0, children: /* @__PURE__ */ jsx(Entry, { entry, termWidth }) }, entry.id)),
|
|
4154
|
+
tail ? /* @__PURE__ */ jsx(AssistantTail, { text: tail, termWidth }) : null,
|
|
4155
|
+
toolTail && toolStream ? /* @__PURE__ */ jsx(
|
|
4156
|
+
ToolStreamBox,
|
|
4157
|
+
{
|
|
4158
|
+
name: toolStream.name,
|
|
4159
|
+
text: toolTail,
|
|
4160
|
+
startedAt: toolStream.startedAt,
|
|
4161
|
+
termWidth
|
|
4162
|
+
}
|
|
4163
|
+
) : null
|
|
4164
|
+
]
|
|
4165
|
+
}
|
|
4166
|
+
)
|
|
4167
|
+
}
|
|
4168
|
+
),
|
|
4169
|
+
/* @__PURE__ */ jsx(Scrollbar, { rows: vp, offset: Math.max(0, scrollOffset), total: totalLines })
|
|
4170
|
+
] });
|
|
4171
|
+
}
|
|
4172
|
+
var MB = 1024 * 1024;
|
|
4173
|
+
function defaultHeapLogPath() {
|
|
4174
|
+
return path4.join(wstackGlobalRoot(), "logs", "heap.jsonl");
|
|
4175
|
+
}
|
|
4176
|
+
function takeHeapSample() {
|
|
4177
|
+
const m = process.memoryUsage();
|
|
4178
|
+
const limit = v8.getHeapStatistics().heap_size_limit || 0;
|
|
4179
|
+
return {
|
|
4180
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4181
|
+
rss: m.rss,
|
|
4182
|
+
heapUsed: m.heapUsed,
|
|
4183
|
+
heapTotal: m.heapTotal,
|
|
4184
|
+
external: m.external,
|
|
4185
|
+
heapLimit: limit,
|
|
4186
|
+
load: limit > 0 ? m.heapUsed / limit : 0
|
|
4187
|
+
};
|
|
4188
|
+
}
|
|
4189
|
+
function startHeapWatchdog(opts = {}) {
|
|
4190
|
+
const sampleEveryMs = opts.sampleEveryMs ?? 6e4;
|
|
4191
|
+
const logEveryMs = opts.logEveryMs ?? 3e5;
|
|
4192
|
+
const logPath = opts.logPath ?? defaultHeapLogPath();
|
|
4193
|
+
const warnAt = opts.warnAt ?? 0.6;
|
|
4194
|
+
const criticalAt = opts.criticalAt ?? 0.85;
|
|
4195
|
+
const REARM_MARGIN = 0.05;
|
|
4196
|
+
let warnArmed = true;
|
|
4197
|
+
let criticalArmed = true;
|
|
4198
|
+
let lastLogAt = 0;
|
|
4199
|
+
let writeChain = Promise.resolve();
|
|
4200
|
+
let dirReady = false;
|
|
4201
|
+
const append = (line) => {
|
|
4202
|
+
writeChain = writeChain.then(async () => {
|
|
4203
|
+
if (!dirReady) {
|
|
4204
|
+
await fs2.mkdir(path4.dirname(logPath), { recursive: true });
|
|
4205
|
+
dirReady = true;
|
|
4206
|
+
}
|
|
4207
|
+
await fs2.appendFile(logPath, `${line}
|
|
4208
|
+
`, "utf8");
|
|
4209
|
+
}).catch(() => void 0);
|
|
4210
|
+
};
|
|
4211
|
+
const tick = () => {
|
|
4212
|
+
const s2 = takeHeapSample();
|
|
4213
|
+
if (s2.load >= criticalAt && criticalArmed) {
|
|
4214
|
+
criticalArmed = false;
|
|
4215
|
+
warnArmed = false;
|
|
4216
|
+
opts.onWarn?.(
|
|
4217
|
+
"critical",
|
|
4218
|
+
`Heap critical: ${Math.round(s2.heapUsed / MB)} MB of ~${Math.round(s2.heapLimit / MB)} MB V8 limit (${Math.round(s2.load * 100)}%). An out-of-memory crash is likely soon \u2014 finish/checkpoint work and restart the session. Diagnostics: ${logPath}`,
|
|
4219
|
+
s2
|
|
4220
|
+
);
|
|
4221
|
+
} else if (s2.load >= warnAt && warnArmed) {
|
|
4222
|
+
warnArmed = false;
|
|
4223
|
+
opts.onWarn?.(
|
|
4224
|
+
"warn",
|
|
4225
|
+
`Heap high: ${Math.round(s2.heapUsed / MB)} MB of ~${Math.round(s2.heapLimit / MB)} MB V8 limit (${Math.round(s2.load * 100)}%). Memory diagnostics are being recorded to ${logPath}`,
|
|
4226
|
+
s2
|
|
4227
|
+
);
|
|
4228
|
+
}
|
|
4229
|
+
if (!warnArmed && s2.load < warnAt - REARM_MARGIN) warnArmed = true;
|
|
4230
|
+
if (!criticalArmed && s2.load < criticalAt - REARM_MARGIN) criticalArmed = true;
|
|
4231
|
+
const due = Date.now() - lastLogAt >= logEveryMs;
|
|
4232
|
+
const crossed = s2.load >= warnAt;
|
|
4233
|
+
if (due || crossed) {
|
|
4234
|
+
lastLogAt = Date.now();
|
|
4235
|
+
let extras = {};
|
|
4236
|
+
try {
|
|
4237
|
+
extras = opts.collectStats?.() ?? {};
|
|
4238
|
+
} catch {
|
|
4239
|
+
}
|
|
4240
|
+
append(JSON.stringify({ pid: process.pid, ...s2, ...extras }));
|
|
4241
|
+
}
|
|
4242
|
+
};
|
|
4243
|
+
const timer = setInterval(tick, sampleEveryMs);
|
|
4244
|
+
timer.unref?.();
|
|
4245
|
+
tick();
|
|
4246
|
+
return () => {
|
|
4247
|
+
clearInterval(timer);
|
|
4248
|
+
};
|
|
4249
|
+
}
|
|
4250
|
+
|
|
4251
|
+
// src/hit-test.ts
|
|
4252
|
+
var SCROLLBAR_HIT_WIDTH = 2;
|
|
4253
|
+
function hitRegion(layout, x, y) {
|
|
4254
|
+
const { termRows, termCols, viewportRows } = layout;
|
|
4255
|
+
if (y < 1 || y > termRows || x < 1 || x > termCols) return null;
|
|
4256
|
+
if (y <= viewportRows) {
|
|
4257
|
+
if (x > termCols - SCROLLBAR_HIT_WIDTH) return { kind: "scrollbar", cell: y - 1 };
|
|
4258
|
+
return { kind: "history", row: y - 1 };
|
|
4259
|
+
}
|
|
4260
|
+
return { kind: "bottom", row: y - viewportRows - 1 };
|
|
4261
|
+
}
|
|
4262
|
+
function statusBarLineRow(opts) {
|
|
4263
|
+
const contentLines = opts.statusBarHeight - opts.headerRows;
|
|
4264
|
+
if (opts.line < 0 || opts.line >= contentLines) return null;
|
|
4265
|
+
const bandTop = opts.termRows - opts.belowHeight - opts.statusBarHeight + 1;
|
|
4266
|
+
return bandTop + opts.headerRows + opts.line;
|
|
4267
|
+
}
|
|
3753
4268
|
|
|
3754
4269
|
// src/fn-keys.ts
|
|
3755
4270
|
function fnKey(data) {
|
|
@@ -3853,6 +4368,45 @@ function layoutInputRows(prompt, value, cursor, width) {
|
|
|
3853
4368
|
if (row.length > 0 || rows.length === 0) rows.push(row);
|
|
3854
4369
|
return rows;
|
|
3855
4370
|
}
|
|
4371
|
+
|
|
4372
|
+
// src/mouse.ts
|
|
4373
|
+
var ESC = String.fromCharCode(27);
|
|
4374
|
+
var MOUSE_CLICK_ON = `${ESC}[?1000h${ESC}[?1006h`;
|
|
4375
|
+
var MOUSE_OFF = `${ESC}[?1003l${ESC}[?1002l${ESC}[?1000l${ESC}[?1006l`;
|
|
4376
|
+
var SGR_MOUSE_GLOBAL = new RegExp(`${ESC}\\[<(\\d+);(\\d+);(\\d+)([Mm])`, "gu");
|
|
4377
|
+
var LEAKED_MOUSE_RE = /\[<\d+;\d+;\d+[Mm]/;
|
|
4378
|
+
function decodeMouse(cb, x, y, released) {
|
|
4379
|
+
const shift = (cb & 4) !== 0;
|
|
4380
|
+
const meta = (cb & 8) !== 0;
|
|
4381
|
+
const ctrl = (cb & 16) !== 0;
|
|
4382
|
+
const motion = (cb & 32) !== 0;
|
|
4383
|
+
const wheel = (cb & 64) !== 0;
|
|
4384
|
+
const low = cb & 3;
|
|
4385
|
+
if (wheel) {
|
|
4386
|
+
const dir = low === 0 ? 1 : low === 1 ? -1 : 0;
|
|
4387
|
+
return { kind: "wheel", button: "none", x, y, wheel: dir, shift, meta, ctrl, motion: false };
|
|
4388
|
+
}
|
|
4389
|
+
const button = low === 0 ? "left" : low === 1 ? "middle" : low === 2 ? "right" : "none";
|
|
4390
|
+
const kind = motion ? "move" : released ? "release" : "press";
|
|
4391
|
+
return { kind, button, x, y, wheel: 0, shift, meta, ctrl, motion };
|
|
4392
|
+
}
|
|
4393
|
+
function parseMouseEvents(data) {
|
|
4394
|
+
const events = [];
|
|
4395
|
+
for (const m of data.matchAll(SGR_MOUSE_GLOBAL)) {
|
|
4396
|
+
events.push(
|
|
4397
|
+
decodeMouse(
|
|
4398
|
+
Number.parseInt(m[1], 10),
|
|
4399
|
+
Number.parseInt(m[2], 10),
|
|
4400
|
+
Number.parseInt(m[3], 10),
|
|
4401
|
+
m[4] === "m"
|
|
4402
|
+
)
|
|
4403
|
+
);
|
|
4404
|
+
}
|
|
4405
|
+
return events;
|
|
4406
|
+
}
|
|
4407
|
+
function isLeakedMouseInput(input) {
|
|
4408
|
+
return LEAKED_MOUSE_RE.test(input);
|
|
4409
|
+
}
|
|
3856
4410
|
function renderRow2(cells, rowKey, promptColor) {
|
|
3857
4411
|
const out = [];
|
|
3858
4412
|
let run = "";
|
|
@@ -3907,14 +4461,6 @@ function isBackspaceOrDelete(data) {
|
|
|
3907
4461
|
if (data === "\x1B[3~") return "delete";
|
|
3908
4462
|
return null;
|
|
3909
4463
|
}
|
|
3910
|
-
function parseMouseWheel(data) {
|
|
3911
|
-
const m = data.match(new RegExp(`^${String.fromCharCode(27)}\\[<(\\d+);(\\d+);(\\d+)([Mm])$`, "u"));
|
|
3912
|
-
if (!m) return null;
|
|
3913
|
-
const cb = Number.parseInt(expectDefined(m[1]), 10);
|
|
3914
|
-
if (cb === 64) return 1;
|
|
3915
|
-
if (cb === 65) return -1;
|
|
3916
|
-
return null;
|
|
3917
|
-
}
|
|
3918
4464
|
var EMPTY_KEY = {
|
|
3919
4465
|
upArrow: false,
|
|
3920
4466
|
downArrow: false,
|
|
@@ -3948,6 +4494,7 @@ var Input = memo(function Input2({
|
|
|
3948
4494
|
const suppressInkDeleteRef = useRef(false);
|
|
3949
4495
|
useInput((input, key) => {
|
|
3950
4496
|
if (disabled) return;
|
|
4497
|
+
if (input && isLeakedMouseInput(input)) return;
|
|
3951
4498
|
if (key.escape && suppressInkEscRef.current) {
|
|
3952
4499
|
suppressInkEscRef.current = false;
|
|
3953
4500
|
return;
|
|
@@ -4011,9 +4558,15 @@ var Input = memo(function Input2({
|
|
|
4011
4558
|
onKey("", { ...EMPTY_KEY, backspace: true, ctrl: true });
|
|
4012
4559
|
return;
|
|
4013
4560
|
}
|
|
4014
|
-
const
|
|
4015
|
-
if (
|
|
4016
|
-
|
|
4561
|
+
const mouseEvents = parseMouseEvents(s2);
|
|
4562
|
+
if (mouseEvents.length > 0) {
|
|
4563
|
+
for (const ev of mouseEvents) {
|
|
4564
|
+
onKey("", {
|
|
4565
|
+
...EMPTY_KEY,
|
|
4566
|
+
mouse: ev,
|
|
4567
|
+
wheelDeltaY: ev.kind === "wheel" ? ev.wheel : void 0
|
|
4568
|
+
});
|
|
4569
|
+
}
|
|
4017
4570
|
return;
|
|
4018
4571
|
}
|
|
4019
4572
|
const fn = fnKey(s2);
|
|
@@ -4319,6 +4872,80 @@ function PhasePanel({ phases, nowTick }) {
|
|
|
4319
4872
|
}
|
|
4320
4873
|
);
|
|
4321
4874
|
}
|
|
4875
|
+
var MAX_VISIBLE2 = 12;
|
|
4876
|
+
function visibleWindow(selected, total) {
|
|
4877
|
+
if (total <= MAX_VISIBLE2) return { start: 0, end: total };
|
|
4878
|
+
const half = Math.floor(MAX_VISIBLE2 / 2);
|
|
4879
|
+
let start = selected - half;
|
|
4880
|
+
let end = start + MAX_VISIBLE2;
|
|
4881
|
+
if (start < 0) {
|
|
4882
|
+
start = 0;
|
|
4883
|
+
end = MAX_VISIBLE2;
|
|
4884
|
+
}
|
|
4885
|
+
if (end > total) {
|
|
4886
|
+
end = total;
|
|
4887
|
+
start = total - MAX_VISIBLE2;
|
|
4888
|
+
}
|
|
4889
|
+
return { start, end };
|
|
4890
|
+
}
|
|
4891
|
+
function ProjectPicker({
|
|
4892
|
+
items,
|
|
4893
|
+
selected,
|
|
4894
|
+
filter,
|
|
4895
|
+
hint
|
|
4896
|
+
}) {
|
|
4897
|
+
const total = items.length;
|
|
4898
|
+
const { start, end } = visibleWindow(selected, total);
|
|
4899
|
+
const visible = items.slice(start, end);
|
|
4900
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, flexShrink: 0, children: [
|
|
4901
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u2501\u2501 Switch Project \u2501\u2501" }),
|
|
4902
|
+
filter ? /* @__PURE__ */ jsxs(Box, { children: [
|
|
4903
|
+
/* @__PURE__ */ jsx(Text, { color: "yellow", children: "Filter: " }),
|
|
4904
|
+
/* @__PURE__ */ jsx(Text, { children: filter }),
|
|
4905
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2588" })
|
|
4906
|
+
] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: "type to filter \xB7 \u2191\u2193 navigate \xB7 Enter select \xB7 Esc cancel" }),
|
|
4907
|
+
start > 0 ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
4908
|
+
"\u2191 ",
|
|
4909
|
+
start,
|
|
4910
|
+
" more above"
|
|
4911
|
+
] }) : null,
|
|
4912
|
+
visible.map((item) => {
|
|
4913
|
+
const idx = items.indexOf(item);
|
|
4914
|
+
const isSelected = idx === selected;
|
|
4915
|
+
const isDivider = item.key === "__divider__";
|
|
4916
|
+
if (isDivider) {
|
|
4917
|
+
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500".repeat(36) }, item.key);
|
|
4918
|
+
}
|
|
4919
|
+
const marker = isSelected ? "\u25B8" : " ";
|
|
4920
|
+
const labelColor = isSelected ? "cyan" : void 0;
|
|
4921
|
+
const metaColor = "grey";
|
|
4922
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
4923
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
4924
|
+
/* @__PURE__ */ jsxs(Text, { inverse: isSelected, color: labelColor, children: [
|
|
4925
|
+
` ${marker} `,
|
|
4926
|
+
/* @__PURE__ */ jsx(Text, { bold: isSelected, children: item.label })
|
|
4927
|
+
] }),
|
|
4928
|
+
item.meta ? /* @__PURE__ */ jsxs(Text, { dimColor: !isSelected, color: isSelected ? "cyan" : metaColor, children: [
|
|
4929
|
+
" ",
|
|
4930
|
+
item.meta
|
|
4931
|
+
] }) : null
|
|
4932
|
+
] }),
|
|
4933
|
+
item.subtitle ? /* @__PURE__ */ jsxs(Text, { dimColor: !isSelected, color: isSelected ? "cyan" : metaColor, children: [
|
|
4934
|
+
" ",
|
|
4935
|
+
item.subtitle
|
|
4936
|
+
] }) : null
|
|
4937
|
+
] }, item.key);
|
|
4938
|
+
}),
|
|
4939
|
+
end < total ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
4940
|
+
"\u2193 ",
|
|
4941
|
+
total - end,
|
|
4942
|
+
" more below \xB7 ",
|
|
4943
|
+
total,
|
|
4944
|
+
" total"
|
|
4945
|
+
] }) : null,
|
|
4946
|
+
hint ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) }) : null
|
|
4947
|
+
] });
|
|
4948
|
+
}
|
|
4322
4949
|
function QueuePanel({ items }) {
|
|
4323
4950
|
const { stdout } = useStdout();
|
|
4324
4951
|
const w = stdout?.columns ?? 80;
|
|
@@ -4549,6 +5176,200 @@ function renderProgressBar(progress, trend) {
|
|
|
4549
5176
|
] })
|
|
4550
5177
|
] });
|
|
4551
5178
|
}
|
|
5179
|
+
function ResumePicker({
|
|
5180
|
+
sessions,
|
|
5181
|
+
selected,
|
|
5182
|
+
busy,
|
|
5183
|
+
error,
|
|
5184
|
+
hint
|
|
5185
|
+
}) {
|
|
5186
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
|
|
5187
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u2501\u2501 Resume Session \u2501\u2501" }),
|
|
5188
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: busy ? "Resuming selected session\u2026" : "\u2191/\u2193 navigate \xB7 Enter select \xB7 Esc cancel" }),
|
|
5189
|
+
error ? /* @__PURE__ */ jsx(Text, { color: "red", children: error }) : null,
|
|
5190
|
+
sessions.length === 0 && !busy ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No sessions found." }) : sessions.map((s2, i) => {
|
|
5191
|
+
const isCurrent = s2.isCurrent;
|
|
5192
|
+
const isSelected = i === selected;
|
|
5193
|
+
const date = s2.startedAt.slice(0, 16).replace("T", " ");
|
|
5194
|
+
const outcomeBadge = s2.outcome === "completed" ? "\u2713 " : s2.outcome === "aborted" ? "\u26A0 " : s2.outcome === "error" ? "\u2717 " : s2.outcome === "timeout" ? "\u23F1 " : " ";
|
|
5195
|
+
const toolStr = s2.toolCallCount > 0 ? `${s2.toolCallCount} tool${s2.toolCallCount === 1 ? "" : "s"}` : "";
|
|
5196
|
+
const iterStr = s2.iterationCount > 0 ? `${s2.iterationCount} iter${s2.iterationCount === 1 ? "" : "s"}` : "";
|
|
5197
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
5198
|
+
/* @__PURE__ */ jsxs(
|
|
5199
|
+
Text,
|
|
5200
|
+
{
|
|
5201
|
+
inverse: isSelected,
|
|
5202
|
+
dimColor: isCurrent ?? false,
|
|
5203
|
+
...isSelected ? { color: isCurrent ? "gray" : "cyan" } : {},
|
|
5204
|
+
children: [
|
|
5205
|
+
isSelected ? "\u203A " : " ",
|
|
5206
|
+
/* @__PURE__ */ jsx(Text, { bold: true, dimColor: isCurrent ?? false, children: s2.id }),
|
|
5207
|
+
isCurrent ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: " (current)" }) : null,
|
|
5208
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5209
|
+
" ",
|
|
5210
|
+
date
|
|
5211
|
+
] })
|
|
5212
|
+
]
|
|
5213
|
+
}
|
|
5214
|
+
),
|
|
5215
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5216
|
+
isSelected ? " " : " ",
|
|
5217
|
+
outcomeBadge,
|
|
5218
|
+
s2.tokenTotal.toLocaleString(),
|
|
5219
|
+
" tok",
|
|
5220
|
+
toolStr ? ` \xB7 ${toolStr}` : "",
|
|
5221
|
+
iterStr ? ` \xB7 ${iterStr}` : "",
|
|
5222
|
+
s2.toolErrorCount > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
5223
|
+
" \xB7 ",
|
|
5224
|
+
s2.toolErrorCount,
|
|
5225
|
+
" err"
|
|
5226
|
+
] }) : null
|
|
5227
|
+
] }),
|
|
5228
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5229
|
+
isSelected ? " " : " ",
|
|
5230
|
+
s2.title.length > 72 ? `${s2.title.slice(0, 71)}\u2026` : s2.title
|
|
5231
|
+
] })
|
|
5232
|
+
] }, s2.id);
|
|
5233
|
+
}),
|
|
5234
|
+
hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
|
|
5235
|
+
] });
|
|
5236
|
+
}
|
|
5237
|
+
function statusIcon(status) {
|
|
5238
|
+
switch (status) {
|
|
5239
|
+
case "active":
|
|
5240
|
+
return "\u25CF";
|
|
5241
|
+
case "idle":
|
|
5242
|
+
return "\u25C9";
|
|
5243
|
+
case "closing":
|
|
5244
|
+
return "\u25D0";
|
|
5245
|
+
case "stale":
|
|
5246
|
+
return "\u25CB";
|
|
5247
|
+
default:
|
|
5248
|
+
return "?";
|
|
5249
|
+
}
|
|
5250
|
+
}
|
|
5251
|
+
function agentIcon(status) {
|
|
5252
|
+
switch (status) {
|
|
5253
|
+
case "running":
|
|
5254
|
+
return "\u25B6";
|
|
5255
|
+
case "streaming":
|
|
5256
|
+
return "\u21BB";
|
|
5257
|
+
case "waiting_user":
|
|
5258
|
+
return "\u23F3";
|
|
5259
|
+
case "error":
|
|
5260
|
+
return "\u2717";
|
|
5261
|
+
case "idle":
|
|
5262
|
+
return "\u25A0";
|
|
5263
|
+
default:
|
|
5264
|
+
return "?";
|
|
5265
|
+
}
|
|
5266
|
+
}
|
|
5267
|
+
function fmtDuration2(startedAt) {
|
|
5268
|
+
const diff = Date.now() - new Date(startedAt).getTime();
|
|
5269
|
+
const min = Math.floor(diff / 6e4);
|
|
5270
|
+
if (min < 1) return "<1m";
|
|
5271
|
+
if (min < 60) return `${min}m`;
|
|
5272
|
+
const h = Math.floor(min / 60);
|
|
5273
|
+
if (h < 24) return `${h}h ${min % 60}m`;
|
|
5274
|
+
return `${Math.floor(h / 24)}d ${h % 24}h`;
|
|
5275
|
+
}
|
|
5276
|
+
function SessionsPanel({
|
|
5277
|
+
sessions,
|
|
5278
|
+
busy,
|
|
5279
|
+
selected,
|
|
5280
|
+
resumeConfirm,
|
|
5281
|
+
currentSessionId
|
|
5282
|
+
}) {
|
|
5283
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, flexShrink: 0, children: [
|
|
5284
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
5285
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u29C9 Sessions" }),
|
|
5286
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 F10 or Esc to close" }),
|
|
5287
|
+
busy && /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 loading\u2026" })
|
|
5288
|
+
] }),
|
|
5289
|
+
resumeConfirm ? /* @__PURE__ */ jsxs(Box, { marginY: 1, borderStyle: "single", borderColor: "yellow", paddingX: 1, children: [
|
|
5290
|
+
/* @__PURE__ */ jsxs(Text, { color: "yellow", bold: true, children: [
|
|
5291
|
+
'\u26A0 Resume session "',
|
|
5292
|
+
resumeConfirm.sessionName,
|
|
5293
|
+
'"?'
|
|
5294
|
+
] }),
|
|
5295
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "This will replace the current conversation. Press Enter to confirm, Esc to cancel." })
|
|
5296
|
+
] }) : null,
|
|
5297
|
+
sessions.length === 0 ? /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: busy ? "Loading sessions..." : "No live sessions. Open another wstack instance to see it here." }) }) : sessions.map((s2, idx) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
5298
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
5299
|
+
/* @__PURE__ */ jsxs(Text, { inverse: idx === selected, color: s2.status === "active" ? "green" : s2.status === "idle" ? "cyan" : "yellow", children: [
|
|
5300
|
+
s2.sessionId === currentSessionId ? "\u25CF " : "",
|
|
5301
|
+
statusIcon(s2.status),
|
|
5302
|
+
" "
|
|
5303
|
+
] }),
|
|
5304
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: s2.projectName }),
|
|
5305
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5306
|
+
" [",
|
|
5307
|
+
s2.projectSlug,
|
|
5308
|
+
"]"
|
|
5309
|
+
] }),
|
|
5310
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5311
|
+
" \xB7 ",
|
|
5312
|
+
s2.sessionId.slice(0, 8)
|
|
5313
|
+
] }),
|
|
5314
|
+
s2.gitBranch ? /* @__PURE__ */ jsxs(Text, { color: "magenta", children: [
|
|
5315
|
+
" \u2387 ",
|
|
5316
|
+
s2.gitBranch
|
|
5317
|
+
] }) : null,
|
|
5318
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5319
|
+
" \xB7 ",
|
|
5320
|
+
fmtDuration2(s2.startedAt)
|
|
5321
|
+
] }),
|
|
5322
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5323
|
+
" \xB7 PID ",
|
|
5324
|
+
s2.pid
|
|
5325
|
+
] })
|
|
5326
|
+
] }),
|
|
5327
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5328
|
+
" wd: ",
|
|
5329
|
+
s2.workingDir
|
|
5330
|
+
] }),
|
|
5331
|
+
/* @__PURE__ */ jsxs(Box, { marginLeft: 2, flexDirection: "column", children: [
|
|
5332
|
+
s2.agents.slice(0, 8).map((a) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
5333
|
+
/* @__PURE__ */ jsxs(Text, { color: a.status === "running" ? "green" : a.status === "streaming" ? "cyan" : a.status === "error" ? "red" : a.status === "waiting_user" ? "yellow" : "grey", children: [
|
|
5334
|
+
agentIcon(a.status),
|
|
5335
|
+
" "
|
|
5336
|
+
] }),
|
|
5337
|
+
/* @__PURE__ */ jsx(Text, { children: a.name }),
|
|
5338
|
+
a.currentTool ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5339
|
+
" [",
|
|
5340
|
+
a.currentTool,
|
|
5341
|
+
"]"
|
|
5342
|
+
] }) : null,
|
|
5343
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5344
|
+
" \xB7 ",
|
|
5345
|
+
a.iterations,
|
|
5346
|
+
" iter \xB7 ",
|
|
5347
|
+
a.toolCalls,
|
|
5348
|
+
" tools"
|
|
5349
|
+
] })
|
|
5350
|
+
] }, a.id)),
|
|
5351
|
+
s2.agents.length > 8 ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5352
|
+
" ... and ",
|
|
5353
|
+
s2.agents.length - 8,
|
|
5354
|
+
" more"
|
|
5355
|
+
] }) : null
|
|
5356
|
+
] })
|
|
5357
|
+
] }, s2.sessionId)),
|
|
5358
|
+
sessions.length > 0 && /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
|
|
5359
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5360
|
+
sessions.length,
|
|
5361
|
+
" session",
|
|
5362
|
+
sessions.length === 1 ? "" : "s",
|
|
5363
|
+
" \xB7 \u2191\u2193 navigate \xB7 Enter to resume/switch \xB7 Esc close"
|
|
5364
|
+
] }),
|
|
5365
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5366
|
+
"Tip: /sessions kill ",
|
|
5367
|
+
"<id>",
|
|
5368
|
+
" to stop a background session"
|
|
5369
|
+
] })
|
|
5370
|
+
] })
|
|
5371
|
+
] });
|
|
5372
|
+
}
|
|
4552
5373
|
var DELAY_PRESETS_MS = [0, 15e3, 3e4, 45e3, 6e4, 12e4];
|
|
4553
5374
|
var SETTINGS_MODES = ["off", "suggest", "auto"];
|
|
4554
5375
|
var LOG_LEVELS = ["error", "warn", "info", "debug", "trace"];
|
|
@@ -4557,6 +5378,7 @@ var COMPACTOR_STRATEGIES = ["hybrid", "intelligent", "selective"];
|
|
|
4557
5378
|
var MAX_ITERATIONS_PRESETS = [100, 200, 500, 1e3, 0];
|
|
4558
5379
|
var AUTO_PROCEED_MAX_PRESETS = [10, 25, 50, 100, 250, 0];
|
|
4559
5380
|
var ENHANCE_DELAY_PRESETS = [3e4, 45e3, 6e4, 9e4, 12e4];
|
|
5381
|
+
var ENHANCE_LANGUAGES = ["original", "english"];
|
|
4560
5382
|
function formatSettingsDelay(ms) {
|
|
4561
5383
|
if (ms === 0) return "disabled";
|
|
4562
5384
|
if (ms >= 6e4) return `${Math.round(ms / 6e4)}m`;
|
|
@@ -4574,7 +5396,7 @@ var MODE_DESC = {
|
|
|
4574
5396
|
suggest: "Shows next-step suggestions after each turn",
|
|
4575
5397
|
auto: "Self-driving \u2014 agent continues automatically"
|
|
4576
5398
|
};
|
|
4577
|
-
var SETTINGS_FIELD_COUNT =
|
|
5399
|
+
var SETTINGS_FIELD_COUNT = 24;
|
|
4578
5400
|
var CONFIG_SCOPES = ["global", "project"];
|
|
4579
5401
|
function SettingsPicker({
|
|
4580
5402
|
field,
|
|
@@ -4599,6 +5421,8 @@ function SettingsPicker({
|
|
|
4599
5421
|
maxIterations,
|
|
4600
5422
|
autoProceedMaxIterations,
|
|
4601
5423
|
enhanceDelayMs,
|
|
5424
|
+
enhanceEnabled,
|
|
5425
|
+
enhanceLanguage,
|
|
4602
5426
|
debugStream,
|
|
4603
5427
|
configScope,
|
|
4604
5428
|
hint
|
|
@@ -4722,6 +5546,16 @@ function SettingsPicker({
|
|
|
4722
5546
|
value: formatEnhanceDelay(enhanceDelayMs),
|
|
4723
5547
|
detail: "Timeout for prompt refinement preview (30s\u2013120s)"
|
|
4724
5548
|
},
|
|
5549
|
+
{
|
|
5550
|
+
label: "Refine",
|
|
5551
|
+
value: boolVal(enhanceEnabled),
|
|
5552
|
+
detail: "Enable prompt refinement before sending"
|
|
5553
|
+
},
|
|
5554
|
+
{
|
|
5555
|
+
label: "Refine language",
|
|
5556
|
+
value: enhanceLanguage,
|
|
5557
|
+
detail: "original (keep language) | english (translate)"
|
|
5558
|
+
},
|
|
4725
5559
|
// ── Debug ──
|
|
4726
5560
|
{ section: "Debug" },
|
|
4727
5561
|
{
|
|
@@ -4883,7 +5717,55 @@ function windowRows(rows, focus, max) {
|
|
|
4883
5717
|
}
|
|
4884
5718
|
return { rows: rows.slice(start, end), start, end, contextHeader };
|
|
4885
5719
|
}
|
|
4886
|
-
function
|
|
5720
|
+
function hintsFor(ctx) {
|
|
5721
|
+
if (ctx.confirm) {
|
|
5722
|
+
return [
|
|
5723
|
+
{ key: "y", label: "yes" },
|
|
5724
|
+
{ key: "n", label: "no" },
|
|
5725
|
+
{ key: "a", label: "always" },
|
|
5726
|
+
{ key: "d", label: "deny" }
|
|
5727
|
+
];
|
|
5728
|
+
}
|
|
5729
|
+
if (ctx.picker) {
|
|
5730
|
+
return [
|
|
5731
|
+
{ key: "\u2191\u2193", label: "move" },
|
|
5732
|
+
{ key: "\u21B5", label: "select" },
|
|
5733
|
+
{ key: "Esc", label: "cancel" }
|
|
5734
|
+
];
|
|
5735
|
+
}
|
|
5736
|
+
if (ctx.monitor) {
|
|
5737
|
+
const hints = [
|
|
5738
|
+
{ key: "Esc", label: "close" },
|
|
5739
|
+
{ key: "^F", label: "fleet" },
|
|
5740
|
+
{ key: "^G", label: "agents" },
|
|
5741
|
+
{ key: "^T", label: "worktrees" },
|
|
5742
|
+
{ key: "F6", label: "todos" },
|
|
5743
|
+
{ key: "F9", label: "goal" }
|
|
5744
|
+
];
|
|
5745
|
+
if (ctx.nextPanelHint) {
|
|
5746
|
+
hints.push({ key: ctx.nextPanelHint.key, label: ctx.nextPanelHint.label, discovery: true });
|
|
5747
|
+
}
|
|
5748
|
+
return hints;
|
|
5749
|
+
}
|
|
5750
|
+
const base = [{ key: "?", label: "help" }];
|
|
5751
|
+
if (ctx.managed) base.push({ key: "PgUp/PgDn", label: "scroll" });
|
|
5752
|
+
base.push({ key: "^G", label: "agents" }, { key: "^C", label: "stop" });
|
|
5753
|
+
if (ctx.nextPanelHint) {
|
|
5754
|
+
base.push({ key: ctx.nextPanelHint.key, label: ctx.nextPanelHint.label, discovery: true });
|
|
5755
|
+
}
|
|
5756
|
+
return base;
|
|
5757
|
+
}
|
|
5758
|
+
function KeyHintBar({ context }) {
|
|
5759
|
+
const hints = hintsFor(context);
|
|
5760
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "row", paddingX: 1, children: hints.map((h, i) => (
|
|
5761
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: hints are positional + stable
|
|
5762
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", marginRight: 2, children: [
|
|
5763
|
+
/* @__PURE__ */ jsx(Text, { color: h.discovery ? theme.monitor.agents : theme.accent, children: h.key }),
|
|
5764
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ` ${h.label}` })
|
|
5765
|
+
] }, i)
|
|
5766
|
+
)) });
|
|
5767
|
+
}
|
|
5768
|
+
function TodosMonitor({ todos }) {
|
|
4887
5769
|
const { stdout } = useStdout();
|
|
4888
5770
|
const done = todos.filter((t) => t.status === "completed").length;
|
|
4889
5771
|
const inProgress = todos.filter((t) => t.status === "in_progress").length;
|
|
@@ -5224,7 +6106,7 @@ async function loadIndex(root) {
|
|
|
5224
6106
|
async function walk(root, rel, depth, out) {
|
|
5225
6107
|
if (out.length >= MAX_FILES_INDEXED) return;
|
|
5226
6108
|
if (depth > MAX_DEPTH) return;
|
|
5227
|
-
const dir = rel ?
|
|
6109
|
+
const dir = rel ? path4.join(root, rel) : root;
|
|
5228
6110
|
let entries;
|
|
5229
6111
|
try {
|
|
5230
6112
|
entries = await fs2.readdir(dir, { withFileTypes: true });
|
|
@@ -5796,11 +6678,28 @@ function useBrainEvents(events, dispatch) {
|
|
|
5796
6678
|
const offAnswered = events.on("brain.decision_answered", (payload) => addBrainEntry("answered", payload));
|
|
5797
6679
|
const offAskHuman = events.on("brain.decision_ask_human", (payload) => addBrainEntry("ask_human", payload));
|
|
5798
6680
|
const offDenied = events.on("brain.decision_denied", (payload) => addBrainEntry("denied", payload));
|
|
6681
|
+
const offIntervention = events.on("brain.intervention", (payload) => {
|
|
6682
|
+
const decision = payload.intervened ? `steered the agent (${payload.kind.replace(/_/g, " ")})` : "observed \u2014 no action needed";
|
|
6683
|
+
const rationale = payload.decision.type === "answer" ? payload.decision.rationale : void 0;
|
|
6684
|
+
dispatch({
|
|
6685
|
+
type: "addEntry",
|
|
6686
|
+
entry: {
|
|
6687
|
+
kind: "brain",
|
|
6688
|
+
status: "intervention",
|
|
6689
|
+
source: "monitor",
|
|
6690
|
+
risk: payload.request.risk,
|
|
6691
|
+
question: payload.request.question,
|
|
6692
|
+
decision,
|
|
6693
|
+
rationale
|
|
6694
|
+
}
|
|
6695
|
+
});
|
|
6696
|
+
});
|
|
5799
6697
|
return () => {
|
|
5800
6698
|
offRequested();
|
|
5801
6699
|
offAnswered();
|
|
5802
6700
|
offAskHuman();
|
|
5803
6701
|
offDenied();
|
|
6702
|
+
offIntervention();
|
|
5804
6703
|
};
|
|
5805
6704
|
}, [events, dispatch]);
|
|
5806
6705
|
}
|
|
@@ -5812,7 +6711,7 @@ function labelFor2(labelsRef, id, name) {
|
|
|
5812
6711
|
const n = m.size + 1;
|
|
5813
6712
|
const v = {
|
|
5814
6713
|
label: name && name !== id ? name : `AGENT#${n}`,
|
|
5815
|
-
color: expectDefined(STREAM_COLORS2[(n - 1) % STREAM_COLORS2.length])
|
|
6714
|
+
color: expectDefined$1(STREAM_COLORS2[(n - 1) % STREAM_COLORS2.length])
|
|
5816
6715
|
};
|
|
5817
6716
|
m.set(id, v);
|
|
5818
6717
|
return v;
|
|
@@ -6081,6 +6980,10 @@ function useAutoPhaseEvents(subscribeAutoPhase, dispatch, stateRef) {
|
|
|
6081
6980
|
if (!p.kept) dispatch({ type: "worktreeRemove", handleId: p.handleId });
|
|
6082
6981
|
break;
|
|
6083
6982
|
}
|
|
6983
|
+
case "countdown.tick": {
|
|
6984
|
+
dispatch({ type: "countdownTick", remainingSeconds: payload.remaining });
|
|
6985
|
+
break;
|
|
6986
|
+
}
|
|
6084
6987
|
}
|
|
6085
6988
|
};
|
|
6086
6989
|
return subscribeAutoPhase(handler);
|
|
@@ -6341,6 +7244,52 @@ function buildSteeringPreamble(snapshot, newDirection) {
|
|
|
6341
7244
|
lines.push("]");
|
|
6342
7245
|
return lines.join("\n");
|
|
6343
7246
|
}
|
|
7247
|
+
var MAX_TOOL_STREAM_RETAINED_CHARS = 1e5;
|
|
7248
|
+
var MAX_RETAINED_INPUT_CHARS = 2048;
|
|
7249
|
+
var MAX_RETAINED_INPUT_DEPTH = 4;
|
|
7250
|
+
var MAX_RETAINED_INPUT_ITEMS = 64;
|
|
7251
|
+
function pruneToolInput(value, depth = 0) {
|
|
7252
|
+
if (typeof value === "string") {
|
|
7253
|
+
return value.length > MAX_RETAINED_INPUT_CHARS ? `${value.slice(0, MAX_RETAINED_INPUT_CHARS)}\u2026 [truncated, ${value.length} chars \u2014 full payload in session log]` : value;
|
|
7254
|
+
}
|
|
7255
|
+
if (value === null || typeof value !== "object") return value;
|
|
7256
|
+
if (depth >= MAX_RETAINED_INPUT_DEPTH) return "[pruned: too deep]";
|
|
7257
|
+
if (Array.isArray(value)) {
|
|
7258
|
+
const head = value.slice(0, MAX_RETAINED_INPUT_ITEMS).map((v) => pruneToolInput(v, depth + 1));
|
|
7259
|
+
if (value.length > MAX_RETAINED_INPUT_ITEMS) {
|
|
7260
|
+
head.push(`[pruned: ${value.length - MAX_RETAINED_INPUT_ITEMS} more items]`);
|
|
7261
|
+
}
|
|
7262
|
+
return head;
|
|
7263
|
+
}
|
|
7264
|
+
const out = {};
|
|
7265
|
+
let n = 0;
|
|
7266
|
+
for (const [k, v] of Object.entries(value)) {
|
|
7267
|
+
if (n++ >= MAX_RETAINED_INPUT_ITEMS) {
|
|
7268
|
+
out["\u2026"] = "[pruned: more keys]";
|
|
7269
|
+
break;
|
|
7270
|
+
}
|
|
7271
|
+
out[k] = pruneToolInput(v, depth + 1);
|
|
7272
|
+
}
|
|
7273
|
+
return out;
|
|
7274
|
+
}
|
|
7275
|
+
function firstSelectable(items) {
|
|
7276
|
+
const idx = items.findIndex((it) => it.key !== "__divider__");
|
|
7277
|
+
return idx >= 0 ? idx : 0;
|
|
7278
|
+
}
|
|
7279
|
+
function skipDivider(items, idx, dir) {
|
|
7280
|
+
let i = idx;
|
|
7281
|
+
for (let steps = 0; steps < items.length; steps++) {
|
|
7282
|
+
const item = items[i];
|
|
7283
|
+
if (!item || item.key === "__divider__") {
|
|
7284
|
+
i += dir;
|
|
7285
|
+
if (i < 0) i = items.length - 1;
|
|
7286
|
+
if (i >= items.length) i = 0;
|
|
7287
|
+
continue;
|
|
7288
|
+
}
|
|
7289
|
+
return i;
|
|
7290
|
+
}
|
|
7291
|
+
return idx;
|
|
7292
|
+
}
|
|
6344
7293
|
function reducer(state, action) {
|
|
6345
7294
|
switch (action.type) {
|
|
6346
7295
|
case "addEntry": {
|
|
@@ -6348,7 +7297,8 @@ function reducer(state, action) {
|
|
|
6348
7297
|
if ((e.kind === "user" || e.kind === "assistant" || e.kind === "info" || e.kind === "warn" || e.kind === "error" || e.kind === "turn-summary") && !e.text?.trim()) {
|
|
6349
7298
|
return state;
|
|
6350
7299
|
}
|
|
6351
|
-
const
|
|
7300
|
+
const stored = e.kind === "tool" && e.input !== void 0 ? { ...e, input: pruneToolInput(e.input) } : e;
|
|
7301
|
+
const appended = [...state.entries, { ...stored, id: state.nextId }];
|
|
6352
7302
|
return { ...state, entries: appended, nextId: state.nextId + 1 };
|
|
6353
7303
|
}
|
|
6354
7304
|
case "setBuffer":
|
|
@@ -6472,9 +7422,11 @@ function reducer(state, action) {
|
|
|
6472
7422
|
case "toolStreamAppend": {
|
|
6473
7423
|
const cur = state.toolStream;
|
|
6474
7424
|
if (cur && cur.toolUseId === action.toolUseId) {
|
|
7425
|
+
const combined = cur.text + action.text;
|
|
7426
|
+
const text = combined.length > MAX_TOOL_STREAM_RETAINED_CHARS ? combined.slice(-MAX_TOOL_STREAM_RETAINED_CHARS) : combined;
|
|
6475
7427
|
return {
|
|
6476
7428
|
...state,
|
|
6477
|
-
toolStream: { ...cur, text
|
|
7429
|
+
toolStream: { ...cur, text }
|
|
6478
7430
|
};
|
|
6479
7431
|
}
|
|
6480
7432
|
return {
|
|
@@ -6661,6 +7613,35 @@ function reducer(state, action) {
|
|
|
6661
7613
|
...state,
|
|
6662
7614
|
autonomyPicker: { ...state.autonomyPicker, hint: action.text }
|
|
6663
7615
|
};
|
|
7616
|
+
case "resumePickerOpen":
|
|
7617
|
+
return {
|
|
7618
|
+
...state,
|
|
7619
|
+
resumePicker: { open: true, sessions: action.sessions, selected: 0, busy: false, hint: void 0, error: void 0 }
|
|
7620
|
+
};
|
|
7621
|
+
case "resumePickerClose":
|
|
7622
|
+
return {
|
|
7623
|
+
...state,
|
|
7624
|
+
resumePicker: { open: false, sessions: [], selected: 0, busy: false, hint: void 0, error: void 0 }
|
|
7625
|
+
};
|
|
7626
|
+
case "resumePickerMove": {
|
|
7627
|
+
const nr = state.resumePicker.sessions.length;
|
|
7628
|
+
if (nr === 0) return state;
|
|
7629
|
+
const nextR = (state.resumePicker.selected + action.delta + nr) % nr;
|
|
7630
|
+
return { ...state, resumePicker: { ...state.resumePicker, selected: nextR } };
|
|
7631
|
+
}
|
|
7632
|
+
case "resumePickerBusy":
|
|
7633
|
+
return { ...state, resumePicker: { ...state.resumePicker, busy: action.on } };
|
|
7634
|
+
case "resumePickerHint":
|
|
7635
|
+
return { ...state, resumePicker: { ...state.resumePicker, hint: action.text } };
|
|
7636
|
+
case "resumePickerError":
|
|
7637
|
+
return { ...state, resumePicker: { ...state.resumePicker, error: action.text, busy: false } };
|
|
7638
|
+
case "replaceHistory": {
|
|
7639
|
+
const banners = state.entries.filter((e) => e.kind === "banner");
|
|
7640
|
+
const maxBannerId = banners.length > 0 ? Math.max(...banners.map((b) => b.id)) : 0;
|
|
7641
|
+
const shifted = action.entries.map((e, i) => ({ ...e, id: maxBannerId + 1 + i }));
|
|
7642
|
+
const nextId = maxBannerId + 1 + shifted.length;
|
|
7643
|
+
return { ...state, entries: [...banners, ...shifted], nextId, historyGen: state.historyGen + 1 };
|
|
7644
|
+
}
|
|
6664
7645
|
case "settingsOpen":
|
|
6665
7646
|
return {
|
|
6666
7647
|
...state,
|
|
@@ -6688,6 +7669,8 @@ function reducer(state, action) {
|
|
|
6688
7669
|
maxIterations: action.maxIterations,
|
|
6689
7670
|
autoProceedMaxIterations: action.autoProceedMaxIterations,
|
|
6690
7671
|
enhanceDelayMs: action.enhanceDelayMs,
|
|
7672
|
+
enhanceEnabled: action.enhanceEnabled,
|
|
7673
|
+
enhanceLanguage: action.enhanceLanguage,
|
|
6691
7674
|
debugStream: action.debugStream,
|
|
6692
7675
|
configScope: action.configScope,
|
|
6693
7676
|
hint: void 0
|
|
@@ -6716,13 +7699,13 @@ function reducer(state, action) {
|
|
|
6716
7699
|
const i = SETTINGS_MODES.indexOf(sp.mode);
|
|
6717
7700
|
const base = i < 0 ? 0 : i;
|
|
6718
7701
|
const next = (base + action.delta + SETTINGS_MODES.length) % SETTINGS_MODES.length;
|
|
6719
|
-
return { ...state, settingsPicker: { ...sp, mode: expectDefined(SETTINGS_MODES[next]), hint: void 0 } };
|
|
7702
|
+
return { ...state, settingsPicker: { ...sp, mode: expectDefined$1(SETTINGS_MODES[next]), hint: void 0 } };
|
|
6720
7703
|
}
|
|
6721
7704
|
if (f === 1) {
|
|
6722
7705
|
const j = DELAY_PRESETS_MS.indexOf(sp.delayMs);
|
|
6723
7706
|
const base = j < 0 ? 0 : j;
|
|
6724
7707
|
const next = (base + action.delta + DELAY_PRESETS_MS.length) % DELAY_PRESETS_MS.length;
|
|
6725
|
-
return { ...state, settingsPicker: { ...sp, delayMs: expectDefined(DELAY_PRESETS_MS[next]), hint: void 0 } };
|
|
7708
|
+
return { ...state, settingsPicker: { ...sp, delayMs: expectDefined$1(DELAY_PRESETS_MS[next]), hint: void 0 } };
|
|
6726
7709
|
}
|
|
6727
7710
|
if (f === 2) return { ...state, settingsPicker: { ...sp, titleAnimation: !sp.titleAnimation, hint: void 0 } };
|
|
6728
7711
|
if (f === 3) return { ...state, settingsPicker: { ...sp, yolo: !sp.yolo, hint: void 0 } };
|
|
@@ -6740,50 +7723,99 @@ function reducer(state, action) {
|
|
|
6740
7723
|
const i = COMPACTOR_STRATEGIES.indexOf(sp.contextStrategy);
|
|
6741
7724
|
const base = i < 0 ? 0 : i;
|
|
6742
7725
|
const next = (base + action.delta + COMPACTOR_STRATEGIES.length) % COMPACTOR_STRATEGIES.length;
|
|
6743
|
-
return { ...state, settingsPicker: { ...sp, contextStrategy: expectDefined(COMPACTOR_STRATEGIES[next]), hint: void 0 } };
|
|
7726
|
+
return { ...state, settingsPicker: { ...sp, contextStrategy: expectDefined$1(COMPACTOR_STRATEGIES[next]), hint: void 0 } };
|
|
6744
7727
|
}
|
|
6745
7728
|
if (f === 15) {
|
|
6746
7729
|
const i = LOG_LEVELS.indexOf(sp.logLevel);
|
|
6747
7730
|
const base = i < 0 ? 0 : i;
|
|
6748
7731
|
const next = (base + action.delta + LOG_LEVELS.length) % LOG_LEVELS.length;
|
|
6749
|
-
return { ...state, settingsPicker: { ...sp, logLevel: expectDefined(LOG_LEVELS[next]), hint: void 0 } };
|
|
7732
|
+
return { ...state, settingsPicker: { ...sp, logLevel: expectDefined$1(LOG_LEVELS[next]), hint: void 0 } };
|
|
6750
7733
|
}
|
|
6751
7734
|
if (f === 16) {
|
|
6752
7735
|
const i = AUDIT_LEVELS.indexOf(sp.auditLevel);
|
|
6753
7736
|
const base = i < 0 ? 0 : i;
|
|
6754
7737
|
const next = (base + action.delta + AUDIT_LEVELS.length) % AUDIT_LEVELS.length;
|
|
6755
|
-
return { ...state, settingsPicker: { ...sp, auditLevel: expectDefined(AUDIT_LEVELS[next]), hint: void 0 } };
|
|
7738
|
+
return { ...state, settingsPicker: { ...sp, auditLevel: expectDefined$1(AUDIT_LEVELS[next]), hint: void 0 } };
|
|
6756
7739
|
}
|
|
6757
7740
|
if (f === 17) return { ...state, settingsPicker: { ...sp, indexOnStart: !sp.indexOnStart, hint: void 0 } };
|
|
6758
7741
|
if (f === 18) {
|
|
6759
7742
|
const j = MAX_ITERATIONS_PRESETS.indexOf(sp.maxIterations);
|
|
6760
7743
|
const base = j < 0 ? 0 : j;
|
|
6761
7744
|
const next = (base + action.delta + MAX_ITERATIONS_PRESETS.length) % MAX_ITERATIONS_PRESETS.length;
|
|
6762
|
-
return { ...state, settingsPicker: { ...sp, maxIterations: expectDefined(MAX_ITERATIONS_PRESETS[next]), hint: void 0 } };
|
|
7745
|
+
return { ...state, settingsPicker: { ...sp, maxIterations: expectDefined$1(MAX_ITERATIONS_PRESETS[next]), hint: void 0 } };
|
|
6763
7746
|
}
|
|
6764
7747
|
if (f === 19) {
|
|
6765
7748
|
const aj = AUTO_PROCEED_MAX_PRESETS.indexOf(sp.autoProceedMaxIterations);
|
|
6766
7749
|
const abase = aj < 0 ? 0 : aj;
|
|
6767
7750
|
const anext = (abase + action.delta + AUTO_PROCEED_MAX_PRESETS.length) % AUTO_PROCEED_MAX_PRESETS.length;
|
|
6768
|
-
return { ...state, settingsPicker: { ...sp, autoProceedMaxIterations: expectDefined(AUTO_PROCEED_MAX_PRESETS[anext]), hint: void 0 } };
|
|
7751
|
+
return { ...state, settingsPicker: { ...sp, autoProceedMaxIterations: expectDefined$1(AUTO_PROCEED_MAX_PRESETS[anext]), hint: void 0 } };
|
|
6769
7752
|
}
|
|
6770
7753
|
if (f === 20) {
|
|
6771
7754
|
const ej = ENHANCE_DELAY_PRESETS.indexOf(sp.enhanceDelayMs);
|
|
6772
7755
|
const ebase = ej < 0 ? 0 : ej;
|
|
6773
7756
|
const enext = (ebase + action.delta + ENHANCE_DELAY_PRESETS.length) % ENHANCE_DELAY_PRESETS.length;
|
|
6774
|
-
return { ...state, settingsPicker: { ...sp, enhanceDelayMs: expectDefined(ENHANCE_DELAY_PRESETS[enext]), hint: void 0 } };
|
|
7757
|
+
return { ...state, settingsPicker: { ...sp, enhanceDelayMs: expectDefined$1(ENHANCE_DELAY_PRESETS[enext]), hint: void 0 } };
|
|
6775
7758
|
}
|
|
6776
|
-
if (f ===
|
|
6777
|
-
if (f ===
|
|
7759
|
+
if (f === 20) return { ...state, settingsPicker: { ...sp, debugStream: !sp.debugStream, hint: void 0 } };
|
|
7760
|
+
if (f === 21) {
|
|
6778
7761
|
const i = CONFIG_SCOPES.indexOf(sp.configScope);
|
|
6779
7762
|
const base = i < 0 ? 0 : i;
|
|
6780
7763
|
const next = (base + action.delta + CONFIG_SCOPES.length) % CONFIG_SCOPES.length;
|
|
6781
|
-
return { ...state, settingsPicker: { ...sp, configScope: expectDefined(CONFIG_SCOPES[next]), hint: void 0 } };
|
|
7764
|
+
return { ...state, settingsPicker: { ...sp, configScope: expectDefined$1(CONFIG_SCOPES[next]), hint: void 0 } };
|
|
7765
|
+
}
|
|
7766
|
+
if (f === 22) return { ...state, settingsPicker: { ...sp, enhanceEnabled: !sp.enhanceEnabled, hint: void 0 } };
|
|
7767
|
+
if (f === 23) {
|
|
7768
|
+
const i = ENHANCE_LANGUAGES.indexOf(sp.enhanceLanguage);
|
|
7769
|
+
const base = i < 0 ? 0 : i;
|
|
7770
|
+
const next = (base + action.delta + ENHANCE_LANGUAGES.length) % ENHANCE_LANGUAGES.length;
|
|
7771
|
+
return { ...state, settingsPicker: { ...sp, enhanceLanguage: expectDefined$1(ENHANCE_LANGUAGES[next]), hint: void 0 } };
|
|
6782
7772
|
}
|
|
6783
7773
|
return state;
|
|
6784
7774
|
}
|
|
6785
7775
|
case "settingsHint":
|
|
6786
7776
|
return { ...state, settingsPicker: { ...state.settingsPicker, hint: action.text } };
|
|
7777
|
+
case "projectPickerOpen":
|
|
7778
|
+
return {
|
|
7779
|
+
...state,
|
|
7780
|
+
projectPicker: {
|
|
7781
|
+
open: true,
|
|
7782
|
+
allItems: action.items,
|
|
7783
|
+
items: action.items,
|
|
7784
|
+
selected: firstSelectable(action.items),
|
|
7785
|
+
filter: "",
|
|
7786
|
+
hint: void 0
|
|
7787
|
+
}
|
|
7788
|
+
};
|
|
7789
|
+
case "projectPickerClose":
|
|
7790
|
+
return {
|
|
7791
|
+
...state,
|
|
7792
|
+
projectPicker: { open: false, allItems: [], items: [], selected: 0, filter: "", hint: void 0 }
|
|
7793
|
+
};
|
|
7794
|
+
case "projectPickerMove": {
|
|
7795
|
+
const cur = state.projectPicker;
|
|
7796
|
+
const list = cur.items;
|
|
7797
|
+
if (list.length === 0) return state;
|
|
7798
|
+
const nextRaw = (cur.selected + action.delta + list.length) % list.length;
|
|
7799
|
+
const next = skipDivider(list, nextRaw, action.delta > 0 ? 1 : -1);
|
|
7800
|
+
return { ...state, projectPicker: { ...cur, selected: next } };
|
|
7801
|
+
}
|
|
7802
|
+
case "projectPickerFilter": {
|
|
7803
|
+
const cur = state.projectPicker;
|
|
7804
|
+
const filtered = action.filter ? cur.allItems.filter(
|
|
7805
|
+
(item) => item.kind !== "project" || item.label.toLowerCase().includes(action.filter.toLowerCase()) || (item.subtitle ?? "").toLowerCase().includes(action.filter.toLowerCase())
|
|
7806
|
+
) : cur.allItems;
|
|
7807
|
+
return {
|
|
7808
|
+
...state,
|
|
7809
|
+
projectPicker: {
|
|
7810
|
+
...cur,
|
|
7811
|
+
filter: action.filter,
|
|
7812
|
+
items: filtered,
|
|
7813
|
+
selected: firstSelectable(filtered)
|
|
7814
|
+
}
|
|
7815
|
+
};
|
|
7816
|
+
}
|
|
7817
|
+
case "projectPickerHint":
|
|
7818
|
+
return { ...state, projectPicker: { ...state.projectPicker, hint: action.text } };
|
|
6787
7819
|
case "confirmOpen":
|
|
6788
7820
|
return { ...state, confirmQueue: [...state.confirmQueue, action.info] };
|
|
6789
7821
|
case "confirmClose":
|
|
@@ -7459,6 +8491,47 @@ function reducer(state, action) {
|
|
|
7459
8491
|
if (state.debugStreamStats === null) return state;
|
|
7460
8492
|
return { ...state, debugStreamStats: null };
|
|
7461
8493
|
}
|
|
8494
|
+
case "toggleSessionsPanel": {
|
|
8495
|
+
return { ...state, sessionsPanelOpen: !state.sessionsPanelOpen };
|
|
8496
|
+
}
|
|
8497
|
+
case "sessionsPanelSet": {
|
|
8498
|
+
return {
|
|
8499
|
+
...state,
|
|
8500
|
+
sessionsPanel: { sessions: action.sessions, busy: false, selected: action.sessions.length > 0 ? 0 : -1 }
|
|
8501
|
+
};
|
|
8502
|
+
}
|
|
8503
|
+
case "sessionsPanelMove": {
|
|
8504
|
+
const cur = state.sessionsPanel;
|
|
8505
|
+
if (cur.sessions.length === 0) return state;
|
|
8506
|
+
const next = (cur.selected + action.delta + cur.sessions.length) % cur.sessions.length;
|
|
8507
|
+
return { ...state, sessionsPanel: { ...cur, selected: next } };
|
|
8508
|
+
}
|
|
8509
|
+
case "sessionsPanelBusy": {
|
|
8510
|
+
return {
|
|
8511
|
+
...state,
|
|
8512
|
+
sessionsPanel: { ...state.sessionsPanel, busy: action.on }
|
|
8513
|
+
};
|
|
8514
|
+
}
|
|
8515
|
+
case "sessionResumeConfirmSet": {
|
|
8516
|
+
return {
|
|
8517
|
+
...state,
|
|
8518
|
+
sessionResumeConfirm: { sessionId: action.sessionId, sessionName: action.sessionName }
|
|
8519
|
+
};
|
|
8520
|
+
}
|
|
8521
|
+
case "sessionResumeConfirmClear": {
|
|
8522
|
+
return { ...state, sessionResumeConfirm: null };
|
|
8523
|
+
}
|
|
8524
|
+
// --- Auto-proceed countdown ---
|
|
8525
|
+
case "countdownTick": {
|
|
8526
|
+
if (action.remainingSeconds <= 0) {
|
|
8527
|
+
return state.countdown ? { ...state, countdown: null } : state;
|
|
8528
|
+
}
|
|
8529
|
+
return { ...state, countdown: { remainingSeconds: action.remainingSeconds } };
|
|
8530
|
+
}
|
|
8531
|
+
case "countdownEnded": {
|
|
8532
|
+
if (state.countdown === null) return state;
|
|
8533
|
+
return { ...state, countdown: null };
|
|
8534
|
+
}
|
|
7462
8535
|
}
|
|
7463
8536
|
}
|
|
7464
8537
|
var INPUT_PROMPT = "\u203A ";
|
|
@@ -7467,7 +8540,7 @@ function selectedSlashCommandLine(picker) {
|
|
|
7467
8540
|
const picked = picker.matches[picker.selected];
|
|
7468
8541
|
return picked ? `/${picked.name}` : null;
|
|
7469
8542
|
}
|
|
7470
|
-
function rehydrateHistory(messages, startId) {
|
|
8543
|
+
function rehydrateHistory(messages, startId, toolCalls) {
|
|
7471
8544
|
const entries = [];
|
|
7472
8545
|
let nextId = startId;
|
|
7473
8546
|
for (const msg of messages) {
|
|
@@ -7481,6 +8554,20 @@ function rehydrateHistory(messages, startId) {
|
|
|
7481
8554
|
entries.push({ id: nextId++, kind: "assistant", text: trimmed });
|
|
7482
8555
|
}
|
|
7483
8556
|
}
|
|
8557
|
+
if (toolCalls && toolCalls.length > 0) {
|
|
8558
|
+
for (const tc of toolCalls) {
|
|
8559
|
+
entries.push({
|
|
8560
|
+
id: nextId++,
|
|
8561
|
+
kind: "tool",
|
|
8562
|
+
name: tc.name,
|
|
8563
|
+
durationMs: tc.durationMs,
|
|
8564
|
+
ok: tc.ok,
|
|
8565
|
+
outputBytes: tc.outputBytes,
|
|
8566
|
+
outputTokens: tc.outputTokens,
|
|
8567
|
+
outputLines: tc.outputLines
|
|
8568
|
+
});
|
|
8569
|
+
}
|
|
8570
|
+
}
|
|
7484
8571
|
return entries;
|
|
7485
8572
|
}
|
|
7486
8573
|
var PASTE_THRESHOLD_CHARS = 200;
|
|
@@ -7495,9 +8582,11 @@ function App({
|
|
|
7495
8582
|
model,
|
|
7496
8583
|
banner = true,
|
|
7497
8584
|
queueStore,
|
|
8585
|
+
onQueueChange,
|
|
7498
8586
|
yolo = false,
|
|
7499
8587
|
chime = false,
|
|
7500
8588
|
confirmExit = true,
|
|
8589
|
+
mouse = false,
|
|
7501
8590
|
enhanceEnabled = true,
|
|
7502
8591
|
enhanceController,
|
|
7503
8592
|
enhanceDelayMs = 15e3,
|
|
@@ -7519,12 +8608,16 @@ function App({
|
|
|
7519
8608
|
getSettings,
|
|
7520
8609
|
saveSettings,
|
|
7521
8610
|
predictNext,
|
|
8611
|
+
onSuggestionsParsed,
|
|
8612
|
+
getSuggestions,
|
|
7522
8613
|
switchAutonomy,
|
|
7523
8614
|
effectiveMaxContext,
|
|
7524
8615
|
onExit,
|
|
7525
8616
|
director,
|
|
7526
8617
|
fleetRoster,
|
|
7527
8618
|
onClearHistory,
|
|
8619
|
+
listSessions,
|
|
8620
|
+
onResumeSession,
|
|
7528
8621
|
fleetStreamController,
|
|
7529
8622
|
statuslineHiddenItems,
|
|
7530
8623
|
setStatuslineHiddenItems,
|
|
@@ -7535,7 +8628,14 @@ function App({
|
|
|
7535
8628
|
modeLabel,
|
|
7536
8629
|
getModeLabel,
|
|
7537
8630
|
registerDebugStreamCallback,
|
|
7538
|
-
restoreDebugStreamCallback
|
|
8631
|
+
restoreDebugStreamCallback,
|
|
8632
|
+
restoredToolCalls,
|
|
8633
|
+
getProjectPickerItems,
|
|
8634
|
+
onProjectSelect,
|
|
8635
|
+
requestExit,
|
|
8636
|
+
getLiveSessions,
|
|
8637
|
+
onSwitchToSession,
|
|
8638
|
+
initialAgentsMonitorOpen
|
|
7539
8639
|
}) {
|
|
7540
8640
|
const { exit } = useApp();
|
|
7541
8641
|
const { stdout } = useStdout();
|
|
@@ -7546,6 +8646,8 @@ function App({
|
|
|
7546
8646
|
const [autonomyLive, setAutonomyLive] = useState(getAutonomy?.() ?? "off");
|
|
7547
8647
|
const [liveModeLabel, setLiveModeLabel] = useState(modeLabel ?? "");
|
|
7548
8648
|
const [hiddenItems, setHiddenItems] = useState(statuslineHiddenItems);
|
|
8649
|
+
const [sessionCount, setSessionCount] = useState(0);
|
|
8650
|
+
const prevBranchRef = useRef(null);
|
|
7549
8651
|
const [indexState, setIndexState] = useState(() => getIndexState());
|
|
7550
8652
|
useEffect(() => {
|
|
7551
8653
|
setIndexState(getIndexState());
|
|
@@ -7596,7 +8698,8 @@ function App({
|
|
|
7596
8698
|
return rehydrateHistory(
|
|
7597
8699
|
visible,
|
|
7598
8700
|
/* startId */
|
|
7599
|
-
1
|
|
8701
|
+
1,
|
|
8702
|
+
restoredToolCalls
|
|
7600
8703
|
);
|
|
7601
8704
|
})();
|
|
7602
8705
|
const initialNextId = 1 + restoredEntries.length;
|
|
@@ -7616,6 +8719,7 @@ function App({
|
|
|
7616
8719
|
] : [],
|
|
7617
8720
|
...restoredEntries
|
|
7618
8721
|
],
|
|
8722
|
+
historyGen: 0,
|
|
7619
8723
|
buffer: "",
|
|
7620
8724
|
cursor: 0,
|
|
7621
8725
|
streamingText: "",
|
|
@@ -7645,7 +8749,9 @@ function App({
|
|
|
7645
8749
|
searchQuery: ""
|
|
7646
8750
|
},
|
|
7647
8751
|
autonomyPicker: { open: false, options: [], selected: 0 },
|
|
7648
|
-
|
|
8752
|
+
resumePicker: { open: false, sessions: [], selected: 0, busy: false, hint: void 0, error: void 0 },
|
|
8753
|
+
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, contextAutoCompact: true, contextStrategy: "hybrid", logLevel: "info", auditLevel: "standard", indexOnStart: true, maxIterations: 500, autoProceedMaxIterations: 50, enhanceDelayMs: 6e4, enhanceEnabled: true, enhanceLanguage: "original", debugStream: false, configScope: "global" },
|
|
8754
|
+
projectPicker: { open: false, allItems: [], items: [], selected: 0, filter: "", hint: void 0 },
|
|
7649
8755
|
confirmQueue: [],
|
|
7650
8756
|
enhance: null,
|
|
7651
8757
|
enhanceEnabled,
|
|
@@ -7667,12 +8773,15 @@ function App({
|
|
|
7667
8773
|
fleetConcurrency: 4,
|
|
7668
8774
|
streamFleet: true,
|
|
7669
8775
|
monitorOpen: false,
|
|
7670
|
-
agentsMonitorOpen: false,
|
|
8776
|
+
agentsMonitorOpen: initialAgentsMonitorOpen ?? false,
|
|
7671
8777
|
helpOpen: false,
|
|
7672
8778
|
todosMonitorOpen: false,
|
|
7673
8779
|
queuePanelOpen: false,
|
|
7674
8780
|
processListOpen: false,
|
|
7675
8781
|
goalPanelOpen: false,
|
|
8782
|
+
sessionsPanelOpen: false,
|
|
8783
|
+
sessionsPanel: { sessions: [], busy: false, selected: -1 },
|
|
8784
|
+
sessionResumeConfirm: null,
|
|
7676
8785
|
collabSession: null,
|
|
7677
8786
|
checkpoints: [],
|
|
7678
8787
|
rewindOverlay: null,
|
|
@@ -7685,7 +8794,8 @@ function App({
|
|
|
7685
8794
|
totalLines: 0,
|
|
7686
8795
|
viewportRows: 0,
|
|
7687
8796
|
pendingNewLines: 0,
|
|
7688
|
-
debugStreamStats: null
|
|
8797
|
+
debugStreamStats: null,
|
|
8798
|
+
countdown: null
|
|
7689
8799
|
});
|
|
7690
8800
|
const builderRef = useRef(null);
|
|
7691
8801
|
if (builderRef.current === null) {
|
|
@@ -7699,9 +8809,23 @@ function App({
|
|
|
7699
8809
|
const lastEnterAtRef = useRef(0);
|
|
7700
8810
|
const tokenPreviewsRef = useRef(/* @__PURE__ */ new Map());
|
|
7701
8811
|
const projectName = React5.useMemo(() => {
|
|
7702
|
-
const base =
|
|
7703
|
-
return base && base !==
|
|
8812
|
+
const base = path4.basename(projectRoot);
|
|
8813
|
+
return base && base !== path4.sep ? base : void 0;
|
|
7704
8814
|
}, [projectRoot]);
|
|
8815
|
+
const [workingDirChip, setWorkingDirChip] = React5.useState(() => {
|
|
8816
|
+
const ctx = agent.ctx;
|
|
8817
|
+
if (ctx.workingDir && ctx.workingDir !== projectRoot) {
|
|
8818
|
+
return path4.relative(projectRoot, ctx.workingDir) || ".";
|
|
8819
|
+
}
|
|
8820
|
+
return void 0;
|
|
8821
|
+
});
|
|
8822
|
+
React5.useEffect(() => {
|
|
8823
|
+
const ctx = agent.ctx;
|
|
8824
|
+
return ctx.onWorkingDirChanged((newDir) => {
|
|
8825
|
+
const rel = path4.relative(projectRoot, newDir) || ".";
|
|
8826
|
+
setWorkingDirChip(rel === "." ? void 0 : rel);
|
|
8827
|
+
});
|
|
8828
|
+
}, [agent.ctx, projectRoot]);
|
|
7705
8829
|
const chimeRef = useRef(chime);
|
|
7706
8830
|
chimeRef.current = chime;
|
|
7707
8831
|
const confirmExitRef = useRef(confirmExit);
|
|
@@ -7713,6 +8837,48 @@ function App({
|
|
|
7713
8837
|
stateRef.current = state;
|
|
7714
8838
|
const draftRef = useRef({ buffer: state.buffer, cursor: state.cursor });
|
|
7715
8839
|
draftRef.current = { buffer: state.buffer, cursor: state.cursor };
|
|
8840
|
+
const [mouseMode, setMouseMode] = useState(mouse);
|
|
8841
|
+
const pickerOverlayOpen = state.modelPicker.open || state.autonomyPicker.open || state.settingsPicker.open || state.projectPicker.open || state.slashPicker.open || state.picker.open;
|
|
8842
|
+
const mouseTrackingOn = mouseMode || pickerOverlayOpen;
|
|
8843
|
+
const mouseWrittenRef = useRef(false);
|
|
8844
|
+
useEffect(() => {
|
|
8845
|
+
if (mouseWrittenRef.current === mouseTrackingOn) return;
|
|
8846
|
+
mouseWrittenRef.current = mouseTrackingOn;
|
|
8847
|
+
try {
|
|
8848
|
+
process.stdout.write(mouseTrackingOn ? MOUSE_CLICK_ON : MOUSE_OFF);
|
|
8849
|
+
} catch {
|
|
8850
|
+
}
|
|
8851
|
+
}, [mouseTrackingOn]);
|
|
8852
|
+
useEffect(
|
|
8853
|
+
() => () => {
|
|
8854
|
+
try {
|
|
8855
|
+
process.stdout.write(MOUSE_OFF);
|
|
8856
|
+
} catch {
|
|
8857
|
+
}
|
|
8858
|
+
},
|
|
8859
|
+
[]
|
|
8860
|
+
);
|
|
8861
|
+
const bottomRegionRef = useRef(null);
|
|
8862
|
+
const statusBarWrapRef = useRef(null);
|
|
8863
|
+
const belowStatusBarRef = useRef(null);
|
|
8864
|
+
const [termRows, setTermRows] = useState(stdout?.rows ?? 24);
|
|
8865
|
+
useEffect(() => {
|
|
8866
|
+
const onResize = () => setTermRows(process.stdout.rows ?? 24);
|
|
8867
|
+
process.stdout.on("resize", onResize);
|
|
8868
|
+
return () => {
|
|
8869
|
+
process.stdout.off("resize", onResize);
|
|
8870
|
+
};
|
|
8871
|
+
}, []);
|
|
8872
|
+
useLayoutEffect(() => {
|
|
8873
|
+
if (!mouseMode) return;
|
|
8874
|
+
const node = bottomRegionRef.current;
|
|
8875
|
+
if (!node) return;
|
|
8876
|
+
const { height } = measureElement(node);
|
|
8877
|
+
const vp = Math.max(1, termRows - height);
|
|
8878
|
+
if (vp !== stateRef.current.viewportRows) {
|
|
8879
|
+
dispatch({ type: "setViewportRows", rows: vp });
|
|
8880
|
+
}
|
|
8881
|
+
});
|
|
7716
8882
|
const handleKeyRef = useRef(null);
|
|
7717
8883
|
const handleRewindTo = React5.useCallback(
|
|
7718
8884
|
async (checkpointIndex) => {
|
|
@@ -7738,6 +8904,35 @@ function App({
|
|
|
7738
8904
|
const t = setInterval(() => setNowTick(Date.now()), 1e4);
|
|
7739
8905
|
return () => clearInterval(t);
|
|
7740
8906
|
}, []);
|
|
8907
|
+
useEffect(() => {
|
|
8908
|
+
const approxChars = (v) => {
|
|
8909
|
+
try {
|
|
8910
|
+
return JSON.stringify(v)?.length ?? 0;
|
|
8911
|
+
} catch {
|
|
8912
|
+
return -1;
|
|
8913
|
+
}
|
|
8914
|
+
};
|
|
8915
|
+
return startHeapWatchdog({
|
|
8916
|
+
collectStats: () => ({
|
|
8917
|
+
historyEntries: stateRef.current.entries.length,
|
|
8918
|
+
historyChars: approxChars(stateRef.current.entries),
|
|
8919
|
+
messages: agent.ctx.state.messages.length,
|
|
8920
|
+
messagesChars: approxChars(agent.ctx.state.messages),
|
|
8921
|
+
runningTools: stateRef.current.runningTools.size,
|
|
8922
|
+
// Bytes queued in stdout's writable buffer. On Windows, TTY writes
|
|
8923
|
+
// are asynchronous — a render storm (e.g. high-frequency tool
|
|
8924
|
+
// progress dispatches) queues whole ANSI frames here as live heap
|
|
8925
|
+
// strings, invisible to every other counter.
|
|
8926
|
+
stdoutQueued: process.stdout.writableLength ?? 0
|
|
8927
|
+
}),
|
|
8928
|
+
onWarn: (level, message) => {
|
|
8929
|
+
dispatch({
|
|
8930
|
+
type: "addEntry",
|
|
8931
|
+
entry: { kind: level === "critical" ? "error" : "warn", text: message }
|
|
8932
|
+
});
|
|
8933
|
+
}
|
|
8934
|
+
});
|
|
8935
|
+
}, [agent.ctx]);
|
|
7741
8936
|
useEffect(() => {
|
|
7742
8937
|
if (state.goalPanelOpen) refreshGoalSummary();
|
|
7743
8938
|
}, [state.goalPanelOpen, nowTick, refreshGoalSummary]);
|
|
@@ -7748,20 +8943,14 @@ function App({
|
|
|
7748
8943
|
return () => clearInterval(t);
|
|
7749
8944
|
}, [state.enhanceBusy]);
|
|
7750
8945
|
const todosRef = useRef(JSON.stringify([]));
|
|
8946
|
+
const staleGuardRef = useRef(JSON.stringify({ a: "", y: false, m: "", model: "", provider: "" }));
|
|
7751
8947
|
useEffect(() => {
|
|
7752
8948
|
const poll = () => {
|
|
7753
|
-
const
|
|
7754
|
-
if (
|
|
7755
|
-
todosRef.current =
|
|
8949
|
+
const todoSnap = JSON.stringify(agent.ctx.todos.map((t2) => ({ s: t2.status })));
|
|
8950
|
+
if (todoSnap !== todosRef.current) {
|
|
8951
|
+
todosRef.current = todoSnap;
|
|
7756
8952
|
setNowTick(Date.now());
|
|
7757
8953
|
}
|
|
7758
|
-
};
|
|
7759
|
-
const t = setInterval(poll, 2e3);
|
|
7760
|
-
return () => clearInterval(t);
|
|
7761
|
-
}, [agent.ctx.todos]);
|
|
7762
|
-
const staleGuardRef = useRef(JSON.stringify({ a: "", y: false, m: "", model: "", provider: "" }));
|
|
7763
|
-
useEffect(() => {
|
|
7764
|
-
const poll = () => {
|
|
7765
8954
|
const a = getAutonomy?.() ?? "off";
|
|
7766
8955
|
const y = getYolo?.() ?? false;
|
|
7767
8956
|
const m = getModeLabel?.() ?? "";
|
|
@@ -7793,23 +8982,162 @@ function App({
|
|
|
7793
8982
|
liveModel,
|
|
7794
8983
|
liveProvider,
|
|
7795
8984
|
agent.ctx.model,
|
|
7796
|
-
agent.ctx.provider
|
|
8985
|
+
agent.ctx.provider,
|
|
8986
|
+
agent.ctx.todos
|
|
7797
8987
|
]);
|
|
7798
8988
|
const [gitInfo, setGitInfo] = React5.useState(null);
|
|
7799
8989
|
useEffect(() => {
|
|
7800
8990
|
let cancelled = false;
|
|
7801
8991
|
const refresh = () => {
|
|
7802
8992
|
readGitInfo(agent.ctx.cwd).then((info) => {
|
|
7803
|
-
if (
|
|
7804
|
-
|
|
8993
|
+
if (cancelled) return;
|
|
8994
|
+
setGitInfo(info);
|
|
8995
|
+
if (info && info.branch) {
|
|
8996
|
+
const prev = prevBranchRef.current;
|
|
8997
|
+
if (prev !== null && prev !== info.branch) {
|
|
8998
|
+
const msg = {
|
|
8999
|
+
role: "user",
|
|
9000
|
+
content: [{ type: "text", text: `[system] Git branch switched: \u2387 ${prev} \u2192 \u2387 ${info.branch}. The working tree is now on branch "${info.branch}". Any file changes from the previous branch are no longer visible.` }]
|
|
9001
|
+
};
|
|
9002
|
+
agent.ctx.messages.push(msg);
|
|
9003
|
+
try {
|
|
9004
|
+
import('@wrongstack/core').then(({ getSessionRegistry }) => {
|
|
9005
|
+
const reg = getSessionRegistry();
|
|
9006
|
+
if (reg) {
|
|
9007
|
+
reg.updateAgents([]).catch(() => {
|
|
9008
|
+
});
|
|
9009
|
+
}
|
|
9010
|
+
}).catch(() => {
|
|
9011
|
+
});
|
|
9012
|
+
} catch {
|
|
9013
|
+
}
|
|
9014
|
+
}
|
|
9015
|
+
prevBranchRef.current = info.branch;
|
|
9016
|
+
}
|
|
9017
|
+
}).catch(() => {
|
|
9018
|
+
if (!cancelled) setGitInfo(null);
|
|
9019
|
+
});
|
|
7805
9020
|
};
|
|
7806
9021
|
refresh();
|
|
9022
|
+
if (gitInfo?.branch && prevBranchRef.current === null) {
|
|
9023
|
+
prevBranchRef.current = gitInfo.branch;
|
|
9024
|
+
}
|
|
7807
9025
|
const t = setInterval(refresh, 5e3);
|
|
7808
9026
|
return () => {
|
|
7809
9027
|
cancelled = true;
|
|
7810
9028
|
clearInterval(t);
|
|
7811
9029
|
};
|
|
7812
|
-
}, [agent.ctx.cwd]);
|
|
9030
|
+
}, [agent.ctx.cwd, gitInfo?.branch]);
|
|
9031
|
+
useEffect(() => {
|
|
9032
|
+
if (!getLiveSessions) return;
|
|
9033
|
+
let cancelled = false;
|
|
9034
|
+
const poll = async () => {
|
|
9035
|
+
try {
|
|
9036
|
+
const sessions = await getLiveSessions();
|
|
9037
|
+
if (!cancelled) setSessionCount(sessions.length);
|
|
9038
|
+
} catch {
|
|
9039
|
+
}
|
|
9040
|
+
};
|
|
9041
|
+
void poll();
|
|
9042
|
+
const t = setInterval(poll, 3e4);
|
|
9043
|
+
if (t.unref) t.unref();
|
|
9044
|
+
return () => {
|
|
9045
|
+
cancelled = true;
|
|
9046
|
+
clearInterval(t);
|
|
9047
|
+
};
|
|
9048
|
+
}, [getLiveSessions]);
|
|
9049
|
+
const [mailboxStatus, setMailboxStatus] = useState({
|
|
9050
|
+
unread: 0,
|
|
9051
|
+
onlineAgents: 0
|
|
9052
|
+
});
|
|
9053
|
+
useEffect(() => {
|
|
9054
|
+
const seenAgents = /* @__PURE__ */ new Set();
|
|
9055
|
+
const unsub1 = events.onPattern("mailbox.unread_count", (_e, payload) => {
|
|
9056
|
+
const p = payload;
|
|
9057
|
+
setMailboxStatus((prev) => ({ ...prev, unread: p?.count ?? 0 }));
|
|
9058
|
+
});
|
|
9059
|
+
const unsub2 = events.onPattern("mailbox.received", (_e, payload) => {
|
|
9060
|
+
const p = payload;
|
|
9061
|
+
setMailboxStatus((prev) => ({
|
|
9062
|
+
...prev,
|
|
9063
|
+
lastSubject: p?.subject ?? prev.lastSubject,
|
|
9064
|
+
lastFrom: p?.from ?? prev.lastFrom
|
|
9065
|
+
}));
|
|
9066
|
+
});
|
|
9067
|
+
const unsub3 = events.onPattern("mailbox.agent_registered", (_e, payload) => {
|
|
9068
|
+
const p = payload;
|
|
9069
|
+
if (p?.agentId) seenAgents.add(p.agentId);
|
|
9070
|
+
setMailboxStatus((prev) => ({ ...prev, onlineAgents: seenAgents.size }));
|
|
9071
|
+
});
|
|
9072
|
+
const unsub4 = events.onPattern("mailbox.agent_heartbeat", (_e, payload) => {
|
|
9073
|
+
const p = payload;
|
|
9074
|
+
if (p?.agentId) seenAgents.add(p.agentId);
|
|
9075
|
+
setMailboxStatus((prev) => ({ ...prev, onlineAgents: seenAgents.size }));
|
|
9076
|
+
});
|
|
9077
|
+
return () => {
|
|
9078
|
+
unsub1();
|
|
9079
|
+
unsub2();
|
|
9080
|
+
unsub3();
|
|
9081
|
+
unsub4();
|
|
9082
|
+
};
|
|
9083
|
+
}, [events]);
|
|
9084
|
+
const [mailboxPanelOpen, setMailboxPanelOpen] = useState(false);
|
|
9085
|
+
const [mailboxMessages, setMailboxMessages] = useState([]);
|
|
9086
|
+
const [mailboxAgents, setMailboxAgents] = useState([]);
|
|
9087
|
+
useEffect(() => {
|
|
9088
|
+
if (!mailboxPanelOpen) return;
|
|
9089
|
+
const poll = async () => {
|
|
9090
|
+
};
|
|
9091
|
+
void poll();
|
|
9092
|
+
const t = setInterval(poll, 1e4);
|
|
9093
|
+
return () => clearInterval(t);
|
|
9094
|
+
}, [mailboxPanelOpen]);
|
|
9095
|
+
useEffect(() => {
|
|
9096
|
+
const unsub = events.onPattern("mailbox.received", (_e, payload) => {
|
|
9097
|
+
const p = payload;
|
|
9098
|
+
if (!p?.messageId) return;
|
|
9099
|
+
setMailboxMessages((prev) => {
|
|
9100
|
+
if (prev.some((m) => m.id === p.messageId)) return prev;
|
|
9101
|
+
return [
|
|
9102
|
+
{
|
|
9103
|
+
id: p.messageId,
|
|
9104
|
+
from: p.from ?? "unknown",
|
|
9105
|
+
to: "*",
|
|
9106
|
+
type: p.type ?? "note",
|
|
9107
|
+
subject: p.subject ?? "",
|
|
9108
|
+
body: "",
|
|
9109
|
+
priority: "normal",
|
|
9110
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9111
|
+
readByCount: 0,
|
|
9112
|
+
readByMe: false,
|
|
9113
|
+
completed: false
|
|
9114
|
+
},
|
|
9115
|
+
...prev
|
|
9116
|
+
].slice(0, 50);
|
|
9117
|
+
});
|
|
9118
|
+
});
|
|
9119
|
+
const unsub2 = events.onPattern("mailbox.agent_registered", (_e, payload) => {
|
|
9120
|
+
const p = payload;
|
|
9121
|
+
if (!p?.agentId) return;
|
|
9122
|
+
setMailboxAgents((prev) => {
|
|
9123
|
+
if (prev.some((a) => a.agentId === p.agentId)) return prev;
|
|
9124
|
+
return [...prev, {
|
|
9125
|
+
agentId: p.agentId,
|
|
9126
|
+
name: p.name ?? p.agentId,
|
|
9127
|
+
role: p.role,
|
|
9128
|
+
sessionId: p.sessionId ?? "?",
|
|
9129
|
+
status: "idle",
|
|
9130
|
+
lastSeenAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9131
|
+
online: true,
|
|
9132
|
+
source: p.source
|
|
9133
|
+
}].slice(0, 30);
|
|
9134
|
+
});
|
|
9135
|
+
});
|
|
9136
|
+
return () => {
|
|
9137
|
+
unsub();
|
|
9138
|
+
unsub2();
|
|
9139
|
+
};
|
|
9140
|
+
}, [events]);
|
|
7813
9141
|
const maxContext = activeMaxContext ?? agent.ctx.provider.capabilities.maxContext;
|
|
7814
9142
|
const currentContextTokens = (tokenCounter?.currentRequestTokens()?.input ?? 0) + (tokenCounter?.currentRequestTokens()?.cacheRead ?? 0);
|
|
7815
9143
|
const contextWindow = useMemo(() => {
|
|
@@ -7897,6 +9225,53 @@ function App({
|
|
|
7897
9225
|
clearInterval(id);
|
|
7898
9226
|
};
|
|
7899
9227
|
}, [agent.ctx.meta]);
|
|
9228
|
+
const [taskCounts, setTaskCounts] = useState(null);
|
|
9229
|
+
useEffect(() => {
|
|
9230
|
+
const taskPath = agent.ctx.meta["task.path"];
|
|
9231
|
+
if (typeof taskPath !== "string" || !taskPath) return;
|
|
9232
|
+
let cancelled = false;
|
|
9233
|
+
const poll = async () => {
|
|
9234
|
+
try {
|
|
9235
|
+
const data = await fs2.readFile(taskPath, "utf8");
|
|
9236
|
+
const parsed = JSON.parse(data);
|
|
9237
|
+
if (cancelled) return;
|
|
9238
|
+
if (!Array.isArray(parsed.tasks)) {
|
|
9239
|
+
setTaskCounts(null);
|
|
9240
|
+
return;
|
|
9241
|
+
}
|
|
9242
|
+
let pending = 0, inProgress = 0, completed = 0, blocked = 0, failed = 0;
|
|
9243
|
+
for (const t of parsed.tasks) {
|
|
9244
|
+
switch (t?.status) {
|
|
9245
|
+
case "completed":
|
|
9246
|
+
completed++;
|
|
9247
|
+
break;
|
|
9248
|
+
case "in_progress":
|
|
9249
|
+
inProgress++;
|
|
9250
|
+
break;
|
|
9251
|
+
case "blocked":
|
|
9252
|
+
blocked++;
|
|
9253
|
+
break;
|
|
9254
|
+
case "failed":
|
|
9255
|
+
failed++;
|
|
9256
|
+
break;
|
|
9257
|
+
default:
|
|
9258
|
+
pending++;
|
|
9259
|
+
break;
|
|
9260
|
+
}
|
|
9261
|
+
}
|
|
9262
|
+
const total = pending + inProgress + completed + blocked + failed;
|
|
9263
|
+
setTaskCounts(total > 0 ? { pending, inProgress, completed, blocked, failed } : null);
|
|
9264
|
+
} catch {
|
|
9265
|
+
if (!cancelled) setTaskCounts(null);
|
|
9266
|
+
}
|
|
9267
|
+
};
|
|
9268
|
+
void poll();
|
|
9269
|
+
const id = setInterval(poll, 3e3);
|
|
9270
|
+
return () => {
|
|
9271
|
+
cancelled = true;
|
|
9272
|
+
clearInterval(id);
|
|
9273
|
+
};
|
|
9274
|
+
}, [agent.ctx.meta]);
|
|
7900
9275
|
const prevAnyOverlayOpen = useRef(false);
|
|
7901
9276
|
const prevEntriesCount = useRef(0);
|
|
7902
9277
|
const prevToolStreamLen = useRef(0);
|
|
@@ -7907,7 +9282,7 @@ function App({
|
|
|
7907
9282
|
}
|
|
7908
9283
|
}, []);
|
|
7909
9284
|
React5.useLayoutEffect(() => {
|
|
7910
|
-
const anyOpenNow = state.picker.open || state.slashPicker.open || state.modelPicker.open || state.autonomyPicker.open || state.settingsPicker.open || state.enhanceBusy || state.enhance != null || state.escConfirm != null || state.confirmQueue.length > 0;
|
|
9285
|
+
const anyOpenNow = state.picker.open || state.slashPicker.open || state.modelPicker.open || state.autonomyPicker.open || state.resumePicker.open || state.settingsPicker.open || state.enhanceBusy || state.enhance != null || state.escConfirm != null || state.confirmQueue.length > 0;
|
|
7911
9286
|
const overlayClosed = prevAnyOverlayOpen.current && !anyOpenNow;
|
|
7912
9287
|
const newEntryCommitted = state.entries.length > prevEntriesCount.current;
|
|
7913
9288
|
const curToolStreamLen = state.toolStream?.text.length ?? 0;
|
|
@@ -7934,22 +9309,29 @@ function App({
|
|
|
7934
9309
|
]);
|
|
7935
9310
|
const resizeGateRef = useRef(0);
|
|
7936
9311
|
const preResizePanelsRef = useRef(null);
|
|
9312
|
+
const resizeRestoreTimerRef = useRef(null);
|
|
9313
|
+
const mountedRef = useRef(true);
|
|
7937
9314
|
useEffect(() => {
|
|
7938
9315
|
const handleResize = () => {
|
|
7939
9316
|
const seq = ++resizeGateRef.current;
|
|
7940
9317
|
preResizePanelsRef.current = {
|
|
7941
9318
|
settings: stateRef.current.settingsPicker.open,
|
|
9319
|
+
projectPicker: stateRef.current.projectPicker.open,
|
|
7942
9320
|
help: stateRef.current.helpOpen,
|
|
7943
9321
|
monitor: stateRef.current.monitorOpen,
|
|
7944
9322
|
agents: stateRef.current.agentsMonitorOpen,
|
|
7945
9323
|
worktree: stateRef.current.worktreeMonitorOpen,
|
|
7946
9324
|
todos: stateRef.current.todosMonitorOpen,
|
|
7947
9325
|
queue: stateRef.current.queuePanelOpen,
|
|
7948
|
-
processList: stateRef.current.processListOpen
|
|
9326
|
+
processList: stateRef.current.processListOpen,
|
|
9327
|
+
goalPanel: stateRef.current.goalPanelOpen,
|
|
9328
|
+
sessionsPanel: stateRef.current.sessionsPanelOpen
|
|
7949
9329
|
};
|
|
7950
9330
|
if (stateRef.current.settingsPicker.open) dispatch({ type: "settingsClose" });
|
|
9331
|
+
if (stateRef.current.projectPicker.open) dispatch({ type: "projectPickerClose" });
|
|
7951
9332
|
if (stateRef.current.modelPicker.open) dispatch({ type: "modelPickerClose" });
|
|
7952
9333
|
if (stateRef.current.autonomyPicker.open) dispatch({ type: "autonomyPickerClose" });
|
|
9334
|
+
if (stateRef.current.resumePicker.open) dispatch({ type: "resumePickerClose" });
|
|
7953
9335
|
if (stateRef.current.slashPicker.open) dispatch({ type: "slashPickerClose" });
|
|
7954
9336
|
if (stateRef.current.picker.open) dispatch({ type: "pickerClose" });
|
|
7955
9337
|
if (stateRef.current.rewindOverlay) dispatch({ type: "rewindOverlayClose" });
|
|
@@ -7960,8 +9342,11 @@ function App({
|
|
|
7960
9342
|
if (stateRef.current.todosMonitorOpen) dispatch({ type: "toggleTodosMonitor" });
|
|
7961
9343
|
if (stateRef.current.queuePanelOpen) dispatch({ type: "toggleQueuePanel" });
|
|
7962
9344
|
if (stateRef.current.processListOpen) dispatch({ type: "toggleProcessList" });
|
|
9345
|
+
if (stateRef.current.goalPanelOpen) dispatch({ type: "toggleGoalPanel" });
|
|
9346
|
+
if (stateRef.current.sessionsPanelOpen) dispatch({ type: "toggleSessionsPanel" });
|
|
7963
9347
|
eraseLiveRegion();
|
|
7964
|
-
setTimeout(() => {
|
|
9348
|
+
resizeRestoreTimerRef.current = setTimeout(() => {
|
|
9349
|
+
if (!mountedRef.current) return;
|
|
7965
9350
|
if (resizeGateRef.current !== seq) return;
|
|
7966
9351
|
const prev = preResizePanelsRef.current;
|
|
7967
9352
|
if (!prev) return;
|
|
@@ -7990,10 +9375,16 @@ function App({
|
|
|
7990
9375
|
maxIterations: sp.maxIterations,
|
|
7991
9376
|
autoProceedMaxIterations: sp.autoProceedMaxIterations,
|
|
7992
9377
|
enhanceDelayMs: sp.enhanceDelayMs,
|
|
9378
|
+
enhanceEnabled: sp.enhanceEnabled,
|
|
9379
|
+
enhanceLanguage: sp.enhanceLanguage,
|
|
7993
9380
|
debugStream: sp.debugStream,
|
|
7994
9381
|
configScope: sp.configScope
|
|
7995
9382
|
});
|
|
7996
9383
|
}
|
|
9384
|
+
if (prev.projectPicker) {
|
|
9385
|
+
const pp = stateRef.current.projectPicker;
|
|
9386
|
+
dispatch({ type: "projectPickerOpen", items: pp.allItems });
|
|
9387
|
+
}
|
|
7997
9388
|
if (prev.help) dispatch({ type: "toggleHelp" });
|
|
7998
9389
|
if (prev.monitor) dispatch({ type: "toggleMonitor" });
|
|
7999
9390
|
if (prev.agents) dispatch({ type: "toggleAgentsMonitor" });
|
|
@@ -8001,11 +9392,19 @@ function App({
|
|
|
8001
9392
|
if (prev.todos) dispatch({ type: "toggleTodosMonitor" });
|
|
8002
9393
|
if (prev.queue) dispatch({ type: "toggleQueuePanel" });
|
|
8003
9394
|
if (prev.processList) dispatch({ type: "toggleProcessList" });
|
|
9395
|
+
if (prev.goalPanel) dispatch({ type: "toggleGoalPanel" });
|
|
9396
|
+
if (prev.sessionsPanel) dispatch({ type: "toggleSessionsPanel" });
|
|
8004
9397
|
preResizePanelsRef.current = null;
|
|
9398
|
+
resizeRestoreTimerRef.current = null;
|
|
8005
9399
|
}, 300);
|
|
8006
9400
|
};
|
|
8007
9401
|
process.stdout.on("resize", handleResize);
|
|
8008
9402
|
return () => {
|
|
9403
|
+
if (resizeRestoreTimerRef.current) {
|
|
9404
|
+
clearTimeout(resizeRestoreTimerRef.current);
|
|
9405
|
+
resizeRestoreTimerRef.current = null;
|
|
9406
|
+
}
|
|
9407
|
+
mountedRef.current = false;
|
|
8009
9408
|
process.stdout.off("resize", handleResize);
|
|
8010
9409
|
};
|
|
8011
9410
|
}, [eraseLiveRegion]);
|
|
@@ -8106,7 +9505,7 @@ function App({
|
|
|
8106
9505
|
dispatch({ type: "pickerClose" });
|
|
8107
9506
|
return;
|
|
8108
9507
|
}
|
|
8109
|
-
const absPath =
|
|
9508
|
+
const absPath = path4.isAbsolute(picked) ? picked : path4.join(projectRoot, picked);
|
|
8110
9509
|
try {
|
|
8111
9510
|
const data = await fs2.readFile(absPath, "utf8");
|
|
8112
9511
|
const token = await builder.registerFile({
|
|
@@ -8167,6 +9566,9 @@ function App({
|
|
|
8167
9566
|
if (!queueStore) return;
|
|
8168
9567
|
queueStore.write(state.queue.map(({ displayText, blocks }) => ({ displayText, blocks }))).catch(() => void 0);
|
|
8169
9568
|
}, [state.queue, queueStore]);
|
|
9569
|
+
useEffect(() => {
|
|
9570
|
+
onQueueChange?.(state.queue.map((q) => q.displayText));
|
|
9571
|
+
}, [state.queue, onQueueChange]);
|
|
8170
9572
|
useEffect(() => {
|
|
8171
9573
|
const cmd = createQueueSlashCommand({
|
|
8172
9574
|
getQueue: () => stateRef.current.queue,
|
|
@@ -8302,6 +9704,28 @@ function App({
|
|
|
8302
9704
|
const providers = await getPickableProviders();
|
|
8303
9705
|
dispatch({ type: "modelPickerOpen", providers });
|
|
8304
9706
|
}, [getPickableProviders]);
|
|
9707
|
+
const openProjectPicker = React5.useCallback(async () => {
|
|
9708
|
+
if (!getProjectPickerItems) return;
|
|
9709
|
+
const items = await getProjectPickerItems();
|
|
9710
|
+
dispatch({ type: "projectPickerOpen", items });
|
|
9711
|
+
}, [getProjectPickerItems]);
|
|
9712
|
+
const loadLiveSessions = React5.useCallback(async () => {
|
|
9713
|
+
if (!getLiveSessions) return;
|
|
9714
|
+
dispatch({ type: "sessionsPanelBusy", on: true });
|
|
9715
|
+
try {
|
|
9716
|
+
const sessions = await getLiveSessions();
|
|
9717
|
+
dispatch({ type: "sessionsPanelSet", sessions });
|
|
9718
|
+
} catch {
|
|
9719
|
+
dispatch({ type: "sessionsPanelBusy", on: false });
|
|
9720
|
+
}
|
|
9721
|
+
}, [getLiveSessions]);
|
|
9722
|
+
useEffect(() => {
|
|
9723
|
+
if (!state.sessionsPanelOpen || !getLiveSessions) return void 0;
|
|
9724
|
+
const t = setInterval(() => {
|
|
9725
|
+
void loadLiveSessions();
|
|
9726
|
+
}, 5e3);
|
|
9727
|
+
return () => clearInterval(t);
|
|
9728
|
+
}, [state.sessionsPanelOpen, getLiveSessions, loadLiveSessions]);
|
|
8305
9729
|
const openSettings = React5.useCallback(() => {
|
|
8306
9730
|
if (!getSettings) return;
|
|
8307
9731
|
const s2 = getSettings();
|
|
@@ -8328,38 +9752,87 @@ function App({
|
|
|
8328
9752
|
maxIterations: s2.maxIterations ?? 500,
|
|
8329
9753
|
autoProceedMaxIterations: s2.autoProceedMaxIterations ?? 50,
|
|
8330
9754
|
enhanceDelayMs: s2.enhanceDelayMs ?? 6e4,
|
|
9755
|
+
enhanceEnabled: s2.enhanceEnabled ?? true,
|
|
9756
|
+
enhanceLanguage: s2.enhanceLanguage ?? "original",
|
|
8331
9757
|
debugStream: s2.debugStream ?? false,
|
|
8332
9758
|
configScope: s2.configScope ?? "global"
|
|
8333
9759
|
});
|
|
8334
9760
|
}, [getSettings]);
|
|
8335
|
-
const
|
|
8336
|
-
const
|
|
9761
|
+
const autoSubmitStreakRef = useRef(0);
|
|
9762
|
+
const autoSubmitCapWarnedRef = useRef(false);
|
|
9763
|
+
const [nextStepsRecheck, setNextStepsRecheck] = useState(0);
|
|
8337
9764
|
useEffect(() => {
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
8341
|
-
|
|
9765
|
+
autoSubmitStreakRef.current = 0;
|
|
9766
|
+
autoSubmitCapWarnedRef.current = false;
|
|
9767
|
+
}, [autonomyLive]);
|
|
9768
|
+
useEffect(() => {
|
|
9769
|
+
if (state.status !== "idle" || autonomyLive !== "auto") {
|
|
9770
|
+
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
9771
|
+
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
9772
|
+
setNextStepsAutoSubmitCountdown(null);
|
|
9773
|
+
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
9774
|
+
return;
|
|
9775
|
+
}
|
|
9776
|
+
if (state.enhance != null || state.enhanceBusy) {
|
|
9777
|
+
return;
|
|
9778
|
+
}
|
|
9779
|
+
if (nextStepsAutoSubmitTimerRef.current != null) {
|
|
8342
9780
|
return;
|
|
8343
9781
|
}
|
|
9782
|
+
const suggestions = getSuggestions?.() ?? [];
|
|
9783
|
+
if (suggestions.length === 0) {
|
|
9784
|
+
const recheck = setTimeout(() => setNextStepsRecheck((t) => t + 1), 1500);
|
|
9785
|
+
return () => clearTimeout(recheck);
|
|
9786
|
+
}
|
|
8344
9787
|
const cfg = getSettings?.();
|
|
9788
|
+
const maxAuto = cfg?.autoProceedMaxIterations ?? 50;
|
|
9789
|
+
if (maxAuto > 0 && autoSubmitStreakRef.current >= maxAuto) {
|
|
9790
|
+
if (!autoSubmitCapWarnedRef.current) {
|
|
9791
|
+
autoSubmitCapWarnedRef.current = true;
|
|
9792
|
+
dispatch({
|
|
9793
|
+
type: "addEntry",
|
|
9794
|
+
entry: {
|
|
9795
|
+
kind: "warn",
|
|
9796
|
+
text: `Auto-proceed paused after ${maxAuto} consecutive automatic turns \u2014 type anything to continue (autonomy stays on).`
|
|
9797
|
+
}
|
|
9798
|
+
});
|
|
9799
|
+
}
|
|
9800
|
+
return;
|
|
9801
|
+
}
|
|
8345
9802
|
const delay = cfg?.delayMs ?? 45e3;
|
|
9803
|
+
const top = suggestions[0];
|
|
9804
|
+
if (!top) return;
|
|
9805
|
+
nextStepsAutoSubmitSuggestionRef.current = top;
|
|
8346
9806
|
const start = Date.now();
|
|
8347
|
-
|
|
8348
|
-
|
|
9807
|
+
setNextStepsAutoSubmitCountdown(Math.ceil(delay / 1e3));
|
|
9808
|
+
nextStepsAutoSubmitTimerRef.current = setInterval(() => {
|
|
8349
9809
|
const remaining = Math.max(0, Math.ceil((delay - (Date.now() - start)) / 1e3));
|
|
8350
9810
|
if (remaining <= 0) {
|
|
8351
|
-
clearInterval(
|
|
8352
|
-
|
|
8353
|
-
|
|
9811
|
+
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
9812
|
+
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
9813
|
+
setNextStepsAutoSubmitCountdown(null);
|
|
9814
|
+
const suggestion = nextStepsAutoSubmitSuggestionRef.current;
|
|
9815
|
+
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
9816
|
+
if (suggestion) {
|
|
9817
|
+
autoSubmitStreakRef.current += 1;
|
|
9818
|
+
setDraft(suggestion, suggestion.length);
|
|
9819
|
+
void (async () => {
|
|
9820
|
+
const trimmed = suggestion.trim();
|
|
9821
|
+
if (!trimmed) return;
|
|
9822
|
+
const blocks = [{ type: "text", text: trimmed }];
|
|
9823
|
+
dispatch({ type: "addEntry", entry: { kind: "user", text: trimmed } });
|
|
9824
|
+
await runBlocksRef.current(blocks);
|
|
9825
|
+
})();
|
|
9826
|
+
}
|
|
8354
9827
|
} else {
|
|
8355
|
-
|
|
9828
|
+
setNextStepsAutoSubmitCountdown(remaining);
|
|
8356
9829
|
}
|
|
8357
9830
|
}, 500);
|
|
8358
9831
|
return () => {
|
|
8359
|
-
clearInterval(
|
|
8360
|
-
|
|
9832
|
+
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
9833
|
+
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
8361
9834
|
};
|
|
8362
|
-
}, [autonomyLive, getSettings]);
|
|
9835
|
+
}, [state.status, autonomyLive, state.enhance, state.enhanceBusy, nextStepsRecheck, getSettings, getSuggestions, dispatch]);
|
|
8363
9836
|
const settingsAutoSaveGateRef = useRef(true);
|
|
8364
9837
|
useEffect(() => {
|
|
8365
9838
|
if (state.settingsPicker.open) {
|
|
@@ -8396,6 +9869,8 @@ function App({
|
|
|
8396
9869
|
maxIterations: sp.maxIterations,
|
|
8397
9870
|
autoProceedMaxIterations: sp.autoProceedMaxIterations,
|
|
8398
9871
|
enhanceDelayMs: sp.enhanceDelayMs,
|
|
9872
|
+
enhanceEnabled: sp.enhanceEnabled,
|
|
9873
|
+
enhanceLanguage: sp.enhanceLanguage,
|
|
8399
9874
|
debugStream: sp.debugStream,
|
|
8400
9875
|
configScope: sp.configScope
|
|
8401
9876
|
})).then((err) => {
|
|
@@ -8458,6 +9933,21 @@ function App({
|
|
|
8458
9933
|
slashRegistry.unregister("settings");
|
|
8459
9934
|
};
|
|
8460
9935
|
}, [slashRegistry, getSettings, saveSettings, openSettings]);
|
|
9936
|
+
useEffect(() => {
|
|
9937
|
+
const cmd = {
|
|
9938
|
+
name: "mailbox",
|
|
9939
|
+
aliases: ["inbox", "mail"],
|
|
9940
|
+
description: "Toggle the inter-agent mailbox panel \u2014 messages, read receipts, online agents.",
|
|
9941
|
+
async run() {
|
|
9942
|
+
setMailboxPanelOpen((prev) => !prev);
|
|
9943
|
+
return { message: void 0 };
|
|
9944
|
+
}
|
|
9945
|
+
};
|
|
9946
|
+
slashRegistry.register(cmd, "tui", { official: true });
|
|
9947
|
+
return () => {
|
|
9948
|
+
slashRegistry.unregister("mailbox");
|
|
9949
|
+
};
|
|
9950
|
+
}, [slashRegistry]);
|
|
8461
9951
|
useEffect(() => {
|
|
8462
9952
|
if (!switchAutonomy) return;
|
|
8463
9953
|
const cmd = {
|
|
@@ -8474,6 +9964,34 @@ function App({
|
|
|
8474
9964
|
slashRegistry.unregister("autonomy");
|
|
8475
9965
|
};
|
|
8476
9966
|
}, [slashRegistry, switchAutonomy]);
|
|
9967
|
+
useEffect(() => {
|
|
9968
|
+
const cmd = {
|
|
9969
|
+
name: "resume",
|
|
9970
|
+
aliases: ["load"],
|
|
9971
|
+
description: "Resume a previous session \u2014 pick from a list of recent sessions.",
|
|
9972
|
+
async run() {
|
|
9973
|
+
if (!listSessions) {
|
|
9974
|
+
return { message: "Session listing not available." };
|
|
9975
|
+
}
|
|
9976
|
+
try {
|
|
9977
|
+
const sessions = await listSessions(20);
|
|
9978
|
+
if (sessions.length === 0) {
|
|
9979
|
+
return { message: "No saved sessions." };
|
|
9980
|
+
}
|
|
9981
|
+
dispatch({ type: "resumePickerOpen", sessions });
|
|
9982
|
+
} catch (err) {
|
|
9983
|
+
return {
|
|
9984
|
+
message: err instanceof Error ? err.message : String(err)
|
|
9985
|
+
};
|
|
9986
|
+
}
|
|
9987
|
+
return { message: void 0 };
|
|
9988
|
+
}
|
|
9989
|
+
};
|
|
9990
|
+
slashRegistry.register(cmd, "tui", { official: true });
|
|
9991
|
+
return () => {
|
|
9992
|
+
slashRegistry.unregister("resume");
|
|
9993
|
+
};
|
|
9994
|
+
}, [slashRegistry, listSessions]);
|
|
8477
9995
|
useEffect(() => {
|
|
8478
9996
|
const FLUSH_MS2 = 100;
|
|
8479
9997
|
const flush = () => {
|
|
@@ -8666,6 +10184,9 @@ function App({
|
|
|
8666
10184
|
}, [state.enhanceEnabled]);
|
|
8667
10185
|
const enhanceAbortRef = useRef(null);
|
|
8668
10186
|
const [enhanceCountdown, setEnhanceCountdown] = useState(null);
|
|
10187
|
+
const [nextStepsAutoSubmitCountdown, setNextStepsAutoSubmitCountdown] = useState(null);
|
|
10188
|
+
const nextStepsAutoSubmitSuggestionRef = useRef(null);
|
|
10189
|
+
const nextStepsAutoSubmitTimerRef = useRef(void 0);
|
|
8669
10190
|
useTuiEventBridge({
|
|
8670
10191
|
events,
|
|
8671
10192
|
dispatch,
|
|
@@ -8873,7 +10394,28 @@ function App({
|
|
|
8873
10394
|
return;
|
|
8874
10395
|
}
|
|
8875
10396
|
}
|
|
8876
|
-
const
|
|
10397
|
+
const overlaySelectable = state.modelPicker.open || state.autonomyPicker.open || state.resumePicker.open || state.settingsPicker.open || state.projectPicker.open || state.slashPicker.open || state.picker.open;
|
|
10398
|
+
const clickConfirm = overlaySelectable && key.mouse?.kind === "press" && key.mouse.button === "left";
|
|
10399
|
+
const clickCancel = overlaySelectable && key.mouse?.kind === "press" && key.mouse.button === "right";
|
|
10400
|
+
const isEnter = key.return || input === "\r" || input === "\n" || clickConfirm;
|
|
10401
|
+
if (clickCancel) {
|
|
10402
|
+
if (state.modelPicker.open) {
|
|
10403
|
+
dispatch(
|
|
10404
|
+
state.modelPicker.step === "model" ? { type: "modelPickerBack" } : { type: "modelPickerClose" }
|
|
10405
|
+
);
|
|
10406
|
+
} else if (state.autonomyPicker.open) {
|
|
10407
|
+
dispatch({ type: "autonomyPickerClose" });
|
|
10408
|
+
} else if (state.resumePicker.open) {
|
|
10409
|
+
dispatch({ type: "resumePickerClose" });
|
|
10410
|
+
} else if (state.settingsPicker.open) {
|
|
10411
|
+
dispatch({ type: "settingsClose" });
|
|
10412
|
+
} else if (state.slashPicker.open) {
|
|
10413
|
+
dispatch({ type: "slashPickerClose" });
|
|
10414
|
+
} else if (state.picker.open) {
|
|
10415
|
+
dispatch({ type: "pickerClose" });
|
|
10416
|
+
}
|
|
10417
|
+
return;
|
|
10418
|
+
}
|
|
8877
10419
|
if (state.modelPicker.open) {
|
|
8878
10420
|
if (key.escape) {
|
|
8879
10421
|
if (state.modelPicker.step === "model") {
|
|
@@ -8883,6 +10425,10 @@ function App({
|
|
|
8883
10425
|
}
|
|
8884
10426
|
return;
|
|
8885
10427
|
}
|
|
10428
|
+
if (key.mouse?.kind === "wheel") {
|
|
10429
|
+
dispatch({ type: "modelPickerMove", delta: key.mouse.wheel > 0 ? -1 : 1 });
|
|
10430
|
+
return;
|
|
10431
|
+
}
|
|
8886
10432
|
if (key.upArrow) {
|
|
8887
10433
|
dispatch({ type: "modelPickerMove", delta: -1 });
|
|
8888
10434
|
return;
|
|
@@ -8948,6 +10494,10 @@ function App({
|
|
|
8948
10494
|
dispatch({ type: "autonomyPickerClose" });
|
|
8949
10495
|
return;
|
|
8950
10496
|
}
|
|
10497
|
+
if (key.mouse?.kind === "wheel") {
|
|
10498
|
+
dispatch({ type: "autonomyPickerMove", delta: key.mouse.wheel > 0 ? -1 : 1 });
|
|
10499
|
+
return;
|
|
10500
|
+
}
|
|
8951
10501
|
if (key.upArrow) {
|
|
8952
10502
|
dispatch({ type: "autonomyPickerMove", delta: -1 });
|
|
8953
10503
|
return;
|
|
@@ -8972,24 +10522,77 @@ function App({
|
|
|
8972
10522
|
}
|
|
8973
10523
|
return;
|
|
8974
10524
|
}
|
|
8975
|
-
if (state.
|
|
8976
|
-
if (key.escape
|
|
8977
|
-
dispatch({ type: "
|
|
10525
|
+
if (state.resumePicker.open) {
|
|
10526
|
+
if (key.escape) {
|
|
10527
|
+
dispatch({ type: "resumePickerClose" });
|
|
8978
10528
|
return;
|
|
8979
10529
|
}
|
|
8980
|
-
if (key.
|
|
8981
|
-
dispatch({ type: "
|
|
10530
|
+
if (key.mouse?.kind === "wheel") {
|
|
10531
|
+
dispatch({ type: "resumePickerMove", delta: key.mouse.wheel > 0 ? -1 : 1 });
|
|
8982
10532
|
return;
|
|
8983
10533
|
}
|
|
8984
|
-
if (key.
|
|
8985
|
-
dispatch({ type: "
|
|
10534
|
+
if (key.upArrow) {
|
|
10535
|
+
dispatch({ type: "resumePickerMove", delta: -1 });
|
|
8986
10536
|
return;
|
|
8987
10537
|
}
|
|
8988
|
-
if (key.
|
|
8989
|
-
dispatch({ type: "
|
|
10538
|
+
if (key.downArrow) {
|
|
10539
|
+
dispatch({ type: "resumePickerMove", delta: 1 });
|
|
8990
10540
|
return;
|
|
8991
10541
|
}
|
|
8992
|
-
if (
|
|
10542
|
+
if (isEnter) {
|
|
10543
|
+
const now = Date.now();
|
|
10544
|
+
if (now - lastEnterAtRef.current < 50) return;
|
|
10545
|
+
lastEnterAtRef.current = now;
|
|
10546
|
+
const session = state.resumePicker.sessions[state.resumePicker.selected];
|
|
10547
|
+
if (!session || session.isCurrent) return;
|
|
10548
|
+
if (state.resumePicker.busy) return;
|
|
10549
|
+
dispatch({ type: "resumePickerBusy", on: true });
|
|
10550
|
+
onResumeSession?.(session.id).then((result) => {
|
|
10551
|
+
if (!result) {
|
|
10552
|
+
dispatch({ type: "resumePickerError", text: `Failed to resume session ${session.id}.` });
|
|
10553
|
+
return;
|
|
10554
|
+
}
|
|
10555
|
+
dispatch({ type: "replaceHistory", entries: result.entries, nextId: result.nextId });
|
|
10556
|
+
dispatch({ type: "resumePickerClose" });
|
|
10557
|
+
dispatch({
|
|
10558
|
+
type: "addEntry",
|
|
10559
|
+
entry: {
|
|
10560
|
+
kind: "info",
|
|
10561
|
+
text: `Resumed session ${result.sessionId} \u2014 ${result.entries.length} entries replayed.`
|
|
10562
|
+
}
|
|
10563
|
+
});
|
|
10564
|
+
}).catch((err) => {
|
|
10565
|
+
dispatch({
|
|
10566
|
+
type: "resumePickerError",
|
|
10567
|
+
text: err instanceof Error ? err.message : String(err)
|
|
10568
|
+
});
|
|
10569
|
+
});
|
|
10570
|
+
return;
|
|
10571
|
+
}
|
|
10572
|
+
return;
|
|
10573
|
+
}
|
|
10574
|
+
if (state.settingsPicker.open) {
|
|
10575
|
+
if (key.escape || key.ctrl && input === "s") {
|
|
10576
|
+
dispatch({ type: "settingsClose" });
|
|
10577
|
+
return;
|
|
10578
|
+
}
|
|
10579
|
+
if (key.mouse?.kind === "wheel") {
|
|
10580
|
+
dispatch({ type: "settingsFieldMove", delta: key.mouse.wheel > 0 ? -1 : 1 });
|
|
10581
|
+
return;
|
|
10582
|
+
}
|
|
10583
|
+
if (key.upArrow) {
|
|
10584
|
+
dispatch({ type: "settingsFieldMove", delta: -1 });
|
|
10585
|
+
return;
|
|
10586
|
+
}
|
|
10587
|
+
if (key.downArrow) {
|
|
10588
|
+
dispatch({ type: "settingsFieldMove", delta: 1 });
|
|
10589
|
+
return;
|
|
10590
|
+
}
|
|
10591
|
+
if (key.leftArrow) {
|
|
10592
|
+
dispatch({ type: "settingsValueChange", delta: -1 });
|
|
10593
|
+
return;
|
|
10594
|
+
}
|
|
10595
|
+
if (key.rightArrow) {
|
|
8993
10596
|
dispatch({ type: "settingsValueChange", delta: 1 });
|
|
8994
10597
|
return;
|
|
8995
10598
|
}
|
|
@@ -9002,11 +10605,166 @@ function App({
|
|
|
9002
10605
|
}
|
|
9003
10606
|
return;
|
|
9004
10607
|
}
|
|
10608
|
+
if (state.projectPicker.open) {
|
|
10609
|
+
if (key.escape) {
|
|
10610
|
+
if (state.projectPicker.filter) {
|
|
10611
|
+
dispatch({ type: "projectPickerFilter", filter: "" });
|
|
10612
|
+
} else {
|
|
10613
|
+
dispatch({ type: "projectPickerClose" });
|
|
10614
|
+
}
|
|
10615
|
+
return;
|
|
10616
|
+
}
|
|
10617
|
+
if (key.mouse?.kind === "wheel") {
|
|
10618
|
+
dispatch({ type: "projectPickerMove", delta: key.mouse.wheel > 0 ? -1 : 1 });
|
|
10619
|
+
return;
|
|
10620
|
+
}
|
|
10621
|
+
if (key.upArrow) {
|
|
10622
|
+
dispatch({ type: "projectPickerMove", delta: -1 });
|
|
10623
|
+
return;
|
|
10624
|
+
}
|
|
10625
|
+
if (key.downArrow) {
|
|
10626
|
+
dispatch({ type: "projectPickerMove", delta: 1 });
|
|
10627
|
+
return;
|
|
10628
|
+
}
|
|
10629
|
+
if (isEnter) {
|
|
10630
|
+
const now = Date.now();
|
|
10631
|
+
if (now - lastEnterAtRef.current < 50) return;
|
|
10632
|
+
lastEnterAtRef.current = now;
|
|
10633
|
+
const items = state.projectPicker.items;
|
|
10634
|
+
const selected = state.projectPicker.selected;
|
|
10635
|
+
if (selected < 0 || selected >= items.length) return;
|
|
10636
|
+
const item = items[selected];
|
|
10637
|
+
if (!item || item.key === "__divider__" || item.key === "quit") {
|
|
10638
|
+
dispatch({ type: "projectPickerClose" });
|
|
10639
|
+
return;
|
|
10640
|
+
}
|
|
10641
|
+
if (item.kind === "project") {
|
|
10642
|
+
onProjectSelect?.(item.key, item.kind);
|
|
10643
|
+
dispatch({ type: "projectPickerClose" });
|
|
10644
|
+
requestExit?.(42);
|
|
10645
|
+
return;
|
|
10646
|
+
}
|
|
10647
|
+
dispatch({ type: "projectPickerClose" });
|
|
10648
|
+
if (item.key === "new-session") {
|
|
10649
|
+
onProjectSelect?.(item.key, item.kind);
|
|
10650
|
+
requestExit?.(42);
|
|
10651
|
+
} else if (item.key === "prev-sessions") {
|
|
10652
|
+
void submit("/resume");
|
|
10653
|
+
}
|
|
10654
|
+
return;
|
|
10655
|
+
}
|
|
10656
|
+
if (input && input.length === 1 && input.charCodeAt(0) >= 32 && input.charCodeAt(0) < 127) {
|
|
10657
|
+
dispatch({ type: "projectPickerFilter", filter: state.projectPicker.filter + input });
|
|
10658
|
+
return;
|
|
10659
|
+
}
|
|
10660
|
+
if (key.backspace) {
|
|
10661
|
+
if (state.projectPicker.filter.length > 0) {
|
|
10662
|
+
dispatch({
|
|
10663
|
+
type: "projectPickerFilter",
|
|
10664
|
+
filter: state.projectPicker.filter.slice(0, -1)
|
|
10665
|
+
});
|
|
10666
|
+
}
|
|
10667
|
+
return;
|
|
10668
|
+
}
|
|
10669
|
+
return;
|
|
10670
|
+
}
|
|
10671
|
+
if (state.sessionsPanelOpen) {
|
|
10672
|
+
if (key.escape) {
|
|
10673
|
+
if (state.sessionResumeConfirm) {
|
|
10674
|
+
dispatch({ type: "sessionResumeConfirmClear" });
|
|
10675
|
+
} else {
|
|
10676
|
+
dispatch({ type: "toggleSessionsPanel" });
|
|
10677
|
+
}
|
|
10678
|
+
return;
|
|
10679
|
+
}
|
|
10680
|
+
if (key.upArrow) {
|
|
10681
|
+
dispatch({ type: "sessionsPanelMove", delta: -1 });
|
|
10682
|
+
return;
|
|
10683
|
+
}
|
|
10684
|
+
if (key.downArrow) {
|
|
10685
|
+
dispatch({ type: "sessionsPanelMove", delta: 1 });
|
|
10686
|
+
return;
|
|
10687
|
+
}
|
|
10688
|
+
if (key.mouse?.kind === "wheel") {
|
|
10689
|
+
dispatch({ type: "sessionsPanelMove", delta: key.mouse.wheel > 0 ? -1 : 1 });
|
|
10690
|
+
return;
|
|
10691
|
+
}
|
|
10692
|
+
if (isEnter) {
|
|
10693
|
+
const now = Date.now();
|
|
10694
|
+
if (now - lastEnterAtRef.current < 50) return;
|
|
10695
|
+
lastEnterAtRef.current = now;
|
|
10696
|
+
if (state.sessionResumeConfirm) {
|
|
10697
|
+
const pending = state.sessionResumeConfirm;
|
|
10698
|
+
dispatch({ type: "sessionResumeConfirmClear" });
|
|
10699
|
+
dispatch({ type: "sessionsPanelBusy", on: true });
|
|
10700
|
+
onResumeSession?.(pending.sessionId).then((result) => {
|
|
10701
|
+
if (!result) {
|
|
10702
|
+
dispatch({ type: "sessionsPanelBusy", on: false });
|
|
10703
|
+
return;
|
|
10704
|
+
}
|
|
10705
|
+
dispatch({ type: "replaceHistory", entries: result.entries, nextId: result.nextId });
|
|
10706
|
+
dispatch({ type: "toggleSessionsPanel" });
|
|
10707
|
+
dispatch({
|
|
10708
|
+
type: "addEntry",
|
|
10709
|
+
entry: {
|
|
10710
|
+
kind: "info",
|
|
10711
|
+
text: `Resumed session ${result.sessionId} \u2014 ${result.entries.length} entries replayed.`
|
|
10712
|
+
}
|
|
10713
|
+
});
|
|
10714
|
+
}).catch(() => {
|
|
10715
|
+
dispatch({ type: "sessionsPanelBusy", on: false });
|
|
10716
|
+
});
|
|
10717
|
+
return;
|
|
10718
|
+
}
|
|
10719
|
+
const sessions = state.sessionsPanel.sessions;
|
|
10720
|
+
const sel = state.sessionsPanel.selected;
|
|
10721
|
+
if (sel < 0 || sel >= sessions.length) return;
|
|
10722
|
+
const session = sessions[sel];
|
|
10723
|
+
if (!session) return;
|
|
10724
|
+
const isCurrentProject = session.projectRoot === projectRoot;
|
|
10725
|
+
if (isCurrentProject) {
|
|
10726
|
+
if (session.pid === process.pid) {
|
|
10727
|
+
dispatch({
|
|
10728
|
+
type: "addEntry",
|
|
10729
|
+
entry: { kind: "info", text: "That is this session \u2014 nothing to resume." }
|
|
10730
|
+
});
|
|
10731
|
+
dispatch({ type: "toggleSessionsPanel" });
|
|
10732
|
+
return;
|
|
10733
|
+
}
|
|
10734
|
+
if (session.pid != null) {
|
|
10735
|
+
dispatch({
|
|
10736
|
+
type: "addEntry",
|
|
10737
|
+
entry: {
|
|
10738
|
+
kind: "warn",
|
|
10739
|
+
text: `Session is open in another running wstack (pid ${session.pid}) \u2014 a live session cannot be resumed here. Use /resume for previous sessions.`
|
|
10740
|
+
}
|
|
10741
|
+
});
|
|
10742
|
+
dispatch({ type: "toggleSessionsPanel" });
|
|
10743
|
+
return;
|
|
10744
|
+
}
|
|
10745
|
+
dispatch({
|
|
10746
|
+
type: "sessionResumeConfirmSet",
|
|
10747
|
+
sessionId: session.sessionId,
|
|
10748
|
+
sessionName: session.projectName
|
|
10749
|
+
});
|
|
10750
|
+
} else {
|
|
10751
|
+
onSwitchToSession?.(session.sessionId, session.projectRoot ?? "", session.projectName);
|
|
10752
|
+
dispatch({ type: "toggleSessionsPanel" });
|
|
10753
|
+
requestExit?.(42);
|
|
10754
|
+
}
|
|
10755
|
+
return;
|
|
10756
|
+
}
|
|
10757
|
+
return;
|
|
10758
|
+
}
|
|
9005
10759
|
if (state.slashPicker.open) {
|
|
9006
10760
|
if (key.escape) {
|
|
9007
10761
|
dispatch({ type: "slashPickerClose" });
|
|
9008
10762
|
return;
|
|
9009
10763
|
}
|
|
10764
|
+
if (key.mouse?.kind === "wheel") {
|
|
10765
|
+
dispatch({ type: "slashPickerMove", delta: key.mouse.wheel > 0 ? -1 : 1 });
|
|
10766
|
+
return;
|
|
10767
|
+
}
|
|
9010
10768
|
if (key.upArrow) {
|
|
9011
10769
|
dispatch({ type: "slashPickerMove", delta: -1 });
|
|
9012
10770
|
return;
|
|
@@ -9043,6 +10801,10 @@ function App({
|
|
|
9043
10801
|
dispatch({ type: "pickerClose" });
|
|
9044
10802
|
return;
|
|
9045
10803
|
}
|
|
10804
|
+
if (key.mouse?.kind === "wheel") {
|
|
10805
|
+
dispatch({ type: "pickerMove", delta: key.mouse.wheel > 0 ? -1 : 1 });
|
|
10806
|
+
return;
|
|
10807
|
+
}
|
|
9046
10808
|
if (key.upArrow) {
|
|
9047
10809
|
dispatch({ type: "pickerMove", delta: -1 });
|
|
9048
10810
|
return;
|
|
@@ -9169,6 +10931,24 @@ function App({
|
|
|
9169
10931
|
if (state.helpOpen) dispatch({ type: "toggleHelp" });
|
|
9170
10932
|
dispatch({ type: "toggleTodosMonitor" });
|
|
9171
10933
|
};
|
|
10934
|
+
if (key.fn === 1) {
|
|
10935
|
+
if (state.projectPicker.open) {
|
|
10936
|
+
dispatch({ type: "projectPickerClose" });
|
|
10937
|
+
} else {
|
|
10938
|
+
if (state.agentsMonitorOpen) dispatch({ type: "toggleAgentsMonitor" });
|
|
10939
|
+
if (state.monitorOpen) dispatch({ type: "toggleMonitor" });
|
|
10940
|
+
if (state.worktreeMonitorOpen) dispatch({ type: "worktreeMonitorToggle" });
|
|
10941
|
+
if (state.todosMonitorOpen) dispatch({ type: "toggleTodosMonitor" });
|
|
10942
|
+
if (state.autoPhase?.monitorOpen) dispatch({ type: "autoPhaseMonitorToggle" });
|
|
10943
|
+
if (state.settingsPicker.open) dispatch({ type: "settingsClose" });
|
|
10944
|
+
if (state.queuePanelOpen) dispatch({ type: "toggleQueuePanel" });
|
|
10945
|
+
if (state.processListOpen) dispatch({ type: "toggleProcessList" });
|
|
10946
|
+
if (state.goalPanelOpen) dispatch({ type: "toggleGoalPanel" });
|
|
10947
|
+
if (state.helpOpen) dispatch({ type: "toggleHelp" });
|
|
10948
|
+
openProjectPicker();
|
|
10949
|
+
}
|
|
10950
|
+
return;
|
|
10951
|
+
}
|
|
9172
10952
|
if (key.ctrl && input === "f" || key.fn === 2) {
|
|
9173
10953
|
toggleFleetOverlay();
|
|
9174
10954
|
return;
|
|
@@ -9181,47 +10961,6 @@ function App({
|
|
|
9181
10961
|
toggleWorktreeOverlay();
|
|
9182
10962
|
return;
|
|
9183
10963
|
}
|
|
9184
|
-
if (key.fn === 5) {
|
|
9185
|
-
if (state.settingsPicker.open) {
|
|
9186
|
-
dispatch({ type: "settingsClose" });
|
|
9187
|
-
} else if (getSettings && saveSettings) {
|
|
9188
|
-
if (state.agentsMonitorOpen) dispatch({ type: "toggleAgentsMonitor" });
|
|
9189
|
-
if (state.monitorOpen) dispatch({ type: "toggleMonitor" });
|
|
9190
|
-
if (state.worktreeMonitorOpen) dispatch({ type: "worktreeMonitorToggle" });
|
|
9191
|
-
if (state.todosMonitorOpen) dispatch({ type: "toggleTodosMonitor" });
|
|
9192
|
-
if (state.autoPhase?.monitorOpen) dispatch({ type: "autoPhaseMonitorToggle" });
|
|
9193
|
-
if (state.queuePanelOpen) dispatch({ type: "toggleQueuePanel" });
|
|
9194
|
-
if (state.helpOpen) dispatch({ type: "toggleHelp" });
|
|
9195
|
-
const cfg = getSettings();
|
|
9196
|
-
dispatch({
|
|
9197
|
-
type: "settingsOpen",
|
|
9198
|
-
mode: cfg.mode,
|
|
9199
|
-
delayMs: cfg.delayMs,
|
|
9200
|
-
titleAnimation: cfg.titleAnimation ?? true,
|
|
9201
|
-
yolo: cfg.yolo ?? false,
|
|
9202
|
-
streamFleet: cfg.streamFleet ?? true,
|
|
9203
|
-
chime: cfg.chime ?? false,
|
|
9204
|
-
confirmExit: cfg.confirmExit ?? true,
|
|
9205
|
-
nextPrediction: cfg.nextPrediction ?? false,
|
|
9206
|
-
featureMcp: cfg.featureMcp ?? true,
|
|
9207
|
-
featurePlugins: cfg.featurePlugins ?? true,
|
|
9208
|
-
featureMemory: cfg.featureMemory ?? true,
|
|
9209
|
-
featureSkills: cfg.featureSkills ?? true,
|
|
9210
|
-
featureModelsRegistry: cfg.featureModelsRegistry ?? true,
|
|
9211
|
-
contextAutoCompact: cfg.contextAutoCompact ?? true,
|
|
9212
|
-
contextStrategy: cfg.contextStrategy ?? "hybrid",
|
|
9213
|
-
logLevel: cfg.logLevel ?? "info",
|
|
9214
|
-
auditLevel: cfg.auditLevel ?? "standard",
|
|
9215
|
-
indexOnStart: cfg.indexOnStart ?? true,
|
|
9216
|
-
maxIterations: cfg.maxIterations ?? 500,
|
|
9217
|
-
autoProceedMaxIterations: cfg.autoProceedMaxIterations ?? 50,
|
|
9218
|
-
enhanceDelayMs: cfg.enhanceDelayMs ?? 6e4,
|
|
9219
|
-
debugStream: cfg.debugStream ?? false,
|
|
9220
|
-
configScope: cfg.configScope ?? "global"
|
|
9221
|
-
});
|
|
9222
|
-
}
|
|
9223
|
-
return;
|
|
9224
|
-
}
|
|
9225
10964
|
if (key.fn === 6) {
|
|
9226
10965
|
toggleTodosOverlay();
|
|
9227
10966
|
return;
|
|
@@ -9274,6 +11013,25 @@ function App({
|
|
|
9274
11013
|
}
|
|
9275
11014
|
return;
|
|
9276
11015
|
}
|
|
11016
|
+
if (key.fn === 10) {
|
|
11017
|
+
if (state.sessionsPanelOpen) {
|
|
11018
|
+
dispatch({ type: "toggleSessionsPanel" });
|
|
11019
|
+
} else {
|
|
11020
|
+
if (state.agentsMonitorOpen) dispatch({ type: "toggleAgentsMonitor" });
|
|
11021
|
+
if (state.monitorOpen) dispatch({ type: "toggleMonitor" });
|
|
11022
|
+
if (state.worktreeMonitorOpen) dispatch({ type: "worktreeMonitorToggle" });
|
|
11023
|
+
if (state.todosMonitorOpen) dispatch({ type: "toggleTodosMonitor" });
|
|
11024
|
+
if (state.autoPhase?.monitorOpen) dispatch({ type: "autoPhaseMonitorToggle" });
|
|
11025
|
+
if (state.settingsPicker.open) dispatch({ type: "settingsClose" });
|
|
11026
|
+
if (state.queuePanelOpen) dispatch({ type: "toggleQueuePanel" });
|
|
11027
|
+
if (state.processListOpen) dispatch({ type: "toggleProcessList" });
|
|
11028
|
+
if (state.goalPanelOpen) dispatch({ type: "toggleGoalPanel" });
|
|
11029
|
+
if (state.helpOpen) dispatch({ type: "toggleHelp" });
|
|
11030
|
+
dispatch({ type: "toggleSessionsPanel" });
|
|
11031
|
+
loadLiveSessions();
|
|
11032
|
+
}
|
|
11033
|
+
return;
|
|
11034
|
+
}
|
|
9277
11035
|
if (key.ctrl && input === "s") {
|
|
9278
11036
|
if (state.settingsPicker.open) {
|
|
9279
11037
|
dispatch({ type: "settingsClose" });
|
|
@@ -9309,6 +11067,8 @@ function App({
|
|
|
9309
11067
|
maxIterations: cfg.maxIterations ?? 500,
|
|
9310
11068
|
autoProceedMaxIterations: cfg.autoProceedMaxIterations ?? 50,
|
|
9311
11069
|
enhanceDelayMs: cfg.enhanceDelayMs ?? 6e4,
|
|
11070
|
+
enhanceEnabled: cfg.enhanceEnabled ?? true,
|
|
11071
|
+
enhanceLanguage: cfg.enhanceLanguage ?? "original",
|
|
9312
11072
|
debugStream: cfg.debugStream ?? false,
|
|
9313
11073
|
configScope: cfg.configScope ?? "global"
|
|
9314
11074
|
});
|
|
@@ -9332,6 +11092,10 @@ function App({
|
|
|
9332
11092
|
dispatch({ type: "settingsClose" });
|
|
9333
11093
|
return;
|
|
9334
11094
|
}
|
|
11095
|
+
if (state.projectPicker.open) {
|
|
11096
|
+
dispatch({ type: "projectPickerClose" });
|
|
11097
|
+
return;
|
|
11098
|
+
}
|
|
9335
11099
|
if (state.queuePanelOpen) {
|
|
9336
11100
|
dispatch({ type: "toggleQueuePanel" });
|
|
9337
11101
|
return;
|
|
@@ -9344,11 +11108,15 @@ function App({
|
|
|
9344
11108
|
dispatch({ type: "toggleGoalPanel" });
|
|
9345
11109
|
return;
|
|
9346
11110
|
}
|
|
11111
|
+
if (state.sessionsPanelOpen) {
|
|
11112
|
+
dispatch({ type: "toggleSessionsPanel" });
|
|
11113
|
+
return;
|
|
11114
|
+
}
|
|
9347
11115
|
}
|
|
9348
11116
|
if (state.processListOpen) {
|
|
9349
11117
|
return;
|
|
9350
11118
|
}
|
|
9351
|
-
if (input === "?" && !key.ctrl && !key.meta && draftRef.current.buffer === "" && !state.slashPicker.open && !state.picker.open && !state.modelPicker.open && !state.autonomyPicker.open && !state.settingsPicker.open && !state.rewindOverlay && !state.monitorOpen && !state.agentsMonitorOpen && !state.worktreeMonitorOpen && !state.todosMonitorOpen && !state.autoPhase?.monitorOpen) {
|
|
11119
|
+
if (input === "?" && !key.ctrl && !key.meta && draftRef.current.buffer === "" && !state.slashPicker.open && !state.picker.open && !state.modelPicker.open && !state.autonomyPicker.open && !state.settingsPicker.open && !state.rewindOverlay && !state.monitorOpen && !state.agentsMonitorOpen && !state.worktreeMonitorOpen && !state.todosMonitorOpen && !state.goalPanelOpen && !state.sessionsPanelOpen && !state.autoPhase?.monitorOpen) {
|
|
9352
11120
|
dispatch({ type: "toggleHelp" });
|
|
9353
11121
|
return;
|
|
9354
11122
|
}
|
|
@@ -9382,6 +11150,12 @@ function App({
|
|
|
9382
11150
|
}
|
|
9383
11151
|
if (cursor === 0) return;
|
|
9384
11152
|
const next2 = buffer.slice(0, cursor - 1) + buffer.slice(cursor);
|
|
11153
|
+
if (nextStepsAutoSubmitTimerRef.current != null) {
|
|
11154
|
+
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
11155
|
+
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
11156
|
+
setNextStepsAutoSubmitCountdown(null);
|
|
11157
|
+
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
11158
|
+
}
|
|
9385
11159
|
setDraft(next2, cursor - 1);
|
|
9386
11160
|
return;
|
|
9387
11161
|
}
|
|
@@ -9392,12 +11166,24 @@ function App({
|
|
|
9392
11166
|
const nextWordStart = afterCursor.indexOf(" ");
|
|
9393
11167
|
const end = nextWordStart === -1 ? buffer.length : cursor + nextWordStart + 1;
|
|
9394
11168
|
const next3 = buffer.slice(0, cursor) + buffer.slice(end);
|
|
11169
|
+
if (nextStepsAutoSubmitTimerRef.current != null) {
|
|
11170
|
+
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
11171
|
+
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
11172
|
+
setNextStepsAutoSubmitCountdown(null);
|
|
11173
|
+
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
11174
|
+
}
|
|
9395
11175
|
setDraft(next3, cursor);
|
|
9396
11176
|
return;
|
|
9397
11177
|
}
|
|
9398
11178
|
if (cursor >= buffer.length) return;
|
|
9399
11179
|
const span = tokenLengthForward(buffer, cursor) || 1;
|
|
9400
11180
|
const next2 = buffer.slice(0, cursor) + buffer.slice(cursor + span);
|
|
11181
|
+
if (nextStepsAutoSubmitTimerRef.current != null) {
|
|
11182
|
+
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
11183
|
+
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
11184
|
+
setNextStepsAutoSubmitCountdown(null);
|
|
11185
|
+
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
11186
|
+
}
|
|
9401
11187
|
setDraft(next2, cursor);
|
|
9402
11188
|
return;
|
|
9403
11189
|
}
|
|
@@ -9433,7 +11219,67 @@ function App({
|
|
|
9433
11219
|
setDraft(buffer, buffer.length);
|
|
9434
11220
|
return;
|
|
9435
11221
|
}
|
|
9436
|
-
const overlayOpen = state.monitorOpen || state.agentsMonitorOpen || state.worktreeMonitorOpen || state.todosMonitorOpen || state.queuePanelOpen || state.processListOpen || state.goalPanelOpen || state.helpOpen || (state.autoPhase?.monitorOpen ?? false) || state.rewindOverlay !== null;
|
|
11222
|
+
const overlayOpen = state.monitorOpen || state.agentsMonitorOpen || state.worktreeMonitorOpen || state.todosMonitorOpen || state.queuePanelOpen || state.processListOpen || state.goalPanelOpen || state.sessionsPanelOpen || state.helpOpen || (state.autoPhase?.monitorOpen ?? false) || state.rewindOverlay !== null;
|
|
11223
|
+
if (mouseMode && !overlayOpen) {
|
|
11224
|
+
if (key.mouse?.kind === "wheel") {
|
|
11225
|
+
if (key.mouse.shift) dispatch({ type: "scrollPage", dir: key.mouse.wheel > 0 ? "up" : "down" });
|
|
11226
|
+
else dispatch({ type: "scrollBy", delta: key.mouse.wheel > 0 ? 3 : -3 });
|
|
11227
|
+
return;
|
|
11228
|
+
}
|
|
11229
|
+
if ((key.mouse?.kind === "press" || key.mouse?.kind === "move") && key.mouse.button === "left") {
|
|
11230
|
+
const region = hitRegion(
|
|
11231
|
+
{ termRows, termCols: stdout?.columns ?? 80, viewportRows: state.viewportRows },
|
|
11232
|
+
key.mouse.x,
|
|
11233
|
+
key.mouse.y
|
|
11234
|
+
);
|
|
11235
|
+
if (region?.kind === "scrollbar") {
|
|
11236
|
+
dispatch({
|
|
11237
|
+
type: "scrollTo",
|
|
11238
|
+
offset: scrollOffsetForTrackRow(state.viewportRows, state.totalLines, region.cell)
|
|
11239
|
+
});
|
|
11240
|
+
return;
|
|
11241
|
+
}
|
|
11242
|
+
}
|
|
11243
|
+
if (key.mouse?.kind === "press" && key.mouse.button === "left" && statusBarWrapRef.current) {
|
|
11244
|
+
const sbHeight = measureElement(statusBarWrapRef.current).height;
|
|
11245
|
+
const belowHeight = belowStatusBarRef.current ? measureElement(belowStatusBarRef.current).height : 0;
|
|
11246
|
+
const cols = stdout?.columns ?? 80;
|
|
11247
|
+
const mx = key.mouse.x;
|
|
11248
|
+
const my = key.mouse.y;
|
|
11249
|
+
const rowFor = (line) => statusBarLineRow({ termRows, statusBarHeight: sbHeight, belowHeight, headerRows: 1, line });
|
|
11250
|
+
const inSpan = (span) => mx >= span.start + 1 && mx <= span.start + span.len;
|
|
11251
|
+
if (cols >= COMPACT_THRESHOLD && my === rowFor(0)) {
|
|
11252
|
+
const span = statusBarModelSpan({
|
|
11253
|
+
version: appVersion,
|
|
11254
|
+
state: state.status,
|
|
11255
|
+
fleetRunning: fleetCounts?.running ?? 0,
|
|
11256
|
+
model: `${liveProvider}/${liveModel}`
|
|
11257
|
+
});
|
|
11258
|
+
if (inSpan(span)) {
|
|
11259
|
+
await openModelPicker();
|
|
11260
|
+
return;
|
|
11261
|
+
}
|
|
11262
|
+
}
|
|
11263
|
+
const autoSpan = statusBarAutonomySpan({ yolo: yoloLive, autonomy: autonomyLive });
|
|
11264
|
+
if (autoSpan && my === rowFor(1) && inSpan(autoSpan)) {
|
|
11265
|
+
dispatch({ type: "autonomyPickerOpen", options: AUTONOMY_OPTIONS });
|
|
11266
|
+
return;
|
|
11267
|
+
}
|
|
11268
|
+
const todosShown = !!todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0);
|
|
11269
|
+
if (todosShown && my === rowFor(2) && inSpan(statusBarTodosSpan())) {
|
|
11270
|
+
dispatch({ type: "toggleTodosMonitor" });
|
|
11271
|
+
return;
|
|
11272
|
+
}
|
|
11273
|
+
}
|
|
11274
|
+
if (key.pageUp) {
|
|
11275
|
+
dispatch({ type: "scrollPage", dir: "up" });
|
|
11276
|
+
return;
|
|
11277
|
+
}
|
|
11278
|
+
if (key.pageDown) {
|
|
11279
|
+
dispatch({ type: "scrollPage", dir: "down" });
|
|
11280
|
+
return;
|
|
11281
|
+
}
|
|
11282
|
+
}
|
|
9437
11283
|
if (key.upArrow) {
|
|
9438
11284
|
if (!overlayOpen && state.inputHistory.length > 0) {
|
|
9439
11285
|
dispatch({ type: "historyUp" });
|
|
@@ -9465,6 +11311,12 @@ function App({
|
|
|
9465
11311
|
return;
|
|
9466
11312
|
}
|
|
9467
11313
|
if (key.ctrl && input === "u") {
|
|
11314
|
+
if (nextStepsAutoSubmitTimerRef.current != null) {
|
|
11315
|
+
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
11316
|
+
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
11317
|
+
setNextStepsAutoSubmitCountdown(null);
|
|
11318
|
+
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
11319
|
+
}
|
|
9468
11320
|
setDraft("", 0);
|
|
9469
11321
|
return;
|
|
9470
11322
|
}
|
|
@@ -9472,12 +11324,24 @@ function App({
|
|
|
9472
11324
|
if (cursor >= buffer.length) return;
|
|
9473
11325
|
const span = tokenLengthForward(buffer, cursor) || 1;
|
|
9474
11326
|
const next2 = buffer.slice(0, cursor) + buffer.slice(cursor + span);
|
|
11327
|
+
if (nextStepsAutoSubmitTimerRef.current != null) {
|
|
11328
|
+
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
11329
|
+
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
11330
|
+
setNextStepsAutoSubmitCountdown(null);
|
|
11331
|
+
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
11332
|
+
}
|
|
9475
11333
|
setDraft(next2, cursor);
|
|
9476
11334
|
return;
|
|
9477
11335
|
}
|
|
9478
11336
|
if (key.ctrl && input === "k") {
|
|
9479
11337
|
if (cursor >= buffer.length) return;
|
|
9480
11338
|
const next2 = buffer.slice(0, cursor);
|
|
11339
|
+
if (nextStepsAutoSubmitTimerRef.current != null) {
|
|
11340
|
+
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
11341
|
+
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
11342
|
+
setNextStepsAutoSubmitCountdown(null);
|
|
11343
|
+
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
11344
|
+
}
|
|
9481
11345
|
setDraft(next2, cursor);
|
|
9482
11346
|
return;
|
|
9483
11347
|
}
|
|
@@ -9495,6 +11359,12 @@ function App({
|
|
|
9495
11359
|
await commitPaste(input);
|
|
9496
11360
|
return;
|
|
9497
11361
|
}
|
|
11362
|
+
if (nextStepsAutoSubmitTimerRef.current != null) {
|
|
11363
|
+
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
11364
|
+
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
11365
|
+
setNextStepsAutoSubmitCountdown(null);
|
|
11366
|
+
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
11367
|
+
}
|
|
9498
11368
|
const next = buffer.slice(0, cursor) + input + buffer.slice(cursor);
|
|
9499
11369
|
setDraft(next, cursor + input.length);
|
|
9500
11370
|
};
|
|
@@ -9561,6 +11431,12 @@ function App({
|
|
|
9561
11431
|
} catch {
|
|
9562
11432
|
}
|
|
9563
11433
|
}
|
|
11434
|
+
if (result.status === "done" && result.finalText && onSuggestionsParsed) {
|
|
11435
|
+
try {
|
|
11436
|
+
onSuggestionsParsed(result.finalText);
|
|
11437
|
+
} catch {
|
|
11438
|
+
}
|
|
11439
|
+
}
|
|
9564
11440
|
if (tokenCounter && before) {
|
|
9565
11441
|
const after = tokenCounter.total();
|
|
9566
11442
|
const costAfter = tokenCounter.estimateCost().total;
|
|
@@ -9715,6 +11591,9 @@ function App({
|
|
|
9715
11591
|
return;
|
|
9716
11592
|
}
|
|
9717
11593
|
dispatch({ type: "resetInterrupts" });
|
|
11594
|
+
autoSubmitStreakRef.current = 0;
|
|
11595
|
+
autoSubmitCapWarnedRef.current = false;
|
|
11596
|
+
dispatch({ type: "scrollToBottom" });
|
|
9718
11597
|
const pushSubmittedHistory = () => {
|
|
9719
11598
|
if (trimmed) dispatch({ type: "historyPush", text: trimmed });
|
|
9720
11599
|
};
|
|
@@ -9755,6 +11634,25 @@ ${content}
|
|
|
9755
11634
|
const m = res.metadata.autoPhaseInit;
|
|
9756
11635
|
dispatch({ type: "autoPhaseInit", title: m.title });
|
|
9757
11636
|
}
|
|
11637
|
+
const mouseToggle = res?.metadata?.mouseToggle;
|
|
11638
|
+
if (mouseToggle) {
|
|
11639
|
+
const nextVal = mouseToggle === "on" ? true : mouseToggle === "off" ? false : mouseToggle === "toggle" ? !mouseMode : mouseMode;
|
|
11640
|
+
if (mouseToggle !== "query" && nextVal !== mouseMode) {
|
|
11641
|
+
setMouseMode(nextVal);
|
|
11642
|
+
const cur = getSettings?.();
|
|
11643
|
+
if (cur && saveSettings) {
|
|
11644
|
+
Promise.resolve(saveSettings({ ...cur, mouseMode: nextVal })).catch(() => {
|
|
11645
|
+
});
|
|
11646
|
+
}
|
|
11647
|
+
}
|
|
11648
|
+
dispatch({
|
|
11649
|
+
type: "addEntry",
|
|
11650
|
+
entry: {
|
|
11651
|
+
kind: "info",
|
|
11652
|
+
text: nextVal ? "Mouse mode: ON \u2014 wheel scrolls the chat in-app, clickable UI active. (Native scrollback off; Shift+wheel = page.)" : "Mouse mode: OFF \u2014 terminal native scrollback restored."
|
|
11653
|
+
}
|
|
11654
|
+
});
|
|
11655
|
+
}
|
|
9758
11656
|
const ctxModel = agent.ctx.model;
|
|
9759
11657
|
if (ctxModel && ctxModel !== liveModel) setLiveModel(ctxModel);
|
|
9760
11658
|
const ctxProviderId = agent.ctx.provider?.id;
|
|
@@ -9914,6 +11812,9 @@ User message:
|
|
|
9914
11812
|
clearDraft();
|
|
9915
11813
|
const blocks = await builder.submit();
|
|
9916
11814
|
if (state.status !== "idle") {
|
|
11815
|
+
if (autonomyLive === "auto" && nextStepsAutoSubmitTimerRef.current != null) {
|
|
11816
|
+
switchAutonomy?.("off");
|
|
11817
|
+
}
|
|
9917
11818
|
dispatch({
|
|
9918
11819
|
type: "addEntry",
|
|
9919
11820
|
entry: { kind: "user", text: displayText, queued: true, pasteContent }
|
|
@@ -9922,6 +11823,9 @@ User message:
|
|
|
9922
11823
|
return;
|
|
9923
11824
|
}
|
|
9924
11825
|
dispatch({ type: "addEntry", entry: { kind: "user", text: displayText, pasteContent } });
|
|
11826
|
+
if (autonomyLive === "auto" && nextStepsAutoSubmitTimerRef.current != null) {
|
|
11827
|
+
switchAutonomy?.("off");
|
|
11828
|
+
}
|
|
9925
11829
|
await runBlocks(blocks);
|
|
9926
11830
|
};
|
|
9927
11831
|
const bootInjectedRef = useRef(false);
|
|
@@ -9974,15 +11878,27 @@ User message:
|
|
|
9974
11878
|
const inputHeight = Math.max(1, inputCellRows.length);
|
|
9975
11879
|
const hideInput = enhanceActive || state.helpOpen || state.processListOpen;
|
|
9976
11880
|
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, flexShrink: 0, children: [
|
|
9977
|
-
/* @__PURE__ */ jsx(
|
|
11881
|
+
mouseMode ? /* @__PURE__ */ jsx(
|
|
11882
|
+
ScrollableHistory,
|
|
11883
|
+
{
|
|
11884
|
+
entries: state.entries,
|
|
11885
|
+
streamingText: state.streamingText,
|
|
11886
|
+
toolStream: state.toolStream,
|
|
11887
|
+
scrollOffset: state.scrollOffset,
|
|
11888
|
+
viewportRows: state.viewportRows,
|
|
11889
|
+
totalLines: state.totalLines,
|
|
11890
|
+
onMeasure: (totalLines) => dispatch({ type: "setMeasuredLines", totalLines })
|
|
11891
|
+
}
|
|
11892
|
+
) : /* @__PURE__ */ jsx(
|
|
9978
11893
|
History,
|
|
9979
11894
|
{
|
|
9980
11895
|
entries: state.entries,
|
|
11896
|
+
generation: state.historyGen,
|
|
9981
11897
|
streamingText: state.streamingText,
|
|
9982
11898
|
toolStream: state.toolStream
|
|
9983
11899
|
}
|
|
9984
11900
|
),
|
|
9985
|
-
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [
|
|
11901
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexShrink: 0, ref: bottomRegionRef, children: [
|
|
9986
11902
|
/* @__PURE__ */ jsx(
|
|
9987
11903
|
Input,
|
|
9988
11904
|
{
|
|
@@ -10033,6 +11949,16 @@ User message:
|
|
|
10033
11949
|
hint: state.autonomyPicker.hint
|
|
10034
11950
|
}
|
|
10035
11951
|
) : null,
|
|
11952
|
+
state.resumePicker.open ? /* @__PURE__ */ jsx(
|
|
11953
|
+
ResumePicker,
|
|
11954
|
+
{
|
|
11955
|
+
sessions: state.resumePicker.sessions,
|
|
11956
|
+
selected: state.resumePicker.selected,
|
|
11957
|
+
busy: state.resumePicker.busy,
|
|
11958
|
+
error: state.resumePicker.error,
|
|
11959
|
+
hint: state.resumePicker.hint
|
|
11960
|
+
}
|
|
11961
|
+
) : null,
|
|
10036
11962
|
state.settingsPicker.open ? /* @__PURE__ */ jsx(
|
|
10037
11963
|
SettingsPicker,
|
|
10038
11964
|
{
|
|
@@ -10058,11 +11984,32 @@ User message:
|
|
|
10058
11984
|
maxIterations: state.settingsPicker.maxIterations,
|
|
10059
11985
|
autoProceedMaxIterations: state.settingsPicker.autoProceedMaxIterations,
|
|
10060
11986
|
enhanceDelayMs: state.settingsPicker.enhanceDelayMs,
|
|
11987
|
+
enhanceEnabled: state.settingsPicker.enhanceEnabled,
|
|
11988
|
+
enhanceLanguage: state.settingsPicker.enhanceLanguage,
|
|
10061
11989
|
debugStream: state.settingsPicker.debugStream,
|
|
10062
11990
|
configScope: state.settingsPicker.configScope,
|
|
10063
11991
|
hint: state.settingsPicker.hint
|
|
10064
11992
|
}
|
|
10065
11993
|
) : null,
|
|
11994
|
+
state.projectPicker.open ? /* @__PURE__ */ jsx(
|
|
11995
|
+
ProjectPicker,
|
|
11996
|
+
{
|
|
11997
|
+
items: state.projectPicker.items,
|
|
11998
|
+
selected: state.projectPicker.selected,
|
|
11999
|
+
filter: state.projectPicker.filter,
|
|
12000
|
+
hint: state.projectPicker.hint
|
|
12001
|
+
}
|
|
12002
|
+
) : null,
|
|
12003
|
+
state.sessionsPanelOpen ? /* @__PURE__ */ jsx(
|
|
12004
|
+
SessionsPanel,
|
|
12005
|
+
{
|
|
12006
|
+
sessions: state.sessionsPanel.sessions,
|
|
12007
|
+
busy: state.sessionsPanel.busy,
|
|
12008
|
+
selected: state.sessionsPanel.selected,
|
|
12009
|
+
resumeConfirm: state.sessionResumeConfirm ? { sessionName: state.sessionResumeConfirm.sessionName } : void 0,
|
|
12010
|
+
currentSessionId: agent.ctx.session?.id
|
|
12011
|
+
}
|
|
12012
|
+
) : null,
|
|
10066
12013
|
state.rewindOverlay ? (() => {
|
|
10067
12014
|
const overlay = state.rewindOverlay;
|
|
10068
12015
|
return /* @__PURE__ */ jsx(
|
|
@@ -10090,7 +12037,7 @@ User message:
|
|
|
10090
12037
|
}
|
|
10091
12038
|
) }) : null,
|
|
10092
12039
|
state.confirmQueue.length > 0 && (() => {
|
|
10093
|
-
const head = expectDefined(state.confirmQueue[0]);
|
|
12040
|
+
const head = expectDefined$1(state.confirmQueue[0]);
|
|
10094
12041
|
let resolved = false;
|
|
10095
12042
|
const onDecision = (decision) => {
|
|
10096
12043
|
if (resolved) return;
|
|
@@ -10175,7 +12122,7 @@ User message:
|
|
|
10175
12122
|
}
|
|
10176
12123
|
);
|
|
10177
12124
|
})() : null,
|
|
10178
|
-
/* @__PURE__ */ jsx(
|
|
12125
|
+
/* @__PURE__ */ jsx(Box, { ref: statusBarWrapRef, flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsx(
|
|
10179
12126
|
StatusBar,
|
|
10180
12127
|
{
|
|
10181
12128
|
model: `${liveProvider}/${liveModel}`,
|
|
@@ -10189,11 +12136,13 @@ User message:
|
|
|
10189
12136
|
startedAt: startedAtRef.current,
|
|
10190
12137
|
todos,
|
|
10191
12138
|
plan: planCounts ?? void 0,
|
|
12139
|
+
tasks: taskCounts ?? void 0,
|
|
10192
12140
|
fleet: fleetCounts,
|
|
10193
12141
|
git: gitInfo,
|
|
10194
12142
|
context: contextWindow,
|
|
10195
12143
|
brain: state.brain,
|
|
10196
12144
|
projectName,
|
|
12145
|
+
workingDir: workingDirChip,
|
|
10197
12146
|
subagentCount: Object.keys(state.fleet).length,
|
|
10198
12147
|
processCount: getProcessRegistry().activeCount,
|
|
10199
12148
|
hiddenItems,
|
|
@@ -10203,67 +12152,101 @@ User message:
|
|
|
10203
12152
|
modeLabel: liveModeLabel || void 0,
|
|
10204
12153
|
debugStreamStats: state.debugStreamStats,
|
|
10205
12154
|
enhanceCountdown,
|
|
10206
|
-
|
|
12155
|
+
nextStepsAutoSubmitCountdown,
|
|
12156
|
+
autoProceedCountdown: state.countdown?.remainingSeconds ?? null,
|
|
12157
|
+
sessionCount,
|
|
12158
|
+
mailbox: mailboxStatus
|
|
10207
12159
|
}
|
|
10208
|
-
),
|
|
10209
|
-
|
|
10210
|
-
|
|
10211
|
-
AgentsMonitor,
|
|
10212
|
-
{
|
|
10213
|
-
entries: entriesWithLeader,
|
|
10214
|
-
totalCost: state.fleetCost,
|
|
10215
|
-
leaderCost: tokenCounter?.estimateCost().total ?? 0,
|
|
10216
|
-
totalTokens: state.fleetTokens,
|
|
10217
|
-
nowTick
|
|
10218
|
-
}
|
|
10219
|
-
) : state.autoPhase?.monitorOpen ? /* @__PURE__ */ jsx(
|
|
10220
|
-
PhaseMonitor,
|
|
10221
|
-
{
|
|
10222
|
-
phases: state.autoPhase.phases,
|
|
10223
|
-
runningPhaseIds: state.autoPhase.runningPhaseIds,
|
|
10224
|
-
elapsedMs: state.autoPhase.elapsedMs,
|
|
10225
|
-
nowTick,
|
|
10226
|
-
onClose: () => dispatch({ type: "autoPhaseMonitorToggle" })
|
|
10227
|
-
}
|
|
10228
|
-
) : state.worktreeMonitorOpen ? /* @__PURE__ */ jsx(
|
|
10229
|
-
WorktreeMonitor,
|
|
10230
|
-
{
|
|
10231
|
-
worktrees: state.worktrees,
|
|
10232
|
-
baseBranch: state.worktreeBase,
|
|
10233
|
-
nowTick,
|
|
10234
|
-
onClose: () => dispatch({ type: "worktreeMonitorToggle" })
|
|
10235
|
-
}
|
|
10236
|
-
) : state.todosMonitorOpen ? /* @__PURE__ */ jsx(TodosMonitor, { todos: agent.ctx.todos }) : state.monitorOpen ? /* @__PURE__ */ jsx(
|
|
10237
|
-
FleetMonitor,
|
|
10238
|
-
{
|
|
10239
|
-
entries: state.fleet,
|
|
10240
|
-
totalCost: state.fleetCost,
|
|
10241
|
-
totalTokens: state.fleetTokens,
|
|
10242
|
-
maxConcurrent: state.fleetConcurrency,
|
|
10243
|
-
nowTick,
|
|
10244
|
-
collabSession: state.collabSession
|
|
10245
|
-
}
|
|
10246
|
-
) : director ? /* @__PURE__ */ jsx(
|
|
10247
|
-
FleetPanel,
|
|
10248
|
-
{
|
|
10249
|
-
entries: entriesWithLeader,
|
|
10250
|
-
totalCost: state.fleetCost,
|
|
10251
|
-
roster: fleetRoster,
|
|
10252
|
-
collabSession: state.collabSession
|
|
10253
|
-
}
|
|
10254
|
-
) : null,
|
|
10255
|
-
state.autoPhase && !state.autoPhase.monitorOpen ? /* @__PURE__ */ jsx(
|
|
10256
|
-
PhasePanel,
|
|
12160
|
+
) }),
|
|
12161
|
+
/* @__PURE__ */ jsx(
|
|
12162
|
+
MailboxPanel,
|
|
10257
12163
|
{
|
|
10258
|
-
|
|
10259
|
-
|
|
10260
|
-
|
|
12164
|
+
messages: mailboxMessages,
|
|
12165
|
+
agents: mailboxAgents,
|
|
12166
|
+
unreadCount: mailboxStatus.unread,
|
|
12167
|
+
open: mailboxPanelOpen
|
|
10261
12168
|
}
|
|
10262
|
-
)
|
|
10263
|
-
|
|
10264
|
-
|
|
10265
|
-
|
|
10266
|
-
|
|
12169
|
+
),
|
|
12170
|
+
/* @__PURE__ */ jsxs(Box, { ref: belowStatusBarRef, flexDirection: "column", flexShrink: 0, children: [
|
|
12171
|
+
state.helpOpen ? /* @__PURE__ */ jsx(HelpOverlay, {}) : null,
|
|
12172
|
+
state.agentsMonitorOpen ? /* @__PURE__ */ jsx(
|
|
12173
|
+
AgentsMonitor,
|
|
12174
|
+
{
|
|
12175
|
+
entries: entriesWithLeader,
|
|
12176
|
+
totalCost: state.fleetCost,
|
|
12177
|
+
leaderCost: tokenCounter?.estimateCost().total ?? 0,
|
|
12178
|
+
totalTokens: state.fleetTokens,
|
|
12179
|
+
nowTick
|
|
12180
|
+
}
|
|
12181
|
+
) : state.autoPhase?.monitorOpen ? /* @__PURE__ */ jsx(
|
|
12182
|
+
PhaseMonitor,
|
|
12183
|
+
{
|
|
12184
|
+
phases: state.autoPhase.phases,
|
|
12185
|
+
runningPhaseIds: state.autoPhase.runningPhaseIds,
|
|
12186
|
+
elapsedMs: state.autoPhase.elapsedMs,
|
|
12187
|
+
nowTick,
|
|
12188
|
+
onClose: () => dispatch({ type: "autoPhaseMonitorToggle" })
|
|
12189
|
+
}
|
|
12190
|
+
) : state.worktreeMonitorOpen ? /* @__PURE__ */ jsx(
|
|
12191
|
+
WorktreeMonitor,
|
|
12192
|
+
{
|
|
12193
|
+
worktrees: state.worktrees,
|
|
12194
|
+
baseBranch: state.worktreeBase,
|
|
12195
|
+
nowTick,
|
|
12196
|
+
onClose: () => dispatch({ type: "worktreeMonitorToggle" })
|
|
12197
|
+
}
|
|
12198
|
+
) : state.todosMonitorOpen ? /* @__PURE__ */ jsx(TodosMonitor, { todos: agent.ctx.todos }) : state.monitorOpen ? /* @__PURE__ */ jsx(
|
|
12199
|
+
FleetMonitor,
|
|
12200
|
+
{
|
|
12201
|
+
entries: state.fleet,
|
|
12202
|
+
totalCost: state.fleetCost,
|
|
12203
|
+
totalTokens: state.fleetTokens,
|
|
12204
|
+
maxConcurrent: state.fleetConcurrency,
|
|
12205
|
+
nowTick,
|
|
12206
|
+
collabSession: state.collabSession
|
|
12207
|
+
}
|
|
12208
|
+
) : director ? /* @__PURE__ */ jsx(
|
|
12209
|
+
FleetPanel,
|
|
12210
|
+
{
|
|
12211
|
+
entries: entriesWithLeader,
|
|
12212
|
+
totalCost: state.fleetCost,
|
|
12213
|
+
roster: fleetRoster,
|
|
12214
|
+
collabSession: state.collabSession
|
|
12215
|
+
}
|
|
12216
|
+
) : null,
|
|
12217
|
+
state.autoPhase && !state.autoPhase.monitorOpen ? /* @__PURE__ */ jsx(
|
|
12218
|
+
PhasePanel,
|
|
12219
|
+
{
|
|
12220
|
+
phases: state.autoPhase.phases,
|
|
12221
|
+
runningPhaseIds: state.autoPhase.runningPhaseIds,
|
|
12222
|
+
nowTick
|
|
12223
|
+
}
|
|
12224
|
+
) : null,
|
|
12225
|
+
Object.keys(state.worktrees).length > 0 && !state.worktreeMonitorOpen && !state.monitorOpen ? /* @__PURE__ */ jsx(WorktreePanel, { worktrees: state.worktrees, nowTick }) : null,
|
|
12226
|
+
state.queuePanelOpen ? /* @__PURE__ */ jsx(QueuePanel, { items: state.queue }) : null,
|
|
12227
|
+
state.processListOpen ? /* @__PURE__ */ jsx(ProcessListMonitor, {}) : null,
|
|
12228
|
+
state.goalPanelOpen ? /* @__PURE__ */ jsx(GoalPanel, { goal: state.goalSummary }) : null,
|
|
12229
|
+
(() => {
|
|
12230
|
+
const anyMonitorOpen = state.agentsMonitorOpen || (state.autoPhase?.monitorOpen ?? false) || state.worktreeMonitorOpen || state.todosMonitorOpen || state.monitorOpen || state.processListOpen || state.queuePanelOpen || state.goalPanelOpen;
|
|
12231
|
+
let nextPanelHint;
|
|
12232
|
+
if (state.agentsMonitorOpen) {
|
|
12233
|
+
nextPanelHint = { key: "F6", label: "todos" };
|
|
12234
|
+
} else if (state.autoPhase?.monitorOpen || state.worktreeMonitorOpen || state.todosMonitorOpen) {
|
|
12235
|
+
nextPanelHint = { key: "F9", label: "goal" };
|
|
12236
|
+
} else if (state.queuePanelOpen || state.processListOpen || state.goalPanelOpen) {
|
|
12237
|
+
nextPanelHint = { key: "F3", label: "agents" };
|
|
12238
|
+
} else if (anyMonitorOpen) {
|
|
12239
|
+
nextPanelHint = { key: "F3", label: "agents" };
|
|
12240
|
+
}
|
|
12241
|
+
const ctx = {
|
|
12242
|
+
monitor: anyMonitorOpen,
|
|
12243
|
+
managed: state.scrollOffset > 0,
|
|
12244
|
+
picker: state.settingsPicker.open || state.modelPicker.open || state.autonomyPicker.open,
|
|
12245
|
+
nextPanelHint
|
|
12246
|
+
};
|
|
12247
|
+
return /* @__PURE__ */ jsx(KeyHintBar, { context: ctx });
|
|
12248
|
+
})()
|
|
12249
|
+
] })
|
|
10267
12250
|
] })
|
|
10268
12251
|
] }) });
|
|
10269
12252
|
}
|
|
@@ -10365,6 +12348,45 @@ function startTerminalTitle(opts) {
|
|
|
10365
12348
|
// src/run-tui.ts
|
|
10366
12349
|
var BRACKETED_PASTE_ON = "\x1B[?2004h";
|
|
10367
12350
|
var BRACKETED_PASTE_OFF = "\x1B[?2004l";
|
|
12351
|
+
var origConsoleLog = console.log;
|
|
12352
|
+
var origConsoleWarn = console.warn;
|
|
12353
|
+
var origConsoleError = console.error;
|
|
12354
|
+
var origConsoleDebug = console.debug;
|
|
12355
|
+
var origConsoleInfo = console.info;
|
|
12356
|
+
var origConsoleTable = console.table;
|
|
12357
|
+
var origConsoleTrace = console.trace;
|
|
12358
|
+
var origStderrWrite = process.stderr.write.bind(process.stderr);
|
|
12359
|
+
var consoleNoop = (..._args) => {
|
|
12360
|
+
};
|
|
12361
|
+
var stderrNoop = ((_chunk, _encodingOrCb, _cb) => {
|
|
12362
|
+
if (typeof _encodingOrCb === "function") _encodingOrCb();
|
|
12363
|
+
else if (typeof _cb === "function") _cb();
|
|
12364
|
+
return true;
|
|
12365
|
+
});
|
|
12366
|
+
var warningNoop = (_warning) => {
|
|
12367
|
+
};
|
|
12368
|
+
function silenceTerminal() {
|
|
12369
|
+
console.log = consoleNoop;
|
|
12370
|
+
console.warn = consoleNoop;
|
|
12371
|
+
console.error = consoleNoop;
|
|
12372
|
+
console.debug = consoleNoop;
|
|
12373
|
+
console.info = consoleNoop;
|
|
12374
|
+
console.table = consoleNoop;
|
|
12375
|
+
console.trace = consoleNoop;
|
|
12376
|
+
process.stderr.write = stderrNoop;
|
|
12377
|
+
process.on("warning", warningNoop);
|
|
12378
|
+
}
|
|
12379
|
+
function unsilenceTerminal() {
|
|
12380
|
+
console.log = origConsoleLog;
|
|
12381
|
+
console.warn = origConsoleWarn;
|
|
12382
|
+
console.error = origConsoleError;
|
|
12383
|
+
console.debug = origConsoleDebug;
|
|
12384
|
+
console.info = origConsoleInfo;
|
|
12385
|
+
console.table = origConsoleTable;
|
|
12386
|
+
console.trace = origConsoleTrace;
|
|
12387
|
+
process.stderr.write = origStderrWrite;
|
|
12388
|
+
process.off("warning", warningNoop);
|
|
12389
|
+
}
|
|
10368
12390
|
async function runTui(opts) {
|
|
10369
12391
|
const stdout = process.stdout;
|
|
10370
12392
|
const stdin = process.stdin;
|
|
@@ -10374,14 +12396,16 @@ async function runTui(opts) {
|
|
|
10374
12396
|
);
|
|
10375
12397
|
return 2;
|
|
10376
12398
|
}
|
|
12399
|
+
silenceTerminal();
|
|
10377
12400
|
stdout.write(BRACKETED_PASTE_ON);
|
|
12401
|
+
const mouseEnabled = opts.mouse ?? opts.getSettings?.().mouseMode ?? process.env.WRONGSTACK_MOUSE === "1";
|
|
10378
12402
|
stdout.write("\x1B[2J\x1B[H");
|
|
10379
12403
|
const inkStdin = stdin;
|
|
10380
12404
|
const stopTitle = opts.titleAnimation !== false ? startTerminalTitle({
|
|
10381
12405
|
stdout,
|
|
10382
12406
|
events: opts.events,
|
|
10383
12407
|
model: opts.model,
|
|
10384
|
-
appName: opts.projectRoot ?
|
|
12408
|
+
appName: opts.projectRoot ? path4.basename(opts.projectRoot) : void 0
|
|
10385
12409
|
}) : (() => {
|
|
10386
12410
|
});
|
|
10387
12411
|
const swallowSignals = ["SIGTSTP", "SIGQUIT", "SIGTTIN", "SIGTTOU"];
|
|
@@ -10397,12 +12421,14 @@ async function runTui(opts) {
|
|
|
10397
12421
|
const cleanup = () => {
|
|
10398
12422
|
if (cleaned) return;
|
|
10399
12423
|
cleaned = true;
|
|
12424
|
+
unsilenceTerminal();
|
|
10400
12425
|
try {
|
|
10401
12426
|
stopTitle();
|
|
10402
12427
|
} catch {
|
|
10403
12428
|
}
|
|
10404
12429
|
try {
|
|
10405
12430
|
stdout.write(BRACKETED_PASTE_OFF);
|
|
12431
|
+
stdout.write(MOUSE_OFF);
|
|
10406
12432
|
} catch {
|
|
10407
12433
|
}
|
|
10408
12434
|
};
|
|
@@ -10423,14 +12449,26 @@ async function runTui(opts) {
|
|
|
10423
12449
|
};
|
|
10424
12450
|
return new Promise((resolve) => {
|
|
10425
12451
|
let exitCode = 0;
|
|
12452
|
+
let hardExitTimer = null;
|
|
10426
12453
|
const onExit = (code) => {
|
|
10427
12454
|
exitCode = code;
|
|
10428
12455
|
};
|
|
10429
12456
|
const settle = (code) => {
|
|
12457
|
+
if (hardExitTimer) {
|
|
12458
|
+
clearTimeout(hardExitTimer);
|
|
12459
|
+
hardExitTimer = null;
|
|
12460
|
+
}
|
|
10430
12461
|
cleanup();
|
|
10431
12462
|
detachListeners();
|
|
10432
12463
|
resolve(code);
|
|
10433
12464
|
};
|
|
12465
|
+
const requestExit = (code) => {
|
|
12466
|
+
onExit(code);
|
|
12467
|
+
instance?.unmount();
|
|
12468
|
+
hardExitTimer = setTimeout(() => process.exit(code), 5e3);
|
|
12469
|
+
hardExitTimer.unref();
|
|
12470
|
+
};
|
|
12471
|
+
opts.requestExit = requestExit;
|
|
10434
12472
|
let instance;
|
|
10435
12473
|
try {
|
|
10436
12474
|
instance = render(
|
|
@@ -10445,6 +12483,7 @@ async function runTui(opts) {
|
|
|
10445
12483
|
model: opts.model,
|
|
10446
12484
|
banner: opts.banner ?? true,
|
|
10447
12485
|
queueStore: opts.queueStore,
|
|
12486
|
+
onQueueChange: opts.onQueueChange,
|
|
10448
12487
|
yolo: opts.yolo,
|
|
10449
12488
|
getYolo: opts.getYolo,
|
|
10450
12489
|
getAutonomy: opts.getAutonomy,
|
|
@@ -10480,12 +12519,24 @@ async function runTui(opts) {
|
|
|
10480
12519
|
getSettings: opts.getSettings,
|
|
10481
12520
|
saveSettings: opts.saveSettings,
|
|
10482
12521
|
predictNext: opts.predictNext,
|
|
12522
|
+
onSuggestionsParsed: opts.onSuggestionsParsed,
|
|
10483
12523
|
chime: opts.chime,
|
|
10484
12524
|
confirmExit: opts.confirmExit,
|
|
12525
|
+
mouse: mouseEnabled,
|
|
10485
12526
|
modeLabel: opts.modeLabel,
|
|
10486
12527
|
getModeLabel: opts.getModeLabel,
|
|
10487
12528
|
registerDebugStreamCallback: opts.registerDebugStreamCallback,
|
|
10488
|
-
restoreDebugStreamCallback: opts.restoreDebugStreamCallback
|
|
12529
|
+
restoreDebugStreamCallback: opts.restoreDebugStreamCallback,
|
|
12530
|
+
restoredMessages: opts.restoredMessages,
|
|
12531
|
+
restoredToolCalls: opts.restoredToolCalls,
|
|
12532
|
+
listSessions: opts.listSessions,
|
|
12533
|
+
onResumeSession: opts.onResumeSession,
|
|
12534
|
+
getProjectPickerItems: opts.getProjectPickerItems,
|
|
12535
|
+
onProjectSelect: opts.onProjectSelect,
|
|
12536
|
+
requestExit: opts.requestExit,
|
|
12537
|
+
getLiveSessions: opts.getLiveSessions,
|
|
12538
|
+
onSwitchToSession: opts.onSwitchToSession,
|
|
12539
|
+
initialAgentsMonitorOpen: opts.initialAgentsMonitorOpen
|
|
10489
12540
|
}),
|
|
10490
12541
|
{ exitOnCtrlC: false, stdin: inkStdin }
|
|
10491
12542
|
);
|
|
@@ -10516,6 +12567,190 @@ async function runTui(opts) {
|
|
|
10516
12567
|
});
|
|
10517
12568
|
}
|
|
10518
12569
|
|
|
10519
|
-
|
|
12570
|
+
// src/components/history/replay.ts
|
|
12571
|
+
function replaySessionEvents(events, startId) {
|
|
12572
|
+
const entries = [];
|
|
12573
|
+
let nextId = startId;
|
|
12574
|
+
const pendingTools = /* @__PURE__ */ new Map();
|
|
12575
|
+
const completedTools = /* @__PURE__ */ new Set();
|
|
12576
|
+
for (const ev of events) {
|
|
12577
|
+
const entry = eventToEntry(ev, pendingTools, completedTools);
|
|
12578
|
+
if (entry) {
|
|
12579
|
+
entries.push({ ...entry, id: nextId++ });
|
|
12580
|
+
}
|
|
12581
|
+
}
|
|
12582
|
+
for (const [, tu] of pendingTools) {
|
|
12583
|
+
entries.push({
|
|
12584
|
+
id: nextId++,
|
|
12585
|
+
kind: "tool",
|
|
12586
|
+
name: tu.name,
|
|
12587
|
+
durationMs: 0,
|
|
12588
|
+
ok: false,
|
|
12589
|
+
input: tu.input
|
|
12590
|
+
});
|
|
12591
|
+
}
|
|
12592
|
+
return entries;
|
|
12593
|
+
}
|
|
12594
|
+
function eventToEntry(ev, pendingTools, completedTools) {
|
|
12595
|
+
switch (ev.type) {
|
|
12596
|
+
case "user_input": {
|
|
12597
|
+
const text = typeof ev.content === "string" ? ev.content : Array.isArray(ev.content) ? ev.content.filter((b) => b.type === "text").map((b) => b.text).join("") : "";
|
|
12598
|
+
if (!text.trim()) return null;
|
|
12599
|
+
return { kind: "user", text };
|
|
12600
|
+
}
|
|
12601
|
+
case "llm_response": {
|
|
12602
|
+
const text = ev.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
12603
|
+
if (!text.trim()) return null;
|
|
12604
|
+
return { kind: "assistant", text };
|
|
12605
|
+
}
|
|
12606
|
+
case "tool_use": {
|
|
12607
|
+
pendingTools.set(ev.id, { name: ev.name, input: ev.input, ts: ev.ts });
|
|
12608
|
+
return null;
|
|
12609
|
+
}
|
|
12610
|
+
case "tool_result": {
|
|
12611
|
+
if (completedTools.has(ev.id)) {
|
|
12612
|
+
completedTools.delete(ev.id);
|
|
12613
|
+
return null;
|
|
12614
|
+
}
|
|
12615
|
+
const tu = pendingTools.get(ev.id);
|
|
12616
|
+
pendingTools.delete(ev.id);
|
|
12617
|
+
return {
|
|
12618
|
+
kind: "tool",
|
|
12619
|
+
name: tu?.name ?? ev.id,
|
|
12620
|
+
durationMs: 0,
|
|
12621
|
+
// duration not available from tool_result alone
|
|
12622
|
+
ok: !ev.isError,
|
|
12623
|
+
input: tu?.input,
|
|
12624
|
+
output: typeof ev.content === "string" ? ev.content.slice(0, 400) : void 0
|
|
12625
|
+
};
|
|
12626
|
+
}
|
|
12627
|
+
case "tool_call_start": {
|
|
12628
|
+
pendingTools.set(ev.id, { name: ev.name, input: ev.input, ts: ev.ts });
|
|
12629
|
+
return null;
|
|
12630
|
+
}
|
|
12631
|
+
case "tool_call_end": {
|
|
12632
|
+
const tu = pendingTools.get(ev.id);
|
|
12633
|
+
pendingTools.delete(ev.id);
|
|
12634
|
+
completedTools.add(ev.id);
|
|
12635
|
+
return {
|
|
12636
|
+
kind: "tool",
|
|
12637
|
+
name: tu?.name ?? ev.name,
|
|
12638
|
+
durationMs: ev.durationMs,
|
|
12639
|
+
ok: ev.ok ?? false,
|
|
12640
|
+
input: tu?.input,
|
|
12641
|
+
outputBytes: ev.outputBytes,
|
|
12642
|
+
outputTokens: ev.outputTokens,
|
|
12643
|
+
outputLines: ev.outputLines
|
|
12644
|
+
};
|
|
12645
|
+
}
|
|
12646
|
+
case "compaction": {
|
|
12647
|
+
const before = (ev.before / 1e3).toFixed(0);
|
|
12648
|
+
const after = (ev.after / 1e3).toFixed(0);
|
|
12649
|
+
const level = ev.level ? ` (${ev.level})` : "";
|
|
12650
|
+
const reductions = ev.reductions && ev.reductions.length > 0 ? ` [${ev.reductions.map((r) => `${r.phase}: \u2212${r.saved}`).join(", ")}]` : "";
|
|
12651
|
+
return {
|
|
12652
|
+
kind: "info",
|
|
12653
|
+
text: `\u27F2 context compacted${level}: ${before}K \u2192 ${after}K tokens${reductions}`
|
|
12654
|
+
};
|
|
12655
|
+
}
|
|
12656
|
+
case "error": {
|
|
12657
|
+
return {
|
|
12658
|
+
kind: "error",
|
|
12659
|
+
text: ev.phase ? `[${ev.phase}] ${ev.message}` : ev.message
|
|
12660
|
+
};
|
|
12661
|
+
}
|
|
12662
|
+
case "provider_retry": {
|
|
12663
|
+
const secs = (ev.delayMs / 1e3).toFixed(ev.delayMs >= 1e3 ? 1 : 2);
|
|
12664
|
+
return {
|
|
12665
|
+
kind: "warn",
|
|
12666
|
+
text: ev.status ? `\u27F3 retry ${ev.attempt} (HTTP ${ev.status}) after ${secs}s \u2014 ${ev.description}` : `\u27F3 retry ${ev.attempt} after ${secs}s \u2014 ${ev.description}`
|
|
12667
|
+
};
|
|
12668
|
+
}
|
|
12669
|
+
case "provider_error": {
|
|
12670
|
+
return {
|
|
12671
|
+
kind: "error",
|
|
12672
|
+
text: ev.status ? `provider error (HTTP ${ev.status}, ${ev.retryable ? "retryable" : "fatal"}): ${ev.description}` : `provider error (${ev.retryable ? "retryable" : "fatal"}): ${ev.description}`
|
|
12673
|
+
};
|
|
12674
|
+
}
|
|
12675
|
+
case "checkpoint": {
|
|
12676
|
+
return {
|
|
12677
|
+
kind: "info",
|
|
12678
|
+
text: `\u2713 checkpoint #${ev.promptIndex}: "${ev.promptPreview.slice(0, 60)}"`
|
|
12679
|
+
};
|
|
12680
|
+
}
|
|
12681
|
+
case "agent_spawned": {
|
|
12682
|
+
return {
|
|
12683
|
+
kind: "subagent",
|
|
12684
|
+
agentLabel: ev.agentId.slice(0, 8),
|
|
12685
|
+
agentColor: "magenta",
|
|
12686
|
+
icon: "\u26A1",
|
|
12687
|
+
text: `spawned as ${ev.role}`
|
|
12688
|
+
};
|
|
12689
|
+
}
|
|
12690
|
+
case "agent_stopped": {
|
|
12691
|
+
return {
|
|
12692
|
+
kind: "subagent",
|
|
12693
|
+
agentLabel: ev.agentId.slice(0, 8),
|
|
12694
|
+
agentColor: "gray",
|
|
12695
|
+
icon: "\u2298",
|
|
12696
|
+
text: "stopped"
|
|
12697
|
+
};
|
|
12698
|
+
}
|
|
12699
|
+
case "agent_error": {
|
|
12700
|
+
return {
|
|
12701
|
+
kind: "subagent",
|
|
12702
|
+
agentLabel: ev.agentId.slice(0, 8),
|
|
12703
|
+
agentColor: "red",
|
|
12704
|
+
icon: "\u2717",
|
|
12705
|
+
text: `error: ${ev.error.slice(0, 80)}`
|
|
12706
|
+
};
|
|
12707
|
+
}
|
|
12708
|
+
case "mode_changed": {
|
|
12709
|
+
return {
|
|
12710
|
+
kind: "info",
|
|
12711
|
+
text: `mode: ${ev.from} \u2192 ${ev.to}`
|
|
12712
|
+
};
|
|
12713
|
+
}
|
|
12714
|
+
case "skill_activated": {
|
|
12715
|
+
return {
|
|
12716
|
+
kind: "info",
|
|
12717
|
+
text: `skill activated: ${ev.skillName}`
|
|
12718
|
+
};
|
|
12719
|
+
}
|
|
12720
|
+
case "skill_deactivated": {
|
|
12721
|
+
return {
|
|
12722
|
+
kind: "info",
|
|
12723
|
+
text: `skill deactivated: ${ev.skillName}`
|
|
12724
|
+
};
|
|
12725
|
+
}
|
|
12726
|
+
case "message_truncated": {
|
|
12727
|
+
return {
|
|
12728
|
+
kind: "warn",
|
|
12729
|
+
text: ev.after < ev.before ? `message truncated: ${ev.before} \u2192 ${ev.after} tokens` : `message truncated at ${ev.after} tokens`
|
|
12730
|
+
};
|
|
12731
|
+
}
|
|
12732
|
+
// Skipped — internal markers not relevant for display
|
|
12733
|
+
case "session_start":
|
|
12734
|
+
case "session_resumed":
|
|
12735
|
+
case "session_end":
|
|
12736
|
+
case "in_flight_start":
|
|
12737
|
+
case "in_flight_end":
|
|
12738
|
+
case "llm_request":
|
|
12739
|
+
case "tool_progress":
|
|
12740
|
+
case "rewound":
|
|
12741
|
+
case "file_snapshot":
|
|
12742
|
+
case "task_created":
|
|
12743
|
+
case "task_updated":
|
|
12744
|
+
case "task_completed":
|
|
12745
|
+
case "task_failed":
|
|
12746
|
+
case "spec_parsed":
|
|
12747
|
+
case "spec_analyzed":
|
|
12748
|
+
return null;
|
|
12749
|
+
default:
|
|
12750
|
+
return null;
|
|
12751
|
+
}
|
|
12752
|
+
}
|
|
12753
|
+
|
|
12754
|
+
export { parseInline, replaySessionEvents, runTui };
|
|
10520
12755
|
//# sourceMappingURL=index.js.map
|
|
10521
12756
|
//# sourceMappingURL=index.js.map
|