@cloverleaf/reference-impl 0.1.1 → 0.2.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/README.md +44 -24
- package/VERSION +1 -1
- package/config/qa-rules.json +19 -0
- package/config/ui-paths.json +3 -0
- package/dist/cli.mjs +196 -0
- package/dist/events.mjs +80 -0
- package/dist/feedback.mjs +41 -0
- package/dist/ids.mjs +60 -0
- package/dist/index.mjs +6 -0
- package/dist/paths.mjs +26 -0
- package/dist/ports.mjs +19 -0
- package/dist/qa-rules.mjs +15 -0
- package/dist/state.mjs +97 -0
- package/dist/ui-paths.mjs +25 -0
- package/dist/validate.mjs +40 -0
- package/install.sh +3 -0
- package/lib/cli.ts +35 -2
- package/lib/feedback.ts +6 -2
- package/lib/ids.ts +3 -2
- package/lib/ports.ts +19 -0
- package/lib/qa-rules.ts +23 -0
- package/lib/state.ts +1 -1
- package/lib/ui-paths.ts +27 -0
- package/lib/validate.ts +3 -20
- package/package.json +12 -6
- package/prompts/documenter.md +72 -0
- package/prompts/qa.md +82 -0
- package/prompts/ui-reviewer.md +93 -0
- package/skills/cloverleaf-document.md +73 -0
- package/skills/cloverleaf-implement.md +20 -4
- package/skills/cloverleaf-merge.md +46 -18
- package/skills/cloverleaf-new-task.md +9 -1
- package/skills/cloverleaf-qa.md +64 -0
- package/skills/cloverleaf-run.md +72 -18
- package/skills/cloverleaf-ui-review.md +73 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cloverleaf-document
|
|
3
|
+
description: Run the Documenter agent on a task in the `implementing` state (full pipeline only). Dispatches a subagent to add doc-only commits to the feature branch, then advances implementing → documenting → review. Usage — /cloverleaf-document <TASK-ID>.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Cloverleaf — document
|
|
7
|
+
|
|
8
|
+
## Steps
|
|
9
|
+
|
|
10
|
+
0. Ensure you are on `main`. State is authoritative on main. Run:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
cd <repo_root>
|
|
14
|
+
current=$(git rev-parse --abbrev-ref HEAD)
|
|
15
|
+
if [ "$current" != "main" ]; then git checkout main; fi
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
If main has uncommitted changes, stop and report — the user must clean up first.
|
|
19
|
+
|
|
20
|
+
1. Capture the TASK-ID argument.
|
|
21
|
+
|
|
22
|
+
2. Load the task:
|
|
23
|
+
```
|
|
24
|
+
~/.claude/plugins/cloverleaf/bin/cloverleaf-cli load-task <repo_root> <TASK-ID>
|
|
25
|
+
```
|
|
26
|
+
Verify `status === "implementing"`. Verify `risk_class === "high"`. If either check fails, report and stop.
|
|
27
|
+
|
|
28
|
+
3. Confirm feature branch exists: `git rev-parse --verify cloverleaf/<TASK-ID>`. If missing, report the discrepancy and stop.
|
|
29
|
+
|
|
30
|
+
4. Compute the diff (without checking out):
|
|
31
|
+
```bash
|
|
32
|
+
git diff main..cloverleaf/<TASK-ID>
|
|
33
|
+
```
|
|
34
|
+
Capture the output for the subagent.
|
|
35
|
+
|
|
36
|
+
5. Dispatch the Documenter subagent via the Task tool:
|
|
37
|
+
- `subagent_type`: `general-purpose`
|
|
38
|
+
- `model`: `sonnet`
|
|
39
|
+
- Prompt: contents of `~/.claude/plugins/cloverleaf/prompts/documenter.md` with substitutions:
|
|
40
|
+
- `{{task}}` → full task JSON (pretty-printed)
|
|
41
|
+
- `{{diff}}` → diff output
|
|
42
|
+
- `{{branch}}` → `cloverleaf/<TASK-ID>`
|
|
43
|
+
- `{{base_branch}}` → `main`
|
|
44
|
+
- `{{repo_root}}` → absolute path
|
|
45
|
+
|
|
46
|
+
6. Parse the subagent's response. Expect JSON of the form `{"commits_added": N, "files_changed": [...], "summary": "..."}`.
|
|
47
|
+
|
|
48
|
+
7. On failure to parse or response with invalid shape: report the response and stop without advancing state.
|
|
49
|
+
|
|
50
|
+
8. Advance state:
|
|
51
|
+
```
|
|
52
|
+
cloverleaf-cli advance-status <repo_root> <TASK-ID> documenting agent
|
|
53
|
+
cloverleaf-cli advance-status <repo_root> <TASK-ID> review agent
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
9. Commit state changes:
|
|
57
|
+
```bash
|
|
58
|
+
cd <repo_root>
|
|
59
|
+
git add .cloverleaf/
|
|
60
|
+
git commit -m "cloverleaf: <TASK-ID> documented → review"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
10. Report:
|
|
64
|
+
- "✓ Documenter done. `<commits_added>` doc commit(s) added. State → review."
|
|
65
|
+
- "Files changed: `<comma-separated files_changed>`."
|
|
66
|
+
- "Next: `/cloverleaf-review <TASK-ID>`."
|
|
67
|
+
|
|
68
|
+
## Rules
|
|
69
|
+
|
|
70
|
+
- Never push.
|
|
71
|
+
- Do not modify source code — Documenter is doc-only.
|
|
72
|
+
- If any `advance-status` call fails, stop and report.
|
|
73
|
+
- The skill's working directory is the consumer's repo root.
|
|
@@ -45,7 +45,9 @@ The user has invoked this skill with a TASK-ID (e.g., `DEMO-001`).
|
|
|
45
45
|
|
|
46
46
|
If this fails (uncommitted changes on main, detached HEAD, etc.), report the error and stop without advancing state.
|
|
47
47
|
|
|
48
|
-
8.
|
|
48
|
+
8. Walk the state machine. Read `task.risk_class` (already captured at step 2).
|
|
49
|
+
|
|
50
|
+
**If `risk_class === "low"` (fast lane — v0.1.1 behavior):**
|
|
49
51
|
|
|
50
52
|
If the current task status is `pending`:
|
|
51
53
|
```
|
|
@@ -61,18 +63,32 @@ The user has invoked this skill with a TASK-ID (e.g., `DEMO-001`).
|
|
|
61
63
|
cloverleaf-cli advance-status <repo_root> <TASK-ID> review agent
|
|
62
64
|
```
|
|
63
65
|
|
|
66
|
+
**If `risk_class === "high"` (full pipeline — new in v0.2):**
|
|
67
|
+
|
|
68
|
+
If the current task status is `pending`:
|
|
69
|
+
```
|
|
70
|
+
cloverleaf-cli advance-status <repo_root> <TASK-ID> tactical-plan agent
|
|
71
|
+
cloverleaf-cli advance-status <repo_root> <TASK-ID> implementing agent
|
|
72
|
+
```
|
|
73
|
+
Stop here. Documenter runs next (will advance implementing → documenting → review).
|
|
74
|
+
|
|
75
|
+
If the current task status was `implementing` (loop-back after Reviewer/UI/QA bounce):
|
|
76
|
+
No state advance — the bouncing skill already moved state back to `implementing`.
|
|
77
|
+
|
|
64
78
|
9. Commit the state changes:
|
|
65
79
|
```
|
|
66
80
|
cd <repo_root>
|
|
67
81
|
git add .cloverleaf/
|
|
68
|
-
git commit -m "cloverleaf: <TASK-ID> →
|
|
82
|
+
git commit -m "cloverleaf: <TASK-ID> → <new-state>"
|
|
69
83
|
```
|
|
84
|
+
where `<new-state>` is `review` for fast lane (`risk_class === "low"`) or `implementing` for full pipeline (`risk_class === "high"`).
|
|
70
85
|
|
|
71
86
|
10. Report:
|
|
72
|
-
- "✓ Implementer done. Branch `<branch>`. State →
|
|
87
|
+
- "✓ Implementer done. Branch `<branch>`. State → <new-state>."
|
|
73
88
|
- "Files changed: <comma-separated>."
|
|
74
89
|
- "Currently on: `main`."
|
|
75
|
-
- "Next: `/cloverleaf-review <TASK-ID>`."
|
|
90
|
+
- **If `risk_class === "low"`:** "Next: `/cloverleaf-review <TASK-ID>`."
|
|
91
|
+
- **If `risk_class === "high"`:** "Next: `/cloverleaf-document <TASK-ID>`."
|
|
76
92
|
|
|
77
93
|
## Rules
|
|
78
94
|
|
|
@@ -1,42 +1,70 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cloverleaf-merge
|
|
3
|
-
description: Human gate for merging a Cloverleaf task.
|
|
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>.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Cloverleaf — merge
|
|
7
7
|
|
|
8
8
|
## Steps
|
|
9
9
|
|
|
10
|
-
0. Ensure you are on `main`.
|
|
11
|
-
|
|
10
|
+
0. Ensure you are on `main`. Run:
|
|
12
11
|
```bash
|
|
13
12
|
cd <repo_root>
|
|
14
13
|
current=$(git rev-parse --abbrev-ref HEAD)
|
|
15
14
|
if [ "$current" != "main" ]; then git checkout main; fi
|
|
16
15
|
```
|
|
17
|
-
|
|
18
|
-
If main has uncommitted changes, stop and report — the user must clean up first.
|
|
16
|
+
If main has uncommitted changes, stop and report.
|
|
19
17
|
|
|
20
18
|
1. Capture the TASK-ID.
|
|
21
19
|
|
|
22
|
-
2. Load the task: `cloverleaf-cli load-task <repo_root> <TASK-ID>`.
|
|
20
|
+
2. Load the task: `cloverleaf-cli load-task <repo_root> <TASK-ID>`. Let `S` = `task.status`.
|
|
21
|
+
|
|
22
|
+
- If `S === "automated-gates"`: this is a fast-lane merge. Proceed with section 3A.
|
|
23
|
+
- If `S === "final-gate"`: this is a full-pipeline merge. Proceed with section 3B.
|
|
24
|
+
- Else: report the current status and stop.
|
|
25
|
+
|
|
26
|
+
### 3A. Fast-lane confirmation
|
|
27
|
+
|
|
28
|
+
3A.1. Show to user:
|
|
29
|
+
> "About to merge `<TASK-ID>` (fast lane). Branch `cloverleaf/<TASK-ID>` has been reviewed and passed. Confirm merge? (y/N)"
|
|
30
|
+
|
|
31
|
+
3A.2. On explicit `y`:
|
|
32
|
+
- `cloverleaf-cli emit-gate-decision <repo_root> <TASK-ID> human_merge approve human`
|
|
33
|
+
- `cloverleaf-cli advance-status <repo_root> <TASK-ID> merged human human_merge fast_lane`
|
|
34
|
+
- Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> merged (fast lane)"`.
|
|
35
|
+
|
|
36
|
+
### 3B. Full-pipeline final approval
|
|
37
|
+
|
|
38
|
+
3B.1. Collect summaries. Read the latest feedback files:
|
|
39
|
+
```bash
|
|
40
|
+
ls <repo_root>/.cloverleaf/feedback/<TASK-ID>-*.json | sort
|
|
41
|
+
```
|
|
42
|
+
Extract `summary` and `verdict` from each. Group by prefix:
|
|
43
|
+
- `r*.json` → Reviewer
|
|
44
|
+
- `u*.json` → UI Reviewer
|
|
45
|
+
- `q*.json` → QA
|
|
23
46
|
|
|
24
|
-
|
|
25
|
-
|
|
47
|
+
3B.2. Show to user:
|
|
48
|
+
> "About to merge `<TASK-ID>` (full pipeline). Final approval required. Summaries:
|
|
49
|
+
> - Reviewer: <summary>
|
|
50
|
+
> - UI Reviewer: <summary or 'not run'>
|
|
51
|
+
> - QA: <summary with results>
|
|
52
|
+
> Confirm merge? (y/N)"
|
|
26
53
|
|
|
27
|
-
|
|
54
|
+
3B.3. On explicit `y`:
|
|
55
|
+
- `cloverleaf-cli emit-gate-decision <repo_root> <TASK-ID> final_approval_gate approve human`
|
|
56
|
+
- `cloverleaf-cli advance-status <repo_root> <TASK-ID> merged human final_approval_gate full_pipeline`
|
|
57
|
+
- Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> merged (full pipeline)"`.
|
|
28
58
|
|
|
29
|
-
4.
|
|
30
|
-
- Emit the gate decision: `cloverleaf-cli emit-gate-decision <repo_root> <TASK-ID> human_merge approve human`. Note: decision is `approve` (not `approved` — per the gate-decision schema's enum).
|
|
31
|
-
- Advance: `cloverleaf-cli advance-status <repo_root> <TASK-ID> merged human human_merge fast_lane`.
|
|
32
|
-
- Commit state: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> merged"`.
|
|
59
|
+
### 4. Common: report
|
|
33
60
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
61
|
+
Report:
|
|
62
|
+
- "✓ Merged `<TASK-ID>`. Branch `cloverleaf/<TASK-ID>` is ready for you to push and open a PR."
|
|
63
|
+
- "Suggested: `git push origin cloverleaf/<TASK-ID>` then open a PR against `main`."
|
|
37
64
|
|
|
38
65
|
## Rules
|
|
39
66
|
|
|
40
|
-
-
|
|
41
|
-
- The
|
|
67
|
+
- Only proceed on explicit `y`, `Y`, `yes`, `YES`. Anything else: abort without state change.
|
|
68
|
+
- The skill does NOT push the branch or open a PR.
|
|
69
|
+
- Fast lane and full pipeline use distinct gates — the state machine records which path was taken.
|
|
42
70
|
- If the user declines, no state change and no commit.
|
|
@@ -53,4 +53,12 @@ The user has invoked this skill with a brief. Your job: turn the brief into a st
|
|
|
53
53
|
## Rules
|
|
54
54
|
|
|
55
55
|
- Do not guess at acceptance criteria. If the brief is too vague (e.g., "make it faster" with no target), ask the user a clarifying question before writing the file.
|
|
56
|
-
-
|
|
56
|
+
- **risk_class inference:** `risk_class` determines the Delivery pipeline (`"low"` → fast lane; `"high"` → full pipeline). Rules:
|
|
57
|
+
1. If the user passed `--risk=high` or `--risk=low` as a flag on the skill invocation, honor it.
|
|
58
|
+
2. Otherwise, set `risk_class: "high"` when the brief OR any acceptance criterion matches (case-insensitive) any of these keywords:
|
|
59
|
+
`site/`, `UI`, `page`, `component`, `style`, `visual`, `layout`, `render`, `display`, `accessibility`, `a11y`, `responsive`, `.astro`, `.css`, `.html`
|
|
60
|
+
3. Also set `risk_class: "high"` for breaking APIs or cross-project work (v0.1.1 behavior, retained).
|
|
61
|
+
4. Default: `risk_class: "low"`.
|
|
62
|
+
- After writing the task, report the chosen risk_class and how it was determined, e.g.:
|
|
63
|
+
> "Risk class: `high` → full pipeline (matched keyword `component` in acceptance criterion). Override with `--risk=low` if desired."
|
|
64
|
+
- Users can manually edit `risk_class` in the task JSON before running `/cloverleaf-run`.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cloverleaf-qa
|
|
3
|
+
description: Run the QA agent on a task in the `qa` state (full pipeline only). Dispatches a subagent to run per-package test suites against an isolated worktree; emits feedback envelope with results; advances qa → final-gate on pass or loops back to implementing on bounce. Usage — /cloverleaf-qa <TASK-ID>.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Cloverleaf — qa
|
|
7
|
+
|
|
8
|
+
## Steps
|
|
9
|
+
|
|
10
|
+
0. Ensure you are on `main`. If not, `git checkout main`. If main has uncommitted changes, stop and report.
|
|
11
|
+
|
|
12
|
+
1. Capture the TASK-ID argument.
|
|
13
|
+
|
|
14
|
+
2. Load the task:
|
|
15
|
+
```
|
|
16
|
+
cloverleaf-cli load-task <repo_root> <TASK-ID>
|
|
17
|
+
```
|
|
18
|
+
Verify `status === "qa"`. If not, report and stop.
|
|
19
|
+
|
|
20
|
+
3. Confirm feature branch exists: `git rev-parse --verify cloverleaf/<TASK-ID>`.
|
|
21
|
+
|
|
22
|
+
4. Load QA rules JSON:
|
|
23
|
+
```bash
|
|
24
|
+
cat ~/.claude/plugins/cloverleaf/config/qa-rules.json
|
|
25
|
+
```
|
|
26
|
+
Capture for the subagent as `qa_rules`.
|
|
27
|
+
|
|
28
|
+
5. Compute diff:
|
|
29
|
+
```bash
|
|
30
|
+
git diff main..cloverleaf/<TASK-ID>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
6. Dispatch the QA subagent via the Task tool:
|
|
34
|
+
- `subagent_type`: `general-purpose`
|
|
35
|
+
- `model`: `sonnet`
|
|
36
|
+
- Prompt: contents of `~/.claude/plugins/cloverleaf/prompts/qa.md` with substitutions for `{{task}}`, `{{diff}}`, `{{branch}}`, `{{base_branch}}`, `{{repo_root}}`, `{{qa_rules}}` (the JSON loaded in step 4).
|
|
37
|
+
|
|
38
|
+
7. Parse response: expect `{"verdict": "pass"|"bounce"|"escalate", "summary", "findings", "results"}`.
|
|
39
|
+
|
|
40
|
+
8. Branch on verdict:
|
|
41
|
+
|
|
42
|
+
**Pass:**
|
|
43
|
+
```
|
|
44
|
+
cloverleaf-cli advance-status <repo_root> <TASK-ID> final-gate agent --path=full_pipeline
|
|
45
|
+
```
|
|
46
|
+
Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> qa passed → final-gate"`.
|
|
47
|
+
Report: "✓ QA passed (`<passed>/<total>` tests). State → final-gate. Next: `/cloverleaf-merge <TASK-ID>`."
|
|
48
|
+
|
|
49
|
+
**Bounce:**
|
|
50
|
+
1. Write feedback envelope: `echo '<json>' > /tmp/cloverleaf-fb-q.json`
|
|
51
|
+
2. `cloverleaf-cli write-feedback <repo_root> <TASK-ID> /tmp/cloverleaf-fb-q.json --prefix=q`
|
|
52
|
+
3. `cloverleaf-cli advance-status <repo_root> <TASK-ID> implementing agent --path=full_pipeline`
|
|
53
|
+
4. Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> qa bounced → implementing"`.
|
|
54
|
+
5. Report: "✗ QA bounced. `<failed>/<total>` tests failed. State → implementing. Next: `/cloverleaf-implement <TASK-ID>`."
|
|
55
|
+
|
|
56
|
+
**Escalate:**
|
|
57
|
+
1. `cloverleaf-cli advance-status <repo_root> <TASK-ID> escalated agent`
|
|
58
|
+
2. Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> qa escalated"`.
|
|
59
|
+
3. Report: "✗ QA escalated. Review infrastructure and retry manually."
|
|
60
|
+
|
|
61
|
+
## Rules
|
|
62
|
+
|
|
63
|
+
- Never push. Read-only. Do not modify source.
|
|
64
|
+
- On illegal state transition, report and stop.
|
package/skills/cloverleaf-run.md
CHANGED
|
@@ -1,41 +1,95 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cloverleaf-run
|
|
3
|
-
description: End-to-end orchestrator.
|
|
3
|
+
description: End-to-end orchestrator. Reads task.risk_class to dispatch fast lane (implement → review → merge) or full pipeline (implement → document → review → [ui-review?] → qa → final-merge). Per-agent bounce counters (max 3 each). Usage — /cloverleaf-run <TASK-ID>.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Cloverleaf — run (orchestrator)
|
|
7
7
|
|
|
8
8
|
## Branch discipline
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Each sub-skill runs from `main`. Between steps, confirm branch is `main` before proceeding. All sub-skills return the user to `main`.
|
|
11
|
+
|
|
12
|
+
## Per-agent bounce budget
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
MAX_REVIEWER_BOUNCES = 3
|
|
16
|
+
MAX_UI_REVIEWER_BOUNCES = 3
|
|
17
|
+
MAX_QA_BOUNCES = 3
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
These counters live in-session (not persisted). Rerunning `/cloverleaf-run` resets.
|
|
11
21
|
|
|
12
22
|
## Steps
|
|
13
23
|
|
|
14
|
-
1. Capture
|
|
24
|
+
1. Capture TASK-ID.
|
|
25
|
+
|
|
26
|
+
2. Load task: `cloverleaf-cli load-task <repo_root> <TASK-ID>`. Verify `status === "pending"`. If not, report and stop.
|
|
27
|
+
|
|
28
|
+
3. Read `task.risk_class`:
|
|
29
|
+
- `"low"` → go to section 4 (Fast Lane)
|
|
30
|
+
- `"high"` → go to section 5 (Full Pipeline)
|
|
31
|
+
|
|
32
|
+
### 4. Fast Lane
|
|
33
|
+
|
|
34
|
+
Initialize `reviewer_bounces = 0`.
|
|
35
|
+
|
|
36
|
+
Loop:
|
|
37
|
+
a. Inline `/cloverleaf-implement <TASK-ID>` steps.
|
|
38
|
+
b. Inline `/cloverleaf-review <TASK-ID>` steps.
|
|
39
|
+
c. Reload task. If `status === "automated-gates"`: pass! Break loop.
|
|
40
|
+
d. If `status === "implementing"`: Reviewer bounced. `reviewer_bounces += 1`. If `reviewer_bounces >= MAX_REVIEWER_BOUNCES`, escalate (section 6). Else continue loop.
|
|
41
|
+
e. Else: unexpected state. Report and stop.
|
|
42
|
+
|
|
43
|
+
After loop: inline `/cloverleaf-merge <TASK-ID>`.
|
|
44
|
+
|
|
45
|
+
### 5. Full Pipeline
|
|
46
|
+
|
|
47
|
+
Initialize `reviewer_bounces = 0`, `ui_reviewer_bounces = 0`, `qa_bounces = 0`.
|
|
48
|
+
|
|
49
|
+
5.1. **Implementer → Documenter → Reviewer loop:**
|
|
50
|
+
|
|
51
|
+
Loop:
|
|
52
|
+
a. Inline `/cloverleaf-implement <TASK-ID>` steps.
|
|
53
|
+
b. Inline `/cloverleaf-document <TASK-ID>` steps.
|
|
54
|
+
c. Inline `/cloverleaf-review <TASK-ID>` steps.
|
|
55
|
+
d. Reload task. If `status === "automated-gates"`: pass! Exit this loop.
|
|
56
|
+
e. If `status === "implementing"`: Reviewer bounced. `reviewer_bounces += 1`. If `reviewer_bounces >= MAX_REVIEWER_BOUNCES`, escalate. Else continue loop.
|
|
57
|
+
f. Else: unexpected. Report and stop.
|
|
15
58
|
|
|
16
|
-
2.
|
|
59
|
+
5.2. **UI-path detection and conditional UI Review:**
|
|
17
60
|
|
|
18
|
-
|
|
61
|
+
```bash
|
|
62
|
+
cloverleaf-cli detect-ui-paths <repo_root> <TASK-ID>
|
|
63
|
+
```
|
|
19
64
|
|
|
20
|
-
|
|
65
|
+
If output is `true`:
|
|
66
|
+
- Advance: `cloverleaf-cli advance-status <repo_root> <TASK-ID> ui-review agent --path=full_pipeline`. Commit.
|
|
67
|
+
- UI-review loop:
|
|
68
|
+
a. Inline `/cloverleaf-ui-review <TASK-ID>` steps.
|
|
69
|
+
b. Reload task. If `status === "qa"`: pass! Exit UI-review loop.
|
|
70
|
+
c. If `status === "implementing"`: UI Reviewer bounced. `ui_reviewer_bounces += 1`. If `>= MAX_UI_REVIEWER_BOUNCES`, escalate. Else return to section 5.1 (Implementer re-runs, which then re-documents, re-reviews).
|
|
71
|
+
d. Else: unexpected. Report and stop.
|
|
21
72
|
|
|
22
|
-
|
|
73
|
+
If output is `false`: skip UI review. Advance: `cloverleaf-cli advance-status <repo_root> <TASK-ID> qa agent --path=full_pipeline`. Commit.
|
|
23
74
|
|
|
24
|
-
|
|
75
|
+
5.3. **QA loop:**
|
|
25
76
|
|
|
26
|
-
|
|
77
|
+
Loop:
|
|
78
|
+
a. Inline `/cloverleaf-qa <TASK-ID>` steps.
|
|
79
|
+
b. Reload task. If `status === "final-gate"`: pass! Exit loop.
|
|
80
|
+
c. If `status === "implementing"`: QA bounced. `qa_bounces += 1`. If `qa_bounces >= MAX_QA_BOUNCES`, escalate. Else return to section 5.1.
|
|
81
|
+
d. Else: unexpected. Report and stop.
|
|
27
82
|
|
|
28
|
-
|
|
83
|
+
5.4. **Final merge:** Inline `/cloverleaf-merge <TASK-ID>` steps (branches to full-pipeline gate per state).
|
|
29
84
|
|
|
30
|
-
|
|
85
|
+
### 6. Escalation
|
|
31
86
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
- Report: "✗ Escalated `<TASK-ID>` after 3 bounces. Review the feedback files under `.cloverleaf/feedback/` and either refine the task or take over manually."
|
|
87
|
+
- `cloverleaf-cli advance-status <repo_root> <TASK-ID> escalated agent`
|
|
88
|
+
- Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> escalated (bounce budget exhausted)"`.
|
|
89
|
+
- Report: "✗ Escalated `<TASK-ID>`. Review `.cloverleaf/feedback/` and either refine the task or take over manually. Counters: reviewer=<N>, ui_reviewer=<N>, qa=<N>."
|
|
36
90
|
|
|
37
91
|
## Rules
|
|
38
92
|
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
93
|
+
- Each agent has its own 3-bounce budget. Bounces from different agents do NOT share counters.
|
|
94
|
+
- On any sub-skill error or escalation, orchestrator stops with clear message.
|
|
95
|
+
- Human merge gate is NOT skipped; confirmation is still required at merge time.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cloverleaf-ui-review
|
|
3
|
+
description: Run the UI Reviewer agent on a task in the `ui-review` state (full pipeline only). Dispatches a subagent to run Playwright + axe-core against a local preview of the feature branch; emits feedback envelope; advances ui-review → qa on pass or loops back to implementing on bounce. Usage — /cloverleaf-ui-review <TASK-ID>.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Cloverleaf — ui-review
|
|
7
|
+
|
|
8
|
+
## Steps
|
|
9
|
+
|
|
10
|
+
0. Ensure you are on `main`. State is authoritative on main. Run:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
cd <repo_root>
|
|
14
|
+
current=$(git rev-parse --abbrev-ref HEAD)
|
|
15
|
+
if [ "$current" != "main" ]; then git checkout main; fi
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
If main has uncommitted changes, stop and report.
|
|
19
|
+
|
|
20
|
+
1. Capture the TASK-ID argument.
|
|
21
|
+
|
|
22
|
+
2. Load the task:
|
|
23
|
+
```
|
|
24
|
+
~/.claude/plugins/cloverleaf/bin/cloverleaf-cli load-task <repo_root> <TASK-ID>
|
|
25
|
+
```
|
|
26
|
+
Verify `status === "ui-review"`. If not, report and stop.
|
|
27
|
+
|
|
28
|
+
3. Confirm feature branch exists: `git rev-parse --verify cloverleaf/<TASK-ID>`. If missing, report and stop.
|
|
29
|
+
|
|
30
|
+
4. Allocate a free `preview_port` via Node:
|
|
31
|
+
```bash
|
|
32
|
+
PREVIEW_PORT=$(node -e "const net=require('net');const s=net.createServer();s.listen(0,()=>{console.log(s.address().port);s.close()})")
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
5. Compute diff for the subagent context:
|
|
36
|
+
```bash
|
|
37
|
+
git diff main..cloverleaf/<TASK-ID>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
6. Dispatch the UI Reviewer subagent via the Task tool:
|
|
41
|
+
- `subagent_type`: `general-purpose`
|
|
42
|
+
- `model`: `sonnet`
|
|
43
|
+
- Prompt: contents of `~/.claude/plugins/cloverleaf/prompts/ui-reviewer.md` with substitutions for `{{task}}`, `{{diff}}`, `{{branch}}`, `{{base_branch}}`, `{{repo_root}}`, `{{preview_port}}`.
|
|
44
|
+
|
|
45
|
+
7. Parse the subagent's response. Expect `{"verdict": "pass"|"bounce"|"escalate", "summary": "...", "findings": [...]}`.
|
|
46
|
+
|
|
47
|
+
8. Branch on verdict:
|
|
48
|
+
|
|
49
|
+
**Pass:**
|
|
50
|
+
```
|
|
51
|
+
cloverleaf-cli advance-status <repo_root> <TASK-ID> qa agent --path=full_pipeline
|
|
52
|
+
```
|
|
53
|
+
Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> ui-review passed → qa"`.
|
|
54
|
+
Report: "✓ UI Review passed. State → qa. Next: `/cloverleaf-qa <TASK-ID>`."
|
|
55
|
+
|
|
56
|
+
**Bounce:**
|
|
57
|
+
1. Write feedback envelope to temp file: `echo '<envelope-json>' > /tmp/cloverleaf-fb-u.json`
|
|
58
|
+
2. `cloverleaf-cli write-feedback <repo_root> <TASK-ID> /tmp/cloverleaf-fb-u.json --prefix=u` — captures path like `.cloverleaf/feedback/<TASK-ID>-u<N>.json`.
|
|
59
|
+
3. `cloverleaf-cli advance-status <repo_root> <TASK-ID> implementing agent --path=full_pipeline`
|
|
60
|
+
4. Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> ui-review bounced → implementing"`.
|
|
61
|
+
5. Report: "✗ UI Review bounced. Findings: <summarize by severity>. State → implementing. Next: `/cloverleaf-implement <TASK-ID>`."
|
|
62
|
+
|
|
63
|
+
**Escalate:**
|
|
64
|
+
1. `cloverleaf-cli advance-status <repo_root> <TASK-ID> escalated agent`
|
|
65
|
+
2. Commit: `git add .cloverleaf/ && git commit -m "cloverleaf: <TASK-ID> ui-review escalated"`.
|
|
66
|
+
3. Report: "✗ UI Review escalated (infrastructure issue). Review and retry manually."
|
|
67
|
+
|
|
68
|
+
## Rules
|
|
69
|
+
|
|
70
|
+
- Never push.
|
|
71
|
+
- Do not modify source code — UI Reviewer is read-only.
|
|
72
|
+
- Always teardown preview server + worktree on error.
|
|
73
|
+
- On illegal state transition, report and stop without partial commits.
|