@muggleai/works 4.7.0 → 4.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,7 @@ Update all Muggle AI components to the latest published version.
10
10
  ## Steps
11
11
 
12
12
  1. Run `/muggle:muggle-status` checks to capture current versions.
13
- 2. Run `muggle setup --force` to download the latest Electron browser test runner.
13
+ 2. Run `muggle upgrade` to check GitHub releases for the latest electron-app version and download it.
14
14
  3. Report the upgrade results:
15
15
  - Previous version vs new version for each component.
16
16
  - Whether the upgrade succeeded or failed.
@@ -0,0 +1,198 @@
1
+ ---
2
+ name: muggle-works-npm-release
3
+ description: >-
4
+ Cut @muggleai/works release: AskQuestion (major/minor/patch), sync master, stop if
5
+ nothing ships, semver baseline + Electron from GitHub, confirm plan, bump
6
+ package.json + sync:versions, full local verify, chore(release) PR, merge via gh,
7
+ dispatch publish-works-to-npm.yml—no local npm publish.
8
+ ---
9
+
10
+ # Muggle Works — npm release (single playbook)
11
+
12
+ Repo: **`multiplex-ai/muggle-ai-works`**. Workflow: **`.github/workflows/publish-works-to-npm.yml`** (“Publish Works to npm”). **Never** run local **`npm publish`** (OIDC trusted publishing in CI).
13
+
14
+ ---
15
+
16
+ ## Phase 1 — Ask bump type (do this first)
17
+
18
+ **Stop until the user answers.**
19
+
20
+ **Prefer `AskQuestion`** with exactly these three options: **major**, **minor**, **patch** (fix). If the environment has no structured question tool, ask the same in plain text:
21
+
22
+ > Is this release a **major**, **minor**, or **patch** (fix)?
23
+
24
+ You may **recommend** a bump from commit subjects (e.g. `feat!` / breaking → major, `feat` → minor, `fix` / `chore` → patch) but **do not** choose for them. **Do not** edit files yet.
25
+
26
+ ---
27
+
28
+ ## Phase 2 — Sync, surface state, empty-release gate
29
+
30
+ Run from **`muggle-ai-works`**:
31
+
32
+ ```bash
33
+ git checkout master && git pull --ff-only && git fetch --tags
34
+ ```
35
+
36
+ Show what is shipping:
37
+
38
+ ```bash
39
+ node -e 'console.log("master package.json:", require("./package.json").version)'
40
+ npm view @muggleai/works version 2>&1 | sed 's/^/npm latest: /'
41
+ ```
42
+
43
+ **Commits since the last release commit** (stop if there is nothing to ship):
44
+
45
+ ```bash
46
+ LAST_RELEASE_SHA=$(git log --grep='chore(release)' --format='%H' -1)
47
+ git log --oneline "$LAST_RELEASE_SHA..HEAD"
48
+ ```
49
+
50
+ - If the log is **empty**, tell the user there is **nothing to ship** and **stop** (no branch, no bump, no PR).
51
+ - If non-empty, present commits as a short table (subject; PR number from title/body if present).
52
+
53
+ ---
54
+
55
+ ## Phase 3 — Version baseline, Electron, print summary, confirm
56
+
57
+ ### npm version (`nextNpmVersion`)
58
+
59
+ 1. **`npm view @muggleai/works version`** — last published on npm.
60
+ 2. Root **`package.json` → `version`** on current **`master`** checkout.
61
+ 3. **Baseline** = **semver-higher** of those two (never target below repo or npm).
62
+ 4. Apply the user’s **major / minor / patch** to that baseline → **`nextNpmVersion`** (semver-correct).
63
+
64
+ ### Electron (`muggleConfig`)
65
+
66
+ 1. Read **`package.json` → `muggleConfig.electronAppVersion`**.
67
+ 2. **Latest desktop on GitHub:**
68
+ `https://api.github.com/repos/multiplex-ai/muggle-ai-works/releases?per_page=30`
69
+ → newest **`tag_name`** matching **`electron-app-v*`** → strip prefix → **`latestElectronVersion`** (semver only).
70
+
71
+ ### Print (always)
72
+
73
+ | Item | Value |
74
+ | :--- | :---- |
75
+ | Last **@muggleai/works** on npm | … |
76
+ | **Baseline** for bump | … |
77
+ | **`nextNpmVersion`** (to publish) | … |
78
+ | Current **`electronAppVersion`** | … |
79
+ | Latest **`electron-app-v…`** on GitHub | … |
80
+
81
+ ### Electron bump decision
82
+
83
+ If **`latestElectronVersion`** ≠ current **`electronAppVersion`**, ask: **bump** Electron + all four **`muggleConfig.checksums`** to **`latestElectronVersion`**, or **keep** current.
84
+
85
+ If bumping, checksums from:
86
+
87
+ `https://github.com/multiplex-ai/muggle-ai-works/releases/download/electron-app-vVERSION/checksums.txt`
88
+
89
+ Map zip artifacts → **`darwin-arm64`**, **`darwin-x64`**, **`win32-x64`**, **`linux-x64`** (same mapping rules as today).
90
+
91
+ **Stop again:** user must **confirm** the full plan (**`nextNpmVersion`** + Electron choice). If they cancel, **do not** branch, merge, or dispatch CI.
92
+
93
+ ---
94
+
95
+ ## Phase 4 — After explicit confirmation only
96
+
97
+ ### 1. Branch and bump
98
+
99
+ ```bash
100
+ git checkout -b "chore/release-<VERSION>"
101
+ npm version "<VERSION>" --no-git-tag-version
102
+ ```
103
+
104
+ Replace **`<VERSION>`** with **`nextNpmVersion`** (dots in the branch name are fine, e.g. `chore/release-4.8.0`).
105
+
106
+ - If Electron bump agreed: set **`muggleConfig.electronAppVersion`** and all four **`muggleConfig.checksums`** in **`package.json`**.
107
+
108
+ ### 2. Propagate versions (do not hand-edit manifests)
109
+
110
+ ```bash
111
+ pnpm run sync:versions
112
+ ```
113
+
114
+ Never hand-edit **`.claude-plugin/marketplace.json`**, **`.cursor-plugin/marketplace.json`**, **`plugin/.claude-plugin/plugin.json`**, **`plugin/.cursor-plugin/plugin.json`**, or **`server.json`** — **`sync-versions`** (and **`build`**) owns them.
115
+
116
+ If you changed Electron after the first sync, run **`pnpm run sync:versions`** again.
117
+
118
+ ### 3. Full local verify (before push)
119
+
120
+ ```bash
121
+ pnpm run lint:check && pnpm run typecheck && pnpm test && pnpm run build && pnpm run verify:plugin && pnpm run verify:contracts && pnpm run verify:electron-release-checksums
122
+ ```
123
+
124
+ - **`pnpm run build`** is required before **`verify:plugin`** — the verifier reads the **built** plugin under **`dist/plugin/`**, not source under **`plugin/`**.
125
+ - If **anything** fails, **stop** and surface the error; **do not** push a broken release.
126
+
127
+ ### 4. Commit (**`chore(release)`**)
128
+
129
+ Stage version-touched files (at minimum **`package.json`** plus whatever **`sync:versions`** changed — typically the marketplace/plugin **`server.json`** paths above).
130
+
131
+ **Subject:** `chore(release): @muggleai/works <VERSION>`
132
+
133
+ **Body:** one bullet per shipping PR / theme, note **Electron** bump or unchanged, and any coordinated follow-ups in sibling repos (e.g. teaching-service, UI). Use a **heredoc** for `git commit` so newlines are preserved.
134
+
135
+ ### 5. PR, merge, update local **`master`**
136
+
137
+ ```bash
138
+ git push -u origin HEAD
139
+ gh pr create --repo multiplex-ai/muggle-ai-works --base master --head <branch> \
140
+ --title "chore(release): @muggleai/works <VERSION>" \
141
+ --body "<PR body: version delta, bump rationale, shipping list, Electron status, manifests touched by sync:versions, short test plan checklist>"
142
+ ```
143
+
144
+ **Merge:** when the human has approved the release in this session, run **`gh pr merge`** (squash is fine unless the repo prefers merge commits), then:
145
+
146
+ ```bash
147
+ git checkout master && git pull --ff-only
148
+ node -e 'console.log("master now:", require("./package.json").version)'
149
+ ```
150
+
151
+ Confirm **`package.json`** on **`master`** matches **`nextNpmVersion`** before publishing.
152
+
153
+ ---
154
+
155
+ ## Phase 5 — Trigger publish (CI only)
156
+
157
+ Prefer **explicit version** (not “auto bump”):
158
+
159
+ ```bash
160
+ gh workflow run publish-works-to-npm.yml --repo multiplex-ai/muggle-ai-works --ref master \
161
+ --field "version=<VERSION>" --field "bump=patch"
162
+ ```
163
+
164
+ The `bump=patch` field is a harmless placeholder when `version` is set; the workflow prefers the explicit `version` input.
165
+
166
+ **Or** **`git tag "v<VERSION>"`** && **`git push origin "v<VERSION>"`** only if that tag **does not** already exist on the remote; if the tag exists, use **`workflow_dispatch`** with **`version`**.
167
+
168
+ Watch the run and confirm jobs succeed:
169
+
170
+ ```bash
171
+ gh run list --repo multiplex-ai/muggle-ai-works --workflow=publish-works-to-npm.yml --limit 1
172
+ gh run watch <RUN_ID> --repo multiplex-ai/muggle-ai-works --exit-status
173
+ ```
174
+
175
+ Verify the registry:
176
+
177
+ ```bash
178
+ npm view @muggleai/works version
179
+ ```
180
+
181
+ Give the user the **Actions run URL**. If npm lags, wait ~60s and retry.
182
+
183
+ ---
184
+
185
+ ## Rules
186
+
187
+ - **No local `npm publish`.**
188
+ - **Phase 1:** use **`AskQuestion`** for major / minor / patch when available (see Phase 1).
189
+ - Phases 1–3: keep chat concise; Phase 4–5 can be terse status lines.
190
+ - If the user cancels after Phase 3, **do not** merge or dispatch CI.
191
+ - **Tag vs npm:** **`v*`** tags are for the **npm** package; **`electron-app-v*`** is separate — **`electronAppVersion`** can move independently of **`version`**.
192
+
193
+ ---
194
+
195
+ ## Notes (troubleshooting)
196
+
197
+ - Workflow **`name:`** / filename is tied to npm **Trusted Publishing** — see the comment block at the top of **`publish-works-to-npm.yml`** if auth fails.
198
+ - If commits land on **`master`** between opening the PR and merging, re-check **`git log`** vs the last **`chore(release)`** before merging; rebasing the release branch may be needed so **`master`** still matches what you intend to ship.
@@ -1,7 +1,7 @@
1
1
  {
2
- "release": "4.7.0",
3
- "buildId": "run-18-1",
4
- "commitSha": "2497ce3c3bd536d511c5f1a8d6621e691fd8f5e3",
5
- "buildTime": "2026-04-11T06:11:05Z",
2
+ "release": "4.8.1",
3
+ "buildId": "run-20-1",
4
+ "commitSha": "8cd42b4b70c049e44510010003084227b04229a8",
5
+ "buildTime": "2026-04-14T21:44:51Z",
6
6
  "serviceName": "muggle-ai-works-mcp"
7
7
  }
