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.
- package/CHANGELOG.md +192 -0
- package/README.md +2 -1
- package/VERSION +1 -1
- package/bin/baldart.js +30 -0
- package/framework/.claude/agents/REGISTRY.md +2 -0
- package/framework/.claude/hooks/agent-discovery-gate.js +167 -0
- package/framework/.claude/hooks/agent-discovery-info.sh +104 -0
- package/framework/.claude/hooks/framework-edit-gate.js +5 -1
- package/framework/.claude/skills/baldart-update/SKILL.md +300 -0
- package/framework/.claude/skills/overlay/SKILL.md +214 -0
- package/framework/AGENTS.md +1 -0
- package/framework/templates/overlays/README.md +13 -0
- package/package.json +1 -1
- package/src/commands/add.js +16 -11
- package/src/commands/doctor.js +138 -13
- package/src/commands/overlay.js +381 -0
- package/src/commands/update.js +18 -6
- package/src/utils/hooks.js +357 -86
- package/src/utils/overlay-merger.js +17 -4
|
@@ -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).
|
package/framework/AGENTS.md
CHANGED
|
@@ -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
package/src/commands/add.js
CHANGED
|
@@ -166,19 +166,24 @@ async function add(repo, options) {
|
|
|
166
166
|
UI.success('Git aliases configured');
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
//
|
|
170
|
-
// Auto-register
|
|
171
|
-
//
|
|
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.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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}`);
|