@muggleai/works 4.10.0 → 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.
- package/README.md +3 -3
- package/dist/{chunk-RK6XKSZK.js → chunk-Q7WNEMN4.js} +109 -43
- package/dist/{chunk-UVXOHXY2.js → chunk-ZKRHFTIC.js} +832 -89
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/.cursor-plugin/plugin.json +1 -1
- package/dist/plugin/README.md +4 -2
- package/dist/plugin/agents/acceptance-tester.md +24 -10
- package/dist/plugin/commands/m.md +7 -0
- package/dist/plugin/commands/mdo.md +7 -0
- package/dist/plugin/commands/mfeedback.md +7 -0
- package/dist/plugin/commands/mimport.md +7 -0
- package/dist/plugin/commands/mpr.md +7 -0
- package/dist/plugin/commands/mprefs.md +7 -0
- package/dist/plugin/commands/mregen.md +7 -0
- package/dist/plugin/commands/mrelease.md +7 -0
- package/dist/plugin/commands/mrepair.md +7 -0
- package/dist/plugin/commands/mstatus.md +7 -0
- package/dist/plugin/commands/mtest.md +7 -0
- package/dist/plugin/commands/mtestlocal.md +7 -0
- package/dist/plugin/commands/mtestprep.md +7 -0
- package/dist/plugin/commands/mupgrade.md +7 -0
- package/dist/plugin/scripts/ensure-electron-app.sh +35 -8
- package/dist/plugin/skills/_aliases.json +18 -0
- package/dist/plugin/skills/_shared/dev-server-readiness.md +231 -0
- package/dist/plugin/skills/_shared/failure-mode-handling.md +244 -0
- package/dist/plugin/skills/_shared/post-merge-cleanup.md +10 -0
- package/dist/plugin/skills/_shared/rebase-before-e2e.md +15 -0
- package/dist/plugin/skills/_shared/telemetry-emit.md +15 -0
- package/dist/plugin/skills/_shared/use-worktrees.md +53 -0
- package/dist/plugin/skills/do/e2e-acceptance.md +63 -18
- package/dist/plugin/skills/do/impact-analysis.md +45 -5
- package/dist/plugin/skills/do/open-prs.md +13 -4
- package/dist/plugin/skills/do/pr-followup.md +225 -0
- package/dist/plugin/skills/do/pre-flight.md +18 -11
- package/dist/plugin/skills/m/SKILL.md +8 -0
- package/dist/plugin/skills/mdo/SKILL.md +8 -0
- package/dist/plugin/skills/mfeedback/SKILL.md +8 -0
- package/dist/plugin/skills/mimport/SKILL.md +8 -0
- package/dist/plugin/skills/mpr/SKILL.md +8 -0
- package/dist/plugin/skills/mprefs/SKILL.md +8 -0
- package/dist/plugin/skills/mregen/SKILL.md +8 -0
- package/dist/plugin/skills/mrelease/SKILL.md +8 -0
- package/dist/plugin/skills/mrepair/SKILL.md +8 -0
- package/dist/plugin/skills/mstatus/SKILL.md +8 -0
- package/dist/plugin/skills/mtest/SKILL.md +8 -0
- package/dist/plugin/skills/mtestlocal/SKILL.md +8 -0
- package/dist/plugin/skills/mtestprep/SKILL.md +8 -0
- package/dist/plugin/skills/muggle/SKILL.md +9 -6
- package/dist/plugin/skills/muggle-do/SKILL.md +22 -4
- package/dist/plugin/skills/muggle-do-pr-followup/SKILL.md +37 -0
- package/dist/plugin/skills/muggle-do-task/SKILL.md +134 -0
- package/dist/plugin/skills/muggle-feedback/SKILL.md +38 -0
- package/dist/plugin/skills/muggle-feedback/ops/delete.md +49 -0
- package/dist/plugin/skills/muggle-feedback/ops/list.md +65 -0
- package/dist/plugin/skills/muggle-feedback/ops/submit.md +117 -0
- package/dist/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +68 -43
- package/dist/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
- package/dist/plugin/skills/muggle-preferences/SKILL.md +16 -108
- package/dist/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
- package/dist/plugin/skills/muggle-preferences/ops/configure.md +49 -0
- package/dist/plugin/skills/muggle-preferences/ops/list.md +9 -0
- package/dist/plugin/skills/muggle-preferences/ops/reset.md +6 -0
- package/dist/plugin/skills/muggle-preferences/ops/set.md +10 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/README.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +3 -3
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +2 -2
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +1 -2
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +4 -4
- package/dist/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +8 -25
- package/dist/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +4 -4
- package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +4 -4
- package/dist/plugin/skills/muggle-repair/SKILL.md +4 -2
- package/dist/plugin/skills/muggle-status/SKILL.md +8 -5
- package/dist/plugin/skills/muggle-test/SKILL.md +110 -86
- package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +73 -66
- package/dist/plugin/skills/muggle-test-import/SKILL.md +28 -23
- package/dist/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
- package/dist/plugin/skills/muggle-test-regenerate-missing/SKILL.md +34 -18
- package/dist/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
- package/dist/plugin/skills/muggle-upgrade/SKILL.md +4 -2
- package/dist/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
- package/dist/plugin/skills/mupgrade/SKILL.md +8 -0
- package/dist/release-manifest.json +4 -4
- package/dist/{src-GD3YFCCW.js → src-2G7ENRGI.js} +1 -1
- package/package.json +9 -7
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/README.md +4 -2
- package/plugin/agents/acceptance-tester.md +24 -10
- package/plugin/commands/m.md +7 -0
- package/plugin/commands/mdo.md +7 -0
- package/plugin/commands/mfeedback.md +7 -0
- package/plugin/commands/mimport.md +7 -0
- package/plugin/commands/mpr.md +7 -0
- package/plugin/commands/mprefs.md +7 -0
- package/plugin/commands/mregen.md +7 -0
- package/plugin/commands/mrelease.md +7 -0
- package/plugin/commands/mrepair.md +7 -0
- package/plugin/commands/mstatus.md +7 -0
- package/plugin/commands/mtest.md +7 -0
- package/plugin/commands/mtestlocal.md +7 -0
- package/plugin/commands/mtestprep.md +7 -0
- package/plugin/commands/mupgrade.md +7 -0
- package/plugin/scripts/ensure-electron-app.sh +35 -8
- package/plugin/skills/_aliases.json +18 -0
- package/plugin/skills/_shared/dev-server-readiness.md +231 -0
- package/plugin/skills/_shared/failure-mode-handling.md +244 -0
- package/plugin/skills/_shared/post-merge-cleanup.md +10 -0
- package/plugin/skills/_shared/rebase-before-e2e.md +15 -0
- package/plugin/skills/_shared/telemetry-emit.md +15 -0
- package/plugin/skills/_shared/use-worktrees.md +53 -0
- package/plugin/skills/do/e2e-acceptance.md +63 -18
- package/plugin/skills/do/impact-analysis.md +45 -5
- package/plugin/skills/do/open-prs.md +13 -4
- package/plugin/skills/do/pr-followup.md +225 -0
- package/plugin/skills/do/pre-flight.md +18 -11
- package/plugin/skills/m/SKILL.md +8 -0
- package/plugin/skills/mdo/SKILL.md +8 -0
- package/plugin/skills/mfeedback/SKILL.md +8 -0
- package/plugin/skills/mimport/SKILL.md +8 -0
- package/plugin/skills/mpr/SKILL.md +8 -0
- package/plugin/skills/mprefs/SKILL.md +8 -0
- package/plugin/skills/mregen/SKILL.md +8 -0
- package/plugin/skills/mrelease/SKILL.md +8 -0
- package/plugin/skills/mrepair/SKILL.md +8 -0
- package/plugin/skills/mstatus/SKILL.md +8 -0
- package/plugin/skills/mtest/SKILL.md +8 -0
- package/plugin/skills/mtestlocal/SKILL.md +8 -0
- package/plugin/skills/mtestprep/SKILL.md +8 -0
- package/plugin/skills/muggle/SKILL.md +9 -6
- package/plugin/skills/muggle-do/SKILL.md +22 -4
- package/plugin/skills/muggle-do-pr-followup/SKILL.md +37 -0
- package/plugin/skills/muggle-do-task/SKILL.md +134 -0
- package/plugin/skills/muggle-feedback/SKILL.md +38 -0
- package/plugin/skills/muggle-feedback/ops/delete.md +49 -0
- package/plugin/skills/muggle-feedback/ops/list.md +65 -0
- package/plugin/skills/muggle-feedback/ops/submit.md +117 -0
- package/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +68 -43
- package/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
- package/plugin/skills/muggle-preferences/SKILL.md +16 -108
- package/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
- package/plugin/skills/muggle-preferences/ops/configure.md +49 -0
- package/plugin/skills/muggle-preferences/ops/list.md +9 -0
- package/plugin/skills/muggle-preferences/ops/reset.md +6 -0
- package/plugin/skills/muggle-preferences/ops/set.md +10 -0
- package/plugin/skills/muggle-preferences/preference-gates/README.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +3 -3
- package/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +2 -2
- package/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +1 -2
- package/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +4 -4
- package/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +8 -25
- package/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +4 -4
- package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +4 -4
- package/plugin/skills/muggle-repair/SKILL.md +4 -2
- package/plugin/skills/muggle-status/SKILL.md +8 -5
- package/plugin/skills/muggle-test/SKILL.md +110 -86
- package/plugin/skills/muggle-test-feature-local/SKILL.md +73 -66
- package/plugin/skills/muggle-test-import/SKILL.md +28 -23
- package/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
- package/plugin/skills/muggle-test-regenerate-missing/SKILL.md +34 -18
- package/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
- package/plugin/skills/muggle-upgrade/SKILL.md +4 -2
- package/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
- package/plugin/skills/mupgrade/SKILL.md +8 -0
- package/scripts/postinstall.mjs +11 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Worktrees for Dev Work
|
|
2
|
+
|
|
3
|
+
Use this for feature development, local validation, and PR iteration.
|
|
4
|
+
|
|
5
|
+
## Core guidance
|
|
6
|
+
|
|
7
|
+
- **One worktree per branch.** Never switch branches inside a long-lived checkout.
|
|
8
|
+
- **Isolate runtime resources.** Parallel worktrees need unique ports and isolated mutable test state.
|
|
9
|
+
- **Keep worktrees disposable.** Create for focused work, remove after merge.
|
|
10
|
+
|
|
11
|
+
## Start new change work
|
|
12
|
+
|
|
13
|
+
1. Update the base branch (usually `main`).
|
|
14
|
+
2. Create a new worktree and branch:
|
|
15
|
+
```bash
|
|
16
|
+
git worktree add <repo>-worktrees/<slug> -b <branch>
|
|
17
|
+
```
|
|
18
|
+
3. Install dependencies and run setup in that worktree.
|
|
19
|
+
4. Keep all edits and commits for the change in that same worktree.
|
|
20
|
+
|
|
21
|
+
## Test in the worktree
|
|
22
|
+
|
|
23
|
+
- Run lint, typecheck, and unit/integration tests from the worktree.
|
|
24
|
+
- Run your local E2E acceptance flow from that same worktree for user-facing validation.
|
|
25
|
+
- Run the dev server from the same worktree so code, env, and cache all match.
|
|
26
|
+
- In parallel runs, ensure each worktree has a unique port and isolated test data.
|
|
27
|
+
|
|
28
|
+
## E2E + worktree checklist
|
|
29
|
+
|
|
30
|
+
1. Confirm command cwd, checked-out branch, and server source are the same worktree.
|
|
31
|
+
2. Start the app from that worktree and verify readiness first (see [`dev-server-readiness.md`](dev-server-readiness.md)).
|
|
32
|
+
3. Run local E2E acceptance checks in that same session.
|
|
33
|
+
4. Isolate test data across parallel branches (separate users/accounts/orgs or resettable fixtures).
|
|
34
|
+
5. Re-run E2E acceptance checks after meaningful code changes during PR review.
|
|
35
|
+
|
|
36
|
+
## Common failure modes to avoid
|
|
37
|
+
|
|
38
|
+
- **Mixed checkouts:** Test command and server run from different directories.
|
|
39
|
+
- **Port collision:** Multiple branches share a dev-server port.
|
|
40
|
+
- **Shared mutable state:** Parallel runs mutate the same account or fixtures.
|
|
41
|
+
- **Stale server:** Old process still serves previous branch code.
|
|
42
|
+
|
|
43
|
+
## Pull request workflow
|
|
44
|
+
|
|
45
|
+
1. Commit on the branch tied to the worktree.
|
|
46
|
+
2. Push the branch and open the PR.
|
|
47
|
+
3. Keep review fixes in that same worktree.
|
|
48
|
+
4. Re-run relevant checks before each push, including E2E acceptance checks for user-facing changes.
|
|
49
|
+
|
|
50
|
+
## Tear down
|
|
51
|
+
|
|
52
|
+
After merge, remove the worktree.
|
|
53
|
+
See [`post-merge-cleanup.md`](post-merge-cleanup.md).
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
# E2E
|
|
1
|
+
# E2E Acceptance Agent (Stage 6/7)
|
|
2
2
|
|
|
3
|
-
You are
|
|
3
|
+
You are executing E2E acceptance validation for the muggle-do cycle.
|
|
4
|
+
|
|
5
|
+
Stage 6 of `muggle-do`. Runs browser acceptance tests against code changes and records evidence for downstream PR rendering.
|
|
6
|
+
|
|
7
|
+
Standalone subagent (different invocation path, used by `muggle-test` Mode C): [`../../agents/acceptance-tester.md`](../../agents/acceptance-tester.md).
|
|
4
8
|
|
|
5
9
|
## Turn preamble
|
|
6
10
|
|
|
@@ -12,23 +16,29 @@ Start the turn with:
|
|
|
12
16
|
|
|
13
17
|
## Design
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
This stage is **mode-driven by pre-flight**:
|
|
20
|
+
|
|
21
|
+
- `local-e2e` runs the local browser flow (`test-feature-local` approach).
|
|
22
|
+
- `unit-only` or `skip` does not execute browser runs and must emit an explicit non-pass verdict (`SKIPPED` / `UNIT-ONLY` equivalent in downstream reporting).
|
|
23
|
+
- `staging-replay` is not executed in this stage path and should be surfaced as `INCONCLUSIVE` unless the caller has already routed to a dedicated staging runner.
|
|
24
|
+
|
|
25
|
+
For local runs, the tool boundaries are:
|
|
16
26
|
|
|
17
27
|
| Scope | MCP tools |
|
|
18
28
|
| :---- | :-------- |
|
|
19
29
|
| Cloud (projects, cases, scripts, auth) | `muggle-remote-*` |
|
|
20
30
|
| Local (Electron run, publish, results) | `muggle-local-*` |
|
|
21
31
|
|
|
22
|
-
This
|
|
32
|
+
This keeps execution deterministic: local runs do not depend on cloud replay execution availability.
|
|
23
33
|
|
|
24
34
|
## Input
|
|
25
35
|
|
|
26
36
|
You receive everything from `state.md` already — pre-flight resolved it:
|
|
27
37
|
|
|
28
|
-
- `localUrl` — the
|
|
29
|
-
- `projectId` — the chosen Muggle project
|
|
38
|
+
- `localUrl` — the running validation target URL (typically localhost in local mode)
|
|
39
|
+
- `projectId` — the chosen Muggle Test project
|
|
30
40
|
- The validation strategy (`local-e2e`, `staging-replay`, `unit-only`, `skip`)
|
|
31
|
-
- Test-user credential status (existing / new / skip)
|
|
41
|
+
- Test-user credential status (existing / new / skip), when credentials are needed
|
|
32
42
|
- The list of changed repos, files, and a summary of changes
|
|
33
43
|
- The requirements goal
|
|
34
44
|
|
|
@@ -36,23 +46,41 @@ You receive everything from `state.md` already — pre-flight resolved it:
|
|
|
36
46
|
|
|
37
47
|
### Step 0: Consume pre-flight (no user questions)
|
|
38
48
|
|
|
39
|
-
Read `state.md`.
|
|
49
|
+
Read `state.md`. Resolve [`autoE2ETest`](../muggle-preferences/preference-gates/autoE2ETest.md) first — `always` (default, including when unset) runs this stage. `ask` should already have been resolved by pre-flight Q13. Use the resolved validation mode (`local-e2e`, `staging-replay`, `unit-only`, `skip`) to pick execution vs early-exit behavior.
|
|
40
50
|
|
|
41
|
-
|
|
51
|
+
Use `localUrl`, `projectId`, and `worktreePath` from `state.md`. Missing any → pre-flight bug; escalate with the session path and halt; do not ask the user.
|
|
42
52
|
|
|
43
53
|
### Step 0.5: Pre-flight verification probes
|
|
44
54
|
|
|
45
|
-
Before launching
|
|
55
|
+
Before launching the local runner:
|
|
46
56
|
|
|
47
|
-
1.
|
|
48
|
-
2.
|
|
49
|
-
3.
|
|
50
|
-
4. If test credentials were marked `existing`, confirm the Auth0 tenant in the repo's env matches the tenant the secrets were created under (recorded in `state.md`). Tenant mismatch → halt with "existing secrets target tenant X, local dev targets tenant Y — update pre-flight to collect new credentials."
|
|
57
|
+
1. **Dev-server + backend readiness** — per [`../_shared/dev-server-readiness.md`](../_shared/dev-server-readiness.md) (port + compile log + backend health). Halt on any failure.
|
|
58
|
+
2. **Auth** — `muggle-remote-auth-status` must be `authenticated`; else escalate.
|
|
59
|
+
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.
|
|
51
60
|
|
|
52
61
|
### Step 1: Authentication already verified
|
|
53
62
|
|
|
54
63
|
Pre-flight handled auth. If `muggle-remote-auth-status` somehow shows expired here (session clock skew, etc.), re-auth silently via `muggle-remote-auth-login` + `muggle-remote-auth-poll` — but do not ask the user "continue with this account?" again.
|
|
55
64
|
|
|
65
|
+
If validation is `unit-only` or `skip`, emit a `SKIPPED` report with a one-line reason and exit cleanly.
|
|
66
|
+
|
|
67
|
+
If validation is `staging-replay`, emit `INCONCLUSIVE` with reason `staging replay not handled in Stage 6 local runner path` and exit cleanly.
|
|
68
|
+
|
|
69
|
+
### Step 1.5: Placeholder branch detection
|
|
70
|
+
|
|
71
|
+
Read `pathClassification` from the impact-analysis output (emitted by `do/impact-analysis.md`). If it is `none` — i.e. `git diff <default-branch>...HEAD --stat` was empty after rebase — there is no code under test and running test cases would only re-test master. Write a one-paragraph SKIPPED result to the E2E report (or return a SKIPPED verdict to the caller) and exit the stage cleanly. **Do not** synthesize test cases or run anything.
|
|
72
|
+
|
|
73
|
+
### Step 1.7: Route + project classification
|
|
74
|
+
|
|
75
|
+
Consume `pathClassification` from impact-analysis and resolve the dispatch target:
|
|
76
|
+
|
|
77
|
+
- `surface-a` → use the classification-specific route + project mapping defined by impact-analysis output
|
|
78
|
+
- `surface-b` → use the classification-specific route + project mapping defined by impact-analysis output
|
|
79
|
+
- `mixed` → run once per classification mapping (route + project), or surface as INCONCLUSIVE if running both is over the wall-time budget
|
|
80
|
+
- `none` → already handled in Step 1.5
|
|
81
|
+
|
|
82
|
+
The `devServerUrl` and project resolved here override any defaults in `state.md` for the remainder of this stage. Treat classification labels as routing hints provided by impact-analysis; do not hardcode product-specific paths in this stage.
|
|
83
|
+
|
|
56
84
|
### Step 2: Get Test Cases
|
|
57
85
|
|
|
58
86
|
Use `muggle-remote-test-case-list` with the project ID to fetch all test cases.
|
|
@@ -93,7 +121,7 @@ For each relevant test case:
|
|
|
93
121
|
|
|
94
122
|
### Local Execution Timeout (`timeoutMs`)
|
|
95
123
|
|
|
96
|
-
The MCP client often uses a **default wait of 300000 ms (5 minutes)**. **Exploratory script generation** (
|
|
124
|
+
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.
|
|
97
125
|
|
|
98
126
|
- **Always pass `timeoutMs`** — `600000` (10 min) or `900000` (15 min) — unless the test case is known to be simple.
|
|
99
127
|
- 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**.
|
|
@@ -135,7 +163,7 @@ For each published test script:
|
|
|
135
163
|
For each test case:
|
|
136
164
|
- Record pass or fail from the run result
|
|
137
165
|
- If failed, capture the error message, failure step index, and `artifactsDir` for local debugging
|
|
138
|
-
-
|
|
166
|
+
- In `local-e2e` mode, every relevant test case must be executed — generate a new script if none exists (no skips)
|
|
139
167
|
|
|
140
168
|
## Output
|
|
141
169
|
|
|
@@ -160,10 +188,26 @@ For each test case:
|
|
|
160
188
|
- steps: `[{ stepIndex, action, screenshotUrl }, ...]`
|
|
161
189
|
- artifactsDir: `<path>` (for local debugging)
|
|
162
190
|
|
|
191
|
+
**Inconclusive:** (count) — use for runs that couldn't yield a pass/fail signal: no replayable script, environment precondition unmet, infra error, agent stalled on auth/cookie banner before reaching the assertion, missing secrets. The product is **not** implicated — that's `failed`, not `inconclusive`.
|
|
192
|
+
- (test case name):
|
|
193
|
+
- testCaseId: `<id>`
|
|
194
|
+
- runId: `<id>` (synthesize a UUID if no run started)
|
|
195
|
+
- viewUrl: `<url>` (project-level run-results fallback when no specific run URL exists)
|
|
196
|
+
- reason: `<one short sentence>`
|
|
197
|
+
- steps: `[{ stepIndex, action, screenshotUrl }, ...]` (may be empty)
|
|
198
|
+
|
|
163
199
|
**Metadata:**
|
|
164
200
|
- projectId: `<projectId>`
|
|
165
201
|
|
|
166
|
-
**Overall:**
|
|
202
|
+
**Overall:** PASS | FAIL | PARTIAL | INCONCLUSIVE | BLOCKED | SKIPPED — see [`../_shared/failure-mode-handling.md`](../_shared/failure-mode-handling.md) section F for the canonical taxonomy.
|
|
203
|
+
|
|
204
|
+
## Hard constraints
|
|
205
|
+
|
|
206
|
+
- **Do NOT shut down the dev server.** The caller manages dev-server lifecycle.
|
|
207
|
+
- **Do NOT delete or move workspace config/state files** (for example `.muggle-ai/`, `.env.local`, or equivalent runtime config artifacts) in the worktree.
|
|
208
|
+
- **Do NOT call destructive remote MCP tools** — no `*-delete`, `*-revoke`, `*-cancel`, or `*-update` against remote-owned definitions.
|
|
209
|
+
- **One replacement script generation max per stage cycle.**
|
|
210
|
+
- **Honor `wallTimeBudgetSec` from the caller** — on approach, write a PARTIAL report; never silently exceed.
|
|
167
211
|
|
|
168
212
|
## Non-negotiables
|
|
169
213
|
|
|
@@ -171,5 +215,6 @@ For each test case:
|
|
|
171
215
|
- Replay: never hand-build or simplify `actionScript` — only use full response from `muggle-remote-action-script-get`.
|
|
172
216
|
- Always pass `timeoutMs` for execution calls; do not rely on default 5-minute timeout.
|
|
173
217
|
- No hiding failures: surface errors, exit codes, and artifact paths.
|
|
174
|
-
-
|
|
218
|
+
- In `local-e2e` mode, every relevant test case must be executed — generate a new script if none exists (no skips).
|
|
175
219
|
- Always publish after execution to ensure screenshots are cloud-accessible for PR comments.
|
|
220
|
+
- **Never drop a test case from the report because it "couldn't run cleanly."** A test that didn't reach its assertion is `inconclusive`, not absent. Dropping it produces misleading verdicts and pushes downstream PR-comment renderers to hand-write the comment — which is the failure mode this stage exists to prevent.
|
|
@@ -15,22 +15,34 @@ Start the turn with:
|
|
|
15
15
|
You receive:
|
|
16
16
|
- A list of repos with their local filesystem paths
|
|
17
17
|
- The requirements goal and affected repos from the requirements stage
|
|
18
|
+
- Pre-flight state, including `worktreePath` when a worktree was selected (see [`../_shared/use-worktrees.md`](../_shared/use-worktrees.md))
|
|
18
19
|
|
|
19
20
|
## Your Job
|
|
20
21
|
|
|
21
22
|
For each repo path provided:
|
|
22
23
|
|
|
23
|
-
1. **
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
1. **Resolve analysis path with worktree awareness:**
|
|
25
|
+
- If `worktreePath` exists for this repo/session, run all git commands from `worktreePath`.
|
|
26
|
+
- Otherwise run from the repo path.
|
|
27
|
+
- Never mix command cwd across base repo + worktree in one analysis pass.
|
|
28
|
+
2. **Detect worktree context:** Run `git worktree list --porcelain` and determine whether the analysis path is:
|
|
29
|
+
- a linked worktree checkout, or
|
|
30
|
+
- the primary checkout.
|
|
31
|
+
Record this in output as `checkoutType`.
|
|
32
|
+
3. **Check the current branch:** Run `git branch --show-current` in the resolved analysis path. If it returns empty (detached HEAD), report an error for that repo.
|
|
33
|
+
4. **Detect the default branch:** Run `git symbolic-ref refs/remotes/origin/HEAD --short` to find the default branch (e.g., `origin/main`). Strip the `origin/` prefix. If this fails, check if `main` or `master` exist locally via `git rev-parse --verify`.
|
|
34
|
+
5. **Verify it's a feature branch:** The current branch must NOT be the default branch. If it is, report an error.
|
|
35
|
+
6. **List changed files:** Run `git diff --name-only <default-branch>...HEAD` to find files changed on this branch relative to the default branch. If no merge base exists, fall back to `git diff --name-only HEAD`.
|
|
36
|
+
7. **Get the diff:** Run `git diff <default-branch>...HEAD` for the full diff.
|
|
37
|
+
8. **Classify changed paths** to drive downstream test routing — emit `pathClassification` (see "Output state — pathClassification" below).
|
|
28
38
|
|
|
29
39
|
## Output
|
|
30
40
|
|
|
31
41
|
Report per repo:
|
|
32
42
|
|
|
33
43
|
**Repo: (name)**
|
|
44
|
+
- Analysis path: (resolved path used for git commands)
|
|
45
|
+
- Checkout type: `worktree` | `primary`
|
|
34
46
|
- Branch: (current branch name)
|
|
35
47
|
- Default branch: (detected default branch)
|
|
36
48
|
- Changed files: (list)
|
|
@@ -40,3 +52,31 @@ Report per repo:
|
|
|
40
52
|
**Summary:** (which repos have changes, which don't, any errors)
|
|
41
53
|
|
|
42
54
|
If NO repos have any changes, clearly state: "No changes detected in any repo."
|
|
55
|
+
|
|
56
|
+
## Output state — pathClassification
|
|
57
|
+
|
|
58
|
+
Per repo, emit one additional field that the E2E acceptance stage (`do/e2e-acceptance.md` Steps 1.5 and 1.7) consumes to pick routing + project mapping without hardcoding product paths:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
pathClassification: <surface-a | surface-b | mixed | none>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Definitions:
|
|
65
|
+
- **`surface-a`** — all changed files match the repo's configured pattern set A.
|
|
66
|
+
- **`surface-b`** — all changed files match the repo's configured pattern set B.
|
|
67
|
+
- **`mixed`** — at least one file matches pattern set A and at least one file matches pattern set B.
|
|
68
|
+
- **`none`** — empty diff (placeholder branch — see standardized output below).
|
|
69
|
+
|
|
70
|
+
Pattern sets must be treated as repo-configured routing buckets (for example, marketing-vs-app areas), not global hardcoded paths in this stage.
|
|
71
|
+
|
|
72
|
+
### Standardized "no changes" output (placeholder branch)
|
|
73
|
+
|
|
74
|
+
If `git diff <default>...HEAD --stat` is empty for a repo, emit:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
pathClassification: none
|
|
78
|
+
filesChanged: []
|
|
79
|
+
recommendation: SKIPPED — placeholder branch, no code under test
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`do/e2e-acceptance.md` Step 1.5 reads this and exits the stage cleanly with a SKIPPED verdict — do not silently run tests against master.
|
|
@@ -41,6 +41,8 @@ You receive:
|
|
|
41
41
|
|
|
42
42
|
For each repo with changes:
|
|
43
43
|
|
|
44
|
+
0. **Apply the `autoCreatePR` gate** per [`../muggle-preferences/preference-gates/README.md`](../muggle-preferences/preference-gates/README.md) + [`autoCreatePR.md`](../muggle-preferences/preference-gates/autoCreatePR.md). On the skip path, record the reason in `result.md` and move to the next repo.
|
|
45
|
+
|
|
44
46
|
1. **Push the branch** to origin: `git push -u origin <branch-name>` in the repo directory.
|
|
45
47
|
2. **Build the PR title:**
|
|
46
48
|
- If E2E acceptance tests have failures: `[E2E FAILING] <goal>`
|
|
@@ -57,10 +59,7 @@ For each repo with changes:
|
|
|
57
59
|
7. **Post the overflow `comment` only if it is non-null.** In the common case, `comment` is `null` and nothing is posted. Never post speculatively.
|
|
58
60
|
|
|
59
61
|
```bash
|
|
60
|
-
gh pr comment <PR#> --body
|
|
61
|
-
<comment field contents>
|
|
62
|
-
EOF
|
|
63
|
-
)"
|
|
62
|
+
jq -r '.comment' /tmp/muggle-pr-section.json | gh pr comment <PR#> --body-file -
|
|
64
63
|
```
|
|
65
64
|
|
|
66
65
|
## Rendering the E2E acceptance block via the shared skill
|
|
@@ -104,3 +103,13 @@ Back in this stage:
|
|
|
104
103
|
- (repo name): comment posted to PR #(number)
|
|
105
104
|
|
|
106
105
|
**Errors:** (any repos where PR creation or comment posting failed, with the error message)
|
|
106
|
+
|
|
107
|
+
## Post-merge cleanup (gated by `autoCleanup`)
|
|
108
|
+
|
|
109
|
+
Cleanup fires in a follow-up turn after merge — never from this stage. See [`../_shared/post-merge-cleanup.md`](../_shared/post-merge-cleanup.md).
|
|
110
|
+
|
|
111
|
+
After printing PR URLs, append one short reminder tied to the gate's current value:
|
|
112
|
+
|
|
113
|
+
- `always` → `Once merged, I'll run the cleanup sequence automatically.`
|
|
114
|
+
- `never` → omit.
|
|
115
|
+
- `ask` / absent → `Once merged, I'll check with you about cleanup.`
|
|
@@ -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.**
|
|
30
|
-
4. **Running backend.**
|
|
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 `
|
|
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.
|