@wrongstack/tui 0.296.4 → 0.298.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 +12 -1
- package/dist/app-props.d.ts +11 -1
- package/dist/app-settings-type.d.ts +5 -1
- package/dist/app-state.d.ts +4 -0
- package/dist/components/auth-panel.d.ts +4 -0
- package/dist/components/confirm-prompt.d.ts +14 -0
- package/dist/components/history/entry.d.ts +7 -1
- package/dist/components/history/index.d.ts +1 -1
- package/dist/components/history/tool-group.d.ts +1 -1
- package/dist/components/history/types.d.ts +6 -0
- package/dist/components/scrollable-history.d.ts +201 -2
- package/dist/components/settings-picker-model.d.ts +17 -1
- package/dist/components/settings-picker.d.ts +5 -1
- package/dist/components/status-bar-types.d.ts +31 -5
- package/dist/components/status-bar.d.ts +1 -1
- package/dist/heap-watchdog.d.ts +6 -42
- package/dist/history-entry.d.ts +9 -0
- package/dist/hooks/use-statusbar-view-model.d.ts +1 -0
- package/dist/hooks/use-tui-slash-commands.d.ts +1 -1
- package/dist/index.js +853 -360
- package/dist/markdown.d.ts +2 -0
- package/dist/run-tui-options.d.ts +10 -1
- package/dist/settings-contracts.d.ts +4 -0
- package/dist/token-previews.d.ts +3 -2
- package/dist/tui-memory-counters.d.ts +38 -0
- package/package.json +10 -8
- package/dist/app-action-type.d.ts.map +0 -1
- package/dist/app-initial-state.d.ts.map +0 -1
- package/dist/app-key-handler.d.ts.map +0 -1
- package/dist/app-props.d.ts.map +0 -1
- package/dist/app-reducer.d.ts.map +0 -1
- package/dist/app-settings-type.d.ts.map +0 -1
- package/dist/app-state-core-types.d.ts.map +0 -1
- package/dist/app-state-fleet.d.ts.map +0 -1
- package/dist/app-state.d.ts.map +0 -1
- package/dist/app-status-region.d.ts.map +0 -1
- package/dist/app-ui-state.d.ts.map +0 -1
- package/dist/app-view-contract.d.ts.map +0 -1
- package/dist/app-view-state.d.ts.map +0 -1
- package/dist/app-view.d.ts.map +0 -1
- package/dist/app.d.ts.map +0 -1
- package/dist/auth-panel-model.d.ts.map +0 -1
- package/dist/brain-contracts.d.ts.map +0 -1
- package/dist/brain-panel-model.d.ts.map +0 -1
- package/dist/checkpoint-retention.d.ts.map +0 -1
- package/dist/clipboard.d.ts.map +0 -1
- package/dist/components/agents-monitor-constants.d.ts.map +0 -1
- package/dist/components/agents-monitor.d.ts.map +0 -1
- package/dist/components/animation-style.d.ts.map +0 -1
- package/dist/components/audit-panel.d.ts.map +0 -1
- package/dist/components/auth-panel-model.d.ts.map +0 -1
- package/dist/components/auth-panel.d.ts.map +0 -1
- package/dist/components/autonomy-picker.d.ts.map +0 -1
- package/dist/components/brain-decision-prompt.d.ts.map +0 -1
- package/dist/components/brain-panel-model.d.ts.map +0 -1
- package/dist/components/brain-panel.d.ts.map +0 -1
- package/dist/components/checkpoint-timeline.d.ts.map +0 -1
- package/dist/components/clear-confirm-panel.d.ts.map +0 -1
- package/dist/components/composer-status-chip.d.ts.map +0 -1
- package/dist/components/confirm-prompt.d.ts.map +0 -1
- package/dist/components/connections-panel.d.ts.map +0 -1
- package/dist/components/context-panel.d.ts.map +0 -1
- package/dist/components/continue-confirm-panel.d.ts.map +0 -1
- package/dist/components/coordinator-panel.d.ts.map +0 -1
- package/dist/components/cron-jobs.d.ts.map +0 -1
- package/dist/components/design-picker.d.ts.map +0 -1
- package/dist/components/enhance-panel.d.ts.map +0 -1
- package/dist/components/entry-error-boundary.d.ts.map +0 -1
- package/dist/components/esc-confirm-prompt.d.ts.map +0 -1
- package/dist/components/exit-confirm-panel.d.ts.map +0 -1
- package/dist/components/f-key-picker.d.ts.map +0 -1
- package/dist/components/file-picker.d.ts.map +0 -1
- package/dist/components/fleet-monitor.d.ts.map +0 -1
- package/dist/components/fleet-panel.d.ts.map +0 -1
- package/dist/components/goal-kanban-panel.d.ts.map +0 -1
- package/dist/components/goal-panel.d.ts.map +0 -1
- package/dist/components/help-overlay.d.ts.map +0 -1
- package/dist/components/help-panel.d.ts.map +0 -1
- package/dist/components/history/assistant.d.ts.map +0 -1
- package/dist/components/history/banner.d.ts.map +0 -1
- package/dist/components/history/basic-format.d.ts.map +0 -1
- package/dist/components/history/code-block-diff-helpers.d.ts.map +0 -1
- package/dist/components/history/code-block.d.ts.map +0 -1
- package/dist/components/history/copy-icon.d.ts.map +0 -1
- package/dist/components/history/entry.d.ts.map +0 -1
- package/dist/components/history/index.d.ts.map +0 -1
- package/dist/components/history/replay.d.ts.map +0 -1
- package/dist/components/history/sage-output-format.d.ts.map +0 -1
- package/dist/components/history/stream-box.d.ts.map +0 -1
- package/dist/components/history/tool-arg-format.d.ts.map +0 -1
- package/dist/components/history/tool-card.d.ts.map +0 -1
- package/dist/components/history/tool-group.d.ts.map +0 -1
- package/dist/components/history/tool-output-summary.d.ts.map +0 -1
- package/dist/components/history/tool-visual-command.d.ts.map +0 -1
- package/dist/components/history/tool-visual-domain.d.ts.map +0 -1
- package/dist/components/history/tool-visual-format.d.ts.map +0 -1
- package/dist/components/history/tool-visual-lsp.d.ts.map +0 -1
- package/dist/components/history/tool-visual-misc.d.ts.map +0 -1
- package/dist/components/history/tool-visual-mode-workdir.d.ts.map +0 -1
- package/dist/components/history/tool-visual-types.d.ts.map +0 -1
- package/dist/components/history/types.d.ts.map +0 -1
- package/dist/components/history/utils.d.ts.map +0 -1
- package/dist/components/history/visual-lines.d.ts.map +0 -1
- package/dist/components/history/visual-memory-logs.d.ts.map +0 -1
- package/dist/components/history.d.ts.map +0 -1
- package/dist/components/input.d.ts.map +0 -1
- package/dist/components/kanban-panel.d.ts.map +0 -1
- package/dist/components/key-hint-bar.d.ts.map +0 -1
- package/dist/components/live-activity-strip.d.ts.map +0 -1
- package/dist/components/mailbox-panel.d.ts.map +0 -1
- package/dist/components/mcp-picker.d.ts.map +0 -1
- package/dist/components/memory-context-widget.d.ts.map +0 -1
- package/dist/components/mode-picker.d.ts.map +0 -1
- package/dist/components/model-picker.d.ts.map +0 -1
- package/dist/components/monitor-shell.d.ts.map +0 -1
- package/dist/components/phase-monitor.d.ts.map +0 -1
- package/dist/components/phase-panel.d.ts.map +0 -1
- package/dist/components/plan-panel.d.ts.map +0 -1
- package/dist/components/plugin-picker.d.ts.map +0 -1
- package/dist/components/powerline-rail.d.ts.map +0 -1
- package/dist/components/process-list.d.ts.map +0 -1
- package/dist/components/project-picker.d.ts.map +0 -1
- package/dist/components/prompt-picker.d.ts.map +0 -1
- package/dist/components/provider-colors.d.ts.map +0 -1
- package/dist/components/queue-panel.d.ts.map +0 -1
- package/dist/components/refine-countdown-panel.d.ts.map +0 -1
- package/dist/components/refine-failure-panel.d.ts.map +0 -1
- package/dist/components/resume-picker.d.ts.map +0 -1
- package/dist/components/scrollable-history.d.ts.map +0 -1
- package/dist/components/sdd-board-overlay.d.ts.map +0 -1
- package/dist/components/send-mode-picker.d.ts.map +0 -1
- package/dist/components/sessions-panel.d.ts.map +0 -1
- package/dist/components/settings-picker-filter.d.ts.map +0 -1
- package/dist/components/settings-picker-jumps.d.ts.map +0 -1
- package/dist/components/settings-picker-model.d.ts.map +0 -1
- package/dist/components/settings-picker-row-list.d.ts.map +0 -1
- package/dist/components/settings-picker.d.ts.map +0 -1
- package/dist/components/shadow-panel.d.ts.map +0 -1
- package/dist/components/shell-command-warning.d.ts.map +0 -1
- package/dist/components/slash-confirm-panel.d.ts.map +0 -1
- package/dist/components/slash-menu.d.ts.map +0 -1
- package/dist/components/status-bar-chips.d.ts.map +0 -1
- package/dist/components/status-bar-format.d.ts.map +0 -1
- package/dist/components/status-bar-helpers.d.ts.map +0 -1
- package/dist/components/status-bar-types.d.ts.map +0 -1
- package/dist/components/status-bar.d.ts.map +0 -1
- package/dist/components/statusline-detail-panel.d.ts.map +0 -1
- package/dist/components/statusline-picker.d.ts.map +0 -1
- package/dist/components/suggestions.d.ts.map +0 -1
- package/dist/components/todos-monitor.d.ts.map +0 -1
- package/dist/components/tools-picker.d.ts.map +0 -1
- package/dist/components/worktree-monitor.d.ts.map +0 -1
- package/dist/components/worktree-panel.d.ts.map +0 -1
- package/dist/connections-health.d.ts.map +0 -1
- package/dist/connections-slash.d.ts.map +0 -1
- package/dist/context-fill.d.ts.map +0 -1
- package/dist/context-slash.d.ts.map +0 -1
- package/dist/cron-slash.d.ts.map +0 -1
- package/dist/esc-close-panels.d.ts.map +0 -1
- package/dist/exit-slash.d.ts.map +0 -1
- package/dist/f-key-panels.d.ts.map +0 -1
- package/dist/file-search.d.ts.map +0 -1
- package/dist/fn-keys.d.ts.map +0 -1
- package/dist/git-info.d.ts.map +0 -1
- package/dist/heap-watchdog.d.ts.map +0 -1
- package/dist/height-cache.d.ts.map +0 -1
- package/dist/highlight.d.ts.map +0 -1
- package/dist/history-archive.d.ts.map +0 -1
- package/dist/history-entry.d.ts.map +0 -1
- package/dist/history-retention.d.ts.map +0 -1
- package/dist/hit-test.d.ts.map +0 -1
- package/dist/hooks/fleet-chat-coalescer.d.ts.map +0 -1
- package/dist/hooks/subagent-history-format.d.ts.map +0 -1
- package/dist/hooks/use-app-picker-keys.d.ts.map +0 -1
- package/dist/hooks/use-app-runtime-refs.d.ts.map +0 -1
- package/dist/hooks/use-app-session-state.d.ts.map +0 -1
- package/dist/hooks/use-auth-panel.d.ts.map +0 -1
- package/dist/hooks/use-autonomous-coordinator.d.ts.map +0 -1
- package/dist/hooks/use-autonomy-drivers.d.ts.map +0 -1
- package/dist/hooks/use-brain-events.d.ts.map +0 -1
- package/dist/hooks/use-brain-panel.d.ts.map +0 -1
- package/dist/hooks/use-brain-risk-sync.d.ts.map +0 -1
- package/dist/hooks/use-chip-staleness-guard.d.ts.map +0 -1
- package/dist/hooks/use-client-telemetry.d.ts.map +0 -1
- package/dist/hooks/use-core-tui-commands.d.ts.map +0 -1
- package/dist/hooks/use-director-fleet-bridge.d.ts.map +0 -1
- package/dist/hooks/use-enhance-runtime-state.d.ts.map +0 -1
- package/dist/hooks/use-exit-command.d.ts.map +0 -1
- package/dist/hooks/use-file-search.d.ts.map +0 -1
- package/dist/hooks/use-fleet-generation-gate.d.ts.map +0 -1
- package/dist/hooks/use-git-session-status.d.ts.map +0 -1
- package/dist/hooks/use-help-panel.d.ts.map +0 -1
- package/dist/hooks/use-history-copy-notice.d.ts.map +0 -1
- package/dist/hooks/use-history-viewport-sync.d.ts.map +0 -1
- package/dist/hooks/use-initial-prompt.d.ts.map +0 -1
- package/dist/hooks/use-input-history-persistence.d.ts.map +0 -1
- package/dist/hooks/use-interrupt-ladder.d.ts.map +0 -1
- package/dist/hooks/use-kanban-board-focus.d.ts.map +0 -1
- package/dist/hooks/use-live-settings-state.d.ts.map +0 -1
- package/dist/hooks/use-live-todos.d.ts.map +0 -1
- package/dist/hooks/use-mailbox-view-model.d.ts.map +0 -1
- package/dist/hooks/use-mode-picker.d.ts.map +0 -1
- package/dist/hooks/use-model-pick.d.ts.map +0 -1
- package/dist/hooks/use-mouse-tracking.d.ts.map +0 -1
- package/dist/hooks/use-next-steps-auto-submit.d.ts.map +0 -1
- package/dist/hooks/use-panel-controllers.d.ts.map +0 -1
- package/dist/hooks/use-paste-handling.d.ts.map +0 -1
- package/dist/hooks/use-picker-keys-types.d.ts.map +0 -1
- package/dist/hooks/use-picker-keys.d.ts.map +0 -1
- package/dist/hooks/use-prompt-picker.d.ts.map +0 -1
- package/dist/hooks/use-provider-event-bridge.d.ts.map +0 -1
- package/dist/hooks/use-queue-manager.d.ts.map +0 -1
- package/dist/hooks/use-session-interrupt-controller.d.ts.map +0 -1
- package/dist/hooks/use-settings-auto-save.d.ts.map +0 -1
- package/dist/hooks/use-shadow-panel.d.ts.map +0 -1
- package/dist/hooks/use-slash-picker.d.ts.map +0 -1
- package/dist/hooks/use-stable-key-handler.d.ts.map +0 -1
- package/dist/hooks/use-statusbar-view-model.d.ts.map +0 -1
- package/dist/hooks/use-statusline-hidden-sync.d.ts.map +0 -1
- package/dist/hooks/use-statusline-state.d.ts.map +0 -1
- package/dist/hooks/use-stream-chip-expiration.d.ts.map +0 -1
- package/dist/hooks/use-subagent-events.d.ts.map +0 -1
- package/dist/hooks/use-terminal-render-lifecycle.d.ts.map +0 -1
- package/dist/hooks/use-todos-auto-clear.d.ts.map +0 -1
- package/dist/hooks/use-token-counter-refresh.d.ts.map +0 -1
- package/dist/hooks/use-tui-activity.d.ts.map +0 -1
- package/dist/hooks/use-tui-controllers.d.ts.map +0 -1
- package/dist/hooks/use-tui-environment-state.d.ts.map +0 -1
- package/dist/hooks/use-tui-event-bridge.d.ts.map +0 -1
- package/dist/hooks/use-tui-slash-commands.d.ts.map +0 -1
- package/dist/hooks/use-working-dir-chip.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -7
- package/dist/ink.d.ts.map +0 -1
- package/dist/input-editing.d.ts.map +0 -1
- package/dist/input-key-router.d.ts.map +0 -1
- package/dist/input-tokens.d.ts.map +0 -1
- package/dist/input-validation/action-helpers.d.ts.map +0 -1
- package/dist/input-validation/action-types.d.ts.map +0 -1
- package/dist/input-validation/allow-lists.d.ts.map +0 -1
- package/dist/input-validation/limits.d.ts.map +0 -1
- package/dist/input-validation/result.d.ts.map +0 -1
- package/dist/input-validation/state-entries.d.ts.map +0 -1
- package/dist/input-validation/terminal.d.ts.map +0 -1
- package/dist/input-validation.d.ts.map +0 -1
- package/dist/kanban-audit.d.ts.map +0 -1
- package/dist/kanban-slash.d.ts.map +0 -1
- package/dist/kill-slash.d.ts.map +0 -1
- package/dist/layout-engine.d.ts.map +0 -1
- package/dist/layout-store.d.ts.map +0 -1
- package/dist/mailbox-view-model-types.d.ts.map +0 -1
- package/dist/markdown-table.d.ts.map +0 -1
- package/dist/markdown.d.ts.map +0 -1
- package/dist/memory-context-monitor.d.ts.map +0 -1
- package/dist/memory-lifecycle-entry.d.ts.map +0 -1
- package/dist/memory-slash-format.d.ts.map +0 -1
- package/dist/memory-slash.d.ts.map +0 -1
- package/dist/mouse.d.ts.map +0 -1
- package/dist/on-panel-open.d.ts.map +0 -1
- package/dist/overlay-key-router.d.ts.map +0 -1
- package/dist/paste-accumulator.d.ts.map +0 -1
- package/dist/prompt-refinement-start.d.ts.map +0 -1
- package/dist/ps-slash.d.ts.map +0 -1
- package/dist/queue-slash.d.ts.map +0 -1
- package/dist/reducers/activity.d.ts.map +0 -1
- package/dist/reducers/composer.d.ts.map +0 -1
- package/dist/reducers/conversation.d.ts.map +0 -1
- package/dist/reducers/dialogs.d.ts.map +0 -1
- package/dist/reducers/fleet.d.ts.map +0 -1
- package/dist/reducers/helpers.d.ts.map +0 -1
- package/dist/reducers/panel-pickers.d.ts.map +0 -1
- package/dist/reducers/settings-panel.d.ts.map +0 -1
- package/dist/reducers/settings-values.d.ts.map +0 -1
- package/dist/reducers/workspace-panels.d.ts.map +0 -1
- package/dist/rehydrate-history.d.ts.map +0 -1
- package/dist/run-blocks-controller.d.ts.map +0 -1
- package/dist/run-tui-client-registration.d.ts.map +0 -1
- package/dist/run-tui-options.d.ts.map +0 -1
- package/dist/run-tui-title-controller.d.ts.map +0 -1
- package/dist/run-tui.d.ts.map +0 -1
- package/dist/running-tools.d.ts.map +0 -1
- package/dist/scroll-anchor.d.ts.map +0 -1
- package/dist/sdd-lifecycle-entry.d.ts.map +0 -1
- package/dist/settings-contracts.d.ts.map +0 -1
- package/dist/shared-types.d.ts.map +0 -1
- package/dist/slash-command-search.d.ts.map +0 -1
- package/dist/steering-preamble.d.ts.map +0 -1
- package/dist/submit-controller.d.ts.map +0 -1
- package/dist/submit-history.d.ts.map +0 -1
- package/dist/submit-prompt-refinement.d.ts.map +0 -1
- package/dist/terminal-modes.d.ts.map +0 -1
- package/dist/terminal-silence.d.ts.map +0 -1
- package/dist/terminal-title.d.ts.map +0 -1
- package/dist/terminal-width.d.ts.map +0 -1
- package/dist/theme.d.ts.map +0 -1
- package/dist/thinking-word.d.ts.map +0 -1
- package/dist/token-previews.d.ts.map +0 -1
- package/dist/tool-glyph.d.ts.map +0 -1
- package/dist/tui-host-capabilities.d.ts.map +0 -1
- package/dist/ui-contracts.d.ts.map +0 -1
- package/dist/ui-glyphs.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/app.tsx
|
|
2
|
-
import * as
|
|
2
|
+
import * as path7 from "node:path";
|
|
3
3
|
import {
|
|
4
4
|
applyRewindToConversation,
|
|
5
5
|
DefaultSessionRewinder
|
|
@@ -1175,7 +1175,6 @@ function hasTokenDisplay(tokens) {
|
|
|
1175
1175
|
return tokens.input > 0 || tokens.output > 0;
|
|
1176
1176
|
}
|
|
1177
1177
|
var RAIL_CAP = 1;
|
|
1178
|
-
var RAIL_PAD = 2;
|
|
1179
1178
|
function statusBarModelSpan(opts) {
|
|
1180
1179
|
const leading = [];
|
|
1181
1180
|
if (opts.yolo) leading.push(opts.monochrome ? "YOLO" : `${glyphs.warning} YOLO`);
|
|
@@ -1192,9 +1191,9 @@ function statusBarModelSpan(opts) {
|
|
|
1192
1191
|
const workingDir = truncateChip(opts.workingDir, 28);
|
|
1193
1192
|
leading.push(opts.monochrome ? workingDir : `${glyphs.workingDirectory} ${workingDir}`);
|
|
1194
1193
|
}
|
|
1195
|
-
const
|
|
1194
|
+
const sepWidth = 2;
|
|
1196
1195
|
const precedingWidth = leading.reduce(
|
|
1197
|
-
(total, text) => total + displayWidth(text) +
|
|
1196
|
+
(total, text) => total + displayWidth(text) + sepWidth,
|
|
1198
1197
|
0
|
|
1199
1198
|
);
|
|
1200
1199
|
const full = opts.provider ? `${opts.provider}/${opts.model}` : opts.model;
|
|
@@ -1205,8 +1204,8 @@ function statusBarAutonomySpan(opts) {
|
|
|
1205
1204
|
let col = RAIL_CAP;
|
|
1206
1205
|
if (opts.yolo) {
|
|
1207
1206
|
const yolo = opts.monochrome ? "YOLO" : `${glyphs.warning} YOLO`;
|
|
1208
|
-
const
|
|
1209
|
-
col += displayWidth(yolo) +
|
|
1207
|
+
const sepWidth = 2;
|
|
1208
|
+
col += displayWidth(yolo) + sepWidth;
|
|
1210
1209
|
}
|
|
1211
1210
|
const label = opts.monochrome ? opts.autonomy.toUpperCase() : `\u221E ${opts.autonomy.toUpperCase()}`;
|
|
1212
1211
|
return { start: col + 1, len: displayWidth(label) };
|
|
@@ -1380,12 +1379,16 @@ var COMFORTABLE_THRESHOLD = 90;
|
|
|
1380
1379
|
function chipColor(color, isNoColor) {
|
|
1381
1380
|
return isNoColor ? void 0 : color;
|
|
1382
1381
|
}
|
|
1382
|
+
var STACK_ORANGE = "#FD9F02";
|
|
1383
1383
|
var LINE_BG_COLORS = [theme.surface, theme.surface, theme.surface, theme.surface];
|
|
1384
1384
|
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
1385
1385
|
var SPINNER_INTERVAL_MS = 1e3;
|
|
1386
1386
|
function StatusBar({
|
|
1387
1387
|
model,
|
|
1388
1388
|
provider,
|
|
1389
|
+
version,
|
|
1390
|
+
latestVersion,
|
|
1391
|
+
updateAvailable,
|
|
1389
1392
|
state,
|
|
1390
1393
|
thinkingWord,
|
|
1391
1394
|
thinkingAnimationStyle,
|
|
@@ -1414,11 +1417,15 @@ function StatusBar({
|
|
|
1414
1417
|
memoryContextMonitor,
|
|
1415
1418
|
contextStrategy,
|
|
1416
1419
|
hiddenItems,
|
|
1420
|
+
// Component-level fallback stays 'detailed' for back-compat with callers/tests
|
|
1421
|
+
// that omit `mode`. The user-facing default is 'minimum' (DEFAULT_STATUSLINE_MODE),
|
|
1422
|
+
// applied at the app/settings layer — not here.
|
|
1417
1423
|
mode = "detailed",
|
|
1418
1424
|
events,
|
|
1419
1425
|
sessionId,
|
|
1420
1426
|
eternalStage,
|
|
1421
1427
|
goalSummary,
|
|
1428
|
+
droppedTools,
|
|
1422
1429
|
indexState,
|
|
1423
1430
|
breakerCountdown,
|
|
1424
1431
|
modeLabel,
|
|
@@ -1565,7 +1572,7 @@ function StatusBar({
|
|
|
1565
1572
|
const liveActive = memoryMonitor ? activeMemoryContextCount(memoryMonitor) : 0;
|
|
1566
1573
|
const reportedActive = memoryMonitor ? liveActive : Sage?.activeInContext ?? 0;
|
|
1567
1574
|
memoryDetailChips.push(
|
|
1568
|
-
/* @__PURE__ */ jsx5(Text, { color: chipColor(theme.accent, isNoColor), children: isNoColor ? "Memory " : `${STATUSLINE_ICONS.memory_context} ` }, "mem-label")
|
|
1575
|
+
/* @__PURE__ */ jsx5(Text, { color: chipColor(theme.accent, isNoColor), children: isNoColor ? "Memory " : `${STATUSLINE_ICONS.memory_context} Memory ` }, "mem-label")
|
|
1569
1576
|
);
|
|
1570
1577
|
if (Sage) {
|
|
1571
1578
|
memoryDetailChips.push(
|
|
@@ -1717,6 +1724,18 @@ function StatusBar({
|
|
|
1717
1724
|
stateStatusChip,
|
|
1718
1725
|
fleetWorkingTime != null && fleetWorkingTime > 0 && showChip("elapsed") ? /* @__PURE__ */ jsx5(Text, { dimColor: !isNoColor, children: isNoColor ? fmtElapsed(fleetWorkingTime) : `${STATUSLINE_ICONS.elapsed} ${fmtElapsed(fleetWorkingTime)}` }) : null
|
|
1719
1726
|
].filter((c) => c !== null);
|
|
1727
|
+
const showUpdateNotice = Boolean(updateAvailable) && typeof latestVersion === "string" && latestVersion.length > 0 && latestVersion !== version;
|
|
1728
|
+
const versionStatusChip = version ? /* @__PURE__ */ jsxs4(Text, { children: [
|
|
1729
|
+
/* @__PURE__ */ jsxs4(Text, { color: isNoColor ? void 0 : theme.textSecondary, dimColor: !isNoColor, children: [
|
|
1730
|
+
"v",
|
|
1731
|
+
version
|
|
1732
|
+
] }),
|
|
1733
|
+
showUpdateNotice ? /* @__PURE__ */ jsxs4(Text, { color: isNoColor ? void 0 : STACK_ORANGE, children: [
|
|
1734
|
+
" \xB7 (update v",
|
|
1735
|
+
latestVersion,
|
|
1736
|
+
")"
|
|
1737
|
+
] }) : null
|
|
1738
|
+
] }) : null;
|
|
1720
1739
|
const minimumChips = [
|
|
1721
1740
|
// State with animation
|
|
1722
1741
|
showChip("state") && thinking ? /* @__PURE__ */ jsx5(
|
|
@@ -1774,10 +1793,6 @@ function StatusBar({
|
|
|
1774
1793
|
) : null,
|
|
1775
1794
|
// Fleet working time
|
|
1776
1795
|
fleetWorkingTime != null && fleetWorkingTime > 0 && showChip("elapsed") ? /* @__PURE__ */ jsx5(Text, { dimColor: !isNoColor, children: fmtElapsed(fleetWorkingTime) }) : null,
|
|
1777
|
-
processMemory && showChip("memory") ? /* @__PURE__ */ jsxs4(Text, { color: chipColor(memoryColor, isNoColor), children: [
|
|
1778
|
-
"RAM ",
|
|
1779
|
-
fmtMemory(processMemory.rss)
|
|
1780
|
-
] }) : null,
|
|
1781
1796
|
// Work summary (compact)
|
|
1782
1797
|
...minimalWorkParts.length > 0 ? [/* @__PURE__ */ jsx5(Text, { dimColor: !isNoColor, children: minimalWorkParts.slice(0, 2).join(" \xB7 ") })] : []
|
|
1783
1798
|
].filter((c) => c !== null);
|
|
@@ -1808,7 +1823,15 @@ function StatusBar({
|
|
|
1808
1823
|
const detailChips = [];
|
|
1809
1824
|
if (mailbox && showMailbox) {
|
|
1810
1825
|
detailChips.push(
|
|
1811
|
-
mailbox.unread > 0 ? /* @__PURE__ */
|
|
1826
|
+
mailbox.unread > 0 ? /* @__PURE__ */ jsxs4(Text, { color: isNoColor ? void 0 : theme.warn, bold: true, children: [
|
|
1827
|
+
STATUSLINE_ICONS.mailbox,
|
|
1828
|
+
" ",
|
|
1829
|
+
mailbox.unread,
|
|
1830
|
+
" new"
|
|
1831
|
+
] }) : /* @__PURE__ */ jsxs4(Text, { dimColor: !isNoColor, children: [
|
|
1832
|
+
STATUSLINE_ICONS.mailbox,
|
|
1833
|
+
" 0"
|
|
1834
|
+
] }),
|
|
1812
1835
|
/* @__PURE__ */ jsxs4(Text, { color: isNoColor ? void 0 : theme.accent, children: [
|
|
1813
1836
|
glyphs.peers,
|
|
1814
1837
|
" ",
|
|
@@ -1838,6 +1861,7 @@ function StatusBar({
|
|
|
1838
1861
|
PowerlineRail,
|
|
1839
1862
|
{
|
|
1840
1863
|
segments: minimumChips,
|
|
1864
|
+
rightAnchor: versionStatusChip,
|
|
1841
1865
|
budget: Math.max(12, termWidth),
|
|
1842
1866
|
monochrome: isNoColor,
|
|
1843
1867
|
fillBg: LINE_BG_COLORS[0]
|
|
@@ -1849,6 +1873,7 @@ function StatusBar({
|
|
|
1849
1873
|
PowerlineRail,
|
|
1850
1874
|
{
|
|
1851
1875
|
segments: isCompact ? modeChips.slice(0, 5) : modeChips,
|
|
1876
|
+
rightAnchor: versionStatusChip,
|
|
1852
1877
|
budget: Math.max(12, termWidth),
|
|
1853
1878
|
monochrome: isNoColor,
|
|
1854
1879
|
fillBg: LINE_BG_COLORS[0]
|
|
@@ -1999,6 +2024,7 @@ function StatusBar({
|
|
|
1999
2024
|
children: isNoColor ? `auto in ${autoProceedCountdown}s` : `${STATUSLINE_ICONS.auto_proceed} auto in ${autoProceedCountdown}s`
|
|
2000
2025
|
}
|
|
2001
2026
|
) : null,
|
|
2027
|
+
droppedTools && droppedTools > 0 ? /* @__PURE__ */ jsx5(Text, { color: isNoColor ? void 0 : theme.warn, children: isNoColor ? `-${droppedTools} tools` : `${STATUSLINE_ICONS.tools} -${droppedTools}` }) : null,
|
|
2002
2028
|
...detailChips
|
|
2003
2029
|
].filter((c) => c !== null),
|
|
2004
2030
|
budget: Math.max(12, termWidth),
|
|
@@ -3582,7 +3608,9 @@ var SETTINGS_PICKER_JUMP_CHORDS = Object.freeze([
|
|
|
3582
3608
|
{ mod: "alt-shift", letter: "g", field: 35, label: "Config scope" },
|
|
3583
3609
|
{ mod: "alt", letter: "n", field: 36, label: "Animation" },
|
|
3584
3610
|
{ mod: "alt", letter: "p", field: 40, label: "Show agent swarm panel" },
|
|
3585
|
-
{ mod: "alt", letter: "r", field: 41, label: "Pre-refine countdown" }
|
|
3611
|
+
{ mod: "alt", letter: "r", field: 41, label: "Pre-refine countdown" },
|
|
3612
|
+
{ mod: "alt-shift", letter: "s", field: 43, label: "Show SAGE Memory Inject" },
|
|
3613
|
+
{ mod: "alt-shift", letter: "t", field: 44, label: "SAGE Memory Inject threshold" }
|
|
3586
3614
|
]);
|
|
3587
3615
|
function settingsPickerJumpField(mod, letter) {
|
|
3588
3616
|
const lower = letter.toLowerCase();
|
|
@@ -3629,6 +3657,7 @@ var CONTEXT_MODE_DESCS = {
|
|
|
3629
3657
|
deep: "Larger context for complex tasks"
|
|
3630
3658
|
};
|
|
3631
3659
|
var STATUSLINE_MODES = ["minimum", "detailed", "no-color"];
|
|
3660
|
+
var DEFAULT_STATUSLINE_MODE = "minimum";
|
|
3632
3661
|
var REASONING_MODES = ["auto", "on", "off"];
|
|
3633
3662
|
var REASONING_EFFORTS = [
|
|
3634
3663
|
"none",
|
|
@@ -3641,8 +3670,8 @@ var REASONING_EFFORTS = [
|
|
|
3641
3670
|
];
|
|
3642
3671
|
var CACHE_TTLS = ["default", "5m", "1h"];
|
|
3643
3672
|
var STATUSLINE_MODE_DESCS = {
|
|
3644
|
-
minimum: "Single line with essential chips only",
|
|
3645
|
-
detailed: "Full multi-line statusline
|
|
3673
|
+
minimum: "Single line with essential chips only (default)",
|
|
3674
|
+
detailed: "Full multi-line statusline",
|
|
3646
3675
|
"no-color": "Multiline statusline without colors or icons"
|
|
3647
3676
|
};
|
|
3648
3677
|
var MAX_ITERATIONS_PRESETS = [100, 200, 500, 1e3, 0];
|
|
@@ -3708,7 +3737,7 @@ var MODE_DESC = {
|
|
|
3708
3737
|
suggest: "Shows next-step suggestions after each turn",
|
|
3709
3738
|
auto: "Self-driving \u2014 agent continues automatically"
|
|
3710
3739
|
};
|
|
3711
|
-
var SETTINGS_FIELD_COUNT =
|
|
3740
|
+
var SETTINGS_FIELD_COUNT = 45;
|
|
3712
3741
|
var THINKING_WORD_FIELD = 22;
|
|
3713
3742
|
var THINKING_WORD_PRESETS = [
|
|
3714
3743
|
"thinking",
|
|
@@ -3811,8 +3840,12 @@ var SETTINGS_FIELD_LABELS = [
|
|
|
3811
3840
|
// 40
|
|
3812
3841
|
"Pre-refine countdown",
|
|
3813
3842
|
// 41
|
|
3814
|
-
"Read symbols"
|
|
3843
|
+
"Read symbols",
|
|
3815
3844
|
// 42
|
|
3845
|
+
"Show SAGE Memory Inject",
|
|
3846
|
+
// 43
|
|
3847
|
+
"SAGE Memory Inject threshold"
|
|
3848
|
+
// 44
|
|
3816
3849
|
];
|
|
3817
3850
|
function resolveSettingsFieldValue(field, input) {
|
|
3818
3851
|
const raw = input.trim().toLowerCase();
|
|
@@ -3837,7 +3870,8 @@ function resolveSettingsFieldValue(field, input) {
|
|
|
3837
3870
|
[37, "breakerEnabled"],
|
|
3838
3871
|
[39, "showModelReasoning"],
|
|
3839
3872
|
[40, "showAgentSwarmPanel"],
|
|
3840
|
-
[42, "readSymbols"]
|
|
3873
|
+
[42, "readSymbols"],
|
|
3874
|
+
[43, "showSageMemoryInject"]
|
|
3841
3875
|
]);
|
|
3842
3876
|
const boolKey = BOOL_FIELDS.get(field);
|
|
3843
3877
|
if (boolKey) {
|
|
@@ -3906,6 +3940,26 @@ function resolveSettingsFieldValue(field, input) {
|
|
|
3906
3940
|
error: `Invalid value "${input}" for ${label}. Valid: ${values.join(", ")}.`
|
|
3907
3941
|
};
|
|
3908
3942
|
}
|
|
3943
|
+
if (field === 44) {
|
|
3944
|
+
const presets = SAGE_THRESHOLD_PRESETS;
|
|
3945
|
+
const rawMatch = raw.match(/^(\d+(?:\.\d+)?)$/);
|
|
3946
|
+
if (rawMatch) {
|
|
3947
|
+
const asFloat = Number.parseFloat(rawMatch[1]);
|
|
3948
|
+
if (presets.includes(asFloat)) {
|
|
3949
|
+
return {
|
|
3950
|
+
ok: true,
|
|
3951
|
+
patch: { sageMemoryInjectThreshold: asFloat },
|
|
3952
|
+
label,
|
|
3953
|
+
displayValue: formatSageThreshold(asFloat)
|
|
3954
|
+
};
|
|
3955
|
+
}
|
|
3956
|
+
}
|
|
3957
|
+
const options = presets.map((p) => formatSageThreshold(p)).join(", ");
|
|
3958
|
+
return {
|
|
3959
|
+
ok: false,
|
|
3960
|
+
error: `Invalid value "${input}" for ${label}. Available: ${options}.`
|
|
3961
|
+
};
|
|
3962
|
+
}
|
|
3909
3963
|
const presetLabel = (n, zeroLabel) => n === 0 ? zeroLabel : String(n);
|
|
3910
3964
|
const PRESET_FIELDS = [
|
|
3911
3965
|
[1, "delayMs", DELAY_PRESETS_MS, (n) => formatSettingsDelay(n)],
|
|
@@ -3988,7 +4042,8 @@ function getSettingsFieldValue(values, field) {
|
|
|
3988
4042
|
[37, "breakerEnabled"],
|
|
3989
4043
|
[39, "showModelReasoning"],
|
|
3990
4044
|
[40, "showAgentSwarmPanel"],
|
|
3991
|
-
[42, "readSymbols"]
|
|
4045
|
+
[42, "readSymbols"],
|
|
4046
|
+
[43, "showSageMemoryInject"]
|
|
3992
4047
|
];
|
|
3993
4048
|
for (const [f, key] of BOOL_KEYS) {
|
|
3994
4049
|
if (field !== f) continue;
|
|
@@ -4023,7 +4078,8 @@ function getSettingsFieldValue(values, field) {
|
|
|
4023
4078
|
[41, "preRefineSeconds", formatPreRefineSeconds],
|
|
4024
4079
|
[21, "multiDiffSummaryThreshold", formatMultiDiffSummaryThreshold],
|
|
4025
4080
|
[30, "maxConcurrent", (n) => presetLabel(n, "runtime default")],
|
|
4026
|
-
[38, "breakerAutoKillResetMs", formatBreakerTimeout]
|
|
4081
|
+
[38, "breakerAutoKillResetMs", formatBreakerTimeout],
|
|
4082
|
+
[44, "sageMemoryInjectThreshold", formatSageThreshold]
|
|
4027
4083
|
];
|
|
4028
4084
|
for (const [f, key, fmt2] of PRESET_KEYS) {
|
|
4029
4085
|
if (field !== f) continue;
|
|
@@ -4077,7 +4133,7 @@ var SETTINGS_SECTIONS = [
|
|
|
4077
4133
|
},
|
|
4078
4134
|
{
|
|
4079
4135
|
name: "Display",
|
|
4080
|
-
fields: [39, 40, 41]
|
|
4136
|
+
fields: [39, 40, 41, 43, 44]
|
|
4081
4137
|
}
|
|
4082
4138
|
];
|
|
4083
4139
|
function formatAllSettingsSummary(values) {
|
|
@@ -4093,6 +4149,10 @@ function formatAllSettingsSummary(values) {
|
|
|
4093
4149
|
}
|
|
4094
4150
|
return lines.join("\n");
|
|
4095
4151
|
}
|
|
4152
|
+
var SAGE_THRESHOLD_PRESETS = [0.72, 0.75, 0.85, 0.9, 0.95];
|
|
4153
|
+
function formatSageThreshold(t) {
|
|
4154
|
+
return t.toFixed(2);
|
|
4155
|
+
}
|
|
4096
4156
|
var SETTINGS_DEFAULTS = Object.freeze({
|
|
4097
4157
|
// Factory defaults mirror the core config defaults: autonomy 'auto'
|
|
4098
4158
|
// (self-driving) and yolo on (auto-approve). Live values still come from
|
|
@@ -4127,7 +4187,7 @@ var SETTINGS_DEFAULTS = Object.freeze({
|
|
|
4127
4187
|
enhanceEnabled: true,
|
|
4128
4188
|
enhanceLanguage: "original",
|
|
4129
4189
|
debugStream: false,
|
|
4130
|
-
statuslineMode:
|
|
4190
|
+
statuslineMode: DEFAULT_STATUSLINE_MODE,
|
|
4131
4191
|
reasoningMode: "auto",
|
|
4132
4192
|
reasoningEffort: "high",
|
|
4133
4193
|
reasoningPreserve: false,
|
|
@@ -4139,7 +4199,9 @@ var SETTINGS_DEFAULTS = Object.freeze({
|
|
|
4139
4199
|
breakerAutoKillResetMs: 6e4,
|
|
4140
4200
|
showModelReasoning: true,
|
|
4141
4201
|
showAgentSwarmPanel: true,
|
|
4142
|
-
readSymbols: false
|
|
4202
|
+
readSymbols: false,
|
|
4203
|
+
showSageMemoryInject: false,
|
|
4204
|
+
sageMemoryInjectThreshold: 0.85
|
|
4143
4205
|
});
|
|
4144
4206
|
function resetSettingsFieldValue(field) {
|
|
4145
4207
|
const result = getSettingsFieldValue(SETTINGS_DEFAULTS, field);
|
|
@@ -4192,7 +4254,9 @@ function buildResetPatch(field) {
|
|
|
4192
4254
|
[39, "showModelReasoning"],
|
|
4193
4255
|
[40, "showAgentSwarmPanel"],
|
|
4194
4256
|
[41, "preRefineSeconds"],
|
|
4195
|
-
[42, "readSymbols"]
|
|
4257
|
+
[42, "readSymbols"],
|
|
4258
|
+
[43, "showSageMemoryInject"],
|
|
4259
|
+
[44, "sageMemoryInjectThreshold"]
|
|
4196
4260
|
];
|
|
4197
4261
|
for (const [f, key] of KEY_MAP) {
|
|
4198
4262
|
if (f === field) {
|
|
@@ -4323,6 +4387,8 @@ function SettingsPicker({
|
|
|
4323
4387
|
breakerAutoKillResetMs,
|
|
4324
4388
|
showModelReasoning,
|
|
4325
4389
|
showAgentSwarmPanel,
|
|
4390
|
+
showSageMemoryInject,
|
|
4391
|
+
sageMemoryInjectThreshold,
|
|
4326
4392
|
readSymbols,
|
|
4327
4393
|
hint
|
|
4328
4394
|
}) {
|
|
@@ -4562,6 +4628,16 @@ function SettingsPicker({
|
|
|
4562
4628
|
label: "Read symbols",
|
|
4563
4629
|
value: boolVal(readSymbols),
|
|
4564
4630
|
detail: "Include codebase-index symbols in read tool results"
|
|
4631
|
+
},
|
|
4632
|
+
{
|
|
4633
|
+
label: "Show SAGE Memory Inject",
|
|
4634
|
+
value: boolVal(showSageMemoryInject),
|
|
4635
|
+
detail: "Show SAGE memory injection blocks in tool results"
|
|
4636
|
+
},
|
|
4637
|
+
{
|
|
4638
|
+
label: "SAGE Memory Inject threshold",
|
|
4639
|
+
value: formatSageThreshold(sageMemoryInjectThreshold),
|
|
4640
|
+
detail: "Min relation strength for injection (0.72\u20130.95)"
|
|
4565
4641
|
}
|
|
4566
4642
|
];
|
|
4567
4643
|
const fieldRowIndex = [];
|
|
@@ -5875,7 +5951,7 @@ var F_KEY_PANEL_ENTRIES = [
|
|
|
5875
5951
|
key: 12,
|
|
5876
5952
|
label: "Kanban board panel",
|
|
5877
5953
|
action: "toggleKanbanPanel",
|
|
5878
|
-
helpKeys: "F12 or Ctrl+
|
|
5954
|
+
helpKeys: "F12 or Ctrl+Y",
|
|
5879
5955
|
helpDescription: "kanban board panel (also /kanban)"
|
|
5880
5956
|
},
|
|
5881
5957
|
{
|
|
@@ -6156,7 +6232,12 @@ function useAppPickerKeys({
|
|
|
6156
6232
|
});
|
|
6157
6233
|
return;
|
|
6158
6234
|
}
|
|
6159
|
-
dispatch({
|
|
6235
|
+
dispatch({
|
|
6236
|
+
type: "replaceHistory",
|
|
6237
|
+
entries: result.entries,
|
|
6238
|
+
nextId: result.nextId,
|
|
6239
|
+
contextSnapshot: result.contextSnapshot
|
|
6240
|
+
});
|
|
6160
6241
|
dispatch({ type: "resumePickerClose" });
|
|
6161
6242
|
dispatch({
|
|
6162
6243
|
type: "addEntry",
|
|
@@ -6182,7 +6263,12 @@ function useAppPickerKeys({
|
|
|
6182
6263
|
dispatch({ type: "sessionsPanelBusy", on: false });
|
|
6183
6264
|
return;
|
|
6184
6265
|
}
|
|
6185
|
-
dispatch({
|
|
6266
|
+
dispatch({
|
|
6267
|
+
type: "replaceHistory",
|
|
6268
|
+
entries: result.entries,
|
|
6269
|
+
nextId: result.nextId,
|
|
6270
|
+
contextSnapshot: result.contextSnapshot
|
|
6271
|
+
});
|
|
6186
6272
|
dispatch({ type: "toggleSessionsPanel" });
|
|
6187
6273
|
dispatch({
|
|
6188
6274
|
type: "addEntry",
|
|
@@ -8531,7 +8617,7 @@ async function handleMemoryWrite(store, sub, rest) {
|
|
|
8531
8617
|
try {
|
|
8532
8618
|
const existing = await Sage.getSage(id);
|
|
8533
8619
|
if (!existing) return { message: `No memory with id \`${id}\`.` };
|
|
8534
|
-
await Sage.deleteSage(id, reason);
|
|
8620
|
+
await Sage.deleteSage(id, reason, { force: true });
|
|
8535
8621
|
return { message: `Deleted \`${id}\`.` };
|
|
8536
8622
|
} catch (err) {
|
|
8537
8623
|
return { message: `Could not delete: ${memErr(err)}` };
|
|
@@ -9779,8 +9865,8 @@ function handleCollabDone(event, dispatch, stateRef) {
|
|
|
9779
9865
|
// src/hooks/use-file-search.ts
|
|
9780
9866
|
import * as fs2 from "node:fs/promises";
|
|
9781
9867
|
import * as path2 from "node:path";
|
|
9782
|
-
import { useEffect as useEffect14 } from "react";
|
|
9783
9868
|
import { toErrorMessage as toErrorMessage4 } from "@wrongstack/core/utils";
|
|
9869
|
+
import { useEffect as useEffect14 } from "react";
|
|
9784
9870
|
|
|
9785
9871
|
// src/file-search.ts
|
|
9786
9872
|
import * as fs from "node:fs/promises";
|
|
@@ -9991,7 +10077,7 @@ var TOKEN_PREVIEWS_MAX_ENTRIES = 64;
|
|
|
9991
10077
|
var TOKEN_PREVIEW_MAX_CHARS = 8 * 1024;
|
|
9992
10078
|
var TOKEN_PREVIEW_MAX_LINES = 6;
|
|
9993
10079
|
var TOKEN_PREVIEWS_MAX_CHARS = 256 * 1024;
|
|
9994
|
-
var
|
|
10080
|
+
var TEXT_FILE_ATTACHMENT_INLINE_MAX_BYTES = 1024 * 1024;
|
|
9995
10081
|
var TRUNCATION_MARKER = "\u2026 [preview truncated]";
|
|
9996
10082
|
var ATTACHMENT_WRAPPER_RE = /^<(?:pasted|file(?: path="[^"]*")?)>\n([\s\S]*)\n<\/(?:pasted|file)>$/;
|
|
9997
10083
|
function createTokenPreview(value, maxChars = TOKEN_PREVIEW_MAX_CHARS, maxLines = TOKEN_PREVIEW_MAX_LINES) {
|
|
@@ -10169,17 +10255,13 @@ function useFileSearch(options) {
|
|
|
10169
10255
|
const absPath = path2.isAbsolute(picked) ? picked : path2.join(projectRoot, picked);
|
|
10170
10256
|
try {
|
|
10171
10257
|
const stat3 = await fs2.stat(absPath);
|
|
10172
|
-
|
|
10173
|
-
|
|
10174
|
-
|
|
10175
|
-
|
|
10176
|
-
|
|
10177
|
-
|
|
10178
|
-
|
|
10179
|
-
if (bytes > TEXT_FILE_ATTACHMENT_MAX_BYTES) {
|
|
10180
|
-
throw new Error(
|
|
10181
|
-
`file exceeds ${(TEXT_FILE_ATTACHMENT_MAX_BYTES / (1024 * 1024)).toFixed(0)} MiB attachment limit (${bytes.toLocaleString()} UTF-8 bytes)`
|
|
10182
|
-
);
|
|
10258
|
+
let data;
|
|
10259
|
+
if (stat3.size > TEXT_FILE_ATTACHMENT_INLINE_MAX_BYTES) {
|
|
10260
|
+
data = fileReadContract(picked, stat3.size);
|
|
10261
|
+
} else {
|
|
10262
|
+
const inline = await fs2.readFile(absPath, "utf8");
|
|
10263
|
+
const bytes = Buffer.byteLength(inline, "utf8");
|
|
10264
|
+
data = bytes > TEXT_FILE_ATTACHMENT_INLINE_MAX_BYTES ? fileReadContract(picked, bytes) : inline;
|
|
10183
10265
|
}
|
|
10184
10266
|
const token = await builder.registerFile({
|
|
10185
10267
|
kind: "file",
|
|
@@ -10205,6 +10287,14 @@ function useFileSearch(options) {
|
|
|
10205
10287
|
};
|
|
10206
10288
|
return { onPickerEnter: acceptPickerSelection };
|
|
10207
10289
|
}
|
|
10290
|
+
function fileReadContract(filePath, bytes) {
|
|
10291
|
+
return [
|
|
10292
|
+
"[File reference contract]",
|
|
10293
|
+
`Referenced project file: ${JSON.stringify(filePath)} (${bytes.toLocaleString()} bytes; content not inlined).`,
|
|
10294
|
+
"Before answering or modifying anything related to this reference, use the available file-reading tools to read the complete file.",
|
|
10295
|
+
"If a read is paginated or chunked, continue from the same path until EOF. Do not treat a partial read or preview as the complete file."
|
|
10296
|
+
].join("\n");
|
|
10297
|
+
}
|
|
10208
10298
|
|
|
10209
10299
|
// src/hooks/use-help-panel.ts
|
|
10210
10300
|
import { useCallback as useCallback8 } from "react";
|
|
@@ -10427,6 +10517,7 @@ function retainCheckpoints(checkpoints, budget = {}) {
|
|
|
10427
10517
|
|
|
10428
10518
|
// src/components/history/replay.ts
|
|
10429
10519
|
import { SESSION_MARKER_EVENT_TYPES, sessionEventToMarker } from "@wrongstack/core/types";
|
|
10520
|
+
import { isFinalTurnStopReason } from "@wrongstack/tools/next-steps";
|
|
10430
10521
|
var MARKER_EVENT_TYPES = SESSION_MARKER_EVENT_TYPES;
|
|
10431
10522
|
var SUBAGENT_MARKER_STYLE = {
|
|
10432
10523
|
agent_spawned: { color: "magenta", icon: "\u26A1" },
|
|
@@ -10464,18 +10555,18 @@ function replaySessionMessages(messages, events, startId) {
|
|
|
10464
10555
|
backbone.push({ ts, entry });
|
|
10465
10556
|
return entry;
|
|
10466
10557
|
};
|
|
10467
|
-
const appendText = (role, text, ts) => {
|
|
10558
|
+
const appendText = (role, text, ts, final) => {
|
|
10468
10559
|
if (!text.trim()) return;
|
|
10469
10560
|
push(
|
|
10470
10561
|
ts,
|
|
10471
|
-
role === "assistant" ? { kind: "assistant", text } : role === "system" ? { kind: "info", text } : { kind: "user", text }
|
|
10562
|
+
role === "assistant" ? { kind: "assistant", text, final } : role === "system" ? { kind: "info", text } : { kind: "user", text }
|
|
10472
10563
|
);
|
|
10473
10564
|
};
|
|
10474
10565
|
for (const message of messages) {
|
|
10475
10566
|
const ts = message.ts ?? lastTs;
|
|
10476
10567
|
if (message.ts) lastTs = message.ts;
|
|
10477
10568
|
if (typeof message.content === "string") {
|
|
10478
|
-
appendText(message.role, message.content, ts);
|
|
10569
|
+
appendText(message.role, message.content, ts, true);
|
|
10479
10570
|
continue;
|
|
10480
10571
|
}
|
|
10481
10572
|
for (const block of message.content) {
|
|
@@ -10483,13 +10574,20 @@ function replaySessionMessages(messages, events, startId) {
|
|
|
10483
10574
|
push(ts, { kind: "thinking", text: block.thinking });
|
|
10484
10575
|
}
|
|
10485
10576
|
}
|
|
10486
|
-
|
|
10487
|
-
|
|
10488
|
-
|
|
10489
|
-
|
|
10490
|
-
|
|
10577
|
+
const final = !message.content.some((block) => block.type === "tool_use");
|
|
10578
|
+
const textParts = [];
|
|
10579
|
+
const flushText = () => {
|
|
10580
|
+
const text = textParts.join("").trim();
|
|
10581
|
+
if (text) appendText(message.role, text, ts, final);
|
|
10582
|
+
textParts.length = 0;
|
|
10583
|
+
};
|
|
10491
10584
|
for (const block of message.content) {
|
|
10585
|
+
if (block.type === "text") {
|
|
10586
|
+
textParts.push(block.text);
|
|
10587
|
+
continue;
|
|
10588
|
+
}
|
|
10492
10589
|
if (block.type === "tool_use") {
|
|
10590
|
+
flushText();
|
|
10493
10591
|
const end2 = toolEnds.get(block.id);
|
|
10494
10592
|
const entry = push(ts, {
|
|
10495
10593
|
kind: "tool",
|
|
@@ -10505,6 +10603,7 @@ function replaySessionMessages(messages, events, startId) {
|
|
|
10505
10603
|
continue;
|
|
10506
10604
|
}
|
|
10507
10605
|
if (block.type !== "tool_result") continue;
|
|
10606
|
+
flushText();
|
|
10508
10607
|
const existing = toolEntries.get(block.tool_use_id);
|
|
10509
10608
|
if (existing) {
|
|
10510
10609
|
existing.output = toolOutputPreview(block.content);
|
|
@@ -10524,6 +10623,7 @@ function replaySessionMessages(messages, events, startId) {
|
|
|
10524
10623
|
outputLines: end?.outputLines
|
|
10525
10624
|
});
|
|
10526
10625
|
}
|
|
10626
|
+
flushText();
|
|
10527
10627
|
}
|
|
10528
10628
|
const dummyPending = /* @__PURE__ */ new Map();
|
|
10529
10629
|
const dummyCompleted = /* @__PURE__ */ new Map();
|
|
@@ -10567,7 +10667,7 @@ function eventToEntry(ev, pendingTools, completedTools) {
|
|
|
10567
10667
|
}
|
|
10568
10668
|
const text = ev.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
10569
10669
|
if (!text.trim()) return null;
|
|
10570
|
-
return { kind: "assistant", text };
|
|
10670
|
+
return { kind: "assistant", text, final: isFinalTurnStopReason(ev.stopReason) };
|
|
10571
10671
|
}
|
|
10572
10672
|
case "tool_use": {
|
|
10573
10673
|
pendingTools.set(ev.id, { name: ev.name, input: ev.input, ts: ev.ts });
|
|
@@ -10824,9 +10924,9 @@ function rehydrateHistory(messages, startId, toolCalls) {
|
|
|
10824
10924
|
outputTokens: tc.outputTokens,
|
|
10825
10925
|
outputLines: tc.outputLines
|
|
10826
10926
|
});
|
|
10827
|
-
const pushAssistantText = (parts) => {
|
|
10927
|
+
const pushAssistantText = (parts, final) => {
|
|
10828
10928
|
const text = parts.join("").trim();
|
|
10829
|
-
if (text) entries.push({ id: nextId++, kind: "assistant", text });
|
|
10929
|
+
if (text) entries.push({ id: nextId++, kind: "assistant", text, final });
|
|
10830
10930
|
parts.length = 0;
|
|
10831
10931
|
};
|
|
10832
10932
|
for (const msg of messages) {
|
|
@@ -10839,23 +10939,25 @@ function rehydrateHistory(messages, startId, toolCalls) {
|
|
|
10839
10939
|
if (msg.role === "assistant") {
|
|
10840
10940
|
if (!Array.isArray(msg.content)) {
|
|
10841
10941
|
const text = textOf(msg).trim();
|
|
10842
|
-
if (text) entries.push({ id: nextId++, kind: "assistant", text });
|
|
10942
|
+
if (text) entries.push({ id: nextId++, kind: "assistant", text, final: true });
|
|
10843
10943
|
continue;
|
|
10844
10944
|
}
|
|
10945
|
+
const blocks = msg.content;
|
|
10946
|
+
const final = !blocks.some((block) => block.type === "tool_use");
|
|
10845
10947
|
const textParts = [];
|
|
10846
|
-
for (const block of
|
|
10948
|
+
for (const block of blocks) {
|
|
10847
10949
|
if (block.type === "text") {
|
|
10848
10950
|
textParts.push(block.text);
|
|
10849
10951
|
continue;
|
|
10850
10952
|
}
|
|
10851
10953
|
if (block.type !== "tool_use") continue;
|
|
10852
|
-
pushAssistantText(textParts);
|
|
10954
|
+
pushAssistantText(textParts, final);
|
|
10853
10955
|
const tc = toolCallsById.get(block.id);
|
|
10854
10956
|
if (!tc) continue;
|
|
10855
10957
|
entries.push(toolEntryFor(tc));
|
|
10856
10958
|
consumed.add(block.id);
|
|
10857
10959
|
}
|
|
10858
|
-
pushAssistantText(textParts);
|
|
10960
|
+
pushAssistantText(textParts, final);
|
|
10859
10961
|
}
|
|
10860
10962
|
}
|
|
10861
10963
|
if (toolCalls) {
|
|
@@ -11035,7 +11137,7 @@ function createInitialState(options) {
|
|
|
11035
11137
|
enhanceEnabled: true,
|
|
11036
11138
|
enhanceLanguage: "original",
|
|
11037
11139
|
debugStream: false,
|
|
11038
|
-
statuslineMode:
|
|
11140
|
+
statuslineMode: DEFAULT_STATUSLINE_MODE,
|
|
11039
11141
|
reasoningMode: "auto",
|
|
11040
11142
|
reasoningEffort: "high",
|
|
11041
11143
|
reasoningPreserve: false,
|
|
@@ -11049,6 +11151,8 @@ function createInitialState(options) {
|
|
|
11049
11151
|
breakerAutoKillResetMs: 6e4,
|
|
11050
11152
|
showModelReasoning: true,
|
|
11051
11153
|
showAgentSwarmPanel: true,
|
|
11154
|
+
showSageMemoryInject: false,
|
|
11155
|
+
sageMemoryInjectThreshold: 0.85,
|
|
11052
11156
|
readSymbols: false
|
|
11053
11157
|
},
|
|
11054
11158
|
statuslinePicker: {
|
|
@@ -12657,11 +12761,19 @@ function reduceComposer(state, action) {
|
|
|
12657
12761
|
const maxBannerId = banners.length > 0 ? Math.max(...banners.map((b) => b.id)) : 0;
|
|
12658
12762
|
const shifted = action.entries.map((e, i) => ({ ...e, id: maxBannerId + 1 + i }));
|
|
12659
12763
|
const nextId = maxBannerId + 1 + shifted.length;
|
|
12764
|
+
const snap = action.contextSnapshot;
|
|
12765
|
+
const leaderWithSnap = snap && snap.tokens > 0 ? {
|
|
12766
|
+
...state.leader,
|
|
12767
|
+
ctxTokens: snap.tokens,
|
|
12768
|
+
ctxMaxTokens: snap.maxContext > 0 ? snap.maxContext : state.leader.ctxMaxTokens
|
|
12769
|
+
} : state.leader;
|
|
12660
12770
|
return {
|
|
12661
12771
|
...state,
|
|
12662
12772
|
entries: retainTuiHistory([...banners, ...shifted]),
|
|
12663
12773
|
nextId,
|
|
12664
|
-
historyGen: state.historyGen + 1
|
|
12774
|
+
historyGen: state.historyGen + 1,
|
|
12775
|
+
leader: leaderWithSnap,
|
|
12776
|
+
contextChipVersion: state.contextChipVersion + 1
|
|
12665
12777
|
};
|
|
12666
12778
|
}
|
|
12667
12779
|
default:
|
|
@@ -13343,6 +13455,8 @@ function reduceSettingsPanel(state, action) {
|
|
|
13343
13455
|
breakerAutoKillResetMs: action.breakerAutoKillResetMs,
|
|
13344
13456
|
showModelReasoning: action.showModelReasoning,
|
|
13345
13457
|
showAgentSwarmPanel: action.showAgentSwarmPanel,
|
|
13458
|
+
showSageMemoryInject: action.showSageMemoryInject,
|
|
13459
|
+
sageMemoryInjectThreshold: action.sageMemoryInjectThreshold,
|
|
13346
13460
|
readSymbols: action.readSymbols,
|
|
13347
13461
|
hint: void 0
|
|
13348
13462
|
}
|
|
@@ -13708,7 +13822,7 @@ function reduceSettingsValues(state, action) {
|
|
|
13708
13822
|
};
|
|
13709
13823
|
if (f === 34) {
|
|
13710
13824
|
const i = STATUSLINE_MODES.indexOf(sp.statuslineMode);
|
|
13711
|
-
const base = i < 0 ? STATUSLINE_MODES.indexOf(
|
|
13825
|
+
const base = i < 0 ? STATUSLINE_MODES.indexOf(DEFAULT_STATUSLINE_MODE) : i;
|
|
13712
13826
|
const next = (base + action.delta + STATUSLINE_MODES.length) % STATUSLINE_MODES.length;
|
|
13713
13827
|
return {
|
|
13714
13828
|
...state,
|
|
@@ -13791,6 +13905,28 @@ function reduceSettingsValues(state, action) {
|
|
|
13791
13905
|
...state,
|
|
13792
13906
|
settingsPicker: { ...sp, readSymbols: !sp.readSymbols, hint: void 0 }
|
|
13793
13907
|
};
|
|
13908
|
+
if (f === 43)
|
|
13909
|
+
return {
|
|
13910
|
+
...state,
|
|
13911
|
+
settingsPicker: {
|
|
13912
|
+
...sp,
|
|
13913
|
+
showSageMemoryInject: !sp.showSageMemoryInject,
|
|
13914
|
+
hint: void 0
|
|
13915
|
+
}
|
|
13916
|
+
};
|
|
13917
|
+
if (f === 44) {
|
|
13918
|
+
const j = SAGE_THRESHOLD_PRESETS.indexOf(sp.sageMemoryInjectThreshold);
|
|
13919
|
+
const base = j < 0 ? 0 : j;
|
|
13920
|
+
const next = (base + action.delta + SAGE_THRESHOLD_PRESETS.length) % SAGE_THRESHOLD_PRESETS.length;
|
|
13921
|
+
return {
|
|
13922
|
+
...state,
|
|
13923
|
+
settingsPicker: {
|
|
13924
|
+
...sp,
|
|
13925
|
+
sageMemoryInjectThreshold: expectDefined2(SAGE_THRESHOLD_PRESETS[next]),
|
|
13926
|
+
hint: void 0
|
|
13927
|
+
}
|
|
13928
|
+
};
|
|
13929
|
+
}
|
|
13794
13930
|
return state;
|
|
13795
13931
|
}
|
|
13796
13932
|
case "settingsValueSet": {
|
|
@@ -14848,47 +14984,79 @@ import { useEffect as useEffect20, useRef as useRef13, useState as useState7 } f
|
|
|
14848
14984
|
import { spawn } from "node:child_process";
|
|
14849
14985
|
import { buildChildEnv } from "@wrongstack/core/utils";
|
|
14850
14986
|
async function readGitInfo(cwd) {
|
|
14987
|
+
let added = 0;
|
|
14988
|
+
let deleted = 0;
|
|
14989
|
+
let untracked = 0;
|
|
14851
14990
|
const [branchRes, numstatRes, statusRes] = await Promise.all([
|
|
14852
14991
|
runGit(cwd, ["branch", "--show-current"]),
|
|
14853
|
-
|
|
14854
|
-
|
|
14992
|
+
foldGit(cwd, ["diff", "HEAD", "--numstat"], (line) => {
|
|
14993
|
+
if (!line) return;
|
|
14994
|
+
const [a, d] = line.split(" ");
|
|
14995
|
+
if (a && a !== "-") added += Number.parseInt(a, 10) || 0;
|
|
14996
|
+
if (d && d !== "-") deleted += Number.parseInt(d, 10) || 0;
|
|
14997
|
+
}),
|
|
14998
|
+
foldGit(cwd, ["status", "--porcelain"], (line) => {
|
|
14999
|
+
if (line.startsWith("?? ")) untracked++;
|
|
15000
|
+
})
|
|
14855
15001
|
]);
|
|
14856
15002
|
if (!branchRes.ok || !numstatRes.ok || !statusRes.ok) return null;
|
|
14857
15003
|
const branch = branchRes.stdout.trim();
|
|
14858
15004
|
const branchLabel = branch || await detachedShortSha(cwd) || "detached";
|
|
14859
|
-
let added = 0;
|
|
14860
|
-
let deleted = 0;
|
|
14861
|
-
for (const line of numstatRes.stdout.split("\n")) {
|
|
14862
|
-
if (!line) continue;
|
|
14863
|
-
const [a, d] = line.split(" ");
|
|
14864
|
-
if (a && a !== "-") added += Number.parseInt(a, 10) || 0;
|
|
14865
|
-
if (d && d !== "-") deleted += Number.parseInt(d, 10) || 0;
|
|
14866
|
-
}
|
|
14867
|
-
let untracked = 0;
|
|
14868
|
-
for (const line of statusRes.stdout.split("\n")) {
|
|
14869
|
-
if (line.startsWith("?? ")) untracked++;
|
|
14870
|
-
}
|
|
14871
15005
|
return { branch: branchLabel, added, deleted, untracked };
|
|
14872
15006
|
}
|
|
14873
15007
|
async function detachedShortSha(cwd) {
|
|
14874
15008
|
const res = await runGit(cwd, ["rev-parse", "--short", "HEAD"]);
|
|
14875
15009
|
return res.ok ? res.stdout.trim() : null;
|
|
14876
15010
|
}
|
|
15011
|
+
var MAX_RETAINED_STDOUT = 64 * 1024;
|
|
15012
|
+
var MAX_LINE_CHARS = 64 * 1024;
|
|
15013
|
+
function spawnGit(cwd, args) {
|
|
15014
|
+
return spawn("git", args, {
|
|
15015
|
+
cwd,
|
|
15016
|
+
env: buildChildEnv(),
|
|
15017
|
+
// Inherit stderr (silent) — we don't care about git's noise.
|
|
15018
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
15019
|
+
// Don't let a slow git hang the TUI.
|
|
15020
|
+
timeout: 3e3,
|
|
15021
|
+
windowsHide: true
|
|
15022
|
+
});
|
|
15023
|
+
}
|
|
15024
|
+
function foldGit(cwd, args, onLine) {
|
|
15025
|
+
return new Promise((resolve) => {
|
|
15026
|
+
try {
|
|
15027
|
+
const child = spawnGit(cwd, args);
|
|
15028
|
+
let carry = "";
|
|
15029
|
+
child.stdout?.setEncoding("utf8");
|
|
15030
|
+
child.stdout?.on("data", (chunk) => {
|
|
15031
|
+
carry += chunk;
|
|
15032
|
+
let start = 0;
|
|
15033
|
+
let nl = carry.indexOf("\n", start);
|
|
15034
|
+
while (nl !== -1) {
|
|
15035
|
+
onLine(carry.slice(start, nl));
|
|
15036
|
+
start = nl + 1;
|
|
15037
|
+
nl = carry.indexOf("\n", start);
|
|
15038
|
+
}
|
|
15039
|
+
if (start > 0) carry = carry.slice(start);
|
|
15040
|
+
if (carry.length > MAX_LINE_CHARS) carry = carry.slice(0, MAX_LINE_CHARS);
|
|
15041
|
+
});
|
|
15042
|
+
child.on("error", () => resolve({ ok: false }));
|
|
15043
|
+
child.on("close", (code) => {
|
|
15044
|
+
if (carry) onLine(carry);
|
|
15045
|
+
resolve({ ok: code === 0 });
|
|
15046
|
+
});
|
|
15047
|
+
} catch {
|
|
15048
|
+
resolve({ ok: false });
|
|
15049
|
+
}
|
|
15050
|
+
});
|
|
15051
|
+
}
|
|
14877
15052
|
function runGit(cwd, args) {
|
|
14878
15053
|
return new Promise((resolve) => {
|
|
14879
15054
|
let stdout = "";
|
|
14880
15055
|
try {
|
|
14881
|
-
const child =
|
|
14882
|
-
|
|
14883
|
-
|
|
14884
|
-
|
|
14885
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
14886
|
-
// Don't let a slow git hang the TUI.
|
|
14887
|
-
timeout: 3e3,
|
|
14888
|
-
windowsHide: true
|
|
14889
|
-
});
|
|
14890
|
-
child.stdout.setEncoding("utf8");
|
|
14891
|
-
child.stdout.on("data", (chunk) => {
|
|
15056
|
+
const child = spawnGit(cwd, args);
|
|
15057
|
+
child.stdout?.setEncoding("utf8");
|
|
15058
|
+
child.stdout?.on("data", (chunk) => {
|
|
15059
|
+
if (stdout.length >= MAX_RETAINED_STDOUT) return;
|
|
14892
15060
|
stdout += chunk;
|
|
14893
15061
|
});
|
|
14894
15062
|
child.on("error", () => resolve({ ok: false, stdout: "" }));
|
|
@@ -15081,7 +15249,7 @@ function useLiveSettingsState({
|
|
|
15081
15249
|
confirmExit
|
|
15082
15250
|
}) {
|
|
15083
15251
|
const liveSettings = getSettings?.();
|
|
15084
|
-
const liveStatuslineMode = liveSettings?.statuslineMode ??
|
|
15252
|
+
const liveStatuslineMode = liveSettings?.statuslineMode ?? DEFAULT_STATUSLINE_MODE;
|
|
15085
15253
|
const liveAnimationStyle = liveSettings?.animationStyle ?? "rainbow";
|
|
15086
15254
|
const liveThinkingWord = liveSettings?.thinkingWord ?? "thinking";
|
|
15087
15255
|
const chimeRef = useRef17(chime);
|
|
@@ -15844,7 +16012,7 @@ function usePanelControllers({
|
|
|
15844
16012
|
enhanceEnabled: s2.enhanceEnabled ?? true,
|
|
15845
16013
|
enhanceLanguage: s2.enhanceLanguage ?? "original",
|
|
15846
16014
|
debugStream: s2.debugStream ?? false,
|
|
15847
|
-
statuslineMode: s2.statuslineMode ??
|
|
16015
|
+
statuslineMode: s2.statuslineMode ?? DEFAULT_STATUSLINE_MODE,
|
|
15848
16016
|
reasoningMode: s2.reasoningMode ?? "auto",
|
|
15849
16017
|
reasoningEffort: s2.reasoningEffort ?? "high",
|
|
15850
16018
|
reasoningPreserve: s2.reasoningPreserve ?? false,
|
|
@@ -15856,6 +16024,8 @@ function usePanelControllers({
|
|
|
15856
16024
|
breakerAutoKillResetMs: s2.breakerAutoKillResetMs ?? 6e4,
|
|
15857
16025
|
showModelReasoning: s2.showModelReasoning ?? true,
|
|
15858
16026
|
showAgentSwarmPanel: s2.showAgentSwarmPanel ?? true,
|
|
16027
|
+
showSageMemoryInject: s2.showSageMemoryInject ?? false,
|
|
16028
|
+
sageMemoryInjectThreshold: s2.sageMemoryInjectThreshold ?? 0.85,
|
|
15859
16029
|
readSymbols: s2.readSymbols ?? false
|
|
15860
16030
|
});
|
|
15861
16031
|
}, [getSettings]);
|
|
@@ -16318,6 +16488,7 @@ function usePromptPicker({
|
|
|
16318
16488
|
|
|
16319
16489
|
// src/hooks/use-provider-event-bridge.ts
|
|
16320
16490
|
import { tuiStreamFlushMs } from "@wrongstack/core/utils";
|
|
16491
|
+
import { isFinalTurnStopReason as isFinalTurnStopReason2 } from "@wrongstack/tools/next-steps";
|
|
16321
16492
|
import {
|
|
16322
16493
|
DEFAULT_MIN_IMPORTANCE,
|
|
16323
16494
|
DEFAULT_MIN_SCORE,
|
|
@@ -16433,6 +16604,65 @@ function shortId(node) {
|
|
|
16433
16604
|
return value.length > 22 ? `${value.slice(0, 19)}\u2026` : value;
|
|
16434
16605
|
}
|
|
16435
16606
|
|
|
16607
|
+
// src/tui-memory-counters.ts
|
|
16608
|
+
var counters = {
|
|
16609
|
+
appRenders: 0,
|
|
16610
|
+
providerTextDeltaEvents: 0,
|
|
16611
|
+
providerTextDeltaChars: 0,
|
|
16612
|
+
providerThinkingDeltaEvents: 0,
|
|
16613
|
+
providerThinkingDeltaChars: 0,
|
|
16614
|
+
providerResponses: 0,
|
|
16615
|
+
toolProgressEvents: 0,
|
|
16616
|
+
toolProgressChars: 0,
|
|
16617
|
+
toolExecutedEvents: 0,
|
|
16618
|
+
toolOutputBytes: 0,
|
|
16619
|
+
streamFlushes: 0,
|
|
16620
|
+
historyRetainedEntries: 0,
|
|
16621
|
+
historyGroupedEntries: 0,
|
|
16622
|
+
historyMountedGroups: 0,
|
|
16623
|
+
historyMountedEntries: 0,
|
|
16624
|
+
historyCachedGroups: 0,
|
|
16625
|
+
historyMeasuredGroups: 0,
|
|
16626
|
+
historyViewportRows: 0,
|
|
16627
|
+
historyTotalRows: 0
|
|
16628
|
+
};
|
|
16629
|
+
function add(key, amount = 1) {
|
|
16630
|
+
counters[key] += Number.isFinite(amount) ? Math.max(0, amount) : 0;
|
|
16631
|
+
}
|
|
16632
|
+
function recordTuiAppRender() {
|
|
16633
|
+
add("appRenders");
|
|
16634
|
+
}
|
|
16635
|
+
function recordProviderTextDelta(chars) {
|
|
16636
|
+
add("providerTextDeltaEvents");
|
|
16637
|
+
add("providerTextDeltaChars", chars);
|
|
16638
|
+
}
|
|
16639
|
+
function recordProviderThinkingDelta(chars) {
|
|
16640
|
+
add("providerThinkingDeltaEvents");
|
|
16641
|
+
add("providerThinkingDeltaChars", chars);
|
|
16642
|
+
}
|
|
16643
|
+
function recordProviderResponse() {
|
|
16644
|
+
add("providerResponses");
|
|
16645
|
+
}
|
|
16646
|
+
function recordToolProgress(chars) {
|
|
16647
|
+
add("toolProgressEvents");
|
|
16648
|
+
add("toolProgressChars", chars);
|
|
16649
|
+
}
|
|
16650
|
+
function recordToolExecuted(outputBytes) {
|
|
16651
|
+
add("toolExecutedEvents");
|
|
16652
|
+
add("toolOutputBytes", outputBytes ?? 0);
|
|
16653
|
+
}
|
|
16654
|
+
function recordStreamFlush() {
|
|
16655
|
+
add("streamFlushes");
|
|
16656
|
+
}
|
|
16657
|
+
function setTuiHistoryMemoryGauges(gauges) {
|
|
16658
|
+
for (const [key, value] of Object.entries(gauges)) {
|
|
16659
|
+
counters[key] = Number.isFinite(value) ? Math.max(0, value) : 0;
|
|
16660
|
+
}
|
|
16661
|
+
}
|
|
16662
|
+
function snapshotTuiMemoryCounters() {
|
|
16663
|
+
return { ...counters };
|
|
16664
|
+
}
|
|
16665
|
+
|
|
16436
16666
|
// src/hooks/subagent-history-format.ts
|
|
16437
16667
|
function formatHistoryDuration(ms) {
|
|
16438
16668
|
if (!Number.isFinite(ms) || ms < 0) return "0s";
|
|
@@ -16544,14 +16774,11 @@ function useProviderEventBridge({
|
|
|
16544
16774
|
}
|
|
16545
16775
|
};
|
|
16546
16776
|
const flush = () => {
|
|
16547
|
-
if (pendingDeltaRef.current) {
|
|
16548
|
-
dispatch({ type: "streamDelta", delta: pendingDeltaRef.current });
|
|
16549
|
-
pendingDeltaRef.current = "";
|
|
16550
|
-
}
|
|
16551
16777
|
if (pendingToolStream) {
|
|
16552
16778
|
dispatch({ type: "toolStreamAppend", ...pendingToolStream });
|
|
16553
16779
|
pendingToolStream = null;
|
|
16554
16780
|
}
|
|
16781
|
+
recordStreamFlush();
|
|
16555
16782
|
flushTimerRef.current = null;
|
|
16556
16783
|
};
|
|
16557
16784
|
const scheduleFlush = () => {
|
|
@@ -16560,29 +16787,19 @@ function useProviderEventBridge({
|
|
|
16560
16787
|
const offDelta = events.on("provider.text_delta", (e) => {
|
|
16561
16788
|
if (activeRunGenerationRef.current !== sessionGenerationRef.current) return;
|
|
16562
16789
|
const text = e.text.replace(/\x1b?\[200~|\x1b?\[201~/g, "");
|
|
16790
|
+
recordProviderTextDelta(text.length);
|
|
16563
16791
|
streamingTextRef.current = retainStreamTail(
|
|
16564
16792
|
streamingTextRef.current,
|
|
16565
16793
|
text,
|
|
16566
16794
|
MAX_ASSISTANT_STREAM_RETAINED_CHARS
|
|
16567
16795
|
);
|
|
16568
|
-
pendingDeltaRef.current = retainStreamTail(
|
|
16569
|
-
pendingDeltaRef.current,
|
|
16570
|
-
text,
|
|
16571
|
-
MAX_ASSISTANT_STREAM_RETAINED_CHARS
|
|
16572
|
-
);
|
|
16573
16796
|
appendStreamSegment("assistant", text);
|
|
16574
|
-
scheduleFlush();
|
|
16575
16797
|
});
|
|
16576
16798
|
const offThinking = events.on("provider.thinking_delta", (e) => {
|
|
16577
16799
|
if (activeRunGenerationRef.current !== sessionGenerationRef.current) return;
|
|
16578
16800
|
const text = e.text.replace(/\x1b?\[200~|\x1b?\[201~/g, "");
|
|
16801
|
+
recordProviderThinkingDelta(text.length);
|
|
16579
16802
|
appendStreamSegment("thinking", text);
|
|
16580
|
-
pendingDeltaRef.current = retainStreamTail(
|
|
16581
|
-
pendingDeltaRef.current,
|
|
16582
|
-
text,
|
|
16583
|
-
MAX_ASSISTANT_STREAM_RETAINED_CHARS
|
|
16584
|
-
);
|
|
16585
|
-
scheduleFlush();
|
|
16586
16803
|
});
|
|
16587
16804
|
const offToolStart = events.on("tool.started", (e) => {
|
|
16588
16805
|
dispatch({ type: "toolStarted", id: e.id, name: e.name });
|
|
@@ -16596,11 +16813,16 @@ function useProviderEventBridge({
|
|
|
16596
16813
|
});
|
|
16597
16814
|
const offToolProgress = events.on("tool.progress", (e) => {
|
|
16598
16815
|
if (e.event.type !== "partial_output" || !e.event.text) return;
|
|
16816
|
+
recordToolProgress(e.event.text.length);
|
|
16599
16817
|
const prev = pendingToolStream;
|
|
16600
16818
|
if (prev && prev.toolUseId === e.id) {
|
|
16601
16819
|
pendingToolStream = {
|
|
16602
16820
|
...prev,
|
|
16603
|
-
text:
|
|
16821
|
+
text: retainStreamTail(
|
|
16822
|
+
prev.text,
|
|
16823
|
+
e.event.text,
|
|
16824
|
+
MAX_TOOL_STREAM_RETAINED_CHARS
|
|
16825
|
+
),
|
|
16604
16826
|
startedAt: prev.startedAt
|
|
16605
16827
|
};
|
|
16606
16828
|
} else {
|
|
@@ -16615,6 +16837,7 @@ function useProviderEventBridge({
|
|
|
16615
16837
|
scheduleFlush();
|
|
16616
16838
|
});
|
|
16617
16839
|
const offTool = events.on("tool.executed", (e) => {
|
|
16840
|
+
recordToolExecuted(e.outputBytes);
|
|
16618
16841
|
if (pendingToolStream) {
|
|
16619
16842
|
dispatch({ type: "toolStreamAppend", ...pendingToolStream });
|
|
16620
16843
|
pendingToolStream = null;
|
|
@@ -16674,6 +16897,7 @@ function useProviderEventBridge({
|
|
|
16674
16897
|
});
|
|
16675
16898
|
const offProvResp = events.on("provider.response", (e) => {
|
|
16676
16899
|
if (activeRunGenerationRef.current !== sessionGenerationRef.current) return;
|
|
16900
|
+
recordProviderResponse();
|
|
16677
16901
|
const segments = canonicalStreamSegments(e.content ?? []);
|
|
16678
16902
|
const fallbackText = contentBlocksText(e.content);
|
|
16679
16903
|
streamingTextRef.current = "";
|
|
@@ -16684,14 +16908,18 @@ function useProviderEventBridge({
|
|
|
16684
16908
|
flushTimerRef.current = null;
|
|
16685
16909
|
}
|
|
16686
16910
|
dispatch({ type: "streamReset" });
|
|
16911
|
+
const final = isFinalTurnStopReason2(e.stopReason);
|
|
16687
16912
|
for (const seg of segments) {
|
|
16688
16913
|
if (seg.text.trim()) {
|
|
16689
|
-
dispatch({
|
|
16914
|
+
dispatch({
|
|
16915
|
+
type: "addEntry",
|
|
16916
|
+
entry: seg.kind === "assistant" ? { kind: "assistant", text: seg.text, final } : { kind: "thinking", text: seg.text }
|
|
16917
|
+
});
|
|
16690
16918
|
if (seg.kind === "assistant") assistantCommittedThisRunRef.current = true;
|
|
16691
16919
|
}
|
|
16692
16920
|
}
|
|
16693
16921
|
if (segments.length === 0 && fallbackText.trim()) {
|
|
16694
|
-
dispatch({ type: "addEntry", entry: { kind: "assistant", text: fallbackText } });
|
|
16922
|
+
dispatch({ type: "addEntry", entry: { kind: "assistant", text: fallbackText, final } });
|
|
16695
16923
|
assistantCommittedThisRunRef.current = true;
|
|
16696
16924
|
}
|
|
16697
16925
|
});
|
|
@@ -16753,18 +16981,21 @@ function useProviderEventBridge({
|
|
|
16753
16981
|
});
|
|
16754
16982
|
});
|
|
16755
16983
|
const offMemoryStale = events.on("memory.staled", (e) => {
|
|
16984
|
+
if (!memoryEventMatchesSession(e, agent.ctx.session.id)) return;
|
|
16756
16985
|
dispatch({
|
|
16757
16986
|
type: "addEntry",
|
|
16758
16987
|
entry: { kind: "warn", text: `SAGE stale: ${e.memoryId} \u2014 ${e.reason}` }
|
|
16759
16988
|
});
|
|
16760
16989
|
});
|
|
16761
16990
|
const offMemoryContradicted = events.on("memory.contradicted", (e) => {
|
|
16991
|
+
if (!memoryEventMatchesSession(e, agent.ctx.session.id)) return;
|
|
16762
16992
|
dispatch({
|
|
16763
16993
|
type: "addEntry",
|
|
16764
16994
|
entry: { kind: "warn", text: `SAGE contradicted: ${e.memoryId}` }
|
|
16765
16995
|
});
|
|
16766
16996
|
});
|
|
16767
16997
|
const offMemoryHygiene = events.on("memory.hygiene_completed", (e) => {
|
|
16998
|
+
if (!memoryEventMatchesSession(e, agent.ctx.session.id)) return;
|
|
16768
16999
|
dispatch({
|
|
16769
17000
|
type: "addEntry",
|
|
16770
17001
|
entry: {
|
|
@@ -16828,6 +17059,7 @@ function useProviderEventBridge({
|
|
|
16828
17059
|
pendingSageStats.clear();
|
|
16829
17060
|
});
|
|
16830
17061
|
const offMemoryLifecycle = events.onPattern("memory.*", (event, payload) => {
|
|
17062
|
+
if (!memoryEventMatchesSession(payload, agent.ctx.session.id)) return;
|
|
16831
17063
|
const lifecycle = memoryLifecycleEntry(event, payload);
|
|
16832
17064
|
if (!lifecycle) return;
|
|
16833
17065
|
dispatch({ type: "addEntry", entry: { kind: "memory-lifecycle", ...lifecycle } });
|
|
@@ -17266,6 +17498,8 @@ function useSettingsAutoSave(state, saveSettings, dispatch) {
|
|
|
17266
17498
|
breakerAutoKillResetMs: sp.breakerAutoKillResetMs,
|
|
17267
17499
|
showModelReasoning: sp.showModelReasoning,
|
|
17268
17500
|
showAgentSwarmPanel: sp.showAgentSwarmPanel,
|
|
17501
|
+
showSageMemoryInject: sp.showSageMemoryInject,
|
|
17502
|
+
sageMemoryInjectThreshold: sp.sageMemoryInjectThreshold,
|
|
17269
17503
|
readSymbols: sp.readSymbols
|
|
17270
17504
|
})
|
|
17271
17505
|
).then((err) => {
|
|
@@ -17315,6 +17549,8 @@ function useSettingsAutoSave(state, saveSettings, dispatch) {
|
|
|
17315
17549
|
state.settingsPicker.breakerAutoKillResetMs,
|
|
17316
17550
|
state.settingsPicker.showModelReasoning,
|
|
17317
17551
|
state.settingsPicker.showAgentSwarmPanel,
|
|
17552
|
+
state.settingsPicker.showSageMemoryInject,
|
|
17553
|
+
state.settingsPicker.sageMemoryInjectThreshold,
|
|
17318
17554
|
state.settingsPicker.readSymbols,
|
|
17319
17555
|
saveSettings
|
|
17320
17556
|
]);
|
|
@@ -17648,6 +17884,8 @@ function useStatusbarViewModel({
|
|
|
17648
17884
|
clearInterval(id);
|
|
17649
17885
|
};
|
|
17650
17886
|
}, [taskPath]);
|
|
17887
|
+
const providerMaxTools = agent.ctx.provider.maxToolsCount ?? 0;
|
|
17888
|
+
const droppedTools = providerMaxTools > 0 ? Math.max(0, (agent.ctx.tools?.length ?? 0) - providerMaxTools) : 0;
|
|
17651
17889
|
return {
|
|
17652
17890
|
contextBreakdown,
|
|
17653
17891
|
currentContextTokens,
|
|
@@ -17658,7 +17896,8 @@ function useStatusbarViewModel({
|
|
|
17658
17896
|
hasVisibleFleetPanel,
|
|
17659
17897
|
entriesWithLeader,
|
|
17660
17898
|
planCounts,
|
|
17661
|
-
taskCounts
|
|
17899
|
+
taskCounts,
|
|
17900
|
+
droppedTools
|
|
17662
17901
|
};
|
|
17663
17902
|
}
|
|
17664
17903
|
|
|
@@ -17949,131 +18188,12 @@ import { useCallback as useCallback18, useEffect as useEffect39, useMemo as useM
|
|
|
17949
18188
|
import * as os from "node:os";
|
|
17950
18189
|
|
|
17951
18190
|
// src/heap-watchdog.ts
|
|
17952
|
-
import
|
|
17953
|
-
|
|
17954
|
-
|
|
17955
|
-
|
|
17956
|
-
|
|
17957
|
-
|
|
17958
|
-
return path5.join(wstackGlobalRoot(), "logs", "heap.jsonl");
|
|
17959
|
-
}
|
|
17960
|
-
function takeHeapSample() {
|
|
17961
|
-
const m = process.memoryUsage();
|
|
17962
|
-
const limit = v8.getHeapStatistics().heap_size_limit || 0;
|
|
17963
|
-
return {
|
|
17964
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17965
|
-
rss: m.rss,
|
|
17966
|
-
heapUsed: m.heapUsed,
|
|
17967
|
-
heapTotal: m.heapTotal,
|
|
17968
|
-
external: m.external,
|
|
17969
|
-
heapLimit: limit,
|
|
17970
|
-
load: limit > 0 ? m.heapUsed / limit : 0
|
|
17971
|
-
};
|
|
17972
|
-
}
|
|
17973
|
-
function startHeapWatchdog(opts = {}) {
|
|
17974
|
-
const sampleEveryMs = opts.sampleEveryMs ?? 6e4;
|
|
17975
|
-
const logEveryMs = opts.logEveryMs ?? 3e5;
|
|
17976
|
-
const logPath = opts.logPath ?? defaultHeapLogPath();
|
|
17977
|
-
const warnAt = opts.warnAt ?? 0.6;
|
|
17978
|
-
const criticalAt = opts.criticalAt ?? 0.85;
|
|
17979
|
-
const REARM_MARGIN = 0.05;
|
|
17980
|
-
let warnArmed = true;
|
|
17981
|
-
let criticalArmed = true;
|
|
17982
|
-
let lastLogAt = 0;
|
|
17983
|
-
let writeInFlight = false;
|
|
17984
|
-
let pendingLine;
|
|
17985
|
-
let drainPromise;
|
|
17986
|
-
let stopped = false;
|
|
17987
|
-
let dirReady = false;
|
|
17988
|
-
const writeDiagnosticLine = opts.writeDiagnosticLine ?? (async (targetPath, line) => {
|
|
17989
|
-
if (!dirReady) {
|
|
17990
|
-
await fsp.mkdir(path5.dirname(targetPath), { recursive: true });
|
|
17991
|
-
dirReady = true;
|
|
17992
|
-
}
|
|
17993
|
-
await fsp.appendFile(targetPath, `${line}
|
|
17994
|
-
`, "utf8");
|
|
17995
|
-
});
|
|
17996
|
-
const drainWrites = async (firstLine) => {
|
|
17997
|
-
let line = firstLine;
|
|
17998
|
-
while (line !== void 0) {
|
|
17999
|
-
try {
|
|
18000
|
-
await writeDiagnosticLine(logPath, line);
|
|
18001
|
-
} catch {
|
|
18002
|
-
}
|
|
18003
|
-
line = pendingLine;
|
|
18004
|
-
pendingLine = void 0;
|
|
18005
|
-
}
|
|
18006
|
-
writeInFlight = false;
|
|
18007
|
-
};
|
|
18008
|
-
const append = (line) => {
|
|
18009
|
-
if (stopped) return;
|
|
18010
|
-
if (writeInFlight) {
|
|
18011
|
-
pendingLine = line;
|
|
18012
|
-
return;
|
|
18013
|
-
}
|
|
18014
|
-
writeInFlight = true;
|
|
18015
|
-
drainPromise = drainWrites(line);
|
|
18016
|
-
};
|
|
18017
|
-
const tick = () => {
|
|
18018
|
-
let userTimings = 0;
|
|
18019
|
-
try {
|
|
18020
|
-
userTimings = performance.getEntriesByType("mark").length + performance.getEntriesByType("measure").length;
|
|
18021
|
-
if (userTimings > 0) {
|
|
18022
|
-
performance.clearMarks();
|
|
18023
|
-
performance.clearMeasures();
|
|
18024
|
-
}
|
|
18025
|
-
} catch {
|
|
18026
|
-
}
|
|
18027
|
-
const s2 = takeHeapSample();
|
|
18028
|
-
if (s2.load >= criticalAt && criticalArmed) {
|
|
18029
|
-
criticalArmed = false;
|
|
18030
|
-
warnArmed = false;
|
|
18031
|
-
opts.onWarn?.(
|
|
18032
|
-
"critical",
|
|
18033
|
-
`Heap critical: ${Math.round(s2.heapUsed / MB)} MB of ~${Math.round(s2.heapLimit / MB)} MB V8 limit (${Math.round(s2.load * 100)}%). An out-of-memory crash is likely soon \u2014 finish/checkpoint work and restart the session. Diagnostics: ${logPath}`,
|
|
18034
|
-
s2
|
|
18035
|
-
);
|
|
18036
|
-
} else if (s2.load >= warnAt && warnArmed) {
|
|
18037
|
-
warnArmed = false;
|
|
18038
|
-
opts.onWarn?.(
|
|
18039
|
-
"warn",
|
|
18040
|
-
`Heap high: ${Math.round(s2.heapUsed / MB)} MB of ~${Math.round(s2.heapLimit / MB)} MB V8 limit (${Math.round(s2.load * 100)}%). Memory diagnostics are being recorded to ${logPath}`,
|
|
18041
|
-
s2
|
|
18042
|
-
);
|
|
18043
|
-
}
|
|
18044
|
-
if (!warnArmed && s2.load < warnAt - REARM_MARGIN) warnArmed = true;
|
|
18045
|
-
if (!criticalArmed && s2.load < criticalAt - REARM_MARGIN) criticalArmed = true;
|
|
18046
|
-
const due = Date.now() - lastLogAt >= logEveryMs;
|
|
18047
|
-
const crossed = s2.load >= warnAt;
|
|
18048
|
-
if (due || crossed) {
|
|
18049
|
-
lastLogAt = Date.now();
|
|
18050
|
-
let extras = {};
|
|
18051
|
-
try {
|
|
18052
|
-
extras = opts.collectStats?.() ?? {};
|
|
18053
|
-
} catch {
|
|
18054
|
-
}
|
|
18055
|
-
append(JSON.stringify({ pid: process.pid, ...s2, userTimings, ...extras }));
|
|
18056
|
-
}
|
|
18057
|
-
};
|
|
18058
|
-
const timer = setInterval(tick, sampleEveryMs);
|
|
18059
|
-
timer.unref?.();
|
|
18060
|
-
tick();
|
|
18061
|
-
if (process.env["NODE_ENV"] !== "production") {
|
|
18062
|
-
append(
|
|
18063
|
-
JSON.stringify({
|
|
18064
|
-
pid: process.pid,
|
|
18065
|
-
warn: "dev_reconciler",
|
|
18066
|
-
nodeEnv: process.env["NODE_ENV"] ?? "",
|
|
18067
|
-
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
18068
|
-
})
|
|
18069
|
-
);
|
|
18070
|
-
}
|
|
18071
|
-
return async () => {
|
|
18072
|
-
stopped = true;
|
|
18073
|
-
clearInterval(timer);
|
|
18074
|
-
await drainPromise;
|
|
18075
|
-
};
|
|
18076
|
-
}
|
|
18191
|
+
import {
|
|
18192
|
+
defaultHeapLogPath,
|
|
18193
|
+
startHeapWatchdog,
|
|
18194
|
+
startSharedHeapWatchdog,
|
|
18195
|
+
takeHeapSample
|
|
18196
|
+
} from "@wrongstack/core/utils";
|
|
18077
18197
|
|
|
18078
18198
|
// src/hooks/use-tui-activity.ts
|
|
18079
18199
|
function attachmentsSize(store) {
|
|
@@ -18102,6 +18222,7 @@ function useTuiActivity({
|
|
|
18102
18222
|
attachments,
|
|
18103
18223
|
builderRef
|
|
18104
18224
|
}) {
|
|
18225
|
+
recordTuiAppRender();
|
|
18105
18226
|
const [rolledThinkingWord, setRolledThinkingWord] = useState17(() => pickRandomTuiThinkingWord());
|
|
18106
18227
|
const thinkingWorking = status === "running" || status === "streaming";
|
|
18107
18228
|
const prevThinkingWorkingRef = useRef28(false);
|
|
@@ -18178,30 +18299,38 @@ function useTuiActivity({
|
|
|
18178
18299
|
return Math.min(100, Math.round(cpuDeltaUsec / 1e3 / wallMs / CPU_CORES * 100));
|
|
18179
18300
|
}, [nowTick]);
|
|
18180
18301
|
useEffect39(() => {
|
|
18181
|
-
const stopHeapWatchdog =
|
|
18182
|
-
collectStats: () =>
|
|
18183
|
-
|
|
18184
|
-
|
|
18185
|
-
|
|
18186
|
-
|
|
18187
|
-
|
|
18188
|
-
|
|
18189
|
-
|
|
18190
|
-
|
|
18191
|
-
|
|
18192
|
-
|
|
18193
|
-
|
|
18194
|
-
|
|
18195
|
-
|
|
18196
|
-
|
|
18197
|
-
|
|
18198
|
-
|
|
18199
|
-
|
|
18200
|
-
|
|
18201
|
-
|
|
18202
|
-
|
|
18203
|
-
|
|
18204
|
-
|
|
18302
|
+
const stopHeapWatchdog = startSharedHeapWatchdog({
|
|
18303
|
+
collectStats: () => {
|
|
18304
|
+
const currentState = stateRef.current;
|
|
18305
|
+
const messages = agentContext.state.messages;
|
|
18306
|
+
return {
|
|
18307
|
+
surface: "tui",
|
|
18308
|
+
sessionId: agentContext.session.id,
|
|
18309
|
+
// Keep this slice to shallow cardinalities: serializing the full
|
|
18310
|
+
// retained graphs created a second allocation spike precisely when
|
|
18311
|
+
// the heap was already high.
|
|
18312
|
+
historyEntries: currentState.entries.length,
|
|
18313
|
+
messages: messages.length,
|
|
18314
|
+
runningTools: currentState.runningTools.size,
|
|
18315
|
+
stdoutQueued: process.stdout.writableLength ?? 0,
|
|
18316
|
+
fleetSize: Object.keys(currentState.fleet ?? {}).length,
|
|
18317
|
+
queued: currentState.queue?.length ?? 0,
|
|
18318
|
+
inputHistory: currentState.inputHistory?.length ?? 0,
|
|
18319
|
+
toolStreamChars: currentState.toolStream?.text.length ?? 0,
|
|
18320
|
+
...snapshotTuiMemoryCounters(),
|
|
18321
|
+
// RAM retention sentinels — distinguish which layer holds old graphs
|
|
18322
|
+
// after /clear so we know where to add cleanup wiring.
|
|
18323
|
+
// attachments: DefaultAttachmentStore.items.size (cumulative
|
|
18324
|
+
// pastes/files/images for the lifetime of this process).
|
|
18325
|
+
// builderRefs: InputBuilder.refs.length (refs retained by the
|
|
18326
|
+
// mounted builder until reset() is called).
|
|
18327
|
+
// directorInFlight: coordinator in-flight task count, used to
|
|
18328
|
+
// detect that `/clear` did not actually drain subagent work.
|
|
18329
|
+
attachments: attachmentsSize(attachments),
|
|
18330
|
+
builderRefs: builderRefsLength(builderRef.current),
|
|
18331
|
+
directorInFlight: directorInFlight(agentContext)
|
|
18332
|
+
};
|
|
18333
|
+
},
|
|
18205
18334
|
onWarn: (level, message) => {
|
|
18206
18335
|
dispatch({
|
|
18207
18336
|
type: "addEntry",
|
|
@@ -19074,9 +19203,7 @@ import {
|
|
|
19074
19203
|
setDesignOverrides
|
|
19075
19204
|
} from "@wrongstack/core/design";
|
|
19076
19205
|
import { toErrorMessage as toErrorMessage8 } from "@wrongstack/core/utils";
|
|
19077
|
-
import {
|
|
19078
|
-
useEffect as useEffect44
|
|
19079
|
-
} from "react";
|
|
19206
|
+
import { useEffect as useEffect44 } from "react";
|
|
19080
19207
|
|
|
19081
19208
|
// src/components/autonomy-picker.tsx
|
|
19082
19209
|
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
@@ -19241,7 +19368,9 @@ function useTuiSlashCommands({
|
|
|
19241
19368
|
motion: pairs["motion"]
|
|
19242
19369
|
});
|
|
19243
19370
|
if (Object.keys(patch).length === 0) {
|
|
19244
|
-
return {
|
|
19371
|
+
return {
|
|
19372
|
+
message: 'Usage: /design tune radius=lg density=compact font="\u2026" motion=snappy'
|
|
19373
|
+
};
|
|
19245
19374
|
}
|
|
19246
19375
|
const merged = await recordOverrides(projectRoot, patch, (/* @__PURE__ */ new Date()).toISOString());
|
|
19247
19376
|
if (!merged) return { message: "No active kit. Pin one first: /design <kit-id>." };
|
|
@@ -19283,12 +19412,18 @@ ${menu}` };
|
|
|
19283
19412
|
kitId: active.kit,
|
|
19284
19413
|
outPath
|
|
19285
19414
|
});
|
|
19286
|
-
const
|
|
19415
|
+
const fsp = await import("node:fs/promises");
|
|
19287
19416
|
const nodePath = await import("node:path");
|
|
19288
|
-
const
|
|
19417
|
+
const { resolveMaterializeTarget } = await import("@wrongstack/core/design");
|
|
19418
|
+
let abs;
|
|
19289
19419
|
try {
|
|
19290
|
-
await
|
|
19291
|
-
|
|
19420
|
+
abs = await resolveMaterializeTarget(result.path, projectRoot);
|
|
19421
|
+
} catch (e) {
|
|
19422
|
+
return { message: e.message };
|
|
19423
|
+
}
|
|
19424
|
+
try {
|
|
19425
|
+
await fsp.mkdir(nodePath.dirname(abs), { recursive: true });
|
|
19426
|
+
await fsp.writeFile(abs, result.content);
|
|
19292
19427
|
} catch (e) {
|
|
19293
19428
|
return { message: `Failed to write ${result.path}: ${e.message}` };
|
|
19294
19429
|
}
|
|
@@ -19562,11 +19697,11 @@ Available chords:
|
|
|
19562
19697
|
}
|
|
19563
19698
|
|
|
19564
19699
|
// src/hooks/use-working-dir-chip.ts
|
|
19565
|
-
import * as
|
|
19700
|
+
import * as path5 from "node:path";
|
|
19566
19701
|
import { useEffect as useEffect45, useState as useState18 } from "react";
|
|
19567
19702
|
function formatWorkingDirChip(workingDir, projectRoot) {
|
|
19568
19703
|
if (!workingDir || workingDir === projectRoot) return void 0;
|
|
19569
|
-
const impl = workingDir.includes("\\") || projectRoot.includes("\\") ?
|
|
19704
|
+
const impl = workingDir.includes("\\") || projectRoot.includes("\\") ? path5.win32 : path5;
|
|
19570
19705
|
const rel = impl.relative(projectRoot, workingDir) || ".";
|
|
19571
19706
|
if (rel === ".") return void 0;
|
|
19572
19707
|
return rel.replaceAll(impl.sep, "/");
|
|
@@ -22642,7 +22777,7 @@ function KanbanPanel({
|
|
|
22642
22777
|
/* @__PURE__ */ jsx24(Text, { dimColor: true, children: "|" }),
|
|
22643
22778
|
/* @__PURE__ */ jsx24(Text, { children: board.title })
|
|
22644
22779
|
] }) : null,
|
|
22645
|
-
/* @__PURE__ */ jsx24(Text, { dimColor: true, children: "| n/p board | Tab task | \u2190\u2192 move | c/a/d create/add/dup | C/T copy/transfer | Ctrl+
|
|
22780
|
+
/* @__PURE__ */ jsx24(Text, { dimColor: true, children: "| n/p board | Tab task | \u2190\u2192 move | c/a/d create/add/dup | C/T copy/transfer | Ctrl+Y toggle | Esc close" })
|
|
22646
22781
|
] }),
|
|
22647
22782
|
prompt ? /* @__PURE__ */ jsx24(PromptLine, { prompt }) : null,
|
|
22648
22783
|
notice && !prompt ? /* @__PURE__ */ jsx24(Text, { color: "green", wrap: "truncate", children: notice }) : null,
|
|
@@ -23452,7 +23587,7 @@ function PhasePanel({ phases, nowTick }) {
|
|
|
23452
23587
|
// src/components/plan-panel.tsx
|
|
23453
23588
|
import { useCallback as useCallback22, useEffect as useEffect56, useMemo as useMemo11, useState as useState29 } from "react";
|
|
23454
23589
|
import * as fs4 from "node:fs/promises";
|
|
23455
|
-
import * as
|
|
23590
|
+
import * as path6 from "node:path";
|
|
23456
23591
|
import { resolveWstackPaths as resolveWstackPaths4, sessionScopedPath } from "@wrongstack/core/utils";
|
|
23457
23592
|
import { jsx as jsx29, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
23458
23593
|
var STATUS_COLOR = {
|
|
@@ -23468,12 +23603,12 @@ var STATUS_ICON = {
|
|
|
23468
23603
|
function planFilePath(projectRoot, sessionId, scope) {
|
|
23469
23604
|
const base = resolveWstackPaths4({ projectRoot }).projectSessions;
|
|
23470
23605
|
if (scope === "project") {
|
|
23471
|
-
return
|
|
23606
|
+
return path6.join(base, "backlog.plan.json");
|
|
23472
23607
|
}
|
|
23473
23608
|
if (sessionId) {
|
|
23474
23609
|
return sessionScopedPath(base, sessionId, ".plan.json");
|
|
23475
23610
|
}
|
|
23476
|
-
return
|
|
23611
|
+
return path6.join(base, "backlog.plan.json");
|
|
23477
23612
|
}
|
|
23478
23613
|
function PlanPanel({
|
|
23479
23614
|
projectRoot,
|
|
@@ -24752,6 +24887,8 @@ function AppStatusRegion({ host, runtime }) {
|
|
|
24752
24887
|
agent,
|
|
24753
24888
|
agentTranscripts,
|
|
24754
24889
|
appVersion,
|
|
24890
|
+
latestVersion,
|
|
24891
|
+
updateAvailable,
|
|
24755
24892
|
director,
|
|
24756
24893
|
events,
|
|
24757
24894
|
fleetRoster,
|
|
@@ -24821,7 +24958,8 @@ function AppStatusRegion({ host, runtime }) {
|
|
|
24821
24958
|
hasVisibleFleetPanel,
|
|
24822
24959
|
entriesWithLeader,
|
|
24823
24960
|
planCounts,
|
|
24824
|
-
taskCounts
|
|
24961
|
+
taskCounts,
|
|
24962
|
+
droppedTools
|
|
24825
24963
|
} = statusbar;
|
|
24826
24964
|
const { mailboxStatus, mailboxPanelOpen, mailboxMessages, mailboxAgents } = mailbox;
|
|
24827
24965
|
const { lowerFunctionPanelOpen } = viewState;
|
|
@@ -24833,6 +24971,8 @@ function AppStatusRegion({ host, runtime }) {
|
|
|
24833
24971
|
provider: liveProvider,
|
|
24834
24972
|
model: liveModel,
|
|
24835
24973
|
version: appVersion,
|
|
24974
|
+
latestVersion,
|
|
24975
|
+
updateAvailable,
|
|
24836
24976
|
state: state.status,
|
|
24837
24977
|
thinkingWord: displayThinkingWord,
|
|
24838
24978
|
thinkingAnimationStyle: (
|
|
@@ -24847,6 +24987,7 @@ function AppStatusRegion({ host, runtime }) {
|
|
|
24847
24987
|
queueCount: state.queue.length,
|
|
24848
24988
|
yolo: yoloLive,
|
|
24849
24989
|
autonomy: autonomyLive,
|
|
24990
|
+
droppedTools,
|
|
24850
24991
|
startedAt,
|
|
24851
24992
|
fleetWorkingTime: fleetWorkingTimeMs,
|
|
24852
24993
|
todos,
|
|
@@ -25232,6 +25373,17 @@ var OAUTH_LABEL = {
|
|
|
25232
25373
|
claude: { title: "Claude Pro/Max", detail: "\u2192 anthropic-oauth" },
|
|
25233
25374
|
copilot: { title: "GitHub Copilot", detail: "\u2192 github-copilot" }
|
|
25234
25375
|
};
|
|
25376
|
+
function formatExpiry(expiresAt) {
|
|
25377
|
+
if (!expiresAt) return null;
|
|
25378
|
+
const expiry = Date.parse(expiresAt);
|
|
25379
|
+
if (!Number.isFinite(expiry)) return null;
|
|
25380
|
+
const now = Date.now();
|
|
25381
|
+
const msLeft = expiry - now;
|
|
25382
|
+
if (msLeft <= 0) return { text: "expired", color: UI_COLORS.error };
|
|
25383
|
+
if (msLeft < 60 * 6e4) return { text: `${Math.round(msLeft / 6e4)}m left`, color: UI_COLORS.error };
|
|
25384
|
+
if (msLeft < 24 * 60 * 6e4) return { text: `${Math.round(msLeft / (60 * 6e4))}h left`, color: UI_COLORS.warning };
|
|
25385
|
+
return { text: `${Math.round(msLeft / (24 * 60 * 6e4))}d left`, color: UI_COLORS.inactive };
|
|
25386
|
+
}
|
|
25235
25387
|
function keySummary(keyRow) {
|
|
25236
25388
|
const method = keyRow.authMethod === "oauth" ? " oauth" : "";
|
|
25237
25389
|
const created = keyRow.createdAt ? ` ${keyRow.createdAt.slice(0, 10)}` : "";
|
|
@@ -25264,6 +25416,7 @@ function renderRow2(row, focused, i) {
|
|
|
25264
25416
|
case "key": {
|
|
25265
25417
|
const k = row.keyRow;
|
|
25266
25418
|
const badge = badgeForKind(k.authMethod);
|
|
25419
|
+
const expiry = formatExpiry(k.expiresAt);
|
|
25267
25420
|
return /* @__PURE__ */ jsxs38(Text, { color: rowColor, wrap: "truncate-end", children: [
|
|
25268
25421
|
marker,
|
|
25269
25422
|
" ",
|
|
@@ -25272,7 +25425,11 @@ function renderRow2(row, focused, i) {
|
|
|
25272
25425
|
k.label.padEnd(20),
|
|
25273
25426
|
" ",
|
|
25274
25427
|
badge ? /* @__PURE__ */ jsx39(Text, { color: badge.color, children: badge.label.padEnd(8) }) : null,
|
|
25275
|
-
/* @__PURE__ */ jsx39(Text, { dimColor: true, children: keySummary(k) })
|
|
25428
|
+
/* @__PURE__ */ jsx39(Text, { dimColor: true, children: keySummary(k) }),
|
|
25429
|
+
expiry ? /* @__PURE__ */ jsxs38(Text, { color: expiry.color, children: [
|
|
25430
|
+
" ",
|
|
25431
|
+
expiry.text
|
|
25432
|
+
] }) : null
|
|
25276
25433
|
] }, `k-${k.label}`);
|
|
25277
25434
|
}
|
|
25278
25435
|
case "provider-action":
|
|
@@ -25971,7 +26128,7 @@ function ClearConfirmPanel({
|
|
|
25971
26128
|
}
|
|
25972
26129
|
|
|
25973
26130
|
// src/components/confirm-prompt.tsx
|
|
25974
|
-
import { writeOut as writeOut2 } from "@wrongstack/core/utils";
|
|
26131
|
+
import { unifiedDiff, writeOut as writeOut2 } from "@wrongstack/core/utils";
|
|
25975
26132
|
import React6 from "react";
|
|
25976
26133
|
|
|
25977
26134
|
// src/highlight.ts
|
|
@@ -26413,8 +26570,8 @@ function detectLang(fenceInfo) {
|
|
|
26413
26570
|
const tag = fenceInfo.trim().toLowerCase().split(/\s+/)[0] ?? "";
|
|
26414
26571
|
return LANG_ALIASES[tag] ?? "plain";
|
|
26415
26572
|
}
|
|
26416
|
-
function langFromPath(
|
|
26417
|
-
const m = /\.([A-Za-z0-9]+)$/.exec(
|
|
26573
|
+
function langFromPath(path10) {
|
|
26574
|
+
const m = /\.([A-Za-z0-9]+)$/.exec(path10.trim());
|
|
26418
26575
|
const ext = m?.[1]?.toLowerCase() ?? "";
|
|
26419
26576
|
return LANG_ALIASES[ext] ?? "plain";
|
|
26420
26577
|
}
|
|
@@ -27726,19 +27883,19 @@ function formatToolArgs(toolName, input) {
|
|
|
27726
27883
|
case "codebase-stats":
|
|
27727
27884
|
return "index health";
|
|
27728
27885
|
case "lsp_diagnostics": {
|
|
27729
|
-
const
|
|
27886
|
+
const path10 = stringOf(obj["path"]);
|
|
27730
27887
|
const severity = stringArrayOf(obj["severity"]) ?? stringArrayOf(obj["severities"]);
|
|
27731
|
-
return [
|
|
27888
|
+
return [path10 ? shortenPath(path10, 40) : "workspace", severity?.join("+")].filter(Boolean).join(" \xB7 ");
|
|
27732
27889
|
}
|
|
27733
27890
|
case "lsp_definition":
|
|
27734
27891
|
case "lsp_completion":
|
|
27735
27892
|
case "lsp_rename": {
|
|
27736
|
-
const
|
|
27893
|
+
const path10 = stringOf(obj["path"]) ?? stringOf(obj["file"]);
|
|
27737
27894
|
const line = numOf(obj["line"]);
|
|
27738
27895
|
const character = numOf(obj["character"]);
|
|
27739
27896
|
const position = line !== void 0 ? `L${line}:${character ?? 1}` : "";
|
|
27740
27897
|
const rename = toolName === "lsp_rename" ? stringOf(obj["new_name"]) : void 0;
|
|
27741
|
-
return [
|
|
27898
|
+
return [path10 ? shortenPath(path10, 38) : "", position, rename ? `\u2192 ${rename}` : ""].filter(Boolean).join(" \xB7 ");
|
|
27742
27899
|
}
|
|
27743
27900
|
case "set_working_dir": {
|
|
27744
27901
|
const p = stringOf(obj["path"]);
|
|
@@ -28181,19 +28338,19 @@ function visualEdit(toolName, text, ok) {
|
|
|
28181
28338
|
const parsed = tryParseJson(text);
|
|
28182
28339
|
if (parsed && typeof parsed === "object") {
|
|
28183
28340
|
const obj = parsed;
|
|
28184
|
-
const
|
|
28341
|
+
const path10 = typeof obj["path"] === "string" ? obj["path"] : void 0;
|
|
28185
28342
|
const replacements = typeof obj["replacements"] === "number" ? obj["replacements"] : void 0;
|
|
28186
28343
|
const bytes = typeof obj["bytes"] === "number" ? obj["bytes"] : void 0;
|
|
28187
28344
|
const created = obj["created"] === true;
|
|
28188
28345
|
const files = Array.isArray(obj["files"]) ? obj["files"] : void 0;
|
|
28189
28346
|
const results = Array.isArray(obj["results"]) ? obj["results"] : void 0;
|
|
28190
|
-
if (toolName === "edit" &&
|
|
28347
|
+
if (toolName === "edit" && path10 !== void 0) {
|
|
28191
28348
|
const repText = replacements !== void 0 ? `${replacements} replacement${replacements === 1 ? "" : "s"}` : void 0;
|
|
28192
|
-
rows.push({ kind: "ok", text: "", marker: "edit ", path:
|
|
28349
|
+
rows.push({ kind: "ok", text: "", marker: "edit ", path: path10 });
|
|
28193
28350
|
if (repText) rows.push({ kind: "meta", text: repText });
|
|
28194
|
-
} else if (toolName === "write" &&
|
|
28351
|
+
} else if (toolName === "write" && path10 !== void 0) {
|
|
28195
28352
|
const sizeText = bytes !== void 0 ? `${bytes} bytes` : created ? "new file" : "updated";
|
|
28196
|
-
rows.push({ kind: "ok", text: "", marker: "write ", path:
|
|
28353
|
+
rows.push({ kind: "ok", text: "", marker: "write ", path: path10 });
|
|
28197
28354
|
rows.push({ kind: "meta", text: sizeText });
|
|
28198
28355
|
} else if ((toolName === "diff" || toolName === "patch") && files && files.length > 0) {
|
|
28199
28356
|
rows.push({
|
|
@@ -28216,8 +28373,8 @@ function visualEdit(toolName, text, ok) {
|
|
|
28216
28373
|
marker: "replace ",
|
|
28217
28374
|
text: `${results.length} replacement${results.length === 1 ? "" : "s"} across ${fileCount} file${fileCount === 1 ? "" : "s"}`
|
|
28218
28375
|
});
|
|
28219
|
-
} else if (
|
|
28220
|
-
rows.push({ kind: "ok", text: "", marker: `${toolName} `, path:
|
|
28376
|
+
} else if (path10 !== void 0) {
|
|
28377
|
+
rows.push({ kind: "ok", text: "", marker: `${toolName} `, path: path10 });
|
|
28221
28378
|
} else {
|
|
28222
28379
|
return void 0;
|
|
28223
28380
|
}
|
|
@@ -28311,12 +28468,12 @@ function parseMatchHit(hit) {
|
|
|
28311
28468
|
}
|
|
28312
28469
|
if (hit && typeof hit === "object") {
|
|
28313
28470
|
const o = hit;
|
|
28314
|
-
const
|
|
28471
|
+
const path10 = stringOf(o["file"]) ?? stringOf(o["path"]) ?? stringOf(o["url"]);
|
|
28315
28472
|
const line = numOf(o["line"]) ?? numOf(o["lineNumber"]);
|
|
28316
28473
|
const title = stringOf(o["title"]);
|
|
28317
28474
|
const snippet2 = stringOf(o["snippet"]);
|
|
28318
28475
|
const text = stringOf(o["text"]) ?? stringOf(o["match"]) ?? stringOf(o["preview"]) ?? [title, snippet2].filter(Boolean).join(" \u2014 ");
|
|
28319
|
-
return { path:
|
|
28476
|
+
return { path: path10, line: line === void 0 ? void 0 : String(line), text };
|
|
28320
28477
|
}
|
|
28321
28478
|
return void 0;
|
|
28322
28479
|
}
|
|
@@ -28414,8 +28571,8 @@ function splitReplaceDiffs(obj) {
|
|
|
28414
28571
|
const record = result;
|
|
28415
28572
|
const diff = stringOf(record["diff"]);
|
|
28416
28573
|
if (!diff?.trim()) continue;
|
|
28417
|
-
const
|
|
28418
|
-
items.push(
|
|
28574
|
+
const path10 = stringOf(record["path"]);
|
|
28575
|
+
items.push(path10 ? { path: path10, diff } : { diff });
|
|
28419
28576
|
}
|
|
28420
28577
|
return items;
|
|
28421
28578
|
}
|
|
@@ -28490,8 +28647,8 @@ function collectMultiFileDiffItems(toolName, output, _input) {
|
|
|
28490
28647
|
if (!diffText?.trim()) return void 0;
|
|
28491
28648
|
const blocks = splitGitStyleDiff(diffText);
|
|
28492
28649
|
if (blocks.length === 0) {
|
|
28493
|
-
const
|
|
28494
|
-
return [{ path:
|
|
28650
|
+
const path10 = explicitFiles[0] ?? extractPatchHeaderPath(diffText);
|
|
28651
|
+
return [{ path: path10, diff: diffText }];
|
|
28495
28652
|
}
|
|
28496
28653
|
return blocks.map((block, idx) => ({
|
|
28497
28654
|
path: explicitFiles[idx] ?? block.path,
|
|
@@ -28525,9 +28682,9 @@ function newFileDiffFromWriteInput(output, input) {
|
|
|
28525
28682
|
const obj = input;
|
|
28526
28683
|
const content = stringOf(obj["content"]);
|
|
28527
28684
|
if (content === void 0) return void 0;
|
|
28528
|
-
const
|
|
28685
|
+
const path10 = stringOf(output["path"]) ?? stringOf(obj["path"]) ?? "new file";
|
|
28529
28686
|
const lines = content === "" ? [] : content.replace(/\n$/, "").split("\n");
|
|
28530
|
-
const header = [`+++ ${
|
|
28687
|
+
const header = [`+++ ${path10}`, `@@ -0,0 +1,${lines.length} @@`];
|
|
28531
28688
|
return [...header, ...lines.map((line) => `+${line}`)].join("\n");
|
|
28532
28689
|
}
|
|
28533
28690
|
function splitGitStyleDiff(diff) {
|
|
@@ -28567,8 +28724,8 @@ function splitGitStyleDiff(diff) {
|
|
|
28567
28724
|
}
|
|
28568
28725
|
flush();
|
|
28569
28726
|
if (blocks.length === 1 && !blocks[0].path) {
|
|
28570
|
-
const
|
|
28571
|
-
if (
|
|
28727
|
+
const path10 = extractPatchHeaderPath(blocks[0].diff);
|
|
28728
|
+
if (path10) blocks[0] = { path: path10, diff: blocks[0].diff };
|
|
28572
28729
|
}
|
|
28573
28730
|
return blocks;
|
|
28574
28731
|
}
|
|
@@ -28589,8 +28746,8 @@ function parseDiffGitPath(line) {
|
|
|
28589
28746
|
function extractPatchHeaderPath(diffText) {
|
|
28590
28747
|
for (const line of diffText.split("\n")) {
|
|
28591
28748
|
if (line.startsWith("+++ ")) {
|
|
28592
|
-
const
|
|
28593
|
-
const cleaned =
|
|
28749
|
+
const path10 = line.slice(4).trim();
|
|
28750
|
+
const cleaned = path10.replace(/^b\//, "").split(" ")[0].trim();
|
|
28594
28751
|
return cleaned || void 0;
|
|
28595
28752
|
}
|
|
28596
28753
|
}
|
|
@@ -28722,13 +28879,13 @@ function formatMultiDiffSummary(summary, threshold = MULTI_DIFF_SUMMARY_THRESHOL
|
|
|
28722
28879
|
return parts.join(" \xB7 ");
|
|
28723
28880
|
}
|
|
28724
28881
|
function DiffFileBlock({
|
|
28725
|
-
path:
|
|
28882
|
+
path: path10,
|
|
28726
28883
|
preview,
|
|
28727
28884
|
useColor = true,
|
|
28728
28885
|
contentWidth
|
|
28729
28886
|
}) {
|
|
28730
28887
|
return /* @__PURE__ */ jsxs45(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
28731
|
-
/* @__PURE__ */ jsx46(Text, { dimColor: true, italic: true, children:
|
|
28888
|
+
/* @__PURE__ */ jsx46(Text, { dimColor: true, italic: true, children: path10 }),
|
|
28732
28889
|
/* @__PURE__ */ jsx46(
|
|
28733
28890
|
DiffBlock,
|
|
28734
28891
|
{
|
|
@@ -28739,7 +28896,7 @@ function DiffFileBlock({
|
|
|
28739
28896
|
hiddenAdded: preview.hiddenAdded,
|
|
28740
28897
|
hiddenRemoved: preview.hiddenRemoved,
|
|
28741
28898
|
useColor,
|
|
28742
|
-
lang: langFromPath(
|
|
28899
|
+
lang: langFromPath(path10),
|
|
28743
28900
|
contentWidth
|
|
28744
28901
|
}
|
|
28745
28902
|
)
|
|
@@ -28983,10 +29140,21 @@ function stringifyInput(input) {
|
|
|
28983
29140
|
function truncate2(s2, max) {
|
|
28984
29141
|
return s2.length <= max ? s2 : `${s2.slice(0, max - 1)}\u2026`;
|
|
28985
29142
|
}
|
|
28986
|
-
function
|
|
28987
|
-
return
|
|
28988
|
-
|
|
28989
|
-
|
|
29143
|
+
function payloadDiff(input) {
|
|
29144
|
+
if (!input || typeof input !== "object") return "";
|
|
29145
|
+
const obj = input;
|
|
29146
|
+
const filePath = typeof obj["path"] === "string" ? obj["path"] : "file";
|
|
29147
|
+
if (typeof obj["diff"] === "string" && obj["diff"]) return obj["diff"];
|
|
29148
|
+
const newString = obj["new_string"];
|
|
29149
|
+
if (typeof newString === "string") {
|
|
29150
|
+
const oldString = typeof obj["old_string"] === "string" ? obj["old_string"] : "";
|
|
29151
|
+
return unifiedDiff(oldString, newString, { fromFile: filePath, toFile: filePath, context: 2 });
|
|
29152
|
+
}
|
|
29153
|
+
const content = obj["content"];
|
|
29154
|
+
if (typeof content === "string" && content) {
|
|
29155
|
+
return unifiedDiff("", content, { fromFile: "/dev/null", toFile: filePath, context: 0 });
|
|
29156
|
+
}
|
|
29157
|
+
return "";
|
|
28990
29158
|
}
|
|
28991
29159
|
var CONFIRM_DIFF_MAX_LINES = 20;
|
|
28992
29160
|
function renderDiffLine(line) {
|
|
@@ -28996,7 +29164,7 @@ function renderDiffLine(line) {
|
|
|
28996
29164
|
"\n"
|
|
28997
29165
|
] }, line);
|
|
28998
29166
|
}
|
|
28999
|
-
function renderDiff(diff,
|
|
29167
|
+
function renderDiff(diff, path10) {
|
|
29000
29168
|
const preview = parseUnifiedDiff(diff, CONFIRM_DIFF_MAX_LINES);
|
|
29001
29169
|
if (preview.rows.length > 0) {
|
|
29002
29170
|
return /* @__PURE__ */ jsx47(
|
|
@@ -29009,7 +29177,7 @@ function renderDiff(diff, path11) {
|
|
|
29009
29177
|
hiddenAdded: preview.hiddenAdded,
|
|
29010
29178
|
hiddenRemoved: preview.hiddenRemoved,
|
|
29011
29179
|
useColor: theme.supportsBackground,
|
|
29012
|
-
lang: langFromPath(
|
|
29180
|
+
lang: langFromPath(path10 ?? "")
|
|
29013
29181
|
}
|
|
29014
29182
|
);
|
|
29015
29183
|
}
|
|
@@ -29046,9 +29214,8 @@ function ConfirmPrompt({
|
|
|
29046
29214
|
}
|
|
29047
29215
|
});
|
|
29048
29216
|
const inputSummary = stringifyInput(input);
|
|
29049
|
-
const showDiff = hasDiff(input);
|
|
29050
29217
|
const inp = input;
|
|
29051
|
-
const diff =
|
|
29218
|
+
const diff = payloadDiff(input);
|
|
29052
29219
|
const diffPath = typeof inp?.path === "string" ? inp.path : void 0;
|
|
29053
29220
|
return /* @__PURE__ */ jsxs46(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
29054
29221
|
/* @__PURE__ */ jsxs46(Box, { flexDirection: "row", children: [
|
|
@@ -29061,7 +29228,7 @@ function ConfirmPrompt({
|
|
|
29061
29228
|
"KANBAN BOUNDARY: ",
|
|
29062
29229
|
boundaryReason
|
|
29063
29230
|
] }) : null,
|
|
29064
|
-
|
|
29231
|
+
diff ? /* @__PURE__ */ jsx47(Box, { flexDirection: "column", marginY: 1, children: renderDiff(diff, diffPath) }) : null,
|
|
29065
29232
|
/* @__PURE__ */ jsx47(Text, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" }),
|
|
29066
29233
|
/* @__PURE__ */ jsx47(Box, { flexDirection: "row", children: /* @__PURE__ */ jsx47(Text, { children: buttonLabels(suggestedPattern).map((l) => /* @__PURE__ */ jsxs46(React6.Fragment, { children: [
|
|
29067
29234
|
/* @__PURE__ */ jsx47(Text, { bold: true, color: BUTTON_COLOR[l.decision], children: l.bracket }),
|
|
@@ -30204,8 +30371,8 @@ function FilePicker({ query, matches, selected }) {
|
|
|
30204
30371
|
] }, m))
|
|
30205
30372
|
] });
|
|
30206
30373
|
}
|
|
30207
|
-
function highlight(
|
|
30208
|
-
return
|
|
30374
|
+
function highlight(path10, _query) {
|
|
30375
|
+
return path10;
|
|
30209
30376
|
}
|
|
30210
30377
|
|
|
30211
30378
|
// src/components/help-panel.tsx
|
|
@@ -31553,14 +31720,14 @@ function estimateSageKvRows(cells, contentWidth) {
|
|
|
31553
31720
|
}
|
|
31554
31721
|
return rows;
|
|
31555
31722
|
}
|
|
31556
|
-
function estimateRenderGroupRows(group, contentWidth) {
|
|
31723
|
+
function estimateRenderGroupRows(group, contentWidth, showSageMemoryInject) {
|
|
31557
31724
|
if (group.type === "tool-group") return group.data.entries.length + 2;
|
|
31558
31725
|
const { entry } = group;
|
|
31559
31726
|
if (entry.kind === "tool") {
|
|
31560
31727
|
const { cleanOutput, sageLines } = resolveEntrySage(entry.output, entry.sageLines);
|
|
31561
31728
|
const memoryLines = sageLines.slice(1);
|
|
31562
31729
|
const panelContentWidth = Math.max(16, contentWidth - 4);
|
|
31563
|
-
const sagePanelRows = memoryLines.length
|
|
31730
|
+
const sagePanelRows = showSageMemoryInject === false || memoryLines.length === 0 ? 0 : 2 + estimateTextRows(
|
|
31564
31731
|
`\u{1F9E0} SAGE MEMORY INJECTED \xB7 ${entry.name} ${memoryLines.length} ${memoryLines.length === 1 ? "memory" : "memories"}${entry.sageStats ? ` \xB7 ${entry.sageStats}` : ""}`,
|
|
31565
31732
|
panelContentWidth,
|
|
31566
31733
|
MAX_TEXT_ESTIMATE_ROWS
|
|
@@ -31583,7 +31750,7 @@ function estimateRenderGroupRows(group, contentWidth) {
|
|
|
31583
31750
|
const kvRows = estimateSageKvRows(kvCells, panelContentWidth);
|
|
31584
31751
|
const gap = rows > 0 ? 1 : 0;
|
|
31585
31752
|
return rows + labelRow + bodyRow + kvRows + gap;
|
|
31586
|
-
}, 0)
|
|
31753
|
+
}, 0);
|
|
31587
31754
|
if (entry.resultRenderMode === "simple") return 3 + sagePanelRows;
|
|
31588
31755
|
if (STRUCTURED_DIFF_TOOLS.has(entry.name)) {
|
|
31589
31756
|
const previewCap = entry.name === "replace" || entry.name === "diff" || entry.name === "patch" ? MULTI_DIFF_MAX_ROWS : DIFF_MAX_LINES;
|
|
@@ -32184,6 +32351,39 @@ function parseInline(text) {
|
|
|
32184
32351
|
continue;
|
|
32185
32352
|
}
|
|
32186
32353
|
}
|
|
32354
|
+
if (ch === "[") {
|
|
32355
|
+
const textEnd = text.indexOf("]", i + 1);
|
|
32356
|
+
if (textEnd > i && text[textEnd + 1] === "(") {
|
|
32357
|
+
const urlEnd = text.indexOf(")", textEnd + 2);
|
|
32358
|
+
if (urlEnd > textEnd) {
|
|
32359
|
+
flush();
|
|
32360
|
+
const linkText = text.slice(i + 1, textEnd);
|
|
32361
|
+
tokens.push({ text: linkText, link: true });
|
|
32362
|
+
i = urlEnd + 1;
|
|
32363
|
+
continue;
|
|
32364
|
+
}
|
|
32365
|
+
}
|
|
32366
|
+
}
|
|
32367
|
+
if (text.startsWith("http://", i) || text.startsWith("https://", i)) {
|
|
32368
|
+
let urlEnd = i + 8;
|
|
32369
|
+
while (urlEnd < text.length) {
|
|
32370
|
+
const c = text[urlEnd];
|
|
32371
|
+
if (c !== void 0 && c.match(/[a-zA-Z0-9._~:/?#@!$&+,;=%\-\[\]()'*]/)) {
|
|
32372
|
+
urlEnd++;
|
|
32373
|
+
} else {
|
|
32374
|
+
break;
|
|
32375
|
+
}
|
|
32376
|
+
}
|
|
32377
|
+
const trailing = text.slice(i, urlEnd);
|
|
32378
|
+
const stripped = trailing.replace(/[.,;!?)]+$/, "");
|
|
32379
|
+
urlEnd = i + stripped.length;
|
|
32380
|
+
if (urlEnd > i + 8) {
|
|
32381
|
+
flush();
|
|
32382
|
+
tokens.push({ text: stripped, link: true });
|
|
32383
|
+
i = urlEnd;
|
|
32384
|
+
continue;
|
|
32385
|
+
}
|
|
32386
|
+
}
|
|
32187
32387
|
plain += ch;
|
|
32188
32388
|
i += 1;
|
|
32189
32389
|
}
|
|
@@ -32201,7 +32401,7 @@ function InlineLine({ tokens, dim }) {
|
|
|
32201
32401
|
return /* @__PURE__ */ jsx66(Text, { children: tokens.map((t, j) => /* @__PURE__ */ jsx66(
|
|
32202
32402
|
Text,
|
|
32203
32403
|
{
|
|
32204
|
-
color: t.code ? theme.accent : "white",
|
|
32404
|
+
color: t.code ? theme.accent : t.link ? theme.accent : "white",
|
|
32205
32405
|
bold: Boolean(t.bold),
|
|
32206
32406
|
italic: Boolean(t.italic),
|
|
32207
32407
|
strikethrough: Boolean(t.strike),
|
|
@@ -32358,7 +32558,7 @@ var ASSISTANT_TAIL_HEIGHT = ASSISTANT_TAIL_MARGIN_Y + ASSISTANT_TAIL_HEADER_ROWS
|
|
|
32358
32558
|
|
|
32359
32559
|
// src/components/history/banner.tsx
|
|
32360
32560
|
import { Fragment as Fragment22, jsx as jsx68, jsxs as jsxs66 } from "react/jsx-runtime";
|
|
32361
|
-
var
|
|
32561
|
+
var STACK_ORANGE2 = "#FD9F02";
|
|
32362
32562
|
var SIGNAL_PINK = "#FE2E5F";
|
|
32363
32563
|
var BORDER = "#3B3C36";
|
|
32364
32564
|
var MUTED = "#B6B2A8";
|
|
@@ -32392,7 +32592,7 @@ function BrandMark({ pinkRow = 1 }) {
|
|
|
32392
32592
|
if (column === PINK_HOME && (row === pinkRow || row === pinkRow + 1)) {
|
|
32393
32593
|
return SIGNAL_PINK;
|
|
32394
32594
|
}
|
|
32395
|
-
if (row < 2 && column !== PINK_HOME) return
|
|
32595
|
+
if (row < 2 && column !== PINK_HOME) return STACK_ORANGE2;
|
|
32396
32596
|
return null;
|
|
32397
32597
|
})
|
|
32398
32598
|
);
|
|
@@ -32443,7 +32643,7 @@ var WORDMARK_LINES = Object.freeze(
|
|
|
32443
32643
|
);
|
|
32444
32644
|
function bannerGradientColor(position, length) {
|
|
32445
32645
|
const progress = length > 1 ? position / (length - 1) : 0.5;
|
|
32446
|
-
return mixHex(
|
|
32646
|
+
return mixHex(STACK_ORANGE2, SIGNAL_PINK, progress);
|
|
32447
32647
|
}
|
|
32448
32648
|
function GradientText({ text }) {
|
|
32449
32649
|
return /* @__PURE__ */ jsx68(Text, { bold: true, children: [...text].map(
|
|
@@ -32468,7 +32668,7 @@ function InfoRow({
|
|
|
32468
32668
|
}) {
|
|
32469
32669
|
const labelWidth = compact ? 6 : 9;
|
|
32470
32670
|
const valueWidth = Math.max(1, contentWidth - labelWidth - 3);
|
|
32471
|
-
const color = accent ?
|
|
32671
|
+
const color = accent ? STACK_ORANGE2 : MUTED;
|
|
32472
32672
|
return /* @__PURE__ */ jsxs66(Text, { children: [
|
|
32473
32673
|
/* @__PURE__ */ jsx68(Text, { color, children: icon }),
|
|
32474
32674
|
/* @__PURE__ */ jsx68(Text, { color, bold: true, children: ` ${trunc(label, labelWidth).padEnd(labelWidth)} ` }),
|
|
@@ -32505,11 +32705,11 @@ function ProfileRow({
|
|
|
32505
32705
|
const profileSegment = segmentMatch?.[1] ?? "";
|
|
32506
32706
|
const segIdx = profileSegment ? displayPath.lastIndexOf(profileSegment) : -1;
|
|
32507
32707
|
return /* @__PURE__ */ jsxs66(Text, { children: [
|
|
32508
|
-
/* @__PURE__ */ jsx68(Text, { color:
|
|
32509
|
-
/* @__PURE__ */ jsx68(Text, { color:
|
|
32708
|
+
/* @__PURE__ */ jsx68(Text, { color: STACK_ORANGE2, children: icon }),
|
|
32709
|
+
/* @__PURE__ */ jsx68(Text, { color: STACK_ORANGE2, bold: true, children: ` ${trunc(label, labelWidth).padEnd(labelWidth)} ` }),
|
|
32510
32710
|
segIdx >= 0 && profileSegment ? /* @__PURE__ */ jsxs66(Fragment22, { children: [
|
|
32511
32711
|
/* @__PURE__ */ jsx68(Text, { color: MUTED, children: displayPath.slice(0, segIdx) }),
|
|
32512
|
-
/* @__PURE__ */ jsx68(Text, { color:
|
|
32712
|
+
/* @__PURE__ */ jsx68(Text, { color: STACK_ORANGE2, bold: true, children: profileSegment }),
|
|
32513
32713
|
/* @__PURE__ */ jsx68(Text, { color: MUTED, children: displayPath.slice(segIdx + profileSegment.length) })
|
|
32514
32714
|
] }) : /* @__PURE__ */ jsx68(Text, { color: MUTED, children: displayPath })
|
|
32515
32715
|
] });
|
|
@@ -32522,7 +32722,7 @@ function Footer({ contentWidth, compact }) {
|
|
|
32522
32722
|
/* @__PURE__ */ jsx68(Text, { dimColor: true, children: OSC8_WRONGSTACK }),
|
|
32523
32723
|
!compact || contentWidth >= 35 ? /* @__PURE__ */ jsxs66(Fragment22, { children: [
|
|
32524
32724
|
/* @__PURE__ */ jsx68(Text, { dimColor: true, children: " \xB7 " }),
|
|
32525
|
-
/* @__PURE__ */ jsx68(Text, { color:
|
|
32725
|
+
/* @__PURE__ */ jsx68(Text, { color: STACK_ORANGE2, children: "\u2605 " }),
|
|
32526
32726
|
/* @__PURE__ */ jsx68(Text, { dimColor: true, children: OSC8_GITHUB })
|
|
32527
32727
|
] }) : null
|
|
32528
32728
|
] }) });
|
|
@@ -32548,7 +32748,7 @@ function AutonomyAgentsSection({
|
|
|
32548
32748
|
if (!agent) return null;
|
|
32549
32749
|
const online = agent.online;
|
|
32550
32750
|
const indicator = online ? "\u25CF" : "\xB7";
|
|
32551
|
-
const color = online ?
|
|
32751
|
+
const color = online ? STACK_ORANGE2 : MUTED;
|
|
32552
32752
|
const detail = agent.detail;
|
|
32553
32753
|
return /* @__PURE__ */ jsxs66(Box, { flexDirection: "row", marginRight: 2, children: [
|
|
32554
32754
|
/* @__PURE__ */ jsx68(Text, { color, children: indicator }),
|
|
@@ -32595,9 +32795,9 @@ function Banner({
|
|
|
32595
32795
|
Math.max(1, panelWidth - (unbordered ? 0 : 4))
|
|
32596
32796
|
);
|
|
32597
32797
|
if (unbordered) {
|
|
32598
|
-
return /* @__PURE__ */ jsx68(Text, { color:
|
|
32798
|
+
return /* @__PURE__ */ jsx68(Text, { color: STACK_ORANGE2, bold: true, children: summary });
|
|
32599
32799
|
}
|
|
32600
|
-
return /* @__PURE__ */ jsx68(Box, { width: panelWidth, borderStyle: "round", borderColor: BORDER, paddingX: 1, children: /* @__PURE__ */ jsx68(Text, { color:
|
|
32800
|
+
return /* @__PURE__ */ jsx68(Box, { width: panelWidth, borderStyle: "round", borderColor: BORDER, paddingX: 1, children: /* @__PURE__ */ jsx68(Text, { color: STACK_ORANGE2, bold: true, children: summary }) });
|
|
32601
32801
|
}
|
|
32602
32802
|
return /* @__PURE__ */ jsxs66(
|
|
32603
32803
|
Box,
|
|
@@ -32614,7 +32814,7 @@ function Banner({
|
|
|
32614
32814
|
"v",
|
|
32615
32815
|
version
|
|
32616
32816
|
] }),
|
|
32617
|
-
entry.updateAvailable && entry.latestVersion ? /* @__PURE__ */ jsxs66(Text, { color:
|
|
32817
|
+
entry.updateAvailable && entry.latestVersion ? /* @__PURE__ */ jsxs66(Text, { color: STACK_ORANGE2, children: [
|
|
32618
32818
|
" \xB7 (update available: v",
|
|
32619
32819
|
entry.latestVersion,
|
|
32620
32820
|
")"
|
|
@@ -32842,9 +33042,11 @@ var Entry = React8.memo(function Entry2({
|
|
|
32842
33042
|
autonomyMode,
|
|
32843
33043
|
multiDiffSummaryThreshold,
|
|
32844
33044
|
todos,
|
|
32845
|
-
showModelReasoning
|
|
33045
|
+
showModelReasoning,
|
|
33046
|
+
showSageMemoryInject
|
|
32846
33047
|
}) {
|
|
32847
33048
|
const openTodos = hasOpenTodos(todos);
|
|
33049
|
+
const isFinalTurnEntry = entry.kind === "assistant" && entry.final === true;
|
|
32848
33050
|
const nextSteps = useMemo13(() => {
|
|
32849
33051
|
if (entry.kind !== "assistant") return { steps: [], stripped: "" };
|
|
32850
33052
|
return parseNextSteps(entry.text, true);
|
|
@@ -32853,10 +33055,17 @@ var Entry = React8.memo(function Entry2({
|
|
|
32853
33055
|
if (!setSuggestions) return;
|
|
32854
33056
|
if (entry.kind !== "assistant") return;
|
|
32855
33057
|
if (openTodos) return;
|
|
33058
|
+
if (!isFinalTurnEntry) return;
|
|
32856
33059
|
const text = entry.text ?? "";
|
|
32857
33060
|
const { texts } = parseNextSteps(text, true);
|
|
32858
33061
|
if (texts.length > 0) setSuggestions(texts);
|
|
32859
|
-
}, [
|
|
33062
|
+
}, [
|
|
33063
|
+
entry.kind,
|
|
33064
|
+
entry.text,
|
|
33065
|
+
openTodos,
|
|
33066
|
+
isFinalTurnEntry,
|
|
33067
|
+
setSuggestions
|
|
33068
|
+
]);
|
|
32860
33069
|
switch (entry.kind) {
|
|
32861
33070
|
case "user":
|
|
32862
33071
|
return /* @__PURE__ */ jsx70(
|
|
@@ -32911,7 +33120,7 @@ var Entry = React8.memo(function Entry2({
|
|
|
32911
33120
|
case "assistant": {
|
|
32912
33121
|
const contentWidth = assistantContentWidth(termWidth);
|
|
32913
33122
|
const { steps, stripped } = nextSteps;
|
|
32914
|
-
const hasNext = steps.length > 0 && !openTodos;
|
|
33123
|
+
const hasNext = steps.length > 0 && !openTodos && isFinalTurnEntry;
|
|
32915
33124
|
return /* @__PURE__ */ jsxs68(Box, { flexDirection: "column", children: [
|
|
32916
33125
|
/* @__PURE__ */ jsxs68(
|
|
32917
33126
|
Box,
|
|
@@ -33011,15 +33220,15 @@ var Entry = React8.memo(function Entry2({
|
|
|
33011
33220
|
const outObj = outJson && typeof outJson === "object" ? outJson : void 0;
|
|
33012
33221
|
const created = name === "write" && (outObj?.["created"] === true || /^[^\n]*\bcreated=true\b/.test(outputForFormatting));
|
|
33013
33222
|
const verb = created ? "Write" : "Update";
|
|
33014
|
-
const
|
|
33223
|
+
const path10 = stringOf(inputObj?.["path"]) ?? stringOf(outObj?.["path"]);
|
|
33015
33224
|
const agg = multiDiffs2 ? summarizeMultiFileDiffs(multiDiffs2) : void 0;
|
|
33016
|
-
const target = multiDiffs2 ? agg?.fileCount === 1 ? multiDiffs2[0].path : `${agg?.fileCount ?? multiDiffs2.length} files` :
|
|
33225
|
+
const target = multiDiffs2 ? agg?.fileCount === 1 ? multiDiffs2[0].path : `${agg?.fileCount ?? multiDiffs2.length} files` : path10 ?? "file";
|
|
33017
33226
|
return {
|
|
33018
33227
|
verb,
|
|
33019
33228
|
target,
|
|
33020
33229
|
added: agg ? agg.added : diff2?.added ?? 0,
|
|
33021
33230
|
removed: agg ? agg.removed : diff2?.removed ?? 0,
|
|
33022
|
-
lang: langFromPath(multiDiffs2 ? "" :
|
|
33231
|
+
lang: langFromPath(multiDiffs2 ? "" : path10 ?? "")
|
|
33023
33232
|
};
|
|
33024
33233
|
})();
|
|
33025
33234
|
return {
|
|
@@ -33103,14 +33312,14 @@ var Entry = React8.memo(function Entry2({
|
|
|
33103
33312
|
]
|
|
33104
33313
|
}
|
|
33105
33314
|
),
|
|
33106
|
-
/* @__PURE__ */ jsx70(
|
|
33315
|
+
showSageMemoryInject !== false ? /* @__PURE__ */ jsx70(
|
|
33107
33316
|
SageMemoryBlock,
|
|
33108
33317
|
{
|
|
33109
33318
|
sageLines,
|
|
33110
33319
|
toolName: entry.name,
|
|
33111
33320
|
stats: entry.sageStats
|
|
33112
33321
|
}
|
|
33113
|
-
)
|
|
33322
|
+
) : null
|
|
33114
33323
|
] });
|
|
33115
33324
|
}
|
|
33116
33325
|
const toolContentWidth = Math.max(20, termWidth - 2);
|
|
@@ -33190,7 +33399,7 @@ var Entry = React8.memo(function Entry2({
|
|
|
33190
33399
|
]
|
|
33191
33400
|
}
|
|
33192
33401
|
),
|
|
33193
|
-
/* @__PURE__ */ jsx70(SageMemoryBlock, { sageLines, toolName: entry.name, stats: entry.sageStats })
|
|
33402
|
+
showSageMemoryInject !== false ? /* @__PURE__ */ jsx70(SageMemoryBlock, { sageLines, toolName: entry.name, stats: entry.sageStats }) : null
|
|
33194
33403
|
] });
|
|
33195
33404
|
}
|
|
33196
33405
|
case "memory-activation": {
|
|
@@ -33467,7 +33676,8 @@ var History = memo2(function History2({
|
|
|
33467
33676
|
autonomyMode,
|
|
33468
33677
|
multiDiffSummaryThreshold,
|
|
33469
33678
|
todos,
|
|
33470
|
-
showModelReasoning
|
|
33679
|
+
showModelReasoning,
|
|
33680
|
+
showSageMemoryInject
|
|
33471
33681
|
}) {
|
|
33472
33682
|
const { stdout } = useStdout();
|
|
33473
33683
|
const [termSize, setTermSize] = useState39({
|
|
@@ -33542,7 +33752,8 @@ var History = memo2(function History2({
|
|
|
33542
33752
|
autonomyMode,
|
|
33543
33753
|
multiDiffSummaryThreshold,
|
|
33544
33754
|
todos,
|
|
33545
|
-
showModelReasoning
|
|
33755
|
+
showModelReasoning,
|
|
33756
|
+
showSageMemoryInject
|
|
33546
33757
|
}
|
|
33547
33758
|
) }, entry.id) }, staticKey),
|
|
33548
33759
|
/* @__PURE__ */ jsx71(Box, { flexGrow: 1 })
|
|
@@ -33552,6 +33763,7 @@ var History = memo2(function History2({
|
|
|
33552
33763
|
// src/components/scrollable-history.tsx
|
|
33553
33764
|
import { jsx as jsx72, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
33554
33765
|
var LIVE_TOOL_STREAM_COPY_ID = -1;
|
|
33766
|
+
var SELECTION_COPY_ID = -2;
|
|
33555
33767
|
function findCopyHit(hits, row, col) {
|
|
33556
33768
|
for (let i = hits.length - 1; i >= 0; i--) {
|
|
33557
33769
|
const hit = hits[i];
|
|
@@ -33581,7 +33793,8 @@ function copyRegistryVisibleClip(opts) {
|
|
|
33581
33793
|
return Math.max(0, opts.mountedRows + opts.tailRows - opts.viewportRows);
|
|
33582
33794
|
}
|
|
33583
33795
|
function liveToolStreamCopyHit(opts) {
|
|
33584
|
-
const
|
|
33796
|
+
const slack = opts.pinnedSlack ?? 0;
|
|
33797
|
+
const headerRow = opts.mountedRows - opts.visibleClip + 1 + slack;
|
|
33585
33798
|
if (!opts.visible || headerRow < 0 || headerRow >= opts.viewportRows) return null;
|
|
33586
33799
|
return {
|
|
33587
33800
|
entryId: LIVE_TOOL_STREAM_COPY_ID,
|
|
@@ -33590,6 +33803,36 @@ function liveToolStreamCopyHit(opts) {
|
|
|
33590
33803
|
iconCol: opts.iconCol
|
|
33591
33804
|
};
|
|
33592
33805
|
}
|
|
33806
|
+
function normalizeSelection(a, b, inProgress) {
|
|
33807
|
+
const topLeft = { row: Math.min(a.row, b.row), col: Math.min(a.col, b.col) };
|
|
33808
|
+
const bottomRight = { row: Math.max(a.row, b.row), col: Math.max(a.col, b.col) };
|
|
33809
|
+
return { topLeft, bottomRight, inProgress };
|
|
33810
|
+
}
|
|
33811
|
+
function isOutOfBand(col, termWidth) {
|
|
33812
|
+
return col < 0 || col >= termWidth;
|
|
33813
|
+
}
|
|
33814
|
+
function selectionToSlices(opts) {
|
|
33815
|
+
const { selection, cards, cardVisibleCols } = opts;
|
|
33816
|
+
const maxCol = Math.max(0, cardVisibleCols - 1);
|
|
33817
|
+
const result = [];
|
|
33818
|
+
for (const card of cards) {
|
|
33819
|
+
const visTop = Math.max(selection.topLeft.row, card.viewportStartRow);
|
|
33820
|
+
const visBot = Math.min(selection.bottomRight.row, card.viewportEndRow - 1);
|
|
33821
|
+
if (visTop > visBot) continue;
|
|
33822
|
+
const entryStartRow = visTop - card.viewportStartRow;
|
|
33823
|
+
const entryEndRow = visBot - card.viewportStartRow;
|
|
33824
|
+
const startCol = entryStartRow === selection.topLeft.row - card.viewportStartRow ? Math.max(0, Math.min(maxCol, selection.topLeft.col)) : 0;
|
|
33825
|
+
const endCol = entryEndRow === selection.bottomRight.row - card.viewportStartRow ? Math.max(startCol, Math.min(maxCol, selection.bottomRight.col)) : maxCol;
|
|
33826
|
+
result.push({
|
|
33827
|
+
entryId: card.entryId,
|
|
33828
|
+
startRow: entryStartRow,
|
|
33829
|
+
startCol,
|
|
33830
|
+
endRow: entryEndRow,
|
|
33831
|
+
endCol
|
|
33832
|
+
});
|
|
33833
|
+
}
|
|
33834
|
+
return result;
|
|
33835
|
+
}
|
|
33593
33836
|
function buildCopyRegistry(opts) {
|
|
33594
33837
|
const mountedGroupRows = opts.renderGroups.reduce(
|
|
33595
33838
|
(rows, group) => rows + (opts.heightCache.getHeight(renderGroupId(group)) ?? 0),
|
|
@@ -33602,12 +33845,13 @@ function buildCopyRegistry(opts) {
|
|
|
33602
33845
|
tailRows: opts.tailRows,
|
|
33603
33846
|
viewportRows: opts.viewportRows
|
|
33604
33847
|
});
|
|
33848
|
+
const pinnedSlack = !opts.scrolled ? Math.max(0, opts.viewportRows - mountedGroupRows - opts.tailRows) : 0;
|
|
33605
33849
|
const hits = [];
|
|
33606
33850
|
let offset = 0;
|
|
33607
33851
|
for (const group of opts.renderGroups) {
|
|
33608
33852
|
const gid = renderGroupId(group);
|
|
33609
33853
|
const groupHeight = opts.heightCache.getHeight(gid) ?? 0;
|
|
33610
|
-
const startRow = offset - visibleClip;
|
|
33854
|
+
const startRow = offset - visibleClip + pinnedSlack;
|
|
33611
33855
|
offset += groupHeight;
|
|
33612
33856
|
const groupEntryIds = group.type === "tool-group" ? group.data.entries.map((entry) => entry.id) : isCopyableEntry(group.entry) && !(group.entry.kind === "thinking" && opts.showModelReasoning === false) ? [group.entry.id] : [];
|
|
33613
33857
|
const entryId = groupEntryIds[0];
|
|
@@ -33627,7 +33871,8 @@ function buildCopyRegistry(opts) {
|
|
|
33627
33871
|
mountedRows: mountedGroupRows,
|
|
33628
33872
|
visibleClip,
|
|
33629
33873
|
viewportRows: opts.viewportRows,
|
|
33630
|
-
iconCol: opts.iconCol
|
|
33874
|
+
iconCol: opts.iconCol,
|
|
33875
|
+
pinnedSlack
|
|
33631
33876
|
})
|
|
33632
33877
|
};
|
|
33633
33878
|
}
|
|
@@ -33643,6 +33888,100 @@ function scrollbarThumb(rows, offset, total) {
|
|
|
33643
33888
|
);
|
|
33644
33889
|
return { top, size, scrollable: true };
|
|
33645
33890
|
}
|
|
33891
|
+
function buildMountedCardSpans(opts) {
|
|
33892
|
+
const mountedGroupRows = opts.renderGroups.reduce(
|
|
33893
|
+
(rows, group) => rows + (opts.heightCache.getHeight(renderGroupId(group)) ?? 0),
|
|
33894
|
+
0
|
|
33895
|
+
);
|
|
33896
|
+
const visibleClip = copyRegistryVisibleClip({
|
|
33897
|
+
scrolled: opts.scrolled,
|
|
33898
|
+
clip: opts.clip,
|
|
33899
|
+
mountedRows: mountedGroupRows,
|
|
33900
|
+
tailRows: opts.tailRows,
|
|
33901
|
+
viewportRows: opts.viewportRows
|
|
33902
|
+
});
|
|
33903
|
+
const spans = [];
|
|
33904
|
+
let offset = 0;
|
|
33905
|
+
const pinnedSlack = !opts.scrolled ? Math.max(0, opts.viewportRows - mountedGroupRows - opts.tailRows) : 0;
|
|
33906
|
+
for (const group of opts.renderGroups) {
|
|
33907
|
+
const gid = renderGroupId(group);
|
|
33908
|
+
const groupHeight = opts.heightCache.getHeight(gid) ?? 0;
|
|
33909
|
+
const viewportStartRow = offset - visibleClip + pinnedSlack;
|
|
33910
|
+
offset += groupHeight;
|
|
33911
|
+
const entryIds = group.type === "tool-group" ? group.data.entries.map((entry) => entry.id) : isCopyableEntry(group.entry) && !(group.entry.kind === "thinking" && opts.showModelReasoning === false) ? [group.entry.id] : [];
|
|
33912
|
+
const entryId = entryIds[0];
|
|
33913
|
+
if (entryId === void 0) continue;
|
|
33914
|
+
const viewportEndRow = viewportStartRow + groupHeight;
|
|
33915
|
+
if (viewportEndRow <= 0 || viewportStartRow >= opts.viewportRows) continue;
|
|
33916
|
+
spans.push({
|
|
33917
|
+
entryId,
|
|
33918
|
+
viewportStartRow,
|
|
33919
|
+
viewportEndRow,
|
|
33920
|
+
totalRows: groupHeight,
|
|
33921
|
+
...entryIds.length > 1 ? { entryIds } : {}
|
|
33922
|
+
});
|
|
33923
|
+
}
|
|
33924
|
+
return spans;
|
|
33925
|
+
}
|
|
33926
|
+
function selectionHitAt(row, spans) {
|
|
33927
|
+
for (const span of spans) {
|
|
33928
|
+
if (row >= span.viewportStartRow && row < span.viewportEndRow) {
|
|
33929
|
+
return { entryId: span.entryId, ...span.entryIds ? { entryIds: span.entryIds } : {} };
|
|
33930
|
+
}
|
|
33931
|
+
}
|
|
33932
|
+
return null;
|
|
33933
|
+
}
|
|
33934
|
+
function assembleSelectionText(opts) {
|
|
33935
|
+
const { slices, entriesById, toolGroupsByHeadId } = opts;
|
|
33936
|
+
if (slices.length === 0) return "";
|
|
33937
|
+
const byEntry = /* @__PURE__ */ new Map();
|
|
33938
|
+
for (const slice of slices) {
|
|
33939
|
+
const list = byEntry.get(slice.entryId);
|
|
33940
|
+
if (list) list.push(slice);
|
|
33941
|
+
else byEntry.set(slice.entryId, [slice]);
|
|
33942
|
+
}
|
|
33943
|
+
const segments = [];
|
|
33944
|
+
let toolGroupCount = 0;
|
|
33945
|
+
for (const [entryId, entrySlices] of byEntry) {
|
|
33946
|
+
const head = entriesById.get(entryId);
|
|
33947
|
+
if (!head) continue;
|
|
33948
|
+
const groupMembers = toolGroupsByHeadId?.get(entryId);
|
|
33949
|
+
const entries = groupMembers && groupMembers.length > 1 ? groupMembers.map((id) => entriesById.get(id)).filter((entry) => entry !== void 0) : [head];
|
|
33950
|
+
if (entries.length === 0) continue;
|
|
33951
|
+
if (entries.length > 1) toolGroupCount += 1;
|
|
33952
|
+
const fullText = entries.length === 1 ? copyableTextForEntry(entries[0]) : copyableTextForEntries(entries);
|
|
33953
|
+
if (fullText.length === 0) continue;
|
|
33954
|
+
if (entries.length > 1) {
|
|
33955
|
+
segments.push(fullText);
|
|
33956
|
+
continue;
|
|
33957
|
+
}
|
|
33958
|
+
for (const slice of entrySlices) {
|
|
33959
|
+
const rows = fullText.split("\n");
|
|
33960
|
+
const collected = [];
|
|
33961
|
+
for (let r = slice.startRow; r <= slice.endRow && r < rows.length; r++) {
|
|
33962
|
+
const line = rows[r] ?? "";
|
|
33963
|
+
if (slice.startRow === slice.endRow) {
|
|
33964
|
+
const start = Math.max(0, Math.min(line.length, slice.startCol));
|
|
33965
|
+
const end = Math.max(start, Math.min(line.length, slice.endCol + 1));
|
|
33966
|
+
if (end > start) collected.push(line.slice(start, end));
|
|
33967
|
+
} else if (r === slice.startRow) {
|
|
33968
|
+
const start = Math.max(0, Math.min(line.length, slice.startCol));
|
|
33969
|
+
if (start < line.length) collected.push(line.slice(start));
|
|
33970
|
+
} else if (r === slice.endRow) {
|
|
33971
|
+
const end = Math.max(0, Math.min(line.length, slice.endCol + 1));
|
|
33972
|
+
if (end > 0) collected.push(line.slice(0, end));
|
|
33973
|
+
} else {
|
|
33974
|
+
collected.push(line);
|
|
33975
|
+
}
|
|
33976
|
+
}
|
|
33977
|
+
const seg = collected.join("\n");
|
|
33978
|
+
if (seg.length > 0) segments.push(seg);
|
|
33979
|
+
}
|
|
33980
|
+
}
|
|
33981
|
+
if (segments.length === 0) return "";
|
|
33982
|
+
const separator = byEntry.size > 1 || toolGroupCount > 0 ? "\n---\n" : "\n";
|
|
33983
|
+
return segments.join(separator);
|
|
33984
|
+
}
|
|
33646
33985
|
function Scrollbar({
|
|
33647
33986
|
rows,
|
|
33648
33987
|
offset,
|
|
@@ -33692,6 +34031,7 @@ var ScrollableHistory = memo3(function ScrollableHistory2({
|
|
|
33692
34031
|
multiDiffSummaryThreshold,
|
|
33693
34032
|
todos,
|
|
33694
34033
|
showModelReasoning,
|
|
34034
|
+
showSageMemoryInject,
|
|
33695
34035
|
layoutStore,
|
|
33696
34036
|
copiedEntryId,
|
|
33697
34037
|
onRequestOlderEntries
|
|
@@ -33727,6 +34067,9 @@ var ScrollableHistory = memo3(function ScrollableHistory2({
|
|
|
33727
34067
|
const measuredGroupIdsRef = useRef37(/* @__PURE__ */ new Set());
|
|
33728
34068
|
const copyHitsRef = useRef37([]);
|
|
33729
34069
|
const liveToolCopyHitRef = useRef37(null);
|
|
34070
|
+
const mountedGroupSpansRef = useRef37([]);
|
|
34071
|
+
const spansSignatureRef = useRef37("");
|
|
34072
|
+
const selectionRef = useRef37({ anchor: null, head: null, inProgress: false });
|
|
33730
34073
|
const toolStreamRef = useRef37(toolStream);
|
|
33731
34074
|
toolStreamRef.current = toolStream;
|
|
33732
34075
|
const entriesByIdRef = useRef37(/* @__PURE__ */ new Map());
|
|
@@ -33734,7 +34077,8 @@ var ScrollableHistory = memo3(function ScrollableHistory2({
|
|
|
33734
34077
|
const preparedGroupIdsRef = useRef37(null);
|
|
33735
34078
|
const preparedEstimateWidthRef = useRef37(null);
|
|
33736
34079
|
const reasoningKey = showModelReasoning === false ? "|r0" : "";
|
|
33737
|
-
const
|
|
34080
|
+
const sageKey = showSageMemoryInject === false ? "|s0" : "";
|
|
34081
|
+
const cacheKey = (layoutStore ? `${groupIdsKey}|w${termWidth}` : groupIdsKey) + reasoningKey + sageKey;
|
|
33738
34082
|
if (preparedGroupIdsRef.current !== cacheKey || preparedEstimateWidthRef.current !== termWidth) {
|
|
33739
34083
|
const widthChanged = preparedEstimateWidthRef.current !== null && preparedEstimateWidthRef.current !== termWidth;
|
|
33740
34084
|
if (widthChanged) {
|
|
@@ -33761,7 +34105,7 @@ var ScrollableHistory = memo3(function ScrollableHistory2({
|
|
|
33761
34105
|
}
|
|
33762
34106
|
if (stored.kind === "measured") measuredGroupIdsRef.current.add(id);
|
|
33763
34107
|
} else {
|
|
33764
|
-
const estimatedRows = estimateRenderGroupRows(group, termWidth);
|
|
34108
|
+
const estimatedRows = estimateRenderGroupRows(group, termWidth, showSageMemoryInject);
|
|
33765
34109
|
heightCache.record(id, estimatedRows);
|
|
33766
34110
|
const kind = group.type === "tool-group" ? "tool-group" : group.entry.kind;
|
|
33767
34111
|
const text = group.type === "tool-group" ? group.data.name : group.entry.text ?? "";
|
|
@@ -33780,7 +34124,10 @@ var ScrollableHistory = memo3(function ScrollableHistory2({
|
|
|
33780
34124
|
const id = renderGroupId(group);
|
|
33781
34125
|
const hidden = group.type !== "tool-group" && group.entry.kind === "thinking" && showModelReasoning === false;
|
|
33782
34126
|
if (hidden) hiddenIds.add(id);
|
|
33783
|
-
return [
|
|
34127
|
+
return [
|
|
34128
|
+
id,
|
|
34129
|
+
hidden ? 0 : estimateRenderGroupRows(group, termWidth, showSageMemoryInject)
|
|
34130
|
+
];
|
|
33784
34131
|
})
|
|
33785
34132
|
);
|
|
33786
34133
|
heightCache.recordMany(
|
|
@@ -33838,6 +34185,7 @@ var ScrollableHistory = memo3(function ScrollableHistory2({
|
|
|
33838
34185
|
const ids = groupIdsRef.current;
|
|
33839
34186
|
const nextId = next ? ids[next.index] : void 0;
|
|
33840
34187
|
const normalized = next && nextId !== void 0 ? { index: next.index, clip: Math.max(0, next.clip) } : null;
|
|
34188
|
+
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
33841
34189
|
effectiveAnchorRef.current = normalized;
|
|
33842
34190
|
setAnchor(normalized && nextId !== void 0 ? { id: nextId, clip: normalized.clip } : null);
|
|
33843
34191
|
setMountBump(0);
|
|
@@ -33883,9 +34231,77 @@ var ScrollableHistory = memo3(function ScrollableHistory2({
|
|
|
33883
34231
|
);
|
|
33884
34232
|
if (payload === null) return null;
|
|
33885
34233
|
return await writeClipboardText(payload.text) ? payload.entryId : null;
|
|
34234
|
+
},
|
|
34235
|
+
beginSelection: (row, col) => {
|
|
34236
|
+
if (isOutOfBand(col, termWidth)) {
|
|
34237
|
+
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
34238
|
+
return;
|
|
34239
|
+
}
|
|
34240
|
+
const cardHit = selectionHitAt(row, mountedGroupSpansRef.current);
|
|
34241
|
+
if (cardHit === null) {
|
|
34242
|
+
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
34243
|
+
return;
|
|
34244
|
+
}
|
|
34245
|
+
selectionRef.current = {
|
|
34246
|
+
anchor: { row, col },
|
|
34247
|
+
head: { row, col },
|
|
34248
|
+
inProgress: true
|
|
34249
|
+
};
|
|
34250
|
+
},
|
|
34251
|
+
extendSelection: (row, col) => {
|
|
34252
|
+
const cur = selectionRef.current;
|
|
34253
|
+
if (cur.anchor === null) return;
|
|
34254
|
+
if (cur.inProgress === false) return;
|
|
34255
|
+
if (isOutOfBand(col, termWidth) || row < 0 || row >= vp) {
|
|
34256
|
+
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
34257
|
+
return;
|
|
34258
|
+
}
|
|
34259
|
+
selectionRef.current = { ...cur, head: { row, col } };
|
|
34260
|
+
},
|
|
34261
|
+
endSelection: () => {
|
|
34262
|
+
const cur = selectionRef.current;
|
|
34263
|
+
if (cur.anchor === null) return;
|
|
34264
|
+
selectionRef.current = { ...cur, inProgress: false };
|
|
34265
|
+
},
|
|
34266
|
+
clearSelection: () => {
|
|
34267
|
+
const cur = selectionRef.current;
|
|
34268
|
+
if (cur.anchor === null && cur.head === null) return;
|
|
34269
|
+
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
34270
|
+
},
|
|
34271
|
+
commitSelection: async () => {
|
|
34272
|
+
const cur = selectionRef.current;
|
|
34273
|
+
if (cur.anchor === null || cur.head === null) return false;
|
|
34274
|
+
if (cur.anchor.row === cur.head.row && cur.anchor.col === cur.head.col) {
|
|
34275
|
+
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
34276
|
+
return false;
|
|
34277
|
+
}
|
|
34278
|
+
const rect = normalizeSelection(cur.anchor, cur.head, cur.inProgress);
|
|
34279
|
+
const slices = selectionToSlices({
|
|
34280
|
+
selection: rect,
|
|
34281
|
+
cards: mountedGroupSpansRef.current,
|
|
34282
|
+
cardVisibleCols: termWidth
|
|
34283
|
+
});
|
|
34284
|
+
const toolGroupsByHeadId = /* @__PURE__ */ new Map();
|
|
34285
|
+
for (const span of mountedGroupSpansRef.current) {
|
|
34286
|
+
if (span.entryIds && span.entryIds.length > 1) {
|
|
34287
|
+
toolGroupsByHeadId.set(span.entryId, span.entryIds);
|
|
34288
|
+
}
|
|
34289
|
+
}
|
|
34290
|
+
const text = assembleSelectionText({
|
|
34291
|
+
slices,
|
|
34292
|
+
entriesById: entriesByIdRef.current,
|
|
34293
|
+
...toolGroupsByHeadId.size > 0 ? { toolGroupsByHeadId } : {}
|
|
34294
|
+
});
|
|
34295
|
+
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
34296
|
+
if (text.length === 0) return false;
|
|
34297
|
+
try {
|
|
34298
|
+
return await writeClipboardText(text);
|
|
34299
|
+
} catch {
|
|
34300
|
+
return false;
|
|
34301
|
+
}
|
|
33886
34302
|
}
|
|
33887
34303
|
}),
|
|
33888
|
-
[applyAnchor]
|
|
34304
|
+
[applyAnchor, termWidth, vp]
|
|
33889
34305
|
);
|
|
33890
34306
|
useEffect67(() => {
|
|
33891
34307
|
if (!controllerRef) return void 0;
|
|
@@ -33912,6 +34328,19 @@ var ScrollableHistory = memo3(function ScrollableHistory2({
|
|
|
33912
34328
|
const clip2 = effectiveAnchor?.clip ?? 0;
|
|
33913
34329
|
planStartIdxRef.current = plan.startIdx;
|
|
33914
34330
|
const totalRows = contentRows(geometry);
|
|
34331
|
+
setTuiHistoryMemoryGauges({
|
|
34332
|
+
historyRetainedEntries: entries.length,
|
|
34333
|
+
historyGroupedEntries: groupedEntries.length,
|
|
34334
|
+
historyMountedGroups: renderGroups.length,
|
|
34335
|
+
historyMountedEntries: renderGroups.reduce(
|
|
34336
|
+
(count, group) => count + (group.type === "tool-group" ? group.data.entries.length : 1),
|
|
34337
|
+
0
|
|
34338
|
+
),
|
|
34339
|
+
historyCachedGroups: heightCache.size,
|
|
34340
|
+
historyMeasuredGroups: measuredGroupIdsRef.current.size,
|
|
34341
|
+
historyViewportRows: vp,
|
|
34342
|
+
historyTotalRows: totalRows
|
|
34343
|
+
});
|
|
33915
34344
|
const offsetFromBottom = scrolled ? Math.max(0, maxTopRow(geometry) - anchorTopRow(geometry, effectiveAnchor)) : 0;
|
|
33916
34345
|
const copyRegistry = buildCopyRegistry({
|
|
33917
34346
|
renderGroups,
|
|
@@ -33927,6 +34356,23 @@ var ScrollableHistory = memo3(function ScrollableHistory2({
|
|
|
33927
34356
|
copyHitsRef.current = copyRegistry.hits;
|
|
33928
34357
|
liveToolCopyHitRef.current = copyRegistry.liveHit;
|
|
33929
34358
|
const copyRailHits = copyRegistry.liveHit ? [...copyRegistry.hits, copyRegistry.liveHit] : copyRegistry.hits;
|
|
34359
|
+
const nextSpans = buildMountedCardSpans({
|
|
34360
|
+
renderGroups,
|
|
34361
|
+
heightCache,
|
|
34362
|
+
scrolled,
|
|
34363
|
+
clip: clip2,
|
|
34364
|
+
tailRows: plan.mountTail ? toolTailHeight : 0,
|
|
34365
|
+
viewportRows: vp,
|
|
34366
|
+
showModelReasoning
|
|
34367
|
+
});
|
|
34368
|
+
const nextSignature = nextSpans.map((s2) => `${s2.entryId}:${s2.viewportStartRow}:${s2.viewportEndRow}`).join("|");
|
|
34369
|
+
if (nextSignature !== spansSignatureRef.current) {
|
|
34370
|
+
if (selectionRef.current.anchor !== null && !selectionRef.current.inProgress) {
|
|
34371
|
+
selectionRef.current = { anchor: null, head: null, inProgress: false };
|
|
34372
|
+
}
|
|
34373
|
+
spansSignatureRef.current = nextSignature;
|
|
34374
|
+
}
|
|
34375
|
+
mountedGroupSpansRef.current = nextSpans;
|
|
33930
34376
|
useLayoutEffect2(() => {
|
|
33931
34377
|
let changed = false;
|
|
33932
34378
|
for (const group of renderGroups) {
|
|
@@ -33991,6 +34437,8 @@ var ScrollableHistory = memo3(function ScrollableHistory2({
|
|
|
33991
34437
|
}
|
|
33992
34438
|
if (planStartIdxRef.current > 0) {
|
|
33993
34439
|
requestOlderFiredRef.current = false;
|
|
34440
|
+
} else if (!scrolled) {
|
|
34441
|
+
requestOlderFiredRef.current = false;
|
|
33994
34442
|
}
|
|
33995
34443
|
if (changed) setMeasureTick((tick) => tick + 1);
|
|
33996
34444
|
});
|
|
@@ -34029,7 +34477,8 @@ var ScrollableHistory = memo3(function ScrollableHistory2({
|
|
|
34029
34477
|
autonomyMode,
|
|
34030
34478
|
multiDiffSummaryThreshold,
|
|
34031
34479
|
todos,
|
|
34032
|
-
showModelReasoning
|
|
34480
|
+
showModelReasoning,
|
|
34481
|
+
showSageMemoryInject
|
|
34033
34482
|
}
|
|
34034
34483
|
)
|
|
34035
34484
|
}
|
|
@@ -34525,6 +34974,7 @@ function AppView({ host, runtime }) {
|
|
|
34525
34974
|
multiDiffSummaryThreshold: state.settingsPicker.multiDiffSummaryThreshold,
|
|
34526
34975
|
todos: liveTodos,
|
|
34527
34976
|
showModelReasoning: state.settingsPicker.open ? state.settingsPicker.showModelReasoning : liveSettings?.showModelReasoning ?? true,
|
|
34977
|
+
showSageMemoryInject: state.settingsPicker.open ? state.settingsPicker.showSageMemoryInject : liveSettings?.showSageMemoryInject ?? false,
|
|
34528
34978
|
layoutStore,
|
|
34529
34979
|
copiedEntryId: state.copiedEntryId,
|
|
34530
34980
|
onRequestOlderEntries: runtime.onRequestOlderEntries
|
|
@@ -34676,6 +35126,8 @@ function AppView({ host, runtime }) {
|
|
|
34676
35126
|
breakerAutoKillResetMs: state.settingsPicker.breakerAutoKillResetMs,
|
|
34677
35127
|
showModelReasoning: state.settingsPicker.showModelReasoning,
|
|
34678
35128
|
showAgentSwarmPanel: state.settingsPicker.showAgentSwarmPanel,
|
|
35129
|
+
showSageMemoryInject: state.settingsPicker.showSageMemoryInject,
|
|
35130
|
+
sageMemoryInjectThreshold: state.settingsPicker.sageMemoryInjectThreshold,
|
|
34679
35131
|
readSymbols: state.settingsPicker.readSymbols,
|
|
34680
35132
|
filter: state.settingsPicker.filter,
|
|
34681
35133
|
hint: state.settingsPicker.hint
|
|
@@ -35069,7 +35521,10 @@ function createRunBlocksController(host) {
|
|
|
35069
35521
|
}
|
|
35070
35522
|
dispatch({ type: "streamReset" });
|
|
35071
35523
|
if (result.status === "done" && result.finalText?.trim() && !refs.assistantCommitted.current) {
|
|
35072
|
-
dispatch({
|
|
35524
|
+
dispatch({
|
|
35525
|
+
type: "addEntry",
|
|
35526
|
+
entry: { kind: "assistant", text: result.finalText, final: true }
|
|
35527
|
+
});
|
|
35073
35528
|
}
|
|
35074
35529
|
if (result.status === "aborted") {
|
|
35075
35530
|
const reason = result.abortReason ? `Aborted (${result.abortReason}).` : "Aborted.";
|
|
@@ -36388,7 +36843,7 @@ function routeSettingsOverlayKey(host, input, key, isEnter) {
|
|
|
36388
36843
|
enhanceEnabled: config.enhanceEnabled ?? true,
|
|
36389
36844
|
enhanceLanguage: config.enhanceLanguage ?? "original",
|
|
36390
36845
|
debugStream: config.debugStream ?? false,
|
|
36391
|
-
statuslineMode: config.statuslineMode ??
|
|
36846
|
+
statuslineMode: config.statuslineMode ?? DEFAULT_STATUSLINE_MODE,
|
|
36392
36847
|
reasoningMode: config.reasoningMode ?? "auto",
|
|
36393
36848
|
reasoningEffort: config.reasoningEffort ?? "high",
|
|
36394
36849
|
reasoningPreserve: config.reasoningPreserve ?? false,
|
|
@@ -36400,6 +36855,8 @@ function routeSettingsOverlayKey(host, input, key, isEnter) {
|
|
|
36400
36855
|
breakerAutoKillResetMs: config.breakerAutoKillResetMs ?? 6e4,
|
|
36401
36856
|
showModelReasoning: config.showModelReasoning ?? true,
|
|
36402
36857
|
showAgentSwarmPanel: config.showAgentSwarmPanel ?? true,
|
|
36858
|
+
showSageMemoryInject: config.showSageMemoryInject ?? false,
|
|
36859
|
+
sageMemoryInjectThreshold: config.sageMemoryInjectThreshold ?? 0.85,
|
|
36403
36860
|
readSymbols: config.readSymbols ?? false
|
|
36404
36861
|
});
|
|
36405
36862
|
return true;
|
|
@@ -36663,7 +37120,7 @@ function createAppKeyHandler(options) {
|
|
|
36663
37120
|
dispatch({ type: "toggleSddBoardMonitor" });
|
|
36664
37121
|
return;
|
|
36665
37122
|
}
|
|
36666
|
-
if (key.ctrl && input === "
|
|
37123
|
+
if (key.ctrl && input === "y") {
|
|
36667
37124
|
dispatch({ type: "toggleKanbanPanel" });
|
|
36668
37125
|
return;
|
|
36669
37126
|
}
|
|
@@ -36703,7 +37160,7 @@ function createAppKeyHandler(options) {
|
|
|
36703
37160
|
}
|
|
36704
37161
|
}
|
|
36705
37162
|
}
|
|
36706
|
-
if (state.sddBoard?.monitorOpen && !key.ctrl && !key.meta) {
|
|
37163
|
+
if (state.sddBoard?.monitorOpen && !key.ctrl && !key.meta && draftRef.current.buffer === "") {
|
|
36707
37164
|
if (key.rightArrow) {
|
|
36708
37165
|
dispatch({ type: "sddBoardFocusNext" });
|
|
36709
37166
|
return;
|
|
@@ -36764,6 +37221,20 @@ function createAppKeyHandler(options) {
|
|
|
36764
37221
|
return;
|
|
36765
37222
|
}
|
|
36766
37223
|
if (!overlayOpen) {
|
|
37224
|
+
if (mouseMode && key.mouse?.kind === "press" && key.mouse.button === "right") {
|
|
37225
|
+
const region = hitRegion(
|
|
37226
|
+
{ termRows, termCols: stdout?.columns ?? 80, viewportRows: state.viewportRows },
|
|
37227
|
+
key.mouse.x,
|
|
37228
|
+
key.mouse.y
|
|
37229
|
+
);
|
|
37230
|
+
if (region?.kind === "history" && key.mouse.x <= (stdout?.columns ?? 80) - SCROLLBAR_HIT_WIDTH) {
|
|
37231
|
+
void historyScrollRef.current?.commitSelection().then((copied) => {
|
|
37232
|
+
if (copied) onHistoryCopy?.(SELECTION_COPY_ID);
|
|
37233
|
+
});
|
|
37234
|
+
return;
|
|
37235
|
+
}
|
|
37236
|
+
historyScrollRef.current?.clearSelection();
|
|
37237
|
+
}
|
|
36767
37238
|
if (key.mouse?.kind === "wheel" && key.mouse.wheel !== 0) {
|
|
36768
37239
|
if (isHistoryScrollTarget(
|
|
36769
37240
|
{ termRows, termCols: stdout?.columns ?? 80, viewportRows: state.viewportRows },
|
|
@@ -36773,6 +37244,7 @@ function createAppKeyHandler(options) {
|
|
|
36773
37244
|
if (key.mouse.shift)
|
|
36774
37245
|
historyScrollRef.current?.scrollPage(key.mouse.wheel > 0 ? "up" : "down");
|
|
36775
37246
|
else historyScrollRef.current?.scrollBy(key.mouse.wheel > 0 ? 1 : -1);
|
|
37247
|
+
historyScrollRef.current?.clearSelection();
|
|
36776
37248
|
return;
|
|
36777
37249
|
}
|
|
36778
37250
|
}
|
|
@@ -36784,16 +37256,31 @@ function createAppKeyHandler(options) {
|
|
|
36784
37256
|
);
|
|
36785
37257
|
const copyRow = region?.kind === "history" ? region.row : region?.kind === "scrollbar" ? region.cell : null;
|
|
36786
37258
|
if (copyRow !== null && key.mouse.kind === "press" && historyScrollRef.current?.hasCopyTargetAt(copyRow, key.mouse.x - 1)) {
|
|
37259
|
+
historyScrollRef.current?.clearSelection();
|
|
36787
37260
|
void historyScrollRef.current.copyAtViewportCell(copyRow, key.mouse.x - 1).then((entryId) => {
|
|
36788
37261
|
if (entryId !== null) onHistoryCopy?.(entryId);
|
|
36789
37262
|
}).catch(() => null);
|
|
36790
37263
|
return;
|
|
36791
37264
|
}
|
|
37265
|
+
if (mouseMode && region?.kind === "history" && key.mouse.x <= (stdout?.columns ?? 80) - SCROLLBAR_HIT_WIDTH) {
|
|
37266
|
+
if (key.mouse.kind === "press") {
|
|
37267
|
+
historyScrollRef.current?.beginSelection(region.row, key.mouse.x - 1);
|
|
37268
|
+
return;
|
|
37269
|
+
}
|
|
37270
|
+
if (key.mouse.kind === "move") {
|
|
37271
|
+
historyScrollRef.current?.extendSelection(region.row, key.mouse.x - 1);
|
|
37272
|
+
return;
|
|
37273
|
+
}
|
|
37274
|
+
}
|
|
36792
37275
|
if (region?.kind === "scrollbar") {
|
|
37276
|
+
historyScrollRef.current?.clearSelection();
|
|
36793
37277
|
historyScrollRef.current?.scrollToTrackCell(region.cell);
|
|
36794
37278
|
return;
|
|
36795
37279
|
}
|
|
36796
37280
|
}
|
|
37281
|
+
if (mouseMode && key.mouse?.kind === "release" && key.mouse.button === "left") {
|
|
37282
|
+
historyScrollRef.current?.endSelection();
|
|
37283
|
+
}
|
|
36797
37284
|
if (mouseMode && key.mouse?.kind === "press" && key.mouse.button === "left" && statusBarWrapRef.current) {
|
|
36798
37285
|
const sbHeight = measureElement(statusBarWrapRef.current).height;
|
|
36799
37286
|
const belowHeight = belowStatusBarRef.current ? measureElement(belowStatusBarRef.current).height : 0;
|
|
@@ -37176,8 +37663,8 @@ function App(props) {
|
|
|
37176
37663
|
submitRef
|
|
37177
37664
|
} = useAppRuntimeRefs(attachments, state);
|
|
37178
37665
|
const projectName = React10.useMemo(() => {
|
|
37179
|
-
const base =
|
|
37180
|
-
return base && base !==
|
|
37666
|
+
const base = path7.basename(projectRoot);
|
|
37667
|
+
return base && base !== path7.sep ? base : void 0;
|
|
37181
37668
|
}, [projectRoot]);
|
|
37182
37669
|
const workingDirChip = useWorkingDirChip(agent.ctx, projectRoot);
|
|
37183
37670
|
const {
|
|
@@ -37913,9 +38400,9 @@ var BRACKETED_PASTE_OFF = "\x1B[?2004l";
|
|
|
37913
38400
|
|
|
37914
38401
|
// src/run-tui-client-registration.ts
|
|
37915
38402
|
import { randomUUID } from "node:crypto";
|
|
37916
|
-
import * as
|
|
38403
|
+
import * as path8 from "node:path";
|
|
37917
38404
|
import { RemoteMailbox, resolveProjectDir } from "@wrongstack/core/coordination";
|
|
37918
|
-
import { wstackGlobalRoot
|
|
38405
|
+
import { wstackGlobalRoot } from "@wrongstack/core/utils";
|
|
37919
38406
|
import {
|
|
37920
38407
|
createHqPublisherFromEnv,
|
|
37921
38408
|
startBrainTelemetryBridge,
|
|
@@ -37941,7 +38428,7 @@ function createRunTuiClientRegistration(opts) {
|
|
|
37941
38428
|
if (!opts.projectRoot) return null;
|
|
37942
38429
|
const generation = ++registrationGeneration;
|
|
37943
38430
|
try {
|
|
37944
|
-
const projectDir = resolveProjectDir(opts.projectRoot,
|
|
38431
|
+
const projectDir = resolveProjectDir(opts.projectRoot, wstackGlobalRoot());
|
|
37945
38432
|
const mailbox = new RemoteMailbox({ projectDir, events: opts.events });
|
|
37946
38433
|
const clientId = `tui@${randomUUID().slice(0, 8)}`;
|
|
37947
38434
|
await mailbox.initialize();
|
|
@@ -38000,7 +38487,7 @@ function createRunTuiClientRegistration(opts) {
|
|
|
38000
38487
|
await mailbox.registerClient({
|
|
38001
38488
|
clientId,
|
|
38002
38489
|
sessionId: opts.getSessionId?.() ?? opts.projectRoot,
|
|
38003
|
-
name: `TUI [${
|
|
38490
|
+
name: `TUI [${path8.basename(opts.projectRoot)}]`,
|
|
38004
38491
|
source: "tui",
|
|
38005
38492
|
pid: process.pid
|
|
38006
38493
|
});
|
|
@@ -38015,7 +38502,7 @@ function createRunTuiClientRegistration(opts) {
|
|
|
38015
38502
|
tuiHqPublisher = createHqPublisherFromEnv({
|
|
38016
38503
|
clientKind: "tui",
|
|
38017
38504
|
projectRoot: opts.projectRoot,
|
|
38018
|
-
projectName:
|
|
38505
|
+
projectName: path8.basename(opts.projectRoot),
|
|
38019
38506
|
appConfig: opts.appConfig
|
|
38020
38507
|
});
|
|
38021
38508
|
tuiHqPublisher?.connect();
|
|
@@ -38028,7 +38515,7 @@ function createRunTuiClientRegistration(opts) {
|
|
|
38028
38515
|
events: opts.events,
|
|
38029
38516
|
sessionId: tuiSessionId,
|
|
38030
38517
|
projectRoot: opts.projectRoot,
|
|
38031
|
-
projectName:
|
|
38518
|
+
projectName: path8.basename(opts.projectRoot)
|
|
38032
38519
|
})
|
|
38033
38520
|
);
|
|
38034
38521
|
} catch {
|
|
@@ -38153,7 +38640,7 @@ function createRunTuiClientRegistration(opts) {
|
|
|
38153
38640
|
}
|
|
38154
38641
|
|
|
38155
38642
|
// src/run-tui-title-controller.ts
|
|
38156
|
-
import * as
|
|
38643
|
+
import * as path9 from "node:path";
|
|
38157
38644
|
|
|
38158
38645
|
// src/terminal-title.ts
|
|
38159
38646
|
var SPINNER = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
@@ -38233,7 +38720,7 @@ function createRunTuiTitleController(opts) {
|
|
|
38233
38720
|
stdout: opts.stdout,
|
|
38234
38721
|
events: opts.events,
|
|
38235
38722
|
model: currentModel,
|
|
38236
|
-
appName: opts.projectRoot ?
|
|
38723
|
+
appName: opts.projectRoot ? path9.basename(opts.projectRoot) : void 0
|
|
38237
38724
|
});
|
|
38238
38725
|
};
|
|
38239
38726
|
const stop = () => {
|
|
@@ -38268,6 +38755,7 @@ var origConsoleInfo = console.info;
|
|
|
38268
38755
|
var origConsoleTable = console.table;
|
|
38269
38756
|
var origConsoleTrace = console.trace;
|
|
38270
38757
|
var origStderrWrite = process.stderr.write.bind(process.stderr);
|
|
38758
|
+
var origStdoutWrite = process.stdout.write.bind(process.stdout);
|
|
38271
38759
|
var consoleNoop = (..._args) => {
|
|
38272
38760
|
};
|
|
38273
38761
|
var stderrNoop = ((_chunk, _encodingOrCb, _cb) => {
|
|
@@ -38297,6 +38785,7 @@ function unsilenceTerminal() {
|
|
|
38297
38785
|
console.table = origConsoleTable;
|
|
38298
38786
|
console.trace = origConsoleTrace;
|
|
38299
38787
|
process.stderr.write = origStderrWrite;
|
|
38788
|
+
process.stdout.write = origStdoutWrite;
|
|
38300
38789
|
process.off("warning", warningNoop);
|
|
38301
38790
|
}
|
|
38302
38791
|
|
|
@@ -38314,6 +38803,10 @@ async function runTui(opts) {
|
|
|
38314
38803
|
const capability = detectTerminal({ stdin, stdout });
|
|
38315
38804
|
const mouseEnabled = opts.mouse ?? opts.getSettings?.().mouseMode ?? process.env.WRONGSTACK_MOUSE === "1";
|
|
38316
38805
|
silenceTerminal();
|
|
38806
|
+
const provider = opts.agent.ctx.provider;
|
|
38807
|
+
if (provider?.suppressMaxToolsWarning) {
|
|
38808
|
+
provider.suppressMaxToolsWarning();
|
|
38809
|
+
}
|
|
38317
38810
|
const inkStdin = stdin;
|
|
38318
38811
|
const {
|
|
38319
38812
|
controller: titleController,
|