@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
package/src/tools/ast-grep.ts
CHANGED
|
@@ -12,9 +12,13 @@ import {
|
|
|
12
12
|
PREVIEW_LIMITS,
|
|
13
13
|
toPathList,
|
|
14
14
|
} from "../render/render-utils";
|
|
15
|
-
import { classifyGroupedLines, groupLineIndicesByBlank } from "./grouped-file-output";
|
|
15
|
+
import { classifyGroupedLines, describeGroupedOutput, groupLineIndicesByBlank } from "./grouped-file-output";
|
|
16
|
+
import { getLanguageFromPath } from "../lang-from-path";
|
|
17
|
+
import { code, compact, node, span } from "../native/describe";
|
|
18
|
+
import type { NativeChild } from "../native/node";
|
|
19
|
+
import { errorText, noteText, resultText, toolHead } from "./native-view";
|
|
16
20
|
import type { OutputMeta } from "./output-meta";
|
|
17
|
-
import type { RenderResultOptions, ToolRenderer } from "./renderer";
|
|
21
|
+
import type { NativeToolView, RenderResultOptions, ToolRenderer } from "./renderer";
|
|
18
22
|
|
|
19
23
|
/** Display metadata returned by ast-grep. */
|
|
20
24
|
export interface AstGrepToolDetails {
|
|
@@ -167,5 +171,81 @@ export const astGrepToolRenderer = {
|
|
|
167
171
|
},
|
|
168
172
|
);
|
|
169
173
|
},
|
|
174
|
+
describeCall(args: AstGrepRenderArgs): NativeToolView {
|
|
175
|
+
const meta: string[] = [];
|
|
176
|
+
const scopePaths = toPathList(args.path ?? args.paths);
|
|
177
|
+
if (scopePaths.length) meta.push(`in ${scopePaths.join(", ")}`);
|
|
178
|
+
if (args.skip !== undefined && args.skip > 0) meta.push(`skip:${args.skip}`);
|
|
179
|
+
return { head: toolHead("AST Grep", span(args.pat ?? "?", "code"), ...meta) };
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
describeResult(
|
|
183
|
+
result: { content: Array<{ type: string; text?: string }>; details?: AstGrepToolDetails; isError?: boolean },
|
|
184
|
+
_options: RenderResultOptions,
|
|
185
|
+
args?: AstGrepRenderArgs,
|
|
186
|
+
): NativeToolView {
|
|
187
|
+
const details = result.details;
|
|
188
|
+
const pattern = span(args?.pat ?? "?", "code");
|
|
189
|
+
if (result.isError) {
|
|
190
|
+
return {
|
|
191
|
+
head: toolHead("AST Grep", pattern),
|
|
192
|
+
tone: "error",
|
|
193
|
+
body: [errorText(resultText(result) || "Unknown error")],
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
const matchCount = details?.matchCount ?? 0;
|
|
197
|
+
const filesSearched = details?.filesSearched ?? 0;
|
|
198
|
+
const limitReached = details?.limitReached ?? false;
|
|
199
|
+
const parseErrors = details?.parseErrors ?? [];
|
|
200
|
+
const parseNote =
|
|
201
|
+
parseErrors.length > 0
|
|
202
|
+
? node(
|
|
203
|
+
"section",
|
|
204
|
+
{
|
|
205
|
+
head: [span(formatParseErrorsCountLabel(parseErrors, details?.parseErrorsTotal), "warning")],
|
|
206
|
+
collapsible: true,
|
|
207
|
+
collapsed: true,
|
|
208
|
+
},
|
|
209
|
+
[code(parseErrors.join("\n"))],
|
|
210
|
+
"parse-errors",
|
|
211
|
+
)
|
|
212
|
+
: undefined;
|
|
213
|
+
if (matchCount === 0) {
|
|
214
|
+
const meta = ["0 matches"];
|
|
215
|
+
if (details?.scopePath) meta.push(`in ${details.scopePath}`);
|
|
216
|
+
if (filesSearched > 0) meta.push(`searched ${filesSearched}`);
|
|
217
|
+
return {
|
|
218
|
+
head: toolHead("AST Grep", pattern, ...meta),
|
|
219
|
+
tone: "warning",
|
|
220
|
+
body: compact<NativeChild>([
|
|
221
|
+
noteText("No matches found"),
|
|
222
|
+
parseErrors.length > 0 &&
|
|
223
|
+
noteText("Query may be mis-scoped; narrow `path` before concluding absence", "warning"),
|
|
224
|
+
parseNote,
|
|
225
|
+
]),
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
const meta = [formatCount("match", matchCount), formatCount("file", details?.fileCount ?? 0)];
|
|
229
|
+
if (details?.scopePath) meta.push(`in ${details.scopePath}`);
|
|
230
|
+
meta.push(`searched ${filesSearched}`);
|
|
231
|
+
const head = toolHead("AST Grep", pattern, ...meta);
|
|
232
|
+
if (limitReached) head.push(span(" limit reached", "warning"));
|
|
233
|
+
const allLines = (details?.displayContent ?? resultText(result)).split("\n");
|
|
234
|
+
const kept = groupLineIndicesByBlank(allLines)
|
|
235
|
+
.filter(indices => {
|
|
236
|
+
const first = allLines[indices[0]!]!;
|
|
237
|
+
return !first.startsWith("Result limit reached") && !first.startsWith("Parse issues:");
|
|
238
|
+
})
|
|
239
|
+
.flatMap(indices => [...indices.map(index => allLines[index]!), ""]);
|
|
240
|
+
return {
|
|
241
|
+
head,
|
|
242
|
+
body: compact<NativeChild>([
|
|
243
|
+
...describeGroupedOutput(kept, { lang: getLanguageFromPath }),
|
|
244
|
+
limitReached && noteText("limit reached; narrow path or increase limit", "warning"),
|
|
245
|
+
parseNote,
|
|
246
|
+
]),
|
|
247
|
+
preview: { lines: COLLAPSED_MATCH_LIMIT },
|
|
248
|
+
};
|
|
249
|
+
},
|
|
170
250
|
mergeCallAndResult: true,
|
|
171
251
|
} satisfies ToolRenderer<AstGrepRenderArgs, AstGrepToolDetails>;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { Text } from "../components/text";
|
|
2
2
|
import type { Theme } from "../theme/theme";
|
|
3
3
|
import { replaceTabs, truncateToWidth, shortenPath } from "../render/render-utils";
|
|
4
|
-
import type {
|
|
4
|
+
import type { TspTone } from "@oh-my-pi/pi-wire";
|
|
5
|
+
import { ansi, compact, kv, node, row, span, text } from "../native/describe";
|
|
6
|
+
import type { NativeNode } from "../native/node";
|
|
7
|
+
import { OwnerMemo } from "../native/memo";
|
|
8
|
+
import { plainText } from "../native/spans";
|
|
9
|
+
import { errorView, resultText, toolHead } from "./native-view";
|
|
10
|
+
import type { NativeToolView, ToolRenderer, ToolRenderResult } from "./renderer";
|
|
5
11
|
import type { TruncationResult } from "./streaming-output";
|
|
6
12
|
|
|
7
13
|
/** Whether a lower or higher metric is better. */
|
|
@@ -155,6 +161,35 @@ export interface InitExperimentDetails {
|
|
|
155
161
|
baselineCommit: string | null;
|
|
156
162
|
}
|
|
157
163
|
|
|
164
|
+
/** Tone of an experiment disposition: kept succeeds, discarded warns, the rest fail. */
|
|
165
|
+
function experimentTone(status: ExperimentStatus): TspTone {
|
|
166
|
+
return status === "keep" ? "success" : status === "discard" ? "warning" : "error";
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** Plain first line of a free-form argument, for single-line heads. */
|
|
170
|
+
function firstLine(value: string | undefined): string {
|
|
171
|
+
return (
|
|
172
|
+
plainText(value ?? "")
|
|
173
|
+
.trim()
|
|
174
|
+
.split("\n")[0] ?? ""
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Result text as a wrapped body, or an error card. */
|
|
179
|
+
function describeTextResult(
|
|
180
|
+
title: string,
|
|
181
|
+
result: ToolRenderResult<unknown>,
|
|
182
|
+
style?: string,
|
|
183
|
+
): NativeToolView | undefined {
|
|
184
|
+
const output = resultText(result);
|
|
185
|
+
if (result.isError) return errorView(title, output);
|
|
186
|
+
const body = plainText(output).trimEnd();
|
|
187
|
+
return body ? { body: [text(style ? [span(body, style)] : body, { wrap: "word" })] } : undefined;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const logResultMemo = new OwnerMemo<NativeToolView | undefined>();
|
|
191
|
+
const runResultMemo = new OwnerMemo<NativeToolView | undefined>();
|
|
192
|
+
|
|
158
193
|
function renderInitCall(name: string, theme: Theme): string {
|
|
159
194
|
return `${theme.fg("toolTitle", theme.bold("init_experiment"))} ${theme.fg("accent", truncateToWidth(replaceTabs(name), 100))}`;
|
|
160
195
|
}
|
|
@@ -168,8 +203,42 @@ export const initExperimentToolRenderer = {
|
|
|
168
203
|
const text = replaceTabs(result.content.find(part => part.type === "text")?.text ?? "");
|
|
169
204
|
return new Text(text, 0, 0);
|
|
170
205
|
},
|
|
206
|
+
describeCall(args): NativeToolView {
|
|
207
|
+
return { head: toolHead("init_experiment", span(firstLine(args.name), "accent")) };
|
|
208
|
+
},
|
|
209
|
+
describeResult(result): NativeToolView | undefined {
|
|
210
|
+
return describeTextResult("init_experiment", result);
|
|
211
|
+
},
|
|
171
212
|
} satisfies ToolRenderer<{ name: string }, InitExperimentDetails>;
|
|
172
213
|
|
|
214
|
+
/** Native log summary: disposition badge, description, and metric/baseline grid. */
|
|
215
|
+
function describeSummary(details: LogDetails): NativeToolView {
|
|
216
|
+
const { experiment, state } = details;
|
|
217
|
+
const tone = experimentTone(experiment.status);
|
|
218
|
+
const deviations = details.scopeDeviations.length;
|
|
219
|
+
return {
|
|
220
|
+
tone,
|
|
221
|
+
body: compact([
|
|
222
|
+
row(
|
|
223
|
+
[
|
|
224
|
+
node("badge", { text: experiment.status.toUpperCase(), tone }),
|
|
225
|
+
text([span(plainText(experiment.description), "muted")], { wrap: "word", grow: 1 }),
|
|
226
|
+
],
|
|
227
|
+
{ gap: "sm" },
|
|
228
|
+
),
|
|
229
|
+
kv([
|
|
230
|
+
[plainText(state.metricName), [span(formatNum(experiment.metric, state.metricUnit), "accent num")]],
|
|
231
|
+
[
|
|
232
|
+
"baseline",
|
|
233
|
+
state.bestMetric !== null ? [span(formatNum(state.bestMetric, state.metricUnit), "num")] : undefined,
|
|
234
|
+
],
|
|
235
|
+
["confidence", state.confidence !== null ? [span(`${state.confidence.toFixed(1)}x`, "num")] : undefined],
|
|
236
|
+
["deviations", deviations > 0 ? [span(String(deviations), "warning")] : undefined],
|
|
237
|
+
]),
|
|
238
|
+
]),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
173
242
|
function renderSummary(details: LogDetails, theme: Theme): string {
|
|
174
243
|
const { experiment, state } = details;
|
|
175
244
|
const color = experiment.status === "keep" ? "success" : experiment.status === "discard" ? "warning" : "error";
|
|
@@ -205,8 +274,46 @@ export const logExperimentToolRenderer = {
|
|
|
205
274
|
}
|
|
206
275
|
return new Text(renderSummary(details, theme), 0, 0);
|
|
207
276
|
},
|
|
277
|
+
describeCall(args): NativeToolView {
|
|
278
|
+
return {
|
|
279
|
+
head: toolHead(
|
|
280
|
+
"log_experiment",
|
|
281
|
+
args.status ? span(args.status, experimentTone(args.status)) : undefined,
|
|
282
|
+
span(firstLine(args.description), "muted"),
|
|
283
|
+
),
|
|
284
|
+
};
|
|
285
|
+
},
|
|
286
|
+
describeResult(result): NativeToolView | undefined {
|
|
287
|
+
return logResultMemo.get(result, [], () => {
|
|
288
|
+
const details = result.details;
|
|
289
|
+
if (result.isError || !details) return describeTextResult("log_experiment", result);
|
|
290
|
+
return describeSummary(details);
|
|
291
|
+
});
|
|
292
|
+
},
|
|
208
293
|
} satisfies ToolRenderer<{ status: ExperimentStatus; description: string }, LogDetails>;
|
|
209
294
|
|
|
295
|
+
/** Native run status: TIMEOUT/FAIL/PASS badge with duration and primary metric. */
|
|
296
|
+
function describeStatus(details: RunDetails): { tone: TspTone; node: NativeNode } {
|
|
297
|
+
const duration = `${details.durationSeconds.toFixed(1)}s`;
|
|
298
|
+
let tone: TspTone = "success";
|
|
299
|
+
let label = "PASS";
|
|
300
|
+
let meta = duration;
|
|
301
|
+
if (details.timedOut) {
|
|
302
|
+
tone = "error";
|
|
303
|
+
label = "TIMEOUT";
|
|
304
|
+
} else if (details.exitCode !== 0) {
|
|
305
|
+
tone = "error";
|
|
306
|
+
label = "FAIL";
|
|
307
|
+
meta = `exit=${details.exitCode} ${duration}`;
|
|
308
|
+
} else if (details.parsedPrimary !== null) {
|
|
309
|
+
meta = `${duration} ${plainText(details.metricName)}=${formatNum(details.parsedPrimary, details.metricUnit)}`;
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
tone,
|
|
313
|
+
node: row([node("badge", { text: label, tone }), text([span(meta, tone)], { truncate: "end" })], { gap: "sm" }),
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
210
317
|
function renderStatus(details: RunDetails, theme: Theme): string {
|
|
211
318
|
if (details.timedOut) {
|
|
212
319
|
return theme.fg("error", `TIMEOUT ${details.durationSeconds.toFixed(1)}s`);
|
|
@@ -263,6 +370,40 @@ export const runExperimentToolRenderer = {
|
|
|
263
370
|
: "";
|
|
264
371
|
return new Text(preview ? `${statusText}\n${theme.fg("dim", preview)}${suffix}` : statusText, 0, 0);
|
|
265
372
|
},
|
|
373
|
+
describeCall(): NativeToolView {
|
|
374
|
+
return { head: toolHead("run_experiment", span(DEFAULT_HARNESS_COMMAND, "muted")) };
|
|
375
|
+
},
|
|
376
|
+
describeResult(result): NativeToolView | undefined {
|
|
377
|
+
return runResultMemo.get(result, [], () => {
|
|
378
|
+
const details = result.details;
|
|
379
|
+
if (isProgressDetails(details)) {
|
|
380
|
+
const output = resultText(result);
|
|
381
|
+
return {
|
|
382
|
+
tone: "warning",
|
|
383
|
+
preview: { lines: 6 },
|
|
384
|
+
body: compact([
|
|
385
|
+
node("spinner", { label: [span(`Running ${plainText(details.elapsed)}…`, "warning")] }),
|
|
386
|
+
output.trim() ? ansi(output, { follow: true }) : undefined,
|
|
387
|
+
]),
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
if (result.isError || !details || !isRunDetails(details)) return describeTextResult("run_experiment", result);
|
|
391
|
+
const status = describeStatus(details);
|
|
392
|
+
return {
|
|
393
|
+
tone: status.tone,
|
|
394
|
+
preview: { lines: 6 },
|
|
395
|
+
body: compact([
|
|
396
|
+
status.node,
|
|
397
|
+
details.tailOutput.trim() ? ansi(details.tailOutput, { follow: true }) : undefined,
|
|
398
|
+
details.truncation && details.fullOutputPath
|
|
399
|
+
? text([span("Full output: ", "warning"), span(shortenPath(details.fullOutputPath), "path")], {
|
|
400
|
+
truncate: "middle",
|
|
401
|
+
})
|
|
402
|
+
: undefined,
|
|
403
|
+
]),
|
|
404
|
+
};
|
|
405
|
+
});
|
|
406
|
+
},
|
|
266
407
|
} satisfies ToolRenderer<unknown, RunDetails | RunExperimentProgressDetails>;
|
|
267
408
|
|
|
268
409
|
/** Persisted experiment notes after an update. */
|
|
@@ -284,4 +425,11 @@ export const updateNotesToolRenderer = {
|
|
|
284
425
|
const text = replaceTabs(result.content.find(part => part.type === "text")?.text ?? "");
|
|
285
426
|
return new Text(theme.fg("muted", text), 0, 0);
|
|
286
427
|
},
|
|
428
|
+
describeCall(args): NativeToolView {
|
|
429
|
+
const preview = args.append_idea ?? args.body?.slice(0, 100);
|
|
430
|
+
return { head: toolHead("update_notes", span(firstLine(preview), "muted")) };
|
|
431
|
+
},
|
|
432
|
+
describeResult(result): NativeToolView | undefined {
|
|
433
|
+
return describeTextResult("update_notes", result, "muted");
|
|
434
|
+
},
|
|
287
435
|
} satisfies ToolRenderer<{ body: string; append_idea?: string }, UpdateNotesDetails>;
|
package/src/tools/bash.ts
CHANGED
|
@@ -18,7 +18,16 @@ import {
|
|
|
18
18
|
stripRawOutputArtifactNotice,
|
|
19
19
|
stripTrailingNotice,
|
|
20
20
|
} from "./output-meta";
|
|
21
|
-
import type {
|
|
21
|
+
import type {
|
|
22
|
+
NativeToolHead,
|
|
23
|
+
NativeToolView,
|
|
24
|
+
RenderResultContextOptions,
|
|
25
|
+
RenderResultOptions,
|
|
26
|
+
ToolRenderer,
|
|
27
|
+
} from "./renderer";
|
|
28
|
+
import { ansi, compact, keyed } from "../native/describe";
|
|
29
|
+
import type { NativeChild } from "../native/node";
|
|
30
|
+
import { footnoteText, resultText } from "./native-view";
|
|
22
31
|
|
|
23
32
|
/** Default collapsed shell output preview height. */
|
|
24
33
|
export const BASH_DEFAULT_PREVIEW_LINES = DEFAULT_TERMINAL_PREVIEW_LINES;
|
|
@@ -261,6 +270,122 @@ export function formatBashCommandLines(args: BashRenderArgs, uiTheme: Theme): st
|
|
|
261
270
|
return highlightedLines.map((line, i) => (i === 0 ? `${prefix}${line}` : line));
|
|
262
271
|
}
|
|
263
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Plain (unstyled) command line for native views: `cd <dir> && NAME="…" <command>`,
|
|
275
|
+
* built from the same decoded display args (incl. streamed `__partialJson` env) as the ANSI path.
|
|
276
|
+
*/
|
|
277
|
+
export function formatBashCommandText(args: BashRenderArgs): string {
|
|
278
|
+
const displayWorkdir = formatToolWorkingDirectory(args.cwd, getProjectDir());
|
|
279
|
+
const envAssignments = formatBashEnvAssignments(getBashEnvForDisplay(args));
|
|
280
|
+
const parts: string[] = [];
|
|
281
|
+
if (displayWorkdir) parts.push(`cd ${displayWorkdir} &&`);
|
|
282
|
+
if (envAssignments) parts.push(envAssignments);
|
|
283
|
+
parts.push(args.command || "…");
|
|
284
|
+
return parts.join(" ");
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/** Bash output with the LLM-facing notices (background, exit, wall time, artifact, truncation) removed. */
|
|
288
|
+
function stripBashNotices(
|
|
289
|
+
rawOutput: string,
|
|
290
|
+
details: BashToolDetails | undefined,
|
|
291
|
+
): { text: string; artifactId?: string } {
|
|
292
|
+
const withoutBackground =
|
|
293
|
+
details?.async?.state === "running"
|
|
294
|
+
? stripTrailingNotice(rawOutput, formatBackgroundNotice(details.async.jobId))
|
|
295
|
+
: rawOutput;
|
|
296
|
+
const strippedOutput = stripOutputNotice(withoutBackground, details?.meta);
|
|
297
|
+
const withoutExit =
|
|
298
|
+
details?.exitCode === undefined
|
|
299
|
+
? strippedOutput
|
|
300
|
+
: stripTrailingNotice(strippedOutput, formatExitCodeNotice(details.exitCode));
|
|
301
|
+
const withoutWall =
|
|
302
|
+
details?.wallTimeMs === undefined
|
|
303
|
+
? withoutExit
|
|
304
|
+
: stripTrailingNotice(withoutExit, formatWallTimeNotice(details.wallTimeMs));
|
|
305
|
+
return stripRawOutputArtifactNotice(withoutWall);
|
|
306
|
+
}
|
|
307
|
+
/** `Wall: 1.20s`, `Timeout: 30s`, … metadata parts shown under bash output. */
|
|
308
|
+
function bashStatsParts(
|
|
309
|
+
details: BashToolDetails | undefined,
|
|
310
|
+
contextTimeout: number | undefined,
|
|
311
|
+
artifactId: string | undefined,
|
|
312
|
+
isError: boolean,
|
|
313
|
+
): string[] {
|
|
314
|
+
const timeoutDisabled = details?.timeoutDisabled === true || contextTimeout === 0;
|
|
315
|
+
const timeoutSeconds = timeoutDisabled ? undefined : (details?.timeoutSeconds ?? contextTimeout);
|
|
316
|
+
const requestedTimeoutSeconds = details?.requestedTimeoutSeconds;
|
|
317
|
+
const wallTimeMs = details?.wallTimeMs;
|
|
318
|
+
const statsParts: string[] = [];
|
|
319
|
+
if (details?.async?.state === "running") {
|
|
320
|
+
statsParts.push(`Backgrounded: ${details.async.jobId}`);
|
|
321
|
+
}
|
|
322
|
+
if (details?.service) {
|
|
323
|
+
const service = details.service;
|
|
324
|
+
statsParts.push(`Service: ${service.name}`, `State: ${service.state}`);
|
|
325
|
+
statsParts.push(`Ready: ${service.ready ? "yes" : service.timedOut ? "timed out" : "no"}`);
|
|
326
|
+
if (service.pid !== undefined) statsParts.push(`PID: ${service.pid}`);
|
|
327
|
+
}
|
|
328
|
+
if (wallTimeMs !== undefined) {
|
|
329
|
+
statsParts.push(`Wall: ${formatWallTimeSeconds(wallTimeMs)}s`);
|
|
330
|
+
}
|
|
331
|
+
if (timeoutDisabled) {
|
|
332
|
+
statsParts.push("Timeout: disabled");
|
|
333
|
+
}
|
|
334
|
+
if (typeof timeoutSeconds === "number") {
|
|
335
|
+
statsParts.push(
|
|
336
|
+
requestedTimeoutSeconds !== undefined && requestedTimeoutSeconds !== timeoutSeconds
|
|
337
|
+
? `Timeout: ${timeoutSeconds}s (requested ${requestedTimeoutSeconds}s clamped)`
|
|
338
|
+
: `Timeout: ${timeoutSeconds}s`,
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
if (artifactId) {
|
|
342
|
+
statsParts.push(`Artifact: ${artifactId}`);
|
|
343
|
+
}
|
|
344
|
+
if (isError && typeof details?.exitCode === "number") {
|
|
345
|
+
statsParts.push(`Exit: ${details.exitCode}`);
|
|
346
|
+
}
|
|
347
|
+
return statsParts;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Native head facts of a shell call: title, the command once (`cd`/env
|
|
352
|
+
* prefix included), a `background` badge for a backgrounded job, the
|
|
353
|
+
* `exit N` chip and a `timed out` note only when the deadline hit.
|
|
354
|
+
*/
|
|
355
|
+
function shellToolHead(
|
|
356
|
+
title: string,
|
|
357
|
+
command: string,
|
|
358
|
+
details: BashToolDetails | undefined,
|
|
359
|
+
settled: boolean,
|
|
360
|
+
): NativeToolHead {
|
|
361
|
+
const exit = settled && details?.exitCode !== undefined && details.exitCode !== 0 ? details.exitCode : undefined;
|
|
362
|
+
return {
|
|
363
|
+
title,
|
|
364
|
+
target: command,
|
|
365
|
+
targetKind: "command",
|
|
366
|
+
lang: "bash",
|
|
367
|
+
badges:
|
|
368
|
+
details?.async?.state === "running"
|
|
369
|
+
? [{ text: "background", title: `Backgrounded as job ${details.async.jobId}` }]
|
|
370
|
+
: undefined,
|
|
371
|
+
exit,
|
|
372
|
+
note: settled && details?.timedOut === true ? "timed out" : undefined,
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/** The quiet final line's facts under shell output: service state and the full-output artifact. */
|
|
377
|
+
function shellFootParts(details: BashToolDetails | undefined, artifactId: string | undefined): string[] {
|
|
378
|
+
const parts: string[] = [];
|
|
379
|
+
const service = details?.service;
|
|
380
|
+
if (service) {
|
|
381
|
+
parts.push(`Service ${service.name}`, service.state);
|
|
382
|
+
parts.push(service.ready ? "ready" : service.timedOut ? "ready timed out" : "not ready");
|
|
383
|
+
if (service.pid !== undefined) parts.push(`PID ${service.pid}`);
|
|
384
|
+
}
|
|
385
|
+
if (artifactId) parts.push(`Artifact ${artifactId}`);
|
|
386
|
+
return parts;
|
|
387
|
+
}
|
|
388
|
+
|
|
264
389
|
function toBashRenderArgs<TArgs>(args: TArgs | undefined, config: ShellRendererConfig<TArgs>): BashRenderArgs {
|
|
265
390
|
return {
|
|
266
391
|
command: config.resolveCommand?.(args),
|
|
@@ -378,58 +503,17 @@ export function createShellRenderer<TArgs>(config: ShellRendererConfig<TArgs>) {
|
|
|
378
503
|
) {
|
|
379
504
|
return cachedSnapshot;
|
|
380
505
|
}
|
|
381
|
-
const
|
|
382
|
-
details?.async?.state === "running"
|
|
383
|
-
? stripTrailingNotice(rawOutput, formatBackgroundNotice(details.async.jobId))
|
|
384
|
-
: rawOutput;
|
|
385
|
-
const strippedOutput = stripOutputNotice(withoutBackground, details?.meta);
|
|
386
|
-
const withoutExit =
|
|
387
|
-
details?.exitCode === undefined
|
|
388
|
-
? strippedOutput
|
|
389
|
-
: stripTrailingNotice(strippedOutput, formatExitCodeNotice(details.exitCode));
|
|
390
|
-
const withoutWall =
|
|
391
|
-
details?.wallTimeMs === undefined
|
|
392
|
-
? withoutExit
|
|
393
|
-
: stripTrailingNotice(withoutExit, formatWallTimeNotice(details.wallTimeMs));
|
|
394
|
-
const rawOutputArtifact = stripRawOutputArtifactNotice(withoutWall);
|
|
506
|
+
const rawOutputArtifact = stripBashNotices(rawOutput, details);
|
|
395
507
|
const output = rawOutputArtifact.text;
|
|
396
508
|
const displayOutput = output.trimEnd();
|
|
397
509
|
const showingFullOutput = expanded && renderContext?.isFullOutput === true;
|
|
398
510
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
if (details?.async?.state === "running") {
|
|
406
|
-
statsParts.push(`Backgrounded: ${details.async.jobId}`);
|
|
407
|
-
}
|
|
408
|
-
if (details?.service) {
|
|
409
|
-
const service = details.service;
|
|
410
|
-
statsParts.push(`Service: ${service.name}`, `State: ${service.state}`);
|
|
411
|
-
statsParts.push(`Ready: ${service.ready ? "yes" : service.timedOut ? "timed out" : "no"}`);
|
|
412
|
-
if (service.pid !== undefined) statsParts.push(`PID: ${service.pid}`);
|
|
413
|
-
}
|
|
414
|
-
if (wallTimeMs !== undefined) {
|
|
415
|
-
statsParts.push(`Wall: ${formatWallTimeSeconds(wallTimeMs)}s`);
|
|
416
|
-
}
|
|
417
|
-
if (timeoutDisabled) {
|
|
418
|
-
statsParts.push("Timeout: disabled");
|
|
419
|
-
}
|
|
420
|
-
if (typeof timeoutSeconds === "number") {
|
|
421
|
-
statsParts.push(
|
|
422
|
-
requestedTimeoutSeconds !== undefined && requestedTimeoutSeconds !== timeoutSeconds
|
|
423
|
-
? `Timeout: ${timeoutSeconds}s (requested ${requestedTimeoutSeconds}s clamped)`
|
|
424
|
-
: `Timeout: ${timeoutSeconds}s`,
|
|
425
|
-
);
|
|
426
|
-
}
|
|
427
|
-
if (rawOutputArtifact.artifactId) {
|
|
428
|
-
statsParts.push(`Artifact: ${rawOutputArtifact.artifactId}`);
|
|
429
|
-
}
|
|
430
|
-
if (isError && typeof details?.exitCode === "number") {
|
|
431
|
-
statsParts.push(`Exit: ${details.exitCode}`);
|
|
432
|
-
}
|
|
511
|
+
const statsParts = bashStatsParts(
|
|
512
|
+
details,
|
|
513
|
+
renderContext?.timeout,
|
|
514
|
+
rawOutputArtifact.artifactId,
|
|
515
|
+
isError,
|
|
516
|
+
);
|
|
433
517
|
const timeoutLine =
|
|
434
518
|
statsParts.length > 0
|
|
435
519
|
? uiTheme.fg(
|
|
@@ -506,6 +590,53 @@ export function createShellRenderer<TArgs>(config: ShellRendererConfig<TArgs>) {
|
|
|
506
590
|
},
|
|
507
591
|
);
|
|
508
592
|
},
|
|
593
|
+
describeCall(args: TArgs, options: RenderResultOptions): NativeToolView {
|
|
594
|
+
const command = formatBashCommandText(toBashRenderArgs(args, config));
|
|
595
|
+
// The command shows once, in the head; the body is only the output.
|
|
596
|
+
return {
|
|
597
|
+
tool: shellToolHead(config.resolveTitle(args, options), command, undefined, false),
|
|
598
|
+
preview: { tail: BASH_DEFAULT_PREVIEW_LINES },
|
|
599
|
+
};
|
|
600
|
+
},
|
|
601
|
+
|
|
602
|
+
describeResult(
|
|
603
|
+
result: {
|
|
604
|
+
content: Array<{ type: string; text?: string }>;
|
|
605
|
+
details?: BashToolDetails;
|
|
606
|
+
isError?: boolean;
|
|
607
|
+
},
|
|
608
|
+
options: RenderResultContextOptions & { renderContext?: BashRenderContext },
|
|
609
|
+
args?: TArgs,
|
|
610
|
+
): NativeToolView {
|
|
611
|
+
const details = result.details;
|
|
612
|
+
const renderContext = options.renderContext;
|
|
613
|
+
const isError = result.isError === true;
|
|
614
|
+
const isPartial = options.isPartial === true;
|
|
615
|
+
const rawOutput = renderContext?.output ?? resultText(result);
|
|
616
|
+
const stripped = stripBashNotices(rawOutput, details);
|
|
617
|
+
const output = stripped.text.trimEnd();
|
|
618
|
+
const expanded = renderContext?.expanded ?? options.expanded;
|
|
619
|
+
const showingFullOutput = expanded && renderContext?.isFullOutput === true;
|
|
620
|
+
const command = formatBashCommandText(toBashRenderArgs(args, config));
|
|
621
|
+
const previewLines = renderContext?.previewLines ?? BASH_DEFAULT_PREVIEW_LINES;
|
|
622
|
+
// Wall time is the head timer, the timeout a note only when hit, the exit a head chip:
|
|
623
|
+
// what is left (service state, artifact, truncation) is one quiet final line.
|
|
624
|
+
const meta = details?.meta;
|
|
625
|
+
const body: NativeChild[] = compact([
|
|
626
|
+
output.trim().length > 0 &&
|
|
627
|
+
keyed(ansi(output, { follow: isPartial, role: "omp.tool.bash.output" }), "output"),
|
|
628
|
+
footnoteText(shellFootParts(details, stripped.artifactId), {
|
|
629
|
+
...meta,
|
|
630
|
+
truncation: showingFullOutput ? undefined : meta?.truncation,
|
|
631
|
+
}),
|
|
632
|
+
]);
|
|
633
|
+
return {
|
|
634
|
+
tool: shellToolHead(config.resolveTitle(args, options), command, details, !isPartial),
|
|
635
|
+
body,
|
|
636
|
+
tone: !isPartial && isError && details?.timedOut === true ? "warning" : undefined,
|
|
637
|
+
preview: { tail: previewLines },
|
|
638
|
+
};
|
|
639
|
+
},
|
|
509
640
|
mergeCallAndResult: true,
|
|
510
641
|
inline: true,
|
|
511
642
|
} satisfies ToolRenderer<TArgs, BashToolDetails>;
|
package/src/tools/cfg-render.ts
CHANGED
|
@@ -16,8 +16,11 @@ import {
|
|
|
16
16
|
} from "../render/render-utils";
|
|
17
17
|
import { highlightCode, type Theme } from "../theme/theme";
|
|
18
18
|
import { parseCfgUrl } from "./cfg-url";
|
|
19
|
-
import type { RenderResultOptions } from "./renderer";
|
|
19
|
+
import type { NativeToolView, RenderResultOptions } from "./renderer";
|
|
20
20
|
import { card, type CardToolResult, firstText, safe } from "./result-card";
|
|
21
|
+
import { code, compact, span, text } from "../native/describe";
|
|
22
|
+
import { plainText } from "../native/spans";
|
|
23
|
+
import { errorView, toolHead } from "./native-view";
|
|
21
24
|
|
|
22
25
|
/** Summary of a `cfg://` read, attached to read tool details. */
|
|
23
26
|
export interface CfgReadDetails {
|
|
@@ -77,6 +80,68 @@ export function renderCfgRead(
|
|
|
77
80
|
}, options);
|
|
78
81
|
}
|
|
79
82
|
|
|
83
|
+
/** TSP view of `read cfg://…`: path and counts in the head, the listing as YAML. */
|
|
84
|
+
export function describeCfgRead(
|
|
85
|
+
url: string,
|
|
86
|
+
result: CardToolResult | undefined,
|
|
87
|
+
details: CfgReadDetails | undefined,
|
|
88
|
+
): NativeToolView {
|
|
89
|
+
const description = (details?.path ?? parseCfgUrl(url)?.segments.join(".")) || "all settings";
|
|
90
|
+
const meta: string[] = [];
|
|
91
|
+
if (details) {
|
|
92
|
+
meta.push(details.count === 1 ? "1 setting" : `${details.count} settings`);
|
|
93
|
+
if (details.modified) meta.push(`${details.modified} modified`);
|
|
94
|
+
}
|
|
95
|
+
if (result?.isError) return errorView("Config", firstText(result) || "Settings read failed.", description, ...meta);
|
|
96
|
+
const head = toolHead("Config", description, ...meta);
|
|
97
|
+
if (!result) return { head };
|
|
98
|
+
const listing = plainText(safe(firstText(result).trimEnd()));
|
|
99
|
+
return {
|
|
100
|
+
head,
|
|
101
|
+
body: listing ? [code(listing, { lang: "yaml" })] : undefined,
|
|
102
|
+
preview: { lines: PREVIEW_LIMITS.COLLAPSED_ITEMS },
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** TSP view of `write cfg://…[/save]`: scope/outcome in the head, then `previous → value`. */
|
|
107
|
+
export function describeCfgWrite(
|
|
108
|
+
url: string,
|
|
109
|
+
content: string | undefined,
|
|
110
|
+
result: CardToolResult | undefined,
|
|
111
|
+
details: CfgWriteDetails | undefined,
|
|
112
|
+
): NativeToolView {
|
|
113
|
+
const target = parseCfgUrl(url);
|
|
114
|
+
const path = details?.path ?? target?.segments.join(".");
|
|
115
|
+
const save = details?.save ?? target?.save ?? false;
|
|
116
|
+
if (result?.isError) return errorView("Config", firstText(result) || "Settings write failed.", path);
|
|
117
|
+
const head = toolHead("Config", path);
|
|
118
|
+
head.push(span(" "), span(save ? "persist" : "session", save ? "accent strong" : "muted"));
|
|
119
|
+
if (details?.outcome === "declined") head.push(span(" "), span("declined", "warning strong"));
|
|
120
|
+
if (details?.outcome === "unchanged") head.push(span(" "), span("unchanged", "muted"));
|
|
121
|
+
const next = span(plainText(details?.value ?? content?.trim() ?? "…"), "toolOutput");
|
|
122
|
+
const change = details
|
|
123
|
+
? [span(plainText(details.previous), "dim"), span(" → ", "dim"), next]
|
|
124
|
+
: [span("→ ", "dim"), next];
|
|
125
|
+
return {
|
|
126
|
+
head,
|
|
127
|
+
tone: details?.outcome === "declined" ? "warning" : undefined,
|
|
128
|
+
body: compact([
|
|
129
|
+
text(change, { wrap: "word" }),
|
|
130
|
+
details?.effective !== undefined
|
|
131
|
+
? text(
|
|
132
|
+
[
|
|
133
|
+
span(
|
|
134
|
+
`still ${plainText(details.effective)}: a higher-precedence layer overrides the saved value`,
|
|
135
|
+
"warning",
|
|
136
|
+
),
|
|
137
|
+
],
|
|
138
|
+
{ wrap: "word" },
|
|
139
|
+
)
|
|
140
|
+
: undefined,
|
|
141
|
+
]),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
80
145
|
/** Render `write cfg://…[/save]`: the proposed value while pending, then the approved/declined change. */
|
|
81
146
|
export function renderCfgWrite(
|
|
82
147
|
url: string,
|