@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
package/src/render/tool-card.ts
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
|
+
import type { TspSpan, TspText } from "@oh-my-pi/pi-wire";
|
|
1
2
|
import { Text } from "../components/text";
|
|
3
|
+
import { compactText, rowsText, styledSpans } from "../native/spans";
|
|
4
|
+
import { sameItems } from "../native/memo";
|
|
5
|
+
import { colorTone } from "../native/tone";
|
|
6
|
+
import { span } from "../native/describe";
|
|
7
|
+
import type { DescribeContext, NativeChild, NativeNode } from "../native/node";
|
|
2
8
|
import type { Theme, ThemeColor } from "../theme/theme";
|
|
3
9
|
import type { Component } from "../tui";
|
|
4
10
|
import { getPaddingX } from "../utils";
|
|
5
11
|
import {
|
|
6
12
|
CachedOutputBlock,
|
|
13
|
+
describeOutputBlock,
|
|
7
14
|
markFramedBlockComponent,
|
|
15
|
+
type NativeOutputBlockSection,
|
|
8
16
|
outputBlockContentWidth,
|
|
9
17
|
type OutputBlockOptions,
|
|
10
18
|
} from "./output-block";
|
|
@@ -75,6 +83,39 @@ function isRenderedLines(value: readonly string[] | Component): value is readonl
|
|
|
75
83
|
return Array.isArray(value);
|
|
76
84
|
}
|
|
77
85
|
|
|
86
|
+
/** Header spans for a structured status line; the status icon is the card's status chip. */
|
|
87
|
+
function statusSpans(status: StatusLineOptions, theme: Theme): TspSpan[] {
|
|
88
|
+
const flatten = (text: string): string => text.replace(/\r\n?|\n/g, " ");
|
|
89
|
+
const spans: TspSpan[] = [];
|
|
90
|
+
if (status.iconOverride) spans.push(...styledSpans(status.iconOverride), span(" "));
|
|
91
|
+
spans.push(span(flatten(status.title), status.titleColor ?? "accent"));
|
|
92
|
+
if (status.description) spans.push(span(": "), span(flatten(status.description), "muted"));
|
|
93
|
+
if (status.badge) {
|
|
94
|
+
const label = `${theme.format.bracketLeft}${flatten(status.badge.label)}${theme.format.bracketRight}`;
|
|
95
|
+
spans.push(span(" "), span(label, status.badge.color));
|
|
96
|
+
}
|
|
97
|
+
const meta = status.meta?.map(flatten).filter(value => value.trim().length > 0) ?? [];
|
|
98
|
+
if (meta.length > 0) spans.push(span(" "), span(meta.join(theme.sep.dot), "dim"));
|
|
99
|
+
return spans;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Last description of a card, reused while the snapshot's inputs are unchanged. */
|
|
103
|
+
interface NativeCardMemo {
|
|
104
|
+
head: string;
|
|
105
|
+
meta: string | undefined;
|
|
106
|
+
phase: ToolCardPhase | undefined;
|
|
107
|
+
applyBg: boolean | undefined;
|
|
108
|
+
borderColor: ThemeColor | undefined;
|
|
109
|
+
/** Per slot: label plus resolved content (component or rows array) and its described child. */
|
|
110
|
+
slots: readonly {
|
|
111
|
+
label: string | undefined;
|
|
112
|
+
separator: boolean;
|
|
113
|
+
content: readonly string[] | Component;
|
|
114
|
+
child: NativeChild;
|
|
115
|
+
}[];
|
|
116
|
+
node: NativeNode;
|
|
117
|
+
}
|
|
118
|
+
|
|
78
119
|
function resolveContent(content: ToolCardContent, width: number): { lines: readonly string[]; component?: Component } {
|
|
79
120
|
const resolved = typeof content === "function" ? content(width) : content;
|
|
80
121
|
if (isRenderedLines(resolved)) return { lines: resolved };
|
|
@@ -96,6 +137,7 @@ export class ToolCard implements Component {
|
|
|
96
137
|
#plainKey = "";
|
|
97
138
|
#renderedChildren: Component[] = [];
|
|
98
139
|
#disposed = false;
|
|
140
|
+
#native: NativeCardMemo | undefined;
|
|
99
141
|
|
|
100
142
|
constructor(theme: Theme, options: ToolCardOptions, build: (context: ToolCardBuildContext) => ToolCardSnapshot) {
|
|
101
143
|
this.#theme = theme;
|
|
@@ -216,6 +258,100 @@ export class ToolCard implements Component {
|
|
|
216
258
|
return this.#plainText.render(width);
|
|
217
259
|
}
|
|
218
260
|
|
|
261
|
+
/**
|
|
262
|
+
* A `card` (flat `inset` for plain cards) with the state's tone and status
|
|
263
|
+
* chip, head from the header/status line, and body slots: components as
|
|
264
|
+
* children, pre-rendered rows as unwrapped text, labelled sections as
|
|
265
|
+
* `section`s. The builder gets the surface width as its only width.
|
|
266
|
+
*/
|
|
267
|
+
describe(cx: DescribeContext): NativeNode {
|
|
268
|
+
const snapshot = this.#build({ width: cx.cols, contentWidth: cx.cols, contentWidthFor: () => cx.cols });
|
|
269
|
+
const previous = this.#native;
|
|
270
|
+
const slotInputs: { label: string | undefined; separator: boolean; content: ToolCardContent }[] = [];
|
|
271
|
+
if (snapshot.body) slotInputs.push({ label: undefined, separator: false, content: snapshot.body });
|
|
272
|
+
for (const section of snapshot.sections ?? []) {
|
|
273
|
+
slotInputs.push({ label: section.label, separator: section.separator === true, content: section.content });
|
|
274
|
+
}
|
|
275
|
+
if (snapshot.footer)
|
|
276
|
+
slotInputs.push({ label: undefined, separator: slotInputs.length > 0, content: snapshot.footer });
|
|
277
|
+
|
|
278
|
+
const nextChildren: Component[] = [];
|
|
279
|
+
const slots = slotInputs.map((input, index) => {
|
|
280
|
+
const content = typeof input.content === "function" ? input.content(cx.cols) : input.content;
|
|
281
|
+
const prior = previous?.slots[index];
|
|
282
|
+
let child: NativeChild;
|
|
283
|
+
if (isRenderedLines(content)) {
|
|
284
|
+
child =
|
|
285
|
+
prior !== undefined && isRenderedLines(prior.content) && sameItems(prior.content, content)
|
|
286
|
+
? prior.child
|
|
287
|
+
: rowsText(content);
|
|
288
|
+
} else {
|
|
289
|
+
child = content;
|
|
290
|
+
if (!nextChildren.includes(content)) nextChildren.push(content);
|
|
291
|
+
}
|
|
292
|
+
return { label: input.label, separator: input.separator, content, child };
|
|
293
|
+
});
|
|
294
|
+
for (const child of this.#renderedChildren) {
|
|
295
|
+
if (!nextChildren.includes(child)) child.dispose?.();
|
|
296
|
+
}
|
|
297
|
+
this.#renderedChildren = nextChildren;
|
|
298
|
+
|
|
299
|
+
const head = snapshot.header ?? (snapshot.status ? JSON.stringify(snapshot.status) : "");
|
|
300
|
+
if (
|
|
301
|
+
previous !== undefined &&
|
|
302
|
+
previous.head === head &&
|
|
303
|
+
previous.meta === snapshot.headerMeta &&
|
|
304
|
+
previous.phase === snapshot.phase &&
|
|
305
|
+
previous.applyBg === snapshot.applyBg &&
|
|
306
|
+
previous.borderColor === snapshot.borderColor &&
|
|
307
|
+
previous.slots.length === slots.length &&
|
|
308
|
+
slots.every((slot, index) => {
|
|
309
|
+
const prior = previous.slots[index]!;
|
|
310
|
+
return prior.label === slot.label && prior.separator === slot.separator && prior.child === slot.child;
|
|
311
|
+
})
|
|
312
|
+
) {
|
|
313
|
+
return previous.node;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const headSpans: TspText | undefined = snapshot.header
|
|
317
|
+
? compactText(styledSpans(snapshot.header))
|
|
318
|
+
: snapshot.status
|
|
319
|
+
? statusSpans(snapshot.status, this.#theme)
|
|
320
|
+
: undefined;
|
|
321
|
+
const sections: NativeOutputBlockSection[] = slots.map((slot, index) => ({
|
|
322
|
+
label: slot.label === undefined ? undefined : compactText(styledSpans(slot.label)),
|
|
323
|
+
separator: slot.separator,
|
|
324
|
+
body: [slot.child],
|
|
325
|
+
key: String(index),
|
|
326
|
+
}));
|
|
327
|
+
const state = toolCardState(snapshot.phase);
|
|
328
|
+
const plain = this.#options.variant === "plain";
|
|
329
|
+
const described = describeOutputBlock({
|
|
330
|
+
head: headSpans,
|
|
331
|
+
meta: snapshot.headerMeta ? compactText(styledSpans(snapshot.headerMeta)) : undefined,
|
|
332
|
+
state,
|
|
333
|
+
role: "omp.tool",
|
|
334
|
+
tone:
|
|
335
|
+
snapshot.borderColor !== undefined
|
|
336
|
+
? (colorTone(snapshot.borderColor) ?? "neutral")
|
|
337
|
+
: plain && snapshot.applyBg === false
|
|
338
|
+
? "neutral"
|
|
339
|
+
: undefined,
|
|
340
|
+
sections,
|
|
341
|
+
inset: plain || undefined,
|
|
342
|
+
});
|
|
343
|
+
this.#native = {
|
|
344
|
+
head,
|
|
345
|
+
meta: snapshot.headerMeta,
|
|
346
|
+
phase: snapshot.phase,
|
|
347
|
+
applyBg: snapshot.applyBg,
|
|
348
|
+
borderColor: snapshot.borderColor,
|
|
349
|
+
slots,
|
|
350
|
+
node: described,
|
|
351
|
+
};
|
|
352
|
+
return described;
|
|
353
|
+
}
|
|
354
|
+
|
|
219
355
|
get debugChildren(): readonly Component[] {
|
|
220
356
|
return this.#renderedChildren;
|
|
221
357
|
}
|
|
@@ -236,6 +372,7 @@ export class ToolCard implements Component {
|
|
|
236
372
|
}
|
|
237
373
|
|
|
238
374
|
invalidate(): void {
|
|
375
|
+
this.#native = undefined;
|
|
239
376
|
this.#block.invalidate();
|
|
240
377
|
this.#lastBlockOptions = undefined;
|
|
241
378
|
this.#plainKey = "";
|
package/src/render/tree-list.ts
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
* Hierarchical tree list rendering helper.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import type { TspTreeNode } from "@oh-my-pi/pi-wire";
|
|
6
|
+
import { styledSpans } from "../native/spans";
|
|
7
|
+
import { node, span } from "../native/describe";
|
|
8
|
+
import type { NativeNode } from "../native/node";
|
|
5
9
|
import type { Theme } from "../theme/theme";
|
|
6
10
|
import { visibleWidth } from "../utils";
|
|
7
11
|
import { TreeView } from "../components/tree-view";
|
|
@@ -169,6 +173,41 @@ export function renderTreeList<T>(options: TreeListOptions<T>, theme: Theme): st
|
|
|
169
173
|
return renderTreeListRows(roots, theme);
|
|
170
174
|
}
|
|
171
175
|
|
|
176
|
+
/**
|
|
177
|
+
* The native form of {@link renderTreeList}: a flat `tree` whose branch
|
|
178
|
+
* gutters are the terminal's. The collapsed item cap (and the caller's
|
|
179
|
+
* trailing summary) are kept as a muted "… N more" node; the visual line
|
|
180
|
+
* budget (`maxCollapsedLines`) is layout and is left to the terminal.
|
|
181
|
+
*/
|
|
182
|
+
export function describeTreeList<T>(options: TreeListOptions<T>, theme: Theme): NativeNode {
|
|
183
|
+
const { items, expanded = false, maxCollapsed = 8, itemType = "item", truncateFrom = "end", renderItem } = options;
|
|
184
|
+
const itemNode = (index: number): TspTreeNode => {
|
|
185
|
+
const rendered = renderItem(items[index], {
|
|
186
|
+
index,
|
|
187
|
+
isLast: index === items.length - 1,
|
|
188
|
+
depth: 0,
|
|
189
|
+
theme,
|
|
190
|
+
prefix: "",
|
|
191
|
+
continuePrefix: "",
|
|
192
|
+
});
|
|
193
|
+
return { id: `i${index}`, label: styledSpans(Array.isArray(rendered) ? rendered.join("\n") : rendered) };
|
|
194
|
+
};
|
|
195
|
+
const summaryNode = (text: string): TspTreeNode => ({ id: "more", label: [span(text, "muted")] });
|
|
196
|
+
const nodes: TspTreeNode[] = [];
|
|
197
|
+
if (!expanded && options.trailingSummary !== undefined) {
|
|
198
|
+
for (let index = 0; index < items.length; index++) nodes.push(itemNode(index));
|
|
199
|
+
if (options.trailingSummary !== "") nodes.push(summaryNode(options.trailingSummary));
|
|
200
|
+
return node("tree", { nodes });
|
|
201
|
+
}
|
|
202
|
+
const shown = expanded ? items.length : Math.min(items.length, maxCollapsed);
|
|
203
|
+
const hidden = items.length - shown;
|
|
204
|
+
const start = truncateFrom === "start" ? items.length - shown : 0;
|
|
205
|
+
if (hidden > 0 && truncateFrom === "start") nodes.push(summaryNode(formatMoreItems(hidden, itemType)));
|
|
206
|
+
for (let index = start; index < start + shown; index++) nodes.push(itemNode(index));
|
|
207
|
+
if (hidden > 0 && truncateFrom === "end") nodes.push(summaryNode(formatMoreItems(hidden, itemType)));
|
|
208
|
+
return node("tree", { nodes });
|
|
209
|
+
}
|
|
210
|
+
|
|
172
211
|
/**
|
|
173
212
|
* Emit pre-rendered item/summary roots through the shared keyed hierarchy.
|
|
174
213
|
* Roots are siblings in display order, so the first N-1 rows draw `├` and the
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Text } from "../components/text";
|
|
2
|
+
import { col } from "../native/describe";
|
|
3
|
+
import type { DescribeContext, NativeNode } from "../native/node";
|
|
2
4
|
import type { Component } from "../tui";
|
|
3
5
|
import { getPaddingX } from "../utils";
|
|
4
6
|
|
|
@@ -23,6 +25,8 @@ export class WidthAwareText implements Component {
|
|
|
23
25
|
#cachedContentWidth = -1;
|
|
24
26
|
#cachedText: string | undefined;
|
|
25
27
|
#ignoreTight = false;
|
|
28
|
+
#nativeCols = -1;
|
|
29
|
+
#native: NativeNode | undefined;
|
|
26
30
|
|
|
27
31
|
constructor(format: (contentWidth: number) => string, paddingX = 1, paddingY = 1) {
|
|
28
32
|
this.#format = format;
|
|
@@ -56,6 +60,22 @@ export class WidthAwareText implements Component {
|
|
|
56
60
|
this.#cachedText = undefined;
|
|
57
61
|
}
|
|
58
62
|
|
|
63
|
+
/**
|
|
64
|
+
* The inner `Text` as the only child, fed the formatter's output. The
|
|
65
|
+
* formatter is width-bound by contract, so it runs once per surface width
|
|
66
|
+
* (the only width a describer knows) and again on `reformat()`.
|
|
67
|
+
*/
|
|
68
|
+
describe(cx: DescribeContext): NativeNode {
|
|
69
|
+
if (this.#cachedText === undefined || cx.cols !== this.#nativeCols) {
|
|
70
|
+
this.#nativeCols = cx.cols;
|
|
71
|
+
this.#cachedContentWidth = -1;
|
|
72
|
+
this.#cachedText = this.#format(Math.max(1, cx.cols));
|
|
73
|
+
this.#inner.setText(this.#cachedText);
|
|
74
|
+
}
|
|
75
|
+
this.#native ??= col([this.#inner]);
|
|
76
|
+
return this.#native;
|
|
77
|
+
}
|
|
78
|
+
|
|
59
79
|
render(width: number): readonly string[] {
|
|
60
80
|
const paddingX = this.#ignoreTight ? this.#paddingX : getPaddingX(this.#paddingX);
|
|
61
81
|
const contentWidth = Math.max(1, width - paddingX * 2);
|
|
@@ -8,6 +8,9 @@ import { renderComposerShapePreview } from "../../overlays/composer-shape-previe
|
|
|
8
8
|
import { getComposerShapeOptions } from "../../overlays/composer-shape-registry";
|
|
9
9
|
import { editorKey } from "../../chrome/keybinding-hints";
|
|
10
10
|
import { getSelectListTheme, theme } from "../../theme/theme";
|
|
11
|
+
import { ansi, col, span, text } from "../../native/describe";
|
|
12
|
+
import type { DescribeContext, NativeNode } from "../../native/node";
|
|
13
|
+
import { Memo } from "../../native/memo";
|
|
11
14
|
import type { SetupScene, SetupSceneController, SetupSceneHost } from "./types";
|
|
12
15
|
|
|
13
16
|
class ComposerSceneController implements SetupSceneController {
|
|
@@ -19,6 +22,7 @@ class ComposerSceneController implements SetupSceneController {
|
|
|
19
22
|
#currentShape: ComposerShape = "band";
|
|
20
23
|
#committing = false;
|
|
21
24
|
#step: WizardStep | undefined;
|
|
25
|
+
#native = new Memo();
|
|
22
26
|
|
|
23
27
|
readonly #host: SetupSceneHost;
|
|
24
28
|
|
|
@@ -52,6 +56,7 @@ class ComposerSceneController implements SetupSceneController {
|
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
invalidate(): void {
|
|
59
|
+
this.#native.clear();
|
|
55
60
|
if (this.#step) this.#step.invalidate();
|
|
56
61
|
else this.#selectList.invalidate();
|
|
57
62
|
}
|
|
@@ -106,6 +111,30 @@ class ComposerSceneController implements SetupSceneController {
|
|
|
106
111
|
return this.#step.render(width);
|
|
107
112
|
}
|
|
108
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Intro, the shape list, and the live preview. The preview is omp's own
|
|
116
|
+
* composer chrome for the highlighted shape — exactly what the classic
|
|
117
|
+
* renderer paints — so it travels as `ansi` rendered at the surface width.
|
|
118
|
+
*/
|
|
119
|
+
describe(cx: DescribeContext): NativeNode {
|
|
120
|
+
const confirm = editorKey("tui.select.confirm");
|
|
121
|
+
return this.#native.get([this.#currentShape, cx.cols, confirm], () =>
|
|
122
|
+
col(
|
|
123
|
+
[
|
|
124
|
+
text([span(`Select a layout; live preview updates below. Press ${confirm} to confirm.`, "muted")]),
|
|
125
|
+
this.#selectList,
|
|
126
|
+
col([
|
|
127
|
+
text([span("Preview:", "muted")]),
|
|
128
|
+
ansi(renderComposerShapePreview(this.#currentShape, cx.cols, this.#host.ctx.statusLine).join("\n"), {
|
|
129
|
+
cols: cx.cols,
|
|
130
|
+
}),
|
|
131
|
+
]),
|
|
132
|
+
],
|
|
133
|
+
{ gap: "sm", role: "omp.setup.composer" },
|
|
134
|
+
),
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
109
138
|
async #commit(shape: ComposerShape): Promise<void> {
|
|
110
139
|
if (this.#committing) return;
|
|
111
140
|
this.#committing = true;
|
|
@@ -4,6 +4,9 @@ import { type SelectItem, SelectList } from "../../components/select-list";
|
|
|
4
4
|
import { Text } from "../../components/text";
|
|
5
5
|
import { WizardStep } from "../../components/wizard-step";
|
|
6
6
|
import { getSelectListTheme, type SymbolPreset, setSymbolPreset, theme } from "../../theme/theme";
|
|
7
|
+
import { col, span, text } from "../../native/describe";
|
|
8
|
+
import type { NativeNode } from "../../native/node";
|
|
9
|
+
import { Memo } from "../../native/memo";
|
|
7
10
|
import type { SetupScene, SetupSceneController, SetupSceneHost } from "./types";
|
|
8
11
|
|
|
9
12
|
const GLYPH_PRESETS = ["nerd", "unicode", "ascii"] as const satisfies readonly SymbolPreset[];
|
|
@@ -34,6 +37,7 @@ class GlyphSceneController implements SetupSceneController {
|
|
|
34
37
|
#previewRequest = 0;
|
|
35
38
|
#committing = false;
|
|
36
39
|
#step: WizardStep | undefined;
|
|
40
|
+
#native = new Memo();
|
|
37
41
|
|
|
38
42
|
readonly #host: SetupSceneHost;
|
|
39
43
|
|
|
@@ -53,6 +57,7 @@ class GlyphSceneController implements SetupSceneController {
|
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
invalidate(): void {
|
|
60
|
+
this.#native.clear();
|
|
56
61
|
if (this.#step) this.#step.invalidate();
|
|
57
62
|
else this.#selectList.invalidate();
|
|
58
63
|
}
|
|
@@ -92,6 +97,16 @@ class GlyphSceneController implements SetupSceneController {
|
|
|
92
97
|
return this.#step.render(width);
|
|
93
98
|
}
|
|
94
99
|
|
|
100
|
+
/** Hint line over the preset list; the list (sample glyphs as item detail) describes itself. */
|
|
101
|
+
describe(): NativeNode {
|
|
102
|
+
return this.#native.get([this.#selectList], () =>
|
|
103
|
+
col(
|
|
104
|
+
[text([span("If a row shows boxes, tofu, or misaligned icons, pick another.", "muted")]), this.#selectList],
|
|
105
|
+
{ gap: "sm", role: "omp.setup.glyph" },
|
|
106
|
+
),
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
95
110
|
async #commit(preset: SymbolPreset): Promise<void> {
|
|
96
111
|
if (this.#committing) return;
|
|
97
112
|
this.#committing = true;
|
|
@@ -6,7 +6,10 @@ import { buildBrowserItems, ModelBrowser, resolveRoleAssignments, sortModelItems
|
|
|
6
6
|
import { BROWSER_FRAME_ROWS } from "../../overlays/model-picker";
|
|
7
7
|
import { formatKeyHint } from "../../app-keybindings";
|
|
8
8
|
import { theme } from "../../theme/theme";
|
|
9
|
-
import
|
|
9
|
+
import { col, node, span, text } from "../../native/describe";
|
|
10
|
+
import type { NativeNode } from "../../native/node";
|
|
11
|
+
import { Memo } from "../../native/memo";
|
|
12
|
+
import type { SetupScene, SetupSceneController, SetupSceneHost, StyledLine } from "./types";
|
|
10
13
|
|
|
11
14
|
const MAX_VISIBLE_MODELS = 10;
|
|
12
15
|
|
|
@@ -14,10 +17,12 @@ class ModelSceneController implements SetupSceneController {
|
|
|
14
17
|
title = "Choose your default model";
|
|
15
18
|
subtitle = "Search configured models and save the model used for new sessions.";
|
|
16
19
|
#browser: ModelBrowser;
|
|
17
|
-
|
|
20
|
+
/** Intro override; `busy` while discovering or saving (a spinner on the native path). */
|
|
21
|
+
#status: (StyledLine & { readonly busy: boolean }) | undefined;
|
|
18
22
|
#selecting = false;
|
|
19
23
|
#disposed = false;
|
|
20
24
|
#step: WizardStep | undefined;
|
|
25
|
+
#native = new Memo();
|
|
21
26
|
|
|
22
27
|
readonly #host: SetupSceneHost;
|
|
23
28
|
|
|
@@ -32,7 +37,7 @@ class ModelSceneController implements SetupSceneController {
|
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
async onMount(): Promise<void> {
|
|
35
|
-
this.#status =
|
|
40
|
+
this.#status = { text: "Discovering available models…", color: "muted", busy: true };
|
|
36
41
|
this.#host.requestRender();
|
|
37
42
|
await this.#refreshModels();
|
|
38
43
|
}
|
|
@@ -42,6 +47,7 @@ class ModelSceneController implements SetupSceneController {
|
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
invalidate(): void {
|
|
50
|
+
this.#native.clear();
|
|
45
51
|
if (this.#step) this.#step.invalidate();
|
|
46
52
|
else this.#browser.invalidate();
|
|
47
53
|
}
|
|
@@ -58,9 +64,14 @@ class ModelSceneController implements SetupSceneController {
|
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
render(width: number, maxLines?: number): readonly string[] {
|
|
67
|
+
const status = this.#status;
|
|
61
68
|
const intro = new Text(
|
|
62
|
-
|
|
63
|
-
theme.fg(
|
|
69
|
+
status
|
|
70
|
+
? theme.fg(status.color, status.text)
|
|
71
|
+
: theme.fg(
|
|
72
|
+
"muted",
|
|
73
|
+
`Type to search. ${formatKeyHint("enter")} saves the highlighted model as your default.`,
|
|
74
|
+
),
|
|
64
75
|
0,
|
|
65
76
|
0,
|
|
66
77
|
);
|
|
@@ -82,6 +93,23 @@ class ModelSceneController implements SetupSceneController {
|
|
|
82
93
|
return this.#step.render(width);
|
|
83
94
|
}
|
|
84
95
|
|
|
96
|
+
/** Intro (a spinner while models load or the choice saves) over the model browser, which describes itself. */
|
|
97
|
+
describe(): NativeNode {
|
|
98
|
+
const status = this.#status;
|
|
99
|
+
const enter = formatKeyHint("enter");
|
|
100
|
+
return this.#native.get([status, enter], () => {
|
|
101
|
+
let intro: NativeNode;
|
|
102
|
+
if (status?.busy) {
|
|
103
|
+
intro = node("spinner", { label: [span(status.text, status.color)] });
|
|
104
|
+
} else if (status) {
|
|
105
|
+
intro = text([span(status.text, status.color)]);
|
|
106
|
+
} else {
|
|
107
|
+
intro = text([span(`Type to search. ${enter} saves the highlighted model as your default.`, "muted")]);
|
|
108
|
+
}
|
|
109
|
+
return col([{ ...intro, key: "intro" }, this.#browser], { gap: "sm", role: "omp.setup.model" });
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
85
113
|
#syncModels(): void {
|
|
86
114
|
const { available, all, current } = this.#host.ctx.getModels();
|
|
87
115
|
const source = this.#host.ctx.modelSource;
|
|
@@ -109,7 +137,7 @@ class ModelSceneController implements SetupSceneController {
|
|
|
109
137
|
this.#host.requestRender();
|
|
110
138
|
} catch (error) {
|
|
111
139
|
if (this.#disposed) return;
|
|
112
|
-
this.#status =
|
|
140
|
+
this.#status = { text: error instanceof Error ? error.message : String(error), color: "error", busy: false };
|
|
113
141
|
this.#host.requestRender();
|
|
114
142
|
}
|
|
115
143
|
}
|
|
@@ -117,7 +145,7 @@ class ModelSceneController implements SetupSceneController {
|
|
|
117
145
|
async #select(model: Model, selector: string): Promise<void> {
|
|
118
146
|
if (this.#selecting) return;
|
|
119
147
|
this.#selecting = true;
|
|
120
|
-
this.#status =
|
|
148
|
+
this.#status = { text: `Saving ${selector} as the default model…`, color: "muted", busy: true };
|
|
121
149
|
this.#host.requestRender();
|
|
122
150
|
try {
|
|
123
151
|
await this.#host.ctx.selectModel(model, selector);
|
|
@@ -125,7 +153,7 @@ class ModelSceneController implements SetupSceneController {
|
|
|
125
153
|
} catch (error) {
|
|
126
154
|
if (this.#disposed) return;
|
|
127
155
|
this.#selecting = false;
|
|
128
|
-
this.#status =
|
|
156
|
+
this.#status = { text: error instanceof Error ? error.message : String(error), color: "error", busy: false };
|
|
129
157
|
this.#host.requestRender();
|
|
130
158
|
}
|
|
131
159
|
}
|
|
@@ -1,11 +1,38 @@
|
|
|
1
1
|
import { centerLine } from "../../utils";
|
|
2
2
|
import { padToWidth } from "../../render/utils";
|
|
3
|
-
import { gradientLogo, PI_LOGO } from "../../prompt/welcome";
|
|
3
|
+
import { gradientLogo, logoNode, PI_LOGO } from "../../prompt/welcome";
|
|
4
4
|
import { theme } from "../../theme/theme";
|
|
5
|
+
import { col, node, span, text } from "../../native/describe";
|
|
6
|
+
import type { NativeNode } from "../../native/node";
|
|
7
|
+
import { Memo } from "../../native/memo";
|
|
5
8
|
import { renderStarfield, SETUP_TICK_MS } from "./splash";
|
|
6
9
|
|
|
7
10
|
export const SETUP_OUTRO_MS = 1200;
|
|
8
11
|
|
|
12
|
+
const outroMemo = new Memo();
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Native outro: the shimmering mark, the saved confirmation, and an
|
|
16
|
+
* indeterminate progress bar standing in for the timed sweep. A click sends
|
|
17
|
+
* the `continue` action.
|
|
18
|
+
*/
|
|
19
|
+
export function describeSetupOutro(): NativeNode {
|
|
20
|
+
const saved = `${theme.status.success} Setup saved`;
|
|
21
|
+
return outroMemo.get([saved], () =>
|
|
22
|
+
col(
|
|
23
|
+
[
|
|
24
|
+
node("spacer", { grow: 1 }),
|
|
25
|
+
logoNode(PI_LOGO, true),
|
|
26
|
+
text([span(saved, "success strong")], { wrap: "none" }),
|
|
27
|
+
text([span("Handing off to the normal CLI…", "muted")], { wrap: "none" }),
|
|
28
|
+
node("progress", { value: null, max: { w: "48ch" } }),
|
|
29
|
+
node("spacer", { grow: 1 }),
|
|
30
|
+
],
|
|
31
|
+
{ align: "center", gap: "sm", grow: 1, role: "omp.setup.outro", actions: { click: "continue" } },
|
|
32
|
+
),
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
9
36
|
export function renderSetupOutro(width: number, height: number, elapsedMs: number): string[] {
|
|
10
37
|
const frame = Math.floor(elapsedMs / SETUP_TICK_MS);
|
|
11
38
|
const lines = renderStarfield(width, height, frame + 1000);
|