@muggleai/works 4.10.0 → 4.10.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.
Files changed (187) hide show
  1. package/README.md +3 -3
  2. package/dist/{chunk-RK6XKSZK.js → chunk-Q7WNEMN4.js} +109 -43
  3. package/dist/{chunk-UVXOHXY2.js → chunk-ZKRHFTIC.js} +832 -89
  4. package/dist/cli.js +2 -2
  5. package/dist/index.js +2 -2
  6. package/dist/plugin/.claude-plugin/plugin.json +1 -1
  7. package/dist/plugin/.cursor-plugin/plugin.json +1 -1
  8. package/dist/plugin/README.md +4 -2
  9. package/dist/plugin/agents/acceptance-tester.md +24 -10
  10. package/dist/plugin/commands/m.md +7 -0
  11. package/dist/plugin/commands/mdo.md +7 -0
  12. package/dist/plugin/commands/mfeedback.md +7 -0
  13. package/dist/plugin/commands/mimport.md +7 -0
  14. package/dist/plugin/commands/mpr.md +7 -0
  15. package/dist/plugin/commands/mprefs.md +7 -0
  16. package/dist/plugin/commands/mregen.md +7 -0
  17. package/dist/plugin/commands/mrelease.md +7 -0
  18. package/dist/plugin/commands/mrepair.md +7 -0
  19. package/dist/plugin/commands/mstatus.md +7 -0
  20. package/dist/plugin/commands/mtest.md +7 -0
  21. package/dist/plugin/commands/mtestlocal.md +7 -0
  22. package/dist/plugin/commands/mtestprep.md +7 -0
  23. package/dist/plugin/commands/mupgrade.md +7 -0
  24. package/dist/plugin/scripts/ensure-electron-app.sh +35 -8
  25. package/dist/plugin/skills/_aliases.json +18 -0
  26. package/dist/plugin/skills/_shared/dev-server-readiness.md +231 -0
  27. package/dist/plugin/skills/_shared/failure-mode-handling.md +244 -0
  28. package/dist/plugin/skills/_shared/post-merge-cleanup.md +10 -0
  29. package/dist/plugin/skills/_shared/rebase-before-e2e.md +15 -0
  30. package/dist/plugin/skills/_shared/telemetry-emit.md +15 -0
  31. package/dist/plugin/skills/_shared/use-worktrees.md +53 -0
  32. package/dist/plugin/skills/do/e2e-acceptance.md +63 -18
  33. package/dist/plugin/skills/do/impact-analysis.md +45 -5
  34. package/dist/plugin/skills/do/open-prs.md +13 -4
  35. package/dist/plugin/skills/do/pr-followup.md +225 -0
  36. package/dist/plugin/skills/do/pre-flight.md +18 -11
  37. package/dist/plugin/skills/m/SKILL.md +8 -0
  38. package/dist/plugin/skills/mdo/SKILL.md +8 -0
  39. package/dist/plugin/skills/mfeedback/SKILL.md +8 -0
  40. package/dist/plugin/skills/mimport/SKILL.md +8 -0
  41. package/dist/plugin/skills/mpr/SKILL.md +8 -0
  42. package/dist/plugin/skills/mprefs/SKILL.md +8 -0
  43. package/dist/plugin/skills/mregen/SKILL.md +8 -0
  44. package/dist/plugin/skills/mrelease/SKILL.md +8 -0
  45. package/dist/plugin/skills/mrepair/SKILL.md +8 -0
  46. package/dist/plugin/skills/mstatus/SKILL.md +8 -0
  47. package/dist/plugin/skills/mtest/SKILL.md +8 -0
  48. package/dist/plugin/skills/mtestlocal/SKILL.md +8 -0
  49. package/dist/plugin/skills/mtestprep/SKILL.md +8 -0
  50. package/dist/plugin/skills/muggle/SKILL.md +9 -6
  51. package/dist/plugin/skills/muggle-do/SKILL.md +22 -4
  52. package/dist/plugin/skills/muggle-do-pr-followup/SKILL.md +37 -0
  53. package/dist/plugin/skills/muggle-do-task/SKILL.md +134 -0
  54. package/dist/plugin/skills/muggle-feedback/SKILL.md +38 -0
  55. package/dist/plugin/skills/muggle-feedback/ops/delete.md +49 -0
  56. package/dist/plugin/skills/muggle-feedback/ops/list.md +65 -0
  57. package/dist/plugin/skills/muggle-feedback/ops/submit.md +117 -0
  58. package/dist/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +68 -43
  59. package/dist/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
  60. package/dist/plugin/skills/muggle-preferences/SKILL.md +16 -108
  61. package/dist/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
  62. package/dist/plugin/skills/muggle-preferences/ops/configure.md +49 -0
  63. package/dist/plugin/skills/muggle-preferences/ops/list.md +9 -0
  64. package/dist/plugin/skills/muggle-preferences/ops/reset.md +6 -0
  65. package/dist/plugin/skills/muggle-preferences/ops/set.md +10 -0
  66. package/dist/plugin/skills/muggle-preferences/preference-gates/README.md +1 -1
  67. package/dist/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
  68. package/dist/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
  69. package/dist/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +3 -3
  70. package/dist/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
  71. package/dist/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +1 -1
  72. package/dist/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +2 -2
  73. package/dist/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
  74. package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
  75. package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +1 -2
  76. package/dist/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
  77. package/dist/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +4 -4
  78. package/dist/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +1 -1
  79. package/dist/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +1 -1
  80. package/dist/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +8 -25
  81. package/dist/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +1 -1
  82. package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +4 -4
  83. package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +4 -4
  84. package/dist/plugin/skills/muggle-repair/SKILL.md +4 -2
  85. package/dist/plugin/skills/muggle-status/SKILL.md +8 -5
  86. package/dist/plugin/skills/muggle-test/SKILL.md +110 -86
  87. package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +73 -66
  88. package/dist/plugin/skills/muggle-test-import/SKILL.md +28 -23
  89. package/dist/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
  90. package/dist/plugin/skills/muggle-test-regenerate-missing/SKILL.md +34 -18
  91. package/dist/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
  92. package/dist/plugin/skills/muggle-upgrade/SKILL.md +4 -2
  93. package/dist/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
  94. package/dist/plugin/skills/mupgrade/SKILL.md +8 -0
  95. package/dist/release-manifest.json +4 -4
  96. package/dist/{src-GD3YFCCW.js → src-2G7ENRGI.js} +1 -1
  97. package/package.json +9 -7
  98. package/plugin/.claude-plugin/plugin.json +1 -1
  99. package/plugin/.cursor-plugin/plugin.json +1 -1
  100. package/plugin/README.md +4 -2
  101. package/plugin/agents/acceptance-tester.md +24 -10
  102. package/plugin/commands/m.md +7 -0
  103. package/plugin/commands/mdo.md +7 -0
  104. package/plugin/commands/mfeedback.md +7 -0
  105. package/plugin/commands/mimport.md +7 -0
  106. package/plugin/commands/mpr.md +7 -0
  107. package/plugin/commands/mprefs.md +7 -0
  108. package/plugin/commands/mregen.md +7 -0
  109. package/plugin/commands/mrelease.md +7 -0
  110. package/plugin/commands/mrepair.md +7 -0
  111. package/plugin/commands/mstatus.md +7 -0
  112. package/plugin/commands/mtest.md +7 -0
  113. package/plugin/commands/mtestlocal.md +7 -0
  114. package/plugin/commands/mtestprep.md +7 -0
  115. package/plugin/commands/mupgrade.md +7 -0
  116. package/plugin/scripts/ensure-electron-app.sh +35 -8
  117. package/plugin/skills/_aliases.json +18 -0
  118. package/plugin/skills/_shared/dev-server-readiness.md +231 -0
  119. package/plugin/skills/_shared/failure-mode-handling.md +244 -0
  120. package/plugin/skills/_shared/post-merge-cleanup.md +10 -0
  121. package/plugin/skills/_shared/rebase-before-e2e.md +15 -0
  122. package/plugin/skills/_shared/telemetry-emit.md +15 -0
  123. package/plugin/skills/_shared/use-worktrees.md +53 -0
  124. package/plugin/skills/do/e2e-acceptance.md +63 -18
  125. package/plugin/skills/do/impact-analysis.md +45 -5
  126. package/plugin/skills/do/open-prs.md +13 -4
  127. package/plugin/skills/do/pr-followup.md +225 -0
  128. package/plugin/skills/do/pre-flight.md +18 -11
  129. package/plugin/skills/m/SKILL.md +8 -0
  130. package/plugin/skills/mdo/SKILL.md +8 -0
  131. package/plugin/skills/mfeedback/SKILL.md +8 -0
  132. package/plugin/skills/mimport/SKILL.md +8 -0
  133. package/plugin/skills/mpr/SKILL.md +8 -0
  134. package/plugin/skills/mprefs/SKILL.md +8 -0
  135. package/plugin/skills/mregen/SKILL.md +8 -0
  136. package/plugin/skills/mrelease/SKILL.md +8 -0
  137. package/plugin/skills/mrepair/SKILL.md +8 -0
  138. package/plugin/skills/mstatus/SKILL.md +8 -0
  139. package/plugin/skills/mtest/SKILL.md +8 -0
  140. package/plugin/skills/mtestlocal/SKILL.md +8 -0
  141. package/plugin/skills/mtestprep/SKILL.md +8 -0
  142. package/plugin/skills/muggle/SKILL.md +9 -6
  143. package/plugin/skills/muggle-do/SKILL.md +22 -4
  144. package/plugin/skills/muggle-do-pr-followup/SKILL.md +37 -0
  145. package/plugin/skills/muggle-do-task/SKILL.md +134 -0
  146. package/plugin/skills/muggle-feedback/SKILL.md +38 -0
  147. package/plugin/skills/muggle-feedback/ops/delete.md +49 -0
  148. package/plugin/skills/muggle-feedback/ops/list.md +65 -0
  149. package/plugin/skills/muggle-feedback/ops/submit.md +117 -0
  150. package/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +68 -43
  151. package/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
  152. package/plugin/skills/muggle-preferences/SKILL.md +16 -108
  153. package/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
  154. package/plugin/skills/muggle-preferences/ops/configure.md +49 -0
  155. package/plugin/skills/muggle-preferences/ops/list.md +9 -0
  156. package/plugin/skills/muggle-preferences/ops/reset.md +6 -0
  157. package/plugin/skills/muggle-preferences/ops/set.md +10 -0
  158. package/plugin/skills/muggle-preferences/preference-gates/README.md +1 -1
  159. package/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
  160. package/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
  161. package/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +3 -3
  162. package/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
  163. package/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +1 -1
  164. package/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +2 -2
  165. package/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
  166. package/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
  167. package/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +1 -2
  168. package/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
  169. package/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +4 -4
  170. package/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +1 -1
  171. package/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +1 -1
  172. package/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +8 -25
  173. package/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +1 -1
  174. package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +4 -4
  175. package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +4 -4
  176. package/plugin/skills/muggle-repair/SKILL.md +4 -2
  177. package/plugin/skills/muggle-status/SKILL.md +8 -5
  178. package/plugin/skills/muggle-test/SKILL.md +110 -86
  179. package/plugin/skills/muggle-test-feature-local/SKILL.md +73 -66
  180. package/plugin/skills/muggle-test-import/SKILL.md +28 -23
  181. package/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
  182. package/plugin/skills/muggle-test-regenerate-missing/SKILL.md +34 -18
  183. package/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
  184. package/plugin/skills/muggle-upgrade/SKILL.md +4 -2
  185. package/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
  186. package/plugin/skills/mupgrade/SKILL.md +8 -0
  187. package/scripts/postinstall.mjs +11 -1
