@muggleai/works 4.9.1 → 4.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-6N7OIBAS.js → chunk-RK6XKSZK.js} +2 -2
- package/dist/{chunk-4KQZLF56.js → chunk-UVXOHXY2.js} +182 -20
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/plugin/.claude-plugin/plugin.json +1 -8
- package/dist/plugin/.cursor-plugin/plugin.json +1 -1
- package/dist/plugin/agents/acceptance-tester.md +1 -8
- package/dist/plugin/scripts/ensure-electron-app.sh +24 -1
- package/dist/plugin/skills/muggle/SKILL.md +3 -12
- package/dist/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +5 -12
- package/dist/plugin/skills/muggle-preferences/SKILL.md +85 -44
- package/dist/plugin/skills/muggle-preferences/preference-gates/README.md +58 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +17 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +15 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +30 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +11 -0
- package/dist/plugin/skills/muggle-preferences/preference-gates/verboseOutput.md +8 -0
- package/dist/plugin/skills/muggle-status/SKILL.md +9 -14
- package/dist/plugin/skills/muggle-test/SKILL.md +56 -55
- package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +35 -36
- package/dist/plugin/skills/muggle-test-import/SKILL.md +58 -24
- package/dist/plugin/skills/muggle-test-regenerate-missing/SKILL.md +20 -22
- package/dist/release-manifest.json +4 -4
- package/dist/src-GD3YFCCW.js +1 -0
- package/package.json +2 -2
- package/plugin/.claude-plugin/plugin.json +1 -8
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/agents/acceptance-tester.md +1 -8
- package/plugin/scripts/ensure-electron-app.sh +24 -1
- package/plugin/skills/muggle/SKILL.md +3 -12
- package/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +5 -12
- package/plugin/skills/muggle-preferences/SKILL.md +85 -44
- package/plugin/skills/muggle-preferences/preference-gates/README.md +58 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoDetectChanges.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoLogin.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoPublishLocalResults.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/autoSelectProject.md +17 -0
- package/plugin/skills/muggle-preferences/preference-gates/checkForUpdates.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/defaultExecutionMode.md +15 -0
- package/plugin/skills/muggle-preferences/preference-gates/openTestResultsAfterRun.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/postPRVisualWalkthrough.md +30 -0
- package/plugin/skills/muggle-preferences/preference-gates/showElectronBrowser.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedTestCases.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/suggestRelatedUseCases.md +11 -0
- package/plugin/skills/muggle-preferences/preference-gates/verboseOutput.md +8 -0
- package/plugin/skills/muggle-status/SKILL.md +9 -14
- package/plugin/skills/muggle-test/SKILL.md +56 -55
- package/plugin/skills/muggle-test-feature-local/SKILL.md +35 -36
- package/plugin/skills/muggle-test-import/SKILL.md +58 -24
- package/plugin/skills/muggle-test-regenerate-missing/SKILL.md +20 -22
- package/dist/src-7GB7WIFT.js +0 -1
|
@@ -20,23 +20,14 @@ in a Muggle project via the API.
|
|
|
20
20
|
|
|
21
21
|
## Preferences
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
Gates run per `preference-gates/README.md`.
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
This skill uses these preferences:
|
|
33
|
-
|
|
34
|
-
| Preference | Decision it gates |
|
|
35
|
-
|------------|------------------|
|
|
36
|
-
| `autoLogin` | Reuse saved credentials when auth is required |
|
|
37
|
-
| `autoSelectProject` | Reuse last-used Muggle project for this repo |
|
|
38
|
-
| `suggestRelatedUseCases` | Suggest related use cases after import |
|
|
39
|
-
| `suggestRelatedTestCases` | Suggest related test cases after import |
|
|
25
|
+
| Preference | Step | Decision it gates |
|
|
26
|
+
|------------|------|-------------------|
|
|
27
|
+
| `autoLogin` | 4 | Reuse saved credentials when auth is required |
|
|
28
|
+
| `autoSelectProject` | 5 | Reuse last-used Muggle project for this repo |
|
|
29
|
+
| `suggestRelatedUseCases` | 8a | Suggest related use cases after import |
|
|
30
|
+
| `suggestRelatedTestCases` | 8b | Suggest related test cases after import |
|
|
40
31
|
|
|
41
32
|
## Concepts
|
|
42
33
|
|
|
@@ -146,14 +137,13 @@ If the user wants changes, incorporate feedback, then ask again. Only proceed af
|
|
|
146
137
|
|
|
147
138
|
---
|
|
148
139
|
|
|
149
|
-
## Step 4 — Authenticate
|
|
140
|
+
## Step 4 — Authenticate (gated by `autoLogin`)
|
|
150
141
|
|
|
151
142
|
Call `muggle-remote-auth-status` first.
|
|
152
143
|
|
|
153
|
-
If **already authenticated** →
|
|
154
|
-
|
|
155
|
-
-
|
|
156
|
-
- Option 2: "No, switch account" → call `muggle-remote-auth-login` with `forceNewSession: true`, then `muggle-remote-auth-poll`.
|
|
144
|
+
If **already authenticated** → gate `autoLogin` (per `preference-gates/README.md`):
|
|
145
|
+
- Pro-action: skip to Step 5.
|
|
146
|
+
- Skip-action: `muggle-remote-auth-login` with `forceNewSession: true`, then `muggle-remote-auth-poll`.
|
|
157
147
|
|
|
158
148
|
If **not authenticated**:
|
|
159
149
|
1. Tell the user a browser window is about to open.
|
|
@@ -163,14 +153,23 @@ If **not authenticated**:
|
|
|
163
153
|
|
|
164
154
|
---
|
|
165
155
|
|
|
166
|
-
## Step 5 — Pick or create a project
|
|
156
|
+
## Step 5 — Pick or create a project (gated by `autoSelectProject`)
|
|
167
157
|
|
|
168
158
|
A **project** is where all your imported use cases, test cases, and future test results are grouped on the Muggle AI dashboard.
|
|
169
159
|
|
|
170
|
-
|
|
160
|
+
The per-repo project cache lives at `<cwd>/.muggle-ai/last-project.json` (via the `muggle-local-last-project-get` / `muggle-local-last-project-set` MCP tools). Look for `Muggle Last Project: id=… url=… name="…"` in session context.
|
|
161
|
+
|
|
162
|
+
Gate `autoSelectProject` (per `preference-gates/README.md`). Cache: `Muggle Last Project` session line.
|
|
163
|
+
- `always` + cache → use cached `projectId`, skip to Step 6. No cache → fall through to `ask`.
|
|
164
|
+
- `never` → full project list; skip Picker 2.
|
|
165
|
+
- `ask` → project list picker (see gate file for spec + Picker 2 override). Skip Picker 2 if "Create new project".
|
|
166
|
+
|
|
167
|
+
### Logic
|
|
168
|
+
|
|
169
|
+
1. Call `muggle-remote-project-list` (only when not satisfied by the `always` cache).
|
|
171
170
|
2. Use `AskQuestion` to present all projects as clickable options. Include the project URL in each label. Always include a "Create new project" option at the end.
|
|
172
171
|
|
|
173
|
-
Prompt: "Pick the project to import into:"
|
|
172
|
+
Prompt: `"Pick the project to import into:"`
|
|
174
173
|
|
|
175
174
|
3. **If creating a new project**, propose values based on what you learned from the source files:
|
|
176
175
|
- **Name**: infer the app name from filenames, URLs, or document headings (e.g., "Acme App")
|
|
@@ -392,3 +391,38 @@ Imported: 3 use cases · 8 test cases
|
|
|
392
391
|
|
|
393
392
|
Next step: run /muggle:do to generate executable browser test scripts for these test cases.
|
|
394
393
|
```
|
|
394
|
+
|
|
395
|
+
### Step 8 — Optional follow-up suggestions
|
|
396
|
+
|
|
397
|
+
Two preferences gate optional follow-ups: `suggestRelatedUseCases` and `suggestRelatedTestCases`. Both are independent — handle each in turn.
|
|
398
|
+
|
|
399
|
+
#### 8a — Related use cases (gated by `suggestRelatedUseCases`)
|
|
400
|
+
|
|
401
|
+
The query is: "from the use cases already in this project, which ones are *not* in the import set but look related to it?" — surface them so the user can decide whether their import missed something the project already tracks.
|
|
402
|
+
|
|
403
|
+
Gate `suggestRelatedUseCases` (per `preference-gates/README.md`):
|
|
404
|
+
- Pro-action: run the query below.
|
|
405
|
+
- Skip-action: skip.
|
|
406
|
+
|
|
407
|
+
When running the query:
|
|
408
|
+
1. Call `muggle-remote-use-case-list` for the project.
|
|
409
|
+
2. Filter out any use case whose `useCaseId` is in the set you just imported in Step 6 (Pass 1).
|
|
410
|
+
3. Rank the remainder by semantic relevance to the imported titles/descriptions (substring overlap, shared keywords — best-effort, no LLM call needed).
|
|
411
|
+
4. Present the top 3-5 via `AskQuestion` with `allow_multiple: true`. Label each with `<title> — <one-line description>`.
|
|
412
|
+
5. For any the user selects, prompt to add follow-up test cases (treat each as a Pass 2 invocation: `muggle-remote-test-case-bulk-preview-submit` → poll → persist via `muggle-remote-test-case-create`).
|
|
413
|
+
6. If the filtered list is empty (the import covers everything in the project), say so and skip.
|
|
414
|
+
|
|
415
|
+
#### 8b — Related test cases (gated by `suggestRelatedTestCases`)
|
|
416
|
+
|
|
417
|
+
For each use case the user just created, surface other test cases already attached that the import didn't add — same idea, scoped to a single use case.
|
|
418
|
+
|
|
419
|
+
Gate `suggestRelatedTestCases` (per `preference-gates/README.md`):
|
|
420
|
+
- Pro-action: run the query below.
|
|
421
|
+
- Skip-action: skip.
|
|
422
|
+
|
|
423
|
+
When running the query, for each use case in the import:
|
|
424
|
+
1. Call `muggle-remote-test-case-list-by-use-case` with that `useCaseId`.
|
|
425
|
+
2. Filter out any test case you just created in Pass 2 of Step 6.
|
|
426
|
+
3. Present the remainder via `AskQuestion` with `allow_multiple: true`, labeled `[<priority>] <title> — <goal>`.
|
|
427
|
+
4. For any the user selects: nothing to create (they already exist) — just confirm to the user that those tests are now part of their Muggle project alongside the imported ones.
|
|
428
|
+
5. If a use case has no extra test cases, skip it silently.
|
|
@@ -11,21 +11,12 @@ Execution is **remote only** — Muggle's cloud generates the scripts in paralle
|
|
|
11
11
|
|
|
12
12
|
## Preferences
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Gates run per `preference-gates/README.md`.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
- **`never`** → skip without asking the user
|
|
21
|
-
- **`ask`** → ask the user, then offer: "Want me to remember this choice for future sessions?" If yes, call `muggle-local-preferences-set` with the key, their chosen value, and scope `global`.
|
|
22
|
-
|
|
23
|
-
This skill uses these preferences:
|
|
24
|
-
|
|
25
|
-
| Preference | Decision it gates |
|
|
26
|
-
|------------|------------------|
|
|
27
|
-
| `autoLogin` | Reuse saved credentials when auth is required |
|
|
28
|
-
| `autoSelectProject` | Reuse last-used Muggle project for this repo |
|
|
16
|
+
| Preference | Step | Decision it gates |
|
|
17
|
+
|------------|------|-------------------|
|
|
18
|
+
| `autoLogin` | 1 | Reuse saved credentials when auth is required |
|
|
19
|
+
| `autoSelectProject` | 2 | Reuse last-used Muggle project for this repo |
|
|
29
20
|
|
|
30
21
|
## Concept: what counts as "no active script"
|
|
31
22
|
|
|
@@ -55,24 +46,31 @@ Treat this filter as a default, not a law. If the user explicitly says "include
|
|
|
55
46
|
|
|
56
47
|
## Workflow
|
|
57
48
|
|
|
58
|
-
### Step 1 — Authenticate
|
|
49
|
+
### Step 1 — Authenticate (gated by `autoLogin`)
|
|
59
50
|
|
|
60
51
|
1. Call `muggle-remote-auth-status`.
|
|
61
|
-
2. If **authenticated and not expired** →
|
|
62
|
-
|
|
63
|
-
-
|
|
64
|
-
- Option 2: "No, switch account"
|
|
65
|
-
If the user picks "switch account", call `muggle-remote-auth-login` with `forceNewSession: true`, then poll with `muggle-remote-auth-poll`.
|
|
52
|
+
2. If **authenticated and not expired** → gate `autoLogin` (per `preference-gates/README.md`):
|
|
53
|
+
- Pro-action: proceed with saved session.
|
|
54
|
+
- Skip-action: `muggle-remote-auth-login` with `forceNewSession: true`, then `muggle-remote-auth-poll`.
|
|
66
55
|
3. If **not authenticated or expired** → call `muggle-remote-auth-login`, then poll with `muggle-remote-auth-poll`.
|
|
67
56
|
4. Do not skip auth and do not assume a stale token still works.
|
|
68
57
|
|
|
69
58
|
If auth keeps failing, suggest the user run `muggle logout && muggle login` from a terminal.
|
|
70
59
|
|
|
71
|
-
### Step 2 — Select Project (
|
|
60
|
+
### Step 2 — Select Project (gated by `autoSelectProject`)
|
|
72
61
|
|
|
73
62
|
A **project** is the unit on the Muggle AI dashboard that groups test cases, scripts, and runs. The user must pick the one to scan — never auto-select from repo name, branch, or URL heuristics.
|
|
74
63
|
|
|
75
|
-
|
|
64
|
+
The per-repo project cache lives at `<cwd>/.muggle-ai/last-project.json` (via the `muggle-local-last-project-get` / `muggle-local-last-project-set` MCP tools). Look for `Muggle Last Project: id=… url=… name="…"` in session context.
|
|
65
|
+
|
|
66
|
+
Gate `autoSelectProject` (per `preference-gates/README.md`). Cache: `Muggle Last Project` session line.
|
|
67
|
+
- `always` + cache → use cached `projectId`, proceed to Step 3. No cache → fall through to `ask`.
|
|
68
|
+
- `never` → full project list; skip Picker 2.
|
|
69
|
+
- `ask` → project list picker (see gate file for spec + Picker 2 override). Skip Picker 2 if "Create new project".
|
|
70
|
+
|
|
71
|
+
### Logic
|
|
72
|
+
|
|
73
|
+
1. Call `muggle-remote-project-list` (only when not satisfied by the `always` cache).
|
|
76
74
|
2. Use `AskQuestion` to present projects as clickable options. Include the project URL in each label so the user can disambiguate. Always include "Create new project" as the last option.
|
|
77
75
|
3. Wait for explicit selection.
|
|
78
76
|
4. If the user picks "Create new project": collect `projectName`, `description`, and `url`, then call `muggle-remote-project-create`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"release": "4.
|
|
3
|
-
"buildId": "run-
|
|
4
|
-
"commitSha": "
|
|
5
|
-
"buildTime": "2026-
|
|
2
|
+
"release": "4.10.0",
|
|
3
|
+
"buildId": "run-28-1",
|
|
4
|
+
"commitSha": "c483ae40dda515e8bf43e72c3c644fd94fc1e1c3",
|
|
5
|
+
"buildTime": "2026-05-05T19:51:19Z",
|
|
6
6
|
"serviceName": "muggle-ai-works-mcp"
|
|
7
7
|
}
|
|
@@ -0,0 +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, resolvePreferences, saveApiKey, saveApiKeyData, saveCredentials, startDeviceCodeFlow, toolRequiresAuth, validatePreference, verifyFileChecksum, writePreferences } from './chunk-UVXOHXY2.js';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@muggleai/works",
|
|
3
3
|
"mcpName": "io.github.multiplex-ai/muggle",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.10.0",
|
|
5
5
|
"description": "Ship quality products with AI-powered E2E acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"commander": "^14.0.3",
|
|
60
60
|
"open": "^11.0.0",
|
|
61
61
|
"ulid": "^3.0.2",
|
|
62
|
-
"uuid": "^
|
|
62
|
+
"uuid": "^14.0.0",
|
|
63
63
|
"winston": "^3.17.0",
|
|
64
64
|
"zod": "^4.3.6"
|
|
65
65
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "muggle",
|
|
3
3
|
"description": "Run real-browser end-to-end (E2E) acceptance tests on your web app from any AI coding agent. Generate test scripts from plain English, replay them on localhost, capture screenshots, and validate user flows like signup, checkout, and dashboards. Works across Claude Code, Cursor, Codex, and Windsurf.",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.10.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Muggle AI",
|
|
7
7
|
"email": "support@muggle-ai.com"
|
|
@@ -9,13 +9,6 @@
|
|
|
9
9
|
"homepage": "https://www.muggletest.com",
|
|
10
10
|
"repository": "https://github.com/multiplex-ai/muggle-ai-works",
|
|
11
11
|
"license": "MIT",
|
|
12
|
-
"agents": [
|
|
13
|
-
{
|
|
14
|
-
"name": "acceptance-tester",
|
|
15
|
-
"path": "agents/acceptance-tester.md",
|
|
16
|
-
"description": "E2E acceptance testing agent — runs real-browser tests, reports structured results with blocking issues and suggested fixes, imports test artifacts, manages preferences, and operates the Muggle AI suite."
|
|
17
|
-
}
|
|
18
|
-
],
|
|
19
12
|
"keywords": [
|
|
20
13
|
"acceptance-testing",
|
|
21
14
|
"testing",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "muggle",
|
|
3
3
|
"displayName": "Muggle AI",
|
|
4
4
|
"description": "Ship quality products with AI-powered end-to-end (E2E) acceptance testing that validates your web app like a real user — from Claude Code and Cursor to PR.",
|
|
5
|
-
"version": "4.
|
|
5
|
+
"version": "4.10.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Muggle AI",
|
|
8
8
|
"email": "support@muggle-ai.com"
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: acceptance-tester
|
|
3
|
-
description:
|
|
4
|
-
E2E acceptance testing agent — runs real-browser tests against web apps and
|
|
5
|
-
reports structured results with blocking issues and suggested fixes. Also
|
|
6
|
-
imports existing test artifacts, manages Muggle preferences, and operates
|
|
7
|
-
the Muggle AI suite (status checks, repairs). Dispatch this agent when the
|
|
8
|
-
team needs acceptance test feedback, test coverage for a feature, or Muggle
|
|
9
|
-
suite operations.
|
|
3
|
+
description: "E2E acceptance testing agent — runs real-browser tests against web apps and reports structured results with blocking issues and suggested fixes. Also imports existing test artifacts, manages Muggle preferences, and operates the Muggle AI suite (status checks, repairs). Dispatch this agent when the team needs acceptance test feedback, test coverage for a feature, or Muggle suite operations."
|
|
10
4
|
model: sonnet
|
|
11
|
-
tools: ["Read", "Write", "Edit", "Bash", "Grep", "Glob"]
|
|
12
5
|
---
|
|
13
6
|
|
|
14
7
|
# Acceptance Tester
|
|
@@ -100,7 +100,30 @@ else
|
|
|
100
100
|
prefs_file_note="\\n\\nMuggle Preferences: not configured. Run \\\`muggle setup\\\` or tell the agent to set preferences."
|
|
101
101
|
fi
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
# --- Last-project cache injection ---
|
|
104
|
+
# Per-repo "last used Muggle project" cache. Lives at <cwd>/.muggle-ai/last-project.json
|
|
105
|
+
# and is honored by skills when autoSelectProject = always.
|
|
106
|
+
last_project_line=""
|
|
107
|
+
last_project_note=""
|
|
108
|
+
last_project_line=$(node -e "
|
|
109
|
+
const fs = require('fs');
|
|
110
|
+
const path = require('path');
|
|
111
|
+
try {
|
|
112
|
+
const cwd = process.env.CLAUDE_CWD || process.env.CURSOR_CWD || process.cwd();
|
|
113
|
+
const lpPath = path.join(cwd, '.muggle-ai', 'last-project.json');
|
|
114
|
+
if (!fs.existsSync(lpPath)) { console.log(''); return; }
|
|
115
|
+
const raw = JSON.parse(fs.readFileSync(lpPath, 'utf-8'));
|
|
116
|
+
const lp = raw && raw.lastProject;
|
|
117
|
+
if (!lp || !lp.projectId) { console.log(''); return; }
|
|
118
|
+
const safeName = String(lp.projectName || '').replace(/\"/g, '\\\\\"');
|
|
119
|
+
console.log('Muggle Last Project: id=' + lp.projectId + ' url=' + lp.projectUrl + ' name=\"' + safeName + '\"');
|
|
120
|
+
} catch { console.log(''); }
|
|
121
|
+
" 2>/dev/null || true)
|
|
122
|
+
if [ -n "$last_project_line" ]; then
|
|
123
|
+
last_project_note="\\n\\n${last_project_line}"
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
context="<EXTREMELY_IMPORTANT>\nYou have access to Muggle AI — a real-browser E2E acceptance testing tool.\n\nWhenever the user asks you to test, validate, verify, or check if their web app works — use the muggle MCP tools. This includes:\n- Testing user flows (signup, login, checkout, forms, dashboards)\n- Verifying UI changes didn't break anything\n- Running regression tests after code changes\n- Validating frontend behavior on localhost or a dev server\n- Checking if a feature works before merging a PR\n\nMuggle launches a real Electron browser that clicks buttons, fills forms, navigates pages, and captures screenshots. It generates replayable test scripts that persist across sessions.\n\nDo NOT write test code (Playwright, Cypress, Selenium) or try to test UI manually when muggle tools are available. Use the muggle skill or muggle MCP tools instead — they are faster, capture visual evidence, and produce reusable test scripts.\n\nTrigger phrases: 'test my app', 'check if it works', 'run E2E acceptance tests', 'validate the UI', 'verify the flow', 'regression test', 'make sure it still works', 'test before merging'.\n</EXTREMELY_IMPORTANT>${upgrade_notice}${prefs_file_note}${last_project_note}"
|
|
104
127
|
|
|
105
128
|
escaped_context=$(escape_for_json "$context")
|
|
106
129
|
|
|
@@ -9,20 +9,11 @@ Use this as the top-level Muggle command router.
|
|
|
9
9
|
|
|
10
10
|
## Preferences
|
|
11
11
|
|
|
12
|
-
User preferences are
|
|
12
|
+
User preferences are injected by the SessionStart hook into a `Muggle Preferences` line in session context (key=value pairs). Resolution: defaults → `~/.muggle-ai/preferences.json` (global) → `<repo>/.muggle-ai/preferences.json` (project). Treat absent prefs as `ask`.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
This router skill itself does not gate any decision on a preference — it just routes user intent to a downstream skill. Each downstream skill consults its own preferences. For example, `checkForUpdates` is consulted by `muggle-status` (Check 4), not here.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
- **`always`** → proceed without asking the user
|
|
18
|
-
- **`never`** → skip without asking the user
|
|
19
|
-
- **`ask`** → ask the user, then offer: "Want me to remember this choice for future sessions?" If yes, call `muggle-local-preferences-set` with the key, their chosen value, and scope `global`.
|
|
20
|
-
|
|
21
|
-
This skill uses these preferences:
|
|
22
|
-
|
|
23
|
-
| Preference | Decision it gates |
|
|
24
|
-
|------------|------------------|
|
|
25
|
-
| `checkForUpdates` | Check for newer Muggle version |
|
|
16
|
+
If the user types "muggle" with no subcommand and you want to surface a contextual hint about the update-check pref, defer to `muggle-status` rather than reimplementing the gate in this router.
|
|
26
17
|
|
|
27
18
|
## Menu
|
|
28
19
|
|
|
@@ -19,20 +19,13 @@ Rendering is always done by `muggle build-pr-section`, a battle-tested CLI that
|
|
|
19
19
|
|
|
20
20
|
## Preferences
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
This skill is invoked by callers (`muggle-test`, `muggle-test-feature-local`, `muggle-do`) **after** the caller has already consulted the `postPRVisualWalkthrough` gate and decided to post. Therefore **the gating happens upstream, not in this skill** — by the time this skill runs, the user has already approved posting (either via the saved gate value or by explicit pick).
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
| Preference | Where it's gated | Decision it gates |
|
|
25
|
+
|------------|------------------|-------------------|
|
|
26
|
+
| `postPRVisualWalkthrough` | Caller skill (e.g. `muggle-test` Step 9, `muggle-test-feature-local` Step 10) | Post visual walkthrough to PR |
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
- **`always`** → proceed without asking the user
|
|
28
|
-
- **`never`** → skip without asking the user
|
|
29
|
-
- **`ask`** → ask the user, then offer: "Want me to remember this choice for future sessions?" If yes, call `muggle-local-preferences-set` with the key, their chosen value, and scope `global`.
|
|
30
|
-
|
|
31
|
-
This skill uses these preferences:
|
|
32
|
-
|
|
33
|
-
| Preference | Decision it gates |
|
|
34
|
-
|------------|------------------|
|
|
35
|
-
| `postPRVisualWalkthrough` | Post visual walkthrough to PR |
|
|
28
|
+
Per-key gate definitions live in `plugin/skills/muggle-preferences/preference-gates/`. This skill only renders and posts.
|
|
36
29
|
|
|
37
30
|
## Input contract: the `E2eReport` JSON
|
|
38
31
|
|
|
@@ -6,7 +6,7 @@ description: >-
|
|
|
6
6
|
defaults, or manage muggle config. Triggers on: 'muggle preferences',
|
|
7
7
|
'show muggle settings', 'change muggle preference', 'set autoLogin to
|
|
8
8
|
always', 'muggle config', 'reset muggle preferences', 'show my muggle
|
|
9
|
-
settings', 'configure muggle'.
|
|
9
|
+
settings', 'configure muggle', 'muggle setup'.
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Muggle Preferences
|
|
@@ -15,68 +15,109 @@ View, set, or reset the preference knobs that control Muggle AI behavior.
|
|
|
15
15
|
|
|
16
16
|
## Operations
|
|
17
17
|
|
|
18
|
-
Parse the user's request to
|
|
18
|
+
Parse the user's request to decide which operation to run:
|
|
19
19
|
|
|
20
|
-
- **List** —
|
|
21
|
-
- **
|
|
22
|
-
- **
|
|
20
|
+
- **List** — show current values. Default when no change is requested.
|
|
21
|
+
- **Change one** — re-run the gate's picker for a single key. Use this when the user invokes `/muggle-preferences <key>` or says "change my <key> preference".
|
|
22
|
+
- **Configure** — interactive picker covering all keys at once. Default when the user wants to change preferences but hasn't named a specific one (e.g. "muggle setup", "configure muggle", "change my preferences").
|
|
23
|
+
- **Set** — direct set when the user names a key+value (e.g. "set autoLogin to always").
|
|
24
|
+
- **Reset** — restore preferences to default (`ask`).
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
Per-key files live in `preference-gates/` — one `<key>.md` per key, plus `README.md` for the contract (`always`/`never`/`ask`, Picker 2 template, silent footer, re-prompt rule). The full key list = `ls preference-gates/*.md` minus `README.md`.
|
|
27
|
+
|
|
28
|
+
## Reading current values
|
|
29
|
+
|
|
30
|
+
Read preferences from session context. Look for the line starting with `Muggle Preferences` — it contains key=value pairs like `autoLogin=ask showElectronBrowser=always ...`.
|
|
25
31
|
|
|
26
|
-
|
|
32
|
+
If no preferences line is present, treat all preferences as `"ask"` (the default).
|
|
27
33
|
|
|
28
|
-
|
|
34
|
+
## List
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
Render a `Preference | Value | Description` table titled `Muggle AI — Preferences`.
|
|
37
|
+
- Keys: every `preference-gates/<key>.md` (excluding `README.md`).
|
|
38
|
+
- Values: from session context (default `ask`).
|
|
39
|
+
- Description: each gate file's first paragraph.
|
|
31
40
|
|
|
41
|
+
Footer:
|
|
32
42
|
```
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
| Preference | Value | Description |
|
|
36
|
-
|--------------------------|--------|----------------------------------------------------------|
|
|
37
|
-
| autoLogin | ask | Reuse saved credentials without prompting |
|
|
38
|
-
| autoSelectProject | ask | Reuse last-used project for this repo |
|
|
39
|
-
| showElectronBrowser | ask | Show browser window during local tests |
|
|
40
|
-
| openTestResultsAfterRun | ask | Open results page on dashboard after local test |
|
|
41
|
-
| defaultExecutionMode | ask | Default to local or remote test execution |
|
|
42
|
-
| autoPublishLocalResults | ask | Upload local results to Muggle cloud |
|
|
43
|
-
| suggestRelatedUseCases | ask | Suggest related use cases after creating/running one |
|
|
44
|
-
| suggestRelatedTestCases | ask | Suggest related test cases after creating/running one |
|
|
45
|
-
| autoDetectChanges | ask | Scan local git changes and map to affected test cases |
|
|
46
|
-
| postPRVisualWalkthrough | ask | Post visual walkthrough with screenshots to PR |
|
|
47
|
-
| checkForUpdates | ask | Check for newer Muggle version at session start |
|
|
48
|
-
| verboseOutput | ask | Show detailed progress logs during execution |
|
|
49
|
-
|
|
50
|
-
Values: always (proceed without asking) · ask (prompt each time) · never (skip without asking)
|
|
43
|
+
Values: always · ask · never (defaultExecutionMode: local/remote/ask)
|
|
51
44
|
Scope: global (~/.muggle-ai/) or project (.muggle-ai/ in repo root)
|
|
52
45
|
```
|
|
53
46
|
|
|
54
|
-
##
|
|
47
|
+
## Change one (single-key picker)
|
|
48
|
+
|
|
49
|
+
Use this when the user invokes `/muggle-preferences <key>` or says "change my <key> preference" / "show me the <key> options". Behavior:
|
|
50
|
+
|
|
51
|
+
1. Check that `preference-gates/<key>.md` exists. If not, list `preference-gates/*.md` and ask.
|
|
52
|
+
2. Open it, run **Picker 1 only**.
|
|
53
|
+
3. Call `muggle-local-preferences-set` with the mapped value, `scope: "global"`. **Skip Picker 2** (user explicitly asked to change).
|
|
54
|
+
4. Confirm: `Set <key> to <value>.`
|
|
55
|
+
|
|
56
|
+
This is the entry point that silent-mode footers point at, so its UX must mirror the per-key gate exactly — same question, same options, same mappings.
|
|
57
|
+
|
|
58
|
+
## Configure (interactive picker)
|
|
59
|
+
|
|
60
|
+
Use this whenever the user wants to change preferences without naming a specific key. The flow runs in a single `AskUserQuestion` call so the user can toggle preferences with the keyboard instead of typing key names.
|
|
61
|
+
|
|
62
|
+
### Step 1 — show current state
|
|
63
|
+
|
|
64
|
+
Print the preference table from the **List** section so the user sees what's set today.
|
|
65
|
+
|
|
66
|
+
### Step 2 — tell the user how to drive the picker
|
|
67
|
+
|
|
68
|
+
Print this instruction block verbatim before calling `AskUserQuestion`:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
How to use this picker:
|
|
72
|
+
↑/↓ move between options
|
|
73
|
+
space toggle a preference (selected = set to `always`)
|
|
74
|
+
tab move to the next question
|
|
75
|
+
enter confirm
|
|
76
|
+
|
|
77
|
+
Anything you don't toggle keeps its current value. After this picker
|
|
78
|
+
you can tell me which (if any) should instead be set to `never`.
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Step 3 — call AskUserQuestion
|
|
82
|
+
|
|
83
|
+
Group keys into categories below (only place this UX grouping lives — not in the gate dir). For each option: label = key name, description = first paragraph of `preference-gates/<key>.md`.
|
|
55
84
|
|
|
56
|
-
|
|
85
|
+
- `multiSelect: true`, `header: "Auth & session"` — `autoLogin`, `autoSelectProject`, `checkForUpdates`, `verboseOutput`
|
|
86
|
+
- `multiSelect: true`, `header: "Test run"` — `showElectronBrowser`, `openTestResultsAfterRun`, `autoPublishLocalResults`, `autoDetectChanges`
|
|
87
|
+
- `multiSelect: true`, `header: "Suggestions & PR"` — `suggestRelatedUseCases`, `suggestRelatedTestCases`, `postPRVisualWalkthrough`
|
|
88
|
+
- `multiSelect: false`, `header: "Default mode"` — `defaultExecutionMode`. Options: `Local — run on my computer` (`local`), `Remote — run in the Muggle cloud` (`remote`), `Ask each time` (don't change).
|
|
89
|
+
- `multiSelect: false`, `header: "Scope"` — final scope question. Options: `Global (all repos)` (~/.muggle-ai/), `This project only` (.muggle-ai/ in repo).
|
|
57
90
|
|
|
58
|
-
|
|
91
|
+
For the multi-select questions: text = `Which of these should auto-proceed (set to "always")?`; selected = `always`.
|
|
59
92
|
|
|
60
|
-
|
|
93
|
+
`AskUserQuestion` accepts up to 4 questions per call — split into two calls if needed (categories first, scope second).
|
|
61
94
|
|
|
62
|
-
|
|
95
|
+
### Step 4 — apply selections
|
|
63
96
|
|
|
64
|
-
|
|
65
|
-
- Default to `global`.
|
|
66
|
-
- If the user says "for this project", "project-level", or "just this repo", use `project` scope and pass `cwd` as the current working directory.
|
|
97
|
+
For each toggled key (multi-select questions): `muggle-local-preferences-set` with `value: "always"`. For `defaultExecutionMode`: only set if user picked Local/Remote (skip "Ask each time"). Pass `scope` from the scope question; pass `cwd` when scope is `project`.
|
|
67
98
|
|
|
68
|
-
5
|
|
69
|
-
- `key`: The preference key
|
|
70
|
-
- `value`: The chosen value
|
|
71
|
-
- `scope`: `"global"` or `"project"`
|
|
72
|
-
- `cwd`: Current working directory (required when scope is `"project"`)
|
|
99
|
+
### Step 5 — offer the `never` follow-up
|
|
73
100
|
|
|
101
|
+
Ask: `Want any of these set to "never" (auto-skip without asking)? Name them, e.g. "never on autoPublishLocalResults", or say "no".`. For named keys, call `muggle-local-preferences-set` with `value: "never"`, same scope.
|
|
102
|
+
|
|
103
|
+
### Step 6 — confirm
|
|
104
|
+
|
|
105
|
+
Print a one-liner summary: `Set autoLogin=always, openTestResultsAfterRun=always (global).`
|
|
106
|
+
|
|
107
|
+
## Set (direct)
|
|
108
|
+
|
|
109
|
+
When the user names both key and value (e.g. "set autoLogin to always", "make showElectronBrowser never for this project"):
|
|
110
|
+
|
|
111
|
+
1. Parse `key` and `value` from the user's message.
|
|
112
|
+
2. Validate `key`: `preference-gates/<key>.md` must exist. If not, list `preference-gates/*.md` and ask.
|
|
113
|
+
3. Validate `value`: must be `always`/`never`/`ask` for all keys; `defaultExecutionMode` accepts `local`/`remote`/`ask` instead.
|
|
114
|
+
4. Scope defaults to `global`. If user says "for this project" / "just this repo", use `project` and pass `cwd`.
|
|
115
|
+
5. Call `muggle-local-preferences-set`.
|
|
74
116
|
6. Confirm: `Set {key} to {value} ({scope}).`
|
|
75
117
|
|
|
76
118
|
## Reset
|
|
77
119
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
2. If the user asks to reset **all preferences**: call `muggle-local-preferences-set` for each of the 12 keys with `value: "ask"`.
|
|
120
|
+
- Specific key: `muggle-local-preferences-set` with `value: "ask"` for that key.
|
|
121
|
+
- All preferences: same call for every `preference-gates/<key>.md`.
|
|
81
122
|
|
|
82
|
-
|
|
123
|
+
Confirm what was reset.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Preference Gates — Contract
|
|
2
|
+
|
|
3
|
+
One file per key in this directory — `ls preference-gates/*.md` is the
|
|
4
|
+
authoritative key list. Skills load this contract + only the gates they
|
|
5
|
+
actually fire.
|
|
6
|
+
|
|
7
|
+
Default allowed values: `always` / `never` / `ask`. Per-key overrides
|
|
8
|
+
are noted in their own file (currently only `defaultExecutionMode`,
|
|
9
|
+
which uses `local` / `remote` / `ask`).
|
|
10
|
+
|
|
11
|
+
## Resolution
|
|
12
|
+
|
|
13
|
+
`SessionStart` injects a `Muggle Preferences` line (`key=value` pairs) from
|
|
14
|
+
`~/.muggle-ai/preferences.json` (global) overlaid by
|
|
15
|
+
`<repo>/.muggle-ai/preferences.json` (project). Absent → treat as `ask`.
|
|
16
|
+
|
|
17
|
+
## Gate behavior
|
|
18
|
+
|
|
19
|
+
- `always` → take the pro-action, then print silent footer.
|
|
20
|
+
- `never` → take the skip-action, then print silent footer.
|
|
21
|
+
- `ask` (or absent) → run Picker 1 (per-key file) → Picker 2 (below).
|
|
22
|
+
|
|
23
|
+
`defaultExecutionMode` uses `local`/`remote` instead of `always`/`never`.
|
|
24
|
+
|
|
25
|
+
## Silent footer (whenever pickers are skipped)
|
|
26
|
+
|
|
27
|
+
The user must always be told **what happened**, **why it was silent**, and
|
|
28
|
+
**how to change it**. Two lines:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
✓ <silent action from per-key file>
|
|
32
|
+
(Skipped the prompt — `<key>` is set to `<value>`. Change: `/muggle-preferences <key>`.)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Concrete example (gate `autoLogin = always`):
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
✓ Continuing as foo@bar.com
|
|
39
|
+
(Skipped the prompt — `autoLogin` is set to `always`. Change: `/muggle-preferences autoLogin`.)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Picker 2 — shared template
|
|
43
|
+
|
|
44
|
+
Header `Remember this choice?`. Question: `"Always <restate Picker 1 choice in
|
|
45
|
+
plain language> from now on, without asking?"`. Never put the raw key or
|
|
46
|
+
`=` in the user-visible text.
|
|
47
|
+
|
|
48
|
+
- `Yes, always` (sub: `You can change this later in muggle preferences.`) → `muggle-local-preferences-set` with the value Picker 1 mapped to, `scope: "global"`.
|
|
49
|
+
- `Just this once` (sub: `I'll ask again next time.`) → don't save.
|
|
50
|
+
|
|
51
|
+
A few keys override this template (their per-key file says how).
|
|
52
|
+
|
|
53
|
+
**Saved value MUST match the Picker 1 choice.** Saving the opposite of
|
|
54
|
+
what the user picked is a bug.
|
|
55
|
+
|
|
56
|
+
## `/muggle-preferences <key>` (re-prompt)
|
|
57
|
+
|
|
58
|
+
Run Picker 1 only, save immediately, skip Picker 2.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# `autoDetectChanges`
|
|
2
|
+
|
|
3
|
+
Scan local git changes to scope the test run, or skip the scan.
|
|
4
|
+
|
|
5
|
+
**Picker 1** — header `Local git scan`, question `"Scan git changes to scope what to test?"`
|
|
6
|
+
- `Yes, scan changes` — `Test cases that match recent diffs get prioritized.` → `always`
|
|
7
|
+
- `No, I'll specify` — `Skip the scan — I'll tell you what to test.` → `never`
|
|
8
|
+
|
|
9
|
+
**Silent action**
|
|
10
|
+
- `always` → `Scanning git changes to scope the run`
|
|
11
|
+
- `never` → `Skipping git scan — please tell me what to test`
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# `autoLogin`
|
|
2
|
+
|
|
3
|
+
Reuse the saved session, or force a fresh login. Substitute `{email}`.
|
|
4
|
+
|
|
5
|
+
**Picker 1** — header `You're already logged in`, question `"Continue as {email}, or sign in with a different account?"`
|
|
6
|
+
- `Continue as me` — `Reuse this session for the rest of this run.` → `always`
|
|
7
|
+
- `Switch account` — `Sign out and log in fresh.` → `never`
|
|
8
|
+
|
|
9
|
+
**Silent action**
|
|
10
|
+
- `always` → `Continuing as {email}`
|
|
11
|
+
- `never` → `Forcing a fresh login`
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# `autoPublishLocalResults`
|
|
2
|
+
|
|
3
|
+
Upload local run artifacts to the Muggle cloud, or keep them local.
|
|
4
|
+
|
|
5
|
+
**Picker 1** — header `Share results?`, question `"Upload these results to the Muggle dashboard?"`
|
|
6
|
+
- `Upload them` — `Needed for the dashboard view, PR walkthrough, and team visibility.` → `always`
|
|
7
|
+
- `Keep local-only` — `Stay on this machine — no dashboard view or PR walkthrough.` → `never`
|
|
8
|
+
|
|
9
|
+
**Silent action**
|
|
10
|
+
- `always` → `Uploading to the dashboard`
|
|
11
|
+
- `never` → `Keeping results local`
|