@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.md
ADDED
|
@@ -0,0 +1,681 @@
|
|
|
1
|
+
# aiw
|
|
2
|
+
|
|
3
|
+
`aiw` is a personal AI programming workflow CLI. It turns a pile of sharp terminal tools into one predictable loop for starting work, opening an AI-ready workspace, reviewing changes, generating commits, and cleaning up worktrees.
|
|
4
|
+
|
|
5
|
+
Default language: English. For the Chinese version, see [README.zh-CN.md](./README.zh-CN.md).
|
|
6
|
+
|
|
7
|
+
## What aiw Is
|
|
8
|
+
|
|
9
|
+
AIW is intentionally a thin orchestration layer. It does not replace the tools you already use. It decides what should happen next, checks that required dependencies exist, and then delegates the actual work to the right tool.
|
|
10
|
+
|
|
11
|
+
The boundary is:
|
|
12
|
+
|
|
13
|
+
- `aiw` owns workflow decisions, config loading, dependency gates, prompts, command routing, and cmux layout generation.
|
|
14
|
+
- Worktrunk owns worktree lifecycle.
|
|
15
|
+
- cmux owns workspaces and panes.
|
|
16
|
+
- lazygit owns Git TUI operations.
|
|
17
|
+
- delta owns diff rendering.
|
|
18
|
+
- agent CLIs own model interaction.
|
|
19
|
+
- yazi, nvim, rg, fd, fzf, bat, and eza keep their native responsibilities.
|
|
20
|
+
|
|
21
|
+
The result is a CLI that keeps a personal workflow consistent without turning itself into a terminal emulator, Git client, editor, diff viewer, daemon, task database, or agent manager.
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
From this 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
|
+
Bootstrap with the published package, then use the installed `aiw` binary:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx @chlrc/aiw init
|
|
37
|
+
aiw doctor
|
|
38
|
+
aiw cmux-new --agent codex
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The normal daily loop is:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# 1. Check whether the local toolchain is ready.
|
|
45
|
+
aiw doctor
|
|
46
|
+
|
|
47
|
+
# 2. Create or switch to a Worktrunk worktree and open the AIW cmux layout.
|
|
48
|
+
aiw cmux-new --agent codex
|
|
49
|
+
|
|
50
|
+
# 3. Work in the four-pane workspace.
|
|
51
|
+
# Files: yazi
|
|
52
|
+
# Agent: codex / claude / opencode / gemini / aider
|
|
53
|
+
# Git: lazygit with the AIW overlay
|
|
54
|
+
# Diff: cmux-git-diff or git diff piped through delta
|
|
55
|
+
|
|
56
|
+
# 4. Review and stage changes.
|
|
57
|
+
aiw git
|
|
58
|
+
|
|
59
|
+
# 5. Generate a commit message from staged changes and commit.
|
|
60
|
+
aiw commit
|
|
61
|
+
|
|
62
|
+
# 6. Merge and clean up a feature worktree when it is done.
|
|
63
|
+
aiw done dev
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Run the checked-out CLI while developing AIW itself:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
node bin/aiw doctor
|
|
70
|
+
node bin/aiw doctor --gate cmux-new --agent codex
|
|
71
|
+
node bin/aiw layout --agent codex --dry-run
|
|
72
|
+
node bin/aiw cmux-new --repo ~/Code/my-repo --branch feat/foo --agent codex --dry-run
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Installation Model
|
|
76
|
+
|
|
77
|
+
AIW is a Node.js ESM CLI targeting Node.js 18 or newer. The executable entrypoint is [bin/aiw](./bin/aiw), and package metadata exposes it as the `aiw` binary.
|
|
78
|
+
|
|
79
|
+
For local development, calling `node bin/aiw ...` is enough. For a global command, use the project install script if available in your checkout:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npm run install:global
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
AIW reads configuration from:
|
|
86
|
+
|
|
87
|
+
1. `$AIW_CONFIG_DIR`, when set.
|
|
88
|
+
2. `~/.config/aiw`, when present.
|
|
89
|
+
3. The repository default [config/](./config) directory.
|
|
90
|
+
|
|
91
|
+
This lets the repo provide a usable default while still allowing a personal config directory outside business repositories.
|
|
92
|
+
|
|
93
|
+
## Init
|
|
94
|
+
|
|
95
|
+
Use `npx @chlrc/aiw init` on macOS or Linux to bootstrap a machine for AIW.
|
|
96
|
+
|
|
97
|
+
The init flow assumes Node.js and `npx` are already available. It checks required environment variables, the POSIX shell platform, and blocking tools for the default workflow. If any blocking dependency is missing, it stops before writing files and prints install guidance. Optional tools such as `fd`, `eza`, and non-default agent CLIs are reported without blocking.
|
|
98
|
+
|
|
99
|
+
When the blocking gate passes, init creates missing directories and config files:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npx @chlrc/aiw init
|
|
103
|
+
npx @chlrc/aiw init --cmux-scope home
|
|
104
|
+
npx @chlrc/aiw init --cmux-scope code --code-root ~/Code --worktrees-root ~/worktrees
|
|
105
|
+
npx @chlrc/aiw init --cmux-scope none --dry-run
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- AIW config defaults to `~/.config/aiw`, or `$AIW_CONFIG_DIR` when set.
|
|
109
|
+
- `--code-root` and `--worktrees-root` control the paths written into `aiw.toml`; defaults are `~/Code` and `~/worktrees`.
|
|
110
|
+
- cmux registration defaults to `~/.config/cmux/cmux.json`; use `--cmux-scope code` to write `<code-root>/.cmux/cmux.json`, or `--cmux-scope none` to skip cmux.
|
|
111
|
+
- In an interactive terminal, init asks where to register cmux. `--yes` uses the default without prompting.
|
|
112
|
+
- Existing AIW config files are kept by default. Use `--force` to overwrite them after backups are created.
|
|
113
|
+
- Existing cmux config is merged, not replaced. AIW actions are added and existing non-AIW plus-button actions are preserved by putting AIW entries in the context menu.
|
|
114
|
+
- Skills are intentionally not initialized yet.
|
|
115
|
+
|
|
116
|
+
## Technology Stack
|
|
117
|
+
|
|
118
|
+
AIW is deliberately dependency-light:
|
|
119
|
+
|
|
120
|
+
- Runtime: Node.js ESM, Node >= 18.
|
|
121
|
+
- Config: small TOML files parsed by AIW itself.
|
|
122
|
+
- Process execution: Node child processes through local helpers.
|
|
123
|
+
- Workspace orchestration: Worktrunk (`wt`) and cmux.
|
|
124
|
+
- Git UI: lazygit, with an AIW-specific overlay loaded only by `aiw git`.
|
|
125
|
+
- Diff UI: `cmux-git-diff` when installed, otherwise `git diff | delta`.
|
|
126
|
+
- Pickers and search: fzf, rg, fd, bat.
|
|
127
|
+
- File and edit surfaces: yazi and nvim.
|
|
128
|
+
- Agents: command adapters defined in [config/agents.toml](./config/agents.toml).
|
|
129
|
+
|
|
130
|
+
The project currently has no full automated test suite. The required check after code changes is:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npm run check
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
For risky CLI behavior, create a temporary Git repo under `/private/tmp` and verify the relevant command non-interactively where possible.
|
|
137
|
+
|
|
138
|
+
## Mental Model
|
|
139
|
+
|
|
140
|
+
Think of AIW in three layers:
|
|
141
|
+
|
|
142
|
+
1. cmux is the front door. The plus button, command palette, or a cmux terminal action is where new work should begin.
|
|
143
|
+
2. `aiw` is the orchestration entrypoint. It resolves the repo, branch/worktree, agent, dependency gates, and layout, then calls the right lower-level command.
|
|
144
|
+
3. Mature CLI tools do the real work: Worktrunk for worktrees, yazi for files, nvim/LazyVim for editing, lazygit for review and staging, delta for diffs, rg/fd/fzf/bat/eza for search and inspection, zoxide in the surrounding shell workflow, and agent CLIs for model interaction.
|
|
145
|
+
|
|
146
|
+
AIW started from a practical goal: recreate the useful Codex App-style workspace motion without moving the workflow into a closed app. The target experience is not just "four panes on screen." It is a continuous path: open cmux, start AIW, create or switch a worktree, land in the standard workspace, inspect files, talk to an agent, stage hunks, watch the diff, commit, merge, and clean up.
|
|
147
|
+
|
|
148
|
+
The important difference is control. A polished app can be pleasant, but it tends to fix the shape of the workflow. In a terminal stack, you can choose the file manager, editor setup, Git UI, diff renderer, fuzzy finder, navigation tools, shell behavior, keybindings, and agent CLI. Shell rendering also matters: when command output is central to development, native terminal tools are easier to trust, tune, and compose than an embedded shell surface.
|
|
149
|
+
|
|
150
|
+
AIW therefore keeps the Codex-style workspace pattern, but makes it cmux-first, terminal-native, and agent-neutral. The same motion should run with Codex, Claude, opencode, Gemini, aider, or any future agent adapter that follows the same config contract. If you care about deep customization and want development control back in your own terminal stack, AIW is the experiment.
|
|
151
|
+
|
|
152
|
+
When you start work, AIW should answer four questions:
|
|
153
|
+
|
|
154
|
+
1. Which repository am I working in?
|
|
155
|
+
2. Which worktree or branch should hold this work?
|
|
156
|
+
3. Which agent should be opened next to the code?
|
|
157
|
+
4. Which standard panes should be visible while I work?
|
|
158
|
+
|
|
159
|
+
Once those are known, AIW stops making domain decisions and delegates:
|
|
160
|
+
|
|
161
|
+
```text
|
|
162
|
+
aiw cmux-new
|
|
163
|
+
-> dependency gate
|
|
164
|
+
-> repository and branch selection
|
|
165
|
+
-> Worktrunk creates or switches the worktree
|
|
166
|
+
-> aiw layout builds the cmux workspace
|
|
167
|
+
-> cmux opens Files / Agent / Git / Diff panes
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
The same idea applies to cleanup:
|
|
171
|
+
|
|
172
|
+
```text
|
|
173
|
+
aiw workspace gc
|
|
174
|
+
-> read Worktrunk and Git state
|
|
175
|
+
-> mark dirty, merged, stale, and cmux-open signals
|
|
176
|
+
-> remove only clean + merged worktrees when explicitly confirmed
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
AIW is not meant to hide the underlying tools. It is meant to make the common path short and the dangerous path explicit.
|
|
180
|
+
|
|
181
|
+
## Design Logic
|
|
182
|
+
|
|
183
|
+
### cmux Is the Entry, AIW Is the Orchestrator
|
|
184
|
+
|
|
185
|
+
The intended entry is cmux, not a standalone AIW dashboard. cmux already owns windows, workspaces, panes, and the user's visible development surface. AIW sits behind that entry as the command that decides what to open and how to wire it together.
|
|
186
|
+
|
|
187
|
+
That is why the main motion is:
|
|
188
|
+
|
|
189
|
+
```text
|
|
190
|
+
cmux entry
|
|
191
|
+
-> aiw cmux-new
|
|
192
|
+
-> dependency gate
|
|
193
|
+
-> Worktrunk worktree create/switch
|
|
194
|
+
-> aiw layout
|
|
195
|
+
-> cmux workspace with Files / Agent / Git / Diff
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
The value is the fluid handoff between layers. cmux stays the place you start and look. AIW stays the workflow brain. The lower-level CLIs stay sharp and native.
|
|
199
|
+
|
|
200
|
+
### Recreate the App Motion, Not the App Lock-In
|
|
201
|
+
|
|
202
|
+
AIW borrows the strongest idea from a Codex App-style interface: keep the code workspace, agent, Git review, and diff loop together, and make starting isolated work feel natural. It does not borrow the lock-in. The workflow is expressed as commands, config files, and a cmux layout, so each layer remains replaceable.
|
|
203
|
+
|
|
204
|
+
That is why agent support is adapter-based. An agent is not hardcoded into the product. It is a command plus optional args for an interactive pane, and separate `commit_args` for one-shot commit generation.
|
|
205
|
+
|
|
206
|
+
### Keep Personal Workflow Out of Business Repos
|
|
207
|
+
|
|
208
|
+
AIW should not write `.aiw`, `.worktrunk`, or `.cmux` files into business repositories by default. Runtime metadata that AIW owns, such as recorded `feature -> target` workspace targets, is stored under Git's common dir rather than in the working tree.
|
|
209
|
+
|
|
210
|
+
### Let the Terminal Stay the Control Plane
|
|
211
|
+
|
|
212
|
+
AIW assumes the user should be able to swap tools, tune rendering, keep native shell behavior, and use existing muscle memory. It composes mature tools such as rg, zoxide, yazi, nvim/LazyVim, lazygit, delta, fzf, Worktrunk, cmux, and agent CLIs instead of flattening them into a new closed UI.
|
|
213
|
+
|
|
214
|
+
This is also why shell and diff output stay in terminal-native tools. The terminal is not a fallback surface for AIW; it is the primary control plane.
|
|
215
|
+
|
|
216
|
+
### Gate Before Side Effects
|
|
217
|
+
|
|
218
|
+
Commands that create worktrees or open cmux layouts run dependency gates first. If an external tool is missing, AIW stops before making a new workspace.
|
|
219
|
+
|
|
220
|
+
Useful examples:
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
aiw doctor
|
|
224
|
+
aiw doctor --gate git
|
|
225
|
+
aiw doctor --gate cmux-new --agent codex
|
|
226
|
+
aiw doctor --gate commit --agent codex
|
|
227
|
+
aiw doctor --json
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Interactive When Human, Explicit When Scripted
|
|
231
|
+
|
|
232
|
+
In a TTY, missing required arguments open searchable pickers where that makes sense. In non-interactive calls, pass explicit arguments or rely on the underlying tool's own behavior.
|
|
233
|
+
|
|
234
|
+
Examples:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
aiw cmux-new
|
|
238
|
+
aiw cmux-new --pick-repo
|
|
239
|
+
aiw workspace open
|
|
240
|
+
aiw workspace open feat/foo --agent codex
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Preserve Native Tool Responsibility
|
|
244
|
+
|
|
245
|
+
`aiw git` opens lazygit. It does not reimplement staging, hunk selection, or commit review.
|
|
246
|
+
|
|
247
|
+
`aiw files` opens yazi. It does not become a file manager.
|
|
248
|
+
|
|
249
|
+
`aiw diff` renders the current Git diff. It does not become a custom diff engine.
|
|
250
|
+
|
|
251
|
+
## Core Commands
|
|
252
|
+
|
|
253
|
+
```bash
|
|
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
|
+
Short workspace aliases are kept for daily use:
|
|
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 and cmux Workflow
|
|
301
|
+
|
|
302
|
+
`aiw cmux-new` is the main entrypoint for new work.
|
|
303
|
+
|
|
304
|
+
Common forms:
|
|
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
|
+
Behavior:
|
|
316
|
+
|
|
317
|
+
- The current Git repository is used automatically when possible.
|
|
318
|
+
- `--pick-repo` lets you select another repository under `paths.code_root`.
|
|
319
|
+
- Without a branch in a TTY, AIW lets you create a new branch from current `HEAD`, open the current checkout, or choose an existing branch.
|
|
320
|
+
- Creating a new branch runs `wt switch --create <branch> --base @ -x "aiw layout --agent <agent>"`.
|
|
321
|
+
- Selecting an existing branch runs `wt switch <branch> -x "aiw layout --agent <agent>"`.
|
|
322
|
+
- `--local` opens the standard layout in the current checkout without creating a Worktrunk worktree.
|
|
323
|
+
- `--dry-run` prints the command that would be run.
|
|
324
|
+
|
|
325
|
+
The standard cmux layout is:
|
|
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` prints the cmux layout JSON without opening cmux.
|
|
338
|
+
|
|
339
|
+
## Workspace Management
|
|
340
|
+
|
|
341
|
+
`aiw workspace ...` is the visibility and lifecycle layer around Worktrunk worktrees.
|
|
342
|
+
|
|
343
|
+
### List
|
|
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
|
+
The table combines Worktrunk, Git, and cmux signals:
|
|
353
|
+
|
|
354
|
+
- branch and path
|
|
355
|
+
- dirty or clean state
|
|
356
|
+
- Worktrunk integration state
|
|
357
|
+
- recorded merge target, if AIW created the worktree
|
|
358
|
+
- inferred merged target, when no recorded target exists
|
|
359
|
+
- cmux-open status
|
|
360
|
+
- age
|
|
361
|
+
- GC signal
|
|
362
|
+
|
|
363
|
+
State markers are intentionally conservative. Dirty worktrees are never automatic cleanup candidates.
|
|
364
|
+
|
|
365
|
+
### Open
|
|
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
|
+
In a TTY, `workspace open` without a target opens a searchable picker over existing worktrees and local branches. A branch target is opened through Worktrunk. A path target opens the AIW cmux layout directly in that Git root.
|
|
375
|
+
|
|
376
|
+
### Done
|
|
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` is only allowed from a feature worktree. It refuses to run from the main workspace. It also refuses to proceed when the current worktree is dirty.
|
|
386
|
+
|
|
387
|
+
When it proceeds, AIW delegates the merge and cleanup to Worktrunk:
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
wt merge <target>
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
If AIW recorded a target when the worktree was created, bare `aiw done` can use that target. In a TTY it opens a target picker when needed. After a successful merge, AIW closes the matching cmux workspace unless `--no-close-cmux` is passed.
|
|
394
|
+
|
|
395
|
+
### Remove and 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` performs a dirty check before calling `wt remove`. Use `--force` only when you intend to hand that decision to Worktrunk.
|
|
408
|
+
|
|
409
|
+
`gc` separates three signals:
|
|
410
|
+
|
|
411
|
+
- `dirty`: blocks automatic cleanup.
|
|
412
|
+
- `merged`: the branch is integrated, same commit, empty, or known to be contained by a target.
|
|
413
|
+
- `stale`: last commit age is greater than `workspace.stale_seconds`, defaulting to seven days.
|
|
414
|
+
|
|
415
|
+
Only clean + merged worktrees are removable. Stale dirty or unmerged worktrees are warning-only.
|
|
416
|
+
|
|
417
|
+
### Workspace hooks
|
|
418
|
+
|
|
419
|
+
Workspace hooks can run shell commands before AIW initializes a cmux workspace or removes a worktree. Configure global hooks in `~/.config/aiw/aiw.toml` and project hooks in an explicit `.aiw.toml` at the Git repository root. AIW reads project hooks only when the file already exists; it does not create project-local workflow files.
|
|
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
|
+
Global hooks run first, then matching global project hooks, then project-local hooks. A `[workspace.hooks.projects.<name>]` table matches `<name>` against the current worktree name and the Git common-dir project name; use `match`, `path`, `paths`, `repo`, or `repos` when the table name is only an alias or when you need path matching. `*` wildcards are supported.
|
|
437
|
+
|
|
438
|
+
Commands run sequentially with `sh -lc` from the target workspace path; a failing hook stops the init/remove action. `pre_init` runs before `aiw layout` calls `cmux new-workspace`. `pre_remove` runs before `aiw workspace done`, `aiw workspace remove`, and `aiw workspace gc --apply` delete paths through Worktrunk.
|
|
439
|
+
|
|
440
|
+
Hook commands receive `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`, and `AIW_AGENT`.
|
|
441
|
+
|
|
442
|
+
## Git, Diff, and AI Commit
|
|
443
|
+
|
|
444
|
+
### lazygit Overlay
|
|
445
|
+
|
|
446
|
+
`aiw git` opens lazygit with the AIW overlay:
|
|
447
|
+
|
|
448
|
+
```bash
|
|
449
|
+
lazygit --use-config-file <aiw-config-dir>/lazygit-delta.yml
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
The overlay:
|
|
453
|
+
|
|
454
|
+
- uses delta for diff display
|
|
455
|
+
- adds `Ctrl-A` as a global lazygit custom command
|
|
456
|
+
- prompts for optional AI commit instructions
|
|
457
|
+
- runs `aiw commit --prompt ...`
|
|
458
|
+
|
|
459
|
+
Directly running `lazygit` is untouched.
|
|
460
|
+
|
|
461
|
+
### Diff
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
aiw diff
|
|
465
|
+
aiw diff --watch
|
|
466
|
+
aiw diff --staged
|
|
467
|
+
aiw diff --all
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
For an unstaged diff, AIW uses `cmux-git-diff` when available. Otherwise it pipes Git diff output through delta. `--watch` refreshes every two seconds.
|
|
471
|
+
|
|
472
|
+
### AI Commit
|
|
473
|
+
|
|
474
|
+
`aiw commit` expects staged changes. It never silently stages files.
|
|
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
|
+
Flow:
|
|
487
|
+
|
|
488
|
+
1. Read `git diff --cached`, `git diff --cached --stat`, and `git status --short`.
|
|
489
|
+
2. Build a prompt from [config/commit-prompt.md](./config/commit-prompt.md).
|
|
490
|
+
3. Append `--prompt` and `--prompt-file` content when provided.
|
|
491
|
+
4. Call the selected agent using `commit_args` from [config/agents.toml](./config/agents.toml).
|
|
492
|
+
5. Clean the agent output into a commit message.
|
|
493
|
+
6. Run `git commit -F -`.
|
|
494
|
+
7. If commit hooks fail, include the hook output in the next prompt and retry up to `commit.retries`.
|
|
495
|
+
|
|
496
|
+
The agent adapter contract is stdin/stdout oriented:
|
|
497
|
+
|
|
498
|
+
- stdin or `{{prompt}}`: full commit prompt and staged diff
|
|
499
|
+
- stdout: commit message only
|
|
500
|
+
- stderr: logs and diagnostics
|
|
501
|
+
|
|
502
|
+
## Configuration
|
|
503
|
+
|
|
504
|
+
Default config files live in [config/](./config):
|
|
505
|
+
|
|
506
|
+
- [config/aiw.toml](./config/aiw.toml): defaults, paths, behavior, commit, Git, and workspace settings
|
|
507
|
+
- [config/agents.toml](./config/agents.toml): agent command adapters
|
|
508
|
+
- [config/commit-prompt.md](./config/commit-prompt.md): base commit prompt
|
|
509
|
+
- [config/lazygit-delta.yml](./config/lazygit-delta.yml): lazygit overlay used only by `aiw git`
|
|
510
|
+
|
|
511
|
+
Important defaults:
|
|
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 entries look like this:
|
|
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
|
+
Use `args` for the interactive agent pane and `commit_args` for one-shot commit generation.
|
|
547
|
+
|
|
548
|
+
## Dependency Gates
|
|
549
|
+
|
|
550
|
+
`aiw doctor` reports tool availability and evaluates a gate. The default gate is `p0`.
|
|
551
|
+
|
|
552
|
+
Useful gates:
|
|
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 behavior:
|
|
564
|
+
|
|
565
|
+
- `cmux-new` requires Git, Worktrunk, cmux, yazi, lazygit, nvim, the selected agent, and either `cmux-git-diff` or delta.
|
|
566
|
+
- `layout` requires the layout tools and selected agent, but not Worktrunk.
|
|
567
|
+
- `init` checks the tools needed to bootstrap the default workflow before writing config.
|
|
568
|
+
- `workspace` requires Git and Worktrunk.
|
|
569
|
+
- `git` requires lazygit and delta when the lazygit overlay is configured.
|
|
570
|
+
- `commit` requires Git and the selected commit agent.
|
|
571
|
+
|
|
572
|
+
Missing optional tools only matter when their command or gate needs them. For example, missing `fd` affects `aiw pick`, not `aiw commit`.
|
|
573
|
+
|
|
574
|
+
## Troubleshooting
|
|
575
|
+
|
|
576
|
+
### `dependency gate ... failed`
|
|
577
|
+
|
|
578
|
+
Run the matching doctor command:
|
|
579
|
+
|
|
580
|
+
```bash
|
|
581
|
+
aiw doctor --gate cmux-new --agent codex
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
Install the missing tool or change the AIW config to use a different command.
|
|
585
|
+
|
|
586
|
+
### `no staged changes`
|
|
587
|
+
|
|
588
|
+
`aiw commit` only reads staged changes. Stage files in lazygit or with Git first:
|
|
589
|
+
|
|
590
|
+
```bash
|
|
591
|
+
aiw git
|
|
592
|
+
git add <path>
|
|
593
|
+
aiw commit
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
### `not inside a Git repository`
|
|
597
|
+
|
|
598
|
+
Most AIW workflows are Git-rooted. Run the command from a Git repository, pass `--repo`, or use `--pick-repo` where supported.
|
|
599
|
+
|
|
600
|
+
### `aiw workspace done must be run from a feature worktree`
|
|
601
|
+
|
|
602
|
+
`done` is a feature worktree cleanup command. Run it inside the feature worktree, not the main checkout.
|
|
603
|
+
|
|
604
|
+
### Dirty Worktree Blocks Remove, Done, or GC
|
|
605
|
+
|
|
606
|
+
AIW protects uncommitted changes. Review them first:
|
|
607
|
+
|
|
608
|
+
```bash
|
|
609
|
+
aiw git
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
Use `--force` only on `workspace remove` when that is the explicit intention.
|
|
613
|
+
|
|
614
|
+
### Shell Prints `fnm_multishells ... Operation not permitted`
|
|
615
|
+
|
|
616
|
+
This can appear in the local environment before command output. If the actual AIW command succeeds, treat it as shell startup noise rather than an AIW failure.
|
|
617
|
+
|
|
618
|
+
## Development Guide
|
|
619
|
+
|
|
620
|
+
Read these before non-trivial changes:
|
|
621
|
+
|
|
622
|
+
- [README.md](./README.md): human-facing usage manual
|
|
623
|
+
- [AGENTS.md](./AGENTS.md): agent-facing development rules
|
|
624
|
+
- [docs/2026-05-29-design.md](./docs/2026-05-29-design.md): original design note
|
|
625
|
+
- [docs/2026-06-01-workflow-handoff.md](./docs/2026-06-01-workflow-handoff.md): workflow history
|
|
626
|
+
- [docs/2026-06-01-workspace-management-plan.md](./docs/2026-06-01-workspace-management-plan.md): workspace management record
|
|
627
|
+
- [handoff.md](./handoff.md): current working context
|
|
628
|
+
|
|
629
|
+
Run this after code changes:
|
|
630
|
+
|
|
631
|
+
```bash
|
|
632
|
+
npm run check
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
Additional targeted checks:
|
|
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
|
+
When changing `src/commit.mjs`, verify against a temporary Git repo with staged changes. When changing worktree behavior, prefer dry-run commands first and then a disposable repo under `/private/tmp`.
|
|
647
|
+
|
|
648
|
+
## Project Layout
|
|
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
|
+
## Status
|
|
673
|
+
|
|
674
|
+
AIW currently focuses on four stable loops:
|
|
675
|
+
|
|
676
|
+
- open or create worktrees with an AI-ready cmux layout
|
|
677
|
+
- inspect and clean up workspaces safely
|
|
678
|
+
- review changes through lazygit and delta
|
|
679
|
+
- generate commit messages from staged diffs through agent CLIs
|
|
680
|
+
|
|
681
|
+
Future work should preserve the same boundary: AIW coordinates; specialized tools do the specialized work.
|