@wrongstack/tui 0.310.0 → 0.313.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-action-type.d.ts +28 -1
- package/dist/app-settings-type.d.ts +13 -1
- package/dist/app-state.d.ts +19 -1
- package/dist/app-view-sidebar.d.ts +10 -2
- package/dist/app-view-state.d.ts +1 -1
- package/dist/components/animation-style.d.ts +2 -2
- package/dist/components/history/scroll-controller-types.d.ts +49 -14
- package/dist/components/history/scrollbar-rail.d.ts +10 -1
- package/dist/components/history/selection-band-store.d.ts +38 -0
- package/dist/components/history/selection-helpers.d.ts +8 -1
- package/dist/components/history/use-history-controller.d.ts +6 -1
- package/dist/components/history/wrap-geometry.d.ts +130 -0
- package/dist/components/settings-picker-model.d.ts +9 -1
- package/dist/components/settings-picker.d.ts +17 -1
- package/dist/components/sidebar-content.d.ts +1 -1
- package/dist/components/sidebar-panels-workspace.d.ts +23 -0
- package/dist/components/sidebar-panels.d.ts +1 -1
- package/dist/components/status-bar-rails.d.ts +6 -0
- package/dist/hooks/use-live-settings-state.d.ts +1 -1
- package/dist/hooks/use-mouse-tracking.d.ts +1 -1
- package/dist/hooks/use-sidebar-panel-data.d.ts +38 -0
- package/dist/index.js +799 -156
- package/dist/input-validation/action-types.d.ts +1 -1
- package/dist/mouse.d.ts +3 -2
- package/dist/reducers/settings-values.d.ts +1 -1
- package/dist/settings-contracts.d.ts +15 -1
- package/dist/ui-contracts.d.ts +3 -2
- package/package.json +8 -7
package/dist/index.js
CHANGED
|
@@ -1936,7 +1936,7 @@ var PANEL_IDS = Object.freeze([
|
|
|
1936
1936
|
"connections"
|
|
1937
1937
|
// Ctrl+N
|
|
1938
1938
|
]);
|
|
1939
|
-
var TOTAL_SETTINGS_FIELD_COUNT = PANEL_POSITION_FIELD_START + PANEL_IDS.length;
|
|
1939
|
+
var TOTAL_SETTINGS_FIELD_COUNT = PANEL_POSITION_FIELD_START + PANEL_IDS.length + 2;
|
|
1940
1940
|
var DEFAULT_PANEL_POSITIONS = Object.freeze({
|
|
1941
1941
|
projectPicker: "bottom",
|
|
1942
1942
|
fleet: "bottom",
|
|
@@ -2601,20 +2601,23 @@ var ACCENT = "#fab387";
|
|
|
2601
2601
|
var DIM = "#313244";
|
|
2602
2602
|
var BREATHE_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
2603
2603
|
var DOTS_FRAMES = ["", ".", "..", "...", "..", "."];
|
|
2604
|
-
var ANIMATION_STYLES = ["rainbow", "wave", "pulse", "dots", "breathe"];
|
|
2604
|
+
var ANIMATION_STYLES = ["rainbow", "wave", "pulse", "dots", "breathe", "static"];
|
|
2605
2605
|
var ANIMATION_STYLE_DESCS = {
|
|
2606
2606
|
rainbow: "Per-glyph hue cycle (default)",
|
|
2607
2607
|
wave: "Single-color brightness sweep",
|
|
2608
2608
|
pulse: "Whole-text brightness pulse",
|
|
2609
2609
|
dots: "Trailing dots ellipsis (. .. ... .. .)",
|
|
2610
|
-
breathe: "Spinning braille glyph prefix, flat text"
|
|
2610
|
+
breathe: "Spinning braille glyph prefix, flat text",
|
|
2611
|
+
static: "No animation \u2014 flat working indicator"
|
|
2611
2612
|
};
|
|
2612
2613
|
var CYCLE_INTERVAL_SECONDS = 12;
|
|
2613
2614
|
var COLOR_TICK_MS = 120;
|
|
2614
2615
|
function colorPhaseFromTime(elapsedMs) {
|
|
2615
2616
|
return Math.floor(Math.max(0, elapsedMs) / COLOR_TICK_MS);
|
|
2616
2617
|
}
|
|
2617
|
-
var CYCLE_ORDER =
|
|
2618
|
+
var CYCLE_ORDER = ANIMATION_STYLES.filter(
|
|
2619
|
+
(style) => style !== "rainbow"
|
|
2620
|
+
);
|
|
2618
2621
|
function styleForCycleTick(tick) {
|
|
2619
2622
|
const idx = Math.max(0, Math.floor(tick / CYCLE_INTERVAL_SECONDS));
|
|
2620
2623
|
const i = idx % CYCLE_ORDER.length;
|
|
@@ -2747,9 +2750,10 @@ function ThinkingChip({
|
|
|
2747
2750
|
phase,
|
|
2748
2751
|
cycleTick
|
|
2749
2752
|
}) {
|
|
2750
|
-
const { time: colorTime } = useAnimation({ interval: COLOR_TICK_MS, isActive: true });
|
|
2751
|
-
const colorPhase = colorPhaseFromTime(colorTime);
|
|
2752
2753
|
const live = style === "cycle" ? styleForCycleTick(cycleTick) : style;
|
|
2754
|
+
const animateColor = live === "rainbow" || live === "wave" || live === "pulse";
|
|
2755
|
+
const { time: colorTime } = useAnimation({ interval: COLOR_TICK_MS, isActive: animateColor });
|
|
2756
|
+
const colorPhase = colorPhaseFromTime(animateColor ? colorTime : 0);
|
|
2753
2757
|
if (live === "rainbow") {
|
|
2754
2758
|
const chars = Array.from(text);
|
|
2755
2759
|
return /* @__PURE__ */ jsx5(Text, { bold: true, children: chars.map((ch, i) => /* @__PURE__ */ jsx5(Text, { color: rainbowColor(i, colorPhase), children: ch }, i)) });
|
|
@@ -2761,6 +2765,9 @@ function ThinkingChip({
|
|
|
2761
2765
|
if (live === "pulse") {
|
|
2762
2766
|
return /* @__PURE__ */ jsx5(Text, { bold: true, color: pulseColor(colorPhase), children: text });
|
|
2763
2767
|
}
|
|
2768
|
+
if (live === "static") {
|
|
2769
|
+
return /* @__PURE__ */ jsx5(Text, { bold: true, color: "green", children: text });
|
|
2770
|
+
}
|
|
2764
2771
|
if (live === "dots") {
|
|
2765
2772
|
const stripped = stripTrailingDots(text);
|
|
2766
2773
|
const idx2 = phase % DOTS_FRAMES.length;
|
|
@@ -3272,7 +3279,19 @@ function buildPrimaryChips(p) {
|
|
|
3272
3279
|
STATUSLINE_ICONS.cache,
|
|
3273
3280
|
" ",
|
|
3274
3281
|
(cache2.hitRatio * 100).toFixed(0),
|
|
3275
|
-
"%"
|
|
3282
|
+
"%",
|
|
3283
|
+
/* @__PURE__ */ jsxs5(Text, { children: [
|
|
3284
|
+
" r",
|
|
3285
|
+
fmtTok(cache2.readTokens)
|
|
3286
|
+
] }),
|
|
3287
|
+
/* @__PURE__ */ jsxs5(Text, { children: [
|
|
3288
|
+
" w",
|
|
3289
|
+
fmtTok(cache2.writeTokens)
|
|
3290
|
+
] }),
|
|
3291
|
+
cache2.savedUsd > 0 ? /* @__PURE__ */ jsxs5(Text, { children: [
|
|
3292
|
+
" ~$",
|
|
3293
|
+
cache2.savedUsd.toFixed(2)
|
|
3294
|
+
] }) : null
|
|
3276
3295
|
] }) : null
|
|
3277
3296
|
] });
|
|
3278
3297
|
})() : null,
|
|
@@ -3815,7 +3834,7 @@ function StatusBar({
|
|
|
3815
3834
|
fleet?.running ?? 0,
|
|
3816
3835
|
thinkingWord
|
|
3817
3836
|
);
|
|
3818
|
-
const statePrefix = state === "idle" || state === "aborting" ? "\u25CF" : spinner;
|
|
3837
|
+
const statePrefix = state === "idle" || state === "aborting" ? "\u25CF" : animationStyle === "static" ? "\u25CF" : spinner;
|
|
3819
3838
|
const thinking = state === "running" || state === "streaming";
|
|
3820
3839
|
const hasAutoProceed = autoProceedCountdown != null && autoProceedCountdown > 0;
|
|
3821
3840
|
const fleetHasActivity = fleet && (fleet.running > 0 || fleet.idle > 0 || fleet.pending > 0 || fleet.completed > 0) || subagentCount > 0;
|
|
@@ -14976,7 +14995,7 @@ function ConnectionsPanel({
|
|
|
14976
14995
|
const [loading, setLoading] = useState17(true);
|
|
14977
14996
|
const [error, setError] = useState17(null);
|
|
14978
14997
|
const cancelledRef = useRef3(false);
|
|
14979
|
-
const
|
|
14998
|
+
const fetch2 = useCallback4(async () => {
|
|
14980
14999
|
try {
|
|
14981
15000
|
const r = await collectConnectionsHealth(projectRoot);
|
|
14982
15001
|
if (cancelledRef.current) return;
|
|
@@ -14991,18 +15010,18 @@ function ConnectionsPanel({
|
|
|
14991
15010
|
}, [projectRoot]);
|
|
14992
15011
|
useEffect16(() => {
|
|
14993
15012
|
cancelledRef.current = false;
|
|
14994
|
-
void
|
|
14995
|
-
const timer = setInterval(() => void
|
|
15013
|
+
void fetch2();
|
|
15014
|
+
const timer = setInterval(() => void fetch2(), REFRESH_MS);
|
|
14996
15015
|
return () => {
|
|
14997
15016
|
cancelledRef.current = true;
|
|
14998
15017
|
clearInterval(timer);
|
|
14999
15018
|
};
|
|
15000
|
-
}, [
|
|
15019
|
+
}, [fetch2]);
|
|
15001
15020
|
const shortcutsEnabled = usePanelShortcutsEnabled();
|
|
15002
15021
|
useInput((_input, _key) => {
|
|
15003
15022
|
if (!shortcutsEnabled) return;
|
|
15004
15023
|
if (_input === "q") onClose();
|
|
15005
|
-
if (_input === "r") void
|
|
15024
|
+
if (_input === "r") void fetch2();
|
|
15006
15025
|
});
|
|
15007
15026
|
const overallLabel = report ? report.overall === "healthy" ? "All required services healthy" : report.overall === "degraded" ? "Some services degraded" : "Service errors detected" : "Checking\u2026";
|
|
15008
15027
|
return /* @__PURE__ */ jsxs40(
|
|
@@ -17711,6 +17730,7 @@ var MODE_DESC = {
|
|
|
17711
17730
|
};
|
|
17712
17731
|
var SETTINGS_FIELD_COUNT = TOTAL_SETTINGS_FIELD_COUNT;
|
|
17713
17732
|
var THINKING_WORD_FIELD = 22;
|
|
17733
|
+
var WRONGPROXY_URL_FIELD = 60;
|
|
17714
17734
|
var THINKING_WORD_PRESETS = [
|
|
17715
17735
|
"thinking",
|
|
17716
17736
|
"random",
|
|
@@ -17844,8 +17864,17 @@ var SETTINGS_FIELD_LABELS = [
|
|
|
17844
17864
|
// 56 (P panel id index 10)
|
|
17845
17865
|
"Kanban placement",
|
|
17846
17866
|
// 57 (P panel id index 11)
|
|
17847
|
-
"Connections placement"
|
|
17867
|
+
"Connections placement",
|
|
17848
17868
|
// 58 (P panel id index 12)
|
|
17869
|
+
// WrongProxy / WrongTrace (appended at the end so existing field
|
|
17870
|
+
// indices 0–58 — including the panel-position block at 46–58 — are
|
|
17871
|
+
// not shifted by the addition). The runtime probe in
|
|
17872
|
+
// `packages/cli/src/wiring/proxy-probe.ts` reacts to these via the
|
|
17873
|
+
// WS `prefs.update` pipeline; the picker is just the user surface.
|
|
17874
|
+
"WrongProxy / WrongTrace",
|
|
17875
|
+
// 59
|
|
17876
|
+
"WrongProxy URL"
|
|
17877
|
+
// 60
|
|
17849
17878
|
];
|
|
17850
17879
|
function resolveSettingsFieldValue(field, input) {
|
|
17851
17880
|
const raw = input.trim().toLowerCase();
|
|
@@ -17872,7 +17901,10 @@ function resolveSettingsFieldValue(field, input) {
|
|
|
17872
17901
|
// [40, 'showAgentSwarmPanel'] — now an enum, see ENUM_FIELDS below
|
|
17873
17902
|
[42, "readSymbols"],
|
|
17874
17903
|
[43, "showSageMemoryInject"],
|
|
17875
|
-
[45, "nextStepsTool"]
|
|
17904
|
+
[45, "nextStepsTool"],
|
|
17905
|
+
// WrongProxy / WrongTrace master switch (field 59). The companion
|
|
17906
|
+
// URL field (60) is text-typed, see resolveSettingsFieldValue.
|
|
17907
|
+
[59, "wrongProxyEnabled"]
|
|
17876
17908
|
]);
|
|
17877
17909
|
const boolKey = BOOL_FIELDS.get(field);
|
|
17878
17910
|
if (boolKey) {
|
|
@@ -18033,6 +18065,16 @@ function resolveSettingsFieldValue(field, input) {
|
|
|
18033
18065
|
}
|
|
18034
18066
|
return { ok: true, patch: { thinkingWord: word }, label, displayValue: word };
|
|
18035
18067
|
}
|
|
18068
|
+
if (field === 60) {
|
|
18069
|
+
const url = input.trim();
|
|
18070
|
+
if (url.length === 0) {
|
|
18071
|
+
return { ok: false, error: `"${input}" is not a valid proxy URL. Use http://host:port or https://host:port.` };
|
|
18072
|
+
}
|
|
18073
|
+
if (!/^https?:\/\//i.test(url)) {
|
|
18074
|
+
return { ok: false, error: `"${input}" is not a valid proxy URL. Use http://host:port or https://host:port.` };
|
|
18075
|
+
}
|
|
18076
|
+
return { ok: true, patch: { wrongProxyUrl: url }, label, displayValue: url };
|
|
18077
|
+
}
|
|
18036
18078
|
if (field >= PANEL_POSITION_FIELD_START && field - PANEL_POSITION_FIELD_START < PANEL_IDS.length) {
|
|
18037
18079
|
const panelId = PANEL_IDS[field - PANEL_POSITION_FIELD_START];
|
|
18038
18080
|
if (raw === "bottom" || raw === "sidebar") {
|
|
@@ -18074,7 +18116,10 @@ function getSettingsFieldValue(values, field) {
|
|
|
18074
18116
|
// [40, 'showAgentSwarmPanel'] — now an enum, see ENUM_KEYS below
|
|
18075
18117
|
[42, "readSymbols"],
|
|
18076
18118
|
[43, "showSageMemoryInject"],
|
|
18077
|
-
[45, "nextStepsTool"]
|
|
18119
|
+
[45, "nextStepsTool"],
|
|
18120
|
+
// WrongProxy / WrongTrace master switch (field 59). The companion
|
|
18121
|
+
// URL field (60) is text-typed, see getSettingsFieldValue.
|
|
18122
|
+
[59, "wrongProxyEnabled"]
|
|
18078
18123
|
];
|
|
18079
18124
|
for (const [f, key] of BOOL_KEYS) {
|
|
18080
18125
|
if (field !== f) continue;
|
|
@@ -18120,6 +18165,9 @@ function getSettingsFieldValue(values, field) {
|
|
|
18120
18165
|
if (field === 22) {
|
|
18121
18166
|
return { ok: true, label, displayValue: values.thinkingWord };
|
|
18122
18167
|
}
|
|
18168
|
+
if (field === 60) {
|
|
18169
|
+
return { ok: true, label, displayValue: values.wrongProxyUrl };
|
|
18170
|
+
}
|
|
18123
18171
|
if (field >= PANEL_POSITION_FIELD_START && field - PANEL_POSITION_FIELD_START < PANEL_IDS.length) {
|
|
18124
18172
|
const panelId = PANEL_IDS[field - PANEL_POSITION_FIELD_START];
|
|
18125
18173
|
return {
|
|
@@ -18178,6 +18226,16 @@ var SETTINGS_SECTIONS = [
|
|
|
18178
18226
|
{
|
|
18179
18227
|
name: "Panels",
|
|
18180
18228
|
fields: [46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58]
|
|
18229
|
+
},
|
|
18230
|
+
{
|
|
18231
|
+
// WrongProxy / WrongTrace — fields 59 (master switch) + 60 (URL).
|
|
18232
|
+
// Sits in its own section because the runtime probe + base-URL
|
|
18233
|
+
// rewrite it controls live outside the picker's normal "feature
|
|
18234
|
+
// toggle" semantics; matching the WebUI's IntegrationsSection
|
|
18235
|
+
// keeps the cross-surface contract obvious. Appended at the end
|
|
18236
|
+
// to avoid shifting the panel-position block 46–58 indices.
|
|
18237
|
+
name: "Integrations",
|
|
18238
|
+
fields: [59, 60]
|
|
18181
18239
|
}
|
|
18182
18240
|
];
|
|
18183
18241
|
function formatAllSettingsSummary(values) {
|
|
@@ -18247,7 +18305,15 @@ var SETTINGS_DEFAULTS = Object.freeze({
|
|
|
18247
18305
|
readSymbols: false,
|
|
18248
18306
|
showSageMemoryInject: true,
|
|
18249
18307
|
sageMemoryInjectThreshold: 0.85,
|
|
18250
|
-
nextStepsTool: false
|
|
18308
|
+
nextStepsTool: false,
|
|
18309
|
+
// WrongProxy / WrongTrace. Defaults mirror the WebUI `LocalPrefs`
|
|
18310
|
+
// DEFAULTS in `packages/webui/src/stores/local-prefs.ts` (master
|
|
18311
|
+
// switch off, URL 'http://localhost:3444'). Required keys here
|
|
18312
|
+
// because `SettingsPickerValues` (mapped from `SettingsPickerPatch`)
|
|
18313
|
+
// makes every key mandatory — omitting them here breaks the type
|
|
18314
|
+
// contract for the entire TUI settings module. See Chimera review.
|
|
18315
|
+
wrongProxyEnabled: false,
|
|
18316
|
+
wrongProxyUrl: "http://localhost:3444"
|
|
18251
18317
|
});
|
|
18252
18318
|
function resetSettingsFieldValue(field) {
|
|
18253
18319
|
const result = getSettingsFieldValue(SETTINGS_DEFAULTS, field);
|
|
@@ -18303,7 +18369,14 @@ function buildResetPatch(field) {
|
|
|
18303
18369
|
[42, "readSymbols"],
|
|
18304
18370
|
[43, "showSageMemoryInject"],
|
|
18305
18371
|
[44, "sageMemoryInjectThreshold"],
|
|
18306
|
-
[45, "nextStepsTool"]
|
|
18372
|
+
[45, "nextStepsTool"],
|
|
18373
|
+
// WrongProxy / WrongTrace: appended at the end so the existing
|
|
18374
|
+
// 46+13 = 59 entries are not shifted (the picker caps + scrolls;
|
|
18375
|
+
// field 59 is boolean, 60 is text). See `Settings.wrongProxy*`
|
|
18376
|
+
// and `ToolsConfig.wrongProxy?: WrongProxyToolConfig` for the
|
|
18377
|
+
// canonical persistence shape.
|
|
18378
|
+
[59, "wrongProxyEnabled"],
|
|
18379
|
+
[60, "wrongProxyUrl"]
|
|
18307
18380
|
];
|
|
18308
18381
|
for (const [f, key] of KEY_MAP) {
|
|
18309
18382
|
if (f === field) {
|
|
@@ -18432,6 +18505,8 @@ function SettingsPicker({
|
|
|
18432
18505
|
thinkingWord,
|
|
18433
18506
|
thinkingWordEditing,
|
|
18434
18507
|
thinkingWordDraft,
|
|
18508
|
+
wrongProxyUrlEditing,
|
|
18509
|
+
wrongProxyUrlDraft,
|
|
18435
18510
|
reasoningMode,
|
|
18436
18511
|
reasoningEffort,
|
|
18437
18512
|
reasoningPreserve,
|
|
@@ -18456,6 +18531,13 @@ function SettingsPicker({
|
|
|
18456
18531
|
nextStepsTool,
|
|
18457
18532
|
readSymbols,
|
|
18458
18533
|
panelPositions,
|
|
18534
|
+
// WrongProxy / WrongTrace: pick these from the same slice as
|
|
18535
|
+
// `nextStepsTool` and `readSymbols`. The runtime probe (see
|
|
18536
|
+
// `runtime-controller-deps.ts:applyLiveSettings`) reads them off the
|
|
18537
|
+
// same object, so adding both at the destructuring level keeps the
|
|
18538
|
+
// mid-session effect coherent.
|
|
18539
|
+
wrongProxyEnabled,
|
|
18540
|
+
wrongProxyUrl,
|
|
18459
18541
|
inputHeight,
|
|
18460
18542
|
hint,
|
|
18461
18543
|
onLayoutComputed
|
|
@@ -18725,7 +18807,25 @@ function SettingsPicker({
|
|
|
18725
18807
|
label: SETTINGS_FIELD_LABELS[45 + i] ?? panelId,
|
|
18726
18808
|
value: panelPositions[panelId],
|
|
18727
18809
|
detail: panelPositions[panelId] === "sidebar" ? "Render in right sidebar" : "Render in lower F-key region"
|
|
18728
|
-
}))
|
|
18810
|
+
})),
|
|
18811
|
+
// ── Integrations (fields 59–60) ─────────────────────────────────────
|
|
18812
|
+
// WrongProxy / WrongTrace. Appended at the end so the existing
|
|
18813
|
+
// field indices 0–58 (including the panel-position block 46–58)
|
|
18814
|
+
// remain stable — see the SettingsPicker "Appended to preserve"
|
|
18815
|
+
// comment above. The runtime probe (see
|
|
18816
|
+
// `runtime-controller-deps.ts:applyLiveSettings`) reads both keys
|
|
18817
|
+
// from the same SettingsPicker slice, so adding them at the
|
|
18818
|
+
// destructuring level keeps the mid-session effect coherent.
|
|
18819
|
+
{
|
|
18820
|
+
label: "WrongProxy / WrongTrace",
|
|
18821
|
+
value: boolVal(wrongProxyEnabled),
|
|
18822
|
+
detail: "Route base URLs through the local proxy (default http://localhost:3444). openai-codex is excluded."
|
|
18823
|
+
},
|
|
18824
|
+
{
|
|
18825
|
+
label: "WrongProxy URL",
|
|
18826
|
+
value: wrongProxyUrlEditing ? `${wrongProxyUrlDraft ?? ""}\u258F` : wrongProxyUrl,
|
|
18827
|
+
detail: wrongProxyUrlEditing ? "type a URL \xB7 Enter \u2713 \xB7 Esc \u2717 (http://host:port or https://host:port)" : "Where the local proxy daemon listens. Probed at <url>/api/health every 30s."
|
|
18828
|
+
}
|
|
18729
18829
|
];
|
|
18730
18830
|
const fieldRowIndex = [];
|
|
18731
18831
|
for (let i = 0; i < rows.length; i++) {
|
|
@@ -20069,6 +20169,10 @@ function AppViewPickers({
|
|
|
20069
20169
|
nextStepsTool: state.settingsPicker.nextStepsTool,
|
|
20070
20170
|
readSymbols: state.settingsPicker.readSymbols,
|
|
20071
20171
|
panelPositions: state.settingsPicker.panelPositions,
|
|
20172
|
+
wrongProxyEnabled: state.settingsPicker.wrongProxyEnabled,
|
|
20173
|
+
wrongProxyUrl: state.settingsPicker.wrongProxyUrl,
|
|
20174
|
+
wrongProxyUrlEditing: state.settingsPicker.wrongProxyUrlEditing,
|
|
20175
|
+
wrongProxyUrlDraft: state.settingsPicker.wrongProxyUrlDraft,
|
|
20072
20176
|
inputHeight,
|
|
20073
20177
|
filter: state.settingsPicker.filter,
|
|
20074
20178
|
hint: state.settingsPicker.hint
|
|
@@ -21147,7 +21251,39 @@ function SidebarContent({
|
|
|
21147
21251
|
accent: theme.warn,
|
|
21148
21252
|
innerWidth: bodyWidth
|
|
21149
21253
|
}
|
|
21150
|
-
)
|
|
21254
|
+
),
|
|
21255
|
+
cs.cacheWrite5m !== void 0 && cs.cacheWrite1h !== void 0 ? /* @__PURE__ */ jsxs77(Fragment25, { children: [
|
|
21256
|
+
/* @__PURE__ */ jsx78(
|
|
21257
|
+
SidebarStatRow,
|
|
21258
|
+
{
|
|
21259
|
+
label: "write 5m",
|
|
21260
|
+
value: fmtTok(cs.cacheWrite5m),
|
|
21261
|
+
color: theme.textSecondary,
|
|
21262
|
+
accent: theme.warn,
|
|
21263
|
+
innerWidth: bodyWidth
|
|
21264
|
+
}
|
|
21265
|
+
),
|
|
21266
|
+
/* @__PURE__ */ jsx78(
|
|
21267
|
+
SidebarStatRow,
|
|
21268
|
+
{
|
|
21269
|
+
label: "write 1h",
|
|
21270
|
+
value: fmtTok(cs.cacheWrite1h),
|
|
21271
|
+
color: theme.textSecondary,
|
|
21272
|
+
accent: theme.warn,
|
|
21273
|
+
innerWidth: bodyWidth
|
|
21274
|
+
}
|
|
21275
|
+
)
|
|
21276
|
+
] }) : null,
|
|
21277
|
+
cs.savedUsd > 0 ? /* @__PURE__ */ jsx78(
|
|
21278
|
+
SidebarStatRow,
|
|
21279
|
+
{
|
|
21280
|
+
label: "saved",
|
|
21281
|
+
value: `~${cs.savedUsd.toFixed(2)}`,
|
|
21282
|
+
color: theme.success,
|
|
21283
|
+
accent: theme.success,
|
|
21284
|
+
innerWidth: bodyWidth
|
|
21285
|
+
}
|
|
21286
|
+
) : null
|
|
21151
21287
|
] }) : null,
|
|
21152
21288
|
cacheCoverageTokens > 0 && contextWindow ? /* @__PURE__ */ jsx78(
|
|
21153
21289
|
SidebarStatRow,
|
|
@@ -21422,56 +21558,7 @@ function SidebarContent({
|
|
|
21422
21558
|
})
|
|
21423
21559
|
}
|
|
21424
21560
|
) : null
|
|
21425
|
-
] }) }) : null
|
|
21426
|
-
(() => {
|
|
21427
|
-
const liveTools = [];
|
|
21428
|
-
for (const entry of Object.values(entries)) {
|
|
21429
|
-
if (entry.currentTool?.name) {
|
|
21430
|
-
liveTools.push({
|
|
21431
|
-
agent: entry.name || entry.id,
|
|
21432
|
-
name: entry.currentTool.name,
|
|
21433
|
-
status: "RUNNING",
|
|
21434
|
-
color: theme.success
|
|
21435
|
-
});
|
|
21436
|
-
} else if (entry.recentTools && entry.recentTools.length > 0) {
|
|
21437
|
-
const lastTool = entry.recentTools[entry.recentTools.length - 1];
|
|
21438
|
-
if (lastTool?.name) {
|
|
21439
|
-
liveTools.push({
|
|
21440
|
-
agent: entry.name || entry.id,
|
|
21441
|
-
name: lastTool.name,
|
|
21442
|
-
status: lastTool.ok === false ? "FAIL" : "OK",
|
|
21443
|
-
color: lastTool.ok === false ? theme.error : theme.textMuted
|
|
21444
|
-
});
|
|
21445
|
-
}
|
|
21446
|
-
}
|
|
21447
|
-
}
|
|
21448
|
-
if (liveTools.length === 0) return null;
|
|
21449
|
-
return /* @__PURE__ */ jsx78(Card, { innerWidth, marginBottom: 0, accent: theme.accent, children: (bodyWidth) => /* @__PURE__ */ jsxs77(Fragment25, { children: [
|
|
21450
|
-
/* @__PURE__ */ jsx78(
|
|
21451
|
-
SidebarSectionHeader,
|
|
21452
|
-
{
|
|
21453
|
-
glyph: glyphs.tools,
|
|
21454
|
-
label: "TOOL TICKER",
|
|
21455
|
-
color: theme.accent,
|
|
21456
|
-
badge: liveTools.some((t) => t.status === "RUNNING") ? "STREAM" : "IDLE",
|
|
21457
|
-
badgeColor: liveTools.some((t) => t.status === "RUNNING") ? theme.success : theme.textMuted,
|
|
21458
|
-
innerWidth: bodyWidth,
|
|
21459
|
-
pill: true
|
|
21460
|
-
}
|
|
21461
|
-
),
|
|
21462
|
-
liveTools.slice(0, 3).map((item, i) => /* @__PURE__ */ jsx78(
|
|
21463
|
-
SidebarStatRow,
|
|
21464
|
-
{
|
|
21465
|
-
label: `${glyphs.zap} ${item.name}`,
|
|
21466
|
-
value: item.status,
|
|
21467
|
-
color: item.color,
|
|
21468
|
-
accent: item.color,
|
|
21469
|
-
innerWidth: bodyWidth
|
|
21470
|
-
},
|
|
21471
|
-
`ticker-${i}`
|
|
21472
|
-
))
|
|
21473
|
-
] }) });
|
|
21474
|
-
})()
|
|
21561
|
+
] }) }) : null
|
|
21475
21562
|
] });
|
|
21476
21563
|
}
|
|
21477
21564
|
|
|
@@ -22411,6 +22498,18 @@ function CoordinatorPanelSidebar({
|
|
|
22411
22498
|
}
|
|
22412
22499
|
);
|
|
22413
22500
|
}
|
|
22501
|
+
function wrongProxyVisual(status) {
|
|
22502
|
+
switch (status) {
|
|
22503
|
+
case "ok":
|
|
22504
|
+
return { glyph: glyphs.success, color: theme.success, pill: "LIVE" };
|
|
22505
|
+
case "warn":
|
|
22506
|
+
return { glyph: glyphs.warning, color: theme.warn, pill: "WARN" };
|
|
22507
|
+
case "down":
|
|
22508
|
+
return { glyph: glyphs.failure, color: theme.error, pill: "DOWN" };
|
|
22509
|
+
default:
|
|
22510
|
+
return { glyph: "?", color: theme.textMuted, pill: "?" };
|
|
22511
|
+
}
|
|
22512
|
+
}
|
|
22414
22513
|
function ConnectionsPanelSidebar({
|
|
22415
22514
|
connections,
|
|
22416
22515
|
width
|
|
@@ -22508,6 +22607,81 @@ function ConnectionsPanelSidebar({
|
|
|
22508
22607
|
}
|
|
22509
22608
|
);
|
|
22510
22609
|
}
|
|
22610
|
+
function WrongProxyPanelSidebar({
|
|
22611
|
+
proxy,
|
|
22612
|
+
width
|
|
22613
|
+
}) {
|
|
22614
|
+
const inner = Math.max(8, width);
|
|
22615
|
+
const bodyWidth = inner >= 18 ? inner - 4 : inner;
|
|
22616
|
+
const visual = proxy ? wrongProxyVisual(proxy.status) : wrongProxyVisual("unknown");
|
|
22617
|
+
const showLatency = inner >= METRIC_MIN_BODY_WIDTH;
|
|
22618
|
+
const latencyLabel = proxy?.latencyMs !== void 0 ? `${proxy.latencyMs}ms` : "";
|
|
22619
|
+
const urlLabel = proxy?.url ?? "\u2014";
|
|
22620
|
+
const ipcLabel = `${glyphs.dividerDot} ipc`;
|
|
22621
|
+
const ipcValue = proxy?.socketPath ? trunc(proxy.socketPath, Math.max(4, bodyWidth - displayWidth(ipcLabel) - 3)) : null;
|
|
22622
|
+
const daemonLabel = `${glyphs.dividerDot} daemon`;
|
|
22623
|
+
const daemonValue = proxy?.version ? trunc(proxy.version, Math.max(4, bodyWidth - displayWidth(daemonLabel) - 3)) : null;
|
|
22624
|
+
return /* @__PURE__ */ jsxs80(
|
|
22625
|
+
SidebarPanelFrame,
|
|
22626
|
+
{
|
|
22627
|
+
accent: visual.color,
|
|
22628
|
+
icon: glyphs.link,
|
|
22629
|
+
title: "WRONGPROXY",
|
|
22630
|
+
width,
|
|
22631
|
+
kicker: "proxy daemon",
|
|
22632
|
+
pillLabel: inner >= PILL_MIN_INNER_WIDTH ? `${visual.glyph} ${visual.pill}` : void 0,
|
|
22633
|
+
pillColor: visual.color,
|
|
22634
|
+
right: inner < PILL_MIN_INNER_WIDTH ? /* @__PURE__ */ jsxs80(Text, { color: visual.color, bold: true, children: [
|
|
22635
|
+
visual.glyph,
|
|
22636
|
+
" ",
|
|
22637
|
+
visual.pill
|
|
22638
|
+
] }) : void 0,
|
|
22639
|
+
children: [
|
|
22640
|
+
/* @__PURE__ */ jsxs80(Box, { flexDirection: "row", width: bodyWidth, children: [
|
|
22641
|
+
/* @__PURE__ */ jsx81(Text, { color: visual.color, children: visual.glyph }),
|
|
22642
|
+
/* @__PURE__ */ jsxs80(Text, { color: theme.textPrimary, bold: true, wrap: "truncate", children: [
|
|
22643
|
+
" ",
|
|
22644
|
+
trunc(
|
|
22645
|
+
urlLabel,
|
|
22646
|
+
Math.max(
|
|
22647
|
+
3,
|
|
22648
|
+
bodyWidth - (showLatency && latencyLabel ? displayWidth(latencyLabel) + 1 : 2)
|
|
22649
|
+
)
|
|
22650
|
+
)
|
|
22651
|
+
] }),
|
|
22652
|
+
showLatency && latencyLabel ? /* @__PURE__ */ jsxs80(Fragment27, { children: [
|
|
22653
|
+
/* @__PURE__ */ jsx81(Box, { flexGrow: 1 }),
|
|
22654
|
+
/* @__PURE__ */ jsx81(Text, { color: theme.textMuted, children: latencyLabel })
|
|
22655
|
+
] }) : null
|
|
22656
|
+
] }),
|
|
22657
|
+
proxy?.detail ? /* @__PURE__ */ jsxs80(Text, { color: proxy.status === "down" ? theme.error : theme.warn, wrap: "truncate", children: [
|
|
22658
|
+
glyphs.warning,
|
|
22659
|
+
" ",
|
|
22660
|
+
trunc(proxy.detail, bodyWidth - 2)
|
|
22661
|
+
] }) : null,
|
|
22662
|
+
ipcValue ? /* @__PURE__ */ jsx81(
|
|
22663
|
+
SidebarStatRow,
|
|
22664
|
+
{
|
|
22665
|
+
label: ipcLabel,
|
|
22666
|
+
value: ipcValue,
|
|
22667
|
+
color: theme.textMuted,
|
|
22668
|
+
innerWidth: bodyWidth,
|
|
22669
|
+
valueMuted: true
|
|
22670
|
+
}
|
|
22671
|
+
) : null,
|
|
22672
|
+
daemonValue ? /* @__PURE__ */ jsx81(
|
|
22673
|
+
SidebarStatRow,
|
|
22674
|
+
{
|
|
22675
|
+
label: daemonLabel,
|
|
22676
|
+
value: daemonValue,
|
|
22677
|
+
color: theme.textPrimary,
|
|
22678
|
+
innerWidth: bodyWidth
|
|
22679
|
+
}
|
|
22680
|
+
) : null
|
|
22681
|
+
]
|
|
22682
|
+
}
|
|
22683
|
+
);
|
|
22684
|
+
}
|
|
22511
22685
|
|
|
22512
22686
|
// src/app-view-sidebar.tsx
|
|
22513
22687
|
import { jsx as jsx82, jsxs as jsxs81 } from "react/jsx-runtime";
|
|
@@ -22521,7 +22695,9 @@ function AppViewSidebar({
|
|
|
22521
22695
|
sidebarProcessData,
|
|
22522
22696
|
sidebarConnectionsData,
|
|
22523
22697
|
sidebarKanbanData,
|
|
22524
|
-
sidebarPlanData
|
|
22698
|
+
sidebarPlanData,
|
|
22699
|
+
sidebarWrongProxyEnabled,
|
|
22700
|
+
sidebarWrongProxyData
|
|
22525
22701
|
}) {
|
|
22526
22702
|
const { agent } = host;
|
|
22527
22703
|
const { state, activity, environment, statusbar, liveTodos, liveSettings } = runtime;
|
|
@@ -22635,6 +22811,7 @@ function AppViewSidebar({
|
|
|
22635
22811
|
}
|
|
22636
22812
|
) : null,
|
|
22637
22813
|
sidebarSlotVisible("connections") ? /* @__PURE__ */ jsx82(ConnectionsPanelSidebar, { connections: sidebarConnectionsData, width: sidebarContentWidth }) : null,
|
|
22814
|
+
sidebarWrongProxyEnabled ? /* @__PURE__ */ jsx82(WrongProxyPanelSidebar, { proxy: sidebarWrongProxyData, width: sidebarContentWidth }) : null,
|
|
22638
22815
|
hiddenSidebarPanelCount > 0 ? /* @__PURE__ */ jsxs81(Text, { color: theme.textMuted, children: [
|
|
22639
22816
|
"+",
|
|
22640
22817
|
hiddenSidebarPanelCount,
|
|
@@ -22985,6 +23162,13 @@ function renderWorking(word, style, spinner, phase, colorPhase, maxWidth) {
|
|
|
22985
23162
|
width: displayWidth(text2)
|
|
22986
23163
|
};
|
|
22987
23164
|
}
|
|
23165
|
+
if (style === "static") {
|
|
23166
|
+
const text2 = truncateDisplay(word, maxWidth);
|
|
23167
|
+
return {
|
|
23168
|
+
node: /* @__PURE__ */ jsx83(Text, { bold: true, color: "green", children: text2 }),
|
|
23169
|
+
width: displayWidth(text2)
|
|
23170
|
+
};
|
|
23171
|
+
}
|
|
22988
23172
|
if (style === "breathe") {
|
|
22989
23173
|
const text2 = truncateDisplay(`${spinner} ${word}`, maxWidth);
|
|
22990
23174
|
return {
|
|
@@ -23057,6 +23241,7 @@ function ComposerTopRail({
|
|
|
23057
23241
|
}) {
|
|
23058
23242
|
const available = Math.max(0, width - 2);
|
|
23059
23243
|
const icon = glyphs.brand;
|
|
23244
|
+
const staticMode = animationStyle === "static";
|
|
23060
23245
|
const requestedStatusWidth = composerStatusReservedWidth(status);
|
|
23061
23246
|
const statusWidth = Math.min(requestedStatusWidth, Math.max(0, available - 3));
|
|
23062
23247
|
const statusSectionW = statusWidth > 0 ? statusWidth + 3 : 0;
|
|
@@ -23071,7 +23256,7 @@ function ComposerTopRail({
|
|
|
23071
23256
|
"\u256D",
|
|
23072
23257
|
title ? /* @__PURE__ */ jsxs83(Fragment29, { children: [
|
|
23073
23258
|
/* @__PURE__ */ jsx84(Text, { children: "\u2500 " }),
|
|
23074
|
-
/* @__PURE__ */ jsx84(ComposerActivityIcon, { status, idleGlyph: glyphs.brand, disabled }),
|
|
23259
|
+
staticMode ? /* @__PURE__ */ jsx84(Text, { bold: true, children: glyphs.brand }) : /* @__PURE__ */ jsx84(ComposerActivityIcon, { status, idleGlyph: glyphs.brand, disabled }),
|
|
23075
23260
|
/* @__PURE__ */ jsx84(Text, { children: ` ${title}` }),
|
|
23076
23261
|
workingTimeChip ? /* @__PURE__ */ jsx84(Text, { dimColor: true, children: workingTimeChip }) : null,
|
|
23077
23262
|
/* @__PURE__ */ jsx84(Text, { children: " " })
|
|
@@ -24457,7 +24642,7 @@ import { memo as memo6, useRef as useRef8 } from "react";
|
|
|
24457
24642
|
|
|
24458
24643
|
// src/components/history/entry.tsx
|
|
24459
24644
|
import { hasOpenTodos } from "@wrongstack/core/utils";
|
|
24460
|
-
import { parseNextSteps } from "@wrongstack/tools/next-steps";
|
|
24645
|
+
import { parseNextSteps as parseNextSteps2 } from "@wrongstack/tools/next-steps";
|
|
24461
24646
|
import React8, { useEffect as useEffect23, useMemo as useMemo8 } from "react";
|
|
24462
24647
|
|
|
24463
24648
|
// src/history-entry.ts
|
|
@@ -25773,6 +25958,63 @@ function ToolEntry({
|
|
|
25773
25958
|
] });
|
|
25774
25959
|
}
|
|
25775
25960
|
|
|
25961
|
+
// src/components/history/wrap-geometry.ts
|
|
25962
|
+
import { parseNextSteps } from "@wrongstack/tools/next-steps";
|
|
25963
|
+
import stringWidth2 from "string-width";
|
|
25964
|
+
import wrapAnsi from "wrap-ansi";
|
|
25965
|
+
var USER_LABEL = "\u{1F464} USER ";
|
|
25966
|
+
var INFO_PREFIX = "\u2139 ";
|
|
25967
|
+
function hasWrapMap(entry) {
|
|
25968
|
+
return entry.kind === "assistant" || entry.kind === "thinking" || entry.kind === "user" || entry.kind === "info";
|
|
25969
|
+
}
|
|
25970
|
+
function textContentWidth(termWidth) {
|
|
25971
|
+
return Math.max(1, termWidth - MESSAGE_PANEL_CHROME_WIDTH);
|
|
25972
|
+
}
|
|
25973
|
+
function infoContentWidth(termWidth) {
|
|
25974
|
+
return Math.max(1, termWidth);
|
|
25975
|
+
}
|
|
25976
|
+
function buildBodyRowMap(kind, rawText, termWidth) {
|
|
25977
|
+
const prefix = kind === "user" ? USER_LABEL : kind === "info" ? INFO_PREFIX : "";
|
|
25978
|
+
const prefixChars = prefix.length;
|
|
25979
|
+
const prefixWidth = stringWidth2(prefix);
|
|
25980
|
+
const base = sanitizeTerminalText(
|
|
25981
|
+
kind === "assistant" ? parseNextSteps(rawText, true).stripped : rawText
|
|
25982
|
+
);
|
|
25983
|
+
const width = kind === "info" ? infoContentWidth(termWidth) : textContentWidth(termWidth);
|
|
25984
|
+
const rows = [];
|
|
25985
|
+
const lines = base.split("\n");
|
|
25986
|
+
for (let i = 0; i < lines.length; i++) {
|
|
25987
|
+
const line = lines[i] ?? "";
|
|
25988
|
+
if (line.length === 0) {
|
|
25989
|
+
rows.push({ line: i, start: 0, end: 0 });
|
|
25990
|
+
continue;
|
|
25991
|
+
}
|
|
25992
|
+
const sub = i === 0 ? prefixChars : 0;
|
|
25993
|
+
const wrapped = i === 0 && prefixChars > 0 ? prefix + line : line;
|
|
25994
|
+
const segments = wrapAnsi(wrapped, width, { trim: false, hard: true }).split("\n");
|
|
25995
|
+
let offset = 0;
|
|
25996
|
+
for (const seg of segments) {
|
|
25997
|
+
rows.push({
|
|
25998
|
+
line: i,
|
|
25999
|
+
start: Math.max(0, offset - sub),
|
|
26000
|
+
end: Math.max(0, offset + seg.length - sub)
|
|
26001
|
+
});
|
|
26002
|
+
offset += seg.length;
|
|
26003
|
+
}
|
|
26004
|
+
}
|
|
26005
|
+
return { rows, text: base, prefixWidth };
|
|
26006
|
+
}
|
|
26007
|
+
function resolveRowCol(map, row, col, atEnd) {
|
|
26008
|
+
const last = map.rows.length - 1;
|
|
26009
|
+
if (last < 0) return { line: 0, offset: 0 };
|
|
26010
|
+
const idx = Math.max(0, Math.min(row, last));
|
|
26011
|
+
const span = map.rows[idx] ?? { line: 0, start: 0, end: 0 };
|
|
26012
|
+
const textCol = idx === 0 && map.prefixWidth > 0 ? Math.max(0, col - map.prefixWidth) : col;
|
|
26013
|
+
const segLen = span.end - span.start;
|
|
26014
|
+
const within = atEnd ? Math.max(0, Math.min(textCol + 1, segLen)) : Math.max(0, Math.min(textCol, segLen));
|
|
26015
|
+
return { line: span.line, offset: span.start + within };
|
|
26016
|
+
}
|
|
26017
|
+
|
|
25776
26018
|
// src/components/history/entry.tsx
|
|
25777
26019
|
import { Fragment as Fragment33, jsx as jsx94, jsxs as jsxs91 } from "react/jsx-runtime";
|
|
25778
26020
|
var Entry = React8.memo(function Entry2({
|
|
@@ -25790,7 +26032,7 @@ var Entry = React8.memo(function Entry2({
|
|
|
25790
26032
|
const isFinalTurnEntry = entry.kind === "assistant" && entry.final === true;
|
|
25791
26033
|
const nextSteps = useMemo8(() => {
|
|
25792
26034
|
if (entry.kind !== "assistant") return { steps: [], stripped: "" };
|
|
25793
|
-
return
|
|
26035
|
+
return parseNextSteps2(entry.text, true);
|
|
25794
26036
|
}, [entry.kind, entry.text]);
|
|
25795
26037
|
useEffect23(() => {
|
|
25796
26038
|
if (!setSuggestions) return;
|
|
@@ -25798,7 +26040,7 @@ var Entry = React8.memo(function Entry2({
|
|
|
25798
26040
|
if (openTodos) return;
|
|
25799
26041
|
if (!isFinalTurnEntry) return;
|
|
25800
26042
|
const text = entry.text ?? "";
|
|
25801
|
-
const { texts } =
|
|
26043
|
+
const { texts } = parseNextSteps2(text, true);
|
|
25802
26044
|
if (texts.length > 0) setSuggestions(texts);
|
|
25803
26045
|
}, [
|
|
25804
26046
|
entry.kind,
|
|
@@ -25820,7 +26062,7 @@ var Entry = React8.memo(function Entry2({
|
|
|
25820
26062
|
borderColor: theme.user,
|
|
25821
26063
|
paddingLeft: 1,
|
|
25822
26064
|
children: /* @__PURE__ */ jsxs91(Text, { children: [
|
|
25823
|
-
/* @__PURE__ */ jsx94(Text, { bold: true, color: theme.user, children:
|
|
26065
|
+
/* @__PURE__ */ jsx94(Text, { bold: true, color: theme.user, children: USER_LABEL }),
|
|
25824
26066
|
/* @__PURE__ */ jsx94(Text, { color: "white", children: sanitizeTerminalText(entry.text) }),
|
|
25825
26067
|
entry.queued ? /* @__PURE__ */ jsx94(Text, { dimColor: true, children: " (queued)" }) : null,
|
|
25826
26068
|
entry.pasteContent ? /* @__PURE__ */ jsxs91(Fragment33, { children: [
|
|
@@ -25967,7 +26209,7 @@ var Entry = React8.memo(function Entry2({
|
|
|
25967
26209
|
}
|
|
25968
26210
|
case "info": {
|
|
25969
26211
|
return /* @__PURE__ */ jsxs91(Text, { dimColor: true, children: [
|
|
25970
|
-
/* @__PURE__ */ jsx94(Text, { children:
|
|
26212
|
+
/* @__PURE__ */ jsx94(Text, { children: INFO_PREFIX }),
|
|
25971
26213
|
sanitizeTerminalText(entry.text)
|
|
25972
26214
|
] });
|
|
25973
26215
|
}
|
|
@@ -26216,7 +26458,7 @@ var History = memo6(function History2({
|
|
|
26216
26458
|
});
|
|
26217
26459
|
|
|
26218
26460
|
// src/components/history/use-history-controller.ts
|
|
26219
|
-
import {
|
|
26461
|
+
import { useCallback as useCallback5, useEffect as useEffect24, useMemo as useMemo9, useRef as useRef9 } from "react";
|
|
26220
26462
|
|
|
26221
26463
|
// src/clipboard.ts
|
|
26222
26464
|
import {
|
|
@@ -26282,6 +26524,38 @@ function selectionHitAt(row, spans) {
|
|
|
26282
26524
|
return null;
|
|
26283
26525
|
}
|
|
26284
26526
|
|
|
26527
|
+
// src/components/history/selection-band-store.ts
|
|
26528
|
+
function sameBand(a, b) {
|
|
26529
|
+
if (a === b) return true;
|
|
26530
|
+
if (a === null || b === null) return false;
|
|
26531
|
+
return a.topRow === b.topRow && a.bottomRow === b.bottomRow && a.headRow === b.headRow;
|
|
26532
|
+
}
|
|
26533
|
+
function bandFromSelection(anchor, head) {
|
|
26534
|
+
return {
|
|
26535
|
+
topRow: Math.min(anchor.row, head.row),
|
|
26536
|
+
bottomRow: Math.max(anchor.row, head.row),
|
|
26537
|
+
headRow: head.row
|
|
26538
|
+
};
|
|
26539
|
+
}
|
|
26540
|
+
function createSelectionBandStore() {
|
|
26541
|
+
let snapshot = null;
|
|
26542
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
26543
|
+
return {
|
|
26544
|
+
subscribe(listener) {
|
|
26545
|
+
listeners.add(listener);
|
|
26546
|
+
return () => {
|
|
26547
|
+
listeners.delete(listener);
|
|
26548
|
+
};
|
|
26549
|
+
},
|
|
26550
|
+
getSnapshot: () => snapshot,
|
|
26551
|
+
publish(next) {
|
|
26552
|
+
if (sameBand(snapshot, next)) return;
|
|
26553
|
+
snapshot = next;
|
|
26554
|
+
for (const listener of listeners) listener();
|
|
26555
|
+
}
|
|
26556
|
+
};
|
|
26557
|
+
}
|
|
26558
|
+
|
|
26285
26559
|
// src/components/history/selection-helpers.ts
|
|
26286
26560
|
function normalizeSelection(a, b, inProgress) {
|
|
26287
26561
|
const topLeft = { row: Math.min(a.row, b.row), col: Math.min(a.col, b.col) };
|
|
@@ -26314,7 +26588,7 @@ function selectionToSlices(opts) {
|
|
|
26314
26588
|
return result;
|
|
26315
26589
|
}
|
|
26316
26590
|
function assembleSelectionText(opts) {
|
|
26317
|
-
const { slices, entriesById, toolGroupsByHeadId } = opts;
|
|
26591
|
+
const { slices, entriesById, toolGroupsByHeadId, termWidth } = opts;
|
|
26318
26592
|
if (slices.length === 0) return "";
|
|
26319
26593
|
const byEntry = /* @__PURE__ */ new Map();
|
|
26320
26594
|
for (const slice of slices) {
|
|
@@ -26337,6 +26611,36 @@ function assembleSelectionText(opts) {
|
|
|
26337
26611
|
segments.push(fullText);
|
|
26338
26612
|
continue;
|
|
26339
26613
|
}
|
|
26614
|
+
const single = entries[0];
|
|
26615
|
+
const map = termWidth !== void 0 && hasWrapMap(single) && !(single.kind === "user" && (single.pasteContent || single.queued)) ? buildBodyRowMap(single.kind, single.text, termWidth) : null;
|
|
26616
|
+
if (map !== null && map.text.length > 0) {
|
|
26617
|
+
const lines = map.text.split("\n");
|
|
26618
|
+
for (const slice of entrySlices) {
|
|
26619
|
+
const a = resolveRowCol(map, slice.startRow, slice.startCol, false);
|
|
26620
|
+
const b = resolveRowCol(map, slice.endRow, slice.endCol, true);
|
|
26621
|
+
if (b.line < a.line) continue;
|
|
26622
|
+
const collected = [];
|
|
26623
|
+
for (let ln = a.line; ln <= b.line && ln < lines.length; ln++) {
|
|
26624
|
+
const line = lines[ln] ?? "";
|
|
26625
|
+
if (ln === a.line && ln === b.line) {
|
|
26626
|
+
const start = Math.max(0, Math.min(line.length, a.offset));
|
|
26627
|
+
const end = Math.max(start, Math.min(line.length, b.offset));
|
|
26628
|
+
if (end > start) collected.push(line.slice(start, end));
|
|
26629
|
+
} else if (ln === a.line) {
|
|
26630
|
+
const start = Math.max(0, Math.min(line.length, a.offset));
|
|
26631
|
+
if (start < line.length) collected.push(line.slice(start));
|
|
26632
|
+
} else if (ln === b.line) {
|
|
26633
|
+
const end = Math.max(0, Math.min(line.length, b.offset));
|
|
26634
|
+
if (end > 0) collected.push(line.slice(0, end));
|
|
26635
|
+
} else {
|
|
26636
|
+
collected.push(line);
|
|
26637
|
+
}
|
|
26638
|
+
}
|
|
26639
|
+
const seg = collected.join("\n");
|
|
26640
|
+
if (seg.length > 0) segments.push(seg);
|
|
26641
|
+
}
|
|
26642
|
+
continue;
|
|
26643
|
+
}
|
|
26340
26644
|
for (const slice of entrySlices) {
|
|
26341
26645
|
const rows = fullText.split("\n");
|
|
26342
26646
|
const collected = [];
|
|
@@ -26379,6 +26683,7 @@ function useHistoryController(opts) {
|
|
|
26379
26683
|
selectionRef,
|
|
26380
26684
|
entriesByIdRef,
|
|
26381
26685
|
toolStreamRef,
|
|
26686
|
+
selectionBandStore,
|
|
26382
26687
|
setAnchor,
|
|
26383
26688
|
setMountBump,
|
|
26384
26689
|
controllerRef
|
|
@@ -26389,15 +26694,36 @@ function useHistoryController(opts) {
|
|
|
26389
26694
|
effectiveAnchorRef.current = effectiveAnchor;
|
|
26390
26695
|
const groupIdsRef = useRef9(groupIds);
|
|
26391
26696
|
groupIdsRef.current = groupIds;
|
|
26392
|
-
const
|
|
26393
|
-
const
|
|
26394
|
-
|
|
26395
|
-
|
|
26396
|
-
|
|
26397
|
-
|
|
26398
|
-
|
|
26399
|
-
|
|
26400
|
-
|
|
26697
|
+
const publishBand = useCallback5(() => {
|
|
26698
|
+
const cur = selectionRef.current;
|
|
26699
|
+
selectionBandStore?.publish(
|
|
26700
|
+
cur.anchor !== null && cur.head !== null && cur.inProgress ? bandFromSelection(cur.anchor, cur.head) : null
|
|
26701
|
+
);
|
|
26702
|
+
}, [selectionBandStore, selectionRef]);
|
|
26703
|
+
const gutterWidthForEntry = (entryId) => {
|
|
26704
|
+
if (entryId === void 0) return 0;
|
|
26705
|
+
const entry = entriesByIdRef.current.get(entryId);
|
|
26706
|
+
if (!entry) return 0;
|
|
26707
|
+
return entry.kind === "assistant" || entry.kind === "thinking" || entry.kind === "user" ? MESSAGE_PANEL_CHROME_WIDTH : 0;
|
|
26708
|
+
};
|
|
26709
|
+
const toBodyLocalCol = (row, col) => {
|
|
26710
|
+
const hit = selectionHitAt(row, mountedGroupSpansRef.current);
|
|
26711
|
+
const gutter = gutterWidthForEntry(hit?.entryId);
|
|
26712
|
+
return gutter === 0 ? col : Math.max(0, col - gutter);
|
|
26713
|
+
};
|
|
26714
|
+
const applyAnchor = useCallback5(
|
|
26715
|
+
(next) => {
|
|
26716
|
+
const ids = groupIdsRef.current;
|
|
26717
|
+
const nextId = next ? ids[next.index] : void 0;
|
|
26718
|
+
const normalized = next && nextId !== void 0 ? { index: next.index, clip: Math.max(0, next.clip) } : null;
|
|
26719
|
+
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
26720
|
+
publishBand();
|
|
26721
|
+
effectiveAnchorRef.current = normalized;
|
|
26722
|
+
setAnchor(normalized && nextId !== void 0 ? { id: nextId, clip: normalized.clip } : null);
|
|
26723
|
+
setMountBump(0);
|
|
26724
|
+
},
|
|
26725
|
+
[selectionRef, publishBand, setAnchor, setMountBump]
|
|
26726
|
+
);
|
|
26401
26727
|
const controller = useMemo9(
|
|
26402
26728
|
() => ({
|
|
26403
26729
|
scrollBy: (deltaUp) => {
|
|
@@ -26443,18 +26769,22 @@ function useHistoryController(opts) {
|
|
|
26443
26769
|
beginSelection: (row, col) => {
|
|
26444
26770
|
if (isOutOfBand(col, termWidth)) {
|
|
26445
26771
|
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
26772
|
+
publishBand();
|
|
26446
26773
|
return;
|
|
26447
26774
|
}
|
|
26448
26775
|
const cardHit = selectionHitAt(row, mountedGroupSpansRef.current);
|
|
26449
26776
|
if (cardHit === null) {
|
|
26450
26777
|
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
26778
|
+
publishBand();
|
|
26451
26779
|
return;
|
|
26452
26780
|
}
|
|
26781
|
+
const bodyCol = toBodyLocalCol(row, col);
|
|
26453
26782
|
selectionRef.current = {
|
|
26454
|
-
anchor: { row, col },
|
|
26455
|
-
head: { row, col },
|
|
26783
|
+
anchor: { row, col: bodyCol },
|
|
26784
|
+
head: { row, col: bodyCol },
|
|
26456
26785
|
inProgress: true
|
|
26457
26786
|
};
|
|
26787
|
+
publishBand();
|
|
26458
26788
|
},
|
|
26459
26789
|
extendSelection: (row, col) => {
|
|
26460
26790
|
const cur = selectionRef.current;
|
|
@@ -26462,25 +26792,31 @@ function useHistoryController(opts) {
|
|
|
26462
26792
|
if (cur.inProgress === false) return;
|
|
26463
26793
|
if (isOutOfBand(col, termWidth) || row < 0 || row >= vp) {
|
|
26464
26794
|
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
26795
|
+
publishBand();
|
|
26465
26796
|
return;
|
|
26466
26797
|
}
|
|
26467
|
-
selectionRef.current = { ...cur, head: { row, col } };
|
|
26798
|
+
selectionRef.current = { ...cur, head: { row, col: toBodyLocalCol(row, col) } };
|
|
26799
|
+
publishBand();
|
|
26468
26800
|
},
|
|
26469
26801
|
endSelection: () => {
|
|
26470
26802
|
const cur = selectionRef.current;
|
|
26471
26803
|
if (cur.anchor === null) return;
|
|
26472
26804
|
selectionRef.current = { ...cur, inProgress: false };
|
|
26805
|
+
publishBand();
|
|
26473
26806
|
},
|
|
26807
|
+
hasSelection: () => selectionRef.current.anchor !== null,
|
|
26474
26808
|
clearSelection: () => {
|
|
26475
26809
|
const cur = selectionRef.current;
|
|
26476
26810
|
if (cur.anchor === null && cur.head === null) return;
|
|
26477
26811
|
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
26812
|
+
publishBand();
|
|
26478
26813
|
},
|
|
26479
26814
|
commitSelection: async () => {
|
|
26480
26815
|
const cur = selectionRef.current;
|
|
26481
26816
|
if (cur.anchor === null || cur.head === null) return false;
|
|
26482
26817
|
if (cur.anchor.row === cur.head.row && cur.anchor.col === cur.head.col) {
|
|
26483
26818
|
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
26819
|
+
publishBand();
|
|
26484
26820
|
return false;
|
|
26485
26821
|
}
|
|
26486
26822
|
const rect = normalizeSelection(cur.anchor, cur.head, cur.inProgress);
|
|
@@ -26498,9 +26834,13 @@ function useHistoryController(opts) {
|
|
|
26498
26834
|
const text = assembleSelectionText({
|
|
26499
26835
|
slices,
|
|
26500
26836
|
entriesById: entriesByIdRef.current,
|
|
26837
|
+
// Wrap-aware row→line translation (v1.1 M4): termWidth is the same
|
|
26838
|
+
// render width the card geometry was built with.
|
|
26839
|
+
termWidth,
|
|
26501
26840
|
...toolGroupsByHeadId.size > 0 ? { toolGroupsByHeadId } : {}
|
|
26502
26841
|
});
|
|
26503
26842
|
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
26843
|
+
publishBand();
|
|
26504
26844
|
if (text.length === 0) return false;
|
|
26505
26845
|
try {
|
|
26506
26846
|
return await writeClipboardText(text);
|
|
@@ -26509,7 +26849,18 @@ function useHistoryController(opts) {
|
|
|
26509
26849
|
}
|
|
26510
26850
|
}
|
|
26511
26851
|
}),
|
|
26512
|
-
[
|
|
26852
|
+
[
|
|
26853
|
+
applyAnchor,
|
|
26854
|
+
publishBand,
|
|
26855
|
+
termWidth,
|
|
26856
|
+
vp,
|
|
26857
|
+
copyHitsRef,
|
|
26858
|
+
liveToolCopyHitRef,
|
|
26859
|
+
mountedGroupSpansRef,
|
|
26860
|
+
selectionRef,
|
|
26861
|
+
entriesByIdRef,
|
|
26862
|
+
toolStreamRef
|
|
26863
|
+
]
|
|
26513
26864
|
);
|
|
26514
26865
|
useEffect24(() => {
|
|
26515
26866
|
if (!controllerRef) return void 0;
|
|
@@ -26528,14 +26879,18 @@ function useHistoryController(opts) {
|
|
|
26528
26879
|
}
|
|
26529
26880
|
|
|
26530
26881
|
// src/components/history/scrollbar-rail.tsx
|
|
26882
|
+
import { useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
26531
26883
|
import { jsx as jsx96, jsxs as jsxs93 } from "react/jsx-runtime";
|
|
26884
|
+
var NO_BAND = createSelectionBandStore();
|
|
26532
26885
|
function Scrollbar({
|
|
26533
26886
|
rows,
|
|
26534
26887
|
offset,
|
|
26535
26888
|
total,
|
|
26536
26889
|
copyHits,
|
|
26537
|
-
copiedEntryId
|
|
26890
|
+
copiedEntryId,
|
|
26891
|
+
selectionBandStore = NO_BAND
|
|
26538
26892
|
}) {
|
|
26893
|
+
const band = useSyncExternalStore2(selectionBandStore.subscribe, selectionBandStore.getSnapshot);
|
|
26539
26894
|
const { top: thumbTop, size: thumbSize, scrollable } = scrollbarThumb(rows, offset, total);
|
|
26540
26895
|
const cells = [];
|
|
26541
26896
|
for (let i = 0; i < rows; i++) {
|
|
@@ -26545,6 +26900,8 @@ function Scrollbar({
|
|
|
26545
26900
|
for (const hit of copyHits) copyByRow.set(hit.startRow, hit);
|
|
26546
26901
|
return /* @__PURE__ */ jsx96(Box, { flexDirection: "column", flexShrink: 0, children: cells.map((cell, row) => {
|
|
26547
26902
|
const copyHit = copyByRow.get(row);
|
|
26903
|
+
const inBand = band !== null && row >= band.topRow && row <= band.bottomRow && row < rows;
|
|
26904
|
+
const isHead = band !== null && row === band.headRow && row < rows;
|
|
26548
26905
|
return /* @__PURE__ */ jsxs93(Box, { flexDirection: "row", children: [
|
|
26549
26906
|
/* @__PURE__ */ jsx96(
|
|
26550
26907
|
Text,
|
|
@@ -26553,7 +26910,7 @@ function Scrollbar({
|
|
|
26553
26910
|
children: copyHit ? COPY_ICON : " "
|
|
26554
26911
|
}
|
|
26555
26912
|
),
|
|
26556
|
-
/* @__PURE__ */ jsx96(Text, { children: " " }),
|
|
26913
|
+
/* @__PURE__ */ jsx96(Text, { ...inBand ? { color: theme.accent } : {}, children: isHead ? "\u2588" : inBand ? "\u258C" : " " }),
|
|
26557
26914
|
/* @__PURE__ */ jsx96(
|
|
26558
26915
|
Text,
|
|
26559
26916
|
{
|
|
@@ -26615,6 +26972,11 @@ var ScrollableHistory = memo7(function ScrollableHistory2({
|
|
|
26615
26972
|
const heightCacheRef = useRef10(null);
|
|
26616
26973
|
if (heightCacheRef.current === null) heightCacheRef.current = new EntryHeightCache();
|
|
26617
26974
|
const heightCache = heightCacheRef.current;
|
|
26975
|
+
const selectionBandStoreRef = useRef10(null);
|
|
26976
|
+
if (selectionBandStoreRef.current === null) {
|
|
26977
|
+
selectionBandStoreRef.current = createSelectionBandStore();
|
|
26978
|
+
}
|
|
26979
|
+
const selectionBandStore = selectionBandStoreRef.current;
|
|
26618
26980
|
const entryNodeRefs = useRef10(/* @__PURE__ */ new Map());
|
|
26619
26981
|
const measuredGroupIdsRef = useRef10(/* @__PURE__ */ new Set());
|
|
26620
26982
|
const copyHitsRef = useRef10([]);
|
|
@@ -26739,6 +27101,7 @@ var ScrollableHistory = memo7(function ScrollableHistory2({
|
|
|
26739
27101
|
selectionRef,
|
|
26740
27102
|
entriesByIdRef,
|
|
26741
27103
|
toolStreamRef,
|
|
27104
|
+
selectionBandStore,
|
|
26742
27105
|
setAnchor,
|
|
26743
27106
|
setMountBump,
|
|
26744
27107
|
controllerRef
|
|
@@ -26947,7 +27310,8 @@ var ScrollableHistory = memo7(function ScrollableHistory2({
|
|
|
26947
27310
|
offset: offsetFromBottom,
|
|
26948
27311
|
total: totalRows,
|
|
26949
27312
|
copyHits: copyRailHits,
|
|
26950
|
-
copiedEntryId
|
|
27313
|
+
copiedEntryId,
|
|
27314
|
+
selectionBandStore
|
|
26951
27315
|
}
|
|
26952
27316
|
)
|
|
26953
27317
|
] });
|
|
@@ -27006,6 +27370,75 @@ function useSidebarConnections(projectRoot, enabled = true) {
|
|
|
27006
27370
|
}, [projectRoot, enabled]);
|
|
27007
27371
|
return connections;
|
|
27008
27372
|
}
|
|
27373
|
+
function useSidebarWrongProxy(url, enabled = true) {
|
|
27374
|
+
const [data, setData] = useState24(null);
|
|
27375
|
+
useEffect26(() => {
|
|
27376
|
+
if (!enabled || !url) {
|
|
27377
|
+
setData(null);
|
|
27378
|
+
return;
|
|
27379
|
+
}
|
|
27380
|
+
let cancelled = false;
|
|
27381
|
+
const probe = async () => {
|
|
27382
|
+
const trimmed = url.trim().replace(/\/+$/, "");
|
|
27383
|
+
const healthUrl = `${trimmed}/api/health`;
|
|
27384
|
+
const startedAt = Date.now();
|
|
27385
|
+
try {
|
|
27386
|
+
const res = await fetch(healthUrl, {
|
|
27387
|
+
method: "GET",
|
|
27388
|
+
// 2s budget — matches the runtime probe in proxy-probe.ts so a
|
|
27389
|
+
// hung localhost:3444 cannot stall the render loop. The TUI
|
|
27390
|
+
// never sees AbortError unless the caller tears us down.
|
|
27391
|
+
signal: AbortSignal.timeout(2e3),
|
|
27392
|
+
headers: { accept: "application/json" }
|
|
27393
|
+
});
|
|
27394
|
+
if (cancelled) return;
|
|
27395
|
+
const ok = res.ok && res.status >= 200 && res.status < 300;
|
|
27396
|
+
let socketPath;
|
|
27397
|
+
let version;
|
|
27398
|
+
if (ok) {
|
|
27399
|
+
try {
|
|
27400
|
+
const body = await res.json();
|
|
27401
|
+
if (body != null && typeof body === "object") {
|
|
27402
|
+
const { socket_path, version: reported } = body;
|
|
27403
|
+
if (typeof socket_path === "string" && socket_path.length > 0) {
|
|
27404
|
+
socketPath = socket_path;
|
|
27405
|
+
}
|
|
27406
|
+
if (typeof reported === "string" && reported.length > 0) {
|
|
27407
|
+
version = reported;
|
|
27408
|
+
}
|
|
27409
|
+
}
|
|
27410
|
+
} catch {
|
|
27411
|
+
}
|
|
27412
|
+
}
|
|
27413
|
+
if (cancelled) return;
|
|
27414
|
+
setData({
|
|
27415
|
+
url: trimmed,
|
|
27416
|
+
status: ok ? "ok" : "warn",
|
|
27417
|
+
latencyMs: Date.now() - startedAt,
|
|
27418
|
+
detail: ok ? void 0 : `HTTP ${res.status}`,
|
|
27419
|
+
socketPath,
|
|
27420
|
+
version
|
|
27421
|
+
});
|
|
27422
|
+
} catch (error) {
|
|
27423
|
+
if (cancelled) return;
|
|
27424
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
27425
|
+
setData({
|
|
27426
|
+
url: trimmed,
|
|
27427
|
+
status: "down",
|
|
27428
|
+
latencyMs: Date.now() - startedAt,
|
|
27429
|
+
detail: message || "unreachable"
|
|
27430
|
+
});
|
|
27431
|
+
}
|
|
27432
|
+
};
|
|
27433
|
+
void probe();
|
|
27434
|
+
const id = setInterval(() => void probe(), 8e3);
|
|
27435
|
+
return () => {
|
|
27436
|
+
cancelled = true;
|
|
27437
|
+
clearInterval(id);
|
|
27438
|
+
};
|
|
27439
|
+
}, [url, enabled]);
|
|
27440
|
+
return data;
|
|
27441
|
+
}
|
|
27009
27442
|
function useSidebarKanban(projectRoot, enabled = true) {
|
|
27010
27443
|
const [data, setData] = useState24({ columns: [], totalActive: 0, activeCardTitles: [] });
|
|
27011
27444
|
useEffect26(() => {
|
|
@@ -27057,11 +27490,7 @@ function useSidebarKanban(projectRoot, enabled = true) {
|
|
|
27057
27490
|
import { jsx as jsx98, jsxs as jsxs95 } from "react/jsx-runtime";
|
|
27058
27491
|
var INPUT_PROMPT = DEFAULT_INPUT_PROMPT;
|
|
27059
27492
|
function AppView({ host, runtime }) {
|
|
27060
|
-
const {
|
|
27061
|
-
agent,
|
|
27062
|
-
appVersion,
|
|
27063
|
-
setSuggestions
|
|
27064
|
-
} = host;
|
|
27493
|
+
const { agent, appVersion, setSuggestions } = host;
|
|
27065
27494
|
const {
|
|
27066
27495
|
state,
|
|
27067
27496
|
activity,
|
|
@@ -27096,6 +27525,12 @@ function AppView({ host, runtime }) {
|
|
|
27096
27525
|
sidebarSlotVisible("connections")
|
|
27097
27526
|
);
|
|
27098
27527
|
const sidebarKanbanData = useSidebarKanban(agent.ctx.projectRoot, sidebarSlotVisible("kanban"));
|
|
27528
|
+
const wrongProxyEnabled = state.settingsPicker.open ? state.settingsPicker.wrongProxyEnabled === true : liveSettings?.wrongProxyEnabled === true;
|
|
27529
|
+
const wrongProxyUrl = state.settingsPicker.open ? state.settingsPicker.wrongProxyUrl : liveSettings?.wrongProxyUrl;
|
|
27530
|
+
const sidebarWrongProxyData = useSidebarWrongProxy(
|
|
27531
|
+
wrongProxyUrl,
|
|
27532
|
+
wrongProxyEnabled && sidebarWidth > 0
|
|
27533
|
+
);
|
|
27099
27534
|
const sidebarPlanData = usePlanPanelData(
|
|
27100
27535
|
agent.ctx.projectRoot,
|
|
27101
27536
|
agent.ctx.session?.id ?? null,
|
|
@@ -27185,7 +27620,9 @@ function AppView({ host, runtime }) {
|
|
|
27185
27620
|
sidebarProcessData,
|
|
27186
27621
|
sidebarConnectionsData,
|
|
27187
27622
|
sidebarKanbanData,
|
|
27188
|
-
sidebarPlanData
|
|
27623
|
+
sidebarPlanData,
|
|
27624
|
+
sidebarWrongProxyEnabled: wrongProxyEnabled,
|
|
27625
|
+
sidebarWrongProxyData
|
|
27189
27626
|
}
|
|
27190
27627
|
)
|
|
27191
27628
|
] })
|
|
@@ -27774,7 +28211,12 @@ function routeSettingsOverlayKey(host, input, key, isEnter) {
|
|
|
27774
28211
|
showSageMemoryInject: config.showSageMemoryInject ?? false,
|
|
27775
28212
|
sageMemoryInjectThreshold: config.sageMemoryInjectThreshold ?? 0.85,
|
|
27776
28213
|
nextStepsTool: config.nextStepsTool ?? false,
|
|
27777
|
-
readSymbols: config.readSymbols ?? false
|
|
28214
|
+
readSymbols: config.readSymbols ?? false,
|
|
28215
|
+
// WrongProxy / WrongTrace: hydrate from the persisted Config (CLI
|
|
28216
|
+
// adapter owns the read/write — see LiveSettingsInput + the
|
|
28217
|
+
// tui-settings-adapter.ts branch tree).
|
|
28218
|
+
wrongProxyEnabled: config.wrongProxyEnabled ?? false,
|
|
28219
|
+
wrongProxyUrl: config.wrongProxyUrl ?? "http://localhost:3444"
|
|
27778
28220
|
});
|
|
27779
28221
|
return true;
|
|
27780
28222
|
}
|
|
@@ -28369,7 +28811,7 @@ function createAppKeyHandler(options) {
|
|
|
28369
28811
|
return;
|
|
28370
28812
|
}
|
|
28371
28813
|
if (!overlayOpen) {
|
|
28372
|
-
if (
|
|
28814
|
+
if (key.mouse?.kind === "press" && key.mouse.button === "right") {
|
|
28373
28815
|
const region = hitRegion(
|
|
28374
28816
|
{ termRows, termCols: historyWidth, viewportRows: state.viewportRows },
|
|
28375
28817
|
key.mouse.x,
|
|
@@ -28409,7 +28851,7 @@ function createAppKeyHandler(options) {
|
|
|
28409
28851
|
return;
|
|
28410
28852
|
}
|
|
28411
28853
|
}
|
|
28412
|
-
if ((key.mouse?.kind === "press" ||
|
|
28854
|
+
if ((key.mouse?.kind === "press" || key.mouse?.kind === "move") && key.mouse.button === "left") {
|
|
28413
28855
|
const region = hitRegion(
|
|
28414
28856
|
{ termRows, termCols: historyWidth, viewportRows: state.viewportRows },
|
|
28415
28857
|
key.mouse.x,
|
|
@@ -28423,7 +28865,7 @@ function createAppKeyHandler(options) {
|
|
|
28423
28865
|
}).catch(() => null);
|
|
28424
28866
|
return;
|
|
28425
28867
|
}
|
|
28426
|
-
if (
|
|
28868
|
+
if (region?.kind === "history" && key.mouse.x <= historyWidth - SCROLLBAR_HIT_WIDTH) {
|
|
28427
28869
|
if (key.mouse.kind === "press") {
|
|
28428
28870
|
historyScrollRef.current?.beginSelection(region.row, key.mouse.x - 1);
|
|
28429
28871
|
return;
|
|
@@ -28439,8 +28881,15 @@ function createAppKeyHandler(options) {
|
|
|
28439
28881
|
return;
|
|
28440
28882
|
}
|
|
28441
28883
|
}
|
|
28442
|
-
if (
|
|
28443
|
-
historyScrollRef.current?.
|
|
28884
|
+
if (key.mouse?.kind === "release" && key.mouse.button === "left") {
|
|
28885
|
+
if (historyScrollRef.current?.hasSelection()) {
|
|
28886
|
+
detach(
|
|
28887
|
+
historyScrollRef.current?.commitSelection().then((copied) => {
|
|
28888
|
+
if (copied) onHistoryCopy?.(SELECTION_COPY_ID);
|
|
28889
|
+
}),
|
|
28890
|
+
"Copy"
|
|
28891
|
+
);
|
|
28892
|
+
}
|
|
28444
28893
|
}
|
|
28445
28894
|
if (mouseMode && key.mouse?.kind === "press" && key.mouse.button === "left" && statusBarWrapRef.current) {
|
|
28446
28895
|
const sbHeight = measureElement(statusBarWrapRef.current).height;
|
|
@@ -29215,6 +29664,19 @@ import {
|
|
|
29215
29664
|
} from "@wrongstack/core/execution";
|
|
29216
29665
|
|
|
29217
29666
|
// src/submit-controller.ts
|
|
29667
|
+
async function waitForIdleSettle(isIdle, deadlineMs, opts = {}) {
|
|
29668
|
+
const maxPollMs = opts.maxPollMs ?? 150;
|
|
29669
|
+
const start = Date.now();
|
|
29670
|
+
let pollMs = 20;
|
|
29671
|
+
while (!isIdle()) {
|
|
29672
|
+
const remaining = deadlineMs - (Date.now() - start);
|
|
29673
|
+
if (remaining <= 0) return false;
|
|
29674
|
+
const wait = Math.min(Math.max(pollMs, 1), maxPollMs, remaining);
|
|
29675
|
+
await new Promise((resolve) => setTimeout(resolve, wait));
|
|
29676
|
+
pollMs = Math.min(pollMs * 2, maxPollMs);
|
|
29677
|
+
}
|
|
29678
|
+
return true;
|
|
29679
|
+
}
|
|
29218
29680
|
var topicAdvisorByAgent = /* @__PURE__ */ new WeakMap();
|
|
29219
29681
|
function topicAdvisorFor(agent) {
|
|
29220
29682
|
let advisor = topicAdvisorByAgent.get(agent);
|
|
@@ -29468,10 +29930,10 @@ function createSubmitController(host) {
|
|
|
29468
29930
|
if (b) {
|
|
29469
29931
|
b.appendText(res.runText);
|
|
29470
29932
|
const blocks2 = await b.submit();
|
|
29471
|
-
|
|
29472
|
-
|
|
29473
|
-
|
|
29474
|
-
|
|
29933
|
+
await waitForIdleSettle(
|
|
29934
|
+
() => stateRef.current.status === "idle",
|
|
29935
|
+
1500
|
|
29936
|
+
);
|
|
29475
29937
|
try {
|
|
29476
29938
|
await runBlocks(blocks2);
|
|
29477
29939
|
} finally {
|
|
@@ -29708,10 +30170,10 @@ User message:
|
|
|
29708
30170
|
if (b) {
|
|
29709
30171
|
b.appendText(preamble);
|
|
29710
30172
|
const steerBlocks = await b.submit();
|
|
29711
|
-
|
|
29712
|
-
|
|
29713
|
-
|
|
29714
|
-
|
|
30173
|
+
await waitForIdleSettle(
|
|
30174
|
+
() => stateRef.current.status === "idle",
|
|
30175
|
+
1500
|
|
30176
|
+
);
|
|
29715
30177
|
try {
|
|
29716
30178
|
stampJournalMarker();
|
|
29717
30179
|
await runBlocks(steerBlocks);
|
|
@@ -30370,6 +30832,32 @@ function tryToolsSettingsPickerKeys(host, input, key, isEnter, debouncedEnter2)
|
|
|
30370
30832
|
}
|
|
30371
30833
|
return true;
|
|
30372
30834
|
}
|
|
30835
|
+
if (sp.wrongProxyUrlEditing) {
|
|
30836
|
+
if (key.escape) {
|
|
30837
|
+
dispatch({ type: "settingsWrongProxyUrlEditCancel" });
|
|
30838
|
+
return true;
|
|
30839
|
+
}
|
|
30840
|
+
if (isEnter) {
|
|
30841
|
+
if (debouncedEnter2(host)) return true;
|
|
30842
|
+
dispatch({ type: "settingsWrongProxyUrlEditCommit" });
|
|
30843
|
+
return true;
|
|
30844
|
+
}
|
|
30845
|
+
if (key.backspace) {
|
|
30846
|
+
dispatch({
|
|
30847
|
+
type: "settingsWrongProxyUrlEditChange",
|
|
30848
|
+
draft: sp.wrongProxyUrlDraft.slice(0, -1)
|
|
30849
|
+
});
|
|
30850
|
+
return true;
|
|
30851
|
+
}
|
|
30852
|
+
if (input && input.length === 1 && input.charCodeAt(0) >= 32 && input.charCodeAt(0) < 127) {
|
|
30853
|
+
dispatch({
|
|
30854
|
+
type: "settingsWrongProxyUrlEditChange",
|
|
30855
|
+
draft: sp.wrongProxyUrlDraft + input
|
|
30856
|
+
});
|
|
30857
|
+
return true;
|
|
30858
|
+
}
|
|
30859
|
+
return true;
|
|
30860
|
+
}
|
|
30373
30861
|
if (key.escape || key.ctrl && input === "s") {
|
|
30374
30862
|
dispatch({ type: "settingsClose" });
|
|
30375
30863
|
return true;
|
|
@@ -31139,6 +31627,8 @@ function useAppPickerKeys({
|
|
|
31139
31627
|
}
|
|
31140
31628
|
if (sp.field === THINKING_WORD_FIELD) {
|
|
31141
31629
|
dispatch({ type: "settingsThinkingEditStart" });
|
|
31630
|
+
} else if (sp.field === WRONGPROXY_URL_FIELD) {
|
|
31631
|
+
dispatch({ type: "settingsWrongProxyUrlEditStart" });
|
|
31142
31632
|
} else {
|
|
31143
31633
|
dispatch({ type: "settingsValueChange", delta: 1 });
|
|
31144
31634
|
}
|
|
@@ -32204,7 +32694,19 @@ function createInitialState(options) {
|
|
|
32204
32694
|
showSageMemoryInject: true,
|
|
32205
32695
|
sageMemoryInjectThreshold: 0.85,
|
|
32206
32696
|
nextStepsTool: false,
|
|
32207
|
-
readSymbols: false
|
|
32697
|
+
readSymbols: false,
|
|
32698
|
+
// WrongProxy / WrongTrace. Defaults match the WebUI LocalPrefs
|
|
32699
|
+
// (master switch off; URL 'http://localhost:3444'). The runtime
|
|
32700
|
+
// probe in `packages/cli/src/wiring/proxy-probe.ts` reacts via
|
|
32701
|
+
// the WS `prefs.update` pipeline — these initial values only
|
|
32702
|
+
// cover the slice before the first `settingsOpen` action lands.
|
|
32703
|
+
wrongProxyEnabled: false,
|
|
32704
|
+
wrongProxyUrl: "http://localhost:3444",
|
|
32705
|
+
// WrongProxy URL text-edit state (field 60). The reducer quartet
|
|
32706
|
+
// at `reducers/settings-values.ts:733-801` seeds the draft from
|
|
32707
|
+
// `wrongProxyUrl` on Start and clears it on Commit/Cancel.
|
|
32708
|
+
wrongProxyUrlEditing: false,
|
|
32709
|
+
wrongProxyUrlDraft: ""
|
|
32208
32710
|
},
|
|
32209
32711
|
statuslinePicker: {
|
|
32210
32712
|
open: false,
|
|
@@ -34598,13 +35100,31 @@ function reduceSettingsPanel(state, action) {
|
|
|
34598
35100
|
sageMemoryInjectThreshold: action.sageMemoryInjectThreshold,
|
|
34599
35101
|
nextStepsTool: action.nextStepsTool,
|
|
34600
35102
|
readSymbols: action.readSymbols,
|
|
35103
|
+
// WrongProxy / WrongTrace: hydrate from the persisted boot-time
|
|
35104
|
+
// values pushed into the action by the TUI settings adapter.
|
|
35105
|
+
// The runtime probe (see `packages/cli/src/wiring/proxy-probe.ts`)
|
|
35106
|
+
// reacts to these via the WS `prefs.update` pipeline.
|
|
35107
|
+
wrongProxyEnabled: action.wrongProxyEnabled,
|
|
35108
|
+
wrongProxyUrl: action.wrongProxyUrl,
|
|
35109
|
+
// WrongProxy URL text-edit state (field 60): always defaults to
|
|
35110
|
+
// 'not editing' + empty draft on open. The Start action seeds
|
|
35111
|
+
// the draft from `wrongProxyUrl` at the reducer boundary.
|
|
35112
|
+
wrongProxyUrlEditing: false,
|
|
35113
|
+
wrongProxyUrlDraft: "",
|
|
34601
35114
|
hint: void 0
|
|
34602
35115
|
}
|
|
34603
35116
|
};
|
|
34604
35117
|
case "settingsClose":
|
|
34605
35118
|
return {
|
|
34606
35119
|
...state,
|
|
34607
|
-
|
|
35120
|
+
...closePanels(state),
|
|
35121
|
+
settingsPicker: {
|
|
35122
|
+
...state.settingsPicker,
|
|
35123
|
+
open: false,
|
|
35124
|
+
filter: "",
|
|
35125
|
+
wrongProxyUrlEditing: false,
|
|
35126
|
+
wrongProxyUrlDraft: ""
|
|
35127
|
+
}
|
|
34608
35128
|
};
|
|
34609
35129
|
case "settingsFieldMove": {
|
|
34610
35130
|
const next = (state.settingsPicker.field + action.delta + SETTINGS_FIELD_COUNT) % SETTINGS_FIELD_COUNT;
|
|
@@ -34616,6 +35136,8 @@ function reduceSettingsPanel(state, action) {
|
|
|
34616
35136
|
lastSettingsField: next,
|
|
34617
35137
|
thinkingWordEditing: false,
|
|
34618
35138
|
thinkingWordDraft: "",
|
|
35139
|
+
wrongProxyUrlEditing: false,
|
|
35140
|
+
wrongProxyUrlDraft: "",
|
|
34619
35141
|
hint: void 0
|
|
34620
35142
|
}
|
|
34621
35143
|
};
|
|
@@ -34628,6 +35150,8 @@ function reduceSettingsPanel(state, action) {
|
|
|
34628
35150
|
...state.settingsPicker,
|
|
34629
35151
|
field,
|
|
34630
35152
|
lastSettingsField: field,
|
|
35153
|
+
wrongProxyUrlEditing: false,
|
|
35154
|
+
wrongProxyUrlDraft: "",
|
|
34631
35155
|
hint: void 0
|
|
34632
35156
|
}
|
|
34633
35157
|
};
|
|
@@ -34645,6 +35169,7 @@ function reduceSettingsPanel(state, action) {
|
|
|
34645
35169
|
|
|
34646
35170
|
// src/reducers/settings-values.ts
|
|
34647
35171
|
import { expectDefined as expectDefined4 } from "@wrongstack/core/utils";
|
|
35172
|
+
import { MAX_WRONGPROXY_URL_LENGTH } from "@wrongstack/core/types";
|
|
34648
35173
|
var settingsValueActionTypes = [
|
|
34649
35174
|
"settingsValueChange",
|
|
34650
35175
|
"settingsValueSet",
|
|
@@ -34652,7 +35177,16 @@ var settingsValueActionTypes = [
|
|
|
34652
35177
|
"settingsThinkingEditStart",
|
|
34653
35178
|
"settingsThinkingEditChange",
|
|
34654
35179
|
"settingsThinkingEditCommit",
|
|
34655
|
-
"settingsThinkingEditCancel"
|
|
35180
|
+
"settingsThinkingEditCancel",
|
|
35181
|
+
// WrongProxy / WrongTrace URL (field 60) text-edit quartet.
|
|
35182
|
+
// Adding these here routes them into `reduceSettingsValues` via the
|
|
35183
|
+
// `SettingsValueAction` extract — without these, the actions hit the
|
|
35184
|
+
// generic `reduce*` path and the `action satisfies never` narrowing
|
|
35185
|
+
// marks the whole `Action` union as unassignable to `never`.
|
|
35186
|
+
"settingsWrongProxyUrlEditStart",
|
|
35187
|
+
"settingsWrongProxyUrlEditChange",
|
|
35188
|
+
"settingsWrongProxyUrlEditCommit",
|
|
35189
|
+
"settingsWrongProxyUrlEditCancel"
|
|
34656
35190
|
];
|
|
34657
35191
|
var settingsValueActionTypeSet = new Set(settingsValueActionTypes);
|
|
34658
35192
|
function isSettingsValueAction(action) {
|
|
@@ -35087,6 +35621,11 @@ function reduceSettingsValues(state, action) {
|
|
|
35087
35621
|
...state,
|
|
35088
35622
|
settingsPicker: { ...sp, nextStepsTool: !sp.nextStepsTool, hint: void 0 }
|
|
35089
35623
|
};
|
|
35624
|
+
if (f === 59)
|
|
35625
|
+
return {
|
|
35626
|
+
...state,
|
|
35627
|
+
settingsPicker: { ...sp, wrongProxyEnabled: !sp.wrongProxyEnabled, hint: void 0 }
|
|
35628
|
+
};
|
|
35090
35629
|
if (f >= PANEL_POSITION_FIELD_START && f - PANEL_POSITION_FIELD_START < PANEL_IDS.length) {
|
|
35091
35630
|
const PANEL_POSITION_CYCLE = ["bottom", "sidebar"];
|
|
35092
35631
|
const panelId = PANEL_IDS[f - PANEL_POSITION_FIELD_START];
|
|
@@ -35185,6 +35724,76 @@ function reduceSettingsValues(state, action) {
|
|
|
35185
35724
|
hint: void 0
|
|
35186
35725
|
}
|
|
35187
35726
|
};
|
|
35727
|
+
// WrongProxy URL (field 60) free-text edit quartet. Mirrors the
|
|
35728
|
+
// `settingsThinkingEdit*` shape: Enter on the row opens the edit
|
|
35729
|
+
// (seeding the draft with the current URL), Change caps the draft
|
|
35730
|
+
// (URLs don't have a strict length cap, but we cap to a sane 2 KiB
|
|
35731
|
+
// to prevent pathological input), Commit validates the scheme and
|
|
35732
|
+
// applies the new value, Cancel discards. Empty draft on commit
|
|
35733
|
+
// keeps the current URL (same semantics as the thinking-word edit).
|
|
35734
|
+
case "settingsWrongProxyUrlEditStart":
|
|
35735
|
+
return {
|
|
35736
|
+
...state,
|
|
35737
|
+
settingsPicker: {
|
|
35738
|
+
...state.settingsPicker,
|
|
35739
|
+
wrongProxyUrlEditing: true,
|
|
35740
|
+
// Seed the draft with the current URL so the user edits from it.
|
|
35741
|
+
wrongProxyUrlDraft: state.settingsPicker.wrongProxyUrl,
|
|
35742
|
+
hint: void 0
|
|
35743
|
+
}
|
|
35744
|
+
};
|
|
35745
|
+
case "settingsWrongProxyUrlEditChange":
|
|
35746
|
+
return {
|
|
35747
|
+
...state,
|
|
35748
|
+
settingsPicker: {
|
|
35749
|
+
...state.settingsPicker,
|
|
35750
|
+
// Cap to a sane 2 KiB so a runaway paste can't bloat the slice.
|
|
35751
|
+
wrongProxyUrlDraft: action.draft.slice(0, MAX_WRONGPROXY_URL_LENGTH),
|
|
35752
|
+
hint: void 0
|
|
35753
|
+
}
|
|
35754
|
+
};
|
|
35755
|
+
case "settingsWrongProxyUrlEditCommit": {
|
|
35756
|
+
const sp = state.settingsPicker;
|
|
35757
|
+
const raw = sp.wrongProxyUrlDraft.trim();
|
|
35758
|
+
if (raw.length === 0) {
|
|
35759
|
+
return {
|
|
35760
|
+
...state,
|
|
35761
|
+
settingsPicker: {
|
|
35762
|
+
...sp,
|
|
35763
|
+
wrongProxyUrlEditing: false,
|
|
35764
|
+
wrongProxyUrlDraft: "",
|
|
35765
|
+
hint: void 0
|
|
35766
|
+
}
|
|
35767
|
+
};
|
|
35768
|
+
}
|
|
35769
|
+
let valid = false;
|
|
35770
|
+
try {
|
|
35771
|
+
const parsed = new URL(raw);
|
|
35772
|
+
valid = parsed.protocol === "http:" || parsed.protocol === "https:";
|
|
35773
|
+
} catch {
|
|
35774
|
+
valid = false;
|
|
35775
|
+
}
|
|
35776
|
+
return {
|
|
35777
|
+
...state,
|
|
35778
|
+
settingsPicker: {
|
|
35779
|
+
...sp,
|
|
35780
|
+
wrongProxyUrl: valid ? raw : sp.wrongProxyUrl,
|
|
35781
|
+
wrongProxyUrlEditing: false,
|
|
35782
|
+
wrongProxyUrlDraft: "",
|
|
35783
|
+
hint: valid ? void 0 : "Invalid URL \u2014 use http://host:port or https://host:port (no whitespace)."
|
|
35784
|
+
}
|
|
35785
|
+
};
|
|
35786
|
+
}
|
|
35787
|
+
case "settingsWrongProxyUrlEditCancel":
|
|
35788
|
+
return {
|
|
35789
|
+
...state,
|
|
35790
|
+
settingsPicker: {
|
|
35791
|
+
...state.settingsPicker,
|
|
35792
|
+
wrongProxyUrlEditing: false,
|
|
35793
|
+
wrongProxyUrlDraft: "",
|
|
35794
|
+
hint: void 0
|
|
35795
|
+
}
|
|
35796
|
+
};
|
|
35188
35797
|
default:
|
|
35189
35798
|
void action;
|
|
35190
35799
|
return state;
|
|
@@ -35196,6 +35805,7 @@ var SIDEBAR_MISSION_MAX_WRAP_LINES = 10;
|
|
|
35196
35805
|
function computeMaxSidebarScroll(state, viewportHeight = 20, effectiveSwarmOnSidebar) {
|
|
35197
35806
|
let contentHeight = 0;
|
|
35198
35807
|
contentHeight += 14;
|
|
35808
|
+
contentHeight += 11;
|
|
35199
35809
|
contentHeight += 5;
|
|
35200
35810
|
const swarmOnSidebar = effectiveSwarmOnSidebar ?? state.settingsPicker.showAgentSwarmPanel === "sidebar";
|
|
35201
35811
|
if (swarmOnSidebar) {
|
|
@@ -36230,6 +36840,10 @@ import {
|
|
|
36230
36840
|
useEffect as useEffect31,
|
|
36231
36841
|
useRef as useRef15
|
|
36232
36842
|
} from "react";
|
|
36843
|
+
var BETWEEN_ITERATION_YIELD_MS = 200;
|
|
36844
|
+
function yieldBetweenIterations(ms = BETWEEN_ITERATION_YIELD_MS) {
|
|
36845
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
36846
|
+
}
|
|
36233
36847
|
function useAutonomyDrivers({
|
|
36234
36848
|
getEternalEngine,
|
|
36235
36849
|
getParallelEngine,
|
|
@@ -36276,7 +36890,7 @@ function useAutonomyDrivers({
|
|
|
36276
36890
|
}
|
|
36277
36891
|
if (!mountedRef.current) break;
|
|
36278
36892
|
dispatch({ type: "status", status: "idle" });
|
|
36279
|
-
await
|
|
36893
|
+
await yieldBetweenIterations();
|
|
36280
36894
|
}
|
|
36281
36895
|
} finally {
|
|
36282
36896
|
eternalLoopRunningRef.current = false;
|
|
@@ -36319,7 +36933,7 @@ function useAutonomyDrivers({
|
|
|
36319
36933
|
}
|
|
36320
36934
|
if (!mountedRef.current) break;
|
|
36321
36935
|
dispatch({ type: "status", status: "idle" });
|
|
36322
|
-
await
|
|
36936
|
+
await yieldBetweenIterations();
|
|
36323
36937
|
}
|
|
36324
36938
|
} finally {
|
|
36325
36939
|
parallelLoopRunningRef.current = false;
|
|
@@ -40792,7 +41406,7 @@ function useMouseTracking(input) {
|
|
|
40792
41406
|
native: nativeMouse,
|
|
40793
41407
|
protocol
|
|
40794
41408
|
});
|
|
40795
|
-
const mouseTrackingSequence = mouseTrackingOn ?
|
|
41409
|
+
const mouseTrackingSequence = mouseTrackingOn ? MOUSE_DRAG_ON : MOUSE_OFF;
|
|
40796
41410
|
const mouseWrittenRef = useRef30(null);
|
|
40797
41411
|
useEffect49(() => {
|
|
40798
41412
|
if (mouseWrittenRef.current === mouseTrackingSequence) return;
|
|
@@ -41391,7 +42005,12 @@ function usePanelControllers({
|
|
|
41391
42005
|
showSageMemoryInject: s2.showSageMemoryInject ?? false,
|
|
41392
42006
|
sageMemoryInjectThreshold: s2.sageMemoryInjectThreshold ?? 0.85,
|
|
41393
42007
|
nextStepsTool: s2.nextStepsTool ?? false,
|
|
41394
|
-
readSymbols: s2.readSymbols ?? false
|
|
42008
|
+
readSymbols: s2.readSymbols ?? false,
|
|
42009
|
+
// WrongProxy / WrongTrace: hydrate from the picker state slice.
|
|
42010
|
+
// Same defaults as the WebUI LocalPrefs and the CLI adapter's
|
|
42011
|
+
// branch tree — see tui-settings-adapter.ts.
|
|
42012
|
+
wrongProxyEnabled: s2.wrongProxyEnabled ?? false,
|
|
42013
|
+
wrongProxyUrl: s2.wrongProxyUrl ?? "http://localhost:3444"
|
|
41395
42014
|
});
|
|
41396
42015
|
}, [getSettings]);
|
|
41397
42016
|
const refreshPluginPicker = React11.useCallback(() => {
|
|
@@ -42364,36 +42983,9 @@ function useQueueManager({
|
|
|
42364
42983
|
midRunSendPickerRef
|
|
42365
42984
|
}) {
|
|
42366
42985
|
const persistState = useRef34({ running: false, pending: null });
|
|
42367
|
-
|
|
42368
|
-
|
|
42369
|
-
|
|
42370
|
-
queueStore.read().then((items) => {
|
|
42371
|
-
if (cancelled || items.length === 0) return;
|
|
42372
|
-
for (const item of items) {
|
|
42373
|
-
dispatch({
|
|
42374
|
-
type: "enqueue",
|
|
42375
|
-
item: {
|
|
42376
|
-
displayText: item.displayText,
|
|
42377
|
-
blocks: item.blocks,
|
|
42378
|
-
...item.shouldRefine !== void 0 ? { shouldRefine: item.shouldRefine } : {},
|
|
42379
|
-
...item.journalRaw !== void 0 ? { journalRaw: item.journalRaw } : {}
|
|
42380
|
-
}
|
|
42381
|
-
});
|
|
42382
|
-
}
|
|
42383
|
-
dispatch({
|
|
42384
|
-
type: "addEntry",
|
|
42385
|
-
entry: {
|
|
42386
|
-
kind: "info",
|
|
42387
|
-
text: `Restored ${items.length} queued message${items.length === 1 ? "" : "s"} from a previous run.`
|
|
42388
|
-
}
|
|
42389
|
-
});
|
|
42390
|
-
}).catch(() => void 0);
|
|
42391
|
-
return () => {
|
|
42392
|
-
cancelled = true;
|
|
42393
|
-
};
|
|
42394
|
-
}, [queueStore]);
|
|
42395
|
-
useEffect53(() => {
|
|
42396
|
-
if (!queueStore) return;
|
|
42986
|
+
const hydrated = useRef34(!queueStore);
|
|
42987
|
+
const pendingBeforeHydration = useRef34(false);
|
|
42988
|
+
const writeQueue = (store) => {
|
|
42397
42989
|
const raw = stateRef.current.queue.map(
|
|
42398
42990
|
({
|
|
42399
42991
|
displayText,
|
|
@@ -42408,7 +43000,7 @@ function useQueueManager({
|
|
|
42408
43000
|
})
|
|
42409
43001
|
);
|
|
42410
43002
|
const persistence = persistState.current;
|
|
42411
|
-
persistence.pending = { store
|
|
43003
|
+
persistence.pending = { store, items: raw };
|
|
42412
43004
|
if (persistence.running) return;
|
|
42413
43005
|
persistence.running = true;
|
|
42414
43006
|
void (async () => {
|
|
@@ -42422,6 +43014,49 @@ function useQueueManager({
|
|
|
42422
43014
|
persistence.running = false;
|
|
42423
43015
|
}
|
|
42424
43016
|
})();
|
|
43017
|
+
};
|
|
43018
|
+
useEffect53(() => {
|
|
43019
|
+
if (!queueStore) return;
|
|
43020
|
+
let cancelled = false;
|
|
43021
|
+
queueStore.read().then((items) => {
|
|
43022
|
+
if (cancelled) return;
|
|
43023
|
+
hydrated.current = true;
|
|
43024
|
+
for (const item of items) {
|
|
43025
|
+
dispatch({
|
|
43026
|
+
type: "enqueue",
|
|
43027
|
+
item: {
|
|
43028
|
+
displayText: item.displayText,
|
|
43029
|
+
blocks: item.blocks,
|
|
43030
|
+
...item.shouldRefine !== void 0 ? { shouldRefine: item.shouldRefine } : {},
|
|
43031
|
+
...item.journalRaw !== void 0 ? { journalRaw: item.journalRaw } : {}
|
|
43032
|
+
}
|
|
43033
|
+
});
|
|
43034
|
+
}
|
|
43035
|
+
if (items.length > 0) {
|
|
43036
|
+
dispatch({
|
|
43037
|
+
type: "addEntry",
|
|
43038
|
+
entry: {
|
|
43039
|
+
kind: "info",
|
|
43040
|
+
text: `Restored ${items.length} queued message${items.length === 1 ? "" : "s"} from a previous run.`
|
|
43041
|
+
}
|
|
43042
|
+
});
|
|
43043
|
+
}
|
|
43044
|
+
if (pendingBeforeHydration.current && items.length === 0) {
|
|
43045
|
+
pendingBeforeHydration.current = false;
|
|
43046
|
+
writeQueue(queueStore);
|
|
43047
|
+
}
|
|
43048
|
+
}).catch(() => void 0);
|
|
43049
|
+
return () => {
|
|
43050
|
+
cancelled = true;
|
|
43051
|
+
};
|
|
43052
|
+
}, [queueStore]);
|
|
43053
|
+
useEffect53(() => {
|
|
43054
|
+
if (!queueStore) return;
|
|
43055
|
+
if (!hydrated.current) {
|
|
43056
|
+
pendingBeforeHydration.current = true;
|
|
43057
|
+
return;
|
|
43058
|
+
}
|
|
43059
|
+
writeQueue(queueStore);
|
|
42425
43060
|
}, [stateRef.current.queue, queueStore, stateRef]);
|
|
42426
43061
|
useEffect53(() => {
|
|
42427
43062
|
onQueueChange?.(stateRef.current.queue.map((q) => q.displayText));
|
|
@@ -42723,7 +43358,13 @@ function useSettingsAutoSave(state, saveSettings, dispatch) {
|
|
|
42723
43358
|
showSageMemoryInject: sp.showSageMemoryInject,
|
|
42724
43359
|
sageMemoryInjectThreshold: sp.sageMemoryInjectThreshold,
|
|
42725
43360
|
nextStepsTool: sp.nextStepsTool,
|
|
42726
|
-
readSymbols: sp.readSymbols
|
|
43361
|
+
readSymbols: sp.readSymbols,
|
|
43362
|
+
// WrongProxy / WrongTrace: persist the picker-state values to
|
|
43363
|
+
// the same Config keys the adapter exposes (see LiveSettingsInput
|
|
43364
|
+
// and the tui-settings-adapter.ts branch tree). Optional with
|
|
43365
|
+
// `??` fallback — older persisted configs may not have the keys.
|
|
43366
|
+
wrongProxyEnabled: sp.wrongProxyEnabled ?? false,
|
|
43367
|
+
wrongProxyUrl: sp.wrongProxyUrl ?? "http://localhost:3444"
|
|
42727
43368
|
})
|
|
42728
43369
|
).then((err) => {
|
|
42729
43370
|
if (err) dispatch({ type: "settingsHint", text: err });
|
|
@@ -42777,6 +43418,8 @@ function useSettingsAutoSave(state, saveSettings, dispatch) {
|
|
|
42777
43418
|
state.settingsPicker.sageMemoryInjectThreshold,
|
|
42778
43419
|
state.settingsPicker.nextStepsTool,
|
|
42779
43420
|
state.settingsPicker.readSymbols,
|
|
43421
|
+
state.settingsPicker.wrongProxyEnabled,
|
|
43422
|
+
state.settingsPicker.wrongProxyUrl,
|
|
42780
43423
|
saveSettings
|
|
42781
43424
|
]);
|
|
42782
43425
|
}
|
|
@@ -46044,7 +46687,7 @@ function App(props) {
|
|
|
46044
46687
|
|
|
46045
46688
|
// src/components/suggestions.ts
|
|
46046
46689
|
import {
|
|
46047
|
-
parseNextSteps as
|
|
46690
|
+
parseNextSteps as parseNextSteps3,
|
|
46048
46691
|
stripNextStepsBlock as stripNextStepsBlock2
|
|
46049
46692
|
} from "@wrongstack/tools/next-steps";
|
|
46050
46693
|
|
|
@@ -46913,7 +47556,7 @@ async function runTui(opts) {
|
|
|
46913
47556
|
export {
|
|
46914
47557
|
buildGoalPreamble2 as buildGoalPreamble,
|
|
46915
47558
|
parseInline,
|
|
46916
|
-
|
|
47559
|
+
parseNextSteps3 as parseNextSteps,
|
|
46917
47560
|
replaySessionMessages,
|
|
46918
47561
|
runTui
|
|
46919
47562
|
};
|