clawt 3.9.13 → 3.10.1

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.
Files changed (106) hide show
  1. package/README.md +80 -1
  2. package/README.zh-CN.md +81 -0
  3. package/dist/index.js +1935 -592
  4. package/dist/postinstall.js +1626 -283
  5. package/docs/config-file.md +2 -0
  6. package/docs/config.md +2 -1
  7. package/docs/init.md +3 -2
  8. package/docs/project-config.md +10 -1
  9. package/docs/spec.md +69 -2
  10. package/package.json +1 -1
  11. package/src/commands/alias.ts +5 -4
  12. package/src/commands/completion.ts +2 -1
  13. package/src/commands/config.ts +25 -7
  14. package/src/commands/cover-validate.ts +3 -2
  15. package/src/commands/create.ts +8 -7
  16. package/src/commands/home.ts +2 -1
  17. package/src/commands/init.ts +13 -6
  18. package/src/commands/list.ts +6 -4
  19. package/src/commands/merge.ts +8 -7
  20. package/src/commands/projects.ts +5 -3
  21. package/src/commands/remove.ts +7 -6
  22. package/src/commands/reset.ts +3 -2
  23. package/src/commands/resume.ts +10 -7
  24. package/src/commands/run.ts +8 -7
  25. package/src/commands/status.ts +16 -11
  26. package/src/commands/sync.ts +4 -3
  27. package/src/commands/tasks.ts +8 -6
  28. package/src/commands/validate.ts +7 -6
  29. package/src/constants/ai-prompts.ts +11 -11
  30. package/src/constants/config.ts +30 -0
  31. package/src/constants/index.ts +3 -2
  32. package/src/constants/messages/alias.ts +44 -14
  33. package/src/constants/messages/cli-descriptions.ts +91 -0
  34. package/src/constants/messages/common.ts +221 -36
  35. package/src/constants/messages/completion.ts +43 -14
  36. package/src/constants/messages/config.ts +61 -18
  37. package/src/constants/messages/cover-validate.ts +43 -14
  38. package/src/constants/messages/create.ts +16 -5
  39. package/src/constants/messages/home.ts +19 -6
  40. package/src/constants/messages/index.ts +2 -0
  41. package/src/constants/messages/init.ts +45 -14
  42. package/src/constants/messages/interactive-panel.ts +183 -29
  43. package/src/constants/messages/merge.ts +140 -38
  44. package/src/constants/messages/post-create.ts +59 -19
  45. package/src/constants/messages/projects.ts +51 -14
  46. package/src/constants/messages/remove.ts +50 -15
  47. package/src/constants/messages/reset.ts +14 -4
  48. package/src/constants/messages/resume.ts +116 -19
  49. package/src/constants/messages/run.ts +165 -35
  50. package/src/constants/messages/status.ts +84 -23
  51. package/src/constants/messages/sync.ts +54 -17
  52. package/src/constants/messages/tasks.ts +21 -7
  53. package/src/constants/messages/update.ts +35 -11
  54. package/src/constants/messages/validate.ts +218 -57
  55. package/src/constants/progress.ts +17 -6
  56. package/src/constants/project-config.ts +17 -0
  57. package/src/constants/prompt.ts +18 -2
  58. package/src/constants/tasks-template.ts +56 -2
  59. package/src/hooks/post-create.ts +5 -2
  60. package/src/index.ts +6 -5
  61. package/src/types/config.ts +2 -0
  62. package/src/utils/alias.ts +2 -1
  63. package/src/utils/claude.ts +10 -9
  64. package/src/utils/config-strategy.ts +3 -3
  65. package/src/utils/dry-run.ts +2 -2
  66. package/src/utils/formatter.ts +18 -11
  67. package/src/utils/i18n.ts +63 -0
  68. package/src/utils/index.ts +2 -0
  69. package/src/utils/interactive-panel-render.ts +6 -3
  70. package/src/utils/progress-render.ts +11 -9
  71. package/src/utils/prompt.ts +2 -1
  72. package/src/utils/task-executor.ts +10 -7
  73. package/src/utils/task-file.ts +2 -1
  74. package/src/utils/terminal.ts +9 -9
  75. package/src/utils/ui-prompts.ts +4 -3
  76. package/src/utils/update-checker.ts +1 -1
  77. package/src/utils/validate-branch.ts +16 -9
  78. package/src/utils/validate-core.ts +2 -1
  79. package/src/utils/validate-runner.ts +2 -2
  80. package/src/utils/worktree-matcher.ts +9 -7
  81. package/tests/unit/commands/alias.test.ts +4 -0
  82. package/tests/unit/commands/completion.test.ts +14 -0
  83. package/tests/unit/commands/config.test.ts +61 -28
  84. package/tests/unit/commands/cover-validate.test.ts +13 -2
  85. package/tests/unit/commands/init.test.ts +6 -2
  86. package/tests/unit/commands/merge.test.ts +14 -0
  87. package/tests/unit/commands/run.test.ts +17 -0
  88. package/tests/unit/commands/tasks.test.ts +39 -9
  89. package/tests/unit/constants/config.test.ts +16 -1
  90. package/tests/unit/constants/messages-post-create.test.ts +93 -1
  91. package/tests/unit/constants/messages.test.ts +85 -1
  92. package/tests/unit/hooks/post-create.test.ts +32 -0
  93. package/tests/unit/utils/alias.test.ts +14 -0
  94. package/tests/unit/utils/claude.test.ts +24 -4
  95. package/tests/unit/utils/config-strategy.test.ts +21 -0
  96. package/tests/unit/utils/conflict-resolver.test.ts +24 -4
  97. package/tests/unit/utils/formatter.test.ts +21 -0
  98. package/tests/unit/utils/i18n.test.ts +91 -0
  99. package/tests/unit/utils/progress.test.ts +39 -18
  100. package/tests/unit/utils/prompt.test.ts +25 -2
  101. package/tests/unit/utils/task-file.test.ts +73 -10
  102. package/tests/unit/utils/terminal-cmux.test.ts +19 -4
  103. package/tests/unit/utils/update-checker.test.ts +2 -0
  104. package/tests/unit/utils/validate-branch.test.ts +26 -1
  105. package/tests/unit/utils/validation.test.ts +2 -2
  106. package/tests/unit/utils/worktree-matcher.test.ts +2 -0
package/dist/index.js CHANGED
@@ -22,592 +22,1775 @@ var PROJECTS_CONFIG_DIR = join(CLAWT_HOME, "projects");
22
22
  var INVALID_BRANCH_CHARS = /[\/\\.\s~:*?[\]^]+/g;
23
23
  var VALIDATE_BRANCH_PREFIX = "clawt-validate-";
24
24
 
25
+ // src/utils/config.ts
26
+ import { existsSync as existsSync3, readFileSync, writeFileSync } from "fs";
27
+
28
+ // src/utils/fs.ts
29
+ import { existsSync, mkdirSync, readdirSync, rmdirSync, statSync } from "fs";
30
+ import { join as join2 } from "path";
31
+ function ensureDir(dirPath) {
32
+ if (!existsSync(dirPath)) {
33
+ mkdirSync(dirPath, { recursive: true });
34
+ }
35
+ }
36
+ function removeEmptyDir(dirPath) {
37
+ if (!existsSync(dirPath)) {
38
+ return false;
39
+ }
40
+ const entries = readdirSync(dirPath);
41
+ if (entries.length === 0) {
42
+ rmdirSync(dirPath);
43
+ return true;
44
+ }
45
+ return false;
46
+ }
47
+ function calculateDirSize(dirPath) {
48
+ let totalSize = 0;
49
+ try {
50
+ const entries = readdirSync(dirPath, { withFileTypes: true });
51
+ for (const entry of entries) {
52
+ const fullPath = join2(dirPath, entry.name);
53
+ try {
54
+ if (entry.isDirectory()) {
55
+ totalSize += calculateDirSize(fullPath);
56
+ } else if (entry.isFile()) {
57
+ totalSize += statSync(fullPath).size;
58
+ }
59
+ } catch {
60
+ }
61
+ }
62
+ } catch {
63
+ }
64
+ return totalSize;
65
+ }
66
+
67
+ // src/logger/index.ts
68
+ import winston from "winston";
69
+ import DailyRotateFile from "winston-daily-rotate-file";
70
+ import chalk from "chalk";
71
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
72
+ if (!existsSync2(LOGS_DIR)) {
73
+ mkdirSync2(LOGS_DIR, { recursive: true });
74
+ }
75
+ var logFormat = winston.format.printf(({ level, message, timestamp }) => {
76
+ const upperLevel = level.toUpperCase().padEnd(5);
77
+ return `[${timestamp}] [${upperLevel}] ${message}`;
78
+ });
79
+ var dailyRotateTransport = new DailyRotateFile({
80
+ dirname: LOGS_DIR,
81
+ filename: "clawt-%DATE%.log",
82
+ datePattern: "YYYY-MM-DD",
83
+ maxSize: "10m",
84
+ maxFiles: "30d"
85
+ });
86
+ var logger = winston.createLogger({
87
+ level: "debug",
88
+ format: winston.format.combine(
89
+ winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
90
+ logFormat
91
+ ),
92
+ transports: [dailyRotateTransport]
93
+ });
94
+ var LEVEL_COLORS = {
95
+ error: chalk.red,
96
+ warn: chalk.yellow,
97
+ info: chalk.cyan,
98
+ debug: chalk.gray
99
+ };
100
+ function colorizeLevel(level) {
101
+ const colorFn = LEVEL_COLORS[level] || chalk.white;
102
+ return colorFn(level.toUpperCase().padEnd(5));
103
+ }
104
+ function enableConsoleTransport() {
105
+ const hasConsole = logger.transports.some(
106
+ (t) => t instanceof winston.transports.Console
107
+ );
108
+ if (hasConsole) {
109
+ return;
110
+ }
111
+ const consoleFormat = winston.format.printf(({ level, message, timestamp }) => {
112
+ return `${chalk.gray(timestamp)} ${colorizeLevel(level)} ${message}`;
113
+ });
114
+ const consoleTransport = new winston.transports.Console({
115
+ level: "debug",
116
+ format: winston.format.combine(
117
+ winston.format.timestamp({ format: DEBUG_TIMESTAMP_FORMAT }),
118
+ consoleFormat
119
+ )
120
+ });
121
+ logger.add(consoleTransport);
122
+ }
123
+
124
+ // src/utils/config.ts
125
+ function loadConfig() {
126
+ if (!existsSync3(CONFIG_PATH)) {
127
+ return { ...DEFAULT_CONFIG };
128
+ }
129
+ try {
130
+ const raw = readFileSync(CONFIG_PATH, "utf-8");
131
+ return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };
132
+ } catch {
133
+ logger.warn(MESSAGES.CONFIG_CORRUPTED);
134
+ writeDefaultConfig();
135
+ return { ...DEFAULT_CONFIG };
136
+ }
137
+ }
138
+ function writeConfig(config2) {
139
+ writeFileSync(CONFIG_PATH, JSON.stringify(config2, null, 2), "utf-8");
140
+ }
141
+ function writeDefaultConfig() {
142
+ writeConfig(DEFAULT_CONFIG);
143
+ }
144
+ function saveConfig(config2) {
145
+ writeFileSync(CONFIG_PATH, JSON.stringify(config2, null, 2), "utf-8");
146
+ }
147
+ function getConfigValue(key) {
148
+ const config2 = loadConfig();
149
+ return config2[key];
150
+ }
151
+ function ensureClawtDirs() {
152
+ ensureDir(CLAWT_HOME);
153
+ ensureDir(LOGS_DIR);
154
+ ensureDir(WORKTREES_DIR);
155
+ ensureDir(PROJECTS_CONFIG_DIR);
156
+ }
157
+ function parseConcurrency(optionValue, configValue) {
158
+ if (optionValue === void 0) {
159
+ return configValue;
160
+ }
161
+ const parsed = parseInt(optionValue, 10);
162
+ if (Number.isNaN(parsed) || parsed < 0) {
163
+ throw new ClawtError(MESSAGES.CONCURRENCY_INVALID);
164
+ }
165
+ return parsed;
166
+ }
167
+
168
+ // src/utils/i18n.ts
169
+ var currentLanguage = null;
170
+ function getCurrentLanguage() {
171
+ if (currentLanguage !== null) {
172
+ return currentLanguage;
173
+ }
174
+ try {
175
+ const config2 = loadConfig();
176
+ currentLanguage = config2.language || "en";
177
+ } catch {
178
+ currentLanguage = "en";
179
+ }
180
+ return currentLanguage;
181
+ }
182
+ function resetLanguageCache() {
183
+ currentLanguage = null;
184
+ }
185
+ function createMessages(i18nMap) {
186
+ const lang = getCurrentLanguage();
187
+ const result = {};
188
+ for (const key of Object.keys(i18nMap)) {
189
+ result[key] = i18nMap[key][lang];
190
+ }
191
+ return result;
192
+ }
193
+
25
194
  // src/constants/messages/common.ts
26
- var COMMON_MESSAGES = {
195
+ var COMMON_MESSAGES_I18N = {
27
196
  /** 不在主 worktree 根目录 */
28
- NOT_MAIN_WORKTREE: "\u8BF7\u5728\u4E3B worktree \u7684\u6839\u76EE\u5F55\u4E0B\u6267\u884C clawt",
197
+ NOT_MAIN_WORKTREE: {
198
+ en: "Please run clawt in the root directory of the main worktree",
199
+ "zh-CN": "\u8BF7\u5728\u4E3B worktree \u7684\u6839\u76EE\u5F55\u4E0B\u6267\u884C clawt"
200
+ },
29
201
  /** 不在 git 仓库中 */
30
- NOT_GIT_REPO: "\u5F53\u524D\u76EE\u5F55\u4E0D\u662F git \u4ED3\u5E93\uFF0C\u8BF7\u5148\u6267\u884C git init \u5E76\u63D0\u4EA4\u540E\uFF0C\u518D\u6267\u884C clawt init \u521D\u59CB\u5316\u9879\u76EE",
202
+ NOT_GIT_REPO: {
203
+ en: "Current directory is not a git repository. Please run git init and make an initial commit, then run clawt init",
204
+ "zh-CN": "\u5F53\u524D\u76EE\u5F55\u4E0D\u662F git \u4ED3\u5E93\uFF0C\u8BF7\u5148\u6267\u884C git init \u5E76\u63D0\u4EA4\u540E\uFF0C\u518D\u6267\u884C clawt init \u521D\u59CB\u5316\u9879\u76EE"
205
+ },
31
206
  /** Git 未安装 */
32
- GIT_NOT_INSTALLED: "Git \u672A\u5B89\u88C5\u6216\u4E0D\u5728 PATH \u4E2D\uFF0C\u8BF7\u5148\u5B89\u88C5 Git",
207
+ GIT_NOT_INSTALLED: {
208
+ en: "Git is not installed or not in PATH. Please install Git first",
209
+ "zh-CN": "Git \u672A\u5B89\u88C5\u6216\u4E0D\u5728 PATH \u4E2D\uFF0C\u8BF7\u5148\u5B89\u88C5 Git"
210
+ },
33
211
  /** Claude Code CLI 未安装 */
34
- CLAUDE_NOT_INSTALLED: "Claude Code CLI \u672A\u5B89\u88C5\uFF0C\u8BF7\u5148\u5B89\u88C5\uFF1Anpm install -g @anthropic-ai/claude-code",
212
+ CLAUDE_NOT_INSTALLED: {
213
+ en: "Claude Code CLI is not installed. Please install it: npm install -g @anthropic-ai/claude-code",
214
+ "zh-CN": "Claude Code CLI \u672A\u5B89\u88C5\uFF0C\u8BF7\u5148\u5B89\u88C5\uFF1Anpm install -g @anthropic-ai/claude-code"
215
+ },
35
216
  /** HEAD 不存在(仓库无任何 commit) */
36
- HEAD_NOT_FOUND: "\u5F53\u524D\u4ED3\u5E93\u5C1A\u672A\u521B\u5EFA\u4EFB\u4F55\u63D0\u4EA4\uFF0C\u8BF7\u5148\u6267\u884C git commit \u521B\u5EFA\u9996\u6B21\u63D0\u4EA4\u540E\u518D\u4F7F\u7528 clawt",
217
+ HEAD_NOT_FOUND: {
218
+ en: "No commits exist in this repository. Please create an initial commit first",
219
+ "zh-CN": "\u5F53\u524D\u4ED3\u5E93\u5C1A\u672A\u521B\u5EFA\u4EFB\u4F55\u63D0\u4EA4\uFF0C\u8BF7\u5148\u6267\u884C git commit \u521B\u5EFA\u9996\u6B21\u63D0\u4EA4\u540E\u518D\u4F7F\u7528 clawt"
220
+ },
37
221
  /** 分支已存在 */
38
- BRANCH_EXISTS: (name) => `\u5206\u652F ${name} \u5DF2\u5B58\u5728\uFF0C\u65E0\u6CD5\u521B\u5EFA`,
222
+ BRANCH_EXISTS: {
223
+ en: (name) => `Branch ${name} already exists, cannot create`,
224
+ "zh-CN": (name) => `\u5206\u652F ${name} \u5DF2\u5B58\u5728\uFF0C\u65E0\u6CD5\u521B\u5EFA`
225
+ },
39
226
  /** 分支名清理后为空 */
40
- BRANCH_NAME_EMPTY: (original) => `\u5206\u652F\u540D "${original}" \u4E2D\u4E0D\u5305\u542B\u5408\u6CD5\u5B57\u7B26\uFF0C\u65E0\u6CD5\u521B\u5EFA\u5206\u652F`,
227
+ BRANCH_NAME_EMPTY: {
228
+ en: (original) => `Branch name "${original}" contains no valid characters, cannot create branch`,
229
+ "zh-CN": (original) => `\u5206\u652F\u540D "${original}" \u4E2D\u4E0D\u5305\u542B\u5408\u6CD5\u5B57\u7B26\uFF0C\u65E0\u6CD5\u521B\u5EFA\u5206\u652F`
230
+ },
41
231
  /** 分支名被转换 */
42
- BRANCH_SANITIZED: (original, sanitized) => `\u5206\u652F\u540D\u5DF2\u8F6C\u6362: ${original} \u2192 ${sanitized}`,
232
+ BRANCH_SANITIZED: {
233
+ en: (original, sanitized) => `Branch name sanitized: ${original} \u2192 ${sanitized}`,
234
+ "zh-CN": (original, sanitized) => `\u5206\u652F\u540D\u5DF2\u8F6C\u6362: ${original} \u2192 ${sanitized}`
235
+ },
43
236
  /** worktree 创建成功 */
44
- WORKTREE_CREATED: (count) => `\u2713 \u5DF2\u521B\u5EFA ${count} \u4E2A worktree`,
237
+ WORKTREE_CREATED: {
238
+ en: (count) => `\u2713 Created ${count} worktree(s)`,
239
+ "zh-CN": (count) => `\u2713 \u5DF2\u521B\u5EFA ${count} \u4E2A worktree`
240
+ },
45
241
  /** worktree 移除成功 */
46
- WORKTREE_REMOVED: (path2) => `\u2713 \u5DF2\u79FB\u9664 worktree: ${path2}`,
242
+ WORKTREE_REMOVED: {
243
+ en: (path2) => `\u2713 Removed worktree: ${path2}`,
244
+ "zh-CN": (path2) => `\u2713 \u5DF2\u79FB\u9664 worktree: ${path2}`
245
+ },
47
246
  /** 没有 worktree */
48
- NO_WORKTREES: "(\u65E0 worktree)",
247
+ NO_WORKTREES: {
248
+ en: "(No worktrees)",
249
+ "zh-CN": "(\u65E0 worktree)"
250
+ },
49
251
  /** 目标 worktree 不存在 */
50
- WORKTREE_NOT_FOUND: (name) => `worktree ${name} \u4E0D\u5B58\u5728`,
252
+ WORKTREE_NOT_FOUND: {
253
+ en: (name) => `Worktree ${name} does not exist`,
254
+ "zh-CN": (name) => `worktree ${name} \u4E0D\u5B58\u5728`
255
+ },
51
256
  /** 主 worktree 有未提交更改 */
52
- MAIN_WORKTREE_DIRTY: "\u4E3B worktree \u6709\u672A\u63D0\u4EA4\u7684\u66F4\u6539\uFF0C\u8BF7\u5148\u5904\u7406",
257
+ MAIN_WORKTREE_DIRTY: {
258
+ en: "Main worktree has uncommitted changes. Please resolve first",
259
+ "zh-CN": "\u4E3B worktree \u6709\u672A\u63D0\u4EA4\u7684\u66F4\u6539\uFF0C\u8BF7\u5148\u5904\u7406"
260
+ },
53
261
  /** 目标 worktree 无更改 */
54
- TARGET_WORKTREE_CLEAN: "\u8BE5 worktree \u7684\u5206\u652F\u4E0A\u6CA1\u6709\u4EFB\u4F55\u66F4\u6539\uFF0C\u65E0\u9700\u9A8C\u8BC1",
262
+ TARGET_WORKTREE_CLEAN: {
263
+ en: "No changes on this worktree branch, nothing to validate",
264
+ "zh-CN": "\u8BE5 worktree \u7684\u5206\u652F\u4E0A\u6CA1\u6709\u4EFB\u4F55\u66F4\u6539\uFF0C\u65E0\u9700\u9A8C\u8BC1"
265
+ },
55
266
  /** 用户取消破坏性操作 */
56
- DESTRUCTIVE_OP_CANCELLED: "\u5DF2\u53D6\u6D88\u64CD\u4F5C",
267
+ DESTRUCTIVE_OP_CANCELLED: {
268
+ en: "Operation cancelled",
269
+ "zh-CN": "\u5DF2\u53D6\u6D88\u64CD\u4F5C"
270
+ },
57
271
  /** 请提供提交信息 */
58
- COMMIT_MESSAGE_REQUIRED: "\u8BF7\u63D0\u4F9B\u63D0\u4EA4\u4FE1\u606F\uFF08-m \u53C2\u6570\uFF09",
272
+ COMMIT_MESSAGE_REQUIRED: {
273
+ en: "Please provide a commit message (-m option)",
274
+ "zh-CN": "\u8BF7\u63D0\u4F9B\u63D0\u4EA4\u4FE1\u606F\uFF08-m \u53C2\u6570\uFF09"
275
+ },
59
276
  /** 配置文件损坏,已重新生成默认配置 */
60
- CONFIG_CORRUPTED: "\u914D\u7F6E\u6587\u4EF6\u635F\u574F\u6216\u65E0\u6CD5\u89E3\u6790\uFF0C\u5DF2\u91CD\u65B0\u751F\u6210\u9ED8\u8BA4\u914D\u7F6E",
277
+ CONFIG_CORRUPTED: {
278
+ en: "Config file corrupted or unparseable, regenerated default config",
279
+ "zh-CN": "\u914D\u7F6E\u6587\u4EF6\u635F\u574F\u6216\u65E0\u6CD5\u89E3\u6790\uFF0C\u5DF2\u91CD\u65B0\u751F\u6210\u9ED8\u8BA4\u914D\u7F6E"
280
+ },
61
281
  /** worktree 状态获取失败 */
62
- WORKTREE_STATUS_UNAVAILABLE: "(\u72B6\u6001\u4E0D\u53EF\u7528)",
282
+ WORKTREE_STATUS_UNAVAILABLE: {
283
+ en: "(Status unavailable)",
284
+ "zh-CN": "(\u72B6\u6001\u4E0D\u53EF\u7528)"
285
+ },
63
286
  /** 分隔线 */
64
- SEPARATOR: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
287
+ SEPARATOR: {
288
+ en: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
289
+ "zh-CN": "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
290
+ },
65
291
  /** 粗分隔线 */
66
- DOUBLE_SEPARATOR: "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550",
292
+ DOUBLE_SEPARATOR: {
293
+ en: "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550",
294
+ "zh-CN": "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"
295
+ },
67
296
  /** 守卫检测:配置的主工作分支已不存在 */
68
- GUARD_BRANCH_NOT_EXISTS: (branchName) => `\u914D\u7F6E\u7684\u4E3B\u5DE5\u4F5C\u5206\u652F ${branchName} \u5DF2\u4E0D\u5B58\u5728\uFF0C\u8BF7\u6267\u884C clawt init \u91CD\u65B0\u8BBE\u7F6E\u4E3B\u5DE5\u4F5C\u5206\u652F`,
297
+ GUARD_BRANCH_NOT_EXISTS: {
298
+ en: (branchName) => `Configured main work branch ${branchName} no longer exists. Please run clawt init to reset`,
299
+ "zh-CN": (branchName) => `\u914D\u7F6E\u7684\u4E3B\u5DE5\u4F5C\u5206\u652F ${branchName} \u5DF2\u4E0D\u5B58\u5728\uFF0C\u8BF7\u6267\u884C clawt init \u91CD\u65B0\u8BBE\u7F6E\u4E3B\u5DE5\u4F5C\u5206\u652F`
300
+ },
69
301
  /** 守卫检测:当前分支与配置的主工作分支不一致 */
70
- GUARD_BRANCH_MISMATCH: (configuredBranch, currentBranch) => `\u5F53\u524D\u5206\u652F ${currentBranch} \u4E0E\u914D\u7F6E\u7684\u4E3B\u5DE5\u4F5C\u5206\u652F ${configuredBranch} \u4E0D\u4E00\u81F4\uFF0C\u5982\u9700\u66F4\u65B0\u8BF7\u6267\u884C clawt init`,
302
+ GUARD_BRANCH_MISMATCH: {
303
+ en: (configuredBranch, currentBranch) => `Current branch ${currentBranch} does not match configured main work branch ${configuredBranch}. Run clawt init to update`,
304
+ "zh-CN": (configuredBranch, currentBranch) => `\u5F53\u524D\u5206\u652F ${currentBranch} \u4E0E\u914D\u7F6E\u7684\u4E3B\u5DE5\u4F5C\u5206\u652F ${configuredBranch} \u4E0D\u4E00\u81F4\uFF0C\u5982\u9700\u66F4\u65B0\u8BF7\u6267\u884C clawt init`
305
+ },
71
306
  /** Git index 被锁定(index.lock 存在) */
72
- GIT_INDEX_LOCKED: (lockFilePath) => `Git index \u88AB\u9501\u5B9A\uFF0C\u65E0\u6CD5\u6267\u884C\u64CD\u4F5C
307
+ GIT_INDEX_LOCKED: {
308
+ en: (lockFilePath) => `Git index is locked, cannot proceed
309
+ Cause: Lock file exists (possibly from an interrupted git operation)
310
+ Lock file path: ${lockFilePath}
311
+ Fix: Confirm no other git operations are running, then run:
312
+ rm ${lockFilePath}`,
313
+ "zh-CN": (lockFilePath) => `Git index \u88AB\u9501\u5B9A\uFF0C\u65E0\u6CD5\u6267\u884C\u64CD\u4F5C
73
314
  \u539F\u56E0\uFF1A\u9501\u6587\u4EF6\u5DF2\u5B58\u5728\uFF08\u53EF\u80FD\u662F\u4E0A\u6B21 git \u64CD\u4F5C\u5F02\u5E38\u4E2D\u65AD\u6B8B\u7559\uFF09
74
315
  \u9501\u6587\u4EF6\u8DEF\u5F84\uFF1A${lockFilePath}
75
316
  \u4FEE\u590D\u65B9\u6CD5\uFF1A\u786E\u8BA4\u6CA1\u6709\u5176\u4ED6 git \u64CD\u4F5C\u5728\u8FDB\u884C\u540E\uFF0C\u6267\u884C\u4EE5\u4E0B\u547D\u4EE4\u5220\u9664\u9501\u6587\u4EF6\uFF1A
76
- rm ${lockFilePath}`,
317
+ rm ${lockFilePath}`
318
+ },
77
319
  /** Git index.lock 重试中(简短提示) */
78
- GIT_INDEX_LOCK_RETRYING: "Git index \u88AB\u9501\u5B9A\uFF0C\u6B63\u5728\u91CD\u8BD5..."
320
+ GIT_INDEX_LOCK_RETRYING: {
321
+ en: "Git index is locked, retrying...",
322
+ "zh-CN": "Git index \u88AB\u9501\u5B9A\uFF0C\u6B63\u5728\u91CD\u8BD5..."
323
+ },
324
+ // --- 从 formatter.ts 迁移 ---
325
+ /** 是否继续? */
326
+ CONFIRM_CONTINUE: {
327
+ en: "Continue?",
328
+ "zh-CN": "\u662F\u5426\u7EE7\u7EED\uFF1F"
329
+ },
330
+ /** 无变更 */
331
+ NO_CHANGES: {
332
+ en: "No changes",
333
+ "zh-CN": "\u65E0\u53D8\u66F4"
334
+ },
335
+ /** 未提交修改 */
336
+ UNCOMMITTED_CHANGES: {
337
+ en: "(uncommitted changes)",
338
+ "zh-CN": "(\u672A\u63D0\u4EA4\u4FEE\u6539)"
339
+ },
340
+ /** 提交数 */
341
+ COMMIT_COUNT: {
342
+ en: (n) => `${n} commit(s)`,
343
+ "zh-CN": (n) => `${n} \u4E2A\u63D0\u4EA4`
344
+ },
345
+ /** 刚刚 */
346
+ JUST_NOW: {
347
+ en: "just now",
348
+ "zh-CN": "\u521A\u521A"
349
+ },
350
+ /** N 分钟前 */
351
+ MINUTES_AGO: {
352
+ en: (n) => `${n} min ago`,
353
+ "zh-CN": (n) => `${n} \u5206\u949F\u524D`
354
+ },
355
+ /** N 小时前 */
356
+ HOURS_AGO: {
357
+ en: (n) => `${n} hr ago`,
358
+ "zh-CN": (n) => `${n} \u5C0F\u65F6\u524D`
359
+ },
360
+ /** N 天前 */
361
+ DAYS_AGO: {
362
+ en: (n) => `${n} day(s) ago`,
363
+ "zh-CN": (n) => `${n} \u5929\u524D`
364
+ },
365
+ /** N 个月前 */
366
+ MONTHS_AGO: {
367
+ en: (n) => `${n} month(s) ago`,
368
+ "zh-CN": (n) => `${n} \u4E2A\u6708\u524D`
369
+ },
370
+ /** N 年前 */
371
+ YEARS_AGO: {
372
+ en: (n) => `${n} year(s) ago`,
373
+ "zh-CN": (n) => `${n} \u5E74\u524D`
374
+ },
375
+ /** 未知错误 */
376
+ UNKNOWN_ERROR: {
377
+ en: "Unknown error",
378
+ "zh-CN": "\u672A\u77E5\u9519\u8BEF"
379
+ },
380
+ // --- 从 ui-prompts.ts 迁移 ---
381
+ /** 非交互模式下无法进行分支选择 */
382
+ NON_INTERACTIVE_BRANCH_SELECT: {
383
+ en: "Cannot select branch in non-interactive mode. Please use -b to specify branch",
384
+ "zh-CN": "\u975E\u4EA4\u4E92\u6A21\u5F0F\u4E0B\u65E0\u6CD5\u8FDB\u884C\u5206\u652F\u9009\u62E9\uFF0C\u8BF7\u4F7F\u7528 -b \u6307\u5B9A\u5206\u652F"
385
+ },
386
+ /** 非交互模式下无法进行分支多选 */
387
+ NON_INTERACTIVE_MULTI_SELECT: {
388
+ en: "Cannot multi-select branches in non-interactive mode",
389
+ "zh-CN": "\u975E\u4EA4\u4E92\u6A21\u5F0F\u4E0B\u65E0\u6CD5\u8FDB\u884C\u5206\u652F\u591A\u9009"
390
+ },
391
+ // --- 从 worktree-matcher.ts 迁移 ---
392
+ /** 今天 */
393
+ TODAY: {
394
+ en: "Today",
395
+ "zh-CN": "\u4ECA\u5929"
396
+ },
397
+ /** 昨天 */
398
+ YESTERDAY: {
399
+ en: "Yesterday",
400
+ "zh-CN": "\u6628\u5929"
401
+ },
402
+ // --- 从 config-strategy.ts 迁移 ---
403
+ /** (未设置) */
404
+ NOT_SET: {
405
+ en: "(not set)",
406
+ "zh-CN": "(\u672A\u8BBE\u7F6E)"
407
+ },
408
+ /** 非交互模式下无法使用交互式配置编辑器 */
409
+ NON_INTERACTIVE_CONFIG_EDITOR: {
410
+ en: "Cannot use interactive config editor in non-interactive mode. Please use: clawt config set <key> <value>",
411
+ "zh-CN": "\u975E\u4EA4\u4E92\u6A21\u5F0F\u4E0B\u65E0\u6CD5\u4F7F\u7528\u4EA4\u4E92\u5F0F\u914D\u7F6E\u7F16\u8F91\u5668\uFF0C\u8BF7\u4F7F\u7528 clawt config set <key> <value>"
412
+ },
413
+ /** 请输入有效的数字 */
414
+ INVALID_NUMBER_PROMPT: {
415
+ en: "Please enter a valid number",
416
+ "zh-CN": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u6570\u5B57"
417
+ },
418
+ // --- 从 commands/config.ts 迁移 ---
419
+ /** 当前配置将被覆盖为默认值 */
420
+ CONFIG_RESET_WARNING: {
421
+ en: "Current configuration will be reset to defaults",
422
+ "zh-CN": "\u5F53\u524D\u914D\u7F6E\u5C06\u88AB\u8986\u76D6\u4E3A\u9ED8\u8BA4\u503C"
423
+ }
79
424
  };
425
+ var COMMON_MESSAGES = createMessages(COMMON_MESSAGES_I18N);
80
426
 
81
427
  // src/constants/messages/run.ts
82
- var RUN_MESSAGES = {
428
+ var RUN_MESSAGES_I18N = {
83
429
  /** 分支已存在时提示使用 resume */
84
- BRANCH_EXISTS_USE_RESUME: (name) => `\u5206\u652F ${name} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u4F7F\u7528 clawt resume -b ${name} \u6062\u590D\u4F1A\u8BDD`,
430
+ BRANCH_EXISTS_USE_RESUME: {
431
+ en: (name) => `Branch ${name} already exists, please use clawt resume -b ${name} to resume session`,
432
+ "zh-CN": (name) => `\u5206\u652F ${name} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u4F7F\u7528 clawt resume -b ${name} \u6062\u590D\u4F1A\u8BDD`
433
+ },
85
434
  /** 检测到用户中断 */
86
- INTERRUPTED: "\u68C0\u6D4B\u5230\u9000\u51FA\u6307\u4EE4\uFF0C\u5DF2\u505C\u6B62 Claude Code \u4EFB\u52A1",
435
+ INTERRUPTED: {
436
+ en: "Exit signal detected, Claude Code tasks stopped",
437
+ "zh-CN": "\u68C0\u6D4B\u5230\u9000\u51FA\u6307\u4EE4\uFF0C\u5DF2\u505C\u6B62 Claude Code \u4EFB\u52A1"
438
+ },
87
439
  /** 中断后自动清理完成 */
88
- INTERRUPT_AUTO_CLEANED: (count) => `\u2713 \u5DF2\u81EA\u52A8\u6E05\u7406 ${count} \u4E2A worktree \u548C\u5BF9\u5E94\u5206\u652F`,
440
+ INTERRUPT_AUTO_CLEANED: {
441
+ en: (count) => `\u2713 Auto-cleaned ${count} worktree(s) and corresponding branches`,
442
+ "zh-CN": (count) => `\u2713 \u5DF2\u81EA\u52A8\u6E05\u7406 ${count} \u4E2A worktree \u548C\u5BF9\u5E94\u5206\u652F`
443
+ },
89
444
  /** 中断后手动确认清理 */
90
- INTERRUPT_CONFIRM_CLEANUP: "\u662F\u5426\u79FB\u9664\u521A\u521A\u521B\u5EFA\u7684 worktree \u548C\u5BF9\u5E94\u5206\u652F\uFF1F",
445
+ INTERRUPT_CONFIRM_CLEANUP: {
446
+ en: "Remove the newly created worktrees and corresponding branches?",
447
+ "zh-CN": "\u662F\u5426\u79FB\u9664\u521A\u521A\u521B\u5EFA\u7684 worktree \u548C\u5BF9\u5E94\u5206\u652F\uFF1F"
448
+ },
91
449
  /** 中断后清理完成 */
92
- INTERRUPT_CLEANED: (count) => `\u2713 \u5DF2\u6E05\u7406 ${count} \u4E2A worktree \u548C\u5BF9\u5E94\u5206\u652F`,
450
+ INTERRUPT_CLEANED: {
451
+ en: (count) => `\u2713 Cleaned ${count} worktree(s) and corresponding branches`,
452
+ "zh-CN": (count) => `\u2713 \u5DF2\u6E05\u7406 ${count} \u4E2A worktree \u548C\u5BF9\u5E94\u5206\u652F`
453
+ },
93
454
  /** 中断后保留 worktree */
94
- INTERRUPT_KEPT: "\u5DF2\u4FDD\u7559 worktree\uFF0C\u53EF\u7A0D\u540E\u4F7F\u7528 clawt remove \u624B\u52A8\u6E05\u7406",
455
+ INTERRUPT_KEPT: {
456
+ en: "Worktrees kept, use clawt remove to clean up later",
457
+ "zh-CN": "\u5DF2\u4FDD\u7559 worktree\uFF0C\u53EF\u7A0D\u540E\u4F7F\u7528 clawt remove \u624B\u52A8\u6E05\u7406"
458
+ },
95
459
  /** 非 TTY 环境降级输出:任务启动 */
96
- PROGRESS_TASK_STARTED: (index, total, branch, path2) => `[${index}/${total}] ${branch} \u542F\u52A8 ${path2}`,
460
+ PROGRESS_TASK_STARTED: {
461
+ en: (index, total, branch, path2) => `[${index}/${total}] ${branch} started ${path2}`,
462
+ "zh-CN": (index, total, branch, path2) => `[${index}/${total}] ${branch} \u542F\u52A8 ${path2}`
463
+ },
97
464
  /** 非 TTY 环境降级输出:任务完成 */
98
- PROGRESS_TASK_DONE: (index, total, branch, duration, cost, detail) => `[${index}/${total}] ${branch} \u2713 \u5B8C\u6210 ${duration} ${cost} ${detail}`,
465
+ PROGRESS_TASK_DONE: {
466
+ en: (index, total, branch, duration, cost, detail) => `[${index}/${total}] ${branch} \u2713 done ${duration} ${cost} ${detail}`,
467
+ "zh-CN": (index, total, branch, duration, cost, detail) => `[${index}/${total}] ${branch} \u2713 \u5B8C\u6210 ${duration} ${cost} ${detail}`
468
+ },
99
469
  /** 非 TTY 环境降级输出:任务失败 */
100
- PROGRESS_TASK_FAILED: (index, total, branch, duration, detail) => `[${index}/${total}] ${branch} \u2717 \u5931\u8D25 ${duration} ${detail}`,
470
+ PROGRESS_TASK_FAILED: {
471
+ en: (index, total, branch, duration, detail) => `[${index}/${total}] ${branch} \u2717 failed ${duration} ${detail}`,
472
+ "zh-CN": (index, total, branch, duration, detail) => `[${index}/${total}] ${branch} \u2717 \u5931\u8D25 ${duration} ${detail}`
473
+ },
101
474
  /** 并发限制提示 */
102
- CONCURRENCY_INFO: (concurrency, total) => `\u5E76\u53D1\u9650\u5236: ${concurrency}\uFF0C\u5171 ${total} \u4E2A\u4EFB\u52A1`,
475
+ CONCURRENCY_INFO: {
476
+ en: (concurrency, total) => `Concurrency: ${concurrency}, total tasks: ${total}`,
477
+ "zh-CN": (concurrency, total) => `\u5E76\u53D1\u9650\u5236: ${concurrency}\uFF0C\u5171 ${total} \u4E2A\u4EFB\u52A1`
478
+ },
103
479
  /** 并发数无效提示 */
104
- CONCURRENCY_INVALID: "\u5E76\u53D1\u6570\u5FC5\u987B\u4E3A\u6B63\u6574\u6570",
480
+ CONCURRENCY_INVALID: {
481
+ en: "Concurrency must be a positive integer",
482
+ "zh-CN": "\u5E76\u53D1\u6570\u5FC5\u987B\u4E3A\u6B63\u6574\u6570"
483
+ },
105
484
  /** 任务文件不存在 */
106
- TASK_FILE_NOT_FOUND: (path2) => `\u4EFB\u52A1\u6587\u4EF6\u4E0D\u5B58\u5728: ${path2}`,
485
+ TASK_FILE_NOT_FOUND: {
486
+ en: (path2) => `Task file not found: ${path2}`,
487
+ "zh-CN": (path2) => `\u4EFB\u52A1\u6587\u4EF6\u4E0D\u5B58\u5728: ${path2}`
488
+ },
107
489
  /** 任务文件中没有解析到有效任务 */
108
- TASK_FILE_EMPTY: "\u4EFB\u52A1\u6587\u4EF6\u4E2D\u6CA1\u6709\u89E3\u6790\u5230\u6709\u6548\u4EFB\u52A1",
490
+ TASK_FILE_EMPTY: {
491
+ en: "No valid tasks found in the task file",
492
+ "zh-CN": "\u4EFB\u52A1\u6587\u4EF6\u4E2D\u6CA1\u6709\u89E3\u6790\u5230\u6709\u6548\u4EFB\u52A1"
493
+ },
109
494
  /** 任务文件中某个任务块缺少分支名 */
110
- TASK_FILE_MISSING_BRANCH: (blockIndex) => `\u4EFB\u52A1\u6587\u4EF6\u7B2C ${blockIndex} \u4E2A\u4EFB\u52A1\u5757\u7F3A\u5C11\u5206\u652F\u540D\uFF08# branch: ...\uFF09`,
495
+ TASK_FILE_MISSING_BRANCH: {
496
+ en: (blockIndex) => `Task block #${blockIndex} is missing branch name (# branch: ...)`,
497
+ "zh-CN": (blockIndex) => `\u4EFB\u52A1\u6587\u4EF6\u7B2C ${blockIndex} \u4E2A\u4EFB\u52A1\u5757\u7F3A\u5C11\u5206\u652F\u540D\uFF08# branch: ...\uFF09`
498
+ },
111
499
  /** 任务文件中某个任务块缺少任务描述 */
112
- TASK_FILE_MISSING_TASK: (branch) => `\u4EFB\u52A1\u6587\u4EF6\u4E2D\u5206\u652F ${branch} \u7F3A\u5C11\u4EFB\u52A1\u63CF\u8FF0`,
500
+ TASK_FILE_MISSING_TASK: {
501
+ en: (branch) => `Task file is missing task description for branch ${branch}`,
502
+ "zh-CN": (branch) => `\u4EFB\u52A1\u6587\u4EF6\u4E2D\u5206\u652F ${branch} \u7F3A\u5C11\u4EFB\u52A1\u63CF\u8FF0`
503
+ },
113
504
  /** 任务文件中某个任务块缺少任务描述(无分支名时按索引定位) */
114
- TASK_FILE_MISSING_TASK_BY_INDEX: (blockIndex) => `\u4EFB\u52A1\u6587\u4EF6\u7B2C ${blockIndex} \u4E2A\u4EFB\u52A1\u5757\u7F3A\u5C11\u4EFB\u52A1\u63CF\u8FF0`,
505
+ TASK_FILE_MISSING_TASK_BY_INDEX: {
506
+ en: (blockIndex) => `Task block #${blockIndex} is missing task description`,
507
+ "zh-CN": (blockIndex) => `\u4EFB\u52A1\u6587\u4EF6\u7B2C ${blockIndex} \u4E2A\u4EFB\u52A1\u5757\u7F3A\u5C11\u4EFB\u52A1\u63CF\u8FF0`
508
+ },
115
509
  /** --file 和 --tasks 不能同时使用 */
116
- FILE_AND_TASKS_CONFLICT: "--file \u548C --tasks \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528",
510
+ FILE_AND_TASKS_CONFLICT: {
511
+ en: "--file and --tasks cannot be used together",
512
+ "zh-CN": "--file \u548C --tasks \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528"
513
+ },
117
514
  /** 任务文件加载成功 */
118
- TASK_FILE_LOADED: (count, path2) => `\u2713 \u4ECE ${path2} \u52A0\u8F7D\u4E86 ${count} \u4E2A\u4EFB\u52A1`,
515
+ TASK_FILE_LOADED: {
516
+ en: (count, path2) => `\u2713 Loaded ${count} task(s) from ${path2}`,
517
+ "zh-CN": (count, path2) => `\u2713 \u4ECE ${path2} \u52A0\u8F7D\u4E86 ${count} \u4E2A\u4EFB\u52A1`
518
+ },
119
519
  /** 未指定 -b 或 -f */
120
- BRANCH_OR_FILE_REQUIRED: "\u8BF7\u6307\u5B9A -b \u5206\u652F\u540D\u6216 -f \u4EFB\u52A1\u6587\u4EF6",
520
+ BRANCH_OR_FILE_REQUIRED: {
521
+ en: "Please specify -b <branch> or -f <task-file>",
522
+ "zh-CN": "\u8BF7\u6307\u5B9A -b \u5206\u652F\u540D\u6216 -f \u4EFB\u52A1\u6587\u4EF6"
523
+ },
121
524
  /** dry-run 预览标题 */
122
- DRY_RUN_TITLE: "Dry Run \u9884\u89C8",
525
+ DRY_RUN_TITLE: {
526
+ en: "Dry Run Preview",
527
+ "zh-CN": "Dry Run \u9884\u89C8"
528
+ },
123
529
  /** dry-run 任务数量 */
124
- DRY_RUN_TASK_COUNT: (count) => `\u4EFB\u52A1\u6570: ${count}`,
530
+ DRY_RUN_TASK_COUNT: {
531
+ en: (count) => `Tasks: ${count}`,
532
+ "zh-CN": (count) => `\u4EFB\u52A1\u6570: ${count}`
533
+ },
125
534
  /** dry-run 并发数 */
126
- DRY_RUN_CONCURRENCY: (concurrency) => `\u5E76\u53D1\u6570: ${concurrency === 0 ? "\u4E0D\u9650\u5236" : concurrency}`,
535
+ DRY_RUN_CONCURRENCY: {
536
+ en: (concurrency) => `Concurrency: ${concurrency === 0 ? "unlimited" : concurrency}`,
537
+ "zh-CN": (concurrency) => `\u5E76\u53D1\u6570: ${concurrency === 0 ? "\u4E0D\u9650\u5236" : concurrency}`
538
+ },
127
539
  /** dry-run worktree 目录 */
128
- DRY_RUN_WORKTREE_DIR: (dir) => `Worktree: ${dir}`,
540
+ DRY_RUN_WORKTREE_DIR: {
541
+ en: (dir) => `Worktree: ${dir}`,
542
+ "zh-CN": (dir) => `Worktree: ${dir}`
543
+ },
129
544
  /** dry-run 分支已存在警告 */
130
- DRY_RUN_BRANCH_EXISTS_WARNING: (name) => `\u5206\u652F ${name} \u5DF2\u5B58\u5728`,
545
+ DRY_RUN_BRANCH_EXISTS_WARNING: {
546
+ en: (name) => `Branch ${name} already exists`,
547
+ "zh-CN": (name) => `\u5206\u652F ${name} \u5DF2\u5B58\u5728`
548
+ },
131
549
  /** dry-run 交互式模式提示(无任务描述) */
132
- DRY_RUN_INTERACTIVE_MODE: "\u6A21\u5F0F: \u4EA4\u4E92\u5F0F\uFF08\u65E0\u9884\u8BBE\u4EFB\u52A1\uFF09",
550
+ DRY_RUN_INTERACTIVE_MODE: {
551
+ en: "Mode: Interactive (no preset task)",
552
+ "zh-CN": "\u6A21\u5F0F: \u4EA4\u4E92\u5F0F\uFF08\u65E0\u9884\u8BBE\u4EFB\u52A1\uFF09"
553
+ },
133
554
  /** dry-run 预览完成且无冲突 */
134
- DRY_RUN_READY: "\u9884\u89C8\u5B8C\u6210\uFF0C\u65E0\u51B2\u7A81\u3002\u79FB\u9664 --dry-run \u5373\u53EF\u6B63\u5F0F\u6267\u884C\u3002",
555
+ DRY_RUN_READY: {
556
+ en: "Preview complete, no conflicts. Remove --dry-run to execute.",
557
+ "zh-CN": "\u9884\u89C8\u5B8C\u6210\uFF0C\u65E0\u51B2\u7A81\u3002\u79FB\u9664 --dry-run \u5373\u53EF\u6B63\u5F0F\u6267\u884C\u3002"
558
+ },
135
559
  /** dry-run 存在分支冲突 */
136
- DRY_RUN_HAS_CONFLICT: "\u5B58\u5728\u5206\u652F\u51B2\u7A81\uFF0C\u5B9E\u9645\u6267\u884C\u65F6\u5C06\u4F1A\u62A5\u9519\u3002\u8BF7\u5148\u5904\u7406\u51B2\u7A81\u7684\u5206\u652F\u3002"
560
+ DRY_RUN_HAS_CONFLICT: {
561
+ en: "Branch conflicts detected. Execution will fail. Please resolve conflicting branches first.",
562
+ "zh-CN": "\u5B58\u5728\u5206\u652F\u51B2\u7A81\uFF0C\u5B9E\u9645\u6267\u884C\u65F6\u5C06\u4F1A\u62A5\u9519\u3002\u8BF7\u5148\u5904\u7406\u51B2\u7A81\u7684\u5206\u652F\u3002"
563
+ },
564
+ // --- 从 dry-run.ts 迁移 ---
565
+ /** 路径标签 */
566
+ PATH_LABEL: {
567
+ en: "Path:",
568
+ "zh-CN": "\u8DEF\u5F84:"
569
+ },
570
+ /** 任务标签 */
571
+ TASK_LABEL: {
572
+ en: "Task:",
573
+ "zh-CN": "\u4EFB\u52A1:"
574
+ },
575
+ // --- 从 task-executor.ts 迁移 ---
576
+ /** 任务执行失败 */
577
+ TASK_FAILED: {
578
+ en: "Task execution failed",
579
+ "zh-CN": "\u4EFB\u52A1\u6267\u884C\u5931\u8D25"
580
+ },
581
+ /** 全部任务已完成 */
582
+ ALL_TASKS_COMPLETED: {
583
+ en: (total) => `All tasks completed (${total}/${total})`,
584
+ "zh-CN": (total) => `\u5168\u90E8\u4EFB\u52A1\u5DF2\u5B8C\u6210 (${total}/${total})`
585
+ },
586
+ /** 成功标签 */
587
+ SUCCESS_LABEL: {
588
+ en: "Succeeded:",
589
+ "zh-CN": "\u6210\u529F:"
590
+ },
591
+ /** 失败标签 */
592
+ FAILURE_LABEL: {
593
+ en: "Failed:",
594
+ "zh-CN": "\u5931\u8D25:"
595
+ },
596
+ /** 总耗时标签 */
597
+ TOTAL_DURATION_LABEL: {
598
+ en: "Total duration:",
599
+ "zh-CN": "\u603B\u8017\u65F6:"
600
+ },
601
+ /** 总花费标签 */
602
+ TOTAL_COST_LABEL: {
603
+ en: "Total cost:",
604
+ "zh-CN": "\u603B\u82B1\u8D39:"
605
+ }
137
606
  };
607
+ var RUN_MESSAGES = createMessages(RUN_MESSAGES_I18N);
138
608
 
139
609
  // src/constants/messages/create.ts
140
- var CREATE_MESSAGES = {
610
+ var CREATE_MESSAGES_I18N = {
141
611
  /** 创建数量参数无效 */
142
- INVALID_COUNT: (value) => `\u65E0\u6548\u7684\u521B\u5EFA\u6570\u91CF: "${value}"\uFF0C\u8BF7\u8F93\u5165\u6B63\u6574\u6570`,
612
+ INVALID_COUNT: {
613
+ en: (value) => `Invalid count: "${value}", please enter a positive integer`,
614
+ "zh-CN": (value) => `\u65E0\u6548\u7684\u521B\u5EFA\u6570\u91CF: "${value}"\uFF0C\u8BF7\u8F93\u5165\u6B63\u6574\u6570`
615
+ },
143
616
  /** 当前不在主工作分支上的警告 */
144
- CREATE_WARN_NOT_ON_MAIN_BRANCH: (mainBranch, currentBranch) => `\u5F53\u524D\u4E0D\u5728\u4E3B\u5DE5\u4F5C\u5206\u652F ${mainBranch} \u4E0A\uFF08\u5F53\u524D: ${currentBranch}\uFF09`
617
+ CREATE_WARN_NOT_ON_MAIN_BRANCH: {
618
+ en: (mainBranch, currentBranch) => `Not on main work branch ${mainBranch} (current: ${currentBranch})`,
619
+ "zh-CN": (mainBranch, currentBranch) => `\u5F53\u524D\u4E0D\u5728\u4E3B\u5DE5\u4F5C\u5206\u652F ${mainBranch} \u4E0A\uFF08\u5F53\u524D: ${currentBranch}\uFF09`
620
+ }
145
621
  };
622
+ var CREATE_MESSAGES = createMessages(CREATE_MESSAGES_I18N);
146
623
 
147
624
  // src/constants/messages/merge.ts
148
- var MERGE_MESSAGES = {
625
+ var MERGE_MESSAGES_I18N = {
149
626
  /** merge 成功 */
150
- MERGE_SUCCESS: (branch, message, pushed) => `\u2713 \u5206\u652F ${branch} \u5DF2\u6210\u529F\u5408\u5E76\u5230\u5F53\u524D\u5206\u652F
151
- \u63D0\u4EA4\u4FE1\u606F: ${message}${pushed ? "\n \u5DF2\u63A8\u9001\u5230\u8FDC\u7A0B\u4ED3\u5E93" : ""}`,
627
+ MERGE_SUCCESS: {
628
+ en: (branch, message, pushed) => `\u2713 Branch ${branch} successfully merged into current branch
629
+ Commit message: ${message}${pushed ? "\n Pushed to remote" : ""}`,
630
+ "zh-CN": (branch, message, pushed) => `\u2713 \u5206\u652F ${branch} \u5DF2\u6210\u529F\u5408\u5E76\u5230\u5F53\u524D\u5206\u652F
631
+ \u63D0\u4EA4\u4FE1\u606F: ${message}${pushed ? "\n \u5DF2\u63A8\u9001\u5230\u8FDC\u7A0B\u4ED3\u5E93" : ""}`
632
+ },
152
633
  /** merge 成功(无提交信息,目标 worktree 已提交过) */
153
- MERGE_SUCCESS_NO_MESSAGE: (branch, pushed) => `\u2713 \u5206\u652F ${branch} \u5DF2\u6210\u529F\u5408\u5E76\u5230\u5F53\u524D\u5206\u652F${pushed ? "\n \u5DF2\u63A8\u9001\u5230\u8FDC\u7A0B\u4ED3\u5E93" : ""}`,
634
+ MERGE_SUCCESS_NO_MESSAGE: {
635
+ en: (branch, pushed) => `\u2713 Branch ${branch} successfully merged into current branch${pushed ? "\n Pushed to remote" : ""}`,
636
+ "zh-CN": (branch, pushed) => `\u2713 \u5206\u652F ${branch} \u5DF2\u6210\u529F\u5408\u5E76\u5230\u5F53\u524D\u5206\u652F${pushed ? "\n \u5DF2\u63A8\u9001\u5230\u8FDC\u7A0B\u4ED3\u5E93" : ""}`
637
+ },
154
638
  /** merge 冲突 */
155
- MERGE_CONFLICT: "\u5408\u5E76\u5B58\u5728\u51B2\u7A81\uFF0C\u8BF7\u624B\u52A8\u5904\u7406\uFF1A\n \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git merge --continue",
639
+ MERGE_CONFLICT: {
640
+ en: "Merge has conflicts, please resolve manually:\n After resolving, run git add . && git merge --continue",
641
+ "zh-CN": "\u5408\u5E76\u5B58\u5728\u51B2\u7A81\uFF0C\u8BF7\u624B\u52A8\u5904\u7406\uFF1A\n \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git merge --continue"
642
+ },
156
643
  /** merge 后清理 worktree 和分支成功 */
157
- WORKTREE_CLEANED: (branch) => `\u2713 \u5DF2\u6E05\u7406 worktree \u548C\u5206\u652F: ${branch}`,
644
+ WORKTREE_CLEANED: {
645
+ en: (branch) => `\u2713 Cleaned worktree and branch: ${branch}`,
646
+ "zh-CN": (branch) => `\u2713 \u5DF2\u6E05\u7406 worktree \u548C\u5206\u652F: ${branch}`
647
+ },
158
648
  /** 目标 worktree 有未提交修改但未指定 -m */
159
- TARGET_WORKTREE_DIRTY_NO_MESSAGE: (worktreePath) => `${worktreePath} \u6709\u672A\u63D0\u4EA4\u7684\u4FEE\u6539\uFF0C\u8BF7\u901A\u8FC7 -m \u53C2\u6570\u63D0\u4F9B\u63D0\u4EA4\u4FE1\u606F`,
649
+ TARGET_WORKTREE_DIRTY_NO_MESSAGE: {
650
+ en: (worktreePath) => `${worktreePath} has uncommitted changes, please provide a commit message via -m option`,
651
+ "zh-CN": (worktreePath) => `${worktreePath} \u6709\u672A\u63D0\u4EA4\u7684\u4FEE\u6539\uFF0C\u8BF7\u901A\u8FC7 -m \u53C2\u6570\u63D0\u4F9B\u63D0\u4EA4\u4FE1\u606F`
652
+ },
160
653
  /** 目标 worktree 既干净又无本地提交 */
161
- TARGET_WORKTREE_NO_CHANGES: "\u76EE\u6807 worktree \u6CA1\u6709\u4EFB\u4F55\u53EF\u5408\u5E76\u7684\u53D8\u66F4\uFF08\u5DE5\u4F5C\u533A\u5E72\u51C0\u4E14\u65E0\u672C\u5730\u63D0\u4EA4\uFF09",
654
+ TARGET_WORKTREE_NO_CHANGES: {
655
+ en: "Target worktree has no changes to merge (working directory clean and no local commits)",
656
+ "zh-CN": "\u76EE\u6807 worktree \u6CA1\u6709\u4EFB\u4F55\u53EF\u5408\u5E76\u7684\u53D8\u66F4\uFF08\u5DE5\u4F5C\u533A\u5E72\u51C0\u4E14\u65E0\u672C\u5730\u63D0\u4EA4\uFF09"
657
+ },
162
658
  /** merge 命令检测到 validate 状态的提示 */
163
- MERGE_VALIDATE_STATE_HINT: (branch) => `\u4E3B worktree \u53EF\u80FD\u5B58\u5728 validate \u6B8B\u7559\u72B6\u6001\uFF0C\u53EF\u5148\u6267\u884C clawt validate -b ${branch} --clean \u6E05\u7406`,
659
+ MERGE_VALIDATE_STATE_HINT: {
660
+ en: (branch) => `Main worktree may have residual validate state, run clawt validate -b ${branch} --clean first`,
661
+ "zh-CN": (branch) => `\u4E3B worktree \u53EF\u80FD\u5B58\u5728 validate \u6B8B\u7559\u72B6\u6001\uFF0C\u53EF\u5148\u6267\u884C clawt validate -b ${branch} --clean \u6E05\u7406`
662
+ },
164
663
  /** merge 检测到 auto-save 提交,提示用户是否压缩 */
165
- MERGE_SQUASH_PROMPT: "\u68C0\u6D4B\u5230 sync \u4EA7\u751F\u7684\u4E34\u65F6\u63D0\u4EA4\uFF0C\u662F\u5426\u5C06\u6240\u6709\u63D0\u4EA4\u538B\u7F29\u4E3A\u4E00\u4E2A\uFF1F\n \u538B\u7F29\u540E\u53D8\u66F4\u5C06\u4FDD\u7559\u5728\u76EE\u6807worktree\u7684\u6682\u5B58\u533A\uFF0C\u9700\u8981\u91CD\u65B0\u63D0\u4EA4\uFF08\u53EF\u4F7F\u7528 Claude Code Cli\u6216\u5176\u4ED6\u5DE5\u5177\u751F\u6210\u63D0\u4EA4\u4FE1\u606F\uFF09",
664
+ MERGE_SQUASH_PROMPT: {
665
+ en: "Detected temporary commits from sync, squash all commits into one?\n After squashing, changes will remain in the target worktree staging area and need to be re-committed (you can use Claude Code CLI or other tools to generate the commit message)",
666
+ "zh-CN": "\u68C0\u6D4B\u5230 sync \u4EA7\u751F\u7684\u4E34\u65F6\u63D0\u4EA4\uFF0C\u662F\u5426\u5C06\u6240\u6709\u63D0\u4EA4\u538B\u7F29\u4E3A\u4E00\u4E2A\uFF1F\n \u538B\u7F29\u540E\u53D8\u66F4\u5C06\u4FDD\u7559\u5728\u76EE\u6807worktree\u7684\u6682\u5B58\u533A\uFF0C\u9700\u8981\u91CD\u65B0\u63D0\u4EA4\uFF08\u53EF\u4F7F\u7528 Claude Code Cli\u6216\u5176\u4ED6\u5DE5\u5177\u751F\u6210\u63D0\u4EA4\u4FE1\u606F\uFF09"
667
+ },
166
668
  /** squash 完成且通过 -m 直接提交后的提示 */
167
- MERGE_SQUASH_COMMITTED: (branch) => `\u2713 \u5DF2\u5C06\u5206\u652F ${branch} \u7684\u6240\u6709\u63D0\u4EA4\u538B\u7F29\u4E3A\u4E00\u4E2A`,
669
+ MERGE_SQUASH_COMMITTED: {
670
+ en: (branch) => `\u2713 All commits from branch ${branch} squashed into one`,
671
+ "zh-CN": (branch) => `\u2713 \u5DF2\u5C06\u5206\u652F ${branch} \u7684\u6240\u6709\u63D0\u4EA4\u538B\u7F29\u4E3A\u4E00\u4E2A`
672
+ },
168
673
  /** squash 完成但未提供 -m,提示用户自行提交 */
169
- MERGE_SQUASH_PENDING: (worktreePath, branch) => `\u2713 \u5DF2\u5C06\u6240\u6709\u63D0\u4EA4\u538B\u7F29\u5230\u6682\u5B58\u533A
674
+ MERGE_SQUASH_PENDING: {
675
+ en: (worktreePath, branch) => `\u2713 All commits squashed into staging area
676
+ Please commit in the target worktree, then re-run merge:
677
+ cd ${worktreePath}
678
+ After committing, run: clawt merge -b ${branch}`,
679
+ "zh-CN": (worktreePath, branch) => `\u2713 \u5DF2\u5C06\u6240\u6709\u63D0\u4EA4\u538B\u7F29\u5230\u6682\u5B58\u533A
170
680
  \u8BF7\u5728\u76EE\u6807 worktree \u4E2D\u63D0\u4EA4\u540E\u91CD\u65B0\u6267\u884C merge\uFF1A
171
681
  cd ${worktreePath}
172
- \u63D0\u4EA4\u5B8C\u6210\u540E\u6267\u884C\uFF1Aclawt merge -b ${branch}`,
682
+ \u63D0\u4EA4\u5B8C\u6210\u540E\u6267\u884C\uFF1Aclawt merge -b ${branch}`
683
+ },
173
684
  /** merge 后 pull 冲突 */
174
- PULL_CONFLICT: "\u81EA\u52A8 pull \u65F6\u53D1\u751F\u51B2\u7A81\uFF0Cmerge \u5DF2\u5B8C\u6210\u4F46\u8FDC\u7A0B\u540C\u6B65\u5931\u8D25\n \u8BF7\u624B\u52A8\u89E3\u51B3\u51B2\u7A81\uFF1A\n \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git commit\n \u7136\u540E\u6267\u884C git push \u63A8\u9001\u5230\u8FDC\u7A0B",
685
+ PULL_CONFLICT: {
686
+ en: "Conflict during auto-pull, merge completed but remote sync failed\n Please resolve manually:\n After resolving, run git add . && git commit\n Then run git push to push to remote",
687
+ "zh-CN": "\u81EA\u52A8 pull \u65F6\u53D1\u751F\u51B2\u7A81\uFF0Cmerge \u5DF2\u5B8C\u6210\u4F46\u8FDC\u7A0B\u540C\u6B65\u5931\u8D25\n \u8BF7\u624B\u52A8\u89E3\u51B3\u51B2\u7A81\uFF1A\n \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git commit\n \u7136\u540E\u6267\u884C git push \u63A8\u9001\u5230\u8FDC\u7A0B"
688
+ },
175
689
  /** push 失败 */
176
- PUSH_FAILED: "\u81EA\u52A8 push \u5931\u8D25\uFF0Cmerge \u548C pull \u5DF2\u5B8C\u6210\n \u8BF7\u624B\u52A8\u6267\u884C git push",
690
+ PUSH_FAILED: {
691
+ en: "Auto-push failed, merge and pull completed\n Please run git push manually",
692
+ "zh-CN": "\u81EA\u52A8 push \u5931\u8D25\uFF0Cmerge \u548C pull \u5DF2\u5B8C\u6210\n \u8BF7\u624B\u52A8\u6267\u884C git push"
693
+ },
177
694
  /** merge 无可用 worktree */
178
- MERGE_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA",
695
+ MERGE_NO_WORKTREES: {
696
+ en: "No worktrees available, please create one with clawt run or clawt create first",
697
+ "zh-CN": "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA"
698
+ },
179
699
  /** merge 模糊匹配无结果,列出可用分支 */
180
- MERGE_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
181
- \u53EF\u7528\u5206\u652F\uFF1A
700
+ MERGE_NO_MATCH: {
701
+ en: (name, branches) => `No branch matching "${name}"
702
+ Available branches:
182
703
  ${branches.map((b) => ` - ${b}`).join("\n")}`,
704
+ "zh-CN": (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
705
+ \u53EF\u7528\u5206\u652F\uFF1A
706
+ ${branches.map((b) => ` - ${b}`).join("\n")}`
707
+ },
183
708
  /** merge 交互选择提示 */
184
- MERGE_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u5408\u5E76\u7684\u5206\u652F",
709
+ MERGE_SELECT_BRANCH: {
710
+ en: "Select a branch to merge",
711
+ "zh-CN": "\u8BF7\u9009\u62E9\u8981\u5408\u5E76\u7684\u5206\u652F"
712
+ },
185
713
  /** merge 模糊匹配到多个结果提示 */
186
- MERGE_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`,
714
+ MERGE_MULTIPLE_MATCHES: {
715
+ en: (name) => `"${name}" matched multiple branches, please select:`,
716
+ "zh-CN": (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`
717
+ },
187
718
  /** 询问是否使用 AI 辅助解决冲突 */
188
- MERGE_CONFLICT_ASK_AI: "\u68C0\u6D4B\u5230\u5408\u5E76\u51B2\u7A81\uFF0C\u662F\u5426\u4F7F\u7528 Claude Code \u81EA\u52A8\u89E3\u51B3\uFF1F",
719
+ MERGE_CONFLICT_ASK_AI: {
720
+ en: "Merge conflict detected, use Claude Code to auto-resolve?",
721
+ "zh-CN": "\u68C0\u6D4B\u5230\u5408\u5E76\u51B2\u7A81\uFF0C\u662F\u5426\u4F7F\u7528 Claude Code \u81EA\u52A8\u89E3\u51B3\uFF1F"
722
+ },
189
723
  /** AI 冲突解决开始 */
190
- MERGE_CONFLICT_AI_START: (fileCount) => `\u6B63\u5728\u4F7F\u7528 Claude Code \u5206\u6790\u5E76\u89E3\u51B3 ${fileCount} \u4E2A\u51B2\u7A81\u6587\u4EF6...`,
724
+ MERGE_CONFLICT_AI_START: {
725
+ en: (fileCount) => `Using Claude Code to analyze and resolve ${fileCount} conflicting file(s)...`,
726
+ "zh-CN": (fileCount) => `\u6B63\u5728\u4F7F\u7528 Claude Code \u5206\u6790\u5E76\u89E3\u51B3 ${fileCount} \u4E2A\u51B2\u7A81\u6587\u4EF6...`
727
+ },
191
728
  /** AI 冲突解决成功 */
192
- MERGE_CONFLICT_AI_SUCCESS: "\u2713 Claude Code \u5DF2\u6210\u529F\u89E3\u51B3\u6240\u6709\u51B2\u7A81",
729
+ MERGE_CONFLICT_AI_SUCCESS: {
730
+ en: "\u2713 Claude Code successfully resolved all conflicts",
731
+ "zh-CN": "\u2713 Claude Code \u5DF2\u6210\u529F\u89E3\u51B3\u6240\u6709\u51B2\u7A81"
732
+ },
193
733
  /** AI 冲突解决后仍有未解决的冲突 */
194
- MERGE_CONFLICT_AI_PARTIAL: (remaining) => `Claude Code \u5DF2\u5904\u7406\u51B2\u7A81\u6587\u4EF6\uFF0C\u4F46\u4ECD\u6709 ${remaining} \u4E2A\u6587\u4EF6\u5B58\u5728\u51B2\u7A81
195
- \u8BF7\u624B\u52A8\u5904\u7406\u5269\u4F59\u51B2\u7A81\u540E\u6267\u884C git add . && git merge --continue`,
734
+ MERGE_CONFLICT_AI_PARTIAL: {
735
+ en: (remaining) => `Claude Code processed conflicts, but ${remaining} file(s) still have conflicts
736
+ Please resolve remaining conflicts manually, then run git add . && git merge --continue`,
737
+ "zh-CN": (remaining) => `Claude Code \u5DF2\u5904\u7406\u51B2\u7A81\u6587\u4EF6\uFF0C\u4F46\u4ECD\u6709 ${remaining} \u4E2A\u6587\u4EF6\u5B58\u5728\u51B2\u7A81
738
+ \u8BF7\u624B\u52A8\u5904\u7406\u5269\u4F59\u51B2\u7A81\u540E\u6267\u884C git add . && git merge --continue`
739
+ },
196
740
  /** AI 冲突解决失败 */
197
- MERGE_CONFLICT_AI_FAILED: (errorMsg) => `Claude Code \u89E3\u51B3\u51B2\u7A81\u5931\u8D25: ${errorMsg}
741
+ MERGE_CONFLICT_AI_FAILED: {
742
+ en: (errorMsg) => `Claude Code failed to resolve conflicts: ${errorMsg}
743
+ Please resolve manually:
744
+ After resolving, run git add . && git merge --continue`,
745
+ "zh-CN": (errorMsg) => `Claude Code \u89E3\u51B3\u51B2\u7A81\u5931\u8D25: ${errorMsg}
198
746
  \u8BF7\u624B\u52A8\u5904\u7406\uFF1A
199
- \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git merge --continue`,
747
+ \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git merge --continue`
748
+ },
200
749
  /** --auto 模式下的冲突手动解决(配置为 manual) */
201
- MERGE_CONFLICT_MANUAL: "\u5408\u5E76\u5B58\u5728\u51B2\u7A81\uFF0C\u8BF7\u624B\u52A8\u5904\u7406\uFF1A\n \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git merge --continue",
750
+ MERGE_CONFLICT_MANUAL: {
751
+ en: "Merge has conflicts, please resolve manually:\n After resolving, run git add . && git merge --continue",
752
+ "zh-CN": "\u5408\u5E76\u5B58\u5728\u51B2\u7A81\uFF0C\u8BF7\u624B\u52A8\u5904\u7406\uFF1A\n \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git merge --continue"
753
+ },
202
754
  /** 目标 worktree 有未提交修改时的交互式提交信息提示 */
203
- MERGE_PROMPT_COMMIT_MESSAGE: "\u76EE\u6807 worktree \u6709\u672A\u63D0\u4EA4\u7684\u4FEE\u6539\uFF0C\u8BF7\u8F93\u5165\u63D0\u4EA4\u4FE1\u606F",
755
+ MERGE_PROMPT_COMMIT_MESSAGE: {
756
+ en: "Target worktree has uncommitted changes, please enter a commit message",
757
+ "zh-CN": "\u76EE\u6807 worktree \u6709\u672A\u63D0\u4EA4\u7684\u4FEE\u6539\uFF0C\u8BF7\u8F93\u5165\u63D0\u4EA4\u4FE1\u606F"
758
+ },
204
759
  /** squash 后的交互式提交信息提示 */
205
- MERGE_SQUASH_PROMPT_COMMIT_MESSAGE: "\u8BF7\u8F93\u5165 squash \u540E\u7684\u63D0\u4EA4\u4FE1\u606F"
760
+ MERGE_SQUASH_PROMPT_COMMIT_MESSAGE: {
761
+ en: "Enter commit message after squash",
762
+ "zh-CN": "\u8BF7\u8F93\u5165 squash \u540E\u7684\u63D0\u4EA4\u4FE1\u606F"
763
+ },
764
+ // --- 从 prompt.ts 迁移 ---
765
+ /** 提交信息不能为空 */
766
+ COMMIT_MESSAGE_NOT_EMPTY: {
767
+ en: "Commit message cannot be empty",
768
+ "zh-CN": "\u63D0\u4EA4\u4FE1\u606F\u4E0D\u80FD\u4E3A\u7A7A"
769
+ },
770
+ // --- 从 commands/merge.ts 迁移 ---
771
+ /** 已配置自动删除 */
772
+ AUTO_DELETE_CONFIGURED: {
773
+ en: (branch) => `Auto-delete configured, worktree and branch will be cleaned up after merge: ${branch}`,
774
+ "zh-CN": (branch) => `\u5DF2\u914D\u7F6E\u81EA\u52A8\u5220\u9664\uFF0Cmerge \u6210\u529F\u540E\u5C06\u81EA\u52A8\u6E05\u7406 worktree \u548C\u5206\u652F: ${branch}`
775
+ },
776
+ /** 是否删除对应的 worktree 和分支 */
777
+ CONFIRM_DELETE_WORKTREE_BRANCH: {
778
+ en: (branch) => `Delete the corresponding worktree and branch (${branch})?`,
779
+ "zh-CN": (branch) => `\u662F\u5426\u5220\u9664\u5BF9\u5E94\u7684 worktree \u548C\u5206\u652F (${branch})\uFF1F`
780
+ }
206
781
  };
782
+ var MERGE_MESSAGES = createMessages(MERGE_MESSAGES_I18N);
207
783
 
208
784
  // src/constants/messages/validate.ts
209
- var VALIDATE_MESSAGES = {
785
+ var VALIDATE_MESSAGES_I18N = {
210
786
  /** validate 成功 */
211
- VALIDATE_SUCCESS: (branch) => `\u2713 \u5DF2\u5C06\u5206\u652F ${branch} \u7684\u53D8\u66F4\u5E94\u7528\u5230\u4E3B worktree
212
- \u53EF\u4EE5\u5F00\u59CB\u9A8C\u8BC1\u4E86`,
787
+ VALIDATE_SUCCESS: {
788
+ en: (branch) => `\u2713 Changes from branch ${branch} applied to main worktree
789
+ Ready for validation`,
790
+ "zh-CN": (branch) => `\u2713 \u5DF2\u5C06\u5206\u652F ${branch} \u7684\u53D8\u66F4\u5E94\u7528\u5230\u4E3B worktree
791
+ \u53EF\u4EE5\u5F00\u59CB\u9A8C\u8BC1\u4E86`
792
+ },
213
793
  /** 增量 validate 成功提示 */
214
- INCREMENTAL_VALIDATE_SUCCESS: (branch) => `\u2713 \u5DF2\u5C06\u5206\u652F ${branch} \u7684\u6700\u65B0\u53D8\u66F4\u5E94\u7528\u5230\u4E3B worktree\uFF08\u589E\u91CF\u6A21\u5F0F\uFF09
215
- \u6682\u5B58\u533A = \u4E0A\u6B21\u5FEB\u7167\uFF0C\u5DE5\u4F5C\u76EE\u5F55 = \u6700\u65B0\u53D8\u66F4`,
794
+ INCREMENTAL_VALIDATE_SUCCESS: {
795
+ en: (branch) => `\u2713 Latest changes from branch ${branch} applied to main worktree (incremental mode)
796
+ Staging area = last snapshot, Working directory = latest changes`,
797
+ "zh-CN": (branch) => `\u2713 \u5DF2\u5C06\u5206\u652F ${branch} \u7684\u6700\u65B0\u53D8\u66F4\u5E94\u7528\u5230\u4E3B worktree\uFF08\u589E\u91CF\u6A21\u5F0F\uFF09
798
+ \u6682\u5B58\u533A = \u4E0A\u6B21\u5FEB\u7167\uFF0C\u5DE5\u4F5C\u76EE\u5F55 = \u6700\u65B0\u53D8\u66F4`
799
+ },
216
800
  /** 增量 validate 降级为全量模式提示 */
217
- INCREMENTAL_VALIDATE_FALLBACK: "\u589E\u91CF\u5BF9\u6BD4\u5931\u8D25\uFF0C\u5DF2\u964D\u7EA7\u4E3A\u5168\u91CF\u6A21\u5F0F",
801
+ INCREMENTAL_VALIDATE_FALLBACK: {
802
+ en: "Incremental comparison failed, fell back to full mode",
803
+ "zh-CN": "\u589E\u91CF\u5BF9\u6BD4\u5931\u8D25\uFF0C\u5DF2\u964D\u7EA7\u4E3A\u5168\u91CF\u6A21\u5F0F"
804
+ },
218
805
  /** 增量 validate 检测到目标 worktree 无新变更 */
219
- INCREMENTAL_VALIDATE_NO_CHANGES: (branch) => `\u5206\u652F ${branch} \u81EA\u4E0A\u6B21 validate \u4EE5\u6765\u6CA1\u6709\u65B0\u7684\u53D8\u66F4\uFF0C\u5DF2\u6062\u590D\u5230\u4E0A\u6B21\u9A8C\u8BC1\u72B6\u6001`,
806
+ INCREMENTAL_VALIDATE_NO_CHANGES: {
807
+ en: (branch) => `Branch ${branch} has no new changes since last validate, restored to previous validation state`,
808
+ "zh-CN": (branch) => `\u5206\u652F ${branch} \u81EA\u4E0A\u6B21 validate \u4EE5\u6765\u6CA1\u6709\u65B0\u7684\u53D8\u66F4\uFF0C\u5DF2\u6062\u590D\u5230\u4E0A\u6B21\u9A8C\u8BC1\u72B6\u6001`
809
+ },
220
810
  /** validate 状态已清理 */
221
- VALIDATE_CLEANED: (branch) => `\u2713 \u5206\u652F ${branch} \u7684 validate \u72B6\u6001\u5DF2\u6E05\u7406`,
811
+ VALIDATE_CLEANED: {
812
+ en: (branch) => `\u2713 Validate state for branch ${branch} cleaned`,
813
+ "zh-CN": (branch) => `\u2713 \u5206\u652F ${branch} \u7684 validate \u72B6\u6001\u5DF2\u6E05\u7406`
814
+ },
222
815
  /** validate patch apply 失败,提示用户同步主分支 */
223
- VALIDATE_PATCH_APPLY_FAILED: (branch) => `\u53D8\u66F4\u8FC1\u79FB\u5931\u8D25\uFF1A\u76EE\u6807\u5206\u652F\u4E0E\u4E3B\u5206\u652F\u5DEE\u5F02\u8FC7\u5927
224
- \u8BF7\u5148\u6267\u884C clawt sync -b ${branch} \u540C\u6B65\u4E3B\u5206\u652F\u540E\u91CD\u8BD5`,
816
+ VALIDATE_PATCH_APPLY_FAILED: {
817
+ en: (branch) => `Change migration failed: target branch has diverged too far from main
818
+ Please run clawt sync -b ${branch} first, then retry`,
819
+ "zh-CN": (branch) => `\u53D8\u66F4\u8FC1\u79FB\u5931\u8D25\uFF1A\u76EE\u6807\u5206\u652F\u4E0E\u4E3B\u5206\u652F\u5DEE\u5F02\u8FC7\u5927
820
+ \u8BF7\u5148\u6267\u884C clawt sync -b ${branch} \u540C\u6B65\u4E3B\u5206\u652F\u540E\u91CD\u8BD5`
821
+ },
225
822
  /** validate 无可用 worktree */
226
- VALIDATE_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA",
823
+ VALIDATE_NO_WORKTREES: {
824
+ en: "No worktrees available, please create one with clawt run or clawt create first",
825
+ "zh-CN": "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA"
826
+ },
227
827
  /** validate 模糊匹配无结果,列出可用分支 */
228
- VALIDATE_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
229
- \u53EF\u7528\u5206\u652F\uFF1A
828
+ VALIDATE_NO_MATCH: {
829
+ en: (name, branches) => `No branch matching "${name}"
830
+ Available branches:
230
831
  ${branches.map((b) => ` - ${b}`).join("\n")}`,
832
+ "zh-CN": (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
833
+ \u53EF\u7528\u5206\u652F\uFF1A
834
+ ${branches.map((b) => ` - ${b}`).join("\n")}`
835
+ },
231
836
  /** validate 交互选择提示 */
232
- VALIDATE_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u9A8C\u8BC1\u7684\u5206\u652F",
837
+ VALIDATE_SELECT_BRANCH: {
838
+ en: "Select a branch to validate",
839
+ "zh-CN": "\u8BF7\u9009\u62E9\u8981\u9A8C\u8BC1\u7684\u5206\u652F"
840
+ },
233
841
  /** validate 模糊匹配到多个结果提示 */
234
- VALIDATE_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`,
842
+ VALIDATE_MULTIPLE_MATCHES: {
843
+ en: (name) => `"${name}" matched multiple branches, please select:`,
844
+ "zh-CN": (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`
845
+ },
235
846
  /** --run 命令开始执行提示 */
236
- VALIDATE_RUN_START: (command) => `\u6B63\u5728\u4E3B worktree \u4E2D\u6267\u884C\u547D\u4EE4: ${command}`,
847
+ VALIDATE_RUN_START: {
848
+ en: (command) => `Running command in main worktree: ${command}`,
849
+ "zh-CN": (command) => `\u6B63\u5728\u4E3B worktree \u4E2D\u6267\u884C\u547D\u4EE4: ${command}`
850
+ },
237
851
  /** --run 命令执行成功(退出码 0) */
238
- VALIDATE_RUN_SUCCESS: (command) => `\u2713 \u547D\u4EE4\u6267\u884C\u5B8C\u6210: ${command}\uFF0C\u9000\u51FA\u7801: 0`,
852
+ VALIDATE_RUN_SUCCESS: {
853
+ en: (command) => `\u2713 Command completed: ${command}, exit code: 0`,
854
+ "zh-CN": (command) => `\u2713 \u547D\u4EE4\u6267\u884C\u5B8C\u6210: ${command}\uFF0C\u9000\u51FA\u7801: 0`
855
+ },
239
856
  /** --run 命令执行失败(退出码非 0) */
240
- VALIDATE_RUN_FAILED: (command, exitCode) => `\u2717 \u547D\u4EE4\u6267\u884C\u5B8C\u6210: ${command}\uFF0C\u9000\u51FA\u7801: ${exitCode}`,
857
+ VALIDATE_RUN_FAILED: {
858
+ en: (command, exitCode) => `\u2717 Command completed: ${command}, exit code: ${exitCode}`,
859
+ "zh-CN": (command, exitCode) => `\u2717 \u547D\u4EE4\u6267\u884C\u5B8C\u6210: ${command}\uFF0C\u9000\u51FA\u7801: ${exitCode}`
860
+ },
241
861
  /** --run 命令执行异常(进程启动失败等) */
242
- VALIDATE_RUN_ERROR: (command, errorMessage) => `\u2717 \u547D\u4EE4\u6267\u884C\u51FA\u9519: ${errorMessage}`,
862
+ VALIDATE_RUN_ERROR: {
863
+ en: (command, errorMessage) => `\u2717 Command execution error: ${errorMessage}`,
864
+ "zh-CN": (command, errorMessage) => `\u2717 \u547D\u4EE4\u6267\u884C\u51FA\u9519: ${errorMessage}`
865
+ },
243
866
  /** 并行命令开始执行提示 */
244
- VALIDATE_PARALLEL_RUN_START: (count) => `\u6B63\u5728\u5E76\u884C\u6267\u884C ${count} \u4E2A\u547D\u4EE4...`,
867
+ VALIDATE_PARALLEL_RUN_START: {
868
+ en: (count) => `Running ${count} command(s) in parallel...`,
869
+ "zh-CN": (count) => `\u6B63\u5728\u5E76\u884C\u6267\u884C ${count} \u4E2A\u547D\u4EE4...`
870
+ },
245
871
  /** 并行执行中单个命令开始提示(带序号) */
246
- VALIDATE_PARALLEL_CMD_START: (index, total, command) => `[${index}/${total}] ${command}`,
872
+ VALIDATE_PARALLEL_CMD_START: {
873
+ en: (index, total, command) => `[${index}/${total}] ${command}`,
874
+ "zh-CN": (index, total, command) => `[${index}/${total}] ${command}`
875
+ },
247
876
  /** 并行执行全部成功汇总提示 */
248
- VALIDATE_PARALLEL_RUN_ALL_SUCCESS: (count) => `\u2713 \u5168\u90E8 ${count} \u4E2A\u547D\u4EE4\u6267\u884C\u6210\u529F`,
877
+ VALIDATE_PARALLEL_RUN_ALL_SUCCESS: {
878
+ en: (count) => `\u2713 All ${count} command(s) completed successfully`,
879
+ "zh-CN": (count) => `\u2713 \u5168\u90E8 ${count} \u4E2A\u547D\u4EE4\u6267\u884C\u6210\u529F`
880
+ },
249
881
  /** 并行执行部分失败汇总提示 */
250
- VALIDATE_PARALLEL_RUN_SUMMARY: (successCount, failedCount) => `\u5171 ${successCount + failedCount} \u4E2A\u547D\u4EE4\uFF0C${successCount} \u4E2A\u6210\u529F\uFF0C${failedCount} \u4E2A\u5931\u8D25`,
882
+ VALIDATE_PARALLEL_RUN_SUMMARY: {
883
+ en: (successCount, failedCount) => `${successCount + failedCount} command(s), ${successCount} succeeded, ${failedCount} failed`,
884
+ "zh-CN": (successCount, failedCount) => `\u5171 ${successCount + failedCount} \u4E2A\u547D\u4EE4\uFF0C${successCount} \u4E2A\u6210\u529F\uFF0C${failedCount} \u4E2A\u5931\u8D25`
885
+ },
251
886
  /** 并行执行中单个命令成功 */
252
- VALIDATE_PARALLEL_CMD_SUCCESS: (command) => ` \u2713 ${command}`,
887
+ VALIDATE_PARALLEL_CMD_SUCCESS: {
888
+ en: (command) => ` \u2713 ${command}`,
889
+ "zh-CN": (command) => ` \u2713 ${command}`
890
+ },
253
891
  /** 并行执行中单个命令失败 */
254
- VALIDATE_PARALLEL_CMD_FAILED: (command, exitCode) => ` \u2717 ${command}\uFF08\u9000\u51FA\u7801: ${exitCode}\uFF09`,
892
+ VALIDATE_PARALLEL_CMD_FAILED: {
893
+ en: (command, exitCode) => ` \u2717 ${command} (exit code: ${exitCode})`,
894
+ "zh-CN": (command, exitCode) => ` \u2717 ${command}\uFF08\u9000\u51FA\u7801: ${exitCode}\uFF09`
895
+ },
255
896
  /** 并行执行中单个命令启动失败 */
256
- VALIDATE_PARALLEL_CMD_ERROR: (command, errorMessage) => ` \u2717 ${command}\uFF08\u9519\u8BEF: ${errorMessage}\uFF09`,
897
+ VALIDATE_PARALLEL_CMD_ERROR: {
898
+ en: (command, errorMessage) => ` \u2717 ${command} (error: ${errorMessage})`,
899
+ "zh-CN": (command, errorMessage) => ` \u2717 ${command}\uFF08\u9519\u8BEF: ${errorMessage}\uFF09`
900
+ },
257
901
  /** patch apply 失败后询问用户是否执行 sync */
258
- VALIDATE_CONFIRM_AUTO_SYNC: (branch) => `\u662F\u5426\u7ACB\u5373\u6267\u884C sync \u540C\u6B65\u4E3B\u5206\u652F\u5230 ${branch}\uFF1F`,
902
+ VALIDATE_CONFIRM_AUTO_SYNC: {
903
+ en: (branch) => `Run sync now to sync main branch to ${branch}?`,
904
+ "zh-CN": (branch) => `\u662F\u5426\u7ACB\u5373\u6267\u884C sync \u540C\u6B65\u4E3B\u5206\u652F\u5230 ${branch}\uFF1F`
905
+ },
259
906
  /** 自动 sync 开始提示 */
260
- VALIDATE_AUTO_SYNC_START: (branch) => `\u6B63\u5728\u81EA\u52A8\u540C\u6B65\u4E3B\u5206\u652F\u5230 ${branch} ...`,
907
+ VALIDATE_AUTO_SYNC_START: {
908
+ en: (branch) => `Auto-syncing main branch to ${branch} ...`,
909
+ "zh-CN": (branch) => `\u6B63\u5728\u81EA\u52A8\u540C\u6B65\u4E3B\u5206\u652F\u5230 ${branch} ...`
910
+ },
261
911
  /** 用户拒绝自动 sync */
262
- VALIDATE_AUTO_SYNC_DECLINED: (branch) => `\u8BF7\u624B\u52A8\u6267\u884C clawt sync -b ${branch} \u540C\u6B65\u4E3B\u5206\u652F\u540E\u91CD\u8BD5`,
912
+ VALIDATE_AUTO_SYNC_DECLINED: {
913
+ en: (branch) => `Please run clawt sync -b ${branch} manually, then retry`,
914
+ "zh-CN": (branch) => `\u8BF7\u624B\u52A8\u6267\u884C clawt sync -b ${branch} \u540C\u6B65\u4E3B\u5206\u652F\u540E\u91CD\u8BD5`
915
+ },
263
916
  /** 验证分支不存在 */
264
- VALIDATE_BRANCH_NOT_FOUND: (validateBranch, branch) => `\u9A8C\u8BC1\u5206\u652F ${validateBranch} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C clawt create \u6216 clawt run \u521B\u5EFA\u5206\u652F ${branch}`,
917
+ VALIDATE_BRANCH_NOT_FOUND: {
918
+ en: (validateBranch, branch) => `Validation branch ${validateBranch} does not exist, please run clawt create or clawt run to create branch ${branch} first`,
919
+ "zh-CN": (validateBranch, branch) => `\u9A8C\u8BC1\u5206\u652F ${validateBranch} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C clawt create \u6216 clawt run \u521B\u5EFA\u5206\u652F ${branch}`
920
+ },
265
921
  /** validate 成功(含验证分支信息) */
266
- VALIDATE_SUCCESS_WITH_BRANCH: (branch, validateBranch) => `\u2713 \u5DF2\u5207\u6362\u5230\u9A8C\u8BC1\u5206\u652F ${validateBranch} \u5E76\u5E94\u7528\u5206\u652F ${branch} \u7684\u53D8\u66F4
267
- \u53EF\u4EE5\u5F00\u59CB\u9A8C\u8BC1\u4E86`,
922
+ VALIDATE_SUCCESS_WITH_BRANCH: {
923
+ en: (branch, validateBranch) => `\u2713 Switched to validation branch ${validateBranch} and applied changes from branch ${branch}
924
+ Ready for validation`,
925
+ "zh-CN": (branch, validateBranch) => `\u2713 \u5DF2\u5207\u6362\u5230\u9A8C\u8BC1\u5206\u652F ${validateBranch} \u5E76\u5E94\u7528\u5206\u652F ${branch} \u7684\u53D8\u66F4
926
+ \u53EF\u4EE5\u5F00\u59CB\u9A8C\u8BC1\u4E86`
927
+ },
268
928
  /** 错误信息已复制到剪贴板提示 */
269
- VALIDATE_RUN_ERROR_COPIED: "\u2702 \u9519\u8BEF\u4FE1\u606F\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F",
929
+ VALIDATE_RUN_ERROR_COPIED: {
930
+ en: "\u2702 Error information copied to clipboard",
931
+ "zh-CN": "\u2702 \u9519\u8BEF\u4FE1\u606F\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F"
932
+ },
270
933
  /** 剪贴板复制失败提示 */
271
- VALIDATE_RUN_ERROR_COPY_FAILED: "\u26A0 \u9519\u8BEF\u4FE1\u606F\u590D\u5236\u5230\u526A\u8D34\u677F\u5931\u8D25",
934
+ VALIDATE_RUN_ERROR_COPY_FAILED: {
935
+ en: "\u26A0 Failed to copy error information to clipboard",
936
+ "zh-CN": "\u26A0 \u9519\u8BEF\u4FE1\u606F\u590D\u5236\u5230\u526A\u8D34\u677F\u5931\u8D25"
937
+ },
272
938
  /** 检测到外部软链接警告 */
273
- VALIDATE_EXTERNAL_SYMLINKS_FOUND: (count) => `\u26A0 \u68C0\u6D4B\u5230 ${count} \u4E2A\u6307\u5411 worktree \u5916\u90E8\u7684\u8F6F\u94FE\u63A5\uFF08\u53EF\u80FD\u7531 AI Agent \u521B\u5EFA\uFF09\uFF0C\u5DF2\u81EA\u52A8\u79FB\u9664`,
939
+ VALIDATE_EXTERNAL_SYMLINKS_FOUND: {
940
+ en: (count) => `\u26A0 Detected ${count} symlink(s) pointing outside the worktree (possibly created by AI Agent), auto-removed`,
941
+ "zh-CN": (count) => `\u26A0 \u68C0\u6D4B\u5230 ${count} \u4E2A\u6307\u5411 worktree \u5916\u90E8\u7684\u8F6F\u94FE\u63A5\uFF08\u53EF\u80FD\u7531 AI Agent \u521B\u5EFA\uFF09\uFF0C\u5DF2\u81EA\u52A8\u79FB\u9664`
942
+ },
274
943
  /** 单命令(含 && 链)剪贴板错误格式 */
275
- VALIDATE_CLIPBOARD_SINGLE_ERROR: (command, stderr) => `${command} \u6307\u4EE4\u6267\u884C\u51FA\u9519\uFF0C\u9519\u8BEF\u4FE1\u606F\uFF1A
944
+ VALIDATE_CLIPBOARD_SINGLE_ERROR: {
945
+ en: (command, stderr) => `${command} command error:
276
946
  ${stderr}`,
947
+ "zh-CN": (command, stderr) => `${command} \u6307\u4EE4\u6267\u884C\u51FA\u9519\uFF0C\u9519\u8BEF\u4FE1\u606F\uFF1A
948
+ ${stderr}`
949
+ },
277
950
  /** 并行命令中单个命令的剪贴板错误格式 */
278
- VALIDATE_CLIPBOARD_PARALLEL_ERROR: (command, stderr) => `${command} \u6307\u4EE4\u6267\u884C\u51FA\u9519\uFF0C\u9519\u8BEF\u4FE1\u606F\uFF1A
951
+ VALIDATE_CLIPBOARD_PARALLEL_ERROR: {
952
+ en: (command, stderr) => `${command} command error:
279
953
  ${stderr}`,
954
+ "zh-CN": (command, stderr) => `${command} \u6307\u4EE4\u6267\u884C\u51FA\u9519\uFF0C\u9519\u8BEF\u4FE1\u606F\uFF1A
955
+ ${stderr}`
956
+ },
280
957
  /** 多个错误之间的分隔符 */
281
- VALIDATE_CLIPBOARD_SEPARATOR: "\n\n---\n\n"
958
+ VALIDATE_CLIPBOARD_SEPARATOR: {
959
+ en: "\n\n---\n\n",
960
+ "zh-CN": "\n\n---\n\n"
961
+ },
962
+ // --- 从 validate-branch.ts 迁移 ---
963
+ /** 工作区仍然不干净 */
964
+ WORKSPACE_STILL_DIRTY: {
965
+ en: "Workspace is still dirty, please resolve manually",
966
+ "zh-CN": "\u5DE5\u4F5C\u533A\u4ECD\u7136\u4E0D\u5E72\u51C0\uFF0C\u8BF7\u624B\u52A8\u5904\u7406"
967
+ },
968
+ /** 当前分支有未提交的更改 */
969
+ UNCOMMITTED_CHANGES_ON_BRANCH: {
970
+ en: "Current branch has uncommitted changes, please choose how to handle:\n",
971
+ "zh-CN": "\u5F53\u524D\u5206\u652F\u6709\u672A\u63D0\u4EA4\u7684\u66F4\u6539\uFF0C\u8BF7\u9009\u62E9\u5904\u7406\u65B9\u5F0F\uFF1A\n"
972
+ },
973
+ /** 选择处理方式 */
974
+ SELECT_ACTION: {
975
+ en: "Select action",
976
+ "zh-CN": "\u9009\u62E9\u5904\u7406\u65B9\u5F0F"
977
+ },
978
+ /** 是否继续执行? */
979
+ CONFIRM_CONTINUE_VALIDATE: {
980
+ en: "Continue?",
981
+ "zh-CN": "\u662F\u5426\u7EE7\u7EED\u6267\u884C\uFF1F"
982
+ },
983
+ /** 用户选择退出 */
984
+ USER_CHOSE_EXIT: {
985
+ en: "User chose to exit, please resolve workspace changes manually and retry",
986
+ "zh-CN": "\u7528\u6237\u9009\u62E9\u9000\u51FA\uFF0C\u8BF7\u624B\u52A8\u5904\u7406\u5DE5\u4F5C\u533A\u66F4\u6539\u540E\u91CD\u8BD5"
987
+ },
988
+ // --- 从 validate-runner.ts 迁移 ---
989
+ /** 指令执行出错,退出码 */
990
+ COMMAND_EXEC_ERROR: {
991
+ en: (command, exitCode) => `${command} command error, exit code: ${exitCode}`,
992
+ "zh-CN": (command, exitCode) => `${command} \u6307\u4EE4\u6267\u884C\u51FA\u9519\uFF0C\u9000\u51FA\u7801: ${exitCode}`
993
+ },
994
+ /** 退出码标签 */
995
+ EXIT_CODE_LABEL: {
996
+ en: (exitCode) => `Exit code: ${exitCode}`,
997
+ "zh-CN": (exitCode) => `\u9000\u51FA\u7801: ${exitCode}`
998
+ }
282
999
  };
1000
+ var VALIDATE_MESSAGES = createMessages(VALIDATE_MESSAGES_I18N);
283
1001
 
284
1002
  // src/constants/messages/sync.ts
285
- var SYNC_MESSAGES = {
1003
+ var SYNC_MESSAGES_I18N = {
286
1004
  /** sync 自动保存未提交变更 */
287
- SYNC_AUTO_COMMITTED: (branch) => `\u5DF2\u81EA\u52A8\u4FDD\u5B58 ${branch} \u5206\u652F\u7684\u672A\u63D0\u4EA4\u53D8\u66F4`,
1005
+ SYNC_AUTO_COMMITTED: {
1006
+ en: (branch) => `Auto-saved uncommitted changes on branch ${branch}`,
1007
+ "zh-CN": (branch) => `\u5DF2\u81EA\u52A8\u4FDD\u5B58 ${branch} \u5206\u652F\u7684\u672A\u63D0\u4EA4\u53D8\u66F4`
1008
+ },
288
1009
  /** sync 开始合并 */
289
- SYNC_MERGING: (targetBranch, mainBranch) => `\u6B63\u5728\u5C06 ${mainBranch} \u5408\u5E76\u5230 ${targetBranch} ...`,
1010
+ SYNC_MERGING: {
1011
+ en: (targetBranch, mainBranch) => `Merging ${mainBranch} into ${targetBranch} ...`,
1012
+ "zh-CN": (targetBranch, mainBranch) => `\u6B63\u5728\u5C06 ${mainBranch} \u5408\u5E76\u5230 ${targetBranch} ...`
1013
+ },
290
1014
  /** sync 成功 */
291
- SYNC_SUCCESS: (targetBranch, mainBranch) => `\u2713 \u5DF2\u5C06 ${mainBranch} \u7684\u6700\u65B0\u4EE3\u7801\u540C\u6B65\u5230 ${targetBranch}`,
1015
+ SYNC_SUCCESS: {
1016
+ en: (targetBranch, mainBranch) => `\u2713 Synced latest code from ${mainBranch} to ${targetBranch}`,
1017
+ "zh-CN": (targetBranch, mainBranch) => `\u2713 \u5DF2\u5C06 ${mainBranch} \u7684\u6700\u65B0\u4EE3\u7801\u540C\u6B65\u5230 ${targetBranch}`
1018
+ },
292
1019
  /** sync 冲突 */
293
- SYNC_CONFLICT: (worktreePath) => `\u5408\u5E76\u5B58\u5728\u51B2\u7A81\uFF0C\u8BF7\u8FDB\u5165\u76EE\u6807 worktree \u624B\u52A8\u89E3\u51B3\uFF1A
1020
+ SYNC_CONFLICT: {
1021
+ en: (worktreePath) => `Merge conflicts detected. Please resolve them in the target worktree:
1022
+ cd ${worktreePath}
1023
+ After resolving conflicts, run: git add . && git merge --continue
1024
+ Then validate changes with: clawt validate -b <branch>`,
1025
+ "zh-CN": (worktreePath) => `\u5408\u5E76\u5B58\u5728\u51B2\u7A81\uFF0C\u8BF7\u8FDB\u5165\u76EE\u6807 worktree \u624B\u52A8\u89E3\u51B3\uFF1A
294
1026
  cd ${worktreePath}
295
1027
  \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git merge --continue
296
- clawt validate -b <branch> \u9A8C\u8BC1\u53D8\u66F4`,
1028
+ clawt validate -b <branch> \u9A8C\u8BC1\u53D8\u66F4`
1029
+ },
297
1030
  /** sync 无可用 worktree */
298
- SYNC_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA",
1031
+ SYNC_NO_WORKTREES: {
1032
+ en: "No worktrees available. Please create one with: clawt run or clawt create",
1033
+ "zh-CN": "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA"
1034
+ },
299
1035
  /** sync 模糊匹配无结果,列出可用分支 */
300
- SYNC_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
301
- \u53EF\u7528\u5206\u652F\uFF1A
1036
+ SYNC_NO_MATCH: {
1037
+ en: (name, branches) => `No branches matching "${name}"
1038
+ Available branches:
302
1039
  ${branches.map((b) => ` - ${b}`).join("\n")}`,
1040
+ "zh-CN": (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
1041
+ \u53EF\u7528\u5206\u652F\uFF1A
1042
+ ${branches.map((b) => ` - ${b}`).join("\n")}`
1043
+ },
303
1044
  /** sync 交互选择提示 */
304
- SYNC_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u540C\u6B65\u7684\u5206\u652F",
1045
+ SYNC_SELECT_BRANCH: {
1046
+ en: "Select branches to sync",
1047
+ "zh-CN": "\u8BF7\u9009\u62E9\u8981\u540C\u6B65\u7684\u5206\u652F"
1048
+ },
305
1049
  /** sync 模糊匹配到多个结果提示 */
306
- SYNC_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`,
1050
+ SYNC_MULTIPLE_MATCHES: {
1051
+ en: (name) => `"${name}" matched multiple branches, please select:`,
1052
+ "zh-CN": (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`
1053
+ },
307
1054
  /** sync 后验证分支已重建提示 */
308
- SYNC_VALIDATE_BRANCH_REBUILT: (validateBranch) => `\u9A8C\u8BC1\u5206\u652F ${validateBranch} \u5DF2\u91CD\u5EFA`
1055
+ SYNC_VALIDATE_BRANCH_REBUILT: {
1056
+ en: (validateBranch) => `Validation branch ${validateBranch} has been rebuilt`,
1057
+ "zh-CN": (validateBranch) => `\u9A8C\u8BC1\u5206\u652F ${validateBranch} \u5DF2\u91CD\u5EFA`
1058
+ }
309
1059
  };
1060
+ var SYNC_MESSAGES = createMessages(SYNC_MESSAGES_I18N);
310
1061
 
311
1062
  // src/constants/messages/resume.ts
312
- var RESUME_MESSAGES = {
1063
+ var RESUME_MESSAGES_I18N = {
313
1064
  /** resume 无可用 worktree */
314
- RESUME_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA",
1065
+ RESUME_NO_WORKTREES: {
1066
+ en: "No worktrees available, please create one with clawt run or clawt create first",
1067
+ "zh-CN": "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA"
1068
+ },
315
1069
  /** resume 模糊匹配无结果,列出可用分支 */
316
- RESUME_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
317
- \u53EF\u7528\u5206\u652F\uFF1A
1070
+ RESUME_NO_MATCH: {
1071
+ en: (name, branches) => `No branch matching "${name}"
1072
+ Available branches:
318
1073
  ${branches.map((b) => ` - ${b}`).join("\n")}`,
1074
+ "zh-CN": (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
1075
+ \u53EF\u7528\u5206\u652F\uFF1A
1076
+ ${branches.map((b) => ` - ${b}`).join("\n")}`
1077
+ },
319
1078
  /** resume 多选交互提示 */
320
- RESUME_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u6062\u590D\u7684\u5206\u652F\uFF08\u7A7A\u683C\u9009\u62E9\uFF0C\u56DE\u8F66\u786E\u8BA4\uFF09",
1079
+ RESUME_SELECT_BRANCH: {
1080
+ en: "Select branches to resume (space to select, enter to confirm)",
1081
+ "zh-CN": "\u8BF7\u9009\u62E9\u8981\u6062\u590D\u7684\u5206\u652F\uFF08\u7A7A\u683C\u9009\u62E9\uFF0C\u56DE\u8F66\u786E\u8BA4\uFF09"
1082
+ },
321
1083
  /** resume 模糊匹配到多个结果的多选提示 */
322
- RESUME_MULTIPLE_MATCHES: (keyword) => `"${keyword}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\u8981\u6062\u590D\u7684\uFF1A`,
1084
+ RESUME_MULTIPLE_MATCHES: {
1085
+ en: (keyword) => `"${keyword}" matched multiple branches, please select which to resume:`,
1086
+ "zh-CN": (keyword) => `"${keyword}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\u8981\u6062\u590D\u7684\uFF1A`
1087
+ },
323
1088
  /** 批量 resume 确认提示 */
324
- RESUME_ALL_CONFIRM: (count) => `\u5373\u5C06\u5728 ${count} \u4E2A\u72EC\u7ACB\u7EC8\u7AEF Tab \u4E2D\u6062\u590D Claude Code \u4F1A\u8BDD\uFF0C\u662F\u5426\u7EE7\u7EED\uFF1F`,
1089
+ RESUME_ALL_CONFIRM: {
1090
+ en: (count) => `About to resume Claude Code sessions in ${count} terminal tabs, continue?`,
1091
+ "zh-CN": (count) => `\u5373\u5C06\u5728 ${count} \u4E2A\u72EC\u7ACB\u7EC8\u7AEF Tab \u4E2D\u6062\u590D Claude Code \u4F1A\u8BDD\uFF0C\u662F\u5426\u7EE7\u7EED\uFF1F`
1092
+ },
325
1093
  /** 批量 resume 完成提示 */
326
- RESUME_ALL_SUCCESS: (count) => `\u5DF2\u5728 ${count} \u4E2A\u7EC8\u7AEF Tab \u4E2D\u542F\u52A8 Claude Code \u4F1A\u8BDD`,
1094
+ RESUME_ALL_SUCCESS: {
1095
+ en: (count) => `Claude Code sessions started in ${count} terminal tabs`,
1096
+ "zh-CN": (count) => `\u5DF2\u5728 ${count} \u4E2A\u7EC8\u7AEF Tab \u4E2D\u542F\u52A8 Claude Code \u4F1A\u8BDD`
1097
+ },
327
1098
  /** 批量 resume 非 macOS 平台提示 */
328
- RESUME_ALL_PLATFORM_UNSUPPORTED: "\u6279\u91CF resume \u76EE\u524D\u4EC5\u652F\u6301 macOS \u5E73\u53F0\uFF08\u901A\u8FC7 AppleScript \u6253\u5F00\u7EC8\u7AEF Tab\uFF09",
1099
+ RESUME_ALL_PLATFORM_UNSUPPORTED: {
1100
+ en: "Batch resume is only supported on macOS (via AppleScript to open terminal tabs)",
1101
+ "zh-CN": "\u6279\u91CF resume \u76EE\u524D\u4EC5\u652F\u6301 macOS \u5E73\u53F0\uFF08\u901A\u8FC7 AppleScript \u6253\u5F00\u7EC8\u7AEF Tab\uFF09"
1102
+ },
329
1103
  /** 批量 resume 无匹配分支提示 */
330
- RESUME_ALL_NO_MATCH: (keyword) => `\u672A\u627E\u5230\u4E0E "${keyword}" \u5339\u914D\u7684\u5206\u652F`,
1104
+ RESUME_ALL_NO_MATCH: {
1105
+ en: (keyword) => `No branch matching "${keyword}"`,
1106
+ "zh-CN": (keyword) => `\u672A\u627E\u5230\u4E0E "${keyword}" \u5339\u914D\u7684\u5206\u652F`
1107
+ },
331
1108
  /** --prompt 必须配合 -b 指定目标分支 */
332
- RESUME_PROMPT_REQUIRES_BRANCH: "--prompt \u5FC5\u987B\u914D\u5408 -b \u6307\u5B9A\u76EE\u6807\u5206\u652F",
1109
+ RESUME_PROMPT_REQUIRES_BRANCH: {
1110
+ en: "--prompt requires -b to specify the target branch",
1111
+ "zh-CN": "--prompt \u5FC5\u987B\u914D\u5408 -b \u6307\u5B9A\u76EE\u6807\u5206\u652F"
1112
+ },
333
1113
  /** --prompt 和 -f 不能同时使用 */
334
- RESUME_PROMPT_FILE_CONFLICT: "--prompt \u548C -f \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528",
1114
+ RESUME_PROMPT_FILE_CONFLICT: {
1115
+ en: "--prompt and -f cannot be used together",
1116
+ "zh-CN": "--prompt \u548C -f \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528"
1117
+ },
335
1118
  /** 未找到对应 worktree */
336
- RESUME_WORKTREE_NOT_FOUND: (branch, available) => `\u672A\u627E\u5230\u5206\u652F "${branch}" \u5BF9\u5E94\u7684 worktree
337
- \u53EF\u7528\u5206\u652F\uFF1A
1119
+ RESUME_WORKTREE_NOT_FOUND: {
1120
+ en: (branch, available) => `No worktree found for branch "${branch}"
1121
+ Available branches:
338
1122
  ${available.map((b) => ` - ${b}`).join("\n")}`,
1123
+ "zh-CN": (branch, available) => `\u672A\u627E\u5230\u5206\u652F "${branch}" \u5BF9\u5E94\u7684 worktree
1124
+ \u53EF\u7528\u5206\u652F\uFF1A
1125
+ ${available.map((b) => ` - ${b}`).join("\n")}`
1126
+ },
339
1127
  /** 追问文件加载完成 */
340
- RESUME_FOLLOW_UP_FILE_LOADED: (count, path2) => `\u4ECE ${path2} \u52A0\u8F7D\u4E86 ${count} \u4E2A\u8FFD\u95EE\u4EFB\u52A1`
1128
+ RESUME_FOLLOW_UP_FILE_LOADED: {
1129
+ en: (count, path2) => `Loaded ${count} follow-up task(s) from ${path2}`,
1130
+ "zh-CN": (count, path2) => `\u4ECE ${path2} \u52A0\u8F7D\u4E86 ${count} \u4E2A\u8FFD\u95EE\u4EFB\u52A1`
1131
+ },
1132
+ // --- 从 terminal.ts 迁移 ---
1133
+ /** 当前不在 cmux 环境中 */
1134
+ NOT_IN_CMUX: {
1135
+ en: "Not currently in a cmux environment, cannot create surface\nPlease run clawt resume from a cmux terminal, or change the terminalApp config",
1136
+ "zh-CN": "\u5F53\u524D\u4E0D\u5728 cmux \u73AF\u5883\u4E2D\uFF0C\u65E0\u6CD5\u521B\u5EFA surface\n\u8BF7\u786E\u4FDD\u5728 cmux \u7EC8\u7AEF\u4E2D\u6267\u884C clawt resume \u547D\u4EE4\uFF0C\u6216\u4FEE\u6539 terminalApp \u914D\u7F6E"
1137
+ },
1138
+ /** Terminal.app 辅助功能权限提示 */
1139
+ TERMINAL_ACCESSIBILITY_HINT: {
1140
+ en: "\nHint: Terminal.app requires Accessibility permission. Grant it in System Settings \u2192 Privacy & Security \u2192 Accessibility",
1141
+ "zh-CN": "\n\u63D0\u793A\uFF1ATerminal.app \u9700\u8981\u8F85\u52A9\u529F\u80FD\u6743\u9650\uFF0C\u8BF7\u5728\u300C\u7CFB\u7EDF\u8BBE\u7F6E \u2192 \u9690\u79C1\u4E0E\u5B89\u5168\u6027 \u2192 \u8F85\u52A9\u529F\u80FD\u300D\u4E2D\u6388\u6743\u7EC8\u7AEF\u5E94\u7528"
1142
+ },
1143
+ /** 批量 resume 仅支持 macOS */
1144
+ BATCH_RESUME_MACOS_ONLY: {
1145
+ en: "Batch resume is only supported on macOS",
1146
+ "zh-CN": "\u6279\u91CF resume \u76EE\u524D\u4EC5\u652F\u6301 macOS \u5E73\u53F0"
1147
+ },
1148
+ // --- 从 claude.ts 迁移 ---
1149
+ /** 正在 worktree 中启动 Claude Code 交互式界面 */
1150
+ STARTING_CLAUDE_INTERACTIVE: {
1151
+ en: "Starting Claude Code interactive session in worktree...",
1152
+ "zh-CN": "\u6B63\u5728 worktree \u4E2D\u542F\u52A8 Claude Code \u4EA4\u4E92\u5F0F\u754C\u9762..."
1153
+ },
1154
+ /** 分支标签 */
1155
+ BRANCH_LABEL: {
1156
+ en: "Branch:",
1157
+ "zh-CN": "\u5206\u652F:"
1158
+ },
1159
+ /** 路径标签(resume 专用,与 run 中的 PATH_LABEL 区分) */
1160
+ PATH_LABEL_RESUME: {
1161
+ en: "Path:",
1162
+ "zh-CN": "\u8DEF\u5F84:"
1163
+ },
1164
+ /** 指令标签 */
1165
+ COMMAND_LABEL: {
1166
+ en: "Command:",
1167
+ "zh-CN": "\u6307\u4EE4:"
1168
+ },
1169
+ /** 模式标签 */
1170
+ MODE_LABEL: {
1171
+ en: "Mode:",
1172
+ "zh-CN": "\u6A21\u5F0F:"
1173
+ },
1174
+ /** 继续上次对话 */
1175
+ CONTINUE_SESSION: {
1176
+ en: "Continue previous session",
1177
+ "zh-CN": "\u7EE7\u7EED\u4E0A\u6B21\u5BF9\u8BDD"
1178
+ },
1179
+ /** 新对话 */
1180
+ NEW_SESSION: {
1181
+ en: "New session",
1182
+ "zh-CN": "\u65B0\u5BF9\u8BDD"
1183
+ },
1184
+ /** 启动 Claude Code 失败 */
1185
+ CLAUDE_START_FAILED: {
1186
+ en: (message) => `Failed to start Claude Code: ${message}`,
1187
+ "zh-CN": (message) => `\u542F\u52A8 Claude Code \u5931\u8D25: ${message}`
1188
+ }
341
1189
  };
1190
+ var RESUME_MESSAGES = createMessages(RESUME_MESSAGES_I18N);
342
1191
 
343
1192
  // src/constants/messages/remove.ts
344
- var REMOVE_MESSAGES = {
1193
+ var REMOVE_MESSAGES_I18N = {
345
1194
  /** remove 无可用 worktree */
346
- REMOVE_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u65E0\u9700\u79FB\u9664",
1195
+ REMOVE_NO_WORKTREES: {
1196
+ en: "No worktrees available, nothing to remove",
1197
+ "zh-CN": "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u65E0\u9700\u79FB\u9664"
1198
+ },
347
1199
  /** remove 多选交互提示 */
348
- REMOVE_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u79FB\u9664\u7684\u5206\u652F\uFF08\u7A7A\u683C\u9009\u62E9\uFF0C\u56DE\u8F66\u786E\u8BA4\uFF09",
1200
+ REMOVE_SELECT_BRANCH: {
1201
+ en: "Select branches to remove (space to select, enter to confirm)",
1202
+ "zh-CN": "\u8BF7\u9009\u62E9\u8981\u79FB\u9664\u7684\u5206\u652F\uFF08\u7A7A\u683C\u9009\u62E9\uFF0C\u56DE\u8F66\u786E\u8BA4\uFF09"
1203
+ },
349
1204
  /** remove 模糊匹配到多个结果提示 */
350
- REMOVE_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\u8981\u79FB\u9664\u7684\uFF08\u7A7A\u683C\u9009\u62E9\uFF0C\u56DE\u8F66\u786E\u8BA4\uFF09\uFF1A`,
1205
+ REMOVE_MULTIPLE_MATCHES: {
1206
+ en: (name) => `"${name}" matched multiple branches, please select which to remove (space to select, enter to confirm):`,
1207
+ "zh-CN": (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\u8981\u79FB\u9664\u7684\uFF08\u7A7A\u683C\u9009\u62E9\uFF0C\u56DE\u8F66\u786E\u8BA4\uFF09\uFF1A`
1208
+ },
351
1209
  /** remove 模糊匹配无结果,列出可用分支 */
352
- REMOVE_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
353
- \u53EF\u7528\u5206\u652F\uFF1A
1210
+ REMOVE_NO_MATCH: {
1211
+ en: (name, branches) => `No branches matching "${name}"
1212
+ Available branches:
354
1213
  ${branches.map((b) => ` - ${b}`).join("\n")}`,
1214
+ "zh-CN": (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
1215
+ \u53EF\u7528\u5206\u652F\uFF1A
1216
+ ${branches.map((b) => ` - ${b}`).join("\n")}`
1217
+ },
355
1218
  /** 批量移除部分失败 */
356
- REMOVE_PARTIAL_FAILURE: (failures) => `\u4EE5\u4E0B worktree \u79FB\u9664\u5931\u8D25\uFF1A
1219
+ REMOVE_PARTIAL_FAILURE: {
1220
+ en: (failures) => `Failed to remove the following worktrees:
357
1221
  ${failures.map((f) => ` \u2717 ${f.path}: ${f.error}`).join("\n")}`,
1222
+ "zh-CN": (failures) => `\u4EE5\u4E0B worktree \u79FB\u9664\u5931\u8D25\uFF1A
1223
+ ${failures.map((f) => ` \u2717 ${f.path}: ${f.error}`).join("\n")}`
1224
+ },
358
1225
  /** 用户选择保留本地分支 */
359
- REMOVE_BRANCHES_KEPT: "\u5DF2\u4FDD\u7559\u672C\u5730\u5206\u652F\uFF0C\u53EF\u7A0D\u540E\u4F7F\u7528 git branch -D <\u5206\u652F\u540D> \u624B\u52A8\u5220\u9664",
1226
+ REMOVE_BRANCHES_KEPT: {
1227
+ en: "Local branches kept. You can manually delete them later with: git branch -D <branch-name>",
1228
+ "zh-CN": "\u5DF2\u4FDD\u7559\u672C\u5730\u5206\u652F\uFF0C\u53EF\u7A0D\u540E\u4F7F\u7528 git branch -D <\u5206\u652F\u540D> \u624B\u52A8\u5220\u9664"
1229
+ },
360
1230
  /** 确认删除本地分支和验证分支 */
361
- REMOVE_CONFIRM_DELETE_BRANCHES: "\u662F\u5426\u540C\u65F6\u5220\u9664\u5BF9\u5E94\u7684\u672C\u5730\u5206\u652F\u548C\u9A8C\u8BC1\u5206\u652F\uFF1F",
1231
+ REMOVE_CONFIRM_DELETE_BRANCHES: {
1232
+ en: "Also delete the associated local and validation branches?",
1233
+ "zh-CN": "\u662F\u5426\u540C\u65F6\u5220\u9664\u5BF9\u5E94\u7684\u672C\u5730\u5206\u652F\u548C\u9A8C\u8BC1\u5206\u652F\uFF1F"
1234
+ },
362
1235
  /** 待移除的 worktree 的分支是主 worktree 当前所在分支 */
363
- REMOVE_BRANCH_IS_CURRENT: (branch) => `\u65E0\u6CD5\u79FB\u9664\uFF1A\u5206\u652F ${branch} \u662F\u4E3B worktree \u5F53\u524D\u6240\u5728\u5206\u652F\uFF0C\u8BF7\u5148\u5207\u6362\u5230\u5176\u4ED6\u5206\u652F\u540E\u518D\u79FB\u9664`,
1236
+ REMOVE_BRANCH_IS_CURRENT: {
1237
+ en: (branch) => `Cannot remove: branch ${branch} is the current branch of the main worktree. Please switch to another branch first`,
1238
+ "zh-CN": (branch) => `\u65E0\u6CD5\u79FB\u9664\uFF1A\u5206\u652F ${branch} \u662F\u4E3B worktree \u5F53\u524D\u6240\u5728\u5206\u652F\uFF0C\u8BF7\u5148\u5207\u6362\u5230\u5176\u4ED6\u5206\u652F\u540E\u518D\u79FB\u9664`
1239
+ },
364
1240
  /** 待移除的 worktree 对应的验证分支是主 worktree 当前所在分支 */
365
- REMOVE_VALIDATE_BRANCH_IS_CURRENT: (branch, validateBranch) => `\u65E0\u6CD5\u79FB\u9664\uFF1A\u5206\u652F ${branch} \u7684\u9A8C\u8BC1\u5206\u652F ${validateBranch} \u662F\u4E3B worktree \u5F53\u524D\u6240\u5728\u5206\u652F\uFF0C\u8BF7\u5148\u5207\u6362\u5230\u5176\u4ED6\u5206\u652F\u540E\u518D\u79FB\u9664`
1241
+ REMOVE_VALIDATE_BRANCH_IS_CURRENT: {
1242
+ en: (branch, validateBranch) => `Cannot remove: the validation branch ${validateBranch} of branch ${branch} is the current branch of the main worktree. Please switch to another branch first`,
1243
+ "zh-CN": (branch, validateBranch) => `\u65E0\u6CD5\u79FB\u9664\uFF1A\u5206\u652F ${branch} \u7684\u9A8C\u8BC1\u5206\u652F ${validateBranch} \u662F\u4E3B worktree \u5F53\u524D\u6240\u5728\u5206\u652F\uFF0C\u8BF7\u5148\u5207\u6362\u5230\u5176\u4ED6\u5206\u652F\u540E\u518D\u79FB\u9664`
1244
+ }
366
1245
  };
1246
+ var REMOVE_MESSAGES = createMessages(REMOVE_MESSAGES_I18N);
367
1247
 
368
1248
  // src/constants/messages/reset.ts
369
- var RESET_MESSAGES = {
1249
+ var RESET_MESSAGES_I18N = {
370
1250
  /** reset 成功 */
371
- RESET_SUCCESS: "\u2713 \u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\u5DF2\u91CD\u7F6E",
1251
+ RESET_SUCCESS: {
1252
+ en: "\u2713 Main worktree working directory and staging area have been reset",
1253
+ "zh-CN": "\u2713 \u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\u5DF2\u91CD\u7F6E"
1254
+ },
372
1255
  /** reset 时工作区和暂存区已干净 */
373
- RESET_ALREADY_CLEAN: "\u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\u5DF2\u662F\u5E72\u51C0\u72B6\u6001\uFF0C\u65E0\u9700\u91CD\u7F6E"
1256
+ RESET_ALREADY_CLEAN: {
1257
+ en: "Main worktree working directory and staging area are already clean, no reset needed",
1258
+ "zh-CN": "\u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\u5DF2\u662F\u5E72\u51C0\u72B6\u6001\uFF0C\u65E0\u9700\u91CD\u7F6E"
1259
+ }
374
1260
  };
1261
+ var RESET_MESSAGES = createMessages(RESET_MESSAGES_I18N);
375
1262
 
376
1263
  // src/constants/messages/config.ts
377
- var CONFIG_ALIAS_DISABLED_HINT = "(\u901A\u8FC7 clawt alias \u547D\u4EE4\u7BA1\u7406)";
378
- var CONFIG_CMD_MESSAGES = {
1264
+ var CONFIG_ALIAS_DISABLED_HINT_I18N = {
1265
+ en: "(Manage via clawt alias command)",
1266
+ "zh-CN": "(\u901A\u8FC7 clawt alias \u547D\u4EE4\u7BA1\u7406)"
1267
+ };
1268
+ var CONFIG_ALIAS_DISABLED_HINT = createMessages({ HINT: CONFIG_ALIAS_DISABLED_HINT_I18N }).HINT;
1269
+ var CONFIG_CMD_MESSAGES_I18N = {
379
1270
  /** 配置已恢复为默认值 */
380
- CONFIG_RESET_SUCCESS: "\u2713 \u914D\u7F6E\u5DF2\u6062\u590D\u4E3A\u9ED8\u8BA4\u503C",
1271
+ CONFIG_RESET_SUCCESS: {
1272
+ en: "\u2713 Configuration reset to defaults",
1273
+ "zh-CN": "\u2713 \u914D\u7F6E\u5DF2\u6062\u590D\u4E3A\u9ED8\u8BA4\u503C"
1274
+ },
381
1275
  /** 配置项设置成功 */
382
- CONFIG_SET_SUCCESS: (key, value) => `\u2713 ${key} \u5DF2\u8BBE\u7F6E\u4E3A ${value}`,
1276
+ CONFIG_SET_SUCCESS: {
1277
+ en: (key, value) => `\u2713 ${key} set to ${value}`,
1278
+ "zh-CN": (key, value) => `\u2713 ${key} \u5DF2\u8BBE\u7F6E\u4E3A ${value}`
1279
+ },
383
1280
  /** 获取配置值显示 */
384
- CONFIG_GET_VALUE: (key, value) => `${key} = ${value}`,
1281
+ CONFIG_GET_VALUE: {
1282
+ en: (key, value) => `${key} = ${value}`,
1283
+ "zh-CN": (key, value) => `${key} = ${value}`
1284
+ },
385
1285
  /** 无效配置项名称 */
386
- CONFIG_INVALID_KEY: (key, validKeys) => `\u65E0\u6548\u7684\u914D\u7F6E\u9879: ${key}
387
- \u53EF\u7528\u7684\u914D\u7F6E\u9879: ${validKeys.join(", ")}`,
1286
+ CONFIG_INVALID_KEY: {
1287
+ en: (key, validKeys) => `Invalid config key: ${key}
1288
+ Available keys: ${validKeys.join(", ")}`,
1289
+ "zh-CN": (key, validKeys) => `\u65E0\u6548\u7684\u914D\u7F6E\u9879: ${key}
1290
+ \u53EF\u7528\u7684\u914D\u7F6E\u9879: ${validKeys.join(", ")}`
1291
+ },
388
1292
  /** 布尔类型值无效 */
389
- CONFIG_INVALID_BOOLEAN: (key) => `\u914D\u7F6E\u9879 ${key} \u4E3A\u5E03\u5C14\u7C7B\u578B\uFF0C\u4EC5\u63A5\u53D7 true \u6216 false`,
1293
+ CONFIG_INVALID_BOOLEAN: {
1294
+ en: (key) => `Config key ${key} is boolean, only accepts true or false`,
1295
+ "zh-CN": (key) => `\u914D\u7F6E\u9879 ${key} \u4E3A\u5E03\u5C14\u7C7B\u578B\uFF0C\u4EC5\u63A5\u53D7 true \u6216 false`
1296
+ },
390
1297
  /** 数字类型值无效 */
391
- CONFIG_INVALID_NUMBER: (key) => `\u914D\u7F6E\u9879 ${key} \u4E3A\u6570\u5B57\u7C7B\u578B\uFF0C\u8BF7\u8F93\u5165\u6709\u6548\u7684\u6570\u5B57`,
1298
+ CONFIG_INVALID_NUMBER: {
1299
+ en: (key) => `Config key ${key} is numeric, please enter a valid number`,
1300
+ "zh-CN": (key) => `\u914D\u7F6E\u9879 ${key} \u4E3A\u6570\u5B57\u7C7B\u578B\uFF0C\u8BF7\u8F93\u5165\u6709\u6548\u7684\u6570\u5B57`
1301
+ },
392
1302
  /** 枚举类型配置项值无效(通用版) */
393
- CONFIG_INVALID_ENUM: (key, validValues) => `\u914D\u7F6E\u9879 ${key} \u4EC5\u63A5\u53D7\u4EE5\u4E0B\u503C: ${validValues.join(", ")}`,
1303
+ CONFIG_INVALID_ENUM: {
1304
+ en: (key, validValues) => `Config key ${key} only accepts: ${validValues.join(", ")}`,
1305
+ "zh-CN": (key, validValues) => `\u914D\u7F6E\u9879 ${key} \u4EC5\u63A5\u53D7\u4EE5\u4E0B\u503C: ${validValues.join(", ")}`
1306
+ },
394
1307
  /** 交互式选择配置项提示 */
395
- CONFIG_SELECT_PROMPT: "\u9009\u62E9\u8981\u4FEE\u6539\u7684\u914D\u7F6E\u9879",
1308
+ CONFIG_SELECT_PROMPT: {
1309
+ en: "Select a config key to modify",
1310
+ "zh-CN": "\u9009\u62E9\u8981\u4FEE\u6539\u7684\u914D\u7F6E\u9879"
1311
+ },
396
1312
  /** 交互式输入新值提示 */
397
- CONFIG_INPUT_PROMPT: (key) => `\u8F93\u5165 ${key} \u7684\u65B0\u503C`,
1313
+ CONFIG_INPUT_PROMPT: {
1314
+ en: (key) => `Enter new value for ${key}`,
1315
+ "zh-CN": (key) => `\u8F93\u5165 ${key} \u7684\u65B0\u503C`
1316
+ },
398
1317
  /** 缺少 value 参数提示 */
399
- CONFIG_MISSING_VALUE: (key) => `\u7F3A\u5C11\u914D\u7F6E\u503C\uFF0C\u7528\u6CD5: clawt config set ${key} <value>`
1318
+ CONFIG_MISSING_VALUE: {
1319
+ en: (key) => `Missing value, usage: clawt config set ${key} <value>`,
1320
+ "zh-CN": (key) => `\u7F3A\u5C11\u914D\u7F6E\u503C\uFF0C\u7528\u6CD5: clawt config set ${key} <value>`
1321
+ }
400
1322
  };
1323
+ var CONFIG_CMD_MESSAGES = createMessages(CONFIG_CMD_MESSAGES_I18N);
401
1324
 
402
1325
  // src/constants/messages/status.ts
403
- var STATUS_MESSAGES = {
1326
+ var STATUS_MESSAGES_I18N = {
404
1327
  /** status 命令标题 */
405
- STATUS_TITLE: (projectName) => `\u9879\u76EE\u72B6\u6001\u603B\u89C8: ${projectName}`,
1328
+ STATUS_TITLE: {
1329
+ en: (projectName) => `Project Status Overview: ${projectName}`,
1330
+ "zh-CN": (projectName) => `\u9879\u76EE\u72B6\u6001\u603B\u89C8: ${projectName}`
1331
+ },
406
1332
  /** status 主 worktree 区块标题 */
407
- STATUS_MAIN_SECTION: "\u4E3B Worktree",
1333
+ STATUS_MAIN_SECTION: {
1334
+ en: "Main Worktree",
1335
+ "zh-CN": "\u4E3B Worktree"
1336
+ },
408
1337
  /** status worktrees 区块标题 */
409
- STATUS_WORKTREES_SECTION: "Worktree \u5217\u8868",
1338
+ STATUS_WORKTREES_SECTION: {
1339
+ en: "Worktrees",
1340
+ "zh-CN": "Worktree \u5217\u8868"
1341
+ },
410
1342
  /** status 快照区块标题 */
411
- STATUS_SNAPSHOTS_SECTION: "Validate \u5FEB\u7167",
1343
+ STATUS_SNAPSHOTS_SECTION: {
1344
+ en: "Validate Snapshots",
1345
+ "zh-CN": "Validate \u5FEB\u7167"
1346
+ },
412
1347
  /** status 无 worktree */
413
- STATUS_NO_WORKTREES: "(\u65E0\u6D3B\u8DC3 worktree)",
1348
+ STATUS_NO_WORKTREES: {
1349
+ en: "(No active worktrees)",
1350
+ "zh-CN": "(\u65E0\u6D3B\u8DC3 worktree)"
1351
+ },
414
1352
  /** status 无未清理快照 */
415
- STATUS_NO_SNAPSHOTS: "(\u65E0\u672A\u6E05\u7406\u7684\u5FEB\u7167)",
1353
+ STATUS_NO_SNAPSHOTS: {
1354
+ en: "(No pending snapshots)",
1355
+ "zh-CN": "(\u65E0\u672A\u6E05\u7406\u7684\u5FEB\u7167)"
1356
+ },
416
1357
  /** status 变更状态:已提交 */
417
- STATUS_CHANGE_COMMITTED: "\u5DF2\u63D0\u4EA4",
1358
+ STATUS_CHANGE_COMMITTED: {
1359
+ en: "Committed",
1360
+ "zh-CN": "\u5DF2\u63D0\u4EA4"
1361
+ },
418
1362
  /** status 变更状态:未提交修改 */
419
- STATUS_CHANGE_UNCOMMITTED: "\u672A\u63D0\u4EA4\u4FEE\u6539",
1363
+ STATUS_CHANGE_UNCOMMITTED: {
1364
+ en: "Uncommitted changes",
1365
+ "zh-CN": "\u672A\u63D0\u4EA4\u4FEE\u6539"
1366
+ },
420
1367
  /** status 变更状态:合并冲突 */
421
- STATUS_CHANGE_CONFLICT: "\u5408\u5E76\u51B2\u7A81",
1368
+ STATUS_CHANGE_CONFLICT: {
1369
+ en: "Merge conflict",
1370
+ "zh-CN": "\u5408\u5E76\u51B2\u7A81"
1371
+ },
422
1372
  /** status 变更状态:无变更 */
423
- STATUS_CHANGE_CLEAN: "\u65E0\u53D8\u66F4",
1373
+ STATUS_CHANGE_CLEAN: {
1374
+ en: "No changes",
1375
+ "zh-CN": "\u65E0\u53D8\u66F4"
1376
+ },
424
1377
  /** status 快照对应 worktree 已不存在 */
425
- STATUS_SNAPSHOT_ORPHANED: (count) => `\u5176\u4E2D ${count} \u4E2A\u5FEB\u7167\u5BF9\u5E94\u7684 worktree \u5DF2\u4E0D\u5B58\u5728`,
1378
+ STATUS_SNAPSHOT_ORPHANED: {
1379
+ en: (count) => `${count} snapshot(s) reference worktrees that no longer exist`,
1380
+ "zh-CN": (count) => `\u5176\u4E2D ${count} \u4E2A\u5FEB\u7167\u5BF9\u5E94\u7684 worktree \u5DF2\u4E0D\u5B58\u5728`
1381
+ },
426
1382
  /** status 分支创建时间标签 */
427
- STATUS_CREATED_AT: (relativeTime) => `\u521B\u5EFA\u4E8E ${relativeTime}`,
1383
+ STATUS_CREATED_AT: {
1384
+ en: (relativeTime) => `Created ${relativeTime}`,
1385
+ "zh-CN": (relativeTime) => `\u521B\u5EFA\u4E8E ${relativeTime}`
1386
+ },
428
1387
  /** status 分支无分叉提交时的提示 */
429
- STATUS_NO_DIVERGED_COMMITS: "\u5C1A\u65E0\u5206\u53C9\u63D0\u4EA4",
1388
+ STATUS_NO_DIVERGED_COMMITS: {
1389
+ en: "No diverged commits yet",
1390
+ "zh-CN": "\u5C1A\u65E0\u5206\u53C9\u63D0\u4EA4"
1391
+ },
430
1392
  /** status 上次验证时间标签 */
431
- STATUS_LAST_VALIDATED: (relativeTime) => `\u4E0A\u6B21\u9A8C\u8BC1: ${relativeTime}`,
1393
+ STATUS_LAST_VALIDATED: {
1394
+ en: (relativeTime) => `Last validated: ${relativeTime}`,
1395
+ "zh-CN": (relativeTime) => `\u4E0A\u6B21\u9A8C\u8BC1: ${relativeTime}`
1396
+ },
432
1397
  /** status 未验证警示 */
433
- STATUS_NOT_VALIDATED: "\u2717 \u672A\u9A8C\u8BC1",
1398
+ STATUS_NOT_VALIDATED: {
1399
+ en: "\u2717 Not validated",
1400
+ "zh-CN": "\u2717 \u672A\u9A8C\u8BC1"
1401
+ },
434
1402
  /** status 配置的主工作分支(正常状态) */
435
- STATUS_CONFIGURED_BRANCH: (branchName) => `\u4E3B\u5DE5\u4F5C\u5206\u652F: ${branchName}`,
1403
+ STATUS_CONFIGURED_BRANCH: {
1404
+ en: (branchName) => `Main work branch: ${branchName}`,
1405
+ "zh-CN": (branchName) => `\u4E3B\u5DE5\u4F5C\u5206\u652F: ${branchName}`
1406
+ },
436
1407
  /** status 配置的主工作分支已不存在 */
437
- STATUS_CONFIGURED_BRANCH_DELETED: (branchName) => `\u2717 \u4E3B\u5DE5\u4F5C\u5206\u652F: ${branchName}\uFF08\u5DF2\u4E0D\u5B58\u5728\uFF0C\u8BF7\u6267\u884C clawt init \u91CD\u65B0\u8BBE\u7F6E\uFF09`,
1408
+ STATUS_CONFIGURED_BRANCH_DELETED: {
1409
+ en: (branchName) => `\u2717 Main work branch: ${branchName} (no longer exists, run clawt init to reset)`,
1410
+ "zh-CN": (branchName) => `\u2717 \u4E3B\u5DE5\u4F5C\u5206\u652F: ${branchName}\uFF08\u5DF2\u4E0D\u5B58\u5728\uFF0C\u8BF7\u6267\u884C clawt init \u91CD\u65B0\u8BBE\u7F6E\uFF09`
1411
+ },
438
1412
  /** status 当前分支与配置的主工作分支不一致 */
439
- STATUS_CONFIGURED_BRANCH_MISMATCH: (branchName) => `\u26A0 \u4E3B\u5DE5\u4F5C\u5206\u652F: ${branchName}\uFF08\u5F53\u524D\u5206\u652F\u4E0D\u4E00\u81F4\uFF0C\u5982\u9700\u66F4\u65B0\u8BF7\u6267\u884C clawt init\uFF09`
1413
+ STATUS_CONFIGURED_BRANCH_MISMATCH: {
1414
+ en: (branchName) => `\u26A0 Main work branch: ${branchName} (current branch mismatch, run clawt init to update)`,
1415
+ "zh-CN": (branchName) => `\u26A0 \u4E3B\u5DE5\u4F5C\u5206\u652F: ${branchName}\uFF08\u5F53\u524D\u5206\u652F\u4E0D\u4E00\u81F4\uFF0C\u5982\u9700\u66F4\u65B0\u8BF7\u6267\u884C clawt init\uFF09`
1416
+ }
440
1417
  };
1418
+ var STATUS_MESSAGES = createMessages(STATUS_MESSAGES_I18N);
441
1419
 
442
1420
  // src/constants/messages/alias.ts
443
- var ALIAS_MESSAGES = {
1421
+ var ALIAS_MESSAGES_I18N = {
444
1422
  /** 别名列表为空 */
445
- ALIAS_LIST_EMPTY: "(\u65E0\u522B\u540D)",
1423
+ ALIAS_LIST_EMPTY: {
1424
+ en: "(No aliases)",
1425
+ "zh-CN": "(\u65E0\u522B\u540D)"
1426
+ },
446
1427
  /** 别名设置成功 */
447
- ALIAS_SET_SUCCESS: (alias, command) => `\u2713 \u5DF2\u8BBE\u7F6E\u522B\u540D: ${alias} \u2192 ${command}`,
1428
+ ALIAS_SET_SUCCESS: {
1429
+ en: (alias, command) => `\u2713 Alias set: ${alias} \u2192 ${command}`,
1430
+ "zh-CN": (alias, command) => `\u2713 \u5DF2\u8BBE\u7F6E\u522B\u540D: ${alias} \u2192 ${command}`
1431
+ },
448
1432
  /** 别名移除成功 */
449
- ALIAS_REMOVE_SUCCESS: (alias) => `\u2713 \u5DF2\u79FB\u9664\u522B\u540D: ${alias}`,
1433
+ ALIAS_REMOVE_SUCCESS: {
1434
+ en: (alias) => `\u2713 Alias removed: ${alias}`,
1435
+ "zh-CN": (alias) => `\u2713 \u5DF2\u79FB\u9664\u522B\u540D: ${alias}`
1436
+ },
450
1437
  /** 别名不存在 */
451
- ALIAS_NOT_FOUND: (alias) => `\u522B\u540D "${alias}" \u4E0D\u5B58\u5728`,
1438
+ ALIAS_NOT_FOUND: {
1439
+ en: (alias) => `Alias "${alias}" does not exist`,
1440
+ "zh-CN": (alias) => `\u522B\u540D "${alias}" \u4E0D\u5B58\u5728`
1441
+ },
452
1442
  /** 别名与内置命令冲突 */
453
- ALIAS_CONFLICTS_BUILTIN: (alias) => `\u522B\u540D "${alias}" \u4E0E\u5185\u7F6E\u547D\u4EE4\u51B2\u7A81\uFF0C\u4E0D\u5141\u8BB8\u8986\u76D6\u5185\u7F6E\u547D\u4EE4`,
1443
+ ALIAS_CONFLICTS_BUILTIN: {
1444
+ en: (alias) => `Alias "${alias}" conflicts with a built-in command. Overriding built-in commands is not allowed`,
1445
+ "zh-CN": (alias) => `\u522B\u540D "${alias}" \u4E0E\u5185\u7F6E\u547D\u4EE4\u51B2\u7A81\uFF0C\u4E0D\u5141\u8BB8\u8986\u76D6\u5185\u7F6E\u547D\u4EE4`
1446
+ },
454
1447
  /** 目标命令不存在 */
455
- ALIAS_TARGET_NOT_FOUND: (command) => `\u76EE\u6807\u547D\u4EE4 "${command}" \u4E0D\u5B58\u5728\uFF0C\u8BF7\u6307\u5B9A\u5DF2\u6CE8\u518C\u7684\u5185\u7F6E\u547D\u4EE4\u540D`,
1448
+ ALIAS_TARGET_NOT_FOUND: {
1449
+ en: (command) => `Target command "${command}" does not exist. Please specify a registered built-in command name`,
1450
+ "zh-CN": (command) => `\u76EE\u6807\u547D\u4EE4 "${command}" \u4E0D\u5B58\u5728\uFF0C\u8BF7\u6307\u5B9A\u5DF2\u6CE8\u518C\u7684\u5185\u7F6E\u547D\u4EE4\u540D`
1451
+ },
456
1452
  /** 别名列表标题 */
457
- ALIAS_LIST_TITLE: "\u5F53\u524D\u522B\u540D\u5217\u8868\uFF1A"
1453
+ ALIAS_LIST_TITLE: {
1454
+ en: "Current aliases:",
1455
+ "zh-CN": "\u5F53\u524D\u522B\u540D\u5217\u8868\uFF1A"
1456
+ }
458
1457
  };
1458
+ var ALIAS_MESSAGES = createMessages(ALIAS_MESSAGES_I18N);
459
1459
 
460
1460
  // src/constants/messages/projects.ts
461
- var PROJECTS_MESSAGES = {
1461
+ var PROJECTS_MESSAGES_I18N = {
462
1462
  /** projects 命令全局概览标题 */
463
- PROJECTS_OVERVIEW_TITLE: "\u9879\u76EE\u6982\u89C8",
1463
+ PROJECTS_OVERVIEW_TITLE: {
1464
+ en: "Project Overview",
1465
+ "zh-CN": "\u9879\u76EE\u6982\u89C8"
1466
+ },
464
1467
  /** projects 命令指定项目详情标题 */
465
- PROJECTS_DETAIL_TITLE: (projectName) => `\u9879\u76EE\u8BE6\u60C5: ${projectName}`,
1468
+ PROJECTS_DETAIL_TITLE: {
1469
+ en: (projectName) => `Project Details: ${projectName}`,
1470
+ "zh-CN": (projectName) => `\u9879\u76EE\u8BE6\u60C5: ${projectName}`
1471
+ },
466
1472
  /** 无项目提示 */
467
- PROJECTS_NO_PROJECTS: "(\u6682\u65E0\u9879\u76EE\uFF0Cworktrees \u76EE\u5F55\u4E3A\u7A7A)",
1473
+ PROJECTS_NO_PROJECTS: {
1474
+ en: "(No projects, worktrees directory is empty)",
1475
+ "zh-CN": "(\u6682\u65E0\u9879\u76EE\uFF0Cworktrees \u76EE\u5F55\u4E3A\u7A7A)"
1476
+ },
468
1477
  /** 项目不存在提示 */
469
- PROJECTS_NOT_FOUND: (name) => `\u9879\u76EE ${name} \u4E0D\u5B58\u5728`,
1478
+ PROJECTS_NOT_FOUND: {
1479
+ en: (name) => `Project ${name} does not exist`,
1480
+ "zh-CN": (name) => `\u9879\u76EE ${name} \u4E0D\u5B58\u5728`
1481
+ },
470
1482
  /** worktree 数量标签 */
471
- PROJECTS_WORKTREE_COUNT: (count) => `${count} \u4E2A worktree`,
1483
+ PROJECTS_WORKTREE_COUNT: {
1484
+ en: (count) => `${count} worktree(s)`,
1485
+ "zh-CN": (count) => `${count} \u4E2A worktree`
1486
+ },
472
1487
  /** 最近活跃时间标签 */
473
- PROJECTS_LAST_ACTIVE: (relativeTime) => `\u6700\u8FD1\u6D3B\u8DC3: ${relativeTime}`,
1488
+ PROJECTS_LAST_ACTIVE: {
1489
+ en: (relativeTime) => `Last active: ${relativeTime}`,
1490
+ "zh-CN": (relativeTime) => `\u6700\u8FD1\u6D3B\u8DC3: ${relativeTime}`
1491
+ },
474
1492
  /** 磁盘占用标签 */
475
- PROJECTS_DISK_USAGE: (size) => `\u78C1\u76D8\u5360\u7528: ${size}`,
1493
+ PROJECTS_DISK_USAGE: {
1494
+ en: (size) => `Disk usage: ${size}`,
1495
+ "zh-CN": (size) => `\u78C1\u76D8\u5360\u7528: ${size}`
1496
+ },
476
1497
  /** 总磁盘占用标签 */
477
- PROJECTS_TOTAL_DISK_USAGE: (size) => `\u603B\u5360\u7528: ${size}`,
1498
+ PROJECTS_TOTAL_DISK_USAGE: {
1499
+ en: (size) => `Total: ${size}`,
1500
+ "zh-CN": (size) => `\u603B\u5360\u7528: ${size}`
1501
+ },
478
1502
  /** projects 详情无 worktree */
479
- PROJECTS_DETAIL_NO_WORKTREES: "(\u8BE5\u9879\u76EE\u4E0B\u65E0 worktree)",
1503
+ PROJECTS_DETAIL_NO_WORKTREES: {
1504
+ en: "(No worktrees in this project)",
1505
+ "zh-CN": "(\u8BE5\u9879\u76EE\u4E0B\u65E0 worktree)"
1506
+ },
480
1507
  /** 路径标签 */
481
- PROJECTS_PATH: (path2) => `\u8DEF\u5F84: ${path2}`,
1508
+ PROJECTS_PATH: {
1509
+ en: (path2) => `Path: ${path2}`,
1510
+ "zh-CN": (path2) => `\u8DEF\u5F84: ${path2}`
1511
+ },
482
1512
  /** 最后修改时间标签 */
483
- PROJECTS_LAST_MODIFIED: (relativeTime) => `\u6700\u540E\u4FEE\u6539: ${relativeTime}`
1513
+ PROJECTS_LAST_MODIFIED: {
1514
+ en: (relativeTime) => `Last modified: ${relativeTime}`,
1515
+ "zh-CN": (relativeTime) => `\u6700\u540E\u4FEE\u6539: ${relativeTime}`
1516
+ }
484
1517
  };
1518
+ var PROJECTS_MESSAGES = createMessages(PROJECTS_MESSAGES_I18N);
485
1519
 
486
1520
  // src/constants/messages/completion.ts
487
- var COMPLETION_MESSAGES = {
1521
+ var COMPLETION_MESSAGES_I18N = {
488
1522
  /** completion 命令的主描述 */
489
- COMPLETION_COMMAND_DESC: "\u4E3A\u7EC8\u7AEF\u63D0\u4F9B shell \u81EA\u52A8\u8865\u5168\u529F\u80FD\uFF08bash/zsh\uFF09",
1523
+ COMPLETION_COMMAND_DESC: {
1524
+ en: "Provide shell auto-completion for terminal (bash/zsh)",
1525
+ "zh-CN": "\u4E3A\u7EC8\u7AEF\u63D0\u4F9B shell \u81EA\u52A8\u8865\u5168\u529F\u80FD\uFF08bash/zsh\uFF09"
1526
+ },
490
1527
  /** bash 子命令描述 */
491
- COMPLETION_BASH_DESC: "\u8F93\u51FA bash \u81EA\u52A8\u8865\u5168\u811A\u672C",
1528
+ COMPLETION_BASH_DESC: {
1529
+ en: "Output bash auto-completion script",
1530
+ "zh-CN": "\u8F93\u51FA bash \u81EA\u52A8\u8865\u5168\u811A\u672C"
1531
+ },
492
1532
  /** zsh 子命令描述 */
493
- COMPLETION_ZSH_DESC: "\u8F93\u51FA zsh \u81EA\u52A8\u8865\u5168\u811A\u672C",
1533
+ COMPLETION_ZSH_DESC: {
1534
+ en: "Output zsh auto-completion script",
1535
+ "zh-CN": "\u8F93\u51FA zsh \u81EA\u52A8\u8865\u5168\u811A\u672C"
1536
+ },
494
1537
  /** install 子命令描述 */
495
- COMPLETION_INSTALL_DESC: "\u81EA\u52A8\u5B89\u88C5\u8865\u5168\u811A\u672C\u5230\u5F53\u524D\u7528\u6237\u7684 shell \u914D\u7F6E\u6587\u4EF6",
1538
+ COMPLETION_INSTALL_DESC: {
1539
+ en: "Auto-install completion script to current user shell config",
1540
+ "zh-CN": "\u81EA\u52A8\u5B89\u88C5\u8865\u5168\u811A\u672C\u5230\u5F53\u524D\u7528\u6237\u7684 shell \u914D\u7F6E\u6587\u4EF6"
1541
+ },
496
1542
  /** 安装成功提示 */
497
- COMPLETION_INSTALL_SUCCESS: "\u81EA\u52A8\u8865\u5168\u914D\u7F6E\u5DF2\u6210\u529F\u5199\u5165",
1543
+ COMPLETION_INSTALL_SUCCESS: {
1544
+ en: "Auto-completion config written successfully",
1545
+ "zh-CN": "\u81EA\u52A8\u8865\u5168\u914D\u7F6E\u5DF2\u6210\u529F\u5199\u5165"
1546
+ },
498
1547
  /** 安装失败或未知的 shell 提示 */
499
- COMPLETION_INSTALL_UNKNOWN_SHELL: "\u672A\u77E5\u7684 Shell \u73AF\u5883\u6216\u65E0\u6CD5\u81EA\u52A8\u5B89\u88C5\uFF0C\u8BF7\u624B\u52A8\u914D\u7F6E\u3002",
1548
+ COMPLETION_INSTALL_UNKNOWN_SHELL: {
1549
+ en: "Unknown shell or unable to auto-install. Please configure manually.",
1550
+ "zh-CN": "\u672A\u77E5\u7684 Shell \u73AF\u5883\u6216\u65E0\u6CD5\u81EA\u52A8\u5B89\u88C5\uFF0C\u8BF7\u624B\u52A8\u914D\u7F6E\u3002"
1551
+ },
500
1552
  /** 补全配置已存在提示 */
501
- COMPLETION_INSTALL_EXISTS: "\u81EA\u52A8\u8865\u5168\u914D\u7F6E\u5DF2\u5B58\u5728\u4E8E\u76EE\u6807\u6587\u4EF6\u4E2D",
1553
+ COMPLETION_INSTALL_EXISTS: {
1554
+ en: "Auto-completion config already exists in target file",
1555
+ "zh-CN": "\u81EA\u52A8\u8865\u5168\u914D\u7F6E\u5DF2\u5B58\u5728\u4E8E\u76EE\u6807\u6587\u4EF6\u4E2D"
1556
+ },
502
1557
  /** 提示用户重启生效 */
503
- COMPLETION_INSTALL_RESTART: (filePath) => `\u8BF7\u91CD\u542F\u7EC8\u7AEF\u6216\u8FD0\u884C \`source ${filePath}\` \u4EE5\u4F7F\u8865\u5168\u751F\u6548\u3002`,
1558
+ COMPLETION_INSTALL_RESTART: {
1559
+ en: (filePath) => `Please restart your terminal or run \`source ${filePath}\` for completion to take effect.`,
1560
+ "zh-CN": (filePath) => `\u8BF7\u91CD\u542F\u7EC8\u7AEF\u6216\u8FD0\u884C \`source ${filePath}\` \u4EE5\u4F7F\u8865\u5168\u751F\u6548\u3002`
1561
+ },
504
1562
  /** 安装写入失败提示 */
505
- COMPLETION_INSTALL_WRITE_ERROR: (filePath) => `\u65E0\u6CD5\u5199\u5165\u6587\u4EF6 ${filePath}\uFF0C\u8BF7\u68C0\u67E5\u6587\u4EF6\u6743\u9650\u6216\u624B\u52A8\u914D\u7F6E\u3002`
1563
+ COMPLETION_INSTALL_WRITE_ERROR: {
1564
+ en: (filePath) => `Cannot write file ${filePath}, please check file permissions or configure manually.`,
1565
+ "zh-CN": (filePath) => `\u65E0\u6CD5\u5199\u5165\u6587\u4EF6 ${filePath}\uFF0C\u8BF7\u68C0\u67E5\u6587\u4EF6\u6743\u9650\u6216\u624B\u52A8\u914D\u7F6E\u3002`
1566
+ }
506
1567
  };
1568
+ var COMPLETION_MESSAGES = createMessages(COMPLETION_MESSAGES_I18N);
507
1569
 
508
1570
  // src/constants/messages/update.ts
509
- var UPDATE_COMMANDS = {
510
- npm: "npm i -g clawt",
511
- pnpm: "pnpm add -g clawt",
512
- yarn: "yarn global add clawt"
1571
+ var UPDATE_COMMANDS_I18N = {
1572
+ npm: {
1573
+ en: "npm i -g clawt",
1574
+ "zh-CN": "npm i -g clawt"
1575
+ },
1576
+ pnpm: {
1577
+ en: "pnpm add -g clawt",
1578
+ "zh-CN": "pnpm add -g clawt"
1579
+ },
1580
+ yarn: {
1581
+ en: "yarn global add clawt",
1582
+ "zh-CN": "yarn global add clawt"
1583
+ }
513
1584
  };
514
- var UPDATE_MESSAGES = {
1585
+ var UPDATE_COMMANDS = createMessages(UPDATE_COMMANDS_I18N);
1586
+ var UPDATE_MESSAGES_I18N = {
515
1587
  /** 版本更新提示 */
516
- UPDATE_AVAILABLE: (currentVersion, latestVersion) => `clawt \u6709\u65B0\u7248\u672C\u53EF\u7528: ${currentVersion} \u2192 ${latestVersion}`,
1588
+ UPDATE_AVAILABLE: {
1589
+ en: (currentVersion, latestVersion) => `clawt update available: ${currentVersion} \u2192 ${latestVersion}`,
1590
+ "zh-CN": (currentVersion, latestVersion) => `clawt \u6709\u65B0\u7248\u672C\u53EF\u7528: ${currentVersion} \u2192 ${latestVersion}`
1591
+ },
517
1592
  /** 更新操作提示 */
518
- UPDATE_HINT: (command) => `\u6267\u884C ${command} \u8FDB\u884C\u66F4\u65B0`
1593
+ UPDATE_HINT: {
1594
+ en: (command) => `Run ${command} to update`,
1595
+ "zh-CN": (command) => `\u6267\u884C ${command} \u8FDB\u884C\u66F4\u65B0`
1596
+ }
519
1597
  };
1598
+ var UPDATE_MESSAGES = createMessages(UPDATE_MESSAGES_I18N);
520
1599
 
521
1600
  // src/constants/messages/init.ts
522
- var INIT_MESSAGES = {
1601
+ var INIT_MESSAGES_I18N = {
523
1602
  /** init 成功 */
524
- INIT_SUCCESS: (branch) => `\u2713 \u9879\u76EE\u521D\u59CB\u5316\u6210\u529F\uFF0C\u4E3B\u5DE5\u4F5C\u5206\u652F\u8BBE\u7F6E\u4E3A: ${branch}`,
1603
+ INIT_SUCCESS: {
1604
+ en: (branch) => `\u2713 Project initialized, main work branch set to: ${branch}`,
1605
+ "zh-CN": (branch) => `\u2713 \u9879\u76EE\u521D\u59CB\u5316\u6210\u529F\uFF0C\u4E3B\u5DE5\u4F5C\u5206\u652F\u8BBE\u7F6E\u4E3A: ${branch}`
1606
+ },
525
1607
  /** init 更新 */
526
- INIT_UPDATED: (oldBranch, newBranch) => `\u2713 \u5DF2\u5C06\u4E3B\u5DE5\u4F5C\u5206\u652F\u4ECE ${oldBranch} \u66F4\u65B0\u4E3A ${newBranch}`,
1608
+ INIT_UPDATED: {
1609
+ en: (oldBranch, newBranch) => `\u2713 Main work branch updated from ${oldBranch} to ${newBranch}`,
1610
+ "zh-CN": (oldBranch, newBranch) => `\u2713 \u5DF2\u5C06\u4E3B\u5DE5\u4F5C\u5206\u652F\u4ECE ${oldBranch} \u66F4\u65B0\u4E3A ${newBranch}`
1611
+ },
527
1612
  /** init show 查看当前项目完整配置(JSON 格式) */
528
- INIT_SHOW: (configJson) => `${configJson}`,
1613
+ INIT_SHOW: {
1614
+ en: (configJson) => `${configJson}`,
1615
+ "zh-CN": (configJson) => `${configJson}`
1616
+ },
529
1617
  /** init 未初始化 */
530
- INIT_NOT_INITIALIZED: "\u9879\u76EE\u5C1A\u672A\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u6267\u884C clawt init \u8BBE\u7F6E\u4E3B\u5DE5\u4F5C\u5206\u652F",
1618
+ INIT_NOT_INITIALIZED: {
1619
+ en: "Project not initialized. Please run clawt init to set the main work branch",
1620
+ "zh-CN": "\u9879\u76EE\u5C1A\u672A\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u6267\u884C clawt init \u8BBE\u7F6E\u4E3B\u5DE5\u4F5C\u5206\u652F"
1621
+ },
531
1622
  /** 项目未初始化(requireProjectConfig 使用) */
532
- PROJECT_NOT_INITIALIZED: "\u9879\u76EE\u5C1A\u672A\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u6267\u884C clawt init \u8BBE\u7F6E\u4E3B\u5DE5\u4F5C\u5206\u652F",
1623
+ PROJECT_NOT_INITIALIZED: {
1624
+ en: "Project not initialized. Please run clawt init to set the main work branch",
1625
+ "zh-CN": "\u9879\u76EE\u5C1A\u672A\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u6267\u884C clawt init \u8BBE\u7F6E\u4E3B\u5DE5\u4F5C\u5206\u652F"
1626
+ },
533
1627
  /** 项目配置缺少 clawtMainWorkBranch 字段 */
534
- PROJECT_CONFIG_MISSING_BRANCH: "\u9879\u76EE\u914D\u7F6E\u7F3A\u5C11\u4E3B\u5DE5\u4F5C\u5206\u652F\u4FE1\u606F\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C clawt init \u8BBE\u7F6E\u4E3B\u5DE5\u4F5C\u5206\u652F",
1628
+ PROJECT_CONFIG_MISSING_BRANCH: {
1629
+ en: "Project config missing main work branch info. Please run clawt init to set the main work branch",
1630
+ "zh-CN": "\u9879\u76EE\u914D\u7F6E\u7F3A\u5C11\u4E3B\u5DE5\u4F5C\u5206\u652F\u4FE1\u606F\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C clawt init \u8BBE\u7F6E\u4E3B\u5DE5\u4F5C\u5206\u652F"
1631
+ },
535
1632
  /** init show 交互式面板选择配置项提示 */
536
- INIT_SELECT_PROMPT: "\u9009\u62E9\u8981\u4FEE\u6539\u7684\u9879\u76EE\u914D\u7F6E\u9879",
1633
+ INIT_SELECT_PROMPT: {
1634
+ en: "Select project config item to modify",
1635
+ "zh-CN": "\u9009\u62E9\u8981\u4FEE\u6539\u7684\u9879\u76EE\u914D\u7F6E\u9879"
1636
+ },
537
1637
  /** init show 交互式面板配置项修改成功 */
538
- INIT_SET_SUCCESS: (key, value) => `\u2713 \u9879\u76EE\u914D\u7F6E ${key} \u5DF2\u8BBE\u7F6E\u4E3A ${value}`
1638
+ INIT_SET_SUCCESS: {
1639
+ en: (key, value) => `\u2713 Project config ${key} set to ${value}`,
1640
+ "zh-CN": (key, value) => `\u2713 \u9879\u76EE\u914D\u7F6E ${key} \u5DF2\u8BBE\u7F6E\u4E3A ${value}`
1641
+ }
539
1642
  };
1643
+ var INIT_MESSAGES = createMessages(INIT_MESSAGES_I18N);
540
1644
 
541
1645
  // src/constants/messages/cover-validate.ts
542
- var COVER_VALIDATE_MESSAGES = {
1646
+ var COVER_VALIDATE_MESSAGES_I18N = {
543
1647
  /** 当前不在验证分支上 */
544
- COVER_VALIDATE_NOT_ON_VALIDATE_BRANCH: "\u5F53\u524D\u5206\u652F\u4E0D\u662F\u9A8C\u8BC1\u5206\u652F\uFF08\u9700\u4EE5 clawt-validate- \u5F00\u5934\uFF09\n \u8BF7\u5148\u901A\u8FC7 clawt validate \u5207\u6362\u5230\u9A8C\u8BC1\u5206\u652F",
1648
+ COVER_VALIDATE_NOT_ON_VALIDATE_BRANCH: {
1649
+ en: "Current branch is not a validate branch (must start with clawt-validate-)\n Please run clawt validate first to switch to a validate branch",
1650
+ "zh-CN": "\u5F53\u524D\u5206\u652F\u4E0D\u662F\u9A8C\u8BC1\u5206\u652F\uFF08\u9700\u4EE5 clawt-validate- \u5F00\u5934\uFF09\n \u8BF7\u5148\u901A\u8FC7 clawt validate \u5207\u6362\u5230\u9A8C\u8BC1\u5206\u652F"
1651
+ },
545
1652
  /** 无增量修改 */
546
- COVER_VALIDATE_NO_CHANGES: "\u9A8C\u8BC1\u5206\u652F\u4E0A\u6CA1\u6709\u76F8\u5BF9\u4E8E\u5FEB\u7167\u7684\u589E\u91CF\u4FEE\u6539\uFF0C\u65E0\u9700\u8986\u76D6",
1653
+ COVER_VALIDATE_NO_CHANGES: {
1654
+ en: "No incremental changes on validate branch relative to snapshot, nothing to cover",
1655
+ "zh-CN": "\u9A8C\u8BC1\u5206\u652F\u4E0A\u6CA1\u6709\u76F8\u5BF9\u4E8E\u5FEB\u7167\u7684\u589E\u91CF\u4FEE\u6539\uFF0C\u65E0\u9700\u8986\u76D6"
1656
+ },
547
1657
  /** 目标 worktree 不存在 */
548
- COVER_VALIDATE_TARGET_NOT_FOUND: (branch) => `\u672A\u627E\u5230\u5206\u652F ${branch} \u5BF9\u5E94\u7684 worktree\uFF0C\u8BF7\u786E\u8BA4\u8BE5 worktree \u5C1A\u672A\u88AB\u79FB\u9664`,
1658
+ COVER_VALIDATE_TARGET_NOT_FOUND: {
1659
+ en: (branch) => `Worktree for branch ${branch} not found. Please confirm the worktree has not been removed`,
1660
+ "zh-CN": (branch) => `\u672A\u627E\u5230\u5206\u652F ${branch} \u5BF9\u5E94\u7684 worktree\uFF0C\u8BF7\u786E\u8BA4\u8BE5 worktree \u5C1A\u672A\u88AB\u79FB\u9664`
1661
+ },
549
1662
  /** 无快照,提示先执行 validate */
550
- COVER_VALIDATE_NO_SNAPSHOT: (branch) => `\u672A\u627E\u5230\u5206\u652F ${branch} \u7684 validate \u5FEB\u7167
551
- \u8BF7\u5148\u6267\u884C clawt validate -b ${branch} \u521B\u5EFA\u5FEB\u7167`,
1663
+ COVER_VALIDATE_NO_SNAPSHOT: {
1664
+ en: (branch) => `No validate snapshot found for branch ${branch}
1665
+ Please run clawt validate -b ${branch} to create a snapshot`,
1666
+ "zh-CN": (branch) => `\u672A\u627E\u5230\u5206\u652F ${branch} \u7684 validate \u5FEB\u7167
1667
+ \u8BF7\u5148\u6267\u884C clawt validate -b ${branch} \u521B\u5EFA\u5FEB\u7167`
1668
+ },
552
1669
  /** 覆盖失败(tree checkout/clean 失败) */
553
- COVER_VALIDATE_COVER_FAILED: (branch) => `\u8986\u76D6\u53D8\u66F4\u5230 worktree ${branch} \u5931\u8D25\uFF1Atree checkout \u6216\u6E05\u7406\u64CD\u4F5C\u51FA\u9519
554
- \u8BF7\u68C0\u67E5\u76EE\u6807 worktree \u72B6\u6001\u540E\u91CD\u8BD5`,
1670
+ COVER_VALIDATE_COVER_FAILED: {
1671
+ en: (branch) => `Failed to cover changes to worktree ${branch}: tree checkout or cleanup error
1672
+ Please check the target worktree status and retry`,
1673
+ "zh-CN": (branch) => `\u8986\u76D6\u53D8\u66F4\u5230 worktree ${branch} \u5931\u8D25\uFF1Atree checkout \u6216\u6E05\u7406\u64CD\u4F5C\u51FA\u9519
1674
+ \u8BF7\u68C0\u67E5\u76EE\u6807 worktree \u72B6\u6001\u540E\u91CD\u8BD5`
1675
+ },
555
1676
  /** 工作区和暂存区无修改,可能为误操作 */
556
- COVER_VALIDATE_WORKING_DIR_CLEAN: "\u5F53\u524D\u9A8C\u8BC1\u5206\u652F\u7684\u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\u6CA1\u6709\u4EFB\u4F55\u4FEE\u6539\uFF0C\u53EF\u80FD\u4E3A\u8BEF\u64CD\u4F5C",
1677
+ COVER_VALIDATE_WORKING_DIR_CLEAN: {
1678
+ en: "Working tree and staging area on current validate branch have no changes, possibly a mistaken operation",
1679
+ "zh-CN": "\u5F53\u524D\u9A8C\u8BC1\u5206\u652F\u7684\u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\u6CA1\u6709\u4EFB\u4F55\u4FEE\u6539\uFF0C\u53EF\u80FD\u4E3A\u8BEF\u64CD\u4F5C"
1680
+ },
557
1681
  /** 覆盖成功 */
558
- COVER_VALIDATE_SUCCESS: (branch) => `\u2713 \u5DF2\u5C06\u9A8C\u8BC1\u5206\u652F\u4E0A\u7684\u4FEE\u6539\u8986\u76D6\u5230 worktree => ${branch}`
1682
+ COVER_VALIDATE_SUCCESS: {
1683
+ en: (branch) => `\u2713 Changes on validate branch covered to worktree => ${branch}`,
1684
+ "zh-CN": (branch) => `\u2713 \u5DF2\u5C06\u9A8C\u8BC1\u5206\u652F\u4E0A\u7684\u4FEE\u6539\u8986\u76D6\u5230 worktree => ${branch}`
1685
+ }
559
1686
  };
1687
+ var COVER_VALIDATE_MESSAGES = createMessages(COVER_VALIDATE_MESSAGES_I18N);
560
1688
 
561
1689
  // src/constants/messages/home.ts
562
- var HOME_MESSAGES = {
1690
+ var HOME_MESSAGES_I18N = {
563
1691
  /** 已在主工作分支上 */
564
- HOME_ALREADY_ON_MAIN: (branch) => `\u5DF2\u5728\u4E3B\u5DE5\u4F5C\u5206\u652F ${branch} \u4E0A\uFF0C\u65E0\u9700\u5207\u6362`,
1692
+ HOME_ALREADY_ON_MAIN: {
1693
+ en: (branch) => `Already on main work branch ${branch}, no switch needed`,
1694
+ "zh-CN": (branch) => `\u5DF2\u5728\u4E3B\u5DE5\u4F5C\u5206\u652F ${branch} \u4E0A\uFF0C\u65E0\u9700\u5207\u6362`
1695
+ },
565
1696
  /** 切换成功 */
566
- HOME_SWITCH_SUCCESS: (from, to) => `\u2713 \u5DF2\u4ECE ${from} \u5207\u6362\u5230\u4E3B\u5DE5\u4F5C\u5206\u652F ${to}`,
1697
+ HOME_SWITCH_SUCCESS: {
1698
+ en: (from, to) => `\u2713 Switched from ${from} to main work branch ${to}`,
1699
+ "zh-CN": (from, to) => `\u2713 \u5DF2\u4ECE ${from} \u5207\u6362\u5230\u4E3B\u5DE5\u4F5C\u5206\u652F ${to}`
1700
+ },
567
1701
  /** 当前在子 worktree,提示用户手动 cd 到主 worktree */
568
- HOME_NOT_IN_MAIN_WORKTREE: (mainPath) => `\u5F53\u524D\u4E0D\u5728\u4E3B worktree\uFF0C\u8BF7\u5148\u5207\u6362\u5230\u4E3B worktree\uFF1A
1702
+ HOME_NOT_IN_MAIN_WORKTREE: {
1703
+ en: (mainPath) => `Not in main worktree. Please switch to main worktree:
1704
+
1705
+ cd ${mainPath}`,
1706
+ "zh-CN": (mainPath) => `\u5F53\u524D\u4E0D\u5728\u4E3B worktree\uFF0C\u8BF7\u5148\u5207\u6362\u5230\u4E3B worktree\uFF1A
569
1707
 
570
1708
  cd ${mainPath}`
1709
+ }
571
1710
  };
1711
+ var HOME_MESSAGES = createMessages(HOME_MESSAGES_I18N);
572
1712
 
573
1713
  // src/constants/messages/tasks.ts
574
- var TASKS_CMD_MESSAGES = {
1714
+ var TASKS_CMD_MESSAGES_I18N = {
575
1715
  /** 任务模板文件已存在 */
576
- TASK_INIT_FILE_EXISTS: (path2) => `\u6587\u4EF6\u5DF2\u5B58\u5728: ${path2}\uFF0C\u5982\u9700\u8986\u76D6\u8BF7\u5148\u5220\u9664`,
1716
+ TASK_INIT_FILE_EXISTS: {
1717
+ en: (path2) => `File already exists: ${path2}, delete it first to overwrite`,
1718
+ "zh-CN": (path2) => `\u6587\u4EF6\u5DF2\u5B58\u5728: ${path2}\uFF0C\u5982\u9700\u8986\u76D6\u8BF7\u5148\u5220\u9664`
1719
+ },
577
1720
  /** 任务模板生成成功 */
578
- TASK_INIT_SUCCESS: (path2) => `\u2713 \u4EFB\u52A1\u6A21\u677F\u5DF2\u751F\u6210: ${path2}`,
1721
+ TASK_INIT_SUCCESS: {
1722
+ en: (path2) => `\u2713 Task template generated: ${path2}`,
1723
+ "zh-CN": (path2) => `\u2713 \u4EFB\u52A1\u6A21\u677F\u5DF2\u751F\u6210: ${path2}`
1724
+ },
579
1725
  /** 任务模板使用提示(分行列出 run 和 resume 两种用法) */
580
- TASK_INIT_HINT: (path2) => `\u6267\u884C\u4EFB\u52A1:
1726
+ TASK_INIT_HINT: {
1727
+ en: (path2) => `Run task:
1728
+ clawt run -f ${path2} # Create worktree and execute (branch name must not exist)
1729
+ clawt resume -f ${path2} # Resume in existing worktree (branch name must exist)`,
1730
+ "zh-CN": (path2) => `\u6267\u884C\u4EFB\u52A1:
581
1731
  clawt run -f ${path2} # \u521B\u5EFA worktree \u5E76\u6267\u884C\uFF08\u5206\u652F\u540D\u9700\u4E0D\u5B58\u5728\uFF09
582
1732
  clawt resume -f ${path2} # \u5728\u5DF2\u6709 worktree \u4E2D\u8FFD\u95EE\uFF08\u5206\u652F\u540D\u9700\u5DF2\u5B58\u5728\uFF09`
1733
+ }
583
1734
  };
1735
+ var TASKS_CMD_MESSAGES = createMessages(TASKS_CMD_MESSAGES_I18N);
584
1736
 
585
1737
  // src/constants/messages/post-create.ts
586
- var POST_CREATE_MESSAGES = {
1738
+ var POST_CREATE_MESSAGES_I18N = {
587
1739
  /** hook 执行跳过(--no-post-create) */
588
- HOOK_SKIPPED: "\u5DF2\u8DF3\u8FC7 postCreate hook\uFF08--no-post-create\uFF09",
1740
+ HOOK_SKIPPED: {
1741
+ en: "Skipped postCreate hook (--no-post-create)",
1742
+ "zh-CN": "\u5DF2\u8DF3\u8FC7 postCreate hook\uFF08--no-post-create\uFF09"
1743
+ },
589
1744
  /** 无 hook 配置 */
590
- HOOK_NOT_CONFIGURED: "\u672A\u914D\u7F6E postCreate hook\uFF0C\u8DF3\u8FC7",
1745
+ HOOK_NOT_CONFIGURED: {
1746
+ en: "postCreate hook not configured, skipping",
1747
+ "zh-CN": "\u672A\u914D\u7F6E postCreate hook\uFF0C\u8DF3\u8FC7"
1748
+ },
591
1749
  /** hook 来源提示 */
592
- HOOK_SOURCE_INFO: (source) => `postCreate hook \u6765\u6E90: ${source}`,
1750
+ HOOK_SOURCE_INFO: {
1751
+ en: (source) => `postCreate hook source: ${source}`,
1752
+ "zh-CN": (source) => `postCreate hook \u6765\u6E90: ${source}`
1753
+ },
593
1754
  /** hook 开始执行 */
594
- HOOK_EXECUTING: (branch, command) => `[${branch}] \u6B63\u5728\u6267\u884C postCreate hook: ${command}`,
1755
+ HOOK_EXECUTING: {
1756
+ en: (branch, command) => `[${branch}] Executing postCreate hook: ${command}`,
1757
+ "zh-CN": (branch, command) => `[${branch}] \u6B63\u5728\u6267\u884C postCreate hook: ${command}`
1758
+ },
595
1759
  /** hook 执行成功 */
596
- HOOK_SUCCESS: (branch) => `[${branch}] postCreate hook \u6267\u884C\u6210\u529F`,
1760
+ HOOK_SUCCESS: {
1761
+ en: (branch) => `[${branch}] postCreate hook executed successfully`,
1762
+ "zh-CN": (branch) => `[${branch}] postCreate hook \u6267\u884C\u6210\u529F`
1763
+ },
597
1764
  /** hook 执行失败 */
598
- HOOK_FAILED: (branch, error) => `[${branch}] postCreate hook \u6267\u884C\u5931\u8D25: ${error}`,
1765
+ HOOK_FAILED: {
1766
+ en: (branch, error) => `[${branch}] postCreate hook execution failed: ${error}`,
1767
+ "zh-CN": (branch, error) => `[${branch}] postCreate hook \u6267\u884C\u5931\u8D25: ${error}`
1768
+ },
599
1769
  /** hook 执行汇总 */
600
- HOOK_SUMMARY: (succeeded, failed) => `postCreate hook \u6267\u884C\u5B8C\u6210: ${succeeded} \u6210\u529F, ${failed} \u5931\u8D25`,
1770
+ HOOK_SUMMARY: {
1771
+ en: (succeeded, failed) => `postCreate hook completed: ${succeeded} succeeded, ${failed} failed`,
1772
+ "zh-CN": (succeeded, failed) => `postCreate hook \u6267\u884C\u5B8C\u6210: ${succeeded} \u6210\u529F, ${failed} \u5931\u8D25`
1773
+ },
601
1774
  /** hook 后台执行中提示 */
602
- HOOK_BACKGROUND_START: (count, command) => `postCreate hook \u6B63\u5728\u540E\u53F0\u6267\u884C (${count} \u4E2A worktree): ${command}`,
1775
+ HOOK_BACKGROUND_START: {
1776
+ en: (count, command) => `postCreate hook running in background (${count} worktree(s)): ${command}`,
1777
+ "zh-CN": (count, command) => `postCreate hook \u6B63\u5728\u540E\u53F0\u6267\u884C (${count} \u4E2A worktree): ${command}`
1778
+ },
603
1779
  /** postCreate.sh 自动添加执行权限 */
604
- POST_CREATE_SCRIPT_AUTO_CHMOD: (path2) => `${path2} \u4E0D\u53EF\u6267\u884C\uFF0C\u5DF2\u81EA\u52A8\u6DFB\u52A0\u6267\u884C\u6743\u9650`,
1780
+ POST_CREATE_SCRIPT_AUTO_CHMOD: {
1781
+ en: (path2) => `${path2} is not executable, auto-added execute permission`,
1782
+ "zh-CN": (path2) => `${path2} \u4E0D\u53EF\u6267\u884C\uFF0C\u5DF2\u81EA\u52A8\u6DFB\u52A0\u6267\u884C\u6743\u9650`
1783
+ },
605
1784
  /** postCreate.sh 不可执行(自动 chmod 失败时降级提示) */
606
- POST_CREATE_SCRIPT_NOT_EXECUTABLE: (path2) => `\u68C0\u6D4B\u5230 ${path2} \u4F46\u4E0D\u53EF\u6267\u884C\uFF0C\u81EA\u52A8\u6DFB\u52A0\u6743\u9650\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u6267\u884C chmod +x ${path2}`
1785
+ POST_CREATE_SCRIPT_NOT_EXECUTABLE: {
1786
+ en: (path2) => `Detected ${path2} but not executable, auto-chmod failed. Please run chmod +x ${path2} manually`,
1787
+ "zh-CN": (path2) => `\u68C0\u6D4B\u5230 ${path2} \u4F46\u4E0D\u53EF\u6267\u884C\uFF0C\u81EA\u52A8\u6DFB\u52A0\u6743\u9650\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u6267\u884C chmod +x ${path2}`
1788
+ }
607
1789
  };
1790
+ var POST_CREATE_MESSAGES = createMessages(POST_CREATE_MESSAGES_I18N);
608
1791
 
609
1792
  // src/constants/messages/interactive-panel.ts
610
- import chalk from "chalk";
1793
+ import chalk2 from "chalk";
611
1794
 
612
1795
  // src/constants/interactive-panel.ts
613
1796
  var PANEL_REFRESH_INTERVAL_MS = 5e3;
@@ -641,7 +1824,17 @@ var PANEL_SEPARATOR_MAX_WIDTH = 60;
641
1824
  var PANEL_DATE_COLOR = "#FF8C00";
642
1825
 
643
1826
  // src/constants/messages/interactive-panel.ts
644
- var SHORTCUT_LABELS = {
1827
+ var SHORTCUT_LABELS_EN = {
1828
+ VALIDATE: "Validate",
1829
+ MERGE: "Merge",
1830
+ DELETE: "Delete",
1831
+ RESUME: "Resume",
1832
+ SYNC: "Sync",
1833
+ COVER: "Cover",
1834
+ REFRESH: "Refresh",
1835
+ QUIT: "Quit"
1836
+ };
1837
+ var SHORTCUT_LABELS_ZH = {
645
1838
  VALIDATE: "\u9A8C\u8BC1",
646
1839
  MERGE: "\u5408\u5E76",
647
1840
  DELETE: "\u5220\u9664",
@@ -651,22 +1844,226 @@ var SHORTCUT_LABELS = {
651
1844
  REFRESH: "\u5237\u65B0",
652
1845
  QUIT: "\u9000\u51FA"
653
1846
  };
654
- var PANEL_FOOTER_SHORTCUTS = Object.entries(SHORTCUT_LABELS).map(([key, label]) => `[${chalk.cyan(PANEL_SHORTCUT_KEYS[key])}]${label}`).join(" ");
655
- var PANEL_FOOTER_COUNTDOWN = (seconds) => chalk.gray(`(${seconds}s \u540E\u5237\u65B0)`);
656
- var PANEL_OVERFLOW_DOWN_HINT = chalk.gray("\u2193 \u66F4\u591A worktree...");
657
- var PANEL_OVERFLOW_UP_HINT = chalk.gray("\u2191 \u66F4\u591A worktree...");
658
- var PANEL_NO_WORKTREES = "(\u65E0\u6D3B\u8DC3 worktree)";
659
- var PANEL_PRESS_ENTER_TO_RETURN = chalk.gray("\n\u6309 Enter \u8FD4\u56DE\u9762\u677F...");
660
- var PANEL_NOT_TTY = "\u4EA4\u4E92\u5F0F\u9762\u677F\u9700\u8981 TTY \u7EC8\u7AEF\u73AF\u5883\uFF0C\u8BF7\u76F4\u63A5\u5728\u7EC8\u7AEF\u4E2D\u8FD0\u884C clawt status -i";
661
- var PANEL_TITLE = (projectName) => chalk.bold.cyan(`\u9879\u76EE\u72B6\u6001\u603B\u89C8: ${projectName}`);
662
- var PANEL_CONFIGURED_BRANCH = (branchName) => chalk.gray(`\u4E3B\u5DE5\u4F5C\u5206\u652F: ${branchName}`);
663
- var PANEL_CONFIGURED_BRANCH_DELETED = (branchName) => chalk.red(`\u2717 \u4E3B\u5DE5\u4F5C\u5206\u652F: ${branchName}\uFF08\u5DF2\u4E0D\u5B58\u5728\uFF09`);
664
- var PANEL_CONFIGURED_BRANCH_MISMATCH = (branchName) => chalk.red(`\u26A0 \u4E3B\u5DE5\u4F5C\u5206\u652F: ${branchName}\uFF08\u4E0D\u4E00\u81F4\uFF09`);
665
- var PANEL_NOT_INITIALIZED = chalk.gray("\u672A\u521D\u59CB\u5316\uFF08\u6267\u884C clawt init \u8BBE\u7F6E\u4E3B\u5DE5\u4F5C\u5206\u652F\uFF09");
666
- var PANEL_UNKNOWN_DATE = "\u672A\u77E5\u65E5\u671F";
667
- var PANEL_SYNCED_WITH_MAIN = "\u4E0E\u4E3B\u5206\u652F\u540C\u6B65";
668
- var PANEL_COMMITS_AHEAD = (count) => `${count} \u4E2A\u672C\u5730\u63D0\u4EA4`;
669
- var PANEL_COMMITS_BEHIND = (count) => `\u843D\u540E\u4E3B\u5206\u652F ${count} \u4E2A\u63D0\u4EA4`;
1847
+ var PANEL_FOOTER_SHORTCUTS_I18N = {
1848
+ PANEL_FOOTER_SHORTCUTS: {
1849
+ en: Object.entries(SHORTCUT_LABELS_EN).map(([key, label]) => `[${chalk2.cyan(PANEL_SHORTCUT_KEYS[key])}]${label}`).join(" "),
1850
+ "zh-CN": Object.entries(SHORTCUT_LABELS_ZH).map(([key, label]) => `[${chalk2.cyan(PANEL_SHORTCUT_KEYS[key])}]${label}`).join(" ")
1851
+ }
1852
+ };
1853
+ var PANEL_FOOTER_SHORTCUTS = createMessages(PANEL_FOOTER_SHORTCUTS_I18N).PANEL_FOOTER_SHORTCUTS;
1854
+ var PANEL_FOOTER_COUNTDOWN_I18N = {
1855
+ PANEL_FOOTER_COUNTDOWN: {
1856
+ en: (seconds) => chalk2.gray(`(refresh in ${seconds}s)`),
1857
+ "zh-CN": (seconds) => chalk2.gray(`(${seconds}s \u540E\u5237\u65B0)`)
1858
+ }
1859
+ };
1860
+ var PANEL_FOOTER_COUNTDOWN = createMessages(PANEL_FOOTER_COUNTDOWN_I18N).PANEL_FOOTER_COUNTDOWN;
1861
+ var PANEL_OVERFLOW_DOWN_HINT_I18N = {
1862
+ PANEL_OVERFLOW_DOWN_HINT: {
1863
+ en: chalk2.gray("\u2193 more worktrees..."),
1864
+ "zh-CN": chalk2.gray("\u2193 \u66F4\u591A worktree...")
1865
+ }
1866
+ };
1867
+ var PANEL_OVERFLOW_DOWN_HINT = createMessages(PANEL_OVERFLOW_DOWN_HINT_I18N).PANEL_OVERFLOW_DOWN_HINT;
1868
+ var PANEL_OVERFLOW_UP_HINT_I18N = {
1869
+ PANEL_OVERFLOW_UP_HINT: {
1870
+ en: chalk2.gray("\u2191 more worktrees..."),
1871
+ "zh-CN": chalk2.gray("\u2191 \u66F4\u591A worktree...")
1872
+ }
1873
+ };
1874
+ var PANEL_OVERFLOW_UP_HINT = createMessages(PANEL_OVERFLOW_UP_HINT_I18N).PANEL_OVERFLOW_UP_HINT;
1875
+ var PANEL_SNAPSHOT_SUMMARY_I18N = {
1876
+ PANEL_SNAPSHOT_SUMMARY: {
1877
+ en: (total, orphaned) => {
1878
+ const base = `Snapshots: ${total}`;
1879
+ if (orphaned > 0) {
1880
+ return `${base} (${chalk2.yellow(`${orphaned} orphaned`)})`;
1881
+ }
1882
+ return base;
1883
+ },
1884
+ "zh-CN": (total, orphaned) => {
1885
+ const base = `\u5FEB\u7167: ${total} \u4E2A`;
1886
+ if (orphaned > 0) {
1887
+ return `${base}\uFF08${chalk2.yellow(`${orphaned} \u4E2A\u5B64\u7ACB`)}\uFF09`;
1888
+ }
1889
+ return base;
1890
+ }
1891
+ }
1892
+ };
1893
+ var PANEL_SNAPSHOT_SUMMARY = createMessages(PANEL_SNAPSHOT_SUMMARY_I18N).PANEL_SNAPSHOT_SUMMARY;
1894
+ var PANEL_NO_WORKTREES_I18N = {
1895
+ PANEL_NO_WORKTREES: {
1896
+ en: "(No active worktrees)",
1897
+ "zh-CN": "(\u65E0\u6D3B\u8DC3 worktree)"
1898
+ }
1899
+ };
1900
+ var PANEL_NO_WORKTREES = createMessages(PANEL_NO_WORKTREES_I18N).PANEL_NO_WORKTREES;
1901
+ var PANEL_PRESS_ENTER_TO_RETURN_I18N = {
1902
+ PANEL_PRESS_ENTER_TO_RETURN: {
1903
+ en: chalk2.gray("\nPress Enter to return to panel..."),
1904
+ "zh-CN": chalk2.gray("\n\u6309 Enter \u8FD4\u56DE\u9762\u677F...")
1905
+ }
1906
+ };
1907
+ var PANEL_PRESS_ENTER_TO_RETURN = createMessages(PANEL_PRESS_ENTER_TO_RETURN_I18N).PANEL_PRESS_ENTER_TO_RETURN;
1908
+ var PANEL_NOT_TTY_I18N = {
1909
+ PANEL_NOT_TTY: {
1910
+ en: "Interactive panel requires a TTY terminal. Please run clawt status -i directly in a terminal",
1911
+ "zh-CN": "\u4EA4\u4E92\u5F0F\u9762\u677F\u9700\u8981 TTY \u7EC8\u7AEF\u73AF\u5883\uFF0C\u8BF7\u76F4\u63A5\u5728\u7EC8\u7AEF\u4E2D\u8FD0\u884C clawt status -i"
1912
+ }
1913
+ };
1914
+ var PANEL_NOT_TTY = createMessages(PANEL_NOT_TTY_I18N).PANEL_NOT_TTY;
1915
+ var PANEL_TITLE_I18N = {
1916
+ PANEL_TITLE: {
1917
+ en: (projectName) => chalk2.bold.cyan(`Project Status: ${projectName}`),
1918
+ "zh-CN": (projectName) => chalk2.bold.cyan(`\u9879\u76EE\u72B6\u6001\u603B\u89C8: ${projectName}`)
1919
+ }
1920
+ };
1921
+ var PANEL_TITLE = createMessages(PANEL_TITLE_I18N).PANEL_TITLE;
1922
+ var PANEL_CONFIGURED_BRANCH_I18N = {
1923
+ PANEL_CONFIGURED_BRANCH: {
1924
+ en: (branchName) => chalk2.gray(`Main work branch: ${branchName}`),
1925
+ "zh-CN": (branchName) => chalk2.gray(`\u4E3B\u5DE5\u4F5C\u5206\u652F: ${branchName}`)
1926
+ }
1927
+ };
1928
+ var PANEL_CONFIGURED_BRANCH = createMessages(PANEL_CONFIGURED_BRANCH_I18N).PANEL_CONFIGURED_BRANCH;
1929
+ var PANEL_CONFIGURED_BRANCH_DELETED_I18N = {
1930
+ PANEL_CONFIGURED_BRANCH_DELETED: {
1931
+ en: (branchName) => chalk2.red(`\u2717 Main work branch: ${branchName} (deleted)`),
1932
+ "zh-CN": (branchName) => chalk2.red(`\u2717 \u4E3B\u5DE5\u4F5C\u5206\u652F: ${branchName}\uFF08\u5DF2\u4E0D\u5B58\u5728\uFF09`)
1933
+ }
1934
+ };
1935
+ var PANEL_CONFIGURED_BRANCH_DELETED = createMessages(PANEL_CONFIGURED_BRANCH_DELETED_I18N).PANEL_CONFIGURED_BRANCH_DELETED;
1936
+ var PANEL_CONFIGURED_BRANCH_MISMATCH_I18N = {
1937
+ PANEL_CONFIGURED_BRANCH_MISMATCH: {
1938
+ en: (branchName) => chalk2.red(`\u26A0 Main work branch: ${branchName} (mismatch)`),
1939
+ "zh-CN": (branchName) => chalk2.red(`\u26A0 \u4E3B\u5DE5\u4F5C\u5206\u652F: ${branchName}\uFF08\u4E0D\u4E00\u81F4\uFF09`)
1940
+ }
1941
+ };
1942
+ var PANEL_CONFIGURED_BRANCH_MISMATCH = createMessages(PANEL_CONFIGURED_BRANCH_MISMATCH_I18N).PANEL_CONFIGURED_BRANCH_MISMATCH;
1943
+ var PANEL_NOT_INITIALIZED_I18N = {
1944
+ PANEL_NOT_INITIALIZED: {
1945
+ en: chalk2.gray("Not initialized (run clawt init to set main work branch)"),
1946
+ "zh-CN": chalk2.gray("\u672A\u521D\u59CB\u5316\uFF08\u6267\u884C clawt init \u8BBE\u7F6E\u4E3B\u5DE5\u4F5C\u5206\u652F\uFF09")
1947
+ }
1948
+ };
1949
+ var PANEL_NOT_INITIALIZED = createMessages(PANEL_NOT_INITIALIZED_I18N).PANEL_NOT_INITIALIZED;
1950
+ var PANEL_UNKNOWN_DATE_I18N = {
1951
+ PANEL_UNKNOWN_DATE: {
1952
+ en: "Unknown date",
1953
+ "zh-CN": "\u672A\u77E5\u65E5\u671F"
1954
+ }
1955
+ };
1956
+ var PANEL_UNKNOWN_DATE = createMessages(PANEL_UNKNOWN_DATE_I18N).PANEL_UNKNOWN_DATE;
1957
+ var PANEL_SYNCED_WITH_MAIN_I18N = {
1958
+ PANEL_SYNCED_WITH_MAIN: {
1959
+ en: "Synced with main branch",
1960
+ "zh-CN": "\u4E0E\u4E3B\u5206\u652F\u540C\u6B65"
1961
+ }
1962
+ };
1963
+ var PANEL_SYNCED_WITH_MAIN = createMessages(PANEL_SYNCED_WITH_MAIN_I18N).PANEL_SYNCED_WITH_MAIN;
1964
+ var PANEL_COMMITS_AHEAD_I18N = {
1965
+ PANEL_COMMITS_AHEAD: {
1966
+ en: (count) => `${count} local commit(s)`,
1967
+ "zh-CN": (count) => `${count} \u4E2A\u672C\u5730\u63D0\u4EA4`
1968
+ }
1969
+ };
1970
+ var PANEL_COMMITS_AHEAD = createMessages(PANEL_COMMITS_AHEAD_I18N).PANEL_COMMITS_AHEAD;
1971
+ var PANEL_COMMITS_BEHIND_I18N = {
1972
+ PANEL_COMMITS_BEHIND: {
1973
+ en: (count) => `${count} commit(s) behind main`,
1974
+ "zh-CN": (count) => `\u843D\u540E\u4E3B\u5206\u652F ${count} \u4E2A\u63D0\u4EA4`
1975
+ }
1976
+ };
1977
+ var PANEL_COMMITS_BEHIND = createMessages(PANEL_COMMITS_BEHIND_I18N).PANEL_COMMITS_BEHIND;
1978
+
1979
+ // src/constants/messages/cli-descriptions.ts
1980
+ var CLI_DESCRIPTIONS_I18N = {
1981
+ // 主程序
1982
+ PROGRAM_DESC: {
1983
+ en: "Run multiple Claude Code Agent tasks in parallel based on Git Worktree",
1984
+ "zh-CN": "\u672C\u5730\u5E76\u884C\u6267\u884C\u591A\u4E2AClaude Code Agent\u4EFB\u52A1\uFF0C\u878D\u5408 Git Worktree \u4E0E Claude Code CLI \u7684\u547D\u4EE4\u884C\u5DE5\u5177"
1985
+ },
1986
+ OPTION_DEBUG: {
1987
+ en: "Output debug information to terminal",
1988
+ "zh-CN": "\u8F93\u51FA\u8BE6\u7EC6\u8C03\u8BD5\u4FE1\u606F\u5230\u7EC8\u7AEF"
1989
+ },
1990
+ OPTION_YES: {
1991
+ en: "Skip all interactive confirmations, suitable for scripts/CI",
1992
+ "zh-CN": "\u8DF3\u8FC7\u6240\u6709\u4EA4\u4E92\u5F0F\u786E\u8BA4\uFF0C\u9002\u7528\u4E8E\u811A\u672C/CI \u73AF\u5883"
1993
+ },
1994
+ // config 命令
1995
+ CONFIG_DESC: { en: "Interactively view and modify global configuration", "zh-CN": "\u4EA4\u4E92\u5F0F\u67E5\u770B\u548C\u4FEE\u6539\u5168\u5C40\u914D\u7F6E" },
1996
+ CONFIG_RESET_DESC: { en: "Reset configuration to defaults", "zh-CN": "\u5C06\u914D\u7F6E\u6062\u590D\u4E3A\u9ED8\u8BA4\u503C" },
1997
+ CONFIG_SET_DESC: { en: "Set a configuration item (interactive without args)", "zh-CN": "\u4FEE\u6539\u914D\u7F6E\u9879\uFF08\u65E0\u53C2\u6570\u8FDB\u5165\u4EA4\u4E92\u5F0F\u914D\u7F6E\uFF09" },
1998
+ CONFIG_GET_DESC: { en: "Get a configuration item value", "zh-CN": "\u83B7\u53D6\u5355\u4E2A\u914D\u7F6E\u9879\u7684\u503C" },
1999
+ // init 命令
2000
+ INIT_DESC: { en: "Initialize project-level configuration, set main work branch", "zh-CN": "\u521D\u59CB\u5316\u9879\u76EE\u7EA7\u914D\u7F6E\uFF0C\u8BBE\u7F6E\u4E3B\u5DE5\u4F5C\u5206\u652F" },
2001
+ INIT_OPTION_BRANCH: { en: "Specify main work branch name (defaults to current branch)", "zh-CN": "\u6307\u5B9A\u4E3B\u5DE5\u4F5C\u5206\u652F\u540D\uFF08\u9ED8\u8BA4\u4F7F\u7528\u5F53\u524D\u5206\u652F\uFF09" },
2002
+ INIT_SHOW_DESC: { en: "Interactively view and modify project configuration (supports --json)", "zh-CN": "\u4EA4\u4E92\u5F0F\u67E5\u770B\u548C\u4FEE\u6539\u9879\u76EE\u914D\u7F6E\uFF08\u652F\u6301 --json \u683C\u5F0F\u8F93\u51FA\uFF09" },
2003
+ INIT_OPTION_JSON: { en: "Output in JSON format", "zh-CN": "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA" },
2004
+ // create 命令
2005
+ CREATE_DESC: { en: "Batch create worktrees and branches (with validate branches)", "zh-CN": "\u6279\u91CF\u521B\u5EFA worktree \u53CA\u5BF9\u5E94\u5206\u652F\uFF08\u542B\u9A8C\u8BC1\u5206\u652F\uFF09" },
2006
+ CREATE_OPTION_NUMBER: { en: "Number of worktrees to create", "zh-CN": "\u521B\u5EFA\u6570\u91CF" },
2007
+ CREATE_OPTION_POST_CREATE: { en: "Run postCreate hook (default on, --no-post-create to skip)", "zh-CN": "\u6267\u884C postCreate hook\uFF08\u9ED8\u8BA4\u5F00\u542F\uFF0C--no-post-create \u8DF3\u8FC7\uFF09" },
2008
+ // run 命令
2009
+ RUN_DESC: { en: "Batch create worktrees + run Claude Code tasks (supports task files)", "zh-CN": "\u6279\u91CF\u521B\u5EFA worktree + \u542F\u52A8 Claude Code \u6267\u884C\u4EFB\u52A1\uFF08\u652F\u6301\u4EFB\u52A1\u6587\u4EF6\uFF09" },
2010
+ RUN_OPTION_BRANCH: { en: "Branch name", "zh-CN": "\u5206\u652F\u540D" },
2011
+ RUN_OPTION_TASKS: { en: "Task list (can be specified multiple times)", "zh-CN": "\u4EFB\u52A1\u5217\u8868\uFF08\u53EF\u591A\u6B21\u6307\u5B9A\uFF09\uFF0C\u4E0D\u4F20\u5219\u5728 worktree \u4E2D\u6253\u5F00 Claude Code \u4EA4\u4E92\u5F0F\u754C\u9762" },
2012
+ RUN_OPTION_CONCURRENCY: { en: "Max concurrency, 0 means unlimited", "zh-CN": "\u6700\u5927\u5E76\u53D1\u6570\uFF0C0 \u8868\u793A\u4E0D\u9650\u5236" },
2013
+ RUN_OPTION_FILE: { en: "Read task list from file (mutually exclusive with --tasks)", "zh-CN": "\u4ECE\u4EFB\u52A1\u6587\u4EF6\u8BFB\u53D6\u4EFB\u52A1\u5217\u8868\uFF08\u4E0E --tasks \u4E92\u65A5\uFF09" },
2014
+ RUN_OPTION_DRY_RUN: { en: "Preview mode, show task plan without executing", "zh-CN": "\u9884\u89C8\u6A21\u5F0F\uFF0C\u4EC5\u5C55\u793A\u4EFB\u52A1\u8BA1\u5212\u4E0D\u5B9E\u9645\u6267\u884C" },
2015
+ RUN_OPTION_POST_CREATE: { en: "Run postCreate hook (default on, --no-post-create to skip)", "zh-CN": "\u6267\u884C postCreate hook\uFF08\u9ED8\u8BA4\u5F00\u542F\uFF0C--no-post-create \u8DF3\u8FC7\uFF09" },
2016
+ // validate 命令
2017
+ VALIDATE_DESC: { en: "Validate a worktree branch changes in the main worktree", "zh-CN": "\u5728\u4E3B worktree \u9A8C\u8BC1\u67D0\u4E2A worktree \u5206\u652F\u7684\u53D8\u66F4\uFF08\u901A\u8FC7\u9A8C\u8BC1\u5206\u652F\uFF09" },
2018
+ VALIDATE_OPTION_BRANCH: { en: "Branch name to validate (supports fuzzy match)", "zh-CN": "\u8981\u9A8C\u8BC1\u7684\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\uFF09" },
2019
+ VALIDATE_OPTION_CLEAN: { en: "Clean up validate state (reset main worktree and delete snapshots)", "zh-CN": "\u6E05\u7406 validate \u72B6\u6001\uFF08\u91CD\u7F6E\u4E3B worktree \u5E76\u5220\u9664\u5FEB\u7167\uFF09" },
2020
+ VALIDATE_OPTION_RUN: { en: "Command to run in main worktree after successful validation", "zh-CN": "validate \u6210\u529F\u540E\u5728\u4E3B worktree \u4E2D\u6267\u884C\u7684\u547D\u4EE4" },
2021
+ // merge 命令
2022
+ MERGE_DESC: { en: "Merge a validated worktree branch into the main worktree", "zh-CN": "\u5408\u5E76\u67D0\u4E2A\u5DF2\u9A8C\u8BC1\u7684 worktree \u5206\u652F\u5230\u4E3B worktree" },
2023
+ MERGE_OPTION_BRANCH: { en: "Branch to merge (supports fuzzy match)", "zh-CN": "\u8981\u5408\u5E76\u7684\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\u4F9B\u9009\u62E9\uFF09" },
2024
+ MERGE_OPTION_MESSAGE: { en: "Commit message (required if target worktree has modifications)", "zh-CN": "\u63D0\u4EA4\u4FE1\u606F\uFF08\u76EE\u6807 worktree \u5DE5\u4F5C\u533A\u6709\u4FEE\u6539\u65F6\u5FC5\u586B\uFF09" },
2025
+ MERGE_OPTION_AUTO: { en: "Auto-resolve conflicts with AI without asking", "zh-CN": "\u9047\u5230\u51B2\u7A81\u76F4\u63A5\u8C03\u7528 AI \u89E3\u51B3\uFF0C\u4E0D\u518D\u8BE2\u95EE" },
2026
+ // remove 命令
2027
+ REMOVE_DESC: { en: "Remove worktree (supports fuzzy match/multi-select/all)", "zh-CN": "\u79FB\u9664 worktree\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D/\u591A\u9009/\u5168\u90E8\uFF09" },
2028
+ REMOVE_OPTION_ALL: { en: "Remove all worktrees for the current project", "zh-CN": "\u79FB\u9664\u5F53\u524D\u9879\u76EE\u4E0B\u6240\u6709 worktree" },
2029
+ REMOVE_OPTION_BRANCH: { en: "Branch name (supports fuzzy match)", "zh-CN": "\u6307\u5B9A\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\uFF09" },
2030
+ // resume 命令
2031
+ RESUME_DESC: { en: "Resume a Claude Code session in an existing worktree", "zh-CN": "\u5728\u5DF2\u6709 worktree \u4E2D\u6062\u590D Claude Code \u4F1A\u8BDD\uFF08\u652F\u6301\u591A\u9009\u6279\u91CF\u6062\u590D\uFF09" },
2032
+ RESUME_OPTION_BRANCH: { en: "Branch to resume (supports fuzzy match)", "zh-CN": "\u8981\u6062\u590D\u7684\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\uFF09" },
2033
+ RESUME_OPTION_PROMPT: { en: "Non-interactive follow-up (requires -b)", "zh-CN": "\u975E\u4EA4\u4E92\u5F0F\u8FFD\u95EE\uFF08\u9700\u914D\u5408 -b \u6307\u5B9A\u5206\u652F\uFF09" },
2034
+ RESUME_OPTION_FILE: { en: "Batch follow-up from task file (matches by branch name)", "zh-CN": "\u4ECE\u4EFB\u52A1\u6587\u4EF6\u6279\u91CF\u8FFD\u95EE\uFF08\u901A\u8FC7 branch \u540D\u5339\u914D\u5DF2\u6709 worktree\uFF09" },
2035
+ RESUME_OPTION_CONCURRENCY: { en: "Max concurrency for batch follow-up, 0 means unlimited", "zh-CN": "\u6279\u91CF\u8FFD\u95EE\u6700\u5927\u5E76\u53D1\u6570\uFF0C0 \u8868\u793A\u4E0D\u9650\u5236" },
2036
+ // sync 命令
2037
+ SYNC_DESC: { en: "Sync main branch code to target worktree", "zh-CN": "\u5C06\u4E3B\u5206\u652F\u6700\u65B0\u4EE3\u7801\u540C\u6B65\u5230\u76EE\u6807 worktree" },
2038
+ SYNC_OPTION_BRANCH: { en: "Branch to sync (supports fuzzy match)", "zh-CN": "\u8981\u540C\u6B65\u7684\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\uFF09" },
2039
+ // status 命令
2040
+ STATUS_DESC: { en: "Show project status overview (supports --json)", "zh-CN": "\u663E\u793A\u9879\u76EE\u5168\u5C40\u72B6\u6001\u603B\u89C8\uFF08\u652F\u6301 --json \u683C\u5F0F\u8F93\u51FA\uFF09" },
2041
+ STATUS_OPTION_JSON: { en: "Output in JSON format", "zh-CN": "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA" },
2042
+ STATUS_OPTION_INTERACTIVE: { en: "Interactive panel mode", "zh-CN": "\u4EA4\u4E92\u5F0F\u9762\u677F\u6A21\u5F0F" },
2043
+ // list 命令
2044
+ LIST_DESC: { en: "List all worktrees (supports --json)", "zh-CN": "\u5217\u51FA\u5F53\u524D\u9879\u76EE\u6240\u6709 worktree\uFF08\u652F\u6301 --json \u683C\u5F0F\u8F93\u51FA\uFF09" },
2045
+ LIST_OPTION_JSON: { en: "Output in JSON format", "zh-CN": "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA" },
2046
+ // reset 命令
2047
+ RESET_DESC: { en: "Reset main worktree working directory and staging area", "zh-CN": "\u91CD\u7F6E\u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\uFF08\u4FDD\u7559 validate \u5FEB\u7167\uFF09" },
2048
+ // home 命令
2049
+ HOME_DESC: { en: "Switch back to the main work branch", "zh-CN": "\u5207\u6362\u56DE\u4E3B\u5DE5\u4F5C\u5206\u652F" },
2050
+ // projects 命令
2051
+ PROJECTS_DESC: { en: "Show worktree overview across projects", "zh-CN": "\u5C55\u793A\u6240\u6709\u9879\u76EE\u7684 worktree \u6982\u89C8\uFF0C\u6216\u67E5\u770B\u6307\u5B9A\u9879\u76EE\u7684 worktree \u8BE6\u60C5" },
2052
+ PROJECTS_OPTION_JSON: { en: "Output in JSON format", "zh-CN": "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA" },
2053
+ // alias 命令
2054
+ ALIAS_DESC: { en: "Manage command aliases (list / set / remove)", "zh-CN": "\u7BA1\u7406\u547D\u4EE4\u522B\u540D\uFF08\u5217\u51FA / \u8BBE\u7F6E / \u79FB\u9664\uFF09" },
2055
+ ALIAS_LIST_DESC: { en: "List all aliases", "zh-CN": "\u5217\u51FA\u6240\u6709\u522B\u540D" },
2056
+ ALIAS_SET_DESC: { en: "Set a command alias", "zh-CN": "\u8BBE\u7F6E\u547D\u4EE4\u522B\u540D" },
2057
+ ALIAS_REMOVE_DESC: { en: "Remove a command alias", "zh-CN": "\u79FB\u9664\u547D\u4EE4\u522B\u540D" },
2058
+ // completion 命令
2059
+ COMPLETION_DESC: { en: "Internal dynamic completion method (not public)", "zh-CN": "\u5185\u90E8\u4F7F\u7528\u7684\u52A8\u6001\u8865\u5168\u65B9\u6CD5\uFF0C\u4E0D\u5BF9\u5916\u516C\u5F00" },
2060
+ // tasks 命令
2061
+ TASKS_DESC: { en: "Task file management", "zh-CN": "\u4EFB\u52A1\u6587\u4EF6\u7BA1\u7406" },
2062
+ TASKS_INIT_DESC: { en: "Generate task template file", "zh-CN": "\u751F\u6210\u4EFB\u52A1\u6A21\u677F\u6587\u4EF6" },
2063
+ // cover 命令
2064
+ COVER_DESC: { en: "Cover validate branch changes back to target worktree", "zh-CN": "\u5C06\u9A8C\u8BC1\u5206\u652F\u4E0A\u7684\u4FEE\u6539\u8986\u76D6\u56DE\u76EE\u6807 worktree\uFF08\u81EA\u52A8\u63A8\u5BFC\u76EE\u6807\u5206\u652F\uFF09" }
2065
+ };
2066
+ var CLI_DESCRIPTIONS = createMessages(CLI_DESCRIPTIONS_I18N);
670
2067
 
671
2068
  // src/constants/messages/index.ts
672
2069
  var MESSAGES = {
@@ -708,6 +2105,11 @@ var ITERM2_APP_PATH = "/Applications/iTerm.app";
708
2105
  // src/constants/config.ts
709
2106
  var CLAUDE_CODE_ENTRYPOINT_VALUE = "cli";
710
2107
  var CONFIG_DEFINITIONS = {
2108
+ language: {
2109
+ defaultValue: "en",
2110
+ description: "\u754C\u9762\u8BED\u8A00\uFF1Aen\uFF08\u82F1\u6587\uFF09\u3001zh-CN\uFF08\u4E2D\u6587\uFF09",
2111
+ allowedValues: ["en", "zh-CN"]
2112
+ },
711
2113
  autoDeleteBranch: {
712
2114
  defaultValue: false,
713
2115
  description: "\u79FB\u9664 worktree \u65F6\u662F\u5426\u81EA\u52A8\u5220\u9664\u5BF9\u5E94\u672C\u5730\u5206\u652F"
@@ -769,6 +2171,23 @@ function deriveConfigDescriptions(definitions) {
769
2171
  }
770
2172
  var DEFAULT_CONFIG = deriveDefaultConfig(CONFIG_DEFINITIONS);
771
2173
  var CONFIG_DESCRIPTIONS = deriveConfigDescriptions(CONFIG_DEFINITIONS);
2174
+ var CONFIG_DESCRIPTIONS_EN = {
2175
+ language: "Interface language: en (English), zh-CN (Chinese)",
2176
+ autoDeleteBranch: "Whether to auto-delete the local branch when removing a worktree",
2177
+ claudeCodeCommand: "Claude Code CLI launch command",
2178
+ autoPullPush: "Whether to auto-run git pull and git push after merge",
2179
+ confirmDestructiveOps: "Whether to prompt for confirmation before destructive operations (reset, validate --clean)",
2180
+ maxConcurrency: "Default max concurrency for run command, 0 means unlimited",
2181
+ terminalApp: "Terminal app for batch resume: auto (auto-detect), iterm2, terminal, cmux (macOS)",
2182
+ resumeInPlace: "Whether to resume in current terminal (single select), false opens in new tab via terminalApp",
2183
+ aliases: "Command alias mapping",
2184
+ autoUpdate: "Whether to enable auto-update checks (every 24 hours via npm registry)",
2185
+ conflictResolveMode: "Merge conflict resolution mode: ask (prompt for AI), auto (auto AI resolve), manual (manual resolve)",
2186
+ conflictResolveTimeoutMs: "Claude Code conflict resolution timeout (ms), default 900000 (15 min)"
2187
+ };
2188
+ function getI18nConfigDescriptions() {
2189
+ return getCurrentLanguage() === "en" ? CONFIG_DESCRIPTIONS_EN : CONFIG_DESCRIPTIONS;
2190
+ }
772
2191
 
773
2192
  // src/constants/project-config.ts
774
2193
  var PROJECT_CONFIG_DEFINITIONS = {
@@ -803,6 +2222,15 @@ function deriveConfigDescriptions2(definitions) {
803
2222
  }
804
2223
  var PROJECT_DEFAULT_CONFIG = deriveDefaultConfig2(PROJECT_CONFIG_DEFINITIONS);
805
2224
  var PROJECT_CONFIG_DESCRIPTIONS = deriveConfigDescriptions2(PROJECT_CONFIG_DEFINITIONS);
2225
+ var PROJECT_CONFIG_DESCRIPTIONS_EN = {
2226
+ clawtMainWorkBranch: "Main worktree branch name",
2227
+ validateRunCommand: "Command to auto-run after validate success (default for -r)",
2228
+ postCreate: "Command to auto-run after worktree creation (e.g. install dependencies)",
2229
+ claudeCodeCommand: "Claude Code CLI launch command (falls back to global config if unset)"
2230
+ };
2231
+ function getI18nProjectConfigDescriptions() {
2232
+ return getCurrentLanguage() === "en" ? PROJECT_CONFIG_DESCRIPTIONS_EN : PROJECT_CONFIG_DESCRIPTIONS;
2233
+ }
806
2234
 
807
2235
  // src/constants/git.ts
808
2236
  var AUTO_SAVE_COMMIT_MESSAGE_PREFIX = "clawt: auto-save before merging";
@@ -836,16 +2264,10 @@ var TASK_STATUS_ICONS = {
836
2264
  /** 失败 */
837
2265
  FAILED: "\u2717"
838
2266
  };
839
- var TASK_STATUS_LABELS = {
840
- /** 排队中 */
841
- PENDING: "\u6392\u961F\u4E2D",
842
- /** 运行中 */
843
- RUNNING: "\u8FD0\u884C\u4E2D",
844
- /** 完成 */
845
- DONE: "\u5B8C\u6210",
846
- /** 失败 */
847
- FAILED: "\u5931\u8D25"
848
- };
2267
+ function getTaskStatusLabels() {
2268
+ const lang = getCurrentLanguage();
2269
+ return lang === "en" ? { PENDING: "Pending", RUNNING: "Running", DONE: "Done", FAILED: "Failed" } : { PENDING: "\u6392\u961F\u4E2D", RUNNING: "\u8FD0\u884C\u4E2D", DONE: "\u5B8C\u6210", FAILED: "\u5931\u8D25" };
2270
+ }
849
2271
  var ACTIVITY_TEXT_MAX_LENGTH = 30;
850
2272
  var TEXT_ACTIVITY_PREFIX = "\u601D\u8003\u4E2D";
851
2273
  var RESULT_PREVIEW_MAX_LENGTH = 40;
@@ -860,29 +2282,33 @@ var CLEAR_SCREEN = "\x1B[2J";
860
2282
  var CURSOR_HOME = "\x1B[H";
861
2283
 
862
2284
  // src/constants/prompt.ts
863
- import chalk2 from "chalk";
2285
+ import chalk3 from "chalk";
864
2286
  var SELECT_ALL_NAME = "__select_all__";
865
2287
  var SELECT_ALL_LABEL = "[select-all]";
866
2288
  var GROUP_SELECT_ALL_PREFIX = "__group_select_all_";
867
2289
  var GROUP_SELECT_ALL_LABEL = (dateLabel) => `[select-all: ${dateLabel}]`;
868
- var GROUP_SEPARATOR_LABEL = (dateLabel, relativeTime) => `\u2550\u2550\u2550\u2550 ${chalk2.bold.hex("#FF8C00")(dateLabel)}\uFF08${chalk2.hex("#FF8C00")(relativeTime)}\uFF09 \u2550\u2550\u2550\u2550`;
2290
+ var GROUP_SEPARATOR_LABEL = (dateLabel, relativeTime) => {
2291
+ const lang = getCurrentLanguage();
2292
+ const separator = lang === "en" ? `\u2550\u2550\u2550\u2550 ${chalk3.bold.hex("#FF8C00")(dateLabel)} (${chalk3.hex("#FF8C00")(relativeTime)}) \u2550\u2550\u2550\u2550` : `\u2550\u2550\u2550\u2550 ${chalk3.bold.hex("#FF8C00")(dateLabel)}\uFF08${chalk3.hex("#FF8C00")(relativeTime)}\uFF09 \u2550\u2550\u2550\u2550`;
2293
+ return separator;
2294
+ };
869
2295
  var UNKNOWN_DATE_GROUP = "\u672A\u77E5\u65E5\u671F";
870
- var UNKNOWN_DATE_SEPARATOR_LABEL = `\u2550\u2550\u2550\u2550 ${chalk2.bold.hex("#FF8C00")("\u672A\u77E5\u65E5\u671F")} \u2550\u2550\u2550\u2550`;
2296
+ var UNKNOWN_DATE_SEPARATOR_LABEL = `\u2550\u2550\u2550\u2550 ${chalk3.bold.hex("#FF8C00")("\u672A\u77E5\u65E5\u671F")} \u2550\u2550\u2550\u2550`;
871
2297
 
872
2298
  // src/constants/ai-prompts.ts
873
- var CONFLICT_RESOLVE_PROMPT = `\u4F60\u662F\u4E00\u4E2A Git \u5408\u5E76\u51B2\u7A81\u89E3\u51B3\u4E13\u5BB6\u3002\u5F53\u524D\u4ED3\u5E93\u5904\u4E8E\u5408\u5E76\u51B2\u7A81\u72B6\u6001\u3002
2299
+ var CONFLICT_RESOLVE_PROMPT = `You are a Git merge conflict resolution expert. The repository is currently in a merge conflict state.
874
2300
 
875
- ## \u4EFB\u52A1
2301
+ ## Task
876
2302
 
877
- 1. \u901A\u8FC7 git status \u548C git diff \u7B49\u547D\u4EE4\uFF0C\u81EA\u884C\u67E5\u770B\u5F53\u524D\u4ED3\u5E93\u7684\u51B2\u7A81\u6587\u4EF6\u5217\u8868\u53CA\u51B2\u7A81\u5185\u5BB9
878
- 2. \u901A\u8FC7 git log \u7B49\u547D\u4EE4\uFF0C\u5206\u6790\u4E24\u4E2A\u5206\u652F\u5404\u81EA\u7684\u53D8\u66F4\u610F\u56FE
879
- 3. \u76F4\u63A5\u7F16\u8F91\u6BCF\u4E2A\u51B2\u7A81\u6587\u4EF6\uFF0C\u79FB\u9664\u6240\u6709\u51B2\u7A81\u6807\u8BB0\uFF08<<<<<<<\u3001=======\u3001>>>>>>>\uFF09
880
- 4. \u4FDD\u7559\u53CC\u65B9\u6709\u610F\u4E49\u7684\u53D8\u66F4\uFF0C\u5408\u7406\u5408\u5E76\u4EE3\u7801\u903B\u8F91
881
- 5. \u5982\u679C\u4E24\u4E2A\u5206\u652F\u4FEE\u6539\u4E86\u540C\u4E00\u6BB5\u4EE3\u7801\u4F46\u610F\u56FE\u4E0D\u540C\uFF0C\u4F18\u5148\u4FDD\u8BC1\u4EE3\u7801\u7684\u6B63\u786E\u6027\u548C\u5B8C\u6574\u6027
882
- 6. \u89E3\u51B3\u51B2\u7A81\u540E\uFF0C\u786E\u4FDD\u4EE3\u7801\u8BED\u6CD5\u6B63\u786E\u3001\u903B\u8F91\u5B8C\u6574
883
- 7. \u4E0D\u8981\u6DFB\u52A0\u4EFB\u4F55\u6CE8\u91CA\u8BF4\u660E\u4F60\u505A\u4E86\u4EC0\u4E48\u4FEE\u6539\uFF0C\u53EA\u9700\u8981\u4FEE\u6539\u6587\u4EF6\u5185\u5BB9
2303
+ 1. Use git status and git diff to examine the list of conflicted files and their contents
2304
+ 2. Use git log to analyze the change intent of each branch
2305
+ 3. Directly edit each conflicted file, removing all conflict markers (<<<<<<<, =======, >>>>>>>)
2306
+ 4. Preserve meaningful changes from both sides, merging code logic appropriately
2307
+ 5. If both branches modified the same section with different intents, prioritize code correctness and completeness
2308
+ 6. After resolving conflicts, ensure code syntax is correct and logic is complete
2309
+ 7. Do not add any comments explaining your modifications, only modify file contents
884
2310
 
885
- \u8BF7\u76F4\u63A5\u5F00\u59CB\u3002`;
2311
+ Please begin.`;
886
2312
 
887
2313
  // src/constants/pre-checks.ts
888
2314
  var PRE_CHECK_CREATE = {
@@ -913,7 +2339,32 @@ var PRE_CHECK_RESUME = {
913
2339
  // src/constants/tasks-template.ts
914
2340
  var TASK_TEMPLATE_OUTPUT_DIR = ".clawt/tasks";
915
2341
  var TASK_TEMPLATE_FILENAME_PREFIX = "clawt-tasks";
916
- var TASK_TEMPLATE_CONTENT = `# Clawt \u4EFB\u52A1\u6587\u4EF6
2342
+ function getTaskTemplateContent() {
2343
+ const lang = getCurrentLanguage();
2344
+ if (lang === "en") {
2345
+ return `# Clawt Task File
2346
+ #
2347
+ # Usage: clawt run -f tasks.md
2348
+ # Format: Text outside tags is ignored, each task is wrapped in START/END tags
2349
+ #
2350
+ # Rules:
2351
+ # 1. Each task block is wrapped with <START> and <END> tags (see example below)
2352
+ # 2. Use # branch: <branch-name> inside the block to declare branch name (can be omitted with -b)
2353
+ # 3. Other lines inside the block are the task description (supports multi-line)
2354
+
2355
+ <!-- CLAWT-TASKS:START -->
2356
+ # branch: feat-example-1
2357
+ Write your first task description here
2358
+ <!-- CLAWT-TASKS:END -->
2359
+
2360
+ <!-- CLAWT-TASKS:START -->
2361
+ # branch: feat-example-2
2362
+ Write your second task description here
2363
+ Multi-line descriptions are supported
2364
+ <!-- CLAWT-TASKS:END -->
2365
+ `;
2366
+ }
2367
+ return `# Clawt \u4EFB\u52A1\u6587\u4EF6
917
2368
  #
918
2369
  # \u4F7F\u7528\u65B9\u6CD5: clawt run -f tasks.md
919
2370
  # \u683C\u5F0F\u8BF4\u660E: \u6807\u7B7E\u5916\u7684\u6587\u672C\u4F1A\u88AB\u5FFD\u7565\uFF0C\u6BCF\u4E2A\u4EFB\u52A1\u7528 START/END \u6807\u7B7E\u5305\u88F9
@@ -934,6 +2385,7 @@ var TASK_TEMPLATE_CONTENT = `# Clawt \u4EFB\u52A1\u6587\u4EF6
934
2385
  \u652F\u6301\u591A\u884C\u63CF\u8FF0
935
2386
  <!-- CLAWT-TASKS:END -->
936
2387
  `;
2388
+ }
937
2389
 
938
2390
  // src/errors/index.ts
939
2391
  var ClawtError = class extends Error {
@@ -950,69 +2402,12 @@ var ClawtError = class extends Error {
950
2402
  }
951
2403
  };
952
2404
 
953
- // src/logger/index.ts
954
- import winston from "winston";
955
- import DailyRotateFile from "winston-daily-rotate-file";
956
- import chalk3 from "chalk";
957
- import { existsSync, mkdirSync } from "fs";
958
- if (!existsSync(LOGS_DIR)) {
959
- mkdirSync(LOGS_DIR, { recursive: true });
960
- }
961
- var logFormat = winston.format.printf(({ level, message, timestamp }) => {
962
- const upperLevel = level.toUpperCase().padEnd(5);
963
- return `[${timestamp}] [${upperLevel}] ${message}`;
964
- });
965
- var dailyRotateTransport = new DailyRotateFile({
966
- dirname: LOGS_DIR,
967
- filename: "clawt-%DATE%.log",
968
- datePattern: "YYYY-MM-DD",
969
- maxSize: "10m",
970
- maxFiles: "30d"
971
- });
972
- var logger = winston.createLogger({
973
- level: "debug",
974
- format: winston.format.combine(
975
- winston.format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }),
976
- logFormat
977
- ),
978
- transports: [dailyRotateTransport]
979
- });
980
- var LEVEL_COLORS = {
981
- error: chalk3.red,
982
- warn: chalk3.yellow,
983
- info: chalk3.cyan,
984
- debug: chalk3.gray
985
- };
986
- function colorizeLevel(level) {
987
- const colorFn = LEVEL_COLORS[level] || chalk3.white;
988
- return colorFn(level.toUpperCase().padEnd(5));
989
- }
990
- function enableConsoleTransport() {
991
- const hasConsole = logger.transports.some(
992
- (t) => t instanceof winston.transports.Console
993
- );
994
- if (hasConsole) {
995
- return;
996
- }
997
- const consoleFormat = winston.format.printf(({ level, message, timestamp }) => {
998
- return `${chalk3.gray(timestamp)} ${colorizeLevel(level)} ${message}`;
999
- });
1000
- const consoleTransport = new winston.transports.Console({
1001
- level: "debug",
1002
- format: winston.format.combine(
1003
- winston.format.timestamp({ format: DEBUG_TIMESTAMP_FORMAT }),
1004
- consoleFormat
1005
- )
1006
- });
1007
- logger.add(consoleTransport);
1008
- }
1009
-
1010
2405
  // src/utils/shell.ts
1011
2406
  import { exec, execSync as execSync2, execFileSync, spawn, spawnSync } from "child_process";
1012
2407
  import { promisify } from "util";
1013
2408
 
1014
2409
  // src/utils/git-lock.ts
1015
- import { join as join2, isAbsolute } from "path";
2410
+ import { join as join3, isAbsolute } from "path";
1016
2411
  import { execSync } from "child_process";
1017
2412
  var INDEX_LOCK_ERROR_PATTERNS = [
1018
2413
  // 英文错误消息
@@ -1042,10 +2437,10 @@ function findGitIndexLockPath(cwd) {
1042
2437
  encoding: "utf-8",
1043
2438
  stdio: ["pipe", "pipe", "pipe"]
1044
2439
  }).trim();
1045
- return isAbsolute(gitDir) ? join2(gitDir, "index.lock") : join2(cwd || process.cwd(), gitDir, "index.lock");
2440
+ return isAbsolute(gitDir) ? join3(gitDir, "index.lock") : join3(cwd || process.cwd(), gitDir, "index.lock");
1046
2441
  } catch (error) {
1047
2442
  logger.warn(`\u5B9A\u4F4D git \u76EE\u5F55\u5931\u8D25: ${error}`);
1048
- return join2(cwd || process.cwd(), ".git", "index.lock");
2443
+ return join3(cwd || process.cwd(), ".git", "index.lock");
1049
2444
  }
1050
2445
  }
1051
2446
  function parseIndexLockPathFromError(errorMessage) {
@@ -1540,17 +2935,22 @@ function confirmAction(question, nonInteractiveDefault = true) {
1540
2935
  });
1541
2936
  }
1542
2937
  function confirmDestructiveAction(dangerousCommand, description) {
1543
- printWarning(`\u5373\u5C06\u6267\u884C ${chalk4.red.bold(dangerousCommand)}\uFF0C${description}`);
1544
- return confirmAction("\u662F\u5426\u7EE7\u7EED\uFF1F");
2938
+ const lang = getCurrentLanguage();
2939
+ const continuePrompt = lang === "en" ? "Continue?" : "\u662F\u5426\u7EE7\u7EED\uFF1F";
2940
+ const warningPrefix = lang === "en" ? `About to execute ${chalk4.red.bold(dangerousCommand)}, ` : `\u5373\u5C06\u6267\u884C ${chalk4.red.bold(dangerousCommand)}\uFF0C`;
2941
+ printWarning(`${warningPrefix}${description}`);
2942
+ return confirmAction(continuePrompt);
1545
2943
  }
1546
2944
  function isWorktreeIdle(status) {
1547
2945
  return status.commitCount === 0 && status.insertions === 0 && status.deletions === 0 && !status.hasDirtyFiles;
1548
2946
  }
1549
2947
  function formatWorktreeStatus(status) {
2948
+ const lang = getCurrentLanguage();
1550
2949
  const parts = [];
1551
- parts.push(chalk4.yellow(`${status.commitCount} \u4E2A\u63D0\u4EA4`));
2950
+ const commitLabel = lang === "en" ? `${status.commitCount} commit${status.commitCount !== 1 ? "s" : ""}` : `${status.commitCount} \u4E2A\u63D0\u4EA4`;
2951
+ parts.push(chalk4.yellow(commitLabel));
1552
2952
  if (status.insertions === 0 && status.deletions === 0) {
1553
- parts.push("\u65E0\u53D8\u66F4");
2953
+ parts.push(lang === "en" ? "No changes" : "\u65E0\u53D8\u66F4");
1554
2954
  } else {
1555
2955
  const diffParts = [];
1556
2956
  diffParts.push(chalk4.green(`+${status.insertions}`));
@@ -1558,7 +2958,7 @@ function formatWorktreeStatus(status) {
1558
2958
  parts.push(diffParts.join(" "));
1559
2959
  }
1560
2960
  if (status.hasDirtyFiles) {
1561
- parts.push(chalk4.gray("(\u672A\u63D0\u4EA4\u4FEE\u6539)"));
2961
+ parts.push(chalk4.gray(lang === "en" ? "(uncommitted changes)" : "(\u672A\u63D0\u4EA4\u4FEE\u6539)"));
1562
2962
  }
1563
2963
  return parts.join(" ");
1564
2964
  }
@@ -1572,6 +2972,7 @@ function formatDuration(ms) {
1572
2972
  return `${minutes}m${String(seconds).padStart(2, "0")}s`;
1573
2973
  }
1574
2974
  function formatRelativeTime(isoDateString) {
2975
+ const lang = getCurrentLanguage();
1575
2976
  const date = new Date(isoDateString);
1576
2977
  const now = /* @__PURE__ */ new Date();
1577
2978
  const diffMs = now.getTime() - date.getTime();
@@ -1579,26 +2980,26 @@ function formatRelativeTime(isoDateString) {
1579
2980
  return null;
1580
2981
  }
1581
2982
  if (diffMs < 0 || diffMs < 60 * 1e3) {
1582
- return "\u521A\u521A";
2983
+ return lang === "en" ? "just now" : "\u521A\u521A";
1583
2984
  }
1584
2985
  const diffMinutes = Math.floor(diffMs / (1e3 * 60));
1585
2986
  const diffHours = Math.floor(diffMs / (1e3 * 60 * 60));
1586
2987
  const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
1587
2988
  if (diffHours < 1) {
1588
- return `${diffMinutes} \u5206\u949F\u524D`;
2989
+ return lang === "en" ? `${diffMinutes} min ago` : `${diffMinutes} \u5206\u949F\u524D`;
1589
2990
  }
1590
2991
  if (diffDays < 1) {
1591
- return `${diffHours} \u5C0F\u65F6\u524D`;
2992
+ return lang === "en" ? `${diffHours} hr ago` : `${diffHours} \u5C0F\u65F6\u524D`;
1592
2993
  }
1593
2994
  if (diffDays < 30) {
1594
- return `${diffDays} \u5929\u524D`;
2995
+ return lang === "en" ? `${diffDays} day${diffDays > 1 ? "s" : ""} ago` : `${diffDays} \u5929\u524D`;
1595
2996
  }
1596
2997
  if (diffDays < 365) {
1597
2998
  const months = Math.floor(diffDays / 30);
1598
- return `${months} \u4E2A\u6708\u524D`;
2999
+ return lang === "en" ? `${months} month${months > 1 ? "s" : ""} ago` : `${months} \u4E2A\u6708\u524D`;
1599
3000
  }
1600
3001
  const years = Math.floor(diffDays / 365);
1601
- return `${years} \u5E74\u524D`;
3002
+ return lang === "en" ? `${years} year${years > 1 ? "s" : ""} ago` : `${years} \u5E74\u524D`;
1602
3003
  }
1603
3004
  function formatDiskSize(bytes) {
1604
3005
  const KB = 1024;
@@ -1670,90 +3071,6 @@ function validateBranchesNotExist(branchNames) {
1670
3071
  import { existsSync as existsSync4, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
1671
3072
  import { join as join4 } from "path";
1672
3073
 
1673
- // src/utils/fs.ts
1674
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readdirSync, rmdirSync, statSync } from "fs";
1675
- import { join as join3 } from "path";
1676
- function ensureDir(dirPath) {
1677
- if (!existsSync2(dirPath)) {
1678
- mkdirSync2(dirPath, { recursive: true });
1679
- }
1680
- }
1681
- function removeEmptyDir(dirPath) {
1682
- if (!existsSync2(dirPath)) {
1683
- return false;
1684
- }
1685
- const entries = readdirSync(dirPath);
1686
- if (entries.length === 0) {
1687
- rmdirSync(dirPath);
1688
- return true;
1689
- }
1690
- return false;
1691
- }
1692
- function calculateDirSize(dirPath) {
1693
- let totalSize = 0;
1694
- try {
1695
- const entries = readdirSync(dirPath, { withFileTypes: true });
1696
- for (const entry of entries) {
1697
- const fullPath = join3(dirPath, entry.name);
1698
- try {
1699
- if (entry.isDirectory()) {
1700
- totalSize += calculateDirSize(fullPath);
1701
- } else if (entry.isFile()) {
1702
- totalSize += statSync(fullPath).size;
1703
- }
1704
- } catch {
1705
- }
1706
- }
1707
- } catch {
1708
- }
1709
- return totalSize;
1710
- }
1711
-
1712
- // src/utils/config.ts
1713
- import { existsSync as existsSync3, readFileSync, writeFileSync } from "fs";
1714
- function loadConfig() {
1715
- if (!existsSync3(CONFIG_PATH)) {
1716
- return { ...DEFAULT_CONFIG };
1717
- }
1718
- try {
1719
- const raw = readFileSync(CONFIG_PATH, "utf-8");
1720
- return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };
1721
- } catch {
1722
- logger.warn(MESSAGES.CONFIG_CORRUPTED);
1723
- writeDefaultConfig();
1724
- return { ...DEFAULT_CONFIG };
1725
- }
1726
- }
1727
- function writeConfig(config2) {
1728
- writeFileSync(CONFIG_PATH, JSON.stringify(config2, null, 2), "utf-8");
1729
- }
1730
- function writeDefaultConfig() {
1731
- writeConfig(DEFAULT_CONFIG);
1732
- }
1733
- function saveConfig(config2) {
1734
- writeFileSync(CONFIG_PATH, JSON.stringify(config2, null, 2), "utf-8");
1735
- }
1736
- function getConfigValue(key) {
1737
- const config2 = loadConfig();
1738
- return config2[key];
1739
- }
1740
- function ensureClawtDirs() {
1741
- ensureDir(CLAWT_HOME);
1742
- ensureDir(LOGS_DIR);
1743
- ensureDir(WORKTREES_DIR);
1744
- ensureDir(PROJECTS_CONFIG_DIR);
1745
- }
1746
- function parseConcurrency(optionValue, configValue) {
1747
- if (optionValue === void 0) {
1748
- return configValue;
1749
- }
1750
- const parsed = parseInt(optionValue, 10);
1751
- if (Number.isNaN(parsed) || parsed < 0) {
1752
- throw new ClawtError(MESSAGES.CONCURRENCY_INVALID);
1753
- }
1754
- return parsed;
1755
- }
1756
-
1757
3074
  // src/utils/json.ts
1758
3075
  function primitiveToString(value) {
1759
3076
  if (value === void 0) {
@@ -1920,31 +3237,31 @@ async function handleDirtyWorkingDir(cwd) {
1920
3237
  gitAddAll(cwd);
1921
3238
  gitStashPush("clawt:auto-stash", cwd);
1922
3239
  if (!isWorkingDirClean(cwd)) {
1923
- throw new ClawtError("\u5DE5\u4F5C\u533A\u4ECD\u7136\u4E0D\u5E72\u51C0\uFF0C\u8BF7\u624B\u52A8\u5904\u7406");
3240
+ throw new ClawtError(MESSAGES.WORKSPACE_STILL_DIRTY);
1924
3241
  }
1925
3242
  return;
1926
3243
  }
1927
- printWarning("\u5F53\u524D\u5206\u652F\u6709\u672A\u63D0\u4EA4\u7684\u66F4\u6539\uFF0C\u8BF7\u9009\u62E9\u5904\u7406\u65B9\u5F0F\uFF1A\n");
3244
+ printWarning(MESSAGES.UNCOMMITTED_CHANGES_ON_BRANCH);
1928
3245
  const choice = await new Enquirer.Select({
1929
- message: "\u9009\u62E9\u5904\u7406\u65B9\u5F0F",
3246
+ message: MESSAGES.SELECT_ACTION,
1930
3247
  choices: [
1931
3248
  {
1932
3249
  name: "reset",
1933
- message: "reset - \u4E22\u5F03\u6240\u6709\u66F4\u6539 (git reset --hard HEAD && git clean -fd)"
3250
+ message: getCurrentLanguage() === "en" ? "reset - Discard all changes (git reset --hard HEAD && git clean -fd)" : "reset - \u4E22\u5F03\u6240\u6709\u66F4\u6539 (git reset --hard HEAD && git clean -fd)"
1934
3251
  },
1935
3252
  {
1936
3253
  name: "stash",
1937
- message: "stash - \u6682\u5B58\u66F4\u6539 (git add . && git stash)"
3254
+ message: getCurrentLanguage() === "en" ? "stash - Stash changes (git add . && git stash)" : "stash - \u6682\u5B58\u66F4\u6539 (git add . && git stash)"
1938
3255
  },
1939
3256
  {
1940
3257
  name: "exit",
1941
- message: "exit - \u9000\u51FA\uFF0C\u624B\u52A8\u5904\u7406"
3258
+ message: getCurrentLanguage() === "en" ? "exit - Exit, handle manually" : "exit - \u9000\u51FA\uFF0C\u624B\u52A8\u5904\u7406"
1942
3259
  }
1943
3260
  ],
1944
3261
  initial: 0
1945
3262
  }).run();
1946
3263
  if (choice === "exit") {
1947
- throw new ClawtError("\u7528\u6237\u9009\u62E9\u9000\u51FA\uFF0C\u8BF7\u624B\u52A8\u5904\u7406\u5DE5\u4F5C\u533A\u66F4\u6539\u540E\u91CD\u8BD5");
3264
+ throw new ClawtError(MESSAGES.USER_CHOSE_EXIT);
1948
3265
  }
1949
3266
  if (choice === "reset") {
1950
3267
  gitResetHard(cwd);
@@ -1954,7 +3271,7 @@ async function handleDirtyWorkingDir(cwd) {
1954
3271
  gitStashPush("clawt:auto-stash", cwd);
1955
3272
  }
1956
3273
  if (!isWorkingDirClean(cwd)) {
1957
- throw new ClawtError("\u5DE5\u4F5C\u533A\u4ECD\u7136\u4E0D\u5E72\u51C0\uFF0C\u8BF7\u624B\u52A8\u5904\u7406");
3274
+ throw new ClawtError(MESSAGES.WORKSPACE_STILL_DIRTY);
1958
3275
  }
1959
3276
  }
1960
3277
  async function ensureOnMainWorkBranch(cwd) {
@@ -1973,7 +3290,7 @@ async function ensureOnMainWorkBranch(cwd) {
1973
3290
  return;
1974
3291
  }
1975
3292
  printWarning(MESSAGES.GUARD_BRANCH_MISMATCH(mainBranch, currentBranch));
1976
- const confirmed = isNonInteractive() ? true : await confirmAction("\u662F\u5426\u7EE7\u7EED\u6267\u884C\uFF1F");
3293
+ const confirmed = isNonInteractive() ? true : await confirmAction(MESSAGES.CONFIRM_CONTINUE_VALIDATE);
1977
3294
  if (!confirmed) {
1978
3295
  throw new ClawtError(MESSAGES.DESTRUCTIVE_OP_CANCELLED);
1979
3296
  }
@@ -2173,7 +3490,7 @@ async function promptCommitMessage(promptMessage, nonInteractiveErrorMessage) {
2173
3490
  });
2174
3491
  const result = await prompt.run();
2175
3492
  if (!result.trim()) {
2176
- throw new ClawtError("\u63D0\u4EA4\u4FE1\u606F\u4E0D\u80FD\u4E3A\u7A7A");
3493
+ throw new ClawtError(MESSAGES.COMMIT_MESSAGE_NOT_EMPTY);
2177
3494
  }
2178
3495
  return result.trim();
2179
3496
  }
@@ -2243,7 +3560,7 @@ end tell
2243
3560
  function openCommandInCmuxSurface(command, title) {
2244
3561
  if (!isCmuxEnvironment()) {
2245
3562
  throw new ClawtError(
2246
- "\u5F53\u524D\u4E0D\u5728 cmux \u73AF\u5883\u4E2D\uFF0C\u65E0\u6CD5\u521B\u5EFA surface\n\u8BF7\u786E\u4FDD\u5728 cmux \u7EC8\u7AEF\u4E2D\u6267\u884C clawt resume \u547D\u4EE4\uFF0C\u6216\u4FEE\u6539 terminalApp \u914D\u7F6E"
3563
+ MESSAGES.NOT_IN_CMUX
2247
3564
  );
2248
3565
  }
2249
3566
  logger.debug(`\u5728 cmux \u4E2D\u521B\u5EFA\u65B0 surface: ${title}`);
@@ -2262,7 +3579,7 @@ function openCommandInCmuxSurface(command, title) {
2262
3579
  logger.debug(`new-split \u8F93\u51FA: ${newSurfaceResult}`);
2263
3580
  const match = newSurfaceResult.match(/(?:OK\s+)?(surface:\d+)/i);
2264
3581
  if (!match) {
2265
- throw new Error(`\u65E0\u6CD5\u89E3\u6790 cmux new-split \u8F93\u51FA: ${newSurfaceResult}`);
3582
+ throw new Error(getCurrentLanguage() === "en" ? `Failed to parse cmux new-split output: ${newSurfaceResult}` : `\u65E0\u6CD5\u89E3\u6790 cmux new-split \u8F93\u51FA: ${newSurfaceResult}`);
2266
3583
  }
2267
3584
  const surfaceRef = match[1];
2268
3585
  logger.debug(`\u5DF2\u521B\u5EFA surface: ${surfaceRef}`);
@@ -2280,7 +3597,7 @@ function openCommandInCmuxSurface(command, title) {
2280
3597
  logger.debug(`\u5DF2\u5411 ${surfaceRef} \u53D1\u9001\u547D\u4EE4`);
2281
3598
  } catch (error) {
2282
3599
  const message = error instanceof Error ? error.message : String(error);
2283
- throw new ClawtError(`\u5728 cmux \u4E2D\u521B\u5EFA surface \u5931\u8D25: ${message}`);
3600
+ throw new ClawtError(getCurrentLanguage() === "en" ? `Failed to create surface in cmux: ${message}` : `\u5728 cmux \u4E2D\u521B\u5EFA surface \u5931\u8D25: ${message}`);
2284
3601
  }
2285
3602
  }
2286
3603
  function executeAppleScript(script, terminalApp) {
@@ -2293,13 +3610,13 @@ function executeAppleScript(script, terminalApp) {
2293
3610
  });
2294
3611
  } catch (error) {
2295
3612
  const message = error instanceof Error ? error.message : String(error);
2296
- const accessibilityHint = terminalApp === "terminal" ? "\n\u63D0\u793A\uFF1ATerminal.app \u9700\u8981\u8F85\u52A9\u529F\u80FD\u6743\u9650\uFF0C\u8BF7\u5728\u300C\u7CFB\u7EDF\u8BBE\u7F6E \u2192 \u9690\u79C1\u4E0E\u5B89\u5168\u6027 \u2192 \u8F85\u52A9\u529F\u80FD\u300D\u4E2D\u6388\u6743\u7EC8\u7AEF\u5E94\u7528" : "";
2297
- throw new ClawtError(`\u6253\u5F00\u7EC8\u7AEF Tab \u5931\u8D25: ${message}${accessibilityHint}`);
3613
+ const accessibilityHint = terminalApp === "terminal" ? MESSAGES.TERMINAL_ACCESSIBILITY_HINT : "";
3614
+ throw new ClawtError(getCurrentLanguage() === "en" ? `Failed to open terminal tab: ${message}${accessibilityHint}` : `\u6253\u5F00\u7EC8\u7AEF Tab \u5931\u8D25: ${message}${accessibilityHint}`);
2298
3615
  }
2299
3616
  }
2300
3617
  function openCommandInNewTerminalTab(command, tabTitle) {
2301
3618
  if (process.platform !== "darwin") {
2302
- throw new ClawtError("\u6279\u91CF resume \u76EE\u524D\u4EC5\u652F\u6301 macOS \u5E73\u53F0");
3619
+ throw new ClawtError(MESSAGES.BATCH_RESUME_MACOS_ONLY);
2303
3620
  }
2304
3621
  const terminalApp = detectTerminalApp();
2305
3622
  switch (terminalApp) {
@@ -2315,7 +3632,7 @@ function openCommandInNewTerminalTab(command, tabTitle) {
2315
3632
  executeAppleScript(terminalScript, "terminal");
2316
3633
  break;
2317
3634
  default:
2318
- throw new ClawtError(`\u4E0D\u652F\u6301\u7684\u7EC8\u7AEF\u7C7B\u578B: ${terminalApp}`);
3635
+ throw new ClawtError(getCurrentLanguage() === "en" ? `Unsupported terminal type: ${terminalApp}` : `\u4E0D\u652F\u6301\u7684\u7EC8\u7AEF\u7C7B\u578B: ${terminalApp}`);
2319
3636
  }
2320
3637
  }
2321
3638
 
@@ -2343,12 +3660,12 @@ function launchInteractiveClaude(worktree, options = {}) {
2343
3660
  if (hasPreviousSession) {
2344
3661
  args.push("--continue");
2345
3662
  }
2346
- printInfo(`\u6B63\u5728 worktree \u4E2D\u542F\u52A8 Claude Code \u4EA4\u4E92\u5F0F\u754C\u9762...`);
2347
- printInfo(` \u5206\u652F: ${worktree.branch}`);
2348
- printInfo(` \u8DEF\u5F84: ${worktree.path}`);
2349
- printInfo(` \u6307\u4EE4: ${commandStr}`);
3663
+ printInfo(MESSAGES.STARTING_CLAUDE_INTERACTIVE);
3664
+ printInfo(` ${MESSAGES.BRANCH_LABEL} ${worktree.branch}`);
3665
+ printInfo(` ${MESSAGES.PATH_LABEL_RESUME} ${worktree.path}`);
3666
+ printInfo(` ${MESSAGES.COMMAND_LABEL} ${commandStr}`);
2350
3667
  if (options.autoContinue) {
2351
- printInfo(` \u6A21\u5F0F: ${hasPreviousSession ? "\u7EE7\u7EED\u4E0A\u6B21\u5BF9\u8BDD" : "\u65B0\u5BF9\u8BDD"}`);
3668
+ printInfo(` ${MESSAGES.MODE_LABEL} ${hasPreviousSession ? MESSAGES.CONTINUE_SESSION : MESSAGES.NEW_SESSION}`);
2352
3669
  }
2353
3670
  printInfo("");
2354
3671
  const result = spawnSync3(cmd, args, {
@@ -2356,10 +3673,10 @@ function launchInteractiveClaude(worktree, options = {}) {
2356
3673
  stdio: "inherit"
2357
3674
  });
2358
3675
  if (result.error) {
2359
- throw new ClawtError(`\u542F\u52A8 Claude Code \u5931\u8D25: ${result.error.message}`);
3676
+ throw new ClawtError(MESSAGES.CLAUDE_START_FAILED(result.error.message));
2360
3677
  }
2361
3678
  if (result.status !== null && result.status !== 0) {
2362
- printWarning(`Claude Code \u9000\u51FA\u7801: ${result.status}`);
3679
+ printWarning(getCurrentLanguage() === "en" ? `Claude Code exit code: ${result.status}` : `Claude Code \u9000\u51FA\u7801: ${result.status}`);
2363
3680
  }
2364
3681
  }
2365
3682
  function escapeShellSingleQuote(str) {
@@ -2373,7 +3690,7 @@ function buildClaudeCommand(worktree, hasPreviousSession) {
2373
3690
  }
2374
3691
  function launchInteractiveClaudeInNewTerminal(worktree, hasPreviousSession) {
2375
3692
  const command = buildClaudeCommand(worktree, hasPreviousSession);
2376
- const modeLabel = hasPreviousSession ? "\u7EE7\u7EED" : "\u65B0\u5BF9\u8BDD";
3693
+ const modeLabel = hasPreviousSession ? MESSAGES.CONTINUE_SESSION : MESSAGES.NEW_SESSION;
2377
3694
  const tabTitle = `clawt: ${worktree.branch}`;
2378
3695
  openCommandInNewTerminalTab(command, tabTitle);
2379
3696
  }
@@ -2471,7 +3788,7 @@ import { statSync as statSync3 } from "fs";
2471
3788
  import Enquirer3 from "enquirer";
2472
3789
  async function promptSelectBranch(worktrees, message) {
2473
3790
  if (isNonInteractive()) {
2474
- throw new ClawtError("\u975E\u4EA4\u4E92\u6A21\u5F0F\u4E0B\u65E0\u6CD5\u8FDB\u884C\u5206\u652F\u9009\u62E9\uFF0C\u8BF7\u901A\u8FC7 -b \u53C2\u6570\u7CBE\u786E\u6307\u5B9A\u5206\u652F\u540D");
3791
+ throw new ClawtError(getCurrentLanguage() === "en" ? "Non-interactive mode cannot select branch, please specify branch name via -b" : "\u975E\u4EA4\u4E92\u6A21\u5F0F\u4E0B\u65E0\u6CD5\u8FDB\u884C\u5206\u652F\u9009\u62E9\uFF0C\u8BF7\u901A\u8FC7 -b \u53C2\u6570\u7CBE\u786E\u6307\u5B9A\u5206\u652F\u540D");
2475
3792
  }
2476
3793
  const selectedBranch = await new Enquirer3.Select({
2477
3794
  message,
@@ -2484,7 +3801,7 @@ async function promptSelectBranch(worktrees, message) {
2484
3801
  }
2485
3802
  async function promptGroupedMultiSelectBranches(worktrees, message) {
2486
3803
  if (isNonInteractive()) {
2487
- throw new ClawtError("\u975E\u4EA4\u4E92\u6A21\u5F0F\u4E0B\u65E0\u6CD5\u8FDB\u884C\u5206\u652F\u591A\u9009\uFF0C\u8BF7\u901A\u8FC7 -b \u53C2\u6570\u7CBE\u786E\u6307\u5B9A\u5206\u652F\u540D");
3804
+ throw new ClawtError(getCurrentLanguage() === "en" ? "Non-interactive mode cannot multi-select branches, please specify branch name via -b" : "\u975E\u4EA4\u4E92\u6A21\u5F0F\u4E0B\u65E0\u6CD5\u8FDB\u884C\u5206\u652F\u591A\u9009\uFF0C\u8BF7\u901A\u8FC7 -b \u53C2\u6570\u7CBE\u786E\u6307\u5B9A\u5206\u652F\u540D");
2488
3805
  }
2489
3806
  const groups = groupWorktreesByDate(worktrees);
2490
3807
  const choices = buildGroupedChoices(groups);
@@ -2627,19 +3944,20 @@ function getWorktreeCreatedTime(dirPath) {
2627
3944
  }
2628
3945
  }
2629
3946
  function formatRelativeDate(dateStr) {
3947
+ const lang = getCurrentLanguage();
2630
3948
  const today = formatLocalDate(/* @__PURE__ */ new Date());
2631
3949
  const todayMs = new Date(today).getTime();
2632
3950
  const targetMs = new Date(dateStr).getTime();
2633
3951
  const diffDays = Math.round((todayMs - targetMs) / (1e3 * 60 * 60 * 24));
2634
- if (diffDays === 0) return "\u4ECA\u5929";
2635
- if (diffDays === 1) return "\u6628\u5929";
2636
- if (diffDays < 30) return `${diffDays} \u5929\u524D`;
3952
+ if (diffDays === 0) return lang === "en" ? "Today" : "\u4ECA\u5929";
3953
+ if (diffDays === 1) return lang === "en" ? "Yesterday" : "\u6628\u5929";
3954
+ if (diffDays < 30) return lang === "en" ? `${diffDays} day${diffDays > 1 ? "s" : ""} ago` : `${diffDays} \u5929\u524D`;
2637
3955
  if (diffDays < 365) {
2638
3956
  const months = Math.floor(diffDays / 30);
2639
- return `${months} \u4E2A\u6708\u524D`;
3957
+ return lang === "en" ? `${months} month${months > 1 ? "s" : ""} ago` : `${months} \u4E2A\u6708\u524D`;
2640
3958
  }
2641
3959
  const years = Math.floor(diffDays / 365);
2642
- return `${years} \u5E74\u524D`;
3960
+ return lang === "en" ? `${years} year${years > 1 ? "s" : ""} ago` : `${years} \u5E74\u524D`;
2643
3961
  }
2644
3962
  function groupWorktreesByDate(worktrees) {
2645
3963
  const groups = /* @__PURE__ */ new Map();
@@ -2720,25 +4038,26 @@ function getMaxPathWidth(tasks) {
2720
4038
  function renderTaskLine(task, total, maxPathWidth, spinnerChar) {
2721
4039
  const indexStr = `[${task.index}/${total}]`;
2722
4040
  const pathStr = task.path.padEnd(maxPathWidth);
4041
+ const labels = getTaskStatusLabels();
2723
4042
  switch (task.status) {
2724
4043
  case "pending": {
2725
- return `${indexStr} ${pathStr} ${chalk5.gray(TASK_STATUS_ICONS.PENDING)} ${chalk5.gray(TASK_STATUS_LABELS.PENDING)}`;
4044
+ return `${indexStr} ${pathStr} ${chalk5.gray(TASK_STATUS_ICONS.PENDING)} ${chalk5.gray(labels.PENDING)}`;
2726
4045
  }
2727
4046
  case "running": {
2728
4047
  const elapsed = formatDuration(Date.now() - task.startedAt);
2729
4048
  const detail = task.activity ? ` ${chalk5.dim(task.activity)}` : "";
2730
- return `${indexStr} ${pathStr} ${chalk5.cyan(spinnerChar)} ${chalk5.cyan(TASK_STATUS_LABELS.RUNNING)} ${chalk5.gray(elapsed)}${detail}`;
4049
+ return `${indexStr} ${pathStr} ${chalk5.cyan(spinnerChar)} ${chalk5.cyan(labels.RUNNING)} ${chalk5.gray(elapsed)}${detail}`;
2731
4050
  }
2732
4051
  case "done": {
2733
4052
  const duration = task.durationMs != null ? formatDuration(task.durationMs) : "N/A";
2734
4053
  const cost = task.costUsd != null ? `$${task.costUsd.toFixed(2)}` : "";
2735
4054
  const preview = task.resultPreview ? ` ${chalk5.dim(task.resultPreview)}` : "";
2736
- return `${indexStr} ${pathStr} ${chalk5.green(TASK_STATUS_ICONS.DONE)} ${chalk5.green(TASK_STATUS_LABELS.DONE)} ${chalk5.gray(duration)} ${chalk5.yellow(cost)}${preview}`;
4055
+ return `${indexStr} ${pathStr} ${chalk5.green(TASK_STATUS_ICONS.DONE)} ${chalk5.green(labels.DONE)} ${chalk5.gray(duration)} ${chalk5.yellow(cost)}${preview}`;
2737
4056
  }
2738
4057
  case "failed": {
2739
4058
  const duration = task.durationMs != null ? formatDuration(task.durationMs) : "N/A";
2740
4059
  const preview = task.resultPreview ? ` ${chalk5.dim(task.resultPreview)}` : "";
2741
- return `${indexStr} ${pathStr} ${chalk5.red(TASK_STATUS_ICONS.FAILED)} ${chalk5.red(TASK_STATUS_LABELS.FAILED)} ${chalk5.gray(duration)}${preview}`;
4060
+ return `${indexStr} ${pathStr} ${chalk5.red(TASK_STATUS_ICONS.FAILED)} ${chalk5.red(labels.FAILED)} ${chalk5.gray(duration)}${preview}`;
2742
4061
  }
2743
4062
  }
2744
4063
  }
@@ -2747,11 +4066,12 @@ function renderSummaryLine(tasks, total) {
2747
4066
  const done = tasks.filter((t) => t.status === "done").length;
2748
4067
  const failed = tasks.filter((t) => t.status === "failed").length;
2749
4068
  const pending = tasks.filter((t) => t.status === "pending").length;
4069
+ const labels = getTaskStatusLabels();
2750
4070
  const parts = [];
2751
- if (running > 0) parts.push(chalk5.cyan(`${running}/${total} ${TASK_STATUS_LABELS.RUNNING}`));
2752
- if (done > 0) parts.push(chalk5.green(`${done}/${total} ${TASK_STATUS_LABELS.DONE}`));
2753
- if (failed > 0) parts.push(chalk5.red(`${failed}/${total} ${TASK_STATUS_LABELS.FAILED}`));
2754
- if (pending > 0) parts.push(chalk5.gray(`${pending}/${total} ${TASK_STATUS_LABELS.PENDING}`));
4071
+ if (running > 0) parts.push(chalk5.cyan(`${running}/${total} ${labels.RUNNING}`));
4072
+ if (done > 0) parts.push(chalk5.green(`${done}/${total} ${labels.DONE}`));
4073
+ if (failed > 0) parts.push(chalk5.red(`${failed}/${total} ${labels.FAILED}`));
4074
+ if (pending > 0) parts.push(chalk5.gray(`${pending}/${total} ${labels.PENDING}`));
2755
4075
  return `[${parts.join(", ")}]`;
2756
4076
  }
2757
4077
 
@@ -2986,7 +4306,7 @@ import { resolve as resolve2 } from "path";
2986
4306
  import { existsSync as existsSync9, readFileSync as readFileSync4 } from "fs";
2987
4307
  var TASK_BLOCK_REGEX = /<!-- CLAWT-TASKS:START -->([\s\S]*?)<!-- CLAWT-TASKS:END -->/g;
2988
4308
  var BRANCH_LINE_REGEX = /^#\s*branch:\s*(.+)$/;
2989
- var EMPTY_TASKS_MESSAGE = "\u4EFB\u52A1\u5217\u8868\u4E0D\u80FD\u4E3A\u7A7A";
4309
+ var EMPTY_TASKS_MESSAGE = getCurrentLanguage() === "en" ? "Task list cannot be empty" : "\u4EFB\u52A1\u5217\u8868\u4E0D\u80FD\u4E3A\u7A7A";
2990
4310
  function parseTasksFromOptions(rawTasks) {
2991
4311
  const tasks = rawTasks.map((t) => t.trim()).filter(Boolean);
2992
4312
  if (tasks.length === 0) {
@@ -3203,7 +4523,7 @@ function executeClaudeTask(worktree, task, onActivity, continueSession) {
3203
4523
  worktreePath: worktree.path,
3204
4524
  success,
3205
4525
  result: finalResult,
3206
- error: success ? void 0 : stderr || "\u4EFB\u52A1\u6267\u884C\u5931\u8D25"
4526
+ error: success ? void 0 : stderr || MESSAGES.TASK_FAILED
3207
4527
  });
3208
4528
  });
3209
4529
  child.on("error", (err) => {
@@ -3221,11 +4541,11 @@ function executeClaudeTask(worktree, task, onActivity, continueSession) {
3221
4541
  }
3222
4542
  function printTaskSummary(summary) {
3223
4543
  printDoubleSeparator();
3224
- printInfo(`\u5168\u90E8\u4EFB\u52A1\u5DF2\u5B8C\u6210 (${summary.total}/${summary.total})`);
3225
- printInfo(` \u6210\u529F: ${summary.succeeded}`);
3226
- printInfo(` \u5931\u8D25: ${summary.failed}`);
3227
- printInfo(` \u603B\u8017\u65F6: ${(summary.totalDurationMs / 1e3).toFixed(1)}s`);
3228
- printInfo(` \u603B\u82B1\u8D39: $${summary.totalCostUsd.toFixed(2)}`);
4544
+ printInfo(MESSAGES.ALL_TASKS_COMPLETED(summary.total));
4545
+ printInfo(` ${MESSAGES.SUCCESS_LABEL} ${summary.succeeded}`);
4546
+ printInfo(` ${MESSAGES.FAILURE_LABEL} ${summary.failed}`);
4547
+ printInfo(` ${MESSAGES.TOTAL_DURATION_LABEL} ${(summary.totalDurationMs / 1e3).toFixed(1)}s`);
4548
+ printInfo(` ${MESSAGES.TOTAL_COST_LABEL} $${summary.totalCostUsd.toFixed(2)}`);
3229
4549
  printDoubleSeparator();
3230
4550
  }
3231
4551
  async function handleInterruptCleanup(worktrees) {
@@ -3323,7 +4643,7 @@ async function executeBatchTasks(worktrees, tasks, concurrency, continueFlags) {
3323
4643
  const count = tasks.length;
3324
4644
  if (continueFlags && continueFlags.length !== count) {
3325
4645
  throw new ClawtError(
3326
- `continueFlags \u957F\u5EA6 (${continueFlags.length}) \u4E0E\u4EFB\u52A1\u6570 (${count}) \u4E0D\u4E00\u81F4`
4646
+ getCurrentLanguage() === "en" ? `continueFlags length (${continueFlags.length}) does not match task count (${count})` : `continueFlags \u957F\u5EA6 (${continueFlags.length}) \u4E0E\u4EFB\u52A1\u6570 (${count}) \u4E0D\u4E00\u81F4`
3327
4647
  );
3328
4648
  }
3329
4649
  if (concurrency > 0) {
@@ -3414,9 +4734,9 @@ function printDryRunPreview(branchNames, tasks, concurrency) {
3414
4734
  } else {
3415
4735
  printInfo(`${chalk6.green("\u2713")} ${indexLabel} ${chalk6.cyan(branch)}`);
3416
4736
  }
3417
- printInfo(` ${chalk6.gray("\u8DEF\u5F84:")} ${worktreePath}`);
4737
+ printInfo(` ${chalk6.gray(MESSAGES.PATH_LABEL)} ${worktreePath}`);
3418
4738
  if (!isInteractive) {
3419
- printInfo(` ${chalk6.gray("\u4EFB\u52A1:")} ${truncateTaskDesc(tasks[i])}`);
4739
+ printInfo(` ${chalk6.gray(MESSAGES.TASK_LABEL)} ${truncateTaskDesc(tasks[i])}`);
3420
4740
  }
3421
4741
  printInfo("");
3422
4742
  }
@@ -3436,7 +4756,7 @@ function applyAliases(program2, aliases) {
3436
4756
  targetCmd.alias(alias);
3437
4757
  logger.debug(`\u5DF2\u6CE8\u518C\u522B\u540D: ${alias} \u2192 ${commandName}`);
3438
4758
  } else {
3439
- logger.warn(`\u522B\u540D "${alias}" \u7684\u76EE\u6807\u547D\u4EE4 "${commandName}" \u4E0D\u5B58\u5728\uFF0C\u5DF2\u8DF3\u8FC7`);
4759
+ logger.warn(getCurrentLanguage() === "en" ? `Alias "${alias}" targets non-existent command "${commandName}", skipped` : `\u522B\u540D "${alias}" \u7684\u76EE\u6807\u547D\u4EE4 "${commandName}" \u4E0D\u5B58\u5728\uFF0C\u5DF2\u8DF3\u8FC7`);
3440
4760
  }
3441
4761
  }
3442
4762
  }
@@ -3485,7 +4805,7 @@ async function promptConfigValue(key, currentValue, allowedValues) {
3485
4805
  }
3486
4806
  function formatConfigValue(value) {
3487
4807
  if (value === void 0 || value === null) {
3488
- return chalk7.dim("(\u672A\u8BBE\u7F6E)");
4808
+ return chalk7.dim(MESSAGES.NOT_SET);
3489
4809
  }
3490
4810
  if (typeof value === "boolean") {
3491
4811
  return value ? chalk7.green("true") : chalk7.yellow("false");
@@ -3494,7 +4814,7 @@ function formatConfigValue(value) {
3494
4814
  }
3495
4815
  async function interactiveConfigEditor(config2, definitions, options) {
3496
4816
  if (isNonInteractive()) {
3497
- throw new ClawtError("\u975E\u4EA4\u4E92\u6A21\u5F0F\u4E0B\u65E0\u6CD5\u4F7F\u7528\u4EA4\u4E92\u5F0F\u914D\u7F6E\u7F16\u8F91\u5668\uFF0C\u8BF7\u4F7F\u7528 clawt config set <key> <value>");
4817
+ throw new ClawtError(MESSAGES.NON_INTERACTIVE_CONFIG_EDITOR);
3498
4818
  }
3499
4819
  const keys = Object.keys(definitions);
3500
4820
  const disabledKeys = options?.disabledKeys ?? {};
@@ -3535,7 +4855,7 @@ async function promptNumberValue(key, currentValue) {
3535
4855
  message: MESSAGES.CONFIG_INPUT_PROMPT(key),
3536
4856
  initial: String(currentValue),
3537
4857
  validate: (val) => {
3538
- if (Number.isNaN(Number(val))) return "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u6570\u5B57";
4858
+ if (Number.isNaN(Number(val))) return MESSAGES.INVALID_NUMBER_PROMPT;
3539
4859
  return true;
3540
4860
  }
3541
4861
  }).run();
@@ -3703,7 +5023,7 @@ function buildSingleErrorClipboard(command, stderr, exitCode) {
3703
5023
  if (stderr.trim()) {
3704
5024
  return MESSAGES.VALIDATE_CLIPBOARD_SINGLE_ERROR(command, stderr.trim());
3705
5025
  }
3706
- return `${command} \u6307\u4EE4\u6267\u884C\u51FA\u9519\uFF0C\u9000\u51FA\u7801: ${exitCode}`;
5026
+ return MESSAGES.COMMAND_EXEC_ERROR(command, exitCode);
3707
5027
  }
3708
5028
  async function executeSingleCommand(command, mainWorktreePath) {
3709
5029
  printInfo(MESSAGES.VALIDATE_RUN_START(command));
@@ -3739,7 +5059,7 @@ function reportParallelResults(results) {
3739
5059
  printSuccess(MESSAGES.VALIDATE_PARALLEL_CMD_SUCCESS(result.command));
3740
5060
  } else {
3741
5061
  printError(MESSAGES.VALIDATE_PARALLEL_CMD_FAILED(result.command, result.exitCode));
3742
- const errorContent = result.stderr.trim() ? result.stderr.trim() : `\u9000\u51FA\u7801: ${result.exitCode}`;
5062
+ const errorContent = result.stderr.trim() ? result.stderr.trim() : MESSAGES.EXIT_CODE_LABEL(result.exitCode);
3743
5063
  errorClipboardParts.push(
3744
5064
  MESSAGES.VALIDATE_CLIPBOARD_PARALLEL_ERROR(result.command, errorContent)
3745
5065
  );
@@ -3831,7 +5151,7 @@ function loadOldSnapshotToStage(oldTreeHash, oldHeadCommitHash, currentHeadCommi
3831
5151
  const stagedTreeHash = gitWriteTree(mainWorktreePath);
3832
5152
  return { success: true, stagedTreeHash };
3833
5153
  } else if (oldChangePatch.length > 0) {
3834
- logger.warn("\u65E7\u53D8\u66F4 patch \u4E0E\u5F53\u524D HEAD \u51B2\u7A81\uFF0C\u964D\u7EA7\u4E3A\u5168\u91CF\u6A21\u5F0F");
5154
+ logger.warn(getCurrentLanguage() === "en" ? "Old changes patch conflicts with current HEAD, falling back to full mode" : "\u65E7\u53D8\u66F4 patch \u4E0E\u5F53\u524D HEAD \u51B2\u7A81\uFF0C\u964D\u7EA7\u4E3A\u5168\u91CF\u6A21\u5F0F");
3835
5155
  return { success: false, stagedTreeHash: "" };
3836
5156
  }
3837
5157
  return { success: true, stagedTreeHash: "" };
@@ -3951,7 +5271,8 @@ function renderDateSeparator(dateKey) {
3951
5271
  return `${leftPad}${chalk9.gray(PANEL_DATE_SEPARATOR_PREFIX)} ${chalk9.bold.hex(PANEL_DATE_COLOR)(PANEL_UNKNOWN_DATE)} ${chalk9.gray(PANEL_DATE_SEPARATOR_PREFIX)}`;
3952
5272
  }
3953
5273
  const relativeDate = formatRelativeDate(dateKey);
3954
- return `${leftPad}${chalk9.gray(PANEL_DATE_SEPARATOR_PREFIX)} ${chalk9.bold.hex(PANEL_DATE_COLOR)(dateKey)}${chalk9.hex(PANEL_DATE_COLOR)(`\uFF08${relativeDate}\uFF09`)} ${chalk9.gray(PANEL_DATE_SEPARATOR_PREFIX)}`;
5274
+ const relativeDateText = getCurrentLanguage() === "en" ? `(${relativeDate})` : `\uFF08${relativeDate}\uFF09`;
5275
+ return `${leftPad}${chalk9.gray(PANEL_DATE_SEPARATOR_PREFIX)} ${chalk9.bold.hex(PANEL_DATE_COLOR)(dateKey)}${chalk9.hex(PANEL_DATE_COLOR)(relativeDateText)} ${chalk9.gray(PANEL_DATE_SEPARATOR_PREFIX)}`;
3955
5276
  }
3956
5277
  function renderWorktreeBlock(wt, isSelected) {
3957
5278
  const lines = [];
@@ -4013,12 +5334,13 @@ function renderConfiguredBranchLine(main2) {
4013
5334
  return PANEL_CONFIGURED_BRANCH(main2.configuredMainBranch);
4014
5335
  }
4015
5336
  function renderMainBranchDiff(main2) {
5337
+ const workingDirLabel = getCurrentLanguage() === "en" ? "Working dir:" : "\u5DE5\u4F5C\u533A:";
4016
5338
  if (main2.insertions === 0 && main2.deletions === 0) {
4017
- return `\u5DE5\u4F5C\u533A: ${chalk9.green(MESSAGES.STATUS_CHANGE_CLEAN)}`;
5339
+ return `${workingDirLabel} ${chalk9.green(MESSAGES.STATUS_CHANGE_CLEAN)}`;
4018
5340
  }
4019
5341
  const insertText = chalk9.green(`+${main2.insertions}`);
4020
5342
  const deleteText = chalk9.red(`-${main2.deletions}`);
4021
- return `\u5DE5\u4F5C\u533A: ${insertText} ${deleteText}`;
5343
+ return `${workingDirLabel} ${insertText} ${deleteText}`;
4022
5344
  }
4023
5345
  function renderFooter(countdown) {
4024
5346
  return `${PANEL_FOOTER_SHORTCUTS} ${PANEL_FOOTER_COUNTDOWN(countdown)}`;
@@ -4689,7 +6011,7 @@ function resolvePostCreateHook() {
4689
6011
  return null;
4690
6012
  }
4691
6013
  function getSourceLabel(hook) {
4692
- return hook.source === "projectConfig" ? "\u9879\u76EE\u914D\u7F6E (postCreate)" : ".clawt/postCreate.sh";
6014
+ return hook.source === "projectConfig" ? getCurrentLanguage() === "en" ? "Project config (postCreate)" : "\u9879\u76EE\u914D\u7F6E (postCreate)" : ".clawt/postCreate.sh";
4693
6015
  }
4694
6016
  function executeOneHook(worktree, hook) {
4695
6017
  return new Promise((resolve5) => {
@@ -4714,7 +6036,7 @@ function executeOneHook(worktree, hook) {
4714
6036
  child.on("close", (code) => {
4715
6037
  if (code !== null && code !== 0) {
4716
6038
  result.success = false;
4717
- result.error = `\u547D\u4EE4\u9000\u51FA\u7801: ${code}`;
6039
+ result.error = getCurrentLanguage() === "en" ? `Command exit code: ${code}` : `\u547D\u4EE4\u9000\u51FA\u7801: ${code}`;
4718
6040
  logger.error(`postCreate hook \u5931\u8D25: ${hook.command} (\u9000\u51FA\u7801: ${code}) @ ${worktree.path}`);
4719
6041
  } else {
4720
6042
  logger.info(`postCreate hook \u6210\u529F: ${hook.command} @ ${worktree.path}`);
@@ -4758,7 +6080,7 @@ function runPostCreateHooks(worktrees, skip) {
4758
6080
  // src/commands/list.ts
4759
6081
  import chalk10 from "chalk";
4760
6082
  function registerListCommand(program2) {
4761
- program2.command("list").description("\u5217\u51FA\u5F53\u524D\u9879\u76EE\u6240\u6709 worktree\uFF08\u652F\u6301 --json \u683C\u5F0F\u8F93\u51FA\uFF09").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").action(async (options) => {
6083
+ program2.command("list").description(getCurrentLanguage() === "en" ? "List all worktrees for the current project (supports --json output)" : "\u5217\u51FA\u5F53\u524D\u9879\u76EE\u6240\u6709 worktree\uFF08\u652F\u6301 --json \u683C\u5F0F\u8F93\u51FA\uFF09").option("--json", getCurrentLanguage() === "en" ? "Output in JSON format" : "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").action(async (options) => {
4762
6084
  await handleList(options);
4763
6085
  });
4764
6086
  }
@@ -4785,7 +6107,8 @@ function printListAsJson(projectName, worktrees) {
4785
6107
  console.log(JSON.stringify(result, null, 2));
4786
6108
  }
4787
6109
  function printListAsText(projectName, worktrees) {
4788
- printInfo(`\u5F53\u524D\u9879\u76EE: ${projectName}
6110
+ const lang = getCurrentLanguage();
6111
+ printInfo(`${lang === "en" ? "Current project" : "\u5F53\u524D\u9879\u76EE"}: ${projectName}
4789
6112
  `);
4790
6113
  if (worktrees.length === 0) {
4791
6114
  printInfo(` ${MESSAGES.NO_WORKTREES}`);
@@ -4802,13 +6125,13 @@ function printListAsText(projectName, worktrees) {
4802
6125
  }
4803
6126
  printInfo("");
4804
6127
  }
4805
- printInfo(`\u5171 ${worktrees.length} \u4E2A worktree`);
6128
+ printInfo(`${worktrees.length} ${lang === "en" ? "worktree(s)" : "\u4E2A worktree"}`);
4806
6129
  }
4807
6130
  }
4808
6131
 
4809
6132
  // src/commands/create.ts
4810
6133
  function registerCreateCommand(program2) {
4811
- program2.command("create").description("\u6279\u91CF\u521B\u5EFA worktree \u53CA\u5BF9\u5E94\u5206\u652F\uFF08\u542B\u9A8C\u8BC1\u5206\u652F\uFF09").requiredOption("-b, --branch <branchName>", "\u5206\u652F\u540D").option("-n, --number <count>", "\u521B\u5EFA\u6570\u91CF", "1").option("--post-create", "\u6267\u884C postCreate hook\uFF08\u9ED8\u8BA4\u5F00\u542F\uFF0C--no-post-create \u8DF3\u8FC7\uFF09", true).action(async (options) => {
6134
+ program2.command("create").description(getCurrentLanguage() === "en" ? "Batch create worktrees and corresponding branches (including validation branches)" : "\u6279\u91CF\u521B\u5EFA worktree \u53CA\u5BF9\u5E94\u5206\u652F\uFF08\u542B\u9A8C\u8BC1\u5206\u652F\uFF09").requiredOption("-b, --branch <branchName>", getCurrentLanguage() === "en" ? "Branch name" : "\u5206\u652F\u540D").option("-n, --number <count>", getCurrentLanguage() === "en" ? "Number of worktrees to create" : "\u521B\u5EFA\u6570\u91CF", "1").option("--post-create", getCurrentLanguage() === "en" ? "Execute postCreate hook (enabled by default, use --no-post-create to skip)" : "\u6267\u884C postCreate hook\uFF08\u9ED8\u8BA4\u5F00\u542F\uFF0C--no-post-create \u8DF3\u8FC7\uFF09", true).action(async (options) => {
4812
6135
  await handleCreate(options);
4813
6136
  });
4814
6137
  }
@@ -4827,10 +6150,10 @@ async function handleCreate(options) {
4827
6150
  printSuccess(MESSAGES.WORKTREE_CREATED(worktrees.length));
4828
6151
  printInfo("");
4829
6152
  worktrees.forEach((wt, index) => {
4830
- printInfo(`\u76EE\u5F55\u8DEF\u5F84${index + 1}\uFF1A`);
6153
+ printInfo(getCurrentLanguage() === "en" ? `Directory path ${index + 1}:` : `\u76EE\u5F55\u8DEF\u5F84${index + 1}\uFF1A`);
4831
6154
  printInfo(` ${wt.path}`);
4832
- printInfo(` \u5206\u652F\u540D: ${wt.branch}`);
4833
- printInfo(` \u9A8C\u8BC1\u5206\u652F: ${getValidateBranchName(wt.branch)}`);
6155
+ printInfo(getCurrentLanguage() === "en" ? ` Branch: ${wt.branch}` : ` \u5206\u652F\u540D: ${wt.branch}`);
6156
+ printInfo(getCurrentLanguage() === "en" ? ` Validation branch: ${getValidateBranchName(wt.branch)}` : ` \u9A8C\u8BC1\u5206\u652F: ${getValidateBranchName(wt.branch)}`);
4834
6157
  printSeparator();
4835
6158
  });
4836
6159
  }
@@ -4843,7 +6166,7 @@ var REMOVE_RESOLVE_MESSAGES = {
4843
6166
  noMatch: MESSAGES.REMOVE_NO_MATCH
4844
6167
  };
4845
6168
  function registerRemoveCommand(program2) {
4846
- program2.command("remove").description("\u79FB\u9664 worktree\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D/\u591A\u9009/\u5168\u90E8\uFF09").option("--all", "\u79FB\u9664\u5F53\u524D\u9879\u76EE\u4E0B\u6240\u6709 worktree").option("-b, --branch <branchName>", "\u6307\u5B9A\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\uFF09").action(async (options) => {
6169
+ program2.command("remove").description(getCurrentLanguage() === "en" ? "Remove worktrees (supports fuzzy match / multi-select / all)" : "\u79FB\u9664 worktree\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D/\u591A\u9009/\u5168\u90E8\uFF09").option("--all", getCurrentLanguage() === "en" ? "Remove all worktrees in the current project" : "\u79FB\u9664\u5F53\u524D\u9879\u76EE\u4E0B\u6240\u6709 worktree").option("-b, --branch <branchName>", getCurrentLanguage() === "en" ? "Specify branch name (supports fuzzy match, lists all branches if not provided)" : "\u6307\u5B9A\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\uFF09").action(async (options) => {
4847
6170
  await handleRemove(options);
4848
6171
  });
4849
6172
  }
@@ -4872,9 +6195,9 @@ async function handleRemove(options) {
4872
6195
  throw new ClawtError(MESSAGES.REMOVE_VALIDATE_BRANCH_IS_CURRENT(wt.branch, validateBranch));
4873
6196
  }
4874
6197
  }
4875
- printInfo("\u5373\u5C06\u79FB\u9664\u4EE5\u4E0B worktree \u53CA\u672C\u5730\u5206\u652F\uFF1A\n");
6198
+ printInfo(getCurrentLanguage() === "en" ? "The following worktrees and local branches will be removed:\n" : "\u5373\u5C06\u79FB\u9664\u4EE5\u4E0B worktree \u53CA\u672C\u5730\u5206\u652F\uFF1A\n");
4876
6199
  worktreesToRemove.forEach((wt, index) => {
4877
- printInfo(` ${index + 1}. ${wt.path} \u2192 \u5206\u652F: ${wt.branch} \u9A8C\u8BC1\u5206\u652F: ${getValidateBranchName(wt.branch)}`);
6200
+ printInfo(getCurrentLanguage() === "en" ? ` ${index + 1}. ${wt.path} \u2192 branch: ${wt.branch} validate branch: ${getValidateBranchName(wt.branch)}` : ` ${index + 1}. ${wt.path} \u2192 \u5206\u652F: ${wt.branch} \u9A8C\u8BC1\u5206\u652F: ${getValidateBranchName(wt.branch)}`);
4878
6201
  });
4879
6202
  printInfo("");
4880
6203
  const autoDelete = getConfigValue("autoDeleteBranch");
@@ -4910,14 +6233,14 @@ async function handleRemove(options) {
4910
6233
  if (failures.length > 0) {
4911
6234
  printError(MESSAGES.REMOVE_PARTIAL_FAILURE(failures));
4912
6235
  throw new ClawtError(
4913
- `${failures.length} \u4E2A worktree \u79FB\u9664\u5931\u8D25`
6236
+ getCurrentLanguage() === "en" ? `${failures.length} worktree removal(s) failed` : `${failures.length} \u4E2A worktree \u79FB\u9664\u5931\u8D25`
4914
6237
  );
4915
6238
  }
4916
6239
  }
4917
6240
 
4918
6241
  // src/commands/run.ts
4919
6242
  function registerRunCommand(program2) {
4920
- program2.command("run").description("\u6279\u91CF\u521B\u5EFA worktree + \u542F\u52A8 Claude Code \u6267\u884C\u4EFB\u52A1\uFF08\u652F\u6301\u4EFB\u52A1\u6587\u4EF6\uFF09").option("-b, --branch <branchName>", "\u5206\u652F\u540D").option("--tasks <task...>", "\u4EFB\u52A1\u5217\u8868\uFF08\u53EF\u591A\u6B21\u6307\u5B9A\uFF09\uFF0C\u4E0D\u4F20\u5219\u5728 worktree \u4E2D\u6253\u5F00 Claude Code \u4EA4\u4E92\u5F0F\u754C\u9762").option("-c, --concurrency <n>", "\u6700\u5927\u5E76\u53D1\u6570\uFF0C0 \u8868\u793A\u4E0D\u9650\u5236").option("-f, --file <path>", "\u4ECE\u4EFB\u52A1\u6587\u4EF6\u8BFB\u53D6\u4EFB\u52A1\u5217\u8868\uFF08\u4E0E --tasks \u4E92\u65A5\uFF09").option("--dry-run", "\u9884\u89C8\u6A21\u5F0F\uFF0C\u4EC5\u5C55\u793A\u4EFB\u52A1\u8BA1\u5212\u4E0D\u5B9E\u9645\u6267\u884C").option("--post-create", "\u6267\u884C postCreate hook\uFF08\u9ED8\u8BA4\u5F00\u542F\uFF0C--no-post-create \u8DF3\u8FC7\uFF09", true).action(async (options) => {
6243
+ program2.command("run").description(getCurrentLanguage() === "en" ? "Batch create worktrees + launch Claude Code to execute tasks (supports task files)" : "\u6279\u91CF\u521B\u5EFA worktree + \u542F\u52A8 Claude Code \u6267\u884C\u4EFB\u52A1\uFF08\u652F\u6301\u4EFB\u52A1\u6587\u4EF6\uFF09").option("-b, --branch <branchName>", getCurrentLanguage() === "en" ? "Branch name" : "\u5206\u652F\u540D").option("--tasks <task...>", getCurrentLanguage() === "en" ? "Task list (can be specified multiple times); opens Claude Code interactive UI in worktree if omitted" : "\u4EFB\u52A1\u5217\u8868\uFF08\u53EF\u591A\u6B21\u6307\u5B9A\uFF09\uFF0C\u4E0D\u4F20\u5219\u5728 worktree \u4E2D\u6253\u5F00 Claude Code \u4EA4\u4E92\u5F0F\u754C\u9762").option("-c, --concurrency <n>", getCurrentLanguage() === "en" ? "Max concurrency, 0 means unlimited" : "\u6700\u5927\u5E76\u53D1\u6570\uFF0C0 \u8868\u793A\u4E0D\u9650\u5236").option("-f, --file <path>", getCurrentLanguage() === "en" ? "Read task list from file (mutually exclusive with --tasks)" : "\u4ECE\u4EFB\u52A1\u6587\u4EF6\u8BFB\u53D6\u4EFB\u52A1\u5217\u8868\uFF08\u4E0E --tasks \u4E92\u65A5\uFF09").option("--dry-run", getCurrentLanguage() === "en" ? "Preview mode, show task plan without executing" : "\u9884\u89C8\u6A21\u5F0F\uFF0C\u4EC5\u5C55\u793A\u4EFB\u52A1\u8BA1\u5212\u4E0D\u5B9E\u9645\u6267\u884C").option("--post-create", getCurrentLanguage() === "en" ? "Execute postCreate hook (enabled by default, use --no-post-create to skip)" : "\u6267\u884C postCreate hook\uFF08\u9ED8\u8BA4\u5F00\u542F\uFF0C--no-post-create \u8DF3\u8FC7\uFF09", true).action(async (options) => {
4921
6244
  await handleRun(options);
4922
6245
  });
4923
6246
  }
@@ -5014,7 +6337,7 @@ var RESUME_RESOLVE_MESSAGES = {
5014
6337
  noMatch: MESSAGES.RESUME_NO_MATCH
5015
6338
  };
5016
6339
  function registerResumeCommand(program2) {
5017
- program2.command("resume").description("\u5728\u5DF2\u6709 worktree \u4E2D\u6062\u590D Claude Code \u4F1A\u8BDD\uFF08\u652F\u6301\u591A\u9009\u6279\u91CF\u6062\u590D\uFF09").option("-b, --branch <branchName>", "\u8981\u6062\u590D\u7684\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\uFF09").option("--prompt <content>", "\u975E\u4EA4\u4E92\u5F0F\u8FFD\u95EE\uFF08\u9700\u914D\u5408 -b \u6307\u5B9A\u5206\u652F\uFF09").option("-f, --file <path>", "\u4ECE\u4EFB\u52A1\u6587\u4EF6\u6279\u91CF\u8FFD\u95EE\uFF08\u901A\u8FC7 branch \u540D\u5339\u914D\u5DF2\u6709 worktree\uFF09").option("-c, --concurrency <n>", "\u6279\u91CF\u8FFD\u95EE\u6700\u5927\u5E76\u53D1\u6570\uFF0C0 \u8868\u793A\u4E0D\u9650\u5236").action(async (options) => {
6340
+ program2.command("resume").description(getCurrentLanguage() === "en" ? "Resume Claude Code sessions in existing worktrees (supports multi-select batch resume)" : "\u5728\u5DF2\u6709 worktree \u4E2D\u6062\u590D Claude Code \u4F1A\u8BDD\uFF08\u652F\u6301\u591A\u9009\u6279\u91CF\u6062\u590D\uFF09").option("-b, --branch <branchName>", getCurrentLanguage() === "en" ? "Branch name to resume (supports fuzzy match, lists all branches if not provided)" : "\u8981\u6062\u590D\u7684\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\uFF09").option("--prompt <content>", getCurrentLanguage() === "en" ? "Non-interactive follow-up prompt (requires -b to specify branch)" : "\u975E\u4EA4\u4E92\u5F0F\u8FFD\u95EE\uFF08\u9700\u914D\u5408 -b \u6307\u5B9A\u5206\u652F\uFF09").option("-f, --file <path>", getCurrentLanguage() === "en" ? "Batch follow-up from task file (matches existing worktrees by branch name)" : "\u4ECE\u4EFB\u52A1\u6587\u4EF6\u6279\u91CF\u8FFD\u95EE\uFF08\u901A\u8FC7 branch \u540D\u5339\u914D\u5DF2\u6709 worktree\uFF09").option("-c, --concurrency <n>", getCurrentLanguage() === "en" ? "Max concurrency for batch follow-ups, 0 means unlimited" : "\u6279\u91CF\u8FFD\u95EE\u6700\u5927\u5E76\u53D1\u6570\uFF0C0 \u8868\u793A\u4E0D\u9650\u5236").action(async (options) => {
5018
6341
  await handleResume(options);
5019
6342
  });
5020
6343
  }
@@ -5087,9 +6410,9 @@ async function handleNonInteractiveBatchResume(filePath, options) {
5087
6410
  await executeBatchTasks(worktrees, tasks, concurrency, continueFlags);
5088
6411
  }
5089
6412
  function printBatchResumePreview(worktrees, sessionMap) {
5090
- printInfo("\u5373\u5C06\u6062\u590D\u7684\u5206\u652F\uFF1A");
6413
+ printInfo(getCurrentLanguage() === "en" ? "Branches to resume:" : "\u5373\u5C06\u6062\u590D\u7684\u5206\u652F\uFF1A");
5091
6414
  for (const wt of worktrees) {
5092
- const modeLabel = sessionMap.get(wt.path) ? "\u7EE7\u7EED\u4E0A\u6B21\u5BF9\u8BDD" : "\u65B0\u5BF9\u8BDD";
6415
+ const modeLabel = sessionMap.get(wt.path) ? getCurrentLanguage() === "en" ? "continue" : "\u7EE7\u7EED\u4E0A\u6B21\u5BF9\u8BDD" : getCurrentLanguage() === "en" ? "new session" : "\u65B0\u5BF9\u8BDD";
5093
6416
  printInfo(` - ${wt.branch} (${modeLabel})`);
5094
6417
  }
5095
6418
  printInfo("");
@@ -5116,7 +6439,7 @@ async function handleBatchResume(worktrees) {
5116
6439
 
5117
6440
  // src/commands/sync.ts
5118
6441
  function registerSyncCommand(program2) {
5119
- program2.command("sync").description("\u5C06\u4E3B\u5206\u652F\u6700\u65B0\u4EE3\u7801\u540C\u6B65\u5230\u76EE\u6807 worktree").option("-b, --branch <branchName>", "\u8981\u540C\u6B65\u7684\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\uFF09").action(async (options) => {
6442
+ program2.command("sync").description(getCurrentLanguage() === "en" ? "Sync the latest code from the main branch to the target worktree" : "\u5C06\u4E3B\u5206\u652F\u6700\u65B0\u4EE3\u7801\u540C\u6B65\u5230\u76EE\u6807 worktree").option("-b, --branch <branchName>", getCurrentLanguage() === "en" ? "Branch name to sync (supports fuzzy match, lists all branches if not provided)" : "\u8981\u540C\u6B65\u7684\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\uFF09").action(async (options) => {
5120
6443
  await handleSync(options);
5121
6444
  });
5122
6445
  }
@@ -5140,7 +6463,7 @@ function mergeMainBranch(worktreePath, mainBranch) {
5140
6463
  if (hasMergeConflict(worktreePath)) {
5141
6464
  return true;
5142
6465
  }
5143
- throw new ClawtError(`\u5408\u5E76 ${mainBranch} \u5931\u8D25`);
6466
+ throw new ClawtError(getCurrentLanguage() === "en" ? `Merge of ${mainBranch} failed` : `\u5408\u5E76 ${mainBranch} \u5931\u8D25`);
5144
6467
  }
5145
6468
  }
5146
6469
  async function executeSyncForBranch(targetWorktreePath, branch) {
@@ -5178,7 +6501,7 @@ var VALIDATE_RESOLVE_MESSAGES = {
5178
6501
  noMatch: MESSAGES.VALIDATE_NO_MATCH
5179
6502
  };
5180
6503
  function registerValidateCommand(program2) {
5181
- program2.command("validate").description("\u5728\u4E3B worktree \u9A8C\u8BC1\u67D0\u4E2A worktree \u5206\u652F\u7684\u53D8\u66F4\uFF08\u901A\u8FC7\u9A8C\u8BC1\u5206\u652F\uFF09").option("-b, --branch <branchName>", "\u8981\u9A8C\u8BC1\u7684\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\uFF09").option("--clean", "\u6E05\u7406 validate \u72B6\u6001\uFF08\u91CD\u7F6E\u4E3B worktree \u5E76\u5220\u9664\u5FEB\u7167\uFF09").option("-r, --run <command>", "validate \u6210\u529F\u540E\u5728\u4E3B worktree \u4E2D\u6267\u884C\u7684\u547D\u4EE4").action(async (options) => {
6504
+ program2.command("validate").description(getCurrentLanguage() === "en" ? "Validate a worktree branch's changes in the main worktree (via validation branch)" : "\u5728\u4E3B worktree \u9A8C\u8BC1\u67D0\u4E2A worktree \u5206\u652F\u7684\u53D8\u66F4\uFF08\u901A\u8FC7\u9A8C\u8BC1\u5206\u652F\uFF09").option("-b, --branch <branchName>", getCurrentLanguage() === "en" ? "Branch name to validate (supports fuzzy match, lists all branches if not provided)" : "\u8981\u9A8C\u8BC1\u7684\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\uFF09").option("--clean", getCurrentLanguage() === "en" ? "Clean validate state (reset main worktree and delete snapshot)" : "\u6E05\u7406 validate \u72B6\u6001\uFF08\u91CD\u7F6E\u4E3B worktree \u5E76\u5220\u9664\u5FEB\u7167\uFF09").option("-r, --run <command>", getCurrentLanguage() === "en" ? "Command to execute in the main worktree after successful validation" : "validate \u6210\u529F\u540E\u5728\u4E3B worktree \u4E2D\u6267\u884C\u7684\u547D\u4EE4").action(async (options) => {
5182
6505
  await handleValidate(options);
5183
6506
  });
5184
6507
  }
@@ -5205,7 +6528,7 @@ async function handleValidateClean(options) {
5205
6528
  if (getConfigValue("confirmDestructiveOps")) {
5206
6529
  const confirmed = await confirmDestructiveAction(
5207
6530
  "git reset --hard + git clean -fd",
5208
- `\u91CD\u7F6E\u4E3B worktree \u5E76\u5220\u9664\u5206\u652F ${branchName} \u7684 validate \u5FEB\u7167`
6531
+ getCurrentLanguage() === "en" ? `Reset main worktree and delete validate snapshot for branch ${branchName}` : `\u91CD\u7F6E\u4E3B worktree \u5E76\u5220\u9664\u5206\u652F ${branchName} \u7684 validate \u5FEB\u7167`
5209
6532
  );
5210
6533
  if (!confirmed) {
5211
6534
  printInfo(MESSAGES.DESTRUCTIVE_OP_CANCELLED);
@@ -5252,7 +6575,7 @@ async function handleIncrementalValidate(targetWorktreePath, mainWorktreePath, p
5252
6575
  try {
5253
6576
  gitReadTree(oldStagedTreeHash, mainWorktreePath);
5254
6577
  } catch (error) {
5255
- logger.warn(`\u6062\u590D\u6682\u5B58\u533A\u5931\u8D25: ${error}`);
6578
+ logger.warn(getCurrentLanguage() === "en" ? `Failed to restore staging area: ${error}` : `\u6062\u590D\u6682\u5B58\u533A\u5931\u8D25: ${error}`);
5256
6579
  }
5257
6580
  }
5258
6581
  printInfo(MESSAGES.INCREMENTAL_VALIDATE_NO_CHANGES(branchName));
@@ -5318,7 +6641,7 @@ async function handleValidate(options) {
5318
6641
 
5319
6642
  // src/commands/cover-validate.ts
5320
6643
  function registerCoverValidateCommand(program2) {
5321
- program2.command("cover").description("\u5C06\u9A8C\u8BC1\u5206\u652F\u4E0A\u7684\u4FEE\u6539\u8986\u76D6\u56DE\u76EE\u6807 worktree\uFF08\u81EA\u52A8\u63A8\u5BFC\u76EE\u6807\u5206\u652F\uFF09").action(async () => {
6644
+ program2.command("cover").description(getCurrentLanguage() === "en" ? "Overwrite changes from the validation branch back to the target worktree (auto-detect target branch)" : "\u5C06\u9A8C\u8BC1\u5206\u652F\u4E0A\u7684\u4FEE\u6539\u8986\u76D6\u56DE\u76EE\u6807 worktree\uFF08\u81EA\u52A8\u63A8\u5BFC\u76EE\u6807\u5206\u652F\uFF09").action(async () => {
5322
6645
  await handleCoverValidate();
5323
6646
  });
5324
6647
  }
@@ -5361,7 +6684,7 @@ async function handleCoverValidate() {
5361
6684
  const { treeHash: snapshotTreeHash } = readSnapshot(projectName, targetBranchName);
5362
6685
  if (isWorkingDirClean(mainWorktreePath)) {
5363
6686
  printInfo(MESSAGES.COVER_VALIDATE_WORKING_DIR_CLEAN);
5364
- const confirmed = await confirmAction("\u662F\u5426\u7EE7\u7EED\u6267\u884C\u8986\u76D6\uFF1F");
6687
+ const confirmed = await confirmAction(getCurrentLanguage() === "en" ? "Proceed with cover?" : "\u662F\u5426\u7EE7\u7EED\u6267\u884C\u8986\u76D6\uFF1F");
5365
6688
  if (!confirmed) return;
5366
6689
  }
5367
6690
  const currentTreeHash = computeWorktreeTreeHash(mainWorktreePath);
@@ -5383,7 +6706,7 @@ async function handleCoverValidate() {
5383
6706
 
5384
6707
  // src/commands/merge.ts
5385
6708
  function registerMergeCommand(program2) {
5386
- program2.command("merge").description("\u5408\u5E76\u67D0\u4E2A\u5DF2\u9A8C\u8BC1\u7684 worktree \u5206\u652F\u5230\u4E3B worktree").option("-b, --branch <branchName>", "\u8981\u5408\u5E76\u7684\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\u4F9B\u9009\u62E9\uFF09").option("-m, --message <commitMessage>", "\u63D0\u4EA4\u4FE1\u606F\uFF08\u76EE\u6807 worktree \u5DE5\u4F5C\u533A\u6709\u4FEE\u6539\u65F6\u5FC5\u586B\uFF09").option("--auto", "\u9047\u5230\u51B2\u7A81\u76F4\u63A5\u8C03\u7528 AI \u89E3\u51B3\uFF0C\u4E0D\u518D\u8BE2\u95EE").action(async (options) => {
6709
+ program2.command("merge").description(getCurrentLanguage() === "en" ? "Merge a validated worktree branch into the main worktree" : "\u5408\u5E76\u67D0\u4E2A\u5DF2\u9A8C\u8BC1\u7684 worktree \u5206\u652F\u5230\u4E3B worktree").option("-b, --branch <branchName>", getCurrentLanguage() === "en" ? "Branch name to merge (supports fuzzy match, lists all branches if not provided)" : "\u8981\u5408\u5E76\u7684\u5206\u652F\u540D\uFF08\u652F\u6301\u6A21\u7CCA\u5339\u914D\uFF0C\u4E0D\u4F20\u5219\u5217\u51FA\u6240\u6709\u5206\u652F\u4F9B\u9009\u62E9\uFF09").option("-m, --message <commitMessage>", getCurrentLanguage() === "en" ? "Commit message (required when target worktree has uncommitted changes)" : "\u63D0\u4EA4\u4FE1\u606F\uFF08\u76EE\u6807 worktree \u5DE5\u4F5C\u533A\u6709\u4FEE\u6539\u65F6\u5FC5\u586B\uFF09").option("--auto", getCurrentLanguage() === "en" ? "Resolve conflicts with AI automatically without prompting" : "\u9047\u5230\u51B2\u7A81\u76F4\u63A5\u8C03\u7528 AI \u89E3\u51B3\uFF0C\u4E0D\u518D\u8BE2\u95EE").action(async (options) => {
5387
6710
  await handleMerge(options);
5388
6711
  });
5389
6712
  }
@@ -5428,10 +6751,10 @@ async function handleSquashIfNeeded(targetWorktreePath, mainWorktreePath, branch
5428
6751
  async function shouldCleanupAfterMerge(branchName) {
5429
6752
  const autoDelete = getConfigValue("autoDeleteBranch");
5430
6753
  if (autoDelete) {
5431
- printInfo(`\u5DF2\u914D\u7F6E\u81EA\u52A8\u5220\u9664\uFF0Cmerge \u6210\u529F\u540E\u5C06\u81EA\u52A8\u6E05\u7406 worktree \u548C\u5206\u652F: ${branchName}`);
6754
+ printInfo(MESSAGES.AUTO_DELETE_CONFIGURED(branchName));
5432
6755
  return true;
5433
6756
  }
5434
- return confirmAction(`\u662F\u5426\u5220\u9664\u5BF9\u5E94\u7684 worktree \u548C\u5206\u652F (${branchName})\uFF1F`, true);
6757
+ return confirmAction(MESSAGES.CONFIRM_DELETE_WORKTREE_BRANCH(branchName), true);
5435
6758
  }
5436
6759
  function cleanupWorktreeAndBranch(worktreePath, branchName) {
5437
6760
  cleanupWorktrees([{ path: worktreePath, branch: branchName }]);
@@ -5506,7 +6829,7 @@ async function handleMerge(options) {
5506
6829
  return;
5507
6830
  }
5508
6831
  } else {
5509
- printInfo("\u5DF2\u8DF3\u8FC7\u81EA\u52A8 pull/push\uFF0C\u8BF7\u624B\u52A8\u6267\u884C git pull && git push");
6832
+ printInfo(getCurrentLanguage() === "en" ? "Auto pull/push skipped, please run git pull && git push manually" : "\u5DF2\u8DF3\u8FC7\u81EA\u52A8 pull/push\uFF0C\u8BF7\u624B\u52A8\u6267\u884C git pull && git push");
5510
6833
  }
5511
6834
  if (options.message) {
5512
6835
  printSuccess(MESSAGES.MERGE_SUCCESS(branch, options.message, autoPullPush));
@@ -5524,16 +6847,16 @@ async function handleMerge(options) {
5524
6847
 
5525
6848
  // src/commands/config.ts
5526
6849
  function registerConfigCommand(program2) {
5527
- const configCmd = program2.command("config").description("\u4EA4\u4E92\u5F0F\u67E5\u770B\u548C\u4FEE\u6539\u5168\u5C40\u914D\u7F6E").action(async () => {
6850
+ const configCmd = program2.command("config").description(getCurrentLanguage() === "en" ? "Interactively view and modify global configuration" : "\u4EA4\u4E92\u5F0F\u67E5\u770B\u548C\u4FEE\u6539\u5168\u5C40\u914D\u7F6E").action(async () => {
5528
6851
  await handleConfigSet();
5529
6852
  });
5530
- configCmd.command("reset").description("\u5C06\u914D\u7F6E\u6062\u590D\u4E3A\u9ED8\u8BA4\u503C").action(async () => {
6853
+ configCmd.command("reset").description(getCurrentLanguage() === "en" ? "Reset configuration to default values" : "\u5C06\u914D\u7F6E\u6062\u590D\u4E3A\u9ED8\u8BA4\u503C").action(async () => {
5531
6854
  await handleConfigReset();
5532
6855
  });
5533
- configCmd.command("set [key] [value]").description("\u4FEE\u6539\u914D\u7F6E\u9879\uFF08\u65E0\u53C2\u6570\u8FDB\u5165\u4EA4\u4E92\u5F0F\u914D\u7F6E\uFF09").action(async (key, value) => {
6856
+ configCmd.command("set [key] [value]").description(getCurrentLanguage() === "en" ? "Modify configuration (enter interactive mode without arguments)" : "\u4FEE\u6539\u914D\u7F6E\u9879\uFF08\u65E0\u53C2\u6570\u8FDB\u5165\u4EA4\u4E92\u5F0F\u914D\u7F6E\uFF09").action(async (key, value) => {
5534
6857
  await handleConfigSet(key, value);
5535
6858
  });
5536
- configCmd.command("get <key>").description("\u83B7\u53D6\u5355\u4E2A\u914D\u7F6E\u9879\u7684\u503C").action((key) => {
6859
+ configCmd.command("get <key>").description(getCurrentLanguage() === "en" ? "Get the value of a single configuration item" : "\u83B7\u53D6\u5355\u4E2A\u914D\u7F6E\u9879\u7684\u503C").action((key) => {
5537
6860
  handleConfigGet(key);
5538
6861
  });
5539
6862
  }
@@ -5541,13 +6864,14 @@ async function handleConfigReset() {
5541
6864
  logger.info("config reset \u547D\u4EE4\u6267\u884C\uFF0C\u6062\u590D\u9ED8\u8BA4\u914D\u7F6E");
5542
6865
  const confirmed = await confirmDestructiveAction(
5543
6866
  "config reset",
5544
- "\u5F53\u524D\u914D\u7F6E\u5C06\u88AB\u8986\u76D6\u4E3A\u9ED8\u8BA4\u503C"
6867
+ MESSAGES.CONFIG_RESET_WARNING
5545
6868
  );
5546
6869
  if (!confirmed) {
5547
6870
  printInfo(MESSAGES.DESTRUCTIVE_OP_CANCELLED);
5548
6871
  return;
5549
6872
  }
5550
6873
  writeDefaultConfig();
6874
+ resetLanguageCache();
5551
6875
  printSuccess(MESSAGES.CONFIG_RESET_SUCCESS);
5552
6876
  }
5553
6877
  async function handleConfigSet(key, value) {
@@ -5571,6 +6895,9 @@ async function handleConfigSet(key, value) {
5571
6895
  const config2 = loadConfig();
5572
6896
  config2[key] = result.value;
5573
6897
  saveConfig(config2);
6898
+ if (key === "language") {
6899
+ resetLanguageCache();
6900
+ }
5574
6901
  logger.info(`config set \u547D\u4EE4\u6267\u884C\uFF0C\u8BBE\u7F6E ${key} = ${String(result.value)}`);
5575
6902
  printSuccess(MESSAGES.CONFIG_SET_SUCCESS(key, String(result.value)));
5576
6903
  }
@@ -5583,11 +6910,18 @@ async function handleInteractiveConfigSet() {
5583
6910
  disabledKeys[k] = CONFIG_ALIAS_DISABLED_HINT;
5584
6911
  }
5585
6912
  }
5586
- const { key, newValue } = await interactiveConfigEditor(config2, CONFIG_DEFINITIONS, {
6913
+ const i18nDescriptions = getI18nConfigDescriptions();
6914
+ const i18nDefinitions = Object.fromEntries(
6915
+ Object.entries(CONFIG_DEFINITIONS).map(([k, def]) => [k, { ...def, description: i18nDescriptions[k] }])
6916
+ );
6917
+ const { key, newValue } = await interactiveConfigEditor(config2, i18nDefinitions, {
5587
6918
  disabledKeys
5588
6919
  });
5589
6920
  config2[key] = newValue;
5590
6921
  saveConfig(config2);
6922
+ if (key === "language") {
6923
+ resetLanguageCache();
6924
+ }
5591
6925
  printSuccess(MESSAGES.CONFIG_SET_SUCCESS(key, String(newValue)));
5592
6926
  }
5593
6927
  function handleConfigGet(key) {
@@ -5603,7 +6937,7 @@ function handleConfigGet(key) {
5603
6937
 
5604
6938
  // src/commands/reset.ts
5605
6939
  function registerResetCommand(program2) {
5606
- program2.command("reset").description("\u91CD\u7F6E\u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\uFF08\u4FDD\u7559 validate \u5FEB\u7167\uFF09").action(async () => {
6940
+ program2.command("reset").description(getCurrentLanguage() === "en" ? "Reset main worktree working directory and staging area (preserves validate snapshots)" : "\u91CD\u7F6E\u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\uFF08\u4FDD\u7559 validate \u5FEB\u7167\uFF09").action(async () => {
5607
6941
  await handleReset();
5608
6942
  });
5609
6943
  }
@@ -5615,7 +6949,7 @@ async function handleReset() {
5615
6949
  if (getConfigValue("confirmDestructiveOps")) {
5616
6950
  const confirmed = await confirmDestructiveAction(
5617
6951
  "git reset --hard + git clean -fd",
5618
- "\u4E22\u5F03\u6240\u6709\u672A\u63D0\u4EA4\u7684\u66F4\u6539"
6952
+ getCurrentLanguage() === "en" ? "Discard all uncommitted changes" : "\u4E22\u5F03\u6240\u6709\u672A\u63D0\u4EA4\u7684\u66F4\u6539"
5619
6953
  );
5620
6954
  if (!confirmed) {
5621
6955
  printInfo(MESSAGES.DESTRUCTIVE_OP_CANCELLED);
@@ -5633,7 +6967,7 @@ async function handleReset() {
5633
6967
  // src/commands/status.ts
5634
6968
  import chalk11 from "chalk";
5635
6969
  function registerStatusCommand(program2) {
5636
- program2.command("status").description("\u663E\u793A\u9879\u76EE\u5168\u5C40\u72B6\u6001\u603B\u89C8\uFF08\u652F\u6301 --json \u683C\u5F0F\u8F93\u51FA\uFF09").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").option("-i, --interactive", "\u4EA4\u4E92\u5F0F\u9762\u677F\u6A21\u5F0F").action(async (options) => {
6970
+ program2.command("status").description(getCurrentLanguage() === "en" ? "Show project global status overview (supports --json output)" : "\u663E\u793A\u9879\u76EE\u5168\u5C40\u72B6\u6001\u603B\u89C8\uFF08\u652F\u6301 --json \u683C\u5F0F\u8F93\u51FA\uFF09").option("--json", getCurrentLanguage() === "en" ? "Output in JSON format" : "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").option("-i, --interactive", getCurrentLanguage() === "en" ? "Interactive panel mode" : "\u4EA4\u4E92\u5F0F\u9762\u677F\u6A21\u5F0F").action(async (options) => {
5637
6971
  await handleStatus(options);
5638
6972
  });
5639
6973
  }
@@ -5777,12 +7111,13 @@ function printStatusAsText(result) {
5777
7111
  printDoubleSeparator();
5778
7112
  }
5779
7113
  function printMainSection(main2) {
7114
+ const lang = getCurrentLanguage();
5780
7115
  printInfo(` ${chalk11.bold("\u25C6")} ${chalk11.bold(MESSAGES.STATUS_MAIN_SECTION)}`);
5781
- printInfo(` \u5206\u652F: ${chalk11.bold(main2.branch)}`);
7116
+ printInfo(` ${lang === "en" ? "Branch" : "\u5206\u652F"}: ${chalk11.bold(main2.branch)}`);
5782
7117
  if (main2.isClean) {
5783
- printInfo(` \u72B6\u6001: ${chalk11.green("\u2713 \u5E72\u51C0")}`);
7118
+ printInfo(` ${lang === "en" ? "Status" : "\u72B6\u6001"}: ${chalk11.green(lang === "en" ? "\u2713 Clean" : "\u2713 \u5E72\u51C0")}`);
5784
7119
  } else {
5785
- printInfo(` \u72B6\u6001: ${chalk11.yellow("\u2717 \u6709\u672A\u63D0\u4EA4\u4FEE\u6539")}`);
7120
+ printInfo(` ${lang === "en" ? "Status" : "\u72B6\u6001"}: ${chalk11.yellow(lang === "en" ? "\u2717 Uncommitted changes" : "\u2717 \u6709\u672A\u63D0\u4EA4\u4FEE\u6539")}`);
5786
7121
  }
5787
7122
  if (main2.configuredMainBranch !== null) {
5788
7123
  if (main2.configuredBranchExists === false) {
@@ -5796,7 +7131,8 @@ function printMainSection(main2) {
5796
7131
  printInfo("");
5797
7132
  }
5798
7133
  function printWorktreesSection(worktrees, total) {
5799
- printInfo(` ${chalk11.bold("\u25C6")} ${chalk11.bold(MESSAGES.STATUS_WORKTREES_SECTION)} (${total} \u4E2A)`);
7134
+ const lang = getCurrentLanguage();
7135
+ printInfo(` ${chalk11.bold("\u25C6")} ${chalk11.bold(MESSAGES.STATUS_WORKTREES_SECTION)} (${total} ${lang === "en" ? "items" : "\u4E2A"})`);
5800
7136
  printInfo("");
5801
7137
  if (worktrees.length === 0) {
5802
7138
  printInfo(` ${MESSAGES.STATUS_NO_WORKTREES}`);
@@ -5807,18 +7143,19 @@ function printWorktreesSection(worktrees, total) {
5807
7143
  }
5808
7144
  }
5809
7145
  function printWorktreeItem(wt) {
7146
+ const lang = getCurrentLanguage();
5810
7147
  const statusLabel = formatChangeStatusLabel2(wt.changeStatus);
5811
7148
  printInfo(` ${chalk11.bold("\u25CF")} ${chalk11.bold(wt.branch)} [${statusLabel}]`);
5812
7149
  if (wt.insertions > 0 || wt.deletions > 0) {
5813
7150
  printInfo(` ${chalk11.green(`+${wt.insertions}`)} ${chalk11.red(`-${wt.deletions}`)}`);
5814
7151
  }
5815
7152
  if (wt.commitsAhead > 0) {
5816
- printInfo(` ${chalk11.yellow(`${wt.commitsAhead} \u4E2A\u672C\u5730\u63D0\u4EA4`)}`);
7153
+ printInfo(` ${chalk11.yellow(lang === "en" ? `${wt.commitsAhead} local commit(s)` : `${wt.commitsAhead} \u4E2A\u672C\u5730\u63D0\u4EA4`)}`);
5817
7154
  }
5818
7155
  if (wt.commitsBehind > 0) {
5819
- printInfo(` ${chalk11.yellow(`\u843D\u540E\u4E3B\u5206\u652F ${wt.commitsBehind} \u4E2A\u63D0\u4EA4`)}`);
7156
+ printInfo(` ${chalk11.yellow(lang === "en" ? `Behind main by ${wt.commitsBehind} commit(s)` : `\u843D\u540E\u4E3B\u5206\u652F ${wt.commitsBehind} \u4E2A\u63D0\u4EA4`)}`);
5820
7157
  } else {
5821
- printInfo(` ${chalk11.green("\u4E0E\u4E3B\u5206\u652F\u540C\u6B65")}`);
7158
+ printInfo(` ${chalk11.green(lang === "en" ? "In sync with main" : "\u4E0E\u4E3B\u5206\u652F\u540C\u6B65")}`);
5822
7159
  }
5823
7160
  if (wt.createdAt) {
5824
7161
  const relativeTime = formatRelativeTime(wt.createdAt);
@@ -5849,7 +7186,8 @@ function formatChangeStatusLabel2(status) {
5849
7186
  }
5850
7187
  }
5851
7188
  function printSnapshotsSection(snapshots) {
5852
- printInfo(` ${chalk11.bold("\u25C6")} ${chalk11.bold(MESSAGES.STATUS_SNAPSHOTS_SECTION)} (${snapshots.total} \u4E2A)`);
7189
+ const lang = getCurrentLanguage();
7190
+ printInfo(` ${chalk11.bold("\u25C6")} ${chalk11.bold(MESSAGES.STATUS_SNAPSHOTS_SECTION)} (${snapshots.total} ${lang === "en" ? "items" : "\u4E2A"})`);
5853
7191
  if (snapshots.orphaned > 0) {
5854
7192
  printInfo(` ${chalk11.yellow(MESSAGES.STATUS_SNAPSHOT_ORPHANED(snapshots.orphaned))}`);
5855
7193
  }
@@ -5910,16 +7248,16 @@ function handleAliasRemove(alias) {
5910
7248
  printSuccess(MESSAGES.ALIAS_REMOVE_SUCCESS(alias));
5911
7249
  }
5912
7250
  function registerAliasCommand(program2) {
5913
- const aliasCmd = program2.command("alias").description("\u7BA1\u7406\u547D\u4EE4\u522B\u540D\uFF08\u5217\u51FA / \u8BBE\u7F6E / \u79FB\u9664\uFF09").action(() => {
7251
+ const aliasCmd = program2.command("alias").description(getCurrentLanguage() === "en" ? "Manage command aliases (list / set / remove)" : "\u7BA1\u7406\u547D\u4EE4\u522B\u540D\uFF08\u5217\u51FA / \u8BBE\u7F6E / \u79FB\u9664\uFF09").action(() => {
5914
7252
  handleAliasList();
5915
7253
  });
5916
- aliasCmd.command("list").description("\u5217\u51FA\u6240\u6709\u522B\u540D").action(() => {
7254
+ aliasCmd.command("list").description(getCurrentLanguage() === "en" ? "List all aliases" : "\u5217\u51FA\u6240\u6709\u522B\u540D").action(() => {
5917
7255
  handleAliasList();
5918
7256
  });
5919
- aliasCmd.command("set <alias> <command>").description("\u8BBE\u7F6E\u547D\u4EE4\u522B\u540D").action((alias, command) => {
7257
+ aliasCmd.command("set <alias> <command>").description(getCurrentLanguage() === "en" ? "Set a command alias" : "\u8BBE\u7F6E\u547D\u4EE4\u522B\u540D").action((alias, command) => {
5920
7258
  handleAliasSet(program2, alias, command);
5921
7259
  });
5922
- aliasCmd.command("remove <alias>").description("\u79FB\u9664\u547D\u4EE4\u522B\u540D").action((alias) => {
7260
+ aliasCmd.command("remove <alias>").description(getCurrentLanguage() === "en" ? "Remove a command alias" : "\u79FB\u9664\u547D\u4EE4\u522B\u540D").action((alias) => {
5923
7261
  handleAliasRemove(alias);
5924
7262
  });
5925
7263
  }
@@ -5929,7 +7267,7 @@ import { existsSync as existsSync11, readdirSync as readdirSync6, statSync as st
5929
7267
  import { join as join11 } from "path";
5930
7268
  import chalk13 from "chalk";
5931
7269
  function registerProjectsCommand(program2) {
5932
- program2.command("projects [name]").description("\u5C55\u793A\u6240\u6709\u9879\u76EE\u7684 worktree \u6982\u89C8\uFF0C\u6216\u67E5\u770B\u6307\u5B9A\u9879\u76EE\u7684 worktree \u8BE6\u60C5").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").action((name, options) => {
7270
+ program2.command("projects [name]").description(getCurrentLanguage() === "en" ? "Show worktree overview across projects, or view details for a specific project" : "\u5C55\u793A\u6240\u6709\u9879\u76EE\u7684 worktree \u6982\u89C8\uFF0C\u6216\u67E5\u770B\u6307\u5B9A\u9879\u76EE\u7684 worktree \u8BE6\u60C5").option("--json", getCurrentLanguage() === "en" ? "Output in JSON format" : "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").action((name, options) => {
5933
7271
  handleProjects({ name, json: options.json });
5934
7272
  });
5935
7273
  }
@@ -6060,7 +7398,8 @@ function printProjectsOverviewAsText(result) {
6060
7398
  }
6061
7399
  printSeparator();
6062
7400
  printInfo("");
6063
- printInfo(` \u5171 ${chalk13.bold(String(result.totalProjects))} \u4E2A\u9879\u76EE ${chalk13.gray(MESSAGES.PROJECTS_TOTAL_DISK_USAGE(formatDiskSize(result.totalDiskUsage)))}`);
7401
+ const lang = getCurrentLanguage();
7402
+ printInfo(` ${chalk13.bold(String(result.totalProjects))} ${lang === "en" ? "project(s)" : "\u4E2A\u9879\u76EE"} ${chalk13.gray(MESSAGES.PROJECTS_TOTAL_DISK_USAGE(formatDiskSize(result.totalDiskUsage)))}`);
6064
7403
  printInfo("");
6065
7404
  printDoubleSeparator();
6066
7405
  }
@@ -6309,7 +7648,7 @@ function registerCompletionCommand(program2) {
6309
7648
  completionCommand.command("install").description(MESSAGES.COMPLETION_INSTALL_DESC).action(() => {
6310
7649
  installCompletions();
6311
7650
  });
6312
- completionCommand.command("_complete [args...]").allowUnknownOption().description("\u5185\u90E8\u4F7F\u7528\u7684\u52A8\u6001\u8865\u5168\u65B9\u6CD5\uFF0C\u4E0D\u5BF9\u5916\u516C\u5F00").action((args) => {
7651
+ completionCommand.command("_complete [args...]").allowUnknownOption().description(getCurrentLanguage() === "en" ? "Internal dynamic completion method, not for public use" : "\u5185\u90E8\u4F7F\u7528\u7684\u52A8\u6001\u8865\u5168\u65B9\u6CD5\uFF0C\u4E0D\u5BF9\u5916\u516C\u5F00").action((args) => {
6313
7652
  if (!args || args.length < 2) return;
6314
7653
  generateCompletions(program2, args);
6315
7654
  });
@@ -6318,11 +7657,11 @@ function registerCompletionCommand(program2) {
6318
7657
  // src/commands/init.ts
6319
7658
  import { Command as Cmd } from "commander";
6320
7659
  function registerInitCommand(program2) {
6321
- const initCmd = program2.command("init").description("\u521D\u59CB\u5316\u9879\u76EE\u7EA7\u914D\u7F6E\uFF0C\u8BBE\u7F6E\u4E3B\u5DE5\u4F5C\u5206\u652F").option("-b, --branch <branchName>", "\u6307\u5B9A\u4E3B\u5DE5\u4F5C\u5206\u652F\u540D\uFF08\u9ED8\u8BA4\u4F7F\u7528\u5F53\u524D\u5206\u652F\uFF09").action(async (options) => {
7660
+ const initCmd = program2.command("init").description(getCurrentLanguage() === "en" ? "Initialize project configuration and set the main work branch" : "\u521D\u59CB\u5316\u9879\u76EE\u7EA7\u914D\u7F6E\uFF0C\u8BBE\u7F6E\u4E3B\u5DE5\u4F5C\u5206\u652F").option("-b, --branch <branchName>", getCurrentLanguage() === "en" ? "Specify the main work branch name (defaults to current branch)" : "\u6307\u5B9A\u4E3B\u5DE5\u4F5C\u5206\u652F\u540D\uFF08\u9ED8\u8BA4\u4F7F\u7528\u5F53\u524D\u5206\u652F\uFF09").action(async (options) => {
6322
7661
  await handleInit(options);
6323
7662
  });
6324
7663
  initCmd.addCommand(
6325
- new Cmd("show").description("\u4EA4\u4E92\u5F0F\u67E5\u770B\u548C\u4FEE\u6539\u9879\u76EE\u914D\u7F6E\uFF08\u652F\u6301 --json \u683C\u5F0F\u8F93\u51FA\uFF09").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").action(async (options) => {
7664
+ new Cmd("show").description(getCurrentLanguage() === "en" ? "Interactively view and modify project configuration (supports --json output)" : "\u4EA4\u4E92\u5F0F\u67E5\u770B\u548C\u4FEE\u6539\u9879\u76EE\u914D\u7F6E\uFF08\u652F\u6301 --json \u683C\u5F0F\u8F93\u51FA\uFF09").option("--json", getCurrentLanguage() === "en" ? "Output in JSON format" : "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").action(async (options) => {
6326
7665
  await handleInitShow(options);
6327
7666
  })
6328
7667
  );
@@ -6335,9 +7674,13 @@ async function handleInitShow(options) {
6335
7674
  return;
6336
7675
  }
6337
7676
  logger.info("init show \u547D\u4EE4\u6267\u884C\uFF0C\u8FDB\u5165\u4EA4\u4E92\u5F0F\u9879\u76EE\u914D\u7F6E");
7677
+ const i18nDescriptions = getI18nProjectConfigDescriptions();
7678
+ const i18nDefinitions = Object.fromEntries(
7679
+ Object.entries(PROJECT_CONFIG_DEFINITIONS).map(([k, def]) => [k, { ...def, description: i18nDescriptions[k] }])
7680
+ );
6338
7681
  const { key, newValue } = await interactiveConfigEditor(
6339
7682
  config2,
6340
- PROJECT_CONFIG_DEFINITIONS,
7683
+ i18nDefinitions,
6341
7684
  { selectPrompt: MESSAGES.INIT_SELECT_PROMPT }
6342
7685
  );
6343
7686
  const mergedConfig = { ...config2, [key]: newValue };
@@ -6370,7 +7713,7 @@ async function handleInit(options) {
6370
7713
 
6371
7714
  // src/commands/home.ts
6372
7715
  function registerHomeCommand(program2) {
6373
- program2.command("home").description("\u5207\u6362\u56DE\u4E3B\u5DE5\u4F5C\u5206\u652F").action(async () => {
7716
+ program2.command("home").description(getCurrentLanguage() === "en" ? "Switch back to the main work branch" : "\u5207\u6362\u56DE\u4E3B\u5DE5\u4F5C\u5206\u652F").action(async () => {
6374
7717
  await handleHome();
6375
7718
  });
6376
7719
  }
@@ -6399,8 +7742,8 @@ async function handleHome() {
6399
7742
  import { resolve as resolve4, dirname as dirname2, join as join13 } from "path";
6400
7743
  import { existsSync as existsSync14, writeFileSync as writeFileSync6 } from "fs";
6401
7744
  function registerTasksCommand(program2) {
6402
- const taskCmd = program2.command("tasks").description("\u4EFB\u52A1\u6587\u4EF6\u7BA1\u7406");
6403
- taskCmd.command("init").description("\u751F\u6210\u4EFB\u52A1\u6A21\u677F\u6587\u4EF6").argument("[path]", "\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84").action(async (path2) => {
7745
+ const taskCmd = program2.command("tasks").description(getCurrentLanguage() === "en" ? "Task file management" : "\u4EFB\u52A1\u6587\u4EF6\u7BA1\u7406");
7746
+ taskCmd.command("init").description(getCurrentLanguage() === "en" ? "Generate task template file" : "\u751F\u6210\u4EFB\u52A1\u6A21\u677F\u6587\u4EF6").argument("[path]", getCurrentLanguage() === "en" ? "Output file path" : "\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84").action(async (path2) => {
6404
7747
  const filePath = path2 ?? join13(TASK_TEMPLATE_OUTPUT_DIR, generateTaskFilename(TASK_TEMPLATE_FILENAME_PREFIX));
6405
7748
  await handleTasksInit(filePath);
6406
7749
  });
@@ -6412,7 +7755,7 @@ async function handleTasksInit(filePath) {
6412
7755
  throw new ClawtError(MESSAGES.TASK_INIT_FILE_EXISTS(filePath));
6413
7756
  }
6414
7757
  ensureDir(dirname2(absolutePath));
6415
- writeFileSync6(absolutePath, TASK_TEMPLATE_CONTENT, "utf-8");
7758
+ writeFileSync6(absolutePath, getTaskTemplateContent(), "utf-8");
6416
7759
  printSuccess(MESSAGES.TASK_INIT_SUCCESS(filePath));
6417
7760
  printHint(MESSAGES.TASK_INIT_HINT(filePath));
6418
7761
  }
@@ -6422,7 +7765,7 @@ var require2 = createRequire(import.meta.url);
6422
7765
  var { version } = require2("../package.json");
6423
7766
  ensureClawtDirs();
6424
7767
  var program = new Command();
6425
- program.name("clawt").description("\u672C\u5730\u5E76\u884C\u6267\u884C\u591A\u4E2AClaude Code Agent\u4EFB\u52A1\uFF0C\u878D\u5408 Git Worktree \u4E0E Claude Code CLI \u7684\u547D\u4EE4\u884C\u5DE5\u5177").version(version).option("--debug", "\u8F93\u51FA\u8BE6\u7EC6\u8C03\u8BD5\u4FE1\u606F\u5230\u7EC8\u7AEF").option("-y, --yes", "\u8DF3\u8FC7\u6240\u6709\u4EA4\u4E92\u5F0F\u786E\u8BA4\uFF0C\u9002\u7528\u4E8E\u811A\u672C/CI \u73AF\u5883");
7768
+ program.name("clawt").description(getCurrentLanguage() === "en" ? "Run multiple Claude Code Agent tasks in parallel \u2014 a CLI tool integrating Git Worktree with Claude Code CLI" : "\u672C\u5730\u5E76\u884C\u6267\u884C\u591A\u4E2AClaude Code Agent\u4EFB\u52A1\uFF0C\u878D\u5408 Git Worktree \u4E0E Claude Code CLI \u7684\u547D\u4EE4\u884C\u5DE5\u5177").version(version).option("--debug", getCurrentLanguage() === "en" ? "Output detailed debug information to terminal" : "\u8F93\u51FA\u8BE6\u7EC6\u8C03\u8BD5\u4FE1\u606F\u5230\u7EC8\u7AEF").option("-y, --yes", getCurrentLanguage() === "en" ? "Skip all interactive confirmations, suitable for scripts/CI environments" : "\u8DF3\u8FC7\u6240\u6709\u4EA4\u4E92\u5F0F\u786E\u8BA4\uFF0C\u9002\u7528\u4E8E\u811A\u672C/CI \u73AF\u5883");
6426
7769
  program.hook("preAction", (thisCommand) => {
6427
7770
  if (thisCommand.opts().debug) {
6428
7771
  enableConsoleTransport();
@@ -6457,7 +7800,7 @@ process.on("uncaughtException", (error) => {
6457
7800
  logger.error(error.message);
6458
7801
  process.exit(error.exitCode);
6459
7802
  }
6460
- printError(error.message || "\u672A\u77E5\u9519\u8BEF");
7803
+ printError(error.message || (getCurrentLanguage() === "en" ? "Unknown error" : "\u672A\u77E5\u9519\u8BEF"));
6461
7804
  logger.error(`\u672A\u6355\u83B7\u5F02\u5E38: ${error.message}
6462
7805
  ${error.stack}`);
6463
7806
  process.exit(EXIT_CODES.ERROR);
@@ -6469,7 +7812,7 @@ process.on("unhandledRejection", (reason) => {
6469
7812
  logger.error(error.message);
6470
7813
  process.exit(error.exitCode);
6471
7814
  }
6472
- printError(error.message || "\u672A\u77E5\u9519\u8BEF");
7815
+ printError(error.message || (getCurrentLanguage() === "en" ? "Unknown error" : "\u672A\u77E5\u9519\u8BEF"));
6473
7816
  logger.error(`\u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD: ${error.message}`);
6474
7817
  process.exit(EXIT_CODES.ERROR);
6475
7818
  });