clawt 3.9.12 → 3.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.clawt/postCreate.sh +0 -0
- package/README.md +3 -0
- package/README.zh-CN.md +3 -0
- package/dist/index.js +1936 -592
- package/dist/postinstall.js +1626 -283
- package/docs/config-file.md +2 -0
- package/docs/config.md +2 -1
- package/docs/init.md +3 -2
- package/docs/project-config.md +10 -1
- package/docs/spec.md +69 -2
- package/docs/status.md +2 -1
- package/package.json +12 -11
- package/scripts/release.sh +2 -2
- package/src/commands/alias.ts +5 -4
- package/src/commands/completion.ts +2 -1
- package/src/commands/config.ts +25 -7
- package/src/commands/cover-validate.ts +3 -2
- package/src/commands/create.ts +8 -7
- package/src/commands/home.ts +2 -1
- package/src/commands/init.ts +13 -6
- package/src/commands/list.ts +6 -4
- package/src/commands/merge.ts +8 -7
- package/src/commands/projects.ts +5 -3
- package/src/commands/remove.ts +7 -6
- package/src/commands/reset.ts +3 -2
- package/src/commands/resume.ts +10 -7
- package/src/commands/run.ts +8 -7
- package/src/commands/status.ts +16 -11
- package/src/commands/sync.ts +4 -3
- package/src/commands/tasks.ts +8 -6
- package/src/commands/validate.ts +7 -6
- package/src/constants/ai-prompts.ts +11 -11
- package/src/constants/config.ts +30 -0
- package/src/constants/index.ts +3 -2
- package/src/constants/messages/alias.ts +44 -14
- package/src/constants/messages/cli-descriptions.ts +91 -0
- package/src/constants/messages/common.ts +221 -36
- package/src/constants/messages/completion.ts +43 -14
- package/src/constants/messages/config.ts +61 -18
- package/src/constants/messages/cover-validate.ts +43 -14
- package/src/constants/messages/create.ts +16 -5
- package/src/constants/messages/home.ts +19 -6
- package/src/constants/messages/index.ts +2 -0
- package/src/constants/messages/init.ts +45 -14
- package/src/constants/messages/interactive-panel.ts +183 -29
- package/src/constants/messages/merge.ts +140 -38
- package/src/constants/messages/post-create.ts +59 -19
- package/src/constants/messages/projects.ts +51 -14
- package/src/constants/messages/remove.ts +50 -15
- package/src/constants/messages/reset.ts +14 -4
- package/src/constants/messages/resume.ts +116 -19
- package/src/constants/messages/run.ts +165 -35
- package/src/constants/messages/status.ts +84 -23
- package/src/constants/messages/sync.ts +54 -17
- package/src/constants/messages/tasks.ts +21 -7
- package/src/constants/messages/update.ts +35 -11
- package/src/constants/messages/validate.ts +218 -57
- package/src/constants/progress.ts +17 -6
- package/src/constants/project-config.ts +17 -0
- package/src/constants/prompt.ts +18 -2
- package/src/constants/tasks-template.ts +56 -2
- package/src/hooks/post-create.ts +5 -2
- package/src/index.ts +6 -5
- package/src/types/config.ts +2 -0
- package/src/utils/alias.ts +2 -1
- package/src/utils/claude.ts +10 -9
- package/src/utils/config-strategy.ts +3 -3
- package/src/utils/dry-run.ts +2 -2
- package/src/utils/formatter.ts +18 -11
- package/src/utils/i18n.ts +63 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/interactive-panel-render.ts +6 -3
- package/src/utils/interactive-panel.ts +3 -1
- package/src/utils/progress-render.ts +11 -9
- package/src/utils/prompt.ts +2 -1
- package/src/utils/task-executor.ts +10 -7
- package/src/utils/task-file.ts +2 -1
- package/src/utils/terminal.ts +9 -9
- package/src/utils/ui-prompts.ts +4 -3
- package/src/utils/update-checker.ts +1 -1
- package/src/utils/validate-branch.ts +16 -9
- package/src/utils/validate-core.ts +2 -1
- package/src/utils/validate-runner.ts +2 -2
- package/src/utils/worktree-matcher.ts +9 -7
- package/tests/unit/commands/alias.test.ts +4 -0
- package/tests/unit/commands/completion.test.ts +14 -0
- package/tests/unit/commands/config.test.ts +61 -28
- package/tests/unit/commands/cover-validate.test.ts +13 -2
- package/tests/unit/commands/init.test.ts +6 -2
- package/tests/unit/commands/merge.test.ts +14 -0
- package/tests/unit/commands/run.test.ts +17 -0
- package/tests/unit/commands/tasks.test.ts +39 -9
- package/tests/unit/constants/config.test.ts +16 -1
- package/tests/unit/constants/messages-post-create.test.ts +93 -1
- package/tests/unit/constants/messages.test.ts +85 -1
- package/tests/unit/hooks/post-create.test.ts +32 -0
- package/tests/unit/utils/alias.test.ts +14 -0
- package/tests/unit/utils/claude.test.ts +24 -4
- package/tests/unit/utils/config-strategy.test.ts +21 -0
- package/tests/unit/utils/conflict-resolver.test.ts +24 -4
- package/tests/unit/utils/formatter.test.ts +21 -0
- package/tests/unit/utils/i18n.test.ts +91 -0
- package/tests/unit/utils/interactive-panel.test.ts +191 -0
- package/tests/unit/utils/progress.test.ts +39 -18
- package/tests/unit/utils/prompt.test.ts +25 -2
- package/tests/unit/utils/task-file.test.ts +73 -10
- package/tests/unit/utils/terminal-cmux.test.ts +19 -4
- package/tests/unit/utils/update-checker.test.ts +2 -0
- package/tests/unit/utils/validate-branch.test.ts +26 -1
- package/tests/unit/utils/validation.test.ts +2 -2
- 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
|
|
195
|
+
var COMMON_MESSAGES_I18N = {
|
|
27
196
|
/** 不在主 worktree 根目录 */
|
|
28
|
-
NOT_MAIN_WORKTREE:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
247
|
+
NO_WORKTREES: {
|
|
248
|
+
en: "(No worktrees)",
|
|
249
|
+
"zh-CN": "(\u65E0 worktree)"
|
|
250
|
+
},
|
|
49
251
|
/** 目标 worktree 不存在 */
|
|
50
|
-
WORKTREE_NOT_FOUND:
|
|
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:
|
|
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:
|
|
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:
|
|
267
|
+
DESTRUCTIVE_OP_CANCELLED: {
|
|
268
|
+
en: "Operation cancelled",
|
|
269
|
+
"zh-CN": "\u5DF2\u53D6\u6D88\u64CD\u4F5C"
|
|
270
|
+
},
|
|
57
271
|
/** 请提供提交信息 */
|
|
58
|
-
COMMIT_MESSAGE_REQUIRED:
|
|
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:
|
|
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:
|
|
282
|
+
WORKTREE_STATUS_UNAVAILABLE: {
|
|
283
|
+
en: "(Status unavailable)",
|
|
284
|
+
"zh-CN": "(\u72B6\u6001\u4E0D\u53EF\u7528)"
|
|
285
|
+
},
|
|
63
286
|
/** 分隔线 */
|
|
64
|
-
SEPARATOR:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
428
|
+
var RUN_MESSAGES_I18N = {
|
|
83
429
|
/** 分支已存在时提示使用 resume */
|
|
84
|
-
BRANCH_EXISTS_USE_RESUME:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
610
|
+
var CREATE_MESSAGES_I18N = {
|
|
141
611
|
/** 创建数量参数无效 */
|
|
142
|
-
INVALID_COUNT:
|
|
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:
|
|
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
|
|
625
|
+
var MERGE_MESSAGES_I18N = {
|
|
149
626
|
/** merge 成功 */
|
|
150
|
-
MERGE_SUCCESS:
|
|
151
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
181
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
195
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
785
|
+
var VALIDATE_MESSAGES_I18N = {
|
|
210
786
|
/** validate 成功 */
|
|
211
|
-
VALIDATE_SUCCESS:
|
|
212
|
-
|
|
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:
|
|
215
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
224
|
-
|
|
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:
|
|
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:
|
|
229
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
887
|
+
VALIDATE_PARALLEL_CMD_SUCCESS: {
|
|
888
|
+
en: (command) => ` \u2713 ${command}`,
|
|
889
|
+
"zh-CN": (command) => ` \u2713 ${command}`
|
|
890
|
+
},
|
|
253
891
|
/** 并行执行中单个命令失败 */
|
|
254
|
-
VALIDATE_PARALLEL_CMD_FAILED:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
267
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
1003
|
+
var SYNC_MESSAGES_I18N = {
|
|
286
1004
|
/** sync 自动保存未提交变更 */
|
|
287
|
-
SYNC_AUTO_COMMITTED:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
301
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
1063
|
+
var RESUME_MESSAGES_I18N = {
|
|
313
1064
|
/** resume 无可用 worktree */
|
|
314
|
-
RESUME_NO_WORKTREES:
|
|
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:
|
|
317
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
337
|
-
|
|
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:
|
|
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
|
|
1193
|
+
var REMOVE_MESSAGES_I18N = {
|
|
345
1194
|
/** remove 无可用 worktree */
|
|
346
|
-
REMOVE_NO_WORKTREES:
|
|
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:
|
|
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:
|
|
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:
|
|
353
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
1249
|
+
var RESET_MESSAGES_I18N = {
|
|
370
1250
|
/** reset 成功 */
|
|
371
|
-
RESET_SUCCESS:
|
|
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:
|
|
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
|
|
378
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
1281
|
+
CONFIG_GET_VALUE: {
|
|
1282
|
+
en: (key, value) => `${key} = ${value}`,
|
|
1283
|
+
"zh-CN": (key, value) => `${key} = ${value}`
|
|
1284
|
+
},
|
|
385
1285
|
/** 无效配置项名称 */
|
|
386
|
-
CONFIG_INVALID_KEY:
|
|
387
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
1326
|
+
var STATUS_MESSAGES_I18N = {
|
|
404
1327
|
/** status 命令标题 */
|
|
405
|
-
STATUS_TITLE:
|
|
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:
|
|
1333
|
+
STATUS_MAIN_SECTION: {
|
|
1334
|
+
en: "Main Worktree",
|
|
1335
|
+
"zh-CN": "\u4E3B Worktree"
|
|
1336
|
+
},
|
|
408
1337
|
/** status worktrees 区块标题 */
|
|
409
|
-
STATUS_WORKTREES_SECTION:
|
|
1338
|
+
STATUS_WORKTREES_SECTION: {
|
|
1339
|
+
en: "Worktrees",
|
|
1340
|
+
"zh-CN": "Worktree \u5217\u8868"
|
|
1341
|
+
},
|
|
410
1342
|
/** status 快照区块标题 */
|
|
411
|
-
STATUS_SNAPSHOTS_SECTION:
|
|
1343
|
+
STATUS_SNAPSHOTS_SECTION: {
|
|
1344
|
+
en: "Validate Snapshots",
|
|
1345
|
+
"zh-CN": "Validate \u5FEB\u7167"
|
|
1346
|
+
},
|
|
412
1347
|
/** status 无 worktree */
|
|
413
|
-
STATUS_NO_WORKTREES:
|
|
1348
|
+
STATUS_NO_WORKTREES: {
|
|
1349
|
+
en: "(No active worktrees)",
|
|
1350
|
+
"zh-CN": "(\u65E0\u6D3B\u8DC3 worktree)"
|
|
1351
|
+
},
|
|
414
1352
|
/** status 无未清理快照 */
|
|
415
|
-
STATUS_NO_SNAPSHOTS:
|
|
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:
|
|
1358
|
+
STATUS_CHANGE_COMMITTED: {
|
|
1359
|
+
en: "Committed",
|
|
1360
|
+
"zh-CN": "\u5DF2\u63D0\u4EA4"
|
|
1361
|
+
},
|
|
418
1362
|
/** status 变更状态:未提交修改 */
|
|
419
|
-
STATUS_CHANGE_UNCOMMITTED:
|
|
1363
|
+
STATUS_CHANGE_UNCOMMITTED: {
|
|
1364
|
+
en: "Uncommitted changes",
|
|
1365
|
+
"zh-CN": "\u672A\u63D0\u4EA4\u4FEE\u6539"
|
|
1366
|
+
},
|
|
420
1367
|
/** status 变更状态:合并冲突 */
|
|
421
|
-
STATUS_CHANGE_CONFLICT:
|
|
1368
|
+
STATUS_CHANGE_CONFLICT: {
|
|
1369
|
+
en: "Merge conflict",
|
|
1370
|
+
"zh-CN": "\u5408\u5E76\u51B2\u7A81"
|
|
1371
|
+
},
|
|
422
1372
|
/** status 变更状态:无变更 */
|
|
423
|
-
STATUS_CHANGE_CLEAN:
|
|
1373
|
+
STATUS_CHANGE_CLEAN: {
|
|
1374
|
+
en: "No changes",
|
|
1375
|
+
"zh-CN": "\u65E0\u53D8\u66F4"
|
|
1376
|
+
},
|
|
424
1377
|
/** status 快照对应 worktree 已不存在 */
|
|
425
|
-
STATUS_SNAPSHOT_ORPHANED:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
1398
|
+
STATUS_NOT_VALIDATED: {
|
|
1399
|
+
en: "\u2717 Not validated",
|
|
1400
|
+
"zh-CN": "\u2717 \u672A\u9A8C\u8BC1"
|
|
1401
|
+
},
|
|
434
1402
|
/** status 配置的主工作分支(正常状态) */
|
|
435
|
-
STATUS_CONFIGURED_BRANCH:
|
|
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:
|
|
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:
|
|
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
|
|
1421
|
+
var ALIAS_MESSAGES_I18N = {
|
|
444
1422
|
/** 别名列表为空 */
|
|
445
|
-
ALIAS_LIST_EMPTY:
|
|
1423
|
+
ALIAS_LIST_EMPTY: {
|
|
1424
|
+
en: "(No aliases)",
|
|
1425
|
+
"zh-CN": "(\u65E0\u522B\u540D)"
|
|
1426
|
+
},
|
|
446
1427
|
/** 别名设置成功 */
|
|
447
|
-
ALIAS_SET_SUCCESS:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
1461
|
+
var PROJECTS_MESSAGES_I18N = {
|
|
462
1462
|
/** projects 命令全局概览标题 */
|
|
463
|
-
PROJECTS_OVERVIEW_TITLE:
|
|
1463
|
+
PROJECTS_OVERVIEW_TITLE: {
|
|
1464
|
+
en: "Project Overview",
|
|
1465
|
+
"zh-CN": "\u9879\u76EE\u6982\u89C8"
|
|
1466
|
+
},
|
|
464
1467
|
/** projects 命令指定项目详情标题 */
|
|
465
|
-
PROJECTS_DETAIL_TITLE:
|
|
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:
|
|
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:
|
|
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:
|
|
1483
|
+
PROJECTS_WORKTREE_COUNT: {
|
|
1484
|
+
en: (count) => `${count} worktree(s)`,
|
|
1485
|
+
"zh-CN": (count) => `${count} \u4E2A worktree`
|
|
1486
|
+
},
|
|
472
1487
|
/** 最近活跃时间标签 */
|
|
473
|
-
PROJECTS_LAST_ACTIVE:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
1508
|
+
PROJECTS_PATH: {
|
|
1509
|
+
en: (path2) => `Path: ${path2}`,
|
|
1510
|
+
"zh-CN": (path2) => `\u8DEF\u5F84: ${path2}`
|
|
1511
|
+
},
|
|
482
1512
|
/** 最后修改时间标签 */
|
|
483
|
-
PROJECTS_LAST_MODIFIED:
|
|
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
|
|
1521
|
+
var COMPLETION_MESSAGES_I18N = {
|
|
488
1522
|
/** completion 命令的主描述 */
|
|
489
|
-
COMPLETION_COMMAND_DESC:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
510
|
-
npm:
|
|
511
|
-
|
|
512
|
-
|
|
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
|
|
1585
|
+
var UPDATE_COMMANDS = createMessages(UPDATE_COMMANDS_I18N);
|
|
1586
|
+
var UPDATE_MESSAGES_I18N = {
|
|
515
1587
|
/** 版本更新提示 */
|
|
516
|
-
UPDATE_AVAILABLE:
|
|
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:
|
|
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
|
|
1601
|
+
var INIT_MESSAGES_I18N = {
|
|
523
1602
|
/** init 成功 */
|
|
524
|
-
INIT_SUCCESS:
|
|
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:
|
|
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:
|
|
1613
|
+
INIT_SHOW: {
|
|
1614
|
+
en: (configJson) => `${configJson}`,
|
|
1615
|
+
"zh-CN": (configJson) => `${configJson}`
|
|
1616
|
+
},
|
|
529
1617
|
/** init 未初始化 */
|
|
530
|
-
INIT_NOT_INITIALIZED:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
1646
|
+
var COVER_VALIDATE_MESSAGES_I18N = {
|
|
543
1647
|
/** 当前不在验证分支上 */
|
|
544
|
-
COVER_VALIDATE_NOT_ON_VALIDATE_BRANCH:
|
|
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:
|
|
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:
|
|
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:
|
|
551
|
-
|
|
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:
|
|
554
|
-
|
|
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:
|
|
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:
|
|
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
|
|
1690
|
+
var HOME_MESSAGES_I18N = {
|
|
563
1691
|
/** 已在主工作分支上 */
|
|
564
|
-
HOME_ALREADY_ON_MAIN:
|
|
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:
|
|
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:
|
|
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
|
|
1714
|
+
var TASKS_CMD_MESSAGES_I18N = {
|
|
575
1715
|
/** 任务模板文件已存在 */
|
|
576
|
-
TASK_INIT_FILE_EXISTS:
|
|
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:
|
|
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:
|
|
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
|
|
1738
|
+
var POST_CREATE_MESSAGES_I18N = {
|
|
587
1739
|
/** hook 执行跳过(--no-post-create) */
|
|
588
|
-
HOOK_SKIPPED:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
var
|
|
661
|
-
var
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
var
|
|
668
|
-
var
|
|
669
|
-
|
|
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
|
-
|
|
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
|
|
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) =>
|
|
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 ${
|
|
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 =
|
|
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
|
-
##
|
|
2301
|
+
## Task
|
|
876
2302
|
|
|
877
|
-
1.
|
|
878
|
-
2.
|
|
879
|
-
3.
|
|
880
|
-
4.
|
|
881
|
-
5.
|
|
882
|
-
6.
|
|
883
|
-
7.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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) ?
|
|
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
|
|
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
|
-
|
|
1544
|
-
|
|
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
|
-
|
|
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(
|
|
3240
|
+
throw new ClawtError(MESSAGES.WORKSPACE_STILL_DIRTY);
|
|
1924
3241
|
}
|
|
1925
3242
|
return;
|
|
1926
3243
|
}
|
|
1927
|
-
printWarning(
|
|
3244
|
+
printWarning(MESSAGES.UNCOMMITTED_CHANGES_ON_BRANCH);
|
|
1928
3245
|
const choice = await new Enquirer.Select({
|
|
1929
|
-
message:
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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" ?
|
|
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(
|
|
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(
|
|
2347
|
-
printInfo(`
|
|
2348
|
-
printInfo(`
|
|
2349
|
-
printInfo(`
|
|
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(`
|
|
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(
|
|
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 ?
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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} ${
|
|
2752
|
-
if (done > 0) parts.push(chalk5.green(`${done}/${total} ${
|
|
2753
|
-
if (failed > 0) parts.push(chalk5.red(`${failed}/${total} ${
|
|
2754
|
-
if (pending > 0) parts.push(chalk5.gray(`${pending}/${total} ${
|
|
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 ||
|
|
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(
|
|
3225
|
-
printInfo(`
|
|
3226
|
-
printInfo(`
|
|
3227
|
-
printInfo(`
|
|
3228
|
-
printInfo(`
|
|
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(
|
|
4737
|
+
printInfo(` ${chalk6.gray(MESSAGES.PATH_LABEL)} ${worktreePath}`);
|
|
3418
4738
|
if (!isInteractive) {
|
|
3419
|
-
printInfo(` ${chalk6.gray(
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
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() :
|
|
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
|
-
|
|
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
|
|
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
|
|
5343
|
+
return `${workingDirLabel} ${insertText} ${deleteText}`;
|
|
4022
5344
|
}
|
|
4023
5345
|
function renderFooter(countdown) {
|
|
4024
5346
|
return `${PANEL_FOOTER_SHORTCUTS} ${PANEL_FOOTER_COUNTDOWN(countdown)}`;
|
|
@@ -4495,6 +5817,7 @@ var InteractivePanel = class {
|
|
|
4495
5817
|
this.initTerminal();
|
|
4496
5818
|
this.keyboardController.start();
|
|
4497
5819
|
this.isOperating = false;
|
|
5820
|
+
this.render();
|
|
4498
5821
|
await this.refreshData();
|
|
4499
5822
|
this.startAutoRefresh();
|
|
4500
5823
|
this.render();
|
|
@@ -4688,7 +6011,7 @@ function resolvePostCreateHook() {
|
|
|
4688
6011
|
return null;
|
|
4689
6012
|
}
|
|
4690
6013
|
function getSourceLabel(hook) {
|
|
4691
|
-
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";
|
|
4692
6015
|
}
|
|
4693
6016
|
function executeOneHook(worktree, hook) {
|
|
4694
6017
|
return new Promise((resolve5) => {
|
|
@@ -4713,7 +6036,7 @@ function executeOneHook(worktree, hook) {
|
|
|
4713
6036
|
child.on("close", (code) => {
|
|
4714
6037
|
if (code !== null && code !== 0) {
|
|
4715
6038
|
result.success = false;
|
|
4716
|
-
result.error = `\u547D\u4EE4\u9000\u51FA\u7801: ${code}`;
|
|
6039
|
+
result.error = getCurrentLanguage() === "en" ? `Command exit code: ${code}` : `\u547D\u4EE4\u9000\u51FA\u7801: ${code}`;
|
|
4717
6040
|
logger.error(`postCreate hook \u5931\u8D25: ${hook.command} (\u9000\u51FA\u7801: ${code}) @ ${worktree.path}`);
|
|
4718
6041
|
} else {
|
|
4719
6042
|
logger.info(`postCreate hook \u6210\u529F: ${hook.command} @ ${worktree.path}`);
|
|
@@ -4757,7 +6080,7 @@ function runPostCreateHooks(worktrees, skip) {
|
|
|
4757
6080
|
// src/commands/list.ts
|
|
4758
6081
|
import chalk10 from "chalk";
|
|
4759
6082
|
function registerListCommand(program2) {
|
|
4760
|
-
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) => {
|
|
4761
6084
|
await handleList(options);
|
|
4762
6085
|
});
|
|
4763
6086
|
}
|
|
@@ -4784,7 +6107,8 @@ function printListAsJson(projectName, worktrees) {
|
|
|
4784
6107
|
console.log(JSON.stringify(result, null, 2));
|
|
4785
6108
|
}
|
|
4786
6109
|
function printListAsText(projectName, worktrees) {
|
|
4787
|
-
|
|
6110
|
+
const lang = getCurrentLanguage();
|
|
6111
|
+
printInfo(`${lang === "en" ? "Current project" : "\u5F53\u524D\u9879\u76EE"}: ${projectName}
|
|
4788
6112
|
`);
|
|
4789
6113
|
if (worktrees.length === 0) {
|
|
4790
6114
|
printInfo(` ${MESSAGES.NO_WORKTREES}`);
|
|
@@ -4801,13 +6125,13 @@ function printListAsText(projectName, worktrees) {
|
|
|
4801
6125
|
}
|
|
4802
6126
|
printInfo("");
|
|
4803
6127
|
}
|
|
4804
|
-
printInfo(
|
|
6128
|
+
printInfo(`${worktrees.length} ${lang === "en" ? "worktree(s)" : "\u4E2A worktree"}`);
|
|
4805
6129
|
}
|
|
4806
6130
|
}
|
|
4807
6131
|
|
|
4808
6132
|
// src/commands/create.ts
|
|
4809
6133
|
function registerCreateCommand(program2) {
|
|
4810
|
-
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) => {
|
|
4811
6135
|
await handleCreate(options);
|
|
4812
6136
|
});
|
|
4813
6137
|
}
|
|
@@ -4826,10 +6150,10 @@ async function handleCreate(options) {
|
|
|
4826
6150
|
printSuccess(MESSAGES.WORKTREE_CREATED(worktrees.length));
|
|
4827
6151
|
printInfo("");
|
|
4828
6152
|
worktrees.forEach((wt, index) => {
|
|
4829
|
-
printInfo(`\u76EE\u5F55\u8DEF\u5F84${index + 1}\uFF1A`);
|
|
6153
|
+
printInfo(getCurrentLanguage() === "en" ? `Directory path ${index + 1}:` : `\u76EE\u5F55\u8DEF\u5F84${index + 1}\uFF1A`);
|
|
4830
6154
|
printInfo(` ${wt.path}`);
|
|
4831
|
-
printInfo(` \u5206\u652F\u540D: ${wt.branch}`);
|
|
4832
|
-
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)}`);
|
|
4833
6157
|
printSeparator();
|
|
4834
6158
|
});
|
|
4835
6159
|
}
|
|
@@ -4842,7 +6166,7 @@ var REMOVE_RESOLVE_MESSAGES = {
|
|
|
4842
6166
|
noMatch: MESSAGES.REMOVE_NO_MATCH
|
|
4843
6167
|
};
|
|
4844
6168
|
function registerRemoveCommand(program2) {
|
|
4845
|
-
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) => {
|
|
4846
6170
|
await handleRemove(options);
|
|
4847
6171
|
});
|
|
4848
6172
|
}
|
|
@@ -4871,9 +6195,9 @@ async function handleRemove(options) {
|
|
|
4871
6195
|
throw new ClawtError(MESSAGES.REMOVE_VALIDATE_BRANCH_IS_CURRENT(wt.branch, validateBranch));
|
|
4872
6196
|
}
|
|
4873
6197
|
}
|
|
4874
|
-
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");
|
|
4875
6199
|
worktreesToRemove.forEach((wt, index) => {
|
|
4876
|
-
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)}`);
|
|
4877
6201
|
});
|
|
4878
6202
|
printInfo("");
|
|
4879
6203
|
const autoDelete = getConfigValue("autoDeleteBranch");
|
|
@@ -4909,14 +6233,14 @@ async function handleRemove(options) {
|
|
|
4909
6233
|
if (failures.length > 0) {
|
|
4910
6234
|
printError(MESSAGES.REMOVE_PARTIAL_FAILURE(failures));
|
|
4911
6235
|
throw new ClawtError(
|
|
4912
|
-
`${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`
|
|
4913
6237
|
);
|
|
4914
6238
|
}
|
|
4915
6239
|
}
|
|
4916
6240
|
|
|
4917
6241
|
// src/commands/run.ts
|
|
4918
6242
|
function registerRunCommand(program2) {
|
|
4919
|
-
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) => {
|
|
4920
6244
|
await handleRun(options);
|
|
4921
6245
|
});
|
|
4922
6246
|
}
|
|
@@ -5013,7 +6337,7 @@ var RESUME_RESOLVE_MESSAGES = {
|
|
|
5013
6337
|
noMatch: MESSAGES.RESUME_NO_MATCH
|
|
5014
6338
|
};
|
|
5015
6339
|
function registerResumeCommand(program2) {
|
|
5016
|
-
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) => {
|
|
5017
6341
|
await handleResume(options);
|
|
5018
6342
|
});
|
|
5019
6343
|
}
|
|
@@ -5086,9 +6410,9 @@ async function handleNonInteractiveBatchResume(filePath, options) {
|
|
|
5086
6410
|
await executeBatchTasks(worktrees, tasks, concurrency, continueFlags);
|
|
5087
6411
|
}
|
|
5088
6412
|
function printBatchResumePreview(worktrees, sessionMap) {
|
|
5089
|
-
printInfo("\u5373\u5C06\u6062\u590D\u7684\u5206\u652F\uFF1A");
|
|
6413
|
+
printInfo(getCurrentLanguage() === "en" ? "Branches to resume:" : "\u5373\u5C06\u6062\u590D\u7684\u5206\u652F\uFF1A");
|
|
5090
6414
|
for (const wt of worktrees) {
|
|
5091
|
-
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";
|
|
5092
6416
|
printInfo(` - ${wt.branch} (${modeLabel})`);
|
|
5093
6417
|
}
|
|
5094
6418
|
printInfo("");
|
|
@@ -5115,7 +6439,7 @@ async function handleBatchResume(worktrees) {
|
|
|
5115
6439
|
|
|
5116
6440
|
// src/commands/sync.ts
|
|
5117
6441
|
function registerSyncCommand(program2) {
|
|
5118
|
-
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) => {
|
|
5119
6443
|
await handleSync(options);
|
|
5120
6444
|
});
|
|
5121
6445
|
}
|
|
@@ -5139,7 +6463,7 @@ function mergeMainBranch(worktreePath, mainBranch) {
|
|
|
5139
6463
|
if (hasMergeConflict(worktreePath)) {
|
|
5140
6464
|
return true;
|
|
5141
6465
|
}
|
|
5142
|
-
throw new ClawtError(`\u5408\u5E76 ${mainBranch} \u5931\u8D25`);
|
|
6466
|
+
throw new ClawtError(getCurrentLanguage() === "en" ? `Merge of ${mainBranch} failed` : `\u5408\u5E76 ${mainBranch} \u5931\u8D25`);
|
|
5143
6467
|
}
|
|
5144
6468
|
}
|
|
5145
6469
|
async function executeSyncForBranch(targetWorktreePath, branch) {
|
|
@@ -5177,7 +6501,7 @@ var VALIDATE_RESOLVE_MESSAGES = {
|
|
|
5177
6501
|
noMatch: MESSAGES.VALIDATE_NO_MATCH
|
|
5178
6502
|
};
|
|
5179
6503
|
function registerValidateCommand(program2) {
|
|
5180
|
-
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) => {
|
|
5181
6505
|
await handleValidate(options);
|
|
5182
6506
|
});
|
|
5183
6507
|
}
|
|
@@ -5204,7 +6528,7 @@ async function handleValidateClean(options) {
|
|
|
5204
6528
|
if (getConfigValue("confirmDestructiveOps")) {
|
|
5205
6529
|
const confirmed = await confirmDestructiveAction(
|
|
5206
6530
|
"git reset --hard + git clean -fd",
|
|
5207
|
-
`\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`
|
|
5208
6532
|
);
|
|
5209
6533
|
if (!confirmed) {
|
|
5210
6534
|
printInfo(MESSAGES.DESTRUCTIVE_OP_CANCELLED);
|
|
@@ -5251,7 +6575,7 @@ async function handleIncrementalValidate(targetWorktreePath, mainWorktreePath, p
|
|
|
5251
6575
|
try {
|
|
5252
6576
|
gitReadTree(oldStagedTreeHash, mainWorktreePath);
|
|
5253
6577
|
} catch (error) {
|
|
5254
|
-
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}`);
|
|
5255
6579
|
}
|
|
5256
6580
|
}
|
|
5257
6581
|
printInfo(MESSAGES.INCREMENTAL_VALIDATE_NO_CHANGES(branchName));
|
|
@@ -5317,7 +6641,7 @@ async function handleValidate(options) {
|
|
|
5317
6641
|
|
|
5318
6642
|
// src/commands/cover-validate.ts
|
|
5319
6643
|
function registerCoverValidateCommand(program2) {
|
|
5320
|
-
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 () => {
|
|
5321
6645
|
await handleCoverValidate();
|
|
5322
6646
|
});
|
|
5323
6647
|
}
|
|
@@ -5360,7 +6684,7 @@ async function handleCoverValidate() {
|
|
|
5360
6684
|
const { treeHash: snapshotTreeHash } = readSnapshot(projectName, targetBranchName);
|
|
5361
6685
|
if (isWorkingDirClean(mainWorktreePath)) {
|
|
5362
6686
|
printInfo(MESSAGES.COVER_VALIDATE_WORKING_DIR_CLEAN);
|
|
5363
|
-
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");
|
|
5364
6688
|
if (!confirmed) return;
|
|
5365
6689
|
}
|
|
5366
6690
|
const currentTreeHash = computeWorktreeTreeHash(mainWorktreePath);
|
|
@@ -5382,7 +6706,7 @@ async function handleCoverValidate() {
|
|
|
5382
6706
|
|
|
5383
6707
|
// src/commands/merge.ts
|
|
5384
6708
|
function registerMergeCommand(program2) {
|
|
5385
|
-
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) => {
|
|
5386
6710
|
await handleMerge(options);
|
|
5387
6711
|
});
|
|
5388
6712
|
}
|
|
@@ -5427,10 +6751,10 @@ async function handleSquashIfNeeded(targetWorktreePath, mainWorktreePath, branch
|
|
|
5427
6751
|
async function shouldCleanupAfterMerge(branchName) {
|
|
5428
6752
|
const autoDelete = getConfigValue("autoDeleteBranch");
|
|
5429
6753
|
if (autoDelete) {
|
|
5430
|
-
printInfo(
|
|
6754
|
+
printInfo(MESSAGES.AUTO_DELETE_CONFIGURED(branchName));
|
|
5431
6755
|
return true;
|
|
5432
6756
|
}
|
|
5433
|
-
return confirmAction(
|
|
6757
|
+
return confirmAction(MESSAGES.CONFIRM_DELETE_WORKTREE_BRANCH(branchName), true);
|
|
5434
6758
|
}
|
|
5435
6759
|
function cleanupWorktreeAndBranch(worktreePath, branchName) {
|
|
5436
6760
|
cleanupWorktrees([{ path: worktreePath, branch: branchName }]);
|
|
@@ -5505,7 +6829,7 @@ async function handleMerge(options) {
|
|
|
5505
6829
|
return;
|
|
5506
6830
|
}
|
|
5507
6831
|
} else {
|
|
5508
|
-
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");
|
|
5509
6833
|
}
|
|
5510
6834
|
if (options.message) {
|
|
5511
6835
|
printSuccess(MESSAGES.MERGE_SUCCESS(branch, options.message, autoPullPush));
|
|
@@ -5523,16 +6847,16 @@ async function handleMerge(options) {
|
|
|
5523
6847
|
|
|
5524
6848
|
// src/commands/config.ts
|
|
5525
6849
|
function registerConfigCommand(program2) {
|
|
5526
|
-
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 () => {
|
|
5527
6851
|
await handleConfigSet();
|
|
5528
6852
|
});
|
|
5529
|
-
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 () => {
|
|
5530
6854
|
await handleConfigReset();
|
|
5531
6855
|
});
|
|
5532
|
-
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) => {
|
|
5533
6857
|
await handleConfigSet(key, value);
|
|
5534
6858
|
});
|
|
5535
|
-
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) => {
|
|
5536
6860
|
handleConfigGet(key);
|
|
5537
6861
|
});
|
|
5538
6862
|
}
|
|
@@ -5540,13 +6864,14 @@ async function handleConfigReset() {
|
|
|
5540
6864
|
logger.info("config reset \u547D\u4EE4\u6267\u884C\uFF0C\u6062\u590D\u9ED8\u8BA4\u914D\u7F6E");
|
|
5541
6865
|
const confirmed = await confirmDestructiveAction(
|
|
5542
6866
|
"config reset",
|
|
5543
|
-
|
|
6867
|
+
MESSAGES.CONFIG_RESET_WARNING
|
|
5544
6868
|
);
|
|
5545
6869
|
if (!confirmed) {
|
|
5546
6870
|
printInfo(MESSAGES.DESTRUCTIVE_OP_CANCELLED);
|
|
5547
6871
|
return;
|
|
5548
6872
|
}
|
|
5549
6873
|
writeDefaultConfig();
|
|
6874
|
+
resetLanguageCache();
|
|
5550
6875
|
printSuccess(MESSAGES.CONFIG_RESET_SUCCESS);
|
|
5551
6876
|
}
|
|
5552
6877
|
async function handleConfigSet(key, value) {
|
|
@@ -5570,6 +6895,9 @@ async function handleConfigSet(key, value) {
|
|
|
5570
6895
|
const config2 = loadConfig();
|
|
5571
6896
|
config2[key] = result.value;
|
|
5572
6897
|
saveConfig(config2);
|
|
6898
|
+
if (key === "language") {
|
|
6899
|
+
resetLanguageCache();
|
|
6900
|
+
}
|
|
5573
6901
|
logger.info(`config set \u547D\u4EE4\u6267\u884C\uFF0C\u8BBE\u7F6E ${key} = ${String(result.value)}`);
|
|
5574
6902
|
printSuccess(MESSAGES.CONFIG_SET_SUCCESS(key, String(result.value)));
|
|
5575
6903
|
}
|
|
@@ -5582,11 +6910,18 @@ async function handleInteractiveConfigSet() {
|
|
|
5582
6910
|
disabledKeys[k] = CONFIG_ALIAS_DISABLED_HINT;
|
|
5583
6911
|
}
|
|
5584
6912
|
}
|
|
5585
|
-
const
|
|
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, {
|
|
5586
6918
|
disabledKeys
|
|
5587
6919
|
});
|
|
5588
6920
|
config2[key] = newValue;
|
|
5589
6921
|
saveConfig(config2);
|
|
6922
|
+
if (key === "language") {
|
|
6923
|
+
resetLanguageCache();
|
|
6924
|
+
}
|
|
5590
6925
|
printSuccess(MESSAGES.CONFIG_SET_SUCCESS(key, String(newValue)));
|
|
5591
6926
|
}
|
|
5592
6927
|
function handleConfigGet(key) {
|
|
@@ -5602,7 +6937,7 @@ function handleConfigGet(key) {
|
|
|
5602
6937
|
|
|
5603
6938
|
// src/commands/reset.ts
|
|
5604
6939
|
function registerResetCommand(program2) {
|
|
5605
|
-
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 () => {
|
|
5606
6941
|
await handleReset();
|
|
5607
6942
|
});
|
|
5608
6943
|
}
|
|
@@ -5614,7 +6949,7 @@ async function handleReset() {
|
|
|
5614
6949
|
if (getConfigValue("confirmDestructiveOps")) {
|
|
5615
6950
|
const confirmed = await confirmDestructiveAction(
|
|
5616
6951
|
"git reset --hard + git clean -fd",
|
|
5617
|
-
"\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"
|
|
5618
6953
|
);
|
|
5619
6954
|
if (!confirmed) {
|
|
5620
6955
|
printInfo(MESSAGES.DESTRUCTIVE_OP_CANCELLED);
|
|
@@ -5632,7 +6967,7 @@ async function handleReset() {
|
|
|
5632
6967
|
// src/commands/status.ts
|
|
5633
6968
|
import chalk11 from "chalk";
|
|
5634
6969
|
function registerStatusCommand(program2) {
|
|
5635
|
-
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) => {
|
|
5636
6971
|
await handleStatus(options);
|
|
5637
6972
|
});
|
|
5638
6973
|
}
|
|
@@ -5776,12 +7111,13 @@ function printStatusAsText(result) {
|
|
|
5776
7111
|
printDoubleSeparator();
|
|
5777
7112
|
}
|
|
5778
7113
|
function printMainSection(main2) {
|
|
7114
|
+
const lang = getCurrentLanguage();
|
|
5779
7115
|
printInfo(` ${chalk11.bold("\u25C6")} ${chalk11.bold(MESSAGES.STATUS_MAIN_SECTION)}`);
|
|
5780
|
-
printInfo(` \u5206\u652F: ${chalk11.bold(main2.branch)}`);
|
|
7116
|
+
printInfo(` ${lang === "en" ? "Branch" : "\u5206\u652F"}: ${chalk11.bold(main2.branch)}`);
|
|
5781
7117
|
if (main2.isClean) {
|
|
5782
|
-
printInfo(` \u72B6\u6001: ${chalk11.green("\u2713 \u5E72\u51C0")}`);
|
|
7118
|
+
printInfo(` ${lang === "en" ? "Status" : "\u72B6\u6001"}: ${chalk11.green(lang === "en" ? "\u2713 Clean" : "\u2713 \u5E72\u51C0")}`);
|
|
5783
7119
|
} else {
|
|
5784
|
-
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")}`);
|
|
5785
7121
|
}
|
|
5786
7122
|
if (main2.configuredMainBranch !== null) {
|
|
5787
7123
|
if (main2.configuredBranchExists === false) {
|
|
@@ -5795,7 +7131,8 @@ function printMainSection(main2) {
|
|
|
5795
7131
|
printInfo("");
|
|
5796
7132
|
}
|
|
5797
7133
|
function printWorktreesSection(worktrees, total) {
|
|
5798
|
-
|
|
7134
|
+
const lang = getCurrentLanguage();
|
|
7135
|
+
printInfo(` ${chalk11.bold("\u25C6")} ${chalk11.bold(MESSAGES.STATUS_WORKTREES_SECTION)} (${total} ${lang === "en" ? "items" : "\u4E2A"})`);
|
|
5799
7136
|
printInfo("");
|
|
5800
7137
|
if (worktrees.length === 0) {
|
|
5801
7138
|
printInfo(` ${MESSAGES.STATUS_NO_WORKTREES}`);
|
|
@@ -5806,18 +7143,19 @@ function printWorktreesSection(worktrees, total) {
|
|
|
5806
7143
|
}
|
|
5807
7144
|
}
|
|
5808
7145
|
function printWorktreeItem(wt) {
|
|
7146
|
+
const lang = getCurrentLanguage();
|
|
5809
7147
|
const statusLabel = formatChangeStatusLabel2(wt.changeStatus);
|
|
5810
7148
|
printInfo(` ${chalk11.bold("\u25CF")} ${chalk11.bold(wt.branch)} [${statusLabel}]`);
|
|
5811
7149
|
if (wt.insertions > 0 || wt.deletions > 0) {
|
|
5812
7150
|
printInfo(` ${chalk11.green(`+${wt.insertions}`)} ${chalk11.red(`-${wt.deletions}`)}`);
|
|
5813
7151
|
}
|
|
5814
7152
|
if (wt.commitsAhead > 0) {
|
|
5815
|
-
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`)}`);
|
|
5816
7154
|
}
|
|
5817
7155
|
if (wt.commitsBehind > 0) {
|
|
5818
|
-
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`)}`);
|
|
5819
7157
|
} else {
|
|
5820
|
-
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")}`);
|
|
5821
7159
|
}
|
|
5822
7160
|
if (wt.createdAt) {
|
|
5823
7161
|
const relativeTime = formatRelativeTime(wt.createdAt);
|
|
@@ -5848,7 +7186,8 @@ function formatChangeStatusLabel2(status) {
|
|
|
5848
7186
|
}
|
|
5849
7187
|
}
|
|
5850
7188
|
function printSnapshotsSection(snapshots) {
|
|
5851
|
-
|
|
7189
|
+
const lang = getCurrentLanguage();
|
|
7190
|
+
printInfo(` ${chalk11.bold("\u25C6")} ${chalk11.bold(MESSAGES.STATUS_SNAPSHOTS_SECTION)} (${snapshots.total} ${lang === "en" ? "items" : "\u4E2A"})`);
|
|
5852
7191
|
if (snapshots.orphaned > 0) {
|
|
5853
7192
|
printInfo(` ${chalk11.yellow(MESSAGES.STATUS_SNAPSHOT_ORPHANED(snapshots.orphaned))}`);
|
|
5854
7193
|
}
|
|
@@ -5909,16 +7248,16 @@ function handleAliasRemove(alias) {
|
|
|
5909
7248
|
printSuccess(MESSAGES.ALIAS_REMOVE_SUCCESS(alias));
|
|
5910
7249
|
}
|
|
5911
7250
|
function registerAliasCommand(program2) {
|
|
5912
|
-
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(() => {
|
|
5913
7252
|
handleAliasList();
|
|
5914
7253
|
});
|
|
5915
|
-
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(() => {
|
|
5916
7255
|
handleAliasList();
|
|
5917
7256
|
});
|
|
5918
|
-
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) => {
|
|
5919
7258
|
handleAliasSet(program2, alias, command);
|
|
5920
7259
|
});
|
|
5921
|
-
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) => {
|
|
5922
7261
|
handleAliasRemove(alias);
|
|
5923
7262
|
});
|
|
5924
7263
|
}
|
|
@@ -5928,7 +7267,7 @@ import { existsSync as existsSync11, readdirSync as readdirSync6, statSync as st
|
|
|
5928
7267
|
import { join as join11 } from "path";
|
|
5929
7268
|
import chalk13 from "chalk";
|
|
5930
7269
|
function registerProjectsCommand(program2) {
|
|
5931
|
-
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) => {
|
|
5932
7271
|
handleProjects({ name, json: options.json });
|
|
5933
7272
|
});
|
|
5934
7273
|
}
|
|
@@ -6059,7 +7398,8 @@ function printProjectsOverviewAsText(result) {
|
|
|
6059
7398
|
}
|
|
6060
7399
|
printSeparator();
|
|
6061
7400
|
printInfo("");
|
|
6062
|
-
|
|
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)))}`);
|
|
6063
7403
|
printInfo("");
|
|
6064
7404
|
printDoubleSeparator();
|
|
6065
7405
|
}
|
|
@@ -6308,7 +7648,7 @@ function registerCompletionCommand(program2) {
|
|
|
6308
7648
|
completionCommand.command("install").description(MESSAGES.COMPLETION_INSTALL_DESC).action(() => {
|
|
6309
7649
|
installCompletions();
|
|
6310
7650
|
});
|
|
6311
|
-
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) => {
|
|
6312
7652
|
if (!args || args.length < 2) return;
|
|
6313
7653
|
generateCompletions(program2, args);
|
|
6314
7654
|
});
|
|
@@ -6317,11 +7657,11 @@ function registerCompletionCommand(program2) {
|
|
|
6317
7657
|
// src/commands/init.ts
|
|
6318
7658
|
import { Command as Cmd } from "commander";
|
|
6319
7659
|
function registerInitCommand(program2) {
|
|
6320
|
-
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) => {
|
|
6321
7661
|
await handleInit(options);
|
|
6322
7662
|
});
|
|
6323
7663
|
initCmd.addCommand(
|
|
6324
|
-
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) => {
|
|
6325
7665
|
await handleInitShow(options);
|
|
6326
7666
|
})
|
|
6327
7667
|
);
|
|
@@ -6334,9 +7674,13 @@ async function handleInitShow(options) {
|
|
|
6334
7674
|
return;
|
|
6335
7675
|
}
|
|
6336
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
|
+
);
|
|
6337
7681
|
const { key, newValue } = await interactiveConfigEditor(
|
|
6338
7682
|
config2,
|
|
6339
|
-
|
|
7683
|
+
i18nDefinitions,
|
|
6340
7684
|
{ selectPrompt: MESSAGES.INIT_SELECT_PROMPT }
|
|
6341
7685
|
);
|
|
6342
7686
|
const mergedConfig = { ...config2, [key]: newValue };
|
|
@@ -6369,7 +7713,7 @@ async function handleInit(options) {
|
|
|
6369
7713
|
|
|
6370
7714
|
// src/commands/home.ts
|
|
6371
7715
|
function registerHomeCommand(program2) {
|
|
6372
|
-
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 () => {
|
|
6373
7717
|
await handleHome();
|
|
6374
7718
|
});
|
|
6375
7719
|
}
|
|
@@ -6398,8 +7742,8 @@ async function handleHome() {
|
|
|
6398
7742
|
import { resolve as resolve4, dirname as dirname2, join as join13 } from "path";
|
|
6399
7743
|
import { existsSync as existsSync14, writeFileSync as writeFileSync6 } from "fs";
|
|
6400
7744
|
function registerTasksCommand(program2) {
|
|
6401
|
-
const taskCmd = program2.command("tasks").description("\u4EFB\u52A1\u6587\u4EF6\u7BA1\u7406");
|
|
6402
|
-
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) => {
|
|
6403
7747
|
const filePath = path2 ?? join13(TASK_TEMPLATE_OUTPUT_DIR, generateTaskFilename(TASK_TEMPLATE_FILENAME_PREFIX));
|
|
6404
7748
|
await handleTasksInit(filePath);
|
|
6405
7749
|
});
|
|
@@ -6411,7 +7755,7 @@ async function handleTasksInit(filePath) {
|
|
|
6411
7755
|
throw new ClawtError(MESSAGES.TASK_INIT_FILE_EXISTS(filePath));
|
|
6412
7756
|
}
|
|
6413
7757
|
ensureDir(dirname2(absolutePath));
|
|
6414
|
-
writeFileSync6(absolutePath,
|
|
7758
|
+
writeFileSync6(absolutePath, getTaskTemplateContent(), "utf-8");
|
|
6415
7759
|
printSuccess(MESSAGES.TASK_INIT_SUCCESS(filePath));
|
|
6416
7760
|
printHint(MESSAGES.TASK_INIT_HINT(filePath));
|
|
6417
7761
|
}
|
|
@@ -6421,7 +7765,7 @@ var require2 = createRequire(import.meta.url);
|
|
|
6421
7765
|
var { version } = require2("../package.json");
|
|
6422
7766
|
ensureClawtDirs();
|
|
6423
7767
|
var program = new Command();
|
|
6424
|
-
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");
|
|
6425
7769
|
program.hook("preAction", (thisCommand) => {
|
|
6426
7770
|
if (thisCommand.opts().debug) {
|
|
6427
7771
|
enableConsoleTransport();
|
|
@@ -6456,7 +7800,7 @@ process.on("uncaughtException", (error) => {
|
|
|
6456
7800
|
logger.error(error.message);
|
|
6457
7801
|
process.exit(error.exitCode);
|
|
6458
7802
|
}
|
|
6459
|
-
printError(error.message || "\u672A\u77E5\u9519\u8BEF");
|
|
7803
|
+
printError(error.message || (getCurrentLanguage() === "en" ? "Unknown error" : "\u672A\u77E5\u9519\u8BEF"));
|
|
6460
7804
|
logger.error(`\u672A\u6355\u83B7\u5F02\u5E38: ${error.message}
|
|
6461
7805
|
${error.stack}`);
|
|
6462
7806
|
process.exit(EXIT_CODES.ERROR);
|
|
@@ -6468,7 +7812,7 @@ process.on("unhandledRejection", (reason) => {
|
|
|
6468
7812
|
logger.error(error.message);
|
|
6469
7813
|
process.exit(error.exitCode);
|
|
6470
7814
|
}
|
|
6471
|
-
printError(error.message || "\u672A\u77E5\u9519\u8BEF");
|
|
7815
|
+
printError(error.message || (getCurrentLanguage() === "en" ? "Unknown error" : "\u672A\u77E5\u9519\u8BEF"));
|
|
6472
7816
|
logger.error(`\u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD: ${error.message}`);
|
|
6473
7817
|
process.exit(EXIT_CODES.ERROR);
|
|
6474
7818
|
});
|