@cloverleaf/reference-impl 0.3.1 → 0.4.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/.claude-plugin/plugin.json +18 -0
- package/VERSION +1 -1
- package/config/affected-routes.json +6 -8
- package/config/qa-rules.json +3 -13
- package/config/ui-paths.json +6 -1
- package/config/ui-review.json +18 -0
- package/dist/affected-routes.mjs +1 -1
- package/dist/axe-dedupe.mjs +42 -0
- package/dist/cli.mjs +32 -1
- package/dist/feedback.mjs +1 -1
- package/dist/plugin-path.mjs +19 -0
- package/dist/qa-report.mjs +65 -0
- package/dist/qa-rules.mjs +1 -1
- package/dist/route-slug.mjs +23 -0
- package/dist/ui-paths.mjs +1 -1
- package/dist/ui-review-config.mjs +41 -0
- package/dist/visual-diff.mjs +62 -0
- package/install.sh +30 -44
- package/lib/affected-routes.ts +1 -1
- package/lib/axe-dedupe.ts +64 -0
- package/lib/cli.ts +32 -1
- package/lib/feedback.ts +8 -1
- package/lib/plugin-path.ts +21 -0
- package/lib/qa-report.ts +77 -0
- package/lib/qa-rules.ts +1 -1
- package/lib/route-slug.ts +21 -0
- package/lib/ui-paths.ts +1 -1
- package/lib/ui-review-config.ts +62 -0
- package/lib/visual-diff.ts +97 -0
- package/package.json +8 -3
- package/prompts/qa.md +21 -0
- package/prompts/ui-reviewer.md +90 -39
- package/skills/{cloverleaf-document.md → cloverleaf-document/SKILL.md} +2 -2
- package/skills/{cloverleaf-implement.md → cloverleaf-implement/SKILL.md} +3 -3
- package/skills/{cloverleaf-merge.md → cloverleaf-merge/SKILL.md} +26 -5
- package/skills/{cloverleaf-new-task.md → cloverleaf-new-task/SKILL.md} +20 -3
- package/skills/{cloverleaf-qa.md → cloverleaf-qa/SKILL.md} +26 -11
- package/skills/{cloverleaf-review.md → cloverleaf-review/SKILL.md} +18 -8
- package/skills/{cloverleaf-ui-review.md → cloverleaf-ui-review/SKILL.md} +37 -20
- /package/skills/{cloverleaf-run.md → cloverleaf-run/SKILL.md} +0 -0
|
@@ -21,7 +21,7 @@ description: Run the Documenter agent on a task in the `implementing` state (ful
|
|
|
21
21
|
|
|
22
22
|
2. Load the task:
|
|
23
23
|
```
|
|
24
|
-
|
|
24
|
+
cloverleaf-cli load-task <repo_root> <TASK-ID>
|
|
25
25
|
```
|
|
26
26
|
Verify `status === "implementing"`. Verify `risk_class === "high"`. If either check fails, report and stop.
|
|
27
27
|
|
|
@@ -36,7 +36,7 @@ description: Run the Documenter agent on a task in the `implementing` state (ful
|
|
|
36
36
|
5. Dispatch the Documenter subagent via the Task tool:
|
|
37
37
|
- `subagent_type`: `general-purpose`
|
|
38
38
|
- `model`: `sonnet`
|
|
39
|
-
- Prompt: contents of
|
|
39
|
+
- Prompt: contents of `$(cloverleaf-cli plugin-root)/prompts/documenter.md` with substitutions:
|
|
40
40
|
- `{{task}}` → full task JSON (pretty-printed)
|
|
41
41
|
- `{{diff}}` → diff output
|
|
42
42
|
- `{{branch}}` → `cloverleaf/<TASK-ID>`
|
|
@@ -13,20 +13,20 @@ The user has invoked this skill with a TASK-ID (e.g., `DEMO-001`).
|
|
|
13
13
|
|
|
14
14
|
2. Load the task:
|
|
15
15
|
```
|
|
16
|
-
|
|
16
|
+
cloverleaf-cli load-task <repo_root> <TASK-ID>
|
|
17
17
|
```
|
|
18
18
|
Parse the JSON. Verify `status === "pending"` OR `status === "implementing"` (the second case is a re-run after a Reviewer bounce). If neither, report the current status and ask the user to use the correct command for that state.
|
|
19
19
|
|
|
20
20
|
3. Load any outstanding feedback:
|
|
21
21
|
```
|
|
22
|
-
|
|
22
|
+
cloverleaf-cli latest-feedback <repo_root> <TASK-ID>
|
|
23
23
|
```
|
|
24
24
|
Capture the output. If present and the latest verdict is `bounce`, pass it into the subagent.
|
|
25
25
|
|
|
26
26
|
4. Dispatch the Implementer subagent via the Task tool:
|
|
27
27
|
- `subagent_type`: `general-purpose`
|
|
28
28
|
- `model`: `sonnet`
|
|
29
|
-
- Prompt: the contents of
|
|
29
|
+
- Prompt: the contents of `$(cloverleaf-cli plugin-root)/prompts/implementer.md`, with placeholders substituted:
|
|
30
30
|
- `{{task}}` → the full task JSON (pretty-printed)
|
|
31
31
|
- `{{feedback}}` → the feedback JSON if present, else the literal string `null`
|
|
32
32
|
- `{{repo_root}}` → absolute path to the current repo
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cloverleaf-merge
|
|
3
|
-
description: Human gate for merging a Cloverleaf task. Branches on state — from `automated-gates` (fast lane) via `human_merge`, or from `final-gate` (full pipeline) via `final_approval_gate`. Requires explicit user confirmation. Usage — /cloverleaf-merge <TASK-ID>.
|
|
3
|
+
description: Human gate for merging a Cloverleaf task. Branches on state — from `automated-gates` (fast lane) via `human_merge`, or from `final-gate` (full pipeline) via `final_approval_gate`. For full-pipeline tasks, performs a real `git merge --no-ff` of the feature branch into main before advancing state. Requires explicit user confirmation. Usage — /cloverleaf-merge <TASK-ID>.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Cloverleaf — merge
|
|
@@ -53,18 +53,39 @@ description: Human gate for merging a Cloverleaf task. Branches on state — fro
|
|
|
53
53
|
|
|
54
54
|
3B.3. On explicit `y`:
|
|
55
55
|
- `cloverleaf-cli emit-gate-decision <repo_root> <TASK-ID> final_approval_gate approve human`
|
|
56
|
-
-
|
|
57
|
-
|
|
56
|
+
- Verify we are on main with a clean working tree:
|
|
57
|
+
```bash
|
|
58
|
+
cd <repo_root>
|
|
59
|
+
git checkout main
|
|
60
|
+
git status
|
|
61
|
+
# must be clean
|
|
62
|
+
```
|
|
63
|
+
If not clean, stop and report.
|
|
64
|
+
- Perform the real merge — brings the feature branch's Implementer commit, ui-review baseline commit, and any feedback commits into main:
|
|
65
|
+
```bash
|
|
66
|
+
git merge --no-ff cloverleaf/${TASK_ID} -m "cloverleaf: ${TASK_ID} merged (full pipeline)"
|
|
67
|
+
```
|
|
68
|
+
If git reports conflicts: abort and escalate.
|
|
69
|
+
```bash
|
|
70
|
+
git merge --abort
|
|
71
|
+
cloverleaf-cli advance-status <repo_root> ${TASK_ID} escalated agent
|
|
72
|
+
```
|
|
73
|
+
Exit with a human-readable error explaining the conflict.
|
|
74
|
+
- Advance task status on main (commits `.cloverleaf/tasks/${TASK_ID}.json` + event):
|
|
75
|
+
```bash
|
|
76
|
+
cloverleaf-cli advance-status <repo_root> ${TASK_ID} merged agent
|
|
77
|
+
```
|
|
58
78
|
|
|
59
79
|
### 4. Common: report
|
|
60
80
|
|
|
61
81
|
Report:
|
|
62
|
-
- "✓ Merged `<TASK-ID>`. Branch `cloverleaf/<TASK-ID>`
|
|
63
|
-
- "Suggested: `git push origin
|
|
82
|
+
- "✓ Merged `<TASK-ID>`. Branch `cloverleaf/<TASK-ID>` has been merged into main."
|
|
83
|
+
- "Suggested: `git push origin main` to push the merge commit."
|
|
64
84
|
|
|
65
85
|
## Rules
|
|
66
86
|
|
|
67
87
|
- Only proceed on explicit `y`, `Y`, `yes`, `YES`. Anything else: abort without state change.
|
|
68
88
|
- The skill does NOT push the branch or open a PR.
|
|
69
89
|
- Fast lane and full pipeline use distinct gates — the state machine records which path was taken.
|
|
90
|
+
- Full-pipeline merges perform a real `git merge --no-ff` before advancing state — the feature branch's code, baselines, and feedback commits all land on main.
|
|
70
91
|
- If the user declines, no state change and no commit.
|
|
@@ -11,13 +11,13 @@ The user has invoked this skill with a brief. Your job: turn the brief into a st
|
|
|
11
11
|
|
|
12
12
|
1. Determine the active project. Run:
|
|
13
13
|
```
|
|
14
|
-
|
|
14
|
+
cloverleaf-cli infer-project <repo_root>
|
|
15
15
|
```
|
|
16
16
|
where `<repo_root>` is the current working directory. On failure (no projects, or multiple projects), report the error and ask the user to specify `--project=<id>` or to create a project config first.
|
|
17
17
|
|
|
18
18
|
2. Allocate the next task ID:
|
|
19
19
|
```
|
|
20
|
-
|
|
20
|
+
cloverleaf-cli next-task-id <repo_root> --project=<project>
|
|
21
21
|
```
|
|
22
22
|
Capture the output (e.g., `DEMO-002`).
|
|
23
23
|
|
|
@@ -45,7 +45,19 @@ The user has invoked this skill with a brief. Your job: turn the brief into a st
|
|
|
45
45
|
|
|
46
46
|
6. Commit: `git add .cloverleaf/tasks/<allocated-id>.json && git commit -m "cloverleaf: task <allocated-id>"`.
|
|
47
47
|
|
|
48
|
-
7.
|
|
48
|
+
7. **v0.4 scaffolding:** Ensure baseline and run directories are set up:
|
|
49
|
+
```bash
|
|
50
|
+
# v0.4 scaffolding additions — baselines tracked, runs ephemeral
|
|
51
|
+
mkdir -p <repo_root>/.cloverleaf/baselines
|
|
52
|
+
mkdir -p <repo_root>/.cloverleaf/runs
|
|
53
|
+
|
|
54
|
+
# Ensure .gitignore excludes runs/ (baselines ARE tracked, only runs is ephemeral)
|
|
55
|
+
if ! grep -qE '^\.cloverleaf/runs/?$' <repo_root>/.gitignore 2>/dev/null; then
|
|
56
|
+
echo '.cloverleaf/runs/' >> <repo_root>/.gitignore
|
|
57
|
+
fi
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
8. Report:
|
|
49
61
|
- "Created `<allocated-id>` at `.cloverleaf/tasks/<allocated-id>.json`."
|
|
50
62
|
- Show the generated acceptance criteria.
|
|
51
63
|
- Suggest: "Review and edit the task if needed, then run `/cloverleaf-run <allocated-id>`."
|
|
@@ -62,3 +74,8 @@ The user has invoked this skill with a brief. Your job: turn the brief into a st
|
|
|
62
74
|
- After writing the task, report the chosen risk_class and how it was determined, e.g.:
|
|
63
75
|
> "Risk class: `high` → full pipeline (matched keyword `component` in acceptance criterion). Override with `--risk=low` if desired."
|
|
64
76
|
- Users can manually edit `risk_class` in the task JSON before running `/cloverleaf-run`.
|
|
77
|
+
|
|
78
|
+
## v0.4 artifacts
|
|
79
|
+
|
|
80
|
+
- `.cloverleaf/baselines/` is **tracked** in git; baseline PNGs travel with code.
|
|
81
|
+
- `.cloverleaf/runs/` is **gitignored**; each task's run artifacts (diffs, candidate screenshots, QA reports) are ephemeral.
|
|
@@ -7,7 +7,11 @@ description: Run the QA agent on a task in the `qa` state (full pipeline only).
|
|
|
7
7
|
|
|
8
8
|
## Steps
|
|
9
9
|
|
|
10
|
-
0.
|
|
10
|
+
0. Pre-flight: ensure you are on `main` and clean stale feedback temp files from previous runs (prevents /tmp leakage between tasks). If not on main, `git checkout main`. If main has uncommitted changes, stop and report.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
rm -f /tmp/cloverleaf-fb-r.json /tmp/cloverleaf-fb-u.json /tmp/cloverleaf-fb-q.json
|
|
14
|
+
```
|
|
11
15
|
|
|
12
16
|
1. Capture the TASK-ID argument.
|
|
13
17
|
|
|
@@ -19,30 +23,35 @@ description: Run the QA agent on a task in the `qa` state (full pipeline only).
|
|
|
19
23
|
|
|
20
24
|
3. Confirm feature branch exists: `git rev-parse --verify cloverleaf/<TASK-ID>`.
|
|
21
25
|
|
|
22
|
-
4.
|
|
26
|
+
4. Ensure required directories exist:
|
|
27
|
+
```bash
|
|
28
|
+
mkdir -p <repo_root>/.cloverleaf/runs/<TASK-ID>/qa
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
5. Load QA rules JSON:
|
|
23
32
|
```bash
|
|
24
33
|
# Consumer override takes precedence over the package default.
|
|
25
34
|
if [ -f "<repo_root>/.cloverleaf/config/qa-rules.json" ]; then
|
|
26
35
|
cat "<repo_root>/.cloverleaf/config/qa-rules.json"
|
|
27
36
|
else
|
|
28
|
-
cat
|
|
37
|
+
cat $(cloverleaf-cli plugin-root)/config/qa-rules.json
|
|
29
38
|
fi
|
|
30
39
|
```
|
|
31
40
|
Capture for the subagent as `qa_rules`.
|
|
32
41
|
|
|
33
|
-
|
|
42
|
+
6. Compute diff:
|
|
34
43
|
```bash
|
|
35
44
|
git diff main..cloverleaf/<TASK-ID>
|
|
36
45
|
```
|
|
37
46
|
|
|
38
|
-
|
|
47
|
+
7. Dispatch the QA subagent via the Task tool:
|
|
39
48
|
- `subagent_type`: `general-purpose`
|
|
40
49
|
- `model`: `sonnet`
|
|
41
|
-
- Prompt: contents of
|
|
50
|
+
- Prompt: contents of `$(cloverleaf-cli plugin-root)/prompts/qa.md` with substitutions for `{{task}}`, `{{diff}}`, `{{branch}}`, `{{base_branch}}`, `{{repo_root}}`, `{{qa_rules}}` (the JSON loaded in step 5).
|
|
42
51
|
|
|
43
|
-
|
|
52
|
+
8. Parse response: expect `{"verdict": "pass"|"bounce"|"escalate", "summary", "findings", "results"}`.
|
|
44
53
|
|
|
45
|
-
|
|
54
|
+
9. Branch on verdict:
|
|
46
55
|
|
|
47
56
|
**Pass:**
|
|
48
57
|
```
|
|
@@ -54,9 +63,15 @@ description: Run the QA agent on a task in the `qa` state (full pipeline only).
|
|
|
54
63
|
**Bounce:**
|
|
55
64
|
1. Write feedback envelope: `echo '<json>' > /tmp/cloverleaf-fb-q.json`
|
|
56
65
|
2. `cloverleaf-cli write-feedback <repo_root> <TASK-ID> /tmp/cloverleaf-fb-q.json --prefix=q`
|
|
57
|
-
3.
|
|
58
|
-
|
|
59
|
-
|
|
66
|
+
3. Commit the persisted feedback file (was missing pre-v0.4.1 — bug #3):
|
|
67
|
+
```bash
|
|
68
|
+
cd <repo_root>
|
|
69
|
+
git add .cloverleaf/feedback/
|
|
70
|
+
git commit -m "cloverleaf: <TASK-ID> qa feedback"
|
|
71
|
+
```
|
|
72
|
+
4. `cloverleaf-cli advance-status <repo_root> <TASK-ID> implementing agent --path=full_pipeline`
|
|
73
|
+
5. Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> qa bounced → implementing"`.
|
|
74
|
+
6. Report: "✗ QA bounced. `<failed>/<total>` tests failed. State → implementing. Next: `/cloverleaf-implement <TASK-ID>`."
|
|
60
75
|
|
|
61
76
|
**Escalate:**
|
|
62
77
|
1. `cloverleaf-cli advance-status <repo_root> <TASK-ID> escalated agent`
|
|
@@ -7,7 +7,7 @@ description: Run the Reviewer agent on a task in the `review` state. Emits a fee
|
|
|
7
7
|
|
|
8
8
|
## Steps
|
|
9
9
|
|
|
10
|
-
0.
|
|
10
|
+
0. Pre-flight: ensure you are on `main` and clean stale feedback temp files from previous runs (prevents /tmp leakage between tasks):
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
13
|
cd <repo_root>
|
|
@@ -17,11 +17,15 @@ description: Run the Reviewer agent on a task in the `review` state. Emits a fee
|
|
|
17
17
|
|
|
18
18
|
If main has uncommitted changes, stop and report — the user must clean up first.
|
|
19
19
|
|
|
20
|
+
```bash
|
|
21
|
+
rm -f /tmp/cloverleaf-fb-r.json /tmp/cloverleaf-fb-u.json /tmp/cloverleaf-fb-q.json
|
|
22
|
+
```
|
|
23
|
+
|
|
20
24
|
1. Capture the TASK-ID argument.
|
|
21
25
|
|
|
22
26
|
2. Load the task:
|
|
23
27
|
```
|
|
24
|
-
|
|
28
|
+
cloverleaf-cli load-task <repo_root> <TASK-ID>
|
|
25
29
|
```
|
|
26
30
|
Verify `status === "review"`. If not, report the current status and stop.
|
|
27
31
|
|
|
@@ -36,7 +40,7 @@ description: Run the Reviewer agent on a task in the `review` state. Emits a fee
|
|
|
36
40
|
5. Dispatch the Reviewer subagent via the Task tool:
|
|
37
41
|
- `subagent_type`: `general-purpose`
|
|
38
42
|
- `model`: `sonnet`
|
|
39
|
-
- Prompt: contents of
|
|
43
|
+
- Prompt: contents of `$(cloverleaf-cli plugin-root)/prompts/reviewer.md` with substitutions for `{{task}}`, `{{branch}}`, `{{base_branch}}`, `{{repo_root}}`, `{{diff}}`.
|
|
40
44
|
|
|
41
45
|
6. Parse the subagent's response. Expect a feedback envelope JSON of the form `{"verdict": "pass"|"bounce", "summary": "...", "findings": [...]}`. Validate shape: verdict must be `pass` or `bounce`; if `bounce`, findings must have at least one entry with `severity` (one of `blocker|error|warning|info`) and `message`.
|
|
42
46
|
|
|
@@ -50,11 +54,17 @@ description: Run the Reviewer agent on a task in the `review` state. Emits a fee
|
|
|
50
54
|
Report: "✓ Review passed. State → automated-gates. Next: `/cloverleaf-merge <TASK-ID>`."
|
|
51
55
|
|
|
52
56
|
**Bounce:**
|
|
53
|
-
1. Write the feedback envelope to a temp file: `echo '<envelope-json>' > /tmp/cloverleaf-fb.json`.
|
|
54
|
-
2. `cloverleaf-cli write-feedback <repo_root> <TASK-ID> /tmp/cloverleaf-fb.json` — captures the path like `.cloverleaf/feedback/<TASK-ID>-r<N>.json`.
|
|
55
|
-
3.
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
1. Write the feedback envelope to a temp file: `echo '<envelope-json>' > /tmp/cloverleaf-fb-r.json`.
|
|
58
|
+
2. `cloverleaf-cli write-feedback <repo_root> <TASK-ID> /tmp/cloverleaf-fb-r.json` — captures the path like `.cloverleaf/feedback/<TASK-ID>-r<N>.json`.
|
|
59
|
+
3. Commit the persisted feedback file (was missing pre-v0.4.1 — bug #3):
|
|
60
|
+
```bash
|
|
61
|
+
cd <repo_root>
|
|
62
|
+
git add .cloverleaf/feedback/
|
|
63
|
+
git commit -m "cloverleaf: <TASK-ID> review feedback"
|
|
64
|
+
```
|
|
65
|
+
4. `cloverleaf-cli advance-status <repo_root> <TASK-ID> implementing agent` — loops back.
|
|
66
|
+
5. Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> review bounced → implementing"`.
|
|
67
|
+
6. Report: "✗ Review bounced. Findings: <summarize findings by severity>. State → implementing. Next: `/cloverleaf-implement <TASK-ID>`."
|
|
58
68
|
|
|
59
69
|
## Rules
|
|
60
70
|
|
|
@@ -7,7 +7,7 @@ description: Run the UI Reviewer agent on a task in the `ui-review` state (full
|
|
|
7
7
|
|
|
8
8
|
## Steps
|
|
9
9
|
|
|
10
|
-
0.
|
|
10
|
+
0. Pre-flight: ensure you are on `main` and clean stale feedback temp files from previous runs (prevents /tmp leakage between tasks):
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
13
|
cd <repo_root>
|
|
@@ -17,22 +17,32 @@ description: Run the UI Reviewer agent on a task in the `ui-review` state (full
|
|
|
17
17
|
|
|
18
18
|
If main has uncommitted changes, stop and report.
|
|
19
19
|
|
|
20
|
+
```bash
|
|
21
|
+
rm -f /tmp/cloverleaf-fb-r.json /tmp/cloverleaf-fb-u.json /tmp/cloverleaf-fb-q.json
|
|
22
|
+
```
|
|
23
|
+
|
|
20
24
|
1. Capture the TASK-ID argument.
|
|
21
25
|
|
|
22
26
|
2. Load the task:
|
|
23
27
|
```
|
|
24
|
-
|
|
28
|
+
cloverleaf-cli load-task <repo_root> <TASK-ID>
|
|
25
29
|
```
|
|
26
30
|
Verify `status === "ui-review"`. If not, report and stop.
|
|
27
31
|
|
|
28
32
|
3. Confirm feature branch exists: `git rev-parse --verify cloverleaf/<TASK-ID>`. If missing, report and stop.
|
|
29
33
|
|
|
30
|
-
4.
|
|
34
|
+
4. Ensure required directories exist:
|
|
35
|
+
```bash
|
|
36
|
+
mkdir -p <repo_root>/.cloverleaf/baselines
|
|
37
|
+
mkdir -p <repo_root>/.cloverleaf/runs/<TASK-ID>/ui-review
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
5. Compute affected routes:
|
|
31
41
|
```bash
|
|
32
|
-
AFFECTED=$(
|
|
42
|
+
AFFECTED=$(cloverleaf-cli affected-routes <repo_root> <TASK-ID>)
|
|
33
43
|
```
|
|
34
44
|
|
|
35
|
-
|
|
45
|
+
6. **Empty-set early-exit.** If `AFFECTED` is `[]`, skip the subagent entirely:
|
|
36
46
|
```bash
|
|
37
47
|
cloverleaf-cli advance-status <repo_root> <TASK-ID> qa agent '' full_pipeline
|
|
38
48
|
cd <repo_root>
|
|
@@ -42,28 +52,29 @@ description: Run the UI Reviewer agent on a task in the `ui-review` state (full
|
|
|
42
52
|
Report: "✓ UI Review skipped (no renderable routes affected). State → qa. Next: `/cloverleaf-qa <TASK-ID>`."
|
|
43
53
|
Stop here.
|
|
44
54
|
|
|
45
|
-
|
|
55
|
+
7. Allocate a free preview port:
|
|
46
56
|
```bash
|
|
47
57
|
PREVIEW_PORT=$(node -e "const net=require('net');const s=net.createServer();s.listen(0,()=>{console.log(s.address().port);s.close()})")
|
|
48
58
|
```
|
|
49
59
|
|
|
50
|
-
|
|
60
|
+
8. Compute diff:
|
|
51
61
|
```bash
|
|
52
62
|
git diff main..cloverleaf/<TASK-ID>
|
|
53
63
|
```
|
|
54
64
|
|
|
55
|
-
|
|
65
|
+
9. **Browser cache env var.** Before the Task-tool dispatch, ensure `PLAYWRIGHT_BROWSERS_PATH=~/.cache/ms-playwright` is exported so the subagent inherits it. This keeps Playwright from re-downloading ~300 MB of browser binaries inside the worktree.
|
|
56
66
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
10. Dispatch the UI Reviewer subagent via the Task tool:
|
|
68
|
+
- `subagent_type`: `general-purpose`
|
|
69
|
+
- `model`: `sonnet`
|
|
70
|
+
- Prompt: contents of `$(cloverleaf-cli plugin-root)/prompts/ui-reviewer.md` with substitutions:
|
|
71
|
+
- `{{task}}`, `{{diff}}`, `{{branch}}`, `{{base_branch}}`, `{{repo_root}}`, `{{preview_port}}`
|
|
72
|
+
- `{{affected_routes}}` → the value of `$AFFECTED` (verbatim — may be `"all"`, a JSON array, or `[]` but step 6 handled `[]` already)
|
|
73
|
+
- `{{ui_review_config}}` → JSON-stringified result of `cloverleaf-cli ui-review-config <repo_root>` (used by the subagent to scope viewport sizes, thresholds, and axe rule overrides)
|
|
63
74
|
|
|
64
|
-
|
|
75
|
+
11. Parse the subagent's response. Expect `{"verdict": "pass"|"bounce"|"escalate", "summary": "...", "findings": [...]}`.
|
|
65
76
|
|
|
66
|
-
|
|
77
|
+
12. Branch on verdict:
|
|
67
78
|
|
|
68
79
|
**Pass:**
|
|
69
80
|
```
|
|
@@ -75,9 +86,15 @@ description: Run the UI Reviewer agent on a task in the `ui-review` state (full
|
|
|
75
86
|
**Bounce:**
|
|
76
87
|
1. Write feedback: `echo '<envelope-json>' > /tmp/cloverleaf-fb-u.json`
|
|
77
88
|
2. `cloverleaf-cli write-feedback <repo_root> <TASK-ID> /tmp/cloverleaf-fb-u.json --prefix=u`
|
|
78
|
-
3.
|
|
79
|
-
|
|
80
|
-
|
|
89
|
+
3. Commit the persisted feedback file (was missing pre-v0.4.1 — bug #3):
|
|
90
|
+
```bash
|
|
91
|
+
cd <repo_root>
|
|
92
|
+
git add .cloverleaf/feedback/
|
|
93
|
+
git commit -m "cloverleaf: <TASK-ID> ui-review feedback"
|
|
94
|
+
```
|
|
95
|
+
4. `cloverleaf-cli advance-status <repo_root> <TASK-ID> implementing agent '' full_pipeline`
|
|
96
|
+
5. Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> ui-review bounced → implementing"`.
|
|
97
|
+
6. Report: "✗ UI Review bounced. Findings: <summary by severity>. State → implementing. Next: `/cloverleaf-implement <TASK-ID>`."
|
|
81
98
|
|
|
82
99
|
**Escalate:**
|
|
83
100
|
1. `cloverleaf-cli advance-status <repo_root> <TASK-ID> escalated agent`
|
|
@@ -89,5 +106,5 @@ description: Run the UI Reviewer agent on a task in the `ui-review` state (full
|
|
|
89
106
|
- Never push.
|
|
90
107
|
- Do not modify source code — UI Reviewer is read-only.
|
|
91
108
|
- Always teardown preview server + worktree on error.
|
|
92
|
-
- Empty-set early-exit (step
|
|
109
|
+
- Empty-set early-exit (step 6) skips the browser entirely — no Playwright invocation, no worktree.
|
|
93
110
|
- On illegal state transition, report and stop without partial commits.
|
|
File without changes
|