@wrongstack/tui 0.119.1 → 0.148.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 +2 -0
- package/dist/index.js +202 -148
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { expectDefined, writeErr, resolveWstackPaths, loadGoal, InputBuilder, DefaultSessionRewinder, writeOut, formatTodosList, buildGoalPreamble, shouldEnhance, enhanceUserPrompt, recentTextTurns, normalizedEqual, buildChildEnv } from '@wrongstack/core';
|
|
2
2
|
export { buildGoalPreamble } from '@wrongstack/core';
|
|
3
3
|
import { Box, Text, useInput, useStdin, useStdout, render, useApp, Static } from 'ink';
|
|
4
|
-
import
|
|
4
|
+
import React5, { useState, useEffect, memo, useRef, useCallback, useReducer, useMemo } from 'react';
|
|
5
5
|
import * as fs2 from 'fs/promises';
|
|
6
6
|
import * as path2 from 'path';
|
|
7
7
|
import { routeImagesForModel } from '@wrongstack/runtime/vision';
|
|
@@ -59,7 +59,9 @@ function StatusBar({
|
|
|
59
59
|
goalSummary,
|
|
60
60
|
indexState,
|
|
61
61
|
modeLabel,
|
|
62
|
-
debugStreamStats
|
|
62
|
+
debugStreamStats,
|
|
63
|
+
enhanceCountdown,
|
|
64
|
+
autoProceedCountdown
|
|
63
65
|
}) {
|
|
64
66
|
const { stdout } = useStdout();
|
|
65
67
|
const [termWidth, setTermWidth] = useState(stdout?.columns ?? 90);
|
|
@@ -96,11 +98,13 @@ function StatusBar({
|
|
|
96
98
|
const { label: stateLabel, color: stateColor } = stateChip(state, fleet?.running ?? 0);
|
|
97
99
|
const statePrefix = state === "idle" || state === "aborting" ? "\u25CF" : spinner;
|
|
98
100
|
const thinking = state === "running" || state === "streaming";
|
|
99
|
-
const
|
|
101
|
+
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;
|
|
100
103
|
const fleetHasActivity = fleet && (fleet.running > 0 || fleet.idle > 0 || fleet.pending > 0 || fleet.completed > 0) || subagentCount > 0;
|
|
101
104
|
const hasBrainActivity = !!brain && brain.state !== "idle";
|
|
102
105
|
const hasDebugStream = !!debugStreamStats;
|
|
103
|
-
const
|
|
106
|
+
const hasEnhanceCountdown = enhanceCountdown != null && enhanceCountdown > 0;
|
|
107
|
+
const hasThirdLine = todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || fleetHasActivity || hasBrainActivity || hasDebugStream || hasEnhanceCountdown;
|
|
104
108
|
return /* @__PURE__ */ jsxs(
|
|
105
109
|
Box,
|
|
106
110
|
{
|
|
@@ -267,6 +271,14 @@ function StatusBar({
|
|
|
267
271
|
yolo || autonomy && autonomy !== "off" || eternalStage || startedAt != null || projectName || goalSummary ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
268
272
|
/* @__PURE__ */ jsx(Text, { color: "cyan", children: modeIcon(modeLabel) })
|
|
269
273
|
] }) : null,
|
|
274
|
+
hasAutoProceed ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
275
|
+
yolo || autonomy && autonomy !== "off" || eternalStage || startedAt != null || projectName || goalSummary || modeLabel ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
276
|
+
/* @__PURE__ */ jsxs(Text, { color: autoProceedCountdown != null && autoProceedCountdown <= 5 ? "yellow" : "cyan", children: [
|
|
277
|
+
"\u23F3 auto in ",
|
|
278
|
+
autoProceedCountdown,
|
|
279
|
+
"s"
|
|
280
|
+
] })
|
|
281
|
+
] }) : null,
|
|
270
282
|
git ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
271
283
|
yolo || startedAt != null || projectName ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
272
284
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
@@ -385,6 +397,14 @@ function StatusBar({
|
|
|
385
397
|
fmtDebugBytes(debugStreamStats.totalBytes)
|
|
386
398
|
] })
|
|
387
399
|
] })
|
|
400
|
+
] }) : null,
|
|
401
|
+
hasEnhanceCountdown && enhanceCountdown != null ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
402
|
+
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || fleetHasActivity || hasBrainActivity || hasDebugStream ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
403
|
+
/* @__PURE__ */ jsxs(Text, { color: enhanceCountdown <= 5 ? "yellow" : "cyan", children: [
|
|
404
|
+
"\u23F3 auto-send in ",
|
|
405
|
+
enhanceCountdown,
|
|
406
|
+
"s"
|
|
407
|
+
] })
|
|
388
408
|
] }) : null
|
|
389
409
|
] }) : /* @__PURE__ */ jsx(Box, { height: 1, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
|
|
390
410
|
fleetAgents && fleetAgents.length > 0 ? /* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 2, children: fleetAgents.map((a, i) => (
|
|
@@ -518,7 +538,7 @@ var WAVE_COLORS = [
|
|
|
518
538
|
function WaveText({ text, phase }) {
|
|
519
539
|
return /* @__PURE__ */ jsx(Text, { bold: true, children: Array.from(text).map((ch, i) => (
|
|
520
540
|
// biome-ignore lint/suspicious/noArrayIndexKey: glyph order is positional and re-rendered each tick
|
|
521
|
-
/* @__PURE__ */ jsx(Text, { color: WAVE_COLORS[(i + phase) % WAVE_COLORS.length], children: ch }, i)
|
|
541
|
+
/* @__PURE__ */ jsx(Text, { color: WAVE_COLORS[(i + phase) % WAVE_COLORS.length] ?? "#ffffff", children: ch }, i)
|
|
522
542
|
)) });
|
|
523
543
|
}
|
|
524
544
|
var FILLED = "\u2588";
|
|
@@ -715,7 +735,7 @@ function FleetMonitor({
|
|
|
715
735
|
] }),
|
|
716
736
|
collabSession.overallVerdict ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
717
737
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
718
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color: VERDICT_COLOR[collabSession.overallVerdict], children: collabSession.overallVerdict })
|
|
738
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: VERDICT_COLOR[collabSession.overallVerdict] ?? "white", children: collabSession.overallVerdict })
|
|
719
739
|
] }) : null
|
|
720
740
|
] }),
|
|
721
741
|
collabSession.timeline.length > 0 ? /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: 0, children: collabSession.timeline.slice(0, 6).map((ev, i) => (
|
|
@@ -861,12 +881,8 @@ function AgentRow({
|
|
|
861
881
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
862
882
|
/* @__PURE__ */ jsx(Text, { color: selected ? "magenta" : "gray", children: selected ? "\u25B6" : " " }),
|
|
863
883
|
/* @__PURE__ */ jsx(Text, { color: s2.color, bold: true, children: s2.icon }),
|
|
864
|
-
/* @__PURE__ */ jsx(Text, { bold: selected,
|
|
884
|
+
/* @__PURE__ */ jsx(Text, { bold: selected, ...selected ? { color: "magenta" } : {}, children: entry.name }),
|
|
865
885
|
modelLabel ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: modelLabel }) : null,
|
|
866
|
-
entry.provider || entry.model ? /* @__PURE__ */ jsxs(Text, { color: "blue", children: [
|
|
867
|
-
entry.provider ? `${entry.provider}/` : "",
|
|
868
|
-
entry.model ?? ""
|
|
869
|
-
] }) : null,
|
|
870
886
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
871
887
|
"L",
|
|
872
888
|
entry.iterations,
|
|
@@ -904,6 +920,7 @@ function AgentDetail({
|
|
|
904
920
|
const lastTool = entry.recentTools[entry.recentTools.length - 1];
|
|
905
921
|
const lastMessage = entry.recentMessages[entry.recentMessages.length - 1];
|
|
906
922
|
const streamTail = entry.streamingText ? snippet(entry.streamingText.slice(-160)) : "";
|
|
923
|
+
const modelLabel = fmtModelLabel(entry.provider, entry.model);
|
|
907
924
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingLeft: 4, borderStyle: "single", borderColor: "magenta", borderLeft: true, children: [
|
|
908
925
|
spark || lastTool ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
909
926
|
/* @__PURE__ */ jsx(Text, { color: "green", children: spark || "" }),
|
|
@@ -914,7 +931,7 @@ function AgentDetail({
|
|
|
914
931
|
lastTool.ok === false ? " \u2717" : ""
|
|
915
932
|
] }) : null
|
|
916
933
|
] }) : null,
|
|
917
|
-
entry.provider || entry.model ? /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
934
|
+
!modelLabel && (entry.provider || entry.model) ? /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
918
935
|
"provider: ",
|
|
919
936
|
entry.provider || "(leader)",
|
|
920
937
|
" \xB7 model: ",
|
|
@@ -1290,7 +1307,7 @@ function ConfirmPrompt({
|
|
|
1290
1307
|
suggestedPattern,
|
|
1291
1308
|
onDecision
|
|
1292
1309
|
}) {
|
|
1293
|
-
|
|
1310
|
+
React5.useEffect(() => {
|
|
1294
1311
|
writeOut("\x07");
|
|
1295
1312
|
}, []);
|
|
1296
1313
|
useInput((input2, _key) => {
|
|
@@ -1319,7 +1336,7 @@ function ConfirmPrompt({
|
|
|
1319
1336
|
inputSummary ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: inputSummary }) : null,
|
|
1320
1337
|
showDiff && diff ? /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginY: 1, children: renderDiff(diff) }) : null,
|
|
1321
1338
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }),
|
|
1322
|
-
/* @__PURE__ */ jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsx(Text, { children: buttonLabels(suggestedPattern).map((l) => /* @__PURE__ */ jsxs(
|
|
1339
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsx(Text, { children: buttonLabels(suggestedPattern).map((l) => /* @__PURE__ */ jsxs(React5.Fragment, { children: [
|
|
1323
1340
|
/* @__PURE__ */ jsx(Text, { bold: true, color: BUTTON_COLOR[l.decision], children: l.bracket }),
|
|
1324
1341
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: l.rest })
|
|
1325
1342
|
] }, l.decision)) }) })
|
|
@@ -1330,22 +1347,24 @@ function EnhancePanel({
|
|
|
1330
1347
|
refined,
|
|
1331
1348
|
english,
|
|
1332
1349
|
delayMs,
|
|
1333
|
-
onDecision
|
|
1350
|
+
onDecision,
|
|
1351
|
+
onTick
|
|
1334
1352
|
}) {
|
|
1335
1353
|
const totalSecs = Math.max(1, Math.ceil(delayMs / 1e3));
|
|
1336
|
-
const
|
|
1337
|
-
const decideRef =
|
|
1354
|
+
const remainingRef = React5.useRef(totalSecs);
|
|
1355
|
+
const decideRef = React5.useRef(onDecision);
|
|
1338
1356
|
decideRef.current = onDecision;
|
|
1339
|
-
|
|
1357
|
+
const tickRef = React5.useRef(onTick);
|
|
1358
|
+
tickRef.current = onTick;
|
|
1359
|
+
React5.useEffect(() => {
|
|
1340
1360
|
const id = setInterval(() => {
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
});
|
|
1361
|
+
const r = remainingRef.current - 1;
|
|
1362
|
+
remainingRef.current = r;
|
|
1363
|
+
tickRef.current?.(r);
|
|
1364
|
+
if (r <= 0) {
|
|
1365
|
+
clearInterval(id);
|
|
1366
|
+
decideRef.current("refined");
|
|
1367
|
+
}
|
|
1349
1368
|
}, 1e3);
|
|
1350
1369
|
return () => clearInterval(id);
|
|
1351
1370
|
}, []);
|
|
@@ -1361,15 +1380,7 @@ function EnhancePanel({
|
|
|
1361
1380
|
}
|
|
1362
1381
|
});
|
|
1363
1382
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
|
|
1364
|
-
/* @__PURE__ */
|
|
1365
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u2728 Refined request" }),
|
|
1366
|
-
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
1367
|
-
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1368
|
-
"\u2014 sending in ",
|
|
1369
|
-
remaining,
|
|
1370
|
-
"s"
|
|
1371
|
-
] })
|
|
1372
|
-
] }),
|
|
1383
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u2728 Refined request" }) }),
|
|
1373
1384
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
|
|
1374
1385
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "original: " }),
|
|
1375
1386
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: original })
|
|
@@ -3112,7 +3123,7 @@ function streamBoxRows(text, maxLines, contentWidth) {
|
|
|
3112
3123
|
}
|
|
3113
3124
|
return rows;
|
|
3114
3125
|
}
|
|
3115
|
-
|
|
3126
|
+
React5.memo(function ToolStreamBox2({
|
|
3116
3127
|
name,
|
|
3117
3128
|
text,
|
|
3118
3129
|
startedAt,
|
|
@@ -3456,7 +3467,7 @@ function brainRiskColor(risk) {
|
|
|
3456
3467
|
return "red";
|
|
3457
3468
|
}
|
|
3458
3469
|
}
|
|
3459
|
-
var Entry =
|
|
3470
|
+
var Entry = React5.memo(function Entry2({
|
|
3460
3471
|
entry,
|
|
3461
3472
|
termWidth
|
|
3462
3473
|
}) {
|
|
@@ -3886,12 +3897,22 @@ var Input = memo(function Input2({
|
|
|
3886
3897
|
onKey
|
|
3887
3898
|
}) {
|
|
3888
3899
|
const suppressInkEscRef = useRef(false);
|
|
3900
|
+
const suppressInkBackspaceRef = useRef(false);
|
|
3901
|
+
const suppressInkDeleteRef = useRef(false);
|
|
3889
3902
|
useInput((input, key) => {
|
|
3890
3903
|
if (disabled) return;
|
|
3891
3904
|
if (key.escape && suppressInkEscRef.current) {
|
|
3892
3905
|
suppressInkEscRef.current = false;
|
|
3893
3906
|
return;
|
|
3894
3907
|
}
|
|
3908
|
+
if (key.backspace && suppressInkBackspaceRef.current) {
|
|
3909
|
+
suppressInkBackspaceRef.current = false;
|
|
3910
|
+
return;
|
|
3911
|
+
}
|
|
3912
|
+
if (key.delete && suppressInkDeleteRef.current) {
|
|
3913
|
+
suppressInkDeleteRef.current = false;
|
|
3914
|
+
return;
|
|
3915
|
+
}
|
|
3895
3916
|
onKey(input, key);
|
|
3896
3917
|
});
|
|
3897
3918
|
const { stdin } = useStdin();
|
|
@@ -3912,6 +3933,7 @@ var Input = memo(function Input2({
|
|
|
3912
3933
|
clearTimeout(escTimer);
|
|
3913
3934
|
escTimer = null;
|
|
3914
3935
|
if (s2 === "\x7F" || s2 === "\b") {
|
|
3936
|
+
suppressInkBackspaceRef.current = true;
|
|
3915
3937
|
onKey("", { ...EMPTY_KEY, backspace: true, ctrl: true });
|
|
3916
3938
|
return;
|
|
3917
3939
|
}
|
|
@@ -3928,14 +3950,17 @@ var Input = memo(function Input2({
|
|
|
3928
3950
|
}
|
|
3929
3951
|
const bsdel = isBackspaceOrDelete(s2);
|
|
3930
3952
|
if (bsdel === "backspace") {
|
|
3953
|
+
suppressInkBackspaceRef.current = true;
|
|
3931
3954
|
onKey("", { ...EMPTY_KEY, backspace: true });
|
|
3932
3955
|
return;
|
|
3933
3956
|
}
|
|
3934
3957
|
if (bsdel === "delete") {
|
|
3958
|
+
suppressInkDeleteRef.current = true;
|
|
3935
3959
|
onKey("", { ...EMPTY_KEY, delete: true });
|
|
3936
3960
|
return;
|
|
3937
3961
|
}
|
|
3938
3962
|
if (bsdel === "metaBackspace") {
|
|
3963
|
+
suppressInkBackspaceRef.current = true;
|
|
3939
3964
|
onKey("", { ...EMPTY_KEY, backspace: true, ctrl: true });
|
|
3940
3965
|
return;
|
|
3941
3966
|
}
|
|
@@ -3982,71 +4007,6 @@ var Input = memo(function Input2({
|
|
|
3982
4007
|
hint ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: hint }) : null
|
|
3983
4008
|
] });
|
|
3984
4009
|
});
|
|
3985
|
-
function fmtElapsed2(ms) {
|
|
3986
|
-
if (ms < 1e3) return `${ms}ms`;
|
|
3987
|
-
if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
|
|
3988
|
-
const m = Math.floor(ms / 6e4);
|
|
3989
|
-
const s2 = Math.floor(ms % 6e4 / 1e3);
|
|
3990
|
-
return `${m}m${s2.toString().padStart(2, "0")}s`;
|
|
3991
|
-
}
|
|
3992
|
-
function fmtBytes2(n) {
|
|
3993
|
-
if (n < 1024) return `${n}B`;
|
|
3994
|
-
return `${(n / 1024).toFixed(1)}KB`;
|
|
3995
|
-
}
|
|
3996
|
-
function fmtRecentTool(tool) {
|
|
3997
|
-
const status = tool.ok === false ? "fail" : "ok";
|
|
3998
|
-
const name = tool.name.length > 18 ? `${tool.name.slice(0, 17)}...` : tool.name;
|
|
3999
|
-
const parts = [status, name];
|
|
4000
|
-
if (typeof tool.durationMs === "number") parts.push(fmtElapsed2(tool.durationMs));
|
|
4001
|
-
if (typeof tool.outputBytes === "number" && tool.outputBytes > 0)
|
|
4002
|
-
parts.push(fmtBytes2(tool.outputBytes));
|
|
4003
|
-
if (typeof tool.outputLines === "number" && tool.outputLines > 0)
|
|
4004
|
-
parts.push(`${tool.outputLines}L`);
|
|
4005
|
-
return parts.join(" ");
|
|
4006
|
-
}
|
|
4007
|
-
function truncToWidth(s2, width) {
|
|
4008
|
-
if (width <= 0) return "";
|
|
4009
|
-
if (s2.length <= width) return s2;
|
|
4010
|
-
if (width === 1) return "\u2026";
|
|
4011
|
-
return `${s2.slice(0, width - 1)}\u2026`;
|
|
4012
|
-
}
|
|
4013
|
-
function formatRow(e, now) {
|
|
4014
|
-
const toolElapsed = e.currentTool ? now - e.currentTool.startedAt : 0;
|
|
4015
|
-
const taskElapsed = now - e.startedAt;
|
|
4016
|
-
const toolSeg = e.currentTool ? `\u2192 ${e.currentTool.name} (${fmtElapsed2(toolElapsed)})` : "\xB7";
|
|
4017
|
-
const recentTools = (e.recentTools ?? []).slice(-2).map(fmtRecentTool).join(" | ");
|
|
4018
|
-
const head = `${e.name.slice(0, 14).padEnd(14)} \xB7 ${toolSeg} \xB7 ${e.iterations}it ${e.toolCalls}tc \xB7 ${fmtElapsed2(taskElapsed)}`;
|
|
4019
|
-
return recentTools ? `${head} | last: ${recentTools}` : head;
|
|
4020
|
-
}
|
|
4021
|
-
function activityStripRows(entries, now, maxRows, width) {
|
|
4022
|
-
const bodyWidth = Math.max(0, width - 2);
|
|
4023
|
-
const running = Object.values(entries).filter((e) => e.status === "running").sort((a, b) => a.startedAt - b.startedAt);
|
|
4024
|
-
const rows = [];
|
|
4025
|
-
const overflow = running.length > maxRows;
|
|
4026
|
-
const shown = overflow ? running.slice(0, maxRows - 1) : running.slice(0, maxRows);
|
|
4027
|
-
for (const e of shown) rows.push(truncToWidth(formatRow(e, now), bodyWidth));
|
|
4028
|
-
if (overflow)
|
|
4029
|
-
rows.push(truncToWidth(`\u2026+${running.length - (maxRows - 1)} more running`, bodyWidth));
|
|
4030
|
-
while (rows.length < maxRows) rows.push("");
|
|
4031
|
-
return rows;
|
|
4032
|
-
}
|
|
4033
|
-
var LiveActivityStrip = React6.memo(function LiveActivityStrip2({
|
|
4034
|
-
entries,
|
|
4035
|
-
nowTick,
|
|
4036
|
-
maxRows = 4
|
|
4037
|
-
}) {
|
|
4038
|
-
const { stdout } = useStdout();
|
|
4039
|
-
const width = Math.max(10, (stdout?.columns ?? 80) - 2);
|
|
4040
|
-
const hasEntries = Object.keys(entries).length > 0;
|
|
4041
|
-
const rows = hasEntries ? activityStripRows(entries, Date.now(), maxRows, width) : new Array(maxRows).fill("");
|
|
4042
|
-
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", paddingX: 1, children: rows.map((text, slot) => (
|
|
4043
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: fixed-height slots, index IS the identity
|
|
4044
|
-
/* @__PURE__ */ jsx(Box, { height: 1, children: text === "" ? /* @__PURE__ */ jsx(Text, { children: " " }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4045
|
-
/* @__PURE__ */ jsx(Text, { color: theme.accent, children: "\u25CF " }),
|
|
4046
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, wrap: "truncate", children: text })
|
|
4047
|
-
] }) }, `strip-${slot}`)
|
|
4048
|
-
)) });
|
|
4049
|
-
});
|
|
4050
4010
|
var MAX_VISIBLE = 10;
|
|
4051
4011
|
function getVisibleWindow(selected, total) {
|
|
4052
4012
|
const half = Math.floor(MAX_VISIBLE / 2);
|
|
@@ -4137,7 +4097,7 @@ function ModelPicker({
|
|
|
4137
4097
|
hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
|
|
4138
4098
|
] });
|
|
4139
4099
|
}
|
|
4140
|
-
var
|
|
4100
|
+
var fmtElapsed2 = (ms) => {
|
|
4141
4101
|
const s2 = Math.floor(ms / 1e3);
|
|
4142
4102
|
const m = Math.floor(s2 / 60);
|
|
4143
4103
|
const h = Math.floor(m / 60);
|
|
@@ -4179,7 +4139,7 @@ function PhaseMonitor({
|
|
|
4179
4139
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
4180
4140
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
4181
4141
|
"\u23F1 ",
|
|
4182
|
-
|
|
4142
|
+
fmtElapsed2(elapsedMs)
|
|
4183
4143
|
] }),
|
|
4184
4144
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
4185
4145
|
/* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
@@ -4204,7 +4164,7 @@ function PhaseMonitor({
|
|
|
4204
4164
|
const s2 = fmtPhase(phase.status);
|
|
4205
4165
|
const phaseKey = Object.keys(phases).find((k) => phases[k] === phase) ?? String(i);
|
|
4206
4166
|
const isRunning = runningPhaseIds.includes(phaseKey);
|
|
4207
|
-
const elapsed = phase.startedAt ?
|
|
4167
|
+
const elapsed = phase.startedAt ? fmtElapsed2(nowTick - phase.startedAt) : "\u2014";
|
|
4208
4168
|
const progress = phase.totalTasks > 0 ? `${phase.completedTasks}/${phase.totalTasks}` : "\u2014";
|
|
4209
4169
|
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: 1, children: /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
4210
4170
|
/* @__PURE__ */ jsx(Text, { color: s2.color, bold: true, children: s2.icon }),
|
|
@@ -4230,7 +4190,7 @@ function PhaseMonitor({
|
|
|
4230
4190
|
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 navigate phases \xB7 Esc close" }) })
|
|
4231
4191
|
] });
|
|
4232
4192
|
}
|
|
4233
|
-
var
|
|
4193
|
+
var fmtElapsed3 = (ms) => {
|
|
4234
4194
|
const s2 = Math.floor(ms / 1e3);
|
|
4235
4195
|
const m = Math.floor(s2 / 60);
|
|
4236
4196
|
const h = Math.floor(m / 60);
|
|
@@ -4293,7 +4253,7 @@ function PhasePanel({ phases, nowTick }) {
|
|
|
4293
4253
|
const phaseKey = Object.keys(phases).find((k) => phases[k] === phase) ?? String(i);
|
|
4294
4254
|
const st2 = s(phase.status);
|
|
4295
4255
|
const progress = phase.totalTasks > 0 ? `${phase.completedTasks}/${phase.totalTasks}` : "";
|
|
4296
|
-
const elapsed = phase.startedAt ?
|
|
4256
|
+
const elapsed = phase.startedAt ? fmtElapsed3(nowTick - phase.startedAt) : "";
|
|
4297
4257
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
4298
4258
|
/* @__PURE__ */ jsx(Text, { color: st2.color, children: st2.icon }),
|
|
4299
4259
|
/* @__PURE__ */ jsx(Text, { children: phase.name.slice(0, 14).padEnd(14) }),
|
|
@@ -4422,7 +4382,7 @@ function ProcessListMonitor() {
|
|
|
4422
4382
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: String(p.pid).padEnd(7) }),
|
|
4423
4383
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: p.name.padEnd(6) }),
|
|
4424
4384
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: `${age}s`.padEnd(7) }),
|
|
4425
|
-
/* @__PURE__ */ jsx(Text, {
|
|
4385
|
+
/* @__PURE__ */ jsx(Text, { ...isSelected ? { color: "red" } : {}, bold: isSelected, children: cmd }),
|
|
4426
4386
|
p.killed ? /* @__PURE__ */ jsx(Text, { color: "red", children: "[killed]" }) : null
|
|
4427
4387
|
] }, p.pid);
|
|
4428
4388
|
}),
|
|
@@ -4491,7 +4451,7 @@ function GoalPanel({ goal }) {
|
|
|
4491
4451
|
const done = /^\[[x✓]\]|✅|\(done\)/i.test(d);
|
|
4492
4452
|
return (
|
|
4493
4453
|
// biome-ignore lint/suspicious/noArrayIndexKey: deliverables are stable text strings
|
|
4494
|
-
/* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, {
|
|
4454
|
+
/* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { ...done ? { color: "green" } : {}, dimColor: !done, children: [
|
|
4495
4455
|
" ",
|
|
4496
4456
|
done ? "\u2713" : "\u25CB",
|
|
4497
4457
|
" ",
|
|
@@ -4548,6 +4508,7 @@ var LOG_LEVELS = ["error", "warn", "info", "debug", "trace"];
|
|
|
4548
4508
|
var AUDIT_LEVELS = ["minimal", "standard", "full"];
|
|
4549
4509
|
var COMPACTOR_STRATEGIES = ["hybrid", "intelligent", "selective"];
|
|
4550
4510
|
var MAX_ITERATIONS_PRESETS = [100, 200, 500, 1e3, 0];
|
|
4511
|
+
var AUTO_PROCEED_MAX_PRESETS = [10, 25, 50, 100, 250, 0];
|
|
4551
4512
|
var ENHANCE_DELAY_PRESETS = [3e4, 45e3, 6e4, 9e4, 12e4];
|
|
4552
4513
|
function formatSettingsDelay(ms) {
|
|
4553
4514
|
if (ms === 0) return "disabled";
|
|
@@ -4566,7 +4527,7 @@ var MODE_DESC = {
|
|
|
4566
4527
|
suggest: "Shows next-step suggestions after each turn",
|
|
4567
4528
|
auto: "Self-driving \u2014 agent continues automatically"
|
|
4568
4529
|
};
|
|
4569
|
-
var SETTINGS_FIELD_COUNT =
|
|
4530
|
+
var SETTINGS_FIELD_COUNT = 23;
|
|
4570
4531
|
var CONFIG_SCOPES = ["global", "project"];
|
|
4571
4532
|
function SettingsPicker({
|
|
4572
4533
|
field,
|
|
@@ -4589,6 +4550,7 @@ function SettingsPicker({
|
|
|
4589
4550
|
auditLevel,
|
|
4590
4551
|
indexOnStart,
|
|
4591
4552
|
maxIterations,
|
|
4553
|
+
autoProceedMaxIterations,
|
|
4592
4554
|
enhanceDelayMs,
|
|
4593
4555
|
debugStream,
|
|
4594
4556
|
configScope,
|
|
@@ -4703,6 +4665,11 @@ function SettingsPicker({
|
|
|
4703
4665
|
value: formatMaxIterations(maxIterations),
|
|
4704
4666
|
detail: "100\u20131000 or unlimited (0)"
|
|
4705
4667
|
},
|
|
4668
|
+
{
|
|
4669
|
+
label: "Auto-proceed max iterations",
|
|
4670
|
+
value: formatMaxIterations(autoProceedMaxIterations),
|
|
4671
|
+
detail: "Stop auto-proceed after N iterations (0 = unlimited, default 50)"
|
|
4672
|
+
},
|
|
4706
4673
|
{
|
|
4707
4674
|
label: "Refine preview countdown",
|
|
4708
4675
|
value: formatEnhanceDelay(enhanceDelayMs),
|
|
@@ -4970,7 +4937,7 @@ function TodosMonitor({ todos }) {
|
|
|
4970
4937
|
)
|
|
4971
4938
|
] });
|
|
4972
4939
|
}
|
|
4973
|
-
var
|
|
4940
|
+
var fmtElapsed4 = (ms) => {
|
|
4974
4941
|
const s2 = Math.floor(ms / 1e3);
|
|
4975
4942
|
const m = Math.floor(s2 / 60);
|
|
4976
4943
|
const h = Math.floor(m / 60);
|
|
@@ -5039,7 +5006,7 @@ function WorktreeMonitor({
|
|
|
5039
5006
|
recent.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No worktrees. They appear when AutoPhase runs with isolation on." }) : recent.map((w) => {
|
|
5040
5007
|
const s2 = fmt(w.status);
|
|
5041
5008
|
const short = w.branch.replace(/^wstack\/ap\//, "");
|
|
5042
|
-
const elapsed = w.allocatedAt ?
|
|
5009
|
+
const elapsed = w.allocatedAt ? fmtElapsed4(nowTick - w.allocatedAt) : "\u2014";
|
|
5043
5010
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
5044
5011
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
5045
5012
|
/* @__PURE__ */ jsx(Text, { color: s2.color, bold: true, children: s2.icon }),
|
|
@@ -5089,7 +5056,7 @@ function WorktreeMonitor({
|
|
|
5089
5056
|
] })
|
|
5090
5057
|
] });
|
|
5091
5058
|
}
|
|
5092
|
-
var
|
|
5059
|
+
var fmtElapsed5 = (ms) => {
|
|
5093
5060
|
const s2 = Math.floor(ms / 1e3);
|
|
5094
5061
|
const m = Math.floor(s2 / 60);
|
|
5095
5062
|
const h = Math.floor(m / 60);
|
|
@@ -5155,7 +5122,7 @@ function WorktreePanel({
|
|
|
5155
5122
|
list.map((w) => {
|
|
5156
5123
|
const s2 = st(w.status);
|
|
5157
5124
|
const conflict = w.status === "needs-review";
|
|
5158
|
-
const elapsed = w.allocatedAt ?
|
|
5125
|
+
const elapsed = w.allocatedAt ? fmtElapsed5(nowTick - w.allocatedAt) : "";
|
|
5159
5126
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
5160
5127
|
/* @__PURE__ */ jsx(Text, { color: s2.color, children: s2.icon }),
|
|
5161
5128
|
/* @__PURE__ */ jsx(Text, { children: w.branch.replace(/^wstack\/ap\//, "").slice(0, 18).padEnd(18) }),
|
|
@@ -5573,6 +5540,20 @@ function useDirectorFleetBridge({
|
|
|
5573
5540
|
}
|
|
5574
5541
|
break;
|
|
5575
5542
|
}
|
|
5543
|
+
case "ctx.pct": {
|
|
5544
|
+
const payload = event.payload;
|
|
5545
|
+
if (payload?.load !== void 0) {
|
|
5546
|
+
enqueue({
|
|
5547
|
+
type: "fleetCtxPct",
|
|
5548
|
+
id: event.subagentId,
|
|
5549
|
+
load: payload.load,
|
|
5550
|
+
tokens: payload.tokens ?? 0,
|
|
5551
|
+
maxContext: payload.maxContext ?? 0,
|
|
5552
|
+
ctxCost: payload.ctxCost
|
|
5553
|
+
});
|
|
5554
|
+
}
|
|
5555
|
+
break;
|
|
5556
|
+
}
|
|
5576
5557
|
case "bug.found":
|
|
5577
5558
|
handleCollabBugFound(event, enqueue, stateRef);
|
|
5578
5559
|
break;
|
|
@@ -6365,6 +6346,9 @@ function reducer(state, action) {
|
|
|
6365
6346
|
case "streamReset":
|
|
6366
6347
|
return { ...state, streamingText: "" };
|
|
6367
6348
|
case "status":
|
|
6349
|
+
if (action.status === "idle") {
|
|
6350
|
+
return { ...state, status: "idle", debugStreamStats: null };
|
|
6351
|
+
}
|
|
6368
6352
|
return { ...state, status: action.status };
|
|
6369
6353
|
case "interrupt":
|
|
6370
6354
|
return { ...state, interrupts: state.interrupts + 1 };
|
|
@@ -6655,6 +6639,7 @@ function reducer(state, action) {
|
|
|
6655
6639
|
auditLevel: action.auditLevel,
|
|
6656
6640
|
indexOnStart: action.indexOnStart,
|
|
6657
6641
|
maxIterations: action.maxIterations,
|
|
6642
|
+
autoProceedMaxIterations: action.autoProceedMaxIterations,
|
|
6658
6643
|
enhanceDelayMs: action.enhanceDelayMs,
|
|
6659
6644
|
debugStream: action.debugStream,
|
|
6660
6645
|
configScope: action.configScope,
|
|
@@ -6730,13 +6715,19 @@ function reducer(state, action) {
|
|
|
6730
6715
|
return { ...state, settingsPicker: { ...sp, maxIterations: expectDefined(MAX_ITERATIONS_PRESETS[next]), hint: void 0 } };
|
|
6731
6716
|
}
|
|
6732
6717
|
if (f === 19) {
|
|
6718
|
+
const aj = AUTO_PROCEED_MAX_PRESETS.indexOf(sp.autoProceedMaxIterations);
|
|
6719
|
+
const abase = aj < 0 ? 0 : aj;
|
|
6720
|
+
const anext = (abase + action.delta + AUTO_PROCEED_MAX_PRESETS.length) % AUTO_PROCEED_MAX_PRESETS.length;
|
|
6721
|
+
return { ...state, settingsPicker: { ...sp, autoProceedMaxIterations: expectDefined(AUTO_PROCEED_MAX_PRESETS[anext]), hint: void 0 } };
|
|
6722
|
+
}
|
|
6723
|
+
if (f === 20) {
|
|
6733
6724
|
const ej = ENHANCE_DELAY_PRESETS.indexOf(sp.enhanceDelayMs);
|
|
6734
6725
|
const ebase = ej < 0 ? 0 : ej;
|
|
6735
6726
|
const enext = (ebase + action.delta + ENHANCE_DELAY_PRESETS.length) % ENHANCE_DELAY_PRESETS.length;
|
|
6736
6727
|
return { ...state, settingsPicker: { ...sp, enhanceDelayMs: expectDefined(ENHANCE_DELAY_PRESETS[enext]), hint: void 0 } };
|
|
6737
6728
|
}
|
|
6738
|
-
if (f ===
|
|
6739
|
-
if (f ===
|
|
6729
|
+
if (f === 21) return { ...state, settingsPicker: { ...sp, debugStream: !sp.debugStream, hint: void 0 } };
|
|
6730
|
+
if (f === 22) {
|
|
6740
6731
|
const i = CONFIG_SCOPES.indexOf(sp.configScope);
|
|
6741
6732
|
const base = i < 0 ? 0 : i;
|
|
6742
6733
|
const next = (base + action.delta + CONFIG_SCOPES.length) % CONFIG_SCOPES.length;
|
|
@@ -7082,25 +7073,32 @@ function reducer(state, action) {
|
|
|
7082
7073
|
return { ...state, streamFleet: action.enabled };
|
|
7083
7074
|
}
|
|
7084
7075
|
case "toggleMonitor": {
|
|
7085
|
-
|
|
7076
|
+
const opening = !state.monitorOpen;
|
|
7077
|
+
return opening ? { ...state, monitorOpen: true, agentsMonitorOpen: false, helpOpen: false, todosMonitorOpen: false, queuePanelOpen: false, processListOpen: false, goalPanelOpen: false } : { ...state, monitorOpen: false };
|
|
7086
7078
|
}
|
|
7087
7079
|
case "toggleAgentsMonitor": {
|
|
7088
|
-
|
|
7080
|
+
const opening = !state.agentsMonitorOpen;
|
|
7081
|
+
return opening ? { ...state, agentsMonitorOpen: true, monitorOpen: false, helpOpen: false, todosMonitorOpen: false, queuePanelOpen: false, processListOpen: false, goalPanelOpen: false } : { ...state, agentsMonitorOpen: false };
|
|
7089
7082
|
}
|
|
7090
7083
|
case "toggleHelp": {
|
|
7091
|
-
|
|
7084
|
+
const opening = !state.helpOpen;
|
|
7085
|
+
return opening ? { ...state, helpOpen: true, monitorOpen: false, agentsMonitorOpen: false, todosMonitorOpen: false, queuePanelOpen: false, processListOpen: false, goalPanelOpen: false } : { ...state, helpOpen: false };
|
|
7092
7086
|
}
|
|
7093
7087
|
case "toggleTodosMonitor": {
|
|
7094
|
-
|
|
7088
|
+
const opening = !state.todosMonitorOpen;
|
|
7089
|
+
return opening ? { ...state, todosMonitorOpen: true, monitorOpen: false, agentsMonitorOpen: false, helpOpen: false, queuePanelOpen: false, processListOpen: false, goalPanelOpen: false } : { ...state, todosMonitorOpen: false };
|
|
7095
7090
|
}
|
|
7096
7091
|
case "toggleQueuePanel": {
|
|
7097
|
-
|
|
7092
|
+
const opening = !state.queuePanelOpen;
|
|
7093
|
+
return opening ? { ...state, queuePanelOpen: true, monitorOpen: false, agentsMonitorOpen: false, helpOpen: false, todosMonitorOpen: false, processListOpen: false, goalPanelOpen: false } : { ...state, queuePanelOpen: false };
|
|
7098
7094
|
}
|
|
7099
7095
|
case "toggleProcessList": {
|
|
7100
|
-
|
|
7096
|
+
const opening = !state.processListOpen;
|
|
7097
|
+
return opening ? { ...state, processListOpen: true, monitorOpen: false, agentsMonitorOpen: false, helpOpen: false, todosMonitorOpen: false, queuePanelOpen: false, goalPanelOpen: false } : { ...state, processListOpen: false };
|
|
7101
7098
|
}
|
|
7102
7099
|
case "toggleGoalPanel": {
|
|
7103
|
-
|
|
7100
|
+
const opening = !state.goalPanelOpen;
|
|
7101
|
+
return opening ? { ...state, goalPanelOpen: true, monitorOpen: false, agentsMonitorOpen: false, helpOpen: false, todosMonitorOpen: false, queuePanelOpen: false, processListOpen: false } : { ...state, goalPanelOpen: false };
|
|
7104
7102
|
}
|
|
7105
7103
|
case "checkpointReceived": {
|
|
7106
7104
|
const existing = state.checkpoints.find((c) => c.promptIndex === action.cp.promptIndex);
|
|
@@ -7600,7 +7598,7 @@ function App({
|
|
|
7600
7598
|
searchQuery: ""
|
|
7601
7599
|
},
|
|
7602
7600
|
autonomyPicker: { open: false, options: [], selected: 0 },
|
|
7603
|
-
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, enhanceDelayMs: 6e4, debugStream: false, configScope: "global" },
|
|
7601
|
+
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, debugStream: false, configScope: "global" },
|
|
7604
7602
|
confirmQueue: [],
|
|
7605
7603
|
enhance: null,
|
|
7606
7604
|
enhanceEnabled,
|
|
@@ -7653,7 +7651,7 @@ function App({
|
|
|
7653
7651
|
const inputGateRef = useRef(false);
|
|
7654
7652
|
const lastEnterAtRef = useRef(0);
|
|
7655
7653
|
const tokenPreviewsRef = useRef(/* @__PURE__ */ new Map());
|
|
7656
|
-
const projectName =
|
|
7654
|
+
const projectName = React5.useMemo(() => {
|
|
7657
7655
|
const base = path2.basename(projectRoot);
|
|
7658
7656
|
return base && base !== path2.sep ? base : void 0;
|
|
7659
7657
|
}, [projectRoot]);
|
|
@@ -7669,7 +7667,7 @@ function App({
|
|
|
7669
7667
|
const draftRef = useRef({ buffer: state.buffer, cursor: state.cursor });
|
|
7670
7668
|
draftRef.current = { buffer: state.buffer, cursor: state.cursor };
|
|
7671
7669
|
const handleKeyRef = useRef(null);
|
|
7672
|
-
const handleRewindTo =
|
|
7670
|
+
const handleRewindTo = React5.useCallback(
|
|
7673
7671
|
async (checkpointIndex) => {
|
|
7674
7672
|
const sessionId = agent.ctx.session.id;
|
|
7675
7673
|
if (!sessionId) return;
|
|
@@ -7688,7 +7686,7 @@ function App({
|
|
|
7688
7686
|
dispatch({ type: "clearInput" });
|
|
7689
7687
|
};
|
|
7690
7688
|
const startedAtRef = useRef(Date.now());
|
|
7691
|
-
const [nowTick, setNowTick] =
|
|
7689
|
+
const [nowTick, setNowTick] = React5.useState(Date.now());
|
|
7692
7690
|
useEffect(() => {
|
|
7693
7691
|
const t = setInterval(() => setNowTick(Date.now()), 1e4);
|
|
7694
7692
|
return () => clearInterval(t);
|
|
@@ -7750,7 +7748,7 @@ function App({
|
|
|
7750
7748
|
agent.ctx.model,
|
|
7751
7749
|
agent.ctx.provider
|
|
7752
7750
|
]);
|
|
7753
|
-
const [gitInfo, setGitInfo] =
|
|
7751
|
+
const [gitInfo, setGitInfo] = React5.useState(null);
|
|
7754
7752
|
useEffect(() => {
|
|
7755
7753
|
let cancelled = false;
|
|
7756
7754
|
const refresh = () => {
|
|
@@ -7861,7 +7859,7 @@ function App({
|
|
|
7861
7859
|
} catch {
|
|
7862
7860
|
}
|
|
7863
7861
|
}, []);
|
|
7864
|
-
|
|
7862
|
+
React5.useLayoutEffect(() => {
|
|
7865
7863
|
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;
|
|
7866
7864
|
const overlayClosed = prevAnyOverlayOpen.current && !anyOpenNow;
|
|
7867
7865
|
const newEntryCommitted = state.entries.length > prevEntriesCount.current;
|
|
@@ -7943,6 +7941,7 @@ function App({
|
|
|
7943
7941
|
auditLevel: sp.auditLevel,
|
|
7944
7942
|
indexOnStart: sp.indexOnStart,
|
|
7945
7943
|
maxIterations: sp.maxIterations,
|
|
7944
|
+
autoProceedMaxIterations: sp.autoProceedMaxIterations,
|
|
7946
7945
|
enhanceDelayMs: sp.enhanceDelayMs,
|
|
7947
7946
|
debugStream: sp.debugStream,
|
|
7948
7947
|
configScope: sp.configScope
|
|
@@ -7963,7 +7962,7 @@ function App({
|
|
|
7963
7962
|
process.stdout.off("resize", handleResize);
|
|
7964
7963
|
};
|
|
7965
7964
|
}, [eraseLiveRegion]);
|
|
7966
|
-
|
|
7965
|
+
React5.useLayoutEffect(() => {
|
|
7967
7966
|
if (state.enhanceBusy || state.enhance != null) eraseLiveRegion();
|
|
7968
7967
|
});
|
|
7969
7968
|
useEffect(() => {
|
|
@@ -8068,6 +8067,7 @@ function App({
|
|
|
8068
8067
|
data,
|
|
8069
8068
|
meta: { filename: picked, label: picked }
|
|
8070
8069
|
});
|
|
8070
|
+
tokenPreviewsRef.current.set(token, data);
|
|
8071
8071
|
const before = draft.buffer.slice(0, tok.start);
|
|
8072
8072
|
const after = draft.buffer.slice(tok.end);
|
|
8073
8073
|
const next = `${before}${token}${after}`;
|
|
@@ -8250,12 +8250,12 @@ function App({
|
|
|
8250
8250
|
slashRegistry.unregister("agents");
|
|
8251
8251
|
};
|
|
8252
8252
|
}, [slashRegistry]);
|
|
8253
|
-
const openModelPicker =
|
|
8253
|
+
const openModelPicker = React5.useCallback(async () => {
|
|
8254
8254
|
if (!getPickableProviders) return;
|
|
8255
8255
|
const providers = await getPickableProviders();
|
|
8256
8256
|
dispatch({ type: "modelPickerOpen", providers });
|
|
8257
8257
|
}, [getPickableProviders]);
|
|
8258
|
-
const openSettings =
|
|
8258
|
+
const openSettings = React5.useCallback(() => {
|
|
8259
8259
|
if (!getSettings) return;
|
|
8260
8260
|
const s2 = getSettings();
|
|
8261
8261
|
dispatch({
|
|
@@ -8279,11 +8279,40 @@ function App({
|
|
|
8279
8279
|
auditLevel: s2.auditLevel ?? "standard",
|
|
8280
8280
|
indexOnStart: s2.indexOnStart ?? true,
|
|
8281
8281
|
maxIterations: s2.maxIterations ?? 500,
|
|
8282
|
+
autoProceedMaxIterations: s2.autoProceedMaxIterations ?? 50,
|
|
8282
8283
|
enhanceDelayMs: s2.enhanceDelayMs ?? 6e4,
|
|
8283
8284
|
debugStream: s2.debugStream ?? false,
|
|
8284
8285
|
configScope: s2.configScope ?? "global"
|
|
8285
8286
|
});
|
|
8286
8287
|
}, [getSettings]);
|
|
8288
|
+
const [autoProceedCountdown, setAutoProceedCountdown] = useState(null);
|
|
8289
|
+
const autoProceedTimerRef = useRef(void 0);
|
|
8290
|
+
useEffect(() => {
|
|
8291
|
+
if (autonomyLive !== "auto") {
|
|
8292
|
+
clearInterval(autoProceedTimerRef.current);
|
|
8293
|
+
autoProceedTimerRef.current = void 0;
|
|
8294
|
+
setAutoProceedCountdown(null);
|
|
8295
|
+
return;
|
|
8296
|
+
}
|
|
8297
|
+
const cfg = getSettings?.();
|
|
8298
|
+
const delay = cfg?.delayMs ?? 45e3;
|
|
8299
|
+
const start = Date.now();
|
|
8300
|
+
setAutoProceedCountdown(Math.ceil(delay / 1e3));
|
|
8301
|
+
autoProceedTimerRef.current = setInterval(() => {
|
|
8302
|
+
const remaining = Math.max(0, Math.ceil((delay - (Date.now() - start)) / 1e3));
|
|
8303
|
+
if (remaining <= 0) {
|
|
8304
|
+
clearInterval(autoProceedTimerRef.current);
|
|
8305
|
+
autoProceedTimerRef.current = void 0;
|
|
8306
|
+
setAutoProceedCountdown(null);
|
|
8307
|
+
} else {
|
|
8308
|
+
setAutoProceedCountdown(remaining);
|
|
8309
|
+
}
|
|
8310
|
+
}, 500);
|
|
8311
|
+
return () => {
|
|
8312
|
+
clearInterval(autoProceedTimerRef.current);
|
|
8313
|
+
autoProceedTimerRef.current = void 0;
|
|
8314
|
+
};
|
|
8315
|
+
}, [autonomyLive, getSettings]);
|
|
8287
8316
|
const settingsAutoSaveGateRef = useRef(true);
|
|
8288
8317
|
useEffect(() => {
|
|
8289
8318
|
if (state.settingsPicker.open) {
|
|
@@ -8318,6 +8347,7 @@ function App({
|
|
|
8318
8347
|
auditLevel: sp.auditLevel,
|
|
8319
8348
|
indexOnStart: sp.indexOnStart,
|
|
8320
8349
|
maxIterations: sp.maxIterations,
|
|
8350
|
+
autoProceedMaxIterations: sp.autoProceedMaxIterations,
|
|
8321
8351
|
enhanceDelayMs: sp.enhanceDelayMs,
|
|
8322
8352
|
debugStream: sp.debugStream,
|
|
8323
8353
|
configScope: sp.configScope
|
|
@@ -8345,6 +8375,7 @@ function App({
|
|
|
8345
8375
|
state.settingsPicker.auditLevel,
|
|
8346
8376
|
state.settingsPicker.indexOnStart,
|
|
8347
8377
|
state.settingsPicker.maxIterations,
|
|
8378
|
+
state.settingsPicker.autoProceedMaxIterations,
|
|
8348
8379
|
state.settingsPicker.enhanceDelayMs,
|
|
8349
8380
|
saveSettings
|
|
8350
8381
|
]);
|
|
@@ -8587,6 +8618,7 @@ function App({
|
|
|
8587
8618
|
enhanceEnabledRef.current = state.enhanceEnabled;
|
|
8588
8619
|
}, [state.enhanceEnabled]);
|
|
8589
8620
|
const enhanceAbortRef = useRef(null);
|
|
8621
|
+
const [enhanceCountdown, setEnhanceCountdown] = useState(null);
|
|
8590
8622
|
useTuiEventBridge({
|
|
8591
8623
|
events,
|
|
8592
8624
|
dispatch,
|
|
@@ -8730,13 +8762,6 @@ function App({
|
|
|
8730
8762
|
process.off("SIGINT", onSigint);
|
|
8731
8763
|
};
|
|
8732
8764
|
}, [director, getEternalEngine, getParallelEngine, switchAutonomy, onExit, exit]);
|
|
8733
|
-
const truncatePastePreview = (text, lines) => {
|
|
8734
|
-
const all = text.split("\n");
|
|
8735
|
-
if (all.length <= lines) return text;
|
|
8736
|
-
const head = all.slice(0, lines).join("\n");
|
|
8737
|
-
return `${head}
|
|
8738
|
-
... (${all.length - lines} more lines)`;
|
|
8739
|
-
};
|
|
8740
8765
|
const commitPaste = async (full) => {
|
|
8741
8766
|
const builder = builderRef.current;
|
|
8742
8767
|
if (!builder || !full) return;
|
|
@@ -8751,7 +8776,7 @@ function App({
|
|
|
8751
8776
|
}
|
|
8752
8777
|
if (mustCollapse || multiLine) {
|
|
8753
8778
|
const token = await builder.registerPaste(full);
|
|
8754
|
-
tokenPreviewsRef.current.set(token,
|
|
8779
|
+
tokenPreviewsRef.current.set(token, full);
|
|
8755
8780
|
const next2 = buffer.slice(0, cursor) + token + buffer.slice(cursor);
|
|
8756
8781
|
setDraft(next2, cursor + token.length);
|
|
8757
8782
|
return;
|
|
@@ -9142,6 +9167,7 @@ function App({
|
|
|
9142
9167
|
auditLevel: cfg.auditLevel ?? "standard",
|
|
9143
9168
|
indexOnStart: cfg.indexOnStart ?? true,
|
|
9144
9169
|
maxIterations: cfg.maxIterations ?? 500,
|
|
9170
|
+
autoProceedMaxIterations: cfg.autoProceedMaxIterations ?? 50,
|
|
9145
9171
|
enhanceDelayMs: cfg.enhanceDelayMs ?? 6e4,
|
|
9146
9172
|
debugStream: cfg.debugStream ?? false,
|
|
9147
9173
|
configScope: cfg.configScope ?? "global"
|
|
@@ -9234,6 +9260,7 @@ function App({
|
|
|
9234
9260
|
auditLevel: cfg.auditLevel ?? "standard",
|
|
9235
9261
|
indexOnStart: cfg.indexOnStart ?? true,
|
|
9236
9262
|
maxIterations: cfg.maxIterations ?? 500,
|
|
9263
|
+
autoProceedMaxIterations: cfg.autoProceedMaxIterations ?? 50,
|
|
9237
9264
|
enhanceDelayMs: cfg.enhanceDelayMs ?? 6e4,
|
|
9238
9265
|
debugStream: cfg.debugStream ?? false,
|
|
9239
9266
|
configScope: cfg.configScope ?? "global"
|
|
@@ -9634,7 +9661,12 @@ function App({
|
|
|
9634
9661
|
const submit = async (overrideRaw) => {
|
|
9635
9662
|
const raw = overrideRaw ?? draftRef.current.buffer;
|
|
9636
9663
|
const trimmed = raw.trim();
|
|
9637
|
-
if (!trimmed)
|
|
9664
|
+
if (!trimmed) {
|
|
9665
|
+
if (state.steeringPending) {
|
|
9666
|
+
dispatch({ type: "steerConsume" });
|
|
9667
|
+
}
|
|
9668
|
+
return;
|
|
9669
|
+
}
|
|
9638
9670
|
dispatch({ type: "resetInterrupts" });
|
|
9639
9671
|
const pushSubmittedHistory = () => {
|
|
9640
9672
|
if (trimmed) dispatch({ type: "historyPush", text: trimmed });
|
|
@@ -9646,11 +9678,29 @@ function App({
|
|
|
9646
9678
|
return;
|
|
9647
9679
|
}
|
|
9648
9680
|
if (trimmed.startsWith("/")) {
|
|
9649
|
-
|
|
9681
|
+
let resolvedForDispatch = trimmed;
|
|
9682
|
+
const pasteParts2 = [];
|
|
9683
|
+
for (const m of trimmed.matchAll(new RegExp(INLINE_TOKEN_SRC, "g"))) {
|
|
9684
|
+
const token = m[0];
|
|
9685
|
+
const content = tokenPreviewsRef.current.get(token);
|
|
9686
|
+
if (content) {
|
|
9687
|
+
resolvedForDispatch = resolvedForDispatch.replace(
|
|
9688
|
+
token,
|
|
9689
|
+
`
|
|
9690
|
+
<pasted>
|
|
9691
|
+
${content}
|
|
9692
|
+
</pasted>`
|
|
9693
|
+
);
|
|
9694
|
+
}
|
|
9695
|
+
pasteParts2.push(token);
|
|
9696
|
+
if (content) pasteParts2.push(` ${content.split("\n").slice(0, 6).join("\n ")}`);
|
|
9697
|
+
}
|
|
9698
|
+
const pasteContent2 = pasteParts2.length > 0 ? pasteParts2.join("\n") : void 0;
|
|
9699
|
+
dispatch({ type: "addEntry", entry: { kind: "user", text: trimmed, pasteContent: pasteContent2 } });
|
|
9650
9700
|
pushSubmittedHistory();
|
|
9651
9701
|
clearDraft();
|
|
9652
9702
|
try {
|
|
9653
|
-
const res = await slashRegistry.dispatch(
|
|
9703
|
+
const res = await slashRegistry.dispatch(resolvedForDispatch, agent.ctx);
|
|
9654
9704
|
if (res?.message) {
|
|
9655
9705
|
dispatch({ type: "addEntry", entry: { kind: "info", text: res.message } });
|
|
9656
9706
|
}
|
|
@@ -9804,7 +9854,7 @@ User message:
|
|
|
9804
9854
|
builder.appendText(toAppend);
|
|
9805
9855
|
}
|
|
9806
9856
|
if (steering) dispatch({ type: "steerConsume" });
|
|
9807
|
-
const displayText =
|
|
9857
|
+
const displayText = steering ? `\u21AF ${effectiveText}` : effectiveText;
|
|
9808
9858
|
const pasteParts = [];
|
|
9809
9859
|
for (const m of trimmed.matchAll(new RegExp(INLINE_TOKEN_SRC, "g"))) {
|
|
9810
9860
|
const token = m[0];
|
|
@@ -9886,7 +9936,6 @@ User message:
|
|
|
9886
9936
|
}
|
|
9887
9937
|
),
|
|
9888
9938
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [
|
|
9889
|
-
/* @__PURE__ */ jsx(LiveActivityStrip, { entries: state.fleet, nowTick }),
|
|
9890
9939
|
/* @__PURE__ */ jsx(
|
|
9891
9940
|
Input,
|
|
9892
9941
|
{
|
|
@@ -9960,6 +10009,7 @@ User message:
|
|
|
9960
10009
|
auditLevel: state.settingsPicker.auditLevel,
|
|
9961
10010
|
indexOnStart: state.settingsPicker.indexOnStart,
|
|
9962
10011
|
maxIterations: state.settingsPicker.maxIterations,
|
|
10012
|
+
autoProceedMaxIterations: state.settingsPicker.autoProceedMaxIterations,
|
|
9963
10013
|
enhanceDelayMs: state.settingsPicker.enhanceDelayMs,
|
|
9964
10014
|
debugStream: state.settingsPicker.debugStream,
|
|
9965
10015
|
configScope: state.settingsPicker.configScope,
|
|
@@ -10063,6 +10113,7 @@ User message:
|
|
|
10063
10113
|
const onDecision = (decision) => {
|
|
10064
10114
|
if (resolved) return;
|
|
10065
10115
|
resolved = true;
|
|
10116
|
+
setEnhanceCountdown(null);
|
|
10066
10117
|
info.resolve(decision);
|
|
10067
10118
|
};
|
|
10068
10119
|
return /* @__PURE__ */ jsx(
|
|
@@ -10072,7 +10123,8 @@ User message:
|
|
|
10072
10123
|
refined: info.refined,
|
|
10073
10124
|
english: info.english,
|
|
10074
10125
|
delayMs: enhanceDelayMs,
|
|
10075
|
-
onDecision
|
|
10126
|
+
onDecision,
|
|
10127
|
+
onTick: (r) => setEnhanceCountdown(r > 0 ? r : null)
|
|
10076
10128
|
}
|
|
10077
10129
|
);
|
|
10078
10130
|
})() : null,
|
|
@@ -10102,7 +10154,9 @@ User message:
|
|
|
10102
10154
|
goalSummary: state.goalSummary,
|
|
10103
10155
|
indexState,
|
|
10104
10156
|
modeLabel: liveModeLabel || void 0,
|
|
10105
|
-
debugStreamStats: state.debugStreamStats
|
|
10157
|
+
debugStreamStats: state.debugStreamStats,
|
|
10158
|
+
enhanceCountdown,
|
|
10159
|
+
autoProceedCountdown
|
|
10106
10160
|
}
|
|
10107
10161
|
),
|
|
10108
10162
|
state.helpOpen ? /* @__PURE__ */ jsx(HelpOverlay, {}) : null,
|
|
@@ -10328,7 +10382,7 @@ async function runTui(opts) {
|
|
|
10328
10382
|
let instance;
|
|
10329
10383
|
try {
|
|
10330
10384
|
instance = render(
|
|
10331
|
-
|
|
10385
|
+
React5.createElement(App, {
|
|
10332
10386
|
agent: opts.agent,
|
|
10333
10387
|
slashRegistry: opts.slashRegistry,
|
|
10334
10388
|
attachments: opts.attachments,
|