@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,92 @@
|
|
|
1
|
+
import { type MermaidAsciiRenderOptions, renderMermaidAsciiSafe } from "@oh-my-pi/pi-utils/mermaid-ascii";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Options controlling how fenced Mermaid source is resolved to terminal ASCII.
|
|
5
|
+
* Extends the raw render options (theme, color mode, spacing, `useAscii`) with a
|
|
6
|
+
* viewport-fitting hint.
|
|
7
|
+
*/
|
|
8
|
+
export interface MermaidResolveOptions extends MermaidAsciiRenderOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Maximum display width (terminal columns) the diagram should occupy. A
|
|
11
|
+
* layout that overflows this width is re-rendered in the perpendicular
|
|
12
|
+
* orientation — a wide horizontal chain collapses to a tall vertical column
|
|
13
|
+
* (which the terminal can scroll), and a wide vertical fan-out collapses to a
|
|
14
|
+
* tall horizontal column. Omit to keep the source's own layout regardless of
|
|
15
|
+
* width.
|
|
16
|
+
*/
|
|
17
|
+
maxWidth?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Memoizes rendered ASCII (and failures) keyed on the render options + the
|
|
21
|
+
// layout-direction variant + source. Width selection happens per call against
|
|
22
|
+
// the cached renders, so a terminal resize re-decides without re-rendering.
|
|
23
|
+
const cache = new Map<string, string | null>();
|
|
24
|
+
|
|
25
|
+
/** Widest rendered row in display columns (ANSI- and CJK-aware). */
|
|
26
|
+
function asciiDisplayWidth(ascii: string): number {
|
|
27
|
+
let max = 0;
|
|
28
|
+
for (const line of ascii.split("\n")) {
|
|
29
|
+
const width = Bun.stringWidth(line);
|
|
30
|
+
if (width > max) max = width;
|
|
31
|
+
}
|
|
32
|
+
return max;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function renderVariant(
|
|
36
|
+
source: string,
|
|
37
|
+
baseOptions: MermaidAsciiRenderOptions,
|
|
38
|
+
baseKey: string,
|
|
39
|
+
direction: "TD" | "LR" | null,
|
|
40
|
+
): string | null {
|
|
41
|
+
const key = `${baseKey}\x00${direction ?? ""}\x00${source}`;
|
|
42
|
+
const cached = cache.get(key);
|
|
43
|
+
if (cached !== undefined) return cached;
|
|
44
|
+
|
|
45
|
+
const ascii = renderMermaidAsciiSafe(source, direction ? { ...baseOptions, direction } : baseOptions);
|
|
46
|
+
cache.set(key, ascii);
|
|
47
|
+
return ascii;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Resolve mermaid ASCII from fenced block source text.
|
|
52
|
+
* Returns null when rendering fails, while memoizing failures to avoid repeated work.
|
|
53
|
+
*/
|
|
54
|
+
export function resolveMermaidAscii(source: string, options?: MermaidResolveOptions): string | null {
|
|
55
|
+
const normalizedSource = source.replace(/\r\n?/g, "\n").trim();
|
|
56
|
+
if (!normalizedSource) return null;
|
|
57
|
+
|
|
58
|
+
const { maxWidth, ...rest } = options ?? {};
|
|
59
|
+
// Default to uncolored output; callers opt into a themed palette explicitly.
|
|
60
|
+
const baseOptions: MermaidAsciiRenderOptions = { colorMode: "none", ...rest };
|
|
61
|
+
const baseKey = JSON.stringify(baseOptions);
|
|
62
|
+
|
|
63
|
+
const base = renderVariant(normalizedSource, baseOptions, baseKey, null);
|
|
64
|
+
if (base === null) return null;
|
|
65
|
+
if (maxWidth === undefined) return base;
|
|
66
|
+
|
|
67
|
+
let best = base;
|
|
68
|
+
let bestWidth = asciiDisplayWidth(base);
|
|
69
|
+
if (bestWidth <= maxWidth) return base;
|
|
70
|
+
|
|
71
|
+
// The as-authored layout overflows. Render both forced orientations and keep
|
|
72
|
+
// the narrowest (clipping at the call site handles any residual overflow).
|
|
73
|
+
// Re-rendering the already-authored orientation is a cache hit, so this stays
|
|
74
|
+
// cheap, and one of the two will be the perpendicular fit.
|
|
75
|
+
for (const direction of ["TD", "LR"] as const) {
|
|
76
|
+
const variant = renderVariant(normalizedSource, baseOptions, baseKey, direction);
|
|
77
|
+
if (variant === null) continue;
|
|
78
|
+
const variantWidth = asciiDisplayWidth(variant);
|
|
79
|
+
if (variantWidth < bestWidth) {
|
|
80
|
+
best = variant;
|
|
81
|
+
bestWidth = variantWidth;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return best;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Clear the mermaid cache.
|
|
89
|
+
*/
|
|
90
|
+
export function clearMermaidCache(): void {
|
|
91
|
+
cache.clear();
|
|
92
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { type } from "@oh-my-pi/omptype";
|
|
2
|
+
import type { SpinnerFramesOverride } from "./symbols";
|
|
3
|
+
import type { ThemeJson } from "./schema";
|
|
4
|
+
|
|
5
|
+
const themeColorsSchema = type({
|
|
6
|
+
accent: "string | number",
|
|
7
|
+
border: "string | number",
|
|
8
|
+
borderAccent: "string | number",
|
|
9
|
+
borderMuted: "string | number",
|
|
10
|
+
success: "string | number",
|
|
11
|
+
error: "string | number",
|
|
12
|
+
warning: "string | number",
|
|
13
|
+
muted: "string | number",
|
|
14
|
+
dim: "string | number",
|
|
15
|
+
text: "string | number",
|
|
16
|
+
thinkingText: "string | number",
|
|
17
|
+
selectedBg: "string | number",
|
|
18
|
+
userMessageBg: "string | number",
|
|
19
|
+
userMessageText: "string | number",
|
|
20
|
+
customMessageBg: "string | number",
|
|
21
|
+
customMessageText: "string | number",
|
|
22
|
+
customMessageLabel: "string | number",
|
|
23
|
+
toolPendingBg: "string | number",
|
|
24
|
+
toolSuccessBg: "string | number",
|
|
25
|
+
toolErrorBg: "string | number",
|
|
26
|
+
toolTitle: "string | number",
|
|
27
|
+
toolOutput: "string | number",
|
|
28
|
+
mdHeading: "string | number",
|
|
29
|
+
mdLink: "string | number",
|
|
30
|
+
mdLinkUrl: "string | number",
|
|
31
|
+
mdCode: "string | number",
|
|
32
|
+
mdCodeBlock: "string | number",
|
|
33
|
+
mdCodeBlockBorder: "string | number",
|
|
34
|
+
mdQuote: "string | number",
|
|
35
|
+
mdQuoteBorder: "string | number",
|
|
36
|
+
mdHr: "string | number",
|
|
37
|
+
mdListBullet: "string | number",
|
|
38
|
+
toolDiffAdded: "string | number",
|
|
39
|
+
toolDiffRemoved: "string | number",
|
|
40
|
+
toolDiffContext: "string | number",
|
|
41
|
+
syntaxComment: "string | number",
|
|
42
|
+
syntaxKeyword: "string | number",
|
|
43
|
+
syntaxFunction: "string | number",
|
|
44
|
+
syntaxVariable: "string | number",
|
|
45
|
+
syntaxString: "string | number",
|
|
46
|
+
syntaxNumber: "string | number",
|
|
47
|
+
syntaxType: "string | number",
|
|
48
|
+
syntaxOperator: "string | number",
|
|
49
|
+
syntaxPunctuation: "string | number",
|
|
50
|
+
thinkingOff: "string | number",
|
|
51
|
+
thinkingMinimal: "string | number",
|
|
52
|
+
thinkingLow: "string | number",
|
|
53
|
+
thinkingMedium: "string | number",
|
|
54
|
+
thinkingHigh: "string | number",
|
|
55
|
+
thinkingXhigh: "string | number",
|
|
56
|
+
"thinkingMax?": "string | number",
|
|
57
|
+
bashMode: "string | number",
|
|
58
|
+
pythonMode: "string | number",
|
|
59
|
+
statusLineBg: "string | number",
|
|
60
|
+
statusLineSep: "string | number",
|
|
61
|
+
statusLineModel: "string | number",
|
|
62
|
+
statusLinePath: "string | number",
|
|
63
|
+
statusLineGitClean: "string | number",
|
|
64
|
+
statusLineGitDirty: "string | number",
|
|
65
|
+
statusLineContext: "string | number",
|
|
66
|
+
statusLineSpend: "string | number",
|
|
67
|
+
statusLineStaged: "string | number",
|
|
68
|
+
statusLineDirty: "string | number",
|
|
69
|
+
statusLineUntracked: "string | number",
|
|
70
|
+
statusLineOutput: "string | number",
|
|
71
|
+
statusLineCost: "string | number",
|
|
72
|
+
statusLineSubagents: "string | number",
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const spinnerFramesSchema = type("unknown").narrow((value): value is SpinnerFramesOverride => {
|
|
76
|
+
if (Array.isArray(value)) return value.length >= 1 && value.every(item => typeof item === "string");
|
|
77
|
+
if (!value || typeof value !== "object") return false;
|
|
78
|
+
const obj = value as Record<string, unknown>;
|
|
79
|
+
const status = obj.status;
|
|
80
|
+
const activity = obj.activity;
|
|
81
|
+
if (status === undefined && activity === undefined) return false;
|
|
82
|
+
if (
|
|
83
|
+
status !== undefined &&
|
|
84
|
+
(!Array.isArray(status) || status.length < 1 || !status.every(item => typeof item === "string"))
|
|
85
|
+
) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
if (
|
|
89
|
+
activity !== undefined &&
|
|
90
|
+
(!Array.isArray(activity) || activity.length < 1 || !activity.every(item => typeof item === "string"))
|
|
91
|
+
) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
return true;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const themeJsonSchema = type({
|
|
98
|
+
"$schema?": "string",
|
|
99
|
+
name: "string",
|
|
100
|
+
"vars?": { "[string]": "string | number" },
|
|
101
|
+
colors: themeColorsSchema,
|
|
102
|
+
"export?": {
|
|
103
|
+
"pageBg?": "string | number",
|
|
104
|
+
"cardBg?": "string | number",
|
|
105
|
+
"infoBg?": "string | number",
|
|
106
|
+
},
|
|
107
|
+
"symbols?": {
|
|
108
|
+
"preset?": "'unicode' | 'nerd' | 'ascii'",
|
|
109
|
+
"overrides?": { "[string]": "string" },
|
|
110
|
+
"spinnerFrames?": spinnerFramesSchema,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
/** Validate a custom theme with the full omptype contract. */
|
|
115
|
+
export function validateThemeJson(value: unknown): ThemeJson {
|
|
116
|
+
const parsed = themeJsonSchema(value);
|
|
117
|
+
if (parsed instanceof type.errors) throw new Error(parsed.summary);
|
|
118
|
+
return parsed as ThemeJson;
|
|
119
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import type { SpinnerFramesOverride } from "./symbols";
|
|
2
|
+
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// Types
|
|
5
|
+
// ============================================================================
|
|
6
|
+
|
|
7
|
+
export type ColorValue = string | number;
|
|
8
|
+
|
|
9
|
+
export interface ThemeJson {
|
|
10
|
+
$schema?: string;
|
|
11
|
+
name: string;
|
|
12
|
+
vars?: Record<string, ColorValue>;
|
|
13
|
+
colors: Omit<Record<ThemeColor | ThemeBg, ColorValue>, "thinkingMax"> & { thinkingMax?: ColorValue };
|
|
14
|
+
export?: {
|
|
15
|
+
pageBg?: ColorValue;
|
|
16
|
+
cardBg?: ColorValue;
|
|
17
|
+
infoBg?: ColorValue;
|
|
18
|
+
};
|
|
19
|
+
symbols?: {
|
|
20
|
+
preset?: "unicode" | "nerd" | "ascii";
|
|
21
|
+
overrides?: Record<string, string>;
|
|
22
|
+
spinnerFrames?: SpinnerFramesOverride;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type ThemeColor =
|
|
27
|
+
| "accent"
|
|
28
|
+
| "border"
|
|
29
|
+
| "borderAccent"
|
|
30
|
+
| "borderMuted"
|
|
31
|
+
| "success"
|
|
32
|
+
| "error"
|
|
33
|
+
| "warning"
|
|
34
|
+
| "muted"
|
|
35
|
+
| "dim"
|
|
36
|
+
| "text"
|
|
37
|
+
| "thinkingText"
|
|
38
|
+
| "userMessageText"
|
|
39
|
+
| "customMessageText"
|
|
40
|
+
| "customMessageLabel"
|
|
41
|
+
| "toolTitle"
|
|
42
|
+
| "toolOutput"
|
|
43
|
+
| "mdHeading"
|
|
44
|
+
| "mdLink"
|
|
45
|
+
| "mdLinkUrl"
|
|
46
|
+
| "mdCode"
|
|
47
|
+
| "mdCodeBlock"
|
|
48
|
+
| "mdCodeBlockBorder"
|
|
49
|
+
| "mdQuote"
|
|
50
|
+
| "mdQuoteBorder"
|
|
51
|
+
| "mdHr"
|
|
52
|
+
| "mdListBullet"
|
|
53
|
+
| "toolDiffAdded"
|
|
54
|
+
| "toolDiffRemoved"
|
|
55
|
+
| "toolDiffContext"
|
|
56
|
+
| "syntaxComment"
|
|
57
|
+
| "syntaxKeyword"
|
|
58
|
+
| "syntaxFunction"
|
|
59
|
+
| "syntaxVariable"
|
|
60
|
+
| "syntaxString"
|
|
61
|
+
| "syntaxNumber"
|
|
62
|
+
| "syntaxType"
|
|
63
|
+
| "syntaxOperator"
|
|
64
|
+
| "syntaxPunctuation"
|
|
65
|
+
| "thinkingOff"
|
|
66
|
+
| "thinkingMinimal"
|
|
67
|
+
| "thinkingLow"
|
|
68
|
+
| "thinkingMedium"
|
|
69
|
+
| "thinkingHigh"
|
|
70
|
+
| "thinkingXhigh"
|
|
71
|
+
| "thinkingMax"
|
|
72
|
+
| "bashMode"
|
|
73
|
+
| "pythonMode"
|
|
74
|
+
| "statusLineSep"
|
|
75
|
+
| "statusLineModel"
|
|
76
|
+
| "statusLinePath"
|
|
77
|
+
| "statusLineGitClean"
|
|
78
|
+
| "statusLineGitDirty"
|
|
79
|
+
| "statusLineContext"
|
|
80
|
+
| "statusLineSpend"
|
|
81
|
+
| "statusLineStaged"
|
|
82
|
+
| "statusLineDirty"
|
|
83
|
+
| "statusLineUntracked"
|
|
84
|
+
| "statusLineOutput"
|
|
85
|
+
| "statusLineCost"
|
|
86
|
+
| "statusLineSubagents";
|
|
87
|
+
|
|
88
|
+
/** Set of all valid ThemeColor string values for runtime validation */
|
|
89
|
+
const THEME_COLOR_RECORD = {
|
|
90
|
+
accent: true,
|
|
91
|
+
border: true,
|
|
92
|
+
borderAccent: true,
|
|
93
|
+
borderMuted: true,
|
|
94
|
+
success: true,
|
|
95
|
+
error: true,
|
|
96
|
+
warning: true,
|
|
97
|
+
muted: true,
|
|
98
|
+
dim: true,
|
|
99
|
+
text: true,
|
|
100
|
+
thinkingText: true,
|
|
101
|
+
userMessageText: true,
|
|
102
|
+
customMessageText: true,
|
|
103
|
+
customMessageLabel: true,
|
|
104
|
+
toolTitle: true,
|
|
105
|
+
toolOutput: true,
|
|
106
|
+
mdHeading: true,
|
|
107
|
+
mdLink: true,
|
|
108
|
+
mdLinkUrl: true,
|
|
109
|
+
mdCode: true,
|
|
110
|
+
mdCodeBlock: true,
|
|
111
|
+
mdCodeBlockBorder: true,
|
|
112
|
+
mdQuote: true,
|
|
113
|
+
mdQuoteBorder: true,
|
|
114
|
+
mdHr: true,
|
|
115
|
+
mdListBullet: true,
|
|
116
|
+
toolDiffAdded: true,
|
|
117
|
+
toolDiffRemoved: true,
|
|
118
|
+
toolDiffContext: true,
|
|
119
|
+
syntaxComment: true,
|
|
120
|
+
syntaxKeyword: true,
|
|
121
|
+
syntaxFunction: true,
|
|
122
|
+
syntaxVariable: true,
|
|
123
|
+
syntaxString: true,
|
|
124
|
+
syntaxNumber: true,
|
|
125
|
+
syntaxType: true,
|
|
126
|
+
syntaxOperator: true,
|
|
127
|
+
syntaxPunctuation: true,
|
|
128
|
+
thinkingOff: true,
|
|
129
|
+
thinkingMinimal: true,
|
|
130
|
+
thinkingLow: true,
|
|
131
|
+
thinkingMedium: true,
|
|
132
|
+
thinkingHigh: true,
|
|
133
|
+
thinkingXhigh: true,
|
|
134
|
+
thinkingMax: true,
|
|
135
|
+
bashMode: true,
|
|
136
|
+
pythonMode: true,
|
|
137
|
+
statusLineSep: true,
|
|
138
|
+
statusLineModel: true,
|
|
139
|
+
statusLinePath: true,
|
|
140
|
+
statusLineGitClean: true,
|
|
141
|
+
statusLineGitDirty: true,
|
|
142
|
+
statusLineContext: true,
|
|
143
|
+
statusLineSpend: true,
|
|
144
|
+
statusLineStaged: true,
|
|
145
|
+
statusLineDirty: true,
|
|
146
|
+
statusLineUntracked: true,
|
|
147
|
+
statusLineOutput: true,
|
|
148
|
+
statusLineCost: true,
|
|
149
|
+
statusLineSubagents: true,
|
|
150
|
+
} satisfies Record<ThemeColor, true>;
|
|
151
|
+
|
|
152
|
+
const VALID_THEME_COLORS: ReadonlySet<string> = new Set(Object.keys(THEME_COLOR_RECORD));
|
|
153
|
+
|
|
154
|
+
/** Check if a string is a valid ThemeColor value */
|
|
155
|
+
export function isValidThemeColor(color: string): color is ThemeColor {
|
|
156
|
+
return VALID_THEME_COLORS.has(color);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export type ThemeBg =
|
|
160
|
+
| "selectedBg"
|
|
161
|
+
| "userMessageBg"
|
|
162
|
+
| "customMessageBg"
|
|
163
|
+
| "toolPendingBg"
|
|
164
|
+
| "toolSuccessBg"
|
|
165
|
+
| "toolErrorBg"
|
|
166
|
+
| "statusLineBg";
|
|
167
|
+
|
|
168
|
+
export type ColorMode = "truecolor" | "256color";
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { TERMINAL } from "../terminal-capabilities";
|
|
2
|
+
import { hexToOklch, oklchCusp, oklchToHex, relativeLuminance } from "@oh-my-pi/pi-utils";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Derive a stable 32-bit hash from a string using djb2.
|
|
6
|
+
*/
|
|
7
|
+
function nameToHash(name: string): number {
|
|
8
|
+
let hash = 5381;
|
|
9
|
+
for (let i = 0; i < name.length; i++) {
|
|
10
|
+
hash = ((hash << 5) + hash) ^ name.charCodeAt(i);
|
|
11
|
+
hash = hash >>> 0; // keep 32-bit unsigned
|
|
12
|
+
}
|
|
13
|
+
return hash;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Fallback cusp-chroma fraction when the theme accent is unparseable or
|
|
18
|
+
* near-gray: sits at each hue's gamut cusp at 70% of its peak chroma,
|
|
19
|
+
* matching a typical vivid accent.
|
|
20
|
+
*/
|
|
21
|
+
const FALLBACK_CUSP_CHROMA_FRACTION = 0.7;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Chroma bounds for the carried theme-accent chroma: the floor keeps the
|
|
25
|
+
* hash-derived hue readable when the theme accent is near-gray, the ceiling
|
|
26
|
+
* tempers neon accents so six sessions don't turn the status line into a
|
|
27
|
+
* highlighter set.
|
|
28
|
+
*/
|
|
29
|
+
const MIN_CHROMA = 0.05;
|
|
30
|
+
const MAX_CHROMA = 0.21;
|
|
31
|
+
|
|
32
|
+
/** Lightness bounds on dark themes so a carried accent lightness stays visible on dark surfaces. */
|
|
33
|
+
const DARK_MIN_LIGHTNESS = 0.65;
|
|
34
|
+
const DARK_MAX_LIGHTNESS = 0.88;
|
|
35
|
+
|
|
36
|
+
/** Minimum contrast ratio (WCAG AA large text) between a light-theme accent and its surface. */
|
|
37
|
+
const ACCENT_MIN_CONTRAST = 3;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Largest relative luminance an accent may have while still meeting
|
|
41
|
+
* {@link ACCENT_MIN_CONTRAST} against a surface of the given luminance.
|
|
42
|
+
*/
|
|
43
|
+
function accentLuminanceCap(surfaceLuminance: number): number {
|
|
44
|
+
return Math.max(0, (surfaceLuminance + 0.05) / ACCENT_MIN_CONTRAST - 0.05);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Minimum angular distance in hue degrees from any theme color to avoid visual collision. */
|
|
48
|
+
const MIN_HUE_DISTANCE = 10;
|
|
49
|
+
/** OKLCH chroma threshold below which hue is meaningless (near-gray). */
|
|
50
|
+
const MIN_CHROMA_FOR_HUE = 0.03;
|
|
51
|
+
|
|
52
|
+
/** Angular distance between two hue values (0-360). */
|
|
53
|
+
function hueDistance(a: number, b: number): number {
|
|
54
|
+
const d = Math.abs(a - b);
|
|
55
|
+
return Math.min(d, 360 - d);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Parse OKLCH hue (0-360) from a hex color string.
|
|
60
|
+
* Returns undefined for near-gray colors where hue is not meaningful.
|
|
61
|
+
*/
|
|
62
|
+
function hexToHue(hex: string): number | undefined {
|
|
63
|
+
const { c, h } = hexToOklch(hex);
|
|
64
|
+
if (!Number.isFinite(h) || c < MIN_CHROMA_FOR_HUE) return undefined;
|
|
65
|
+
return h;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Find a hue at least {@link MIN_HUE_DISTANCE} from all occupied hues,
|
|
70
|
+
* walked outward in arc positions so it never leaves the admissible arc.
|
|
71
|
+
* Returns the hue at `pos` unchanged if no safe hue exists within the arc.
|
|
72
|
+
*/
|
|
73
|
+
function findSafeHue(pos: number, occupied: number[], intervals: readonly HueInterval[]): number {
|
|
74
|
+
const total = arcLength(intervals);
|
|
75
|
+
const hueAt = (p: number) => arcToHue(intervals, Math.max(0, Math.min(total - 1, p)));
|
|
76
|
+
const target = hueAt(pos);
|
|
77
|
+
if (occupied.length === 0) return target;
|
|
78
|
+
if (occupied.every(h => hueDistance(target, h) >= MIN_HUE_DISTANCE)) {
|
|
79
|
+
return target;
|
|
80
|
+
}
|
|
81
|
+
for (let d = 1; d < total; d++) {
|
|
82
|
+
for (const dir of [1, -1]) {
|
|
83
|
+
const candidate = hueAt(pos + d * dir);
|
|
84
|
+
if (occupied.every(h => hueDistance(candidate, h) >= MIN_HUE_DISTANCE)) {
|
|
85
|
+
return candidate;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// fallback: keep the original target if no safe spot exists within the arc
|
|
90
|
+
return target;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Inclusive hue interval [start, end] in OKLCH degrees. */
|
|
94
|
+
type HueInterval = readonly [number, number];
|
|
95
|
+
|
|
96
|
+
/** Number of integer hue positions across all intervals. */
|
|
97
|
+
function arcLength(intervals: readonly HueInterval[]): number {
|
|
98
|
+
let n = 0;
|
|
99
|
+
for (const [a, b] of intervals) n += b - a + 1;
|
|
100
|
+
return n;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Map an arc position (`0..arcLength-1`) to its hue degree. */
|
|
104
|
+
function arcToHue(intervals: readonly HueInterval[], pos: number): number {
|
|
105
|
+
let p = pos;
|
|
106
|
+
for (const [a, b] of intervals) {
|
|
107
|
+
const n = b - a + 1;
|
|
108
|
+
if (p < n) return a + p;
|
|
109
|
+
p -= n;
|
|
110
|
+
}
|
|
111
|
+
return intervals[intervals.length - 1]?.[1] ?? 0;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Dark themes draw hues from the full wheel, restricted to hues whose
|
|
116
|
+
* sRGB gamut cusp is reachable under {@link DARK_MAX_LIGHTNESS}. A hue whose
|
|
117
|
+
* vividness peak needs more lightness than the cap can only render as a
|
|
118
|
+
* darkened version of itself, and yellow (cusp L ≈ 0.97) is the one hue
|
|
119
|
+
* that shifts category when darkened — to olive/mustard — so the derivation
|
|
120
|
+
* excludes the yellow/chartreuse core (≈94–138°) and the over-light cyan
|
|
121
|
+
* peak (≈158–200°) for every theme. Collisions with theme-semantic hues are
|
|
122
|
+
* handled per-theme by {@link findSafeHue}, not by narrowing the arc.
|
|
123
|
+
*/
|
|
124
|
+
const DARK_HUE_INTERVALS: readonly HueInterval[] = (() => {
|
|
125
|
+
const intervals: Array<[number, number]> = [];
|
|
126
|
+
let start = -1;
|
|
127
|
+
for (let h = 0; h <= 360; h++) {
|
|
128
|
+
if (h < 360 && oklchCusp(h).l <= DARK_MAX_LIGHTNESS) {
|
|
129
|
+
if (start < 0) start = h;
|
|
130
|
+
} else if (start >= 0) {
|
|
131
|
+
intervals.push([start, h - 1]);
|
|
132
|
+
start = -1;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return intervals;
|
|
136
|
+
})();
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Light themes keep a declared cool band (cyan → blue → purple); lightness
|
|
140
|
+
* there is governed by the contrast bisection against the surface, not the
|
|
141
|
+
* dark cap, and darkened cool hues stay categorical (dark blue is blue).
|
|
142
|
+
*/
|
|
143
|
+
const LIGHT_HUE_INTERVALS: readonly HueInterval[] = [[195, 330]];
|
|
144
|
+
|
|
145
|
+
/** Theme-derived inputs for {@link getSessionAccentHex}; see `Theme.sessionAccentInputs`. */
|
|
146
|
+
export interface SessionAccentTheme {
|
|
147
|
+
/** Theme accent hex; the session accent adopts its OKLCH lightness and chroma. */
|
|
148
|
+
accentHex: string;
|
|
149
|
+
/** Major theme color hexes checked for hue collision. */
|
|
150
|
+
colorHexes: string[];
|
|
151
|
+
/** WCAG luminance of the status-line surface on light themes; undefined on dark themes. */
|
|
152
|
+
surfaceLuminance?: number;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Derive a stable CSS hex accent color from a session name and the active theme.
|
|
157
|
+
*
|
|
158
|
+
* The session name hash picks only the **hue**, from a dark/light-specific
|
|
159
|
+
* hue arc so the accent feels natural for the theme type: the full wheel on
|
|
160
|
+
* dark minus hues whose vividness peak is unreachable under the dark
|
|
161
|
+
* lightness cap (see {@link DARK_HUE_INTERVALS}); cool on light. **Lightness and chroma are carried over from the theme's own accent
|
|
162
|
+
* color**, normalized to the sRGB gamut cusp of each hue: the lightness at
|
|
163
|
+
* which a hue peaks in chroma varies wildly (yellow ≈ 0.97, blue ≈ 0.45), so
|
|
164
|
+
* absolute OKLCH lightness cannot transfer between hues — a pink accent's
|
|
165
|
+
* l≈0.67 re-hued to yellow is mustard, not vivid yellow. Instead the
|
|
166
|
+
* accent's position relative to its own hue's cusp (lightness side and
|
|
167
|
+
* chroma fraction) is re-applied at the target hue's cusp, so the session
|
|
168
|
+
* accent inherits the theme's vividness at every hue. The hue is checked against all
|
|
169
|
+
* theme color hues and shifted if it lands within {@link MIN_HUE_DISTANCE}
|
|
170
|
+
* of one, but the shift walks along the admissible arc so it never drifts
|
|
171
|
+
* into an unrelated or excluded part of the spectrum.
|
|
172
|
+
*
|
|
173
|
+
* On dark themes (`surfaceLuminance` undefined) the carried lightness is
|
|
174
|
+
* clamped to stay visible on dark surfaces. On light themes it is reduced
|
|
175
|
+
* until the accent's luminance clears {@link ACCENT_MIN_CONTRAST} against
|
|
176
|
+
* the actual surface it renders on — legible on near-white *and* mid-light
|
|
177
|
+
* backgrounds.
|
|
178
|
+
*
|
|
179
|
+
* @param name — session name for per-session uniqueness.
|
|
180
|
+
* @param theme — accent hex, collision colors, and surface luminance of the active theme.
|
|
181
|
+
*/
|
|
182
|
+
export function getSessionAccentHex(name: string, theme: SessionAccentTheme): string {
|
|
183
|
+
// 1. Pick hue range based on theme mode
|
|
184
|
+
const isDark = theme.surfaceLuminance === undefined;
|
|
185
|
+
const intervals = isDark ? DARK_HUE_INTERVALS : LIGHT_HUE_INTERVALS;
|
|
186
|
+
|
|
187
|
+
// 2. Session name picks a position along the admissible arc
|
|
188
|
+
const pos = nameToHash(name) % arcLength(intervals);
|
|
189
|
+
|
|
190
|
+
// 3. Shift away if too close to any theme color — stays within the arc
|
|
191
|
+
const themeHues = theme.colorHexes.map(hexToHue).filter((h): h is number => h !== undefined);
|
|
192
|
+
const targetHue = findSafeHue(pos, themeHues, intervals);
|
|
193
|
+
|
|
194
|
+
// 4. Carry the theme accent's perceived weight, re-normalized to the
|
|
195
|
+
// target hue's gamut cusp (see doc comment above).
|
|
196
|
+
const accent = hexToOklch(theme.accentHex);
|
|
197
|
+
const usable =
|
|
198
|
+
Number.isFinite(accent.l) &&
|
|
199
|
+
Number.isFinite(accent.c) &&
|
|
200
|
+
Number.isFinite(accent.h) &&
|
|
201
|
+
accent.c >= MIN_CHROMA_FOR_HUE;
|
|
202
|
+
const target = oklchCusp(targetHue);
|
|
203
|
+
let lightness: number;
|
|
204
|
+
let chromaFraction: number;
|
|
205
|
+
if (usable) {
|
|
206
|
+
const source = oklchCusp(accent.h);
|
|
207
|
+
// Preserve which side of the cusp the accent sits on and how far along:
|
|
208
|
+
// below-cusp accents map proportionally into [0, targetCusp.l], above-cusp
|
|
209
|
+
// (pastel) accents into [targetCusp.l, 1].
|
|
210
|
+
lightness =
|
|
211
|
+
accent.l <= source.l
|
|
212
|
+
? (accent.l / source.l) * target.l
|
|
213
|
+
: target.l + ((accent.l - source.l) / (1 - source.l)) * (1 - target.l);
|
|
214
|
+
chromaFraction = accent.c / source.c;
|
|
215
|
+
} else {
|
|
216
|
+
lightness = target.l;
|
|
217
|
+
chromaFraction = FALLBACK_CUSP_CHROMA_FRACTION;
|
|
218
|
+
}
|
|
219
|
+
const chroma = Math.max(MIN_CHROMA, Math.min(MAX_CHROMA, chromaFraction * target.c));
|
|
220
|
+
|
|
221
|
+
// 5. Lightness/contrast — clamped visible on dark, bisected for AA on light
|
|
222
|
+
if (theme.surfaceLuminance === undefined) {
|
|
223
|
+
const l = Math.max(DARK_MIN_LIGHTNESS, Math.min(DARK_MAX_LIGHTNESS, lightness));
|
|
224
|
+
return oklchToHex({ l, c: chroma, h: targetHue });
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const cap = accentLuminanceCap(theme.surfaceLuminance);
|
|
228
|
+
const top = oklchToHex({ l: lightness, c: chroma, h: targetHue });
|
|
229
|
+
if ((relativeLuminance(top) ?? 0) <= cap) return top;
|
|
230
|
+
|
|
231
|
+
// Bisect lightness: `lo` always yields luminance <= cap, `hi` always above it.
|
|
232
|
+
let lo = 0;
|
|
233
|
+
let hi = lightness;
|
|
234
|
+
for (let i = 0; i < 20; i++) {
|
|
235
|
+
const mid = (lo + hi) / 2;
|
|
236
|
+
if ((relativeLuminance(oklchToHex({ l: mid, c: chroma, h: targetHue })) ?? 0) > cap) {
|
|
237
|
+
hi = mid;
|
|
238
|
+
} else {
|
|
239
|
+
lo = mid;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return oklchToHex({ l: lo, c: chroma, h: targetHue });
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Convert a hex accent color to an ANSI foreground escape sequence matching
|
|
247
|
+
* the detected terminal color depth.
|
|
248
|
+
* Returns `undefined` if `hex` is nullish or Bun.color conversion fails.
|
|
249
|
+
*/
|
|
250
|
+
export function getSessionAccentAnsi(hex: string | undefined): string | undefined {
|
|
251
|
+
if (!hex) return undefined;
|
|
252
|
+
return Bun.color(hex, TERMINAL.trueColor ? "ansi-16m" : "ansi-256") ?? undefined;
|
|
253
|
+
}
|