@muggleai/works 5.0.3 → 5.1.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 (136) hide show
  1. package/README.md +2 -3
  2. package/dist/{chunk-XO5BQZM3.js → chunk-2BHC6TQR.js} +3 -4
  3. package/dist/{chunk-KDRSEHK5.js → chunk-MOHR7QUN.js} +197 -291
  4. package/dist/cli.js +2 -2
  5. package/dist/index.js +2 -2
  6. package/dist/plugin/.claude-plugin/plugin.json +1 -1
  7. package/dist/plugin/.cursor-plugin/plugin.json +1 -1
  8. package/dist/plugin/scripts/ensure-electron-app.sh +1 -1
  9. package/dist/plugin/scripts/guardrails.mjs +4 -2
  10. package/dist/plugin/skills/_shared/debug-failed-run.md +53 -0
  11. package/dist/plugin/skills/_shared/dev-loop/publish.md +4 -8
  12. package/dist/plugin/skills/_shared/pr-followup-helpers/allow-list.md +1 -1
  13. package/dist/plugin/skills/_shared/pr-followup-helpers/echo-skip.md +1 -1
  14. package/dist/plugin/skills/_shared/resolve-e2e-validation-context.md +1 -1
  15. package/dist/plugin/skills/_shared/telemetry-events/pr-followup-tick.md +1 -1
  16. package/dist/plugin/skills/_shared/test-case-chain-readiness.md +1 -2
  17. package/dist/plugin/skills/_shared/vcs/CLAUDE.md +9 -0
  18. package/dist/plugin/skills/_shared/vcs/detect-vcs.md +28 -0
  19. package/dist/plugin/skills/_shared/vcs/github/pr-metadata.md +25 -0
  20. package/{plugin/skills/_shared/github-cli-recipes → dist/plugin/skills/_shared/vcs/github}/unresolved-threads.md +1 -1
  21. package/{plugin/skills/_shared/github-cli-recipes → dist/plugin/skills/_shared/vcs/github}/verify-working-tree.md +1 -1
  22. package/dist/plugin/skills/_shared/vcs/github.md +21 -0
  23. package/dist/plugin/skills/_shared/vcs/gitlab/loop-user-identity.md +9 -0
  24. package/dist/plugin/skills/_shared/vcs/gitlab/mr-create.md +11 -0
  25. package/dist/plugin/skills/_shared/vcs/gitlab/mr-discussions.md +18 -0
  26. package/dist/plugin/skills/_shared/vcs/gitlab/mr-edit.md +8 -0
  27. package/dist/plugin/skills/_shared/vcs/gitlab/mr-metadata.md +22 -0
  28. package/dist/plugin/skills/_shared/vcs/gitlab/mr-note.md +7 -0
  29. package/dist/plugin/skills/_shared/vcs/gitlab/mr-pipeline.md +27 -0
  30. package/dist/plugin/skills/_shared/vcs/gitlab/reply-discussion.md +9 -0
  31. package/dist/plugin/skills/_shared/vcs/gitlab/resolve-discussion.md +10 -0
  32. package/dist/plugin/skills/_shared/vcs/gitlab/unresolved-discussions.md +18 -0
  33. package/dist/plugin/skills/_shared/vcs/gitlab.md +24 -0
  34. package/dist/plugin/skills/do/address-reviews.md +10 -6
  35. package/dist/plugin/skills/do/e2e-acceptance.md +6 -4
  36. package/dist/plugin/skills/do/fix-ci.md +1 -1
  37. package/dist/plugin/skills/do/input-routing.md +4 -4
  38. package/dist/plugin/skills/do/open-prs/forward.md +6 -4
  39. package/dist/plugin/skills/do/open-prs/update.md +8 -6
  40. package/dist/plugin/skills/do/per-comment-replies.md +22 -13
  41. package/dist/plugin/skills/do/resolve-conflicts.md +1 -1
  42. package/dist/plugin/skills/do/resolve-reminder.md +8 -6
  43. package/dist/plugin/skills/muggle-browser-task/SKILL.md +1 -1
  44. package/dist/plugin/skills/muggle-do/SKILL.md +2 -2
  45. package/dist/plugin/skills/muggle-feedback/ops/submit.md +4 -4
  46. package/dist/plugin/skills/muggle-pr-followup/CLAUDE.md +2 -2
  47. package/dist/plugin/skills/muggle-pr-followup/bootstrap.md +13 -11
  48. package/dist/plugin/skills/muggle-pr-followup/contract.md +18 -12
  49. package/dist/plugin/skills/muggle-pr-followup/finalize.md +1 -1
  50. package/dist/plugin/skills/muggle-pr-followup/reconcile.md +1 -1
  51. package/dist/plugin/skills/muggle-pr-followup/state-schemas.md +4 -1
  52. package/dist/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +13 -13
  53. package/dist/plugin/skills/muggle-preferences/ops/configure.md +2 -2
  54. package/dist/plugin/skills/muggle-test/SKILL.md +30 -143
  55. package/dist/plugin/skills/muggle-test/execute-local.md +60 -0
  56. package/dist/plugin/skills/muggle-test/execute-remote.md +49 -0
  57. package/dist/plugin/skills/muggle-test/reference.md +1 -2
  58. package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +9 -18
  59. package/dist/release-manifest.json +4 -4
  60. package/dist/{src-2O5UH4FA.js → src-SS2AL3O7.js} +1 -1
  61. package/package.json +6 -6
  62. package/plugin/.claude-plugin/plugin.json +1 -1
  63. package/plugin/.cursor-plugin/plugin.json +1 -1
  64. package/plugin/scripts/ensure-electron-app.sh +1 -1
  65. package/plugin/scripts/guardrails.mjs +4 -2
  66. package/plugin/skills/_shared/debug-failed-run.md +53 -0
  67. package/plugin/skills/_shared/dev-loop/publish.md +4 -8
  68. package/plugin/skills/_shared/pr-followup-helpers/allow-list.md +1 -1
  69. package/plugin/skills/_shared/pr-followup-helpers/echo-skip.md +1 -1
  70. package/plugin/skills/_shared/resolve-e2e-validation-context.md +1 -1
  71. package/plugin/skills/_shared/telemetry-events/pr-followup-tick.md +1 -1
  72. package/plugin/skills/_shared/test-case-chain-readiness.md +1 -2
  73. package/plugin/skills/_shared/vcs/CLAUDE.md +9 -0
  74. package/plugin/skills/_shared/vcs/detect-vcs.md +28 -0
  75. package/plugin/skills/_shared/vcs/github/pr-metadata.md +25 -0
  76. package/{dist/plugin/skills/_shared/github-cli-recipes → plugin/skills/_shared/vcs/github}/unresolved-threads.md +1 -1
  77. package/{dist/plugin/skills/_shared/github-cli-recipes → plugin/skills/_shared/vcs/github}/verify-working-tree.md +1 -1
  78. package/plugin/skills/_shared/vcs/github.md +21 -0
  79. package/plugin/skills/_shared/vcs/gitlab/loop-user-identity.md +9 -0
  80. package/plugin/skills/_shared/vcs/gitlab/mr-create.md +11 -0
  81. package/plugin/skills/_shared/vcs/gitlab/mr-discussions.md +18 -0
  82. package/plugin/skills/_shared/vcs/gitlab/mr-edit.md +8 -0
  83. package/plugin/skills/_shared/vcs/gitlab/mr-metadata.md +22 -0
  84. package/plugin/skills/_shared/vcs/gitlab/mr-note.md +7 -0
  85. package/plugin/skills/_shared/vcs/gitlab/mr-pipeline.md +27 -0
  86. package/plugin/skills/_shared/vcs/gitlab/reply-discussion.md +9 -0
  87. package/plugin/skills/_shared/vcs/gitlab/resolve-discussion.md +10 -0
  88. package/plugin/skills/_shared/vcs/gitlab/unresolved-discussions.md +18 -0
  89. package/plugin/skills/_shared/vcs/gitlab.md +24 -0
  90. package/plugin/skills/do/address-reviews.md +10 -6
  91. package/plugin/skills/do/e2e-acceptance.md +6 -4
  92. package/plugin/skills/do/fix-ci.md +1 -1
  93. package/plugin/skills/do/input-routing.md +4 -4
  94. package/plugin/skills/do/open-prs/forward.md +6 -4
  95. package/plugin/skills/do/open-prs/update.md +8 -6
  96. package/plugin/skills/do/per-comment-replies.md +22 -13
  97. package/plugin/skills/do/resolve-conflicts.md +1 -1
  98. package/plugin/skills/do/resolve-reminder.md +8 -6
  99. package/plugin/skills/muggle-browser-task/SKILL.md +1 -1
  100. package/plugin/skills/muggle-do/SKILL.md +2 -2
  101. package/plugin/skills/muggle-feedback/ops/submit.md +4 -4
  102. package/plugin/skills/muggle-pr-followup/CLAUDE.md +2 -2
  103. package/plugin/skills/muggle-pr-followup/bootstrap.md +13 -11
  104. package/plugin/skills/muggle-pr-followup/contract.md +18 -12
  105. package/plugin/skills/muggle-pr-followup/finalize.md +1 -1
  106. package/plugin/skills/muggle-pr-followup/reconcile.md +1 -1
  107. package/plugin/skills/muggle-pr-followup/state-schemas.md +4 -1
  108. package/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +13 -13
  109. package/plugin/skills/muggle-preferences/ops/configure.md +2 -2
  110. package/plugin/skills/muggle-test/SKILL.md +30 -143
  111. package/plugin/skills/muggle-test/execute-local.md +60 -0
  112. package/plugin/skills/muggle-test/execute-remote.md +49 -0
  113. package/plugin/skills/muggle-test/reference.md +1 -2
  114. package/plugin/skills/muggle-test-feature-local/SKILL.md +9 -18
  115. package/dist/plugin/skills/_shared/github-cli-recipes/pr-metadata.md +0 -13
  116. package/dist/plugin/skills/_shared/github-cli-recipes.md +0 -21
  117. package/dist/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +0 -11
  118. package/plugin/skills/_shared/github-cli-recipes/pr-metadata.md +0 -13
  119. package/plugin/skills/_shared/github-cli-recipes.md +0 -21
  120. package/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +0 -11
  121. /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/line-comments-for-review.md +0 -0
  122. /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/loop-user-identity.md +0 -0
  123. /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/pr-checks.md +0 -0
  124. /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/pr-edit.md +0 -0
  125. /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/push-to-branch.md +0 -0
  126. /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/reply-line-comment.md +0 -0
  127. /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/submitted-reviews.md +0 -0
  128. /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/top-level-comment.md +0 -0
  129. /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/line-comments-for-review.md +0 -0
  130. /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/loop-user-identity.md +0 -0
  131. /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/pr-checks.md +0 -0
  132. /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/pr-edit.md +0 -0
  133. /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/push-to-branch.md +0 -0
  134. /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/reply-line-comment.md +0 -0
  135. /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/submitted-reviews.md +0 -0
  136. /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/top-level-comment.md +0 -0
