@caddis/cli 0.4.65 → 0.4.67
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/bundles/antigravity-plugin/plugin.json +1 -1
- package/bundles/antigravity-plugin/scripts/caddis_created.py +191 -0
- package/bundles/antigravity-plugin/scripts/caddis_docs_pr.py +11 -3
- package/bundles/antigravity-plugin/scripts/caddis_lanes.py +4 -0
- package/bundles/antigravity-plugin/scripts/caddis_own_cleanup.py +424 -0
- package/bundles/antigravity-plugin/scripts/caddis_roadmap_page.py +205 -70
- package/bundles/antigravity-plugin/scripts/caddis_roadmap_run.py +3 -0
- package/bundles/antigravity-plugin/scripts/caddis_worktree_root.py +26 -3
- package/bundles/antigravity-plugin/scripts/roadmap_assets/LICENSE-Lucide.txt +43 -0
- package/bundles/antigravity-plugin/scripts/roadmap_assets/{OFL-JetBrainsMono.txt → OFL-Atkinson.txt} +2 -2
- package/bundles/antigravity-plugin/scripts/roadmap_assets/fonts.css +3 -3
- package/bundles/antigravity-plugin/scripts/roadmap_assets/icons.svg +2 -0
- package/bundles/antigravity-plugin/skills/catchup/SKILL.md +11 -5
- package/bundles/antigravity-plugin/skills/cloud-phases/SKILL.md +4 -3
- package/bundles/antigravity-plugin/skills/feature-plan/SKILL.md +1 -1
- package/bundles/antigravity-plugin/skills/handoff/SKILL.md +58 -28
- package/bundles/antigravity-plugin/skills/pr-merge/SKILL.md +4 -3
- package/bundles/antigravity-plugin/skills/roadmap/assets/plan-resume-prompt.md +3 -3
- package/bundles/antigravity-plugin/skills/ship-merge/SKILL.md +4 -3
- package/bundles/antigravity-plugin/skills/ship-pr/SKILL.md +4 -3
- package/bundles/antigravity-plugin/skills/using-git-worktrees/SKILL.md +7 -1
- package/bundles/codex/.codex/skills/devops/using-git-worktrees/SKILL.md +7 -1
- package/bundles/codex/.codex/skills/workflow/roadmap/assets/plan-resume-prompt.md +3 -3
- package/bundles/manifest.json +2 -2
- package/package.json +1 -1
|
@@ -70,6 +70,10 @@ on is worse than one sentence admitting there is nothing to recap.
|
|
|
70
70
|
|
|
71
71
|
## Workstreams and open work
|
|
72
72
|
|
|
73
|
+
Open items live in three stores (the 3-store model): this session's tasks (saved at handoff to
|
|
74
|
+
`.caddis/relay/<name>.tasks.md`), the open parking-lot items (`/caddis:park`), and the roadmap and the plan
|
|
75
|
+
Tracker for the order of work. Catchup reads those three and nothing else.
|
|
76
|
+
|
|
73
77
|
**No argument:** this is the last step of the catchup procedure above, not a separate one.
|
|
74
78
|
After the list, add the workstream index and the open work:
|
|
75
79
|
0. The roadmap on origin is the order of work. List the roadmaps, then show each one's status line:
|
|
@@ -82,10 +86,8 @@ After the list, add the workstream index and the open work:
|
|
|
82
86
|
1. Refresh and show the index: `python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_workstreams.py" render-index`,
|
|
83
87
|
then display `.caddis/relay.md`. If it refuses a legacy `.caddis/relay.md`, display that file
|
|
84
88
|
as it is and suggest `/handoff`, which migrates it.
|
|
85
|
-
2. Show open
|
|
86
|
-
|
|
87
|
-
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_todo.py" open-work
|
|
88
|
-
```
|
|
89
|
+
2. Show the open parking-lot items, the durable backlog: follow `/caddis:park list` (List mode). Print its table
|
|
90
|
+
and its counts; if the repo has no `.caddis/parking-lot/`, say `No parking-lot items.` and go on.
|
|
89
91
|
Before saying `Nothing is parked.`, check for an old `/digress` stack: if `.caddis/workstreams.json`
|
|
90
92
|
exists, run `caddis_workstreams.py migrate-legacy` (it keeps a backup and reports conflicts
|
|
91
93
|
instead of overwriting), then show the index again. Only with no relays and no old stack, state:
|
|
@@ -97,7 +99,11 @@ instead of overwriting), then show the index again. Only with no relays and no o
|
|
|
97
99
|
`python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_relay_git.py" fetch <name>`. It reads only
|
|
98
100
|
`refs/caddis/relay/<name>`, never checks out or merges, and refuses to replace a different local
|
|
99
101
|
relay. Pass `--replace` only if the user confirms the local one may be overwritten.
|
|
100
|
-
3.
|
|
102
|
+
3. Load the saved tasks, the same way `/caddis:fleet-open` does: if `.caddis/relay/<name>.tasks.md` exists (table
|
|
103
|
+
`| Old # | Status | Subject |`), make one `TaskCreate` per row with the Subject as its subject, then a
|
|
104
|
+
`TaskUpdate` to `in_progress` for each row with Status `in_progress`. No file means 0 tasks. If this session
|
|
105
|
+
already holds tasks (`TaskList`), do not create a row whose subject is already there. Count them.
|
|
106
|
+
4. Restate where you were and resume the workstream; name the number of tasks you loaded.
|
|
101
107
|
|
|
102
108
|
## Rules
|
|
103
109
|
- **Never** run a destructive or history-rewriting git action (no `git checkout`, `git reset`, `git stash`,
|
|
@@ -37,10 +37,10 @@ It prints `SHARED: yes <reason>` or `SHARED: no` and exits 0. It says yes when t
|
|
|
37
37
|
|
|
38
38
|
- **On `SHARED: no`,** do the steps as written, in this checkout.
|
|
39
39
|
- **On `SHARED: yes`,** never move this checkout. Leave its changes as they are, and report them. Instead:
|
|
40
|
-
- **Rebase:** `git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" rebase-<name>)" <branch>`, then
|
|
40
|
+
- **Rebase:** `git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" rebase-<name> --record --purpose "rebase <name>")" <branch>`, then
|
|
41
41
|
`git -C <worktree> rebase origin/<default>` and `git -C <worktree> push --force-with-lease origin HEAD:<branch>`.
|
|
42
42
|
- **Pull a branch to test it:** `git fetch origin`, then
|
|
43
|
-
`git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" test-<name>)" origin/<branch>` (for the default branch,
|
|
43
|
+
`git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" test-<name> --record --purpose "test <name>")" origin/<branch>` (for the default branch,
|
|
44
44
|
`origin/<default>`), and run the gates there. Install dependencies fresh; never link `node_modules` or a venv.
|
|
45
45
|
- **Clean up after a merge:** do not switch or pull. Run `git fetch --prune`, then
|
|
46
46
|
`git fetch origin <default>:<default>`: it fast-forwards the default branch with no checkout. Git refuses when a
|
|
@@ -50,7 +50,8 @@ It prints `SHARED: yes <reason>` or `SHARED: no` and exits 0. It says yes when t
|
|
|
50
50
|
|
|
51
51
|
`<name>` is the branch name with each `/` written as `-`. `caddis_worktree_root.py` prints the path of a new worktree:
|
|
52
52
|
`$CADDIS_WORKTREE_ROOT/<repo>/<short-name>`, else `<parent of the main checkout>/.worktrees/<repo>/<short-name>`. Never `%TEMP%`: Windows
|
|
53
|
-
cleanup can empty it.
|
|
53
|
+
cleanup can empty it. `--record --purpose "<why>"` also writes the path to this
|
|
54
|
+
session's created list (`caddis_created.py`), so `/handoff` can remove the worktree later. The caddis guard checks only the `Shared checkout: yes` line in
|
|
54
55
|
`AGENTS.md`, not a dirty tree: with that line, it asks before a tree move, and denies it in a headless session.
|
|
55
56
|
<!-- /checkout-safety -->
|
|
56
57
|
|
|
@@ -375,7 +375,7 @@ A `risk: high` phase gets two independent review runs: run by the roadmap/plan r
|
|
|
375
375
|
|
|
376
376
|
Small work that does not meet a trigger skips its block.
|
|
377
377
|
|
|
378
|
-
**Trigger: Always.**
|
|
378
|
+
**Trigger: Always.** The plan's own Tracker is its row of record: give every phase one Tracker row, and when the repo has a roadmap (`caddis_roadmap.py list` prints a slug), name the plan in a roadmap milestone through `/caddis:roadmap` (a docs PR). Work the plan defers on purpose goes to a parking-lot item with `/caddis:park`, and its Tracker row names the file. Open items live in three stores (the 3-store model): the session task list, parking-lot items, and the roadmap and Tracker. The older to-do and repo-backlog stores are retired: do not create them.
|
|
379
379
|
|
|
380
380
|
**Trigger: The plan records a decision.** Record it with `/caddis:decide`.
|
|
381
381
|
|
|
@@ -33,13 +33,14 @@ them into its commit, so check first, before Step 1.
|
|
|
33
33
|
`WORKTREE: <path>`. That worktree is this session's only; no other session's edits can enter it.
|
|
34
34
|
Then, in the steps below:
|
|
35
35
|
- Step 1: tell the `knowledge-transfer` subagent to edit files ONLY under the `WORKTREE:` path.
|
|
36
|
-
- Step 3, point 4:
|
|
37
|
-
|
|
36
|
+
- Step 3, point 4: make the plan's Tracker edit in `<worktree>/.caddis/plans/<feature>.md`, and write
|
|
37
|
+
any new parking-lot item under `<worktree>/.caddis/parking-lot/`, not in this checkout.
|
|
38
38
|
- Step 4: skip `caddis_tidy.py --apply` (report `skipped: shared checkout`).
|
|
39
|
-
- Step 6:
|
|
40
|
-
`.caddis/todo-list/` files and has no worktree option).
|
|
39
|
+
- Step 6: retired; nothing to skip (row 8 reports `skipped: retired (see the 3-store model)`).
|
|
41
40
|
- Step 6b: skip `session_state.py prune` (report `skipped: shared checkout`).
|
|
42
41
|
- Step 6c: run `--reindex` in the worktree (it edits the tracked `DOC-MAP.md`).
|
|
42
|
+
- Step 6d: runs as written. It never writes a file in this checkout; it only removes worktrees and
|
|
43
|
+
scratch folders this session recorded.
|
|
43
44
|
- The relay stays in this checkout: `.caddis/relay/` is local and gitignored.
|
|
44
45
|
After Step 6c, run:
|
|
45
46
|
```
|
|
@@ -52,25 +53,29 @@ them into its commit, so check first, before Step 1.
|
|
|
52
53
|
|
|
53
54
|
## Checklist
|
|
54
55
|
The handoff is a fixed checklist. Every row ends as `done`, `skipped: <reason>` or `failed: <error>`, and
|
|
55
|
-
Step 8 prints all
|
|
56
|
+
Step 8 prints all 14 in this order. Never drop a row from the report, even when its step did not apply.
|
|
57
|
+
Rows 3 and 8 are retired (the 3-store model, 21 Oct 2026): they stay in the list so the row numbers do not
|
|
58
|
+
move for a fleet that mixes caddis versions, and each always reports
|
|
59
|
+
`skipped: retired (see the 3-store model)`. A later release removes them with their scripts.
|
|
56
60
|
|
|
57
61
|
| # | Row | What it is | Shared checkout (Step 0) |
|
|
58
62
|
|---|---|---|---|
|
|
59
63
|
| 1 | `knowledge-transfer` | Step 1 | edits only in the Step 0 worktree |
|
|
60
64
|
| 2 | `plan-tracker` | the plan's Tracker row (Rules) | edit in the Step 0 worktree |
|
|
61
|
-
| 3 | `open-work-row` |
|
|
65
|
+
| 3 | `open-work-row` | retired: always `skipped: retired (see the 3-store model)` | never runs |
|
|
62
66
|
| 4 | `relay` | Step 3: the relay, written from scratch with current state only | the relay is local; runs |
|
|
63
67
|
| 5 | `tasks-file` | Step 3c | runs |
|
|
64
68
|
| 6 | `kb-index` | Step 6c: refresh the KB index | in the Step 0 worktree |
|
|
65
69
|
| 7 | `violations-report` | Step 6c: report standing violations, each with a one-line fix command | runs (report only) |
|
|
66
|
-
| 8 | `todo-reconcile` |
|
|
70
|
+
| 8 | `todo-reconcile` | retired: always `skipped: retired (see the 3-store model)` | never runs |
|
|
67
71
|
| 9 | `usage-record` | Step 6b: `session_state.py usage` | runs |
|
|
68
72
|
| 10 | `tidy-apply` | Step 4: `caddis_tidy.py --apply` | `skipped: shared checkout` |
|
|
69
73
|
| 11 | `state-prune` | Step 6b: `session_state.py prune` | `skipped: shared checkout` |
|
|
70
74
|
| 12 | `prune-list` | Step 6b: `caddis_tidy.py --prune`, list only | runs (lists, never applies) |
|
|
71
75
|
| 13 | `handover-check` | Step 5 | runs |
|
|
76
|
+
| 14 | `own-cleanup` | Step 6d: `caddis_created.py cleanup --apply` removes this session's merged, clean worktrees and scratch folders; lists the rest with a reason | runs (only this session's recorded worktrees and scratch) |
|
|
72
77
|
|
|
73
|
-
`tidy-apply
|
|
78
|
+
`tidy-apply` and `state-prune` run only on `SHARED: no`. Handoff never runs
|
|
74
79
|
`caddis_tidy.py --prune --apply` on its own, in any checkout; only the user can ask for it (Step 6b). In a
|
|
75
80
|
shared checkout the report also lists every tracked file Step 1 changed, under `Docs PR needed:`.
|
|
76
81
|
|
|
@@ -157,15 +162,19 @@ history, and the relay has a 4,000-character budget (`caddis_budget.py`).
|
|
|
157
162
|
> to the user and stop.
|
|
158
163
|
> 3. **Read the stored version's hash** before you compose: `caddis_workstreams.py hash <name>`
|
|
159
164
|
> (prints `none` for a new workstream).
|
|
160
|
-
> 4. **
|
|
161
|
-
>
|
|
162
|
-
>
|
|
163
|
-
>
|
|
164
|
-
>
|
|
165
|
-
>
|
|
166
|
-
>
|
|
167
|
-
>
|
|
168
|
-
>
|
|
165
|
+
> 4. **Place every open item in its store (the 3-store model).** An open item lives in the store that
|
|
166
|
+
> matches how long it lives:
|
|
167
|
+
> - **This session's own tasks:** the native task list. Step 3c saves it to
|
|
168
|
+
> `.caddis/relay/<name>.tasks.md`, a snapshot that the next handoff replaces. It is never a backlog.
|
|
169
|
+
> - **An item that must outlive the next handoff** (an owner decision, deferred work, a watch item):
|
|
170
|
+
> file it with `/caddis:park`, once, and name its slug in the relay's `## Open questions / blockers`.
|
|
171
|
+
> Park only work we will do later (`park.md` Step 1). A parking-lot file is tracked, so in a shared
|
|
172
|
+
> checkout (Step 0) write it in the Step 0 worktree.
|
|
173
|
+
> - **The order of work:** the plan Tracker and the roadmap (below). Set the Tracker row of each phase this
|
|
174
|
+
> session finished (Rules).
|
|
175
|
+
> Row 3 (`open-work-row`) is retired: report it exactly as `skipped: retired (see the 3-store model)`.
|
|
176
|
+
> The `.caddis/open-work.md` and `.caddis/todo-list/` stores are retired. Never write them. A repo that
|
|
177
|
+
> still holds an old file keeps it as its own document; caddis no longer reads or writes it.
|
|
169
178
|
> **Order of work:** when the repo has a roadmap (`caddis_roadmap.py list` prints a slug), the
|
|
170
179
|
> roadmap on origin is the order of work. Write the relay's "Next step (exact)" as
|
|
171
180
|
> `next: top open item of roadmap <slug> (caddis_roadmap.py status --roadmap <slug>)`. Never copy a
|
|
@@ -213,7 +222,8 @@ Paths are relative to the repo root.
|
|
|
213
222
|
<Commands run this session and their result: pass / fail / not-run. Be honest.>
|
|
214
223
|
|
|
215
224
|
## Open questions / blockers
|
|
216
|
-
<Decisions needed, ambiguities, anything unverified. "None" if truly none
|
|
225
|
+
<Decisions needed, ambiguities, anything unverified. "None" if truly none. An item that must outlive the
|
|
226
|
+
next handoff is filed with `/caddis:park`: name its slug here, never copy its text.>
|
|
217
227
|
|
|
218
228
|
## Learnings captured
|
|
219
229
|
knowledge-transfer: <✓ ran → files written | ✗ skipped → reason>
|
|
@@ -232,7 +242,7 @@ STATUS: <CONTINUE | OWNER-GATE <P>-OG<n> | BLOCKED <owner> | FAILED <reason>>
|
|
|
232
242
|
|
|
233
243
|
Small work that does not meet a trigger skips its block.
|
|
234
244
|
|
|
235
|
-
**Trigger: Always.** The relay ends with a status line, the last non-empty line, and it is exactly one of `STATUS: CONTINUE`, `STATUS: OWNER-GATE <P>-OG<n>`, `STATUS: BLOCKED <owner>` or `STATUS: FAILED <reason>`. In Step 3, point 5, write the relay with `python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_workstreams.py" put <name> <temp-file> --require-status --expected-hash <hash>` instead of `write` (in short: put --require-status), with the same hash Step 3 read, so a peer's newer relay is never overwritten. It rejects a relay with no valid status line, and renders the index.
|
|
245
|
+
**Trigger: Always.** The relay ends with a status line, the last non-empty line, and it is exactly one of `STATUS: CONTINUE`, `STATUS: OWNER-GATE <P>-OG<n>`, `STATUS: BLOCKED <owner>` or `STATUS: FAILED <reason>`. In Step 3, point 5, write the relay with `python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_workstreams.py" put <name> <temp-file> --require-status --expected-hash <hash>` instead of `write` (in short: put --require-status), with the same hash Step 3 read, so a peer's newer relay is never overwritten. It rejects a relay with no valid status line, and renders the index.
|
|
236
246
|
|
|
237
247
|
## Step 3c - Save the open tasks
|
|
238
248
|
The task list dies with the session unless it is saved. Write this session's open tasks beside
|
|
@@ -262,7 +272,7 @@ be blocked by a script it does not have. Include its report in your output. A **
|
|
|
262
272
|
(`done/<name>` already exists) is reported by the script, not fatal — surface it, do not fail the
|
|
263
273
|
handoff over it. Exit 2 means a plan is held because its Tracker still has open rows (`held (open Tracker rows): ...` lines, from Phase 3): show those lines; finish, park (`.caddis/parking-lot/<file>.md` in the row) or mark the rows `dropped: <reason>`, or set the plan status back. Do not fail the handoff over it.
|
|
264
274
|
|
|
265
|
-
After step 4, for each item this session closed (a phase `<plan>#<n>`, a plan slug, or
|
|
275
|
+
After step 4, for each item this session closed (a phase `<plan>#<n>`, a plan slug, or a parking-lot slug), run `mentions` to check whether another relay's Next step still names it:
|
|
266
276
|
```
|
|
267
277
|
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_workstreams.py" mentions --item "<item>" --except <name>
|
|
268
278
|
```
|
|
@@ -284,12 +294,10 @@ incoming session looking for a prompt that was never written. Fix what it lists,
|
|
|
284
294
|
It also notes any generated artefact committed before its generator last changed. That is advisory,
|
|
285
295
|
not blocking — but do not quote a report the note names without rebuilding it first.
|
|
286
296
|
|
|
287
|
-
## Step 6 —
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
```
|
|
292
|
-
This marks ad-hoc to-do items done by metadata ID; it never edits the Tracker and ignores phase rows.
|
|
297
|
+
## Step 6 — retired (task reconcile)
|
|
298
|
+
This step is retired. It used to reconcile the `todo-list/` store, which is retired too (the 3-store model),
|
|
299
|
+
so the step does nothing: do not run any script for it. Report row 8 (`todo-reconcile`) as
|
|
300
|
+
`skipped: retired (see the 3-store model)`. The script stays in place for older installs only.
|
|
293
301
|
|
|
294
302
|
## Step 6b — record usage and tidy session state
|
|
295
303
|
The Stop hook only writes the session-state file. These two used to run on every turn; they run
|
|
@@ -341,6 +349,27 @@ Then, when the repo has a roadmap (`.caddis/roadmaps/`), re-render its page so p
|
|
|
341
349
|
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_roadmap.py" render --all
|
|
342
350
|
```
|
|
343
351
|
|
|
352
|
+
## Step 6d — remove this session's own worktrees and scratch folders
|
|
353
|
+
Checklist row 14, `own-cleanup`. It runs in every checkout, a shared one too, after the Step 0 `finish`
|
|
354
|
+
(falls back to `scripts/caddis_created.py` in a source checkout; if the script is missing, or exits 2 because
|
|
355
|
+
it has no `cleanup`, the row is `skipped: not installed`):
|
|
356
|
+
```
|
|
357
|
+
python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_created.py" cleanup --session-id <session-id> --apply
|
|
358
|
+
```
|
|
359
|
+
It reads only this session's record (`~/.caddis/sessions/<session-id>.created.jsonl`). A worktree goes only
|
|
360
|
+
when its PR is merged, `git status` is clean, it has no commits after the PR head, and every file its branch
|
|
361
|
+
changed equals `origin/<default>` (so a squash merge counts). Then its local and remote branch go too: each
|
|
362
|
+
only while its tip is still the merged work. A scratch folder goes after a full scan, links first.
|
|
363
|
+
|
|
364
|
+
It never removes: another session's worktree (it is not in this record), a roadmap runner's worktree, the
|
|
365
|
+
worktree this session is working in, one with uncommitted changes (untracked files count), one whose PR is
|
|
366
|
+
not merged or not found, one whose tree differs from `origin/<default>`, or anything through a
|
|
367
|
+
junction or symlink (a link is removed as a link; its target stays). It prints one line per entry (`REMOVED`, `KEPT
|
|
368
|
+
<path>: <reason>`, `GONE` or `FAILED <path>: <problem>`) and ends with
|
|
369
|
+
`[OWN-CLEANUP] removed <n>, kept <n>, gone <n>, failed <n>`. Include that summary line and each `KEPT` and
|
|
370
|
+
`FAILED` line in your report. It always exits 0: a kept or failed entry is not a failure of the row, which is
|
|
371
|
+
`done` when the script ran.
|
|
372
|
+
|
|
344
373
|
## Step 7 — push prompt (interactive only)
|
|
345
374
|
If this is an interactive session, ask the user every time — never reuse an earlier answer:
|
|
346
375
|
`Push this note for another machine? (y/N)`
|
|
@@ -360,17 +389,18 @@ Print this block, every row filled with `done`, `skipped: <reason>` or `failed:
|
|
|
360
389
|
=== HANDOFF CHECKLIST ===
|
|
361
390
|
1 knowledge-transfer done | skipped: <reason> | failed: <error>
|
|
362
391
|
2 plan-tracker <same three forms>
|
|
363
|
-
3 open-work-row
|
|
392
|
+
3 open-work-row skipped: retired (see the 3-store model)
|
|
364
393
|
4 relay <same three forms>
|
|
365
394
|
5 tasks-file <same three forms>
|
|
366
395
|
6 kb-index <same three forms>
|
|
367
396
|
7 violations-report <same three forms>
|
|
368
|
-
8 todo-reconcile
|
|
397
|
+
8 todo-reconcile skipped: retired (see the 3-store model)
|
|
369
398
|
9 usage-record <same three forms>
|
|
370
399
|
10 tidy-apply <same three forms>
|
|
371
400
|
11 state-prune <same three forms>
|
|
372
401
|
12 prune-list <same three forms>
|
|
373
402
|
13 handover-check <same three forms>
|
|
403
|
+
14 own-cleanup <same three forms>
|
|
374
404
|
Shared checkout: yes|no <reason>
|
|
375
405
|
```
|
|
376
406
|
|
|
@@ -43,10 +43,10 @@ It prints `SHARED: yes <reason>` or `SHARED: no` and exits 0. It says yes when t
|
|
|
43
43
|
|
|
44
44
|
- **On `SHARED: no`,** do the steps as written, in this checkout.
|
|
45
45
|
- **On `SHARED: yes`,** never move this checkout. Leave its changes as they are, and report them. Instead:
|
|
46
|
-
- **Rebase:** `git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" rebase-<name>)" <branch>`, then
|
|
46
|
+
- **Rebase:** `git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" rebase-<name> --record --purpose "rebase <name>")" <branch>`, then
|
|
47
47
|
`git -C <worktree> rebase origin/<default>` and `git -C <worktree> push --force-with-lease origin HEAD:<branch>`.
|
|
48
48
|
- **Pull a branch to test it:** `git fetch origin`, then
|
|
49
|
-
`git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" test-<name>)" origin/<branch>` (for the default branch,
|
|
49
|
+
`git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" test-<name> --record --purpose "test <name>")" origin/<branch>` (for the default branch,
|
|
50
50
|
`origin/<default>`), and run the gates there. Install dependencies fresh; never link `node_modules` or a venv.
|
|
51
51
|
- **Clean up after a merge:** do not switch or pull. Run `git fetch --prune`, then
|
|
52
52
|
`git fetch origin <default>:<default>`: it fast-forwards the default branch with no checkout. Git refuses when a
|
|
@@ -56,7 +56,8 @@ It prints `SHARED: yes <reason>` or `SHARED: no` and exits 0. It says yes when t
|
|
|
56
56
|
|
|
57
57
|
`<name>` is the branch name with each `/` written as `-`. `caddis_worktree_root.py` prints the path of a new worktree:
|
|
58
58
|
`$CADDIS_WORKTREE_ROOT/<repo>/<short-name>`, else `<parent of the main checkout>/.worktrees/<repo>/<short-name>`. Never `%TEMP%`: Windows
|
|
59
|
-
cleanup can empty it.
|
|
59
|
+
cleanup can empty it. `--record --purpose "<why>"` also writes the path to this
|
|
60
|
+
session's created list (`caddis_created.py`), so `/handoff` can remove the worktree later. The caddis guard checks only the `Shared checkout: yes` line in
|
|
60
61
|
`AGENTS.md`, not a dirty tree: with that line, it asks before a tree move, and denies it in a headless session.
|
|
61
62
|
<!-- /checkout-safety -->
|
|
62
63
|
|
|
@@ -15,7 +15,7 @@ Use the scripts in that folder; do not look for them in another caddis install.
|
|
|
15
15
|
|
|
16
16
|
1. The plan `.caddis/plans/{{slug}}.md`: its goal, its decisions, its tracker. Every decision binds you.
|
|
17
17
|
2. The relay `.caddis/relay/{{slug}}.md`. Its "Next step" says where to start.
|
|
18
|
-
3. The open-
|
|
18
|
+
3. The open parking-lot items (`.caddis/parking-lot/*.md` with `status: open`) that name this plan, when any.
|
|
19
19
|
|
|
20
20
|
## 2. Step 0: reconcile
|
|
21
21
|
|
|
@@ -47,8 +47,8 @@ publish a branch that does). Commit the phase there, with its tracker row set to
|
|
|
47
47
|
- The runner reviews `risk: high` phases. A phase marked `**Risk:** high`: do not halt for it and do not run the
|
|
48
48
|
review yourself. When its exit gate is green, set its row `done` and end with `STATUS: CONTINUE`. The runner then
|
|
49
49
|
reviews it twice and, on findings, starts one fix session.
|
|
50
|
-
- Set the tracker row of the batch to `done` (with its evidence) when its exit gate is green.
|
|
51
|
-
|
|
50
|
+
- Set the tracker row of the batch to `done` (with its evidence) when its exit gate is green. Work you defer on
|
|
51
|
+
purpose is filed once with `/caddis:park` (a parking-lot item); never write a to-do or backlog file.
|
|
52
52
|
|
|
53
53
|
## 5. Write the relay
|
|
54
54
|
|
|
@@ -42,10 +42,10 @@ It prints `SHARED: yes <reason>` or `SHARED: no` and exits 0. It says yes when t
|
|
|
42
42
|
|
|
43
43
|
- **On `SHARED: no`,** do the steps as written, in this checkout.
|
|
44
44
|
- **On `SHARED: yes`,** never move this checkout. Leave its changes as they are, and report them. Instead:
|
|
45
|
-
- **Rebase:** `git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" rebase-<name>)" <branch>`, then
|
|
45
|
+
- **Rebase:** `git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" rebase-<name> --record --purpose "rebase <name>")" <branch>`, then
|
|
46
46
|
`git -C <worktree> rebase origin/<default>` and `git -C <worktree> push --force-with-lease origin HEAD:<branch>`.
|
|
47
47
|
- **Pull a branch to test it:** `git fetch origin`, then
|
|
48
|
-
`git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" test-<name>)" origin/<branch>` (for the default branch,
|
|
48
|
+
`git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" test-<name> --record --purpose "test <name>")" origin/<branch>` (for the default branch,
|
|
49
49
|
`origin/<default>`), and run the gates there. Install dependencies fresh; never link `node_modules` or a venv.
|
|
50
50
|
- **Clean up after a merge:** do not switch or pull. Run `git fetch --prune`, then
|
|
51
51
|
`git fetch origin <default>:<default>`: it fast-forwards the default branch with no checkout. Git refuses when a
|
|
@@ -55,7 +55,8 @@ It prints `SHARED: yes <reason>` or `SHARED: no` and exits 0. It says yes when t
|
|
|
55
55
|
|
|
56
56
|
`<name>` is the branch name with each `/` written as `-`. `caddis_worktree_root.py` prints the path of a new worktree:
|
|
57
57
|
`$CADDIS_WORKTREE_ROOT/<repo>/<short-name>`, else `<parent of the main checkout>/.worktrees/<repo>/<short-name>`. Never `%TEMP%`: Windows
|
|
58
|
-
cleanup can empty it.
|
|
58
|
+
cleanup can empty it. `--record --purpose "<why>"` also writes the path to this
|
|
59
|
+
session's created list (`caddis_created.py`), so `/handoff` can remove the worktree later. The caddis guard checks only the `Shared checkout: yes` line in
|
|
59
60
|
`AGENTS.md`, not a dirty tree: with that line, it asks before a tree move, and denies it in a headless session.
|
|
60
61
|
<!-- /checkout-safety -->
|
|
61
62
|
|
|
@@ -41,10 +41,10 @@ It prints `SHARED: yes <reason>` or `SHARED: no` and exits 0. It says yes when t
|
|
|
41
41
|
|
|
42
42
|
- **On `SHARED: no`,** do the steps as written, in this checkout.
|
|
43
43
|
- **On `SHARED: yes`,** never move this checkout. Leave its changes as they are, and report them. Instead:
|
|
44
|
-
- **Rebase:** `git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" rebase-<name>)" <branch>`, then
|
|
44
|
+
- **Rebase:** `git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" rebase-<name> --record --purpose "rebase <name>")" <branch>`, then
|
|
45
45
|
`git -C <worktree> rebase origin/<default>` and `git -C <worktree> push --force-with-lease origin HEAD:<branch>`.
|
|
46
46
|
- **Pull a branch to test it:** `git fetch origin`, then
|
|
47
|
-
`git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" test-<name>)" origin/<branch>` (for the default branch,
|
|
47
|
+
`git worktree add --detach "$(python "${CLAUDE_PLUGIN_ROOT}/scripts/caddis_worktree_root.py" test-<name> --record --purpose "test <name>")" origin/<branch>` (for the default branch,
|
|
48
48
|
`origin/<default>`), and run the gates there. Install dependencies fresh; never link `node_modules` or a venv.
|
|
49
49
|
- **Clean up after a merge:** do not switch or pull. Run `git fetch --prune`, then
|
|
50
50
|
`git fetch origin <default>:<default>`: it fast-forwards the default branch with no checkout. Git refuses when a
|
|
@@ -54,7 +54,8 @@ It prints `SHARED: yes <reason>` or `SHARED: no` and exits 0. It says yes when t
|
|
|
54
54
|
|
|
55
55
|
`<name>` is the branch name with each `/` written as `-`. `caddis_worktree_root.py` prints the path of a new worktree:
|
|
56
56
|
`$CADDIS_WORKTREE_ROOT/<repo>/<short-name>`, else `<parent of the main checkout>/.worktrees/<repo>/<short-name>`. Never `%TEMP%`: Windows
|
|
57
|
-
cleanup can empty it.
|
|
57
|
+
cleanup can empty it. `--record --purpose "<why>"` also writes the path to this
|
|
58
|
+
session's created list (`caddis_created.py`), so `/handoff` can remove the worktree later. The caddis guard checks only the `Shared checkout: yes` line in
|
|
58
59
|
`AGENTS.md`, not a dirty tree: with that line, it asks before a tree move, and denies it in a headless session.
|
|
59
60
|
<!-- /checkout-safety -->
|
|
60
61
|
|
|
@@ -39,10 +39,16 @@ If none is true, stop here and use `git switch -c`.
|
|
|
39
39
|
script `caddis_worktree_root.py` prints the path; use it so the rule lives in one place:
|
|
40
40
|
|
|
41
41
|
```powershell
|
|
42
|
-
$wt = python "<caddis scripts>\caddis_worktree_root.py" <short-name> # run in the repo; prints the path
|
|
42
|
+
$wt = python "<caddis scripts>\caddis_worktree_root.py" <short-name> --record --purpose "<why>" # run in the repo; prints the path
|
|
43
43
|
git worktree add -b <branch> $wt origin/<default>
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
+
`--record` also writes the path to this session's created list (`caddis_created.py`), so `/handoff` can remove the
|
|
47
|
+
worktree later. Always record it, subagents most of all: their tool calls are in a separate transcript that the
|
|
48
|
+
Stop hook does not read. If you create a worktree without the helper, run
|
|
49
|
+
`python "<caddis scripts>\caddis_created.py" record --path <path> --kind worktree --purpose "<why>"` right after
|
|
50
|
+
`git worktree add`.
|
|
51
|
+
|
|
46
52
|
`<caddis scripts>` is the `scripts` folder of the installed caddis plugin. Do not create worktrees inside the
|
|
47
53
|
repo. An existing worktree stays where it is: moving it breaks a venv, which keeps absolute paths.
|
|
48
54
|
4. State the full path of the worktree. Work only there, and do not switch branches in it.
|
|
@@ -39,10 +39,16 @@ If none is true, stop here and use `git switch -c`.
|
|
|
39
39
|
script `caddis_worktree_root.py` prints the path; use it so the rule lives in one place:
|
|
40
40
|
|
|
41
41
|
```powershell
|
|
42
|
-
$wt = python "<caddis scripts>\caddis_worktree_root.py" <short-name> # run in the repo; prints the path
|
|
42
|
+
$wt = python "<caddis scripts>\caddis_worktree_root.py" <short-name> --record --purpose "<why>" # run in the repo; prints the path
|
|
43
43
|
git worktree add -b <branch> $wt origin/<default>
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
+
`--record` also writes the path to this session's created list (`caddis_created.py`), so `/handoff` can remove the
|
|
47
|
+
worktree later. Always record it, subagents most of all: their tool calls are in a separate transcript that the
|
|
48
|
+
Stop hook does not read. If you create a worktree without the helper, run
|
|
49
|
+
`python "<caddis scripts>\caddis_created.py" record --path <path> --kind worktree --purpose "<why>"` right after
|
|
50
|
+
`git worktree add`.
|
|
51
|
+
|
|
46
52
|
`<caddis scripts>` is the `scripts` folder of the installed caddis plugin. Do not create worktrees inside the
|
|
47
53
|
repo. An existing worktree stays where it is: moving it breaks a venv, which keeps absolute paths.
|
|
48
54
|
4. State the full path of the worktree. Work only there, and do not switch branches in it.
|
|
@@ -15,7 +15,7 @@ Use the scripts in that folder; do not look for them in another caddis install.
|
|
|
15
15
|
|
|
16
16
|
1. The plan `.caddis/plans/{{slug}}.md`: its goal, its decisions, its tracker. Every decision binds you.
|
|
17
17
|
2. The relay `.caddis/relay/{{slug}}.md`. Its "Next step" says where to start.
|
|
18
|
-
3. The open-
|
|
18
|
+
3. The open parking-lot items (`.caddis/parking-lot/*.md` with `status: open`) that name this plan, when any.
|
|
19
19
|
|
|
20
20
|
## 2. Step 0: reconcile
|
|
21
21
|
|
|
@@ -47,8 +47,8 @@ publish a branch that does). Commit the phase there, with its tracker row set to
|
|
|
47
47
|
- The runner reviews `risk: high` phases. A phase marked `**Risk:** high`: do not halt for it and do not run the
|
|
48
48
|
review yourself. When its exit gate is green, set its row `done` and end with `STATUS: CONTINUE`. The runner then
|
|
49
49
|
reviews it twice and, on findings, starts one fix session.
|
|
50
|
-
- Set the tracker row of the batch to `done` (with its evidence) when its exit gate is green.
|
|
51
|
-
|
|
50
|
+
- Set the tracker row of the batch to `done` (with its evidence) when its exit gate is green. Work you defer on
|
|
51
|
+
purpose is filed once with `/caddis:park` (a parking-lot item); never write a to-do or backlog file.
|
|
52
52
|
|
|
53
53
|
## 5. Write the relay
|
|
54
54
|
|
package/bundles/manifest.json
CHANGED
package/package.json
CHANGED