@@ -1 +1 @@
1
- export { buildElectronAppChecksumsUrl, buildElectronAppReleaseAssetUrl, buildElectronAppReleaseTag, calculateFileChecksum, createApiKeyWithToken, createChildLogger, deleteApiKeyData, deleteCredentials, e2e_exports as e2e, getApiKey, getApiKeyFilePath, getAuthService, getBundledElectronAppVersion, getCallerCredentials, getCallerCredentialsAsync, getChecksumForPlatform, getConfig, getCredentialsFilePath, getDataDir, getDownloadBaseUrl, getElectronAppChecksums, getElectronAppDir, getElectronAppVersion, getElectronAppVersionSource, getLocalQaTools, getLogger, getPlatformKey, getQaTools, getValidApiKeyData, getValidCredentials, hasApiKey, isElectronAppInstalled, loadApiKeyData, loadCredentials, local_exports as localQa, mcp_exports as mcp, openBrowserUrl, performLogin, performLogout, pollDeviceCode, e2e_exports as qa, resetConfig, resetLogger, saveApiKey, saveApiKeyData, saveCredentials, startDeviceCodeFlow, toolRequiresAuth, verifyFileChecksum } from './chunk-HDEZDEM6.js';
1
+ export { buildElectronAppChecksumsUrl, buildElectronAppReleaseAssetUrl, buildElectronAppReleaseTag, calculateFileChecksum, createApiKeyWithToken, createChildLogger, deleteApiKeyData, deleteCredentials, e2e_exports as e2e, getApiKey, getApiKeyFilePath, getAuthService, getBundledElectronAppVersion, getCallerCredentials, getCallerCredentialsAsync, getChecksumForPlatform, getConfig, getCredentialsFilePath, getDataDir, getDownloadBaseUrl, getElectronAppChecksums, getElectronAppDir, getElectronAppVersion, getElectronAppVersionSource, getLocalQaTools, getLogger, getPlatformKey, getQaTools, getValidApiKeyData, getValidCredentials, hasApiKey, isElectronAppInstalled, loadApiKeyData, loadCredentials, local_exports as localQa, mcp_exports as mcp, openBrowserUrl, performLogin, performLogout, pollDeviceCode, e2e_exports as qa, resetConfig, resetLogger, saveApiKey, saveApiKeyData, saveCredentials, startDeviceCodeFlow, toolRequiresAuth, verifyFileChecksum } from './chunk-44I5ROCB.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": "4.7.0",
4
+ "version": "4.8.1",
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.0.51",
44
+ "electronAppVersion": "1.0.59",
45
45
  "downloadBaseUrl": "https://github.com/multiplex-ai/muggle-ai-works/releases/download",
