@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,287 @@
|
|
|
1
|
+
import { applyBackgroundToLine, padding, visibleWidth } from "../utils";
|
|
2
|
+
import { type Component, Container } from "../tui";
|
|
3
|
+
import { Disclosure } from "../components/disclosure";
|
|
4
|
+
import { Markdown } from "../components/markdown";
|
|
5
|
+
import { formatBytes } from "@oh-my-pi/pi-utils";
|
|
6
|
+
import { ensureThemeSync, getMarkdownTheme, theme } from "../theme";
|
|
7
|
+
import {
|
|
8
|
+
attachmentSgr,
|
|
9
|
+
collapseImageMarkers,
|
|
10
|
+
COMPOSER_TOKEN_REGEX,
|
|
11
|
+
composerTokenRegex,
|
|
12
|
+
modelChipStyle,
|
|
13
|
+
modelMentionChipLabel,
|
|
14
|
+
renderPlaceholders,
|
|
15
|
+
skillChipStyle,
|
|
16
|
+
} from "../prompt/composer-attachments";
|
|
17
|
+
import { MODEL_MENTION_TAG_RE } from "../prompt/model-mention-syntax";
|
|
18
|
+
import { fileHyperlink } from "../render";
|
|
19
|
+
import { imageReferenceHyperlink } from "../prompt/image-references";
|
|
20
|
+
import { highlightMagicKeywords } from "../prompt/magic-keywords";
|
|
21
|
+
import type { ReactionTarget } from "./reaction";
|
|
22
|
+
|
|
23
|
+
// OSC 133 shell integration: marks prompt zones for terminal multiplexers.
|
|
24
|
+
//
|
|
25
|
+
// The zone must be *closed* within the same render. `133;B` sets a sticky
|
|
26
|
+
// cursor semantic of `.input` in Ghostty (and Ghostty-derived terminals such
|
|
27
|
+
// as cmux) that only a command-start marker clears; leaving it latched makes
|
|
28
|
+
// `cursorIsAtPrompt()` permanently true and tags every subsequently painted
|
|
29
|
+
// cell as `.input`. Combined with `cursor-click-to-move = true` (Ghostty's
|
|
30
|
+
// default) that turns every left-click inside the pane into a burst of
|
|
31
|
+
// synthesized arrow keys on omp's pty, slamming the editor caret to column 0
|
|
32
|
+
// (#8030, #6115).
|
|
33
|
+
//
|
|
34
|
+
// `133;C` is therefore emitted immediately followed by `133;D;0` at the end of
|
|
35
|
+
// the bubble. That clears the input state without reintroducing the grouping
|
|
36
|
+
// problem the marker was originally omitted to avoid: the command zone opens
|
|
37
|
+
// and finishes inside this component, so later assistant/tool output can never
|
|
38
|
+
// be grouped under the first submitted prompt.
|
|
39
|
+
const OSC133_ZONE_START = "\x1b]133;A\x07";
|
|
40
|
+
const OSC133_ZONE_END = "\x1b]133;B\x07";
|
|
41
|
+
const OSC133_COMMAND_START = "\x1b]133;C\x07";
|
|
42
|
+
const OSC133_COMMAND_DONE = "\x1b]133;D;0\x07";
|
|
43
|
+
const OSC133_ZONE_CLOSE = OSC133_ZONE_END + OSC133_COMMAND_START + OSC133_COMMAND_DONE;
|
|
44
|
+
|
|
45
|
+
/** How a user bubble styles its prose and chips (see {@link userBubbleColor}). */
|
|
46
|
+
export interface UserBubbleOptions {
|
|
47
|
+
/** Materialized `file://` targets per attached image, indexed by chip number. */
|
|
48
|
+
imageLinks?: readonly (string | undefined)[];
|
|
49
|
+
/** Agent-attributed input: dim, flat prose. */
|
|
50
|
+
synthetic?: boolean;
|
|
51
|
+
/** SKILL.md path for a skill chip by name; `undefined` leaves the chip unlinked. */
|
|
52
|
+
skillPath?: (name: string) => string | undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Foreground styling for prose inside a user bubble: the bubble text color with the
|
|
57
|
+
* magic-keyword glow, attachment chips in their composer identity color, and skill
|
|
58
|
+
* chips as soft pills (linked to their SKILL.md) — each token restoring the bubble's
|
|
59
|
+
* own foreground after it. Shared by {@link UserMessageComponent} and the skill
|
|
60
|
+
* callout so both read as one turn.
|
|
61
|
+
*/
|
|
62
|
+
export function userBubbleColor(
|
|
63
|
+
options: UserBubbleOptions = {},
|
|
64
|
+
tokenRegex: RegExp = COMPOSER_TOKEN_REGEX,
|
|
65
|
+
): (value: string) => string {
|
|
66
|
+
const { imageLinks, synthetic = false, skillPath } = options;
|
|
67
|
+
// The Markdown component routes code spans and fenced blocks through its own code styling
|
|
68
|
+
// (never `color`), so those are already excluded; `highlightMagicKeywords` additionally
|
|
69
|
+
// restores the bubble's own foreground after each painted keyword so the gradient never
|
|
70
|
+
// bleeds into the rest of the line.
|
|
71
|
+
const keywordReset = theme.getFgOnBgAnsi("userMessageText", "userMessageBg");
|
|
72
|
+
const bubbleReset = `${keywordReset}${theme.getBgAnsi("userMessageBg")}`;
|
|
73
|
+
const renderText = synthetic
|
|
74
|
+
? (text: string) => theme.fg("dim", text)
|
|
75
|
+
: (text: string) => theme.fgOnBg("userMessageText", "userMessageBg", highlightMagicKeywords(text, keywordReset));
|
|
76
|
+
return (value: string) =>
|
|
77
|
+
renderPlaceholders(
|
|
78
|
+
value,
|
|
79
|
+
{
|
|
80
|
+
renderText,
|
|
81
|
+
renderSkill: (label, name) => {
|
|
82
|
+
const styled = skillChipStyle(label, bubbleReset);
|
|
83
|
+
const path = skillPath?.(name);
|
|
84
|
+
return path ? fileHyperlink(path, styled, { line: 1 }) : styled;
|
|
85
|
+
},
|
|
86
|
+
renderMention: label => modelChipStyle(label, bubbleReset),
|
|
87
|
+
renderReference: (label, kind, index, form) => {
|
|
88
|
+
// Chip tokens keep their composer identity color; the bubble's own
|
|
89
|
+
// foreground resumes after the token (same pattern as keywords).
|
|
90
|
+
const styled =
|
|
91
|
+
form === "chip"
|
|
92
|
+
? `${attachmentSgr(kind, index)}\x1b[1m${label}\x1b[22m${keywordReset}`
|
|
93
|
+
: theme.fg("accent", `\x1b[1m${label}\x1b[22m`);
|
|
94
|
+
return kind === "image" || kind === "video"
|
|
95
|
+
? imageReferenceHyperlink(label, index, imageLinks, () => styled)
|
|
96
|
+
: styled;
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
tokenRegex,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Component that renders a user message. Accepts an agent reaction badge
|
|
105
|
+
* (see {@link ReactionTarget}) drawn right-aligned in the bubble's top padding row.
|
|
106
|
+
*/
|
|
107
|
+
export class UserMessageComponent extends Container implements ReactionTarget {
|
|
108
|
+
// Memoized OSC 133 zone wrapping keyed on the underlying container render
|
|
109
|
+
// (same source ref ⇒ identical rows ⇒ reuse the wrapped copy). Keeps this
|
|
110
|
+
// component reference-stable for the transcript's incremental assembly and
|
|
111
|
+
// never mutates the container's cached array.
|
|
112
|
+
#zoneSource: readonly string[] | undefined;
|
|
113
|
+
#zoneLines: string[] | undefined;
|
|
114
|
+
readonly #bgColor: (value: string) => string;
|
|
115
|
+
#reaction: string | undefined;
|
|
116
|
+
|
|
117
|
+
constructor(text: string, options: UserBubbleOptions = {}) {
|
|
118
|
+
super();
|
|
119
|
+
ensureThemeSync();
|
|
120
|
+
// Display-only collapse: the stored/wire text carries bracketed `[Image #N, WxH]` markers,
|
|
121
|
+
// but the transcript shows the same compact `<icon> #N` chip the composer used. Runs before
|
|
122
|
+
// Markdown layout so wrapping and bubble padding are computed on the visible text.
|
|
123
|
+
text = collapseImageMarkers(text, Number.POSITIVE_INFINITY, () => {});
|
|
124
|
+
const mentionLabels: string[] = [];
|
|
125
|
+
MODEL_MENTION_TAG_RE.lastIndex = 0;
|
|
126
|
+
text = text.replace(MODEL_MENTION_TAG_RE, (_tag, _agent: string, name: string) => {
|
|
127
|
+
const label = modelMentionChipLabel(name);
|
|
128
|
+
mentionLabels.push(label);
|
|
129
|
+
return label;
|
|
130
|
+
});
|
|
131
|
+
const bgColor = (value: string) => theme.bg("userMessageBg", value);
|
|
132
|
+
this.#bgColor = bgColor;
|
|
133
|
+
const md = new Markdown(text, 1, 1, getMarkdownTheme(), {
|
|
134
|
+
bgColor,
|
|
135
|
+
color: userBubbleColor(options, composerTokenRegex(mentionLabels)),
|
|
136
|
+
});
|
|
137
|
+
md.setIgnoreTight(true);
|
|
138
|
+
this.addChild(md);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
setReaction(emoji: string): void {
|
|
142
|
+
if (this.#reaction === emoji) return;
|
|
143
|
+
this.#reaction = emoji;
|
|
144
|
+
this.#zoneLines = undefined;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** The top padding row with the reaction badge right-aligned inside the horizontal padding. */
|
|
148
|
+
#reactionRow(width: number): string {
|
|
149
|
+
const emoji = this.#reaction!;
|
|
150
|
+
return applyBackgroundToLine(padding(width - 1 - visibleWidth(emoji)) + emoji, width, this.#bgColor);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
override render(width: number): readonly string[] {
|
|
154
|
+
const lines = super.render(width);
|
|
155
|
+
if (lines.length === 0) {
|
|
156
|
+
return lines;
|
|
157
|
+
}
|
|
158
|
+
if (this.#zoneSource === lines && this.#zoneLines !== undefined) {
|
|
159
|
+
return this.#zoneLines;
|
|
160
|
+
}
|
|
161
|
+
const wrapped = lines.slice();
|
|
162
|
+
if (this.#reaction !== undefined) wrapped[0] = this.#reactionRow(width);
|
|
163
|
+
wrapped[0] = OSC133_ZONE_START + wrapped[0];
|
|
164
|
+
wrapped[wrapped.length - 1] = wrapped[wrapped.length - 1] + OSC133_ZONE_CLOSE;
|
|
165
|
+
this.#zoneSource = lines;
|
|
166
|
+
this.#zoneLines = wrapped;
|
|
167
|
+
return wrapped;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Always-visible dim summary row for a collapsed synthetic input. Kept as a
|
|
173
|
+
* small domain renderer so the width-truncated label never pays Markdown
|
|
174
|
+
* layout; the heavy body lives in the {@link Disclosure} detail slot.
|
|
175
|
+
*/
|
|
176
|
+
class SyntheticSummary implements Component {
|
|
177
|
+
readonly #summary: string;
|
|
178
|
+
#cache: { width: number; lines: readonly string[] } | undefined;
|
|
179
|
+
|
|
180
|
+
constructor(summary: string) {
|
|
181
|
+
this.#summary = summary;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
invalidate(): void {
|
|
185
|
+
this.#cache = undefined;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
render(width: number): readonly string[] {
|
|
189
|
+
width = Math.max(1, width);
|
|
190
|
+
if (this.#cache?.width === width) return this.#cache.lines;
|
|
191
|
+
const hint = `${theme.sep.dot.trim()} ctrl+o`;
|
|
192
|
+
const lines = [` ${theme.fg("dim", truncateSummary(`${this.#summary} ${hint}`, Math.max(10, width - 1)))}`];
|
|
193
|
+
this.#cache = { width, lines };
|
|
194
|
+
return lines;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Collapsed placeholder for a synthetic (agent-attributed) user input in the
|
|
200
|
+
* file/remote-backed transcript viewer — chiefly the advisor's `Session update`
|
|
201
|
+
* replay dumps, which can each be hundreds of KiB of Markdown and, on cold open,
|
|
202
|
+
* blocked the TUI for tens of seconds while every historical body was laid out
|
|
203
|
+
* before the viewport clip (issue #6308).
|
|
204
|
+
*
|
|
205
|
+
* Collapsed by default: renders one dim summary row (label · size · line count ·
|
|
206
|
+
* expand hint) and builds NO Markdown. The heavy {@link UserMessageComponent} is
|
|
207
|
+
* constructed lazily only when expanded via `ctrl+o`, so blocks above the
|
|
208
|
+
* viewport never pay layout cost until the reader asks to see them. The raw
|
|
209
|
+
* observability data stays intact in `__advisor.jsonl`.
|
|
210
|
+
*/
|
|
211
|
+
export class CollapsedSyntheticMessageComponent implements Component {
|
|
212
|
+
#disclosure: Disclosure;
|
|
213
|
+
|
|
214
|
+
readonly #text: string;
|
|
215
|
+
readonly #imageLinks?: readonly (string | undefined)[];
|
|
216
|
+
|
|
217
|
+
constructor(text: string, imageLinks?: readonly (string | undefined)[]) {
|
|
218
|
+
this.#text = text;
|
|
219
|
+
this.#imageLinks = imageLinks;
|
|
220
|
+
|
|
221
|
+
// The heavy UserMessageComponent is constructed lazily only on the
|
|
222
|
+
// first expanded render and retained across collapse/re-expand cycles.
|
|
223
|
+
this.#disclosure = new Disclosure({
|
|
224
|
+
summary: new SyntheticSummary(summarizeSyntheticInput(text)),
|
|
225
|
+
body: () => new UserMessageComponent(this.#text, { synthetic: true, imageLinks: this.#imageLinks }),
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** ctrl+o toggle: reveal/hide the full Markdown body. */
|
|
230
|
+
setExpanded(expanded: boolean): void {
|
|
231
|
+
this.#disclosure.setExpanded(expanded);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
setIgnoreTight(ignore: boolean): this {
|
|
235
|
+
this.#disclosure.setIgnoreTight(ignore);
|
|
236
|
+
return this;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
invalidate(): void {
|
|
240
|
+
this.#disclosure.invalidate();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
dispose(): void {
|
|
244
|
+
this.#disclosure.dispose();
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
render(width: number): readonly string[] {
|
|
248
|
+
return this.#disclosure.render(width);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/** Truncate a plain summary label to `maxWidth` display columns, appending `…`. */
|
|
253
|
+
function truncateSummary(text: string, maxWidth: number): string {
|
|
254
|
+
if (Bun.stringWidth(text, { countAnsiEscapeCodes: false }) <= maxWidth) return text;
|
|
255
|
+
let out = "";
|
|
256
|
+
let w = 0;
|
|
257
|
+
for (const ch of text) {
|
|
258
|
+
const cw = Bun.stringWidth(ch, { countAnsiEscapeCodes: false });
|
|
259
|
+
if (w + cw > maxWidth - 1) break;
|
|
260
|
+
out += ch;
|
|
261
|
+
w += cw;
|
|
262
|
+
}
|
|
263
|
+
return `${out}…`;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* One-line summary for a collapsed synthetic input: `<label> · <size> · <n>
|
|
268
|
+
* lines`. The label is the first Markdown heading's text (e.g. `Session
|
|
269
|
+
* update`), falling back to `Synthetic input` when the body opens with none.
|
|
270
|
+
*/
|
|
271
|
+
function summarizeSyntheticInput(text: string): string {
|
|
272
|
+
const size = formatBytes(Buffer.byteLength(text, "utf-8"));
|
|
273
|
+
const lineCount = text === "" ? 0 : text.split("\n").length;
|
|
274
|
+
const dot = theme.sep.dot.trim();
|
|
275
|
+
return `${syntheticInputLabel(text)} ${dot} ${size} ${dot} ${lineCount} line${lineCount === 1 ? "" : "s"}`;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/** First Markdown heading text in `text`, else `Synthetic input`. */
|
|
279
|
+
function syntheticInputLabel(text: string): string {
|
|
280
|
+
for (const raw of text.split("\n")) {
|
|
281
|
+
const line = raw.trim();
|
|
282
|
+
if (!line) continue;
|
|
283
|
+
const heading = /^#{1,6}\s+(.*)$/.exec(line);
|
|
284
|
+
return heading ? heading[1]!.trim() || "Synthetic input" : "Synthetic input";
|
|
285
|
+
}
|
|
286
|
+
return "Synthetic input";
|
|
287
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Container } from "../tui";
|
|
2
|
+
/**
|
|
3
|
+
* Capabilities a mounted {@link ChatBlock} may use against its host transcript.
|
|
4
|
+
* Kept minimal so blocks never reach into the full TUI/InteractiveMode surface.
|
|
5
|
+
*/
|
|
6
|
+
export interface ChatBlockHost {
|
|
7
|
+
/** Schedule a repaint of the transcript. */
|
|
8
|
+
requestRender(): void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Lifecycle-aware transcript block — the "return a block, let the host mount it"
|
|
13
|
+
* primitive, modelled on React/Svelte component lifecycles.
|
|
14
|
+
*
|
|
15
|
+
* Producers build and return a `ChatBlock` instead of poking `chatContainer` and
|
|
16
|
+
* `ui.requestRender()` directly. The host (`ctx.present`) appends it and calls
|
|
17
|
+
* {@link mount}, which runs {@link onMount}; effects started there register
|
|
18
|
+
* teardown via {@link onCleanup}. The block repaints through {@link requestRender}
|
|
19
|
+
* — never touching the TUI — and tears down exactly once on {@link finish}
|
|
20
|
+
* (self-complete: stop the animation, keep the final frame in the transcript) or
|
|
21
|
+
* {@link dispose} (host discards it, e.g. a transcript reset).
|
|
22
|
+
*
|
|
23
|
+
* While mounted and unfinished a block reports `isTranscriptBlockFinalized() ===
|
|
24
|
+
* false` so {@link "../components/transcript-container".TranscriptContainer}
|
|
25
|
+
* keeps it in the live, repaintable region on ED3-risk terminals; after
|
|
26
|
+
* `finish()`/`dispose()` it reports `true` and freezes at its final content.
|
|
27
|
+
*/
|
|
28
|
+
export abstract class ChatBlock extends Container {
|
|
29
|
+
#host: ChatBlockHost | undefined;
|
|
30
|
+
#cleanups: Array<() => void> = [];
|
|
31
|
+
#active = false;
|
|
32
|
+
#disposed = false;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Run setup after the block is in the transcript: start timers/subscriptions
|
|
36
|
+
* and register their teardown with {@link onCleanup}. Default: no-op (a block
|
|
37
|
+
* whose content is fixed at construction needs no mount work).
|
|
38
|
+
*/
|
|
39
|
+
protected onMount(): void {}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Register a teardown to run on {@link finish}/{@link dispose}, à la a
|
|
43
|
+
* `useEffect` cleanup. If the block is already disposed the cleanup runs
|
|
44
|
+
* immediately so callers never leak.
|
|
45
|
+
*/
|
|
46
|
+
protected onCleanup(cleanup: () => void): void {
|
|
47
|
+
if (this.#disposed) {
|
|
48
|
+
cleanup();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this.#cleanups.push(cleanup);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Ask the host to repaint. No-op before mount or after dispose. */
|
|
55
|
+
protected requestRender(): void {
|
|
56
|
+
this.#host?.requestRender();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** True between {@link mount} and {@link finish}/{@link dispose}. */
|
|
60
|
+
protected get active(): boolean {
|
|
61
|
+
return this.#active;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Host-only: attach the host and run {@link onMount}. Idempotent — a second
|
|
66
|
+
* call (e.g. a transcript rebuild that re-presents the same instance) is a
|
|
67
|
+
* no-op.
|
|
68
|
+
*/
|
|
69
|
+
mount(host: ChatBlockHost): void {
|
|
70
|
+
if (this.#host || this.#disposed) return;
|
|
71
|
+
this.#host = host;
|
|
72
|
+
this.#active = true;
|
|
73
|
+
this.onMount();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Self-complete: stop ongoing effects and freeze the block at its current
|
|
78
|
+
* content, leaving it rendered in the transcript. Use when the operation the
|
|
79
|
+
* block represents finishes (connection resolved, download done).
|
|
80
|
+
*/
|
|
81
|
+
finish(): void {
|
|
82
|
+
if (!this.#active) return;
|
|
83
|
+
this.#active = false;
|
|
84
|
+
this.#runCleanups();
|
|
85
|
+
this.requestRender();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Host-only teardown: release everything and propagate to children. Called
|
|
90
|
+
* when the host permanently discards the block (transcript reset). Idempotent.
|
|
91
|
+
*/
|
|
92
|
+
override dispose(): void {
|
|
93
|
+
if (this.#disposed) return;
|
|
94
|
+
this.#disposed = true;
|
|
95
|
+
this.#active = false;
|
|
96
|
+
this.#runCleanups();
|
|
97
|
+
super.dispose();
|
|
98
|
+
this.#host = undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Live blocks stay repaintable; finished/disposed ones may freeze. */
|
|
102
|
+
isTranscriptBlockFinalized(): boolean {
|
|
103
|
+
return !this.#active;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
#runCleanups(): void {
|
|
107
|
+
const cleanups = this.#cleanups.splice(0);
|
|
108
|
+
for (const cleanup of cleanups) cleanup();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { Component } from "../tui";
|
|
2
|
+
import { Ellipsis, truncateToWidth, visibleWidth } from "../utils";
|
|
3
|
+
import type { AnimationFrame, TranscriptPresentationTarget } from "./transcript-container";
|
|
4
|
+
import { fgOrPlain } from "../theme/theme";
|
|
5
|
+
import { urlHyperlinkAlways } from "../render/index";
|
|
6
|
+
import { QrCode, renderQrHalfBlocks } from "./qrcode";
|
|
7
|
+
|
|
8
|
+
/** Scheme-less display form of a collab browser deep link, OSC-8 linked. */
|
|
9
|
+
export function collabBrowserLink(webLink: string, label?: string): string {
|
|
10
|
+
const schemeLess = webLink.replace(/^https?:\/\//, "");
|
|
11
|
+
const display = fgOrPlain("accent", `\x1b[4m${label ?? schemeLess}\x1b[24m`);
|
|
12
|
+
const linked = urlHyperlinkAlways(webLink, display);
|
|
13
|
+
// Without OSC-8 support, keep the literal URL at the visible prefix.
|
|
14
|
+
return label !== undefined && linked === display ? fgOrPlain("accent", `\x1b[4m${schemeLess}\x1b[24m`) : linked;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* One-shot transcript block that prints a collab browser-join URL as a
|
|
19
|
+
* scannable QR code. The symbol is encoded once at construction (byte mode,
|
|
20
|
+
* EC level M) and rendered as ANSI half-blocks; on terminals too narrow for
|
|
21
|
+
* the symbol it degrades to a one-line hint that includes the URL.
|
|
22
|
+
*
|
|
23
|
+
* The transcript viewport can also clip a live block to a single row under
|
|
24
|
+
* pressure (many short settled blocks — typical when thinking is a one-line
|
|
25
|
+
* summary rather than a tall trace). The QR's first/last rows are a white
|
|
26
|
+
* quiet zone, so a 1-row clip looks like an empty white line. When the
|
|
27
|
+
* allocated height cannot fit the full symbol, degrade to the same hint.
|
|
28
|
+
* The sibling `/collab` status heading can also collapse to its first row
|
|
29
|
+
* under that pressure, so the hint must carry the URL itself — "use the
|
|
30
|
+
* URL above" is not reachable.
|
|
31
|
+
*/
|
|
32
|
+
export class CollabQrCodeComponent implements Component, TranscriptPresentationTarget {
|
|
33
|
+
readonly #lines: readonly string[];
|
|
34
|
+
readonly #minWidth: number;
|
|
35
|
+
#allocatedRows = Number.POSITIVE_INFINITY;
|
|
36
|
+
|
|
37
|
+
constructor(readonly url: string) {
|
|
38
|
+
const rows = renderQrHalfBlocks(QrCode.encodeText(url, "M"));
|
|
39
|
+
this.#lines = rows.map(row => ` ${row}`);
|
|
40
|
+
this.#minWidth = rows.reduce((max, row) => Math.max(max, visibleWidth(row)), 0) + 1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
setTranscriptAllocation(rows: number, _frame?: AnimationFrame): void {
|
|
44
|
+
this.#allocatedRows = Number.isFinite(rows) ? Math.max(0, Math.trunc(rows)) : Number.POSITIVE_INFINITY;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
render(width: number): readonly string[] {
|
|
48
|
+
if (width < this.#minWidth) {
|
|
49
|
+
return [this.#hiddenHint(`terminal width ${width}; need ${this.#minWidth}`, width)];
|
|
50
|
+
}
|
|
51
|
+
if (this.#allocatedRows < this.#lines.length) {
|
|
52
|
+
return [this.#hiddenHint(`viewport height ${this.#allocatedRows}; need ${this.#lines.length}`, width)];
|
|
53
|
+
}
|
|
54
|
+
return this.#lines;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Survives emergency 1-row transcript pressure when this block is otherwise hidden. */
|
|
58
|
+
renderTranscriptBlockEmergencyRow(width: number): string {
|
|
59
|
+
return this.#hiddenHint(
|
|
60
|
+
Number.isFinite(this.#allocatedRows)
|
|
61
|
+
? `viewport height ${this.#allocatedRows}; need ${this.#lines.length}`
|
|
62
|
+
: "transcript pressure",
|
|
63
|
+
width,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
#hiddenHint(reason: string, width: number): string {
|
|
68
|
+
return truncateToWidth(
|
|
69
|
+
`${collabBrowserLink(this.url, "Join")} ${fgOrPlain("warning", `QR code hidden: ${reason}.`)}`,
|
|
70
|
+
width,
|
|
71
|
+
Ellipsis.Omit,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { formatNumber } from "@oh-my-pi/pi-utils";
|
|
2
|
+
import type { ThemeColor } from "../theme/index";
|
|
3
|
+
export type ContextUsageLevel = "normal" | "warning" | "purple" | "error";
|
|
4
|
+
|
|
5
|
+
const CONTEXT_WARNING_PERCENT_THRESHOLD = 50;
|
|
6
|
+
const CONTEXT_WARNING_TOKEN_THRESHOLD = 150_000;
|
|
7
|
+
const CONTEXT_PURPLE_PERCENT_THRESHOLD = 70;
|
|
8
|
+
const CONTEXT_PURPLE_TOKEN_THRESHOLD = 270_000;
|
|
9
|
+
const CONTEXT_ERROR_PERCENT_THRESHOLD = 90;
|
|
10
|
+
const CONTEXT_ERROR_TOKEN_THRESHOLD = 500_000;
|
|
11
|
+
|
|
12
|
+
function reachesThreshold(
|
|
13
|
+
contextPercent: number,
|
|
14
|
+
contextWindow: number,
|
|
15
|
+
percentThreshold: number,
|
|
16
|
+
tokenThreshold: number,
|
|
17
|
+
): boolean {
|
|
18
|
+
if (!Number.isFinite(contextPercent) || contextPercent <= 0) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!Number.isFinite(contextWindow) || contextWindow <= 0) {
|
|
23
|
+
return contextPercent >= percentThreshold;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const tokenPercentThreshold = (tokenThreshold / contextWindow) * 100;
|
|
27
|
+
return contextPercent >= Math.min(percentThreshold, tokenPercentThreshold);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function getContextUsageLevel(contextPercent: number, contextWindow: number): ContextUsageLevel {
|
|
31
|
+
if (
|
|
32
|
+
reachesThreshold(contextPercent, contextWindow, CONTEXT_ERROR_PERCENT_THRESHOLD, CONTEXT_ERROR_TOKEN_THRESHOLD)
|
|
33
|
+
) {
|
|
34
|
+
return "error";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (
|
|
38
|
+
reachesThreshold(contextPercent, contextWindow, CONTEXT_PURPLE_PERCENT_THRESHOLD, CONTEXT_PURPLE_TOKEN_THRESHOLD)
|
|
39
|
+
) {
|
|
40
|
+
return "purple";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (
|
|
44
|
+
reachesThreshold(
|
|
45
|
+
contextPercent,
|
|
46
|
+
contextWindow,
|
|
47
|
+
CONTEXT_WARNING_PERCENT_THRESHOLD,
|
|
48
|
+
CONTEXT_WARNING_TOKEN_THRESHOLD,
|
|
49
|
+
)
|
|
50
|
+
) {
|
|
51
|
+
return "warning";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return "normal";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Format context usage as `<percent>%/<window>` when the model window is known.
|
|
59
|
+
* Unknown windows render as `<tokens>/?`, because `0.0%/0` suggests a real
|
|
60
|
+
* empty context instead of missing provider metadata.
|
|
61
|
+
*/
|
|
62
|
+
export function formatContextUsage(
|
|
63
|
+
contextPercent: number | null | undefined,
|
|
64
|
+
contextWindow: number,
|
|
65
|
+
usedTokens?: number,
|
|
66
|
+
): string {
|
|
67
|
+
if (!Number.isFinite(contextWindow) || contextWindow <= 0) {
|
|
68
|
+
return `${formatNumber(usedTokens ?? 0)}/?`;
|
|
69
|
+
}
|
|
70
|
+
const pct = contextPercent === null || contextPercent === undefined ? "?" : `${contextPercent.toFixed(1)}%`;
|
|
71
|
+
return `${pct}/${formatNumber(contextWindow)}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function getContextUsageThemeColor(level: ContextUsageLevel): ThemeColor {
|
|
75
|
+
switch (level) {
|
|
76
|
+
case "error":
|
|
77
|
+
return "error";
|
|
78
|
+
case "purple":
|
|
79
|
+
return "thinkingHigh";
|
|
80
|
+
case "warning":
|
|
81
|
+
return "warning";
|
|
82
|
+
case "normal":
|
|
83
|
+
return "statusLineContext";
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reusable countdown timer for dialog components.
|
|
3
|
+
*/
|
|
4
|
+
import type { TUI } from "../tui";
|
|
5
|
+
export class CountdownTimer {
|
|
6
|
+
#intervalId: NodeJS.Timeout | undefined;
|
|
7
|
+
#expireTimeoutId: NodeJS.Timeout | undefined;
|
|
8
|
+
#remainingSeconds: number;
|
|
9
|
+
#deadlineMs = 0;
|
|
10
|
+
readonly #initialMs: number;
|
|
11
|
+
|
|
12
|
+
constructor(
|
|
13
|
+
timeoutMs: number,
|
|
14
|
+
private tui: TUI | undefined,
|
|
15
|
+
private onTick: (seconds: number) => void,
|
|
16
|
+
private onExpire: () => void,
|
|
17
|
+
) {
|
|
18
|
+
this.#initialMs = timeoutMs;
|
|
19
|
+
this.#remainingSeconds = Math.ceil(timeoutMs / 1000);
|
|
20
|
+
this.#start();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
#calculateRemainingSeconds(now = Date.now()): number {
|
|
24
|
+
const remainingMs = Math.max(0, this.#deadlineMs - now);
|
|
25
|
+
return Math.ceil(remainingMs / 1000);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#start(): void {
|
|
29
|
+
const now = Date.now();
|
|
30
|
+
this.#deadlineMs = now + this.#initialMs;
|
|
31
|
+
this.#remainingSeconds = this.#calculateRemainingSeconds(now);
|
|
32
|
+
this.onTick(this.#remainingSeconds);
|
|
33
|
+
this.tui?.requestRender();
|
|
34
|
+
|
|
35
|
+
this.#expireTimeoutId = setTimeout(() => {
|
|
36
|
+
this.dispose();
|
|
37
|
+
this.onExpire();
|
|
38
|
+
}, this.#initialMs);
|
|
39
|
+
|
|
40
|
+
this.#startInterval();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
#startInterval(): void {
|
|
44
|
+
if (this.#intervalId) {
|
|
45
|
+
clearInterval(this.#intervalId);
|
|
46
|
+
this.#intervalId = undefined;
|
|
47
|
+
}
|
|
48
|
+
this.#intervalId = setInterval(() => {
|
|
49
|
+
const remainingSeconds = this.#calculateRemainingSeconds();
|
|
50
|
+
if (remainingSeconds !== this.#remainingSeconds) {
|
|
51
|
+
this.#remainingSeconds = remainingSeconds;
|
|
52
|
+
this.onTick(this.#remainingSeconds);
|
|
53
|
+
}
|
|
54
|
+
this.tui?.requestRender();
|
|
55
|
+
}, 1000);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Reset the countdown to its initial value */
|
|
59
|
+
reset(): void {
|
|
60
|
+
this.dispose();
|
|
61
|
+
this.#start();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
dispose(): void {
|
|
65
|
+
if (this.#intervalId) {
|
|
66
|
+
clearInterval(this.#intervalId);
|
|
67
|
+
this.#intervalId = undefined;
|
|
68
|
+
}
|
|
69
|
+
if (this.#expireTimeoutId) {
|
|
70
|
+
clearTimeout(this.#expireTimeoutId);
|
|
71
|
+
this.#expireTimeoutId = undefined;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|