@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.
- package/README.md +3 -3
- package/dist/{chunk-RK6XKSZK.js → chunk-Q7WNEMN4.js} +109 -43
- package/dist/{chunk-UVXOHXY2.js → chunk-ZKRHFTIC.js} +832 -89
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/.cursor-plugin/plugin.json +1 -1
- package/dist/plugin/README.md +4 -2
- package/dist/plugin/agents/acceptance-tester.md +24 -10
- package/dist/plugin/commands/m.md +7 -0
- package/dist/plugin/commands/mdo.md +7 -0
- package/dist/plugin/commands/mfeedback.md +7 -0
- package/dist/plugin/commands/mimport.md +7 -0
- package/dist/plugin/commands/mpr.md +7 -0
- package/dist/plugin/commands/mprefs.md +7 -0
- package/dist/plugin/commands/mregen.md +7 -0
- package/dist/plugin/commands/mrelease.md +7 -0
- package/dist/plugin/commands/mrepair.md +7 -0
- package/dist/plugin/commands/mstatus.md +7 -0
- package/dist/plugin/commands/mtest.md +7 -0
- package/dist/plugin/commands/mtestlocal.md +7 -0
- package/dist/plugin/commands/mtestprep.md +7 -0
- package/dist/plugin/commands/mupgrade.md +7 -0
- package/dist/plugin/scripts/ensure-electron-app.sh +35 -8
- package/dist/plugin/skills/_aliases.json +18 -0
- package/dist/plugin/skills/_shared/dev-server-readiness.md +231 -0
- package/dist/plugin/skills/_shared/failure-mode-handling.md +244 -0
- package/dist/plugin/skills/_shared/post-merge-cleanup.md +10 -0
- package/dist/plugin/skills/_shared/rebase-before-e2e.md +15 -0
- package/dist/plugin/skills/_shared/telemetry-emit.md +15 -0
- package/dist/plugin/skills/_shared/use-worktrees.md +53 -0
- package/dist/plugin/skills/do/e2e-acceptance.md +63 -18
- package/dist/plugin/skills/do/impact-analysis.md +45 -5
- package/dist/plugin/skills/do/open-prs.md +13 -4
- package/dist/plugin/skills/do/pr-followup.md +225 -0
- package/dist/plugin/skills/do/pre-flight.md +18 -11
- package/dist/plugin/skills/m/SKILL.md +8 -0
- package/dist/plugin/skills/mdo/SKILL.md +8 -0
- package/dist/plugin/skills/mfeedback/SKILL.md +8 -0
- package/dist/plugin/skills/mimport/SKILL.md +8 -0
- package/dist/plugin/skills/mpr/SKILL.md +8 -0
- package/dist/plugin/skills/mprefs/SKILL.md +8 -0
- package/dist/plugin/skills/mregen/SKILL.md +8 -0
- package/dist/plugin/skills/mrelease/SKILL.md +8 -0
- package/dist/plugin/skills/mrepair/SKILL.md +8 -0
- package/dist/plugin/skills/mstatus/SKILL.md +8 -0
- package/dist/plugin/skills/mtest/SKILL.md +8 -0
- package/dist/plugin/skills/mtestlocal/SKILL.md +8 -0
- package/dist/plugin/skills/mtestprep/SKILL.md +8 -0
- package/dist/plugin/skills/muggle/SKILL.md +9 -6
- package/dist/plugin/skills/muggle-do/SKILL.md +22 -4
- package/dist/plugin/skills/muggle-do-pr-followup/SKILL.md +37 -0
- package/dist/plugin/skills/muggle-do-task/SKILL.md +134 -0
- package/dist/plugin/skills/muggle-feedback/SKILL.md +38 -0
- package/dist/plugin/skills/muggle-feedback/ops/delete.md +49 -0
- package/dist/plugin/skills/muggle-feedback/ops/list.md +65 -0
- package/dist/plugin/skills/muggle-feedback/ops/submit.md +117 -0
- package/dist/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +68 -43
- package/dist/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
- package/dist/plugin/skills/muggle-preferences/SKILL.md +16 -108
- package/dist/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
- package/dist/plugin/skills/muggle-preferences/ops/configure.md +49 -0
- package/dist/plugin/skills/muggle-preferences/ops/list.md +9 -0
- package/dist/plugin/skills/muggle-preferences/ops/reset.md +6 -0
- package/dist/plugin/skills/muggle-preferences/ops/set.md +10 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/README.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +3 -3
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +2 -2
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +1 -2
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +4 -4
- package/dist/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +8 -25
- package/dist/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +1 -1
- package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +4 -4
- package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +4 -4
- package/dist/plugin/skills/muggle-repair/SKILL.md +4 -2
- package/dist/plugin/skills/muggle-status/SKILL.md +8 -5
- package/dist/plugin/skills/muggle-test/SKILL.md +110 -86
- package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +73 -66
- package/dist/plugin/skills/muggle-test-import/SKILL.md +28 -23
- package/dist/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
- package/dist/plugin/skills/muggle-test-regenerate-missing/SKILL.md +34 -18
- package/dist/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
- package/dist/plugin/skills/muggle-upgrade/SKILL.md +4 -2
- package/dist/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
- package/dist/plugin/skills/mupgrade/SKILL.md +8 -0
- package/dist/release-manifest.json +4 -4
- package/dist/{src-GD3YFCCW.js → src-2G7ENRGI.js} +1 -1
- package/package.json +9 -7
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/README.md +4 -2
- package/plugin/agents/acceptance-tester.md +24 -10
- package/plugin/commands/m.md +7 -0
- package/plugin/commands/mdo.md +7 -0
- package/plugin/commands/mfeedback.md +7 -0
- package/plugin/commands/mimport.md +7 -0
- package/plugin/commands/mpr.md +7 -0
- package/plugin/commands/mprefs.md +7 -0
- package/plugin/commands/mregen.md +7 -0
- package/plugin/commands/mrelease.md +7 -0
- package/plugin/commands/mrepair.md +7 -0
- package/plugin/commands/mstatus.md +7 -0
- package/plugin/commands/mtest.md +7 -0
- package/plugin/commands/mtestlocal.md +7 -0
- package/plugin/commands/mtestprep.md +7 -0
- package/plugin/commands/mupgrade.md +7 -0
- package/plugin/scripts/ensure-electron-app.sh +35 -8
- package/plugin/skills/_aliases.json +18 -0
- package/plugin/skills/_shared/dev-server-readiness.md +231 -0
- package/plugin/skills/_shared/failure-mode-handling.md +244 -0
- package/plugin/skills/_shared/post-merge-cleanup.md +10 -0
- package/plugin/skills/_shared/rebase-before-e2e.md +15 -0
- package/plugin/skills/_shared/telemetry-emit.md +15 -0
- package/plugin/skills/_shared/use-worktrees.md +53 -0
- package/plugin/skills/do/e2e-acceptance.md +63 -18
- package/plugin/skills/do/impact-analysis.md +45 -5
- package/plugin/skills/do/open-prs.md +13 -4
- package/plugin/skills/do/pr-followup.md +225 -0
- package/plugin/skills/do/pre-flight.md +18 -11
- package/plugin/skills/m/SKILL.md +8 -0
- package/plugin/skills/mdo/SKILL.md +8 -0
- package/plugin/skills/mfeedback/SKILL.md +8 -0
- package/plugin/skills/mimport/SKILL.md +8 -0
- package/plugin/skills/mpr/SKILL.md +8 -0
- package/plugin/skills/mprefs/SKILL.md +8 -0
- package/plugin/skills/mregen/SKILL.md +8 -0
- package/plugin/skills/mrelease/SKILL.md +8 -0
- package/plugin/skills/mrepair/SKILL.md +8 -0
- package/plugin/skills/mstatus/SKILL.md +8 -0
- package/plugin/skills/mtest/SKILL.md +8 -0
- package/plugin/skills/mtestlocal/SKILL.md +8 -0
- package/plugin/skills/mtestprep/SKILL.md +8 -0
- package/plugin/skills/muggle/SKILL.md +9 -6
- package/plugin/skills/muggle-do/SKILL.md +22 -4
- package/plugin/skills/muggle-do-pr-followup/SKILL.md +37 -0
- package/plugin/skills/muggle-do-task/SKILL.md +134 -0
- package/plugin/skills/muggle-feedback/SKILL.md +38 -0
- package/plugin/skills/muggle-feedback/ops/delete.md +49 -0
- package/plugin/skills/muggle-feedback/ops/list.md +65 -0
- package/plugin/skills/muggle-feedback/ops/submit.md +117 -0
- package/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +68 -43
- package/plugin/skills/muggle-pr-visual-walkthrough/e2e-report-assembly.md +86 -0
- package/plugin/skills/muggle-preferences/SKILL.md +16 -108
- package/plugin/skills/muggle-preferences/ops/change-one.md +10 -0
- package/plugin/skills/muggle-preferences/ops/configure.md +49 -0
- package/plugin/skills/muggle-preferences/ops/list.md +9 -0
- package/plugin/skills/muggle-preferences/ops/reset.md +6 -0
- package/plugin/skills/muggle-preferences/ops/set.md +10 -0
- package/plugin/skills/muggle-preferences/preference-gates/README.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/autoCleanup.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoCreatePR.md +13 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +3 -3
- package/plugin/skills/muggle-preferences/preference-gates/autoE2ETest.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +2 -2
- package/plugin/skills/muggle-preferences/preference-gates/autoRebase.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoSelectLocalHost.md +19 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +1 -2
- package/plugin/skills/muggle-preferences/preference-gates/autoUseWorktree.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +4 -4
- package/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +8 -25
- package/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +1 -1
- package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +4 -4
- package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +4 -4
- package/plugin/skills/muggle-repair/SKILL.md +4 -2
- package/plugin/skills/muggle-status/SKILL.md +8 -5
- package/plugin/skills/muggle-test/SKILL.md +110 -86
- package/plugin/skills/muggle-test-feature-local/SKILL.md +73 -66
- package/plugin/skills/muggle-test-import/SKILL.md +28 -23
- package/plugin/skills/muggle-test-prepare/SKILL.md +79 -18
- package/plugin/skills/muggle-test-regenerate-missing/SKILL.md +34 -18
- package/plugin/skills/muggle-test-regenerate-missing/evals/evals.json +9 -9
- package/plugin/skills/muggle-upgrade/SKILL.md +4 -2
- package/plugin/skills/muggle-works-npm-release/SKILL.md +6 -4
- package/plugin/skills/mupgrade/SKILL.md +8 -0
- 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-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
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>${
|
|
462
|
-
const
|
|
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
|
|
490
|
+
return `<b>${testNumber}. </b>${head}${base} \u2014 ${test.description}`;
|
|
465
491
|
}
|
|
466
|
-
return
|
|
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(
|
|
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-
|
|
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
|
|
868
|
+
return path.join(getDataDir(), ELECTRON_APP_DIR);
|
|
811
869
|
}
|
|
812
870
|
function getCursorSkillsDir() {
|
|
813
|
-
return
|
|
871
|
+
return path.join(homedir(), CURSOR_SKILLS_DIR, CURSOR_SKILLS_SUBDIR);
|
|
814
872
|
}
|
|
815
873
|
function getInstallManifestPath() {
|
|
816
|
-
return
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
1167
|
+
return path.join(versionDir, "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
|
|
1110
1168
|
case "win32":
|
|
1111
|
-
return
|
|
1169
|
+
return path.join(versionDir, "MuggleAI.exe");
|
|
1112
1170
|
case "linux":
|
|
1113
|
-
return
|
|
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 =
|
|
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
|
|
1709
|
+
return path.join(versionDir, "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
|
|
1644
1710
|
case "win32":
|
|
1645
|
-
return
|
|
1711
|
+
return path.join(versionDir, "MuggleAI.exe");
|
|
1646
1712
|
case "linux":
|
|
1647
|
-
return
|
|
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 =
|
|
1745
|
-
const cursorDir =
|
|
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 ${
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
2034
|
+
return path.join(versionDir, "MuggleAI.app", "Contents", "MacOS", "MuggleAI");
|
|
1969
2035
|
case "win32":
|
|
1970
|
-
return
|
|
2036
|
+
return path.join(versionDir, "MuggleAI.exe");
|
|
1971
2037
|
case "linux":
|
|
1972
|
-
return
|
|
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 =
|
|
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 =
|
|
2192
|
+
const metadataPath = path.join(versionDir, INSTALL_METADATA_FILE_NAME2);
|
|
2127
2193
|
writeInstallMetadata2({
|
|
2128
2194
|
metadataPath,
|
|
2129
2195
|
version,
|