package/README.md CHANGED
@@ -19,7 +19,7 @@ Your AI assistant writes code fast. But does the feature actually work? Does the
19
19
 
20
20
  muggle-ai-works closes the gap between "code complete" and "actually works."
21
21
 
22
- - **Catch UX regressions before your users do** — AI drives a real browser against your localhost across desktop and mobile resolutions, clicks through flows like a user would, and reports failures with step-by-step screenshots. No Playwright scripts to maintain.
22
+ - **Catch UX regressions before your users do** — `/muggle:muggle-test` AI drives a real browser against your localhost across desktop and mobile resolutions, clicks through flows like a user would, and reports failures with step-by-step screenshots. No Playwright scripts to maintain.
23
23
  - **Go from requirement to merged PR in one command** — `/muggle:muggle-do` handles the full cycle: code the feature, run unit tests, run E2E acceptance tests against the app in a real browser at multiple viewports, triage failures, and open a PR with evidence attached.
24
24
  - **70+ MCP tools for custom workflows** — manage projects, generate test cases from plain English, replay test scripts, batch-run regressions, and publish results to your team. Works in Claude Code, Cursor, and any MCP client.
25
25
 
@@ -27,7 +27,7 @@ muggle-ai-works closes the gap between "code complete" and "actually works."
27
27
 
