mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-20 16:57:46 +00:00
feat: add i18n for /agents command
This commit is contained in:
@@ -95,12 +95,146 @@ export default {
|
||||
'Show quit confirmation dialog': 'Show quit confirmation dialog',
|
||||
'Copy the last result or code snippet to clipboard':
|
||||
'Copy the last result or code snippet to clipboard',
|
||||
|
||||
// ============================================================================
|
||||
// Commands - Agents
|
||||
// ============================================================================
|
||||
'Manage subagents for specialized task delegation.':
|
||||
'Manage subagents for specialized task delegation.',
|
||||
'Manage existing subagents (view, edit, delete).':
|
||||
'Manage existing subagents (view, edit, delete).',
|
||||
'Create a new subagent with guided setup.':
|
||||
'Create a new subagent with guided setup.',
|
||||
|
||||
// ============================================================================
|
||||
// Agents - Management Dialog
|
||||
// ============================================================================
|
||||
Agents: 'Agents',
|
||||
'Choose Action': 'Choose Action',
|
||||
'Edit {{name}}': 'Edit {{name}}',
|
||||
'Edit Tools: {{name}}': 'Edit Tools: {{name}}',
|
||||
'Edit Color: {{name}}': 'Edit Color: {{name}}',
|
||||
'Delete {{name}}': 'Delete {{name}}',
|
||||
'Unknown Step': 'Unknown Step',
|
||||
'Esc to close': 'Esc to close',
|
||||
'Enter to select, ↑↓ to navigate, Esc to close':
|
||||
'Enter to select, ↑↓ to navigate, Esc to close',
|
||||
'Esc to go back': 'Esc to go back',
|
||||
'Enter to confirm, Esc to cancel': 'Enter to confirm, Esc to cancel',
|
||||
'Enter to select, ↑↓ to navigate, Esc to go back':
|
||||
'Enter to select, ↑↓ to navigate, Esc to go back',
|
||||
'Invalid step: {{step}}': 'Invalid step: {{step}}',
|
||||
'No subagents found.': 'No subagents found.',
|
||||
"Use '/agents create' to create your first subagent.":
|
||||
"Use '/agents create' to create your first subagent.",
|
||||
'(built-in)': '(built-in)',
|
||||
'(overridden by project level agent)': '(overridden by project level agent)',
|
||||
'Project Level ({{path}})': 'Project Level ({{path}})',
|
||||
'User Level ({{path}})': 'User Level ({{path}})',
|
||||
'Built-in Agents': 'Built-in Agents',
|
||||
'Using: {{count}} agents': 'Using: {{count}} agents',
|
||||
'View Agent': 'View Agent',
|
||||
'Edit Agent': 'Edit Agent',
|
||||
'Delete Agent': 'Delete Agent',
|
||||
Back: 'Back',
|
||||
'No agent selected': 'No agent selected',
|
||||
'File Path: ': 'File Path: ',
|
||||
'Tools: ': 'Tools: ',
|
||||
'Color: ': 'Color: ',
|
||||
'Description:': 'Description:',
|
||||
'System Prompt:': 'System Prompt:',
|
||||
'Open in editor': 'Open in editor',
|
||||
'Edit tools': 'Edit tools',
|
||||
'Edit color': 'Edit color',
|
||||
'❌ Error:': '❌ Error:',
|
||||
'Are you sure you want to delete agent "{{name}}"?':
|
||||
'Are you sure you want to delete agent "{{name}}"?',
|
||||
// ============================================================================
|
||||
// Agents - Creation Wizard
|
||||
// ============================================================================
|
||||
'Project Level (.qwen/agents/)': 'Project Level (.qwen/agents/)',
|
||||
'User Level (~/.qwen/agents/)': 'User Level (~/.qwen/agents/)',
|
||||
'✅ Subagent Created Successfully!': '✅ Subagent Created Successfully!',
|
||||
'Subagent "{{name}}" has been saved to {{level}} level.':
|
||||
'Subagent "{{name}}" has been saved to {{level}} level.',
|
||||
'Name: ': 'Name: ',
|
||||
'Location: ': 'Location: ',
|
||||
'❌ Error saving subagent:': '❌ Error saving subagent:',
|
||||
'Warnings:': 'Warnings:',
|
||||
'Name "{{name}}" already exists at {{level}} level - will overwrite existing subagent':
|
||||
'Name "{{name}}" already exists at {{level}} level - will overwrite existing subagent',
|
||||
'Name "{{name}}" exists at user level - project level will take precedence':
|
||||
'Name "{{name}}" exists at user level - project level will take precedence',
|
||||
'Name "{{name}}" exists at project level - existing subagent will take precedence':
|
||||
'Name "{{name}}" exists at project level - existing subagent will take precedence',
|
||||
'Description is over {{length}} characters':
|
||||
'Description is over {{length}} characters',
|
||||
'System prompt is over {{length}} characters':
|
||||
'System prompt is over {{length}} characters',
|
||||
// Agents - Creation Wizard Steps
|
||||
'Step {{n}}: Choose Location': 'Step {{n}}: Choose Location',
|
||||
'Step {{n}}: Choose Generation Method':
|
||||
'Step {{n}}: Choose Generation Method',
|
||||
'Generate with Qwen Code (Recommended)':
|
||||
'Generate with Qwen Code (Recommended)',
|
||||
'Manual Creation': 'Manual Creation',
|
||||
'Describe what this subagent should do and when it should be used. (Be comprehensive for best results)':
|
||||
'Describe what this subagent should do and when it should be used. (Be comprehensive for best results)',
|
||||
'e.g., Expert code reviewer that reviews code based on best practices...':
|
||||
'e.g., Expert code reviewer that reviews code based on best practices...',
|
||||
'Generating subagent configuration...':
|
||||
'Generating subagent configuration...',
|
||||
'Failed to generate subagent: {{error}}':
|
||||
'Failed to generate subagent: {{error}}',
|
||||
'Step {{n}}: Describe Your Subagent': 'Step {{n}}: Describe Your Subagent',
|
||||
'Step {{n}}: Enter Subagent Name': 'Step {{n}}: Enter Subagent Name',
|
||||
'Step {{n}}: Enter System Prompt': 'Step {{n}}: Enter System Prompt',
|
||||
'Step {{n}}: Enter Description': 'Step {{n}}: Enter Description',
|
||||
// Agents - Tool Selection
|
||||
'Step {{n}}: Select Tools': 'Step {{n}}: Select Tools',
|
||||
'All Tools (Default)': 'All Tools (Default)',
|
||||
'All Tools': 'All Tools',
|
||||
'Read-only Tools': 'Read-only Tools',
|
||||
'Read & Edit Tools': 'Read & Edit Tools',
|
||||
'Read & Edit & Execution Tools': 'Read & Edit & Execution Tools',
|
||||
'All tools selected, including MCP tools':
|
||||
'All tools selected, including MCP tools',
|
||||
'Selected tools:': 'Selected tools:',
|
||||
'Read-only tools:': 'Read-only tools:',
|
||||
'Edit tools:': 'Edit tools:',
|
||||
'Execution tools:': 'Execution tools:',
|
||||
'Step {{n}}: Choose Background Color': 'Step {{n}}: Choose Background Color',
|
||||
'Step {{n}}: Confirm and Save': 'Step {{n}}: Confirm and Save',
|
||||
// Agents - Navigation & Instructions
|
||||
'Esc to cancel': 'Esc to cancel',
|
||||
'Press Enter to save, e to save and edit, Esc to go back':
|
||||
'Press Enter to save, e to save and edit, Esc to go back',
|
||||
'Press Enter to continue, {{navigation}}Esc to {{action}}':
|
||||
'Press Enter to continue, {{navigation}}Esc to {{action}}',
|
||||
cancel: 'cancel',
|
||||
'go back': 'go back',
|
||||
'↑↓ to navigate, ': '↑↓ to navigate, ',
|
||||
'Enter a clear, unique name for this subagent.':
|
||||
'Enter a clear, unique name for this subagent.',
|
||||
'e.g., Code Reviewer': 'e.g., Code Reviewer',
|
||||
'Name cannot be empty.': 'Name cannot be empty.',
|
||||
"Write the system prompt that defines this subagent's behavior. Be comprehensive for best results.":
|
||||
"Write the system prompt that defines this subagent's behavior. Be comprehensive for best results.",
|
||||
'e.g., You are an expert code reviewer...':
|
||||
'e.g., You are an expert code reviewer...',
|
||||
'System prompt cannot be empty.': 'System prompt cannot be empty.',
|
||||
'Describe when and how this subagent should be used.':
|
||||
'Describe when and how this subagent should be used.',
|
||||
'e.g., Reviews code for best practices and potential bugs.':
|
||||
'e.g., Reviews code for best practices and potential bugs.',
|
||||
'Description cannot be empty.': 'Description cannot be empty.',
|
||||
'Failed to launch editor: {{error}}': 'Failed to launch editor: {{error}}',
|
||||
'Failed to save and edit subagent: {{error}}':
|
||||
'Failed to save and edit subagent: {{error}}',
|
||||
|
||||
// ============================================================================
|
||||
// Commands - General (continued)
|
||||
// ============================================================================
|
||||
'View and edit Qwen Code settings': 'View and edit Qwen Code settings',
|
||||
'toggle vim mode on/off': 'toggle vim mode on/off',
|
||||
'check session stats. Usage: /stats [model|tools]':
|
||||
@@ -247,6 +381,9 @@ export default {
|
||||
'Workspace approval mode exists and takes priority. User-level change will have no effect.',
|
||||
'(Use Enter to select, Tab to change focus)':
|
||||
'(Use Enter to select, Tab to change focus)',
|
||||
'Apply To': 'Apply To',
|
||||
'User Settings': 'User Settings',
|
||||
'Workspace Settings': 'Workspace Settings',
|
||||
|
||||
// ============================================================================
|
||||
// Commands - Memory
|
||||
|
||||
@@ -93,11 +93,139 @@ export default {
|
||||
'Show quit confirmation dialog': '显示退出确认对话框',
|
||||
'Copy the last result or code snippet to clipboard':
|
||||
'将最后的结果或代码片段复制到剪贴板',
|
||||
|
||||
// ============================================================================
|
||||
// Commands - Agents
|
||||
// ============================================================================
|
||||
'Manage subagents for specialized task delegation.':
|
||||
'管理用于专门任务委派的子代理',
|
||||
'Manage existing subagents (view, edit, delete).':
|
||||
'管理现有子代理(查看、编辑、删除)',
|
||||
'Create a new subagent with guided setup.': '通过引导式设置创建新的子代理',
|
||||
|
||||
// ============================================================================
|
||||
// Agents - Management Dialog
|
||||
// ============================================================================
|
||||
Agents: '代理',
|
||||
'Choose Action': '选择操作',
|
||||
'Edit {{name}}': '编辑 {{name}}',
|
||||
'Edit Tools: {{name}}': '编辑工具: {{name}}',
|
||||
'Edit Color: {{name}}': '编辑颜色: {{name}}',
|
||||
'Delete {{name}}': '删除 {{name}}',
|
||||
'Unknown Step': '未知步骤',
|
||||
'Esc to close': '按 Esc 关闭',
|
||||
'Enter to select, ↑↓ to navigate, Esc to close':
|
||||
'Enter 选择,↑↓ 导航,Esc 关闭',
|
||||
'Esc to go back': '按 Esc 返回',
|
||||
'Enter to confirm, Esc to cancel': 'Enter 确认,Esc 取消',
|
||||
'Enter to select, ↑↓ to navigate, Esc to go back':
|
||||
'Enter 选择,↑↓ 导航,Esc 返回',
|
||||
'Invalid step: {{step}}': '无效步骤: {{step}}',
|
||||
'No subagents found.': '未找到子代理。',
|
||||
"Use '/agents create' to create your first subagent.":
|
||||
"使用 '/agents create' 创建您的第一个子代理。",
|
||||
'(built-in)': '(内置)',
|
||||
'(overridden by project level agent)': '(已被项目级代理覆盖)',
|
||||
'Project Level ({{path}})': '项目级 ({{path}})',
|
||||
'User Level ({{path}})': '用户级 ({{path}})',
|
||||
'Built-in Agents': '内置代理',
|
||||
'Using: {{count}} agents': '使用中: {{count}} 个代理',
|
||||
'View Agent': '查看代理',
|
||||
'Edit Agent': '编辑代理',
|
||||
'Delete Agent': '删除代理',
|
||||
Back: '返回',
|
||||
'No agent selected': '未选择代理',
|
||||
'File Path: ': '文件路径: ',
|
||||
'Tools: ': '工具: ',
|
||||
'Color: ': '颜色: ',
|
||||
'Description:': '描述:',
|
||||
'System Prompt:': '系统提示:',
|
||||
'Open in editor': '在编辑器中打开',
|
||||
'Edit tools': '编辑工具',
|
||||
'Edit color': '编辑颜色',
|
||||
'❌ Error:': '❌ 错误:',
|
||||
'Are you sure you want to delete agent "{{name}}"?':
|
||||
'您确定要删除代理 "{{name}}" 吗?',
|
||||
// ============================================================================
|
||||
// Agents - Creation Wizard
|
||||
// ============================================================================
|
||||
'Project Level (.qwen/agents/)': '项目级 (.qwen/agents/)',
|
||||
'User Level (~/.qwen/agents/)': '用户级 (~/.qwen/agents/)',
|
||||
'✅ Subagent Created Successfully!': '✅ 子代理创建成功!',
|
||||
'Subagent "{{name}}" has been saved to {{level}} level.':
|
||||
'子代理 "{{name}}" 已保存到 {{level}} 级别。',
|
||||
'Name: ': '名称: ',
|
||||
'Location: ': '位置: ',
|
||||
'❌ Error saving subagent:': '❌ 保存子代理时出错:',
|
||||
'Warnings:': '警告:',
|
||||
'Name "{{name}}" already exists at {{level}} level - will overwrite existing subagent':
|
||||
'名称 "{{name}}" 在 {{level}} 级别已存在 - 将覆盖现有子代理',
|
||||
'Name "{{name}}" exists at user level - project level will take precedence':
|
||||
'名称 "{{name}}" 在用户级别存在 - 项目级别将优先',
|
||||
'Name "{{name}}" exists at project level - existing subagent will take precedence':
|
||||
'名称 "{{name}}" 在项目级别存在 - 现有子代理将优先',
|
||||
'Description is over {{length}} characters': '描述超过 {{length}} 个字符',
|
||||
'System prompt is over {{length}} characters':
|
||||
'系统提示超过 {{length}} 个字符',
|
||||
// Agents - Creation Wizard Steps
|
||||
'Step {{n}}: Choose Location': '步骤 {{n}}: 选择位置',
|
||||
'Step {{n}}: Choose Generation Method': '步骤 {{n}}: 选择生成方式',
|
||||
'Generate with Qwen Code (Recommended)': '使用 Qwen Code 生成(推荐)',
|
||||
'Manual Creation': '手动创建',
|
||||
'Describe what this subagent should do and when it should be used. (Be comprehensive for best results)':
|
||||
'描述此子代理应该做什么以及何时使用它。(为了获得最佳效果,请全面描述)',
|
||||
'e.g., Expert code reviewer that reviews code based on best practices...':
|
||||
'例如:专业的代码审查员,根据最佳实践审查代码...',
|
||||
'Generating subagent configuration...': '正在生成子代理配置...',
|
||||
'Failed to generate subagent: {{error}}': '生成子代理失败: {{error}}',
|
||||
'Step {{n}}: Describe Your Subagent': '步骤 {{n}}: 描述您的子代理',
|
||||
'Step {{n}}: Enter Subagent Name': '步骤 {{n}}: 输入子代理名称',
|
||||
'Step {{n}}: Enter System Prompt': '步骤 {{n}}: 输入系统提示',
|
||||
'Step {{n}}: Enter Description': '步骤 {{n}}: 输入描述',
|
||||
// Agents - Tool Selection
|
||||
'Step {{n}}: Select Tools': '步骤 {{n}}: 选择工具',
|
||||
'All Tools (Default)': '所有工具(默认)',
|
||||
'All Tools': '所有工具',
|
||||
'Read-only Tools': '只读工具',
|
||||
'Read & Edit Tools': '读取和编辑工具',
|
||||
'Read & Edit & Execution Tools': '读取、编辑和执行工具',
|
||||
'All tools selected, including MCP tools': '已选择所有工具,包括 MCP 工具',
|
||||
'Selected tools:': '已选择的工具:',
|
||||
'Read-only tools:': '只读工具:',
|
||||
'Edit tools:': '编辑工具:',
|
||||
'Execution tools:': '执行工具:',
|
||||
'Step {{n}}: Choose Background Color': '步骤 {{n}}: 选择背景颜色',
|
||||
'Step {{n}}: Confirm and Save': '步骤 {{n}}: 确认并保存',
|
||||
// Agents - Navigation & Instructions
|
||||
'Esc to cancel': '按 Esc 取消',
|
||||
'Press Enter to save, e to save and edit, Esc to go back':
|
||||
'按 Enter 保存,e 保存并编辑,Esc 返回',
|
||||
'Press Enter to continue, {{navigation}}Esc to {{action}}':
|
||||
'按 Enter 继续,{{navigation}}Esc {{action}}',
|
||||
cancel: '取消',
|
||||
'go back': '返回',
|
||||
'↑↓ to navigate, ': '↑↓ 导航,',
|
||||
'Enter a clear, unique name for this subagent.':
|
||||
'为此子代理输入一个清晰、唯一的名称。',
|
||||
'e.g., Code Reviewer': '例如:代码审查员',
|
||||
'Name cannot be empty.': '名称不能为空。',
|
||||
"Write the system prompt that defines this subagent's behavior. Be comprehensive for best results.":
|
||||
'编写定义此子代理行为的系统提示。为了获得最佳效果,请全面描述。',
|
||||
'e.g., You are an expert code reviewer...':
|
||||
'例如:您是一位专业的代码审查员...',
|
||||
'System prompt cannot be empty.': '系统提示不能为空。',
|
||||
'Describe when and how this subagent should be used.':
|
||||
'描述何时以及如何使用此子代理。',
|
||||
'e.g., Reviews code for best practices and potential bugs.':
|
||||
'例如:审查代码以查找最佳实践和潜在错误。',
|
||||
'Description cannot be empty.': '描述不能为空。',
|
||||
'Failed to launch editor: {{error}}': '启动编辑器失败: {{error}}',
|
||||
'Failed to save and edit subagent: {{error}}':
|
||||
'保存并编辑子代理失败: {{error}}',
|
||||
|
||||
// ============================================================================
|
||||
// Commands - General (continued)
|
||||
// ============================================================================
|
||||
'View and edit Qwen Code settings': '查看和编辑 Qwen Code 设置',
|
||||
'toggle vim mode on/off': '切换 vim 模式开关',
|
||||
'check session stats. Usage: /stats [model|tools]':
|
||||
@@ -232,6 +360,9 @@ export default {
|
||||
'工作区审批模式已存在并具有优先级。用户级别的更改将无效。',
|
||||
'(Use Enter to select, Tab to change focus)':
|
||||
'(使用 Enter 选择,Tab 切换焦点)',
|
||||
'Apply To': '应用于',
|
||||
'User Settings': '用户设置',
|
||||
'Workspace Settings': '工作区设置',
|
||||
|
||||
// ============================================================================
|
||||
// Commands - Memory
|
||||
@@ -454,7 +585,7 @@ export default {
|
||||
// ============================================================================
|
||||
'Get started': '开始使用',
|
||||
'How would you like to authenticate for this project?':
|
||||
'您想如何为此项目进行认证?',
|
||||
'您希望如何为此项目进行身份验证?',
|
||||
'OpenAI API key is required to use OpenAI authentication.':
|
||||
'使用 OpenAI 认证需要 OpenAI API 密钥',
|
||||
'You must select an auth method to proceed. Press Ctrl+C again to exit.':
|
||||
@@ -462,8 +593,8 @@ export default {
|
||||
'(Use Enter to Set Auth)': '(使用 Enter 设置认证)',
|
||||
'Terms of Services and Privacy Notice for Qwen Code':
|
||||
'Qwen Code 的服务条款和隐私声明',
|
||||
'Qwen OAuth': 'Qwen OAuth',
|
||||
OpenAI: 'OpenAI',
|
||||
'Qwen OAuth': 'Qwen OAuth (推荐)',
|
||||
OpenAI: 'OpenAI (兼容 API)',
|
||||
'Failed to login. Message: {{message}}': '登录失败。消息:{{message}}',
|
||||
'Authentication is enforced to be {{enforcedType}}, but you are currently using {{currentType}}.':
|
||||
'认证方式被强制设置为 {{enforcedType}},但您当前使用的是 {{currentType}}',
|
||||
|
||||
@@ -19,6 +19,7 @@ import { SettingScope } from '../../config/settings.js';
|
||||
import type { EditorType } from '@qwen-code/qwen-code-core';
|
||||
import { isEditorAvailable } from '@qwen-code/qwen-code-core';
|
||||
import { useKeypress } from '../hooks/useKeypress.js';
|
||||
import { t } from '../../i18n/index.js';
|
||||
|
||||
interface EditorDialogProps {
|
||||
onSelect: (editorType: EditorType | undefined, scope: SettingScope) => void;
|
||||
@@ -66,12 +67,16 @@ export function EditorSettingsDialog({
|
||||
|
||||
const scopeItems = [
|
||||
{
|
||||
label: 'User Settings',
|
||||
get label() {
|
||||
return t('User Settings');
|
||||
},
|
||||
value: SettingScope.User,
|
||||
key: SettingScope.User,
|
||||
},
|
||||
{
|
||||
label: 'Workspace Settings',
|
||||
get label() {
|
||||
return t('Workspace Settings');
|
||||
},
|
||||
value: SettingScope.Workspace,
|
||||
key: SettingScope.Workspace,
|
||||
},
|
||||
@@ -145,7 +150,8 @@ export function EditorSettingsDialog({
|
||||
|
||||
<Box marginTop={1} flexDirection="column">
|
||||
<Text bold={focusedSection === 'scope'}>
|
||||
{focusedSection === 'scope' ? '> ' : ' '}Apply To
|
||||
{focusedSection === 'scope' ? '> ' : ' '}
|
||||
{t('Apply To')}
|
||||
</Text>
|
||||
<RadioButtonSelect
|
||||
items={scopeItems}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Box, Text } from 'ink';
|
||||
import type { SettingScope } from '../../../config/settings.js';
|
||||
import { getScopeItems } from '../../../utils/dialogScopeUtils.js';
|
||||
import { RadioButtonSelect } from './RadioButtonSelect.js';
|
||||
import { t } from '../../../i18n/index.js';
|
||||
|
||||
interface ScopeSelectorProps {
|
||||
/** Callback function when a scope is selected */
|
||||
@@ -29,6 +30,7 @@ export function ScopeSelector({
|
||||
}: ScopeSelectorProps): React.JSX.Element {
|
||||
const scopeItems = getScopeItems().map((item) => ({
|
||||
...item,
|
||||
label: t(item.label),
|
||||
key: item.value,
|
||||
}));
|
||||
|
||||
@@ -40,7 +42,8 @@ export function ScopeSelector({
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
<Text bold={isFocused} wrap="truncate">
|
||||
{isFocused ? '> ' : ' '}Apply To
|
||||
{isFocused ? '> ' : ' '}
|
||||
{t('Apply To')}
|
||||
</Text>
|
||||
<RadioButtonSelect
|
||||
items={scopeItems}
|
||||
|
||||
@@ -20,6 +20,7 @@ import type { Config } from '@qwen-code/qwen-code-core';
|
||||
import { theme } from '../../../semantic-colors.js';
|
||||
import { TextEntryStep } from './TextEntryStep.js';
|
||||
import { useKeypress } from '../../../hooks/useKeypress.js';
|
||||
import { t } from '../../../../i18n/index.js';
|
||||
|
||||
interface AgentCreationWizardProps {
|
||||
onClose: () => void;
|
||||
@@ -90,25 +91,25 @@ export function AgentCreationWizard({
|
||||
const n = state.currentStep;
|
||||
switch (kind) {
|
||||
case 'LOCATION':
|
||||
return `Step ${n}: Choose Location`;
|
||||
return t('Step {{n}}: Choose Location', { n: n.toString() });
|
||||
case 'GEN_METHOD':
|
||||
return `Step ${n}: Choose Generation Method`;
|
||||
return t('Step {{n}}: Choose Generation Method', { n: n.toString() });
|
||||
case 'LLM_DESC':
|
||||
return `Step ${n}: Describe Your Subagent`;
|
||||
return t('Step {{n}}: Describe Your Subagent', { n: n.toString() });
|
||||
case 'MANUAL_NAME':
|
||||
return `Step ${n}: Enter Subagent Name`;
|
||||
return t('Step {{n}}: Enter Subagent Name', { n: n.toString() });
|
||||
case 'MANUAL_PROMPT':
|
||||
return `Step ${n}: Enter System Prompt`;
|
||||
return t('Step {{n}}: Enter System Prompt', { n: n.toString() });
|
||||
case 'MANUAL_DESC':
|
||||
return `Step ${n}: Enter Description`;
|
||||
return t('Step {{n}}: Enter Description', { n: n.toString() });
|
||||
case 'TOOLS':
|
||||
return `Step ${n}: Select Tools`;
|
||||
return t('Step {{n}}: Select Tools', { n: n.toString() });
|
||||
case 'COLOR':
|
||||
return `Step ${n}: Choose Background Color`;
|
||||
return t('Step {{n}}: Choose Background Color', { n: n.toString() });
|
||||
case 'FINAL':
|
||||
return `Step ${n}: Confirm and Save`;
|
||||
return t('Step {{n}}: Confirm and Save', { n: n.toString() });
|
||||
default:
|
||||
return 'Unknown Step';
|
||||
return t('Unknown Step');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -163,11 +164,11 @@ export function AgentCreationWizard({
|
||||
// Special case: During generation in description input step, only show cancel option
|
||||
const kind = getStepKind(state.generationMethod, state.currentStep);
|
||||
if (kind === 'LLM_DESC' && state.isGenerating) {
|
||||
return 'Esc to cancel';
|
||||
return t('Esc to cancel');
|
||||
}
|
||||
|
||||
if (getStepKind(state.generationMethod, state.currentStep) === 'FINAL') {
|
||||
return 'Press Enter to save, e to save and edit, Esc to go back';
|
||||
return t('Press Enter to save, e to save and edit, Esc to go back');
|
||||
}
|
||||
|
||||
// Steps that have ↑↓ navigation (RadioButtonSelect components)
|
||||
@@ -177,14 +178,17 @@ export function AgentCreationWizard({
|
||||
kindForNav === 'GEN_METHOD' ||
|
||||
kindForNav === 'TOOLS' ||
|
||||
kindForNav === 'COLOR';
|
||||
const navigationPart = hasNavigation ? '↑↓ to navigate, ' : '';
|
||||
const navigationPart = hasNavigation ? t('↑↓ to navigate, ') : '';
|
||||
|
||||
const escAction =
|
||||
state.currentStep === WIZARD_STEPS.LOCATION_SELECTION
|
||||
? 'cancel'
|
||||
: 'go back';
|
||||
? t('cancel')
|
||||
: t('go back');
|
||||
|
||||
return `Press Enter to continue, ${navigationPart}Esc to ${escAction}`;
|
||||
return t('Press Enter to continue, {{navigation}}Esc to {{action}}', {
|
||||
navigation: navigationPart,
|
||||
action: escAction,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -210,16 +214,16 @@ export function AgentCreationWizard({
|
||||
state={state}
|
||||
dispatch={dispatch}
|
||||
onNext={handleNext}
|
||||
description="Enter a clear, unique name for this subagent."
|
||||
placeholder="e.g., Code Reviewer"
|
||||
description={t('Enter a clear, unique name for this subagent.')}
|
||||
placeholder={t('e.g., Code Reviewer')}
|
||||
height={1}
|
||||
initialText={state.generatedName}
|
||||
onChange={(t) => {
|
||||
const value = t; // keep raw, trim later when validating
|
||||
onChange={(text) => {
|
||||
const value = text; // keep raw, trim later when validating
|
||||
dispatch({ type: 'SET_GENERATED_NAME', name: value });
|
||||
}}
|
||||
validate={(t) =>
|
||||
t.trim().length === 0 ? 'Name cannot be empty.' : null
|
||||
validate={(text) =>
|
||||
text.trim().length === 0 ? t('Name cannot be empty.') : null
|
||||
}
|
||||
/>
|
||||
);
|
||||
@@ -230,18 +234,22 @@ export function AgentCreationWizard({
|
||||
state={state}
|
||||
dispatch={dispatch}
|
||||
onNext={handleNext}
|
||||
description="Write the system prompt that defines this subagent's behavior. Be comprehensive for best results."
|
||||
placeholder="e.g., You are an expert code reviewer..."
|
||||
description={t(
|
||||
"Write the system prompt that defines this subagent's behavior. Be comprehensive for best results.",
|
||||
)}
|
||||
placeholder={t('e.g., You are an expert code reviewer...')}
|
||||
height={10}
|
||||
initialText={state.generatedSystemPrompt}
|
||||
onChange={(t) => {
|
||||
onChange={(text) => {
|
||||
dispatch({
|
||||
type: 'SET_GENERATED_SYSTEM_PROMPT',
|
||||
systemPrompt: t,
|
||||
systemPrompt: text,
|
||||
});
|
||||
}}
|
||||
validate={(t) =>
|
||||
t.trim().length === 0 ? 'System prompt cannot be empty.' : null
|
||||
validate={(text) =>
|
||||
text.trim().length === 0
|
||||
? t('System prompt cannot be empty.')
|
||||
: null
|
||||
}
|
||||
/>
|
||||
);
|
||||
@@ -252,15 +260,24 @@ export function AgentCreationWizard({
|
||||
state={state}
|
||||
dispatch={dispatch}
|
||||
onNext={handleNext}
|
||||
description="Describe when and how this subagent should be used."
|
||||
placeholder="e.g., Reviews code for best practices and potential bugs."
|
||||
description={t(
|
||||
'Describe when and how this subagent should be used.',
|
||||
)}
|
||||
placeholder={t(
|
||||
'e.g., Reviews code for best practices and potential bugs.',
|
||||
)}
|
||||
height={6}
|
||||
initialText={state.generatedDescription}
|
||||
onChange={(t) => {
|
||||
dispatch({ type: 'SET_GENERATED_DESCRIPTION', description: t });
|
||||
onChange={(text) => {
|
||||
dispatch({
|
||||
type: 'SET_GENERATED_DESCRIPTION',
|
||||
description: text,
|
||||
});
|
||||
}}
|
||||
validate={(t) =>
|
||||
t.trim().length === 0 ? 'Description cannot be empty.' : null
|
||||
validate={(text) =>
|
||||
text.trim().length === 0
|
||||
? t('Description cannot be empty.')
|
||||
: null
|
||||
}
|
||||
/>
|
||||
);
|
||||
@@ -292,7 +309,9 @@ export function AgentCreationWizard({
|
||||
return (
|
||||
<Box>
|
||||
<Text color={theme.status.error}>
|
||||
Invalid step: {state.currentStep}
|
||||
{t('Invalid step: {{step}}', {
|
||||
step: state.currentStep.toString(),
|
||||
})}
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -15,6 +15,7 @@ import { theme } from '../../../semantic-colors.js';
|
||||
import { shouldShowColor, getColorForDisplay } from '../utils.js';
|
||||
import { useLaunchEditor } from '../../../hooks/useLaunchEditor.js';
|
||||
import { useKeypress } from '../../../hooks/useKeypress.js';
|
||||
import { t } from '../../../../i18n/index.js';
|
||||
|
||||
/**
|
||||
* Step 6: Final confirmation and actions.
|
||||
@@ -62,15 +63,24 @@ export function CreationSummary({
|
||||
|
||||
if (conflictLevel === targetLevel) {
|
||||
allWarnings.push(
|
||||
`Name "${state.generatedName}" already exists at ${conflictLevel} level - will overwrite existing subagent`,
|
||||
t(
|
||||
'Name "{{name}}" already exists at {{level}} level - will overwrite existing subagent',
|
||||
{ name: state.generatedName, level: conflictLevel },
|
||||
),
|
||||
);
|
||||
} else if (targetLevel === 'project') {
|
||||
allWarnings.push(
|
||||
`Name "${state.generatedName}" exists at user level - project level will take precedence`,
|
||||
t(
|
||||
'Name "{{name}}" exists at user level - project level will take precedence',
|
||||
{ name: state.generatedName },
|
||||
),
|
||||
);
|
||||
} else {
|
||||
allWarnings.push(
|
||||
`Name "${state.generatedName}" exists at project level - existing subagent will take precedence`,
|
||||
t(
|
||||
'Name "{{name}}" exists at project level - existing subagent will take precedence',
|
||||
{ name: state.generatedName },
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -83,12 +93,16 @@ export function CreationSummary({
|
||||
// Check length warnings
|
||||
if (state.generatedDescription.length > 300) {
|
||||
allWarnings.push(
|
||||
`Description is over ${state.generatedDescription.length} characters`,
|
||||
t('Description is over {{length}} characters', {
|
||||
length: state.generatedDescription.length.toString(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (state.generatedSystemPrompt.length > 10000) {
|
||||
allWarnings.push(
|
||||
`System prompt is over ${state.generatedSystemPrompt.length} characters`,
|
||||
t('System prompt is over {{length}} characters', {
|
||||
length: state.generatedSystemPrompt.length.toString(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -181,7 +195,9 @@ export function CreationSummary({
|
||||
showSuccessAndClose();
|
||||
} catch (error) {
|
||||
setSaveError(
|
||||
`Failed to save and edit subagent: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
||||
t('Failed to save and edit subagent: {{error}}', {
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
}),
|
||||
);
|
||||
}
|
||||
}, [
|
||||
@@ -215,13 +231,15 @@ export function CreationSummary({
|
||||
<Box flexDirection="column" gap={1}>
|
||||
<Box>
|
||||
<Text bold color={theme.status.success}>
|
||||
✅ Subagent Created Successfully!
|
||||
{t('✅ Subagent Created Successfully!')}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>
|
||||
Subagent "{state.generatedName}" has been saved to{' '}
|
||||
{state.location} level.
|
||||
{t('Subagent "{{name}}" has been saved to {{level}} level.', {
|
||||
name: state.generatedName,
|
||||
level: state.location,
|
||||
})}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
@@ -232,35 +250,35 @@ export function CreationSummary({
|
||||
<Box flexDirection="column" gap={1}>
|
||||
<Box flexDirection="column">
|
||||
<Box>
|
||||
<Text color={theme.text.primary}>Name: </Text>
|
||||
<Text color={theme.text.primary}>{t('Name: ')}</Text>
|
||||
<Text color={getColorForDisplay(state.color)}>
|
||||
{state.generatedName}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text color={theme.text.primary}>Location: </Text>
|
||||
<Text color={theme.text.primary}>{t('Location: ')}</Text>
|
||||
<Text>
|
||||
{state.location === 'project'
|
||||
? 'Project Level (.qwen/agents/)'
|
||||
: 'User Level (~/.qwen/agents/)'}
|
||||
? t('Project Level (.qwen/agents/)')
|
||||
: t('User Level (~/.qwen/agents/)')}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text color={theme.text.primary}>Tools: </Text>
|
||||
<Text color={theme.text.primary}>{t('Tools: ')}</Text>
|
||||
<Text>{toolsDisplay}</Text>
|
||||
</Box>
|
||||
|
||||
{shouldShowColor(state.color) && (
|
||||
<Box>
|
||||
<Text color={theme.text.primary}>Color: </Text>
|
||||
<Text color={theme.text.primary}>{t('Color: ')}</Text>
|
||||
<Text color={getColorForDisplay(state.color)}>{state.color}</Text>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Box marginTop={1}>
|
||||
<Text color={theme.text.primary}>Description:</Text>
|
||||
<Text color={theme.text.primary}>{t('Description:')}</Text>
|
||||
</Box>
|
||||
<Box padding={1} paddingBottom={0}>
|
||||
<Text wrap="wrap">
|
||||
@@ -269,7 +287,7 @@ export function CreationSummary({
|
||||
</Box>
|
||||
|
||||
<Box marginTop={1}>
|
||||
<Text color={theme.text.primary}>System Prompt:</Text>
|
||||
<Text color={theme.text.primary}>{t('System Prompt:')}</Text>
|
||||
</Box>
|
||||
<Box padding={1} paddingBottom={0}>
|
||||
<Text wrap="wrap">
|
||||
@@ -281,7 +299,7 @@ export function CreationSummary({
|
||||
{saveError && (
|
||||
<Box flexDirection="column">
|
||||
<Text bold color={theme.status.error}>
|
||||
❌ Error saving subagent:
|
||||
{t('❌ Error saving subagent:')}
|
||||
</Text>
|
||||
<Box flexDirection="column" padding={1} paddingBottom={0}>
|
||||
<Text color={theme.status.error} wrap="wrap">
|
||||
@@ -294,7 +312,7 @@ export function CreationSummary({
|
||||
{warnings.length > 0 && (
|
||||
<Box flexDirection="column">
|
||||
<Text bold color={theme.status.warning}>
|
||||
Warnings:
|
||||
{t('Warnings:')}
|
||||
</Text>
|
||||
<Box flexDirection="column" padding={1} paddingBottom={0}>
|
||||
{warnings.map((warning, index) => (
|
||||
|
||||
@@ -14,6 +14,7 @@ import { useKeypress, type Key } from '../../../hooks/useKeypress.js';
|
||||
import { keyMatchers, Command } from '../../../keyMatchers.js';
|
||||
import { theme } from '../../../semantic-colors.js';
|
||||
import { TextInput } from '../../shared/TextInput.js';
|
||||
import { t } from '../../../../i18n/index.js';
|
||||
|
||||
/**
|
||||
* Step 3: Description input with LLM generation.
|
||||
@@ -103,7 +104,9 @@ export function DescriptionInput({
|
||||
dispatch({
|
||||
type: 'SET_VALIDATION_ERRORS',
|
||||
errors: [
|
||||
`Failed to generate subagent: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
||||
t('Failed to generate subagent: {{error}}', {
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
@@ -135,15 +138,17 @@ export function DescriptionInput({
|
||||
isActive: state.isGenerating,
|
||||
});
|
||||
|
||||
const placeholder =
|
||||
'e.g., Expert code reviewer that reviews code based on best practices...';
|
||||
const placeholder = t(
|
||||
'e.g., Expert code reviewer that reviews code based on best practices...',
|
||||
);
|
||||
|
||||
return (
|
||||
<Box flexDirection="column" gap={1}>
|
||||
<Box>
|
||||
<Text color={theme.text.secondary}>
|
||||
Describe what this subagent should do and when it should be used. (Be
|
||||
comprehensive for best results)
|
||||
{t(
|
||||
'Describe what this subagent should do and when it should be used. (Be comprehensive for best results)',
|
||||
)}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
@@ -153,7 +158,7 @@ export function DescriptionInput({
|
||||
<Spinner />
|
||||
</Box>
|
||||
<Text color={theme.text.accent}>
|
||||
Generating subagent configuration...
|
||||
{t('Generating subagent configuration...')}
|
||||
</Text>
|
||||
</Box>
|
||||
) : (
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import { Box } from 'ink';
|
||||
import { RadioButtonSelect } from '../../shared/RadioButtonSelect.js';
|
||||
import type { WizardStepProps } from '../types.js';
|
||||
import { t } from '../../../../i18n/index.js';
|
||||
|
||||
interface GenerationOption {
|
||||
label: string;
|
||||
@@ -15,11 +16,15 @@ interface GenerationOption {
|
||||
|
||||
const generationOptions: GenerationOption[] = [
|
||||
{
|
||||
label: 'Generate with Qwen Code (Recommended)',
|
||||
get label() {
|
||||
return t('Generate with Qwen Code (Recommended)');
|
||||
},
|
||||
value: 'qwen',
|
||||
},
|
||||
{
|
||||
label: 'Manual Creation',
|
||||
get label() {
|
||||
return t('Manual Creation');
|
||||
},
|
||||
value: 'manual',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import { Box } from 'ink';
|
||||
import { RadioButtonSelect } from '../../shared/RadioButtonSelect.js';
|
||||
import type { WizardStepProps } from '../types.js';
|
||||
import { t } from '../../../../i18n/index.js';
|
||||
|
||||
interface LocationOption {
|
||||
label: string;
|
||||
@@ -15,11 +16,15 @@ interface LocationOption {
|
||||
|
||||
const locationOptions: LocationOption[] = [
|
||||
{
|
||||
label: 'Project Level (.qwen/agents/)',
|
||||
get label() {
|
||||
return t('Project Level (.qwen/agents/)');
|
||||
},
|
||||
value: 'project',
|
||||
},
|
||||
{
|
||||
label: 'User Level (~/.qwen/agents/)',
|
||||
get label() {
|
||||
return t('User Level (~/.qwen/agents/)');
|
||||
},
|
||||
value: 'user',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -10,6 +10,7 @@ import { RadioButtonSelect } from '../../shared/RadioButtonSelect.js';
|
||||
import type { ToolCategory } from '../types.js';
|
||||
import { Kind, type Config } from '@qwen-code/qwen-code-core';
|
||||
import { theme } from '../../../semantic-colors.js';
|
||||
import { t } from '../../../../i18n/index.js';
|
||||
|
||||
interface ToolOption {
|
||||
label: string;
|
||||
@@ -45,7 +46,7 @@ export function ToolSelector({
|
||||
toolCategories: [
|
||||
{
|
||||
id: 'all',
|
||||
name: 'All Tools (Default)',
|
||||
name: t('All Tools (Default)'),
|
||||
tools: [],
|
||||
},
|
||||
],
|
||||
@@ -89,22 +90,22 @@ export function ToolSelector({
|
||||
const toolCategories = [
|
||||
{
|
||||
id: 'all',
|
||||
name: 'All Tools',
|
||||
name: t('All Tools'),
|
||||
tools: [],
|
||||
},
|
||||
{
|
||||
id: 'read',
|
||||
name: 'Read-only Tools',
|
||||
name: t('Read-only Tools'),
|
||||
tools: readTools,
|
||||
},
|
||||
{
|
||||
id: 'edit',
|
||||
name: 'Read & Edit Tools',
|
||||
name: t('Read & Edit Tools'),
|
||||
tools: [...readTools, ...editTools],
|
||||
},
|
||||
{
|
||||
id: 'execute',
|
||||
name: 'Read & Edit & Execution Tools',
|
||||
name: t('Read & Edit & Execution Tools'),
|
||||
tools: [...readTools, ...editTools, ...executeTools],
|
||||
},
|
||||
].filter((category) => category.id === 'all' || category.tools.length > 0);
|
||||
@@ -202,11 +203,11 @@ export function ToolSelector({
|
||||
<Box flexDirection="column">
|
||||
{currentCategory.id === 'all' ? (
|
||||
<Text color={theme.text.secondary}>
|
||||
All tools selected, including MCP tools
|
||||
{t('All tools selected, including MCP tools')}
|
||||
</Text>
|
||||
) : currentCategory.tools.length > 0 ? (
|
||||
<>
|
||||
<Text color={theme.text.secondary}>Selected tools:</Text>
|
||||
<Text color={theme.text.secondary}>{t('Selected tools:')}</Text>
|
||||
<Box flexDirection="column" marginLeft={2}>
|
||||
{(() => {
|
||||
// Filter the already categorized tools to show only those in current category
|
||||
@@ -224,17 +225,19 @@ export function ToolSelector({
|
||||
<>
|
||||
{categoryReadTools.length > 0 && (
|
||||
<Text color={theme.text.secondary}>
|
||||
• Read-only tools: {categoryReadTools.join(', ')}
|
||||
• {t('Read-only tools:')}{' '}
|
||||
{categoryReadTools.join(', ')}
|
||||
</Text>
|
||||
)}
|
||||
{categoryEditTools.length > 0 && (
|
||||
<Text color={theme.text.secondary}>
|
||||
• Edit tools: {categoryEditTools.join(', ')}
|
||||
• {t('Edit tools:')} {categoryEditTools.join(', ')}
|
||||
</Text>
|
||||
)}
|
||||
{categoryExecuteTools.length > 0 && (
|
||||
<Text color={theme.text.secondary}>
|
||||
• Execution tools: {categoryExecuteTools.join(', ')}
|
||||
• {t('Execution tools:')}{' '}
|
||||
{categoryExecuteTools.join(', ')}
|
||||
</Text>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Box } from 'ink';
|
||||
import { RadioButtonSelect } from '../../shared/RadioButtonSelect.js';
|
||||
import { MANAGEMENT_STEPS } from '../types.js';
|
||||
import { type SubagentConfig } from '@qwen-code/qwen-code-core';
|
||||
import { t } from '../../../../i18n/index.js';
|
||||
|
||||
interface ActionSelectionStepProps {
|
||||
selectedAgent: SubagentConfig | null;
|
||||
@@ -27,10 +28,34 @@ export const ActionSelectionStep = ({
|
||||
|
||||
// Filter actions based on whether the agent is built-in
|
||||
const allActions = [
|
||||
{ key: 'view', label: 'View Agent', value: 'view' as const },
|
||||
{ key: 'edit', label: 'Edit Agent', value: 'edit' as const },
|
||||
{ key: 'delete', label: 'Delete Agent', value: 'delete' as const },
|
||||
{ key: 'back', label: 'Back', value: 'back' as const },
|
||||
{
|
||||
key: 'view',
|
||||
get label() {
|
||||
return t('View Agent');
|
||||
},
|
||||
value: 'view' as const,
|
||||
},
|
||||
{
|
||||
key: 'edit',
|
||||
get label() {
|
||||
return t('Edit Agent');
|
||||
},
|
||||
value: 'edit' as const,
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
get label() {
|
||||
return t('Delete Agent');
|
||||
},
|
||||
value: 'delete' as const,
|
||||
},
|
||||
{
|
||||
key: 'back',
|
||||
get label() {
|
||||
return t('Back');
|
||||
},
|
||||
value: 'back' as const,
|
||||
},
|
||||
];
|
||||
|
||||
const actions = selectedAgent?.isBuiltin
|
||||
|
||||
@@ -9,6 +9,7 @@ import { type SubagentConfig } from '@qwen-code/qwen-code-core';
|
||||
import type { StepNavigationProps } from '../types.js';
|
||||
import { theme } from '../../../semantic-colors.js';
|
||||
import { useKeypress } from '../../../hooks/useKeypress.js';
|
||||
import { t } from '../../../../i18n/index.js';
|
||||
|
||||
interface AgentDeleteStepProps extends StepNavigationProps {
|
||||
selectedAgent: SubagentConfig | null;
|
||||
@@ -41,7 +42,7 @@ export function AgentDeleteStep({
|
||||
if (!selectedAgent) {
|
||||
return (
|
||||
<Box>
|
||||
<Text color={theme.status.error}>No agent selected</Text>
|
||||
<Text color={theme.status.error}>{t('No agent selected')}</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -49,8 +50,9 @@ export function AgentDeleteStep({
|
||||
return (
|
||||
<Box flexDirection="column" gap={1}>
|
||||
<Text color={theme.status.error}>
|
||||
Are you sure you want to delete agent “{selectedAgent.name}
|
||||
”?
|
||||
{t('Are you sure you want to delete agent "{{name}}"?', {
|
||||
name: selectedAgent.name,
|
||||
})}
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -11,6 +11,7 @@ import { MANAGEMENT_STEPS } from '../types.js';
|
||||
import { theme } from '../../../semantic-colors.js';
|
||||
import { useLaunchEditor } from '../../../hooks/useLaunchEditor.js';
|
||||
import { type SubagentConfig } from '@qwen-code/qwen-code-core';
|
||||
import { t } from '../../../../i18n/index.js';
|
||||
|
||||
interface EditOption {
|
||||
id: string;
|
||||
@@ -20,15 +21,21 @@ interface EditOption {
|
||||
const editOptions: EditOption[] = [
|
||||
{
|
||||
id: 'editor',
|
||||
label: 'Open in editor',
|
||||
get label() {
|
||||
return t('Open in editor');
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'tools',
|
||||
label: 'Edit tools',
|
||||
get label() {
|
||||
return t('Edit tools');
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'color',
|
||||
label: 'Edit color',
|
||||
get label() {
|
||||
return t('Edit color');
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -65,7 +72,9 @@ export function EditOptionsStep({
|
||||
await launchEditor(selectedAgent?.filePath);
|
||||
} catch (err) {
|
||||
setError(
|
||||
`Failed to launch editor: ${err instanceof Error ? err.message : 'Unknown error'}`,
|
||||
t('Failed to launch editor: {{error}}', {
|
||||
error: err instanceof Error ? err.message : 'Unknown error',
|
||||
}),
|
||||
);
|
||||
}
|
||||
} else if (selectedValue === 'tools') {
|
||||
@@ -98,7 +107,7 @@ export function EditOptionsStep({
|
||||
{error && (
|
||||
<Box flexDirection="column">
|
||||
<Text bold color={theme.status.error}>
|
||||
❌ Error:
|
||||
{t('❌ Error:')}
|
||||
</Text>
|
||||
<Box flexDirection="column" padding={1} paddingBottom={0}>
|
||||
<Text color={theme.status.error} wrap="wrap">
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Box, Text } from 'ink';
|
||||
import { theme } from '../../../semantic-colors.js';
|
||||
import { useKeypress } from '../../../hooks/useKeypress.js';
|
||||
import { type SubagentConfig } from '@qwen-code/qwen-code-core';
|
||||
import { t } from '../../../../i18n/index.js';
|
||||
|
||||
interface NavigationState {
|
||||
currentBlock: 'project' | 'user' | 'builtin';
|
||||
@@ -205,9 +206,9 @@ export const AgentSelectionStep = ({
|
||||
if (availableAgents.length === 0) {
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
<Text color={theme.text.secondary}>No subagents found.</Text>
|
||||
<Text color={theme.text.secondary}>{t('No subagents found.')}</Text>
|
||||
<Text color={theme.text.secondary}>
|
||||
Use '/agents create' to create your first subagent.
|
||||
{t("Use '/agents create' to create your first subagent.")}
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
@@ -237,7 +238,7 @@ export const AgentSelectionStep = ({
|
||||
{agent.isBuiltin && (
|
||||
<Text color={isSelected ? theme.text.accent : theme.text.secondary}>
|
||||
{' '}
|
||||
(built-in)
|
||||
{t('(built-in)')}
|
||||
</Text>
|
||||
)}
|
||||
{agent.level === 'user' && projectNames.has(agent.name) && (
|
||||
@@ -245,7 +246,7 @@ export const AgentSelectionStep = ({
|
||||
color={isSelected ? theme.status.warning : theme.text.secondary}
|
||||
>
|
||||
{' '}
|
||||
(overridden by project level agent)
|
||||
{t('(overridden by project level agent)')}
|
||||
</Text>
|
||||
)}
|
||||
</Text>
|
||||
@@ -265,7 +266,9 @@ export const AgentSelectionStep = ({
|
||||
{projectAgents.length > 0 && (
|
||||
<Box flexDirection="column" marginBottom={1}>
|
||||
<Text color={theme.text.primary} bold>
|
||||
Project Level ({projectAgents[0].filePath.replace(/\/[^/]+$/, '')})
|
||||
{t('Project Level ({{path}})', {
|
||||
path: projectAgents[0].filePath.replace(/\/[^/]+$/, ''),
|
||||
})}
|
||||
</Text>
|
||||
<Box marginTop={1} flexDirection="column">
|
||||
{projectAgents.map((agent, index) => {
|
||||
@@ -285,7 +288,9 @@ export const AgentSelectionStep = ({
|
||||
marginBottom={builtinAgents.length > 0 ? 1 : 0}
|
||||
>
|
||||
<Text color={theme.text.primary} bold>
|
||||
User Level ({userAgents[0].filePath.replace(/\/[^/]+$/, '')})
|
||||
{t('User Level ({{path}})', {
|
||||
path: userAgents[0].filePath.replace(/\/[^/]+$/, ''),
|
||||
})}
|
||||
</Text>
|
||||
<Box marginTop={1} flexDirection="column">
|
||||
{userAgents.map((agent, index) => {
|
||||
@@ -302,7 +307,7 @@ export const AgentSelectionStep = ({
|
||||
{builtinAgents.length > 0 && (
|
||||
<Box flexDirection="column">
|
||||
<Text color={theme.text.primary} bold>
|
||||
Built-in Agents
|
||||
{t('Built-in Agents')}
|
||||
</Text>
|
||||
<Box marginTop={1} flexDirection="column">
|
||||
{builtinAgents.map((agent, index) => {
|
||||
@@ -321,7 +326,9 @@ export const AgentSelectionStep = ({
|
||||
builtinAgents.length > 0) && (
|
||||
<Box marginTop={1}>
|
||||
<Text color={theme.text.secondary}>
|
||||
Using: {enabledAgentsCount} agents
|
||||
{t('Using: {{count}} agents', {
|
||||
count: enabledAgentsCount.toString(),
|
||||
})}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Box, Text } from 'ink';
|
||||
import { theme } from '../../../semantic-colors.js';
|
||||
import { shouldShowColor, getColorForDisplay } from '../utils.js';
|
||||
import { type SubagentConfig } from '@qwen-code/qwen-code-core';
|
||||
import { t } from '../../../../i18n/index.js';
|
||||
|
||||
interface AgentViewerStepProps {
|
||||
selectedAgent: SubagentConfig | null;
|
||||
@@ -17,7 +18,7 @@ export const AgentViewerStep = ({ selectedAgent }: AgentViewerStepProps) => {
|
||||
if (!selectedAgent) {
|
||||
return (
|
||||
<Box>
|
||||
<Text color={theme.status.error}>No agent selected</Text>
|
||||
<Text color={theme.status.error}>{t('No agent selected')}</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -30,31 +31,31 @@ export const AgentViewerStep = ({ selectedAgent }: AgentViewerStepProps) => {
|
||||
<Box flexDirection="column" gap={1}>
|
||||
<Box flexDirection="column">
|
||||
<Box>
|
||||
<Text color={theme.text.primary}>File Path: </Text>
|
||||
<Text color={theme.text.primary}>{t('File Path: ')}</Text>
|
||||
<Text>{agent.filePath}</Text>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text color={theme.text.primary}>Tools: </Text>
|
||||
<Text color={theme.text.primary}>{t('Tools: ')}</Text>
|
||||
<Text>{toolsDisplay}</Text>
|
||||
</Box>
|
||||
|
||||
{shouldShowColor(agent.color) && (
|
||||
<Box>
|
||||
<Text color={theme.text.primary}>Color: </Text>
|
||||
<Text color={theme.text.primary}>{t('Color: ')}</Text>
|
||||
<Text color={getColorForDisplay(agent.color)}>{agent.color}</Text>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Box marginTop={1}>
|
||||
<Text color={theme.text.primary}>Description:</Text>
|
||||
<Text color={theme.text.primary}>{t('Description:')}</Text>
|
||||
</Box>
|
||||
<Box padding={1} paddingBottom={0}>
|
||||
<Text wrap="wrap">{agent.description}</Text>
|
||||
</Box>
|
||||
|
||||
<Box marginTop={1}>
|
||||
<Text color={theme.text.primary}>System Prompt:</Text>
|
||||
<Text color={theme.text.primary}>{t('System Prompt:')}</Text>
|
||||
</Box>
|
||||
<Box padding={1} paddingBottom={0}>
|
||||
<Text wrap="wrap">{agent.systemPrompt}</Text>
|
||||
|
||||
@@ -18,6 +18,7 @@ import { theme } from '../../../semantic-colors.js';
|
||||
import { getColorForDisplay, shouldShowColor } from '../utils.js';
|
||||
import type { SubagentConfig, Config } from '@qwen-code/qwen-code-core';
|
||||
import { useKeypress } from '../../../hooks/useKeypress.js';
|
||||
import { t } from '../../../../i18n/index.js';
|
||||
|
||||
interface AgentsManagerDialogProps {
|
||||
onClose: () => void;
|
||||
@@ -143,21 +144,21 @@ export function AgentsManagerDialog({
|
||||
const getStepHeaderText = () => {
|
||||
switch (currentStep) {
|
||||
case MANAGEMENT_STEPS.AGENT_SELECTION:
|
||||
return 'Agents';
|
||||
return t('Agents');
|
||||
case MANAGEMENT_STEPS.ACTION_SELECTION:
|
||||
return 'Choose Action';
|
||||
return t('Choose Action');
|
||||
case MANAGEMENT_STEPS.AGENT_VIEWER:
|
||||
return selectedAgent?.name;
|
||||
case MANAGEMENT_STEPS.EDIT_OPTIONS:
|
||||
return `Edit ${selectedAgent?.name}`;
|
||||
return t('Edit {{name}}', { name: selectedAgent?.name || '' });
|
||||
case MANAGEMENT_STEPS.EDIT_TOOLS:
|
||||
return `Edit Tools: ${selectedAgent?.name}`;
|
||||
return t('Edit Tools: {{name}}', { name: selectedAgent?.name || '' });
|
||||
case MANAGEMENT_STEPS.EDIT_COLOR:
|
||||
return `Edit Color: ${selectedAgent?.name}`;
|
||||
return t('Edit Color: {{name}}', { name: selectedAgent?.name || '' });
|
||||
case MANAGEMENT_STEPS.DELETE_CONFIRMATION:
|
||||
return `Delete ${selectedAgent?.name}`;
|
||||
return t('Delete {{name}}', { name: selectedAgent?.name || '' });
|
||||
default:
|
||||
return 'Unknown Step';
|
||||
return t('Unknown Step');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -183,20 +184,20 @@ export function AgentsManagerDialog({
|
||||
const getNavigationInstructions = () => {
|
||||
if (currentStep === MANAGEMENT_STEPS.AGENT_SELECTION) {
|
||||
if (availableAgents.length === 0) {
|
||||
return 'Esc to close';
|
||||
return t('Esc to close');
|
||||
}
|
||||
return 'Enter to select, ↑↓ to navigate, Esc to close';
|
||||
return t('Enter to select, ↑↓ to navigate, Esc to close');
|
||||
}
|
||||
|
||||
if (currentStep === MANAGEMENT_STEPS.AGENT_VIEWER) {
|
||||
return 'Esc to go back';
|
||||
return t('Esc to go back');
|
||||
}
|
||||
|
||||
if (currentStep === MANAGEMENT_STEPS.DELETE_CONFIRMATION) {
|
||||
return 'Enter to confirm, Esc to cancel';
|
||||
return t('Enter to confirm, Esc to cancel');
|
||||
}
|
||||
|
||||
return 'Enter to select, ↑↓ to navigate, Esc to go back';
|
||||
return t('Enter to select, ↑↓ to navigate, Esc to go back');
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -295,7 +296,9 @@ export function AgentsManagerDialog({
|
||||
default:
|
||||
return (
|
||||
<Box>
|
||||
<Text color={theme.status.error}>Invalid step: {currentStep}</Text>
|
||||
<Text color={theme.status.error}>
|
||||
{t('Invalid step: {{step}}', { step: currentStep })}
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user