clawt 2.10.0 → 2.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/.claude/agent-memory/docs-sync-updater/MEMORY.md +9 -6
  2. package/.claude/agents/docs-sync-updater.md +11 -0
  3. package/README.md +63 -290
  4. package/dist/index.js +203 -104
  5. package/dist/postinstall.js +242 -0
  6. package/docs/spec.md +27 -14
  7. package/package.json +1 -1
  8. package/src/commands/remove.ts +21 -28
  9. package/src/constants/index.ts +1 -1
  10. package/src/constants/messages/common.ts +41 -0
  11. package/src/constants/messages/config.ts +5 -0
  12. package/src/constants/messages/create.ts +5 -0
  13. package/src/constants/messages/index.ts +29 -0
  14. package/src/constants/messages/merge.ts +42 -0
  15. package/src/constants/messages/remove.ts +15 -0
  16. package/src/constants/messages/reset.ts +7 -0
  17. package/src/constants/messages/resume.ts +12 -0
  18. package/src/constants/messages/run.ts +16 -0
  19. package/src/constants/messages/status.ts +25 -0
  20. package/src/constants/messages/sync.ts +24 -0
  21. package/src/constants/messages/validate.ts +25 -0
  22. package/src/utils/index.ts +2 -2
  23. package/src/utils/worktree-matcher.ts +92 -0
  24. package/tests/unit/commands/config.test.ts +110 -0
  25. package/tests/unit/commands/create.test.ts +115 -0
  26. package/tests/unit/commands/list.test.ts +118 -0
  27. package/tests/unit/commands/merge.test.ts +323 -0
  28. package/tests/unit/commands/remove.test.ts +240 -0
  29. package/tests/unit/commands/reset.test.ts +124 -0
  30. package/tests/unit/commands/resume.test.ts +91 -0
  31. package/tests/unit/commands/run.test.ts +207 -0
  32. package/tests/unit/commands/status.test.ts +214 -0
  33. package/tests/unit/commands/sync.test.ts +208 -0
  34. package/tests/unit/commands/validate.test.ts +382 -0
  35. package/tests/unit/constants/messages.test.ts +1 -1
  36. package/tests/unit/utils/config.test.ts +21 -1
  37. package/tests/unit/utils/formatter.test.ts +44 -1
  38. package/tests/unit/utils/git.test.ts +44 -0
  39. package/tests/unit/utils/validate-snapshot.test.ts +25 -0
  40. package/tests/unit/utils/worktree-matcher.test.ts +81 -5
package/dist/index.js CHANGED
@@ -18,8 +18,8 @@ var VALIDATE_SNAPSHOTS_DIR = join(CLAWT_HOME, "validate-snapshots");
18
18
  // src/constants/branch.ts
19
19
  var INVALID_BRANCH_CHARS = /[\/\\.\s~:*?[\]^]+/g;
20
20
 
