@deepseek-harness-tui/dsh-tui 0.11.1 → 0.12.0
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 +70 -24
- 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 +93 -6
- package/cordis.patch.yml +63 -22
- package/cordis.yml +3 -2
- package/guide/dsh-tui-guide/SKILL.md +37 -0
- package/guide/dsh-tui-guide/configuration.en.md +410 -0
- package/guide/dsh-tui-guide/configuration.md +349 -0
- package/guide/dsh-tui-guide/getting-started.en.md +398 -0
- package/guide/dsh-tui-guide/getting-started.md +397 -0
- package/guide/dsh-tui-guide/interaction.en.md +674 -0
- package/guide/dsh-tui-guide/interaction.md +747 -0
- package/guide/dsh-tui-guide/migrate.en.md +166 -0
- package/guide/dsh-tui-guide/migrate.md +132 -0
- package/guide/dsh-tui-guide/plugins.en.md +68 -0
- package/guide/dsh-tui-guide/plugins.md +56 -0
- package/guide/dsh-tui-guide/themes.en.md +192 -0
- package/guide/dsh-tui-guide/themes.md +185 -0
- package/guide/dsh-tui-guide/user-guide.en.md +608 -0
- package/guide/dsh-tui-guide/user-guide.md +586 -0
- package/guide/dsh-tui-guide/vscode.en.md +301 -0
- package/guide/dsh-tui-guide/vscode.md +272 -0
- package/lib/settings.json +1272 -0
- package/lib/types/adapter/channel/ui-policy.d.ts +10 -2
- package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
- package/lib/types/adapter/channel/ui-policy.js +17 -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 +14 -1
- package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-ui.d.ts +75 -6
- package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-view.d.ts +86 -9
- 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/Chat/JobCard.d.ts +9 -0
- package/lib/types/components/Chat/JobCard.d.ts.map +1 -1
- package/lib/types/components/Chat/JobCard.js +42 -15
- package/lib/types/components/Chat/SubagentMessage.js +6 -6
- 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/JobsPanel.d.ts.map +1 -1
- package/lib/types/components/JobsPanel.js +80 -33
- 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 +16 -7
- 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/PresetPicker.d.ts +4 -0
- package/lib/types/components/PresetPicker.d.ts.map +1 -1
- package/lib/types/components/PresetPicker.js +5 -1
- 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 +60 -8
- 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 +59 -0
- package/lib/types/components/StarPrompt.d.ts.map +1 -0
- package/lib/types/components/StarPrompt.js +326 -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 +8 -8
- package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
- package/lib/types/components/SubagentDetailScene.js +108 -10
- 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 +35 -0
- package/lib/types/components/WhaleGirl.d.ts.map +1 -0
- package/lib/types/components/WhaleGirl.js +50 -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 +6 -5
- 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/trajectory/MiniWake.d.ts +11 -1
- package/lib/types/components/trajectory/MiniWake.d.ts.map +1 -1
- package/lib/types/components/trajectory/MiniWake.js +9 -3
- 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/external-commands.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/external-commands.js +8 -2
- package/lib/types/dsh-adapter/channel/job-projection.d.ts +1 -0
- package/lib/types/dsh-adapter/channel/job-projection.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/job-projection.js +88 -3
- 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/mode-actions.d.ts +13 -0
- package/lib/types/dsh-adapter/channel/mode-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/mode-actions.js +48 -7
- package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/mode-permission-actions.js +25 -9
- 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 +31 -5
- 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 +17 -2
- 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 +143 -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 +35 -5
- 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 +6 -5
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +14 -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/jobs.d.ts +82 -16
- package/lib/types/dsh-adapter/jobs.d.ts.map +1 -1
- package/lib/types/dsh-adapter/jobs.js +104 -9
- 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/oauth/bonus.d.ts +27 -0
- package/lib/types/dsh-adapter/oauth/bonus.d.ts.map +1 -0
- package/lib/types/dsh-adapter/oauth/bonus.js +69 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/command.d.ts +2 -1
- package/lib/types/dsh-adapter/oauth/command.d.ts.map +1 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/command.js +7 -4
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/credentials.d.ts +13 -10
- package/lib/types/dsh-adapter/oauth/credentials.d.ts.map +1 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/credentials.js +61 -23
- package/lib/types/dsh-adapter/oauth/deepseek.d.ts +39 -0
- package/lib/types/dsh-adapter/oauth/deepseek.d.ts.map +1 -0
- package/lib/types/dsh-adapter/oauth/deepseek.js +189 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/index.d.ts +24 -16
- package/lib/types/dsh-adapter/oauth/index.d.ts.map +1 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/index.js +34 -20
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/interaction.d.ts +14 -12
- package/lib/types/dsh-adapter/oauth/interaction.d.ts.map +1 -0
- package/lib/types/dsh-adapter/oauth/interaction.js +283 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/opener.d.ts +2 -1
- package/lib/types/dsh-adapter/oauth/opener.d.ts.map +1 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/opener.js +1 -1
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/pi-ai.d.ts +10 -3
- package/lib/types/dsh-adapter/oauth/pi-ai.d.ts.map +1 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/pi-ai.js +8 -3
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/profiles.d.ts +6 -3
- package/lib/types/dsh-adapter/oauth/profiles.d.ts.map +1 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/profiles.js +11 -3
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/service.d.ts +14 -7
- package/lib/types/dsh-adapter/oauth/service.d.ts.map +1 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/service.js +82 -17
- package/lib/types/dsh-adapter/plugin.d.ts +12 -3
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +215 -376
- package/lib/types/dsh-adapter/presets.d.ts +6 -4
- package/lib/types/dsh-adapter/presets.d.ts.map +1 -1
- package/lib/types/dsh-adapter/presets.js +6 -4
- 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 +260 -68
- 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 +29 -3
- package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
- package/lib/types/dsh-adapter/subagents.js +87 -3
- 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 +598 -60
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +198 -31
- 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 +15 -2
- 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 +61 -1
- package/lib/types/ink/parse-keypress.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.js +764 -93
- 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 +32 -1
- package/lib/types/ink/terminal-querier.d.ts.map +1 -1
- package/lib/types/ink/terminal-querier.js +54 -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/ink/update-overflow-guard.d.ts +24 -0
- package/lib/types/ink/update-overflow-guard.d.ts.map +1 -1
- package/lib/types/ink/update-overflow-guard.js +25 -3
- 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/minimalUiMode.d.ts +19 -0
- package/lib/types/minimalUiMode.d.ts.map +1 -0
- package/lib/types/minimalUiMode.js +23 -0
- package/lib/types/oauth.d.ts +5 -10
- package/lib/types/oauth.d.ts.map +1 -1
- package/lib/types/oauth.js +5 -10
- 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 +627 -54
- 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 +4 -0
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +57 -27
- 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 +16 -4
- 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/update.js +2 -2
- 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/lib/types/utils/pastedImagePath.d.ts +8 -0
- package/lib/types/utils/pastedImagePath.d.ts.map +1 -1
- package/lib/types/utils/pastedImagePath.js +29 -5
- 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 +127 -102
- package/presets/liangshen/agent.cordis.yml +4 -1
- package/presets/liangshen/preset.yml +1 -1
- package/lib/types/minimalMode.d.ts +0 -13
- package/lib/types/minimalMode.d.ts.map +0 -1
- package/lib/types/minimalMode.js +0 -17
- package/node_modules/@deepseek-harness-tui/dsh-auth/LICENSE +0 -21
- package/node_modules/@deepseek-harness-tui/dsh-auth/README.md +0 -143
- package/node_modules/@deepseek-harness-tui/dsh-auth/cordis.patch.yml +0 -11
- package/node_modules/@deepseek-harness-tui/dsh-auth/dsh-plugin.json +0 -44
- package/node_modules/@deepseek-harness-tui/dsh-auth/lib/interaction.js +0 -193
- package/node_modules/@deepseek-harness-tui/dsh-auth/package.json +0 -69
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex adapter: `~/.codex/sessions/YYYY/MM/DD/rollout-<id>.jsonl`. File
|
|
3
|
+
* discovery lives here; the rollout format is parsed by the pure
|
|
4
|
+
* codex.parse.ts. The browse scan runs the same parser over the rollout's
|
|
5
|
+
* head: the first session_meta, the first real prompt and the sub-agent
|
|
6
|
+
* marker all sit there.
|
|
7
|
+
*
|
|
8
|
+
* @module @deepseek-harness-tui/dsh-tui/migrate/adapters/codex
|
|
9
|
+
*/
|
|
10
|
+
import { readdirSync, readFileSync, statSync } from 'node:fs';
|
|
11
|
+
import { homedir } from 'node:os';
|
|
12
|
+
import { basename, join } from 'node:path';
|
|
13
|
+
import { parseCodexRollout } from './codex.parse.js';
|
|
14
|
+
import { countEntries } from './scan.js';
|
|
15
|
+
import { fingerprintOf, loadText, runScan, walkFiles, withHead } from './scan-fs.js';
|
|
16
|
+
const isRollout = (name) => name.startsWith('rollout-') && name.endsWith('.jsonl');
|
|
17
|
+
const WALK = { maxDepth: 5, match: isRollout };
|
|
18
|
+
/** The rollout's stable source id: the uuid in its file name. */
|
|
19
|
+
function sourceIdOf(path) {
|
|
20
|
+
const match = /rollout-.*-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/u.exec(path);
|
|
21
|
+
// Fallback is the bare file name, never the whole path: the id is the dedupe
|
|
22
|
+
// key, so an absolute path would make it depend on where the store lives.
|
|
23
|
+
return match?.[1] ?? basename(path);
|
|
24
|
+
}
|
|
25
|
+
function readOne(path) {
|
|
26
|
+
let raw;
|
|
27
|
+
try {
|
|
28
|
+
raw = readFileSync(path, 'utf8');
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
return parseCodexRollout({ raw, sourceId: sourceIdOf(path) });
|
|
34
|
+
}
|
|
35
|
+
async function summarize({ ref, fp }) {
|
|
36
|
+
const session = await withHead(ref, fp.size, raw => parseCodexRollout({ raw, sourceId: sourceIdOf(ref) }));
|
|
37
|
+
if (session === undefined)
|
|
38
|
+
return null;
|
|
39
|
+
return {
|
|
40
|
+
agentId: 'codex',
|
|
41
|
+
sessionKey: session.sourceId,
|
|
42
|
+
ref,
|
|
43
|
+
title: session.title ?? '',
|
|
44
|
+
cwd: session.cwd,
|
|
45
|
+
lastMessageAt: fp.mtimeMs,
|
|
46
|
+
createdAt: session.startedAt || fp.mtimeMs,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export const codexAdapter = {
|
|
50
|
+
id: 'codex',
|
|
51
|
+
label: 'Codex',
|
|
52
|
+
roots: () => [join(homedir(), '.codex', 'sessions')],
|
|
53
|
+
discover() {
|
|
54
|
+
const roots = this.roots();
|
|
55
|
+
const sessions = [];
|
|
56
|
+
const walk = (dir, depth) => {
|
|
57
|
+
if (depth > 5)
|
|
58
|
+
return;
|
|
59
|
+
let entries;
|
|
60
|
+
try {
|
|
61
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
for (const entry of entries) {
|
|
67
|
+
const path = join(dir, entry.name);
|
|
68
|
+
if (entry.isDirectory())
|
|
69
|
+
walk(path, depth + 1);
|
|
70
|
+
else if (entry.isFile() && isRollout(entry.name)) {
|
|
71
|
+
try {
|
|
72
|
+
if (statSync(path).size > 64 * 1024 * 1024)
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const session = readOne(path);
|
|
79
|
+
if (session !== undefined)
|
|
80
|
+
sessions.push(session);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
for (const root of roots)
|
|
85
|
+
walk(root, 0);
|
|
86
|
+
return { roots, sessions };
|
|
87
|
+
},
|
|
88
|
+
count() {
|
|
89
|
+
return countEntries(this.roots(), { maxDepth: WALK.maxDepth, fileMatch: WALK.match });
|
|
90
|
+
},
|
|
91
|
+
walk: WALK,
|
|
92
|
+
async scan(options) {
|
|
93
|
+
const files = walkFiles(this.roots(), { ...WALK, signal: options?.signal });
|
|
94
|
+
return runScan(files, file => file.path, fingerprintOf, options, summarize);
|
|
95
|
+
},
|
|
96
|
+
async load(ref) {
|
|
97
|
+
const raw = await loadText(ref);
|
|
98
|
+
if (typeof raw !== 'string')
|
|
99
|
+
return raw;
|
|
100
|
+
return parseCodexRollout({ raw, sourceId: sourceIdOf(ref) }) ?? { skip: 'not-a-session' };
|
|
101
|
+
},
|
|
102
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { MigrationSession } from '../types.js';
|
|
2
|
+
/** What the adapter knows about a rollout besides its text. */
|
|
3
|
+
export interface CodexRolloutInput {
|
|
4
|
+
readonly raw: string;
|
|
5
|
+
/** The rollout's stable source id (the uuid in its file name). */
|
|
6
|
+
readonly sourceId: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Parse one Codex rollout.
|
|
10
|
+
* @returns The session, or undefined when it records no cwd or no prompt, or
|
|
11
|
+
* is a sub-agent thread (`thread_source: 'subagent'` / `source.subagent`):
|
|
12
|
+
* those are spawned by a main session and are not conversations of their
|
|
13
|
+
* own. Forks (`forked_from_id` without the sub-agent marker) are kept.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseCodexRollout(input: CodexRolloutInput): MigrationSession | undefined;
|
|
16
|
+
//# sourceMappingURL=codex.parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.parse.d.ts","sourceRoot":"","sources":["../../../../../src/dsh-adapter/migrate/adapters/codex.parse.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAA4C,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE7F,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AA4ED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,SAAS,CAkKxF"}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex rollout parsing (pure): one `rollout-*.jsonl` → one
|
|
3
|
+
* {@link MigrationSession}.
|
|
4
|
+
*
|
|
5
|
+
* Rows are `{ timestamp, type, payload }` envelopes. `session_meta` and
|
|
6
|
+
* `turn_context` carry metadata (cwd, the model in effect); `response_item`
|
|
7
|
+
* rows are the model-visible history (OpenAI Responses items); `event_msg`
|
|
8
|
+
* rows are UI housekeeping that repeats response items and is skipped.
|
|
9
|
+
*
|
|
10
|
+
* Codex writes its harness context as user-role blocks: `<environment_context>`,
|
|
11
|
+
* `<user_instructions>` and other `<…>` blocks, and the
|
|
12
|
+
* `# AGENTS.md instructions` block that opens most rollouts. Those blocks are
|
|
13
|
+
* dropped; a user message made only of them opens no turn and never titles
|
|
14
|
+
* the session.
|
|
15
|
+
*
|
|
16
|
+
* Tool traffic: `function_call` / `custom_tool_call` items are tool calls of
|
|
17
|
+
* the step in progress; their `*_output` items pair back by `call_id`. A
|
|
18
|
+
* step is one model call: an output ends it, and the next model-produced
|
|
19
|
+
* item opens the next one. `agent_message` items (a sub-agent's report to
|
|
20
|
+
* this thread) are inputs of the next model call.
|
|
21
|
+
*
|
|
22
|
+
* @module @deepseek-harness-tui/dsh-tui/migrate/adapters/codex.parse
|
|
23
|
+
*/
|
|
24
|
+
import { isRecord, parseJsonl } from '../parse/jsonl.js';
|
|
25
|
+
import { isInjectedText, unwrapUserText } from '../parse/injection.js';
|
|
26
|
+
import { emptyStats } from '../parse/role-turns.js';
|
|
27
|
+
import { normalizeTitle } from '../parse/title.js';
|
|
28
|
+
import { CallIndex, IMAGE_PLACEHOLDER, closeToolPairs, newStep } from '../parse/tools.js';
|
|
29
|
+
function toMillis(iso) {
|
|
30
|
+
return typeof iso === 'string' ? Date.parse(iso) || 0 : 0;
|
|
31
|
+
}
|
|
32
|
+
/** Text of the blocks of one kind (`input_text` / `output_text`). */
|
|
33
|
+
function blocksText(content, want) {
|
|
34
|
+
if (!Array.isArray(content))
|
|
35
|
+
return '';
|
|
36
|
+
const parts = [];
|
|
37
|
+
for (const block of content) {
|
|
38
|
+
if (isRecord(block) && block.type === want && typeof block.text === 'string' && block.text !== '')
|
|
39
|
+
parts.push(block.text);
|
|
40
|
+
}
|
|
41
|
+
return parts.join('\n\n');
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Codex-only frames around or beside the human's words: the text blocks that
|
|
45
|
+
* wrap an attached image, the aborted-turn marker, and shell-command echoes.
|
|
46
|
+
* Matched as prefixes like the shared table — a user text that merely starts
|
|
47
|
+
* with `<` (an HTML or XML question) is the human's and must stay.
|
|
48
|
+
*/
|
|
49
|
+
const CODEX_FRAME_PREFIXES = ['<image name=', '</image>', '<turn_aborted>', '<user_shell_command>'];
|
|
50
|
+
function isCodexFrame(text) {
|
|
51
|
+
const head = text.trimStart();
|
|
52
|
+
return CODEX_FRAME_PREFIXES.some(prefix => head.startsWith(prefix));
|
|
53
|
+
}
|
|
54
|
+
/** The human part of a user message: harness blocks dropped, images kept as
|
|
55
|
+
* placeholders. Returns the text and how many blocks were dropped. */
|
|
56
|
+
function userPrompt(content) {
|
|
57
|
+
if (!Array.isArray(content))
|
|
58
|
+
return { text: '', dropped: 0 };
|
|
59
|
+
const parts = [];
|
|
60
|
+
let dropped = 0;
|
|
61
|
+
for (const block of content) {
|
|
62
|
+
if (!isRecord(block))
|
|
63
|
+
continue;
|
|
64
|
+
if (block.type === 'input_image') {
|
|
65
|
+
parts.push(IMAGE_PLACEHOLDER);
|
|
66
|
+
}
|
|
67
|
+
else if (block.type === 'input_text' && typeof block.text === 'string' && block.text.trim() !== '') {
|
|
68
|
+
if (isCodexFrame(block.text) || isInjectedText(block.text))
|
|
69
|
+
dropped += 1;
|
|
70
|
+
else
|
|
71
|
+
parts.push(block.text);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return { text: parts.join('\n\n').trim(), dropped };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Model-facing text of a tool output. Codex writes three shapes: a plain
|
|
78
|
+
* string, a JSON string `{"output": "...", "metadata": …}` (the inner output
|
|
79
|
+
* is what the model saw), and an array of `input_text` / `input_image`
|
|
80
|
+
* blocks (the most common shape in current rollouts).
|
|
81
|
+
*/
|
|
82
|
+
function toolOutputText(output) {
|
|
83
|
+
if (Array.isArray(output)) {
|
|
84
|
+
const parts = [];
|
|
85
|
+
for (const block of output) {
|
|
86
|
+
if (!isRecord(block))
|
|
87
|
+
continue;
|
|
88
|
+
if (block.type === 'input_text' && typeof block.text === 'string')
|
|
89
|
+
parts.push(block.text);
|
|
90
|
+
else if (block.type === 'input_image')
|
|
91
|
+
parts.push(IMAGE_PLACEHOLDER);
|
|
92
|
+
}
|
|
93
|
+
return parts.join('\n');
|
|
94
|
+
}
|
|
95
|
+
if (isRecord(output))
|
|
96
|
+
return typeof output.output === 'string' ? output.output : JSON.stringify(output);
|
|
97
|
+
if (typeof output !== 'string')
|
|
98
|
+
return '';
|
|
99
|
+
if (output.startsWith('{')) {
|
|
100
|
+
try {
|
|
101
|
+
const parsed = JSON.parse(output);
|
|
102
|
+
if (isRecord(parsed) && typeof parsed.output === 'string')
|
|
103
|
+
return parsed.output;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Plain text that happens to start with a brace.
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return output;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Parse one Codex rollout.
|
|
113
|
+
* @returns The session, or undefined when it records no cwd or no prompt, or
|
|
114
|
+
* is a sub-agent thread (`thread_source: 'subagent'` / `source.subagent`):
|
|
115
|
+
* those are spawned by a main session and are not conversations of their
|
|
116
|
+
* own. Forks (`forked_from_id` without the sub-agent marker) are kept.
|
|
117
|
+
*/
|
|
118
|
+
export function parseCodexRollout(input) {
|
|
119
|
+
const { records, badLines } = parseJsonl(input.raw);
|
|
120
|
+
const stats = { ...emptyStats(), badLines };
|
|
121
|
+
let turns = [];
|
|
122
|
+
let current;
|
|
123
|
+
let cwd;
|
|
124
|
+
let startedAt = 0;
|
|
125
|
+
let model;
|
|
126
|
+
const calls = new CallIndex();
|
|
127
|
+
/** The model call in progress; a tool output ends it (see modelStep). */
|
|
128
|
+
let step;
|
|
129
|
+
let sawOutput = false;
|
|
130
|
+
let unnamedCalls = 0;
|
|
131
|
+
let sawMeta = false;
|
|
132
|
+
/** Messages from sub-agents waiting for the next model call. */
|
|
133
|
+
let pendingInputs = [];
|
|
134
|
+
let subagent = false;
|
|
135
|
+
/** A compaction summary waiting for the turn that follows the boundary. */
|
|
136
|
+
let pendingCompaction;
|
|
137
|
+
const openTurn = (prompt) => {
|
|
138
|
+
// Sub-agent messages no model call consumed before a new prompt are stale.
|
|
139
|
+
if (prompt !== '') {
|
|
140
|
+
stats.filtered += pendingInputs.length;
|
|
141
|
+
pendingInputs = [];
|
|
142
|
+
}
|
|
143
|
+
current = pendingCompaction === undefined ? { prompt, steps: [] } : { prompt, compaction: pendingCompaction, steps: [] };
|
|
144
|
+
pendingCompaction = undefined;
|
|
145
|
+
turns.push(current);
|
|
146
|
+
step = undefined;
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* The step a model-produced item belongs to. One model call returns its
|
|
150
|
+
* reasoning, message and tool calls together, then the harness appends the
|
|
151
|
+
* tool outputs; so the first model item AFTER an output starts the next
|
|
152
|
+
* call.
|
|
153
|
+
*/
|
|
154
|
+
const modelStep = () => {
|
|
155
|
+
if (current === undefined)
|
|
156
|
+
openTurn('');
|
|
157
|
+
if (step === undefined || sawOutput) {
|
|
158
|
+
step = newStep(model);
|
|
159
|
+
step.inputs = pendingInputs;
|
|
160
|
+
pendingInputs = [];
|
|
161
|
+
current.steps.push(step);
|
|
162
|
+
sawOutput = false;
|
|
163
|
+
}
|
|
164
|
+
return step;
|
|
165
|
+
};
|
|
166
|
+
const acceptItem = (payload) => {
|
|
167
|
+
switch (payload.type) {
|
|
168
|
+
case 'message': {
|
|
169
|
+
if (payload.role === 'user') {
|
|
170
|
+
const { text: prompt, dropped } = userPrompt(payload.content);
|
|
171
|
+
stats.filtered += dropped;
|
|
172
|
+
if (prompt === '')
|
|
173
|
+
return;
|
|
174
|
+
openTurn(prompt);
|
|
175
|
+
}
|
|
176
|
+
else if (payload.role === 'assistant') {
|
|
177
|
+
const text = blocksText(payload.content, 'output_text');
|
|
178
|
+
if (text !== '')
|
|
179
|
+
modelStep().blocks.push({ type: 'text', text });
|
|
180
|
+
}
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
case 'agent_message': {
|
|
184
|
+
// A sub-agent's report delivered to this thread: model-visible input
|
|
185
|
+
// of the next model call, not a turn of its own.
|
|
186
|
+
const text = blocksText(payload.content, 'input_text');
|
|
187
|
+
if (text === '')
|
|
188
|
+
return;
|
|
189
|
+
pendingInputs.push(text);
|
|
190
|
+
stats.meta += 1;
|
|
191
|
+
sawOutput = true;
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
case 'reasoning': {
|
|
195
|
+
// The readable part is the summary; `encrypted_content` is opaque
|
|
196
|
+
// provider state and is never copied.
|
|
197
|
+
const text = Array.isArray(payload.summary)
|
|
198
|
+
? payload.summary.filter(isRecord).map(part => part.text).filter((part) => typeof part === 'string' && part.trim() !== '').join('\n\n')
|
|
199
|
+
: '';
|
|
200
|
+
if (text !== '')
|
|
201
|
+
modelStep().blocks.push({ type: 'reasoning', text });
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
case 'function_call':
|
|
205
|
+
case 'custom_tool_call': {
|
|
206
|
+
const id = typeof payload.call_id === 'string' && payload.call_id !== '' ? payload.call_id : `codex-call-${++unnamedCalls}`;
|
|
207
|
+
const name = typeof payload.name === 'string' && payload.name !== '' ? payload.name : 'unknown';
|
|
208
|
+
// function_call arguments are the model's JSON text; a custom tool's
|
|
209
|
+
// input is free-form (a patch, a JS snippet), kept as one JSON field.
|
|
210
|
+
const args = payload.type === 'function_call'
|
|
211
|
+
? (typeof payload.arguments === 'string' ? payload.arguments : JSON.stringify(payload.arguments ?? {}))
|
|
212
|
+
: JSON.stringify({ input: payload.input ?? '' });
|
|
213
|
+
const target = modelStep();
|
|
214
|
+
target.blocks.push({ type: 'tool-call', id, name, arguments: args });
|
|
215
|
+
calls.register(target);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
case 'function_call_output':
|
|
219
|
+
case 'custom_tool_call_output': {
|
|
220
|
+
if (typeof payload.call_id === 'string')
|
|
221
|
+
calls.attach(payload.call_id, toolOutputText(payload.output), false);
|
|
222
|
+
else
|
|
223
|
+
calls.orphans += 1;
|
|
224
|
+
sawOutput = true;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
for (const record of records) {
|
|
229
|
+
const payload = record.payload;
|
|
230
|
+
if (!isRecord(payload))
|
|
231
|
+
continue;
|
|
232
|
+
const time = toMillis(record.timestamp);
|
|
233
|
+
if (record.type === 'session_meta') {
|
|
234
|
+
// Only the FIRST meta describes this rollout: a forked or spawned
|
|
235
|
+
// thread repeats its parent's meta after its own, with the inherited
|
|
236
|
+
// history.
|
|
237
|
+
if (!sawMeta) {
|
|
238
|
+
sawMeta = true;
|
|
239
|
+
if (typeof payload.cwd === 'string' && payload.cwd !== '')
|
|
240
|
+
cwd = payload.cwd;
|
|
241
|
+
startedAt ||= toMillis(payload.timestamp) || time;
|
|
242
|
+
subagent = payload.thread_source === 'subagent' || (isRecord(payload.source) && payload.source.subagent !== undefined);
|
|
243
|
+
}
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
// Codex records the active model per turn; it applies to the steps after it.
|
|
247
|
+
// Compaction boundary: Codex folded the window before it into a handoff
|
|
248
|
+
// summary and kept writing the same rollout. The summary becomes a
|
|
249
|
+
// native checkpoint in front of the next turn; a turn cut in half by the
|
|
250
|
+
// boundary continues as a prompt-less turn after it.
|
|
251
|
+
if (record.type === 'compacted') {
|
|
252
|
+
const summary = typeof payload.message === 'string' ? payload.message.trim() : '';
|
|
253
|
+
if (summary !== '') {
|
|
254
|
+
pendingCompaction = model === undefined ? { summary } : { summary, model };
|
|
255
|
+
current = undefined;
|
|
256
|
+
step = undefined;
|
|
257
|
+
}
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
// The only event_msg that carries meaning the response items lack: the
|
|
261
|
+
// turn was interrupted (the recorded reason is always a coarse
|
|
262
|
+
// 'interrupted').
|
|
263
|
+
if (record.type === 'event_msg' && payload.type === 'turn_aborted') {
|
|
264
|
+
if (current !== undefined)
|
|
265
|
+
current.aborted = true;
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
if (record.type === 'turn_context') {
|
|
269
|
+
if (typeof payload.model === 'string' && payload.model !== '')
|
|
270
|
+
model = payload.model;
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
if (record.type !== 'response_item')
|
|
274
|
+
continue;
|
|
275
|
+
startedAt ||= time;
|
|
276
|
+
acceptItem(payload);
|
|
277
|
+
}
|
|
278
|
+
stats.filtered += pendingInputs.length;
|
|
279
|
+
if (pendingCompaction !== undefined)
|
|
280
|
+
turns.push({ prompt: '', compaction: pendingCompaction, steps: [] });
|
|
281
|
+
turns = turns.filter(turn => turn.prompt !== '' || turn.steps.length > 0 || turn.compaction !== undefined);
|
|
282
|
+
stats.droppedToolResults = calls.orphans + closeToolPairs(turns);
|
|
283
|
+
if (subagent || cwd === undefined || !turns.some(turn => turn.prompt !== ''))
|
|
284
|
+
return undefined;
|
|
285
|
+
// Codex keeps no title of its own: the first real prompt is the fallback.
|
|
286
|
+
const firstPrompt = turns.find(turn => turn.prompt !== '')?.prompt;
|
|
287
|
+
const title = normalizeTitle(firstPrompt === undefined ? undefined : unwrapUserText(firstPrompt));
|
|
288
|
+
return { sourceId: input.sourceId, cwd, ...(title === '' ? {} : { title }), titleExplicit: false, startedAt, turns, stats };
|
|
289
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grok-build.d.ts","sourceRoot":"","sources":["../../../../../src/dsh-adapter/migrate/adapters/grok-build.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAgD,gBAAgB,EAA+D,MAAM,aAAa,CAAA;AA+C9J,eAAO,MAAM,gBAAgB,EAAE,gBAkD9B,CAAA"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* grok-build adapter: `~/.grok/sessions/<encoded-cwd>/<uuid>/` — each session
|
|
3
|
+
* directory holds a `summary.json` and a `chat_history.jsonl`. Discovery and
|
|
4
|
+
* the `GROK_HOME` override live here; both files are parsed by the pure
|
|
5
|
+
* grok-build.parse.ts. A session directory is one browse entry: its
|
|
6
|
+
* fingerprint combines both files, and its summary comes from the whole
|
|
7
|
+
* summary.json plus the head of the history.
|
|
8
|
+
*
|
|
9
|
+
* @module @deepseek-harness-tui/dsh-tui/migrate/adapters/grok-build
|
|
10
|
+
*/
|
|
11
|
+
import { readdirSync, readFileSync, statSync } from 'node:fs';
|
|
12
|
+
import { homedir } from 'node:os';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { parseGrokSession } from './grok-build.parse.js';
|
|
15
|
+
import { countEntries } from './scan.js';
|
|
16
|
+
import { fingerprintOf, loadText, runScan, walkFiles, withHead } from './scan-fs.js';
|
|
17
|
+
const HISTORY_FILE = 'chat_history.jsonl';
|
|
18
|
+
const SUMMARY_FILE = 'summary.json';
|
|
19
|
+
const WALK = { maxDepth: 2, match: name => name === HISTORY_FILE };
|
|
20
|
+
/** One change token for both files of a session directory. */
|
|
21
|
+
async function directoryFingerprint(dir) {
|
|
22
|
+
const history = await fingerprintOf(join(dir, HISTORY_FILE));
|
|
23
|
+
const summary = await fingerprintOf(join(dir, SUMMARY_FILE));
|
|
24
|
+
if (history === undefined || summary === undefined)
|
|
25
|
+
return undefined;
|
|
26
|
+
return { mtimeMs: Math.max(history.mtimeMs, summary.mtimeMs), size: history.size + summary.size };
|
|
27
|
+
}
|
|
28
|
+
async function summarize({ ref, fp }) {
|
|
29
|
+
const summaryJson = await loadText(join(ref, SUMMARY_FILE));
|
|
30
|
+
const history = await fingerprintOf(join(ref, HISTORY_FILE));
|
|
31
|
+
if (typeof summaryJson !== 'string' || history === undefined)
|
|
32
|
+
return null;
|
|
33
|
+
const session = await withHead(join(ref, HISTORY_FILE), history.size, chatHistory => parseGrokSession({ summaryJson, chatHistory }));
|
|
34
|
+
if (session === undefined)
|
|
35
|
+
return null;
|
|
36
|
+
return {
|
|
37
|
+
agentId: 'grok-build',
|
|
38
|
+
sessionKey: session.sourceId,
|
|
39
|
+
ref,
|
|
40
|
+
title: session.title ?? '',
|
|
41
|
+
cwd: session.cwd,
|
|
42
|
+
lastMessageAt: fp.mtimeMs,
|
|
43
|
+
createdAt: session.startedAt || fp.mtimeMs,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function readOne(dir) {
|
|
47
|
+
let summaryJson;
|
|
48
|
+
let chatHistory;
|
|
49
|
+
try {
|
|
50
|
+
summaryJson = readFileSync(join(dir, 'summary.json'), 'utf8');
|
|
51
|
+
chatHistory = readFileSync(join(dir, 'chat_history.jsonl'), 'utf8');
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
return parseGrokSession({ summaryJson, chatHistory });
|
|
57
|
+
}
|
|
58
|
+
export const grokBuildAdapter = {
|
|
59
|
+
id: 'grok-build',
|
|
60
|
+
label: 'Grok Build',
|
|
61
|
+
roots() {
|
|
62
|
+
const grokHome = process.env.GROK_HOME?.trim();
|
|
63
|
+
return [join(grokHome !== undefined && grokHome !== '' ? grokHome : join(homedir(), '.grok'), 'sessions')];
|
|
64
|
+
},
|
|
65
|
+
discover() {
|
|
66
|
+
const roots = this.roots();
|
|
67
|
+
const sessions = [];
|
|
68
|
+
const walk = (dir, depth) => {
|
|
69
|
+
if (depth > 2)
|
|
70
|
+
return;
|
|
71
|
+
let entries;
|
|
72
|
+
try {
|
|
73
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
for (const entry of entries) {
|
|
79
|
+
const path = join(dir, entry.name);
|
|
80
|
+
if (entry.isDirectory())
|
|
81
|
+
walk(path, depth + 1);
|
|
82
|
+
else if (entry.isFile() && entry.name === 'chat_history.jsonl') {
|
|
83
|
+
try {
|
|
84
|
+
if (statSync(path).size > 64 * 1024 * 1024)
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const session = readOne(dir);
|
|
91
|
+
if (session !== undefined)
|
|
92
|
+
sessions.push(session);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
for (const root of roots)
|
|
97
|
+
walk(root, 0);
|
|
98
|
+
return { roots, sessions };
|
|
99
|
+
},
|
|
100
|
+
count() {
|
|
101
|
+
return countEntries(this.roots(), { maxDepth: WALK.maxDepth, fileMatch: WALK.match });
|
|
102
|
+
},
|
|
103
|
+
walk: WALK,
|
|
104
|
+
async scan(options) {
|
|
105
|
+
const files = walkFiles(this.roots(), { ...WALK, signal: options?.signal });
|
|
106
|
+
return runScan(files, file => file.dir, directoryFingerprint, options, summarize);
|
|
107
|
+
},
|
|
108
|
+
async load(ref) {
|
|
109
|
+
const summaryJson = await loadText(join(ref, SUMMARY_FILE));
|
|
110
|
+
if (typeof summaryJson !== 'string')
|
|
111
|
+
return summaryJson;
|
|
112
|
+
const chatHistory = await loadText(join(ref, HISTORY_FILE));
|
|
113
|
+
if (typeof chatHistory !== 'string')
|
|
114
|
+
return chatHistory;
|
|
115
|
+
return parseGrokSession({ summaryJson, chatHistory }) ?? { skip: 'not-a-session' };
|
|
116
|
+
},
|
|
117
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { MigrationSession } from '../types.js';
|
|
2
|
+
/** One session directory's two files, as text. */
|
|
3
|
+
export interface GrokSessionInput {
|
|
4
|
+
readonly summaryJson: string;
|
|
5
|
+
readonly chatHistory: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Parse one Grok Build session.
|
|
9
|
+
* @returns The session, or undefined when the summary lacks an id or cwd,
|
|
10
|
+
* or the history holds no prompt.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseGrokSession(input: GrokSessionInput): MigrationSession | undefined;
|
|
13
|
+
//# sourceMappingURL=grok-build.parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grok-build.parse.d.ts","sourceRoot":"","sources":["../../../../../src/dsh-adapter/migrate/adapters/grok-build.parse.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAgC,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAMjF,kDAAkD;AAClD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AA2BD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,SAAS,CAwGtF"}
|