@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.
Files changed (137) hide show
  1. package/README.md +3 -3
  2. package/dist/plugin/.claude-plugin/plugin.json +1 -1
  3. package/dist/plugin/.cursor-plugin/plugin.json +1 -1
  4. package/dist/plugin/README.md +1 -1
  5. package/dist/plugin/agents/acceptance-tester.md +2 -0
  6. package/dist/plugin/commands/mbt.md +7 -0
  7. package/dist/plugin/commands/mdo.md +3 -3
  8. package/dist/plugin/commands/mprfollowup.md +7 -0
  9. package/dist/plugin/skills/CLAUDE.md +15 -0
  10. package/dist/plugin/skills/_aliases.json +2 -1
  11. package/dist/plugin/skills/_shared/ci-check-to-command.md +10 -0
  12. package/dist/plugin/skills/_shared/dev-loop/action-script.md +3 -0
  13. package/dist/plugin/skills/_shared/dev-loop/failures.md +14 -0
  14. package/dist/plugin/skills/_shared/dev-loop/fresh-session.md +10 -0
  15. package/dist/plugin/skills/_shared/dev-loop/publish.md +13 -0
  16. package/dist/plugin/skills/_shared/dev-loop/run.md +34 -0
  17. package/dist/plugin/skills/_shared/dev-loop/timeouts.md +6 -0
  18. package/dist/plugin/skills/_shared/failure-mode-handling.md +2 -2
  19. package/dist/plugin/skills/_shared/github-cli-recipes/pr-checks.md +22 -0
  20. package/dist/plugin/skills/_shared/github-cli-recipes.md +1 -0
  21. package/dist/plugin/skills/_shared/post-merge-cleanup.md +1 -1
  22. package/dist/plugin/skills/_shared/pr-branch-worktree.md +1 -1
  23. package/dist/plugin/skills/_shared/rebase-before-e2e.md +7 -1
  24. package/dist/plugin/skills/_shared/resolve-e2e-validation-context.md +1 -1
  25. package/dist/plugin/skills/_shared/resolve-rebase-conflicts.md +60 -0
  26. package/dist/plugin/skills/_shared/telemetry-events/muggle-do-cycle.md +8 -1
  27. package/dist/plugin/skills/_shared/telemetry-events/muggle-do-escalation.md +2 -1
  28. package/dist/plugin/skills/_shared/telemetry-events/pr-followup-tick.md +4 -0
  29. package/dist/plugin/skills/_shared/use-worktrees.md +2 -1
  30. package/dist/plugin/skills/do/address-reviews.md +7 -1
  31. package/dist/plugin/skills/do/build.md +2 -1
  32. package/dist/plugin/skills/do/cleanup.md +14 -0
  33. package/dist/plugin/skills/do/e2e-acceptance.md +5 -66
  34. package/dist/plugin/skills/do/fix-ci.md +60 -0
  35. package/dist/plugin/skills/do/input-routing.md +12 -0
  36. package/dist/plugin/skills/do/open-prs/forward.md +3 -3
  37. package/dist/plugin/skills/do/open-prs/update.md +1 -1
  38. package/dist/plugin/skills/do/pre-flight.md +3 -3
  39. package/dist/plugin/skills/mbt/SKILL.md +8 -0
  40. package/dist/plugin/skills/mdo/SKILL.md +3 -3
  41. package/dist/plugin/skills/mprfollowup/SKILL.md +8 -0
  42. package/dist/plugin/skills/muggle/SKILL.md +1 -0
  43. package/{plugin/skills/muggle-do-task → dist/plugin/skills/muggle-browser-task}/SKILL.md +1 -1
  44. package/dist/plugin/skills/muggle-do/SKILL.md +29 -10
  45. package/dist/plugin/skills/muggle-feedback/SKILL.md +1 -1
  46. package/dist/plugin/skills/muggle-pr-followup/CLAUDE.md +4 -5
  47. package/dist/plugin/skills/muggle-pr-followup/SKILL.md +5 -3
  48. package/dist/plugin/skills/muggle-pr-followup/auto-track.md +5 -1
  49. package/dist/plugin/skills/muggle-pr-followup/bootstrap.md +5 -3
  50. package/dist/plugin/skills/muggle-pr-followup/contract.md +34 -17
  51. package/dist/plugin/skills/muggle-pr-followup/finalize.md +29 -0
  52. package/dist/plugin/skills/muggle-pr-followup/reconcile.md +33 -0
  53. package/dist/plugin/skills/muggle-pr-followup/state-schemas.md +10 -2
  54. package/dist/plugin/skills/muggle-preferences/ops/configure.md +2 -1
  55. package/dist/plugin/skills/muggle-preferences/preference-gates/autoResolveConflicts.md +11 -0
  56. package/dist/plugin/skills/muggle-preferences/preference-gates/autoWatchPR.md +13 -0
  57. package/dist/plugin/skills/muggle-preferences/preference-gates/reusePreparePlan.md +11 -0
  58. package/dist/plugin/skills/muggle-status/SKILL.md +1 -1
  59. package/dist/plugin/skills/muggle-test/SKILL.md +30 -48
  60. package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +20 -44
  61. package/dist/plugin/skills/muggle-test-prepare/SKILL.md +5 -1
  62. package/dist/plugin/skills/muggle-test-prepare/steps/check-running.md +7 -5
  63. package/dist/plugin/skills/muggle-test-prepare/steps/identify-services.md +2 -0
  64. package/dist/plugin/skills/muggle-test-prepare/steps/readiness-report.md +30 -0
  65. package/dist/plugin/skills/muggle-test-prepare/steps/reuse-plan.md +44 -0
  66. package/dist/release-manifest.json +4 -4
  67. package/package.json +7 -6
  68. package/plugin/.claude-plugin/plugin.json +1 -1
  69. package/plugin/.cursor-plugin/plugin.json +1 -1
  70. package/plugin/README.md +1 -1
  71. package/plugin/agents/acceptance-tester.md +2 -0
  72. package/plugin/commands/mbt.md +7 -0
  73. package/plugin/commands/mdo.md +3 -3
  74. package/plugin/commands/mprfollowup.md +7 -0
  75. package/plugin/skills/CLAUDE.md +15 -0
  76. package/plugin/skills/_aliases.json +2 -1
  77. package/plugin/skills/_shared/ci-check-to-command.md +10 -0
  78. package/plugin/skills/_shared/dev-loop/action-script.md +3 -0
  79. package/plugin/skills/_shared/dev-loop/failures.md +14 -0
  80. package/plugin/skills/_shared/dev-loop/fresh-session.md +10 -0
  81. package/plugin/skills/_shared/dev-loop/publish.md +13 -0
  82. package/plugin/skills/_shared/dev-loop/run.md +34 -0
  83. package/plugin/skills/_shared/dev-loop/timeouts.md +6 -0
  84. package/plugin/skills/_shared/failure-mode-handling.md +2 -2
  85. package/plugin/skills/_shared/github-cli-recipes/pr-checks.md +22 -0
  86. package/plugin/skills/_shared/github-cli-recipes.md +1 -0
  87. package/plugin/skills/_shared/post-merge-cleanup.md +1 -1
  88. package/plugin/skills/_shared/pr-branch-worktree.md +1 -1
  89. package/plugin/skills/_shared/rebase-before-e2e.md +7 -1
  90. package/plugin/skills/_shared/resolve-e2e-validation-context.md +1 -1
  91. package/plugin/skills/_shared/resolve-rebase-conflicts.md +60 -0
  92. package/plugin/skills/_shared/telemetry-events/muggle-do-cycle.md +8 -1
  93. package/plugin/skills/_shared/telemetry-events/muggle-do-escalation.md +2 -1
  94. package/plugin/skills/_shared/telemetry-events/pr-followup-tick.md +4 -0
  95. package/plugin/skills/_shared/use-worktrees.md +2 -1
  96. package/plugin/skills/do/address-reviews.md +7 -1
  97. package/plugin/skills/do/build.md +2 -1
  98. package/plugin/skills/do/cleanup.md +14 -0
  99. package/plugin/skills/do/e2e-acceptance.md +5 -66
  100. package/plugin/skills/do/fix-ci.md +60 -0
  101. package/plugin/skills/do/input-routing.md +12 -0
  102. package/plugin/skills/do/open-prs/forward.md +3 -3
  103. package/plugin/skills/do/open-prs/update.md +1 -1
  104. package/plugin/skills/do/pre-flight.md +3 -3
  105. package/plugin/skills/mbt/SKILL.md +8 -0
  106. package/plugin/skills/mdo/SKILL.md +3 -3
  107. package/plugin/skills/mprfollowup/SKILL.md +8 -0
  108. package/plugin/skills/muggle/SKILL.md +1 -0
  109. package/{dist/plugin/skills/muggle-do-task → plugin/skills/muggle-browser-task}/SKILL.md +1 -1
  110. package/plugin/skills/muggle-do/SKILL.md +29 -10
  111. package/plugin/skills/muggle-feedback/SKILL.md +1 -1
  112. package/plugin/skills/muggle-pr-followup/CLAUDE.md +4 -5
  113. package/plugin/skills/muggle-pr-followup/SKILL.md +5 -3
  114. package/plugin/skills/muggle-pr-followup/auto-track.md +5 -1
  115. package/plugin/skills/muggle-pr-followup/bootstrap.md +5 -3
  116. package/plugin/skills/muggle-pr-followup/contract.md +34 -17
  117. package/plugin/skills/muggle-pr-followup/finalize.md +29 -0
  118. package/plugin/skills/muggle-pr-followup/reconcile.md +33 -0
  119. package/plugin/skills/muggle-pr-followup/state-schemas.md +10 -2
  120. package/plugin/skills/muggle-preferences/ops/configure.md +2 -1
  121. package/plugin/skills/muggle-preferences/preference-gates/autoResolveConflicts.md +11 -0
  122. package/plugin/skills/muggle-preferences/preference-gates/autoWatchPR.md +13 -0
  123. package/plugin/skills/muggle-preferences/preference-gates/reusePreparePlan.md +11 -0
  124. package/plugin/skills/muggle-status/SKILL.md +1 -1
  125. package/plugin/skills/muggle-test/SKILL.md +30 -48
  126. package/plugin/skills/muggle-test-feature-local/SKILL.md +20 -44
  127. package/plugin/skills/muggle-test-prepare/SKILL.md +5 -1
  128. package/plugin/skills/muggle-test-prepare/steps/check-running.md +7 -5
  129. package/plugin/skills/muggle-test-prepare/steps/identify-services.md +2 -0
  130. package/plugin/skills/muggle-test-prepare/steps/readiness-report.md +30 -0
  131. package/plugin/skills/muggle-test-prepare/steps/reuse-plan.md +44 -0
  132. package/dist/plugin/commands/mrelease.md +0 -7
  133. package/dist/plugin/skills/mrelease/SKILL.md +0 -8
  134. package/dist/plugin/skills/muggle-works-npm-release/SKILL.md +0 -200
  135. package/plugin/commands/mrelease.md +0 -7
  136. package/plugin/skills/mrelease/SKILL.md +0 -8
  137. package/plugin/skills/muggle-works-npm-release/SKILL.md +0 -200
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "muggle",
3
3
  "description": "Run real-browser end-to-end (E2E) acceptance tests on your web app from any AI coding agent. Generate test scripts from plain English, replay them on localhost, capture screenshots, and validate user flows like signup, checkout, and dashboards. Works across Claude Code, Cursor, Codex, and Windsurf.",
