@muggleai/works 4.9.2 → 4.10.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 (56) hide show
  1. package/dist/{chunk-6N7OIBAS.js → chunk-RK6XKSZK.js} +2 -2
  2. package/dist/{chunk-4KQZLF56.js → chunk-UVXOHXY2.js} +182 -20
  3. package/dist/cli.js +2 -2
  4. package/dist/index.js +2 -2
  5. package/dist/plugin/.claude-plugin/plugin.json +1 -1
  6. package/dist/plugin/.cursor-plugin/plugin.json +1 -1
  7. package/dist/plugin/scripts/ensure-electron-app.sh +24 -1
  8. package/dist/plugin/skills/muggle/SKILL.md +3 -12
  9. package/dist/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +5 -12
  10. package/dist/plugin/skills/muggle-preferences/SKILL.md +85 -44
  11. package/dist/plugin/skills/muggle-preferences/preference-gates/README.md +58 -0
  12. package/dist/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +11 -0
  13. package/dist/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +11 -0
  14. package/dist/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +11 -0
  15. package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +17 -0
  16. package/dist/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +11 -0
  17. package/dist/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +15 -0
  18. package/dist/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +11 -0
  19. package/dist/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +30 -0
  20. package/dist/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +11 -0
  21. package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +11 -0
  22. package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +11 -0
  23. package/dist/plugin/skills/muggle-preferences/preference-gates/verboseOutput.md +8 -0
  24. package/dist/plugin/skills/muggle-status/SKILL.md +9 -14
  25. package/dist/plugin/skills/muggle-test/SKILL.md +56 -55
  26. package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +35 -36
  27. package/dist/plugin/skills/muggle-test-import/SKILL.md +58 -24
  28. package/dist/plugin/skills/muggle-test-regenerate-missing/SKILL.md +20 -22
  29. package/dist/release-manifest.json +4 -4
  30. package/dist/src-GD3YFCCW.js +1 -0
  31. package/package.json +2 -2
  32. package/plugin/.claude-plugin/plugin.json +1 -1
  33. package/plugin/.cursor-plugin/plugin.json +1 -1
  34. package/plugin/scripts/ensure-electron-app.sh +24 -1
  35. package/plugin/skills/muggle/SKILL.md +3 -12
  36. package/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +5 -12
  37. package/plugin/skills/muggle-preferences/SKILL.md +85 -44
  38. package/plugin/skills/muggle-preferences/preference-gates/README.md +58 -0
  39. package/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +11 -0
  40. package/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +11 -0
  41. package/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +11 -0
  42. package/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +17 -0
  43. package/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +11 -0
  44. package/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +15 -0
  45. package/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +11 -0
  46. package/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +30 -0
  47. package/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +11 -0
  48. package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +11 -0
  49. package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +11 -0
  50. package/plugin/skills/muggle-preferences/preference-gates/verboseOutput.md +8 -0
  51. package/plugin/skills/muggle-status/SKILL.md +9 -14
  52. package/plugin/skills/muggle-test/SKILL.md +56 -55
  53. package/plugin/skills/muggle-test-feature-local/SKILL.md +35 -36
  54. package/plugin/skills/muggle-test-import/SKILL.md +58 -24
  55. package/plugin/skills/muggle-test-regenerate-missing/SKILL.md +20 -22
  56. package/dist/src-7GB7WIFT.js +0 -1
