baldart 3.18.1 → 3.21.1

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.
@@ -0,0 +1,300 @@
1
+ ---
2
+ name: baldart-update
3
+ description: "Guidance for updating BALDART framework to the latest version in a consumer repo. Use when the user says /baldart-update, 'aggiorna baldart', 'aggiorna framework', 'update del framework', 'pull baldart latest', or wants to bring the framework up-to-date. Replicates all 5 native CLI decision points (preview diff, working tree stash, hooks drift, schema config drift, BALDART-managed auto-commit) as chat-side confirmations before launching `npx baldart update --yes` via Bash. For non-update drift, defers to `npx baldart` (smart doctor)."
4
+ contamination_scan: skip
5
+ ---
6
+
7
+ # /baldart-update — Update framework in this consumer
8
+
9
+ Guide the user through an update of the BALDART framework inside their
10
+ consumer repo, replicating in chat **every interactive decision point** the
11
+ CLI would normally ask in the terminal — so the CLI can be driven with
12
+ `--yes` while the user keeps full control of each choice.
13
+
14
+ ```
15
+ ╔══════════════════════════════════════════════════════════════════════╗
16
+ ║ BOOTSTRAP NOTICE ║
17
+ ║ ║
18
+ ║ IF THIS IS THE FIRST UPDATE AFTER A CONSUMER WAS ON A VERSION ║
19
+ ║ THAT PREDATES /baldart-update, THIS SKILL DOES NOT YET EXIST IN ║
20
+ ║ THE CONSUMER'S .claude/skills/. The user must run: ║
21
+ ║ ║
22
+ ║ npx baldart update ║
23
+ ║ ║
24
+ ║ directly in their terminal **once**, and the skill becomes ║
25
+ ║ available for every subsequent update. This skill is the pattern ║
26
+ ║ for follow-up updates, not the very first one. ║
27
+ ╚══════════════════════════════════════════════════════════════════════╝
28
+ ```
29
+
30
+ ## Execution model — IMPORTANT
31
+
32
+ This is an **agent-driven skill with full chat-side replication** of every
33
+ decision point the CLI would pose interactively. The flow is:
34
+
35
+ 1. Run *read-only* probes to detect the same conditions `update.js` would
36
+ detect (version drift, dirty working tree, hooks drift, schema config
37
+ drift, BALDART-managed files to auto-commit).
38
+ 2. For each detected condition, surface it in chat and ask the user the
39
+ exact same question the CLI would ask in a TTY.
40
+ 3. Once every prompt has been answered in chat, launch `npx baldart update
41
+ --yes` via `Bash` (with a long timeout — see Hard rules). The `--yes`
42
+ flag is safe here precisely because there is no native prompt left to
43
+ silence: every one of them has already been resolved above.
44
+ 4. Parse the CLI output, report the backup tag + new version, surface any
45
+ stash-pop conflicts that may have happened after the subtree pull.
46
+
47
+ This is the **intentional divergence** from `/baldart-push`, which is
48
+ pure-guidance (the user runs the CLI themselves). Here the user has asked
49
+ for an agent that drives the update, so the skill drives it — but it
50
+ replicates every confirmation so nothing is silently auto-accepted.
51
+
52
+ ## When to use
53
+
54
+ - The user invokes `/baldart-update`.
55
+ - The user says "aggiorna baldart", "aggiorna framework", "update del
56
+ framework", "pull baldart latest", "porta baldart all'ultima versione".
57
+ - The user wants to bring the framework payload in the consumer repo
58
+ in sync with upstream `main`.
59
+
60
+ ## When NOT to use
61
+
62
+ - The user wants to fix drift that is NOT an update (hooks missing, config
63
+ schema drift in isolation, broken symlinks). → `npx baldart` (smart
64
+ doctor) is the right tool — it picks the right action among ~12.
65
+ - The consumer has no `.framework/` directory yet. → `npx baldart add`.
66
+ - The user wants to contribute local framework improvements upstream.
67
+ → `/baldart-push`.
68
+ - The user is in the BALDART repo itself (i.e. `/Users/.../BALDART`),
69
+ not in a consumer. This skill is for consumers; this repo updates
70
+ via `git pull`.
71
+
72
+ ## Project Context
73
+
74
+ **Reads from `baldart.config.yml`:** none directly (the skill reads
75
+ `.framework/VERSION`, `.baldart/state.json`, and `.claude/settings.json`,
76
+ which are BALDART-owned and not gated by config keys).
77
+ **Gated by features:** none.
78
+ **Overlay:** loads `.baldart/overlays/baldart-update.md` if present.
79
+ Typical overlay content: extra pre-flight checks specific to the consumer
80
+ (e.g. "block update if a release branch is open"), or post-update
81
+ verification steps (e.g. "run `npm test` after symlink reconcile").
82
+ **On missing/empty keys:** not applicable — the skill operates on BALDART's
83
+ own state files. See [framework/agents/project-context.md](../../../agents/project-context.md)
84
+ for the protocol.
85
+
86
+ ## Hard rules
87
+
88
+ 1. **MUST NOT re-implement the logic of `update.js`.** Same rule as
89
+ `/baldart-push`: the CLI is the source of truth. The skill only
90
+ replicates prompts and parses output.
91
+ 2. **MUST replicate in chat all 5 decision points** before passing `--yes`:
92
+ preview, working-tree stash, hooks drift, schema config drift,
93
+ auto-commit of BALDART-managed files. Silencing one is dishonest — the
94
+ user thinks they confirmed everything, but they didn't see that prompt.
95
+ 3. **MUST pass `timeout: 600000` (10 minutes)** to the `Bash` call running
96
+ `npx baldart update --yes`. The default 120s is not enough for subtree
97
+ pull + symlink reconcile + post-update wizard + hooks register +
98
+ auto-commit on real-world repos.
99
+ 4. **MUST NOT pass `--auto-stash`** to the CLI: `--yes` already implies it.
100
+ Passing both is imprecise and signals a misread of the CLI.
101
+ 5. **MUST report the backup tag** generated by the CLI, so the user has a
102
+ one-line rollback path.
103
+ 6. **MUST NOT launch update if `.framework/` is missing** — defer to
104
+ `npx baldart add` and stop.
105
+ 7. **MUST NOT assume defaults when a pre-check fails.** If the skill cannot
106
+ read `.claude/settings.json` or `baldart.config.yml`, it asks the user
107
+ how to proceed or aborts. Never silence a decision point because a
108
+ probe failed.
109
+
110
+ ## The 5 decision points the skill replicates
111
+
112
+ | # | Native CLI prompt | Chat-side replication | Detect via |
113
+ |---|------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
114
+ | 1 | "Proceed with update?" | Show "Remote: N commit(s) ahead" + last N commit messages, ask "Procedo?" | `npx baldart version` (parse "Remote: …" + "Repository: <url>") → if N > 0, `git fetch <url> main && git log HEAD..FETCH_HEAD --oneline -- .framework/` |
115
+ | 2 | "Stash dirty working tree?" | List modified files, explain they will go into `baldart-pre-update-<timestamp>`, ask explicit confirmation | `git status --porcelain` in consumer root |
116
+ | 3 | Hooks drift prompt | Compare `.claude/settings.json` entries vs `HOOK_REGISTRY`; if drift, describe what backfill will change | `cat .claude/settings.json` + read `.framework/src/utils/hooks.js` for `HOOK_REGISTRY` |
117
+ | 4 | Schema config migration | Compare `baldart.config.yml` keys vs `.framework/framework/templates/baldart.config.template.yml`; if missing keys, list which + consequence | semantic diff key-by-key (NOT textual diff) |
118
+ | 5 | Auto-commit BALDART-managed | Classify `git status --porcelain` paths as BALDART-managed vs user-owned by path-prefix, show classification, confirm commit of the managed subset | path-prefix matching on `.framework/`, `.claude/agents/`, `.claude/skills/`, `.claude/commands/`, `AGENTS.md`, `agents/` |
119
+
120
+ > **IMPORTANT — do NOT use `git -C .framework fetch`.** `.framework/` is a git
121
+ > subtree, not a separate repo: git commands inside it fall back to the consumer's
122
+ > own repo and would fetch the wrong remote. The correct pattern (mirroring
123
+ > `update.js` + `src/utils/git.js`) is `git fetch <BALDART-repo-url> main` from
124
+ > the consumer root, then `git log HEAD..FETCH_HEAD -- .framework/` for the
125
+ > preview. The repo URL is exposed by `npx baldart version` in the
126
+ > `Repository:` line.
127
+
128
+ ## Workflow
129
+
130
+ ### Step 0 — Pre-flight (read-only)
131
+
132
+ ```bash
133
+ # One call gives both: installed version, behind count, and the
134
+ # BALDART repo URL. NO git operation inside .framework/ — that
135
+ # directory is a git subtree, not a separate repo.
136
+ npx baldart version
137
+ ```
138
+
139
+ Parse the output for:
140
+
141
+ - `Installed: vX.Y.Z` — current framework version in the consumer.
142
+ - `Remote: N commit(s) ahead — pull with …` — number of commits behind upstream. If this line is absent or shows 0, the consumer is up-to-date.
143
+ - `Repository: <url>` — the BALDART git URL (needed in Step 1).
144
+
145
+ If `Remote:` is absent / shows 0 → tell the user "Already up-to-date — version vX.Y.Z" and STOP. Do not launch the CLI.
146
+
147
+ If `.framework/` does not exist, `npx baldart version` will say "framework not installed" — STOP and instruct `npx baldart add`. Do not attempt to recover.
148
+
149
+ ### Step 1 — Replicate decision point #1 (preview)
150
+
151
+ ```bash
152
+ # Use the URL extracted from Step 0, not `git -C .framework`.
153
+ # This mirrors src/utils/git.js (fetch + diffWithRemote use FETCH_HEAD,
154
+ # never `git -C .framework`).
155
+ git fetch <BALDART-repo-url> main
156
+ git log HEAD..FETCH_HEAD --oneline -- .framework/
157
+ ```
158
+
159
+ Surface to the user:
160
+
161
+ - Current installed version (from Step 0).
162
+ - Number of commits behind (from Step 0).
163
+ - One-line summary of each incoming commit (from the `git log` above).
164
+
165
+ Ask: *"Procedo con l'aggiornamento?"*. If no → STOP.
166
+
167
+ ### Step 2 — Replicate decision point #2 (working tree)
168
+
169
+ ```bash
170
+ git status --porcelain
171
+ ```
172
+
173
+ If output is empty, proceed silently. If not, list the modified files in
174
+ chat, explain:
175
+
176
+ > *"Il working tree ha N file modificati. Il CLI li stasherà in un ref
177
+ > `baldart-pre-update-<timestamp>` prima del pull e li ripristinerà dopo.
178
+ > Posso procedere con lo stash automatico?"*
179
+
180
+ If the user refuses → STOP, instruct them to commit or stash manually
181
+ and re-run `/baldart-update`.
182
+
183
+ ### Step 3 — Replicate decision points #3 + #4 (hooks/schema drift)
184
+
185
+ ```bash
186
+ # Hooks drift detection
187
+ cat .claude/settings.json
188
+ # Compare entries against HOOK_REGISTRY in .framework/src/utils/hooks.js
189
+ # (the skill reads both and reports any expected entry missing
190
+ # or any installed entry with a stale config)
191
+
192
+ # Schema drift detection
193
+ # Compare top-level keys in baldart.config.yml against
194
+ # .framework/framework/templates/baldart.config.template.yml
195
+ ```
196
+
197
+ For each drift detected, describe what `update.js` would do:
198
+
199
+ - Hooks drift → "il CLI registrerà le hook mancanti in `settings.json`
200
+ (entry: `baldart-<hook-name>`). Procedo?"
201
+ - Schema drift → "il CLI segnalerà che mancano le chiavi `X.Y` da
202
+ `baldart.config.yml` e suggerirà di rilanciare `npx baldart configure`
203
+ dopo l'update. Procedo (l'update non bloccherà, ma è bene saperlo)?"
204
+
205
+ If a probe fails (e.g. `settings.json` malformed), ask the user how to
206
+ proceed — never silently assume "no drift".
207
+
208
+ ### Step 4 — Replicate decision point #5 (auto-commit classification)
209
+
210
+ ```bash
211
+ git status --porcelain
212
+ ```
213
+
214
+ Classify each path:
215
+
216
+ - **BALDART-managed**: starts with `.framework/`, `.claude/agents/`,
217
+ `.claude/skills/`, `.claude/commands/`, `AGENTS.md`, `agents/`.
218
+ - **User-owned**: everything else.
219
+
220
+ Show the user the classification:
221
+
222
+ > *"Dopo il pull, il CLI auto-committa SOLO i file BALDART-managed che
223
+ > risultano modificati dal reconcile (es. symlink ricreati, agent/command
224
+ > generati). I tuoi file user-owned non vengono toccati. Procedo?"*
225
+
226
+ If no managed files would be modified, skip the prompt silently.
227
+
228
+ ### Step 5 — Run the CLI
229
+
230
+ ```bash
231
+ npx baldart update --yes
232
+ ```
233
+
234
+ **Use the Bash tool with `timeout: 600000`** (10 minutes). Capture stdout
235
+ and stderr — both are needed for Step 6.
236
+
237
+ Do NOT pass `--auto-stash` (redundant with `--yes`).
238
+
239
+ ### Step 6 — Report
240
+
241
+ Extract the post-update facts and surface them:
242
+
243
+ ```bash
244
+ # Backup tag (most recent baldart-pre-update-* tag)
245
+ git tag -l 'baldart-pre-update-*' --sort=-creatordate | head -1
246
+
247
+ # New installed version
248
+ cat .framework/VERSION
249
+
250
+ # Stash-pop conflicts (if any)
251
+ # Grep stdout/stderr for: CONFLICT, "stash pop failed", "unmerged paths"
252
+ # If matches found, list the conflicted paths:
253
+ git status --porcelain | grep '^UU'
254
+ ```
255
+
256
+ Report to the user, in order:
257
+
258
+ 1. **Version**: `vX.Y.Z → vA.B.C` (delta).
259
+ 2. **Backup tag**: the `baldart-pre-update-<timestamp>` ref, with the
260
+ rollback command: `git reset --hard <tag>` (only if needed).
261
+ 3. **Hooks reconciled**: any hook backfilled.
262
+ 4. **Schema notes**: any missing key still flagged → suggest
263
+ `npx baldart configure`.
264
+ 5. **Stash-pop status**: clean / conflicts present (with file list).
265
+ 6. **Suggested next step**: if schema drift residual or other non-update
266
+ doctor checks fired, suggest `npx baldart` (smart doctor).
267
+
268
+ ## Failure modes
269
+
270
+ | Symptom | Cause | What you do |
271
+ |--------------------------------------------------------|----------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
272
+ | `git -C .framework fetch` errors out | Offline / auth issue / repo URL changed | STOP. Surface the error verbatim. Ask the user to retry when network is back. Do not launch update. |
273
+ | Working tree dirty + user refuses stash | Authoring decision | STOP cleanly. Instruct: commit or stash manually, then re-run `/baldart-update`. |
274
+ | `update.js` exits non-zero (subtree pull conflict) | Upstream and local both modified the same file | Surface the CLI error verbatim. Provide the backup tag + `git reset --hard <tag>` rollback command. Do NOT attempt automatic conflict resolution. |
275
+ | Stash-pop conflicts after the subtree pull | User-modified file collides with framework change | Detected by grep on stdout/stderr (`CONFLICT`, `stash pop failed`, `unmerged paths`). List `git status --porcelain | grep '^UU'` paths. Instruct manual resolve. NEVER auto-resolve with `--hard` or `--no-verify`. |
276
+ | `.framework/` missing | Consumer never installed BALDART | STOP. Instruct `npx baldart add`. Do not improvise. |
277
+ | Bash 10-minute timeout exceeded | Very slow network / disk / huge repo | Surface the timeout. Instruct the user to run `npx baldart update` manually in their terminal to see live progress. |
278
+ | Pre-check probe fails (e.g. `settings.json` malformed) | Consumer state inconsistent | STOP. Surface the probe failure. Ask the user whether to proceed without that pre-check, or to fix manually first. Never silently assume "no drift". |
279
+
280
+ ## Why this skill exists
281
+
282
+ The smart doctor (`npx baldart`, no args) already proposes an update
283
+ when it detects remote ahead — but it does so as **one of about twelve**
284
+ possible actions (install, configure, migrate, repair symlinks, register
285
+ hooks, reconcile state ledger, …). When the user knows they want *only*
286
+ to update, going through the doctor is more friction than signal.
287
+
288
+ This skill is the direct path for that case, **and** it does what the
289
+ terminal CLI does — surface every decision point as a confirmation —
290
+ inside the chat instead of in the user's shell. The user keeps the
291
+ control they would have in a TTY, but they get it conversationally.
292
+
293
+ `/baldart-push` and `/baldart-update` together form the conversational
294
+ spine of BALDART maintenance:
295
+
296
+ - `/baldart-update` — pull from upstream.
297
+ - `/baldart-push` — push to upstream.
298
+
299
+ Both wrap the CLI without re-implementing it; both keep the user in the
300
+ loop. The CLI remains the source of truth.
@@ -0,0 +1,214 @@
1
+ ---
2
+ name: overlay
3
+ description: "Guided author of .baldart/overlays/ — the per-project customisation layer for BALDART skills, agents, and commands. Use when the user says /overlay, 'customizza skill', 'modifica agente upstream', 'personalizza comando', 'crea overlay', 'extend skill X', 'override agent Y', 'overlay drift', or when the framework-edit-gate hook blocked an edit and pointed here. The skill walks the user through choosing the right canal (skill / agent / command), scaffolds the overlay with correct frontmatter and section markers via `npx baldart overlay scaffold`, validates the merge via `npx baldart overlay validate`, and surfaces drift via `npx baldart overlay drift`. Never edits `.framework/` directly and never re-implements the merger logic — the CLI is the source of truth."
4
+ contamination_scan: skip
5
+ ---
6
+
7
+ # /overlay — Customise the framework, the right way
8
+
9
+ Author an overlay under `.baldart/overlays/` for a BALDART skill, agent, or command, instead of editing `.framework/` (which gets overwritten on `baldart update` and blocked by the contamination scanner).
10
+
11
+ ## Execution model
12
+
13
+ This skill is a **thin guidance wrapper** around `npx baldart overlay`. The CLI is non-interactive (no prompts), so the skill can invoke it via the Bash tool. The CLI is the source of truth for:
14
+
15
+ - Path conventions (`.baldart/overlays/<name>.md` for skills, `.baldart/overlays/agents/<name>.md`, `.baldart/overlays/commands/<name>.md`).
16
+ - Frontmatter schema (`base_<kind>`, `base_<kind>_version`, `base_file_sha`, `mode`).
17
+ - Merger validation (uses `src/utils/overlay-merger.js` internally).
18
+ - Drift detection (SHA-based when `base_file_sha` is present, version-based fallback).
19
+
20
+ The skill MUST NOT re-implement any of the above. If you find yourself writing path logic or YAML manipulation, stop — invoke the CLI.
21
+
22
+ ## When to use
23
+
24
+ - The user invokes `/overlay`.
25
+ - The user says "customizza skill X", "personalizza il command Y", "modifica l'agente Z per questo progetto".
26
+ - The user wants a project-specific opinion to apply (brand voice, debug entry point, stack mandate, custom workflow) without contaminating the framework upstream.
27
+ - The user follows the handoff from the `framework-edit-gate` hook message ("invoke /overlay for a guided flow").
28
+ - The user asks "is my overlay still in sync with the framework?" or "drift overlay".
29
+
30
+ ## When NOT to use
31
+
32
+ - The improvement is **generic** (useful for all consumers). Send it upstream via `/baldart-push` instead.
33
+ - The user wants to install / update the framework itself (use `npx baldart` / `update`).
34
+ - The user wants to author a brand-new skill that has no base in the framework — they create it directly under `.claude/skills/<name>/`. Overlays are for *modifying* a framework primitive, not for net-new ones.
35
+ - The user wants to modify a **hook** under `.claude/hooks/`. Hooks are installed as **plain copies** (consumer-owned, no auto-update) — they do not fit the overlay model. The consumer edits them directly in their repo. If the change should benefit every consumer, edit the `.template` file under `.framework/.claude/hooks/` and push upstream via `/baldart-push`. Overlay scope is limited to skills, agents, and commands.
36
+
37
+ ## Project Context
38
+
39
+ **Reads from `baldart.config.yml`:** none (overlay paths are universal).
40
+ **Gated by features:** none.
41
+ **Overlay:** this skill has no overlay (it would be paradoxical).
42
+ **On missing/empty keys:** not applicable.
43
+
44
+ ## Hard rules
45
+
46
+ 1. **NEVER edit files under `.framework/` directly.** The contamination scanner will block the edit, and even if it didn't, `baldart update` would overwrite the change.
47
+ 2. **NEVER edit a file with the marker `<!-- baldart-generated:` on line 1.** It is auto-regenerated from base + overlay. The hook blocks this. Edit the overlay instead.
48
+ 3. **NEVER fabricate `base_<kind>_version` or `base_file_sha`.** Both are computed by the CLI at scaffold time. The skill never writes these by hand.
49
+ 4. **NEVER write to `.baldart/overlays/` with the Edit/Write tools to *create* a new overlay.** Use `npx baldart overlay scaffold` so the frontmatter is correct. Editing the *body* of an already-scaffolded overlay with Edit/Write is fine.
50
+ 5. **NEVER re-implement the section-merge logic** (`[OVERRIDE]/[APPEND]/[PREPEND]`). The merger in `overlay-merger.js` is the only place it lives.
51
+ 6. **When the user's intent is clearly generic** ("we should add a Quality bar step to every coder workflow"), redirect them to `/baldart-push` instead of scaffolding an overlay.
52
+
53
+ ## Workflow
54
+
55
+ ### Step 0 — Pre-check
56
+
57
+ Before anything, confirm this is a consumer repo:
58
+
59
+ ```
60
+ [ -d .framework ] && echo OK
61
+ ```
62
+
63
+ If not OK, stop and say: "This repo is not a BALDART consumer. Run `npx baldart` to install the framework first."
64
+
65
+ Also confirm the overlays directory exists (it should, after `configure`):
66
+
67
+ ```
68
+ [ -d .baldart/overlays ] || mkdir -p .baldart/overlays
69
+ ```
70
+
71
+ ### Step 1 — Discovery
72
+
73
+ Ask the user:
74
+
75
+ 1. **What do they want to customise?** A skill, an agent, or a command?
76
+ - **Skill**: shapes how a `/-command` workflow behaves (e.g. `/bug`, `/capture`, `/new`). Base lives at `.framework/framework/.claude/skills/<name>/SKILL.md`. Overlay is concat'd at runtime by the agent — section markers are textual conventions, not parsed.
77
+ - **Agent**: shapes how a specialised subagent reasons (e.g. `coder`, `code-reviewer`, `qa-sentinel`). Base lives at `.framework/framework/.claude/agents/<name>.md`. Overlay is merged section-by-section via markers, producing a generated file at `.claude/agents/<name>.md`.
78
+ - **Command**: shapes a top-level slash command (e.g. `/codexreview`, `/check`). Base lives at `.framework/framework/.claude/commands/<name>.md`. Same marker-based merge as agents.
79
+
80
+ 2. **Which one?** List the available bases for the chosen kind:
81
+
82
+ ```bash
83
+ # for skills
84
+ ls .framework/framework/.claude/skills/
85
+ # for agents
86
+ ls .framework/framework/.claude/agents/
87
+ # for commands
88
+ ls .framework/framework/.claude/commands/
89
+ ```
90
+
91
+ 3. **What intent?**
92
+ - `extend` (default) — add to / tweak parts of the base.
93
+ - `override` (skills only) — replace the entire base skill with the overlay content. Rare; use only when the base does not fit your project at all.
94
+
95
+ ### Step 2 — Inspect base + existing overlay
96
+
97
+ Read the base file with the Read tool. Show the user the H2 section list (`grep '^## ' <base-file>`). This is what they can target with `[OVERRIDE]/[APPEND]/[PREPEND]` (for agent/command) or as textual landmarks (for skill).
98
+
99
+ If `.baldart/overlays/<path>` already exists:
100
+
101
+ - Show its current frontmatter and section list.
102
+ - Run drift check: `npx baldart overlay drift .baldart/overlays/<path>`.
103
+ - Switch to "extend existing" mode: the skill will guide the user to add / modify sections by **editing the file directly** (Edit tool), not by re-scaffolding.
104
+
105
+ ### Step 3 — Scaffold (new overlays only)
106
+
107
+ Invoke the CLI:
108
+
109
+ ```bash
110
+ npx baldart overlay scaffold <kind>/<name> [--mode override]
111
+ ```
112
+
113
+ Where `<kind>` is `skill`, `agents`, or `commands` (plural for agent/command to match the overlay subdir convention). Examples:
114
+
115
+ - `npx baldart overlay scaffold agents/coder`
116
+ - `npx baldart overlay scaffold commands/codexreview`
117
+ - `npx baldart overlay scaffold bug` (no slash → skill)
118
+ - `npx baldart overlay scaffold skill/bug --mode override`
119
+
120
+ The CLI:
121
+ - Validates that the base exists in `.framework/`.
122
+ - Computes `base_file_sha` (sha256, 12 chars) from the base content.
123
+ - Reads framework `VERSION`.
124
+ - Writes `.baldart/overlays/<path>` with the correct frontmatter and a placeholder body.
125
+
126
+ If the overlay already exists, the CLI refuses (idempotent). Use Step 4 to extend it instead.
127
+
128
+ ### Step 4 — Author the body
129
+
130
+ Open the scaffolded file with the Read tool, show the user the placeholder content, and ask what they want to put there. Use the Edit tool to insert their content. Examples of what each marker does:
131
+
132
+ **For agent / command overlays:**
133
+
134
+ ```markdown
135
+ ## [APPEND] Quality bar
136
+
137
+ - Before closing any task, run `npm run test:e2e -- --grep <feature>`.
138
+ - Attach the Playwright screenshot to the commit body.
139
+
140
+ ## [OVERRIDE] When to escalate
141
+
142
+ In this project, escalate to the human owner before touching `prisma/schema.prisma`.
143
+
144
+ ## Project-only conventions
145
+
146
+ (New section, appended at the end of the merged file.)
147
+ - All API calls go through `src/lib/api-client.ts`.
148
+ ```
149
+
150
+ **For skill overlays** (concat model — markers are textual conventions only):
151
+
152
+ ```markdown
153
+ ## [APPEND] Project-specific guidance
154
+
155
+ In this project, debug entry points are in `apps/web/`. Always start
156
+ Playwright in headed mode for visual bugs.
157
+ ```
158
+
159
+ Reference examples already shipped with the framework:
160
+ - `.framework/framework/templates/overlays/ui-design.fidelity-example.md` (skill, fidelity-app brand voice)
161
+ - `.framework/framework/templates/overlays/copywriting.fidelity-example.md` (skill, 4-pillar brand voice)
162
+ - `.framework/framework/templates/overlays/agents/coder.example.md` (agent, marker-based)
163
+ - `.framework/framework/templates/overlays/commands/codexreview.example.md` (command, marker-based)
164
+
165
+ ### Step 5 — Validate
166
+
167
+ Run:
168
+
169
+ ```bash
170
+ npx baldart overlay validate <path>
171
+ ```
172
+
173
+ The CLI dry-runs the merger and reports:
174
+ - Frontmatter parse status.
175
+ - For agent/command: number of lines generated, any warnings (e.g. an overlay section whose heading does not match any base H2 — it will be appended as a new section, which may be intentional).
176
+ - Whether the base file changed since the overlay was authored (SHA comparison).
177
+
178
+ If `validate` reports errors, fix them with Edit and re-run. If it reports warnings about non-matching headings, decide with the user whether that is intentional (new custom section) or a typo to correct.
179
+
180
+ ### Step 6 — Apply
181
+
182
+ - **For skills**: nothing to do. The overlay is loaded at runtime by Claude when the user invokes a `/-command` that uses the skill.
183
+ - **For agents / commands**: run `npx baldart update` to regenerate the file in `.claude/<kind>s/<name>.md` from base + overlay. The regenerated file carries the `<!-- baldart-generated: -->` marker on line 1 — do not edit it manually (the `framework-edit-gate` hook will block, anyway).
184
+
185
+ ### Step 7 — Drift maintenance (periodic)
186
+
187
+ When the user updates the framework (`npx baldart update` bumps `VERSION`), the base files for their overlays may have changed. Tell them how to audit:
188
+
189
+ ```bash
190
+ npx baldart overlay drift --all
191
+ ```
192
+
193
+ For each drifted overlay, the user should:
194
+ 1. Open the base file: `.framework/framework/.claude/<path>`.
195
+ 2. Read the diff against what they expected (use `git -C .framework log -p -- framework/.claude/<path>` to see the upstream changes).
196
+ 3. If the overlay still makes sense, refresh the `base_file_sha` by re-running scaffold (after backing up the overlay body) — or simply update `base_file_sha` by hand once they have confirmed the overlay still applies cleanly.
197
+ 4. If the overlay no longer makes sense, edit it to align with the new base.
198
+
199
+ ## Failure modes & remediation
200
+
201
+ | Symptom | Likely cause | Remediation |
202
+ |---|---|---|
203
+ | `scaffold` says "already exists" | Overlay was authored previously | Edit the existing file directly. Run `overlay drift` first to check. |
204
+ | `validate` says "frontmatter mismatch" | `base_<kind>: <name>` does not match the overlay's filename | Either fix the frontmatter or rename the file. The two MUST agree. |
205
+ | `validate` warning "overlay section has no matching H2 in base" | The user used `[OVERRIDE]` / `[APPEND]` / `[PREPEND]` with a heading that does not exist in the base file | Either fix the heading to match an existing base H2, or drop the marker (the section will become a new custom section appended at the end). |
206
+ | `drift` says "drift unknown" | Overlay was authored before `base_file_sha` existed (pre-v3.19.0) | Re-run `scaffold` on a temp path to capture the current SHA, then merge that into the overlay frontmatter manually. Or just accept the version-based fallback. |
207
+ | Hook blocked an edit to a generated file | The user tried to edit `.claude/agents/<x>.md` directly, which is BALDART-managed | Edit the overlay at `.baldart/overlays/agents/<x>.md` instead. The hook message already says this. |
208
+
209
+ ## Reference
210
+
211
+ - `framework/agents/project-context.md` § 5 — overlay protocol.
212
+ - `framework/templates/overlays/README.md` — conventions and pointer to example overlays.
213
+ - `src/utils/overlay-merger.js` — merger implementation (read-only; do not duplicate in the skill).
214
+ - `src/commands/overlay.js` — CLI implementation (skill calls this via Bash).
@@ -94,6 +94,7 @@ Conflict steps (must follow in order):
94
94
 