4
- "version": "4.13.1",
4
+ "version": "4.15.0",
5
5
  "author": {
6
6
  "name": "Muggle AI",
7
7
  "email": "support@muggle-ai.com"
@@ -2,7 +2,7 @@
2
2
  "name": "muggle",
3
3
  "displayName": "Muggle AI",
4
4
  "description": "Ship quality products with AI-powered end-to-end (E2E) acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
5
- "version": "4.13.1",
5
+ "version": "4.15.0",
6
6
  "author": {
7
7
  "name": "Muggle AI",
8
8
  "email": "support@muggle-ai.com"
package/plugin/README.md CHANGED
@@ -33,7 +33,7 @@ Type `muggle` to discover the full command family.
33
33
  | `/muggle:muggle-repair` | Diagnose and fix broken installation automatically. |
34
34
  | `/muggle:muggle-upgrade` | Update Electron browser test runner and MCP server to latest version. |
35
35
 
36
- Each skill above also ships a short alias to save typing — `m` (router), `mtest`, `mdo`, `mpr`, `mprefs`, `mstatus`, `mrepair`, `mupgrade`, `mfeedback`, `mimport`, `mtestlocal`, `mtestprep`, `mregen`, `mrelease`. Type `/m` (Claude Code) or `m` (Cursor) to open the menu, or jump straight to one (e.g. `/mtest`).
36
+ Each skill above also ships a short alias to save typing — `m` (router), `mtest`, `mdo`, `mpr`, `mprefs`, `mstatus`, `mrepair`, `mupgrade`, `mfeedback`, `mimport`, `mtestlocal`, `mtestprep`, `mregen`. Type `/m` (Claude Code) or `m` (Cursor) to open the menu, or jump straight to one (e.g. `/mtest`).
37
37
 
38
38
  ## MCP Tools
39
39
 
@@ -22,6 +22,8 @@ You operate through skills — never call raw MCP tools directly.
22
22
 
23
23
  Select the skill based on what the orchestrator asks you to do. If the task doesn't clearly map to one skill, ask for clarification.
24
24
 
25
+ The run loop these skills execute (replay/regen, timeouts, publish, screenshots) lives in [`../skills/_shared/dev-loop/run.md`](../skills/_shared/dev-loop/run.md) — you reach it through `muggle-test`, never by calling MCP tools yourself.
26
+
25
27
  ## Input Contract
26
28
 
27
29
  The orchestrator provides a dispatch prompt with:
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: Run a browser automation task on a website in natural language (alias for /muggle-browser-task)
3
+ argument-hint: [task description and target site]
4
+ allowed-tools: [Skill]
5
+ ---
6
+
7
+ Invoke the `muggle-browser-task` skill via the Skill tool. Forward `$ARGUMENTS` as the skill's `args`.
@@ -1,7 +1,7 @@
1
1
  ---
2
- description: Run a browser automation task on a website in natural language (alias for /muggle-do-task)
3
- argument-hint: [task description and target site]
2
+ description: Muggle AI autonomous workflow entry point (alias for /muggle-do)
3
+ argument-hint: [what to build, or a directive]
4
4
  allowed-tools: [Skill]
5
5
  ---
6
6
 
7
- Invoke the `muggle-do-task` skill via the Skill tool. Forward `$ARGUMENTS` as the skill's `args`.
7
+ Invoke the `muggle-do` skill via the Skill tool. Forward `$ARGUMENTS` as the skill's `args`.
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: Watch a PR for review follow-ups (alias for /muggle-pr-followup)
3
+ argument-hint: [PR url | slug pr-number | empty to auto-track]
4
+ allowed-tools: [Skill]
5
+ ---
6
+
7
+ Invoke the `muggle-pr-followup` skill via the Skill tool. Forward `$ARGUMENTS` as the skill's `args`.
@@ -0,0 +1,15 @@
1
+ # Skill authoring conventions
2
+
3
+ Rules for every skill under `plugin/skills/`. Read before adding or editing one.
4
+
5
+ ## One-way dependencies — no reverse references
6
+
7
+ Skill cross-references form a one-way graph. If any file in skill **A** references skill **B** — a markdown link to B's files, or a documented dependency on B's internals — then **no file in B may reference A back**. Reference *downward*, toward the more general / lower-level skill you depend on; pass anything the other direction needs as input, not as a link.
8
+
9
+ A reverse reference (A → B and B → A) couples the depended-on skill to its caller, creates a cycle no one can reason about in isolation, and makes every edit ripple both ways. The lower-level skill must stay reusable by callers it has never heard of.
10
+
11
+ **Runtime dispatch is not a doc reference.** A dumb-pipe skill may *fire* another skill's slash command at runtime (hand off and forget) — that is an action, not a dependency. What the rule forbids is a procedure file **linking to** or **encoding the internals of** the skill it hands off to.
12
+
13
+ **Worked example.** `muggle-pr-followup` (the dumb-pipe watcher) is lower-level than `muggle-do` (the executor that orchestrates it). `muggle-do` references `muggle-pr-followup`; `muggle-pr-followup`'s files must not link back to `muggle-do`. A watcher tick still dispatches `/muggle-do …` at runtime — allowed — but no watcher file links a `do/` file or restates its steps, and shared primitives like `muggle-pr-followup/finalize.md` stay dispatch-free so any caller can reuse them.
14
+
15
+ When you feel the urge to link "up" to a caller, that is the smell — restructure so the caller passes what is needed in.
@@ -3,6 +3,7 @@
3
3
  "m",
4
4
  "mtest",
5
5
  "mdo",
6
+ "mbt",
6
7
  "mpr",
7
8
  "mprefs",
8
9
  "mstatus",
@@ -13,6 +14,6 @@
13
14
  "mtestlocal",
14
15
  "mtestprep",
15
16
  "mregen",
16
- "mrelease"
17
+ "mprfollowup"
17
18
  ]
18
19
  }
