@umsai/ums-code 0.3.0-v2 → 0.6.0-v1
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/dist/package.json +6 -6
- package/dist/src/{zed-integration → acp-integration}/acp.d.ts +13 -0
- package/dist/src/{zed-integration → acp-integration}/acp.js +32 -0
- package/dist/src/acp-integration/acp.js.map +1 -0
- package/dist/src/acp-integration/acpAgent.d.ts +10 -0
- package/dist/src/acp-integration/acpAgent.js +264 -0
- package/dist/src/acp-integration/acpAgent.js.map +1 -0
- package/dist/src/{zed-integration → acp-integration}/schema.d.ts +2235 -905
- package/dist/src/{zed-integration → acp-integration}/schema.js +100 -2
- package/dist/src/acp-integration/schema.js.map +1 -0
- package/dist/src/{zed-integration/fileSystemService.d.ts → acp-integration/service/filesystem.d.ts} +1 -1
- package/dist/src/{zed-integration/fileSystemService.js → acp-integration/service/filesystem.js} +14 -1
- package/dist/src/acp-integration/service/filesystem.js.map +1 -0
- package/dist/src/{ui/hooks/useQuotaAndFallback.test.d.ts → acp-integration/service/filesystem.test.d.ts} +1 -1
- package/dist/src/acp-integration/service/filesystem.test.js +39 -0
- package/dist/src/acp-integration/service/filesystem.test.js.map +1 -0
- package/dist/src/acp-integration/session/HistoryReplayer.d.ts +51 -0
- package/dist/src/acp-integration/session/HistoryReplayer.js +164 -0
- package/dist/src/acp-integration/session/HistoryReplayer.js.map +1 -0
- package/dist/src/acp-integration/session/HistoryReplayer.test.d.ts +6 -0
- package/dist/src/acp-integration/session/HistoryReplayer.test.js +374 -0
- package/dist/src/acp-integration/session/HistoryReplayer.test.js.map +1 -0
- package/dist/src/acp-integration/session/Session.d.ts +61 -0
- package/dist/src/acp-integration/session/Session.js +839 -0
- package/dist/src/acp-integration/session/Session.js.map +1 -0
- package/dist/src/acp-integration/session/SubAgentTracker.d.ts +51 -0
- package/dist/src/acp-integration/session/SubAgentTracker.js +257 -0
- package/dist/src/acp-integration/session/SubAgentTracker.js.map +1 -0
- package/dist/src/acp-integration/session/SubAgentTracker.test.d.ts +6 -0
- package/dist/src/acp-integration/session/SubAgentTracker.test.js +369 -0
- package/dist/src/acp-integration/session/SubAgentTracker.test.js.map +1 -0
- package/dist/src/acp-integration/session/emitters/BaseEmitter.d.ts +27 -0
- package/dist/src/acp-integration/session/emitters/BaseEmitter.js +34 -0
- package/dist/src/acp-integration/session/emitters/BaseEmitter.js.map +1 -0
- package/dist/src/acp-integration/session/emitters/MessageEmitter.d.ts +41 -0
- package/dist/src/acp-integration/session/emitters/MessageEmitter.js +77 -0
- package/dist/src/acp-integration/session/emitters/MessageEmitter.js.map +1 -0
- package/dist/src/acp-integration/session/emitters/MessageEmitter.test.d.ts +6 -0
- package/dist/src/acp-integration/session/emitters/MessageEmitter.test.js +174 -0
- package/dist/src/acp-integration/session/emitters/MessageEmitter.test.js.map +1 -0
- package/dist/src/acp-integration/session/emitters/PlanEmitter.d.ts +39 -0
- package/dist/src/acp-integration/session/emitters/PlanEmitter.js +83 -0
- package/dist/src/acp-integration/session/emitters/PlanEmitter.js.map +1 -0
- package/dist/src/acp-integration/session/emitters/PlanEmitter.test.d.ts +6 -0
- package/dist/src/acp-integration/session/emitters/PlanEmitter.test.js +176 -0
- package/dist/src/acp-integration/session/emitters/PlanEmitter.test.js.map +1 -0
- package/dist/src/acp-integration/session/emitters/ToolCallEmitter.d.ts +80 -0
- package/dist/src/acp-integration/session/emitters/ToolCallEmitter.js +248 -0
- package/dist/src/acp-integration/session/emitters/ToolCallEmitter.js.map +1 -0
- package/dist/src/acp-integration/session/emitters/ToolCallEmitter.test.d.ts +6 -0
- package/dist/src/acp-integration/session/emitters/ToolCallEmitter.test.js +561 -0
- package/dist/src/acp-integration/session/emitters/ToolCallEmitter.test.js.map +1 -0
- package/dist/src/acp-integration/session/emitters/index.d.ts +9 -0
- package/dist/src/acp-integration/session/emitters/index.js +10 -0
- package/dist/src/acp-integration/session/emitters/index.js.map +1 -0
- package/dist/src/acp-integration/session/index.d.ts +24 -0
- package/dist/src/acp-integration/session/index.js +16 -0
- package/dist/src/acp-integration/session/index.js.map +1 -0
- package/dist/src/acp-integration/session/types.d.ts +71 -0
- package/dist/src/acp-integration/session/types.js +7 -0
- package/dist/src/acp-integration/session/types.js.map +1 -0
- package/dist/src/commandMode.d.ts +11 -0
- package/dist/src/commandMode.js +238 -0
- package/dist/src/commandMode.js.map +1 -0
- package/dist/src/config/auth.d.ts +1 -0
- package/dist/src/config/auth.js +29 -0
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/config.d.ts +19 -3
- package/dist/src/config/config.js +175 -24
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/extension.js +0 -2
- package/dist/src/config/extension.js.map +1 -1
- package/dist/src/config/extensions/update.test.js +9 -0
- package/dist/src/config/extensions/update.test.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +53 -2
- package/dist/src/config/settingsSchema.js +46 -2
- package/dist/src/config/settingsSchema.js.map +1 -1
- package/dist/src/core/auth.d.ts +1 -1
- package/dist/src/core/auth.js +3 -2
- package/dist/src/core/auth.js.map +1 -1
- package/dist/src/core/initializer.js +3 -0
- package/dist/src/core/initializer.js.map +1 -1
- package/dist/src/gemini.js +75 -35
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +37 -4
- package/dist/src/gemini.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +3 -3
- package/dist/src/generated/git-commit.js +3 -3
- package/dist/src/i18n/index.d.ts +10 -2
- package/dist/src/i18n/index.js +26 -1
- package/dist/src/i18n/index.js.map +1 -1
- package/dist/src/i18n/languages.d.ts +20 -0
- package/dist/src/i18n/languages.js +36 -0
- package/dist/src/i18n/languages.js.map +1 -0
- package/dist/src/i18n/locales/de.js +1073 -0
- package/dist/src/i18n/locales/en.js +121 -175
- package/dist/src/i18n/locales/ru.js +1095 -0
- package/dist/src/i18n/locales/zh.js +52 -174
- package/dist/src/nonInteractive/control/ControlDispatcher.d.ts +24 -1
- package/dist/src/nonInteractive/control/ControlDispatcher.js +46 -17
- package/dist/src/nonInteractive/control/ControlDispatcher.js.map +1 -1
- package/dist/src/nonInteractive/control/ControlService.d.ts +2 -1
- package/dist/src/nonInteractive/control/ControlService.js +22 -37
- package/dist/src/nonInteractive/control/ControlService.js.map +1 -1
- package/dist/src/nonInteractive/control/controllers/baseController.d.ts +2 -1
- package/dist/src/nonInteractive/control/controllers/baseController.js +38 -5
- package/dist/src/nonInteractive/control/controllers/baseController.js.map +1 -1
- package/dist/src/nonInteractive/control/controllers/permissionController.d.ts +1 -22
- package/dist/src/nonInteractive/control/controllers/permissionController.js +38 -38
- package/dist/src/nonInteractive/control/controllers/permissionController.js.map +1 -1
- package/dist/src/nonInteractive/control/controllers/sdkMcpController.d.ts +54 -0
- package/dist/src/nonInteractive/control/controllers/sdkMcpController.js +84 -0
- package/dist/src/nonInteractive/control/controllers/sdkMcpController.js.map +1 -0
- package/dist/src/nonInteractive/control/controllers/systemController.d.ts +16 -6
- package/dist/src/nonInteractive/control/controllers/systemController.js +184 -44
- package/dist/src/nonInteractive/control/controllers/systemController.js.map +1 -1
- package/dist/src/nonInteractive/control/types/serviceAPIs.d.ts +1 -16
- package/dist/src/nonInteractive/io/BaseJsonOutputAdapter.d.ts +11 -0
- package/dist/src/nonInteractive/io/BaseJsonOutputAdapter.js +64 -5
- package/dist/src/nonInteractive/io/BaseJsonOutputAdapter.js.map +1 -1
- package/dist/src/nonInteractive/io/BaseJsonOutputAdapter.test.js +40 -0
- package/dist/src/nonInteractive/io/BaseJsonOutputAdapter.test.js.map +1 -1
- package/dist/src/nonInteractive/io/StreamJsonOutputAdapter.test.js +50 -0
- package/dist/src/nonInteractive/io/StreamJsonOutputAdapter.test.js.map +1 -1
- package/dist/src/nonInteractive/session.d.ts +0 -16
- package/dist/src/nonInteractive/session.js +317 -321
- package/dist/src/nonInteractive/session.js.map +1 -1
- package/dist/src/nonInteractive/session.test.js +6 -0
- package/dist/src/nonInteractive/session.test.js.map +1 -1
- package/dist/src/nonInteractive/types.d.ts +57 -3
- package/dist/src/nonInteractive/types.js +0 -1
- package/dist/src/nonInteractive/types.js.map +1 -1
- package/dist/src/nonInteractiveCli.js +121 -56
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/nonInteractiveCliCommands.d.ts +48 -9
- package/dist/src/nonInteractiveCliCommands.js +180 -64
- package/dist/src/nonInteractiveCliCommands.js.map +1 -1
- package/dist/src/nonInteractiveCliCommands.test.d.ts +6 -0
- package/dist/src/nonInteractiveCliCommands.test.js +157 -0
- package/dist/src/nonInteractiveCliCommands.test.js.map +1 -0
- package/dist/src/services/BuiltinCommandLoader.js +7 -6
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.test.js +0 -3
- package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -1
- package/dist/src/services/McpPromptLoader.js +4 -2
- package/dist/src/services/McpPromptLoader.js.map +1 -1
- package/dist/src/services/McpPromptLoader.test.js +1 -1
- package/dist/src/services/McpPromptLoader.test.js.map +1 -1
- package/dist/src/test-utils/mockCommandContext.js +11 -2
- package/dist/src/test-utils/mockCommandContext.js.map +1 -1
- package/dist/src/ui/AppContainer.js +62 -56
- package/dist/src/ui/AppContainer.js.map +1 -1
- package/dist/src/ui/AppContainer.test.js +0 -46
- package/dist/src/ui/AppContainer.test.js.map +1 -1
- package/dist/src/ui/auth/AuthDialog.test.js +4 -4
- package/dist/src/ui/auth/AuthDialog.test.js.map +1 -1
- package/dist/src/ui/auth/useAuth.js +31 -4
- package/dist/src/ui/auth/useAuth.js.map +1 -1
- package/dist/src/ui/commands/approvalModeCommand.js +53 -4
- package/dist/src/ui/commands/approvalModeCommand.js.map +1 -1
- package/dist/src/ui/commands/approvalModeCommand.test.js +72 -10
- package/dist/src/ui/commands/approvalModeCommand.test.js.map +1 -1
- package/dist/src/ui/commands/clearCommand.js +22 -10
- package/dist/src/ui/commands/clearCommand.js.map +1 -1
- package/dist/src/ui/commands/compressCommand.js +86 -16
- package/dist/src/ui/commands/compressCommand.js.map +1 -1
- package/dist/src/ui/commands/languageCommand.d.ts +6 -1
- package/dist/src/ui/commands/languageCommand.js +162 -183
- package/dist/src/ui/commands/languageCommand.js.map +1 -1
- package/dist/src/ui/commands/languageCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/languageCommand.test.js +558 -0
- package/dist/src/ui/commands/languageCommand.test.js.map +1 -0
- package/dist/src/ui/commands/modelCommand.js +4 -2
- package/dist/src/ui/commands/modelCommand.js.map +1 -1
- package/dist/src/ui/commands/quitCommand.d.ts +0 -1
- package/dist/src/ui/commands/quitCommand.js +0 -27
- package/dist/src/ui/commands/quitCommand.js.map +1 -1
- package/dist/src/ui/commands/restoreCommand.js +1 -1
- package/dist/src/ui/commands/restoreCommand.js.map +1 -1
- package/dist/src/ui/commands/resumeCommand.d.ts +7 -0
- package/dist/src/ui/commands/resumeCommand.js +19 -0
- package/dist/src/ui/commands/resumeCommand.js.map +1 -0
- package/dist/src/ui/commands/resumeCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/resumeCommand.test.js +32 -0
- package/dist/src/ui/commands/resumeCommand.test.js.map +1 -0
- package/dist/src/ui/commands/reviewCommand.d.ts +9 -0
- package/dist/src/ui/commands/reviewCommand.js +2046 -0
- package/dist/src/ui/commands/reviewCommand.js.map +1 -0
- package/dist/src/ui/commands/reviewCommand.test.js +600 -0
- package/dist/src/ui/commands/reviewCommand.test.js.map +1 -0
- package/dist/src/ui/commands/setupGithubCommand.js +11 -10
- package/dist/src/ui/commands/setupGithubCommand.js.map +1 -1
- package/dist/src/ui/commands/setupGithubCommand.test.js +14 -14
- package/dist/src/ui/commands/setupGithubCommand.test.js.map +1 -1
- package/dist/src/ui/commands/summaryCommand.js +129 -42
- package/dist/src/ui/commands/summaryCommand.js.map +1 -1
- package/dist/src/ui/commands/types.d.ts +24 -10
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/commands/ums/unittestCommand.d.ts +9 -0
- package/dist/src/ui/commands/ums/unittestCommand.js +387 -0
- package/dist/src/ui/commands/ums/unittestCommand.js.map +1 -0
- package/dist/src/ui/components/Composer.test.js +1 -2
- package/dist/src/ui/components/Composer.test.js.map +1 -1
- package/dist/src/ui/components/ContextUsageDisplay.d.ts +3 -2
- package/dist/src/ui/components/ContextUsageDisplay.js +8 -2
- package/dist/src/ui/components/ContextUsageDisplay.js.map +1 -1
- package/dist/src/ui/components/DialogManager.js +7 -23
- package/dist/src/ui/components/DialogManager.js.map +1 -1
- package/dist/src/ui/components/Footer.js +2 -3
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/Help.js +13 -2
- package/dist/src/ui/components/Help.js.map +1 -1
- package/dist/src/ui/components/Help.test.js +6 -0
- package/dist/src/ui/components/Help.test.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.js +3 -1
- package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.test.js +5 -2
- package/dist/src/ui/components/HistoryItemDisplay.test.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.js +6 -4
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/ModelDialog.d.ts +3 -1
- package/dist/src/ui/components/ModelDialog.js +25 -5
- package/dist/src/ui/components/ModelDialog.js.map +1 -1
- package/dist/src/ui/components/OpenAIKeyPrompt.d.ts +3 -0
- package/dist/src/ui/components/OpenAIKeyPrompt.js +1 -0
- package/dist/src/ui/components/OpenAIKeyPrompt.js.map +1 -1
- package/dist/src/ui/components/PermissionsModifyTrustDialog.js +1 -1
- package/dist/src/ui/components/PermissionsModifyTrustDialog.js.map +1 -1
- package/dist/src/ui/components/SessionPicker.d.ts +18 -0
- package/dist/src/ui/components/SessionPicker.js +69 -0
- package/dist/src/ui/components/SessionPicker.js.map +1 -0
- package/dist/src/ui/components/SessionSummaryDisplay.js +14 -2
- package/dist/src/ui/components/SessionSummaryDisplay.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.test.js +2 -2
- package/dist/src/ui/components/StandaloneSessionPicker.d.ts +10 -0
- package/dist/src/ui/components/StandaloneSessionPicker.js +78 -0
- package/dist/src/ui/components/StandaloneSessionPicker.js.map +1 -0
- package/dist/src/ui/components/StandaloneSessionPicker.test.d.ts +6 -0
- package/dist/src/ui/components/StandaloneSessionPicker.test.js +410 -0
- package/dist/src/ui/components/StandaloneSessionPicker.test.js.map +1 -0
- package/dist/src/ui/components/SuggestionsDisplay.js +3 -2
- package/dist/src/ui/components/SuggestionsDisplay.js.map +1 -1
- package/dist/src/ui/components/messages/GeminiThoughtMessage.d.ts +18 -0
- package/dist/src/ui/components/messages/GeminiThoughtMessage.js +14 -0
- package/dist/src/ui/components/messages/GeminiThoughtMessage.js.map +1 -0
- package/dist/src/ui/components/messages/GeminiThoughtMessageContent.d.ts +18 -0
- package/dist/src/ui/components/messages/GeminiThoughtMessageContent.js +14 -0
- package/dist/src/ui/components/messages/GeminiThoughtMessageContent.js.map +1 -0
- package/dist/src/ui/components/subagents/manage/AgentEditStep.js +4 -1
- package/dist/src/ui/components/subagents/manage/AgentEditStep.js.map +1 -1
- package/dist/src/ui/components/subagents/manage/AgentSelectionStep.js +2 -2
- package/dist/src/ui/components/subagents/manage/AgentSelectionStep.js.map +1 -1
- package/dist/src/ui/components/ums/UMSKeyPrompt.d.ts +1 -1
- package/dist/src/ui/components/ums/UMSKeyPrompt.js +24 -4
- package/dist/src/ui/components/ums/UMSKeyPrompt.js.map +1 -1
- package/dist/src/ui/components/ums/umsStartupWarnings.d.ts +6 -0
- package/dist/src/ui/components/ums/umsStartupWarnings.js +47 -0
- package/dist/src/ui/components/ums/umsStartupWarnings.js.map +1 -0
- package/dist/src/ui/contexts/SessionContext.d.ts +2 -0
- package/dist/src/ui/contexts/SessionContext.js +18 -10
- package/dist/src/ui/contexts/SessionContext.js.map +1 -1
- package/dist/src/ui/contexts/UIActionsContext.d.ts +3 -1
- package/dist/src/ui/contexts/UIActionsContext.js.map +1 -1
- package/dist/src/ui/contexts/UIStateContext.d.ts +3 -11
- package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.d.ts +3 -8
- package/dist/src/ui/hooks/slashCommandProcessor.js +77 -101
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAttentionNotifications.d.ts +3 -1
- package/dist/src/ui/hooks/useAttentionNotifications.js +10 -5
- package/dist/src/ui/hooks/useAttentionNotifications.js.map +1 -1
- package/dist/src/ui/hooks/useAttentionNotifications.test.js +39 -2
- package/dist/src/ui/hooks/useAttentionNotifications.test.js.map +1 -1
- package/dist/src/ui/hooks/useDialogClose.d.ts +0 -3
- package/dist/src/ui/hooks/useDialogClose.js +0 -2
- package/dist/src/ui/hooks/useDialogClose.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +87 -12
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useLoadingIndicator.test.js +11 -6
- package/dist/src/ui/hooks/useLoadingIndicator.test.js.map +1 -1
- package/dist/src/ui/hooks/useLogger.d.ts +1 -1
- package/dist/src/ui/hooks/useLogger.js +6 -3
- package/dist/src/ui/hooks/useLogger.js.map +1 -1
- package/dist/src/ui/hooks/usePhraseCycler.js +12 -136
- package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
- package/dist/src/ui/hooks/useQwenAuth.test.js +1 -1
- package/dist/src/ui/hooks/useQwenAuth.test.js.map +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js +2 -2
- package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
- package/dist/src/ui/hooks/useResumeCommand.d.ts +20 -0
- package/dist/src/ui/hooks/useResumeCommand.js +49 -0
- package/dist/src/ui/hooks/useResumeCommand.js.map +1 -0
- package/dist/src/ui/hooks/useResumeCommand.test.d.ts +6 -0
- package/dist/src/ui/hooks/useResumeCommand.test.js +144 -0
- package/dist/src/ui/hooks/useResumeCommand.test.js.map +1 -0
- package/dist/src/ui/hooks/useSessionPicker.d.ts +36 -0
- package/dist/src/ui/hooks/useSessionPicker.js +189 -0
- package/dist/src/ui/hooks/useSessionPicker.js.map +1 -0
- package/dist/src/ui/hooks/useSlashCompletion.js +9 -1
- package/dist/src/ui/hooks/useSlashCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.test.js +36 -31
- package/dist/src/ui/hooks/useSlashCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js +2 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/models/availableModels.d.ts +9 -2
- package/dist/src/ui/models/availableModels.js +32 -35
- package/dist/src/ui/models/availableModels.js.map +1 -1
- package/dist/src/ui/noninteractive/nonInteractiveUi.js +0 -1
- package/dist/src/ui/noninteractive/nonInteractiveUi.js.map +1 -1
- package/dist/src/ui/types.d.ts +9 -14
- package/dist/src/ui/types.js +0 -1
- package/dist/src/ui/types.js.map +1 -1
- package/dist/src/ui/utils/InlineMarkdownRenderer.d.ts +1 -0
- package/dist/src/ui/utils/InlineMarkdownRenderer.js +2 -2
- package/dist/src/ui/utils/InlineMarkdownRenderer.js.map +1 -1
- package/dist/src/ui/utils/MarkdownDisplay.d.ts +1 -0
- package/dist/src/ui/utils/MarkdownDisplay.js +13 -13
- package/dist/src/ui/utils/MarkdownDisplay.js.map +1 -1
- package/dist/src/ui/utils/formatters.d.ts +6 -0
- package/dist/src/ui/utils/formatters.js +31 -0
- package/dist/src/ui/utils/formatters.js.map +1 -1
- package/dist/src/ui/utils/formatters.test.js +51 -2
- package/dist/src/ui/utils/formatters.test.js.map +1 -1
- package/dist/src/ui/utils/resumeHistoryUtils.d.ts +19 -0
- package/dist/src/ui/utils/resumeHistoryUtils.js +267 -0
- package/dist/src/ui/utils/resumeHistoryUtils.js.map +1 -0
- package/dist/src/ui/utils/resumeHistoryUtils.test.d.ts +6 -0
- package/dist/src/ui/utils/resumeHistoryUtils.test.js +253 -0
- package/dist/src/ui/utils/resumeHistoryUtils.test.js.map +1 -0
- package/dist/src/ui/utils/sessionPickerUtils.d.ts +30 -0
- package/dist/src/ui/utils/sessionPickerUtils.js +41 -0
- package/dist/src/ui/utils/sessionPickerUtils.js.map +1 -0
- package/dist/src/ui/utils/sessionPickerUtils.test.d.ts +6 -0
- package/dist/src/ui/utils/sessionPickerUtils.test.js +38 -0
- package/dist/src/ui/utils/sessionPickerUtils.test.js.map +1 -0
- package/dist/src/utils/attentionNotification.d.ts +1 -0
- package/dist/src/utils/attentionNotification.js +4 -0
- package/dist/src/utils/attentionNotification.js.map +1 -1
- package/dist/src/utils/errors.d.ts +1 -1
- package/dist/src/utils/errors.js +14 -3
- package/dist/src/utils/errors.js.map +1 -1
- package/dist/src/utils/errors.test.js +43 -1
- package/dist/src/utils/errors.test.js.map +1 -1
- package/dist/src/utils/gitUtils.js +25 -8
- package/dist/src/utils/gitUtils.js.map +1 -1
- package/dist/src/utils/gitUtils.test.js +59 -0
- package/dist/src/utils/gitUtils.test.js.map +1 -1
- package/dist/src/utils/nonInteractiveHelpers.d.ts +3 -1
- package/dist/src/utils/nonInteractiveHelpers.js +14 -15
- package/dist/src/utils/nonInteractiveHelpers.js.map +1 -1
- package/dist/src/utils/nonInteractiveHelpers.test.js +36 -21
- package/dist/src/utils/nonInteractiveHelpers.test.js.map +1 -1
- package/dist/src/utils/relaunch.js +2 -2
- package/dist/src/utils/relaunch.js.map +1 -1
- package/dist/src/utils/relaunch.test.js +5 -5
- package/dist/src/utils/relaunch.test.js.map +1 -1
- package/dist/src/utils/systemInfo.js +2 -1
- package/dist/src/utils/systemInfo.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.js +10 -1
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/dist/src/nonInteractive/control/controllers/mcpController.d.ts +0 -42
- package/dist/src/nonInteractive/control/controllers/mcpController.js +0 -205
- package/dist/src/nonInteractive/control/controllers/mcpController.js.map +0 -1
- package/dist/src/ui/commands/chatCommand.d.ts +0 -9
- package/dist/src/ui/commands/chatCommand.js +0 -351
- package/dist/src/ui/commands/chatCommand.js.map +0 -1
- package/dist/src/ui/commands/corgiCommand.d.ts +0 -7
- package/dist/src/ui/commands/corgiCommand.js +0 -16
- package/dist/src/ui/commands/corgiCommand.js.map +0 -1
- package/dist/src/ui/components/ProQuotaDialog.d.ts +0 -13
- package/dist/src/ui/components/ProQuotaDialog.js +0 -24
- package/dist/src/ui/components/ProQuotaDialog.js.map +0 -1
- package/dist/src/ui/components/ProQuotaDialog.test.js +0 -58
- package/dist/src/ui/components/ProQuotaDialog.test.js.map +0 -1
- package/dist/src/ui/components/QuitConfirmationDialog.d.ts +0 -17
- package/dist/src/ui/components/QuitConfirmationDialog.js +0 -49
- package/dist/src/ui/components/QuitConfirmationDialog.js.map +0 -1
- package/dist/src/ui/hooks/usePromptCompletion.d.ts +0 -23
- package/dist/src/ui/hooks/usePromptCompletion.js +0 -177
- package/dist/src/ui/hooks/usePromptCompletion.js.map +0 -1
- package/dist/src/ui/hooks/useQuitConfirmation.d.ts +0 -14
- package/dist/src/ui/hooks/useQuitConfirmation.js +0 -36
- package/dist/src/ui/hooks/useQuitConfirmation.js.map +0 -1
- package/dist/src/ui/hooks/useQuotaAndFallback.d.ts +0 -21
- package/dist/src/ui/hooks/useQuotaAndFallback.js +0 -122
- package/dist/src/ui/hooks/useQuotaAndFallback.js.map +0 -1
- package/dist/src/ui/hooks/useQuotaAndFallback.test.js +0 -269
- package/dist/src/ui/hooks/useQuotaAndFallback.test.js.map +0 -1
- package/dist/src/zed-integration/acp.js.map +0 -1
- package/dist/src/zed-integration/fileSystemService.js.map +0 -1
- package/dist/src/zed-integration/schema.js.map +0 -1
- package/dist/src/zed-integration/zedIntegration.d.ts +0 -17
- package/dist/src/zed-integration/zedIntegration.js +0 -1135
- package/dist/src/zed-integration/zedIntegration.js.map +0 -1
- /package/dist/src/ui/{components/ProQuotaDialog.test.d.ts → commands/reviewCommand.test.d.ts} +0 -0
|
@@ -12,19 +12,7 @@ import { isCLIUserMessage, isCLIAssistantMessage, isCLISystemMessage, isCLIResul
|
|
|
12
12
|
import { createMinimalSettings } from '../config/settings.js';
|
|
13
13
|
import { runNonInteractive } from '../nonInteractiveCli.js';
|
|
14
14
|
import { ConsolePatcher } from '../ui/utils/ConsolePatcher.js';
|
|
15
|
-
|
|
16
|
-
INITIALIZING: 'initializing',
|
|
17
|
-
IDLE: 'idle',
|
|
18
|
-
PROCESSING_QUERY: 'processing_query',
|
|
19
|
-
SHUTTING_DOWN: 'shutting_down',
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Session Manager
|
|
23
|
-
*
|
|
24
|
-
* Manages the session lifecycle and message processing state machine.
|
|
25
|
-
*/
|
|
26
|
-
class SessionManager {
|
|
27
|
-
state = SESSION_STATE.INITIALIZING;
|
|
15
|
+
class Session {
|
|
28
16
|
userMessageQueue = [];
|
|
29
17
|
abortController;
|
|
30
18
|
config;
|
|
@@ -39,6 +27,14 @@ class SessionManager {
|
|
|
39
27
|
debugMode;
|
|
40
28
|
shutdownHandler = null;
|
|
41
29
|
initialPrompt = null;
|
|
30
|
+
processingPromise = null;
|
|
31
|
+
isShuttingDown = false;
|
|
32
|
+
configInitialized = false;
|
|
33
|
+
// Single initialization promise that resolves when session is ready for user messages.
|
|
34
|
+
// Created lazily once initialization actually starts.
|
|
35
|
+
initializationPromise = null;
|
|
36
|
+
initializationResolve = null;
|
|
37
|
+
initializationReject = null;
|
|
42
38
|
constructor(config, initialPrompt) {
|
|
43
39
|
this.config = config;
|
|
44
40
|
this.sessionId = config.getSessionId();
|
|
@@ -47,135 +43,86 @@ class SessionManager {
|
|
|
47
43
|
this.initialPrompt = initialPrompt ?? null;
|
|
48
44
|
this.inputReader = new StreamJsonInputReader();
|
|
49
45
|
this.outputAdapter = new StreamJsonOutputAdapter(config, config.getIncludePartialMessages());
|
|
50
|
-
// Setup signal handlers for graceful shutdown
|
|
51
46
|
this.setupSignalHandlers();
|
|
52
47
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
ensureInitializationPromise() {
|
|
49
|
+
if (this.initializationPromise) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this.initializationPromise = new Promise((resolve, reject) => {
|
|
53
|
+
this.initializationResolve = () => {
|
|
54
|
+
resolve();
|
|
55
|
+
this.initializationResolve = null;
|
|
56
|
+
this.initializationReject = null;
|
|
57
|
+
};
|
|
58
|
+
this.initializationReject = (error) => {
|
|
59
|
+
reject(error);
|
|
60
|
+
this.initializationResolve = null;
|
|
61
|
+
this.initializationReject = null;
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
}
|
|
56
65
|
getNextPromptId() {
|
|
57
66
|
this.promptIdCounter++;
|
|
58
67
|
return `${this.sessionId}########${this.promptIdCounter}`;
|
|
59
68
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
* Classifies incoming messages and routes them to appropriate handlers.
|
|
64
|
-
*/
|
|
65
|
-
route(message) {
|
|
66
|
-
// Check control messages first
|
|
67
|
-
if (isControlRequest(message)) {
|
|
68
|
-
return { type: 'control_request', message };
|
|
69
|
-
}
|
|
70
|
-
if (isControlResponse(message)) {
|
|
71
|
-
return { type: 'control_response', message };
|
|
72
|
-
}
|
|
73
|
-
if (isControlCancel(message)) {
|
|
74
|
-
return { type: 'control_cancel', message };
|
|
75
|
-
}
|
|
76
|
-
// Check data messages
|
|
77
|
-
if (isCLIUserMessage(message)) {
|
|
78
|
-
return { type: 'user', message };
|
|
79
|
-
}
|
|
80
|
-
if (isCLIAssistantMessage(message)) {
|
|
81
|
-
return { type: 'assistant', message };
|
|
82
|
-
}
|
|
83
|
-
if (isCLISystemMessage(message)) {
|
|
84
|
-
return { type: 'system', message };
|
|
69
|
+
async ensureConfigInitialized(options) {
|
|
70
|
+
if (this.configInitialized) {
|
|
71
|
+
return;
|
|
85
72
|
}
|
|
86
|
-
if (
|
|
87
|
-
|
|
73
|
+
if (this.debugMode) {
|
|
74
|
+
console.error('[Session] Initializing config');
|
|
88
75
|
}
|
|
89
|
-
|
|
90
|
-
|
|
76
|
+
try {
|
|
77
|
+
await this.config.initialize(options);
|
|
78
|
+
this.configInitialized = true;
|
|
91
79
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
80
|
+
catch (error) {
|
|
81
|
+
if (this.debugMode) {
|
|
82
|
+
console.error('[Session] Failed to initialize config:', error);
|
|
83
|
+
}
|
|
84
|
+
throw error;
|
|
95
85
|
}
|
|
96
|
-
return { type: 'unknown', message };
|
|
97
86
|
}
|
|
98
87
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* Handles:
|
|
102
|
-
* - Abort check
|
|
103
|
-
* - First message detection and handling
|
|
104
|
-
* - Normal message processing
|
|
105
|
-
* - Shutdown state checks
|
|
106
|
-
*
|
|
107
|
-
* @param message - Message to process
|
|
108
|
-
* @returns true if the calling code should exit (break/return), false to continue
|
|
88
|
+
* Mark initialization as complete
|
|
109
89
|
*/
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
// Handle first message if control system not yet initialized
|
|
116
|
-
if (this.controlSystemEnabled === null) {
|
|
117
|
-
const handled = await this.handleFirstMessage(message);
|
|
118
|
-
if (handled) {
|
|
119
|
-
// If handled, check if we should shutdown
|
|
120
|
-
return this.state === SESSION_STATE.SHUTTING_DOWN;
|
|
90
|
+
completeInitialization() {
|
|
91
|
+
if (this.initializationResolve) {
|
|
92
|
+
if (this.debugMode) {
|
|
93
|
+
console.error('[Session] Initialization complete');
|
|
121
94
|
}
|
|
122
|
-
|
|
95
|
+
this.initializationResolve();
|
|
96
|
+
this.initializationResolve = null;
|
|
97
|
+
this.initializationReject = null;
|
|
123
98
|
}
|
|
124
|
-
// Process message normally
|
|
125
|
-
await this.processMessage(message);
|
|
126
|
-
// Check for shutdown after processing
|
|
127
|
-
return this.state === SESSION_STATE.SHUTTING_DOWN;
|
|
128
99
|
}
|
|
129
100
|
/**
|
|
130
|
-
*
|
|
101
|
+
* Mark initialization as failed
|
|
131
102
|
*/
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (this.debugMode) {
|
|
135
|
-
console.error('[SessionManager] Starting session', this.sessionId);
|
|
136
|
-
}
|
|
137
|
-
// Process initial prompt if provided
|
|
138
|
-
if (this.initialPrompt !== null) {
|
|
139
|
-
const shouldExit = await this.processSingleMessage(this.initialPrompt);
|
|
140
|
-
if (shouldExit) {
|
|
141
|
-
await this.shutdown();
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
// Process messages from stream
|
|
146
|
-
for await (const message of this.inputReader.read()) {
|
|
147
|
-
const shouldExit = await this.processSingleMessage(message);
|
|
148
|
-
if (shouldExit) {
|
|
149
|
-
break;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
// Stream closed, shutdown
|
|
153
|
-
await this.shutdown();
|
|
154
|
-
}
|
|
155
|
-
catch (error) {
|
|
103
|
+
failInitialization(error) {
|
|
104
|
+
if (this.initializationReject) {
|
|
156
105
|
if (this.debugMode) {
|
|
157
|
-
console.error('[
|
|
106
|
+
console.error('[Session] Initialization failed:', error);
|
|
158
107
|
}
|
|
159
|
-
|
|
160
|
-
|
|
108
|
+
this.initializationReject(error);
|
|
109
|
+
this.initializationResolve = null;
|
|
110
|
+
this.initializationReject = null;
|
|
161
111
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Wait for session to be ready for user messages
|
|
115
|
+
*/
|
|
116
|
+
async waitForInitialization() {
|
|
117
|
+
if (!this.initializationPromise) {
|
|
118
|
+
return;
|
|
165
119
|
}
|
|
120
|
+
await this.initializationPromise;
|
|
166
121
|
}
|
|
167
122
|
ensureControlSystem() {
|
|
168
123
|
if (this.controlContext && this.dispatcher && this.controlService) {
|
|
169
124
|
return;
|
|
170
125
|
}
|
|
171
|
-
// The control system follows a strict three-layer architecture:
|
|
172
|
-
// 1. ControlContext (shared session state)
|
|
173
|
-
// 2. ControlDispatcher (protocol routing SDK ↔ CLI)
|
|
174
|
-
// 3. ControlService (programmatic API for CLI runtime)
|
|
175
|
-
//
|
|
176
|
-
// Application code MUST interact with the control plane exclusively through
|
|
177
|
-
// ControlService. ControlDispatcher is reserved for protocol-level message
|
|
178
|
-
// routing and should never be used directly outside of this file.
|
|
179
126
|
this.controlContext = new ControlContext({
|
|
180
127
|
config: this.config,
|
|
181
128
|
streamJson: this.outputAdapter,
|
|
@@ -196,224 +143,133 @@ class SessionManager {
|
|
|
196
143
|
}
|
|
197
144
|
return this.dispatcher;
|
|
198
145
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
146
|
+
/**
|
|
147
|
+
* Handle the first message to determine session mode (SDK vs direct).
|
|
148
|
+
* This is synchronous from the message loop's perspective - it starts
|
|
149
|
+
* async work but does not return a promise that the loop awaits.
|
|
150
|
+
*
|
|
151
|
+
* The initialization completes asynchronously and resolves initializationPromise
|
|
152
|
+
* when ready for user messages.
|
|
153
|
+
*/
|
|
154
|
+
handleFirstMessage(message) {
|
|
155
|
+
if (isControlRequest(message)) {
|
|
156
|
+
const request = message;
|
|
203
157
|
this.controlSystemEnabled = true;
|
|
204
158
|
this.ensureControlSystem();
|
|
205
159
|
if (request.request.subtype === 'initialize') {
|
|
206
|
-
|
|
207
|
-
this.
|
|
208
|
-
return
|
|
160
|
+
// Start SDK mode initialization (fire-and-forget from loop perspective)
|
|
161
|
+
void this.initializeSdkMode(request);
|
|
162
|
+
return;
|
|
209
163
|
}
|
|
210
|
-
|
|
164
|
+
if (this.debugMode) {
|
|
165
|
+
console.error('[Session] Ignoring non-initialize control request during initialization');
|
|
166
|
+
}
|
|
167
|
+
return;
|
|
211
168
|
}
|
|
212
|
-
if (
|
|
169
|
+
if (isCLIUserMessage(message)) {
|
|
213
170
|
this.controlSystemEnabled = false;
|
|
214
|
-
|
|
215
|
-
this.
|
|
216
|
-
|
|
217
|
-
return true;
|
|
171
|
+
// Start direct mode initialization (fire-and-forget from loop perspective)
|
|
172
|
+
void this.initializeDirectMode(message);
|
|
173
|
+
return;
|
|
218
174
|
}
|
|
219
175
|
this.controlSystemEnabled = false;
|
|
220
|
-
return false;
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Process a single message from the stream
|
|
224
|
-
*/
|
|
225
|
-
async processMessage(message) {
|
|
226
|
-
const routed = this.route(message);
|
|
227
|
-
if (this.debugMode) {
|
|
228
|
-
console.error(`[SessionManager] State: ${this.state}, Message type: ${routed.type}`);
|
|
229
|
-
}
|
|
230
|
-
switch (this.state) {
|
|
231
|
-
case SESSION_STATE.INITIALIZING:
|
|
232
|
-
await this.handleInitializingState(routed);
|
|
233
|
-
break;
|
|
234
|
-
case SESSION_STATE.IDLE:
|
|
235
|
-
await this.handleIdleState(routed);
|
|
236
|
-
break;
|
|
237
|
-
case SESSION_STATE.PROCESSING_QUERY:
|
|
238
|
-
await this.handleProcessingState(routed);
|
|
239
|
-
break;
|
|
240
|
-
case SESSION_STATE.SHUTTING_DOWN:
|
|
241
|
-
// Ignore all messages during shutdown
|
|
242
|
-
break;
|
|
243
|
-
default: {
|
|
244
|
-
// Exhaustive check
|
|
245
|
-
const _exhaustiveCheck = this.state;
|
|
246
|
-
if (this.debugMode) {
|
|
247
|
-
console.error('[SessionManager] Unknown state:', _exhaustiveCheck);
|
|
248
|
-
}
|
|
249
|
-
break;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
176
|
}
|
|
253
177
|
/**
|
|
254
|
-
*
|
|
178
|
+
* SDK mode initialization flow
|
|
179
|
+
* Dispatches initialize request and initializes config with MCP support
|
|
255
180
|
*/
|
|
256
|
-
async
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
console.error('[SessionManager] Initialized, transitioning to idle');
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
else {
|
|
274
|
-
if (this.debugMode) {
|
|
275
|
-
console.error('[SessionManager] Ignoring non-initialize control request during initialization');
|
|
276
|
-
}
|
|
277
|
-
}
|
|
181
|
+
async initializeSdkMode(request) {
|
|
182
|
+
this.ensureInitializationPromise();
|
|
183
|
+
try {
|
|
184
|
+
// Dispatch the initialize request first
|
|
185
|
+
// This registers SDK MCP servers in the control context
|
|
186
|
+
await this.dispatcher?.dispatch(request);
|
|
187
|
+
// Get sendSdkMcpMessage callback from SdkMcpController
|
|
188
|
+
// This callback is used by McpClientManager to send MCP messages
|
|
189
|
+
// from CLI MCP clients to SDK MCP servers via the control plane
|
|
190
|
+
const sendSdkMcpMessage = this.dispatcher?.sdkMcpController.createSendSdkMcpMessage();
|
|
191
|
+
// Initialize config with SDK MCP message support
|
|
192
|
+
await this.ensureConfigInitialized({ sendSdkMcpMessage });
|
|
193
|
+
// Initialization complete!
|
|
194
|
+
this.completeInitialization();
|
|
278
195
|
}
|
|
279
|
-
|
|
196
|
+
catch (error) {
|
|
280
197
|
if (this.debugMode) {
|
|
281
|
-
console.error('[
|
|
198
|
+
console.error('[Session] SDK mode initialization failed:', error);
|
|
282
199
|
}
|
|
200
|
+
this.failInitialization(error instanceof Error ? error : new Error(String(error)));
|
|
283
201
|
}
|
|
284
202
|
}
|
|
285
203
|
/**
|
|
286
|
-
*
|
|
204
|
+
* Direct mode initialization flow
|
|
205
|
+
* Initializes config and enqueues the first user message
|
|
287
206
|
*/
|
|
288
|
-
async
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
const request = routed.message;
|
|
298
|
-
await dispatcher.dispatch(request);
|
|
299
|
-
// Stay in idle state
|
|
300
|
-
}
|
|
301
|
-
else if (routed.type === 'control_response') {
|
|
302
|
-
if (!dispatcher) {
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
const response = routed.message;
|
|
306
|
-
dispatcher.handleControlResponse(response);
|
|
307
|
-
// Stay in idle state
|
|
308
|
-
}
|
|
309
|
-
else if (routed.type === 'control_cancel') {
|
|
310
|
-
if (!dispatcher) {
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
const cancelRequest = routed.message;
|
|
314
|
-
dispatcher.handleCancel(cancelRequest.request_id);
|
|
315
|
-
}
|
|
316
|
-
else if (routed.type === 'user') {
|
|
317
|
-
const userMessage = routed.message;
|
|
318
|
-
this.userMessageQueue.push(userMessage);
|
|
319
|
-
// Start processing queue
|
|
320
|
-
await this.processUserMessageQueue();
|
|
207
|
+
async initializeDirectMode(userMessage) {
|
|
208
|
+
this.ensureInitializationPromise();
|
|
209
|
+
try {
|
|
210
|
+
// Initialize config
|
|
211
|
+
await this.ensureConfigInitialized();
|
|
212
|
+
// Initialization complete!
|
|
213
|
+
this.completeInitialization();
|
|
214
|
+
// Enqueue the first user message for processing
|
|
215
|
+
this.enqueueUserMessage(userMessage);
|
|
321
216
|
}
|
|
322
|
-
|
|
217
|
+
catch (error) {
|
|
323
218
|
if (this.debugMode) {
|
|
324
|
-
console.error('[
|
|
219
|
+
console.error('[Session] Direct mode initialization failed:', error);
|
|
325
220
|
}
|
|
221
|
+
this.failInitialization(error instanceof Error ? error : new Error(String(error)));
|
|
326
222
|
}
|
|
327
223
|
}
|
|
328
224
|
/**
|
|
329
|
-
* Handle
|
|
225
|
+
* Handle control request asynchronously (fire-and-forget from main loop).
|
|
226
|
+
* Errors are handled internally and responses sent by dispatcher.
|
|
330
227
|
*/
|
|
331
|
-
|
|
228
|
+
handleControlRequestAsync(request) {
|
|
332
229
|
const dispatcher = this.getDispatcher();
|
|
333
|
-
if (
|
|
334
|
-
if (!dispatcher) {
|
|
335
|
-
if (this.debugMode) {
|
|
336
|
-
console.error('[SessionManager] Control request ignored during processing (disabled)');
|
|
337
|
-
}
|
|
338
|
-
return;
|
|
339
|
-
}
|
|
340
|
-
const request = routed.message;
|
|
341
|
-
await dispatcher.dispatch(request);
|
|
342
|
-
// Continue processing
|
|
343
|
-
}
|
|
344
|
-
else if (routed.type === 'control_response') {
|
|
345
|
-
if (!dispatcher) {
|
|
346
|
-
return;
|
|
347
|
-
}
|
|
348
|
-
const response = routed.message;
|
|
349
|
-
dispatcher.handleControlResponse(response);
|
|
350
|
-
// Continue processing
|
|
351
|
-
}
|
|
352
|
-
else if (routed.type === 'user') {
|
|
353
|
-
// Enqueue for later
|
|
354
|
-
const userMessage = routed.message;
|
|
355
|
-
this.userMessageQueue.push(userMessage);
|
|
230
|
+
if (!dispatcher) {
|
|
356
231
|
if (this.debugMode) {
|
|
357
|
-
console.error('[
|
|
232
|
+
console.error('[Session] Control system not enabled');
|
|
358
233
|
}
|
|
234
|
+
return;
|
|
359
235
|
}
|
|
360
|
-
|
|
236
|
+
// Fire-and-forget: dispatch runs concurrently
|
|
237
|
+
// The dispatcher's pendingIncomingRequests tracks completion
|
|
238
|
+
void dispatcher.dispatch(request).catch((error) => {
|
|
361
239
|
if (this.debugMode) {
|
|
362
|
-
console.error('[
|
|
240
|
+
console.error('[Session] Control request dispatch error:', error);
|
|
363
241
|
}
|
|
364
|
-
|
|
242
|
+
// Error response is already sent by dispatcher.dispatch()
|
|
243
|
+
});
|
|
365
244
|
}
|
|
366
245
|
/**
|
|
367
|
-
*
|
|
246
|
+
* Handle control response - MUST be synchronous
|
|
247
|
+
* This resolves pending outgoing requests, breaking the deadlock cycle.
|
|
368
248
|
*/
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
this.state = SESSION_STATE.PROCESSING_QUERY;
|
|
373
|
-
const userMessage = this.userMessageQueue.shift();
|
|
374
|
-
try {
|
|
375
|
-
await this.processUserMessage(userMessage);
|
|
376
|
-
}
|
|
377
|
-
catch (error) {
|
|
378
|
-
if (this.debugMode) {
|
|
379
|
-
console.error('[SessionManager] Error processing user message:', error);
|
|
380
|
-
}
|
|
381
|
-
// Send error result
|
|
382
|
-
this.emitErrorResult(error);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
// If control system is disabled (single-query mode) and queue is empty,
|
|
386
|
-
// automatically shutdown instead of returning to idle
|
|
387
|
-
if (!this.abortController.signal.aborted &&
|
|
388
|
-
this.state === SESSION_STATE.PROCESSING_QUERY &&
|
|
389
|
-
this.controlSystemEnabled === false &&
|
|
390
|
-
this.userMessageQueue.length === 0) {
|
|
391
|
-
if (this.debugMode) {
|
|
392
|
-
console.error('[SessionManager] Single-query mode: queue processed, shutting down');
|
|
393
|
-
}
|
|
394
|
-
this.state = SESSION_STATE.SHUTTING_DOWN;
|
|
249
|
+
handleControlResponse(response) {
|
|
250
|
+
const dispatcher = this.getDispatcher();
|
|
251
|
+
if (!dispatcher) {
|
|
395
252
|
return;
|
|
396
253
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}
|
|
254
|
+
dispatcher.handleControlResponse(response);
|
|
255
|
+
}
|
|
256
|
+
handleControlCancel(cancelRequest) {
|
|
257
|
+
const dispatcher = this.getDispatcher();
|
|
258
|
+
if (!dispatcher) {
|
|
259
|
+
return;
|
|
404
260
|
}
|
|
261
|
+
dispatcher.handleCancel(cancelRequest.request_id);
|
|
405
262
|
}
|
|
406
|
-
/**
|
|
407
|
-
* Process a single user message
|
|
408
|
-
*/
|
|
409
263
|
async processUserMessage(userMessage) {
|
|
410
264
|
const input = extractUserMessageText(userMessage);
|
|
411
265
|
if (!input) {
|
|
412
266
|
if (this.debugMode) {
|
|
413
|
-
console.error('[
|
|
267
|
+
console.error('[Session] No text content in user message');
|
|
414
268
|
}
|
|
415
269
|
return;
|
|
416
270
|
}
|
|
271
|
+
// Wait for initialization to complete before processing user messages
|
|
272
|
+
await this.waitForInitialization();
|
|
417
273
|
const promptId = this.getNextPromptId();
|
|
418
274
|
try {
|
|
419
275
|
await runNonInteractive(this.config, createMinimalSettings(), input, promptId, {
|
|
@@ -423,15 +279,47 @@ class SessionManager {
|
|
|
423
279
|
});
|
|
424
280
|
}
|
|
425
281
|
catch (error) {
|
|
426
|
-
// Error already handled by runNonInteractive via adapter.emitResult
|
|
427
282
|
if (this.debugMode) {
|
|
428
|
-
console.error('[
|
|
283
|
+
console.error('[Session] Query execution error:', error);
|
|
429
284
|
}
|
|
430
285
|
}
|
|
431
286
|
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
287
|
+
async processUserMessageQueue() {
|
|
288
|
+
if (this.isShuttingDown || this.abortController.signal.aborted) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
while (this.userMessageQueue.length > 0 &&
|
|
292
|
+
!this.isShuttingDown &&
|
|
293
|
+
!this.abortController.signal.aborted) {
|
|
294
|
+
const userMessage = this.userMessageQueue.shift();
|
|
295
|
+
try {
|
|
296
|
+
await this.processUserMessage(userMessage);
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
if (this.debugMode) {
|
|
300
|
+
console.error('[Session] Error processing user message:', error);
|
|
301
|
+
}
|
|
302
|
+
this.emitErrorResult(error);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
enqueueUserMessage(userMessage) {
|
|
307
|
+
this.userMessageQueue.push(userMessage);
|
|
308
|
+
this.ensureProcessingStarted();
|
|
309
|
+
}
|
|
310
|
+
ensureProcessingStarted() {
|
|
311
|
+
if (this.processingPromise) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
this.processingPromise = this.processUserMessageQueue().finally(() => {
|
|
315
|
+
this.processingPromise = null;
|
|
316
|
+
if (this.userMessageQueue.length > 0 &&
|
|
317
|
+
!this.isShuttingDown &&
|
|
318
|
+
!this.abortController.signal.aborted) {
|
|
319
|
+
this.ensureProcessingStarted();
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
}
|
|
435
323
|
emitErrorResult(error, numTurns = 0, durationMs = 0, apiDurationMs = 0) {
|
|
436
324
|
const message = error instanceof Error ? error.message : String(error);
|
|
437
325
|
this.outputAdapter.emitResult({
|
|
@@ -443,47 +331,70 @@ class SessionManager {
|
|
|
443
331
|
usage: undefined,
|
|
444
332
|
});
|
|
445
333
|
}
|
|
446
|
-
/**
|
|
447
|
-
* Handle interrupt control request
|
|
448
|
-
*/
|
|
449
334
|
handleInterrupt() {
|
|
450
335
|
if (this.debugMode) {
|
|
451
|
-
console.error('[
|
|
452
|
-
}
|
|
453
|
-
// Abort current query if processing
|
|
454
|
-
if (this.state === SESSION_STATE.PROCESSING_QUERY) {
|
|
455
|
-
this.abortController.abort();
|
|
456
|
-
this.abortController = new AbortController(); // Create new controller for next query
|
|
336
|
+
console.error('[Session] Interrupt requested');
|
|
457
337
|
}
|
|
338
|
+
this.abortController.abort();
|
|
339
|
+
this.abortController = new AbortController();
|
|
458
340
|
}
|
|
459
|
-
/**
|
|
460
|
-
* Setup signal handlers for graceful shutdown
|
|
461
|
-
*/
|
|
462
341
|
setupSignalHandlers() {
|
|
463
342
|
this.shutdownHandler = () => {
|
|
464
343
|
if (this.debugMode) {
|
|
465
|
-
console.error('[
|
|
344
|
+
console.error('[Session] Shutdown signal received');
|
|
466
345
|
}
|
|
346
|
+
this.isShuttingDown = true;
|
|
467
347
|
this.abortController.abort();
|
|
468
|
-
this.state = SESSION_STATE.SHUTTING_DOWN;
|
|
469
348
|
};
|
|
470
349
|
process.on('SIGINT', this.shutdownHandler);
|
|
471
350
|
process.on('SIGTERM', this.shutdownHandler);
|
|
472
351
|
}
|
|
473
352
|
/**
|
|
474
|
-
*
|
|
353
|
+
* Wait for all pending work to complete before shutdown
|
|
475
354
|
*/
|
|
355
|
+
async waitForAllPendingWork() {
|
|
356
|
+
// 1. Wait for initialization to complete (or fail)
|
|
357
|
+
try {
|
|
358
|
+
await this.waitForInitialization();
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
if (this.debugMode) {
|
|
362
|
+
console.error('[Session] Initialization error during shutdown:', error);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// 2. Wait for all control request handlers using dispatcher's tracking
|
|
366
|
+
if (this.dispatcher) {
|
|
367
|
+
const pendingCount = this.dispatcher.getPendingIncomingRequestCount();
|
|
368
|
+
if (pendingCount > 0 && this.debugMode) {
|
|
369
|
+
console.error(`[Session] Waiting for ${pendingCount} pending control request handlers`);
|
|
370
|
+
}
|
|
371
|
+
await this.dispatcher.waitForPendingIncomingRequests();
|
|
372
|
+
}
|
|
373
|
+
// 3. Wait for user message processing queue
|
|
374
|
+
while (this.processingPromise) {
|
|
375
|
+
if (this.debugMode) {
|
|
376
|
+
console.error('[Session] Waiting for user message processing');
|
|
377
|
+
}
|
|
378
|
+
try {
|
|
379
|
+
await this.processingPromise;
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
if (this.debugMode) {
|
|
383
|
+
console.error('[Session] Error in user message processing:', error);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
476
388
|
async shutdown() {
|
|
477
389
|
if (this.debugMode) {
|
|
478
|
-
console.error('[
|
|
390
|
+
console.error('[Session] Shutting down');
|
|
479
391
|
}
|
|
480
|
-
this.
|
|
392
|
+
this.isShuttingDown = true;
|
|
393
|
+
// Wait for all pending work
|
|
394
|
+
await this.waitForAllPendingWork();
|
|
481
395
|
this.dispatcher?.shutdown();
|
|
482
396
|
this.cleanupSignalHandlers();
|
|
483
397
|
}
|
|
484
|
-
/**
|
|
485
|
-
* Remove signal handlers to prevent memory leaks
|
|
486
|
-
*/
|
|
487
398
|
cleanupSignalHandlers() {
|
|
488
399
|
if (this.shutdownHandler) {
|
|
489
400
|
process.removeListener('SIGINT', this.shutdownHandler);
|
|
@@ -491,6 +402,98 @@ class SessionManager {
|
|
|
491
402
|
this.shutdownHandler = null;
|
|
492
403
|
}
|
|
493
404
|
}
|
|
405
|
+
/**
|
|
406
|
+
* Main message processing loop
|
|
407
|
+
*
|
|
408
|
+
* CRITICAL: This loop must NEVER await handlers that might need to
|
|
409
|
+
* send control requests and wait for responses. Such handlers must
|
|
410
|
+
* be started in fire-and-forget mode, allowing the loop to continue
|
|
411
|
+
* reading responses that resolve pending requests.
|
|
412
|
+
*
|
|
413
|
+
* Message handling order:
|
|
414
|
+
* 1. control_response - FIRST, synchronously resolves pending requests
|
|
415
|
+
* 2. First message - determines mode, starts async initialization
|
|
416
|
+
* 3. control_request - fire-and-forget, tracked by dispatcher
|
|
417
|
+
* 4. control_cancel - synchronous
|
|
418
|
+
* 5. user_message - enqueued for processing
|
|
419
|
+
*/
|
|
420
|
+
async run() {
|
|
421
|
+
try {
|
|
422
|
+
if (this.debugMode) {
|
|
423
|
+
console.error('[Session] Starting session', this.sessionId);
|
|
424
|
+
}
|
|
425
|
+
// Handle initial prompt if provided (fire-and-forget)
|
|
426
|
+
if (this.initialPrompt !== null) {
|
|
427
|
+
this.handleFirstMessage(this.initialPrompt);
|
|
428
|
+
}
|
|
429
|
+
try {
|
|
430
|
+
for await (const message of this.inputReader.read()) {
|
|
431
|
+
if (this.abortController.signal.aborted) {
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
434
|
+
// ============================================================
|
|
435
|
+
// CRITICAL: Handle control_response FIRST and SYNCHRONOUSLY
|
|
436
|
+
// This resolves pending outgoing requests, breaking deadlock.
|
|
437
|
+
// ============================================================
|
|
438
|
+
if (isControlResponse(message)) {
|
|
439
|
+
this.handleControlResponse(message);
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
// Handle first message to determine session mode
|
|
443
|
+
if (this.controlSystemEnabled === null) {
|
|
444
|
+
this.handleFirstMessage(message);
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
// ============================================================
|
|
448
|
+
// CRITICAL: Handle control_request in FIRE-AND-FORGET mode
|
|
449
|
+
// DON'T await - let handler run concurrently while loop continues
|
|
450
|
+
// Dispatcher's pendingIncomingRequests tracks completion
|
|
451
|
+
// ============================================================
|
|
452
|
+
if (isControlRequest(message)) {
|
|
453
|
+
this.handleControlRequestAsync(message);
|
|
454
|
+
}
|
|
455
|
+
else if (isControlCancel(message)) {
|
|
456
|
+
// Cancel is synchronous - OK to handle inline
|
|
457
|
+
this.handleControlCancel(message);
|
|
458
|
+
}
|
|
459
|
+
else if (isCLIUserMessage(message)) {
|
|
460
|
+
// User messages are enqueued, processing runs separately
|
|
461
|
+
this.enqueueUserMessage(message);
|
|
462
|
+
}
|
|
463
|
+
else if (this.debugMode) {
|
|
464
|
+
if (!isCLIAssistantMessage(message) &&
|
|
465
|
+
!isCLISystemMessage(message) &&
|
|
466
|
+
!isCLIResultMessage(message) &&
|
|
467
|
+
!isCLIPartialAssistantMessage(message)) {
|
|
468
|
+
console.error('[Session] Unknown message type:', JSON.stringify(message, null, 2));
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
if (this.isShuttingDown) {
|
|
472
|
+
break;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
catch (streamError) {
|
|
477
|
+
if (this.debugMode) {
|
|
478
|
+
console.error('[Session] Stream reading error:', streamError);
|
|
479
|
+
}
|
|
480
|
+
throw streamError;
|
|
481
|
+
}
|
|
482
|
+
// Stream ended - wait for all pending work before shutdown
|
|
483
|
+
await this.waitForAllPendingWork();
|
|
484
|
+
await this.shutdown();
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
if (this.debugMode) {
|
|
488
|
+
console.error('[Session] Error:', error);
|
|
489
|
+
}
|
|
490
|
+
await this.shutdown();
|
|
491
|
+
throw error;
|
|
492
|
+
}
|
|
493
|
+
finally {
|
|
494
|
+
this.cleanupSignalHandlers();
|
|
495
|
+
}
|
|
496
|
+
}
|
|
494
497
|
}
|
|
495
498
|
function extractUserMessageText(message) {
|
|
496
499
|
const content = message.message.content;
|
|
@@ -513,19 +516,12 @@ function extractUserMessageText(message) {
|
|
|
513
516
|
}
|
|
514
517
|
return null;
|
|
515
518
|
}
|
|
516
|
-
/**
|
|
517
|
-
* Entry point for stream-json mode
|
|
518
|
-
*
|
|
519
|
-
* @param config - Configuration object
|
|
520
|
-
* @param input - Optional initial prompt input to process before reading from stream
|
|
521
|
-
*/
|
|
522
519
|
export async function runNonInteractiveStreamJson(config, input) {
|
|
523
520
|
const consolePatcher = new ConsolePatcher({
|
|
524
521
|
debugMode: config.getDebugMode(),
|
|
525
522
|
});
|
|
526
523
|
consolePatcher.patch();
|
|
527
524
|
try {
|
|
528
|
-
// Create initial user message from prompt input if provided
|
|
529
525
|
let initialPrompt = undefined;
|
|
530
526
|
if (input && input.trim().length > 0) {
|
|
531
527
|
const sessionId = config.getSessionId();
|
|
@@ -539,7 +535,7 @@ export async function runNonInteractiveStreamJson(config, input) {
|
|
|
539
535
|
parent_tool_use_id: null,
|
|
540
536
|
};
|
|
541
537
|
}
|
|
542
|
-
const manager = new
|
|
538
|
+
const manager = new Session(config, initialPrompt);
|
|
543
539
|
await manager.run();
|
|
544
540
|
}
|
|
545
541
|
finally {
|