@muggleai/works 4.10.1 → 4.11.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.
Files changed (40) hide show
  1. package/dist/plugin/.claude-plugin/plugin.json +1 -1
  2. package/dist/plugin/.cursor-plugin/plugin.json +1 -1
  3. package/dist/plugin/skills/_shared/pr-followup-helpers.md +151 -0
  4. package/dist/plugin/skills/do/build.md +51 -0
  5. package/dist/plugin/skills/do/e2e-acceptance.md +2 -2
  6. package/dist/plugin/skills/do/impact-analysis.md +2 -2
  7. package/dist/plugin/skills/do/open-prs.md +67 -78
  8. package/dist/plugin/skills/do/pre-flight.md +3 -3
  9. package/dist/plugin/skills/do/requirements.md +2 -2
  10. package/dist/plugin/skills/do/unit-tests.md +2 -2
  11. package/dist/plugin/skills/muggle-do/SKILL.md +34 -77
  12. package/dist/plugin/skills/muggle-feedback/SKILL.md +2 -1
  13. package/dist/plugin/skills/muggle-feedback/ops/submit.md +16 -3
  14. package/dist/plugin/skills/muggle-pr-followup/SKILL.md +59 -0
  15. package/dist/plugin/skills/muggle-pr-followup/contract.md +190 -0
  16. package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +14 -0
  17. package/dist/release-manifest.json +4 -4
  18. package/package.json +6 -6
  19. package/plugin/.claude-plugin/plugin.json +1 -1
  20. package/plugin/.cursor-plugin/plugin.json +1 -1
  21. package/plugin/skills/_shared/pr-followup-helpers.md +151 -0
  22. package/plugin/skills/do/build.md +51 -0
  23. package/plugin/skills/do/e2e-acceptance.md +2 -2
  24. package/plugin/skills/do/impact-analysis.md +2 -2
  25. package/plugin/skills/do/open-prs.md +67 -78
  26. package/plugin/skills/do/pre-flight.md +3 -3
  27. package/plugin/skills/do/requirements.md +2 -2
  28. package/plugin/skills/do/unit-tests.md +2 -2
  29. package/plugin/skills/muggle-do/SKILL.md +34 -77
  30. package/plugin/skills/muggle-feedback/SKILL.md +2 -1
  31. package/plugin/skills/muggle-feedback/ops/submit.md +16 -3
  32. package/plugin/skills/muggle-pr-followup/SKILL.md +59 -0
  33. package/plugin/skills/muggle-pr-followup/contract.md +190 -0
  34. package/plugin/skills/muggle-test-feature-local/SKILL.md +14 -0
  35. package/dist/plugin/skills/do/pr-followup.md +0 -225
  36. package/dist/plugin/skills/do/validate-code.md +0 -38
  37. package/dist/plugin/skills/muggle-do-pr-followup/SKILL.md +0 -37
  38. package/plugin/skills/do/pr-followup.md +0 -225
  39. package/plugin/skills/do/validate-code.md +0 -38
  40. package/plugin/skills/muggle-do-pr-followup/SKILL.md +0 -37
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "muggle",
3
3
  "description": "Run real-browser end-to-end (E2E) acceptance tests on your web app from any AI coding agent. Generate test scripts from plain English, replay them on localhost, capture screenshots, and validate user flows like signup, checkout, and dashboards. Works across Claude Code, Cursor, Codex, and Windsurf.",
4
- "version": "4.10.1",
4
+ "version": "4.11.1",
5
5
  "author": {
6
6
  "name": "Muggle AI",
7
7
  "email": "support@muggle-ai.com"
@@ -2,7 +2,7 @@
2
2
  "name": "muggle",
3
3
  "displayName": "Muggle AI",
4
4
  "description": "Ship quality products with AI-powered end-to-end (E2E) acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
5
- "version": "4.10.1",
5
+ "version": "4.11.1",
6
6
  "author": {
7
7
  "name": "Muggle AI",
8
8
  "email": "support@muggle-ai.com"
@@ -0,0 +1,151 @@
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** — but reply per line comment (threaded), not per review.
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 **one** implementation cycle for the whole review; reply **threaded per line comment** referencing the new SHA (top-level only when the review is body-only). |
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 shape (all replies for one review reference the same SHA):
114
+
115
+ - **threaded** (default): `Done in <sha> — <attribution>. (Review #<review_id>, cycle <status>.)`
116
+ - **top-level** (fallback, body-only reviews): `Re: review #<review_id> — addressed in <sha>, cycle <status>.`
117
+ - **ambiguous**: no bot reply.
118
+
119
+ ### Worked examples — Actionable reviews
120
+
121
+ | Review (summarized) | Why actionable |
122
+ | :------------------ | :------------- |
123
+ | 3 comments: "rename `fooBar` to `foo_bar`", "use `const` here", "fix this typo" | Three concrete edits |
124
+ | 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 |
125
+ | 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 |
126
+ | 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 |
127
+ | 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 |
128
+ | 1 comment: "I'd lean toward the bar.ts pattern" | Concrete referent (bar.ts) — apply that pattern |
129
+
130
+ The single review goes through one full cycle regardless of comment count.
131
+
132
+ ### Worked examples — Ambiguous reviews
133
+
134
+ | Review (summarized) | Why ambiguous |
135
+ | :------------------ | :------------ |
136
+ | 1 comment: "👀" / "hmm" / ":thinking:" | No signal at all |
137
+ | 1 comment: "this is wrong" with no target or direction | Asserts a problem but doesn't propose a fix |
138
+ | 2 comments: "use X" + "but actually don't use X" | Self-contradicting — can't reconcile without the reviewer |
139
+ | 1 comment: "we discussed this offline — please address" | References context the loop doesn't have |
140
+ | 1 comment: "won't this break the prod migration we did last week?" | Implicit change request gated on knowledge the loop can't access |
141
+ | 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 |
142
+
143
+ 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).
144
+
145
+ ### Borderline rule
146
+
147
+ 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.
148
+
149
+ If you can paraphrase it only as **"the reviewer is dissatisfied but I can't tell with what"** — it's ambiguous.
150
+
151
+ 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/7)
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/7 — E2E acceptance** — running browser tests against the validation target from pre-flight.
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 3/7)
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 3/7 — Impact analysis** — diffing each affected repo against its default branch.
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/7)
1
+ # PR Creation Agent (Stage 7 — Open PR)
2
2
 