@@ -7,7 +7,7 @@ description: "Change-driven E2E acceptance testing with Muggle AI: detect the us
7
7
 
8
8
  > Telemetry first step: see [`_shared/telemetry-emit.md`](../_shared/telemetry-emit.md). Use `skillName: "muggle-test"`.
9
9
 
10
- A router skill that detects code changes, resolves impacted test cases, executes them locally or remotely, publishes results to the Muggle AI dashboard, and posts E2E acceptance summaries to the PR. The user can invoke this at any moment, in any state.
10
+ A router skill that detects code changes, resolves impacted test cases, executes them locally or remotely, reads the cloud results from the Muggle AI dashboard (local runs are published by the studio during execution; remote runs publish cloud-side), and posts E2E acceptance summaries to the PR. The user can invoke this at any moment, in any state.
11
11
 
12
12
  ## UX Guidelines — Minimize Typing
13
13
 
@@ -42,11 +42,10 @@ Gates run per `preference-gates/README.md`.
42
42
  |------------|------|-------------------|
43
43
  | `autoLogin` | 3 | Reuse saved credentials when auth is required |
44
44
  | `autoSelectProject` | 4 | Reuse last-used Muggle Test project for this repo |
45
- | `autoSelectLocalHost` | 7A | Reuse last-used local dev server URL for this repo |
45
+ | `autoSelectLocalHost` | execute-local | Reuse last-used local dev server URL for this repo |
46
46
  | `autoDetectChanges` | 2 | Scan local git changes and map to affected test cases |
47
47
  | `defaultExecutionMode` | 1 | Default to local or remote test execution |
48
- | `autoPublishLocalResults` | 7A | Upload local results to Muggle Test cloud after run |
49
- | `showElectronBrowser` | 7A | Show the Electron browser window during local test execution (vs. run headless) |
48
+ | `showElectronBrowser` | execute-local | Show the Electron browser window during local test execution (vs. run headless) |
50
49
  | `postPRVisualWalkthrough` | 9 | Post visual walkthrough to PR after results are available |
51
50
  | `autoCreatePR` | 9 (if no PR) | Auto-create the PR when posting the walkthrough has no PR to target |
52
51
  | `autoWatchPR` | 9.5 (if a PR exists) | Start a `muggle-pr-followup` watcher on the PR after the run |
@@ -235,148 +234,37 @@ Then show the per-case decision in one `AskUserQuestion`:
235
234
 
236
235
  If the user picks "Override one or more", let them flip the mode for any test case via a second multi-select `AskUserQuestion`. Emit a follow-up `pre-execution-classification` event with `userAction` set whenever the user overrides.
237
236
 
238
- ## Step 7A: Execute — Local Mode
237
+ ## Step 7: Execute
239
238
 
240
- ### Local environment readiness
239
+ ### Fetch test case details (both modes)
241
240
 
242
- Before anything else, invoke [`muggle-test-prepare`](../muggle-test-prepare/SKILL.md) — the readiness/service-start owner (idempotent; halt on what it surfaces). The URL gate below only *selects* the target; prepare is what guarantees something is listening and compiled.
241
+ Hydrate every selected test case **once**, before dispatch: issue **all** `muggle-remote-test-case-get` calls in parallel (single message, multiple tool calls). Both paths consume the result — never re-fetch inside a path.
243
242
 
244
- ### Pre-flight question — Local URL (gated by `autoSelectLocalHost`)
243
+ ### Dispatch by mode
245
244
 
246
- Skill responsibilities (the rest is in `preference-gates/autoSelectLocalHost.md`):
247
- - **Read the cache**: `Muggle Test Last Host: <url>` session-context line, or `muggle-local-last-host-get`. Pass as `{lastHost}` substitution.
248
- - **Auto-detect a suggested URL**: `lsof -iTCP -sTCP:LISTEN -nP | grep -E ':(3000|3001|4200|5173|8080)'`. Pass as `{suggestedHost}`.
249
- - **Save the cache**: call `muggle-local-last-host-set` after the user picks (the gate file requires this on every pick).
245
+ Run the path matching the mode confirmed in Step 1. Each path owns its own process and returns a **uniform runs list** — `[{ testCaseId, mode, runId | runtimeId, status, viewUrl? }]` — that Steps 7C–10 consume mode-agnostically.
250
246
 
