clawt 2.1.0 → 2.2.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/.claude/agent-memory/docs-sync-updater/MEMORY.md +4 -3
- package/CLAUDE.md +9 -2
- package/README.md +13 -0
- package/dist/index.js +25 -1
- package/docs/spec.md +34 -0
- package/package.json +1 -1
- package/src/commands/reset.ts +42 -0
- package/src/constants/messages.ts +4 -0
- package/src/index.ts +2 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
### docs/spec.md
|
|
6
6
|
- 完整的软件规格说明,包含 7 大章节
|
|
7
|
-
- 命令流程在 `5. 需求场景详细设计` 下,每个命令一个子章节(5.1-5.
|
|
7
|
+
- 命令流程在 `5. 需求场景详细设计` 下,每个命令一个子章节(5.1-5.13)
|
|
8
8
|
- run 命令对应 `5.2 批量创建 Worktree + 执行 Claude Code 任务`,流程按步骤编号描述
|
|
9
9
|
- merge 命令对应 `5.6 合并验证过的分支`,流程按步骤编号描述
|
|
10
10
|
- config 命令对应 `5.10 查看全局配置`,只读展示配置
|
|
@@ -60,13 +60,14 @@ run 命令有两种模式(自 claudeCodeCommand 特性后):
|
|
|
60
60
|
- 传 `--tasks`:并行任务模式(多 worktree + `executeClaudeTask` + spawnProcess)
|
|
61
61
|
- CLAUDE.md 中的核心流程按模式分段描述
|
|
62
62
|
|
|
63
|
-
## 命令清单(
|
|
63
|
+
## 命令清单(10 个)
|
|
64
64
|
|
|
65
|
-
`create`、`run`、`resume`、`list`、`remove`、`validate`、`merge`、`config`
|
|
65
|
+
`create`、`run`、`resume`、`list`、`remove`、`validate`、`merge`、`config`、`sync`、`reset`
|
|
66
66
|
|
|
67
67
|
Notes:
|
|
68
68
|
- resume 和 run(交互式模式)共用 `launchInteractiveClaude()`,该函数从 run.ts 提取到 src/utils/claude.ts
|
|
69
69
|
- `claudeCodeCommand` 配置项同时影响 run 交互式模式和 resume 命令
|
|
70
|
+
- reset 命令与 validate --clean 的区别:reset 不删除快照文件,validate --clean 会删除快照
|
|
70
71
|
|
|
71
72
|
## validate 快照机制
|
|
72
73
|
|
package/CLAUDE.md
CHANGED
|
@@ -24,7 +24,7 @@ npm i -g . # 本地全局安装进行测试
|
|
|
24
24
|
|
|
25
25
|
每个命令为独立文件 `src/commands/<name>.ts`,导出 `registerXxxCommand(program)` 函数,在 `src/index.ts` 中统一注册到 Commander。命令内部逻辑封装在对应的 `handleXxx` 函数中。
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
十个命令:`create`、`run`、`resume`、`list`、`remove`、`validate`、`merge`、`config`、`sync`、`reset`。
|
|
28
28
|
|
|
29
29
|
### 核心流程(run 命令)
|
|
30
30
|
|
|
@@ -75,11 +75,18 @@ run 命令有两种模式:
|
|
|
75
75
|
6. 冲突处理:有冲突时提示用户手动解决,无冲突则输出成功
|
|
76
76
|
7. 合并成功后清除该分支的 validate 快照(代码基础已变化,旧快照无效)
|
|
77
77
|
|
|
78
|
+
### reset 命令流程
|
|
79
|
+
|
|
80
|
+
1. `validateMainWorktree()` 确认在主 worktree 根目录
|
|
81
|
+
2. 检测主 worktree 工作区和暂存区是否干净(`isWorkingDirClean()`)
|
|
82
|
+
3. 不干净 → `gitResetHard()` + `gitCleanForce()` 重置工作区和暂存区(保留 validate 快照)
|
|
83
|
+
4. 已干净 → 提示无需重置
|
|
84
|
+
|
|
78
85
|
### 目录层级
|
|
79
86
|
|
|
80
87
|
- `src/commands/` — 各命令的注册与处理逻辑
|
|
81
88
|
- `src/utils/` — 工具函数(git 操作(含三点 diff、分支合并、冲突检测、merge-base 计算、commit message 检测、soft reset 到指定 commit 等)、shell 执行与子进程管理、分支名处理、worktree 管理与批量清理、配置、格式化输出、交互式输入、Claude Code 交互式启动、validate 快照管理(含 HEAD hash 一致性校验))
|
|
82
|
-
- `src/constants/` — 常量定义(路径、退出码、消息模板、分支规则、配置默认值、终端控制序列、validate 快照目录、sync 相关消息、git 常量(如 `AUTO_SAVE_COMMIT_MESSAGE`)、squash 相关消息)
|
|
89
|
+
- `src/constants/` — 常量定义(路径、退出码、消息模板、分支规则、配置默认值、终端控制序列、validate 快照目录、sync 相关消息、git 常量(如 `AUTO_SAVE_COMMIT_MESSAGE`)、squash 相关消息、reset 相关消息)
|
|
83
90
|
- `src/types/` — TypeScript 类型定义
|
|
84
91
|
- `src/errors/` — 自定义 `ClawtError` 错误类(携带退出码)
|
|
85
92
|
- `src/logger/` — winston 日志(按日期滚动,写入 `~/.clawt/logs/`)
|
package/README.md
CHANGED
|
@@ -187,6 +187,19 @@ clawt list
|
|
|
187
187
|
|
|
188
188
|
列出当前项目在 `~/.clawt/worktrees/` 下的所有 worktree 及对应分支。
|
|
189
189
|
|
|
190
|
+
### `clawt reset` — 重置主 worktree 工作区和暂存区
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
clawt reset
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
重置主 worktree 的工作区和暂存区(`git reset --hard` + `git clean -f`),恢复到干净状态。与 `clawt validate --clean` 不同,`reset` 不会删除 validate 快照文件,适用于只想清空变更而保留快照以便后续增量 validate 的场景。如果工作区和暂存区已是干净状态,会提示无需重置。
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
# 重置主 worktree 工作区和暂存区
|
|
200
|
+
clawt reset
|
|
201
|
+
```
|
|
202
|
+
|
|
190
203
|
### `clawt config` — 查看全局配置
|
|
191
204
|
|
|
192
205
|
```bash
|
package/dist/index.js
CHANGED
|
@@ -111,7 +111,11 @@ var MESSAGES = {
|
|
|
111
111
|
MERGE_SQUASH_PENDING: (worktreePath, branch) => `\u2713 \u5DF2\u5C06\u6240\u6709\u63D0\u4EA4\u538B\u7F29\u5230\u6682\u5B58\u533A
|
|
112
112
|
\u8BF7\u5728\u76EE\u6807 worktree \u4E2D\u63D0\u4EA4\u540E\u91CD\u65B0\u6267\u884C merge\uFF1A
|
|
113
113
|
cd ${worktreePath}
|
|
114
|
-
\u63D0\u4EA4\u5B8C\u6210\u540E\u6267\u884C\uFF1Aclawt merge -b ${branch}
|
|
114
|
+
\u63D0\u4EA4\u5B8C\u6210\u540E\u6267\u884C\uFF1Aclawt merge -b ${branch}`,
|
|
115
|
+
/** reset 成功 */
|
|
116
|
+
RESET_SUCCESS: "\u2713 \u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\u5DF2\u91CD\u7F6E",
|
|
117
|
+
/** reset 时工作区和暂存区已干净 */
|
|
118
|
+
RESET_ALREADY_CLEAN: "\u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\u5DF2\u662F\u5E72\u51C0\u72B6\u6001\uFF0C\u65E0\u9700\u91CD\u7F6E"
|
|
115
119
|
};
|
|
116
120
|
|
|
117
121
|
// src/constants/exitCodes.ts
|
|
@@ -1329,6 +1333,25 @@ async function handleSync(options) {
|
|
|
1329
1333
|
printSuccess(MESSAGES.SYNC_SUCCESS(branch, mainBranch));
|
|
1330
1334
|
}
|
|
1331
1335
|
|
|
1336
|
+
// src/commands/reset.ts
|
|
1337
|
+
function registerResetCommand(program2) {
|
|
1338
|
+
program2.command("reset").description("\u91CD\u7F6E\u4E3B worktree \u5DE5\u4F5C\u533A\u548C\u6682\u5B58\u533A\uFF08\u4FDD\u7559 validate \u5FEB\u7167\uFF09").action(() => {
|
|
1339
|
+
handleReset();
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
function handleReset() {
|
|
1343
|
+
validateMainWorktree();
|
|
1344
|
+
const mainWorktreePath = getGitTopLevel();
|
|
1345
|
+
logger.info("reset \u547D\u4EE4\u6267\u884C");
|
|
1346
|
+
if (!isWorkingDirClean(mainWorktreePath)) {
|
|
1347
|
+
gitResetHard(mainWorktreePath);
|
|
1348
|
+
gitCleanForce(mainWorktreePath);
|
|
1349
|
+
printSuccess(MESSAGES.RESET_SUCCESS);
|
|
1350
|
+
} else {
|
|
1351
|
+
printInfo(MESSAGES.RESET_ALREADY_CLEAN);
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1332
1355
|
// src/index.ts
|
|
1333
1356
|
var require2 = createRequire(import.meta.url);
|
|
1334
1357
|
var { version } = require2("../package.json");
|
|
@@ -1344,6 +1367,7 @@ registerValidateCommand(program);
|
|
|
1344
1367
|
registerMergeCommand(program);
|
|
1345
1368
|
registerConfigCommand(program);
|
|
1346
1369
|
registerSyncCommand(program);
|
|
1370
|
+
registerResetCommand(program);
|
|
1347
1371
|
process.on("uncaughtException", (error) => {
|
|
1348
1372
|
if (error instanceof ClawtError) {
|
|
1349
1373
|
printError(error.message);
|
package/docs/spec.md
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
- [5.10 查看全局配置](#510-查看全局配置)
|
|
25
25
|
- [5.11 在已有 Worktree 中恢复会话](#511-在已有-worktree-中恢复会话)
|
|
26
26
|
- [5.12 将主分支代码同步到目标 Worktree](#512-将主分支代码同步到目标-worktree)
|
|
27
|
+
- [5.13 重置主 Worktree 工作区和暂存区](#513-重置主-worktree-工作区和暂存区)
|
|
27
28
|
- [6. 错误处理规范](#6-错误处理规范)
|
|
28
29
|
- [7. 非功能性需求](#7-非功能性需求)
|
|
29
30
|
|
|
@@ -168,6 +169,7 @@ git show-ref --verify refs/heads/<branchName> 2>/dev/null
|
|
|
168
169
|
| `clawt config` | 查看全局配置 | 5.10 |
|
|
169
170
|
| `clawt resume` | 在已有 worktree 中恢复 Claude Code 交互式会话 | 5.11 |
|
|
170
171
|
| `clawt sync` | 将主分支最新代码同步到目标 worktree | 5.12 |
|
|
172
|
+
| `clawt reset` | 重置主 worktree 工作区和暂存区 | 5.13 |
|
|
171
173
|
|
|
172
174
|
所有命令执行前,都必须先执行**主 worktree 校验**(见 [2.1](#21-主-worktree-的定义与定位规则))。
|
|
173
175
|
|
|
@@ -889,6 +891,38 @@ clawt sync -b <branchName>
|
|
|
889
891
|
|
|
890
892
|
---
|
|
891
893
|
|
|
894
|
+
### 5.13 重置主 Worktree 工作区和暂存区
|
|
895
|
+
|
|
896
|
+
**命令:**
|
|
897
|
+
|
|
898
|
+
```bash
|
|
899
|
+
clawt reset
|
|
900
|
+
```
|
|
901
|
+
|
|
902
|
+
**无参数。**
|
|
903
|
+
|
|
904
|
+
**使用场景:**
|
|
905
|
+
|
|
906
|
+
当用户通过 `clawt validate` 将分支变更迁移到主 worktree 后,希望快速清除工作区和暂存区的所有修改,恢复到干净状态。与 `clawt validate --clean` 的区别在于:`reset` 仅重置工作区和暂存区,**不删除** validate 快照文件,适用于只想清空变更而保留快照以便后续增量 validate 的场景。
|
|
907
|
+
|
|
908
|
+
**运行流程:**
|
|
909
|
+
|
|
910
|
+
1. **主 worktree 校验** (2.1)
|
|
911
|
+
2. **检测工作区状态**:通过 `git status --porcelain` 检测主 worktree 是否有未提交的更改
|
|
912
|
+
- **工作区干净** → 输出提示 `主 worktree 工作区和暂存区已是干净状态,无需重置`,退出
|
|
913
|
+
- **工作区不干净** → 继续
|
|
914
|
+
3. **重置工作区和暂存区**:
|
|
915
|
+
```bash
|
|
916
|
+
git reset --hard
|
|
917
|
+
git clean -f
|
|
918
|
+
```
|
|
919
|
+
4. **输出成功提示**:
|
|
920
|
+
```
|
|
921
|
+
✓ 主 worktree 工作区和暂存区已重置
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
---
|
|
925
|
+
|
|
892
926
|
## 6. 错误处理规范
|
|
893
927
|
|
|
894
928
|
### 6.1 通用错误处理
|
package/package.json
CHANGED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import { logger } from '../logger/index.js';
|
|
3
|
+
import { MESSAGES } from '../constants/index.js';
|
|
4
|
+
import {
|
|
5
|
+
validateMainWorktree,
|
|
6
|
+
getGitTopLevel,
|
|
7
|
+
isWorkingDirClean,
|
|
8
|
+
gitResetHard,
|
|
9
|
+
gitCleanForce,
|
|
10
|
+
printSuccess,
|
|
11
|
+
printInfo,
|
|
12
|
+
} from '../utils/index.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 注册 reset 命令:重置主 worktree 工作区和暂存区
|
|
16
|
+
* @param {Command} program - Commander 实例
|
|
17
|
+
*/
|
|
18
|
+
export function registerResetCommand(program: Command): void {
|
|
19
|
+
program
|
|
20
|
+
.command('reset')
|
|
21
|
+
.description('重置主 worktree 工作区和暂存区(保留 validate 快照)')
|
|
22
|
+
.action(() => {
|
|
23
|
+
handleReset();
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 执行 reset 命令:重置主 worktree 工作区和暂存区
|
|
29
|
+
*/
|
|
30
|
+
function handleReset(): void {
|
|
31
|
+
validateMainWorktree();
|
|
32
|
+
const mainWorktreePath = getGitTopLevel();
|
|
33
|
+
logger.info('reset 命令执行');
|
|
34
|
+
|
|
35
|
+
if (!isWorkingDirClean(mainWorktreePath)) {
|
|
36
|
+
gitResetHard(mainWorktreePath);
|
|
37
|
+
gitCleanForce(mainWorktreePath);
|
|
38
|
+
printSuccess(MESSAGES.RESET_SUCCESS);
|
|
39
|
+
} else {
|
|
40
|
+
printInfo(MESSAGES.RESET_ALREADY_CLEAN);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -95,4 +95,8 @@ export const MESSAGES = {
|
|
|
95
95
|
/** squash 完成但未提供 -m,提示用户自行提交 */
|
|
96
96
|
MERGE_SQUASH_PENDING: (worktreePath: string, branch: string) =>
|
|
97
97
|
`✓ 已将所有提交压缩到暂存区\n 请在目标 worktree 中提交后重新执行 merge:\n cd ${worktreePath}\n 提交完成后执行:clawt merge -b ${branch}`,
|
|
98
|
+
/** reset 成功 */
|
|
99
|
+
RESET_SUCCESS: '✓ 主 worktree 工作区和暂存区已重置',
|
|
100
|
+
/** reset 时工作区和暂存区已干净 */
|
|
101
|
+
RESET_ALREADY_CLEAN: '主 worktree 工作区和暂存区已是干净状态,无需重置',
|
|
98
102
|
} as const;
|
package/src/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { registerValidateCommand } from './commands/validate.js';
|
|
|
13
13
|
import { registerMergeCommand } from './commands/merge.js';
|
|
14
14
|
import { registerConfigCommand } from './commands/config.js';
|
|
15
15
|
import { registerSyncCommand } from './commands/sync.js';
|
|
16
|
+
import { registerResetCommand } from './commands/reset.js';
|
|
16
17
|
|
|
17
18
|
// 从 package.json 读取版本号,避免硬编码
|
|
18
19
|
const require = createRequire(import.meta.url);
|
|
@@ -38,6 +39,7 @@ registerValidateCommand(program);
|
|
|
38
39
|
registerMergeCommand(program);
|
|
39
40
|
registerConfigCommand(program);
|
|
40
41
|
registerSyncCommand(program);
|
|
42
|
+
registerResetCommand(program);
|
|
41
43
|
|
|
42
44
|
// 全局未捕获异常处理
|
|
43
45
|
process.on('uncaughtException', (error) => {
|