3
- You are creating pull requests for each repository that has changes after a successful dev cycle run.
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/7 — Open PR** — rendering the visual walkthrough and pushing the PR.
8
+ **Stage 7 — Open PR** — pushing the branch and opening the PR.
11
9
  ```
12
10
 
13
- ## Non-negotiable: visual walkthrough is required
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
- - [ ] `muggle-pr-visual-walkthrough` was invoked (or the skip reason is recorded).
22
- - [ ] The `body` returned by the skill is embedded verbatim in the PR body.
23
- - [ ] If `comment` is non-null, it will be posted as a follow-up after the PR is created.
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
- If you cannot check all three, **halt** — do not create the PR. Fix the upstream stage first.
17
+ ## Per repo
26
18
 
27
- ## Input
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
- You receive:
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
- ## Your Job
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
- For each repo with changes:
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
- 0. **Apply the `autoCreatePR` gate** per [`../muggle-preferences/preference-gates/README.md`](../muggle-preferences/preference-gates/README.md) + [`autoCreatePR.md`](../muggle-preferences/preference-gates/autoCreatePR.md). On the skip path, record the reason in `result.md` and move to the next repo.
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
- ## Rendering the E2E acceptance block via the shared skill
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
- ### Invocation — Mode B (render-only)
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
- Invoke `muggle-pr-visual-walkthrough` via the `Skill` tool with the `E2eReport` already in context. The skill will:
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
- 1. Validate the `E2eReport` and call `muggle build-pr-section` (piping the JSON to stdin).
78
- 2. Parse the CLI's `{body, comment}` stdout.
79
- 3. **Return `{body, comment}` to this stage's conversation** without posting anything — because Mode B is render-only. `body` is the E2E markdown block; `comment` is a non-null overflow follow-up comment only when content exceeds the byte budget, otherwise `null`.
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
- ### After rendering
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
- Back in this stage:
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
- - Embed `body` in the `gh pr create --body` body (see step 4 above).
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
- ### Notes on fit vs. overflow
80
+ ## Self-check before exit
92
81
 
93
- - **Common case (fit):** the full evidence (summary, per-test rows, collapsible failure details) lives in the PR description, `comment` is `null`, no follow-up comment is posted.
94
- - **Overflow case:** the CLI detects the full body would exceed its byte budget; `body` contains the summary, per-test rows, and a pointer line; `comment` contains the overflow details. Post both.
95
- - You do not make the fit-vs-overflow decision — the CLI does. Never post the comment when it is `null`.
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
- - (repo name): (PR URL)
101
-
102
- **E2E acceptance overflow comments posted:** (only include repos where an overflow comment was actually posted)
103
- - (repo name): comment posted to PR #(number)
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 (gated by `autoCleanup`)
96
+ ## Post-merge cleanup
108
97
 
109
- Cleanup fires in a follow-up turn after merge — never from this stage. See [`../_shared/post-merge-cleanup.md`](../_shared/post-merge-cleanup.md).
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
- After printing PR URLs, append one short reminder tied to the gate's current value:
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/7)
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/7 — Pre-flight** — consolidating everything the cycle needs before going silent.
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/7 — Pre-flight (<timestamp>)
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/7)
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/7 — Requirements** — extracting structured goals from the pre-flight-clarified task.
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/7)
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/7 — Unit tests** — running each repo's test suite.
10
+ **Stage 5 — Unit tests** — running each repo's test suite.
11
11
  ```
12
12
 
13
13
  ## Input