codebyplan 1.13.38 → 1.13.39
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 +557 -117
- package/package.json +1 -1
- package/templates/agents/cbp-map-architecture.md +90 -0
- package/templates/agents/cbp-round-executor.md +10 -0
- package/templates/agents/cbp-task-planner.md +5 -0
- package/templates/context/architecture/arch-map-spec.md +204 -0
- package/templates/context/architecture-map.md +117 -0
- package/templates/hooks/validate-structure.sh +3 -2
- package/templates/rules/architecture-map.md +30 -0
- package/templates/rules/context-file-loading.md +3 -0
- package/templates/rules/supabase-branch-lifecycle.md +1 -1
- package/templates/settings.project.base.json +5 -1
- package/templates/skills/cbp-checkpoint-end/SKILL.md +6 -3
- package/templates/skills/cbp-git-worktree-remove/SKILL.md +3 -2
- package/templates/skills/cbp-map-architecture/SKILL.md +170 -0
- package/templates/skills/cbp-refresh-arch-map/SKILL.md +191 -0
- package/templates/skills/cbp-session-start/SKILL.md +33 -2
- package/templates/skills/cbp-ship/reference/surface-supabase.md +3 -3
- package/templates/skills/cbp-ship-configure/SKILL.md +1 -1
- package/templates/skills/cbp-ship-configure/reference/railway-backend.md +2 -2
- package/templates/skills/cbp-ship-configure/reference/vercel.md +1 -1
- package/templates/skills/cbp-ship-main/SKILL.md +3 -2
- package/templates/skills/cbp-standalone-task-complete/SKILL.md +3 -2
- package/templates/skills/cbp-supabase-migrate/SKILL.md +2 -6
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
name: cbp-map-architecture
|
|
4
|
+
description: Orchestrate architecture map generation for one or all modules. Spawns the cbp-map-architecture agent per module, writes per-module .md files to .claude/architecture/, regenerates INDEX.md and graph.md, and stamps each module via the CLI. Idempotent — safe to re-run.
|
|
5
|
+
argument-hint: '[--module <path>] [--deep <path,...>]'
|
|
6
|
+
allowed-tools: Read, Write, Edit, Glob, Grep, Bash, Task
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Map Architecture
|
|
10
|
+
|
|
11
|
+
Generate or refresh the `.claude/architecture/` map for one or all repository modules.
|
|
12
|
+
Idempotent — re-running regenerates stale or missing maps without touching fresh ones.
|
|
13
|
+
|
|
14
|
+
Distinct from `/cbp-refresh-arch-map` (TASK-3: drift-scoped refresh that only re-runs
|
|
15
|
+
modules whose stamped SHA has since changed). This skill maps **all** target modules
|
|
16
|
+
unconditionally, or a specific subset when `--module` is given.
|
|
17
|
+
|
|
18
|
+
## Arguments
|
|
19
|
+
|
|
20
|
+
`$ARGUMENTS` accepts:
|
|
21
|
+
|
|
22
|
+
| Flag | Description |
|
|
23
|
+
|------|-------------|
|
|
24
|
+
| `--module <path>` | Map a single module (e.g. `apps/web`). Omit to map all discovered modules. |
|
|
25
|
+
| `--deep <path,...>` | Comma-separated list of modules to map at `deep` depth. All others default to `skeleton`. |
|
|
26
|
+
|
|
27
|
+
## Instructions
|
|
28
|
+
|
|
29
|
+
### Step A: Discover target modules
|
|
30
|
+
|
|
31
|
+
1. Run `codebyplan arch-map status` (Bash) to enumerate all discovered modules and their
|
|
32
|
+
current map presence + freshness. Capture the output.
|
|
33
|
+
2. If `--module <path>` was given, restrict the target list to that one module.
|
|
34
|
+
3. Parse `--deep <path,...>` into a set of paths that should be mapped at `deep` depth.
|
|
35
|
+
All other targets default to `skeleton`.
|
|
36
|
+
|
|
37
|
+
Output:
|
|
38
|
+
```yaml
|
|
39
|
+
targets:
|
|
40
|
+
- path: string # module path relative to repo root
|
|
41
|
+
depth: skeleton|deep
|
|
42
|
+
has_map: boolean # from arch-map status output
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Step B: Spawn the cbp-map-architecture agent per module
|
|
46
|
+
|
|
47
|
+
For each module in `targets[]`:
|
|
48
|
+
|
|
49
|
+
1. Derive the map-file slug from the module path:
|
|
50
|
+
- Replace `/` with `-`
|
|
51
|
+
- Normalize a leading `.` to `dot-` (e.g. `.github` → `dot-github.md`)
|
|
52
|
+
- Example: `apps/web` → `apps-web.md`
|
|
53
|
+
|
|
54
|
+
2. Spawn the `cbp-map-architecture` agent (via Task tool) with input:
|
|
55
|
+
```yaml
|
|
56
|
+
module_path: <path>
|
|
57
|
+
depth: skeleton|deep
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
3. Receive the agent's returned map content (a full `.claude/architecture/<slug>.md`
|
|
61
|
+
text block, starting with `---` YAML frontmatter).
|
|
62
|
+
|
|
63
|
+
4. Write the content to `.claude/architecture/<slug>.md` using the Write tool.
|
|
64
|
+
Create the `.claude/architecture/` directory if it does not yet exist.
|
|
65
|
+
|
|
66
|
+
Modules may be spawned concurrently (parallel Task calls) when there are multiple targets
|
|
67
|
+
with no inter-module dependency. The agent is read-only and safe to parallelize.
|
|
68
|
+
|
|
69
|
+
### Step C: Regenerate INDEX.md and graph.md
|
|
70
|
+
|
|
71
|
+
After all per-module map files are written:
|
|
72
|
+
|
|
73
|
+
**INDEX.md** — regenerate `.claude/architecture/INDEX.md` from scratch:
|
|
74
|
+
|
|
75
|
+
1. Read all `.claude/architecture/*.md` files (excluding INDEX.md and graph.md).
|
|
76
|
+
2. For each file, parse the YAML frontmatter fields: `module`, `depth`,
|
|
77
|
+
`generated_from_sha`, `generated_at`.
|
|
78
|
+
3. Derive the short SHA: first 8 chars of `generated_from_sha`, or `unset` if null.
|
|
79
|
+
4. Derive the date: `YYYY-MM-DD` portion of `generated_at`, or `unset` if null.
|
|
80
|
+
5. Write INDEX.md following the canonical format from `context/architecture/arch-map-spec.md`:
|
|
81
|
+
|
|
82
|
+
```markdown
|
|
83
|
+
# Architecture Map Index
|
|
84
|
+
|
|
85
|
+
Grep-friendly registry of per-module architecture maps. Layout convention in `context/architecture/arch-map-spec.md`.
|
|
86
|
+
|
|
87
|
+
| Module | Depth | SHA | Generated | Map File |
|
|
88
|
+
|--------|-------|-----|-----------|----------|
|
|
89
|
+
| <module> | <depth> | <sha_short> | <date> | <map_file> |
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**graph.md** — regenerate `.claude/architecture/graph.md` from scratch:
|
|
93
|
+
|
|
94
|
+
1. For each map file, read the `## 4. Dependencies (In / Out)` section.
|
|
95
|
+
2. Extract "Consumes" entries — each named module becomes an edge: `<module> -> <dependency>`.
|
|
96
|
+
3. Collect all edges into a Set keyed on the exact `"<from> -> <to>"` string, then write each unique edge once. graph.md lists each directed edge exactly once — duplicate declarations across multiple maps are deduplicated at write time.
|
|
97
|
+
4. Write graph.md following the canonical format from `context/architecture/arch-map-spec.md`:
|
|
98
|
+
|
|
99
|
+
```markdown
|
|
100
|
+
# Architecture Dependency Graph
|
|
101
|
+
|
|
102
|
+
Adjacency list of cross-module edges. Each entry: `<from> -> <to>`.
|
|
103
|
+
Generated from the `Dependencies (In / Out)` sections of individual map files
|
|
104
|
+
(first-party `@codebyplan/*` workspace imports, verified against each module's `package.json`).
|
|
105
|
+
|
|
106
|
+
Scope: edges are TypeScript workspace package imports only. Runtime/service dependencies
|
|
107
|
+
(shared schema directories, HTTP calls between apps) are documented per-map in
|
|
108
|
+
`## 4. Dependencies (In / Out)` and are intentionally NOT graphed here — a module with
|
|
109
|
+
no edge is not necessarily isolated; consult its map file for runtime coupling.
|
|
110
|
+
|
|
111
|
+
## Edges
|
|
112
|
+
|
|
113
|
+
<module-A> -> <module-B>
|
|
114
|
+
<module-A> -> <module-C>
|
|
115
|
+
<module-B> -> <module-D>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
If no dependency edges are found, write the header only (empty Edges section is valid).
|
|
119
|
+
|
|
120
|
+
### Step D: Stamp each freshly written module
|
|
121
|
+
|
|
122
|
+
For each module written in Step B, run:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
codebyplan arch-map stamp <module-path>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
This updates `.codebyplan/architecture.json` with the current git SHA and timestamp,
|
|
129
|
+
and mirrors those values into the map file's YAML frontmatter.
|
|
130
|
+
|
|
131
|
+
If `--depth` should be recorded explicitly (e.g. `deep`), pass `--depth <deep|skeleton>`:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
codebyplan arch-map stamp <module-path> --depth <depth>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Step E: Report
|
|
138
|
+
|
|
139
|
+
Print a summary:
|
|
140
|
+
- Modules mapped (count + list)
|
|
141
|
+
- INDEX.md row count
|
|
142
|
+
- graph.md edge count
|
|
143
|
+
- Any modules that were skipped or blocked (with reason)
|
|
144
|
+
|
|
145
|
+
## Idempotency Notes
|
|
146
|
+
|
|
147
|
+
- Re-running this skill over an already-mapped module regenerates the map from scratch.
|
|
148
|
+
There is no "skip if fresh" logic here — use `/cbp-refresh-arch-map` (TASK-3) when
|
|
149
|
+
you want drift-scoped re-runs that skip fresh modules.
|
|
150
|
+
- `codebyplan arch-map stamp` is idempotent — stamping the same SHA twice is a no-op in
|
|
151
|
+
practice (the values overwrite with the same content).
|
|
152
|
+
|
|
153
|
+
## Failure Modes
|
|
154
|
+
|
|
155
|
+
| Condition | Action |
|
|
156
|
+
|-----------|--------|
|
|
157
|
+
| `cbp-map-architecture` agent returns `blocked` for a module | Write a warning to INDEX.md row; continue with remaining modules |
|
|
158
|
+
| `.claude/architecture/` directory creation fails | Surface as blocked — check file-system permissions |
|
|
159
|
+
| `codebyplan arch-map status` not available | Surface as blocked — run `npx codebyplan arch-map status` to verify CLI is installed |
|
|
160
|
+
|
|
161
|
+
## Integration
|
|
162
|
+
|
|
163
|
+
- **Triggered by**: user invocation (`/cbp-map-architecture [args]`)
|
|
164
|
+
- **Spawns**: `cbp-map-architecture` agent (one per module)
|
|
165
|
+
- **Calls**: `codebyplan arch-map status`, `codebyplan arch-map stamp`
|
|
166
|
+
- **Writes**: `.claude/architecture/<slug>.md`, `.claude/architecture/INDEX.md`, `.claude/architecture/graph.md`
|
|
167
|
+
- **Updates**: `.codebyplan/architecture.json` (via stamp CLI)
|
|
168
|
+
- **Consultation contract**: `.claude/context/architecture-map.md`
|
|
169
|
+
- **Artifact spec**: `.claude/context/architecture/arch-map-spec.md`
|
|
170
|
+
- **Related skill**: `/cbp-refresh-arch-map` — drift-scoped refresh (TASK-3)
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
name: cbp-refresh-arch-map
|
|
4
|
+
description: Drift-scoped refresh of the .claude/architecture/ map — re-runs the cbp-map-architecture agent for ONLY the modules whose stamped git SHA has changed, regenerates INDEX.md + graph.md, and re-stamps. Idempotent; no-op when no module has drifted.
|
|
5
|
+
argument-hint: '[--module <path>]'
|
|
6
|
+
allowed-tools: Read, Write, Edit, Glob, Grep, Bash, Task
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Refresh Architecture Map (drift-scoped)
|
|
10
|
+
|
|
11
|
+
Re-generate ONLY the architecture maps that have gone stale. A module is **stale**
|
|
12
|
+
when its source has been committed past the git SHA recorded in
|
|
13
|
+
`.codebyplan/architecture.json` — exactly what `codebyplan arch-map drift` reports.
|
|
14
|
+
|
|
15
|
+
Distinct from `/cbp-map-architecture` (which maps **all** target modules
|
|
16
|
+
unconditionally, or a named subset). This skill is the cheap incremental path: it
|
|
17
|
+
touches nothing that is already fresh, preserving each stale module's existing
|
|
18
|
+
depth (`skeleton` / `deep`) from the manifest.
|
|
19
|
+
|
|
20
|
+
This is the freshness loop the session-start drift nudge points at — when a session
|
|
21
|
+
starts and N modules are stale, you run this to bring the maps current in one pass.
|
|
22
|
+
|
|
23
|
+
## Arguments
|
|
24
|
+
|
|
25
|
+
`$ARGUMENTS` accepts:
|
|
26
|
+
|
|
27
|
+
| Flag | Description |
|
|
28
|
+
|------|-------------|
|
|
29
|
+
| `--module <path>` | Refresh a single module even if drift does not flag it (force re-run). When omitted, the drifted set from `codebyplan arch-map drift` is the target list. |
|
|
30
|
+
|
|
31
|
+
## Instructions
|
|
32
|
+
|
|
33
|
+
### Step A: Compute the stale set
|
|
34
|
+
|
|
35
|
+
1. Run `codebyplan arch-map drift` (Bash) and capture the output. Each drifted module
|
|
36
|
+
is printed on a `DRIFTED <path>` line (the CLI is hook-safe — it exits 0 and prints
|
|
37
|
+
`All stamped modules are fresh.` when nothing has drifted).
|
|
38
|
+
2. Read `.codebyplan/architecture.json` (Read) to recover each module's stored `depth`
|
|
39
|
+
and `map_file`. The manifest is the source of truth for depth — a drift refresh MUST
|
|
40
|
+
preserve the depth the module was originally mapped at, never silently downgrade a
|
|
41
|
+
`deep` map to `skeleton`.
|
|
42
|
+
3. Build the target list:
|
|
43
|
+
- Default: every `DRIFTED <path>` module from Step A.1.
|
|
44
|
+
- `--module <path>` given: just that one module (look up its depth in the manifest;
|
|
45
|
+
default `skeleton` if it has no manifest entry yet).
|
|
46
|
+
|
|
47
|
+
```yaml
|
|
48
|
+
targets:
|
|
49
|
+
- path: string # module path relative to repo root
|
|
50
|
+
depth: skeleton|deep # preserved from architecture.json
|
|
51
|
+
map_file: string # .claude/architecture/<slug>.md from the manifest
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Step B: No-op short-circuit
|
|
55
|
+
|
|
56
|
+
If the target list is empty (drift reported `All stamped modules are fresh.` and no
|
|
57
|
+
`--module` override was given), print and STOP:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
✓ All architecture maps are fresh — nothing to refresh.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Do NOT spawn agents, regenerate INDEX/graph, or re-stamp. An empty drift set is a
|
|
64
|
+
legitimate success state, not an error.
|
|
65
|
+
|
|
66
|
+
### Step C: Re-run the agent for each stale module
|
|
67
|
+
|
|
68
|
+
For each module in `targets[]`:
|
|
69
|
+
|
|
70
|
+
1. Spawn the `cbp-map-architecture` agent (via Task tool) with input:
|
|
71
|
+
```yaml
|
|
72
|
+
module_path: <path>
|
|
73
|
+
depth: <preserved depth from the manifest>
|
|
74
|
+
```
|
|
75
|
+
2. Receive the agent's returned map content (a full `.claude/architecture/<slug>.md`
|
|
76
|
+
text block, opening with `---` YAML frontmatter).
|
|
77
|
+
3. Write the content to the module's `map_file` path using the Write tool (overwrites
|
|
78
|
+
the stale map). The agent returns `generated_from_sha: null` / `generated_at: null`
|
|
79
|
+
in the frontmatter — Step E's `stamp` fills those in.
|
|
80
|
+
|
|
81
|
+
Stale modules are independent and read-only to analyze, so spawn them concurrently
|
|
82
|
+
(parallel Task calls) when there is more than one.
|
|
83
|
+
|
|
84
|
+
If the agent returns `blocked` for a module (e.g. the module path no longer exists),
|
|
85
|
+
skip it, record the reason for Step F, and continue with the rest.
|
|
86
|
+
|
|
87
|
+
### Step D: Regenerate INDEX.md and graph.md (wholesale)
|
|
88
|
+
|
|
89
|
+
INDEX.md and graph.md are derived from the FULL set of map files, so regenerate both
|
|
90
|
+
from scratch after the stale maps are rewritten — unaffected rows/edges are reproduced
|
|
91
|
+
unchanged because their source map files did not move.
|
|
92
|
+
|
|
93
|
+
**INDEX.md** — rebuild `.claude/architecture/INDEX.md`:
|
|
94
|
+
|
|
95
|
+
1. Read all `.claude/architecture/*.md` files (excluding INDEX.md and graph.md).
|
|
96
|
+
2. Parse each file's frontmatter: `module`, `depth`, `generated_from_sha`, `generated_at`.
|
|
97
|
+
Note: freshly-rewritten maps still carry `null` SHA/date here — that is corrected by
|
|
98
|
+
Step E (stamp), so regenerate INDEX.md AFTER stamping, or re-read post-stamp.
|
|
99
|
+
3. Short SHA = first 8 chars of `generated_from_sha`, or `unset` if null. Date =
|
|
100
|
+
`YYYY-MM-DD` of `generated_at`, or `unset` if null.
|
|
101
|
+
4. Write the canonical header + one row per module (format in
|
|
102
|
+
`context/architecture/arch-map-spec.md`):
|
|
103
|
+
|
|
104
|
+
```markdown
|
|
105
|
+
# Architecture Map Index
|
|
106
|
+
|
|
107
|
+
Grep-friendly registry of per-module architecture maps. Layout convention in `context/architecture/arch-map-spec.md`.
|
|
108
|
+
|
|
109
|
+
| Module | Depth | SHA | Generated | Map File |
|
|
110
|
+
|--------|-------|-----|-----------|----------|
|
|
111
|
+
| <module> | <depth> | <sha_short> | <date> | <map_file> |
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**graph.md** — rebuild `.claude/architecture/graph.md`:
|
|
115
|
+
|
|
116
|
+
1. For each map file, read its `## 4. Dependencies (In / Out)` section.
|
|
117
|
+
2. Each "Consumes" entry becomes a directed edge `<from> -> <to>`.
|
|
118
|
+
3. Deduplicate edges by the exact `"<from> -> <to>"` string — each unique edge once.
|
|
119
|
+
4. Write the canonical format (header only is valid when there are no edges):
|
|
120
|
+
|
|
121
|
+
```markdown
|
|
122
|
+
# Architecture Dependency Graph
|
|
123
|
+
|
|
124
|
+
Adjacency list of cross-module edges. Each entry: `<from> -> <to>`.
|
|
125
|
+
Generated from the `Dependencies (In / Out)` sections of individual map files
|
|
126
|
+
(first-party `@codebyplan/*` workspace imports, verified against each module's `package.json`).
|
|
127
|
+
|
|
128
|
+
Scope: edges are TypeScript workspace package imports only. Runtime/service dependencies
|
|
129
|
+
(shared schema directories, HTTP calls between apps) are documented per-map in
|
|
130
|
+
`## 4. Dependencies (In / Out)` and are intentionally NOT graphed here — a module with
|
|
131
|
+
no edge is not necessarily isolated; consult its map file for runtime coupling.
|
|
132
|
+
|
|
133
|
+
## Edges
|
|
134
|
+
|
|
135
|
+
<module-A> -> <module-B>
|
|
136
|
+
<module-A> -> <module-C>
|
|
137
|
+
<module-B> -> <module-D>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Step E: Re-stamp each refreshed module
|
|
141
|
+
|
|
142
|
+
For each successfully rewritten module, run:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
codebyplan arch-map stamp <module-path> --depth <preserved-depth>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
This records the current git SHA + timestamp in `.codebyplan/architecture.json` and
|
|
149
|
+
mirrors them into the map file's frontmatter, clearing the drift. Pass `--depth` so a
|
|
150
|
+
`deep` map is never re-recorded as `skeleton`.
|
|
151
|
+
|
|
152
|
+
After stamping, regenerate INDEX.md once more (or re-read the now-stamped frontmatter)
|
|
153
|
+
so its SHA/date columns reflect the fresh stamps rather than the transient `null` state.
|
|
154
|
+
|
|
155
|
+
### Step F: Report
|
|
156
|
+
|
|
157
|
+
Print a summary:
|
|
158
|
+
- Modules refreshed (count + list, with depth)
|
|
159
|
+
- Modules skipped/blocked (with reason), if any
|
|
160
|
+
- INDEX.md row count, graph.md edge count
|
|
161
|
+
- A final `codebyplan arch-map drift` run confirming zero remaining drift
|
|
162
|
+
|
|
163
|
+
## Idempotency Notes
|
|
164
|
+
|
|
165
|
+
- Running this skill twice in a row is safe: the second run finds zero drift and
|
|
166
|
+
short-circuits at Step B.
|
|
167
|
+
- `codebyplan arch-map stamp` is idempotent — re-stamping the same SHA overwrites with
|
|
168
|
+
identical values.
|
|
169
|
+
- This skill never touches fresh modules — that is the entire point of the drift gate.
|
|
170
|
+
Use `/cbp-map-architecture` when you want to regenerate everything regardless of drift.
|
|
171
|
+
|
|
172
|
+
## Failure Modes
|
|
173
|
+
|
|
174
|
+
| Condition | Action |
|
|
175
|
+
|-----------|--------|
|
|
176
|
+
| `codebyplan arch-map drift` reports `No stamped modules found` | No maps exist yet — direct the user to `/cbp-map-architecture` to generate the initial maps, then STOP |
|
|
177
|
+
| `cbp-map-architecture` agent returns `blocked` for a module | Skip it, record the reason in the Step F report, continue with the rest |
|
|
178
|
+
| `.codebyplan/architecture.json` missing or unparseable | Surface as blocked — the manifest is required to recover per-module depth; run `/cbp-map-architecture` first |
|
|
179
|
+
| `codebyplan arch-map` CLI not available | Surface as blocked — run `npx codebyplan arch-map status` to verify the CLI is installed |
|
|
180
|
+
|
|
181
|
+
## Integration
|
|
182
|
+
|
|
183
|
+
- **Triggered by**: user invocation (`/cbp-refresh-arch-map [--module <path>]`); nudged by the `/cbp-session-start` Step 1.55 architecture-map drift line
|
|
184
|
+
- **Spawns**: `cbp-map-architecture` agent (one per stale module)
|
|
185
|
+
- **Calls**: `codebyplan arch-map drift`, `codebyplan arch-map stamp`
|
|
186
|
+
- **Reads**: `.codebyplan/architecture.json` (per-module depth + map_file)
|
|
187
|
+
- **Writes**: `.claude/architecture/<slug>.md` (stale modules only), `.claude/architecture/INDEX.md`, `.claude/architecture/graph.md`
|
|
188
|
+
- **Updates**: `.codebyplan/architecture.json` (via stamp CLI)
|
|
189
|
+
- **Consultation contract**: `.claude/context/architecture-map.md`
|
|
190
|
+
- **Artifact spec**: `.claude/context/architecture/arch-map-spec.md`
|
|
191
|
+
- **Related skill**: `/cbp-map-architecture` — full (non-drift) generation
|
|
@@ -12,7 +12,7 @@ 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 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 1.7 may surface a one-line LSP binary nudge, 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 → 1.7 → 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.55 may surface a one-line architecture-map drift nudge, Step 1.6 may run an install-and-halt path, Step 1.7 may surface a one-line LSP binary nudge, 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.55 → 1.6 → 1.7 → 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
17
|
### Step 0: MCP Health Gate
|
|
18
18
|
|
|
@@ -91,6 +91,34 @@ Surface — never block — when this worktree's source-monorepo `.claude/` infr
|
|
|
91
91
|
|
|
92
92
|
Fully non-blocking; every failure path falls through with no output.
|
|
93
93
|
|
|
94
|
+
### Step 1.55: Architecture-Map Drift Check
|
|
95
|
+
|
|
96
|
+
Surface — never block — when this repo's generated `.claude/architecture/` maps have
|
|
97
|
+
gone stale (a mapped module's source was committed past the SHA stamped in
|
|
98
|
+
`.codebyplan/architecture.json`). Runs after the infra-drift check (Step 1.5) and may add
|
|
99
|
+
one line to the Step 6 output. This is the freshness nudge for the architecture-map
|
|
100
|
+
pipeline (mirrors the infra-drift pattern; the analog for first-party code maps):
|
|
101
|
+
|
|
102
|
+
- **No manifest** — `.codebyplan/architecture.json` absent → skip silently (the repo has
|
|
103
|
+
no maps yet; nothing to drift-check).
|
|
104
|
+
- **Manifest present** — run the drift probe best-effort and count drifted modules:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npx codebyplan arch-map drift 2>/dev/null | grep -c '^[[:space:]]*DRIFTED' || true
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
If the count is `> 0`, hold this single line for Step 6:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
⚠ .claude/architecture is N module(s) stale — run /cbp-refresh-arch-map
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
A count of `0` (all maps fresh, no stamped modules, or any probe failure) emits nothing.
|
|
117
|
+
|
|
118
|
+
Fully non-blocking; every failure path falls through with no output. The `arch-map` CLI is
|
|
119
|
+
itself hook-safe (exits 0 on any internal error), so a missing or too-old `codebyplan`
|
|
120
|
+
binary simply yields a zero count and no line.
|
|
121
|
+
|
|
94
122
|
### Step 1.6: Package Freshness Gate
|
|
95
123
|
|
|
96
124
|
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).
|
|
@@ -227,6 +255,9 @@ Session active | Worktree: [worktree_id or "unregistered"]
|
|
|
227
255
|
|
|
228
256
|
[⚠ resolve-worktree: <error_kind> — local state is broken; routing may be unreliable. Run `npx codebyplan setup` to repair. — only when error_kind is non-null and not tuple_miss]
|
|
229
257
|
|
|
258
|
+
[⚠ .claude/ infra is N behind — run /cbp-refresh-infra — only when Step 1.5 found drift]
|
|
259
|
+
[⚠ .claude/architecture is N module(s) stale — run /cbp-refresh-arch-map — only when Step 1.55 found drift]
|
|
260
|
+
|
|
230
261
|
Previous session: [title or "none"]
|
|
231
262
|
Pending: [pending items from previous log, or "—"]
|
|
232
263
|
|
|
@@ -253,7 +284,7 @@ Three-branch gate using `owned_count` and `total_count` from Step 5.8:
|
|
|
253
284
|
|
|
254
285
|
- **Triggered by**: user invocation, `/clear` recovery
|
|
255
286
|
- **Resolves**: `npx codebyplan resolve-worktree --json` (worktree id + distress signal; non-tuple-miss distress is non-blocking at session-start)
|
|
256
|
-
- **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); `npx codebyplan lsp --check` (Step 1.7 LSP binary nudge — reads `.codebyplan/lsp.json`, non-blocking). 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
|
|
287
|
+
- **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 arch-map drift` + `.codebyplan/architecture.json` presence (Step 1.55 architecture-map drift nudge, non-blocking); `npx codebyplan version-status` (Step 1.6 package-freshness gate); `npx codebyplan lsp --check` (Step 1.7 LSP binary nudge — reads `.codebyplan/lsp.json`, non-blocking). 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
|
|
257
288
|
- **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
|
|
258
289
|
- **Spawns**: none
|
|
259
290
|
- **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)
|
|
@@ -35,8 +35,8 @@ This is **always interactive**. The orchestrator does NOT silently apply migrati
|
|
|
35
35
|
|
|
36
36
|
1. **List pending migrations**:
|
|
37
37
|
```bash
|
|
38
|
-
PROJECT_REF=$(jq -r '.surfaces.supabase.project_ref' .codebyplan/shipment.json)
|
|
39
|
-
LAST_VERSION=$(jq -r '.surfaces.supabase.last_shipped_migration_version // ""' .codebyplan/shipment.json)
|
|
38
|
+
PROJECT_REF=$(jq -r '.shipment.surfaces.supabase.project_ref' .codebyplan/shipment.json)
|
|
39
|
+
LAST_VERSION=$(jq -r '.shipment.surfaces.supabase.last_shipped_migration_version // ""' .codebyplan/shipment.json)
|
|
40
40
|
|
|
41
41
|
PENDING=$(ls supabase/migrations/*.sql | sort)
|
|
42
42
|
if [ -n "$LAST_VERSION" ]; then
|
|
@@ -116,7 +116,7 @@ This is **always interactive**. The orchestrator does NOT silently apply migrati
|
|
|
116
116
|
7. **Update the last-shipped marker**:
|
|
117
117
|
```bash
|
|
118
118
|
LAST_APPLIED=$(echo "$PENDING" | tail -1 | xargs basename)
|
|
119
|
-
jq --arg v "$LAST_APPLIED" '.surfaces.supabase.last_shipped_migration_version = $v' .codebyplan/shipment.json > .codebyplan/shipment.json.tmp
|
|
119
|
+
jq --arg v "$LAST_APPLIED" '.shipment.surfaces.supabase.last_shipped_migration_version = $v' .codebyplan/shipment.json > .codebyplan/shipment.json.tmp
|
|
120
120
|
mv .codebyplan/shipment.json.tmp .codebyplan/shipment.json
|
|
121
121
|
```
|
|
122
122
|
|
|
@@ -126,7 +126,7 @@ The skill's job is to verify these credentials EXIST and are valid; never to sto
|
|
|
126
126
|
Run the verification step from the surface reference. For Vercel, this is:
|
|
127
127
|
|
|
128
128
|
```bash
|
|
129
|
-
vercel inspect "$(jq -r '.surfaces."vercel-web".project_id' .codebyplan/shipment.json)" 2>&1 | head -20
|
|
129
|
+
vercel inspect "$(jq -r '.shipment.surfaces."vercel-web".project_id' .codebyplan/shipment.json)" 2>&1 | head -20
|
|
130
130
|
```
|
|
131
131
|
|
|
132
132
|
If verification passes, mark the surface as configured. If it fails, surface the error and offer to retry the failing step.
|
|
@@ -161,7 +161,7 @@ railway domain
|
|
|
161
161
|
Verify:
|
|
162
162
|
|
|
163
163
|
```bash
|
|
164
|
-
PROJECT_ID=$(jq -r '.surfaces."railway-backend".project_id' .codebyplan/shipment.json)
|
|
164
|
+
PROJECT_ID=$(jq -r '.shipment.surfaces."railway-backend".project_id' .codebyplan/shipment.json)
|
|
165
165
|
railway status --json | jq
|
|
166
166
|
# Expect: project + service info matching saved IDs
|
|
167
167
|
```
|
|
@@ -171,7 +171,7 @@ Test deploy:
|
|
|
171
171
|
```bash
|
|
172
172
|
railway up --detach
|
|
173
173
|
# Wait, then verify URL responds
|
|
174
|
-
URL=$(jq -r '.surfaces."railway-backend".url' .codebyplan/shipment.json)
|
|
174
|
+
URL=$(jq -r '.shipment.surfaces."railway-backend".url' .codebyplan/shipment.json)
|
|
175
175
|
curl -sI "$URL/health" | head -1
|
|
176
176
|
```
|
|
177
177
|
|
|
@@ -98,7 +98,7 @@ Write `.codebyplan/shipment.json`:
|
|
|
98
98
|
Verify:
|
|
99
99
|
|
|
100
100
|
```bash
|
|
101
|
-
PROJECT_ID=$(jq -r '.surfaces."vercel-web".project_id' .codebyplan/shipment.json)
|
|
101
|
+
PROJECT_ID=$(jq -r '.shipment.surfaces."vercel-web".project_id' .codebyplan/shipment.json)
|
|
102
102
|
vercel inspect "$PROJECT_ID" --json | jq -r '.name, .latestDeployments[0].readyState'
|
|
103
103
|
```
|
|
104
104
|
|
|
@@ -80,12 +80,13 @@ If `branch_deleted === true`, run a conditional Supabase preview-branch teardown
|
|
|
80
80
|
> Lifecycle contract: see [[supabase-branch-lifecycle]].
|
|
81
81
|
|
|
82
82
|
- Read `FEAT_BRANCH` from the `feat_branch` field in the Step 3 JSON output — NOT from `git branch --show-current`. By the time Step 4 runs, `codebyplan ship` has already checked out the base branch (unless `--keep-feat` was passed), so the live branch is the base, not the feat branch.
|
|
83
|
-
-
|
|
83
|
+
- Resolve the parent project ref: read `.codebyplan/shipment.json` `.shipment.surfaces.supabase.project_ref`; if absent or empty, read the first line of `supabase/.temp/project-ref`. Use that resolved ref as the `project_id`.
|
|
84
|
+
- Call `mcp__supabase__list_branches` with the resolved `project_id`.
|
|
84
85
|
- Scan the returned list for an entry whose `name` exactly equals `$FEAT_BRANCH`.
|
|
85
86
|
- If found: call `mcp__supabase__delete_branch` with its `branch_id`. Report the Supabase delete outcome alongside `pr_url` / `merge_commit` / `branch_deleted`.
|
|
86
87
|
- If not found: no-op silently — the GitHub integration may have already removed the preview branch on PR close; not-found is success, NOT an error.
|
|
87
88
|
- If the `list_branches` call itself fails (network, auth, or a non-success response — distinct from a successful lookup that returns no match): emit a non-blocking warning that the Supabase preview branch for `$FEAT_BRANCH` may still exist and should be verified in the dashboard. Do not treat an API failure as a not-found success.
|
|
88
|
-
- Never delete the
|
|
89
|
+
- Never delete the branch where `is_default` is true in the `list_branches` response (the production/parent project branch) or any other persistent/long-lived branch.
|
|
89
90
|
- This coordinates safely with `/cbp-checkpoint-end` — the existence-checked delete makes any second attempt a harmless no-op.
|
|
90
91
|
|
|
91
92
|
## Key Rules
|
|
@@ -169,12 +169,13 @@ Parse the JSON output and store: `pr_url`, `merge_commit`, `branch_deleted`, `fe
|
|
|
169
169
|
When `branch_deleted === true` in the ship JSON:
|
|
170
170
|
|
|
171
171
|
- Read `FEAT_BRANCH` from the `feat_branch` field in the ship JSON — NOT from `git branch --show-current`. By the time Step 7.3 runs, `codebyplan ship` has already checked out the base branch, so the live branch is the base, not the feat branch.
|
|
172
|
-
-
|
|
172
|
+
- Resolve the parent project ref: read `.codebyplan/shipment.json` `.shipment.surfaces.supabase.project_ref`; if absent or empty, read the first line of `supabase/.temp/project-ref`. Use that resolved ref as the `project_id`.
|
|
173
|
+
- Call `mcp__supabase__list_branches` with the resolved `project_id`.
|
|
173
174
|
- Scan the returned list for an entry whose `name` exactly equals `FEAT_BRANCH`.
|
|
174
175
|
- If found: call `mcp__supabase__delete_branch` with its `branch_id`. Report the outcome.
|
|
175
176
|
- If not found: no-op silently — the GitHub integration may have already removed the preview branch on PR close; not-found is success, NOT an error.
|
|
176
177
|
- If the `list_branches` call itself fails (network, auth, or non-success response): emit a non-blocking warning that the Supabase preview branch for `FEAT_BRANCH` may still exist and should be verified in the dashboard. Never treat an API failure as a not-found success.
|
|
177
|
-
- Never delete the
|
|
178
|
+
- Never delete the branch where `is_default` is true in the `list_branches` response (the production/parent project branch) or any other persistent/long-lived branch.
|
|
178
179
|
|
|
179
180
|
### Step 7.5: Complete Standalone Task
|
|
180
181
|
|
|
@@ -125,11 +125,7 @@ already provisioned the branch. Capture it as `PREVIEW_PROJECT_REF` and jump str
|
|
|
125
125
|
|
|
126
126
|
### Idempotency check (list before create)
|
|
127
127
|
|
|
128
|
-
Call `mcp__supabase__list_branches` with the
|
|
129
|
-
parent `project_id` for MCP calls is the same ref string stored in `.codebyplan/shipment.json`
|
|
130
|
-
`surfaces.supabase.project_ref` — Supabase uses that one ref as both the project identifier
|
|
131
|
-
and the branch target. Scan the returned list for an entry whose `name` exactly equals
|
|
132
|
-
`$BRANCH` (slashes included — `feat/CHK-144-...` is a valid Supabase branch name).
|
|
128
|
+
Resolve the parent project ref: read `.codebyplan/shipment.json` `.shipment.surfaces.supabase.project_ref`; if absent or empty, read the first line of `supabase/.temp/project-ref`. Use that resolved ref as the `project_id` for all MCP calls in this step. The parent `project_id` is the same ref that Supabase uses as both the project identifier and the branch target. Call `mcp__supabase__list_branches` with the resolved `project_id`. Scan the returned list for an entry whose `name` exactly equals `$BRANCH` (slashes included — `feat/CHK-144-...` is a valid Supabase branch name).
|
|
133
129
|
|
|
134
130
|
- **Match found**: capture its `project_ref` as `PREVIEW_PROJECT_REF`. Skip creation; proceed
|
|
135
131
|
to "Record connection". This is the idempotent reuse path (covers a branch the GitHub
|
|
@@ -148,7 +144,7 @@ Cost confirmation is mandatory before creating a branch — never bypass it:
|
|
|
148
144
|
stays empty.
|
|
149
145
|
|
|
150
146
|
After cost is confirmed, call `mcp__supabase__create_branch`:
|
|
151
|
-
- `project_id`:
|
|
147
|
+
- `project_id`: the resolved parent project ref (`.codebyplan/shipment.json` `.shipment.surfaces.supabase.project_ref`, falling back to the first line of `supabase/.temp/project-ref`)
|
|
152
148
|
- `name`: `$BRANCH` (verbatim — slashes included)
|
|
153
149
|
- `confirm_cost_id`: the same id from the `get_cost` response that was passed to `confirm_cost`
|
|
154
150
|
|