@umsai/ums-code 0.3.0-v1 → 0.5.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 +4 -4
- package/dist/src/{zed-integration → acp-integration}/acp.d.ts +7 -0
- package/dist/src/{zed-integration → acp-integration}/acp.js +25 -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 +238 -0
- package/dist/src/acp-integration/acpAgent.js.map +1 -0
- package/dist/src/{zed-integration → acp-integration}/schema.d.ts +1030 -43
- package/dist/src/{zed-integration → acp-integration}/schema.js +81 -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/acp-integration/service/filesystem.test.d.ts +6 -0
- 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 +66 -0
- package/dist/src/acp-integration/session/Session.js +760 -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/config/auth.d.ts +1 -0
- package/dist/src/config/auth.js +3 -0
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/config.d.ts +11 -3
- package/dist/src/config/config.js +84 -8
- 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/settingsSchema.d.ts +12 -0
- package/dist/src/config/settingsSchema.js +10 -0
- 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/gemini.js +38 -18
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +7 -0
- package/dist/src/gemini.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/i18n/index.d.ts +1 -1
- package/dist/src/i18n/index.js +4 -0
- package/dist/src/i18n/index.js.map +1 -1
- package/dist/src/i18n/locales/en.js +1 -13
- package/dist/src/i18n/locales/ru.js +1121 -0
- package/dist/src/i18n/locales/zh.js +1 -10
- 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 +189 -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 +54 -2
- package/dist/src/nonInteractive/io/BaseJsonOutputAdapter.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 +25 -46
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.js +5 -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/test-utils/mockCommandContext.js +11 -2
- package/dist/src/test-utils/mockCommandContext.js.map +1 -1
- package/dist/src/ui/AppContainer.js +39 -36
- package/dist/src/ui/AppContainer.js.map +1 -1
- package/dist/src/ui/auth/useAuth.js +20 -1
- package/dist/src/ui/auth/useAuth.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/languageCommand.js +41 -8
- 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 +463 -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/reviewCommand.d.ts +9 -0
- package/dist/src/ui/commands/reviewCommand.js +1267 -0
- package/dist/src/ui/commands/reviewCommand.js.map +1 -0
- package/dist/src/ui/commands/reviewCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/reviewCommand.test.js +545 -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/types.d.ts +4 -9
- 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 +3 -19
- 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/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/ResumeSessionPicker.d.ts +10 -0
- package/dist/src/ui/components/ResumeSessionPicker.js +249 -0
- package/dist/src/ui/components/ResumeSessionPicker.js.map +1 -0
- package/dist/src/ui/components/SessionSummaryDisplay.js +10 -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/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 +23 -3
- 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/UIStateContext.d.ts +1 -3
- package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.d.ts +2 -8
- package/dist/src/ui/hooks/slashCommandProcessor.js +68 -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 +49 -9
- package/dist/src/ui/hooks/useGeminiStream.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/useReactToolScheduler.js +2 -2
- package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
- 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 +1 -0
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/models/availableModels.d.ts +8 -2
- package/dist/src/ui/models/availableModels.js +24 -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 +263 -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 +248 -0
- package/dist/src/ui/utils/resumeHistoryUtils.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/gitUtils.js +3 -3
- package/dist/src/utils/gitUtils.js.map +1 -1
- package/dist/src/utils/nonInteractiveHelpers.js +1 -1
- package/dist/src/utils/nonInteractiveHelpers.js.map +1 -1
- package/dist/src/utils/nonInteractiveHelpers.test.js +1 -1
- package/dist/src/utils/nonInteractiveHelpers.test.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.js +1 -1
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- 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/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/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
|
@@ -62,8 +62,9 @@ function getCurrentLlmOutputLanguage() {
|
|
|
62
62
|
if (fs.existsSync(filePath)) {
|
|
63
63
|
try {
|
|
64
64
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
65
|
-
// Extract language name from the first line
|
|
66
|
-
|
|
65
|
+
// Extract language name from the first line
|
|
66
|
+
// Template format: "# CRITICAL: Chinese Output Language Rule - HIGHEST PRIORITY"
|
|
67
|
+
const match = content.match(/^#.*?(\w+)\s+Output Language Rule/i);
|
|
67
68
|
if (match) {
|
|
68
69
|
return match[1];
|
|
69
70
|
}
|
|
@@ -104,12 +105,13 @@ async function setUiLanguage(context, lang) {
|
|
|
104
105
|
const langDisplayNames = {
|
|
105
106
|
zh: '中文(zh-CN)',
|
|
106
107
|
en: 'English(en-US)',
|
|
108
|
+
ru: 'Русский (ru-RU)',
|
|
107
109
|
};
|
|
108
110
|
return {
|
|
109
111
|
type: 'message',
|
|
110
112
|
messageType: 'info',
|
|
111
113
|
content: t('UI language changed to {{lang}}', {
|
|
112
|
-
lang: langDisplayNames[lang],
|
|
114
|
+
lang: langDisplayNames[lang] || lang,
|
|
113
115
|
}),
|
|
114
116
|
};
|
|
115
117
|
}
|
|
@@ -174,7 +176,7 @@ export const languageCommand = {
|
|
|
174
176
|
: t('LLM output language not set'),
|
|
175
177
|
'',
|
|
176
178
|
t('Available subcommands:'),
|
|
177
|
-
` /language ui [zh-CN|en-US] - ${t('Set UI language')}`,
|
|
179
|
+
` /language ui [zh-CN|en-US|ru-RU] - ${t('Set UI language')}`,
|
|
178
180
|
` /language output <language> - ${t('Set LLM output language')}`,
|
|
179
181
|
].join('\n');
|
|
180
182
|
return {
|
|
@@ -187,7 +189,7 @@ export const languageCommand = {
|
|
|
187
189
|
const parts = trimmedArgs.split(/\s+/);
|
|
188
190
|
const subcommand = parts[0].toLowerCase();
|
|
189
191
|
if (subcommand === 'ui') {
|
|
190
|
-
// Handle /language ui [zh-CN|en-US]
|
|
192
|
+
// Handle /language ui [zh-CN|en-US|ru-RU]
|
|
191
193
|
if (parts.length === 1) {
|
|
192
194
|
// Show UI language subcommand help
|
|
193
195
|
return {
|
|
@@ -196,11 +198,12 @@ export const languageCommand = {
|
|
|
196
198
|
content: [
|
|
197
199
|
t('Set UI language'),
|
|
198
200
|
'',
|
|
199
|
-
t('Usage: /language ui [zh-CN|en-US]'),
|
|
201
|
+
t('Usage: /language ui [zh-CN|en-US|ru-RU]'),
|
|
200
202
|
'',
|
|
201
203
|
t('Available options:'),
|
|
202
204
|
t(' - zh-CN: Simplified Chinese'),
|
|
203
205
|
t(' - en-US: English'),
|
|
206
|
+
t(' - ru-RU: Russian'),
|
|
204
207
|
'',
|
|
205
208
|
t('To request additional UI language packs, please open an issue on GitHub.'),
|
|
206
209
|
].join('\n'),
|
|
@@ -217,11 +220,17 @@ export const languageCommand = {
|
|
|
217
220
|
langArg === 'zh-cn') {
|
|
218
221
|
targetLang = 'zh';
|
|
219
222
|
}
|
|
223
|
+
else if (langArg === 'ru' ||
|
|
224
|
+
langArg === 'ru-RU' ||
|
|
225
|
+
langArg === 'russian' ||
|
|
226
|
+
langArg === 'русский') {
|
|
227
|
+
targetLang = 'ru';
|
|
228
|
+
}
|
|
220
229
|
else {
|
|
221
230
|
return {
|
|
222
231
|
type: 'message',
|
|
223
232
|
messageType: 'error',
|
|
224
|
-
content: t('Invalid language. Available: en-US, zh-CN'),
|
|
233
|
+
content: t('Invalid language. Available: en-US, zh-CN, ru-RU'),
|
|
225
234
|
};
|
|
226
235
|
}
|
|
227
236
|
return setUiLanguage(context, targetLang);
|
|
@@ -257,13 +266,19 @@ export const languageCommand = {
|
|
|
257
266
|
langArg === 'zh-cn') {
|
|
258
267
|
targetLang = 'zh';
|
|
259
268
|
}
|
|
269
|
+
else if (langArg === 'ru' ||
|
|
270
|
+
langArg === 'ru-RU' ||
|
|
271
|
+
langArg === 'russian' ||
|
|
272
|
+
langArg === 'русский') {
|
|
273
|
+
targetLang = 'ru';
|
|
274
|
+
}
|
|
260
275
|
else {
|
|
261
276
|
return {
|
|
262
277
|
type: 'message',
|
|
263
278
|
messageType: 'error',
|
|
264
279
|
content: [
|
|
265
280
|
t('Invalid command. Available subcommands:'),
|
|
266
|
-
' - /language ui [zh-CN|en-US] - ' + t('Set UI language'),
|
|
281
|
+
' - /language ui [zh-CN|en-US|ru-RU] - ' + t('Set UI language'),
|
|
267
282
|
' - /language output <language> - ' + t('Set LLM output language'),
|
|
268
283
|
].join('\n'),
|
|
269
284
|
};
|
|
@@ -354,6 +369,24 @@ export const languageCommand = {
|
|
|
354
369
|
return setUiLanguage(context, 'en');
|
|
355
370
|
},
|
|
356
371
|
},
|
|
372
|
+
{
|
|
373
|
+
name: 'ru-RU',
|
|
374
|
+
altNames: ['ru', 'russian', 'русский'],
|
|
375
|
+
get description() {
|
|
376
|
+
return t('Set UI language to Russian (ru-RU)');
|
|
377
|
+
},
|
|
378
|
+
kind: CommandKind.BUILT_IN,
|
|
379
|
+
action: async (context, args) => {
|
|
380
|
+
if (args.trim().length > 0) {
|
|
381
|
+
return {
|
|
382
|
+
type: 'message',
|
|
383
|
+
messageType: 'error',
|
|
384
|
+
content: t('Language subcommands do not accept additional arguments.'),
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
return setUiLanguage(context, 'ru');
|
|
388
|
+
},
|
|
389
|
+
},
|
|
357
390
|
],
|
|
358
391
|
},
|
|
359
392
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"languageCommand.js","sourceRoot":"","sources":["../../../../src/ui/commands/languageCommand.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAElB,CAAC,GACF,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,MAAM,iCAAiC,GAAG,oBAAoB,CAAC;AAE/D;;GAEG;AACH,SAAS,6BAA6B,CAAC,QAAgB;IACrD,OAAO,kBAAkB,QAAQ;;;;wBAIX,QAAQ,CAAC,WAAW,EAAE;;yLAE2I,QAAQ,CAAC,WAAW,EAAE;;qBAE1L,QAAQ;;;;wKAI2I,QAAQ;;;;;gCAKhJ,QAAQ,wBAAwB,QAAQ;4CAC5B,QAAQ;4BACxB,QAAQ;;;;;;;;;;2DAUuB,QAAQ;;oDAEf,QAAQ,CAAC,WAAW,EAAE;CACzE,CAAC;AACF,CAAC;AAED;;GAEG;AACH,SAAS,4BAA4B;IACnC,OAAO,IAAI,CAAC,IAAI,CACd,OAAO,CAAC,gBAAgB,EAAE,EAC1B,iCAAiC,CAClC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,2BAA2B;IAClC,MAAM,QAAQ,GAAG,4BAA4B,EAAE,CAAC;IAChD,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnD,
|
|
1
|
+
{"version":3,"file":"languageCommand.js","sourceRoot":"","sources":["../../../../src/ui/commands/languageCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Qwen
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
import { CommandKind } from './types.js';
|
|
9
|
+
import { createMockCommandContext } from '../../test-utils/mockCommandContext.js';
|
|
10
|
+
// Mock i18n module
|
|
11
|
+
vi.mock('../../i18n/index.js', () => ({
|
|
12
|
+
setLanguageAsync: vi.fn().mockResolvedValue(undefined),
|
|
13
|
+
getCurrentLanguage: vi.fn().mockReturnValue('en'),
|
|
14
|
+
t: vi.fn((key) => key),
|
|
15
|
+
}));
|
|
16
|
+
// Mock settings module to avoid Storage side effect
|
|
17
|
+
vi.mock('../../config/settings.js', () => ({
|
|
18
|
+
SettingScope: {
|
|
19
|
+
User: 'user',
|
|
20
|
+
Workspace: 'workspace',
|
|
21
|
+
Default: 'default',
|
|
22
|
+
},
|
|
23
|
+
}));
|
|
24
|
+
// Mock fs module
|
|
25
|
+
vi.mock('node:fs', async (importOriginal) => {
|
|
26
|
+
const actual = await importOriginal();
|
|
27
|
+
return {
|
|
28
|
+
...actual,
|
|
29
|
+
existsSync: vi.fn(),
|
|
30
|
+
readFileSync: vi.fn(),
|
|
31
|
+
writeFileSync: vi.fn(),
|
|
32
|
+
mkdirSync: vi.fn(),
|
|
33
|
+
default: {
|
|
34
|
+
...actual,
|
|
35
|
+
existsSync: vi.fn(),
|
|
36
|
+
readFileSync: vi.fn(),
|
|
37
|
+
writeFileSync: vi.fn(),
|
|
38
|
+
mkdirSync: vi.fn(),
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
// Mock Storage from core
|
|
43
|
+
vi.mock('@umsai/ums-code-core', async (importOriginal) => {
|
|
44
|
+
const actual = await importOriginal();
|
|
45
|
+
return {
|
|
46
|
+
...actual,
|
|
47
|
+
Storage: {
|
|
48
|
+
getGlobalQwenDir: vi.fn().mockReturnValue('/mock/.qwen'),
|
|
49
|
+
getGlobalSettingsPath: vi.fn().mockReturnValue('/mock/.qwen/settings.json'),
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
// Import modules after mocking
|
|
54
|
+
import * as i18n from '../../i18n/index.js';
|
|
55
|
+
import { languageCommand } from './languageCommand.js';
|
|
56
|
+
describe('languageCommand', () => {
|
|
57
|
+
let mockContext;
|
|
58
|
+
beforeEach(() => {
|
|
59
|
+
vi.clearAllMocks();
|
|
60
|
+
mockContext = createMockCommandContext({
|
|
61
|
+
services: {
|
|
62
|
+
config: {
|
|
63
|
+
getModel: vi.fn().mockReturnValue('test-model'),
|
|
64
|
+
},
|
|
65
|
+
settings: {
|
|
66
|
+
merged: {},
|
|
67
|
+
setValue: vi.fn(),
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
// Reset i18n mocks
|
|
72
|
+
vi.mocked(i18n.getCurrentLanguage).mockReturnValue('en');
|
|
73
|
+
vi.mocked(i18n.t).mockImplementation((key) => key);
|
|
74
|
+
// Reset fs mocks
|
|
75
|
+
vi.mocked(fs.existsSync).mockReturnValue(false);
|
|
76
|
+
});
|
|
77
|
+
afterEach(() => {
|
|
78
|
+
vi.clearAllMocks();
|
|
79
|
+
});
|
|
80
|
+
describe('command metadata', () => {
|
|
81
|
+
it('should have the correct name', () => {
|
|
82
|
+
expect(languageCommand.name).toBe('language');
|
|
83
|
+
});
|
|
84
|
+
it('should have a description', () => {
|
|
85
|
+
expect(languageCommand.description).toBeDefined();
|
|
86
|
+
expect(typeof languageCommand.description).toBe('string');
|
|
87
|
+
});
|
|
88
|
+
it('should be a built-in command', () => {
|
|
89
|
+
expect(languageCommand.kind).toBe(CommandKind.BUILT_IN);
|
|
90
|
+
});
|
|
91
|
+
it('should have subcommands', () => {
|
|
92
|
+
expect(languageCommand.subCommands).toBeDefined();
|
|
93
|
+
expect(languageCommand.subCommands?.length).toBe(2);
|
|
94
|
+
});
|
|
95
|
+
it('should have ui and output subcommands', () => {
|
|
96
|
+
const subCommandNames = languageCommand.subCommands?.map((c) => c.name);
|
|
97
|
+
expect(subCommandNames).toContain('ui');
|
|
98
|
+
expect(subCommandNames).toContain('output');
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe('main command action - no arguments', () => {
|
|
102
|
+
it('should show current language settings when no arguments provided', async () => {
|
|
103
|
+
if (!languageCommand.action) {
|
|
104
|
+
throw new Error('The language command must have an action.');
|
|
105
|
+
}
|
|
106
|
+
const result = await languageCommand.action(mockContext, '');
|
|
107
|
+
expect(result).toEqual({
|
|
108
|
+
type: 'message',
|
|
109
|
+
messageType: 'info',
|
|
110
|
+
content: expect.stringContaining('Current UI language:'),
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
it('should show available subcommands in help', async () => {
|
|
114
|
+
if (!languageCommand.action) {
|
|
115
|
+
throw new Error('The language command must have an action.');
|
|
116
|
+
}
|
|
117
|
+
const result = await languageCommand.action(mockContext, '');
|
|
118
|
+
expect(result).toEqual({
|
|
119
|
+
type: 'message',
|
|
120
|
+
messageType: 'info',
|
|
121
|
+
content: expect.stringContaining('/language ui'),
|
|
122
|
+
});
|
|
123
|
+
expect(result).toEqual({
|
|
124
|
+
type: 'message',
|
|
125
|
+
messageType: 'info',
|
|
126
|
+
content: expect.stringContaining('/language output'),
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
it('should show LLM output language when set', async () => {
|
|
130
|
+
vi.mocked(fs.existsSync).mockReturnValue(true);
|
|
131
|
+
vi.mocked(fs.readFileSync).mockReturnValue('# CRITICAL: Chinese Output Language Rule - HIGHEST PRIORITY');
|
|
132
|
+
// Make t() function handle interpolation for this test
|
|
133
|
+
vi.mocked(i18n.t).mockImplementation((key, params) => {
|
|
134
|
+
if (params && key.includes('{{lang}}')) {
|
|
135
|
+
return key.replace('{{lang}}', params['lang'] || '');
|
|
136
|
+
}
|
|
137
|
+
return key;
|
|
138
|
+
});
|
|
139
|
+
if (!languageCommand.action) {
|
|
140
|
+
throw new Error('The language command must have an action.');
|
|
141
|
+
}
|
|
142
|
+
const result = await languageCommand.action(mockContext, '');
|
|
143
|
+
expect(result).toEqual({
|
|
144
|
+
type: 'message',
|
|
145
|
+
messageType: 'info',
|
|
146
|
+
content: expect.stringContaining('Current UI language:'),
|
|
147
|
+
});
|
|
148
|
+
// Verify it correctly parses "Chinese" from the template format
|
|
149
|
+
expect(result).toEqual({
|
|
150
|
+
type: 'message',
|
|
151
|
+
messageType: 'info',
|
|
152
|
+
content: expect.stringContaining('Chinese'),
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
describe('main command action - config not available', () => {
|
|
157
|
+
it('should return error when config is null', async () => {
|
|
158
|
+
mockContext.services.config = null;
|
|
159
|
+
if (!languageCommand.action) {
|
|
160
|
+
throw new Error('The language command must have an action.');
|
|
161
|
+
}
|
|
162
|
+
const result = await languageCommand.action(mockContext, '');
|
|
163
|
+
expect(result).toEqual({
|
|
164
|
+
type: 'message',
|
|
165
|
+
messageType: 'error',
|
|
166
|
+
content: expect.stringContaining('Configuration not available'),
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
describe('/language ui subcommand', () => {
|
|
171
|
+
it('should show help when no language argument provided', async () => {
|
|
172
|
+
if (!languageCommand.action) {
|
|
173
|
+
throw new Error('The language command must have an action.');
|
|
174
|
+
}
|
|
175
|
+
const result = await languageCommand.action(mockContext, 'ui');
|
|
176
|
+
expect(result).toEqual({
|
|
177
|
+
type: 'message',
|
|
178
|
+
messageType: 'info',
|
|
179
|
+
content: expect.stringContaining('Usage: /language ui'),
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
it('should set English with "en"', async () => {
|
|
183
|
+
if (!languageCommand.action) {
|
|
184
|
+
throw new Error('The language command must have an action.');
|
|
185
|
+
}
|
|
186
|
+
const result = await languageCommand.action(mockContext, 'ui en');
|
|
187
|
+
expect(i18n.setLanguageAsync).toHaveBeenCalledWith('en');
|
|
188
|
+
expect(mockContext.services.settings.setValue).toHaveBeenCalled();
|
|
189
|
+
expect(mockContext.ui.reloadCommands).toHaveBeenCalled();
|
|
190
|
+
expect(result).toEqual({
|
|
191
|
+
type: 'message',
|
|
192
|
+
messageType: 'info',
|
|
193
|
+
content: expect.stringContaining('UI language changed'),
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
it('should set English with "en-US"', async () => {
|
|
197
|
+
if (!languageCommand.action) {
|
|
198
|
+
throw new Error('The language command must have an action.');
|
|
199
|
+
}
|
|
200
|
+
const result = await languageCommand.action(mockContext, 'ui en-US');
|
|
201
|
+
expect(i18n.setLanguageAsync).toHaveBeenCalledWith('en');
|
|
202
|
+
expect(result).toEqual({
|
|
203
|
+
type: 'message',
|
|
204
|
+
messageType: 'info',
|
|
205
|
+
content: expect.stringContaining('UI language changed'),
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
it('should set English with "english"', async () => {
|
|
209
|
+
if (!languageCommand.action) {
|
|
210
|
+
throw new Error('The language command must have an action.');
|
|
211
|
+
}
|
|
212
|
+
const result = await languageCommand.action(mockContext, 'ui english');
|
|
213
|
+
expect(i18n.setLanguageAsync).toHaveBeenCalledWith('en');
|
|
214
|
+
expect(result).toEqual({
|
|
215
|
+
type: 'message',
|
|
216
|
+
messageType: 'info',
|
|
217
|
+
content: expect.stringContaining('UI language changed'),
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
it('should set Chinese with "zh"', async () => {
|
|
221
|
+
if (!languageCommand.action) {
|
|
222
|
+
throw new Error('The language command must have an action.');
|
|
223
|
+
}
|
|
224
|
+
const result = await languageCommand.action(mockContext, 'ui zh');
|
|
225
|
+
expect(i18n.setLanguageAsync).toHaveBeenCalledWith('zh');
|
|
226
|
+
expect(result).toEqual({
|
|
227
|
+
type: 'message',
|
|
228
|
+
messageType: 'info',
|
|
229
|
+
content: expect.stringContaining('UI language changed'),
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
it('should set Chinese with "zh-CN"', async () => {
|
|
233
|
+
if (!languageCommand.action) {
|
|
234
|
+
throw new Error('The language command must have an action.');
|
|
235
|
+
}
|
|
236
|
+
const result = await languageCommand.action(mockContext, 'ui zh-CN');
|
|
237
|
+
expect(i18n.setLanguageAsync).toHaveBeenCalledWith('zh');
|
|
238
|
+
expect(result).toEqual({
|
|
239
|
+
type: 'message',
|
|
240
|
+
messageType: 'info',
|
|
241
|
+
content: expect.stringContaining('UI language changed'),
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
it('should set Chinese with "chinese"', async () => {
|
|
245
|
+
if (!languageCommand.action) {
|
|
246
|
+
throw new Error('The language command must have an action.');
|
|
247
|
+
}
|
|
248
|
+
const result = await languageCommand.action(mockContext, 'ui chinese');
|
|
249
|
+
expect(i18n.setLanguageAsync).toHaveBeenCalledWith('zh');
|
|
250
|
+
expect(result).toEqual({
|
|
251
|
+
type: 'message',
|
|
252
|
+
messageType: 'info',
|
|
253
|
+
content: expect.stringContaining('UI language changed'),
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
it('should return error for invalid language', async () => {
|
|
257
|
+
if (!languageCommand.action) {
|
|
258
|
+
throw new Error('The language command must have an action.');
|
|
259
|
+
}
|
|
260
|
+
const result = await languageCommand.action(mockContext, 'ui invalid');
|
|
261
|
+
expect(i18n.setLanguageAsync).not.toHaveBeenCalled();
|
|
262
|
+
expect(result).toEqual({
|
|
263
|
+
type: 'message',
|
|
264
|
+
messageType: 'error',
|
|
265
|
+
content: expect.stringContaining('Invalid language'),
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
it('should persist setting to user scope', async () => {
|
|
269
|
+
if (!languageCommand.action) {
|
|
270
|
+
throw new Error('The language command must have an action.');
|
|
271
|
+
}
|
|
272
|
+
await languageCommand.action(mockContext, 'ui en');
|
|
273
|
+
expect(mockContext.services.settings.setValue).toHaveBeenCalledWith(expect.anything(), // SettingScope.User
|
|
274
|
+
'general.language', 'en');
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
describe('/language output subcommand', () => {
|
|
278
|
+
it('should show help when no language argument provided', async () => {
|
|
279
|
+
if (!languageCommand.action) {
|
|
280
|
+
throw new Error('The language command must have an action.');
|
|
281
|
+
}
|
|
282
|
+
const result = await languageCommand.action(mockContext, 'output');
|
|
283
|
+
expect(result).toEqual({
|
|
284
|
+
type: 'message',
|
|
285
|
+
messageType: 'info',
|
|
286
|
+
content: expect.stringContaining('Usage: /language output'),
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
it('should create LLM output language rule file', async () => {
|
|
290
|
+
if (!languageCommand.action) {
|
|
291
|
+
throw new Error('The language command must have an action.');
|
|
292
|
+
}
|
|
293
|
+
const result = await languageCommand.action(mockContext, 'output Chinese');
|
|
294
|
+
expect(fs.mkdirSync).toHaveBeenCalled();
|
|
295
|
+
expect(fs.writeFileSync).toHaveBeenCalledWith(expect.stringContaining('output-language.md'), expect.stringContaining('Chinese'), 'utf-8');
|
|
296
|
+
expect(result).toEqual({
|
|
297
|
+
type: 'message',
|
|
298
|
+
messageType: 'info',
|
|
299
|
+
content: expect.stringContaining('LLM output language rule file generated'),
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
it('should include restart notice in success message', async () => {
|
|
303
|
+
if (!languageCommand.action) {
|
|
304
|
+
throw new Error('The language command must have an action.');
|
|
305
|
+
}
|
|
306
|
+
const result = await languageCommand.action(mockContext, 'output Japanese');
|
|
307
|
+
expect(result).toEqual({
|
|
308
|
+
type: 'message',
|
|
309
|
+
messageType: 'info',
|
|
310
|
+
content: expect.stringContaining('restart'),
|
|
311
|
+
});
|
|
312
|
+
});
|
|
313
|
+
it('should handle file write errors gracefully', async () => {
|
|
314
|
+
vi.mocked(fs.writeFileSync).mockImplementation(() => {
|
|
315
|
+
throw new Error('Permission denied');
|
|
316
|
+
});
|
|
317
|
+
if (!languageCommand.action) {
|
|
318
|
+
throw new Error('The language command must have an action.');
|
|
319
|
+
}
|
|
320
|
+
const result = await languageCommand.action(mockContext, 'output German');
|
|
321
|
+
expect(result).toEqual({
|
|
322
|
+
type: 'message',
|
|
323
|
+
messageType: 'error',
|
|
324
|
+
content: expect.stringContaining('Failed to generate'),
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
describe('backward compatibility - direct language arguments', () => {
|
|
329
|
+
it('should set Chinese with direct "zh" argument', async () => {
|
|
330
|
+
if (!languageCommand.action) {
|
|
331
|
+
throw new Error('The language command must have an action.');
|
|
332
|
+
}
|
|
333
|
+
const result = await languageCommand.action(mockContext, 'zh');
|
|
334
|
+
expect(i18n.setLanguageAsync).toHaveBeenCalledWith('zh');
|
|
335
|
+
expect(result).toEqual({
|
|
336
|
+
type: 'message',
|
|
337
|
+
messageType: 'info',
|
|
338
|
+
content: expect.stringContaining('UI language changed'),
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
it('should set English with direct "en" argument', async () => {
|
|
342
|
+
if (!languageCommand.action) {
|
|
343
|
+
throw new Error('The language command must have an action.');
|
|
344
|
+
}
|
|
345
|
+
const result = await languageCommand.action(mockContext, 'en');
|
|
346
|
+
expect(i18n.setLanguageAsync).toHaveBeenCalledWith('en');
|
|
347
|
+
expect(result).toEqual({
|
|
348
|
+
type: 'message',
|
|
349
|
+
messageType: 'info',
|
|
350
|
+
content: expect.stringContaining('UI language changed'),
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
it('should return error for unknown direct argument', async () => {
|
|
354
|
+
if (!languageCommand.action) {
|
|
355
|
+
throw new Error('The language command must have an action.');
|
|
356
|
+
}
|
|
357
|
+
const result = await languageCommand.action(mockContext, 'unknown');
|
|
358
|
+
expect(i18n.setLanguageAsync).not.toHaveBeenCalled();
|
|
359
|
+
expect(result).toEqual({
|
|
360
|
+
type: 'message',
|
|
361
|
+
messageType: 'error',
|
|
362
|
+
content: expect.stringContaining('Invalid command'),
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
describe('ui subcommand object', () => {
|
|
367
|
+
const uiSubcommand = languageCommand.subCommands?.find((c) => c.name === 'ui');
|
|
368
|
+
it('should have correct metadata', () => {
|
|
369
|
+
expect(uiSubcommand).toBeDefined();
|
|
370
|
+
expect(uiSubcommand?.name).toBe('ui');
|
|
371
|
+
expect(uiSubcommand?.kind).toBe(CommandKind.BUILT_IN);
|
|
372
|
+
});
|
|
373
|
+
it('should have nested language subcommands', () => {
|
|
374
|
+
const nestedNames = uiSubcommand?.subCommands?.map((c) => c.name);
|
|
375
|
+
expect(nestedNames).toContain('zh-CN');
|
|
376
|
+
expect(nestedNames).toContain('en-US');
|
|
377
|
+
});
|
|
378
|
+
it('should have action that sets language', async () => {
|
|
379
|
+
if (!uiSubcommand?.action) {
|
|
380
|
+
throw new Error('UI subcommand must have an action.');
|
|
381
|
+
}
|
|
382
|
+
const result = await uiSubcommand.action(mockContext, 'en');
|
|
383
|
+
expect(i18n.setLanguageAsync).toHaveBeenCalledWith('en');
|
|
384
|
+
expect(result).toEqual({
|
|
385
|
+
type: 'message',
|
|
386
|
+
messageType: 'info',
|
|
387
|
+
content: expect.stringContaining('UI language changed'),
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
});
|
|
391
|
+
describe('output subcommand object', () => {
|
|
392
|
+
const outputSubcommand = languageCommand.subCommands?.find((c) => c.name === 'output');
|
|
393
|
+
it('should have correct metadata', () => {
|
|
394
|
+
expect(outputSubcommand).toBeDefined();
|
|
395
|
+
expect(outputSubcommand?.name).toBe('output');
|
|
396
|
+
expect(outputSubcommand?.kind).toBe(CommandKind.BUILT_IN);
|
|
397
|
+
});
|
|
398
|
+
it('should have action that generates rule file', async () => {
|
|
399
|
+
if (!outputSubcommand?.action) {
|
|
400
|
+
throw new Error('Output subcommand must have an action.');
|
|
401
|
+
}
|
|
402
|
+
// Ensure mocks are properly set for this test
|
|
403
|
+
vi.mocked(fs.mkdirSync).mockImplementation(() => undefined);
|
|
404
|
+
vi.mocked(fs.writeFileSync).mockImplementation(() => undefined);
|
|
405
|
+
const result = await outputSubcommand.action(mockContext, 'French');
|
|
406
|
+
expect(fs.writeFileSync).toHaveBeenCalled();
|
|
407
|
+
expect(result).toEqual({
|
|
408
|
+
type: 'message',
|
|
409
|
+
messageType: 'info',
|
|
410
|
+
content: expect.stringContaining('LLM output language rule file generated'),
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
describe('nested ui language subcommands', () => {
|
|
415
|
+
const uiSubcommand = languageCommand.subCommands?.find((c) => c.name === 'ui');
|
|
416
|
+
const zhCNSubcommand = uiSubcommand?.subCommands?.find((c) => c.name === 'zh-CN');
|
|
417
|
+
const enUSSubcommand = uiSubcommand?.subCommands?.find((c) => c.name === 'en-US');
|
|
418
|
+
it('zh-CN should have aliases', () => {
|
|
419
|
+
expect(zhCNSubcommand?.altNames).toContain('zh');
|
|
420
|
+
expect(zhCNSubcommand?.altNames).toContain('chinese');
|
|
421
|
+
});
|
|
422
|
+
it('en-US should have aliases', () => {
|
|
423
|
+
expect(enUSSubcommand?.altNames).toContain('en');
|
|
424
|
+
expect(enUSSubcommand?.altNames).toContain('english');
|
|
425
|
+
});
|
|
426
|
+
it('zh-CN action should set Chinese', async () => {
|
|
427
|
+
if (!zhCNSubcommand?.action) {
|
|
428
|
+
throw new Error('zh-CN subcommand must have an action.');
|
|
429
|
+
}
|
|
430
|
+
const result = await zhCNSubcommand.action(mockContext, '');
|
|
431
|
+
expect(i18n.setLanguageAsync).toHaveBeenCalledWith('zh');
|
|
432
|
+
expect(result).toEqual({
|
|
433
|
+
type: 'message',
|
|
434
|
+
messageType: 'info',
|
|
435
|
+
content: expect.stringContaining('UI language changed'),
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
it('en-US action should set English', async () => {
|
|
439
|
+
if (!enUSSubcommand?.action) {
|
|
440
|
+
throw new Error('en-US subcommand must have an action.');
|
|
441
|
+
}
|
|
442
|
+
const result = await enUSSubcommand.action(mockContext, '');
|
|
443
|
+
expect(i18n.setLanguageAsync).toHaveBeenCalledWith('en');
|
|
444
|
+
expect(result).toEqual({
|
|
445
|
+
type: 'message',
|
|
446
|
+
messageType: 'info',
|
|
447
|
+
content: expect.stringContaining('UI language changed'),
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
it('should reject extra arguments', async () => {
|
|
451
|
+
if (!zhCNSubcommand?.action) {
|
|
452
|
+
throw new Error('zh-CN subcommand must have an action.');
|
|
453
|
+
}
|
|
454
|
+
const result = await zhCNSubcommand.action(mockContext, 'extra args');
|
|
455
|
+
expect(result).toEqual({
|
|
456
|
+
type: 'message',
|
|
457
|
+
messageType: 'error',
|
|
458
|
+
content: expect.stringContaining('do not accept additional arguments'),
|
|
459
|
+
});
|
|
460
|
+
});
|
|
461
|
+
});
|
|
462
|
+
});
|
|
463
|
+
//# sourceMappingURL=languageCommand.test.js.map
|