@@ -0,0 +1,10 @@
1
+ # CI check → local fix command
2
+
3
+ Map a red CI check to the local command that reproduces and fixes it. Repo-agnostic — read the repo's `package.json` scripts; never hardcode script names.
4
+
5
+ | Failing check | Local action |
6
+ | :------------ | :----------- |
7
+ | lint / format | Run the repo's lint `--fix` / formatter; restage. |
8
+ | typecheck | Run the typecheck script; read the errors; edit the types. |
9
+ | unit / test | Run the suite; read the failures; fix the code or the test. |
10
+ | out of scope — E2E-in-CI, build/deploy infra, flaky / non-deterministic, or unknown | Do **not** attempt; record for escalation. |
@@ -0,0 +1,3 @@
1
+ # Dev Loop — Action Script
2
+
3
+ On the replay path use the `muggle-remote-action-script-get` response **as-is** — never edit, shorten, or rebuild `actionScript`; replay needs the full `label` paths for element lookup. For batches, fan the script fetches out in parallel before the sequential execute loop.
@@ -0,0 +1,14 @@
1
+ # Dev Loop — Reading the Result
2
+
3
+ For each `runId`, call `muggle-local-run-result-get` and read **structured fields**, never `execute`'s stdout tail (a truncated display excerpt). Order: `Status` → `Error` → `Artifacts`. Retain per test case: `testCaseId`, `testScriptId` (if any), `runId`, `status`, `artifactsDir`.
4
+
5
+ ## Artifacts
6
+
7
+ The `Artifacts` section is present after any completed run; it names `artifactsDir` and lists files. On pass, `results.md` is the step-by-step verdict (read it before summarizing). On failure, `stdout.log` + `stderr.log` are always present; `action-script.json` appears when generation reached step-emission (typical for `goal_not_achievable`); `results.md` and per-step screenshots are absent on the failure path — don't hunt for them.
8
+
9
+ ## Common failures
10
+
11
+ - `Electron execution timed out after 300000ms` → orchestration wait too short; see [`timeouts.md`](timeouts.md).
12
+ - **Exit code 26** (with "LLM failed to generate / replay action script") is usually a completed exploration whose outcome was **goal not achievable** (`goal_not_achievable`, summary with `halt`) — e.g. asserting "view a completed run" on an account that has none. Read the summary; don't assume a crash. Fix the precondition: pick a project/account that already has the needed state, or narrow the goal so generation isn't forced to create resources from scratch.
13
+
14
+ Then route via [`../failure-mode-handling.md`](../failure-mode-handling.md).
@@ -0,0 +1,10 @@
1
+ # Dev Loop — Fresh Session
2
+
3
+ Pass `freshSession: true` for a test case that needs clean browser state (no prior cookies, localStorage, or login):
4
+
5
+ - Registration / sign-up.
6
+ - Login / authentication when the flow itself is under test (not a test that merely uses login as a prerequisite).
7
+ - Cookie-consent / GDPR first-visit banners.
8
+ - Onboarding / first-run experiences.
9
+
10
+ Otherwise omit it (defaults `false`, preserving session state). Evaluate per test case — in a batch some need it and some don't.
@@ -0,0 +1,13 @@
1
+ # Dev Loop — Publish & Screenshots
2
+
3
+ ## Publish
4
+
5
+ After every completed run — pass or fail — publish: failed runs still need cloud-hosted screenshots and per-step actions for the walkthrough, and the upload `status` tells the backend whether to promote the action script as the canonical replay script (pass → promote; fail → record only).
6
+
7
+ `muggle-local-publish-test-script` with `runId` and `cloudTestCaseId`. Retain `testScriptId`, `actionScriptId`, `viewUrl`. Batch publishes in parallel.
8
+
9
+ If publish rejects with `has no generated actionScript steps to publish` (a true zero-step run), fall back to `muggle-remote-local-run-upload` with whatever exists (`summaryStep`, `errorMessage`, empty `actionScript`); capture `actionScriptId` and `viewUrl` the same way.
10
+
11
+ ## Screenshots
12
+
13
+ Per published script, `muggle-remote-test-script-get` with the `testScriptId` from publish → per step `operation.screenshotUrl` and `operation.action`. Retain `{ stepIndex, action, screenshotUrl }`. Batch in parallel. These feed the `E2eReport` consumed by [`../../muggle-pr-visual-walkthrough/SKILL.md`](../../muggle-pr-visual-walkthrough/SKILL.md) — the dev loop does not post to the PR.
@@ -0,0 +1,34 @@
1
+ # Dev Loop — Run a Test
2
+
3
+ > The local dev loop: run one test case in the browser (replay an existing script, or regenerate from the case), then record the result. Source of truth for the run mechanics; the sibling files in this folder own each invariant. Used by `muggle-test`, `muggle-test-feature-local`, `muggle-do` Stage 6 ([`../../do/e2e-acceptance.md`](../../do/e2e-acceptance.md)), and the `acceptance-tester` agent.
4
+
5
+ Not owned here — the caller resolves and passes in: which test cases to run, replay-vs-regen classification and failure routing ([`../failure-mode-handling.md`](../failure-mode-handling.md)), dev-server readiness ([`../dev-server-readiness.md`](../dev-server-readiness.md)), validation context ([`../resolve-e2e-validation-context.md`](../resolve-e2e-validation-context.md)), and PR posting ([`../../muggle-pr-visual-walkthrough/SKILL.md`](../../muggle-pr-visual-walkthrough/SKILL.md)).
6
+
7
+ ## Inputs
8
+
9
+ The caller resolves these before the loop and supplies them per test case:
10
+
11
+ - `mode` — `replay` or `regen`, already chosen (by the user, or by [`../failure-mode-handling.md`](../failure-mode-handling.md) for change-driven callers).
12
+ - `localUrl` — local execution target. Local-only; never changes the cloud project or test definitions.
13
+ - `cwd` — absolute path of the active working tree (PR-branch worktree if one exists, else repo root). Drives the cross-worktree single-flight lock so concurrent runs serialize.
14
+ - `testCase` / `cloudTestCaseId` — the cloud test case and its id.
15
+ - `showUi` — from the caller's `showElectronBrowser` resolution: omit for visible, `false` for headless.
16
+
17
+ The tool boundary is fixed: cloud reads (`muggle-remote-*`) resolve definitions and scripts; local tools (`muggle-local-*`) run the browser, fetch results, and publish.
18
+
19
+ ## Sequence
20
+
21
+ One local browser exists, so **execution is sequential** — one test case at a time, in the caller's order. The pre/post fetches are independent across test cases and should be issued in parallel batches around the sequential execute calls.
22
+
23
+ Per test case, branch on `mode`:
24
+
25
+ **Replay**
26
+ 1. `muggle-remote-test-script-get` (latest replayable script) → note `actionScriptId`.
27
+ 2. `muggle-remote-action-script-get` with that id → full `actionScript` (see [`action-script.md`](action-script.md)).
28
+ 3. `muggle-local-execute-replay` with `testScript`, `actionScript`, `localUrl`, `cwd`, `showUi`, `freshSession` (see [`fresh-session.md`](fresh-session.md)), `timeoutMs` (see [`timeouts.md`](timeouts.md)).
29
+
30
+ **Regen**
31
+ 1. `muggle-remote-test-case-get` → full test case object.
32
+ 2. `muggle-local-execute-test-generation` with `testCase`, `localUrl`, `cwd`, `showUi`, `freshSession`, `timeoutMs`.
33
+
34
+ Store the returned `runId`, tagged with its `mode`. If a run fails, log it and continue the batch — never abort. Read the result per [`failures.md`](failures.md), then [`publish.md`](publish.md).
@@ -0,0 +1,6 @@
1
+ # Dev Loop — Timeouts
2
+
3
+ The MCP client default wait is **300000 ms (5 min)**. Exploratory generation (identity login, multi-step flows, many LLM iterations) routinely runs longer while the browser is still healthy.
4
+
5
+ - **Always pass `timeoutMs`** — `600000` (10 min) or `900000` (15 min) — unless the test case is known simple or the user wants a short cap.
6
+ - `Electron execution timed out after 300000ms` while logs show the run still progressing (steps, screenshots, LLM calls) is an **orchestration timeout, not a browser defect** — increase `timeoutMs` and retry.
@@ -1,6 +1,6 @@
1
1
  # Failure-Mode Handling — Shared Reference