251
- Gate `autoSelectLocalHost` per `preference-gates/README.md` + `preference-gates/autoSelectLocalHost.md`.
247
+ - **Mode A (Local)** → [`execute-local.md`](execute-local.md). Inputs: the hydrated test cases, per-case `mode` from Step 6f, and `cwd` (the PR-branch worktree from Step 2 if one exists, else the repo root).
248
+ - **Mode B (Remote)** → [`execute-remote.md`](execute-remote.md). Inputs: the hydrated test cases, per-case `mode` from Step 6f, `projectId` / `useCaseId`.
252
249
 
253
- ### Pre-flight visibility (gated by `showElectronBrowser`)
250
+ ## Step 7C: Route every failed run through the debug path
254
251
 
255
- Gate `showElectronBrowser` (per `preference-gates/README.md`). Resolve once; apply same `showUi` to every test case.
256
- - `always` → omit `showUi` (defaults visible).
257
- - `never` → pass `showUi: false`.
258
- - `ask` → run Picker 1 from `preference-gates/showElectronBrowser.md` via `AskUserQuestion`; map the answer back to one of the actions above.
252
+ For every run with `status: "failed"` (or any non-passing terminal state) returned by Step 7 (either path), route through [`_shared/debug-failed-run.md`](../_shared/debug-failed-run.md). This is **mandatory** — a failure is never reported without it. The debug path gathers evidence (attempted steps + reasoning + screenshot), diagnoses via [`_shared/failure-mode-handling.md`](../_shared/failure-mode-handling.md) (§B replay / §C regen), shows the debug card, and presents the guaranteed selection in which **"give feedback & rerun"** is always an option and "skip" is never the default.
259
253
 
260
- ### Fetch test case details (in parallel)
261
-
262
- Before execution, fetch full test case details for all selected test cases by issuing **all** `muggle-remote-test-case-get` calls in parallel (single message, multiple tool calls).
263
-
264
- ### Run the dev loop
265
-
266
- Execute each selected test case via the shared loop in [`../_shared/dev-loop/run.md`](../_shared/dev-loop/run.md): [sequential replay/regen](../_shared/dev-loop/run.md), [`actionScript` as-is](../_shared/dev-loop/action-script.md), [`freshSession`](../_shared/dev-loop/fresh-session.md), and [`timeoutMs`](../_shared/dev-loop/timeouts.md).
267
-
268
- Caller glue:
269
- - `mode` per test case comes from Step 6f; `localUrl` from the pre-flight question; `showUi` from the `showElectronBrowser` resolution.
270
- - `cwd` = the PR-branch worktree from Step 2 if one was created, else the user's repo root — it drives the cross-worktree single-flight lock so concurrent muggle-test runs from different branches serialize.
271
- - On a failed run, continue the batch and route it through Step 7C after completion.
272
-
273
- ### Collect results
274
-
275
- Fetch every `runId` per [`../_shared/dev-loop/failures.md`](../_shared/dev-loop/failures.md), reading structured fields and [interpreting failures](../_shared/dev-loop/failures.md) — never `execute`'s stdout tail. Issue the `muggle-local-run-result-get` calls in parallel; use `Error` as the headline for failures and route through Step 7C.
276
-
277
- ### Publish each run to cloud (gated by `autoPublishLocalResults`)
278
-
279
- Gate `autoPublishLocalResults` (per `preference-gates/README.md`):
280
- - `always` → proceed to publish logic below.
281
- - `never` → skip to report summary; tell user Steps 8/9 and per-step screenshots are unavailable without publishing.
282
- - `ask` → run Picker 1 from `preference-gates/autoPublishLocalResults.md` via `AskUserQuestion`; map the answer back to one of the actions above.
283
-
284
- ### Publish logic (when publishing is enabled)
285
-
286
- Publish every completed run per [`../_shared/dev-loop/publish.md`](../_shared/dev-loop/publish.md) — parallel `muggle-local-publish-test-script` with the zero-step `muggle-remote-local-run-upload` fallback. Store every `viewUrl`, `testScriptId`, `actionScriptId` — used in the next steps.
287
-
288
- ### Report summary
289
-
290
- ```
291
- Test Case Status Duration Steps View Steps on Muggle AI
292
- ─────────────────────────────────────────────────────────────────────────
293
- Login with valid creds PASSED 12.3s 8 https://www.muggle-ai.com/...
294
- Login with invalid creds PASSED 9.1s 6 https://www.muggle-ai.com/...
295
- Checkout flow FAILED 15.7s 12 https://www.muggle-ai.com/...
296
- ─────────────────────────────────────────────────────────────────────────
297
- Total: 3 tests | 2 passed | 1 failed | 37.1s
298
- ```
299
-
300
- For failures: show which step failed, the local screenshot path, and a suggestion.
301
-
302
- ## Step 7B: Execute — Remote Mode
303
-
304
- ### Ask for target URL
305
-
306
- > "What's the preview/staging URL to test against?"
307
-
308
- ### Fetch test case details (in parallel)
309
-
310
- Issue all `muggle-remote-test-case-get` calls in parallel (single message, multiple tool calls) to hydrate the test case bodies.
311
-
312
- ### Trigger remote workflows (in parallel)
313
-
314
- Branch each test case on the mode chosen in Step 6f, then issue **all** workflow-start calls in parallel — never loop them sequentially. Mix regen and replay starts in the same parallel batch.
315
-
316
- **Regen-mode test case** — `muggle-remote-workflow-start-test-script-generation`:
317
-
318
- - `projectId`: The project ID
319
- - `useCaseId`: The use case ID
320
- - `testCaseId`: The test case ID
321
- - `name`: `"muggle-test: {test case title}"`
322
- - `url`: The preview/staging URL
323
- - `goal`: From the test case
324
- - `precondition`: From the test case (use `"None"` if empty)
325
- - `instructions`: From the test case
326
- - `expectedResult`: From the test case
327
-
328
- **Replay-mode test case** — `muggle-remote-workflow-start-test-script-replay` against the latest replayable script for that test case (resolve via `muggle-remote-test-script-list` if not already in hand from Step 6f). Tag results with `mode: "replay"` so Step 7C can route failures correctly.
329
-
330
- Store each returned workflow runtime ID along with its mode tag.
331
-
332
- ### Monitor and report (in parallel)
333
-
334
- Issue all `muggle-remote-wf-get-ts-gen-latest-run` calls in parallel, one per runtime ID.
335
-
336
- ```
337
- Test Case Workflow Status Runtime ID
338
- ────────────────────────────────────────────────────────
339
- Login with valid creds RUNNING rt-abc123
340
- Login with invalid creds COMPLETED rt-def456
341
- Checkout flow QUEUED rt-ghi789
342
- ```
343
-
344
- ## Step 7C: Route failures through the failure-mode handler
345
-
346
- For every run with `status: "failed"` (or any non-passing terminal state) from 7A or 7B, follow [`_shared/failure-mode-handling.md`](../_shared/failure-mode-handling.md):
347
-
348
- - **Replay-mode failures** — section B (buckets: `infra` / `stale-script` / `product-defect`).
349
- - **Regen-mode failures** — section C (buckets: `transient` / `infra` / `agent-course` / `product-uxux`).
350
-
351
- For each failed run:
352
- 1. Read the run with `muggle-local-run-result-get` (local) or `muggle-remote-wf-get-ts-gen-latest-run` / `muggle-remote-wf-get-ts-replay-latest-run` (remote) and extract signals per the heuristics in the shared doc.
353
- 2. Emit `replay-failure-classified` or `regen-failure-classified` via `muggle-local-telemetry-event-emit` **before** asking the user.
354
- 3. Present the recommended action via `AskUserQuestion` along with the alternatives the shared doc lists for that bucket.
355
- 4. After the user picks, emit the matching `*-resolved` event with `userAction` set to what they chose.
356
-
357
- Process failures one at a time so the user isn't drowning in pickers — but emit telemetry per failure regardless.
254
+ Pass it per failed run: the `runId` (local) or workflow runtime id (remote), the `mode` that failed, `testCaseId`, `projectId`, and the execution handle (local: [`execute-local.md`](execute-local.md); remote: [`execute-remote.md`](execute-remote.md)) so a rerun re-enters the same path. Process failures one at a time so the user isn't drowning in pickers.
358
255
 
