clawt 3.5.3 → 3.6.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.
- package/.claude/agents/docs-sync-updater.md +24 -44
- package/CLAUDE.md +6 -0
- package/dist/index.js +169 -16
- package/dist/postinstall.js +16 -2
- package/package.json +1 -1
- package/src/commands/home.ts +24 -2
- package/src/commands/init.ts +23 -6
- package/src/commands/resume.ts +91 -0
- package/src/constants/messages/home.ts +2 -0
- package/src/constants/messages/resume.ts +10 -0
- package/src/types/command.ts +12 -0
- package/src/types/index.ts +1 -1
- package/src/utils/git-core.ts +40 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/task-executor.ts +34 -8
- package/src/utils/validation.ts +1 -1
- package/tests/unit/commands/resume.test.ts +241 -3
- package/docs/alias.md +0 -114
- package/docs/completion.md +0 -55
- package/docs/config-file.md +0 -45
- package/docs/config.md +0 -93
- package/docs/cover-validate.md +0 -94
- package/docs/create.md +0 -101
- package/docs/home.md +0 -58
- package/docs/init.md +0 -81
- package/docs/list.md +0 -73
- package/docs/log.md +0 -67
- package/docs/merge.md +0 -137
- package/docs/notification.md +0 -94
- package/docs/project-config.md +0 -132
- package/docs/projects.md +0 -135
- package/docs/remove.md +0 -90
- package/docs/reset.md +0 -37
- package/docs/resume.md +0 -100
- package/docs/run.md +0 -146
- package/docs/spec.md +0 -415
- package/docs/status.md +0 -343
- package/docs/sync.md +0 -128
- package/docs/update-check.md +0 -95
- package/docs/validate.md +0 -416
package/docs/notification.md
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
### 5.3 任务完成通知机制
|
|
2
|
-
|
|
3
|
-
**触发条件:** 通过 `clawt run` 启动了多个 Claude Code 任务后自动进入通知模式。
|
|
4
|
-
|
|
5
|
-
**机制说明:**
|
|
6
|
-
|
|
7
|
-
Claude Code CLI 以 `--output-format stream-json --verbose` 运行时,stdout 会持续输出 JSON 行(每行一个事件),包括 `system`、`assistant`(含 `tool_use` 和 `text`)、`user`(含 `tool_result`)等类型。任务结束时输出 `type: "result"` 事件:
|
|
8
|
-
|
|
9
|
-
```json
|
|
10
|
-
{
|
|
11
|
-
"type": "result",
|
|
12
|
-
"subtype": "success",
|
|
13
|
-
"is_error": false,
|
|
14
|
-
"duration_ms": 182809,
|
|
15
|
-
"duration_api_ms": 0,
|
|
16
|
-
"num_turns": 1,
|
|
17
|
-
"result": "xxx",
|
|
18
|
-
"stop_reason": "stop_sequence",
|
|
19
|
-
"session_id": "e771e449-b695-48e7-8006-bbf3f0dd3e98",
|
|
20
|
-
"total_cost_usd": 0,
|
|
21
|
-
"usage": { ... }
|
|
22
|
-
}
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
**流式事件解析(`src/utils/stream-parser.ts`):**
|
|
26
|
-
|
|
27
|
-
由于 stdout 的 `data` 事件可能在行中间切割,使用 `createLineBuffer()` 行缓冲器拼接完整行后,通过 `parseStreamLine()` 解析为 `StreamEvent` 对象,再由 `parseStreamEvent()` 提取活动信息(`ParsedActivity`):
|
|
28
|
-
|
|
29
|
-
- **`tool_use` 类型**:提取工具名和文件路径/命令参数,格式如 `Read index.ts`、`Bash ls -la`
|
|
30
|
-
- **`text` 类型**:提取文本片段,格式如 `思考中: 让我分析一下`
|
|
31
|
-
- **`result` 类型**:构造 `ClaudeCodeResult` 对象,提取耗时、费用、结果文本等
|
|
32
|
-
|
|
33
|
-
活动描述文本最大长度为 `ACTIVITY_TEXT_MAX_LENGTH`(30 字符),超出后截断并追加省略号。结果预览文本最大长度为 `RESULT_PREVIEW_MAX_LENGTH`(40 字符)。
|
|
34
|
-
|
|
35
|
-
**事件监听与通知流程:**
|
|
36
|
-
|
|
37
|
-
1. 为每个 Claude Code 子进程维护状态(运行中 / 已完成 / 已失败)
|
|
38
|
-
2. 监听每个子进程的 `close` 事件(基于 Node.js `ChildProcess` 的事件驱动机制)
|
|
39
|
-
3. 在流式传输过程中实时解析每一行事件,当遇到 `type=result` 时保存到 `finalResult`;子进程触发 `close` 事件时,flush 行缓冲器并组装最终结果
|
|
40
|
-
4. 在主 worktree 的 clawt 终端实时输出通知。TTY 环境下使用进度面板,进度面板每个任务行第二列显示 worktree 路径(终端可点击跳转),运行中显示实时活动描述,完成/失败后显示结果预览。任务行格式示例:
|
|
41
|
-
|
|
42
|
-
```
|
|
43
|
-
[1/3] /path/to/worktree ⠹ 运行中 1m23s Read index.ts
|
|
44
|
-
[2/3] /path/to/worktree ✓ 完成 2m05s $0.08 任务已成功完成
|
|
45
|
-
[3/3] /path/to/worktree ◦ 排队中
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
5. 先完成的先通知,**不需要**失败重试机制
|
|
49
|
-
6. 当所有任务完成后,输出汇总信息:
|
|
50
|
-
|
|
51
|
-
```
|
|
52
|
-
════════════════════════════════════════
|
|
53
|
-
全部任务已完成 (3/3)
|
|
54
|
-
成功: 2
|
|
55
|
-
失败: 1
|
|
56
|
-
总耗时: 245.3s
|
|
57
|
-
总花费: $0.15
|
|
58
|
-
════════════════════════════════════════
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
#### 进度面板渲染机制
|
|
62
|
-
|
|
63
|
-
进度面板由 `ProgressRenderer`(`src/utils/progress.ts`)负责渲染,渲染函数拆分到 `src/utils/progress-render.ts`。
|
|
64
|
-
|
|
65
|
-
**TTY 模式渲染策略(备选屏幕缓冲区):**
|
|
66
|
-
|
|
67
|
-
- **进入备选屏幕**:`start()` 时通过 `ALT_SCREEN_ENTER`(`\x1B[?1049h`)进入终端备选屏幕缓冲区,隔离进度面板与主屏幕内容
|
|
68
|
-
- **禁用行换行**:通过 `LINE_WRAP_DISABLE`(`\x1B[?7l`)防止超长行自动折行,配合按终端宽度截断保证每行只占一行
|
|
69
|
-
- **每帧渲染**:使用 `CLEAR_SCREEN` + `CURSOR_HOME` 清屏后完全重绘,无需计算 `CURSOR_UP` 回退量,不受终端 reflow 影响
|
|
70
|
-
- **防闪烁**:每帧渲染使用 Synchronized Output(`SYNC_OUTPUT_START` / `SYNC_OUTPUT_END`),终端缓冲全部输出后一次性刷新
|
|
71
|
-
- **行宽截断**:通过 `truncateToTerminalWidth()`(`src/utils/progress-render.ts`)将含 ANSI 转义码的字符串截断到终端可见列数,使用 `string-width` 库正确计算中文/emoji 宽度
|
|
72
|
-
- **终端 resize 响应**:监听 `process.stdout` 的 `resize` 事件,窗口宽度变化时立即触发重绘
|
|
73
|
-
- **退出时恢复**:`stop()` 时恢复行换行、显示光标、退出备选屏幕,然后在主屏幕上重新输出最终面板状态(备选屏幕内容不保留)
|
|
74
|
-
- **异常退出兜底**:注册 `process.on('exit')` 处理器,确保即使异常退出也能恢复终端状态
|
|
75
|
-
|
|
76
|
-
**任务行格式:**
|
|
77
|
-
|
|
78
|
-
```
|
|
79
|
-
[1/3] /path/to/worktree ⠹ 运行中 1m23s Read index.ts
|
|
80
|
-
[2/3] /path/to/worktree ✓ 完成 2m05s $0.08 任务已成功完成
|
|
81
|
-
[3/3] /path/to/worktree ◦ 排队中
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
- 第二列为 worktree 路径(`path.padEnd(maxPathWidth)` 对齐)
|
|
85
|
-
- 运行中状态:末尾显示实时活动描述文本(如工具名+文件名、思考中+文本片段)
|
|
86
|
-
- 完成/失败状态:末尾显示结果预览文本(从 `ClaudeCodeResult.result` 提取,最大 40 字符)
|
|
87
|
-
|
|
88
|
-
**非 TTY 降级模式:**
|
|
89
|
-
|
|
90
|
-
- 启动时输出 `[1/3] branch 启动 path`
|
|
91
|
-
- 完成时输出 `[1/3] branch ✓ 完成 duration cost detail`(`detail` 优先使用结果预览,无则回退到路径)
|
|
92
|
-
- 失败时输出 `[1/3] branch ✗ 失败 duration detail`
|
|
93
|
-
|
|
94
|
-
---
|
package/docs/project-config.md
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
### 项目级配置
|
|
2
|
-
|
|
3
|
-
#### 概述
|
|
4
|
-
|
|
5
|
-
项目级配置是每个 Git 项目独立的 clawt 配置,用于记录该项目特有的设置(如主工作分支名、validate 自动运行命令等)。与全局配置(`~/.clawt/config.json`,见 [config-file.md](./config-file.md))不同,项目级配置按项目隔离存储。
|
|
6
|
-
|
|
7
|
-
#### 存放路径
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
~/.clawt/projects/<projectName>/config.json
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
其中 `<projectName>` 为项目根目录的目录名(通过 `git rev-parse --show-toplevel` 获取后取 `basename`)。
|
|
14
|
-
|
|
15
|
-
#### 配置项列表
|
|
16
|
-
|
|
17
|
-
```json
|
|
18
|
-
{
|
|
19
|
-
"clawtMainWorkBranch": "main",
|
|
20
|
-
"validateRunCommand": "npm test"
|
|
21
|
-
}
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
| 配置项 | 类型 | 必填 | 默认值 | 说明 |
|
|
25
|
-
| --- | --- | --- | --- | --- |
|
|
26
|
-
| `clawtMainWorkBranch` | `string` | 是 | `""` | 项目的主工作分支名,用于 create 时检测当前分支是否为主分支,以及 sync、merge 等命令获取主分支名 |
|
|
27
|
-
| `validateRunCommand` | `string` | 否 | `undefined` | validate 成功后自动执行的命令(作为 `-r` 选项的默认值)。不传 `-r` 时,validate 命令会自动从此项读取 |
|
|
28
|
-
|
|
29
|
-
#### 配置项定义数据源
|
|
30
|
-
|
|
31
|
-
项目级配置项的完整定义集中在 `src/constants/project-config.ts` 中的 `PROJECT_CONFIG_DEFINITIONS` 常量,作为**单一数据源**(Single Source of Truth)。新增项目配置项只需在此处维护,`PROJECT_DEFAULT_CONFIG` 和 `PROJECT_CONFIG_DESCRIPTIONS` 会自动从中派生:
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
// src/constants/project-config.ts
|
|
35
|
-
|
|
36
|
-
export const PROJECT_CONFIG_DEFINITIONS: ProjectConfigDefinitions = {
|
|
37
|
-
clawtMainWorkBranch: {
|
|
38
|
-
defaultValue: '',
|
|
39
|
-
description: '主 worktree 的工作分支名',
|
|
40
|
-
},
|
|
41
|
-
validateRunCommand: {
|
|
42
|
-
defaultValue: undefined as unknown as string | undefined,
|
|
43
|
-
description: 'validate 成功后自动执行的命令(-r 的默认值)',
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
/** 项目默认配置(从 PROJECT_CONFIG_DEFINITIONS 自动派生) */
|
|
48
|
-
export const PROJECT_DEFAULT_CONFIG: Required<ProjectConfig> = deriveDefaultConfig(PROJECT_CONFIG_DEFINITIONS);
|
|
49
|
-
|
|
50
|
-
/** 项目配置项描述映射(从 PROJECT_CONFIG_DEFINITIONS 自动派生) */
|
|
51
|
-
export const PROJECT_CONFIG_DESCRIPTIONS: Record<keyof Required<ProjectConfig>, string> = deriveConfigDescriptions(PROJECT_CONFIG_DEFINITIONS);
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
#### 相关类型定义
|
|
55
|
-
|
|
56
|
-
类型定义位于 `src/types/projectConfig.ts`:
|
|
57
|
-
|
|
58
|
-
| 类型 | 说明 |
|
|
59
|
-
| --- | --- |
|
|
60
|
-
| `ProjectConfig` | 项目级配置接口,包含 `clawtMainWorkBranch`(必填)和 `validateRunCommand`(可选) |
|
|
61
|
-
| `ProjectConfigItemDefinition<T>` | 单个配置项定义,含 `defaultValue`(默认值)、`description`(描述)、可选 `allowedValues`(枚举值列表,仅对 string 类型有效) |
|
|
62
|
-
| `ProjectConfigDefinitions` | 所有配置项的完整定义映射,键为 `ProjectConfig` 的所有属性名,值为对应的 `ProjectConfigItemDefinition` |
|
|
63
|
-
|
|
64
|
-
```typescript
|
|
65
|
-
// src/types/projectConfig.ts
|
|
66
|
-
|
|
67
|
-
export interface ProjectConfig {
|
|
68
|
-
clawtMainWorkBranch: string;
|
|
69
|
-
validateRunCommand?: string;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export interface ProjectConfigItemDefinition<T> {
|
|
73
|
-
defaultValue: T;
|
|
74
|
-
description: string;
|
|
75
|
-
allowedValues?: T extends string ? readonly string[] : never;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export type ProjectConfigDefinitions = {
|
|
79
|
-
[K in keyof Required<ProjectConfig>]: ProjectConfigItemDefinition<ProjectConfig[K]>;
|
|
80
|
-
};
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
#### 工具函数
|
|
84
|
-
|
|
85
|
-
工具函数位于 `src/utils/project-config.ts`:
|
|
86
|
-
|
|
87
|
-
| 函数 | 签名 | 说明 |
|
|
88
|
-
| --- | --- | --- |
|
|
89
|
-
| `getProjectConfigPath` | `(projectName: string) => string` | 获取项目配置文件的完整路径 |
|
|
90
|
-
| `loadProjectConfig` | `() => ProjectConfig \| null` | 加载当前项目的配置,配置文件不存在或解析失败时返回 `null` |
|
|
91
|
-
| `saveProjectConfig` | `(config: ProjectConfig) => void` | 保存项目配置到文件,自动创建项目子目录 |
|
|
92
|
-
| `requireProjectConfig` | `() => ProjectConfig` | 获取当前项目配置,不存在或缺少 `clawtMainWorkBranch` 时抛出 `ClawtError` |
|
|
93
|
-
| `getMainWorkBranch` | `() => string` | 从项目配置中获取主工作分支名(内部调用 `requireProjectConfig`) |
|
|
94
|
-
| `getValidateRunCommand` | `() => string \| undefined` | 从项目配置中获取 validate 自动执行命令,未配置时返回 `undefined` |
|
|
95
|
-
|
|
96
|
-
#### 设置方式
|
|
97
|
-
|
|
98
|
-
通过 `clawt init` 命令设置(详见 [init.md](./init.md)):
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
# 以当前分支作为主工作分支初始化
|
|
102
|
-
clawt init
|
|
103
|
-
|
|
104
|
-
# 指定主工作分支名
|
|
105
|
-
clawt init -b <branchName>
|
|
106
|
-
|
|
107
|
-
# 交互式查看和修改所有项目配置项
|
|
108
|
-
clawt init show
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
`init show` 子命令调用通用的 `interactiveConfigEditor`(`src/utils/config-strategy.ts`),基于 `PROJECT_CONFIG_DEFINITIONS` 构建配置项列表,提供交互式面板供用户查看和修改所有项目配置项。
|
|
112
|
-
|
|
113
|
-
#### 前置校验
|
|
114
|
-
|
|
115
|
-
除 `clawt init` 以外的所有核心命令(create、run、validate、sync、remove、merge、reset),执行时都会校验项目级配置是否存在。如果未执行过 `clawt init`,命令会直接报错并提示用户先初始化:
|
|
116
|
-
|
|
117
|
-
```
|
|
118
|
-
✗ 该项目尚未初始化,请先执行 clawt init -b<branchName>设置主工作分支
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
> **实现细节**:`ensureOnMainWorkBranch()` 内部已通过 `getMainWorkBranch()` -> `requireProjectConfig()` 完成了项目配置校验,因此调用了 `ensureOnMainWorkBranch` 的命令(create、run、validate、sync、remove、merge)无需再显式调用 `requireProjectConfig()`,避免重复校验。仅 reset 命令因不调用 `ensureOnMainWorkBranch`,需要自行调用 `requireProjectConfig()`。
|
|
122
|
-
|
|
123
|
-
#### 路径常量
|
|
124
|
-
|
|
125
|
-
在 `src/constants/paths.ts` 中定义:
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
/** 项目级配置目录 ~/.clawt/projects/ */
|
|
129
|
-
export const PROJECTS_CONFIG_DIR = join(CLAWT_HOME, 'projects');
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
---
|
package/docs/projects.md
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
### 5.18 跨项目 Worktree 概览
|
|
2
|
-
|
|
3
|
-
**命令:**
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
clawt projects [name] [--json]
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
**参数:**
|
|
10
|
-
|
|
11
|
-
| 参数 | 必填 | 说明 |
|
|
12
|
-
| -------- | ---- | ---------------------------------------------- |
|
|
13
|
-
| `[name]` | 否 | 指定项目名,查看该项目的 worktree 详情 |
|
|
14
|
-
| `--json` | 否 | 以 JSON 格式输出完整数据 |
|
|
15
|
-
|
|
16
|
-
**使用场景:**
|
|
17
|
-
|
|
18
|
-
当使用 clawt 管理多个不同项目时,快速了解所有项目的 worktree 数量、磁盘占用和最近活跃时间。也可以指定项目名查看该项目下每个 worktree 的分支、路径、最后修改时间和磁盘占用。
|
|
19
|
-
|
|
20
|
-
**注意:** `projects` 命令不需要在主 worktree 中执行(与其他命令不同),它直接扫描 `~/.clawt/worktrees/` 目录。
|
|
21
|
-
|
|
22
|
-
**运行流程:**
|
|
23
|
-
|
|
24
|
-
#### 无参数模式(项目概览)
|
|
25
|
-
|
|
26
|
-
1. 扫描 `~/.clawt/worktrees/` 目录,列出所有项目子目录(如果目录不存在或为空,输出 `(暂无项目,worktrees 目录为空)` 提示并结束)
|
|
27
|
-
2. 对每个项目收集以下信息:
|
|
28
|
-
- **项目名**(目录名即项目名)
|
|
29
|
-
- **worktree 数量**(项目目录下的子目录数)
|
|
30
|
-
- **最近活跃时间**(取项目目录自身和所有 worktree 目录 mtime 的最大值,通过 `formatLocalISOString()` 格式化为本机时区的 ISO 8601 字符串)
|
|
31
|
-
- **磁盘占用**(通过 `calculateDirSize()` 递归计算整个项目目录的总大小)
|
|
32
|
-
3. 按最近活跃时间降序排序
|
|
33
|
-
4. 输出概览信息(文本或 JSON)
|
|
34
|
-
|
|
35
|
-
#### 指定项目模式(worktree 详情)
|
|
36
|
-
|
|
37
|
-
1. 检查 `~/.clawt/worktrees/<name>/` 是否存在,不存在则报错退出
|
|
38
|
-
2. 扫描项目目录,对每个 worktree 子目录收集(如果项目目录下无 worktree 子目录,输出 `(该项目下无 worktree)` 提示并结束):
|
|
39
|
-
- **分支名**(目录名即分支名)
|
|
40
|
-
- **worktree 路径**
|
|
41
|
-
- **最后修改时间**(目录 mtime,通过 `formatLocalISOString()` 格式化)
|
|
42
|
-
- **磁盘占用**(通过 `calculateDirSize()` 递归计算)
|
|
43
|
-
3. 按最后修改时间降序排序
|
|
44
|
-
4. 输出详情信息(文本或 JSON)
|
|
45
|
-
|
|
46
|
-
**文本输出格式(概览模式):**
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
════════════════════════════════════════
|
|
50
|
-
项目概览
|
|
51
|
-
════════════════════════════════════════
|
|
52
|
-
|
|
53
|
-
● my-project
|
|
54
|
-
3 个 worktree 最近活跃: 2 小时前 磁盘占用: 1.5 GB
|
|
55
|
-
|
|
56
|
-
● another-project
|
|
57
|
-
1 个 worktree 最近活跃: 3 天前 磁盘占用: 256.0 MB
|
|
58
|
-
|
|
59
|
-
────────────────────────────────────────
|
|
60
|
-
|
|
61
|
-
共 2 个项目 总占用: 1.8 GB
|
|
62
|
-
|
|
63
|
-
════════════════════════════════════════
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
**文本输出格式(详情模式):**
|
|
67
|
-
|
|
68
|
-
```
|
|
69
|
-
════════════════════════════════════════
|
|
70
|
-
项目详情: my-project
|
|
71
|
-
════════════════════════════════════════
|
|
72
|
-
|
|
73
|
-
◆ 路径: ~/.clawt/worktrees/my-project
|
|
74
|
-
总占用: 1.5 GB
|
|
75
|
-
|
|
76
|
-
────────────────────────────────────────
|
|
77
|
-
|
|
78
|
-
● feature-login
|
|
79
|
-
~/.clawt/worktrees/my-project/feature-login
|
|
80
|
-
最后修改: 2 小时前 磁盘占用: 800.0 MB
|
|
81
|
-
|
|
82
|
-
● feature-signup
|
|
83
|
-
~/.clawt/worktrees/my-project/feature-signup
|
|
84
|
-
最后修改: 1 天前 磁盘占用: 700.0 MB
|
|
85
|
-
|
|
86
|
-
════════════════════════════════════════
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
**JSON 输出格式(概览模式,`--json`):**
|
|
90
|
-
|
|
91
|
-
```json
|
|
92
|
-
{
|
|
93
|
-
"projects": [
|
|
94
|
-
{
|
|
95
|
-
"name": "my-project",
|
|
96
|
-
"worktreeCount": 3,
|
|
97
|
-
"lastActiveTime": "2025-06-15T18:30:00.000+08:00",
|
|
98
|
-
"diskUsage": 1610612736
|
|
99
|
-
}
|
|
100
|
-
],
|
|
101
|
-
"totalProjects": 1,
|
|
102
|
-
"totalDiskUsage": 1610612736
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
**JSON 输出格式(详情模式,`--json`):**
|
|
107
|
-
|
|
108
|
-
```json
|
|
109
|
-
{
|
|
110
|
-
"name": "my-project",
|
|
111
|
-
"projectDir": "/Users/<username>/.clawt/worktrees/my-project",
|
|
112
|
-
"worktrees": [
|
|
113
|
-
{
|
|
114
|
-
"branch": "feature-login",
|
|
115
|
-
"path": "/Users/<username>/.clawt/worktrees/my-project/feature-login",
|
|
116
|
-
"lastModifiedTime": "2025-06-15T18:30:00.000+08:00",
|
|
117
|
-
"diskUsage": 838860800
|
|
118
|
-
}
|
|
119
|
-
],
|
|
120
|
-
"totalDiskUsage": 838860800
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
**实现要点:**
|
|
125
|
-
|
|
126
|
-
- 命令注册函数:`registerProjectsCommand()`(在 `src/commands/projects.ts`)
|
|
127
|
-
- 类型定义在 `src/types/project.ts`:`ProjectOverview`、`ProjectWorktreeDetail`、`ProjectDetailResult`、`ProjectsOverviewResult`
|
|
128
|
-
- 命令选项类型:`ProjectsOptions`(在 `src/types/command.ts`)
|
|
129
|
-
- 消息常量在 `PROJECTS_MESSAGES`(在 `src/constants/messages/projects.ts`)
|
|
130
|
-
- 时间格式化使用 `formatLocalISOString()`(在 `src/utils/formatter.ts`),输出本机时区的 ISO 8601 字符串(替代 `Date.toISOString()` 的 UTC 输出)
|
|
131
|
-
- 磁盘大小展示使用 `formatDiskSize()`(在 `src/utils/formatter.ts`),将字节数格式化为带单位的可读字符串
|
|
132
|
-
- 目录大小计算使用 `calculateDirSize()`(在 `src/utils/fs.ts`),递归遍历目录计算总字节数
|
|
133
|
-
- 时间的相对展示使用 `formatRelativeTime()`(在 `src/utils/formatter.ts`),将 ISO 8601 日期转换为中文相对时间(如"2 小时前")
|
|
134
|
-
|
|
135
|
-
---
|
package/docs/remove.md
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
### 5.5 移除 Worktree
|
|
2
|
-
|
|
3
|
-
**命令:**
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
# 移除当前项目所有 worktree
|
|
7
|
-
clawt remove --all
|
|
8
|
-
|
|
9
|
-
# 指定分支名(支持模糊匹配)
|
|
10
|
-
clawt remove -b <branchName>
|
|
11
|
-
|
|
12
|
-
# 不指定参数(列出所有分支供多选)
|
|
13
|
-
clawt remove
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
**参数:**
|
|
17
|
-
|
|
18
|
-
| 参数 | 必填 | 说明 |
|
|
19
|
-
| --------- | ---- | ---------------------------------------------------------------------- |
|
|
20
|
-
| `--all` | 否 | 移除当前项目 (`~/.clawt/worktrees/<project>/`) 下所有 worktree |
|
|
21
|
-
| `-b` | 否 | 指定分支名(支持模糊匹配,不传则列出所有分支供多选) |
|
|
22
|
-
|
|
23
|
-
> **提示:** 不传 `--all` 也不传 `-b` 时,会列出当前项目所有 worktree 供交互式多选。
|
|
24
|
-
|
|
25
|
-
**运行流程:**
|
|
26
|
-
|
|
27
|
-
1. **前置校验**:
|
|
28
|
-
- 主 worktree 校验 (2.1)
|
|
29
|
-
- HEAD 存在性校验
|
|
30
|
-
- 项目配置文件校验(确保项目已通过 `clawt init` 初始化)
|
|
31
|
-
2. **获取项目名** (2.2)
|
|
32
|
-
3. **确定待移除的 worktree 列表**:
|
|
33
|
-
- **指定 `--all`** → 选中当前项目所有 worktree(若当前项目无 worktree,则提示并退出)
|
|
34
|
-
- **未指定 `--all`** → 通过 `resolveTargetWorktrees` 解析目标 worktree(多选版本),匹配策略如下:
|
|
35
|
-
- **未传 `-b` 参数**:
|
|
36
|
-
- 无可用 worktree → 报错退出
|
|
37
|
-
- 仅 1 个 worktree → 直接使用,无需选择
|
|
38
|
-
- 多个 worktree → 通过交互式多选列表(Enquirer.MultiSelect)让用户选择(空格选择,回车确认)
|
|
39
|
-
- **传了 `-b` 参数**:
|
|
40
|
-
1. **精确匹配优先**:在 worktree 列表中查找分支名完全相同的 worktree,找到则直接使用
|
|
41
|
-
2. **模糊匹配**(子串匹配,大小写不敏感):
|
|
42
|
-
- 唯一匹配 → 直接使用
|
|
43
|
-
- 多个匹配 → 通过交互式多选列表让用户从匹配结果中选择
|
|
44
|
-
3. **无匹配** → 报错退出,并列出所有可用分支名
|
|
45
|
-
4. **当前分支安全检查**:逐个检查待移除的分支,如果该分支或其对应的验证分支(`clawt-validate-<branchName>`)是主 worktree 当前所在分支,则抛出错误并阻止移除。
|
|
46
|
-
5. 列出即将移除的 worktree 及对应分支:
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
即将移除以下 worktree 及本地分支:
|
|
50
|
-
|
|
51
|
-
1. ~/.clawt/worktrees/main-project/feature-scheme-1 → 分支: feature-scheme-1 验证分支: clawt-validate-feature-scheme-1
|
|
52
|
-
2. ~/.clawt/worktrees/main-project/feature-scheme-2 → 分支: feature-scheme-2 验证分支: clawt-validate-feature-scheme-2
|
|
53
|
-
3. ~/.clawt/worktrees/main-project/feature-scheme-3 → 分支: feature-scheme-3 验证分支: clawt-validate-feature-scheme-3
|
|
54
|
-
|
|
55
|
-
是否同时删除对应的本地分支和验证分支?(y/N)
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
6. **判断是否删除本地分支**:
|
|
59
|
-
- 如果配置文件 `~/.clawt/config.json` 中 `autoDeleteBranch` 为 `true`,则跳过询问,直接删除分支
|
|
60
|
-
- 否则询问用户是否删除,用户拒绝时提示可稍后手动删除
|
|
61
|
-
7. 对每个 worktree 依次执行(单个失败不影响其他):
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
# 移除 worktree
|
|
65
|
-
git worktree remove -f <worktree路径>
|
|
66
|
-
|
|
67
|
-
# 如果用户选择了删除分支(或 autoDeleteBranch 为 true)
|
|
68
|
-
git branch -D <branchName>
|
|
69
|
-
|
|
70
|
-
# 无条件删除验证分支(不受用户确认控制,存在则删除)
|
|
71
|
-
git branch -D clawt-validate-<branchName>
|
|
72
|
-
# 无条件清理该分支对应的 validate 快照
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
8. 如果使用 `--all` 模式,额外清理整个项目的 validate 快照目录。
|
|
76
|
-
|
|
77
|
-
9. 移除完成后执行清理:
|
|
78
|
-
- `git worktree prune` 清理已失效的 worktree 引用
|
|
79
|
-
- 如果 `~/.clawt/worktrees/<project>/` 下已无 worktree,则删除该项目目录
|
|
80
|
-
|
|
81
|
-
10. 批量移除时,单个 worktree 移除失败不会中断整个流程,而是收集所有失败项,最后汇总报告并以错误状态退出(抛出 ClawtError)。
|
|
82
|
-
|
|
83
|
-
**实现要点:**
|
|
84
|
-
|
|
85
|
-
- 消息常量定义在 `src/constants/messages/remove.ts`
|
|
86
|
-
- 分支解析逻辑复用公共模块 `resolveTargetWorktrees`(`src/utils/worktree-matcher.ts`)
|
|
87
|
-
- 验证分支删除通过 `deleteValidateBranch`(`src/utils/validate-branch.ts`),内部判断分支是否存在后才执行删除
|
|
88
|
-
- 快照清理通过 `removeSnapshot` 和 `removeProjectSnapshots`(`src/utils/validate-snapshot.ts`)
|
|
89
|
-
|
|
90
|
-
---
|
package/docs/reset.md
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
### 5.13 重置主 Worktree 工作区和暂存区
|
|
2
|
-
|
|
3
|
-
**命令:**
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
clawt reset
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
**无参数。**
|
|
10
|
-
|
|
11
|
-
**使用场景:**
|
|
12
|
-
|
|
13
|
-
当用户通过 `clawt validate` 将分支变更迁移到主 worktree 后,希望快速清除工作区和暂存区的所有修改,恢复到干净状态。与 `clawt validate --clean` 的区别在于:`reset` 仅重置工作区和暂存区,**不删除** validate 快照文件,也**不切换分支**,适用于只想清空变更而保留快照以便后续增量 validate 的场景。
|
|
14
|
-
|
|
15
|
-
> **设计原因**:reset 的职责是「重置工作区状态」,分支切换属于 validate --clean 和 remove 等命令的职责。将分支切换耦合到 reset 会违反单一职责原则。
|
|
16
|
-
|
|
17
|
-
**运行流程:**
|
|
18
|
-
|
|
19
|
-
1. **前置校验**(`runPreChecks`):
|
|
20
|
-
- `requireMainWorktree`:主 worktree 校验 (2.1)
|
|
21
|
-
- `requireHead`:HEAD 存在校验
|
|
22
|
-
- `requireProjectConfig`:项目级配置校验
|
|
23
|
-
2. **检测工作区状态**:通过 `git status --porcelain` 检测主 worktree 是否有未提交的更改
|
|
24
|
-
- **工作区干净** → 输出提示 `主 worktree 工作区和暂存区已是干净状态,无需重置`,退出
|
|
25
|
-
- **工作区不干净** → 继续
|
|
26
|
-
3. **确认破坏性操作**:如果配置项 `confirmDestructiveOps` 为 `true`,提示确认(显示即将执行的危险指令 `git reset --hard + git clean -fd` 和操作后果 `丢弃所有未提交的更改`),用户取消则输出 `已取消操作` 并退出
|
|
27
|
-
4. **重置工作区和暂存区**:
|
|
28
|
-
```bash
|
|
29
|
-
git reset --hard HEAD
|
|
30
|
-
git clean -fd
|
|
31
|
-
```
|
|
32
|
-
5. **输出成功提示**:
|
|
33
|
-
```
|
|
34
|
-
✓ 主 worktree 工作区和暂存区已重置
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
---
|
package/docs/resume.md
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
### 5.11 在已有 Worktree 中恢复会话
|
|
2
|
-
|
|
3
|
-
**命令:**
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
# 指定分支名(支持模糊匹配)
|
|
7
|
-
clawt resume -b <branchName>
|
|
8
|
-
|
|
9
|
-
# 不指定分支名(列出所有分支供多选)
|
|
10
|
-
clawt resume
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
**参数:**
|
|
14
|
-
|
|
15
|
-
| 参数 | 必填 | 说明 |
|
|
16
|
-
| ---- | ---- | ----------------------------------------------------- |
|
|
17
|
-
| `-b` | 否 | 要恢复的分支名(支持模糊匹配,不传则列出所有分支供多选) |
|
|
18
|
-
|
|
19
|
-
**使用场景:**
|
|
20
|
-
|
|
21
|
-
当用户之前通过 `clawt run` 或 `clawt create` 创建了 worktree 但会话已结束,希望在该 worktree 中重新打开 Claude Code 交互式界面继续工作。支持一次选中多个分支,自动在独立终端 Tab 中批量恢复。
|
|
22
|
-
|
|
23
|
-
**运行流程:**
|
|
24
|
-
|
|
25
|
-
1. **前置校验**(`PRE_CHECK_RESUME`):主 worktree 校验 (2.1) + HEAD 存在性校验 + Claude Code CLI 可用性校验
|
|
26
|
-
2. **解析目标 worktree**:根据是否传入 `-b` 参数以及 worktree 数量,采用不同的解析策略:
|
|
27
|
-
- **未传 `-b` 参数**:
|
|
28
|
-
- 获取当前项目所有 worktree
|
|
29
|
-
- 无可用 worktree → 报错退出
|
|
30
|
-
- 仅 1 个 worktree → 通过 `resolveTargetWorktrees` 直接使用,无需选择
|
|
31
|
-
- 多个 worktree → 通过 `promptGroupedMultiSelectBranches` 展示**按日期分组的交互式多选列表**(详见下文「按日期分组多选」)
|
|
32
|
-
- **传了 `-b` 参数**:通过 `resolveTargetWorktrees` 解析,匹配策略如下:
|
|
33
|
-
1. **精确匹配优先**:在 worktree 列表中查找分支名完全相同的 worktree,找到则直接使用
|
|
34
|
-
2. **模糊匹配**(子串匹配,大小写不敏感):
|
|
35
|
-
- 唯一匹配 → 直接使用
|
|
36
|
-
- 多个匹配 → 通过交互式多选列表让用户从匹配结果中选择
|
|
37
|
-
3. **无匹配** → 报错退出,并列出所有可用分支名
|
|
38
|
-
3. **根据选中数量自动分发**:
|
|
39
|
-
- **用户未选择任何分支** → 直接退出
|
|
40
|
-
- **选中 1 个** → 根据全局配置项 `resumeInPlace` 决定打开方式:
|
|
41
|
-
- `resumeInPlace: true` → 在当前终端就地恢复,通过 `launchInteractiveClaude()` 启动(使用 `spawnSync` + `inherit stdio`)
|
|
42
|
-
- `resumeInPlace: false`(默认) → 通过 `launchInteractiveClaudeInNewTerminal()` 在新终端 Tab 中恢复,终端类型由 `terminalApp` 配置控制
|
|
43
|
-
- **选中多个** → 进入批量恢复流程(见下文),始终在新终端 Tab 中打开,不受 `resumeInPlace` 影响
|
|
44
|
-
|
|
45
|
-
**批量恢复流程:**
|
|
46
|
-
|
|
47
|
-
1. **计算会话状态**:一次性遍历所有选中的 worktree,通过 `hasClaudeSessionHistory()` 检测是否存在历史会话,构建 sessionMap 避免重复 I/O
|
|
48
|
-
2. **输出预览**:列出即将恢复的分支及其会话状态("继续上次对话"或"新对话")
|
|
49
|
-
3. **用户确认**:提示即将在 N 个独立终端 Tab 中恢复会话,等待用户确认
|
|
50
|
-
4. **逐个在新终端 Tab 中启动**:通过 `launchInteractiveClaudeInNewTerminal()` 构建 shell 命令并通过 AppleScript 在新终端 Tab 中执行
|
|
51
|
-
5. **输出完成提示**
|
|
52
|
-
|
|
53
|
-
**终端 Tab 管理:**
|
|
54
|
-
|
|
55
|
-
批量恢复通过 `openCommandInNewTerminalTab()`(`src/utils/terminal.ts`)在新终端 Tab 中启动 Claude Code。终端类型由配置项 `terminalApp` 控制:
|
|
56
|
-
|
|
57
|
-
| 配置值 | 行为 |
|
|
58
|
-
| ---------- | ------------------------------------------------------------ |
|
|
59
|
-
| `auto` | 自动检测:优先检测 iTerm2 是否已安装(`/Applications/iTerm.app`),已安装则使用 iTerm2,否则降级到 Terminal.app |
|
|
60
|
-
| `iterm2` | 强制使用 iTerm2 |
|
|
61
|
-
| `terminal` | 强制使用 Terminal.app |
|
|
62
|
-
|
|
63
|
-
**平台限制:** 批量恢复目前仅支持 macOS 平台(通过 AppleScript 打开终端 Tab)。非 macOS 平台会抛出错误。
|
|
64
|
-
|
|
65
|
-
**权限要求:** Terminal.app 通过 System Events 模拟键盘操作(`Cmd+T`)新建 Tab,需要在「系统设置 → 隐私与安全性 → 辅助功能」中授权终端应用。iTerm2 使用原生 AppleScript 接口,无需辅助功能权限。
|
|
66
|
-
|
|
67
|
-
启动命令通过配置项 `claudeCodeCommand`(默认值 `claude`)指定,与 `clawt run` 不传 `--tasks` 时的交互式界面行为一致。
|
|
68
|
-
|
|
69
|
-
**按日期分组多选:**
|
|
70
|
-
|
|
71
|
-
当未传 `-b` 且有多个 worktree 时,使用 `promptGroupedMultiSelectBranches` 展示按创建日期分组的交互式多选列表,实现流程如下:
|
|
72
|
-
|
|
73
|
-
1. **日期分组**(`groupWorktreesByDate`):通过 `statSync` 获取各 worktree 目录的文件系统创建时间(`birthtime`),按本地时区格式化为 `YYYY-MM-DD` 作为分组键。无法获取创建时间的分支归入「未知日期」组。分组按日期降序排列,未知日期组在最后。
|
|
74
|
-
2. **构建选项列表**(`buildGroupedChoices`):生成包含以下元素的 Enquirer MultiSelect choices 数组:
|
|
75
|
-
- 顶部:全局全选选项 `[select-all]`
|
|
76
|
-
- 每组:日期分隔线(显示日期和相对时间,如「2026-02-26(昨天)」)→ 组级全选选项 `[select-all: YYYY-MM-DD]` → 该组内各分支
|
|
77
|
-
2.5. **构建组成员映射**(`buildGroupMembershipMap`):生成"组全选 name → 该组分支 name 列表"的 Map,供三级联动的 `space()` 方法快速查找某个组全选项对应的所有分支
|
|
78
|
-
3. **三级联动选择**:通过继承 Enquirer MultiSelect 并覆写 `space()` 方法实现,同步逻辑由 `syncGlobalSelectAll` 和 `syncGroupSelectAll` 两个内部函数负责:
|
|
79
|
-
- **全局全选**:toggle 所有 choices(含组全选)
|
|
80
|
-
- **组级全选**:toggle 该组内所有分支,并同步全局全选状态
|
|
81
|
-
- **普通分支**:toggle 该分支,同步所属组全选和全局全选状态
|
|
82
|
-
4. **过滤结果**:返回时过滤掉全选项和组全选项,只返回实际选中的 worktree
|
|
83
|
-
|
|
84
|
-
相对日期显示规则:`formatRelativeDate` 基于自然日差值计算——今天 / 昨天 / N 天前 / N 个月前 / N 年前。
|
|
85
|
-
|
|
86
|
-
相关常量定义在 `src/constants/prompt.ts`:
|
|
87
|
-
|
|
88
|
-
| 常量 | 说明 |
|
|
89
|
-
| ---- | ---- |
|
|
90
|
-
| `GROUP_SELECT_ALL_PREFIX` | 组级全选选项的 name 前缀(`__group_select_all_`) |
|
|
91
|
-
| `GROUP_SELECT_ALL_LABEL(dateLabel)` | 生成组级全选选项的显示文本 |
|
|
92
|
-
| `GROUP_SEPARATOR_LABEL(dateLabel, relativeTime)` | 生成日期分隔线的显示文本(含 chalk 高亮) |
|
|
93
|
-
| `UNKNOWN_DATE_GROUP` | 无法获取创建日期时的默认分组名称(`未知日期`) |
|
|
94
|
-
| `UNKNOWN_DATE_SEPARATOR_LABEL` | 未知日期分组的分隔线显示文本 |
|
|
95
|
-
| `SELECT_ALL_NAME` | 全局全选选项的标识名称(`__select_all__`) |
|
|
96
|
-
| `SELECT_ALL_LABEL` | 全局全选选项的显示文本(`[select-all]`) |
|
|
97
|
-
|
|
98
|
-
**会话自动续接:** 启动前会自动检测该 worktree 是否存在 Claude Code 历史会话(通过检查 `~/.claude/projects/<encoded-path>/` 下是否有 `.jsonl` 文件判断),如果存在则自动追加 `--continue` 参数继续上次对话,否则打开新对话。启动信息中会显示当前模式("继续上次对话"或"新对话")。路径编码规则:将绝对路径中所有非字母数字字符替换为 `-`(与 Claude Code 源码的编码逻辑一致)。
|
|
99
|
-
|
|
100
|
-
---
|