2
2
 
3
- > Source of truth for **(a)** the pre-execution replay-vs-regen choice and **(b)** the post-execution failure router used by `muggle-test`, `muggle-test-feature-local`, `muggle-do-task`, and `muggle-test-regenerate-missing`. Skills MUST link here rather than restate the rules.
3
+ > Source of truth for **(a)** the pre-execution replay-vs-regen choice and **(b)** the post-execution failure router used by `muggle-test`, `muggle-test-feature-local`, `muggle-browser-task`, and `muggle-test-regenerate-missing`. Skills MUST link here rather than restate the rules.
4
4
 
5
5
  ## The contract
6
6
 
@@ -55,7 +55,7 @@ Subagents return the verdict as part of a structured block, not free-form prose.
55
55
 
56
56
  ## A. Pre-execution: replay vs regen (used by `muggle-test`)
57
57
 
58
- Run during change analysis, **per impacted test case**. Picks the initial execution mode before Step 7. Other skills with a single user-picked target (`muggle-test-feature-local`, `muggle-do-task`) skip this section — the user already chose.
58
+ Run during change analysis, **per impacted test case**. Picks the initial execution mode before Step 7. Other skills with a single user-picked target (`muggle-test-feature-local`, `muggle-browser-task`) skip this section — the user already chose.
59
59
 