359
256
  ## Step 8: Open Results in Browser
360
257
 
361
- After execution and publishing are complete, open the Muggle AI dashboard so the user can visually inspect results and screenshots.
362
-
363
- ### Mode A (Local) — open each published viewUrl
258
+ After execution, open the Muggle AI dashboard so the user can inspect results and screenshots. The studio published every local run during execution, so each run result already carries its `viewUrl` (read it from `muggle-local-run-result-get`). Key off the uniform runs list:
364
259
 
365
- For each published run's `viewUrl`:
366
- ```bash
367
- open "https://www.muggle-ai.com/muggleTestV0/dashboard/projects/{projectId}/scripts?modal=script-details&testCaseId={testCaseId}"
368
- ```
369
-
370
- If there are many runs (>3), open just the project-level runs page instead of individual tabs:
371
- ```bash
372
- open "https://www.muggle-ai.com/muggleTestV0/dashboard/projects/{projectId}/runs"
373
- ```
374
-
375
- ### Mode B (Remote) — open the project runs page
376
-
377
- ```bash
378
- open "https://www.muggle-ai.com/muggleTestV0/dashboard/projects/{projectId}/runs"
379
- ```
260
+ - **Runs carry a `viewUrl` and there are ≤3** — open each:
261
+ ```bash
262
+ open "https://www.muggle-ai.com/muggleTestV0/dashboard/projects/{projectId}/scripts?modal=script-details&testCaseId={testCaseId}"
263
+ ```
264
+ - **Otherwise** (more than 3 runs, or a run with no `viewUrl`) — open the project runs page:
265
+ ```bash
266
+ open "https://www.muggle-ai.com/muggleTestV0/dashboard/projects/{projectId}/runs"
267
+ ```
380
268
 
381
269
  Tell the user:
382
270
  > "I've opened the Muggle AI dashboard in your browser — you can see the test results, step-by-step screenshots, and action scripts there."
@@ -388,7 +276,7 @@ After reporting results:
388
276
  1. Fire [`postPRVisualWalkthrough`](../muggle-preferences/preference-gates/postPRVisualWalkthrough.md). On skip → Step 9.5.
389
277
  2. `gh pr view --json number,title,url 2>/dev/null` — find the PR.
390
278
  3. If no PR: fire [`autoCreatePR`](../muggle-preferences/preference-gates/autoCreatePR.md). On skip → Step 9.5.
391
- 4. Assemble the `E2eReport` — see [`../muggle-pr-visual-walkthrough/e2e-report-assembly.md`](../muggle-pr-visual-walkthrough/e2e-report-assembly.md). Include all runs from Step 7A (passed and failed).
279
+ 4. Assemble the `E2eReport` — see [`../muggle-pr-visual-walkthrough/e2e-report-assembly.md`](../muggle-pr-visual-walkthrough/e2e-report-assembly.md). Include all runs from Step 7 (passed and failed).
392
280
  5. Invoke [`../muggle-pr-visual-walkthrough/SKILL.md`](../muggle-pr-visual-walkthrough/SKILL.md) Mode A with the `E2eReport`.
393
281
 
394
282
  ## Step 9.5: Offer to watch the PR for review follow-ups
@@ -403,27 +291,26 @@ Once a PR exists for this work, offer to keep watching its review thread.
403
291
 
404
292
  The `/mprfollowup` shortcut starts the same watcher manually at any time.
405
293
 
406
- ## Step 10: Offer feedback on failures
407
-
408
- After the report is complete, if **any** test in the run had a `failed` or unexpected status (or the user verbally flags something looked off), suggest the feedback skill:
294
+ ## Step 10: Offer feedback on a clean pass
409
295
 
410
- > "Looks like `<N>` test(s) didn't go as expected. Want to leave feedback on what should've happened? It triggers regeneration on the affected scripts."
296
+ Failures already got a guaranteed feedback-&-rerun offer in Step 7C's debug path — don't re-ask for them here.
411
297
 
