@oh-my-pi/pi-tui 18.4.3 → 18.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/dist/types/apps/cleanse-board.d.ts +17 -0
- package/dist/types/apps/git/help.d.ts +16 -0
- package/dist/types/apps/git/sidebar.d.ts +18 -0
- package/dist/types/apps/live-visualizer.d.ts +10 -0
- package/dist/types/apps/ps-top.d.ts +15 -0
- package/dist/types/apps/standalone-picker.d.ts +3 -0
- package/dist/types/autocomplete.d.ts +8 -0
- package/dist/types/chat/advisor-message.d.ts +12 -2
- package/dist/types/chat/assistant-message.d.ts +20 -0
- package/dist/types/chat/bash-execution.d.ts +9 -0
- package/dist/types/chat/chat-transcript-builder.d.ts +6 -1
- package/dist/types/chat/collab-prompt-message.d.ts +4 -0
- package/dist/types/chat/compaction-summary-message.d.ts +15 -0
- package/dist/types/chat/eval-execution.d.ts +8 -0
- package/dist/types/chat/execution-shared.d.ts +58 -0
- package/dist/types/chat/late-diagnostics-message.d.ts +15 -1
- package/dist/types/chat/read-tool-group.d.ts +15 -0
- package/dist/types/chat/skill-message.d.ts +9 -0
- package/dist/types/chat/stripped-tool-calls-placeholder.d.ts +3 -0
- package/dist/types/chat/todo-reminder.d.ts +4 -1
- package/dist/types/chat/tool-execution.d.ts +25 -1
- package/dist/types/chat/transcript-actions.d.ts +37 -0
- package/dist/types/chat/transcript-entry.d.ts +3 -1
- package/dist/types/chat/user-message.d.ts +25 -0
- package/dist/types/chrome/collab-qrcode.d.ts +7 -0
- package/dist/types/chrome/context-thresholds.d.ts +11 -0
- package/dist/types/chrome/countdown-timer.d.ts +9 -3
- package/dist/types/chrome/diff.d.ts +12 -0
- package/dist/types/chrome/dynamic-border.d.ts +3 -0
- package/dist/types/chrome/format.d.ts +6 -0
- package/dist/types/chrome/message-divider.d.ts +13 -0
- package/dist/types/chrome/message-frame.d.ts +10 -0
- package/dist/types/chrome/message-notice.d.ts +23 -0
- package/dist/types/chrome/overlay-box.d.ts +11 -2
- package/dist/types/chrome/qrcode.d.ts +7 -0
- package/dist/types/chrome/segment-track.d.ts +7 -0
- package/dist/types/chrome/selector-helpers.d.ts +0 -6
- package/dist/types/chrome/status-notice.d.ts +14 -0
- package/dist/types/chrome/streaming-panel.d.ts +3 -0
- package/dist/types/chrome/tool-activity.d.ts +3 -0
- package/dist/types/chrome/transcript-container.d.ts +13 -0
- package/dist/types/chrome/transcript-status.d.ts +15 -3
- package/dist/types/components/box.d.ts +7 -0
- package/dist/types/components/disclosure.d.ts +9 -0
- package/dist/types/components/editor.d.ts +37 -0
- package/dist/types/components/form.d.ts +14 -0
- package/dist/types/components/image.d.ts +7 -0
- package/dist/types/components/input.d.ts +20 -1
- package/dist/types/components/key-value-list.d.ts +3 -0
- package/dist/types/components/layout/geometry.d.ts +16 -0
- package/dist/types/components/layout/row.d.ts +7 -0
- package/dist/types/components/layout/split-pane.d.ts +8 -0
- package/dist/types/components/layout/stack.d.ts +6 -0
- package/dist/types/components/loader.d.ts +48 -0
- package/dist/types/components/markdown.d.ts +8 -0
- package/dist/types/components/metric.d.ts +7 -0
- package/dist/types/components/progress-bar.d.ts +3 -0
- package/dist/types/components/scroll-view.d.ts +6 -0
- package/dist/types/components/section.d.ts +3 -0
- package/dist/types/components/select-list.d.ts +33 -0
- package/dist/types/components/settings-list.d.ts +68 -0
- package/dist/types/components/spacer.d.ts +4 -0
- package/dist/types/components/tab-bar.d.ts +9 -0
- package/dist/types/components/table.d.ts +7 -0
- package/dist/types/components/text.d.ts +6 -0
- package/dist/types/components/tree-view.d.ts +9 -0
- package/dist/types/components/truncated-text.d.ts +3 -0
- package/dist/types/components/wizard-step.d.ts +6 -0
- package/dist/types/hotkeys-markdown.d.ts +24 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/latex-block.d.ts +7 -0
- package/dist/types/native/apply.d.ts +39 -0
- package/dist/types/native/backend.d.ts +94 -0
- package/dist/types/native/blobs.d.ts +29 -0
- package/dist/types/native/describe.d.ts +56 -0
- package/dist/types/native/encode.d.ts +50 -0
- package/dist/types/native/icons.d.ts +18 -0
- package/dist/types/native/memo.d.ts +27 -0
- package/dist/types/native/node.d.ts +107 -0
- package/dist/types/native/overlay.d.ts +64 -0
- package/dist/types/native/picker.d.ts +124 -0
- package/dist/types/native/reconcile.d.ts +41 -0
- package/dist/types/native/settle.d.ts +11 -0
- package/dist/types/native/spans.d.ts +21 -0
- package/dist/types/native/state.d.ts +6 -0
- package/dist/types/native/tone.d.ts +24 -0
- package/dist/types/overlays/advisor-config.d.ts +20 -0
- package/dist/types/overlays/agent-hub-renderer.d.ts +27 -11
- package/dist/types/overlays/agent-hub.d.ts +10 -0
- package/dist/types/overlays/agent-transcript-viewer.d.ts +7 -0
- package/dist/types/overlays/agents-hub.d.ts +8 -0
- package/dist/types/overlays/annotation-overlay.d.ts +3 -0
- package/dist/types/overlays/ask-dialog.d.ts +23 -0
- package/dist/types/overlays/bordered-loader.d.ts +3 -0
- package/dist/types/overlays/btw-history-panel.d.ts +9 -0
- package/dist/types/overlays/btw-panel.d.ts +3 -0
- package/dist/types/overlays/cleanse-panel.d.ts +5 -2
- package/dist/types/overlays/composer-shape-preview.d.ts +7 -1
- package/dist/types/overlays/copy-selector.d.ts +38 -0
- package/dist/types/overlays/error-banner.d.ts +9 -0
- package/dist/types/overlays/extensions/extension-list.d.ts +1 -0
- package/dist/types/overlays/history-search.d.ts +18 -0
- package/dist/types/overlays/hook-editor.d.ts +28 -1
- package/dist/types/overlays/hook-input.d.ts +3 -0
- package/dist/types/overlays/hook-selector.d.ts +10 -0
- package/dist/types/overlays/hub-frame.d.ts +18 -0
- package/dist/types/overlays/jobs-panel.d.ts +24 -0
- package/dist/types/overlays/login-dialog.d.ts +10 -0
- package/dist/types/overlays/logout-account-selector.d.ts +4 -0
- package/dist/types/overlays/mcp-add-wizard.d.ts +4 -0
- package/dist/types/overlays/model-browser.d.ts +69 -0
- package/dist/types/overlays/model-hub.d.ts +7 -0
- package/dist/types/overlays/model-picker.d.ts +7 -0
- package/dist/types/overlays/move-overlay.d.ts +3 -0
- package/dist/types/overlays/oauth-selector.d.ts +4 -0
- package/dist/types/overlays/omfg-panel.d.ts +3 -0
- package/dist/types/overlays/pause-screen.d.ts +12 -0
- package/dist/types/overlays/plan-review-overlay.d.ts +5 -0
- package/dist/types/overlays/plan-save-overlay.d.ts +10 -0
- package/dist/types/overlays/plugin-selector.d.ts +4 -0
- package/dist/types/overlays/plugin-settings.d.ts +30 -0
- package/dist/types/overlays/queue-mode-selector.d.ts +4 -0
- package/dist/types/overlays/reset-usage-selector.d.ts +8 -0
- package/dist/types/overlays/rewind-selector.d.ts +5 -0
- package/dist/types/overlays/session-info-overlay.d.ts +19 -1
- package/dist/types/overlays/session-selector.d.ts +64 -1
- package/dist/types/overlays/settings-defs.d.ts +14 -0
- package/dist/types/overlays/settings-selector.d.ts +21 -0
- package/dist/types/overlays/show-images-selector.d.ts +4 -0
- package/dist/types/overlays/snapcompact-shape-preview.d.ts +2 -0
- package/dist/types/overlays/stats-notice.d.ts +8 -0
- package/dist/types/overlays/theme-selector.d.ts +11 -0
- package/dist/types/overlays/thinking-selector.d.ts +4 -0
- package/dist/types/overlays/tree-selector.d.ts +60 -2
- package/dist/types/overlays/usage-dashboard.d.ts +26 -3
- package/dist/types/overlays/usage-row.d.ts +36 -2
- package/dist/types/prompt/attachment-chips.d.ts +8 -0
- package/dist/types/prompt/composer-attachments.d.ts +15 -3
- package/dist/types/prompt/composer.d.ts +18 -1
- package/dist/types/prompt/custom-editor.d.ts +48 -2
- package/dist/types/prompt/editor-top-gap.d.ts +2 -0
- package/dist/types/prompt/macos-spelling.d.ts +6 -0
- package/dist/types/prompt/magic-keywords.d.ts +9 -0
- package/dist/types/prompt/queued-messages.d.ts +23 -0
- package/dist/types/prompt/skill-tokens.d.ts +4 -2
- package/dist/types/prompt/welcome.d.ts +16 -0
- package/dist/types/render/code-cell.d.ts +10 -0
- package/dist/types/render/file-list.d.ts +8 -0
- package/dist/types/render/hyperlink.d.ts +14 -0
- package/dist/types/render/output-block.d.ts +43 -0
- package/dist/types/render/output-pane.d.ts +17 -0
- package/dist/types/render/tool-card.d.ts +8 -0
- package/dist/types/render/tree-list.d.ts +8 -0
- package/dist/types/render/width-aware-text.d.ts +7 -0
- package/dist/types/setup/scenes/outro.d.ts +7 -0
- package/dist/types/setup/scenes/sign-in.d.ts +7 -0
- package/dist/types/setup/scenes/splash.d.ts +8 -0
- package/dist/types/setup/scenes/types.d.ts +6 -1
- package/dist/types/setup/wizard-overlay.d.ts +9 -0
- package/dist/types/status-line/component.d.ts +49 -5
- package/dist/types/status-line/context-usage.d.ts +20 -0
- package/dist/types/status-line/footer.d.ts +8 -0
- package/dist/types/status-line/metrics.d.ts +1 -2
- package/dist/types/status-line/segments.d.ts +10 -1
- package/dist/types/status-line/types.d.ts +40 -1
- package/dist/types/terminal-capabilities.d.ts +1 -1
- package/dist/types/terminal.d.ts +27 -0
- package/dist/types/theme/defaults/index.d.ts +100 -0
- package/dist/types/theme/schema.d.ts +2 -0
- package/dist/types/theme/shimmer.d.ts +8 -0
- package/dist/types/theme/theme-class.d.ts +2 -0
- package/dist/types/theme/theme.d.ts +33 -1
- package/dist/types/tools/ask.d.ts +3 -0
- package/dist/types/tools/ast-edit.d.ts +10 -1
- package/dist/types/tools/ast-grep.d.ts +10 -1
- package/dist/types/tools/autoresearch.d.ts +21 -4
- package/dist/types/tools/bash.d.ts +30 -1
- package/dist/types/tools/cfg-render.d.ts +5 -1
- package/dist/types/tools/debug.d.ts +3 -1
- package/dist/types/tools/default-renderer.d.ts +6 -1
- package/dist/types/tools/edit.d.ts +14 -1
- package/dist/types/tools/eval.d.ts +12 -1
- package/dist/types/tools/fetch.d.ts +16 -1
- package/dist/types/tools/find.d.ts +15 -1
- package/dist/types/tools/github.d.ts +3 -0
- package/dist/types/tools/glob.d.ts +14 -1
- package/dist/types/tools/goal.d.ts +3 -1
- package/dist/types/tools/grep.d.ts +14 -1
- package/dist/types/tools/grouped-file-output.d.ts +58 -0
- package/dist/types/tools/json-tree.d.ts +20 -0
- package/dist/types/tools/lsp.d.ts +3 -10
- package/dist/types/tools/mcp.d.ts +16 -1
- package/dist/types/tools/memory.d.ts +26 -0
- package/dist/types/tools/native-view.d.ts +90 -0
- package/dist/types/tools/proc-render.d.ts +7 -1
- package/dist/types/tools/read.d.ts +23 -1
- package/dist/types/tools/renderer.d.ts +57 -0
- package/dist/types/tools/report-tool-issue.d.ts +3 -0
- package/dist/types/tools/resolve.d.ts +14 -1
- package/dist/types/tools/task.d.ts +3 -0
- package/dist/types/tools/think.d.ts +3 -0
- package/dist/types/tools/todo.d.ts +12 -0
- package/dist/types/tools/vibe.d.ts +3 -1
- package/dist/types/tools/wait.d.ts +3 -0
- package/dist/types/tools/web-search.d.ts +8 -0
- package/dist/types/tools/write.d.ts +14 -1
- package/dist/types/tools/xdev.d.ts +13 -0
- package/dist/types/tui.d.ts +49 -0
- package/package.json +9 -9
- package/src/apps/autoresearch-dashboard.ts +362 -4
- package/src/apps/cleanse-board.ts +219 -1
- package/src/apps/cleanse-picker.ts +9 -1
- package/src/apps/debug/log-viewer.ts +15 -15
- package/src/apps/debug/protocol-probe.ts +2 -20
- package/src/apps/git/avatar.ts +2 -22
- package/src/apps/git/git-tui.ts +406 -59
- package/src/apps/git/help.ts +130 -0
- package/src/apps/git/sidebar.ts +491 -0
- package/src/apps/live-visualizer.ts +65 -0
- package/src/apps/ps-top.ts +448 -17
- package/src/apps/session-picker.ts +1 -0
- package/src/apps/setup-model-picker.ts +5 -1
- package/src/apps/standalone-picker.ts +55 -1
- package/src/autocomplete.ts +44 -1
- package/src/chat/advisor-message.ts +72 -3
- package/src/chat/assistant-message.ts +346 -11
- package/src/chat/background-tan-message.ts +4 -4
- package/src/chat/bash-execution.ts +81 -0
- package/src/chat/cache-invalidation-marker.ts +8 -0
- package/src/chat/chat-transcript-builder.ts +37 -6
- package/src/chat/collab-prompt-message.ts +15 -3
- package/src/chat/compaction-summary-message.ts +74 -1
- package/src/chat/custom-message.ts +3 -1
- package/src/chat/eval-execution.ts +57 -0
- package/src/chat/execution-shared.ts +153 -1
- package/src/chat/hook-message.ts +1 -0
- package/src/chat/late-diagnostics-message.ts +85 -2
- package/src/chat/read-tool-group.ts +341 -1
- package/src/chat/served-model-marker.ts +8 -0
- package/src/chat/skill-message.ts +63 -0
- package/src/chat/stripped-tool-calls-placeholder.ts +18 -10
- package/src/chat/todo-reminder.ts +34 -4
- package/src/chat/tool-execution.ts +385 -10
- package/src/chat/transcript-actions.ts +38 -0
- package/src/chat/transcript-browser.ts +2 -9
- package/src/chat/transcript-entry.ts +10 -1
- package/src/chat/transcript-render-helpers.ts +16 -15
- package/src/chat/ttsr-notification.ts +38 -1
- package/src/chat/user-message.ts +167 -4
- package/src/chrome/collab-qrcode.ts +27 -2
- package/src/chrome/context-thresholds.ts +34 -0
- package/src/chrome/countdown-timer.ts +24 -1
- package/src/chrome/diff.ts +60 -1
- package/src/chrome/dynamic-border.ts +7 -0
- package/src/chrome/format.ts +12 -0
- package/src/chrome/message-divider.ts +33 -1
- package/src/chrome/message-frame.ts +53 -10
- package/src/chrome/message-notice.ts +71 -0
- package/src/chrome/overlay-box.ts +45 -2
- package/src/chrome/qrcode.ts +28 -0
- package/src/chrome/segment-track.ts +26 -0
- package/src/chrome/selector-helpers.ts +1 -17
- package/src/chrome/status-notice.ts +46 -0
- package/src/chrome/streaming-panel.ts +25 -1
- package/src/chrome/tool-activity.ts +20 -0
- package/src/chrome/transcript-container.ts +37 -0
- package/src/chrome/transcript-status.ts +40 -11
- package/src/components/box.ts +51 -0
- package/src/components/disclosure.ts +33 -0
- package/src/components/editor.ts +216 -27
- package/src/components/form.ts +93 -9
- package/src/components/image.ts +30 -0
- package/src/components/input.ts +77 -26
- package/src/components/key-value-list.ts +18 -0
- package/src/components/layout/geometry.ts +44 -0
- package/src/components/layout/row.ts +30 -0
- package/src/components/layout/split-pane.ts +65 -0
- package/src/components/layout/stack.ts +27 -0
- package/src/components/loader.ts +183 -1
- package/src/components/markdown.ts +21 -0
- package/src/components/metric.ts +39 -0
- package/src/components/progress-bar.ts +28 -0
- package/src/components/scroll-view.ts +23 -0
- package/src/components/section.ts +16 -0
- package/src/components/select-list.ts +174 -25
- package/src/components/settings-list.ts +264 -7
- package/src/components/spacer.ts +17 -0
- package/src/components/tab-bar.ts +42 -0
- package/src/components/table.ts +34 -0
- package/src/components/text.ts +23 -0
- package/src/components/tree-view.ts +65 -0
- package/src/components/truncated-text.ts +14 -0
- package/src/components/wizard-step.ts +18 -9
- package/src/debug-server.ts +14 -7
- package/src/hotkeys-markdown.ts +251 -69
- package/src/index.ts +6 -0
- package/src/latex-block.ts +11 -0
- package/src/native/apply.ts +275 -0
- package/src/native/backend.ts +682 -0
- package/src/native/blobs.ts +70 -0
- package/src/native/describe.ts +124 -0
- package/src/native/encode.ts +233 -0
- package/src/native/icons.ts +184 -0
- package/src/native/memo.ts +64 -0
- package/src/native/node.ts +112 -0
- package/src/native/overlay.ts +131 -0
- package/src/native/picker.ts +333 -0
- package/src/native/reconcile.ts +1063 -0
- package/src/native/settle.ts +23 -0
- package/src/native/spans.ts +308 -0
- package/src/native/state.ts +28 -0
- package/src/native/tone.ts +79 -0
- package/src/overlays/advisor-config.ts +420 -0
- package/src/overlays/agent-hub-renderer.ts +155 -18
- package/src/overlays/agent-hub.ts +1037 -44
- package/src/overlays/agent-transcript-viewer.ts +129 -0
- package/src/overlays/agents-hub.ts +688 -53
- package/src/overlays/annotation-overlay.ts +391 -52
- package/src/overlays/ask-dialog.ts +435 -24
- package/src/overlays/bordered-loader.ts +17 -0
- package/src/overlays/btw-history-panel.ts +182 -0
- package/src/overlays/btw-panel.ts +68 -2
- package/src/overlays/cleanse-panel.ts +105 -15
- package/src/overlays/codex-reset-fireworks.ts +65 -5
- package/src/overlays/composer-shape-preview.ts +26 -1
- package/src/overlays/copy-selector.ts +545 -23
- package/src/overlays/error-banner.ts +44 -0
- package/src/overlays/extensions/extension-list.ts +23 -17
- package/src/overlays/history-search.ts +175 -33
- package/src/overlays/hook-editor.ts +113 -6
- package/src/overlays/hook-input.ts +22 -1
- package/src/overlays/hook-selector.ts +311 -22
- package/src/overlays/hub-frame.ts +80 -0
- package/src/overlays/jobs-panel.ts +112 -0
- package/src/overlays/login-dialog.ts +183 -1
- package/src/overlays/logout-account-selector.ts +102 -4
- package/src/overlays/mcp-add-wizard.ts +232 -53
- package/src/overlays/model-browser.ts +681 -22
- package/src/overlays/model-hub.ts +1402 -78
- package/src/overlays/model-picker.ts +175 -1
- package/src/overlays/move-overlay.ts +45 -0
- package/src/overlays/oauth-selector.ts +227 -23
- package/src/overlays/omfg-panel.ts +86 -2
- package/src/overlays/pause-screen.ts +55 -4
- package/src/overlays/plan-review-overlay.ts +352 -0
- package/src/overlays/plan-save-overlay.ts +45 -0
- package/src/overlays/plugin-selector.ts +21 -1
- package/src/overlays/plugin-settings.ts +195 -5
- package/src/overlays/queue-mode-selector.ts +19 -1
- package/src/overlays/reset-usage-selector.ts +110 -40
- package/src/overlays/rewind-selector.ts +458 -44
- package/src/overlays/session-account-selector.ts +1 -1
- package/src/overlays/session-info-overlay.ts +137 -1
- package/src/overlays/session-selector.ts +807 -46
- package/src/overlays/settings-defs.ts +41 -0
- package/src/overlays/settings-selector.ts +583 -23
- package/src/overlays/show-images-selector.ts +18 -1
- package/src/overlays/snapcompact-shape-preview.ts +48 -3
- package/src/overlays/stats-notice.ts +31 -0
- package/src/overlays/theme-selector.ts +31 -1
- package/src/overlays/thinking-selector.ts +22 -1
- package/src/overlays/tree-selector.ts +570 -110
- package/src/overlays/usage-dashboard.ts +587 -12
- package/src/overlays/usage-row.ts +161 -25
- package/src/prompt/attachment-chips.ts +60 -0
- package/src/prompt/composer-attachments.ts +31 -9
- package/src/prompt/composer.ts +55 -2
- package/src/prompt/custom-editor.ts +302 -4
- package/src/prompt/editor-top-gap.ts +8 -0
- package/src/prompt/macos-spelling.ts +24 -9
- package/src/prompt/magic-keywords.ts +22 -1
- package/src/prompt/model-mention-autocomplete.ts +1 -0
- package/src/prompt/queued-messages.ts +101 -0
- package/src/prompt/skill-tokens.ts +5 -3
- package/src/prompt/welcome.ts +213 -6
- package/src/render/code-cell.ts +103 -2
- package/src/render/file-list.ts +29 -0
- package/src/render/hyperlink.ts +32 -0
- package/src/render/output-block.ts +110 -0
- package/src/render/output-pane.ts +37 -0
- package/src/render/tool-card.ts +137 -0
- package/src/render/tree-list.ts +39 -0
- package/src/render/width-aware-text.ts +20 -0
- package/src/setup/scenes/composer.ts +29 -0
- package/src/setup/scenes/glyph.ts +15 -0
- package/src/setup/scenes/model.ts +36 -8
- package/src/setup/scenes/outro.ts +28 -1
- package/src/setup/scenes/sign-in.ts +122 -13
- package/src/setup/scenes/splash.ts +28 -1
- package/src/setup/scenes/theme.ts +88 -3
- package/src/setup/scenes/types.ts +7 -1
- package/src/setup/startup-splash.ts +46 -9
- package/src/setup/wizard-overlay.ts +140 -23
- package/src/status-line/component.ts +398 -16
- package/src/status-line/context-usage.ts +279 -50
- package/src/status-line/footer.ts +94 -1
- package/src/status-line/metrics.ts +3 -6
- package/src/status-line/segments.ts +463 -97
- package/src/status-line/separators.ts +3 -16
- package/src/status-line/types.ts +43 -1
- package/src/terminal-capabilities.ts +7 -0
- package/src/terminal.ts +130 -2
- package/src/theme/defaults/dark-neon-noir.json +100 -0
- package/src/theme/defaults/index.ts +2 -0
- package/src/theme/defaults/light-prism.json +5 -5
- package/src/theme/defaults/onyx.json +62 -62
- package/src/theme/schema.ts +15 -0
- package/src/theme/shimmer.ts +33 -0
- package/src/theme/theme-class.ts +24 -19
- package/src/theme/theme.ts +111 -9
- package/src/tools/ask.ts +157 -1
- package/src/tools/ast-edit.ts +174 -1
- package/src/tools/ast-grep.ts +82 -2
- package/src/tools/autoresearch.ts +149 -1
- package/src/tools/bash.ts +180 -49
- package/src/tools/cfg-render.ts +66 -1
- package/src/tools/debug.ts +78 -1
- package/src/tools/default-renderer.ts +35 -1
- package/src/tools/edit.ts +247 -2
- package/src/tools/eval.ts +257 -1
- package/src/tools/fetch.ts +102 -3
- package/src/tools/find.ts +127 -1
- package/src/tools/github.ts +119 -10
- package/src/tools/glob.ts +116 -1
- package/src/tools/goal.ts +56 -1
- package/src/tools/grep.ts +83 -2
- package/src/tools/grouped-file-output.ts +205 -0
- package/src/tools/json-tree.ts +116 -1
- package/src/tools/lsp.ts +318 -1
- package/src/tools/mcp.ts +80 -1
- package/src/tools/memory.ts +93 -11
- package/src/tools/native-view.ts +292 -0
- package/src/tools/proc-render.ts +221 -1
- package/src/tools/read.ts +199 -4
- package/src/tools/renderer.ts +61 -0
- package/src/tools/report-tool-issue.ts +7 -1
- package/src/tools/resolve.ts +63 -1
- package/src/tools/task.ts +406 -4
- package/src/tools/think.ts +19 -1
- package/src/tools/todo.ts +89 -0
- package/src/tools/vibe.ts +230 -2
- package/src/tools/wait.ts +181 -1
- package/src/tools/web-search.ts +113 -1
- package/src/tools/write.ts +144 -5
- package/src/tools/xdev.ts +64 -1
- package/src/tui.ts +294 -3
|
@@ -27,7 +27,12 @@ import {
|
|
|
27
27
|
SKILL_PROMPT_MESSAGE_TYPE,
|
|
28
28
|
type SkillPromptDetails,
|
|
29
29
|
} from "./messages";
|
|
30
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
imageContent,
|
|
32
|
+
textContent,
|
|
33
|
+
type TranscriptEntryLike as TranscriptEntry,
|
|
34
|
+
transcriptEntryMessage,
|
|
35
|
+
} from "./transcript-entry";
|
|
31
36
|
import { theme } from "../theme";
|
|
32
37
|
import {
|
|
33
38
|
assistantHasVisibleContent,
|
|
@@ -54,12 +59,16 @@ import {
|
|
|
54
59
|
} from "./compaction-summary-message";
|
|
55
60
|
import { CustomMessageComponent } from "./custom-message";
|
|
56
61
|
import { EvalExecutionComponent } from "./eval-execution";
|
|
57
|
-
import {
|
|
62
|
+
import {
|
|
63
|
+
type LateDiagnosticsFile,
|
|
64
|
+
LateDiagnosticsMessageComponent,
|
|
65
|
+
routeLateDiagnostics,
|
|
66
|
+
} from "./late-diagnostics-message";
|
|
58
67
|
import { groupedReadUsageCallIds, ReadToolGroupComponent, readArgsCollapseIntoGroup } from "./read-tool-group";
|
|
59
68
|
import { SkillMessageComponent } from "./skill-message";
|
|
60
69
|
import { ToolExecutionComponent } from "./tool-execution";
|
|
61
70
|
import { TranscriptContainer } from "../chrome/transcript-container";
|
|
62
|
-
import { createUsageRowBlock, turnElapsedMs } from "../overlays/usage-row";
|
|
71
|
+
import { createUsageRowBlock, TurnUsageTally, turnElapsedMs } from "../overlays/usage-row";
|
|
63
72
|
import { CollapsedSyntheticMessageComponent, UserMessageComponent } from "./user-message";
|
|
64
73
|
|
|
65
74
|
export interface ChatTranscriptBuilderDeps {
|
|
@@ -88,6 +97,7 @@ export class ChatTranscriptBuilder {
|
|
|
88
97
|
#pendingReadUsageCallIds: string[] | undefined;
|
|
89
98
|
#pendingUsageElapsedMs: number | undefined;
|
|
90
99
|
#turnStartedAt: number | undefined;
|
|
100
|
+
readonly #turnUsage = new TurnUsageTally();
|
|
91
101
|
#lastAssistantUsage: Usage | undefined;
|
|
92
102
|
#servedModelTracker = new ServedModelTracker();
|
|
93
103
|
#waitingPoll: ToolExecutionComponent | null = null;
|
|
@@ -124,7 +134,12 @@ export class ChatTranscriptBuilder {
|
|
|
124
134
|
if (this.#readArgs.size === 0 && this.#pendingTools.size === 0) this.#flushPendingUsage();
|
|
125
135
|
}
|
|
126
136
|
|
|
127
|
-
/**
|
|
137
|
+
/**
|
|
138
|
+
* Toggle tool-output expansion across every expandable component. Cards a
|
|
139
|
+
* TSP terminal collapsed or expanded locally mirror that into their own
|
|
140
|
+
* state, so this re-applies the transcript-wide state to every one of them
|
|
141
|
+
* even when it equals the previous value.
|
|
142
|
+
*/
|
|
128
143
|
setExpanded(expanded: boolean): void {
|
|
129
144
|
this.#expanded = expanded;
|
|
130
145
|
for (const component of this.#expandables) component.setExpanded(expanded);
|
|
@@ -156,6 +171,7 @@ export class ChatTranscriptBuilder {
|
|
|
156
171
|
this.#pendingReadUsageCallIds = undefined;
|
|
157
172
|
this.#pendingUsageElapsedMs = undefined;
|
|
158
173
|
this.#turnStartedAt = undefined;
|
|
174
|
+
this.#turnUsage.reset();
|
|
159
175
|
this.#lastAssistantUsage = undefined;
|
|
160
176
|
this.#servedModelTracker = new ServedModelTracker();
|
|
161
177
|
this.#waitingPoll = null;
|
|
@@ -282,7 +298,9 @@ export class ChatTranscriptBuilder {
|
|
|
282
298
|
// agent-attributed `user` message (advisor tool-loop redirect) must not.
|
|
283
299
|
if (message.role === "user" && message.attribution !== "agent") {
|
|
284
300
|
this.#turnStartedAt = message.timestamp;
|
|
301
|
+
this.#turnUsage.reset();
|
|
285
302
|
} else if (message.role === "developer" && message.synthetic) {
|
|
303
|
+
this.#turnUsage.reset();
|
|
286
304
|
// A synthetic developer message initiates a fresh run (auto-
|
|
287
305
|
// continue, /goal, approved plan): replay must not inherit the
|
|
288
306
|
// preceding user prompt's timestamp, mirroring the live
|
|
@@ -313,6 +331,8 @@ export class ChatTranscriptBuilder {
|
|
|
313
331
|
this.container.addChild(
|
|
314
332
|
new UserMessageComponent(userText, {
|
|
315
333
|
liveSteered: message.role === "user" && message.liveSteered === true,
|
|
334
|
+
timestamp: message.timestamp,
|
|
335
|
+
images: imageContent(message.content),
|
|
316
336
|
}),
|
|
317
337
|
);
|
|
318
338
|
}
|
|
@@ -348,6 +368,7 @@ export class ChatTranscriptBuilder {
|
|
|
348
368
|
// message does.
|
|
349
369
|
if (message.role === "custom" && isUserTurnInitiator(message as CustomMessage)) {
|
|
350
370
|
this.#turnStartedAt = message.timestamp;
|
|
371
|
+
this.#turnUsage.reset();
|
|
351
372
|
}
|
|
352
373
|
this.#appendCustomMessage(message);
|
|
353
374
|
break;
|
|
@@ -398,6 +419,7 @@ export class ChatTranscriptBuilder {
|
|
|
398
419
|
this.#trackExpandable(assistantComponent);
|
|
399
420
|
assistantComponent.pickReactionTarget(this.container.children);
|
|
400
421
|
this.container.addChild(assistantComponent);
|
|
422
|
+
let lastAssistantComponent = assistantComponent;
|
|
401
423
|
|
|
402
424
|
if (displayPreferences.cacheMissMarker) {
|
|
403
425
|
const invalidation = detectCacheInvalidation(this.#lastAssistantUsage, message.usage);
|
|
@@ -433,6 +455,7 @@ export class ChatTranscriptBuilder {
|
|
|
433
455
|
component.setToolResultImagesVisible(!displayPreferences.hideToolActivity);
|
|
434
456
|
this.#trackExpandable(component);
|
|
435
457
|
this.container.addChild(component);
|
|
458
|
+
lastAssistantComponent = component;
|
|
436
459
|
};
|
|
437
460
|
|
|
438
461
|
for (const content of message.content) {
|
|
@@ -491,6 +514,8 @@ export class ChatTranscriptBuilder {
|
|
|
491
514
|
}
|
|
492
515
|
appendAssistantSegment(afterToolSegment);
|
|
493
516
|
}
|
|
517
|
+
const turnUsage = this.#turnUsage.add(message, this.#turnStartedAt);
|
|
518
|
+
if (turnUsage) lastAssistantComponent.setTurnUsage(turnUsage);
|
|
494
519
|
|
|
495
520
|
this.#pendingUsage =
|
|
496
521
|
displayPreferences.showTokenUsage && assistantUsageIsBilled(message.usage) ? message.usage : undefined;
|
|
@@ -544,7 +569,10 @@ export class ChatTranscriptBuilder {
|
|
|
544
569
|
}
|
|
545
570
|
if (message.customType === LSP_LATE_DIAGNOSTIC_MESSAGE_TYPE) {
|
|
546
571
|
const details = (message as CustomMessage<{ files?: LateDiagnosticsFile[] }>).details;
|
|
547
|
-
|
|
572
|
+
// Native: into the edit/write frames they belong to; the rest stand alone.
|
|
573
|
+
const files = routeLateDiagnostics(this.container.children, details?.files ?? []);
|
|
574
|
+
if (files.length === 0) return;
|
|
575
|
+
const component = new LateDiagnosticsMessageComponent(files);
|
|
548
576
|
this.#trackExpandable(component);
|
|
549
577
|
this.container.addChild(component);
|
|
550
578
|
return;
|
|
@@ -570,7 +598,10 @@ export class ChatTranscriptBuilder {
|
|
|
570
598
|
}
|
|
571
599
|
if (message.customType === "advisor") {
|
|
572
600
|
const details = (message as CustomMessage<AdvisorMessageDetails>).details;
|
|
573
|
-
|
|
601
|
+
const card = createAdvisorMessageCard(details, () => this.#expanded, theme);
|
|
602
|
+
// Tracked so a transcript-wide toggle also clears a per-card native toggle.
|
|
603
|
+
this.#trackExpandable(card);
|
|
604
|
+
this.container.addChild(card);
|
|
574
605
|
return;
|
|
575
606
|
}
|
|
576
607
|
if (message.customType === LAUNCH_COMPLETION_MESSAGE_TYPE) {
|
|
@@ -5,12 +5,16 @@ import { Text } from "../components/text";
|
|
|
5
5
|
import type { CollabPromptDetails } from "./messages";
|
|
6
6
|
import type { CustomMessage } from "./messages";
|
|
7
7
|
import { getMarkdownTheme, theme } from "../theme";
|
|
8
|
+
import { card, md, span } from "../native/describe";
|
|
9
|
+
import type { NativeNode } from "../native/node";
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Renders a collab guest prompt on every participant's transcript: a
|
|
11
13
|
* user-message-styled bubble prefixed with the author's name.
|
|
12
14
|
*/
|
|
13
15
|
export class CollabPromptMessageComponent extends Container {
|
|
16
|
+
readonly #native: NativeNode;
|
|
17
|
+
|
|
14
18
|
constructor(message: CustomMessage<CollabPromptDetails>) {
|
|
15
19
|
super();
|
|
16
20
|
const from = message.details?.from?.trim() || "guest";
|
|
@@ -24,11 +28,19 @@ export class CollabPromptMessageComponent extends Container {
|
|
|
24
28
|
.filter((content): content is TextContent => content.type === "text")
|
|
25
29
|
.map(content => content.text)
|
|
26
30
|
.join("");
|
|
27
|
-
const
|
|
31
|
+
const markdown = new Markdown(text, 1, 1, getMarkdownTheme(), {
|
|
28
32
|
bgColor: (value: string) => theme.bg("userMessageBg", value),
|
|
29
33
|
color: (value: string) => theme.fgOnBg("userMessageText", "userMessageBg", value),
|
|
30
34
|
});
|
|
31
|
-
|
|
32
|
-
this.addChild(
|
|
35
|
+
markdown.setIgnoreTight(true);
|
|
36
|
+
this.addChild(markdown);
|
|
37
|
+
this.#native = card({ role: "omp.user.collab", tone: "user", head: [span(`«${from}» ›`, "accent strong")] }, [
|
|
38
|
+
md(text),
|
|
39
|
+
]);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** A user-toned card headed by the guest's name, with the prompt as markdown. */
|
|
43
|
+
override describe(): NativeNode {
|
|
44
|
+
return this.#native;
|
|
33
45
|
}
|
|
34
46
|
}
|
|
@@ -3,9 +3,13 @@ import { Disclosure } from "../components/disclosure";
|
|
|
3
3
|
import { type Component } from "../tui";
|
|
4
4
|
import { Markdown } from "../components/markdown";
|
|
5
5
|
import { formatNumber } from "@oh-my-pi/pi-utils";
|
|
6
|
-
import { getMarkdownTheme, theme } from "../theme";
|
|
6
|
+
import { getMarkdownTheme, getThemeEpoch, theme } from "../theme";
|
|
7
7
|
import { expandKeyHint } from "../render/render-utils";
|
|
8
8
|
import type { BranchSummaryMessage, CompactionSummaryMessage, CustomMessage } from "./messages";
|
|
9
|
+
import type { TspSpan } from "@oh-my-pi/pi-wire";
|
|
10
|
+
import { md, node, span, text } from "../native/describe";
|
|
11
|
+
import { type NativeChild, type NativeNode, type NativeUiEvent, rootToggleExpanded } from "../native/node";
|
|
12
|
+
import { Memo } from "../native/memo";
|
|
9
13
|
|
|
10
14
|
/** Divider labels per compaction method; unknown/legacy methods fall back to "compacted". */
|
|
11
15
|
const COMPACTION_METHOD_LABELS: Record<string, string> = {
|
|
@@ -24,7 +28,13 @@ function compactionAmount(message: CompactionSummaryMessage): string | undefined
|
|
|
24
28
|
|
|
25
29
|
interface SummaryDividerOptions {
|
|
26
30
|
label: () => string;
|
|
31
|
+
/** Themed spans of the label for native terminals. */
|
|
32
|
+
nativeLabel: () => TspSpan[];
|
|
27
33
|
detailMarkdown: () => string;
|
|
34
|
+
/** Native body when it differs from the markdown detail. */
|
|
35
|
+
nativeDetail?: () => NativeChild[];
|
|
36
|
+
/** Semantic role of the native section. */
|
|
37
|
+
role: string;
|
|
28
38
|
}
|
|
29
39
|
|
|
30
40
|
/**
|
|
@@ -83,6 +93,8 @@ class SummaryMessageComponent implements Component {
|
|
|
83
93
|
#disclosure: Disclosure;
|
|
84
94
|
#ignoreTight: boolean | undefined;
|
|
85
95
|
#disposed = false;
|
|
96
|
+
#expanded = false;
|
|
97
|
+
readonly #native = new Memo();
|
|
86
98
|
|
|
87
99
|
readonly #options: SummaryDividerOptions;
|
|
88
100
|
|
|
@@ -92,9 +104,35 @@ class SummaryMessageComponent implements Component {
|
|
|
92
104
|
}
|
|
93
105
|
|
|
94
106
|
setExpanded(expanded: boolean): void {
|
|
107
|
+
this.#expanded = expanded;
|
|
95
108
|
this.#disclosure.setExpanded(expanded);
|
|
96
109
|
}
|
|
97
110
|
|
|
111
|
+
/**
|
|
112
|
+
* A collapsible `section` headed by the divider label, with the summary
|
|
113
|
+
* markdown as its body; expanding is terminal-local and mirrored back
|
|
114
|
+
* through {@link handleNativeEvent}.
|
|
115
|
+
*/
|
|
116
|
+
describe(): NativeNode {
|
|
117
|
+
return this.#native.get([this.#expanded, getThemeEpoch()], () =>
|
|
118
|
+
node(
|
|
119
|
+
"section",
|
|
120
|
+
{
|
|
121
|
+
role: this.#options.role,
|
|
122
|
+
head: this.#options.nativeLabel(),
|
|
123
|
+
collapsible: true,
|
|
124
|
+
collapsed: !this.#expanded,
|
|
125
|
+
},
|
|
126
|
+
this.#options.nativeDetail?.() ?? [md(this.#options.detailMarkdown())],
|
|
127
|
+
),
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
handleNativeEvent(event: NativeUiEvent): void {
|
|
132
|
+
const expanded = rootToggleExpanded(event);
|
|
133
|
+
if (expanded !== undefined) this.setExpanded(expanded);
|
|
134
|
+
}
|
|
135
|
+
|
|
98
136
|
setIgnoreTight(ignore: boolean): this {
|
|
99
137
|
if (this.#disposed || this.#ignoreTight === ignore) return this;
|
|
100
138
|
this.#ignoreTight = ignore;
|
|
@@ -160,11 +198,42 @@ export class CompactionSummaryMessageComponent extends SummaryMessageComponent {
|
|
|
160
198
|
// A dead-end warning stamped by the progress guard badges the bar;
|
|
161
199
|
// the full text lives in the ctrl+o detail block below.
|
|
162
200
|
label: () => compactionLabel(message),
|
|
201
|
+
nativeLabel: () => compactionNativeLabel(message),
|
|
202
|
+
nativeDetail: () => compactionNativeDetail(message),
|
|
163
203
|
detailMarkdown: () => compactionDetailMarkdown(message),
|
|
204
|
+
role: "omp.compaction",
|
|
164
205
|
});
|
|
165
206
|
}
|
|
166
207
|
}
|
|
167
208
|
|
|
209
|
+
/** The divider chip: `Soft-compacted · 19K → 6.9K tokens`, the arrow dimmed. */
|
|
210
|
+
function compactionNativeLabel(message: CompactionSummaryMessage): TspSpan[] {
|
|
211
|
+
const name = (message.method && COMPACTION_METHOD_LABELS[message.method]) || "compacted";
|
|
212
|
+
const spans = [span(`${name[0]!.toUpperCase()}${name.slice(1)}`, "muted")];
|
|
213
|
+
if (message.tokensAfter !== undefined && message.tokensBefore > 0) {
|
|
214
|
+
spans.push(
|
|
215
|
+
span(` · ${formatNumber(message.tokensBefore)}`, "muted mono"),
|
|
216
|
+
span(" → ", "dim"),
|
|
217
|
+
span(`${formatNumber(message.tokensAfter)} tokens`, "muted mono"),
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
if (message.warning) spans.push(span(` ${theme.icon.warning}`, "warning"));
|
|
221
|
+
return spans;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/** The expanded divider: a caption, the warning if any, then the summary itself (the chip already has the amounts). */
|
|
225
|
+
function compactionNativeDetail(message: CompactionSummaryMessage): NativeChild[] {
|
|
226
|
+
const frames = message.images?.length ?? 0;
|
|
227
|
+
const caption =
|
|
228
|
+
frames > 0
|
|
229
|
+
? `Summary · ${frames} snapcompact frame${frames === 1 ? "" : "s"} attached`
|
|
230
|
+
: "Summary of the earlier conversation";
|
|
231
|
+
const detail: NativeChild[] = [text([span(caption, "dim")], { role: "omp.compaction.caption", key: "caption" })];
|
|
232
|
+
if (message.warning) detail.push(text([span(message.warning, "warning")], { wrap: "word", key: "warning" }));
|
|
233
|
+
detail.push(md(message.summary, { key: "summary" }));
|
|
234
|
+
return detail;
|
|
235
|
+
}
|
|
236
|
+
|
|
168
237
|
function compactionLabel(message: CompactionSummaryMessage): string {
|
|
169
238
|
const name = (message.method && COMPACTION_METHOD_LABELS[message.method]) || "compacted";
|
|
170
239
|
let label = `${theme.icon.camera} ${name}`;
|
|
@@ -199,6 +268,8 @@ export class HandoffSummaryMessageComponent extends SummaryMessageComponent {
|
|
|
199
268
|
constructor(message: CustomMessage<unknown>) {
|
|
200
269
|
super({
|
|
201
270
|
label: () => `${theme.icon.context} handed-off`,
|
|
271
|
+
nativeLabel: () => [span("Handed off", "muted")],
|
|
272
|
+
role: "omp.handoff",
|
|
202
273
|
detailMarkdown: () => {
|
|
203
274
|
const document = extractHandoffDocument(getCustomMessageText(message));
|
|
204
275
|
return `**Handoff context**\n\n${document || "_No handoff content._"}`;
|
|
@@ -226,6 +297,8 @@ export class BranchSummaryMessageComponent extends SummaryMessageComponent {
|
|
|
226
297
|
constructor(message: BranchSummaryMessage) {
|
|
227
298
|
super({
|
|
228
299
|
label: () => `${theme.icon.branch} branch`,
|
|
300
|
+
nativeLabel: () => [span("Branch summarized", "muted")],
|
|
301
|
+
role: "omp.branch",
|
|
229
302
|
detailMarkdown: () => `**Branch summary**\n\n${message.summary}`,
|
|
230
303
|
});
|
|
231
304
|
}
|
|
@@ -10,11 +10,13 @@ import { type CustomMessage, LIVE_DELEGATION_MESSAGE_TYPE } from "./messages";
|
|
|
10
10
|
export class CustomMessageComponent extends FramedMessageComponent<CustomMessage<unknown>> {
|
|
11
11
|
constructor(message: CustomMessage<unknown>, customRenderer?: MessageRenderer) {
|
|
12
12
|
const isLiveDelegation = message.customType === LIVE_DELEGATION_MESSAGE_TYPE;
|
|
13
|
+
const isHook = String(message.role) === "hookMessage";
|
|
13
14
|
super({
|
|
14
15
|
message,
|
|
16
|
+
role: isHook ? "omp.hook" : isLiveDelegation ? "omp.custom.delegation" : "omp.custom",
|
|
15
17
|
// The transcript dispatch routes both `custom` and legacy `hookMessage` roles here:
|
|
16
18
|
// tag hooks with the hook glyph, other injected messages with a neutral package.
|
|
17
|
-
icon: () => (
|
|
19
|
+
icon: () => (isHook ? theme.icon.extensionHook : theme.icon.package),
|
|
18
20
|
hideHeader: isLiveDelegation,
|
|
19
21
|
borderColor: isLiveDelegation ? "borderAccent" : undefined,
|
|
20
22
|
customRenderer,
|
|
@@ -15,11 +15,16 @@ import {
|
|
|
15
15
|
buildExecutionFrame,
|
|
16
16
|
buildStatusFooter,
|
|
17
17
|
clampDisplayLine,
|
|
18
|
+
describeExecutionCard,
|
|
19
|
+
describeExecutionTool,
|
|
18
20
|
type ExecutionColorKey,
|
|
19
21
|
type ExecutionStatus,
|
|
20
22
|
PREVIEW_LINES,
|
|
21
23
|
resolveExecutionStatus,
|
|
22
24
|
} from "./execution-shared";
|
|
25
|
+
import { code, span } from "../native/describe";
|
|
26
|
+
import { type DescribeContext, type NativeNode, type NativeUiEvent, rootToggleExpanded } from "../native/node";
|
|
27
|
+
import { Memo } from "../native/memo";
|
|
23
28
|
|
|
24
29
|
export type EvalExecutionLanguage = "python" | "js";
|
|
25
30
|
|
|
@@ -40,6 +45,11 @@ export class EvalExecutionComponent extends Container {
|
|
|
40
45
|
readonly #code: string;
|
|
41
46
|
readonly #excludeFromContext: boolean;
|
|
42
47
|
readonly #language: EvalExecutionLanguage;
|
|
48
|
+
readonly #startedAt = performance.now();
|
|
49
|
+
#endedAt: number | undefined;
|
|
50
|
+
// Bumped whenever the output pane's text changes.
|
|
51
|
+
#outputVersion = 0;
|
|
52
|
+
readonly #native = new Memo();
|
|
43
53
|
|
|
44
54
|
#highlightLang(): "python" | "javascript" {
|
|
45
55
|
return this.#language === "js" ? "javascript" : "python";
|
|
@@ -107,9 +117,54 @@ export class EvalExecutionComponent extends Container {
|
|
|
107
117
|
this.#updateDisplay();
|
|
108
118
|
}
|
|
109
119
|
|
|
120
|
+
handleNativeEvent(event: NativeUiEvent): void {
|
|
121
|
+
const expanded = rootToggleExpanded(event);
|
|
122
|
+
if (expanded !== undefined) this.setExpanded(expanded);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* The agent's eval `tool` frame (role `omp.eval`) with a `you` badge: the
|
|
127
|
+
* cell source in the head, its output as an `ansi` mini terminal. Terminals
|
|
128
|
+
* without the `tool` kind get a `card` with the cell as `code` over the output.
|
|
129
|
+
*/
|
|
130
|
+
override describe(cx?: DescribeContext): NativeNode {
|
|
131
|
+
const dataFirst = cx?.supports("tool") === true;
|
|
132
|
+
const key = [dataFirst, this.#outputVersion, this.#status, this.#expanded];
|
|
133
|
+
return this.#native.get(key, () => {
|
|
134
|
+
const title = this.#language === "js" ? "JavaScript" : "Python";
|
|
135
|
+
const common = {
|
|
136
|
+
role: "omp.eval",
|
|
137
|
+
status: this.#status,
|
|
138
|
+
startedAt: this.#startedAt,
|
|
139
|
+
expanded: this.#expanded,
|
|
140
|
+
output: this.#outputPane.getText(),
|
|
141
|
+
exitCode: this.#exitCode,
|
|
142
|
+
truncation: this.#truncation,
|
|
143
|
+
artifactError: this.#artifactError,
|
|
144
|
+
};
|
|
145
|
+
return dataFirst
|
|
146
|
+
? describeExecutionTool({
|
|
147
|
+
...common,
|
|
148
|
+
name: "eval",
|
|
149
|
+
title,
|
|
150
|
+
command: this.#code,
|
|
151
|
+
lang: this.#highlightLang(),
|
|
152
|
+
excluded: this.#excludeFromContext,
|
|
153
|
+
endedAt: this.#endedAt,
|
|
154
|
+
})
|
|
155
|
+
: describeExecutionCard({
|
|
156
|
+
...common,
|
|
157
|
+
head: [span(title, `${this.#excludeFromContext ? "dim" : "pythonMode"} strong`)],
|
|
158
|
+
muted: this.#excludeFromContext,
|
|
159
|
+
lead: [code(this.#code, { lang: this.#highlightLang(), key: "code" })],
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
110
164
|
appendOutput(chunk: string): void {
|
|
111
165
|
// Chunk is pre-sanitized by OutputSink.push() — no need to sanitize again.
|
|
112
166
|
this.#outputPane.append(chunk);
|
|
167
|
+
this.#outputVersion++;
|
|
113
168
|
this.#updateDisplay();
|
|
114
169
|
}
|
|
115
170
|
|
|
@@ -120,12 +175,14 @@ export class EvalExecutionComponent extends Container {
|
|
|
120
175
|
): void {
|
|
121
176
|
this.#exitCode = exitCode;
|
|
122
177
|
this.#status = resolveExecutionStatus(exitCode, cancelled);
|
|
178
|
+
this.#endedAt ??= performance.now();
|
|
123
179
|
this.#truncation = options?.truncation;
|
|
124
180
|
this.#artifactError = options?.artifactError;
|
|
125
181
|
this.#outputPane.finish();
|
|
126
182
|
if (options?.output !== undefined) {
|
|
127
183
|
this.#setOutput(options.output);
|
|
128
184
|
}
|
|
185
|
+
this.#outputVersion++;
|
|
129
186
|
|
|
130
187
|
this.#loader.stop();
|
|
131
188
|
this.#updateDisplay();
|
|
@@ -16,7 +16,10 @@ import { formatArtifactErrorNotice, formatTruncationMetaNotice, type TruncationM
|
|
|
16
16
|
import { DynamicBorder } from "../chrome/dynamic-border";
|
|
17
17
|
import { Ellipsis, truncateToWidth, visibleWidth } from "../utils";
|
|
18
18
|
import { interruptKey } from "../chrome/keybinding-hints";
|
|
19
|
-
import { expandKeyHint } from "../render/render-utils";
|
|
19
|
+
import { DEFAULT_TERMINAL_PREVIEW_LINES, expandKeyHint } from "../render/render-utils";
|
|
20
|
+
import type { TspCardStatus, TspSpan, TspText, TspTone } from "@oh-my-pi/pi-wire";
|
|
21
|
+
import { card, node, span, text } from "../native/describe";
|
|
22
|
+
import type { NativeChild, NativeNode } from "../native/node";
|
|
20
23
|
|
|
21
24
|
/** Output rows shown while an execution is collapsed. */
|
|
22
25
|
export const PREVIEW_LINES = 20;
|
|
@@ -104,6 +107,155 @@ export function buildStatusFooter(opts: {
|
|
|
104
107
|
return new Text(`\n${parts.join("\n")}`, 1, 0);
|
|
105
108
|
}
|
|
106
109
|
|
|
110
|
+
const EXECUTION_CARD_STATUS: Record<ExecutionStatus, TspCardStatus> = {
|
|
111
|
+
running: "running",
|
|
112
|
+
complete: "done",
|
|
113
|
+
cancelled: "cancelled",
|
|
114
|
+
error: "error",
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/** Inputs for {@link describeExecutionCard}. */
|
|
118
|
+
export interface ExecutionCardInput {
|
|
119
|
+
readonly role: string;
|
|
120
|
+
readonly head: TspText;
|
|
121
|
+
/** Excluded from context (`!!`/`$$`): a muted card. */
|
|
122
|
+
readonly muted: boolean;
|
|
123
|
+
readonly status: ExecutionStatus;
|
|
124
|
+
/** `performance.now()` when the run started; drives the live elapsed timer. */
|
|
125
|
+
readonly startedAt: number;
|
|
126
|
+
readonly expanded: boolean;
|
|
127
|
+
/** Body nodes before the output (the eval cell's code). */
|
|
128
|
+
readonly lead?: readonly NativeChild[];
|
|
129
|
+
/** Raw terminal output. */
|
|
130
|
+
readonly output: string;
|
|
131
|
+
readonly images?: readonly NativeChild[];
|
|
132
|
+
readonly exitCode: number | undefined;
|
|
133
|
+
readonly truncation: TruncationMeta | undefined;
|
|
134
|
+
readonly artifactError?: OutputArtifactError;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Native card shared by user bash/eval runs: the head with a live `elapsed`
|
|
139
|
+
* while running, the output as an `ansi` mini terminal that follows its tail
|
|
140
|
+
* while running, a cancel hint spinner, then exit/truncation notes. The
|
|
141
|
+
* terminal clamps the collapsed body and owns the "N more lines" affordance.
|
|
142
|
+
*/
|
|
143
|
+
export function describeExecutionCard(input: ExecutionCardInput): NativeNode {
|
|
144
|
+
const running = input.status === "running";
|
|
145
|
+
const headChildren: NativeChild[] = [text(input.head, { lines: 1, grow: 1 })];
|
|
146
|
+
if (running) {
|
|
147
|
+
headChildren.push(node("elapsed", { age: Math.max(0, Math.round(performance.now() - input.startedAt)) }));
|
|
148
|
+
}
|
|
149
|
+
const children: NativeChild[] = [
|
|
150
|
+
node("row", { gap: "sm", align: "baseline" }, headChildren, "head"),
|
|
151
|
+
...(input.lead ?? []),
|
|
152
|
+
];
|
|
153
|
+
if (input.output) {
|
|
154
|
+
children.push(
|
|
155
|
+
node("ansi", { text: input.output, follow: running, preview: { lines: PREVIEW_LINES } }, undefined, "output"),
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
if (input.images) children.push(...input.images);
|
|
159
|
+
if (running) {
|
|
160
|
+
children.push(
|
|
161
|
+
node("spinner", { label: [span(`Running… (${interruptKey()} to cancel)`, "muted")] }, undefined, "running"),
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
const notes: TspSpan[] = [];
|
|
165
|
+
const note = (value: string, token: string): void => {
|
|
166
|
+
if (notes.length > 0) notes.push(span("\n"));
|
|
167
|
+
notes.push(span(value, token));
|
|
168
|
+
};
|
|
169
|
+
if (input.status === "cancelled") note("(cancelled)", "warning");
|
|
170
|
+
else if (input.status === "error") note(`(exit ${input.exitCode})`, "error");
|
|
171
|
+
if (input.truncation) note(formatTruncationMetaNotice(input.truncation), "warning");
|
|
172
|
+
if (input.artifactError) note(formatArtifactErrorNotice(input.artifactError), "warning");
|
|
173
|
+
if (notes.length > 0) children.push(text(notes, { wrap: "word", key: "notes" }));
|
|
174
|
+
return card(
|
|
175
|
+
{
|
|
176
|
+
role: input.role,
|
|
177
|
+
tone: input.muted ? "muted" : undefined,
|
|
178
|
+
status: EXECUTION_CARD_STATUS[input.status],
|
|
179
|
+
collapsible: true,
|
|
180
|
+
collapsed: !input.expanded,
|
|
181
|
+
preview: { lines: PREVIEW_LINES },
|
|
182
|
+
},
|
|
183
|
+
children,
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** Inputs for {@link describeExecutionTool}. */
|
|
188
|
+
export interface ExecutionToolInput {
|
|
189
|
+
readonly role: string;
|
|
190
|
+
/** Tool name for the head icon (`bash`, `eval`). */
|
|
191
|
+
readonly name: string;
|
|
192
|
+
readonly title: string;
|
|
193
|
+
/** The command / cell source, shown once in the head. */
|
|
194
|
+
readonly command: string;
|
|
195
|
+
readonly lang: string;
|
|
196
|
+
/** Excluded from context (`!!`/`$$`). */
|
|
197
|
+
readonly excluded: boolean;
|
|
198
|
+
readonly status: ExecutionStatus;
|
|
199
|
+
/** `performance.now()` when the run started / ended. */
|
|
200
|
+
readonly startedAt: number;
|
|
201
|
+
readonly endedAt: number | undefined;
|
|
202
|
+
readonly expanded: boolean;
|
|
203
|
+
/** Raw terminal output. */
|
|
204
|
+
readonly output: string;
|
|
205
|
+
readonly images?: readonly NativeChild[];
|
|
206
|
+
readonly exitCode: number | undefined;
|
|
207
|
+
readonly truncation: TruncationMeta | undefined;
|
|
208
|
+
readonly artifactError?: OutputArtifactError;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* A user `!`/`$` run as the agent's `tool` frame (§6.6): the command in the
|
|
213
|
+
* head with a `you` badge (plus `not sent` when excluded from context), the
|
|
214
|
+
* timer, exit chip and cancelled note; the body is the output as an `ansi`
|
|
215
|
+
* mini terminal following its tail, then one quiet truncation line.
|
|
216
|
+
*/
|
|
217
|
+
export function describeExecutionTool(input: ExecutionToolInput): NativeNode {
|
|
218
|
+
const running = input.status === "running";
|
|
219
|
+
const body: NativeChild[] = [];
|
|
220
|
+
if (input.output) body.push(node("ansi", { text: input.output, follow: running }, undefined, "output"));
|
|
221
|
+
if (input.images) body.push(...input.images);
|
|
222
|
+
const notes: string[] = [];
|
|
223
|
+
if (input.truncation) notes.push(formatTruncationMetaNotice(input.truncation));
|
|
224
|
+
if (input.artifactError) notes.push(formatArtifactErrorNotice(input.artifactError));
|
|
225
|
+
if (notes.length > 0) {
|
|
226
|
+
body.push({
|
|
227
|
+
...text([span(notes.join(" · "), "muted")], { wrap: "word", role: "omp.tool.notice" }),
|
|
228
|
+
key: "foot",
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
const ms = Math.max(0, Math.round((input.endedAt ?? performance.now()) - input.startedAt));
|
|
232
|
+
const badges: { text: string; tone?: TspTone; title?: string }[] = [{ text: "you", tone: "user" }];
|
|
233
|
+
if (input.excluded) badges.push({ text: "not sent", title: "Not sent to the model", tone: "muted" });
|
|
234
|
+
const hasBody = body.length > 0;
|
|
235
|
+
return node(
|
|
236
|
+
"tool",
|
|
237
|
+
{
|
|
238
|
+
role: input.role,
|
|
239
|
+
name: input.name,
|
|
240
|
+
title: input.title,
|
|
241
|
+
target: input.command,
|
|
242
|
+
targetKind: "command",
|
|
243
|
+
lang: input.lang,
|
|
244
|
+
badges,
|
|
245
|
+
status: EXECUTION_CARD_STATUS[input.status],
|
|
246
|
+
age: running ? ms : undefined,
|
|
247
|
+
took: running ? undefined : ms,
|
|
248
|
+
exit: input.status === "error" ? input.exitCode : undefined,
|
|
249
|
+
note: input.status === "cancelled" ? "cancelled" : undefined,
|
|
250
|
+
frame: "card",
|
|
251
|
+
collapsible: hasBody,
|
|
252
|
+
collapsed: hasBody ? !input.expanded : undefined,
|
|
253
|
+
preview: hasBody ? { tail: DEFAULT_TERMINAL_PREVIEW_LINES } : undefined,
|
|
254
|
+
},
|
|
255
|
+
body,
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
107
259
|
/**
|
|
108
260
|
* Derive the post-run status from an exit code + cancellation flag using the
|
|
109
261
|
* same precedence both execution components apply.
|
package/src/chat/hook-message.ts
CHANGED
|
@@ -13,6 +13,7 @@ export class HookMessageComponent extends FramedMessageComponent<HookMessage<unk
|
|
|
13
13
|
constructor(message: HookMessage<unknown>, customRenderer?: HookMessageRenderer) {
|
|
14
14
|
super({
|
|
15
15
|
message,
|
|
16
|
+
role: "omp.hook",
|
|
16
17
|
collapseAfterLines: HOOK_COLLAPSED_LINES,
|
|
17
18
|
customRenderer,
|
|
18
19
|
});
|