@oh-my-pi/pi-tui 18.4.2 → 18.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +56 -0
- package/dist/types/apps/cleanse-board.d.ts +17 -0
- package/dist/types/apps/git/help.d.ts +16 -0
- package/dist/types/apps/git/sidebar.d.ts +18 -0
- package/dist/types/apps/live-visualizer.d.ts +10 -0
- package/dist/types/apps/ps-top.d.ts +15 -0
- package/dist/types/apps/standalone-picker.d.ts +3 -0
- package/dist/types/autocomplete.d.ts +8 -0
- package/dist/types/chat/advisor-message.d.ts +12 -2
- package/dist/types/chat/assistant-message.d.ts +20 -0
- package/dist/types/chat/bash-execution.d.ts +9 -0
- package/dist/types/chat/chat-transcript-builder.d.ts +6 -1
- package/dist/types/chat/collab-prompt-message.d.ts +4 -0
- package/dist/types/chat/compaction-summary-message.d.ts +15 -0
- package/dist/types/chat/eval-execution.d.ts +8 -0
- package/dist/types/chat/execution-shared.d.ts +58 -0
- package/dist/types/chat/late-diagnostics-message.d.ts +15 -1
- package/dist/types/chat/read-tool-group.d.ts +15 -0
- package/dist/types/chat/skill-message.d.ts +9 -0
- package/dist/types/chat/stripped-tool-calls-placeholder.d.ts +3 -0
- package/dist/types/chat/thinking-display.d.ts +2 -0
- package/dist/types/chat/todo-reminder.d.ts +4 -1
- package/dist/types/chat/tool-execution.d.ts +25 -1
- package/dist/types/chat/transcript-actions.d.ts +37 -0
- package/dist/types/chat/transcript-entry.d.ts +3 -1
- package/dist/types/chat/user-message.d.ts +25 -0
- package/dist/types/chrome/collab-qrcode.d.ts +7 -0
- package/dist/types/chrome/context-thresholds.d.ts +11 -0
- package/dist/types/chrome/countdown-timer.d.ts +9 -3
- package/dist/types/chrome/diff.d.ts +12 -0
- package/dist/types/chrome/dynamic-border.d.ts +3 -0
- package/dist/types/chrome/format.d.ts +6 -0
- package/dist/types/chrome/message-divider.d.ts +13 -0
- package/dist/types/chrome/message-frame.d.ts +10 -0
- package/dist/types/chrome/message-notice.d.ts +23 -0
- package/dist/types/chrome/overlay-box.d.ts +11 -2
- package/dist/types/chrome/qrcode.d.ts +7 -0
- package/dist/types/chrome/segment-track.d.ts +7 -0
- package/dist/types/chrome/selector-helpers.d.ts +0 -6
- package/dist/types/chrome/status-notice.d.ts +14 -0
- package/dist/types/chrome/streaming-panel.d.ts +3 -0
- package/dist/types/chrome/tool-activity.d.ts +3 -0
- package/dist/types/chrome/transcript-container.d.ts +13 -0
- package/dist/types/chrome/transcript-status.d.ts +15 -3
- package/dist/types/components/box.d.ts +7 -0
- package/dist/types/components/disclosure.d.ts +9 -0
- package/dist/types/components/editor.d.ts +42 -0
- package/dist/types/components/form.d.ts +14 -0
- package/dist/types/components/image.d.ts +7 -0
- package/dist/types/components/input.d.ts +20 -1
- package/dist/types/components/key-value-list.d.ts +3 -0
- package/dist/types/components/layout/geometry.d.ts +16 -0
- package/dist/types/components/layout/row.d.ts +7 -0
- package/dist/types/components/layout/split-pane.d.ts +8 -0
- package/dist/types/components/layout/stack.d.ts +6 -0
- package/dist/types/components/loader.d.ts +48 -0
- package/dist/types/components/markdown.d.ts +8 -0
- package/dist/types/components/metric.d.ts +7 -0
- package/dist/types/components/progress-bar.d.ts +3 -0
- package/dist/types/components/scroll-view.d.ts +6 -0
- package/dist/types/components/section.d.ts +3 -0
- package/dist/types/components/select-list.d.ts +33 -0
- package/dist/types/components/settings-list.d.ts +68 -0
- package/dist/types/components/spacer.d.ts +4 -0
- package/dist/types/components/tab-bar.d.ts +9 -0
- package/dist/types/components/table.d.ts +7 -0
- package/dist/types/components/text.d.ts +6 -0
- package/dist/types/components/tree-view.d.ts +9 -0
- package/dist/types/components/truncated-text.d.ts +3 -0
- package/dist/types/components/wizard-step.d.ts +6 -0
- package/dist/types/hotkeys-markdown.d.ts +24 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/latex-block.d.ts +7 -0
- package/dist/types/loop-watchdog.d.ts +9 -0
- package/dist/types/native/apply.d.ts +39 -0
- package/dist/types/native/backend.d.ts +94 -0
- package/dist/types/native/blobs.d.ts +29 -0
- package/dist/types/native/describe.d.ts +56 -0
- package/dist/types/native/encode.d.ts +50 -0
- package/dist/types/native/icons.d.ts +18 -0
- package/dist/types/native/memo.d.ts +27 -0
- package/dist/types/native/node.d.ts +107 -0
- package/dist/types/native/overlay.d.ts +64 -0
- package/dist/types/native/picker.d.ts +124 -0
- package/dist/types/native/reconcile.d.ts +41 -0
- package/dist/types/native/settle.d.ts +11 -0
- package/dist/types/native/spans.d.ts +21 -0
- package/dist/types/native/state.d.ts +6 -0
- package/dist/types/native/tone.d.ts +24 -0
- package/dist/types/overlays/advisor-config.d.ts +20 -0
- package/dist/types/overlays/agent-hub-renderer.d.ts +27 -11
- package/dist/types/overlays/agent-hub.d.ts +10 -0
- package/dist/types/overlays/agent-transcript-viewer.d.ts +7 -0
- package/dist/types/overlays/agents-hub.d.ts +8 -0
- package/dist/types/overlays/annotation-overlay.d.ts +3 -0
- package/dist/types/overlays/ask-dialog.d.ts +23 -0
- package/dist/types/overlays/bordered-loader.d.ts +3 -0
- package/dist/types/overlays/btw-history-panel.d.ts +9 -0
- package/dist/types/overlays/btw-panel.d.ts +3 -0
- package/dist/types/overlays/cleanse-panel.d.ts +5 -2
- package/dist/types/overlays/composer-shape-preview.d.ts +7 -1
- package/dist/types/overlays/copy-selector.d.ts +38 -0
- package/dist/types/overlays/error-banner.d.ts +9 -0
- package/dist/types/overlays/extensions/extension-list.d.ts +1 -0
- package/dist/types/overlays/history-search.d.ts +18 -0
- package/dist/types/overlays/hook-editor.d.ts +28 -1
- package/dist/types/overlays/hook-input.d.ts +3 -0
- package/dist/types/overlays/hook-selector.d.ts +10 -0
- package/dist/types/overlays/hub-frame.d.ts +18 -0
- package/dist/types/overlays/jobs-panel.d.ts +24 -0
- package/dist/types/overlays/login-dialog.d.ts +10 -0
- package/dist/types/overlays/logout-account-selector.d.ts +4 -0
- package/dist/types/overlays/mcp-add-wizard.d.ts +4 -0
- package/dist/types/overlays/model-browser.d.ts +69 -0
- package/dist/types/overlays/model-hub.d.ts +7 -0
- package/dist/types/overlays/model-picker.d.ts +9 -1
- package/dist/types/overlays/move-overlay.d.ts +3 -0
- package/dist/types/overlays/oauth-selector.d.ts +4 -0
- package/dist/types/overlays/omfg-panel.d.ts +3 -0
- package/dist/types/overlays/pause-screen.d.ts +12 -0
- package/dist/types/overlays/plan-review-overlay.d.ts +5 -0
- package/dist/types/overlays/plan-save-overlay.d.ts +10 -0
- package/dist/types/overlays/plugin-selector.d.ts +4 -0
- package/dist/types/overlays/plugin-settings.d.ts +30 -0
- package/dist/types/overlays/queue-mode-selector.d.ts +4 -0
- package/dist/types/overlays/reset-usage-selector.d.ts +8 -0
- package/dist/types/overlays/rewind-selector.d.ts +5 -0
- package/dist/types/overlays/session-info-overlay.d.ts +19 -1
- package/dist/types/overlays/session-selector.d.ts +64 -1
- package/dist/types/overlays/settings-defs.d.ts +14 -0
- package/dist/types/overlays/settings-selector.d.ts +21 -0
- package/dist/types/overlays/show-images-selector.d.ts +4 -0
- package/dist/types/overlays/snapcompact-shape-preview.d.ts +2 -0
- package/dist/types/overlays/stats-notice.d.ts +8 -0
- package/dist/types/overlays/theme-selector.d.ts +11 -0
- package/dist/types/overlays/thinking-selector.d.ts +4 -0
- package/dist/types/overlays/tree-selector.d.ts +60 -2
- package/dist/types/overlays/usage-dashboard.d.ts +26 -3
- package/dist/types/overlays/usage-row.d.ts +36 -2
- package/dist/types/prompt/attachment-chips.d.ts +8 -0
- package/dist/types/prompt/composer-attachments.d.ts +15 -3
- package/dist/types/prompt/composer.d.ts +18 -1
- package/dist/types/prompt/custom-editor.d.ts +48 -2
- package/dist/types/prompt/editor-top-gap.d.ts +2 -0
- package/dist/types/prompt/macos-spelling.d.ts +6 -0
- package/dist/types/prompt/magic-keywords.d.ts +9 -0
- package/dist/types/prompt/queued-messages.d.ts +23 -0
- package/dist/types/prompt/skill-tokens.d.ts +4 -2
- package/dist/types/prompt/welcome.d.ts +16 -0
- package/dist/types/render/code-cell.d.ts +10 -0
- package/dist/types/render/file-list.d.ts +8 -0
- package/dist/types/render/hyperlink.d.ts +14 -0
- package/dist/types/render/output-block.d.ts +43 -0
- package/dist/types/render/output-pane.d.ts +17 -0
- package/dist/types/render/tool-card.d.ts +8 -0
- package/dist/types/render/tree-list.d.ts +8 -0
- package/dist/types/render/width-aware-text.d.ts +7 -0
- package/dist/types/setup/scenes/outro.d.ts +7 -0
- package/dist/types/setup/scenes/sign-in.d.ts +16 -9
- package/dist/types/setup/scenes/splash.d.ts +8 -0
- package/dist/types/setup/scenes/types.d.ts +6 -27
- package/dist/types/setup/wizard-overlay.d.ts +9 -0
- package/dist/types/status-line/component.d.ts +49 -5
- package/dist/types/status-line/context-usage.d.ts +20 -0
- package/dist/types/status-line/footer.d.ts +8 -0
- package/dist/types/status-line/metrics.d.ts +1 -2
- package/dist/types/status-line/segments.d.ts +10 -1
- package/dist/types/status-line/types.d.ts +40 -1
- package/dist/types/stdin-buffer.d.ts +10 -7
- package/dist/types/terminal-capabilities.d.ts +1 -1
- package/dist/types/terminal.d.ts +36 -0
- package/dist/types/theme/defaults/index.d.ts +100 -0
- package/dist/types/theme/schema.d.ts +2 -0
- package/dist/types/theme/shimmer.d.ts +8 -0
- package/dist/types/theme/theme-class.d.ts +2 -0
- package/dist/types/theme/theme.d.ts +33 -1
- package/dist/types/tools/ask.d.ts +3 -0
- package/dist/types/tools/ast-edit.d.ts +10 -1
- package/dist/types/tools/ast-grep.d.ts +10 -1
- package/dist/types/tools/autoresearch.d.ts +21 -4
- package/dist/types/tools/bash.d.ts +30 -1
- package/dist/types/tools/cfg-render.d.ts +5 -1
- package/dist/types/tools/debug.d.ts +3 -1
- package/dist/types/tools/default-renderer.d.ts +6 -1
- package/dist/types/tools/edit.d.ts +14 -1
- package/dist/types/tools/eval.d.ts +12 -1
- package/dist/types/tools/fetch.d.ts +16 -1
- package/dist/types/tools/find.d.ts +15 -1
- package/dist/types/tools/github.d.ts +3 -0
- package/dist/types/tools/glob.d.ts +14 -1
- package/dist/types/tools/goal.d.ts +3 -1
- package/dist/types/tools/grep.d.ts +14 -1
- package/dist/types/tools/grouped-file-output.d.ts +58 -0
- package/dist/types/tools/json-tree.d.ts +20 -0
- package/dist/types/tools/lsp.d.ts +3 -10
- package/dist/types/tools/mcp.d.ts +16 -1
- package/dist/types/tools/memory.d.ts +26 -0
- package/dist/types/tools/native-view.d.ts +90 -0
- package/dist/types/tools/proc-render.d.ts +7 -1
- package/dist/types/tools/read.d.ts +23 -1
- package/dist/types/tools/renderer.d.ts +57 -0
- package/dist/types/tools/report-tool-issue.d.ts +3 -0
- package/dist/types/tools/resolve.d.ts +14 -1
- package/dist/types/tools/task.d.ts +3 -0
- package/dist/types/tools/think.d.ts +3 -0
- package/dist/types/tools/todo.d.ts +12 -0
- package/dist/types/tools/vibe.d.ts +3 -1
- package/dist/types/tools/wait.d.ts +3 -0
- package/dist/types/tools/web-search-types.d.ts +90 -0
- package/dist/types/tools/web-search.d.ts +9 -168
- package/dist/types/tools/write.d.ts +14 -1
- package/dist/types/tools/xdev.d.ts +13 -0
- package/dist/types/tui.d.ts +49 -0
- package/package.json +9 -9
- package/src/apps/autoresearch-dashboard.ts +362 -4
- package/src/apps/cleanse-board.ts +219 -1
- package/src/apps/cleanse-picker.ts +9 -1
- package/src/apps/debug/log-viewer.ts +15 -15
- package/src/apps/debug/protocol-probe.ts +2 -20
- package/src/apps/git/avatar.ts +2 -22
- package/src/apps/git/git-tui.ts +406 -59
- package/src/apps/git/help.ts +130 -0
- package/src/apps/git/sidebar.ts +491 -0
- package/src/apps/live-visualizer.ts +65 -0
- package/src/apps/ps-top.ts +448 -17
- package/src/apps/session-picker.ts +1 -0
- package/src/apps/setup-model-picker.ts +5 -1
- package/src/apps/standalone-picker.ts +55 -1
- package/src/autocomplete.ts +44 -1
- package/src/chat/advisor-message.ts +72 -3
- package/src/chat/assistant-message.ts +538 -51
- package/src/chat/background-tan-message.ts +4 -4
- package/src/chat/bash-execution.ts +81 -0
- package/src/chat/cache-invalidation-marker.ts +8 -0
- package/src/chat/chat-transcript-builder.ts +37 -6
- package/src/chat/collab-prompt-message.ts +15 -3
- package/src/chat/compaction-summary-message.ts +74 -1
- package/src/chat/custom-message.ts +3 -1
- package/src/chat/eval-execution.ts +57 -0
- package/src/chat/execution-shared.ts +153 -1
- package/src/chat/hook-message.ts +1 -0
- package/src/chat/late-diagnostics-message.ts +85 -2
- package/src/chat/read-tool-group.ts +341 -1
- package/src/chat/served-model-marker.ts +8 -0
- package/src/chat/skill-message.ts +63 -0
- package/src/chat/stripped-tool-calls-placeholder.ts +18 -10
- package/src/chat/thinking-display.ts +73 -11
- package/src/chat/todo-reminder.ts +34 -4
- package/src/chat/tool-execution.ts +385 -10
- package/src/chat/transcript-actions.ts +38 -0
- package/src/chat/transcript-browser.ts +2 -9
- package/src/chat/transcript-entry.ts +10 -1
- package/src/chat/transcript-render-helpers.ts +16 -15
- package/src/chat/ttsr-notification.ts +38 -1
- package/src/chat/user-message.ts +167 -4
- package/src/chrome/collab-qrcode.ts +27 -2
- package/src/chrome/context-thresholds.ts +34 -0
- package/src/chrome/countdown-timer.ts +24 -1
- package/src/chrome/diff.ts +60 -1
- package/src/chrome/dynamic-border.ts +7 -0
- package/src/chrome/format.ts +12 -0
- package/src/chrome/message-divider.ts +33 -1
- package/src/chrome/message-frame.ts +53 -10
- package/src/chrome/message-notice.ts +71 -0
- package/src/chrome/overlay-box.ts +45 -2
- package/src/chrome/qrcode.ts +28 -0
- package/src/chrome/segment-track.ts +26 -0
- package/src/chrome/selector-helpers.ts +1 -17
- package/src/chrome/status-notice.ts +46 -0
- package/src/chrome/streaming-panel.ts +25 -1
- package/src/chrome/tool-activity.ts +20 -0
- package/src/chrome/transcript-container.ts +139 -17
- package/src/chrome/transcript-status.ts +40 -11
- package/src/components/box.ts +51 -0
- package/src/components/disclosure.ts +33 -0
- package/src/components/editor.ts +239 -36
- package/src/components/form.ts +93 -9
- package/src/components/image.ts +30 -0
- package/src/components/input.ts +77 -26
- package/src/components/key-value-list.ts +18 -0
- package/src/components/layout/geometry.ts +44 -0
- package/src/components/layout/row.ts +30 -0
- package/src/components/layout/split-pane.ts +65 -0
- package/src/components/layout/stack.ts +27 -0
- package/src/components/loader.ts +183 -1
- package/src/components/markdown.ts +131 -56
- package/src/components/metric.ts +39 -0
- package/src/components/progress-bar.ts +28 -0
- package/src/components/scroll-view.ts +23 -0
- package/src/components/section.ts +16 -0
- package/src/components/select-list.ts +174 -25
- package/src/components/settings-list.ts +264 -7
- package/src/components/spacer.ts +17 -0
- package/src/components/tab-bar.ts +42 -0
- package/src/components/table.ts +34 -0
- package/src/components/text.ts +23 -0
- package/src/components/tree-view.ts +65 -0
- package/src/components/truncated-text.ts +14 -0
- package/src/components/wizard-step.ts +18 -9
- package/src/debug-server.ts +14 -7
- package/src/hotkeys-markdown.ts +251 -69
- package/src/index.ts +6 -0
- package/src/latex-block.ts +11 -0
- package/src/loop-watchdog.ts +38 -10
- package/src/native/apply.ts +275 -0
- package/src/native/backend.ts +682 -0
- package/src/native/blobs.ts +70 -0
- package/src/native/describe.ts +124 -0
- package/src/native/encode.ts +233 -0
- package/src/native/icons.ts +184 -0
- package/src/native/memo.ts +64 -0
- package/src/native/node.ts +112 -0
- package/src/native/overlay.ts +131 -0
- package/src/native/picker.ts +333 -0
- package/src/native/reconcile.ts +1063 -0
- package/src/native/settle.ts +23 -0
- package/src/native/spans.ts +308 -0
- package/src/native/state.ts +28 -0
- package/src/native/tone.ts +79 -0
- package/src/overlays/advisor-config.ts +420 -0
- package/src/overlays/agent-hub-renderer.ts +155 -18
- package/src/overlays/agent-hub.ts +1037 -44
- package/src/overlays/agent-transcript-viewer.ts +129 -0
- package/src/overlays/agents-hub.ts +688 -53
- package/src/overlays/annotation-overlay.ts +391 -52
- package/src/overlays/ask-dialog.ts +435 -24
- package/src/overlays/bordered-loader.ts +17 -0
- package/src/overlays/btw-history-panel.ts +182 -0
- package/src/overlays/btw-panel.ts +68 -2
- package/src/overlays/cleanse-panel.ts +105 -15
- package/src/overlays/codex-reset-fireworks.ts +65 -5
- package/src/overlays/composer-shape-preview.ts +26 -1
- package/src/overlays/copy-selector.ts +545 -23
- package/src/overlays/error-banner.ts +44 -0
- package/src/overlays/extensions/extension-list.ts +23 -17
- package/src/overlays/history-search.ts +175 -33
- package/src/overlays/hook-editor.ts +113 -6
- package/src/overlays/hook-input.ts +22 -1
- package/src/overlays/hook-selector.ts +311 -22
- package/src/overlays/hub-frame.ts +80 -0
- package/src/overlays/jobs-panel.ts +112 -0
- package/src/overlays/login-dialog.ts +183 -1
- package/src/overlays/logout-account-selector.ts +102 -4
- package/src/overlays/mcp-add-wizard.ts +232 -53
- package/src/overlays/model-browser.ts +681 -22
- package/src/overlays/model-hub.ts +1402 -78
- package/src/overlays/model-picker.ts +184 -7
- package/src/overlays/move-overlay.ts +45 -0
- package/src/overlays/oauth-selector.ts +227 -23
- package/src/overlays/omfg-panel.ts +86 -2
- package/src/overlays/pause-screen.ts +55 -4
- package/src/overlays/plan-review-overlay.ts +352 -0
- package/src/overlays/plan-save-overlay.ts +45 -0
- package/src/overlays/plugin-selector.ts +21 -1
- package/src/overlays/plugin-settings.ts +195 -5
- package/src/overlays/queue-mode-selector.ts +19 -1
- package/src/overlays/reset-usage-selector.ts +110 -40
- package/src/overlays/rewind-selector.ts +458 -44
- package/src/overlays/session-account-selector.ts +1 -1
- package/src/overlays/session-info-overlay.ts +137 -1
- package/src/overlays/session-selector.ts +807 -46
- package/src/overlays/settings-defs.ts +41 -0
- package/src/overlays/settings-selector.ts +585 -33
- package/src/overlays/show-images-selector.ts +18 -1
- package/src/overlays/snapcompact-shape-preview.ts +48 -3
- package/src/overlays/stats-notice.ts +31 -0
- package/src/overlays/theme-selector.ts +31 -1
- package/src/overlays/thinking-selector.ts +22 -1
- package/src/overlays/tree-selector.ts +570 -110
- package/src/overlays/usage-dashboard.ts +587 -12
- package/src/overlays/usage-row.ts +161 -25
- package/src/prompt/attachment-chips.ts +60 -0
- package/src/prompt/composer-attachments.ts +31 -9
- package/src/prompt/composer.ts +55 -2
- package/src/prompt/custom-editor.ts +302 -4
- package/src/prompt/editor-top-gap.ts +8 -0
- package/src/prompt/macos-spelling.ts +24 -9
- package/src/prompt/magic-keywords.ts +22 -1
- package/src/prompt/model-mention-autocomplete.ts +1 -0
- package/src/prompt/queued-messages.ts +101 -0
- package/src/prompt/skill-tokens.ts +5 -3
- package/src/prompt/welcome.ts +213 -6
- package/src/render/code-cell.ts +103 -2
- package/src/render/file-list.ts +29 -0
- package/src/render/hyperlink.ts +32 -0
- package/src/render/output-block.ts +110 -0
- package/src/render/output-pane.ts +37 -0
- package/src/render/tool-card.ts +137 -0
- package/src/render/tree-list.ts +39 -0
- package/src/render/width-aware-text.ts +20 -0
- package/src/setup/scenes/composer.ts +29 -0
- package/src/setup/scenes/glyph.ts +15 -0
- package/src/setup/scenes/model.ts +36 -8
- package/src/setup/scenes/outro.ts +28 -1
- package/src/setup/scenes/sign-in.ts +138 -24
- package/src/setup/scenes/splash.ts +28 -1
- package/src/setup/scenes/theme.ts +88 -3
- package/src/setup/scenes/types.ts +7 -28
- package/src/setup/startup-splash.ts +46 -9
- package/src/setup/wizard-overlay.ts +140 -23
- package/src/setup/wizard.ts +1 -1
- package/src/status-line/component.ts +414 -18
- package/src/status-line/context-usage.ts +279 -50
- package/src/status-line/footer.ts +94 -1
- package/src/status-line/metrics.ts +3 -6
- package/src/status-line/segments.ts +463 -97
- package/src/status-line/separators.ts +3 -16
- package/src/status-line/types.ts +43 -1
- package/src/stdin-buffer.ts +27 -21
- package/src/terminal-capabilities.ts +7 -0
- package/src/terminal.ts +153 -11
- package/src/theme/defaults/dark-neon-noir.json +100 -0
- package/src/theme/defaults/index.ts +2 -0
- package/src/theme/defaults/light-prism.json +5 -5
- package/src/theme/defaults/onyx.json +62 -62
- package/src/theme/mermaid-cache.ts +10 -1
- package/src/theme/schema.ts +15 -0
- package/src/theme/shimmer.ts +33 -0
- package/src/theme/theme-class.ts +24 -19
- package/src/theme/theme.ts +111 -9
- package/src/theme/tui-adapters.ts +14 -1
- package/src/tools/ask.ts +157 -1
- package/src/tools/ast-edit.ts +174 -1
- package/src/tools/ast-grep.ts +82 -2
- package/src/tools/autoresearch.ts +149 -1
- package/src/tools/bash.ts +233 -62
- package/src/tools/cfg-render.ts +66 -1
- package/src/tools/debug.ts +78 -1
- package/src/tools/default-renderer.ts +35 -1
- package/src/tools/edit.ts +357 -31
- package/src/tools/eval.ts +257 -1
- package/src/tools/fetch.ts +102 -3
- package/src/tools/find.ts +127 -1
- package/src/tools/github.ts +119 -10
- package/src/tools/glob.ts +116 -1
- package/src/tools/goal.ts +56 -1
- package/src/tools/grep.ts +83 -2
- package/src/tools/grouped-file-output.ts +205 -0
- package/src/tools/json-tree.ts +116 -1
- package/src/tools/lsp.ts +318 -1
- package/src/tools/mcp.ts +80 -1
- package/src/tools/memory.ts +93 -11
- package/src/tools/native-view.ts +292 -0
- package/src/tools/proc-render.ts +221 -1
- package/src/tools/read.ts +199 -4
- package/src/tools/renderer.ts +61 -0
- package/src/tools/report-tool-issue.ts +7 -1
- package/src/tools/resolve.ts +63 -1
- package/src/tools/streaming-output.ts +79 -16
- package/src/tools/task.ts +406 -4
- package/src/tools/think.ts +19 -1
- package/src/tools/todo.ts +89 -0
- package/src/tools/vibe.ts +230 -2
- package/src/tools/wait.ts +181 -1
- package/src/tools/web-search-types.ts +99 -0
- package/src/tools/web-search.ts +111 -170
- package/src/tools/write.ts +144 -5
- package/src/tools/xdev.ts +64 -1
- package/src/tui.ts +295 -4
- package/dist/types/setup/scenes/providers.d.ts +0 -3
- package/dist/types/setup/scenes/web-search.d.ts +0 -22
- package/src/setup/scenes/providers.ts +0 -110
- package/src/setup/scenes/web-search.ts +0 -165
package/src/components/metric.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { styleSpans } from "../native/spans";
|
|
2
|
+
import { node, text } from "../native/describe";
|
|
3
|
+
import type { DescribeContext, NativeNode } from "../native/node";
|
|
1
4
|
import type { Component } from "../tui";
|
|
2
5
|
import { Ellipsis, getWidthConfigEpoch, truncateToWidth, visibleWidth } from "../utils";
|
|
3
6
|
import { Text } from "./text";
|
|
@@ -85,6 +88,7 @@ export class MetricRow implements Component {
|
|
|
85
88
|
readonly #options: MetricRowOptions;
|
|
86
89
|
readonly #text: Text;
|
|
87
90
|
#cache: { width: number; epoch: number; source: readonly string[]; lines: readonly string[] } | undefined;
|
|
91
|
+
#native: NativeNode | undefined;
|
|
88
92
|
|
|
89
93
|
constructor(metrics: readonly MetricSpec[], options: MetricRowOptions = {}) {
|
|
90
94
|
this.#metrics = metrics;
|
|
@@ -96,12 +100,47 @@ export class MetricRow implements Component {
|
|
|
96
100
|
if (this.#metrics === metrics) return false;
|
|
97
101
|
this.#metrics = metrics;
|
|
98
102
|
this.#cache = undefined;
|
|
103
|
+
this.#native = undefined;
|
|
99
104
|
return true;
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
invalidate(): void {
|
|
103
108
|
this.#text.invalidate();
|
|
104
109
|
this.#cache = undefined;
|
|
110
|
+
this.#native = undefined;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* `drop` overflow becomes a transparent `status` strip whose segments keep
|
|
115
|
+
* the metric priorities (the terminal drops the lowest first); the other
|
|
116
|
+
* modes are one text run that wraps or truncates.
|
|
117
|
+
*/
|
|
118
|
+
describe(_cx: DescribeContext): NativeNode {
|
|
119
|
+
if (this.#native) return this.#native;
|
|
120
|
+
const options = this.#options;
|
|
121
|
+
if (options.overflow === "drop") {
|
|
122
|
+
const segs: NativeNode[] = [];
|
|
123
|
+
this.#metrics.forEach((metric, index) => {
|
|
124
|
+
const formatted = formatMetric(metric);
|
|
125
|
+
if (formatted === undefined) return;
|
|
126
|
+
segs.push(
|
|
127
|
+
node(
|
|
128
|
+
"seg",
|
|
129
|
+
{ side: "left", priority: metric.priority ?? 0, spans: styleSpans(formatted, options.style) },
|
|
130
|
+
undefined,
|
|
131
|
+
String(index),
|
|
132
|
+
),
|
|
133
|
+
);
|
|
134
|
+
});
|
|
135
|
+
this.#native = node("status", { transparent: true }, segs);
|
|
136
|
+
return this.#native;
|
|
137
|
+
}
|
|
138
|
+
const joined = formatMetricRow(this.#metrics, { separator: options.separator });
|
|
139
|
+
this.#native =
|
|
140
|
+
options.overflow === "wrap"
|
|
141
|
+
? text(styleSpans(joined, options.style), { wrap: "word" })
|
|
142
|
+
: text(styleSpans(joined, options.style), { wrap: "none", truncate: "end" });
|
|
143
|
+
return this.#native;
|
|
105
144
|
}
|
|
106
145
|
|
|
107
146
|
render(width: number): readonly string[] {
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { compactText, styledSpans } from "../native/spans";
|
|
2
|
+
import { node } from "../native/describe";
|
|
3
|
+
import type { DescribeContext, NativeNode } from "../native/node";
|
|
1
4
|
import type { Component } from "../tui";
|
|
2
5
|
import { Ellipsis, getWidthConfigEpoch, truncateToWidth, visibleWidth } from "../utils";
|
|
3
6
|
|
|
@@ -87,6 +90,7 @@ export class ProgressBar implements Component {
|
|
|
87
90
|
#value: number | undefined;
|
|
88
91
|
readonly #options: ProgressBarOptions;
|
|
89
92
|
#cache: { width: number; epoch: number; value: number | undefined; lines: readonly string[] } | undefined;
|
|
93
|
+
#native: NativeNode | undefined;
|
|
90
94
|
|
|
91
95
|
constructor(value: number | undefined, options: ProgressBarOptions) {
|
|
92
96
|
this.#value = value;
|
|
@@ -97,11 +101,35 @@ export class ProgressBar implements Component {
|
|
|
97
101
|
if (Object.is(this.#value, value)) return false;
|
|
98
102
|
this.#value = value;
|
|
99
103
|
this.#cache = undefined;
|
|
104
|
+
this.#native = undefined;
|
|
100
105
|
return true;
|
|
101
106
|
}
|
|
102
107
|
|
|
103
108
|
invalidate(): void {
|
|
104
109
|
this.#cache = undefined;
|
|
110
|
+
this.#native = undefined;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** A native `progress` bar (indeterminate when the value is unknown); prefix, suffix and percentage label it. */
|
|
114
|
+
describe(_cx: DescribeContext): NativeNode {
|
|
115
|
+
if (this.#native) return this.#native;
|
|
116
|
+
const options = this.#options;
|
|
117
|
+
const fraction = progressFraction(this.#value, options.min, options.max);
|
|
118
|
+
const parts: string[] = [];
|
|
119
|
+
// Frame punctuation (`[`, `]`, `▕`) around the bar is the terminal's chrome now; only wording labels it.
|
|
120
|
+
const frame = /^[^\p{L}\p{N}]+|[^\p{L}\p{N}%)]+$/gu;
|
|
121
|
+
const prefix = singleLine(options.prefix ?? "").replace(frame, "");
|
|
122
|
+
const suffix = singleLine(options.suffix ?? "").replace(frame, "");
|
|
123
|
+
if (prefix) parts.push(prefix);
|
|
124
|
+
if (suffix) parts.push(suffix);
|
|
125
|
+
if (fraction !== undefined && options.showPercentage === true) {
|
|
126
|
+
parts.push(singleLine(options.formatPercentage?.(fraction) ?? `${Math.round(fraction * 100)}%`));
|
|
127
|
+
}
|
|
128
|
+
this.#native = node("progress", {
|
|
129
|
+
value: fraction ?? null,
|
|
130
|
+
label: parts.length > 0 ? compactText(styledSpans(parts.join(" "))) : undefined,
|
|
131
|
+
});
|
|
132
|
+
return this.#native;
|
|
105
133
|
}
|
|
106
134
|
|
|
107
135
|
render(width: number): readonly string[] {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { matchesKey } from "../keys";
|
|
2
|
+
import { rowsText } from "../native/spans";
|
|
3
|
+
import { col } from "../native/describe";
|
|
4
|
+
import type { DescribeContext, NativeNode } from "../native/node";
|
|
2
5
|
import type { Component } from "../tui";
|
|
3
6
|
import { Ellipsis, getWidthConfigEpoch, padding, replaceTabs, truncateToWidth, visibleWidth } from "../utils";
|
|
4
7
|
import {
|
|
@@ -126,6 +129,7 @@ export class ScrollView implements Component {
|
|
|
126
129
|
#rangeSnapshot: RangeSnapshot | undefined;
|
|
127
130
|
#cache: RenderCache | undefined;
|
|
128
131
|
#disposed = false;
|
|
132
|
+
#native: { content: readonly string[] | Component; height: number; node: NativeNode } | undefined;
|
|
129
133
|
|
|
130
134
|
constructor(content: readonly string[] | Component, options: ScrollViewOptions) {
|
|
131
135
|
this.#child = isComponent(content) ? content : undefined;
|
|
@@ -400,6 +404,7 @@ export class ScrollView implements Component {
|
|
|
400
404
|
invalidate(): void {
|
|
401
405
|
if (this.#disposed) return;
|
|
402
406
|
this.#cache = undefined;
|
|
407
|
+
this.#native = undefined;
|
|
403
408
|
this.#child?.invalidate?.();
|
|
404
409
|
}
|
|
405
410
|
|
|
@@ -415,6 +420,24 @@ export class ScrollView implements Component {
|
|
|
415
420
|
child?.dispose?.();
|
|
416
421
|
}
|
|
417
422
|
|
|
423
|
+
/**
|
|
424
|
+
* The whole content in a `col` capped at the viewport height: the
|
|
425
|
+
* terminal scrolls it natively and draws its own scrollbar.
|
|
426
|
+
*/
|
|
427
|
+
describe(_cx: DescribeContext): NativeNode {
|
|
428
|
+
const content = this.#child ?? this.#lines;
|
|
429
|
+
const cached = this.#native;
|
|
430
|
+
if (cached?.content === content && cached.height === this.#height) return cached.node;
|
|
431
|
+
const described = this.#disposed
|
|
432
|
+
? col([], { hidden: true })
|
|
433
|
+
: col([this.#child ?? rowsText(this.#lines)], {
|
|
434
|
+
max: { h: `${this.#height}lines` },
|
|
435
|
+
hidden: this.#height === 0 ? true : undefined,
|
|
436
|
+
});
|
|
437
|
+
this.#native = { content, height: this.#height, node: described };
|
|
438
|
+
return described;
|
|
439
|
+
}
|
|
440
|
+
|
|
418
441
|
render(width: number): readonly string[] {
|
|
419
442
|
if (this.#disposed) return EMPTY_LINES;
|
|
420
443
|
const safeWidth = normalizedRows(width);
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { compactText, rowsText, styledSpans } from "../native/spans";
|
|
2
|
+
import { node } from "../native/describe";
|
|
3
|
+
import type { DescribeContext, NativeNode } from "../native/node";
|
|
1
4
|
import type { Component } from "../tui";
|
|
2
5
|
import { Ellipsis, getWidthConfigEpoch, replaceTabs, truncateToWidth, visibleWidth } from "../utils";
|
|
3
6
|
|
|
@@ -37,6 +40,7 @@ export class Section implements Component {
|
|
|
37
40
|
readonly #options: SectionOptions;
|
|
38
41
|
#cache: { width: number; epoch: number; child: readonly string[]; lines: readonly string[] } | undefined;
|
|
39
42
|
#disposed = false;
|
|
43
|
+
#native: { title: string; node: NativeNode } | undefined;
|
|
40
44
|
|
|
41
45
|
constructor(options: SectionOptions) {
|
|
42
46
|
this.#options = options;
|
|
@@ -53,6 +57,18 @@ export class Section implements Component {
|
|
|
53
57
|
if (isComponent(this.#options.body)) this.#options.body.dispose?.();
|
|
54
58
|
}
|
|
55
59
|
|
|
60
|
+
/** A `section` headed by the styled title; the rule is the terminal's. */
|
|
61
|
+
describe(_cx: DescribeContext): NativeNode {
|
|
62
|
+
const options = this.#options;
|
|
63
|
+
const rawTitle = singleLine(options.title);
|
|
64
|
+
const title = options.titleStyle?.(rawTitle) ?? rawTitle;
|
|
65
|
+
if (this.#native?.title === title) return this.#native.node;
|
|
66
|
+
const body = isComponent(options.body) ? options.body : rowsText(options.body);
|
|
67
|
+
const described = node("section", { head: compactText(styledSpans(title)) }, [body]);
|
|
68
|
+
this.#native = { title, node: described };
|
|
69
|
+
return described;
|
|
70
|
+
}
|
|
71
|
+
|
|
56
72
|
render(width: number): readonly string[] {
|
|
57
73
|
const renderWidth = finiteWidth(width);
|
|
58
74
|
const epoch = getWidthConfigEpoch();
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { popLoopPhase, pushLoopPhase } from "@oh-my-pi/pi-utils";
|
|
2
|
+
import { Input } from "./input";
|
|
2
3
|
import { getMenuWindow, MenuSelection } from "./menu-selection";
|
|
3
4
|
import { getKeybindings } from "../keybindings";
|
|
4
5
|
import { extractPrintableText, matchesKey } from "../keys";
|
|
5
6
|
import { type MouseRoutable, routeSelectListMouse, type SgrMouseEvent } from "../mouse";
|
|
7
|
+
import { col, node, span } from "../native/describe";
|
|
8
|
+
import { sameItems, sameProps } from "../native/memo";
|
|
9
|
+
import { plainLine } from "../native/spans";
|
|
10
|
+
import type { TspProps } from "@oh-my-pi/pi-wire";
|
|
11
|
+
import type { DescribeContext, NativeChild, NativeNode, NativeUiEvent } from "../native/node";
|
|
6
12
|
import type { SymbolTheme } from "../symbols";
|
|
7
13
|
import type { Component } from "../tui";
|
|
8
14
|
import { Ellipsis, padding, replaceTabs, truncateToWidth, visibleWidth, wrapTextWithAnsi } from "../utils";
|
|
@@ -23,12 +29,25 @@ function sanitizeSingleLine(text: string): string {
|
|
|
23
29
|
|
|
24
30
|
const clamp = (value: number, min: number, max: number): number => Math.max(min, Math.min(value, max));
|
|
25
31
|
|
|
32
|
+
/** Described `item` node cached on the item, rebuilt only when its visible fields change. */
|
|
33
|
+
const kNativeItem = Symbol("selectList.nativeItem");
|
|
34
|
+
|
|
35
|
+
interface NativeDescribedItem extends SelectItem {
|
|
36
|
+
[kNativeItem]?: { signature: string; node: NativeNode };
|
|
37
|
+
}
|
|
38
|
+
|
|
26
39
|
export interface SelectItem {
|
|
27
40
|
value: string;
|
|
28
41
|
label: string;
|
|
29
42
|
description?: string;
|
|
30
43
|
/** Optional type-indicator glyph rendered in an aligned column before the label */
|
|
31
44
|
icon?: string;
|
|
45
|
+
/** Named icon a TSP terminal draws from its own set (replaces the {@link icon} glyph natively). */
|
|
46
|
+
iconName?: string;
|
|
47
|
+
/** Native detail text when it differs from the ANSI {@link description} (which may embed {@link state}). */
|
|
48
|
+
nativeDetail?: string;
|
|
49
|
+
/** Live state drawn right-aligned natively ("demo/demo", "off"). */
|
|
50
|
+
state?: string;
|
|
32
51
|
/** Dim hint text shown inline after cursor when this item is selected */
|
|
33
52
|
hint?: string;
|
|
34
53
|
/** Disabled rows stay visible but are skipped by navigation and cannot activate. */
|
|
@@ -153,6 +172,12 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
153
172
|
#hoveredIndex: number | null = null;
|
|
154
173
|
/** Per-render map of 0-based output line → filtered-item index. */
|
|
155
174
|
#hitRows: (number | undefined)[] = [];
|
|
175
|
+
#nativeList?: { props: TspProps<"list">; items: readonly NativeNode[]; node: NativeNode };
|
|
176
|
+
#nativeRoot?: { list: NativeNode; status: string; node: NativeNode };
|
|
177
|
+
/** Typed text marked at the start of native item labels (an autocomplete popup's query). */
|
|
178
|
+
#nativeMark: string | undefined;
|
|
179
|
+
/** The type-to-filter field; its value is pushed into the selection's query. */
|
|
180
|
+
readonly #search = new Input();
|
|
156
181
|
|
|
157
182
|
onSelect?: (item: SelectItem) => void;
|
|
158
183
|
onCancel?: () => void;
|
|
@@ -172,6 +197,7 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
172
197
|
requiresConfirmation: item => item.confirmation !== undefined,
|
|
173
198
|
filter: layout.filterItems,
|
|
174
199
|
});
|
|
200
|
+
this.#search.prompt = "";
|
|
175
201
|
}
|
|
176
202
|
/** Return item, selection, and filter state for debug inspection. */
|
|
177
203
|
debugState(): Record<string, unknown> {
|
|
@@ -193,8 +219,10 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
193
219
|
this.#maxVisible = Math.max(1, Math.trunc(rows));
|
|
194
220
|
}
|
|
195
221
|
|
|
222
|
+
/** Replace the filter text (caret to end) and refilter. */
|
|
196
223
|
setFilter(filter: string): void {
|
|
197
|
-
this.#
|
|
224
|
+
this.#search.setValue(filter);
|
|
225
|
+
this.#setFilter(this.#search.getValue(), true);
|
|
198
226
|
}
|
|
199
227
|
|
|
200
228
|
/** Replace controlled items while retaining the selected value when possible. */
|
|
@@ -215,6 +243,26 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
215
243
|
return this.#selection.query;
|
|
216
244
|
}
|
|
217
245
|
|
|
246
|
+
/**
|
|
247
|
+
* What a native `picker` shows: the filtered items in order, the selected
|
|
248
|
+
* and pending values, the query and its caret (UTF-16 offset).
|
|
249
|
+
*/
|
|
250
|
+
pickerView(): {
|
|
251
|
+
readonly items: readonly SelectItem[];
|
|
252
|
+
readonly selected: string | null;
|
|
253
|
+
readonly pending: string | null;
|
|
254
|
+
readonly query: string;
|
|
255
|
+
readonly cursor: number;
|
|
256
|
+
} {
|
|
257
|
+
return {
|
|
258
|
+
items: this.#selection.visibleItems,
|
|
259
|
+
selected: this.#selection.selectedKey ?? null,
|
|
260
|
+
pending: this.#selection.pendingKey ?? null,
|
|
261
|
+
query: this.#selection.query,
|
|
262
|
+
cursor: this.#search.getCursor(),
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
218
266
|
/** Resolve a 0-based rendered-line index to a filtered-item index. */
|
|
219
267
|
hitTest(line: number): number | undefined {
|
|
220
268
|
return this.#hitRows[line];
|
|
@@ -242,6 +290,95 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
242
290
|
routeSelectListMouse(this, event, line);
|
|
243
291
|
}
|
|
244
292
|
|
|
293
|
+
/**
|
|
294
|
+
* A `list` of `item`s keyed by item value, with the selection, the search
|
|
295
|
+
* query and the empty/no-match text, plus a status line (search query,
|
|
296
|
+
* pending confirmation, host status) under it when one applies.
|
|
297
|
+
*/
|
|
298
|
+
describe(_cx: DescribeContext): NativeNode {
|
|
299
|
+
const items: NativeNode[] = [];
|
|
300
|
+
for (const item of this.#selection.visibleItems) items.push(this.#describeItem(item));
|
|
301
|
+
const query = this.#selection.query;
|
|
302
|
+
const cachedMax = this.#nativeList?.props.max;
|
|
303
|
+
const props: TspProps<"list"> = {
|
|
304
|
+
selected: this.#selection.selectedKey ?? null,
|
|
305
|
+
filter: this.#nativeMark === undefined ? query.trim() || undefined : undefined,
|
|
306
|
+
empty:
|
|
307
|
+
query.trim().length > 0
|
|
308
|
+
? (this.layout.noMatchText ?? "No matching items")
|
|
309
|
+
: (this.layout.emptyText ?? "No items"),
|
|
310
|
+
max:
|
|
311
|
+
typeof cachedMax === "object" && cachedMax.lines === this.#maxVisible
|
|
312
|
+
? cachedMax
|
|
313
|
+
: { lines: this.#maxVisible },
|
|
314
|
+
};
|
|
315
|
+
const cachedList = this.#nativeList;
|
|
316
|
+
const list =
|
|
317
|
+
cachedList && sameProps(cachedList.props, props) && sameItems(cachedList.items, items)
|
|
318
|
+
? cachedList.node
|
|
319
|
+
: node("list", props, items, "list");
|
|
320
|
+
if (list !== cachedList?.node) this.#nativeList = { props, items, node: list };
|
|
321
|
+
|
|
322
|
+
const status = this.#shouldRenderSearchStatus() ? plainLine(this.#statusText()) : "";
|
|
323
|
+
const cachedRoot = this.#nativeRoot;
|
|
324
|
+
if (cachedRoot && cachedRoot.list === list && cachedRoot.status === status) return cachedRoot.node;
|
|
325
|
+
const children: NativeChild[] = [list];
|
|
326
|
+
if (status) children.push(node("text", { spans: [span(status, "muted")], wrap: "none" }, undefined, "status"));
|
|
327
|
+
const root = col(children, { role: "omp.select" });
|
|
328
|
+
this.#nativeRoot = { list, status, node: root };
|
|
329
|
+
return root;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Mark `typed` where it leads a native item label (`{s:"mark"}`), for lists
|
|
334
|
+
* whose items were matched against text outside the list (autocomplete).
|
|
335
|
+
* The list then sends no `filter`: the marks already say what matched.
|
|
336
|
+
*/
|
|
337
|
+
setNativeMark(typed: string): void {
|
|
338
|
+
this.#nativeMark = typed;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/** Pointer select/activate on an item does what a click does today: select it and request activation. */
|
|
342
|
+
handleNativeEvent(event: NativeUiEvent): void {
|
|
343
|
+
if (event.type !== "select" && event.type !== "activate") return;
|
|
344
|
+
const index = this.#selection.visibleItems.findIndex(item => item.value === event.item);
|
|
345
|
+
if (index >= 0) this.clickItem(index);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
#describeItem(item: NativeDescribedItem): NativeNode {
|
|
349
|
+
const pending = this.#selection.isPending(item);
|
|
350
|
+
const label = plainLine(this.#sanitizedLabel(item));
|
|
351
|
+
const description = plainLine((pending ? item.confirmation : this.#sanitizedDescription(item)) ?? "");
|
|
352
|
+
const detail = pending || item.nativeDetail === undefined ? description : plainLine(item.nativeDetail);
|
|
353
|
+
const icon = item.icon && item.iconName === undefined ? plainLine(item.icon) : "";
|
|
354
|
+
const state = item.state ? plainLine(item.state) : "";
|
|
355
|
+
const mark = this.#nativeMark ?? "";
|
|
356
|
+
const marked = mark.length > 0 && label.toLowerCase().startsWith(mark.toLowerCase()) ? mark.length : 0;
|
|
357
|
+
const signature =
|
|
358
|
+
`${label}\0${detail}\0${icon}\0${item.iconName}\0${state}\0${marked}\0` +
|
|
359
|
+
`${item.disabled === true}\0${pending}`;
|
|
360
|
+
const cached = item[kNativeItem];
|
|
361
|
+
if (cached?.signature === signature) return cached.node;
|
|
362
|
+
const name = marked === 0 ? [span(label)] : [span(label.slice(0, marked), "mark")];
|
|
363
|
+
if (marked > 0 && marked < label.length) name.push(span(label.slice(marked)));
|
|
364
|
+
const described = node(
|
|
365
|
+
"item",
|
|
366
|
+
{
|
|
367
|
+
// A named icon comes from the terminal's set; a bare glyph leads the label.
|
|
368
|
+
icon: item.iconName,
|
|
369
|
+
label: icon ? [span(`${icon} `, "muted"), ...name] : name,
|
|
370
|
+
detail: detail ? [span(detail, pending ? "warning" : "muted")] : undefined,
|
|
371
|
+
value: state ? [span(state, "muted")] : undefined,
|
|
372
|
+
disabled: item.disabled === true ? true : undefined,
|
|
373
|
+
tone: pending ? "warning" : undefined,
|
|
374
|
+
},
|
|
375
|
+
undefined,
|
|
376
|
+
item.value,
|
|
377
|
+
);
|
|
378
|
+
item[kNativeItem] = { signature, node: described };
|
|
379
|
+
return described;
|
|
380
|
+
}
|
|
381
|
+
|
|
245
382
|
invalidate(): void {
|
|
246
383
|
// No cached state to invalidate currently
|
|
247
384
|
}
|
|
@@ -356,14 +493,15 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
356
493
|
return;
|
|
357
494
|
}
|
|
358
495
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
496
|
+
// Typed text filters even when it collides with a navigation binding; then
|
|
497
|
+
// host navigation; every other key is the search field's.
|
|
498
|
+
if (extractPrintableText(keyData) !== undefined && this.#handleSearchInput(keyData)) return;
|
|
499
|
+
const wrap = this.layout.wrapNavigation !== false;
|
|
362
500
|
let selectionChanged = false;
|
|
363
501
|
if (kb.matches(keyData, "tui.select.up")) {
|
|
364
|
-
selectionChanged = this.#selection.move(-1,
|
|
502
|
+
selectionChanged = this.#selection.move(-1, wrap);
|
|
365
503
|
} else if (kb.matches(keyData, "tui.select.down")) {
|
|
366
|
-
selectionChanged = this.#selection.move(1,
|
|
504
|
+
selectionChanged = this.#selection.move(1, wrap);
|
|
367
505
|
} else if (kb.matches(keyData, "tui.select.pageUp")) {
|
|
368
506
|
selectionChanged = this.#selection.move(-this.#maxVisible);
|
|
369
507
|
} else if (kb.matches(keyData, "tui.select.pageDown")) {
|
|
@@ -373,7 +511,9 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
373
511
|
} else if (matchesKey(keyData, "end")) {
|
|
374
512
|
selectionChanged = this.#selection.moveToBoundary("last");
|
|
375
513
|
} else if (kb.matches(keyData, "tui.select.confirm") || keyData === "\n") {
|
|
376
|
-
this.#activateSelected();
|
|
514
|
+
if (this.#selection.visibleItems.length > 0) this.#activateSelected();
|
|
515
|
+
} else {
|
|
516
|
+
this.#handleSearchInput(keyData);
|
|
377
517
|
}
|
|
378
518
|
if (selectionChanged) this.#notifySelectionChange();
|
|
379
519
|
}
|
|
@@ -570,6 +710,21 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
570
710
|
}
|
|
571
711
|
|
|
572
712
|
#renderStatusLine(width: number): string {
|
|
713
|
+
const avail = Math.max(1, width - 2);
|
|
714
|
+
if (
|
|
715
|
+
this.layout.statusText === undefined &&
|
|
716
|
+
this.#selection.pendingKey === undefined &&
|
|
717
|
+
this.#selection.query.length > 0
|
|
718
|
+
) {
|
|
719
|
+
const label = truncateToWidth(" Search: ", avail, Ellipsis.Omit);
|
|
720
|
+
const fieldWidth = avail - visibleWidth(label);
|
|
721
|
+
const styled = this.theme.scrollInfo(label);
|
|
722
|
+
return fieldWidth > 0 ? styled + this.#search.render(fieldWidth)[0].trimEnd() : styled;
|
|
723
|
+
}
|
|
724
|
+
return this.theme.scrollInfo(truncateToWidth(this.#statusText(), avail, Ellipsis.Omit));
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
#statusText(): string {
|
|
573
728
|
const pendingItem =
|
|
574
729
|
this.#selection.pendingKey === undefined
|
|
575
730
|
? undefined
|
|
@@ -582,12 +737,10 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
582
737
|
totalCount: this.#selection.items.length,
|
|
583
738
|
pendingItem,
|
|
584
739
|
});
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
: (pendingItem?.confirmation ??
|
|
740
|
+
return this.layout.statusText !== undefined
|
|
741
|
+
? (custom ?? "")
|
|
742
|
+
: (pendingItem?.confirmation ??
|
|
589
743
|
(query ? ` Search: ${query}` : this.#canEditSearch() ? " Type to search" : ""));
|
|
590
|
-
return this.theme.scrollInfo(truncateToWidth(statusText, Math.max(1, width - 2), Ellipsis.Omit));
|
|
591
744
|
}
|
|
592
745
|
|
|
593
746
|
#shouldRenderSearchStatus(): boolean {
|
|
@@ -608,21 +761,17 @@ export class SelectList implements Component, MouseRoutable {
|
|
|
608
761
|
#handleSearchInput(keyData: string): boolean {
|
|
609
762
|
if (!this.#canEditSearch()) return false;
|
|
610
763
|
|
|
611
|
-
const
|
|
612
|
-
if (
|
|
613
|
-
if (
|
|
614
|
-
const
|
|
615
|
-
|
|
616
|
-
this.#setFilter(chars.join(""), true);
|
|
617
|
-
return true;
|
|
764
|
+
const before = this.#search.getValue();
|
|
765
|
+
if (before.length === 0) {
|
|
766
|
+
if (getKeybindings().matches(keyData, "tui.editor.deleteCharBackward")) return false;
|
|
767
|
+
const printableText = extractPrintableText(keyData);
|
|
768
|
+
if (printableText !== undefined && printableText.trim().length === 0) return false;
|
|
618
769
|
}
|
|
619
770
|
|
|
620
|
-
const
|
|
621
|
-
|
|
622
|
-
if (
|
|
623
|
-
|
|
624
|
-
this.#setFilter(this.#selection.query + printableText, true);
|
|
625
|
-
return true;
|
|
771
|
+
const consumed = this.#search.handleInput(keyData);
|
|
772
|
+
const after = this.#search.getValue();
|
|
773
|
+
if (after !== before) this.#setFilter(after, true);
|
|
774
|
+
return consumed;
|
|
626
775
|
}
|
|
627
776
|
|
|
628
777
|
#setFilter(filter: string, notify: boolean): void {
|