@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
|
@@ -14,6 +14,7 @@ import { foldLongLines } from '../../utils/fold-long-lines.js';
|
|
|
14
14
|
import { getLang, t } from '../../i18n.js';
|
|
15
15
|
import { revealLinesOf, snapReveal } from '../smoothReveal.js';
|
|
16
16
|
import { useRevealVersion } from '../../hooks/useRevealVersion.js';
|
|
17
|
+
import { primaryComboString } from '../../utils/keymap.js';
|
|
17
18
|
/** Tool display names localize through the `tool-name-*` dictionary family
|
|
18
19
|
* (i18n.ts): DSH emits lowercase tool ids (`bash`), display names resolve
|
|
19
20
|
* per language — proper nouns (Bash, PowerShell) stay identical in zh.
|
|
@@ -191,7 +192,7 @@ function capLines(lines, max, verbose) {
|
|
|
191
192
|
return lines;
|
|
192
193
|
return [
|
|
193
194
|
...lines.slice(0, max),
|
|
194
|
-
{ ...dim(t('lines-folded-expand', { n: lines.length - max })), revealOnHover: true },
|
|
195
|
+
{ ...dim(t('lines-folded-expand', { n: lines.length - max, key: primaryComboString('transcript') })), revealOnHover: true },
|
|
195
196
|
];
|
|
196
197
|
}
|
|
197
198
|
/** Long-line clip for the body rows (utils/fold-long-lines.ts): the line cap
|
|
@@ -330,7 +331,7 @@ function HeaderTitle({ name, title, isTerminal, folded, displayArgs, argsLanguag
|
|
|
330
331
|
return (_jsxs(_Fragment, { children: [_jsx(Box, { flexShrink: 0, children: _jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: name }) }), displayArgs !== '' && (_jsxs(Box, { flexWrap: "nowrap", ...headerTooltip, children: [_jsx(Text, { children: "(" }), _jsx(SyntaxText, { text: clipHeaderArgs(displayArgs), sourceText: displayArgs, language: argsLanguage }), _jsx(Text, { children: ")" })] }))] }));
|
|
331
332
|
}
|
|
332
333
|
if (isTerminal) {
|
|
333
|
-
return (_jsxs(_Fragment, { children: [_jsx(Box, { flexShrink: 0, children: _jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: name }) }), _jsx(Box, { flexWrap: "nowrap", ...headerTooltip, children: folded === undefined ? (_jsxs(Text, { children: ["(", title, ")"] })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { children: ["(", folded.first, ")"] }), folded.hiddenLines > 0 && (_jsx(Text, { dimColor: true, children: ` ${t('lines-folded-expand', { n: folded.hiddenLines })}` }))] })) })] }));
|
|
334
|
+
return (_jsxs(_Fragment, { children: [_jsx(Box, { flexShrink: 0, children: _jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: name }) }), _jsx(Box, { flexWrap: "nowrap", ...headerTooltip, children: folded === undefined ? (_jsxs(Text, { children: ["(", title, ")"] })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { children: ["(", folded.first, ")"] }), folded.hiddenLines > 0 && (_jsx(Text, { dimColor: true, children: ` ${t('lines-folded-expand', { n: folded.hiddenLines, key: primaryComboString('transcript') })}` }))] })) })] }));
|
|
334
335
|
}
|
|
335
336
|
const trimmed = title.trim();
|
|
336
337
|
if (trimmed === '') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TranscriptImages.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/TranscriptImages.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAEtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;
|
|
1
|
+
{"version":3,"file":"TranscriptImages.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/TranscriptImages.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAEtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAA;AAW7E,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,gFAAgB,CAAA;AAEpD;wEACwE;AACxE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAGnE;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,MAAU,EACV,SAAS,EACT,gBAAwB,GACzB,EAAE;IACD,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;IACrD;iDAC6C;IAC7C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;CACpC,GAAG,KAAK,CAAC,SAAS,CA6BlB;AAqGD,yEAAyE;AACzE,wBAAgB,iCAAiC,IAAI,IAAI,CAGxD"}
|
|
@@ -5,6 +5,8 @@ import { TERMINAL_IMAGE_PREVIEW_MAX_EDGE, TERMINAL_IMAGE_PREVIEW_MAX_BYTES } fro
|
|
|
5
5
|
import { makeDecodeTier } from './transcriptImageDecode.js';
|
|
6
6
|
import { cleanRenderText } from '../../dsh-adapter/sanitize.js';
|
|
7
7
|
import { getLang, subscribeLang, t } from '../../i18n.js';
|
|
8
|
+
import { useTerminalBackground } from '../design-system/ThemeProvider.js';
|
|
9
|
+
import { getImageBacking, subscribeImageBacking } from '../../tuiDisplayPrefs.js';
|
|
8
10
|
const thumbnailTier = makeDecodeTier(384, 24);
|
|
9
11
|
// One modal at a time: current + previous suffices for instant reopen.
|
|
10
12
|
const fullTier = makeDecodeTier(TERMINAL_IMAGE_PREVIEW_MAX_EDGE, 2, TERMINAL_IMAGE_PREVIEW_MAX_BYTES / 4);
|
|
@@ -42,6 +44,14 @@ function TranscriptImagePreview({ image, width, height, graphicsAvailable, onPre
|
|
|
42
44
|
setState({ kind: 'failed' }); });
|
|
43
45
|
return () => { live = false; controller.abort(); };
|
|
44
46
|
}, [image, graphicsAvailable]);
|
|
47
|
+
// What sits behind the raster follows `dsh-tui.imageBacking`: photos
|
|
48
|
+
// may float transparent like formulas (the wallpaper shows at
|
|
49
|
+
// anti-aliased edges and transparent corners — Sixel's binary alpha drops
|
|
50
|
+
// their softest pixels) or composite onto the terminal colour, which
|
|
51
|
+
// keeps soft edges smooth on any background.
|
|
52
|
+
const backing = React.useSyncExternalStore(subscribeImageBacking, getImageBacking);
|
|
53
|
+
const composited = backing === 'terminal';
|
|
54
|
+
const terminalBackground = useTerminalBackground();
|
|
45
55
|
const label = transcriptImageLabel(image);
|
|
46
56
|
const fallback = !graphicsAvailable
|
|
47
57
|
? t('transcript-image-ready', { name: label })
|
|
@@ -50,7 +60,7 @@ function TranscriptImagePreview({ image, width, height, graphicsAvailable, onPre
|
|
|
50
60
|
: state.kind === 'loading'
|
|
51
61
|
? t('transcript-image-loading', { name: label })
|
|
52
62
|
: t('transcript-image-ready', { name: label });
|
|
53
|
-
const preview = (_jsx(Image, { presentation: "transcript", source: graphicsAvailable && state.kind === 'ready' ? state.source : undefined, width: width, height: height, alt: label, children: _jsx(Box, { width: width, height: height, alignItems: "center", justifyContent: "center", children: _jsxs(Text, { dimColor: true, wrap: "truncate", children: ["[", fallback, "]"] }) }) }));
|
|
63
|
+
const preview = (_jsx(Box, { backgroundColor: composited ? terminalBackground : undefined, children: _jsx(Image, { ...(composited ? {} : { transparent: true }), presentation: "transcript", source: graphicsAvailable && state.kind === 'ready' ? state.source : undefined, width: width, height: height, alt: label, children: _jsx(Box, { width: width, height: height, alignItems: "center", justifyContent: "center", children: _jsxs(Text, { dimColor: true, wrap: "truncate", children: ["[", fallback, "]"] }) }) }) }));
|
|
54
64
|
if (onPreview === undefined)
|
|
55
65
|
return preview;
|
|
56
66
|
return (_jsx(Box, { onClick: event => {
|
|
@@ -64,8 +64,20 @@ export type AskUserQuestionPanelProps = {
|
|
|
64
64
|
readonly onAnswer: (selection: QuestionSelection) => void;
|
|
65
65
|
/** Esc on the first question / Ctrl+C — aborts the whole ask. */
|
|
66
66
|
readonly onCancel: () => void;
|
|
67
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* Esc, when the host wants to decide back-vs-cancel from the live store.
|
|
69
|
+
* A same-batch → then Esc still runs on the panel mounted for question 1,
|
|
70
|
+
* whose `onBack` is absent; this callback sees that → already advanced.
|
|
71
|
+
*/
|
|
72
|
+
readonly onEscape?: (draft: QuestionDraft) => void;
|
|
73
|
+
/** Esc / ← on later questions — navigates to the previous question. */
|
|
68
74
|
readonly onBack?: (draft: QuestionDraft) => void;
|
|
75
|
+
/**
|
|
76
|
+
* → — navigates to the next question without submitting. On the free-text
|
|
77
|
+
* row this only fires when the caret is already at the end, so ←/→ keep
|
|
78
|
+
* editing the answer.
|
|
79
|
+
*/
|
|
80
|
+
readonly onForward?: (draft: QuestionDraft) => void;
|
|
69
81
|
/**
|
|
70
82
|
* Test seam: clipboard reader for the Ctrl+V paste arm. Defaults to the
|
|
71
83
|
* real cross-platform reader (PowerShell/pbpaste/wl-paste…); headless
|
|
@@ -89,5 +101,5 @@ export type AskUserQuestionPanelProps = {
|
|
|
89
101
|
* pointer, so an unclickable row would just eat a line. */
|
|
90
102
|
readonly fullscreen?: boolean;
|
|
91
103
|
};
|
|
92
|
-
export declare function AskUserQuestionPanel({ question, position, total, answered, initialDraft, onAnswer, onCancel, onBack, readClipboardOverride, collapsed, onExpand, onToggleFold, fullscreen, }: AskUserQuestionPanelProps): React.ReactNode;
|
|
104
|
+
export declare function AskUserQuestionPanel({ question, position, total, answered, initialDraft, onAnswer, onCancel, onEscape, onBack, onForward, readClipboardOverride, collapsed, onExpand, onToggleFold, fullscreen, }: AskUserQuestionPanelProps): React.ReactNode;
|
|
93
105
|
//# sourceMappingURL=AskUserQuestionPanel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AskUserQuestionPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/AskUserQuestionPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAMtF,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"AskUserQuestionPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/AskUserQuestionPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAMtF,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAuB5E,MAAM,MAAM,yBAAyB,GAAG;IACtC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;QAC9B;;oEAE4D;QAC5D,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;QAClC;;qEAE6D;QAC7D,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;QAC5C;0EACkE;QAClE,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAA;IACrC,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAClD,uEAAuE;IACvE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAChD;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IACnD;;;;OAIG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;IAC7D;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IAClC;;gEAE4D;IAC5D,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAC9B,CAAA;AAED,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,SAAS,EACT,qBAAqB,EACrB,SAAiB,EACjB,QAAQ,EACR,YAAY,EACZ,UAAkB,GACnB,EAAE,yBAAyB,GAAG,KAAK,CAAC,SAAS,CA2pB7C"}
|
|
@@ -34,10 +34,14 @@ import { POINTER } from '../../terminal-utils/figures.js';
|
|
|
34
34
|
import { PlanReviewPanel } from './PlanReviewPanel.js';
|
|
35
35
|
import { QuestionMinimizedBar } from './QuestionMinimizedBar.js';
|
|
36
36
|
import { isPlainReturnInput } from '../../utils/modifiers.js';
|
|
37
|
-
import { actionMatches, effectiveComboDisplay } from '../../utils/keymap.js';
|
|
37
|
+
import { actionMatches, comboDisplay, effectiveComboDisplay, primaryComboString } from '../../utils/keymap.js';
|
|
38
38
|
import { flattenPasteInline } from '../../dsh-adapter/sanitize.js';
|
|
39
39
|
import { readClipboard } from '../../utils/clipboard.js';
|
|
40
40
|
import { listWindow } from '../listWindow.js';
|
|
41
|
+
/** Unmodified arrows switch questions; Ctrl/Alt/Super/Shift stay caret motion. */
|
|
42
|
+
function isPlainArrow(key) {
|
|
43
|
+
return key.ctrl !== true && key.meta !== true && key.super !== true && key.shift !== true;
|
|
44
|
+
}
|
|
41
45
|
const CHECKED = '◉';
|
|
42
46
|
const UNCHECKED = '○';
|
|
43
47
|
const PENCIL = '✎';
|
|
@@ -51,7 +55,7 @@ const PENCIL = '✎';
|
|
|
51
55
|
* PlanReviewPanel (the two panels share the same input contract).
|
|
52
56
|
*/
|
|
53
57
|
const ANSWER_PASTE_MAX_POINTS = 8000;
|
|
54
|
-
export function AskUserQuestionPanel({ question, position, total, answered, initialDraft, onAnswer, onCancel, onBack, readClipboardOverride, collapsed = false, onExpand, onToggleFold, fullscreen = false, }) {
|
|
58
|
+
export function AskUserQuestionPanel({ question, position, total, answered, initialDraft, onAnswer, onCancel, onEscape, onBack, onForward, readClipboardOverride, collapsed = false, onExpand, onToggleFold, fullscreen = false, }) {
|
|
55
59
|
// Plan-mode's exit_plan_mode ask carries a presentation intent: render
|
|
56
60
|
// the plan decision card instead of the generic questionnaire. The
|
|
57
61
|
// branch precedes every hook so hook order stays stable per remount key.
|
|
@@ -79,6 +83,11 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
79
83
|
: selectedIndices[0] ?? 0;
|
|
80
84
|
const [focusIndex, setFocusIndex] = React.useState(initialFocus);
|
|
81
85
|
const [checked, setChecked] = React.useState(() => new Set(multiSelect ? selectedIndices : []));
|
|
86
|
+
// Same stdin batch, same closure: Space / ↑ / ↓ must be visible to a
|
|
87
|
+
// following → before React commits. Refs are the draft source; state
|
|
88
|
+
// only repaints.
|
|
89
|
+
const focusRef = React.useRef(initialFocus);
|
|
90
|
+
const checkedRef = React.useRef(new Set(multiSelect ? selectedIndices : []));
|
|
82
91
|
const [customText, setCustomText] = React.useState(initialCustom);
|
|
83
92
|
const [customCursor, setCustomCursor] = React.useState(() => [...initialCustom].length);
|
|
84
93
|
// Synchronous source of truth for the handlers (see the module header):
|
|
@@ -105,6 +114,28 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
105
114
|
/** Single-select label captured by typing on a focused option — submitted
|
|
106
115
|
* together with the custom text when the input row itself is Entered. */
|
|
107
116
|
const [attached, setAttached] = React.useState(() => initialCustom !== '' && !multiSelect ? (initialSelected[0] ?? null) : null);
|
|
117
|
+
const attachedRef = React.useRef(initialCustom !== '' && !multiSelect ? (initialSelected[0] ?? null) : null);
|
|
118
|
+
const placeFocus = (index) => {
|
|
119
|
+
focusRef.current = index;
|
|
120
|
+
setFocusIndex(index);
|
|
121
|
+
};
|
|
122
|
+
const placeChecked = (next) => {
|
|
123
|
+
checkedRef.current = next;
|
|
124
|
+
setChecked(next);
|
|
125
|
+
};
|
|
126
|
+
const toggleCheckedAt = (index) => {
|
|
127
|
+
const next = new Set(checkedRef.current);
|
|
128
|
+
if (next.has(index))
|
|
129
|
+
next.delete(index);
|
|
130
|
+
else
|
|
131
|
+
next.add(index);
|
|
132
|
+
placeChecked(next);
|
|
133
|
+
};
|
|
134
|
+
const placeAttached = (value) => {
|
|
135
|
+
attachedRef.current = value;
|
|
136
|
+
setAttached(value);
|
|
137
|
+
};
|
|
138
|
+
const onInputRow = () => !hideCustomInput && focusRef.current === options.length;
|
|
108
139
|
const [error, setError] = React.useState(null);
|
|
109
140
|
const inputFocused = !hideCustomInput && focusIndex === options.length;
|
|
110
141
|
// Chat chrome + panel scaffolding consume twelve rows before the option
|
|
@@ -139,7 +170,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
139
170
|
const moveFocus = (delta) => {
|
|
140
171
|
if (rowCount <= 1)
|
|
141
172
|
return;
|
|
142
|
-
|
|
173
|
+
placeFocus((focusRef.current + delta + rowCount) % rowCount);
|
|
143
174
|
setError(null);
|
|
144
175
|
};
|
|
145
176
|
/** Append at the text tail (option-row typing has no visible cursor). */
|
|
@@ -156,7 +187,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
156
187
|
points.splice(at - 1, 1);
|
|
157
188
|
const next = points.join('');
|
|
158
189
|
if (next === '')
|
|
159
|
-
|
|
190
|
+
placeAttached(null);
|
|
160
191
|
applyText(next, at - 1);
|
|
161
192
|
};
|
|
162
193
|
/**
|
|
@@ -181,7 +212,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
181
212
|
points.splice(at, 0, ...text);
|
|
182
213
|
applyText(points.join(''), at + [...text].length);
|
|
183
214
|
if (!atCaret && !multiSelect)
|
|
184
|
-
|
|
215
|
+
placeAttached(options[focusRef.current]?.label ?? null);
|
|
185
216
|
return 'ok';
|
|
186
217
|
};
|
|
187
218
|
/** Inline error for an over-cap paste (shared by both transports). */
|
|
@@ -223,7 +254,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
223
254
|
pasteBusyRef.current = false;
|
|
224
255
|
});
|
|
225
256
|
};
|
|
226
|
-
const checkedLabels = () => [...
|
|
257
|
+
const checkedLabels = () => [...checkedRef.current].sort((a, b) => a - b).map(index => options[index]?.label)
|
|
227
258
|
.filter((label) => label !== undefined);
|
|
228
259
|
/** Enter on a real option: the option(s) plus whatever the input row holds. */
|
|
229
260
|
const submitOptions = () => {
|
|
@@ -237,7 +268,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
237
268
|
onAnswer({ selected, ...(text !== '' ? { custom: text } : {}) });
|
|
238
269
|
return;
|
|
239
270
|
}
|
|
240
|
-
const label = options[
|
|
271
|
+
const label = options[focusRef.current]?.label;
|
|
241
272
|
if (label === undefined) {
|
|
242
273
|
setError(t('question-select-or-answer'));
|
|
243
274
|
return;
|
|
@@ -261,16 +292,16 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
261
292
|
setError(t('question-type-answer-first'));
|
|
262
293
|
return;
|
|
263
294
|
}
|
|
264
|
-
onAnswer({ selected:
|
|
295
|
+
onAnswer({ selected: attachedRef.current !== null ? [attachedRef.current] : [], custom: text });
|
|
265
296
|
};
|
|
266
297
|
/** Capture the visible answer state before navigating away. */
|
|
267
298
|
const currentDraft = () => {
|
|
268
299
|
const selected = multiSelect
|
|
269
300
|
? checkedLabels()
|
|
270
|
-
:
|
|
271
|
-
? (
|
|
301
|
+
: onInputRow()
|
|
302
|
+
? (attachedRef.current === null ? [] : [attachedRef.current])
|
|
272
303
|
: (() => {
|
|
273
|
-
const label = options[
|
|
304
|
+
const label = options[focusRef.current]?.label;
|
|
274
305
|
return label === undefined ? [] : [label];
|
|
275
306
|
})();
|
|
276
307
|
return {
|
|
@@ -299,7 +330,9 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
299
330
|
return;
|
|
300
331
|
}
|
|
301
332
|
if (key.escape) {
|
|
302
|
-
if (
|
|
333
|
+
if (onEscape !== undefined)
|
|
334
|
+
onEscape(currentDraft());
|
|
335
|
+
else if (onBack !== undefined)
|
|
303
336
|
onBack(currentDraft());
|
|
304
337
|
else
|
|
305
338
|
onCancel();
|
|
@@ -328,7 +361,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
328
361
|
pasteFromClipboard();
|
|
329
362
|
return;
|
|
330
363
|
}
|
|
331
|
-
if (
|
|
364
|
+
if (onInputRow()) {
|
|
332
365
|
if (key.upArrow) {
|
|
333
366
|
moveFocus(-1);
|
|
334
367
|
return;
|
|
@@ -352,17 +385,28 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
352
385
|
points.splice(at, 1);
|
|
353
386
|
const next = points.join('');
|
|
354
387
|
if (next === '')
|
|
355
|
-
|
|
388
|
+
placeAttached(null);
|
|
356
389
|
applyText(next, at);
|
|
357
390
|
}
|
|
358
391
|
return;
|
|
359
392
|
}
|
|
360
393
|
if (key.leftArrow) {
|
|
394
|
+
// Plain ← at the start of the answer switches questions; anywhere
|
|
395
|
+
// else (and modified arrows) stays a caret step.
|
|
396
|
+
if (isPlainArrow(key) && cursorRef.current === 0 && onBack !== undefined) {
|
|
397
|
+
onBack(currentDraft());
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
361
400
|
applyText(textRef.current, Math.max(0, cursorRef.current - 1));
|
|
362
401
|
return;
|
|
363
402
|
}
|
|
364
403
|
if (key.rightArrow) {
|
|
365
|
-
|
|
404
|
+
const length = [...textRef.current].length;
|
|
405
|
+
if (isPlainArrow(key) && cursorRef.current >= length && onForward !== undefined) {
|
|
406
|
+
onForward(currentDraft());
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
applyText(textRef.current, Math.min(length, cursorRef.current + 1));
|
|
366
410
|
return;
|
|
367
411
|
}
|
|
368
412
|
if (key.home) {
|
|
@@ -393,20 +437,23 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
393
437
|
moveFocus(1);
|
|
394
438
|
return;
|
|
395
439
|
}
|
|
440
|
+
if (key.leftArrow && isPlainArrow(key)) {
|
|
441
|
+
if (onBack !== undefined)
|
|
442
|
+
onBack(currentDraft());
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
if (key.rightArrow && isPlainArrow(key)) {
|
|
446
|
+
if (onForward !== undefined)
|
|
447
|
+
onForward(currentDraft());
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
396
450
|
if (key.tab && !hideCustomInput) {
|
|
397
|
-
|
|
451
|
+
placeFocus(options.length);
|
|
398
452
|
setError(null);
|
|
399
453
|
return;
|
|
400
454
|
}
|
|
401
455
|
if (input === ' ' && multiSelect) {
|
|
402
|
-
|
|
403
|
-
const next = new Set(previous);
|
|
404
|
-
if (next.has(focusIndex))
|
|
405
|
-
next.delete(focusIndex);
|
|
406
|
-
else
|
|
407
|
-
next.add(focusIndex);
|
|
408
|
-
return next;
|
|
409
|
-
});
|
|
456
|
+
toggleCheckedAt(focusRef.current);
|
|
410
457
|
return;
|
|
411
458
|
}
|
|
412
459
|
if (isPlainReturnInput(input, key)) {
|
|
@@ -424,7 +471,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
424
471
|
if (!hideCustomInput && !key.ctrl && !key.meta && !key.super && input) {
|
|
425
472
|
appendText(input);
|
|
426
473
|
if (!multiSelect)
|
|
427
|
-
|
|
474
|
+
placeAttached(options[focusRef.current]?.label ?? null);
|
|
428
475
|
}
|
|
429
476
|
});
|
|
430
477
|
const remaining = total - answered;
|
|
@@ -443,7 +490,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
443
490
|
const focusInputRow = () => {
|
|
444
491
|
if (hideCustomInput)
|
|
445
492
|
return;
|
|
446
|
-
|
|
493
|
+
placeFocus(options.length);
|
|
447
494
|
setError(null);
|
|
448
495
|
};
|
|
449
496
|
/**
|
|
@@ -454,14 +501,7 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
454
501
|
*/
|
|
455
502
|
const clickOption = (index) => {
|
|
456
503
|
if (multiSelect) {
|
|
457
|
-
|
|
458
|
-
const next = new Set(previous);
|
|
459
|
-
if (next.has(index))
|
|
460
|
-
next.delete(index);
|
|
461
|
-
else
|
|
462
|
-
next.add(index);
|
|
463
|
-
return next;
|
|
464
|
-
});
|
|
504
|
+
toggleCheckedAt(index);
|
|
465
505
|
return;
|
|
466
506
|
}
|
|
467
507
|
const label = options[index]?.label;
|
|
@@ -475,9 +515,9 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
475
515
|
const [headerHovered, setHeaderHovered] = React.useState(false);
|
|
476
516
|
/** Mouse submit row hover (multi-select: clicking submits the checked set). */
|
|
477
517
|
const [submitHovered, setSubmitHovered] = React.useState(false);
|
|
478
|
-
const renderInputRow = () => (_jsxs(Box, { flexDirection: "row", marginTop: inputFocused ? 1 : 0, onClick: focusInputRow, onMouseEnter: () => setHoverIndex(options.length), onMouseLeave: () => setHoverIndex(current => (current === options.length ? -1 : current)), backgroundColor: hoverIndex === options.length && !inputFocused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : undefined, bold: inputFocused, children: inputFocused ? POINTER : ' ' }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : 'suggestion', children: PENCIL }) }), _jsxs(Box, { flexDirection: "row", marginLeft: 1, children: [_jsx(Text, { bold: inputFocused, color: inputFocused ? 'accent' : 'suggestion', children: t('question-custom-tab') }), attached !== null && (_jsx(Text, { color: "suggestion", children: t('question-attached-label', { label: attached }) })), _jsx(Text, { dimColor: true, children: "\uFF1A" }), customText === '' && !inputFocused ? (_jsx(Text, { ref: caretRef, dimColor: true, children: t('question-direct-input') })) : (_jsxs(_Fragment, { children: [_jsx(Text, { wrap: "wrap", children: textPoints.slice(0, customCursor).join('') }), inputFocused
|
|
518
|
+
const renderInputRow = () => (_jsxs(Box, { flexDirection: "row", marginTop: inputFocused ? 1 : 0, onClick: focusInputRow, onMouseEnter: () => setHoverIndex(options.length), onMouseLeave: () => setHoverIndex(current => (current === options.length ? -1 : current)), backgroundColor: hoverIndex === options.length && !inputFocused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : undefined, bold: inputFocused, children: inputFocused ? POINTER : ' ' }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : 'suggestion', children: PENCIL }) }), _jsxs(Box, { flexDirection: "row", marginLeft: 1, children: [_jsx(Text, { bold: inputFocused, color: inputFocused ? 'accent' : 'suggestion', children: t('question-custom-tab') }), attached !== null && (_jsx(Text, { color: "suggestion", children: t('question-attached-label', { label: attached }) })), _jsx(Text, { dimColor: true, children: "\uFF1A" }), customText === '' && !inputFocused ? (_jsxs(_Fragment, { children: [_jsx(Text, { ref: caretRef, children: ' ' }), _jsx(Text, { dimColor: true, children: t('question-direct-input') })] })) : (_jsxs(_Fragment, { children: [_jsx(Text, { wrap: "wrap", children: textPoints.slice(0, customCursor).join('') }), inputFocused
|
|
479
519
|
? _jsx(Text, { ref: caretRef, inverse: true, children: cursorChar })
|
|
480
|
-
: _jsx(Text, { ref: caretRef,
|
|
520
|
+
: _jsx(Text, { ref: caretRef, children: "\u258F" }), _jsx(Text, { wrap: "wrap", children: textPoints.slice(inputFocused ? customCursor + 1 : customCursor).join('') })] }))] })] }));
|
|
481
521
|
const renderOptions = () => (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [options.slice(optionWindow.start, optionWindow.end).map((option, index) => {
|
|
482
522
|
const absoluteIndex = optionWindow.start + index;
|
|
483
523
|
const focused = absoluteIndex === focusIndex;
|
|
@@ -498,10 +538,11 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
498
538
|
const hintParts = inputFocused
|
|
499
539
|
? [
|
|
500
540
|
t('question-hint-type'),
|
|
501
|
-
t('question-hint-paste'),
|
|
541
|
+
t('question-hint-paste', { key: comboDisplay(primaryComboString('paste')) }),
|
|
502
542
|
t('question-hint-enter'),
|
|
503
543
|
...(options.length > 0 ? [t('question-hint-back')] : []),
|
|
504
544
|
onBack === undefined ? t('question-hint-esc') : t('question-hint-previous'),
|
|
545
|
+
...(onBack !== undefined || onForward !== undefined ? [t('question-hint-switch-input')] : []),
|
|
505
546
|
...(onBack === undefined ? [] : [t('question-hint-cancel')]),
|
|
506
547
|
...(multiSelect && checked.size > 0 ? [t('question-hint-selected', { n: checked.size })] : []),
|
|
507
548
|
t('question-fold-hint', { combo: foldCombo }),
|
|
@@ -509,9 +550,10 @@ export function AskUserQuestionPanel({ question, position, total, answered, init
|
|
|
509
550
|
: [
|
|
510
551
|
t('question-hint-select'),
|
|
511
552
|
...(multiSelect ? [t('question-hint-multi')] : []),
|
|
512
|
-
...(hideCustomInput ? [] : [t('question-hint-paste'), t('question-hint-attach')]),
|
|
553
|
+
...(hideCustomInput ? [] : [t('question-hint-paste', { key: comboDisplay(primaryComboString('paste')) }), t('question-hint-attach')]),
|
|
513
554
|
t('question-hint-enter'),
|
|
514
555
|
onBack === undefined ? t('question-hint-esc') : t('question-hint-previous'),
|
|
556
|
+
...(onBack !== undefined || onForward !== undefined ? [t('question-hint-switch')] : []),
|
|
515
557
|
...(onBack === undefined ? [] : [t('question-hint-cancel')]),
|
|
516
558
|
...(multiSelect && checked.size > 0 ? [t('question-hint-selected', { n: checked.size })] : []),
|
|
517
559
|
t('question-fold-hint', { combo: foldCombo }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlanReviewPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/PlanReviewPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAIvE,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAa5E,MAAM,MAAM,oBAAoB,GAAG;IACjC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;IAC7B;;;OAGG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;CAC9D,CAAA;AAED,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,qBAAqB,GACtB,EAAE,oBAAoB,GAAG,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"PlanReviewPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/PlanReviewPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAIvE,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAa5E,MAAM,MAAM,oBAAoB,GAAG;IACjC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;IAC7B;;;OAGG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;CAC9D,CAAA;AAED,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,qBAAqB,GACtB,EAAE,oBAAoB,GAAG,KAAK,CAAC,SAAS,CA4ZxC"}
|
|
@@ -33,7 +33,7 @@ import { Divider } from '../design-system/Divider.js';
|
|
|
33
33
|
import { Markdown } from '../Markdown.js';
|
|
34
34
|
import { POINTER } from '../../terminal-utils/figures.js';
|
|
35
35
|
import { isPlainReturnInput } from '../../utils/modifiers.js';
|
|
36
|
-
import { actionMatches } from '../../utils/keymap.js';
|
|
36
|
+
import { actionMatches, comboDisplay, primaryComboString } from '../../utils/keymap.js';
|
|
37
37
|
import { flattenPasteInline } from '../../dsh-adapter/sanitize.js';
|
|
38
38
|
import { readClipboard } from '../../utils/clipboard.js';
|
|
39
39
|
const PENCIL = '✎';
|
|
@@ -345,7 +345,7 @@ export function PlanReviewPanel({ question, onAnswer, onCancel, readClipboardOve
|
|
|
345
345
|
const focused = index === focusIndex;
|
|
346
346
|
const isApprove = option.label === approveLabel;
|
|
347
347
|
return (_jsxs(Box, { flexDirection: "row", marginTop: focused ? 1 : 0, onClick: () => clickOption(index), onMouseEnter: () => setHoverIndex(index), onMouseLeave: () => setHoverIndex(current => (current === index ? -1 : current)), backgroundColor: hoverIndex === index && !focused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: focused ? 'accent' : undefined, bold: focused, children: focused ? POINTER : ' ' }) }), _jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [_jsxs(Text, { bold: focused, color: focused || isApprove ? 'accent' : undefined, wrap: "wrap", children: [index + 1, ". ", option.label] }), option.description !== undefined && (_jsx(Text, { dimColor: true, wrap: "wrap", children: option.description }))] })] }, option.label));
|
|
348
|
-
}), _jsxs(Box, { flexDirection: "row", marginTop: inputFocused ? 1 : 0, onClick: focusFeedbackRow, onMouseEnter: () => setHoverIndex(options.length), onMouseLeave: () => setHoverIndex(current => (current === options.length ? -1 : current)), backgroundColor: hoverIndex === options.length && !inputFocused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : undefined, bold: inputFocused, children: inputFocused ? POINTER : ' ' }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : 'suggestion', children: PENCIL }) }), _jsx(Box, { flexDirection: "row", marginLeft: 1, children: feedback === '' && !inputFocused ? (_jsx(Text, { ref: caretRef, dimColor: true, children: t('plan-review-feedback-placeholder') })) : (_jsxs(_Fragment, { children: [_jsx(Text, { wrap: "wrap", children: feedbackPoints.slice(0, cursor).join('') }), inputFocused
|
|
348
|
+
}), _jsxs(Box, { flexDirection: "row", marginTop: inputFocused ? 1 : 0, onClick: focusFeedbackRow, onMouseEnter: () => setHoverIndex(options.length), onMouseLeave: () => setHoverIndex(current => (current === options.length ? -1 : current)), backgroundColor: hoverIndex === options.length && !inputFocused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : undefined, bold: inputFocused, children: inputFocused ? POINTER : ' ' }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'accent' : 'suggestion', children: PENCIL }) }), _jsx(Box, { flexDirection: "row", marginLeft: 1, children: feedback === '' && !inputFocused ? (_jsxs(_Fragment, { children: [_jsx(Text, { ref: caretRef, children: ' ' }), _jsx(Text, { dimColor: true, children: t('plan-review-feedback-placeholder') })] })) : (_jsxs(_Fragment, { children: [_jsx(Text, { wrap: "wrap", children: feedbackPoints.slice(0, cursor).join('') }), inputFocused
|
|
349
349
|
? _jsx(Text, { ref: caretRef, inverse: true, children: cursorChar })
|
|
350
|
-
: _jsx(Text, { ref: caretRef,
|
|
350
|
+
: _jsx(Text, { ref: caretRef, children: "\u258F" }), _jsx(Text, { wrap: "wrap", children: feedbackPoints.slice(inputFocused ? cursor + 1 : cursor).join('') })] })) })] })] }), error !== null && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "error", children: error }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: t('plan-review-hint', { paste: comboDisplay(primaryComboString('paste')) }) }) })] }));
|
|
351
351
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ClickEvent } from '../../ink/events/click-event.js';
|
|
3
|
+
import type { ForeignSessionRow as ForeignSessionSummary } from '../../adapter/ports/channel-session.js';
|
|
4
|
+
/**
|
|
5
|
+
* One conversation of another agent in a source tab: its title, and a facts
|
|
6
|
+
* line with when it last moved and where it ran.
|
|
7
|
+
*
|
|
8
|
+
* It looks like a DSH session row on purpose — the same two lines, the same
|
|
9
|
+
* `❯`, green selection and blue hover (see SessionListRow) — so the tabs read
|
|
10
|
+
* as one screen. It is its own component rather than a shared core so the DSH
|
|
11
|
+
* row stays untouched; the handful of lines below are the whole overlap.
|
|
12
|
+
*
|
|
13
|
+
* Deliberately NO import status. Selecting a row imports it on the spot (or
|
|
14
|
+
* opens the copy an earlier selection made), so "imported or not" is a detail
|
|
15
|
+
* of the selection, not a fact the user has to read before choosing; showing it
|
|
16
|
+
* would also invite a sync the feature does not do.
|
|
17
|
+
*
|
|
18
|
+
* The working directory rides on the facts line here, unlike the DSH row: the
|
|
19
|
+
* rail groups by directory, but a search spans every group of the source and
|
|
20
|
+
* "which project was this" is the question a foreign title answers worst.
|
|
21
|
+
*/
|
|
22
|
+
export declare function ForeignSessionRow({ session, width, focused, home, now, onClick, }: {
|
|
23
|
+
session: ForeignSessionSummary;
|
|
24
|
+
/** Columns available to the row. */
|
|
25
|
+
width: number;
|
|
26
|
+
focused: boolean;
|
|
27
|
+
/** Home directory, for collapsing the path to `~`. */
|
|
28
|
+
home: string;
|
|
29
|
+
/** Epoch ms used for every relative time in this render pass. */
|
|
30
|
+
now: number;
|
|
31
|
+
/** Mouse click: import and open (same path as Enter). */
|
|
32
|
+
onClick?(event: ClickEvent): void;
|
|
33
|
+
}): React.ReactNode;
|
|
34
|
+
//# sourceMappingURL=ForeignSessionRow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ForeignSessionRow.d.ts","sourceRoot":"","sources":["../../../../src/components/sessions/ForeignSessionRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAEvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAGjE,OAAO,KAAK,EAAE,iBAAiB,IAAI,qBAAqB,EAAE,MAAM,wCAAwC,CAAA;AAExG;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,KAAK,EACL,OAAO,EACP,IAAI,EACJ,GAAG,EACH,OAAO,GACR,EAAE;IACD,OAAO,EAAE,qBAAqB,CAAA;IAC9B,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAA;IACZ,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAA;IACX,yDAAyD;IACzD,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CAClC,GAAG,KAAK,CAAC,SAAS,CAmClB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Box, Text } from '../../ui.js';
|
|
4
|
+
import { useTooltip } from '../Tooltip.js';
|
|
5
|
+
import { formatAbsolute, formatProject, formatWhen, truncateWidth } from '../../sessions/format.js';
|
|
6
|
+
/**
|
|
7
|
+
* One conversation of another agent in a source tab: its title, and a facts
|
|
8
|
+
* line with when it last moved and where it ran.
|
|
9
|
+
*
|
|
10
|
+
* It looks like a DSH session row on purpose — the same two lines, the same
|
|
11
|
+
* `❯`, green selection and blue hover (see SessionListRow) — so the tabs read
|
|
12
|
+
* as one screen. It is its own component rather than a shared core so the DSH
|
|
13
|
+
* row stays untouched; the handful of lines below are the whole overlap.
|
|
14
|
+
*
|
|
15
|
+
* Deliberately NO import status. Selecting a row imports it on the spot (or
|
|
16
|
+
* opens the copy an earlier selection made), so "imported or not" is a detail
|
|
17
|
+
* of the selection, not a fact the user has to read before choosing; showing it
|
|
18
|
+
* would also invite a sync the feature does not do.
|
|
19
|
+
*
|
|
20
|
+
* The working directory rides on the facts line here, unlike the DSH row: the
|
|
21
|
+
* rail groups by directory, but a search spans every group of the source and
|
|
22
|
+
* "which project was this" is the question a foreign title answers worst.
|
|
23
|
+
*/
|
|
24
|
+
export function ForeignSessionRow({ session, width, focused, home, now, onClick, }) {
|
|
25
|
+
const [hovered, setHovered] = useState(false);
|
|
26
|
+
// Two cells for the focus marker.
|
|
27
|
+
const body = Math.max(8, width - 2);
|
|
28
|
+
const shownTitle = truncateWidth(session.title, Math.max(4, body - 2));
|
|
29
|
+
const titleTooltip = useTooltip(() => {
|
|
30
|
+
const parts = [];
|
|
31
|
+
if (shownTitle !== session.title)
|
|
32
|
+
parts.push(session.title);
|
|
33
|
+
parts.push(formatAbsolute(session.updatedAt));
|
|
34
|
+
if (session.cwd !== '')
|
|
35
|
+
parts.push(session.cwd);
|
|
36
|
+
return parts.join('\n');
|
|
37
|
+
});
|
|
38
|
+
const facts = [formatWhen(session.updatedAt, now), formatProject(session.cwd, home)];
|
|
39
|
+
return (_jsxs(Box, { flexDirection: "column", flexShrink: 0, onClick: onClick, onMouseEnter: onClick === undefined ? undefined : () => setHovered(true), onMouseLeave: onClick === undefined ? undefined : () => setHovered(false),
|
|
40
|
+
// Hover is the blue prompt and never marks the focused row; selection is
|
|
41
|
+
// the green foreground below, as on the DSH row.
|
|
42
|
+
backgroundColor: hovered && !focused ? 'userMessageBackgroundHover' : undefined, children: [_jsxs(Box, { children: [_jsx(Text, { color: focused ? 'success' : 'subtle', children: focused ? '❯ ' : ' ' }), _jsx(Box, { ...titleTooltip, children: _jsx(Text, { color: focused ? 'success' : undefined, bold: focused, children: shownTitle }) })] }), _jsx(Text, { color: focused ? 'success' : undefined, dimColor: !focused, children: ` ${truncateWidth(facts.join(' · '), body)}` })] }));
|
|
43
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ClickEvent } from '../../ink/events/click-event.js';
|
|
3
|
+
/** One tab of the session screen's source strip. */
|
|
4
|
+
export interface SourceTab {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly label: string;
|
|
7
|
+
}
|
|
8
|
+
/** Which tabs the strip draws and which fold into the `+N` cell. */
|
|
9
|
+
export interface SourceTabsLayout {
|
|
10
|
+
readonly shown: readonly SourceTab[];
|
|
11
|
+
readonly hidden: readonly SourceTab[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Display width of a strip: its cells, the `│` after the leading DSH tab when
|
|
15
|
+
* anything follows it, and the `+N` cell when tabs are folded.
|
|
16
|
+
* @param shown - Tabs drawn in full; the first is the DSH tab when present.
|
|
17
|
+
* @param hidden - How many tabs fold into `+N`.
|
|
18
|
+
* @param leadId - Id of the tab the separator follows.
|
|
19
|
+
* @returns Terminal cells the strip occupies.
|
|
20
|
+
*/
|
|
21
|
+
export declare function sourceTabsWidth(shown: readonly SourceTab[], hidden: number, leadId: string): number;
|
|
22
|
+
/**
|
|
23
|
+
* Fit the strip into `budget` cells.
|
|
24
|
+
*
|
|
25
|
+
* Tabs fold from the END (the strip is sorted by recency, so the oldest source
|
|
26
|
+
* goes first) into one `+N` cell. The active tab never folds — a strip that
|
|
27
|
+
* hid the tab you are on could not tell you where you are — and the leading
|
|
28
|
+
* tab is the last to go after it.
|
|
29
|
+
* @param tabs - Every tab, leading tab first.
|
|
30
|
+
* @param active - Id of the active tab.
|
|
31
|
+
* @param budget - Cells available to the strip.
|
|
32
|
+
* @returns The tabs to draw and the tabs behind `+N`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function layoutSourceTabs(tabs: readonly SourceTab[], active: string, budget: number): SourceTabsLayout;
|
|
35
|
+
/**
|
|
36
|
+
* The source strip in the session screen's header: `DSH │ Claude Code Codex`.
|
|
37
|
+
*
|
|
38
|
+
* The active tab is a reverse block in the remember colour; the others are dim
|
|
39
|
+
* until the pointer is over them. Every click stops propagation, because the
|
|
40
|
+
* screen's root closes open menus on click and a tab click is not a click on
|
|
41
|
+
* the background.
|
|
42
|
+
*/
|
|
43
|
+
export declare function SourceTabs({ layout, active, leadId, onSelect, onOverflow, }: {
|
|
44
|
+
layout: SourceTabsLayout;
|
|
45
|
+
active: string;
|
|
46
|
+
/** Id of the tab the `│` separator follows. */
|
|
47
|
+
leadId: string;
|
|
48
|
+
onSelect(id: string): void;
|
|
49
|
+
/** Click on `+N`: open the list of folded tabs at the pointer. */
|
|
50
|
+
onOverflow(event: ClickEvent): void;
|
|
51
|
+
}): React.ReactNode;
|
|
52
|
+
//# sourceMappingURL=SourceTabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SourceTabs.d.ts","sourceRoot":"","sources":["../../../../src/components/sessions/SourceTabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAEvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAGjE,oDAAoD;AACpD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,oEAAoE;AACpE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;IACpC,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAA;CACtC;AAKD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKnG;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAW7G;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,MAAM,EACN,MAAM,EACN,QAAQ,EACR,UAAU,GACX,EAAE;IACD,MAAM,EAAE,gBAAgB,CAAA;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,kEAAkE;IAClE,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CACpC,GAAG,KAAK,CAAC,SAAS,CA8BlB"}
|