@deepseek-harness-tui/dsh-tui 0.11.0 → 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 +55 -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 +43 -20
- package/cordis.yml +6 -4
- package/lib/settings.json +1272 -0
- package/lib/types/activityPrefs.d.ts +24 -0
- package/lib/types/activityPrefs.d.ts.map +1 -1
- package/lib/types/activityPrefs.js +50 -1
- package/lib/types/adapter/channel/state.d.ts.map +1 -1
- package/lib/types/adapter/channel/state.js +3 -1
- 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 +14 -1
- 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 +53 -7
- package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-view.d.ts +43 -12
- package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel.d.ts +4 -1
- package/lib/types/adapter/ports/channel.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/ActivityLine.d.ts +7 -2
- package/lib/types/components/ActivityLine.d.ts.map +1 -1
- package/lib/types/components/ActivityLine.js +0 -8
- 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 +15 -5
- 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 +96 -9
- package/lib/types/components/SplitDiffView.d.ts.map +1 -1
- package/lib/types/components/SplitDiffView.js +3 -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/SubagentCard.d.ts.map +1 -1
- package/lib/types/components/SubagentCard.js +12 -6
- package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
- package/lib/types/components/SubagentDetailScene.js +8 -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/HintLine.d.ts +1 -2
- package/lib/types/components/design-system/HintLine.d.ts.map +1 -1
- package/lib/types/components/design-system/HintLine.js +1 -2
- 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 +2 -1
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantThinkingMessage.js +4 -2
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +2 -2
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +31 -26
- 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/activity-store.d.ts +221 -0
- package/lib/types/dsh-adapter/activity-store.d.ts.map +1 -0
- package/lib/types/dsh-adapter/activity-store.js +359 -0
- 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 +2 -1
- package/lib/types/dsh-adapter/channel/background-action.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/background-action.js +2 -0
- package/lib/types/dsh-adapter/channel/binding-events.d.ts +15 -14
- package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/binding-events.js +70 -21
- package/lib/types/dsh-adapter/channel/compaction.d.ts +2 -2
- package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/compaction.js +35 -4
- 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 +1 -2
- package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/model-switch.js +6 -2
- 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-adoption.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/session-adoption.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-adoption.js +1 -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 +3 -1
- package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-live-adoption.js +10 -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 +43 -9
- 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 -1
- package/lib/types/dsh-adapter/channel/session-resume.d.ts +2 -1
- package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-resume.js +5 -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 +19 -1
- package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/state.js +8 -3
- package/lib/types/dsh-adapter/channel/subagent-projection.d.ts +32 -17
- package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/subagent-projection.js +309 -8
- 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 +1 -1
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +34 -18
- package/lib/types/dsh-adapter/compat/index.d.ts +1 -1
- package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/compat/index.js +1 -1
- 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/compat/sessionLog.d.ts +18 -0
- package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -1
- package/lib/types/dsh-adapter/compat/sessionLog.js +18 -3
- package/lib/types/dsh-adapter/compat/settings.d.ts +2 -0
- package/lib/types/dsh-adapter/compat/settings.d.ts.map +1 -1
- package/lib/types/dsh-adapter/compat/settings.js +14 -0
- package/lib/types/dsh-adapter/contract.d.ts +5 -4
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +9 -5
- 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 +5 -3
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +168 -372
- 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/settings-sections.d.ts.map +1 -1
- package/lib/types/dsh-adapter/settings-sections.js +7 -4
- 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 +44 -6
- package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
- package/lib/types/dsh-adapter/subagents.js +163 -26
- 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/history.d.ts +13 -1
- package/lib/types/history.d.ts.map +1 -1
- package/lib/types/history.js +15 -2
- package/lib/types/i18n.d.ts +512 -41
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +199 -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/log-update.d.ts.map +1 -1
- package/lib/types/ink/log-update.js +19 -1
- 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 +68 -18
- package/lib/types/ink/selection.d.ts.map +1 -1
- package/lib/types/ink/selection.js +178 -31
- 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 +17 -1
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +618 -57
- 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 +5 -1
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +47 -17
- 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 +1 -1
- package/lib/types/utils/fold-long-lines.d.ts.map +1 -1
- package/lib/types/utils/fold-long-lines.js +3 -2
- 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/lib/types/working-activity.d.ts +10 -9
- package/lib/types/working-activity.d.ts.map +1 -1
- package/lib/types/working-activity.js +17 -10
- 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 +117 -99
- package/lib/types/components/design-system/KeyboardShortcutHint.d.ts +0 -19
- package/lib/types/components/design-system/KeyboardShortcutHint.d.ts.map +0 -1
- package/lib/types/components/design-system/KeyboardShortcutHint.js +0 -14
- package/lib/types/dsh-adapter/channel/activity.d.ts +0 -20
- package/lib/types/dsh-adapter/channel/activity.d.ts.map +0 -1
- package/lib/types/dsh-adapter/channel/activity.js +0 -113
- package/lib/types/terminal-utils/terminal.d.ts +0 -18
- package/lib/types/terminal-utils/terminal.d.ts.map +0 -1
- package/lib/types/terminal-utils/terminal.js +0 -96
|
@@ -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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { getLang, t as tr, tOr } from '../i18n.js';
|
|
4
4
|
import { pickRandomTip } from '../tips.js';
|
|
@@ -6,14 +6,21 @@ import { upstreamDriftSummary, UPSTREAM_VALIDATED_VERSION } from '../dsh-adapter
|
|
|
6
6
|
import { readFileSync } from 'node:fs';
|
|
7
7
|
import { dirname, join } from 'node:path';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
|
-
import { Box, Text, useAnimationFrame, useTerminalSize } from '../ui.js';
|
|
9
|
+
import { Box, Text, useAnimationFrame, useTerminalImages, useTerminalSize } from '../ui.js';
|
|
10
10
|
import { getTheme } from '../theme.js';
|
|
11
11
|
import { useTheme } from './design-system/ThemeProvider.js';
|
|
12
12
|
import { parseRGB } from './Spinner/spinnerUtils.js';
|
|
13
13
|
import { renderBigText } from './bigfont.js';
|
|
14
|
+
import { COLUMN_GAP, WHALE_BOX_WIDTH, resolveSplashLayout } from './splashLayout.js';
|
|
15
|
+
import { withTagline, pickSplashFont, splashFontById } from './splashFonts.js';
|
|
16
|
+
import { pickSplashEgg, splashStarLine } from './splashEggs.js';
|
|
17
|
+
import { isHistoricMilestone, markStarAsked, pendingStarMilestone, recordLaunch, STAR_MILESTONES, usageSnapshot } from '../usageStats.js';
|
|
18
|
+
import { effectiveComboDisplay } from '../utils/keymap.js';
|
|
14
19
|
import { stringWidth } from '../ink/stringWidth.js';
|
|
15
20
|
import { BRAND, FLASH, ICE, PALE, sweep } from './shimmer.js';
|
|
16
21
|
import { STANDARD_FRAME_INDEX, WhaleArt } from './Whale.js';
|
|
22
|
+
import { WhaleGirlArt } from './WhaleGirl.js';
|
|
23
|
+
import { MAID_BOX_CENTER, MaidPortrait, useMaidPortraits } from './maidPortrait.js';
|
|
17
24
|
import { OPENING_SEQUENCES, pickOpeningSequence, WHALE_FRAME_INDEX } from './whaleFrames.js';
|
|
18
25
|
import { RESTING_POSE } from './whaleLayers.js';
|
|
19
26
|
import { initialWhaleIdleState, nextWhaleIdleStep, } from './whaleIdle.js';
|
|
@@ -35,14 +42,6 @@ const VERSION = (() => {
|
|
|
35
42
|
return '0.1.0';
|
|
36
43
|
}
|
|
37
44
|
})();
|
|
38
|
-
/** Below this width the whale hides and the header goes text-only. */
|
|
39
|
-
const WHALE_MIN_COLUMNS = 64;
|
|
40
|
-
/**
|
|
41
|
-
* Fixed whale box width: the tail-wag frames reach 4 columns further right
|
|
42
|
-
* than the standard pose, and a pinned width keeps the text column from
|
|
43
|
-
* shifting sideways during the opening animation.
|
|
44
|
-
*/
|
|
45
|
-
const FULL_WHALE_WIDTH = 40;
|
|
46
45
|
/**
|
|
47
46
|
* Center of the whale art's bounding box: sprite columns 3..34 (center
|
|
48
47
|
* 18.5) of the 40-wide box. The welcome tagline is indented so its own
|
|
@@ -54,6 +53,8 @@ const FULL_WHALE_WIDTH = 40;
|
|
|
54
53
|
* centered under the art too.
|
|
55
54
|
*/
|
|
56
55
|
const WHALE_CENTER = 18.5;
|
|
56
|
+
/** 「高兴鲸娘」停留时长(点她之后自动回安静版)。 */
|
|
57
|
+
const MAID_HAPPY_MS = 3000;
|
|
57
58
|
/** `max` → `Max` (effort levels arrive lower-case from the adapter). */
|
|
58
59
|
function capitalize(text) {
|
|
59
60
|
return text.length === 0 ? text : text[0].toUpperCase() + text.slice(1);
|
|
@@ -70,12 +71,23 @@ function capitalize(text) {
|
|
|
70
71
|
*
|
|
71
72
|
* Layout: the 13-row pixel whale beside a text column of matching height —
|
|
72
73
|
* the `✦ dsh-TUI` wordmark with version, the `DEEPSEEK`/`HARNESS` tagline in
|
|
73
|
-
* the 5-row block font (brand-blue → ice gradient
|
|
74
|
+
* the 5-row block font (brand-blue → ice gradient, a blank row between the
|
|
75
|
+
* two words, both stretched to the same width — see `splashFonts.ts` for the
|
|
76
|
+
* eight faces and the per-face kerning), the model/effort and
|
|
74
77
|
* cwd in plain text (no brand-color highlight), the startup tip, and below
|
|
75
78
|
* the whale the welcome tagline, centered under the art, in ice
|
|
76
|
-
* blue. Narrow terminals
|
|
79
|
+
* blue. Narrow terminals climb down the `resolveSplashLayout` ladder —
|
|
80
|
+
* whale + big text, then the big text alone, then the whale alone, then one
|
|
81
|
+
* plain title line. The face rotates by local date (`pickSplashFont`), so a
|
|
82
|
+
* given day always shows the same one.
|
|
83
|
+
*
|
|
84
|
+
* Two easter eggs sit on top of that layout without changing it (both live in
|
|
85
|
+
* `splashEggs.ts`): the holiday word pair swaps the two big-text words on its
|
|
86
|
+
* date (`MERRY` on 12/25, …), and a 1-in-20 roll replaces the welcome tagline
|
|
87
|
+
* with a clickable "star us on GitHub" line whose indent is recomputed from
|
|
88
|
+
* its own width.
|
|
77
89
|
*/
|
|
78
|
-
export function LogoV2({ model, effort, cwd, skipIntro = false, intro, tip, whale = true, whaleIdle = true, working = false, drift, }) {
|
|
90
|
+
export function LogoV2({ model, effort, cwd, skipIntro = false, intro, tip, fontId, whale = true, whaleIdle = true, whaleGirl = false, starred = false, starReveal, onStarClick, working = false, drift, egg, starChance, }) {
|
|
79
91
|
// One intro per logo mount: the production path rolls (startup splash
|
|
80
92
|
// and each /deepseek replay roll independently), the `intro` seam pins
|
|
81
93
|
// a specific animation for probes.
|
|
@@ -134,13 +146,52 @@ export function LogoV2({ model, effort, cwd, skipIntro = false, intro, tip, whal
|
|
|
134
146
|
clearTimeout(timer);
|
|
135
147
|
};
|
|
136
148
|
}, [heartSeq, heartKey, settled, whaleIdle, whaleFrozen]);
|
|
149
|
+
/** 预览缝:`DSH_TUI_STAR_LINE=1` 时开屏就显示求 star 标语行(不记账)。 */
|
|
150
|
+
const starLinePreview = process.env.DSH_TUI_STAR_LINE === '1';
|
|
137
151
|
const [themeName] = useTheme();
|
|
152
|
+
/** 终端真底色(Sixel 不透明衬底;见渲染处的注释)。 */
|
|
138
153
|
const theme = getTheme(themeName);
|
|
139
154
|
const { columns } = useTerminalSize();
|
|
140
155
|
const wordmarkRGB = parseRGB(theme.accent) ?? BRAND;
|
|
141
156
|
const wordmarkShimmerRGB = parseRGB(theme.accentShimmer) ?? ICE;
|
|
142
157
|
const taglineRGB = parseRGB(theme.activity) ?? ICE;
|
|
143
|
-
|
|
158
|
+
// 按天轮换的大字字体:同一天内恒定、隔天换一款;`fontId`(设置项)可 pin 住一款。
|
|
159
|
+
const [dailyFont] = React.useState(() => pickSplashFont());
|
|
160
|
+
const font = fontId === undefined ? dailyFont : splashFontById(fontId);
|
|
161
|
+
// 节日彩蛋:本地日期整天恒定,每次 mount 只判一次(照 pickSplashFont 的写法)。
|
|
162
|
+
// 只换词——字身宽度不变、字距按新词重解,所以阶梯阈值也跟着当天真实标题宽度走。
|
|
163
|
+
const [dailyEgg] = React.useState(() => (egg === undefined ? pickSplashEgg() : egg));
|
|
164
|
+
const titleFont = dailyEgg === null ? font : withTagline(font, dailyEgg.top, dailyEgg.bottom);
|
|
165
|
+
// 窄终端阶梯:鲸鱼 + 大字 → 纯大字 → 纯鲸鱼 → 一行纯文字(阈值随字体字身宽度变)。
|
|
166
|
+
const { showWhale, showBigTitle, showPlainTitle } = resolveSplashLayout(columns, { whale, font: titleFont });
|
|
167
|
+
// 女仆娘档优先走**真图**(Kitty/Sixel 终端图像协议,见 `maidPortrait.tsx`);
|
|
168
|
+
// 协议不可用(内联模式、终端不支持)或资产解码失败时,回落到字符画版
|
|
169
|
+
// 女仆娘(`WhaleGirl.tsx` 半块精灵——作者占位,之后会换更好看的)。
|
|
170
|
+
// 两种形态都是静态立绘:闲置动画与点击爱心仍是鲸鱼专属。
|
|
171
|
+
// `maidImageActive` 只在「真图画出来了」时为真。
|
|
172
|
+
const imagesAvailable = useTerminalImages(whaleGirl);
|
|
173
|
+
const portraits = useMaidPortraits(whaleGirl && imagesAvailable);
|
|
174
|
+
const maidSource = portraits?.normal;
|
|
175
|
+
const maidImageActive = whaleGirl && imagesAvailable && maidSource !== undefined;
|
|
176
|
+
// 点一下她 → 换成「高兴鲸娘」几秒(自动回安静版;第一个任务后定格、
|
|
177
|
+
// 不再响应,与鲸鱼的规则一致)。定时器在卸载/重挂时清掉。
|
|
178
|
+
const [maidHappy, setMaidHappy] = React.useState(false);
|
|
179
|
+
const maidHappyTimerRef = React.useRef(null);
|
|
180
|
+
const reactMaid = React.useCallback(() => {
|
|
181
|
+
setMaidHappy(true);
|
|
182
|
+
if (maidHappyTimerRef.current !== null)
|
|
183
|
+
clearTimeout(maidHappyTimerRef.current);
|
|
184
|
+
const timer = setTimeout(() => {
|
|
185
|
+
maidHappyTimerRef.current = null;
|
|
186
|
+
setMaidHappy(false);
|
|
187
|
+
}, MAID_HAPPY_MS);
|
|
188
|
+
timer.unref?.();
|
|
189
|
+
maidHappyTimerRef.current = timer;
|
|
190
|
+
}, []);
|
|
191
|
+
React.useEffect(() => () => {
|
|
192
|
+
if (maidHappyTimerRef.current !== null)
|
|
193
|
+
clearTimeout(maidHappyTimerRef.current);
|
|
194
|
+
}, []);
|
|
144
195
|
// Welcome-phase idle behaviors (settings `dsh-tui.whaleIdle`): fin
|
|
145
196
|
// flutters, tail thumps and blinks while idle, and a sleep-Z loop after
|
|
146
197
|
// sustained inactivity — all as INDEPENDENT layers composed per tick
|
|
@@ -156,7 +207,9 @@ export function LogoV2({ model, effort, cwd, skipIntro = false, intro, tip, whal
|
|
|
156
207
|
const pendingHeartRef = React.useRef(false);
|
|
157
208
|
const tickRef = React.useRef(null);
|
|
158
209
|
React.useEffect(() => {
|
|
159
|
-
|
|
210
|
+
// 女仆娘档(真图或字符画)没有闲置规划器:立绘是静态的,开屏定格
|
|
211
|
+
// 后不给她留任何定时器。
|
|
212
|
+
if (!settled || !whaleIdle || !showWhale || whaleFrozen || whaleGirl) {
|
|
160
213
|
setIdlePose(null);
|
|
161
214
|
tickRef.current = null;
|
|
162
215
|
return;
|
|
@@ -187,7 +240,7 @@ export function LogoV2({ model, effort, cwd, skipIntro = false, intro, tip, whal
|
|
|
187
240
|
if (timer !== undefined)
|
|
188
241
|
clearTimeout(timer);
|
|
189
242
|
};
|
|
190
|
-
}, [settled, whaleIdle, showWhale, working, whaleFrozen]);
|
|
243
|
+
}, [settled, whaleIdle, showWhale, working, whaleFrozen, whaleGirl]);
|
|
191
244
|
// Render priority: the layered planner pose owns the settled header while
|
|
192
245
|
// it runs (hearts and blinks compose over the body planes). Otherwise a
|
|
193
246
|
// click heart plays as whole heart frames over the intro — or over the
|
|
@@ -201,6 +254,55 @@ export function LogoV2({ model, effort, cwd, skipIntro = false, intro, tip, whal
|
|
|
201
254
|
// off-screen, leaving the static gradient behind.
|
|
202
255
|
const t = settled ? 0 : time;
|
|
203
256
|
const tagline = tr('logo-tagline');
|
|
257
|
+
// 求 star 改由**本机用量里程碑**触发(累计启动次数 / 累计在线时长),不再每次随机:
|
|
258
|
+
// 跨档时只报最高那一档、每档只报一次(`usageStats` 记账)。`starChance` 退化成测试缝
|
|
259
|
+
// ——0 关掉、非 0 强开(强开时用最高那档的文案)。`DSH_TUI_STAR_LINE=1`
|
|
260
|
+
// 是给人看效果的预览缝:强开标语行且**不记账**(生产不设这个变量)。
|
|
261
|
+
const [starMilestone] = React.useState(() => {
|
|
262
|
+
const usage = recordLaunch();
|
|
263
|
+
if (starLinePreview)
|
|
264
|
+
return STAR_MILESTONES.length - 1;
|
|
265
|
+
if (starChance === 0)
|
|
266
|
+
return null;
|
|
267
|
+
if (starChance !== undefined)
|
|
268
|
+
return STAR_MILESTONES.length - 1;
|
|
269
|
+
const pending = pendingStarMilestone(usage);
|
|
270
|
+
// 历史性时刻(99h / 999 次)不走标语行——那两档归 Chat 的开屏弹窗
|
|
271
|
+
//(弹窗自己 markStarAsked)。这里既不画也不记,档位保持待报;
|
|
272
|
+
// 弹窗这轮没机会弹(回合中等)就留给下一次启动。
|
|
273
|
+
return pending !== null && isHistoricMilestone(pending) ? null : pending;
|
|
274
|
+
});
|
|
275
|
+
const starLine = starMilestone === null
|
|
276
|
+
? null
|
|
277
|
+
: splashStarLine({ usage: usageSnapshot(), keyHint: effectiveComboDisplay('star'), caught: starred });
|
|
278
|
+
// 彩蛋的渐显:标题先出,数字一秒后、求星行两秒后各跟一行(只在标语块
|
|
279
|
+
// 出现时播一次;本次会话已 star 过、或重挂时直接展开)。
|
|
280
|
+
const starLineActive = starLine !== null;
|
|
281
|
+
const starRevealInstant = starReveal === 'instant';
|
|
282
|
+
const [revealed, setRevealed] = React.useState(() => (starRevealInstant ? 2 : 0));
|
|
283
|
+
React.useEffect(() => {
|
|
284
|
+
if (!starLineActive)
|
|
285
|
+
return;
|
|
286
|
+
if (starRevealInstant || starred === true) {
|
|
287
|
+
setRevealed(2);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const timers = [
|
|
291
|
+
setTimeout(() => setRevealed(previous => Math.max(previous, 1)), 1000),
|
|
292
|
+
setTimeout(() => setRevealed(previous => Math.max(previous, 2)), 2000),
|
|
293
|
+
];
|
|
294
|
+
for (const timer of timers)
|
|
295
|
+
timer.unref?.();
|
|
296
|
+
return () => { for (const timer of timers)
|
|
297
|
+
clearTimeout(timer); };
|
|
298
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- 只在标语块出现时播一次
|
|
299
|
+
}, [starLineActive]);
|
|
300
|
+
// 显示过就把这一档记下来,下次启动不再冒出来(同档只求一次)。预览缝
|
|
301
|
+
// (`DSH_TUI_STAR_LINE=1`)不记账——那是给人看效果的,不该消耗档位。
|
|
302
|
+
React.useEffect(() => {
|
|
303
|
+
if (starMilestone !== null && !starLinePreview)
|
|
304
|
+
markStarAsked(starMilestone);
|
|
305
|
+
}, [starMilestone]);
|
|
204
306
|
// One random tip per mount: the settled header must not re-roll on every
|
|
205
307
|
// repaint (language switch, terminal resize), or the line would flicker.
|
|
206
308
|
// `tip` is a test seam; production always passes undefined and rolls.
|
|
@@ -209,20 +311,42 @@ export function LogoV2({ model, effort, cwd, skipIntro = false, intro, tip, whal
|
|
|
209
311
|
// the same memoized contract data the adapter checks (undefined when the
|
|
210
312
|
// install matches). `drift` is a test seam to pin or suppress it.
|
|
211
313
|
const [driftLine] = React.useState(() => drift === undefined ? upstreamDriftSummary() : drift);
|
|
212
|
-
// Indent that centers the tagline under the whale art's bounding box
|
|
314
|
+
// Indent that centers the tagline under the whale art's bounding box, from
|
|
315
|
+
// the width the line ACTUALLY shows: the star easter egg renders a longer
|
|
316
|
+
// line than `logo-tagline`, so reusing the tagline's width would push it
|
|
317
|
+
// visibly off-center.
|
|
318
|
+
const welcomeWidth = starLine === null ? stringWidth(tagline) : starLine.width;
|
|
213
319
|
const welcomePad = showWhale
|
|
214
|
-
? Math.max(0, Math.round(WHALE_CENTER -
|
|
320
|
+
? Math.max(0, Math.round((whaleGirl ? MAID_BOX_CENTER : WHALE_CENTER) - welcomeWidth / 2))
|
|
215
321
|
: 2;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
322
|
+
// 两行标题各自用字体声明的字距;下排再按 `bottomIndent` 居中——
|
|
323
|
+
// 两者一起保证画出来的列数相等(见 splashFonts 的 tagline 契约)。
|
|
324
|
+
// 节日彩蛋换的就是这里的两排词(`titleFont` 已按当天词对重解字距);字体若自带
|
|
325
|
+
// 配色(半立体那款的灰阶)就用它,否则沿用主题的 accent→activity。
|
|
326
|
+
const { top, bottom, topKerning, bottomKerning, bottomIndent } = titleFont.tagline;
|
|
327
|
+
const bigDeepSeek = renderBigText(titleFont, top, t, titleFont.palette?.from ?? wordmarkRGB, titleFont.palette?.to ?? taglineRGB, FLASH, 60, topKerning);
|
|
328
|
+
const bigHarness = renderBigText(titleFont, bottom, t, titleFont.palette?.from ?? taglineRGB, titleFont.palette?.to ?? PALE, FLASH, 60, bottomKerning, bottomIndent);
|
|
329
|
+
// 立绘槽位的**唯一真源**:文字列的实际行数——词标 1 + 两排大字 + 两排
|
|
330
|
+
// 之间空 1 行 + 模型/目录/提示 3 行。槽位与它等高,图片既不压过文字列
|
|
331
|
+
// 也不留一截在下面(实机反馈「超出去、不和谐」);大字换字体/换词时也
|
|
332
|
+
// 自动跟着变,不写死 15。
|
|
333
|
+
const textColumnRows = bigDeepSeek.length + bigHarness.length + 5;
|
|
334
|
+
return (_jsxs(Box, { ref: ref, flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { flexDirection: "row", gap: COLUMN_GAP, width: "100%", alignItems: "center", children: [showWhale && (_jsx(Box, { flexShrink: 0, onClick: () => {
|
|
219
335
|
// Frozen (first task started): the whale is a static logo —
|
|
220
336
|
// clicks do nothing. Settled: the layered planner consumes the
|
|
221
337
|
// click on its next tick — run that tick immediately so the
|
|
222
338
|
// heart shows instantly instead of after the current delay.
|
|
223
|
-
// Intro: the whole-frame heart pass above.
|
|
339
|
+
// Intro: the whole-frame heart pass above. The maid (raster)
|
|
340
|
+
// reacts with the happy portrait instead of hearts; character-
|
|
341
|
+
// art fallback stays static.
|
|
224
342
|
if (whaleFrozen)
|
|
225
343
|
return;
|
|
344
|
+
if (maidImageActive) {
|
|
345
|
+
reactMaid();
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
if (whaleGirl)
|
|
349
|
+
return;
|
|
226
350
|
if (settled && whaleIdle) {
|
|
227
351
|
pendingHeartRef.current = true;
|
|
228
352
|
tickRef.current?.();
|
|
@@ -231,9 +355,9 @@ export function LogoV2({ model, effort, cwd, skipIntro = false, intro, tip, whal
|
|
|
231
355
|
setHeartSeq(0);
|
|
232
356
|
setHeartKey(k => k + 1);
|
|
233
357
|
}
|
|
234
|
-
}, children: _jsx(WhaleArt, { frameIndex: frameIndex, pose: settled && whaleIdle && !whaleFrozen ? (idlePose ?? RESTING_POSE) : undefined, width:
|
|
358
|
+
}, children: whaleGirl ? (_jsx(Box, { width: WHALE_BOX_WIDTH, height: textColumnRows, flexDirection: "row", justifyContent: "center", alignItems: "center", children: maidImageActive ? (_jsx(MaidPortrait, { source: maidHappy ? (portraits?.happy ?? maidSource) : maidSource, maxColumns: WHALE_BOX_WIDTH, maxRows: textColumnRows, presentation: "transcript" })) : (_jsx(WhaleGirlArt, { width: WHALE_BOX_WIDTH })) })) : (_jsx(WhaleArt, { frameIndex: frameIndex, pose: settled && whaleIdle && !whaleFrozen ? (idlePose ?? RESTING_POSE) : undefined, width: WHALE_BOX_WIDTH })) })), (showBigTitle || showPlainTitle) && (_jsxs(Box, { flexDirection: "column", flexShrink: 1, children: [_jsxs(Text, { wrap: "truncate-end", children: [sweep('✦ dsh-TUI', t, wordmarkRGB, wordmarkShimmerRGB, 60), _jsx(Text, { dimColor: true, children: ' v' + VERSION })] }), showBigTitle ? (_jsxs(_Fragment, { children: [bigDeepSeek.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `ds-${index}`))), _jsx(Box, { height: 1 }), bigHarness.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `h-${index}`)))] })) : (showPlainTitle && (_jsx(Text, { color: "accent", bold: true, wrap: "truncate-end", children: "DeepSeek Harness" }))), _jsxs(Text, { wrap: "truncate-end", children: [model, effort !== undefined && _jsx(Text, { dimColor: true, children: ' · ' + capitalize(effort) + ' effort' })] }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: cwd }), _jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { dimColor: true, children: tr('logo-tip-prefix') }), getLang() === 'zh' ? randomTip.zh : randomTip.en, _jsx(Text, { dimColor: true, children: ' · /tips ' + tr('logo-tip-more') })] }), driftLine != null && (_jsxs(Text, { color: "warning", wrap: "wrap", children: ["\u26A0", ' ', tOr(`logo-drift-${driftLine.kind}`, `The dsh engine (${driftLine.versions.join(' / ')}) does not match the validated ${UPSTREAM_VALIDATED_VERSION}; reinstall via npm i -g @deepseek-ai/dsh@${UPSTREAM_VALIDATED_VERSION}.`, {
|
|
235
359
|
installed: driftLine.versions.join(' / '),
|
|
236
360
|
validated: UPSTREAM_VALIDATED_VERSION,
|
|
237
361
|
primary: UPSTREAM_VALIDATED_VERSION,
|
|
238
|
-
})] }))] })] }), _jsx(Box, { marginTop: 1, paddingLeft: welcomePad, children: _jsx(Text, { children: sweep(tagline, t, taglineRGB, FLASH, 60) }) })] }));
|
|
362
|
+
})] }))] }))] }), _jsx(Box, { flexDirection: "column", marginTop: 1, ...(starLine === null || onStarClick === undefined ? {} : { onClick: onStarClick }), children: starLine === null ? (_jsx(Box, { paddingLeft: welcomePad, children: _jsx(Text, { children: sweep(tagline, t, taglineRGB, FLASH, 60) }) })) : (_jsxs(_Fragment, { children: [_jsx(Box, { paddingLeft: welcomePad, children: _jsx(Text, { children: sweep(starLine.title, t, taglineRGB, FLASH, 60) }) }), revealed >= 1 && (_jsx(Box, { paddingLeft: welcomePad, children: _jsx(Text, { dimColor: true, children: starLine.stats }) })), revealed >= 2 && starred !== true && starLine.ask !== null && (_jsx(Box, { paddingLeft: welcomePad, children: _jsx(Text, { children: starLine.ask }) }))] })) })] }));
|
|
239
363
|
}
|
|
@@ -4,8 +4,9 @@ import { type Token } from 'marked';
|
|
|
4
4
|
* Markdown 渲染组件:marked 分词 + ANSI 格式化。
|
|
5
5
|
*
|
|
6
6
|
* 表格 token 交给 MarkdownTable 渲染为带边框的 flexbox 布局,mermaid
|
|
7
|
-
* 代码块交给 MermaidDiagram 画成 box-drawing
|
|
8
|
-
*
|
|
7
|
+
* 代码块交给 MermaidDiagram 画成 box-drawing 图,`$$` 公式块交给
|
|
8
|
+
* MathBlock 排成多行 Unicode(三者都需要终端宽度,所以是独立节点而不是
|
|
9
|
+
* ANSI 字符串);行内公式在 formatToken 里转成单行 Unicode;
|
|
9
10
|
* 其余块级内容由 formatToken 转成 ANSI 字符串,按块边界分批放进
|
|
10
11
|
* Text(只去整段首尾空白)。代码块高亮由 cli-highlight 异步提供,
|
|
11
12
|
* 加载完成后自动触发一次重渲染。无 markdown 语法的纯文本走快速
|
|
@@ -17,6 +18,12 @@ type Props = {
|
|
|
17
18
|
dimColor?: boolean;
|
|
18
19
|
/** 为 false 时跳过 token 缓存(流式尾部的内容逐帧变化,缓存必然失效) */
|
|
19
20
|
cacheTokens?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Whether paragraphs may show inline math as images (`mathRendering:
|
|
23
|
+
* image`). Streaming text passes false: a paragraph switching to images
|
|
24
|
+
* mid-stream would re-wrap under the reader; the settled message switches.
|
|
25
|
+
*/
|
|
26
|
+
inlineMathImages?: boolean;
|
|
20
27
|
};
|
|
21
28
|
/**
|
|
22
29
|
* Tokens that render as their own layout node (a width-aware component)
|
|
@@ -36,7 +43,7 @@ export declare function isStandaloneToken(token: Token): boolean;
|
|
|
36
43
|
* block — the dominant long-output stall (string-width via wrap-ansi, 60%+
|
|
37
44
|
* of CPU in streaming profiles).
|
|
38
45
|
*/
|
|
39
|
-
declare function MarkdownImpl({ children, dimColor, cacheTokens }: Props): React.ReactNode;
|
|
46
|
+
declare function MarkdownImpl({ children, dimColor, cacheTokens, inlineMathImages }: Props): React.ReactNode;
|
|
40
47
|
/**
|
|
41
48
|
* Memoized Markdown: skips the whole token→ANSI→layout pipeline when the
|
|
42
49
|
* content string is the same reference (see MarkdownImpl's doc comment).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAU,KAAK,KAAK,EAAe,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAU,KAAK,KAAK,EAAe,MAAM,QAAQ,CAAA;AAYxD;;;;;;;;;;;GAWG;AAEH,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B,CAAA;AAyED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAEvD;AAuGD;;;;;;;;;;GAUG;AACH,iBAAS,YAAY,CAAC,EAAE,QAAQ,EAAE,QAAgB,EAAE,WAAkB,EAAE,gBAAuB,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAkCzH;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ,gDAOpB,CAAA"}
|