@linxiraos/pi-tui 1.1.27 → 1.2.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/CHANGELOG.md +47 -463
- package/README.md +7 -5
- package/dist/types/app-keybindings.d.ts +1 -1
- package/dist/types/apps/cleanse-board.d.ts +1 -1
- package/dist/types/apps/debug/log-viewer.d.ts +4 -0
- package/dist/types/apps/debug/raw-sse-buffer.d.ts +2 -0
- package/dist/types/apps/git/git-tui.d.ts +2 -2
- package/dist/types/apps/git/help.d.ts +3 -1
- package/dist/types/apps/if-bench-board.d.ts +2 -2
- package/dist/types/apps/setup-model-picker.d.ts +1 -1
- package/dist/types/autocomplete.d.ts +5 -2
- package/dist/types/charts/chart-plan.d.ts +674 -0
- package/dist/types/charts/chart-svg.d.ts +59 -0
- package/dist/types/charts/table-data.d.ts +175 -0
- package/dist/types/chat/assistant-message.d.ts +5 -0
- package/dist/types/chat/chat-transcript-builder.d.ts +2 -0
- package/dist/types/chat/compaction-summary-message.d.ts +1 -0
- package/dist/types/chat/execution-shared.d.ts +6 -5
- package/dist/types/chat/fence-figure.d.ts +42 -0
- package/dist/types/chat/figure-markdown.d.ts +42 -0
- package/dist/types/chat/messages.d.ts +1 -1
- package/dist/types/chat/svg-figure.d.ts +33 -0
- package/dist/types/chat/svg-source.d.ts +49 -0
- package/dist/types/chat/table-chart.d.ts +89 -0
- package/dist/types/chat/tool-execution.d.ts +2 -0
- package/dist/types/chat/user-message.d.ts +15 -2
- package/dist/types/chrome/shared.d.ts +9 -0
- package/dist/types/chrome/transcript-container.d.ts +6 -0
- package/dist/types/components/box.d.ts +1 -0
- package/dist/types/components/disclosure.d.ts +1 -0
- package/dist/types/components/editor.d.ts +15 -4
- package/dist/types/components/form.d.ts +1 -0
- package/dist/types/components/image.d.ts +12 -44
- package/dist/types/components/key-value-list.d.ts +1 -0
- package/dist/types/components/layout/row.d.ts +1 -0
- package/dist/types/components/layout/stack.d.ts +1 -0
- package/dist/types/components/markdown.d.ts +36 -3
- package/dist/types/components/scroll-view.d.ts +1 -0
- package/dist/types/components/section.d.ts +1 -0
- package/dist/types/components/table.d.ts +1 -0
- package/dist/types/components/text.d.ts +1 -0
- package/dist/types/components/tree-view.d.ts +7 -0
- package/dist/types/components/truncated-text.d.ts +1 -0
- package/dist/types/fuzzy.d.ts +29 -1
- package/dist/types/key-hint-format.d.ts +1 -1
- package/dist/types/keybinding-matchers.d.ts +3 -0
- package/dist/types/keybindings.d.ts +1 -1
- package/dist/types/kitty-graphics.d.ts +2 -2
- package/dist/types/loop-watchdog.d.ts +8 -7
- package/dist/types/multiplexers/cmux.d.ts +16 -0
- package/dist/types/multiplexers/herdr.d.ts +26 -0
- package/dist/types/multiplexers/notify.d.ts +13 -0
- package/dist/types/multiplexers/orca.d.ts +12 -0
- package/dist/types/multiplexers/screen.d.ts +9 -0
- package/dist/types/multiplexers/tmux.d.ts +29 -0
- package/dist/types/multiplexers/types.d.ts +100 -0
- package/dist/types/multiplexers/wmux.d.ts +12 -0
- package/dist/types/multiplexers/zellij.d.ts +12 -0
- package/dist/types/native/backend.d.ts +3 -2
- package/dist/types/native/blobs.d.ts +7 -3
- package/dist/types/native/encode.d.ts +3 -4
- package/dist/types/native/overlay.d.ts +5 -0
- package/dist/types/overlays/agent-hub-projection.d.ts +6 -5
- package/dist/types/overlays/agent-hub-types.d.ts +9 -0
- package/dist/types/overlays/agent-hub.d.ts +2 -0
- package/dist/types/overlays/agent-transcript-viewer.d.ts +11 -2
- package/dist/types/overlays/agents-hub.d.ts +9 -0
- package/dist/types/overlays/annotation-overlay.d.ts +19 -2
- package/dist/types/overlays/annotation-types.d.ts +2 -0
- package/dist/types/overlays/ask-dialog.d.ts +5 -2
- package/dist/types/overlays/history-search.d.ts +10 -0
- package/dist/types/overlays/hook-selector.d.ts +9 -4
- package/dist/types/overlays/jobs-panel.d.ts +1 -7
- package/dist/types/overlays/model-browser.d.ts +54 -7
- package/dist/types/overlays/model-hub.d.ts +23 -0
- package/dist/types/overlays/oauth-selector.d.ts +0 -1
- package/dist/types/overlays/plan-review-overlay.d.ts +3 -2
- package/dist/types/overlays/session-observer-registry.d.ts +2 -0
- package/dist/types/overlays/session-selector.d.ts +6 -2
- package/dist/types/overlays/settings-defs.d.ts +1 -0
- package/dist/types/overlays/usage-dashboard.d.ts +8 -4
- package/dist/types/overlays/usage-display.d.ts +3 -1
- package/dist/types/prompt/composer.d.ts +1 -1
- package/dist/types/prompt/custom-editor.d.ts +11 -8
- package/dist/types/prompt/image-source.d.ts +2 -1
- package/dist/types/prompt/interactive-context-helpers.d.ts +4 -1
- package/dist/types/prompt/model-mention-autocomplete.d.ts +1 -1
- package/dist/types/prompt/welcome.d.ts +6 -1
- package/dist/types/render/composite.d.ts +2 -0
- package/dist/types/render/output-pane.d.ts +1 -0
- package/dist/types/render/render-utils.d.ts +1 -0
- package/dist/types/render/tool-card.d.ts +6 -0
- package/dist/types/render/width-aware-text.d.ts +2 -0
- package/dist/types/setup/scenes/types.d.ts +1 -0
- package/dist/types/status-line/component.d.ts +3 -0
- package/dist/types/status-line/host.d.ts +4 -1
- package/dist/types/status-line/segments.d.ts +2 -0
- package/dist/types/status-line/types.d.ts +14 -3
- package/dist/types/terminal-capabilities.d.ts +27 -35
- package/dist/types/terminal-multiplexer.d.ts +127 -14
- package/dist/types/terminal.d.ts +22 -6
- package/dist/types/theme/active-symbols.d.ts +1 -1
- package/dist/types/theme/schema.d.ts +11 -2
- package/dist/types/theme/symbols.d.ts +1 -1
- package/dist/types/theme/theme-class.d.ts +7 -0
- package/dist/types/theme/theme.d.ts +1 -1
- package/dist/types/theme/tui-adapters.d.ts +3 -0
- package/dist/types/tmux.d.ts +11 -4
- package/dist/types/tools/daemon.d.ts +1 -1
- package/dist/types/tools/eval.d.ts +22 -3
- package/dist/types/tools/glob.d.ts +4 -0
- package/dist/types/tools/native-view.d.ts +47 -0
- package/dist/types/tools/output-meta.d.ts +11 -1
- package/dist/types/tools/renderer.d.ts +37 -2
- package/dist/types/tools/streaming-output.d.ts +20 -1
- package/dist/types/tools/task.d.ts +0 -4
- package/dist/types/tools/write.d.ts +9 -2
- package/dist/types/tools/yield.d.ts +22 -0
- package/dist/types/tui.d.ts +31 -0
- package/dist/types/utils.d.ts +6 -0
- package/dist/types/vim.d.ts +19 -5
- package/package.json +13 -9
- package/src/app-keybindings.d.ts +1 -1
- package/src/app-keybindings.ts +1 -1
- package/src/apps/autoresearch-dashboard.ts +7 -3
- package/src/apps/cleanse-board.ts +2 -2
- package/src/apps/cleanse-picker.ts +1 -1
- package/src/apps/debug/log-viewer.ts +188 -72
- package/src/apps/debug/raw-sse-buffer.ts +8 -0
- package/src/apps/debug/raw-sse.ts +39 -5
- package/src/apps/git/diff-pane.ts +26 -5
- package/src/apps/git/git-tui.ts +2 -2
- package/src/apps/git/help.ts +29 -20
- package/src/apps/if-bench-board.ts +2 -2
- package/src/apps/ps-top.ts +2 -2
- package/src/apps/setup-model-picker.ts +1 -1
- package/src/autocomplete.d.ts +5 -2
- package/src/autocomplete.ts +67 -43
- package/src/charts/chart-plan.d.ts +674 -0
- package/src/charts/chart-plan.ts +5081 -0
- package/src/charts/chart-svg.d.ts +59 -0
- package/src/charts/chart-svg.ts +4657 -0
- package/src/charts/table-data.d.ts +175 -0
- package/src/charts/table-data.ts +1478 -0
- package/src/chat/advisor-message.ts +11 -0
- package/src/chat/assistant-message.d.ts +5 -0
- package/src/chat/assistant-message.ts +219 -50
- package/src/chat/chat-transcript-builder.d.ts +2 -0
- package/src/chat/chat-transcript-builder.ts +5 -3
- package/src/chat/compaction-summary-message.d.ts +1 -0
- package/src/chat/compaction-summary-message.ts +8 -0
- package/src/chat/execution-shared.d.ts +6 -5
- package/src/chat/execution-shared.ts +42 -25
- package/src/chat/fence-figure.d.ts +42 -0
- package/src/chat/fence-figure.ts +80 -0
- package/src/chat/figure-markdown.d.ts +42 -0
- package/src/chat/figure-markdown.ts +174 -0
- package/src/chat/messages.d.ts +1 -1
- package/src/chat/messages.ts +1 -1
- package/src/chat/read-tool-group.ts +6 -4
- package/src/chat/skill-message.ts +6 -0
- package/src/chat/svg-figure.d.ts +33 -0
- package/src/chat/svg-figure.ts +399 -0
- package/src/chat/svg-source.d.ts +49 -0
- package/src/chat/svg-source.ts +188 -0
- package/src/chat/table-chart.d.ts +89 -0
- package/src/chat/table-chart.ts +294 -0
- package/src/chat/tool-execution.d.ts +2 -0
- package/src/chat/tool-execution.ts +80 -6
- package/src/chat/user-message.d.ts +15 -2
- package/src/chat/user-message.ts +55 -3
- package/src/chrome/shared.ts +53 -0
- package/src/chrome/transcript-container.d.ts +6 -0
- package/src/chrome/transcript-container.ts +93 -13
- package/src/components/box.d.ts +1 -0
- package/src/components/box.ts +5 -0
- package/src/components/disclosure.d.ts +1 -0
- package/src/components/disclosure.ts +8 -0
- package/src/components/editor.d.ts +15 -4
- package/src/components/editor.ts +294 -46
- package/src/components/form.d.ts +1 -0
- package/src/components/form.ts +8 -0
- package/src/components/image.d.ts +12 -44
- package/src/components/image.ts +47 -151
- package/src/components/key-value-list.d.ts +1 -0
- package/src/components/key-value-list.ts +4 -0
- package/src/components/layout/row.d.ts +1 -0
- package/src/components/layout/row.ts +7 -0
- package/src/components/layout/stack.d.ts +1 -0
- package/src/components/layout/stack.ts +7 -0
- package/src/components/markdown.d.ts +36 -3
- package/src/components/markdown.ts +433 -318
- package/src/components/scroll-view.d.ts +1 -0
- package/src/components/scroll-view.ts +5 -0
- package/src/components/section.d.ts +1 -0
- package/src/components/section.ts +5 -0
- package/src/components/settings-list.ts +2 -0
- package/src/components/table.d.ts +1 -0
- package/src/components/table.ts +4 -0
- package/src/components/text.d.ts +1 -0
- package/src/components/text.ts +7 -0
- package/src/components/tree-view.d.ts +7 -0
- package/src/components/tree-view.ts +38 -8
- package/src/components/truncated-text.d.ts +1 -0
- package/src/components/truncated-text.ts +5 -0
- package/src/desktop-notify.ts +1 -1
- package/src/fuzzy.d.ts +29 -1
- package/src/fuzzy.ts +115 -30
- package/src/key-hint-format.d.ts +1 -1
- package/src/key-hint-format.ts +1 -1
- package/src/keybinding-matchers.d.ts +3 -0
- package/src/keybinding-matchers.ts +6 -2
- package/src/keybindings.d.ts +1 -1
- package/src/keybindings.ts +1 -1
- package/src/kitty-graphics.d.ts +2 -2
- package/src/kitty-graphics.ts +4 -4
- package/src/loop-watchdog.d.ts +8 -7
- package/src/loop-watchdog.ts +18 -13
- package/src/multiplexers/cmux.d.ts +16 -0
- package/src/multiplexers/cmux.ts +29 -0
- package/src/multiplexers/herdr.d.ts +26 -0
- package/src/multiplexers/herdr.ts +64 -0
- package/src/multiplexers/notify.d.ts +13 -0
- package/src/multiplexers/notify.ts +24 -0
- package/src/multiplexers/orca.d.ts +12 -0
- package/src/multiplexers/orca.ts +16 -0
- package/src/multiplexers/screen.d.ts +9 -0
- package/src/multiplexers/screen.ts +15 -0
- package/src/multiplexers/tmux.d.ts +29 -0
- package/src/multiplexers/tmux.ts +40 -0
- package/src/multiplexers/types.d.ts +100 -0
- package/src/multiplexers/types.ts +110 -0
- package/src/multiplexers/wmux.d.ts +12 -0
- package/src/multiplexers/wmux.ts +16 -0
- package/src/multiplexers/zellij.d.ts +12 -0
- package/src/multiplexers/zellij.ts +24 -0
- package/src/native/backend.d.ts +3 -2
- package/src/native/backend.ts +174 -18
- package/src/native/blobs.d.ts +7 -3
- package/src/native/blobs.ts +47 -12
- package/src/native/encode.d.ts +3 -4
- package/src/native/encode.ts +58 -31
- package/src/native/overlay.d.ts +5 -0
- package/src/native/overlay.ts +13 -0
- package/src/native/reconcile.ts +4 -0
- package/src/overlays/agent-hub-projection.d.ts +6 -5
- package/src/overlays/agent-hub-projection.ts +124 -13
- package/src/overlays/agent-hub-types.d.ts +9 -0
- package/src/overlays/agent-hub-types.ts +6 -0
- package/src/overlays/agent-hub.ts +44 -29
- package/src/overlays/agent-transcript-viewer.ts +91 -23
- package/src/overlays/agents-hub.ts +28 -8
- package/src/overlays/annotation-overlay.ts +293 -90
- package/src/overlays/annotation-types.ts +2 -0
- package/src/overlays/ask-dialog.ts +7 -10
- package/src/overlays/btw-history-panel.ts +12 -1
- package/src/overlays/copy-selector.ts +30 -8
- package/src/overlays/extensions/state-manager.ts +52 -12
- package/src/overlays/history-search.ts +100 -7
- package/src/overlays/hook-selector.ts +12 -5
- package/src/overlays/jobs-panel.ts +28 -46
- package/src/overlays/model-browser.ts +341 -110
- package/src/overlays/model-hub.ts +300 -49
- package/src/overlays/move-overlay.ts +28 -14
- package/src/overlays/oauth-selector.ts +54 -70
- package/src/overlays/plan-review-overlay.ts +194 -70
- package/src/overlays/plugin-settings.ts +3 -3
- package/src/overlays/report-panel.ts +2 -2
- package/src/overlays/rewind-selector.ts +86 -17
- package/src/overlays/session-observer-registry.d.ts +2 -0
- package/src/overlays/session-observer-registry.ts +10 -2
- package/src/overlays/session-selector.ts +64 -26
- package/src/overlays/settings-defs.ts +4 -3
- package/src/overlays/settings-selector.ts +33 -8
- package/src/overlays/snapcompact-shape-preview.ts +2 -3
- package/src/overlays/stats-notice.ts +1 -1
- package/src/overlays/tree-selector.ts +41 -20
- package/src/overlays/usage-dashboard.ts +100 -50
- package/src/overlays/usage-display.ts +10 -4
- package/src/prompt/attachment-chips.ts +15 -11
- package/src/prompt/composer-attachments.ts +6 -4
- package/src/prompt/composer.ts +4 -15
- package/src/prompt/custom-editor.ts +54 -26
- package/src/prompt/image-source.ts +2 -1
- package/src/prompt/interactive-context-helpers.ts +30 -18
- package/src/prompt/macos-spelling.ts +7 -0
- package/src/prompt/magic-keywords.ts +11 -2
- package/src/prompt/model-mention-autocomplete.ts +14 -14
- package/src/prompt/tips.txt +6 -5
- package/src/prompt/welcome.ts +55 -12
- package/src/prompt/word-completion.ts +38 -5
- package/src/render/composite.d.ts +2 -0
- package/src/render/composite.ts +64 -0
- package/src/render/output-pane.d.ts +1 -0
- package/src/render/output-pane.ts +6 -0
- package/src/render/render-utils.d.ts +1 -0
- package/src/render/render-utils.ts +11 -0
- package/src/render/tool-card.d.ts +6 -0
- package/src/render/tool-card.ts +15 -0
- package/src/render/width-aware-text.d.ts +2 -0
- package/src/render/width-aware-text.ts +5 -0
- package/src/setup/scenes/model.ts +2 -1
- package/src/setup/scenes/types.ts +1 -0
- package/src/status-line/component.ts +292 -78
- package/src/status-line/host.ts +4 -1
- package/src/status-line/segments.ts +40 -22
- package/src/status-line/types.ts +15 -3
- package/src/terminal-capabilities.d.ts +27 -35
- package/src/terminal-capabilities.ts +75 -189
- package/src/terminal-multiplexer.d.ts +127 -14
- package/src/terminal-multiplexer.ts +112 -33
- package/src/terminal.d.ts +22 -6
- package/src/terminal.ts +139 -37
- package/src/theme/active-symbols.d.ts +1 -1
- package/src/theme/active-symbols.ts +1 -1
- package/src/theme/schema-validation.ts +1 -0
- package/src/theme/schema.d.ts +11 -2
- package/src/theme/schema.ts +14 -1
- package/src/theme/session-color.ts +1 -7
- package/src/theme/symbols.d.ts +1 -1
- package/src/theme/symbols.ts +6 -1
- package/src/theme/theme-class.d.ts +7 -0
- package/src/theme/theme-class.ts +26 -1
- package/src/theme/theme-schema.json +5 -1
- package/src/theme/theme.d.ts +1 -1
- package/src/theme/theme.ts +8 -4
- package/src/theme/tui-adapters.d.ts +3 -0
- package/src/theme/tui-adapters.ts +68 -0
- package/src/tmux.d.ts +11 -4
- package/src/tmux.ts +47 -11
- package/src/tools/ast-edit.ts +59 -35
- package/src/tools/ast-grep.ts +35 -16
- package/src/tools/bash.ts +92 -42
- package/src/tools/daemon.d.ts +1 -1
- package/src/tools/daemon.ts +1 -1
- package/src/tools/default-renderer.ts +35 -19
- package/src/tools/edit.ts +142 -120
- package/src/tools/eval-format/index.ts +28 -2
- package/src/tools/eval-format/javascript.ts +7 -5
- package/src/tools/eval.d.ts +22 -3
- package/src/tools/eval.ts +364 -208
- package/src/tools/fetch.ts +5 -6
- package/src/tools/glob.d.ts +4 -0
- package/src/tools/glob.ts +33 -65
- package/src/tools/grep.ts +81 -48
- package/src/tools/index.ts +2 -0
- package/src/tools/lsp.ts +81 -59
- package/src/tools/mcp.ts +111 -68
- package/src/tools/native-view.d.ts +47 -0
- package/src/tools/native-view.ts +102 -1
- package/src/tools/output-meta.d.ts +11 -1
- package/src/tools/output-meta.ts +23 -3
- package/src/tools/read.ts +7 -5
- package/src/tools/renderer.d.ts +37 -2
- package/src/tools/renderer.ts +42 -2
- package/src/tools/streaming-output.d.ts +20 -1
- package/src/tools/streaming-output.ts +149 -50
- package/src/tools/task.d.ts +0 -4
- package/src/tools/task.ts +112 -59
- package/src/tools/todo.ts +119 -30
- package/src/tools/wait.ts +34 -24
- package/src/tools/web-search.ts +1 -1
- package/src/tools/write.d.ts +9 -2
- package/src/tools/write.ts +147 -95
- package/src/tools/yield.d.ts +22 -0
- package/src/tools/yield.ts +225 -0
- package/src/tui.d.ts +31 -0
- package/src/tui.ts +309 -160
- package/src/utils.d.ts +6 -0
- package/src/utils.ts +19 -0
- package/src/vim.d.ts +19 -5
- package/src/vim.ts +333 -18
- package/src/windows-input-mode.ts +8 -0
package/src/tools/edit.ts
CHANGED
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
invalidateRenderedStringCache,
|
|
37
37
|
PREVIEW_LIMITS,
|
|
38
38
|
previewWindowRows,
|
|
39
|
+
releaseRenderedStringCache,
|
|
39
40
|
type RenderedStringCache,
|
|
40
41
|
replaceTabs,
|
|
41
42
|
shortenPath,
|
|
@@ -1110,41 +1111,49 @@ export const editToolRenderer = {
|
|
|
1110
1111
|
return renderInlineEditRow(uiTheme, { op, rename, rawPath, pending: true });
|
|
1111
1112
|
}
|
|
1112
1113
|
const callPreviewCaches: RenderedStringCache[] = [];
|
|
1113
|
-
return framedToolCard(
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1114
|
+
return framedToolCard(
|
|
1115
|
+
uiTheme,
|
|
1116
|
+
({ width }) => {
|
|
1117
|
+
// No status icon on the head row: it's the head of the framed block,
|
|
1118
|
+
// and native-scrollback commits are prefix-only — an animated glyph
|
|
1119
|
+
// would pin the commit boundary at the top, and the pending hourglass
|
|
1120
|
+
// just adds noise. The liveness cue rides the trailing "(preview)" /
|
|
1121
|
+
// "(streaming)" line instead.
|
|
1122
|
+
const header = renderEditHeader(width, uiTheme, {
|
|
1123
|
+
op,
|
|
1124
|
+
rawPath,
|
|
1125
|
+
rename,
|
|
1126
|
+
extraSuffix: fileCount > 1 ? uiTheme.fg("dim", ` (+${fileCount - 1} more)`) : undefined,
|
|
1127
|
+
});
|
|
1128
|
+
let body = getCallPreview(
|
|
1129
|
+
editArgs,
|
|
1130
|
+
rawPath,
|
|
1131
|
+
width,
|
|
1132
|
+
uiTheme,
|
|
1133
|
+
renderContext,
|
|
1134
|
+
options.expanded,
|
|
1135
|
+
options?.spinnerFrame,
|
|
1136
|
+
callPreviewCaches,
|
|
1137
|
+
);
|
|
1138
|
+
if (applyPatchError) {
|
|
1139
|
+
body += `\n${uiTheme.fg("error", truncateToWidth(replaceTabs(applyPatchError), Math.max(1, width - 2)))}`;
|
|
1140
|
+
}
|
|
1141
|
+
const bodyLines = body ? body.split("\n") : [];
|
|
1142
|
+
while (bodyLines.length > 0 && bodyLines[0].trim() === "") bodyLines.shift();
|
|
1143
|
+
return {
|
|
1144
|
+
header,
|
|
1145
|
+
sections: bodyLines.length > 0 ? [{ content: bodyLines }] : [],
|
|
1146
|
+
phase: applyPatchError ? "error" : "pending",
|
|
1147
|
+
borderColor: applyPatchError ? "error" : "borderMuted",
|
|
1148
|
+
contentPaddingLeft: 0,
|
|
1149
|
+
};
|
|
1150
|
+
},
|
|
1151
|
+
{
|
|
1152
|
+
onReleaseRenderCaches: () => {
|
|
1153
|
+
for (const cache of callPreviewCaches) releaseRenderedStringCache(cache);
|
|
1154
|
+
},
|
|
1155
|
+
},
|
|
1156
|
+
);
|
|
1148
1157
|
},
|
|
1149
1158
|
|
|
1150
1159
|
describeCall(
|
|
@@ -1452,74 +1461,54 @@ function renderSingleFileResult(
|
|
|
1452
1461
|
const renderedDiffCache = createRenderedStringCache();
|
|
1453
1462
|
const statsSuffixCache = createRenderedStringCache();
|
|
1454
1463
|
|
|
1455
|
-
return framedToolCard(
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
(editDiffPreview && "firstChangedLine" in editDiffPreview ? editDiffPreview.firstChangedLine : undefined) ||
|
|
1472
|
-
(details && !isError ? details.firstChangedLine : undefined);
|
|
1473
|
-
const linkPath = details && "path" in details ? details.path : undefined;
|
|
1474
|
-
|
|
1475
|
-
// Change stats ride inline on the header bar next to the path.
|
|
1476
|
-
const previewDiff = editDiffPreview && !("error" in editDiffPreview) ? editDiffPreview.diff : undefined;
|
|
1477
|
-
const headerDiff = isError ? undefined : details?.diff || previewDiff;
|
|
1478
|
-
const statsSuffix = headerDiff
|
|
1479
|
-
? cachedRenderedString(statsSuffixCache, uiTheme, false, "", headerDiff, () =>
|
|
1480
|
-
formatDiffStatsSuffix(headerDiff, uiTheme),
|
|
1481
|
-
)
|
|
1482
|
-
: "";
|
|
1483
|
-
const header = renderEditHeader(width, uiTheme, {
|
|
1484
|
-
icon: isError ? "error" : "success",
|
|
1485
|
-
iconOverride: !isError && !options.isPartial ? uiTheme.styledSymbol("tool.edit", "accent") : undefined,
|
|
1486
|
-
op,
|
|
1487
|
-
rawPath,
|
|
1488
|
-
rename,
|
|
1489
|
-
firstChangedLine,
|
|
1490
|
-
linkPath,
|
|
1491
|
-
statsSuffix,
|
|
1492
|
-
});
|
|
1493
|
-
const innerWidth = Math.max(1, width - 2);
|
|
1494
|
-
|
|
1495
|
-
let body = "";
|
|
1496
|
-
if (isError) {
|
|
1497
|
-
if (errorText) body = uiTheme.fg("error", replaceTabs(errorText));
|
|
1498
|
-
} else if (details?.diff) {
|
|
1499
|
-
body = renderDiffSection(
|
|
1500
|
-
details.diff,
|
|
1501
|
-
rawPath,
|
|
1502
|
-
expanded,
|
|
1503
|
-
innerWidth,
|
|
1504
|
-
uiTheme,
|
|
1505
|
-
renderDiffFn,
|
|
1506
|
-
renderedDiffCache,
|
|
1507
|
-
diffSectionCache,
|
|
1508
|
-
);
|
|
1509
|
-
} else if (details) {
|
|
1510
|
-
// Authoritative result with no textual diff: a delete, a move-only
|
|
1511
|
-
// rename, or a genuine no-op. The header already names the op
|
|
1512
|
-
// (Delete / `src → dst`); only a true no-op needs an explanatory
|
|
1513
|
-
// body so an empty card isn't mistaken for a stalled edit.
|
|
1514
|
-
if (op !== "delete" && op !== "create" && !rename) {
|
|
1515
|
-
const noChangePath = linkPath ? shortenPath(linkPath) : rawPath ? shortenPath(rawPath) : "";
|
|
1516
|
-
body = uiTheme.fg("dim", `No changes were made${noChangePath ? ` to ${noChangePath}` : ""}.`);
|
|
1464
|
+
return framedToolCard(
|
|
1465
|
+
uiTheme,
|
|
1466
|
+
({ width }) => {
|
|
1467
|
+
const { expanded, renderContext } = options;
|
|
1468
|
+
// A finalized result is authoritative: its `details` describe exactly
|
|
1469
|
+
// what happened. The shared streaming `editDiffPreview` is a call-phase
|
|
1470
|
+
// artifact (in a batch it reflects only the first file), so consulting it
|
|
1471
|
+
// for an empty-diff delete/move/no-op result mislabels the card. Fall
|
|
1472
|
+
// back to the preview only when no details exist yet.
|
|
1473
|
+
const editDiffPreview = details ? undefined : renderContext?.editDiffPreview;
|
|
1474
|
+
const renderDiffFn = renderContext?.renderDiff ?? renderFallbackDiff;
|
|
1475
|
+
|
|
1476
|
+
if (diffSectionRenderDiffFn !== renderDiffFn) {
|
|
1477
|
+
diffSectionRenderDiffFn = renderDiffFn;
|
|
1478
|
+
invalidateRenderedStringCache(diffSectionCache);
|
|
1479
|
+
invalidateRenderedStringCache(renderedDiffCache);
|
|
1517
1480
|
}
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1481
|
+
const firstChangedLine =
|
|
1482
|
+
(editDiffPreview && "firstChangedLine" in editDiffPreview ? editDiffPreview.firstChangedLine : undefined) ||
|
|
1483
|
+
(details && !isError ? details.firstChangedLine : undefined);
|
|
1484
|
+
const linkPath = details && "path" in details ? details.path : undefined;
|
|
1485
|
+
|
|
1486
|
+
// Change stats ride inline on the header bar next to the path.
|
|
1487
|
+
const previewDiff = editDiffPreview && !("error" in editDiffPreview) ? editDiffPreview.diff : undefined;
|
|
1488
|
+
const headerDiff = isError ? undefined : details?.diff || previewDiff;
|
|
1489
|
+
const statsSuffix = headerDiff
|
|
1490
|
+
? cachedRenderedString(statsSuffixCache, uiTheme, false, "", headerDiff, () =>
|
|
1491
|
+
formatDiffStatsSuffix(headerDiff, uiTheme),
|
|
1492
|
+
)
|
|
1493
|
+
: "";
|
|
1494
|
+
const header = renderEditHeader(width, uiTheme, {
|
|
1495
|
+
icon: isError ? "error" : "success",
|
|
1496
|
+
iconOverride: !isError && !options.isPartial ? uiTheme.styledSymbol("tool.edit", "accent") : undefined,
|
|
1497
|
+
op,
|
|
1498
|
+
rawPath,
|
|
1499
|
+
rename,
|
|
1500
|
+
firstChangedLine,
|
|
1501
|
+
linkPath,
|
|
1502
|
+
statsSuffix,
|
|
1503
|
+
});
|
|
1504
|
+
const innerWidth = Math.max(1, width - 2);
|
|
1505
|
+
|
|
1506
|
+
let body = "";
|
|
1507
|
+
if (isError) {
|
|
1508
|
+
if (errorText) body = uiTheme.fg("error", replaceTabs(errorText));
|
|
1509
|
+
} else if (details?.diff) {
|
|
1521
1510
|
body = renderDiffSection(
|
|
1522
|
-
|
|
1511
|
+
details.diff,
|
|
1523
1512
|
rawPath,
|
|
1524
1513
|
expanded,
|
|
1525
1514
|
innerWidth,
|
|
@@ -1528,27 +1517,56 @@ function renderSingleFileResult(
|
|
|
1528
1517
|
renderedDiffCache,
|
|
1529
1518
|
diffSectionCache,
|
|
1530
1519
|
);
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1520
|
+
} else if (details) {
|
|
1521
|
+
// Authoritative result with no textual diff: a delete, a move-only
|
|
1522
|
+
// rename, or a genuine no-op. The header already names the op
|
|
1523
|
+
// (Delete / `src → dst`); only a true no-op needs an explanatory
|
|
1524
|
+
// body so an empty card isn't mistaken for a stalled edit.
|
|
1525
|
+
if (op !== "delete" && op !== "create" && !rename) {
|
|
1526
|
+
const noChangePath = linkPath ? shortenPath(linkPath) : rawPath ? shortenPath(rawPath) : "";
|
|
1527
|
+
body = uiTheme.fg("dim", `No changes were made${noChangePath ? ` to ${noChangePath}` : ""}.`);
|
|
1528
|
+
}
|
|
1529
|
+
} else if (editDiffPreview) {
|
|
1530
|
+
if ("error" in editDiffPreview) body = uiTheme.fg("error", replaceTabs(editDiffPreview.error));
|
|
1531
|
+
else if (editDiffPreview.diff)
|
|
1532
|
+
body = renderDiffSection(
|
|
1533
|
+
editDiffPreview.diff,
|
|
1534
|
+
rawPath,
|
|
1535
|
+
expanded,
|
|
1536
|
+
innerWidth,
|
|
1537
|
+
uiTheme,
|
|
1538
|
+
renderDiffFn,
|
|
1539
|
+
renderedDiffCache,
|
|
1540
|
+
diffSectionCache,
|
|
1541
|
+
);
|
|
1542
|
+
}
|
|
1543
|
+
if (details?.diagnostics) {
|
|
1544
|
+
body += formatDiagnostics(details.diagnostics, expanded, uiTheme, (fp: string) =>
|
|
1545
|
+
uiTheme.getLangIcon(getLanguageFromPath(fp)),
|
|
1546
|
+
);
|
|
1547
|
+
}
|
|
1537
1548
|
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1549
|
+
// Diff lines self-wrap with a continuation gutter; pre-wrap to the frame's
|
|
1550
|
+
// inner width so renderOutputBlock's generic wrap is a no-op. Edit frames
|
|
1551
|
+
// use a flush left border because code-frame gutters already provide padding.
|
|
1552
|
+
const bodyLines =
|
|
1553
|
+
body.length > 0 ? body.split("\n").flatMap(line => wrapEditRendererLine(line, innerWidth)) : [];
|
|
1554
|
+
while (bodyLines.length > 0 && bodyLines[0].trim() === "") bodyLines.shift();
|
|
1543
1555
|
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1556
|
+
return {
|
|
1557
|
+
header,
|
|
1558
|
+
sections: bodyLines.length > 0 ? [{ content: bodyLines }] : [],
|
|
1559
|
+
phase: isError ? "error" : options.isPartial ? "partial" : "success",
|
|
1560
|
+
borderColor: isError ? "error" : "borderMuted",
|
|
1561
|
+
contentPaddingLeft: 0,
|
|
1562
|
+
};
|
|
1563
|
+
},
|
|
1564
|
+
{
|
|
1565
|
+
// Only the width-keyed diff section goes; the highlighted diff and stats suffix do not depend on width, and
|
|
1566
|
+
// re-highlighting every committed card on each resize replay costs seconds.
|
|
1567
|
+
onReleaseRenderCaches: () => releaseRenderedStringCache(diffSectionCache),
|
|
1568
|
+
},
|
|
1569
|
+
);
|
|
1552
1570
|
}
|
|
1553
1571
|
|
|
1554
1572
|
function renderMultiFileResult(
|
|
@@ -1603,5 +1621,9 @@ function renderMultiFileResult(
|
|
|
1603
1621
|
cached = undefined;
|
|
1604
1622
|
for (const c of fileComponents) c.invalidate?.();
|
|
1605
1623
|
},
|
|
1624
|
+
releaseRenderCaches() {
|
|
1625
|
+
cached = undefined;
|
|
1626
|
+
for (const c of fileComponents) c.releaseRenderCaches?.();
|
|
1627
|
+
},
|
|
1606
1628
|
};
|
|
1607
1629
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LRUCache } from "@linxiraos/pi-utils/lru";
|
|
1
2
|
import type { EvalLanguage } from "../eval";
|
|
2
3
|
import { formatJavaScriptForDisplay } from "./javascript";
|
|
3
4
|
import { formatPythonForDisplay } from "./python";
|
|
@@ -5,13 +6,38 @@ import { formatPythonForDisplay } from "./python";
|
|
|
5
6
|
export * from "./javascript";
|
|
6
7
|
export * from "./python";
|
|
7
8
|
|
|
9
|
+
function createDisplayFormatMemo(): LRUCache<string, string> {
|
|
10
|
+
return new LRUCache<string, string>({
|
|
11
|
+
max: 64,
|
|
12
|
+
maxSize: 4_000_000,
|
|
13
|
+
// LRUCache rejects sizes <= 0; empty sources (cells not yet streamed) still cost one.
|
|
14
|
+
sizeCalculation: (formatted, source) => formatted.length + source.length + 1,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Formatted display text keyed by source, one memo per formatter. Renderers
|
|
20
|
+
* reformat every cell on each streamed argument delta and result update; the
|
|
21
|
+
* memo keeps that linear in the changed cell instead of the whole call.
|
|
22
|
+
*/
|
|
23
|
+
const jsDisplayMemo = createDisplayFormatMemo();
|
|
24
|
+
const pythonDisplayMemo = createDisplayFormatMemo();
|
|
25
|
+
|
|
8
26
|
/** Formats an arbitrary eval-code prefix for display without changing the executed source. */
|
|
9
27
|
export function formatEvalCodeForDisplay(source: string, language: EvalLanguage): string {
|
|
10
28
|
if (/^\s*%/.test(source)) return source;
|
|
11
29
|
switch (language) {
|
|
12
30
|
case "js":
|
|
13
|
-
return
|
|
31
|
+
return memoizedFormat(jsDisplayMemo, source, formatJavaScriptForDisplay);
|
|
14
32
|
case "python":
|
|
15
|
-
return
|
|
33
|
+
return memoizedFormat(pythonDisplayMemo, source, formatPythonForDisplay);
|
|
16
34
|
}
|
|
17
35
|
}
|
|
36
|
+
|
|
37
|
+
function memoizedFormat(memo: LRUCache<string, string>, source: string, format: (source: string) => string): string {
|
|
38
|
+
const cached = memo.get(source);
|
|
39
|
+
if (cached !== undefined) return cached;
|
|
40
|
+
const formatted = format(source);
|
|
41
|
+
memo.set(source, formatted);
|
|
42
|
+
return formatted;
|
|
43
|
+
}
|
|
@@ -249,7 +249,9 @@ interface DisplayBraceNode {
|
|
|
249
249
|
|
|
250
250
|
function classifySourceBraces(source: string): boolean[] {
|
|
251
251
|
const objects: boolean[] = [];
|
|
252
|
-
|
|
252
|
+
// Whether the current statement has seen `class`/`function`/`switch`, whose
|
|
253
|
+
// next `{` opens a block. A flag instead of a word list keeps each brace O(1).
|
|
254
|
+
let statementDeclaresBlock = false;
|
|
253
255
|
let previousToken = "";
|
|
254
256
|
let previousWord = "";
|
|
255
257
|
let regexAllowed = true;
|
|
@@ -287,7 +289,7 @@ function classifySourceBraces(source: string): boolean[] {
|
|
|
287
289
|
if (isIdentifierStart(char)) {
|
|
288
290
|
const end = scanIdentifier(source, index);
|
|
289
291
|
const word = source.slice(index, end);
|
|
290
|
-
|
|
292
|
+
if (word === "class" || word === "function" || word === "switch") statementDeclaresBlock = true;
|
|
291
293
|
previousWord = word;
|
|
292
294
|
previousToken = word;
|
|
293
295
|
regexAllowed = REGEX_PREFIX_WORDS[word] === true;
|
|
@@ -307,7 +309,7 @@ function classifySourceBraces(source: string): boolean[] {
|
|
|
307
309
|
previousToken === ")" ||
|
|
308
310
|
previousToken === "}" ||
|
|
309
311
|
BLOCK_BRACE_WORDS[previousWord] === true ||
|
|
310
|
-
|
|
312
|
+
statementDeclaresBlock;
|
|
311
313
|
const isObject =
|
|
312
314
|
!isBlock &&
|
|
313
315
|
(previousToken === "=" ||
|
|
@@ -319,7 +321,7 @@ function classifySourceBraces(source: string): boolean[] {
|
|
|
319
321
|
previousToken === "" ||
|
|
320
322
|
OBJECT_PREFIX_WORDS[previousWord] === true);
|
|
321
323
|
objects.push(isObject);
|
|
322
|
-
if (isBlock)
|
|
324
|
+
if (isBlock) statementDeclaresBlock = false;
|
|
323
325
|
previousToken = "{";
|
|
324
326
|
previousWord = "";
|
|
325
327
|
regexAllowed = true;
|
|
@@ -334,7 +336,7 @@ function classifySourceBraces(source: string): boolean[] {
|
|
|
334
336
|
continue;
|
|
335
337
|
}
|
|
336
338
|
if (char === ";") {
|
|
337
|
-
|
|
339
|
+
statementDeclaresBlock = false;
|
|
338
340
|
previousToken = ";";
|
|
339
341
|
previousWord = "";
|
|
340
342
|
regexAllowed = true;
|
package/src/tools/eval.d.ts
CHANGED
|
@@ -24,6 +24,8 @@ export interface EvalCellResult {
|
|
|
24
24
|
durationMs?: number;
|
|
25
25
|
exitCode?: number;
|
|
26
26
|
statusEvents?: EvalStatusEvent[];
|
|
27
|
+
/** Discrete events dropped from the front of `statusEvents` (see {@link recordStatusEvent}). */
|
|
28
|
+
statusEventsElided?: number;
|
|
27
29
|
hasMarkdown?: boolean;
|
|
28
30
|
}
|
|
29
31
|
/** Tool result detail object surfaced to the UI/transcript. */
|
|
@@ -32,6 +34,8 @@ export interface EvalToolDetails {
|
|
|
32
34
|
jsonOutputs?: unknown[];
|
|
33
35
|
images?: ImageContent[];
|
|
34
36
|
statusEvents?: EvalStatusEvent[];
|
|
37
|
+
/** Discrete events dropped from the front of `statusEvents` (see {@link recordStatusEvent}). */
|
|
38
|
+
statusEventsElided?: number;
|
|
35
39
|
isError?: boolean;
|
|
36
40
|
meta?: OutputMeta;
|
|
37
41
|
/** First backend that produced cells. Kept for transcript compatibility. */
|
|
@@ -74,13 +78,28 @@ export declare function statusEventKey(event: {
|
|
|
74
78
|
op: string;
|
|
75
79
|
[key: string]: unknown;
|
|
76
80
|
}): string | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Discrete status events a log keeps. A cell polling a helper in a loop emits
|
|
83
|
+
* one event per call (hundreds of thousands), and every live update and the
|
|
84
|
+
* persisted tool result would otherwise carry them all.
|
|
85
|
+
*/
|
|
86
|
+
export declare const MAX_STATUS_EVENTS = 200;
|
|
87
|
+
/** A status event list plus the count of discrete events dropped from its front. */
|
|
88
|
+
export type StatusEventLog = Pick<EvalCellResult, "statusEvents" | "statusEventsElided">;
|
|
77
89
|
/**
|
|
78
90
|
* Append or replace a status event. Progress snapshots (see
|
|
79
91
|
* {@link statusEventKey}) coalesce in place, preserving first-seen order; every
|
|
80
|
-
* other op is a discrete action and simply appends.
|
|
81
|
-
* list bounded even when a subagent or batch emits hundreds of progress ticks.
|
|
92
|
+
* other op is a discrete action and simply appends.
|
|
82
93
|
*/
|
|
83
94
|
export declare function upsertStatusEvent(events: EvalStatusEvent[], event: EvalStatusEvent): void;
|
|
95
|
+
/**
|
|
96
|
+
* {@link upsertStatusEvent} into a bounded log. Past {@link MAX_STATUS_EVENTS},
|
|
97
|
+
* the oldest discrete event is dropped and counted. Snapshots stay, since agent
|
|
98
|
+
* cards read them, and so does the newest committed `todo` result, which the
|
|
99
|
+
* session todo panel refreshes from. Renderers already show only the newest
|
|
100
|
+
* events behind an "… N earlier" row.
|
|
101
|
+
*/
|
|
102
|
+
export declare function recordStatusEvent(log: StatusEventLog, event: EvalStatusEvent): void;
|
|
84
103
|
/** Render eval code cells, structured display output, and progress events. */
|
|
85
104
|
export declare const evalToolRenderer: {
|
|
86
105
|
animatedPendingPreview: true;
|
|
@@ -95,7 +114,7 @@ export declare const evalToolRenderer: {
|
|
|
95
114
|
}, options: RenderResultOptions & {
|
|
96
115
|
renderContext?: EvalRenderContext;
|
|
97
116
|
}, uiTheme: Theme, _args?: EvalRenderArgs): Component;
|
|
98
|
-
describeCall(args: EvalRenderArgs,
|
|
117
|
+
describeCall(args: EvalRenderArgs, options: RenderResultOptions): NativeToolView;
|
|
99
118
|
describeResult(result: {
|
|
100
119
|
content: Array<{
|
|
101
120
|
type: string;
|