412
- Use `AskUserQuestion`:
413
- - **Yes — give feedback** → invoke the `muggle-feedback` skill via the `Skill` tool. Pass the failed run's `runId` (local) or `testScriptId` (remote) as anchor context so the submit flow opens with the correct script already loaded.
298
+ This step is only for a run that **passed** but the user flags as off (a misclick, wrong element, a summary that doesn't match intent). When that happens, use `AskUserQuestion`:
299
+ - **Yes — give feedback** → invoke the `muggle-feedback` skill via the `Skill` tool, passing the run's `runId` (local) or `testScriptId` (remote) as anchor context so the submit flow opens with the correct script already loaded.
414
300
  - **No — skip**
415
301
 
416
- This is a suggestion, not automatic invocation. Skip silently if every test passed cleanly.
302
+ Skip silently if nothing looked off.
417
303
 
418
304
  ## Non-negotiables
419
305
 
420
306
  Each rule below is covered in-step above; these are the ones this skill most often violates, kept here as reinforcement:
421
307
 
422
308
  - **Test-case shape** — never skip the generate→review cycle, never consolidate the generator's micro-tests, one atomic behavior per test case. Creating test cases directly or merging the generator's output is the single most frequent mistake.
309
+ - **Every failure routes through the debug path** — no failed run is summarized-and-dropped. Step 7C → [`_shared/debug-failed-run.md`](../_shared/debug-failed-run.md) is mandatory, "give feedback & rerun" is always offered, and "skip" is never the default.
423
310
  - **Confirm intent before acting** — local vs remote; never guess the localhost/preview URL.
424
311
  - **PR URLs run in a dedicated worktree** — never switch the user's main checkout; pass that worktree as `cwd`.
425
312
  - **Every selection uses `AskUserQuestion`** — never ask the user to type a number; the user picks the project (never auto-select).
426
313
  - **Parallelize independent cloud jobs**; the only sequential loop is local Electron execution (one browser).
427
- - **Publish before opening the browser**, and delegate PR posting to `muggle-pr-visual-walkthrough` — never inline the walkthrough or call `gh pr comment` here.
314
+ - **Read cloud refs off the run result** (the studio published during execution) and delegate PR posting to `muggle-pr-visual-walkthrough` — never inline the walkthrough or call `gh pr comment` here.
428
315
 
429
316
  Phase→tool map and multi-agent (acceptance-tester) dispatch: [`reference.md`](reference.md).
@@ -0,0 +1,60 @@
1
+ # Muggle Test — Local Execution Path (Mode A)
2
+
3
+ > The Local execution process for the `muggle-test` router: run the selected test cases against localhost via the Electron browser and collect results. The studio publishes each run to the cloud during execution, so the run result already carries the cloud refs. Returns a uniform runs list to the router. Per-test-case mechanics are shared with [`../_shared/dev-loop/run.md`](../_shared/dev-loop/run.md).
4
+
5
+ ## Inputs (the router passes these in)
6
+
7
+ - The hydrated test cases (fetched once by the router before dispatch).
8
+ - Per-case `mode` — `replay` or `regen`, chosen during replay-vs-regen classification.
9
+ - `cwd` — the PR-branch worktree if one exists, else the repo root.
10
+
11
+ ## Local environment readiness
12
+
13
+ Before anything else, invoke [`muggle-test-prepare`](../muggle-test-prepare/SKILL.md) — the readiness/service-start owner (idempotent; halt on what it surfaces). The URL gate below only *selects* the target; prepare is what guarantees something is listening and compiled.
14
+
15
+ ## Pre-flight question — Local URL (gated by `autoSelectLocalHost`)
16
+
17
+ Skill responsibilities (the rest is in `preference-gates/autoSelectLocalHost.md`):
18
+ - **Read the cache**: `Muggle Test Last Host: <url>` session-context line, or `muggle-local-last-host-get`. Pass as `{lastHost}` substitution.
19
+ - **Auto-detect a suggested URL**: `lsof -iTCP -sTCP:LISTEN -nP | grep -E ':(3000|3001|4200|5173|8080)'`. Pass as `{suggestedHost}`.
20
+ - **Save the cache**: call `muggle-local-last-host-set` after the user picks (the gate file requires this on every pick).
21
+
22
+ Gate `autoSelectLocalHost` per `preference-gates/README.md` + `preference-gates/autoSelectLocalHost.md`.
23
+
24
+ ## Pre-flight visibility (gated by `showElectronBrowser`)
25
+
26
+ Gate `showElectronBrowser` (per `preference-gates/README.md`). Resolve once; apply same `showUi` to every test case.
27
+ - `always` → omit `showUi` (defaults visible).
28
+ - `never` → pass `showUi: false`.
29
+ - `ask` → run Picker 1 from `preference-gates/showElectronBrowser.md` via `AskUserQuestion`; map the answer back to one of the actions above.
30
+
31
+ ## Run the dev loop
32
+
33
+ Execute each test case via the shared loop in [`../_shared/dev-loop/run.md`](../_shared/dev-loop/run.md): [sequential replay/regen](../_shared/dev-loop/run.md), [`actionScript` as-is](../_shared/dev-loop/action-script.md), [`freshSession`](../_shared/dev-loop/fresh-session.md), and [`timeoutMs`](../_shared/dev-loop/timeouts.md).
34
+
35
+ Caller glue:
36
+ - `mode` per test case is the input from the router; `localUrl` from the pre-flight question; `showUi` from the `showElectronBrowser` resolution.
37
+ - `cwd` is the input from the router — it drives the cross-worktree single-flight lock so concurrent muggle-test runs from different branches serialize.
38
+ - On a failed run, continue the batch; the router routes failures through the debug path after this path returns.
39
+
40
+ ## Collect results
41
+
42
+ Fetch every `runId` per [`../_shared/dev-loop/failures.md`](../_shared/dev-loop/failures.md), reading structured fields and [interpreting failures](../_shared/dev-loop/failures.md) — never `execute`'s stdout tail. Issue the `muggle-local-run-result-get` calls in parallel; use `Error` as the headline for failures. The studio already published each run, so the same call surfaces `viewUrl` / `cloudTestScriptId` / `cloudActionScriptId` — retain them per [`../_shared/dev-loop/publish.md`](../_shared/dev-loop/publish.md) for the dashboard and walkthrough.
43
+
44
+ ## Report summary
45
+
46
+ ```
47
+ Test Case Status Duration Steps View Steps on Muggle AI
48
+ ─────────────────────────────────────────────────────────────────────────
49
+ Login with valid creds PASSED 12.3s 8 https://www.muggle-ai.com/...
50
+ Login with invalid creds PASSED 9.1s 6 https://www.muggle-ai.com/...
51
+ Checkout flow FAILED 15.7s 12 https://www.muggle-ai.com/...
52
+ ─────────────────────────────────────────────────────────────────────────
53
+ Total: 3 tests | 2 passed | 1 failed | 37.1s
54
+ ```
55
+
56
+ For failures, don't hand-write a verdict — the router routes each through the debug path.
57
+
58
+ ## Output
59
+
60
+ Return the uniform runs list the router consumes: `[{ testCaseId, mode, runId, status, viewUrl?, cloudTestScriptId?, cloudActionScriptId? }]`. The studio published each run during execution, so `viewUrl` / `cloudTestScriptId` / `cloudActionScriptId` come straight off the run result (`muggle-local-run-result-get`).
@@ -0,0 +1,49 @@
1
+ # Muggle Test — Remote Execution Path (Mode B)
2
+
3
+ > The Remote execution process for the `muggle-test` router: trigger cloud test-script generation/replay against a preview/staging URL and monitor. Returns a uniform runs list to the router.
4
+
5
+ ## Inputs (the router passes these in)
6
+
7
+ - The hydrated test cases (fetched once by the router before dispatch).
8
+ - Per-case `mode` — `replay` or `regen`, chosen during replay-vs-regen classification.
9
+ - `projectId`, `useCaseId`.
10
+
11
+ ## Ask for target URL
12
+
13
+ > "What's the preview/staging URL to test against?"
14
+
15
+ ## Trigger remote workflows (in parallel)
16
+
17
+ Branch each test case on its `mode`, then issue **all** workflow-start calls in parallel — never loop them sequentially. Mix regen and replay starts in the same parallel batch.
18
+
19
+ **Regen-mode test case** — `muggle-remote-workflow-start-test-script-generation`:
20
+
21
+ - `projectId`: The project ID
22
+ - `useCaseId`: The use case ID
23
+ - `testCaseId`: The test case ID
24
+ - `name`: `"muggle-test: {test case title}"`
25
+ - `url`: The preview/staging URL
26
+ - `goal`: From the test case
27
+ - `precondition`: From the test case (use `"None"` if empty)
28
+ - `instructions`: From the test case
29
+ - `expectedResult`: From the test case
30
+
31
+ **Replay-mode test case** — `muggle-remote-workflow-start-test-script-replay` against the latest replayable script for that test case (resolve via `muggle-remote-test-script-list` if not already in hand from the classification step). Tag results with `mode: "replay"` so the router routes failures correctly.
32
+
33
+ Store each returned workflow runtime ID along with its mode tag.
34
+
35
+ ## Monitor and report (in parallel)
36
+
37
+ Issue all `muggle-remote-wf-get-ts-gen-latest-run` calls in parallel, one per runtime ID.
38
+
39
+ ```
40
+ Test Case Workflow Status Runtime ID
41
+ ────────────────────────────────────────────────────────
42
+ Login with valid creds RUNNING rt-abc123
43
+ Login with invalid creds COMPLETED rt-def456
44
+ Checkout flow QUEUED rt-ghi789
45
+ ```
46
+
47
+ ## Output
48
+
49
+ Return the uniform runs list the router consumes: `[{ testCaseId, mode, runtimeId, status }]`.
@@ -23,9 +23,8 @@ Lookup material pulled out of `SKILL.md` to keep the always-loaded body lean. Ev
23
23
  | Execute (regen) | `muggle-remote-workflow-start-test-script-generation` | Remote |
24
24
  | Execute (replay) | `muggle-remote-workflow-start-test-script-replay` | Remote |
25
25
  | Failure-mode telemetry | `muggle-local-telemetry-event-emit` | Both |
26
- | Results | `muggle-local-run-result-get` | Local |
26
+ | Results + cloud refs (studio-published `viewUrl` / `cloudTestScriptId` / `cloudActionScriptId`) | `muggle-local-run-result-get` | Local |
27
27
  | Results | `muggle-remote-wf-get-ts-gen-latest-run`, `muggle-remote-wf-get-ts-replay-latest-run` | Remote |
28
- | Publish | `muggle-local-publish-test-script` | Local |
29
28
  | Per-step screenshots (for walkthrough) | `muggle-remote-test-script-get` | Both |
30
29
  | Browser | `open` (shell command) | Both |
31
30
  | PR walkthrough | `muggle-pr-visual-walkthrough` (shared skill) | Both |
@@ -12,7 +12,7 @@ description: Run a real-browser end-to-end (E2E) acceptance test against localho
12
12
  | Scope | MCP tools |
13
13
  | :---- | :-------- |
14
14
  | Cloud (projects, cases, scripts, auth) | `muggle-remote-*` |
15
- | Local (Electron run, publish, results) | `muggle-local-*` |
15
+ | Local (Electron run, results — the studio publishes during the run) | `muggle-local-*` |
16
16
  | Create new entities (preview / create) | `muggle-remote-project-create`, `muggle-remote-use-case-prompt-preview`, `muggle-remote-use-case-create-from-prompts`, `muggle-remote-test-case-generate-from-prompt`, `muggle-remote-test-case-create` |
17
17
 
18
18
  The local URL only changes where the browser opens; it does not change the remote project or test definitions.
@@ -158,11 +158,11 @@ Gate `showElectronBrowser` (per `preference-gates/README.md`). Reuse the choice
158
158
 
159
159
  `showUi` is only ever omitted or `false` — never pass `showUi: true`.
160
160
 
161
- ### 8. Upload run to cloud (every completed run; open `viewUrl` gated by `openTestResultsAfterRun`)
161
+ ### 8. Open the run on the dashboard (`viewUrl` gated by `openTestResultsAfterRun`)
162
162
 
163
- Upload pass-or-fail. Failed runs still need cloud-hosted screenshots and per-step actions for the PR walkthrough — without them reviewers see only a generic "failed" link. The `status` field in the upload payload tells the backend whether to promote the run's action script as the test case's canonical replay script (passed → promote; failed → record only).
163
+ The studio publishes every completed run — pass or fail — to the cloud during execution, so the run result already carries the cloud refs. Failed runs are published too, so reviewers get the per-step screenshots, not just a generic "failed" link.
164
164
 
165
- - Publish per [`../_shared/dev-loop/publish.md`](../_shared/dev-loop/publish.md) — includes the zero-step `muggle-remote-local-run-upload` fallback.
165
+ - Read the cloud refs per [`../_shared/dev-loop/publish.md`](../_shared/dev-loop/publish.md): `viewUrl` / `cloudTestScriptId` / `cloudActionScriptId` from `muggle-local-run-result-get`.
166
166
  - Gate `openTestResultsAfterRun` (per `preference-gates/README.md`):
167
167
  - `always` → open `viewUrl` automatically (`open "<viewUrl>"` on macOS or OS equivalent).
168
168
  - `never` → print the URL only.
@@ -172,24 +172,15 @@ Upload pass-or-fail. Failed runs still need cloud-hosted screenshots and per-ste
172
172
 
173
173
  Read the run record per [`../_shared/dev-loop/failures.md`](../_shared/dev-loop/failures.md) and [failure interpretation](../_shared/dev-loop/failures.md) — never diagnose from `execute`'s stdout tail.
174
174
 
175
- - Include in the report: status, duration, pass/fail summary, per-step summary (passed runs), artifact paths, errors if failed, and script view URL when publishing ran.
175
+ - Include in the report: status, duration, pass/fail summary, per-step summary (passed runs), artifact paths, errors if failed, and the `viewUrl` from the run result.
176
176
 
177
- ### 9a. Route failures through the failure-mode handler
177
+ ### 9a. Route a failed run through the debug path
178
178
 
179
- If the run's status is `failed` or any non-passing terminal state, follow [`_shared/failure-mode-handling.md`](../_shared/failure-mode-handling.md):
179
+ If the run's status is `failed` or any non-passing terminal state, route through [`_shared/debug-failed-run.md`](../_shared/debug-failed-run.md) — **mandatory**; a failure is never reported without it. It gathers evidence (attempted steps + reasoning + screenshot), diagnoses via [`_shared/failure-mode-handling.md`](../_shared/failure-mode-handling.md) (§B replay / §C regen), shows the debug card, and presents the guaranteed selection in which **"give feedback & rerun"** is always offered and "skip" is never the default.
180
180
 
181
- - **Replay-mode run failed** (the user picked an existing script in Step 5) → section B (buckets: `infra` / `stale-script` / `product-defect`).
182
- - **Regen-mode run failed** (the user picked "Generate new script" or no script existed) → section C (buckets: `transient` / `infra` / `agent-course` / `product-uxux`).
181
+ Pass it: the `runId`, the `mode` that failed (replay if the user picked an existing script in Step 5, else regen), `testCaseId`, `projectId`, and the local execution handle so a rerun re-enters the same path.
183
182
 
184
- Steps:
185
- 1. Read the run via `muggle-local-run-result-get` and extract signals per the heuristics in the shared doc.
186
- 2. Emit `replay-failure-classified` or `regen-failure-classified` via `muggle-local-telemetry-event-emit` **before** asking the user.
187
- 3. Present the recommended action via `AskUserQuestion` with the alternatives the shared doc lists for that bucket.
188
- 4. After the user picks, emit the matching `*-resolved` event with `userAction`.
189
-
190
- If the user picks `muggle-feedback` from any bucket's options, invoke the `muggle-feedback` skill via the `Skill` tool, passing the just-finished `runId` so the submit flow opens with this run preloaded.
191
-
192
- Skip silently when the run passed cleanly — failure-mode events are by definition about failures.
183
+ Skip only when the run passed cleanly — the debug path is by definition about failures.
193
184
 
194
185
  ### 9b. Remind the user to guide the agent (every Electron invocation)
195
186
 
@@ -1,7 +1,7 @@
1
1
  {
2
- "release": "5.0.3",
3
- "buildId": "run-51-1",
4
- "commitSha": "7285eaa7458b2a240299e20be18ba94590413f2e",
5
- "buildTime": "2026-06-09T19:26:19Z",
2
+ "release": "5.1.0",
3
+ "buildId": "run-53-1",
4
+ "commitSha": "3a0e7525c2c606afb9a64c2d78baffa5b400cf50",
5
+ "buildTime": "2026-06-11T20:57:59Z",
6
6
  "serviceName": "muggle-ai-works-mcp"
7
7
  }
@@ -1 +1 @@
1
- export { DEFAULT_PREFERENCES, PREFERENCES_FILE_NAME, PREFERENCES_PROJECT_DIR_NAME, PREFERENCES_SCHEMA, PREFERENCES_VERSION, PREFERENCE_ALLOWED_VALUES, PreferenceKey, PreferenceValue, buildElectronAppChecksumsUrl, buildElectronAppReleaseAssetUrl, buildElectronAppReleaseTag, calculateFileChecksum, createApiKeyWithToken, createChildLogger, deleteApiKeyData, deleteCredentials, e2e_exports as e2e, formatPreferencesOneLiner, getApiKey, getApiKeyFilePath, getAuthService, getBundledElectronAppVersion, getCallerCredentials, getCallerCredentialsAsync, getChecksumForPlatform, getConfig, getCredentialsFilePath, getDataDir, getDownloadBaseUrl, getElectronAppChecksums, getElectronAppDir, getElectronAppVersion, getElectronAppVersionSource, getLocalQaTools, getLogger, getPlatformKey, getQaTools, getValidApiKeyData, getValidCredentials, hasApiKey, isElectronAppInstalled, isFirstRun, loadApiKeyData, loadCredentials, local_exports as localQa, mcp_exports as mcp, openBrowserUrl, performLogin, performLogout, pollDeviceCode, e2e_exports as qa, readGlobalPreferences, readProjectPreferences, resetConfig, resetLogger, resetPreference, resolveElectronAppPathOrNull, resolvePreferences, saveApiKey, saveApiKeyData, saveCredentials, startDeviceCodeFlow, toolRequiresAuth, validatePreference, verifyFileChecksum, writePreferences } from './chunk-KDRSEHK5.js';
1
+ export { DEFAULT_PREFERENCES, PREFERENCES_FILE_NAME, PREFERENCES_PROJECT_DIR_NAME, PREFERENCES_SCHEMA, PREFERENCES_VERSION, PREFERENCE_ALLOWED_VALUES, PreferenceKey, PreferenceValue, buildElectronAppChecksumsUrl, buildElectronAppReleaseAssetUrl, buildElectronAppReleaseTag, calculateFileChecksum, createApiKeyWithToken, createChildLogger, deleteApiKeyData, deleteCredentials, e2e_exports as e2e, formatPreferencesOneLiner, getApiKey, getApiKeyFilePath, getAuthService, getBundledElectronAppVersion, getCallerCredentials, getCallerCredentialsAsync, getChecksumForPlatform, getConfig, getCredentialsFilePath, getDataDir, getDownloadBaseUrl, getElectronAppChecksums, getElectronAppDir, getElectronAppVersion, getElectronAppVersionSource, getLocalQaTools, getLogger, getPlatformKey, getQaTools, getValidApiKeyData, getValidCredentials, hasApiKey, isElectronAppInstalled, isFirstRun, loadApiKeyData, loadCredentials, local_exports as localQa, mcp_exports as mcp, openBrowserUrl, performLogin, performLogout, pollDeviceCode, e2e_exports as qa, readGlobalPreferences, readProjectPreferences, resetConfig, resetLogger, resetPreference, resolveElectronAppPathOrNull, resolvePreferences, saveApiKey, saveApiKeyData, saveCredentials, startDeviceCodeFlow, toolRequiresAuth, validatePreference, verifyFileChecksum, writePreferences } from './chunk-MOHR7QUN.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@muggleai/works",
3
3
  "mcpName": "io.github.multiplex-ai/muggle",
4
- "version": "5.0.3",
4
+ "version": "5.1.0",
5
5
  "description": "Ship quality products with AI-powered E2E acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
@@ -41,14 +41,14 @@
41
41
  "test:watch": "vitest"
42
42
  },
