@oh-my-pi/pi-tui 18.4.3 → 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 +36 -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/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 +37 -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/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 +7 -0
- 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 +7 -0
- package/dist/types/setup/scenes/splash.d.ts +8 -0
- package/dist/types/setup/scenes/types.d.ts +6 -1
- 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/terminal-capabilities.d.ts +1 -1
- package/dist/types/terminal.d.ts +27 -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.d.ts +8 -0
- 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 +346 -11
- 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/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 +37 -0
- 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 +216 -27
- 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 +21 -0
- 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/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 +175 -1
- 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 +583 -23
- 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 +122 -13
- package/src/setup/scenes/splash.ts +28 -1
- package/src/setup/scenes/theme.ts +88 -3
- package/src/setup/scenes/types.ts +7 -1
- package/src/setup/startup-splash.ts +46 -9
- package/src/setup/wizard-overlay.ts +140 -23
- package/src/status-line/component.ts +398 -16
- 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/terminal-capabilities.ts +7 -0
- package/src/terminal.ts +130 -2
- 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/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/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 +180 -49
- 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 +247 -2
- 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/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.ts +113 -1
- package/src/tools/write.ts +144 -5
- package/src/tools/xdev.ts +64 -1
- package/src/tui.ts +294 -3
|
@@ -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);
|
|
@@ -86,6 +86,14 @@ export class ServedModelMarkerComponent extends MessageDividerComponent {
|
|
|
86
86
|
labelColor: "warning",
|
|
87
87
|
ruleColor: "dim",
|
|
88
88
|
ruleWidth: 10,
|
|
89
|
+
role: "omp.marker.served-model",
|
|
90
|
+
native: {
|
|
91
|
+
icon: "warn",
|
|
92
|
+
label: () => {
|
|
93
|
+
const via = info.upstreamProvider ? `${info.provider}/${info.upstreamProvider}` : info.provider;
|
|
94
|
+
return `Served ${info.served} · requested ${info.requested} · via ${via}`;
|
|
95
|
+
},
|
|
96
|
+
},
|
|
89
97
|
});
|
|
90
98
|
}
|
|
91
99
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { pathToFileURL } from "node:url";
|
|
1
2
|
import type { TextContent } from "@oh-my-pi/pi-ai";
|
|
2
3
|
import { type Component } from "../tui";
|
|
3
4
|
import { Box } from "../components/box";
|
|
@@ -11,6 +12,10 @@ import type { CustomMessage, SkillPromptDetails } from "./messages";
|
|
|
11
12
|
import { fileHyperlink } from "../render";
|
|
12
13
|
import { collapseSkillTokens, skillChipLabel, skillChipStyle, skillToken } from "../prompt/composer-attachments";
|
|
13
14
|
import { type UserBubbleOptions, UserMessageComponent, userBubbleColor } from "./user-message";
|
|
15
|
+
import type { TspSpan } from "@oh-my-pi/pi-wire";
|
|
16
|
+
import { card, md, node, span, text } from "../native/describe";
|
|
17
|
+
import { type NativeChild, type NativeNode, type NativeUiEvent, rootToggleExpanded } from "../native/node";
|
|
18
|
+
import { Memo } from "../native/memo";
|
|
14
19
|
|
|
15
20
|
/**
|
|
16
21
|
* Transcript row for a user-invoked skill. Two layouts, chosen by where the
|
|
@@ -41,6 +46,8 @@ export class SkillMessageComponent extends Container {
|
|
|
41
46
|
|
|
42
47
|
readonly #message: CustomMessage<SkillPromptDetails>;
|
|
43
48
|
readonly #imageLinks?: readonly (string | undefined)[];
|
|
49
|
+
#expanded = false;
|
|
50
|
+
readonly #native = new Memo();
|
|
44
51
|
|
|
45
52
|
constructor(message: CustomMessage<SkillPromptDetails>, imageLinks?: readonly (string | undefined)[]) {
|
|
46
53
|
super();
|
|
@@ -51,9 +58,65 @@ export class SkillMessageComponent extends Container {
|
|
|
51
58
|
}
|
|
52
59
|
|
|
53
60
|
setExpanded(expanded: boolean): void {
|
|
61
|
+
this.#expanded = expanded;
|
|
54
62
|
this.#disclosure?.setExpanded(expanded);
|
|
55
63
|
}
|
|
56
64
|
|
|
65
|
+
handleNativeEvent(event: NativeUiEvent): void {
|
|
66
|
+
const expanded = rootToggleExpanded(event);
|
|
67
|
+
if (expanded !== undefined) this.setExpanded(expanded);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* A user-toned card (role `omp.skill`): the skill chip (linked to its
|
|
72
|
+
* SKILL.md) and prompt size in the head, the user's draft as markdown, and
|
|
73
|
+
* the loaded skill prompt, described only while expanded because it can
|
|
74
|
+
* be large.
|
|
75
|
+
*/
|
|
76
|
+
override describe(): NativeNode {
|
|
77
|
+
return this.#native.get([this.#expanded], () => {
|
|
78
|
+
const details = this.#message.details;
|
|
79
|
+
const name = details?.name?.trim() || "unknown";
|
|
80
|
+
const token = skillToken(name);
|
|
81
|
+
const prompt = details?.prompt ?? (details?.args ? `${token} ${details.args}` : token);
|
|
82
|
+
const display = collapseSkillTokens(
|
|
83
|
+
prompt,
|
|
84
|
+
candidate => candidate === name,
|
|
85
|
+
() => {},
|
|
86
|
+
);
|
|
87
|
+
const label = skillChipLabel(name);
|
|
88
|
+
const leading = display.startsWith(label) && /^\s*$/.test(display.charAt(label.length));
|
|
89
|
+
const draft = leading ? display.slice(label.length).trim() : display;
|
|
90
|
+
const head: TspSpan[] = [
|
|
91
|
+
span(
|
|
92
|
+
label,
|
|
93
|
+
"customMessageLabel strong",
|
|
94
|
+
details?.path ? { href: pathToFileURL(details.path).href } : undefined,
|
|
95
|
+
),
|
|
96
|
+
];
|
|
97
|
+
if (typeof details?.lineCount === "number") {
|
|
98
|
+
head.push(span(` ${details.lineCount} ${details.lineCount === 1 ? "line" : "lines"}`, "muted"));
|
|
99
|
+
}
|
|
100
|
+
const children: NativeChild[] = [];
|
|
101
|
+
if (draft) children.push(md(draft));
|
|
102
|
+
const promptText = this.#expanded ? this.#extractText() : "";
|
|
103
|
+
if (promptText) {
|
|
104
|
+
children.push(
|
|
105
|
+
node(
|
|
106
|
+
"section",
|
|
107
|
+
{ head: [span("prompt", "muted")], role: "omp.skill.prompt" },
|
|
108
|
+
[md(promptText)],
|
|
109
|
+
"prompt",
|
|
110
|
+
),
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
return card(
|
|
114
|
+
{ role: "omp.skill", tone: "user", head, collapsible: true, collapsed: !this.#expanded },
|
|
115
|
+
children.length > 0 ? children : [text([span(label, "muted")])],
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
57
120
|
/**
|
|
58
121
|
* Transcript finalization contract (see `FinalizableBlock`): an optimistic
|
|
59
122
|
* `/skill:` row reports `false` so the container keeps it live and removable
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Text } from "../components/text";
|
|
2
2
|
import { theme } from "../theme";
|
|
3
|
+
import { span, text } from "../native/describe";
|
|
4
|
+
import type { NativeNode } from "../native/node";
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Dim transcript marker for tool calls stripped from the resolved branch
|
|
@@ -8,26 +10,32 @@ import { theme } from "../theme";
|
|
|
8
10
|
*/
|
|
9
11
|
export class StrippedToolCallsPlaceholder extends Text {
|
|
10
12
|
#toolActivityVisible: boolean;
|
|
13
|
+
readonly #label: string;
|
|
14
|
+
#native: NativeNode | undefined;
|
|
11
15
|
|
|
12
16
|
constructor(strippedToolCalls: number, toolActivityVisible: boolean) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
theme.italic(
|
|
17
|
-
`${strippedToolCalls} tool call${strippedToolCalls === 1 ? "" : "s"} elided — no result on this branch`,
|
|
18
|
-
),
|
|
19
|
-
),
|
|
20
|
-
1,
|
|
21
|
-
0,
|
|
22
|
-
);
|
|
17
|
+
const label = `${strippedToolCalls} tool call${strippedToolCalls === 1 ? "" : "s"} elided — no result on this branch`;
|
|
18
|
+
super(theme.fg("dim", theme.italic(label)), 1, 0);
|
|
19
|
+
this.#label = label;
|
|
23
20
|
this.#toolActivityVisible = toolActivityVisible;
|
|
24
21
|
}
|
|
25
22
|
|
|
26
23
|
setToolActivityVisible(visible: boolean): void {
|
|
27
24
|
this.#toolActivityVisible = visible;
|
|
25
|
+
this.#native = undefined;
|
|
28
26
|
this.invalidate();
|
|
29
27
|
}
|
|
30
28
|
|
|
29
|
+
/** A dim italic note, mounted but hidden while tool activity is hidden. */
|
|
30
|
+
override describe(): NativeNode {
|
|
31
|
+
this.#native ??= text([span(this.#label, "dim em")], {
|
|
32
|
+
wrap: "word",
|
|
33
|
+
role: "omp.tool.elided",
|
|
34
|
+
hidden: this.#toolActivityVisible ? undefined : true,
|
|
35
|
+
});
|
|
36
|
+
return this.#native;
|
|
37
|
+
}
|
|
38
|
+
|
|
31
39
|
override render(width: number): readonly string[] {
|
|
32
40
|
if (!this.#toolActivityVisible) return [];
|
|
33
41
|
return super.render(width);
|