@wrongstack/tui 0.280.1 → 0.281.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 +8 -2
- package/dist/index.js +697 -281
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
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, getDesignKitLoader, clearActiveKit, clearPersistedActiveKit, recordOverrides, setDesignOverrides, loadActiveKit, isDesignStack, materializeTokens, applyTokenOverrides, setActiveKit, projectSlug, shouldEnhance, enhanceUserPrompt, recentTextTurns, normalizedEqual, setBtwNote, buildChildEnv, DefaultPromptLoader, PromptUsageStore } from '@wrongstack/core';
|
|
1
|
+
import { hasOpenTodos, writeErr, resolveProjectDir, wstackGlobalRoot, createHqPublisherFromEnv, startFleetTelemetryBridge, startBrainTelemetryBridge, startWorktreeTelemetryBridge, startToolTelemetryBridge, startCostTelemetryBridge, GlobalMailbox, resolveWstackPaths, loadGoal, InputHistoryStore, DefaultSecretScrubber, INPUT_HISTORY_DEFAULT_MAX, InputBuilder, DefaultSessionRewinder, writeOut, formatTodosList, buildGoalPreamble, expectDefined as expectDefined$1, getDesignKitLoader, clearActiveKit, clearPersistedActiveKit, recordOverrides, setDesignOverrides, loadActiveKit, isDesignStack, materializeTokens, applyTokenOverrides, setActiveKit, projectSlug, shouldEnhance, enhanceUserPrompt, recentTextTurns, normalizedEqual, setBtwNote, buildChildEnv, DefaultPromptLoader, PromptUsageStore } 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';
|
|
@@ -423,6 +423,93 @@ function pickRandomTuiThinkingWord(previous) {
|
|
|
423
423
|
const idx = Math.floor(Math.random() * list.length);
|
|
424
424
|
return list[idx] ?? list[0] ?? DEFAULT_TUI_THINKING_WORD;
|
|
425
425
|
}
|
|
426
|
+
|
|
427
|
+
// src/components/animation-style.tsx
|
|
428
|
+
var HUE_WHEEL = [
|
|
429
|
+
"#f38ba8",
|
|
430
|
+
// red
|
|
431
|
+
"#eba0ac",
|
|
432
|
+
// maroon
|
|
433
|
+
"#fab387",
|
|
434
|
+
// peach
|
|
435
|
+
"#f9e2af",
|
|
436
|
+
// yellow
|
|
437
|
+
"#a6e3a1",
|
|
438
|
+
// green
|
|
439
|
+
"#94e2d5",
|
|
440
|
+
// teal
|
|
441
|
+
"#89dceb",
|
|
442
|
+
// sky
|
|
443
|
+
"#89b4fa",
|
|
444
|
+
// blue
|
|
445
|
+
"#b4befe",
|
|
446
|
+
// lavender
|
|
447
|
+
"#cba6f7",
|
|
448
|
+
// mauve
|
|
449
|
+
"#f5c2e7",
|
|
450
|
+
// pink
|
|
451
|
+
"#f2cdcd"
|
|
452
|
+
// flamingo
|
|
453
|
+
];
|
|
454
|
+
var ACCENT = "#fab387";
|
|
455
|
+
var DIM = "#3b3b4f";
|
|
456
|
+
var BREATHE_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
457
|
+
var DOTS_FRAMES = ["", ".", "..", "...", "..", "."];
|
|
458
|
+
var ANIMATION_STYLES = ["rainbow", "wave", "pulse", "dots", "breathe"];
|
|
459
|
+
var ANIMATION_STYLE_DESCS = {
|
|
460
|
+
rainbow: "Per-glyph hue cycle (default)",
|
|
461
|
+
wave: "Single-color brightness sweep",
|
|
462
|
+
pulse: "Whole-text brightness pulse",
|
|
463
|
+
dots: "Trailing dots ellipsis (. .. ... .. .)",
|
|
464
|
+
breathe: "Spinning braille glyph prefix, flat text"
|
|
465
|
+
};
|
|
466
|
+
var CYCLE_INTERVAL_SECONDS = 12;
|
|
467
|
+
var CYCLE_TICK_INTERVAL_MS = 1e3;
|
|
468
|
+
var CYCLE_ORDER = ["wave", "pulse", "dots", "breathe"];
|
|
469
|
+
function styleForCycleTick(tick) {
|
|
470
|
+
const idx = Math.max(0, Math.floor(tick / CYCLE_INTERVAL_SECONDS));
|
|
471
|
+
const i = idx % CYCLE_ORDER.length;
|
|
472
|
+
return CYCLE_ORDER[i] ?? CYCLE_ORDER[0];
|
|
473
|
+
}
|
|
474
|
+
function mixHex(a, b, t) {
|
|
475
|
+
const ca = parseHex(a);
|
|
476
|
+
const cb = parseHex(b);
|
|
477
|
+
if (!ca || !cb) return b;
|
|
478
|
+
const k = Math.max(0, Math.min(1, t));
|
|
479
|
+
const r = Math.round(ca[0] + (cb[0] - ca[0]) * k);
|
|
480
|
+
const g = Math.round(ca[1] + (cb[1] - ca[1]) * k);
|
|
481
|
+
const bl = Math.round(ca[2] + (cb[2] - ca[2]) * k);
|
|
482
|
+
return `#${toHex(r)}${toHex(g)}${toHex(bl)}`;
|
|
483
|
+
}
|
|
484
|
+
function parseHex(s2) {
|
|
485
|
+
if (!/^#[0-9a-f]{6}$/i.test(s2)) return null;
|
|
486
|
+
return [parseInt(s2.slice(1, 3), 16), parseInt(s2.slice(3, 5), 16), parseInt(s2.slice(5, 7), 16)];
|
|
487
|
+
}
|
|
488
|
+
function toHex(n) {
|
|
489
|
+
return n.toString(16).padStart(2, "0");
|
|
490
|
+
}
|
|
491
|
+
function waveColor(charIndex, phase, length) {
|
|
492
|
+
const t = length > 0 ? charIndex / length : 0;
|
|
493
|
+
const sweep = Math.sin(t * Math.PI * 2 + phase / 10);
|
|
494
|
+
return mixHex(DIM, ACCENT, (sweep + 1) / 2);
|
|
495
|
+
}
|
|
496
|
+
function pulseColor(phase) {
|
|
497
|
+
const t = phase % 16 / 16;
|
|
498
|
+
const k = 0.5 - 0.5 * Math.cos(t * Math.PI * 2);
|
|
499
|
+
return mixHex(DIM, ACCENT, k);
|
|
500
|
+
}
|
|
501
|
+
function stripTrailingDots(text) {
|
|
502
|
+
let s2 = text;
|
|
503
|
+
while (s2.length > 0) {
|
|
504
|
+
const last = s2.charAt(s2.length - 1);
|
|
505
|
+
if (last === "." || last === " " || last === "\u2026" || last === "\xB7") {
|
|
506
|
+
s2 = s2.slice(0, -1);
|
|
507
|
+
} else {
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
return s2;
|
|
512
|
+
}
|
|
426
513
|
var DELAY_PRESETS_MS = [0, 15e3, 3e4, 45e3, 6e4, 12e4];
|
|
427
514
|
var SETTINGS_MODES = ["off", "suggest", "auto"];
|
|
428
515
|
var LOG_LEVELS = ["error", "warn", "info", "debug", "trace"];
|
|
@@ -473,12 +560,17 @@ function formatMultiDiffSummaryThreshold(n) {
|
|
|
473
560
|
function formatEnhanceDelay(ms) {
|
|
474
561
|
return `${Math.round(ms / 1e3)}s`;
|
|
475
562
|
}
|
|
563
|
+
var ANIMATION_STYLE_CHOICES = [...ANIMATION_STYLES, "cycle"];
|
|
564
|
+
function formatAnimationStyle(style) {
|
|
565
|
+
if (style === "cycle") return "cycle (shuffle all)";
|
|
566
|
+
return ANIMATION_STYLE_DESCS[style];
|
|
567
|
+
}
|
|
476
568
|
var MODE_DESC = {
|
|
477
569
|
off: "Agent stops after each turn (normal)",
|
|
478
570
|
suggest: "Shows next-step suggestions after each turn",
|
|
479
571
|
auto: "Self-driving \u2014 agent continues automatically"
|
|
480
572
|
};
|
|
481
|
-
var SETTINGS_FIELD_COUNT =
|
|
573
|
+
var SETTINGS_FIELD_COUNT = 37;
|
|
482
574
|
var THINKING_WORD_FIELD = 22;
|
|
483
575
|
var SETTINGS_PICKER_JUMP_CHORDS = Object.freeze([
|
|
484
576
|
// ── Ctrl chords (Tools / Reasoning / Fleet / Debug sections) ──
|
|
@@ -514,7 +606,12 @@ var SETTINGS_PICKER_JUMP_CHORDS = Object.freeze([
|
|
|
514
606
|
{ mod: "alt-shift", letter: "l", field: 31, label: "Log level" },
|
|
515
607
|
{ mod: "alt-shift", letter: "a", field: 32, label: "Audit level" },
|
|
516
608
|
{ mod: "alt-shift", letter: "b", field: 33, label: "Stream debug logging" },
|
|
517
|
-
{ mod: "alt-shift", letter: "g", field: 35, label: "Config scope" }
|
|
609
|
+
{ mod: "alt-shift", letter: "g", field: 35, label: "Config scope" },
|
|
610
|
+
// ── Unmapped / Chord for Animation ──
|
|
611
|
+
// 'N' for a**N**imation — Alt+N is unlisted (only Alt+B,C,D,E,F are taken).
|
|
612
|
+
// Animation sits in the UX section alongside the rest of the visible-only
|
|
613
|
+
// toggle rows and is newly added after the Debug section at field 36.
|
|
614
|
+
{ mod: "alt", letter: "n", field: 36, label: "Animation" }
|
|
518
615
|
]);
|
|
519
616
|
function settingsPickerJumpField(mod, letter) {
|
|
520
617
|
const lower = letter.toLowerCase();
|
|
@@ -636,8 +733,10 @@ var SETTINGS_FIELD_LABELS = [
|
|
|
636
733
|
// 33
|
|
637
734
|
"Statusline",
|
|
638
735
|
// 34
|
|
639
|
-
"Config scope"
|
|
736
|
+
"Config scope",
|
|
640
737
|
// 35
|
|
738
|
+
"Animation"
|
|
739
|
+
// 36
|
|
641
740
|
];
|
|
642
741
|
function resolveSettingsFieldValue(field, input) {
|
|
643
742
|
const raw = input.trim().toLowerCase();
|
|
@@ -683,7 +782,8 @@ function resolveSettingsFieldValue(field, input) {
|
|
|
683
782
|
[31, "logLevel", LOG_LEVELS],
|
|
684
783
|
[32, "auditLevel", AUDIT_LEVELS],
|
|
685
784
|
[34, "statuslineMode", STATUSLINE_MODES],
|
|
686
|
-
[35, "configScope", CONFIG_SCOPES]
|
|
785
|
+
[35, "configScope", CONFIG_SCOPES],
|
|
786
|
+
[36, "animationStyle", ANIMATION_STYLE_CHOICES]
|
|
687
787
|
];
|
|
688
788
|
for (const [f, key, values] of ENUM_FIELDS) {
|
|
689
789
|
if (field !== f) continue;
|
|
@@ -776,7 +876,8 @@ function getSettingsFieldValue(values, field) {
|
|
|
776
876
|
[31, "logLevel"],
|
|
777
877
|
[32, "auditLevel"],
|
|
778
878
|
[34, "statuslineMode"],
|
|
779
|
-
[35, "configScope"]
|
|
879
|
+
[35, "configScope"],
|
|
880
|
+
[36, "animationStyle"]
|
|
780
881
|
];
|
|
781
882
|
for (const [f, key] of ENUM_KEYS) {
|
|
782
883
|
if (field !== f) continue;
|
|
@@ -835,7 +936,7 @@ var SETTINGS_SECTIONS = [
|
|
|
835
936
|
},
|
|
836
937
|
{
|
|
837
938
|
name: "Debug",
|
|
838
|
-
fields: [33, 34, 35]
|
|
939
|
+
fields: [33, 34, 35, 36]
|
|
839
940
|
}
|
|
840
941
|
];
|
|
841
942
|
function formatAllSettingsSummary(values) {
|
|
@@ -890,7 +991,8 @@ var SETTINGS_DEFAULTS = Object.freeze({
|
|
|
890
991
|
reasoningPreserve: false,
|
|
891
992
|
thinkingWord: "thinking",
|
|
892
993
|
cacheTtl: "default",
|
|
893
|
-
configScope: "global"
|
|
994
|
+
configScope: "global",
|
|
995
|
+
animationStyle: "rainbow"
|
|
894
996
|
});
|
|
895
997
|
function resetSettingsFieldValue(field) {
|
|
896
998
|
const result = getSettingsFieldValue(SETTINGS_DEFAULTS, field);
|
|
@@ -936,7 +1038,8 @@ function buildResetPatch(field) {
|
|
|
936
1038
|
[32, "auditLevel"],
|
|
937
1039
|
[33, "debugStream"],
|
|
938
1040
|
[34, "statuslineMode"],
|
|
939
|
-
[35, "configScope"]
|
|
1041
|
+
[35, "configScope"],
|
|
1042
|
+
[36, "animationStyle"]
|
|
940
1043
|
];
|
|
941
1044
|
for (const [f, key] of KEY_MAP) {
|
|
942
1045
|
if (f === field) {
|
|
@@ -986,6 +1089,7 @@ function SettingsPicker({
|
|
|
986
1089
|
debugStream,
|
|
987
1090
|
statuslineMode,
|
|
988
1091
|
configScope,
|
|
1092
|
+
animationStyle,
|
|
989
1093
|
hint
|
|
990
1094
|
}) {
|
|
991
1095
|
const boolVal = (v) => v ? "on" : "off";
|
|
@@ -1183,6 +1287,11 @@ function SettingsPicker({
|
|
|
1183
1287
|
label: "Config scope",
|
|
1184
1288
|
value: configScope,
|
|
1185
1289
|
detail: "global (~/.wrongstack/) or project (.wrongstack/)"
|
|
1290
|
+
},
|
|
1291
|
+
{
|
|
1292
|
+
label: "Animation",
|
|
1293
|
+
value: animationStyle,
|
|
1294
|
+
detail: formatAnimationStyle(animationStyle)
|
|
1186
1295
|
}
|
|
1187
1296
|
];
|
|
1188
1297
|
const fieldRowIndex = [];
|
|
@@ -1969,6 +2078,7 @@ function reducer(state, action) {
|
|
|
1969
2078
|
buffer: "",
|
|
1970
2079
|
cursor: 0,
|
|
1971
2080
|
historyIndex: 0,
|
|
2081
|
+
historyDraft: "",
|
|
1972
2082
|
picker: { open: false, query: "", matches: [], selected: 0 },
|
|
1973
2083
|
slashPicker: { open: false, query: "", matches: [], selected: 0 }
|
|
1974
2084
|
};
|
|
@@ -2160,13 +2270,34 @@ function reducer(state, action) {
|
|
|
2160
2270
|
if (state.inputHistory.length === 0) return state;
|
|
2161
2271
|
const next = Math.min(state.historyIndex + 1, state.inputHistory.length);
|
|
2162
2272
|
const entry = state.inputHistory[next - 1] ?? "";
|
|
2163
|
-
|
|
2273
|
+
const historyDraft = state.historyIndex === 0 ? state.buffer : state.historyDraft;
|
|
2274
|
+
return {
|
|
2275
|
+
...state,
|
|
2276
|
+
historyIndex: next,
|
|
2277
|
+
buffer: entry,
|
|
2278
|
+
cursor: entry.length,
|
|
2279
|
+
historyDraft
|
|
2280
|
+
};
|
|
2164
2281
|
}
|
|
2165
2282
|
case "historyDown": {
|
|
2166
2283
|
if (state.historyIndex === 0) return state;
|
|
2167
2284
|
const next = state.historyIndex - 1;
|
|
2168
|
-
const entry = next === 0 ?
|
|
2169
|
-
return {
|
|
2285
|
+
const entry = next === 0 ? state.historyDraft : state.inputHistory[next - 1] ?? "";
|
|
2286
|
+
return {
|
|
2287
|
+
...state,
|
|
2288
|
+
historyIndex: next,
|
|
2289
|
+
buffer: entry,
|
|
2290
|
+
cursor: entry.length,
|
|
2291
|
+
// Clear the draft snapshot once we're back at the buffer; the next
|
|
2292
|
+
// Up will capture whatever the user has typed by then.
|
|
2293
|
+
historyDraft: next === 0 ? "" : state.historyDraft
|
|
2294
|
+
};
|
|
2295
|
+
}
|
|
2296
|
+
case "setInputHistory": {
|
|
2297
|
+
return { ...state, inputHistory: action.entries.slice(0, 100) };
|
|
2298
|
+
}
|
|
2299
|
+
case "clearInputHistory": {
|
|
2300
|
+
return { ...state, inputHistory: [], historyIndex: 0, historyDraft: "" };
|
|
2170
2301
|
}
|
|
2171
2302
|
case "modelPickerOpen":
|
|
2172
2303
|
return {
|
|
@@ -2458,6 +2589,7 @@ function reducer(state, action) {
|
|
|
2458
2589
|
filter: "",
|
|
2459
2590
|
cacheTtl: action.cacheTtl,
|
|
2460
2591
|
configScope: action.configScope,
|
|
2592
|
+
animationStyle: action.animationStyle,
|
|
2461
2593
|
hint: void 0
|
|
2462
2594
|
}
|
|
2463
2595
|
};
|
|
@@ -2815,6 +2947,19 @@ function reducer(state, action) {
|
|
|
2815
2947
|
}
|
|
2816
2948
|
};
|
|
2817
2949
|
}
|
|
2950
|
+
if (f === 36) {
|
|
2951
|
+
const i = ANIMATION_STYLE_CHOICES.indexOf(sp.animationStyle);
|
|
2952
|
+
const base = i < 0 ? 0 : i;
|
|
2953
|
+
const next = (base + action.delta + ANIMATION_STYLE_CHOICES.length) % ANIMATION_STYLE_CHOICES.length;
|
|
2954
|
+
return {
|
|
2955
|
+
...state,
|
|
2956
|
+
settingsPicker: {
|
|
2957
|
+
...sp,
|
|
2958
|
+
animationStyle: expectDefined$1(ANIMATION_STYLE_CHOICES[next]),
|
|
2959
|
+
hint: void 0
|
|
2960
|
+
}
|
|
2961
|
+
};
|
|
2962
|
+
}
|
|
2818
2963
|
return state;
|
|
2819
2964
|
}
|
|
2820
2965
|
case "settingsValueSet": {
|
|
@@ -3902,6 +4047,7 @@ function StatusBar({
|
|
|
3902
4047
|
version,
|
|
3903
4048
|
state,
|
|
3904
4049
|
thinkingWord,
|
|
4050
|
+
thinkingAnimationStyle,
|
|
3905
4051
|
tokenCounter,
|
|
3906
4052
|
hint,
|
|
3907
4053
|
queueCount = 0,
|
|
@@ -3980,14 +4126,31 @@ function StatusBar({
|
|
|
3980
4126
|
return () => clearInterval(t);
|
|
3981
4127
|
}, [state]);
|
|
3982
4128
|
const spinner = expectDefined$1(SPINNER_FRAMES[spinnerIdx]);
|
|
3983
|
-
const
|
|
4129
|
+
const animationStyle = thinkingAnimationStyle ?? "rainbow";
|
|
4130
|
+
const [cycleTick, setCycleTick] = useState(0);
|
|
4131
|
+
useEffect(() => {
|
|
4132
|
+
if (animationStyle !== "cycle") return;
|
|
4133
|
+
if (state === "idle" || state === "aborting") return;
|
|
4134
|
+
const t = setInterval(() => setCycleTick((n) => n + 1), CYCLE_TICK_INTERVAL_MS);
|
|
4135
|
+
return () => clearInterval(t);
|
|
4136
|
+
}, [animationStyle, state]);
|
|
4137
|
+
const { label: stateLabel, color: stateColor } = stateChip(
|
|
4138
|
+
state,
|
|
4139
|
+
fleet?.running ?? 0,
|
|
4140
|
+
thinkingWord
|
|
4141
|
+
);
|
|
3984
4142
|
const statePrefix = state === "idle" || state === "aborting" ? "\u25CF" : spinner;
|
|
3985
4143
|
const thinking = state === "running" || state === "streaming";
|
|
3986
4144
|
const hasAutoProceed = autoProceedCountdown != null && autoProceedCountdown > 0;
|
|
3987
|
-
const hasSecondLine = yolo && showChip("yolo") || autonomy && autonomy !== "off" && showChip("autonomy") || eternalStage != null && showChip("eternal_stage") || startedAt != null && showChip("elapsed") || git !== null && git !== void 0 && showChip("git") || projectName !== void 0 && projectName.length > 0 && showChip("project") || workingDir !== void 0 && workingDir.length > 0 && showChip("working_dir") || goalSummary !== null && goalSummary !== void 0 && showChip("goal") || !!modeLabel && showChip("mode") || hasAutoProceed && showChip("auto_proceed") || tokenSavingMode && showChip("token_saving") || typeof toolCount === "number" && toolCount > 0 && showChip("tools") || sessionCount != null && sessionCount > 0 && showChip("sessions");
|
|
4145
|
+
const hasSecondLine = yolo && showChip("yolo") || autonomy && autonomy !== "off" && showChip("autonomy") || eternalStage != null && showChip("eternal_stage") || startedAt != null && showChip("elapsed") || git !== null && git !== void 0 && showChip("git") || projectName !== void 0 && projectName.length > 0 && showChip("project") || workingDir !== void 0 && workingDir.length > 0 && showChip("working_dir") || goalSummary !== null && goalSummary !== void 0 && showChip("goal") || !!modeLabel && showChip("mode") || hasAutoProceed && showChip("auto_proceed") || tokenSavingMode !== void 0 && tokenSavingMode !== "off" && showChip("token_saving") || typeof toolCount === "number" && toolCount > 0 && showChip("tools") || sessionCount != null && sessionCount > 0 && showChip("sessions");
|
|
3988
4146
|
const fleetHasActivity = fleet && (fleet.running > 0 || fleet.idle > 0 || fleet.pending > 0 || fleet.completed > 0) || subagentCount > 0;
|
|
3989
4147
|
const showBrain = isStreamChipVisible("brain", brain, hiddenSet, visibleChips);
|
|
3990
|
-
const showDebugStream = isStreamChipVisible(
|
|
4148
|
+
const showDebugStream = isStreamChipVisible(
|
|
4149
|
+
"debug_stream",
|
|
4150
|
+
debugStreamStats,
|
|
4151
|
+
hiddenSet,
|
|
4152
|
+
visibleChips
|
|
4153
|
+
);
|
|
3991
4154
|
const showEnhance = isStreamChipVisible("enhance", enhanceCountdown, hiddenSet, visibleChips);
|
|
3992
4155
|
const showMailbox = showChip("mailbox") && hasMailboxActivity(mailbox);
|
|
3993
4156
|
const hasNextStepsAutoSubmit = nextStepsAutoSubmitCountdown != null && nextStepsAutoSubmitCountdown > 0;
|
|
@@ -4025,7 +4188,15 @@ function StatusBar({
|
|
|
4025
4188
|
] })
|
|
4026
4189
|
] }) : null,
|
|
4027
4190
|
version && showChip("version") && (showChip("state") || showChip("model")) ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
4028
|
-
showChip("state") && thinking ? /* @__PURE__ */ jsx(
|
|
4191
|
+
showChip("state") && thinking ? /* @__PURE__ */ jsx(
|
|
4192
|
+
ThinkingChip,
|
|
4193
|
+
{
|
|
4194
|
+
text: `${statePrefix} ${stateLabel}`,
|
|
4195
|
+
style: thinkingAnimationStyle ?? "rainbow",
|
|
4196
|
+
phase: spinnerIdx,
|
|
4197
|
+
cycleTick
|
|
4198
|
+
}
|
|
4199
|
+
) : showChip("state") ? /* @__PURE__ */ jsxs(Text, { color: stateColor, children: [
|
|
4029
4200
|
statePrefix,
|
|
4030
4201
|
" ",
|
|
4031
4202
|
stateLabel
|
|
@@ -4034,12 +4205,18 @@ function StatusBar({
|
|
|
4034
4205
|
showChip("model") ? /* @__PURE__ */ jsx(Text, { color: "magenta", children: model }) : null,
|
|
4035
4206
|
ctxClampedRatio !== void 0 && ctxPctText && ctxMax !== void 0 && showChip("context") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4036
4207
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
4037
|
-
/* @__PURE__ */ jsxs(
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4208
|
+
/* @__PURE__ */ jsxs(
|
|
4209
|
+
Text,
|
|
4210
|
+
{
|
|
4211
|
+
color: ctxClampedRatio < 0.6 ? "green" : ctxClampedRatio < 0.75 ? "yellow" : "red",
|
|
4212
|
+
children: [
|
|
4213
|
+
"ctx ",
|
|
4214
|
+
ctxPctText,
|
|
4215
|
+
"/",
|
|
4216
|
+
fmtTok(ctxMax)
|
|
4217
|
+
]
|
|
4218
|
+
}
|
|
4219
|
+
)
|
|
4043
4220
|
] }) : null,
|
|
4044
4221
|
showTokenDisplay && showChip("tokens") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4045
4222
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
|
|
@@ -4080,7 +4257,15 @@ function StatusBar({
|
|
|
4080
4257
|
/* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 2, children: isCompact ? (
|
|
4081
4258
|
// Ultra-compact: state · model
|
|
4082
4259
|
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4083
|
-
showChip("state") && thinking ? /* @__PURE__ */ jsx(
|
|
4260
|
+
showChip("state") && thinking ? /* @__PURE__ */ jsx(
|
|
4261
|
+
ThinkingChip,
|
|
4262
|
+
{
|
|
4263
|
+
text: `${statePrefix}${stateLabel}`,
|
|
4264
|
+
style: animationStyle,
|
|
4265
|
+
phase: spinnerIdx,
|
|
4266
|
+
cycleTick
|
|
4267
|
+
}
|
|
4268
|
+
) : showChip("state") ? /* @__PURE__ */ jsxs(Text, { color: stateColor, children: [
|
|
4084
4269
|
statePrefix,
|
|
4085
4270
|
stateLabel
|
|
4086
4271
|
] }) : null,
|
|
@@ -4100,7 +4285,15 @@ function StatusBar({
|
|
|
4100
4285
|
] }),
|
|
4101
4286
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" })
|
|
4102
4287
|
] }) : null,
|
|
4103
|
-
showChip("state") && thinking ? /* @__PURE__ */ jsx(
|
|
4288
|
+
showChip("state") && thinking ? /* @__PURE__ */ jsx(
|
|
4289
|
+
ThinkingChip,
|
|
4290
|
+
{
|
|
4291
|
+
text: `${statePrefix} ${stateLabel}`,
|
|
4292
|
+
style: animationStyle,
|
|
4293
|
+
phase: spinnerIdx,
|
|
4294
|
+
cycleTick
|
|
4295
|
+
}
|
|
4296
|
+
) : showChip("state") ? /* @__PURE__ */ jsxs(Text, { color: stateColor, children: [
|
|
4104
4297
|
statePrefix,
|
|
4105
4298
|
" ",
|
|
4106
4299
|
stateLabel
|
|
@@ -4115,19 +4308,25 @@ function StatusBar({
|
|
|
4115
4308
|
const ratio = context.used / context.max;
|
|
4116
4309
|
const clampedRatio = Math.min(ratio, 1);
|
|
4117
4310
|
const pctText = `${Math.min(Math.round(ratio * 100), 100)}%`;
|
|
4118
|
-
return /* @__PURE__ */ jsxs(
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4311
|
+
return /* @__PURE__ */ jsxs(
|
|
4312
|
+
Text,
|
|
4313
|
+
{
|
|
4314
|
+
color: clampedRatio < 0.6 ? "green" : clampedRatio < 0.75 ? "yellow" : "red",
|
|
4315
|
+
children: [
|
|
4316
|
+
"ctx ",
|
|
4317
|
+
renderMeter(clampedRatio, 8),
|
|
4318
|
+
" ",
|
|
4319
|
+
pctText,
|
|
4320
|
+
"/",
|
|
4321
|
+
fmtTok(context.max),
|
|
4322
|
+
contextStrategy ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
4323
|
+
" [",
|
|
4324
|
+
contextStrategy,
|
|
4325
|
+
"]"
|
|
4326
|
+
] }) : null
|
|
4327
|
+
]
|
|
4328
|
+
}
|
|
4329
|
+
);
|
|
4131
4330
|
})()
|
|
4132
4331
|
] }) : null,
|
|
4133
4332
|
showTokenDisplay && showChip("tokens") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -4248,11 +4447,17 @@ function StatusBar({
|
|
|
4248
4447
|
}
|
|
4249
4448
|
) : null,
|
|
4250
4449
|
modeLabel && showChip("mode") ? /* @__PURE__ */ jsx(Text, { color: "cyan", children: modeIcon(modeLabel) }) : null,
|
|
4251
|
-
hasAutoProceed && showChip("auto_proceed") ? /* @__PURE__ */ jsxs(
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4450
|
+
hasAutoProceed && showChip("auto_proceed") ? /* @__PURE__ */ jsxs(
|
|
4451
|
+
Text,
|
|
4452
|
+
{
|
|
4453
|
+
color: autoProceedCountdown != null && autoProceedCountdown <= 5 ? "yellow" : "cyan",
|
|
4454
|
+
children: [
|
|
4455
|
+
"\u23F3 auto in ",
|
|
4456
|
+
autoProceedCountdown,
|
|
4457
|
+
"s"
|
|
4458
|
+
]
|
|
4459
|
+
}
|
|
4460
|
+
) : null,
|
|
4256
4461
|
git && showChip("git") ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
4257
4462
|
/* @__PURE__ */ jsxs(Text, { color: "magenta", children: [
|
|
4258
4463
|
"\u2387 ",
|
|
@@ -4279,7 +4484,10 @@ function StatusBar({
|
|
|
4279
4484
|
" tool",
|
|
4280
4485
|
toolCount === 1 ? "" : "s"
|
|
4281
4486
|
] }) : null,
|
|
4282
|
-
tokenSavingMode && showChip("token_saving") ? /* @__PURE__ */
|
|
4487
|
+
tokenSavingMode !== void 0 && tokenSavingMode !== "off" && showChip("token_saving") ? /* @__PURE__ */ jsxs(Text, { color: "yellow", bold: true, children: [
|
|
4488
|
+
"\u{1F4BE} ",
|
|
4489
|
+
tokenSavingMode
|
|
4490
|
+
] }) : null,
|
|
4283
4491
|
sideEffectCount > 0 ? /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
4284
4492
|
"\u26A0 ",
|
|
4285
4493
|
sideEffectCount,
|
|
@@ -4446,15 +4654,18 @@ function StatusBar({
|
|
|
4446
4654
|
mailbox.onlineAgents === 1 ? "" : "s",
|
|
4447
4655
|
mailbox.onlineClients.tui + mailbox.onlineClients.webui + mailbox.onlineClients.repl > 0 ? /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
4448
4656
|
mailbox.onlineClients.tui > 0 ? /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
4449
|
-
"
|
|
4657
|
+
" ",
|
|
4658
|
+
"\xB7 \u{1F5A5} TUI",
|
|
4450
4659
|
mailbox.onlineClients.tui > 1 ? `\xD7${mailbox.onlineClients.tui}` : ""
|
|
4451
4660
|
] }) : null,
|
|
4452
4661
|
mailbox.onlineClients.webui > 0 ? /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
4453
|
-
"
|
|
4662
|
+
" ",
|
|
4663
|
+
"\xB7 \u{1F310} WebUI",
|
|
4454
4664
|
mailbox.onlineClients.webui > 1 ? `\xD7${mailbox.onlineClients.webui}` : ""
|
|
4455
4665
|
] }) : null,
|
|
4456
4666
|
mailbox.onlineClients.repl > 0 ? /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
4457
|
-
"
|
|
4667
|
+
" ",
|
|
4668
|
+
"\xB7 \u2328 REPL",
|
|
4458
4669
|
mailbox.onlineClients.repl > 1 ? `\xD7${mailbox.onlineClients.repl}` : ""
|
|
4459
4670
|
] }) : null
|
|
4460
4671
|
] }) : null
|
|
@@ -4628,35 +4839,6 @@ function stateChip(state, fleetRunning, thinkingWord) {
|
|
|
4628
4839
|
if (state === "aborting") return { label: "aborting\u2026", color: "yellow" };
|
|
4629
4840
|
return { label: `${normalizeTuiThinkingWord(thinkingWord)}\u2026`, color: "green" };
|
|
4630
4841
|
}
|
|
4631
|
-
var WAVE_COLORS = [
|
|
4632
|
-
"#f38ba8",
|
|
4633
|
-
// red
|
|
4634
|
-
"#eba0ac",
|
|
4635
|
-
// maroon
|
|
4636
|
-
"#fab387",
|
|
4637
|
-
// peach
|
|
4638
|
-
"#f9e2af",
|
|
4639
|
-
// yellow
|
|
4640
|
-
"#a6e3a1",
|
|
4641
|
-
// green
|
|
4642
|
-
"#94e2d5",
|
|
4643
|
-
// teal
|
|
4644
|
-
"#89dceb",
|
|
4645
|
-
// sky
|
|
4646
|
-
"#89b4fa",
|
|
4647
|
-
// blue
|
|
4648
|
-
"#b4befe",
|
|
4649
|
-
// lavender
|
|
4650
|
-
"#cba6f7",
|
|
4651
|
-
// mauve
|
|
4652
|
-
"#f5c2e7",
|
|
4653
|
-
// pink
|
|
4654
|
-
"#f2cdcd"
|
|
4655
|
-
// flamingo
|
|
4656
|
-
];
|
|
4657
|
-
function WaveText({ text, phase }) {
|
|
4658
|
-
return /* @__PURE__ */ jsx(Text, { bold: true, children: Array.from(text).map((ch, i) => /* @__PURE__ */ jsx(Text, { color: WAVE_COLORS[(i + phase) % WAVE_COLORS.length] ?? "#ffffff", children: ch }, i)) });
|
|
4659
|
-
}
|
|
4660
4842
|
var FILLED = "\u2588";
|
|
4661
4843
|
var EMPTY = "\u2591";
|
|
4662
4844
|
function renderProgress(ratio, width) {
|
|
@@ -4706,6 +4888,40 @@ function fmtDebugBytes(n) {
|
|
|
4706
4888
|
function pad2(n) {
|
|
4707
4889
|
return n < 10 ? `0${n}` : String(n);
|
|
4708
4890
|
}
|
|
4891
|
+
function ThinkingChip({
|
|
4892
|
+
text,
|
|
4893
|
+
style,
|
|
4894
|
+
phase,
|
|
4895
|
+
cycleTick
|
|
4896
|
+
}) {
|
|
4897
|
+
const live = style === "cycle" ? styleForCycleTick(cycleTick) : style;
|
|
4898
|
+
if (live === "rainbow") {
|
|
4899
|
+
return /* @__PURE__ */ jsx(Text, { bold: true, children: Array.from(text).map((ch, i) => /* @__PURE__ */ jsx(Text, { color: HUE_WHEEL[(i + phase) % HUE_WHEEL.length] ?? "#ffffff", children: ch }, i)) });
|
|
4900
|
+
}
|
|
4901
|
+
if (live === "wave") {
|
|
4902
|
+
const len = Array.from(text).length;
|
|
4903
|
+
return /* @__PURE__ */ jsx(Text, { bold: true, children: Array.from(text).map((ch, i) => /* @__PURE__ */ jsx(Text, { color: waveColor(i, phase, len), children: ch }, i)) });
|
|
4904
|
+
}
|
|
4905
|
+
if (live === "pulse") {
|
|
4906
|
+
return /* @__PURE__ */ jsx(Text, { bold: true, color: pulseColor(phase), children: text });
|
|
4907
|
+
}
|
|
4908
|
+
if (live === "dots") {
|
|
4909
|
+
const stripped = stripTrailingDots(text);
|
|
4910
|
+
const idx2 = phase % DOTS_FRAMES.length;
|
|
4911
|
+
const suffix = DOTS_FRAMES[idx2] ?? "";
|
|
4912
|
+
return /* @__PURE__ */ jsxs(Text, { bold: true, color: "green", children: [
|
|
4913
|
+
stripped,
|
|
4914
|
+
suffix ? ` ${suffix}` : ""
|
|
4915
|
+
] });
|
|
4916
|
+
}
|
|
4917
|
+
const idx = phase % BREATHE_FRAMES.length;
|
|
4918
|
+
const prefix = BREATHE_FRAMES[idx] ?? "\u280B";
|
|
4919
|
+
return /* @__PURE__ */ jsxs(Text, { bold: true, color: "green", children: [
|
|
4920
|
+
prefix,
|
|
4921
|
+
" ",
|
|
4922
|
+
text
|
|
4923
|
+
] });
|
|
4924
|
+
}
|
|
4709
4925
|
function shortSessionId(sessionId) {
|
|
4710
4926
|
const leaf = sessionId.split("/").pop() ?? sessionId;
|
|
4711
4927
|
return leaf.length > 12 ? `${leaf.slice(0, 12)}\u2026` : leaf;
|
|
@@ -6330,7 +6546,12 @@ function formatToolArgs(toolName, input) {
|
|
|
6330
6546
|
const filter = stringOf(obj["filter"]);
|
|
6331
6547
|
const since = stringOf(obj["since"]);
|
|
6332
6548
|
const lines = typeof obj["lines"] === "number" ? `${obj["lines"]} lines` : "";
|
|
6333
|
-
return [
|
|
6549
|
+
return [
|
|
6550
|
+
target ? shortenPath(target, 34) : "",
|
|
6551
|
+
filter ? `/${truncMid(filter, 16)}/` : "",
|
|
6552
|
+
since,
|
|
6553
|
+
lines
|
|
6554
|
+
].filter(Boolean).join(" \xB7 ");
|
|
6334
6555
|
}
|
|
6335
6556
|
case "tool_help": {
|
|
6336
6557
|
const tool = stringOf(obj["tool"]) ?? "all";
|
|
@@ -6364,7 +6585,11 @@ function formatToolArgs(toolName, input) {
|
|
|
6364
6585
|
}
|
|
6365
6586
|
case "codebase-search": {
|
|
6366
6587
|
const query = stringOf(obj["query"]);
|
|
6367
|
-
const filters = [
|
|
6588
|
+
const filters = [
|
|
6589
|
+
stringOf(obj["kind"]),
|
|
6590
|
+
stringOf(obj["lang"]),
|
|
6591
|
+
stringOf(obj["file"]) ? `in ${shortenPath(String(obj["file"]), 24)}` : ""
|
|
6592
|
+
].filter(Boolean).join(" \xB7 ");
|
|
6368
6593
|
return [query ? `"${truncMid(query, 30)}"` : "", filters].filter(Boolean).join(" \xB7 ");
|
|
6369
6594
|
}
|
|
6370
6595
|
case "codebase-stats":
|
|
@@ -6465,7 +6690,9 @@ function formatToolOutput(toolName, output, ok, _outputBytes, outputLines) {
|
|
|
6465
6690
|
const files = numOf(o["files_modified"]);
|
|
6466
6691
|
const reps = numOf(o["total_replacements"]);
|
|
6467
6692
|
if (files !== void 0 && reps !== void 0) {
|
|
6468
|
-
return [
|
|
6693
|
+
return [
|
|
6694
|
+
`${reps} replacement${reps === 1 ? "" : "s"} in ${files} file${files === 1 ? "" : "s"}`
|
|
6695
|
+
];
|
|
6469
6696
|
}
|
|
6470
6697
|
}
|
|
6471
6698
|
if (toolName === "diff" && json && typeof json === "object") {
|
|
@@ -6817,8 +7044,10 @@ function formatToolVisualOutput(toolName, output, ok, input) {
|
|
|
6817
7044
|
}
|
|
6818
7045
|
if (toolName === "logs") return visualLogs(text);
|
|
6819
7046
|
if (toolName === "document") return visualDocument(text);
|
|
6820
|
-
if (toolName === "tool_help" || toolName === "tool_search")
|
|
6821
|
-
|
|
7047
|
+
if (toolName === "tool_help" || toolName === "tool_search")
|
|
7048
|
+
return visualToolCatalog(toolName, text);
|
|
7049
|
+
if (toolName === "tool_use" || toolName === "batch_tool_use")
|
|
7050
|
+
return visualMetaExecution(toolName, text, ok);
|
|
6822
7051
|
if (toolName === "codebase-index" || toolName === "codebase-search" || toolName === "codebase-stats") {
|
|
6823
7052
|
return visualCodebase(toolName, text, ok);
|
|
6824
7053
|
}
|
|
@@ -6826,7 +7055,10 @@ function formatToolVisualOutput(toolName, output, ok, input) {
|
|
|
6826
7055
|
if (toolName === "mode") return visualMode(text, ok);
|
|
6827
7056
|
return void 0;
|
|
6828
7057
|
}
|
|
6829
|
-
function ToolOutputLines({
|
|
7058
|
+
function ToolOutputLines({
|
|
7059
|
+
lines,
|
|
7060
|
+
hasFollowingBlock
|
|
7061
|
+
}) {
|
|
6830
7062
|
return /* @__PURE__ */ jsx(Fragment, { children: lines.map((line, i) => {
|
|
6831
7063
|
const branch = i === lines.length - 1 && !hasFollowingBlock ? " \u2514\u2500 " : " \u251C\u2500 ";
|
|
6832
7064
|
const color = colorForVisualKind(line.kind);
|
|
@@ -6924,13 +7156,21 @@ function visualRead(text) {
|
|
|
6924
7156
|
const first = firstNonEmpty(lines.join("\n"));
|
|
6925
7157
|
return first ? [{ kind: "meta", text: first }] : void 0;
|
|
6926
7158
|
}
|
|
6927
|
-
const rows = numbered.slice(0,
|
|
7159
|
+
const rows = numbered.slice(0, 10).map((match) => ({
|
|
6928
7160
|
kind: "code",
|
|
6929
7161
|
lineNo: match[1],
|
|
6930
7162
|
text: match[2] ?? ""
|
|
6931
7163
|
}));
|
|
6932
|
-
if (numbered.length >
|
|
6933
|
-
|
|
7164
|
+
if (numbered.length > 10) {
|
|
7165
|
+
const extra = numbered.slice(10, 15).map((match) => ({
|
|
7166
|
+
kind: "code",
|
|
7167
|
+
lineNo: match[1],
|
|
7168
|
+
text: match[2] ?? ""
|
|
7169
|
+
}));
|
|
7170
|
+
rows.push(...extra);
|
|
7171
|
+
if (numbered.length > 15) {
|
|
7172
|
+
rows.push({ kind: "meta", text: `more ${numbered.length - 15} line(s)` });
|
|
7173
|
+
}
|
|
6934
7174
|
}
|
|
6935
7175
|
return rows;
|
|
6936
7176
|
}
|
|
@@ -6968,7 +7208,8 @@ function visualSearch(toolName, text) {
|
|
|
6968
7208
|
consumed++;
|
|
6969
7209
|
}
|
|
6970
7210
|
}
|
|
6971
|
-
if (lines.length > consumed)
|
|
7211
|
+
if (lines.length > consumed)
|
|
7212
|
+
rows.push({ kind: "meta", text: `${lines.length - consumed} more result line(s)` });
|
|
6972
7213
|
return rows.length > 0 ? rows : void 0;
|
|
6973
7214
|
}
|
|
6974
7215
|
function visualSearchMatches(matches, count) {
|
|
@@ -6978,8 +7219,10 @@ function visualSearchMatches(matches, count) {
|
|
|
6978
7219
|
const hit = parseMatchHit(match);
|
|
6979
7220
|
if (hit) rows.push({ kind: "match", path: hit.path, lineNo: hit.line, text: hit.text });
|
|
6980
7221
|
}
|
|
6981
|
-
if (rows.length === 0)
|
|
6982
|
-
|
|
7222
|
+
if (rows.length === 0)
|
|
7223
|
+
return count > 0 ? [{ kind: "meta", text: `${count} result${count === 1 ? "" : "s"}` }] : void 0;
|
|
7224
|
+
if (count > rows.length)
|
|
7225
|
+
rows.push({ kind: "meta", text: `${count - rows.length} more result(s)` });
|
|
6983
7226
|
return rows;
|
|
6984
7227
|
}
|
|
6985
7228
|
function parseMatchHit(hit) {
|
|
@@ -7000,24 +7243,32 @@ function parseMatchHit(hit) {
|
|
|
7000
7243
|
}
|
|
7001
7244
|
function visualPathList(toolName, text) {
|
|
7002
7245
|
const json = tryParseJson(text);
|
|
7003
|
-
const files = json && typeof json === "object" && Array.isArray(json["files"]) ? json["files"].filter(
|
|
7246
|
+
const files = json && typeof json === "object" && Array.isArray(json["files"]) ? json["files"].filter(
|
|
7247
|
+
(v) => typeof v === "string"
|
|
7248
|
+
) : bodyLines(text).filter((line) => line.trim() && !line.startsWith(`${toolName}:`));
|
|
7004
7249
|
if (files.length === 0) return void 0;
|
|
7005
|
-
const rows = files.slice(0, VISUAL_MAX_LINES).map(
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
|
|
7250
|
+
const rows = files.slice(0, VISUAL_MAX_LINES).map(
|
|
7251
|
+
(file) => ({
|
|
7252
|
+
kind: "path",
|
|
7253
|
+
path: file,
|
|
7254
|
+
text: ""
|
|
7255
|
+
})
|
|
7256
|
+
);
|
|
7257
|
+
if (files.length > rows.length)
|
|
7258
|
+
rows.push({ kind: "meta", text: `${files.length - rows.length} more path(s)` });
|
|
7011
7259
|
return rows;
|
|
7012
7260
|
}
|
|
7013
7261
|
function visualTree(text) {
|
|
7014
7262
|
const lines = bodyLines(text).filter((line) => line.trim());
|
|
7015
7263
|
if (lines.length === 0) return void 0;
|
|
7016
|
-
const rows = lines.slice(0, VISUAL_MAX_LINES).map(
|
|
7017
|
-
|
|
7018
|
-
|
|
7019
|
-
|
|
7020
|
-
|
|
7264
|
+
const rows = lines.slice(0, VISUAL_MAX_LINES).map(
|
|
7265
|
+
(line) => ({
|
|
7266
|
+
kind: line.includes("\u2500\u2500") || line.includes("|--") ? "path" : "meta",
|
|
7267
|
+
text: line
|
|
7268
|
+
})
|
|
7269
|
+
);
|
|
7270
|
+
if (lines.length > rows.length)
|
|
7271
|
+
rows.push({ kind: "meta", text: `${lines.length - rows.length} more tree line(s)` });
|
|
7021
7272
|
return rows;
|
|
7022
7273
|
}
|
|
7023
7274
|
function visualCommand(toolName, text, ok) {
|
|
@@ -7047,7 +7298,11 @@ function commandRows(opts) {
|
|
|
7047
7298
|
const rows = [];
|
|
7048
7299
|
const statusKind = opts.timedOut ? "warn" : opts.ok && (opts.exit ?? 0) === 0 ? "ok" : "error";
|
|
7049
7300
|
const status = opts.timedOut ? "timed out" : opts.exit !== void 0 ? `exit ${opts.exit}` : opts.ok ? "completed" : "failed";
|
|
7050
|
-
rows.push({
|
|
7301
|
+
rows.push({
|
|
7302
|
+
kind: statusKind,
|
|
7303
|
+
marker: statusKind === "ok" ? "ok " : statusKind === "warn" ? "! " : "x ",
|
|
7304
|
+
text: opts.label ? `${opts.label} ${status}` : status
|
|
7305
|
+
});
|
|
7051
7306
|
appendOutputPreview(rows, opts.stdout, "stdout");
|
|
7052
7307
|
appendOutputPreview(rows, opts.stderr, "stderr");
|
|
7053
7308
|
return rows.length > 0 ? rows.slice(0, VISUAL_MAX_LINES) : void 0;
|
|
@@ -7067,7 +7322,13 @@ function visualVerifier(toolName, text, ok) {
|
|
|
7067
7322
|
changed2 > 0 ? `${changed2} changed` : void 0,
|
|
7068
7323
|
toolName === "test" ? `${numOf(obj["passed"]) ?? 0}/${numOf(obj["tests_run"]) ?? 0} passed` : void 0
|
|
7069
7324
|
].filter(Boolean);
|
|
7070
|
-
return [
|
|
7325
|
+
return [
|
|
7326
|
+
{
|
|
7327
|
+
kind: statusKind2,
|
|
7328
|
+
marker: statusKind2 === "ok" ? "ok " : statusKind2 === "warn" ? "! " : "x ",
|
|
7329
|
+
text: parts.join(" \xB7 ") || toolName
|
|
7330
|
+
}
|
|
7331
|
+
];
|
|
7071
7332
|
}
|
|
7072
7333
|
const header = parseHeaderLine(text);
|
|
7073
7334
|
const sections = parseNamedSections(text);
|
|
@@ -7079,17 +7340,19 @@ function visualVerifier(toolName, text, ok) {
|
|
|
7079
7340
|
const warningCount = numberFromParsedField(fields, "warnings") ?? 0;
|
|
7080
7341
|
const changed = numberFromParsedField(fields, "files_changed") ?? 0;
|
|
7081
7342
|
const statusKind = !ok || errorContext || errorCount > 0 ? "error" : status === "changed" || changed > 0 ? "warn" : "ok";
|
|
7082
|
-
const rows = [
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
|
|
7343
|
+
const rows = [
|
|
7344
|
+
{
|
|
7345
|
+
kind: statusKind,
|
|
7346
|
+
marker: statusKind === "ok" ? "ok " : statusKind === "warn" ? "! " : "x ",
|
|
7347
|
+
text: [
|
|
7348
|
+
toolName,
|
|
7349
|
+
status ? `status=${status}` : void 0,
|
|
7350
|
+
errorCount > 0 ? `${errorCount} error${errorCount === 1 ? "" : "s"}` : void 0,
|
|
7351
|
+
warningCount > 0 ? `${warningCount} warning${warningCount === 1 ? "" : "s"}` : void 0,
|
|
7352
|
+
changed > 0 ? `${changed} changed` : void 0
|
|
7353
|
+
].filter(Boolean).join(" \xB7 ")
|
|
7354
|
+
}
|
|
7355
|
+
];
|
|
7093
7356
|
appendOutputPreview(rows, errorContext, "stderr");
|
|
7094
7357
|
return rows.slice(0, VISUAL_MAX_LINES);
|
|
7095
7358
|
}
|
|
@@ -7111,11 +7374,13 @@ function visualFetch(text) {
|
|
|
7111
7374
|
}
|
|
7112
7375
|
function fetchRows(status, contentType, content) {
|
|
7113
7376
|
const kind = status === void 0 ? "meta" : status >= 200 && status < 300 ? "ok" : status >= 300 && status < 400 ? "warn" : "error";
|
|
7114
|
-
const rows = [
|
|
7115
|
-
|
|
7116
|
-
|
|
7117
|
-
|
|
7118
|
-
|
|
7377
|
+
const rows = [
|
|
7378
|
+
{
|
|
7379
|
+
kind,
|
|
7380
|
+
marker: kind === "ok" ? "ok " : kind === "warn" ? "! " : kind === "error" ? "x " : void 0,
|
|
7381
|
+
text: [status !== void 0 ? `HTTP ${status}` : "HTTP", contentType?.split(";")[0]].filter(Boolean).join(" \xB7 ")
|
|
7382
|
+
}
|
|
7383
|
+
];
|
|
7119
7384
|
const preview = firstNonEmpty(content ?? "");
|
|
7120
7385
|
if (preview) rows.push({ kind: "stdout", text: preview });
|
|
7121
7386
|
return rows;
|
|
@@ -7128,7 +7393,13 @@ function visualJson(text) {
|
|
|
7128
7393
|
if (err) return [{ kind: "error", marker: "x ", text: err }];
|
|
7129
7394
|
const type = stringOf(obj["type"]);
|
|
7130
7395
|
const keys = Array.isArray(obj["keys"]) ? obj["keys"].length : void 0;
|
|
7131
|
-
return [
|
|
7396
|
+
return [
|
|
7397
|
+
{
|
|
7398
|
+
kind: "ok",
|
|
7399
|
+
marker: "ok ",
|
|
7400
|
+
text: [type ?? "json", keys !== void 0 ? `${keys} key${keys === 1 ? "" : "s"}` : void 0].filter(Boolean).join(" \xB7 ")
|
|
7401
|
+
}
|
|
7402
|
+
];
|
|
7132
7403
|
}
|
|
7133
7404
|
function visualOutdated(text) {
|
|
7134
7405
|
const lines = bodyLines(text).filter((line) => line.trim() && !line.startsWith("outdated"));
|
|
@@ -7138,11 +7409,13 @@ function visualOutdated(text) {
|
|
|
7138
7409
|
function visualAudit(text) {
|
|
7139
7410
|
const lines = bodyLines(text).filter((line) => line.trim() && !line.startsWith("audit"));
|
|
7140
7411
|
if (lines.length === 0) return void 0;
|
|
7141
|
-
return lines.slice(0, VISUAL_MAX_LINES).map(
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
|
|
7412
|
+
return lines.slice(0, VISUAL_MAX_LINES).map(
|
|
7413
|
+
(line) => ({
|
|
7414
|
+
kind: /^critical|^high/i.test(line) ? "error" : /^moderate|^medium/i.test(line) ? "warn" : "meta",
|
|
7415
|
+
marker: /^critical|^high/i.test(line) ? "x " : /^moderate|^medium/i.test(line) ? "! " : void 0,
|
|
7416
|
+
text: line
|
|
7417
|
+
})
|
|
7418
|
+
);
|
|
7146
7419
|
}
|
|
7147
7420
|
function visualScaffold(text) {
|
|
7148
7421
|
const json = tryParseJson(text);
|
|
@@ -7154,7 +7427,8 @@ function visualScaffold(text) {
|
|
|
7154
7427
|
for (const file of created.slice(0, 5)) {
|
|
7155
7428
|
if (typeof file === "string") rows.push({ kind: "ok", marker: "+ ", path: file, text: "" });
|
|
7156
7429
|
}
|
|
7157
|
-
if (skipped.length > 0)
|
|
7430
|
+
if (skipped.length > 0)
|
|
7431
|
+
rows.push({ kind: "warn", marker: "! ", text: `${skipped.length} skipped` });
|
|
7158
7432
|
return rows.length > 0 ? rows : void 0;
|
|
7159
7433
|
}
|
|
7160
7434
|
function visualTodo(text) {
|
|
@@ -7162,11 +7436,13 @@ function visualTodo(text) {
|
|
|
7162
7436
|
const fields = json && typeof json === "object" && !Array.isArray(json) ? recordToStringFields(json) : parseHeaderLine(text).fields;
|
|
7163
7437
|
const count = numberFromParsedField(fields, "count") ?? 0;
|
|
7164
7438
|
const inProgress = numberFromParsedField(fields, "in_progress") ?? 0;
|
|
7165
|
-
return [
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7439
|
+
return [
|
|
7440
|
+
{
|
|
7441
|
+
kind: count > 0 ? "ok" : "meta",
|
|
7442
|
+
marker: count > 0 ? "ok " : void 0,
|
|
7443
|
+
text: `${count} todo${count === 1 ? "" : "s"}${inProgress > 0 ? ` \xB7 ${inProgress} in progress` : ""}`
|
|
7444
|
+
}
|
|
7445
|
+
];
|
|
7170
7446
|
}
|
|
7171
7447
|
function visualWorkBoard(toolName, text, ok) {
|
|
7172
7448
|
const json = tryParseJson(text);
|
|
@@ -7179,7 +7455,11 @@ function visualWorkBoard(toolName, text, ok) {
|
|
|
7179
7455
|
for (const todo of todos.slice(0, 3)) {
|
|
7180
7456
|
if (todo && typeof todo === "object") {
|
|
7181
7457
|
const o = todo;
|
|
7182
|
-
rows2.push({
|
|
7458
|
+
rows2.push({
|
|
7459
|
+
kind: "path",
|
|
7460
|
+
marker: "+ ",
|
|
7461
|
+
text: stringOf(o["content"]) ?? stringOf(o["id"]) ?? "todo"
|
|
7462
|
+
});
|
|
7183
7463
|
}
|
|
7184
7464
|
}
|
|
7185
7465
|
return rows2.slice(0, VISUAL_MAX_LINES);
|
|
@@ -7187,7 +7467,10 @@ function visualWorkBoard(toolName, text, ok) {
|
|
|
7187
7467
|
const header = parseHeaderLine(text);
|
|
7188
7468
|
const sections = parseNamedSections(text);
|
|
7189
7469
|
const rows = boardSummaryRows(toolName, header.fields, ok);
|
|
7190
|
-
appendBoardPreview(
|
|
7470
|
+
appendBoardPreview(
|
|
7471
|
+
rows,
|
|
7472
|
+
sections.get("message") ?? sections.get("plan") ?? bodyLines(text).join("\n")
|
|
7473
|
+
);
|
|
7191
7474
|
return rows.slice(0, VISUAL_MAX_LINES);
|
|
7192
7475
|
}
|
|
7193
7476
|
function boardSummaryRows(toolName, fields, ok) {
|
|
@@ -7203,17 +7486,22 @@ function boardSummaryRows(toolName, fields, ok) {
|
|
|
7203
7486
|
completed !== void 0 ? `${completed} done` : void 0,
|
|
7204
7487
|
inProgress !== void 0 && inProgress > 0 ? `${inProgress} in progress` : void 0
|
|
7205
7488
|
].filter(Boolean);
|
|
7206
|
-
return [
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
|
|
7489
|
+
return [
|
|
7490
|
+
{
|
|
7491
|
+
kind: success ? "ok" : "error",
|
|
7492
|
+
marker: success ? "ok " : "x ",
|
|
7493
|
+
text: parts.join(" \xB7 ") || toolName
|
|
7494
|
+
}
|
|
7495
|
+
];
|
|
7211
7496
|
}
|
|
7212
7497
|
function appendBoardPreview(rows, text) {
|
|
7213
7498
|
if (!text) return;
|
|
7214
7499
|
const lines = text.split(/\r?\n/).map((line) => line.replace(/^[\s│├└─>*-]+/, "").trim()).filter((line) => line && !line.startsWith("{") && !line.startsWith("["));
|
|
7215
7500
|
for (const line of lines.slice(0, 4)) {
|
|
7216
|
-
rows.push({
|
|
7501
|
+
rows.push({
|
|
7502
|
+
kind: line.includes("failed") || line.includes("not configured") ? "error" : "meta",
|
|
7503
|
+
text: line
|
|
7504
|
+
});
|
|
7217
7505
|
}
|
|
7218
7506
|
}
|
|
7219
7507
|
function visualMemory(toolName, text, ok) {
|
|
@@ -7246,7 +7534,11 @@ function memoryResultRows(results) {
|
|
|
7246
7534
|
const parsed = tryParseJson(result);
|
|
7247
7535
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7248
7536
|
const o = parsed;
|
|
7249
|
-
rows.push({
|
|
7537
|
+
rows.push({
|
|
7538
|
+
kind: "meta",
|
|
7539
|
+
marker: tagMarker(stringOf(o["priority"])),
|
|
7540
|
+
text: memoryText(o)
|
|
7541
|
+
});
|
|
7250
7542
|
} else {
|
|
7251
7543
|
rows.push({ kind: "meta", text: result });
|
|
7252
7544
|
}
|
|
@@ -7255,7 +7547,8 @@ function memoryResultRows(results) {
|
|
|
7255
7547
|
rows.push({ kind: "meta", marker: tagMarker(stringOf(o["priority"])), text: memoryText(o) });
|
|
7256
7548
|
}
|
|
7257
7549
|
}
|
|
7258
|
-
if (results.length > rows.length)
|
|
7550
|
+
if (results.length > rows.length)
|
|
7551
|
+
rows.push({ kind: "meta", text: `${results.length - rows.length} more memory result(s)` });
|
|
7259
7552
|
return rows;
|
|
7260
7553
|
}
|
|
7261
7554
|
function memoryText(o) {
|
|
@@ -7272,16 +7565,23 @@ function visualLogs(text) {
|
|
|
7272
7565
|
const json = tryParseJson(text);
|
|
7273
7566
|
if (json && typeof json === "object" && !Array.isArray(json)) {
|
|
7274
7567
|
const obj = json;
|
|
7275
|
-
const rows2 = [
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
|
|
7568
|
+
const rows2 = [
|
|
7569
|
+
{
|
|
7570
|
+
kind: "meta",
|
|
7571
|
+
text: `${stringOf(obj["source"]) ?? "logs"} \xB7 ${numOf(obj["total"]) ?? 0} entries${obj["truncated"] === true ? " \xB7 truncated" : ""}`
|
|
7572
|
+
}
|
|
7573
|
+
];
|
|
7279
7574
|
const entries = Array.isArray(obj["entries"]) ? obj["entries"] : [];
|
|
7280
7575
|
appendLogEntries(rows2, entries);
|
|
7281
7576
|
return rows2;
|
|
7282
7577
|
}
|
|
7283
7578
|
const header = parseHeaderLine(text);
|
|
7284
|
-
const rows = [
|
|
7579
|
+
const rows = [
|
|
7580
|
+
{
|
|
7581
|
+
kind: "meta",
|
|
7582
|
+
text: `${header.label}${header.fields["total"] ? ` \xB7 ${header.fields["total"]} entries` : ""}`
|
|
7583
|
+
}
|
|
7584
|
+
];
|
|
7285
7585
|
appendLogEntries(rows, bodyLines(text));
|
|
7286
7586
|
return rows.slice(0, VISUAL_MAX_LINES);
|
|
7287
7587
|
}
|
|
@@ -7291,10 +7591,20 @@ function appendLogEntries(rows, entries) {
|
|
|
7291
7591
|
rows.push(logLine(entry));
|
|
7292
7592
|
} else if (entry && typeof entry === "object") {
|
|
7293
7593
|
const o = entry;
|
|
7294
|
-
rows.push(
|
|
7594
|
+
rows.push(
|
|
7595
|
+
logLine(
|
|
7596
|
+
[
|
|
7597
|
+
stringOf(o["timestamp"]),
|
|
7598
|
+
stringOf(o["level"]),
|
|
7599
|
+
stringOf(o["source"]),
|
|
7600
|
+
stringOf(o["message"])
|
|
7601
|
+
].filter(Boolean).join(" ")
|
|
7602
|
+
)
|
|
7603
|
+
);
|
|
7295
7604
|
}
|
|
7296
7605
|
}
|
|
7297
|
-
if (entries.length > 5)
|
|
7606
|
+
if (entries.length > 5)
|
|
7607
|
+
rows.push({ kind: "meta", text: `${entries.length - 5} more log line(s)` });
|
|
7298
7608
|
}
|
|
7299
7609
|
function logLine(line) {
|
|
7300
7610
|
const kind = /\b(error|fatal|panic)\b/i.test(line) ? "error" : /\b(warn|warning)\b/i.test(line) ? "warn" : "stdout";
|
|
@@ -7345,7 +7655,11 @@ function visualToolCatalog(toolName, text) {
|
|
|
7345
7655
|
if (json && typeof json === "object" && !Array.isArray(json)) {
|
|
7346
7656
|
const obj = json;
|
|
7347
7657
|
const total = numOf(obj["total"]) ?? 0;
|
|
7348
|
-
rows.push({
|
|
7658
|
+
rows.push({
|
|
7659
|
+
kind: total > 0 ? "ok" : "warn",
|
|
7660
|
+
marker: total > 0 ? "ok " : "! ",
|
|
7661
|
+
text: `${toolName} \xB7 ${total} result${total === 1 ? "" : "s"}`
|
|
7662
|
+
});
|
|
7349
7663
|
const tools = Array.isArray(obj["tools"]) ? obj["tools"] : [];
|
|
7350
7664
|
for (const tool of tools.slice(0, 5)) {
|
|
7351
7665
|
if (tool && typeof tool === "object") {
|
|
@@ -7366,26 +7680,32 @@ function visualMetaExecution(toolName, text, ok) {
|
|
|
7366
7680
|
const json = tryParseJson(text);
|
|
7367
7681
|
if (!json || typeof json !== "object" || Array.isArray(json)) {
|
|
7368
7682
|
const header = parseHeaderLine(text);
|
|
7369
|
-
return [
|
|
7683
|
+
return [
|
|
7684
|
+
{ kind: ok ? "ok" : "error", marker: ok ? "ok " : "x ", text: header.label || toolName }
|
|
7685
|
+
];
|
|
7370
7686
|
}
|
|
7371
7687
|
const obj = json;
|
|
7372
7688
|
if (toolName === "tool_use") {
|
|
7373
7689
|
const success = obj["success"] !== false && ok;
|
|
7374
7690
|
const target = stringOf(obj["tool"]) ?? "tool";
|
|
7375
|
-
return [
|
|
7376
|
-
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
|
|
7691
|
+
return [
|
|
7692
|
+
{
|
|
7693
|
+
kind: success ? "ok" : "error",
|
|
7694
|
+
marker: success ? "ok " : "x ",
|
|
7695
|
+
text: `${target} \xB7 ${numOf(obj["executionMs"]) ?? 0}ms${success ? "" : ` \xB7 ${stringOf(obj["error"]) ?? "failed"}`}`
|
|
7696
|
+
}
|
|
7697
|
+
];
|
|
7380
7698
|
}
|
|
7381
7699
|
const total = numOf(obj["total"]) ?? 0;
|
|
7382
7700
|
const succeeded = numOf(obj["succeeded"]) ?? 0;
|
|
7383
7701
|
const failed = numOf(obj["failed"]) ?? 0;
|
|
7384
|
-
const rows = [
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
|
|
7702
|
+
const rows = [
|
|
7703
|
+
{
|
|
7704
|
+
kind: failed > 0 || !ok ? "error" : "ok",
|
|
7705
|
+
marker: failed > 0 || !ok ? "x " : "ok ",
|
|
7706
|
+
text: `${succeeded}/${total} succeeded${failed > 0 ? ` \xB7 ${failed} failed` : ""}`
|
|
7707
|
+
}
|
|
7708
|
+
];
|
|
7389
7709
|
const results = Array.isArray(obj["results"]) ? obj["results"] : [];
|
|
7390
7710
|
for (const result of results.slice(0, 5)) {
|
|
7391
7711
|
if (result && typeof result === "object") {
|
|
@@ -7404,17 +7724,21 @@ function visualCodebase(toolName, text, ok) {
|
|
|
7404
7724
|
const json = tryParseJson(text);
|
|
7405
7725
|
if (!json || typeof json !== "object" || Array.isArray(json)) {
|
|
7406
7726
|
const header = parseHeaderLine(text);
|
|
7407
|
-
return [
|
|
7727
|
+
return [
|
|
7728
|
+
{ kind: ok ? "ok" : "warn", marker: ok ? "ok " : "! ", text: header.label || toolName }
|
|
7729
|
+
];
|
|
7408
7730
|
}
|
|
7409
7731
|
const obj = json;
|
|
7410
7732
|
if (toolName === "codebase-search") {
|
|
7411
7733
|
const status2 = stringOf(obj["indexStatus"]);
|
|
7412
7734
|
const total = numOf(obj["total"]) ?? 0;
|
|
7413
|
-
const rows = [
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7735
|
+
const rows = [
|
|
7736
|
+
{
|
|
7737
|
+
kind: status2 ? "warn" : "ok",
|
|
7738
|
+
marker: status2 ? "! " : "ok ",
|
|
7739
|
+
text: status2 ?? `${total} symbol result${total === 1 ? "" : "s"} for "${stringOf(obj["query"]) ?? ""}"`
|
|
7740
|
+
}
|
|
7741
|
+
];
|
|
7418
7742
|
const results = Array.isArray(obj["results"]) ? obj["results"] : [];
|
|
7419
7743
|
for (const result of results.slice(0, 5)) {
|
|
7420
7744
|
if (result && typeof result === "object") {
|
|
@@ -7431,30 +7755,36 @@ function visualCodebase(toolName, text, ok) {
|
|
|
7431
7755
|
}
|
|
7432
7756
|
if (toolName === "codebase-index") {
|
|
7433
7757
|
const errors = Array.isArray(obj["errors"]) ? obj["errors"] : [];
|
|
7434
|
-
return [
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7758
|
+
return [
|
|
7759
|
+
{
|
|
7760
|
+
kind: errors.length > 0 || !ok ? "error" : stringOf(obj["note"]) ? "warn" : "ok",
|
|
7761
|
+
marker: errors.length > 0 || !ok ? "x " : stringOf(obj["note"]) ? "! " : "ok ",
|
|
7762
|
+
text: stringOf(obj["note"]) ?? `${numOf(obj["filesIndexed"]) ?? 0} files \xB7 ${numOf(obj["symbolsIndexed"]) ?? 0} symbols \xB7 ${fmtDuration(numOf(obj["durationMs"]) ?? 0)}`
|
|
7763
|
+
}
|
|
7764
|
+
];
|
|
7439
7765
|
}
|
|
7440
7766
|
const status = stringOf(obj["indexStatus"]);
|
|
7441
|
-
return [
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7767
|
+
return [
|
|
7768
|
+
{
|
|
7769
|
+
kind: status ? "warn" : "ok",
|
|
7770
|
+
marker: status ? "! " : "ok ",
|
|
7771
|
+
text: status ?? `${numOf(obj["totalSymbols"]) ?? 0} symbols \xB7 ${numOf(obj["totalFiles"]) ?? 0} files \xB7 ${fmtBytes(numOf(obj["sizeBytes"]) ?? 0)}`
|
|
7772
|
+
}
|
|
7773
|
+
];
|
|
7446
7774
|
}
|
|
7447
7775
|
function visualWorkingDir(text, ok) {
|
|
7448
7776
|
const json = tryParseJson(text);
|
|
7449
7777
|
const obj = json && typeof json === "object" && !Array.isArray(json) ? json : void 0;
|
|
7450
7778
|
if (!obj) return void 0;
|
|
7451
7779
|
const err = stringOf(obj["error"]);
|
|
7452
|
-
return [
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7780
|
+
return [
|
|
7781
|
+
{
|
|
7782
|
+
kind: err || !ok ? "error" : "ok",
|
|
7783
|
+
marker: err || !ok ? "x " : "ok ",
|
|
7784
|
+
path: stringOf(obj["current"]),
|
|
7785
|
+
text: err ?? stringOf(obj["message"]) ?? "working directory"
|
|
7786
|
+
}
|
|
7787
|
+
];
|
|
7458
7788
|
}
|
|
7459
7789
|
function visualMode(text, ok) {
|
|
7460
7790
|
const json = tryParseJson(text);
|
|
@@ -7462,21 +7792,32 @@ function visualMode(text, ok) {
|
|
|
7462
7792
|
if (!obj) return void 0;
|
|
7463
7793
|
if (Array.isArray(obj["modes"])) {
|
|
7464
7794
|
const modes = obj["modes"];
|
|
7465
|
-
const rows = [
|
|
7795
|
+
const rows = [
|
|
7796
|
+
{ kind: "ok", marker: "ok ", text: `${modes.length} mode${modes.length === 1 ? "" : "s"}` }
|
|
7797
|
+
];
|
|
7466
7798
|
for (const mode of modes.slice(0, 5)) {
|
|
7467
7799
|
if (mode && typeof mode === "object") {
|
|
7468
7800
|
const m = mode;
|
|
7469
|
-
rows.push({
|
|
7801
|
+
rows.push({
|
|
7802
|
+
kind: "path",
|
|
7803
|
+
text: [stringOf(m["id"]), stringOf(m["name"]), stringOf(m["description"])].filter(Boolean).join(" \xB7 ")
|
|
7804
|
+
});
|
|
7470
7805
|
}
|
|
7471
7806
|
}
|
|
7472
7807
|
return rows;
|
|
7473
7808
|
}
|
|
7474
7809
|
const success = obj["success"] !== false && ok;
|
|
7475
|
-
return [
|
|
7476
|
-
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
|
|
7810
|
+
return [
|
|
7811
|
+
{
|
|
7812
|
+
kind: success ? "ok" : "error",
|
|
7813
|
+
marker: success ? "ok " : "x ",
|
|
7814
|
+
text: [
|
|
7815
|
+
stringOf(obj["action"]) ?? "mode",
|
|
7816
|
+
stringOf(obj["currentMode"]),
|
|
7817
|
+
stringOf(obj["message"])
|
|
7818
|
+
].filter(Boolean).join(" \xB7 ")
|
|
7819
|
+
}
|
|
7820
|
+
];
|
|
7480
7821
|
}
|
|
7481
7822
|
function recordToStringFields(obj) {
|
|
7482
7823
|
const out = {};
|
|
@@ -7492,7 +7833,8 @@ function appendOutputPreview(rows, output, kind) {
|
|
|
7492
7833
|
if (!output) return;
|
|
7493
7834
|
const lines = output.split(/\r?\n/).filter((line) => line.trim());
|
|
7494
7835
|
for (const line of lines.slice(0, 3)) rows.push({ kind, text: line.trim() });
|
|
7495
|
-
if (lines.length > 3)
|
|
7836
|
+
if (lines.length > 3)
|
|
7837
|
+
rows.push({ kind: "meta", text: `${lines.length - 3} more ${kind} line(s)` });
|
|
7496
7838
|
}
|
|
7497
7839
|
function bodyLines(text) {
|
|
7498
7840
|
const lines = text.replace(/\r/g, "").split("\n");
|
|
@@ -7800,6 +8142,12 @@ function DiffBlock({
|
|
|
7800
8142
|
};
|
|
7801
8143
|
const stats = showStats ? formatDiffStats(added, removed) : null;
|
|
7802
8144
|
const bodyBudget = typeof contentWidth === "number" ? Math.max(16, contentWidth - (2 + 3 + gutterWidth + 3)) : DIFF_FALLBACK_WRAP_WIDTH;
|
|
8145
|
+
const hasWidth = typeof contentWidth === "number";
|
|
8146
|
+
const padBody = (seg) => {
|
|
8147
|
+
if (!hasWidth) return 0;
|
|
8148
|
+
const len = seg.reduce((n, t) => n + t.text.length, 0);
|
|
8149
|
+
return Math.max(0, bodyBudget - len);
|
|
8150
|
+
};
|
|
7803
8151
|
const contPrefix = ` ${blank} `;
|
|
7804
8152
|
const hiddenStats = [];
|
|
7805
8153
|
if (hiddenAdded > 0) hiddenStats.push(`+${hiddenAdded}`);
|
|
@@ -7833,14 +8181,18 @@ function DiffBlock({
|
|
|
7833
8181
|
const markerColor = row.kind === "add" ? theme.success : theme.error;
|
|
7834
8182
|
if (useColor) {
|
|
7835
8183
|
const bg = row.kind === "add" ? theme.diffAddBg : theme.diffDelBg;
|
|
7836
|
-
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: segments.map((seg, si) =>
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
/* @__PURE__ */
|
|
7840
|
-
|
|
7841
|
-
|
|
7842
|
-
|
|
7843
|
-
|
|
8184
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: segments.map((seg, si) => {
|
|
8185
|
+
const pad = padBody(seg);
|
|
8186
|
+
return /* @__PURE__ */ jsxs(Text, { backgroundColor: bg, children: [
|
|
8187
|
+
si === 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8188
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ` ${ln} ` }),
|
|
8189
|
+
/* @__PURE__ */ jsx(Text, { color: markerColor, bold: true, children: marker }),
|
|
8190
|
+
/* @__PURE__ */ jsx(Text, { children: " " })
|
|
8191
|
+
] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: contPrefix }),
|
|
8192
|
+
renderTokens(seg),
|
|
8193
|
+
pad > 0 ? /* @__PURE__ */ jsx(Text, { children: " ".repeat(pad) }) : null
|
|
8194
|
+
] }, si);
|
|
8195
|
+
}) }, key);
|
|
7844
8196
|
}
|
|
7845
8197
|
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: segments.map((seg, si) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
7846
8198
|
si === 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -10003,16 +10355,21 @@ var Entry = React5.memo(function Entry2({
|
|
|
10003
10355
|
if (mutation) {
|
|
10004
10356
|
const statsText = formatDiffStats(mutation.added, mutation.removed) ?? "No line changes";
|
|
10005
10357
|
const targetBudget = Math.max(24, termWidth - mutation.verb.length - 16);
|
|
10358
|
+
const hasCounts = mutation.added > 0 || mutation.removed > 0;
|
|
10006
10359
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
10007
10360
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
10008
|
-
/* @__PURE__ */ jsx(Text, { color
|
|
10361
|
+
/* @__PURE__ */ jsx(Text, { color, children: glyph2 }),
|
|
10009
10362
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
10010
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color
|
|
10363
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color, children: `${mutation.verb}(${shortenPath(mutation.target, targetBudget)})` }),
|
|
10011
10364
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: ` \xB7 ${fmtDuration(entry.durationMs)}` })
|
|
10012
10365
|
] }),
|
|
10013
10366
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
10014
10367
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " \u23BF " }),
|
|
10015
|
-
/* @__PURE__ */ jsx(Text, { children:
|
|
10368
|
+
mutation.added > 0 ? /* @__PURE__ */ jsx(Text, { bold: true, color: theme.success, children: `+${mutation.added}` }) : null,
|
|
10369
|
+
mutation.added > 0 && mutation.removed > 0 ? /* @__PURE__ */ jsx(Text, { children: " " }) : null,
|
|
10370
|
+
mutation.removed > 0 ? /* @__PURE__ */ jsx(Text, { bold: true, color: theme.error, children: `-${mutation.removed}` }) : null,
|
|
10371
|
+
hasCounts ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }) : null,
|
|
10372
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: statsText })
|
|
10016
10373
|
] }),
|
|
10017
10374
|
entry.resultRenderMode !== "simple" && multiDiffs ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
10018
10375
|
(() => {
|
|
@@ -15244,14 +15601,16 @@ function createPanelOpenDispatcher(deps) {
|
|
|
15244
15601
|
}
|
|
15245
15602
|
};
|
|
15246
15603
|
}
|
|
15247
|
-
|
|
15248
|
-
|
|
15249
|
-
|
|
15250
|
-
|
|
15251
|
-
|
|
15252
|
-
|
|
15604
|
+
|
|
15605
|
+
// src/input-editing.ts
|
|
15606
|
+
var WORD_SEPARATORS = new Set(
|
|
15607
|
+
// dashes
|
|
15608
|
+
"-/\\.,;:!?\u2026()[]{}<>\"'`+=*^%|~@#$&\xB7\u2022\u2014\u2013".split("")
|
|
15609
|
+
);
|
|
15253
15610
|
function isInputWordSeparator(ch) {
|
|
15254
|
-
|
|
15611
|
+
if (ch === void 0) return true;
|
|
15612
|
+
if (/\s/.test(ch)) return true;
|
|
15613
|
+
return WORD_SEPARATORS.has(ch);
|
|
15255
15614
|
}
|
|
15256
15615
|
function previousInputWordStart(buffer, cursor) {
|
|
15257
15616
|
let i = Math.max(0, Math.min(cursor, buffer.length));
|
|
@@ -15286,6 +15645,34 @@ function nextInputWordStart(buffer, cursor) {
|
|
|
15286
15645
|
while (i < buffer.length && isInputWordSeparator(buffer[i])) i++;
|
|
15287
15646
|
return i;
|
|
15288
15647
|
}
|
|
15648
|
+
function deleteWordBackward(buffer, cursor) {
|
|
15649
|
+
if (cursor === 0) return null;
|
|
15650
|
+
const chip = tokenSpanAt(buffer, cursor);
|
|
15651
|
+
const deleteStart = chip && cursor > chip.start && cursor < chip.end ? chip.start : previousInputWordStart(buffer, cursor);
|
|
15652
|
+
const deleteEnd = chip && cursor > chip.start && cursor < chip.end ? chip.end : cursor;
|
|
15653
|
+
if (deleteStart === deleteEnd) return null;
|
|
15654
|
+
return {
|
|
15655
|
+
buffer: buffer.slice(0, deleteStart) + buffer.slice(deleteEnd),
|
|
15656
|
+
cursor: deleteStart
|
|
15657
|
+
};
|
|
15658
|
+
}
|
|
15659
|
+
function deleteWordForward(buffer, cursor) {
|
|
15660
|
+
if (cursor >= buffer.length) return null;
|
|
15661
|
+
const chip = tokenSpanAt(buffer, cursor);
|
|
15662
|
+
const deleteStart = chip && cursor > chip.start && cursor < chip.end ? chip.start : cursor;
|
|
15663
|
+
const deleteEnd = chip && cursor > chip.start && cursor < chip.end ? chip.end : nextInputWordStart(buffer, cursor);
|
|
15664
|
+
if (deleteStart === deleteEnd) return null;
|
|
15665
|
+
return {
|
|
15666
|
+
buffer: buffer.slice(0, deleteStart) + buffer.slice(deleteEnd),
|
|
15667
|
+
cursor: deleteStart
|
|
15668
|
+
};
|
|
15669
|
+
}
|
|
15670
|
+
var INPUT_PROMPT = "\u203A ";
|
|
15671
|
+
function selectedSlashCommandLine(picker) {
|
|
15672
|
+
if (!picker.open || picker.matches.length === 0) return null;
|
|
15673
|
+
const picked = picker.matches[picker.selected];
|
|
15674
|
+
return picked ? `/${picked.name}` : null;
|
|
15675
|
+
}
|
|
15289
15676
|
function rehydrateHistory(messages, startId, toolCalls) {
|
|
15290
15677
|
const entries = [];
|
|
15291
15678
|
const toolCallsById = /* @__PURE__ */ new Map();
|
|
@@ -15624,6 +16011,7 @@ function App({
|
|
|
15624
16011
|
nextQueueId: 1,
|
|
15625
16012
|
inputHistory: [],
|
|
15626
16013
|
historyIndex: 0,
|
|
16014
|
+
historyDraft: "",
|
|
15627
16015
|
modelPicker: {
|
|
15628
16016
|
open: false,
|
|
15629
16017
|
step: "provider",
|
|
@@ -15693,7 +16081,8 @@ function App({
|
|
|
15693
16081
|
thinkingWordEditing: false,
|
|
15694
16082
|
thinkingWordDraft: "",
|
|
15695
16083
|
cacheTtl: "default",
|
|
15696
|
-
configScope: "global"
|
|
16084
|
+
configScope: "global",
|
|
16085
|
+
animationStyle: "rainbow"
|
|
15697
16086
|
},
|
|
15698
16087
|
statuslinePicker: { open: false, field: 0, hiddenItems: [], visibleChips: [], hint: void 0 },
|
|
15699
16088
|
pluginPicker: { open: false, items: [], selected: 0, busy: false, hint: void 0 },
|
|
@@ -15763,6 +16152,44 @@ function App({
|
|
|
15763
16152
|
debugStreamStats: null,
|
|
15764
16153
|
countdown: null
|
|
15765
16154
|
});
|
|
16155
|
+
const inputHistoryStore = useMemo(() => {
|
|
16156
|
+
if (!projectRoot) return null;
|
|
16157
|
+
const file = resolveWstackPaths({ projectRoot }).projectInputHistory;
|
|
16158
|
+
return new InputHistoryStore(file, new DefaultSecretScrubber(), INPUT_HISTORY_DEFAULT_MAX);
|
|
16159
|
+
}, [projectRoot]);
|
|
16160
|
+
const inputHistoryLoadedRef = useRef(false);
|
|
16161
|
+
const inputHistorySaveTimerRef = useRef(void 0);
|
|
16162
|
+
const inputHistoryLastSavedRef = useRef("");
|
|
16163
|
+
useEffect(() => {
|
|
16164
|
+
if (!inputHistoryStore) return;
|
|
16165
|
+
let cancelled = false;
|
|
16166
|
+
inputHistoryStore.load().then((entries) => {
|
|
16167
|
+
if (cancelled) return;
|
|
16168
|
+
inputHistoryLoadedRef.current = true;
|
|
16169
|
+
inputHistoryLastSavedRef.current = JSON.stringify(entries);
|
|
16170
|
+
if (entries.length === 0) return;
|
|
16171
|
+
dispatch({ type: "setInputHistory", entries });
|
|
16172
|
+
}).catch(() => {
|
|
16173
|
+
if (!cancelled) inputHistoryLoadedRef.current = true;
|
|
16174
|
+
});
|
|
16175
|
+
return () => {
|
|
16176
|
+
cancelled = true;
|
|
16177
|
+
};
|
|
16178
|
+
}, [inputHistoryStore]);
|
|
16179
|
+
useEffect(() => {
|
|
16180
|
+
if (!inputHistoryStore || !inputHistoryLoadedRef.current) return;
|
|
16181
|
+
const snapshot = JSON.stringify(state.inputHistory);
|
|
16182
|
+
if (snapshot === inputHistoryLastSavedRef.current) return;
|
|
16183
|
+
if (inputHistorySaveTimerRef.current) clearTimeout(inputHistorySaveTimerRef.current);
|
|
16184
|
+
inputHistorySaveTimerRef.current = setTimeout(() => {
|
|
16185
|
+
inputHistoryLastSavedRef.current = snapshot;
|
|
16186
|
+
inputHistoryStore.save(state.inputHistory).catch(() => {
|
|
16187
|
+
});
|
|
16188
|
+
}, 200);
|
|
16189
|
+
return () => {
|
|
16190
|
+
if (inputHistorySaveTimerRef.current) clearTimeout(inputHistorySaveTimerRef.current);
|
|
16191
|
+
};
|
|
16192
|
+
}, [state.inputHistory, inputHistoryStore]);
|
|
15766
16193
|
const getPromptLoader = () => {
|
|
15767
16194
|
if (!promptLoaderRef.current && projectRoot) {
|
|
15768
16195
|
let bundledDir;
|
|
@@ -15882,6 +16309,7 @@ function App({
|
|
|
15882
16309
|
}, [agent.ctx, projectRoot]);
|
|
15883
16310
|
const liveSettings = getSettings?.();
|
|
15884
16311
|
const liveStatuslineMode = liveSettings?.statuslineMode ?? "detailed";
|
|
16312
|
+
const liveAnimationStyle = liveSettings?.animationStyle ?? "rainbow";
|
|
15885
16313
|
const liveThinkingWord = liveSettings?.thinkingWord ?? "thinking";
|
|
15886
16314
|
const [rolledThinkingWord, setRolledThinkingWord] = useState(() => pickRandomTuiThinkingWord());
|
|
15887
16315
|
const thinkingWorking = state.status === "running" || state.status === "streaming";
|
|
@@ -16528,7 +16956,8 @@ function App({
|
|
|
16528
16956
|
reasoningPreserve: sp.reasoningPreserve,
|
|
16529
16957
|
thinkingWord: sp.thinkingWord,
|
|
16530
16958
|
cacheTtl: sp.cacheTtl,
|
|
16531
|
-
configScope: sp.configScope
|
|
16959
|
+
configScope: sp.configScope,
|
|
16960
|
+
animationStyle: sp.animationStyle
|
|
16532
16961
|
});
|
|
16533
16962
|
}
|
|
16534
16963
|
if (prev.projectPicker) {
|
|
@@ -16748,7 +17177,13 @@ function App({
|
|
|
16748
17177
|
return () => {
|
|
16749
17178
|
if (onPanelOpen) onPanelOpen.current = null;
|
|
16750
17179
|
};
|
|
16751
|
-
}, [
|
|
17180
|
+
}, [
|
|
17181
|
+
onPanelOpen,
|
|
17182
|
+
dispatch,
|
|
17183
|
+
openProjectPicker,
|
|
17184
|
+
openStatuslinePicker,
|
|
17185
|
+
authPanelController.openAuthPanel
|
|
17186
|
+
]);
|
|
16752
17187
|
useEffect(() => {
|
|
16753
17188
|
if (!state.sessionsPanelOpen || !getLiveSessions) return void 0;
|
|
16754
17189
|
const t = setInterval(() => {
|
|
@@ -16797,7 +17232,8 @@ function App({
|
|
|
16797
17232
|
reasoningPreserve: s2.reasoningPreserve ?? false,
|
|
16798
17233
|
thinkingWord: s2.thinkingWord ?? "thinking",
|
|
16799
17234
|
cacheTtl: s2.cacheTtl ?? "default",
|
|
16800
|
-
configScope: s2.configScope ?? "global"
|
|
17235
|
+
configScope: s2.configScope ?? "global",
|
|
17236
|
+
animationStyle: s2.animationStyle ?? "rainbow"
|
|
16801
17237
|
});
|
|
16802
17238
|
}, [getSettings]);
|
|
16803
17239
|
const refreshPluginPicker = React5.useCallback(() => {
|
|
@@ -16985,7 +17421,8 @@ function App({
|
|
|
16985
17421
|
reasoningPreserve: sp.reasoningPreserve,
|
|
16986
17422
|
thinkingWord: sp.thinkingWord,
|
|
16987
17423
|
cacheTtl: sp.cacheTtl,
|
|
16988
|
-
configScope: sp.configScope
|
|
17424
|
+
configScope: sp.configScope,
|
|
17425
|
+
animationStyle: sp.animationStyle
|
|
16989
17426
|
})
|
|
16990
17427
|
).then((err) => {
|
|
16991
17428
|
if (err) dispatch({ type: "settingsHint", text: err });
|
|
@@ -17027,6 +17464,7 @@ function App({
|
|
|
17027
17464
|
state.settingsPicker.thinkingWord,
|
|
17028
17465
|
state.settingsPicker.cacheTtl,
|
|
17029
17466
|
state.settingsPicker.configScope,
|
|
17467
|
+
state.settingsPicker.animationStyle,
|
|
17030
17468
|
saveSettings
|
|
17031
17469
|
]);
|
|
17032
17470
|
useEffect(() => {
|
|
@@ -17664,6 +18102,14 @@ Available chords:
|
|
|
17664
18102
|
const [nextStepsAutoSubmitLabel, setNextStepsAutoSubmitLabel] = useState(null);
|
|
17665
18103
|
const nextStepsAutoSubmitSuggestionRef = useRef(null);
|
|
17666
18104
|
const nextStepsAutoSubmitTimerRef = useRef(void 0);
|
|
18105
|
+
const cancelNextStepsCountdown = useCallback(() => {
|
|
18106
|
+
if (nextStepsAutoSubmitTimerRef.current == null) return;
|
|
18107
|
+
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
18108
|
+
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
18109
|
+
setNextStepsAutoSubmitCountdown(null);
|
|
18110
|
+
setNextStepsAutoSubmitLabel(null);
|
|
18111
|
+
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
18112
|
+
}, []);
|
|
17667
18113
|
const getActiveSessionId = useCallback(() => agent.ctx.session.id, [agent]);
|
|
17668
18114
|
useTuiEventBridge({
|
|
17669
18115
|
events,
|
|
@@ -18452,7 +18898,8 @@ Available chords:
|
|
|
18452
18898
|
reasoningPreserve: cfg.reasoningPreserve ?? false,
|
|
18453
18899
|
thinkingWord: cfg.thinkingWord ?? "thinking",
|
|
18454
18900
|
cacheTtl: cfg.cacheTtl ?? "default",
|
|
18455
|
-
configScope: cfg.configScope ?? "global"
|
|
18901
|
+
configScope: cfg.configScope ?? "global",
|
|
18902
|
+
animationStyle: cfg.animationStyle ?? "rainbow"
|
|
18456
18903
|
});
|
|
18457
18904
|
}
|
|
18458
18905
|
return;
|
|
@@ -18538,19 +18985,11 @@ Available chords:
|
|
|
18538
18985
|
}
|
|
18539
18986
|
if (key.backspace) {
|
|
18540
18987
|
if (key.ctrl) {
|
|
18541
|
-
|
|
18542
|
-
|
|
18543
|
-
|
|
18544
|
-
|
|
18545
|
-
|
|
18546
|
-
if (nextStepsAutoSubmitTimerRef.current != null) {
|
|
18547
|
-
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
18548
|
-
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
18549
|
-
setNextStepsAutoSubmitCountdown(null);
|
|
18550
|
-
setNextStepsAutoSubmitLabel(null);
|
|
18551
|
-
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
18552
|
-
}
|
|
18553
|
-
setDraft(next3, deleteStart);
|
|
18988
|
+
const res = deleteWordBackward(buffer, cursor);
|
|
18989
|
+
if (res) {
|
|
18990
|
+
cancelNextStepsCountdown();
|
|
18991
|
+
setDraft(res.buffer, res.cursor);
|
|
18992
|
+
}
|
|
18554
18993
|
return;
|
|
18555
18994
|
}
|
|
18556
18995
|
const tokenDel = deleteTokenBackward(buffer, cursor);
|
|
@@ -18560,43 +18999,31 @@ Available chords:
|
|
|
18560
18999
|
}
|
|
18561
19000
|
if (cursor === 0) return;
|
|
18562
19001
|
const next2 = buffer.slice(0, cursor - 1) + buffer.slice(cursor);
|
|
18563
|
-
|
|
18564
|
-
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
18565
|
-
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
18566
|
-
setNextStepsAutoSubmitCountdown(null);
|
|
18567
|
-
setNextStepsAutoSubmitLabel(null);
|
|
18568
|
-
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
18569
|
-
}
|
|
19002
|
+
cancelNextStepsCountdown();
|
|
18570
19003
|
setDraft(next2, cursor - 1);
|
|
18571
19004
|
return;
|
|
18572
19005
|
}
|
|
19006
|
+
if (key.ctrl && input === "w") {
|
|
19007
|
+
const res = deleteWordBackward(buffer, cursor);
|
|
19008
|
+
if (res) {
|
|
19009
|
+
cancelNextStepsCountdown();
|
|
19010
|
+
setDraft(res.buffer, res.cursor);
|
|
19011
|
+
}
|
|
19012
|
+
return;
|
|
19013
|
+
}
|
|
18573
19014
|
if (key.delete) {
|
|
18574
19015
|
if (key.ctrl) {
|
|
18575
|
-
|
|
18576
|
-
|
|
18577
|
-
|
|
18578
|
-
|
|
18579
|
-
|
|
18580
|
-
if (nextStepsAutoSubmitTimerRef.current != null) {
|
|
18581
|
-
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
18582
|
-
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
18583
|
-
setNextStepsAutoSubmitCountdown(null);
|
|
18584
|
-
setNextStepsAutoSubmitLabel(null);
|
|
18585
|
-
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
18586
|
-
}
|
|
18587
|
-
setDraft(next3, deleteStart);
|
|
19016
|
+
const res = deleteWordForward(buffer, cursor);
|
|
19017
|
+
if (res) {
|
|
19018
|
+
cancelNextStepsCountdown();
|
|
19019
|
+
setDraft(res.buffer, res.cursor);
|
|
19020
|
+
}
|
|
18588
19021
|
return;
|
|
18589
19022
|
}
|
|
18590
19023
|
if (cursor >= buffer.length) return;
|
|
18591
19024
|
const span = tokenLengthForward(buffer, cursor) || 1;
|
|
18592
19025
|
const next2 = buffer.slice(0, cursor) + buffer.slice(cursor + span);
|
|
18593
|
-
|
|
18594
|
-
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
18595
|
-
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
18596
|
-
setNextStepsAutoSubmitCountdown(null);
|
|
18597
|
-
setNextStepsAutoSubmitLabel(null);
|
|
18598
|
-
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
18599
|
-
}
|
|
19026
|
+
cancelNextStepsCountdown();
|
|
18600
19027
|
setDraft(next2, cursor);
|
|
18601
19028
|
return;
|
|
18602
19029
|
}
|
|
@@ -18809,13 +19236,7 @@ Available chords:
|
|
|
18809
19236
|
return;
|
|
18810
19237
|
}
|
|
18811
19238
|
if (key.ctrl && input === "u") {
|
|
18812
|
-
|
|
18813
|
-
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
18814
|
-
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
18815
|
-
setNextStepsAutoSubmitCountdown(null);
|
|
18816
|
-
setNextStepsAutoSubmitLabel(null);
|
|
18817
|
-
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
18818
|
-
}
|
|
19239
|
+
cancelNextStepsCountdown();
|
|
18819
19240
|
setDraft("", 0);
|
|
18820
19241
|
return;
|
|
18821
19242
|
}
|
|
@@ -18823,26 +19244,14 @@ Available chords:
|
|
|
18823
19244
|
if (cursor >= buffer.length) return;
|
|
18824
19245
|
const span = tokenLengthForward(buffer, cursor) || 1;
|
|
18825
19246
|
const next2 = buffer.slice(0, cursor) + buffer.slice(cursor + span);
|
|
18826
|
-
|
|
18827
|
-
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
18828
|
-
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
18829
|
-
setNextStepsAutoSubmitCountdown(null);
|
|
18830
|
-
setNextStepsAutoSubmitLabel(null);
|
|
18831
|
-
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
18832
|
-
}
|
|
19247
|
+
cancelNextStepsCountdown();
|
|
18833
19248
|
setDraft(next2, cursor);
|
|
18834
19249
|
return;
|
|
18835
19250
|
}
|
|
18836
19251
|
if (key.ctrl && input === "k") {
|
|
18837
19252
|
if (cursor >= buffer.length) return;
|
|
18838
19253
|
const next2 = buffer.slice(0, cursor);
|
|
18839
|
-
|
|
18840
|
-
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
18841
|
-
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
18842
|
-
setNextStepsAutoSubmitCountdown(null);
|
|
18843
|
-
setNextStepsAutoSubmitLabel(null);
|
|
18844
|
-
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
18845
|
-
}
|
|
19254
|
+
cancelNextStepsCountdown();
|
|
18846
19255
|
setDraft(next2, cursor);
|
|
18847
19256
|
return;
|
|
18848
19257
|
}
|
|
@@ -18864,13 +19273,7 @@ Available chords:
|
|
|
18864
19273
|
await commitPaste(input);
|
|
18865
19274
|
return;
|
|
18866
19275
|
}
|
|
18867
|
-
|
|
18868
|
-
clearInterval(nextStepsAutoSubmitTimerRef.current);
|
|
18869
|
-
nextStepsAutoSubmitTimerRef.current = void 0;
|
|
18870
|
-
setNextStepsAutoSubmitCountdown(null);
|
|
18871
|
-
setNextStepsAutoSubmitLabel(null);
|
|
18872
|
-
nextStepsAutoSubmitSuggestionRef.current = null;
|
|
18873
|
-
}
|
|
19276
|
+
cancelNextStepsCountdown();
|
|
18874
19277
|
const next = buffer.slice(0, cursor) + input + buffer.slice(cursor);
|
|
18875
19278
|
setDraft(next, cursor + input.length);
|
|
18876
19279
|
};
|
|
@@ -18900,10 +19303,15 @@ Available chords:
|
|
|
18900
19303
|
}
|
|
18901
19304
|
});
|
|
18902
19305
|
}
|
|
19306
|
+
const assistantEntriesBeforeRun = stateRef.current.entries.filter(
|
|
19307
|
+
(entry) => entry.kind === "assistant"
|
|
19308
|
+
).length;
|
|
18903
19309
|
const result = await agent.run(routed.blocks, { signal: ctrl.signal });
|
|
18904
19310
|
const lingering = streamingTextRef.current;
|
|
18905
19311
|
if (lingering.trim()) {
|
|
18906
19312
|
dispatch({ type: "addEntry", entry: { kind: "assistant", text: lingering } });
|
|
19313
|
+
} else if (result.status === "done" && result.finalText?.trim() && stateRef.current.entries.filter((entry) => entry.kind === "assistant").length === assistantEntriesBeforeRun) {
|
|
19314
|
+
dispatch({ type: "addEntry", entry: { kind: "assistant", text: result.finalText } });
|
|
18907
19315
|
}
|
|
18908
19316
|
streamingTextRef.current = "";
|
|
18909
19317
|
pendingDeltaRef.current = "";
|
|
@@ -19607,6 +20015,7 @@ ${content}
|
|
|
19607
20015
|
reasoningPreserve: state.settingsPicker.reasoningPreserve,
|
|
19608
20016
|
cacheTtl: state.settingsPicker.cacheTtl,
|
|
19609
20017
|
configScope: state.settingsPicker.configScope,
|
|
20018
|
+
animationStyle: state.settingsPicker.animationStyle,
|
|
19610
20019
|
filter: state.settingsPicker.filter,
|
|
19611
20020
|
hint: state.settingsPicker.hint
|
|
19612
20021
|
}
|
|
@@ -19819,6 +20228,13 @@ ${content}
|
|
|
19819
20228
|
version: appVersion,
|
|
19820
20229
|
state: state.status,
|
|
19821
20230
|
thinkingWord: displayThinkingWord,
|
|
20231
|
+
thinkingAnimationStyle: (
|
|
20232
|
+
// While the settings picker is open, preview the picker's live
|
|
20233
|
+
// ←/→ selection synchronously (saveSettings → configStore is
|
|
20234
|
+
// async, so liveAnimationStyle lags a keystroke). When closed,
|
|
20235
|
+
// use the persisted value from getSettings().
|
|
20236
|
+
state.settingsPicker.open ? state.settingsPicker.animationStyle : liveAnimationStyle
|
|
20237
|
+
),
|
|
19822
20238
|
tokenCounter,
|
|
19823
20239
|
hint: renderRunningTools(state.runningTools) || state.hint,
|
|
19824
20240
|
queueCount: state.queue.length,
|
|
@@ -19854,7 +20270,7 @@ ${content}
|
|
|
19854
20270
|
autoProceedCountdown: state.countdown?.remainingSeconds ?? null,
|
|
19855
20271
|
sessionCount,
|
|
19856
20272
|
mailbox: mailboxStatus,
|
|
19857
|
-
tokenSavingMode:
|
|
20273
|
+
tokenSavingMode: liveSettings?.featureTokenSaving ?? tokenSavingMode,
|
|
19858
20274
|
toolCount,
|
|
19859
20275
|
sideEffectCount: agent.ctx.sideEffects?.length ?? 0
|
|
19860
20276
|
}
|