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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebyplan",
3
- "version": "1.13.8",
3
+ "version": "1.13.10",
4
4
  "description": "CLI for CodeByPlan — AI-powered development planning and tracking",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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[@]}" 2>&1; then
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 persisted in any of these files it is resolved at runtime via `npx codebyplan resolve-worktree` based on the device_id, filesystem path, and current git branch.
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, parses `git status --short`, merges drift + staging + web-UI flag, and writes both round and task.
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. Per `.claude/rules/session-resume.md` write-path contract.
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. If `infra_files` is empty skip. Otherwise present once:
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
- 5. On `yes`: `git add` the listed files, then trigger `/cbp-git-commit`.
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-update CLIs operate on the freshest tree.
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: Auto-Update CodeByPlan Assets
103
+ ### Step 1.7: Package Freshness Gate
103
104
 
104
- Run the latest published CLIs to pull any asset or config changes. Sub-block A runs first, then Sub-block B. A failure in A does **not** skip B each sub-block has its own retry-and-warn lane.
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
- **a) `codebyplan claude` (asset subcommand group)**
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
- Do **not** run `sync`, `setup`, or any other state-changing subcommand — this step updates the cached binary only.
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
- 1. Run `git status --porcelain -- .codebyplan/` to detect any file changes.
166
- 2. If non-empty, present once (same pattern as Step 1.5):
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
- .codebyplan/ was updated. Commit these changes?
170
- [list of changed paths under .codebyplan/]
121
+ ```
122
+ codebyplan updated. Commit these changes before ending the session?
123
+ [list of changed paths under .claude/ and .codebyplan/]
171
124
 
172
- Reply: yes | no | select
173
- ```
125
+ Reply: yes | no | select
126
+ ```
174
127
 
175
- On `yes`: `git add` the listed paths only, then trigger `/cbp-git-commit`.
176
- On `no`: skip. On `select`: ask which subset.
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
- 3. Print the command's stdout (the version line) as a one-line session summary (e.g. `codebyplan 1.4.2`). Silent when the command produces no stdout.
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. Steps 1.5 and 1.7 may invoke `/cbp-git-commit` inline on user approval.
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**: `.claude/rules/session-resume.md` (handoff payload shape + write-path contract)
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 → 2 → 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.
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 Check
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**: Show warning:
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
- MCP connection failed. Check:
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
- Session continues but MCP-dependent features will be unavailable.
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 CBP tooling has fallen behind. Runs after Step 1.4 and may add one line to the Step 6 output. Two mutually-exclusive concepts, keyed on repo type (`$PRODUCTION` is the branch resolved in Step 1.4):
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
- - **Consumer (concept B)** no `templates/`, but an install manifest exists (`.claude/.cbp.manifest.json`, falling back to `.cbp-claude.manifest.json` then `.codebyplan-claude.manifest.json`). Compare its `version` to the latest published `codebyplan`, offline-safe:
90
+ - **Neither** skip silently.
94
91
 
95
- ```bash
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
- When `$LATEST` is non-empty and newer than the manifest `version`, hold one line for Step 6: `⚠ codebyplan {installed} → {LATEST} — run npx codebyplan@latest claude update`. Any failure (offline, npm absent) → silent.
94
+ ### Step 1.6: Package Freshness Gate
100
95
 
101
- - **Neither** skip silently.
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
- Concept B never fires in the monorepo — the `templates/` guard routes the source repo to concept A only (its manifest `version` is intentionally stale). Fully non-blocking; every failure path falls through with no output.
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
- ### Step 2: Check Dev Server
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
- **Skip if `server_type` is `"none"`.**
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
- 1. Get `server_port` from `.codebyplan/server.json`
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 (per `.claude/rules/session-resume.md`) 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.
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`, 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) or the install manifest + `npm view codebyplan version` (Step 1.5 consumer drift)
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**: `.claude/rules/session-resume.md` (handoff payload shape + freshness gate contract)
247
+ - **Pairs with**: `/cbp-session-end` Step 1.3 (handoff write-path; the freshness-gate contract is specified inline in Step 4.5 above)