95
95
  - MUST treat `AGENTS.md` as authoritative for agent rules.
96
96
  - MUST invoke `codebase-architect` agent (via Task tool) whenever you need to understand codebase structure, existing patterns, or code architecture before planning or implementing changes; do not proceed with planning or implementation without first understanding the existing system through codebase-architect.
97
+ - MUST NOT silently fall back when an `Agent` (a.k.a. `Task`) tool call returns empty (`0 tool uses · Done`), times out, or fails with `permissionDecision: deny`. This pattern indicates a Claude Code sub-agent failure (see anthropics/claude-code#56869) or a discovery miss / blocked agent (see #20931 and BALDART's own `agent-discovery-gate` PreToolUse hook), NOT a signal to substitute another agent. STOP, report to the user verbatim: "Agent `<name>` non discoverato o fallito in questa sessione — riavvia Claude Code e verifica con `npx baldart doctor`", and wait for direction. Never auto-route to `feature-dev:*`, `general-purpose`, or any other marketplace/built-in agent as a replacement. **This rule is the ONLY defense against bug #56869 (which BALDART cannot patch from outside Claude Code); deviating from it reintroduces the exact failure mode the rule exists to prevent.**
97
98
  - MUST NOT work on files/components already claimed by another agent; multiple agents allowed if working on independent areas.
98
99
  - MUST perform a mandatory clarity analysis before fixing any issue labeled `bug`; confirm that the issue description, proposed correct behavior, and edge cases are unambiguous, document any resolved doubts, and only start fix work once every zone of uncertainty is covered.
99
100
  - MUST mark missing info as UNKNOWN and ask the user; if blocked, set `BLOCKED` with a blocker.
@@ -22,10 +22,23 @@ Every overlay file has YAML frontmatter:
22
22
  ---
23
23
  base_skill: <skill-name> # MUST match the skill directory name
24
24
  base_skill_version: <semver> # framework version when authored
25
+ base_file_sha: "<12-char-sha>" # optional (v3.19.0+) — base file content sha for accurate drift detection
25
26
  mode: extend | override # default: extend
26
27
  ---
27
28
  ```
28
29
 
30
+ For agent overlays use `base_agent` / `base_agent_version`, and for command
31
+ overlays `base_command` / `base_command_version`.
32
+
33
+ The optional `base_file_sha` (v3.19.0+) records the sha256 prefix (12 chars)
34
+ of the base file at the moment the overlay was scaffolded. When present,
35
+ `npx baldart overlay drift` uses it to detect base-file changes precisely
36
+ instead of falling back to a version-string compare. The value MUST be
37
+ quoted because an all-digit hex like `000000000000` would otherwise be
38
+ parsed as a number by YAML. The `npx baldart overlay scaffold` CLI writes
39
+ this field automatically; hand-written overlays may omit it (drift detection
40
+ silently degrades to the version-only fallback — no error).
41
+
29
42
  Sections marked `## [OVERRIDE] <topic>` replace the same `<topic>` from the
30
43
  base skill. Everything else extends the base.
31
44
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baldart",
3
- "version": "3.18.1",
3
+ "version": "3.21.1",
4
4
  "description": "Claude Agent Framework - Reusable framework for coordinating AI agents and humans in software projects",
5
5
  "bin": {
6
6
  "baldart": "./bin/baldart.js"
@@ -166,19 +166,24 @@ async function add(repo, options) {
166
166
  UI.success('Git aliases configured');
167
167
  }
168
168
 
169
- // Framework-edit-gate hook (since v3.3.0)
170
- // Auto-register the PreToolUse hook that prevents project-specific
171
- // tokens from being written into .framework/ skills accidentally.
169
+ // BALDART hooks (multi-hook registry since v3.18.0)
170
+ // Auto-register every hook in src/utils/hooks.js HOOK_REGISTRY into
171
+ // .claude/settings.json. Drift on an existing entry triggers an
172
+ // interactive prompt (Keep / Replace / Show diff).
172
173
  try {
173
- const res = Hooks.register();
174
- if (res.status === 'created') {
175
- UI.success('Registered framework-edit-gate hook in .claude/settings.json');
176
- } else if (res.status === 'updated') {
177
- UI.success('Added framework-edit-gate hook to existing .claude/settings.json');
178
- } else if (res.status === 'already') {
179
- UI.info('framework-edit-gate hook already registered.');
180
- } else if (res.status === 'malformed') {
174
+ const res = await Hooks.registerAll(process.cwd(), {
175
+ onDrift: Hooks.createDriftPrompt(UI),
176
+ });
177
+ if (res.malformed) {
181
178
  UI.warning('.claude/settings.json is malformed; skipped hook registration. Run `npx baldart doctor` after fixing it.');
179
+ } else {
180
+ for (const r of res.results) {
181
+ if (r.status === 'created') UI.success(`Registered hook \`${r.id}\` in .claude/settings.json`);
182
+ else if (r.status === 'legacy-migrated') UI.success(`Migrated legacy hook to \`${r.id}\` (previous: ${r.previousCommand})`);
183
+ else if (r.status === 'drift-replaced') UI.success(`Replaced drifted hook \`${r.id}\` (was: ${r.previousCommand})`);
184
+ else if (r.status === 'drift-kept') UI.info(`Kept user-customized hook \`${r.id}\` as-is.`);
185
+ else if (r.status === 'already') UI.info(`Hook \`${r.id}\` already registered.`);
186
+ }
182
187
  }
183
188
  } catch (err) {
184
189
  UI.warning(`Hook registration skipped: ${err.message}`);