60
60
  ### Inputs
61
61
 
@@ -0,0 +1,22 @@
1
+ # PR check-run rollup
2
+
3
+ Fetch the CI check state for a PR's head — what the watcher polls to detect red CI.
4
+
5
+ ```bash
6
+ gh pr checks <pr-number> --repo <owner>/<repo> --json name,state,bucket,link
7
+ ```
8
+
9
+ Each row:
10
+
11
+ - `name` — the check's name (e.g. `lint`, `typecheck`, `unit`, `build`).
12
+ - `state` — `SUCCESS` / `FAILURE` / `PENDING` / `SKIPPED` / `CANCELLED` / `NEUTRAL` (gh folds status + conclusion into one field).
13
+ - `bucket` — `pass` / `fail` / `pending` / `skipping` / `cancel`; the coarse rollup — filter on this.
14
+ - `link` — the check's details URL, for pulling logs in the fix-ci stage.
15
+
16
+ Classify for the watcher:
17
+
18
+ - **pending** — any row with `bucket == "pending"`. Checks haven't settled → idle.
19
+ - **red** — any row with `bucket == "fail"` (`state` FAILURE / CANCELLED / TIMED_OUT). Candidate for fix-ci.
20
+ - **green** — every row `pass` / `skipping`, or no rows at all.
21
+
22
+ The fix-ci dispatch carries the `name`s of the red rows. `gh pr checks` exits non-zero when any check fails — capture output regardless of exit code.
@@ -10,6 +10,7 @@ Skills assume a working `gh auth status`. Auth errors surface verbatim from `gh`
10
10
  | :----- | :------- |
11
11
  | [`pr-metadata`](github-cli-recipes/pr-metadata.md) | Snapshot PR state, head SHA, branch — watcher + bootstrap. |
12
12
  | [`submitted-reviews`](github-cli-recipes/submitted-reviews.md) | Fetch reviews past a cursor — watcher's poll. |
13
+ | [`pr-checks`](github-cli-recipes/pr-checks.md) | Check-run rollup for the head SHA — watcher's CI poll. |
13
14
  | [`line-comments-for-review`](github-cli-recipes/line-comments-for-review.md) | Pull a review's line comments — `/muggle-do` per-comment routing. |
14
15
  | [`unresolved-threads`](github-cli-recipes/unresolved-threads.md) | GraphQL fetch of unresolved comment threads — resolve-reminder. |
15
16
  | [`reply-line-comment`](github-cli-recipes/reply-line-comment.md) | POST a threaded reply on a line comment. |
@@ -5,6 +5,6 @@ Gated by [`autoCleanup`](../muggle-preferences/preference-gates/autoCleanup.md).
5
5
  On `always`, the four steps below run as one pre-authorized sequence (no per-step prompts). Stop on the first failure; do not force.
6
6
 
7
7
  1. `git worktree remove {worktreePath}` — only if a worktree was used.