21
- // src/constants/messages.ts
22
- var MESSAGES = {
21
+ // src/constants/messages/common.ts
22
+ var COMMON_MESSAGES = {
23
23
  /** 不在主 worktree 根目录 */
24
24
  NOT_MAIN_WORKTREE: "\u8BF7\u5728\u4E3B worktree \u7684\u6839\u76EE\u5F55\u4E0B\u6267\u884C clawt",
25
25
  /** Git 未安装 */
@@ -28,8 +28,6 @@ var MESSAGES = {
28
28
  CLAUDE_NOT_INSTALLED: "Claude Code CLI \u672A\u5B89\u88C5\uFF0C\u8BF7\u5148\u5B89\u88C5\uFF1Anpm install -g @anthropic-ai/claude-code",
29
29
  /** 分支已存在 */
30
30
  BRANCH_EXISTS: (name) => `\u5206\u652F ${name} \u5DF2\u5B58\u5728\uFF0C\u65E0\u6CD5\u521B\u5EFA`,
31
- /** 分支已存在时提示使用 resume */
32
- BRANCH_EXISTS_USE_RESUME: (name) => `\u5206\u652F ${name} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u4F7F\u7528 clawt resume -b ${name} \u6062\u590D\u4F1A\u8BDD`,
33
31
  /** 分支名清理后为空 */
34
32
  BRANCH_NAME_EMPTY: (original) => `\u5206\u652F\u540D "${original}" \u4E2D\u4E0D\u5305\u542B\u5408\u6CD5\u5B57\u7B26\uFF0C\u65E0\u6CD5\u521B\u5EFA\u5206\u652F`,
35
33
  /** 分支名被转换 */
@@ -46,9 +44,44 @@ var MESSAGES = {
46
44
  MAIN_WORKTREE_DIRTY: "\u4E3B worktree \u6709\u672A\u63D0\u4EA4\u7684\u66F4\u6539\uFF0C\u8BF7\u5148\u5904\u7406",
47
45
  /** 目标 worktree 无更改 */
48
46
  TARGET_WORKTREE_CLEAN: "\u8BE5 worktree \u7684\u5206\u652F\u4E0A\u6CA1\u6709\u4EFB\u4F55\u66F4\u6539\uFF0C\u65E0\u9700\u9A8C\u8BC1",
49
- /** validate 成功 */
50
- VALIDATE_SUCCESS: (branch) => `\u2713 \u5DF2\u5C06\u5206\u652F ${branch} \u7684\u53D8\u66F4\u5E94\u7528\u5230\u4E3B worktree
51
- \u53EF\u4EE5\u5F00\u59CB\u9A8C\u8BC1\u4E86`,
47
+ /** 用户取消破坏性操作 */
48
+ DESTRUCTIVE_OP_CANCELLED: "\u5DF2\u53D6\u6D88\u64CD\u4F5C",
49
+ /** 请提供提交信息 */
50
+ COMMIT_MESSAGE_REQUIRED: "\u8BF7\u63D0\u4F9B\u63D0\u4EA4\u4FE1\u606F\uFF08-m \u53C2\u6570\uFF09",
51
+ /** 配置文件损坏,已重新生成默认配置 */
52
+ CONFIG_CORRUPTED: "\u914D\u7F6E\u6587\u4EF6\u635F\u574F\u6216\u65E0\u6CD5\u89E3\u6790\uFF0C\u5DF2\u91CD\u65B0\u751F\u6210\u9ED8\u8BA4\u914D\u7F6E",
53
+ /** worktree 状态获取失败 */
54
+ WORKTREE_STATUS_UNAVAILABLE: "(\u72B6\u6001\u4E0D\u53EF\u7528)",
55
+ /** 分隔线 */
56
+ SEPARATOR: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
57
+ /** 粗分隔线 */
58
+ DOUBLE_SEPARATOR: "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"
59
+ };
60
+
61
+ // src/constants/messages/run.ts
62
+ var RUN_MESSAGES = {
63
+ /** 分支已存在时提示使用 resume */
64
+ BRANCH_EXISTS_USE_RESUME: (name) => `\u5206\u652F ${name} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u4F7F\u7528 clawt resume -b ${name} \u6062\u590D\u4F1A\u8BDD`,
65
+ /** 检测到用户中断 */
66
+ INTERRUPTED: "\u68C0\u6D4B\u5230\u9000\u51FA\u6307\u4EE4\uFF0C\u5DF2\u505C\u6B62 Claude Code \u4EFB\u52A1",
67
+ /** 中断后自动清理完成 */
68
+ INTERRUPT_AUTO_CLEANED: (count) => `\u2713 \u5DF2\u81EA\u52A8\u6E05\u7406 ${count} \u4E2A worktree \u548C\u5BF9\u5E94\u5206\u652F`,
69
+ /** 中断后手动确认清理 */
70
+ INTERRUPT_CONFIRM_CLEANUP: "\u662F\u5426\u79FB\u9664\u521A\u521A\u521B\u5EFA\u7684 worktree \u548C\u5BF9\u5E94\u5206\u652F\uFF1F",
71
+ /** 中断后清理完成 */
72
+ INTERRUPT_CLEANED: (count) => `\u2713 \u5DF2\u6E05\u7406 ${count} \u4E2A worktree \u548C\u5BF9\u5E94\u5206\u652F`,
73
+ /** 中断后保留 worktree */
74
+ INTERRUPT_KEPT: "\u5DF2\u4FDD\u7559 worktree\uFF0C\u53EF\u7A0D\u540E\u4F7F\u7528 clawt remove \u624B\u52A8\u6E05\u7406"
75
+ };
76
+
77
+ // src/constants/messages/create.ts
78
+ var CREATE_MESSAGES = {
79
+ /** 创建数量参数无效 */
80
+ INVALID_COUNT: (value) => `\u65E0\u6548\u7684\u521B\u5EFA\u6570\u91CF: "${value}"\uFF0C\u8BF7\u8F93\u5165\u6B63\u6574\u6570`
81
+ };
82
+
83
+ // src/constants/messages/merge.ts
84
+ var MERGE_MESSAGES = {
52
85
  /** merge 成功 */
53
86
  MERGE_SUCCESS: (branch, message, pushed) => `\u2713 \u5206\u652F ${branch} \u5DF2\u6210\u529F\u5408\u5E76\u5230\u5F53\u524D\u5206\u652F
54
87
  \u63D0\u4EA4\u4FE1\u606F: ${message}${pushed ? "\n \u5DF2\u63A8\u9001\u5230\u8FDC\u7A0B\u4ED3\u5E93" : ""}`,
@@ -58,57 +91,12 @@ var MESSAGES = {
58
91
  MERGE_CONFLICT: "\u5408\u5E76\u5B58\u5728\u51B2\u7A81\uFF0C\u8BF7\u624B\u52A8\u5904\u7406\uFF1A\n \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git merge --continue",
59
92
  /** merge 后清理 worktree 和分支成功 */
60
93
  WORKTREE_CLEANED: (branch) => `\u2713 \u5DF2\u6E05\u7406 worktree \u548C\u5206\u652F: ${branch}`,
61
- /** 请提供提交信息 */
62
- COMMIT_MESSAGE_REQUIRED: "\u8BF7\u63D0\u4F9B\u63D0\u4EA4\u4FE1\u606F\uFF08-m \u53C2\u6570\uFF09",
63
94
  /** 目标 worktree 有未提交修改但未指定 -m */
64
95
  TARGET_WORKTREE_DIRTY_NO_MESSAGE: "\u76EE\u6807 worktree \u6709\u672A\u63D0\u4EA4\u7684\u4FEE\u6539\uFF0C\u8BF7\u901A\u8FC7 -m \u53C2\u6570\u63D0\u4F9B\u63D0\u4EA4\u4FE1\u606F",
65
96
  /** 目标 worktree 既干净又无本地提交 */
66
97
  TARGET_WORKTREE_NO_CHANGES: "\u76EE\u6807 worktree \u6CA1\u6709\u4EFB\u4F55\u53EF\u5408\u5E76\u7684\u53D8\u66F4\uFF08\u5DE5\u4F5C\u533A\u5E72\u51C0\u4E14\u65E0\u672C\u5730\u63D0\u4EA4\uFF09",
67
- /** 检测到用户中断 */
68
- INTERRUPTED: "\u68C0\u6D4B\u5230\u9000\u51FA\u6307\u4EE4\uFF0C\u5DF2\u505C\u6B62 Claude Code \u4EFB\u52A1",
69
- /** 中断后自动清理完成 */
70
- INTERRUPT_AUTO_CLEANED: (count) => `\u2713 \u5DF2\u81EA\u52A8\u6E05\u7406 ${count} \u4E2A worktree \u548C\u5BF9\u5E94\u5206\u652F`,
71
- /** 中断后手动确认清理 */
72
- INTERRUPT_CONFIRM_CLEANUP: "\u662F\u5426\u79FB\u9664\u521A\u521A\u521B\u5EFA\u7684 worktree \u548C\u5BF9\u5E94\u5206\u652F\uFF1F",
73
- /** 中断后清理完成 */
74
- INTERRUPT_CLEANED: (count) => `\u2713 \u5DF2\u6E05\u7406 ${count} \u4E2A worktree \u548C\u5BF9\u5E94\u5206\u652F`,
75
- /** 中断后保留 worktree */
76
- INTERRUPT_KEPT: "\u5DF2\u4FDD\u7559 worktree\uFF0C\u53EF\u7A0D\u540E\u4F7F\u7528 clawt remove \u624B\u52A8\u6E05\u7406",
77
- /** 配置文件损坏,已重新生成默认配置 */
78
- CONFIG_CORRUPTED: "\u914D\u7F6E\u6587\u4EF6\u635F\u574F\u6216\u65E0\u6CD5\u89E3\u6790\uFF0C\u5DF2\u91CD\u65B0\u751F\u6210\u9ED8\u8BA4\u914D\u7F6E",
79
- /** 配置已恢复为默认值 */
80
- CONFIG_RESET_SUCCESS: "\u2713 \u914D\u7F6E\u5DF2\u6062\u590D\u4E3A\u9ED8\u8BA4\u503C",
81
- /** 分隔线 */
82
- SEPARATOR: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
83
- /** 粗分隔线 */
84
- DOUBLE_SEPARATOR: "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550",
85
- /** 创建数量参数无效 */
86
- INVALID_COUNT: (value) => `\u65E0\u6548\u7684\u521B\u5EFA\u6570\u91CF: "${value}"\uFF0C\u8BF7\u8F93\u5165\u6B63\u6574\u6570`,
87
- /** worktree 状态获取失败 */
88
- WORKTREE_STATUS_UNAVAILABLE: "(\u72B6\u6001\u4E0D\u53EF\u7528)",
89
- /** 增量 validate 成功提示 */
90
- INCREMENTAL_VALIDATE_SUCCESS: (branch) => `\u2713 \u5DF2\u5C06\u5206\u652F ${branch} \u7684\u6700\u65B0\u53D8\u66F4\u5E94\u7528\u5230\u4E3B worktree\uFF08\u589E\u91CF\u6A21\u5F0F\uFF09
91
- \u6682\u5B58\u533A = \u4E0A\u6B21\u5FEB\u7167\uFF0C\u5DE5\u4F5C\u76EE\u5F55 = \u6700\u65B0\u53D8\u66F4`,
92
- /** 增量 validate 降级为全量模式提示 */
93
- INCREMENTAL_VALIDATE_FALLBACK: "\u589E\u91CF\u5BF9\u6BD4\u5931\u8D25\uFF0C\u5DF2\u964D\u7EA7\u4E3A\u5168\u91CF\u6A21\u5F0F",
94
- /** validate 状态已清理 */
95
- VALIDATE_CLEANED: (branch) => `\u2713 \u5206\u652F ${branch} \u7684 validate \u72B6\u6001\u5DF2\u6E05\u7406`,
96
98
  /** merge 命令检测到 validate 状态的提示 */
97
99
  MERGE_VALIDATE_STATE_HINT: (branch) => `\u4E3B worktree \u53EF\u80FD\u5B58\u5728 validate \u6B8B\u7559\u72B6\u6001\uFF0C\u53EF\u5148\u6267\u884C clawt validate -b ${branch} --clean \u6E05\u7406`,
98
- /** sync 自动保存未提交变更 */
99
- SYNC_AUTO_COMMITTED: (branch) => `\u5DF2\u81EA\u52A8\u4FDD\u5B58 ${branch} \u5206\u652F\u7684\u672A\u63D0\u4EA4\u53D8\u66F4`,
100
- /** sync 开始合并 */
101
- SYNC_MERGING: (targetBranch, mainBranch) => `\u6B63\u5728\u5C06 ${mainBranch} \u5408\u5E76\u5230 ${targetBranch} ...`,
102
- /** sync 成功 */
103
- SYNC_SUCCESS: (targetBranch, mainBranch) => `\u2713 \u5DF2\u5C06 ${mainBranch} \u7684\u6700\u65B0\u4EE3\u7801\u540C\u6B65\u5230 ${targetBranch}`,
104
- /** sync 冲突 */
105
- SYNC_CONFLICT: (worktreePath) => `\u5408\u5E76\u5B58\u5728\u51B2\u7A81\uFF0C\u8BF7\u8FDB\u5165\u76EE\u6807 worktree \u624B\u52A8\u89E3\u51B3\uFF1A
106
- cd ${worktreePath}
107
- \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git merge --continue
108
- clawt validate -b <branch> \u9A8C\u8BC1\u53D8\u66F4`,
109
- /** validate patch apply 失败,提示用户同步主分支 */
110
- VALIDATE_PATCH_APPLY_FAILED: (branch) => `\u53D8\u66F4\u8FC1\u79FB\u5931\u8D25\uFF1A\u76EE\u6807\u5206\u652F\u4E0E\u4E3B\u5206\u652F\u5DEE\u5F02\u8FC7\u5927
111
- \u8BF7\u5148\u6267\u884C clawt sync -b ${branch} \u540C\u6B65\u4E3B\u5206\u652F\u540E\u91CD\u8BD5`,
112
100
  /** merge 检测到 auto-save 提交,提示用户是否压缩 */
113
101
  MERGE_SQUASH_PROMPT: "\u68C0\u6D4B\u5230 sync \u4EA7\u751F\u7684\u4E34\u65F6\u63D0\u4EA4\uFF0C\u662F\u5426\u5C06\u6240\u6709\u63D0\u4EA4\u538B\u7F29\u4E3A\u4E00\u4E2A\uFF1F\n \u538B\u7F29\u540E\u53D8\u66F4\u5C06\u4FDD\u7559\u5728\u76EE\u6807worktree\u7684\u6682\u5B58\u533A\uFF0C\u9700\u8981\u91CD\u65B0\u63D0\u4EA4\uFF08\u53EF\u4F7F\u7528 Claude Code Cli\u6216\u5176\u4ED6\u5DE5\u5177\u751F\u6210\u63D0\u4EA4\u4FE1\u606F\uFF09",
114
102
  /** squash 完成且通过 -m 直接提交后的提示 */
@@ -118,25 +106,37 @@ var MESSAGES = {
118
106
  \u8BF7\u5728\u76EE\u6807 worktree \u4E2D\u63D0\u4EA4\u540E\u91CD\u65B0\u6267\u884C merge\uFF1A
119
107
  cd ${worktreePath}
120
108
  \u63D0\u4EA4\u5B8C\u6210\u540E\u6267\u884C\uFF1Aclawt merge -b ${branch}`,
121
- /** 用户取消破坏性操作 */
122
- DESTRUCTIVE_OP_CANCELLED: "\u5DF2\u53D6\u6D88\u64CD\u4F5C",
123
- /** reset 成功 */
124
- RESET_SUCCESS: "\u2713 \u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\u5DF2\u91CD\u7F6E",
125
- /** reset 时工作区和暂存区已干净 */
126
- RESET_ALREADY_CLEAN: "\u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\u5DF2\u662F\u5E72\u51C0\u72B6\u6001\uFF0C\u65E0\u9700\u91CD\u7F6E",
127
- /** 批量移除部分失败 */
128
- REMOVE_PARTIAL_FAILURE: (failures) => `\u4EE5\u4E0B worktree \u79FB\u9664\u5931\u8D25\uFF1A
129
- ${failures.map((f) => ` \u2717 ${f.path}: ${f.error}`).join("\n")}`,
130
- /** resume 无可用 worktree */
131
- RESUME_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA",
132
- /** resume 模糊匹配无结果,列出可用分支 */
133
- RESUME_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
109
+ /** merge 后 pull 冲突 */
110
+ PULL_CONFLICT: "\u81EA\u52A8 pull \u65F6\u53D1\u751F\u51B2\u7A81\uFF0Cmerge \u5DF2\u5B8C\u6210\u4F46\u8FDC\u7A0B\u540C\u6B65\u5931\u8D25\n \u8BF7\u624B\u52A8\u89E3\u51B3\u51B2\u7A81\uFF1A\n \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git commit\n \u7136\u540E\u6267\u884C git push \u63A8\u9001\u5230\u8FDC\u7A0B",
111
+ /** push 失败 */
112
+ PUSH_FAILED: "\u81EA\u52A8 push \u5931\u8D25\uFF0Cmerge \u548C pull \u5DF2\u5B8C\u6210\n \u8BF7\u624B\u52A8\u6267\u884C git push",
113
+ /** merge 无可用 worktree */
114
+ MERGE_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA",
115
+ /** merge 模糊匹配无结果,列出可用分支 */
116
+ MERGE_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
134
117
  \u53EF\u7528\u5206\u652F\uFF1A
135
118
  ${branches.map((b) => ` - ${b}`).join("\n")}`,
136
- /** resume 交互选择提示 */
137
- RESUME_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u6062\u590D\u7684\u5206\u652F",
138
- /** resume 模糊匹配到多个结果提示 */
139
- RESUME_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`,
119
+ /** merge 交互选择提示 */
120
+ MERGE_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u5408\u5E76\u7684\u5206\u652F",
121
+ /** merge 模糊匹配到多个结果提示 */
122
+ MERGE_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`
123
+ };
124
+
125
+ // src/constants/messages/validate.ts
126
+ var VALIDATE_MESSAGES = {
127
+ /** validate 成功 */
128
+ VALIDATE_SUCCESS: (branch) => `\u2713 \u5DF2\u5C06\u5206\u652F ${branch} \u7684\u53D8\u66F4\u5E94\u7528\u5230\u4E3B worktree
129
+ \u53EF\u4EE5\u5F00\u59CB\u9A8C\u8BC1\u4E86`,
130
+ /** 增量 validate 成功提示 */
131
+ INCREMENTAL_VALIDATE_SUCCESS: (branch) => `\u2713 \u5DF2\u5C06\u5206\u652F ${branch} \u7684\u6700\u65B0\u53D8\u66F4\u5E94\u7528\u5230\u4E3B worktree\uFF08\u589E\u91CF\u6A21\u5F0F\uFF09
132
+ \u6682\u5B58\u533A = \u4E0A\u6B21\u5FEB\u7167\uFF0C\u5DE5\u4F5C\u76EE\u5F55 = \u6700\u65B0\u53D8\u66F4`,
133
+ /** 增量 validate 降级为全量模式提示 */
134
+ INCREMENTAL_VALIDATE_FALLBACK: "\u589E\u91CF\u5BF9\u6BD4\u5931\u8D25\uFF0C\u5DF2\u964D\u7EA7\u4E3A\u5168\u91CF\u6A21\u5F0F",
135
+ /** validate 状态已清理 */
136
+ VALIDATE_CLEANED: (branch) => `\u2713 \u5206\u652F ${branch} \u7684 validate \u72B6\u6001\u5DF2\u6E05\u7406`,
137
+ /** validate patch apply 失败,提示用户同步主分支 */
138
+ VALIDATE_PATCH_APPLY_FAILED: (branch) => `\u53D8\u66F4\u8FC1\u79FB\u5931\u8D25\uFF1A\u76EE\u6807\u5206\u652F\u4E0E\u4E3B\u5206\u652F\u5DEE\u5F02\u8FC7\u5927
139
+ \u8BF7\u5148\u6267\u884C clawt sync -b ${branch} \u540C\u6B65\u4E3B\u5206\u652F\u540E\u91CD\u8BD5`,
140
140
  /** validate 无可用 worktree */
141
141
  VALIDATE_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA",
142
142
  /** validate 模糊匹配无结果,列出可用分支 */
@@ -146,17 +146,22 @@ ${branches.map((b) => ` - ${b}`).join("\n")}`,
146
146
  /** validate 交互选择提示 */
147
147
  VALIDATE_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u9A8C\u8BC1\u7684\u5206\u652F",
148
148
  /** validate 模糊匹配到多个结果提示 */
149
- VALIDATE_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`,
150
- /** merge 无可用 worktree */
151
- MERGE_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA",
152
- /** merge 模糊匹配无结果,列出可用分支 */
153
- MERGE_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
154
- \u53EF\u7528\u5206\u652F\uFF1A
155
- ${branches.map((b) => ` - ${b}`).join("\n")}`,
156
- /** merge 交互选择提示 */
157
- MERGE_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u5408\u5E76\u7684\u5206\u652F",
158
- /** merge 模糊匹配到多个结果提示 */
159
- MERGE_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`,
149
+ VALIDATE_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`
150
+ };
151
+
152
+ // src/constants/messages/sync.ts
153
+ var SYNC_MESSAGES = {
154
+ /** sync 自动保存未提交变更 */
155
+ SYNC_AUTO_COMMITTED: (branch) => `\u5DF2\u81EA\u52A8\u4FDD\u5B58 ${branch} \u5206\u652F\u7684\u672A\u63D0\u4EA4\u53D8\u66F4`,
156
+ /** sync 开始合并 */
157
+ SYNC_MERGING: (targetBranch, mainBranch) => `\u6B63\u5728\u5C06 ${mainBranch} \u5408\u5E76\u5230 ${targetBranch} ...`,
158
+ /** sync 成功 */
159
+ SYNC_SUCCESS: (targetBranch, mainBranch) => `\u2713 \u5DF2\u5C06 ${mainBranch} \u7684\u6700\u65B0\u4EE3\u7801\u540C\u6B65\u5230 ${targetBranch}`,
160
+ /** sync 冲突 */
161
+ SYNC_CONFLICT: (worktreePath) => `\u5408\u5E76\u5B58\u5728\u51B2\u7A81\uFF0C\u8BF7\u8FDB\u5165\u76EE\u6807 worktree \u624B\u52A8\u89E3\u51B3\uFF1A
162
+ cd ${worktreePath}
163
+ \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git merge --continue
164
+ clawt validate -b <branch> \u9A8C\u8BC1\u53D8\u66F4`,
160
165
  /** sync 无可用 worktree */
161
166
  SYNC_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA",
162
167
  /** sync 模糊匹配无结果,列出可用分支 */
@@ -166,7 +171,56 @@ ${branches.map((b) => ` - ${b}`).join("\n")}`,
166
171
  /** sync 交互选择提示 */
167
172
  SYNC_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u540C\u6B65\u7684\u5206\u652F",
168
173
  /** sync 模糊匹配到多个结果提示 */
169
- SYNC_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`,
174
+ SYNC_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`
175
+ };
176
+
177
+ // src/constants/messages/resume.ts
178
+ var RESUME_MESSAGES = {
179
+ /** resume 无可用 worktree */
180
+ RESUME_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA",
181
+ /** resume 模糊匹配无结果,列出可用分支 */
182
+ RESUME_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
183
+ \u53EF\u7528\u5206\u652F\uFF1A
184
+ ${branches.map((b) => ` - ${b}`).join("\n")}`,
185
+ /** resume 交互选择提示 */
186
+ RESUME_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u6062\u590D\u7684\u5206\u652F",
187
+ /** resume 模糊匹配到多个结果提示 */
188
+ RESUME_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`
189
+ };
190
+
191
+ // src/constants/messages/remove.ts
192
+ var REMOVE_MESSAGES = {
193
+ /** remove 无可用 worktree */
194
+ REMOVE_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u65E0\u9700\u79FB\u9664",
195
+ /** remove 多选交互提示 */
196
+ REMOVE_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u79FB\u9664\u7684\u5206\u652F\uFF08\u7A7A\u683C\u9009\u62E9\uFF0C\u56DE\u8F66\u786E\u8BA4\uFF09",
197
+ /** remove 模糊匹配到多个结果提示 */
198
+ REMOVE_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\u8981\u79FB\u9664\u7684\uFF08\u7A7A\u683C\u9009\u62E9\uFF0C\u56DE\u8F66\u786E\u8BA4\uFF09\uFF1A`,
199
+ /** remove 模糊匹配无结果,列出可用分支 */
200
+ REMOVE_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
201
+ \u53EF\u7528\u5206\u652F\uFF1A
202
+ ${branches.map((b) => ` - ${b}`).join("\n")}`,
203
+ /** 批量移除部分失败 */
204
+ REMOVE_PARTIAL_FAILURE: (failures) => `\u4EE5\u4E0B worktree \u79FB\u9664\u5931\u8D25\uFF1A
205
+ ${failures.map((f) => ` \u2717 ${f.path}: ${f.error}`).join("\n")}`
206
+ };
207
+
208
+ // src/constants/messages/reset.ts
209
+ var RESET_MESSAGES = {
210
+ /** reset 成功 */
211
+ RESET_SUCCESS: "\u2713 \u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\u5DF2\u91CD\u7F6E",
212
+ /** reset 时工作区和暂存区已干净 */
213
+ RESET_ALREADY_CLEAN: "\u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\u5DF2\u662F\u5E72\u51C0\u72B6\u6001\uFF0C\u65E0\u9700\u91CD\u7F6E"
214
+ };
215
+
216
+ // src/constants/messages/config.ts
217
+ var CONFIG_CMD_MESSAGES = {
218
+ /** 配置已恢复为默认值 */
219
+ CONFIG_RESET_SUCCESS: "\u2713 \u914D\u7F6E\u5DF2\u6062\u590D\u4E3A\u9ED8\u8BA4\u503C"
220
+ };
221
+
222
+ // src/constants/messages/status.ts
223
+ var STATUS_MESSAGES = {
170
224
  /** status 命令标题 */
171
225
  STATUS_TITLE: (projectName) => `\u9879\u76EE\u72B6\u6001\u603B\u89C8: ${projectName}`,
172
226
  /** status 主 worktree 区块标题 */
@@ -188,11 +242,22 @@ ${branches.map((b) => ` - ${b}`).join("\n")}`,
188
242
  /** status 变更状态:无变更 */
189
243
  STATUS_CHANGE_CLEAN: "\u65E0\u53D8\u66F4",
190
244
  /** status 快照对应 worktree 已不存在 */
191
- STATUS_SNAPSHOT_ORPHANED: "(\u5BF9\u5E94 worktree \u5DF2\u4E0D\u5B58\u5728)",
192
- /** merge 后 pull 冲突 */
193
- PULL_CONFLICT: "\u81EA\u52A8 pull \u65F6\u53D1\u751F\u51B2\u7A81\uFF0Cmerge \u5DF2\u5B8C\u6210\u4F46\u8FDC\u7A0B\u540C\u6B65\u5931\u8D25\n \u8BF7\u624B\u52A8\u89E3\u51B3\u51B2\u7A81\uFF1A\n \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git commit\n \u7136\u540E\u6267\u884C git push \u63A8\u9001\u5230\u8FDC\u7A0B",
194
- /** push 失败 */
195
- PUSH_FAILED: "\u81EA\u52A8 push \u5931\u8D25\uFF0Cmerge \u548C pull \u5DF2\u5B8C\u6210\n \u8BF7\u624B\u52A8\u6267\u884C git push"
245
+ STATUS_SNAPSHOT_ORPHANED: "(\u5BF9\u5E94 worktree \u5DF2\u4E0D\u5B58\u5728)"
246
+ };
247
+
248
+ // src/constants/messages/index.ts
249
+ var MESSAGES = {
250
+ ...COMMON_MESSAGES,
251
+ ...RUN_MESSAGES,
252
+ ...CREATE_MESSAGES,
253
+ ...MERGE_MESSAGES,
254
+ ...VALIDATE_MESSAGES,
255
+ ...SYNC_MESSAGES,
256
+ ...RESUME_MESSAGES,
257
+ ...REMOVE_MESSAGES,
258
+ ...RESET_MESSAGES,
259
+ ...CONFIG_CMD_MESSAGES,
260
+ ...STATUS_MESSAGES
196
261
  };
197
262
 
198
263
  // src/constants/exitCodes.ts
@@ -871,6 +936,44 @@ async function promptSelectBranch(worktrees, message) {
871
936
  }).run();
872
937
  return worktrees.find((wt) => wt.branch === selectedBranch);
873
938
  }
939
+ async function promptMultiSelectBranches(worktrees, message) {
940
+ const selectedBranches = await new Enquirer2.MultiSelect({
941
+ message,
942
+ choices: worktrees.map((wt) => ({
943
+ name: wt.branch,
944
+ message: wt.branch
945
+ })),
946
+ // 使用空心圆/实心圆作为选中指示符
947
+ symbols: {
948
+ indicator: { on: "\u25CF", off: "\u25CB" }
949
+ }
950
+ }).run();
951
+ return worktrees.filter((wt) => selectedBranches.includes(wt.branch));
952
+ }
953
+ async function resolveTargetWorktrees(worktrees, messages, branchName) {
954
+ if (worktrees.length === 0) {
955
+ throw new ClawtError(messages.noWorktrees);
956
+ }
957
+ if (!branchName) {
958
+ if (worktrees.length === 1) {
959
+ return [worktrees[0]];
960
+ }
961
+ return promptMultiSelectBranches(worktrees, messages.selectBranch);
962
+ }
963
+ const exactMatch = findExactMatch(worktrees, branchName);
964
+ if (exactMatch) {
965
+ return [exactMatch];
966
+ }
967
+ const fuzzyMatches = findFuzzyMatches(worktrees, branchName);
968
+ if (fuzzyMatches.length === 1) {
969
+ return [fuzzyMatches[0]];
970
+ }
971
+ if (fuzzyMatches.length > 1) {
972
+ return promptMultiSelectBranches(fuzzyMatches, messages.multipleMatches(branchName));
973
+ }
974
+ const allBranches = worktrees.map((wt) => wt.branch);
975
+ throw new ClawtError(messages.noMatch(branchName, allBranches));
976
+ }
874
977
  async function resolveTargetWorktree(worktrees, messages, branchName) {
875
978
  if (worktrees.length === 0) {
876
979
  throw new ClawtError(messages.noWorktrees);
@@ -975,32 +1078,28 @@ function handleCreate(options) {
975
1078
  }
976
1079
 
977
1080
  // src/commands/remove.ts
1081
+ var REMOVE_RESOLVE_MESSAGES = {
1082
+ noWorktrees: MESSAGES.REMOVE_NO_WORKTREES,
1083
+ selectBranch: MESSAGES.REMOVE_SELECT_BRANCH,
1084
+ multipleMatches: MESSAGES.REMOVE_MULTIPLE_MATCHES,
1085
+ noMatch: MESSAGES.REMOVE_NO_MATCH
1086
+ };
978
1087
  function registerRemoveCommand(program2) {
979
- program2.command("remove").description("\u79FB\u9664 worktree\uFF08\u652F\u6301\u5355\u4E2A/\u6279\u91CF/\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\u5B8C\u6574\u5206\u652F\u540D\u7CBE\u786E\u5339\u914D\uFF09").action(async (options) => {
1088
+ program2.command("remove").description("\u79FB\u9664 worktree\uFF08\u652F\u6301\u5355\u4E2A/\u6279\u91CF/\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) => {
980
1089
  await handleRemove(options);
981
1090
  });
982
1091
  }
983
- function resolveWorktreesToRemove(options) {
984
- const allWorktrees = getProjectWorktrees();
985
- if (options.all) {
986
- return allWorktrees;
987
- }
988
- if (!options.branch) {
989
- throw new ClawtError("\u8BF7\u6307\u5B9A --all \u6216 -b <branchName> \u53C2\u6570");
990
- }
991
- const matched = allWorktrees.filter(
992
- (wt) => wt.branch === options.branch || wt.branch.startsWith(`${options.branch}-`)
993
- );
994
- if (matched.length === 0) {
995
- throw new ClawtError(MESSAGES.WORKTREE_NOT_FOUND(options.branch));
996
- }
997
- return matched;
998
- }
999
1092
  async function handleRemove(options) {
1000
1093
  validateMainWorktree();
1001
1094
  const projectName = getProjectName();
1002
1095
  logger.info(`remove \u547D\u4EE4\u6267\u884C\uFF0C\u9879\u76EE: ${projectName}`);
1003
- const worktreesToRemove = resolveWorktreesToRemove(options);
1096
+ const allWorktrees = getProjectWorktrees();
1097
+ let worktreesToRemove;
1098
+ if (options.all) {
1099
+ worktreesToRemove = allWorktrees;
1100
+ } else {
1101
+ worktreesToRemove = await resolveTargetWorktrees(allWorktrees, REMOVE_RESOLVE_MESSAGES, options.branch);
1102
+ }
1004
1103
  if (worktreesToRemove.length === 0) {
1005
1104
  printInfo(MESSAGES.NO_WORKTREES);
1006
1105
  return;
@@ -10,6 +10,248 @@ var LOGS_DIR = join(CLAWT_HOME, "logs");
10
10
  var WORKTREES_DIR = join(CLAWT_HOME, "worktrees");
11
11
  var VALIDATE_SNAPSHOTS_DIR = join(CLAWT_HOME, "validate-snapshots");
12
12
 
13
+ // src/constants/messages/common.ts
14
+ var COMMON_MESSAGES = {
15
+ /** 不在主 worktree 根目录 */
16
+ NOT_MAIN_WORKTREE: "\u8BF7\u5728\u4E3B worktree \u7684\u6839\u76EE\u5F55\u4E0B\u6267\u884C clawt",
17
+ /** Git 未安装 */
18
+ GIT_NOT_INSTALLED: "Git \u672A\u5B89\u88C5\u6216\u4E0D\u5728 PATH \u4E2D\uFF0C\u8BF7\u5148\u5B89\u88C5 Git",
19
+ /** Claude Code CLI 未安装 */
20
+ CLAUDE_NOT_INSTALLED: "Claude Code CLI \u672A\u5B89\u88C5\uFF0C\u8BF7\u5148\u5B89\u88C5\uFF1Anpm install -g @anthropic-ai/claude-code",
21
+ /** 分支已存在 */
22
+ BRANCH_EXISTS: (name) => `\u5206\u652F ${name} \u5DF2\u5B58\u5728\uFF0C\u65E0\u6CD5\u521B\u5EFA`,
23
+ /** 分支名清理后为空 */
24
+ BRANCH_NAME_EMPTY: (original) => `\u5206\u652F\u540D "${original}" \u4E2D\u4E0D\u5305\u542B\u5408\u6CD5\u5B57\u7B26\uFF0C\u65E0\u6CD5\u521B\u5EFA\u5206\u652F`,
25
+ /** 分支名被转换 */
26
+ BRANCH_SANITIZED: (original, sanitized) => `\u5206\u652F\u540D\u5DF2\u8F6C\u6362: ${original} \u2192 ${sanitized}`,
27
+ /** worktree 创建成功 */
28
+ WORKTREE_CREATED: (count) => `\u2713 \u5DF2\u521B\u5EFA ${count} \u4E2A worktree`,
29
+ /** worktree 移除成功 */
30
+ WORKTREE_REMOVED: (path) => `\u2713 \u5DF2\u79FB\u9664 worktree: ${path}`,
31
+ /** 没有 worktree */
32
+ NO_WORKTREES: "(\u65E0 worktree)",
33
+ /** 目标 worktree 不存在 */
34
+ WORKTREE_NOT_FOUND: (name) => `worktree ${name} \u4E0D\u5B58\u5728`,
35
+ /** 主 worktree 有未提交更改 */
36
+ MAIN_WORKTREE_DIRTY: "\u4E3B worktree \u6709\u672A\u63D0\u4EA4\u7684\u66F4\u6539\uFF0C\u8BF7\u5148\u5904\u7406",
37
+ /** 目标 worktree 无更改 */
38
+ TARGET_WORKTREE_CLEAN: "\u8BE5 worktree \u7684\u5206\u652F\u4E0A\u6CA1\u6709\u4EFB\u4F55\u66F4\u6539\uFF0C\u65E0\u9700\u9A8C\u8BC1",
39
+ /** 用户取消破坏性操作 */
40
+ DESTRUCTIVE_OP_CANCELLED: "\u5DF2\u53D6\u6D88\u64CD\u4F5C",
41
+ /** 请提供提交信息 */
42
+ COMMIT_MESSAGE_REQUIRED: "\u8BF7\u63D0\u4F9B\u63D0\u4EA4\u4FE1\u606F\uFF08-m \u53C2\u6570\uFF09",
43
+ /** 配置文件损坏,已重新生成默认配置 */
44
+ CONFIG_CORRUPTED: "\u914D\u7F6E\u6587\u4EF6\u635F\u574F\u6216\u65E0\u6CD5\u89E3\u6790\uFF0C\u5DF2\u91CD\u65B0\u751F\u6210\u9ED8\u8BA4\u914D\u7F6E",
45
+ /** worktree 状态获取失败 */
46
+ WORKTREE_STATUS_UNAVAILABLE: "(\u72B6\u6001\u4E0D\u53EF\u7528)",
47
+ /** 分隔线 */
48
+ SEPARATOR: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",
49
+ /** 粗分隔线 */
50
+ DOUBLE_SEPARATOR: "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"
51
+ };
52
+
53
+ // src/constants/messages/run.ts
54
+ var RUN_MESSAGES = {
55
+ /** 分支已存在时提示使用 resume */
56
+ BRANCH_EXISTS_USE_RESUME: (name) => `\u5206\u652F ${name} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u4F7F\u7528 clawt resume -b ${name} \u6062\u590D\u4F1A\u8BDD`,
57
+ /** 检测到用户中断 */
58
+ INTERRUPTED: "\u68C0\u6D4B\u5230\u9000\u51FA\u6307\u4EE4\uFF0C\u5DF2\u505C\u6B62 Claude Code \u4EFB\u52A1",
59
+ /** 中断后自动清理完成 */
60
+ INTERRUPT_AUTO_CLEANED: (count) => `\u2713 \u5DF2\u81EA\u52A8\u6E05\u7406 ${count} \u4E2A worktree \u548C\u5BF9\u5E94\u5206\u652F`,
61
+ /** 中断后手动确认清理 */
62
+ INTERRUPT_CONFIRM_CLEANUP: "\u662F\u5426\u79FB\u9664\u521A\u521A\u521B\u5EFA\u7684 worktree \u548C\u5BF9\u5E94\u5206\u652F\uFF1F",
63
+ /** 中断后清理完成 */
64
+ INTERRUPT_CLEANED: (count) => `\u2713 \u5DF2\u6E05\u7406 ${count} \u4E2A worktree \u548C\u5BF9\u5E94\u5206\u652F`,
65
+ /** 中断后保留 worktree */
66
+ INTERRUPT_KEPT: "\u5DF2\u4FDD\u7559 worktree\uFF0C\u53EF\u7A0D\u540E\u4F7F\u7528 clawt remove \u624B\u52A8\u6E05\u7406"
67
+ };
68
+
69
+ // src/constants/messages/create.ts
70
+ var CREATE_MESSAGES = {
71
+ /** 创建数量参数无效 */
72
+ INVALID_COUNT: (value) => `\u65E0\u6548\u7684\u521B\u5EFA\u6570\u91CF: "${value}"\uFF0C\u8BF7\u8F93\u5165\u6B63\u6574\u6570`
73
+ };
74
+
75
+ // src/constants/messages/merge.ts
76
+ var MERGE_MESSAGES = {
77
+ /** merge 成功 */
78
+ MERGE_SUCCESS: (branch, message, pushed) => `\u2713 \u5206\u652F ${branch} \u5DF2\u6210\u529F\u5408\u5E76\u5230\u5F53\u524D\u5206\u652F
79
+ \u63D0\u4EA4\u4FE1\u606F: ${message}${pushed ? "\n \u5DF2\u63A8\u9001\u5230\u8FDC\u7A0B\u4ED3\u5E93" : ""}`,
80
+ /** merge 成功(无提交信息,目标 worktree 已提交过) */
81
+ MERGE_SUCCESS_NO_MESSAGE: (branch, pushed) => `\u2713 \u5206\u652F ${branch} \u5DF2\u6210\u529F\u5408\u5E76\u5230\u5F53\u524D\u5206\u652F${pushed ? "\n \u5DF2\u63A8\u9001\u5230\u8FDC\u7A0B\u4ED3\u5E93" : ""}`,
82
+ /** merge 冲突 */
83
+ MERGE_CONFLICT: "\u5408\u5E76\u5B58\u5728\u51B2\u7A81\uFF0C\u8BF7\u624B\u52A8\u5904\u7406\uFF1A\n \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git merge --continue",
84
+ /** merge 后清理 worktree 和分支成功 */
85
+ WORKTREE_CLEANED: (branch) => `\u2713 \u5DF2\u6E05\u7406 worktree \u548C\u5206\u652F: ${branch}`,
86
+ /** 目标 worktree 有未提交修改但未指定 -m */
87
+ TARGET_WORKTREE_DIRTY_NO_MESSAGE: "\u76EE\u6807 worktree \u6709\u672A\u63D0\u4EA4\u7684\u4FEE\u6539\uFF0C\u8BF7\u901A\u8FC7 -m \u53C2\u6570\u63D0\u4F9B\u63D0\u4EA4\u4FE1\u606F",
88
+ /** 目标 worktree 既干净又无本地提交 */
89
+ TARGET_WORKTREE_NO_CHANGES: "\u76EE\u6807 worktree \u6CA1\u6709\u4EFB\u4F55\u53EF\u5408\u5E76\u7684\u53D8\u66F4\uFF08\u5DE5\u4F5C\u533A\u5E72\u51C0\u4E14\u65E0\u672C\u5730\u63D0\u4EA4\uFF09",
90
+ /** merge 命令检测到 validate 状态的提示 */
91
+ MERGE_VALIDATE_STATE_HINT: (branch) => `\u4E3B worktree \u53EF\u80FD\u5B58\u5728 validate \u6B8B\u7559\u72B6\u6001\uFF0C\u53EF\u5148\u6267\u884C clawt validate -b ${branch} --clean \u6E05\u7406`,
92
+ /** merge 检测到 auto-save 提交,提示用户是否压缩 */
93
+ MERGE_SQUASH_PROMPT: "\u68C0\u6D4B\u5230 sync \u4EA7\u751F\u7684\u4E34\u65F6\u63D0\u4EA4\uFF0C\u662F\u5426\u5C06\u6240\u6709\u63D0\u4EA4\u538B\u7F29\u4E3A\u4E00\u4E2A\uFF1F\n \u538B\u7F29\u540E\u53D8\u66F4\u5C06\u4FDD\u7559\u5728\u76EE\u6807worktree\u7684\u6682\u5B58\u533A\uFF0C\u9700\u8981\u91CD\u65B0\u63D0\u4EA4\uFF08\u53EF\u4F7F\u7528 Claude Code Cli\u6216\u5176\u4ED6\u5DE5\u5177\u751F\u6210\u63D0\u4EA4\u4FE1\u606F\uFF09",
94
+ /** squash 完成且通过 -m 直接提交后的提示 */
95
+ MERGE_SQUASH_COMMITTED: (branch) => `\u2713 \u5DF2\u5C06\u5206\u652F ${branch} \u7684\u6240\u6709\u63D0\u4EA4\u538B\u7F29\u4E3A\u4E00\u4E2A`,
96
+ /** squash 完成但未提供 -m,提示用户自行提交 */
97
+ MERGE_SQUASH_PENDING: (worktreePath, branch) => `\u2713 \u5DF2\u5C06\u6240\u6709\u63D0\u4EA4\u538B\u7F29\u5230\u6682\u5B58\u533A
98
+ \u8BF7\u5728\u76EE\u6807 worktree \u4E2D\u63D0\u4EA4\u540E\u91CD\u65B0\u6267\u884C merge\uFF1A
99
+ cd ${worktreePath}
100
+ \u63D0\u4EA4\u5B8C\u6210\u540E\u6267\u884C\uFF1Aclawt merge -b ${branch}`,
101
+ /** merge 后 pull 冲突 */
102
+ PULL_CONFLICT: "\u81EA\u52A8 pull \u65F6\u53D1\u751F\u51B2\u7A81\uFF0Cmerge \u5DF2\u5B8C\u6210\u4F46\u8FDC\u7A0B\u540C\u6B65\u5931\u8D25\n \u8BF7\u624B\u52A8\u89E3\u51B3\u51B2\u7A81\uFF1A\n \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git commit\n \u7136\u540E\u6267\u884C git push \u63A8\u9001\u5230\u8FDC\u7A0B",
103
+ /** push 失败 */
104
+ PUSH_FAILED: "\u81EA\u52A8 push \u5931\u8D25\uFF0Cmerge \u548C pull \u5DF2\u5B8C\u6210\n \u8BF7\u624B\u52A8\u6267\u884C git push",
105
+ /** merge 无可用 worktree */
106
+ MERGE_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA",
107
+ /** merge 模糊匹配无结果,列出可用分支 */
108
+ MERGE_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
109
+ \u53EF\u7528\u5206\u652F\uFF1A
110
+ ${branches.map((b) => ` - ${b}`).join("\n")}`,
111
+ /** merge 交互选择提示 */
112
+ MERGE_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u5408\u5E76\u7684\u5206\u652F",
113
+ /** merge 模糊匹配到多个结果提示 */
114
+ MERGE_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`
115
+ };
116
+
117
+ // src/constants/messages/validate.ts
118
+ var VALIDATE_MESSAGES = {
119
+ /** validate 成功 */
120
+ VALIDATE_SUCCESS: (branch) => `\u2713 \u5DF2\u5C06\u5206\u652F ${branch} \u7684\u53D8\u66F4\u5E94\u7528\u5230\u4E3B worktree
121
+ \u53EF\u4EE5\u5F00\u59CB\u9A8C\u8BC1\u4E86`,
122
+ /** 增量 validate 成功提示 */
123
+ INCREMENTAL_VALIDATE_SUCCESS: (branch) => `\u2713 \u5DF2\u5C06\u5206\u652F ${branch} \u7684\u6700\u65B0\u53D8\u66F4\u5E94\u7528\u5230\u4E3B worktree\uFF08\u589E\u91CF\u6A21\u5F0F\uFF09
124
+ \u6682\u5B58\u533A = \u4E0A\u6B21\u5FEB\u7167\uFF0C\u5DE5\u4F5C\u76EE\u5F55 = \u6700\u65B0\u53D8\u66F4`,
125
+ /** 增量 validate 降级为全量模式提示 */
126
+ INCREMENTAL_VALIDATE_FALLBACK: "\u589E\u91CF\u5BF9\u6BD4\u5931\u8D25\uFF0C\u5DF2\u964D\u7EA7\u4E3A\u5168\u91CF\u6A21\u5F0F",
127
+ /** validate 状态已清理 */
128
+ VALIDATE_CLEANED: (branch) => `\u2713 \u5206\u652F ${branch} \u7684 validate \u72B6\u6001\u5DF2\u6E05\u7406`,
129
+ /** validate patch apply 失败,提示用户同步主分支 */
130
+ VALIDATE_PATCH_APPLY_FAILED: (branch) => `\u53D8\u66F4\u8FC1\u79FB\u5931\u8D25\uFF1A\u76EE\u6807\u5206\u652F\u4E0E\u4E3B\u5206\u652F\u5DEE\u5F02\u8FC7\u5927
131
+ \u8BF7\u5148\u6267\u884C clawt sync -b ${branch} \u540C\u6B65\u4E3B\u5206\u652F\u540E\u91CD\u8BD5`,
132
+ /** validate 无可用 worktree */
133
+ VALIDATE_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA",
134
+ /** validate 模糊匹配无结果,列出可用分支 */
135
+ VALIDATE_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
136
+ \u53EF\u7528\u5206\u652F\uFF1A
137
+ ${branches.map((b) => ` - ${b}`).join("\n")}`,
138
+ /** validate 交互选择提示 */
139
+ VALIDATE_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u9A8C\u8BC1\u7684\u5206\u652F",
140
+ /** validate 模糊匹配到多个结果提示 */
141
+ VALIDATE_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`
142
+ };
143
+
144
+ // src/constants/messages/sync.ts
145
+ var SYNC_MESSAGES = {
146
+ /** sync 自动保存未提交变更 */
147
+ SYNC_AUTO_COMMITTED: (branch) => `\u5DF2\u81EA\u52A8\u4FDD\u5B58 ${branch} \u5206\u652F\u7684\u672A\u63D0\u4EA4\u53D8\u66F4`,
148
+ /** sync 开始合并 */
149
+ SYNC_MERGING: (targetBranch, mainBranch) => `\u6B63\u5728\u5C06 ${mainBranch} \u5408\u5E76\u5230 ${targetBranch} ...`,
150
+ /** sync 成功 */
151
+ SYNC_SUCCESS: (targetBranch, mainBranch) => `\u2713 \u5DF2\u5C06 ${mainBranch} \u7684\u6700\u65B0\u4EE3\u7801\u540C\u6B65\u5230 ${targetBranch}`,
152
+ /** sync 冲突 */
153
+ SYNC_CONFLICT: (worktreePath) => `\u5408\u5E76\u5B58\u5728\u51B2\u7A81\uFF0C\u8BF7\u8FDB\u5165\u76EE\u6807 worktree \u624B\u52A8\u89E3\u51B3\uFF1A
154
+ cd ${worktreePath}
155
+ \u89E3\u51B3\u51B2\u7A81\u540E\u6267\u884C git add . && git merge --continue
156
+ clawt validate -b <branch> \u9A8C\u8BC1\u53D8\u66F4`,
157
+ /** sync 无可用 worktree */
158
+ SYNC_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA",
159
+ /** sync 模糊匹配无结果,列出可用分支 */
160
+ SYNC_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
161
+ \u53EF\u7528\u5206\u652F\uFF1A
162
+ ${branches.map((b) => ` - ${b}`).join("\n")}`,
163
+ /** sync 交互选择提示 */
164
+ SYNC_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u540C\u6B65\u7684\u5206\u652F",
165
+ /** sync 模糊匹配到多个结果提示 */
166
+ SYNC_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`
167
+ };
168
+
169
+ // src/constants/messages/resume.ts
170
+ var RESUME_MESSAGES = {
171
+ /** resume 无可用 worktree */
172
+ RESUME_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u8BF7\u5148\u901A\u8FC7 clawt run \u6216 clawt create \u521B\u5EFA",
173
+ /** resume 模糊匹配无结果,列出可用分支 */
174
+ RESUME_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
175
+ \u53EF\u7528\u5206\u652F\uFF1A
176
+ ${branches.map((b) => ` - ${b}`).join("\n")}`,
177
+ /** resume 交互选择提示 */
178
+ RESUME_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u6062\u590D\u7684\u5206\u652F",
179
+ /** resume 模糊匹配到多个结果提示 */
180
+ RESUME_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\uFF1A`
181
+ };
182
+
183
+ // src/constants/messages/remove.ts
184
+ var REMOVE_MESSAGES = {
185
+ /** remove 无可用 worktree */
186
+ REMOVE_NO_WORKTREES: "\u5F53\u524D\u9879\u76EE\u6CA1\u6709\u53EF\u7528\u7684 worktree\uFF0C\u65E0\u9700\u79FB\u9664",
187
+ /** remove 多选交互提示 */
188
+ REMOVE_SELECT_BRANCH: "\u8BF7\u9009\u62E9\u8981\u79FB\u9664\u7684\u5206\u652F\uFF08\u7A7A\u683C\u9009\u62E9\uFF0C\u56DE\u8F66\u786E\u8BA4\uFF09",
189
+ /** remove 模糊匹配到多个结果提示 */
190
+ REMOVE_MULTIPLE_MATCHES: (name) => `"${name}" \u5339\u914D\u5230\u591A\u4E2A\u5206\u652F\uFF0C\u8BF7\u9009\u62E9\u8981\u79FB\u9664\u7684\uFF08\u7A7A\u683C\u9009\u62E9\uFF0C\u56DE\u8F66\u786E\u8BA4\uFF09\uFF1A`,
191
+ /** remove 模糊匹配无结果,列出可用分支 */
192
+ REMOVE_NO_MATCH: (name, branches) => `\u672A\u627E\u5230\u4E0E "${name}" \u5339\u914D\u7684\u5206\u652F
193
+ \u53EF\u7528\u5206\u652F\uFF1A
194
+ ${branches.map((b) => ` - ${b}`).join("\n")}`,
195
+ /** 批量移除部分失败 */
196
+ REMOVE_PARTIAL_FAILURE: (failures) => `\u4EE5\u4E0B worktree \u79FB\u9664\u5931\u8D25\uFF1A
197
+ ${failures.map((f) => ` \u2717 ${f.path}: ${f.error}`).join("\n")}`
198
+ };
199
+
200
+ // src/constants/messages/reset.ts
201
+ var RESET_MESSAGES = {
202
+ /** reset 成功 */
203
+ RESET_SUCCESS: "\u2713 \u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\u5DF2\u91CD\u7F6E",
204
+ /** reset 时工作区和暂存区已干净 */
205
+ RESET_ALREADY_CLEAN: "\u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\u5DF2\u662F\u5E72\u51C0\u72B6\u6001\uFF0C\u65E0\u9700\u91CD\u7F6E"
206
+ };
207
+
208
+ // src/constants/messages/config.ts
209
+ var CONFIG_CMD_MESSAGES = {
210
+ /** 配置已恢复为默认值 */
211
+ CONFIG_RESET_SUCCESS: "\u2713 \u914D\u7F6E\u5DF2\u6062\u590D\u4E3A\u9ED8\u8BA4\u503C"
212
+ };
213
+
214
+ // src/constants/messages/status.ts
215
+ var STATUS_MESSAGES = {
216
+ /** status 命令标题 */
217
+ STATUS_TITLE: (projectName) => `\u9879\u76EE\u72B6\u6001\u603B\u89C8: ${projectName}`,
218
+ /** status 主 worktree 区块标题 */
219
+ STATUS_MAIN_SECTION: "\u4E3B Worktree",
220
+ /** status worktrees 区块标题 */
221
+ STATUS_WORKTREES_SECTION: "Worktree \u5217\u8868",
222
+ /** status 快照区块标题 */
223
+ STATUS_SNAPSHOTS_SECTION: "\u672A\u6E05\u7406\u7684 Validate \u5FEB\u7167",
224
+ /** status 无 worktree */
225
+ STATUS_NO_WORKTREES: "(\u65E0\u6D3B\u8DC3 worktree)",
226
+ /** status 无未清理快照 */
227
+ STATUS_NO_SNAPSHOTS: "(\u65E0\u672A\u6E05\u7406\u7684\u5FEB\u7167)",
228
+ /** status 变更状态:已提交 */
229
+ STATUS_CHANGE_COMMITTED: "\u5DF2\u63D0\u4EA4",
230
+ /** status 变更状态:未提交修改 */
231
+ STATUS_CHANGE_UNCOMMITTED: "\u672A\u63D0\u4EA4\u4FEE\u6539",
232
+ /** status 变更状态:合并冲突 */
233
+ STATUS_CHANGE_CONFLICT: "\u5408\u5E76\u51B2\u7A81",
234
+ /** status 变更状态:无变更 */
235
+ STATUS_CHANGE_CLEAN: "\u65E0\u53D8\u66F4",
236
+ /** status 快照对应 worktree 已不存在 */
237
+ STATUS_SNAPSHOT_ORPHANED: "(\u5BF9\u5E94 worktree \u5DF2\u4E0D\u5B58\u5728)"
238
+ };
239
+
240
+ // src/constants/messages/index.ts
241
+ var MESSAGES = {
242
+ ...COMMON_MESSAGES,
243
+ ...RUN_MESSAGES,
244
+ ...CREATE_MESSAGES,
245
+ ...MERGE_MESSAGES,
246
+ ...VALIDATE_MESSAGES,
247
+ ...SYNC_MESSAGES,
248
+ ...RESUME_MESSAGES,
249
+ ...REMOVE_MESSAGES,
250
+ ...RESET_MESSAGES,
251
+ ...CONFIG_CMD_MESSAGES,
252
+ ...STATUS_MESSAGES
253
+ };
254
+
13
255
  // src/constants/config.ts
14
256
  var CONFIG_DEFINITIONS = {
15
257
  autoDeleteBranch: {