@oh-my-pi/pi-tui 18.2.4 → 18.2.5
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,35 @@
|
|
|
1
|
+
import type { BackgroundTanDispatchDetails, CustomMessage } from "./messages";
|
|
2
|
+
import { replaceTabs } from "../render/render-utils";
|
|
3
|
+
import { theme } from "../theme";
|
|
4
|
+
import type { TranscriptBlock } from "../chrome/transcript-container";
|
|
5
|
+
import { TranscriptStatusBlock } from "../chrome/transcript-status";
|
|
6
|
+
|
|
7
|
+
const TAN_WORK_PREVIEW_LENGTH = 56;
|
|
8
|
+
|
|
9
|
+
function previewWork(work: string): string {
|
|
10
|
+
const singleLine = replaceTabs(work).trim().replace(/\s+/g, " ");
|
|
11
|
+
if (singleLine.length <= TAN_WORK_PREVIEW_LENGTH) return singleLine;
|
|
12
|
+
return `${singleLine.slice(0, TAN_WORK_PREVIEW_LENGTH - 1)}…`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Single-line transcript pill for a `/tan` background-dispatch breadcrumb,
|
|
17
|
+
* styled as a sibling of the "Background job completed" line. The full
|
|
18
|
+
* system-notice content (the persisted `content`) is for the model only — the
|
|
19
|
+
* user sees one compact line, not the raw `<system-notice>` block.
|
|
20
|
+
*/
|
|
21
|
+
export function createBackgroundTanDispatchBlock(message: CustomMessage<unknown>): TranscriptBlock {
|
|
22
|
+
const details = (message as CustomMessage<Partial<BackgroundTanDispatchDetails>>).details;
|
|
23
|
+
const jobId = details?.jobId ?? "unknown";
|
|
24
|
+
const work = details?.work ? previewWork(details.work) : undefined;
|
|
25
|
+
return new TranscriptStatusBlock([
|
|
26
|
+
{
|
|
27
|
+
parts: [
|
|
28
|
+
theme.fg("muted", `${theme.icon.output} Tangent dispatched`),
|
|
29
|
+
theme.fg("dim", "[task]"),
|
|
30
|
+
theme.fg("accent", jobId),
|
|
31
|
+
work ? theme.fg("dim", `${theme.format.dash} ${work}`) : undefined,
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
]);
|
|
35
|
+
}
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component for displaying bash command execution with streaming output.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { ImageContent } from "@oh-my-pi/pi-ai";
|
|
6
|
+
import { Image } from "../components/image";
|
|
7
|
+
import type { Loader } from "../components/loader";
|
|
8
|
+
import { Text } from "../components/text";
|
|
9
|
+
import { getImageDimensions, imageFallback, ImageProtocol, TERMINAL } from "../terminal-capabilities";
|
|
10
|
+
import { Container, type TUI } from "../tui";
|
|
11
|
+
import { sanitizeText } from "@oh-my-pi/pi-utils";
|
|
12
|
+
import type { Terminal as XtermTerminalType } from "@oh-my-pi/pi-utils/vterm";
|
|
13
|
+
import { theme } from "../theme/theme";
|
|
14
|
+
import type { OutputArtifactError } from "../tools/streaming-output";
|
|
15
|
+
import type { TruncationMeta } from "../tools/output-meta";
|
|
16
|
+
import { resolveImageOptions } from "../render/render-utils";
|
|
17
|
+
import { OutputPane } from "../render/output-pane";
|
|
18
|
+
import { loadXtermTerminal, readTerminalRows, styleTerminalRow } from "../tools/terminal-output";
|
|
19
|
+
import { getSixelLineMask, isSixelPassthroughEnabled, sanitizeWithOptionalSixelPassthrough } from "../render/sixel";
|
|
20
|
+
import {
|
|
21
|
+
buildExecutionFrame,
|
|
22
|
+
buildStatusFooter,
|
|
23
|
+
clampDisplayLine,
|
|
24
|
+
type ExecutionStatus,
|
|
25
|
+
PREVIEW_LINES,
|
|
26
|
+
resolveExecutionStatus,
|
|
27
|
+
} from "./execution-shared";
|
|
28
|
+
|
|
29
|
+
const STREAMING_LINE_CAP = PREVIEW_LINES * 5;
|
|
30
|
+
// Minimum interval between processing incoming chunks for display (ms).
|
|
31
|
+
// Chunks arriving faster than this are accumulated and processed in one batch.
|
|
32
|
+
const CHUNK_THROTTLE_MS = 50;
|
|
33
|
+
// Scrollback retained by the PTY replay terminal; bounds memory and the
|
|
34
|
+
// expanded view for long-running commands.
|
|
35
|
+
const PTY_SCROLLBACK_ROWS = 4096;
|
|
36
|
+
// Caps the unwritten PTY chunk backlog while xterm.write drains.
|
|
37
|
+
const MAX_PTY_QUEUE_CHUNKS = 512;
|
|
38
|
+
let nextBashExecutionId = 0;
|
|
39
|
+
|
|
40
|
+
/** PTY size for `!` commands: the execution frame's inner content area. */
|
|
41
|
+
export function bashPtyViewport(ui: TUI): { cols: number; rows: number } {
|
|
42
|
+
return {
|
|
43
|
+
cols: Math.max(20, (ui.terminal?.columns ?? 80) - 2),
|
|
44
|
+
rows: Math.max(5, (ui.terminal?.rows ?? 24) - 4),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export class BashExecutionComponent extends Container {
|
|
49
|
+
#outputLines: string[] = [];
|
|
50
|
+
#status: ExecutionStatus = "running";
|
|
51
|
+
#exitCode: number | undefined = undefined;
|
|
52
|
+
#loader: Loader;
|
|
53
|
+
#truncation?: TruncationMeta;
|
|
54
|
+
#artifactError?: OutputArtifactError;
|
|
55
|
+
#expanded = false;
|
|
56
|
+
// Post-finalize mutation counter (FinalizableBlock.getTranscriptBlockVersion):
|
|
57
|
+
// a completed command's block still mutates on expansion toggles, and the
|
|
58
|
+
// transcript's width-epoch resolution and committed-render bypass must
|
|
59
|
+
// observe that.
|
|
60
|
+
#blockVersion = 0;
|
|
61
|
+
#displayDirty = false;
|
|
62
|
+
#chunkGate = false;
|
|
63
|
+
#contentContainer: Container;
|
|
64
|
+
#outputPane: OutputPane;
|
|
65
|
+
#headerText: Text;
|
|
66
|
+
#ui: TUI;
|
|
67
|
+
// PTY replay state: raw terminal bytes stream into a headless xterm and the
|
|
68
|
+
// display lines are re-read from its screen+scrollback (same pipeline as
|
|
69
|
+
// `launch` logs), so color survives and CR/cursor movement render correctly.
|
|
70
|
+
#ptyMode = false;
|
|
71
|
+
#ptyTerminal?: XtermTerminalType;
|
|
72
|
+
#ptyLoadStarted = false;
|
|
73
|
+
#ptyQueue: string[] = [];
|
|
74
|
+
#ptyWriting = false;
|
|
75
|
+
#ptyRefreshQueued = false;
|
|
76
|
+
#ptyReplayFinalized = false;
|
|
77
|
+
#images: readonly ImageContent[] = [];
|
|
78
|
+
#showImages = true;
|
|
79
|
+
readonly #instanceId = nextBashExecutionId++;
|
|
80
|
+
readonly #command: string;
|
|
81
|
+
|
|
82
|
+
constructor(command: string, ui: TUI, excludeFromContext = false) {
|
|
83
|
+
super();
|
|
84
|
+
this.#command = command;
|
|
85
|
+
this.#ui = ui;
|
|
86
|
+
|
|
87
|
+
// Use dim border for excluded-from-context commands (!! prefix)
|
|
88
|
+
const colorKey = excludeFromContext ? "dim" : "bashMode";
|
|
89
|
+
const { contentContainer, loader } = buildExecutionFrame(this, ui, colorKey);
|
|
90
|
+
this.#contentContainer = contentContainer;
|
|
91
|
+
this.#loader = loader;
|
|
92
|
+
this.#outputPane = new OutputPane(theme, {
|
|
93
|
+
expanded: false,
|
|
94
|
+
collapsedMaxLines: PREVIEW_LINES,
|
|
95
|
+
edge: "tail",
|
|
96
|
+
visual: true,
|
|
97
|
+
paddingX: 1,
|
|
98
|
+
leadingBlank: true,
|
|
99
|
+
showHiddenMarker: false,
|
|
100
|
+
showExpandHint: false,
|
|
101
|
+
styleLine: line => this.#styleDisplayLine(line),
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Command header
|
|
105
|
+
this.#headerText = new Text(theme.fg(colorKey, theme.bold(`$ ${command}`)), 1, 0);
|
|
106
|
+
this.#contentContainer.addChild(this.#headerText);
|
|
107
|
+
this.#contentContainer.addChild(this.#loader);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Transcript finalization contract (see `FinalizableBlock`): the collapsed
|
|
112
|
+
* streaming preview rewrites its tail window every chunk, so the block must
|
|
113
|
+
* stay out of native scrollback until the command completes.
|
|
114
|
+
*/
|
|
115
|
+
isTranscriptBlockFinalized(): boolean {
|
|
116
|
+
return this.#status !== "running" && (!this.#ptyMode || this.#ptyReplayFinalized);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
getTranscriptBlockVersion(): number {
|
|
120
|
+
return this.#blockVersion;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Set whether the output is expanded (shows full output) or collapsed (preview only).
|
|
125
|
+
*/
|
|
126
|
+
setExpanded(expanded: boolean): void {
|
|
127
|
+
if (this.#expanded !== expanded) this.#blockVersion++;
|
|
128
|
+
this.#expanded = expanded;
|
|
129
|
+
this.#outputPane.setExpanded(expanded);
|
|
130
|
+
this.#updateDisplay();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
override invalidate(): void {
|
|
134
|
+
super.invalidate();
|
|
135
|
+
this.#displayDirty = false;
|
|
136
|
+
this.#updateDisplay();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
appendOutput(chunk: string): void {
|
|
140
|
+
if (this.#ptyMode) return;
|
|
141
|
+
// During high-throughput output (e.g. seq 1 500M), processing every
|
|
142
|
+
// chunk would saturate the event loop. Instead, accept one chunk per
|
|
143
|
+
// throttle window and drop the rest — the OutputSink captures everything
|
|
144
|
+
// for the artifact, and setComplete() replaces with the final output.
|
|
145
|
+
if (this.#chunkGate) return;
|
|
146
|
+
this.#chunkGate = true;
|
|
147
|
+
setTimeout(() => {
|
|
148
|
+
this.#chunkGate = false;
|
|
149
|
+
}, CHUNK_THROTTLE_MS);
|
|
150
|
+
|
|
151
|
+
const incomingLines = chunk.split("\n");
|
|
152
|
+
if (this.#outputLines.length > 0 && incomingLines.length > 0) {
|
|
153
|
+
const lastIndex = this.#outputLines.length - 1;
|
|
154
|
+
const mergedLines = [`${this.#outputLines[lastIndex]}${incomingLines[0]}`, ...incomingLines.slice(1)];
|
|
155
|
+
const clampedMergedLines = this.#clampLinesPreservingSixel(mergedLines);
|
|
156
|
+
this.#outputLines[lastIndex] = clampedMergedLines[0] ?? "";
|
|
157
|
+
this.#outputLines.push(...clampedMergedLines.slice(1));
|
|
158
|
+
} else {
|
|
159
|
+
this.#outputLines.push(...this.#clampLinesPreservingSixel(incomingLines));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Cap stored lines during streaming to avoid unbounded memory growth
|
|
163
|
+
if (this.#outputLines.length > STREAMING_LINE_CAP) {
|
|
164
|
+
this.#outputLines = this.#outputLines.slice(-STREAMING_LINE_CAP);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
this.#displayDirty = true;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Switch to PTY rendering and feed raw terminal bytes through the vterm replay. */
|
|
171
|
+
appendPtyChunk(chunk: string): void {
|
|
172
|
+
if (this.#status !== "running" && !this.#ptyWriting && this.#ptyQueue.length === 0) return;
|
|
173
|
+
this.#ptyMode = true;
|
|
174
|
+
this.#ptyReplayFinalized = false;
|
|
175
|
+
this.#ptyQueue.push(chunk);
|
|
176
|
+
if (this.#ptyQueue.length > MAX_PTY_QUEUE_CHUNKS) {
|
|
177
|
+
const firstPending = this.#ptyWriting ? 1 : 0;
|
|
178
|
+
this.#ptyQueue.splice(firstPending, this.#ptyQueue.length - firstPending - MAX_PTY_QUEUE_CHUNKS);
|
|
179
|
+
// A dropped chunk can split an in-flight DCS/OSC string; a stray string
|
|
180
|
+
// terminator is a no-op in the ground state but resynchronizes the parser.
|
|
181
|
+
this.#ptyQueue[firstPending] = `\u001b\\${this.#ptyQueue[firstPending]}`;
|
|
182
|
+
}
|
|
183
|
+
if (!this.#ptyLoadStarted) {
|
|
184
|
+
this.#ptyLoadStarted = true;
|
|
185
|
+
void loadXtermTerminal().then(Terminal => {
|
|
186
|
+
const { cols, rows } = bashPtyViewport(this.#ui);
|
|
187
|
+
this.#ptyTerminal = new Terminal({
|
|
188
|
+
cols,
|
|
189
|
+
rows,
|
|
190
|
+
disableStdin: true,
|
|
191
|
+
allowProposedApi: true,
|
|
192
|
+
scrollback: PTY_SCROLLBACK_ROWS,
|
|
193
|
+
});
|
|
194
|
+
this.#drainPtyQueue();
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
this.#drainPtyQueue();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
#drainPtyQueue(): void {
|
|
201
|
+
const terminal = this.#ptyTerminal;
|
|
202
|
+
if (!terminal || this.#ptyWriting) return;
|
|
203
|
+
const chunk = this.#ptyQueue.shift();
|
|
204
|
+
if (chunk === undefined) {
|
|
205
|
+
if (this.#status !== "running") this.#finalizePtyOutput();
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
this.#ptyWriting = true;
|
|
209
|
+
terminal.write(chunk, () => {
|
|
210
|
+
this.#ptyWriting = false;
|
|
211
|
+
this.#schedulePtyRefresh();
|
|
212
|
+
this.#drainPtyQueue();
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
#schedulePtyRefresh(): void {
|
|
217
|
+
if (this.#chunkGate) {
|
|
218
|
+
this.#ptyRefreshQueued = true;
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
this.#chunkGate = true;
|
|
222
|
+
this.#refreshPtyLines(false);
|
|
223
|
+
setTimeout(() => {
|
|
224
|
+
this.#chunkGate = false;
|
|
225
|
+
if (this.#ptyRefreshQueued) {
|
|
226
|
+
this.#ptyRefreshQueued = false;
|
|
227
|
+
this.#schedulePtyRefresh();
|
|
228
|
+
}
|
|
229
|
+
}, CHUNK_THROTTLE_MS);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** Re-read display lines from the replay terminal (tail window while streaming). */
|
|
233
|
+
#refreshPtyLines(full: boolean): void {
|
|
234
|
+
const terminal = this.#ptyTerminal;
|
|
235
|
+
if (!terminal) return;
|
|
236
|
+
const buffer = terminal.buffer.active;
|
|
237
|
+
const startRow = full ? 0 : Math.max(0, buffer.length - STREAMING_LINE_CAP);
|
|
238
|
+
const rows = readTerminalRows(terminal, startRow, buffer.length - startRow);
|
|
239
|
+
while (rows.length > 0 && rows[rows.length - 1] === "") rows.pop();
|
|
240
|
+
const base = theme.getFgAnsi("muted");
|
|
241
|
+
this.#outputLines = rows.map(row => (row ? styleTerminalRow(row, base) : ""));
|
|
242
|
+
this.#displayDirty = true;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** Final full-scrollback read; the terminal is disposed once lines are snapshotted. */
|
|
246
|
+
#finalizePtyOutput(): void {
|
|
247
|
+
const terminal = this.#ptyTerminal;
|
|
248
|
+
if (!terminal) return;
|
|
249
|
+
this.#refreshPtyLines(true);
|
|
250
|
+
this.#ptyTerminal = undefined;
|
|
251
|
+
terminal.dispose();
|
|
252
|
+
this.#ptyReplayFinalized = true;
|
|
253
|
+
this.#blockVersion++;
|
|
254
|
+
this.#updateDisplay();
|
|
255
|
+
this.#ui.requestComponentRender(this);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
setComplete(
|
|
259
|
+
exitCode: number | undefined,
|
|
260
|
+
cancelled: boolean,
|
|
261
|
+
options?: {
|
|
262
|
+
output?: string;
|
|
263
|
+
truncation?: TruncationMeta;
|
|
264
|
+
artifactError?: OutputArtifactError;
|
|
265
|
+
images?: readonly ImageContent[];
|
|
266
|
+
showImages?: boolean;
|
|
267
|
+
},
|
|
268
|
+
): void {
|
|
269
|
+
this.#exitCode = exitCode;
|
|
270
|
+
this.#status = resolveExecutionStatus(exitCode, cancelled);
|
|
271
|
+
this.#truncation = options?.truncation;
|
|
272
|
+
this.#artifactError = options?.artifactError;
|
|
273
|
+
this.#images = options?.images ?? [];
|
|
274
|
+
this.#showImages = options?.showImages ?? true;
|
|
275
|
+
if (options?.output !== undefined && !this.#ptyMode) {
|
|
276
|
+
this.#setOutput(options.output);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Stop loader
|
|
280
|
+
this.#loader.stop();
|
|
281
|
+
// PTY lines still queued keep draining; the empty-queue drain finalizes.
|
|
282
|
+
if (this.#ptyMode && !this.#ptyWriting && this.#ptyQueue.length === 0) {
|
|
283
|
+
this.#finalizePtyOutput();
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
this.#updateDisplay();
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
override render(width: number): readonly string[] {
|
|
290
|
+
if (this.#displayDirty) {
|
|
291
|
+
this.#displayDirty = false;
|
|
292
|
+
this.#updateDisplay();
|
|
293
|
+
}
|
|
294
|
+
return super.render(width);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
#updateDisplay(): void {
|
|
298
|
+
const availableLines = this.#outputLines;
|
|
299
|
+
|
|
300
|
+
// Full output is shown when expanded or when sixel passthrough renders
|
|
301
|
+
// the raw payload; the collapsed preview shows only the tail window.
|
|
302
|
+
const sixelLineMask =
|
|
303
|
+
TERMINAL.imageProtocol === ImageProtocol.Sixel && isSixelPassthroughEnabled()
|
|
304
|
+
? getSixelLineMask(availableLines)
|
|
305
|
+
: undefined;
|
|
306
|
+
const hasSixelOutput = sixelLineMask?.some(Boolean) ?? false;
|
|
307
|
+
const showingAllLines = this.#expanded || hasSixelOutput;
|
|
308
|
+
// Only the collapsed preview hides lines; when the full output is shown
|
|
309
|
+
// the footer must not keep advertising hidden lines / ctrl+o.
|
|
310
|
+
const hiddenLineCount = showingAllLines ? 0 : Math.max(0, availableLines.length - PREVIEW_LINES);
|
|
311
|
+
this.#outputPane.configure({ uncapSixel: hasSixelOutput });
|
|
312
|
+
this.#outputPane.setLines(availableLines);
|
|
313
|
+
|
|
314
|
+
// Rebuild content container
|
|
315
|
+
this.#contentContainer.clear();
|
|
316
|
+
|
|
317
|
+
// Command header
|
|
318
|
+
this.#contentContainer.addChild(this.#headerText);
|
|
319
|
+
|
|
320
|
+
// Output
|
|
321
|
+
if (availableLines.length > 0) this.#contentContainer.addChild(this.#outputPane);
|
|
322
|
+
|
|
323
|
+
for (let index = 0; index < this.#images.length; index++) {
|
|
324
|
+
const image = this.#images[index]!;
|
|
325
|
+
if (TERMINAL.imageProtocol && this.#showImages) {
|
|
326
|
+
this.#contentContainer.addChild(
|
|
327
|
+
new Image(
|
|
328
|
+
image.data,
|
|
329
|
+
image.mimeType,
|
|
330
|
+
{ fallbackColor: text => theme.fg("muted", text) },
|
|
331
|
+
{
|
|
332
|
+
...resolveImageOptions(),
|
|
333
|
+
budget: this.#ui.imageBudget,
|
|
334
|
+
imageKey: `be${this.#instanceId}:${index}`,
|
|
335
|
+
},
|
|
336
|
+
),
|
|
337
|
+
);
|
|
338
|
+
} else {
|
|
339
|
+
const dimensions = getImageDimensions(image.data, image.mimeType) ?? undefined;
|
|
340
|
+
this.#contentContainer.addChild(
|
|
341
|
+
new Text(theme.fg("muted", imageFallback(image.mimeType, dimensions)), 1, 0),
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Loader or status
|
|
347
|
+
if (this.#status === "running") {
|
|
348
|
+
this.#contentContainer.addChild(this.#loader);
|
|
349
|
+
} else {
|
|
350
|
+
const footer = buildStatusFooter({
|
|
351
|
+
status: this.#status,
|
|
352
|
+
exitCode: this.#exitCode,
|
|
353
|
+
truncation: this.#truncation,
|
|
354
|
+
artifactError: this.#artifactError,
|
|
355
|
+
hiddenLineCount,
|
|
356
|
+
suppressHiddenCount: hasSixelOutput,
|
|
357
|
+
});
|
|
358
|
+
if (footer) this.#contentContainer.addChild(footer);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/** PTY replay rows arrive pre-styled (safe SGR + reset); plain lines get muted. */
|
|
363
|
+
#styleDisplayLine(line: string): string {
|
|
364
|
+
return this.#ptyMode ? line : theme.fg("muted", line);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
#clampLinesPreservingSixel(lines: string[]): string[] {
|
|
368
|
+
if (lines.length === 0) return [];
|
|
369
|
+
const sixelLineMask = getSixelLineMask(lines);
|
|
370
|
+
if (!sixelLineMask.some(Boolean)) {
|
|
371
|
+
return lines.map(clampDisplayLine);
|
|
372
|
+
}
|
|
373
|
+
return lines.map((line, index) => (sixelLineMask[index] ? line : clampDisplayLine(line)));
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
#setOutput(output: string): void {
|
|
377
|
+
const clean = sanitizeWithOptionalSixelPassthrough(output, sanitizeText);
|
|
378
|
+
this.#outputLines = clean ? this.#clampLinesPreservingSixel(clean.split("\n")) : [];
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Get the raw output for creating BashExecutionMessage.
|
|
383
|
+
*/
|
|
384
|
+
getOutput(): string {
|
|
385
|
+
return this.#outputLines.join("\n");
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Get the command that was executed.
|
|
390
|
+
*/
|
|
391
|
+
getCommand(): string {
|
|
392
|
+
return this.#command;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { Usage } from "@oh-my-pi/pi-ai";
|
|
2
|
+
import { formatNumber } from "@oh-my-pi/pi-utils";
|
|
3
|
+
import { MessageDividerComponent } from "../chrome/message-divider";
|
|
4
|
+
import { theme } from "../theme";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Minimum prefix the previous turn must have READ back from cache before a
|
|
8
|
+
* collapse on the current turn counts as an invalidation. Filters out tiny
|
|
9
|
+
* contexts and providers below the cacheable-prefix floor, where a zero
|
|
10
|
+
* `cacheRead` is expected rather than a reset.
|
|
11
|
+
*/
|
|
12
|
+
const MIN_CACHE_FOOTPRINT = 2048;
|
|
13
|
+
|
|
14
|
+
/** A prompt-cache invalidation detected from a turn's usage. */
|
|
15
|
+
export interface CacheInvalidation {
|
|
16
|
+
/** Prompt tokens the cold turn had to (re)process instead of reading from cache. */
|
|
17
|
+
reprocessedTokens: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Decide whether `current` turn lost a *working* prompt cache that `prev` was
|
|
22
|
+
* reusing.
|
|
23
|
+
*
|
|
24
|
+
* The provider reports a warm prefix as `cacheRead`; a model/thinking/tool/
|
|
25
|
+
* system-prompt change (or a history rewrite) breaks the prefix, so the next
|
|
26
|
+
* request reads nothing from cache and re-pays for the whole prompt. We flag
|
|
27
|
+
* only the transition where a demonstrably warm cache goes cold: the previous
|
|
28
|
+
* turn must have actually READ a meaningful prefix back, and this turn's
|
|
29
|
+
* `cacheRead` collapsed to zero while it still reprocessed a non-trivial prompt.
|
|
30
|
+
*
|
|
31
|
+
* Requiring a prior warm read is deliberate. A turn that merely WROTE the prefix
|
|
32
|
+
* (`cacheRead` 0) has not proven the cache is live — that is the session's first
|
|
33
|
+
* request, or a re-write after expiry — so a following cold turn there is
|
|
34
|
+
* expected, not an invalidation the user caused (e.g. a long-running first tool
|
|
35
|
+
* call outliving the provider's 5-minute cache TTL surfaced a spurious "cache
|
|
36
|
+
* miss" right under the opening message). It also collapses a run of consecutive
|
|
37
|
+
* cold turns to the single marker at the moment the cache actually broke, instead
|
|
38
|
+
* of repeating the banner on every turn while it re-warms.
|
|
39
|
+
*
|
|
40
|
+
* Returns `undefined` (no marker) for the first turn, turns whose predecessor
|
|
41
|
+
* never read a warm prefix, tiny contexts, turns that reused any cache, and —
|
|
42
|
+
* crucially — turns on providers with *implicit* best-effort caching. Only an
|
|
43
|
+
* explicit, prefix-controlled cache (Anthropic / Bedrock `cache_control`)
|
|
44
|
+
* re-creates the prefix on a cold turn (`cacheWrite > 0`); implicit caches
|
|
45
|
+
* (Google / OpenAI / Fireworks) report `cacheWrite: 0` and drop `cacheRead` to
|
|
46
|
+
* zero intermittently as routine propagation noise that self-heals the next
|
|
47
|
+
* turn, so flagging it would be a false positive.
|
|
48
|
+
*/
|
|
49
|
+
export function detectCacheInvalidation(prev: Usage | undefined, current: Usage): CacheInvalidation | undefined {
|
|
50
|
+
if (!prev) return undefined;
|
|
51
|
+
// Only flag a warm→cold transition: the previous turn must have actually read
|
|
52
|
+
// a meaningful prefix from cache. A write-only predecessor (first request, or
|
|
53
|
+
// a re-write after expiry) has not proven the cache is live, so a cold turn
|
|
54
|
+
// behind it is expected — not an invalidation worth surfacing.
|
|
55
|
+
if (prev.cacheRead < MIN_CACHE_FOOTPRINT) return undefined;
|
|
56
|
+
// Any cache reuse this turn means the prefix survived (at least partly).
|
|
57
|
+
if (current.cacheRead > 0) return undefined;
|
|
58
|
+
// Only an explicit, prefix-controlled cache re-creates the prefix on a cold
|
|
59
|
+
// turn — Anthropic/Bedrock report that as `cacheWrite`. Implicit best-effort
|
|
60
|
+
// caches (Google/OpenAI/Fireworks) report `cacheWrite: 0` and drop `cacheRead`
|
|
61
|
+
// to zero intermittently as propagation noise, not a real invalidation.
|
|
62
|
+
if (current.cacheWrite <= 0) return undefined;
|
|
63
|
+
const reprocessedTokens = current.cacheWrite + current.input;
|
|
64
|
+
if (reprocessedTokens < MIN_CACHE_FOOTPRINT) return undefined;
|
|
65
|
+
return { reprocessedTokens };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Slim left-aligned divider rendered after an assistant turn whose request lost
|
|
70
|
+
* the prompt cache. It trails streamed content because usage arrives at message
|
|
71
|
+
* end, after completed rows may already be in native history.
|
|
72
|
+
*
|
|
73
|
+
* Mirrors the compaction divider's banner styling but spans only a short rule
|
|
74
|
+
* plus label (not the full width) and carries no expandable detail:
|
|
75
|
+
*
|
|
76
|
+
* ────────── ⊘ cache miss · 50.9k tokens
|
|
77
|
+
*/
|
|
78
|
+
export class CacheInvalidationMarkerComponent extends MessageDividerComponent {
|
|
79
|
+
constructor(info: CacheInvalidation) {
|
|
80
|
+
super({
|
|
81
|
+
label: () => {
|
|
82
|
+
const icon = theme.icon.cacheMiss;
|
|
83
|
+
const head = icon ? `${icon} cache miss` : "cache miss";
|
|
84
|
+
const tokens = info.reprocessedTokens;
|
|
85
|
+
return tokens > 0 ? `${head} ${theme.sep.dot.trim()} ${formatNumber(tokens)} tokens` : head;
|
|
86
|
+
},
|
|
87
|
+
labelColor: "muted",
|
|
88
|
+
ruleColor: "dim",
|
|
89
|
+
ruleWidth: 10,
|
|
90
|
+
// Too narrow to frame — preserve the legacy bare label.
|
|
91
|
+
truncateWhenNarrow: false,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|