@muggleai/works 5.3.0 → 5.3.2
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/dist/{chunk-IGXNFT4M.js → chunk-LTULYOOW.js} +2 -2
- package/dist/{chunk-MPLQNDZX.js → chunk-LVUJ4E62.js} +40 -1
- 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/scripts/guardrails.mjs +2 -4
- package/dist/plugin/skills/CLAUDE.md +15 -0
- package/dist/plugin/skills/muggle/SKILL.md +1 -0
- package/dist/plugin/skills/muggle-feedback/SKILL.md +1 -0
- package/dist/plugin/skills/muggle-pr-followup/SKILL.md +1 -0
- package/dist/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +1 -0
- package/dist/plugin/skills/muggle-preferences/SKILL.md +1 -0
- package/dist/plugin/skills/muggle-repair/SKILL.md +1 -0
- package/dist/plugin/skills/muggle-status/SKILL.md +1 -0
- package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +4 -4
- package/dist/plugin/skills/muggle-test-prepare/SKILL.md +1 -0
- package/dist/plugin/skills/muggle-test-regenerate-missing/SKILL.md +1 -0
- package/dist/plugin/skills/muggle-upgrade/SKILL.md +1 -0
- package/dist/release-manifest.json +4 -4
- package/dist/{src-MQFKDZW5.js → src-FDK2KQSZ.js} +1 -1
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/scripts/guardrails.mjs +2 -4
- package/plugin/skills/CLAUDE.md +15 -0
- package/plugin/skills/muggle/SKILL.md +1 -0
- package/plugin/skills/muggle-feedback/SKILL.md +1 -0
- package/plugin/skills/muggle-pr-followup/SKILL.md +1 -0
- package/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +1 -0
- package/plugin/skills/muggle-preferences/SKILL.md +1 -0
- package/plugin/skills/muggle-repair/SKILL.md +1 -0
- package/plugin/skills/muggle-status/SKILL.md +1 -0
- package/plugin/skills/muggle-test-feature-local/SKILL.md +4 -4
- package/plugin/skills/muggle-test-prepare/SKILL.md +1 -0
- package/plugin/skills/muggle-test-regenerate-missing/SKILL.md +1 -0
- package/plugin/skills/muggle-upgrade/SKILL.md +1 -0
|
@@ -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, initTelemetry, Surface, ServiceName, track, EventName, getQaTools, getLocalQaTools, performLogout, performLogin, toolRequiresAuth, getCallerCredentials, hasShownDisclosure, getDisclosureCopy, markDisclosureShown, 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, hasShownDisclosure, getDisclosureCopy, markDisclosureShown, getBundledElectronAppVersion, getElectronAppVersionSource, getCredentialsFilePath, buildElectronAppChecksumsUrl, __require } from './chunk-LVUJ4E62.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';
|
|
@@ -736,7 +736,7 @@ async function resolveGsScreenshotUrls(report, opts) {
|
|
|
736
736
|
if (gsUrls.length === 0) {
|
|
737
737
|
return report;
|
|
738
738
|
}
|
|
739
|
-
const mcps = await import('./src-
|
|
739
|
+
const mcps = await import('./src-FDK2KQSZ.js');
|
|
740
740
|
const credentials = await mcps.getCallerCredentialsAsync();
|
|
741
741
|
if (!credentials.bearerToken && !credentials.apiKey) {
|
|
742
742
|
stderrWrite(
|
|
@@ -2067,6 +2067,10 @@ function buildGenerationActionScript(params) {
|
|
|
2067
2067
|
actionScriptId: params.localTestScriptId,
|
|
2068
2068
|
workflowRunId: params.runId,
|
|
2069
2069
|
url: params.localUrl,
|
|
2070
|
+
// The studio executes against `url` (localhost) but uploads `productionUrl`
|
|
2071
|
+
// as the run's remoteUrl. Without it the studio falls back to the localhost
|
|
2072
|
+
// url, so the run record shows localhost where the test case's cloud url belongs.
|
|
2073
|
+
productionUrl: params.testCase.url,
|
|
2070
2074
|
// Tags the run as locally executed so the studio skips its own cloud
|
|
2071
2075
|
// ActionScript/TestScript write — the /local-run/upload path is the
|
|
2072
2076
|
// single writer for local runs (avoids duplicate Firestore docs).
|
|
@@ -2120,6 +2124,11 @@ function buildReplayActionScript(params) {
|
|
|
2120
2124
|
testCaseId: params.testScript.testCaseId,
|
|
2121
2125
|
testScriptId: params.testScript.id,
|
|
2122
2126
|
workflowRunId: params.runId,
|
|
2127
|
+
// The studio executes against the rewritten localhost steps but uploads
|
|
2128
|
+
// `productionUrl` as the run's remoteUrl. Without it the studio falls back
|
|
2129
|
+
// to the localhost url, so the run record shows localhost where the test
|
|
2130
|
+
// script's cloud url belongs.
|
|
2131
|
+
productionUrl: params.testScript.url,
|
|
2123
2132
|
// Tags the run as locally executed so the studio skips its own cloud
|
|
2124
2133
|
// ActionScript write — replay's cloud record is owned by the upload path
|
|
2125
2134
|
// (avoids duplicate Firestore docs).
|
|
@@ -2313,6 +2322,31 @@ async function readLocalExecutionLockState() {
|
|
|
2313
2322
|
return readState();
|
|
2314
2323
|
}
|
|
2315
2324
|
|
|
2325
|
+
// packages/mcps/src/mcp/local/services/spawn-failure-message.ts
|
|
2326
|
+
function describeElectronSpawnFailure(params) {
|
|
2327
|
+
const base = `Failed to start electron-app: ${params.error.message}`;
|
|
2328
|
+
const platform6 = params.platform ?? process.platform;
|
|
2329
|
+
const blockedByAppControl = platform6 === "win32" && (params.error.code === "UNKNOWN" || params.error.code === "EPERM");
|
|
2330
|
+
if (!blockedByAppControl) {
|
|
2331
|
+
return base;
|
|
2332
|
+
}
|
|
2333
|
+
return [
|
|
2334
|
+
base,
|
|
2335
|
+
"",
|
|
2336
|
+
"This is almost certainly Windows Smart App Control (or a WDAC policy) blocking the",
|
|
2337
|
+
"Muggle desktop app because it is not yet code-signed: the OS refuses to launch the",
|
|
2338
|
+
"binary before it starts, so there is no output and the run fails in 0ms.",
|
|
2339
|
+
"",
|
|
2340
|
+
` Binary: ${params.electronAppPath}`,
|
|
2341
|
+
" Confirm: launch the binary directly, or check Event Viewer > Applications and Services",
|
|
2342
|
+
' Logs > Microsoft > Windows > CodeIntegrity (events 3033/3077) for "An Application',
|
|
2343
|
+
' Control policy has blocked this file."',
|
|
2344
|
+
"",
|
|
2345
|
+
" To run Muggle now: Settings > Privacy & security > Windows Security > App & browser",
|
|
2346
|
+
" control > Smart App Control > Off. A signed build that passes Smart App Control is on the way."
|
|
2347
|
+
].join("\n");
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2316
2350
|
// packages/mcps/src/mcp/local/services/execution-service.ts
|
|
2317
2351
|
var logger4 = getLogger();
|
|
2318
2352
|
function extractStudioCloudRefs(studioReturnedResult) {
|
|
@@ -2629,7 +2663,12 @@ ${processInfo.capturedStderr}`
|
|
|
2629
2663
|
child.on("error", (error) => {
|
|
2630
2664
|
finalize({
|
|
2631
2665
|
ok: false,
|
|
2632
|
-
payload: new Error(
|
|
2666
|
+
payload: new Error(
|
|
2667
|
+
describeElectronSpawnFailure({
|
|
2668
|
+
error,
|
|
2669
|
+
electronAppPath
|
|
2670
|
+
})
|
|
2671
|
+
)
|
|
2633
2672
|
});
|
|
2634
2673
|
});
|
|
2635
2674
|
child.on("close", (code, signal) => {
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { src_exports as commands, createUnifiedMcpServer, server_exports as server } from './chunk-
|
|
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-
|
|
1
|
+
export { src_exports as commands, createUnifiedMcpServer, server_exports as server } from './chunk-LTULYOOW.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-LVUJ4E62.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": "5.3.
|
|
4
|
+
"version": "5.3.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": "5.3.
|
|
5
|
+
"version": "5.3.1",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Muggle AI",
|
|
8
8
|
"email": "support@muggle-ai.com"
|
|
@@ -43,7 +43,7 @@ ${input2.tool_response?.output ?? ""}`;
|
|
|
43
43
|
// src/guardrails/testsGreen.ts
|
|
44
44
|
var TEST_CMD = /\b(pnpm|npm|yarn)\s+(run\s+)?test\b|\b(jest|vitest|pytest)\b|\bgo\s+test\b|\bcargo\s+test\b/;
|
|
45
45
|
var FAIL = /\b\d+\s+failed\b|\bFAIL\b|✗/;
|
|
46
|
-
var
|
|
46
|
+
var E2E_TOOL = /muggle.*(execute|test-generation|replay)/i;
|
|
47
47
|
function isTestCommand(cmd) {
|
|
48
48
|
return TEST_CMD.test(cmd);
|
|
49
49
|
}
|
|
@@ -54,9 +54,7 @@ ${input2.tool_response?.stderr ?? ""}`;
|
|
|
54
54
|
return !FAIL.test(out);
|
|
55
55
|
}
|
|
56
56
|
function isE2ERun(input2) {
|
|
57
|
-
|
|
58
|
-
const tool = input2.tool_name ?? "";
|
|
59
|
-
return E2E_RUN.test(cmd) || /muggle.*(execute|test-generation|replay)/i.test(tool);
|
|
57
|
+
return E2E_TOOL.test(input2.tool_name ?? "");
|
|
60
58
|
}
|
|
61
59
|
|
|
62
60
|
// src/guardrails/shouldRunE2E.ts
|
|
@@ -13,3 +13,18 @@ A reverse reference (A → B and B → A) couples the depended-on skill to its c
|
|
|
13
13
|
**Worked example.** `muggle-pr-followup` (the dumb-pipe watcher) is lower-level than `muggle-do` (the executor that orchestrates it). `muggle-do` references `muggle-pr-followup`; `muggle-pr-followup`'s files must not link back to `muggle-do`. A watcher tick still dispatches `/muggle-do …` at runtime — allowed — but no watcher file links a `do/` file or restates its steps, and shared primitives like `muggle-pr-followup/finalize.md` stay dispatch-free so any caller can reuse them.
|
|
14
14
|
|
|
15
15
|
When you feel the urge to link "up" to a caller, that is the smell — restructure so the caller passes what is needed in.
|
|
16
|
+
|
|
17
|
+
## Model tiers
|
|
18
|
+
|
|
19
|
+
Each skill sets a `model:` in its `SKILL.md` frontmatter sized to its cognitive load. `model:` is a native Claude Code field — the override applies while the skill is active and reverts to the session model when it exits. Cheaper, faster models run the mechanical skills; the default (Opus) is reserved for the ones that actually reason. Cost and latency scale with the model, and these skills run often (the watcher fires every minute), so the tier is a real lever, not cosmetics.
|
|
20
|
+
|
|
21
|
+
| Model | Skills | Why this tier |
|
|
22
|
+
|-------|--------|---------------|
|
|
23
|
+
| `haiku` | `muggle`, `muggle-status`, `muggle-repair`, `muggle-upgrade`, `muggle-preferences`, `muggle-feedback`, `muggle-pr-followup` | Routers and dumb pipes. They follow an explicit procedure with no open-ended reasoning: route intent to a downstream skill, run a fixed CLI sequence, CRUD a config file, format a status report, or poll provider state and branch on conditions. `muggle-pr-followup` is the canonical case — a watcher that reads GitHub state and dispatches; all judgment lives in the `muggle-do` it hands off to. |
|
|
24
|
+
| `sonnet` | `muggle-pr-visual-walkthrough`, `muggle-test-regenerate-missing` | Multi-step orchestration with light judgment, short of deep reasoning: assemble run data and build a PR section with fit-vs-overflow handling; scan, filter, bulk-dispatch, and classify per-item failures into buckets. More moving parts than a router, but each step is well-defined. |
|
|
25
|
+
| `opus` (explicit pin) | `muggle-test-prepare` | Pinned for **reliability**, not raw reasoning load: it's flaky on smaller models, and since other skills gate on the environment it readies, a wrong call is expensive. Pin explicitly rather than leaving `model:` unset so it stays on Opus even when the user's session runs a cheaper model. |
|
|
26
|
+
| default (Opus) — no `model:` set | `muggle-do`, `muggle-test`, `muggle-test-feature-local`, `muggle-browser-task`, `muggle-test-import` | Reasoning-heavy. Authoring code to a PR, mapping a code diff to affected user flows and interpreting E2E results, reasoning about an arbitrary website's flow to drive a browser, translating Playwright/Cypress/PRD artifacts into Muggle test cases. Leave `model:` unset so the skill inherits the session model. |
|
|
27
|
+
|
|
28
|
+
**Choosing a tier for a new skill.** Ask what the skill actually does. Pure routing / fixed procedure / CRUD / reporting → `haiku`. Several well-defined steps with some judgment or classification → `sonnet`. Open-ended reasoning, code authoring, or interpreting ambiguous real-world state → leave `model:` unset (Opus). When unsure between two tiers, pick the cheaper one and watch for misbehavior — the likeliest to need a bump is anything doing AI-based classification. If a skill proves flaky on its tier and reliability matters more than cost (other skills depend on it, or a wrong call is expensive), pin it up explicitly — `model: opus` — rather than leaving it unset, so the floor holds regardless of the user's session model.
|
|
29
|
+
|
|
30
|
+
**Never set `model:` on aliases or commands.** The alias skills (`m`, `mstatus`, …) and `plugin/commands/*.md` are thin routers that re-invoke the canonical skill via the `Skill` tool. The canonical `SKILL.md`'s `model:` takes effect once it loads, so a model on the alias would only apply to the negligible one-line hand-off — and risks drifting from the canonical value.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-feedback
|
|
3
|
+
model: haiku
|
|
3
4
|
description: "Use when the user wants to flag that a generated Muggle Test action script — or one specific step in it — did the wrong thing, so Muggle can analyze and regenerate affected scripts. Covers any report that a script or step is wrong, broken, or misbehaving (clicked the wrong element, step N did not work, broken at the submit step), whether from a recent local/remote run or a pasted Muggle dashboard run/script URL. Also lists, views, or deletes previously submitted feedback. Triggers on /muggle-feedback, give feedback on this run, the test was wrong, flag this run."
|
|
4
5
|
---
|
|
5
6
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-pr-followup
|
|
3
|
+
model: haiku
|
|
3
4
|
description: "Use when the user wants a pull request's incoming review feedback handled for them — it watches one PR's review thread and, each time a reviewer submits new comments, dispatches the work to address them. Engage on PR-review-follow-up intent: \"watch my PR and address review comments as they come in\", \"keep an eye on PR #123 and respond to reviewer feedback\", \"babysit my PR's review thread\", \"I'm stepping away — handle my PR's reviews while I'm gone\". This is PR-review-specific automation — prefer it over the generic loop skill. It only watches and dispatches; the actual edits and replies are muggle-do. Not for posting test results to a PR (use muggle-pr-visual-walkthrough)."
|
|
4
5
|
---
|
|
5
6
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-pr-visual-walkthrough
|
|
3
|
+
model: sonnet
|
|
3
4
|
description: Renders and posts a visual walkthrough of Muggle AI E2E acceptance test results to a PR — per-test-case dashboard links, step-by-step screenshots, and pass/fail summary — using the `muggle build-pr-section` CLI for deterministic formatting with automatic fit-vs-overflow. Use at the end of any Muggle Test test run (local or remote) to give PR reviewers clickable visual evidence that user flows work. Triggers on 'post results to PR', 'attach walkthrough to PR', 'share E2E screenshots on the PR', 'add visual walkthrough to PR'.
|
|
4
5
|
---
|
|
5
6
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-status
|
|
3
|
+
model: haiku
|
|
3
4
|
description: "Check the health of the user's Muggle AI installation and diagnose why it's misbehaving — MCP server connectivity, tool loading, login/auth validity, overall setup. Engage on muggle status and on any diagnostic question about Muggle itself: is muggle working or healthy, why does muggle keep failing or timing out, are the muggle MCP tools loading, is my muggle login still valid. Prefer this over answering from memory whenever the user is unsure Muggle itself is functioning. Boundary: diagnosing is muggle-status; fixing a broken install is muggle-repair. Not for the health of the user's own app, CI, or infra."
|
|
4
5
|
---
|
|
5
6
|
|
|
@@ -151,12 +151,12 @@ Caller glue: `mode` is the path chosen in §5; `localUrl` from §4; `cwd` = the
|
|
|
151
151
|
|
|
152
152
|
Resolve the `showElectronBrowser` gate **first**, then call `muggle-local-execute-test-generation` or `muggle-local-execute-replay`. **Do not** ask the user to re-approve the Electron launch itself — choosing this skill is the approval. That run-approval suppression does **not** extend to the gate below: when `showElectronBrowser=ask` you must still fire its picker.
|
|
153
153
|
|
|
154
|
-
Gate `showElectronBrowser` (per `preference-gates/README.md`). Reuse the choice within a session.
|
|
155
|
-
- `always` → omit `showUi`
|
|
156
|
-
- `never` → pass `showUi: false`.
|
|
154
|
+
Gate `showElectronBrowser` (per `preference-gates/README.md`). Reuse the choice within a session. The runner shows the browser by default, so treat `showUi` as a **hide switch** — include it only to turn the browser off:
|
|
155
|
+
- `always` (show it) → **omit `showUi` entirely** — no `showUi` key in the call. Passing `showUi: false` here is a bug: it hides the browser the user wanted to watch.
|
|
156
|
+
- `never` (hide it) → pass `showUi: false`.
|
|
157
157
|
- `ask` → you **must** call `AskUserQuestion` (Picker 1 from `preference-gates/showElectronBrowser.md`) **before** the execute call, then map the answer to the `always`/`never` action above. Do not decide for the user.
|
|
158
158
|
|
|
159
|
-
`showUi`
|
|
159
|
+
So the execute call carries **no `showUi` key** for `always`, or `showUi: false` for `never` — never `showUi: true`.
|
|
160
160
|
|
|
161
161
|
### 8. Open the run on the dashboard (`viewUrl` gated by `openTestResultsAfterRun`)
|
|
162
162
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-test-prepare
|
|
3
|
+
model: opus
|
|
3
4
|
description: "Get a user's local environment ready before running E2E acceptance tests — verify the dev servers, APIs, and sibling services they need are up and responding, and offer to start whatever is missing (with approval per step). Trigger when the user wants to confirm specific ports or localhost URLs are listening before testing (check if localhost:3000 and the api on 8080 are up, are my services running), spin up their local dev stack, or verify their setup — and whenever another muggle skill (muggle-test, muggle-do, muggle-test-feature-local) needs services running but they're not. This is environment readiness and service startup, not running the tests."
|
|
4
5
|
---
|
|
5
6
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-test-regenerate-missing
|
|
3
|
+
model: sonnet
|
|
3
4
|
description: "Bulk-regenerate test scripts for every test case in a Muggle AI project that has no active script. Scans the project, finds test cases stuck in DRAFT or GENERATION_PENDING, shows the user the list, and on approval kicks off bulk remote script generation via the Muggle Test cloud. Use when the user wants to regenerate missing scripts, fill in missing test scripts, generate scripts for test cases without one, rebuild scripts for stale test cases, or bulk regenerate across a project. Handles discovery, filtering, confirmation, and remote dispatch end-to-end."
|
|
4
5
|
---
|
|
5
6
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"release": "5.3.
|
|
3
|
-
"buildId": "run-
|
|
4
|
-
"commitSha": "
|
|
5
|
-
"buildTime": "2026-06-
|
|
2
|
+
"release": "5.3.1",
|
|
3
|
+
"buildId": "run-57-1",
|
|
4
|
+
"commitSha": "59719feeefb8f02aeb763df7a131f15e3e0efe1c",
|
|
5
|
+
"buildTime": "2026-06-24T23:19:55Z",
|
|
6
6
|
"serviceName": "muggle-ai-works-mcp"
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { DEFAULT_PREFERENCES, PREFERENCES_FILE_NAME, PREFERENCES_PROJECT_DIR_NAME, PREFERENCES_SCHEMA, PREFERENCES_VERSION, PREFERENCE_ALLOWED_VALUES, PreferenceKey, PreferenceValue, buildElectronAppChecksumsUrl, buildElectronAppReleaseAssetUrl, buildElectronAppReleaseTag, calculateFileChecksum, createApiKeyWithToken, createChildLogger, deleteApiKeyData, deleteCredentials, e2e_exports as e2e, formatPreferencesOneLiner, getApiKey, getApiKeyFilePath, getAuthService, getBundledElectronAppVersion, getCallerCredentials, getCallerCredentialsAsync, getChecksumForPlatform, getConfig, getCredentialsFilePath, getDataDir, getDownloadBaseUrl, getElectronAppChecksums, getElectronAppDir, getElectronAppVersion, getElectronAppVersionSource, getLocalQaTools, getLogger, getPlatformKey, getQaTools, getValidApiKeyData, getValidCredentials, hasApiKey, isElectronAppInstalled, isFirstRun, loadApiKeyData, loadCredentials, local_exports as localQa, mcp_exports as mcp, openBrowserUrl, performLogin, performLogout, pollDeviceCode, e2e_exports as qa, readGlobalPreferences, readProjectPreferences, resetConfig, resetLogger, resetPreference, resolveElectronAppPathOrNull, resolvePreferences, saveApiKey, saveApiKeyData, saveCredentials, startDeviceCodeFlow, toolRequiresAuth, validatePreference, verifyFileChecksum, writePreferences } from './chunk-
|
|
1
|
+
export { DEFAULT_PREFERENCES, PREFERENCES_FILE_NAME, PREFERENCES_PROJECT_DIR_NAME, PREFERENCES_SCHEMA, PREFERENCES_VERSION, PREFERENCE_ALLOWED_VALUES, PreferenceKey, PreferenceValue, buildElectronAppChecksumsUrl, buildElectronAppReleaseAssetUrl, buildElectronAppReleaseTag, calculateFileChecksum, createApiKeyWithToken, createChildLogger, deleteApiKeyData, deleteCredentials, e2e_exports as e2e, formatPreferencesOneLiner, getApiKey, getApiKeyFilePath, getAuthService, getBundledElectronAppVersion, getCallerCredentials, getCallerCredentialsAsync, getChecksumForPlatform, getConfig, getCredentialsFilePath, getDataDir, getDownloadBaseUrl, getElectronAppChecksums, getElectronAppDir, getElectronAppVersion, getElectronAppVersionSource, getLocalQaTools, getLogger, getPlatformKey, getQaTools, getValidApiKeyData, getValidCredentials, hasApiKey, isElectronAppInstalled, isFirstRun, loadApiKeyData, loadCredentials, local_exports as localQa, mcp_exports as mcp, openBrowserUrl, performLogin, performLogout, pollDeviceCode, e2e_exports as qa, readGlobalPreferences, readProjectPreferences, resetConfig, resetLogger, resetPreference, resolveElectronAppPathOrNull, resolvePreferences, saveApiKey, saveApiKeyData, saveCredentials, startDeviceCodeFlow, toolRequiresAuth, validatePreference, verifyFileChecksum, writePreferences } from './chunk-LVUJ4E62.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": "5.3.
|
|
4
|
+
"version": "5.3.2",
|
|
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",
|
|
@@ -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": "5.3.
|
|
4
|
+
"version": "5.3.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": "5.3.
|
|
5
|
+
"version": "5.3.1",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Muggle AI",
|
|
8
8
|
"email": "support@muggle-ai.com"
|
|
@@ -43,7 +43,7 @@ ${input2.tool_response?.output ?? ""}`;
|
|
|
43
43
|
// src/guardrails/testsGreen.ts
|
|
44
44
|
var TEST_CMD = /\b(pnpm|npm|yarn)\s+(run\s+)?test\b|\b(jest|vitest|pytest)\b|\bgo\s+test\b|\bcargo\s+test\b/;
|
|
45
45
|
var FAIL = /\b\d+\s+failed\b|\bFAIL\b|✗/;
|
|
46
|
-
var
|
|
46
|
+
var E2E_TOOL = /muggle.*(execute|test-generation|replay)/i;
|
|
47
47
|
function isTestCommand(cmd) {
|
|
48
48
|
return TEST_CMD.test(cmd);
|
|
49
49
|
}
|
|
@@ -54,9 +54,7 @@ ${input2.tool_response?.stderr ?? ""}`;
|
|
|
54
54
|
return !FAIL.test(out);
|
|
55
55
|
}
|
|
56
56
|
function isE2ERun(input2) {
|
|
57
|
-
|
|
58
|
-
const tool = input2.tool_name ?? "";
|
|
59
|
-
return E2E_RUN.test(cmd) || /muggle.*(execute|test-generation|replay)/i.test(tool);
|
|
57
|
+
return E2E_TOOL.test(input2.tool_name ?? "");
|
|
60
58
|
}
|
|
61
59
|
|
|
62
60
|
// src/guardrails/shouldRunE2E.ts
|
package/plugin/skills/CLAUDE.md
CHANGED
|
@@ -13,3 +13,18 @@ A reverse reference (A → B and B → A) couples the depended-on skill to its c
|
|
|
13
13
|
**Worked example.** `muggle-pr-followup` (the dumb-pipe watcher) is lower-level than `muggle-do` (the executor that orchestrates it). `muggle-do` references `muggle-pr-followup`; `muggle-pr-followup`'s files must not link back to `muggle-do`. A watcher tick still dispatches `/muggle-do …` at runtime — allowed — but no watcher file links a `do/` file or restates its steps, and shared primitives like `muggle-pr-followup/finalize.md` stay dispatch-free so any caller can reuse them.
|
|
14
14
|
|
|
15
15
|
When you feel the urge to link "up" to a caller, that is the smell — restructure so the caller passes what is needed in.
|
|
16
|
+
|
|
17
|
+
## Model tiers
|
|
18
|
+
|
|
19
|
+
Each skill sets a `model:` in its `SKILL.md` frontmatter sized to its cognitive load. `model:` is a native Claude Code field — the override applies while the skill is active and reverts to the session model when it exits. Cheaper, faster models run the mechanical skills; the default (Opus) is reserved for the ones that actually reason. Cost and latency scale with the model, and these skills run often (the watcher fires every minute), so the tier is a real lever, not cosmetics.
|
|
20
|
+
|
|
21
|
+
| Model | Skills | Why this tier |
|
|
22
|
+
|-------|--------|---------------|
|
|
23
|
+
| `haiku` | `muggle`, `muggle-status`, `muggle-repair`, `muggle-upgrade`, `muggle-preferences`, `muggle-feedback`, `muggle-pr-followup` | Routers and dumb pipes. They follow an explicit procedure with no open-ended reasoning: route intent to a downstream skill, run a fixed CLI sequence, CRUD a config file, format a status report, or poll provider state and branch on conditions. `muggle-pr-followup` is the canonical case — a watcher that reads GitHub state and dispatches; all judgment lives in the `muggle-do` it hands off to. |
|
|
24
|
+
| `sonnet` | `muggle-pr-visual-walkthrough`, `muggle-test-regenerate-missing` | Multi-step orchestration with light judgment, short of deep reasoning: assemble run data and build a PR section with fit-vs-overflow handling; scan, filter, bulk-dispatch, and classify per-item failures into buckets. More moving parts than a router, but each step is well-defined. |
|
|
25
|
+
| `opus` (explicit pin) | `muggle-test-prepare` | Pinned for **reliability**, not raw reasoning load: it's flaky on smaller models, and since other skills gate on the environment it readies, a wrong call is expensive. Pin explicitly rather than leaving `model:` unset so it stays on Opus even when the user's session runs a cheaper model. |
|
|
26
|
+
| default (Opus) — no `model:` set | `muggle-do`, `muggle-test`, `muggle-test-feature-local`, `muggle-browser-task`, `muggle-test-import` | Reasoning-heavy. Authoring code to a PR, mapping a code diff to affected user flows and interpreting E2E results, reasoning about an arbitrary website's flow to drive a browser, translating Playwright/Cypress/PRD artifacts into Muggle test cases. Leave `model:` unset so the skill inherits the session model. |
|
|
27
|
+
|
|
28
|
+
**Choosing a tier for a new skill.** Ask what the skill actually does. Pure routing / fixed procedure / CRUD / reporting → `haiku`. Several well-defined steps with some judgment or classification → `sonnet`. Open-ended reasoning, code authoring, or interpreting ambiguous real-world state → leave `model:` unset (Opus). When unsure between two tiers, pick the cheaper one and watch for misbehavior — the likeliest to need a bump is anything doing AI-based classification. If a skill proves flaky on its tier and reliability matters more than cost (other skills depend on it, or a wrong call is expensive), pin it up explicitly — `model: opus` — rather than leaving it unset, so the floor holds regardless of the user's session model.
|
|
29
|
+
|
|
30
|
+
**Never set `model:` on aliases or commands.** The alias skills (`m`, `mstatus`, …) and `plugin/commands/*.md` are thin routers that re-invoke the canonical skill via the `Skill` tool. The canonical `SKILL.md`'s `model:` takes effect once it loads, so a model on the alias would only apply to the negligible one-line hand-off — and risks drifting from the canonical value.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-feedback
|
|
3
|
+
model: haiku
|
|
3
4
|
description: "Use when the user wants to flag that a generated Muggle Test action script — or one specific step in it — did the wrong thing, so Muggle can analyze and regenerate affected scripts. Covers any report that a script or step is wrong, broken, or misbehaving (clicked the wrong element, step N did not work, broken at the submit step), whether from a recent local/remote run or a pasted Muggle dashboard run/script URL. Also lists, views, or deletes previously submitted feedback. Triggers on /muggle-feedback, give feedback on this run, the test was wrong, flag this run."
|
|
4
5
|
---
|
|
5
6
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-pr-followup
|
|
3
|
+
model: haiku
|
|
3
4
|
description: "Use when the user wants a pull request's incoming review feedback handled for them — it watches one PR's review thread and, each time a reviewer submits new comments, dispatches the work to address them. Engage on PR-review-follow-up intent: \"watch my PR and address review comments as they come in\", \"keep an eye on PR #123 and respond to reviewer feedback\", \"babysit my PR's review thread\", \"I'm stepping away — handle my PR's reviews while I'm gone\". This is PR-review-specific automation — prefer it over the generic loop skill. It only watches and dispatches; the actual edits and replies are muggle-do. Not for posting test results to a PR (use muggle-pr-visual-walkthrough)."
|
|
4
5
|
---
|
|
5
6
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-pr-visual-walkthrough
|
|
3
|
+
model: sonnet
|
|
3
4
|
description: Renders and posts a visual walkthrough of Muggle AI E2E acceptance test results to a PR — per-test-case dashboard links, step-by-step screenshots, and pass/fail summary — using the `muggle build-pr-section` CLI for deterministic formatting with automatic fit-vs-overflow. Use at the end of any Muggle Test test run (local or remote) to give PR reviewers clickable visual evidence that user flows work. Triggers on 'post results to PR', 'attach walkthrough to PR', 'share E2E screenshots on the PR', 'add visual walkthrough to PR'.
|
|
4
5
|
---
|
|
5
6
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-status
|
|
3
|
+
model: haiku
|
|
3
4
|
description: "Check the health of the user's Muggle AI installation and diagnose why it's misbehaving — MCP server connectivity, tool loading, login/auth validity, overall setup. Engage on muggle status and on any diagnostic question about Muggle itself: is muggle working or healthy, why does muggle keep failing or timing out, are the muggle MCP tools loading, is my muggle login still valid. Prefer this over answering from memory whenever the user is unsure Muggle itself is functioning. Boundary: diagnosing is muggle-status; fixing a broken install is muggle-repair. Not for the health of the user's own app, CI, or infra."
|
|
4
5
|
---
|
|
5
6
|
|
|
@@ -151,12 +151,12 @@ Caller glue: `mode` is the path chosen in §5; `localUrl` from §4; `cwd` = the
|
|
|
151
151
|
|
|
152
152
|
Resolve the `showElectronBrowser` gate **first**, then call `muggle-local-execute-test-generation` or `muggle-local-execute-replay`. **Do not** ask the user to re-approve the Electron launch itself — choosing this skill is the approval. That run-approval suppression does **not** extend to the gate below: when `showElectronBrowser=ask` you must still fire its picker.
|
|
153
153
|
|
|
154
|
-
Gate `showElectronBrowser` (per `preference-gates/README.md`). Reuse the choice within a session.
|
|
155
|
-
- `always` → omit `showUi`
|
|
156
|
-
- `never` → pass `showUi: false`.
|
|
154
|
+
Gate `showElectronBrowser` (per `preference-gates/README.md`). Reuse the choice within a session. The runner shows the browser by default, so treat `showUi` as a **hide switch** — include it only to turn the browser off:
|
|
155
|
+
- `always` (show it) → **omit `showUi` entirely** — no `showUi` key in the call. Passing `showUi: false` here is a bug: it hides the browser the user wanted to watch.
|
|
156
|
+
- `never` (hide it) → pass `showUi: false`.
|
|
157
157
|
- `ask` → you **must** call `AskUserQuestion` (Picker 1 from `preference-gates/showElectronBrowser.md`) **before** the execute call, then map the answer to the `always`/`never` action above. Do not decide for the user.
|
|
158
158
|
|
|
159
|
-
`showUi`
|
|
159
|
+
So the execute call carries **no `showUi` key** for `always`, or `showUi: false` for `never` — never `showUi: true`.
|
|
160
160
|
|
|
161
161
|
### 8. Open the run on the dashboard (`viewUrl` gated by `openTestResultsAfterRun`)
|
|
162
162
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-test-prepare
|
|
3
|
+
model: opus
|
|
3
4
|
description: "Get a user's local environment ready before running E2E acceptance tests — verify the dev servers, APIs, and sibling services they need are up and responding, and offer to start whatever is missing (with approval per step). Trigger when the user wants to confirm specific ports or localhost URLs are listening before testing (check if localhost:3000 and the api on 8080 are up, are my services running), spin up their local dev stack, or verify their setup — and whenever another muggle skill (muggle-test, muggle-do, muggle-test-feature-local) needs services running but they're not. This is environment readiness and service startup, not running the tests."
|
|
4
5
|
---
|
|
5
6
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: muggle-test-regenerate-missing
|
|
3
|
+
model: sonnet
|
|
3
4
|
description: "Bulk-regenerate test scripts for every test case in a Muggle AI project that has no active script. Scans the project, finds test cases stuck in DRAFT or GENERATION_PENDING, shows the user the list, and on approval kicks off bulk remote script generation via the Muggle Test cloud. Use when the user wants to regenerate missing scripts, fill in missing test scripts, generate scripts for test cases without one, rebuild scripts for stale test cases, or bulk regenerate across a project. Handles discovery, filtering, confirmation, and remote dispatch end-to-end."
|
|
4
5
|
---
|
|
5
6
|
|