@oh-my-pi/pi-tui 18.4.2 → 18.4.4
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 +56 -0
- package/dist/types/apps/cleanse-board.d.ts +17 -0
- package/dist/types/apps/git/help.d.ts +16 -0
- package/dist/types/apps/git/sidebar.d.ts +18 -0
- package/dist/types/apps/live-visualizer.d.ts +10 -0
- package/dist/types/apps/ps-top.d.ts +15 -0
- package/dist/types/apps/standalone-picker.d.ts +3 -0
- package/dist/types/autocomplete.d.ts +8 -0
- package/dist/types/chat/advisor-message.d.ts +12 -2
- package/dist/types/chat/assistant-message.d.ts +20 -0
- package/dist/types/chat/bash-execution.d.ts +9 -0
- package/dist/types/chat/chat-transcript-builder.d.ts +6 -1
- package/dist/types/chat/collab-prompt-message.d.ts +4 -0
- package/dist/types/chat/compaction-summary-message.d.ts +15 -0
- package/dist/types/chat/eval-execution.d.ts +8 -0
- package/dist/types/chat/execution-shared.d.ts +58 -0
- package/dist/types/chat/late-diagnostics-message.d.ts +15 -1
- package/dist/types/chat/read-tool-group.d.ts +15 -0
- package/dist/types/chat/skill-message.d.ts +9 -0
- package/dist/types/chat/stripped-tool-calls-placeholder.d.ts +3 -0
- package/dist/types/chat/thinking-display.d.ts +2 -0
- package/dist/types/chat/todo-reminder.d.ts +4 -1
- package/dist/types/chat/tool-execution.d.ts +25 -1
- package/dist/types/chat/transcript-actions.d.ts +37 -0
- package/dist/types/chat/transcript-entry.d.ts +3 -1
- package/dist/types/chat/user-message.d.ts +25 -0
- package/dist/types/chrome/collab-qrcode.d.ts +7 -0
- package/dist/types/chrome/context-thresholds.d.ts +11 -0
- package/dist/types/chrome/countdown-timer.d.ts +9 -3
- package/dist/types/chrome/diff.d.ts +12 -0
- package/dist/types/chrome/dynamic-border.d.ts +3 -0
- package/dist/types/chrome/format.d.ts +6 -0
- package/dist/types/chrome/message-divider.d.ts +13 -0
- package/dist/types/chrome/message-frame.d.ts +10 -0
- package/dist/types/chrome/message-notice.d.ts +23 -0
- package/dist/types/chrome/overlay-box.d.ts +11 -2
- package/dist/types/chrome/qrcode.d.ts +7 -0
- package/dist/types/chrome/segment-track.d.ts +7 -0
- package/dist/types/chrome/selector-helpers.d.ts +0 -6
- package/dist/types/chrome/status-notice.d.ts +14 -0
- package/dist/types/chrome/streaming-panel.d.ts +3 -0
- package/dist/types/chrome/tool-activity.d.ts +3 -0
- package/dist/types/chrome/transcript-container.d.ts +13 -0
- package/dist/types/chrome/transcript-status.d.ts +15 -3
- package/dist/types/components/box.d.ts +7 -0
- package/dist/types/components/disclosure.d.ts +9 -0
- package/dist/types/components/editor.d.ts +42 -0
- package/dist/types/components/form.d.ts +14 -0
- package/dist/types/components/image.d.ts +7 -0
- package/dist/types/components/input.d.ts +20 -1
- package/dist/types/components/key-value-list.d.ts +3 -0
- package/dist/types/components/layout/geometry.d.ts +16 -0
- package/dist/types/components/layout/row.d.ts +7 -0
- package/dist/types/components/layout/split-pane.d.ts +8 -0
- package/dist/types/components/layout/stack.d.ts +6 -0
- package/dist/types/components/loader.d.ts +48 -0
- package/dist/types/components/markdown.d.ts +8 -0
- package/dist/types/components/metric.d.ts +7 -0
- package/dist/types/components/progress-bar.d.ts +3 -0
- package/dist/types/components/scroll-view.d.ts +6 -0
- package/dist/types/components/section.d.ts +3 -0
- package/dist/types/components/select-list.d.ts +33 -0
- package/dist/types/components/settings-list.d.ts +68 -0
- package/dist/types/components/spacer.d.ts +4 -0
- package/dist/types/components/tab-bar.d.ts +9 -0
- package/dist/types/components/table.d.ts +7 -0
- package/dist/types/components/text.d.ts +6 -0
- package/dist/types/components/tree-view.d.ts +9 -0
- package/dist/types/components/truncated-text.d.ts +3 -0
- package/dist/types/components/wizard-step.d.ts +6 -0
- package/dist/types/hotkeys-markdown.d.ts +24 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/latex-block.d.ts +7 -0
- package/dist/types/loop-watchdog.d.ts +9 -0
- package/dist/types/native/apply.d.ts +39 -0
- package/dist/types/native/backend.d.ts +94 -0
- package/dist/types/native/blobs.d.ts +29 -0
- package/dist/types/native/describe.d.ts +56 -0
- package/dist/types/native/encode.d.ts +50 -0
- package/dist/types/native/icons.d.ts +18 -0
- package/dist/types/native/memo.d.ts +27 -0
- package/dist/types/native/node.d.ts +107 -0
- package/dist/types/native/overlay.d.ts +64 -0
- package/dist/types/native/picker.d.ts +124 -0
- package/dist/types/native/reconcile.d.ts +41 -0
- package/dist/types/native/settle.d.ts +11 -0
- package/dist/types/native/spans.d.ts +21 -0
- package/dist/types/native/state.d.ts +6 -0
- package/dist/types/native/tone.d.ts +24 -0
- package/dist/types/overlays/advisor-config.d.ts +20 -0
- package/dist/types/overlays/agent-hub-renderer.d.ts +27 -11
- package/dist/types/overlays/agent-hub.d.ts +10 -0
- package/dist/types/overlays/agent-transcript-viewer.d.ts +7 -0
- package/dist/types/overlays/agents-hub.d.ts +8 -0
- package/dist/types/overlays/annotation-overlay.d.ts +3 -0
- package/dist/types/overlays/ask-dialog.d.ts +23 -0
- package/dist/types/overlays/bordered-loader.d.ts +3 -0
- package/dist/types/overlays/btw-history-panel.d.ts +9 -0
- package/dist/types/overlays/btw-panel.d.ts +3 -0
- package/dist/types/overlays/cleanse-panel.d.ts +5 -2
- package/dist/types/overlays/composer-shape-preview.d.ts +7 -1
- package/dist/types/overlays/copy-selector.d.ts +38 -0
- package/dist/types/overlays/error-banner.d.ts +9 -0
- package/dist/types/overlays/extensions/extension-list.d.ts +1 -0
- package/dist/types/overlays/history-search.d.ts +18 -0
- package/dist/types/overlays/hook-editor.d.ts +28 -1
- package/dist/types/overlays/hook-input.d.ts +3 -0
- package/dist/types/overlays/hook-selector.d.ts +10 -0
- package/dist/types/overlays/hub-frame.d.ts +18 -0
- package/dist/types/overlays/jobs-panel.d.ts +24 -0
- package/dist/types/overlays/login-dialog.d.ts +10 -0
- package/dist/types/overlays/logout-account-selector.d.ts +4 -0
- package/dist/types/overlays/mcp-add-wizard.d.ts +4 -0
- package/dist/types/overlays/model-browser.d.ts +69 -0
- package/dist/types/overlays/model-hub.d.ts +7 -0
- package/dist/types/overlays/model-picker.d.ts +9 -1
- package/dist/types/overlays/move-overlay.d.ts +3 -0
- package/dist/types/overlays/oauth-selector.d.ts +4 -0
- package/dist/types/overlays/omfg-panel.d.ts +3 -0
- package/dist/types/overlays/pause-screen.d.ts +12 -0
- package/dist/types/overlays/plan-review-overlay.d.ts +5 -0
- package/dist/types/overlays/plan-save-overlay.d.ts +10 -0
- package/dist/types/overlays/plugin-selector.d.ts +4 -0
- package/dist/types/overlays/plugin-settings.d.ts +30 -0
- package/dist/types/overlays/queue-mode-selector.d.ts +4 -0
- package/dist/types/overlays/reset-usage-selector.d.ts +8 -0
- package/dist/types/overlays/rewind-selector.d.ts +5 -0
- package/dist/types/overlays/session-info-overlay.d.ts +19 -1
- package/dist/types/overlays/session-selector.d.ts +64 -1
- package/dist/types/overlays/settings-defs.d.ts +14 -0
- package/dist/types/overlays/settings-selector.d.ts +21 -0
- package/dist/types/overlays/show-images-selector.d.ts +4 -0
- package/dist/types/overlays/snapcompact-shape-preview.d.ts +2 -0
- package/dist/types/overlays/stats-notice.d.ts +8 -0
- package/dist/types/overlays/theme-selector.d.ts +11 -0
- package/dist/types/overlays/thinking-selector.d.ts +4 -0
- package/dist/types/overlays/tree-selector.d.ts +60 -2
- package/dist/types/overlays/usage-dashboard.d.ts +26 -3
- package/dist/types/overlays/usage-row.d.ts +36 -2
- package/dist/types/prompt/attachment-chips.d.ts +8 -0
- package/dist/types/prompt/composer-attachments.d.ts +15 -3
- package/dist/types/prompt/composer.d.ts +18 -1
- package/dist/types/prompt/custom-editor.d.ts +48 -2
- package/dist/types/prompt/editor-top-gap.d.ts +2 -0
- package/dist/types/prompt/macos-spelling.d.ts +6 -0
- package/dist/types/prompt/magic-keywords.d.ts +9 -0
- package/dist/types/prompt/queued-messages.d.ts +23 -0
- package/dist/types/prompt/skill-tokens.d.ts +4 -2
- package/dist/types/prompt/welcome.d.ts +16 -0
- package/dist/types/render/code-cell.d.ts +10 -0
- package/dist/types/render/file-list.d.ts +8 -0
- package/dist/types/render/hyperlink.d.ts +14 -0
- package/dist/types/render/output-block.d.ts +43 -0
- package/dist/types/render/output-pane.d.ts +17 -0
- package/dist/types/render/tool-card.d.ts +8 -0
- package/dist/types/render/tree-list.d.ts +8 -0
- package/dist/types/render/width-aware-text.d.ts +7 -0
- package/dist/types/setup/scenes/outro.d.ts +7 -0
- package/dist/types/setup/scenes/sign-in.d.ts +16 -9
- package/dist/types/setup/scenes/splash.d.ts +8 -0
- package/dist/types/setup/scenes/types.d.ts +6 -27
- package/dist/types/setup/wizard-overlay.d.ts +9 -0
- package/dist/types/status-line/component.d.ts +49 -5
- package/dist/types/status-line/context-usage.d.ts +20 -0
- package/dist/types/status-line/footer.d.ts +8 -0
- package/dist/types/status-line/metrics.d.ts +1 -2
- package/dist/types/status-line/segments.d.ts +10 -1
- package/dist/types/status-line/types.d.ts +40 -1
- package/dist/types/stdin-buffer.d.ts +10 -7
- package/dist/types/terminal-capabilities.d.ts +1 -1
- package/dist/types/terminal.d.ts +36 -0
- package/dist/types/theme/defaults/index.d.ts +100 -0
- package/dist/types/theme/schema.d.ts +2 -0
- package/dist/types/theme/shimmer.d.ts +8 -0
- package/dist/types/theme/theme-class.d.ts +2 -0
- package/dist/types/theme/theme.d.ts +33 -1
- package/dist/types/tools/ask.d.ts +3 -0
- package/dist/types/tools/ast-edit.d.ts +10 -1
- package/dist/types/tools/ast-grep.d.ts +10 -1
- package/dist/types/tools/autoresearch.d.ts +21 -4
- package/dist/types/tools/bash.d.ts +30 -1
- package/dist/types/tools/cfg-render.d.ts +5 -1
- package/dist/types/tools/debug.d.ts +3 -1
- package/dist/types/tools/default-renderer.d.ts +6 -1
- package/dist/types/tools/edit.d.ts +14 -1
- package/dist/types/tools/eval.d.ts +12 -1
- package/dist/types/tools/fetch.d.ts +16 -1
- package/dist/types/tools/find.d.ts +15 -1
- package/dist/types/tools/github.d.ts +3 -0
- package/dist/types/tools/glob.d.ts +14 -1
- package/dist/types/tools/goal.d.ts +3 -1
- package/dist/types/tools/grep.d.ts +14 -1
- package/dist/types/tools/grouped-file-output.d.ts +58 -0
- package/dist/types/tools/json-tree.d.ts +20 -0
- package/dist/types/tools/lsp.d.ts +3 -10
- package/dist/types/tools/mcp.d.ts +16 -1
- package/dist/types/tools/memory.d.ts +26 -0
- package/dist/types/tools/native-view.d.ts +90 -0
- package/dist/types/tools/proc-render.d.ts +7 -1
- package/dist/types/tools/read.d.ts +23 -1
- package/dist/types/tools/renderer.d.ts +57 -0
- package/dist/types/tools/report-tool-issue.d.ts +3 -0
- package/dist/types/tools/resolve.d.ts +14 -1
- package/dist/types/tools/task.d.ts +3 -0
- package/dist/types/tools/think.d.ts +3 -0
- package/dist/types/tools/todo.d.ts +12 -0
- package/dist/types/tools/vibe.d.ts +3 -1
- package/dist/types/tools/wait.d.ts +3 -0
- package/dist/types/tools/web-search-types.d.ts +90 -0
- package/dist/types/tools/web-search.d.ts +9 -168
- package/dist/types/tools/write.d.ts +14 -1
- package/dist/types/tools/xdev.d.ts +13 -0
- package/dist/types/tui.d.ts +49 -0
- package/package.json +9 -9
- package/src/apps/autoresearch-dashboard.ts +362 -4
- package/src/apps/cleanse-board.ts +219 -1
- package/src/apps/cleanse-picker.ts +9 -1
- package/src/apps/debug/log-viewer.ts +15 -15
- package/src/apps/debug/protocol-probe.ts +2 -20
- package/src/apps/git/avatar.ts +2 -22
- package/src/apps/git/git-tui.ts +406 -59
- package/src/apps/git/help.ts +130 -0
- package/src/apps/git/sidebar.ts +491 -0
- package/src/apps/live-visualizer.ts +65 -0
- package/src/apps/ps-top.ts +448 -17
- package/src/apps/session-picker.ts +1 -0
- package/src/apps/setup-model-picker.ts +5 -1
- package/src/apps/standalone-picker.ts +55 -1
- package/src/autocomplete.ts +44 -1
- package/src/chat/advisor-message.ts +72 -3
- package/src/chat/assistant-message.ts +538 -51
- package/src/chat/background-tan-message.ts +4 -4
- package/src/chat/bash-execution.ts +81 -0
- package/src/chat/cache-invalidation-marker.ts +8 -0
- package/src/chat/chat-transcript-builder.ts +37 -6
- package/src/chat/collab-prompt-message.ts +15 -3
- package/src/chat/compaction-summary-message.ts +74 -1
- package/src/chat/custom-message.ts +3 -1
- package/src/chat/eval-execution.ts +57 -0
- package/src/chat/execution-shared.ts +153 -1
- package/src/chat/hook-message.ts +1 -0
- package/src/chat/late-diagnostics-message.ts +85 -2
- package/src/chat/read-tool-group.ts +341 -1
- package/src/chat/served-model-marker.ts +8 -0
- package/src/chat/skill-message.ts +63 -0
- package/src/chat/stripped-tool-calls-placeholder.ts +18 -10
- package/src/chat/thinking-display.ts +73 -11
- package/src/chat/todo-reminder.ts +34 -4
- package/src/chat/tool-execution.ts +385 -10
- package/src/chat/transcript-actions.ts +38 -0
- package/src/chat/transcript-browser.ts +2 -9
- package/src/chat/transcript-entry.ts +10 -1
- package/src/chat/transcript-render-helpers.ts +16 -15
- package/src/chat/ttsr-notification.ts +38 -1
- package/src/chat/user-message.ts +167 -4
- package/src/chrome/collab-qrcode.ts +27 -2
- package/src/chrome/context-thresholds.ts +34 -0
- package/src/chrome/countdown-timer.ts +24 -1
- package/src/chrome/diff.ts +60 -1
- package/src/chrome/dynamic-border.ts +7 -0
- package/src/chrome/format.ts +12 -0
- package/src/chrome/message-divider.ts +33 -1
- package/src/chrome/message-frame.ts +53 -10
- package/src/chrome/message-notice.ts +71 -0
- package/src/chrome/overlay-box.ts +45 -2
- package/src/chrome/qrcode.ts +28 -0
- package/src/chrome/segment-track.ts +26 -0
- package/src/chrome/selector-helpers.ts +1 -17
- package/src/chrome/status-notice.ts +46 -0
- package/src/chrome/streaming-panel.ts +25 -1
- package/src/chrome/tool-activity.ts +20 -0
- package/src/chrome/transcript-container.ts +139 -17
- package/src/chrome/transcript-status.ts +40 -11
- package/src/components/box.ts +51 -0
- package/src/components/disclosure.ts +33 -0
- package/src/components/editor.ts +239 -36
- package/src/components/form.ts +93 -9
- package/src/components/image.ts +30 -0
- package/src/components/input.ts +77 -26
- package/src/components/key-value-list.ts +18 -0
- package/src/components/layout/geometry.ts +44 -0
- package/src/components/layout/row.ts +30 -0
- package/src/components/layout/split-pane.ts +65 -0
- package/src/components/layout/stack.ts +27 -0
- package/src/components/loader.ts +183 -1
- package/src/components/markdown.ts +131 -56
- package/src/components/metric.ts +39 -0
- package/src/components/progress-bar.ts +28 -0
- package/src/components/scroll-view.ts +23 -0
- package/src/components/section.ts +16 -0
- package/src/components/select-list.ts +174 -25
- package/src/components/settings-list.ts +264 -7
- package/src/components/spacer.ts +17 -0
- package/src/components/tab-bar.ts +42 -0
- package/src/components/table.ts +34 -0
- package/src/components/text.ts +23 -0
- package/src/components/tree-view.ts +65 -0
- package/src/components/truncated-text.ts +14 -0
- package/src/components/wizard-step.ts +18 -9
- package/src/debug-server.ts +14 -7
- package/src/hotkeys-markdown.ts +251 -69
- package/src/index.ts +6 -0
- package/src/latex-block.ts +11 -0
- package/src/loop-watchdog.ts +38 -10
- package/src/native/apply.ts +275 -0
- package/src/native/backend.ts +682 -0
- package/src/native/blobs.ts +70 -0
- package/src/native/describe.ts +124 -0
- package/src/native/encode.ts +233 -0
- package/src/native/icons.ts +184 -0
- package/src/native/memo.ts +64 -0
- package/src/native/node.ts +112 -0
- package/src/native/overlay.ts +131 -0
- package/src/native/picker.ts +333 -0
- package/src/native/reconcile.ts +1063 -0
- package/src/native/settle.ts +23 -0
- package/src/native/spans.ts +308 -0
- package/src/native/state.ts +28 -0
- package/src/native/tone.ts +79 -0
- package/src/overlays/advisor-config.ts +420 -0
- package/src/overlays/agent-hub-renderer.ts +155 -18
- package/src/overlays/agent-hub.ts +1037 -44
- package/src/overlays/agent-transcript-viewer.ts +129 -0
- package/src/overlays/agents-hub.ts +688 -53
- package/src/overlays/annotation-overlay.ts +391 -52
- package/src/overlays/ask-dialog.ts +435 -24
- package/src/overlays/bordered-loader.ts +17 -0
- package/src/overlays/btw-history-panel.ts +182 -0
- package/src/overlays/btw-panel.ts +68 -2
- package/src/overlays/cleanse-panel.ts +105 -15
- package/src/overlays/codex-reset-fireworks.ts +65 -5
- package/src/overlays/composer-shape-preview.ts +26 -1
- package/src/overlays/copy-selector.ts +545 -23
- package/src/overlays/error-banner.ts +44 -0
- package/src/overlays/extensions/extension-list.ts +23 -17
- package/src/overlays/history-search.ts +175 -33
- package/src/overlays/hook-editor.ts +113 -6
- package/src/overlays/hook-input.ts +22 -1
- package/src/overlays/hook-selector.ts +311 -22
- package/src/overlays/hub-frame.ts +80 -0
- package/src/overlays/jobs-panel.ts +112 -0
- package/src/overlays/login-dialog.ts +183 -1
- package/src/overlays/logout-account-selector.ts +102 -4
- package/src/overlays/mcp-add-wizard.ts +232 -53
- package/src/overlays/model-browser.ts +681 -22
- package/src/overlays/model-hub.ts +1402 -78
- package/src/overlays/model-picker.ts +184 -7
- package/src/overlays/move-overlay.ts +45 -0
- package/src/overlays/oauth-selector.ts +227 -23
- package/src/overlays/omfg-panel.ts +86 -2
- package/src/overlays/pause-screen.ts +55 -4
- package/src/overlays/plan-review-overlay.ts +352 -0
- package/src/overlays/plan-save-overlay.ts +45 -0
- package/src/overlays/plugin-selector.ts +21 -1
- package/src/overlays/plugin-settings.ts +195 -5
- package/src/overlays/queue-mode-selector.ts +19 -1
- package/src/overlays/reset-usage-selector.ts +110 -40
- package/src/overlays/rewind-selector.ts +458 -44
- package/src/overlays/session-account-selector.ts +1 -1
- package/src/overlays/session-info-overlay.ts +137 -1
- package/src/overlays/session-selector.ts +807 -46
- package/src/overlays/settings-defs.ts +41 -0
- package/src/overlays/settings-selector.ts +585 -33
- package/src/overlays/show-images-selector.ts +18 -1
- package/src/overlays/snapcompact-shape-preview.ts +48 -3
- package/src/overlays/stats-notice.ts +31 -0
- package/src/overlays/theme-selector.ts +31 -1
- package/src/overlays/thinking-selector.ts +22 -1
- package/src/overlays/tree-selector.ts +570 -110
- package/src/overlays/usage-dashboard.ts +587 -12
- package/src/overlays/usage-row.ts +161 -25
- package/src/prompt/attachment-chips.ts +60 -0
- package/src/prompt/composer-attachments.ts +31 -9
- package/src/prompt/composer.ts +55 -2
- package/src/prompt/custom-editor.ts +302 -4
- package/src/prompt/editor-top-gap.ts +8 -0
- package/src/prompt/macos-spelling.ts +24 -9
- package/src/prompt/magic-keywords.ts +22 -1
- package/src/prompt/model-mention-autocomplete.ts +1 -0
- package/src/prompt/queued-messages.ts +101 -0
- package/src/prompt/skill-tokens.ts +5 -3
- package/src/prompt/welcome.ts +213 -6
- package/src/render/code-cell.ts +103 -2
- package/src/render/file-list.ts +29 -0
- package/src/render/hyperlink.ts +32 -0
- package/src/render/output-block.ts +110 -0
- package/src/render/output-pane.ts +37 -0
- package/src/render/tool-card.ts +137 -0
- package/src/render/tree-list.ts +39 -0
- package/src/render/width-aware-text.ts +20 -0
- package/src/setup/scenes/composer.ts +29 -0
- package/src/setup/scenes/glyph.ts +15 -0
- package/src/setup/scenes/model.ts +36 -8
- package/src/setup/scenes/outro.ts +28 -1
- package/src/setup/scenes/sign-in.ts +138 -24
- package/src/setup/scenes/splash.ts +28 -1
- package/src/setup/scenes/theme.ts +88 -3
- package/src/setup/scenes/types.ts +7 -28
- package/src/setup/startup-splash.ts +46 -9
- package/src/setup/wizard-overlay.ts +140 -23
- package/src/setup/wizard.ts +1 -1
- package/src/status-line/component.ts +414 -18
- package/src/status-line/context-usage.ts +279 -50
- package/src/status-line/footer.ts +94 -1
- package/src/status-line/metrics.ts +3 -6
- package/src/status-line/segments.ts +463 -97
- package/src/status-line/separators.ts +3 -16
- package/src/status-line/types.ts +43 -1
- package/src/stdin-buffer.ts +27 -21
- package/src/terminal-capabilities.ts +7 -0
- package/src/terminal.ts +153 -11
- package/src/theme/defaults/dark-neon-noir.json +100 -0
- package/src/theme/defaults/index.ts +2 -0
- package/src/theme/defaults/light-prism.json +5 -5
- package/src/theme/defaults/onyx.json +62 -62
- package/src/theme/mermaid-cache.ts +10 -1
- package/src/theme/schema.ts +15 -0
- package/src/theme/shimmer.ts +33 -0
- package/src/theme/theme-class.ts +24 -19
- package/src/theme/theme.ts +111 -9
- package/src/theme/tui-adapters.ts +14 -1
- package/src/tools/ask.ts +157 -1
- package/src/tools/ast-edit.ts +174 -1
- package/src/tools/ast-grep.ts +82 -2
- package/src/tools/autoresearch.ts +149 -1
- package/src/tools/bash.ts +233 -62
- package/src/tools/cfg-render.ts +66 -1
- package/src/tools/debug.ts +78 -1
- package/src/tools/default-renderer.ts +35 -1
- package/src/tools/edit.ts +357 -31
- package/src/tools/eval.ts +257 -1
- package/src/tools/fetch.ts +102 -3
- package/src/tools/find.ts +127 -1
- package/src/tools/github.ts +119 -10
- package/src/tools/glob.ts +116 -1
- package/src/tools/goal.ts +56 -1
- package/src/tools/grep.ts +83 -2
- package/src/tools/grouped-file-output.ts +205 -0
- package/src/tools/json-tree.ts +116 -1
- package/src/tools/lsp.ts +318 -1
- package/src/tools/mcp.ts +80 -1
- package/src/tools/memory.ts +93 -11
- package/src/tools/native-view.ts +292 -0
- package/src/tools/proc-render.ts +221 -1
- package/src/tools/read.ts +199 -4
- package/src/tools/renderer.ts +61 -0
- package/src/tools/report-tool-issue.ts +7 -1
- package/src/tools/resolve.ts +63 -1
- package/src/tools/streaming-output.ts +79 -16
- package/src/tools/task.ts +406 -4
- package/src/tools/think.ts +19 -1
- package/src/tools/todo.ts +89 -0
- package/src/tools/vibe.ts +230 -2
- package/src/tools/wait.ts +181 -1
- package/src/tools/web-search-types.ts +99 -0
- package/src/tools/web-search.ts +111 -170
- package/src/tools/write.ts +144 -5
- package/src/tools/xdev.ts +64 -1
- package/src/tui.ts +295 -4
- package/dist/types/setup/scenes/providers.d.ts +0 -3
- package/dist/types/setup/scenes/web-search.d.ts +0 -22
- package/src/setup/scenes/providers.ts +0 -110
- package/src/setup/scenes/web-search.ts +0 -165
|
@@ -16,7 +16,10 @@ import { formatArtifactErrorNotice, formatTruncationMetaNotice, type TruncationM
|
|
|
16
16
|
import { DynamicBorder } from "../chrome/dynamic-border";
|
|
17
17
|
import { Ellipsis, truncateToWidth, visibleWidth } from "../utils";
|
|
18
18
|
import { interruptKey } from "../chrome/keybinding-hints";
|
|
19
|
-
import { expandKeyHint } from "../render/render-utils";
|
|
19
|
+
import { DEFAULT_TERMINAL_PREVIEW_LINES, expandKeyHint } from "../render/render-utils";
|
|
20
|
+
import type { TspCardStatus, TspSpan, TspText, TspTone } from "@oh-my-pi/pi-wire";
|
|
21
|
+
import { card, node, span, text } from "../native/describe";
|
|
22
|
+
import type { NativeChild, NativeNode } from "../native/node";
|
|
20
23
|
|
|
21
24
|
/** Output rows shown while an execution is collapsed. */
|
|
22
25
|
export const PREVIEW_LINES = 20;
|
|
@@ -104,6 +107,155 @@ export function buildStatusFooter(opts: {
|
|
|
104
107
|
return new Text(`\n${parts.join("\n")}`, 1, 0);
|
|
105
108
|
}
|
|
106
109
|
|
|
110
|
+
const EXECUTION_CARD_STATUS: Record<ExecutionStatus, TspCardStatus> = {
|
|
111
|
+
running: "running",
|
|
112
|
+
complete: "done",
|
|
113
|
+
cancelled: "cancelled",
|
|
114
|
+
error: "error",
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/** Inputs for {@link describeExecutionCard}. */
|
|
118
|
+
export interface ExecutionCardInput {
|
|
119
|
+
readonly role: string;
|
|
120
|
+
readonly head: TspText;
|
|
121
|
+
/** Excluded from context (`!!`/`$$`): a muted card. */
|
|
122
|
+
readonly muted: boolean;
|
|
123
|
+
readonly status: ExecutionStatus;
|
|
124
|
+
/** `performance.now()` when the run started; drives the live elapsed timer. */
|
|
125
|
+
readonly startedAt: number;
|
|
126
|
+
readonly expanded: boolean;
|
|
127
|
+
/** Body nodes before the output (the eval cell's code). */
|
|
128
|
+
readonly lead?: readonly NativeChild[];
|
|
129
|
+
/** Raw terminal output. */
|
|
130
|
+
readonly output: string;
|
|
131
|
+
readonly images?: readonly NativeChild[];
|
|
132
|
+
readonly exitCode: number | undefined;
|
|
133
|
+
readonly truncation: TruncationMeta | undefined;
|
|
134
|
+
readonly artifactError?: OutputArtifactError;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Native card shared by user bash/eval runs: the head with a live `elapsed`
|
|
139
|
+
* while running, the output as an `ansi` mini terminal that follows its tail
|
|
140
|
+
* while running, a cancel hint spinner, then exit/truncation notes. The
|
|
141
|
+
* terminal clamps the collapsed body and owns the "N more lines" affordance.
|
|
142
|
+
*/
|
|
143
|
+
export function describeExecutionCard(input: ExecutionCardInput): NativeNode {
|
|
144
|
+
const running = input.status === "running";
|
|
145
|
+
const headChildren: NativeChild[] = [text(input.head, { lines: 1, grow: 1 })];
|
|
146
|
+
if (running) {
|
|
147
|
+
headChildren.push(node("elapsed", { age: Math.max(0, Math.round(performance.now() - input.startedAt)) }));
|
|
148
|
+
}
|
|
149
|
+
const children: NativeChild[] = [
|
|
150
|
+
node("row", { gap: "sm", align: "baseline" }, headChildren, "head"),
|
|
151
|
+
...(input.lead ?? []),
|
|
152
|
+
];
|
|
153
|
+
if (input.output) {
|
|
154
|
+
children.push(
|
|
155
|
+
node("ansi", { text: input.output, follow: running, preview: { lines: PREVIEW_LINES } }, undefined, "output"),
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
if (input.images) children.push(...input.images);
|
|
159
|
+
if (running) {
|
|
160
|
+
children.push(
|
|
161
|
+
node("spinner", { label: [span(`Running… (${interruptKey()} to cancel)`, "muted")] }, undefined, "running"),
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
const notes: TspSpan[] = [];
|
|
165
|
+
const note = (value: string, token: string): void => {
|
|
166
|
+
if (notes.length > 0) notes.push(span("\n"));
|
|
167
|
+
notes.push(span(value, token));
|
|
168
|
+
};
|
|
169
|
+
if (input.status === "cancelled") note("(cancelled)", "warning");
|
|
170
|
+
else if (input.status === "error") note(`(exit ${input.exitCode})`, "error");
|
|
171
|
+
if (input.truncation) note(formatTruncationMetaNotice(input.truncation), "warning");
|
|
172
|
+
if (input.artifactError) note(formatArtifactErrorNotice(input.artifactError), "warning");
|
|
173
|
+
if (notes.length > 0) children.push(text(notes, { wrap: "word", key: "notes" }));
|
|
174
|
+
return card(
|
|
175
|
+
{
|
|
176
|
+
role: input.role,
|
|
177
|
+
tone: input.muted ? "muted" : undefined,
|
|
178
|
+
status: EXECUTION_CARD_STATUS[input.status],
|
|
179
|
+
collapsible: true,
|
|
180
|
+
collapsed: !input.expanded,
|
|
181
|
+
preview: { lines: PREVIEW_LINES },
|
|
182
|
+
},
|
|
183
|
+
children,
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** Inputs for {@link describeExecutionTool}. */
|
|
188
|
+
export interface ExecutionToolInput {
|
|
189
|
+
readonly role: string;
|
|
190
|
+
/** Tool name for the head icon (`bash`, `eval`). */
|
|
191
|
+
readonly name: string;
|
|
192
|
+
readonly title: string;
|
|
193
|
+
/** The command / cell source, shown once in the head. */
|
|
194
|
+
readonly command: string;
|
|
195
|
+
readonly lang: string;
|
|
196
|
+
/** Excluded from context (`!!`/`$$`). */
|
|
197
|
+
readonly excluded: boolean;
|
|
198
|
+
readonly status: ExecutionStatus;
|
|
199
|
+
/** `performance.now()` when the run started / ended. */
|
|
200
|
+
readonly startedAt: number;
|
|
201
|
+
readonly endedAt: number | undefined;
|
|
202
|
+
readonly expanded: boolean;
|
|
203
|
+
/** Raw terminal output. */
|
|
204
|
+
readonly output: string;
|
|
205
|
+
readonly images?: readonly NativeChild[];
|
|
206
|
+
readonly exitCode: number | undefined;
|
|
207
|
+
readonly truncation: TruncationMeta | undefined;
|
|
208
|
+
readonly artifactError?: OutputArtifactError;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* A user `!`/`$` run as the agent's `tool` frame (§6.6): the command in the
|
|
213
|
+
* head with a `you` badge (plus `not sent` when excluded from context), the
|
|
214
|
+
* timer, exit chip and cancelled note; the body is the output as an `ansi`
|
|
215
|
+
* mini terminal following its tail, then one quiet truncation line.
|
|
216
|
+
*/
|
|
217
|
+
export function describeExecutionTool(input: ExecutionToolInput): NativeNode {
|
|
218
|
+
const running = input.status === "running";
|
|
219
|
+
const body: NativeChild[] = [];
|
|
220
|
+
if (input.output) body.push(node("ansi", { text: input.output, follow: running }, undefined, "output"));
|
|
221
|
+
if (input.images) body.push(...input.images);
|
|
222
|
+
const notes: string[] = [];
|
|
223
|
+
if (input.truncation) notes.push(formatTruncationMetaNotice(input.truncation));
|
|
224
|
+
if (input.artifactError) notes.push(formatArtifactErrorNotice(input.artifactError));
|
|
225
|
+
if (notes.length > 0) {
|
|
226
|
+
body.push({
|
|
227
|
+
...text([span(notes.join(" · "), "muted")], { wrap: "word", role: "omp.tool.notice" }),
|
|
228
|
+
key: "foot",
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
const ms = Math.max(0, Math.round((input.endedAt ?? performance.now()) - input.startedAt));
|
|
232
|
+
const badges: { text: string; tone?: TspTone; title?: string }[] = [{ text: "you", tone: "user" }];
|
|
233
|
+
if (input.excluded) badges.push({ text: "not sent", title: "Not sent to the model", tone: "muted" });
|
|
234
|
+
const hasBody = body.length > 0;
|
|
235
|
+
return node(
|
|
236
|
+
"tool",
|
|
237
|
+
{
|
|
238
|
+
role: input.role,
|
|
239
|
+
name: input.name,
|
|
240
|
+
title: input.title,
|
|
241
|
+
target: input.command,
|
|
242
|
+
targetKind: "command",
|
|
243
|
+
lang: input.lang,
|
|
244
|
+
badges,
|
|
245
|
+
status: EXECUTION_CARD_STATUS[input.status],
|
|
246
|
+
age: running ? ms : undefined,
|
|
247
|
+
took: running ? undefined : ms,
|
|
248
|
+
exit: input.status === "error" ? input.exitCode : undefined,
|
|
249
|
+
note: input.status === "cancelled" ? "cancelled" : undefined,
|
|
250
|
+
frame: "card",
|
|
251
|
+
collapsible: hasBody,
|
|
252
|
+
collapsed: hasBody ? !input.expanded : undefined,
|
|
253
|
+
preview: hasBody ? { tail: DEFAULT_TERMINAL_PREVIEW_LINES } : undefined,
|
|
254
|
+
},
|
|
255
|
+
body,
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
107
259
|
/**
|
|
108
260
|
* Derive the post-run status from an exit code + cancellation flag using the
|
|
109
261
|
* same precedence both execution components apply.
|
package/src/chat/hook-message.ts
CHANGED
|
@@ -13,6 +13,7 @@ export class HookMessageComponent extends FramedMessageComponent<HookMessage<unk
|
|
|
13
13
|
constructor(message: HookMessage<unknown>, customRenderer?: HookMessageRenderer) {
|
|
14
14
|
super({
|
|
15
15
|
message,
|
|
16
|
+
role: "omp.hook",
|
|
16
17
|
collapseAfterLines: HOOK_COLLAPSED_LINES,
|
|
17
18
|
customRenderer,
|
|
18
19
|
});
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
import { Container } from "../tui";
|
|
1
|
+
import { type Component, Container } from "../tui";
|
|
2
|
+
import { isNativeRendering } from "../native/state";
|
|
2
3
|
import { Disclosure } from "../components/disclosure";
|
|
3
4
|
import { Text } from "../components/text";
|
|
4
5
|
import { formatDiagnostics } from "../render/render-utils";
|
|
5
|
-
import { getLanguageFromPath, theme } from "../theme";
|
|
6
|
+
import { getLanguageFromPath, getThemeEpoch, theme } from "../theme";
|
|
7
|
+
import { card, span, text, withHidden } from "../native/describe";
|
|
8
|
+
import { type NativeNode, type NativeUiEvent, rootToggleExpanded } from "../native/node";
|
|
9
|
+
import { plainText } from "../native/spans";
|
|
10
|
+
import { Memo } from "../native/memo";
|
|
11
|
+
|
|
12
|
+
/** Diagnostics shown by the collapsed native card, matching the ANSI tree's collapsed count. */
|
|
13
|
+
const COLLAPSED_DIAGNOSTICS = 5;
|
|
6
14
|
|
|
7
15
|
const EMPTY_ROWS: readonly string[] = [];
|
|
8
16
|
|
|
@@ -14,6 +22,45 @@ export interface LateDiagnosticsFile {
|
|
|
14
22
|
messages?: string[];
|
|
15
23
|
}
|
|
16
24
|
|
|
25
|
+
/** A tool frame (edit/write) that takes late diagnostics for its own paths. */
|
|
26
|
+
interface LateDiagnosticsTarget {
|
|
27
|
+
attachLateDiagnostics(
|
|
28
|
+
files: readonly { path: string; summary: string; errored: boolean; messages: string[] }[],
|
|
29
|
+
): boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Native terminals append late diagnostics into the edit/write frame they
|
|
34
|
+
* belong to: each file goes to the most recent tool component in `blocks`
|
|
35
|
+
* that accepts it. Returns the files no frame took (all of them on the ANSI
|
|
36
|
+
* path), for the standalone {@link LateDiagnosticsMessageComponent}.
|
|
37
|
+
*/
|
|
38
|
+
export function routeLateDiagnostics(
|
|
39
|
+
blocks: readonly Component[],
|
|
40
|
+
files: readonly LateDiagnosticsFile[],
|
|
41
|
+
): LateDiagnosticsFile[] {
|
|
42
|
+
if (!isNativeRendering()) return [...files];
|
|
43
|
+
const targets = blocks.filter(
|
|
44
|
+
(block): block is Component & LateDiagnosticsTarget =>
|
|
45
|
+
typeof (block as Partial<LateDiagnosticsTarget>).attachLateDiagnostics === "function",
|
|
46
|
+
);
|
|
47
|
+
const unrouted: LateDiagnosticsFile[] = [];
|
|
48
|
+
for (const file of files) {
|
|
49
|
+
const entry = file.path
|
|
50
|
+
? {
|
|
51
|
+
path: file.path,
|
|
52
|
+
summary: file.summary ?? "",
|
|
53
|
+
errored: file.errored === true,
|
|
54
|
+
messages: file.messages ?? [],
|
|
55
|
+
}
|
|
56
|
+
: undefined;
|
|
57
|
+
const routed =
|
|
58
|
+
entry !== undefined && targets.findLast(target => target.attachLateDiagnostics([entry])) !== undefined;
|
|
59
|
+
if (!routed) unrouted.push(file);
|
|
60
|
+
}
|
|
61
|
+
return unrouted;
|
|
62
|
+
}
|
|
63
|
+
|
|
17
64
|
/**
|
|
18
65
|
* Renders late LSP diagnostics (arrived after edit/write returned) in the
|
|
19
66
|
* transcript, reusing the same tree renderer the edit/write tools use so the
|
|
@@ -26,6 +73,8 @@ export class LateDiagnosticsMessageComponent extends Container {
|
|
|
26
73
|
// lazily on its first render. Only the tool-visibility gate stays here.
|
|
27
74
|
#disclosure: Disclosure | undefined;
|
|
28
75
|
readonly #files: LateDiagnosticsFile[];
|
|
76
|
+
#expanded = false;
|
|
77
|
+
readonly #native = new Memo();
|
|
29
78
|
|
|
30
79
|
constructor(files: LateDiagnosticsFile[]) {
|
|
31
80
|
super();
|
|
@@ -35,6 +84,7 @@ export class LateDiagnosticsMessageComponent extends Container {
|
|
|
35
84
|
}
|
|
36
85
|
|
|
37
86
|
setExpanded(expanded: boolean): void {
|
|
87
|
+
this.#expanded = expanded;
|
|
38
88
|
this.#disclosure?.setExpanded(expanded);
|
|
39
89
|
}
|
|
40
90
|
|
|
@@ -47,6 +97,39 @@ export class LateDiagnosticsMessageComponent extends Container {
|
|
|
47
97
|
return super.render(width);
|
|
48
98
|
}
|
|
49
99
|
|
|
100
|
+
handleNativeEvent(event: NativeUiEvent): void {
|
|
101
|
+
const expanded = rootToggleExpanded(event);
|
|
102
|
+
if (expanded !== undefined) this.setExpanded(expanded);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* A severity-toned card (role `omp.diagnostics.late`) with one wrapped line
|
|
107
|
+
* per diagnostic, clamped by the terminal while collapsed.
|
|
108
|
+
*/
|
|
109
|
+
override describe(): NativeNode {
|
|
110
|
+
const key = [this.#expanded, this.#toolActivityVisible, getThemeEpoch()];
|
|
111
|
+
return this.#native.get(key, () => {
|
|
112
|
+
const input = this.#diagnosticInput();
|
|
113
|
+
const icon = input?.errored ? theme.status.error : theme.status.warning;
|
|
114
|
+
const head = [span(`${icon} `, input?.errored ? "error" : "warning"), span("Late diagnostics", "toolTitle")];
|
|
115
|
+
if (input?.summary) head.push(span(` (${plainText(input.summary)})`, "dim"));
|
|
116
|
+
const diagnostics = card(
|
|
117
|
+
{
|
|
118
|
+
role: "omp.diagnostics.late",
|
|
119
|
+
tone: input?.errored ? "error" : "warning",
|
|
120
|
+
head,
|
|
121
|
+
collapsible: true,
|
|
122
|
+
collapsed: !this.#expanded,
|
|
123
|
+
preview: { lines: COLLAPSED_DIAGNOSTICS },
|
|
124
|
+
},
|
|
125
|
+
(input?.messages ?? []).map((message, index) =>
|
|
126
|
+
text([span(plainText(message), "mono")], { wrap: "word", key: `d${index}` }),
|
|
127
|
+
),
|
|
128
|
+
);
|
|
129
|
+
return withHidden(diagnostics, !this.#toolActivityVisible);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
50
133
|
override invalidate(): void {
|
|
51
134
|
this.#rebuild();
|
|
52
135
|
}
|
|
@@ -1,17 +1,38 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
|
+
import { pathToFileURL } from "node:url";
|
|
2
3
|
import type { AssistantMessage, Usage } from "@oh-my-pi/pi-ai";
|
|
3
4
|
import { type Component } from "../tui";
|
|
4
5
|
import { Container } from "../tui";
|
|
5
6
|
import { Text } from "../components/text";
|
|
6
7
|
import { getLanguageFromPath, theme } from "../theme";
|
|
7
8
|
import { parseLineRanges, selectorLineRanges } from "../tools/line-ranges";
|
|
8
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
type ReadRenderArgs,
|
|
11
|
+
type ReadToolDetails,
|
|
12
|
+
readContentCode,
|
|
13
|
+
readSourceFsPath,
|
|
14
|
+
splitPathAndSel,
|
|
15
|
+
} from "../tools/read";
|
|
9
16
|
import { PREVIEW_LIMITS, shortenPath } from "../render/render-utils";
|
|
10
17
|
import { fileHyperlink, renderCodeCell } from "../render";
|
|
11
18
|
import { canonicalizeMessage } from "./thinking-display";
|
|
12
19
|
import { internalUrlSchemeSpec, splitUrlScheme } from "../tools/url-scheme-host";
|
|
13
20
|
import type { ToolExecutionHandle } from "./tool-execution";
|
|
14
21
|
import { formatUsageRow } from "../overlays/usage-row";
|
|
22
|
+
import { formatCount } from "@oh-my-pi/pi-utils";
|
|
23
|
+
import type { TspCardStatus, TspSpan, TspText } from "@oh-my-pi/pi-wire";
|
|
24
|
+
import type { NativeToolHead } from "../tools/renderer";
|
|
25
|
+
import { card, code, keyed, node, span, text, withHidden } from "../native/describe";
|
|
26
|
+
import {
|
|
27
|
+
type DescribeContext,
|
|
28
|
+
type NativeChild,
|
|
29
|
+
type NativeNode,
|
|
30
|
+
type NativeUiEvent,
|
|
31
|
+
rootToggleExpanded,
|
|
32
|
+
} from "../native/node";
|
|
33
|
+
import { plainText } from "../native/spans";
|
|
34
|
+
import { Memo } from "../native/memo";
|
|
35
|
+
import { fileHref, fileRow, inlineErrorView } from "../tools/native-view";
|
|
15
36
|
|
|
16
37
|
/**
|
|
17
38
|
* Extract the read call's target path. `path` is the canonical arg; `file_path`
|
|
@@ -117,6 +138,21 @@ type ReadUsageRow = {
|
|
|
117
138
|
/** Number of code lines to show in collapsed preview mode */
|
|
118
139
|
const COLLAPSED_PREVIEW_LINES = PREVIEW_LIMITS.OUTPUT_COLLAPSED;
|
|
119
140
|
|
|
141
|
+
/**
|
|
142
|
+
* Collapsed clamp for a data-first group whose previews are already trimmed
|
|
143
|
+
* to {@link COLLAPSED_PREVIEW_LINES}: large enough never to cut the trimmed
|
|
144
|
+
* body, so collapsed shows every file and the head of each preview.
|
|
145
|
+
*/
|
|
146
|
+
const TRIMMED_BODY_PREVIEW = { lines: 1000 } as const;
|
|
147
|
+
|
|
148
|
+
/** Native item tone per read status; successful reads stay neutral. */
|
|
149
|
+
const READ_STATUS_TONE: Record<ReadEntry["status"], "pending" | "warning" | "error" | undefined> = {
|
|
150
|
+
success: undefined,
|
|
151
|
+
pending: "pending",
|
|
152
|
+
warning: "warning",
|
|
153
|
+
error: "error",
|
|
154
|
+
};
|
|
155
|
+
|
|
120
156
|
type ReadDisplayTarget = {
|
|
121
157
|
entry: ReadEntry;
|
|
122
158
|
targetPath: string;
|
|
@@ -329,6 +365,10 @@ export class ReadToolGroupComponent extends Container implements ToolExecutionHa
|
|
|
329
365
|
// run broke, seal(), or an expansion toggle — and the transcript's
|
|
330
366
|
// width-epoch resolution and committed-render bypass must observe it.
|
|
331
367
|
#blockVersion = 0;
|
|
368
|
+
#displayVersion = 0;
|
|
369
|
+
readonly #native = new Memo();
|
|
370
|
+
/** Content previews toggled in the terminal, by tool call id. */
|
|
371
|
+
#previewCollapsed = new Map<string, boolean>();
|
|
332
372
|
|
|
333
373
|
constructor(options: ReadToolGroupOptions = {}) {
|
|
334
374
|
super();
|
|
@@ -503,6 +543,7 @@ export class ReadToolGroupComponent extends Container implements ToolExecutionHa
|
|
|
503
543
|
setExpanded(expanded: boolean): void {
|
|
504
544
|
if (this.#expanded !== expanded) this.#blockVersion++;
|
|
505
545
|
this.#expanded = expanded;
|
|
546
|
+
this.#previewCollapsed.clear();
|
|
506
547
|
this.#updateDisplay();
|
|
507
548
|
}
|
|
508
549
|
|
|
@@ -515,7 +556,306 @@ export class ReadToolGroupComponent extends Container implements ToolExecutionHa
|
|
|
515
556
|
return this;
|
|
516
557
|
}
|
|
517
558
|
|
|
559
|
+
/**
|
|
560
|
+
* Mirrors the terminal's toggles: the `tool` head (the group's root) is
|
|
561
|
+
* `Ctrl+O`'s expansion; a fallback preview card collapses on its own
|
|
562
|
+
* (`setExpanded` resets those).
|
|
563
|
+
*/
|
|
564
|
+
handleNativeEvent(event: NativeUiEvent): void {
|
|
565
|
+
const expanded = rootToggleExpanded(event);
|
|
566
|
+
if (expanded !== undefined) {
|
|
567
|
+
this.setExpanded(expanded);
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
if (event.type !== "toggle" || !event.key.startsWith("p")) return;
|
|
571
|
+
const toolCallId = event.key.slice(1);
|
|
572
|
+
if (!this.#entries.has(toolCallId)) return;
|
|
573
|
+
this.#previewCollapsed.set(toolCallId, event.collapsed);
|
|
574
|
+
this.#displayVersion++;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* The read run as one inline `tool` on terminals that list the kind, else
|
|
579
|
+
* the fallback: a bare `card` (role `omp.tool.read`) with `Read <path>` or
|
|
580
|
+
* `Read (N)` in the head, a `list` of path items (status tone, link,
|
|
581
|
+
* correction and conflict detail, nested usage) and, with content previews
|
|
582
|
+
* on, a `code` block per read clamped by the card's preview while collapsed.
|
|
583
|
+
*/
|
|
584
|
+
override describe(cx?: DescribeContext): NativeNode {
|
|
585
|
+
const dataFirst = cx?.supports("tool") === true;
|
|
586
|
+
const key = [dataFirst, this.#displayVersion, this.#toolActivityVisible, this.#sealed];
|
|
587
|
+
return this.#native.get(key, () =>
|
|
588
|
+
withHidden(dataFirst ? this.#describeTool() : this.#describeGroup(), !this.#toolActivityVisible),
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* The data-first read (§7.3 read, read group, read error): one inline
|
|
594
|
+
* `tool` (role `omp.tool.read`). One file: `Read path:13-36`, a failure's
|
|
595
|
+
* message in the head. Several: `Read 3 files` over one 22px row per file
|
|
596
|
+
* (glyph, dim dir, strong name, range). Content previews are numbered
|
|
597
|
+
* `code` (a section per file in a group), trimmed while collapsed.
|
|
598
|
+
*/
|
|
599
|
+
#describeTool(): NativeNode {
|
|
600
|
+
const entries = [...this.#entries.values()];
|
|
601
|
+
const rows = this.#buildSummaryRows(this.#displayTargetsForEntries(entries));
|
|
602
|
+
const status = this.#groupStatus(entries);
|
|
603
|
+
const previews = entries.filter(entry => entry.status !== "error" && this.#shouldRenderPreview(entry));
|
|
604
|
+
const body: NativeChild[] = [];
|
|
605
|
+
let head: NativeToolHead;
|
|
606
|
+
// Previews (and a long error message) are what a collapse hides; plain rows always show.
|
|
607
|
+
let collapsible = previews.length > 0;
|
|
608
|
+
if (rows.length <= 1) {
|
|
609
|
+
const row = rows[0];
|
|
610
|
+
const error = row && this.#statusForTargets(row.targets) === "error" ? this.#errorFor(row) : undefined;
|
|
611
|
+
const rowHead: NativeToolHead = row ? this.#nativeRowHead(row) : { target: "…", targetKind: "path" };
|
|
612
|
+
if (error !== undefined) {
|
|
613
|
+
const view = inlineErrorView(rowHead, error);
|
|
614
|
+
head = view.tool ?? rowHead;
|
|
615
|
+
if (view.body) {
|
|
616
|
+
body.push(...view.body);
|
|
617
|
+
collapsible = true;
|
|
618
|
+
}
|
|
619
|
+
} else {
|
|
620
|
+
head = rowHead;
|
|
621
|
+
}
|
|
622
|
+
for (const entry of previews) body.push(...this.#nativePreview(entry));
|
|
623
|
+
for (const [i, usage] of (this.#usageRowsBySummaryRow(rows).get(0) ?? []).entries()) {
|
|
624
|
+
body.push(this.#nativeUsage(usage, `u${i}`));
|
|
625
|
+
}
|
|
626
|
+
} else {
|
|
627
|
+
head = { target: formatCount("file", rows.length), targetKind: "text" };
|
|
628
|
+
const summaryRows = this.#buildSummaryRows(
|
|
629
|
+
this.#displayTargetsForEntries(entries.filter(entry => !previews.includes(entry))),
|
|
630
|
+
);
|
|
631
|
+
const usageByRow = this.#usageRowsBySummaryRow(summaryRows);
|
|
632
|
+
for (const [index, row] of summaryRows.entries()) {
|
|
633
|
+
body.push(this.#nativeFileRow(row));
|
|
634
|
+
for (const [i, usage] of (usageByRow.get(index) ?? []).entries()) {
|
|
635
|
+
body.push(this.#nativeUsage(usage, `u${index}.${i}`));
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
for (const entry of previews) {
|
|
639
|
+
const split = splitPathAndSel(entry.path);
|
|
640
|
+
const name = shortenPath(split.path);
|
|
641
|
+
const sectionHead: TspSpan[] = [span(name || "…", "path")];
|
|
642
|
+
if (split.sel) sectionHead.push(span(`:${split.sel}`, "muted"));
|
|
643
|
+
body.push(node("section", { head: sectionHead }, this.#nativePreview(entry), `p${entry.toolCallId}`));
|
|
644
|
+
const usage = this.#usageRows.get(entry.toolCallId);
|
|
645
|
+
if (usage) body.push(this.#nativeUsage(usage, `u${entry.toolCallId}`));
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
return node(
|
|
649
|
+
"tool",
|
|
650
|
+
{
|
|
651
|
+
...head,
|
|
652
|
+
role: "omp.tool.read",
|
|
653
|
+
name: "read",
|
|
654
|
+
title: "Read",
|
|
655
|
+
status,
|
|
656
|
+
tone: status === "error" ? "error" : undefined,
|
|
657
|
+
frame: "inline",
|
|
658
|
+
collapsible,
|
|
659
|
+
collapsed: collapsible ? !this.#expanded : undefined,
|
|
660
|
+
preview: collapsible ? TRIMMED_BODY_PREVIEW : undefined,
|
|
661
|
+
},
|
|
662
|
+
body,
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/** Head data for one summary row: the path (+ selector) target, its link, correction and conflicts. */
|
|
667
|
+
#nativeRowHead(row: ReadSummaryRow): NativeToolHead {
|
|
668
|
+
const split = splitPathAndSel(row.targetPath);
|
|
669
|
+
const filePath = shortenPath(split.sel ? split.path : row.targetPath);
|
|
670
|
+
const correctedFrom = this.#correctedFromForTargets(row.targets);
|
|
671
|
+
const conflicts = this.#conflictCountForTargets(row.targets);
|
|
672
|
+
return {
|
|
673
|
+
target: filePath ? `${filePath}${split.sel ? `:${split.sel}` : ""}` : "…",
|
|
674
|
+
targetKind: "path",
|
|
675
|
+
href: fileHref(linkPathForTargets(row.targets)),
|
|
676
|
+
meta: correctedFrom ? [`corrected from ${shortenPath(correctedFrom)}`] : undefined,
|
|
677
|
+
badges: conflicts
|
|
678
|
+
? [{ text: `${conflicts} conflict${conflicts === 1 ? "" : "s"}`, tone: "warning" }]
|
|
679
|
+
: undefined,
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/** One 22px group row: status glyph, path and range, conflicts chip, then the correction or error message. */
|
|
684
|
+
#nativeFileRow(row: ReadSummaryRow): NativeNode {
|
|
685
|
+
const split = splitPathAndSel(row.targetPath);
|
|
686
|
+
const status = this.#statusForTargets(row.targets);
|
|
687
|
+
const correctedFrom = this.#correctedFromForTargets(row.targets);
|
|
688
|
+
const conflicts = this.#conflictCountForTargets(row.targets);
|
|
689
|
+
const error = status === "error" ? this.#errorFor(row) : undefined;
|
|
690
|
+
const detail: TspText | undefined =
|
|
691
|
+
error !== undefined
|
|
692
|
+
? [span(`— ${error.split("\n", 1)[0]}`, "error")]
|
|
693
|
+
: correctedFrom
|
|
694
|
+
? `corrected from ${shortenPath(correctedFrom)}`
|
|
695
|
+
: undefined;
|
|
696
|
+
return fileRow(shortenPath(split.sel ? split.path : row.targetPath), {
|
|
697
|
+
range: split.sel ? `:${split.sel}` : undefined,
|
|
698
|
+
href: fileHref(linkPathForTargets(row.targets)),
|
|
699
|
+
icon: status === "error" ? "x-circle" : undefined,
|
|
700
|
+
tone: READ_STATUS_TONE[status],
|
|
701
|
+
chip: conflicts ? { text: `${conflicts} conflict${conflicts === 1 ? "" : "s"}` } : undefined,
|
|
702
|
+
detail,
|
|
703
|
+
title: error,
|
|
704
|
+
key: row.targetPath,
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/** The failure message of a row's failed read (its result text, `Error:` prefix dropped). */
|
|
709
|
+
#errorFor(row: ReadSummaryRow): string {
|
|
710
|
+
const failed = row.targets.find(target => target.entry.status === "error")?.entry;
|
|
711
|
+
return (
|
|
712
|
+
plainText(failed?.contentText ?? "")
|
|
713
|
+
.replace(/^Error:\s*/, "")
|
|
714
|
+
.trim() || "Read failed"
|
|
715
|
+
);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/** One read's content as numbered `code`, trimmed to its first lines (plus a count) while collapsed. */
|
|
719
|
+
#nativePreview(entry: ReadEntry): NativeChild[] {
|
|
720
|
+
const split = splitPathAndSel(entry.path);
|
|
721
|
+
const lines = (entry.contentText ?? "").split("\n");
|
|
722
|
+
const shown = this.#expanded ? lines.length : Math.min(lines.length, COLLAPSED_PREVIEW_LINES);
|
|
723
|
+
const blocks: NativeChild[] = readContentCode(
|
|
724
|
+
lines.slice(0, shown).join("\n"),
|
|
725
|
+
entry.codeStartLine ?? firstSelectorLine(split.sel) ?? 1,
|
|
726
|
+
entry.codeLineNumbers?.slice(0, shown),
|
|
727
|
+
getLanguageFromPath(split.path),
|
|
728
|
+
);
|
|
729
|
+
const hidden = lines.length - shown;
|
|
730
|
+
if (hidden > 0) {
|
|
731
|
+
blocks.push(
|
|
732
|
+
keyed(text([span(formatCount("more line", hidden), "muted")], { role: "omp.tool.stats" }), "more"),
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
return blocks;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
#describeGroup(): NativeNode {
|
|
739
|
+
const entries = [...this.#entries.values()];
|
|
740
|
+
const rows = this.#buildSummaryRows(this.#displayTargetsForEntries(entries));
|
|
741
|
+
const usageByRow = this.#usageRowsBySummaryRow(rows);
|
|
742
|
+
const previews = entries.filter(entry => this.#shouldRenderPreview(entry));
|
|
743
|
+
const status = this.#groupStatus(entries);
|
|
744
|
+
const title = span("Read", "toolTitle");
|
|
745
|
+
const children: NativeChild[] = [];
|
|
746
|
+
let head: TspSpan[] = [title];
|
|
747
|
+
if (rows.length === 1) {
|
|
748
|
+
head = [title, span(" "), ...this.#nativePathSpans(rows[0]!)];
|
|
749
|
+
if (previews.length === 0) {
|
|
750
|
+
for (const usage of usageByRow.get(0) ?? []) children.push(this.#nativeUsage(usage, "u0"));
|
|
751
|
+
}
|
|
752
|
+
} else if (rows.length > 1) {
|
|
753
|
+
head = [title, span(` (${rows.length})`, "dim")];
|
|
754
|
+
const summaryTargets = this.#displayTargetsForEntries(
|
|
755
|
+
entries.filter(entry => !this.#shouldRenderPreview(entry)),
|
|
756
|
+
);
|
|
757
|
+
const summaryRows = this.#buildSummaryRows(summaryTargets);
|
|
758
|
+
const summaryUsage = this.#usageRowsBySummaryRow(summaryRows);
|
|
759
|
+
const items = summaryRows.map((row, index) => {
|
|
760
|
+
const usage = (summaryUsage.get(index) ?? []).map(usageRow =>
|
|
761
|
+
plainText(
|
|
762
|
+
formatUsageRow(
|
|
763
|
+
usageRow.usage,
|
|
764
|
+
usageRow.durationMs,
|
|
765
|
+
usageRow.ttftMs,
|
|
766
|
+
usageRow.timestamp,
|
|
767
|
+
usageRow.turnElapsedMs,
|
|
768
|
+
),
|
|
769
|
+
),
|
|
770
|
+
);
|
|
771
|
+
return node(
|
|
772
|
+
"item",
|
|
773
|
+
{
|
|
774
|
+
label: this.#nativePathSpans(row),
|
|
775
|
+
tone: READ_STATUS_TONE[this.#statusForTargets(row.targets)],
|
|
776
|
+
detail: usage.length > 0 ? [span(usage.join(" · "), "dim")] : undefined,
|
|
777
|
+
},
|
|
778
|
+
[],
|
|
779
|
+
row.targetPath,
|
|
780
|
+
);
|
|
781
|
+
});
|
|
782
|
+
if (items.length > 0) children.push(node("list", {}, items));
|
|
783
|
+
}
|
|
784
|
+
for (const entry of previews) {
|
|
785
|
+
const split = splitPathAndSel(entry.path);
|
|
786
|
+
const pathValue = shortenPath(entry.path);
|
|
787
|
+
children.push(
|
|
788
|
+
node(
|
|
789
|
+
"card",
|
|
790
|
+
{
|
|
791
|
+
role: "omp.tool.read.preview",
|
|
792
|
+
tone: READ_STATUS_TONE[entry.status],
|
|
793
|
+
head: pathValue ? [title, span(" "), span(pathValue, "path")] : [title],
|
|
794
|
+
collapsible: true,
|
|
795
|
+
collapsed: this.#previewCollapsed.get(entry.toolCallId) ?? !this.#expanded,
|
|
796
|
+
preview: { lines: COLLAPSED_PREVIEW_LINES },
|
|
797
|
+
},
|
|
798
|
+
[
|
|
799
|
+
code(entry.contentText ?? "", {
|
|
800
|
+
lang: getLanguageFromPath(split.path),
|
|
801
|
+
start: entry.codeStartLine,
|
|
802
|
+
numbers: true,
|
|
803
|
+
}),
|
|
804
|
+
],
|
|
805
|
+
`p${entry.toolCallId}`,
|
|
806
|
+
),
|
|
807
|
+
);
|
|
808
|
+
const usage = this.#usageRows.get(entry.toolCallId);
|
|
809
|
+
if (usage) children.push(this.#nativeUsage(usage, `u${entry.toolCallId}`));
|
|
810
|
+
}
|
|
811
|
+
return card(
|
|
812
|
+
{
|
|
813
|
+
role: "omp.tool.read",
|
|
814
|
+
// A group is plain rows: the per-file previews are the only frames.
|
|
815
|
+
variant: "bare",
|
|
816
|
+
status,
|
|
817
|
+
tone: status === "error" ? "error" : status === "running" ? "pending" : undefined,
|
|
818
|
+
head,
|
|
819
|
+
},
|
|
820
|
+
children,
|
|
821
|
+
);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
#groupStatus(entries: readonly ReadEntry[]): TspCardStatus {
|
|
825
|
+
let rank = 0;
|
|
826
|
+
for (const entry of entries) rank = Math.max(rank, READ_STATUS_RANK[entry.status]);
|
|
827
|
+
if (rank === READ_STATUS_RANK.error) return "error";
|
|
828
|
+
if (rank === READ_STATUS_RANK.pending) return this.#sealed ? "cancelled" : "running";
|
|
829
|
+
return "done";
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/** Path spans for a summary row: linked path, selector, correction note and conflict badge. */
|
|
833
|
+
#nativePathSpans(row: ReadSummaryRow): TspSpan[] {
|
|
834
|
+
const split = splitPathAndSel(row.targetPath);
|
|
835
|
+
const filePath = shortenPath(split.sel ? split.path : row.targetPath);
|
|
836
|
+
const linkPath = linkPathForTargets(row.targets);
|
|
837
|
+
const spans: TspSpan[] = [];
|
|
838
|
+
if (filePath) {
|
|
839
|
+
const href = linkPath && path.isAbsolute(linkPath) ? pathToFileURL(linkPath).href : undefined;
|
|
840
|
+
spans.push(span(filePath, "path", href ? { href } : undefined));
|
|
841
|
+
} else {
|
|
842
|
+
spans.push(span("…", "toolOutput"));
|
|
843
|
+
}
|
|
844
|
+
if (split.sel) spans.push(span(`:${split.sel}`, "accent"));
|
|
845
|
+
const correctedFrom = this.#correctedFromForTargets(row.targets);
|
|
846
|
+
if (correctedFrom) spans.push(span(` (corrected from ${shortenPath(correctedFrom)})`, "dim"));
|
|
847
|
+
const conflicts = this.#conflictCountForTargets(row.targets);
|
|
848
|
+
if (conflicts) spans.push(span(` (⚠ ${conflicts} conflict${conflicts === 1 ? "" : "s"})`, "warning"));
|
|
849
|
+
return spans;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
#nativeUsage(usage: ReadUsageRow, key: string): NativeNode {
|
|
853
|
+
const line = formatUsageRow(usage.usage, usage.durationMs, usage.ttftMs, usage.timestamp, usage.turnElapsedMs);
|
|
854
|
+
return text([span(plainText(line), "dim")], { wrap: "word", key, role: "omp.usage" });
|
|
855
|
+
}
|
|
856
|
+
|
|
518
857
|
#updateDisplay(): void {
|
|
858
|
+
this.#displayVersion++;
|
|
519
859
|
const entries = [...this.#entries.values()];
|
|
520
860
|
const displayTargets = this.#displayTargetsForEntries(entries);
|
|
521
861
|
const displayRows = this.#buildSummaryRows(displayTargets);
|