@wrongstack/tui 0.119.1 → 0.141.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.js +47 -102
- 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';
|
|
@@ -518,7 +518,7 @@ var WAVE_COLORS = [
|
|
|
518
518
|
function WaveText({ text, phase }) {
|
|
519
519
|
return /* @__PURE__ */ jsx(Text, { bold: true, children: Array.from(text).map((ch, i) => (
|
|
520
520
|
// 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)
|
|
521
|
+
/* @__PURE__ */ jsx(Text, { color: WAVE_COLORS[(i + phase) % WAVE_COLORS.length] ?? "#ffffff", children: ch }, i)
|
|
522
522
|
)) });
|
|
523
523
|
}
|
|
524
524
|
var FILLED = "\u2588";
|
|
@@ -715,7 +715,7 @@ function FleetMonitor({
|
|
|
715
715
|
] }),
|
|
716
716
|
collabSession.overallVerdict ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
717
717
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
718
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color: VERDICT_COLOR[collabSession.overallVerdict], children: collabSession.overallVerdict })
|
|
718
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: VERDICT_COLOR[collabSession.overallVerdict] ?? "white", children: collabSession.overallVerdict })
|
|
719
719
|
] }) : null
|
|
720
720
|
] }),
|
|
721
721
|
collabSession.timeline.length > 0 ? /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: 0, children: collabSession.timeline.slice(0, 6).map((ev, i) => (
|
|
@@ -861,12 +861,8 @@ function AgentRow({
|
|
|
861
861
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
862
862
|
/* @__PURE__ */ jsx(Text, { color: selected ? "magenta" : "gray", children: selected ? "\u25B6" : " " }),
|
|
863
863
|
/* @__PURE__ */ jsx(Text, { color: s2.color, bold: true, children: s2.icon }),
|
|
864
|
-
/* @__PURE__ */ jsx(Text, { bold: selected,
|
|
864
|
+
/* @__PURE__ */ jsx(Text, { bold: selected, ...selected ? { color: "magenta" } : {}, children: entry.name }),
|
|
865
865
|
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
866
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
871
867
|
"L",
|
|
872
868
|
entry.iterations,
|
|
@@ -904,6 +900,7 @@ function AgentDetail({
|
|
|
904
900
|
const lastTool = entry.recentTools[entry.recentTools.length - 1];
|
|
905
901
|
const lastMessage = entry.recentMessages[entry.recentMessages.length - 1];
|
|
906
902
|
const streamTail = entry.streamingText ? snippet(entry.streamingText.slice(-160)) : "";
|
|
903
|
+
const modelLabel = fmtModelLabel(entry.provider, entry.model);
|
|
907
904
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingLeft: 4, borderStyle: "single", borderColor: "magenta", borderLeft: true, children: [
|
|
908
905
|
spark || lastTool ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
909
906
|
/* @__PURE__ */ jsx(Text, { color: "green", children: spark || "" }),
|
|
@@ -914,7 +911,7 @@ function AgentDetail({
|
|
|
914
911
|
lastTool.ok === false ? " \u2717" : ""
|
|
915
912
|
] }) : null
|
|
916
913
|
] }) : null,
|
|
917
|
-
entry.provider || entry.model ? /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
914
|
+
!modelLabel && (entry.provider || entry.model) ? /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
918
915
|
"provider: ",
|
|
919
916
|
entry.provider || "(leader)",
|
|
920
917
|
" \xB7 model: ",
|
|
@@ -1290,7 +1287,7 @@ function ConfirmPrompt({
|
|
|
1290
1287
|
suggestedPattern,
|
|
1291
1288
|
onDecision
|
|
1292
1289
|
}) {
|
|
1293
|
-
|
|
1290
|
+
React5.useEffect(() => {
|
|
1294
1291
|
writeOut("\x07");
|
|
1295
1292
|
}, []);
|
|
1296
1293
|
useInput((input2, _key) => {
|
|
@@ -1319,7 +1316,7 @@ function ConfirmPrompt({
|
|
|
1319
1316
|
inputSummary ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: inputSummary }) : null,
|
|
1320
1317
|
showDiff && diff ? /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginY: 1, children: renderDiff(diff) }) : null,
|
|
1321
1318
|
/* @__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(
|
|
1319
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsx(Text, { children: buttonLabels(suggestedPattern).map((l) => /* @__PURE__ */ jsxs(React5.Fragment, { children: [
|
|
1323
1320
|
/* @__PURE__ */ jsx(Text, { bold: true, color: BUTTON_COLOR[l.decision], children: l.bracket }),
|
|
1324
1321
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: l.rest })
|
|
1325
1322
|
] }, l.decision)) }) })
|
|
@@ -1333,10 +1330,10 @@ function EnhancePanel({
|
|
|
1333
1330
|
onDecision
|
|
1334
1331
|
}) {
|
|
1335
1332
|
const totalSecs = Math.max(1, Math.ceil(delayMs / 1e3));
|
|
1336
|
-
const [remaining, setRemaining] =
|
|
1337
|
-
const decideRef =
|
|
1333
|
+
const [remaining, setRemaining] = React5.useState(totalSecs);
|
|
1334
|
+
const decideRef = React5.useRef(onDecision);
|
|
1338
1335
|
decideRef.current = onDecision;
|
|
1339
|
-
|
|
1336
|
+
React5.useEffect(() => {
|
|
1340
1337
|
const id = setInterval(() => {
|
|
1341
1338
|
setRemaining((r) => {
|
|
1342
1339
|
if (r <= 1) {
|
|
@@ -3112,7 +3109,7 @@ function streamBoxRows(text, maxLines, contentWidth) {
|
|
|
3112
3109
|
}
|
|
3113
3110
|
return rows;
|
|
3114
3111
|
}
|
|
3115
|
-
|
|
3112
|
+
React5.memo(function ToolStreamBox2({
|
|
3116
3113
|
name,
|
|
3117
3114
|
text,
|
|
3118
3115
|
startedAt,
|
|
@@ -3456,7 +3453,7 @@ function brainRiskColor(risk) {
|
|
|
3456
3453
|
return "red";
|
|
3457
3454
|
}
|
|
3458
3455
|
}
|
|
3459
|
-
var Entry =
|
|
3456
|
+
var Entry = React5.memo(function Entry2({
|
|
3460
3457
|
entry,
|
|
3461
3458
|
termWidth
|
|
3462
3459
|
}) {
|
|
@@ -3886,12 +3883,22 @@ var Input = memo(function Input2({
|
|
|
3886
3883
|
onKey
|
|
3887
3884
|
}) {
|
|
3888
3885
|
const suppressInkEscRef = useRef(false);
|
|
3886
|
+
const suppressInkBackspaceRef = useRef(false);
|
|
3887
|
+
const suppressInkDeleteRef = useRef(false);
|
|
3889
3888
|
useInput((input, key) => {
|
|
3890
3889
|
if (disabled) return;
|
|
3891
3890
|
if (key.escape && suppressInkEscRef.current) {
|
|
3892
3891
|
suppressInkEscRef.current = false;
|
|
3893
3892
|
return;
|
|
3894
3893
|
}
|
|
3894
|
+
if (key.backspace && suppressInkBackspaceRef.current) {
|
|
3895
|
+
suppressInkBackspaceRef.current = false;
|
|
3896
|
+
return;
|
|
3897
|
+
}
|
|
3898
|
+
if (key.delete && suppressInkDeleteRef.current) {
|
|
3899
|
+
suppressInkDeleteRef.current = false;
|
|
3900
|
+
return;
|
|
3901
|
+
}
|
|
3895
3902
|
onKey(input, key);
|
|
3896
3903
|
});
|
|
3897
3904
|
const { stdin } = useStdin();
|
|
@@ -3912,6 +3919,7 @@ var Input = memo(function Input2({
|
|
|
3912
3919
|
clearTimeout(escTimer);
|
|
3913
3920
|
escTimer = null;
|
|
3914
3921
|
if (s2 === "\x7F" || s2 === "\b") {
|
|
3922
|
+
suppressInkBackspaceRef.current = true;
|
|
3915
3923
|
onKey("", { ...EMPTY_KEY, backspace: true, ctrl: true });
|
|
3916
3924
|
return;
|
|
3917
3925
|
}
|
|
@@ -3928,14 +3936,17 @@ var Input = memo(function Input2({
|
|
|
3928
3936
|
}
|
|
3929
3937
|
const bsdel = isBackspaceOrDelete(s2);
|
|
3930
3938
|
if (bsdel === "backspace") {
|
|
3939
|
+
suppressInkBackspaceRef.current = true;
|
|
3931
3940
|
onKey("", { ...EMPTY_KEY, backspace: true });
|
|
3932
3941
|
return;
|
|
3933
3942
|
}
|
|
3934
3943
|
if (bsdel === "delete") {
|
|
3944
|
+
suppressInkDeleteRef.current = true;
|
|
3935
3945
|
onKey("", { ...EMPTY_KEY, delete: true });
|
|
3936
3946
|
return;
|
|
3937
3947
|
}
|
|
3938
3948
|
if (bsdel === "metaBackspace") {
|
|
3949
|
+
suppressInkBackspaceRef.current = true;
|
|
3939
3950
|
onKey("", { ...EMPTY_KEY, backspace: true, ctrl: true });
|
|
3940
3951
|
return;
|
|
3941
3952
|
}
|
|
@@ -3982,71 +3993,6 @@ var Input = memo(function Input2({
|
|
|
3982
3993
|
hint ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: hint }) : null
|
|
3983
3994
|
] });
|
|
3984
3995
|
});
|
|
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
3996
|
var MAX_VISIBLE = 10;
|
|
4051
3997
|
function getVisibleWindow(selected, total) {
|
|
4052
3998
|
const half = Math.floor(MAX_VISIBLE / 2);
|
|
@@ -4137,7 +4083,7 @@ function ModelPicker({
|
|
|
4137
4083
|
hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
|
|
4138
4084
|
] });
|
|
4139
4085
|
}
|
|
4140
|
-
var
|
|
4086
|
+
var fmtElapsed2 = (ms) => {
|
|
4141
4087
|
const s2 = Math.floor(ms / 1e3);
|
|
4142
4088
|
const m = Math.floor(s2 / 60);
|
|
4143
4089
|
const h = Math.floor(m / 60);
|
|
@@ -4179,7 +4125,7 @@ function PhaseMonitor({
|
|
|
4179
4125
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
4180
4126
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
4181
4127
|
"\u23F1 ",
|
|
4182
|
-
|
|
4128
|
+
fmtElapsed2(elapsedMs)
|
|
4183
4129
|
] }),
|
|
4184
4130
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
4185
4131
|
/* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
@@ -4204,7 +4150,7 @@ function PhaseMonitor({
|
|
|
4204
4150
|
const s2 = fmtPhase(phase.status);
|
|
4205
4151
|
const phaseKey = Object.keys(phases).find((k) => phases[k] === phase) ?? String(i);
|
|
4206
4152
|
const isRunning = runningPhaseIds.includes(phaseKey);
|
|
4207
|
-
const elapsed = phase.startedAt ?
|
|
4153
|
+
const elapsed = phase.startedAt ? fmtElapsed2(nowTick - phase.startedAt) : "\u2014";
|
|
4208
4154
|
const progress = phase.totalTasks > 0 ? `${phase.completedTasks}/${phase.totalTasks}` : "\u2014";
|
|
4209
4155
|
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: 1, children: /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
4210
4156
|
/* @__PURE__ */ jsx(Text, { color: s2.color, bold: true, children: s2.icon }),
|
|
@@ -4230,7 +4176,7 @@ function PhaseMonitor({
|
|
|
4230
4176
|
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 navigate phases \xB7 Esc close" }) })
|
|
4231
4177
|
] });
|
|
4232
4178
|
}
|
|
4233
|
-
var
|
|
4179
|
+
var fmtElapsed3 = (ms) => {
|
|
4234
4180
|
const s2 = Math.floor(ms / 1e3);
|
|
4235
4181
|
const m = Math.floor(s2 / 60);
|
|
4236
4182
|
const h = Math.floor(m / 60);
|
|
@@ -4293,7 +4239,7 @@ function PhasePanel({ phases, nowTick }) {
|
|
|
4293
4239
|
const phaseKey = Object.keys(phases).find((k) => phases[k] === phase) ?? String(i);
|
|
4294
4240
|
const st2 = s(phase.status);
|
|
4295
4241
|
const progress = phase.totalTasks > 0 ? `${phase.completedTasks}/${phase.totalTasks}` : "";
|
|
4296
|
-
const elapsed = phase.startedAt ?
|
|
4242
|
+
const elapsed = phase.startedAt ? fmtElapsed3(nowTick - phase.startedAt) : "";
|
|
4297
4243
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
4298
4244
|
/* @__PURE__ */ jsx(Text, { color: st2.color, children: st2.icon }),
|
|
4299
4245
|
/* @__PURE__ */ jsx(Text, { children: phase.name.slice(0, 14).padEnd(14) }),
|
|
@@ -4422,7 +4368,7 @@ function ProcessListMonitor() {
|
|
|
4422
4368
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: String(p.pid).padEnd(7) }),
|
|
4423
4369
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: p.name.padEnd(6) }),
|
|
4424
4370
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: `${age}s`.padEnd(7) }),
|
|
4425
|
-
/* @__PURE__ */ jsx(Text, {
|
|
4371
|
+
/* @__PURE__ */ jsx(Text, { ...isSelected ? { color: "red" } : {}, bold: isSelected, children: cmd }),
|
|
4426
4372
|
p.killed ? /* @__PURE__ */ jsx(Text, { color: "red", children: "[killed]" }) : null
|
|
4427
4373
|
] }, p.pid);
|
|
4428
4374
|
}),
|
|
@@ -4491,7 +4437,7 @@ function GoalPanel({ goal }) {
|
|
|
4491
4437
|
const done = /^\[[x✓]\]|✅|\(done\)/i.test(d);
|
|
4492
4438
|
return (
|
|
4493
4439
|
// biome-ignore lint/suspicious/noArrayIndexKey: deliverables are stable text strings
|
|
4494
|
-
/* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, {
|
|
4440
|
+
/* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { ...done ? { color: "green" } : {}, dimColor: !done, children: [
|
|
4495
4441
|
" ",
|
|
4496
4442
|
done ? "\u2713" : "\u25CB",
|
|
4497
4443
|
" ",
|
|
@@ -4970,7 +4916,7 @@ function TodosMonitor({ todos }) {
|
|
|
4970
4916
|
)
|
|
4971
4917
|
] });
|
|
4972
4918
|
}
|
|
4973
|
-
var
|
|
4919
|
+
var fmtElapsed4 = (ms) => {
|
|
4974
4920
|
const s2 = Math.floor(ms / 1e3);
|
|
4975
4921
|
const m = Math.floor(s2 / 60);
|
|
4976
4922
|
const h = Math.floor(m / 60);
|
|
@@ -5039,7 +4985,7 @@ function WorktreeMonitor({
|
|
|
5039
4985
|
recent.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No worktrees. They appear when AutoPhase runs with isolation on." }) : recent.map((w) => {
|
|
5040
4986
|
const s2 = fmt(w.status);
|
|
5041
4987
|
const short = w.branch.replace(/^wstack\/ap\//, "");
|
|
5042
|
-
const elapsed = w.allocatedAt ?
|
|
4988
|
+
const elapsed = w.allocatedAt ? fmtElapsed4(nowTick - w.allocatedAt) : "\u2014";
|
|
5043
4989
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
5044
4990
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
5045
4991
|
/* @__PURE__ */ jsx(Text, { color: s2.color, bold: true, children: s2.icon }),
|
|
@@ -5089,7 +5035,7 @@ function WorktreeMonitor({
|
|
|
5089
5035
|
] })
|
|
5090
5036
|
] });
|
|
5091
5037
|
}
|
|
5092
|
-
var
|
|
5038
|
+
var fmtElapsed5 = (ms) => {
|
|
5093
5039
|
const s2 = Math.floor(ms / 1e3);
|
|
5094
5040
|
const m = Math.floor(s2 / 60);
|
|
5095
5041
|
const h = Math.floor(m / 60);
|
|
@@ -5155,7 +5101,7 @@ function WorktreePanel({
|
|
|
5155
5101
|
list.map((w) => {
|
|
5156
5102
|
const s2 = st(w.status);
|
|
5157
5103
|
const conflict = w.status === "needs-review";
|
|
5158
|
-
const elapsed = w.allocatedAt ?
|
|
5104
|
+
const elapsed = w.allocatedAt ? fmtElapsed5(nowTick - w.allocatedAt) : "";
|
|
5159
5105
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
5160
5106
|
/* @__PURE__ */ jsx(Text, { color: s2.color, children: s2.icon }),
|
|
5161
5107
|
/* @__PURE__ */ jsx(Text, { children: w.branch.replace(/^wstack\/ap\//, "").slice(0, 18).padEnd(18) }),
|
|
@@ -7653,7 +7599,7 @@ function App({
|
|
|
7653
7599
|
const inputGateRef = useRef(false);
|
|
7654
7600
|
const lastEnterAtRef = useRef(0);
|
|
7655
7601
|
const tokenPreviewsRef = useRef(/* @__PURE__ */ new Map());
|
|
7656
|
-
const projectName =
|
|
7602
|
+
const projectName = React5.useMemo(() => {
|
|
7657
7603
|
const base = path2.basename(projectRoot);
|
|
7658
7604
|
return base && base !== path2.sep ? base : void 0;
|
|
7659
7605
|
}, [projectRoot]);
|
|
@@ -7669,7 +7615,7 @@ function App({
|
|
|
7669
7615
|
const draftRef = useRef({ buffer: state.buffer, cursor: state.cursor });
|
|
7670
7616
|
draftRef.current = { buffer: state.buffer, cursor: state.cursor };
|
|
7671
7617
|
const handleKeyRef = useRef(null);
|
|
7672
|
-
const handleRewindTo =
|
|
7618
|
+
const handleRewindTo = React5.useCallback(
|
|
7673
7619
|
async (checkpointIndex) => {
|
|
7674
7620
|
const sessionId = agent.ctx.session.id;
|
|
7675
7621
|
if (!sessionId) return;
|
|
@@ -7688,7 +7634,7 @@ function App({
|
|
|
7688
7634
|
dispatch({ type: "clearInput" });
|
|
7689
7635
|
};
|
|
7690
7636
|
const startedAtRef = useRef(Date.now());
|
|
7691
|
-
const [nowTick, setNowTick] =
|
|
7637
|
+
const [nowTick, setNowTick] = React5.useState(Date.now());
|
|
7692
7638
|
useEffect(() => {
|
|
7693
7639
|
const t = setInterval(() => setNowTick(Date.now()), 1e4);
|
|
7694
7640
|
return () => clearInterval(t);
|
|
@@ -7750,7 +7696,7 @@ function App({
|
|
|
7750
7696
|
agent.ctx.model,
|
|
7751
7697
|
agent.ctx.provider
|
|
7752
7698
|
]);
|
|
7753
|
-
const [gitInfo, setGitInfo] =
|
|
7699
|
+
const [gitInfo, setGitInfo] = React5.useState(null);
|
|
7754
7700
|
useEffect(() => {
|
|
7755
7701
|
let cancelled = false;
|
|
7756
7702
|
const refresh = () => {
|
|
@@ -7861,7 +7807,7 @@ function App({
|
|
|
7861
7807
|
} catch {
|
|
7862
7808
|
}
|
|
7863
7809
|
}, []);
|
|
7864
|
-
|
|
7810
|
+
React5.useLayoutEffect(() => {
|
|
7865
7811
|
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
7812
|
const overlayClosed = prevAnyOverlayOpen.current && !anyOpenNow;
|
|
7867
7813
|
const newEntryCommitted = state.entries.length > prevEntriesCount.current;
|
|
@@ -7963,7 +7909,7 @@ function App({
|
|
|
7963
7909
|
process.stdout.off("resize", handleResize);
|
|
7964
7910
|
};
|
|
7965
7911
|
}, [eraseLiveRegion]);
|
|
7966
|
-
|
|
7912
|
+
React5.useLayoutEffect(() => {
|
|
7967
7913
|
if (state.enhanceBusy || state.enhance != null) eraseLiveRegion();
|
|
7968
7914
|
});
|
|
7969
7915
|
useEffect(() => {
|
|
@@ -8250,12 +8196,12 @@ function App({
|
|
|
8250
8196
|
slashRegistry.unregister("agents");
|
|
8251
8197
|
};
|
|
8252
8198
|
}, [slashRegistry]);
|
|
8253
|
-
const openModelPicker =
|
|
8199
|
+
const openModelPicker = React5.useCallback(async () => {
|
|
8254
8200
|
if (!getPickableProviders) return;
|
|
8255
8201
|
const providers = await getPickableProviders();
|
|
8256
8202
|
dispatch({ type: "modelPickerOpen", providers });
|
|
8257
8203
|
}, [getPickableProviders]);
|
|
8258
|
-
const openSettings =
|
|
8204
|
+
const openSettings = React5.useCallback(() => {
|
|
8259
8205
|
if (!getSettings) return;
|
|
8260
8206
|
const s2 = getSettings();
|
|
8261
8207
|
dispatch({
|
|
@@ -9886,7 +9832,6 @@ User message:
|
|
|
9886
9832
|
}
|
|
9887
9833
|
),
|
|
9888
9834
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [
|
|
9889
|
-
/* @__PURE__ */ jsx(LiveActivityStrip, { entries: state.fleet, nowTick }),
|
|
9890
9835
|
/* @__PURE__ */ jsx(
|
|
9891
9836
|
Input,
|
|
9892
9837
|
{
|
|
@@ -10328,7 +10273,7 @@ async function runTui(opts) {
|
|
|
10328
10273
|
let instance;
|
|
10329
10274
|
try {
|
|
10330
10275
|
instance = render(
|
|
10331
|
-
|
|
10276
|
+
React5.createElement(App, {
|
|
10332
10277
|
agent: opts.agent,
|
|
10333
10278
|
slashRegistry: opts.slashRegistry,
|
|
10334
10279
|
attachments: opts.attachments,
|