@muggleai/works 4.9.2 → 4.10.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 (190) hide show
  1. package/README.md +3 -3
  2. package/dist/{chunk-6N7OIBAS.js → chunk-Q7WNEMN4.js} +109 -43
  3. package/dist/{chunk-4KQZLF56.js → chunk-ZKRHFTIC.js} +996 -91
  4. package/dist/cli.js +2 -2
  5. package/dist/index.js +2 -2
  6. package/dist/plugin/.claude-plugin/plugin.json +1 -1
  7. package/dist/plugin/.cursor-plugin/plugin.json +1 -1
  8. package/dist/plugin/README.md +4 -2
  9. package/dist/plugin/agents/acceptance-tester.md +24 -10
  10. package/dist/plugin/commands/m.md +7 -0
  11. package/dist/plugin/commands/mdo.md +7 -0
  12. package/dist/plugin/commands/mfeedback.md +7 -0
  13. package/dist/plugin/commands/mimport.md +7 -0
  14. package/dist/plugin/commands/mpr.md +7 -0
  15. package/dist/plugin/commands/mprefs.md +7 -0
  16. package/dist/plugin/commands/mregen.md +7 -0
  17. package/dist/plugin/commands/mrelease.md +7 -0
  18. package/dist/plugin/commands/mrepair.md +7 -0
  19. package/dist/plugin/commands/mstatus.md +7 -0
  20. package/dist/plugin/commands/mtest.md +7 -0
  21. package/dist/plugin/commands/mtestlocal.md +7 -0
  22. package/dist/plugin/commands/mtestprep.md +7 -0
  23. package/dist/plugin/commands/mupgrade.md +7 -0
  24. package/dist/plugin/scripts/ensure-electron-app.sh +56 -6
  25. package/dist/plugin/skills/_aliases.json +18 -0
  26. package/dist/plugin/skills/_shared/dev-server-readiness.md +231 -0
  27. package/dist/plugin/skills/_shared/failure-mode-handling.md +244 -0
  28. package/dist/plugin/skills/_shared/post-merge-cleanup.md +10 -0
  29. package/dist/plugin/skills/_shared/rebase-before-e2e.md +15 -0
  30. package/dist/plugin/skills/_shared/telemetry-emit.md +15 -0
  31. package/dist/plugin/skills/_shared/use-worktrees.md +53 -0
  32. package/dist/plugin/skills/do/e2e-acceptance.md +63 -18
  33. package/dist/plugin/skills/do/impact-analysis.md +45 -5
  34. package/dist/plugin/skills/do/open-prs.md +13 -4
  35. package/dist/plugin/skills/do/pr-followup.md +225 -0
  36. package/dist/plugin/skills/do/pre-flight.md +18 -11
  37. package/dist/plugin/skills/m/SKILL.md +8 -0
  38. package/dist/plugin/skills/mdo/SKILL.md +8 -0
  39. package/dist/plugin/skills/mfeedback/SKILL.md +8 -0
  40. package/dist/plugin/skills/mimport/SKILL.md +8 -0
  41. package/dist/plugin/skills/mpr/SKILL.md +8 -0
  42. package/dist/plugin/skills/mprefs/SKILL.md +8 -0
  43. package/dist/plugin/skills/mregen/SKILL.md +8 -0
  44. package/dist/plugin/skills/mrelease/SKILL.md +8 -0
  45. package/dist/plugin/skills/mrepair/SKILL.md +8 -0
  46. package/dist/plugin/skills/mstatus/SKILL.md +8 -0
  47. package/dist/plugin/skills/mtest/SKILL.md +8 -0
  48. package/dist/plugin/skills/mtestlocal/SKILL.md +8 -0
  49. package/dist/plugin/skills/mtestprep/SKILL.md +8 -0
  50. package/dist/plugin/skills/muggle/SKILL.md +11 -17
  51. package/dist/plugin/skills/muggle-do/SKILL.md +22 -4
  52. package/dist/plugin/skills/muggle-do-pr-followup/SKILL.md +37 -0
  53. package/dist/plugin/skills/muggle-do-task/SKILL.md +134 -0
  54. package/dist/plugin/skills/muggle-feedback/SKILL.md +38 -0
  55. package/dist/plugin/skills/muggle-feedback/ops/delete.md +49 -0
  56. package/dist/plugin/skills/muggle-feedback/ops/list.md +65 -0
  57. package/dist/plugin/skills/muggle-feedback/ops/submit.md +117 -0
  58. package/dist/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +73 -55
  59. package/dist/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
  60. package/dist/plugin/skills/muggle-preferences/SKILL.md +17 -68
  61. package/dist/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
  62. package/dist/plugin/skills/muggle-preferences/ops/configure.md +49 -0
  63. package/dist/plugin/skills/muggle-preferences/ops/list.md +9 -0
  64. package/dist/plugin/skills/muggle-preferences/ops/reset.md +6 -0
  65. package/dist/plugin/skills/muggle-preferences/ops/set.md +10 -0
  66. package/dist/plugin/skills/muggle-preferences/preference-gates/README.md +58 -0
  67. package/dist/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
  68. package/dist/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
  69. package/dist/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +11 -0
  70. package/dist/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
  71. package/dist/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +11 -0
  72. package/dist/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +11 -0
  73. package/dist/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
  74. package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
  75. package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +16 -0
  76. package/dist/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
  77. package/dist/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +11 -0
  78. package/dist/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +15 -0
  79. package/dist/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +11 -0
  80. package/dist/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +13 -0
  81. package/dist/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +11 -0
  82. package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +11 -0
  83. package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +11 -0
  84. package/dist/plugin/skills/muggle-preferences/preference-gates/verboseOutput.md +8 -0
  85. package/dist/plugin/skills/muggle-repair/SKILL.md +4 -2
  86. package/dist/plugin/skills/muggle-status/SKILL.md +14 -16
  87. package/dist/plugin/skills/muggle-test/SKILL.md +148 -123
  88. package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +92 -86
  89. package/dist/plugin/skills/muggle-test-import/SKILL.md +74 -35
  90. package/dist/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
  91. package/dist/plugin/skills/muggle-test-regenerate-missing/SKILL.md +49 -35
  92. package/dist/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
  93. package/dist/plugin/skills/muggle-upgrade/SKILL.md +4 -2
  94. package/dist/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
  95. package/dist/plugin/skills/mupgrade/SKILL.md +8 -0
  96. package/dist/release-manifest.json +4 -4
  97. package/dist/src-2G7ENRGI.js +1 -0
  98. package/package.json +10 -8
  99. package/plugin/.claude-plugin/plugin.json +1 -1
  100. package/plugin/.cursor-plugin/plugin.json +1 -1
  101. package/plugin/README.md +4 -2
  102. package/plugin/agents/acceptance-tester.md +24 -10
  103. package/plugin/commands/m.md +7 -0
  104. package/plugin/commands/mdo.md +7 -0
  105. package/plugin/commands/mfeedback.md +7 -0
  106. package/plugin/commands/mimport.md +7 -0
  107. package/plugin/commands/mpr.md +7 -0
  108. package/plugin/commands/mprefs.md +7 -0
  109. package/plugin/commands/mregen.md +7 -0
  110. package/plugin/commands/mrelease.md +7 -0
  111. package/plugin/commands/mrepair.md +7 -0
  112. package/plugin/commands/mstatus.md +7 -0
  113. package/plugin/commands/mtest.md +7 -0
  114. package/plugin/commands/mtestlocal.md +7 -0
  115. package/plugin/commands/mtestprep.md +7 -0
  116. package/plugin/commands/mupgrade.md +7 -0
  117. package/plugin/scripts/ensure-electron-app.sh +56 -6
  118. package/plugin/skills/_aliases.json +18 -0
  119. package/plugin/skills/_shared/dev-server-readiness.md +231 -0
  120. package/plugin/skills/_shared/failure-mode-handling.md +244 -0
  121. package/plugin/skills/_shared/post-merge-cleanup.md +10 -0
  122. package/plugin/skills/_shared/rebase-before-e2e.md +15 -0
  123. package/plugin/skills/_shared/telemetry-emit.md +15 -0
  124. package/plugin/skills/_shared/use-worktrees.md +53 -0
  125. package/plugin/skills/do/e2e-acceptance.md +63 -18
  126. package/plugin/skills/do/impact-analysis.md +45 -5
  127. package/plugin/skills/do/open-prs.md +13 -4
  128. package/plugin/skills/do/pr-followup.md +225 -0
  129. package/plugin/skills/do/pre-flight.md +18 -11
  130. package/plugin/skills/m/SKILL.md +8 -0
  131. package/plugin/skills/mdo/SKILL.md +8 -0
  132. package/plugin/skills/mfeedback/SKILL.md +8 -0
  133. package/plugin/skills/mimport/SKILL.md +8 -0
  134. package/plugin/skills/mpr/SKILL.md +8 -0
  135. package/plugin/skills/mprefs/SKILL.md +8 -0
  136. package/plugin/skills/mregen/SKILL.md +8 -0
  137. package/plugin/skills/mrelease/SKILL.md +8 -0
  138. package/plugin/skills/mrepair/SKILL.md +8 -0
  139. package/plugin/skills/mstatus/SKILL.md +8 -0
  140. package/plugin/skills/mtest/SKILL.md +8 -0
  141. package/plugin/skills/mtestlocal/SKILL.md +8 -0
  142. package/plugin/skills/mtestprep/SKILL.md +8 -0
  143. package/plugin/skills/muggle/SKILL.md +11 -17
  144. package/plugin/skills/muggle-do/SKILL.md +22 -4
  145. package/plugin/skills/muggle-do-pr-followup/SKILL.md +37 -0
  146. package/plugin/skills/muggle-do-task/SKILL.md +134 -0
  147. package/plugin/skills/muggle-feedback/SKILL.md +38 -0
  148. package/plugin/skills/muggle-feedback/ops/delete.md +49 -0
  149. package/plugin/skills/muggle-feedback/ops/list.md +65 -0
  150. package/plugin/skills/muggle-feedback/ops/submit.md +117 -0
  151. package/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +73 -55
  152. package/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
  153. package/plugin/skills/muggle-preferences/SKILL.md +17 -68
  154. package/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
  155. package/plugin/skills/muggle-preferences/ops/configure.md +49 -0
  156. package/plugin/skills/muggle-preferences/ops/list.md +9 -0
  157. package/plugin/skills/muggle-preferences/ops/reset.md +6 -0
  158. package/plugin/skills/muggle-preferences/ops/set.md +10 -0
  159. package/plugin/skills/muggle-preferences/preference-gates/README.md +58 -0
  160. package/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
  161. package/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
  162. package/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +11 -0
  163. package/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
  164. package/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +11 -0
  165. package/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +11 -0
  166. package/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
  167. package/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
  168. package/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +16 -0
  169. package/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
  170. package/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +11 -0
  171. package/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +15 -0
  172. package/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +11 -0
  173. package/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +13 -0
  174. package/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +11 -0
  175. package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +11 -0
  176. package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +11 -0
  177. package/plugin/skills/muggle-preferences/preference-gates/verboseOutput.md +8 -0
  178. package/plugin/skills/muggle-repair/SKILL.md +4 -2
  179. package/plugin/skills/muggle-status/SKILL.md +14 -16
  180. package/plugin/skills/muggle-test/SKILL.md +148 -123
  181. package/plugin/skills/muggle-test-feature-local/SKILL.md +92 -86
  182. package/plugin/skills/muggle-test-import/SKILL.md +74 -35
  183. package/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
  184. package/plugin/skills/muggle-test-regenerate-missing/SKILL.md +49 -35
  185. package/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
  186. package/plugin/skills/muggle-upgrade/SKILL.md +4 -2
  187. package/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
  188. package/plugin/skills/mupgrade/SKILL.md +8 -0
  189. package/scripts/postinstall.mjs +11 -1
  190. package/dist/src-7GB7WIFT.js +0 -1
