@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
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import type { Usage } from "@oh-my-pi/pi-ai";
|
|
2
|
-
import { Container
|
|
1
|
+
import type { AssistantMessage, Usage } from "@oh-my-pi/pi-ai";
|
|
2
|
+
import { Container } from "../tui";
|
|
3
|
+
import { Spacer } from "../components/spacer";
|
|
3
4
|
import { formatDuration, formatNumber } from "@oh-my-pi/pi-utils";
|
|
4
5
|
import { theme } from "../theme/theme";
|
|
5
6
|
import { formatMetricRow, MetricRow, type MetricSpec } from "../components/metric";
|
|
7
|
+
import { node, row, span, text } from "../native/describe";
|
|
8
|
+
import type { NativeChild, NativeNode } from "../native/node";
|
|
6
9
|
|
|
7
10
|
/** Below this the rate is nonsense (cached/instant responses yield absurd tok/s). */
|
|
8
11
|
const MIN_DURATION_MS = 100;
|
|
@@ -32,13 +35,84 @@ export function turnElapsedMs(
|
|
|
32
35
|
return elapsed > 0 ? Math.round(elapsed) : undefined;
|
|
33
36
|
}
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
/** A finished turn's totals, the native `omp.turn.usage` line under its last answer. */
|
|
39
|
+
export interface TurnUsageSummary {
|
|
40
|
+
/** Prompt→yield wall time; undefined when either end is unknown. */
|
|
41
|
+
readonly elapsedMs: number | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Prompt tokens: input, cache writes and orchestration input. Cache reads
|
|
44
|
+
* re-read the context each request, so they stay out (as in the status
|
|
45
|
+
* line's total).
|
|
46
|
+
*/
|
|
47
|
+
readonly input: number;
|
|
48
|
+
/** Output tokens, orchestration output included. */
|
|
49
|
+
readonly output: number;
|
|
50
|
+
/** Billed cost in dollars. */
|
|
51
|
+
readonly cost: number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Sums the requests of a turn. {@link add} returns the turn's summary on the
|
|
56
|
+
* message that ends the run (any stop but `toolUse`) and starts over.
|
|
57
|
+
*/
|
|
58
|
+
export class TurnUsageTally {
|
|
59
|
+
#input = 0;
|
|
60
|
+
#output = 0;
|
|
61
|
+
#cost = 0;
|
|
62
|
+
|
|
63
|
+
/** Drop a partial turn (a new prompt, a fresh run). */
|
|
64
|
+
reset(): void {
|
|
65
|
+
this.#input = 0;
|
|
66
|
+
this.#output = 0;
|
|
67
|
+
this.#cost = 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
add(message: AssistantMessage, turnStartedAt: number | undefined): TurnUsageSummary | undefined {
|
|
71
|
+
const { usage } = message;
|
|
72
|
+
this.#input += usage.input + usage.cacheWrite + (usage.orchestration?.input ?? 0);
|
|
73
|
+
this.#output += usage.output + (usage.orchestration?.output ?? 0);
|
|
74
|
+
this.#cost += usage.cost.total;
|
|
75
|
+
if (message.stopReason === "toolUse") return undefined;
|
|
76
|
+
const summary =
|
|
77
|
+
this.#input + this.#output > 0 || this.#cost > 0
|
|
78
|
+
? {
|
|
79
|
+
elapsedMs: turnElapsedMs(turnStartedAt, message),
|
|
80
|
+
input: this.#input,
|
|
81
|
+
output: this.#output,
|
|
82
|
+
cost: this.#cost,
|
|
83
|
+
}
|
|
84
|
+
: undefined;
|
|
85
|
+
this.reset();
|
|
86
|
+
return summary;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The native turn line: `12.4s · 19K tok · $0.02 this turn` (the time drops
|
|
92
|
+
* out when unknown, the cost when nothing was billed), and its tooltip with
|
|
93
|
+
* exact counts.
|
|
94
|
+
*/
|
|
95
|
+
export function formatTurnUsage(summary: TurnUsageSummary): { text: string; title: string } {
|
|
96
|
+
const tokens = summary.input + summary.output;
|
|
97
|
+
const cost = summary.cost > 0 ? (summary.cost < 0.005 ? "<$0.01" : `$${summary.cost.toFixed(2)}`) : undefined;
|
|
98
|
+
const time = summary.elapsedMs === undefined ? undefined : formatDuration(summary.elapsedMs);
|
|
99
|
+
const text = [time, `${formatNumber(tokens)} tok`, cost].filter(part => part !== undefined).join(" · ");
|
|
100
|
+
const exact = `${tokens.toLocaleString("en-US")} tokens (${summary.input.toLocaleString("en-US")} in · ${summary.output.toLocaleString("en-US")} out)`;
|
|
101
|
+
const title = [time, exact, cost].filter(part => part !== undefined).join(" · ");
|
|
102
|
+
return { text: `${text} this turn`, title: `This turn: ${title}` };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Output tokens per second over the whole request; undefined when the duration is too short to mean anything. */
|
|
106
|
+
function usageThroughput(usage: Usage, durationMs: number | undefined): number | undefined {
|
|
107
|
+
if (!durationMs || durationMs <= MIN_DURATION_MS || usage.output <= 0) return undefined;
|
|
108
|
+
// TPS over the total request duration — the post-TTFT window undercounts
|
|
109
|
+
// generation time when reasoning tokens are hidden before the first
|
|
110
|
+
// visible byte, inflating the rate.
|
|
111
|
+
return (usage.output / durationMs) * 1000;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Every metric except throughput, which the native row declares as a `rate`. */
|
|
115
|
+
function usageRowBaseSpecs(usage: Usage, ttftMs?: number, timestamp?: number, turnElapsedMs?: number): MetricSpec[] {
|
|
42
116
|
const totalInput = usage.input + usage.cacheWrite;
|
|
43
117
|
const specs: MetricSpec[] = [];
|
|
44
118
|
// Lead with the turn's local wall-clock time (down to the second), log-line style.
|
|
@@ -61,16 +135,88 @@ function usageRowSpecs(
|
|
|
61
135
|
if (ttftMs && ttftMs > 0) {
|
|
62
136
|
specs.push({ leading: theme.icon.time, value: `${(ttftMs / 1000).toFixed(1)}s` });
|
|
63
137
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
138
|
+
return specs;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function usageRowSpecs(
|
|
142
|
+
usage: Usage,
|
|
143
|
+
durationMs?: number,
|
|
144
|
+
ttftMs?: number,
|
|
145
|
+
timestamp?: number,
|
|
146
|
+
turnElapsedMs?: number,
|
|
147
|
+
): MetricSpec[] {
|
|
148
|
+
const specs = usageRowBaseSpecs(usage, ttftMs, timestamp, turnElapsedMs);
|
|
149
|
+
const tokPerSec = usageThroughput(usage, durationMs);
|
|
150
|
+
if (tokPerSec !== undefined) {
|
|
69
151
|
specs.push({ leading: theme.icon.throughput, value: `${tokPerSec.toFixed(1)}/s` });
|
|
70
152
|
}
|
|
71
153
|
return specs;
|
|
72
154
|
}
|
|
73
155
|
|
|
156
|
+
/** Per-turn usage block: a dim metric strip under the turn; natively a wrapping row with a `rate` for throughput. */
|
|
157
|
+
class UsageRowBlock extends Container {
|
|
158
|
+
readonly #usage: Usage;
|
|
159
|
+
readonly #durationMs: number | undefined;
|
|
160
|
+
readonly #ttftMs: number | undefined;
|
|
161
|
+
readonly #timestamp: number | undefined;
|
|
162
|
+
readonly #turnElapsedMs: number | undefined;
|
|
163
|
+
#nativeNode: NativeNode | undefined;
|
|
164
|
+
|
|
165
|
+
constructor(usage: Usage, durationMs?: number, ttftMs?: number, timestamp?: number, turnElapsedMs?: number) {
|
|
166
|
+
super();
|
|
167
|
+
this.#usage = usage;
|
|
168
|
+
this.#durationMs = durationMs;
|
|
169
|
+
this.#ttftMs = ttftMs;
|
|
170
|
+
this.#timestamp = timestamp;
|
|
171
|
+
this.#turnElapsedMs = turnElapsedMs;
|
|
172
|
+
this.addChild(new Spacer(1));
|
|
173
|
+
this.addChild(
|
|
174
|
+
new MetricRow(usageRowSpecs(usage, durationMs, ttftMs, timestamp, turnElapsedMs), {
|
|
175
|
+
separator: " ",
|
|
176
|
+
overflow: "wrap",
|
|
177
|
+
paddingX: 1,
|
|
178
|
+
paddingY: 0,
|
|
179
|
+
style: text => theme.fg("dim", text),
|
|
180
|
+
}),
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* One quiet mono line (`18:02 · Δ 6.2s · in 18.4K · out 640 · cache 12K ·
|
|
186
|
+
* ttft 0.9s · 96 tok/s`): worded metrics instead of the ANSI icons, the
|
|
187
|
+
* full timestamp in the tooltip, and throughput as a `rate`.
|
|
188
|
+
*/
|
|
189
|
+
override describe(): NativeNode {
|
|
190
|
+
if (this.#nativeNode) return this.#nativeNode;
|
|
191
|
+
const usage = this.#usage;
|
|
192
|
+
const parts: string[] = [];
|
|
193
|
+
const timestamp = this.#timestamp;
|
|
194
|
+
const stamped = timestamp !== undefined && Number.isFinite(timestamp) && timestamp > 0;
|
|
195
|
+
if (stamped) parts.push(formatUsageTimestamp(timestamp).slice(11, 16));
|
|
196
|
+
if (this.#turnElapsedMs !== undefined && this.#turnElapsedMs > 0) {
|
|
197
|
+
parts.push(`Δ ${formatDuration(Math.round(this.#turnElapsedMs))}`);
|
|
198
|
+
}
|
|
199
|
+
parts.push(`in ${formatNumber(usage.input + usage.cacheWrite)}`, `out ${formatNumber(usage.output)}`);
|
|
200
|
+
if (usage.cacheRead > 0) parts.push(`cache ${formatNumber(usage.cacheRead)}`);
|
|
201
|
+
if (this.#ttftMs && this.#ttftMs > 0) parts.push(`ttft ${(this.#ttftMs / 1000).toFixed(1)}s`);
|
|
202
|
+
const children: NativeChild[] = [text([span(parts.join(" · "), "dim")])];
|
|
203
|
+
const tokPerSec = usageThroughput(usage, this.#durationMs);
|
|
204
|
+
if (tokPerSec !== undefined) {
|
|
205
|
+
children.push(
|
|
206
|
+
text([span(" · ", "dim")]),
|
|
207
|
+
node("rate", { value: Math.round(tokPerSec * 10) / 10, unit: "tok/s" }),
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
this.#nativeNode = row(children, {
|
|
211
|
+
role: "omp.usage.turn",
|
|
212
|
+
gap: "none",
|
|
213
|
+
align: "baseline",
|
|
214
|
+
...(stamped ? { title: formatUsageTimestamp(timestamp) } : {}),
|
|
215
|
+
});
|
|
216
|
+
return this.#nativeNode;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
74
220
|
/** Format the metrics shared by standalone usage blocks and compact tool groups. */
|
|
75
221
|
export function formatUsageRow(
|
|
76
222
|
usage: Usage,
|
|
@@ -102,17 +248,7 @@ export function createUsageRowBlock(
|
|
|
102
248
|
timestamp?: number,
|
|
103
249
|
turnElapsedMs?: number,
|
|
104
250
|
): Container {
|
|
105
|
-
const block = new
|
|
106
|
-
block.addChild(new Spacer(1));
|
|
107
|
-
block.addChild(
|
|
108
|
-
new MetricRow(usageRowSpecs(usage, durationMs, ttftMs, timestamp, turnElapsedMs), {
|
|
109
|
-
separator: " ",
|
|
110
|
-
overflow: "wrap",
|
|
111
|
-
paddingX: 1,
|
|
112
|
-
paddingY: 0,
|
|
113
|
-
style: text => theme.fg("dim", text),
|
|
114
|
-
}),
|
|
115
|
-
);
|
|
251
|
+
const block = new UsageRowBlock(usage, durationMs, ttftMs, timestamp, turnElapsedMs);
|
|
116
252
|
usageRowBlocks.add(block);
|
|
117
253
|
return block;
|
|
118
254
|
}
|
|
@@ -12,6 +12,10 @@ import {
|
|
|
12
12
|
visibleWidth,
|
|
13
13
|
} from "../index";
|
|
14
14
|
import { fileHyperlink } from "../render/hyperlink";
|
|
15
|
+
import { registerNativeBlob } from "../native/blobs";
|
|
16
|
+
import { node, row, span } from "../native/describe";
|
|
17
|
+
import { plainText } from "../native/spans";
|
|
18
|
+
import type { DescribeContext, NativeNode } from "../native/node";
|
|
15
19
|
import { convertImageToPng } from "../chat/image-loading";
|
|
16
20
|
import { attachmentSgr } from "./composer-attachments";
|
|
17
21
|
import { cachedImageDimensions, setCachedImageDimensions } from "./image-references";
|
|
@@ -29,9 +33,12 @@ const RESET_FG = "\x1b[39m";
|
|
|
29
33
|
* (pastes are usually re-encoded JPEG/WebP) convert before transmit — the same pipeline
|
|
30
34
|
* the transcript uses. `null` = conversion in flight or failed. */
|
|
31
35
|
const kImagePng = Symbol("omp.imagePng");
|
|
36
|
+
/** Content address of the draft image's decoded bytes, registered once for TSP `image` nodes. */
|
|
37
|
+
const kImageBlob = Symbol("omp.imageBlob");
|
|
32
38
|
|
|
33
39
|
interface ImageContentWithPng extends ImageContent {
|
|
34
40
|
[kImagePng]?: ImageContent | null;
|
|
41
|
+
[kImageBlob]?: string;
|
|
35
42
|
}
|
|
36
43
|
|
|
37
44
|
/**
|
|
@@ -50,6 +57,59 @@ export class AttachmentChipsBand implements Component {
|
|
|
50
57
|
private readonly requestRender: () => void,
|
|
51
58
|
) {}
|
|
52
59
|
|
|
60
|
+
#native: { chips: readonly ComposerChipDescriptor[]; node: NativeNode } | undefined;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* A wrapping `row` of chip `card`s (`omp.composer.chip`) titled with the
|
|
64
|
+
* buffer token (`<icon> #N`): images and videos show the image itself,
|
|
65
|
+
* pastes their leading lines; the caption carries pixel size or line/char
|
|
66
|
+
* count. Hidden while nothing is staged.
|
|
67
|
+
*/
|
|
68
|
+
describe(_cx: DescribeContext): NativeNode {
|
|
69
|
+
const chips = this.editor.composerChips();
|
|
70
|
+
if (this.#native?.chips === chips) return this.#native.node;
|
|
71
|
+
const cards: NativeNode[] = [];
|
|
72
|
+
for (const chip of chips) {
|
|
73
|
+
const icon = theme.symbol(
|
|
74
|
+
chip.kind === "paste" ? "chip.paste" : chip.kind === "video" ? "chip.video" : "chip.image",
|
|
75
|
+
);
|
|
76
|
+
const title = `${icon} #${chip.n}`;
|
|
77
|
+
let content: NativeNode;
|
|
78
|
+
let caption: string;
|
|
79
|
+
if (chip.kind === "paste") {
|
|
80
|
+
caption = chip.text.lineCount > 1 ? `+${chip.text.lineCount} lines` : `${chip.text.charCount} chars`;
|
|
81
|
+
content = node("text", {
|
|
82
|
+
spans: [span(plainText(chip.text.content.split("\n", 4).join("\n")), "muted")],
|
|
83
|
+
wrap: "none",
|
|
84
|
+
lines: 4,
|
|
85
|
+
});
|
|
86
|
+
} else {
|
|
87
|
+
const dims = this.#imageDims(chip.image);
|
|
88
|
+
caption = dims ? `${dims.width}x${dims.height}` : "";
|
|
89
|
+
const image = chip.image as ImageContentWithPng;
|
|
90
|
+
const blob = image[kImageBlob] ?? registerNativeBlob(Buffer.from(image.data, "base64"), image.mimeType);
|
|
91
|
+
image[kImageBlob] = blob;
|
|
92
|
+
content = node("image", {
|
|
93
|
+
blob,
|
|
94
|
+
alt: title,
|
|
95
|
+
w: dims?.width,
|
|
96
|
+
h: dims?.height,
|
|
97
|
+
max: { w: "12ch", h: "4lines" },
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const head =
|
|
101
|
+
chip.kind !== "paste" && chip.link ? [span(title, "strong", { href: chip.link })] : [span(title, "strong")];
|
|
102
|
+
const children: NativeNode[] = [content];
|
|
103
|
+
if (caption) children.push(node("text", { spans: [span(caption, "dim")], wrap: "none" }));
|
|
104
|
+
cards.push(
|
|
105
|
+
node("card", { role: "omp.composer.chip", tone: "accent", head }, children, `${chip.kind}:${chip.n}`),
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
const described = row(cards, { gap: "sm", wrap: true, role: "omp.composer.chips", hidden: cards.length === 0 });
|
|
109
|
+
this.#native = { chips, node: described };
|
|
110
|
+
return described;
|
|
111
|
+
}
|
|
112
|
+
|
|
53
113
|
render(width: number): readonly string[] {
|
|
54
114
|
const chips = this.editor.composerChips();
|
|
55
115
|
if (chips.length === 0) return [];
|
|
@@ -47,8 +47,10 @@ export function modelChipStyle(label: string, restore = "\x1b[39m\x1b[49m"): str
|
|
|
47
47
|
/** Every glyph a skill chip may start with, across all symbol presets. */
|
|
48
48
|
const SKILL_ICONS = [...new Set(Object.values(SYMBOL_PRESETS).map(m => m["icon.extensionSkill"]))];
|
|
49
49
|
|
|
50
|
-
/** Skill names as they appear in chips: word characters and dashes, dots only between segments
|
|
51
|
-
|
|
50
|
+
/** Skill names as they appear in chips: word characters and dashes, dots only between segments,
|
|
51
|
+
* optionally behind one collision namespace (`<namespace>/<name>`). */
|
|
52
|
+
const SKILL_NAME_SEGMENT_SOURCE = "[\\w-]+(?:\\.[\\w-]+)*";
|
|
53
|
+
const SKILL_NAME_SOURCE = `${SKILL_NAME_SEGMENT_SOURCE}(?:/${SKILL_NAME_SEGMENT_SOURCE})?`;
|
|
52
54
|
|
|
53
55
|
/** Regex source for a chip glyph; word glyphs (ASCII preset) must not continue a preceding word. */
|
|
54
56
|
function glyphSource(icon: string): string {
|
|
@@ -214,12 +216,26 @@ export function composerTokenRegex(mentionLabels: Iterable<string>): RegExp {
|
|
|
214
216
|
|
|
215
217
|
const VISION_MARKER_REGEX = /\[(Image|Video) #([1-9]\d*)((?:,[^\]\n]*)?)\](?: attachment:\/\/(\2))?/g;
|
|
216
218
|
|
|
217
|
-
/**
|
|
218
|
-
export function
|
|
219
|
-
|
|
219
|
+
/** Marker for the Nth attached image or video preview: `[Image #N, WxH]`, or `[Image #N]` without dims. */
|
|
220
|
+
export function formatVisionMarker(
|
|
221
|
+
kind: "image" | "video",
|
|
222
|
+
n: number,
|
|
223
|
+
dims?: { width: number; height: number },
|
|
224
|
+
): string {
|
|
225
|
+
const label = `${kind === "video" ? "Video" : "Image"} #${n}`;
|
|
226
|
+
return dims ? `[${label}, ${dims.width}x${dims.height}]` : `[${label}]`;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Offsets image marker indices, including matching `attachment://` references. With `imageCount`,
|
|
231
|
+
* markers above it are left alone: like `compactImageMarkers`, they are not this text's attachments.
|
|
232
|
+
*/
|
|
233
|
+
export function shiftImageMarkers(text: string, offset: number, imageCount?: number): string {
|
|
234
|
+
if (offset === 0 || imageCount === 0) return text;
|
|
220
235
|
return text.replace(
|
|
221
236
|
VISION_MARKER_REGEX,
|
|
222
|
-
(
|
|
237
|
+
(match, kind: string, idx: string, tail: string, attachmentIdx: string | undefined) => {
|
|
238
|
+
if (imageCount !== undefined && Number(idx) > imageCount) return match;
|
|
223
239
|
const marker = `[${kind} #${Number(idx) + offset}${tail}]`;
|
|
224
240
|
return attachmentIdx === undefined ? marker : `${marker} attachment://${Number(attachmentIdx) + offset}`;
|
|
225
241
|
},
|
|
@@ -249,8 +265,14 @@ export function collapseImageMarkers(
|
|
|
249
265
|
/**
|
|
250
266
|
* Drops unreferenced vision attachments from a submission and densely remaps
|
|
251
267
|
* retained image/video markers. Returns `null` when no compaction is needed.
|
|
268
|
+
* With `byAppearance`, retained markers are also renumbered in the order they first
|
|
269
|
+
* appear, for editors whose images attach out of order (concurrent path loads).
|
|
252
270
|
*/
|
|
253
|
-
export function compactImageMarkers(
|
|
271
|
+
export function compactImageMarkers(
|
|
272
|
+
text: string,
|
|
273
|
+
imageCount: number,
|
|
274
|
+
options?: { byAppearance?: boolean },
|
|
275
|
+
): { text: string; keep: number[] } | null {
|
|
254
276
|
if (imageCount === 0) return null;
|
|
255
277
|
const referenced = new Set<number>();
|
|
256
278
|
const scanner = new RegExp(VISION_MARKER_REGEX.source, "g");
|
|
@@ -260,8 +282,8 @@ export function compactImageMarkers(text: string, imageCount: number): { text: s
|
|
|
260
282
|
const n = Number(match[2]);
|
|
261
283
|
if (n <= imageCount) referenced.add(n);
|
|
262
284
|
}
|
|
263
|
-
|
|
264
|
-
|
|
285
|
+
const keep = options?.byAppearance ? [...referenced] : [...referenced].sort((a, b) => a - b);
|
|
286
|
+
if (keep.length === imageCount && keep.every((n, i) => n === i + 1)) return null;
|
|
265
287
|
const remap = new Map<number, number>(keep.map((n, i) => [n, i + 1]));
|
|
266
288
|
const rewritten = text.replace(
|
|
267
289
|
VISION_MARKER_REGEX,
|
package/src/prompt/composer.ts
CHANGED
|
@@ -16,6 +16,8 @@ import {
|
|
|
16
16
|
type ViewportSize,
|
|
17
17
|
} from "../tui";
|
|
18
18
|
import { sliceWithWidth, visibleWidth } from "../utils";
|
|
19
|
+
import type { NativeChild, NativeSurface, NativeSurfaceProvider } from "../native/node";
|
|
20
|
+
import { sameItems } from "../native/memo";
|
|
19
21
|
import { postmortem } from "@oh-my-pi/pi-utils";
|
|
20
22
|
import { CustomEditor } from "./custom-editor";
|
|
21
23
|
import type { WordCompletionMethod } from "./word-completion";
|
|
@@ -99,6 +101,13 @@ export interface RuntimeChildrenOptions {
|
|
|
99
101
|
* settled rows it displaces retire to native scrollback.
|
|
100
102
|
*/
|
|
101
103
|
readonly transient?: readonly Component[];
|
|
104
|
+
/**
|
|
105
|
+
* Dock order on a TSP terminal (no status strip; the composer carries its
|
|
106
|
+
* facts): the native dock stacks HUD pills, the working row and queued messages over
|
|
107
|
+
* the composer in its own order, and may add describe-only roots. Defaults
|
|
108
|
+
* to the roots below the transcript in render order.
|
|
109
|
+
*/
|
|
110
|
+
readonly nativeDock?: readonly Component[];
|
|
102
111
|
}
|
|
103
112
|
|
|
104
113
|
/** Controls the first terminal paint for a composer that does not already own the terminal. */
|
|
@@ -114,7 +123,11 @@ export interface ComposerStartOptions {
|
|
|
114
123
|
readonly deferInput?: boolean;
|
|
115
124
|
}
|
|
116
125
|
|
|
117
|
-
/**
|
|
126
|
+
/**
|
|
127
|
+
* Mount slot below the editor: the startup status line, then the session-aware
|
|
128
|
+
* one. ANSI only: a TSP terminal has no status strip, the composer carries the
|
|
129
|
+
* status line's facts ({@link StatusLineComponent.describeComposerFacts}).
|
|
130
|
+
*/
|
|
118
131
|
class StatusHost implements Component {
|
|
119
132
|
#component: Component | undefined;
|
|
120
133
|
|
|
@@ -189,7 +202,7 @@ function rowTargetCandidates(target: Component): ((local: number) => string[]) |
|
|
|
189
202
|
* It owns the terminal, welcome header, and editor; InteractiveMode later supplies authoritative
|
|
190
203
|
* data and mounts the session-aware runtime children without replacing the visible header.
|
|
191
204
|
*/
|
|
192
|
-
export class Composer implements TerminalFrameProvider {
|
|
205
|
+
export class Composer implements TerminalFrameProvider, NativeSurfaceProvider {
|
|
193
206
|
readonly ui: TUI;
|
|
194
207
|
#editor: CustomEditor;
|
|
195
208
|
readonly #header = new Container();
|
|
@@ -207,6 +220,7 @@ export class Composer implements TerminalFrameProvider {
|
|
|
207
220
|
#headerBefore: readonly Component[] = [];
|
|
208
221
|
#headerAfter: readonly Component[] = [];
|
|
209
222
|
#runtimeChildren: readonly Component[] = [];
|
|
223
|
+
#nativeDock: readonly Component[] | undefined;
|
|
210
224
|
/** Cache-driven status line shown until {@link setStatusComponent} mounts the session's. */
|
|
211
225
|
#startupStatus: StatusLineComponent | undefined;
|
|
212
226
|
#runtimeMounted = false;
|
|
@@ -263,6 +277,8 @@ export class Composer implements TerminalFrameProvider {
|
|
|
263
277
|
#transientChrome: ReadonlySet<Component> = new Set();
|
|
264
278
|
#transientChromeFloor: number | undefined;
|
|
265
279
|
#lastInterruptAt = 0;
|
|
280
|
+
/** Last described surface; its arrays are reused while their children are unchanged. */
|
|
281
|
+
#nativeSurface: NativeSurface = { main: [], dock: [] };
|
|
266
282
|
#started = false;
|
|
267
283
|
#stopped = false;
|
|
268
284
|
#transferred = false;
|
|
@@ -415,6 +431,41 @@ export class Composer implements TerminalFrameProvider {
|
|
|
415
431
|
return { history, viewport: this.#paintHoverBand(mutable, spans) };
|
|
416
432
|
}
|
|
417
433
|
|
|
434
|
+
/**
|
|
435
|
+
* Describe the whole surface for a TSP terminal. `main` is the flowing
|
|
436
|
+
* document: the header (welcome, extras) and every transcript block as its
|
|
437
|
+
* own component child. `dock` is the live chrome below the transcript in
|
|
438
|
+
* render order: pending messages, HUDs, the working row, the editor and the
|
|
439
|
+
* status line. There is no history/viewport split: retirement, resize
|
|
440
|
+
* replay and hover bands are ANSI concerns.
|
|
441
|
+
*/
|
|
442
|
+
describeSurface(): NativeSurface {
|
|
443
|
+
if (!this.#started || this.#stopped) return this.#nativeSurface;
|
|
444
|
+
const main: NativeChild[] = [...this.#header.children];
|
|
445
|
+
const dock: NativeChild[] = [];
|
|
446
|
+
if (!this.#runtimeMounted) {
|
|
447
|
+
// The bootstrap gap is row spacing; the terminal owns the dock layout.
|
|
448
|
+
dock.push(this.editor);
|
|
449
|
+
} else {
|
|
450
|
+
const roots = this.#runtimeChildren;
|
|
451
|
+
const transcriptIndex = roots.findIndex(root => root instanceof TranscriptContainer);
|
|
452
|
+
if (transcriptIndex < 0) {
|
|
453
|
+
dock.push(...roots);
|
|
454
|
+
} else {
|
|
455
|
+
const transcript = roots[transcriptIndex] as TranscriptContainer;
|
|
456
|
+
main.push(...roots.slice(0, transcriptIndex), ...transcript.nativeBlocks());
|
|
457
|
+
dock.push(...(this.#nativeDock ?? roots.slice(transcriptIndex + 1)));
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
const previous = this.#nativeSurface;
|
|
461
|
+
const nextMain = sameItems(previous.main, main) ? previous.main : main;
|
|
462
|
+
const nextDock = sameItems(previous.dock, dock) ? previous.dock : dock;
|
|
463
|
+
if (nextMain !== previous.main || nextDock !== previous.dock) {
|
|
464
|
+
this.#nativeSurface = { main: nextMain, dock: nextDock };
|
|
465
|
+
}
|
|
466
|
+
return this.#nativeSurface;
|
|
467
|
+
}
|
|
468
|
+
|
|
418
469
|
/**
|
|
419
470
|
* Append one below-transcript root's rows to `after`, recording click spans
|
|
420
471
|
* for its row targets in `after` coordinates.
|
|
@@ -837,6 +888,7 @@ export class Composer implements TerminalFrameProvider {
|
|
|
837
888
|
this.#disposeStartupStatus();
|
|
838
889
|
this.#statusHost.setComponent(component);
|
|
839
890
|
this.editor.setTopBorderProvider(undefined);
|
|
891
|
+
this.editor.composerFacts = component;
|
|
840
892
|
}
|
|
841
893
|
|
|
842
894
|
#disposeStartupStatus(): void {
|
|
@@ -849,6 +901,7 @@ export class Composer implements TerminalFrameProvider {
|
|
|
849
901
|
if (this.#stopped) return;
|
|
850
902
|
this.#transientChrome = new Set(options.transient);
|
|
851
903
|
this.#transientChromeFloor = undefined;
|
|
904
|
+
this.#nativeDock = options.nativeDock;
|
|
852
905
|
this.ui.removeChild(this.#statusHost);
|
|
853
906
|
if (this.#runtimeMounted) {
|
|
854
907
|
for (const child of this.#runtimeChildren) this.ui.removeChild(child);
|