@wrongstack/tui 0.283.1 → 0.284.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +5 -52
- package/dist/index.js +71 -192
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,9 @@ import * as _wrongstack_core from '@wrongstack/core';
|
|
|
2
2
|
import { TokenSavingTier, Agent, SlashCommandRegistry, AttachmentStore, EventBus, TokenCounter, QueueStore, AutonomyStage, Director, Message, AutonomousCoordinator, CoordinatorEvent, SessionEvent } from '@wrongstack/core';
|
|
3
3
|
export { buildGoalPreamble } from '@wrongstack/core';
|
|
4
4
|
import { VisionAdapters } from '@wrongstack/runtime/vision';
|
|
5
|
+
import { SddRunControl, SddLifecycleResult } from '@wrongstack/sdd';
|
|
5
6
|
import React from 'react';
|
|
7
|
+
export { ParseNextStepsResult, ParsedNextStep, parseNextSteps } from '@wrongstack/tools/next-steps';
|
|
6
8
|
|
|
7
9
|
/** A single session row from the SessionRegistry, exposed via WebSocket. */
|
|
8
10
|
interface LiveSessionEntry {
|
|
@@ -402,14 +404,14 @@ interface RunTuiOptions {
|
|
|
402
404
|
* Access the active SDD parallel run's control surface (or null). The TUI's
|
|
403
405
|
* SIGINT handler uses it to stop a running `/sdd parallel` on the first Ctrl+C.
|
|
404
406
|
*/
|
|
405
|
-
getSddRun?: (() =>
|
|
407
|
+
getSddRun?: (() => SddRunControl | null) | undefined;
|
|
406
408
|
/**
|
|
407
409
|
* Apply a post-run SDD lifecycle op (clean / rollback / destroy) from the host.
|
|
408
410
|
* Drives the board overlay keys c / z / x so they work after the run ends.
|
|
409
411
|
*/
|
|
410
412
|
onSddLifecycle?: ((op: 'cleanup_worktrees' | 'rollback' | 'destroy', opts?: {
|
|
411
413
|
revertMerged?: boolean;
|
|
412
|
-
}) => Promise<
|
|
414
|
+
}) => Promise<SddLifecycleResult>) | undefined;
|
|
413
415
|
/**
|
|
414
416
|
* Subscribe to live per-iteration events from the eternal engine.
|
|
415
417
|
* Returns an unsubscribe function. TUI uses this to render each
|
|
@@ -905,53 +907,4 @@ declare function parseInline(text: string): InlineToken[];
|
|
|
905
907
|
*/
|
|
906
908
|
declare function replaySessionEvents(events: SessionEvent[], startId: number): HistoryEntry[];
|
|
907
909
|
|
|
908
|
-
|
|
909
|
-
* Unified next-steps suggestion parser.
|
|
910
|
-
*
|
|
911
|
-
* Three code paths feed into the suggestion store:
|
|
912
|
-
* 1. TUI rendering — entry.tsx parses only "<nextsteps>" from assistant output
|
|
913
|
-
* 2. REPL store — repl.ts parses only "<nextsteps>" from final agent output
|
|
914
|
-
* 3. /suggest output — suggest.ts parses LLM-generated numbered lists
|
|
915
|
-
*
|
|
916
|
-
* Heading mode (`requireHeading = true`):
|
|
917
|
-
* Assistant-output paths accept only balanced <nextsteps>...</nextsteps> blocks.
|
|
918
|
-
* Loose headings like "Next steps:" are intentionally ignored so `/next` only
|
|
919
|
-
* activates for the canonical machine-readable format.
|
|
920
|
-
*
|
|
921
|
-
* Raw mode (`requireHeading = false`):
|
|
922
|
-
* Parses numbered/bullet items from anywhere in text (subagent /suggest output).
|
|
923
|
-
*
|
|
924
|
-
* Supported assistant-output format:
|
|
925
|
-
* <nextsteps> (canonical XML tag format)
|
|
926
|
-
*/
|
|
927
|
-
interface ParsedNextStep {
|
|
928
|
-
index: number;
|
|
929
|
-
text: string;
|
|
930
|
-
/** Whether this item has auto="true" attribute for YOLO+auto autonomy mode. */
|
|
931
|
-
auto?: boolean;
|
|
932
|
-
}
|
|
933
|
-
interface ParseNextStepsResult {
|
|
934
|
-
/** Matched steps with their original index and stripped text. */
|
|
935
|
-
steps: ParsedNextStep[];
|
|
936
|
-
/** Flat string array — what gets stored in the suggestion store. */
|
|
937
|
-
texts: string[];
|
|
938
|
-
/**
|
|
939
|
-
* Content with the entire canonical "<nextsteps>" block removed.
|
|
940
|
-
* Used by entry.tsx to strip suggestions from the rendered message body.
|
|
941
|
-
*/
|
|
942
|
-
stripped: string;
|
|
943
|
-
/** Flat string array — texts of items with auto="true" attribute only. */
|
|
944
|
-
autoTexts: string[];
|
|
945
|
-
}
|
|
946
|
-
/**
|
|
947
|
-
* Parse canonical "<nextsteps>" blocks from assistant output (or raw numbered lines).
|
|
948
|
-
*
|
|
949
|
-
* @param content — raw assistant message text or subagent output
|
|
950
|
-
* @param strict — retained for compatibility; assistant-output paths always require the canonical XML tag.
|
|
951
|
-
* @param requireHeading — when true, a canonical XML tag must precede the item list.
|
|
952
|
-
* when false, numbered/bullet items are parsed from anywhere in text
|
|
953
|
-
* (used by /suggest subagent output which has no heading).
|
|
954
|
-
*/
|
|
955
|
-
declare function parseNextSteps(content: string, strict?: boolean, requireHeading?: boolean): ParseNextStepsResult;
|
|
956
|
-
|
|
957
|
-
export { type AuthCatalogRow, type AuthFlowIo, type AuthFlowResult, type AuthKeyRow, type AuthLocalPresetRow, type AuthOAuthKind, type AuthPanelHost, type AuthProviderRow, type ParseNextStepsResult, type ParsedNextStep, type PluginPickerItem, type RunTuiOptions, type Settings, parseInline, parseNextSteps, replaySessionEvents, runTui };
|
|
910
|
+
export { type AuthCatalogRow, type AuthFlowIo, type AuthFlowResult, type AuthKeyRow, type AuthLocalPresetRow, type AuthOAuthKind, type AuthPanelHost, type AuthProviderRow, type PluginPickerItem, type RunTuiOptions, type Settings, parseInline, replaySessionEvents, runTui };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { hasOpenTodos, writeErr, resolveProjectDir, wstackGlobalRoot, createHqPublisherFromEnv, startFleetTelemetryBridge, startBrainTelemetryBridge, startWorktreeTelemetryBridge, startToolTelemetryBridge, startCostTelemetryBridge, GlobalMailbox, resolveWstackPaths, loadGoal, InputBuilder, DefaultSessionRewinder, writeOut, formatTodosList, buildGoalPreamble, expectDefined as expectDefined$1, InputHistoryStore, DefaultSecretScrubber, INPUT_HISTORY_DEFAULT_MAX, DefaultPromptLoader, PromptUsageStore, getDesignKitLoader, clearActiveKit, clearPersistedActiveKit, recordOverrides, setDesignOverrides, loadActiveKit, isDesignStack, materializeTokens, applyTokenOverrides, setActiveKit, projectSlug, detectContinueIntent, resolveContinuation, shouldEnhance, enhanceUserPrompt, recentTextTurns, normalizedEqual, setBtwNote,
|
|
1
|
+
import { hasOpenTodos, writeErr, resolveProjectDir, wstackGlobalRoot, createHqPublisherFromEnv, startFleetTelemetryBridge, startBrainTelemetryBridge, startWorktreeTelemetryBridge, startToolTelemetryBridge, startCostTelemetryBridge, GlobalMailbox, resolveWstackPaths, loadGoal, InputBuilder, DefaultSessionRewinder, writeOut, formatTodosList, buildGoalPreamble, expectDefined as expectDefined$1, InputHistoryStore, DefaultSecretScrubber, INPUT_HISTORY_DEFAULT_MAX, DefaultPromptLoader, PromptUsageStore, getDesignKitLoader, clearActiveKit, clearPersistedActiveKit, recordOverrides, setDesignOverrides, loadActiveKit, isDesignStack, materializeTokens, applyTokenOverrides, setActiveKit, projectSlug, detectContinueIntent, resolveContinuation, shouldEnhance, enhanceUserPrompt, recentTextTurns, normalizedEqual, setBtwNote, buildChildEnv } from '@wrongstack/core';
|
|
2
2
|
export { buildGoalPreamble } from '@wrongstack/core';
|
|
3
3
|
import { Box as Box$1, useStdout, Static, useInput, useStdin, measureElement, Text as Text$1, render, useApp } from 'ink';
|
|
4
4
|
import { randomUUID } from 'crypto';
|
|
@@ -10,6 +10,10 @@ import { routeImagesForModel } from '@wrongstack/runtime/vision';
|
|
|
10
10
|
import { getIndexState, onIndexStateChange, getProcessRegistry } from '@wrongstack/tools';
|
|
11
11
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
12
12
|
import { getToolIcon, TOOL_ICON_CONFIG } from '@wrongstack/tools/tool-icons';
|
|
13
|
+
import { parseUnifiedDiffPreview } from '@wrongstack/tools/tool-diff';
|
|
14
|
+
import { parseNextSteps, stripNextStepsBlock } from '@wrongstack/tools/next-steps';
|
|
15
|
+
export { parseNextSteps } from '@wrongstack/tools/next-steps';
|
|
16
|
+
import { listBoards, getBoard, createBoard, addTask, removeTask, moveTask, updateTask, duplicateBoard, copyTaskToBoard, transferTaskToBoard } from '@wrongstack/kanban';
|
|
13
17
|
import { spawn } from 'child_process';
|
|
14
18
|
import * as v8 from 'v8';
|
|
15
19
|
import { readClipboardText, readClipboardImage } from '@wrongstack/runtime/clipboard';
|
|
@@ -1686,6 +1690,7 @@ function clampContextLoad(load) {
|
|
|
1686
1690
|
return Math.max(0, Math.min(1, load));
|
|
1687
1691
|
}
|
|
1688
1692
|
var MAX_TOOL_STREAM_RETAINED_CHARS = 1e5;
|
|
1693
|
+
var MAX_ASSISTANT_STREAM_RETAINED_CHARS = 16384;
|
|
1689
1694
|
var MAX_RETAINED_INPUT_CHARS = 2048;
|
|
1690
1695
|
var MAX_RETAINED_INPUT_DEPTH = 4;
|
|
1691
1696
|
var MAX_RETAINED_INPUT_ITEMS = 64;
|
|
@@ -2120,8 +2125,11 @@ function reducer(state, action) {
|
|
|
2120
2125
|
}
|
|
2121
2126
|
};
|
|
2122
2127
|
}
|
|
2123
|
-
case "streamDelta":
|
|
2124
|
-
|
|
2128
|
+
case "streamDelta": {
|
|
2129
|
+
const combined = state.streamingText + action.delta;
|
|
2130
|
+
const streamingText = combined.length > MAX_ASSISTANT_STREAM_RETAINED_CHARS ? combined.slice(-MAX_ASSISTANT_STREAM_RETAINED_CHARS) : combined;
|
|
2131
|
+
return { ...state, streamingText };
|
|
2132
|
+
}
|
|
2125
2133
|
case "streamReset":
|
|
2126
2134
|
return { ...state, streamingText: "" };
|
|
2127
2135
|
case "status":
|
|
@@ -4251,7 +4259,7 @@ var SPINNER_INTERVAL_MS = 250;
|
|
|
4251
4259
|
function tokenDisplayTotals(usage, currentRequest) {
|
|
4252
4260
|
const usageInput = usage ? usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0) : 0;
|
|
4253
4261
|
const usageOutput = usage?.output ?? 0;
|
|
4254
|
-
const fallbackInput = currentRequest ? currentRequest.input + currentRequest.cacheRead : 0;
|
|
4262
|
+
const fallbackInput = currentRequest ? currentRequest.input + currentRequest.cacheRead + (currentRequest.cacheWrite ?? 0) : 0;
|
|
4255
4263
|
return {
|
|
4256
4264
|
input: usageInput > 0 ? usageInput : fallbackInput,
|
|
4257
4265
|
output: usageOutput
|
|
@@ -6102,6 +6110,10 @@ function renderRow(row, focused, i) {
|
|
|
6102
6110
|
return /* @__PURE__ */ jsx(Text, { children: " " }, `r-${i}`);
|
|
6103
6111
|
}
|
|
6104
6112
|
}
|
|
6113
|
+
var URL_LINE_RE = /^https?:\/\/\S+$/;
|
|
6114
|
+
function isAuthFlowUrlLine(line) {
|
|
6115
|
+
return URL_LINE_RE.test(line.trim());
|
|
6116
|
+
}
|
|
6105
6117
|
function viewTitle(panel) {
|
|
6106
6118
|
switch (panel.view) {
|
|
6107
6119
|
case "list":
|
|
@@ -6177,16 +6189,19 @@ function AuthPanel({ panel }) {
|
|
|
6177
6189
|
] }) }) : null,
|
|
6178
6190
|
panel.view === "flow" ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
6179
6191
|
logWindow.length === 0 && !panel.flowDone ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Starting\u2026" }) : null,
|
|
6180
|
-
logWindow.map((line) =>
|
|
6181
|
-
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6192
|
+
logWindow.map((line) => {
|
|
6193
|
+
const isUrl = isAuthFlowUrlLine(line);
|
|
6194
|
+
return /* @__PURE__ */ jsx(
|
|
6195
|
+
Text,
|
|
6196
|
+
{
|
|
6197
|
+
wrap: isUrl ? "wrap" : "truncate-end",
|
|
6198
|
+
color: isUrl ? UI_COLORS.hint : line.startsWith("\u2717") ? UI_COLORS.error : line.startsWith("\u2713") ? UI_COLORS.active : void 0,
|
|
6199
|
+
dimColor: !isUrl && !line.startsWith("\u2717") && !line.startsWith("\u2713"),
|
|
6200
|
+
children: line
|
|
6201
|
+
},
|
|
6202
|
+
line
|
|
6203
|
+
);
|
|
6204
|
+
}),
|
|
6190
6205
|
panel.flowDone ? /* @__PURE__ */ jsxs(Text, { color: panel.flowOk ? UI_COLORS.active : UI_COLORS.error, children: [
|
|
6191
6206
|
panel.flowOk ? "\u2713 Done." : "\u2717 Not completed.",
|
|
6192
6207
|
" ",
|
|
@@ -8565,8 +8580,24 @@ function tailForDisplay(text, maxChars) {
|
|
|
8565
8580
|
}
|
|
8566
8581
|
var MAX_CODE_LINES = 80;
|
|
8567
8582
|
var DIFF_MAX_LINES = Number.POSITIVE_INFINITY;
|
|
8568
|
-
var DIFF_LINE_SAFETY_CAP = 4e3;
|
|
8569
8583
|
var DIFF_FALLBACK_WRAP_WIDTH = 100;
|
|
8584
|
+
var HARD_TAB_WIDTH = 8;
|
|
8585
|
+
function expandTabs(text, tabWidth = HARD_TAB_WIDTH) {
|
|
8586
|
+
if (!text.includes(" ")) return text;
|
|
8587
|
+
let out = "";
|
|
8588
|
+
let col = 0;
|
|
8589
|
+
for (const ch of text) {
|
|
8590
|
+
if (ch === " ") {
|
|
8591
|
+
const advance = tabWidth - col % tabWidth;
|
|
8592
|
+
out += " ".repeat(advance);
|
|
8593
|
+
col += advance;
|
|
8594
|
+
} else {
|
|
8595
|
+
out += ch;
|
|
8596
|
+
col += 1;
|
|
8597
|
+
}
|
|
8598
|
+
}
|
|
8599
|
+
return out;
|
|
8600
|
+
}
|
|
8570
8601
|
function CodeBlock({
|
|
8571
8602
|
code,
|
|
8572
8603
|
lang,
|
|
@@ -8580,7 +8611,8 @@ function CodeBlock({
|
|
|
8580
8611
|
const maxW = Math.max(20, Math.min(boxWidth - 4 - gutterW - 1, 120));
|
|
8581
8612
|
let carry = {};
|
|
8582
8613
|
const rows = lines.map((raw) => {
|
|
8583
|
-
const
|
|
8614
|
+
const expanded = expandTabs(raw);
|
|
8615
|
+
const display = expanded.length > maxW ? `${expanded.slice(0, maxW - 1)}\u2026` : expanded;
|
|
8584
8616
|
const r = highlightLine(display, lang, carry);
|
|
8585
8617
|
carry = r.carry;
|
|
8586
8618
|
return r.tokens;
|
|
@@ -8759,9 +8791,9 @@ function DiffBlock({
|
|
|
8759
8791
|
};
|
|
8760
8792
|
const textForDisplay = (row) => {
|
|
8761
8793
|
if ((row.kind === "add" || row.kind === "del" || row.kind === "ctx") && row.text.length > 0) {
|
|
8762
|
-
return row.text.slice(1) || " ";
|
|
8794
|
+
return expandTabs(row.text.slice(1)) || " ";
|
|
8763
8795
|
}
|
|
8764
|
-
return row.text || " ";
|
|
8796
|
+
return expandTabs(row.text) || " ";
|
|
8765
8797
|
};
|
|
8766
8798
|
const stats = showStats ? formatDiffStats(added, removed) : null;
|
|
8767
8799
|
const terminalWrapGuard = typeof contentWidth === "number" ? 1 : 0;
|
|
@@ -8831,64 +8863,7 @@ function DiffBlock({
|
|
|
8831
8863
|
] });
|
|
8832
8864
|
}
|
|
8833
8865
|
function parseUnifiedDiff(diff, maxLines) {
|
|
8834
|
-
|
|
8835
|
-
let oldLn = 0;
|
|
8836
|
-
let newLn = 0;
|
|
8837
|
-
for (const raw of diff.split("\n")) {
|
|
8838
|
-
const line = raw.replace(/\r$/, "");
|
|
8839
|
-
if (line.startsWith("+++") || line.startsWith("---")) continue;
|
|
8840
|
-
if (line.startsWith("diff --git") || line.startsWith("index ")) continue;
|
|
8841
|
-
if (line.startsWith("@@")) {
|
|
8842
|
-
const m = line.match(/^@@\s+-(\d+)(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s+@@/);
|
|
8843
|
-
if (m) {
|
|
8844
|
-
oldLn = Number.parseInt(m[1] ?? "0", 10) || 0;
|
|
8845
|
-
newLn = Number.parseInt(m[2] ?? "0", 10) || 0;
|
|
8846
|
-
}
|
|
8847
|
-
all.push({ kind: "hunk", text: truncMid(line, 60) });
|
|
8848
|
-
continue;
|
|
8849
|
-
}
|
|
8850
|
-
if (line.startsWith("+")) {
|
|
8851
|
-
all.push({ kind: "add", text: truncMid(line, DIFF_LINE_SAFETY_CAP), newLine: newLn });
|
|
8852
|
-
newLn++;
|
|
8853
|
-
continue;
|
|
8854
|
-
}
|
|
8855
|
-
if (line.startsWith("-")) {
|
|
8856
|
-
all.push({ kind: "del", text: truncMid(line, DIFF_LINE_SAFETY_CAP), oldLine: oldLn });
|
|
8857
|
-
oldLn++;
|
|
8858
|
-
continue;
|
|
8859
|
-
}
|
|
8860
|
-
if (line.startsWith("\\ No newline")) {
|
|
8861
|
-
all.push({ kind: "meta", text: line });
|
|
8862
|
-
continue;
|
|
8863
|
-
}
|
|
8864
|
-
if (line.length === 0) continue;
|
|
8865
|
-
all.push({
|
|
8866
|
-
kind: "ctx",
|
|
8867
|
-
text: truncMid(line, DIFF_LINE_SAFETY_CAP),
|
|
8868
|
-
oldLine: oldLn,
|
|
8869
|
-
newLine: newLn
|
|
8870
|
-
});
|
|
8871
|
-
oldLn++;
|
|
8872
|
-
newLn++;
|
|
8873
|
-
}
|
|
8874
|
-
const added = all.filter((row) => row.kind === "add").length;
|
|
8875
|
-
const removed = all.filter((row) => row.kind === "del").length;
|
|
8876
|
-
if (all.length === 0) {
|
|
8877
|
-
return { rows: [], hidden: 0, added: 0, removed: 0, hiddenAdded: 0, hiddenRemoved: 0 };
|
|
8878
|
-
}
|
|
8879
|
-
if (all.length <= maxLines) {
|
|
8880
|
-
return { rows: all, hidden: 0, added, removed, hiddenAdded: 0, hiddenRemoved: 0 };
|
|
8881
|
-
}
|
|
8882
|
-
const rows = all.slice(0, maxLines);
|
|
8883
|
-
const hiddenRows = all.slice(maxLines);
|
|
8884
|
-
return {
|
|
8885
|
-
rows,
|
|
8886
|
-
hidden: hiddenRows.length,
|
|
8887
|
-
added,
|
|
8888
|
-
removed,
|
|
8889
|
-
hiddenAdded: hiddenRows.filter((row) => row.kind === "add").length,
|
|
8890
|
-
hiddenRemoved: hiddenRows.filter((row) => row.kind === "del").length
|
|
8891
|
-
};
|
|
8866
|
+
return parseUnifiedDiffPreview(diff, maxLines);
|
|
8892
8867
|
}
|
|
8893
8868
|
function extractDiffPreview(toolName, output, input) {
|
|
8894
8869
|
if (!output) return void 0;
|
|
@@ -10940,118 +10915,6 @@ function Banner({
|
|
|
10940
10915
|
] })
|
|
10941
10916
|
] });
|
|
10942
10917
|
}
|
|
10943
|
-
|
|
10944
|
-
// src/components/suggestions.ts
|
|
10945
|
-
var NEXT_STEPS_TAG_RE = /<nextsteps>\s*\n+/i;
|
|
10946
|
-
var ITEM_RE = /^(?:(\d+)[.)]\s*|[-*•]\s*)(.+?)(\s+auto="true")?$/;
|
|
10947
|
-
var MAX_STEPS = 6;
|
|
10948
|
-
function parseNextSteps(content, strict = false, requireHeading = true) {
|
|
10949
|
-
if (requireHeading) {
|
|
10950
|
-
return parseWithHeading(content);
|
|
10951
|
-
}
|
|
10952
|
-
return parseRawNumbered(content);
|
|
10953
|
-
}
|
|
10954
|
-
function parseRawNumbered(content) {
|
|
10955
|
-
const lines = content.split("\n");
|
|
10956
|
-
const steps = [];
|
|
10957
|
-
const seenNumbers = /* @__PURE__ */ new Set();
|
|
10958
|
-
for (const rawLine of lines) {
|
|
10959
|
-
const line = rawLine.trim();
|
|
10960
|
-
if (!line) continue;
|
|
10961
|
-
const m = ITEM_RE.exec(line);
|
|
10962
|
-
if (!m) continue;
|
|
10963
|
-
const numPart = m[1];
|
|
10964
|
-
const text = m[2].trim();
|
|
10965
|
-
const hasAuto = !!m[3];
|
|
10966
|
-
let index;
|
|
10967
|
-
if (numPart !== void 0) {
|
|
10968
|
-
index = Number.parseInt(numPart, 10);
|
|
10969
|
-
} else {
|
|
10970
|
-
index = steps.length + 1;
|
|
10971
|
-
}
|
|
10972
|
-
if (seenNumbers.has(index)) continue;
|
|
10973
|
-
if (text.length < 3) continue;
|
|
10974
|
-
seenNumbers.add(index);
|
|
10975
|
-
steps.push({ index, text, auto: hasAuto });
|
|
10976
|
-
if (steps.length >= MAX_STEPS) break;
|
|
10977
|
-
}
|
|
10978
|
-
return {
|
|
10979
|
-
steps,
|
|
10980
|
-
texts: steps.map((s2) => s2.text),
|
|
10981
|
-
stripped: content,
|
|
10982
|
-
autoTexts: steps.filter((s2) => s2.auto).map((s2) => s2.text)
|
|
10983
|
-
};
|
|
10984
|
-
}
|
|
10985
|
-
function parseWithHeading(content, _strict) {
|
|
10986
|
-
const headingMatch = NEXT_STEPS_TAG_RE.exec(content);
|
|
10987
|
-
if (!headingMatch) {
|
|
10988
|
-
return { steps: [], texts: [], stripped: content, autoTexts: [] };
|
|
10989
|
-
}
|
|
10990
|
-
const headingEnd = headingMatch.index + headingMatch[0].length;
|
|
10991
|
-
const afterHeading = content.slice(headingEnd);
|
|
10992
|
-
const lines = afterHeading.split("\n");
|
|
10993
|
-
const steps = [];
|
|
10994
|
-
const seenNumbers = /* @__PURE__ */ new Set();
|
|
10995
|
-
for (const rawLine of lines) {
|
|
10996
|
-
const line = rawLine.trim();
|
|
10997
|
-
if (!line) continue;
|
|
10998
|
-
const m = ITEM_RE.exec(line);
|
|
10999
|
-
if (!m) break;
|
|
11000
|
-
const numPart = m[1];
|
|
11001
|
-
const text = m[2].trim();
|
|
11002
|
-
const hasAuto = !!m[3];
|
|
11003
|
-
let index;
|
|
11004
|
-
if (numPart !== void 0) {
|
|
11005
|
-
index = Number.parseInt(numPart, 10);
|
|
11006
|
-
} else {
|
|
11007
|
-
index = steps.length + 1;
|
|
11008
|
-
}
|
|
11009
|
-
if (seenNumbers.has(index)) continue;
|
|
11010
|
-
if (text.length < 3) continue;
|
|
11011
|
-
seenNumbers.add(index);
|
|
11012
|
-
steps.push({ index, text, auto: hasAuto });
|
|
11013
|
-
if (steps.length >= MAX_STEPS) break;
|
|
11014
|
-
}
|
|
11015
|
-
if (steps.length === 0) {
|
|
11016
|
-
return { steps: [], texts: [], stripped: content, autoTexts: [] };
|
|
11017
|
-
}
|
|
11018
|
-
if (!afterHeading.includes("</nextsteps>")) {
|
|
11019
|
-
return { steps: [], texts: [], stripped: content, autoTexts: [] };
|
|
11020
|
-
}
|
|
11021
|
-
const texts = steps.map((s2) => s2.text);
|
|
11022
|
-
const autoTexts = steps.filter((s2) => s2.auto).map((s2) => s2.text);
|
|
11023
|
-
const blockStart = headingMatch.index;
|
|
11024
|
-
const blockEnd = headingMatch[0].length + findBlockEnd(afterHeading, steps.length);
|
|
11025
|
-
const stripped = (content.slice(0, blockStart) + content.slice(blockStart + blockEnd)).replace(/\n{3,}/g, "\n\n").trim();
|
|
11026
|
-
return { steps, texts, stripped, autoTexts };
|
|
11027
|
-
}
|
|
11028
|
-
function findBlockEnd(afterHeading, stepCount) {
|
|
11029
|
-
const closeIdx = afterHeading.indexOf("</nextsteps>");
|
|
11030
|
-
if (closeIdx !== -1) {
|
|
11031
|
-
let end = closeIdx + "</nextsteps>".length;
|
|
11032
|
-
if (afterHeading[end] === "\n") end += 1;
|
|
11033
|
-
return end;
|
|
11034
|
-
}
|
|
11035
|
-
const lines = afterHeading.split("\n");
|
|
11036
|
-
let consumed = 0;
|
|
11037
|
-
let found = 0;
|
|
11038
|
-
for (const rawLine of lines) {
|
|
11039
|
-
const line = rawLine.trim();
|
|
11040
|
-
if (!line) break;
|
|
11041
|
-
const m = ITEM_RE.exec(line);
|
|
11042
|
-
if (!m) break;
|
|
11043
|
-
consumed += rawLine.length + 1;
|
|
11044
|
-
found++;
|
|
11045
|
-
if (found >= stepCount) {
|
|
11046
|
-
consumed -= 1;
|
|
11047
|
-
break;
|
|
11048
|
-
}
|
|
11049
|
-
}
|
|
11050
|
-
return consumed;
|
|
11051
|
-
}
|
|
11052
|
-
function stripNextStepsBlock(text) {
|
|
11053
|
-
return text.replace(/<nextsteps\b[^>]*>[\s\S]*?<\/nextsteps>/gi, "").replace(/<nextsteps\b[^>]*\/?>/gi, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
11054
|
-
}
|
|
11055
10918
|
function brainStatusStyle(status) {
|
|
11056
10919
|
switch (status) {
|
|
11057
10920
|
case "thinking":
|
|
@@ -18746,7 +18609,9 @@ function App({
|
|
|
18746
18609
|
};
|
|
18747
18610
|
}, [events]);
|
|
18748
18611
|
const maxContext = activeMaxContext ?? agent.ctx.provider.capabilities.maxContext;
|
|
18749
|
-
const
|
|
18612
|
+
const currentRequestTokens = tokenCounter?.currentRequestTokens();
|
|
18613
|
+
const currentCacheWrite = currentRequestTokens?.cacheWrite ?? 0;
|
|
18614
|
+
const currentContextTokens = (currentRequestTokens?.input ?? 0) + (currentRequestTokens?.cacheRead ?? 0) + currentCacheWrite;
|
|
18750
18615
|
const contextWindow = useMemo(() => {
|
|
18751
18616
|
void state.contextChipVersion;
|
|
18752
18617
|
return currentContextTokens > 0 && maxContext > 0 ? { used: currentContextTokens, max: maxContext } : void 0;
|
|
@@ -22911,6 +22776,7 @@ async function runTui(opts) {
|
|
|
22911
22776
|
}
|
|
22912
22777
|
}
|
|
22913
22778
|
let cleaned = false;
|
|
22779
|
+
let inkInstance = null;
|
|
22914
22780
|
const cleanup = () => {
|
|
22915
22781
|
if (cleaned) return;
|
|
22916
22782
|
cleaned = true;
|
|
@@ -22932,12 +22798,21 @@ async function runTui(opts) {
|
|
|
22932
22798
|
const forceExitViaRapidCtrlC = () => {
|
|
22933
22799
|
detachListeners();
|
|
22934
22800
|
unregisterTuiClient();
|
|
22801
|
+
try {
|
|
22802
|
+
opts.agent.ctx.session.flushSync?.();
|
|
22803
|
+
} catch {
|
|
22804
|
+
}
|
|
22935
22805
|
stdout.write(BRACKETED_PASTE_OFF);
|
|
22936
22806
|
stdout.write(MOUSE_OFF);
|
|
22937
22807
|
process.exit(130);
|
|
22938
22808
|
};
|
|
22939
22809
|
const signals = ["SIGTERM", "SIGHUP", "SIGINT"];
|
|
22940
|
-
const signalHandler = () =>
|
|
22810
|
+
const signalHandler = () => {
|
|
22811
|
+
cleanup();
|
|
22812
|
+
inkInstance?.unmount();
|
|
22813
|
+
const sig = setTimeout(() => process.exit(143), 5e3);
|
|
22814
|
+
sig.unref();
|
|
22815
|
+
};
|
|
22941
22816
|
const exitHandler = () => cleanup();
|
|
22942
22817
|
const sigintHandler = () => {
|
|
22943
22818
|
const now = Date.now();
|
|
@@ -22949,6 +22824,9 @@ async function runTui(opts) {
|
|
|
22949
22824
|
return;
|
|
22950
22825
|
}
|
|
22951
22826
|
cleanup();
|
|
22827
|
+
inkInstance?.unmount();
|
|
22828
|
+
const sig = setTimeout(() => process.exit(130), 5e3);
|
|
22829
|
+
sig.unref();
|
|
22952
22830
|
};
|
|
22953
22831
|
process.on("SIGINT", sigintHandler);
|
|
22954
22832
|
for (const s2 of ["SIGTERM", "SIGHUP"]) {
|
|
@@ -23090,7 +22968,7 @@ async function runTui(opts) {
|
|
|
23090
22968
|
};
|
|
23091
22969
|
const requestExit = (code) => {
|
|
23092
22970
|
onExit(code);
|
|
23093
|
-
|
|
22971
|
+
inkInstance?.unmount();
|
|
23094
22972
|
hardExitTimer = setTimeout(() => process.exit(code), 5e3);
|
|
23095
22973
|
hardExitTimer.unref();
|
|
23096
22974
|
};
|
|
@@ -23211,6 +23089,7 @@ async function runTui(opts) {
|
|
|
23211
23089
|
}),
|
|
23212
23090
|
{ exitOnCtrlC: false, stdin: inkStdin }
|
|
23213
23091
|
);
|
|
23092
|
+
inkInstance = instance;
|
|
23214
23093
|
} catch (err) {
|
|
23215
23094
|
writeErr(
|
|
23216
23095
|
`wstack: TUI failed to start: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -23422,6 +23301,6 @@ function eventToEntry(ev, pendingTools, completedTools) {
|
|
|
23422
23301
|
}
|
|
23423
23302
|
}
|
|
23424
23303
|
|
|
23425
|
-
export { parseInline,
|
|
23304
|
+
export { parseInline, replaySessionEvents, runTui };
|
|
23426
23305
|
//# sourceMappingURL=index.js.map
|
|
23427
23306
|
//# sourceMappingURL=index.js.map
|