@wrongstack/tui 0.32.0 → 0.51.3
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 +51 -26
- package/dist/index.js +399 -44
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Readable } from 'stream';
|
|
2
|
+
import { writeErr, InputBuilder, DefaultSessionRewinder, writeOut, formatTodosList, buildGoalPreamble, buildChildEnv } from '@wrongstack/core';
|
|
3
|
+
export { buildGoalPreamble } from '@wrongstack/core';
|
|
2
4
|
import { Box, Text, render, useApp, useStdout, measureElement, Static, useInput, useStdin } from 'ink';
|
|
3
5
|
import React4, { useState, useEffect, useReducer, useRef, useMemo, useCallback, useLayoutEffect } from 'react';
|
|
4
6
|
import * as fs2 from 'fs/promises';
|
|
5
7
|
import * as path2 from 'path';
|
|
6
|
-
import { InputBuilder, DefaultSessionRewinder, formatTodosList, buildGoalPreamble, buildChildEnv } from '@wrongstack/core';
|
|
7
|
-
export { buildGoalPreamble } from '@wrongstack/core';
|
|
8
8
|
import { routeImagesForModel } from '@wrongstack/runtime/vision';
|
|
9
9
|
import { getProcessRegistry } from '@wrongstack/tools';
|
|
10
10
|
import { readClipboardImage } from '@wrongstack/runtime/clipboard';
|
|
@@ -54,6 +54,7 @@ function StatusBar({
|
|
|
54
54
|
git,
|
|
55
55
|
subagentCount = 0,
|
|
56
56
|
context,
|
|
57
|
+
brain,
|
|
57
58
|
projectName,
|
|
58
59
|
processCount,
|
|
59
60
|
hiddenItems,
|
|
@@ -79,7 +80,8 @@ function StatusBar({
|
|
|
79
80
|
const { label: stateLabel, color: stateColor } = stateChip(state, fleet?.running ?? 0);
|
|
80
81
|
const hasSecondLine = yolo || autonomy && autonomy !== "off" || elapsedMs !== void 0 || git !== null && git !== void 0 || projectName !== void 0 && projectName.length > 0 || goalSummary !== null && goalSummary !== void 0;
|
|
81
82
|
const fleetHasActivity = fleet && (fleet.running > 0 || fleet.idle > 0 || fleet.pending > 0 || fleet.completed > 0) || subagentCount > 0;
|
|
82
|
-
const
|
|
83
|
+
const hasBrainActivity = !!brain && brain.state !== "idle";
|
|
84
|
+
const hasThirdLine = todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || fleetHasActivity || hasBrainActivity;
|
|
83
85
|
return /* @__PURE__ */ jsxs(
|
|
84
86
|
Box,
|
|
85
87
|
{
|
|
@@ -316,6 +318,10 @@ function StatusBar({
|
|
|
316
318
|
" agent",
|
|
317
319
|
subagentCount === 1 ? "" : "s"
|
|
318
320
|
] })
|
|
321
|
+
] }) : null,
|
|
322
|
+
hasBrainActivity && brain ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
323
|
+
todos && (todos.pending > 0 || todos.inProgress > 0 || todos.completed > 0) || plan && (plan.open > 0 || plan.inProgress > 0 || plan.done > 0) || fleetHasActivity ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
324
|
+
/* @__PURE__ */ jsx(BrainChip, { brain })
|
|
319
325
|
] }) : null
|
|
320
326
|
] }) : null,
|
|
321
327
|
fleetAgents && fleetAgents.length > 0 ? /* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 2, children: fleetAgents.map((a, i) => (
|
|
@@ -348,6 +354,18 @@ function StatusBar({
|
|
|
348
354
|
}
|
|
349
355
|
);
|
|
350
356
|
}
|
|
357
|
+
function BrainChip({ brain }) {
|
|
358
|
+
const color = brain.state === "denied" ? "red" : brain.state === "ask_human" ? "yellow" : brain.state === "deciding" ? "magenta" : "cyan";
|
|
359
|
+
const label = brain.state === "deciding" ? "deciding" : brain.state === "ask_human" ? "human" : brain.state;
|
|
360
|
+
const scope = brain.source ? ` ${brain.source}` : "";
|
|
361
|
+
const summary = brain.summary ? ` \xB7 ${brain.summary.slice(0, 40)}` : "";
|
|
362
|
+
return /* @__PURE__ */ jsxs(Text, { color, children: [
|
|
363
|
+
"\u{1F9E0} ",
|
|
364
|
+
label,
|
|
365
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: scope }),
|
|
366
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: summary })
|
|
367
|
+
] });
|
|
368
|
+
}
|
|
351
369
|
function EternalStageChip({
|
|
352
370
|
stage
|
|
353
371
|
}) {
|
|
@@ -376,6 +394,25 @@ function EternalStageChip({
|
|
|
376
394
|
]
|
|
377
395
|
}
|
|
378
396
|
);
|
|
397
|
+
case "decompose":
|
|
398
|
+
return /* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u2B07 decompose" });
|
|
399
|
+
case "fanout":
|
|
400
|
+
return /* @__PURE__ */ jsxs(Text, { color: "magenta", children: [
|
|
401
|
+
"\u21C4 fanout: ",
|
|
402
|
+
stage.slots
|
|
403
|
+
] });
|
|
404
|
+
case "await":
|
|
405
|
+
return /* @__PURE__ */ jsxs(Text, { color: "magenta", children: [
|
|
406
|
+
"\u23F3 await: ",
|
|
407
|
+
stage.taskIds.length
|
|
408
|
+
] });
|
|
409
|
+
case "aggregate":
|
|
410
|
+
return /* @__PURE__ */ jsxs(Text, { color: stage.goalComplete ? "green" : "magenta", children: [
|
|
411
|
+
"\u21A9 aggregate: ",
|
|
412
|
+
stage.successCount,
|
|
413
|
+
"/",
|
|
414
|
+
stage.total
|
|
415
|
+
] });
|
|
379
416
|
case "sleep":
|
|
380
417
|
return /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
381
418
|
"\u{1F4A4} sleep ",
|
|
@@ -526,6 +563,11 @@ function fmtCost(n) {
|
|
|
526
563
|
if (n === 0) return "\u2014";
|
|
527
564
|
return `$${n.toFixed(3)}`;
|
|
528
565
|
}
|
|
566
|
+
function fmtModelLabel(provider, model) {
|
|
567
|
+
if (!model && !provider) return "";
|
|
568
|
+
const short = model ? model.includes("/") ? model.slice(model.lastIndexOf("/") + 1) : model : "?";
|
|
569
|
+
return provider ? `${provider}:${short}` : short;
|
|
570
|
+
}
|
|
529
571
|
function FleetMonitor({
|
|
530
572
|
entries,
|
|
531
573
|
totalCost,
|
|
@@ -598,7 +640,7 @@ function FleetMonitor({
|
|
|
598
640
|
"\u2717",
|
|
599
641
|
failed
|
|
600
642
|
] }) : null,
|
|
601
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 Ctrl+F to close" })
|
|
643
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 Ctrl+F / F2 to close" })
|
|
602
644
|
] }),
|
|
603
645
|
collabSession ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
604
646
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
@@ -658,20 +700,24 @@ function FleetMonitor({
|
|
|
658
700
|
shown.length > 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
659
701
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
660
702
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }),
|
|
661
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "name".padEnd(
|
|
662
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "
|
|
663
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "
|
|
703
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "name".padEnd(14) }),
|
|
704
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "model".padEnd(18) }),
|
|
705
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "status".padEnd(9) }),
|
|
706
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "L/t\xB7ctx".padEnd(12) }),
|
|
664
707
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "elapsed".padEnd(8) }),
|
|
665
708
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "cost" })
|
|
666
709
|
] }),
|
|
667
710
|
shown.map((e) => {
|
|
668
711
|
const s2 = STATUS[e.status];
|
|
669
712
|
const elapsed = e.status === "running" ? fmtElapsed(Math.max(0, nowTick - e.startedAt)) : fmtElapsed(Math.max(0, nowTick - e.lastEventAt)) + " ago";
|
|
713
|
+
const model = fmtModelLabel(e.provider, e.model) || "\u2014";
|
|
714
|
+
const ltCtx = e.ctxPct !== void 0 ? `L${e.iterations} ${e.toolCalls}t ${Math.round(e.ctxPct * 100)}%` : `L${e.iterations} ${e.toolCalls}t`;
|
|
670
715
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
671
716
|
/* @__PURE__ */ jsx(Text, { color: s2.color, children: s2.icon }),
|
|
672
|
-
/* @__PURE__ */ jsx(Text, { children: e.name.padEnd(
|
|
673
|
-
/* @__PURE__ */ jsx(Text, {
|
|
674
|
-
/* @__PURE__ */ jsx(Text, {
|
|
717
|
+
/* @__PURE__ */ jsx(Text, { children: e.name.padEnd(14).slice(0, 14) }),
|
|
718
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: model.padEnd(18).slice(0, 18) }),
|
|
719
|
+
/* @__PURE__ */ jsx(Text, { color: s2.color, children: e.status.padEnd(9) }),
|
|
720
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ltCtx.padEnd(12).slice(0, 12) }),
|
|
675
721
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: elapsed.padEnd(8).slice(0, 8) }),
|
|
676
722
|
/* @__PURE__ */ jsx(Text, { color: "yellow", children: fmtCost(e.cost) }),
|
|
677
723
|
e.extensions && e.extensions > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
@@ -725,6 +771,9 @@ function fmtTokens2(n) {
|
|
|
725
771
|
if (n < 1e6) return `${(n / 1e3).toFixed(1)}k`;
|
|
726
772
|
return `${(n / 1e6).toFixed(1)}M`;
|
|
727
773
|
}
|
|
774
|
+
function fmtExactTokens(n) {
|
|
775
|
+
return `${Math.round(n).toLocaleString("en-US")} tok`;
|
|
776
|
+
}
|
|
728
777
|
function snippet(s2, max = 72) {
|
|
729
778
|
const oneLine2 = s2.replace(/\s+/g, " ").trim();
|
|
730
779
|
if (oneLine2.length <= max) return oneLine2;
|
|
@@ -786,7 +835,7 @@ function AgentsMonitor({
|
|
|
786
835
|
"\u2717",
|
|
787
836
|
totalFailed
|
|
788
837
|
] }) : null,
|
|
789
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 Ctrl+G to close" })
|
|
838
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7 Ctrl+G / F3 to close" })
|
|
790
839
|
] }),
|
|
791
840
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
792
841
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "shown" }),
|
|
@@ -821,6 +870,11 @@ function AgentsMonitor({
|
|
|
821
870
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
822
871
|
/* @__PURE__ */ jsx(Text, { color: s2.color, bold: true, children: s2.icon }),
|
|
823
872
|
/* @__PURE__ */ jsx(Text, { bold: true, children: e.name }),
|
|
873
|
+
fmtModelLabel(e.provider, e.model) ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: fmtModelLabel(e.provider, e.model) }) : null,
|
|
874
|
+
e.ctxMaxTokens && e.ctxMaxTokens > 0 ? /* @__PURE__ */ jsxs(Text, { color: "blue", children: [
|
|
875
|
+
"ctx max ",
|
|
876
|
+
fmtExactTokens(e.ctxMaxTokens)
|
|
877
|
+
] }) : null,
|
|
824
878
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
825
879
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: elapsed }),
|
|
826
880
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
@@ -831,6 +885,10 @@ function AgentsMonitor({
|
|
|
831
885
|
e.toolCalls,
|
|
832
886
|
"t"
|
|
833
887
|
] }),
|
|
888
|
+
e.ctxPct !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
889
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
890
|
+
/* @__PURE__ */ jsx(ContextBar, { pct: e.ctxPct, tokens: e.ctxTokens, maxTokens: e.ctxMaxTokens })
|
|
891
|
+
] }) : null,
|
|
834
892
|
e.extensions && e.extensions > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
835
893
|
"\u26A1\xD7",
|
|
836
894
|
e.extensions
|
|
@@ -877,11 +935,7 @@ function AgentsMonitor({
|
|
|
877
935
|
e.failureReason && e.status !== "success" ? /* @__PURE__ */ jsx(Box, { paddingLeft: 2, children: /* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
878
936
|
"\u2717 ",
|
|
879
937
|
e.failureReason
|
|
880
|
-
] }) }) : null
|
|
881
|
-
e.ctxPct !== void 0 ? /* @__PURE__ */ jsxs(Box, { paddingLeft: 2, children: [
|
|
882
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "ctx " }),
|
|
883
|
-
/* @__PURE__ */ jsx(ContextBar, { pct: e.ctxPct, tokens: e.ctxTokens, maxTokens: e.ctxMaxTokens })
|
|
884
|
-
] }) : null
|
|
938
|
+
] }) }) : null
|
|
885
939
|
] }, e.id);
|
|
886
940
|
})
|
|
887
941
|
] });
|
|
@@ -942,6 +996,92 @@ function AutonomyPicker({
|
|
|
942
996
|
hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
|
|
943
997
|
] });
|
|
944
998
|
}
|
|
999
|
+
function riskColor(risk) {
|
|
1000
|
+
switch (risk) {
|
|
1001
|
+
case "low":
|
|
1002
|
+
return "green";
|
|
1003
|
+
case "medium":
|
|
1004
|
+
return "cyan";
|
|
1005
|
+
case "high":
|
|
1006
|
+
return "yellow";
|
|
1007
|
+
case "critical":
|
|
1008
|
+
return "red";
|
|
1009
|
+
default:
|
|
1010
|
+
return "white";
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
function optionKey(index) {
|
|
1014
|
+
return String.fromCharCode("A".charCodeAt(0) + index);
|
|
1015
|
+
}
|
|
1016
|
+
function contextLines(context) {
|
|
1017
|
+
if (!context?.trim()) return [];
|
|
1018
|
+
return context.trim().split("\n").slice(0, 5);
|
|
1019
|
+
}
|
|
1020
|
+
function BrainDecisionPrompt({
|
|
1021
|
+
requestId,
|
|
1022
|
+
source,
|
|
1023
|
+
risk,
|
|
1024
|
+
question,
|
|
1025
|
+
context,
|
|
1026
|
+
options = [],
|
|
1027
|
+
onAnswer
|
|
1028
|
+
}) {
|
|
1029
|
+
const color = riskColor(risk);
|
|
1030
|
+
const ctx = contextLines(context);
|
|
1031
|
+
useInput((input, key) => {
|
|
1032
|
+
if (!onAnswer) return;
|
|
1033
|
+
if (key.escape || input.toLowerCase() === "d") {
|
|
1034
|
+
onAnswer({ id: requestId, deny: true, text: "Denied by human from TUI." });
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
const ch = input.toLowerCase();
|
|
1038
|
+
const index = ch >= "a" && ch <= "z" ? ch.charCodeAt(0) - "a".charCodeAt(0) : Number(ch) - 1;
|
|
1039
|
+
const option = Number.isInteger(index) && index >= 0 ? options[index] : void 0;
|
|
1040
|
+
if (option) onAnswer({ id: requestId, optionId: option.id, text: option.label });
|
|
1041
|
+
});
|
|
1042
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 1, children: [
|
|
1043
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsx(Text, { bold: true, color: "magenta", children: "\u{1F9E0} BRAIN REQUIRES HUMAN DECISION" }) }),
|
|
1044
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
1045
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Source:" }),
|
|
1046
|
+
/* @__PURE__ */ jsx(Text, { children: source }),
|
|
1047
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Risk:" }),
|
|
1048
|
+
/* @__PURE__ */ jsx(Text, { color, children: risk })
|
|
1049
|
+
] }),
|
|
1050
|
+
/* @__PURE__ */ jsx(Text, { color: "white", children: question }),
|
|
1051
|
+
ctx.length > 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
1052
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Context:" }),
|
|
1053
|
+
ctx.map((line, index) => (
|
|
1054
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: context lines are static for this prompt render
|
|
1055
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: line }, index)
|
|
1056
|
+
))
|
|
1057
|
+
] }) : null,
|
|
1058
|
+
options.length > 0 ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
1059
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Options:" }),
|
|
1060
|
+
options.slice(0, 6).map((option, index) => {
|
|
1061
|
+
const key = optionKey(index);
|
|
1062
|
+
const optionColor = riskColor(String(option.risk ?? risk));
|
|
1063
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
1064
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1065
|
+
/* @__PURE__ */ jsxs(Text, { bold: true, color: "yellow", children: [
|
|
1066
|
+
"[",
|
|
1067
|
+
key,
|
|
1068
|
+
"]"
|
|
1069
|
+
] }),
|
|
1070
|
+
" ",
|
|
1071
|
+
/* @__PURE__ */ jsx(Text, { color: optionColor, children: option.label }),
|
|
1072
|
+
option.recommended ? /* @__PURE__ */ jsx(Text, { color: "green", children: " recommended" }) : null
|
|
1073
|
+
] }),
|
|
1074
|
+
option.consequence ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1075
|
+
" ",
|
|
1076
|
+
option.consequence
|
|
1077
|
+
] }) : null
|
|
1078
|
+
] }, option.id);
|
|
1079
|
+
})
|
|
1080
|
+
] }) : null,
|
|
1081
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }),
|
|
1082
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Press A/B/C or 1/2/3 to answer; Esc or D denies with the safe default." })
|
|
1083
|
+
] });
|
|
1084
|
+
}
|
|
945
1085
|
function CheckpointTimeline({
|
|
946
1086
|
checkpoints,
|
|
947
1087
|
selected,
|
|
@@ -1041,7 +1181,7 @@ function ConfirmPrompt({
|
|
|
1041
1181
|
onDecision
|
|
1042
1182
|
}) {
|
|
1043
1183
|
React4.useEffect(() => {
|
|
1044
|
-
|
|
1184
|
+
writeOut("\x07");
|
|
1045
1185
|
}, []);
|
|
1046
1186
|
useInput((input2, _key) => {
|
|
1047
1187
|
if (!input2 || input2 === "\r" || input2 === "\n") return;
|
|
@@ -1182,9 +1322,9 @@ function helpSections(opts) {
|
|
|
1182
1322
|
{
|
|
1183
1323
|
title: "Monitors",
|
|
1184
1324
|
entries: [
|
|
1185
|
-
{ keys: "Ctrl+F", desc: "fleet orchestration monitor" },
|
|
1186
|
-
{ keys: "Ctrl+G", desc: "agents live monitor" },
|
|
1187
|
-
{ keys: "Ctrl+T", desc: "worktree monitor" },
|
|
1325
|
+
{ keys: "Ctrl+F / F2", desc: "fleet orchestration monitor" },
|
|
1326
|
+
{ keys: "Ctrl+G / F3", desc: "agents live monitor" },
|
|
1327
|
+
{ keys: "Ctrl+T / F4", desc: "worktree monitor" },
|
|
1188
1328
|
{ keys: "Esc", desc: "close the open monitor / overlay" }
|
|
1189
1329
|
]
|
|
1190
1330
|
},
|
|
@@ -2308,6 +2448,30 @@ function DiffBlock({ rows, hidden }) {
|
|
|
2308
2448
|
hidden > 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, italic: true, children: `${blank} \u2026 ${hidden} more line${hidden === 1 ? "" : "s"}` }) : null
|
|
2309
2449
|
] });
|
|
2310
2450
|
}
|
|
2451
|
+
function brainStatusStyle(status) {
|
|
2452
|
+
switch (status) {
|
|
2453
|
+
case "thinking":
|
|
2454
|
+
return { icon: "\u2026", color: "magenta" };
|
|
2455
|
+
case "answered":
|
|
2456
|
+
return { icon: "\u2696", color: "cyan" };
|
|
2457
|
+
case "ask_human":
|
|
2458
|
+
return { icon: "?", color: "yellow" };
|
|
2459
|
+
case "denied":
|
|
2460
|
+
return { icon: "\xD7", color: "red" };
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
function brainRiskColor(risk) {
|
|
2464
|
+
switch (risk) {
|
|
2465
|
+
case "low":
|
|
2466
|
+
return "green";
|
|
2467
|
+
case "medium":
|
|
2468
|
+
return "cyan";
|
|
2469
|
+
case "high":
|
|
2470
|
+
return "yellow";
|
|
2471
|
+
case "critical":
|
|
2472
|
+
return "red";
|
|
2473
|
+
}
|
|
2474
|
+
}
|
|
2311
2475
|
var Entry = React4.memo(function Entry2({
|
|
2312
2476
|
entry,
|
|
2313
2477
|
termWidth
|
|
@@ -2440,6 +2604,38 @@ var Entry = React4.memo(function Entry2({
|
|
|
2440
2604
|
);
|
|
2441
2605
|
case "turn-summary":
|
|
2442
2606
|
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: entry.text });
|
|
2607
|
+
case "brain": {
|
|
2608
|
+
const statusStyle = brainStatusStyle(entry.status);
|
|
2609
|
+
const riskColor2 = brainRiskColor(entry.risk);
|
|
2610
|
+
return /* @__PURE__ */ jsxs(
|
|
2611
|
+
Box,
|
|
2612
|
+
{
|
|
2613
|
+
flexDirection: "column",
|
|
2614
|
+
marginY: 1,
|
|
2615
|
+
borderStyle: "single",
|
|
2616
|
+
borderTop: false,
|
|
2617
|
+
borderRight: false,
|
|
2618
|
+
borderBottom: false,
|
|
2619
|
+
borderColor: "magenta",
|
|
2620
|
+
paddingLeft: 1,
|
|
2621
|
+
children: [
|
|
2622
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
|
|
2623
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "magenta", children: "BRAIN" }),
|
|
2624
|
+
/* @__PURE__ */ jsx(Text, { color: statusStyle.color, children: statusStyle.icon }),
|
|
2625
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: entry.source }),
|
|
2626
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
|
|
2627
|
+
/* @__PURE__ */ jsx(Text, { color: riskColor2, children: entry.risk })
|
|
2628
|
+
] }),
|
|
2629
|
+
/* @__PURE__ */ jsx(Text, { color: "white", children: entry.question }),
|
|
2630
|
+
entry.decision ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
2631
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Decision: " }),
|
|
2632
|
+
/* @__PURE__ */ jsx(Text, { color: statusStyle.color, children: entry.decision })
|
|
2633
|
+
] }) : null,
|
|
2634
|
+
entry.rationale ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: entry.rationale }) : null
|
|
2635
|
+
]
|
|
2636
|
+
}
|
|
2637
|
+
);
|
|
2638
|
+
}
|
|
2443
2639
|
case "confirm":
|
|
2444
2640
|
return /* @__PURE__ */ jsxs(
|
|
2445
2641
|
Box,
|
|
@@ -3181,6 +3377,42 @@ function truncMid(s2, max) {
|
|
|
3181
3377
|
return `${s2.slice(0, max - 1)}\u2026`;
|
|
3182
3378
|
}
|
|
3183
3379
|
|
|
3380
|
+
// src/fn-keys.ts
|
|
3381
|
+
function fnKey(data) {
|
|
3382
|
+
switch (data) {
|
|
3383
|
+
case "\x1BOP":
|
|
3384
|
+
case "\x1B[11~":
|
|
3385
|
+
return 1;
|
|
3386
|
+
case "\x1BOQ":
|
|
3387
|
+
case "\x1B[12~":
|
|
3388
|
+
return 2;
|
|
3389
|
+
case "\x1BOR":
|
|
3390
|
+
case "\x1B[13~":
|
|
3391
|
+
return 3;
|
|
3392
|
+
case "\x1BOS":
|
|
3393
|
+
case "\x1B[14~":
|
|
3394
|
+
return 4;
|
|
3395
|
+
case "\x1B[15~":
|
|
3396
|
+
return 5;
|
|
3397
|
+
case "\x1B[17~":
|
|
3398
|
+
return 6;
|
|
3399
|
+
case "\x1B[18~":
|
|
3400
|
+
return 7;
|
|
3401
|
+
case "\x1B[19~":
|
|
3402
|
+
return 8;
|
|
3403
|
+
case "\x1B[20~":
|
|
3404
|
+
return 9;
|
|
3405
|
+
case "\x1B[21~":
|
|
3406
|
+
return 10;
|
|
3407
|
+
case "\x1B[23~":
|
|
3408
|
+
return 11;
|
|
3409
|
+
case "\x1B[24~":
|
|
3410
|
+
return 12;
|
|
3411
|
+
default:
|
|
3412
|
+
return null;
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
|
|
3184
3416
|
// src/input-tokens.ts
|
|
3185
3417
|
var INLINE_TOKEN_SRC = "\\[(?:pasted|image|file) #\\d+[^\\]]*\\]|\\[file:[^\\]]+\\]";
|
|
3186
3418
|
var AT_END = new RegExp(`(?:${INLINE_TOKEN_SRC})$`);
|
|
@@ -3375,9 +3607,18 @@ function Input({
|
|
|
3375
3607
|
useEffect(() => {
|
|
3376
3608
|
if (!stdin || disabled) return;
|
|
3377
3609
|
const handleData = (data) => {
|
|
3378
|
-
const
|
|
3379
|
-
|
|
3380
|
-
|
|
3610
|
+
const s2 = data.toString();
|
|
3611
|
+
const kind = isHomeEnd(s2);
|
|
3612
|
+
if (kind === "home") {
|
|
3613
|
+
onKey("", { ...EMPTY_KEY, home: true });
|
|
3614
|
+
return;
|
|
3615
|
+
}
|
|
3616
|
+
if (kind === "end") {
|
|
3617
|
+
onKey("", { ...EMPTY_KEY, end: true });
|
|
3618
|
+
return;
|
|
3619
|
+
}
|
|
3620
|
+
const fn = fnKey(s2);
|
|
3621
|
+
if (fn !== null) onKey("", { ...EMPTY_KEY, fn });
|
|
3381
3622
|
};
|
|
3382
3623
|
stdin.on("data", handleData);
|
|
3383
3624
|
return () => {
|
|
@@ -3974,7 +4215,7 @@ function WorktreeMonitor({
|
|
|
3974
4215
|
failed
|
|
3975
4216
|
] })
|
|
3976
4217
|
] }) : null,
|
|
3977
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 Ctrl+T / Esc to close" })
|
|
4218
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502 Ctrl+T / F4 / Esc to close" })
|
|
3978
4219
|
] }),
|
|
3979
4220
|
list.length === 0 ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No worktrees. They appear when AutoPhase runs with isolation on." }) : list.map((w) => {
|
|
3980
4221
|
const s2 = fmt(w.status);
|
|
@@ -4519,6 +4760,21 @@ function reducer(state, action) {
|
|
|
4519
4760
|
return { ...state, interrupts: 0 };
|
|
4520
4761
|
case "hint":
|
|
4521
4762
|
return { ...state, hint: action.text };
|
|
4763
|
+
case "brainStatus":
|
|
4764
|
+
return {
|
|
4765
|
+
...state,
|
|
4766
|
+
brain: {
|
|
4767
|
+
state: action.state,
|
|
4768
|
+
source: action.source,
|
|
4769
|
+
risk: action.risk,
|
|
4770
|
+
summary: action.summary,
|
|
4771
|
+
updatedAt: Date.now()
|
|
4772
|
+
}
|
|
4773
|
+
};
|
|
4774
|
+
case "brainPromptSet":
|
|
4775
|
+
return { ...state, brainPrompt: action.prompt };
|
|
4776
|
+
case "brainPromptClear":
|
|
4777
|
+
return { ...state, brainPrompt: null };
|
|
4522
4778
|
case "pickerOpen":
|
|
4523
4779
|
return {
|
|
4524
4780
|
...state,
|
|
@@ -5479,6 +5735,7 @@ function App({
|
|
|
5479
5735
|
const { exit } = useApp();
|
|
5480
5736
|
const [liveModel, setLiveModel] = useState(model);
|
|
5481
5737
|
const [liveProvider, setLiveProvider] = useState(provider ?? "agent");
|
|
5738
|
+
const [activeMaxContext, setActiveMaxContext] = useState(effectiveMaxContext);
|
|
5482
5739
|
const [yoloLive, setYoloLive] = useState(yolo);
|
|
5483
5740
|
const [autonomyLive, setAutonomyLive] = useState(getAutonomy?.() ?? "off");
|
|
5484
5741
|
const [hiddenItems, setHiddenItems] = useState(statuslineHiddenItems);
|
|
@@ -5547,6 +5804,8 @@ function App({
|
|
|
5547
5804
|
steeringPending: false,
|
|
5548
5805
|
steerSnapshot: null,
|
|
5549
5806
|
hint: "",
|
|
5807
|
+
brain: { state: "idle" },
|
|
5808
|
+
brainPrompt: null,
|
|
5550
5809
|
nextId: 1,
|
|
5551
5810
|
picker: { open: false, query: "", matches: [], selected: 0 },
|
|
5552
5811
|
slashPicker: { open: false, query: "", matches: [], selected: 0 },
|
|
@@ -5888,7 +6147,7 @@ function App({
|
|
|
5888
6147
|
clearInterval(t);
|
|
5889
6148
|
};
|
|
5890
6149
|
}, [agent.ctx.cwd]);
|
|
5891
|
-
const maxContext =
|
|
6150
|
+
const maxContext = activeMaxContext ?? agent.ctx.provider.capabilities.maxContext;
|
|
5892
6151
|
const currentContextTokens = (tokenCounter?.currentRequestTokens()?.input ?? 0) + (tokenCounter?.currentRequestTokens()?.cacheRead ?? 0);
|
|
5893
6152
|
const contextWindow = useMemo(() => {
|
|
5894
6153
|
void state.contextChipVersion;
|
|
@@ -5934,10 +6193,10 @@ function App({
|
|
|
5934
6193
|
currentTool: state.leader.currentTool,
|
|
5935
6194
|
ctxPct: state.leader.ctxPct,
|
|
5936
6195
|
ctxTokens: state.leader.ctxTokens,
|
|
5937
|
-
ctxMaxTokens: state.leader.ctxMaxTokens
|
|
6196
|
+
ctxMaxTokens: state.leader.ctxMaxTokens ?? effectiveMaxContext
|
|
5938
6197
|
};
|
|
5939
6198
|
return { leader: leaderEntry, ...state.fleet };
|
|
5940
|
-
}, [state.fleet, state.leader, state.status, provider, model]);
|
|
6199
|
+
}, [state.fleet, state.leader, state.status, provider, model, effectiveMaxContext]);
|
|
5941
6200
|
const STREAM_COLORS = ["cyan", "magenta", "yellow", "green", "blue"];
|
|
5942
6201
|
const labelsRef = useRef(/* @__PURE__ */ new Map());
|
|
5943
6202
|
const labelFor = (id, name) => {
|
|
@@ -5990,7 +6249,7 @@ function App({
|
|
|
5990
6249
|
const prevEntriesCount = useRef(0);
|
|
5991
6250
|
const eraseLiveRegion = useCallback(() => {
|
|
5992
6251
|
try {
|
|
5993
|
-
|
|
6252
|
+
writeOut("\x1B[J");
|
|
5994
6253
|
} catch {
|
|
5995
6254
|
}
|
|
5996
6255
|
}, []);
|
|
@@ -6202,7 +6461,7 @@ function App({
|
|
|
6202
6461
|
const arg = args.trim().toLowerCase();
|
|
6203
6462
|
if (arg === "off") {
|
|
6204
6463
|
try {
|
|
6205
|
-
|
|
6464
|
+
writeOut(ALT_OFF);
|
|
6206
6465
|
} catch {
|
|
6207
6466
|
return { message: "Failed to exit alt-screen." };
|
|
6208
6467
|
}
|
|
@@ -6213,7 +6472,7 @@ function App({
|
|
|
6213
6472
|
}
|
|
6214
6473
|
if (arg === "on") {
|
|
6215
6474
|
try {
|
|
6216
|
-
|
|
6475
|
+
writeOut(ALT_ON);
|
|
6217
6476
|
} catch {
|
|
6218
6477
|
return { message: "Failed to re-enter alt-screen." };
|
|
6219
6478
|
}
|
|
@@ -6254,9 +6513,9 @@ function App({
|
|
|
6254
6513
|
};
|
|
6255
6514
|
}
|
|
6256
6515
|
try {
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6516
|
+
writeOut(ALT_ON);
|
|
6517
|
+
writeOut("\x1B[H");
|
|
6518
|
+
writeOut(MOUSE_ON_SEQ);
|
|
6260
6519
|
} catch {
|
|
6261
6520
|
return { message: "Failed to enable mouse mode." };
|
|
6262
6521
|
}
|
|
@@ -6267,8 +6526,8 @@ function App({
|
|
|
6267
6526
|
};
|
|
6268
6527
|
}
|
|
6269
6528
|
try {
|
|
6270
|
-
|
|
6271
|
-
|
|
6529
|
+
writeOut(MOUSE_OFF_SEQ);
|
|
6530
|
+
writeOut(ALT_OFF);
|
|
6272
6531
|
} catch {
|
|
6273
6532
|
return { message: "Failed to disable mouse mode." };
|
|
6274
6533
|
}
|
|
@@ -6714,6 +6973,7 @@ function App({
|
|
|
6714
6973
|
});
|
|
6715
6974
|
});
|
|
6716
6975
|
const offLeaderCtxPct = events.on("ctx.pct", (e) => {
|
|
6976
|
+
setActiveMaxContext(e.maxContext);
|
|
6717
6977
|
dispatch({
|
|
6718
6978
|
type: "leaderCtxPct",
|
|
6719
6979
|
load: e.load,
|
|
@@ -6721,6 +6981,9 @@ function App({
|
|
|
6721
6981
|
maxContext: e.maxContext
|
|
6722
6982
|
});
|
|
6723
6983
|
});
|
|
6984
|
+
const offLeaderMaxContext = events.on("ctx.max_context", (e) => {
|
|
6985
|
+
if (e.maxContext > 0) setActiveMaxContext(e.maxContext);
|
|
6986
|
+
});
|
|
6724
6987
|
const offTool = events.on("subagent.tool_executed", (e) => {
|
|
6725
6988
|
dispatch({
|
|
6726
6989
|
type: "fleetTool",
|
|
@@ -6741,6 +7004,7 @@ function App({
|
|
|
6741
7004
|
offIterationSummary();
|
|
6742
7005
|
offCtxPct();
|
|
6743
7006
|
offLeaderCtxPct();
|
|
7007
|
+
offLeaderMaxContext();
|
|
6744
7008
|
offTool();
|
|
6745
7009
|
};
|
|
6746
7010
|
}, [events, director]);
|
|
@@ -6768,6 +7032,71 @@ function App({
|
|
|
6768
7032
|
offRewound();
|
|
6769
7033
|
};
|
|
6770
7034
|
}, [events, onClearHistory]);
|
|
7035
|
+
useEffect(() => {
|
|
7036
|
+
const requestSummary = (request) => `${request.source}: ${request.question}`.slice(0, 80);
|
|
7037
|
+
const addBrainEntry = (status, payload) => {
|
|
7038
|
+
const p = payload;
|
|
7039
|
+
const decision = p.decision.optionId ?? p.decision.text ?? p.decision.reason ?? p.decision.prompt ?? p.decision.type;
|
|
7040
|
+
dispatch({
|
|
7041
|
+
type: "brainStatus",
|
|
7042
|
+
state: status,
|
|
7043
|
+
source: p.request.source,
|
|
7044
|
+
risk: p.request.risk,
|
|
7045
|
+
summary: decision
|
|
7046
|
+
});
|
|
7047
|
+
if (status === "ask_human") {
|
|
7048
|
+
dispatch({
|
|
7049
|
+
type: "brainPromptSet",
|
|
7050
|
+
prompt: {
|
|
7051
|
+
requestId: p.request.id,
|
|
7052
|
+
source: p.request.source,
|
|
7053
|
+
risk: p.request.risk,
|
|
7054
|
+
question: p.request.question,
|
|
7055
|
+
context: p.request.context,
|
|
7056
|
+
options: p.request.options
|
|
7057
|
+
}
|
|
7058
|
+
});
|
|
7059
|
+
} else {
|
|
7060
|
+
dispatch({ type: "brainPromptClear" });
|
|
7061
|
+
}
|
|
7062
|
+
dispatch({
|
|
7063
|
+
type: "addEntry",
|
|
7064
|
+
entry: {
|
|
7065
|
+
kind: "brain",
|
|
7066
|
+
status,
|
|
7067
|
+
source: p.request.source,
|
|
7068
|
+
risk: p.request.risk,
|
|
7069
|
+
question: p.request.question,
|
|
7070
|
+
decision,
|
|
7071
|
+
rationale: p.decision.rationale
|
|
7072
|
+
}
|
|
7073
|
+
});
|
|
7074
|
+
};
|
|
7075
|
+
const offRequested = events.on("brain.decision_requested", ({ request }) => {
|
|
7076
|
+
dispatch({
|
|
7077
|
+
type: "brainStatus",
|
|
7078
|
+
state: "deciding",
|
|
7079
|
+
source: request.source,
|
|
7080
|
+
risk: request.risk,
|
|
7081
|
+
summary: requestSummary(request)
|
|
7082
|
+
});
|
|
7083
|
+
});
|
|
7084
|
+
const offAnswered = events.on("brain.decision_answered", (payload) => {
|
|
7085
|
+
addBrainEntry("answered", payload);
|
|
7086
|
+
});
|
|
7087
|
+
const offAskHuman = events.on("brain.decision_ask_human", (payload) => {
|
|
7088
|
+
addBrainEntry("ask_human", payload);
|
|
7089
|
+
});
|
|
7090
|
+
const offDenied = events.on("brain.decision_denied", (payload) => {
|
|
7091
|
+
addBrainEntry("denied", payload);
|
|
7092
|
+
});
|
|
7093
|
+
return () => {
|
|
7094
|
+
offRequested();
|
|
7095
|
+
offAnswered();
|
|
7096
|
+
offAskHuman();
|
|
7097
|
+
offDenied();
|
|
7098
|
+
};
|
|
7099
|
+
}, [events]);
|
|
6771
7100
|
useEffect(() => {
|
|
6772
7101
|
if (!subscribeAutoPhase) return;
|
|
6773
7102
|
const handler = (event, payload) => {
|
|
@@ -7558,6 +7887,7 @@ function App({
|
|
|
7558
7887
|
}
|
|
7559
7888
|
setLiveProvider(providerId);
|
|
7560
7889
|
setLiveModel(modelId);
|
|
7890
|
+
setActiveMaxContext(agent.ctx.provider.capabilities.maxContext);
|
|
7561
7891
|
dispatch({
|
|
7562
7892
|
type: "addEntry",
|
|
7563
7893
|
entry: { kind: "info", text: `Switched to ${providerId} / ${modelId}.` }
|
|
@@ -7728,25 +8058,23 @@ function App({
|
|
|
7728
8058
|
});
|
|
7729
8059
|
return;
|
|
7730
8060
|
}
|
|
7731
|
-
|
|
8061
|
+
const toggleFleetOverlay = () => {
|
|
7732
8062
|
if (state.agentsMonitorOpen) {
|
|
7733
8063
|
dispatch({ type: "toggleAgentsMonitor" });
|
|
7734
8064
|
dispatch({ type: "toggleMonitor" });
|
|
7735
8065
|
} else {
|
|
7736
8066
|
dispatch({ type: "toggleMonitor" });
|
|
7737
8067
|
}
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
if (key.ctrl && input === "g") {
|
|
8068
|
+
};
|
|
8069
|
+
const toggleAgentsOverlay = () => {
|
|
7741
8070
|
if (state.monitorOpen) {
|
|
7742
8071
|
dispatch({ type: "toggleMonitor" });
|
|
7743
8072
|
dispatch({ type: "toggleAgentsMonitor" });
|
|
7744
8073
|
} else {
|
|
7745
8074
|
dispatch({ type: "toggleAgentsMonitor" });
|
|
7746
8075
|
}
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
if (key.ctrl && input === "t") {
|
|
8076
|
+
};
|
|
8077
|
+
const toggleWorktreeOverlay = () => {
|
|
7750
8078
|
if (state.worktreeMonitorOpen) {
|
|
7751
8079
|
dispatch({ type: "worktreeMonitorToggle" });
|
|
7752
8080
|
return;
|
|
@@ -7755,6 +8083,17 @@ function App({
|
|
|
7755
8083
|
if (state.monitorOpen) dispatch({ type: "toggleMonitor" });
|
|
7756
8084
|
if (state.autoPhase?.monitorOpen) dispatch({ type: "autoPhaseMonitorToggle" });
|
|
7757
8085
|
dispatch({ type: "worktreeMonitorToggle" });
|
|
8086
|
+
};
|
|
8087
|
+
if (key.ctrl && input === "f" || key.fn === 2) {
|
|
8088
|
+
toggleFleetOverlay();
|
|
8089
|
+
return;
|
|
8090
|
+
}
|
|
8091
|
+
if (key.ctrl && input === "g" || key.fn === 3) {
|
|
8092
|
+
toggleAgentsOverlay();
|
|
8093
|
+
return;
|
|
8094
|
+
}
|
|
8095
|
+
if (key.ctrl && input === "t" || key.fn === 4) {
|
|
8096
|
+
toggleWorktreeOverlay();
|
|
7758
8097
|
return;
|
|
7759
8098
|
}
|
|
7760
8099
|
if (key.ctrl && input === "s") {
|
|
@@ -7910,6 +8249,7 @@ function App({
|
|
|
7910
8249
|
return;
|
|
7911
8250
|
}
|
|
7912
8251
|
if (!input || key.ctrl || key.meta) return;
|
|
8252
|
+
if (input.charCodeAt(0) === 27) return;
|
|
7913
8253
|
if (input.length > PASTE_THRESHOLD_CHARS) {
|
|
7914
8254
|
await commitPaste(input);
|
|
7915
8255
|
return;
|
|
@@ -8148,6 +8488,10 @@ function App({
|
|
|
8148
8488
|
if (ctxModel && ctxModel !== liveModel) setLiveModel(ctxModel);
|
|
8149
8489
|
const ctxProviderId = agent.ctx.provider?.id;
|
|
8150
8490
|
if (ctxProviderId && ctxProviderId !== liveProvider) setLiveProvider(ctxProviderId);
|
|
8491
|
+
const ctxMaxContext = agent.ctx.provider.capabilities.maxContext;
|
|
8492
|
+
if (ctxMaxContext > 0 && ctxMaxContext !== activeMaxContext) {
|
|
8493
|
+
setActiveMaxContext(ctxMaxContext);
|
|
8494
|
+
}
|
|
8151
8495
|
if (getYolo) {
|
|
8152
8496
|
const currentYolo = getYolo();
|
|
8153
8497
|
if (currentYolo !== yoloLive) setYoloLive(currentYolo);
|
|
@@ -8372,6 +8716,16 @@ User message:
|
|
|
8372
8716
|
onClose: () => dispatch({ type: "rewindOverlayClose" })
|
|
8373
8717
|
}
|
|
8374
8718
|
) : null,
|
|
8719
|
+
state.brainPrompt ? /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginY: 1, flexShrink: 0, children: /* @__PURE__ */ jsx(
|
|
8720
|
+
BrainDecisionPrompt,
|
|
8721
|
+
{
|
|
8722
|
+
...state.brainPrompt,
|
|
8723
|
+
onAnswer: (answer) => {
|
|
8724
|
+
events.emit("brain.human_answered", { ...answer, at: Date.now() });
|
|
8725
|
+
dispatch({ type: "brainPromptClear" });
|
|
8726
|
+
}
|
|
8727
|
+
}
|
|
8728
|
+
) }) : null,
|
|
8375
8729
|
state.confirmQueue.length > 0 && (() => {
|
|
8376
8730
|
const head = state.confirmQueue[0];
|
|
8377
8731
|
let resolved = false;
|
|
@@ -8409,6 +8763,7 @@ User message:
|
|
|
8409
8763
|
fleet: fleetCounts,
|
|
8410
8764
|
git: gitInfo,
|
|
8411
8765
|
context: contextWindow,
|
|
8766
|
+
brain: state.brain,
|
|
8412
8767
|
projectName,
|
|
8413
8768
|
subagentCount: Object.keys(state.fleet).length,
|
|
8414
8769
|
processCount: getProcessRegistry().activeCount,
|
|
@@ -8634,7 +8989,7 @@ async function runTui(opts) {
|
|
|
8634
8989
|
const stdout = process.stdout;
|
|
8635
8990
|
const stdin = process.stdin;
|
|
8636
8991
|
if (!stdout.isTTY || !stdin.isTTY) {
|
|
8637
|
-
|
|
8992
|
+
writeErr(
|
|
8638
8993
|
"wstack: --tui requires an interactive terminal on both stdin and stdout.\n Drop the flag (use the plain REPL) or run wstack directly without piping.\n"
|
|
8639
8994
|
);
|
|
8640
8995
|
return 2;
|
|
@@ -8861,7 +9216,7 @@ async function runTui(opts) {
|
|
|
8861
9216
|
{ exitOnCtrlC: false, stdin: inkStdin }
|
|
8862
9217
|
);
|
|
8863
9218
|
} catch (err) {
|
|
8864
|
-
|
|
9219
|
+
writeErr(
|
|
8865
9220
|
`wstack: TUI failed to start: ${err instanceof Error ? err.message : String(err)}
|
|
8866
9221
|
`
|
|
8867
9222
|
);
|