codebyplan 1.13.8 → 1.13.10
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/dist/cli.js +436 -110
- package/package.json +1 -1
- package/templates/hooks/cbp-mcp-round-sync.sh +17 -1
- package/templates/settings.project.base.json +2 -0
- package/templates/skills/cbp-git-worktree-create/SKILL.md +1 -1
- package/templates/skills/cbp-round-update/SKILL.md +14 -1
- package/templates/skills/cbp-session-end/SKILL.md +28 -75
- package/templates/skills/cbp-session-start/SKILL.md +46 -30
package/package.json
CHANGED
|
@@ -12,6 +12,14 @@
|
|
|
12
12
|
# - Web-UI flag (app_file_approval_by_user) consumption + reset
|
|
13
13
|
# - Writes both PATCH /api/rounds/${ROUND_ID} and PATCH /api/tasks/${TASK_ID}
|
|
14
14
|
#
|
|
15
|
+
# Caller worktree identity:
|
|
16
|
+
# The CLI auto-resolves caller_worktree_id (override flag → cache →
|
|
17
|
+
# in-process tuple API) and hard-fails with exit 1 if it cannot resolve
|
|
18
|
+
# on the write path. This hook resolves the worktree id before invoking the
|
|
19
|
+
# CLI and passes it via --caller-worktree-id so the server can honor the
|
|
20
|
+
# feat-worktree lock. The hook itself stays non-fatal (exits 0) and surfaces
|
|
21
|
+
# the CLI's stderr output to the user.
|
|
22
|
+
#
|
|
15
23
|
# Flags:
|
|
16
24
|
# --dry-run Pass through to CLI (prints merged payload, no API writes).
|
|
17
25
|
# Used by fixture-based smoke tests.
|
|
@@ -67,11 +75,19 @@ if [ -z "$TASK_ID" ]; then
|
|
|
67
75
|
exit 0
|
|
68
76
|
fi
|
|
69
77
|
|
|
78
|
+
# Resolve worktree id before invoking the CLI so the server can honor the
|
|
79
|
+
# feat-worktree lock. On miss (unregistered worktree) the CLI falls back to
|
|
80
|
+
# its in-process resolve and hard-fails with guidance if still unresolved.
|
|
81
|
+
WORKTREE_ID=$(npx codebyplan resolve-worktree 2>/dev/null)
|
|
82
|
+
|
|
70
83
|
# Delegate to the codebyplan CLI (single source of truth for merge semantics)
|
|
71
84
|
CMD_ARGS=("round" "sync-approvals" "--round-id" "$ROUND_ID" "--task-id" "$TASK_ID")
|
|
85
|
+
if [ -n "$WORKTREE_ID" ]; then
|
|
86
|
+
CMD_ARGS+=("--caller-worktree-id" "$WORKTREE_ID")
|
|
87
|
+
fi
|
|
72
88
|
[ "$DRY_RUN" = "true" ] && CMD_ARGS+=("--dry-run")
|
|
73
89
|
|
|
74
|
-
if npx codebyplan "${CMD_ARGS[@]}"
|
|
90
|
+
if npx codebyplan "${CMD_ARGS[@]}"; then
|
|
75
91
|
echo "cbp-mcp-round-sync: synced via CLI for round ${ROUND_ID}" >&2
|
|
76
92
|
else
|
|
77
93
|
echo "cbp-mcp-round-sync: CLI sync failed for round ${ROUND_ID} (non-fatal)" >&2
|
|
@@ -181,6 +181,8 @@
|
|
|
181
181
|
"Bash(npx codebyplan resolve-worktree:*)",
|
|
182
182
|
"Bash(codebyplan cmux-sync:*)",
|
|
183
183
|
"Bash(npx codebyplan cmux-sync:*)",
|
|
184
|
+
"Bash(codebyplan version-status:*)",
|
|
185
|
+
"Bash(npx codebyplan version-status:*)",
|
|
184
186
|
"Bash(codebyplan statusline:*)",
|
|
185
187
|
"Bash(npx codebyplan statusline:*)",
|
|
186
188
|
"Bash(codebyplan ports:*)",
|
|
@@ -196,7 +196,7 @@ echo '{}' > "$WORKTREE_PATH/.codebyplan/shipment.json"
|
|
|
196
196
|
echo '{}' > "$WORKTREE_PATH/.codebyplan/vendor.json"
|
|
197
197
|
```
|
|
198
198
|
|
|
199
|
-
The `.codebyplan/device.local.json` file is created by `npx codebyplan setup` on the device (gitignored). The `worktree_id` is never
|
|
199
|
+
The `.codebyplan/device.local.json` file is created by `npx codebyplan setup` on the device (gitignored). The `worktree_id` is never COMMITTED; it may be cached per-device in the gitignored `.codebyplan/worktree.local.json` (branch-keyed, re-derivable via `codebyplan resolve-worktree --cache`), otherwise resolved at runtime from the `(device_id, repo path, branch)` tuple via `npx codebyplan resolve-worktree`.
|
|
200
200
|
|
|
201
201
|
No need to mark as `skip-worktree` — the committed files are merge-safe per CHK-108 and CHK-120.
|
|
202
202
|
|
|
@@ -69,7 +69,20 @@ Run:
|
|
|
69
69
|
npx codebyplan round sync-approvals --round-id <round_id> --task-id <task_id>
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
The CLI auto-resolves the worktree id
|
|
72
|
+
The CLI auto-resolves the caller worktree id with the following precedence:
|
|
73
|
+
1. `--caller-worktree-id <uuid>` override (if passed — skips all resolution)
|
|
74
|
+
2. Per-device branch-keyed cache (`.codebyplan/worktree.local.json`)
|
|
75
|
+
3. In-process tuple API call: `POST /worktrees/resolve` using `(device_id, repo_path, branch)`
|
|
76
|
+
|
|
77
|
+
On the write path (non `--dry-run`), if the worktree id cannot be resolved the CLI **hard-fails with exit 1** and prints an actionable message. To pre-populate the cache:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
npx codebyplan resolve-worktree --cache
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
If this worktree is not yet registered, run `npx codebyplan setup` first, then re-run `/cbp-round-update`.
|
|
84
|
+
|
|
85
|
+
The CLI parses `git status --short`, merges drift + staging + web-UI flag, and writes both round and task (forwarding `caller_worktree_id` on both writes so the server honors the feat-worktree lock).
|
|
73
86
|
|
|
74
87
|
Read the stdout JSON: `{ added, stale_marked, reactivated, total_files }`.
|
|
75
88
|
|
|
@@ -25,7 +25,7 @@ Always write a session log for this session — **even if empty**. `/cbp-session
|
|
|
25
25
|
|
|
26
26
|
### Step 1.3: Capture Handoff Snapshot
|
|
27
27
|
|
|
28
|
-
Snapshot the current next-action so the next `/cbp-session-start` (Step 4.5) can auto-resume.
|
|
28
|
+
Snapshot the current next-action so the next `/cbp-session-start` (Step 4.5) can auto-resume. The handoff write-path + payload shape are specified inline here and in `/cbp-session-start` Step 4.5 (freshness gate).
|
|
29
29
|
|
|
30
30
|
1. Call MCP `get_next_action({ repo_id, worktree_id })`.
|
|
31
31
|
2. If the returned `command` is non-empty (active work in flight):
|
|
@@ -60,7 +60,8 @@ Same rule as `/cbp-session-start` Step 5.7 — only commit files that are **not*
|
|
|
60
60
|
- Collect `files[]` from those rounds → `task_files` set
|
|
61
61
|
- If no active task exists, `task_files` is empty
|
|
62
62
|
3. `infra_files = changed_files − task_files`
|
|
63
|
-
4.
|
|
63
|
+
4. Re-run `git status --porcelain` immediately before showing the commit-prompt (after Steps 1–1.3 have completed their MCP round-trips). Recompute `infra_files` from the fresh listing — eliminates the race where files appear in the index only after the network round-trips complete.
|
|
64
|
+
5. If `infra_files` is empty → skip. Otherwise present once:
|
|
64
65
|
|
|
65
66
|
```
|
|
66
67
|
Commit these non-task files before ending session?
|
|
@@ -69,7 +70,7 @@ Same rule as `/cbp-session-start` Step 5.7 — only commit files that are **not*
|
|
|
69
70
|
Reply: yes | no | select
|
|
70
71
|
```
|
|
71
72
|
|
|
72
|
-
|
|
73
|
+
6. On `yes`: `git add` the listed files, then trigger `/cbp-git-commit`.
|
|
73
74
|
On `no`: skip. On `select`: ask which subset.
|
|
74
75
|
|
|
75
76
|
Non-blocking — session end proceeds either way.
|
|
@@ -78,7 +79,7 @@ Non-blocking — session end proceeds either way.
|
|
|
78
79
|
|
|
79
80
|
Keep this worktree's **home branch** rooted at the freshest production tip — no prompt, fully non-blocking. Home branches are the folder-named placeholder branches each worktree rests on (e.g. `codebyplan-web`); `feat/*` branches are deliberately skipped — they integrate via `/cbp-merge-main` with QA, never an auto fast-forward.
|
|
80
81
|
|
|
81
|
-
Runs after Step 1.5 so any infra commits land first, and before Step 1.7 so the asset
|
|
82
|
+
Runs after Step 1.5 so any infra commits land first, and before Step 1.7 so the freshness gate's asset update operates on the freshest tree.
|
|
82
83
|
|
|
83
84
|
Resolve the production branch: read `.codebyplan/git.json` and take `branch_config.production` (fall back to `main` if the file or field is absent). Call this `$PRODUCTION`. Then compare the current branch against the worktree's folder name:
|
|
84
85
|
|
|
@@ -99,83 +100,35 @@ CURRENT="$(git rev-parse --abbrev-ref HEAD)"
|
|
|
99
100
|
|
|
100
101
|
Never rebase, reset, force-push, or stash. A non-fast-forwardable home branch is a signal to reconcile manually, not to overwrite.
|
|
101
102
|
|
|
102
|
-
### Step 1.7:
|
|
103
|
+
### Step 1.7: Package Freshness Gate
|
|
103
104
|
|
|
104
|
-
|
|
105
|
+
Check whether a newer `codebyplan` is published and safe to auto-install on this worktree's current branch, then run the local install + asset update. Runs after the Step 1.6 home-branch fast-forward (so any update lands on the freshest tree) and before Step 2. Fully non-blocking — the guard and skip branches proceed silently; any failure in the install/update commands warns once and continues to Step 2. session-end never halts.
|
|
105
106
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
Run the latest published CLI's asset-update verb to pull any skill / agent / hook changes:
|
|
109
|
-
|
|
110
|
-
```
|
|
111
|
-
npx codebyplan@latest claude update
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Always run — do not skip, even when the current repo is the canonical-owner monorepo source.
|
|
115
|
-
|
|
116
|
-
The command may pause for interactive prompts when:
|
|
117
|
-
|
|
118
|
-
- a tracked file has been hand-edited locally (overwrite / skip / diff)
|
|
119
|
-
- a new file is being shipped for the first time (opt-in / skip)
|
|
120
|
-
- a file has been removed from the package (remove / keep)
|
|
121
|
-
|
|
122
|
-
Respond to each prompt in the terminal as it appears. The commit prompt below runs only after all per-file prompts are resolved.
|
|
123
|
-
|
|
124
|
-
Failure handling:
|
|
125
|
-
|
|
126
|
-
- On non-zero exit: wait ~5 s, retry once.
|
|
127
|
-
- If retry also fails: print a warning and continue — this step is non-blocking.
|
|
128
|
-
|
|
129
|
-
After the command exits (success):
|
|
130
|
-
|
|
131
|
-
1. Run `git status --porcelain -- .claude/` to detect any file changes.
|
|
132
|
-
2. If non-empty, present once (same pattern as Step 1.5):
|
|
133
|
-
|
|
134
|
-
```
|
|
135
|
-
.claude/ was updated. Commit these changes?
|
|
136
|
-
[list of changed paths under .claude/]
|
|
137
|
-
|
|
138
|
-
Reply: yes | no | select
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
On `yes`: `git add` the listed paths only (not the whole `.claude/` directory), then trigger `/cbp-git-commit`.
|
|
142
|
-
On `no`: skip. On `select`: ask which subset.
|
|
143
|
-
|
|
144
|
-
3. Print the final stdout line from the update command as a one-line session summary (e.g. `codebyplan claude update: 47 files tracked.`). Silent when the command produces no stdout.
|
|
145
|
-
|
|
146
|
-
Non-blocking — session end proceeds regardless of outcome.
|
|
147
|
-
|
|
148
|
-
**b) `codebyplan` (project CLI)**
|
|
149
|
-
|
|
150
|
-
Fetch the latest published version of the project CLI. The `codebyplan` CLI has no `update` verb (subcommands are `setup`, `sync`, `eslint`); the freshness idiom is to invoke a fast read-only flag with `@latest` so npx fetches and caches the newest published version:
|
|
151
|
-
|
|
152
|
-
```
|
|
153
|
-
npx codebyplan@latest --version
|
|
107
|
+
```bash
|
|
108
|
+
VERSION_JSON=$(npx codebyplan version-status 2>/dev/null)
|
|
154
109
|
```
|
|
155
110
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
Failure handling:
|
|
159
|
-
|
|
160
|
-
- On non-zero exit: wait ~5 s, retry once.
|
|
161
|
-
- If retry also fails: print a warning and continue — this step is non-blocking.
|
|
162
|
-
|
|
163
|
-
After the command exits (success):
|
|
111
|
+
Parse `$VERSION_JSON` as JSON and branch on the result:
|
|
164
112
|
|
|
165
|
-
|
|
166
|
-
2.
|
|
113
|
+
- **Probe failed / unparseable** — the command errored, produced no output, or the output cannot be parsed as JSON carrying the required keys (`newer`, `guarded`, `installCommand`). This includes an installed `codebyplan` too old to have the `version-status` subcommand (which prints `Unknown command`). → **FAIL-SAFE SKIP**: proceed silently to Step 2. A best-effort freshness probe must never disrupt session-end.
|
|
114
|
+
- **`guarded: true`** (protected/main branch OR the canonical `codebyplan` source monorepo — any `guardReason`) → skip silently, proceed to Step 2. Gate on the `guarded` boolean only; never branch on the specific `guardReason` string. This is the guard that prevents clobbering the canonical monorepo's ahead-of-published `.claude/` and blocks any update or commit on a protected branch.
|
|
115
|
+
- **`newer: false`** (already up to date) → skip silently, proceed to Step 2.
|
|
116
|
+
- **`newer: true` AND `guarded: false`** → run the update path:
|
|
117
|
+
1. Run the JSON's `installCommand` (e.g. `pnpm add codebyplan@latest`) to LOCALLY install `codebyplan@latest` via the repo's package manager. Never a global `-g` install.
|
|
118
|
+
2. Run `npx codebyplan claude update` to refresh the worktree's `.claude/` assets on the current branch. If `installCommand` (step 1) or this command exits non-zero, warn once and skip to Step 2 — this path is non-blocking.
|
|
119
|
+
3. Detect changes across BOTH asset directories in one pass: `git status --porcelain -- .claude/ .codebyplan/`. If non-empty, present a single combined offer (same pattern as Step 1.5):
|
|
167
120
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
121
|
+
```
|
|
122
|
+
codebyplan updated. Commit these changes before ending the session?
|
|
123
|
+
[list of changed paths under .claude/ and .codebyplan/]
|
|
171
124
|
|
|
172
|
-
|
|
173
|
-
|
|
125
|
+
Reply: yes | no | select
|
|
126
|
+
```
|
|
174
127
|
|
|
175
|
-
|
|
176
|
-
|
|
128
|
+
On `yes`: `git add` the listed paths only (not the whole directories), then trigger `/cbp-git-commit`. On `no`: skip. On `select`: ask which subset.
|
|
129
|
+
4. Continue to Step 2 — session-end does NOT halt. The update lands in the current worktree on its current branch; main/protected branches and the canonical source repo are already excluded by the `guarded` check above.
|
|
177
130
|
|
|
178
|
-
|
|
131
|
+
**Home branches are intentionally not guarded.** A worktree's folder-named home branch (e.g. `codebyplan-web`) is neither protected/main nor the canonical source, so `version-status` returns `guarded:false` there and this gate runs the update exactly as on a feat branch — landing it on whichever branch the worktree currently rests on (the deliberate "update the branch they're on, except main/canonical" behavior).
|
|
179
132
|
|
|
180
133
|
Non-blocking — session end proceeds regardless of outcome.
|
|
181
134
|
|
|
@@ -204,9 +157,9 @@ You can close this window.
|
|
|
204
157
|
## Integration
|
|
205
158
|
|
|
206
159
|
- **Triggered by**: user invocation (prompted by `/cbp-todo` when no work remains)
|
|
207
|
-
- **Reads**: `.codebyplan/repo.json`, `.codebyplan/git.json` (`branch_config.production` for the Step 1.6 home-branch fast-forward), MCP `get_session_logs` (resolve current log), MCP `get_current_task`, MCP `get_rounds`, MCP `get_next_action` (Step 1.3 handoff snapshot)
|
|
160
|
+
- **Reads**: `.codebyplan/repo.json`, `.codebyplan/git.json` (`branch_config.production` for the Step 1.6 home-branch fast-forward), MCP `get_session_logs` (resolve current log), MCP `get_current_task`, MCP `get_rounds`, MCP `get_next_action` (Step 1.3 handoff snapshot); `npx codebyplan version-status` (Step 1.7 package-freshness gate)
|
|
208
161
|
- **Writes**: MCP `update_session_log` (with `ended_at` + `handoff` per TASK-2 alias surface; or `create_session_log` fallback), MCP `update_session_state` (deactivate)
|
|
209
162
|
- **Spawns**: none
|
|
210
|
-
- **Triggers**: none at the skill-contract level.
|
|
163
|
+
- **Triggers**: none at the skill-contract level. Step 1.5 may invoke `/cbp-git-commit` inline on user approval; Step 1.7 may invoke `/cbp-git-commit` on the `newer:true AND guarded:false` update path (committing changed `.claude/` and `.codebyplan/` paths).
|
|
211
164
|
- **Paired with**: `/cbp-session-start`
|
|
212
|
-
- **Pairs with**:
|
|
165
|
+
- **Pairs with**: `/cbp-session-start` Step 4.5 (handoff payload shape + freshness-gate contract; specified inline — no separate rule file)
|
|
@@ -12,32 +12,29 @@ Activate the session, open a fresh session log, and surface the previous log's p
|
|
|
12
12
|
|
|
13
13
|
## Instructions
|
|
14
14
|
|
|
15
|
-
Run Steps 0 through 5.8 silently (no intermediate output) — except Step 1.4 may surface a one-line fast-forward note or warning, Step 1.5 may surface a one-line infra-drift nudge, and Step 5.7 may surface an approval gate. (Step numbers are organizational labels; execution order is 0 → 1 → 1.4 → 1.5 →
|
|
15
|
+
Run Steps 0 through 5.8 silently (no intermediate output) — except Step 0 aborts the session on MCP failure, Step 1.4 may surface a one-line fast-forward note or warning, Step 1.5 may surface a one-line infra-drift nudge, Step 1.6 may run an install-and-halt path, Step 4.5 may auto-resume a handoff and exit session-start entirely (no Step 6 output), and Step 5.7 may surface an approval gate. (Step numbers are organizational labels; execution order is 0 → 1 → 1.4 → 1.5 → 1.6 → 3 → 4 → 4.5 → 5 → 5.7 → 5.8 → 6 → 7.) Produce ONE output block at Step 6, then auto-trigger or stop per Step 7.
|
|
16
16
|
|
|
17
|
-
### Step 0: MCP Health
|
|
17
|
+
### Step 0: MCP Health Gate
|
|
18
18
|
|
|
19
|
-
Call MCP `health_check` tool.
|
|
19
|
+
Call MCP `health_check` tool. **The MCP connection is vital — this is a hard gate.**
|
|
20
20
|
|
|
21
|
-
- **If succeeds**: Continue silently
|
|
22
|
-
- **If fails**:
|
|
21
|
+
- **If succeeds**: Continue silently to Step 1.
|
|
22
|
+
- **If fails**: Print the error below and **STOP the entire session-start**. Do NOT continue to Step 1 or any later step — no config load, no `update_session_state(activate)`, no `create_session_log`, no `/cbp-todo` trigger:
|
|
23
23
|
|
|
24
24
|
```
|
|
25
|
-
|
|
25
|
+
✖ MCP connection failed — session-start aborted. Check:
|
|
26
26
|
1. Network connectivity
|
|
27
27
|
2. API key validity (CODEBYPLAN_API_KEY env var)
|
|
28
28
|
3. codebyplan.com availability
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
Fix the connection, then run /cbp-session-start again.
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
Continue to Step 1 (non-blocking).
|
|
34
|
-
|
|
35
33
|
### Step 1: Load Config
|
|
36
34
|
|
|
37
35
|
Read per-concern config files from the project root. Single load point for the session:
|
|
38
36
|
|
|
39
37
|
- `repo_id` (UUID) — from `.codebyplan/repo.json`, required for all MCP operations
|
|
40
|
-
- `server_port`, `server_type`, `auto_push_enabled` — from `.codebyplan/server.json`
|
|
41
38
|
- `git_branch` — from `.codebyplan/git.json`
|
|
42
39
|
|
|
43
40
|
Resolve `worktree_id` at runtime using the structured JSON form:
|
|
@@ -79,7 +76,7 @@ Never rebase, reset, force-push, or stash. A non-fast-forwardable home branch is
|
|
|
79
76
|
|
|
80
77
|
### Step 1.5: Infra Drift Check
|
|
81
78
|
|
|
82
|
-
Surface — never block — when this worktree's
|
|
79
|
+
Surface — never block — when this worktree's source-monorepo `.claude/` infra has fallen behind. Runs after Step 1.4 and may add one line to the Step 6 output (`$PRODUCTION` is the branch resolved in Step 1.4). Consumer-repo package-version freshness is handled by Step 1.6 (the freshness gate), not here:
|
|
83
80
|
|
|
84
81
|
- **Monorepo (concept A)** — both `packages/codebyplan-package/templates/` and `scripts/infra-drift.mjs` exist. Step 1.4 skips the fetch on a feat branch, so refresh `origin/$PRODUCTION` best-effort first, then run the reporter:
|
|
85
82
|
|
|
@@ -90,26 +87,46 @@ Surface — never block — when this worktree's CBP tooling has fallen behind.
|
|
|
90
87
|
|
|
91
88
|
The script self-guards (feat branch + behind > 0) and emits at most one `⚠ .claude/ infra is N behind — run /cbp-refresh-infra` line. Hold any output for Step 6.
|
|
92
89
|
|
|
93
|
-
- **
|
|
90
|
+
- **Neither** → skip silently.
|
|
94
91
|
|
|
95
|
-
|
|
96
|
-
LATEST="$(npm view codebyplan version 2>/dev/null)"
|
|
97
|
-
```
|
|
92
|
+
Fully non-blocking; every failure path falls through with no output.
|
|
98
93
|
|
|
99
|
-
|
|
94
|
+
### Step 1.6: Package Freshness Gate
|
|
100
95
|
|
|
101
|
-
-
|
|
96
|
+
Check whether a newer `codebyplan` is published and safe to auto-install on this worktree's current branch. Runs AFTER the infra-drift check (Step 1.5) and BEFORE session activation (Step 3).
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
VERSION_JSON=$(npx codebyplan version-status 2>/dev/null)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Parse `$VERSION_JSON` as JSON and branch on the result:
|
|
103
|
+
|
|
104
|
+
- **Probe failed / unparseable** — the command errored, produced no output, or the output cannot be parsed as JSON carrying the required keys (`newer`, `guarded`, `installCommand`). This includes an installed `codebyplan` too old to have the `version-status` subcommand (which prints `Unknown command`). → **FAIL-SAFE SKIP**: proceed silently to Step 3. Never disrupt a session over a best-effort freshness probe — the MCP gate (Step 0) is the only vital gate.
|
|
105
|
+
- **`guarded: true`** (protected/main branch OR the canonical `codebyplan` source monorepo — any `guardReason`) → skip silently, proceed to Step 3. Gate on the `guarded` boolean only; never branch on the specific `guardReason` string.
|
|
106
|
+
- **`newer: false`** (already up to date) → skip silently, proceed to Step 3.
|
|
107
|
+
- **`newer: true` AND `guarded: false`** → run the update path:
|
|
108
|
+
1. Run the JSON's `installCommand` (e.g. `pnpm add codebyplan@latest`) to LOCALLY install `codebyplan@latest` via the repo's package manager. Never a global `-g` install.
|
|
109
|
+
2. Run `npx codebyplan claude update` to refresh the worktree's `.claude/` assets on the current branch.
|
|
110
|
+
3. Detect changes across BOTH asset directories in one pass: `git status --porcelain -- .claude/ .codebyplan/`. If non-empty, offer the same commit gate as Step 5.7:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
codebyplan updated. Commit the resulting .claude/ and .codebyplan/ changes before exiting?
|
|
114
|
+
[list of changed paths under .claude/ and .codebyplan/]
|
|
115
|
+
|
|
116
|
+
Reply: yes | no | select
|
|
117
|
+
```
|
|
102
118
|
|
|
103
|
-
|
|
119
|
+
On `yes`: `git add` the listed paths only, then trigger `/cbp-git-commit`. On `no`: skip. On `select`: ask which subset.
|
|
120
|
+
4. **HALT** — do NOT proceed to Step 3. Print:
|
|
104
121
|
|
|
105
|
-
|
|
122
|
+
```
|
|
123
|
+
✓ codebyplan updated to {latest}. Start a FRESH Claude Code session
|
|
124
|
+
(run /clear or open a new window) so the updated .claude/ takes effect.
|
|
125
|
+
```
|
|
106
126
|
|
|
107
|
-
|
|
127
|
+
On this update-and-halt path the session is NOT continued: `update_session_state(activate)` is NOT called, `create_session_log` is NOT called, and `/cbp-todo` is NOT triggered.
|
|
108
128
|
|
|
109
|
-
|
|
110
|
-
2. Check if running: `lsof -ti:{PORT} 2>/dev/null`
|
|
111
|
-
3. If running, verify health: `curl -s -o /dev/null -w "%{http_code}" http://localhost:{PORT}/ --max-time 2`
|
|
112
|
-
4. If NOT running, note in output that user should start via desktop app
|
|
129
|
+
**Home branches are intentionally not guarded.** A worktree's folder-named home branch (e.g. `codebyplan-web`) is neither protected/main nor the canonical source, so `version-status` returns `guarded:false` there and this gate fires exactly as on a feat branch. That is deliberate — the update lands on whatever branch the worktree is currently resting on (the "update the branch they're on, except main/canonical" decision), not an accidental halt.
|
|
113
130
|
|
|
114
131
|
### Step 3: Update Session State
|
|
115
132
|
|
|
@@ -136,7 +153,7 @@ Hold the new log's ID in context so `/cbp-session-end` can update the same recor
|
|
|
136
153
|
|
|
137
154
|
### Step 4.5: Handoff Auto-Resume Probe
|
|
138
155
|
|
|
139
|
-
Probe the most-recent closed session log for a structured handoff payload (
|
|
156
|
+
Probe the most-recent closed session log for a structured handoff payload (the handoff freshness-gate contract is specified inline in this step) and auto-resume directly into the captured command when fresh. Additive — placed BEFORE the existing `/cbp-todo` auto-trigger; ALL failure paths fall through silently to Step 7.
|
|
140
157
|
|
|
141
158
|
1. Reuse the row held from Step 4 (same `get_session_logs({ repo_id, worktree_id, limit: 1 })` call shape — no extra MCP round-trip).
|
|
142
159
|
2. **Defensive gates** (any failure → silent fall-through to Step 7):
|
|
@@ -205,7 +222,6 @@ Ownership: [total_count] active CHK(s), [owned_count] owned by this worktree
|
|
|
205
222
|
[Owned: CHK-NNN (title), … — only when owned_count > 0]
|
|
206
223
|
[Cross-worktree: CHK-ZZZ (name), … — only when total_count > owned_count]
|
|
207
224
|
|
|
208
|
-
[⚠ Dev server not running — start via desktop app — only if applicable]
|
|
209
225
|
[⚠ Worktree unregistered — run `npx codebyplan setup` to register — only when WORKTREE_ID is null and no resolver distress was already shown]
|
|
210
226
|
```
|
|
211
227
|
|
|
@@ -223,9 +239,9 @@ Three-branch gate using `owned_count` and `total_count` from Step 5.8:
|
|
|
223
239
|
|
|
224
240
|
- **Triggered by**: user invocation, `/clear` recovery
|
|
225
241
|
- **Resolves**: `npx codebyplan resolve-worktree --json` (worktree id + distress signal; non-tuple-miss distress is non-blocking at session-start)
|
|
226
|
-
- **Reads**: `.codebyplan/repo.json`, `.codebyplan/git.json` (`branch_config.production` for the Step 1.4 home-branch fast-forward), MCP `get_session_logs` (worktree-filtered, limit 1 — single call shared by Step 4 and Step 4.5), MCP `health_check
|
|
227
|
-
- **Writes**: MCP `create_session_log` (new, possibly empty), MCP `update_session_state` (activate)
|
|
242
|
+
- **Reads**: `.codebyplan/repo.json`, `.codebyplan/git.json` (`branch_config.production` for the Step 1.4 home-branch fast-forward), MCP `get_session_logs` (worktree-filtered, limit 1 — single call shared by Step 4 and Step 4.5), MCP `health_check` (Step 0 hard gate), MCP `get_current_task`, MCP `get_rounds`, MCP `get_checkpoints` (two calls: `{ repo_id, status: 'active' }` for the Step 5.8 ownership partition; `{ repo_id }` unfiltered for the Step 4.5 freshness probe, which may resolve a non-active checkpoint), MCP `get_tasks` / `get_rounds` for the Step 4.5 freshness probe; `scripts/infra-drift.mjs` + a best-effort `git fetch` (Step 1.5 monorepo drift); `npx codebyplan version-status` (Step 1.6 package-freshness gate). Reads at Step 3 and later (session-state, session logs, checkpoints, tasks/rounds) do NOT fire on a Step 0 MCP hard-fail or the Step 1.6 update-and-halt path
|
|
243
|
+
- **Writes**: MCP `create_session_log` (new, possibly empty), MCP `update_session_state` (activate) — both SKIPPED on a Step 0 MCP hard-fail and on the Step 1.6 update-and-halt path
|
|
228
244
|
- **Spawns**: none
|
|
229
|
-
- **Triggers**: `/cbp-git-commit` (conditional, on user approval), `handoff.command` (on fresh handoff hit at Step 4.5), `/cbp-todo` (auto fall-through when owned_count >= 1 or total_count === 0; STOPS with no trigger when total_count >= 1 AND owned_count === 0)
|
|
245
|
+
- **Triggers**: `/cbp-git-commit` (conditional, on user approval at Step 5.7 or the Step 1.6 update path), `handoff.command` (on fresh handoff hit at Step 4.5), `/cbp-todo` (auto fall-through when owned_count >= 1 or total_count === 0; STOPS with no trigger when total_count >= 1 AND owned_count === 0; NOT triggered on a Step 0 hard-fail or the Step 1.6 update-and-halt path)
|
|
230
246
|
- **Paired with**: `/cbp-session-end`
|
|
231
|
-
- **Pairs with**:
|
|
247
|
+
- **Pairs with**: `/cbp-session-end` Step 1.3 (handoff write-path; the freshness-gate contract is specified inline in Step 4.5 above)
|