28
28
  ## Quick Start
29
29
 
30
- ### 1. Install (choose your client)
30
+ ### 1. Install skills and mcps (choose your client)
31
31
 
32
32
  **Claude Code (full plugin experience)**
33
33
 
@@ -613,4 +613,4 @@ See `internal/skills/optimize-descriptions/SKILL.md` for the full guide.
613
613
 
614
614
  [MIT](LICENSE) — Use it, fork it, make it yours.
615
615
 
616
- If this helps your development workflow, consider giving it a star. It helps others find it.
616
+ If this helps your development workflow, consider giving it a star. It helps others find it.
@@ -1,4 +1,4 @@
1
- import { __export, getLogger, getConfig, createChildLogger, buildElectronAppReleaseAssetUrl, getAuthService, hasApiKey, getElectronAppVersion, getElectronAppDir, getPlatformKey, isFirstRun, writePreferences, DEFAULT_PREFERENCES, getDataDir, PREFERENCES_FILE_NAME, isElectronAppInstalled, getElectronAppChecksums, getChecksumForPlatform, verifyFileChecksum, calculateFileChecksum, getQaTools, getLocalQaTools, performLogout, performLogin, toolRequiresAuth, getCallerCredentials, getBundledElectronAppVersion, getElectronAppVersionSource, getCredentialsFilePath, buildElectronAppChecksumsUrl, __require } from './chunk-UVXOHXY2.js';
1
+ import { __export, getLogger, getConfig, createChildLogger, buildElectronAppReleaseAssetUrl, getAuthService, hasApiKey, getElectronAppVersion, getElectronAppDir, getPlatformKey, isFirstRun, writePreferences, DEFAULT_PREFERENCES, getDataDir, PREFERENCES_FILE_NAME, isElectronAppInstalled, getElectronAppChecksums, getChecksumForPlatform, verifyFileChecksum, calculateFileChecksum, initTelemetry, Surface, ServiceName, track, EventName, getQaTools, getLocalQaTools, performLogout, performLogin, toolRequiresAuth, getCallerCredentials, getBundledElectronAppVersion, getElectronAppVersionSource, getCredentialsFilePath, buildElectronAppChecksumsUrl, __require } from './chunk-ZKRHFTIC.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';
@@ -6,7 +6,7 @@ import { z, ZodError } from 'zod';
6
6
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
7
7
  import * as fs from 'fs';