8
- 2. `git branch -d {branch}` then `git push origin --delete {branch}`.
8
+ 2. `git branch -d {branch}` — **skip when no worktree was used**: the branch is the user's current live checkout (a bootstrap/auto-track watcher), and the checked-out branch must never be deleted. Then `git push origin --delete {branch}`.
9
9
  3. Clear `.muggle-ai/` session folders for this branch's runs and stale `/tmp/muggle-prepare-*.log` files. Cloud results stay.
10
10
  4. Invoke `commit-commands:clean_gone` via the `Skill` tool.
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## When this applies
6
6
 
7
- A skill receives a GitHub PR URL of the form `github.com/<org>/<repo>/pull/<n>` and needs the PR's branch checked out to test against it locally.
7
+ A skill receives a GitHub PR URL of the form `github.com/<org>/<repo>/pull/<n>` and needs the PR's branch checked out to test against it locally. For worktree principles (one-per-branch, port/data isolation, teardown) see [`use-worktrees.md`](use-worktrees.md) — this file owns only the materialize-an-existing-PR-branch operation.
8
8
 
9
9
  ## Steps
10
10
 
@@ -10,6 +10,12 @@ default=$(git symbolic-ref refs/remotes/origin/HEAD --short | sed 's|origin/||')
10
10
  behind=$(git rev-list --count "HEAD..origin/${default}")
11
11
  ```
12
12
 
13
- Pass `{behind}` and `{default}` to the picker prompts. On `always`, run `git rebase origin/${default}`; stop and report on conflicts — never auto-resolve.
13
+ Pass `{behind}` and `{default}` to the picker prompts. On `always`:
14
+
15
+ 1. Capture the rollback point: `pre_rebase_sha=$(git rev-parse HEAD)`.
16
+ 2. `git rebase origin/${default}`.
17
+ 3. On conflict, branch by [`autoResolveConflicts`](../muggle-preferences/preference-gates/autoResolveConflicts.md):
18
+ - `never` (default) → `git rebase --abort`; stop and report, naming the conflicted files. Never auto-resolve.
19
+ - `always` → hand off to [`resolve-rebase-conflicts.md`](resolve-rebase-conflicts.md) with `pre_rebase_sha`; it resolves, runs the verify-or-rollback gate, and either proceeds or restores `pre_rebase_sha` and escalates.
14
20
 
15
21
  Stale branches produce false failures and false greens — that's why this gate exists.
@@ -8,7 +8,7 @@ The sections below are the steps in order: reuse an existing context if one is o
8
8
 
9
9
  ## Reuse an existing context
10
10
 
11
- If a `## Pre-flight answers` block already exists for this working tree — the current session slot, or the most recent sibling session under `.muggle-do/sessions/*` — fire the [`autoReuseValidationContext`](../muggle-preferences/preference-gates/autoReuseValidationContext.md) gate before gathering anything:
11
+ If a `## Pre-flight answers` block already exists for this working tree — the current session slot, or the most recent sibling session under `~/.muggle-ai/muggle-do/sessions/*` — fire the [`autoReuseValidationContext`](../muggle-preferences/preference-gates/autoReuseValidationContext.md) gate before gathering anything:
12
12
 
13
13
  - `always` → copy the existing block into this session; skip the questionnaire.
14
14
  - `never` → ignore it; run the full gather below.