@@ -0,0 +1,15 @@
1
+ # `defaultExecutionMode` (`local` / `remote` / `ask`)
2
+
3
+ Default place to run tests when the user's request is ambiguous.
4
+
5
+ **Picker 1** — header `Where to run tests?`, question `"On your computer or in the cloud?"`
6
+ - `On my computer` — `Real browser on localhost. Faster feedback while developing.` → `local`
7
+ - `In the cloud` — `Muggle's cloud runs against a preview/staging URL.` → `remote`
8
+
9
+ If the user's intent is already clear (e.g. "test on staging"), skip Picker 1
10
+ — confirm with `"Yes, proceed in <mode>"` / `"Switch to <other mode>"` and
11
+ skip Picker 2.
12
+
13
+ **Silent action**
14
+ - `local` → `Running on your computer`
15
+ - `remote` → `Running in the cloud`
@@ -0,0 +1,11 @@
1
+ # `openTestResultsAfterRun`
2
+
3
+ Auto-open the dashboard after a run, or just print the URL.
4
+
5
+ **Picker 1** — header `After the run`, question `"Open the test results in your browser when this finishes?"`
6
+ - `Open the dashboard` — `See screenshots, step details, and pass/fail at a glance.` → `always`
7
+ - `Just print the link` — `Skip auto-open — I'll just hand you the URL.` → `never`
8
+
9
+ **Silent action**
10
+ - `always` → `Opening results on the dashboard`
11
+ - `never` → `Just printing the link — no auto-open`
@@ -0,0 +1,30 @@
1
+ # `postPRVisualWalkthrough`
2
+
3
+ Post a visual walkthrough of test results to a PR.
4
+
5
+ **PR detection (mandatory before any picker).** Run `gh pr view --json number,title,url 2>/dev/null` first. The result picks Case A or B.
6
+ Substitute `{prNumber}`, `{prTitle}` into prompts.
7
+
8
+ ## Case A — open PR found
9
+
10
+ **Picker 1** — header `Share with the team`, question `"Post a visual walkthrough to PR #{prNumber} ({prTitle})?"`
11
+ - `Yes, post to #{prNumber}` — `Reviewers see clickable per-test screenshots and dashboard links.` → `always`
12
+ - `Skip` — `Keep it off the PR — you can post later from the dashboard.` → `never`
13
+
14
+ **Silent action (Case A)**
15
+ - `always` → `Posting walkthrough to PR #{prNumber}`
16
+ - `never` → `Skipping PR walkthrough for #{prNumber}`
17
+
18
+ ## Case B — no open PR
19
+
20
+ Situational fork — saved value is *not* updated from this picker.
21
+
22
+ **Picker 1** — header `No PR yet`, question `"This branch has no open PR. Create one and post the walkthrough, or skip?"`
23
+ - `Create a PR and post` — `I'll open a PR for this branch, then attach the walkthrough.` → run PR-creation flow (calling skill's responsibility), then post.
24
+ - `Skip` — `Skip the walkthrough this time — you can post later from the dashboard.` → continue.
25
+
26
+ **Picker 2** — skipped entirely.
27
+
28
+ **Silent action (Case B)** — when saved gate is `always` or `never` but no PR exists:
29
+ - `always` → fall through to Case B Picker 1 (don't auto-create silently). Print: `(`postPRVisualWalkthrough = always`, but this branch has no PR — asking what to do.)`
30
+ - `never` → `Skipping PR walkthrough — no open PR for this branch`
@@ -0,0 +1,11 @@
1
+ # `showElectronBrowser`
2
+
3
+ Show the Electron browser during local tests, or run hidden.
4
+
5
+ **Picker 1** — header `Browser window`, question `"Show the test browser as it runs?"`
6
+ - `Show it` — `Watch the test live — useful when something's failing.` → `always` (omit `showUi`)
7
+ - `Run hidden` — `Skip watching — let it run in the background while you do other things.` → `never` (pass `showUi: false`)
8
+
9
+ **Silent action**
10
+ - `always` → `Showing the browser`
11
+ - `never` → `Running hidden`
@@ -0,0 +1,11 @@
1
+ # `suggestRelatedTestCases`
2
+
3
+ After creating/running a test case, surface related ones already attached to the use case.
4
+
5
+ **Picker 1** — header `Related test cases`, question `"Surface related test cases already attached to this use case?"`
6
+ - `Yes, suggest related` — `Catch test cases your import or change might have missed.` → `always`
7
+ - `No, skip` — `Don't show suggestions — I'll ask if I want them later.` → `never`
8
+
9
+ **Silent action**
10
+ - `always` → `Showing related test cases below`
11
+ - `never` → `Skipping test case suggestions`
@@ -0,0 +1,11 @@
1
+ # `suggestRelatedUseCases`
2
+
3
+ After creating/running a use case, surface related ones already in the project.
4
+
5
+ **Picker 1** — header `Related use cases`, question `"Surface related use cases already in this project?"`
6
+ - `Yes, suggest related` — `Catch use cases your import or change might have missed.` → `always`
7
+ - `No, skip` — `Don't show suggestions — I'll ask if I want them later.` → `never`
8
+
9
+ **Silent action**
10
+ - `always` → `Showing related use cases below`
11
+ - `never` → `Skipping use case suggestions`
@@ -0,0 +1,8 @@
1
+ # `verboseOutput`
2
+
3
+ Show detailed progress logs during execution.
4
+
5
+ **Not gated.** This is a UX-only knob — no Picker 1, no silent footer.
6
+ Skills read the saved value from session context and adjust their log
7
+ verbosity. The `muggle-preferences` skill exposes it through Configure
8
+ and Set so users can change it.
@@ -9,20 +9,11 @@ Run a full health check and report results.
9
9
 
10
10
  ## Preferences
11
11
 
12
- User preferences are available in the session context (injected at session start). Look for the line starting with `Muggle Preferences` — it contains key=value pairs like `autoLogin=ask showElectronBrowser=always ...`.
12
+ Gates run per `preference-gates/README.md`.
13
13
 
14
- If no preferences line is present, treat all preferences as `"ask"`.
15
-
16
- When you reach a decision gated by a preference:
17
- - **`always`** → proceed without asking the user
18
- - **`never`** → skip without asking the user
19
- - **`ask`** → ask the user, then offer: "Want me to remember this choice for future sessions?" If yes, call `muggle-local-preferences-set` with the key, their chosen value, and scope `global`.
20
-
21
- This skill uses these preferences:
22
-
23
- | Preference | Decision it gates |
24
- |------------|------------------|
25
- | `checkForUpdates` | Check for newer Muggle version |
14
+ | Preference | Step | Decision it gates |
15
+ |------------|------|-------------------|
16
+ | `checkForUpdates` | Check 4 | Check for newer Muggle version |
26
17
 
27
18
  ## Checks
28
19
 
@@ -32,7 +23,11 @@ This skill uses these preferences:
32
23
 
33
24
  3. **Authentication** — call `muggle-remote-auth-status`. Report whether credentials are valid and when they expire.
34
25
 
35
- 4. **CLI version** — capture installed (`muggle --version`) and latest (`npm view @muggleai/works version`). Compare with `sort -V`; flag as out-of-date only when latest is strictly greater.
26
+ 4. **CLI version** — gate `checkForUpdates` (per `preference-gates/README.md`):
27
+ - Pro-action: run the check below.
28
+ - Skip-action: render the row as `[skip] check disabled by preference`.
29
+
30
+ When the check runs: capture installed (`muggle --version`) and latest (`npm view @muggleai/works version`). Compare with `sort -V`; flag as out-of-date only when latest is strictly greater.
36
31
 
37
32
  ## Output
38
33
 
@@ -34,25 +34,17 @@ Every test case verifies exactly **one** user-observable behavior. Never bundle
34
34
 
35
35
  ## Preferences
36
36
 
37
- User preferences are available in the session context (injected at session start). Look for the line starting with `Muggle Preferences` — it contains key=value pairs like `autoLogin=ask showElectronBrowser=always ...`.
38
-
39
- If no preferences line is present, treat all preferences as `"ask"`.
40
-
41
- When you reach a decision gated by a preference:
42
- - **`always`** → proceed without asking the user
43
- - **`never`** → skip without asking the user
44
- - **`ask`** → ask the user, then offer: "Want me to remember this choice for future sessions?" If yes, call `muggle-local-preferences-set` with the key, their chosen value, and scope `global`.
45
-
46
- This skill uses these preferences:
47
-
48
- | Preference | Decision it gates |
49
- |------------|------------------|
50
- | `autoLogin` | Reuse saved credentials when auth is required |
51
- | `autoSelectProject` | Reuse last-used Muggle project for this repo |
52
- | `autoDetectChanges` | Scan local git changes and map to affected test cases |
53
- | `defaultExecutionMode` | Default to local or remote test execution |
54
- | `autoPublishLocalResults` | Upload local results to Muggle cloud after run |
55
- | `postPRVisualWalkthrough` | Post visual walkthrough to PR after results are available |
37
+ Gates run per `preference-gates/README.md`.
38
+
39
+ | Preference | Step | Decision it gates |
40
+ |------------|------|-------------------|
41
+ | `autoLogin` | 3 | Reuse saved credentials when auth is required |
42
+ | `autoSelectProject` | 4 | Reuse last-used Muggle project for this repo |
43
+ | `autoDetectChanges` | 2 | Scan local git changes and map to affected test cases |
44
+ | `defaultExecutionMode` | 1 | Default to local or remote test execution |
45
+ | `autoPublishLocalResults` | 7A | Upload local results to Muggle cloud after run |
46
+ | `showElectronBrowser` | 7A | Show the Electron browser window during local test execution (vs. run headless) |
47
+ | `postPRVisualWalkthrough` | 9 | Post visual walkthrough to PR after results are available |
56
48
 
57
49
  ## Step 1: Confirm Scope of Work (Always First)
58
50
 
@@ -72,19 +64,23 @@ Signs the user wants this: mentions "localhost", "local", "my machine", "dev ser
72
64
 
73
65
  Signs the user wants this: mentions "preview", "staging", "deployed", "preview URL", "test on preview", "test the deployment", or provides a non-localhost URL.
74
66
 
75
- ### Confirming
67
+ ### Confirming (gated by `defaultExecutionMode`)
68
+
69
+ Gate `defaultExecutionMode` (per `preference-gates/README.md`). Uses `local`/`remote`/`ask`.
70
+ - `local` → proceed in Local mode.
71
+ - `remote` → proceed in Remote mode.
72
+ - `ask` + intent clear → skip Picker 1, confirm one-shot then skip Picker 2.
73
+ - `ask` + ambiguous → run Picker 1 from gate file.
76
74
 
77
- If the user's intent is clear, state back what you understood and use `AskQuestion` to confirm:
78
- - Option 1: "Yes, proceed"
79
- - Option 2: "Switch to [the other mode]"
75
+ Only proceed after selection.
80
76
 
81
- If ambiguous, use `AskQuestion` to let the user choose:
82
- - Option 1: "On my computer — test your localhost dev server in a browser on your machine"
83
- - Option 2: "In the cloud — test remotely targeting your deployed preview/staging URL"
77
+ ## Step 2: Detect Local Changes (gated by `autoDetectChanges`)
84
78
 
85
- Only proceed after the user selects an option.
79
+ Gate `autoDetectChanges` (per `preference-gates/README.md`):
80
+ - Pro-action: run the scan and proceed to analysis below.
81
+ - Skip-action: ask "What would you like to test?" then jump to Step 3.
86
82
 
87
- ## Step 2: Detect Local Changes
83
+ ### Analysis (when scan is enabled)
88
84
 
89
85
  Analyze the working directory to understand what changed.
90
86
 
@@ -104,36 +100,35 @@ If no changes detected (clean tree), tell the user and ask what they want to tes
104
100
  ## Step 3: Authenticate
105
101
 
106
102
  1. Call `muggle-remote-auth-status`
107
- 2. If **authenticated and not expired** → print the logged-in email and ask via `AskQuestion`:
108
- > "You're logged in as **{email}**. Continue with this account?"
109
- - Option 1: "Yes, continue"
110
- - Option 2: "No, switch account"
111
- If the user picks "switch account", call `muggle-remote-auth-login` with `forceNewSession: true`, then `muggle-remote-auth-poll`.
103
+ 2. If **authenticated and not expired** → gate `autoLogin` (per `preference-gates/README.md`):
104
+ - Pro-action: reuse saved session.
105
+ - Skip-action: `muggle-remote-auth-login` with `forceNewSession: true`, then `muggle-remote-auth-poll`.
112
106
  3. If **not authenticated or expired** → call `muggle-remote-auth-login`
113
107
  4. If login pending → call `muggle-remote-auth-poll`
114
108
 
115
109
  If auth fails repeatedly, suggest: `muggle logout && muggle login` from terminal.
116
110
 
117
- ## Step 4: Select Project (User Must Choose)
111
+ ## Step 4: Select Project (gated by `autoSelectProject`)
118
112
 
119
113
  A **project** is where all your test results, use cases, and test scripts are grouped on the Muggle AI dashboard. Pick the project that matches what you're working on.
120
114
 
121
- 1. Call `muggle-remote-project-list`
122
- 2. Use `AskQuestion` to present all projects as clickable options. Include the project URL in each label so the user can identify the right one. Always include a "Create new project" option at the end.
115
+ The per-repo cache lives at `<cwd>/.muggle-ai/last-project.json` (managed via the `muggle-local-last-project-get` / `muggle-local-last-project-set` MCP tools). Look for the `Muggle Last Project: id=… url=… name="…"` line in session context — if present, that's this repo's cached pick.
123
116
 
124
- Example labels:
125
- - "MUGGLE AI STAGING 1 — https://staging.muggle-ai.com/"
126
- - "Tanka Testing — https://www.tanka.ai"
127
- - "Create new project"
117
+ Gate `autoSelectProject` (per `preference-gates/README.md`). Cache: `Muggle Last Project` session line.
118
+ - `always` + cache → use cached `projectId`, skip to Step 5. No cache → fall through to `ask`.
119
+ - `never` → full project list; skip Picker 2.
120
+ - `ask` → project list picker (see gate file for spec + Picker 2 override). Skip Picker 2 if "Create new project".
128
121
 
129
- Prompt: "Pick the project to group this test run into:"
122
+ ### Logic
130
123
 
131
- 3. **Wait for the user to explicitly choose** — do NOT auto-select based on repo name or URL matching
124
+ 1. Resolve the chosen project per the gate above.
125
+ 2. Call `muggle-remote-project-list` only when the gate doesn't already give a `projectId` from the cache.
126
+ 3. **Wait for the user to explicitly choose** when presenting the picker — do NOT auto-select based on repo name or URL matching.
132
127
  4. **If user chooses "Create new project"**:
133
128
  - Ask for `projectName`, `description`, and the production/preview URL
134
129
  - Call `muggle-remote-project-create`
135
130
 
136
- Store the `projectId` only after user confirms.
131
+ Store the `projectId` only after user confirms (or after silent reuse from the cache).
137
132
 
138
133
  ## Step 5: Select Use Case (Best-Effort Shortlist)
139
134
 
@@ -216,7 +211,11 @@ Try to auto-detect the dev server URL by checking running terminals or common po
216
211
 
217
212
  If nothing detected, ask as free text: "Your local app should be running. What's the URL? (e.g., http://localhost:3000)"
218
213
 
219
- **No separate approval or visibility question.** The user picking Local mode in Step 1 *is* the approval — do not ask "ready to launch Electron?" before every run. The Electron browser defaults to visible; if the user wants headless, they will say so, otherwise let it run visible.
214
+ ### Pre-flight visibility (gated by `showElectronBrowser`)
215
+
216
+ Gate `showElectronBrowser` (per `preference-gates/README.md`). Resolve once; apply same `showUi` to every test case.
217
+ - Pro-action: omit `showUi` (defaults visible).
218
+ - Skip-action: pass `showUi: false`.
220
219
 
221
220
  ### Fetch test case details (in parallel)
222
221
 
@@ -240,7 +239,7 @@ Execution itself **must** be sequential because there is only one local Electron
240
239
  1. Call `muggle-local-execute-test-generation`:
241
240
  - `testCase`: Full test case object from the parallel fetch above
242
241
  - `localUrl`: User's local URL from the pre-flight question
243
- - `showUi`: omit (default visible) unless the user explicitly asked for headless, then pass `false`
242
+ - `showUi`: from the `showElectronBrowser` resolution — omit (default visible) for `always`, pass `false` for `never`
244
243
  - `freshSession`: `true` if the test case requires a clean browser state (see above), omit otherwise
245
244
  2. Store the returned `runId`
246
245
 
@@ -250,7 +249,13 @@ If a generation fails, log it and continue to the next. Do not abort the batch.
250
249
 
251
250
  For every `runId`, issue all `muggle-local-run-result-get` calls in parallel. Extract: status, duration, step count, `artifactsDir`.
252
251
 
253
- ### Publish each run to cloud (in parallel)
252
+ ### Publish each run to cloud (gated by `autoPublishLocalResults`)
253
+
254
+ Gate `autoPublishLocalResults` (per `preference-gates/README.md`):
255
+ - Pro-action: proceed to publish logic below.
256
+ - Skip-action: skip to report summary; tell user Steps 8/9 and per-step screenshots are unavailable without publishing.
257
+
258
+ ### Publish logic (when publishing is enabled)
254
259
 
255
260
  For every completed run, issue all `muggle-local-publish-test-script` calls in parallel (single message, multiple tool calls):
256
261
  - `runId`: The local run ID
@@ -377,18 +382,15 @@ Assemble the report:
377
382
 
378
383
  See the shared skill for the full schema (including the failed-test shape with `failureStepIndex` and `error`).
379
384
 
380
- ### 9b: Ask the user
381
-
382
- Use `AskQuestion`:
383
-
384
- > "Post a visual walkthrough of these results to the PR? Reviewers can click each test case to see step-by-step screenshots on the Muggle AI dashboard."
385
+ ### 9b: Detect the PR, then apply the `postPRVisualWalkthrough` gate
385
386
 
386
- - Option 1: "Yes, post to PR"
387
- - Option 2: "Skip"
387
+ Run `gh pr view --json number,title,url 2>/dev/null` first (mandatory — gate uses the result). Then gate `postPRVisualWalkthrough` (per `preference-gates/README.md` + gate file for two-case Picker 1):
388
+ - **Case A (PR found)** — `always` → proceed to 9c; `never`/skip → stop.
389
+ - **Case B (no PR)** — always run Picker 1 regardless of saved value; "Create a PR and post" → create PR then proceed to 9c; "Skip" → stop.
388
390
 
389
391
  ### 9c: Invoke the shared skill in Mode A
390
392
 
391
- If the user chooses "Yes, post to PR", invoke the `muggle-pr-visual-walkthrough` skill via the `Skill` tool. With the `E2eReport` already in context, the skill will:
393
+ If 9b resolved to "post" (either via `postPRVisualWalkthrough = always` or the user picking "Yes, post to PR"), invoke the `muggle-pr-visual-walkthrough` skill via the `Skill` tool. With the `E2eReport` already in context, the skill will:
392
394
 
393
395
  1. Call `muggle build-pr-section` to render the markdown block (fit-vs-overflow automatic)
394
396
  2. Find the PR via `gh pr view`
@@ -434,7 +436,6 @@ This skill always uses **Mode A** (post to an existing PR); `muggle-do` is the o
434
436
  - **One atomic behavior per test case** — every test case verifies exactly one user-observable behavior. Never bundle signup/login/navigation/bootstrap/teardown into a test case body. Ordering and dependencies are Muggle's service responsibility, not the skill's.
435
437
  - **Never consolidate the generator's output** — if `muggle-remote-test-case-generate-from-prompt` returns N micro-tests, accept all N; never merge them into fewer test cases, even if "the plan" says 4 UC / 4 TC.
436
438
  - **Never skip the generate→review cycle** — always present generated test cases to the user before calling `muggle-remote-test-case-create`, even when you're confident. "I'll skip the review and create directly" is always wrong.
437
- - **Never ask for Electron launch approval before each run** — the user picking Local mode is the approval. Don't prompt "Ready to launch Electron?" before execution; just run.
438
439
  - **Never silently drop test cases** — log failures and continue, then report them
439
440
  - **Never guess the URL** — always ask the user for localhost or preview URL
440
441
  - **Always publish before opening browser** — the dashboard needs the published data to show results
@@ -24,39 +24,35 @@ The local URL only changes where the browser opens; it does not change the remot
24
24
 
25
25
  ## Preferences
26
26
 
27
- User preferences are available in the session context (injected at session start). Look for the line starting with `Muggle Preferences` — it contains key=value pairs like `autoLogin=ask showElectronBrowser=always ...`.
27
+ Gates run per `preference-gates/README.md`.
28
28
 
29
- If no preferences line is present, treat all preferences as `"ask"`.
30
-
31
- When you reach a decision gated by a preference:
32
- - **`always`** → proceed without asking the user
33
- - **`never`** → skip without asking the user
34
- - **`ask`** → ask the user, then offer: "Want me to remember this choice for future sessions?" If yes, call `muggle-local-preferences-set` with the key, their chosen value, and scope `global`.
35
-
36
- This skill uses these preferences:
37
-
38
- | Preference | Decision it gates |
39
- |------------|------------------|
40
- | `autoLogin` | Reuse saved credentials when auth is required |
41
- | `autoSelectProject` | Reuse last-used Muggle project for this repo |
42
- | `showElectronBrowser` | Show Electron browser window during local E2E tests |
43
- | `openTestResultsAfterRun` | Open results page on Muggle dashboard after run |
29
+ | Preference | Step | Decision it gates |
30
+ |------------|------|-------------------|
31
+ | `autoLogin` | 1 | Reuse saved credentials when auth is required |
32
+ | `autoSelectProject` | 2 | Reuse last-used Muggle project for this repo |
33
+ | `showElectronBrowser` | 7 | Show Electron browser window during local E2E tests |
34
+ | `openTestResultsAfterRun` | 8 | Open results page on Muggle dashboard after run |
35
+ | `postPRVisualWalkthrough` | 10 | Post visual walkthrough to PR after results |
44
36
 
45
37
  ## Workflow
46
38
 
47
- ### 1. Auth
39
+ ### 1. Auth (gated by `autoLogin`)
48
40
 
49
41
  - `muggle-remote-auth-status`
50
- - If **authenticated**: print the logged-in email and ask via `AskQuestion`:
51
- > "You're logged in as **{email}**. Continue with this account?"
52
- - Option 1: "Yes, continue"
53
- - Option 2: "No, switch account"
54
- If the user picks "switch account", call `muggle-remote-auth-login` with `forceNewSession: true` then `muggle-remote-auth-poll`.
55
- - If **not signed in or expired**: call `muggle-remote-auth-login` then `muggle-remote-auth-poll`.
56
- Do not skip or assume auth.
42
+ - If **authenticated**: gate `autoLogin` (per `preference-gates/README.md`):
43
+ - Pro-action: proceed with saved session.
44
+ - Skip-action: `muggle-remote-auth-login` with `forceNewSession: true`, then `muggle-remote-auth-poll`.
45
+ - If **not signed in or expired**: call `muggle-remote-auth-login` then `muggle-remote-auth-poll`. Do not skip or assume auth.
57
46
 
58
47
  ### 2. Targets (user must confirm)
59
48
 
49
+ The per-repo project cache lives at `<cwd>/.muggle-ai/last-project.json` (via the `muggle-local-last-project-get` / `muggle-local-last-project-set` MCP tools). Look for `Muggle Last Project: id=… url=… name="…"` in session context.
50
+
51
+ Gate `autoSelectProject` (per `preference-gates/README.md`). Cache: `Muggle Last Project` session line.
52
+ - `always` + cache → use cached `projectId`, skip to use case selection. No cache → fall through to `ask`.
53
+ - `never` → full project list; skip Picker 2.
54
+ - `ask` → project list picker (see gate file for spec + Picker 2 override). Skip Picker 2 if "Create new project".
55
+
60
56
  Ask the user to pick **project**, **use case**, and **test case** (do not infer).
61
57
 
62
58
  - `muggle-remote-project-list`
@@ -153,14 +149,20 @@ The MCP client often uses a **default wait of 300000 ms (5 minutes)** for `muggl
153
149
  - **`Electron execution timed out after 300000ms`:** Orchestration wait too short — see **`timeoutMs`** above.
154
150
  - **Exit code 26** (and messages like **LLM failed to generate / replay action script**): Often corresponds to a completed exploration whose **outcome was goal not achievable** (`goal_not_achievable`, summary with `halt`) — e.g. verifying "view script after a successful run" when **no run or script exists yet** in the UI. Use `muggle-local-run-result-get` and read the **summary / structured summary**; do not assume an Electron crash. **Fix:** choose a **project that already has** completed runs and scripts, or **change the test case** so preconditions match what localhost can satisfy (e.g. include steps to create and run a test first, or assert only empty-state UI when no runs exist).
155
151
 
156
- ### 7. Execute (no approval prompt)
152
+ ### 7. Execute (no approval prompt; `showUi` gated by `showElectronBrowser`)
153
+
154
+ Call `muggle-local-execute-test-generation` or `muggle-local-execute-replay` directly. **Do not** ask the user to re-approve the Electron launch — the user choosing this skill in the first place is the approval.
157
155
 
158
- Call `muggle-local-execute-test-generation` or `muggle-local-execute-replay` directly. **Do not** ask the user to re-approve the Electron launch — the user choosing this skill in the first place is the approval. The browser defaults to visible; only pass `showUi: false` if the user explicitly asked for headless.
156
+ Gate `showElectronBrowser` (per `preference-gates/README.md`). Reuse choice within a session.
157
+ - Pro-action: omit `showUi`.
158
+ - Skip-action: pass `showUi: false`.
159
159
 
160
- ### 8. After successful generation only
160
+ ### 8. After successful generation only (open `viewUrl` gated by `openTestResultsAfterRun`)
161
161
 
162
162
  - `muggle-local-publish-test-script`
163
- - Open returned `viewUrl` for the user (`open "<viewUrl>"` on macOS or OS equivalent).
163
+ - Gate `openTestResultsAfterRun` (per `preference-gates/README.md`):
164
+ - Pro-action: open `viewUrl` automatically (`open "<viewUrl>"` on macOS or OS equivalent).
165
+ - Skip-action: print the URL only.
164
166
 
165
167
  ### 9. Report
166
168
 
@@ -204,18 +206,15 @@ Assemble the `E2eReport`:
204
206
 
205
207
  See the `muggle:muggle-pr-visual-walkthrough` skill for the full schema including the failed-test shape.
206
208
 
207
- #### 10b: Ask the user
208
-
209
- Use `AskQuestion`:
210
-
211
- > "Post a visual walkthrough of this run to the PR? Reviewers can click the test case to see step-by-step screenshots on the Muggle AI dashboard."
209
+ #### 10b: Detect the PR, then apply the `postPRVisualWalkthrough` gate
212
210
 
213
- - Option 1: "Yes, post to PR"
214
- - Option 2: "Skip"
211
+ Run `gh pr view --json number,title,url 2>/dev/null` first (mandatory). Then gate `postPRVisualWalkthrough` (per `preference-gates/README.md` + gate file):
212
+ - **Case A (PR found)** — `always` → proceed to 10c; `never`/skip → stop.
213
+ - **Case B (no PR)** — always run Picker 1 regardless of saved value; "Create a PR and post" → create PR then proceed to 10c; "Skip" → stop.
215
214
 
216
215
  #### 10c: Invoke the shared skill in Mode A
217
216
 
218
- If the user chooses "Yes, post to PR", invoke the `muggle:muggle-pr-visual-walkthrough` skill via the `Skill` tool. With the `E2eReport` in context, the skill renders the markdown block via the CLI, finds the PR via `gh pr view`, posts `body` as a comment, posts the overflow `comment` only if the CLI emitted one, and confirms the PR URL to the user.
217
+ Invoke the `muggle:muggle-pr-visual-walkthrough` skill via the `Skill` tool. With the `E2eReport` in context, the skill renders the markdown block via the CLI, posts `body` as a comment to the PR, posts the overflow `comment` only if the CLI emitted one, and confirms the PR URL to the user.
219
218
 
220
219
  Always use **Mode A** (post to existing PR) from this skill. Never hand-write the walkthrough markdown or call `gh pr comment` directly — delegate to `muggle:muggle-pr-visual-walkthrough`.
221
220
 
@@ -20,23 +20,14 @@ in a Muggle project via the API.
20
20
 
21
21
  ## Preferences
22
22
 
23
- User preferences are available in the session context (injected at session start). Look for the line starting with `Muggle Preferences` — it contains key=value pairs like `autoLogin=ask showElectronBrowser=always ...`.
23
+ Gates run per `preference-gates/README.md`.
24
24
 
25
- If no preferences line is present, treat all preferences as `"ask"`.
26
-
27
- When you reach a decision gated by a preference:
28
- - **`always`** → proceed without asking the user
29
- - **`never`** → skip without asking the user
30
- - **`ask`** → ask the user, then offer: "Want me to remember this choice for future sessions?" If yes, call `muggle-local-preferences-set` with the key, their chosen value, and scope `global`.
31
-
32
- This skill uses these preferences:
33
-
34
- | Preference | Decision it gates |
35
- |------------|------------------|
36
- | `autoLogin` | Reuse saved credentials when auth is required |
37
- | `autoSelectProject` | Reuse last-used Muggle project for this repo |
38
- | `suggestRelatedUseCases` | Suggest related use cases after import |
39
- | `suggestRelatedTestCases` | Suggest related test cases after import |
25
+ | Preference | Step | Decision it gates |
26
+ |------------|------|-------------------|
27
+ | `autoLogin` | 4 | Reuse saved credentials when auth is required |
28
+ | `autoSelectProject` | 5 | Reuse last-used Muggle project for this repo |
29
+ | `suggestRelatedUseCases` | 8a | Suggest related use cases after import |
30
+ | `suggestRelatedTestCases` | 8b | Suggest related test cases after import |
40
31
 
41
32
  ## Concepts
42
33
 
@@ -146,14 +137,13 @@ If the user wants changes, incorporate feedback, then ask again. Only proceed af
146
137
 
147
138
  ---
148
139
 
149
- ## Step 4 — Authenticate
140
+ ## Step 4 — Authenticate (gated by `autoLogin`)
150
141
 
151
142
  Call `muggle-remote-auth-status` first.
152
143
 
153
- If **already authenticated** → print the logged-in email and ask via `AskQuestion`:
154
- > "You're logged in as **{email}**. Continue with this account?"
155
- - Option 1: "Yes, continue" → skip to Step 5.
156
- - Option 2: "No, switch account" → call `muggle-remote-auth-login` with `forceNewSession: true`, then `muggle-remote-auth-poll`.
144
+ If **already authenticated** → gate `autoLogin` (per `preference-gates/README.md`):
145
+ - Pro-action: skip to Step 5.
146
+ - Skip-action: `muggle-remote-auth-login` with `forceNewSession: true`, then `muggle-remote-auth-poll`.
157
147
 
158
148
  If **not authenticated**:
159
149
  1. Tell the user a browser window is about to open.
@@ -163,14 +153,23 @@ If **not authenticated**:
163
153
 
164
154
  ---
165
155
 
166
- ## Step 5 — Pick or create a project
156
+ ## Step 5 — Pick or create a project (gated by `autoSelectProject`)
167
157
 
168
158
  A **project** is where all your imported use cases, test cases, and future test results are grouped on the Muggle AI dashboard.
169
159
 
170
- 1. Call `muggle-remote-project-list`
160
+ The per-repo project cache lives at `<cwd>/.muggle-ai/last-project.json` (via the `muggle-local-last-project-get` / `muggle-local-last-project-set` MCP tools). Look for `Muggle Last Project: id=… url=… name="…"` in session context.
161
+
162
+ Gate `autoSelectProject` (per `preference-gates/README.md`). Cache: `Muggle Last Project` session line.
163
+ - `always` + cache → use cached `projectId`, skip to Step 6. No cache → fall through to `ask`.
164
+ - `never` → full project list; skip Picker 2.
165
+ - `ask` → project list picker (see gate file for spec + Picker 2 override). Skip Picker 2 if "Create new project".
166
+
167
+ ### Logic
168
+
169
+ 1. Call `muggle-remote-project-list` (only when not satisfied by the `always` cache).
171
170
  2. Use `AskQuestion` to present all projects as clickable options. Include the project URL in each label. Always include a "Create new project" option at the end.
172
171
 
173
- Prompt: "Pick the project to import into:"
172
+ Prompt: `"Pick the project to import into:"`
174
173
 
175
174
  3. **If creating a new project**, propose values based on what you learned from the source files:
176
175
  - **Name**: infer the app name from filenames, URLs, or document headings (e.g., "Acme App")
@@ -392,3 +391,38 @@ Imported: 3 use cases · 8 test cases
392
391
 
393
392
  Next step: run /muggle:do to generate executable browser test scripts for these test cases.
394
393
  ```
394
+
395
+ ### Step 8 — Optional follow-up suggestions
396
+
397
+ Two preferences gate optional follow-ups: `suggestRelatedUseCases` and `suggestRelatedTestCases`. Both are independent — handle each in turn.
398
+
399
+ #### 8a — Related use cases (gated by `suggestRelatedUseCases`)
400
+
401
+ The query is: "from the use cases already in this project, which ones are *not* in the import set but look related to it?" — surface them so the user can decide whether their import missed something the project already tracks.
402
+
403
+ Gate `suggestRelatedUseCases` (per `preference-gates/README.md`):
404
+ - Pro-action: run the query below.
405
+ - Skip-action: skip.
406
+
407
+ When running the query:
408
+ 1. Call `muggle-remote-use-case-list` for the project.
409
+ 2. Filter out any use case whose `useCaseId` is in the set you just imported in Step 6 (Pass 1).
410
+ 3. Rank the remainder by semantic relevance to the imported titles/descriptions (substring overlap, shared keywords — best-effort, no LLM call needed).
411
+ 4. Present the top 3-5 via `AskQuestion` with `allow_multiple: true`. Label each with `<title> — <one-line description>`.
412
+ 5. For any the user selects, prompt to add follow-up test cases (treat each as a Pass 2 invocation: `muggle-remote-test-case-bulk-preview-submit` → poll → persist via `muggle-remote-test-case-create`).
413
+ 6. If the filtered list is empty (the import covers everything in the project), say so and skip.
414
+
415
+ #### 8b — Related test cases (gated by `suggestRelatedTestCases`)
416
+
417
+ For each use case the user just created, surface other test cases already attached that the import didn't add — same idea, scoped to a single use case.
418
+
419
+ Gate `suggestRelatedTestCases` (per `preference-gates/README.md`):
420
+ - Pro-action: run the query below.
421
+ - Skip-action: skip.
422
+
423
+ When running the query, for each use case in the import:
424
+ 1. Call `muggle-remote-test-case-list-by-use-case` with that `useCaseId`.
425
+ 2. Filter out any test case you just created in Pass 2 of Step 6.
426
+ 3. Present the remainder via `AskQuestion` with `allow_multiple: true`, labeled `[<priority>] <title> — <goal>`.
427
+ 4. For any the user selects: nothing to create (they already exist) — just confirm to the user that those tests are now part of their Muggle project alongside the imported ones.
428
+ 5. If a use case has no extra test cases, skip it silently.