yadflow 3.5.0 → 3.5.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 CHANGED
@@ -1,14 +1,9 @@
1
- # [3.5.0](https://github.com/abdelrahmannasr/yadflow/compare/v3.4.2...v3.5.0) (2026-07-02)
1
+ ## [3.5.1](https://github.com/abdelrahmannasr/yadflow/compare/v3.5.0...v3.5.1) (2026-07-02)
2
2
 
3
3
 
4
4
  ### Bug Fixes
5
5
 
6
- * **usage:** address CodeRabbit review on PR [#98](https://github.com/abdelrahmannasr/yadflow/issues/98) ([e5e64fa](https://github.com/abdelrahmannasr/yadflow/commit/e5e64fa1c19de53b553a8679e76e8304c2001073))
7
-
8
-
9
- ### Features
10
-
11
- * **usage:** add derived team-member usage & behavior report ([1813026](https://github.com/abdelrahmannasr/yadflow/commit/181302613b6585b696fbf3ee132a236543c7fd63))
6
+ * preserve roster and verified_authors on hub reconfigure ([84bd0af](https://github.com/abdelrahmannasr/yadflow/commit/84bd0affed378e9b6ed60fa2471816f7a585c9c7))
12
7
 
13
8
  # [2.2.0](https://github.com/abdelrahmannasr/yadflow/compare/v2.1.0...v2.2.0) (2026-06-14)
14
9
 
package/cli/setup.mjs CHANGED
@@ -4,7 +4,7 @@ import fs from 'node:fs';
4
4
  import os from 'node:os';
5
5
  import {
6
6
  c, log, step, guide, ok, info, warn, hand, fail, ask, askYesNo, run, has,
7
- exists, readJSON, writeJSON,
7
+ exists, readJSON, readJSONStrict, writeJSON,
8
8
  } from './lib.mjs';
9
9
  import { VERSION, IDE_FOLDER_TARGETS, PROJECT_FILES, DESIGN_TOOLS, DESIGN_PRIMARY, TESTING_TOOLS, TESTING_PRIMARY, LEARNING_TOOLS, LEARNING_PRIMARY } from './manifest.mjs';
10
10
  import {
@@ -96,6 +96,21 @@ function normalizeRoles(entry) {
96
96
  return entry.roles;
97
97
  }
98
98
 
99
+ // Build the hub.json object for a (re)configure write, preserving user-owned identity data the wizard
100
+ // does not re-collect: top-level `verified_authors` (and any other existing fields), plus a previously
101
+ // populated `roster` when this run collected none (solo re-runs skip the reviewer loop). Never blanks a
102
+ // non-empty roster; never drops verified_authors. Mirrors the safe { ...cur } merge on the keep path.
103
+ // Trade-off (deliberate, fail-safe): a reconfigure can no longer EMPTY a populated roster — collecting
104
+ // zero reviewers keeps the existing entries. To actually remove members, use `yad roster remove` (or
105
+ // edit hub.json directly); this flow only ever grows or replaces the roster, never silently clears it.
106
+ export function buildReconfiguredHub(cur, fields) {
107
+ const { roster, ...rest } = fields;
108
+ const keptRoster = (Array.isArray(roster) && roster.length)
109
+ ? roster
110
+ : (Array.isArray(cur?.roster) ? cur.roster : []);
111
+ return { ...(cur || {}), ...rest, roster: keptRoster };
112
+ }
113
+
99
114
  // Upsert one roster member into hub.json, keyed by `login`. Deep-merges the per-scope `roles` map so
100
115
  // scopes the caller did not name are preserved; sets `name`/`email` when given; validates the login
101
116
  // against the hub (warn-only — a miss flags `unverified`, `checked:false` skips silently). Creates the
@@ -485,14 +500,30 @@ export async function runSetup(root, opts = {}) {
485
500
  // Record git_url — doctor needs it to scope the auth probe (YAD-CFG-005) and the bridge/PR flow
486
501
  // needs it to open PRs. Derived from the origin remote already resolved above; null when local-only.
487
502
  const git_url = enabled ? ((remote.ok && remote.stdout.trim()) || null) : null;
488
- writeJSON(hubPath, { platform: enabled ? platform : null, git_url, bridge_enabled: enabled, bridge: enabled, default_branch, roster, solo, profile: { codebase, repo_layout, team_size } });
489
- ok(`wrote ${PROJECT_FILES.hubConfig} (${roster.length} reviewer(s)${solo ? ', solo mode' : ''})`);
503
+ // Merge into the existing file, never clobber: roster + verified_authors are user-owned identity
504
+ // data (the verified-commits gate's allowlist derives from them). A reconfigure that collects no
505
+ // reviewers (e.g. solo mode skips the loop) must NOT blank a populated roster or drop verified_authors.
506
+ // Read strict so a corrupt hub aborts here (YAD-STATE-001) rather than fail-open to `{}` and rewrite
507
+ // the file with identity stripped — the same silent-loss hole, just triggered by a parse failure.
508
+ const cur = readJSONStrict(hubPath, {}) || {};
509
+ const next = buildReconfiguredHub(cur, {
510
+ platform: enabled ? platform : null, git_url, bridge_enabled: enabled, bridge: enabled,
511
+ default_branch, roster, solo, profile: { codebase, repo_layout, team_size },
512
+ });
513
+ if (!roster.length && Array.isArray(cur.roster) && cur.roster.length) {
514
+ info(`kept existing roster (${cur.roster.length} member(s)) — reconfigure collected none`);
515
+ }
516
+ if (cur.verified_authors?.length) info(`preserved ${cur.verified_authors.length} verified_authors entry(ies)`);
517
+ writeJSON(hubPath, next);
518
+ ok(`wrote ${PROJECT_FILES.hubConfig} (${next.roster.length} reviewer(s)${solo ? ', solo mode' : ''})`);
490
519
  }
491
520
  // Persist the profile + solo flag even on the "keeping existing" path, so re-running setup with new
492
521
  // flags (e.g. `yad setup --solo`) updates the mode without a full reconfigure. Merge, never clobber.
493
522
  // Also backfill a missing git_url from origin here (idempotent repair for the doctor's YAD-CFG-005).
494
523
  if (exists(hubPath)) {
495
- const cur = readJSON(hubPath, {}) || {};
524
+ // Strict read for the same reason as the reconfigure write above: a corrupt hub must abort, never
525
+ // fail-open to `{}` and get rewritten with roster/verified_authors stripped on a plain re-run.
526
+ const cur = readJSONStrict(hubPath, {}) || {};
496
527
  const backfillUrl = (cur.platform && !cur.git_url)
497
528
  ? ((run('git', ['remote', 'get-url', 'origin'], { cwd: root }).stdout || '').trim() || null)
498
529
  : null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yadflow",
3
- "version": "3.5.0",
3
+ "version": "3.5.1",
4
4
  "description": "Yadflow — the gated, team, multi-repo SDLC: author → review → build with a PR-driven review gate and a zero-dependency `yad` CLI (setup, gate, commit, open-pr, ship, repo, thread, reconcile). A BMAD module + 37 yad-* skills.",
5
5
  "type": "module",
6
6
  "author": "AbdelRahman Nasr",