@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/lsp.ts
CHANGED
|
@@ -7,12 +7,14 @@
|
|
|
7
7
|
* - Grouped references and symbols
|
|
8
8
|
* - Collapsible/expandable views
|
|
9
9
|
*/
|
|
10
|
-
import type {
|
|
10
|
+
import type { TspSpan, TspText, TspTone, TspTreeNode } from "@oh-my-pi/pi-wire";
|
|
11
|
+
import type { NativeToolHead, NativeToolView, RenderResultOptions, ToolRenderer, ToolRenderResult } from "./renderer";
|
|
11
12
|
import type { Component } from "../tui";
|
|
12
13
|
import { Text } from "../components/text";
|
|
13
14
|
import { getLanguageFromPath } from "../lang-from-path";
|
|
14
15
|
import { highlightCode as highlightThemeCode, type Theme } from "../theme/theme";
|
|
15
16
|
import {
|
|
17
|
+
formatCount,
|
|
16
18
|
formatExpandHint,
|
|
17
19
|
formatMoreItems,
|
|
18
20
|
formatStatusIcon,
|
|
@@ -26,6 +28,13 @@ import {
|
|
|
26
28
|
} from "../render/render-utils";
|
|
27
29
|
import { renderStatusLine } from "../render";
|
|
28
30
|
import { framedToolCard } from "../render/tool-card";
|
|
31
|
+
import { ansi, code, col, compact, keyed, md, node, row, span, text } from "../native/describe";
|
|
32
|
+
import type { NativeNode } from "../native/node";
|
|
33
|
+
import { OwnerMemo } from "../native/memo";
|
|
34
|
+
import { plainText } from "../native/spans";
|
|
35
|
+
import { walkGroupedOutput } from "./grouped-file-output";
|
|
36
|
+
import { diagnosticGlyph, fileHref, fileRow, inlineErrorView } from "./native-view";
|
|
37
|
+
import { activeThemeSymbol } from "../theme/active-symbols";
|
|
29
38
|
|
|
30
39
|
/** Display arguments for an LSP tool request. */
|
|
31
40
|
export interface LspParams {
|
|
@@ -693,10 +702,318 @@ function severityToColor(severity: ParsedDiagnostic["severity"]): "error" | "war
|
|
|
693
702
|
}
|
|
694
703
|
}
|
|
695
704
|
|
|
705
|
+
// =============================================================================
|
|
706
|
+
// Native (TSP) Description
|
|
707
|
+
// =============================================================================
|
|
708
|
+
|
|
709
|
+
/** The head verb for an LSP action (`type_definition` → `Type definition`). */
|
|
710
|
+
function lspActionTitle(action: string | undefined): string {
|
|
711
|
+
if (!action || action === "request") return "LSP";
|
|
712
|
+
const words = action.replace(/_/g, " ");
|
|
713
|
+
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* Native head (§7.3 lsp): the action as the verb; the file (`:line`) as a
|
|
718
|
+
* path target, else the query; then the symbol and option facts, then the
|
|
719
|
+
* result `meta` (a count chip).
|
|
720
|
+
*/
|
|
721
|
+
function lspNativeHead(
|
|
722
|
+
request: Partial<LspParams> | undefined,
|
|
723
|
+
fallbackAction: string,
|
|
724
|
+
meta: readonly TspText[] = [],
|
|
725
|
+
): NativeToolHead {
|
|
726
|
+
const facts: string[] = [];
|
|
727
|
+
const symbol = request?.symbol ? plainText(request.symbol).replaceAll(/\r?\n/g, " ") : undefined;
|
|
728
|
+
let target: string | undefined;
|
|
729
|
+
let targetKind: NativeToolHead["targetKind"];
|
|
730
|
+
if (request?.file) {
|
|
731
|
+
target = request.line !== undefined ? `${shortenPath(request.file)}:${request.line}` : shortenPath(request.file);
|
|
732
|
+
targetKind = "path";
|
|
733
|
+
} else if (request?.query) {
|
|
734
|
+
target = request.query;
|
|
735
|
+
targetKind = "query";
|
|
736
|
+
} else if (request?.line !== undefined) {
|
|
737
|
+
facts.push(`line ${request.line}`);
|
|
738
|
+
}
|
|
739
|
+
if (symbol) facts.push(symbol);
|
|
740
|
+
if (request?.query && target !== request.query) facts.push(`query:${request.query}`);
|
|
741
|
+
if (request?.new_name) facts.push(`\u2192 ${request.new_name}`);
|
|
742
|
+
if (request?.apply !== undefined) facts.push(`apply:${request.apply ? "true" : "false"}`);
|
|
743
|
+
return {
|
|
744
|
+
title: lspActionTitle(request?.action ?? fallbackAction),
|
|
745
|
+
target,
|
|
746
|
+
targetKind,
|
|
747
|
+
href: request?.file ? fileHref(request.file) : undefined,
|
|
748
|
+
meta: [...(facts.length > 0 ? [plainText(facts.join(" \u00b7 "))] : []), ...meta],
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/** A diagnostics response, parsed: diagnostics, server failures and partial-failure warnings. */
|
|
753
|
+
interface LspDiagnosticsParse {
|
|
754
|
+
diagnostics: ParsedDiagnostic[];
|
|
755
|
+
failures: string[];
|
|
756
|
+
warnings: string[];
|
|
757
|
+
/** Lines neither a diagnostic nor a status line (kept verbatim). */
|
|
758
|
+
other: string[];
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
const DIAGNOSTIC_AT_RE = /^\d+:\d+\s+\[/;
|
|
762
|
+
const DIAGNOSTICS_SUMMARY_RE = /^\d+ \w+\(s\)(?:, \d+ \w+\(s\))*:?$/;
|
|
763
|
+
/** A per-file status line's leading status glyph (`✘`, `⚠`, a Nerd Font glyph, ASCII `[!!]`). */
|
|
764
|
+
const STATUS_GLYPH_RE = /^(?:\[[^\]\s]*\]|[^\p{L}\p{N}\s./~\\]+)\s+/u;
|
|
765
|
+
/** Per-file summaries (`✗ a.ts: 2 error(s)`, `✓ a.ts: no issues`) repeat what the rows and head count. */
|
|
766
|
+
const FILE_SUMMARY_RE = /: (?:no issues|\d+ \w+\(s\)(?:, \d+ \w+\(s\))*)$/;
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* Parse a diagnostics response: grouped (`# dir/`, `## file`, ` 12:5 [error] …`)
|
|
770
|
+
* or flat (`file:12:5 [error] …`) diagnostic lines, and the per-file status
|
|
771
|
+
* lines (`✗ file: all language servers failed (…)`, `⚠ …some servers failed`,
|
|
772
|
+
* `✓ file: no issues`, `✗ file: 2 error(s)`).
|
|
773
|
+
*/
|
|
774
|
+
function parseLspDiagnostics(lines: readonly string[]): LspDiagnosticsParse {
|
|
775
|
+
const out: LspDiagnosticsParse = { diagnostics: [], failures: [], warnings: [], other: [] };
|
|
776
|
+
let file: string | undefined;
|
|
777
|
+
for (const event of walkGroupedOutput(lines)) {
|
|
778
|
+
if (event.kind !== "line") {
|
|
779
|
+
file = event.kind === "file" ? event.path : undefined;
|
|
780
|
+
continue;
|
|
781
|
+
}
|
|
782
|
+
const line = event.text.trim();
|
|
783
|
+
if (line === "OK" || DIAGNOSTICS_SUMMARY_RE.test(line)) continue;
|
|
784
|
+
// Matched by wording, not glyph: a transcript may outlive the theme that wrote it.
|
|
785
|
+
if (/\ball language servers failed\b/.test(line)) {
|
|
786
|
+
out.failures.push(line.replace(STATUS_GLYPH_RE, ""));
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
789
|
+
if (/\bsome servers failed\b/.test(line)) {
|
|
790
|
+
out.warnings.push(line.replace(STATUS_GLYPH_RE, ""));
|
|
791
|
+
continue;
|
|
792
|
+
}
|
|
793
|
+
if (FILE_SUMMARY_RE.test(line)) continue;
|
|
794
|
+
const parsed = parseDiagnosticMessage(file && DIAGNOSTIC_AT_RE.test(line) ? `${file}:${line}` : line);
|
|
795
|
+
if (parsed) out.diagnostics.push(parsed);
|
|
796
|
+
else out.other.push(line);
|
|
797
|
+
}
|
|
798
|
+
return out;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/** `2 errors · 1 warning` in the severity tones, or undefined when there are none. */
|
|
802
|
+
function diagnosticCounts(diagnostics: readonly ParsedDiagnostic[]): TspSpan[] | undefined {
|
|
803
|
+
const counts: Record<ParsedDiagnostic["severity"], number> = { error: 0, warning: 0, info: 0, hint: 0 };
|
|
804
|
+
for (const d of diagnostics) counts[d.severity]++;
|
|
805
|
+
const spans: TspSpan[] = [];
|
|
806
|
+
for (const severity of ["error", "warning", "info", "hint"] as const) {
|
|
807
|
+
const n = counts[severity];
|
|
808
|
+
if (!n) continue;
|
|
809
|
+
if (spans.length > 0) spans.push(span(" \u00b7 ", "dim"));
|
|
810
|
+
spans.push(span(formatCount(severity, n), severityTone(severity)));
|
|
811
|
+
}
|
|
812
|
+
return spans.length > 0 ? spans : undefined;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
function severityTone(severity: ParsedDiagnostic["severity"]): TspTone {
|
|
816
|
+
switch (severity) {
|
|
817
|
+
case "error":
|
|
818
|
+
return "error";
|
|
819
|
+
case "warning":
|
|
820
|
+
return "warning";
|
|
821
|
+
case "info":
|
|
822
|
+
return "info";
|
|
823
|
+
default:
|
|
824
|
+
return "muted";
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/** One diagnostic row (role `omp.tool.diagnostic`): severity icon, mono `file:line:col`, source chip, message. */
|
|
829
|
+
function diagnosticRow(diag: ParsedDiagnostic, key: string): NativeNode {
|
|
830
|
+
const message: TspSpan[] = [span(diag.message)];
|
|
831
|
+
if (diag.code) message.push(span(` ${diag.code}`, "muted"));
|
|
832
|
+
return keyed(
|
|
833
|
+
row(
|
|
834
|
+
compact([
|
|
835
|
+
diagnosticGlyph(diag.severity),
|
|
836
|
+
text([span(`${diag.filePath}:${diag.line}:${diag.col}`, "mono muted")], { wrap: "none" }),
|
|
837
|
+
diag.source ? node("badge", { text: diag.source }) : undefined,
|
|
838
|
+
text(message, { wrap: "word", grow: 1 }),
|
|
839
|
+
]),
|
|
840
|
+
{ role: "omp.tool.diagnostic" },
|
|
841
|
+
),
|
|
842
|
+
key,
|
|
843
|
+
);
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/** A server failure / partial-failure row: the status icon and the message, in its tone. */
|
|
847
|
+
function statusRow(message: string, tone: "error" | "warning", key: string): NativeNode {
|
|
848
|
+
return keyed(
|
|
849
|
+
row([diagnosticGlyph(tone), text([span(plainText(message), tone)], { wrap: "word", grow: 1 })], {
|
|
850
|
+
role: tone === "error" ? "omp.tool.error" : "omp.tool.diagnostic",
|
|
851
|
+
}),
|
|
852
|
+
key,
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* Diagnostics view: a card when there are diagnostics or failures (rows of
|
|
858
|
+
* severity icon · `file:line:col` · source · message), an inline `No issues`
|
|
859
|
+
* otherwise. A failed server is an error row, never "No issues".
|
|
860
|
+
*/
|
|
861
|
+
function describeLspDiagnostics(request: Partial<LspParams> | undefined, fallbackAction: string, lines: string[]) {
|
|
862
|
+
const parsed = parseLspDiagnostics(lines);
|
|
863
|
+
const counts = diagnosticCounts(parsed.diagnostics);
|
|
864
|
+
const failed =
|
|
865
|
+
parsed.failures.length > 0 ? [span(formatCount("server failure", parsed.failures.length), "error")] : undefined;
|
|
866
|
+
const rows: NativeNode[] = [
|
|
867
|
+
...parsed.failures.map((message, i) => statusRow(message, "error", `x${i}`)),
|
|
868
|
+
...parsed.diagnostics.map((diag, i) => diagnosticRow(diag, `d${i}`)),
|
|
869
|
+
...parsed.warnings.map((message, i) => statusRow(message, "warning", `w${i}`)),
|
|
870
|
+
];
|
|
871
|
+
if (parsed.other.length > 0) rows.push(keyed(code(parsed.other.join("\n"), { wrap: true }), "other"));
|
|
872
|
+
const hasErrors = parsed.failures.length > 0 || parsed.diagnostics.some(d => d.severity === "error");
|
|
873
|
+
const meta = compact<TspText>([counts, failed, !counts && !failed && "No issues"]);
|
|
874
|
+
const head = lspNativeHead(request, fallbackAction, meta);
|
|
875
|
+
if (parsed.diagnostics.length === 0 && parsed.failures.length === 0) {
|
|
876
|
+
return { tool: head, inline: true, body: rows.length > 0 ? rows : undefined } satisfies NativeToolView;
|
|
877
|
+
}
|
|
878
|
+
return {
|
|
879
|
+
tool: head,
|
|
880
|
+
tone: hasErrors ? "error" : "warning",
|
|
881
|
+
body: rows,
|
|
882
|
+
preview: { lines: 8 },
|
|
883
|
+
} satisfies NativeToolView;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
/** References grouped by file (§7.3): a file row with the count, then the `line:col` positions. */
|
|
887
|
+
function describeLspReferences(lines: string[]): NativeNode[] {
|
|
888
|
+
const byFile = new Map<string, string[]>();
|
|
889
|
+
for (const loc of lines) {
|
|
890
|
+
const match = loc.trim().match(/^(.+):(\d+):(\d+)$/);
|
|
891
|
+
if (!match) continue;
|
|
892
|
+
const [, file, line, col] = match;
|
|
893
|
+
let locs = byFile.get(file);
|
|
894
|
+
if (!locs) {
|
|
895
|
+
locs = [];
|
|
896
|
+
byFile.set(file, locs);
|
|
897
|
+
}
|
|
898
|
+
locs.push(`${line}:${col}`);
|
|
899
|
+
}
|
|
900
|
+
const nodes: NativeNode[] = [];
|
|
901
|
+
for (const [file, locs] of byFile) {
|
|
902
|
+
const name = plainText(file);
|
|
903
|
+
nodes.push(
|
|
904
|
+
keyed(
|
|
905
|
+
col(
|
|
906
|
+
[
|
|
907
|
+
fileRow(name, { chip: { text: String(locs.length), title: formatCount("reference", locs.length) } }),
|
|
908
|
+
text([span(locs.join(" "), "mono muted")], { wrap: "word" }),
|
|
909
|
+
],
|
|
910
|
+
{ gap: "xs" },
|
|
911
|
+
),
|
|
912
|
+
name,
|
|
913
|
+
),
|
|
914
|
+
);
|
|
915
|
+
}
|
|
916
|
+
return nodes;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
function describeLspSymbols(lines: string[]): NativeNode | undefined {
|
|
920
|
+
const roots: TspTreeNode[] = [];
|
|
921
|
+
const stack: { indent: number; children: TspTreeNode[] }[] = [];
|
|
922
|
+
let index = 0;
|
|
923
|
+
for (const line of lines) {
|
|
924
|
+
if (!line.includes("@") || !line.includes("line")) continue;
|
|
925
|
+
const symMatch = line.trim().match(/^(\S+)\s+(.+?)\s*@\s*line\s*(\d+)/);
|
|
926
|
+
if (!symMatch) continue;
|
|
927
|
+
const indent = line.match(/^(\s*)/)?.[1].length ?? 0;
|
|
928
|
+
const children: TspTreeNode[] = [];
|
|
929
|
+
const treeNode: TspTreeNode = {
|
|
930
|
+
id: `${index++}`,
|
|
931
|
+
label: [
|
|
932
|
+
span(plainText(symMatch[1]), "accent"),
|
|
933
|
+
span(" "),
|
|
934
|
+
span(plainText(symMatch[2]), "accent"),
|
|
935
|
+
span(` line ${symMatch[3]}`, "muted"),
|
|
936
|
+
],
|
|
937
|
+
open: true,
|
|
938
|
+
children,
|
|
939
|
+
};
|
|
940
|
+
while (stack.length > 0 && stack[stack.length - 1].indent >= indent) stack.pop();
|
|
941
|
+
(stack[stack.length - 1]?.children ?? roots).push(treeNode);
|
|
942
|
+
stack.push({ indent, children });
|
|
943
|
+
}
|
|
944
|
+
return roots.length > 0 ? node("tree", { nodes: roots }) : undefined;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
function describeLspResult(result: ToolRenderResult<LspToolDetails>, args: LspParams | undefined): NativeToolView {
|
|
948
|
+
const request = args ?? result.details?.request;
|
|
949
|
+
const fallbackAction = result.details?.action ?? "request";
|
|
950
|
+
const content = result.content?.[0];
|
|
951
|
+
const text = content?.type === "text" ? (content.text ?? "") : "";
|
|
952
|
+
if (result.isError) return inlineErrorView(lspNativeHead(request, fallbackAction), text || "LSP request failed");
|
|
953
|
+
if (!text) return { tool: lspNativeHead(request, fallbackAction, ["No result"]), tone: "warning", inline: true };
|
|
954
|
+
|
|
955
|
+
const lines = text.split("\n");
|
|
956
|
+
const statusError = activeThemeSymbol("status.error");
|
|
957
|
+
const refMatch = text.match(/(\d+)\s+reference\(s\)/);
|
|
958
|
+
const symbolsMatch = text.match(/Symbols in (.+):/);
|
|
959
|
+
|
|
960
|
+
if (/```(\w*)\n([\s\S]*?)```/.test(text)) {
|
|
961
|
+
return { tool: lspNativeHead(request, fallbackAction), inline: true, body: [md(text)], preview: { lines: 4 } };
|
|
962
|
+
}
|
|
963
|
+
if (
|
|
964
|
+
/\d+\s+(?:error|warning)\(s\)/.test(text) ||
|
|
965
|
+
text.includes(statusError) ||
|
|
966
|
+
(request?.action ?? fallbackAction) === "diagnostics"
|
|
967
|
+
) {
|
|
968
|
+
return describeLspDiagnostics(request, fallbackAction, lines);
|
|
969
|
+
}
|
|
970
|
+
if (refMatch) {
|
|
971
|
+
const refCount = Number.parseInt(refMatch[1], 10);
|
|
972
|
+
const body = describeLspReferences(lines);
|
|
973
|
+
return {
|
|
974
|
+
tool: lspNativeHead(request, fallbackAction, [formatCount("reference", refCount)]),
|
|
975
|
+
tone: refCount > 0 ? undefined : "warning",
|
|
976
|
+
inline: true,
|
|
977
|
+
body: body.length > 0 ? body : undefined,
|
|
978
|
+
preview: { lines: 8 },
|
|
979
|
+
};
|
|
980
|
+
}
|
|
981
|
+
if (symbolsMatch) {
|
|
982
|
+
const body = describeLspSymbols(lines);
|
|
983
|
+
return {
|
|
984
|
+
tool: lspNativeHead(request, fallbackAction, [`in ${symbolsMatch[1]}`]),
|
|
985
|
+
inline: true,
|
|
986
|
+
body: body ? [body] : undefined,
|
|
987
|
+
preview: { lines: 8 },
|
|
988
|
+
};
|
|
989
|
+
}
|
|
990
|
+
const hasError = text.includes("Error:") || text.includes(statusError);
|
|
991
|
+
const hasSuccess = text.includes(activeThemeSymbol("status.success")) || text.includes("Applied");
|
|
992
|
+
return {
|
|
993
|
+
tool: lspNativeHead(request, fallbackAction),
|
|
994
|
+
tone: hasError && !hasSuccess ? "error" : undefined,
|
|
995
|
+
inline: true,
|
|
996
|
+
body: [ansi(text)],
|
|
997
|
+
preview: { lines: 4 },
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
const lspResultMemo = new OwnerMemo<NativeToolView | undefined>();
|
|
1002
|
+
|
|
696
1003
|
/** Render LSP requests and responses in the transcript. */
|
|
697
1004
|
export const lspToolRenderer = {
|
|
698
1005
|
renderCall,
|
|
699
1006
|
renderResult,
|
|
1007
|
+
describeCall(args: LspParams): NativeToolView {
|
|
1008
|
+
return { tool: lspNativeHead(args, "request"), inline: true };
|
|
1009
|
+
},
|
|
1010
|
+
describeResult(
|
|
1011
|
+
result: ToolRenderResult<LspToolDetails>,
|
|
1012
|
+
_options: RenderResultOptions,
|
|
1013
|
+
args?: LspParams,
|
|
1014
|
+
): NativeToolView | undefined {
|
|
1015
|
+
return lspResultMemo.get(result, [], () => describeLspResult(result, args));
|
|
1016
|
+
},
|
|
700
1017
|
mergeCallAndResult: true,
|
|
701
1018
|
inline: true,
|
|
702
1019
|
} satisfies ToolRenderer<LspParams, LspToolDetails>;
|
package/src/tools/mcp.ts
CHANGED
|
@@ -6,9 +6,16 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { type Component, Markdown } from "../index";
|
|
8
8
|
|
|
9
|
-
import type { RenderResultOptions } from "./renderer";
|
|
9
|
+
import type { NativeToolHead, NativeToolView, RenderResultOptions } from "./renderer";
|
|
10
|
+
import { INTENT_FIELD } from "@oh-my-pi/pi-wire";
|
|
11
|
+
import { ansi, md } from "../native/describe";
|
|
12
|
+
import type { NativeChild } from "../native/node";
|
|
13
|
+
import { OwnerMemo } from "../native/memo";
|
|
14
|
+
import { plainText } from "../native/spans";
|
|
15
|
+
import { errorText, noteText, truncationNotice } from "./native-view";
|
|
10
16
|
import { getMarkdownTheme, type Theme } from "../theme/theme";
|
|
11
17
|
import {
|
|
18
|
+
describeJsonTree,
|
|
12
19
|
formatArgsInline,
|
|
13
20
|
JSON_TREE_MAX_DEPTH_COLLAPSED,
|
|
14
21
|
JSON_TREE_MAX_DEPTH_EXPANDED,
|
|
@@ -230,6 +237,78 @@ export function renderMCPResult(
|
|
|
230
237
|
);
|
|
231
238
|
}
|
|
232
239
|
|
|
240
|
+
/** Visible MCP argument entries (streaming/intent bookkeeping keys dropped). */
|
|
241
|
+
function visibleMcpArgs(args: Record<string, unknown> | undefined): [string, unknown][] {
|
|
242
|
+
if (!args || typeof args !== "object") return [];
|
|
243
|
+
return Object.entries(args).filter(([key]) => key !== INTENT_FIELD && key !== "__partialJson");
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/** Inline args summary budget in characters (a data cap, not a width). */
|
|
247
|
+
const MCP_ARGS_SUMMARY_CHARS = 160;
|
|
248
|
+
|
|
249
|
+
/** Native MCP head: the tool title with a one-line args summary as target. */
|
|
250
|
+
function mcpHead(title: string, args: Record<string, unknown> | undefined): NativeToolHead {
|
|
251
|
+
const entries = visibleMcpArgs(args);
|
|
252
|
+
const summary =
|
|
253
|
+
entries.length > 0
|
|
254
|
+
? formatArgsInline(Object.fromEntries(entries), MCP_ARGS_SUMMARY_CHARS, { characterBudget: true })
|
|
255
|
+
: "";
|
|
256
|
+
return { title, target: summary ? plainText(summary) : undefined, targetKind: "text" };
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Native MCP call view: the head only, inline while pending. */
|
|
260
|
+
export function describeMCPCall(args: Record<string, unknown>, label: string): NativeToolView {
|
|
261
|
+
return { tool: mcpHead(label, args), inline: true };
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const mcpResultMemo = new OwnerMemo<NativeToolView | undefined>();
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Native MCP result view: JSON output as a JSON tree, Markdown when the
|
|
268
|
+
* preference is on, otherwise the raw text as tool output. The head's args
|
|
269
|
+
* summary stands in for the ANSI card's Args tree.
|
|
270
|
+
*/
|
|
271
|
+
export function describeMCPResult(
|
|
272
|
+
result: { content: Array<{ type: string; text?: string }>; details?: MCPToolDetails; isError?: boolean },
|
|
273
|
+
_options: RenderResultOptions,
|
|
274
|
+
args?: Record<string, unknown>,
|
|
275
|
+
): NativeToolView | undefined {
|
|
276
|
+
return mcpResultMemo.get(result, [renderMarkdownResults, JSON.stringify(args ?? null)], () => {
|
|
277
|
+
const textContent = (result.content ?? [])
|
|
278
|
+
.filter(block => block.type === "text")
|
|
279
|
+
.map(block => block.text ?? "")
|
|
280
|
+
.filter(text => text.length > 0)
|
|
281
|
+
.join("\n\n");
|
|
282
|
+
const output = stripOutputNotice(textContent, result.details?.meta).trimEnd();
|
|
283
|
+
const isError = result.isError ?? result.details?.isError ?? false;
|
|
284
|
+
const title = result.details ? `${result.details.serverName}/${result.details.mcpToolName}` : "MCP";
|
|
285
|
+
const body: NativeChild[] = [];
|
|
286
|
+
let parsed: unknown;
|
|
287
|
+
let isJson = false;
|
|
288
|
+
if (output.startsWith("{") || output.startsWith("[")) {
|
|
289
|
+
try {
|
|
290
|
+
parsed = JSON.parse(output);
|
|
291
|
+
isJson = true;
|
|
292
|
+
} catch {
|
|
293
|
+
// Bracketed non-JSON text falls through to Markdown/raw output.
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (!output) body.push(noteText("(no output)"));
|
|
297
|
+
else if (isError) body.push(errorText(output));
|
|
298
|
+
else if (isJson) body.push(describeJsonTree(parsed));
|
|
299
|
+
else if (renderMarkdownResults) body.push(md(output));
|
|
300
|
+
else body.push(ansi(output));
|
|
301
|
+
const warning = truncationNotice(result.details?.meta);
|
|
302
|
+
if (warning) body.push(warning);
|
|
303
|
+
return {
|
|
304
|
+
tool: mcpHead(title, args),
|
|
305
|
+
tone: isError ? "error" : undefined,
|
|
306
|
+
body,
|
|
307
|
+
preview: { lines: 4 },
|
|
308
|
+
};
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
233
312
|
import type { OutputMeta } from "./output-meta";
|
|
234
313
|
|
|
235
314
|
let renderMarkdownResults = false;
|
package/src/tools/memory.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ToolRenderer } from "./renderer";
|
|
1
|
+
import type { NativeToolView, ToolRenderer } from "./renderer";
|
|
2
2
|
/**
|
|
3
3
|
* Inline TUI renderers for the long-term memory tools (`retain`, `recall`,
|
|
4
4
|
* `reflect`).
|
|
@@ -23,6 +23,10 @@ import {
|
|
|
23
23
|
replaceTabs,
|
|
24
24
|
type ToolUIStatus,
|
|
25
25
|
} from "../render/render-utils";
|
|
26
|
+
import { item, list, md, span, text } from "../native/describe";
|
|
27
|
+
import { OwnerMemo } from "../native/memo";
|
|
28
|
+
import { plainText } from "../native/spans";
|
|
29
|
+
import { errorView, resultText, toolHead } from "./native-view";
|
|
26
30
|
|
|
27
31
|
// Each stored memory renders as `<bullet> <content>`; the bullet glyph comes
|
|
28
32
|
// from the active theme (`•` by default, a nerd-font dot under nerd themes).
|
|
@@ -48,10 +52,6 @@ function retainContents(args: RetainRenderArgs | undefined): string[] {
|
|
|
48
52
|
return contents;
|
|
49
53
|
}
|
|
50
54
|
|
|
51
|
-
function resultText(result: { content?: Array<{ type: string; text?: string }> }): string {
|
|
52
|
-
return (result.content?.find(c => c.type === "text")?.text ?? "").trim();
|
|
53
|
-
}
|
|
54
|
-
|
|
55
55
|
/** Single-line query header used by `recall`/`reflect` calls and results. */
|
|
56
56
|
function queryHeader(
|
|
57
57
|
title: string,
|
|
@@ -85,6 +85,24 @@ function retainComponent(contents: string[], header: string, getExpanded: () =>
|
|
|
85
85
|
});
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
/** Retained memories as a list, clamped to the collapsed item budget. */
|
|
89
|
+
function describeRetain(contents: string[], summary?: string): NativeToolView {
|
|
90
|
+
return {
|
|
91
|
+
head: toolHead("Retain", summary),
|
|
92
|
+
inline: true,
|
|
93
|
+
body:
|
|
94
|
+
contents.length > 0
|
|
95
|
+
? [list(contents.map((content, i) => item(String(i), { label: plainText(content) })))]
|
|
96
|
+
: [],
|
|
97
|
+
preview: { lines: PREVIEW_LIMITS.COLLAPSED_ITEMS },
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const retainCallMemo = new OwnerMemo<NativeToolView | undefined>();
|
|
102
|
+
const retainResultMemo = new OwnerMemo<NativeToolView | undefined>();
|
|
103
|
+
const recallResultMemo = new OwnerMemo<NativeToolView | undefined>();
|
|
104
|
+
const reflectResultMemo = new OwnerMemo<NativeToolView | undefined>();
|
|
105
|
+
|
|
88
106
|
/** Render retained memory items and their storage summary. */
|
|
89
107
|
export const retainToolRenderer = {
|
|
90
108
|
inline: true,
|
|
@@ -101,12 +119,12 @@ export const retainToolRenderer = {
|
|
|
101
119
|
args?: RetainRenderArgs,
|
|
102
120
|
): Component {
|
|
103
121
|
if (result.isError) {
|
|
104
|
-
return new Text(formatErrorMessage(resultText(result) || "Retain failed", theme), 0, 0);
|
|
122
|
+
return new Text(formatErrorMessage(resultText(result).trim() || "Retain failed", theme), 0, 0);
|
|
105
123
|
}
|
|
106
124
|
const contents = retainContents(args);
|
|
107
125
|
// `summary` is the tool's own "N memories stored/queued." line; drop the
|
|
108
126
|
// trailing period so it reads cleanly as a status meta segment.
|
|
109
|
-
const summary = resultText(result).replace(/\.$/, "");
|
|
127
|
+
const summary = resultText(result).trim().replace(/\.$/, "");
|
|
110
128
|
const header = renderStatusLine(
|
|
111
129
|
{
|
|
112
130
|
iconOverride: theme.styledSymbol("tool.memory", "accent"),
|
|
@@ -117,6 +135,21 @@ export const retainToolRenderer = {
|
|
|
117
135
|
);
|
|
118
136
|
return retainComponent(contents, header, () => options.expanded, theme);
|
|
119
137
|
},
|
|
138
|
+
describeCall(args: RetainRenderArgs): NativeToolView | undefined {
|
|
139
|
+
const contents = retainContents(args);
|
|
140
|
+
return retainCallMemo.get(args, [contents.join("\0")], () => describeRetain(contents));
|
|
141
|
+
},
|
|
142
|
+
describeResult(
|
|
143
|
+
result: { content: Array<{ type: string; text?: string }>; details?: MemoryRetainDetails; isError?: boolean },
|
|
144
|
+
_options: RenderResultOptions,
|
|
145
|
+
args?: RetainRenderArgs,
|
|
146
|
+
): NativeToolView | undefined {
|
|
147
|
+
return retainResultMemo.get(result, [], () => {
|
|
148
|
+
if (result.isError)
|
|
149
|
+
return { ...errorView("Retain", resultText(result).trim() || "Retain failed"), inline: true };
|
|
150
|
+
return describeRetain(retainContents(args), resultText(result).trim().replace(/\.$/, ""));
|
|
151
|
+
});
|
|
152
|
+
},
|
|
120
153
|
} satisfies ToolRenderer<RetainRenderArgs, MemoryRetainDetails>;
|
|
121
154
|
|
|
122
155
|
/** Render recalled memories with an expandable body. */
|
|
@@ -133,9 +166,9 @@ export const recallToolRenderer = {
|
|
|
133
166
|
args?: QueryRenderArgs,
|
|
134
167
|
): Component {
|
|
135
168
|
if (result.isError) {
|
|
136
|
-
return new Text(formatErrorMessage(resultText(result) || "Recall failed", theme), 0, 0);
|
|
169
|
+
return new Text(formatErrorMessage(resultText(result).trim() || "Recall failed", theme), 0, 0);
|
|
137
170
|
}
|
|
138
|
-
const text = resultText(result);
|
|
171
|
+
const text = resultText(result).trim();
|
|
139
172
|
const match = text.match(/^Found (\d+) relevant/);
|
|
140
173
|
const found = match ? Number(match[1]) : 0;
|
|
141
174
|
const meta = [found > 0 ? `${found} found` : "no matches"];
|
|
@@ -165,6 +198,34 @@ export const recallToolRenderer = {
|
|
|
165
198
|
},
|
|
166
199
|
);
|
|
167
200
|
},
|
|
201
|
+
describeCall(args: QueryRenderArgs): NativeToolView {
|
|
202
|
+
return { head: toolHead("Recall", args.query?.trim()), inline: true };
|
|
203
|
+
},
|
|
204
|
+
describeResult(
|
|
205
|
+
result: { content: Array<{ type: string; text?: string }>; isError?: boolean },
|
|
206
|
+
_options: RenderResultOptions,
|
|
207
|
+
args?: QueryRenderArgs,
|
|
208
|
+
): NativeToolView | undefined {
|
|
209
|
+
return recallResultMemo.get(result, [], () => {
|
|
210
|
+
const query = args?.query?.trim();
|
|
211
|
+
const output = resultText(result).trim();
|
|
212
|
+
if (result.isError) return { ...errorView("Recall", output || "Recall failed", query), inline: true };
|
|
213
|
+
const found = Number(output.match(/^Found (\d+) relevant/)?.[1] ?? 0);
|
|
214
|
+
if (found === 0) return { head: toolHead("Recall", query, "no matches"), tone: "warning", inline: true };
|
|
215
|
+
// Collapsed keeps to the header; expanding reveals the recalled memories.
|
|
216
|
+
const memories = output
|
|
217
|
+
.replace(/^[^\n]*\n+/, "")
|
|
218
|
+
.split("\n")
|
|
219
|
+
.slice(0, PREVIEW_LIMITS.OUTPUT_EXPANDED)
|
|
220
|
+
.join("\n");
|
|
221
|
+
return {
|
|
222
|
+
head: toolHead("Recall", query, `${found} found`),
|
|
223
|
+
inline: true,
|
|
224
|
+
body: memories.trim() ? [text([span(plainText(memories), "muted")], { wrap: "word" })] : [],
|
|
225
|
+
preview: { lines: 0 },
|
|
226
|
+
};
|
|
227
|
+
});
|
|
228
|
+
},
|
|
168
229
|
} satisfies ToolRenderer<QueryRenderArgs, unknown>;
|
|
169
230
|
|
|
170
231
|
/** Render synthesized memory reflections. */
|
|
@@ -181,7 +242,7 @@ export const reflectToolRenderer = {
|
|
|
181
242
|
args?: QueryRenderArgs,
|
|
182
243
|
): Component {
|
|
183
244
|
if (result.isError) {
|
|
184
|
-
return new Text(formatErrorMessage(resultText(result) || "Reflect failed", theme), 0, 0);
|
|
245
|
+
return new Text(formatErrorMessage(resultText(result).trim() || "Reflect failed", theme), 0, 0);
|
|
185
246
|
}
|
|
186
247
|
const header = queryHeader(
|
|
187
248
|
"Reflect",
|
|
@@ -191,7 +252,7 @@ export const reflectToolRenderer = {
|
|
|
191
252
|
undefined,
|
|
192
253
|
theme.styledSymbol("tool.memory", "accent"),
|
|
193
254
|
);
|
|
194
|
-
const answer = resultText(result);
|
|
255
|
+
const answer = resultText(result).trim();
|
|
195
256
|
const answerLines = answer.split("\n").filter(line => line.trim().length > 0);
|
|
196
257
|
return createCachedComponent(
|
|
197
258
|
() => options.expanded,
|
|
@@ -212,6 +273,27 @@ export const reflectToolRenderer = {
|
|
|
212
273
|
},
|
|
213
274
|
);
|
|
214
275
|
},
|
|
276
|
+
describeCall(args: QueryRenderArgs): NativeToolView {
|
|
277
|
+
return { head: toolHead("Reflect", args.query?.trim()), inline: true };
|
|
278
|
+
},
|
|
279
|
+
describeResult(
|
|
280
|
+
result: { content: Array<{ type: string; text?: string }>; isError?: boolean },
|
|
281
|
+
_options: RenderResultOptions,
|
|
282
|
+
args?: QueryRenderArgs,
|
|
283
|
+
): NativeToolView | undefined {
|
|
284
|
+
return reflectResultMemo.get(result, [], () => {
|
|
285
|
+
const query = args?.query?.trim();
|
|
286
|
+
const answer = resultText(result).trim();
|
|
287
|
+
if (result.isError) return { ...errorView("Reflect", answer || "Reflect failed", query), inline: true };
|
|
288
|
+
const shown = answer.split("\n").slice(0, PREVIEW_LIMITS.OUTPUT_EXPANDED).join("\n").trim();
|
|
289
|
+
return {
|
|
290
|
+
head: toolHead("Reflect", query),
|
|
291
|
+
inline: true,
|
|
292
|
+
body: shown ? [md(shown, { role: "omp.memory.reflect" })] : [],
|
|
293
|
+
preview: { lines: PREVIEW_LIMITS.OUTPUT_COLLAPSED },
|
|
294
|
+
};
|
|
295
|
+
});
|
|
296
|
+
},
|
|
215
297
|
} satisfies ToolRenderer<QueryRenderArgs, unknown>;
|
|
216
298
|
|
|
217
299
|
/** Number of memories accepted by retain. */
|