@wrongstack/tui 0.257.2 → 0.260.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +46 -25
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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';
|
|
@@ -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;
|
|
@@ -215,6 +219,7 @@ function StatusBar({
|
|
|
215
219
|
const hasDebugStream = !!debugStreamStats;
|
|
216
220
|
const hasEnhanceCountdown = enhanceCountdown != null && enhanceCountdown > 0;
|
|
217
221
|
const hasNextStepsAutoSubmit = nextStepsAutoSubmitCountdown != null && nextStepsAutoSubmitCountdown > 0;
|
|
222
|
+
const countdownColor = nextStepsAutoSubmitCountdown != null ? nextStepsAutoSubmitCountdown > 20 ? "green" : nextStepsAutoSubmitCountdown > 10 ? "yellow" : "red" : "green";
|
|
218
223
|
const hasTaskActivity = tasks && (tasks.pending > 0 || tasks.inProgress > 0 || tasks.completed > 0 || tasks.blocked > 0 || tasks.failed > 0);
|
|
219
224
|
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
225
|
return /* @__PURE__ */ jsxs(
|
|
@@ -574,7 +579,7 @@ function StatusBar({
|
|
|
574
579
|
] }) : null,
|
|
575
580
|
hasEnhanceCountdown && enhanceCountdown != null ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
576
581
|
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
|
|
582
|
+
/* @__PURE__ */ jsxs(Text, { color: enhanceCountdown > 15 ? "green" : enhanceCountdown > 5 ? "yellow" : "red", children: [
|
|
578
583
|
"\u23F3 auto-send in ",
|
|
579
584
|
enhanceCountdown,
|
|
580
585
|
"s"
|
|
@@ -582,12 +587,14 @@ function StatusBar({
|
|
|
582
587
|
] }) : null,
|
|
583
588
|
hasNextStepsAutoSubmit && nextStepsAutoSubmitCountdown != null ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
584
589
|
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:
|
|
590
|
+
/* @__PURE__ */ jsxs(Text, { color: countdownColor, bold: true, children: [
|
|
586
591
|
"\u23F3 ",
|
|
587
|
-
nextStepsAutoSubmitLabel ? truncateLabel(nextStepsAutoSubmitLabel, 30) : "next step",
|
|
588
|
-
" in ",
|
|
589
592
|
nextStepsAutoSubmitCountdown,
|
|
590
593
|
"s"
|
|
594
|
+
] }),
|
|
595
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
596
|
+
" ",
|
|
597
|
+
nextStepsAutoSubmitLabel ? formatSuggestionLabel(nextStepsAutoSubmitLabel) : ""
|
|
591
598
|
] })
|
|
592
599
|
] }) : null
|
|
593
600
|
] }) : /* @__PURE__ */ jsx(Box, { height: 1, children: /* @__PURE__ */ jsx(Text, { children: " " }) }),
|
|
@@ -1564,9 +1571,9 @@ function buttonLabels(suggestedPattern) {
|
|
|
1564
1571
|
function stringifyInput(input) {
|
|
1565
1572
|
if (!input || typeof input !== "object") return "";
|
|
1566
1573
|
const obj = input;
|
|
1567
|
-
return Object.entries(obj).filter(([k]) => k !== "content" && k !== "new_string").map(([k, v]) => `${k}: ${
|
|
1574
|
+
return Object.entries(obj).filter(([k]) => k !== "content" && k !== "new_string").map(([k, v]) => `${k}: ${truncate(JSON.stringify(v), 80)}`).join(" ");
|
|
1568
1575
|
}
|
|
1569
|
-
function
|
|
1576
|
+
function truncate(s2, max) {
|
|
1570
1577
|
return s2.length <= max ? s2 : `${s2.slice(0, max - 1)}\u2026`;
|
|
1571
1578
|
}
|
|
1572
1579
|
function hasDiff(input) {
|
|
@@ -3915,6 +3922,9 @@ function parseWithHeading(content, strict) {
|
|
|
3915
3922
|
if (steps.length === 0) {
|
|
3916
3923
|
return { steps: [], texts: [], stripped: content, autoTexts: [] };
|
|
3917
3924
|
}
|
|
3925
|
+
if (strict && !afterHeading.includes("</next_steps>")) {
|
|
3926
|
+
return { steps: [], texts: [], stripped: content, autoTexts: [] };
|
|
3927
|
+
}
|
|
3918
3928
|
const texts = steps.map((s2) => s2.text);
|
|
3919
3929
|
const autoTexts = steps.filter((s2) => s2.auto).map((s2) => s2.text);
|
|
3920
3930
|
const blockStart = headingMatch.index;
|
|
@@ -3948,6 +3958,9 @@ function findBlockEnd(afterHeading, stepCount) {
|
|
|
3948
3958
|
}
|
|
3949
3959
|
return consumed;
|
|
3950
3960
|
}
|
|
3961
|
+
function stripNextStepsBlock(text) {
|
|
3962
|
+
return text.replace(/<next_steps\b[^>]*>[\s\S]*?<\/next_steps>/gi, "").replace(/<next_steps\b[^>]*\/?>/gi, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
3963
|
+
}
|
|
3951
3964
|
function brainStatusStyle(status) {
|
|
3952
3965
|
switch (status) {
|
|
3953
3966
|
case "thinking":
|
|
@@ -3977,7 +3990,9 @@ function brainRiskColor(risk) {
|
|
|
3977
3990
|
var Entry = React5.memo(function Entry2({
|
|
3978
3991
|
entry,
|
|
3979
3992
|
termWidth,
|
|
3980
|
-
setSuggestions
|
|
3993
|
+
setSuggestions,
|
|
3994
|
+
autonomyMode,
|
|
3995
|
+
autoSubmitCountdown
|
|
3981
3996
|
}) {
|
|
3982
3997
|
const nextSteps = useMemo(() => {
|
|
3983
3998
|
if (entry.kind !== "assistant") return { steps: [], stripped: "" };
|
|
@@ -3985,6 +4000,7 @@ var Entry = React5.memo(function Entry2({
|
|
|
3985
4000
|
}, [entry.kind, entry.text]);
|
|
3986
4001
|
useEffect(() => {
|
|
3987
4002
|
if (!setSuggestions) return;
|
|
4003
|
+
if (entry.kind !== "assistant") return;
|
|
3988
4004
|
const text = entry.text ?? "";
|
|
3989
4005
|
const { texts } = parseNextSteps(text, true);
|
|
3990
4006
|
if (texts.length > 0) setSuggestions(texts);
|
|
@@ -4055,10 +4071,11 @@ var Entry = React5.memo(function Entry2({
|
|
|
4055
4071
|
/* @__PURE__ */ jsx(Text, { bold: true, color: theme.accent, children: "\u{1F4A1} NEXT STEPS " }),
|
|
4056
4072
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "(use /next 1, /next 1 2 3 to select)" })
|
|
4057
4073
|
] }),
|
|
4058
|
-
steps.map((s2) => /* @__PURE__ */ jsx(Box, { flexDirection: "row", marginTop: 0, children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
4074
|
+
steps.map((s2, i) => /* @__PURE__ */ jsx(Box, { flexDirection: "row", marginTop: 0, children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
4059
4075
|
/* @__PURE__ */ jsx(Text, { bold: true, color: theme.accent, children: ` ${s2.index}. ` }),
|
|
4060
4076
|
/* @__PURE__ */ jsx(Text, { children: s2.text }),
|
|
4061
|
-
s2.auto ? /* @__PURE__ */ jsx(Text, { color: "cyan", dimColor: true, children: " auto" }) : null
|
|
4077
|
+
s2.auto ? /* @__PURE__ */ jsx(Text, { color: "cyan", dimColor: true, children: " auto" }) : null,
|
|
4078
|
+
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
4079
|
] }) }, s2.index))
|
|
4063
4080
|
]
|
|
4064
4081
|
}
|
|
@@ -4230,7 +4247,7 @@ var Entry = React5.memo(function Entry2({
|
|
|
4230
4247
|
}
|
|
4231
4248
|
}
|
|
4232
4249
|
});
|
|
4233
|
-
function History({ entries, generation, streamingText, toolStream, setSuggestions }) {
|
|
4250
|
+
function History({ entries, generation, streamingText, toolStream, setSuggestions, autonomyMode, autoSubmitCountdown }) {
|
|
4234
4251
|
const { stdout } = useStdout();
|
|
4235
4252
|
const [termSize, setTermSize] = useState({
|
|
4236
4253
|
columns: stdout?.columns ?? 80,
|
|
@@ -4248,7 +4265,7 @@ function History({ entries, generation, streamingText, toolStream, setSuggestion
|
|
|
4248
4265
|
const termWidth = termSize.columns;
|
|
4249
4266
|
const tail = streamingText ? tailForDisplay(streamingText, MAX_STREAM_DISPLAY_CHARS) : "";
|
|
4250
4267
|
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),
|
|
4268
|
+
/* @__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
4269
|
/* @__PURE__ */ jsx(Box, { flexGrow: 1, children: tail ? /* @__PURE__ */ jsx(AssistantTail, { text: tail, termWidth }) : null })
|
|
4253
4270
|
] });
|
|
4254
4271
|
}
|
|
@@ -4298,7 +4315,9 @@ function ScrollableHistory({
|
|
|
4298
4315
|
totalLines,
|
|
4299
4316
|
onMeasure,
|
|
4300
4317
|
maxWidth,
|
|
4301
|
-
setSuggestions
|
|
4318
|
+
setSuggestions,
|
|
4319
|
+
autonomyMode,
|
|
4320
|
+
autoSubmitCountdown
|
|
4302
4321
|
}) {
|
|
4303
4322
|
const { stdout } = useStdout();
|
|
4304
4323
|
const rawWidth = stdout?.columns ?? 80;
|
|
@@ -4337,7 +4356,7 @@ function ScrollableHistory({
|
|
|
4337
4356
|
flexShrink: 0,
|
|
4338
4357
|
children: [
|
|
4339
4358
|
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)),
|
|
4359
|
+
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
4360
|
tail ? /* @__PURE__ */ jsx(AssistantTail, { text: tail, termWidth }) : null,
|
|
4342
4361
|
toolTail && toolStream ? /* @__PURE__ */ jsx(
|
|
4343
4362
|
ToolStreamBox,
|
|
@@ -6456,10 +6475,10 @@ function useDirectorFleetBridge({
|
|
|
6456
6475
|
let streamFlushTimer = null;
|
|
6457
6476
|
const flushStreamBufs = () => {
|
|
6458
6477
|
for (const [id, text] of streamBuf) {
|
|
6459
|
-
const
|
|
6460
|
-
if (!
|
|
6478
|
+
const cleaned = stripNextStepsBlock(text);
|
|
6479
|
+
if (!cleaned) continue;
|
|
6461
6480
|
const label = labelFor(labelsRef, id);
|
|
6462
|
-
enq({ type: "fleetMessage", id, text:
|
|
6481
|
+
enq({ type: "fleetMessage", id, text: cleaned });
|
|
6463
6482
|
if (streamFleetRef.current) {
|
|
6464
6483
|
enq({
|
|
6465
6484
|
type: "addEntry",
|
|
@@ -6468,7 +6487,7 @@ function useDirectorFleetBridge({
|
|
|
6468
6487
|
agentLabel: label.label,
|
|
6469
6488
|
agentColor: label.color,
|
|
6470
6489
|
icon: "\u{1F4AC}",
|
|
6471
|
-
text:
|
|
6490
|
+
text: cleaned
|
|
6472
6491
|
}
|
|
6473
6492
|
});
|
|
6474
6493
|
}
|
|
@@ -10100,7 +10119,6 @@ function App({
|
|
|
10100
10119
|
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
10101
10120
|
if (suggestion) {
|
|
10102
10121
|
autoSubmitStreakRef.current += 1;
|
|
10103
|
-
setDraft(suggestion, suggestion.length);
|
|
10104
10122
|
void (async () => {
|
|
10105
10123
|
const trimmed = suggestion.trim();
|
|
10106
10124
|
if (!trimmed) {
|
|
@@ -12014,7 +12032,6 @@ ${content}
|
|
|
12014
12032
|
while (stateRef.current.status !== "idle" && Date.now() - start < 1500) {
|
|
12015
12033
|
await new Promise((r) => setTimeout(r, 25));
|
|
12016
12034
|
}
|
|
12017
|
-
setDraft(res.runText, res.runText.length);
|
|
12018
12035
|
try {
|
|
12019
12036
|
await runBlocks(blocks2);
|
|
12020
12037
|
} finally {
|
|
@@ -12215,7 +12232,9 @@ User message:
|
|
|
12215
12232
|
viewportRows: state.viewportRows,
|
|
12216
12233
|
totalLines: state.totalLines,
|
|
12217
12234
|
onMeasure: (totalLines) => dispatch({ type: "setMeasuredLines", totalLines }),
|
|
12218
|
-
setSuggestions
|
|
12235
|
+
setSuggestions,
|
|
12236
|
+
autonomyMode: autonomyLive,
|
|
12237
|
+
autoSubmitCountdown: nextStepsAutoSubmitCountdown
|
|
12219
12238
|
}
|
|
12220
12239
|
) : /* @__PURE__ */ jsx(
|
|
12221
12240
|
History,
|
|
@@ -12224,7 +12243,9 @@ User message:
|
|
|
12224
12243
|
generation: state.historyGen,
|
|
12225
12244
|
streamingText: state.streamingText,
|
|
12226
12245
|
toolStream: state.toolStream,
|
|
12227
|
-
setSuggestions
|
|
12246
|
+
setSuggestions,
|
|
12247
|
+
autonomyMode: autonomyLive,
|
|
12248
|
+
autoSubmitCountdown: nextStepsAutoSubmitCountdown
|
|
12228
12249
|
}
|
|
12229
12250
|
),
|
|
12230
12251
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexShrink: 0, ref: bottomRegionRef, children: [
|