baldart 3.8.1 → 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 CHANGED
@@ -5,6 +5,16 @@ 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
+
8
18
  ## [3.8.1] - 2026-05-22
9
19
 
10
20
  Documentation: promote the "one command for everything" install path in the README and surface the global-install recommendation in CLAUDE.md.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 3.8.1
1
+ 3.8.2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baldart",
3
- "version": "3.8.1",
3
+ "version": "3.8.2",
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"
@@ -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
- proceed = await UI.confirm(`Run: ${action.label}?`, true);
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}`);