8
8
  import { readFileSync, existsSync, rmSync, mkdirSync, readdirSync, createWriteStream, writeFileSync, statSync } from 'fs';
9
- import * as path4 from 'path';
9
+ import * as path from 'path';
10
10
  import { dirname, resolve, join } from 'path';
11
11
  import { fileURLToPath } from 'url';
12
12
  import { Command } from 'commander';
@@ -338,10 +338,31 @@ function countTests(report) {
338
338
  const total = report.tests.length;
339
339
  const passed = report.tests.filter((t) => t.status === "passed").length;
340
340
  const failed = report.tests.filter((t) => t.status === "failed").length;
341
- return { total, passed, failed };
341
+ const inconclusive = report.tests.filter((t) => t.status === "inconclusive").length;
342
+ return { total, passed, failed, inconclusive };
342
343
  }
343
344
  function statusEmoji(test) {
344
- return test.status === "passed" ? "\u2705" : "\u274C";
345
+ if (test.status === "passed") return "\u2705";
346
+ if (test.status === "failed") return "\u274C";
347
+ return "\u26A0\uFE0F";
348
+ }
349
+ function computeVerdict(report) {
350
+ if (report.tests.length === 0) return "none";
351
+ if (report.tests.some((t) => t.status === "failed")) return "fail";
352
+ if (report.tests.some((t) => t.status === "inconclusive")) return "inconclusive";
353
+ return "pass";
354
+ }
355
+ function renderVerdictLine(verdict) {
356
+ switch (verdict) {
357
+ case "pass":
358
+ return "**Verdict: \u2705 PASS**";
359
+ case "fail":
360
+ return "**Verdict: \u274C FAIL**";
361
+ case "inconclusive":
362
+ return "**Verdict: \u26A0\uFE0F INCONCLUSIVE**";
363
+ case "none":
364
+ return null;
365
+ }
345
366
  }
