@chlrc/aiw 0.1.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/README.md +681 -0
- package/README.zh-CN.md +681 -0
- package/bin/aiw +8 -0
- package/config/agents.toml +24 -0
- package/config/aiw.toml +41 -0
- package/config/commit-prompt.md +8 -0
- package/config/lazygit-delta.yml +15 -0
- package/package.json +42 -0
- package/scripts/install-global.sh +16 -0
- package/src/agent.mjs +53 -0
- package/src/cli.mjs +422 -0
- package/src/commit.mjs +175 -0
- package/src/config.mjs +190 -0
- package/src/deps.mjs +172 -0
- package/src/git.mjs +210 -0
- package/src/hooks.mjs +252 -0
- package/src/init.mjs +719 -0
- package/src/layout.mjs +54 -0
- package/src/prompt.mjs +60 -0
- package/src/run.mjs +78 -0
- package/src/workspace.mjs +1422 -0
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,681 @@
|
|
|
1
|
+
# aiw
|
|
2
|
+
|
|
3
|
+
`aiw` 是一个个人 AI 编程工作流 CLI。它把一组锋利的终端工具串成稳定路径:开始任务、打开适合 AI 协作的 workspace、审查改动、生成提交、清理 worktree。
|
|
4
|
+
|
|
5
|
+
默认文档语言是英文。英文版见 [README.md](./README.md)。
|
|
6
|
+
|
|
7
|
+
## aiw 是什么
|
|
8
|
+
|
|
9
|
+
AIW 是一个很薄的编排层。它不替代你已经在用的工具,而是决定下一步应该调用什么,检查依赖是否齐全,然后把具体能力交还给对应工具。
|
|
10
|
+
|
|
11
|
+
边界如下:
|
|
12
|
+
|
|
13
|
+
- `aiw` 负责工作流决策、配置读取、依赖门禁、prompt、命令路由和 cmux layout 生成。
|
|
14
|
+
- Worktrunk 负责 worktree 生命周期。
|
|
15
|
+
- cmux 负责 workspace 和 pane。
|
|
16
|
+
- lazygit 负责 Git TUI 操作。
|
|
17
|
+
- delta 负责 diff 渲染。
|
|
18
|
+
- agent CLI 负责模型交互。
|
|
19
|
+
- yazi、nvim、rg、fd、fzf、bat、eza 保持各自原生职责。
|
|
20
|
+
|
|
21
|
+
因此,AIW 的目标不是变成终端模拟器、Git 客户端、编辑器、diff 查看器、守护进程、任务数据库或 agent 管理器,而是把个人工作流固定下来。
|
|
22
|
+
|
|
23
|
+
## 快速上手
|
|
24
|
+
|
|
25
|
+
从当前 checkout 运行:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
node bin/aiw --help
|
|
29
|
+
node bin/aiw doctor
|
|
30
|
+
node bin/aiw cmux-new --agent codex
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
如果 `aiw` 已经安装到 `PATH`:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
aiw doctor
|
|
37
|
+
aiw cmux-new --agent codex
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
日常工作流通常是:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# 1. 检查本机工具链是否就绪。
|
|
44
|
+
aiw doctor
|
|
45
|
+
|
|
46
|
+
# 2. 创建或切换 Worktrunk worktree,并打开 AIW cmux layout。
|
|
47
|
+
aiw cmux-new --agent codex
|
|
48
|
+
|
|
49
|
+
# 3. 在四分屏 workspace 里工作。
|
|
50
|
+
# Files: yazi
|
|
51
|
+
# Agent: codex / claude / opencode / gemini / aider
|
|
52
|
+
# Git: lazygit + AIW overlay
|
|
53
|
+
# Diff: cmux-git-diff,或 git diff 通过 delta 渲染
|
|
54
|
+
|
|
55
|
+
# 4. 审查并 stage 改动。
|
|
56
|
+
aiw git
|
|
57
|
+
|
|
58
|
+
# 5. 基于 staged changes 生成 commit message 并提交。
|
|
59
|
+
aiw commit
|
|
60
|
+
|
|
61
|
+
# 6. feature worktree 完成后合并并清理。
|
|
62
|
+
aiw done dev
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
开发 AIW 自身时,优先运行 checkout 内 CLI:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
node bin/aiw doctor
|
|
69
|
+
node bin/aiw doctor --gate cmux-new --agent codex
|
|
70
|
+
node bin/aiw layout --agent codex --dry-run
|
|
71
|
+
node bin/aiw cmux-new --repo ~/Code/my-repo --branch feat/foo --agent codex --dry-run
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 安装模型
|
|
75
|
+
|
|
76
|
+
AIW 是 Node.js ESM CLI,要求 Node.js 18 或更新版本。可执行入口是 [bin/aiw](./bin/aiw),package metadata 把它暴露为 `aiw` binary。
|
|
77
|
+
|
|
78
|
+
本地开发时,直接运行 `node bin/aiw ...` 即可。需要全局命令时,如果 checkout 内存在安装脚本,可运行:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm run install:global
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
AIW 按以下顺序读取配置:
|
|
85
|
+
|
|
86
|
+
1. 设置了 `$AIW_CONFIG_DIR` 时使用它。
|
|
87
|
+
2. 存在 `~/.config/aiw` 时使用它。
|
|
88
|
+
3. 否则使用仓库内默认 [config/](./config) 目录。
|
|
89
|
+
|
|
90
|
+
这样仓库可以提供开箱默认值,同时允许个人配置留在业务仓库之外。
|
|
91
|
+
|
|
92
|
+
## 初始化
|
|
93
|
+
|
|
94
|
+
在 macOS 或 Linux 上,可以用 `npx @chlrc/aiw init` 为一台机器初始化 AIW。
|
|
95
|
+
|
|
96
|
+
初始化流程假设 Node.js 和 `npx` 已经可用。它会检查必要环境变量、POSIX shell 平台,以及默认工作流所需的阻塞依赖;如果缺少阻塞依赖,会在写文件前停止并给出安装建议。`fd`、`eza`、非默认 agent CLI 这类可选工具只报告,不阻塞。
|
|
97
|
+
|
|
98
|
+
依赖门禁通过后,init 会创建缺失的目录和配置文件:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npx @chlrc/aiw init
|
|
102
|
+
npx @chlrc/aiw init --cmux-scope home
|
|
103
|
+
npx @chlrc/aiw init --cmux-scope code --code-root ~/Code --worktrees-root ~/worktrees
|
|
104
|
+
npx @chlrc/aiw init --cmux-scope none --dry-run
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- AIW 配置默认写入 `~/.config/aiw`;设置了 `$AIW_CONFIG_DIR` 时使用它。
|
|
108
|
+
- `--code-root` 和 `--worktrees-root` 控制写入 `aiw.toml` 的路径,默认是 `~/Code` 和 `~/worktrees`。
|
|
109
|
+
- cmux 注册默认写入 `~/.config/cmux/cmux.json`;`--cmux-scope code` 写入 `<code-root>/.cmux/cmux.json`;`--cmux-scope none` 跳过 cmux。
|
|
110
|
+
- 交互式终端中,init 会询问 cmux 注册位置;`--yes` 使用默认值且不提示。
|
|
111
|
+
- 已存在的 AIW 配置默认保留;使用 `--force` 覆盖前会先创建备份。
|
|
112
|
+
- 已存在的 cmux 配置会合并,不会整体替换;AIW action 会被加入,已有非 AIW plus-button action 会通过 context menu 保留。
|
|
113
|
+
- Skills 暂不由 init 初始化。
|
|
114
|
+
|
|
115
|
+
## 技术栈
|
|
116
|
+
|
|
117
|
+
AIW 有意保持低依赖:
|
|
118
|
+
|
|
119
|
+
- Runtime: Node.js ESM,Node >= 18。
|
|
120
|
+
- Config: 少量 TOML 文件,由 AIW 自己解析。
|
|
121
|
+
- Process execution: 通过本地 helper 调用 Node child process。
|
|
122
|
+
- Workspace orchestration: Worktrunk (`wt`) 和 cmux。
|
|
123
|
+
- Git UI: lazygit;仅 `aiw git` 会加载 AIW 专用 overlay。
|
|
124
|
+
- Diff UI: 优先 `cmux-git-diff`,否则 `git diff | delta`。
|
|
125
|
+
- Picker 和搜索: fzf、rg、fd、bat。
|
|
126
|
+
- 文件和编辑界面: yazi、nvim。
|
|
127
|
+
- Agent: 在 [config/agents.toml](./config/agents.toml) 中声明命令适配器。
|
|
128
|
+
|
|
129
|
+
当前还没有完整自动化测试套件。代码改动后必须运行:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npm run check
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
风险较高的 CLI 行为建议在 `/private/tmp` 下创建临时 Git repo,并尽量用非交互命令验证。
|
|
136
|
+
|
|
137
|
+
## 心智模型
|
|
138
|
+
|
|
139
|
+
可以把 AIW 理解成三层:
|
|
140
|
+
|
|
141
|
+
1. cmux 是入口。plus button、command palette,或者 cmux 里的 terminal action,是新任务开始的地方。
|
|
142
|
+
2. `aiw` 是编排入口。它负责解析 repo、branch/worktree、agent、依赖门禁和 layout,然后调用正确的底层命令。
|
|
143
|
+
3. 成熟 CLI 工具负责真正执行:Worktrunk 管 worktree,yazi 管文件,nvim/LazyVim 管编辑,lazygit 管审查和 stage,delta 管 diff,rg/fd/fzf/bat/eza 管搜索和查看,zoxide 融入外层 shell 导航,agent CLI 负责模型交互。
|
|
144
|
+
|
|
145
|
+
AIW 最初的目标很实际:在 Codex App 之外复刻它里面有价值的 workspace 动线,但不把 workflow 搬进一个封闭 App。目标不只是“屏幕上有四个 pane”,而是一条连续动作:打开 cmux,启动 AIW,创建或切换 worktree,进入标准 workspace,看文件,和 agent 交流,stage hunk,看实时 diff,commit,merge,清理。
|
|
146
|
+
|
|
147
|
+
关键差异是控制权。成熟 App 的体验可以很完整,但它通常也固定了工作流形状。在终端工具栈里,你可以选择文件管理器、编辑器配置、Git UI、diff renderer、fuzzy finder、目录跳转工具、shell 行为、快捷键和 agent CLI。shell 渲染也是体验的一部分:当命令输出是开发过程的核心时,原生终端工具比嵌入式 shell 界面更可信、更可调,也更容易拼装。
|
|
148
|
+
|
|
149
|
+
所以 AIW 保留 Codex-style workspace 的模式,但把它做成 cmux-first、terminal-native 和 agent-neutral。同一套动线应该可以运行在 Codex、Claude、opencode、Gemini、aider,或者任何未来遵守同一配置契约的 agent adapter 上。如果你对自定义性要求很强,希望把开发控制权还给自己的终端工具栈,AIW 就是这套实验。
|
|
150
|
+
|
|
151
|
+
开始工作时,AIW 要回答四个问题:
|
|
152
|
+
|
|
153
|
+
1. 当前要处理哪个 repository?
|
|
154
|
+
2. 这项工作应该放在哪个 worktree 或 branch?
|
|
155
|
+
3. 应该在代码旁边打开哪个 agent?
|
|
156
|
+
4. 工作时默认可见哪些 pane?
|
|
157
|
+
|
|
158
|
+
答案确定后,AIW 就停止做领域决策,把执行交给底层工具:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
aiw cmux-new
|
|
162
|
+
-> dependency gate
|
|
163
|
+
-> repository and branch selection
|
|
164
|
+
-> Worktrunk creates or switches the worktree
|
|
165
|
+
-> aiw layout builds the cmux workspace
|
|
166
|
+
-> cmux opens Files / Agent / Git / Diff panes
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
清理流程也是同一套思想:
|
|
170
|
+
|
|
171
|
+
```text
|
|
172
|
+
aiw workspace gc
|
|
173
|
+
-> read Worktrunk and Git state
|
|
174
|
+
-> mark dirty, merged, stale, and cmux-open signals
|
|
175
|
+
-> remove only clean + merged worktrees when explicitly confirmed
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
AIW 不试图隐藏底层工具。它做的是缩短常见路径,并把危险路径显式化。
|
|
179
|
+
|
|
180
|
+
## 设计逻辑
|
|
181
|
+
|
|
182
|
+
### cmux 是入口,AIW 是编排器
|
|
183
|
+
|
|
184
|
+
预期入口是 cmux,而不是一个独立的 AIW dashboard。cmux 已经负责窗口、workspace、pane,以及用户真实看到的开发界面。AIW 站在这个入口背后,作为决定打开什么、怎么串起来的命令。
|
|
185
|
+
|
|
186
|
+
所以主动线是:
|
|
187
|
+
|
|
188
|
+
```text
|
|
189
|
+
cmux entry
|
|
190
|
+
-> aiw cmux-new
|
|
191
|
+
-> dependency gate
|
|
192
|
+
-> Worktrunk worktree create/switch
|
|
193
|
+
-> aiw layout
|
|
194
|
+
-> cmux workspace with Files / Agent / Git / Diff
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
价值在于层与层之间的交接很流畅。cmux 继续作为开始工作和承载视图的地方;AIW 作为 workflow brain;底层 CLI 继续保持锋利和原生。
|
|
198
|
+
|
|
199
|
+
### 复刻 App 动线,而不是复刻 App 锁定
|
|
200
|
+
|
|
201
|
+
AIW 借用了 Codex App-style 界面里最有价值的部分:把代码 workspace、agent、Git 审查和 diff loop 放在一起,并让隔离任务的启动变得自然。它不借用锁定。整个 workflow 表达为命令、配置文件和 cmux layout,因此每一层都可以替换。
|
|
202
|
+
|
|
203
|
+
这也是为什么 agent 支持是 adapter-based。agent 不硬编码进产品里。它只是一个命令,加上用于交互式 pane 的可选 args,以及用于一次性生成 commit message 的 `commit_args`。
|
|
204
|
+
|
|
205
|
+
### 不把个人工作流写进业务仓库
|
|
206
|
+
|
|
207
|
+
AIW 默认不向业务仓库写入 `.aiw`、`.worktrunk` 或 `.cmux` 文件。AIW 自己拥有的运行时 metadata,例如创建 worktree 时记录的 `feature -> target`,写在 Git common dir 下,而不是业务 working tree 里。
|
|
208
|
+
|
|
209
|
+
### 让终端继续作为控制平面
|
|
210
|
+
|
|
211
|
+
AIW 假设用户应该能够替换工具、调整渲染、保留原生 shell 行为,并继续使用已有肌肉记忆。它组合 rg、zoxide、yazi、nvim/LazyVim、lazygit、delta、fzf、Worktrunk、cmux 和 agent CLI 这类成熟工具,而不是把它们压平成一个新的封闭 UI。
|
|
212
|
+
|
|
213
|
+
这也是为什么 shell 和 diff 输出继续留在 terminal-native 工具里。终端不是 AIW 的 fallback surface,而是主要控制平面。
|
|
214
|
+
|
|
215
|
+
### 有副作用前先过门禁
|
|
216
|
+
|
|
217
|
+
会创建 worktree 或打开 cmux layout 的命令会先跑 dependency gate。如果外部工具缺失,AIW 会在创建新 workspace 前停止。
|
|
218
|
+
|
|
219
|
+
常用检查:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
aiw doctor
|
|
223
|
+
aiw doctor --gate git
|
|
224
|
+
aiw doctor --gate cmux-new --agent codex
|
|
225
|
+
aiw doctor --gate commit --agent codex
|
|
226
|
+
aiw doctor --json
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### 人类交互时可选择,脚本调用时要显式
|
|
230
|
+
|
|
231
|
+
在 TTY 中,缺少必要参数时会尽量打开可搜索 picker。非交互调用中,应显式传入参数,或保留底层工具默认行为。
|
|
232
|
+
|
|
233
|
+
例如:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
aiw cmux-new
|
|
237
|
+
aiw cmux-new --pick-repo
|
|
238
|
+
aiw workspace open
|
|
239
|
+
aiw workspace open feat/foo --agent codex
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### 保留原生工具职责
|
|
243
|
+
|
|
244
|
+
`aiw git` 打开 lazygit,不重写 stage、hunk 选择或提交前审查。
|
|
245
|
+
|
|
246
|
+
`aiw files` 打开 yazi,不变成文件管理器。
|
|
247
|
+
|
|
248
|
+
`aiw diff` 渲染当前 Git diff,不实现自定义 diff engine。
|
|
249
|
+
|
|
250
|
+
## 核心命令
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
npx @chlrc/aiw init
|
|
254
|
+
aiw doctor
|
|
255
|
+
aiw cmux-new --agent codex
|
|
256
|
+
aiw cmux-new --pick-repo --agent codex
|
|
257
|
+
aiw cmux-new --local --agent codex
|
|
258
|
+
aiw cmux-new --repo ~/Code/my-repo --branch feat/foo --agent codex --dry-run
|
|
259
|
+
aiw layout --agent codex --dry-run
|
|
260
|
+
|
|
261
|
+
aiw workspace list
|
|
262
|
+
aiw workspace list --json
|
|
263
|
+
aiw workspace open
|
|
264
|
+
aiw workspace open feat/foo --agent codex
|
|
265
|
+
aiw workspace done dev
|
|
266
|
+
aiw workspace remove feat/foo
|
|
267
|
+
aiw workspace gc
|
|
268
|
+
aiw workspace gc --dry-run
|
|
269
|
+
aiw workspace gc --apply
|
|
270
|
+
|
|
271
|
+
aiw git
|
|
272
|
+
aiw diff
|
|
273
|
+
aiw diff --watch
|
|
274
|
+
aiw diff --staged
|
|
275
|
+
aiw commit
|
|
276
|
+
aiw commit --agent codex
|
|
277
|
+
aiw commit --prompt "Use scope aiw"
|
|
278
|
+
aiw commit --prompt-file ~/commit-style.md
|
|
279
|
+
|
|
280
|
+
aiw files
|
|
281
|
+
aiw edit src/file.ts:10
|
|
282
|
+
aiw grep keyword
|
|
283
|
+
aiw pick
|
|
284
|
+
aiw tree 3
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
日常使用保留了 workspace 短 alias:
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
aiw ws list
|
|
291
|
+
aiw list
|
|
292
|
+
aiw open feat/foo
|
|
293
|
+
aiw switch feat/foo
|
|
294
|
+
aiw done
|
|
295
|
+
aiw remove feat/foo
|
|
296
|
+
aiw gc
|
|
297
|
+
aiw clean
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Worktree 和 cmux 工作流
|
|
301
|
+
|
|
302
|
+
`aiw cmux-new` 是新任务的主入口。
|
|
303
|
+
|
|
304
|
+
常见形式:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
aiw cmux-new
|
|
308
|
+
aiw cmux-new --agent codex
|
|
309
|
+
aiw cmux-new --pick-repo --agent codex
|
|
310
|
+
aiw cmux-new --repo ~/Code/my-repo --agent codex
|
|
311
|
+
aiw cmux-new --repo ~/Code/my-repo --branch feat/foo --agent codex
|
|
312
|
+
aiw cmux-new --local --agent codex
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
行为:
|
|
316
|
+
|
|
317
|
+
- 能识别当前 Git repo 时,默认使用当前 repo。
|
|
318
|
+
- `--pick-repo` 可以选择 `paths.code_root` 下的其他 repo。
|
|
319
|
+
- TTY 中没有传 branch 时,AIW 会让你选择从当前 `HEAD` 创建新分支、打开当前 checkout、或选择已有分支。
|
|
320
|
+
- 创建新分支时运行 `wt switch --create <branch> --base @ -x "aiw layout --agent <agent>"`。
|
|
321
|
+
- 选择已有分支时运行 `wt switch <branch> -x "aiw layout --agent <agent>"`。
|
|
322
|
+
- `--local` 在当前 checkout 打开标准 layout,不创建 Worktrunk worktree。
|
|
323
|
+
- `--dry-run` 打印将要运行的命令。
|
|
324
|
+
|
|
325
|
+
标准 cmux layout:
|
|
326
|
+
|
|
327
|
+
```text
|
|
328
|
+
+----------------------+----------------------+
|
|
329
|
+
| Files | Agent |
|
|
330
|
+
| aiw files | codex/claude/etc. |
|
|
331
|
+
+----------------------+----------------------+
|
|
332
|
+
| Git | Diff |
|
|
333
|
+
| aiw git | aiw diff --watch |
|
|
334
|
+
+----------------------+----------------------+
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
`aiw layout --print-json` 可以只打印 cmux layout JSON,不打开 cmux。
|
|
338
|
+
|
|
339
|
+
## Workspace 管理
|
|
340
|
+
|
|
341
|
+
`aiw workspace ...` 是 Worktrunk worktree 的可见性和生命周期层。
|
|
342
|
+
|
|
343
|
+
### 列表
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
aiw workspace list
|
|
347
|
+
aiw workspace list --json
|
|
348
|
+
aiw workspace list --stale-seconds 604800
|
|
349
|
+
aiw workspace states
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
表格会合并 Worktrunk、Git 和 cmux 信号:
|
|
353
|
+
|
|
354
|
+
- branch 和 path
|
|
355
|
+
- dirty 或 clean 状态
|
|
356
|
+
- Worktrunk integration state
|
|
357
|
+
- AIW 创建 worktree 时记录的 merge target
|
|
358
|
+
- 没有记录 target 时推断出的 merged target
|
|
359
|
+
- cmux 是否已打开
|
|
360
|
+
- age
|
|
361
|
+
- GC signal
|
|
362
|
+
|
|
363
|
+
这些状态标记刻意保持保守。dirty worktree 永远不会成为自动清理候选。
|
|
364
|
+
|
|
365
|
+
### 打开
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
aiw workspace open
|
|
369
|
+
aiw workspace open feat/foo --agent codex
|
|
370
|
+
aiw workspace open /path/to/worktree --agent codex
|
|
371
|
+
aiw open feat/foo
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
TTY 中不传 target 时,`workspace open` 会打开可搜索 picker,列出现有 worktree 和本地 branch。branch target 通过 Worktrunk 打开;path target 则直接在对应 Git root 打开 AIW cmux layout。
|
|
375
|
+
|
|
376
|
+
### 收尾
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
aiw workspace done
|
|
380
|
+
aiw workspace done dev
|
|
381
|
+
aiw workspace done dev --no-close-cmux
|
|
382
|
+
aiw done dev
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
`done` 只能在 feature worktree 内执行。主 workspace 会被拒绝;当前 worktree dirty 时也会被拒绝。
|
|
386
|
+
|
|
387
|
+
通过检查后,AIW 把 merge 和 cleanup 交给 Worktrunk:
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
wt merge <target>
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
如果 AIW 在创建 worktree 时记录过 target,裸 `aiw done` 可以使用该 target。TTY 中缺少 target 时会打开目标分支 picker。成功 merge 后,AIW 默认关闭匹配的 cmux workspace;传 `--no-close-cmux` 可保留。
|
|
394
|
+
|
|
395
|
+
### 删除和 GC
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
aiw workspace remove feat/foo
|
|
399
|
+
aiw workspace remove feat/foo --force
|
|
400
|
+
aiw workspace gc
|
|
401
|
+
aiw workspace gc --dry-run
|
|
402
|
+
aiw workspace gc --apply
|
|
403
|
+
aiw workspace gc --yes
|
|
404
|
+
aiw workspace gc --json
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
`remove` 会在调用 `wt remove` 前做 dirty check。只有明确要把风险交给 Worktrunk 时才使用 `--force`。
|
|
408
|
+
|
|
409
|
+
`gc` 拆分三类信号:
|
|
410
|
+
|
|
411
|
+
- `dirty`: 阻止自动清理。
|
|
412
|
+
- `merged`: branch 已 integrated、same commit、empty,或确认已包含在目标分支。
|
|
413
|
+
- `stale`: 最近一次 commit 时间超过 `workspace.stale_seconds`,默认七天。
|
|
414
|
+
|
|
415
|
+
只有 clean + merged 的 worktree 会进入可删除候选。stale 但 dirty 或未合并的 worktree 只会产生 warning。
|
|
416
|
+
|
|
417
|
+
### Workspace hooks
|
|
418
|
+
|
|
419
|
+
Workspace hooks 可以在 AIW 初始化 cmux workspace 前,或删除 worktree 前运行 shell 命令。全局 hooks 配在 `~/.config/aiw/aiw.toml`;项目 hooks 配在 Git repo 根目录下显式存在的 `.aiw.toml`。AIW 只读取已存在的项目配置文件,不会主动创建业务仓库里的个人 workflow 文件。
|
|
420
|
+
|
|
421
|
+
```toml
|
|
422
|
+
[workspace.hooks]
|
|
423
|
+
pre_init = ["echo preparing $AIW_WORKSPACE_PATH"]
|
|
424
|
+
pre_remove = ["echo removing $AIW_WORKSPACE_TARGET"]
|
|
425
|
+
|
|
426
|
+
[workspace.hooks.projects.my-repo]
|
|
427
|
+
pre_init = ["echo preparing only $AIW_PROJECT_NAME"]
|
|
428
|
+
pre_remove = ["echo cleaning only $AIW_PROJECT_PATH"]
|
|
429
|
+
|
|
430
|
+
[workspace.hooks.projects.my-alias]
|
|
431
|
+
match = "repo.name.with.dots"
|
|
432
|
+
path = "~/Code/repo.name.with.dots"
|
|
433
|
+
pre_init = ["echo project matched by name or path"]
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
执行顺序是:全局 hooks、匹配的全局项目 hooks、项目本地 hooks。`[workspace.hooks.projects.<name>]` 默认用 `<name>` 匹配当前 worktree 名和 Git common-dir 项目名;如果表名只是别名,或需要按路径匹配,可以使用 `match`、`path`、`paths`、`repo`、`repos`。支持 `*` 通配符。
|
|
437
|
+
|
|
438
|
+
命令会在目标 workspace path 下通过 `sh -lc` 顺序执行;任一 hook 失败都会中断当前动作。`pre_init` 在 `aiw layout` 调用 `cmux new-workspace` 前执行。`pre_remove` 在 `aiw workspace done`、`aiw workspace remove` 和 `aiw workspace gc --apply` 通过 Worktrunk 删除路径前执行。
|
|
439
|
+
|
|
440
|
+
Hook 命令会收到这些环境变量:`AIW_HOOK_EVENT`、`AIW_HOOK_SOURCE`、`AIW_HOOK_CONFIG`、`AIW_HOOK_RULE`、`AIW_REPO`、`AIW_PROJECT_NAME`、`AIW_PROJECT_PATH`、`AIW_WORKSPACE_PATH`、`AIW_WORKSPACE_BRANCH`、`AIW_WORKSPACE_TARGET`、`AIW_AGENT`。
|
|
441
|
+
|
|
442
|
+
## Git、Diff 和 AI Commit
|
|
443
|
+
|
|
444
|
+
### lazygit Overlay
|
|
445
|
+
|
|
446
|
+
`aiw git` 用 AIW overlay 打开 lazygit:
|
|
447
|
+
|
|
448
|
+
```bash
|
|
449
|
+
lazygit --use-config-file <aiw-config-dir>/lazygit-delta.yml
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
这个 overlay:
|
|
453
|
+
|
|
454
|
+
- 使用 delta 展示 diff
|
|
455
|
+
- 增加全局 `Ctrl-A` 自定义命令
|
|
456
|
+
- 询问可选 AI commit instruction
|
|
457
|
+
- 运行 `aiw commit --prompt ...`
|
|
458
|
+
|
|
459
|
+
直接运行 `lazygit` 不受影响。
|
|
460
|
+
|
|
461
|
+
### Diff
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
aiw diff
|
|
465
|
+
aiw diff --watch
|
|
466
|
+
aiw diff --staged
|
|
467
|
+
aiw diff --all
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
对 unstaged diff,AIW 优先使用 `cmux-git-diff`。缺失时,使用 Git diff 输出并通过 delta 渲染。`--watch` 每两秒刷新。
|
|
471
|
+
|
|
472
|
+
### AI Commit
|
|
473
|
+
|
|
474
|
+
`aiw commit` 只处理 staged changes,不会默默帮你 stage 文件。
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
aiw git
|
|
478
|
+
aiw commit
|
|
479
|
+
aiw commit --agent codex
|
|
480
|
+
aiw commit --prompt "Use scope aiw"
|
|
481
|
+
aiw commit --prompt-file ~/commit-style.md
|
|
482
|
+
aiw commit --print-prompt
|
|
483
|
+
aiw commit --dry-run
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
流程:
|
|
487
|
+
|
|
488
|
+
1. 读取 `git diff --cached`、`git diff --cached --stat` 和 `git status --short`。
|
|
489
|
+
2. 基于 [config/commit-prompt.md](./config/commit-prompt.md) 构造 prompt。
|
|
490
|
+
3. 追加 `--prompt` 和 `--prompt-file` 内容。
|
|
491
|
+
4. 按 [config/agents.toml](./config/agents.toml) 的 `commit_args` 调用选定 agent。
|
|
492
|
+
5. 清理 agent 输出,得到 commit message。
|
|
493
|
+
6. 运行 `git commit -F -`。
|
|
494
|
+
7. 如果 commit hook 失败,把 hook 输出注入下一轮 prompt,并按 `commit.retries` 重试。
|
|
495
|
+
|
|
496
|
+
Agent adapter 契约是 stdin/stdout 风格:
|
|
497
|
+
|
|
498
|
+
- stdin 或 `{{prompt}}`: 完整 commit prompt 和 staged diff
|
|
499
|
+
- stdout: 只输出 commit message
|
|
500
|
+
- stderr: 日志和诊断信息
|
|
501
|
+
|
|
502
|
+
## 配置
|
|
503
|
+
|
|
504
|
+
默认配置文件在 [config/](./config):
|
|
505
|
+
|
|
506
|
+
- [config/aiw.toml](./config/aiw.toml): defaults、paths、behavior、commit、Git 和 workspace 设置
|
|
507
|
+
- [config/agents.toml](./config/agents.toml): agent command adapters
|
|
508
|
+
- [config/commit-prompt.md](./config/commit-prompt.md): 基础 commit prompt
|
|
509
|
+
- [config/lazygit-delta.yml](./config/lazygit-delta.yml): 仅 `aiw git` 使用的 lazygit overlay
|
|
510
|
+
|
|
511
|
+
关键默认值:
|
|
512
|
+
|
|
513
|
+
```toml
|
|
514
|
+
[defaults]
|
|
515
|
+
agent = "codex"
|
|
516
|
+
editor = "nvim"
|
|
517
|
+
files = "yazi"
|
|
518
|
+
git = "lazygit"
|
|
519
|
+
|
|
520
|
+
[paths]
|
|
521
|
+
code_root = "~/Code"
|
|
522
|
+
worktrees = "~/worktrees"
|
|
523
|
+
|
|
524
|
+
[commit]
|
|
525
|
+
agent = "codex"
|
|
526
|
+
retries = 3
|
|
527
|
+
max_diff_chars = 120000
|
|
528
|
+
|
|
529
|
+
[workspace]
|
|
530
|
+
stale_seconds = 604800
|
|
531
|
+
|
|
532
|
+
[workspace.hooks]
|
|
533
|
+
pre_init = []
|
|
534
|
+
pre_remove = []
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
Agent 配置示例:
|
|
538
|
+
|
|
539
|
+
```toml
|
|
540
|
+
[agents.codex]
|
|
541
|
+
cmd = "codex"
|
|
542
|
+
args = []
|
|
543
|
+
commit_args = ["exec", "--skip-git-repo-check", "--sandbox", "read-only", "--color", "never", "-"]
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
`args` 用于交互式 agent pane,`commit_args` 用于一次性 commit message 生成。
|
|
547
|
+
|
|
548
|
+
## 依赖门禁
|
|
549
|
+
|
|
550
|
+
`aiw doctor` 会展示工具可用性并评估 gate。默认 gate 是 `p0`。
|
|
551
|
+
|
|
552
|
+
常用 gate:
|
|
553
|
+
|
|
554
|
+
```bash
|
|
555
|
+
aiw doctor --gate git
|
|
556
|
+
aiw doctor --gate workspace
|
|
557
|
+
aiw doctor --gate layout --agent codex
|
|
558
|
+
aiw doctor --gate cmux-new --agent codex
|
|
559
|
+
aiw doctor --gate init --agent codex
|
|
560
|
+
aiw doctor --gate commit --agent codex
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
Gate 行为:
|
|
564
|
+
|
|
565
|
+
- `cmux-new` 需要 Git、Worktrunk、cmux、yazi、lazygit、nvim、选定 agent,以及 `cmux-git-diff` 或 delta 之一。
|
|
566
|
+
- `layout` 需要 layout 相关工具和选定 agent,但不需要 Worktrunk。
|
|
567
|
+
- `init` 在写配置前检查默认工作流初始化所需工具。
|
|
568
|
+
- `workspace` 需要 Git 和 Worktrunk。
|
|
569
|
+
- `git` 在配置 lazygit overlay 时需要 lazygit 和 delta。
|
|
570
|
+
- `commit` 需要 Git 和选定 commit agent。
|
|
571
|
+
|
|
572
|
+
缺失的可选工具只在对应命令或 gate 需要时才阻塞。例如缺少 `fd` 会影响 `aiw pick`,不会影响 `aiw commit`。
|
|
573
|
+
|
|
574
|
+
## 故障排查
|
|
575
|
+
|
|
576
|
+
### `dependency gate ... failed`
|
|
577
|
+
|
|
578
|
+
运行对应 doctor 命令:
|
|
579
|
+
|
|
580
|
+
```bash
|
|
581
|
+
aiw doctor --gate cmux-new --agent codex
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
安装缺失工具,或修改 AIW 配置使用其他命令。
|
|
585
|
+
|
|
586
|
+
### `no staged changes`
|
|
587
|
+
|
|
588
|
+
`aiw commit` 只读取 staged changes。请先在 lazygit 或 Git CLI 中 stage:
|
|
589
|
+
|
|
590
|
+
```bash
|
|
591
|
+
aiw git
|
|
592
|
+
git add <path>
|
|
593
|
+
aiw commit
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
### `not inside a Git repository`
|
|
597
|
+
|
|
598
|
+
大多数 AIW 工作流都基于 Git root。请在 Git repository 中运行,传 `--repo`,或在支持的命令里使用 `--pick-repo`。
|
|
599
|
+
|
|
600
|
+
### `aiw workspace done must be run from a feature worktree`
|
|
601
|
+
|
|
602
|
+
`done` 是 feature worktree 收尾命令。请在 feature worktree 内执行,而不是在主 checkout 里执行。
|
|
603
|
+
|
|
604
|
+
### Dirty Worktree 阻塞 remove、done 或 GC
|
|
605
|
+
|
|
606
|
+
AIW 会保护未提交改动。先审查它们:
|
|
607
|
+
|
|
608
|
+
```bash
|
|
609
|
+
aiw git
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
只有明确要删除或交给 Worktrunk 决策时,才在 `workspace remove` 上使用 `--force`。
|
|
613
|
+
|
|
614
|
+
### Shell 输出 `fnm_multishells ... Operation not permitted`
|
|
615
|
+
|
|
616
|
+
本地环境中可能在命令输出前出现这类信息。如果实际 AIW 命令成功,可以把它视为 shell startup 噪音,而不是 AIW 失败。
|
|
617
|
+
|
|
618
|
+
## 开发指南
|
|
619
|
+
|
|
620
|
+
非平凡改动前先读:
|
|
621
|
+
|
|
622
|
+
- [README.md](./README.md): 给人类看的使用说明书
|
|
623
|
+
- [AGENTS.md](./AGENTS.md): 给 AI agent 看的开发规范
|
|
624
|
+
- [docs/2026-05-29-design.md](./docs/2026-05-29-design.md): 原始设计记录
|
|
625
|
+
- [docs/2026-06-01-workflow-handoff.md](./docs/2026-06-01-workflow-handoff.md): workflow 历史记录
|
|
626
|
+
- [docs/2026-06-01-workspace-management-plan.md](./docs/2026-06-01-workspace-management-plan.md): workspace 管理记录
|
|
627
|
+
- [handoff.md](./handoff.md): 当前活动 handoff
|
|
628
|
+
|
|
629
|
+
代码改动后运行:
|
|
630
|
+
|
|
631
|
+
```bash
|
|
632
|
+
npm run check
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
额外定向检查:
|
|
636
|
+
|
|
637
|
+
```bash
|
|
638
|
+
node bin/aiw doctor --gate git
|
|
639
|
+
ruby -ryaml -e 'YAML.load_file("config/lazygit-delta.yml")'
|
|
640
|
+
node bin/aiw doctor --gate commit --agent codex
|
|
641
|
+
node bin/aiw doctor --gate cmux-new --agent codex
|
|
642
|
+
node bin/aiw layout --agent codex --dry-run
|
|
643
|
+
node bin/aiw init --cmux-scope none --dry-run --no-reload
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
修改 `src/commit.mjs` 时,用有 staged changes 的临时 Git repo 验证。修改 worktree 行为时,先用 dry-run,再用 `/private/tmp` 下的一次性 repo 验证。
|
|
647
|
+
|
|
648
|
+
## 项目结构
|
|
649
|
+
|
|
650
|
+
```text
|
|
651
|
+
bin/aiw executable entrypoint
|
|
652
|
+
src/cli.mjs top-level command dispatch
|
|
653
|
+
src/config.mjs config loading and agent resolution
|
|
654
|
+
src/deps.mjs dependency gates and doctor output
|
|
655
|
+
src/git.mjs Git repo, repo picker, branch selection helpers
|
|
656
|
+
src/layout.mjs cmux layout generation
|
|
657
|
+
src/hooks.mjs workspace hook loading and execution
|
|
658
|
+
src/init.mjs first-time machine bootstrap
|
|
659
|
+
src/workspace.mjs workspace list/open/done/remove/gc
|
|
660
|
+
src/commit.mjs AI commit workflow
|
|
661
|
+
src/agent.mjs agent invocation and output cleanup
|
|
662
|
+
src/prompt.mjs TTY input and fzf picker helpers
|
|
663
|
+
src/run.mjs process execution helpers
|
|
664
|
+
config/aiw.toml default workflow config
|
|
665
|
+
config/agents.toml agent adapters
|
|
666
|
+
config/commit-prompt.md base AI commit prompt
|
|
667
|
+
config/lazygit-delta.yml lazygit overlay used by aiw git
|
|
668
|
+
docs/ design notes and dated handoff records
|
|
669
|
+
handoff.md current activity handoff
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
## 当前状态
|
|
673
|
+
|
|
674
|
+
AIW 当前聚焦四条稳定路径:
|
|
675
|
+
|
|
676
|
+
- 创建或打开 worktree,并进入适合 AI 协作的 cmux layout
|
|
677
|
+
- 安全地查看和清理 workspace
|
|
678
|
+
- 通过 lazygit 和 delta 审查改动
|
|
679
|
+
- 通过 agent CLI 基于 staged diff 生成 commit message
|
|
680
|
+
|
|
681
|
+
后续演进应继续保持这个边界:AIW 负责协调,专业工具负责专业能力。
|
package/bin/aiw
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { main } from "../src/cli.mjs";
|
|
3
|
+
|
|
4
|
+
main(process.argv.slice(2)).catch((error) => {
|
|
5
|
+
const message = error && typeof error.message === "string" ? error.message : String(error);
|
|
6
|
+
console.error(`[error] ${message}`);
|
|
7
|
+
process.exit(typeof error.exitCode === "number" ? error.exitCode : 1);
|
|
8
|
+
});
|