@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.
- package/README.md +2 -3
- package/dist/{chunk-XO5BQZM3.js → chunk-2BHC6TQR.js} +3 -4
- package/dist/{chunk-KDRSEHK5.js → chunk-MOHR7QUN.js} +197 -291
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/.cursor-plugin/plugin.json +1 -1
- package/dist/plugin/scripts/ensure-electron-app.sh +1 -1
- package/dist/plugin/scripts/guardrails.mjs +4 -2
- package/dist/plugin/skills/_shared/debug-failed-run.md +53 -0
- package/dist/plugin/skills/_shared/dev-loop/publish.md +4 -8
- package/dist/plugin/skills/_shared/pr-followup-helpers/allow-list.md +1 -1
- package/dist/plugin/skills/_shared/pr-followup-helpers/echo-skip.md +1 -1
- package/dist/plugin/skills/_shared/resolve-e2e-validation-context.md +1 -1
- package/dist/plugin/skills/_shared/telemetry-events/pr-followup-tick.md +1 -1
- package/dist/plugin/skills/_shared/test-case-chain-readiness.md +1 -2
- package/dist/plugin/skills/_shared/vcs/CLAUDE.md +9 -0
- package/dist/plugin/skills/_shared/vcs/detect-vcs.md +28 -0
- package/dist/plugin/skills/_shared/vcs/github/pr-metadata.md +25 -0
- package/{plugin/skills/_shared/github-cli-recipes → dist/plugin/skills/_shared/vcs/github}/unresolved-threads.md +1 -1
- package/{plugin/skills/_shared/github-cli-recipes → dist/plugin/skills/_shared/vcs/github}/verify-working-tree.md +1 -1
- package/dist/plugin/skills/_shared/vcs/github.md +21 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/loop-user-identity.md +9 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-create.md +11 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-discussions.md +18 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-edit.md +8 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-metadata.md +22 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-note.md +7 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/mr-pipeline.md +27 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/reply-discussion.md +9 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/resolve-discussion.md +10 -0
- package/dist/plugin/skills/_shared/vcs/gitlab/unresolved-discussions.md +18 -0
- package/dist/plugin/skills/_shared/vcs/gitlab.md +24 -0
- package/dist/plugin/skills/do/address-reviews.md +10 -6
- package/dist/plugin/skills/do/e2e-acceptance.md +6 -4
- package/dist/plugin/skills/do/fix-ci.md +1 -1
- package/dist/plugin/skills/do/input-routing.md +4 -4
- package/dist/plugin/skills/do/open-prs/forward.md +6 -4
- package/dist/plugin/skills/do/open-prs/update.md +8 -6
- package/dist/plugin/skills/do/per-comment-replies.md +22 -13
- package/dist/plugin/skills/do/resolve-conflicts.md +1 -1
- package/dist/plugin/skills/do/resolve-reminder.md +8 -6
- package/dist/plugin/skills/muggle-browser-task/SKILL.md +1 -1
- package/dist/plugin/skills/muggle-do/SKILL.md +2 -2
- package/dist/plugin/skills/muggle-feedback/ops/submit.md +4 -4
- package/dist/plugin/skills/muggle-pr-followup/CLAUDE.md +2 -2
- package/dist/plugin/skills/muggle-pr-followup/bootstrap.md +13 -11
- package/dist/plugin/skills/muggle-pr-followup/contract.md +18 -12
- package/dist/plugin/skills/muggle-pr-followup/finalize.md +1 -1
- package/dist/plugin/skills/muggle-pr-followup/reconcile.md +1 -1
- package/dist/plugin/skills/muggle-pr-followup/state-schemas.md +4 -1
- package/dist/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +13 -13
- package/dist/plugin/skills/muggle-preferences/ops/configure.md +2 -2
- package/dist/plugin/skills/muggle-test/SKILL.md +30 -143
- package/dist/plugin/skills/muggle-test/execute-local.md +60 -0
- package/dist/plugin/skills/muggle-test/execute-remote.md +49 -0
- package/dist/plugin/skills/muggle-test/reference.md +1 -2
- package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +9 -18
- package/dist/release-manifest.json +4 -4
- package/dist/{src-2O5UH4FA.js → src-SS2AL3O7.js} +1 -1
- package/package.json +6 -6
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/scripts/ensure-electron-app.sh +1 -1
- package/plugin/scripts/guardrails.mjs +4 -2
- package/plugin/skills/_shared/debug-failed-run.md +53 -0
- package/plugin/skills/_shared/dev-loop/publish.md +4 -8
- package/plugin/skills/_shared/pr-followup-helpers/allow-list.md +1 -1
- package/plugin/skills/_shared/pr-followup-helpers/echo-skip.md +1 -1
- package/plugin/skills/_shared/resolve-e2e-validation-context.md +1 -1
- package/plugin/skills/_shared/telemetry-events/pr-followup-tick.md +1 -1
- package/plugin/skills/_shared/test-case-chain-readiness.md +1 -2
- package/plugin/skills/_shared/vcs/CLAUDE.md +9 -0
- package/plugin/skills/_shared/vcs/detect-vcs.md +28 -0
- package/plugin/skills/_shared/vcs/github/pr-metadata.md +25 -0
- package/{dist/plugin/skills/_shared/github-cli-recipes → plugin/skills/_shared/vcs/github}/unresolved-threads.md +1 -1
- package/{dist/plugin/skills/_shared/github-cli-recipes → plugin/skills/_shared/vcs/github}/verify-working-tree.md +1 -1
- package/plugin/skills/_shared/vcs/github.md +21 -0
- package/plugin/skills/_shared/vcs/gitlab/loop-user-identity.md +9 -0
- package/plugin/skills/_shared/vcs/gitlab/mr-create.md +11 -0
- package/plugin/skills/_shared/vcs/gitlab/mr-discussions.md +18 -0
- package/plugin/skills/_shared/vcs/gitlab/mr-edit.md +8 -0
- package/plugin/skills/_shared/vcs/gitlab/mr-metadata.md +22 -0
- package/plugin/skills/_shared/vcs/gitlab/mr-note.md +7 -0
- package/plugin/skills/_shared/vcs/gitlab/mr-pipeline.md +27 -0
- package/plugin/skills/_shared/vcs/gitlab/reply-discussion.md +9 -0
- package/plugin/skills/_shared/vcs/gitlab/resolve-discussion.md +10 -0
- package/plugin/skills/_shared/vcs/gitlab/unresolved-discussions.md +18 -0
- package/plugin/skills/_shared/vcs/gitlab.md +24 -0
- package/plugin/skills/do/address-reviews.md +10 -6
- package/plugin/skills/do/e2e-acceptance.md +6 -4
- package/plugin/skills/do/fix-ci.md +1 -1
- package/plugin/skills/do/input-routing.md +4 -4
- package/plugin/skills/do/open-prs/forward.md +6 -4
- package/plugin/skills/do/open-prs/update.md +8 -6
- package/plugin/skills/do/per-comment-replies.md +22 -13
- package/plugin/skills/do/resolve-conflicts.md +1 -1
- package/plugin/skills/do/resolve-reminder.md +8 -6
- package/plugin/skills/muggle-browser-task/SKILL.md +1 -1
- package/plugin/skills/muggle-do/SKILL.md +2 -2
- package/plugin/skills/muggle-feedback/ops/submit.md +4 -4
- package/plugin/skills/muggle-pr-followup/CLAUDE.md +2 -2
- package/plugin/skills/muggle-pr-followup/bootstrap.md +13 -11
- package/plugin/skills/muggle-pr-followup/contract.md +18 -12
- package/plugin/skills/muggle-pr-followup/finalize.md +1 -1
- package/plugin/skills/muggle-pr-followup/reconcile.md +1 -1
- package/plugin/skills/muggle-pr-followup/state-schemas.md +4 -1
- package/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +13 -13
- package/plugin/skills/muggle-preferences/ops/configure.md +2 -2
- package/plugin/skills/muggle-test/SKILL.md +30 -143
- package/plugin/skills/muggle-test/execute-local.md +60 -0
- package/plugin/skills/muggle-test/execute-remote.md +49 -0
- package/plugin/skills/muggle-test/reference.md +1 -2
- package/plugin/skills/muggle-test-feature-local/SKILL.md +9 -18
- package/dist/plugin/skills/_shared/github-cli-recipes/pr-metadata.md +0 -13
- package/dist/plugin/skills/_shared/github-cli-recipes.md +0 -21
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +0 -11
- package/plugin/skills/_shared/github-cli-recipes/pr-metadata.md +0 -13
- package/plugin/skills/_shared/github-cli-recipes.md +0 -21
- package/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +0 -11
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/line-comments-for-review.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/loop-user-identity.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/pr-checks.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/pr-edit.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/push-to-branch.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/reply-line-comment.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/submitted-reviews.md +0 -0
- /package/dist/plugin/skills/_shared/{github-cli-recipes → vcs/github}/top-level-comment.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/line-comments-for-review.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/loop-user-identity.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/pr-checks.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/pr-edit.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/push-to-branch.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/reply-line-comment.md +0 -0
- /package/plugin/skills/_shared/{github-cli-recipes → vcs/github}/submitted-reviews.md +0 -0
- /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,
|
|
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` |
|
|
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
|
-
| `
|
|
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
|
|
237
|
+
## Step 7: Execute
|
|
239
238
|
|
|
240
|
-
###
|
|
239
|
+
### Fetch test case details (both modes)
|
|
241
240
|
|
|
242
|
-
|
|
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
|
-
###
|
|
243
|
+
### Dispatch by mode
|
|
245
244
|
|
|
246
|
-
|
|
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
|
-
|
|
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
|
-
|
|
250
|
+
## Step 7C: Route every failed run through the debug path
|
|
254
251
|
|
|
255
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
366
|
-
```bash
|
|
367
|
-
open "https://www.muggle-ai.com/muggleTestV0/dashboard/projects/{projectId}/scripts?modal=script-details&testCaseId={testCaseId}"
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
413
|
-
- **Yes — give feedback** → invoke the `muggle-feedback` skill via the `Skill` tool
|
|
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
|
-
|
|
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
|
-
- **
|
|
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,
|
|
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.
|
|
161
|
+
### 8. Open the run on the dashboard (`viewUrl` gated by `openTestResultsAfterRun`)
|
|
162
162
|
|
|
163
|
-
|
|
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
|
-
-
|
|
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
|
|
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
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
"buildId": "run-
|
|
4
|
-
"commitSha": "
|
|
5
|
-
"buildTime": "2026-06-
|
|
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-
|
|
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
|
|
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.
|
|
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": "
|
|
49
|
-
"darwin-x64": "
|
|
50
|
-
"linux-x64": "
|
|
51
|
-
"win32-x64": "
|
|
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
|
|
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
|
|
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',
|
|
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 —
|
|
1
|
+
# Dev Loop — Cloud Refs & Screenshots
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Cloud refs
|
|
4
4
|
|
|
5
|
-
|
|
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
|
|
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
|
|
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
|
|