@@ -0,0 +1,60 @@
1
+ # Auto-Resolve Rebase Conflicts
2
+
3
+ The autonomous conflict-resolution body, run when a rebase onto `origin/{default}` reports conflicts **and** [`autoResolveConflicts`](../muggle-preferences/preference-gates/autoResolveConflicts.md) is `always`. Under the default `never` the caller aborts and escalates instead, and this file never runs. The caller hands off the inputs below; this file names no caller — the dependency runs one way.
4
+
5
+ Contract: never push an auto-resolved rebase that has not passed the verify gate, and always keep the branch restorable to its pre-rebase state.
6
+
7
+ ## Inputs
8
+
9
+ - `pre_rebase_sha` — branch HEAD captured by the caller **before** `git rebase`; the rollback point.
10
+ - `default` — the branch being rebased onto.
11
+ - Session context: slug, PR url/number, and the persisted validation strategy (for the E2E step).
12
+
13
+ ## Procedure
14
+
15
+ ### Step 1 — Enumerate and classify conflicts
16
+
17
+ ```bash
18
+ git diff --name-only --diff-filter=U
19
+ ```
20
+
21
+ Classify each conflicted path:
22
+
23
+ - **Mechanical** — lockfiles (`package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, `Cargo.lock`, …), generated output (`dist/`, build artifacts, snapshots), or pure formatting / import-order churn.
24
+ - **Semantic** — anything carrying logic: source, behavior-changing config, tests.
25
+
26
+ ### Step 2 — Resolve
27
+
28
+ - **Mechanical** → resolve deterministically: regenerate the lockfile with the repo's package manager; regenerate or take-incoming for generated files; run the repo's formatter. Never hand-merge a lockfile.
29
+ - **Semantic** → a reasoned 3-way resolution preserving the intent of **both** sides (ours = the PR's change, theirs = the new default-branch line). If intent in load-bearing logic can't be confidently reconciled, do not guess → Step 5.
30
+
31
+ Then `git add -A && git rebase --continue`, and repeat Steps 1–2 for each remaining conflicted commit until the rebase completes.
32
+
33
+ ### Step 3 — Verify gate (mandatory)
34
+
35
+ Each must pass, in order:
36
+
37
+ 1. **Build** — typecheck + lint on the changed surface, per [`../do/build.md`](../do/build.md).
38
+ 2. **Unit suite** — per [`../do/unit-tests.md`](../do/unit-tests.md); record PASS.
39
+ 3. **E2E** — per [`../do/e2e-acceptance.md`](../do/e2e-acceptance.md) and the persisted [`autoE2ETest`](../muggle-preferences/preference-gates/autoE2ETest.md) strategy. A poll-only session with no validation context reports `SKIPPED`, same as the normal cycle.
40
+
41
+ ### Step 4 — Pass → proceed
42
+
43
+ Return success. The caller resumes the normal flow; the push happens downstream, so a resolved rebase ships only after it has verified.
44
+
45
+ ### Step 5 — Fail → restore + escalate
46
+
47
+ On an unreconcilable semantic conflict (Step 2) or any verify failure (Step 3):
48
+
49
+ ```bash
50
+ git rebase --abort 2>/dev/null || true
51
+ git reset --hard <pre_rebase_sha>
52
+ ```
53
+
54
+ The branch is now byte-for-byte its pre-rebase state. Emit one terminal escalation per [`../muggle-pr-followup/output-templates/escalation.md`](../muggle-pr-followup/output-templates/escalation.md) naming the conflicted files and the failing step, plus the `muggle-do:escalation` event with `kind: "rebase-conflict"` ([`telemetry-events/muggle-do-escalation.md`](telemetry-events/muggle-do-escalation.md)). Do not push.
55
+
56
+ ## Invariants
57
+
58
+ - A push never follows a verify failure.
59
+ - The branch is always restorable to `pre_rebase_sha`.
60
+ - This file runs only under `autoResolveConflicts = always`; `never` is the caller's unchanged abort-and-escalate path.
@@ -12,9 +12,12 @@ One per address-reviews invocation, regardless of outcome.
12
12
  "review_ids_in": [<int>, ...],
13
13
  "review_ids_actionable": [<int>, ...],
14
14
  "review_ids_ambiguous": [<int>, ...],
15
+ "ci_checks_in": ["<check-name>", ...],
16
+ "ci_checks_fixed": ["<check-name>", ...],
17
+ "ci_checks_escalated": ["<check-name>", ...],
15
18
  "head_sha_before": "<sha-or-null>",
16
19
  "head_sha_after": "<sha-or-null>",
17
- "outcome": "pushed" | "escalated" | "mixed" | "no-op" | "self-loop-skip"
20
+ "outcome": "pushed" | "escalated" | "mixed" | "no-op" | "self-loop-skip" | "ci-fixed" | "ci-escalated"
18
21
  }
19
22
  ```
20
23
 
@@ -24,3 +27,7 @@ One per address-reviews invocation, regardless of outcome.
24
27
  - `"mixed"` — both branches happened in the same invocation.
25
28
  - `"no-op"` — every input id was already in the escalated set; no work.
26
29
  - `"self-loop-skip"` — review was a synthetic wrapper around the agent's own reply (every line comment is a reply carrying the loop marker `<!-- muggle-do:bot -->`). Cursor advanced silently; no work, no escalation.
30
+ - `"ci-fixed"` — a watcher-dispatched fix-ci cycle pushed a fix for one or more red checks.
31
+ - `"ci-escalated"` — fix-ci exhausted its 3 attempts for the SHA or the failing checks were out of scope; the SHA was added to `ci_escalated_shas`. No further auto-fix on it.
32
+
33
+ For fix-ci cycles (`ci-fixed` / `ci-escalated`) the `review_ids_*` arrays are empty and the `ci_checks_*` arrays carry the data: `ci_checks_in` (red checks dispatched), `ci_checks_fixed` (made green and pushed), `ci_checks_escalated` (out-of-scope or unresolved).
@@ -9,7 +9,7 @@ Zero or one per address-reviews invocation. Fires when `/muggle-do` emits a term
9
9
  "session_slug": "<slug>",
10
10
  "repo": "<owner>/<repo>",
11
11
  "pr_number": <int>,
12
- "kind": "ambiguous-review" | "design-adjustment",
12
+ "kind": "ambiguous-review" | "design-adjustment" | "rebase-conflict",
13
13
  "review_ids": [<int>, ...]
14
14
  }
15
15
  ```
@@ -17,3 +17,4 @@ Zero or one per address-reviews invocation. Fires when `/muggle-do` emits a term
17
17
  `kind`:
18
18
  - `"ambiguous-review"` — one or more reviews classified ambiguous in this batch.
19
19
  - `"design-adjustment"` — mid-cycle, the work surfaced a design-level conflict.
20
+ - `"rebase-conflict"` — an opt-in auto-rebase hit conflicts that couldn't be resolved and verified; the branch was restored to its pre-rebase SHA. `review_ids` may be empty.
@@ -11,6 +11,8 @@ One per watcher iteration (idle or not).
11
11
  "pr_number": <int>,
12
12
  "reviews_seen": <int>,
13
13
  "dispatched_review_ids": [<int>, ...],
14
+ "checks_red": <int>,
15
+ "dispatched_ci_fix": true | false,
14
16
  "terminal": true | false,
15
17
  "idle": true | false,
16
18
  "tick_duration_ms": <int>
@@ -19,5 +21,7 @@ One per watcher iteration (idle or not).
19
21
 
20
22
  - `reviews_seen`: count of new submitted reviews past the cursor, **after** filtering by the escalated set.
21
23
  - `dispatched_review_ids`: review ids handed to `/muggle-do`. Empty when idle.
24
+ - `checks_red`: count of failing checks on the head SHA. `0` when reviews were dispatched (reviews preempt the CI poll) or CI was green/pending.
25
+ - `dispatched_ci_fix`: true when this tick dispatched `/muggle-do` with a fix-ci directive.
22
26
  - `terminal`: true when this tick observed the PR merged or closed and wrote `result.md`.
23
27
  - `idle`: true when no reviews were dispatched this tick.
@@ -7,13 +7,14 @@ Use this for feature development, local validation, and PR iteration.
7
7
  - **One worktree per branch.** Never switch branches inside a long-lived checkout.
8
8
  - **Isolate runtime resources.** Parallel worktrees need unique ports and isolated mutable test state.
9
9
  - **Keep worktrees disposable.** Create for focused work, remove after merge.
10
+ - **Existing PR branch?** Materialize it via [`pr-branch-worktree.md`](pr-branch-worktree.md) — same `<repo>/.claude/worktrees/` path scheme, checking out the existing branch instead of creating a new one.
10
11
 
11
12
  ## Start new change work
12
13
 
13
14
  1. Update the base branch (usually `main`).
14
15
  2. Create a new worktree and branch:
15
16
  ```bash
