@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
|
@@ -13,18 +13,38 @@ import type { Theme } from "../theme/theme";
|
|
|
13
13
|
import { ensureThemeSync, getThemeEpoch, theme } from "../theme/theme";
|
|
14
14
|
import {
|
|
15
15
|
type FirstResultViewportRepaint,
|
|
16
|
+
type NativeToolView,
|
|
17
|
+
type RenderResultContextOptions,
|
|
16
18
|
type ToolActivitySummary,
|
|
17
19
|
type ToolRenderer,
|
|
18
20
|
toolRenderers,
|
|
19
21
|
} from "../tools/index";
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
+
import { describeDefaultToolExecution, formatDefaultToolExecution } from "../tools/default-renderer";
|
|
23
|
+
import { INTENT_FIELD, type TspCardStatus, type TspPreview, type TspText, type TspTone } from "@oh-my-pi/pi-wire";
|
|
24
|
+
import { card, col, EMPTY_NODE, node, span, text, withHidden } from "../native/describe";
|
|
25
|
+
import {
|
|
26
|
+
type DescribeContext,
|
|
27
|
+
type NativeChild,
|
|
28
|
+
type NativeNode,
|
|
29
|
+
type NativeUiEvent,
|
|
30
|
+
rootToggleExpanded,
|
|
31
|
+
} from "../native/node";
|
|
32
|
+
import { plainText } from "../native/spans";
|
|
33
|
+
import { diagnosticsSection, displayPath, toolHead } from "../tools/native-view";
|
|
34
|
+
import type { FileDiagnosticsResult } from "../tools/lsp";
|
|
35
|
+
import { NativeImageCache } from "../native/blobs";
|
|
36
|
+
import { Memo } from "../native/memo";
|
|
22
37
|
import { type EditMode, type PerFileDiffPreview, renderStreamingFallback } from "../tools/edit";
|
|
23
|
-
import { EVAL_DEFAULT_PREVIEW_LINES } from "../tools/eval";
|
|
24
38
|
import { taskCardAgentIds } from "../tools/task";
|
|
25
39
|
import { TODO_STRIKE_TOTAL_FRAMES, type TodoToolDetails } from "../tools/todo";
|
|
40
|
+
import { isNativeRendering } from "../native/state";
|
|
26
41
|
import { isWaitingPollDetails } from "../tools/wait";
|
|
27
|
-
import {
|
|
42
|
+
import {
|
|
43
|
+
DEFAULT_TERMINAL_PREVIEW_LINES,
|
|
44
|
+
formatStatusIcon,
|
|
45
|
+
replaceTabs,
|
|
46
|
+
resolveImageOptions,
|
|
47
|
+
} from "../render/render-utils";
|
|
28
48
|
import type { XdevMountedState } from "../tools/xdev";
|
|
29
49
|
import { isFramedBlockComponent, markFramedBlockComponent, renderStatusLine, WidthAwareText } from "../render/index";
|
|
30
50
|
import { cachedPngConversion, convertImageToPngShared, imagePayloadKey } from "./image-loading";
|
|
@@ -85,6 +105,17 @@ function resolveEditModeForTool(toolName: string, tool: AgentTool | undefined):
|
|
|
85
105
|
|
|
86
106
|
type ToolRendererStage = "call" | "result";
|
|
87
107
|
|
|
108
|
+
/** A renderer's preview as the fallback card's clamp (`tail` becomes a head clamp of the same size). */
|
|
109
|
+
function cardPreview(preview: NativeToolView["preview"]): TspPreview | undefined {
|
|
110
|
+
if (preview === undefined) return { lines: DEFAULT_TERMINAL_PREVIEW_LINES };
|
|
111
|
+
if (preview === "none") return undefined;
|
|
112
|
+
if (preview !== "auto" && "tail" in preview) return { lines: preview.tail };
|
|
113
|
+
return preview;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** The describe hooks of a registry renderer or of a custom tool object. */
|
|
117
|
+
type ToolDescriber = Pick<ToolRenderer, "describeCall" | "describeResult" | "mergeCallAndResult">;
|
|
118
|
+
|
|
88
119
|
class SafeToolRendererComponent implements Component {
|
|
89
120
|
#toolName: string;
|
|
90
121
|
#stage: ToolRendererStage;
|
|
@@ -182,6 +213,15 @@ export interface ToolExecutionHandle extends Component {
|
|
|
182
213
|
seal(): void;
|
|
183
214
|
}
|
|
184
215
|
|
|
216
|
+
/** Card tone per status when the renderer doesn't choose one; settled cards stay neutral. */
|
|
217
|
+
const NATIVE_STATUS_TONE: Record<TspCardStatus, TspTone | undefined> = {
|
|
218
|
+
pending: "pending",
|
|
219
|
+
running: "pending",
|
|
220
|
+
done: undefined,
|
|
221
|
+
error: "error",
|
|
222
|
+
cancelled: "info",
|
|
223
|
+
};
|
|
224
|
+
|
|
185
225
|
/** Phase-locked spinner glyph index shared by every live tool block so parallel
|
|
186
226
|
* spinners advance in lockstep instead of each tracking its own start time. */
|
|
187
227
|
export function sharedSpinnerFrame(frameCount: number, now: number = performance.now()): number {
|
|
@@ -198,8 +238,14 @@ let sharedSpinnerTimer: NodeJS.Timeout | undefined;
|
|
|
198
238
|
|
|
199
239
|
/** Arm the shared spinner ticker if it is not already running. */
|
|
200
240
|
function ensureSharedSpinnerTicker(): void {
|
|
201
|
-
if (sharedSpinnerTimer) return;
|
|
241
|
+
if (sharedSpinnerTimer || isNativeRendering()) return;
|
|
202
242
|
sharedSpinnerTimer = setInterval(() => {
|
|
243
|
+
// A native surface opened while blocks were live: the terminal clocks
|
|
244
|
+
// their spinners, so the repaint ticker has nothing left to do.
|
|
245
|
+
if (isNativeRendering()) {
|
|
246
|
+
stopSharedSpinnerTicker();
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
203
249
|
const frame = sharedSpinnerFrame(theme.spinnerFrames.length);
|
|
204
250
|
// Removing the current block mid-iteration is safe on a Set.
|
|
205
251
|
for (const block of liveSpinnerBlocks) block.tickSpinner(frame);
|
|
@@ -331,6 +377,13 @@ export class ToolExecutionComponent extends Container {
|
|
|
331
377
|
// Execution start on the presentation clock (performance.now domain, the
|
|
332
378
|
// same domain as AnimationFrame.now supplied by the transcript allocator).
|
|
333
379
|
#executionStartedAtNow: number | undefined;
|
|
380
|
+
// When the call settled (final result or seal), same clock; freezes the native elapsed timer.
|
|
381
|
+
#executionEndedAtNow: number | undefined;
|
|
382
|
+
readonly #toolCallId: string | undefined;
|
|
383
|
+
readonly #native = new Memo();
|
|
384
|
+
// LSP diagnostics that arrived after the result (native only), shown in the frame.
|
|
385
|
+
#lateDiagnostics: readonly FileDiagnosticsResult[] | undefined;
|
|
386
|
+
readonly #nativeImages = new NativeImageCache();
|
|
334
387
|
// Wall clock captured whenever a task card is rebuilt.
|
|
335
388
|
#taskRenderNowMs = Date.now();
|
|
336
389
|
// Set on each `render()` when the last painted pending shape must be
|
|
@@ -360,10 +413,11 @@ export class ToolExecutionComponent extends Container {
|
|
|
360
413
|
tool: AgentTool | undefined,
|
|
361
414
|
ui: ToolExecutionUi,
|
|
362
415
|
_cwd: string = getProjectDir(),
|
|
363
|
-
|
|
416
|
+
toolCallId?: string,
|
|
364
417
|
) {
|
|
365
418
|
super();
|
|
366
419
|
ensureThemeSync();
|
|
420
|
+
this.#toolCallId = toolCallId;
|
|
367
421
|
this.#toolName = toolName;
|
|
368
422
|
this.#toolLabel = tool?.label ?? toolName;
|
|
369
423
|
this.#renderer = options.useBuiltInRenderer === false ? undefined : toolRenderers[toolName];
|
|
@@ -522,6 +576,7 @@ export class ToolExecutionComponent extends Container {
|
|
|
522
576
|
if (!isPartial) {
|
|
523
577
|
this.#argsComplete = true;
|
|
524
578
|
this.#previewReady?.resolve();
|
|
579
|
+
this.#executionEndedAtNow ??= performance.now();
|
|
525
580
|
}
|
|
526
581
|
this.#updateSpinnerAnimation();
|
|
527
582
|
this.#updateTodoStrikeAnimation();
|
|
@@ -625,7 +680,9 @@ export class ToolExecutionComponent extends Container {
|
|
|
625
680
|
this.#toolName !== "todo" &&
|
|
626
681
|
!isBackgroundAsyncRunning &&
|
|
627
682
|
(pendingCallConsumesSpinner || partialResultConsumesSpinner);
|
|
628
|
-
|
|
683
|
+
// TSP terminals clock spinners themselves; the frame counter is ANSI-only.
|
|
684
|
+
const needsSpinner =
|
|
685
|
+
!isNativeRendering() && (isStreamingArgs || isLivePartialTool || this.#displaceableByToolName === "wait");
|
|
629
686
|
if (needsSpinner && !this.#spinnerActive) {
|
|
630
687
|
const frameCount = theme.spinnerFrames.length;
|
|
631
688
|
const frame = sharedSpinnerFrame(frameCount);
|
|
@@ -658,7 +715,8 @@ export class ToolExecutionComponent extends Container {
|
|
|
658
715
|
}
|
|
659
716
|
|
|
660
717
|
#updateTodoStrikeAnimation(): void {
|
|
661
|
-
|
|
718
|
+
// TSP terminals draw the completion strike from the `del` token; no repaint ticks.
|
|
719
|
+
if (this.#toolName !== "todo" || this.#isPartial || this.#result?.isError || isNativeRendering()) {
|
|
662
720
|
this.#stopTodoStrikeAnimation();
|
|
663
721
|
return;
|
|
664
722
|
}
|
|
@@ -738,6 +796,7 @@ export class ToolExecutionComponent extends Container {
|
|
|
738
796
|
this.#sealed = true;
|
|
739
797
|
this.#blockVersion++;
|
|
740
798
|
this.#displaceableByToolName = undefined;
|
|
799
|
+
this.#executionEndedAtNow ??= performance.now();
|
|
741
800
|
this.stopAnimation();
|
|
742
801
|
this.#updateDisplay();
|
|
743
802
|
this.#ui.requestRender();
|
|
@@ -791,6 +850,322 @@ export class ToolExecutionComponent extends Container {
|
|
|
791
850
|
this.#updateDisplay();
|
|
792
851
|
}
|
|
793
852
|
|
|
853
|
+
/** Mirrors the card collapsed or expanded in the terminal, so `Ctrl+O` and native toggles share one state. */
|
|
854
|
+
handleNativeEvent(event: NativeUiEvent): void {
|
|
855
|
+
const expanded = rootToggleExpanded(event);
|
|
856
|
+
if (expanded !== undefined) this.setExpanded(expanded);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/** The file paths this call targets (edit/write/apply_patch args), display-relative. */
|
|
860
|
+
#targetPaths(): string[] {
|
|
861
|
+
const args = this.#args;
|
|
862
|
+
if (!isRecord(args)) return [];
|
|
863
|
+
const out: string[] = [];
|
|
864
|
+
const add = (value: unknown) => {
|
|
865
|
+
if (typeof value === "string" && value) out.push(displayPath(value));
|
|
866
|
+
};
|
|
867
|
+
add(args.path);
|
|
868
|
+
add(args.file_path);
|
|
869
|
+
for (const key of ["edits", "files"] as const) {
|
|
870
|
+
const list = args[key];
|
|
871
|
+
if (Array.isArray(list)) for (const entry of list) if (isRecord(entry)) add(entry.path);
|
|
872
|
+
}
|
|
873
|
+
return out;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
/** Whether this call targets `filePath` (the late-diagnostics router matches with it). */
|
|
877
|
+
matchesPath(filePath: string): boolean {
|
|
878
|
+
const wanted = displayPath(filePath);
|
|
879
|
+
return this.#targetPaths().includes(wanted);
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
/**
|
|
883
|
+
* Attaches LSP diagnostics that arrived after the result into this call's
|
|
884
|
+
* frame (§7.3: a diagnostics section plus a count chip in the head). Native
|
|
885
|
+
* rendering only; returns false when nothing matched, so the caller shows
|
|
886
|
+
* its standalone notice instead.
|
|
887
|
+
*/
|
|
888
|
+
attachLateDiagnostics(files: readonly (FileDiagnosticsResult & { readonly path: string })[]): boolean {
|
|
889
|
+
if (!isNativeRendering()) return false;
|
|
890
|
+
const mine = files.filter(file => this.matchesPath(file.path));
|
|
891
|
+
if (mine.length === 0) return false;
|
|
892
|
+
this.#lateDiagnostics = mine;
|
|
893
|
+
this.#blockVersion++;
|
|
894
|
+
this.#displayInputVersion++;
|
|
895
|
+
this.invalidate();
|
|
896
|
+
return true;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
/**
|
|
900
|
+
* The tool card: `card` role `omp.tool.<name>` with the renderer's
|
|
901
|
+
* {@link NativeToolView} (head spans, body nodes), a status chip, an
|
|
902
|
+
* `elapsed` timer in the head and terminal-local collapse clamped to the
|
|
903
|
+
* view's preview. Renderers without describe hooks (and extension tools
|
|
904
|
+
* with only render hooks) get the generic card. Hidden tool activity stays
|
|
905
|
+
* mounted so toggling it is one prop change.
|
|
906
|
+
*/
|
|
907
|
+
override describe(cx?: DescribeContext): NativeNode {
|
|
908
|
+
if (this.#toolName === "wait" && this.#isBenignSkip()) return EMPTY_NODE;
|
|
909
|
+
const dataFirst = cx?.supports("tool") === true;
|
|
910
|
+
const key = [
|
|
911
|
+
dataFirst,
|
|
912
|
+
this.#resultVersion,
|
|
913
|
+
this.#expanded,
|
|
914
|
+
this.#isPartial,
|
|
915
|
+
this.#argsComplete,
|
|
916
|
+
this.#executionStarted,
|
|
917
|
+
this.#sealed,
|
|
918
|
+
this.#parkedBackground,
|
|
919
|
+
this.#showImages,
|
|
920
|
+
this.#displayInputVersion,
|
|
921
|
+
this.#toolActivityVisible,
|
|
922
|
+
getThemeEpoch(),
|
|
923
|
+
];
|
|
924
|
+
return this.#native.get(key, () =>
|
|
925
|
+
withHidden(dataFirst ? this.#describeTool() : this.#describeCard(), !this.#toolActivityVisible),
|
|
926
|
+
);
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
/** Milliseconds since execution started (running) or its total (settled); undefined before it starts. */
|
|
930
|
+
#elapsedMs(status: TspCardStatus): number | undefined {
|
|
931
|
+
const started = this.#executionStartedAtNow;
|
|
932
|
+
if (started === undefined) return undefined;
|
|
933
|
+
const ended = status === "running" ? undefined : this.#executionEndedAtNow;
|
|
934
|
+
return Math.max(0, Math.round((ended ?? performance.now()) - started));
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
/** The late diagnostics section and head chip, when LSP reported after the result. */
|
|
938
|
+
#lateDiagnosticsParts(): { section?: NativeNode; chip?: { text: string; tone: TspTone } } {
|
|
939
|
+
const files = this.#lateDiagnostics;
|
|
940
|
+
if (!files || files.length === 0) return {};
|
|
941
|
+
const sections = files.map(file => diagnosticsSection(file)).filter((n): n is NativeNode => n !== undefined);
|
|
942
|
+
const count = files.reduce((sum, file) => sum + file.messages.length, 0);
|
|
943
|
+
const errored = files.some(file => file.errored);
|
|
944
|
+
const section =
|
|
945
|
+
sections.length === 1
|
|
946
|
+
? sections[0]
|
|
947
|
+
: node("col", { gap: "sm", role: "omp.tool.diagnostics" }, sections, "late");
|
|
948
|
+
return {
|
|
949
|
+
section,
|
|
950
|
+
chip: { text: count === 1 ? "1 diagnostic" : `${count} diagnostics`, tone: errored ? "error" : "warning" },
|
|
951
|
+
};
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
/**
|
|
955
|
+
* The data-first `tool` node (§7.2): the renderer's head data, status,
|
|
956
|
+
* timer, exit and intent as props; its body as borderless children.
|
|
957
|
+
*/
|
|
958
|
+
#describeTool(): NativeNode {
|
|
959
|
+
const view = this.#nativeView();
|
|
960
|
+
const status = this.#nativeStatus();
|
|
961
|
+
const head = view.tool;
|
|
962
|
+
const late = this.#lateDiagnosticsParts();
|
|
963
|
+
const body: NativeChild[] = [...(view.body ?? []), ...this.#nativeResultImages()];
|
|
964
|
+
if (late.section) body.push(late.section);
|
|
965
|
+
const inline = view.inline === true;
|
|
966
|
+
const hasBody = body.length > 0;
|
|
967
|
+
const ms = this.#elapsedMs(status);
|
|
968
|
+
const live = status === "running" || status === "pending";
|
|
969
|
+
const intent = isRecord(this.#args) ? this.#args[INTENT_FIELD] : undefined;
|
|
970
|
+
const badges = [...(head?.badges ?? []), ...(late.chip ? [late.chip] : [])];
|
|
971
|
+
const title: TspText = head?.title ?? (head ? this.#toolLabel : (view.head ?? this.#toolLabel));
|
|
972
|
+
const preview = view.preview ?? (inline ? "none" : { lines: DEFAULT_TERMINAL_PREVIEW_LINES });
|
|
973
|
+
return node(
|
|
974
|
+
"tool",
|
|
975
|
+
{
|
|
976
|
+
role: `omp.tool.${this.#toolName}`,
|
|
977
|
+
key: this.#toolCallId,
|
|
978
|
+
name: this.#toolName,
|
|
979
|
+
// `title` here is the head verb (TspToolProps), not the common tooltip.
|
|
980
|
+
title: title as string,
|
|
981
|
+
target: head?.target,
|
|
982
|
+
targetKind: head?.targetKind,
|
|
983
|
+
lang: head?.lang,
|
|
984
|
+
href: head?.href,
|
|
985
|
+
meta: head?.meta,
|
|
986
|
+
badges: badges.length > 0 ? badges : undefined,
|
|
987
|
+
note: head?.note ?? (status === "cancelled" && !this.#isBenignSkip() ? "cancelled" : undefined),
|
|
988
|
+
exit: head?.exit ?? undefined,
|
|
989
|
+
status,
|
|
990
|
+
age: live ? ms : undefined,
|
|
991
|
+
took: live ? undefined : ms,
|
|
992
|
+
intent: typeof intent === "string" && intent ? plainText(intent) : undefined,
|
|
993
|
+
frame: inline ? "inline" : "card",
|
|
994
|
+
collapsible: hasBody,
|
|
995
|
+
collapsed: hasBody ? !this.#expanded : undefined,
|
|
996
|
+
preview: hasBody ? (preview === "auto" ? { lines: DEFAULT_TERMINAL_PREVIEW_LINES } : preview) : undefined,
|
|
997
|
+
tools: view.tools,
|
|
998
|
+
tone: view.tone,
|
|
999
|
+
},
|
|
1000
|
+
body,
|
|
1001
|
+
);
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/** The fallback card head: the renderer's spans, else spans from its data head. */
|
|
1005
|
+
#fallbackHead(view: NativeToolView): NativeToolView["head"] {
|
|
1006
|
+
if (view.head !== undefined) return view.head;
|
|
1007
|
+
const head = view.tool;
|
|
1008
|
+
if (!head) return undefined;
|
|
1009
|
+
const title =
|
|
1010
|
+
typeof head.title === "string"
|
|
1011
|
+
? head.title
|
|
1012
|
+
: head.title
|
|
1013
|
+
? plainText(head.title.map(s => s.t).join(""))
|
|
1014
|
+
: this.#toolLabel;
|
|
1015
|
+
const target = typeof head.target === "string" ? span(head.target, "muted") : head.target?.map(s => ({ ...s }));
|
|
1016
|
+
const meta = (head.meta ?? []).map(m => (typeof m === "string" ? m : m.map(s => s.t).join("")));
|
|
1017
|
+
const spans = toolHead(title, ...(Array.isArray(target) ? target : [target]), ...meta);
|
|
1018
|
+
if (head.exit) spans.push(span(" "), span(`exit ${head.exit}`, "error"));
|
|
1019
|
+
if (head.note)
|
|
1020
|
+
spans.push(
|
|
1021
|
+
span(" "),
|
|
1022
|
+
span(typeof head.note === "string" ? head.note : head.note.map(s => s.t).join(""), "muted"),
|
|
1023
|
+
);
|
|
1024
|
+
return spans;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
#describeCard(): NativeNode {
|
|
1028
|
+
const view = this.#nativeView();
|
|
1029
|
+
const status = this.#nativeStatus();
|
|
1030
|
+
const late = this.#lateDiagnosticsParts();
|
|
1031
|
+
const fallbackHead = this.#fallbackHead(view);
|
|
1032
|
+
const headChildren: NativeChild[] = [
|
|
1033
|
+
// One line; paths drop whole directories first (path-aware middle cut), the full head in the tooltip.
|
|
1034
|
+
text(fallbackHead ?? [span(this.#toolLabel, "toolTitle")], {
|
|
1035
|
+
lines: 1,
|
|
1036
|
+
truncate: "middle",
|
|
1037
|
+
grow: 1,
|
|
1038
|
+
title: typeof fallbackHead === "string" ? fallbackHead : fallbackHead?.map(s => s.t).join(""),
|
|
1039
|
+
}),
|
|
1040
|
+
];
|
|
1041
|
+
const started = this.#executionStartedAtNow;
|
|
1042
|
+
if (started !== undefined) {
|
|
1043
|
+
const ended = status === "running" ? undefined : this.#executionEndedAtNow;
|
|
1044
|
+
const took = Math.max(0, Math.round((ended ?? performance.now()) - started));
|
|
1045
|
+
headChildren.push(node("elapsed", ended === undefined ? { age: took } : { age: took, stopped: took }));
|
|
1046
|
+
}
|
|
1047
|
+
const children: NativeChild[] = [
|
|
1048
|
+
node("row", { gap: "sm", align: "baseline" }, headChildren, "head"),
|
|
1049
|
+
...(view.body ?? []),
|
|
1050
|
+
...this.#nativeResultImages(),
|
|
1051
|
+
...(late.section ? [late.section] : []),
|
|
1052
|
+
];
|
|
1053
|
+
const role = `omp.tool.${this.#toolName}`;
|
|
1054
|
+
if (view.inline) return col(children, { role });
|
|
1055
|
+
const hasBody = children.length > 1;
|
|
1056
|
+
return card(
|
|
1057
|
+
{
|
|
1058
|
+
role,
|
|
1059
|
+
key: this.#toolCallId,
|
|
1060
|
+
tone: view.tone ?? NATIVE_STATUS_TONE[status],
|
|
1061
|
+
status,
|
|
1062
|
+
collapsible: hasBody,
|
|
1063
|
+
collapsed: hasBody ? !this.#expanded : undefined,
|
|
1064
|
+
preview: hasBody ? cardPreview(view.preview) : undefined,
|
|
1065
|
+
},
|
|
1066
|
+
children,
|
|
1067
|
+
);
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
#nativeStatus(): TspCardStatus {
|
|
1071
|
+
if (this.#isBenignSkip()) return "cancelled";
|
|
1072
|
+
if (this.#result !== undefined && !this.#isPartial) return this.#result.isError ? "error" : "done";
|
|
1073
|
+
if (this.#sealed) return "cancelled";
|
|
1074
|
+
return this.#result !== undefined || this.#executionStarted ? "running" : "pending";
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
/**
|
|
1078
|
+
* The renderer's semantic view: the call view until a result exists, then
|
|
1079
|
+
* the result view (merged renderers) or the call head over both bodies.
|
|
1080
|
+
* A renderer that throws falls back to the generic card.
|
|
1081
|
+
*/
|
|
1082
|
+
#nativeView(): NativeToolView {
|
|
1083
|
+
const options: RenderResultContextOptions = {
|
|
1084
|
+
expanded: this.#expanded,
|
|
1085
|
+
isPartial: this.#isPartial,
|
|
1086
|
+
argsComplete: this.#argsComplete,
|
|
1087
|
+
executionStarted: this.#executionStarted,
|
|
1088
|
+
renderContext: this.#buildRenderContext(),
|
|
1089
|
+
};
|
|
1090
|
+
// Custom tools (MCP, extensions) carry their own describe hooks, mirroring
|
|
1091
|
+
// the ANSI path's preference for the tool's renderCall/renderResult.
|
|
1092
|
+
const toolDescriber = this.#tool as ToolDescriber | undefined;
|
|
1093
|
+
const renderer: ToolDescriber | undefined =
|
|
1094
|
+
toolDescriber?.describeCall || toolDescriber?.describeResult ? toolDescriber : this.#renderer;
|
|
1095
|
+
if (this.#isBenignSkip() || !renderer || (!renderer.describeCall && !renderer.describeResult)) {
|
|
1096
|
+
return this.#defaultNativeView(options);
|
|
1097
|
+
}
|
|
1098
|
+
try {
|
|
1099
|
+
const args = this.#getCallArgsForRender();
|
|
1100
|
+
const result = this.#result;
|
|
1101
|
+
const merged = renderer.mergeCallAndResult === true;
|
|
1102
|
+
const resultView = result
|
|
1103
|
+
? renderer.describeResult?.(
|
|
1104
|
+
{ content: result.content, details: result.details, isError: result.isError },
|
|
1105
|
+
options,
|
|
1106
|
+
args,
|
|
1107
|
+
)
|
|
1108
|
+
: undefined;
|
|
1109
|
+
const callView = !result || !merged || !resultView ? renderer.describeCall?.(args, options) : undefined;
|
|
1110
|
+
if (merged || !callView || !resultView) {
|
|
1111
|
+
return resultView ?? callView ?? { head: [span(this.#toolLabel, "toolTitle")] };
|
|
1112
|
+
}
|
|
1113
|
+
return {
|
|
1114
|
+
tool: callView.tool || resultView.tool ? { ...callView.tool, ...resultView.tool } : undefined,
|
|
1115
|
+
head: callView.head ?? resultView.head,
|
|
1116
|
+
body: [...(callView.body ?? []), ...(resultView.body ?? [])],
|
|
1117
|
+
tone: resultView.tone ?? callView.tone,
|
|
1118
|
+
preview: resultView.preview ?? callView.preview,
|
|
1119
|
+
inline: resultView.inline ?? callView.inline,
|
|
1120
|
+
tools: resultView.tools ?? callView.tools,
|
|
1121
|
+
};
|
|
1122
|
+
} catch (err) {
|
|
1123
|
+
logger.warn("Tool describe failed", { tool: this.#toolName, error: String(err) });
|
|
1124
|
+
return this.#defaultNativeView(options);
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
#defaultNativeView(options: RenderResultContextOptions): NativeToolView {
|
|
1129
|
+
const result = this.#result;
|
|
1130
|
+
return describeDefaultToolExecution({
|
|
1131
|
+
label: this.#toolLabel,
|
|
1132
|
+
args: this.#args,
|
|
1133
|
+
result: result
|
|
1134
|
+
? { output: this.#nativeTextOutput(), isError: result.isError, skipped: this.#isBenignSkip() }
|
|
1135
|
+
: undefined,
|
|
1136
|
+
options,
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
/** Result text for the generic card; images are native nodes unless images are hidden. */
|
|
1141
|
+
#nativeTextOutput(): string {
|
|
1142
|
+
const result = this.#result;
|
|
1143
|
+
if (!result) return "";
|
|
1144
|
+
const output = result.content
|
|
1145
|
+
.filter(block => block.type === "text")
|
|
1146
|
+
.map(block => sanitizeText(block.text || ""))
|
|
1147
|
+
.join("\n");
|
|
1148
|
+
if (this.#showImages) return output;
|
|
1149
|
+
const indicators = this.#getAllImageBlocks()
|
|
1150
|
+
.map(image => {
|
|
1151
|
+
const mimeType = String(image.mimeType);
|
|
1152
|
+
const dims = image.data ? (getImageDimensions(image.data, mimeType) ?? undefined) : undefined;
|
|
1153
|
+
return imageFallback(mimeType, dims);
|
|
1154
|
+
})
|
|
1155
|
+
.join("\n");
|
|
1156
|
+
return indicators ? (output ? `${output}\n${indicators}` : indicators) : output;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
#nativeResultImages(): NativeNode[] {
|
|
1160
|
+
if (!this.#result || !this.#showImages) return [];
|
|
1161
|
+
const images: NativeNode[] = [];
|
|
1162
|
+
this.#getAllImageBlocks().forEach((image, index) => {
|
|
1163
|
+
if (image.data && image.mimeType)
|
|
1164
|
+
images.push(this.#nativeImages.get(`img${index}`, image.data, image.mimeType));
|
|
1165
|
+
});
|
|
1166
|
+
return images;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
794
1169
|
/** Apply the transcript allocator's current viewport reservation. */
|
|
795
1170
|
setTranscriptAllocation(rows: number, frame: AnimationFrame): void {
|
|
796
1171
|
this.#allocation = Math.max(0, Math.trunc(rows));
|
|
@@ -1295,13 +1670,13 @@ export class ToolExecutionComponent extends Container {
|
|
|
1295
1670
|
context.output = output;
|
|
1296
1671
|
}
|
|
1297
1672
|
context.expanded = this.#expanded;
|
|
1298
|
-
context.previewLines =
|
|
1673
|
+
context.previewLines = DEFAULT_TERMINAL_PREVIEW_LINES;
|
|
1299
1674
|
context.timeout = normalizeTimeoutSeconds(isRecord(this.#args) ? this.#args.timeout : undefined, 3600);
|
|
1300
1675
|
} else if (this.#toolName === "eval" && this.#result) {
|
|
1301
1676
|
const output = this.#getTextOutput().trimEnd();
|
|
1302
1677
|
context.output = output;
|
|
1303
1678
|
context.expanded = this.#expanded;
|
|
1304
|
-
context.previewLines =
|
|
1679
|
+
context.previewLines = DEFAULT_TERMINAL_PREVIEW_LINES;
|
|
1305
1680
|
} else if (this.#toolName === "task") {
|
|
1306
1681
|
// Once a result snapshot exists the task renderer's `renderResult`
|
|
1307
1682
|
// draws every dispatched agent as a progress/result line, so tell
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pointer actions on transcript blocks in a native terminal (a user message's
|
|
3
|
+
* hover toolbar, an error frame's action row). Blocks describe the controls;
|
|
4
|
+
* the interactive host registers the one handler that runs omp's existing
|
|
5
|
+
* commands for them, so a click and the key binding take the same path.
|
|
6
|
+
*/
|
|
7
|
+
export type TranscriptAction =
|
|
8
|
+
/** Retry the last failed turn (`app.retry`). */
|
|
9
|
+
| { readonly act: "retry" }
|
|
10
|
+
/** Open the temporary model picker (`app.model.selectTemporary`). */
|
|
11
|
+
| { readonly act: "switch-model" }
|
|
12
|
+
/** Open the transcript rewind selector. */
|
|
13
|
+
| { readonly act: "rewind" }
|
|
14
|
+
/** Resume the session stored at `path` (a welcome card's recent session). */
|
|
15
|
+
| { readonly act: "resume"; readonly path: string }
|
|
16
|
+
/** Put `text` on the clipboard. */
|
|
17
|
+
| { readonly act: "copy"; readonly text: string };
|
|
18
|
+
|
|
19
|
+
type Handler = (action: TranscriptAction) => void;
|
|
20
|
+
|
|
21
|
+
let handler: Handler | undefined;
|
|
22
|
+
|
|
23
|
+
/** Register (or clear, with `undefined`) the host's handler. */
|
|
24
|
+
export function setTranscriptActionHandler(next: Handler | undefined): void {
|
|
25
|
+
handler = next;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Run `action` through the host; false when no host handles actions. */
|
|
29
|
+
export function runTranscriptAction(action: TranscriptAction): boolean {
|
|
30
|
+
if (!handler) return false;
|
|
31
|
+
handler(action);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Whether a host handles actions (controls are only described when one does). */
|
|
36
|
+
export function hasTranscriptActions(): boolean {
|
|
37
|
+
return handler !== undefined;
|
|
38
|
+
}
|
|
@@ -3,6 +3,7 @@ import { type ScrollRangeAnchor, ScrollView } from "../components/scroll-view";
|
|
|
3
3
|
import { DynamicBorder } from "../chrome/dynamic-border";
|
|
4
4
|
import { truncateToWidth } from "../utils";
|
|
5
5
|
import { theme } from "../theme/theme";
|
|
6
|
+
import { sameItems } from "../native/memo";
|
|
6
7
|
import {
|
|
7
8
|
composeOutlineColumn,
|
|
8
9
|
type ComposedColumn,
|
|
@@ -73,14 +74,6 @@ interface BrowserLayout {
|
|
|
73
74
|
bodyHeight: number;
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
function sameLines(left: readonly string[], right: readonly string[]): boolean {
|
|
77
|
-
if (left.length !== right.length) return false;
|
|
78
|
-
for (let index = 0; index < left.length; index++) {
|
|
79
|
-
if (left[index] !== right[index]) return false;
|
|
80
|
-
}
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
77
|
/** Nearest visible target, preferring the preceding item just like the legacy selectors. */
|
|
85
78
|
export function nearestVisibleOutlineTarget(visible: readonly boolean[], selected: number): number {
|
|
86
79
|
if (selected < 0 || selected >= visible.length) return visible.findIndex(Boolean);
|
|
@@ -250,7 +243,7 @@ export class TranscriptBrowser implements Component {
|
|
|
250
243
|
for (const line of frame.footer) output.push(this.#chromeLine(line, frameWidth));
|
|
251
244
|
output.push(...border);
|
|
252
245
|
const cached = this.#cachedLines;
|
|
253
|
-
if (cached &&
|
|
246
|
+
if (cached && sameItems(cached, output)) return cached;
|
|
254
247
|
this.#cachedLines = output;
|
|
255
248
|
return output;
|
|
256
249
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import { createCustomMessage } from "@oh-my-pi/pi-agent-core/compaction/messages";
|
|
3
|
-
import type { MessageAttribution } from "@oh-my-pi/pi-ai";
|
|
3
|
+
import type { ImageContent, MessageAttribution, TextContent } from "@oh-my-pi/pi-ai";
|
|
4
4
|
import {
|
|
5
5
|
type CustomMessage,
|
|
6
6
|
type CustomMessageContent,
|
|
@@ -106,6 +106,15 @@ export function textContent(content: string | ReadonlyArray<{ type: string; text
|
|
|
106
106
|
return text;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
/** Well-formed image blocks in order: a `[Image #N]` marker in the text names the Nth. */
|
|
110
|
+
export function imageContent(content: string | ReadonlyArray<TextContent | ImageContent>): ImageContent[] {
|
|
111
|
+
if (typeof content === "string") return [];
|
|
112
|
+
return content.filter(
|
|
113
|
+
(block): block is ImageContent =>
|
|
114
|
+
block.type === "image" && typeof block.data === "string" && typeof block.mimeType === "string",
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
109
118
|
/** Join text blocks with spaces and collapse whitespace into a single-line label. */
|
|
110
119
|
export function userMessageLabel(content: string | ReadonlyArray<{ type: string; text?: string }>): string {
|
|
111
120
|
return textContent(content, " ").replace(/\s+/g, " ").trim();
|
|
@@ -62,18 +62,18 @@ export function buildAsyncResultBlock(message: CustomOrHookMessage): ToolActivit
|
|
|
62
62
|
const duration = typeof job.durationMs === "number" ? formatDuration(job.durationMs) : undefined;
|
|
63
63
|
rows.push({
|
|
64
64
|
parts: [
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
duration ?
|
|
65
|
+
{ text: `${theme.status.done} Background job completed`, color: "success" },
|
|
66
|
+
{ text: typeLabel, color: "dim" },
|
|
67
|
+
{ text: jobId, color: "accent" },
|
|
68
|
+
duration ? { text: `(${duration})`, color: "dim" } : undefined,
|
|
69
69
|
],
|
|
70
70
|
});
|
|
71
71
|
if (job.meta?.artifactError) {
|
|
72
|
-
rows.push({ parts: [
|
|
72
|
+
rows.push({ parts: [{ text: formatArtifactErrorNotice(job.meta.artifactError), color: "warning" }] });
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
if (details?.meta?.artifactError) {
|
|
76
|
-
rows.push({ parts: [
|
|
76
|
+
rows.push({ parts: [{ text: formatArtifactErrorNotice(details.meta.artifactError), color: "warning" }] });
|
|
77
77
|
}
|
|
78
78
|
return new ToolActivityContainer(new TranscriptStatusBlock(rows));
|
|
79
79
|
}
|
|
@@ -88,7 +88,7 @@ export function buildLaunchCompletionBlock(message: CustomOrHookMessage): ToolAc
|
|
|
88
88
|
const rows: TranscriptStatusRow[] = [];
|
|
89
89
|
const daemons = details?.daemons ?? [];
|
|
90
90
|
if (daemons.length === 0 && typeof message.content === "string") {
|
|
91
|
-
rows.push({ parts: [
|
|
91
|
+
rows.push({ parts: [{ text: `${theme.status.done} ${message.content}`, color: "dim" }] });
|
|
92
92
|
}
|
|
93
93
|
for (const daemon of daemons) {
|
|
94
94
|
const failed = daemon.state === "failed" || (daemon.exitCode !== undefined && daemon.exitCode !== 0);
|
|
@@ -99,11 +99,11 @@ export function buildLaunchCompletionBlock(message: CustomOrHookMessage): ToolAc
|
|
|
99
99
|
rows.push({
|
|
100
100
|
parts: [
|
|
101
101
|
failed
|
|
102
|
-
?
|
|
103
|
-
:
|
|
104
|
-
|
|
105
|
-
daemon.exitCode !== undefined ?
|
|
106
|
-
duration ?
|
|
102
|
+
? { text: `${theme.status.error} Supervised process failed`, color: "error" }
|
|
103
|
+
: { text: `${theme.status.done} Supervised process completed`, color: "success" },
|
|
104
|
+
{ text: daemon.name, color: "accent" },
|
|
105
|
+
daemon.exitCode !== undefined ? { text: `(exit ${daemon.exitCode})`, color: "dim" } : undefined,
|
|
106
|
+
duration ? { text: `(${duration})`, color: "dim" } : undefined,
|
|
107
107
|
],
|
|
108
108
|
});
|
|
109
109
|
}
|
|
@@ -173,9 +173,10 @@ export function buildFileMentionBlock(files: FileMentionMessage["files"], indent
|
|
|
173
173
|
}
|
|
174
174
|
rows.push({
|
|
175
175
|
parts: [
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
176
|
+
{ text: theme.tree.last, color: "dim", rowsOnly: true },
|
|
177
|
+
{ text: "Read", color: "muted" },
|
|
178
|
+
{ text: file.path, color: "accent" },
|
|
179
|
+
{ text: suffix, color: "dim" },
|
|
179
180
|
],
|
|
180
181
|
indent,
|
|
181
182
|
});
|