46
46
  "runtimeTargetDefault": "production",
47
47
  "checksums": {
48
- "darwin-arm64": "6be5d2ff37541d9933e065f94f04348d7e4be63f01896b334a108a755a79f770",
49
- "darwin-x64": "5c381e68829a330eecb8bd6edb9e5fba820e995acafe7fe78474fd7c43174f40",
50
- "win32-x64": "2c101c467f75e8d60482aad16ad3c1a1e8edecac9ae58cdf7f1ad74cdf1141f7",
51
- "linux-x64": "efeed3f2caf1cd301e8cc503a8ebae1f604ce73f7325c43202dee1c8a858a8a8"
48
+ "darwin-arm64": "c6da3f7f6b6875174a70a6c065554ed051ff99f731470e161ab71d9a9e568a87",
49
+ "darwin-x64": "ff93b24724fd415b99c40bcce2cc90a31e453a6408aad45a63480ff92606e7b0",
50
+ "win32-x64": "59bc67ea0a067fb4a204b87c73bf8cc387e705307f77ec96202822ff14b587fa",
51
+ "linux-x64": "714c93f586ac423377d9061924d2f703c175e3b541ef6ad22c96f6c20d3f4ea0"
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": "4.7.0",
4
+ "version": "4.8.1",
5
5
  "author": {
6
6
  "name": "Muggle AI",
7
7
  "email": "support@muggle-ai.com"
@@ -2,7 +2,7 @@
2
2
  "name": "muggle",
3
3
  "displayName": "Muggle AI",
4
4
  "description": "Ship quality products with AI-powered end-to-end (E2E) acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
5
- "version": "4.7.0",
5
+ "version": "4.8.1",
6
6
  "author": {
7
7
  "name": "Muggle AI",
8
8
  "email": "support@muggle-ai.com"
package/plugin/README.md CHANGED
@@ -15,7 +15,7 @@ For npm installs:
15
15
  npm install -g @muggleai/works
16
16
  ```
17
17
 
18
- This updates the CLI and syncs `muggle-*` skills into `~/.cursor/skills/` for Cursor. Claude slash commands remain plugin-managed, so use `/plugin update muggleai@muggle-works` to refresh them.
18
+ This updates the CLI, configures Cursor MCP (`~/.cursor/mcp.json`), and syncs `muggle-*` skills into `~/.cursor/skills/`. Claude slash commands remain plugin-managed, so use `/plugin update muggleai@muggle-works` to refresh them.
19
19
 
20
20
  ## Skills
21
21
 
@@ -200,6 +200,17 @@ If nothing detected, ask as free text: "Your local app should be running. What's
200
200
 
201
201
  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).
202
202
 
203
+ ### Determine `freshSession` per test case
204
+
205
+ Before executing each test case, inspect its content (title, goal, instructions, preconditions) for signals that it requires a **clean browser state** — no prior cookies, localStorage, or logged-in session. Set `freshSession: true` when the test case involves any of:
206
+
207
+ - **Registration / sign-up** — creating a new account
208
+ - **Login / authentication** — verifying the login flow itself (not a test that merely *uses* login as a prerequisite)
209
+ - **Cookie consent / GDPR banners** — verifying first-visit consent prompts
210
+ - **Onboarding flows** — first-time user experiences that only appear on a fresh session
211
+
212
+ If none of the above apply, omit `freshSession` (defaults to `false`, preserving any existing session state). Evaluate this per test case — in a batch, some may need it and others may not.
213
+
203
214
  ### Run sequentially (Electron constraint)
204
215
 
205
216
  Execution itself **must** be sequential because there is only one local Electron browser. For each test case, in order:
@@ -208,6 +219,7 @@ Execution itself **must** be sequential because there is only one local Electron
208
219
  - `testCase`: Full test case object from the parallel fetch above
209
220
  - `localUrl`: User's local URL from the pre-flight question
210
221
  - `showUi`: omit (default visible) unless the user explicitly asked for headless, then pass `false`
222
+ - `freshSession`: `true` if the test case requires a clean browser state (see above), omit otherwise
211
223
  2. Store the returned `runId`
212
224
 
213
225
  If a generation fails, log it and continue to the next. Do not abort the batch.
@@ -231,7 +243,7 @@ Store every `viewUrl` — these are used in the next steps.
231
243
  ### Report summary
232
244
 
233
245
  ```
234
- Test Case Status Duration Steps View on Muggle
246
+ Test Case Status Duration Steps View Steps on Muggle AI
235
247
  ─────────────────────────────────────────────────────────────────────────
236
248
  Login with valid creds PASSED 12.3s 8 https://www.muggle-ai.com/...
237
249
  Login with invalid creds PASSED 9.1s 6 https://www.muggle-ai.com/...
@@ -86,17 +86,28 @@ Remind them: local URL is only the execution target, not tied to cloud project c
86
86
 
87
87
  ### 5. Load data for the chosen path
88
88
 
89
+ **Determine `freshSession`**
90
+
91
+ Before calling either execution tool, inspect the test case content (title, goal, instructions, preconditions) for signals that the test requires a **clean browser state** — no prior cookies, localStorage, or logged-in session. Pass `freshSession: true` when the test case involves any of:
92
+
93
+ - **Registration / sign-up** — creating a new account
94
+ - **Login / authentication** — verifying the login flow itself (not a test that merely *uses* login as a prerequisite)
95
+ - **Cookie consent / GDPR banners** — verifying first-visit consent prompts
96
+ - **Onboarding flows** — first-time user experiences that only appear on a fresh session
97
+
98
+ If none of the above apply, omit `freshSession` (defaults to `false`, preserving any existing session state).
99
+
89
100
  **Generate**
90
101
 
91
102
  1. `muggle-remote-test-case-get`
92
- 2. `muggle-local-execute-test-generation` with that test case + `localUrl` (optional: `showUi: false` for headless — defaults to visible; **`timeoutMs`** — see below)
103
+ 2. `muggle-local-execute-test-generation` with that test case + `localUrl` (optional: `showUi: false` for headless — defaults to visible; **`freshSession`** — see above; **`timeoutMs`** — see below)
93
104
 
94
105
  **Replay**
95
106
 
96
107
  1. `muggle-remote-test-script-get` — note `actionScriptId`
97
108
  2. `muggle-remote-action-script-get` with that id — full `actionScript`
98
109
  **Use the API response as-is.** Do not edit, shorten, or rebuild `actionScript`; replay needs full `label` paths for element lookup.
99
- 3. `muggle-local-execute-replay` with `testScript`, `actionScript`, `localUrl` (optional: `showUi: false` for headless — defaults to visible; **`timeoutMs`** — see below)
110
+ 3. `muggle-local-execute-replay` with `testScript`, `actionScript`, `localUrl` (optional: `showUi: false` for headless — defaults to visible; **`freshSession`** — see above; **`timeoutMs`** — see below)
100
111
 
101
112
  ### Local execution timeout (`timeoutMs`)
102
113
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: muggle-test-regenerate-missing
3
- description: "Bulk-regenerate test scripts for every test case in a Muggle AI project that doesn't currently have an active script. Scans the project, finds test cases stuck in DRAFT or GENERATION_PENDING (no usable script attached), shows the user the list, and on approval kicks off remote test script generation for each one in parallel via the Muggle cloud. Use this skill whenever the user asks to 'regenerate missing scripts', 'fill in missing test scripts', 'generate scripts for test cases without one', 'regen all the test cases that don't have scripts', 'rebuild scripts for stale test cases', 'fix test cases with no script', 'bulk regenerate', or any phrasing that means 'kick off script generation across a project for the cases that need it'. Triggers on: 'regenerate missing test scripts', 'generate scripts for all empty test cases', 'fill the gaps in my test scripts', 'bulk test script regen', 'all my test cases without active scripts'. This is the go-to skill for project-wide script catch-up — it handles discovery, filtering, confirmation, and remote workflow dispatch end-to-end."
3
+ description: "Bulk-regenerate test scripts for every test case in a Muggle AI project that doesn't currently have an active script. Scans the project, finds test cases stuck in DRAFT or GENERATION_PENDING (no usable script attached), shows the user the list, and on approval kicks off bulk remote test script generation via the Muggle cloud. Use this skill whenever the user asks to 'regenerate missing scripts', 'fill in missing test scripts', 'generate scripts for test cases without one', 'regen all the test cases that don't have scripts', 'rebuild scripts for stale test cases', 'fix test cases with no script', 'bulk regenerate', or any phrasing that means 'kick off script generation across a project for the cases that need it'. Triggers on: 'regenerate missing test scripts', 'generate scripts for all empty test cases', 'fill the gaps in my test scripts', 'bulk test script regen', 'all my test cases without active scripts'. This is the go-to skill for project-wide script catch-up — it handles discovery, filtering, confirmation, and remote workflow dispatch end-to-end."
4
4
  ---
5
5
 
6
6
  # Muggle Test — Regenerate Missing Test Scripts
@@ -116,27 +116,22 @@ After selection, call `AskQuestion` once more for a final confirmation:
116
116
 
117
117
  Only proceed after the user picks "Yes".
118
118
 
119
- ### Step 6 — Dispatch Remote Generations
119
+ ### Step 6 — Dispatch Remote Generations (Bulk)
120
120
 
121
- For each selected test case, in order:
121
+ Send a single bulk request instead of dispatching one workflow per test case:
122
122
 
123
- 1. Call `muggle-remote-test-case-get` with `testCaseId` to fetch the full record (the list endpoint returns a slim shape; generation needs `goal`, `precondition`, `instructions`, `expectedResult`, `url`).
124
- 2. Call `muggle-remote-workflow-start-test-script-generation` with:
123
+ 1. Call `muggle-remote-workflow-start-test-script-generation-bulk` with:
125
124
  - `projectId` — from Step 2
126
- - `useCaseId` — from the test case
127
- - `testCaseId` — the test case being regenerated
128
- - `name` `"muggle-test-regenerate-missing: {test case title}"` (so it's easy to find this batch later in the dashboard)
129
- - `url` prefer the test case's own `url` if set, else the project URL from Step 2
130
- - `goal`, `precondition`, `instructions`, `expectedResult` — straight from the test case. If `precondition` is empty, pass `"None"` (the schema requires a non-empty string).
131
- 3. Capture the returned workflow runtime ID and store it alongside the test case.
125
+ - `name` — `"muggle-test-regenerate-missing: bulk ({count} test cases)"` where `{count}` is the number of selected test cases
126
+ - `testCaseIds` — array of all selected test case IDs from Step 5
127
+ 2. The backend handles looking up full test case details (goal, precondition, instructions, expectedResult, url), so there is no need to call `muggle-remote-test-case-get` per test case.
128
+ 3. Parse the response to get the `items` array with per-test-case status. Each item contains the test case ID, dispatch status, and (when successful) the workflow runtime ID.
132
129
 
133
- **Failure handling:** if a single dispatch fails (validation error, server error, missing field), log it inline, mark the test case as `dispatch_failed`, and continue to the next one. Do not abort the whole batch — partial progress is more useful than nothing.
134
-
135
- **Pacing:** Muggle's cloud handles parallelism on its side, so you don't need to throttle. Just dispatch sequentially as fast as the API will accept them.
130
+ **Failure handling:** the bulk API returns per-item status in the response `items` array. Individual test cases may fail (validation error, missing field, etc.) while others succeed. Surface failures in the Step 7 report — partial progress beats no progress.
136
131
 
137
132
  ### Step 7 — Report
138
133
 
139
- After all dispatches are done, print a summary table:
134
+ After the bulk dispatch returns, build a summary table from the response `items` array. Each item contains a test case ID, dispatch status, and (when successful) a workflow runtime ID. Cross-reference with the test case list from Step 3 to fill in titles and use case names:
140
135
 
141
136
  ```
142
137
  Test Case Use Case Prev Status Dispatch Runtime
@@ -149,7 +144,7 @@ Apply expired coupon Checkout Flow GENERATION_PEND. ❌ fa
149
144
  Total: 17 dispatched | 16 started | 1 failed
150
145
  ```
151
146
 
152
- For failures: include a one-line error excerpt and (where possible) a hint at the cause (e.g., "missing instructions field — edit the test case in the dashboard, then re-run this skill").
147
+ For failures: include a one-line error excerpt from the item's error field and (where possible) a hint at the cause (e.g., "missing instructions field — edit the test case in the dashboard, then re-run this skill").
153
148
 
154
149
  ### Step 8 — Open the Dashboard
155
150
 
@@ -183,8 +178,7 @@ Add item to cart rt-ghi789 COMPLETED 12
183
178
  | Auth | `muggle-remote-auth-status`, `muggle-remote-auth-login`, `muggle-remote-auth-poll` |
184
179
  | Project | `muggle-remote-project-list`, `muggle-remote-project-create` |
185
180
  | Scan | `muggle-remote-test-case-list` (paginated) |
186
- | Detail | `muggle-remote-test-case-get` |
187
- | Dispatch | `muggle-remote-workflow-start-test-script-generation` |
181
+ | Dispatch | `muggle-remote-workflow-start-test-script-generation-bulk` |
188
182
  | Status (optional) | `muggle-remote-wf-get-ts-gen-latest-run`, `muggle-remote-wf-get-latest-ts-gen-by-tc` |
189
183
  | Browser | `open` (shell command) |
190
184
 
@@ -193,9 +187,8 @@ Add item to cart rt-ghi789 COMPLETED 12
193
187
  - **The user MUST select the project** — present projects via `AskQuestion`, never infer from cwd, repo name, or URL guesses.
194
188
  - **The user MUST approve which test cases to regenerate** — show the candidates via `AskQuestion`, let them deselect, then confirm again before any dispatch. Bulk-regenerating without approval can waste meaningful workflow budget.
195
189
  - **Default filter is `DRAFT` + `GENERATION_PENDING`** — never include `GENERATING`, `ACTIVE`, `DEPRECATED`, `ARCHIVED`, `REPLAYING`, or `REPLAY_PENDING` unless the user explicitly says so. `GENERATING` already has a workflow in flight and dispatching another races against it. `ACTIVE` test cases already have working scripts. The rest reflect deliberate user decisions or in-flight replays the skill should not interfere with.
196
- - **Use `muggle-remote-test-case-get` before each dispatch** the list endpoint returns a slim shape and generation needs the full payload.
197
- - **Failures don't abort the batch** — log and continue, then surface them at the end. Partial progress beats no progress.
198
- - **Never throttle artificially** — dispatch sequentially as fast as the API accepts. Muggle's cloud handles parallelism.
190
+ - **Use the bulk endpoint for dispatch** — call `muggle-remote-workflow-start-test-script-generation-bulk` once with all selected test case IDs rather than dispatching one-by-one. The backend resolves full test case details internally.
191
+ - **Failures don't abort the batch** — the bulk API returns per-item status. Surface failures in the report. Partial progress beats no progress.
199
192
  - **Open the dashboard, don't poll by default** — the runs page is the canonical view of progress. Only poll if the user explicitly asks.
200
193
  - **Use `AskQuestion` for every selection** — never ask the user to type a number.
201
194
  - **Can be invoked at any state** — if the user already has a project chosen in conversation context, skip Step 2 and go straight to scanning.
@@ -10,7 +10,7 @@ Update all Muggle AI components to the latest published version.
10
10
  ## Steps
11
11
 
12
12
  1. Run `/muggle:muggle-status` checks to capture current versions.
13
- 2. Run `muggle setup --force` to download the latest Electron browser test runner.
13
+ 2. Run `muggle upgrade` to check GitHub releases for the latest electron-app version and download it.
14
14
  3. Report the upgrade results:
15
15
  - Previous version vs new version for each component.
16
16
  - Whether the upgrade succeeded or failed.
@@ -0,0 +1,198 @@
1
+ ---
2
+ name: muggle-works-npm-release
3
+ description: >-
4
+ Cut @muggleai/works release: AskQuestion (major/minor/patch), sync master, stop if
5
+ nothing ships, semver baseline + Electron from GitHub, confirm plan, bump
6
+ package.json + sync:versions, full local verify, chore(release) PR, merge via gh,
7
+ dispatch publish-works-to-npm.yml—no local npm publish.
8
+ ---
9
+
10
+ # Muggle Works — npm release (single playbook)
11
+
12
+ Repo: **`multiplex-ai/muggle-ai-works`**. Workflow: **`.github/workflows/publish-works-to-npm.yml`** (“Publish Works to npm”). **Never** run local **`npm publish`** (OIDC trusted publishing in CI).
13
+
14
+ ---
15
+
16
+ ## Phase 1 — Ask bump type (do this first)
17
+
18
+ **Stop until the user answers.**
19
+
20
+ **Prefer `AskQuestion`** with exactly these three options: **major**, **minor**, **patch** (fix). If the environment has no structured question tool, ask the same in plain text:
21
+
22
+ > Is this release a **major**, **minor**, or **patch** (fix)?
23
+
24
+ You may **recommend** a bump from commit subjects (e.g. `feat!` / breaking → major, `feat` → minor, `fix` / `chore` → patch) but **do not** choose for them. **Do not** edit files yet.
25
+
26
+ ---
27
+
28
+ ## Phase 2 — Sync, surface state, empty-release gate
29
+
30
+ Run from **`muggle-ai-works`**:
31
+
32
+ ```bash
33
+ git checkout master && git pull --ff-only && git fetch --tags
34
+ ```
35
+
36
+ Show what is shipping:
37
+
38
+ ```bash
39
+ node -e 'console.log("master package.json:", require("./package.json").version)'
40
+ npm view @muggleai/works version 2>&1 | sed 's/^/npm latest: /'
41
+ ```
42
+
43
+ **Commits since the last release commit** (stop if there is nothing to ship):
44
+
45
+ ```bash
46
+ LAST_RELEASE_SHA=$(git log --grep='chore(release)' --format='%H' -1)
47
+ git log --oneline "$LAST_RELEASE_SHA..HEAD"
48
+ ```
49
+
50
+ - If the log is **empty**, tell the user there is **nothing to ship** and **stop** (no branch, no bump, no PR).
51
+ - If non-empty, present commits as a short table (subject; PR number from title/body if present).
52
+
53
+ ---
54
+
55
+ ## Phase 3 — Version baseline, Electron, print summary, confirm
56
+
57
+ ### npm version (`nextNpmVersion`)
58
+
59
+ 1. **`npm view @muggleai/works version`** — last published on npm.
60
+ 2. Root **`package.json` → `version`** on current **`master`** checkout.
61
+ 3. **Baseline** = **semver-higher** of those two (never target below repo or npm).
62
+ 4. Apply the user’s **major / minor / patch** to that baseline → **`nextNpmVersion`** (semver-correct).
63
+
64
+ ### Electron (`muggleConfig`)
65
+
66
+ 1. Read **`package.json` → `muggleConfig.electronAppVersion`**.
67
+ 2. **Latest desktop on GitHub:**
68
+ `https://api.github.com/repos/multiplex-ai/muggle-ai-works/releases?per_page=30`
69
+ → newest **`tag_name`** matching **`electron-app-v*`** → strip prefix → **`latestElectronVersion`** (semver only).
70
+
71
+ ### Print (always)
72
+
73
+ | Item | Value |
74
+ | :--- | :---- |
75
+ | Last **@muggleai/works** on npm | … |
76
+ | **Baseline** for bump | … |
77
+ | **`nextNpmVersion`** (to publish) | … |
78
+ | Current **`electronAppVersion`** | … |
79
+ | Latest **`electron-app-v…`** on GitHub | … |
80
+
81
+ ### Electron bump decision
82
+
83
+ If **`latestElectronVersion`** ≠ current **`electronAppVersion`**, ask: **bump** Electron + all four **`muggleConfig.checksums`** to **`latestElectronVersion`**, or **keep** current.
84
+
85
+ If bumping, checksums from:
86
+
87
+ `https://github.com/multiplex-ai/muggle-ai-works/releases/download/electron-app-vVERSION/checksums.txt`
88
+
89
+ Map zip artifacts → **`darwin-arm64`**, **`darwin-x64`**, **`win32-x64`**, **`linux-x64`** (same mapping rules as today).
90
+
91
+ **Stop again:** user must **confirm** the full plan (**`nextNpmVersion`** + Electron choice). If they cancel, **do not** branch, merge, or dispatch CI.
92
+
93
+ ---
94
+
95
+ ## Phase 4 — After explicit confirmation only
96
+
97
+ ### 1. Branch and bump
98
+
99
+ ```bash
100
+ git checkout -b "chore/release-<VERSION>"
101
+ npm version "<VERSION>" --no-git-tag-version
102
+ ```
103
+
104
+ Replace **`<VERSION>`** with **`nextNpmVersion`** (dots in the branch name are fine, e.g. `chore/release-4.8.0`).
105
+
106
+ - If Electron bump agreed: set **`muggleConfig.electronAppVersion`** and all four **`muggleConfig.checksums`** in **`package.json`**.
107
+
108
+ ### 2. Propagate versions (do not hand-edit manifests)
109
+
110
+ ```bash
111
+ pnpm run sync:versions
112
+ ```
113
+
114
+ Never hand-edit **`.claude-plugin/marketplace.json`**, **`.cursor-plugin/marketplace.json`**, **`plugin/.claude-plugin/plugin.json`**, **`plugin/.cursor-plugin/plugin.json`**, or **`server.json`** — **`sync-versions`** (and **`build`**) owns them.
115
+
116
+ If you changed Electron after the first sync, run **`pnpm run sync:versions`** again.
117
+
118
+ ### 3. Full local verify (before push)
119
+
120
+ ```bash
121
+ pnpm run lint:check && pnpm run typecheck && pnpm test && pnpm run build && pnpm run verify:plugin && pnpm run verify:contracts && pnpm run verify:electron-release-checksums
122
+ ```
123
+
124
+ - **`pnpm run build`** is required before **`verify:plugin`** — the verifier reads the **built** plugin under **`dist/plugin/`**, not source under **`plugin/`**.
125
+ - If **anything** fails, **stop** and surface the error; **do not** push a broken release.
126
+
127
+ ### 4. Commit (**`chore(release)`**)
128
+
129
+ Stage version-touched files (at minimum **`package.json`** plus whatever **`sync:versions`** changed — typically the marketplace/plugin **`server.json`** paths above).
130
+
131
+ **Subject:** `chore(release): @muggleai/works <VERSION>`
132
+
133
+ **Body:** one bullet per shipping PR / theme, note **Electron** bump or unchanged, and any coordinated follow-ups in sibling repos (e.g. teaching-service, UI). Use a **heredoc** for `git commit` so newlines are preserved.
134
+
135
+ ### 5. PR, merge, update local **`master`**
136
+
137
+ ```bash
138
+ git push -u origin HEAD
139
+ gh pr create --repo multiplex-ai/muggle-ai-works --base master --head <branch> \
140
+ --title "chore(release): @muggleai/works <VERSION>" \
141
+ --body "<PR body: version delta, bump rationale, shipping list, Electron status, manifests touched by sync:versions, short test plan checklist>"
142
+ ```
143
+
144
+ **Merge:** when the human has approved the release in this session, run **`gh pr merge`** (squash is fine unless the repo prefers merge commits), then:
145
+
146
+ ```bash
147
+ git checkout master && git pull --ff-only
148
+ node -e 'console.log("master now:", require("./package.json").version)'
149
+ ```
150
+
151
+ Confirm **`package.json`** on **`master`** matches **`nextNpmVersion`** before publishing.
152
+
153
+ ---
154
+
155
+ ## Phase 5 — Trigger publish (CI only)
156
+
157
+ Prefer **explicit version** (not “auto bump”):
158
+
159
+ ```bash
160
+ gh workflow run publish-works-to-npm.yml --repo multiplex-ai/muggle-ai-works --ref master \
161
+ --field "version=<VERSION>" --field "bump=patch"
162
+ ```
163
+
164
+ The `bump=patch` field is a harmless placeholder when `version` is set; the workflow prefers the explicit `version` input.
165
+
166
+ **Or** **`git tag "v<VERSION>"`** && **`git push origin "v<VERSION>"`** only if that tag **does not** already exist on the remote; if the tag exists, use **`workflow_dispatch`** with **`version`**.
167
+
168
+ Watch the run and confirm jobs succeed:
169
+
170
+ ```bash
171
+ gh run list --repo multiplex-ai/muggle-ai-works --workflow=publish-works-to-npm.yml --limit 1
172
+ gh run watch <RUN_ID> --repo multiplex-ai/muggle-ai-works --exit-status
173
+ ```
174
+
175
+ Verify the registry:
176
+
177
+ ```bash
178
+ npm view @muggleai/works version
179
+ ```
180
+
181
+ Give the user the **Actions run URL**. If npm lags, wait ~60s and retry.
182
+
183
+ ---
184
+
185
+ ## Rules
186
+
187
+ - **No local `npm publish`.**
188
+ - **Phase 1:** use **`AskQuestion`** for major / minor / patch when available (see Phase 1).
189
+ - Phases 1–3: keep chat concise; Phase 4–5 can be terse status lines.
190
+ - If the user cancels after Phase 3, **do not** merge or dispatch CI.
191
+ - **Tag vs npm:** **`v*`** tags are for the **npm** package; **`electron-app-v*`** is separate — **`electronAppVersion`** can move independently of **`version`**.
192
+
193
+ ---
194
+
195
+ ## Notes (troubleshooting)
196
+
197
+ - Workflow **`name:`** / filename is tied to npm **Trusted Publishing** — see the comment block at the top of **`publish-works-to-npm.yml`** if auth fails.
198
+ - If commits land on **`master`** between opening the PR and merging, re-check **`git log`** vs the last **`chore(release)`** before merging; rebasing the release branch may be needed so **`master`** still matches what you intend to ship.