@muggleai/works 4.7.0 → 4.8.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 CHANGED
@@ -554,12 +554,7 @@ CI/CD and publishing
554
554
  | `verify-end-user-upgrade.yml` | Weekly + manual | Existing-user upgrade validation (cleanup + re-download + health checks) |
555
555
  | `publish-works-to-npm.yml` | Tag `v*` or manual | Verify (including release checksums), audit, smoke-install, publish to npm |
556
556
 
557
-
558
- ```bash
559
- git tag v<version> && git push --tags
560
- # publish-works-to-npm.yml handles the rest
561
- ```
562
-
557
+ **Publishing `@muggleai/works`:** use the repo-level skill **`plugin/skills/muggle-works-npm-release/SKILL.md`** (bump + `pnpm run sync:versions`, local verify, `chore(release)` PR, merge, then `workflow_dispatch` with an explicit `version`). Do not rely on tagging alone while `package.json` / marketplace manifests on `master` are still old — CI can publish a version that does not match the checked-in manifests. Tag `v*` push remains a valid workflow trigger when it matches the merged release commit.
563
558
 
564
559
  Release tag strategy
565
560
 
@@ -1,4 +1,4 @@
1
- import { __export, getLogger, getConfig, createChildLogger, buildElectronAppReleaseAssetUrl, getAuthService, hasApiKey, getElectronAppVersion, getElectronAppDir, getPlatformKey, isElectronAppInstalled, getElectronAppChecksums, getChecksumForPlatform, verifyFileChecksum, calculateFileChecksum, getQaTools, getLocalQaTools, performLogout, performLogin, toolRequiresAuth, getCallerCredentials, getDataDir, getBundledElectronAppVersion, getElectronAppVersionSource, getCredentialsFilePath, buildElectronAppChecksumsUrl, __require } from './chunk-HDEZDEM6.js';
1
+ import { __export, getLogger, getConfig, createChildLogger, buildElectronAppReleaseAssetUrl, getAuthService, hasApiKey, getElectronAppVersion, getElectronAppDir, getPlatformKey, isElectronAppInstalled, getElectronAppChecksums, getChecksumForPlatform, verifyFileChecksum, calculateFileChecksum, getQaTools, getLocalQaTools, performLogout, performLogin, toolRequiresAuth, getCallerCredentials, getDataDir, getBundledElectronAppVersion, getElectronAppVersionSource, getCredentialsFilePath, buildElectronAppChecksumsUrl, __require } from './chunk-OUI734ME.js';
2
2
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
3
  import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';
4
4
  import { v4 } from 'uuid';
@@ -686,7 +686,7 @@ async function resolveGsScreenshotUrls(report, opts) {
686
686
  if (gsUrls.length === 0) {
687
687
  return report;
688
688
  }
689
- const mcps = await import('./src-TX2KXI26.js');
689
+ const mcps = await import('./src-2IDMKEJ5.js');
690
690
  const credentials = await mcps.getCallerCredentialsAsync();
691
691
  if (!credentials.bearerToken && !credentials.apiKey) {
692
692
  stderrWrite(
@@ -2407,9 +2407,11 @@ ${executionResult.stderr}`;
2407
2407
  `Generated script does not contain a valid 'steps' array. File: ${generatedScriptPath}`
2408
2408
  );
2409
2409
  }
2410
+ const generatedSummaryStep = generatedScript.summaryStep;
2410
2411
  storage.updateTestScript(localTestScript.id, {
2411
2412
  status: "generated",
2412
- actionScript: generatedSteps
2413
+ actionScript: generatedSteps,
2414
+ summaryStep: generatedSummaryStep
2413
2415
  });
2414
2416
  const artifactsDir = await moveResultsToArtifacts({
2415
2417
  runId,
@@ -5629,6 +5631,7 @@ var publishTestScriptTool = {
5629
5631
  uploadedAt
5630
5632
  },
5631
5633
  actionScript: testScript.actionScript,
5634
+ summaryStep: testScript.summaryStep,
5632
5635
  status: runResult.status === "passed" ? "passed" : "failed",
5633
5636
  executionTimeMs: runResult.executionTimeMs,
5634
5637
  errorMessage: runResult.errorMessage
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { runCli } from './chunk-SMRMPHDD.js';
3
- import './chunk-HDEZDEM6.js';
2
+ import { runCli } from './chunk-2ZDLQAO4.js';
3
+ import './chunk-OUI734ME.js';
4
4
 
5
5
  // src/cli/main.ts
6
6
  runCli().catch((error) => {
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { src_exports as commands, createUnifiedMcpServer, server_exports as server } from './chunk-SMRMPHDD.js';
2
- export { createChildLogger, e2e_exports as e2e, getConfig, getLocalQaTools, getLogger, getQaTools, local_exports as localQa, mcp_exports as mcp, e2e_exports as qa, src_exports as shared } from './chunk-HDEZDEM6.js';
1
+ export { src_exports as commands, createUnifiedMcpServer, server_exports as server } from './chunk-2ZDLQAO4.js';
2
+ export { createChildLogger, e2e_exports as e2e, getConfig, getLocalQaTools, getLogger, getQaTools, local_exports as localQa, mcp_exports as mcp, e2e_exports as qa, src_exports as shared } from './chunk-OUI734ME.js';
@@ -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.0",
5
5
  "author": {
6
6
  "name": "Muggle AI",
7
7
  "email": "support@muggle-ai.com"
@@ -2,7 +2,7 @@
2
2
  "name": "muggle",
3
3
  "displayName": "Muggle AI",
4
4
  "description": "Ship quality products with AI-powered end-to-end (E2E) acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
5
- "version": "4.7.0",
5
+ "version": "4.8.0",
6
6
  "author": {
7
7
  "name": "Muggle AI",
8
8
  "email": "support@muggle-ai.com"
@@ -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.0",
3
+ "buildId": "run-19-1",
4
+ "commitSha": "970c730d39e45df17c9f9498ddcad410beafb8fb",
5
+ "buildTime": "2026-04-12T05:58:39Z",
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-OUI734ME.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.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.0.51",
44
+ "electronAppVersion": "1.0.55",
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": "b489ecb3273d8c15727ab80430468099a41e58417ef0f853de435f13aff0d903",
49
+ "darwin-x64": "38a34f45a23a9b53e3383c1f016363a294a28c3abdc454da35a34f1b03ddc191",
50
+ "win32-x64": "795495f9ddaab676e60f0140651c04f8d375adbadd3258a387bc7c82581c6d76",
51
+ "linux-x64": "2005101c8b23bce055c2d059e0a123f2b795779fd88df3658fdd1b74f4684599"
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.0",
5
5
  "author": {
6
6
  "name": "Muggle AI",
7
7
  "email": "support@muggle-ai.com"
@@ -2,7 +2,7 @@
2
2
  "name": "muggle",
3
3
  "displayName": "Muggle AI",
4
4
  "description": "Ship quality products with AI-powered end-to-end (E2E) acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
5
- "version": "4.7.0",
5
+ "version": "4.8.0",
6
6
  "author": {
7
7
  "name": "Muggle AI",
8
8
  "email": "support@muggle-ai.com"
@@ -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.