43
43
  "muggleConfig": {
44
- "electronAppVersion": "1.2.2",
44
+ "electronAppVersion": "1.4.0",
45
45
  "downloadBaseUrl": "https://github.com/multiplex-ai/muggle-ai-works/releases/download",
46
46
  "runtimeTargetDefault": "production",
47
47
  "checksums": {
48
- "darwin-arm64": "45c09f605d05fc72c60fae54847a689e1858aac9e2c4acca7f25c17a8cd1ad7b",
49
- "darwin-x64": "b662a57106f1d90c646180ac506d2f567bbbcea33b3fe5ecb9e83b8166426400",
50
- "linux-x64": "2f86a28e2dc9c7777710c31001686596ce36c560c93e93c53c9bcc4470c07be4",
51
- "win32-x64": "42f3f28e58efb207a0f2b4993cbc3f2232c30e20960b29b56a45e4c387777346"
48
+ "darwin-arm64": "9dd7ac0a378a1d5db908a102aec4f596741e943572a7d55b08e2a62f336981bc",
49
+ "darwin-x64": "70c9c6df21e03ad1529682e6cf8150ddfef306e1019e4b3bd2a4e7d025a98d64",
50
+ "linux-x64": "14ee27b3c22988bf72f13f3734e1594dcbb0fb94f699d5ad789ea8cf452dc7a1",
51
+ "win32-x64": "9e059917ba4605527b47d23b43bd78438cf59e7df38c4c9698f6b9487ed64a97"
52
52
  }
53
53
  },
