@wrongstack/tui 0.257.2 → 0.264.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +22 -1
- package/dist/index.js +457 -108
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { writeErr, resolveProjectDir, wstackGlobalRoot, GlobalMailbox, resolveWstackPaths, loadGoal, InputBuilder, DefaultSessionRewinder, writeOut, formatTodosList, buildGoalPreamble, expectDefined as expectDefined$1, shouldEnhance, enhanceUserPrompt, recentTextTurns, normalizedEqual,
|
|
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';
|
|
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
5
|
import * as path4 from 'path';
|
|
6
6
|
import React5, { forwardRef, useState, useEffect, useMemo, memo, useRef, useCallback, useReducer, useLayoutEffect } from 'react';
|
|
7
7
|
import * as fs2 from 'fs/promises';
|
|
8
|
+
import { expectDefined, toErrorMessage } from '@wrongstack/core/utils';
|
|
8
9
|
import { routeImagesForModel } from '@wrongstack/runtime/vision';
|
|
9
10
|
import { getIndexState, onIndexStateChange, getProcessRegistry } from '@wrongstack/tools';
|
|
10
11
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
11
|
-
import { readClipboardImage } from '@wrongstack/runtime/clipboard';
|
|
12
|
-
import { expectDefined } from '@wrongstack/core/utils';
|
|
12
|
+
import { readClipboardText, readClipboardImage } from '@wrongstack/runtime/clipboard';
|
|
13
13
|
import * as v8 from 'v8';
|
|
14
14
|
import { spawn } from 'child_process';
|
|
15
15
|
|
|
@@ -126,9 +126,13 @@ function modeIcon(label) {
|
|
|
126
126
|
const icon = MODE_ICONS[label] ?? "\u25AA";
|
|
127
127
|
return `${icon} ${label}`;
|
|
128
128
|
}
|
|
129
|
-
function
|
|
130
|
-
const stripped = label.replace(/^\/next\s+[\d\s]+\s*/, "");
|
|
131
|
-
|
|
129
|
+
function formatSuggestionLabel(label, maxLen = 28) {
|
|
130
|
+
const stripped = label.replace(/^\/next\s+[\d\s]+\s*/, "").trim();
|
|
131
|
+
if (!stripped) return "";
|
|
132
|
+
if (stripped.length <= maxLen) return stripped;
|
|
133
|
+
const shortened = stripped.slice(0, maxLen);
|
|
134
|
+
const lastSpace = shortened.lastIndexOf(" ");
|
|
135
|
+
return lastSpace > 10 ? `${shortened.slice(0, lastSpace)}\u2026` : `${shortened}\u2026`;
|
|
132
136
|
}
|
|
133
137
|
var COMPACT_THRESHOLD = 50;
|
|
134
138
|
var COMFORTABLE_THRESHOLD = 90;
|
|
@@ -156,6 +160,7 @@ function StatusBar({
|
|
|
156
160
|
workingDir,
|
|
157
161
|
processCount,
|
|
158
162
|
context,
|
|
163
|
+
contextStrategy,
|
|
159
164
|
hiddenItems,
|
|
160
165
|
events,
|
|
161
166
|
eternalStage,
|
|
@@ -215,6 +220,7 @@ function StatusBar({
|
|
|
215
220
|
const hasDebugStream = !!debugStreamStats;
|
|
216
221
|
const hasEnhanceCountdown = enhanceCountdown != null && enhanceCountdown > 0;
|
|
217
222
|
const hasNextStepsAutoSubmit = nextStepsAutoSubmitCountdown != null && nextStepsAutoSubmitCountdown > 0;
|
|
223
|
+
const countdownColor = nextStepsAutoSubmitCountdown != null ? nextStepsAutoSubmitCountdown > 20 ? "green" : nextStepsAutoSubmitCountdown > 10 ? "yellow" : "red" : "green";
|
|
218
224
|
const hasTaskActivity = tasks && (tasks.pending > 0 || tasks.inProgress > 0 || tasks.completed > 0 || tasks.blocked > 0 || tasks.failed > 0);
|
|
219
225
|
const hasThirdLine = todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || hasTaskActivity || fleetHasActivity || hasBrainActivity || hasDebugStream || hasEnhanceCountdown || hasNextStepsAutoSubmit;
|
|
220
226
|
return /* @__PURE__ */ jsxs(
|
|
@@ -268,7 +274,12 @@ function StatusBar({
|
|
|
268
274
|
"ctx ",
|
|
269
275
|
renderMeter(clampedRatio, 8),
|
|
270
276
|
" ",
|
|
271
|
-
pctText
|
|
277
|
+
pctText,
|
|
278
|
+
contextStrategy ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
279
|
+
" [",
|
|
280
|
+
contextStrategy,
|
|
281
|
+
"]"
|
|
282
|
+
] }) : null
|
|
272
283
|
] });
|
|
273
284
|
})()
|
|
274
285
|
] }) : null,
|
|
@@ -574,7 +585,7 @@ function StatusBar({
|
|
|
574
585
|
] }) : null,
|
|
575
586
|
hasEnhanceCountdown && enhanceCountdown != null ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
576
587
|
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || fleetHasActivity || hasBrainActivity || hasDebugStream ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
577
|
-
/* @__PURE__ */ jsxs(Text, { color: enhanceCountdown
|
|
588
|
+
/* @__PURE__ */ jsxs(Text, { color: enhanceCountdown > 15 ? "green" : enhanceCountdown > 5 ? "yellow" : "red", children: [
|
|
578
589
|
"\u23F3 auto-send in ",
|
|
579
590
|
enhanceCountdown,
|
|
580
591
|
"s"
|
|
@@ -582,12 +593,15 @@ function StatusBar({
|
|
|
582
593
|
] }) : null,
|
|
583
594
|
hasNextStepsAutoSubmit && nextStepsAutoSubmitCountdown != null ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
584
595
|
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || fleetHasActivity || hasBrainActivity || hasDebugStream || hasEnhanceCountdown ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
585
|
-
/* @__PURE__ */ jsxs(Text, { color:
|
|
596
|
+
/* @__PURE__ */ jsxs(Text, { color: countdownColor, bold: true, children: [
|
|
586
597
|
"\u23F3 ",
|
|
587
|
-
nextStepsAutoSubmitLabel ? truncateLabel(nextStepsAutoSubmitLabel, 30) : "next step",
|
|
588
|
-
" in ",
|
|
589
598
|
nextStepsAutoSubmitCountdown,
|
|
590
599
|
"s"
|
|
600
|
+
] }),
|
|
601
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
602
|
+
" ",
|
|
603
|
+
nextStepsAutoSubmitLabel ? formatSuggestionLabel(nextStepsAutoSubmitLabel) : "",
|
|
604
|
+
" \xB7 \u21E5 edit"
|
|
591
605
|
] })
|
|
592
606
|
] }) : null
|
|
593
607
|
] }) : /* @__PURE__ */ jsx(Box, { height: 1, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
|
|
@@ -1564,9 +1578,9 @@ function buttonLabels(suggestedPattern) {
|
|
|
1564
1578
|
function stringifyInput(input) {
|
|
1565
1579
|
if (!input || typeof input !== "object") return "";
|
|
1566
1580
|
const obj = input;
|
|
1567
|
-
return Object.entries(obj).filter(([k]) => k !== "content" && k !== "new_string").map(([k, v]) => `${k}: ${
|
|
1581
|
+
return Object.entries(obj).filter(([k]) => k !== "content" && k !== "new_string").map(([k, v]) => `${k}: ${truncate(JSON.stringify(v), 80)}`).join(" ");
|
|
1568
1582
|
}
|
|
1569
|
-
function
|
|
1583
|
+
function truncate(s2, max) {
|
|
1570
1584
|
return s2.length <= max ? s2 : `${s2.slice(0, max - 1)}\u2026`;
|
|
1571
1585
|
}
|
|
1572
1586
|
function hasDiff(input) {
|
|
@@ -3915,10 +3929,14 @@ function parseWithHeading(content, strict) {
|
|
|
3915
3929
|
if (steps.length === 0) {
|
|
3916
3930
|
return { steps: [], texts: [], stripped: content, autoTexts: [] };
|
|
3917
3931
|
}
|
|
3932
|
+
const headingWasXmlTag = headingMatch[0].startsWith("<");
|
|
3933
|
+
if (strict && headingWasXmlTag && !afterHeading.includes("</next_steps>")) {
|
|
3934
|
+
return { steps: [], texts: [], stripped: content, autoTexts: [] };
|
|
3935
|
+
}
|
|
3918
3936
|
const texts = steps.map((s2) => s2.text);
|
|
3919
3937
|
const autoTexts = steps.filter((s2) => s2.auto).map((s2) => s2.text);
|
|
3920
3938
|
const blockStart = headingMatch.index;
|
|
3921
|
-
const blockEnd =
|
|
3939
|
+
const blockEnd = headingMatch[0].length + findBlockEnd(afterHeading, steps.length);
|
|
3922
3940
|
const stripped = (content.slice(0, blockStart) + content.slice(blockStart + blockEnd)).replace(/\n{3,}/g, "\n\n").trim();
|
|
3923
3941
|
return { steps, texts, stripped, autoTexts };
|
|
3924
3942
|
}
|
|
@@ -3927,27 +3945,32 @@ function buildPermissiveHeadingRe() {
|
|
|
3927
3945
|
return new RegExp(variants, "i");
|
|
3928
3946
|
}
|
|
3929
3947
|
function findBlockEnd(afterHeading, stepCount) {
|
|
3948
|
+
const closeIdx = afterHeading.indexOf("</next_steps>");
|
|
3949
|
+
if (closeIdx !== -1) {
|
|
3950
|
+
let end = closeIdx + "</next_steps>".length;
|
|
3951
|
+
if (afterHeading[end] === "\n") end += 1;
|
|
3952
|
+
return end;
|
|
3953
|
+
}
|
|
3930
3954
|
const lines = afterHeading.split("\n");
|
|
3931
3955
|
let consumed = 0;
|
|
3932
3956
|
let found = 0;
|
|
3933
3957
|
for (const rawLine of lines) {
|
|
3934
3958
|
const line = rawLine.trim();
|
|
3935
|
-
if (line
|
|
3936
|
-
consumed += rawLine.length + 1;
|
|
3937
|
-
break;
|
|
3938
|
-
}
|
|
3939
|
-
if (!line) {
|
|
3940
|
-
consumed += rawLine.length + 1;
|
|
3941
|
-
continue;
|
|
3942
|
-
}
|
|
3959
|
+
if (!line) break;
|
|
3943
3960
|
const m = ITEM_RE.exec(line);
|
|
3944
3961
|
if (!m) break;
|
|
3945
3962
|
consumed += rawLine.length + 1;
|
|
3946
3963
|
found++;
|
|
3947
|
-
if (found >= stepCount)
|
|
3964
|
+
if (found >= stepCount) {
|
|
3965
|
+
consumed -= 1;
|
|
3966
|
+
break;
|
|
3967
|
+
}
|
|
3948
3968
|
}
|
|
3949
3969
|
return consumed;
|
|
3950
3970
|
}
|
|
3971
|
+
function stripNextStepsBlock(text) {
|
|
3972
|
+
return text.replace(/<next_steps\b[^>]*>[\s\S]*?<\/next_steps>/gi, "").replace(/<next_steps\b[^>]*\/?>/gi, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
3973
|
+
}
|
|
3951
3974
|
function brainStatusStyle(status) {
|
|
3952
3975
|
switch (status) {
|
|
3953
3976
|
case "thinking":
|
|
@@ -3977,7 +4000,9 @@ function brainRiskColor(risk) {
|
|
|
3977
4000
|
var Entry = React5.memo(function Entry2({
|
|
3978
4001
|
entry,
|
|
3979
4002
|
termWidth,
|
|
3980
|
-
setSuggestions
|
|
4003
|
+
setSuggestions,
|
|
4004
|
+
autonomyMode,
|
|
4005
|
+
autoSubmitCountdown
|
|
3981
4006
|
}) {
|
|
3982
4007
|
const nextSteps = useMemo(() => {
|
|
3983
4008
|
if (entry.kind !== "assistant") return { steps: [], stripped: "" };
|
|
@@ -3985,6 +4010,7 @@ var Entry = React5.memo(function Entry2({
|
|
|
3985
4010
|
}, [entry.kind, entry.text]);
|
|
3986
4011
|
useEffect(() => {
|
|
3987
4012
|
if (!setSuggestions) return;
|
|
4013
|
+
if (entry.kind !== "assistant") return;
|
|
3988
4014
|
const text = entry.text ?? "";
|
|
3989
4015
|
const { texts } = parseNextSteps(text, true);
|
|
3990
4016
|
if (texts.length > 0) setSuggestions(texts);
|
|
@@ -4055,10 +4081,11 @@ var Entry = React5.memo(function Entry2({
|
|
|
4055
4081
|
/* @__PURE__ */ jsx(Text, { bold: true, color: theme.accent, children: "\u{1F4A1} NEXT STEPS " }),
|
|
4056
4082
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "(use /next 1, /next 1 2 3 to select)" })
|
|
4057
4083
|
] }),
|
|
4058
|
-
steps.map((s2) => /* @__PURE__ */ jsx(Box, { flexDirection: "row", marginTop: 0, children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
4084
|
+
steps.map((s2, i) => /* @__PURE__ */ jsx(Box, { flexDirection: "row", marginTop: 0, children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
4059
4085
|
/* @__PURE__ */ jsx(Text, { bold: true, color: theme.accent, children: ` ${s2.index}. ` }),
|
|
4060
4086
|
/* @__PURE__ */ jsx(Text, { children: s2.text }),
|
|
4061
|
-
s2.auto ? /* @__PURE__ */ jsx(Text, { color: "cyan", dimColor: true, children: " auto" }) : null
|
|
4087
|
+
s2.auto ? /* @__PURE__ */ jsx(Text, { color: "cyan", dimColor: true, children: " auto" }) : null,
|
|
4088
|
+
autonomyMode === "auto" && i === 0 ? autoSubmitCountdown != null && autoSubmitCountdown > 0 ? /* @__PURE__ */ jsx(Text, { color: autoSubmitCountdown > 20 ? "green" : autoSubmitCountdown > 10 ? "yellow" : "red", children: ` auto in ${autoSubmitCountdown}s` }) : /* @__PURE__ */ jsx(Text, { color: "cyan", children: " \u23E9" }) : null
|
|
4062
4089
|
] }) }, s2.index))
|
|
4063
4090
|
]
|
|
4064
4091
|
}
|
|
@@ -4230,7 +4257,7 @@ var Entry = React5.memo(function Entry2({
|
|
|
4230
4257
|
}
|
|
4231
4258
|
}
|
|
4232
4259
|
});
|
|
4233
|
-
function History({ entries, generation, streamingText, toolStream, setSuggestions }) {
|
|
4260
|
+
function History({ entries, generation, streamingText, toolStream, setSuggestions, autonomyMode, autoSubmitCountdown }) {
|
|
4234
4261
|
const { stdout } = useStdout();
|
|
4235
4262
|
const [termSize, setTermSize] = useState({
|
|
4236
4263
|
columns: stdout?.columns ?? 80,
|
|
@@ -4248,7 +4275,7 @@ function History({ entries, generation, streamingText, toolStream, setSuggestion
|
|
|
4248
4275
|
const termWidth = termSize.columns;
|
|
4249
4276
|
const tail = streamingText ? tailForDisplay(streamingText, MAX_STREAM_DISPLAY_CHARS) : "";
|
|
4250
4277
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4251
|
-
/* @__PURE__ */ jsx(Static, { items: entries, children: (entry) => /* @__PURE__ */ jsx(Box, { marginBottom: entry.kind === "turn-summary" ? 1 : 0, children: /* @__PURE__ */ jsx(Entry, { entry, termWidth, setSuggestions }) }, entry.id) }, generation ?? 0),
|
|
4278
|
+
/* @__PURE__ */ jsx(Static, { items: entries, children: (entry) => /* @__PURE__ */ jsx(Box, { marginBottom: entry.kind === "turn-summary" ? 1 : 0, children: /* @__PURE__ */ jsx(Entry, { entry, termWidth, setSuggestions, autonomyMode, autoSubmitCountdown }) }, entry.id) }, generation ?? 0),
|
|
4252
4279
|
/* @__PURE__ */ jsx(Box, { flexGrow: 1, children: tail ? /* @__PURE__ */ jsx(AssistantTail, { text: tail, termWidth }) : null })
|
|
4253
4280
|
] });
|
|
4254
4281
|
}
|
|
@@ -4298,7 +4325,9 @@ function ScrollableHistory({
|
|
|
4298
4325
|
totalLines,
|
|
4299
4326
|
onMeasure,
|
|
4300
4327
|
maxWidth,
|
|
4301
|
-
setSuggestions
|
|
4328
|
+
setSuggestions,
|
|
4329
|
+
autonomyMode,
|
|
4330
|
+
autoSubmitCountdown
|
|
4302
4331
|
}) {
|
|
4303
4332
|
const { stdout } = useStdout();
|
|
4304
4333
|
const rawWidth = stdout?.columns ?? 80;
|
|
@@ -4337,7 +4366,7 @@ function ScrollableHistory({
|
|
|
4337
4366
|
flexShrink: 0,
|
|
4338
4367
|
children: [
|
|
4339
4368
|
hiddenCount > 0 ? /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsx(Text, { dimColor: true, italic: true, children: ` \u2191 ${hiddenCount} earlier ${hiddenCount === 1 ? "entry" : "entries"} (scroll lives in this session; full log on disk)` }) }) : null,
|
|
4340
|
-
shown.map((entry) => /* @__PURE__ */ jsx(Box, { marginBottom: entry.kind === "turn-summary" ? 1 : 0, flexShrink: 0, children: /* @__PURE__ */ jsx(Entry, { entry, termWidth, setSuggestions }) }, entry.id)),
|
|
4369
|
+
shown.map((entry) => /* @__PURE__ */ jsx(Box, { marginBottom: entry.kind === "turn-summary" ? 1 : 0, flexShrink: 0, children: /* @__PURE__ */ jsx(Entry, { entry, termWidth, setSuggestions, autonomyMode, autoSubmitCountdown }) }, entry.id)),
|
|
4341
4370
|
tail ? /* @__PURE__ */ jsx(AssistantTail, { text: tail, termWidth }) : null,
|
|
4342
4371
|
toolTail && toolStream ? /* @__PURE__ */ jsx(
|
|
4343
4372
|
ToolStreamBox,
|
|
@@ -4917,12 +4946,8 @@ function PhaseMonitor({
|
|
|
4917
4946
|
phases,
|
|
4918
4947
|
runningPhaseIds,
|
|
4919
4948
|
elapsedMs,
|
|
4920
|
-
nowTick
|
|
4921
|
-
onClose
|
|
4949
|
+
nowTick
|
|
4922
4950
|
}) {
|
|
4923
|
-
useInput((_, key) => {
|
|
4924
|
-
if (key.escape) onClose();
|
|
4925
|
-
});
|
|
4926
4951
|
const phaseList = Object.values(phases);
|
|
4927
4952
|
const running = phaseList.filter(
|
|
4928
4953
|
(p) => runningPhaseIds.includes(Object.keys(phases).find((k) => phases[k] === p) ?? "")
|
|
@@ -4954,7 +4979,7 @@ function PhaseMonitor({
|
|
|
4954
4979
|
failed.length
|
|
4955
4980
|
] })
|
|
4956
4981
|
] }) : null,
|
|
4957
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 Ctrl+P
|
|
4982
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 Ctrl+P to close" })
|
|
4958
4983
|
] }),
|
|
4959
4984
|
phaseList.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No phases active. Use /autophase start [title] to begin." }) : phaseList.map((phase, i) => {
|
|
4960
4985
|
const s2 = fmtPhase(phase.status);
|
|
@@ -4983,7 +5008,7 @@ function PhaseMonitor({
|
|
|
4983
5008
|
] })
|
|
4984
5009
|
] }) }, phaseKey);
|
|
4985
5010
|
}),
|
|
4986
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 navigate phases
|
|
5011
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 navigate phases" }) })
|
|
4987
5012
|
] });
|
|
4988
5013
|
}
|
|
4989
5014
|
var fmtElapsed3 = (ms) => {
|
|
@@ -5164,7 +5189,7 @@ function QueuePanel({ items }) {
|
|
|
5164
5189
|
"+",
|
|
5165
5190
|
overflow
|
|
5166
5191
|
] }) : null,
|
|
5167
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 F7
|
|
5192
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 F7 to close" })
|
|
5168
5193
|
] }) }),
|
|
5169
5194
|
items.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No queued messages" }) : /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
5170
5195
|
visible.map((item, i) => /* @__PURE__ */ jsxs(Box, { flexDirection: "row", flexShrink: 0, children: [
|
|
@@ -5240,7 +5265,7 @@ function ProcessListMonitor() {
|
|
|
5240
5265
|
breakerState,
|
|
5241
5266
|
b.state !== "closed" ? ` fail=${b.consecutiveFailures}/5 slow=${b.slowCallsInWindow}/3` : ""
|
|
5242
5267
|
] }),
|
|
5243
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 F8
|
|
5268
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 F8 to close" })
|
|
5244
5269
|
] }),
|
|
5245
5270
|
all.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No active processes. Bash/exec spawns appear here." }) : null,
|
|
5246
5271
|
all.map((p, i) => {
|
|
@@ -5281,7 +5306,7 @@ function GoalPanel({ goal }) {
|
|
|
5281
5306
|
] }),
|
|
5282
5307
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " to create one." })
|
|
5283
5308
|
] }),
|
|
5284
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press F9
|
|
5309
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press F9 to close." }) })
|
|
5285
5310
|
] });
|
|
5286
5311
|
}
|
|
5287
5312
|
const displayGoal = goal.refinedGoal || goal.goal;
|
|
@@ -5347,7 +5372,7 @@ function GoalPanel({ goal }) {
|
|
|
5347
5372
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Last task: " }),
|
|
5348
5373
|
/* @__PURE__ */ jsx(Text, { children: goal.lastTask.length > 50 ? goal.lastTask.slice(0, 47) + "\u2026" : goal.lastTask })
|
|
5349
5374
|
] }),
|
|
5350
|
-
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press F9
|
|
5375
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press F9 to close." }) })
|
|
5351
5376
|
] })
|
|
5352
5377
|
] });
|
|
5353
5378
|
}
|
|
@@ -5372,6 +5397,115 @@ function renderProgressBar(progress, trend) {
|
|
|
5372
5397
|
] })
|
|
5373
5398
|
] });
|
|
5374
5399
|
}
|
|
5400
|
+
var KIND_COLOR = {
|
|
5401
|
+
goal: "cyan",
|
|
5402
|
+
task: "yellow",
|
|
5403
|
+
knowledge: "green",
|
|
5404
|
+
consensus: "magenta",
|
|
5405
|
+
deadlock: "red"
|
|
5406
|
+
};
|
|
5407
|
+
function fmtElapsed4(at, nowTick) {
|
|
5408
|
+
const s2 = Math.floor((nowTick - at) / 1e3);
|
|
5409
|
+
if (s2 < 60) return `${s2}s ago`;
|
|
5410
|
+
const m = Math.floor(s2 / 60);
|
|
5411
|
+
if (m < 60) return `${m}m ago`;
|
|
5412
|
+
return `${Math.floor(m / 60)}h ago`;
|
|
5413
|
+
}
|
|
5414
|
+
function GoalRow({
|
|
5415
|
+
goal
|
|
5416
|
+
}) {
|
|
5417
|
+
const statusColor = {
|
|
5418
|
+
active: "green",
|
|
5419
|
+
paused: "yellow",
|
|
5420
|
+
completed: "gray",
|
|
5421
|
+
failed: "red"
|
|
5422
|
+
};
|
|
5423
|
+
const color = statusColor[goal.status] ?? "gray";
|
|
5424
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: [
|
|
5425
|
+
/* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color, bold: true, children: [
|
|
5426
|
+
goal.status === "active" ? "\u25B6" : goal.status === "paused" ? "\u23F8" : goal.status === "completed" ? "\u2713" : "\u2717",
|
|
5427
|
+
" ",
|
|
5428
|
+
goal.title || "(unnamed goal)"
|
|
5429
|
+
] }) }),
|
|
5430
|
+
goal.tasks.length > 0 && /* @__PURE__ */ jsx(Box, { flexDirection: "column", paddingLeft: 2, children: goal.tasks.map((task) => {
|
|
5431
|
+
const taskColor = {
|
|
5432
|
+
pending: "gray",
|
|
5433
|
+
running: "yellow",
|
|
5434
|
+
done: "green",
|
|
5435
|
+
failed: "red"
|
|
5436
|
+
};
|
|
5437
|
+
return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color: taskColor[task.status] ?? "gray", children: [
|
|
5438
|
+
task.status === "pending" ? "\u25CB" : task.status === "running" ? "\u25B6" : task.status === "done" ? "\u2713" : "\u2717",
|
|
5439
|
+
" ",
|
|
5440
|
+
task.title,
|
|
5441
|
+
task.assignedTo ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5442
|
+
" \u2192 ",
|
|
5443
|
+
task.assignedTo
|
|
5444
|
+
] }) : null
|
|
5445
|
+
] }) }, task.id);
|
|
5446
|
+
}) }),
|
|
5447
|
+
goal.participants.length > 0 && /* @__PURE__ */ jsx(Box, { paddingLeft: 2, children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
5448
|
+
"participants: ",
|
|
5449
|
+
goal.participants.join(", ")
|
|
5450
|
+
] }) })
|
|
5451
|
+
] }, goal.id);
|
|
5452
|
+
}
|
|
5453
|
+
function CoordinatorPanel({
|
|
5454
|
+
coordinator,
|
|
5455
|
+
nowTick,
|
|
5456
|
+
onClose
|
|
5457
|
+
}) {
|
|
5458
|
+
const handleInput = useCallback(
|
|
5459
|
+
(input, _key) => {
|
|
5460
|
+
if (input === "q" || input === "Q" || input === "\x1B") {
|
|
5461
|
+
onClose();
|
|
5462
|
+
}
|
|
5463
|
+
},
|
|
5464
|
+
[onClose]
|
|
5465
|
+
);
|
|
5466
|
+
useInput(handleInput);
|
|
5467
|
+
const { goals, timeline, knowledgeCount, healthy } = coordinator;
|
|
5468
|
+
return /* @__PURE__ */ jsxs(
|
|
5469
|
+
Box,
|
|
5470
|
+
{
|
|
5471
|
+
flexDirection: "column",
|
|
5472
|
+
borderStyle: "round",
|
|
5473
|
+
borderColor: "cyan",
|
|
5474
|
+
paddingX: 1,
|
|
5475
|
+
height: Math.min(30, Math.max(10, goals.length * 4 + timeline.length + 8)),
|
|
5476
|
+
width: 80,
|
|
5477
|
+
children: [
|
|
5478
|
+
/* @__PURE__ */ jsxs(Box, { borderStyle: "bold", borderColor: "cyan", paddingX: 1, marginBottom: 1, children: [
|
|
5479
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u{1F916} AutonomousCoordinator" }),
|
|
5480
|
+
/* @__PURE__ */ jsx(Box, { flexGrow: 1 }),
|
|
5481
|
+
/* @__PURE__ */ jsx(Text, { dimColor: !healthy, color: healthy ? "green" : "red", children: healthy ? "\u25CF connected" : "\u25CB disconnected" }),
|
|
5482
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \xB7 q/esc to close" })
|
|
5483
|
+
] }),
|
|
5484
|
+
goals.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
5485
|
+
/* @__PURE__ */ jsxs(Text, { bold: true, children: [
|
|
5486
|
+
"Goals (",
|
|
5487
|
+
goals.length,
|
|
5488
|
+
")"
|
|
5489
|
+
] }),
|
|
5490
|
+
goals.map((goal) => /* @__PURE__ */ jsx(GoalRow, { goal }, goal.id))
|
|
5491
|
+
] }),
|
|
5492
|
+
/* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
5493
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Knowledge " }),
|
|
5494
|
+
/* @__PURE__ */ jsx(Text, { color: "green", children: knowledgeCount }),
|
|
5495
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " shared facts" })
|
|
5496
|
+
] }),
|
|
5497
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [
|
|
5498
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Activity" }),
|
|
5499
|
+
timeline.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: " No activity yet" }) : timeline.slice(0, 10).map((entry, i) => /* @__PURE__ */ jsxs(Box, { alignItems: "flex-start", children: [
|
|
5500
|
+
/* @__PURE__ */ jsx(Text, { color: KIND_COLOR[entry.kind] ?? "gray", dimColor: i > 2, children: entry.icon }),
|
|
5501
|
+
/* @__PURE__ */ jsx(Box, { flexGrow: 1, marginLeft: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: i > 2, children: entry.text }) }),
|
|
5502
|
+
/* @__PURE__ */ jsx(Box, { marginLeft: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: fmtElapsed4(entry.at, nowTick) }) })
|
|
5503
|
+
] }, i))
|
|
5504
|
+
] })
|
|
5505
|
+
]
|
|
5506
|
+
}
|
|
5507
|
+
);
|
|
5508
|
+
}
|
|
5375
5509
|
function ResumePicker({
|
|
5376
5510
|
sessions,
|
|
5377
5511
|
selected,
|
|
@@ -5479,7 +5613,7 @@ function SessionsPanel({
|
|
|
5479
5613
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, flexShrink: 0, children: [
|
|
5480
5614
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
5481
5615
|
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "\u29C9 Sessions" }),
|
|
5482
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 F10
|
|
5616
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 F10 to close" }),
|
|
5483
5617
|
busy && /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 loading\u2026" })
|
|
5484
5618
|
] }),
|
|
5485
5619
|
resumeConfirm ? /* @__PURE__ */ jsxs(Box, { marginY: 1, borderStyle: "single", borderColor: "yellow", paddingX: 1, children: [
|
|
@@ -5592,7 +5726,7 @@ var MODE_DESC = {
|
|
|
5592
5726
|
suggest: "Shows next-step suggestions after each turn",
|
|
5593
5727
|
auto: "Self-driving \u2014 agent continues automatically"
|
|
5594
5728
|
};
|
|
5595
|
-
var SETTINGS_FIELD_COUNT =
|
|
5729
|
+
var SETTINGS_FIELD_COUNT = 27;
|
|
5596
5730
|
var CONFIG_SCOPES = ["global", "project"];
|
|
5597
5731
|
function SettingsPicker({
|
|
5598
5732
|
field,
|
|
@@ -5610,6 +5744,7 @@ function SettingsPicker({
|
|
|
5610
5744
|
featureSkills,
|
|
5611
5745
|
featureModelsRegistry,
|
|
5612
5746
|
featureTokenSaving,
|
|
5747
|
+
allowOutsideProjectRoot,
|
|
5613
5748
|
contextAutoCompact,
|
|
5614
5749
|
contextStrategy,
|
|
5615
5750
|
logLevel,
|
|
@@ -5698,6 +5833,11 @@ function SettingsPicker({
|
|
|
5698
5833
|
value: boolVal(featureTokenSaving),
|
|
5699
5834
|
detail: "Omit non-essential tools and trim system prompt to save tokens"
|
|
5700
5835
|
},
|
|
5836
|
+
{
|
|
5837
|
+
label: "Allow outside project",
|
|
5838
|
+
value: boolVal(allowOutsideProjectRoot),
|
|
5839
|
+
detail: "Allow tools to access paths outside project root"
|
|
5840
|
+
},
|
|
5701
5841
|
// ── Context ──
|
|
5702
5842
|
{ section: "Context" },
|
|
5703
5843
|
{
|
|
@@ -5803,7 +5943,7 @@ function SettingsPicker({
|
|
|
5803
5943
|
};
|
|
5804
5944
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
5805
5945
|
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u2501\u2501 Settings \u2501\u2501" }),
|
|
5806
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 field \xB7 \u2190/\u2192 change (instant
|
|
5946
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 field \xB7 \u2190/\u2192 change (instant apply) \xB7 F5 to close" }),
|
|
5807
5947
|
hasAbove ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \u2191 ${windowStart} field${windowStart === 1 ? "" : "s"} above` }) : null,
|
|
5808
5948
|
rows.map((row, i) => {
|
|
5809
5949
|
const fieldAtRow = fieldRowIndex.indexOf(i);
|
|
@@ -6053,7 +6193,7 @@ function TodosMonitor({ todos }) {
|
|
|
6053
6193
|
done
|
|
6054
6194
|
] })
|
|
6055
6195
|
] }) : null,
|
|
6056
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 F6
|
|
6196
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 F6 to close" })
|
|
6057
6197
|
] }),
|
|
6058
6198
|
todos.length === 0 ? /* @__PURE__ */ jsx(Box, { marginY: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No todos. The agent will create them as it plans work." }) }) : twoCols ? (
|
|
6059
6199
|
/* Two-column layout: split the list in half, render side-by-side.
|
|
@@ -6068,7 +6208,7 @@ function TodosMonitor({ todos }) {
|
|
|
6068
6208
|
)
|
|
6069
6209
|
] });
|
|
6070
6210
|
}
|
|
6071
|
-
var
|
|
6211
|
+
var fmtElapsed5 = (ms) => {
|
|
6072
6212
|
const s2 = Math.floor(ms / 1e3);
|
|
6073
6213
|
const m = Math.floor(s2 / 60);
|
|
6074
6214
|
const h = Math.floor(m / 60);
|
|
@@ -6095,7 +6235,7 @@ function WorktreeMonitor({
|
|
|
6095
6235
|
onClose
|
|
6096
6236
|
}) {
|
|
6097
6237
|
useInput((input, key) => {
|
|
6098
|
-
if (key.
|
|
6238
|
+
if (key.ctrl && input === "w") onClose();
|
|
6099
6239
|
});
|
|
6100
6240
|
const TERMINAL_TTL_MS = 5 * 6e4;
|
|
6101
6241
|
const list = Object.values(worktrees);
|
|
@@ -6132,12 +6272,12 @@ function WorktreeMonitor({
|
|
|
6132
6272
|
failed
|
|
6133
6273
|
] })
|
|
6134
6274
|
] }) : null,
|
|
6135
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 Ctrl+T / F4
|
|
6275
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 Ctrl+T / F4 to close" })
|
|
6136
6276
|
] }),
|
|
6137
6277
|
recent.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No worktrees. They appear when AutoPhase runs with isolation on." }) : recent.map((w) => {
|
|
6138
6278
|
const s2 = fmt(w.status);
|
|
6139
6279
|
const short = w.branch.replace(/^wstack\/ap\//, "");
|
|
6140
|
-
const elapsed = w.allocatedAt ?
|
|
6280
|
+
const elapsed = w.allocatedAt ? fmtElapsed5(nowTick - w.allocatedAt) : "\u2014";
|
|
6141
6281
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
6142
6282
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
6143
6283
|
/* @__PURE__ */ jsx(Text, { color: s2.color, bold: true, children: s2.icon }),
|
|
@@ -6182,12 +6322,12 @@ function WorktreeMonitor({
|
|
|
6182
6322
|
] }, w.branch);
|
|
6183
6323
|
}),
|
|
6184
6324
|
/* @__PURE__ */ jsxs(Box, { marginTop: 1, children: [
|
|
6185
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "
|
|
6325
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Ctrl+T to close \xB7 merge conflicts with /worktree merge <branch>" }),
|
|
6186
6326
|
staleTerminal > 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \xB7 ${staleTerminal} terminal pruned` }) : null
|
|
6187
6327
|
] })
|
|
6188
6328
|
] });
|
|
6189
6329
|
}
|
|
6190
|
-
var
|
|
6330
|
+
var fmtElapsed6 = (ms) => {
|
|
6191
6331
|
const s2 = Math.floor(ms / 1e3);
|
|
6192
6332
|
const m = Math.floor(s2 / 60);
|
|
6193
6333
|
const h = Math.floor(m / 60);
|
|
@@ -6253,7 +6393,7 @@ function WorktreePanel({
|
|
|
6253
6393
|
list.map((w) => {
|
|
6254
6394
|
const s2 = st(w.status);
|
|
6255
6395
|
const conflict = w.status === "needs-review";
|
|
6256
|
-
const elapsed = w.allocatedAt ?
|
|
6396
|
+
const elapsed = w.allocatedAt ? fmtElapsed6(nowTick - w.allocatedAt) : "";
|
|
6257
6397
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
6258
6398
|
/* @__PURE__ */ jsx(Text, { color: s2.color, children: s2.icon }),
|
|
6259
6399
|
/* @__PURE__ */ jsx(Text, { children: w.branch.replace(/^wstack\/ap\//, "").slice(0, 18).padEnd(18) }),
|
|
@@ -6456,10 +6596,10 @@ function useDirectorFleetBridge({
|
|
|
6456
6596
|
let streamFlushTimer = null;
|
|
6457
6597
|
const flushStreamBufs = () => {
|
|
6458
6598
|
for (const [id, text] of streamBuf) {
|
|
6459
|
-
const
|
|
6460
|
-
if (!
|
|
6599
|
+
const cleaned = stripNextStepsBlock(text);
|
|
6600
|
+
if (!cleaned) continue;
|
|
6461
6601
|
const label = labelFor(labelsRef, id);
|
|
6462
|
-
enq({ type: "fleetMessage", id, text:
|
|
6602
|
+
enq({ type: "fleetMessage", id, text: cleaned });
|
|
6463
6603
|
if (streamFleetRef.current) {
|
|
6464
6604
|
enq({
|
|
6465
6605
|
type: "addEntry",
|
|
@@ -6468,7 +6608,7 @@ function useDirectorFleetBridge({
|
|
|
6468
6608
|
agentLabel: label.label,
|
|
6469
6609
|
agentColor: label.color,
|
|
6470
6610
|
icon: "\u{1F4AC}",
|
|
6471
|
-
text:
|
|
6611
|
+
text: cleaned
|
|
6472
6612
|
}
|
|
6473
6613
|
});
|
|
6474
6614
|
}
|
|
@@ -6798,6 +6938,21 @@ function handleCollabDone(event, dispatch, stateRef) {
|
|
|
6798
6938
|
verdict: payload.report.overallVerdict ?? "needs_revision"
|
|
6799
6939
|
});
|
|
6800
6940
|
}
|
|
6941
|
+
function useAutonomousCoordinator(subscribeCoordinatorEvents, dispatch) {
|
|
6942
|
+
const dispatchRef = useRef(dispatch);
|
|
6943
|
+
dispatchRef.current = dispatch;
|
|
6944
|
+
const handler = useCallback((event) => {
|
|
6945
|
+
dispatchRef.current({
|
|
6946
|
+
type: "coordinatorEvent",
|
|
6947
|
+
event
|
|
6948
|
+
});
|
|
6949
|
+
}, []);
|
|
6950
|
+
useEffect(() => {
|
|
6951
|
+
if (!subscribeCoordinatorEvents) return;
|
|
6952
|
+
const unsubscribe = subscribeCoordinatorEvents(handler);
|
|
6953
|
+
return unsubscribe;
|
|
6954
|
+
}, [subscribeCoordinatorEvents, handler]);
|
|
6955
|
+
}
|
|
6801
6956
|
function useStatuslineState(opts) {
|
|
6802
6957
|
const [liveModel, setLiveModel] = useState(opts.model);
|
|
6803
6958
|
const [liveProvider, setLiveProvider] = useState(opts.provider ?? "agent");
|
|
@@ -7549,11 +7704,17 @@ function reducer(state, action) {
|
|
|
7549
7704
|
const banner = state.entries.find((e) => e.kind === "banner");
|
|
7550
7705
|
return {
|
|
7551
7706
|
...state,
|
|
7552
|
-
entries: banner ? [banner] :
|
|
7707
|
+
entries: banner ? [banner] : [],
|
|
7553
7708
|
queue: [],
|
|
7554
7709
|
nextQueueId: 1,
|
|
7555
7710
|
scrollOffset: 0,
|
|
7556
7711
|
pendingNewLines: 0,
|
|
7712
|
+
// Bump the generation so <Static> remounts — without this, Ink's
|
|
7713
|
+
// already-written index exceeds the new (shorter) array and the
|
|
7714
|
+
// committed entries stay on screen even though `state.entries` no
|
|
7715
|
+
// longer references them. /clear would otherwise appear to do
|
|
7716
|
+
// nothing to the visible chat history.
|
|
7717
|
+
historyGen: state.historyGen + 1,
|
|
7557
7718
|
// Reset fleet state on /clear so old subagent entries don't
|
|
7558
7719
|
// cause the LiveActivityStrip to render stale spacers, and
|
|
7559
7720
|
// the fleet cost/tokens chips show zero.
|
|
@@ -7895,6 +8056,7 @@ function reducer(state, action) {
|
|
|
7895
8056
|
featureSkills: action.featureSkills,
|
|
7896
8057
|
featureModelsRegistry: action.featureModelsRegistry,
|
|
7897
8058
|
featureTokenSaving: action.featureTokenSaving,
|
|
8059
|
+
allowOutsideProjectRoot: action.allowOutsideProjectRoot,
|
|
7898
8060
|
contextAutoCompact: action.contextAutoCompact,
|
|
7899
8061
|
contextStrategy: action.contextStrategy,
|
|
7900
8062
|
logLevel: action.logLevel,
|
|
@@ -7929,6 +8091,7 @@ function reducer(state, action) {
|
|
|
7929
8091
|
case "settingsValueChange": {
|
|
7930
8092
|
const sp = state.settingsPicker;
|
|
7931
8093
|
const f = sp.field;
|
|
8094
|
+
const bootHint = "\u21BB Takes effect next session";
|
|
7932
8095
|
if (f === 0) {
|
|
7933
8096
|
const i = SETTINGS_MODES.indexOf(sp.mode);
|
|
7934
8097
|
const base = i < 0 ? 0 : i;
|
|
@@ -7947,59 +8110,60 @@ function reducer(state, action) {
|
|
|
7947
8110
|
if (f === 5) return { ...state, settingsPicker: { ...sp, chime: !sp.chime, hint: void 0 } };
|
|
7948
8111
|
if (f === 6) return { ...state, settingsPicker: { ...sp, confirmExit: !sp.confirmExit, hint: void 0 } };
|
|
7949
8112
|
if (f === 7) return { ...state, settingsPicker: { ...sp, nextPrediction: !sp.nextPrediction, hint: void 0 } };
|
|
7950
|
-
if (f === 8) return { ...state, settingsPicker: { ...sp, featureMcp: !sp.featureMcp, hint:
|
|
7951
|
-
if (f === 9) return { ...state, settingsPicker: { ...sp, featurePlugins: !sp.featurePlugins, hint:
|
|
7952
|
-
if (f === 10) return { ...state, settingsPicker: { ...sp, featureMemory: !sp.featureMemory, hint:
|
|
7953
|
-
if (f === 11) return { ...state, settingsPicker: { ...sp, featureSkills: !sp.featureSkills, hint:
|
|
7954
|
-
if (f === 12) return { ...state, settingsPicker: { ...sp, featureModelsRegistry: !sp.featureModelsRegistry, hint:
|
|
7955
|
-
if (f === 13) return { ...state, settingsPicker: { ...sp, featureTokenSaving: !sp.featureTokenSaving, hint:
|
|
7956
|
-
if (f === 14) return { ...state, settingsPicker: { ...sp,
|
|
7957
|
-
if (f === 15) {
|
|
8113
|
+
if (f === 8) return { ...state, settingsPicker: { ...sp, featureMcp: !sp.featureMcp, hint: bootHint } };
|
|
8114
|
+
if (f === 9) return { ...state, settingsPicker: { ...sp, featurePlugins: !sp.featurePlugins, hint: bootHint } };
|
|
8115
|
+
if (f === 10) return { ...state, settingsPicker: { ...sp, featureMemory: !sp.featureMemory, hint: bootHint } };
|
|
8116
|
+
if (f === 11) return { ...state, settingsPicker: { ...sp, featureSkills: !sp.featureSkills, hint: bootHint } };
|
|
8117
|
+
if (f === 12) return { ...state, settingsPicker: { ...sp, featureModelsRegistry: !sp.featureModelsRegistry, hint: bootHint } };
|
|
8118
|
+
if (f === 13) return { ...state, settingsPicker: { ...sp, featureTokenSaving: !sp.featureTokenSaving, hint: bootHint } };
|
|
8119
|
+
if (f === 14) return { ...state, settingsPicker: { ...sp, allowOutsideProjectRoot: !sp.allowOutsideProjectRoot, hint: void 0 } };
|
|
8120
|
+
if (f === 15) return { ...state, settingsPicker: { ...sp, contextAutoCompact: !sp.contextAutoCompact, hint: void 0 } };
|
|
8121
|
+
if (f === 16) {
|
|
7958
8122
|
const i = COMPACTOR_STRATEGIES.indexOf(sp.contextStrategy);
|
|
7959
8123
|
const base = i < 0 ? 0 : i;
|
|
7960
8124
|
const next = (base + action.delta + COMPACTOR_STRATEGIES.length) % COMPACTOR_STRATEGIES.length;
|
|
7961
|
-
return { ...state, settingsPicker: { ...sp, contextStrategy: expectDefined$1(COMPACTOR_STRATEGIES[next]), hint:
|
|
8125
|
+
return { ...state, settingsPicker: { ...sp, contextStrategy: expectDefined$1(COMPACTOR_STRATEGIES[next]), hint: bootHint } };
|
|
7962
8126
|
}
|
|
7963
|
-
if (f ===
|
|
8127
|
+
if (f === 17) {
|
|
7964
8128
|
const i = LOG_LEVELS.indexOf(sp.logLevel);
|
|
7965
8129
|
const base = i < 0 ? 0 : i;
|
|
7966
8130
|
const next = (base + action.delta + LOG_LEVELS.length) % LOG_LEVELS.length;
|
|
7967
8131
|
return { ...state, settingsPicker: { ...sp, logLevel: expectDefined$1(LOG_LEVELS[next]), hint: void 0 } };
|
|
7968
8132
|
}
|
|
7969
|
-
if (f ===
|
|
8133
|
+
if (f === 18) {
|
|
7970
8134
|
const i = AUDIT_LEVELS.indexOf(sp.auditLevel);
|
|
7971
8135
|
const base = i < 0 ? 0 : i;
|
|
7972
8136
|
const next = (base + action.delta + AUDIT_LEVELS.length) % AUDIT_LEVELS.length;
|
|
7973
8137
|
return { ...state, settingsPicker: { ...sp, auditLevel: expectDefined$1(AUDIT_LEVELS[next]), hint: void 0 } };
|
|
7974
8138
|
}
|
|
7975
|
-
if (f ===
|
|
7976
|
-
if (f ===
|
|
8139
|
+
if (f === 19) return { ...state, settingsPicker: { ...sp, indexOnStart: !sp.indexOnStart, hint: bootHint } };
|
|
8140
|
+
if (f === 20) {
|
|
7977
8141
|
const j = MAX_ITERATIONS_PRESETS.indexOf(sp.maxIterations);
|
|
7978
8142
|
const base = j < 0 ? 0 : j;
|
|
7979
8143
|
const next = (base + action.delta + MAX_ITERATIONS_PRESETS.length) % MAX_ITERATIONS_PRESETS.length;
|
|
7980
8144
|
return { ...state, settingsPicker: { ...sp, maxIterations: expectDefined$1(MAX_ITERATIONS_PRESETS[next]), hint: void 0 } };
|
|
7981
8145
|
}
|
|
7982
|
-
if (f ===
|
|
8146
|
+
if (f === 21) {
|
|
7983
8147
|
const aj = AUTO_PROCEED_MAX_PRESETS.indexOf(sp.autoProceedMaxIterations);
|
|
7984
8148
|
const abase = aj < 0 ? 0 : aj;
|
|
7985
8149
|
const anext = (abase + action.delta + AUTO_PROCEED_MAX_PRESETS.length) % AUTO_PROCEED_MAX_PRESETS.length;
|
|
7986
8150
|
return { ...state, settingsPicker: { ...sp, autoProceedMaxIterations: expectDefined$1(AUTO_PROCEED_MAX_PRESETS[anext]), hint: void 0 } };
|
|
7987
8151
|
}
|
|
7988
|
-
if (f ===
|
|
8152
|
+
if (f === 22) {
|
|
7989
8153
|
const ej = ENHANCE_DELAY_PRESETS.indexOf(sp.enhanceDelayMs);
|
|
7990
8154
|
const ebase = ej < 0 ? 0 : ej;
|
|
7991
8155
|
const enext = (ebase + action.delta + ENHANCE_DELAY_PRESETS.length) % ENHANCE_DELAY_PRESETS.length;
|
|
7992
8156
|
return { ...state, settingsPicker: { ...sp, enhanceDelayMs: expectDefined$1(ENHANCE_DELAY_PRESETS[enext]), hint: void 0 } };
|
|
7993
8157
|
}
|
|
7994
|
-
if (f ===
|
|
7995
|
-
if (f ===
|
|
8158
|
+
if (f === 23) return { ...state, settingsPicker: { ...sp, enhanceEnabled: !sp.enhanceEnabled, hint: void 0 } };
|
|
8159
|
+
if (f === 24) {
|
|
7996
8160
|
const i = ENHANCE_LANGUAGES.indexOf(sp.enhanceLanguage);
|
|
7997
8161
|
const base = i < 0 ? 0 : i;
|
|
7998
8162
|
const next = (base + action.delta + ENHANCE_LANGUAGES.length) % ENHANCE_LANGUAGES.length;
|
|
7999
8163
|
return { ...state, settingsPicker: { ...sp, enhanceLanguage: expectDefined$1(ENHANCE_LANGUAGES[next]), hint: void 0 } };
|
|
8000
8164
|
}
|
|
8001
|
-
if (f ===
|
|
8002
|
-
if (f ===
|
|
8165
|
+
if (f === 25) return { ...state, settingsPicker: { ...sp, debugStream: !sp.debugStream, hint: void 0 } };
|
|
8166
|
+
if (f === 26) {
|
|
8003
8167
|
const i = CONFIG_SCOPES.indexOf(sp.configScope);
|
|
8004
8168
|
const base = i < 0 ? 0 : i;
|
|
8005
8169
|
const next = (base + action.delta + CONFIG_SCOPES.length) % CONFIG_SCOPES.length;
|
|
@@ -8730,9 +8894,10 @@ function reducer(state, action) {
|
|
|
8730
8894
|
return { ...state, sessionsPanelOpen: !state.sessionsPanelOpen };
|
|
8731
8895
|
}
|
|
8732
8896
|
case "sessionsPanelSet": {
|
|
8897
|
+
const sessions = Array.isArray(action.sessions) ? action.sessions : [];
|
|
8733
8898
|
return {
|
|
8734
8899
|
...state,
|
|
8735
|
-
sessionsPanel: { sessions
|
|
8900
|
+
sessionsPanel: { sessions, busy: false, selected: sessions.length > 0 ? 0 : -1 }
|
|
8736
8901
|
};
|
|
8737
8902
|
}
|
|
8738
8903
|
case "sessionsPanelMove": {
|
|
@@ -8767,6 +8932,81 @@ function reducer(state, action) {
|
|
|
8767
8932
|
if (state.countdown === null) return state;
|
|
8768
8933
|
return { ...state, countdown: null };
|
|
8769
8934
|
}
|
|
8935
|
+
// --- AutonomousCoordinator ---
|
|
8936
|
+
case "coordinatorEvent": {
|
|
8937
|
+
const { event } = action;
|
|
8938
|
+
const now = Date.now();
|
|
8939
|
+
let kind;
|
|
8940
|
+
let icon;
|
|
8941
|
+
switch (event.type) {
|
|
8942
|
+
case "goal:added":
|
|
8943
|
+
kind = "goal";
|
|
8944
|
+
icon = "\u{1F3AF}";
|
|
8945
|
+
break;
|
|
8946
|
+
case "goal:completed":
|
|
8947
|
+
kind = "goal";
|
|
8948
|
+
icon = "\u2705";
|
|
8949
|
+
break;
|
|
8950
|
+
case "goal:failed":
|
|
8951
|
+
kind = "goal";
|
|
8952
|
+
icon = "\u274C";
|
|
8953
|
+
break;
|
|
8954
|
+
case "task:ready":
|
|
8955
|
+
kind = "task";
|
|
8956
|
+
icon = "\u26A1";
|
|
8957
|
+
break;
|
|
8958
|
+
case "task:completed":
|
|
8959
|
+
kind = "task";
|
|
8960
|
+
icon = "\u2713";
|
|
8961
|
+
break;
|
|
8962
|
+
case "knowledge:added":
|
|
8963
|
+
kind = "knowledge";
|
|
8964
|
+
icon = "\u{1F4A1}";
|
|
8965
|
+
break;
|
|
8966
|
+
case "consensus:reached":
|
|
8967
|
+
kind = "consensus";
|
|
8968
|
+
icon = "\u{1F91D}";
|
|
8969
|
+
break;
|
|
8970
|
+
case "deadlock:detected":
|
|
8971
|
+
kind = "deadlock";
|
|
8972
|
+
icon = "\u26A0\uFE0F";
|
|
8973
|
+
break;
|
|
8974
|
+
default:
|
|
8975
|
+
kind = "goal";
|
|
8976
|
+
icon = "\u2022";
|
|
8977
|
+
break;
|
|
8978
|
+
}
|
|
8979
|
+
const timelineEntry = {
|
|
8980
|
+
at: now,
|
|
8981
|
+
kind,
|
|
8982
|
+
icon,
|
|
8983
|
+
text: event.text ?? event.type
|
|
8984
|
+
};
|
|
8985
|
+
return {
|
|
8986
|
+
...state,
|
|
8987
|
+
coordinator: {
|
|
8988
|
+
...state.coordinator,
|
|
8989
|
+
healthy: true,
|
|
8990
|
+
knowledgeCount: event.type === "knowledge:added" ? state.coordinator.knowledgeCount + 1 : state.coordinator.knowledgeCount,
|
|
8991
|
+
timeline: [timelineEntry, ...state.coordinator.timeline].slice(0, 50)
|
|
8992
|
+
}
|
|
8993
|
+
};
|
|
8994
|
+
}
|
|
8995
|
+
case "toggleCoordinatorMonitor": {
|
|
8996
|
+
const opening = !state.coordinator.monitorOpen;
|
|
8997
|
+
return opening ? {
|
|
8998
|
+
...state,
|
|
8999
|
+
coordinator: { ...state.coordinator, monitorOpen: true },
|
|
9000
|
+
// Close other monitors when opening coordinator
|
|
9001
|
+
monitorOpen: false,
|
|
9002
|
+
agentsMonitorOpen: false,
|
|
9003
|
+
helpOpen: false,
|
|
9004
|
+
todosMonitorOpen: false,
|
|
9005
|
+
queuePanelOpen: false,
|
|
9006
|
+
processListOpen: false,
|
|
9007
|
+
goalPanelOpen: false
|
|
9008
|
+
} : { ...state, coordinator: { ...state.coordinator, monitorOpen: false } };
|
|
9009
|
+
}
|
|
8770
9010
|
}
|
|
8771
9011
|
}
|
|
8772
9012
|
var INPUT_PROMPT = "\u203A ";
|
|
@@ -8821,6 +9061,7 @@ function App({
|
|
|
8821
9061
|
yolo = false,
|
|
8822
9062
|
chime = false,
|
|
8823
9063
|
confirmExit = true,
|
|
9064
|
+
titleController,
|
|
8824
9065
|
mouse = false,
|
|
8825
9066
|
enhanceEnabled = true,
|
|
8826
9067
|
enhanceController,
|
|
@@ -8876,7 +9117,8 @@ function App({
|
|
|
8876
9117
|
requestExit,
|
|
8877
9118
|
getLiveSessions,
|
|
8878
9119
|
onSwitchToSession,
|
|
8879
|
-
initialAgentsMonitorOpen
|
|
9120
|
+
initialAgentsMonitorOpen,
|
|
9121
|
+
subscribeCoordinatorEvents
|
|
8880
9122
|
}) {
|
|
8881
9123
|
const { exit } = useApp();
|
|
8882
9124
|
const { stdout } = useStdout();
|
|
@@ -9009,7 +9251,7 @@ function App({
|
|
|
9009
9251
|
},
|
|
9010
9252
|
autonomyPicker: { open: false, options: [], selected: 0 },
|
|
9011
9253
|
resumePicker: { open: false, sessions: [], selected: 0, busy: false, hint: void 0, error: void 0 },
|
|
9012
|
-
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, featureTokenSaving: false, contextAutoCompact: true, contextStrategy: "hybrid", logLevel: "info", auditLevel: "standard", indexOnStart: true, maxIterations: 500, autoProceedMaxIterations: 50, enhanceDelayMs: 6e4, enhanceEnabled: true, enhanceLanguage: "original", debugStream: false, configScope: "global" },
|
|
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, featureTokenSaving: false, 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" },
|
|
9013
9255
|
projectPicker: { open: false, allItems: [], items: [], selected: 0, filter: "", hint: void 0 },
|
|
9014
9256
|
confirmQueue: [],
|
|
9015
9257
|
enhance: null,
|
|
@@ -9049,6 +9291,13 @@ function App({
|
|
|
9049
9291
|
autoPhase: null,
|
|
9050
9292
|
worktrees: {},
|
|
9051
9293
|
worktreeMonitorOpen: false,
|
|
9294
|
+
coordinator: {
|
|
9295
|
+
goals: [],
|
|
9296
|
+
timeline: [],
|
|
9297
|
+
knowledgeCount: 0,
|
|
9298
|
+
monitorOpen: false,
|
|
9299
|
+
healthy: false
|
|
9300
|
+
},
|
|
9052
9301
|
scrollOffset: 0,
|
|
9053
9302
|
totalLines: 0,
|
|
9054
9303
|
viewportRows: 0,
|
|
@@ -9056,6 +9305,7 @@ function App({
|
|
|
9056
9305
|
debugStreamStats: null,
|
|
9057
9306
|
countdown: null
|
|
9058
9307
|
});
|
|
9308
|
+
useAutonomousCoordinator(subscribeCoordinatorEvents, dispatch);
|
|
9059
9309
|
const builderRef = useRef(null);
|
|
9060
9310
|
if (builderRef.current === null) {
|
|
9061
9311
|
builderRef.current = new InputBuilder({ store: attachments });
|
|
@@ -9085,10 +9335,16 @@ function App({
|
|
|
9085
9335
|
setWorkingDirChip(rel === "." ? void 0 : rel);
|
|
9086
9336
|
});
|
|
9087
9337
|
}, [agent.ctx, projectRoot]);
|
|
9338
|
+
const liveSettings = getSettings?.();
|
|
9088
9339
|
const chimeRef = useRef(chime);
|
|
9089
|
-
chimeRef.current = chime;
|
|
9340
|
+
chimeRef.current = liveSettings?.chime ?? chime;
|
|
9090
9341
|
const confirmExitRef = useRef(confirmExit);
|
|
9091
|
-
confirmExitRef.current = confirmExit;
|
|
9342
|
+
confirmExitRef.current = liveSettings?.confirmExit ?? confirmExit;
|
|
9343
|
+
const liveTitleAnimation = liveSettings?.titleAnimation;
|
|
9344
|
+
useEffect(() => {
|
|
9345
|
+
if (!titleController) return;
|
|
9346
|
+
titleController.setEnabled(liveTitleAnimation !== false);
|
|
9347
|
+
}, [titleController, liveTitleAnimation]);
|
|
9092
9348
|
const streamingTextRef = useRef("");
|
|
9093
9349
|
const pendingDeltaRef = useRef("");
|
|
9094
9350
|
const flushTimerRef = useRef(null);
|
|
@@ -9556,7 +9812,7 @@ function App({
|
|
|
9556
9812
|
}
|
|
9557
9813
|
}, []);
|
|
9558
9814
|
React5.useLayoutEffect(() => {
|
|
9559
|
-
const anyOpenNow = state.picker.open || state.slashPicker.open || state.modelPicker.open || state.autonomyPicker.open || state.resumePicker.open || state.settingsPicker.open || state.enhanceBusy || state.enhance != null || state.escConfirm != null || state.confirmQueue.length > 0;
|
|
9815
|
+
const anyOpenNow = state.picker.open || state.slashPicker.open || state.modelPicker.open || state.autonomyPicker.open || state.resumePicker.open || state.settingsPicker.open || state.enhanceBusy || state.enhance != null || state.coordinator.monitorOpen || state.escConfirm != null || state.confirmQueue.length > 0;
|
|
9560
9816
|
const overlayClosed = prevAnyOverlayOpen.current && !anyOpenNow;
|
|
9561
9817
|
const newEntryCommitted = state.entries.length > prevEntriesCount.current;
|
|
9562
9818
|
const curToolStreamLen = state.toolStream?.text.length ?? 0;
|
|
@@ -9575,6 +9831,7 @@ function App({
|
|
|
9575
9831
|
state.settingsPicker.open,
|
|
9576
9832
|
state.enhanceBusy,
|
|
9577
9833
|
state.enhance,
|
|
9834
|
+
state.coordinator.monitorOpen,
|
|
9578
9835
|
state.escConfirm,
|
|
9579
9836
|
state.confirmQueue.length,
|
|
9580
9837
|
state.entries.length,
|
|
@@ -9599,7 +9856,8 @@ function App({
|
|
|
9599
9856
|
queue: stateRef.current.queuePanelOpen,
|
|
9600
9857
|
processList: stateRef.current.processListOpen,
|
|
9601
9858
|
goalPanel: stateRef.current.goalPanelOpen,
|
|
9602
|
-
sessionsPanel: stateRef.current.sessionsPanelOpen
|
|
9859
|
+
sessionsPanel: stateRef.current.sessionsPanelOpen,
|
|
9860
|
+
coordinator: stateRef.current.coordinator.monitorOpen
|
|
9603
9861
|
};
|
|
9604
9862
|
if (stateRef.current.settingsPicker.open) dispatch({ type: "settingsClose" });
|
|
9605
9863
|
if (stateRef.current.projectPicker.open) dispatch({ type: "projectPickerClose" });
|
|
@@ -9642,6 +9900,7 @@ function App({
|
|
|
9642
9900
|
featureSkills: sp.featureSkills,
|
|
9643
9901
|
featureModelsRegistry: sp.featureModelsRegistry,
|
|
9644
9902
|
featureTokenSaving: sp.featureTokenSaving,
|
|
9903
|
+
allowOutsideProjectRoot: sp.allowOutsideProjectRoot,
|
|
9645
9904
|
contextAutoCompact: sp.contextAutoCompact,
|
|
9646
9905
|
contextStrategy: sp.contextStrategy,
|
|
9647
9906
|
logLevel: sp.logLevel,
|
|
@@ -9669,6 +9928,7 @@ function App({
|
|
|
9669
9928
|
if (prev.processList) dispatch({ type: "toggleProcessList" });
|
|
9670
9929
|
if (prev.goalPanel) dispatch({ type: "toggleGoalPanel" });
|
|
9671
9930
|
if (prev.sessionsPanel) dispatch({ type: "toggleSessionsPanel" });
|
|
9931
|
+
if (prev.coordinator) dispatch({ type: "toggleCoordinatorMonitor" });
|
|
9672
9932
|
preResizePanelsRef.current = null;
|
|
9673
9933
|
resizeRestoreTimerRef.current = null;
|
|
9674
9934
|
}, 300);
|
|
@@ -9762,7 +10022,28 @@ function App({
|
|
|
9762
10022
|
type: "addEntry",
|
|
9763
10023
|
entry: {
|
|
9764
10024
|
kind: "error",
|
|
9765
|
-
text: `Clipboard image error: ${
|
|
10025
|
+
text: `Clipboard image error: ${toErrorMessage(err)}`
|
|
10026
|
+
}
|
|
10027
|
+
});
|
|
10028
|
+
}
|
|
10029
|
+
};
|
|
10030
|
+
const pasteClipboardText = async () => {
|
|
10031
|
+
try {
|
|
10032
|
+
const text = await readClipboardText();
|
|
10033
|
+
if (!text) {
|
|
10034
|
+
dispatch({
|
|
10035
|
+
type: "addEntry",
|
|
10036
|
+
entry: { kind: "info", text: "No text on the clipboard." }
|
|
10037
|
+
});
|
|
10038
|
+
return;
|
|
10039
|
+
}
|
|
10040
|
+
await commitPaste(text);
|
|
10041
|
+
} catch (err) {
|
|
10042
|
+
dispatch({
|
|
10043
|
+
type: "addEntry",
|
|
10044
|
+
entry: {
|
|
10045
|
+
kind: "error",
|
|
10046
|
+
text: `Clipboard error: ${toErrorMessage(err)}`
|
|
9766
10047
|
}
|
|
9767
10048
|
});
|
|
9768
10049
|
}
|
|
@@ -9799,7 +10080,7 @@ function App({
|
|
|
9799
10080
|
type: "addEntry",
|
|
9800
10081
|
entry: {
|
|
9801
10082
|
kind: "error",
|
|
9802
|
-
text: `Attach failed: ${
|
|
10083
|
+
text: `Attach failed: ${toErrorMessage(err)}`
|
|
9803
10084
|
}
|
|
9804
10085
|
});
|
|
9805
10086
|
dispatch({ type: "pickerClose" });
|
|
@@ -9985,7 +10266,10 @@ function App({
|
|
|
9985
10266
|
dispatch({ type: "projectPickerOpen", items });
|
|
9986
10267
|
}, [getProjectPickerItems]);
|
|
9987
10268
|
const loadLiveSessions = React5.useCallback(async () => {
|
|
9988
|
-
if (!getLiveSessions)
|
|
10269
|
+
if (!getLiveSessions) {
|
|
10270
|
+
dispatch({ type: "sessionsPanelSet", sessions: [] });
|
|
10271
|
+
return;
|
|
10272
|
+
}
|
|
9989
10273
|
dispatch({ type: "sessionsPanelBusy", on: true });
|
|
9990
10274
|
try {
|
|
9991
10275
|
const sessions = await getLiveSessions();
|
|
@@ -10020,6 +10304,7 @@ function App({
|
|
|
10020
10304
|
featureSkills: s2.featureSkills ?? true,
|
|
10021
10305
|
featureModelsRegistry: s2.featureModelsRegistry ?? true,
|
|
10022
10306
|
featureTokenSaving: s2.featureTokenSaving ?? false,
|
|
10307
|
+
allowOutsideProjectRoot: s2.allowOutsideProjectRoot ?? true,
|
|
10023
10308
|
contextAutoCompact: s2.contextAutoCompact ?? true,
|
|
10024
10309
|
contextStrategy: s2.contextStrategy ?? "hybrid",
|
|
10025
10310
|
logLevel: s2.logLevel ?? "info",
|
|
@@ -10100,7 +10385,6 @@ function App({
|
|
|
10100
10385
|
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
10101
10386
|
if (suggestion) {
|
|
10102
10387
|
autoSubmitStreakRef.current += 1;
|
|
10103
|
-
setDraft(suggestion, suggestion.length);
|
|
10104
10388
|
void (async () => {
|
|
10105
10389
|
const trimmed = suggestion.trim();
|
|
10106
10390
|
if (!trimmed) {
|
|
@@ -10156,6 +10440,7 @@ function App({
|
|
|
10156
10440
|
featureSkills: sp.featureSkills,
|
|
10157
10441
|
featureModelsRegistry: sp.featureModelsRegistry,
|
|
10158
10442
|
featureTokenSaving: sp.featureTokenSaving,
|
|
10443
|
+
allowOutsideProjectRoot: sp.allowOutsideProjectRoot,
|
|
10159
10444
|
contextAutoCompact: sp.contextAutoCompact,
|
|
10160
10445
|
contextStrategy: sp.contextStrategy,
|
|
10161
10446
|
logLevel: sp.logLevel,
|
|
@@ -10186,6 +10471,8 @@ function App({
|
|
|
10186
10471
|
state.settingsPicker.featureMemory,
|
|
10187
10472
|
state.settingsPicker.featureSkills,
|
|
10188
10473
|
state.settingsPicker.featureModelsRegistry,
|
|
10474
|
+
state.settingsPicker.featureTokenSaving,
|
|
10475
|
+
state.settingsPicker.allowOutsideProjectRoot,
|
|
10189
10476
|
state.settingsPicker.contextAutoCompact,
|
|
10190
10477
|
state.settingsPicker.contextStrategy,
|
|
10191
10478
|
state.settingsPicker.logLevel,
|
|
@@ -10194,6 +10481,9 @@ function App({
|
|
|
10194
10481
|
state.settingsPicker.maxIterations,
|
|
10195
10482
|
state.settingsPicker.autoProceedMaxIterations,
|
|
10196
10483
|
state.settingsPicker.enhanceDelayMs,
|
|
10484
|
+
state.settingsPicker.enhanceEnabled,
|
|
10485
|
+
state.settingsPicker.enhanceLanguage,
|
|
10486
|
+
state.settingsPicker.debugStream,
|
|
10197
10487
|
saveSettings
|
|
10198
10488
|
]);
|
|
10199
10489
|
useEffect(() => {
|
|
@@ -10276,7 +10566,7 @@ function App({
|
|
|
10276
10566
|
dispatch({ type: "resumePickerOpen", sessions });
|
|
10277
10567
|
} catch (err) {
|
|
10278
10568
|
return {
|
|
10279
|
-
message:
|
|
10569
|
+
message: toErrorMessage(err)
|
|
10280
10570
|
};
|
|
10281
10571
|
}
|
|
10282
10572
|
return { message: void 0 };
|
|
@@ -10879,7 +11169,7 @@ function App({
|
|
|
10879
11169
|
}).catch((err) => {
|
|
10880
11170
|
dispatch({
|
|
10881
11171
|
type: "resumePickerError",
|
|
10882
|
-
text:
|
|
11172
|
+
text: toErrorMessage(err)
|
|
10883
11173
|
});
|
|
10884
11174
|
});
|
|
10885
11175
|
return;
|
|
@@ -11328,7 +11618,7 @@ function App({
|
|
|
11328
11618
|
}
|
|
11329
11619
|
return;
|
|
11330
11620
|
}
|
|
11331
|
-
if (key.fn === 10) {
|
|
11621
|
+
if (key.fn === 10 || key.escape && state.sessionsPanelOpen) {
|
|
11332
11622
|
if (state.sessionsPanelOpen) {
|
|
11333
11623
|
dispatch({ type: "toggleSessionsPanel" });
|
|
11334
11624
|
} else {
|
|
@@ -11347,6 +11637,10 @@ function App({
|
|
|
11347
11637
|
}
|
|
11348
11638
|
return;
|
|
11349
11639
|
}
|
|
11640
|
+
if (key.fn === 11 || input === "\x1B" && state.coordinator.monitorOpen) {
|
|
11641
|
+
dispatch({ type: "toggleCoordinatorMonitor" });
|
|
11642
|
+
return;
|
|
11643
|
+
}
|
|
11350
11644
|
if (key.ctrl && input === "s") {
|
|
11351
11645
|
if (state.settingsPicker.open) {
|
|
11352
11646
|
dispatch({ type: "settingsClose" });
|
|
@@ -11375,6 +11669,7 @@ function App({
|
|
|
11375
11669
|
featureSkills: cfg.featureSkills ?? true,
|
|
11376
11670
|
featureModelsRegistry: cfg.featureModelsRegistry ?? true,
|
|
11377
11671
|
featureTokenSaving: cfg.featureTokenSaving ?? false,
|
|
11672
|
+
allowOutsideProjectRoot: cfg.allowOutsideProjectRoot ?? true,
|
|
11378
11673
|
contextAutoCompact: cfg.contextAutoCompact ?? true,
|
|
11379
11674
|
contextStrategy: cfg.contextStrategy ?? "hybrid",
|
|
11380
11675
|
logLevel: cfg.logLevel ?? "info",
|
|
@@ -11424,10 +11719,18 @@ function App({
|
|
|
11424
11719
|
dispatch({ type: "toggleGoalPanel" });
|
|
11425
11720
|
return;
|
|
11426
11721
|
}
|
|
11722
|
+
if (state.helpOpen) {
|
|
11723
|
+
dispatch({ type: "toggleHelp" });
|
|
11724
|
+
return;
|
|
11725
|
+
}
|
|
11427
11726
|
if (state.sessionsPanelOpen) {
|
|
11428
11727
|
dispatch({ type: "toggleSessionsPanel" });
|
|
11429
11728
|
return;
|
|
11430
11729
|
}
|
|
11730
|
+
if (state.coordinator.monitorOpen) {
|
|
11731
|
+
dispatch({ type: "toggleCoordinatorMonitor" });
|
|
11732
|
+
return;
|
|
11733
|
+
}
|
|
11431
11734
|
}
|
|
11432
11735
|
if (state.processListOpen) {
|
|
11433
11736
|
return;
|
|
@@ -11450,6 +11753,17 @@ function App({
|
|
|
11450
11753
|
return;
|
|
11451
11754
|
}
|
|
11452
11755
|
const { buffer, cursor } = draftRef.current;
|
|
11756
|
+
if (key.tab && nextStepsAutoSubmitTimerRef.current != null) {
|
|
11757
|
+
const pending = nextStepsAutoSubmitSuggestionRef.current ?? nextStepsAutoSubmitLabel ?? "";
|
|
11758
|
+
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
11759
|
+
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
11760
|
+
setNextStepsAutoSubmitCountdown(null);
|
|
11761
|
+
setNextStepsAutoSubmitLabel(null);
|
|
11762
|
+
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
11763
|
+
const text = pending.trim();
|
|
11764
|
+
if (text) setDraft(text, text.length);
|
|
11765
|
+
return;
|
|
11766
|
+
}
|
|
11453
11767
|
if (key.backspace) {
|
|
11454
11768
|
if (key.ctrl) {
|
|
11455
11769
|
if (cursor === 0) return;
|
|
@@ -11537,7 +11851,7 @@ function App({
|
|
|
11537
11851
|
setDraft(buffer, buffer.length);
|
|
11538
11852
|
return;
|
|
11539
11853
|
}
|
|
11540
|
-
const overlayOpen = state.monitorOpen || state.agentsMonitorOpen || state.worktreeMonitorOpen || state.todosMonitorOpen || state.queuePanelOpen || state.processListOpen || state.goalPanelOpen || state.sessionsPanelOpen || state.helpOpen || (state.autoPhase?.monitorOpen ?? false) || state.rewindOverlay !== null;
|
|
11854
|
+
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;
|
|
11541
11855
|
if (mouseMode && !overlayOpen) {
|
|
11542
11856
|
if (key.mouse?.kind === "wheel") {
|
|
11543
11857
|
if (key.mouse.shift) dispatch({ type: "scrollPage", dir: key.mouse.wheel > 0 ? "up" : "down" });
|
|
@@ -11666,6 +11980,10 @@ function App({
|
|
|
11666
11980
|
setDraft(next2, cursor);
|
|
11667
11981
|
return;
|
|
11668
11982
|
}
|
|
11983
|
+
if (key.ctrl && input === "v") {
|
|
11984
|
+
await pasteClipboardText();
|
|
11985
|
+
return;
|
|
11986
|
+
}
|
|
11669
11987
|
if (key.meta && input === "v") {
|
|
11670
11988
|
await pasteClipboardImage();
|
|
11671
11989
|
return;
|
|
@@ -11789,7 +12107,7 @@ function App({
|
|
|
11789
12107
|
} catch (err) {
|
|
11790
12108
|
dispatch({
|
|
11791
12109
|
type: "addEntry",
|
|
11792
|
-
entry: { kind: "error", text:
|
|
12110
|
+
entry: { kind: "error", text: toErrorMessage(err) }
|
|
11793
12111
|
});
|
|
11794
12112
|
} finally {
|
|
11795
12113
|
activeCtrlRef.current = null;
|
|
@@ -11831,7 +12149,7 @@ function App({
|
|
|
11831
12149
|
type: "addEntry",
|
|
11832
12150
|
entry: {
|
|
11833
12151
|
kind: "error",
|
|
11834
|
-
text: `[eternal] ${
|
|
12152
|
+
text: `[eternal] ${toErrorMessage(err)}`
|
|
11835
12153
|
}
|
|
11836
12154
|
});
|
|
11837
12155
|
}
|
|
@@ -11867,7 +12185,7 @@ function App({
|
|
|
11867
12185
|
type: "addEntry",
|
|
11868
12186
|
entry: {
|
|
11869
12187
|
kind: "error",
|
|
11870
|
-
text: `[parallel] ${
|
|
12188
|
+
text: `[parallel] ${toErrorMessage(err)}`
|
|
11871
12189
|
}
|
|
11872
12190
|
});
|
|
11873
12191
|
}
|
|
@@ -12014,7 +12332,6 @@ ${content}
|
|
|
12014
12332
|
while (stateRef.current.status !== "idle" && Date.now() - start < 1500) {
|
|
12015
12333
|
await new Promise((r) => setTimeout(r, 25));
|
|
12016
12334
|
}
|
|
12017
|
-
setDraft(res.runText, res.runText.length);
|
|
12018
12335
|
try {
|
|
12019
12336
|
await runBlocks(blocks2);
|
|
12020
12337
|
} finally {
|
|
@@ -12030,7 +12347,7 @@ ${content}
|
|
|
12030
12347
|
} catch (err) {
|
|
12031
12348
|
dispatch({
|
|
12032
12349
|
type: "addEntry",
|
|
12033
|
-
entry: { kind: "error", text:
|
|
12350
|
+
entry: { kind: "error", text: toErrorMessage(err) }
|
|
12034
12351
|
});
|
|
12035
12352
|
}
|
|
12036
12353
|
return;
|
|
@@ -12215,7 +12532,9 @@ User message:
|
|
|
12215
12532
|
viewportRows: state.viewportRows,
|
|
12216
12533
|
totalLines: state.totalLines,
|
|
12217
12534
|
onMeasure: (totalLines) => dispatch({ type: "setMeasuredLines", totalLines }),
|
|
12218
|
-
setSuggestions
|
|
12535
|
+
setSuggestions,
|
|
12536
|
+
autonomyMode: autonomyLive,
|
|
12537
|
+
autoSubmitCountdown: nextStepsAutoSubmitCountdown
|
|
12219
12538
|
}
|
|
12220
12539
|
) : /* @__PURE__ */ jsx(
|
|
12221
12540
|
History,
|
|
@@ -12224,7 +12543,9 @@ User message:
|
|
|
12224
12543
|
generation: state.historyGen,
|
|
12225
12544
|
streamingText: state.streamingText,
|
|
12226
12545
|
toolStream: state.toolStream,
|
|
12227
|
-
setSuggestions
|
|
12546
|
+
setSuggestions,
|
|
12547
|
+
autonomyMode: autonomyLive,
|
|
12548
|
+
autoSubmitCountdown: nextStepsAutoSubmitCountdown
|
|
12228
12549
|
}
|
|
12229
12550
|
),
|
|
12230
12551
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexShrink: 0, ref: bottomRegionRef, children: [
|
|
@@ -12306,6 +12627,7 @@ User message:
|
|
|
12306
12627
|
featureSkills: state.settingsPicker.featureSkills,
|
|
12307
12628
|
featureModelsRegistry: state.settingsPicker.featureModelsRegistry,
|
|
12308
12629
|
featureTokenSaving: state.settingsPicker.featureTokenSaving,
|
|
12630
|
+
allowOutsideProjectRoot: state.settingsPicker.allowOutsideProjectRoot,
|
|
12309
12631
|
contextAutoCompact: state.settingsPicker.contextAutoCompact,
|
|
12310
12632
|
contextStrategy: state.settingsPicker.contextStrategy,
|
|
12311
12633
|
logLevel: state.settingsPicker.logLevel,
|
|
@@ -12340,6 +12662,14 @@ User message:
|
|
|
12340
12662
|
currentSessionId: agent.ctx.session?.id
|
|
12341
12663
|
}
|
|
12342
12664
|
) : null,
|
|
12665
|
+
state.coordinator.monitorOpen ? /* @__PURE__ */ jsx(
|
|
12666
|
+
CoordinatorPanel,
|
|
12667
|
+
{
|
|
12668
|
+
coordinator: state.coordinator,
|
|
12669
|
+
nowTick,
|
|
12670
|
+
onClose: () => dispatch({ type: "toggleCoordinatorMonitor" })
|
|
12671
|
+
}
|
|
12672
|
+
) : null,
|
|
12343
12673
|
state.rewindOverlay ? (() => {
|
|
12344
12674
|
const overlay = state.rewindOverlay;
|
|
12345
12675
|
return /* @__PURE__ */ jsx(
|
|
@@ -12470,6 +12800,7 @@ User message:
|
|
|
12470
12800
|
fleet: fleetCounts,
|
|
12471
12801
|
git: gitInfo,
|
|
12472
12802
|
context: contextWindow,
|
|
12803
|
+
contextStrategy: getSettings ? getSettings().contextStrategy : void 0,
|
|
12473
12804
|
brain: state.brain,
|
|
12474
12805
|
projectName,
|
|
12475
12806
|
workingDir: workingDirChip,
|
|
@@ -12518,8 +12849,7 @@ User message:
|
|
|
12518
12849
|
phases: state.autoPhase.phases,
|
|
12519
12850
|
runningPhaseIds: state.autoPhase.runningPhaseIds,
|
|
12520
12851
|
elapsedMs: state.autoPhase.elapsedMs,
|
|
12521
|
-
nowTick
|
|
12522
|
-
onClose: () => dispatch({ type: "autoPhaseMonitorToggle" })
|
|
12852
|
+
nowTick
|
|
12523
12853
|
}
|
|
12524
12854
|
) : state.worktreeMonitorOpen ? /* @__PURE__ */ jsx(
|
|
12525
12855
|
WorktreeMonitor,
|
|
@@ -12735,13 +13065,30 @@ async function runTui(opts) {
|
|
|
12735
13065
|
const mouseEnabled = opts.mouse ?? opts.getSettings?.().mouseMode ?? process.env.WRONGSTACK_MOUSE === "1";
|
|
12736
13066
|
stdout.write("\x1B[2J\x1B[H");
|
|
12737
13067
|
const inkStdin = stdin;
|
|
12738
|
-
|
|
12739
|
-
|
|
12740
|
-
|
|
12741
|
-
|
|
12742
|
-
|
|
12743
|
-
|
|
12744
|
-
|
|
13068
|
+
let titleStop = null;
|
|
13069
|
+
const startTitle = () => {
|
|
13070
|
+
if (titleStop) return;
|
|
13071
|
+
titleStop = startTerminalTitle({
|
|
13072
|
+
stdout,
|
|
13073
|
+
events: opts.events,
|
|
13074
|
+
model: opts.model,
|
|
13075
|
+
appName: opts.projectRoot ? path4.basename(opts.projectRoot) : void 0
|
|
13076
|
+
});
|
|
13077
|
+
};
|
|
13078
|
+
const stopTitle = () => {
|
|
13079
|
+
try {
|
|
13080
|
+
titleStop?.();
|
|
13081
|
+
} catch {
|
|
13082
|
+
}
|
|
13083
|
+
titleStop = null;
|
|
13084
|
+
};
|
|
13085
|
+
const titleController = {
|
|
13086
|
+
setEnabled(on) {
|
|
13087
|
+
if (on) startTitle();
|
|
13088
|
+
else stopTitle();
|
|
13089
|
+
}
|
|
13090
|
+
};
|
|
13091
|
+
if (opts.titleAnimation !== false) startTitle();
|
|
12745
13092
|
const swallowSignals = ["SIGTSTP", "SIGQUIT", "SIGTTIN", "SIGTTOU"];
|
|
12746
13093
|
const swallow = () => {
|
|
12747
13094
|
};
|
|
@@ -12920,6 +13267,7 @@ async function runTui(opts) {
|
|
|
12920
13267
|
setSuggestions: opts.setSuggestions,
|
|
12921
13268
|
chime: opts.chime,
|
|
12922
13269
|
confirmExit: opts.confirmExit,
|
|
13270
|
+
titleController,
|
|
12923
13271
|
mouse: mouseEnabled,
|
|
12924
13272
|
modeLabel: opts.modeLabel,
|
|
12925
13273
|
tokenSavingMode: opts.tokenSavingMode,
|
|
@@ -12936,7 +13284,8 @@ async function runTui(opts) {
|
|
|
12936
13284
|
requestExit: opts.requestExit,
|
|
12937
13285
|
getLiveSessions: opts.getLiveSessions,
|
|
12938
13286
|
onSwitchToSession: opts.onSwitchToSession,
|
|
12939
|
-
initialAgentsMonitorOpen: opts.initialAgentsMonitorOpen
|
|
13287
|
+
initialAgentsMonitorOpen: opts.initialAgentsMonitorOpen,
|
|
13288
|
+
subscribeCoordinatorEvents: opts.subscribeCoordinatorEvents
|
|
12940
13289
|
}),
|
|
12941
13290
|
{ exitOnCtrlC: false, stdin: inkStdin }
|
|
12942
13291
|
);
|