@@ -0,0 +1,225 @@
1
+ # PR follow-up agent (Stage 8/8)
2
+
3
+ You are babysitting one or more open pull requests opened by stage 7. Each invocation of this stage is **one polling tick** dispatched by `/loop 5m /muggle:muggle-do-pr-followup <slug>`. The tick is short, idempotent, and addresses **at most one item per PR**.
4
+
5
+ The loop ends when every PR in the session is merged or closed.
6
+
7
+ ## Turn preamble
8
+
9
+ Start the turn with:
10
+
11
+ ```
12
+ **Stage 8/8 — PR follow-up** — polling <N> PR(s), tick #<K>.
13
+ ```
14
+
15
+ Resolve `<N>` from `prs.json` (non-terminal entries only) and `<K>` from the tick counter in `state.md`.
16
+
17
+ ## Stage-8 exception to the no-mid-cycle-questions rule
18
+
19
+ Stages 2–7 never ask the user mid-cycle. **Stage 8 may escalate** when a reviewer comment is ambiguous (see [Decision rule: classify](#decision-rule-classify) below). This is deliberate — the user has already walked away by the time stage 8 starts, and forcing a guess on an ambiguous design comment is worse than pausing.
20
+
21
+ Escalation is the **only** user-facing path in stage 8. Anything else — directives, questions, CI failures, retries — runs silently.
22
+
23
+ ## Inputs
24
+
25
+ Read these from `.muggle-do/sessions/<slug>/`:
26
+
27
+ - `state.md` — current tick counter, session metadata, the pre-flight answers (for context when classifying comments).
28
+ - `prs.json` — list of `{repo, number, url, head_sha, state}`. Entries with `state: "merged"` or `state: "closed"` are skipped.
29
+ - `last_seen.json` — per-PR cursor: `{commentId, reviewId, checkRunCompletedAt, last_pushed_sha, idle_tick_count, escalated_comment_ids[]}`.
30
+
31
+ If any of these don't exist, the tick is a no-op — log an error to `followup.log` and exit.
32
+
33
+ ## Per-tick contract
34
+
35
+ Do these steps in order. **Do not batch — at most one actionable item per PR.**
36
+
37
+ ### Step 1: Refresh PR states
38
+
39
+ For each PR in `prs.json` not already terminal:
40
+
41
+ ```bash
42
+ gh pr view <number> --repo <repo> --json state,mergedAt,closedAt,headRefOid
43
+ ```
44
+
45
+ If `state` is `MERGED` or `CLOSED`, mark the entry terminal in `prs.json`. Update `head_sha` if it changed.
46
+
47
+ ### Step 2: Termination check
48
+
49
+ If every entry in `prs.json` is now terminal:
50
+
51
+ 1. Write `result.md` with one section per PR (URL, final state, count of items addressed, count escalated, final commit SHA).
52
+ 2. **Do not schedule the next tick.** End the turn with no `ScheduleWakeup`-equivalent — `/loop` ends naturally.
53
+ 3. Emit the final tick-summary telemetry event (see [Telemetry](#telemetry)) with `prs_terminal == pr_count`.
54
+
55
+ ### Step 3: Resolve the reviewer allow-list (every tick)
56
+
57
+ For each non-terminal PR, compute the set of GitHub logins allowed to drive changes:
58
+
59
+ ```bash
60
+ gh pr view <number> --repo <repo> --json reviewRequests,author
61
+ ```
62
+
63
+ Add requested reviewers. Add CODEOWNERS by parsing `.github/CODEOWNERS` (or `CODEOWNERS` / `docs/CODEOWNERS`) from the PR's head branch. Remove the PR author and any bot accounts (logins ending in `[bot]`, plus the standard list: `dependabot`, `github-actions`, `renovate`).
64
+
65
+ This is per-tick by design (decision 9): reviewers added or removed after the PR opened take effect on the next poll.
66
+
67
+ ### Step 4: Pull new actionable items
68
+
69
+ For each non-terminal PR, fetch items newer than the cursor in `last_seen.json`:
70
+
71
+ - **Line-level review comments**:
72
+ ```bash
73
+ gh api repos/<owner>/<repo>/pulls/<number>/comments --paginate
74
+ ```
75
+ Filter to comments with `id > last_seen.commentId` AND `user.login` in the allow-list AND not already in `escalated_comment_ids` (avoid re-escalating).
76
+
77
+ - **CHANGES_REQUESTED review bodies** (only when the review has a non-empty body and no associated line comments):
78
+ ```bash
79
+ gh api repos/<owner>/<repo>/pulls/<number>/reviews --paginate
80
+ ```
81
+ Filter to reviews with `id > last_seen.reviewId` AND `state == "CHANGES_REQUESTED"` AND `user.login` in the allow-list AND `body` is non-empty.
82
+
83
+ - **Failing CI checks** (apply the `head_sha` guard, decision 11):
84
+ ```bash
85
+ gh pr checks <number> --repo <repo> --json name,state,completedAt,detailsUrl,workflow
86
+ ```
87
+ Filter to checks where `state == "FAILURE"` AND `completedAt > last_seen.checkRunCompletedAt`. **Skip any check whose target SHA equals `last_pushed_sha`** — CI is still digesting our last push, addressing it again would double-handle.
88
+
89
+ ### Step 5: Pick one item per PR
90
+
91
+ If a PR has zero actionable items, increment `idle_tick_count` for that PR. Otherwise sort the PR's items by timestamp ascending and take the **oldest one**. Reset `idle_tick_count` to 0 for that PR.
92
+
93
+ If every PR has zero actionable items this tick:
94
+ - Append a one-line heartbeat to `followup.log`: `<ts> tick #<K> idle (PRs: #A, #B, ...)`.
95
+ - If `idle_tick_count >= 12` for any PR, also rewrite `state.md` with `idle since <ts>, last poll <ts>` for that PR (decision 12).
96
+ - Emit tick-summary telemetry, exit the turn (next tick fires in 5 min via `/loop`).
97
+
98
+ ### Step 6: Classify and route
99
+
100
+ For each picked item, classify it:
101
+
102
+ #### Decision rule: classify
103
+
104
+ | Class | Signals | Action |
105
+ | :---- | :------ | :----- |
106
+ | **directive** | Imperative verb on a concrete target: "rename X to Y", "extract this", "add a null check", "remove this branch", "use `const` here", "this should be `async`", "delete this comment". Includes review-body summaries that read as a list of changes. | Fix → commit → push → reply `Done in <sha> — <one-line>`. |
107
+ | **question** | Ends with `?` and is not a rhetorical disguise. "Why this approach?", "Is this called from X?", "Does this need to handle Z?". | Reply inline with the answer. No code change. No push. |
108
+ | **CI failure** | Source is a failing check, not a comment. | Read the failing job log, fix, commit, push. No reply. |
109
+ | **ambiguous** (default) | Proposes an alternative without instructing ("I think we should use Z instead", "Have you considered Y?"), conflicts with a deliberate choice in the PR description or design doc, or is a multi-part comment mixing question and change request. | **Escalate.** See [Step 7: Escalate](#step-7-escalate). |
110
+
111
+ When the comment matches neither **directive** nor **question** cleanly, default to **ambiguous**. Do not guess. The cost of escalating a directive that could have been auto-handled is small; the cost of pushing a wrong change because we guessed is large.
112
+
113
+ #### Decision rule: reply text (adaptive, decision 6)
114
+
115
+ - **directive**: short, one-line. `Done in <sha> — renamed \`fooBar\` to \`foo_bar\` per request.` Use the [reply-routing helper](#reply-routing) to hit the correct endpoint.
116
+ - **question**: answer inline. Pull surrounding-code context if needed. Reply length matches the question's complexity — don't write three paragraphs to answer a yes/no.
117
+ - **CI failure**: no comment to reply to. The fix commit is the response. The commit message should reference the failing check by name (e.g. `fix(ci): typecheck — narrow type of foo`).
118
+ - **ambiguous**: no reply written by the bot. The escalation goes to the user, who replies to the comment themselves.
119
+
120
+ ### Step 7: Escalate
121
+
122
+ When the picked item is **ambiguous**:
123
+
124
+ 1. Add the comment id to `last_seen.escalated_comment_ids` so it isn't re-picked next tick.
125
+ 2. Append an entry to `followup.log` describing the comment and why it was classified ambiguous.
126
+ 3. Pause this PR's loop by writing `escalated: true` against the PR's entry in `prs.json`. Subsequent ticks skip this PR until the user clears the escalation.
127
+ 4. End the turn with a **single terminal message** to the user:
128
+
129
+ ```
130
+ **Stage 8 escalation — <repo>#<number>**
131
+
132
+ <reviewer-login> left an ambiguous comment on <file>:<line>:
133
+
134
+ > <quoted comment body>
135
+
136
+ Classifying it as a directive would mean: <one-line interpretation>
137
+ Classifying it as a question would mean: <one-line alternative>
138
+
139
+ Reply to that GitHub comment yourself, or tell me which way to go. I'll resume polling once the comment is either resolved or has a follow-up from you.
140
+ ```
141
+
142
+ The user clears the escalation by either resolving the GitHub thread (the next tick sees it resolved and removes it from `escalated_comment_ids`) or by replying in this terminal session with a directive that the next tick will pick up.
143
+
144
+ ### Step 8: Update cursors and push
145
+
146
+ After addressing a non-escalated item:
147
+
148
+ - Advance `last_seen.commentId` / `last_seen.reviewId` / `last_seen.checkRunCompletedAt` past the addressed item.
149
+ - If a push happened, set `last_seen.last_pushed_sha` to the new HEAD SHA. This arms the `head_sha` guard for the next tick (decision 11).
150
+ - Emit per-item telemetry (see [Telemetry](#telemetry)).
151
+
152
+ ### Step 9: Emit tick-summary telemetry and exit
153
+
154
+ Emit one `muggle-local-telemetry-skill-emit` event per tick (see [Telemetry](#telemetry)). Exit the turn. Next tick fires in 5 min via `/loop`.
155
+
156
+ ## Reply routing
157
+
158
+ GitHub's PR comment APIs are not uniform. Route by parent type:
159
+
160
+ - **Reply to a line-level review comment** (most common): `POST /repos/{owner}/{repo}/pulls/{n}/comments/{comment_id}/replies` with `{"body": "..."}`. The reply lands in the same review thread.
161
+ - **Reply to a CHANGES_REQUESTED review body** (no inline comment to reply to): post a fresh top-level PR comment via `gh pr comment <number> --body "..."` referencing the review. There is no "reply to review body" endpoint.
162
+ - **Failing CI**: no reply. The fix commit is the response.
163
+
164
+ Never post the same reply twice — the cursor in `last_seen.json` is the only re-entry guard.
165
+
166
+ ## Telemetry
167
+
168
+ Two telemetry shapes per tick (decision 14):
169
+
170
+ **Per-item** (one event per addressed/escalated item):
171
+
172
+ ```json
173
+ {
174
+ "skill": "muggle-do-pr-followup",
175
+ "event": "item",
176
+ "session_slug": "<slug>",
177
+ "repo": "<repo>",
178
+ "pr_number": <n>,
179
+ "item_type": "directive|question|ci_failure|ambiguous",
180
+ "outcome": "fixed_and_pushed|replied|escalated",
181
+ "comment_id": <id-or-null>,
182
+ "head_sha": "<sha-or-null>"
183
+ }
184
+ ```
185
+
186
+ **Per-tick summary** (always one, even on idle ticks):
187
+
188
+ ```json
189
+ {
190
+ "skill": "muggle-do-pr-followup",
191
+ "event": "tick",
192
+ "session_slug": "<slug>",
193
+ "tick": <K>,
194
+ "pr_count": <total>,
195
+ "prs_terminal": <count>,
196
+ "items_seen": <count>,
197
+ "items_addressed": <count>,
198
+ "items_escalated": <count>,
199
+ "pushed": true|false,
200
+ "tick_duration_ms": <ms>
201
+ }
202
+ ```
203
+
204
+ ## Output
205
+
206
+ This stage produces no console output beyond:
207
+ - The turn preamble (always).
208
+ - An escalation terminal message (only when an item is classified ambiguous).
209
+ - The final `result.md` summary (only on the terminating tick — written to disk, not printed).
210
+
211
+ Everything else lives in `followup.log` and `last_seen.json`.
212
+
213
+ ## Self-check before ending the turn
214
+
215
+ Before exiting, confirm:
216
+
217
+ - [ ] `last_seen.json` was advanced for every item handled.
218
+ - [ ] `prs.json` reflects current PR states (terminal entries marked).
219
+ - [ ] `followup.log` has at minimum a heartbeat or per-item line for this tick.
220
+ - [ ] Telemetry events were emitted (per-item + per-tick).
221
+ - [ ] If pushed, `last_pushed_sha` is set.
222
+ - [ ] If escalated, `escalated_comment_ids` contains the comment id.
223
+ - [ ] If terminal, the loop is NOT continued (do not schedule another tick).
224
+
225
+ If any are missing, fix before exit — a dropped cursor causes double-handling next tick.
@@ -17,7 +17,7 @@ Start the turn with:
17
17
  You receive:
18
18
 
19
19
  - The user's task description (from `$ARGUMENTS`).
20
- - The list of configured repos (names + paths) from the Muggle config.
20
+ - The list of configured repos (names + paths) from the Muggle Test config.
21
21
  - Any session directory that already exists (resumption case).
22
22
 
23
23
  ## Silent detection (do this first — no user prompts)
@@ -26,31 +26,38 @@ Before asking anything, gather every fact you can resolve without the user:
26
26
 
27
27
  1. **Candidate repo(s).** Match keywords in the task description against configured repo names. If one repo is an obvious match, propose it as the default; if two or three are plausible, list them.
28
28
  2. **Current branch and default branch** for each candidate repo. Run `git -C <repo> symbolic-ref refs/remotes/origin/HEAD --short` and `git -C <repo> branch --show-current`. If the current branch is the default, the pre-flight must collect a new branch name.
29
- 3. **Running dev server.** Scan common dev ports — `lsof -iTCP -sTCP:LISTEN -nP | grep -E ':(3000|3001|3999|4200|5173|8080)'` — and hit `/` with `curl -s -o /dev/null -w "%{http_code}"` to confirm 2xx.
30
- 4. **Running backend.** If the repo's `.env.local` (or equivalent) declares a backend URL (e.g. `REACT_APP_BACKEND_BASE_URL=http://localhost:5050`), probe the health endpoint; note up/down.
31
- 5. **Muggle MCP auth.** Call `muggle-remote-auth-status`. If expired, you will ask to re-auth in the questionnaire.
32
- 6. **Candidate Muggle projects.** Call `muggle-remote-project-list` and rank by semantic match against the task description and the repo's dev URL.
33
- 7. **Existing test-user secrets.** For each candidate Muggle project, call `muggle-remote-secret-list` and note whether `managed_profile_email` / `managed_profile_password` exist.
29
+ 3. **Running dev server.** Detect listening ports and reconcile env-file URL/port using [`../_shared/dev-server-readiness.md`](../_shared/dev-server-readiness.md).
30
+ 4. **Running backend.** Probe backend health per [`../_shared/dev-server-readiness.md`](../_shared/dev-server-readiness.md) ("Backend health"). Note up/down.
31
+ 5. **Muggle Test MCP auth.** Call `muggle-remote-auth-status`. If expired, you will ask to re-auth in the questionnaire.
32
+ 6. **Candidate Muggle Test projects.** Call `muggle-remote-project-list` and rank by semantic match against the task description and the repo's dev URL.
33
+ 7. **Existing test-user secrets.** For each candidate Muggle Test project, call `muggle-remote-secret-list` and note whether `managed_profile_email` / `managed_profile_password` exist.
34
34
  8. **Auth0 tenant in use for local dev.** Grep the repo's env file for `*AUTH0_DOMAIN*`; record the tenant. This tells the user whether the staging-tenant test user will work or not.
35
+ 9. **Branch hygiene signals** for the `autoUseWorktree` and `autoRebase` gates (see [`../_shared/use-worktrees.md`](../_shared/use-worktrees.md), [`../_shared/rebase-before-e2e.md`](../_shared/rebase-before-e2e.md)):
36
+ - Is the current checkout already a worktree? `git -C <repo> rev-parse --is-inside-work-tree` plus `git -C <repo> worktree list`.
37
+ - How many commits behind `origin/<default>`? `git -C <repo> fetch origin && git -C <repo> rev-list --count "HEAD..origin/$(git -C <repo> symbolic-ref refs/remotes/origin/HEAD --short | sed 's|origin/||')"`.
38
+ 10. **`autoE2ETest` preference.** Read the session-context preferences line. Unset → treat as `always` (this gate's default — opposite of the system-wide `ask` default). `ask` → surface in Q13. `always` → no question; stage 6 runs.
35
39
 
36
40
  ## The consolidated questionnaire
37
41
 
38
- Present **one `AskQuestion`** (or the platform's structured-selection equivalent) that collects every remaining decision. Use detected values as defaults whenever possible. Questions to include, in this order:
42
+ Present **one `AskUserQuestion`** (or the platform's structured-selection equivalent) that collects every remaining decision. Use detected values as defaults whenever possible. Questions to include, in this order:
39
43
 
40
44
  1. **Task scope clarification** — only if the task description is genuinely ambiguous. Offer 2–3 interpretations as options plus "Other — type a clarification." If the task is unambiguous, omit.
41
45
  2. **Repo(s) to modify** — pre-selected with the best silent match. "Confirm <repo>" / "Change repo" / "Multi-repo (list them)".
42
46
  3. **Branch name** — default: `users/<user>/<slug>` derived from the task. "Use default" / "Use different name (type)".
43
47
  4. **Validation strategy** — the single most important question. Options:
44
- - **Local E2E** (Muggle Electron against a running localhost) — default if a dev server was detected.
48
+ - **Local E2E** (Muggle Test Electron against a running localhost) — default if a dev server was detected.
45
49
  - **Staging replay** — for changes already deployed to a preview URL.
46
50
  - **Unit tests only** — skip E2E, acceptable for pure refactors or backend-only changes.
47
51
  - **Skip validation** — explicit opt-out; the PR title gets `[UNVERIFIED]`.
48
52
  5. **Local URL** — only if validation is Local E2E. Default: the detected port. "Confirm `<detected>`" / "Type a different URL".
49
53
  6. **Backend reachable?** — only if validation is Local E2E and a backend URL is declared. If the health probe failed, ask "Start the backend now and I'll re-probe" / "Proceed anyway" / "Skip to unit tests only".
50
- 7. **Muggle project** — pre-selected with the best silent match. "Use <top match>" / "Use a different existing project (list)" / "Create new".
54
+ 7. **Muggle Test project** — pre-selected with the best silent match. "Use <top match>" / "Use a different existing project (list)" / "Create new".
51
55
  8. **Test-user credentials** — only if validation is Local E2E AND the Auth0 tenant in the repo differs from the tenant the managed secrets were created under. Options: "Reuse existing secrets (may fail if tenant mismatch — will surface failure)" / "Create new secrets for this tenant (provide email + password)" / "Switch to staging replay".
52
56
  9. **PR target branch** — default: the repo's default branch. "Use default" / "Target a different branch".
53
- 10. **Re-auth Muggle MCP?** — only if auth was missing/expired. "Log in now" / "Abort".
57
+ 10. **Re-auth Muggle Test MCP?** — only if auth was missing/expired. "Log in now" / "Abort".
58
+ 11. **Worktree for this change?** — gate: [`autoUseWorktree`](../muggle-preferences/preference-gates/autoUseWorktree.md). Options: create a sibling worktree, or work in the current checkout.
59
+ 12. **Rebase onto `origin/<default>` first?** — gate: [`autoRebase`](../muggle-preferences/preference-gates/autoRebase.md), only if `behind > 0`. Options: rebase before stage 6, or run as-is.
60
+ 13. **Run E2E at the end of every cycle?** — gate: [`autoE2ETest`](../muggle-preferences/preference-gates/autoE2ETest.md), only if step 10's silent detection resolved to `ask`. Options: always run stage 6, or ask each cycle.
54
61
 
55
62
  If fewer than two of the above need the user, still gather them in a single turn — never open a second round.
56
63
 
@@ -73,7 +80,7 @@ After the user answers, write **`state.md`** with every resolved value, verbatim
73
80
  - Validation: <strategy>
74
81
  - Local URL: <url or N/A>
75
82
  - Backend status: <up | down | N/A>
76
- - Muggle project: <name> (<uuid>)
83
+ - Muggle Test project: <name> (<uuid>)
77
84
  - Test credentials: <existing | new | skip>
78
85
  - PR target: <branch>
79
86
  - Auth status: <ok | re-authed | N/A>
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: m
3
+ description: Explicit short alias for the `muggle` skill (router/menu). ONLY invoke when the user explicitly types `m` or `/m` — never auto-trigger from any other phrasing.
4
+ ---
5
+
6
+ # m — alias for muggle
7
+
8
+ Invoke the `muggle` skill via the Skill tool. Forward any user-provided arguments unchanged.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: mdo
3
+ description: Explicit short alias for the `muggle-do-task` skill. ONLY invoke when the user explicitly types `mdo` or `/mdo` — never auto-trigger from any other phrasing.
4
+ ---
5
+
6
+ # mdo — alias for muggle-do-task
7
+
8
+ Invoke the `muggle-do-task` skill via the Skill tool. Forward any user-provided arguments unchanged.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: mfeedback
3
+ description: Explicit short alias for the `muggle-feedback` skill. ONLY invoke when the user explicitly types `mfeedback` or `/mfeedback` — never auto-trigger from any other phrasing.
4
+ ---
5
+
6
+ # mfeedback — alias for muggle-feedback
7
+
8
+ Invoke the `muggle-feedback` skill via the Skill tool. Forward any user-provided arguments unchanged.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: mimport
3
+ description: Explicit short alias for the `muggle-test-import` skill. ONLY invoke when the user explicitly types `mimport` or `/mimport` — never auto-trigger from any other phrasing.
4
+ ---
5
+
6
+ # mimport — alias for muggle-test-import
7
+
8
+ Invoke the `muggle-test-import` skill via the Skill tool. Forward any user-provided arguments unchanged.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: mpr
3
+ description: Explicit short alias for the `muggle-pr-visual-walkthrough` skill. ONLY invoke when the user explicitly types `mpr` or `/mpr` — never auto-trigger from any other phrasing.
4
+ ---
5
+
6
+ # mpr — alias for muggle-pr-visual-walkthrough
7
+
8
+ Invoke the `muggle-pr-visual-walkthrough` skill via the Skill tool. Forward any user-provided arguments unchanged.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: mprefs
3
+ description: Explicit short alias for the `muggle-preferences` skill. ONLY invoke when the user explicitly types `mprefs` or `/mprefs` — never auto-trigger from any other phrasing.
4
+ ---
5
+
6
+ # mprefs — alias for muggle-preferences
7
+
8
+ Invoke the `muggle-preferences` skill via the Skill tool. Forward any user-provided arguments unchanged.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: mregen
3
+ description: Explicit short alias for the `muggle-test-regenerate-missing` skill. ONLY invoke when the user explicitly types `mregen` or `/mregen` — never auto-trigger from any other phrasing.
4
+ ---
5
+
6
+ # mregen — alias for muggle-test-regenerate-missing
7
+
8
+ Invoke the `muggle-test-regenerate-missing` skill via the Skill tool. Forward any user-provided arguments unchanged.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: mrelease
3
+ description: Explicit short alias for the `muggle-works-npm-release` skill. ONLY invoke when the user explicitly types `mrelease` or `/mrelease` — never auto-trigger from any other phrasing.
4
+ ---
5
+
6
+ # mrelease — alias for muggle-works-npm-release
7
+
8
+ Invoke the `muggle-works-npm-release` skill via the Skill tool. Forward any user-provided arguments unchanged.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: mrepair
3
+ description: Explicit short alias for the `muggle-repair` skill. ONLY invoke when the user explicitly types `mrepair` or `/mrepair` — never auto-trigger from any other phrasing.
4
+ ---
5
+
6
+ # mrepair — alias for muggle-repair
7
+
8
+ Invoke the `muggle-repair` skill via the Skill tool. Forward any user-provided arguments unchanged.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: mstatus
3
+ description: Explicit short alias for the `muggle-status` skill. ONLY invoke when the user explicitly types `mstatus` or `/mstatus` — never auto-trigger from any other phrasing.
4
+ ---
5
+
6
+ # mstatus — alias for muggle-status
7
+
8
+ Invoke the `muggle-status` skill via the Skill tool. Forward any user-provided arguments unchanged.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: mtest
3
+ description: Explicit short alias for the `muggle-test` skill. ONLY invoke when the user explicitly types `mtest` or `/mtest` — never auto-trigger from any other phrasing.
4
+ ---
5
+
6
+ # mtest — alias for muggle-test
7
+
8
+ Invoke the `muggle-test` skill via the Skill tool. Forward any user-provided arguments unchanged.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: mtestlocal
3
+ description: Explicit short alias for the `muggle-test-feature-local` skill. ONLY invoke when the user explicitly types `mtestlocal` or `/mtestlocal` — never auto-trigger from any other phrasing.
4
+ ---
5
+
6
+ # mtestlocal — alias for muggle-test-feature-local
7
+
8
+ Invoke the `muggle-test-feature-local` skill via the Skill tool. Forward any user-provided arguments unchanged.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: mtestprep
3
+ description: Explicit short alias for the `muggle-test-prepare` skill. ONLY invoke when the user explicitly types `mtestprep` or `/mtestprep` — never auto-trigger from any other phrasing.
4
+ ---
5
+
6
+ # mtestprep — alias for muggle-test-prepare
7
+
8
+ Invoke the `muggle-test-prepare` skill via the Skill tool. Forward any user-provided arguments unchanged.
@@ -1,32 +1,25 @@
1
1
  ---
2
2
  name: muggle
3
- description: Muggle AI command router and menu. Use when user types "muggle" or asks for available Muggle commands.
3
+ description: Muggle AI command router and menu. Use when user types "muggle" or asks for available Muggle Test commands.
4
4
  ---
5
5
 
6
- # Muggle
6
+ # Muggle Test
7
7
 
8
- Use this as the top-level Muggle command router.
8
+ > Telemetry first step: see [`_shared/telemetry-emit.md`](../_shared/telemetry-emit.md). Use `skillName: "muggle"`.
9
9
 
10
- ## Preferences
11
-
12
- User preferences are available in the session context (injected at session start). Look for the line starting with `Muggle Preferences` — it contains key=value pairs like `autoLogin=ask showElectronBrowser=always ...`.
10
+ Use this as the top-level Muggle Test command router.
13
11
 
14
- If no preferences line is present, treat all preferences as `"ask"`.
12
+ ## Preferences
15
13
 
16
- When you reach a decision gated by a preference:
17
- - **`always`** → proceed without asking the user
18
- - **`never`** → skip without asking the user
19
- - **`ask`** → ask the user, then offer: "Want me to remember this choice for future sessions?" If yes, call `muggle-local-preferences-set` with the key, their chosen value, and scope `global`.
14
+ User preferences are injected by the SessionStart hook into a `Muggle Test Preferences` line in session context (key=value pairs). Resolution: defaults → `~/.muggle-ai/preferences.json` (global) → `<repo>/.muggle-ai/preferences.json` (project). Treat absent prefs as `ask`.
20
15
 
21
- This skill uses these preferences:
16
+ This router skill itself does not gate any decision on a preference — it just routes user intent to a downstream skill. Each downstream skill consults its own preferences. For example, `checkForUpdates` is consulted by `muggle-status` (Check 4), not here.
22
17
 
23
- | Preference | Decision it gates |
24
- |------------|------------------|
25
- | `checkForUpdates` | Check for newer Muggle version |
18
+ If the user types "muggle" with no subcommand and you want to surface a contextual hint about the update-check pref, defer to `muggle-status` rather than reimplementing the gate in this router.
26
19
 
27
20
  ## Menu
28
21
 
29
- When user asks for "muggle" with no specific subcommand, use `AskQuestion` to present these four options:
22
+ When user asks for "muggle" with no specific subcommand, use `AskUserQuestion` to present these four options:
30
23
 
31
24
  - "Test a feature — run E2E acceptance tests locally or remotely" → `muggle-test-feature-local` (local) or `muggle-test` (remote/change-driven)
32
25
  - "Build something — implement a feature with E2E acceptance tests and a visual PR" → `muggle-do`
@@ -44,5 +37,6 @@ If the user intent clearly matches one command, route directly — no menu neede
44
37
  - test localhost/validate single feature/test a feature → `muggle-test-feature-local`
45
38
  - build/implement from request/end-to-end → `muggle-do`
46
39
  - post results to PR/attach walkthrough/visual evidence on PR → `muggle-pr-visual-walkthrough`
40
+ - give feedback on a run/the test was wrong/step N didn't work/show my feedback/delete feedback → `muggle-feedback`
47
41
 
48
- If intent is ambiguous, use `AskQuestion` with the most likely options rather than asking the user to type a clarification.
42
+ If intent is ambiguous, use `AskUserQuestion` with the most likely options rather than asking the user to type a clarification.
@@ -4,9 +4,11 @@ description: Unified Muggle AI workflow entry point. Use when user types muggle
4
4
  disable-model-invocation: true
5
5
  ---
6
6
 
7
- # Muggle Do
7
+ # Muggle Test Do
8
8
 
9
- Muggle Do runs a battle-tested autonomous dev cycle: **pre-flight → requirements → impact analysis → validate code → unit tests → E2E acceptance → open PR**.
9
+ > Telemetry first step: see [`_shared/telemetry-emit.md`](../_shared/telemetry-emit.md). Use `skillName: "muggle-do"`.
10
+
11
+ Muggle Test Do runs a battle-tested autonomous dev cycle: **pre-flight → requirements → impact analysis → validate code → unit tests → E2E acceptance → open PR**.
10
12
 
11
13
  The design goal is **fire and review**: the user answers one consolidated pre-flight questionnaire, then walks away. Every subsequent stage runs unattended until completion or a genuine blocker.
12
14
 
@@ -16,12 +18,28 @@ For maintenance tasks, use the dedicated skills:
16
18
  - `/muggle:muggle-repair`
17
19
  - `/muggle:muggle-upgrade`
18
20
 
21
+ ## Preferences
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
+
19
33
  ## Input routing
20
34
 
21
35
  Treat `$ARGUMENTS` as the user command:
22
36
 
23
37
  - Empty / `help` / `menu` / `?` → show menu and session selector.
24
- - Anything else → treat as a new task description and start/resume a dev-cycle session.
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?"
25
43
 
26
44
  ## The seven stages
27
45
 
@@ -39,7 +57,7 @@ Treat `$ARGUMENTS` as the user command:
39
57
 
40
58
  ## Front-loading (stage 1 non-negotiable)
41
59
 
42
- All ambiguity — task scope, repo selection, validation strategy, localhost URL, backend health, Muggle project, test-user credentials, branch name, PR target — is resolved in a **single** pre-flight turn. See `pre-flight.md` for the exact questionnaire.
60
+ All ambiguity — task scope, repo selection, validation strategy, localhost URL, backend health, Muggle Test project, test-user credentials, branch name, PR target — is resolved in a **single** pre-flight turn. See `pre-flight.md` for the exact questionnaire.
43
61
 
44
62
  **Red-flag behaviors (do not do):**
45
63
 
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: muggle-do-pr-followup
3
+ description: One polling tick of /muggle-do stage 8 — addresses reviewer comments and CI failures on PRs opened by an earlier /muggle-do session. Dispatched by `/loop 5m /muggle:muggle-do-pr-followup <slug>` after stage 7; also re-runnable by hand on any session slug.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # Muggle Test Do — PR follow-up
8
+
9
+ > Telemetry first step: see [`_shared/telemetry-emit.md`](../_shared/telemetry-emit.md). Use `skillName: "muggle-do-pr-followup"`.
10
+
11
+ This skill is the **dispatch entry** for stage 8 of /muggle-do. It is intentionally thin — the actual per-tick logic lives in [`../do/pr-followup.md`](../do/pr-followup.md), the single source of truth.
12
+
13
+ ## Input routing
14
+
15
+ `$ARGUMENTS` is the **session slug** (the directory name under `.muggle-do/sessions/`).
16
+
17
+ - Empty / `help` / `?` → list available session slugs from `.muggle-do/sessions/` that have a non-empty `prs.json` with at least one non-terminal entry, then exit. Do not start a poll.
18
+ - Otherwise → resolve `.muggle-do/sessions/<slug>/`. If the directory or its `prs.json` is missing, log the error to `followup.log` (creating it if needed) and exit. Do **not** ask the user.
19
+
20
+ ## Run one tick
21
+
22
+ With a valid session slug, follow [`../do/pr-followup.md`](../do/pr-followup.md) exactly. That file owns:
23
+
24
+ - The turn preamble.
25
+ - The 9-step per-tick contract.
26
+ - The classify rule (directive / question / CI failure / ambiguous → escalate).
27
+ - Reply routing.
28
+ - Telemetry shape.
29
+ - The self-check before exit.
30
+
31
+ This skill file adds nothing beyond the slug resolution above.
32
+
33
+ ## Why a separate entry exists
34
+
35
+ - `/loop 5m /muggle:muggle-do-pr-followup <slug>` (dispatched by stage 7 of /muggle-do) needs a slash-addressable target.
36
+ - Manual re-attach: if `/loop` was killed and the user wants to resume, they can run `/muggle:muggle-do-pr-followup <slug>` once to drive a single tick, or re-dispatch the `/loop` themselves.
37
+ - Isolated debugging: a single tick is reproducible against a real session dir.