baldart 3.8.0 → 3.8.2
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 +21 -0
- package/README.md +46 -25
- package/VERSION +1 -1
- package/package.json +1 -1
- package/src/commands/doctor.js +25 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ All notable changes to BALDART will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.8.2] - 2026-05-22
|
|
9
|
+
|
|
10
|
+
`baldart` (smart doctor) no longer double-confirms safe actions. Previously, running `baldart` with a remote-ahead state would ask *"Run: Pull N commit(s)?"* and then the `update` command would ask *"Proceed with update?"* immediately after — two prompts for the same intent.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **`src/commands/doctor.js` action runner** — every action now carries an `autoOk` flag. Safe & idempotent actions (`update`, `configure*`, `migrate`, `register-edit-gate`) run without the outer doctor confirmation (their own internal prompts take over). Actions that change external state or need explicit version classification (`add`, `push`) keep the outer confirmation so the user signals intent explicitly.
|
|
15
|
+
|
|
16
|
+
Result: `baldart` in a repo with "remote ahead" now goes straight into the update flow (with its own pre-flight stash + diff preview + proceed prompt), instead of double-asking.
|
|
17
|
+
|
|
18
|
+
## [3.8.1] - 2026-05-22
|
|
19
|
+
|
|
20
|
+
Documentation: promote the "one command for everything" install path in the README and surface the global-install recommendation in CLAUDE.md.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- **`README.md` Quick Start** — restructured. Primary path is now `npm i -g baldart` once, then `baldart` (no args) in any project. Added a table that maps every repo state to the action `baldart` proposes (install / migrate / configure / update / push). The `npx baldart …` form remains documented as the no-global-install alternative.
|
|
25
|
+
- **`CLAUDE.md`** — added the recommended end-user install (`npm i -g baldart`) to the distribution note.
|
|
26
|
+
|
|
27
|
+
No behavioural changes; the smart-doctor entry point has worked this way since v3.2.0, this release just makes it discoverable.
|
|
28
|
+
|
|
8
29
|
## [3.8.0] - 2026-05-22
|
|
9
30
|
|
|
10
31
|
`.claude/agents/` and `.claude/commands/` move from bulk symlink to **per-item merge** with an **overlay system** (compile-time merge of base + overlay). Closes the long-standing gap where specializing a framework agent forced you to either fork the whole file (and lose upstream updates) or contaminate `.framework/`.
|
package/README.md
CHANGED
|
@@ -14,47 +14,68 @@ BALDART provides a portable system for:
|
|
|
14
14
|
|
|
15
15
|
## Quick Start
|
|
16
16
|
|
|
17
|
-
###
|
|
17
|
+
### One command for everything (recommended)
|
|
18
|
+
|
|
19
|
+
Install the CLI globally once:
|
|
18
20
|
|
|
19
21
|
```bash
|
|
20
|
-
|
|
21
|
-
npx baldart add
|
|
22
|
+
npm i -g baldart
|
|
22
23
|
```
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
Then in any project directory just run:
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- Copies customizable templates (hooks, UI guidelines, backlog cards)
|
|
30
|
-
- Creates required directories (docs/, templates/, backlog/)
|
|
27
|
+
```bash
|
|
28
|
+
baldart
|
|
29
|
+
```
|
|
31
30
|
|
|
32
|
-
|
|
31
|
+
That's it. `baldart` with no arguments runs the **smart doctor**: it auto-detects the repo state and proposes the next sensible action with a `Y/n` prompt. You don't need to remember `add` vs `update` vs `configure` vs `migrate` — it picks the right one.
|
|
33
32
|
|
|
34
|
-
|
|
33
|
+
| Repo state | What `baldart` proposes |
|
|
34
|
+
|---|---|
|
|
35
|
+
| No `.framework/` | "Install BALDART framework" → runs `add` |
|
|
36
|
+
| Legacy bulk-symlink (pre-v3.8.0) | "Migrate legacy layout" → runs `migrate` |
|
|
37
|
+
| Missing `baldart.config.yml` | "Generate baldart.config.yml" → runs `configure` |
|
|
38
|
+
| New config keys in this framework version | "Refresh baldart.config.yml" → runs `configure` |
|
|
39
|
+
| `framework-edit-gate` hook not registered | "Register hook" |
|
|
40
|
+
| Remote framework is ahead | "Pull N commit(s) from upstream" → runs `update` |
|
|
41
|
+
| Local framework changes ready to share | "Push local improvements upstream" → runs `push` |
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
# Smart entry point: diagnose install state and propose next action.
|
|
38
|
-
# `npx baldart` with no arguments runs this; equivalent to `baldart doctor`.
|
|
39
|
-
npx baldart
|
|
43
|
+
If several conditions hold, actions are presented in priority order (e.g. update before push).
|
|
40
44
|
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
Upgrade the CLI later:
|
|
46
|
+
```bash
|
|
47
|
+
npm i -g baldart@latest
|
|
48
|
+
```
|
|
43
49
|
|
|
44
|
-
|
|
45
|
-
npx baldart status
|
|
50
|
+
### Without the global install
|
|
46
51
|
|
|
47
|
-
|
|
48
|
-
npx baldart configure
|
|
52
|
+
If you don't want a global install, every command also works via `npx`:
|
|
49
53
|
|
|
50
|
-
|
|
54
|
+
```bash
|
|
55
|
+
npx baldart # same smart entry point
|
|
56
|
+
npx baldart add # explicit subcommands
|
|
51
57
|
npx baldart update
|
|
52
|
-
|
|
53
|
-
# Contribute improvements upstream (auto bump + CHANGELOG + tag)
|
|
58
|
+
npx baldart configure
|
|
54
59
|
npx baldart push
|
|
60
|
+
npx baldart version
|
|
61
|
+
npx baldart status
|
|
55
62
|
```
|
|
56
63
|
|
|
57
|
-
>
|
|
64
|
+
> The legacy `npx -y github:antbald/BALDART <cmd>` form still works if you need to install from an unreleased commit on `main`. For pinning a specific version: `npx baldart@3.8.0 <cmd>`.
|
|
65
|
+
|
|
66
|
+
### What `add` (first install) does
|
|
67
|
+
|
|
68
|
+
- Downloads the framework via Git subtree into `.framework/`
|
|
69
|
+
- Creates symlinks for auto-updateable files (AGENTS.md, agents/)
|
|
70
|
+
- Per-item-merges framework agents/commands/skills into `.claude/` (real directories where your own files coexist)
|
|
71
|
+
- Detects Codex on the machine and mirrors skills into `.agents/skills/` if found
|
|
72
|
+
- Copies customizable templates (hooks, UI guidelines, backlog cards)
|
|
73
|
+
- Registers the `framework-edit-gate` hook in `.claude/settings.json`
|
|
74
|
+
- Runs `configure` interactively to populate `baldart.config.yml`
|
|
75
|
+
|
|
76
|
+
No additional activation steps needed — once installed, Claude Code (and Codex) automatically pick up the agents, commands, skills, and protocols.
|
|
77
|
+
|
|
78
|
+
> **Tip**: During installation, BALDART offers to configure git aliases (`fw-version`, `fw-update`, `fw-push`) — handy if you don't want the global install but find `npx baldart …` long.
|
|
58
79
|
|
|
59
80
|
## Features
|
|
60
81
|
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.8.
|
|
1
|
+
3.8.2
|
package/package.json
CHANGED
package/src/commands/doctor.js
CHANGED
|
@@ -228,11 +228,19 @@ function planActions(state) {
|
|
|
228
228
|
return actions;
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
+
// `autoOk` policy:
|
|
232
|
+
// - true → safe & idempotent action that has its own internal prompts
|
|
233
|
+
// (update, configure, migrate, hook register). The outer doctor
|
|
234
|
+
// prompt would be a redundant double-confirmation, so we skip it.
|
|
235
|
+
// - false → state-changing action that warrants explicit intent at the
|
|
236
|
+
// doctor level (add = first install, push = writes to remote
|
|
237
|
+
// and triggers a version-classification dialog).
|
|
231
238
|
if (!state.frameworkPresent) {
|
|
232
239
|
actions.push({
|
|
233
240
|
key: 'add',
|
|
234
241
|
label: 'Install BALDART framework',
|
|
235
242
|
why: 'No .framework/ directory found in this repo.',
|
|
243
|
+
autoOk: false,
|
|
236
244
|
run: async () => {
|
|
237
245
|
const add = require('./add');
|
|
238
246
|
await add(REPO_DEFAULT, { branch: 'main' });
|
|
@@ -246,6 +254,7 @@ function planActions(state) {
|
|
|
246
254
|
key: 'migrate',
|
|
247
255
|
label: 'Migrate legacy v2.0.x layout',
|
|
248
256
|
why: '.claude/skills/ is a bulk symlink — v2.0.x layout. v2.1.1+ uses per-item merge.',
|
|
257
|
+
autoOk: true,
|
|
249
258
|
run: () => require('./migrate')(),
|
|
250
259
|
});
|
|
251
260
|
return actions;
|
|
@@ -256,6 +265,7 @@ function planActions(state) {
|
|
|
256
265
|
key: 'configure-malformed',
|
|
257
266
|
label: 'Rewrite baldart.config.yml (current file is malformed)',
|
|
258
267
|
why: 'Existing baldart.config.yml is not valid YAML — re-running configure will rebuild it.',
|
|
268
|
+
autoOk: true,
|
|
259
269
|
run: () => require('./configure')(),
|
|
260
270
|
});
|
|
261
271
|
return actions;
|
|
@@ -266,6 +276,7 @@ function planActions(state) {
|
|
|
266
276
|
key: 'configure',
|
|
267
277
|
label: 'Generate baldart.config.yml',
|
|
268
278
|
why: 'Skills require a config to resolve project-specific paths/identity/stack. Without it they will prompt on every invocation.',
|
|
279
|
+
autoOk: true,
|
|
269
280
|
run: () => require('./configure')(),
|
|
270
281
|
});
|
|
271
282
|
return actions;
|
|
@@ -276,6 +287,7 @@ function planActions(state) {
|
|
|
276
287
|
key: 'configure-drift',
|
|
277
288
|
label: `Refresh baldart.config.yml (${state.configSchemaMissing.length} new key(s) from framework template)`,
|
|
278
289
|
why: 'Framework added config keys this consumer doesn\'t yet declare: ' + state.configSchemaMissing.join(', '),
|
|
290
|
+
autoOk: true,
|
|
279
291
|
run: () => require('./configure')(),
|
|
280
292
|
});
|
|
281
293
|
// Drift is non-blocking — keep checking for other actions after.
|
|
@@ -286,6 +298,7 @@ function planActions(state) {
|
|
|
286
298
|
key: 'register-edit-gate',
|
|
287
299
|
label: 'Register framework-edit-gate hook (.claude/settings.json)',
|
|
288
300
|
why: 'Prevents project-specific tokens (Neo-Brutalism, merchant, …) from being written to .framework/ accidentally. Standard in v3.3.0+; missing on installs predating that version.',
|
|
301
|
+
autoOk: true,
|
|
289
302
|
run: async () => {
|
|
290
303
|
const res = require('../utils/hooks').register();
|
|
291
304
|
UI.success(`Hook registered: ${res.status} (${res.path})`);
|
|
@@ -301,6 +314,7 @@ function planActions(state) {
|
|
|
301
314
|
key: 'update',
|
|
302
315
|
label: `Pull ${state.remote.behind} commit(s) from upstream`,
|
|
303
316
|
why: 'Remote framework is ahead of your local copy. Updating first keeps your contributions on a fresh base.',
|
|
317
|
+
autoOk: true, // update has its own internal "Proceed?" prompt + pre-flight stash
|
|
304
318
|
run: () => require('./update')(),
|
|
305
319
|
});
|
|
306
320
|
}
|
|
@@ -312,6 +326,7 @@ function planActions(state) {
|
|
|
312
326
|
why: state.workingTreeDirty
|
|
313
327
|
? `${state.workingTreeDirty} uncommitted file(s) in .framework/ — commit them through \`baldart push\`.`
|
|
314
328
|
: `${state.commitsAhead} commit(s) on .framework/ not yet pushed.`,
|
|
329
|
+
autoOk: false, // push writes to remote and asks for version classification — keep explicit intent
|
|
315
330
|
run: () => require('./push')(),
|
|
316
331
|
});
|
|
317
332
|
}
|
|
@@ -472,7 +487,16 @@ async function doctor(opts = {}) {
|
|
|
472
487
|
for (const action of actions) {
|
|
473
488
|
let proceed = auto;
|
|
474
489
|
if (!auto) {
|
|
475
|
-
|
|
490
|
+
// Safe & idempotent actions (`autoOk: true`) run without an outer
|
|
491
|
+
// confirmation — they have their own internal prompts. Actions that
|
|
492
|
+
// change external state or require explicit version classification
|
|
493
|
+
// (add, push) still ask here so the user signals intent.
|
|
494
|
+
if (action.autoOk) {
|
|
495
|
+
UI.info(`→ Running: ${action.label}`);
|
|
496
|
+
proceed = true;
|
|
497
|
+
} else {
|
|
498
|
+
proceed = await UI.confirm(`Run: ${action.label}?`, true);
|
|
499
|
+
}
|
|
476
500
|
}
|
|
477
501
|
if (!proceed) {
|
|
478
502
|
UI.info(`Skipped: ${action.label}`);
|