@muggleai/works 4.13.1 → 4.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/.cursor-plugin/plugin.json +1 -1
- package/dist/plugin/README.md +1 -1
- package/dist/plugin/agents/acceptance-tester.md +2 -0
- package/dist/plugin/commands/mbt.md +7 -0
- package/dist/plugin/commands/mdo.md +3 -3
- package/dist/plugin/commands/mprfollowup.md +7 -0
- package/dist/plugin/skills/CLAUDE.md +15 -0
- package/dist/plugin/skills/_aliases.json +2 -1
- package/dist/plugin/skills/_shared/ci-check-to-command.md +10 -0
- package/dist/plugin/skills/_shared/dev-loop/action-script.md +3 -0
- package/dist/plugin/skills/_shared/dev-loop/failures.md +14 -0
- package/dist/plugin/skills/_shared/dev-loop/fresh-session.md +10 -0
- package/dist/plugin/skills/_shared/dev-loop/publish.md +13 -0
- package/dist/plugin/skills/_shared/dev-loop/run.md +34 -0
- package/dist/plugin/skills/_shared/dev-loop/timeouts.md +6 -0
- package/dist/plugin/skills/_shared/failure-mode-handling.md +2 -2
- package/dist/plugin/skills/_shared/github-cli-recipes/pr-checks.md +22 -0
- package/dist/plugin/skills/_shared/github-cli-recipes.md +1 -0
- package/dist/plugin/skills/_shared/post-merge-cleanup.md +1 -1
- package/dist/plugin/skills/_shared/pr-branch-worktree.md +1 -1
- package/dist/plugin/skills/_shared/rebase-before-e2e.md +7 -1
- package/dist/plugin/skills/_shared/resolve-e2e-validation-context.md +1 -1
- package/dist/plugin/skills/_shared/resolve-rebase-conflicts.md +60 -0
- package/dist/plugin/skills/_shared/telemetry-events/muggle-do-cycle.md +8 -1
- package/dist/plugin/skills/_shared/telemetry-events/muggle-do-escalation.md +2 -1
- package/dist/plugin/skills/_shared/telemetry-events/pr-followup-tick.md +4 -0
- package/dist/plugin/skills/_shared/use-worktrees.md +2 -1
- package/dist/plugin/skills/do/address-reviews.md +7 -1
- package/dist/plugin/skills/do/build.md +2 -1
- package/dist/plugin/skills/do/cleanup.md +14 -0
- package/dist/plugin/skills/do/e2e-acceptance.md +5 -66
- package/dist/plugin/skills/do/fix-ci.md +60 -0
- package/dist/plugin/skills/do/input-routing.md +12 -0
- package/dist/plugin/skills/do/open-prs/forward.md +3 -3
- package/dist/plugin/skills/do/open-prs/update.md +1 -1
- package/dist/plugin/skills/do/pre-flight.md +3 -3
- package/dist/plugin/skills/mbt/SKILL.md +8 -0
- package/dist/plugin/skills/mdo/SKILL.md +3 -3
- package/dist/plugin/skills/mprfollowup/SKILL.md +8 -0
- package/dist/plugin/skills/muggle/SKILL.md +1 -0
- package/{plugin/skills/muggle-do-task → dist/plugin/skills/muggle-browser-task}/SKILL.md +1 -1
- package/dist/plugin/skills/muggle-do/SKILL.md +29 -10
- package/dist/plugin/skills/muggle-feedback/SKILL.md +1 -1
- package/dist/plugin/skills/muggle-pr-followup/CLAUDE.md +4 -5
- package/dist/plugin/skills/muggle-pr-followup/SKILL.md +5 -3
- package/dist/plugin/skills/muggle-pr-followup/auto-track.md +5 -1
- package/dist/plugin/skills/muggle-pr-followup/bootstrap.md +5 -3
- package/dist/plugin/skills/muggle-pr-followup/contract.md +34 -17
- package/dist/plugin/skills/muggle-pr-followup/finalize.md +29 -0
- package/dist/plugin/skills/muggle-pr-followup/reconcile.md +33 -0
- package/dist/plugin/skills/muggle-pr-followup/state-schemas.md +10 -2
- package/dist/plugin/skills/muggle-preferences/ops/configure.md +2 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoResolveConflicts.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoWatchPR.md +13 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/reusePreparePlan.md +11 -0
- package/dist/plugin/skills/muggle-status/SKILL.md +1 -1
- package/dist/plugin/skills/muggle-test/SKILL.md +30 -48
- package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +20 -44
- package/dist/plugin/skills/muggle-test-prepare/SKILL.md +5 -1
- package/dist/plugin/skills/muggle-test-prepare/steps/check-running.md +7 -5
- package/dist/plugin/skills/muggle-test-prepare/steps/identify-services.md +2 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/readiness-report.md +30 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/reuse-plan.md +44 -0
- package/dist/release-manifest.json +4 -4
- package/package.json +7 -6
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/README.md +1 -1
- package/plugin/agents/acceptance-tester.md +2 -0
- package/plugin/commands/mbt.md +7 -0
- package/plugin/commands/mdo.md +3 -3
- package/plugin/commands/mprfollowup.md +7 -0
- package/plugin/skills/CLAUDE.md +15 -0
- package/plugin/skills/_aliases.json +2 -1
- package/plugin/skills/_shared/ci-check-to-command.md +10 -0
- package/plugin/skills/_shared/dev-loop/action-script.md +3 -0
- package/plugin/skills/_shared/dev-loop/failures.md +14 -0
- package/plugin/skills/_shared/dev-loop/fresh-session.md +10 -0
- package/plugin/skills/_shared/dev-loop/publish.md +13 -0
- package/plugin/skills/_shared/dev-loop/run.md +34 -0
- package/plugin/skills/_shared/dev-loop/timeouts.md +6 -0
- package/plugin/skills/_shared/failure-mode-handling.md +2 -2
- package/plugin/skills/_shared/github-cli-recipes/pr-checks.md +22 -0
- package/plugin/skills/_shared/github-cli-recipes.md +1 -0
- package/plugin/skills/_shared/post-merge-cleanup.md +1 -1
- package/plugin/skills/_shared/pr-branch-worktree.md +1 -1
- package/plugin/skills/_shared/rebase-before-e2e.md +7 -1
- package/plugin/skills/_shared/resolve-e2e-validation-context.md +1 -1
- package/plugin/skills/_shared/resolve-rebase-conflicts.md +60 -0
- package/plugin/skills/_shared/telemetry-events/muggle-do-cycle.md +8 -1
- package/plugin/skills/_shared/telemetry-events/muggle-do-escalation.md +2 -1
- package/plugin/skills/_shared/telemetry-events/pr-followup-tick.md +4 -0
- package/plugin/skills/_shared/use-worktrees.md +2 -1
- package/plugin/skills/do/address-reviews.md +7 -1
- package/plugin/skills/do/build.md +2 -1
- package/plugin/skills/do/cleanup.md +14 -0
- package/plugin/skills/do/e2e-acceptance.md +5 -66
- package/plugin/skills/do/fix-ci.md +60 -0
- package/plugin/skills/do/input-routing.md +12 -0
- package/plugin/skills/do/open-prs/forward.md +3 -3
- package/plugin/skills/do/open-prs/update.md +1 -1
- package/plugin/skills/do/pre-flight.md +3 -3
- package/plugin/skills/mbt/SKILL.md +8 -0
- package/plugin/skills/mdo/SKILL.md +3 -3
- package/plugin/skills/mprfollowup/SKILL.md +8 -0
- package/plugin/skills/muggle/SKILL.md +1 -0
- package/{dist/plugin/skills/muggle-do-task → plugin/skills/muggle-browser-task}/SKILL.md +1 -1
- package/plugin/skills/muggle-do/SKILL.md +29 -10
- package/plugin/skills/muggle-feedback/SKILL.md +1 -1
- package/plugin/skills/muggle-pr-followup/CLAUDE.md +4 -5
- package/plugin/skills/muggle-pr-followup/SKILL.md +5 -3
- package/plugin/skills/muggle-pr-followup/auto-track.md +5 -1
- package/plugin/skills/muggle-pr-followup/bootstrap.md +5 -3
- package/plugin/skills/muggle-pr-followup/contract.md +34 -17
- package/plugin/skills/muggle-pr-followup/finalize.md +29 -0
- package/plugin/skills/muggle-pr-followup/reconcile.md +33 -0
- package/plugin/skills/muggle-pr-followup/state-schemas.md +10 -2
- package/plugin/skills/muggle-preferences/ops/configure.md +2 -1
- package/plugin/skills/muggle-preferences/preference-gates/autoResolveConflicts.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoWatchPR.md +13 -0
- package/plugin/skills/muggle-preferences/preference-gates/reusePreparePlan.md +11 -0
- package/plugin/skills/muggle-status/SKILL.md +1 -1
- package/plugin/skills/muggle-test/SKILL.md +30 -48
- package/plugin/skills/muggle-test-feature-local/SKILL.md +20 -44
- package/plugin/skills/muggle-test-prepare/SKILL.md +5 -1
- package/plugin/skills/muggle-test-prepare/steps/check-running.md +7 -5
- package/plugin/skills/muggle-test-prepare/steps/identify-services.md +2 -0
- package/plugin/skills/muggle-test-prepare/steps/readiness-report.md +30 -0
- package/plugin/skills/muggle-test-prepare/steps/reuse-plan.md +44 -0
- package/dist/plugin/commands/mrelease.md +0 -7
- package/dist/plugin/skills/mrelease/SKILL.md +0 -8
- package/dist/plugin/skills/muggle-works-npm-release/SKILL.md +0 -200
- package/plugin/commands/mrelease.md +0 -7
- package/plugin/skills/mrelease/SKILL.md +0 -8
- package/plugin/skills/muggle-works-npm-release/SKILL.md +0 -200
|
@@ -58,7 +58,7 @@ For a `local-e2e` block, use `localUrl`, `projectId`, and the working-tree path
|
|
|
58
58
|
|
|
59
59
|
Before launching the local runner:
|
|
60
60
|
|
|
61
|
-
1. **Dev-server + backend readiness** —
|
|
61
|
+
1. **Dev-server + backend readiness** — invoke [`muggle-test-prepare`](../muggle-test-prepare/SKILL.md), the readiness/service-start owner (idempotent fast-exit when healthy; probes via `dev-server-readiness.md`). Halt on failure.
|
|
62
62
|
2. **Auth** — `muggle-remote-auth-status` must be `authenticated`; else escalate.
|
|
63
63
|
3. **Identity tenant/domain match** — if test credentials were marked `existing`, confirm the repo's configured identity tenant/domain matches the recorded tenant/domain. Mismatch → halt.
|
|
64
64
|
|
|
@@ -96,71 +96,11 @@ Based on the changed files and the requirements goal, determine which test cases
|
|
|
96
96
|
- Test cases that cover areas potentially affected by the changes
|
|
97
97
|
- When in doubt, include the test case (better to over-test than miss a regression)
|
|
98
98
|
|
|
99
|
-
### Step 4:
|
|
99
|
+
### Step 4: Run the dev loop, publish, gather screenshots
|
|
100
100
|
|
|
101
|
-
For each relevant test case:
|
|
101
|
+
For each relevant test case, run the shared loop in [`../_shared/dev-loop/run.md`](../_shared/dev-loop/run.md): `muggle-remote-test-script-list` by `testCaseId` to pick [replay vs regen](../_shared/dev-loop/run.md), [execute with `timeoutMs`](../_shared/dev-loop/timeouts.md), [fetch the result](../_shared/dev-loop/failures.md) and [interpret failures](../_shared/dev-loop/failures.md), [publish](../_shared/dev-loop/publish.md), and gather [per-step screenshots](../_shared/dev-loop/publish.md).
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
2. **If a script exists** (replay path):
|
|
106
|
-
- `muggle-remote-test-script-get` with `testScriptId` → note `actionScriptId`
|
|
107
|
-
- `muggle-remote-action-script-get` with that id → full `actionScript`
|
|
108
|
-
- **Use the API response as-is.** Do not edit, shorten, or rebuild `actionScript`; replay needs full `label` paths for element lookup.
|
|
109
|
-
- `muggle-local-execute-replay` with:
|
|
110
|
-
- `testScript`: the full script object
|
|
111
|
-
- `actionScript`: the full action script object (from `muggle-remote-action-script-get`)
|
|
112
|
-
- `localUrl`: the resolved local URL
|
|
113
|
-
- `timeoutMs`: `600000` (10 min) or `900000` (15 min) for complex flows
|
|
114
|
-
|
|
115
|
-
3. **If no script exists** (generation path):
|
|
116
|
-
- `muggle-remote-test-case-get` with `testCaseId` to fetch the full test case object.
|
|
117
|
-
- `muggle-local-execute-test-generation` with:
|
|
118
|
-
- `testCase`: the full test case object
|
|
119
|
-
- `localUrl`: the resolved local URL
|
|
120
|
-
- `timeoutMs`: `600000` (10 min) or `900000` (15 min) for complex flows
|
|
121
|
-
|
|
122
|
-
4. When execution completes, call `muggle-local-run-result-get` with the `runId` returned by the execute call.
|
|
123
|
-
|
|
124
|
-
5. **Retain per test case:** `testCaseId`, `testScriptId` (if present), `runId`, `status` (passed/failed), `artifactsDir`.
|
|
125
|
-
|
|
126
|
-
### Local Execution Timeout (`timeoutMs`)
|
|
127
|
-
|
|
128
|
-
The MCP client often uses a **default wait of 300000 ms (5 minutes)**. **Exploratory script generation** (identity login, multi-step app flows, many LLM iterations) routinely **runs longer than 5 minutes** while Electron is still healthy.
|
|
129
|
-
|
|
130
|
-
- **Always pass `timeoutMs`** — `600000` (10 min) or `900000` (15 min) — unless the test case is known to be simple.
|
|
131
|
-
- If the tool reports **`Electron execution timed out after 300000ms`** but Electron logs show the run still progressing (steps, screenshots, LLM calls), treat it as **orchestration timeout**, not an Electron app defect: **increase `timeoutMs` and retry**.
|
|
132
|
-
|
|
133
|
-
### Interpreting Failures
|
|
134
|
-
|
|
135
|
-
- **`Electron execution timed out after 300000ms`:** Orchestration wait too short — see `timeoutMs` above.
|
|
136
|
-
- **Exit code 26** (and messages like **LLM failed to generate / replay action script**): Often corresponds to a completed exploration whose **outcome was goal not achievable** (`goal_not_achievable`, summary with `halt`). Use `muggle-local-run-result-get` and read the **summary / structured summary**; do not assume an Electron crash.
|
|
137
|
-
- **Fix for precondition failures:** Choose a project/account that already has the needed state, or narrow the test goal so generation does not try to create resources from scratch unless intentional.
|
|
138
|
-
|
|
139
|
-
### Step 5: Publish Test Scripts
|
|
140
|
-
|
|
141
|
-
After each test execution completes (whether pass or fail):
|
|
142
|
-
|
|
143
|
-
1. Call `muggle-local-publish-test-script` with:
|
|
144
|
-
- `runId`: the run ID from execution
|
|
145
|
-
- `cloudTestCaseId`: the test case ID
|
|
146
|
-
|
|
147
|
-
2. **Retain from publish response:**
|
|
148
|
-
- `testScriptId`: the cloud test script ID
|
|
149
|
-
- `viewUrl`: the URL to view the run on muggle-ai.com
|
|
150
|
-
|
|
151
|
-
This ensures all screenshots are uploaded to the cloud and accessible via URLs for PR comments.
|
|
152
|
-
|
|
153
|
-
### Step 6: Fetch Screenshot URLs
|
|
154
|
-
|
|
155
|
-
For each published test script:
|
|
156
|
-
|
|
157
|
-
1. Call `muggle-remote-test-script-get` with the `testScriptId` from publish.
|
|
158
|
-
|
|
159
|
-
2. Extract from the response:
|
|
160
|
-
- `steps[].operation.screenshotUrl`: cloud URL for each step's screenshot
|
|
161
|
-
- `steps[].operation.action`: the action description for each step
|
|
162
|
-
|
|
163
|
-
3. **Retain per test case:** array of `{ stepIndex, action, screenshotUrl }`.
|
|
103
|
+
Inputs to the loop: `mode` from the script-exists check, `localUrl`/project from Step 1.7, `cwd` = the working tree recorded in `state.md`.
|
|
164
104
|
|
|
165
105
|
### Step 7: Collect Results
|
|
166
106
|
|
|
@@ -216,8 +156,7 @@ For each test case:
|
|
|
216
156
|
## Non-negotiables
|
|
217
157
|
|
|
218
158
|
- No silent auth skip; always verify with `muggle-remote-auth-status` first.
|
|
219
|
-
- Replay
|
|
220
|
-
- Always pass `timeoutMs` for execution calls; do not rely on default 5-minute timeout.
|
|
159
|
+
- Replay/timeout/result discipline per [`../_shared/dev-loop/run.md`](../_shared/dev-loop/run.md) — never hand-build `actionScript`, always pass `timeoutMs`, read structured run-result fields.
|
|
221
160
|
- No hiding failures: surface errors, exit codes, and artifact paths.
|
|
222
161
|
- In `local-e2e` mode, every relevant test case must be executed — generate a new script if none exists (no skips).
|
|
223
162
|
- Always publish after execution to ensure screenshots are cloud-accessible for PR comments.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Fix-CI (watcher-dispatched)
|
|
2
|
+
|
|
3
|
+
Resolve red CI on a PR's head — lint/format, typecheck, and failing unit tests — verifying green before re-push. A dumb-pipe dispatch like address-reviews: the executor receives a PR URL, slug, and the failing check names, and fixes them — it owns the fix, not the decision to dispatch.
|
|
4
|
+
|
|
5
|
+
## Turn preamble
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
**/muggle-do fix-ci** — fixing <count> red check(s) on <owner>/<repo>#<n>.
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Input
|
|
12
|
+
|
|
13
|
+
`$ARGUMENTS` carries a `github.com/.../pull/<n>` URL, `slug=<slug>`, and the failing check names (no review ids). Parse all three.
|
|
14
|
+
|
|
15
|
+
## Inputs from disk
|
|
16
|
+
|
|
17
|
+
From `~/.muggle-ai/muggle-do/sessions/<slug>/`: `prs.json` (PR + local checkout / branch), `last_seen.json` (`ci_fix_attempts`, `ci_escalated_shas`, `pushed_shas`), `state.md` (worktree path, validation strategy).
|
|
18
|
+
|
|
19
|
+
## Procedure
|
|
20
|
+
|
|
21
|
+
### Step 1 — Re-attach
|
|
22
|
+
|
|
23
|
+
Check out the PR branch in the session's working tree (per `state.md`). Capture `red_sha = prs.json[0].head_sha`.
|
|
24
|
+
|
|
25
|
+
### Step 2 — Map each failing check to a local command
|
|
26
|
+
|
|
27
|
+
Per [`../_shared/ci-check-to-command.md`](../_shared/ci-check-to-command.md). Fix the in-scope checks in the working tree; record out-of-scope checks for escalation (Step 6).
|
|
28
|
+
|
|
29
|
+
### Step 3 — Verify before push
|
|
30
|
+
|
|
31
|
+
- Build (typecheck + lint on the changed surface) + unit suite must pass.
|
|
32
|
+
- Run E2E (per [`../muggle-preferences/preference-gates/autoE2ETest.md`](../muggle-preferences/preference-gates/autoE2ETest.md)) only if the fix touched app logic; lint/format-only fixes skip E2E.
|
|
33
|
+
|
|
34
|
+
A fix that can't be made green locally is not pushed → Step 6.
|
|
35
|
+
|
|
36
|
+
### Step 4 — Commit + push
|
|
37
|
+
|
|
38
|
+
Commit per the `fix(ci): <check> — <what>` convention ([`../_shared/pr-followup-helpers/reply-routing.md`](../_shared/pr-followup-helpers/reply-routing.md)). Push. Append the new SHA to `last_seen.pushed_shas`. **No PR replies** — the fix commit is the response.
|
|
39
|
+
|
|
40
|
+
### Step 5 — Update state + respawn
|
|
41
|
+
|
|
42
|
+
- Increment `last_seen.ci_fix_attempts[red_sha]`.
|
|
43
|
+
- Respawn the watcher: `/loop 1m /muggle:muggle-pr-followup <slug> <n>`. CI on the new SHA is the verify loop — a still-red SHA returns as a fresh dispatch, bounded by the per-SHA fix budget (Step 6).
|
|
44
|
+
|
|
45
|
+
### Step 6 — Escalate (budget spent or out of scope)
|
|
46
|
+
|
|
47
|
+
When the failing checks are all out of scope, or `ci_fix_attempts[red_sha]` has reached 3 with CI still red:
|
|
48
|
+
|
|
49
|
+
1. Add `red_sha` to `last_seen.ci_escalated_shas` so the SHA is not re-fixed.
|
|
50
|
+
2. Emit one terminal message naming the unresolved checks.
|
|
51
|
+
3. Emit the cycle event with `outcome: "ci-escalated"` (Step 7). Do not loop further on this SHA.
|
|
52
|
+
|
|
53
|
+
### Step 7 — Telemetry
|
|
54
|
+
|
|
55
|
+
Emit one `muggle-do:cycle` event ([`../_shared/telemetry-events/muggle-do-cycle.md`](../_shared/telemetry-events/muggle-do-cycle.md)): `outcome: "ci-fixed"` when a fix pushed, `"ci-escalated"` when escalated — with `ci_checks_in` / `ci_checks_fixed` / `ci_checks_escalated`.
|
|
56
|
+
|
|
57
|
+
## Guardrails
|
|
58
|
+
|
|
59
|
+
- Max 3 fix attempts per SHA; out-of-scope checks escalate immediately rather than churn.
|
|
60
|
+
- No PR replies; the fix commit is the response.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Input routing
|
|
2
|
+
|
|
3
|
+
How `/muggle-do` resolves `$ARGUMENTS` to a mode. Modes 1–3 are programmatic — dispatched by the watcher — so never ask on those. Inspect in order:
|
|
4
|
+
|
|
5
|
+
1. **Address-reviews** — a `github.com/.../pull/<n>` URL **and** one or more review ids (integers ≥ 100000000) → [`address-reviews.md`](address-reviews.md).
|
|
6
|
+
2. **Fix-CI** — a `github.com/.../pull/<n>` URL **and** a `fix ci` / `fix-ci` directive with failing check names (no review ids) → [`fix-ci.md`](fix-ci.md).
|
|
7
|
+
3. **Post-merge cleanup** — a `cleanup` token and `slug=<slug>` (no PR URL, no review ids) → [`cleanup.md`](cleanup.md).
|
|
8
|
+
4. **Empty / `help` / `menu` / `?`** → menu + session selector.
|
|
9
|
+
5. **Task automation** (perform an action on a website) → `muggle:muggle-browser-task`.
|
|
10
|
+
6. **Otherwise** → forward pipeline at Stage 1.
|
|
11
|
+
|
|
12
|
+
When in doubt between #5 and #6, ask one question.
|
|
@@ -40,13 +40,13 @@ Forward pipeline's Stage 7. Invoked by `/muggle-do` after stages 1–6 of a fres
|
|
|
40
40
|
|
|
41
41
|
After every repo is processed, build the watcher manifest and dispatch one watcher loop per opened PR. The dispatches are the LAST action this stage takes.
|
|
42
42
|
|
|
43
|
-
Write
|
|
43
|
+
Write `~/.muggle-ai/muggle-do/sessions/<slug>/prs.json` per [`../../muggle-pr-followup/state-schemas.md`](../../muggle-pr-followup/state-schemas.md#prsjson):
|
|
44
44
|
|
|
45
45
|
```json
|
|
46
46
|
[{ "repo": "owner/repo", "number": 142, "url": "...", "head_sha": "...", "state": "open" }]
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
Seed
|
|
49
|
+
Seed `~/.muggle-ai/muggle-do/sessions/<slug>/last_seen.json` per [`../../muggle-pr-followup/state-schemas.md`](../../muggle-pr-followup/state-schemas.md#last_seenjson) — empty cursor shape with `pushed_shas: []`. Forward mode never has prior reviews to skip, so `reviewId: 0`.
|
|
50
50
|
|
|
51
51
|
**Do not** seed `cycle.json` or `requirements.md`. The watcher is a dumb pipe; `/muggle-do` reads reviews off GitHub.
|
|
52
52
|
|
|
@@ -71,7 +71,7 @@ If `prs.json` is empty, **do not dispatch** — record the reason in `result.md`
|
|
|
71
71
|
|
|
72
72
|
## Post-merge cleanup
|
|
73
73
|
|
|
74
|
-
Gated by `autoCleanup`.
|
|
74
|
+
Gated by `autoCleanup`. Triggered when the watcher's terminal tick observes the merge and dispatches `/muggle-do`'s cleanup directive ([`../cleanup.md`](../cleanup.md)) — never from this stage. See [`../../_shared/post-merge-cleanup.md`](../../_shared/post-merge-cleanup.md).
|
|
75
75
|
|
|
76
76
|
Append one short reminder tied to the gate value:
|
|
77
77
|
|
|
@@ -13,7 +13,7 @@ Does **not** create a PR, seed session state, or dispatch a watcher (`/muggle-do
|
|
|
13
13
|
## Inputs
|
|
14
14
|
|
|
15
15
|
- Per-repo: path, branch (head ref name).
|
|
16
|
-
- The existing PR URL + number from
|
|
16
|
+
- The existing PR URL + number from `~/.muggle-ai/muggle-do/sessions/<slug>/prs.json`.
|
|
17
17
|
- **Optional** E2E acceptance report from stage 6. Produced by [`../e2e-acceptance.md`](../e2e-acceptance.md); schema in [`../../muggle-pr-visual-walkthrough/SKILL.md`](../../muggle-pr-visual-walkthrough/SKILL.md).
|
|
18
18
|
|
|
19
19
|
## Procedure
|
|
@@ -26,8 +26,8 @@ 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. **
|
|
30
|
-
4. **
|
|
29
|
+
3. **Local environment readiness.** Invoke [`muggle-test-prepare`](../muggle-test-prepare/SKILL.md) — the owner of dev-server/backend detection and service start (idempotent; it probes via `dev-server-readiness.md` internally). Use what it reports as the dev-server/URL pre-flight signal.
|
|
30
|
+
4. **Backend health.** Covered by the same `muggle-test-prepare` invocation above (it probes backend health); note up/down.
|
|
31
31
|
5. **Muggle Test MCP auth.** Call `muggle-remote-auth-status`. If expired, you will ask to re-auth in the questionnaire.
|
|
32
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
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.
|
|
@@ -55,7 +55,7 @@ Present **one `AskUserQuestion`** (or the platform's structured-selection equiva
|
|
|
55
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".
|
|
56
56
|
9. **PR target branch** — default: the repo's default branch. "Use default" / "Target a different branch".
|
|
57
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
|
|
58
|
+
11. **Worktree for this change?** — gate: [`autoUseWorktree`](../muggle-preferences/preference-gates/autoUseWorktree.md). Options: create a dedicated worktree (per [`../_shared/use-worktrees.md`](../_shared/use-worktrees.md)), or work in the current checkout.
|
|
59
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
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.
|
|
61
61
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mbt
|
|
3
|
+
description: Explicit short alias for the `muggle-browser-task` skill. ONLY invoke when the user explicitly types `mbt` or `/mbt` — never auto-trigger from any other phrasing.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# mbt — alias for muggle-browser-task
|
|
7
|
+
|
|
8
|
+
Invoke the `muggle-browser-task` skill via the Skill tool. Forward any user-provided arguments unchanged.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mdo
|
|
3
|
-
description: Explicit short alias for the `muggle-do
|
|
3
|
+
description: Explicit short alias for the `muggle-do` skill. ONLY invoke when the user explicitly types `mdo` or `/mdo` — never auto-trigger from any other phrasing.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# mdo — alias for muggle-do
|
|
6
|
+
# mdo — alias for muggle-do
|
|
7
7
|
|
|
8
|
-
Invoke the `muggle-do
|
|
8
|
+
Invoke the `muggle-do` skill via the Skill tool. Forward any user-provided arguments unchanged.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mprfollowup
|
|
3
|
+
description: Explicit short alias for the `muggle-pr-followup` skill. ONLY invoke when the user explicitly types `mprfollowup` or `/mprfollowup` — never auto-trigger from any other phrasing.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# mprfollowup — alias for muggle-pr-followup
|
|
7
|
+
|
|
8
|
+
Invoke the `muggle-pr-followup` skill via the Skill tool. Forward any user-provided arguments unchanged.
|
|
@@ -37,6 +37,7 @@ If the user intent clearly matches one command, route directly — no menu neede
|
|
|
37
37
|
- test localhost/validate single feature/test a feature → `muggle-test-feature-local`
|
|
38
38
|
- build/implement from request/end-to-end → `muggle-do`
|
|
39
39
|
- post results to PR/attach walkthrough/visual evidence on PR → `muggle-pr-visual-walkthrough`
|
|
40
|
+
- watch my PR for reviews/follow up on PR reviews/babysit PR review thread → `muggle-pr-followup`
|
|
40
41
|
- give feedback on a run/the test was wrong/step N didn't work/show my feedback/delete feedback → `muggle-feedback`
|
|
41
42
|
|
|
42
43
|
If intent is ambiguous, use `AskUserQuestion` with the most likely options rather than asking the user to type a clarification.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: muggle-
|
|
2
|
+
name: muggle-browser-task
|
|
3
3
|
description: Run a browser automation task on a website using natural language. Finds or creates the Muggle Test project, use case, test case, and script, then executes locally via the electron app. Use when the user wants to perform an action on a website (post, fill a form, click through a flow) rather than implement a code change.
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -25,32 +25,51 @@ Runs an autonomous dev cycle from requirements to PR. **Fire and review:** user
|
|
|
25
25
|
|
|
26
26
|
Stage 7 dispatches one watcher per opened PR as its last action.
|
|
27
27
|
|
|
28
|
+
## Execution protocol (non-negotiable)
|
|
29
|
+
|
|
30
|
+
The pipeline table lists **pointers, not summaries**. Open each stage's file and execute from it — running a stage off its one-line row here is how tests, E2E, and session state get silently skipped. If you have not read a stage's file this run, you have not run that stage.
|
|
31
|
+
|
|
32
|
+
**Bootstrap before any code, in order:**
|
|
33
|
+
1. Emit telemetry — [`../_shared/telemetry-emit.md`](../_shared/telemetry-emit.md), `skillName: "muggle-do"`.
|
|
34
|
+
2. Create `~/.muggle-ai/muggle-do/sessions/<slug>/` with `state.md` + `iterations/001.md` (pre-flight owns this; do it even when running unattended).
|
|
35
|
+
3. `TodoWrite` one item per stage 1–8 — these stages are the checklist; never swap in your own decomposition.
|
|
36
|
+
|
|
37
|
+
**Per stage:** read the file → execute it → append a marker to `iterations/<NNN>.md` citing the evidence that file requires (jest exit code, E2E verdict + `runId`, screenshot path). A stage is done only when its evidence is written, never on recollection.
|
|
38
|
+
|
|
39
|
+
### "Autonomous" / "without my intervention" collapses exactly one thing
|
|
40
|
+
Best-effort the Stage-1 questionnaire and don't ask. It does **not** license skipping telemetry, session artifacts, requirements, unit tests, E2E (`autoE2ETest` defaults to `always`), browser verification, the gate below, or the watcher hand-off. Run the whole pipeline silently — never a shortcut.
|
|
41
|
+
|
|
42
|
+
### Definition of Done — gate before Stage 7
|
|
43
|
+
Do not create or update a PR until each line holds, or is waived by a one-line reason written into `state.md` (silence is not a waiver):
|
|
44
|
+
- `requirements.md` written (forward runs)
|
|
45
|
+
- Build clean — typecheck + lint on changed files
|
|
46
|
+
- New/changed logic carries unit tests (authored in Stage 3; Stage 5 only runs the suite)
|
|
47
|
+
- Unit suite run, PASS recorded
|
|
48
|
+
- E2E verdict recorded with `runId` per `autoE2ETest` — or `[E2E FAILING]` / `SKIPPED` + reason
|
|
49
|
+
- UI changes verified in a real browser with evidence (screenshot path or muggle `runId`); `curl` + `grep` is not verification
|
|
50
|
+
|
|
51
|
+
Opening a PR with an unchecked, unwaived line is a cycle failure.
|
|
52
|
+
|
|
28
53
|
## Address-reviews flow
|
|
29
54
|
|
|
30
55
|
When invoked with the directive (PR URL + slug + review ids), routes to [`../do/address-reviews.md`](../do/address-reviews.md). Shares stages 3–6 + walkthrough with the forward pipeline; skips pre-flight, requirements, and PR creation. See the orchestrator for the cycle's exact step order, classification rules, and respawn logic.
|
|
31
56
|
|
|
32
57
|
## Input routing
|
|
33
58
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
1. **Address-reviews** — input contains a `github.com/.../pull/<n>` URL **and** one or more integers ≥ 100000000 (review id shape) → [`../do/address-reviews.md`](../do/address-reviews.md). Programmatic; never ask.
|
|
37
|
-
2. **Empty / `help` / `menu` / `?`** → menu + session selector.
|
|
38
|
-
3. **Task automation** (perform an action on a website) → `muggle:muggle-do-task`.
|
|
39
|
-
4. **Otherwise** → forward pipeline at Stage 1.
|
|
40
|
-
|
|
41
|
-
When in doubt between #3 and #4, ask one question.
|
|
59
|
+
`/muggle-do` serves one interactive mode (the forward pipeline, from a fresh task) and three programmatic modes the watcher dispatches (address-reviews, fix-ci, post-merge cleanup). Resolve `$ARGUMENTS` to a mode per [`../do/input-routing.md`](../do/input-routing.md) before doing anything else.
|
|
42
60
|
|
|
43
61
|
## Preferences
|
|
44
62
|
|
|
45
63
|
| Preference | Gate |
|
|
46
64
|
| :--------- | :--- |
|
|
47
65
|
| `autoE2ETest` | Stage 6 — run E2E every cycle (default `always`), or fold into pre-flight |
|
|
66
|
+
| `autoResolveConflicts` | On rebase conflict — resolve autonomously behind a verify-or-rollback gate (opt-in), or abort + escalate (default `never`) |
|
|
48
67
|
|
|
49
|
-
`autoUseWorktree`, `autoRebase`, `autoCreatePR`, `autoCleanup` fire from per-stage files.
|
|
68
|
+
`autoUseWorktree`, `autoRebase`, `autoResolveConflicts`, `autoCreatePR`, `autoCleanup` fire from per-stage files.
|
|
50
69
|
|
|
51
70
|
## Session model
|
|
52
71
|
|
|
53
|
-
|
|
72
|
+
`~/.muggle-ai/muggle-do/sessions/<slug>/`. Schemas: [`../muggle-pr-followup/state-schemas.md`](../muggle-pr-followup/state-schemas.md).
|
|
54
73
|
|
|
55
74
|
| File | Owner |
|
|
56
75
|
| :--- | :---- |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-feedback
|
|
3
|
-
description:
|
|
3
|
+
description: Use when the user wants to flag that a generated Muggle Test action script — or one specific step in it — did the wrong thing, and have it captured so Muggle can analyze and regenerate affected scripts. Covers any report that a script or step is wrong, broken, or misbehaving (clicked the wrong element, bad summary, "step N didn't work", "broken at the submit step"), whether the user just ran a test locally or remotely or pastes a Muggle dashboard run/script URL and points at what failed. Also use to view, list, or delete previously submitted feedback. Triggers on '/muggle-feedback', 'give feedback on this run', 'the test was wrong', 'flag this run', 'show/list/delete my feedback'. Auto-detects run context from a recent local run, a remote run, or a dashboard URL in the prompt.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Muggle Test Feedback
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# muggle-pr-followup — folder TOC
|
|
2
2
|
|
|
3
|
-
This folder holds the watcher loop for PR review follow-ups. The watcher is a **dumb pipe**: it polls for new submitted reviews and dispatches `/muggle-do` when there
|
|
3
|
+
This folder holds the watcher loop for PR review follow-ups. The watcher is a **dumb pipe**: it polls for new submitted reviews and CI checks and dispatches `/muggle-do` when there's review feedback or fixable red CI. Cycle execution, classification, replies, and escalation all live in `/muggle-do`'s address-reviews mode — see [stage-8 design](../../../../muggle-ai-brain/architecture/2026-05-08-muggle-do-pr-comment-loop-design.md) for the architectural rationale.
|
|
4
4
|
|
|
5
5
|
## Files in this folder
|
|
6
6
|
|
|
@@ -8,6 +8,8 @@ This folder holds the watcher loop for PR review follow-ups. The watcher is a **
|
|
|
8
8
|
- [`auto-track.md`](auto-track.md) — the no-args procedure: discovers PRs pushed this session (any repo) and seeds one poll-only watcher each. Seeds no E2E context — the watcher only watches.
|
|
9
9
|
- [`bootstrap.md`](bootstrap.md) — the bootstrap procedure (asks once for the E2E validation context, seeds state, dispatches the first watcher).
|
|
10
10
|
- [`contract.md`](contract.md) — the watcher per-tick procedure (poll → dispatch → exit).
|
|
11
|
+
- [`finalize.md`](finalize.md) — shared termination sequence for a terminal PR (mark terminal, `result.md`, log/telemetry, unschedule cron, post-merge cleanup handoff). Called by `contract.md` and `reconcile.md`.
|
|
12
|
+
- [`reconcile.md`](reconcile.md) — sweep that finalizes slots whose PR went terminal while polling lapsed; runs at the top of auto-track and on demand.
|
|
11
13
|
- [`state-schemas.md`](state-schemas.md) — canonical JSON shapes of session state files.
|
|
12
14
|
- [`output-templates.md`](output-templates.md) — TOC of message templates; per-group files in `output-templates/`.
|
|
13
15
|
|
|
@@ -21,7 +23,4 @@ Shared with other skills, under `../_shared/`:
|
|
|
21
23
|
- [`telemetry-events.md`](../_shared/telemetry-events.md) — TOC of canonical event shapes; per-event files in `_shared/telemetry-events/`.
|
|
22
24
|
- [`github-cli-recipes.md`](../_shared/github-cli-recipes.md) — TOC of reusable `gh` / `git` snippets; per-recipe files in `_shared/github-cli-recipes/`.
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
- [`open-prs.md`](../do/open-prs.md) — TOC for the create-or-update PR stage; per-mode files in `do/open-prs/`.
|
|
27
|
-
- [`resolve-reminder.md`](../do/resolve-reminder.md) — `/muggle-do`'s per-round stage that nudges the reviewer to resolve addressed-but-still-open threads.
|
|
26
|
+
Callers (e.g. `/muggle-do`) reference this folder, not the reverse — see [`../CLAUDE.md`](../CLAUDE.md) for the one-way-dependency rule.
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-pr-followup
|
|
3
|
-
description:
|
|
4
|
-
disable-model-invocation: true
|
|
3
|
+
description: Use this skill when the user wants a pull request's incoming review feedback handled for them — it watches one PR's review thread and, each time a reviewer submits new comments, dispatches the work to address them. Engage on PR-review-follow-up intent: "watch my PR and address review comments as they come in", "keep an eye on PR #123 and respond to reviewer feedback", "follow up on my PR's reviews", "babysit my PR's review thread", "auto-handle reviews on the PR I just opened", "I'm stepping away — handle my PR's reviews while I'm gone". Run with no args to track every PR you pushed this session (any repo); pass a PR URL to start watching a specific one. This is PR-review-specific automation: when the recurring thing the user wants handled is a PR's review comments, use this — not the generic `loop` skill. It only watches and dispatches; the actual edits and replies are `muggle-do`. Not for posting test results to a PR (use muggle-pr-visual-walkthrough).
|
|
5
4
|
---
|
|
6
5
|
|
|
7
6
|
# muggle-pr-followup
|
|
8
7
|
|
|
9
8
|
> Telemetry first step: see [`../_shared/telemetry-emit.md`](../_shared/telemetry-emit.md). Use `skillName: "muggle-pr-followup"`.
|
|
10
9
|
|
|
11
|
-
A watcher that babysits one open PR's review thread. Polls for new submitted reviews; when
|
|
10
|
+
A watcher that babysits one open PR's review thread and CI. Polls for new submitted reviews and check-run state; when review feedback lands or CI goes red, hands the work to `/muggle-do` and exits. On merge, it hands off post-merge cleanup to `/muggle-do` the same way. `/muggle-do` is the executor — it classifies the reviews or fixes the failing checks, pushes, replies per comment, and respawns the watcher.
|
|
12
11
|
|
|
13
12
|
**The watcher is a dumb pipe.** It does not classify reviews, iterate cycles, post replies, or escalate. All of that lives in `/muggle-do`. See [stage-8 design](../../../../muggle-ai-brain/architecture/2026-05-08-muggle-do-pr-comment-loop-design.md) for the rationale.
|
|
14
13
|
|
|
@@ -27,6 +26,9 @@ The skill recognizes its mode by inspecting `$ARGUMENTS` and falling back to on-
|
|
|
27
26
|
| `<pr-number>` alone | zero or multiple matches | **error:** ambiguous; list candidates and exit |
|
|
28
27
|
| empty | — | **auto-track** → [`auto-track.md`](auto-track.md) |
|
|
29
28
|
| `help` / `?` | — | **help:** list active loops per [`output-templates/help.md`](output-templates/help.md) |
|
|
29
|
+
| `reconcile` / `sweep` (optional `<slug>`) | — | **reconcile** → [`reconcile.md`](reconcile.md) |
|
|
30
|
+
|
|
31
|
+
Auto-track runs **reconcile** first, so a no-arg invocation also finalizes any slot whose PR merged or closed while its watcher was down (expired cron, ended session). Reconcile never re-arms a watcher.
|
|
30
32
|
|
|
31
33
|
Bootstrap accepts three optional trailing flags:
|
|
32
34
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The procedure for the **auto-track mode** of `muggle-pr-followup` — invoked when the skill is dispatched with **no arguments**. Routing is in [`SKILL.md`](SKILL.md#routing).
|
|
4
4
|
|
|
5
|
-
Auto-track discovers the PRs you pushed or opened during this Claude Code session — across **any repo** — and starts one **poll-only watcher** per PR. The watcher only watches: it seeds nothing about E2E. Running and posting E2E is `/muggle-do`'s job; a watcher with no validation context yields a `SKIPPED` E2E verdict when `/muggle-do` runs
|
|
5
|
+
Auto-track discovers the PRs you pushed or opened during this Claude Code session — across **any repo** — and starts one **poll-only watcher** per PR. The watcher only watches: it seeds nothing about E2E. Running and posting E2E is `/muggle-do`'s job; a watcher with no validation context yields a `SKIPPED` E2E verdict when `/muggle-do` runs.
|
|
6
6
|
|
|
7
7
|
## Turn preamble
|
|
8
8
|
|
|
@@ -16,6 +16,10 @@ Auto-track discovers the PRs you pushed or opened during this Claude Code sessio
|
|
|
16
16
|
|
|
17
17
|
## Procedure
|
|
18
18
|
|
|
19
|
+
### Step 0 — Reconcile existing slots
|
|
20
|
+
|
|
21
|
+
Run [`reconcile.md`](reconcile.md) first. A no-arg invocation is the natural moment to finalize any slot whose PR merged or closed while its watcher was down — an expired `/loop` cron or an ended session leaves termination un-run (see reconcile's rationale). Then continue discovering new PRs below.
|
|
22
|
+
|
|
19
23
|
### Step 1 — Discover candidate PRs from session context
|
|
20
24
|
|
|
21
25
|
A PR counts as **pushed this session** if, earlier in this conversation, you:
|
|
@@ -37,11 +37,13 @@ Per [`../_shared/github-cli-recipes/verify-working-tree.md`](../_shared/github-c
|
|
|
37
37
|
|
|
38
38
|
### Step 4 — Resolve the slug
|
|
39
39
|
|
|
40
|
-
Default: `<repo>-pr<n>` (e.g. `muggle-ai-works-pr154`). Override: `--slug=<name>`. Session dir is
|
|
40
|
+
Default: `<repo>-pr<n>` (e.g. `muggle-ai-works-pr154`). Override: `--slug=<name>`. Session dir is `~/.muggle-ai/muggle-do/sessions/<slug>/` (under the user's home, shared across repos; the slug's repo-pr<n> prefix keeps it unique).
|
|
41
41
|
|
|
42
42
|
### Step 5 — Idempotency check
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
**Legacy-slot migration.** Pre-move sessions lived at the repo-relative `.muggle-do/sessions/<slug>/` ([`state-schemas.md`](state-schemas.md#legacy-location)). If the new home-dir slot is absent but `<working-tree>/.muggle-do/sessions/<slug>/` exists (working tree from Step 3), move it to the new location first — this carries an in-flight watcher's cursor, `escalated_review_ids`, and `pushed_shas` across the upgrade. Bootstrap is the only stage that performs this: it is the one entry point that knows the old repo-relative path (the cwd), and it is the natural re-entry point after a plugin upgrade. A slot that fails to migrate loses nothing durable — GitHub holds the reviews, so a fresh bootstrap (cursor `0`) re-processes them.
|
|
45
|
+
|
|
46
|
+
If `~/.muggle-ai/muggle-do/sessions/<slug>/` exists (including a slot just migrated above):
|
|
45
47
|
|
|
46
48
|
- Without `--resume` → exit with the slot-conflict abort. Both remedies (delete + re-run, or pass `--resume`) are spelled out in the message.
|
|
47
49
|
- With `--resume` → refresh `prs.json[0].head_sha` to the current `headRefOid` from Step 2; leave `last_seen.json` and the cursor untouched. If `state.md` already has a `## Pre-flight answers` block, skip to Step 8; if not (older session), run Step 6.5 to backfill it, then skip to Step 8.
|
|
@@ -61,7 +63,7 @@ Capture the fields for Step 7. Do **not** run E2E now — the first watcher tick
|
|
|
61
63
|
|
|
62
64
|
Identify the loop user once per [`../_shared/github-cli-recipes/loop-user-identity.md`](../_shared/github-cli-recipes/loop-user-identity.md); cache in `state.md`.
|
|
63
65
|
|
|
64
|
-
Write under
|
|
66
|
+
Write under `~/.muggle-ai/muggle-do/sessions/<slug>/`:
|
|
65
67
|
|
|
66
68
|
**`prs.json`** — see [`state-schemas.md`](state-schemas.md#prsjson). One entry, `state` = `"open"`, `head_sha` from Step 2's `headRefOid`.
|
|
67
69
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Watcher Per-Tick Contract
|
|
2
2
|
|
|
3
|
-
The procedure for the **tick mode** of `muggle-pr-followup` — one polling iteration scoped to one PR. The watcher is a dumb pipe: it polls for new submitted reviews, dispatches `/muggle-do` if there
|
|
3
|
+
The procedure for the **tick mode** of `muggle-pr-followup` — one polling iteration scoped to one PR. The watcher is a dumb pipe: it polls for new submitted reviews and CI checks, dispatches `/muggle-do` if there's review feedback or fixable red CI, and exits. It does not classify, fix, amend requirements, post replies, run cycles, or escalate.
|
|
4
4
|
|
|
5
5
|
Routing into this mode is documented in [`SKILL.md`](SKILL.md#routing). The architectural rationale lives in the brain doc `architecture/2026-05-08-muggle-do-pr-comment-loop-design.md`.
|
|
6
6
|
|
|
@@ -16,7 +16,7 @@ Routing into this mode is documented in [`SKILL.md`](SKILL.md#routing). The arch
|
|
|
16
16
|
|
|
17
17
|
## Inputs from disk
|
|
18
18
|
|
|
19
|
-
Read these from
|
|
19
|
+
Read these from `~/.muggle-ai/muggle-do/sessions/<slug>/`:
|
|
20
20
|
|
|
21
21
|
- `prs.json` — see [`state-schemas.md`](state-schemas.md#prsjson). The watcher touches the single entry whose `number` matches the dispatched PR number.
|
|
22
22
|
- `last_seen.json` — see [`state-schemas.md`](state-schemas.md#last_seenjson). Keyed by `"<owner>/<repo>#<n>"`.
|
|
@@ -33,25 +33,22 @@ Per [`../_shared/github-cli-recipes/pr-metadata.md`](../_shared/github-cli-recip
|
|
|
33
33
|
|
|
34
34
|
If `state` is `MERGED` or `CLOSED`:
|
|
35
35
|
|
|
36
|
-
1.
|
|
37
|
-
2.
|
|
38
|
-
3. Append a terminal line to `followup.log` per [`output-templates/watcher-log.md`](output-templates/watcher-log.md).
|
|
39
|
-
4. Emit a `tick` event with `terminal: true` per [`../_shared/telemetry-events/pr-followup-tick.md`](../_shared/telemetry-events/pr-followup-tick.md).
|
|
40
|
-
5. **Cancel the cron schedule that fires this watcher.** `/loop 1m ...` from bootstrap was registered via `CronCreate`; a fixed-interval cron keeps firing regardless of whether the skill re-dispatches. Call `CronList`, find any job whose command ends with `/muggle:muggle-pr-followup <slug> <pr-number>` (exact two-arg match), and `CronDelete` it. No-op if none matches — the tick may have been invoked manually rather than via `/loop`.
|
|
41
|
-
6. Exit. The watcher has now unscheduled itself; no future ticks will fire for this PR.
|
|
36
|
+
1. Finalize the slot per [`finalize.md`](finalize.md) — mark terminal, write `result.md`, log + telemetry, unschedule this watcher's cron.
|
|
37
|
+
2. **If `MERGED`**, hand off post-merge cleanup as the last action of the turn (skip on `CLOSED` — unmerged, leave the branch and any worktree intact):
|
|
42
38
|
|
|
43
|
-
|
|
39
|
+
```
|
|
40
|
+
/muggle-do post-merge cleanup slug=<slug>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`/muggle-do` owns the worktree/branch knowledge and honors the `autoCleanup` gate. This is a runtime dispatch, not a doc dependency on `/muggle-do` — see the one-way rule in [`../CLAUDE.md`](../CLAUDE.md).
|
|
44
|
+
3. Exit. The watcher has unscheduled itself; no future ticks fire for this PR.
|
|
44
45
|
|
|
45
|
-
Per [`../_shared/github-cli-recipes/submitted-reviews.md`](../_shared/github-cli-recipes/submitted-reviews.md). **Also exclude review ids that appear in `last_seen.escalated_review_ids`** — those have already been escalated and the watcher must not re-dispatch them.
|
|
46
46
|
|
|
47
|
-
### Step
|
|
47
|
+
### Step 3 — Fetch new submitted reviews
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
2. Append an idle line to `followup.log` per [`output-templates/watcher-log.md`](output-templates/watcher-log.md).
|
|
51
|
-
3. Emit a `tick` event with `idle: true`, `reviews_seen: 0`, `dispatched_review_ids: []`.
|
|
52
|
-
4. Exit. The next tick fires in 1 min via `/loop`.
|
|
49
|
+
Per [`../_shared/github-cli-recipes/submitted-reviews.md`](../_shared/github-cli-recipes/submitted-reviews.md). **Also exclude review ids that appear in `last_seen.escalated_review_ids`** — those have already been escalated and the watcher must not re-dispatch them.
|
|
53
50
|
|
|
54
|
-
### Step
|
|
51
|
+
### Step 4 — If one or more new reviews → dispatch (reviews preempt CI)
|
|
55
52
|
|
|
56
53
|
The watcher does **not** classify. Classification, batching, replying, escalation, and cycle execution all live in `/muggle-do`. The watcher's job is to hand over the list of new review ids and exit.
|
|
57
54
|
|
|
@@ -67,7 +64,27 @@ The watcher does **not** classify. Classification, batching, replying, escalatio
|
|
|
67
64
|
```
|
|
68
65
|
3. Append a dispatching line to `followup.log` per [`output-templates/watcher-log.md`](output-templates/watcher-log.md).
|
|
69
66
|
4. Emit a `tick` event with `reviews_seen: <count>`, `dispatched_review_ids: [<id>, ...]`.
|
|
70
|
-
5. Exit.
|
|
67
|
+
5. Exit. **Reviews preempt CI** — when reviews land, this tick dispatches address-reviews and never polls CI. The cron keeps firing; the next tick still arrives. The watcher only self-unschedules in Step 2 (terminal).
|
|
68
|
+
|
|
69
|
+
### Step 5 — No new reviews → poll CI for the head SHA
|
|
70
|
+
|
|
71
|
+
Fetch the check-run rollup for `prs.json[0].head_sha` per [`../_shared/github-cli-recipes/pr-checks.md`](../_shared/github-cli-recipes/pr-checks.md), then:
|
|
72
|
+
|
|
73
|
+
- **Any check still pending** (`bucket == "pending"`) → idle (wait for checks to settle).
|
|
74
|
+
- **All checks green / skipped, or no checks** → idle (green path).
|
|
75
|
+
- **One or more checks red** (`bucket == "fail"`), **and** `ci_fix_attempts[head_sha] < 3`, **and** `head_sha` ∉ `ci_escalated_shas` → dispatch and exit:
|
|
76
|
+
1. Reset `last_seen.idle_tick_count` to 0.
|
|
77
|
+
2. Dispatch `/muggle-do` with a *fix-ci* directive carrying the PR URL, slug, and the red check names (no review ids):
|
|
78
|
+
```
|
|
79
|
+
/muggle-do fix ci <check-1> <check-2> ... on <pr-url> slug=<slug>
|
|
80
|
+
```
|
|
81
|
+
3. Append a dispatching line to `followup.log`; emit a `tick` event with `checks_red: <count>`, `dispatched_ci_fix: true`.
|
|
82
|
+
4. Exit. The next tick re-checks CI on the new head SHA — CI itself is the verify loop.
|
|
83
|
+
- **One or more red, but `ci_fix_attempts[head_sha] >= 3` or `head_sha` ∈ `ci_escalated_shas`** → idle. The fix budget is spent; `/muggle-do`'s fix-ci stage already recorded the escalation. The watcher does not re-dispatch.
|
|
84
|
+
|
|
85
|
+
### Step 6 — Idle
|
|
86
|
+
|
|
87
|
+
Any idle branch (Steps 4–5 that did not dispatch): increment `last_seen.idle_tick_count`, append an idle line to `followup.log` per [`output-templates/watcher-log.md`](output-templates/watcher-log.md), emit a `tick` event with `idle: true`, `reviews_seen: 0`, `dispatched_review_ids: []`, `checks_red: <count or 0>`, `dispatched_ci_fix: false`. Exit. The next tick fires in 1 min via `/loop`.
|
|
71
88
|
|
|
72
89
|
## Output
|
|
73
90
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Finalize a Terminal PR
|
|
2
|
+
|
|
3
|
+
The shared, **pure** termination sequence for a follow-up slot whose PR is `MERGED` or `CLOSED`. Called by [`contract.md`](contract.md) Step 2 (a tick observed the transition) and [`reconcile.md`](reconcile.md) (a sweep found a slot whose polling lapsed before the transition). One slot, run once.
|
|
4
|
+
|
|
5
|
+
This step only finalizes — marks the slot terminal, writes the record, unschedules the cron. It **dispatches nothing**. Post-merge cleanup is a separate, caller-owned concern: the tick ([`contract.md`](contract.md)) hands it off; a reconcile backfill skips it.
|
|
6
|
+
|
|
7
|
+
## Inputs
|
|
8
|
+
|
|
9
|
+
- `<slug>`, `<owner>/<repo>`, `<n>` — the slot's PR.
|
|
10
|
+
- `state` — `MERGED` or `CLOSED`, from a fresh [`../_shared/github-cli-recipes/pr-metadata.md`](../_shared/github-cli-recipes/pr-metadata.md).
|
|
11
|
+
- `mergeCommit` + `mergedAt` when `MERGED`.
|
|
12
|
+
|
|
13
|
+
## Procedure
|
|
14
|
+
|
|
15
|
+
### Step 1 — Mark the slot terminal
|
|
16
|
+
|
|
17
|
+
Rewrite `prs.json[0].state` to `merged` / `closed` ([`state-schemas.md`](state-schemas.md#prsjson)). That state plus the `result.md` written next are the terminal marker — there is no separate flag.
|
|
18
|
+
|
|
19
|
+
### Step 2 — Write `result.md`
|
|
20
|
+
|
|
21
|
+
Once, per [`state-schemas.md`](state-schemas.md#resultmd). Pull `cycles_completed`, `pushed_shas`, and `escalated_review_ids` from `last_seen.json`.
|
|
22
|
+
|
|
23
|
+
### Step 3 — Log and telemetry
|
|
24
|
+
|
|
25
|
+
Append the terminal line per [`output-templates/watcher-log.md`](output-templates/watcher-log.md). Emit one `tick` event with `terminal: true` per [`../_shared/telemetry-events/pr-followup-tick.md`](../_shared/telemetry-events/pr-followup-tick.md).
|
|
26
|
+
|
|
27
|
+
### Step 4 — Unschedule the cron
|
|
28
|
+
|
|
29
|
+
Call `CronList`, find any job whose command ends with `/muggle:muggle-pr-followup <slug> <n>` (exact two-arg match), and `CronDelete` it. No-op when none matches — a manually-run tick, or a cron that already expired. Recurring `/loop` crons auto-expire after 7 days; that lapse is the gap [`reconcile.md`](reconcile.md) exists to catch.
|