@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
|
@@ -37,6 +37,10 @@ import {
|
|
|
37
37
|
topBorderSplit,
|
|
38
38
|
} from "../chrome/overlay-box";
|
|
39
39
|
import { matchesAppExternalEditor } from "../keybinding-matchers";
|
|
40
|
+
import type { KeyName } from "../key-hint-format";
|
|
41
|
+
import { item, keyed, node, row as rowNode, span, text } from "../native/describe";
|
|
42
|
+
import { leafKey, type NativeChild, type NativeNode, type NativeUiEvent } from "../native/node";
|
|
43
|
+
import { hintsRow, itemIndex, type NativeHint, noteSpans, overlayCard, selectList } from "../native/overlay";
|
|
40
44
|
|
|
41
45
|
function fit(text: string, width: number): string {
|
|
42
46
|
if (width <= 0) return "";
|
|
@@ -100,6 +104,13 @@ interface RenderedBody {
|
|
|
100
104
|
|
|
101
105
|
type FocusRegion = "files" | "diff" | "actions";
|
|
102
106
|
|
|
107
|
+
/** Described body rows of the current file (or text), rebuilt when the file or annotations change. */
|
|
108
|
+
interface NativeBody {
|
|
109
|
+
fileIndex: number;
|
|
110
|
+
rev: number;
|
|
111
|
+
items: NativeNode[];
|
|
112
|
+
}
|
|
113
|
+
|
|
103
114
|
const SOURCE_SELECTION_GUTTER_WIDTH = 2;
|
|
104
115
|
|
|
105
116
|
const OVERLAY_TITLE = "Code Review";
|
|
@@ -159,6 +170,13 @@ export class AnnotationOverlay implements Component {
|
|
|
159
170
|
#textViewportDriven = false;
|
|
160
171
|
#textRenderedRowBySource: readonly number[] = [];
|
|
161
172
|
#staticRenderedDiffBodies = new WeakMap<ReviewDiffFile, RenderedDiffBody>();
|
|
173
|
+
/** Bumped on every annotation change (each one pushes an undo snapshot) and on undo. */
|
|
174
|
+
#annotationRev = 0;
|
|
175
|
+
#nativeBody: NativeBody | undefined;
|
|
176
|
+
#nativeSig = "";
|
|
177
|
+
#nativeRoot: NativeNode | undefined;
|
|
178
|
+
/** Body the memoized root was built from. */
|
|
179
|
+
#nativeRootBody: NativeBody | undefined;
|
|
162
180
|
|
|
163
181
|
readonly #tui: TUI;
|
|
164
182
|
readonly #theme: Theme;
|
|
@@ -446,20 +464,26 @@ export class AnnotationOverlay implements Component {
|
|
|
446
464
|
}
|
|
447
465
|
return;
|
|
448
466
|
}
|
|
449
|
-
if (this.#keybindings.matches(data, "tui.select.confirm"))
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
467
|
+
if (this.#keybindings.matches(data, "tui.select.confirm")) this.#confirmAction();
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
#actionDisabled(index: number): boolean {
|
|
471
|
+
const hasAnnotations = this.#textSource ? this.#textAnnotations.length > 0 : this.#annotations.length > 0;
|
|
472
|
+
return this.#textSource ? !hasAnnotations : index === 1 && !hasAnnotations;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
#confirmAction(): void {
|
|
476
|
+
if (this.#actionDisabled(this.#actionIndex)) return;
|
|
477
|
+
if (this.#textSource) {
|
|
478
|
+
this.#finish({
|
|
479
|
+
action: "paste",
|
|
480
|
+
annotations: this.getTextAnnotations(),
|
|
481
|
+
});
|
|
482
|
+
} else {
|
|
483
|
+
this.#finish({
|
|
484
|
+
action: this.#actionIndex === 0 ? "review" : "paste",
|
|
485
|
+
annotations: this.getAnnotations(),
|
|
486
|
+
});
|
|
463
487
|
}
|
|
464
488
|
}
|
|
465
489
|
|
|
@@ -708,7 +732,10 @@ export class AnnotationOverlay implements Component {
|
|
|
708
732
|
chooser.selected = (chooser.selected + 1) % chooser.entries.length;
|
|
709
733
|
return;
|
|
710
734
|
}
|
|
711
|
-
if (
|
|
735
|
+
if (this.#keybindings.matches(data, "tui.select.confirm")) this.#openChosenAnnotation(chooser);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
#openChosenAnnotation(chooser: AnnotationChooser): void {
|
|
712
739
|
const index = chooser.entries[chooser.selected];
|
|
713
740
|
this.#annotationChooser = undefined;
|
|
714
741
|
if (index === undefined) return;
|
|
@@ -733,11 +760,13 @@ export class AnnotationOverlay implements Component {
|
|
|
733
760
|
|
|
734
761
|
#pushUndo(): void {
|
|
735
762
|
this.#undoStack.push({ annotations: [...this.#annotations], textAnnotations: [...this.#textAnnotations] });
|
|
763
|
+
this.#annotationRev++;
|
|
736
764
|
}
|
|
737
765
|
|
|
738
766
|
#undoAnnotation(): void {
|
|
739
767
|
const snapshot = this.#undoStack.pop();
|
|
740
768
|
if (!snapshot) return;
|
|
769
|
+
this.#annotationRev++;
|
|
741
770
|
this.#annotations = snapshot.annotations;
|
|
742
771
|
this.#textAnnotations = snapshot.textAnnotations;
|
|
743
772
|
if (this.#annotations.length === 0 && this.#actionIndex === 1) this.#actionIndex = 0;
|
|
@@ -1002,38 +1031,9 @@ export class AnnotationOverlay implements Component {
|
|
|
1002
1031
|
return this.#renderAnnotationChooser(width, maxChooserRows);
|
|
1003
1032
|
}
|
|
1004
1033
|
if (this.#annotating) {
|
|
1005
|
-
|
|
1006
|
-
let action: string;
|
|
1007
|
-
if (this.#textSource) {
|
|
1008
|
-
const label = sanitizeStatusText(this.#textSource.label);
|
|
1009
|
-
location =
|
|
1010
|
-
this.#annotationScope === "text" ? `${label} · text` : `${label} · line ${this.#sourceIndex + 1}`;
|
|
1011
|
-
action =
|
|
1012
|
-
this.#editingAnnotationIndex === undefined
|
|
1013
|
-
? this.#annotationScope === "text"
|
|
1014
|
-
? "Annotate text"
|
|
1015
|
-
: "Annotate line"
|
|
1016
|
-
: "Edit annotation";
|
|
1017
|
-
} else {
|
|
1018
|
-
const file = this.#currentFile();
|
|
1019
|
-
const source = this.#currentSourceRows()[this.#sourceIndex];
|
|
1020
|
-
location =
|
|
1021
|
-
this.#annotationScope === "file"
|
|
1022
|
-
? file
|
|
1023
|
-
? `${displayFileLabel(file)} · file`
|
|
1024
|
-
: "file"
|
|
1025
|
-
: source && file
|
|
1026
|
-
? `${displayFileLabel(file)} · ${source.oldLine ?? "-"}/${source.newLine ?? "-"}`
|
|
1027
|
-
: "diff row";
|
|
1028
|
-
action =
|
|
1029
|
-
this.#editingAnnotationIndex === undefined
|
|
1030
|
-
? this.#annotationScope === "file"
|
|
1031
|
-
? "Annotate file"
|
|
1032
|
-
: "Annotate line"
|
|
1033
|
-
: "Edit annotation";
|
|
1034
|
-
}
|
|
1034
|
+
const { action, location } = this.#annotationCaption();
|
|
1035
1035
|
const caption = truncateToWidth(
|
|
1036
|
-
`${this.#theme.fg("dim", action)} ${this.#theme.fg("accent",
|
|
1036
|
+
`${this.#theme.fg("dim", action)} ${this.#theme.fg("accent", location)}`,
|
|
1037
1037
|
width,
|
|
1038
1038
|
Ellipsis.Unicode,
|
|
1039
1039
|
);
|
|
@@ -1047,6 +1047,45 @@ export class AnnotationOverlay implements Component {
|
|
|
1047
1047
|
this.#editor.focused = true;
|
|
1048
1048
|
return [caption, ...this.#editor.render(width), this.#theme.fg("dim", hints.join(" · "))];
|
|
1049
1049
|
}
|
|
1050
|
+
return [this.#theme.fg("dim", this.#helpText())];
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/** What the active annotation draft does and where it lands. */
|
|
1054
|
+
#annotationCaption(): { action: string; location: string } {
|
|
1055
|
+
let location: string;
|
|
1056
|
+
let action: string;
|
|
1057
|
+
if (this.#textSource) {
|
|
1058
|
+
const label = sanitizeStatusText(this.#textSource.label);
|
|
1059
|
+
location = this.#annotationScope === "text" ? `${label} · text` : `${label} · line ${this.#sourceIndex + 1}`;
|
|
1060
|
+
action =
|
|
1061
|
+
this.#editingAnnotationIndex === undefined
|
|
1062
|
+
? this.#annotationScope === "text"
|
|
1063
|
+
? "Annotate text"
|
|
1064
|
+
: "Annotate line"
|
|
1065
|
+
: "Edit annotation";
|
|
1066
|
+
} else {
|
|
1067
|
+
const file = this.#currentFile();
|
|
1068
|
+
const source = this.#currentSourceRows()[this.#sourceIndex];
|
|
1069
|
+
location =
|
|
1070
|
+
this.#annotationScope === "file"
|
|
1071
|
+
? file
|
|
1072
|
+
? `${displayFileLabel(file)} · file`
|
|
1073
|
+
: "file"
|
|
1074
|
+
: source && file
|
|
1075
|
+
? `${displayFileLabel(file)} · ${source.oldLine ?? "-"}/${source.newLine ?? "-"}`
|
|
1076
|
+
: "diff row";
|
|
1077
|
+
action =
|
|
1078
|
+
this.#editingAnnotationIndex === undefined
|
|
1079
|
+
? this.#annotationScope === "file"
|
|
1080
|
+
? "Annotate file"
|
|
1081
|
+
: "Annotate line"
|
|
1082
|
+
: "Edit annotation";
|
|
1083
|
+
}
|
|
1084
|
+
return { action, location: sanitizeStatusText(location) };
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
/** Footer help for the focused region. */
|
|
1088
|
+
#helpText(): string {
|
|
1050
1089
|
const upDown = `${this.#key("tui.select.up")}/${this.#key("tui.select.down")}`;
|
|
1051
1090
|
const confirm = this.#key("tui.select.confirm");
|
|
1052
1091
|
const editNote = `${formatKeyHint("e")} edit note`;
|
|
@@ -1056,12 +1095,7 @@ export class AnnotationOverlay implements Component {
|
|
|
1056
1095
|
: this.#focus === "diff"
|
|
1057
1096
|
? `${upDown} line · ${formatKeyHint("shift")} faster · ${this.#key("tui.select.pageUp")}/${this.#key("tui.select.pageDown")} · ${formatKeyHints(["g", "shift+g"])} ends · ${formatKeyHint("a")} line note · ${formatKeyHint("shift+a")} ${this.#textSource ? "text" : "file"} note · ${editNote}`
|
|
1058
1097
|
: `${upDown} select · ${confirm} confirm`;
|
|
1059
|
-
return
|
|
1060
|
-
this.#theme.fg(
|
|
1061
|
-
"dim",
|
|
1062
|
-
`${focusHelp} · ${formatKeyHint("u")} undo · ${formatKeyHint("tab")} regions · ${this.#key("tui.select.cancel")} cancel`,
|
|
1063
|
-
),
|
|
1064
|
-
];
|
|
1098
|
+
return `${focusHelp} · ${formatKeyHint("u")} undo · ${formatKeyHint("tab")} regions · ${this.#key("tui.select.cancel")} cancel`;
|
|
1065
1099
|
}
|
|
1066
1100
|
|
|
1067
1101
|
#ensureCursorVisible(renderedRowBySource: readonly number[]): void {
|
|
@@ -1105,6 +1139,311 @@ export class AnnotationOverlay implements Component {
|
|
|
1105
1139
|
});
|
|
1106
1140
|
}
|
|
1107
1141
|
|
|
1142
|
+
describe(): NativeNode {
|
|
1143
|
+
// The terminal lays out the file sidebar; diffs always have one, text never does.
|
|
1144
|
+
this.#sidebarShown = !this.#textSource;
|
|
1145
|
+
if (!this.#sidebarShown && this.#focus === "files") this.#focus = "diff";
|
|
1146
|
+
// Page size for PgUp/PgDn, matching the rendered body height.
|
|
1147
|
+
this.#bodyHeight = Math.max(MIN_BODY_ROWS, (process.stdout.rows || 40) - (this.#actions.length + 8));
|
|
1148
|
+
this.#editor.focused = this.#annotating;
|
|
1149
|
+
const body = this.#describeBodyItems();
|
|
1150
|
+
const chooser = this.#annotationChooser;
|
|
1151
|
+
const sig = [
|
|
1152
|
+
this.#focus,
|
|
1153
|
+
this.#fileIndex,
|
|
1154
|
+
this.#sourceIndex,
|
|
1155
|
+
this.#actionIndex,
|
|
1156
|
+
this.#annotating ? `annotating:${this.#annotationScope}:${this.#editingAnnotationIndex}` : "",
|
|
1157
|
+
chooser ? `chooser:${chooser.selected}:${chooser.entries.join()}` : "",
|
|
1158
|
+
].join("|");
|
|
1159
|
+
if (this.#nativeRoot && sig === this.#nativeSig && body === this.#nativeRootBody) return this.#nativeRoot;
|
|
1160
|
+
|
|
1161
|
+
const children: NativeChild[] = [];
|
|
1162
|
+
const lines = selectList("lines", body.items, {
|
|
1163
|
+
selected: this.#focus === "diff" ? `l${this.#sourceIndex}` : null,
|
|
1164
|
+
virtual: true,
|
|
1165
|
+
empty: [span(this.#textSource ? "No text" : "No reviewable files", "dim")],
|
|
1166
|
+
role: this.#textSource ? "omp.overlay.annotateText.lines" : "omp.overlay.codeReview.diff",
|
|
1167
|
+
tone: this.#focus === "diff" ? "accent" : undefined,
|
|
1168
|
+
});
|
|
1169
|
+
const main = node("col", { grow: 1 }, [this.#describeHeader(), lines], "main");
|
|
1170
|
+
if (this.#sidebarShown) {
|
|
1171
|
+
const files = selectList(
|
|
1172
|
+
"files",
|
|
1173
|
+
this.#files.map((file, index) => {
|
|
1174
|
+
const count = this.#annotationCount(index);
|
|
1175
|
+
const value = [
|
|
1176
|
+
span(`+${file.linesAdded}`, "ins"),
|
|
1177
|
+
span("/", "dim"),
|
|
1178
|
+
span(`-${file.linesRemoved}`, "del"),
|
|
1179
|
+
];
|
|
1180
|
+
if (count) value.push(span(` ✎${count}`, "warning"));
|
|
1181
|
+
return item(`f${index}`, { label: [span(displayFileLabel(file), "path")], value });
|
|
1182
|
+
}),
|
|
1183
|
+
{
|
|
1184
|
+
selected: this.#files.length > 0 ? `f${this.#fileIndex}` : null,
|
|
1185
|
+
role: "omp.overlay.codeReview.files",
|
|
1186
|
+
tone: this.#focus === "files" ? "accent" : undefined,
|
|
1187
|
+
},
|
|
1188
|
+
);
|
|
1189
|
+
const sidebar = node("col", { max: { w: "34ch" }, shrink: 0 }, [files], "sidebar");
|
|
1190
|
+
children.push(keyed(rowNode([sidebar, main], { gap: "md", align: "start" }), "split"));
|
|
1191
|
+
} else {
|
|
1192
|
+
children.push(main);
|
|
1193
|
+
}
|
|
1194
|
+
children.push(keyed(text([span(sanitizeStatusText(this.#mode), "accent strong")]), "mode"));
|
|
1195
|
+
children.push(
|
|
1196
|
+
selectList(
|
|
1197
|
+
"actions",
|
|
1198
|
+
this.#actions.map((label, index) =>
|
|
1199
|
+
item(`a${index}`, { label, disabled: this.#actionDisabled(index) || undefined }),
|
|
1200
|
+
),
|
|
1201
|
+
{ selected: `a${this.#actionIndex}`, tone: this.#focus === "actions" ? "accent" : undefined },
|
|
1202
|
+
),
|
|
1203
|
+
);
|
|
1204
|
+
children.push(...this.#describeFooter());
|
|
1205
|
+
|
|
1206
|
+
this.#nativeSig = sig;
|
|
1207
|
+
this.#nativeRootBody = body;
|
|
1208
|
+
this.#nativeRoot = overlayCard(
|
|
1209
|
+
this.#textSource ? "omp.overlay.annotateText" : "omp.overlay.codeReview",
|
|
1210
|
+
this.#textSource ? TEXT_OVERLAY_TITLE : OVERLAY_TITLE,
|
|
1211
|
+
children,
|
|
1212
|
+
);
|
|
1213
|
+
return this.#nativeRoot;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
handleNativeEvent(event: NativeUiEvent): void {
|
|
1217
|
+
if (this.#finished || this.#externalOperation) return;
|
|
1218
|
+
if (event.type !== "select" && event.type !== "activate") return;
|
|
1219
|
+
const activate = event.type === "activate";
|
|
1220
|
+
const leaf = leafKey(event.key);
|
|
1221
|
+
const chooser = this.#annotationChooser;
|
|
1222
|
+
if (leaf === "chooser") {
|
|
1223
|
+
const index = itemIndex(event.item, "c");
|
|
1224
|
+
if (!chooser || index < 0 || index >= chooser.entries.length) return;
|
|
1225
|
+
chooser.selected = index;
|
|
1226
|
+
if (activate) this.#openChosenAnnotation(chooser);
|
|
1227
|
+
return;
|
|
1228
|
+
}
|
|
1229
|
+
// A draft commits against the current file/row, so the target stays put
|
|
1230
|
+
// while the editor or the chooser is open.
|
|
1231
|
+
if (chooser || this.#annotating) return;
|
|
1232
|
+
switch (leaf) {
|
|
1233
|
+
case "files": {
|
|
1234
|
+
const index = itemIndex(event.item, "f");
|
|
1235
|
+
if (index < 0 || index >= this.#files.length) return;
|
|
1236
|
+
this.#focus = "files";
|
|
1237
|
+
if (index !== this.#fileIndex) this.#selectFile(index);
|
|
1238
|
+
if (activate) this.#focus = "diff";
|
|
1239
|
+
return;
|
|
1240
|
+
}
|
|
1241
|
+
case "lines": {
|
|
1242
|
+
const index = itemIndex(event.item, "l");
|
|
1243
|
+
const rowCount = this.#textSource ? this.#textLines.length : this.#currentSourceRows().length;
|
|
1244
|
+
if (index < 0 || index >= rowCount) return;
|
|
1245
|
+
this.#focus = "diff";
|
|
1246
|
+
this.#sourceIndex = index;
|
|
1247
|
+
this.#textViewportDriven = false;
|
|
1248
|
+
if (activate) this.#focus = "actions";
|
|
1249
|
+
return;
|
|
1250
|
+
}
|
|
1251
|
+
case "actions": {
|
|
1252
|
+
const index = itemIndex(event.item, "a");
|
|
1253
|
+
if (index < 0 || index >= this.#actions.length || this.#actionDisabled(index)) return;
|
|
1254
|
+
this.#focus = "actions";
|
|
1255
|
+
this.#actionIndex = index;
|
|
1256
|
+
if (activate) this.#confirmAction();
|
|
1257
|
+
return;
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
/** One item per diff/text row; annotation callouts are disabled items before their row. */
|
|
1263
|
+
#describeBodyItems(): NativeBody {
|
|
1264
|
+
const cached = this.#nativeBody;
|
|
1265
|
+
if (cached && cached.fileIndex === this.#fileIndex && cached.rev === this.#annotationRev) return cached;
|
|
1266
|
+
const items: NativeNode[] = [];
|
|
1267
|
+
const note = (key: string, label: string, body: string) =>
|
|
1268
|
+
items.push(
|
|
1269
|
+
item(key, {
|
|
1270
|
+
label: noteSpans(label, sanitizeText(body)),
|
|
1271
|
+
disabled: true,
|
|
1272
|
+
tone: "warning",
|
|
1273
|
+
role: "omp.overlay.codeReview.note",
|
|
1274
|
+
}),
|
|
1275
|
+
);
|
|
1276
|
+
if (this.#textSource) {
|
|
1277
|
+
for (const [index, entry] of this.#textAnnotations.entries()) {
|
|
1278
|
+
if (entry.annotation.scope === "text") note(`n${index}`, "text note", entry.annotation.note);
|
|
1279
|
+
}
|
|
1280
|
+
for (const [sourceIndex, sourceLine] of this.#textLines.entries()) {
|
|
1281
|
+
for (const [index, entry] of this.#textAnnotations.entries()) {
|
|
1282
|
+
if (entry.annotation.scope === "line" && entry.sourceIndex === sourceIndex) {
|
|
1283
|
+
note(`n${index}`, "note", entry.annotation.note);
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
items.push(item(`l${sourceIndex}`, { label: sanitizeText(sourceLine) }));
|
|
1287
|
+
}
|
|
1288
|
+
} else {
|
|
1289
|
+
const file = this.#currentFile();
|
|
1290
|
+
if (file) {
|
|
1291
|
+
for (const [index, entry] of this.#annotations.entries()) {
|
|
1292
|
+
if (entry.fileIndex === this.#fileIndex && entry.annotation.scope === "file") {
|
|
1293
|
+
note(`n${index}`, "file note", entry.annotation.note);
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
if (file.isBinary) {
|
|
1297
|
+
items.push(
|
|
1298
|
+
item("binary", { label: [span("Binary diff; no annotatable source rows", "dim")], disabled: true }),
|
|
1299
|
+
);
|
|
1300
|
+
} else if (file.rows.length === 0) {
|
|
1301
|
+
items.push(
|
|
1302
|
+
item("empty", {
|
|
1303
|
+
label: [span("No diff hunks; this may be a rename-only change", "dim")],
|
|
1304
|
+
disabled: true,
|
|
1305
|
+
}),
|
|
1306
|
+
);
|
|
1307
|
+
}
|
|
1308
|
+
let sourceIndex = 0;
|
|
1309
|
+
for (const [rowIndex, diffRow] of file.isBinary ? [] : file.rows.entries()) {
|
|
1310
|
+
if (!isSourceRow(diffRow)) {
|
|
1311
|
+
const s = diffRow.kind === "hunk" ? "accent" : "dim";
|
|
1312
|
+
items.push(item(`r${rowIndex}`, { label: [span(sanitizeText(diffRow.raw), s)], disabled: true }));
|
|
1313
|
+
continue;
|
|
1314
|
+
}
|
|
1315
|
+
for (const [index, entry] of this.#annotations.entries()) {
|
|
1316
|
+
if (
|
|
1317
|
+
entry.fileIndex === this.#fileIndex &&
|
|
1318
|
+
entry.sourceIndex === sourceIndex &&
|
|
1319
|
+
entry.annotation.scope === "line"
|
|
1320
|
+
) {
|
|
1321
|
+
note(`n${index}`, "note", entry.annotation.note);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
const marker = diffRow.kind === "added" ? "+" : diffRow.kind === "removed" ? "-" : " ";
|
|
1325
|
+
const lineNumber = diffRow.kind === "removed" ? diffRow.oldLine : (diffRow.newLine ?? diffRow.oldLine);
|
|
1326
|
+
const color: DiffColor =
|
|
1327
|
+
diffRow.kind === "added"
|
|
1328
|
+
? "toolDiffAdded"
|
|
1329
|
+
: diffRow.kind === "removed"
|
|
1330
|
+
? "toolDiffRemoved"
|
|
1331
|
+
: "toolDiffContext";
|
|
1332
|
+
items.push(
|
|
1333
|
+
item(`l${sourceIndex}`, {
|
|
1334
|
+
label: [
|
|
1335
|
+
span(marker, `${color} mono`),
|
|
1336
|
+
span(`${lineNumber ?? ""} `, "num dim mono"),
|
|
1337
|
+
span(sanitizeText(diffRow.content), `${color} mono`),
|
|
1338
|
+
],
|
|
1339
|
+
}),
|
|
1340
|
+
);
|
|
1341
|
+
sourceIndex++;
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
this.#nativeBody = { fileIndex: this.#fileIndex, rev: this.#annotationRev, items };
|
|
1346
|
+
return this.#nativeBody;
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
#describeHeader(): NativeNode {
|
|
1350
|
+
if (this.#textSource) {
|
|
1351
|
+
const count = this.#textAnnotations.length;
|
|
1352
|
+
const spans = [span(sanitizeStatusText(this.#textSource.label), "strong")];
|
|
1353
|
+
if (count) spans.push(span(` ✎${count}`, "dim"));
|
|
1354
|
+
return keyed(text(spans, { truncate: "end" }), "header");
|
|
1355
|
+
}
|
|
1356
|
+
const file = this.#currentFile();
|
|
1357
|
+
if (!file) return keyed(text([span("No reviewable files", "dim")]), "header");
|
|
1358
|
+
const count = this.#annotationCount(this.#fileIndex);
|
|
1359
|
+
const spans = [
|
|
1360
|
+
span(sanitizeStatusText(displayFileLabel(file)), "strong path"),
|
|
1361
|
+
span(` +${file.linesAdded}`, "ins"),
|
|
1362
|
+
span("/", "dim"),
|
|
1363
|
+
span(`-${file.linesRemoved}`, "del"),
|
|
1364
|
+
];
|
|
1365
|
+
if (count) spans.push(span(` ✎${count}`, "dim"));
|
|
1366
|
+
return keyed(text(spans, { truncate: "middle" }), "header");
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
#describeFooter(): NativeChild[] {
|
|
1370
|
+
const chooser = this.#annotationChooser;
|
|
1371
|
+
if (chooser) {
|
|
1372
|
+
const entries = chooser.entries.map((index, i) => {
|
|
1373
|
+
const entry = chooser.kind === "text" ? this.#textAnnotations[index] : this.#annotations[index];
|
|
1374
|
+
const location = !entry
|
|
1375
|
+
? ""
|
|
1376
|
+
: "fileIndex" in entry
|
|
1377
|
+
? this.#annotationLocation(entry)
|
|
1378
|
+
: this.#textAnnotationLocation(entry);
|
|
1379
|
+
return item(`c${i}`, {
|
|
1380
|
+
label: sanitizeStatusText(entry?.annotation.note.split(/\r?\n/, 1)[0] ?? ""),
|
|
1381
|
+
detail: location,
|
|
1382
|
+
});
|
|
1383
|
+
});
|
|
1384
|
+
return [
|
|
1385
|
+
keyed(text([span("Edit annotation", "accent strong")]), "chooserHead"),
|
|
1386
|
+
selectList("chooser", entries, { selected: `c${chooser.selected}` }),
|
|
1387
|
+
hintsRow(
|
|
1388
|
+
[
|
|
1389
|
+
this.#hint(["tui.select.up", "tui.select.down"], "choose"),
|
|
1390
|
+
this.#hint("tui.select.confirm", "edit"),
|
|
1391
|
+
this.#hint("tui.select.cancel", "cancel"),
|
|
1392
|
+
],
|
|
1393
|
+
"chooserHints",
|
|
1394
|
+
),
|
|
1395
|
+
];
|
|
1396
|
+
}
|
|
1397
|
+
if (this.#annotating) {
|
|
1398
|
+
const { action, location } = this.#annotationCaption();
|
|
1399
|
+
return [
|
|
1400
|
+
keyed(text([span(`${action} `, "dim"), span(location, "accent")], { truncate: "end" }), "annotateHead"),
|
|
1401
|
+
this.#editor,
|
|
1402
|
+
hintsRow(
|
|
1403
|
+
[
|
|
1404
|
+
this.#hint("tui.input.submit", "save"),
|
|
1405
|
+
this.#hint("tui.input.newLine", "newline"),
|
|
1406
|
+
this.#hint("tui.select.cancel", "cancel"),
|
|
1407
|
+
this.#hint("app.editor.external", "editor"),
|
|
1408
|
+
],
|
|
1409
|
+
"annotateHints",
|
|
1410
|
+
),
|
|
1411
|
+
];
|
|
1412
|
+
}
|
|
1413
|
+
const key = (keys: KeyName | readonly KeyName[], label: string): NativeHint => ({
|
|
1414
|
+
keys: typeof keys === "string" ? [keys] : keys,
|
|
1415
|
+
label,
|
|
1416
|
+
});
|
|
1417
|
+
const upDown = (label: string) => this.#hint(["tui.select.up", "tui.select.down"], label);
|
|
1418
|
+
const editNote = key("e", "edit note");
|
|
1419
|
+
const hints: (NativeHint | undefined)[] =
|
|
1420
|
+
this.#focus === "files"
|
|
1421
|
+
? [upDown("file"), this.#hint("tui.select.confirm", "diff"), key(["a", "shift+a"], "file note"), editNote]
|
|
1422
|
+
: this.#focus === "diff"
|
|
1423
|
+
? [
|
|
1424
|
+
upDown("line"),
|
|
1425
|
+
key("shift", "faster"),
|
|
1426
|
+
this.#hint(["tui.select.pageUp", "tui.select.pageDown"], "page"),
|
|
1427
|
+
key(["g", "shift+g"], "ends"),
|
|
1428
|
+
key("a", "line note"),
|
|
1429
|
+
key("shift+a", this.#textSource ? "text note" : "file note"),
|
|
1430
|
+
editNote,
|
|
1431
|
+
]
|
|
1432
|
+
: [upDown("select"), this.#hint("tui.select.confirm", "confirm")];
|
|
1433
|
+
hints.push(key("u", "undo"), key("tab", "regions"), this.#hint("tui.select.cancel", "cancel"));
|
|
1434
|
+
return [hintsRow(hints)];
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
/** Keycap hint for the primary keys this overlay's keybindings bind to `actions`. */
|
|
1438
|
+
#hint(actions: Keybinding | readonly Keybinding[], label: string): NativeHint | undefined {
|
|
1439
|
+
const keys: KeyName[] = [];
|
|
1440
|
+
for (const action of typeof actions === "string" ? [actions] : actions) {
|
|
1441
|
+
const [key] = this.#keybindings.getKeys(action);
|
|
1442
|
+
if (key) keys.push(key);
|
|
1443
|
+
}
|
|
1444
|
+
return keys.length > 0 ? { keys, label } : undefined;
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1108
1447
|
render(width: number): readonly string[] {
|
|
1109
1448
|
const terminalHeight = process.stdout.rows || 40;
|
|
1110
1449
|
this.#sidebarShown = this.#textSource ? false : this.#canShowSidebar(width);
|