16
- git worktree add <repo>-worktrees/<slug> -b <branch>
17
+ git worktree add <repo>/.claude/worktrees/<sanitized-branch> -b <branch>
17
18
  ```
18
19
  3. Install dependencies and run setup in that worktree.
19
20
  4. Keep all edits and commits for the change in that same worktree.
@@ -19,7 +19,7 @@ Exact phrasing comes from the watcher's dispatch (see [`../muggle-pr-followup/co
19
19
 
20
20
  ## Inputs from disk
21
21
 
22
- Read from `.muggle-do/sessions/<slug>/`:
22
+ Read from `~/.muggle-ai/muggle-do/sessions/<slug>/`:
23
23
 
24
24
  - `prs.json` — to locate the PR's local checkout path (the `repo` field maps to a configured local repo) and capture `head_sha_before`.
25
25
  - `last_seen.json` — for `pushed_shas[]` (used by the resolve-reminder stage) and to update the cursor.
@@ -27,6 +27,10 @@ Read from `.muggle-do/sessions/<slug>/`:
27
27
 
28
28
  ## Procedure
29
29
 
30
+ ### Step 0 — Track the default branch
31
+
32
+ Before assembling work, rebase onto the latest default branch so the cycle addresses reviews against current master, not a stale base. Run [`../_shared/rebase-before-e2e.md`](../_shared/rebase-before-e2e.md) — gated by [`autoRebase`](../muggle-preferences/preference-gates/autoRebase.md), fires only when `behind > 0`. Conflict handling follows [`autoResolveConflicts`](../muggle-preferences/preference-gates/autoResolveConflicts.md): the default `never` aborts and escalates (`kind: "rebase-conflict"`); `always` resolves behind the verify-or-rollback gate. If the rebase escalates, stop the cycle — do not push.
33
+
30
34
  ### Step 1 — Assemble the work set
31
35
 
32
36
  Two sources, combined into one batch (dedupe by comment id):
@@ -63,6 +67,8 @@ The user clarifies on GitHub by submitting a new review. The next watcher tick p
63
67
 
64
68
  If `actionable_review_ids` is empty, skip the rest of Step 4 and Step 5; proceed to Step 5.5 (resolve-reminder) then Step 6. Otherwise:
65
69
 
70
+ Before any edits, ensure the PR's branch workspace is the working directory. If `state.md` carries a `worktreePath` (forward-mode session), use it. Otherwise materialize the PR branch per [`../_shared/pr-branch-worktree.md`](../_shared/pr-branch-worktree.md) — the single owner of checking out a PR branch in isolation — so a bootstrap or auto-track watcher never edits the user's live checkout. If the resolved tree is dirty with unrelated work, escalate per Step 7 rather than editing it.
71
+
66
72
  #### 4a. Flatten the work
67
73
 
68
74
  The actionable reviews together carry a flat list of change items, one per line comment plus any directive in the review body. Each item is design, code logic, or test in nature; the cycle does **not** treat each item as a separate cycle iteration — it plans them together and runs the work **once** for the whole batch.
@@ -20,7 +20,8 @@ For each affected repo:
20
20
  1. **Re-read `requirements.md`.** Treat goal + AC as frozen. If something is unclear at this stage, that's a pre-flight bug — escalate, do not improvise.
21
21
  2. **Apply the change** in the repo's worktree. Edit existing files first; create new files only when the requirements demand it. Match the surrounding code's style, naming, and file layout.
22
22
  3. **Don't add what wasn't asked for.** No speculative abstractions, no extra logging, no "while I'm here" refactors. Three similar lines is better than a premature abstraction.
23
- 4. **Commit** with a conventional-commit subject:
23
+ 4. **Cover new logic with tests.** If you added or changed non-trivial logic (a hook, reducer, parser, state machine, branching util), write its unit tests now — Stage 5 only *runs* the suite, it never authors tests. Untested new logic is a Definition-of-Done failure, not a Stage-5 gap.
24
+ 5. **Commit** with a conventional-commit subject:
24
25
  - `feat(<scope>): <short>` for new behavior
25
26
  - `fix(<scope>): <short>` for bug fixes
26
27
  - `refactor(<scope>): <short>` for reshape
@@ -0,0 +1,14 @@
1
+ # Post-Merge Cleanup Stage
2
+
3
+ Invoked by `/muggle-do` when the watcher forwards a PR's terminal (`merged`) state. This stage only resolves the session's workspace and **delegates** teardown to the shared procedure — it does not restate the teardown steps. Never runs while the PR is open.
4
+
5
+ ## Input
6
+
7
+ `$ARGUMENTS` carries the session slug as `slug=<slug>`. No PR URL, no review ids.
8
+
9
+ ## Procedure
10
+
11
+ 1. Read `~/.muggle-ai/muggle-do/sessions/<slug>/`: `prs.json` (PR `repo`, `number`, observed `state`) and `state.md` (`worktreePath` if a worktree was used, and the target branch `headRefName`).
12
+ 2. Confirm `prs.json` shows the PR `merged`. If it is still open or was closed unmerged, do nothing and exit — this stage is post-merge only.
13
+ 3. Run [`../_shared/post-merge-cleanup.md`](../_shared/post-merge-cleanup.md) with `{worktreePath}` and `{branch}`. That file owns the teardown sequence **and its safety rules** — including skipping worktree-remove and local branch deletion when no worktree was used. This stage adds no teardown logic of its own.
14
+ 4. Append a cleanup line to the session's `followup.log`.
@@ -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** — per [`../_shared/dev-server-readiness.md`](../_shared/dev-server-readiness.md) (port + compile log + backend health). Halt on any failure.
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: Execute Tests Locally
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
- 1. Call `muggle-remote-test-script-list` filtered by `testCaseId` to check for an existing script.
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: never hand-build or simplify `actionScript` — only use full response from `muggle-remote-action-script-get`.
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.