@muggleai/works 4.10.1 → 4.11.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/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/.cursor-plugin/plugin.json +1 -1
- package/dist/plugin/skills/_shared/pr-followup-helpers.md +150 -0
- package/dist/plugin/skills/do/build.md +51 -0
- package/dist/plugin/skills/do/e2e-acceptance.md +2 -2
- package/dist/plugin/skills/do/impact-analysis.md +2 -2
- package/dist/plugin/skills/do/open-prs.md +67 -78
- package/dist/plugin/skills/do/pre-flight.md +3 -3
- package/dist/plugin/skills/do/requirements.md +2 -2
- package/dist/plugin/skills/do/unit-tests.md +2 -2
- package/dist/plugin/skills/muggle-do/SKILL.md +34 -77
- package/dist/plugin/skills/muggle-feedback/SKILL.md +2 -1
- package/dist/plugin/skills/muggle-feedback/ops/submit.md +16 -3
- package/dist/plugin/skills/muggle-pr-followup/SKILL.md +59 -0
- package/dist/plugin/skills/muggle-pr-followup/contract.md +191 -0
- package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +14 -0
- package/dist/release-manifest.json +4 -4
- package/package.json +6 -6
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/skills/_shared/pr-followup-helpers.md +150 -0
- package/plugin/skills/do/build.md +51 -0
- package/plugin/skills/do/e2e-acceptance.md +2 -2
- package/plugin/skills/do/impact-analysis.md +2 -2
- package/plugin/skills/do/open-prs.md +67 -78
- package/plugin/skills/do/pre-flight.md +3 -3
- package/plugin/skills/do/requirements.md +2 -2
- package/plugin/skills/do/unit-tests.md +2 -2
- package/plugin/skills/muggle-do/SKILL.md +34 -77
- package/plugin/skills/muggle-feedback/SKILL.md +2 -1
- package/plugin/skills/muggle-feedback/ops/submit.md +16 -3
- package/plugin/skills/muggle-pr-followup/SKILL.md +59 -0
- package/plugin/skills/muggle-pr-followup/contract.md +191 -0
- package/plugin/skills/muggle-test-feature-local/SKILL.md +14 -0
- package/dist/plugin/skills/do/pr-followup.md +0 -225
- package/dist/plugin/skills/do/validate-code.md +0 -38
- package/dist/plugin/skills/muggle-do-pr-followup/SKILL.md +0 -37
- package/plugin/skills/do/pr-followup.md +0 -225
- package/plugin/skills/do/validate-code.md +0 -38
- package/plugin/skills/muggle-do-pr-followup/SKILL.md +0 -37
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# PR follow-up helpers
|
|
2
|
+
|
|
3
|
+
Generic operational guidance for running a PR-comment follow-up loop on GitHub: reviewer allow-list resolution, reply routing across the different comment endpoints, and a classification rule for reviewer comments with worked examples and a borderline test. Caller-agnostic — any loop that picks one comment per tick and decides what to do with it can drive off this doc.
|
|
4
|
+
|
|
5
|
+
The classification produces an **action shape** (in-place change, deep-cycle through the caller's implementation pipeline, reply only, escalate, etc.) — the caller maps each shape to its specific routing (which stage to dispatch, which terminal-message template to use, which reply endpoint to hit).
|
|
6
|
+
|
|
7
|
+
## Resolving the reviewer allow-list
|
|
8
|
+
|
|
9
|
+
Stage 8 only acts on comments authored by users in the **allow-list** = (requested reviewers ∪ CODEOWNERS) − bots − PR author. Re-resolve every tick (decision 9 in the design doc).
|
|
10
|
+
|
|
11
|
+
### Step 1: requested reviewers
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
gh pr view <number> --repo <owner>/<repo> --json reviewRequests,author
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`reviewRequests` is an array of `{ login? , slug? }`. User reviewers have `login`; team reviewers have `slug` (and `name`). Expand teams to member logins:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
gh api orgs/<org>/teams/<slug>/members --jq '.[].login'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Record `prAuthor = author.login` for the exclusion step.
|
|
24
|
+
|
|
25
|
+
### Step 2: CODEOWNERS
|
|
26
|
+
|
|
27
|
+
Look for the file in this order — first hit wins:
|
|
28
|
+
|
|
29
|
+
1. `.github/CODEOWNERS`
|
|
30
|
+
2. `CODEOWNERS`
|
|
31
|
+
3. `docs/CODEOWNERS`
|
|
32
|
+
|
|
33
|
+
Read from the PR's **head branch** (not master), because a PR that adds CODEOWNERS should be allowed to take effect once merged but is informational while open. In practice this means:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
gh api repos/<owner>/<repo>/contents/.github/CODEOWNERS?ref=<head_sha> --jq '.content' | base64 -d
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Parse line-by-line:
|
|
40
|
+
|
|
41
|
+
- Skip blank lines and lines starting with `#`.
|
|
42
|
+
- Each line is `<pattern> <owner1> <owner2> ...`.
|
|
43
|
+
- Owners are either `@user` or `@org/team`. Strip the leading `@`.
|
|
44
|
+
- For our purposes we don't need to match `<pattern>` against changed files — CODEOWNERS membership for the *repo* is enough. Collect the union of all owners across all lines.
|
|
45
|
+
|
|
46
|
+
Expand `@org/team` to member logins via the orgs/teams/members endpoint (same as Step 1).
|
|
47
|
+
|
|
48
|
+
If no CODEOWNERS file exists in any of the three locations, the CODEOWNERS contribution is empty. Don't fail.
|
|
49
|
+
|
|
50
|
+
### Step 3: filter
|
|
51
|
+
|
|
52
|
+
Allow-list = (requested reviewers ∪ CODEOWNERS) − `{prAuthor}` − bot logins.
|
|
53
|
+
|
|
54
|
+
Bot logins are any login matching:
|
|
55
|
+
|
|
56
|
+
- Ends with `[bot]` (e.g. `dependabot[bot]`)
|
|
57
|
+
- Exact match in the standard list: `dependabot`, `github-actions`, `renovate`, `mergify`
|
|
58
|
+
|
|
59
|
+
A comment author not in the allow-list is silently ignored — do not reply, do not address.
|
|
60
|
+
|
|
61
|
+
## Reply routing
|
|
62
|
+
|
|
63
|
+
GitHub's PR APIs are not uniform across comment types. Route by parent type.
|
|
64
|
+
|
|
65
|
+
### Line-level review comment
|
|
66
|
+
|
|
67
|
+
A comment attached to a specific file:line that belongs to a review thread. This is the **most common** path.
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
gh api \
|
|
71
|
+
--method POST \
|
|
72
|
+
-H "Accept: application/vnd.github+json" \
|
|
73
|
+
/repos/<owner>/<repo>/pulls/<number>/comments/<comment_id>/replies \
|
|
74
|
+
-f body="Done in $(git rev-parse --short HEAD) — renamed \`fooBar\` to \`foo_bar\`."
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The reply lands in the same review thread. The reply itself becomes a new line-level comment with `in_reply_to_id = <comment_id>`.
|
|
78
|
+
|
|
79
|
+
### Review body (CHANGES_REQUESTED with no inline comments)
|
|
80
|
+
|
|
81
|
+
A reviewer left a summary review with `state: CHANGES_REQUESTED` and a body, but **no** inline comments. GitHub has no "reply to review body" endpoint — post a top-level PR comment that references the review:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
gh pr comment <number> --repo <owner>/<repo> --body "Re: review #<review_id> — done in $(git rev-parse --short HEAD)."
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Failing CI check
|
|
88
|
+
|
|
89
|
+
No reply. The fix commit IS the response. Include the failing check name in the commit subject so the connection is obvious in `git log`:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
fix(ci): typecheck — narrow type of foo
|
|
93
|
+
fix(ci): lint — remove unused import
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Never
|
|
97
|
+
|
|
98
|
+
- Never post a top-level comment in reply to a line-level comment. It loses thread context and pollutes the PR conversation tab.
|
|
99
|
+
- Never `gh pr review --comment` for replies — that endpoint is for *new* reviews, not replies.
|
|
100
|
+
- Never reply twice to the same comment. The cursor in `last_seen.json` is the only re-entry guard; advance it after every reply.
|
|
101
|
+
|
|
102
|
+
## Classify
|
|
103
|
+
|
|
104
|
+
Classify the **review as a unit**, not individual comments.
|
|
105
|
+
|
|
106
|
+
| Class | Signal | Action |
|
|
107
|
+
| :---- | :----- | :----- |
|
|
108
|
+
| **actionable** | Review names at least one concrete change or asks an answerable question. Soft phrasing counts when there's a concrete referent. | Treat as amended requirements; run the caller's implementation cycle; reply with one summary referencing the new SHA. |
|
|
109
|
+
| **ambiguous** | No actionable signal — pure vibes, contradictory, or depends on knowledge the loop can't access. | Escalate once with two interpretations; pause the PR. |
|
|
110
|
+
|
|
111
|
+
Default to **actionable**. CI catches wrong attempts; reviewers correct on the next round. Escalation is a round-trip with an absent user — reserve it.
|
|
112
|
+
|
|
113
|
+
Reply summary shape:
|
|
114
|
+
|
|
115
|
+
- **actionable**: `Addressed review <review_id> in <sha> — cycle ran clean (or: with <N> failures, see walkthrough).`
|
|
116
|
+
- **ambiguous**: no bot reply.
|
|
117
|
+
|
|
118
|
+
### Worked examples — Actionable reviews
|
|
119
|
+
|
|
120
|
+
| Review (summarized) | Why actionable |
|
|
121
|
+
| :------------------ | :------------- |
|
|
122
|
+
| 3 comments: "rename `fooBar` to `foo_bar`", "use `const` here", "fix this typo" | Three concrete edits |
|
|
123
|
+
| 1 comment: "could the procedure be simpler?" | Soft-phrased but the intent is clear — simplify; pick the best interpretation, run the cycle, reply with what was changed |
|
|
124
|
+
| Review body: "Mostly looks good. Two things: extract the validation into a helper, and add a null check before the lookup." Plus 0 line comments. | Two concrete directives in the body |
|
|
125
|
+
| 4 comments: "why this approach?", "is this called from X?", "does this need to handle empty array?", "what's the perf here?" | All questions but each is answerable; cycle dispatches an "answer + maybe-fix" pass and the reply summary captures each answer |
|
|
126
|
+
| 1 comment: "rewrite this module — the architecture doesn't match the spec" | Substantive rebuild, but the direction is clear: redo the module per the spec |
|
|
127
|
+
| 1 comment: "I'd lean toward the bar.ts pattern" | Concrete referent (bar.ts) — apply that pattern |
|
|
128
|
+
|
|
129
|
+
The single review goes through one full cycle regardless of comment count.
|
|
130
|
+
|
|
131
|
+
### Worked examples — Ambiguous reviews
|
|
132
|
+
|
|
133
|
+
| Review (summarized) | Why ambiguous |
|
|
134
|
+
| :------------------ | :------------ |
|
|
135
|
+
| 1 comment: "👀" / "hmm" / ":thinking:" | No signal at all |
|
|
136
|
+
| 1 comment: "this is wrong" with no target or direction | Asserts a problem but doesn't propose a fix |
|
|
137
|
+
| 2 comments: "use X" + "but actually don't use X" | Self-contradicting — can't reconcile without the reviewer |
|
|
138
|
+
| 1 comment: "we discussed this offline — please address" | References context the loop doesn't have |
|
|
139
|
+
| 1 comment: "won't this break the prod migration we did last week?" | Implicit change request gated on knowledge the loop can't access |
|
|
140
|
+
| Mixed: 2 concrete directives + 1 comment "but also, rethink the whole approach" | The "rethink the whole approach" subverts the other two; escalate to confirm scope |
|
|
141
|
+
|
|
142
|
+
Escalate per the caller's escalation procedure (write the review id to the cursor's escalated set, emit one terminal message with both interpretations, pause the PR until the user resolves).
|
|
143
|
+
|
|
144
|
+
### Borderline rule
|
|
145
|
+
|
|
146
|
+
If you can paraphrase the review's intent as **"do X"** with X being a concrete change (one or several) — it's actionable. Pick the best interpretation and dispatch the cycle.
|
|
147
|
+
|
|
148
|
+
If you can paraphrase it only as **"the reviewer is dissatisfied but I can't tell with what"** — it's ambiguous.
|
|
149
|
+
|
|
150
|
+
When the review mixes both ("3 concrete directives + 1 dissatisfaction"), the safer move is usually to action the concrete directives and ask about the dissatisfaction in the reply summary. Pure ambiguity means *nothing* in the review is actionable.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Build Agent (Stage 3)
|
|
2
|
+
|
|
3
|
+
Implement the code change for this dev cycle. Read the frozen requirements from stage 2, produce the edits in each affected repo's worktree, and commit.
|
|
4
|
+
|
|
5
|
+
## Turn preamble
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
**Stage 3 — Build** — implementing the change per the frozen requirements.
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Inputs
|
|
12
|
+
|
|
13
|
+
- `requirements.md` from stage 2: goal, acceptance criteria, affected repos.
|
|
14
|
+
- `state.md` from pre-flight: worktree path per repo, target branch, anything else the build needs to know about the environment.
|
|
15
|
+
|
|
16
|
+
## Your job
|
|
17
|
+
|
|
18
|
+
For each affected repo:
|
|
19
|
+
|
|
20
|
+
1. **Re-read `requirements.md`.** Treat goal + AC as frozen. If something is unclear at this stage, that's a pre-flight bug — escalate, do not improvise.
|
|
21
|
+
2. **Apply the change** in the repo's worktree. Edit existing files first; create new files only when the requirements demand it. Match the surrounding code's style, naming, and file layout.
|
|
22
|
+
3. **Don't add what wasn't asked for.** No speculative abstractions, no extra logging, no "while I'm here" refactors. Three similar lines is better than a premature abstraction.
|
|
23
|
+
4. **Commit** with a conventional-commit subject:
|
|
24
|
+
- `feat(<scope>): <short>` for new behavior
|
|
25
|
+
- `fix(<scope>): <short>` for bug fixes
|
|
26
|
+
- `refactor(<scope>): <short>` for reshape
|
|
27
|
+
- `docs(...)`, `chore(...)`, `test(...)` as appropriate
|
|
28
|
+
|
|
29
|
+
The body explains *why* when the why is non-obvious. The diff already says *what*.
|
|
30
|
+
|
|
31
|
+
## Output
|
|
32
|
+
|
|
33
|
+
Per repo:
|
|
34
|
+
|
|
35
|
+
**Repo:** name
|
|
36
|
+
- Files edited / created: list
|
|
37
|
+
- Commit subject: `<conventional commit>`
|
|
38
|
+
- Notable choices: anything that needed a judgment call (briefly)
|
|
39
|
+
|
|
40
|
+
**Overall:** READY for impact analysis | BLOCKED — reason
|
|
41
|
+
|
|
42
|
+
If a requirement is fundamentally unimplementable as written, halt and escalate with the specific blocker — do not ship a half-finished implementation.
|
|
43
|
+
|
|
44
|
+
## Re-entry from stage 8
|
|
45
|
+
|
|
46
|
+
Stage 8 (PR follow-up) may dispatch back to this stage when a reviewer comment requires real implementation work rather than an in-place doc edit. When re-entered:
|
|
47
|
+
|
|
48
|
+
- The dispatch from stage 8 carries the comment(s) that triggered the re-build as additional context; treat them as amendments to the goal/AC for this iteration.
|
|
49
|
+
- Continue on the existing branch — do not re-create the worktree.
|
|
50
|
+
- Cycle forward through impact analysis → unit tests → E2E → open PR (which is a no-op since the PR already exists; just push).
|
|
51
|
+
- Stage 8 resumes polling after the push lands.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# E2E Acceptance Agent (Stage 6
|
|
1
|
+
# E2E Acceptance Agent (Stage 6)
|
|
2
2
|
|
|
3
3
|
You are executing E2E acceptance validation for the muggle-do cycle.
|
|
4
4
|
|
|
@@ -11,7 +11,7 @@ Standalone subagent (different invocation path, used by `muggle-test` Mode C): [
|
|
|
11
11
|
Start the turn with:
|
|
12
12
|
|
|
13
13
|
```
|
|
14
|
-
**Stage 6
|
|
14
|
+
**Stage 6 — E2E acceptance** — running browser tests against the validation target from pre-flight.
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
## Design
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Impact Analysis Agent (Stage
|
|
1
|
+
# Impact Analysis Agent (Stage 4)
|
|
2
2
|
|
|
3
3
|
You are analyzing git repositories to determine which ones have actual code changes that need to go through the dev cycle pipeline.
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ You are analyzing git repositories to determine which ones have actual code chan
|
|
|
7
7
|
Start the turn with:
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
**Stage
|
|
10
|
+
**Stage 4 — Impact analysis** — diffing each affected repo against its default branch.
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
## Input
|
|
@@ -1,114 +1,103 @@
|
|
|
1
|
-
# PR Creation Agent (Stage 7
|
|
1
|
+
# PR Creation Agent (Stage 7 — Open PR)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Open a pull request for each repo that has changes. If an E2E walkthrough report is available from the previous stage, attach it. Honor preference gates. Hand off to stage 8 once done.
|
|
4
4
|
|
|
5
5
|
## Turn preamble
|
|
6
6
|
|
|
7
|
-
Start the turn with:
|
|
8
|
-
|
|
9
7
|
```
|
|
10
|
-
**Stage 7
|
|
8
|
+
**Stage 7 — Open PR** — pushing the branch and opening the PR.
|
|
11
9
|
```
|
|
12
10
|
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
**You MUST invoke `muggle-pr-visual-walkthrough` (Mode B) to render the E2E section of the PR body.** Hand-writing the PR body with a text summary and `gh pr create` is a stage failure — reviewers rely on the dashboard links and per-step screenshots the walkthrough produces.
|
|
16
|
-
|
|
17
|
-
If the E2E stage was skipped (validation was `unit-only` or `skip`), you may omit the walkthrough section — but mark the PR title with `[UNVERIFIED]` or `[UNIT-ONLY]` accordingly, and record the reason in the PR body under `## Validation`.
|
|
18
|
-
|
|
19
|
-
Before calling `gh pr create`, self-check:
|
|
11
|
+
## Inputs
|
|
20
12
|
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
13
|
+
- Per-repo: name, path, branch.
|
|
14
|
+
- Requirements: goal, acceptance criteria.
|
|
15
|
+
- **Optional** E2E acceptance report from stage 6 — only present when validation ran. Produced by [`e2e-acceptance.md`](e2e-acceptance.md); schema is canonical in [`muggle-pr-visual-walkthrough/SKILL.md`](../muggle-pr-visual-walkthrough/SKILL.md) (Zod-validated by the CLI).
|
|
24
16
|
|
|
25
|
-
|
|
17
|
+
## Per repo
|
|
26
18
|
|
|
27
|
-
|
|
19
|
+
0. **`autoCreatePR` gate** — apply per [`../muggle-preferences/preference-gates/autoCreatePR.md`](../muggle-preferences/preference-gates/autoCreatePR.md). On skip, record the reason in `result.md` and move on.
|
|
28
20
|
|
|
29
|
-
|
|
30
|
-
- Per-repo: repo name, path, branch name
|
|
31
|
-
- Requirements: goal, acceptance criteria
|
|
32
|
-
- E2E acceptance report: passed/failed test cases, each with:
|
|
33
|
-
- `testCaseId`, `testScriptId`, `runId`, `projectId`
|
|
34
|
-
- `viewUrl`: link to view run on muggle-ai.com
|
|
35
|
-
- `steps`: array of `{ stepIndex, action, screenshotUrl }`
|
|
36
|
-
- `failureStepIndex` and `error` (if failed)
|
|
37
|
-
- `artifactsDir` (for local debugging)
|
|
38
|
-
- `description` and `useCaseName` (optional but recommended) — test case one-liner and parent use case title; drive the grouped overview and the per-test collapsible headers in the rendered walkthrough. Prefer values already in the `e2e-acceptance.md` stage's conversation context; only call `muggle-remote-test-case-get` / `muggle-remote-use-case-get` for anything you don't already have.
|
|
21
|
+
1. **Push:** `git push -u origin <branch>` in the repo directory.
|
|
39
22
|
|
|
40
|
-
|
|
23
|
+
2. **Title** (under 70 chars):
|
|
24
|
+
- E2E report exists and has failures → `[E2E FAILING] <goal>`
|
|
25
|
+
- No E2E report at all (validation was `unit-only` or `skip`) → `[UNVERIFIED] <goal>` or `[UNIT-ONLY] <goal>` to match the validation strategy
|
|
26
|
+
- Otherwise → `<goal>`
|
|
41
27
|
|
|
42
|
-
|
|
28
|
+
3. **Body** — assemble in order:
|
|
29
|
+
- `## Goal` — from requirements.
|
|
30
|
+
- `## Acceptance Criteria` — bulleted; omit section if empty.
|
|
31
|
+
- `## Changes` — summary of what changed in this repo.
|
|
32
|
+
- `## Validation` — one line: link to E2E report, or `unit-only`, or `skip — <reason>`.
|
|
33
|
+
- **If an E2E report exists,** invoke [`muggle-pr-visual-walkthrough`](../muggle-pr-visual-walkthrough/SKILL.md) Mode B to render the walkthrough block. Embed the returned `body` verbatim (it brings its own `## E2E Acceptance Results` heading). If no report, skip this block entirely.
|
|
43
34
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
1. **Push the branch** to origin: `git push -u origin <branch-name>` in the repo directory.
|
|
47
|
-
2. **Build the PR title:**
|
|
48
|
-
- If E2E acceptance tests have failures: `[E2E FAILING] <goal>`
|
|
49
|
-
- Otherwise: `<goal>`
|
|
50
|
-
- Keep under 70 characters
|
|
51
|
-
3. **Render the E2E acceptance block** by invoking the shared `muggle-pr-visual-walkthrough` skill in **Mode B** (render-only for embedding). See "Rendering the E2E acceptance block via the shared skill" below. You receive `{body, comment}` where `body` is the E2E markdown block and `comment` is a non-null overflow comment only when the content exceeds the CLI's byte budget.
|
|
52
|
-
4. **Build the PR body** by concatenating, in order:
|
|
53
|
-
- `## Goal` — the requirements goal
|
|
54
|
-
- `## Acceptance Criteria` — bulleted list (omit section if empty)
|
|
55
|
-
- `## Changes` — summary of what changed in this repo
|
|
56
|
-
- The `body` field from the skill output (already contains its own `## E2E Acceptance Results` header — do not add another)
|
|
57
|
-
5. **Create the PR** using `gh pr create --title "..." --body "..." --head <branch>` in the repo directory.
|
|
58
|
-
6. **Capture the PR URL** and extract the PR number.
|
|
59
|
-
7. **Post the overflow `comment` only if it is non-null.** In the common case, `comment` is `null` and nothing is posted. Never post speculatively.
|
|
35
|
+
4. **Create:** `gh pr create --title "..." --body "..." --head <branch>`. Capture the PR URL and number.
|
|
60
36
|
|
|
37
|
+
5. **Overflow comment:** if the walkthrough skill returned a non-null `comment`, post it once:
|
|
61
38
|
```bash
|
|
62
39
|
jq -r '.comment' /tmp/muggle-pr-section.json | gh pr comment <PR#> --body-file -
|
|
63
40
|
```
|
|
41
|
+
Never post when `comment` is `null`.
|
|
64
42
|
|
|
65
|
-
##
|
|
66
|
-
|
|
67
|
-
**Do not hand-write the `## E2E Acceptance Results` markdown, and do not call `muggle build-pr-section` directly from this stage.** The rendering workflow is owned by the shared **`muggle-pr-visual-walkthrough`** skill (see `plugin/skills/muggle-pr-visual-walkthrough/SKILL.md`), which wraps the CLI and enforces the `E2eReport` input contract with a Zod schema.
|
|
68
|
-
|
|
69
|
-
### Input — the `E2eReport` JSON
|
|
70
|
-
|
|
71
|
-
The `e2e-acceptance.md` stage already produces an `E2eReport` with the exact shape the skill expects (`projectId` + `tests[]` with per-test `name`, `testCaseId`, `testScriptId`, `runId`, `viewUrl`, `status`, and `steps[]` of `{stepIndex, action, screenshotUrl}`; failed tests additionally have `failureStepIndex`, `error`, and optionally `artifactsDir`; every test may additionally carry `description` and `useCaseName` — optional but recommended — which drive the grouped overview and per-test collapsible headers in the rendered walkthrough). Pass it through unchanged — do not reshape it. The full schema is documented in the shared skill.
|
|
43
|
+
## Stage 8 handoff
|
|
72
44
|
|
|
73
|
-
|
|
45
|
+
After every repo is processed, build the manifest and dispatch **one follow-up loop per opened PR**. The dispatches are the LAST action this stage takes — once they fire, the original session is free.
|
|
74
46
|
|
|
75
|
-
|
|
47
|
+
Write `.muggle-do/sessions/<slug>/prs.json` with one entry per **opened** PR (skip repos where `autoCreatePR` short-circuited or PR creation failed):
|
|
76
48
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
Mode A (where the skill itself finds an existing PR and posts a `gh pr comment`) is **not used by `muggle-do`** — it's for interactive callers like `muggle-test` that are mid-development with a PR already open. `muggle-do` always creates new PRs, so it always uses Mode B.
|
|
49
|
+
```json
|
|
50
|
+
[{ "repo": "owner/repo", "number": 142, "url": "...", "head_sha": "...", "state": "open" }]
|
|
51
|
+
```
|
|
82
52
|
|
|
83
|
-
|
|
53
|
+
Seed `.muggle-do/sessions/<slug>/last_seen.json` keyed by `"<owner>/<repo>#<n>"` with the empty-cursor shape (full shape in [`../muggle-pr-followup/contract.md`](../muggle-pr-followup/contract.md)). Stage 7 only seeds; each per-PR loop owns advancing its own cursor.
|
|
54
|
+
|
|
55
|
+
Also seed `.muggle-do/sessions/<slug>/cycle.json` — the muggle-do implementation cycle declaration the follow-up loop will invoke on each actionable review:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"cycleName": "muggle-do dev cycle",
|
|
60
|
+
"steps": [
|
|
61
|
+
{ "stage": 3, "file": "../do/build.md" },
|
|
62
|
+
{ "stage": 4, "file": "../do/impact-analysis.md" },
|
|
63
|
+
{ "stage": 5, "file": "../do/unit-tests.md" },
|
|
64
|
+
{ "stage": 6, "file": "../do/e2e-acceptance.md" },
|
|
65
|
+
{ "name": "post-walkthrough", "skill": "muggle-pr-visual-walkthrough", "mode": "A" }
|
|
66
|
+
],
|
|
67
|
+
"pushHandler": "git push origin <branch>",
|
|
68
|
+
"useSubagent": false
|
|
69
|
+
}
|
|
70
|
+
```
|
|
84
71
|
|
|
85
|
-
|
|
72
|
+
For each entry in `prs.json`, dispatch its own loop as the final action:
|
|
73
|
+
```
|
|
74
|
+
/loop 1m /muggle:muggle-pr-followup <slug> <pr-number>
|
|
75
|
+
```
|
|
76
|
+
Resolve `<slug>` from the session directory's basename. One loop per PR — multi-repo sessions opening N PRs result in N independent loops, each tracking its own PR's review thread.
|
|
86
77
|
|
|
87
|
-
|
|
88
|
-
- Post the overflow `comment` as a follow-up **only when it is non-null** (see step 7 above).
|
|
89
|
-
- If the CLI exited non-zero, the skill surfaces the stderr error — do not swallow it, surface it to the user.
|
|
78
|
+
If `prs.json` is empty (all repos skipped, or all PR creations failed), **do not dispatch** — record the reason in `result.md` and exit.
|
|
90
79
|
|
|
91
|
-
|
|
80
|
+
## Self-check before exit
|
|
92
81
|
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
82
|
+
- [ ] Every non-skipped repo got `gh pr create` to succeed.
|
|
83
|
+
- [ ] When an E2E report existed, the walkthrough block was rendered via Mode B (not hand-written).
|
|
84
|
+
- [ ] Overflow `comment` was posted only when non-null.
|
|
85
|
+
- [ ] `prs.json` and `last_seen.json` reflect the PRs actually opened.
|
|
86
|
+
- [ ] If `prs.json` is non-empty, the `/loop` dispatch was the last action.
|
|
96
87
|
|
|
97
88
|
## Output
|
|
98
89
|
|
|
99
|
-
**PRs Created:**
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
**
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
**Errors:** (any repos where PR creation or comment posting failed, with the error message)
|
|
90
|
+
**PRs Created:** repo → URL
|
|
91
|
+
**Skipped:** repo → reason (when `autoCreatePR` short-circuited)
|
|
92
|
+
**Overflow comments posted:** repo → PR #
|
|
93
|
+
**Stage 8:** `Watching <N> PR(s) — one /loop 1m /muggle:muggle-pr-followup <slug> <pr#> per PR` | `No PRs to watch — stage 8 not dispatched`
|
|
94
|
+
**Errors:** repo → message
|
|
106
95
|
|
|
107
|
-
## Post-merge cleanup
|
|
96
|
+
## Post-merge cleanup
|
|
108
97
|
|
|
109
|
-
|
|
98
|
+
Gated by `autoCleanup`. Fires in a follow-up turn after merge — never from this stage. See [`../_shared/post-merge-cleanup.md`](../_shared/post-merge-cleanup.md).
|
|
110
99
|
|
|
111
|
-
|
|
100
|
+
Append one short reminder tied to the gate value:
|
|
112
101
|
|
|
113
102
|
- `always` → `Once merged, I'll run the cleanup sequence automatically.`
|
|
114
103
|
- `never` → omit.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Pre-flight Agent (Stage 1
|
|
1
|
+
# Pre-flight Agent (Stage 1)
|
|
2
2
|
|
|
3
3
|
You are running the **only user-facing stage** of the muggle-do dev cycle. Your job is to consolidate every ambiguity — task scope, repos, validation strategy, environment, credentials, PR target — into a **single turn** so the rest of the cycle can run unattended.
|
|
4
4
|
|
|
@@ -9,7 +9,7 @@ You are running the **only user-facing stage** of the muggle-do dev cycle. Your
|
|
|
9
9
|
Start the turn with:
|
|
10
10
|
|
|
11
11
|
```
|
|
12
|
-
**Stage 1
|
|
12
|
+
**Stage 1 — Pre-flight** — consolidating everything the cycle needs before going silent.
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Input
|
|
@@ -94,7 +94,7 @@ Also initialize `iterations/001.md` with a header:
|
|
|
94
94
|
```markdown
|
|
95
95
|
# Iteration 001 — <ISO-8601 timestamp>
|
|
96
96
|
|
|
97
|
-
### Stage 1
|
|
97
|
+
### Stage 1 — Pre-flight (<timestamp>)
|
|
98
98
|
|
|
99
99
|
<verbatim copy of pre-flight answers>
|
|
100
100
|
```
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Requirements Analysis Agent (Stage 2
|
|
1
|
+
# Requirements Analysis Agent (Stage 2)
|
|
2
2
|
|
|
3
3
|
You are analyzing a user's task description to extract structured requirements for an autonomous development cycle.
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ You are analyzing a user's task description to extract structured requirements f
|
|
|
7
7
|
Start the turn with:
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
**Stage 2
|
|
10
|
+
**Stage 2 — Requirements** — extracting structured goals from the pre-flight-clarified task.
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
Pre-flight already resolved ambiguity via the consolidated questionnaire. **Do not ask the user any questions here** — infer silently and record assumptions in Notes.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Unit Test Runner Agent (Stage 5
|
|
1
|
+
# Unit Test Runner Agent (Stage 5)
|
|
2
2
|
|
|
3
3
|
You are running unit tests for each repository that has changes in the dev cycle pipeline.
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ You are running unit tests for each repository that has changes in the dev cycle
|
|
|
7
7
|
Start the turn with:
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
**Stage 5
|
|
10
|
+
**Stage 5 — Unit tests** — running each repo's test suite.
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
## Input
|
|
@@ -8,108 +8,65 @@ disable-model-invocation: true
|
|
|
8
8
|
|
|
9
9
|
> Telemetry first step: see [`_shared/telemetry-emit.md`](../_shared/telemetry-emit.md). Use `skillName: "muggle-do"`.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Runs an autonomous dev cycle from requirements to PR. **Fire and review:** the user answers one pre-flight questionnaire, then walks away.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
For maintenance tasks, use the dedicated skills:
|
|
13
|
+
For maintenance, use the dedicated skills:
|
|
16
14
|
|
|
17
15
|
- `/muggle:muggle-status`
|
|
18
16
|
- `/muggle:muggle-repair`
|
|
19
17
|
- `/muggle:muggle-upgrade`
|
|
20
18
|
|
|
21
|
-
##
|
|
22
|
-
|
|
23
|
-
Gates run per [`preference-gates/README.md`](../muggle-preferences/preference-gates/README.md).
|
|
24
|
-
|
|
25
|
-
| Preference | Stage | Decision it gates |
|
|
26
|
-
|------------|-------|-------------------|
|
|
27
|
-
| `autoUseWorktree` | 1 (pre-flight) | Create a worktree (see [`_shared/use-worktrees.md`](../_shared/use-worktrees.md)) |
|
|
28
|
-
| `autoE2ETest` | 6 (e2e-acceptance) | Run E2E every cycle (default `always`), or fold the question into pre-flight |
|
|
29
|
-
| `autoRebase` | 6 (e2e-acceptance) | Rebase onto `origin/<default>` (see [`_shared/rebase-before-e2e.md`](../_shared/rebase-before-e2e.md)) |
|
|
30
|
-
| `autoCreatePR` | 7 (open-prs) | Push the branch and open the PR (see [`do/open-prs.md`](../do/open-prs.md)) |
|
|
31
|
-
| `autoCleanup` | 7 (post-merge) | Run cleanup sequence (see [`_shared/post-merge-cleanup.md`](../_shared/post-merge-cleanup.md)) |
|
|
32
|
-
|
|
33
|
-
## Input routing
|
|
34
|
-
|
|
35
|
-
Treat `$ARGUMENTS` as the user command:
|
|
36
|
-
|
|
37
|
-
- Empty / `help` / `menu` / `?` → show menu and session selector.
|
|
38
|
-
- Anything else → infer intent:
|
|
39
|
-
- **Task automation** (user wants to perform an action on a website — post something, fill a form, click through a flow) → invoke `muggle:muggle-do-task` skill with the full prompt as arguments.
|
|
40
|
-
- **Feature development** (user wants to build, implement, fix, or refactor code) → treat as a new task description and start/resume a dev-cycle session.
|
|
41
|
-
|
|
42
|
-
When in doubt, ask one question: "Do you want me to run this as a browser automation task, or implement it as a code change?"
|
|
43
|
-
|
|
44
|
-
## The seven stages
|
|
19
|
+
## The pipeline
|
|
45
20
|
|
|
46
21
|
| # | Stage | File | User-facing? |
|
|
47
22
|
| :- | :---- | :--- | :----------- |
|
|
48
|
-
| 1 | Pre-flight | [../do/pre-flight.md](../do/pre-flight.md) | **Yes —
|
|
23
|
+
| 1 | Pre-flight | [../do/pre-flight.md](../do/pre-flight.md) | **Yes — one consolidated turn** |
|
|
49
24
|
| 2 | Requirements | [../do/requirements.md](../do/requirements.md) | No |
|
|
50
|
-
| 3 |
|
|
51
|
-
| 4 |
|
|
25
|
+
| 3 | Build | [../do/build.md](../do/build.md) | No |
|
|
26
|
+
| 4 | Impact analysis | [../do/impact-analysis.md](../do/impact-analysis.md) | No |
|
|
52
27
|
| 5 | Unit tests | [../do/unit-tests.md](../do/unit-tests.md) | No |
|
|
53
28
|
| 6 | E2E acceptance | [../do/e2e-acceptance.md](../do/e2e-acceptance.md) | No |
|
|
54
29
|
| 7 | Open PR | [../do/open-prs.md](../do/open-prs.md) | No |
|
|
30
|
+
| 8 | PR follow-up | [../muggle-pr-followup/SKILL.md](../muggle-pr-followup/SKILL.md) (generic) — invoked with muggle-do's cycle declaration | **Yes — only on ambiguous reviews** |
|
|
55
31
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
## Front-loading (stage 1 non-negotiable)
|
|
32
|
+
Stage 1 talks to the user once. Stages 2–7 run silently. Stage 7 dispatches **one Stage-8 follow-up loop per PR** it opens (not one per session); each loop polls its own PR independently for new submitted reviews. When a review lands, the loop cycles back through Stage 3 (Build) → 4 → 5 → 6 → fresh visual walkthrough → push to the existing branch, then resumes polling for the next round. Each loop may escalate once on an ambiguous review.
|
|
59
33
|
|
|
60
|
-
|
|
34
|
+
**Each stage's file is the single source of truth for that stage** — definition, contract, inputs/outputs, preference gates, output format. Read each stage file directly for its rules. This file is only the orchestration spine.
|
|
61
35
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
- Asking a clarifying question mid-cycle because "I didn't think of that at pre-flight."
|
|
65
|
-
- Starting a dev server mid-cycle and discovering the port is wrong.
|
|
66
|
-
- Reaching the E2E stage before knowing how the user wants it validated.
|
|
67
|
-
- Asking the user to "pick one" across multiple turns instead of one turn.
|
|
68
|
-
|
|
69
|
-
If any of these happen, the pre-flight was incomplete — treat it as a skill bug, not a user bug, and expand `pre-flight.md` to cover the missed case after the run.
|
|
70
|
-
|
|
71
|
-
## Session model
|
|
36
|
+
## Preferences
|
|
72
37
|
|
|
73
|
-
|
|
38
|
+
| Preference | Stage | Decision it gates |
|
|
39
|
+
|------------|-------|-------------------|
|
|
40
|
+
| `autoE2ETest` | 6 (E2E acceptance) | Run E2E every cycle (default `always`), or fold the question into pre-flight |
|
|
74
41
|
|
|
75
|
-
|
|
76
|
-
- `iterations/<NNN>.md` — append-only log of stage transitions for iteration NNN: what ran, what was decided, what artifacts were produced.
|
|
77
|
-
- `requirements.md` — frozen output of stage 2.
|
|
78
|
-
- `result.md` — final summary written by stage 7 (PR URLs, E2E outcome, open issues).
|
|
42
|
+
Other gates that fire during this cycle (`autoUseWorktree`, `autoRebase`, `autoCreatePR`, `autoCleanup`) are owned by the per-stage files; see each stage for its contract.
|
|
79
43
|
|
|
80
|
-
|
|
44
|
+
## Input routing
|
|
81
45
|
|
|
82
|
-
|
|
83
|
-
2. Rewrite `state.md` to reflect the new current stage and any relevant counters.
|
|
46
|
+
Treat `$ARGUMENTS` as the user command:
|
|
84
47
|
|
|
85
|
-
|
|
48
|
+
- Empty / `help` / `menu` / `?` → show menu and session selector.
|
|
49
|
+
- Anything else → infer intent:
|
|
50
|
+
- **Task automation** (perform an action on a website — post something, fill a form, click through a flow) → invoke `muggle:muggle-do-task` with the full prompt.
|
|
51
|
+
- **Feature development** (build / fix / refactor code) → start or resume a dev-cycle session.
|
|
86
52
|
|
|
87
|
-
|
|
53
|
+
When in doubt, ask one question: "Browser automation task, or code change?"
|
|
88
54
|
|
|
89
|
-
|
|
55
|
+
## Session model
|
|
90
56
|
|
|
91
|
-
|
|
92
|
-
**Stage N/7 — <stage name>** — <one-line intent>
|
|
93
|
-
```
|
|
57
|
+
Every run writes to `.muggle-do/sessions/<slug>/`. Stages own the files they produce:
|
|
94
58
|
|
|
95
|
-
|
|
59
|
+
| File | Owned by | Purpose |
|
|
60
|
+
| :--- | :------- | :------ |
|
|
61
|
+
| `state.md` | Stage 1 (rewritten by every transition) | Current stage, pre-flight answers, blockers |
|
|
62
|
+
| `iterations/<NNN>.md` | Every stage | Append-only stage transition log |
|
|
63
|
+
| `requirements.md` | Stage 2 | Frozen requirements |
|
|
64
|
+
| `prs.json`, `last_seen.json`, `followup.log` | Stage 8 | See [`pr-followup.md`](../do/pr-followup.md) |
|
|
65
|
+
| `result.md` | Stage 7 (seeded), Stage 8 (finalized) | Per-PR final state |
|
|
96
66
|
|
|
97
67
|
## Guardrails
|
|
98
68
|
|
|
99
|
-
- **
|
|
100
|
-
- **
|
|
101
|
-
- **
|
|
102
|
-
- **
|
|
103
|
-
- **If the same stage fails 3 times in a row, escalate with details.**
|
|
104
|
-
- **If total iterations reach 3 and E2E acceptance tests still fail**, continue to PR creation with `[E2E FAILING]` in the title; the visual walkthrough section makes the failures reviewable.
|
|
105
|
-
|
|
106
|
-
## Completion contract
|
|
107
|
-
|
|
108
|
-
When stage 7 finishes, the final message to the user contains at minimum:
|
|
109
|
-
|
|
110
|
-
- PR URL(s)
|
|
111
|
-
- E2E status (passing / `[E2E FAILING]`)
|
|
112
|
-
- Link to the run dashboard for each test case (via the walkthrough skill output)
|
|
113
|
-
- Path to `result.md` for full details
|
|
114
|
-
|
|
115
|
-
No other content. The user already read the walkthrough in the PR body — do not re-summarize it here.
|
|
69
|
+
- **Stage 1 is the only forward-pipeline user-facing stage.** Stages 2–7 don't ask questions mid-cycle. If a stage hits a blocker pre-flight didn't cover, treat as a pre-flight bug — escalate once and expand `pre-flight.md` after the run.
|
|
70
|
+
- **Stage 8 may escalate** once per ambiguous review comment, and may dispatch back to Stage 3 when needed — see [`pr-followup.md`](../do/pr-followup.md).
|
|
71
|
+
- **If the same stage fails 3 times in a row, escalate** with details.
|
|
72
|
+
- **If 3 cycle iterations reach E2E with failures**, ship with `[E2E FAILING]` per [`open-prs.md`](../do/open-prs.md). The walkthrough section keeps the failures reviewable.
|