yadflow 3.5.0 → 3.5.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 +1 -11
- package/README.md +81 -18
- package/cli/setup.mjs +35 -4
- package/package.json +8 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
### Bug Fixes
|
|
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))
|
|
1
|
+
## [3.5.2](https://github.com/abdelrahmannasr/yadflow/compare/v3.5.1...v3.5.2) (2026-07-02)
|
|
12
2
|
|
|
13
3
|
# [2.2.0](https://github.com/abdelrahmannasr/yadflow/compare/v2.1.0...v2.2.0) (2026-06-14)
|
|
14
4
|
|
package/README.md
CHANGED
|
@@ -5,9 +5,17 @@
|
|
|
5
5
|
[](https://github.com/abdelrahmannasr/yadflow/blob/main/package.json)
|
|
6
6
|
[](https://abdelrahmannasr.github.io/yadflow/)
|
|
7
7
|
|
|
8
|
-
**A
|
|
8
|
+
**A governance layer for AI-assisted software engineering — a gated development lifecycle where
|
|
9
|
+
AI builds and a human clears every gate.**
|
|
9
10
|
*AI builds. The hand decides.* (*yad* — **يد**, Arabic for "hand".) On npm and GitHub as `yadflow`.
|
|
10
11
|
|
|
12
|
+
> **Not another coding assistant — the governance layer around the one you already use.**
|
|
13
|
+
> Yadflow doesn't write your code; it governs how AI-written code ships. Keep Cursor, GitHub Copilot,
|
|
14
|
+
> Claude Code, Continue — or hand-written commits. The zero-dependency `yad` CLI and the CI gates
|
|
15
|
+
> review the work **no matter who or what produced it.** The workflow skills run today in
|
|
16
|
+
> **Claude Code** (plus `.agents`, Zencoder, and OpenCode), and **BMAD is the default packaging,
|
|
17
|
+
> not a limitation.**
|
|
18
|
+
|
|
11
19
|
## The problem
|
|
12
20
|
|
|
13
21
|
AI writes code faster than any team can review it. Left ungoverned, that speed turns into risk:
|
|
@@ -18,8 +26,9 @@ AI, the harder it gets to keep control of quality, architecture, and accountabil
|
|
|
18
26
|
## What Yadflow is
|
|
19
27
|
|
|
20
28
|
Yadflow puts a **human gate on every step** of the lifecycle. Each step does its work, writes its
|
|
21
|
-
output to a plain file, and **waits** — it never advances until a human
|
|
22
|
-
a step has *earned* the right to auto-advance
|
|
29
|
+
output to a plain file, and **waits** — it never advances until a human clears its gate (by approving,
|
|
30
|
+
or in solo mode by merging your own PR), or, later, once a step has *earned* the right to auto-advance.
|
|
31
|
+
Reviews ride real PR/MRs; all state lives in files you
|
|
23
32
|
can read, diff, and edit — no database, nothing hidden. The result is a paper trail for every decision
|
|
24
33
|
and a hard wall between "AI proposed" and "we shipped it."
|
|
25
34
|
|
|
@@ -54,39 +63,93 @@ Every step stops at a gate until a human approves. New here? **Walk it lesson-by
|
|
|
54
63
|
[guided tutorial](https://abdelrahmannasr.github.io/yadflow/tutorial/)**, or read the
|
|
55
64
|
[team guide](TEAM-GUIDE.md).
|
|
56
65
|
|
|
66
|
+
## What `npx yadflow setup` installs
|
|
67
|
+
|
|
68
|
+

|
|
69
|
+
|
|
70
|
+
The wizard is idempotent and profile-driven (solo/team, greenfield/brownfield, monorepo/separate).
|
|
71
|
+
In one pass it produces:
|
|
72
|
+
|
|
73
|
+
- **The `yad` CLI** — zero-dependency Node (`setup`, `gate`, `commit`, `open-pr`, `ship`, `repo`,
|
|
74
|
+
`thread`, `reconcile`, `usage`, `doctor`), run via `npx` or a global install.
|
|
75
|
+
- **37 workflow skills** installed into your AI assistant — **Claude Code** (`.claude/`) first-class,
|
|
76
|
+
plus `.agents`, Zencoder, and OpenCode.
|
|
77
|
+
- **`.sdlc/` config** — the product hub, connected repos, reviewer roster, and tool connections
|
|
78
|
+
(design, testing, learning), all as plain JSON you can read and diff.
|
|
79
|
+
- **CI gates**, wired into every connected repo and the hub as **GitHub Actions or GitLab CI** —
|
|
80
|
+
spec-link, contract-check, verified-commits, build/test/lint, and the feature-thread gates, shipped
|
|
81
|
+
as CI-agnostic bash under `checks/`.
|
|
82
|
+
- **PR/MR templates** and an opt-in CodeRabbit config.
|
|
83
|
+
|
|
84
|
+
Your first `yad-epic` seeds the `epics/EP-<slug>/` ledger — state, approvals, and the contract lock —
|
|
85
|
+
so the audit trail starts the moment you begin real work.
|
|
86
|
+
|
|
87
|
+
## Your first five minutes
|
|
88
|
+
|
|
89
|
+
<!-- IMAGE: docs/media/artifact-waiting.png — "A generated epic waits at its gate — nothing advances until a human approves." -->
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
setup → AI drafts an artifact → ⛔ gate waits → you approve → next step → ⛔ gate waits → …
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
1. **`npx yadflow setup`** — the wizard installs skills, connects your repo, and wires the gates.
|
|
96
|
+
2. **Run `yad-epic`** in your assistant — it drafts the epic, then **stops** and writes it to a file.
|
|
97
|
+
3. **A gate waits.** Nothing advances until you review it.
|
|
98
|
+
4. **You approve** — file-only, or by merging the review PR/MR.
|
|
99
|
+
5. **The workflow continues** to the next step, which stops again.
|
|
100
|
+
|
|
101
|
+
Every step is the same contract: *AI proposes → a human decides → the trail is recorded.*
|
|
102
|
+
|
|
57
103
|
## How it works (in five points)
|
|
58
104
|
|
|
59
105
|
- **Front half = decide.** Once per epic, in the product hub: epic, architecture + a locked contract,
|
|
60
106
|
UI, stories, test cases. Always human-gated — nothing auto-advances.
|
|
61
107
|
- **Build half = build.** Once per story per code repo: spec → implement → checks → ship.
|
|
62
108
|
- **Every step stops at a gate.** A human moves it forward (file-only, or by merging a review PR/MR).
|
|
109
|
+
<!-- IMAGE: docs/media/pr-gate.png — "The review gate rides a real PR/MR: approve to advance, comment to block." -->
|
|
63
110
|
- **Automation is opt-in and earned.** A safe back-half step can earn auto-advance after it proves
|
|
64
111
|
itself — and a one-command kill switch reverts everything to manual. The engineer review and all
|
|
65
112
|
front states are never automatable.
|
|
66
113
|
- **Everything is files.** State, approvals, the contract lock, the build log — all plain files under
|
|
67
114
|
`epics/EP-<slug>/`. No database. The audit trail *is* the repo.
|
|
68
115
|
|
|
116
|
+
## Why not just use Cursor?
|
|
117
|
+
|
|
118
|
+
Because Yadflow lives in a different layer. Cursor, Claude Code, Copilot, Continue, Roo, and Cline
|
|
119
|
+
*generate* code. Yadflow *governs* what happens to it — review, architectural control, and an audit
|
|
120
|
+
trail — so you get AI speed without losing control of quality or accountability. They're
|
|
121
|
+
complementary: bring your favorite, and Yadflow wraps the engineering process around it.
|
|
122
|
+
|
|
123
|
+
| | Your AI assistant | **Yadflow** |
|
|
124
|
+
|---------------|--------------------------|------------------------------------------------------|
|
|
125
|
+
| **Layer** | Writes the code | Governs how it ships |
|
|
126
|
+
| **Output** | Diffs, completions | Gated artifacts + a file-based audit trail |
|
|
127
|
+
| **Answers** | "Write this for me" | "Should this merge — and who approved it?" |
|
|
128
|
+
| **Review** | You eyeball the diff | Human-gated PR/MR, contract lock, earned automation |
|
|
129
|
+
| **Fit** | Bring your own | Wraps around all of them |
|
|
130
|
+
|
|
69
131
|
## Review, made a pairing — and a lesson
|
|
70
132
|
|
|
71
133
|
Reviewing AI-generated code is where governance lives or dies, so Yadflow makes the honest review the
|
|
72
|
-
*easiest* path
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
growth in a **private, local-only** learning log (`yad status` rolls it up). It's
|
|
79
|
-
it never blocks a merge
|
|
80
|
-
|
|
134
|
+
*easiest* path. The **Review Companion** turns any PR/MR into a 60-second trailer, swipe-through cards,
|
|
135
|
+
and a grounded chat. **Pair Review** (`yad pair-review`) goes further: the AI walks you through the
|
|
136
|
+
change one risk-ordered stop at a time, explains each, then asks you about it — until both sides are
|
|
137
|
+
satisfied.
|
|
138
|
+
|
|
139
|
+
It doubles as a lesson: it teaches a transferable review method, scores you against it, and records
|
|
140
|
+
your review-skill growth in a **private, local-only** learning log (`yad status` rolls it up). It's
|
|
141
|
+
**soft and additive** — it never blocks a merge on its own, yet any genuine concern it surfaces blocks
|
|
142
|
+
like a normal review comment.
|
|
81
143
|
|
|
82
144
|
## Who it's for
|
|
83
145
|
|
|
84
|
-
Tech leads and engineering managers who want their team to move fast with AI
|
|
85
|
-
review, architectural control, or an audit trail — the governance layer around
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
146
|
+
Tech leads and engineering managers who want their team to move fast with AI-assisted development
|
|
147
|
+
**without** giving up review, architectural control, or an audit trail — the governance layer around
|
|
148
|
+
AI-assisted software engineering, not another code generator.
|
|
149
|
+
|
|
150
|
+
And because the audit trail *is* the repo, **`yad usage`** turns it into a per-member adoption &
|
|
151
|
+
behavior report (HTML/JSON/MD): who authored, reviewed, approved, and shipped, with factual
|
|
152
|
+
workflow-hygiene flags — derived read-only, so an EM can see how the team actually uses the flow.
|
|
90
153
|
|
|
91
154
|
## Documentation
|
|
92
155
|
|
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
|
-
|
|
489
|
-
|
|
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
|
-
|
|
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.
|
|
3
|
+
"version": "3.5.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",
|
|
@@ -52,7 +52,13 @@
|
|
|
52
52
|
"cli",
|
|
53
53
|
"spec-driven-development",
|
|
54
54
|
"learning",
|
|
55
|
-
"deeptutor"
|
|
55
|
+
"deeptutor",
|
|
56
|
+
"ai-governance",
|
|
57
|
+
"ai-code-review",
|
|
58
|
+
"ai-assisted-development",
|
|
59
|
+
"gated-workflow",
|
|
60
|
+
"code-review",
|
|
61
|
+
"software-delivery"
|
|
56
62
|
],
|
|
57
63
|
"devDependencies": {
|
|
58
64
|
"@eslint/js": "^10.0.1",
|