@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
|
@@ -8,6 +8,8 @@ import { type SelectItem, SelectList, type SgrMouseEvent } from "../index";
|
|
|
8
8
|
import { getSelectListTheme } from "../theme/theme";
|
|
9
9
|
import { OverlayPanel } from "../chrome/overlay-box";
|
|
10
10
|
import { routeSelectListMouseWithTopBorder } from "../chrome/select-list-mouse-routing";
|
|
11
|
+
import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node";
|
|
12
|
+
import { SelectListSheet } from "../native/picker";
|
|
11
13
|
|
|
12
14
|
export interface PluginSelectorCallbacks {
|
|
13
15
|
onSelect: (pluginName: string, marketplace: string, scope?: "user" | "project") => void;
|
|
@@ -23,6 +25,7 @@ export interface PluginItem {
|
|
|
23
25
|
|
|
24
26
|
export class PluginSelectorComponent extends OverlayPanel {
|
|
25
27
|
#selectList: SelectList;
|
|
28
|
+
#sheet: SelectListSheet;
|
|
26
29
|
|
|
27
30
|
constructor(
|
|
28
31
|
marketplaceCount: number,
|
|
@@ -30,7 +33,7 @@ export class PluginSelectorComponent extends OverlayPanel {
|
|
|
30
33
|
installedIds: Set<string>,
|
|
31
34
|
callbacks: PluginSelectorCallbacks,
|
|
32
35
|
) {
|
|
33
|
-
super("Plugins");
|
|
36
|
+
super("Plugins", "omp.overlay.plugins");
|
|
34
37
|
|
|
35
38
|
const items: SelectItem[] = plugins.map(({ plugin, marketplace, scope }) => {
|
|
36
39
|
// Encode scope into the value so onSelect can recover it without a parallel Map.
|
|
@@ -75,6 +78,23 @@ export class PluginSelectorComponent extends OverlayPanel {
|
|
|
75
78
|
};
|
|
76
79
|
|
|
77
80
|
this.addChild(this.#selectList);
|
|
81
|
+
this.#sheet = new SelectListSheet(this.#selectList, {
|
|
82
|
+
title: "Plugins",
|
|
83
|
+
icon: "plus",
|
|
84
|
+
noun: "plugins",
|
|
85
|
+
confirm: "Install",
|
|
86
|
+
decorate: item => (item.hint ? { facts: { marketplace: item.hint } } : undefined),
|
|
87
|
+
columns: [{ id: "marketplace", format: "dim" }],
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
override describe(cx: DescribeContext): NativeNode | null {
|
|
92
|
+
return cx.supports("picker") ? this.#sheet.describe() : super.describe(cx);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Picker pointer events drive the list exactly as its keys do. */
|
|
96
|
+
handleNativeEvent(event: NativeUiEvent): void {
|
|
97
|
+
this.#sheet.handle(event);
|
|
78
98
|
}
|
|
79
99
|
|
|
80
100
|
getSelectList(): SelectList {
|
|
@@ -22,8 +22,76 @@ import { shortenPath } from "../render/render-utils";
|
|
|
22
22
|
import { OverlayPanel } from "../chrome/overlay-box";
|
|
23
23
|
import { FormField, SelectFormField, TextFormField } from "../components/form";
|
|
24
24
|
import { formTheme } from "../chrome/form-theme";
|
|
25
|
-
import { SettingsFormField } from "../components/settings-list";
|
|
25
|
+
import { type PrefsEditing, SettingsFormField, type SettingsList } from "../components/settings-list";
|
|
26
26
|
import { editorKey } from "../chrome/keybinding-hints";
|
|
27
|
+
import type { DescribeContext, NativeChild, NativeNode, NativeUiEvent } from "../native/node";
|
|
28
|
+
import { col, node, span, text } from "../native/describe";
|
|
29
|
+
import type { TspPrefsControl, TspPrefsSection } from "@oh-my-pi/pi-wire";
|
|
30
|
+
import { actionHint, hintsRow, overlayCard } from "../native/overlay";
|
|
31
|
+
|
|
32
|
+
const PLUGIN_SETTINGS_ROLE = "omp.overlay.plugin-settings";
|
|
33
|
+
/** A plugin row's control on the native settings page: open the plugin's settings. */
|
|
34
|
+
const PLUGIN_CONFIGURE: TspPrefsControl = { k: "action", label: "Configure", act: "open" };
|
|
35
|
+
|
|
36
|
+
/** The plugins tab as a native settings page draws it (the settings selector puts it in its `prefs` node). */
|
|
37
|
+
export interface PluginPrefsPage {
|
|
38
|
+
lead: string;
|
|
39
|
+
sections: TspPrefsSection[];
|
|
40
|
+
focus: string | null;
|
|
41
|
+
editing: PrefsEditing | null;
|
|
42
|
+
/** An open value editor without a native control, shown over the page. */
|
|
43
|
+
editor?: NativeChild;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* A plugin detail list as native page sections: on/off rows as switches,
|
|
48
|
+
* value rows as an edit button showing the value (the row's editor opens
|
|
49
|
+
* over the page, see {@link prefsDetailEvent}).
|
|
50
|
+
*/
|
|
51
|
+
function prefsDetailPage(title: string, lead: string, list: SettingsList | undefined): PluginPrefsPage {
|
|
52
|
+
if (!list) return { lead, sections: [], focus: null, editing: null };
|
|
53
|
+
const sections = list.prefsSections(
|
|
54
|
+
() => ({ id: "plugin", title }),
|
|
55
|
+
(item): TspPrefsControl =>
|
|
56
|
+
item.values?.length === 2 && item.values.includes("true") && item.values.includes("false")
|
|
57
|
+
? { k: "switch", on: item.currentValue === "true" }
|
|
58
|
+
: { k: "action", label: item.currentValue.trim() || "Edit…", act: "edit" },
|
|
59
|
+
);
|
|
60
|
+
const open = list.openSubmenu;
|
|
61
|
+
return {
|
|
62
|
+
lead,
|
|
63
|
+
sections: sections.map(section => ({
|
|
64
|
+
...section,
|
|
65
|
+
rows: section.rows.map(row => ({ ...row, label: row.label.trim() })),
|
|
66
|
+
})),
|
|
67
|
+
focus: list.prefsFocus().row ?? null,
|
|
68
|
+
editing: null,
|
|
69
|
+
editor: open ? col([open.component], { role: "omp.prefs.editor" }) : undefined,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** A native page event on a plugin detail list, through the keys' code paths. */
|
|
74
|
+
function prefsDetailEvent(list: SettingsList | undefined, event: NativeUiEvent): void {
|
|
75
|
+
if (!list) return;
|
|
76
|
+
switch (event.type) {
|
|
77
|
+
case "change":
|
|
78
|
+
if (typeof event.value === "boolean") list.applyValue(event.item, String(event.value));
|
|
79
|
+
return;
|
|
80
|
+
case "select":
|
|
81
|
+
list.selectItem(event.item);
|
|
82
|
+
return;
|
|
83
|
+
case "activate":
|
|
84
|
+
list.openSubmenuFor(event.item);
|
|
85
|
+
return;
|
|
86
|
+
case "action":
|
|
87
|
+
if (event.act === "edit" && event.value) list.openSubmenuFor(event.value);
|
|
88
|
+
else if (event.act === "close" && event.value && list.openSubmenu?.id === event.value)
|
|
89
|
+
list.handleInput("\x1b");
|
|
90
|
+
return;
|
|
91
|
+
case "toggle":
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
27
95
|
|
|
28
96
|
/** Setting metadata consumed by the plugin settings UI. */
|
|
29
97
|
export type PluginSettingSchema = {
|
|
@@ -227,12 +295,13 @@ function findEntryByValue(entries: ReadonlyArray<PluginListEntry>, value: string
|
|
|
227
295
|
*/
|
|
228
296
|
export class PluginListComponent extends OverlayPanel {
|
|
229
297
|
readonly #selectList: SelectList;
|
|
298
|
+
#native: NativeNode | undefined;
|
|
230
299
|
|
|
231
300
|
constructor(
|
|
232
301
|
private readonly entries: ReadonlyArray<PluginListEntry>,
|
|
233
302
|
callbacks: PluginListCallbacks,
|
|
234
303
|
) {
|
|
235
|
-
super("Plugins");
|
|
304
|
+
super("Plugins", PLUGIN_SETTINGS_ROLE);
|
|
236
305
|
this.addChild(new Spacer(1));
|
|
237
306
|
|
|
238
307
|
if (entries.length === 0) {
|
|
@@ -283,6 +352,74 @@ export class PluginListComponent extends OverlayPanel {
|
|
|
283
352
|
);
|
|
284
353
|
}
|
|
285
354
|
|
|
355
|
+
/** The installed plugins as one native page section: a row per plugin with its status and a Configure button. */
|
|
356
|
+
prefsPage(): PluginPrefsPage {
|
|
357
|
+
const rows = this.entries.map(entry => {
|
|
358
|
+
const id = entryValue(entry);
|
|
359
|
+
if (entry.kind === "npm") {
|
|
360
|
+
const p = entry.plugin;
|
|
361
|
+
const features = p.manifest.features ? Object.keys(p.manifest.features).length : 0;
|
|
362
|
+
const parts = [p.enabled ? "Enabled" : "Disabled", "npm", `v${p.version}`];
|
|
363
|
+
if (features > 0) parts.push(`${p.enabledFeatures?.length ?? features}/${features} features`);
|
|
364
|
+
return { id, label: p.name, hint: parts.join(" · "), control: PLUGIN_CONFIGURE };
|
|
365
|
+
}
|
|
366
|
+
const s = entry.plugin;
|
|
367
|
+
const parts = [marketplaceEnabled(s) ? "Enabled" : "Disabled", "marketplace", s.scope];
|
|
368
|
+
parts.push(`v${s.entries[0]?.version ?? "?"}`);
|
|
369
|
+
return {
|
|
370
|
+
id,
|
|
371
|
+
label: s.id,
|
|
372
|
+
hint: parts.join(" · "),
|
|
373
|
+
warning: s.shadowedBy ? `Shadowed by the ${s.shadowedBy} install` : undefined,
|
|
374
|
+
control: PLUGIN_CONFIGURE,
|
|
375
|
+
};
|
|
376
|
+
});
|
|
377
|
+
return {
|
|
378
|
+
lead:
|
|
379
|
+
rows.length > 0
|
|
380
|
+
? "Plugins installed for you and this project. Configure one to turn it or its features on and off."
|
|
381
|
+
: "No plugins installed. Install one with omp plugin install <package>, or <name>@<marketplace>.",
|
|
382
|
+
sections: rows.length > 0 ? [{ id: "installed", title: "Installed", rows }] : [],
|
|
383
|
+
focus: this.#selectList.getSelectedItem()?.value ?? null,
|
|
384
|
+
editing: null,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/** A native page event: a row click moves the selection, Configure (or a double click) opens the plugin. */
|
|
389
|
+
handlePrefsEvent(event: NativeUiEvent): void {
|
|
390
|
+
if (event.type === "select") this.#selectList.setSelectedValue(event.item);
|
|
391
|
+
else if (event.type === "activate") this.#selectList.handleNativeEvent(event);
|
|
392
|
+
else if (event.type === "action" && event.act === "open" && event.value) {
|
|
393
|
+
this.#selectList.handleNativeEvent({ type: "activate", key: event.key, item: event.value });
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/** The plugin list (the select list describes itself) and its hints, or install guidance when empty. */
|
|
398
|
+
override describe(_cx: DescribeContext): NativeNode {
|
|
399
|
+
if (this.#native) return this.#native;
|
|
400
|
+
const body =
|
|
401
|
+
this.entries.length === 0
|
|
402
|
+
? [
|
|
403
|
+
text([span("No plugins installed", "muted")]),
|
|
404
|
+
node("kv", {
|
|
405
|
+
items: [
|
|
406
|
+
{ k: "Install npm plugins", v: [span("omp plugin install <package>", "code")] },
|
|
407
|
+
{
|
|
408
|
+
k: "Install marketplace plugins",
|
|
409
|
+
v: [span("omp plugin install <name>@<marketplace>", "code")],
|
|
410
|
+
},
|
|
411
|
+
],
|
|
412
|
+
}),
|
|
413
|
+
hintsRow([actionHint("tui.select.cancel", "go back")]),
|
|
414
|
+
]
|
|
415
|
+
: [
|
|
416
|
+
this.#selectList,
|
|
417
|
+
hintsRow([actionHint("tui.select.confirm", "configure"), actionHint("tui.select.cancel", "go back")]),
|
|
418
|
+
];
|
|
419
|
+
this.#native = overlayCard(PLUGIN_SETTINGS_ROLE, this.title, body);
|
|
420
|
+
return this.#native;
|
|
421
|
+
}
|
|
422
|
+
|
|
286
423
|
#renderItem(entry: PluginListEntry): SelectItem {
|
|
287
424
|
const kindBadge = theme.fg("dim", entry.kind === "npm" ? "[npm]" : "[marketplace]");
|
|
288
425
|
|
|
@@ -357,7 +494,7 @@ export class PluginDetailComponent extends OverlayPanel {
|
|
|
357
494
|
private readonly manager: PluginSettingsManager,
|
|
358
495
|
private readonly callbacks: PluginDetailCallbacks,
|
|
359
496
|
) {
|
|
360
|
-
super(plugin.name);
|
|
497
|
+
super(plugin.name, PLUGIN_SETTINGS_ROLE);
|
|
361
498
|
|
|
362
499
|
void this.#rebuild();
|
|
363
500
|
}
|
|
@@ -452,6 +589,20 @@ export class PluginDetailComponent extends OverlayPanel {
|
|
|
452
589
|
if (!this.#settingsList) return;
|
|
453
590
|
this.#settingsList.handleInput(data);
|
|
454
591
|
}
|
|
592
|
+
|
|
593
|
+
/** This plugin's settings as a native page section. */
|
|
594
|
+
prefsPage(): PluginPrefsPage {
|
|
595
|
+
return prefsDetailPage(
|
|
596
|
+
this.plugin.name,
|
|
597
|
+
this.plugin.manifest.description || "Turn the plugin and its features on and off, and change its settings.",
|
|
598
|
+
this.#settingsList?.settingsList,
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/** A native page event on this plugin's settings. */
|
|
603
|
+
handlePrefsEvent(event: NativeUiEvent): void {
|
|
604
|
+
prefsDetailEvent(this.#settingsList?.settingsList, event);
|
|
605
|
+
}
|
|
455
606
|
}
|
|
456
607
|
|
|
457
608
|
// =============================================================================
|
|
@@ -479,7 +630,7 @@ export class MarketplacePluginDetailComponent extends OverlayPanel {
|
|
|
479
630
|
private readonly manager: PluginSettingsManager,
|
|
480
631
|
private readonly callbacks: MarketplacePluginDetailCallbacks,
|
|
481
632
|
) {
|
|
482
|
-
super(plugin.id);
|
|
633
|
+
super(plugin.id, PLUGIN_SETTINGS_ROLE);
|
|
483
634
|
this.#render(undefined, []);
|
|
484
635
|
void this.#loadConfig();
|
|
485
636
|
}
|
|
@@ -575,6 +726,20 @@ export class MarketplacePluginDetailComponent extends OverlayPanel {
|
|
|
575
726
|
handleInput(data: string): void {
|
|
576
727
|
this.#settingsList.handleInput(data);
|
|
577
728
|
}
|
|
729
|
+
|
|
730
|
+
/** This plugin's settings as a native page section, with its install facts as the lead. */
|
|
731
|
+
prefsPage(): PluginPrefsPage {
|
|
732
|
+
const entry = this.plugin.entries[0];
|
|
733
|
+
const facts = [`${this.plugin.scope} install`, `v${entry?.version ?? "?"}`];
|
|
734
|
+
if (entry?.installPath) facts.push(shortenPath(entry.installPath));
|
|
735
|
+
if (this.plugin.shadowedBy) facts.push(`shadowed by the ${this.plugin.shadowedBy} install`);
|
|
736
|
+
return prefsDetailPage(this.plugin.id, facts.join(" · "), this.#settingsList?.settingsList);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
/** A native page event on this plugin's settings. */
|
|
740
|
+
handlePrefsEvent(event: NativeUiEvent): void {
|
|
741
|
+
prefsDetailEvent(this.#settingsList?.settingsList, event);
|
|
742
|
+
}
|
|
578
743
|
}
|
|
579
744
|
|
|
580
745
|
// =============================================================================
|
|
@@ -589,7 +754,7 @@ class ConfigFieldPanel extends OverlayPanel {
|
|
|
589
754
|
#field: FormField;
|
|
590
755
|
|
|
591
756
|
constructor(key: string, field: FormField) {
|
|
592
|
-
super(key);
|
|
757
|
+
super(key, `${PLUGIN_SETTINGS_ROLE}.field`);
|
|
593
758
|
this.#field = field;
|
|
594
759
|
this.addChild(field);
|
|
595
760
|
}
|
|
@@ -765,6 +930,31 @@ export class PluginSettingsComponent extends Container {
|
|
|
765
930
|
this.callbacks.requestRender?.();
|
|
766
931
|
}
|
|
767
932
|
|
|
933
|
+
/** The current view (list or a plugin's settings) as a native settings page. */
|
|
934
|
+
prefsPage(): PluginPrefsPage {
|
|
935
|
+
const view = this.#viewComponent;
|
|
936
|
+
if (
|
|
937
|
+
view instanceof PluginListComponent ||
|
|
938
|
+
view instanceof PluginDetailComponent ||
|
|
939
|
+
view instanceof MarketplacePluginDetailComponent
|
|
940
|
+
) {
|
|
941
|
+
return view.prefsPage();
|
|
942
|
+
}
|
|
943
|
+
return { lead: "Loading installed plugins…", sections: [], focus: null, editing: null };
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
/** Routes a native page event to the current view. */
|
|
947
|
+
handlePrefsEvent(event: NativeUiEvent): void {
|
|
948
|
+
const view = this.#viewComponent;
|
|
949
|
+
if (
|
|
950
|
+
view instanceof PluginListComponent ||
|
|
951
|
+
view instanceof PluginDetailComponent ||
|
|
952
|
+
view instanceof MarketplacePluginDetailComponent
|
|
953
|
+
) {
|
|
954
|
+
view.handlePrefsEvent(event);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
|
|
768
958
|
#showPluginDetail(plugin: InstalledPlugin): void {
|
|
769
959
|
this.#currentView = "npm-detail";
|
|
770
960
|
this.#currentPlugin = plugin;
|
|
@@ -2,19 +2,22 @@ import { type SelectItem, SelectList, type SgrMouseEvent } from "../index";
|
|
|
2
2
|
import { getSelectListTheme } from "../theme/theme";
|
|
3
3
|
import { OverlayPanel } from "../chrome/overlay-box";
|
|
4
4
|
import { routeSelectListMouseWithTopBorder } from "../chrome/select-list-mouse-routing";
|
|
5
|
+
import type { DescribeContext, NativeNode, NativeUiEvent } from "../native/node";
|
|
6
|
+
import { SelectListSheet } from "../native/picker";
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Component that renders a queue mode selector with borders
|
|
8
10
|
*/
|
|
9
11
|
export class QueueModeSelectorComponent extends OverlayPanel {
|
|
10
12
|
#selectList: SelectList;
|
|
13
|
+
#sheet: SelectListSheet;
|
|
11
14
|
|
|
12
15
|
constructor(
|
|
13
16
|
currentMode: "all" | "one-at-a-time",
|
|
14
17
|
onSelect: (mode: "all" | "one-at-a-time") => void,
|
|
15
18
|
onCancel: () => void,
|
|
16
19
|
) {
|
|
17
|
-
super("Queue Mode");
|
|
20
|
+
super("Queue Mode", "omp.overlay.queue-mode");
|
|
18
21
|
|
|
19
22
|
const queueModes: SelectItem[] = [
|
|
20
23
|
{
|
|
@@ -43,6 +46,21 @@ export class QueueModeSelectorComponent extends OverlayPanel {
|
|
|
43
46
|
};
|
|
44
47
|
|
|
45
48
|
this.addChild(this.#selectList);
|
|
49
|
+
this.#sheet = new SelectListSheet(this.#selectList, {
|
|
50
|
+
title: "Queue mode",
|
|
51
|
+
icon: "list",
|
|
52
|
+
noun: "modes",
|
|
53
|
+
current: [currentMode],
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
override describe(cx: DescribeContext): NativeNode | null {
|
|
58
|
+
return cx.supports("picker") ? this.#sheet.describe() : super.describe(cx);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Picker pointer events drive the list exactly as its keys do. */
|
|
62
|
+
handleNativeEvent(event: NativeUiEvent): void {
|
|
63
|
+
this.#sheet.handle(event);
|
|
46
64
|
}
|
|
47
65
|
|
|
48
66
|
getSelectList(): SelectList {
|
|
@@ -9,9 +9,33 @@ import { centeredViewportRange } from "../components/scroll-viewport";
|
|
|
9
9
|
import { formatUsageResetWindow } from "./usage-display";
|
|
10
10
|
import { formatKeyHint } from "../app-keybindings";
|
|
11
11
|
import { editorKey, editorKeys } from "../chrome/keybinding-hints";
|
|
12
|
+
import { node, span, text } from "../native/describe";
|
|
13
|
+
import type { NativeNode, NativeUiEvent } from "../native/node";
|
|
14
|
+
import { actionHint, hintsRow, overlayCard } from "../native/overlay";
|
|
12
15
|
|
|
13
16
|
const RESET_SELECTOR_MAX_VISIBLE = 10;
|
|
14
17
|
|
|
18
|
+
const oneLine = (value: string): string => sanitizeText(value.replace(/[\r\n\t]+/g, " "));
|
|
19
|
+
|
|
20
|
+
/** Reset count, usability, expiry and unavailability of an account row, or its error. */
|
|
21
|
+
function accountCountLabel(account: ResetUsageAccount): string {
|
|
22
|
+
if (account.error) return oneLine(account.error);
|
|
23
|
+
let countLabel = `${account.availableCount} saved reset${account.availableCount === 1 ? "" : "s"}`;
|
|
24
|
+
if (account.redeemableCount !== account.availableCount) {
|
|
25
|
+
countLabel += ` · ${account.redeemableCount} usable now`;
|
|
26
|
+
}
|
|
27
|
+
if (account.expiresAt) {
|
|
28
|
+
const expiryMs = Date.parse(account.expiresAt);
|
|
29
|
+
if (!Number.isNaN(expiryMs)) {
|
|
30
|
+
countLabel += expiryMs > Date.now() ? ` · expires in ${formatDuration(expiryMs - Date.now())}` : " · expired";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (account.redeemableCount <= 0 && account.unavailableReason) {
|
|
34
|
+
countLabel += ` · ${oneLine(account.unavailableReason)}`;
|
|
35
|
+
}
|
|
36
|
+
return countLabel;
|
|
37
|
+
}
|
|
38
|
+
|
|
15
39
|
/** One account row with its redeemable rate-limit reset credits. */
|
|
16
40
|
export interface ResetUsageAccount {
|
|
17
41
|
label: string;
|
|
@@ -47,9 +71,12 @@ export class ResetUsageSelectorComponent extends OverlayPanel {
|
|
|
47
71
|
#statusMessage: string | undefined;
|
|
48
72
|
#onSelectCallback: (account: ResetUsageAccount) => void;
|
|
49
73
|
#onCancelCallback: () => void;
|
|
74
|
+
#nativeItems: readonly NativeNode[] | undefined;
|
|
75
|
+
#nativeHints: NativeNode | undefined;
|
|
76
|
+
#nativeRoot: NativeNode | undefined;
|
|
50
77
|
|
|
51
78
|
constructor(accounts: ResetUsageAccount[], onSelect: (account: ResetUsageAccount) => void, onCancel: () => void) {
|
|
52
|
-
super("Spend a saved rate-limit reset");
|
|
79
|
+
super("Spend a saved rate-limit reset", "omp.overlay.reset-usage");
|
|
53
80
|
this.#onSelectCallback = onSelect;
|
|
54
81
|
this.#onCancelCallback = onCancel;
|
|
55
82
|
const firstRedeemable = accounts.find(account => account.redeemableCount > 0);
|
|
@@ -71,8 +98,8 @@ export class ResetUsageSelectorComponent extends OverlayPanel {
|
|
|
71
98
|
}
|
|
72
99
|
|
|
73
100
|
#updateList(): void {
|
|
101
|
+
this.#nativeRoot = undefined;
|
|
74
102
|
this.#listContainer.clear();
|
|
75
|
-
const oneLine = (value: string): string => sanitizeText(value.replace(/[\r\n\t]+/g, " "));
|
|
76
103
|
|
|
77
104
|
const items = this.#menu.visibleItems;
|
|
78
105
|
const total = items.length;
|
|
@@ -85,25 +112,7 @@ export class ResetUsageSelectorComponent extends OverlayPanel {
|
|
|
85
112
|
if (!account) continue;
|
|
86
113
|
const isSelected = i === this.#menu.selectedIndex;
|
|
87
114
|
const redeemable = account.redeemableCount > 0;
|
|
88
|
-
|
|
89
|
-
if (account.error) {
|
|
90
|
-
countLabel = oneLine(account.error);
|
|
91
|
-
} else {
|
|
92
|
-
countLabel = `${account.availableCount} saved reset${account.availableCount === 1 ? "" : "s"}`;
|
|
93
|
-
if (account.redeemableCount !== account.availableCount) {
|
|
94
|
-
countLabel += ` · ${account.redeemableCount} usable now`;
|
|
95
|
-
}
|
|
96
|
-
if (account.expiresAt) {
|
|
97
|
-
const expiryMs = Date.parse(account.expiresAt);
|
|
98
|
-
if (!Number.isNaN(expiryMs)) {
|
|
99
|
-
countLabel +=
|
|
100
|
-
expiryMs > Date.now() ? ` · expires in ${formatDuration(expiryMs - Date.now())}` : " · expired";
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (!redeemable && account.unavailableReason) {
|
|
104
|
-
countLabel += ` · ${oneLine(account.unavailableReason)}`;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
115
|
+
const countLabel = accountCountLabel(account);
|
|
107
116
|
const countText = account.error
|
|
108
117
|
? theme.fg("error", countLabel)
|
|
109
118
|
: redeemable
|
|
@@ -205,25 +214,86 @@ export class ResetUsageSelectorComponent extends OverlayPanel {
|
|
|
205
214
|
this.#statusMessage = undefined;
|
|
206
215
|
this.#updateList();
|
|
207
216
|
} else if (matchesKey(keyData, "enter") || matchesKey(keyData, "return") || keyData === "\n") {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
217
|
+
this.#activateSelection();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
#activateSelection(): void {
|
|
222
|
+
const account = this.#menu.selectedItem;
|
|
223
|
+
if (!account) return;
|
|
224
|
+
if (account.redeemableCount <= 0) {
|
|
225
|
+
this.#statusMessage = account.unavailableReason
|
|
226
|
+
? `That account's saved resets are unavailable: ${account.unavailableReason}`
|
|
227
|
+
: "That account has no saved resets usable right now.";
|
|
228
|
+
this.#updateList();
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const result = this.#menu.requestActivation();
|
|
232
|
+
if (result.kind === "pending") {
|
|
233
|
+
this.#statusMessage = undefined;
|
|
234
|
+
this.#updateList();
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (result.kind === "confirmed") {
|
|
238
|
+
this.#onSelectCallback(result.item);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
override describe(): NativeNode {
|
|
243
|
+
if (this.#nativeRoot) return this.#nativeRoot;
|
|
244
|
+
this.#nativeItems ??= this.#menu.visibleItems.map(account => {
|
|
245
|
+
const redeemable = account.redeemableCount > 0;
|
|
246
|
+
const detail = [span(`${oneLine(account.providerLabel)} · #${account.target.credentialId}`, "muted")];
|
|
247
|
+
if (account.active) detail.push(span(" (active)", "muted"));
|
|
248
|
+
return node(
|
|
249
|
+
"item",
|
|
250
|
+
{
|
|
251
|
+
label: redeemable ? oneLine(account.label) : [span(oneLine(account.label), "dim")],
|
|
252
|
+
detail,
|
|
253
|
+
value: [span(accountCountLabel(account), account.error ? "error" : redeemable ? "success" : "dim")],
|
|
254
|
+
},
|
|
255
|
+
undefined,
|
|
256
|
+
this.#menu.adapter.getKey(account),
|
|
257
|
+
);
|
|
258
|
+
});
|
|
259
|
+
const pending = this.#menu.visibleItems.find(item => this.#menu.isPending(item));
|
|
260
|
+
const children: NativeNode[] = [
|
|
261
|
+
node(
|
|
262
|
+
"list",
|
|
263
|
+
{
|
|
264
|
+
selected: this.#menu.selectedKey ?? null,
|
|
265
|
+
empty: [span("No provider accounts with saved resets", "muted")],
|
|
266
|
+
max: { lines: RESET_SELECTOR_MAX_VISIBLE },
|
|
267
|
+
},
|
|
268
|
+
this.#nativeItems,
|
|
269
|
+
"list",
|
|
270
|
+
),
|
|
271
|
+
pending
|
|
272
|
+
? text([span(oneLine(this.#confirmationMessage(pending)), "warning")])
|
|
273
|
+
: (this.#nativeHints ??= hintsRow([
|
|
274
|
+
actionHint(["tui.select.up", "tui.select.down"], "select"),
|
|
275
|
+
{ keys: ["enter"], label: "spend a reset" },
|
|
276
|
+
actionHint("tui.select.cancel", "cancel"),
|
|
277
|
+
])),
|
|
278
|
+
];
|
|
279
|
+
if (this.#statusMessage) children.push(text([span(oneLine(this.#statusMessage), "warning")]));
|
|
280
|
+
this.#nativeRoot = overlayCard(this.nativeRole, this.title, children);
|
|
281
|
+
return this.#nativeRoot;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* A click (or double-click) on an account highlights it and presses Enter:
|
|
286
|
+
* moving to another account drops a pending confirmation, so spending a
|
|
287
|
+
* reset still takes a second activation of the same account.
|
|
288
|
+
*/
|
|
289
|
+
handleNativeEvent(event: NativeUiEvent): void {
|
|
290
|
+
if ((event.type !== "select" && event.type !== "activate") || event.key !== "list") return;
|
|
291
|
+
if (this.#menu.selectedKey !== event.item) {
|
|
292
|
+
this.#menu.cancelConfirmation();
|
|
293
|
+
this.#menu.setSelectedKey(event.item);
|
|
294
|
+
if (this.#menu.selectedKey !== event.item) return;
|
|
295
|
+
this.#statusMessage = undefined;
|
|
227
296
|
}
|
|
297
|
+
this.#activateSelection();
|
|
228
298
|
}
|
|
229
299
|
}
|