@wrongstack/tui 0.82.6 → 0.87.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 +165 -34
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { routeImagesForModel } from '@wrongstack/runtime/vision';
|
|
|
8
8
|
import { getIndexState, onIndexStateChange, getProcessRegistry } from '@wrongstack/tools';
|
|
9
9
|
import { readClipboardImage } from '@wrongstack/runtime/clipboard';
|
|
10
10
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
11
|
+
import { expectDefined as expectDefined$1 } from '@wrongstack/core/utils';
|
|
11
12
|
import { spawn } from 'child_process';
|
|
12
13
|
|
|
13
14
|
// src/run-tui.ts
|
|
@@ -1337,6 +1338,47 @@ function EnhancePanel({
|
|
|
1337
1338
|
] }) })
|
|
1338
1339
|
] });
|
|
1339
1340
|
}
|
|
1341
|
+
function EscConfirmPrompt({
|
|
1342
|
+
runningTools,
|
|
1343
|
+
subagentCount,
|
|
1344
|
+
onConfirm,
|
|
1345
|
+
onCancel
|
|
1346
|
+
}) {
|
|
1347
|
+
useInput((input, key) => {
|
|
1348
|
+
if (key.escape) {
|
|
1349
|
+
onCancel();
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
const ch = input.toLowerCase();
|
|
1353
|
+
if (ch === "y" || key.return) {
|
|
1354
|
+
onConfirm();
|
|
1355
|
+
} else if (ch === "n") {
|
|
1356
|
+
onCancel();
|
|
1357
|
+
}
|
|
1358
|
+
});
|
|
1359
|
+
const running = runningTools.length;
|
|
1360
|
+
const toolLabel = running === 1 ? runningTools[0] : null;
|
|
1361
|
+
const toolHint = toolLabel ? ` (${toolLabel})` : running > 1 ? ` (${running} tools)` : "";
|
|
1362
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, marginY: 1, children: [
|
|
1363
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "\u23F8 Interrupt the current run?" }) }),
|
|
1364
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
1365
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1366
|
+
"The agent is working",
|
|
1367
|
+
toolHint,
|
|
1368
|
+
".",
|
|
1369
|
+
subagentCount > 0 ? ` ${subagentCount} subagent${subagentCount === 1 ? "" : "s"} active.` : ""
|
|
1370
|
+
] }),
|
|
1371
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Stop to give a new direction now, or let it finish." })
|
|
1372
|
+
] }),
|
|
1373
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }),
|
|
1374
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
1375
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "green", children: "[y]" }),
|
|
1376
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "es \u2014 stop and steer " }),
|
|
1377
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "red", children: "[n]" }),
|
|
1378
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "o / Esc \u2014 keep running" })
|
|
1379
|
+
] }) })
|
|
1380
|
+
] });
|
|
1381
|
+
}
|
|
1340
1382
|
function FilePicker({ query, matches, selected }) {
|
|
1341
1383
|
if (matches.length === 0) {
|
|
1342
1384
|
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
@@ -1933,14 +1975,6 @@ function detectLang(fenceInfo) {
|
|
|
1933
1975
|
const tag = fenceInfo.trim().toLowerCase().split(/\s+/)[0] ?? "";
|
|
1934
1976
|
return LANG_ALIASES[tag] ?? "plain";
|
|
1935
1977
|
}
|
|
1936
|
-
|
|
1937
|
-
// src/markdown-table.ts
|
|
1938
|
-
function expectDefined2(value) {
|
|
1939
|
-
if (value === null || value === void 0) {
|
|
1940
|
-
throw new Error("Expected value to be defined");
|
|
1941
|
-
}
|
|
1942
|
-
return value;
|
|
1943
|
-
}
|
|
1944
1978
|
var ROW_RE = /^\s*\|.*\|\s*$/;
|
|
1945
1979
|
var SEP_RE = /^\s*\|[\s\-:|]+\|\s*$/;
|
|
1946
1980
|
function detectTable(lines, start) {
|
|
@@ -2024,14 +2058,14 @@ function computeWidths(allRows, cols, maxWidth, sepWidths) {
|
|
|
2024
2058
|
const stripped = stripInlineMarkers(cell);
|
|
2025
2059
|
const w = longestWord(stripped);
|
|
2026
2060
|
const total = strWidth(stripped);
|
|
2027
|
-
natural[c] = Math.max(
|
|
2061
|
+
natural[c] = Math.max(expectDefined$1(natural[c]), w, total);
|
|
2028
2062
|
}
|
|
2029
2063
|
}
|
|
2030
2064
|
if (sepWidths) {
|
|
2031
2065
|
for (let c = 0; c < cols && c < sepWidths.length; c++) {
|
|
2032
2066
|
const sepW = sepWidths[c];
|
|
2033
2067
|
if (sepW != null) {
|
|
2034
|
-
natural[c] = Math.max(
|
|
2068
|
+
natural[c] = Math.max(expectDefined$1(natural[c]), sepW);
|
|
2035
2069
|
}
|
|
2036
2070
|
}
|
|
2037
2071
|
}
|
|
@@ -2043,7 +2077,7 @@ function computeWidths(allRows, cols, maxWidth, sepWidths) {
|
|
|
2043
2077
|
let maxIdx = -1;
|
|
2044
2078
|
let maxVal = MIN_COL_WIDTH;
|
|
2045
2079
|
for (let i = 0; i < cols; i++) {
|
|
2046
|
-
const w =
|
|
2080
|
+
const w = expectDefined$1(widths[i]);
|
|
2047
2081
|
if (w > maxVal) {
|
|
2048
2082
|
maxVal = w;
|
|
2049
2083
|
maxIdx = i;
|
|
@@ -2103,7 +2137,7 @@ function strWidth(s2) {
|
|
|
2103
2137
|
if (i < len) i++;
|
|
2104
2138
|
continue;
|
|
2105
2139
|
}
|
|
2106
|
-
const code =
|
|
2140
|
+
const code = expectDefined$1(s2.codePointAt(i));
|
|
2107
2141
|
const cpLen = code > 65535 ? 2 : 1;
|
|
2108
2142
|
if (code === 8205 || // ZWJ — Zero Width Joiner (emoji sequences)
|
|
2109
2143
|
code === 8203 || // ZWSP — Zero Width Space
|
|
@@ -2134,7 +2168,6 @@ function strWidth(s2) {
|
|
|
2134
2168
|
code >= 8960 && code <= 9215 || // Miscellaneous Technical
|
|
2135
2169
|
code >= 11088 && code <= 11093 || // Stars and similar
|
|
2136
2170
|
code >= 10548 && code <= 10549 || // Arrow forms
|
|
2137
|
-
code >= 8592 && code <= 8703 || // Arrows
|
|
2138
2171
|
code >= 9632 && code <= 9727 || // Geometric Shapes
|
|
2139
2172
|
code >= 9664 && code <= 9726 || // More Geometric Shapes (includes ▶)
|
|
2140
2173
|
code >= 9984 && code <= 10175) {
|
|
@@ -4292,7 +4325,7 @@ function SettingsPicker({
|
|
|
4292
4325
|
{
|
|
4293
4326
|
label: "Confirm before exit",
|
|
4294
4327
|
value: boolVal(confirmExit),
|
|
4295
|
-
detail: "
|
|
4328
|
+
detail: "Confirmation on Esc interrupt & Ctrl+C exit"
|
|
4296
4329
|
},
|
|
4297
4330
|
{
|
|
4298
4331
|
label: "Next-step prediction",
|
|
@@ -4427,6 +4460,7 @@ function SettingsPicker({
|
|
|
4427
4460
|
hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
|
|
4428
4461
|
] });
|
|
4429
4462
|
}
|
|
4463
|
+
var MAX_VISIBLE_ITEMS = 8;
|
|
4430
4464
|
function SlashMenu({ query, matches, selected }) {
|
|
4431
4465
|
const placeholder = query ? `/${query}` : "/";
|
|
4432
4466
|
const rows = [];
|
|
@@ -4439,12 +4473,26 @@ function SlashMenu({ query, matches, selected }) {
|
|
|
4439
4473
|
}
|
|
4440
4474
|
rows.push({ type: "item", match: m, index: i });
|
|
4441
4475
|
}
|
|
4442
|
-
|
|
4476
|
+
const selectedRowIdx = rows.findIndex((r) => r.type === "item" && r.index === selected);
|
|
4477
|
+
const visible = windowRows(rows, selectedRowIdx < 0 ? 0 : selectedRowIdx, MAX_VISIBLE_ITEMS);
|
|
4478
|
+
const hiddenAbove = visible.start;
|
|
4479
|
+
const hiddenBelow = rows.length - visible.end;
|
|
4480
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
4443
4481
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
4444
|
-
placeholder
|
|
4445
|
-
"
|
|
4482
|
+
placeholder,
|
|
4483
|
+
" ",
|
|
4484
|
+
matches.length > 0 ? `(${selected + 1}/${matches.length})` : ""
|
|
4485
|
+
] }),
|
|
4486
|
+
hiddenAbove > 0 && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
4487
|
+
" \u2191 ",
|
|
4488
|
+
hiddenAbove,
|
|
4489
|
+
" more"
|
|
4490
|
+
] }),
|
|
4491
|
+
visible.contextHeader && /* @__PURE__ */ jsxs(Text, { bold: true, color: "yellow", dimColor: true, children: [
|
|
4492
|
+
" ",
|
|
4493
|
+
visible.contextHeader
|
|
4446
4494
|
] }),
|
|
4447
|
-
rows.map((row) => {
|
|
4495
|
+
visible.rows.map((row) => {
|
|
4448
4496
|
if (row.type === "header") {
|
|
4449
4497
|
return /* @__PURE__ */ jsxs(Text, { bold: true, color: "yellow", dimColor: true, children: [
|
|
4450
4498
|
" ",
|
|
@@ -4465,9 +4513,41 @@ function SlashMenu({ query, matches, selected }) {
|
|
|
4465
4513
|
] })
|
|
4466
4514
|
] }, m.name);
|
|
4467
4515
|
}),
|
|
4468
|
-
|
|
4516
|
+
hiddenBelow > 0 && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
4517
|
+
" \u2193 ",
|
|
4518
|
+
hiddenBelow,
|
|
4519
|
+
" more"
|
|
4520
|
+
] }),
|
|
4521
|
+
matches.length === 0 && /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No matching commands" }),
|
|
4522
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500\u2500\u2500 \u2191\u2193 nav \xB7 Enter run \xB7 Tab fill \xB7 Esc close" })
|
|
4469
4523
|
] });
|
|
4470
4524
|
}
|
|
4525
|
+
function windowRows(rows, focus, max) {
|
|
4526
|
+
if (rows.length <= max) {
|
|
4527
|
+
return { rows, start: 0, end: rows.length, contextHeader: null };
|
|
4528
|
+
}
|
|
4529
|
+
let start = focus - Math.floor(max / 2);
|
|
4530
|
+
if (start < 0) start = 0;
|
|
4531
|
+
let end = start + max;
|
|
4532
|
+
if (end > rows.length) {
|
|
4533
|
+
end = rows.length;
|
|
4534
|
+
start = end - max;
|
|
4535
|
+
}
|
|
4536
|
+
let contextHeader = null;
|
|
4537
|
+
if (start > 0) {
|
|
4538
|
+
const first = rows[start];
|
|
4539
|
+
if (first && first.type === "item") {
|
|
4540
|
+
for (let i = start - 1; i >= 0; i--) {
|
|
4541
|
+
const r = rows[i];
|
|
4542
|
+
if (r && r.type === "header") {
|
|
4543
|
+
contextHeader = r.category;
|
|
4544
|
+
break;
|
|
4545
|
+
}
|
|
4546
|
+
}
|
|
4547
|
+
}
|
|
4548
|
+
}
|
|
4549
|
+
return { rows: rows.slice(start, end), start, end, contextHeader };
|
|
4550
|
+
}
|
|
4471
4551
|
function TodosMonitor({ todos }) {
|
|
4472
4552
|
const { stdout } = useStdout();
|
|
4473
4553
|
const done = todos.filter((t) => t.status === "completed").length;
|
|
@@ -5728,6 +5808,10 @@ function reducer(state, action) {
|
|
|
5728
5808
|
return { ...state, enhanceEnabled: action.enabled };
|
|
5729
5809
|
case "enhanceBusy":
|
|
5730
5810
|
return { ...state, enhanceBusy: action.on };
|
|
5811
|
+
case "escConfirmOpen":
|
|
5812
|
+
return { ...state, escConfirm: { snapshot: action.snapshot } };
|
|
5813
|
+
case "escConfirmClose":
|
|
5814
|
+
return { ...state, escConfirm: null };
|
|
5731
5815
|
case "resetContextChip":
|
|
5732
5816
|
return { ...state, contextChipVersion: state.contextChipVersion + 1 };
|
|
5733
5817
|
// --- Fleet ---
|
|
@@ -6404,7 +6488,7 @@ function App({
|
|
|
6404
6488
|
confirmExit = true,
|
|
6405
6489
|
enhanceEnabled = true,
|
|
6406
6490
|
enhanceController,
|
|
6407
|
-
enhanceDelayMs =
|
|
6491
|
+
enhanceDelayMs = 15e3,
|
|
6408
6492
|
getYolo,
|
|
6409
6493
|
getAutonomy,
|
|
6410
6494
|
getEternalEngine,
|
|
@@ -6542,6 +6626,7 @@ function App({
|
|
|
6542
6626
|
enhance: null,
|
|
6543
6627
|
enhanceEnabled,
|
|
6544
6628
|
enhanceBusy: false,
|
|
6629
|
+
escConfirm: null,
|
|
6545
6630
|
contextChipVersion: 0,
|
|
6546
6631
|
fleet: {},
|
|
6547
6632
|
leader: {
|
|
@@ -6764,7 +6849,7 @@ function App({
|
|
|
6764
6849
|
}
|
|
6765
6850
|
}, []);
|
|
6766
6851
|
React6.useLayoutEffect(() => {
|
|
6767
|
-
const anyOpenNow = state.picker.open || state.slashPicker.open || state.modelPicker.open || state.autonomyPicker.open || state.settingsPicker.open || state.enhanceBusy || state.enhance != null || state.confirmQueue.length > 0;
|
|
6852
|
+
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;
|
|
6768
6853
|
const overlayClosed = prevAnyOverlayOpen.current && !anyOpenNow;
|
|
6769
6854
|
const newEntryCommitted = state.entries.length > prevEntriesCount.current;
|
|
6770
6855
|
const curToolStreamLen = state.toolStream?.text.length ?? 0;
|
|
@@ -6783,6 +6868,7 @@ function App({
|
|
|
6783
6868
|
state.settingsPicker.open,
|
|
6784
6869
|
state.enhanceBusy,
|
|
6785
6870
|
state.enhance,
|
|
6871
|
+
state.escConfirm,
|
|
6786
6872
|
state.confirmQueue.length,
|
|
6787
6873
|
state.entries.length,
|
|
6788
6874
|
state.toolStream?.text,
|
|
@@ -8073,6 +8159,7 @@ function App({
|
|
|
8073
8159
|
return;
|
|
8074
8160
|
}
|
|
8075
8161
|
if (state.enhance) return;
|
|
8162
|
+
if (state.escConfirm) return;
|
|
8076
8163
|
if (state.helpOpen) {
|
|
8077
8164
|
if (key.escape || input === "?" || input === "q") dispatch({ type: "toggleHelp" });
|
|
8078
8165
|
return;
|
|
@@ -8312,17 +8399,26 @@ function App({
|
|
|
8312
8399
|
}));
|
|
8313
8400
|
const subagentsTerminated = subagents.length;
|
|
8314
8401
|
const partialAssistantText = streamingTextRef.current.slice(-1500);
|
|
8402
|
+
const snapshot = {
|
|
8403
|
+
runningTools,
|
|
8404
|
+
subagents,
|
|
8405
|
+
subagentsTerminated,
|
|
8406
|
+
partialAssistantText
|
|
8407
|
+
};
|
|
8408
|
+
if (confirmExitRef.current) {
|
|
8409
|
+
dispatch({ type: "escConfirmOpen", snapshot });
|
|
8410
|
+
dispatch({
|
|
8411
|
+
type: "addEntry",
|
|
8412
|
+
entry: {
|
|
8413
|
+
kind: "warn",
|
|
8414
|
+
text: `\u23F8 Interrupt? [y]es \u2014 stop and steer \xB7 [n]o / Esc \u2014 keep running` + (subagentsTerminated > 0 ? ` (${subagentsTerminated} subagent${subagentsTerminated === 1 ? "" : "s"})` : "")
|
|
8415
|
+
}
|
|
8416
|
+
});
|
|
8417
|
+
return;
|
|
8418
|
+
}
|
|
8315
8419
|
activeCtrlRef.current?.abort();
|
|
8316
8420
|
dispatch({ type: "status", status: "aborting" });
|
|
8317
|
-
dispatch({
|
|
8318
|
-
type: "steerStart",
|
|
8319
|
-
snapshot: {
|
|
8320
|
-
runningTools,
|
|
8321
|
-
subagents,
|
|
8322
|
-
subagentsTerminated,
|
|
8323
|
-
partialAssistantText
|
|
8324
|
-
}
|
|
8325
|
-
});
|
|
8421
|
+
dispatch({ type: "steerStart", snapshot });
|
|
8326
8422
|
if (director && subagentsTerminated > 0) {
|
|
8327
8423
|
const cap = new Promise((resolve) => {
|
|
8328
8424
|
const t = setTimeout(resolve, 1500);
|
|
@@ -9102,14 +9198,14 @@ User message:
|
|
|
9102
9198
|
),
|
|
9103
9199
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [
|
|
9104
9200
|
/* @__PURE__ */ jsx(LiveActivityStrip, { entries: state.fleet, nowTick }),
|
|
9105
|
-
/* @__PURE__ */ jsx(
|
|
9201
|
+
enhanceActive ? /* @__PURE__ */ jsx(Box, { height: 1 }) : /* @__PURE__ */ jsx(
|
|
9106
9202
|
Input,
|
|
9107
9203
|
{
|
|
9108
9204
|
prompt: INPUT_PROMPT,
|
|
9109
|
-
value:
|
|
9110
|
-
cursor:
|
|
9205
|
+
value: state.buffer,
|
|
9206
|
+
cursor: state.cursor,
|
|
9111
9207
|
disabled: state.status === "aborting" && !state.steeringPending || state.confirmQueue.length > 0,
|
|
9112
|
-
hint:
|
|
9208
|
+
hint: inputHint,
|
|
9113
9209
|
onKey: handleKey
|
|
9114
9210
|
}
|
|
9115
9211
|
),
|
|
@@ -9221,6 +9317,41 @@ User message:
|
|
|
9221
9317
|
}
|
|
9222
9318
|
);
|
|
9223
9319
|
})(),
|
|
9320
|
+
state.escConfirm ? /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginY: 1, flexShrink: 0, children: /* @__PURE__ */ jsx(
|
|
9321
|
+
EscConfirmPrompt,
|
|
9322
|
+
{
|
|
9323
|
+
runningTools: state.escConfirm.snapshot.runningTools,
|
|
9324
|
+
subagentCount: state.escConfirm.snapshot.subagentsTerminated,
|
|
9325
|
+
onConfirm: () => {
|
|
9326
|
+
const { snapshot } = state.escConfirm;
|
|
9327
|
+
activeCtrlRef.current?.abort();
|
|
9328
|
+
dispatch({ type: "status", status: "aborting" });
|
|
9329
|
+
dispatch({ type: "steerStart", snapshot });
|
|
9330
|
+
if (director && snapshot.subagentsTerminated > 0) {
|
|
9331
|
+
const cap = new Promise((resolve) => {
|
|
9332
|
+
const t = setTimeout(resolve, 1500);
|
|
9333
|
+
t.unref?.();
|
|
9334
|
+
});
|
|
9335
|
+
void Promise.race([director.terminateAll().catch(() => void 0), cap]);
|
|
9336
|
+
}
|
|
9337
|
+
const droppedCount = state.queue.length;
|
|
9338
|
+
if (droppedCount > 0) dispatch({ type: "queueClear" });
|
|
9339
|
+
const droppedTag = droppedCount > 0 ? ` \xB7 dropped ${droppedCount} queued` : "";
|
|
9340
|
+
const fleetTag = snapshot.subagentsTerminated > 0 ? ` \xB7 stopped ${snapshot.subagentsTerminated} subagent${snapshot.subagentsTerminated === 1 ? "" : "s"}` : "";
|
|
9341
|
+
dispatch({
|
|
9342
|
+
type: "addEntry",
|
|
9343
|
+
entry: {
|
|
9344
|
+
kind: "warn",
|
|
9345
|
+
text: `\u21AF Interrupted${droppedTag}${fleetTag}. Type your new direction.`
|
|
9346
|
+
}
|
|
9347
|
+
});
|
|
9348
|
+
dispatch({ type: "escConfirmClose" });
|
|
9349
|
+
},
|
|
9350
|
+
onCancel: () => {
|
|
9351
|
+
dispatch({ type: "escConfirmClose" });
|
|
9352
|
+
}
|
|
9353
|
+
}
|
|
9354
|
+
) }) : null,
|
|
9224
9355
|
state.enhanceBusy && !state.enhance ? /* @__PURE__ */ jsx(Box, { paddingX: 1, children: /* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u2728 refining your request\u2026" }) }) : null,
|
|
9225
9356
|
state.enhance ? (() => {
|
|
9226
9357
|
const info = state.enhance;
|