54
54
  "dependencies": {
@@ -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": "5.0.3",
4
+ "version": "5.1.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": "5.0.3",
5
+ "version": "5.1.0",
6
6
  "author": {
7
7
  "name": "Muggle AI",
8
8
  "email": "support@muggle-ai.com"
@@ -104,7 +104,7 @@ if [ -f "$prefs_global_file" ]; then
104
104
  const defaults = {
105
105
  autoLogin:'ask', autoSelectProject:'ask', autoSelectLocalHost:'ask',
106
106
  showElectronBrowser:'ask', openTestResultsAfterRun:'ask',
107
- defaultExecutionMode:'ask', autoPublishLocalResults:'ask',
107
+ defaultExecutionMode:'ask',
108
108
  suggestRelatedUseCases:'ask', suggestRelatedTestCases:'ask', autoDetectChanges:'ask',
109
109
  postPRVisualWalkthrough:'ask', autoCreatePR:'ask',
110
110
  checkForUpdates:'ask', verboseOutput:'ask',
@@ -27,14 +27,16 @@ function markPrHandled(sessionId2, prUrl, dirOverride) {
27
27
 
28
28
  // src/guardrails/prOpened.ts
29
29
  var PR_URL = /https:\/\/github\.com\/[^/\s]+\/[^/\s]+\/pull\/\d+/;
30
+ var MR_URL = /https?:\/\/[^/\s]+\/[^\s]+\/-\/merge_requests\/\d+/;
30
31
  var CREATE_CMD = /\bgh\s+pr\s+(create|ready)\b/;
32
+ var MR_CREATE_CMD = /\bglab\s+mr\s+create\b|\bglab\s+mr\s+update\b.*--ready\b/;
31
33
  function detectPrOpened(input2) {
32
34
  if (input2.tool_name !== "Bash") return null;
33
35
  const cmd = input2.tool_input?.command ?? "";
34
- if (!CREATE_CMD.test(cmd)) return null;
36
+ if (!CREATE_CMD.test(cmd) && !MR_CREATE_CMD.test(cmd)) return null;
35
37
  const out = `${input2.tool_response?.stdout ?? ""}
36
38
  ${input2.tool_response?.output ?? ""}`;
37
- const m = out.match(PR_URL);
39
+ const m = out.match(PR_URL) ?? out.match(MR_URL);
38
40
  return m ? m[0] : null;
39
41
  }
40
42
 
@@ -0,0 +1,53 @@
1
+ # Debug a Failed Run — Shared Reference
2
+
3
+ > Presentation layer for a single failed run. Turns one non-passing terminal run — local or remote — into a debug path: **evidence → diagnosis → a guaranteed user choice that always offers "give feedback & rerun".** Used by `muggle-test` (Step 7C), `muggle-test-feature-local`, and the `muggle-do` e2e stage. Depends on [`failure-mode-handling.md`](./failure-mode-handling.md) for the bucket taxonomy and telemetry schema — never the reverse. Don't restate its tables; read them.
4
+
5
+ ## The guarantee
6
+
7
+ Every non-passing terminal run MUST route through this doc before it is reported. A failure is never summarized-and-dropped: the user is always shown *what happened* and is always presented a selection in which **"give feedback & rerun" is a first-class option**. "Skip — just report" stays selectable but is never the default.
8
+
9
+ The guarantee binds **interactive** callers. An autonomous caller with no user to prompt (the `acceptance-tester` agent) runs Steps 1–2 (evidence + diagnosis into its structured report) and skips Step 3's interactive offer.
10
+
11
+ ## Inputs (the caller passes these in)
12
+
13
+ - `runId` (local) or workflow runtime id (remote).
14
+ - `mode` — `replay` or `regen`, the mode that failed.
15
+ - `testCaseId`, `projectId`.
16
+ - A re-execute handle — the loop/tool the caller used to run this case, so a rerun re-enters the same execution path.
17
+
18
+ ## Step 1 — Gather evidence
19
+
20
+ Read **structured run fields**, never the `execute` stdout tail (see [`dev-loop/failures.md`](./dev-loop/failures.md)). Assemble:
21
+
22
+ - **Attempted steps + reasoning** — local: the attempted steps + `summaryStep` halt reason from `action-script.json` in `artifactsDir`; remote: the per-step list + `summaryStep` from `muggle-remote-wf-get-ts-gen-latest-run` / `muggle-remote-wf-get-ts-replay-latest-run`.
23
+ - **Visual evidence** — a failed run already preserves the full step-by-step on disk: every per-step frame under `<artifactsDir>/electron-runtime/screenshot/` (with per-step label data under `.../dataset/`), alongside the step script at `<artifactsDir>/action-script.json`. `run-result-get` returns `artifactsDir` — read the whole set there; don't trust a step's `screenshotLocalPath`, which points at the original runtime dir. Once published — failed runs are published too, see [`dev-loop/publish.md`](./dev-loop/publish.md) — the same frames are cloud-hosted per step as `screenshotUrl`, the form remote runs expose directly.
24
+ - **Verdict** — `Status` + `Error`.
25
+
26
+ ## Step 2 — Diagnose
27
+
28
+ Classify into the failure bucket per [`failure-mode-handling.md`](./failure-mode-handling.md) — §B for a replay failure, §C for a regen failure. That bucket **is** the initial diagnosis. Phrase it for a human ("Looks like a **stale script** — the selectors moved; the product itself probably still works"), not as a telemetry label. Emit the `replay-failure-classified` / `regen-failure-classified` event now, before presenting anything.
29
+
30
+ ## Step 3 — Present the debug card, then the guaranteed offer
31
+
32
+ Show the **debug card** first: attempted steps + reasoning, the failing step's screenshot (or a one-line note if a path is genuinely absent), and the one-line diagnosis.
33
+
34
+ Then present one `AskUserQuestion` whose options are:
35
+
36
+ 1. **Give feedback & rerun** — always present. Invoke the `muggle-feedback` skill with this run's anchor (`runId` local / `testScriptId` remote) so the user says what should have happened, then re-execute per Step 4.
37
+ 2. **The bucket's recommended action** from §B/§C (regenerate, report bug, share defect, retry…). Label it `(Recommended)` — it is the classifier's pick.
38
+ 3. **Retry as-is**.
39
+ 4. **Skip — just report** — last, never the default.
40
+
41
+ The bucket's recommended action and its alternatives live in `failure-mode-handling.md` §B/§C — read them there, don't restate them.
42
+
43
+ **Feedback anchor by lane.** Feedback attaches to a cloud action-script id. `muggle-feedback` owns resolving it: for a **local** run it publishes/uploads first when the run isn't already published; for a **remote** run it uses the existing script. Pass `runId` (local) or `testScriptId` (remote) and let it resolve the anchor — don't resolve or upload here.
44
+
45
+ ## Step 4 — Rerun (always regen)
46
+
47
+ On "give feedback & rerun": once `muggle-feedback` returns, re-execute the test case in **regen** mode — feedback adjusts the agent's course, so the prior script is discarded; replay is never the rerun path. Local: the regen branch of [`dev-loop/run.md`](./dev-loop/run.md). Remote: `muggle-remote-workflow-start-test-script-generation`. Read the new run's result back through this doc (Step 1) so a second failure is debugged too.
48
+
49
+ ## Step 5 — Resolve
50
+
51
+ Emit the `replay-failure-resolved` / `regen-failure-resolved` event with `userAction` set to the pick (`feedback-rerun`, the bucket action, `retry`, or `skip`) — one `*-classified` and one `*-resolved` per failure, per [`failure-mode-handling.md`](./failure-mode-handling.md) §D.
52
+
53
+ Process failures one at a time so the user isn't drowning in pickers.
@@ -1,13 +1,9 @@
1
- # Dev Loop — Publish & Screenshots
1
+ # Dev Loop — Cloud Refs & Screenshots
2
2
 
3
- ## Publish
3
+ ## Cloud refs
4
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.
5
+ The studio publishes every completed run — pass or fail — to the cloud during execution. There is no publish step to run. The run result already carries the cloud identifiers: read `viewUrl`, `cloudTestScriptId`, and `cloudActionScriptId` from `muggle-local-run-result-get` for the run. (`cloudTestScriptId` is absent for a failed generation — the backend records the action script and `viewUrl` but no test script.)
10
6
 
11
7
  ## Screenshots
12
8
 
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.
9
+ Per run, `muggle-remote-test-script-get` with the `cloudTestScriptId` from the run result → 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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  The address-reviews flow only acts on reviews submitted by users in the **allow-list** = (requested reviewers ∪ CODEOWNERS ∪ {PR author}) − bots. Re-resolve every invocation — never cache across cycles.
4
4
 
5
- The PR author is implicitly a valid reviewer: in single-account workflows, the human running the agent and the PR's author are the same identity, and the agent must honor their reviews. Self-loop is prevented at the watcher's filter layer rather than here: `POST /pulls/<n>/comments/<id>/replies` does create an implicit review under the loop user's identity, and the watcher drops it via the loop-echo clause in [`../github-cli-recipes/submitted-reviews.md`](../github-cli-recipes/submitted-reviews.md) — matched by the loop signature ([`loop-signature.md`](loop-signature.md)), so the author's *genuine* reviews and thread replies still get through. Including the PR author in this allow-list is therefore safe.
5
+ The PR author is implicitly a valid reviewer: in single-account workflows, the human running the agent and the PR's author are the same identity, and the agent must honor their reviews. Self-loop is prevented at the watcher's filter layer rather than here: `POST /pulls/<n>/comments/<id>/replies` does create an implicit review under the loop user's identity, and the watcher drops it via the loop-echo clause in [`../vcs/github/submitted-reviews.md`](../vcs/github/submitted-reviews.md) — matched by the loop signature ([`loop-signature.md`](loop-signature.md)), so the author's *genuine* reviews and thread replies still get through. Including the PR author in this allow-list is therefore safe.
6
6
 
7
7
  ## Step 1: requested reviewers
8
8