@sylad/cadence 1.8.0 → 1.9.0
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +23 -7
- package/agents/code-reviewer.md +2 -2
- package/agents/doc-keeper.md +19 -0
- package/agents/qa-reviewer.md +2 -2
- package/agents/spec-writer.md +1 -1
- package/agents/ux-reviewer.md +1 -1
- package/bin/cadence.js +9 -1
- package/dist/audit.js +14 -4
- package/dist/check.js +6 -0
- package/dist/cli.js +235 -30
- package/dist/config.js +101 -5
- package/dist/corrections.js +23 -2
- package/dist/deliver.js +78 -21
- package/dist/docsync.js +19 -3
- package/dist/git.js +16 -3
- package/dist/lead.js +37 -12
- package/dist/migrate.js +166 -0
- package/dist/orchestrate/briefs.js +28 -6
- package/dist/orchestrate/command.js +303 -34
- package/dist/orchestrate/cycle.js +720 -273
- package/dist/orchestrate/guard.js +2 -2
- package/dist/orchestrate/integrate.js +85 -0
- package/dist/orchestrate/launch.js +37 -5
- package/dist/orchestrate/mutex.js +30 -0
- package/dist/orchestrate/pool.js +74 -36
- package/dist/orchestrate/registry.js +123 -14
- package/dist/orchestrate/result.js +1 -1
- package/dist/orchestrate/snapshot.js +25 -0
- package/dist/orchestrate/spec.js +89 -5
- package/dist/orchestrate/state.js +42 -6
- package/dist/orchestrate/table.js +61 -2
- package/dist/orchestrate/timeouts.js +40 -0
- package/dist/orchestrate/worktree.js +368 -0
- package/dist/perf.js +80 -19
- package/dist/plan.js +92 -6
- package/dist/ready-free.js +109 -0
- package/dist/ref/add.js +116 -0
- package/dist/ref/check.js +338 -0
- package/dist/ref/command.js +78 -0
- package/dist/ref/corpus-render.js +83 -0
- package/dist/ref/corpus.js +201 -0
- package/dist/ref/evaluate.js +241 -0
- package/dist/ref/figures.js +179 -0
- package/dist/ref/measure.js +330 -0
- package/dist/ref/pdf.js +104 -0
- package/dist/ref/png.js +125 -0
- package/dist/ref/store.js +40 -0
- package/dist/ref/tools.js +51 -0
- package/dist/resources.js +51 -0
- package/dist/session.js +5 -2
- package/dist/state.js +60 -7
- package/dist/testgate.js +15 -0
- package/docs/cadence-hud.md +12 -0
- package/docs/cycle-vague-dark.svg +1 -1
- package/docs/cycle-vague-light.svg +1 -1
- package/docs/deliver.md +58 -3
- package/docs/fonctionnement-wave-dark.svg +1 -1
- package/docs/fonctionnement-wave-light.svg +1 -1
- package/docs/fonctionnement.md +5 -5
- package/docs/lead.md +35 -12
- package/docs/news.md +24 -1
- package/docs/orchestrate.md +230 -19
- package/docs/perf.md +13 -8
- package/docs/raf.md +89 -11
- package/docs/ref.md +316 -0
- package/docs/session.md +2 -2
- package/docs/skills.md +9 -2
- package/docs/spec.md +1 -1
- package/docs/stabilite.md +4 -4
- package/docs/whats-new.md +2 -0
- package/package.json +2 -1
- package/skills/deliver/SKILL.md +6 -1
- package/skills/lead/SKILL.md +24 -6
- package/skills/session-close/SKILL.md +1 -1
- package/skills/session-start/SKILL.md +2 -2
- package/templates/inventaire.json +96 -0
- package/templates/orchestrate/accept-back.md +1 -0
- package/templates/orchestrate/accept.md +1 -0
- package/templates/orchestrate/fiche.md +1 -0
- package/templates/orchestrate/fix-docs.md +18 -0
- package/templates/orchestrate/fix-minors.md +2 -1
- package/templates/orchestrate/fix.md +5 -2
- package/templates/orchestrate/implement.md +6 -3
- package/templates/orchestrate/maquette.md +2 -1
- package/templates/orchestrate/precheck.md +2 -1
- package/templates/orchestrate/review-recheck.md +2 -0
- package/templates/orchestrate/review-small.md +5 -1
- package/templates/orchestrate/review.md +2 -0
- package/templates/orchestrate/spec-back.md +2 -1
- package/templates/orchestrate/spec.md +4 -3
- package/templates/orchestrate/ux.md +3 -1
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
{
|
|
9
9
|
"name": "cadence",
|
|
10
10
|
"description": "Session start and close rituals driven by a versioned plan (raf), and deliveries proven by their effect. Needs the cadence CLI (npm i -g @sylad/cadence).",
|
|
11
|
-
"version": "1.
|
|
11
|
+
"version": "1.9.0",
|
|
12
12
|
"source": "./",
|
|
13
13
|
"author": {
|
|
14
14
|
"name": "Sylvain Ladoire"
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
{
|
|
18
18
|
"name": "cadence-hud",
|
|
19
19
|
"description": "A status band above the Claude Code prompt: context, 5 h / 7 d quota windows, cost per model, agents of the session and the running cadence orchestrate waves. Works without the cadence CLI, except the per-project plan progress, which needs `cadence` on the PATH.",
|
|
20
|
-
"version": "0.
|
|
20
|
+
"version": "0.5.0",
|
|
21
21
|
"source": "./plugins/cadence-hud",
|
|
22
22
|
"author": {
|
|
23
23
|
"name": "Sylvain Ladoire"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cadence",
|
|
3
3
|
"description": "A repo-native working method: session start and close rituals driven by a versioned plan (raf), deliveries proven by their effect, and three reviewer agents (UX, code, QA).",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.9.0",
|
|
5
5
|
"author": { "name": "Sylvain Ladoire" },
|
|
6
6
|
"homepage": "https://github.com/Sylad/cadence",
|
|
7
7
|
"repository": "https://github.com/Sylad/cadence",
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
A small working method that lives in your repository: a versioned plan linked to your commits, waves of fresh AI sessions driven by a program, and deliveries proved by their effect.
|
|
4
4
|
Solo developers and AI-assisted sessions lose track of *what is left to do* and *what each commit was for*; cadence keeps both in plain files next to the code.
|
|
5
5
|
**raf** is the plan, **news** the changelog with screenshots, **session** the facts to open and close a day, **deliver** waits for the CI, deploys, then checks the effect.
|
|
6
|
-
**orchestrate** runs a lot through spec, review, code and UX passes, each in its own session; the **lead** decides, re-verifies and delivers.
|
|
6
|
+
**orchestrate** runs a lot through spec, review, code and UX passes, each in its own session (with a short `TMPDIR` of its own, `<os tmpdir>/cadence-<hash>`, outside the repository and the wave's state folder, removed at the end of each pass of the lot; short because Chrome's Unix sockets live there and are limited to 107 characters); the **lead** decides, re-verifies and delivers. An **experimental** worktree mode (`orchestrate.worktrees: true` in `cadence.yaml`: independent lots of one repository in parallel, each in its own git worktree) is built but **refused**, on start and on `--resume`, without `CADENCE_EXPERIMENTAL_WORKTREES=1`; lots L299–L301 must be done before it is enabled ([docs/orchestrate.md](docs/orchestrate.md#one-worktree-per-lot-orchestrateworktrees-l279)).
|
|
7
7
|
Four [Claude Code](https://claude.com/claude-code) skills, three reviewer agents and a status-band plugin (`cadence-hud`) turn it into rituals.
|
|
8
8
|
|
|
9
9
|
<picture>
|
|
@@ -15,21 +15,35 @@ Four [Claude Code](https://claude.com/claude-code) skills, three reviewer agents
|
|
|
15
15
|
|
|
16
16
|
```sh
|
|
17
17
|
npm install -g @sylad/cadence # or: npx -p @sylad/cadence raf …
|
|
18
|
-
raf init #
|
|
18
|
+
raf init # .cadence/raf.yaml + .cadence/notes/ + a post-commit hook
|
|
19
|
+
# (a legacy docs/plan/raf.yaml is still read until moved: `raf migrate` moves it, see docs/raf.md)
|
|
19
20
|
raf add "My first lot" --estimate 1
|
|
20
21
|
```
|
|
21
22
|
|
|
22
|
-
Then `raf start L1`, commit with `feat(L1): …`, `raf now` to see where you are, `raf done L1` when it is finished.
|
|
23
|
+
Then `raf start L1`, commit with `feat(L1): …`, `raf now` to see where you are, `raf done L1` when it is finished. A title gone stale after a change of scope is replaced with `raf title L1 "new title"` (any status, the old one is kept in a dated note). A lot that occupies a resource shared between projects says so with `raf add --uses banc` or `raf uses L1 banc`, the folder's `cadence.yaml` lists the resources (`resources: [banc]`), and `raf check` refuses a name that is not declared ([docs/raf.md](docs/raf.md#shared-resources-uses-and-resources)); `cadence lead hold <label>` / `lead release <label>` declare the sessions the lead starts by hand so that they are subtracted from the free slots of `orchestrate --status` and `lead tour` ([docs/lead.md](docs/lead.md#lead-hold-and-release)); `cadence lead tour` and `orchestrate --continue` list, next to the free slots, the ready lots whose resources no `doing` lot (in any project sharing them, at every `depth:` of the declaring `cadence.yaml`) or live wave holds (`--json`: `free`); the `lead` skill reads that list again each time an agent comes back or a lot is blocked, before waiting).
|
|
24
|
+
|
|
25
|
+
## Install as a Claude Code plugin
|
|
26
|
+
|
|
27
|
+
The repository is its own [Claude Code](https://claude.com/claude-code) plugin marketplace. In a Claude Code session:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
/plugin marketplace add Sylad/cadence
|
|
31
|
+
/plugin install cadence@cadence # skills /cadence:session-start, session-close, deliver, lead + the three reviewer agents
|
|
32
|
+
/plugin install cadence-hud@cadence # the status band above the prompt
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The two plugins are independent. `cadence@cadence` carries the rituals, which call the **`cadence` CLI** (`raf`, `session`, `deliver`, …): install it too with `npm install -g @sylad/cadence`, the plugin does not bring it. `cadence-hud` works without the CLI; only its per-project plan progress needs `cadence` on the `PATH`. Without the plugin, `cadence skills install` copies the skills and agents into the repository. Details: [docs/skills.md](docs/skills.md) and [docs/cadence-hud.md](docs/cadence-hud.md).
|
|
23
36
|
|
|
24
37
|
## Where to read more
|
|
25
38
|
|
|
26
39
|
| Page | What it covers |
|
|
27
40
|
|---|---|
|
|
28
41
|
| [docs/raf.md](docs/raf.md) | the plan: commands, plan file, foreign plan formats, Gantt |
|
|
29
|
-
| [docs/orchestrate.md](docs/orchestrate.md) | waves of sessions: budgets, spec, accept and review steps, neighbouring repositories |
|
|
42
|
+
| [docs/orchestrate.md](docs/orchestrate.md) | waves of sessions: budgets, spec, accept and review steps, neighbouring repositories, one worktree per lot (experimental, not enabled: `orchestrate.worktrees: true` is refused until L299–L301 are done; `--integrate`, `--replay`, `--remove-worktree` belong to it, and a new wave of a lot handed back recovers its branch) |
|
|
30
43
|
| [docs/deliver.md](docs/deliver.md) | delivery: wait for CI, deploy, verify the effect |
|
|
31
44
|
| [docs/spec.md](docs/spec.md) | the screen and back-end sheets, `cadence spec check\|qa\|reseal` |
|
|
32
45
|
| [docs/lead.md](docs/lead.md) | the lead workflow and `cadence lead tour` |
|
|
46
|
+
| [docs/ref.md](docs/ref.md) | reference documents: `cadence ref add` (rendered pages, positioned text, images, figure index), `cadence ref measure` (colours, WCAG contrast, boxes, OCR, font size), `cadence ref check` (the inventory schema, `templates/inventaire.json`), `cadence ref eval` (recall, precision, false « read », tokens per page against a known inventory) and `cadence ref corpus` (the synthetic corpus with a known truth, rendered by Playwright) |
|
|
33
47
|
| [docs/stabilite.md](docs/stabilite.md) | what is guaranteed from 1.0.0 and what is not |
|
|
34
48
|
|
|
35
49
|
Also: [news](docs/news.md) (changelog, UX, code and QA reviews, documentation that follows the code), [session](docs/session.md), [corrections](docs/corrections.md), [perf](docs/perf.md), [skills and agents](docs/skills.md), [cadence-hud](docs/cadence-hud.md), [releasing](docs/releasing.md), [overview](docs/overview.md), [how it all works](docs/fonctionnement.md) (four figures).
|
|
@@ -39,10 +53,11 @@ Also: [news](docs/news.md) (changelog, UX, code and QA reviews, documentation th
|
|
|
39
53
|
|
|
40
54
|
- **raf** (French *reste à faire*, "what is left to do"): the plan, linked to your commits by the lot id in the message, computed from `git log` and never stored.
|
|
41
55
|
- **news**: a user-facing changelog with screenshots, tied to the plan; a lot is not done until its entry is written.
|
|
42
|
-
- **session**: `session start` and `session close` gather the facts of a work session.
|
|
43
|
-
- **deliver**: wait for the CI of the pushed commit, run the deploy commands, then **verify the effect**; a delivery is done only when its checks pass. A failed delivery is logged as a *red delivery
|
|
56
|
+
- **session**: `session start` and `session close` gather the facts of a work session (each lot in progress shows its commit count, `0 commit` included, next to its last activity).
|
|
57
|
+
- **deliver**: wait for the CI of the pushed commit, run the deploy commands, then **verify the effect**; a delivery is done only when its checks pass. A failed delivery is logged as a *red delivery* with its class (refusal, CI, deploy, check) and the last lines of the failing command's output. While a wave runs, `cadence deliver --sha <sha>` is accepted when no commit of the sha belongs to a lot that is not ready, so a ready lot ships while the wave runs.
|
|
58
|
+
- **auto-verification** (L236): before it reports, an `implement` or `fix` session re-reads the complete diff of its lot (of its fix commits, in `fix`) against the grid of the `code-reviewer` (code bug, architecture drift, architecture documentation, edge cases, one test per changed behaviour), fixes what it finds and writes an « auto-vérification » paragraph in its report; the measure is `cadence corrections --classify` and the share right the first time of `cadence perf`.
|
|
44
59
|
- **perf**: `cadence perf` is the dashboard of the workflow (speed next to quality, `⚠` on a trend), including the red deliveries and the blocking QA findings; `cadence lead tour` opens with its *perf header*, one line per `⚠`, nothing when stable ([docs/perf.md](docs/perf.md)).
|
|
45
|
-
|
|
60
|
+
- **doc-keeper** (L306): a generic agent that reads the diff of a lot and the project's map of documents (`docs.sync`, README, `docs/`, CHANGELOG, news), says which documents must change and updates them (or only lists them, read-only); `cadence orchestrate` calls it before the review when `docs.sync` reports a document behind the lot, the lead by hand; a document outside the repository only through the `docs.articles` key of the project's `cadence.yaml` (it then proposes a lot, never writes it) ([docs/news.md](docs/news.md#the-librarian-doc-keeper)).
|
|
46
61
|
Reviews are opt-in gates: `ux-reviewer` (no user-facing change is done before its usability review), `code-reviewer` (no lot with commits is done before its code review) and `qa-reviewer`, which walks the delivered app in a real browser.
|
|
47
62
|
|
|
48
63
|
</details>
|
|
@@ -51,6 +66,7 @@ Reviews are opt-in gates: `ux-reviewer` (no user-facing change is done before it
|
|
|
51
66
|
|
|
52
67
|
Two lines per version; the long form is in [docs/whats-new.md](docs/whats-new.md) and the full history, with dates, in [CHANGELOG.md](CHANGELOG.md).
|
|
53
68
|
|
|
69
|
+
- **1.9.0**: the plan lives at `.cadence/raf.yaml` (`raf migrate`); `cadence ref` reads reference documents; `doc-keeper` agent, `orchestrate.testGate`, `cadence lead hold` shown by `cadence-hud`.
|
|
54
70
|
- **1.8.0**: `cadence perf` shows the speed of the workflow next to its quality (cost in euros per delivered lot, red deliveries, blocking QA findings), and `cadence lead tour` opens with a perf header.
|
|
55
71
|
- **1.7.0**: `cadence orchestrate` no longer replays `accept` on a green sealed acceptation and refuses `--resume --dry-run`; `spec reseal --porteur` accepts a sheet amended by a delivered lot; the README becomes a short home page.
|
|
56
72
|
- **1.6.0**: the mockup review sweeps everything in its first report and runs up to `orchestrate.maquetteReviews` times (3 by default); the acceptance lock names the first offending commit.
|
package/agents/code-reviewer.md
CHANGED
|
@@ -21,8 +21,8 @@ fact. If the path or the id is missing, or the lot has no commit to review, say
|
|
|
21
21
|
folder's CLAUDE.md does not count unless it names this project. Then find the commands that
|
|
22
22
|
test, type-check, lint and build: in the README, then in the manifest (`package.json` scripts,
|
|
23
23
|
Makefile, `pyproject.toml`…).
|
|
24
|
-
2. **Read the lot**: its title, notes and sub-tasks in the plan (`docs/plan/raf.yaml`, or the file
|
|
25
|
-
named by `plan:` in `cadence.yaml`). That is the goal the commits are measured against. When the
|
|
24
|
+
2. **Read the lot**: its title, notes and sub-tasks in the plan (`.cadence/raf.yaml`, the legacy `docs/plan/raf.yaml`, or the file
|
|
25
|
+
named by `plan:` in `cadence.yaml`). That is the goal the commits are measured against. When the brief gives a "Goal of the lot", that goal of the lot given in the brief takes precedence over the title in the plan (a title can be stale; the goal was given on purpose): measure the commits against it, not against the title. When the
|
|
26
26
|
lot has only a title, also read the bodies of its commits and any spec the lot cites.
|
|
27
27
|
3. **Get the commits from the tool**: `raf commits <id>` prints exactly the set the gate counts —
|
|
28
28
|
`<sha> <subject>` per line, oldest first, the commits that only touch the plan left out. Only
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: doc-keeper
|
|
3
|
+
description: Generic librarian. For one repository and one lot, reads the diff of the lot and the project's map of documents (docs.sync of cadence.yaml, README, docs/, CHANGELOG, Nouveautés), says which documents must change, then updates them (writing session) or only lists them (read-only session). A document outside the repository only when the configuration names it (docs.articles), and then it proposes a lot for that repository's plan and never writes it. Called by orchestrate when docs.sync reports a document behind the lot, or by the lead by hand.
|
|
4
|
+
tools: Read, Write, Edit, Grep, Glob, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You keep the documentation of one repository true to the work of one lot. You write documents; you never write the code of the lot.
|
|
8
|
+
|
|
9
|
+
Follow the brief you are given. The method:
|
|
10
|
+
|
|
11
|
+
1. **Read the diff of the lot.** The commits that cite the lot (`git log`, then `git show <sha>` for each; never a `git diff` range, which would take in the commits of other lots). Note what the change makes true or false for a reader: a behaviour, a command, a key, a default, a name, a file.
|
|
12
|
+
2. **Draw the map of the documents.** The `docs.sync` rules of the project's `cadence.yaml` (the code paths and the documents they call for), then what the project keeps besides: the README, the pages of `docs/`, the CHANGELOG, the Nouveautés / What's new entries, the architecture document. Read the project's CLAUDE.md first for its own rules on documentation. Nothing about a folder or a machine comes from you: only this project's files.
|
|
13
|
+
3. **Say which documents must change, and why.** For each: the file, the passage, the sentence that the diff makes false or leaves out. A document the diff does not touch the truth of is not listed.
|
|
14
|
+
4. **Act according to the session.**
|
|
15
|
+
- Writing session: update each document, in the language and the style it already has. Test the project's documentation checks if it has any (links, doc tests). Commit as soon as a document is right, with explicit paths (never `git add -A` or `commit -a`) and a message that cites the lot (`docs(<lot>): …`). A CHANGELOG or Nouveautés entry only if the project keeps one for this kind of change.
|
|
16
|
+
- Read-only session (no write tool, or a brief that says read-only): change nothing; list the documents of step 3 with the passage to write, ready to be applied by someone else.
|
|
17
|
+
5. **A document outside the repository** is yours only when the configuration says so: the brief then lists the entries of `docs.articles` (the cadence.yaml of the project: « this project is also described by this file of that repository », with the absolute path of the repository, open to you for reading). Never guess such a file, never go looking for one. Do not edit it, and never write to the plan of that repository (no `raf add`, no edit of its plan file): write a proposed lot instead — a title and a body that name the repository, the file, the passage and the sentence to change — and put it in the `resume` of your report, starting with « lot proposé ». The lead decides whether it enters that repository's plan.
|
|
18
|
+
|
|
19
|
+
Never push, deliver, or run `raf done|start|note|review|ux`. Never run `git checkout` or `git switch` to another commit or branch in this repository. Do not launch subagents. Do not stop to ask: an interpretation you settle yourself goes under "choix" with the alternative you did not take. A document you could not check against the code goes under "nonVerifie". Give the report in the structured output the brief asks for.
|
package/agents/qa-reviewer.md
CHANGED
|
@@ -107,7 +107,7 @@ a delivery rarely changes them all:
|
|
|
107
107
|
- the pages that call the changed endpoints (`raf commits <id>` and the diff tell which routes
|
|
108
108
|
changed; the `api:` lines of the expectations, and the calls you see a page make, tell which
|
|
109
109
|
pages use them);
|
|
110
|
-
- the pages of the screens the lot changed (
|
|
110
|
+
- the pages of the screens the lot changed (the goal of the lot given in the brief takes precedence over the title in the plan; then its notes in the plan, and
|
|
111
111
|
the components in its commits, name them);
|
|
112
112
|
- the home page.
|
|
113
113
|
|
|
@@ -165,7 +165,7 @@ A short report:
|
|
|
165
165
|
(/players shows no player)", "no expectations file: 13 pages walked, 1 defect, 8 suspects, draft
|
|
166
166
|
returned". It is the last line of the report.
|
|
167
167
|
|
|
168
|
-
Give screenshots and snapshots a
|
|
168
|
+
Give screenshots and snapshots the absolute path of the capture directory your brief names when it names one (a wave's Playwright server resolves a bare name against the repository, not its output directory); with no such directory in the brief, a path under `.playwright-mcp/` (e.g. `.playwright-mcp/page-home.png`: the Playwright MCP resolves a bare file name against the repository, where it would land at the root and dirty the working tree) and no other path inside the repository (list them in the report if git does not ignore that folder). Other temporary files go in a temporary directory outside the repository, or in the one
|
|
169
169
|
the caller names; remove them, or list their paths in the report — except the QA browser profile, which is kept for the next pass. The working tree is left as you
|
|
170
170
|
found it.
|
|
171
171
|
|
package/agents/spec-writer.md
CHANGED
|
@@ -10,7 +10,7 @@ Follow the brief you are given. The method:
|
|
|
10
10
|
|
|
11
11
|
1. **Read the charter first.** The project's CLAUDE.md, its CSS and variables, the neighbouring components and pages, `docs/qa/expectations.md`, the routes and API contracts already present. The mockup must look like the product: reuse what exists, invent nothing when an equivalent exists.
|
|
12
12
|
2. **List the states before drawing**: empty, loading, error, and loaded when there is data. Each is an addressable section `#etat-<état>` of one static `maquette.html` (HTML + CSS, no business JavaScript). Each field of the sheet carries `data-testid="<field id>"`.
|
|
13
|
-
3. **Render and look.** Capture each state at **1440 px** and **390 px** wide with the browser tool (Playwright),
|
|
13
|
+
3. **Render and look.** Capture each state at **1440 px** and **390 px** wide with the browser tool (Playwright), named `maquette-<état>-<largeur>.png`, with the absolute capture-directory path your brief gives in front of the name (a bare name lands in the repository), and look at every capture before keeping it: a mockup you did not look at is not checked. Copy the kept captures into the spec folder.
|
|
14
14
|
Before keeping a state, check its sample data: compute the weekday of every date shown (`date -d`), never write it from memory.
|
|
15
15
|
4. **Write the sheet** in the format of the template of the brief, and run `cadence spec check` on it until it passes. Every rule is `sourcee` (say where it comes from) or `hypothese` (say what would change if it were wrong, in `si_faux`). Never dress a guess as a source.
|
|
16
16
|
5. **Costly choices are questions.** If a rule would fix a data model or storage, a public or shared API contract or an already published route, a destructive or irreversible action, or contradict an existing sourced rule, do not write it as a hypothesis: stop and ask, in the `questions` of the report. Wording, field order, the error state and spacing are written hypotheses.
|
package/agents/ux-reviewer.md
CHANGED
|
@@ -38,7 +38,7 @@ When the brief says "conformity" (the orchestrator, after the code, for a lot th
|
|
|
38
38
|
|
|
39
39
|
1. **Look before judging.** Capture the screen with the browser tool available (Playwright or
|
|
40
40
|
equivalent) at **1440 px** and **390 px** wide, in its main states: empty, loaded, error, loading,
|
|
41
|
-
and the key interaction. Look at every capture. Give screenshots and snapshots a
|
|
41
|
+
and the key interaction. Look at every capture. Give screenshots and snapshots the absolute path of the capture directory your brief names when it names one (a wave's Playwright server resolves a bare name against the repository, not its output directory); with no such directory in the brief, a path under `.playwright-mcp/` (e.g. `.playwright-mcp/page-home.png`: the Playwright MCP resolves a bare file name against the repository, where it would land at the root and dirty the working tree) and no other path inside the repository (list them in the report if git does not ignore that folder). Anything else you create goes in a temporary directory outside the repository, removed afterwards.
|
|
42
42
|
2. **Walk the main task** a real user comes for (find, read, compare, act, undo) and count the steps.
|
|
43
43
|
3. **Check, and measure where a number exists:**
|
|
44
44
|
- Nielsen's 10 heuristics — especially visibility of system status, match with the user's words,
|
package/bin/cadence.js
CHANGED
|
@@ -13,7 +13,7 @@ const io = {
|
|
|
13
13
|
|
|
14
14
|
if (tool === 'raf') {
|
|
15
15
|
process.exitCode = await run(args, io);
|
|
16
|
-
} else if (['news', 'session', 'deliver', 'verify', 'skills', 'orchestrate', 'lead', 'corrections', 'perf', 'spec'].includes(tool)) {
|
|
16
|
+
} else if (['news', 'session', 'deliver', 'verify', 'skills', 'orchestrate', 'lead', 'corrections', 'perf', 'spec', 'ref'].includes(tool)) {
|
|
17
17
|
process.exitCode = await run([tool, ...args], io);
|
|
18
18
|
} else if (tool === '--version' || tool === '-v') {
|
|
19
19
|
const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
@@ -33,6 +33,12 @@ if (tool === 'raf') {
|
|
|
33
33
|
cadence deliver [--dry-run] [--sha rév] [--config cadence.yaml] [-- arguments du script du projet]
|
|
34
34
|
CI du sha poussé → déploiement → vérifications de l'effet ;
|
|
35
35
|
ou le script de livraison du projet (deliver.script), sous verrou et journal
|
|
36
|
+
cadence ref add <document.pdf> [--sections 3-5,9] [--slug nom]
|
|
37
|
+
enregistre un document de référence hors du dépôt : pages rendues, texte positionné, images, index des figures
|
|
38
|
+
et des passages qui les citent ; exige poppler, ImageMagick et tesseract (outil absent nommé avec sa commande, code 2)
|
|
39
|
+
cadence ref measure <slug> <page> <page | x,y | x,y,l,h> [--quoi couleurs|contraste|boites|texte] [--largeur 1440] [--json]
|
|
40
|
+
mesure une zone d'une page rendue : couleurs, contraste WCAG 2.2, boîtes, mots OCR et taille de police estimée,
|
|
41
|
+
ramenés à 1440 px de large, tolérance déclarée
|
|
36
42
|
cadence verify [--retry secondes] [--sha rév]
|
|
37
43
|
rejoue les vérifications d'effet (deliver.verify) hors livraison, une passe, en parallèle ;
|
|
38
44
|
code 0 tout vert, 1 un effet rouge, 2 rien à vérifier ; « session start » la lance aussi
|
|
@@ -41,6 +47,8 @@ if (tool === 'raf') {
|
|
|
41
47
|
--max-sessions : sessions simultanées, toutes vagues confondues (CADENCE_MAX_SESSIONS)
|
|
42
48
|
--continue [--until HH:MM] [--priority a,b] : tire seul les lots prêts du plan, jusqu'à une borne
|
|
43
49
|
--waits [--since AAAA-MM-JJ] : l'attente de créneau de session par jour et par vague, lue dans les journaux
|
|
50
|
+
cadence lead hold <étiquette> [--ttl minutes] | lead release <étiquette>
|
|
51
|
+
déclare, puis rend, une session lancée à la main par le lead : soustraite des créneaux libres
|
|
44
52
|
cadence lead tour [dossier] [--idle 3] [--json]
|
|
45
53
|
le tableau du lead, sans modèle : une ligne par sous-dossier qui a un plan, ou la ligne du dossier courant
|
|
46
54
|
s'il est lui-même un projet ; une première ligne « cadence.yaml · ✗ erreur » si priority: est illisible
|
package/dist/audit.js
CHANGED
|
@@ -4,19 +4,29 @@ import { check } from './check.js';
|
|
|
4
4
|
import { parse } from 'yaml';
|
|
5
5
|
import { changedFiles, fileAt, readCommits } from './git.js';
|
|
6
6
|
import { citedRefs, linkCommits, scopeOf } from './link.js';
|
|
7
|
-
import { readDocsConfig, readNewsConfig, readOrchestrateConfig } from './config.js';
|
|
7
|
+
import { PLAN_DEFAULT, PLAN_LEGACY, readDocsConfig, readNewsConfig, readOrchestrateConfig } from './config.js';
|
|
8
8
|
import { ficheHypotheses } from './spec.js';
|
|
9
9
|
import { docSyncGaps, filesOf, gapMessage } from './docsync.js';
|
|
10
10
|
import { loadEntries, newsIssues, PUBLIC_TITLE_DEFAULT, publicTitleTooLong, reusedNewsTitle } from './news.js';
|
|
11
11
|
import { isRecurring } from './recurring.js';
|
|
12
|
+
import { resourceIssues } from './resources.js';
|
|
12
13
|
import { escapeRe, isOpen } from './plan.js';
|
|
13
14
|
/** Chemin de la configuration lue, relatif à la racine : celui de --config, sinon cadence.yaml. */
|
|
14
15
|
function configRel(plan, root) {
|
|
15
16
|
return plan.configFile ? relative(root, plan.configFile) : 'cadence.yaml';
|
|
16
17
|
}
|
|
17
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Le plan, sa page Gantt, la configuration lue (cadence.yaml) et les fichiers tenus avec lui (plan.files). Le plan par défaut
|
|
20
|
+
* (.cadence/raf.yaml) compte aussi son emplacement hérité docs/plan/ : après le `git mv` proposé par raf, les anciens commits du
|
|
21
|
+
* plan et le commit du déplacement (qui liste la suppression et l'ajout) restent des commits de plan seul (L246, fiche plan-dossier-cache R12).
|
|
22
|
+
*/
|
|
18
23
|
export function ownFiles(plan, root) {
|
|
19
|
-
|
|
24
|
+
const own = new Set([relative(root, plan.path), relative(root, join(dirname(plan.path), 'gantt.html')), configRel(plan, root), ...plan.maintained]);
|
|
25
|
+
if (relative(root, plan.path) === PLAN_DEFAULT) {
|
|
26
|
+
own.add(PLAN_LEGACY);
|
|
27
|
+
own.add(join(dirname(PLAN_LEGACY), 'gantt.html'));
|
|
28
|
+
}
|
|
29
|
+
return own;
|
|
20
30
|
}
|
|
21
31
|
function withoutPlanKey(text) {
|
|
22
32
|
if (text === null)
|
|
@@ -160,7 +170,7 @@ export function audit(plan, root, newsDir, today, opts = {}) {
|
|
|
160
170
|
const m = l.public ? publicTitleTooLong(l.public, max) : reused ? publicTitleTooLong(reused, max) : null;
|
|
161
171
|
return m ? [{ message: `${l.id} : ${reused && !l.public ? m.replace('titre public', 'titre public repris de la Nouveauté') : m}` }] : [];
|
|
162
172
|
});
|
|
163
|
-
const issues = [...check(lots, { ...linked, byLot: all.byLot }, today, opts.idle ?? 7), ...newsIssues(lots, entries, newsDir, hypothesesOf(root, plan.configFile ?? join(root, 'cadence.yaml'))), ...titles, ...gates, ...docSyncIssues(plan, root, all.byLot), ...(plan.hasPublicField ? missingPublicTitles(lots, entries) : []),
|
|
173
|
+
const issues = [...check(lots, { ...linked, byLot: all.byLot }, today, opts.idle ?? 7), ...newsIssues(lots, entries, newsDir, hypothesesOf(root, plan.configFile ?? join(root, 'cadence.yaml'))), ...titles, ...gates, ...docSyncIssues(plan, root, all.byLot), ...resourceIssues(lots, root), ...(plan.hasPublicField ? missingPublicTitles(lots, entries) : []),
|
|
164
174
|
...plan.ignore.invalid.map((src) => ({ message: `ignore : motif invalide « ${src} »` }))];
|
|
165
175
|
// Un plan en lecture seule se corrige avec l'outil du projet : ne pas conseiller une commande raf qui refuserait.
|
|
166
176
|
return plan.readonly ? issues.map((i) => ({ ...i, message: i.message.replace(/ — raf (start|public) .*$/, '') })) : issues;
|
package/dist/check.js
CHANGED
|
@@ -3,6 +3,8 @@ import { isOpen } from './plan.js';
|
|
|
3
3
|
import { isRecurring } from './recurring.js';
|
|
4
4
|
/** Un commit sur une ligne : sha abrégé et sujet. */
|
|
5
5
|
export const short = (c) => `${c.sha.slice(0, 7)} ${c.subject}`;
|
|
6
|
+
/** Titre d'un lot de revue UX planifiée : « Revue UX — <écran> ». */
|
|
7
|
+
const UX_REVIEW_TITLE = /^revue ux\s+—/i;
|
|
6
8
|
export function check(lots, linked, today, idleDays = 7) {
|
|
7
9
|
const issues = [];
|
|
8
10
|
const ids = new Set(lots.map((l) => l.id));
|
|
@@ -30,6 +32,10 @@ export function check(lots, linked, today, idleDays = 7) {
|
|
|
30
32
|
issues.push({ kind: 'done-open-tasks', message: `${lot.id} terminé avec sous-tâche(s) ouverte(s) : ${open.map((t) => t.id).join(', ')}` });
|
|
31
33
|
}
|
|
32
34
|
}
|
|
35
|
+
// L271 : sans visible:, le lot ne passe par aucune étape UX d'orchestrate (precheck → implement → review) et la revue de l'écran n'a pas lieu.
|
|
36
|
+
if (isOpen(lot.status) && UX_REVIEW_TITLE.test(lot.title) && !lot.visible) {
|
|
37
|
+
issues.push({ kind: 'ux-review-not-visible', message: `${lot.id} est une revue UX (« ${lot.title.slice(0, 60)} ») sans visible: — l'étape UX n'aurait pas lieu : poser visible: true dans le plan (raf visible ${lot.id} on, ou raf add --visible pour un nouveau lot)` });
|
|
38
|
+
}
|
|
33
39
|
for (const p of lot.problems)
|
|
34
40
|
issues.push({ kind: 'bad-field', message: `${lot.id} : ${p}` });
|
|
35
41
|
for (const d of lot.after) {
|