yadflow 3.4.1 → 3.4.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 +7 -1
- package/cli/doctor.mjs +22 -10
- package/cli/errors.mjs +1 -0
- package/cli/setup.mjs +12 -4
- package/package.json +1 -1
- package/skills/yad-connect-repos/references/hub-config.md +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
## [3.4.
|
|
1
|
+
## [3.4.2](https://github.com/abdelrahmannasr/yadflow/compare/v3.4.1...v3.4.2) (2026-07-01)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **doctor:** warn YAD-CFG-005 on hub.json missing git_url; stop misleading YAD-ENV-002 ([3f588af](https://github.com/abdelrahmannasr/yadflow/commit/3f588af2e01e117e661b08b5f5b8e069e41e887f))
|
|
7
|
+
* **setup:** write and backfill hub.json git_url from the origin remote ([c809358](https://github.com/abdelrahmannasr/yadflow/commit/c8093581319dcb9700b3dd0ebe930dbf784348ff))
|
|
2
8
|
|
|
3
9
|
# [2.2.0](https://github.com/abdelrahmannasr/yadflow/compare/v2.1.0...v2.2.0) (2026-06-14)
|
|
4
10
|
|
package/cli/doctor.mjs
CHANGED
|
@@ -76,13 +76,25 @@ export function projectChecks(checks, root) {
|
|
|
76
76
|
// platform CLI + auth (best-effort; auth probing is the user's own session)
|
|
77
77
|
const cli = cliFor(hub.platform);
|
|
78
78
|
if (cli) {
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
// git_url is required whenever a platform is set — doctor needs it to scope the auth probe
|
|
80
|
+
// and the bridge/PR flow needs it to open PRs. Warn on its absence directly (not on the
|
|
81
|
+
// resolved host), so it fires even when an origin remote can substitute: the field itself
|
|
82
|
+
// is required regardless.
|
|
83
|
+
if (!hostFromGitUrl(hub.git_url)) {
|
|
84
|
+
check(checks, 'hub-git-url', 'project', 'warn',
|
|
85
|
+
`${PROJECT_FILES.hubConfig} sets platform '${hub.platform}' but has no git_url [YAD-CFG-005]`,
|
|
86
|
+
'add git_url to hub.json (or re-run `yad setup`) — auth/PR checks need the hub host');
|
|
87
|
+
}
|
|
88
|
+
// Scope the auth probe to the hub's own host (derived from git_url, falling back to the
|
|
89
|
+
// origin remote). `${cli} auth status` without --hostname exits non-zero when ANY configured
|
|
90
|
+
// instance fails, so an unrelated stale login (e.g. a dead gitlab.com token) would falsely
|
|
91
|
+
// flag a working self-hosted hub — so we SKIP the probe entirely when no host resolves
|
|
92
|
+
// rather than run the flaky unscoped form.
|
|
93
|
+
const host = hostFromGitUrl(hub.git_url)
|
|
94
|
+
|| hostFromGitUrl(run('git', ['remote', 'get-url', 'origin'], { cwd: root }).stdout);
|
|
84
95
|
if (!has(cli)) check(checks, 'platform-cli', 'project', 'warn', `${cli} not found on PATH [YAD-ENV-002]`, `install ${cli} — the gate degrades to file-only without it`);
|
|
85
|
-
else if (!
|
|
96
|
+
else if (!host) check(checks, 'platform-cli', 'project', 'warn', 'auth check skipped — hub host unknown (no git_url / origin)', 'add git_url to hub.json so the auth probe can target the right host');
|
|
97
|
+
else if (!run(cli, ['auth', 'status', '--hostname', host]).ok) check(checks, 'platform-cli', 'project', 'warn', `${cli} present but not authenticated for ${host} [YAD-ENV-002]`, `run \`${cli} auth login --hostname ${host}\``);
|
|
86
98
|
else {
|
|
87
99
|
check(checks, 'platform-cli', 'project', 'ok', `${cli} present and authenticated`);
|
|
88
100
|
// Re-validate each roster login against the hub (warn-only). Skips when a login is already
|
|
@@ -99,10 +111,10 @@ export function projectChecks(checks, root) {
|
|
|
99
111
|
// probe a cheap api call (warn-only) to surface it before a sync silently holds the gate.
|
|
100
112
|
if (hub.platform === 'gitlab') {
|
|
101
113
|
// Scope the probe to the hub's own host (like the auth check above) so a multi-instance
|
|
102
|
-
// setup doesn't hit the wrong GitLab
|
|
103
|
-
|
|
104
|
-
if (!run('glab',
|
|
105
|
-
check(checks, 'gitlab-api', 'project', 'warn', `glab is authenticated but \`glab api\` failed
|
|
114
|
+
// setup doesn't hit the wrong GitLab. `host` is guaranteed truthy here (we skip the whole
|
|
115
|
+
// auth branch when it cannot be resolved), so the probe is always host-scoped.
|
|
116
|
+
if (!run('glab', ['api', 'version', '--hostname', host]).ok) {
|
|
117
|
+
check(checks, 'gitlab-api', 'project', 'warn', `glab is authenticated but \`glab api\` failed for ${host} [YAD-ENV-002]`, 'ensure the token has `api` scope — the gate reads MR approvals/discussions via the API');
|
|
106
118
|
}
|
|
107
119
|
}
|
|
108
120
|
// Solo + GitHub: a branch that "requires approvals" would block the solo dev's own merge
|
package/cli/errors.mjs
CHANGED
|
@@ -23,6 +23,7 @@ export const CODES = {
|
|
|
23
23
|
'YAD-CFG-002': 'design.json names an unknown design tool (expected one of config.yaml design.tools, or none)',
|
|
24
24
|
'YAD-CFG-003': 'testing.json names an unknown testing tool (expected one of config.yaml testing.tools, or none)',
|
|
25
25
|
'YAD-CFG-004': 'learning.json names an unknown learning tool (expected one of config.yaml learning.tools, or none)',
|
|
26
|
+
'YAD-CFG-005': 'hub.json sets a platform but is missing git_url (required to scope auth + open PRs)',
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
export const err = (code, message, hint) => new YadError(code, message, hint);
|
package/cli/setup.mjs
CHANGED
|
@@ -482,16 +482,24 @@ export async function runSetup(root, opts = {}) {
|
|
|
482
482
|
// `bridge_enabled` is the canonical flag (hub-config schema); keep the legacy `bridge` spelling
|
|
483
483
|
// for anything that still reads it.
|
|
484
484
|
const enabled = platform !== 'none';
|
|
485
|
-
|
|
485
|
+
// Record git_url — doctor needs it to scope the auth probe (YAD-CFG-005) and the bridge/PR flow
|
|
486
|
+
// needs it to open PRs. Derived from the origin remote already resolved above; null when local-only.
|
|
487
|
+
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 } });
|
|
486
489
|
ok(`wrote ${PROJECT_FILES.hubConfig} (${roster.length} reviewer(s)${solo ? ', solo mode' : ''})`);
|
|
487
490
|
}
|
|
488
491
|
// Persist the profile + solo flag even on the "keeping existing" path, so re-running setup with new
|
|
489
492
|
// flags (e.g. `yad setup --solo`) updates the mode without a full reconfigure. Merge, never clobber.
|
|
493
|
+
// Also backfill a missing git_url from origin here (idempotent repair for the doctor's YAD-CFG-005).
|
|
490
494
|
if (exists(hubPath)) {
|
|
491
495
|
const cur = readJSON(hubPath, {}) || {};
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
496
|
+
const backfillUrl = (cur.platform && !cur.git_url)
|
|
497
|
+
? ((run('git', ['remote', 'get-url', 'origin'], { cwd: root }).stdout || '').trim() || null)
|
|
498
|
+
: null;
|
|
499
|
+
if (cur.solo !== solo || JSON.stringify(cur.profile || {}) !== JSON.stringify({ codebase, repo_layout, team_size }) || backfillUrl) {
|
|
500
|
+
writeJSON(hubPath, { ...cur, ...(backfillUrl ? { git_url: backfillUrl } : {}), solo, profile: { codebase, repo_layout, team_size } });
|
|
501
|
+
if (backfillUrl) info(`backfilled hub git_url from origin: ${backfillUrl}`);
|
|
502
|
+
else info(`recorded profile: ${solo ? 'solo' : `team(${team_size})`}, ${codebase}, ${repo_layout}`);
|
|
495
503
|
}
|
|
496
504
|
}
|
|
497
505
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yadflow",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.2",
|
|
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",
|
|
@@ -16,7 +16,7 @@ login to an SDLC name + role. It is a single object for the hub itself — the s
|
|
|
16
16
|
```json
|
|
17
17
|
{
|
|
18
18
|
"platform": "github", // github | gitlab (from the hub's own remote host); null when local-only
|
|
19
|
-
"git_url": "https://github.com/abdelrahmannasr/yadflow.git",
|
|
19
|
+
"git_url": "https://github.com/abdelrahmannasr/yadflow.git", // REQUIRED when platform is non-null (scopes auth + opens PRs); yad doctor warns YAD-CFG-005 if absent
|
|
20
20
|
"default_branch": "main",
|
|
21
21
|
"bridge_enabled": true, // open review PRs/MRs on the hub for front-half reviews
|
|
22
22
|
"review": { "requireEngagement": false }, // Review Companion: false (soft) counts bare approves but nudges; true counts only verified-engagement approvals
|
|
@@ -69,6 +69,11 @@ run `git remote get-url origin` **on the hub itself** and read the host —
|
|
|
69
69
|
Auth is the **local user's own** `gh`/`glab`/git credentials; **no tokens are ever stored** (same rule
|
|
70
70
|
as the registry). `detect-hub` upserts `hub.json` in place — it is idempotent and safe to re-run.
|
|
71
71
|
|
|
72
|
+
**`git_url` is required whenever `platform` is non-null.** `yad doctor` uses it to scope the auth
|
|
73
|
+
probe to the hub's own host (an unscoped `glab auth status` fails on any unrelated broken instance),
|
|
74
|
+
and the bridge/PR flow uses it to open PRs. Doctor flags its absence with a warn (`YAD-CFG-005`);
|
|
75
|
+
re-running `yad setup` backfills it from the origin remote (idempotent, non-interactive).
|
|
76
|
+
|
|
72
77
|
## Bridge enable / degradation
|
|
73
78
|
|
|
74
79
|
- `bridge_enabled: true` **and** a non-null `platform` **and** `gh`/`glab` authenticated → the front-half
|