346
367
  function endingScreenshot(test) {
347
368
  if (test.steps.length === 0) {
@@ -360,6 +381,9 @@ function defaultEndingCaption(test) {
360
381
  if (test.status === "failed") {
361
382
  return `Failure at step ${test.failureStepIndex}`;
362
383
  }
384
+ if (test.status === "inconclusive") {
385
+ return "Last frame before run was cut short";
386
+ }
363
387
  return "Final page after the test completed";
364
388
  }
365
389
  function endingFrame(test) {
@@ -392,12 +416,14 @@ function buildTestNumbering(report) {
392
416
  return map;
393
417
  }
394
418
  function renderOverview(report) {
395
- const { total, passed, failed } = countTests(report);
396
- const lines = [
397
- "## E2E Acceptance Results",
398
- "",
399
- `**${total} tests ran \u2014 ${passed} passed / ${failed} failed**`
400
- ];
419
+ const { total, passed, failed, inconclusive } = countTests(report);
420
+ const verdict = computeVerdict(report);
421
+ const verdictLine = renderVerdictLine(verdict);
422
+ const lines = ["## E2E Acceptance Results", ""];
423
+ if (verdictLine) {
424
+ lines.push(verdictLine, "");
425
+ }
426
+ lines.push(`**${total} tests ran \u2014 ${passed} passed / ${failed} failed / ${inconclusive} inconclusive**`);
401
427
  if (total === 0) {
402
428
  lines.push("", "_No tests were executed._");
403
429
  return lines.join("\n");
@@ -458,12 +484,12 @@ ${body.join("\n")}
458
484
  </details>`;
459
485
  }
460
486
  function renderSummaryLine(test, testNumber) {
461
- const base = `<b>${testNumber}. ${test.name}</b> ${statusEmoji(test)}`;
462
- const tail = " <i>\u25B6 click to expand</i>";
487
+ const base = `<b>${test.name}</b> ${statusEmoji(test)}`;
488
+ const head = "<i>\u25B6 click to expand</i> ";
463
489
  if (test.description) {
464
- return `${base} \u2014 ${test.description}${tail}`;
490
+ return `<b>${testNumber}. </b>${head}${base} \u2014 ${test.description}`;
465
491
  }
466
- return `${base}${tail}`;
492
+ return `<b>${testNumber}. </b>${head}${base}`;
467
493
  }
468
494
  function renderEndingFrame(test) {
469
495
  const frame = endingFrame(test);
@@ -481,12 +507,15 @@ function renderResultSummary(test, projectId) {
481
507
  const lines = [];
482
508
  if (test.status === "passed") {
483
509
  lines.push(`**Result:** \u2705 PASSED`);
484
- } else {
510
+ } else if (test.status === "failed") {
485
511
  lines.push(`**Result:** \u274C FAILED at step ${test.failureStepIndex}`);
486
512
  lines.push(`**Error:** \`${safeInlineCode(test.error)}\``);
513
+ } else {
514
+ lines.push(`**Result:** \u26A0\uFE0F INCONCLUSIVE`);
515
+ lines.push(`**Reason:** \`${safeInlineCode(test.reason)}\``);
487
516
  }
488
517
  lines.push(`**Steps:** ${test.steps.length}`);
489
- lines.push(`[View steps on Muggle AI \u2192](${dashboardUrl})`);
518
+ lines.push(`<a href="${dashboardUrl}" target="_blank" rel="noopener noreferrer">View steps on Muggle AI \u2192</a>`);
490
519
  return lines;
491
520
  }
492
521
  function renderBody(report, opts) {
@@ -577,9 +606,25 @@ var FailedTestSchema = z.object({
577
606
  endingScreenshotUrl: z.string().url().optional(),
578
607
  endingScreenshotCaption: z.string().min(1).optional()
579
608
  });
609
+ var InconclusiveTestSchema = z.object({
610
+ name: z.string().min(1),
611
+ testCaseId: z.string().min(1),
612
+ testScriptId: z.string().min(1).optional(),
613
+ runId: z.string().min(1),
614
+ viewUrl: z.string().url(),
615
+ status: z.literal("inconclusive"),
616
+ steps: z.array(StepSchema),
617
+ reason: z.string().min(1),
618
+ artifactsDir: z.string().min(1).optional(),
619
+ useCaseName: z.string().min(1).optional(),
620
+ description: z.string().min(1).optional(),
621
+ endingScreenshotUrl: z.string().url().optional(),
622
+ endingScreenshotCaption: z.string().min(1).optional()
623
+ });
580
624
  var TestResultSchema = z.discriminatedUnion("status", [
581
625
  PassedTestSchema,
582
- FailedTestSchema
626
+ FailedTestSchema,
627
+ InconclusiveTestSchema
583
628
  ]);
584
629
  var E2eReportSchema = z.object({
585
630
  projectId: z.string().min(1),
@@ -686,7 +731,7 @@ async function resolveGsScreenshotUrls(report, opts) {
686
731
  if (gsUrls.length === 0) {
687
732
  return report;
688
733
  }
689
- const mcps = await import('./src-GD3YFCCW.js');
734
+ const mcps = await import('./src-2G7ENRGI.js');
690
735
  const credentials = await mcps.getCallerCredentialsAsync();
691
736
  if (!credentials.bearerToken && !credentials.apiKey) {
692
737
  stderrWrite(
@@ -805,15 +850,28 @@ var ELECTRON_APP_DIR = "electron-app";
805
850
  var CURSOR_SKILLS_DIR = ".cursor";
806
851
  var CURSOR_SKILLS_SUBDIR = "skills";
807
852
  var MUGGLE_SKILL_PREFIX = "muggle";
853
+ function loadMuggleAliasSkills() {
854
+ let dir = path.dirname(fileURLToPath(import.meta.url));
855
+ while (dir !== path.dirname(dir)) {
856
+ const manifestPath = path.join(dir, "plugin", "skills", "_aliases.json");
857
+ if (existsSync(manifestPath)) {
858
+ const parsed = JSON.parse(readFileSync(manifestPath, "utf-8"));
859
+ return new Set(parsed.aliases);
860
+ }
861
+ dir = path.dirname(dir);
862
+ }
863
+ throw new Error("Could not locate plugin/skills/_aliases.json relative to cleanup module");
864
+ }
865
+ var MUGGLE_ALIAS_SKILLS = loadMuggleAliasSkills();
808
866
  var INSTALL_MANIFEST_FILE = "install-manifest.json";
809
867
  function getElectronAppBaseDir() {
810
- return path4.join(getDataDir(), ELECTRON_APP_DIR);
868
+ return path.join(getDataDir(), ELECTRON_APP_DIR);
811
869
  }
812
870
  function getCursorSkillsDir() {
813
- return path4.join(homedir(), CURSOR_SKILLS_DIR, CURSOR_SKILLS_SUBDIR);
871
+ return path.join(homedir(), CURSOR_SKILLS_DIR, CURSOR_SKILLS_SUBDIR);
814
872
  }
815
873
  function getInstallManifestPath() {
816
- return path4.join(getDataDir(), INSTALL_MANIFEST_FILE);
874
+ return path.join(getDataDir(), INSTALL_MANIFEST_FILE);
817
875
  }
818
876
  function readInstallManifest() {
819
877
  const manifestPath = getInstallManifestPath();
@@ -845,13 +903,13 @@ function listObsoleteSkills() {
845
903
  if (!entry.isDirectory()) {
846
904
  continue;
847
905
  }
848
- if (!entry.name.startsWith(MUGGLE_SKILL_PREFIX)) {
906
+ if (!entry.name.startsWith(MUGGLE_SKILL_PREFIX) && !MUGGLE_ALIAS_SKILLS.has(entry.name)) {
849
907
  continue;
850
908
  }
851
909
  if (manifestSkills.has(entry.name)) {
852
910
  continue;
853
911
  }
854
- const skillPath = path4.join(skillsDir, entry.name);
912
+ const skillPath = path.join(skillsDir, entry.name);
855
913
  const sizeBytes = getDirectorySize(skillPath);
856
914
  obsoleteSkills.push({
857
915
  name: entry.name,
@@ -897,7 +955,7 @@ function getDirectorySize(dirPath) {
897
955
  try {
898
956
  const entries = readdirSync(dirPath, { withFileTypes: true });
899
957
  for (const entry of entries) {
900
- const fullPath = path4.join(dirPath, entry.name);
958
+ const fullPath = path.join(dirPath, entry.name);
901
959
  if (entry.isDirectory()) {
902
960
  totalSize += getDirectorySize(fullPath);
903
961
  } else if (entry.isFile()) {
@@ -950,7 +1008,7 @@ function listInstalledVersions() {
950
1008
  if (!/^\d+\.\d+\.\d+$/.test(entry.name)) {
951
1009
  continue;
952
1010
  }
953
- const versionPath = path4.join(baseDir, entry.name);
1011
+ const versionPath = path.join(baseDir, entry.name);
954
1012
  const sizeBytes = getDirectorySize(versionPath);
955
1013
  versions.push({
956
1014
  version: entry.name,
@@ -1106,11 +1164,11 @@ function getExpectedExecutablePath(versionDir) {
1106
1164
  const os = platform();
1107
1165
  switch (os) {
1108
1166
  case "darwin":
1109
- return path4.join(versionDir, "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
1167
+ return path.join(versionDir, "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
1110
1168
  case "win32":
1111
- return path4.join(versionDir, "MuggleAI.exe");
1169
+ return path.join(versionDir, "MuggleAI.exe");
1112
1170
  case "linux":
1113
- return path4.join(versionDir, "MuggleAI");
1171
+ return path.join(versionDir, "MuggleAI");
1114
1172
  default:
1115
1173
  throw new Error(`Unsupported platform: ${os}`);
1116
1174
  }
@@ -1119,7 +1177,7 @@ function verifyElectronAppInstallation() {
1119
1177
  const version = getElectronAppVersion();
1120
1178
  const versionDir = getElectronAppDir(version);
1121
1179
  const executablePath = getExpectedExecutablePath(versionDir);
1122
- const metadataPath = path4.join(versionDir, ".install-metadata.json");
1180
+ const metadataPath = path.join(versionDir, ".install-metadata.json");
1123
1181
  const result = {
1124
1182
  valid: false,
1125
1183
  versionDir,
@@ -1591,6 +1649,14 @@ async function serveCommand(options) {
1591
1649
  enableLocal,
1592
1650
  transport: "stdio"
1593
1651
  });
1652
+ try {
1653
+ initTelemetry({ serviceName: ServiceName.MuggleMcp, surface: Surface.McpLocal });
1654
+ track({ name: EventName.SystemStartup, props: { serviceName: ServiceName.MuggleMcp } });
1655
+ } catch (err) {
1656
+ logger5.warn("Telemetry init skipped", {
1657
+ error: err instanceof Error ? err.message : String(err)
1658
+ });
1659
+ }
1594
1660
  try {
1595
1661
  if (enableQa) {
1596
1662
  const qaTools = getQaTools();
@@ -1640,11 +1706,11 @@ function getExpectedExecutablePath2(versionDir) {
1640
1706
  const os = platform();
1641
1707
  switch (os) {
1642
1708
  case "darwin":
1643
- return path4.join(versionDir, "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
1709
+ return path.join(versionDir, "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
1644
1710
  case "win32":
1645
- return path4.join(versionDir, "MuggleAI.exe");
1711
+ return path.join(versionDir, "MuggleAI.exe");
1646
1712
  case "linux":
1647
- return path4.join(versionDir, "MuggleAI");
1713
+ return path.join(versionDir, "MuggleAI");
1648
1714
  default:
1649
1715
  throw new Error(`Unsupported platform: ${os}`);
1650
1716
  }
@@ -1741,8 +1807,8 @@ function cleanupFailedInstall(versionDir) {
1741
1807
  }
1742
1808
  }
1743
1809
  function upsertCursorMcpConfig() {
1744
- const cursorMcpConfigPath = path4.join(homedir(), ".cursor", "mcp.json");
1745
- const cursorDir = path4.join(homedir(), ".cursor");
1810
+ const cursorMcpConfigPath = path.join(homedir(), ".cursor", "mcp.json");
1811
+ const cursorDir = path.join(homedir(), ".cursor");
1746
1812
  let config = {};
1747
1813
  if (existsSync(cursorMcpConfigPath)) {
1748
1814
  try {
@@ -1779,7 +1845,7 @@ async function setupCommand(options) {
1779
1845
  upsertCursorMcpConfig();
1780
1846
  if (isFirstRun()) {
1781
1847
  writePreferences(DEFAULT_PREFERENCES, "global");
1782
- console.log(`Default preferences written to ${path4.join(getDataDir(), PREFERENCES_FILE_NAME)}`);
1848
+ console.log(`Default preferences written to ${path.join(getDataDir(), PREFERENCES_FILE_NAME)}`);
1783
1849
  console.log("All preferences default to 'ask'. You can customize them anytime by editing the file or telling the agent to change a preference.");
1784
1850
  }
1785
1851
  if (!options.force && isElectronAppInstalled()) {
@@ -1799,7 +1865,7 @@ async function setupCommand(options) {
1799
1865
  rmSync(versionDir, { recursive: true, force: true });
1800
1866
  }
1801
1867
  mkdirSync(versionDir, { recursive: true });
1802
- const tempFile = path4.join(versionDir, binaryName);
1868
+ const tempFile = path.join(versionDir, binaryName);
1803
1869
  await downloadWithRetry(downloadUrl, tempFile);
1804
1870
  console.log("Download complete, verifying checksum...");
1805
1871
  const checksums = getElectronAppChecksums();
@@ -1835,7 +1901,7 @@ The archive may be corrupted or in an unexpected format.`
1835
1901
  );
1836
1902
  }
1837
1903
  const executableChecksum = await calculateFileChecksum(executablePath);
1838
- const metadataPath = path4.join(versionDir, INSTALL_METADATA_FILE_NAME);
1904
+ const metadataPath = path.join(versionDir, INSTALL_METADATA_FILE_NAME);
1839
1905
  writeInstallMetadata({
1840
1906
  metadataPath,
1841
1907
  version,
@@ -1877,7 +1943,7 @@ function extractVersionFromTag(tag) {
1877
1943
  return match ? match[1] : null;
1878
1944
  }
1879
1945
  function getVersionOverridePath() {
1880
- return path4.join(getDataDir(), VERSION_OVERRIDE_FILE);
1946
+ return path.join(getDataDir(), VERSION_OVERRIDE_FILE);
1881
1947
  }
1882
1948
  function getEffectiveElectronAppVersion() {
1883
1949
  const overridePath = getVersionOverridePath();
@@ -1965,11 +2031,11 @@ function getExpectedExecutablePath3(versionDir) {
1965
2031
  const os = platform();
1966
2032
  switch (os) {
1967
2033
  case "darwin":
1968
- return path4.join(versionDir, "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
2034
+ return path.join(versionDir, "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
1969
2035
  case "win32":
1970
- return path4.join(versionDir, "MuggleAI.exe");
2036
+ return path.join(versionDir, "MuggleAI.exe");
1971
2037
  case "linux":
1972
- return path4.join(versionDir, "MuggleAI");
2038
+ return path.join(versionDir, "MuggleAI");
1973
2039
  default:
1974
2040
  throw new Error(`Unsupported platform: ${os}`);
1975
2041
  }
@@ -2081,7 +2147,7 @@ async function downloadAndInstall(version, downloadUrl, checksum) {
2081
2147
  if (!response.ok) {
2082
2148
  throw new Error(`Download failed: ${response.status} ${response.statusText}`);
2083
2149
  }
2084
- const tempFile = path4.join(versionDir, binaryName);
2150
+ const tempFile = path.join(versionDir, binaryName);
2085
2151
  const fileStream = createWriteStream(tempFile);
2086
2152
  if (!response.body) {
2087
2153
  throw new Error("No response body");
@@ -2123,7 +2189,7 @@ The archive may be corrupted or in an unexpected format.`
2123
2189
  );
2124
2190
  }
2125
2191
  const executableChecksum = await calculateFileChecksum(executablePath);
2126
- const metadataPath = path4.join(versionDir, INSTALL_METADATA_FILE_NAME2);
2192
+ const metadataPath = path.join(versionDir, INSTALL_METADATA_FILE_NAME2);
2127
2193
  writeInstallMetadata2({
2128
2194
  metadataPath,
2129
2195
  version,