@wrongstack/tui 0.264.0 → 0.265.1
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 +15 -3
- package/dist/index.js +615 -63
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { writeErr, resolveProjectDir, wstackGlobalRoot, GlobalMailbox, resolveWstackPaths, loadGoal, InputBuilder, DefaultSessionRewinder, writeOut, formatTodosList, buildGoalPreamble, expectDefined as expectDefined$1, shouldEnhance, enhanceUserPrompt, recentTextTurns, normalizedEqual, buildChildEnv } from '@wrongstack/core';
|
|
1
|
+
import { writeErr, resolveProjectDir, wstackGlobalRoot, GlobalMailbox, resolveWstackPaths, loadGoal, InputBuilder, DefaultSessionRewinder, writeOut, formatTodosList, buildGoalPreamble, expectDefined as expectDefined$1, projectSlug, shouldEnhance, enhanceUserPrompt, recentTextTurns, normalizedEqual, buildChildEnv } from '@wrongstack/core';
|
|
2
2
|
export { buildGoalPreamble } from '@wrongstack/core';
|
|
3
3
|
import { Box as Box$1, useInput, useStdin, useStdout, Text as Text$1, render, useApp, measureElement, Static } from 'ink';
|
|
4
4
|
import { randomUUID } from 'crypto';
|
|
5
|
-
import * as
|
|
5
|
+
import * as path5 from 'path';
|
|
6
6
|
import React5, { forwardRef, useState, useEffect, useMemo, memo, useRef, useCallback, useReducer, useLayoutEffect } from 'react';
|
|
7
|
-
import * as
|
|
8
|
-
import { expectDefined, toErrorMessage } from '@wrongstack/core/utils';
|
|
7
|
+
import * as fs3 from 'fs/promises';
|
|
8
|
+
import { expectDefined, toErrorMessage, resolveWstackPaths as resolveWstackPaths$1 } from '@wrongstack/core/utils';
|
|
9
9
|
import { routeImagesForModel } from '@wrongstack/runtime/vision';
|
|
10
10
|
import { getIndexState, onIndexStateChange, getProcessRegistry } from '@wrongstack/tools';
|
|
11
11
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
12
12
|
import { readClipboardText, readClipboardImage } from '@wrongstack/runtime/clipboard';
|
|
13
|
+
import { getToolIcon, TOOL_ICON_CONFIG } from '@wrongstack/tools/tool-icons';
|
|
13
14
|
import * as v8 from 'v8';
|
|
14
15
|
import { spawn } from 'child_process';
|
|
15
16
|
|
|
@@ -166,6 +167,7 @@ function StatusBar({
|
|
|
166
167
|
eternalStage,
|
|
167
168
|
goalSummary,
|
|
168
169
|
indexState,
|
|
170
|
+
breakerCountdown,
|
|
169
171
|
modeLabel,
|
|
170
172
|
debugStreamStats,
|
|
171
173
|
enhanceCountdown,
|
|
@@ -340,7 +342,21 @@ function StatusBar({
|
|
|
340
342
|
] }) : indexState?.circuit?.state === "open" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
341
343
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
342
344
|
/* @__PURE__ */ jsx(Text, { color: "red", children: "\u2699 index paused (/reindex)" })
|
|
343
|
-
] }) : null
|
|
345
|
+
] }) : null,
|
|
346
|
+
breakerCountdown ? (() => {
|
|
347
|
+
const secs = Math.ceil(breakerCountdown.remainingMs / 1e3);
|
|
348
|
+
const ratio = breakerCountdown.totalMs > 0 ? breakerCountdown.remainingMs / breakerCountdown.totalMs : 0;
|
|
349
|
+
const c = secs > 20 ? "green" : secs > 10 ? "yellow" : "red";
|
|
350
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
351
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
352
|
+
/* @__PURE__ */ jsxs(Text, { color: c, bold: true, children: [
|
|
353
|
+
"\u26A1 kill/reset in ",
|
|
354
|
+
secs,
|
|
355
|
+
"s",
|
|
356
|
+
ratio <= 0.25 ? "!" : ""
|
|
357
|
+
] })
|
|
358
|
+
] });
|
|
359
|
+
})() : null
|
|
344
360
|
] })
|
|
345
361
|
) }),
|
|
346
362
|
hasSecondLine ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
@@ -491,6 +507,11 @@ function StatusBar({
|
|
|
491
507
|
plan.done > 0 ? /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
492
508
|
"\u2713",
|
|
493
509
|
plan.done
|
|
510
|
+
] }) : null,
|
|
511
|
+
plan.scope ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
512
|
+
" [",
|
|
513
|
+
plan.scope,
|
|
514
|
+
"]"
|
|
494
515
|
] }) : null
|
|
495
516
|
] })
|
|
496
517
|
] }) : null,
|
|
@@ -521,6 +542,11 @@ function StatusBar({
|
|
|
521
542
|
tasks.failed > 0 ? /* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
522
543
|
"\u2717",
|
|
523
544
|
tasks.failed
|
|
545
|
+
] }) : null,
|
|
546
|
+
tasks.scope ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
547
|
+
" [",
|
|
548
|
+
tasks.scope,
|
|
549
|
+
"]"
|
|
524
550
|
] }) : null
|
|
525
551
|
] })
|
|
526
552
|
] }) : null,
|
|
@@ -1765,8 +1791,8 @@ function FilePicker({ query, matches, selected }) {
|
|
|
1765
1791
|
] }, m))
|
|
1766
1792
|
] });
|
|
1767
1793
|
}
|
|
1768
|
-
function highlight(
|
|
1769
|
-
return
|
|
1794
|
+
function highlight(path7, _query) {
|
|
1795
|
+
return path7;
|
|
1770
1796
|
}
|
|
1771
1797
|
function FleetPanel({
|
|
1772
1798
|
entries,
|
|
@@ -1930,6 +1956,36 @@ function MailboxPanel({
|
|
|
1930
1956
|
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "/mailbox \u2014 Esc to close" }) })
|
|
1931
1957
|
] });
|
|
1932
1958
|
}
|
|
1959
|
+
var TOOL_GLYPHS = {
|
|
1960
|
+
file: "\u25A4",
|
|
1961
|
+
edit: "\u270E",
|
|
1962
|
+
search: "\u2315",
|
|
1963
|
+
folder: "\u25A3",
|
|
1964
|
+
terminal: "\u25B8",
|
|
1965
|
+
web: "\u25C8",
|
|
1966
|
+
git: "\u2387",
|
|
1967
|
+
tree: "\u2630",
|
|
1968
|
+
code: "\u2699",
|
|
1969
|
+
test: "\u2697",
|
|
1970
|
+
package: "\u2B22",
|
|
1971
|
+
document: "\u2637",
|
|
1972
|
+
scaffold: "\u2731",
|
|
1973
|
+
todo: "\u2610",
|
|
1974
|
+
plan: "\u2756",
|
|
1975
|
+
task: "\u25AA",
|
|
1976
|
+
meta: "\u274F",
|
|
1977
|
+
index: "\u229B",
|
|
1978
|
+
json: "\u2317",
|
|
1979
|
+
diff: "\u2206",
|
|
1980
|
+
logs: "\u2261",
|
|
1981
|
+
settings: "\u2699",
|
|
1982
|
+
brain: "\u2726",
|
|
1983
|
+
fallback: "\u2022"
|
|
1984
|
+
};
|
|
1985
|
+
function getToolVisual(name) {
|
|
1986
|
+
const id = getToolIcon(name);
|
|
1987
|
+
return { glyph: TOOL_GLYPHS[id], color: TOOL_ICON_CONFIG[id].color };
|
|
1988
|
+
}
|
|
1933
1989
|
function helpSections() {
|
|
1934
1990
|
const nav = [];
|
|
1935
1991
|
nav.push(
|
|
@@ -1976,31 +2032,133 @@ function helpSections() {
|
|
|
1976
2032
|
{ keys: "/settings", desc: "autonomy defaults (also Ctrl+S)" },
|
|
1977
2033
|
{ keys: "/clear", desc: "clear the conversation" }
|
|
1978
2034
|
]
|
|
2035
|
+
},
|
|
2036
|
+
{
|
|
2037
|
+
title: "Tool Colors",
|
|
2038
|
+
entries: toolColorLegend()
|
|
1979
2039
|
}
|
|
1980
2040
|
];
|
|
1981
2041
|
}
|
|
2042
|
+
function toolColorLegend() {
|
|
2043
|
+
const tools = [
|
|
2044
|
+
// File operations (most common)
|
|
2045
|
+
{ name: "read/write", tool: "read", desc: "file I/O" },
|
|
2046
|
+
{ name: "write", tool: "write", desc: "create file" },
|
|
2047
|
+
{ name: "edit", tool: "edit", desc: "edit file" },
|
|
2048
|
+
{ name: "patch", tool: "patch", desc: "diff/patch" },
|
|
2049
|
+
// Search
|
|
2050
|
+
{ name: "search", tool: "grep", desc: "search" },
|
|
2051
|
+
{ name: "glob", tool: "glob", desc: "glob/pattern" },
|
|
2052
|
+
// Shell & web
|
|
2053
|
+
{ name: "terminal", tool: "bash", desc: "shell" },
|
|
2054
|
+
{ name: "web", tool: "fetch", desc: "web" },
|
|
2055
|
+
// Navigation & tree
|
|
2056
|
+
{ name: "folder", tool: "ls", desc: "navigate" },
|
|
2057
|
+
{ name: "tree", tool: "tree", desc: "tree view" },
|
|
2058
|
+
// VCS
|
|
2059
|
+
{ name: "git", tool: "git", desc: "git" },
|
|
2060
|
+
// Code quality
|
|
2061
|
+
{ name: "lint", tool: "lint", desc: "lint" },
|
|
2062
|
+
{ name: "format", tool: "format", desc: "format" },
|
|
2063
|
+
{ name: "typecheck", tool: "typecheck", desc: "typecheck" },
|
|
2064
|
+
// Testing & packages
|
|
2065
|
+
{ name: "test", tool: "test", desc: "test" },
|
|
2066
|
+
{ name: "package", tool: "install", desc: "packages" },
|
|
2067
|
+
{ name: "audit", tool: "audit", desc: "audit" },
|
|
2068
|
+
// Planning & tracking
|
|
2069
|
+
{ name: "todo", tool: "todo", desc: "todos" },
|
|
2070
|
+
{ name: "plan", tool: "plan", desc: "planning" },
|
|
2071
|
+
{ name: "task", tool: "task", desc: "tasks" },
|
|
2072
|
+
// Docs & scaffolding
|
|
2073
|
+
{ name: "document", tool: "document", desc: "docs" },
|
|
2074
|
+
{ name: "scaffold", tool: "scaffold", desc: "scaffold" },
|
|
2075
|
+
// Data & logs
|
|
2076
|
+
{ name: "json", tool: "json", desc: "JSON" },
|
|
2077
|
+
{ name: "logs", tool: "logs", desc: "logs" },
|
|
2078
|
+
// Memory & meta
|
|
2079
|
+
{ name: "brain", tool: "remember", desc: "memory" },
|
|
2080
|
+
{ name: "tool_use", tool: "tool_use", desc: "tool chain" }
|
|
2081
|
+
];
|
|
2082
|
+
return tools.map(({ name, tool, desc }) => {
|
|
2083
|
+
const { glyph, color } = getToolVisual(tool);
|
|
2084
|
+
return {
|
|
2085
|
+
keys: `${glyph} ${name}`,
|
|
2086
|
+
desc: `${desc} (${color})`
|
|
2087
|
+
};
|
|
2088
|
+
});
|
|
2089
|
+
}
|
|
2090
|
+
function splitIntoColumns(entries) {
|
|
2091
|
+
const left = [];
|
|
2092
|
+
const right = [];
|
|
2093
|
+
for (const entry of entries) {
|
|
2094
|
+
if (left.length <= right.length) {
|
|
2095
|
+
left.push(entry);
|
|
2096
|
+
} else {
|
|
2097
|
+
right.push(entry);
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
return [left, right];
|
|
2101
|
+
}
|
|
1982
2102
|
function HelpOverlay() {
|
|
1983
2103
|
const sections = helpSections();
|
|
1984
|
-
const
|
|
2104
|
+
const otherSections = sections.filter((s2) => s2.title !== "Tool Colors");
|
|
2105
|
+
const otherKeyWidth = Math.max(
|
|
2106
|
+
...otherSections.flatMap((s2) => s2.entries.map((e) => e.keys.length)),
|
|
2107
|
+
0
|
|
2108
|
+
);
|
|
2109
|
+
const toolSection = sections.find((s2) => s2.title === "Tool Colors");
|
|
2110
|
+
const toolKeyWidth = toolSection ? Math.max(...toolSection.entries.map((e) => e.keys.length), 0) : 0;
|
|
1985
2111
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
1986
2112
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
1987
2113
|
/* @__PURE__ */ jsx(Text, { bold: true, color: theme.accent, children: "Keyboard shortcuts" }),
|
|
1988
2114
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 Esc to close" })
|
|
1989
2115
|
] }),
|
|
1990
|
-
sections.map((sec) =>
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
Box,
|
|
1994
|
-
|
|
1995
|
-
flexDirection: "row",
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2116
|
+
sections.map((sec) => {
|
|
2117
|
+
if (sec.title === "Tool Colors") {
|
|
2118
|
+
const [leftCol, rightCol] = splitIntoColumns(sec.entries);
|
|
2119
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
2120
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: theme.brand, children: sec.title }),
|
|
2121
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
2122
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: leftCol.map((e, i) => /* @__PURE__ */ jsxs(
|
|
2123
|
+
Box,
|
|
2124
|
+
{
|
|
2125
|
+
flexDirection: "row",
|
|
2126
|
+
children: [
|
|
2127
|
+
/* @__PURE__ */ jsx(Text, { color: theme.accent, children: e.keys.padEnd(toolKeyWidth + 2) }),
|
|
2128
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: e.desc })
|
|
2129
|
+
]
|
|
2130
|
+
},
|
|
2131
|
+
i
|
|
2132
|
+
)) }),
|
|
2133
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: rightCol.map((e, i) => /* @__PURE__ */ jsxs(
|
|
2134
|
+
Box,
|
|
2135
|
+
{
|
|
2136
|
+
flexDirection: "row",
|
|
2137
|
+
children: [
|
|
2138
|
+
/* @__PURE__ */ jsx(Text, { color: theme.accent, children: e.keys.padEnd(toolKeyWidth + 2) }),
|
|
2139
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: e.desc })
|
|
2140
|
+
]
|
|
2141
|
+
},
|
|
2142
|
+
i
|
|
2143
|
+
)) })
|
|
2144
|
+
] })
|
|
2145
|
+
] }, sec.title);
|
|
2146
|
+
}
|
|
2147
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
2148
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: theme.brand, children: sec.title }),
|
|
2149
|
+
sec.entries.map((e, i) => /* @__PURE__ */ jsxs(
|
|
2150
|
+
Box,
|
|
2151
|
+
{
|
|
2152
|
+
flexDirection: "row",
|
|
2153
|
+
children: [
|
|
2154
|
+
/* @__PURE__ */ jsx(Text, { color: theme.accent, children: e.keys.padEnd(otherKeyWidth + 2) }),
|
|
2155
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: e.desc })
|
|
2156
|
+
]
|
|
2157
|
+
},
|
|
2158
|
+
i
|
|
2159
|
+
))
|
|
2160
|
+
] }, sec.title);
|
|
2161
|
+
})
|
|
2004
2162
|
] });
|
|
2005
2163
|
}
|
|
2006
2164
|
|
|
@@ -3525,6 +3683,7 @@ var ToolStreamBox = React5.memo(function ToolStreamBox2({
|
|
|
3525
3683
|
startedAt,
|
|
3526
3684
|
termWidth
|
|
3527
3685
|
}) {
|
|
3686
|
+
const { glyph, color } = getToolVisual(name);
|
|
3528
3687
|
const [tick, setTick] = useState(0);
|
|
3529
3688
|
useEffect(() => {
|
|
3530
3689
|
const t = setInterval(() => setTick((n) => n + 1), 500);
|
|
@@ -3537,8 +3696,11 @@ var ToolStreamBox = React5.memo(function ToolStreamBox2({
|
|
|
3537
3696
|
const rows = streamBoxRows(text, MAX_STREAM_LINES, contentWidth);
|
|
3538
3697
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 0, children: [
|
|
3539
3698
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
|
|
3540
|
-
/* @__PURE__ */
|
|
3541
|
-
|
|
3699
|
+
/* @__PURE__ */ jsxs(Text, { color, children: [
|
|
3700
|
+
glyph,
|
|
3701
|
+
" "
|
|
3702
|
+
] }),
|
|
3703
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color, children: name }),
|
|
3542
3704
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u23F1 ${fmtDuration(elapsedMs)}` }),
|
|
3543
3705
|
hidden > 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` (${totalLines} lines, showing last ${MAX_STREAM_LINES})` }) : null
|
|
3544
3706
|
] }),
|
|
@@ -3811,7 +3973,7 @@ function Banner({
|
|
|
3811
3973
|
entry
|
|
3812
3974
|
}) {
|
|
3813
3975
|
const cwdShort = shortenPath(entry.cwd, 48);
|
|
3814
|
-
const projectLabel =
|
|
3976
|
+
const projectLabel = path5.basename(entry.cwd);
|
|
3815
3977
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 2, paddingY: 0, children: [
|
|
3816
3978
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
3817
3979
|
/* @__PURE__ */ jsx(Text, { color: "magenta", bold: true, children: " \u259F\u259B " }),
|
|
@@ -4093,6 +4255,7 @@ var Entry = React5.memo(function Entry2({
|
|
|
4093
4255
|
] });
|
|
4094
4256
|
}
|
|
4095
4257
|
case "tool": {
|
|
4258
|
+
const { glyph, color } = getToolVisual(entry.name);
|
|
4096
4259
|
const argSummary = formatToolArgs(entry.name, entry.input);
|
|
4097
4260
|
const outLines = formatToolOutput(
|
|
4098
4261
|
entry.name,
|
|
@@ -4118,9 +4281,9 @@ var Entry = React5.memo(function Entry2({
|
|
|
4118
4281
|
})();
|
|
4119
4282
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
4120
4283
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
4121
|
-
/* @__PURE__ */ jsx(Text, { color
|
|
4122
|
-
" ",
|
|
4123
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color
|
|
4284
|
+
/* @__PURE__ */ jsx(Text, { color, children: glyph }),
|
|
4285
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
4286
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color, children: entry.name }),
|
|
4124
4287
|
argSummary ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4125
4288
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
4126
4289
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: argSummary })
|
|
@@ -4387,7 +4550,7 @@ function ScrollableHistory({
|
|
|
4387
4550
|
}
|
|
4388
4551
|
var MB = 1024 * 1024;
|
|
4389
4552
|
function defaultHeapLogPath() {
|
|
4390
|
-
return
|
|
4553
|
+
return path5.join(wstackGlobalRoot(), "logs", "heap.jsonl");
|
|
4391
4554
|
}
|
|
4392
4555
|
function takeHeapSample() {
|
|
4393
4556
|
const m = process.memoryUsage();
|
|
@@ -4417,10 +4580,10 @@ function startHeapWatchdog(opts = {}) {
|
|
|
4417
4580
|
const append = (line) => {
|
|
4418
4581
|
writeChain = writeChain.then(async () => {
|
|
4419
4582
|
if (!dirReady) {
|
|
4420
|
-
await
|
|
4583
|
+
await fs3.mkdir(path5.dirname(logPath), { recursive: true });
|
|
4421
4584
|
dirReady = true;
|
|
4422
4585
|
}
|
|
4423
|
-
await
|
|
4586
|
+
await fs3.appendFile(logPath, `${line}
|
|
4424
4587
|
`, "utf8");
|
|
4425
4588
|
}).catch(() => void 0);
|
|
4426
4589
|
};
|
|
@@ -4593,6 +4756,52 @@ function layoutInputRows(prompt, value, cursor, width) {
|
|
|
4593
4756
|
if (row.length > 0 || rows.length === 0) rows.push(row);
|
|
4594
4757
|
return rows;
|
|
4595
4758
|
}
|
|
4759
|
+
function inputIndexAtRowCol(prompt, value, width, row, col) {
|
|
4760
|
+
const w = Math.max(1, Math.floor(width));
|
|
4761
|
+
const flat = [];
|
|
4762
|
+
for (let i = 0; i < prompt.length; i++) flat.push({ ch: prompt[i], buf: -1 });
|
|
4763
|
+
for (let i = 0; i < value.length; i++) flat.push({ ch: value[i], buf: i });
|
|
4764
|
+
const rows = [];
|
|
4765
|
+
const starts = [];
|
|
4766
|
+
let cur = [];
|
|
4767
|
+
let curStart = 0;
|
|
4768
|
+
for (const cell of flat) {
|
|
4769
|
+
if (cell.ch === "\n") {
|
|
4770
|
+
rows.push(cur);
|
|
4771
|
+
starts.push(curStart);
|
|
4772
|
+
cur = [];
|
|
4773
|
+
curStart = cell.buf + 1;
|
|
4774
|
+
continue;
|
|
4775
|
+
}
|
|
4776
|
+
if (cur.length === 0 && cell.buf >= 0) curStart = cell.buf;
|
|
4777
|
+
cur.push({ buf: cell.buf });
|
|
4778
|
+
if (cur.length >= w) {
|
|
4779
|
+
rows.push(cur);
|
|
4780
|
+
starts.push(curStart);
|
|
4781
|
+
cur = [];
|
|
4782
|
+
curStart = -1;
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4785
|
+
if (cur.length > 0 || rows.length === 0) {
|
|
4786
|
+
rows.push(cur);
|
|
4787
|
+
starts.push(curStart);
|
|
4788
|
+
}
|
|
4789
|
+
const clamp = (n) => Math.max(0, Math.min(value.length, n));
|
|
4790
|
+
if (row < 0) return 0;
|
|
4791
|
+
if (row >= rows.length) return value.length;
|
|
4792
|
+
const r = rows[row];
|
|
4793
|
+
const c = Math.max(0, col);
|
|
4794
|
+
if (c < r.length) {
|
|
4795
|
+
const b = r[c].buf;
|
|
4796
|
+
return b < 0 ? 0 : clamp(b);
|
|
4797
|
+
}
|
|
4798
|
+
for (let k = r.length - 1; k >= 0; k--) {
|
|
4799
|
+
const b = r[k].buf;
|
|
4800
|
+
if (b >= 0) return clamp(b + 1);
|
|
4801
|
+
}
|
|
4802
|
+
const start = starts[row];
|
|
4803
|
+
return clamp(start !== void 0 && start >= 0 ? start : value.length);
|
|
4804
|
+
}
|
|
4596
4805
|
|
|
4597
4806
|
// src/mouse.ts
|
|
4598
4807
|
var ESC = String.fromCharCode(27);
|
|
@@ -5294,7 +5503,25 @@ function ProcessListMonitor() {
|
|
|
5294
5503
|
] })
|
|
5295
5504
|
] });
|
|
5296
5505
|
}
|
|
5297
|
-
function GoalPanel({
|
|
5506
|
+
function GoalPanel({
|
|
5507
|
+
goal,
|
|
5508
|
+
onCoordinatorStart,
|
|
5509
|
+
onCoordinatorStop,
|
|
5510
|
+
coordinatorRunning
|
|
5511
|
+
}) {
|
|
5512
|
+
useInput((input) => {
|
|
5513
|
+
if (input === "c" || input === "C") {
|
|
5514
|
+
if (onCoordinatorStart && goal) {
|
|
5515
|
+
const goalText = goal.refinedGoal || goal.goal;
|
|
5516
|
+
onCoordinatorStart(goalText);
|
|
5517
|
+
}
|
|
5518
|
+
}
|
|
5519
|
+
if (input === "S") {
|
|
5520
|
+
if (onCoordinatorStop) {
|
|
5521
|
+
onCoordinatorStop();
|
|
5522
|
+
}
|
|
5523
|
+
}
|
|
5524
|
+
});
|
|
5298
5525
|
if (!goal) {
|
|
5299
5526
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", padding: 1, children: [
|
|
5300
5527
|
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: theme.accent, children: "\u{1F3AF} Goal" }) }),
|
|
@@ -5306,7 +5533,11 @@ function GoalPanel({ goal }) {
|
|
|
5306
5533
|
] }),
|
|
5307
5534
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " to create one." })
|
|
5308
5535
|
] }),
|
|
5309
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press F9 to close." }) })
|
|
5536
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press F9 to close." }) }),
|
|
5537
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: coordinatorRunning ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5538
|
+
/* @__PURE__ */ jsx(Text, { color: "green", children: "\u25CF Coordinator running " }),
|
|
5539
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "[S] Stop coordinator" })
|
|
5540
|
+
] }) : /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "[C] Start coordinator" }) }) })
|
|
5310
5541
|
] });
|
|
5311
5542
|
}
|
|
5312
5543
|
const displayGoal = goal.refinedGoal || goal.goal;
|
|
@@ -5372,7 +5603,11 @@ function GoalPanel({ goal }) {
|
|
|
5372
5603
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Last task: " }),
|
|
5373
5604
|
/* @__PURE__ */ jsx(Text, { children: goal.lastTask.length > 50 ? goal.lastTask.slice(0, 47) + "\u2026" : goal.lastTask })
|
|
5374
5605
|
] }),
|
|
5375
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press F9 to close." }) })
|
|
5606
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press F9 to close." }) }),
|
|
5607
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: coordinatorRunning ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5608
|
+
/* @__PURE__ */ jsx(Text, { color: "green", children: "\u25CF Coordinator running " }),
|
|
5609
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "[S] Stop coordinator" })
|
|
5610
|
+
] }) : /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "[C] Start coordinator" }) }) })
|
|
5376
5611
|
] })
|
|
5377
5612
|
] });
|
|
5378
5613
|
}
|
|
@@ -5397,6 +5632,152 @@ function renderProgressBar(progress, trend) {
|
|
|
5397
5632
|
] })
|
|
5398
5633
|
] });
|
|
5399
5634
|
}
|
|
5635
|
+
var STATUS_COLOR = {
|
|
5636
|
+
open: "gray",
|
|
5637
|
+
in_progress: "yellow",
|
|
5638
|
+
done: "green"
|
|
5639
|
+
};
|
|
5640
|
+
var STATUS_ICON = {
|
|
5641
|
+
open: "\u25CB",
|
|
5642
|
+
in_progress: "\u25D0",
|
|
5643
|
+
done: "\u2713"
|
|
5644
|
+
};
|
|
5645
|
+
function planFilePath(projectRoot, sessionId, scope) {
|
|
5646
|
+
const base = resolveWstackPaths$1({ projectRoot }).projectSessions;
|
|
5647
|
+
if (scope === "project") {
|
|
5648
|
+
return path5.join(base, "backlog.plan.json");
|
|
5649
|
+
}
|
|
5650
|
+
if (sessionId) {
|
|
5651
|
+
return path5.join(base, `${sessionId}.plan.json`);
|
|
5652
|
+
}
|
|
5653
|
+
return path5.join(base, "backlog.plan.json");
|
|
5654
|
+
}
|
|
5655
|
+
function PlanPanel({ projectRoot, sessionId, onClose: _onClose }) {
|
|
5656
|
+
const [items, setItems] = useState([]);
|
|
5657
|
+
const [title, setTitle2] = useState(void 0);
|
|
5658
|
+
const [scope, setScope] = useState("session");
|
|
5659
|
+
const [loading, setLoading] = useState(true);
|
|
5660
|
+
const [error, setError] = useState(null);
|
|
5661
|
+
async function load(scope_) {
|
|
5662
|
+
setLoading(true);
|
|
5663
|
+
setError(null);
|
|
5664
|
+
try {
|
|
5665
|
+
const filePath = planFilePath(projectRoot, sessionId, scope_);
|
|
5666
|
+
let content;
|
|
5667
|
+
try {
|
|
5668
|
+
content = await fs3.readFile(filePath, "utf-8");
|
|
5669
|
+
} catch {
|
|
5670
|
+
setItems([]);
|
|
5671
|
+
setTitle2(void 0);
|
|
5672
|
+
setScope(scope_);
|
|
5673
|
+
setLoading(false);
|
|
5674
|
+
return;
|
|
5675
|
+
}
|
|
5676
|
+
const parsed = JSON.parse(content);
|
|
5677
|
+
setItems(parsed.items ?? []);
|
|
5678
|
+
setTitle2(parsed.title);
|
|
5679
|
+
setScope(scope_);
|
|
5680
|
+
} catch (err) {
|
|
5681
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
5682
|
+
} finally {
|
|
5683
|
+
setLoading(false);
|
|
5684
|
+
}
|
|
5685
|
+
}
|
|
5686
|
+
useEffect(() => {
|
|
5687
|
+
void load("session");
|
|
5688
|
+
}, []);
|
|
5689
|
+
async function handleScopeSwitch(newScope) {
|
|
5690
|
+
await load(newScope);
|
|
5691
|
+
}
|
|
5692
|
+
useInput((input) => {
|
|
5693
|
+
if (input === "s" || input === "S") {
|
|
5694
|
+
void handleScopeSwitch(scope === "session" ? "project" : "session");
|
|
5695
|
+
}
|
|
5696
|
+
});
|
|
5697
|
+
const open = items.filter((i) => i.status === "open");
|
|
5698
|
+
const inProgress = items.filter((i) => i.status === "in_progress");
|
|
5699
|
+
const done = items.filter((i) => i.status === "done");
|
|
5700
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
|
|
5701
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, marginBottom: 1, children: [
|
|
5702
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u{1F4CB} PLAN" }),
|
|
5703
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
5704
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: scope === "session" ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "session-scoped" }) : /* @__PURE__ */ jsx(Text, { color: "yellow", children: "project-scoped" }) }),
|
|
5705
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
5706
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5707
|
+
items.length,
|
|
5708
|
+
" item",
|
|
5709
|
+
items.length !== 1 ? "s" : ""
|
|
5710
|
+
] }),
|
|
5711
|
+
title ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5712
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
5713
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: title })
|
|
5714
|
+
] }) : null,
|
|
5715
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 F5/Esc to close" })
|
|
5716
|
+
] }),
|
|
5717
|
+
loading ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Loading plan..." }) : error ? /* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
5718
|
+
"Error: ",
|
|
5719
|
+
error
|
|
5720
|
+
] }) : items.length === 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 0, children: [
|
|
5721
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "No plan items yet." }),
|
|
5722
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5723
|
+
"Use ",
|
|
5724
|
+
/* @__PURE__ */ jsx(Text, { color: theme.accent, children: "/plan add <title>" }),
|
|
5725
|
+
" to create one."
|
|
5726
|
+
] })
|
|
5727
|
+
] }) : /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 0, children: [
|
|
5728
|
+
inProgress.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
5729
|
+
/* @__PURE__ */ jsxs(Text, { color: "yellow", bold: true, children: [
|
|
5730
|
+
"In Progress (",
|
|
5731
|
+
inProgress.length,
|
|
5732
|
+
")"
|
|
5733
|
+
] }),
|
|
5734
|
+
inProgress.map((item) => /* @__PURE__ */ jsx(PlanRow, { item }, item.id))
|
|
5735
|
+
] }),
|
|
5736
|
+
open.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
5737
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, bold: true, children: [
|
|
5738
|
+
"Open (",
|
|
5739
|
+
open.length,
|
|
5740
|
+
")"
|
|
5741
|
+
] }),
|
|
5742
|
+
open.map((item) => /* @__PURE__ */ jsx(PlanRow, { item }, item.id))
|
|
5743
|
+
] }),
|
|
5744
|
+
done.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
5745
|
+
/* @__PURE__ */ jsxs(Text, { color: "green", bold: true, children: [
|
|
5746
|
+
"Done (",
|
|
5747
|
+
done.length,
|
|
5748
|
+
")"
|
|
5749
|
+
] }),
|
|
5750
|
+
done.map((item) => /* @__PURE__ */ jsx(PlanRow, { item }, item.id))
|
|
5751
|
+
] })
|
|
5752
|
+
] }),
|
|
5753
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5754
|
+
"[",
|
|
5755
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: "S" }),
|
|
5756
|
+
"] Switch scope to",
|
|
5757
|
+
" ",
|
|
5758
|
+
scope === "session" ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: "project" }) : /* @__PURE__ */ jsx(Text, { color: "cyan", children: "session" }),
|
|
5759
|
+
" ",
|
|
5760
|
+
"\xB7 Use ",
|
|
5761
|
+
/* @__PURE__ */ jsx(Text, { color: theme.accent, children: "/plan add" }),
|
|
5762
|
+
" to add items \xB7",
|
|
5763
|
+
" ",
|
|
5764
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "F5/Esc to close" })
|
|
5765
|
+
] }) })
|
|
5766
|
+
] });
|
|
5767
|
+
}
|
|
5768
|
+
function PlanRow({ item }) {
|
|
5769
|
+
const icon = STATUS_ICON[item.status] ?? "?";
|
|
5770
|
+
const color = STATUS_COLOR[item.status] ?? "white";
|
|
5771
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
5772
|
+
/* @__PURE__ */ jsx(Text, { color, children: icon }),
|
|
5773
|
+
/* @__PURE__ */ jsx(Text, { color, children: item.title }),
|
|
5774
|
+
item.details ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5775
|
+
" \u2014 ",
|
|
5776
|
+
item.details.slice(0, 60),
|
|
5777
|
+
item.details.length > 60 ? "\u2026" : ""
|
|
5778
|
+
] }) : null
|
|
5779
|
+
] });
|
|
5780
|
+
}
|
|
5400
5781
|
var KIND_COLOR = {
|
|
5401
5782
|
goal: "cyan",
|
|
5402
5783
|
task: "yellow",
|
|
@@ -5709,6 +6090,14 @@ var MAX_ITERATIONS_PRESETS = [100, 200, 500, 1e3, 0];
|
|
|
5709
6090
|
var AUTO_PROCEED_MAX_PRESETS = [10, 25, 50, 100, 250, 0];
|
|
5710
6091
|
var ENHANCE_DELAY_PRESETS = [3e4, 45e3, 6e4, 9e4, 12e4];
|
|
5711
6092
|
var ENHANCE_LANGUAGES = ["original", "english"];
|
|
6093
|
+
var TOKEN_SAVING_TIERS = ["off", "minimal", "light", "medium", "aggressive"];
|
|
6094
|
+
var TOKEN_SAVING_TIER_DESCS = {
|
|
6095
|
+
off: "All tools enabled (full prompt)",
|
|
6096
|
+
minimal: "~3\u20134k tokens \u2014 core tools only",
|
|
6097
|
+
light: "~2\u20133k tokens \u2014 core + patterns",
|
|
6098
|
+
medium: "~1.5\u20132k tokens \u2014 most tools enabled",
|
|
6099
|
+
aggressive: "~4\u20135k tokens \u2014 trimmed prompt"
|
|
6100
|
+
};
|
|
5712
6101
|
function formatSettingsDelay(ms) {
|
|
5713
6102
|
if (ms === 0) return "disabled";
|
|
5714
6103
|
if (ms >= 6e4) return `${Math.round(ms / 6e4)}m`;
|
|
@@ -5743,7 +6132,7 @@ function SettingsPicker({
|
|
|
5743
6132
|
featureMemory,
|
|
5744
6133
|
featureSkills,
|
|
5745
6134
|
featureModelsRegistry,
|
|
5746
|
-
|
|
6135
|
+
tokenSavingTier,
|
|
5747
6136
|
allowOutsideProjectRoot,
|
|
5748
6137
|
contextAutoCompact,
|
|
5749
6138
|
contextStrategy,
|
|
@@ -5830,8 +6219,8 @@ function SettingsPicker({
|
|
|
5830
6219
|
},
|
|
5831
6220
|
{
|
|
5832
6221
|
label: "Token-saving mode",
|
|
5833
|
-
value:
|
|
5834
|
-
detail:
|
|
6222
|
+
value: tokenSavingTier,
|
|
6223
|
+
detail: TOKEN_SAVING_TIER_DESCS[tokenSavingTier]
|
|
5835
6224
|
},
|
|
5836
6225
|
{
|
|
5837
6226
|
label: "Allow outside project",
|
|
@@ -6448,10 +6837,10 @@ async function loadIndex(root) {
|
|
|
6448
6837
|
async function walk(root, rel, depth, out) {
|
|
6449
6838
|
if (out.length >= MAX_FILES_INDEXED) return;
|
|
6450
6839
|
if (depth > MAX_DEPTH) return;
|
|
6451
|
-
const dir = rel ?
|
|
6840
|
+
const dir = rel ? path5.join(root, rel) : root;
|
|
6452
6841
|
let entries;
|
|
6453
6842
|
try {
|
|
6454
|
-
entries = await
|
|
6843
|
+
entries = await fs3.readdir(dir, { withFileTypes: true });
|
|
6455
6844
|
} catch {
|
|
6456
6845
|
return;
|
|
6457
6846
|
}
|
|
@@ -8055,7 +8444,7 @@ function reducer(state, action) {
|
|
|
8055
8444
|
featureMemory: action.featureMemory,
|
|
8056
8445
|
featureSkills: action.featureSkills,
|
|
8057
8446
|
featureModelsRegistry: action.featureModelsRegistry,
|
|
8058
|
-
|
|
8447
|
+
tokenSavingTier: action.tokenSavingTier,
|
|
8059
8448
|
allowOutsideProjectRoot: action.allowOutsideProjectRoot,
|
|
8060
8449
|
contextAutoCompact: action.contextAutoCompact,
|
|
8061
8450
|
contextStrategy: action.contextStrategy,
|
|
@@ -8115,7 +8504,12 @@ function reducer(state, action) {
|
|
|
8115
8504
|
if (f === 10) return { ...state, settingsPicker: { ...sp, featureMemory: !sp.featureMemory, hint: bootHint } };
|
|
8116
8505
|
if (f === 11) return { ...state, settingsPicker: { ...sp, featureSkills: !sp.featureSkills, hint: bootHint } };
|
|
8117
8506
|
if (f === 12) return { ...state, settingsPicker: { ...sp, featureModelsRegistry: !sp.featureModelsRegistry, hint: bootHint } };
|
|
8118
|
-
if (f === 13)
|
|
8507
|
+
if (f === 13) {
|
|
8508
|
+
const i = TOKEN_SAVING_TIERS.indexOf(sp.tokenSavingTier);
|
|
8509
|
+
const base = i < 0 ? 0 : i;
|
|
8510
|
+
const next = (base + action.delta + TOKEN_SAVING_TIERS.length) % TOKEN_SAVING_TIERS.length;
|
|
8511
|
+
return { ...state, settingsPicker: { ...sp, tokenSavingTier: TOKEN_SAVING_TIERS[next] ?? "off", hint: bootHint } };
|
|
8512
|
+
}
|
|
8119
8513
|
if (f === 14) return { ...state, settingsPicker: { ...sp, allowOutsideProjectRoot: !sp.allowOutsideProjectRoot, hint: void 0 } };
|
|
8120
8514
|
if (f === 15) return { ...state, settingsPicker: { ...sp, contextAutoCompact: !sp.contextAutoCompact, hint: void 0 } };
|
|
8121
8515
|
if (f === 16) {
|
|
@@ -8574,6 +8968,10 @@ function reducer(state, action) {
|
|
|
8574
8968
|
const opening = !state.processListOpen;
|
|
8575
8969
|
return opening ? { ...state, processListOpen: true, monitorOpen: false, agentsMonitorOpen: false, helpOpen: false, todosMonitorOpen: false, queuePanelOpen: false, goalPanelOpen: false } : { ...state, processListOpen: false };
|
|
8576
8970
|
}
|
|
8971
|
+
case "togglePlanPanel": {
|
|
8972
|
+
const opening = !state.planPanelOpen;
|
|
8973
|
+
return opening ? { ...state, planPanelOpen: true, monitorOpen: false, agentsMonitorOpen: false, helpOpen: false, todosMonitorOpen: false, queuePanelOpen: false, processListOpen: false, goalPanelOpen: false } : { ...state, planPanelOpen: false };
|
|
8974
|
+
}
|
|
8577
8975
|
case "toggleGoalPanel": {
|
|
8578
8976
|
const opening = !state.goalPanelOpen;
|
|
8579
8977
|
return opening ? { ...state, goalPanelOpen: true, monitorOpen: false, agentsMonitorOpen: false, helpOpen: false, todosMonitorOpen: false, queuePanelOpen: false, processListOpen: false } : { ...state, goalPanelOpen: false };
|
|
@@ -9118,7 +9516,11 @@ function App({
|
|
|
9118
9516
|
getLiveSessions,
|
|
9119
9517
|
onSwitchToSession,
|
|
9120
9518
|
initialAgentsMonitorOpen,
|
|
9121
|
-
subscribeCoordinatorEvents
|
|
9519
|
+
subscribeCoordinatorEvents,
|
|
9520
|
+
onCoordinatorStart,
|
|
9521
|
+
onCoordinatorStop,
|
|
9522
|
+
coordinatorRunning = false,
|
|
9523
|
+
clientId
|
|
9122
9524
|
}) {
|
|
9123
9525
|
const { exit } = useApp();
|
|
9124
9526
|
const { stdout } = useStdout();
|
|
@@ -9154,6 +9556,28 @@ function App({
|
|
|
9154
9556
|
setIndexState(getIndexState());
|
|
9155
9557
|
return onIndexStateChange((next) => setIndexState(next));
|
|
9156
9558
|
}, []);
|
|
9559
|
+
const [breakerCountdown, setBreakerCountdown] = useState(
|
|
9560
|
+
() => getProcessRegistry().getBreakerCountdown()
|
|
9561
|
+
);
|
|
9562
|
+
useEffect(() => {
|
|
9563
|
+
const s2 = getSettings?.();
|
|
9564
|
+
if (s2) {
|
|
9565
|
+
getProcessRegistry().setBreakerConfig({
|
|
9566
|
+
enabled: s2.breakerEnabled ?? false,
|
|
9567
|
+
autoKillResetMs: s2.breakerAutoKillResetMs ?? 6e4
|
|
9568
|
+
});
|
|
9569
|
+
}
|
|
9570
|
+
return getProcessRegistry().onBreakerCountdownChange((snap) => setBreakerCountdown(snap));
|
|
9571
|
+
}, [getSettings]);
|
|
9572
|
+
const breakerArmed = breakerCountdown !== null;
|
|
9573
|
+
useEffect(() => {
|
|
9574
|
+
if (!breakerArmed) return;
|
|
9575
|
+
const t = setInterval(
|
|
9576
|
+
() => setBreakerCountdown(getProcessRegistry().getBreakerCountdown()),
|
|
9577
|
+
1e3
|
|
9578
|
+
);
|
|
9579
|
+
return () => clearInterval(t);
|
|
9580
|
+
}, [breakerArmed]);
|
|
9157
9581
|
useEffect(() => {
|
|
9158
9582
|
setHiddenItems([...statuslineHiddenItems]);
|
|
9159
9583
|
}, [statuslineHiddenItems]);
|
|
@@ -9251,7 +9675,7 @@ function App({
|
|
|
9251
9675
|
},
|
|
9252
9676
|
autonomyPicker: { open: false, options: [], selected: 0 },
|
|
9253
9677
|
resumePicker: { open: false, sessions: [], selected: 0, busy: false, hint: void 0, error: void 0 },
|
|
9254
|
-
settingsPicker: { open: false, field: 0, mode: "off", delayMs: 0, titleAnimation: true, yolo: false, streamFleet: true, chime: false, confirmExit: true, nextPrediction: false, featureMcp: true, featurePlugins: true, featureMemory: true, featureSkills: true, featureModelsRegistry: true,
|
|
9678
|
+
settingsPicker: { open: false, field: 0, mode: "off", delayMs: 0, titleAnimation: true, yolo: false, streamFleet: true, chime: false, confirmExit: true, nextPrediction: false, featureMcp: true, featurePlugins: true, featureMemory: true, featureSkills: true, featureModelsRegistry: true, tokenSavingTier: "off", allowOutsideProjectRoot: true, contextAutoCompact: true, contextStrategy: "hybrid", logLevel: "info", auditLevel: "standard", indexOnStart: true, maxIterations: 500, autoProceedMaxIterations: 50, enhanceDelayMs: 6e4, enhanceEnabled: true, enhanceLanguage: "original", debugStream: false, configScope: "global" },
|
|
9255
9679
|
projectPicker: { open: false, allItems: [], items: [], selected: 0, filter: "", hint: void 0 },
|
|
9256
9680
|
confirmQueue: [],
|
|
9257
9681
|
enhance: null,
|
|
@@ -9279,6 +9703,7 @@ function App({
|
|
|
9279
9703
|
todosMonitorOpen: false,
|
|
9280
9704
|
queuePanelOpen: false,
|
|
9281
9705
|
processListOpen: false,
|
|
9706
|
+
planPanelOpen: false,
|
|
9282
9707
|
goalPanelOpen: false,
|
|
9283
9708
|
sessionsPanelOpen: false,
|
|
9284
9709
|
sessionsPanel: { sessions: [], busy: false, selected: -1 },
|
|
@@ -9318,20 +9743,20 @@ function App({
|
|
|
9318
9743
|
const lastEnterAtRef = useRef(0);
|
|
9319
9744
|
const tokenPreviewsRef = useRef(/* @__PURE__ */ new Map());
|
|
9320
9745
|
const projectName = React5.useMemo(() => {
|
|
9321
|
-
const base =
|
|
9322
|
-
return base && base !==
|
|
9746
|
+
const base = path5.basename(projectRoot);
|
|
9747
|
+
return base && base !== path5.sep ? base : void 0;
|
|
9323
9748
|
}, [projectRoot]);
|
|
9324
9749
|
const [workingDirChip, setWorkingDirChip] = React5.useState(() => {
|
|
9325
9750
|
const ctx = agent.ctx;
|
|
9326
9751
|
if (ctx.workingDir && ctx.workingDir !== projectRoot) {
|
|
9327
|
-
return
|
|
9752
|
+
return path5.relative(projectRoot, ctx.workingDir) || ".";
|
|
9328
9753
|
}
|
|
9329
9754
|
return void 0;
|
|
9330
9755
|
});
|
|
9331
9756
|
React5.useEffect(() => {
|
|
9332
9757
|
const ctx = agent.ctx;
|
|
9333
9758
|
return ctx.onWorkingDirChanged((newDir) => {
|
|
9334
|
-
const rel =
|
|
9759
|
+
const rel = path5.relative(projectRoot, newDir) || ".";
|
|
9335
9760
|
setWorkingDirChip(rel === "." ? void 0 : rel);
|
|
9336
9761
|
});
|
|
9337
9762
|
}, [agent.ctx, projectRoot]);
|
|
@@ -9728,7 +10153,7 @@ function App({
|
|
|
9728
10153
|
let cancelled = false;
|
|
9729
10154
|
const poll = async () => {
|
|
9730
10155
|
try {
|
|
9731
|
-
const data = await
|
|
10156
|
+
const data = await fs3.readFile(planPath, "utf8");
|
|
9732
10157
|
const parsed = JSON.parse(data);
|
|
9733
10158
|
if (cancelled) return;
|
|
9734
10159
|
if (!Array.isArray(parsed.items)) {
|
|
@@ -9762,7 +10187,7 @@ function App({
|
|
|
9762
10187
|
let cancelled = false;
|
|
9763
10188
|
const poll = async () => {
|
|
9764
10189
|
try {
|
|
9765
|
-
const data = await
|
|
10190
|
+
const data = await fs3.readFile(taskPath, "utf8");
|
|
9766
10191
|
const parsed = JSON.parse(data);
|
|
9767
10192
|
if (cancelled) return;
|
|
9768
10193
|
if (!Array.isArray(parsed.tasks)) {
|
|
@@ -9874,6 +10299,7 @@ function App({
|
|
|
9874
10299
|
if (stateRef.current.todosMonitorOpen) dispatch({ type: "toggleTodosMonitor" });
|
|
9875
10300
|
if (stateRef.current.queuePanelOpen) dispatch({ type: "toggleQueuePanel" });
|
|
9876
10301
|
if (stateRef.current.processListOpen) dispatch({ type: "toggleProcessList" });
|
|
10302
|
+
if (stateRef.current.planPanelOpen) dispatch({ type: "togglePlanPanel" });
|
|
9877
10303
|
if (stateRef.current.goalPanelOpen) dispatch({ type: "toggleGoalPanel" });
|
|
9878
10304
|
if (stateRef.current.sessionsPanelOpen) dispatch({ type: "toggleSessionsPanel" });
|
|
9879
10305
|
eraseLiveRegion();
|
|
@@ -9899,7 +10325,7 @@ function App({
|
|
|
9899
10325
|
featureMemory: sp.featureMemory,
|
|
9900
10326
|
featureSkills: sp.featureSkills,
|
|
9901
10327
|
featureModelsRegistry: sp.featureModelsRegistry,
|
|
9902
|
-
|
|
10328
|
+
tokenSavingTier: sp.tokenSavingTier,
|
|
9903
10329
|
allowOutsideProjectRoot: sp.allowOutsideProjectRoot,
|
|
9904
10330
|
contextAutoCompact: sp.contextAutoCompact,
|
|
9905
10331
|
contextStrategy: sp.contextStrategy,
|
|
@@ -10061,9 +10487,9 @@ function App({
|
|
|
10061
10487
|
dispatch({ type: "pickerClose" });
|
|
10062
10488
|
return;
|
|
10063
10489
|
}
|
|
10064
|
-
const absPath =
|
|
10490
|
+
const absPath = path5.isAbsolute(picked) ? picked : path5.join(projectRoot, picked);
|
|
10065
10491
|
try {
|
|
10066
|
-
const data = await
|
|
10492
|
+
const data = await fs3.readFile(absPath, "utf8");
|
|
10067
10493
|
const token = await builder.registerFile({
|
|
10068
10494
|
kind: "file",
|
|
10069
10495
|
data,
|
|
@@ -10303,7 +10729,7 @@ function App({
|
|
|
10303
10729
|
featureMemory: s2.featureMemory ?? true,
|
|
10304
10730
|
featureSkills: s2.featureSkills ?? true,
|
|
10305
10731
|
featureModelsRegistry: s2.featureModelsRegistry ?? true,
|
|
10306
|
-
|
|
10732
|
+
tokenSavingTier: s2.featureTokenSaving ?? "off",
|
|
10307
10733
|
allowOutsideProjectRoot: s2.allowOutsideProjectRoot ?? true,
|
|
10308
10734
|
contextAutoCompact: s2.contextAutoCompact ?? true,
|
|
10309
10735
|
contextStrategy: s2.contextStrategy ?? "hybrid",
|
|
@@ -10439,7 +10865,7 @@ function App({
|
|
|
10439
10865
|
featureMemory: sp.featureMemory,
|
|
10440
10866
|
featureSkills: sp.featureSkills,
|
|
10441
10867
|
featureModelsRegistry: sp.featureModelsRegistry,
|
|
10442
|
-
featureTokenSaving: sp.
|
|
10868
|
+
featureTokenSaving: sp.tokenSavingTier,
|
|
10443
10869
|
allowOutsideProjectRoot: sp.allowOutsideProjectRoot,
|
|
10444
10870
|
contextAutoCompact: sp.contextAutoCompact,
|
|
10445
10871
|
contextStrategy: sp.contextStrategy,
|
|
@@ -10471,7 +10897,7 @@ function App({
|
|
|
10471
10897
|
state.settingsPicker.featureMemory,
|
|
10472
10898
|
state.settingsPicker.featureSkills,
|
|
10473
10899
|
state.settingsPicker.featureModelsRegistry,
|
|
10474
|
-
state.settingsPicker.
|
|
10900
|
+
state.settingsPicker.tokenSavingTier,
|
|
10475
10901
|
state.settingsPicker.allowOutsideProjectRoot,
|
|
10476
10902
|
state.settingsPicker.contextAutoCompact,
|
|
10477
10903
|
state.settingsPicker.contextStrategy,
|
|
@@ -10746,6 +11172,47 @@ function App({
|
|
|
10746
11172
|
if (flushTimerRef.current) clearTimeout(flushTimerRef.current);
|
|
10747
11173
|
};
|
|
10748
11174
|
}, [events, agent.ctx.todos]);
|
|
11175
|
+
useEffect(() => {
|
|
11176
|
+
if (!clientId || !events) return;
|
|
11177
|
+
let toolCalls = 0;
|
|
11178
|
+
const emitStatus = () => {
|
|
11179
|
+
const usage = tokenCounter?.total();
|
|
11180
|
+
const cost = tokenCounter?.estimateCost();
|
|
11181
|
+
const mode = getAutonomy?.() ?? "off";
|
|
11182
|
+
events.emit("client.status", {
|
|
11183
|
+
clientType: "tui",
|
|
11184
|
+
clientId,
|
|
11185
|
+
projectHash: agent.ctx.projectRoot ? projectSlug(agent.ctx.projectRoot) : "unknown",
|
|
11186
|
+
agentCount: 1,
|
|
11187
|
+
// TUI is a single leader agent
|
|
11188
|
+
model: agent.ctx.model,
|
|
11189
|
+
mode,
|
|
11190
|
+
toolCalls,
|
|
11191
|
+
inputTokens: usage?.input ?? 0,
|
|
11192
|
+
outputTokens: usage?.output ?? 0,
|
|
11193
|
+
cacheTokens: (usage?.cacheRead ?? 0) + (usage?.cacheWrite ?? 0),
|
|
11194
|
+
costUsd: cost?.total ?? 0,
|
|
11195
|
+
timestamp: Date.now(),
|
|
11196
|
+
projectSlug: agent.ctx.projectRoot ? projectSlug(agent.ctx.projectRoot) : "unknown"
|
|
11197
|
+
});
|
|
11198
|
+
};
|
|
11199
|
+
const offTool = events.on("tool.executed", () => {
|
|
11200
|
+
toolCalls++;
|
|
11201
|
+
emitStatus();
|
|
11202
|
+
});
|
|
11203
|
+
const offProviderResp = events.on("provider.response", () => {
|
|
11204
|
+
emitStatus();
|
|
11205
|
+
});
|
|
11206
|
+
const offIterCompleted = events.on("iteration.completed", () => {
|
|
11207
|
+
emitStatus();
|
|
11208
|
+
});
|
|
11209
|
+
emitStatus();
|
|
11210
|
+
return () => {
|
|
11211
|
+
offTool();
|
|
11212
|
+
offProviderResp();
|
|
11213
|
+
offIterCompleted();
|
|
11214
|
+
};
|
|
11215
|
+
}, [events, clientId, tokenCounter, getAutonomy, agent.ctx.model, agent.ctx.projectRoot]);
|
|
10749
11216
|
useEffect(() => {
|
|
10750
11217
|
if (!registerDebugStreamCallback) return;
|
|
10751
11218
|
let cancelled = false;
|
|
@@ -11566,6 +12033,21 @@ function App({
|
|
|
11566
12033
|
toggleWorktreeOverlay();
|
|
11567
12034
|
return;
|
|
11568
12035
|
}
|
|
12036
|
+
if (key.fn === 5) {
|
|
12037
|
+
if (state.planPanelOpen) {
|
|
12038
|
+
dispatch({ type: "togglePlanPanel" });
|
|
12039
|
+
} else {
|
|
12040
|
+
if (state.agentsMonitorOpen) dispatch({ type: "toggleAgentsMonitor" });
|
|
12041
|
+
if (state.monitorOpen) dispatch({ type: "toggleMonitor" });
|
|
12042
|
+
if (state.worktreeMonitorOpen) dispatch({ type: "worktreeMonitorToggle" });
|
|
12043
|
+
if (state.todosMonitorOpen) dispatch({ type: "toggleTodosMonitor" });
|
|
12044
|
+
if (state.autoPhase?.monitorOpen) dispatch({ type: "autoPhaseMonitorToggle" });
|
|
12045
|
+
if (state.settingsPicker.open) dispatch({ type: "settingsClose" });
|
|
12046
|
+
if (state.helpOpen) dispatch({ type: "toggleHelp" });
|
|
12047
|
+
dispatch({ type: "togglePlanPanel" });
|
|
12048
|
+
}
|
|
12049
|
+
return;
|
|
12050
|
+
}
|
|
11569
12051
|
if (key.fn === 6) {
|
|
11570
12052
|
toggleTodosOverlay();
|
|
11571
12053
|
return;
|
|
@@ -11668,7 +12150,7 @@ function App({
|
|
|
11668
12150
|
featureMemory: cfg.featureMemory ?? true,
|
|
11669
12151
|
featureSkills: cfg.featureSkills ?? true,
|
|
11670
12152
|
featureModelsRegistry: cfg.featureModelsRegistry ?? true,
|
|
11671
|
-
|
|
12153
|
+
tokenSavingTier: cfg.featureTokenSaving ?? "off",
|
|
11672
12154
|
allowOutsideProjectRoot: cfg.allowOutsideProjectRoot ?? true,
|
|
11673
12155
|
contextAutoCompact: cfg.contextAutoCompact ?? true,
|
|
11674
12156
|
contextStrategy: cfg.contextStrategy ?? "hybrid",
|
|
@@ -11851,6 +12333,57 @@ function App({
|
|
|
11851
12333
|
setDraft(buffer, buffer.length);
|
|
11852
12334
|
return;
|
|
11853
12335
|
}
|
|
12336
|
+
if (key.upArrow || key.downArrow || key.pageUp || key.pageDown) {
|
|
12337
|
+
const width = stdout?.columns ?? 80;
|
|
12338
|
+
const rows = layoutInputRows(INPUT_PROMPT, buffer, cursor, width);
|
|
12339
|
+
if (rows.length <= 1) ; else {
|
|
12340
|
+
let row = 0, col = 0, offset = 0;
|
|
12341
|
+
outer: for (let r = 0; r < rows.length; r++) {
|
|
12342
|
+
const cells = rows[r];
|
|
12343
|
+
for (let c = 0; c < cells.length; c++) {
|
|
12344
|
+
if (offset === cursor) {
|
|
12345
|
+
row = r;
|
|
12346
|
+
col = c;
|
|
12347
|
+
break outer;
|
|
12348
|
+
}
|
|
12349
|
+
offset++;
|
|
12350
|
+
}
|
|
12351
|
+
if (cells.length < width) offset++;
|
|
12352
|
+
}
|
|
12353
|
+
if (key.upArrow) {
|
|
12354
|
+
if (row > 0) {
|
|
12355
|
+
const prevRowLen = rows[row - 1].filter((cell) => !cell.prompt && !cell.chip).length;
|
|
12356
|
+
const targetCol = Math.min(col, prevRowLen);
|
|
12357
|
+
const target = inputIndexAtRowCol(INPUT_PROMPT, buffer, width, row - 1, targetCol);
|
|
12358
|
+
setDraft(buffer, target);
|
|
12359
|
+
return;
|
|
12360
|
+
}
|
|
12361
|
+
return;
|
|
12362
|
+
}
|
|
12363
|
+
if (key.downArrow) {
|
|
12364
|
+
if (row < rows.length - 1) {
|
|
12365
|
+
const nextRowLen = rows[row + 1].filter((cell) => !cell.prompt && !cell.chip).length;
|
|
12366
|
+
const targetCol = Math.min(col, nextRowLen);
|
|
12367
|
+
const target = inputIndexAtRowCol(INPUT_PROMPT, buffer, width, row + 1, targetCol);
|
|
12368
|
+
setDraft(buffer, target);
|
|
12369
|
+
return;
|
|
12370
|
+
}
|
|
12371
|
+
return;
|
|
12372
|
+
}
|
|
12373
|
+
if (key.pageUp || key.pageDown) {
|
|
12374
|
+
const pageSize = Math.max(1, Math.floor((stdout?.rows ?? 24) / 2));
|
|
12375
|
+
const delta = key.pageUp ? -pageSize : pageSize;
|
|
12376
|
+
const targetRow = Math.max(0, Math.min(rows.length - 1, row + delta));
|
|
12377
|
+
if (targetRow !== row) {
|
|
12378
|
+
const targetRowLen = rows[targetRow].filter((cell) => !cell.prompt && !cell.chip).length;
|
|
12379
|
+
const targetCol = Math.min(col, targetRowLen);
|
|
12380
|
+
const target = inputIndexAtRowCol(INPUT_PROMPT, buffer, width, targetRow, targetCol);
|
|
12381
|
+
setDraft(buffer, target);
|
|
12382
|
+
}
|
|
12383
|
+
return;
|
|
12384
|
+
}
|
|
12385
|
+
}
|
|
12386
|
+
}
|
|
11854
12387
|
const overlayOpen = state.monitorOpen || state.agentsMonitorOpen || state.worktreeMonitorOpen || state.todosMonitorOpen || state.queuePanelOpen || state.processListOpen || state.goalPanelOpen || state.sessionsPanelOpen || state.coordinator.monitorOpen || state.helpOpen || (state.autoPhase?.monitorOpen ?? false) || state.rewindOverlay !== null;
|
|
11855
12388
|
if (mouseMode && !overlayOpen) {
|
|
11856
12389
|
if (key.mouse?.kind === "wheel") {
|
|
@@ -11980,7 +12513,7 @@ function App({
|
|
|
11980
12513
|
setDraft(next2, cursor);
|
|
11981
12514
|
return;
|
|
11982
12515
|
}
|
|
11983
|
-
if (key.ctrl
|
|
12516
|
+
if (key.ctrl) {
|
|
11984
12517
|
await pasteClipboardText();
|
|
11985
12518
|
return;
|
|
11986
12519
|
}
|
|
@@ -12626,7 +13159,7 @@ User message:
|
|
|
12626
13159
|
featureMemory: state.settingsPicker.featureMemory,
|
|
12627
13160
|
featureSkills: state.settingsPicker.featureSkills,
|
|
12628
13161
|
featureModelsRegistry: state.settingsPicker.featureModelsRegistry,
|
|
12629
|
-
|
|
13162
|
+
tokenSavingTier: state.settingsPicker.tokenSavingTier,
|
|
12630
13163
|
allowOutsideProjectRoot: state.settingsPicker.allowOutsideProjectRoot,
|
|
12631
13164
|
contextAutoCompact: state.settingsPicker.contextAutoCompact,
|
|
12632
13165
|
contextStrategy: state.settingsPicker.contextStrategy,
|
|
@@ -12811,6 +13344,7 @@ User message:
|
|
|
12811
13344
|
eternalStage: state.eternalStage,
|
|
12812
13345
|
goalSummary: state.goalSummary,
|
|
12813
13346
|
indexState,
|
|
13347
|
+
breakerCountdown,
|
|
12814
13348
|
modeLabel: liveModeLabel || void 0,
|
|
12815
13349
|
debugStreamStats: state.debugStreamStats,
|
|
12816
13350
|
enhanceCountdown,
|
|
@@ -12819,7 +13353,7 @@ User message:
|
|
|
12819
13353
|
autoProceedCountdown: state.countdown?.remainingSeconds ?? null,
|
|
12820
13354
|
sessionCount,
|
|
12821
13355
|
mailbox: mailboxStatus,
|
|
12822
|
-
tokenSavingMode: getSettings ? getSettings().featureTokenSaving : tokenSavingMode,
|
|
13356
|
+
tokenSavingMode: getSettings ? getSettings().featureTokenSaving !== "off" : tokenSavingMode,
|
|
12823
13357
|
toolCount
|
|
12824
13358
|
}
|
|
12825
13359
|
) }),
|
|
@@ -12889,7 +13423,23 @@ User message:
|
|
|
12889
13423
|
Object.keys(state.worktrees).length > 0 && !state.worktreeMonitorOpen && !state.monitorOpen ? /* @__PURE__ */ jsx(WorktreePanel, { worktrees: state.worktrees, nowTick }) : null,
|
|
12890
13424
|
state.queuePanelOpen ? /* @__PURE__ */ jsx(QueuePanel, { items: state.queue }) : null,
|
|
12891
13425
|
state.processListOpen ? /* @__PURE__ */ jsx(ProcessListMonitor, {}) : null,
|
|
12892
|
-
state.
|
|
13426
|
+
state.planPanelOpen ? /* @__PURE__ */ jsx(
|
|
13427
|
+
PlanPanel,
|
|
13428
|
+
{
|
|
13429
|
+
projectRoot,
|
|
13430
|
+
sessionId: agent.ctx.session?.id ?? null,
|
|
13431
|
+
onClose: () => dispatch({ type: "togglePlanPanel" })
|
|
13432
|
+
}
|
|
13433
|
+
) : null,
|
|
13434
|
+
state.goalPanelOpen ? /* @__PURE__ */ jsx(
|
|
13435
|
+
GoalPanel,
|
|
13436
|
+
{
|
|
13437
|
+
goal: state.goalSummary,
|
|
13438
|
+
onCoordinatorStart: onCoordinatorStart ?? void 0,
|
|
13439
|
+
onCoordinatorStop: onCoordinatorStop ?? void 0,
|
|
13440
|
+
coordinatorRunning
|
|
13441
|
+
}
|
|
13442
|
+
) : null,
|
|
12893
13443
|
(() => {
|
|
12894
13444
|
const anyMonitorOpen = state.agentsMonitorOpen || (state.autoPhase?.monitorOpen ?? false) || state.worktreeMonitorOpen || state.todosMonitorOpen || state.monitorOpen || state.processListOpen || state.queuePanelOpen || state.goalPanelOpen;
|
|
12895
13445
|
let nextPanelHint;
|
|
@@ -13072,7 +13622,7 @@ async function runTui(opts) {
|
|
|
13072
13622
|
stdout,
|
|
13073
13623
|
events: opts.events,
|
|
13074
13624
|
model: opts.model,
|
|
13075
|
-
appName: opts.projectRoot ?
|
|
13625
|
+
appName: opts.projectRoot ? path5.basename(opts.projectRoot) : void 0
|
|
13076
13626
|
});
|
|
13077
13627
|
};
|
|
13078
13628
|
const stopTitle = () => {
|
|
@@ -13142,7 +13692,7 @@ async function runTui(opts) {
|
|
|
13142
13692
|
await mailbox.registerClient({
|
|
13143
13693
|
clientId,
|
|
13144
13694
|
sessionId: opts.projectRoot,
|
|
13145
|
-
name: `TUI [${
|
|
13695
|
+
name: `TUI [${path5.basename(opts.projectRoot)}]`,
|
|
13146
13696
|
source: "tui",
|
|
13147
13697
|
pid: process.pid
|
|
13148
13698
|
});
|
|
@@ -13285,7 +13835,9 @@ async function runTui(opts) {
|
|
|
13285
13835
|
getLiveSessions: opts.getLiveSessions,
|
|
13286
13836
|
onSwitchToSession: opts.onSwitchToSession,
|
|
13287
13837
|
initialAgentsMonitorOpen: opts.initialAgentsMonitorOpen,
|
|
13288
|
-
subscribeCoordinatorEvents: opts.subscribeCoordinatorEvents
|
|
13838
|
+
subscribeCoordinatorEvents: opts.subscribeCoordinatorEvents,
|
|
13839
|
+
onCoordinatorStart: opts.onCoordinatorStart,
|
|
13840
|
+
onCoordinatorStop: opts.onCoordinatorStop
|
|
13289
13841
|
}),
|
|
13290
13842
|
{ exitOnCtrlC: false, stdin: inkStdin }
|
|
13291
13843
|
);
|