@oh-my-pi/pi-tui 18.2.4 → 18.2.6
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 +23 -0
- package/README.md +43 -0
- package/dist/types/app-keybindings.d.ts +395 -0
- package/dist/types/apps/autoresearch-dashboard.d.ts +43 -0
- package/dist/types/apps/autoresearch-data.d.ts +15 -0
- package/dist/types/apps/cleanse-board.d.ts +66 -0
- package/dist/types/apps/cleanse-picker.d.ts +23 -0
- package/dist/types/apps/debug/log-formatting.d.ts +6 -0
- package/dist/types/apps/debug/log-viewer.d.ts +81 -0
- package/dist/types/apps/debug/protocol-probe.d.ts +42 -0
- package/dist/types/apps/debug/raw-sse-buffer.d.ts +58 -0
- package/dist/types/apps/debug/raw-sse.d.ts +26 -0
- package/dist/types/apps/debug/terminal-info.d.ts +34 -0
- package/dist/types/apps/debug/viewer-frame.d.ts +52 -0
- package/dist/types/apps/git/avatar.d.ts +9 -0
- package/dist/types/apps/git/colors.d.ts +49 -0
- package/dist/types/apps/git/diff-pane.d.ts +188 -0
- package/dist/types/apps/git/git-tui.d.ts +66 -0
- package/dist/types/apps/git/sidebar.d.ts +149 -0
- package/dist/types/apps/git/state.d.ts +117 -0
- package/dist/types/apps/if-bench-board.d.ts +75 -0
- package/dist/types/apps/live-visualizer.d.ts +33 -0
- package/dist/types/apps/ps-data.d.ts +51 -0
- package/dist/types/apps/ps-top.d.ts +33 -0
- package/dist/types/apps/session-picker.d.ts +26 -0
- package/dist/types/apps/setup-model-picker.d.ts +13 -0
- package/dist/types/apps/standalone-picker.d.ts +42 -0
- package/dist/types/autocomplete.d.ts +4 -0
- package/dist/types/chat/advisor-message.d.ts +11 -0
- package/dist/types/chat/assistant-message.d.ts +106 -0
- package/dist/types/chat/background-tan-message.d.ts +9 -0
- package/dist/types/chat/bash-execution.d.ts +47 -0
- package/dist/types/chat/cache-invalidation-marker.d.ts +50 -0
- package/dist/types/chat/chat-transcript-builder.d.ts +50 -0
- package/dist/types/chat/collab-prompt-message.d.ts +10 -0
- package/dist/types/chat/compaction-summary-message.d.ts +54 -0
- package/dist/types/chat/custom-message.d.ts +10 -0
- package/dist/types/chat/display-preferences.d.ts +13 -0
- package/dist/types/chat/eval-execution.d.ts +29 -0
- package/dist/types/chat/execution-shared.d.ts +51 -0
- package/dist/types/chat/extension-types.d.ts +28 -0
- package/dist/types/chat/hook-message.d.ts +10 -0
- package/dist/types/chat/image-loading.d.ts +46 -0
- package/dist/types/chat/late-diagnostics-message.d.ts +21 -0
- package/dist/types/chat/messages.d.ts +189 -0
- package/dist/types/chat/reaction.d.ts +30 -0
- package/dist/types/chat/read-target.d.ts +4 -0
- package/dist/types/chat/read-tool-group.d.ts +67 -0
- package/dist/types/chat/served-model-marker.d.ts +47 -0
- package/dist/types/chat/skill-message.d.ts +33 -0
- package/dist/types/chat/skill-title-input.d.ts +14 -0
- package/dist/types/chat/stripped-tool-calls-placeholder.d.ts +12 -0
- package/dist/types/chat/thinking-display.d.ts +12 -0
- package/dist/types/chat/todo-reminder.d.ts +13 -0
- package/dist/types/chat/tool-execution.d.ts +138 -0
- package/dist/types/chat/transcript-browser.d.ts +93 -0
- package/dist/types/chat/transcript-entry.d.ts +45 -0
- package/dist/types/chat/transcript-outline.d.ts +86 -0
- package/dist/types/chat/transcript-render-helpers.d.ts +92 -0
- package/dist/types/chat/ttsr-notification.d.ts +23 -0
- package/dist/types/chat/user-message.d.ts +52 -0
- package/dist/types/chrome/chat-block.d.ts +64 -0
- package/dist/types/chrome/collab-qrcode.d.ts +28 -0
- package/dist/types/chrome/context-thresholds.d.ts +10 -0
- package/dist/types/chrome/countdown-timer.d.ts +14 -0
- package/dist/types/chrome/diff.d.ts +14 -0
- package/dist/types/chrome/dynamic-border.d.ts +16 -0
- package/dist/types/chrome/error-block.d.ts +17 -0
- package/dist/types/chrome/form-theme.d.ts +3 -0
- package/dist/types/chrome/format.d.ts +12 -0
- package/dist/types/chrome/index.d.ts +20 -0
- package/dist/types/chrome/keybinding-hints.d.ts +40 -0
- package/dist/types/chrome/live-board.d.ts +23 -0
- package/dist/types/chrome/local-date.d.ts +4 -0
- package/dist/types/chrome/message-divider.d.ts +22 -0
- package/dist/types/chrome/message-frame.d.ts +52 -0
- package/dist/types/chrome/message-notice.d.ts +35 -0
- package/dist/types/chrome/overlay-box.d.ts +74 -0
- package/dist/types/chrome/qrcode.d.ts +48 -0
- package/dist/types/chrome/segment-track.d.ts +27 -0
- package/dist/types/chrome/select-list-mouse-routing.d.ts +4 -0
- package/dist/types/chrome/selector-helpers.d.ts +52 -0
- package/dist/types/chrome/shared.d.ts +5 -0
- package/dist/types/chrome/streaming-panel.d.ts +19 -0
- package/dist/types/chrome/tool-activity.d.ts +17 -0
- package/dist/types/chrome/transcript-container.d.ts +129 -0
- package/dist/types/chrome/transcript-status.d.ts +12 -0
- package/dist/types/chrome/visual-truncate.d.ts +19 -0
- package/dist/types/components/disclosure.d.ts +42 -0
- package/dist/types/components/form.d.ts +130 -0
- package/dist/types/components/key-value-list.d.ts +24 -0
- package/dist/types/components/layout/geometry.d.ts +73 -0
- package/dist/types/components/layout/row.d.ts +55 -0
- package/dist/types/components/layout/split-pane.d.ts +80 -0
- package/dist/types/components/layout/stack.d.ts +50 -0
- package/dist/types/components/menu-selection.d.ts +71 -0
- package/dist/types/components/metric.d.ts +44 -0
- package/dist/types/components/progress-bar.d.ts +36 -0
- package/dist/types/components/scroll-view.d.ts +53 -19
- package/dist/types/components/scroll-viewport.d.ts +46 -0
- package/dist/types/components/section.d.ts +19 -0
- package/dist/types/components/select-list.d.ts +46 -2
- package/dist/types/components/settings-list.d.ts +20 -0
- package/dist/types/components/table.d.ts +32 -0
- package/dist/types/components/tree-view.d.ts +130 -0
- package/dist/types/components/wizard-step.d.ts +60 -0
- package/dist/types/hotkeys-markdown.d.ts +7 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/keybinding-matchers.d.ts +35 -0
- package/dist/types/keys.d.ts +2 -2
- package/dist/types/lang-from-path.d.ts +9 -0
- package/dist/types/overlays/advisor-config.d.ts +114 -0
- package/dist/types/overlays/agent-activity.d.ts +41 -0
- package/dist/types/overlays/agent-hub-projection.d.ts +33 -0
- package/dist/types/overlays/agent-hub-renderer.d.ts +53 -0
- package/dist/types/overlays/agent-hub-types.d.ts +99 -0
- package/dist/types/overlays/agent-hub.d.ts +126 -0
- package/dist/types/overlays/agent-transcript-viewer.d.ts +71 -0
- package/dist/types/overlays/agents-hub.d.ts +72 -0
- package/dist/types/overlays/ask-dialog.d.ts +88 -0
- package/dist/types/overlays/bordered-loader.d.ts +11 -0
- package/dist/types/overlays/btw-history-panel.d.ts +29 -0
- package/dist/types/overlays/btw-history.d.ts +17 -0
- package/dist/types/overlays/btw-panel.d.ts +26 -0
- package/dist/types/overlays/cleanse-panel.d.ts +36 -0
- package/dist/types/overlays/codex-reset-fireworks.d.ts +52 -0
- package/dist/types/overlays/composer-shape-preview.d.ts +47 -0
- package/dist/types/overlays/composer-shape-registry.d.ts +50 -0
- package/dist/types/overlays/copy-selector.d.ts +48 -0
- package/dist/types/overlays/copy-targets.d.ts +63 -0
- package/dist/types/overlays/error-banner.d.ts +13 -0
- package/dist/types/overlays/extensions/display-text.d.ts +10 -0
- package/dist/types/overlays/extensions/extension-dashboard.d.ts +63 -0
- package/dist/types/overlays/extensions/extension-list.d.ts +54 -0
- package/dist/types/overlays/extensions/inspector-model.d.ts +109 -0
- package/dist/types/overlays/extensions/inspector-panel.d.ts +17 -0
- package/dist/types/overlays/extensions/live-tool-session.d.ts +28 -0
- package/dist/types/overlays/extensions/mcp-runtime.d.ts +107 -0
- package/dist/types/overlays/extensions/state-manager.d.ts +42 -0
- package/dist/types/overlays/extensions/types.d.ts +165 -0
- package/dist/types/overlays/history-search.d.ts +16 -0
- package/dist/types/overlays/hook-editor.d.ts +44 -0
- package/dist/types/overlays/hook-input.d.ts +20 -0
- package/dist/types/overlays/hook-selector.d.ts +71 -0
- package/dist/types/overlays/hub-frame.d.ts +77 -0
- package/dist/types/overlays/login-dialog.d.ts +43 -0
- package/dist/types/overlays/logout-account-selector.d.ts +15 -0
- package/dist/types/overlays/mcp-add-wizard.d.ts +87 -0
- package/dist/types/overlays/model-browser.d.ts +213 -0
- package/dist/types/overlays/model-hub.d.ts +72 -0
- package/dist/types/overlays/model-picker.d.ts +74 -0
- package/dist/types/overlays/model-selector.d.ts +52 -0
- package/dist/types/overlays/move-overlay.d.ts +39 -0
- package/dist/types/overlays/oauth-selector.d.ts +41 -0
- package/dist/types/overlays/omfg-panel.d.ts +20 -0
- package/dist/types/overlays/pause-screen.d.ts +43 -0
- package/dist/types/overlays/plan-review-overlay.d.ts +89 -0
- package/dist/types/overlays/plan-save-overlay.d.ts +19 -0
- package/dist/types/overlays/plan-toc.d.ts +41 -0
- package/dist/types/overlays/plugin-selector.d.ts +28 -0
- package/dist/types/overlays/plugin-settings.d.ts +180 -0
- package/dist/types/overlays/queue-mode-selector.d.ts +11 -0
- package/dist/types/overlays/reset-usage-selector.d.ts +23 -0
- package/dist/types/overlays/rewind-selector.d.ts +61 -0
- package/dist/types/overlays/running-subagent-badge.d.ts +6 -0
- package/dist/types/overlays/session-account-selector.d.ts +24 -0
- package/dist/types/overlays/session-info-overlay.d.ts +17 -0
- package/dist/types/overlays/session-observer-registry.d.ts +77 -0
- package/dist/types/overlays/session-selector.d.ts +131 -0
- package/dist/types/overlays/settings-defs.d.ts +119 -0
- package/dist/types/overlays/settings-selector.d.ts +73 -0
- package/dist/types/overlays/show-images-selector.d.ts +11 -0
- package/dist/types/overlays/snapcompact-shape-preview.d.ts +31 -0
- package/dist/types/overlays/theme-selector.d.ts +12 -0
- package/dist/types/overlays/thinking-selector.d.ts +12 -0
- package/dist/types/overlays/tiny-title-download-progress.d.ts +21 -0
- package/dist/types/overlays/tree-selector.d.ts +92 -0
- package/dist/types/overlays/usage-dashboard.d.ts +94 -0
- package/dist/types/overlays/usage-display.d.ts +5 -0
- package/dist/types/overlays/usage-row.d.ts +17 -0
- package/dist/types/prompt/attachment-chips.d.ts +19 -0
- package/dist/types/prompt/composer-attachments.d.ts +71 -0
- package/dist/types/prompt/composer-cache.d.ts +37 -0
- package/dist/types/prompt/composer.d.ts +159 -0
- package/dist/types/prompt/custom-editor.d.ts +261 -0
- package/dist/types/prompt/editor-top-gap.d.ts +18 -0
- package/dist/types/prompt/emoji-autocomplete.d.ts +16 -0
- package/dist/types/prompt/github-ref-autocomplete.d.ts +35 -0
- package/dist/types/prompt/gradient-highlight.d.ts +32 -0
- package/dist/types/prompt/image-format.d.ts +4 -0
- package/dist/types/prompt/image-references.d.ts +26 -0
- package/dist/types/prompt/interactive-context-helpers.d.ts +43 -0
- package/dist/types/prompt/internal-url-autocomplete.d.ts +56 -0
- package/dist/types/prompt/macos-spelling.d.ts +44 -0
- package/dist/types/prompt/magic-keyword-boundary.d.ts +9 -0
- package/dist/types/prompt/magic-keywords.d.ts +26 -0
- package/dist/types/prompt/markdown-prose.d.ts +15 -0
- package/dist/types/prompt/model-mention-autocomplete.d.ts +25 -0
- package/dist/types/prompt/model-mention-syntax.d.ts +24 -0
- package/dist/types/prompt/orchestrate.d.ts +13 -0
- package/dist/types/prompt/prompt-action-autocomplete.d.ts +56 -0
- package/dist/types/prompt/queue-input.d.ts +8 -0
- package/dist/types/prompt/skill-tokens.d.ts +13 -0
- package/dist/types/prompt/tools-markdown.d.ts +12 -0
- package/dist/types/prompt/ultrathink.d.ts +13 -0
- package/dist/types/prompt/usage-amounts.d.ts +26 -0
- package/dist/types/prompt/video.d.ts +18 -0
- package/dist/types/prompt/welcome.d.ts +83 -0
- package/dist/types/prompt/workflow.d.ts +13 -0
- package/dist/types/render/code-cell.d.ts +51 -0
- package/dist/types/render/file-list.d.ts +22 -0
- package/dist/types/render/hyperlink.d.ts +80 -0
- package/dist/types/render/index.d.ts +16 -0
- package/dist/types/render/output-block.d.ts +54 -0
- package/dist/types/render/output-pane.d.ts +80 -0
- package/dist/types/render/render-utils.d.ts +312 -0
- package/dist/types/render/sixel.d.ts +21 -0
- package/dist/types/render/status-line.d.ts +23 -0
- package/dist/types/render/tool-card.d.ts +71 -0
- package/dist/types/render/tree-list.d.ts +29 -0
- package/dist/types/render/types.d.ts +17 -0
- package/dist/types/render/utils.d.ts +43 -0
- package/dist/types/render/width-aware-text.d.ts +23 -0
- package/dist/types/setup/lazy.d.ts +3 -0
- package/dist/types/setup/scenes/composer.d.ts +3 -0
- package/dist/types/setup/scenes/glyph.d.ts +3 -0
- package/dist/types/setup/scenes/model.d.ts +3 -0
- package/dist/types/setup/scenes/outro.d.ts +2 -0
- package/dist/types/setup/scenes/providers.d.ts +3 -0
- package/dist/types/setup/scenes/sign-in.d.ts +21 -0
- package/dist/types/setup/scenes/splash.d.ts +11 -0
- package/dist/types/setup/scenes/theme.d.ts +3 -0
- package/dist/types/setup/scenes/types.d.ts +110 -0
- package/dist/types/setup/scenes/web-search.d.ts +22 -0
- package/dist/types/setup/setup-version.d.ts +11 -0
- package/dist/types/setup/startup-splash.d.ts +9 -0
- package/dist/types/setup/wizard-overlay.d.ts +16 -0
- package/dist/types/setup/wizard.d.ts +25 -0
- package/dist/types/status-line/component.d.ts +182 -0
- package/dist/types/status-line/context-usage.d.ts +156 -0
- package/dist/types/status-line/footer.d.ts +30 -0
- package/dist/types/status-line/git-utils.d.ts +22 -0
- package/dist/types/status-line/host.d.ts +129 -0
- package/dist/types/status-line/index.d.ts +6 -0
- package/dist/types/status-line/loop.d.ts +18 -0
- package/dist/types/status-line/metrics.d.ts +21 -0
- package/dist/types/status-line/presets.d.ts +3 -0
- package/dist/types/status-line/schema.d.ts +15 -0
- package/dist/types/status-line/segments.d.ts +5 -0
- package/dist/types/status-line/separators.d.ts +3 -0
- package/dist/types/status-line/types.d.ts +236 -0
- package/dist/types/stdin-buffer.d.ts +4 -0
- package/dist/types/theme/color.d.ts +24 -0
- package/dist/types/theme/defaults/index.d.ts +9489 -0
- package/dist/types/theme/index.d.ts +4 -0
- package/dist/types/theme/loader.d.ts +23 -0
- package/dist/types/theme/mermaid-cache.d.ts +26 -0
- package/dist/types/theme/schema-validation.d.ts +3 -0
- package/dist/types/theme/schema.d.ts +25 -0
- package/dist/types/theme/session-color.d.ts +43 -0
- package/dist/types/theme/shimmer.d.ts +44 -0
- package/dist/types/theme/symbols.d.ts +34 -0
- package/dist/types/theme/theme-class.d.ts +299 -0
- package/dist/types/theme/theme.d.ts +111 -0
- package/dist/types/theme/tui-adapters.d.ts +30 -0
- package/dist/types/thinking.d.ts +165 -0
- package/dist/types/tools/agent-tree.d.ts +36 -0
- package/dist/types/tools/ask.d.ts +67 -0
- package/dist/types/tools/ast-edit.d.ts +53 -0
- package/dist/types/tools/ast-grep.d.ts +52 -0
- package/dist/types/tools/autoresearch.d.ts +156 -0
- package/dist/types/tools/bash-interactive.d.ts +28 -0
- package/dist/types/tools/bash.d.ts +103 -0
- package/dist/types/tools/conflict-detect.d.ts +43 -0
- package/dist/types/tools/debug.d.ts +60 -0
- package/dist/types/tools/default-renderer.d.ts +24 -0
- package/dist/types/tools/edit.d.ts +158 -0
- package/dist/types/tools/eval-format/code-mode-declarations.d.ts +5 -0
- package/dist/types/tools/eval-format/index.d.ts +5 -0
- package/dist/types/tools/eval-format/javascript.d.ts +2 -0
- package/dist/types/tools/eval-format/python.d.ts +2 -0
- package/dist/types/tools/eval.d.ts +94 -0
- package/dist/types/tools/fetch.d.ts +42 -0
- package/dist/types/tools/gh-format.d.ts +8 -0
- package/dist/types/tools/github.d.ts +144 -0
- package/dist/types/tools/glob.d.ts +44 -0
- package/dist/types/tools/goal.d.ts +42 -0
- package/dist/types/tools/grep.d.ts +64 -0
- package/dist/types/tools/grouped-file-output.d.ts +71 -0
- package/dist/types/tools/hashline-format.d.ts +28 -0
- package/dist/types/tools/hub.d.ts +340 -0
- package/dist/types/tools/index.d.ts +4 -0
- package/dist/types/tools/json-tree.d.ts +59 -0
- package/dist/types/tools/line-ranges.d.ts +29 -0
- package/dist/types/tools/list-limit.d.ts +15 -0
- package/dist/types/tools/lsp.d.ts +72 -0
- package/dist/types/tools/match-line-format.d.ts +11 -0
- package/dist/types/tools/mcp.d.ts +81 -0
- package/dist/types/tools/memory.d.ts +67 -0
- package/dist/types/tools/output-meta.d.ts +151 -0
- package/dist/types/tools/read.d.ts +139 -0
- package/dist/types/tools/renderer.d.ts +98 -0
- package/dist/types/tools/report-tool-issue.d.ts +8 -0
- package/dist/types/tools/resolve.d.ts +47 -0
- package/dist/types/tools/streaming-output.d.ts +282 -0
- package/dist/types/tools/subprocess.d.ts +24 -0
- package/dist/types/tools/task-repair-args.d.ts +53 -0
- package/dist/types/tools/task-yield-assembly.d.ts +20 -0
- package/dist/types/tools/task.d.ts +425 -0
- package/dist/types/tools/terminal-output.d.ts +8 -0
- package/dist/types/tools/think.d.ts +13 -0
- package/dist/types/tools/todo.d.ts +118 -0
- package/dist/types/tools/tool-errors.d.ts +7 -0
- package/dist/types/tools/vibe.d.ts +120 -0
- package/dist/types/tools/web-search.d.ts +195 -0
- package/dist/types/tools/write.d.ts +76 -0
- package/dist/types/tools/xd-url.d.ts +13 -0
- package/dist/types/tools/xdev.d.ts +52 -0
- package/dist/types/tui.d.ts +18 -0
- package/dist/types/utils.d.ts +2 -0
- package/package.json +37 -3
- package/src/app-keybindings.ts +760 -0
- package/src/apps/autoresearch-dashboard.ts +500 -0
- package/src/apps/autoresearch-data.ts +64 -0
- package/src/apps/cleanse-board.ts +341 -0
- package/src/apps/cleanse-picker.ts +57 -0
- package/src/apps/debug/log-formatting.ts +53 -0
- package/src/apps/debug/log-viewer.ts +868 -0
- package/src/apps/debug/protocol-probe.ts +267 -0
- package/src/apps/debug/raw-sse-buffer.ts +449 -0
- package/src/apps/debug/raw-sse.ts +282 -0
- package/src/apps/debug/terminal-info.ts +115 -0
- package/src/apps/debug/viewer-frame.ts +174 -0
- package/src/apps/git/avatar.ts +52 -0
- package/src/apps/git/colors.ts +109 -0
- package/src/apps/git/diff-pane.ts +1512 -0
- package/src/apps/git/git-tui.ts +889 -0
- package/src/apps/git/sidebar.ts +1204 -0
- package/src/apps/git/state.ts +113 -0
- package/src/apps/if-bench-board.ts +324 -0
- package/src/apps/live-visualizer.ts +238 -0
- package/src/apps/ps-data.ts +116 -0
- package/src/apps/ps-top.ts +422 -0
- package/src/apps/session-picker.ts +95 -0
- package/src/apps/setup-model-picker.ts +21 -0
- package/src/apps/standalone-picker.ts +111 -0
- package/src/autocomplete.ts +9 -13
- package/src/chat/advisor-message.ts +175 -0
- package/src/chat/assistant-message.ts +1214 -0
- package/src/chat/background-tan-message.ts +35 -0
- package/src/chat/bash-execution.ts +394 -0
- package/src/chat/cache-invalidation-marker.ts +94 -0
- package/src/chat/chat-transcript-builder.ts +593 -0
- package/src/chat/collab-prompt-message.ts +34 -0
- package/src/chat/compaction-summary-message.ts +261 -0
- package/src/chat/custom-message.ts +23 -0
- package/src/chat/display-preferences.ts +24 -0
- package/src/chat/eval-execution.ts +172 -0
- package/src/chat/execution-shared.ts +113 -0
- package/src/chat/extension-types.ts +46 -0
- package/src/chat/hook-message.ts +20 -0
- package/src/chat/image-loading.ts +122 -0
- package/src/chat/late-diagnostics-message.ts +92 -0
- package/src/chat/messages.ts +305 -0
- package/src/chat/reaction.ts +65 -0
- package/src/chat/read-target.ts +7 -0
- package/src/chat/read-tool-group.ts +873 -0
- package/src/chat/served-model-marker.ts +91 -0
- package/src/chat/skill-message.ts +220 -0
- package/src/chat/skill-title-input.ts +41 -0
- package/src/chat/stripped-tool-calls-placeholder.ts +35 -0
- package/src/chat/thinking-display.ts +312 -0
- package/src/chat/todo-reminder.ts +33 -0
- package/src/chat/tool-execution.ts +1395 -0
- package/src/chat/transcript-browser.ts +268 -0
- package/src/chat/transcript-entry.ts +96 -0
- package/src/chat/transcript-outline.ts +260 -0
- package/src/chat/transcript-render-helpers.ts +315 -0
- package/src/chat/ttsr-notification.ts +123 -0
- package/src/chat/user-message.ts +287 -0
- package/src/chrome/chat-block.ts +110 -0
- package/src/chrome/collab-qrcode.ts +74 -0
- package/src/chrome/context-thresholds.ts +85 -0
- package/src/chrome/countdown-timer.ts +74 -0
- package/src/chrome/diff.ts +266 -0
- package/src/chrome/dynamic-border.ts +36 -0
- package/src/chrome/error-block.ts +63 -0
- package/src/chrome/form-theme.ts +10 -0
- package/src/chrome/format.ts +66 -0
- package/src/chrome/index.ts +21 -0
- package/src/chrome/keybinding-hints.ts +55 -0
- package/src/chrome/live-board.ts +123 -0
- package/src/chrome/local-date.ts +20 -0
- package/src/chrome/message-divider.ts +51 -0
- package/src/chrome/message-frame.ts +164 -0
- package/src/chrome/message-notice.ts +103 -0
- package/src/chrome/overlay-box.ts +301 -0
- package/src/chrome/qrcode.ts +539 -0
- package/src/chrome/segment-track.ts +86 -0
- package/src/chrome/select-list-mouse-routing.ts +11 -0
- package/src/chrome/selector-helpers.ts +119 -0
- package/src/chrome/shared.ts +27 -0
- package/src/chrome/streaming-panel.ts +72 -0
- package/src/chrome/tool-activity.ts +44 -0
- package/src/chrome/transcript-container.ts +902 -0
- package/src/chrome/transcript-status.ts +27 -0
- package/src/chrome/visual-truncate.ts +70 -0
- package/src/components/disclosure.ts +235 -0
- package/src/components/editor.ts +10 -12
- package/src/components/form.ts +566 -0
- package/src/components/input.ts +6 -27
- package/src/components/key-value-list.ts +88 -0
- package/src/components/layout/geometry.ts +202 -0
- package/src/components/layout/row.ts +283 -0
- package/src/components/layout/split-pane.ts +349 -0
- package/src/components/layout/stack.ts +261 -0
- package/src/components/markdown.ts +16 -12
- package/src/components/menu-selection.ts +248 -0
- package/src/components/metric.ts +132 -0
- package/src/components/progress-bar.ts +140 -0
- package/src/components/scroll-view.ts +372 -70
- package/src/components/scroll-viewport.ts +154 -0
- package/src/components/section.ts +77 -0
- package/src/components/select-list.ts +238 -159
- package/src/components/settings-list.ts +103 -80
- package/src/components/table.ts +127 -0
- package/src/components/tree-view.ts +481 -0
- package/src/components/wizard-step.ts +229 -0
- package/src/deccara.ts +1 -3
- package/src/hotkeys-markdown.ts +100 -0
- package/src/index.ts +18 -0
- package/src/keybinding-matchers.ts +99 -0
- package/src/keys.ts +2 -2
- package/src/lang-from-path.ts +252 -0
- package/src/overlays/advisor-config.ts +761 -0
- package/src/overlays/agent-activity.ts +113 -0
- package/src/overlays/agent-hub-projection.ts +250 -0
- package/src/overlays/agent-hub-renderer.ts +281 -0
- package/src/overlays/agent-hub-types.ts +74 -0
- package/src/overlays/agent-hub.ts +1562 -0
- package/src/overlays/agent-transcript-viewer.ts +669 -0
- package/src/overlays/agents-hub.ts +1203 -0
- package/src/overlays/ask-dialog.ts +1202 -0
- package/src/overlays/bordered-loader.ts +41 -0
- package/src/overlays/btw-history-panel.ts +591 -0
- package/src/overlays/btw-history.ts +33 -0
- package/src/overlays/btw-panel.ts +167 -0
- package/src/overlays/cleanse-panel.ts +167 -0
- package/src/overlays/codex-reset-fireworks.ts +375 -0
- package/src/overlays/composer-shape-preview.ts +137 -0
- package/src/overlays/composer-shape-registry.ts +82 -0
- package/src/overlays/copy-selector.ts +618 -0
- package/src/overlays/copy-targets.ts +210 -0
- package/src/overlays/error-banner.ts +39 -0
- package/src/overlays/extensions/display-text.ts +39 -0
- package/src/overlays/extensions/extension-dashboard.ts +645 -0
- package/src/overlays/extensions/extension-list.ts +667 -0
- package/src/overlays/extensions/inspector-model.ts +484 -0
- package/src/overlays/extensions/inspector-panel.ts +669 -0
- package/src/overlays/extensions/live-tool-session.ts +67 -0
- package/src/overlays/extensions/mcp-runtime.ts +289 -0
- package/src/overlays/extensions/state-manager.ts +337 -0
- package/src/overlays/extensions/types.ts +208 -0
- package/src/overlays/history-search.ts +268 -0
- package/src/overlays/hook-editor.ts +272 -0
- package/src/overlays/hook-input.ts +84 -0
- package/src/overlays/hook-selector.ts +635 -0
- package/src/overlays/hub-frame.ts +262 -0
- package/src/overlays/login-dialog.ts +231 -0
- package/src/overlays/logout-account-selector.ts +115 -0
- package/src/overlays/mcp-add-wizard.ts +1436 -0
- package/src/overlays/model-browser.ts +1176 -0
- package/src/overlays/model-hub.ts +2279 -0
- package/src/overlays/model-picker.ts +285 -0
- package/src/overlays/model-selector.ts +107 -0
- package/src/overlays/move-overlay.ts +197 -0
- package/src/overlays/oauth-selector.ts +446 -0
- package/src/overlays/omfg-panel.ts +136 -0
- package/src/overlays/pause-screen.ts +198 -0
- package/src/overlays/plan-review-overlay.ts +1227 -0
- package/src/overlays/plan-save-overlay.ts +74 -0
- package/src/overlays/plan-toc.ts +139 -0
- package/src/overlays/plugin-selector.ts +97 -0
- package/src/overlays/plugin-settings.ts +839 -0
- package/src/overlays/queue-mode-selector.ts +55 -0
- package/src/overlays/reset-usage-selector.ts +170 -0
- package/src/overlays/rewind-selector.ts +499 -0
- package/src/overlays/running-subagent-badge.ts +19 -0
- package/src/overlays/session-account-selector.ts +68 -0
- package/src/overlays/session-info-overlay.ts +96 -0
- package/src/overlays/session-observer-registry.ts +289 -0
- package/src/overlays/session-selector.ts +1137 -0
- package/src/overlays/settings-defs.ts +315 -0
- package/src/overlays/settings-selector.ts +1415 -0
- package/src/overlays/show-images-selector.ts +44 -0
- package/src/overlays/snapcompact-shape-preview-doc.md +14 -0
- package/src/overlays/snapcompact-shape-preview.ts +192 -0
- package/src/overlays/theme-selector.ts +62 -0
- package/src/overlays/thinking-selector.ts +51 -0
- package/src/overlays/tiny-title-download-progress.ts +102 -0
- package/src/overlays/tree-selector.ts +1121 -0
- package/src/overlays/usage-dashboard.ts +629 -0
- package/src/overlays/usage-display.ts +45 -0
- package/src/overlays/usage-row.ts +118 -0
- package/src/prompt/attachment-chips.ts +201 -0
- package/src/prompt/composer-attachments.ts +280 -0
- package/src/prompt/composer-cache.ts +304 -0
- package/src/prompt/composer.ts +934 -0
- package/src/prompt/custom-editor.ts +1392 -0
- package/src/prompt/data/emojis.json +1 -0
- package/src/prompt/editor-top-gap.ts +28 -0
- package/src/prompt/emoji-autocomplete.ts +285 -0
- package/src/prompt/github-ref-autocomplete.ts +75 -0
- package/src/prompt/gradient-highlight.ts +101 -0
- package/src/prompt/image-format.ts +28 -0
- package/src/prompt/image-references.ts +102 -0
- package/src/prompt/interactive-context-helpers.ts +126 -0
- package/src/prompt/internal-url-autocomplete.ts +155 -0
- package/src/prompt/macos-spelling.ts +456 -0
- package/src/prompt/magic-keyword-boundary.ts +23 -0
- package/src/prompt/magic-keywords.ts +42 -0
- package/src/prompt/markdown-prose.ts +245 -0
- package/src/prompt/model-mention-autocomplete.ts +94 -0
- package/src/prompt/model-mention-syntax.ts +41 -0
- package/src/prompt/orchestrate.ts +26 -0
- package/src/prompt/prompt-action-autocomplete.ts +337 -0
- package/src/prompt/queue-input.ts +132 -0
- package/src/prompt/skill-tokens.ts +36 -0
- package/src/prompt/tips.txt +27 -0
- package/src/prompt/tools-markdown.ts +29 -0
- package/src/prompt/ultrathink.ts +26 -0
- package/src/prompt/usage-amounts.ts +99 -0
- package/src/prompt/video.ts +47 -0
- package/src/prompt/welcome.ts +605 -0
- package/src/prompt/workflow.ts +26 -0
- package/src/render/code-cell.ts +244 -0
- package/src/render/file-list.ts +58 -0
- package/src/render/hyperlink.ts +192 -0
- package/src/render/index.ts +17 -0
- package/src/render/output-block.ts +267 -0
- package/src/render/output-pane.ts +299 -0
- package/src/render/render-utils.ts +1182 -0
- package/src/render/sixel.ts +69 -0
- package/src/render/status-line.ts +55 -0
- package/src/render/tool-card.ts +272 -0
- package/src/render/tree-list.ts +188 -0
- package/src/render/types.ts +19 -0
- package/src/render/utils.ts +109 -0
- package/src/render/width-aware-text.ts +60 -0
- package/src/setup/lazy.ts +17 -0
- package/src/setup/scenes/composer.ts +127 -0
- package/src/setup/scenes/glyph.ts +120 -0
- package/src/setup/scenes/model.ts +138 -0
- package/src/setup/scenes/outro.ts +24 -0
- package/src/setup/scenes/providers.ts +107 -0
- package/src/setup/scenes/sign-in.ts +373 -0
- package/src/setup/scenes/splash.ts +192 -0
- package/src/setup/scenes/theme.ts +343 -0
- package/src/setup/scenes/types.ts +111 -0
- package/src/setup/scenes/web-search.ts +165 -0
- package/src/setup/setup-version.ts +11 -0
- package/src/setup/startup-splash.ts +107 -0
- package/src/setup/wizard-overlay.ts +319 -0
- package/src/setup/wizard.ts +101 -0
- package/src/status-line/component.ts +3003 -0
- package/src/status-line/context-usage.ts +688 -0
- package/src/status-line/footer.ts +323 -0
- package/src/status-line/git-utils.ts +42 -0
- package/src/status-line/host.ts +97 -0
- package/src/status-line/index.ts +6 -0
- package/src/status-line/loop.ts +28 -0
- package/src/status-line/metrics.ts +94 -0
- package/src/status-line/presets.ts +107 -0
- package/src/status-line/schema.ts +57 -0
- package/src/status-line/segments.ts +934 -0
- package/src/status-line/separators.ts +55 -0
- package/src/status-line/types.ts +227 -0
- package/src/stdin-buffer.ts +4 -2
- package/src/theme/color.ts +95 -0
- package/src/theme/dark.json +95 -0
- package/src/theme/defaults/alabaster.json +93 -0
- package/src/theme/defaults/amethyst.json +96 -0
- package/src/theme/defaults/anthracite.json +93 -0
- package/src/theme/defaults/basalt.json +91 -0
- package/src/theme/defaults/birch.json +95 -0
- package/src/theme/defaults/dark-abyss.json +91 -0
- package/src/theme/defaults/dark-arctic.json +104 -0
- package/src/theme/defaults/dark-aurora.json +95 -0
- package/src/theme/defaults/dark-catppuccin.json +107 -0
- package/src/theme/defaults/dark-cavern.json +91 -0
- package/src/theme/defaults/dark-celestial.json +106 -0
- package/src/theme/defaults/dark-copper.json +95 -0
- package/src/theme/defaults/dark-cosmos.json +90 -0
- package/src/theme/defaults/dark-cyberpunk.json +102 -0
- package/src/theme/defaults/dark-dracula.json +98 -0
- package/src/theme/defaults/dark-eclipse.json +91 -0
- package/src/theme/defaults/dark-ember.json +95 -0
- package/src/theme/defaults/dark-equinox.json +90 -0
- package/src/theme/defaults/dark-forest.json +96 -0
- package/src/theme/defaults/dark-github.json +105 -0
- package/src/theme/defaults/dark-gruvbox.json +112 -0
- package/src/theme/defaults/dark-lavender.json +95 -0
- package/src/theme/defaults/dark-lunar.json +89 -0
- package/src/theme/defaults/dark-midnight.json +95 -0
- package/src/theme/defaults/dark-monochrome.json +94 -0
- package/src/theme/defaults/dark-monokai.json +98 -0
- package/src/theme/defaults/dark-nebula.json +90 -0
- package/src/theme/defaults/dark-nord.json +98 -0
- package/src/theme/defaults/dark-ocean.json +101 -0
- package/src/theme/defaults/dark-one.json +100 -0
- package/src/theme/defaults/dark-poimandres.json +115 -0
- package/src/theme/defaults/dark-rainforest.json +91 -0
- package/src/theme/defaults/dark-reef.json +91 -0
- package/src/theme/defaults/dark-retro.json +92 -0
- package/src/theme/defaults/dark-rose-pine.json +96 -0
- package/src/theme/defaults/dark-sakura.json +95 -0
- package/src/theme/defaults/dark-slate.json +95 -0
- package/src/theme/defaults/dark-solarized.json +97 -0
- package/src/theme/defaults/dark-solstice.json +90 -0
- package/src/theme/defaults/dark-starfall.json +91 -0
- package/src/theme/defaults/dark-sunset.json +99 -0
- package/src/theme/defaults/dark-swamp.json +90 -0
- package/src/theme/defaults/dark-synthwave.json +103 -0
- package/src/theme/defaults/dark-taiga.json +91 -0
- package/src/theme/defaults/dark-terminal.json +95 -0
- package/src/theme/defaults/dark-tokyo-night.json +101 -0
- package/src/theme/defaults/dark-tundra.json +91 -0
- package/src/theme/defaults/dark-twilight.json +91 -0
- package/src/theme/defaults/dark-volcanic.json +91 -0
- package/src/theme/defaults/graphite.json +92 -0
- package/src/theme/defaults/index.ts +201 -0
- package/src/theme/defaults/light-arctic.json +107 -0
- package/src/theme/defaults/light-aurora-day.json +91 -0
- package/src/theme/defaults/light-canyon.json +91 -0
- package/src/theme/defaults/light-catppuccin.json +106 -0
- package/src/theme/defaults/light-cirrus.json +90 -0
- package/src/theme/defaults/light-coral.json +95 -0
- package/src/theme/defaults/light-cyberpunk.json +96 -0
- package/src/theme/defaults/light-dawn.json +90 -0
- package/src/theme/defaults/light-dunes.json +91 -0
- package/src/theme/defaults/light-eucalyptus.json +95 -0
- package/src/theme/defaults/light-forest.json +100 -0
- package/src/theme/defaults/light-frost.json +95 -0
- package/src/theme/defaults/light-github.json +115 -0
- package/src/theme/defaults/light-glacier.json +91 -0
- package/src/theme/defaults/light-gruvbox.json +108 -0
- package/src/theme/defaults/light-haze.json +90 -0
- package/src/theme/defaults/light-honeycomb.json +95 -0
- package/src/theme/defaults/light-lagoon.json +91 -0
- package/src/theme/defaults/light-lavender.json +95 -0
- package/src/theme/defaults/light-meadow.json +91 -0
- package/src/theme/defaults/light-mint.json +95 -0
- package/src/theme/defaults/light-monochrome.json +101 -0
- package/src/theme/defaults/light-ocean.json +99 -0
- package/src/theme/defaults/light-one.json +99 -0
- package/src/theme/defaults/light-opal.json +91 -0
- package/src/theme/defaults/light-orchard.json +91 -0
- package/src/theme/defaults/light-paper.json +95 -0
- package/src/theme/defaults/light-poimandres.json +115 -0
- package/src/theme/defaults/light-prism.json +90 -0
- package/src/theme/defaults/light-retro.json +98 -0
- package/src/theme/defaults/light-sand.json +95 -0
- package/src/theme/defaults/light-savanna.json +91 -0
- package/src/theme/defaults/light-solarized.json +102 -0
- package/src/theme/defaults/light-soleil.json +90 -0
- package/src/theme/defaults/light-sunset.json +99 -0
- package/src/theme/defaults/light-synthwave.json +98 -0
- package/src/theme/defaults/light-tokyo-night.json +111 -0
- package/src/theme/defaults/light-wetland.json +91 -0
- package/src/theme/defaults/light-zenith.json +89 -0
- package/src/theme/defaults/limestone.json +94 -0
- package/src/theme/defaults/mahogany.json +97 -0
- package/src/theme/defaults/marble.json +93 -0
- package/src/theme/defaults/obsidian.json +91 -0
- package/src/theme/defaults/onyx.json +91 -0
- package/src/theme/defaults/pearl.json +93 -0
- package/src/theme/defaults/porcelain.json +91 -0
- package/src/theme/defaults/quartz.json +96 -0
- package/src/theme/defaults/sandstone.json +95 -0
- package/src/theme/defaults/titanium.json +90 -0
- package/src/theme/index.ts +5 -0
- package/src/theme/light.json +93 -0
- package/src/theme/loader.ts +200 -0
- package/src/theme/mermaid-cache.ts +92 -0
- package/src/theme/schema-validation.ts +119 -0
- package/src/theme/schema.ts +168 -0
- package/src/theme/session-color.ts +253 -0
- package/src/theme/shimmer.ts +307 -0
- package/src/theme/symbols.ts +1433 -0
- package/src/theme/theme-class.ts +787 -0
- package/src/theme/theme-schema.json +463 -0
- package/src/theme/theme.ts +810 -0
- package/src/theme/tui-adapters.ts +339 -0
- package/src/thinking.ts +380 -0
- package/src/tools/agent-tree.ts +128 -0
- package/src/tools/ask.ts +482 -0
- package/src/tools/ast-edit.ts +210 -0
- package/src/tools/ast-grep.ts +171 -0
- package/src/tools/autoresearch.ts +287 -0
- package/src/tools/bash-interactive.ts +295 -0
- package/src/tools/bash.ts +468 -0
- package/src/tools/conflict-detect.ts +77 -0
- package/src/tools/debug.ts +167 -0
- package/src/tools/default-renderer.ts +172 -0
- package/src/tools/edit.ts +1258 -0
- package/src/tools/eval-format/code-mode-declarations.ts +61 -0
- package/src/tools/eval-format/index.ts +16 -0
- package/src/tools/eval-format/javascript.ts +952 -0
- package/src/tools/eval-format/python.ts +544 -0
- package/src/tools/eval.ts +835 -0
- package/src/tools/fetch.ts +226 -0
- package/src/tools/gh-format.ts +18 -0
- package/src/tools/github.ts +686 -0
- package/src/tools/glob.ts +213 -0
- package/src/tools/goal.ts +153 -0
- package/src/tools/grep.ts +385 -0
- package/src/tools/grouped-file-output.ts +211 -0
- package/src/tools/hashline-format.ts +59 -0
- package/src/tools/hub.ts +1488 -0
- package/src/tools/index.ts +71 -0
- package/src/tools/json-tree.ts +388 -0
- package/src/tools/line-ranges.ts +98 -0
- package/src/tools/list-limit.ts +43 -0
- package/src/tools/lsp.ts +702 -0
- package/src/tools/match-line-format.ts +20 -0
- package/src/tools/mcp.ts +309 -0
- package/src/tools/memory.ts +220 -0
- package/src/tools/output-meta.ts +367 -0
- package/src/tools/read.ts +628 -0
- package/src/tools/renderer.ts +107 -0
- package/src/tools/report-tool-issue.ts +13 -0
- package/src/tools/resolve.ts +139 -0
- package/src/tools/streaming-output.ts +1576 -0
- package/src/tools/subprocess.ts +39 -0
- package/src/tools/task-repair-args.ts +118 -0
- package/src/tools/task-yield-assembly.ts +147 -0
- package/src/tools/task.ts +2110 -0
- package/src/tools/terminal-output.ts +153 -0
- package/src/tools/think.ts +28 -0
- package/src/tools/todo.ts +580 -0
- package/src/tools/tool-errors.ts +15 -0
- package/src/tools/vibe.ts +420 -0
- package/src/tools/web-search.ts +409 -0
- package/src/tools/write.ts +511 -0
- package/src/tools/xd-url.ts +28 -0
- package/src/tools/xdev.ts +201 -0
- package/src/tui.ts +57 -4
- package/src/utils.ts +8 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { $env, $flag } from "@oh-my-pi/pi-utils";
|
|
2
|
+
|
|
3
|
+
const SIXEL_START_REGEX = /\x1bP(?:[0-9;]*)q/u;
|
|
4
|
+
const SIXEL_END_SEQUENCE = "\x1b\\";
|
|
5
|
+
const SIXEL_END_BELL = "\x07";
|
|
6
|
+
const SIXEL_SEQUENCE_REGEX = /\x1bP(?:[0-9;]*)q[\s\S]*?(?:\x1b\\|\x07)/gu;
|
|
7
|
+
const SIXEL_PLACEHOLDER_PREFIX = "__OMP_SIXEL_SEQUENCE_";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Returns whether SIXEL passthrough is explicitly enabled.
|
|
11
|
+
*
|
|
12
|
+
* Both gates must be enabled to preserve SIXEL control sequences:
|
|
13
|
+
* - PI_FORCE_IMAGE_PROTOCOL=sixel
|
|
14
|
+
* - PI_ALLOW_SIXEL_PASSTHROUGH=1
|
|
15
|
+
*/
|
|
16
|
+
export function isSixelPassthroughEnabled(): boolean {
|
|
17
|
+
const forcedProtocol = $env.PI_FORCE_IMAGE_PROTOCOL?.trim().toLowerCase();
|
|
18
|
+
return forcedProtocol === "sixel" && $flag("PI_ALLOW_SIXEL_PASSTHROUGH");
|
|
19
|
+
}
|
|
20
|
+
/** Returns true when the text contains a SIXEL start sequence. */
|
|
21
|
+
export function containsSixelSequence(text: string): boolean {
|
|
22
|
+
return SIXEL_START_REGEX.test(text);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Returns a boolean mask indicating which lines belong to a SIXEL sequence block.
|
|
27
|
+
* Supports multi-line SIXEL payloads generated by libsixel.
|
|
28
|
+
*/
|
|
29
|
+
export function getSixelLineMask(lines: readonly string[]): boolean[] {
|
|
30
|
+
let inSequence = false;
|
|
31
|
+
return lines.map(line => {
|
|
32
|
+
const hasStart = containsSixelSequence(line);
|
|
33
|
+
if (hasStart) {
|
|
34
|
+
inSequence = true;
|
|
35
|
+
}
|
|
36
|
+
const isSixelLine = inSequence;
|
|
37
|
+
if (inSequence && (line.includes(SIXEL_END_SEQUENCE) || line.includes(SIXEL_END_BELL))) {
|
|
38
|
+
inSequence = false;
|
|
39
|
+
}
|
|
40
|
+
return isSixelLine;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Returns true when the line contains a SIXEL start sequence. */
|
|
45
|
+
export function isSixelLine(line: string): boolean {
|
|
46
|
+
return containsSixelSequence(line);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Sanitizes text while preserving embedded SIXEL sequences when passthrough is enabled.
|
|
51
|
+
*/
|
|
52
|
+
export function sanitizeWithOptionalSixelPassthrough(text: string, sanitize: (text: string) => string): string {
|
|
53
|
+
if (!isSixelPassthroughEnabled() || !containsSixelSequence(text)) {
|
|
54
|
+
return sanitize(text);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const preservedSequences: string[] = [];
|
|
58
|
+
const tokenized = text.replace(SIXEL_SEQUENCE_REGEX, match => {
|
|
59
|
+
const token = `${SIXEL_PLACEHOLDER_PREFIX}${preservedSequences.length}__`;
|
|
60
|
+
preservedSequences.push(match);
|
|
61
|
+
return token;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const sanitized = sanitize(tokenized);
|
|
65
|
+
return sanitized.replace(/__OMP_SIXEL_SEQUENCE_(\d+)__/gu, (_, indexText: string) => {
|
|
66
|
+
const index = Number.parseInt(indexText, 10);
|
|
67
|
+
return preservedSequences[index] ?? "";
|
|
68
|
+
});
|
|
69
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standardized status header rendering for tool output.
|
|
3
|
+
*/
|
|
4
|
+
import type { Theme, ThemeColor } from "../theme/theme";
|
|
5
|
+
import { formatStatusIcon, type ToolUIStatus } from "./render-utils";
|
|
6
|
+
|
|
7
|
+
/** Status icon, title, description, and metadata for a single header row. */
|
|
8
|
+
export interface StatusLineOptions {
|
|
9
|
+
icon?: ToolUIStatus;
|
|
10
|
+
/** Pre-rendered glyph that replaces the status icon (e.g. a magnifier for
|
|
11
|
+
* search-family tools). Takes precedence over `icon`. */
|
|
12
|
+
iconOverride?: string;
|
|
13
|
+
spinnerFrame?: number;
|
|
14
|
+
title: string;
|
|
15
|
+
titleColor?: ThemeColor;
|
|
16
|
+
description?: string;
|
|
17
|
+
badge?: { label: string; color: ThemeColor };
|
|
18
|
+
meta?: string[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Flatten CR/LF runs in caller-supplied header fragments so a single newline
|
|
23
|
+
* embedded in `description` or `meta` cannot expand the status line into
|
|
24
|
+
* multiple rows — which would otherwise break the bordered output block the
|
|
25
|
+
* header sits on. Tab characters are left alone; tool renderers that need
|
|
26
|
+
* tab-safe text run `replaceTabs()` themselves.
|
|
27
|
+
*/
|
|
28
|
+
function flattenForHeader(text: string): string {
|
|
29
|
+
return text.replace(/\r\n?|\n/g, " ");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Render a single-line status header, flattening multiline fields. */
|
|
33
|
+
export function renderStatusLine(options: StatusLineOptions, theme: Theme): string {
|
|
34
|
+
const icon =
|
|
35
|
+
options.iconOverride ?? (options.icon ? formatStatusIcon(options.icon, theme, options.spinnerFrame) : "");
|
|
36
|
+
const titleColor = options.titleColor ?? "accent";
|
|
37
|
+
const title = theme.fg(titleColor, flattenForHeader(options.title));
|
|
38
|
+
let line = icon ? `${icon} ${title}` : title;
|
|
39
|
+
|
|
40
|
+
if (options.description) {
|
|
41
|
+
line += `: ${theme.fg("muted", flattenForHeader(options.description))}`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (options.badge) {
|
|
45
|
+
const { label, color } = options.badge;
|
|
46
|
+
line += ` ${theme.fg(color, `${theme.format.bracketLeft}${flattenForHeader(label)}${theme.format.bracketRight}`)}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const meta = options.meta?.map(flattenForHeader).filter(value => value.trim().length > 0) ?? [];
|
|
50
|
+
if (meta.length > 0) {
|
|
51
|
+
line += ` ${theme.fg("dim", meta.join(theme.sep.dot))}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return line;
|
|
55
|
+
}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { Text } from "../components/text";
|
|
2
|
+
import type { Theme, ThemeColor } from "../theme/theme";
|
|
3
|
+
import type { Component } from "../tui";
|
|
4
|
+
import { getPaddingX } from "../utils";
|
|
5
|
+
import {
|
|
6
|
+
CachedOutputBlock,
|
|
7
|
+
markFramedBlockComponent,
|
|
8
|
+
outputBlockContentWidth,
|
|
9
|
+
type OutputBlockOptions,
|
|
10
|
+
} from "./output-block";
|
|
11
|
+
import { renderStatusLine, type StatusLineOptions } from "./status-line";
|
|
12
|
+
import type { State } from "./types";
|
|
13
|
+
import { getStateBgColor } from "./utils";
|
|
14
|
+
|
|
15
|
+
/** Lifecycle distinctions shared by tool call and result cards. */
|
|
16
|
+
export type ToolCardPhase = "pending" | "running" | "partial" | "success" | "warning" | "error" | "info";
|
|
17
|
+
|
|
18
|
+
/** Fixed card topology. Framed cards own their border; plain cards flow inline. */
|
|
19
|
+
export type ToolCardVariant = "framed" | "plain";
|
|
20
|
+
|
|
21
|
+
/** Lazily rendered slot content. Components retain their own width caches. */
|
|
22
|
+
export type ToolCardContent = readonly string[] | Component | ((width: number) => readonly string[] | Component);
|
|
23
|
+
|
|
24
|
+
/** A labeled body section in a tool card. */
|
|
25
|
+
export interface ToolCardSection {
|
|
26
|
+
label?: string;
|
|
27
|
+
content: ToolCardContent;
|
|
28
|
+
separator?: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Snapshot returned by a ToolCard builder on each render. */
|
|
32
|
+
export interface ToolCardSnapshot {
|
|
33
|
+
/** Pre-rendered header. Prefer `status` for ordinary tool lifecycle rows. */
|
|
34
|
+
header?: string;
|
|
35
|
+
/** Structured status header, rendered by the shared status-line primitive. */
|
|
36
|
+
status?: StatusLineOptions;
|
|
37
|
+
headerMeta?: string;
|
|
38
|
+
phase?: ToolCardPhase;
|
|
39
|
+
body?: ToolCardContent;
|
|
40
|
+
sections?: readonly ToolCardSection[];
|
|
41
|
+
footer?: ToolCardContent;
|
|
42
|
+
applyBg?: boolean;
|
|
43
|
+
contentPaddingLeft?: number;
|
|
44
|
+
contentPaddingRight?: number;
|
|
45
|
+
borderColor?: ThemeColor;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Width information supplied to a ToolCard's lazy snapshot builder. */
|
|
49
|
+
export interface ToolCardBuildContext {
|
|
50
|
+
width: number;
|
|
51
|
+
/** Inner width for the default one-column framed padding. */
|
|
52
|
+
contentWidth: number;
|
|
53
|
+
/** Compute an inner width when this snapshot opts into custom frame padding. */
|
|
54
|
+
contentWidthFor(contentPaddingLeft?: number, contentPaddingRight?: number): number;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Construction options whose topology remains fixed for a card's lifetime. */
|
|
58
|
+
export interface ToolCardOptions {
|
|
59
|
+
variant: ToolCardVariant;
|
|
60
|
+
paddingX?: number;
|
|
61
|
+
paddingY?: number;
|
|
62
|
+
ignoreTight?: boolean;
|
|
63
|
+
onInvalidate?: () => void;
|
|
64
|
+
onDispose?: () => void;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Map transcript lifecycle terminology onto the output frame's visual states. */
|
|
68
|
+
export function toolCardState(phase: ToolCardPhase | undefined): State | undefined {
|
|
69
|
+
if (phase === "partial") return "pending";
|
|
70
|
+
if (phase === "info") return undefined;
|
|
71
|
+
return phase;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function isRenderedLines(value: readonly string[] | Component): value is readonly string[] {
|
|
75
|
+
return Array.isArray(value);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function resolveContent(content: ToolCardContent, width: number): { lines: readonly string[]; component?: Component } {
|
|
79
|
+
const resolved = typeof content === "function" ? content(width) : content;
|
|
80
|
+
if (isRenderedLines(resolved)) return { lines: resolved };
|
|
81
|
+
return { lines: resolved.render(width), component: resolved };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Cached tool-card layout with lazy body/section/footer children. The builder
|
|
86
|
+
* may read mutable streaming state at render time; unchanged snapshots retain
|
|
87
|
+
* their rendered array identity through CachedOutputBlock or Text.
|
|
88
|
+
*/
|
|
89
|
+
export class ToolCard implements Component {
|
|
90
|
+
readonly #theme: Theme;
|
|
91
|
+
readonly #options: ToolCardOptions;
|
|
92
|
+
readonly #build: (context: ToolCardBuildContext) => ToolCardSnapshot;
|
|
93
|
+
readonly #block = new CachedOutputBlock();
|
|
94
|
+
#lastBlockOptions?: OutputBlockOptions;
|
|
95
|
+
#plainText: Text;
|
|
96
|
+
#plainKey = "";
|
|
97
|
+
#renderedChildren: Component[] = [];
|
|
98
|
+
#disposed = false;
|
|
99
|
+
|
|
100
|
+
constructor(theme: Theme, options: ToolCardOptions, build: (context: ToolCardBuildContext) => ToolCardSnapshot) {
|
|
101
|
+
this.#theme = theme;
|
|
102
|
+
this.#options = options;
|
|
103
|
+
this.#build = build;
|
|
104
|
+
this.#plainText = new Text("", options.paddingX ?? 0, options.paddingY ?? 0);
|
|
105
|
+
this.#plainText.setIgnoreTight(options.ignoreTight ?? true);
|
|
106
|
+
if (options.variant === "framed") markFramedBlockComponent(this);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
render(width: number): readonly string[] {
|
|
110
|
+
const configuredPadding = this.#options.paddingX ?? 0;
|
|
111
|
+
const plainPadding = this.#options.ignoreTight === false ? getPaddingX(configuredPadding) : configuredPadding;
|
|
112
|
+
const defaultContentWidth =
|
|
113
|
+
this.#options.variant === "framed" ? outputBlockContentWidth(width) : Math.max(1, width - plainPadding * 2);
|
|
114
|
+
const snapshot = this.#build({
|
|
115
|
+
width,
|
|
116
|
+
contentWidth: defaultContentWidth,
|
|
117
|
+
contentWidthFor: (contentPaddingLeft?: number, contentPaddingRight?: number) =>
|
|
118
|
+
this.#options.variant === "framed"
|
|
119
|
+
? outputBlockContentWidth(width, contentPaddingLeft, contentPaddingRight)
|
|
120
|
+
: defaultContentWidth,
|
|
121
|
+
});
|
|
122
|
+
const contentWidth =
|
|
123
|
+
this.#options.variant === "framed"
|
|
124
|
+
? outputBlockContentWidth(width, snapshot.contentPaddingLeft, snapshot.contentPaddingRight)
|
|
125
|
+
: defaultContentWidth;
|
|
126
|
+
|
|
127
|
+
const previousChildren = this.#renderedChildren;
|
|
128
|
+
const nextChildren: Component[] = [];
|
|
129
|
+
const nextChildSet = new Set<Component>();
|
|
130
|
+
const retainChild = (component: Component | undefined): void => {
|
|
131
|
+
if (!component || nextChildSet.has(component)) return;
|
|
132
|
+
nextChildSet.add(component);
|
|
133
|
+
nextChildren.push(component);
|
|
134
|
+
};
|
|
135
|
+
const sections: Array<{ label?: string; lines: readonly string[]; separator?: boolean }> = [];
|
|
136
|
+
if (snapshot.body) {
|
|
137
|
+
const body = resolveContent(snapshot.body, contentWidth);
|
|
138
|
+
sections.push({ lines: body.lines });
|
|
139
|
+
retainChild(body.component);
|
|
140
|
+
}
|
|
141
|
+
for (const section of snapshot.sections ?? []) {
|
|
142
|
+
const resolved = resolveContent(section.content, contentWidth);
|
|
143
|
+
sections.push({ label: section.label, lines: resolved.lines, separator: section.separator });
|
|
144
|
+
retainChild(resolved.component);
|
|
145
|
+
}
|
|
146
|
+
if (snapshot.footer) {
|
|
147
|
+
const footer = resolveContent(snapshot.footer, contentWidth);
|
|
148
|
+
sections.push({ lines: footer.lines, separator: sections.length > 0 });
|
|
149
|
+
retainChild(footer.component);
|
|
150
|
+
}
|
|
151
|
+
for (const previousChild of previousChildren) {
|
|
152
|
+
if (!nextChildSet.has(previousChild)) previousChild.dispose?.();
|
|
153
|
+
}
|
|
154
|
+
this.#renderedChildren = nextChildren;
|
|
155
|
+
|
|
156
|
+
const state = toolCardState(snapshot.phase);
|
|
157
|
+
const header = snapshot.header ?? (snapshot.status ? renderStatusLine(snapshot.status, this.#theme) : undefined);
|
|
158
|
+
if (this.#options.variant === "framed") {
|
|
159
|
+
const previousOptions = this.#lastBlockOptions;
|
|
160
|
+
const previousSections = previousOptions?.sections;
|
|
161
|
+
const sectionsStable =
|
|
162
|
+
previousSections?.length === sections.length &&
|
|
163
|
+
sections.every((section, index) => {
|
|
164
|
+
const previous = previousSections[index];
|
|
165
|
+
return (
|
|
166
|
+
previous?.label === section.label &&
|
|
167
|
+
previous.lines === section.lines &&
|
|
168
|
+
previous.separator === section.separator
|
|
169
|
+
);
|
|
170
|
+
});
|
|
171
|
+
const reusableOptions =
|
|
172
|
+
previousOptions?.width === width &&
|
|
173
|
+
previousOptions.header === header &&
|
|
174
|
+
previousOptions.headerMeta === snapshot.headerMeta &&
|
|
175
|
+
previousOptions.state === state &&
|
|
176
|
+
previousOptions.applyBg === snapshot.applyBg &&
|
|
177
|
+
previousOptions.contentPaddingLeft === snapshot.contentPaddingLeft &&
|
|
178
|
+
previousOptions.contentPaddingRight === snapshot.contentPaddingRight &&
|
|
179
|
+
previousOptions.borderColor === snapshot.borderColor &&
|
|
180
|
+
sectionsStable
|
|
181
|
+
? previousOptions
|
|
182
|
+
: undefined;
|
|
183
|
+
const blockOptions: OutputBlockOptions = reusableOptions ?? {
|
|
184
|
+
header,
|
|
185
|
+
headerMeta: snapshot.headerMeta,
|
|
186
|
+
state,
|
|
187
|
+
sections,
|
|
188
|
+
width,
|
|
189
|
+
applyBg: snapshot.applyBg,
|
|
190
|
+
contentPaddingLeft: snapshot.contentPaddingLeft,
|
|
191
|
+
contentPaddingRight: snapshot.contentPaddingRight,
|
|
192
|
+
borderColor: snapshot.borderColor,
|
|
193
|
+
};
|
|
194
|
+
this.#lastBlockOptions = blockOptions;
|
|
195
|
+
return this.#block.render(blockOptions, this.#theme);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const lines: string[] = [];
|
|
199
|
+
if (header) {
|
|
200
|
+
lines.push(snapshot.headerMeta ? `${header} ${snapshot.headerMeta}` : header);
|
|
201
|
+
}
|
|
202
|
+
for (const section of sections) {
|
|
203
|
+
if (section.separator && lines.length > 0) lines.push("");
|
|
204
|
+
if (section.label) lines.push(section.label);
|
|
205
|
+
lines.push(...section.lines);
|
|
206
|
+
}
|
|
207
|
+
const text = lines.join("\n");
|
|
208
|
+
const key = `${width}:${text.length}:${Bun.hash(text).toString(36)}:${state ?? "info"}:${snapshot.applyBg ?? true}`;
|
|
209
|
+
if (key !== this.#plainKey) {
|
|
210
|
+
this.#plainKey = key;
|
|
211
|
+
this.#plainText.setText(text);
|
|
212
|
+
this.#plainText.setCustomBgFn(
|
|
213
|
+
state && snapshot.applyBg !== false ? value => this.#theme.bg(getStateBgColor(state), value) : undefined,
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
return this.#plainText.render(width);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
get debugChildren(): readonly Component[] {
|
|
220
|
+
return this.#renderedChildren;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
get wantsKeyRelease(): boolean {
|
|
224
|
+
return this.#renderedChildren.some(child => child.wantsKeyRelease === true);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
handleInput(data: string): void {
|
|
228
|
+
for (const child of this.#renderedChildren) child.handleInput?.(data);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
setIgnoreTight(ignore: boolean): void {
|
|
232
|
+
this.#options.ignoreTight = ignore;
|
|
233
|
+
this.#plainText.setIgnoreTight(ignore);
|
|
234
|
+
for (const child of this.#renderedChildren) child.setIgnoreTight?.(ignore);
|
|
235
|
+
this.invalidate();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
invalidate(): void {
|
|
239
|
+
this.#block.invalidate();
|
|
240
|
+
this.#lastBlockOptions = undefined;
|
|
241
|
+
this.#plainKey = "";
|
|
242
|
+
this.#plainText.invalidate();
|
|
243
|
+
for (const child of this.#renderedChildren) child.invalidate?.();
|
|
244
|
+
this.#options.onInvalidate?.();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
dispose(): void {
|
|
248
|
+
if (this.#disposed) return;
|
|
249
|
+
this.#disposed = true;
|
|
250
|
+
for (const child of this.#renderedChildren) child.dispose?.();
|
|
251
|
+
this.#options.onDispose?.();
|
|
252
|
+
this.#renderedChildren = [];
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** Construct a lazy framed tool card. */
|
|
257
|
+
export function framedToolCard(
|
|
258
|
+
theme: Theme,
|
|
259
|
+
build: (context: ToolCardBuildContext) => ToolCardSnapshot,
|
|
260
|
+
options: Omit<ToolCardOptions, "variant"> = {},
|
|
261
|
+
): ToolCard {
|
|
262
|
+
return new ToolCard(theme, { ...options, variant: "framed" }, build);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/** Construct a lazy inline tool card, optionally state-tinted. */
|
|
266
|
+
export function plainToolCard(
|
|
267
|
+
theme: Theme,
|
|
268
|
+
build: (context: ToolCardBuildContext) => ToolCardSnapshot,
|
|
269
|
+
options: Omit<ToolCardOptions, "variant"> = {},
|
|
270
|
+
): ToolCard {
|
|
271
|
+
return new ToolCard(theme, { ...options, variant: "plain" }, build);
|
|
272
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hierarchical tree list rendering helper.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Theme } from "../theme/theme";
|
|
6
|
+
import { visibleWidth } from "../utils";
|
|
7
|
+
import { TreeView } from "../components/tree-view";
|
|
8
|
+
import { formatMoreItems } from "./render-utils";
|
|
9
|
+
import type { TreeContext } from "./types";
|
|
10
|
+
import { getTreeBranch, getTreeContinuePrefix } from "./utils";
|
|
11
|
+
|
|
12
|
+
/** Tree items and callbacks controlling their presentation. */
|
|
13
|
+
export interface TreeListOptions<T> {
|
|
14
|
+
items: T[];
|
|
15
|
+
expanded?: boolean;
|
|
16
|
+
maxCollapsed?: number;
|
|
17
|
+
/** Strict total-line budget for collapsed mode. When set (and not expanded),
|
|
18
|
+
* rendered item lines plus the trailing summary line must fit within this budget.
|
|
19
|
+
*/
|
|
20
|
+
maxCollapsedLines?: number;
|
|
21
|
+
itemType?: string;
|
|
22
|
+
truncateFrom?: "start" | "end";
|
|
23
|
+
/** Caller-supplied trailing summary line. When set (and not expanded),
|
|
24
|
+
* `renderTreeList` renders exactly the provided `items` (the caller has
|
|
25
|
+
* already applied its own selection/cap) and appends this text as the
|
|
26
|
+
* final `└` row, with the last item using `├`. Empty string renders the
|
|
27
|
+
* items with no summary. Bypasses the built-in truncation/`maxCollapsed`
|
|
28
|
+
* path. */
|
|
29
|
+
trailingSummary?: string;
|
|
30
|
+
/** Called once per item with `isLast: false` during budget calculation;
|
|
31
|
+
* line count MUST NOT vary based on `isLast`. */
|
|
32
|
+
renderItem: (item: T, context: TreeContext) => string | string[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
type TreeListRow = { kind: "item"; index: number; lines: string[] } | { kind: "summary"; text: string };
|
|
36
|
+
|
|
37
|
+
/** Render tree items with themed branches and optional expansion. */
|
|
38
|
+
export function renderTreeList<T>(options: TreeListOptions<T>, theme: Theme): string[] {
|
|
39
|
+
const {
|
|
40
|
+
items,
|
|
41
|
+
expanded = false,
|
|
42
|
+
maxCollapsed = 8,
|
|
43
|
+
maxCollapsedLines,
|
|
44
|
+
itemType = "item",
|
|
45
|
+
truncateFrom = "end",
|
|
46
|
+
renderItem,
|
|
47
|
+
} = options;
|
|
48
|
+
const maxItems = expanded ? items.length : Math.min(items.length, maxCollapsed);
|
|
49
|
+
const linesBudget = !expanded && maxCollapsedLines !== undefined ? maxCollapsedLines : Infinity;
|
|
50
|
+
const branchPrefix = `${theme.fg("dim", getTreeBranch(false, theme))} `;
|
|
51
|
+
const lastPrefix = `${theme.fg("dim", getTreeBranch(true, theme))} `;
|
|
52
|
+
const branchContinuePrefix = theme.fg("dim", getTreeContinuePrefix(false, theme));
|
|
53
|
+
const lastContinuePrefix = theme.fg("dim", getTreeContinuePrefix(true, theme));
|
|
54
|
+
const prefixWidth = Math.max(
|
|
55
|
+
visibleWidth(branchPrefix),
|
|
56
|
+
visibleWidth(lastPrefix),
|
|
57
|
+
visibleWidth(branchContinuePrefix),
|
|
58
|
+
visibleWidth(lastContinuePrefix),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const toItemRow = (itemIndex: number): TreeListRow => {
|
|
62
|
+
const rendered = renderItem(items[itemIndex], {
|
|
63
|
+
index: itemIndex,
|
|
64
|
+
isLast: false,
|
|
65
|
+
depth: 0,
|
|
66
|
+
theme,
|
|
67
|
+
prefix: "",
|
|
68
|
+
continuePrefix: "",
|
|
69
|
+
prefixWidth,
|
|
70
|
+
});
|
|
71
|
+
return { kind: "item", index: itemIndex, lines: Array.isArray(rendered) ? rendered : rendered ? [rendered] : [] };
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// Caller-driven collapse: render exactly the provided items (the caller
|
|
75
|
+
// already picked/capped them) plus an optional trailing summary row. The
|
|
76
|
+
// walking-viewport todo policy uses this so item selection lives in the
|
|
77
|
+
// todo domain, not here.
|
|
78
|
+
if (!expanded && options.trailingSummary !== undefined) {
|
|
79
|
+
const summary = options.trailingSummary;
|
|
80
|
+
const roots: TreeListRow[] = [];
|
|
81
|
+
for (let i = 0; i < items.length; i++) {
|
|
82
|
+
roots.push(toItemRow(i));
|
|
83
|
+
}
|
|
84
|
+
if (summary !== "") {
|
|
85
|
+
roots.push({ kind: "summary", text: theme.fg("muted", summary) });
|
|
86
|
+
}
|
|
87
|
+
return renderTreeListRows(roots, theme);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const candidateIndices: number[] = [];
|
|
91
|
+
if (truncateFrom === "start") {
|
|
92
|
+
const startCandidateIdx = Math.max(0, items.length - maxItems);
|
|
93
|
+
for (let i = startCandidateIdx; i < items.length; i++) {
|
|
94
|
+
candidateIndices.push(i);
|
|
95
|
+
}
|
|
96
|
+
} else {
|
|
97
|
+
for (let i = 0; i < maxItems; i++) {
|
|
98
|
+
candidateIndices.push(i);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Pre-render each candidate item once.
|
|
103
|
+
// isLast cannot be known at this point (fittingCount is not yet determined);
|
|
104
|
+
// renderItem implementations MUST NOT vary line count based on isLast.
|
|
105
|
+
const preRendered: string[][] = [];
|
|
106
|
+
for (let i = 0; i < candidateIndices.length; i++) {
|
|
107
|
+
const itemIdx = candidateIndices[i];
|
|
108
|
+
const rendered = renderItem(items[itemIdx], {
|
|
109
|
+
index: itemIdx,
|
|
110
|
+
isLast: false,
|
|
111
|
+
depth: 0,
|
|
112
|
+
theme,
|
|
113
|
+
prefix: "",
|
|
114
|
+
continuePrefix: "",
|
|
115
|
+
prefixWidth,
|
|
116
|
+
});
|
|
117
|
+
preRendered.push(Array.isArray(rendered) ? rendered : rendered ? [rendered] : []);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
let displayedSlice: { start: number; end: number };
|
|
121
|
+
let remaining: number;
|
|
122
|
+
let fittedLineCount = 0;
|
|
123
|
+
|
|
124
|
+
if (truncateFrom === "start") {
|
|
125
|
+
let fittingCount = candidateIndices.length;
|
|
126
|
+
if (linesBudget !== Infinity) {
|
|
127
|
+
fittingCount = 0;
|
|
128
|
+
for (let i = candidateIndices.length - 1; i >= 0; i--) {
|
|
129
|
+
const count = preRendered[i].length;
|
|
130
|
+
const remainingBefore = candidateIndices[i];
|
|
131
|
+
const reservedSummaryLines = remainingBefore > 0 ? 1 : 0;
|
|
132
|
+
if (fittedLineCount + count + reservedSummaryLines > linesBudget) break;
|
|
133
|
+
fittedLineCount += count;
|
|
134
|
+
fittingCount++;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const start = candidateIndices.length - fittingCount;
|
|
138
|
+
displayedSlice = { start, end: candidateIndices.length };
|
|
139
|
+
remaining = candidateIndices.length > 0 ? candidateIndices[start] : 0;
|
|
140
|
+
} else {
|
|
141
|
+
let fittingCount = candidateIndices.length;
|
|
142
|
+
if (linesBudget !== Infinity) {
|
|
143
|
+
fittingCount = 0;
|
|
144
|
+
for (let i = 0; i < candidateIndices.length; i++) {
|
|
145
|
+
const count = preRendered[i].length;
|
|
146
|
+
const remainingAfter = items.length - (i + 1);
|
|
147
|
+
const reservedSummaryLines = remainingAfter > 0 ? 1 : 0;
|
|
148
|
+
if (fittedLineCount + count + reservedSummaryLines > linesBudget) break;
|
|
149
|
+
fittedLineCount += count;
|
|
150
|
+
fittingCount = i + 1;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
displayedSlice = { start: 0, end: fittingCount };
|
|
154
|
+
remaining = items.length - fittingCount;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const hasSummary = !expanded && remaining > 0 && (linesBudget === Infinity || fittedLineCount < linesBudget);
|
|
158
|
+
|
|
159
|
+
const roots: TreeListRow[] = [];
|
|
160
|
+
if (truncateFrom === "start" && hasSummary) {
|
|
161
|
+
roots.push({ kind: "summary", text: theme.fg("muted", formatMoreItems(remaining, itemType)) });
|
|
162
|
+
}
|
|
163
|
+
for (let i = displayedSlice.start; i < displayedSlice.end; i++) {
|
|
164
|
+
roots.push({ kind: "item", index: candidateIndices[i], lines: preRendered[i]! });
|
|
165
|
+
}
|
|
166
|
+
if (truncateFrom === "end" && hasSummary) {
|
|
167
|
+
roots.push({ kind: "summary", text: theme.fg("muted", formatMoreItems(remaining, itemType)) });
|
|
168
|
+
}
|
|
169
|
+
return renderTreeListRows(roots, theme);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Emit pre-rendered item/summary roots through the shared keyed hierarchy.
|
|
174
|
+
* Roots are siblings in display order, so the first N-1 rows draw `├` and the
|
|
175
|
+
* final row draws `└` — matching the historical branch/continuation geometry.
|
|
176
|
+
* Formatting adapters render unbounded, so truncation stays disabled here.
|
|
177
|
+
*/
|
|
178
|
+
function renderTreeListRows(roots: TreeListRow[], theme: Theme): string[] {
|
|
179
|
+
const tree = new TreeView<TreeListRow, number>({
|
|
180
|
+
roots,
|
|
181
|
+
getKey: item => (item.kind === "summary" ? -1 : item.index),
|
|
182
|
+
getChildren: () => [],
|
|
183
|
+
theme,
|
|
184
|
+
truncateRows: false,
|
|
185
|
+
renderRow: item => (item.kind === "summary" ? [item.text] : item.lines),
|
|
186
|
+
});
|
|
187
|
+
return [...tree.render(Number.POSITIVE_INFINITY)];
|
|
188
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for TUI rendering components.
|
|
3
|
+
*/
|
|
4
|
+
import type { Theme } from "../theme/theme";
|
|
5
|
+
|
|
6
|
+
/** Visual state of a rendered tool output. */
|
|
7
|
+
export type State = "pending" | "running" | "success" | "error" | "warning";
|
|
8
|
+
|
|
9
|
+
/** Position and theme context passed to tree item renderers. */
|
|
10
|
+
export interface TreeContext {
|
|
11
|
+
index: number;
|
|
12
|
+
isLast: boolean;
|
|
13
|
+
depth: number;
|
|
14
|
+
theme: Theme;
|
|
15
|
+
prefix: string;
|
|
16
|
+
continuePrefix: string;
|
|
17
|
+
/** Maximum rendered branch/continuation prefix width reserved during pre-rendering. */
|
|
18
|
+
prefixWidth?: number;
|
|
19
|
+
}
|