@deepseek-harness-tui/dsh-tui 0.11.1 → 0.11.2
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/README.md +50 -20
- package/assets/whale-girl/whale-girl-dark.png +0 -0
- package/assets/whale-girl/whale-girl-happy.png +0 -0
- package/assets/whale-girl/whale-girl.png +0 -0
- package/bin/dsh-tui.js +63 -3
- package/cordis.patch.yml +39 -17
- package/cordis.yml +3 -2
- package/lib/settings.json +1272 -0
- package/lib/types/adapter/channel/ui-policy.d.ts +9 -2
- package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
- package/lib/types/adapter/channel/ui-policy.js +13 -0
- package/lib/types/adapter/kernel/replay.d.ts.map +1 -1
- package/lib/types/adapter/kernel/replay.js +2 -0
- package/lib/types/adapter/ports/channel-display.d.ts +12 -0
- package/lib/types/adapter/ports/channel-display.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-session.d.ts +38 -0
- package/lib/types/adapter/ports/channel-session.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-settings.d.ts +12 -0
- package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-ui.d.ts +46 -4
- package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-view.d.ts +43 -0
- package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +2 -0
- package/lib/types/components/BalanceReportRow.d.ts +10 -2
- package/lib/types/components/BalanceReportRow.d.ts.map +1 -1
- package/lib/types/components/BalanceReportRow.js +18 -4
- package/lib/types/components/CompactionStatusRow.d.ts +24 -0
- package/lib/types/components/CompactionStatusRow.d.ts.map +1 -0
- package/lib/types/components/CompactionStatusRow.js +72 -0
- package/lib/types/components/GoalTodoPanel.js +2 -2
- package/lib/types/components/HelpMenu.d.ts +2 -2
- package/lib/types/components/HelpMenu.d.ts.map +1 -1
- package/lib/types/components/HelpMenu.js +5 -4
- package/lib/types/components/InlineMathParagraph.d.ts +22 -0
- package/lib/types/components/InlineMathParagraph.d.ts.map +1 -0
- package/lib/types/components/InlineMathParagraph.js +178 -0
- package/lib/types/components/LogoV2.d.ts +41 -3
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +148 -24
- package/lib/types/components/Markdown.d.ts +10 -3
- package/lib/types/components/Markdown.d.ts.map +1 -1
- package/lib/types/components/Markdown.js +47 -14
- package/lib/types/components/MathBlock.d.ts +13 -0
- package/lib/types/components/MathBlock.d.ts.map +1 -0
- package/lib/types/components/MathBlock.js +136 -0
- package/lib/types/components/MessageList.d.ts +10 -1
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +13 -4
- package/lib/types/components/MigratePicker.d.ts +30 -0
- package/lib/types/components/MigratePicker.d.ts.map +1 -0
- package/lib/types/components/MigratePicker.js +38 -0
- package/lib/types/components/PromptInput.d.ts +17 -0
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +48 -7
- package/lib/types/components/SplitDiffView.d.ts.map +1 -1
- package/lib/types/components/SplitDiffView.js +2 -1
- package/lib/types/components/StarPrompt.d.ts +53 -0
- package/lib/types/components/StarPrompt.d.ts.map +1 -0
- package/lib/types/components/StarPrompt.js +281 -0
- package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
- package/lib/types/components/StreamingMarkdown.js +20 -3
- package/lib/types/components/TimelineRail.d.ts.map +1 -1
- package/lib/types/components/TimelineRail.js +9 -1
- package/lib/types/components/Whale.d.ts +17 -8
- package/lib/types/components/Whale.d.ts.map +1 -1
- package/lib/types/components/Whale.js +25 -15
- package/lib/types/components/WhaleGirl.d.ts +29 -0
- package/lib/types/components/WhaleGirl.d.ts.map +1 -0
- package/lib/types/components/WhaleGirl.js +32 -0
- package/lib/types/components/WorkingSpinner.d.ts +4 -1
- package/lib/types/components/WorkingSpinner.d.ts.map +1 -1
- package/lib/types/components/WorkingSpinner.js +2 -2
- package/lib/types/components/bigfont.d.ts +47 -18
- package/lib/types/components/bigfont.d.ts.map +1 -1
- package/lib/types/components/bigfont.js +55 -40
- package/lib/types/components/design-system/ThemeProvider.d.ts +6 -0
- package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -1
- package/lib/types/components/design-system/ThemeProvider.js +40 -1
- package/lib/types/components/maidPortrait.d.ts +44 -0
- package/lib/types/components/maidPortrait.d.ts.map +1 -0
- package/lib/types/components/maidPortrait.js +178 -0
- package/lib/types/components/mathPreview.d.ts +25 -0
- package/lib/types/components/mathPreview.d.ts.map +1 -0
- package/lib/types/components/mathPreview.js +48 -0
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantThinkingMessage.js +2 -1
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +3 -2
- package/lib/types/components/messages/TranscriptImages.d.ts.map +1 -1
- package/lib/types/components/messages/TranscriptImages.js +11 -1
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts +14 -2
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.js +80 -38
- package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
- package/lib/types/components/questions/PlanReviewPanel.js +3 -3
- package/lib/types/components/sessions/ForeignSessionRow.d.ts +34 -0
- package/lib/types/components/sessions/ForeignSessionRow.d.ts.map +1 -0
- package/lib/types/components/sessions/ForeignSessionRow.js +43 -0
- package/lib/types/components/sessions/SourceTabs.d.ts +52 -0
- package/lib/types/components/sessions/SourceTabs.d.ts.map +1 -0
- package/lib/types/components/sessions/SourceTabs.js +70 -0
- package/lib/types/components/splashEggs.d.ts +56 -0
- package/lib/types/components/splashEggs.d.ts.map +1 -0
- package/lib/types/components/splashEggs.js +67 -0
- package/lib/types/components/splashFonts.d.ts +119 -0
- package/lib/types/components/splashFonts.d.ts.map +1 -0
- package/lib/types/components/splashFonts.js +267 -0
- package/lib/types/components/splashLayout.d.ts +41 -0
- package/lib/types/components/splashLayout.d.ts.map +1 -0
- package/lib/types/components/splashLayout.js +40 -0
- package/lib/types/components/whaleGirlSprite.d.ts +17 -0
- package/lib/types/components/whaleGirlSprite.d.ts.map +1 -0
- package/lib/types/components/whaleGirlSprite.js +47 -0
- package/lib/types/deepseekPricing.d.ts +74 -0
- package/lib/types/deepseekPricing.d.ts.map +1 -1
- package/lib/types/deepseekPricing.js +110 -11
- package/lib/types/dsh-adapter/channel/action-readiness.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/action-readiness.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/action-readiness.js +6 -1
- package/lib/types/dsh-adapter/channel/background-action.d.ts +1 -0
- package/lib/types/dsh-adapter/channel/background-action.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/background-action.js +1 -0
- package/lib/types/dsh-adapter/channel/binding-events.d.ts +8 -9
- package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/binding-events.js +69 -21
- package/lib/types/dsh-adapter/channel/compaction.d.ts +2 -1
- package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/compaction.js +35 -2
- package/lib/types/dsh-adapter/channel/local-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/local-actions.js +6 -1
- package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/model-switch.js +5 -1
- package/lib/types/dsh-adapter/channel/paths.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/paths.js +7 -1
- package/lib/types/dsh-adapter/channel/preferences.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/preferences.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/preferences.js +16 -0
- package/lib/types/dsh-adapter/channel/projection.d.ts +1 -2
- package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/projection.js +127 -17
- package/lib/types/dsh-adapter/channel/question-record.d.ts +76 -0
- package/lib/types/dsh-adapter/channel/question-record.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/question-record.js +107 -0
- package/lib/types/dsh-adapter/channel/session-lineage.d.ts +42 -0
- package/lib/types/dsh-adapter/channel/session-lineage.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-lineage.js +51 -0
- package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts +2 -0
- package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-live-adoption.js +9 -3
- package/lib/types/dsh-adapter/channel/session-metadata.d.ts +2 -1
- package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-metadata.js +39 -7
- package/lib/types/dsh-adapter/channel/session-reset.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-reset.js +7 -0
- package/lib/types/dsh-adapter/channel/session-resume.d.ts +1 -0
- package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-resume.js +4 -2
- package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/settings-host.js +8 -0
- package/lib/types/dsh-adapter/channel/state.d.ts +14 -1
- package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/state.js +6 -1
- package/lib/types/dsh-adapter/channel/subagent-projection.d.ts +30 -35
- package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/subagent-projection.js +138 -4
- package/lib/types/dsh-adapter/channel/types.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +19 -4
- package/lib/types/dsh-adapter/compat/messages.d.ts +6 -0
- package/lib/types/dsh-adapter/compat/messages.d.ts.map +1 -1
- package/lib/types/dsh-adapter/compat/messages.js +9 -0
- package/lib/types/dsh-adapter/contract.d.ts +5 -5
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +8 -6
- package/lib/types/dsh-adapter/index.d.ts +36 -1
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +22 -6
- package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts +3 -0
- package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/claude-code.js +131 -0
- package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.d.ts +17 -0
- package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.js +329 -0
- package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts +3 -0
- package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/codex.js +102 -0
- package/lib/types/dsh-adapter/migrate/adapters/codex.parse.d.ts +16 -0
- package/lib/types/dsh-adapter/migrate/adapters/codex.parse.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/codex.parse.js +289 -0
- package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts +3 -0
- package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/grok-build.js +117 -0
- package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.d.ts +13 -0
- package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.js +178 -0
- package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts +3 -0
- package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/omp.js +133 -0
- package/lib/types/dsh-adapter/migrate/adapters/scan-fs.d.ts +60 -0
- package/lib/types/dsh-adapter/migrate/adapters/scan-fs.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/scan-fs.js +178 -0
- package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts +8 -0
- package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/scan.js +40 -0
- package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts +3 -0
- package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/zcode.js +93 -0
- package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.d.ts +9 -0
- package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.js +89 -0
- package/lib/types/dsh-adapter/migrate/bin-path.d.ts +6 -0
- package/lib/types/dsh-adapter/migrate/bin-path.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/bin-path.js +30 -0
- package/lib/types/dsh-adapter/migrate/browse.d.ts +42 -0
- package/lib/types/dsh-adapter/migrate/browse.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/browse.js +90 -0
- package/lib/types/dsh-adapter/migrate/cli.d.ts +9 -0
- package/lib/types/dsh-adapter/migrate/cli.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/cli.js +106 -0
- package/lib/types/dsh-adapter/migrate/import-one.d.ts +89 -0
- package/lib/types/dsh-adapter/migrate/import-one.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/import-one.js +133 -0
- package/lib/types/dsh-adapter/migrate/index.d.ts +35 -0
- package/lib/types/dsh-adapter/migrate/index.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/index.js +107 -0
- package/lib/types/dsh-adapter/migrate/parse/injection.d.ts +40 -0
- package/lib/types/dsh-adapter/migrate/parse/injection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/parse/injection.js +127 -0
- package/lib/types/dsh-adapter/migrate/parse/jsonl.d.ts +28 -0
- package/lib/types/dsh-adapter/migrate/parse/jsonl.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/parse/jsonl.js +40 -0
- package/lib/types/dsh-adapter/migrate/parse/role-turns.d.ts +28 -0
- package/lib/types/dsh-adapter/migrate/parse/role-turns.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/parse/role-turns.js +50 -0
- package/lib/types/dsh-adapter/migrate/parse/title.d.ts +18 -0
- package/lib/types/dsh-adapter/migrate/parse/title.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/parse/title.js +29 -0
- package/lib/types/dsh-adapter/migrate/parse/tools.d.ts +62 -0
- package/lib/types/dsh-adapter/migrate/parse/tools.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/parse/tools.js +110 -0
- package/lib/types/dsh-adapter/migrate/picker.d.ts +64 -0
- package/lib/types/dsh-adapter/migrate/picker.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/picker.js +86 -0
- package/lib/types/dsh-adapter/migrate/recent-agents.d.ts +40 -0
- package/lib/types/dsh-adapter/migrate/recent-agents.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/recent-agents.js +100 -0
- package/lib/types/dsh-adapter/migrate/sessionize.d.ts +39 -0
- package/lib/types/dsh-adapter/migrate/sessionize.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/sessionize.js +271 -0
- package/lib/types/dsh-adapter/migrate/types.d.ts +176 -0
- package/lib/types/dsh-adapter/migrate/types.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/types.js +11 -0
- package/lib/types/dsh-adapter/migrate/uuid.d.ts +7 -0
- package/lib/types/dsh-adapter/migrate/uuid.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/uuid.js +25 -0
- package/lib/types/dsh-adapter/plugin.d.ts +4 -2
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +143 -364
- package/lib/types/dsh-adapter/providerWizard.d.ts +17 -0
- package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -1
- package/lib/types/dsh-adapter/providerWizard.js +254 -66
- package/lib/types/dsh-adapter/questions.d.ts +22 -15
- package/lib/types/dsh-adapter/questions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/questions.js +47 -45
- package/lib/types/dsh-adapter/sessions/digest.d.ts +11 -6
- package/lib/types/dsh-adapter/sessions/digest.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sessions/digest.js +20 -13
- package/lib/types/dsh-adapter/sessions/frames.d.ts +3 -1
- package/lib/types/dsh-adapter/sessions/frames.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sessions/frames.js +5 -4
- package/lib/types/dsh-adapter/sessions/list.d.ts +6 -1
- package/lib/types/dsh-adapter/sessions/list.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sessions/list.js +188 -164
- package/lib/types/dsh-adapter/sessions/recovery.d.ts +16 -0
- package/lib/types/dsh-adapter/sessions/recovery.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sessions/recovery.js +108 -0
- package/lib/types/dsh-adapter/sessions/snapshot.d.ts +7 -0
- package/lib/types/dsh-adapter/sessions/snapshot.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sessions/snapshot.js +90 -0
- package/lib/types/dsh-adapter/sessions/store.d.ts +10 -4
- package/lib/types/dsh-adapter/sessions/store.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sessions/store.js +62 -25
- package/lib/types/dsh-adapter/sideQuestion.d.ts +41 -2
- package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sideQuestion.js +98 -2
- package/lib/types/dsh-adapter/subagents.d.ts +28 -3
- package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
- package/lib/types/dsh-adapter/subagents.js +77 -2
- package/lib/types/herdr.d.ts +2 -0
- package/lib/types/herdr.d.ts.map +1 -1
- package/lib/types/herdr.js +9 -3
- package/lib/types/i18n.d.ts +424 -42
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +145 -20
- package/lib/types/ink/components/App.d.ts +2 -2
- package/lib/types/ink/components/App.d.ts.map +1 -1
- package/lib/types/ink/components/App.js +5 -1
- package/lib/types/ink/components/Image.d.ts +14 -1
- package/lib/types/ink/components/Image.d.ts.map +1 -1
- package/lib/types/ink/components/Image.js +2 -2
- package/lib/types/ink/events/input-event.js +3 -3
- package/lib/types/ink/hooks/use-terminal-images.d.ts +12 -0
- package/lib/types/ink/hooks/use-terminal-images.d.ts.map +1 -1
- package/lib/types/ink/hooks/use-terminal-images.js +13 -0
- package/lib/types/ink/ink.d.ts +6 -0
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +16 -1
- package/lib/types/ink/kitty-graphics.d.ts +44 -3
- package/lib/types/ink/kitty-graphics.d.ts.map +1 -1
- package/lib/types/ink/kitty-graphics.js +184 -23
- package/lib/types/ink/output.d.ts +24 -2
- package/lib/types/ink/output.d.ts.map +1 -1
- package/lib/types/ink/output.js +83 -5
- package/lib/types/ink/parse-keypress.d.ts +26 -1
- package/lib/types/ink/parse-keypress.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.js +156 -13
- package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
- package/lib/types/ink/render-node-to-output.js +8 -1
- package/lib/types/ink/screen.d.ts +24 -0
- package/lib/types/ink/screen.d.ts.map +1 -1
- package/lib/types/ink/screen.js +89 -0
- package/lib/types/ink/selection.d.ts +40 -18
- package/lib/types/ink/selection.d.ts.map +1 -1
- package/lib/types/ink/selection.js +142 -30
- package/lib/types/ink/sixel-codec.d.ts +12 -1
- package/lib/types/ink/sixel-codec.d.ts.map +1 -1
- package/lib/types/ink/sixel-codec.js +29 -5
- package/lib/types/ink/sixel-graphics.d.ts.map +1 -1
- package/lib/types/ink/sixel-graphics.js +5 -3
- package/lib/types/ink/styles.d.ts +9 -0
- package/lib/types/ink/styles.d.ts.map +1 -1
- package/lib/types/ink/terminal-image.d.ts +8 -0
- package/lib/types/ink/terminal-image.d.ts.map +1 -1
- package/lib/types/ink/terminal-querier.d.ts +7 -1
- package/lib/types/ink/terminal-querier.d.ts.map +1 -1
- package/lib/types/ink/terminal-querier.js +12 -2
- package/lib/types/ink/timeline-rail.d.ts +5 -0
- package/lib/types/ink/timeline-rail.d.ts.map +1 -1
- package/lib/types/math/inline-layout.d.ts +29 -0
- package/lib/types/math/inline-layout.d.ts.map +1 -0
- package/lib/types/math/inline-layout.js +106 -0
- package/lib/types/math/layout.d.ts +58 -0
- package/lib/types/math/layout.d.ts.map +1 -0
- package/lib/types/math/layout.js +59 -0
- package/lib/types/math/renderer.d.ts +64 -0
- package/lib/types/math/renderer.d.ts.map +1 -0
- package/lib/types/math/renderer.js +256 -0
- package/lib/types/screens/Chat.d.ts +14 -1
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +606 -53
- package/lib/types/screens/SessionSupervisor.d.ts +2 -1
- package/lib/types/screens/SessionSupervisor.d.ts.map +1 -1
- package/lib/types/screens/SessionSupervisor.js +156 -19
- package/lib/types/screens/Settings.d.ts.map +1 -1
- package/lib/types/screens/Settings.js +49 -11
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +45 -15
- package/lib/types/screens/chatOverlay.d.ts +5 -0
- package/lib/types/screens/chatOverlay.d.ts.map +1 -1
- package/lib/types/screens/chatOverlay.js +1 -0
- package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.d.ts +47 -0
- package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.d.ts.map +1 -0
- package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.js +65 -0
- package/lib/types/screens/sessionSupervisor/model.d.ts +12 -0
- package/lib/types/screens/sessionSupervisor/model.d.ts.map +1 -1
- package/lib/types/screens/sessionSupervisor/model.js +26 -0
- package/lib/types/screens/sessionSupervisor/useForeignSessions.d.ts +107 -0
- package/lib/types/screens/sessionSupervisor/useForeignSessions.d.ts.map +1 -0
- package/lib/types/screens/sessionSupervisor/useForeignSessions.js +312 -0
- package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts +4 -1
- package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts.map +1 -1
- package/lib/types/screens/sessionSupervisor/useSessionSupervisor.js +97 -14
- package/lib/types/sessionHistory.d.ts +2 -2
- package/lib/types/sessionHistory.d.ts.map +1 -1
- package/lib/types/sessionHistory.js +31 -5
- package/lib/types/settings/definitions.d.ts +681 -0
- package/lib/types/settings/definitions.d.ts.map +1 -0
- package/lib/types/settings/definitions.js +511 -0
- package/lib/types/starAction.d.ts +44 -0
- package/lib/types/starAction.d.ts.map +1 -0
- package/lib/types/starAction.js +52 -0
- package/lib/types/terminal-utils/latex.d.ts +10 -0
- package/lib/types/terminal-utils/latex.d.ts.map +1 -0
- package/lib/types/terminal-utils/latex.js +1417 -0
- package/lib/types/terminal-utils/markdown.d.ts +3 -1
- package/lib/types/terminal-utils/markdown.d.ts.map +1 -1
- package/lib/types/terminal-utils/markdown.js +26 -1
- package/lib/types/terminal-utils/math.d.ts +66 -0
- package/lib/types/terminal-utils/math.d.ts.map +1 -0
- package/lib/types/terminal-utils/math.js +337 -0
- package/lib/types/tips.d.ts.map +1 -1
- package/lib/types/tips.js +6 -0
- package/lib/types/tuiDisplayPrefs.d.ts +67 -0
- package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
- package/lib/types/tuiDisplayPrefs.js +59 -0
- package/lib/types/ui.d.ts +1 -1
- package/lib/types/ui.d.ts.map +1 -1
- package/lib/types/ui.js +1 -1
- package/lib/types/usageStats.d.ts +98 -0
- package/lib/types/usageStats.d.ts.map +1 -0
- package/lib/types/usageStats.js +169 -0
- package/lib/types/utils/bmp.d.ts +17 -0
- package/lib/types/utils/bmp.d.ts.map +1 -0
- package/lib/types/utils/bmp.js +154 -0
- package/lib/types/utils/clipboard.d.ts +14 -2
- package/lib/types/utils/clipboard.d.ts.map +1 -1
- package/lib/types/utils/clipboard.js +143 -8
- package/lib/types/utils/fold-long-lines.d.ts.map +1 -1
- package/lib/types/utils/fold-long-lines.js +2 -1
- package/lib/types/utils/keymap.d.ts +4 -1
- package/lib/types/utils/keymap.d.ts.map +1 -1
- package/lib/types/utils/keymap.js +8 -0
- package/lib/types/utils/modifiers.d.ts +4 -3
- package/lib/types/utils/modifiers.d.ts.map +1 -1
- package/lib/types/utils/modifiers.js +4 -3
- package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/LICENSE +202 -0
- package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/NOTICE +20 -0
- package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/index.d.ts +16 -0
- package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/bundled-packages.json +4 -0
- package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/index.mjs +20 -0
- package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/index.mjs.LEGAL.txt +35 -0
- package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/package.json +29 -0
- package/package.json +111 -97
package/lib/types/commands.js
CHANGED
|
@@ -42,7 +42,9 @@ export const LOCAL_COMMANDS = [
|
|
|
42
42
|
{ name: 'config', description: 'Show the dsh-tui configuration source' },
|
|
43
43
|
{ name: 'reload', description: 'Reload preference files from disk and apply live' },
|
|
44
44
|
{ name: 'settings', description: 'View and edit plugin settings' },
|
|
45
|
+
{ name: 'star', description: 'Star this project on GitHub (one-key via the gh CLI)' },
|
|
45
46
|
{ name: 'doctor', description: 'Run environment checks' },
|
|
47
|
+
{ name: 'migrate', description: 'Import conversations from other coding agents (claude-code / codex / omp / zcode / grok-build)' },
|
|
46
48
|
{ name: 'init', description: 'Create AGENTS.md in the working directory' },
|
|
47
49
|
{ name: 'agents', description: 'Show subagents of this session' },
|
|
48
50
|
{ name: 'jobs', description: 'Show background jobs of this session' },
|
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { BalanceResult } from '../deepseekBalance.js';
|
|
3
3
|
import type { TokenUsage } from '../dsh-adapter/channel.js';
|
|
4
|
+
import type { ChannelUi } from '../adapter/channel/ui-policy.js';
|
|
4
5
|
/**
|
|
5
6
|
* `/balance` 余额报告行:Divider + 一行安静摘要,hover 展开明细
|
|
6
7
|
* (各币种赠送/充值拆分、本会话 token 与花费估算、失败原因),点击行
|
|
7
8
|
* 重新查询,右上角 × 关闭 —— 与 AutoRecapRow 同一套视觉与交互语言。
|
|
8
9
|
* 报告只活在内存里:不进 transcript、不进会话日志。
|
|
9
10
|
*/
|
|
10
|
-
export declare function BalanceReportRow({ result, refreshing, tokens, model, onRefresh, onDismiss, }: {
|
|
11
|
+
export declare function BalanceReportRow({ result, refreshing, tokens, model, provider, mainCost, subagentCost, onRefresh, onDismiss, }: {
|
|
11
12
|
/** null 表示查询仍在途。 */
|
|
12
13
|
result: BalanceResult | null;
|
|
13
14
|
/** 查询在途(刷新时摘要不动,明细区显示加载行)。 */
|
|
14
15
|
refreshing: boolean;
|
|
15
|
-
/** 会话累计 token(hover
|
|
16
|
+
/** 会话累计 token(hover 明细里的花费估算输入;没有 mainCost 的旧快照
|
|
17
|
+
* 回退到这份总量 + 当前模型)。 */
|
|
16
18
|
tokens: TokenUsage;
|
|
17
19
|
/** 当前模型 id(花费估算的单价匹配)。 */
|
|
18
20
|
model: string;
|
|
21
|
+
/** 当前 provider(主会话用量的官方判定)。 */
|
|
22
|
+
provider: string;
|
|
23
|
+
/** 主会话按模型分桶(费用估算输入;旧快照缺省时回退 tokens)。 */
|
|
24
|
+
mainCost?: ChannelUi['mainCost'];
|
|
25
|
+
/** 子代理按 (provider, model) 分桶(费用估算输入)。 */
|
|
26
|
+
subagentCost?: ChannelUi['subagentCost'];
|
|
19
27
|
/** 点击报告行:重新查询余额。 */
|
|
20
28
|
onRefresh: () => void;
|
|
21
29
|
/** 点击 ×:关闭报告。 */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BalanceReportRow.d.ts","sourceRoot":"","sources":["../../../src/components/BalanceReportRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAE1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"BalanceReportRow.d.ts","sourceRoot":"","sources":["../../../src/components/BalanceReportRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAE1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAA;AAGhE;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,UAAU,EACV,MAAM,EACN,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,SAAS,GACV,EAAE;IACD,oBAAoB;IACpB,MAAM,EAAE,aAAa,GAAG,IAAI,CAAA;IAC5B,8BAA8B;IAC9B,UAAU,EAAE,OAAO,CAAA;IACnB;2BACuB;IACvB,MAAM,EAAE,UAAU,CAAA;IAClB,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAA;IAChC,yCAAyC;IACzC,YAAY,CAAC,EAAE,SAAS,CAAC,cAAc,CAAC,CAAA;IACxC,oBAAoB;IACpB,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,iBAAiB;IACjB,SAAS,EAAE,MAAM,IAAI,CAAA;CACtB,GAAG,KAAK,CAAC,SAAS,CAuHlB"}
|
|
@@ -3,7 +3,7 @@ import React from 'react';
|
|
|
3
3
|
import { Box, Text } from '../ui.js';
|
|
4
4
|
import { Divider } from './design-system/Divider.js';
|
|
5
5
|
import { t } from '../i18n.js';
|
|
6
|
-
import {
|
|
6
|
+
import { estimateSessionCostSnapshotCny, isPeakHour, priceForModel } from '../deepseekPricing.js';
|
|
7
7
|
import { formatTokens } from '../terminal-utils/format.js';
|
|
8
8
|
/**
|
|
9
9
|
* `/balance` 余额报告行:Divider + 一行安静摘要,hover 展开明细
|
|
@@ -11,7 +11,7 @@ import { formatTokens } from '../terminal-utils/format.js';
|
|
|
11
11
|
* 重新查询,右上角 × 关闭 —— 与 AutoRecapRow 同一套视觉与交互语言。
|
|
12
12
|
* 报告只活在内存里:不进 transcript、不进会话日志。
|
|
13
13
|
*/
|
|
14
|
-
export function BalanceReportRow({ result, refreshing, tokens, model, onRefresh, onDismiss, }) {
|
|
14
|
+
export function BalanceReportRow({ result, refreshing, tokens, model, provider, mainCost, subagentCost, onRefresh, onDismiss, }) {
|
|
15
15
|
const [hovered, setHovered] = React.useState(false);
|
|
16
16
|
const summary = (() => {
|
|
17
17
|
if (result === null)
|
|
@@ -30,7 +30,13 @@ export function BalanceReportRow({ result, refreshing, tokens, model, onRefresh,
|
|
|
30
30
|
: t('balance-summary-state-off'),
|
|
31
31
|
});
|
|
32
32
|
})();
|
|
33
|
-
const estimate =
|
|
33
|
+
const estimate = estimateSessionCostSnapshotCny({
|
|
34
|
+
provider,
|
|
35
|
+
main: mainCost,
|
|
36
|
+
subagents: subagentCost,
|
|
37
|
+
fallbackTokens: tokens,
|
|
38
|
+
fallbackModel: model,
|
|
39
|
+
});
|
|
34
40
|
const detailLines = (() => {
|
|
35
41
|
if (result === null)
|
|
36
42
|
return [];
|
|
@@ -63,7 +69,7 @@ export function BalanceReportRow({ result, refreshing, tokens, model, onRefresh,
|
|
|
63
69
|
output: price.output[rateIndex].toFixed(1),
|
|
64
70
|
}));
|
|
65
71
|
}
|
|
66
|
-
if (estimate !== undefined) {
|
|
72
|
+
if (estimate !== undefined && estimate.total > 0) {
|
|
67
73
|
lines.push(t('balance-hover-tokens', {
|
|
68
74
|
input: formatTokens(tokens.input),
|
|
69
75
|
output: formatTokens(tokens.output),
|
|
@@ -74,6 +80,14 @@ export function BalanceReportRow({ result, refreshing, tokens, model, onRefresh,
|
|
|
74
80
|
idleName: t('cost-idle-name'),
|
|
75
81
|
}));
|
|
76
82
|
}
|
|
83
|
+
// 拆解口径(DESIGN D6):主会话 / 子代理各按自身模型分组计价;无法计价
|
|
84
|
+
// 的用量只报 token,让"估算偏低"变成可见事实而不是静默少算。
|
|
85
|
+
if (estimate !== undefined) {
|
|
86
|
+
lines.push(`${t('cost-split-main', { cost: estimate.main.toFixed(2) })} · ${t('cost-split-subagent', { cost: estimate.subagent.toFixed(2) })}`);
|
|
87
|
+
if (estimate.unpricedTokens > 0) {
|
|
88
|
+
lines.push(t('cost-unpriced', { tokens: formatTokens(estimate.unpricedTokens) }));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
77
91
|
return lines;
|
|
78
92
|
})();
|
|
79
93
|
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Divider, {}), _jsxs(Box, { flexDirection: "column", marginTop: 1, marginLeft: 1, onClick: onRefresh, onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), children: [_jsx(Text, { dimColor: !hovered, children: refreshing ? t('balance-summary-loading') : summary }), hovered && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [detailLines.map((line, index) => (_jsx(Text, { dimColor: true, wrap: "truncate", children: line }, index))), result !== null && (_jsxs(Box, { flexDirection: "row", marginTop: 1, children: [_jsxs(Text, { color: "success", children: [" [", result.ok ? t('balance-refresh') : t('balance-retry'), "]"] }), _jsx(Box, { onClick: (event) => {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { CompactionStatus } from '../adapter/ports/channel-view.js';
|
|
3
|
+
/**
|
|
4
|
+
* The in-flight compaction row, in the same slot as the working spinner.
|
|
5
|
+
*
|
|
6
|
+
* A `/compact` runs for tens of seconds (measured on real sessions: median
|
|
7
|
+
* ~25s, p90 ~70s) and the old transient toast covered the first four of them,
|
|
8
|
+
* leaving the screen indistinguishable from idle. This row stays for the whole
|
|
9
|
+
* bracket, counts up, and shows the summarizer's own output as it streams
|
|
10
|
+
* (`compaction.outputChars`) — the one honest progress signal a compaction has,
|
|
11
|
+
* since the host exposes no proportional one.
|
|
12
|
+
*
|
|
13
|
+
* Its leading indicator follows the spinner slot: the `/activity` preset while
|
|
14
|
+
* the working-activity line owns that slot (a running turn shows the preset, so
|
|
15
|
+
* the compaction must not answer with a different glyph), the classic dot
|
|
16
|
+
* otherwise.
|
|
17
|
+
*/
|
|
18
|
+
export declare function CompactionStatusRow({ compaction, activityPreset, }: {
|
|
19
|
+
compaction: CompactionStatus;
|
|
20
|
+
/** `/activity` preset name to draw the indicator with; undefined keeps the
|
|
21
|
+
* classic dot family. */
|
|
22
|
+
activityPreset?: string;
|
|
23
|
+
}): React.ReactNode;
|
|
24
|
+
//# sourceMappingURL=CompactionStatusRow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompactionStatusRow.d.ts","sourceRoot":"","sources":["../../../src/components/CompactionStatusRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AASzB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AAmBxE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,UAAU,EACV,cAAc,GACf,EAAE;IACD,UAAU,EAAE,gBAAgB,CAAA;IAC5B;8BAC0B;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,GAAG,KAAK,CAAC,SAAS,CAkDlB"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Box, Text } from '../ui.js';
|
|
4
|
+
import { useAnimationFrame } from '../ink/hooks/use-animation-frame.js';
|
|
5
|
+
import { useTerminalSize } from '../ink/hooks/use-terminal-size.js';
|
|
6
|
+
import { stringWidth } from '../ink/stringWidth.js';
|
|
7
|
+
import { t } from '../i18n.js';
|
|
8
|
+
import { formatDuration, formatTokens } from '../terminal-utils/format.js';
|
|
9
|
+
import { SpinnerGlyph } from './Spinner/SpinnerGlyph.js';
|
|
10
|
+
import { resolvePreset } from './activityFrames.js';
|
|
11
|
+
/** Field separator, matching the working spinner's row. */
|
|
12
|
+
const SEP = ' · ';
|
|
13
|
+
/** Cells kept clear so a long row never wraps into the prompt below. */
|
|
14
|
+
const RESERVE = 2;
|
|
15
|
+
/** Cadence of the classic dot spinner, so that slot agrees with the turn's. */
|
|
16
|
+
const FRAME_MS = 140;
|
|
17
|
+
/** Tick granularity: fine enough for the fastest `/activity` preset (120ms). */
|
|
18
|
+
const TICK_MS = 60;
|
|
19
|
+
/** Columns the classic dot occupies (`SpinnerGlyph`'s fixed two-column slot). */
|
|
20
|
+
const DOT_SLOT = 2;
|
|
21
|
+
/**
|
|
22
|
+
* The in-flight compaction row, in the same slot as the working spinner.
|
|
23
|
+
*
|
|
24
|
+
* A `/compact` runs for tens of seconds (measured on real sessions: median
|
|
25
|
+
* ~25s, p90 ~70s) and the old transient toast covered the first four of them,
|
|
26
|
+
* leaving the screen indistinguishable from idle. This row stays for the whole
|
|
27
|
+
* bracket, counts up, and shows the summarizer's own output as it streams
|
|
28
|
+
* (`compaction.outputChars`) — the one honest progress signal a compaction has,
|
|
29
|
+
* since the host exposes no proportional one.
|
|
30
|
+
*
|
|
31
|
+
* Its leading indicator follows the spinner slot: the `/activity` preset while
|
|
32
|
+
* the working-activity line owns that slot (a running turn shows the preset, so
|
|
33
|
+
* the compaction must not answer with a different glyph), the classic dot
|
|
34
|
+
* otherwise.
|
|
35
|
+
*/
|
|
36
|
+
export function CompactionStatusRow({ compaction, activityPreset, }) {
|
|
37
|
+
const { columns } = useTerminalSize();
|
|
38
|
+
const [viewportRef, time] = useAnimationFrame(TICK_MS);
|
|
39
|
+
// `random` resolves per call, so the pick is memoized per preset name — the
|
|
40
|
+
// rule the activity line and the subagent rows already follow.
|
|
41
|
+
const indicator = React.useMemo(() => {
|
|
42
|
+
if (activityPreset === undefined)
|
|
43
|
+
return null;
|
|
44
|
+
const preset = resolvePreset(activityPreset);
|
|
45
|
+
// The widest frame, not the current one: the row must not reflow mid-pulse.
|
|
46
|
+
return { preset, width: Math.max(...preset.frames.map(frame => stringWidth(frame))) + 1 };
|
|
47
|
+
}, [activityPreset]);
|
|
48
|
+
const glyph = indicator === null
|
|
49
|
+
? null
|
|
50
|
+
: indicator.preset.frames[Math.floor(time / indicator.preset.intervalMs) % indicator.preset.frames.length] ?? '·';
|
|
51
|
+
// Derived from wall-clock each frame (the row is only mounted while a
|
|
52
|
+
// compaction runs, so the tick stops with it).
|
|
53
|
+
const elapsed = formatDuration(Date.now() - compaction.startedAt);
|
|
54
|
+
const frame = Math.floor(time / FRAME_MS);
|
|
55
|
+
const label = t('compact-working');
|
|
56
|
+
const detail = compaction.phase === 'summary'
|
|
57
|
+
? `↓ ${formatTokens(Math.round(compaction.outputChars / 4))} tokens`
|
|
58
|
+
: t('compact-phase-prefill');
|
|
59
|
+
const hint = compaction.cancellable ? t('compact-esc-cancel') : undefined;
|
|
60
|
+
// The hint is actionable and the phase is informative, so a narrow terminal
|
|
61
|
+
// drops the phase first and the hint only when even that does not fit.
|
|
62
|
+
const budget = Math.max(0, columns - RESERVE);
|
|
63
|
+
const base = (indicator === null ? DOT_SLOT : indicator.width) + stringWidth(label);
|
|
64
|
+
const elapsedWidth = stringWidth(SEP) + stringWidth(elapsed);
|
|
65
|
+
const hintWidth = hint === undefined ? 0 : stringWidth(SEP) + stringWidth(hint);
|
|
66
|
+
const detailWidth = stringWidth(SEP) + stringWidth(detail);
|
|
67
|
+
const showHint = hint !== undefined && base + elapsedWidth + hintWidth <= budget;
|
|
68
|
+
const showDetail = base + elapsedWidth + hintWidth + detailWidth <= budget;
|
|
69
|
+
return (_jsxs(Box, { ref: viewportRef, flexDirection: "row", flexWrap: "wrap", marginTop: 1, width: "100%", children: [glyph === null
|
|
70
|
+
? _jsx(SpinnerGlyph, { frame: frame, messageColor: "accent" })
|
|
71
|
+
: _jsx(Text, { color: "activity", children: `${glyph} ` }), _jsx(Text, { color: "accent", children: label }), showDetail && _jsx(Text, { dimColor: true, children: `${SEP}${detail}` }), _jsx(Text, { dimColor: true, children: `${SEP}${elapsed}` }), showHint && _jsx(Text, { dimColor: true, children: `${SEP}${hint}` })] }));
|
|
72
|
+
}
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { Box, Text } from '../ui.js';
|
|
4
4
|
import { t } from '../i18n.js';
|
|
5
|
-
import {
|
|
5
|
+
import { primaryComboString } from '../utils/keymap.js';
|
|
6
6
|
/** Maximum todo rows shown before the overflow line. */
|
|
7
7
|
const MAX_TODOS = 8;
|
|
8
8
|
const PHASE_LABEL = {
|
|
@@ -127,5 +127,5 @@ export function GoalTodoPanel({ channel, collapsed = false, onToggle, }) {
|
|
|
127
127
|
return (_jsxs(Box, { flexDirection: "column", paddingLeft: 2, paddingRight: 2, paddingTop: 1, children: [goal !== undefined && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", width: "100%", height: 1, children: [_jsx(Text, { color: "suggestion", children: "\uD83C\uDFAF " }), _jsx(Box, { flexGrow: 1, flexShrink: 1, children: _jsx(Text, { bold: true, wrap: "truncate", children: goal.objective }) }), _jsx(Box, { flexShrink: 0, marginLeft: 1, children: _jsx(PhaseBadge, { phase: goal.phase, roundsStarted: goal.roundsStarted, maxGoalRounds: goal.maxGoalRounds, elapsed: elapsed }) })] }), goal.phase === 'blocked' && goal.blockedReason !== undefined && (_jsxs(Box, { flexDirection: "row", marginTop: 1, height: 1, children: [_jsx(Text, { dimColor: true, children: "\u2502 " }), _jsx(Text, { color: "error", wrap: "truncate", children: goal.blockedReason.message })] }))] })), showTodoSection && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", height: 1, onClick: onToggle, onMouseEnter: () => setHeaderHovered(true), onMouseLeave: () => setHeaderHovered(false), backgroundColor: headerHovered ? 'userMessageBackgroundHover' : undefined, children: [_jsxs(Text, { dimColor: true, children: [collapsed ? '▸' : '▾', " "] }), _jsxs(Text, { dimColor: true, children: ["\u2713 ", doneCount, "/", allTodos.length] }), collapsed && preview !== undefined && (_jsx(Box, { flexGrow: 1, flexShrink: 1, marginLeft: 1, children: preview.status === 'in_progress' ? (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: "suggestion", children: "\u25CF " }), preview.content] })) : (_jsxs(Text, { wrap: "truncate", dimColor: true, children: ["\u25CB ", preview.content] })) }))] }), !collapsed && (_jsxs(Box, { flexDirection: "column", children: [visible.map((todo, index) => {
|
|
128
128
|
const last = index === visible.length - 1 && hidden === 0;
|
|
129
129
|
return (_jsxs(Box, { flexDirection: "row", height: 1, children: [_jsx(BranchPrefix, { last: last }), _jsx(TodoGlyph, { status: todo.status }), _jsx(Text, { wrap: "truncate", dimColor: todo.status === 'completed', children: todo.content })] }, index));
|
|
130
|
-
}), hidden > 0 && (_jsxs(Box, { flexDirection: "row", height: 1, children: [_jsx(BranchPrefix, { last: true }), _jsxs(Text, { dimColor: true, children: ["\u2026 ", hidden, " more"] })] })), _jsxs(Text, { dimColor: true, children: [" ", t('goal-todo-fold-hint', {
|
|
130
|
+
}), hidden > 0 && (_jsxs(Box, { flexDirection: "row", height: 1, children: [_jsx(BranchPrefix, { last: true }), _jsxs(Text, { dimColor: true, children: ["\u2026 ", hidden, " more"] })] })), _jsxs(Text, { dimColor: true, children: [" ", t('goal-todo-fold-hint', { key: primaryComboString('todoFold') })] })] }))] }))] }));
|
|
131
131
|
}
|
|
@@ -8,8 +8,8 @@ import type { LocalCommand } from '../commands.js';
|
|
|
8
8
|
* commands plus plugin-registered ones from the DSH registry (plan/goal/…).
|
|
9
9
|
* Skill entries (user-invocable skills merged for `/` completion, issue
|
|
10
10
|
* #86) are hidden — a skills directory can hold dozens of entries and the
|
|
11
|
-
* menu is for chrome commands. Modifier labels
|
|
12
|
-
*
|
|
11
|
+
* menu is for chrome commands. Modifier labels always read ctrl+ (see
|
|
12
|
+
* modLabel): Ctrl works in every terminal, ⌘ is only a macOS alias.
|
|
13
13
|
*/
|
|
14
14
|
export declare function HelpMenu({ commands, viewportHeight, viewportWidth, scrollRef, onCommandPick, }: {
|
|
15
15
|
commands: readonly LocalCommand[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HelpMenu.d.ts","sourceRoot":"","sources":["../../../src/components/HelpMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"HelpMenu.d.ts","sourceRoot":"","sources":["../../../src/components/HelpMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAMlD;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,cAAc,EACd,aAAa,EACb,SAAS,EACT,aAAa,GACd,EAAE;IACD,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAA;IACjC,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,yEAAyE;IACzE,SAAS,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;IACtC;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACvC,GAAG,KAAK,CAAC,SAAS,CAoHlB"}
|
|
@@ -3,6 +3,7 @@ import React from 'react';
|
|
|
3
3
|
import { Box, ScrollBox, Text } from '../ui.js';
|
|
4
4
|
import { localizedDescription } from '../commands.js';
|
|
5
5
|
import { t } from '../i18n.js';
|
|
6
|
+
import { primaryComboString } from '../utils/keymap.js';
|
|
6
7
|
import { modLabel } from '../utils/modifiers.js';
|
|
7
8
|
/**
|
|
8
9
|
* The `?` help menu with a three-column shortcut layout, trimmed to the keys
|
|
@@ -11,13 +12,13 @@ import { modLabel } from '../utils/modifiers.js';
|
|
|
11
12
|
* commands plus plugin-registered ones from the DSH registry (plan/goal/…).
|
|
12
13
|
* Skill entries (user-invocable skills merged for `/` completion, issue
|
|
13
14
|
* #86) are hidden — a skills directory can hold dozens of entries and the
|
|
14
|
-
* menu is for chrome commands. Modifier labels
|
|
15
|
-
*
|
|
15
|
+
* menu is for chrome commands. Modifier labels always read ctrl+ (see
|
|
16
|
+
* modLabel): Ctrl works in every terminal, ⌘ is only a macOS alias.
|
|
16
17
|
*/
|
|
17
18
|
export function HelpMenu({ commands, viewportHeight, viewportWidth, scrollRef, onCommandPick, }) {
|
|
18
19
|
const chrome = commands.filter(command => !command.skill);
|
|
19
|
-
const primaryShortcuts = (_jsxs(Box, { flexDirection: "column", width: 26, flexShrink: 0, children: [_jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-for-commands') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-this-help') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-verbose-output', {
|
|
20
|
-
const secondaryShortcuts = (_jsxs(Box, { flexDirection: "column", width: 24, flexShrink: 0, children: [_jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-clear-input') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-history-nav') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-move-cursor') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-word-jumps', { mod: modLabel }) }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-complete-command') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-cycle-mode') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-open-editor') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-fold-todos', {
|
|
20
|
+
const primaryShortcuts = (_jsxs(Box, { flexDirection: "column", width: 26, flexShrink: 0, children: [_jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-for-commands') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-this-help') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-verbose-output', { key: primaryComboString('transcript') }) }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-open-trajectory', { key: primaryComboString('trajectory') }) }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-search-history', { key: primaryComboString('history') }) }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-interrupt') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-exit') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-redraw', { key: primaryComboString('redraw') }) }) })] }));
|
|
21
|
+
const secondaryShortcuts = (_jsxs(Box, { flexDirection: "column", width: 24, flexShrink: 0, children: [_jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-clear-input') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-history-nav') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-move-cursor') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-word-jumps', { mod: modLabel }) }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-complete-command') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-cycle-mode') }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-open-editor', { key: primaryComboString('editor') }) }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: t('help-fold-todos', { key: primaryComboString('todoFold') }) }) })] }));
|
|
21
22
|
const commandRows = chrome.map(command => (_jsx(HelpCommandRow, { command: command, onPick: onCommandPick }, command.name)));
|
|
22
23
|
const compactCommandRows = chrome.map(command => (_jsx(HelpCommandRow, { command: command, onPick: onCommandPick }, command.name)));
|
|
23
24
|
const commandList = (_jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [_jsx(Text, { dimColor: true, children: t('help-commands-title') }), commandRows] }));
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Tokens } from 'marked';
|
|
3
|
+
import type { CliHighlight } from '../terminal-utils/cliHighlight.js';
|
|
4
|
+
/**
|
|
5
|
+
* A top-level paragraph whose inline formulas show as terminal images
|
|
6
|
+
* (`mathRendering: image`, Kitty or Sixel graphics, a measured cell size).
|
|
7
|
+
*
|
|
8
|
+
* It renders exactly like the plain <Text> paragraph until it can switch
|
|
9
|
+
* whole: the paragraph's width is measured, and every formula has settled
|
|
10
|
+
* (typeset into a one-row image, or failed). The switch then happens once,
|
|
11
|
+
* so formulas arriving one by one never shift the wrap points. Formulas that
|
|
12
|
+
* failed or would shrink below legibility on one row keep their Unicode
|
|
13
|
+
* form. Each row is laid out by `layoutInlineMedia` and drawn as text
|
|
14
|
+
* pieces with one-row <Image> slots between them.
|
|
15
|
+
*/
|
|
16
|
+
type Props = {
|
|
17
|
+
token: Tokens.Paragraph;
|
|
18
|
+
highlight: CliHighlight | null;
|
|
19
|
+
};
|
|
20
|
+
export declare function InlineMathParagraph({ token, highlight }: Props): React.ReactNode;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=InlineMathParagraph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InlineMathParagraph.d.ts","sourceRoot":"","sources":["../../../src/components/InlineMathParagraph.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,KAAK,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAA;AAQ3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAA;AAQrE;;;;;;;;;;;GAWG;AAEH,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,CAAC,SAAS,CAAA;IACvB,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;CAC/B,CAAA;AAOD,wBAAgB,mBAAmB,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAiGhF"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Box, Image, Text, useTerminalImageCellSize, useTerminalImageProtocol, useTerminalImages } from '../ui.js';
|
|
4
|
+
import measureElement from '../ink/measure-element.js';
|
|
5
|
+
import { useTerminalSize } from '../ink/hooks/use-terminal-size.js';
|
|
6
|
+
import { INLINE_MEDIA_MAX, inlineMediaPlaceholder, layoutInlineMedia } from '../math/inline-layout.js';
|
|
7
|
+
import { peekMathRaster, renderMathRaster } from '../math/renderer.js';
|
|
8
|
+
import { getTheme } from '../theme.js';
|
|
9
|
+
import { formatToken } from '../terminal-utils/markdown.js';
|
|
10
|
+
import { isMathToken, renderInlineMath } from '../terminal-utils/math.js';
|
|
11
|
+
import { useTerminalBackground, useTheme } from './design-system/ThemeProvider.js';
|
|
12
|
+
import { themeInkHex } from './MathBlock.js';
|
|
13
|
+
import { getMathImageBacking, subscribeMathImageBacking } from '../tuiDisplayPrefs.js';
|
|
14
|
+
import { useMathPreviewOpener } from './mathPreview.js';
|
|
15
|
+
const WIDTH_PROBE = ' '.repeat(1024);
|
|
16
|
+
/** Distinct widths applied before measurement freezes (see Divider). */
|
|
17
|
+
const MAX_APPLIED_MEASUREMENTS = 4;
|
|
18
|
+
export function InlineMathParagraph({ token, highlight }) {
|
|
19
|
+
const plain = React.useMemo(() => formatToken(token, 0, null, null, highlight).trim(), [token, highlight]);
|
|
20
|
+
const formulas = React.useMemo(() => collectInlineMath(token).slice(0, INLINE_MEDIA_MAX), [token]);
|
|
21
|
+
const graphics = useTerminalImages(formulas.length > 0);
|
|
22
|
+
const protocol = useTerminalImageProtocol();
|
|
23
|
+
const cellSize = useTerminalImageCellSize();
|
|
24
|
+
const [themeName] = useTheme();
|
|
25
|
+
const color = themeInkHex(getTheme(themeName).text);
|
|
26
|
+
const previewMath = useMathPreviewOpener();
|
|
27
|
+
const backdrop = React.useSyncExternalStore(subscribeMathImageBacking, getMathImageBacking);
|
|
28
|
+
const composited = backdrop === 'terminal';
|
|
29
|
+
const terminalBackground = useTerminalBackground();
|
|
30
|
+
const width = useMeasuredWidth();
|
|
31
|
+
const requests = React.useMemo(() => {
|
|
32
|
+
if (!graphics || (protocol !== 'kitty' && protocol !== 'sixel') || cellSize === undefined || color === undefined)
|
|
33
|
+
return undefined;
|
|
34
|
+
if (width.value === undefined || formulas.length === 0)
|
|
35
|
+
return undefined;
|
|
36
|
+
return formulas.map(formula => ({
|
|
37
|
+
tex: formula.text, display: false, color, cellSize, maxColumns: width.value, maxRows: 1,
|
|
38
|
+
}));
|
|
39
|
+
}, [graphics, protocol, cellSize, color, width.value, formulas]);
|
|
40
|
+
const results = useSettledRasters(requests);
|
|
41
|
+
const layout = React.useMemo(() => {
|
|
42
|
+
if (results === undefined || width.value === undefined)
|
|
43
|
+
return undefined;
|
|
44
|
+
const media = [];
|
|
45
|
+
const slot = new Map();
|
|
46
|
+
formulas.forEach((formula, index) => {
|
|
47
|
+
const result = results[index];
|
|
48
|
+
// Failures and formulas that did not fit one row keep their Unicode.
|
|
49
|
+
if (!result.ok || result.raster.rows !== 1)
|
|
50
|
+
return;
|
|
51
|
+
slot.set(formula, inlineMediaPlaceholder(media.length, result.raster.columns));
|
|
52
|
+
media.push({ formula, raster: result.raster });
|
|
53
|
+
});
|
|
54
|
+
if (media.length === 0)
|
|
55
|
+
return undefined;
|
|
56
|
+
const formatted = formatToken(withPlaceholders(token, slot), 0, null, null, highlight).trim();
|
|
57
|
+
const rows = layoutInlineMedia(formatted, width.value, media.map(entry => entry.raster.columns));
|
|
58
|
+
return rows === undefined ? undefined : { rows, media };
|
|
59
|
+
}, [results, width.value, formulas, token, highlight]);
|
|
60
|
+
return (_jsxs(Box, { ref: width.ref, flexDirection: "column", children: [_jsx(Box, { height: 0, overflow: "hidden", children: _jsx(Text, { wrap: "truncate", children: WIDTH_PROBE }) }), layout === undefined
|
|
61
|
+
? _jsx(Text, { children: plain })
|
|
62
|
+
: layout.rows.map((row, rowIndex) => (_jsx(Box, { flexDirection: "row", height: 1, softWrapContinuation: row.continuation ? layout.rows[rowIndex - 1]?.width : undefined, children: row.pieces.map((piece, pieceIndex) => {
|
|
63
|
+
if (piece.kind === 'text') {
|
|
64
|
+
return (_jsx(Box, { width: piece.width, flexShrink: 0, children: _jsx(Text, { wrap: "truncate", children: piece.text }) }, `t${pieceIndex}`));
|
|
65
|
+
}
|
|
66
|
+
const { formula, raster } = layout.media[piece.index];
|
|
67
|
+
// Keyed by the formula slot, so an unchanged layout keeps the
|
|
68
|
+
// same image node (placements follow node identity). The
|
|
69
|
+
// transcript presentation is what lets Sixel paint the one-row
|
|
70
|
+
// slot at all, and crops instead of dropping it at a viewport
|
|
71
|
+
// edge — the same contract block formulas use.
|
|
72
|
+
const formulaRequest = requests?.[piece.index];
|
|
73
|
+
const painted = (_jsx(Image, { ...(composited ? {} : { transparent: true }), presentation: "transcript", source: raster.source, width: piece.columns, height: 1, alt: formula.text, copyText: formula.raw, children: _jsx(Text, { dimColor: true, wrap: "truncate", children: renderInlineMath(formula.text) ?? formula.raw }) }));
|
|
74
|
+
const image = composited
|
|
75
|
+
? (_jsx(Box, { width: piece.columns, height: 1, flexShrink: 0, backgroundColor: terminalBackground, children: painted }))
|
|
76
|
+
: painted;
|
|
77
|
+
return previewMath === undefined || formulaRequest === undefined
|
|
78
|
+
? _jsx(React.Fragment, { children: image }, `m${piece.index}:${raster.key}`)
|
|
79
|
+
: (_jsx(Box, { onClick: event => { event.stopImmediatePropagation(); previewMath({ tex: formula.text, request: formulaRequest, source: raster.source }); }, children: image }, `m${piece.index}:${raster.key}`));
|
|
80
|
+
}) }, rowIndex)))] }));
|
|
81
|
+
}
|
|
82
|
+
/** Inline math tokens of a paragraph, in reading order. */
|
|
83
|
+
function collectInlineMath(token) {
|
|
84
|
+
const found = [];
|
|
85
|
+
const walk = (tokens) => {
|
|
86
|
+
for (const child of tokens ?? []) {
|
|
87
|
+
if (isMathToken(child))
|
|
88
|
+
found.push(child);
|
|
89
|
+
else
|
|
90
|
+
walk(child.tokens);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
walk(token.tokens);
|
|
94
|
+
return found;
|
|
95
|
+
}
|
|
96
|
+
/** A copy of `token` whose listed math tokens format as placeholder runs. */
|
|
97
|
+
function withPlaceholders(token, slot) {
|
|
98
|
+
const children = token.tokens;
|
|
99
|
+
if (children === undefined)
|
|
100
|
+
return token;
|
|
101
|
+
return {
|
|
102
|
+
...token,
|
|
103
|
+
tokens: children.map(child => {
|
|
104
|
+
const placeholder = isMathToken(child) ? slot.get(child) : undefined;
|
|
105
|
+
return placeholder !== undefined
|
|
106
|
+
? { type: 'escape', raw: child.raw, text: placeholder }
|
|
107
|
+
: withPlaceholders(child, slot);
|
|
108
|
+
}),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Results for every request once all have settled; a cached set is used on
|
|
113
|
+
* the first render (a paragraph scrolled back into view switches at once).
|
|
114
|
+
*/
|
|
115
|
+
function useSettledRasters(requests) {
|
|
116
|
+
const key = requests === undefined ? undefined : requests.map(requestKey).join('\u0001');
|
|
117
|
+
const cached = React.useMemo(() => {
|
|
118
|
+
if (requests === undefined)
|
|
119
|
+
return undefined;
|
|
120
|
+
const peeked = requests.map(peekMathRaster);
|
|
121
|
+
return peeked.every(result => result !== undefined) ? peeked : undefined;
|
|
122
|
+
// `key` captures every field of every request.
|
|
123
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
124
|
+
}, [key]);
|
|
125
|
+
const [settled, setSettled] = React.useState();
|
|
126
|
+
React.useEffect(() => {
|
|
127
|
+
if (requests === undefined || cached !== undefined || key === undefined)
|
|
128
|
+
return;
|
|
129
|
+
let live = true;
|
|
130
|
+
void Promise.all(requests.map(renderMathRaster)).then(results => {
|
|
131
|
+
if (live)
|
|
132
|
+
setSettled({ key, results });
|
|
133
|
+
});
|
|
134
|
+
return () => { live = false; };
|
|
135
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
136
|
+
}, [key]);
|
|
137
|
+
if (cached !== undefined)
|
|
138
|
+
return cached;
|
|
139
|
+
return settled !== undefined && settled.key === key ? settled.results : undefined;
|
|
140
|
+
}
|
|
141
|
+
function requestKey(request) {
|
|
142
|
+
return [request.tex, request.color, request.cellSize.width, request.cellSize.height, request.maxColumns, request.maxRows].join('\u0000');
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The laid-out width of the paragraph box. Its width comes from the parent,
|
|
146
|
+
* not from its content, but the guard from Divider still bounds how many
|
|
147
|
+
* distinct widths are applied per terminal width in case a layout ever
|
|
148
|
+
* feeds back.
|
|
149
|
+
*/
|
|
150
|
+
function useMeasuredWidth() {
|
|
151
|
+
const { columns } = useTerminalSize();
|
|
152
|
+
const ref = React.useRef(null);
|
|
153
|
+
const [value, setValue] = React.useState();
|
|
154
|
+
const negotiation = React.useRef({ columns, applied: [], frozen: false });
|
|
155
|
+
React.useLayoutEffect(() => {
|
|
156
|
+
const node = ref.current;
|
|
157
|
+
if (node === null)
|
|
158
|
+
return;
|
|
159
|
+
const state = negotiation.current;
|
|
160
|
+
if (state.columns !== columns) {
|
|
161
|
+
state.columns = columns;
|
|
162
|
+
state.applied = [];
|
|
163
|
+
state.frozen = false;
|
|
164
|
+
}
|
|
165
|
+
if (state.frozen)
|
|
166
|
+
return;
|
|
167
|
+
const measured = Math.floor(measureElement(node).width);
|
|
168
|
+
if (measured <= 0 || measured === value)
|
|
169
|
+
return;
|
|
170
|
+
if (state.applied.includes(measured) || state.applied.length >= MAX_APPLIED_MEASUREMENTS) {
|
|
171
|
+
state.frozen = true;
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
state.applied.push(measured);
|
|
175
|
+
setValue(measured);
|
|
176
|
+
});
|
|
177
|
+
return { ref, value };
|
|
178
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { type Tip } from '../tips.js';
|
|
3
3
|
import { type UpstreamDriftSummary } from '../dsh-adapter/contract.js';
|
|
4
|
+
import { type SplashEgg } from './splashEggs.js';
|
|
4
5
|
import { type WhaleIntroId } from './whaleFrames.js';
|
|
5
6
|
/**
|
|
6
7
|
* The header splash: one layout, two phases. The **opening** (~1.7–3.5s,
|
|
@@ -14,12 +15,23 @@ import { type WhaleIntroId } from './whaleFrames.js';
|
|
|
14
15
|
*
|
|
15
16
|
* Layout: the 13-row pixel whale beside a text column of matching height —
|
|
16
17
|
* the `✦ dsh-TUI` wordmark with version, the `DEEPSEEK`/`HARNESS` tagline in
|
|
17
|
-
* the 5-row block font (brand-blue → ice gradient
|
|
18
|
+
* the 5-row block font (brand-blue → ice gradient, a blank row between the
|
|
19
|
+
* two words, both stretched to the same width — see `splashFonts.ts` for the
|
|
20
|
+
* eight faces and the per-face kerning), the model/effort and
|
|
18
21
|
* cwd in plain text (no brand-color highlight), the startup tip, and below
|
|
19
22
|
* the whale the welcome tagline, centered under the art, in ice
|
|
20
|
-
* blue. Narrow terminals
|
|
23
|
+
* blue. Narrow terminals climb down the `resolveSplashLayout` ladder —
|
|
24
|
+
* whale + big text, then the big text alone, then the whale alone, then one
|
|
25
|
+
* plain title line. The face rotates by local date (`pickSplashFont`), so a
|
|
26
|
+
* given day always shows the same one.
|
|
27
|
+
*
|
|
28
|
+
* Two easter eggs sit on top of that layout without changing it (both live in
|
|
29
|
+
* `splashEggs.ts`): the holiday word pair swaps the two big-text words on its
|
|
30
|
+
* date (`MERRY` on 12/25, …), and a 1-in-20 roll replaces the welcome tagline
|
|
31
|
+
* with a clickable "star us on GitHub" line whose indent is recomputed from
|
|
32
|
+
* its own width.
|
|
21
33
|
*/
|
|
22
|
-
export declare function LogoV2({ model, effort, cwd, skipIntro, intro, tip, whale, whaleIdle, working, drift, }: {
|
|
34
|
+
export declare function LogoV2({ model, effort, cwd, skipIntro, intro, tip, fontId, whale, whaleIdle, whaleGirl, starred, starReveal, onStarClick, working, drift, egg, starChance, }: {
|
|
23
35
|
model: string;
|
|
24
36
|
effort?: string | undefined;
|
|
25
37
|
cwd: string;
|
|
@@ -27,10 +39,36 @@ export declare function LogoV2({ model, effort, cwd, skipIntro, intro, tip, whal
|
|
|
27
39
|
skipIntro?: boolean;
|
|
28
40
|
/** Test seam: pin the intro animation instead of rolling one at startup. */
|
|
29
41
|
intro?: WhaleIntroId;
|
|
42
|
+
/** Big-text face id (settings `dsh-tui.splashFont`); undefined → the
|
|
43
|
+
* date-rotated `pickSplashFont()`. */
|
|
44
|
+
fontId?: string | undefined;
|
|
30
45
|
/** Test seam: pin the startup tip line (probes need a deterministic tip). */
|
|
31
46
|
tip?: Tip;
|
|
47
|
+
/** Test seam: pin the holiday word pair instead of reading the local date
|
|
48
|
+
* (`null` forces the normal words; `undefined` — production — rolls by
|
|
49
|
+
* date). See `splashEggs.ts`. */
|
|
50
|
+
egg?: SplashEgg | null;
|
|
51
|
+
/** Test seam: pin the star tagline's chance (1 forces the egg, 0 suppresses
|
|
52
|
+
* it; production rolls `SPLASH_STAR_CHANCE` once per mount). */
|
|
53
|
+
starChance?: number;
|
|
32
54
|
/** Show the pixel whale art (settings `dsh-tui.whale`); off → text-only header. */
|
|
33
55
|
whale?: boolean;
|
|
56
|
+
/** Swap the header's pixel whale for the maid portrait (settings
|
|
57
|
+
* `dsh-tui.whaleGirl`; off by default). The portrait renders FIRST as a
|
|
58
|
+
* real raster through the terminal image protocols (Kitty/Sixel —
|
|
59
|
+
* `maidPortrait.tsx`), keeping the art's full fidelity; when the terminal
|
|
60
|
+
* cannot (inline mode, unsupported protocol, decode failure) the
|
|
61
|
+
* character-art maid (`WhaleGirl.tsx`, the author's placeholder to be
|
|
62
|
+
* replaced with better art) takes the slot. Both forms are static, so
|
|
63
|
+
* `whaleIdle` only animates the whale. */
|
|
64
|
+
whaleGirl?: boolean;
|
|
65
|
+
/** 本次会话已经 star 过:彩蛋标题换成「捡到一颗小星星啦」,不再重复求。 */
|
|
66
|
+
starred?: boolean;
|
|
67
|
+
/** 彩蛋渐显的测试缝:`instant` 时三行一次画全(静态渲染夹具用;真机不传)。 */
|
|
68
|
+
starReveal?: 'instant';
|
|
69
|
+
/** 求 star 标语那一行被点击时执行(一键 star,与 `/star` / `Alt+S` 同一个
|
|
70
|
+
* 动作)。不传则那一行不可点——只有它出现时才有这个交互。 */
|
|
71
|
+
onStarClick?: () => void;
|
|
34
72
|
/** Welcome-phase idle whale behaviors — fin flutters, tail thumps,
|
|
35
73
|
* sleep after inactivity (settings `dsh-tui.whaleIdle`; on by default —
|
|
36
74
|
* an explicit `false` keeps the settled header timer-free). Click-hearts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LogoV2.d.ts","sourceRoot":"","sources":["../../../src/components/LogoV2.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAiB,KAAK,GAAG,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,EAAoD,KAAK,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"LogoV2.d.ts","sourceRoot":"","sources":["../../../src/components/LogoV2.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAiB,KAAK,GAAG,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,EAAoD,KAAK,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AAWxH,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAQ/E,OAAO,EAA+E,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAA;AA+CjI;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,MAAM,EACN,GAAG,EACH,SAAiB,EACjB,KAAK,EACL,GAAG,EACH,MAAM,EACN,KAAY,EACZ,SAAgB,EAChB,SAAiB,EACjB,OAAe,EACf,UAAU,EACV,WAAW,EACX,OAAe,EACf,KAAK,EACL,GAAG,EACH,UAAU,GACX,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,iFAAiF;IACjF,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,YAAY,CAAA;IACpB;0CACsC;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,6EAA6E;IAC7E,GAAG,CAAC,EAAE,GAAG,CAAA;IACT;;qCAEiC;IACjC,GAAG,CAAC,EAAE,SAAS,GAAG,IAAI,CAAA;IACtB;oEACgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,mFAAmF;IACnF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;;;;8CAO0C;IAC1C,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,4CAA4C;IAC5C,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gDAAgD;IAChD,UAAU,CAAC,EAAE,SAAS,CAAA;IACtB;sCACkC;IAClC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB;;;4CAGwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;mCAG+B;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;2EACuE;IACvE,KAAK,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAA;CACpC,GAAG,KAAK,CAAC,SAAS,CAgZlB"}
|