@oh-my-pi/pi-tui 18.4.3 → 18.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/dist/types/apps/cleanse-board.d.ts +17 -0
- package/dist/types/apps/git/help.d.ts +16 -0
- package/dist/types/apps/git/sidebar.d.ts +18 -0
- package/dist/types/apps/live-visualizer.d.ts +10 -0
- package/dist/types/apps/ps-top.d.ts +15 -0
- package/dist/types/apps/standalone-picker.d.ts +3 -0
- package/dist/types/autocomplete.d.ts +8 -0
- package/dist/types/chat/advisor-message.d.ts +12 -2
- package/dist/types/chat/assistant-message.d.ts +20 -0
- package/dist/types/chat/bash-execution.d.ts +9 -0
- package/dist/types/chat/chat-transcript-builder.d.ts +6 -1
- package/dist/types/chat/collab-prompt-message.d.ts +4 -0
- package/dist/types/chat/compaction-summary-message.d.ts +15 -0
- package/dist/types/chat/eval-execution.d.ts +8 -0
- package/dist/types/chat/execution-shared.d.ts +58 -0
- package/dist/types/chat/late-diagnostics-message.d.ts +15 -1
- package/dist/types/chat/read-tool-group.d.ts +15 -0
- package/dist/types/chat/skill-message.d.ts +9 -0
- package/dist/types/chat/stripped-tool-calls-placeholder.d.ts +3 -0
- package/dist/types/chat/todo-reminder.d.ts +4 -1
- package/dist/types/chat/tool-execution.d.ts +25 -1
- package/dist/types/chat/transcript-actions.d.ts +37 -0
- package/dist/types/chat/transcript-entry.d.ts +3 -1
- package/dist/types/chat/user-message.d.ts +25 -0
- package/dist/types/chrome/collab-qrcode.d.ts +7 -0
- package/dist/types/chrome/context-thresholds.d.ts +11 -0
- package/dist/types/chrome/countdown-timer.d.ts +9 -3
- package/dist/types/chrome/diff.d.ts +12 -0
- package/dist/types/chrome/dynamic-border.d.ts +3 -0
- package/dist/types/chrome/format.d.ts +6 -0
- package/dist/types/chrome/message-divider.d.ts +13 -0
- package/dist/types/chrome/message-frame.d.ts +10 -0
- package/dist/types/chrome/message-notice.d.ts +23 -0
- package/dist/types/chrome/overlay-box.d.ts +11 -2
- package/dist/types/chrome/qrcode.d.ts +7 -0
- package/dist/types/chrome/segment-track.d.ts +7 -0
- package/dist/types/chrome/selector-helpers.d.ts +0 -6
- package/dist/types/chrome/status-notice.d.ts +14 -0
- package/dist/types/chrome/streaming-panel.d.ts +3 -0
- package/dist/types/chrome/tool-activity.d.ts +3 -0
- package/dist/types/chrome/transcript-container.d.ts +13 -0
- package/dist/types/chrome/transcript-status.d.ts +15 -3
- package/dist/types/components/box.d.ts +7 -0
- package/dist/types/components/disclosure.d.ts +9 -0
- package/dist/types/components/editor.d.ts +37 -0
- package/dist/types/components/form.d.ts +14 -0
- package/dist/types/components/image.d.ts +7 -0
- package/dist/types/components/input.d.ts +20 -1
- package/dist/types/components/key-value-list.d.ts +3 -0
- package/dist/types/components/layout/geometry.d.ts +16 -0
- package/dist/types/components/layout/row.d.ts +7 -0
- package/dist/types/components/layout/split-pane.d.ts +8 -0
- package/dist/types/components/layout/stack.d.ts +6 -0
- package/dist/types/components/loader.d.ts +48 -0
- package/dist/types/components/markdown.d.ts +8 -0
- package/dist/types/components/metric.d.ts +7 -0
- package/dist/types/components/progress-bar.d.ts +3 -0
- package/dist/types/components/scroll-view.d.ts +6 -0
- package/dist/types/components/section.d.ts +3 -0
- package/dist/types/components/select-list.d.ts +33 -0
- package/dist/types/components/settings-list.d.ts +68 -0
- package/dist/types/components/spacer.d.ts +4 -0
- package/dist/types/components/tab-bar.d.ts +9 -0
- package/dist/types/components/table.d.ts +7 -0
- package/dist/types/components/text.d.ts +6 -0
- package/dist/types/components/tree-view.d.ts +9 -0
- package/dist/types/components/truncated-text.d.ts +3 -0
- package/dist/types/components/wizard-step.d.ts +6 -0
- package/dist/types/hotkeys-markdown.d.ts +24 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/latex-block.d.ts +7 -0
- package/dist/types/native/apply.d.ts +39 -0
- package/dist/types/native/backend.d.ts +94 -0
- package/dist/types/native/blobs.d.ts +29 -0
- package/dist/types/native/describe.d.ts +56 -0
- package/dist/types/native/encode.d.ts +50 -0
- package/dist/types/native/icons.d.ts +18 -0
- package/dist/types/native/memo.d.ts +27 -0
- package/dist/types/native/node.d.ts +107 -0
- package/dist/types/native/overlay.d.ts +64 -0
- package/dist/types/native/picker.d.ts +124 -0
- package/dist/types/native/reconcile.d.ts +41 -0
- package/dist/types/native/settle.d.ts +11 -0
- package/dist/types/native/spans.d.ts +21 -0
- package/dist/types/native/state.d.ts +6 -0
- package/dist/types/native/tone.d.ts +24 -0
- package/dist/types/overlays/advisor-config.d.ts +20 -0
- package/dist/types/overlays/agent-hub-renderer.d.ts +27 -11
- package/dist/types/overlays/agent-hub.d.ts +10 -0
- package/dist/types/overlays/agent-transcript-viewer.d.ts +7 -0
- package/dist/types/overlays/agents-hub.d.ts +8 -0
- package/dist/types/overlays/annotation-overlay.d.ts +3 -0
- package/dist/types/overlays/ask-dialog.d.ts +23 -0
- package/dist/types/overlays/bordered-loader.d.ts +3 -0
- package/dist/types/overlays/btw-history-panel.d.ts +9 -0
- package/dist/types/overlays/btw-panel.d.ts +3 -0
- package/dist/types/overlays/cleanse-panel.d.ts +5 -2
- package/dist/types/overlays/composer-shape-preview.d.ts +7 -1
- package/dist/types/overlays/copy-selector.d.ts +38 -0
- package/dist/types/overlays/error-banner.d.ts +9 -0
- package/dist/types/overlays/extensions/extension-list.d.ts +1 -0
- package/dist/types/overlays/history-search.d.ts +18 -0
- package/dist/types/overlays/hook-editor.d.ts +28 -1
- package/dist/types/overlays/hook-input.d.ts +3 -0
- package/dist/types/overlays/hook-selector.d.ts +10 -0
- package/dist/types/overlays/hub-frame.d.ts +18 -0
- package/dist/types/overlays/jobs-panel.d.ts +24 -0
- package/dist/types/overlays/login-dialog.d.ts +10 -0
- package/dist/types/overlays/logout-account-selector.d.ts +4 -0
- package/dist/types/overlays/mcp-add-wizard.d.ts +4 -0
- package/dist/types/overlays/model-browser.d.ts +69 -0
- package/dist/types/overlays/model-hub.d.ts +7 -0
- package/dist/types/overlays/model-picker.d.ts +7 -0
- package/dist/types/overlays/move-overlay.d.ts +3 -0
- package/dist/types/overlays/oauth-selector.d.ts +4 -0
- package/dist/types/overlays/omfg-panel.d.ts +3 -0
- package/dist/types/overlays/pause-screen.d.ts +12 -0
- package/dist/types/overlays/plan-review-overlay.d.ts +5 -0
- package/dist/types/overlays/plan-save-overlay.d.ts +10 -0
- package/dist/types/overlays/plugin-selector.d.ts +4 -0
- package/dist/types/overlays/plugin-settings.d.ts +30 -0
- package/dist/types/overlays/queue-mode-selector.d.ts +4 -0
- package/dist/types/overlays/reset-usage-selector.d.ts +8 -0
- package/dist/types/overlays/rewind-selector.d.ts +5 -0
- package/dist/types/overlays/session-info-overlay.d.ts +19 -1
- package/dist/types/overlays/session-selector.d.ts +64 -1
- package/dist/types/overlays/settings-defs.d.ts +14 -0
- package/dist/types/overlays/settings-selector.d.ts +21 -0
- package/dist/types/overlays/show-images-selector.d.ts +4 -0
- package/dist/types/overlays/snapcompact-shape-preview.d.ts +2 -0
- package/dist/types/overlays/stats-notice.d.ts +8 -0
- package/dist/types/overlays/theme-selector.d.ts +11 -0
- package/dist/types/overlays/thinking-selector.d.ts +4 -0
- package/dist/types/overlays/tree-selector.d.ts +60 -2
- package/dist/types/overlays/usage-dashboard.d.ts +26 -3
- package/dist/types/overlays/usage-row.d.ts +36 -2
- package/dist/types/prompt/attachment-chips.d.ts +8 -0
- package/dist/types/prompt/composer-attachments.d.ts +15 -3
- package/dist/types/prompt/composer.d.ts +18 -1
- package/dist/types/prompt/custom-editor.d.ts +48 -2
- package/dist/types/prompt/editor-top-gap.d.ts +2 -0
- package/dist/types/prompt/macos-spelling.d.ts +6 -0
- package/dist/types/prompt/magic-keywords.d.ts +9 -0
- package/dist/types/prompt/queued-messages.d.ts +23 -0
- package/dist/types/prompt/skill-tokens.d.ts +4 -2
- package/dist/types/prompt/welcome.d.ts +16 -0
- package/dist/types/render/code-cell.d.ts +10 -0
- package/dist/types/render/file-list.d.ts +8 -0
- package/dist/types/render/hyperlink.d.ts +14 -0
- package/dist/types/render/output-block.d.ts +43 -0
- package/dist/types/render/output-pane.d.ts +17 -0
- package/dist/types/render/tool-card.d.ts +8 -0
- package/dist/types/render/tree-list.d.ts +8 -0
- package/dist/types/render/width-aware-text.d.ts +7 -0
- package/dist/types/setup/scenes/outro.d.ts +7 -0
- package/dist/types/setup/scenes/sign-in.d.ts +7 -0
- package/dist/types/setup/scenes/splash.d.ts +8 -0
- package/dist/types/setup/scenes/types.d.ts +6 -1
- package/dist/types/setup/wizard-overlay.d.ts +9 -0
- package/dist/types/status-line/component.d.ts +49 -5
- package/dist/types/status-line/context-usage.d.ts +20 -0
- package/dist/types/status-line/footer.d.ts +8 -0
- package/dist/types/status-line/metrics.d.ts +1 -2
- package/dist/types/status-line/segments.d.ts +10 -1
- package/dist/types/status-line/types.d.ts +40 -1
- package/dist/types/terminal-capabilities.d.ts +1 -1
- package/dist/types/terminal.d.ts +27 -0
- package/dist/types/theme/defaults/index.d.ts +100 -0
- package/dist/types/theme/schema.d.ts +2 -0
- package/dist/types/theme/shimmer.d.ts +8 -0
- package/dist/types/theme/theme-class.d.ts +2 -0
- package/dist/types/theme/theme.d.ts +33 -1
- package/dist/types/tools/ask.d.ts +3 -0
- package/dist/types/tools/ast-edit.d.ts +10 -1
- package/dist/types/tools/ast-grep.d.ts +10 -1
- package/dist/types/tools/autoresearch.d.ts +21 -4
- package/dist/types/tools/bash.d.ts +30 -1
- package/dist/types/tools/cfg-render.d.ts +5 -1
- package/dist/types/tools/debug.d.ts +3 -1
- package/dist/types/tools/default-renderer.d.ts +6 -1
- package/dist/types/tools/edit.d.ts +14 -1
- package/dist/types/tools/eval.d.ts +12 -1
- package/dist/types/tools/fetch.d.ts +16 -1
- package/dist/types/tools/find.d.ts +15 -1
- package/dist/types/tools/github.d.ts +3 -0
- package/dist/types/tools/glob.d.ts +14 -1
- package/dist/types/tools/goal.d.ts +3 -1
- package/dist/types/tools/grep.d.ts +14 -1
- package/dist/types/tools/grouped-file-output.d.ts +58 -0
- package/dist/types/tools/json-tree.d.ts +20 -0
- package/dist/types/tools/lsp.d.ts +3 -10
- package/dist/types/tools/mcp.d.ts +16 -1
- package/dist/types/tools/memory.d.ts +26 -0
- package/dist/types/tools/native-view.d.ts +90 -0
- package/dist/types/tools/proc-render.d.ts +7 -1
- package/dist/types/tools/read.d.ts +23 -1
- package/dist/types/tools/renderer.d.ts +57 -0
- package/dist/types/tools/report-tool-issue.d.ts +3 -0
- package/dist/types/tools/resolve.d.ts +14 -1
- package/dist/types/tools/task.d.ts +3 -0
- package/dist/types/tools/think.d.ts +3 -0
- package/dist/types/tools/todo.d.ts +12 -0
- package/dist/types/tools/vibe.d.ts +3 -1
- package/dist/types/tools/wait.d.ts +3 -0
- package/dist/types/tools/web-search.d.ts +8 -0
- package/dist/types/tools/write.d.ts +14 -1
- package/dist/types/tools/xdev.d.ts +13 -0
- package/dist/types/tui.d.ts +49 -0
- package/package.json +9 -9
- package/src/apps/autoresearch-dashboard.ts +362 -4
- package/src/apps/cleanse-board.ts +219 -1
- package/src/apps/cleanse-picker.ts +9 -1
- package/src/apps/debug/log-viewer.ts +15 -15
- package/src/apps/debug/protocol-probe.ts +2 -20
- package/src/apps/git/avatar.ts +2 -22
- package/src/apps/git/git-tui.ts +406 -59
- package/src/apps/git/help.ts +130 -0
- package/src/apps/git/sidebar.ts +491 -0
- package/src/apps/live-visualizer.ts +65 -0
- package/src/apps/ps-top.ts +448 -17
- package/src/apps/session-picker.ts +1 -0
- package/src/apps/setup-model-picker.ts +5 -1
- package/src/apps/standalone-picker.ts +55 -1
- package/src/autocomplete.ts +44 -1
- package/src/chat/advisor-message.ts +72 -3
- package/src/chat/assistant-message.ts +346 -11
- package/src/chat/background-tan-message.ts +4 -4
- package/src/chat/bash-execution.ts +81 -0
- package/src/chat/cache-invalidation-marker.ts +8 -0
- package/src/chat/chat-transcript-builder.ts +37 -6
- package/src/chat/collab-prompt-message.ts +15 -3
- package/src/chat/compaction-summary-message.ts +74 -1
- package/src/chat/custom-message.ts +3 -1
- package/src/chat/eval-execution.ts +57 -0
- package/src/chat/execution-shared.ts +153 -1
- package/src/chat/hook-message.ts +1 -0
- package/src/chat/late-diagnostics-message.ts +85 -2
- package/src/chat/read-tool-group.ts +341 -1
- package/src/chat/served-model-marker.ts +8 -0
- package/src/chat/skill-message.ts +63 -0
- package/src/chat/stripped-tool-calls-placeholder.ts +18 -10
- package/src/chat/todo-reminder.ts +34 -4
- package/src/chat/tool-execution.ts +385 -10
- package/src/chat/transcript-actions.ts +38 -0
- package/src/chat/transcript-browser.ts +2 -9
- package/src/chat/transcript-entry.ts +10 -1
- package/src/chat/transcript-render-helpers.ts +16 -15
- package/src/chat/ttsr-notification.ts +38 -1
- package/src/chat/user-message.ts +167 -4
- package/src/chrome/collab-qrcode.ts +27 -2
- package/src/chrome/context-thresholds.ts +34 -0
- package/src/chrome/countdown-timer.ts +24 -1
- package/src/chrome/diff.ts +60 -1
- package/src/chrome/dynamic-border.ts +7 -0
- package/src/chrome/format.ts +12 -0
- package/src/chrome/message-divider.ts +33 -1
- package/src/chrome/message-frame.ts +53 -10
- package/src/chrome/message-notice.ts +71 -0
- package/src/chrome/overlay-box.ts +45 -2
- package/src/chrome/qrcode.ts +28 -0
- package/src/chrome/segment-track.ts +26 -0
- package/src/chrome/selector-helpers.ts +1 -17
- package/src/chrome/status-notice.ts +46 -0
- package/src/chrome/streaming-panel.ts +25 -1
- package/src/chrome/tool-activity.ts +20 -0
- package/src/chrome/transcript-container.ts +37 -0
- package/src/chrome/transcript-status.ts +40 -11
- package/src/components/box.ts +51 -0
- package/src/components/disclosure.ts +33 -0
- package/src/components/editor.ts +216 -27
- package/src/components/form.ts +93 -9
- package/src/components/image.ts +30 -0
- package/src/components/input.ts +77 -26
- package/src/components/key-value-list.ts +18 -0
- package/src/components/layout/geometry.ts +44 -0
- package/src/components/layout/row.ts +30 -0
- package/src/components/layout/split-pane.ts +65 -0
- package/src/components/layout/stack.ts +27 -0
- package/src/components/loader.ts +183 -1
- package/src/components/markdown.ts +21 -0
- package/src/components/metric.ts +39 -0
- package/src/components/progress-bar.ts +28 -0
- package/src/components/scroll-view.ts +23 -0
- package/src/components/section.ts +16 -0
- package/src/components/select-list.ts +174 -25
- package/src/components/settings-list.ts +264 -7
- package/src/components/spacer.ts +17 -0
- package/src/components/tab-bar.ts +42 -0
- package/src/components/table.ts +34 -0
- package/src/components/text.ts +23 -0
- package/src/components/tree-view.ts +65 -0
- package/src/components/truncated-text.ts +14 -0
- package/src/components/wizard-step.ts +18 -9
- package/src/debug-server.ts +14 -7
- package/src/hotkeys-markdown.ts +251 -69
- package/src/index.ts +6 -0
- package/src/latex-block.ts +11 -0
- package/src/native/apply.ts +275 -0
- package/src/native/backend.ts +682 -0
- package/src/native/blobs.ts +70 -0
- package/src/native/describe.ts +124 -0
- package/src/native/encode.ts +233 -0
- package/src/native/icons.ts +184 -0
- package/src/native/memo.ts +64 -0
- package/src/native/node.ts +112 -0
- package/src/native/overlay.ts +131 -0
- package/src/native/picker.ts +333 -0
- package/src/native/reconcile.ts +1063 -0
- package/src/native/settle.ts +23 -0
- package/src/native/spans.ts +308 -0
- package/src/native/state.ts +28 -0
- package/src/native/tone.ts +79 -0
- package/src/overlays/advisor-config.ts +420 -0
- package/src/overlays/agent-hub-renderer.ts +155 -18
- package/src/overlays/agent-hub.ts +1037 -44
- package/src/overlays/agent-transcript-viewer.ts +129 -0
- package/src/overlays/agents-hub.ts +688 -53
- package/src/overlays/annotation-overlay.ts +391 -52
- package/src/overlays/ask-dialog.ts +435 -24
- package/src/overlays/bordered-loader.ts +17 -0
- package/src/overlays/btw-history-panel.ts +182 -0
- package/src/overlays/btw-panel.ts +68 -2
- package/src/overlays/cleanse-panel.ts +105 -15
- package/src/overlays/codex-reset-fireworks.ts +65 -5
- package/src/overlays/composer-shape-preview.ts +26 -1
- package/src/overlays/copy-selector.ts +545 -23
- package/src/overlays/error-banner.ts +44 -0
- package/src/overlays/extensions/extension-list.ts +23 -17
- package/src/overlays/history-search.ts +175 -33
- package/src/overlays/hook-editor.ts +113 -6
- package/src/overlays/hook-input.ts +22 -1
- package/src/overlays/hook-selector.ts +311 -22
- package/src/overlays/hub-frame.ts +80 -0
- package/src/overlays/jobs-panel.ts +112 -0
- package/src/overlays/login-dialog.ts +183 -1
- package/src/overlays/logout-account-selector.ts +102 -4
- package/src/overlays/mcp-add-wizard.ts +232 -53
- package/src/overlays/model-browser.ts +681 -22
- package/src/overlays/model-hub.ts +1402 -78
- package/src/overlays/model-picker.ts +175 -1
- package/src/overlays/move-overlay.ts +45 -0
- package/src/overlays/oauth-selector.ts +227 -23
- package/src/overlays/omfg-panel.ts +86 -2
- package/src/overlays/pause-screen.ts +55 -4
- package/src/overlays/plan-review-overlay.ts +352 -0
- package/src/overlays/plan-save-overlay.ts +45 -0
- package/src/overlays/plugin-selector.ts +21 -1
- package/src/overlays/plugin-settings.ts +195 -5
- package/src/overlays/queue-mode-selector.ts +19 -1
- package/src/overlays/reset-usage-selector.ts +110 -40
- package/src/overlays/rewind-selector.ts +458 -44
- package/src/overlays/session-account-selector.ts +1 -1
- package/src/overlays/session-info-overlay.ts +137 -1
- package/src/overlays/session-selector.ts +807 -46
- package/src/overlays/settings-defs.ts +41 -0
- package/src/overlays/settings-selector.ts +583 -23
- package/src/overlays/show-images-selector.ts +18 -1
- package/src/overlays/snapcompact-shape-preview.ts +48 -3
- package/src/overlays/stats-notice.ts +31 -0
- package/src/overlays/theme-selector.ts +31 -1
- package/src/overlays/thinking-selector.ts +22 -1
- package/src/overlays/tree-selector.ts +570 -110
- package/src/overlays/usage-dashboard.ts +587 -12
- package/src/overlays/usage-row.ts +161 -25
- package/src/prompt/attachment-chips.ts +60 -0
- package/src/prompt/composer-attachments.ts +31 -9
- package/src/prompt/composer.ts +55 -2
- package/src/prompt/custom-editor.ts +302 -4
- package/src/prompt/editor-top-gap.ts +8 -0
- package/src/prompt/macos-spelling.ts +24 -9
- package/src/prompt/magic-keywords.ts +22 -1
- package/src/prompt/model-mention-autocomplete.ts +1 -0
- package/src/prompt/queued-messages.ts +101 -0
- package/src/prompt/skill-tokens.ts +5 -3
- package/src/prompt/welcome.ts +213 -6
- package/src/render/code-cell.ts +103 -2
- package/src/render/file-list.ts +29 -0
- package/src/render/hyperlink.ts +32 -0
- package/src/render/output-block.ts +110 -0
- package/src/render/output-pane.ts +37 -0
- package/src/render/tool-card.ts +137 -0
- package/src/render/tree-list.ts +39 -0
- package/src/render/width-aware-text.ts +20 -0
- package/src/setup/scenes/composer.ts +29 -0
- package/src/setup/scenes/glyph.ts +15 -0
- package/src/setup/scenes/model.ts +36 -8
- package/src/setup/scenes/outro.ts +28 -1
- package/src/setup/scenes/sign-in.ts +122 -13
- package/src/setup/scenes/splash.ts +28 -1
- package/src/setup/scenes/theme.ts +88 -3
- package/src/setup/scenes/types.ts +7 -1
- package/src/setup/startup-splash.ts +46 -9
- package/src/setup/wizard-overlay.ts +140 -23
- package/src/status-line/component.ts +398 -16
- package/src/status-line/context-usage.ts +279 -50
- package/src/status-line/footer.ts +94 -1
- package/src/status-line/metrics.ts +3 -6
- package/src/status-line/segments.ts +463 -97
- package/src/status-line/separators.ts +3 -16
- package/src/status-line/types.ts +43 -1
- package/src/terminal-capabilities.ts +7 -0
- package/src/terminal.ts +130 -2
- package/src/theme/defaults/dark-neon-noir.json +100 -0
- package/src/theme/defaults/index.ts +2 -0
- package/src/theme/defaults/light-prism.json +5 -5
- package/src/theme/defaults/onyx.json +62 -62
- package/src/theme/schema.ts +15 -0
- package/src/theme/shimmer.ts +33 -0
- package/src/theme/theme-class.ts +24 -19
- package/src/theme/theme.ts +111 -9
- package/src/tools/ask.ts +157 -1
- package/src/tools/ast-edit.ts +174 -1
- package/src/tools/ast-grep.ts +82 -2
- package/src/tools/autoresearch.ts +149 -1
- package/src/tools/bash.ts +180 -49
- package/src/tools/cfg-render.ts +66 -1
- package/src/tools/debug.ts +78 -1
- package/src/tools/default-renderer.ts +35 -1
- package/src/tools/edit.ts +247 -2
- package/src/tools/eval.ts +257 -1
- package/src/tools/fetch.ts +102 -3
- package/src/tools/find.ts +127 -1
- package/src/tools/github.ts +119 -10
- package/src/tools/glob.ts +116 -1
- package/src/tools/goal.ts +56 -1
- package/src/tools/grep.ts +83 -2
- package/src/tools/grouped-file-output.ts +205 -0
- package/src/tools/json-tree.ts +116 -1
- package/src/tools/lsp.ts +318 -1
- package/src/tools/mcp.ts +80 -1
- package/src/tools/memory.ts +93 -11
- package/src/tools/native-view.ts +292 -0
- package/src/tools/proc-render.ts +221 -1
- package/src/tools/read.ts +199 -4
- package/src/tools/renderer.ts +61 -0
- package/src/tools/report-tool-issue.ts +7 -1
- package/src/tools/resolve.ts +63 -1
- package/src/tools/task.ts +406 -4
- package/src/tools/think.ts +19 -1
- package/src/tools/todo.ts +89 -0
- package/src/tools/vibe.ts +230 -2
- package/src/tools/wait.ts +181 -1
- package/src/tools/web-search.ts +113 -1
- package/src/tools/write.ts +144 -5
- package/src/tools/xdev.ts +64 -1
- package/src/tui.ts +294 -3
|
@@ -1,27 +1,56 @@
|
|
|
1
|
+
import type { TspSpan } from "@oh-my-pi/pi-wire";
|
|
1
2
|
import { Text } from "../components/text";
|
|
3
|
+
import { col, span, text } from "../native/describe";
|
|
4
|
+
import type { NativeNode } from "../native/node";
|
|
5
|
+
import { type ThemeColor, theme } from "../theme";
|
|
2
6
|
import { TranscriptBlock } from "./transcript-container";
|
|
3
7
|
|
|
4
|
-
/** One
|
|
8
|
+
/** One themed run of a status row. */
|
|
9
|
+
export interface TranscriptStatusPart {
|
|
10
|
+
readonly text: string;
|
|
11
|
+
readonly color: ThemeColor;
|
|
12
|
+
/** Glyph art (tree connectors) drawn only in rows; native terminals draw their own structure. */
|
|
13
|
+
readonly rowsOnly?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** One compact transcript status row assembled from themed parts, joined by single spaces. */
|
|
5
17
|
export interface TranscriptStatusRow {
|
|
6
|
-
readonly parts: readonly (
|
|
18
|
+
readonly parts: readonly (TranscriptStatusPart | undefined)[];
|
|
7
19
|
readonly indent?: number;
|
|
8
20
|
}
|
|
9
21
|
|
|
10
22
|
/** Shared compact status-pill block used by notices and background activity. */
|
|
11
23
|
export class TranscriptStatusBlock extends TranscriptBlock {
|
|
24
|
+
readonly #rows: TspSpan[][] = [];
|
|
25
|
+
#native: NativeNode | undefined;
|
|
26
|
+
|
|
12
27
|
constructor(rows: readonly TranscriptStatusRow[]) {
|
|
13
28
|
super();
|
|
14
|
-
for (const row of rows)
|
|
15
|
-
const parts: string[] = [];
|
|
16
|
-
for (const part of row.parts) {
|
|
17
|
-
if (part) parts.push(part);
|
|
18
|
-
}
|
|
19
|
-
this.addChild(new Text(parts.join(" "), row.indent ?? 1, 0));
|
|
20
|
-
}
|
|
29
|
+
for (const row of rows) this.addLine(row.parts, row.indent);
|
|
21
30
|
}
|
|
22
31
|
|
|
23
32
|
/** Append a supplemental line such as an artifact warning. */
|
|
24
|
-
addLine(
|
|
25
|
-
|
|
33
|
+
addLine(parts: readonly (TranscriptStatusPart | undefined)[], indent = 1): void {
|
|
34
|
+
const styled: string[] = [];
|
|
35
|
+
const spans: TspSpan[] = [];
|
|
36
|
+
for (const part of parts) {
|
|
37
|
+
if (!part) continue;
|
|
38
|
+
styled.push(theme.fg(part.color, part.text));
|
|
39
|
+
if (part.rowsOnly) continue;
|
|
40
|
+
if (spans.length > 0) spans.push(span(" "));
|
|
41
|
+
spans.push(span(part.text, part.color));
|
|
42
|
+
}
|
|
43
|
+
this.addChild(new Text(styled.join(" "), indent, 0));
|
|
44
|
+
this.#rows.push(spans);
|
|
45
|
+
this.#native = undefined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** One wrapped text line per status row. */
|
|
49
|
+
override describe(): NativeNode {
|
|
50
|
+
this.#native ??= col(
|
|
51
|
+
this.#rows.map(spans => text(spans, { wrap: "word" })),
|
|
52
|
+
{ role: "omp.status-block" },
|
|
53
|
+
);
|
|
54
|
+
return this.#native;
|
|
26
55
|
}
|
|
27
56
|
}
|
package/src/components/box.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { backgroundChrome, colorTone, sampleBackground, sampleForeground } from "../native/tone";
|
|
2
|
+
import { sameItems } from "../native/memo";
|
|
3
|
+
import { card, col } from "../native/describe";
|
|
4
|
+
import type { DescribeContext, NativeNode } from "../native/node";
|
|
1
5
|
import type { Component } from "../tui";
|
|
2
6
|
import {
|
|
3
7
|
getPaddingX,
|
|
@@ -52,6 +56,13 @@ export class Box implements Component {
|
|
|
52
56
|
|
|
53
57
|
// Cache for rendered output
|
|
54
58
|
#cached?: Cache;
|
|
59
|
+
#native?: {
|
|
60
|
+
children: readonly Component[];
|
|
61
|
+
bg: string | undefined;
|
|
62
|
+
border: BoxBorder | undefined;
|
|
63
|
+
borderColor: string | undefined;
|
|
64
|
+
node: NativeNode;
|
|
65
|
+
};
|
|
55
66
|
|
|
56
67
|
constructor(paddingX = 1, paddingY = 1, bgFn?: (text: string) => string, border?: BoxBorder) {
|
|
57
68
|
this.#paddingX = paddingX;
|
|
@@ -124,6 +135,46 @@ export class Box implements Component {
|
|
|
124
135
|
}
|
|
125
136
|
}
|
|
126
137
|
|
|
138
|
+
/**
|
|
139
|
+
* A `card` when the box has a border or background: the background token
|
|
140
|
+
* picks tone/role (user message, tool state, selection), a border colour
|
|
141
|
+
* picks the ring tone. A plain `col` otherwise. Padding is the terminal's.
|
|
142
|
+
*/
|
|
143
|
+
describe(_cx: DescribeContext): NativeNode {
|
|
144
|
+
const bg = sampleBackground(this.#bgFn);
|
|
145
|
+
const border = this.#border;
|
|
146
|
+
const borderColor = border ? sampleForeground(border.color) : undefined;
|
|
147
|
+
const cached = this.#native;
|
|
148
|
+
if (
|
|
149
|
+
cached !== undefined &&
|
|
150
|
+
cached.bg === bg &&
|
|
151
|
+
cached.border === border &&
|
|
152
|
+
cached.borderColor === borderColor &&
|
|
153
|
+
sameItems(cached.children, this.children)
|
|
154
|
+
) {
|
|
155
|
+
return cached.node;
|
|
156
|
+
}
|
|
157
|
+
const children = [...this.children];
|
|
158
|
+
let described: NativeNode;
|
|
159
|
+
if (!border && !this.#bgFn) {
|
|
160
|
+
described = col(children);
|
|
161
|
+
} else {
|
|
162
|
+
const chrome = backgroundChrome(bg);
|
|
163
|
+
described = card(
|
|
164
|
+
{
|
|
165
|
+
role: chrome.role ?? "omp.panel",
|
|
166
|
+
tone: borderColor !== undefined ? (colorTone(borderColor) ?? "neutral") : (chrome.tone ?? "neutral"),
|
|
167
|
+
selected: chrome.selected,
|
|
168
|
+
// Fill without a ring: a flat inset panel.
|
|
169
|
+
inset: border ? undefined : true,
|
|
170
|
+
},
|
|
171
|
+
children,
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
this.#native = { children, bg, border, borderColor, node: described };
|
|
175
|
+
return described;
|
|
176
|
+
}
|
|
177
|
+
|
|
127
178
|
render(width: number): readonly string[] {
|
|
128
179
|
const children = this.children;
|
|
129
180
|
const count = children.length;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { node } from "../native/describe";
|
|
2
|
+
import type { DescribeContext, NativeChild, NativeNode, NativeUiEvent } from "../native/node";
|
|
1
3
|
import type { Component } from "../tui";
|
|
2
4
|
|
|
3
5
|
/** A component slot; factory slots are constructed only when their branch is first rendered. */
|
|
@@ -48,6 +50,7 @@ export class Disclosure implements Component {
|
|
|
48
50
|
#ignoreTight: boolean | undefined;
|
|
49
51
|
#disposed = false;
|
|
50
52
|
#cache: RenderCache | undefined;
|
|
53
|
+
#native: { expanded: boolean; node: NativeNode } | undefined;
|
|
51
54
|
#boundedCache:
|
|
52
55
|
| {
|
|
53
56
|
source: readonly string[];
|
|
@@ -74,6 +77,7 @@ export class Disclosure implements Component {
|
|
|
74
77
|
if (this.#disposed || this.#expanded === expanded) return;
|
|
75
78
|
this.#expanded = expanded;
|
|
76
79
|
this.#cache = undefined;
|
|
80
|
+
this.#native = undefined;
|
|
77
81
|
this.#boundedCache = undefined;
|
|
78
82
|
}
|
|
79
83
|
|
|
@@ -131,6 +135,34 @@ export class Disclosure implements Component {
|
|
|
131
135
|
return children;
|
|
132
136
|
}
|
|
133
137
|
|
|
138
|
+
/**
|
|
139
|
+
* A collapsible `section`. The summary (and, while collapsed, the preview)
|
|
140
|
+
* form the always-visible header child; the lazily built body is the
|
|
141
|
+
* section body and is only materialized once expanded.
|
|
142
|
+
*/
|
|
143
|
+
describe(_cx: DescribeContext): NativeNode {
|
|
144
|
+
if (this.#disposed) return DISPOSED_NODE;
|
|
145
|
+
const expanded = this.#expanded;
|
|
146
|
+
if (this.#native?.expanded === expanded) return this.#native.node;
|
|
147
|
+
const head: NativeChild[] = [];
|
|
148
|
+
const summary = this.#getSummary();
|
|
149
|
+
if (summary) head.push(summary);
|
|
150
|
+
if (!expanded) {
|
|
151
|
+
const preview = this.#getCollapsedBody();
|
|
152
|
+
if (preview) head.push(preview);
|
|
153
|
+
}
|
|
154
|
+
const children: NativeChild[] = [node("col", undefined, head, "head")];
|
|
155
|
+
if (expanded) children.push(this.#getBody());
|
|
156
|
+
const described = node("section", { collapsible: true, collapsed: !expanded }, children);
|
|
157
|
+
this.#native = { expanded, node: described };
|
|
158
|
+
return described;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** Mirror the terminal-local toggle into the controlled state. */
|
|
162
|
+
handleNativeEvent(event: NativeUiEvent): void {
|
|
163
|
+
if (event.type === "toggle" && event.key === "") this.setExpanded(!event.collapsed);
|
|
164
|
+
}
|
|
165
|
+
|
|
134
166
|
render(width: number): readonly string[] {
|
|
135
167
|
if (this.#disposed) return EMPTY_ROWS;
|
|
136
168
|
width = Math.max(1, Math.floor(Number.isFinite(width) ? width : 1));
|
|
@@ -232,4 +264,5 @@ function rowsMatchSnapshot(rows: readonly string[], snapshot: readonly string[])
|
|
|
232
264
|
}
|
|
233
265
|
|
|
234
266
|
const EMPTY_ROWS: readonly string[] = [];
|
|
267
|
+
const DISPOSED_NODE: NativeNode = node("col", { hidden: true });
|
|
235
268
|
const EMPTY_COMPONENTS: readonly Component[] = [];
|
package/src/components/editor.ts
CHANGED
|
@@ -14,6 +14,11 @@ import { BracketedPasteHandler, decodeReencodedPasteControls } from "../brackete
|
|
|
14
14
|
import { canonicalKeyId, getKeybindings, type KeybindingsManager } from "../keybindings";
|
|
15
15
|
import { extractPrintableText, matchesKey, parseKey } from "../keys";
|
|
16
16
|
import { KillRing } from "../kill-ring";
|
|
17
|
+
import type { TspEditorDecoration, TspEditorProps, TspTone } from "@oh-my-pi/pi-wire";
|
|
18
|
+
import { col, node } from "../native/describe";
|
|
19
|
+
import { sameItems, sameProps } from "../native/memo";
|
|
20
|
+
import { plainText } from "../native/spans";
|
|
21
|
+
import type { DescribeContext, NativeChild, NativeNode } from "../native/node";
|
|
17
22
|
import type { SymbolTheme } from "../symbols";
|
|
18
23
|
import { type Component, CURSOR_MARKER, type Focusable } from "../tui";
|
|
19
24
|
import {
|
|
@@ -52,7 +57,36 @@ export type { EditorBorderStyle, EditorTopBorder };
|
|
|
52
57
|
|
|
53
58
|
import { type SelectItem, SelectList, type SelectListLayoutOptions, type SelectListTheme } from "./select-list";
|
|
54
59
|
|
|
60
|
+
/** The TSP root an {@link Editor.describeLayout} hook builds around the `editor` node. */
|
|
61
|
+
export interface NativeEditorLayout {
|
|
62
|
+
readonly role: string;
|
|
63
|
+
/** Tone of the root (`pending` while a turn runs). */
|
|
64
|
+
readonly tone?: TspTone;
|
|
65
|
+
readonly children: readonly NativeChild[];
|
|
66
|
+
/** Keypath of the `editor` node inside the root (the autocomplete's caret anchor). */
|
|
67
|
+
readonly caret: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Vim mode as the TSP `editor.mode` label. */
|
|
71
|
+
const VIM_MODE_LABELS: Record<VimMode, string> = {
|
|
72
|
+
insert: "INSERT",
|
|
73
|
+
normal: "NORMAL",
|
|
74
|
+
visual: "VISUAL",
|
|
75
|
+
"visual-line": "VISUAL",
|
|
76
|
+
};
|
|
77
|
+
|
|
55
78
|
const PASSTHROUGH_COLOR = (text: string): string => text;
|
|
79
|
+
|
|
80
|
+
/** Value equality of two decoration lists, so an unchanged set keeps its identity across text edits elsewhere. */
|
|
81
|
+
function sameDecorations(a: readonly TspEditorDecoration[], b: readonly TspEditorDecoration[]): boolean {
|
|
82
|
+
if (a.length !== b.length) return false;
|
|
83
|
+
for (let i = 0; i < a.length; i++) {
|
|
84
|
+
const x = a[i]!;
|
|
85
|
+
const y = b[i]!;
|
|
86
|
+
if (x.from !== y.from || x.to !== y.to || x.s !== y.s || x.fx !== y.fx) return false;
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
56
90
|
const MENTION_CONTEXT_RE = /(?:^|\s)\^[^\s]*$/;
|
|
57
91
|
const AT_TOKEN_RE = /(?:^|\s)(@[^\s]*)$/;
|
|
58
92
|
|
|
@@ -568,7 +602,30 @@ export class Editor implements Component, Focusable {
|
|
|
568
602
|
* Width-changing output is allowed on lines without the cursor; it is truncated
|
|
569
603
|
* to the content width rather than reflowed. Cursor glyphs and inline hints are excluded. */
|
|
570
604
|
decorateText: ((text: string, context: EditorTextDecorationContext) => string) | undefined;
|
|
605
|
+
/**
|
|
606
|
+
* TSP counterpart of {@link decorateText}: styled ranges over the buffer
|
|
607
|
+
* (UTF-16 offsets into the lines joined by `\n`). Called only when the text
|
|
608
|
+
* changed or the editor was invalidated since the last description.
|
|
609
|
+
*/
|
|
610
|
+
describeDecorations: ((lines: readonly string[]) => readonly TspEditorDecoration[]) | undefined;
|
|
611
|
+
/** TSP code language of the buffer (`python`, `bash`): the terminal highlights it in the mono face. */
|
|
612
|
+
describeLanguage: (() => string | undefined) | undefined;
|
|
613
|
+
/**
|
|
614
|
+
* TSP chrome around the `editor` node (the prompt composer's chips, mode
|
|
615
|
+
* chip, send/stop): the root role, the children with `input` placed where
|
|
616
|
+
* the layout wants it, and the input's keypath for the caret-anchored
|
|
617
|
+
* autocomplete. Unset: a plain `omp.editor` column over the input.
|
|
618
|
+
*/
|
|
619
|
+
describeLayout: ((input: NativeNode, cx: DescribeContext) => NativeEditorLayout) | undefined;
|
|
620
|
+
/** TSP placeholder for the empty buffer; natively it replaces the rotating ANSI {@link placeholder} hints. */
|
|
621
|
+
nativePlaceholder: string | undefined;
|
|
571
622
|
#promptGutter: string | undefined;
|
|
623
|
+
/** Bumped by {@link invalidate}: host-side decoration inputs (spelling results, settings) changed. */
|
|
624
|
+
#nativeGeneration = 0;
|
|
625
|
+
#nativeDecor?: { text: string; generation: number; decor: readonly TspEditorDecoration[] | undefined };
|
|
626
|
+
#nativeEditor?: { props: TspEditorProps; node: NativeNode };
|
|
627
|
+
#nativeOverlay?: { list: SelectList; caret: string; node: NativeNode };
|
|
628
|
+
#nativeRoot?: { role: string; tone: TspTone | undefined; children: readonly NativeChild[]; node: NativeNode };
|
|
572
629
|
|
|
573
630
|
// Store last layout width for cursor navigation
|
|
574
631
|
#lastLayoutWidth: number = 80;
|
|
@@ -1032,7 +1089,7 @@ export class Editor implements Component, Focusable {
|
|
|
1032
1089
|
}
|
|
1033
1090
|
|
|
1034
1091
|
invalidate(): void {
|
|
1035
|
-
|
|
1092
|
+
this.#nativeGeneration++;
|
|
1036
1093
|
}
|
|
1037
1094
|
|
|
1038
1095
|
/** Active chrome style; a hidden border collapses every shape to borderless. */
|
|
@@ -1553,6 +1610,125 @@ export class Editor implements Component, Focusable {
|
|
|
1553
1610
|
return result;
|
|
1554
1611
|
}
|
|
1555
1612
|
|
|
1613
|
+
/**
|
|
1614
|
+
* An `editor` node (key `input`) carrying the buffer, caret, Vim selection
|
|
1615
|
+
* anchor and mode, decorations, ghost completion, placeholder, prompt and
|
|
1616
|
+
* height cap; the frame, wrapping, scrolling and caret are the terminal's,
|
|
1617
|
+
* so composer shapes play no part. An open autocomplete popup follows as an
|
|
1618
|
+
* `overlay` anchored to the caret around the completion list. Typing and
|
|
1619
|
+
* caret moves change only `text` and `cursor` on the same node.
|
|
1620
|
+
*/
|
|
1621
|
+
describe(cx: DescribeContext): NativeNode {
|
|
1622
|
+
// Vertical caret motion walks visual rows; the terminal owns the real
|
|
1623
|
+
// wrap, so the surface width is the closest available layout width.
|
|
1624
|
+
this.#lastLayoutWidth = Math.max(1, cx.cols);
|
|
1625
|
+
const { lines, cursorLine, cursorCol } = this.#state;
|
|
1626
|
+
const text = lines.join("\n");
|
|
1627
|
+
let offset = 0;
|
|
1628
|
+
for (let i = 0; i < cursorLine; i++) offset += (lines[i]?.length ?? 0) + 1;
|
|
1629
|
+
const cursor = offset + cursorCol;
|
|
1630
|
+
|
|
1631
|
+
let decor = this.#nativeDecor;
|
|
1632
|
+
if (decor?.text !== text || decor.generation !== this.#nativeGeneration) {
|
|
1633
|
+
const next = this.describeDecorations?.(lines);
|
|
1634
|
+
decor = {
|
|
1635
|
+
text,
|
|
1636
|
+
generation: this.#nativeGeneration,
|
|
1637
|
+
decor:
|
|
1638
|
+
next && next.length > 0
|
|
1639
|
+
? decor?.decor && sameDecorations(decor.decor, next)
|
|
1640
|
+
? decor.decor
|
|
1641
|
+
: next
|
|
1642
|
+
: undefined,
|
|
1643
|
+
};
|
|
1644
|
+
this.#nativeDecor = decor;
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
const placeholder = this.#getPlaceholder();
|
|
1648
|
+
const nativePlaceholder =
|
|
1649
|
+
this.nativePlaceholder !== undefined && !this.#autocompleteState && this.#isEditorEmpty()
|
|
1650
|
+
? this.nativePlaceholder
|
|
1651
|
+
: placeholder && plainText(placeholder).trim();
|
|
1652
|
+
const atLineEnd = cursorCol >= (lines[cursorLine]?.length ?? 0);
|
|
1653
|
+
const ghost = nativePlaceholder || !atLineEnd ? null : this.#getInlineHint();
|
|
1654
|
+
const vim = this.#vim;
|
|
1655
|
+
let anchor: number | null = null;
|
|
1656
|
+
if (vim?.visual && vim.anchor !== null) {
|
|
1657
|
+
let anchorOffset = 0;
|
|
1658
|
+
for (let i = 0; i < vim.anchor.line; i++) anchorOffset += (lines[i]?.length ?? 0) + 1;
|
|
1659
|
+
if (vim.mode === "visual-line") {
|
|
1660
|
+
// Linewise: stretch the anchor to the far edge of its line.
|
|
1661
|
+
const before =
|
|
1662
|
+
vim.anchor.line < cursorLine || (vim.anchor.line === cursorLine && vim.anchor.col <= cursorCol);
|
|
1663
|
+
anchor = before ? anchorOffset : anchorOffset + (lines[vim.anchor.line]?.length ?? 0);
|
|
1664
|
+
} else {
|
|
1665
|
+
anchor = anchorOffset + vim.anchor.col;
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
const prompt = this.#promptGutter === undefined ? "" : plainText(this.#promptGutter);
|
|
1669
|
+
const props: TspEditorProps = {
|
|
1670
|
+
text,
|
|
1671
|
+
cursor,
|
|
1672
|
+
anchor: anchor ?? undefined,
|
|
1673
|
+
decor: decor.decor,
|
|
1674
|
+
ghost: ghost ? plainText(ghost) : undefined,
|
|
1675
|
+
placeholder: nativePlaceholder || undefined,
|
|
1676
|
+
prompt: prompt || undefined,
|
|
1677
|
+
mode: vim ? VIM_MODE_LABELS[vim.mode] : undefined,
|
|
1678
|
+
lang: this.describeLanguage?.(),
|
|
1679
|
+
maxLines: this.#maxHeight,
|
|
1680
|
+
};
|
|
1681
|
+
let editor = this.#nativeEditor;
|
|
1682
|
+
if (!editor || !sameProps(editor.props, props)) {
|
|
1683
|
+
editor = { props, node: node("editor", props, undefined, "input") };
|
|
1684
|
+
this.#nativeEditor = editor;
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
const layout = this.describeLayout?.(editor.node, cx) ?? {
|
|
1688
|
+
role: "omp.editor",
|
|
1689
|
+
children: [editor.node],
|
|
1690
|
+
caret: "input",
|
|
1691
|
+
};
|
|
1692
|
+
const children: NativeChild[] = [...layout.children];
|
|
1693
|
+
const list = this.#visibleAutocompleteList();
|
|
1694
|
+
if (list) {
|
|
1695
|
+
list.setNativeMark(this.#autocompleteMark());
|
|
1696
|
+
const overlay = this.#nativeOverlay;
|
|
1697
|
+
if (overlay?.list !== list || overlay.caret !== layout.caret) {
|
|
1698
|
+
this.#nativeOverlay = {
|
|
1699
|
+
list,
|
|
1700
|
+
caret: layout.caret,
|
|
1701
|
+
node: node("overlay", { anchor: { caret: layout.caret }, role: "omp.autocomplete" }, [list], "complete"),
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
children.push(this.#nativeOverlay!.node);
|
|
1705
|
+
} else {
|
|
1706
|
+
this.#nativeOverlay = undefined;
|
|
1707
|
+
}
|
|
1708
|
+
const root = this.#nativeRoot;
|
|
1709
|
+
if (root && root.role === layout.role && root.tone === layout.tone && sameItems(root.children, children)) {
|
|
1710
|
+
return root.node;
|
|
1711
|
+
}
|
|
1712
|
+
const described = col(children, layout.tone ? { role: layout.role, tone: layout.tone } : { role: layout.role });
|
|
1713
|
+
this.#nativeRoot = { role: layout.role, tone: layout.tone, children, node: described };
|
|
1714
|
+
return described;
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
/**
|
|
1718
|
+
* The typed text the open popup matches item labels against, for the TSP
|
|
1719
|
+
* `mark`: the completion prefix (the live `@` token while a file list
|
|
1720
|
+
* narrows in place) without its sigil, from its last path segment on.
|
|
1721
|
+
*/
|
|
1722
|
+
#autocompleteMark(): string {
|
|
1723
|
+
let typed = this.#autocompletePrefix;
|
|
1724
|
+
if (typed.startsWith("@")) {
|
|
1725
|
+
const line = this.#state.lines[this.#state.cursorLine] ?? "";
|
|
1726
|
+
typed = AT_TOKEN_RE.exec(line.slice(0, this.#state.cursorCol))?.[1] ?? typed;
|
|
1727
|
+
}
|
|
1728
|
+
typed = typed.replace(/^[/@:#$^]"?/, "");
|
|
1729
|
+
return typed.slice(typed.lastIndexOf("/") + 1);
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1556
1732
|
handleInput(data: string): void {
|
|
1557
1733
|
// Iterative, not recursive: the bytes trailing a completed bracketed
|
|
1558
1734
|
// paste (which may themselves contain further pastes) loop back here,
|
|
@@ -1723,31 +1899,8 @@ export class Editor implements Component, Focusable {
|
|
|
1723
1899
|
// arrow at end of line moves the cursor.
|
|
1724
1900
|
this.#cancelAutocomplete();
|
|
1725
1901
|
this.onAutocompleteUpdate?.();
|
|
1726
|
-
} else
|
|
1727
|
-
|
|
1728
|
-
this.#isSlashCommandNameAutocompleteSelection() || isDirectoryCompletionValue(selected.value);
|
|
1729
|
-
const result = this.#autocompleteProvider.applyCompletion(
|
|
1730
|
-
this.#state.lines,
|
|
1731
|
-
this.#state.cursorLine,
|
|
1732
|
-
this.#state.cursorCol,
|
|
1733
|
-
selected,
|
|
1734
|
-
this.#autocompletePrefix,
|
|
1735
|
-
);
|
|
1736
|
-
|
|
1737
|
-
this.#state.lines = result.lines;
|
|
1738
|
-
this.#state.cursorLine = result.cursorLine;
|
|
1739
|
-
this.#setCursorCol(result.cursorCol);
|
|
1740
|
-
|
|
1741
|
-
this.#cancelAutocomplete();
|
|
1742
|
-
this.onAutocompleteUpdate?.();
|
|
1743
|
-
|
|
1744
|
-
this.#notifyChange();
|
|
1745
|
-
|
|
1746
|
-
result.onApplied?.();
|
|
1747
|
-
|
|
1748
|
-
if (shouldChainAutocomplete) {
|
|
1749
|
-
queueMicrotask(() => void this.#tryTriggerAutocomplete());
|
|
1750
|
-
}
|
|
1902
|
+
} else {
|
|
1903
|
+
this.#acceptAutocompleteSelection(selected);
|
|
1751
1904
|
}
|
|
1752
1905
|
// Only an accepted candidate consumes the key; an empty list falls through.
|
|
1753
1906
|
if (selected) return;
|
|
@@ -4111,6 +4264,35 @@ export class Editor implements Component, Focusable {
|
|
|
4111
4264
|
}
|
|
4112
4265
|
await this.#queueAutocompleteRequest({ kind: "regular", explicitTab });
|
|
4113
4266
|
}
|
|
4267
|
+
/** Apply `selected` the way Tab does: complete it in place and chain into directories/commands. */
|
|
4268
|
+
#acceptAutocompleteSelection(selected: SelectItem): void {
|
|
4269
|
+
if (!this.#autocompleteProvider) return;
|
|
4270
|
+
const shouldChainAutocomplete =
|
|
4271
|
+
this.#isSlashCommandNameAutocompleteSelection() || isDirectoryCompletionValue(selected.value);
|
|
4272
|
+
const result = this.#autocompleteProvider.applyCompletion(
|
|
4273
|
+
this.#state.lines,
|
|
4274
|
+
this.#state.cursorLine,
|
|
4275
|
+
this.#state.cursorCol,
|
|
4276
|
+
selected,
|
|
4277
|
+
this.#autocompletePrefix,
|
|
4278
|
+
);
|
|
4279
|
+
|
|
4280
|
+
this.#state.lines = result.lines;
|
|
4281
|
+
this.#state.cursorLine = result.cursorLine;
|
|
4282
|
+
this.#setCursorCol(result.cursorCol);
|
|
4283
|
+
|
|
4284
|
+
this.#cancelAutocomplete();
|
|
4285
|
+
this.onAutocompleteUpdate?.();
|
|
4286
|
+
|
|
4287
|
+
this.#notifyChange();
|
|
4288
|
+
|
|
4289
|
+
result.onApplied?.();
|
|
4290
|
+
|
|
4291
|
+
if (shouldChainAutocomplete) {
|
|
4292
|
+
queueMicrotask(() => void this.#tryTriggerAutocomplete());
|
|
4293
|
+
}
|
|
4294
|
+
}
|
|
4295
|
+
|
|
4114
4296
|
#createAutocompleteList(
|
|
4115
4297
|
prefix: string,
|
|
4116
4298
|
items: Array<{ value: string; label: string; description?: string }>,
|
|
@@ -4120,7 +4302,14 @@ export class Editor implements Component, Focusable {
|
|
|
4120
4302
|
: prefix.startsWith("@")
|
|
4121
4303
|
? AT_FILE_SELECT_LIST_LAYOUT
|
|
4122
4304
|
: AUTOCOMPLETE_SELECT_LIST_LAYOUT;
|
|
4123
|
-
|
|
4305
|
+
const list = new SelectList(items, this.#autocompleteMaxVisible, this.#theme.selectList, layout);
|
|
4306
|
+
// A pointer pick on the popup (TSP `select`/`activate`) accepts it like Tab.
|
|
4307
|
+
list.onSelect = item => {
|
|
4308
|
+
if (this.#autocompleteList !== list) return;
|
|
4309
|
+
if (this.#autocompleteState === "assist") this.#applySpellingSuggestion();
|
|
4310
|
+
else this.#acceptAutocompleteSelection(item);
|
|
4311
|
+
};
|
|
4312
|
+
return list;
|
|
4124
4313
|
}
|
|
4125
4314
|
|
|
4126
4315
|
async #handleTabCompletion(): Promise<void> {
|