@muggleai/works 4.8.4 → 4.9.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-44I5ROCB.js → chunk-4KQZLF56.js} +219 -7
- package/dist/{chunk-OMLNCNSZ.js → chunk-6N7OIBAS.js} +7 -2
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/plugin/.claude-plugin/plugin.json +8 -1
- package/dist/plugin/.cursor-plugin/plugin.json +1 -1
- package/dist/plugin/agents/acceptance-tester.md +103 -0
- package/dist/plugin/scripts/ensure-electron-app.sh +37 -1
- package/dist/plugin/skills/muggle/SKILL.md +24 -8
- package/dist/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +17 -0
- package/dist/plugin/skills/muggle-preferences/SKILL.md +82 -0
- package/dist/plugin/skills/muggle-status/SKILL.md +17 -0
- package/dist/plugin/skills/muggle-test/SKILL.md +26 -0
- package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +50 -19
- package/dist/plugin/skills/muggle-test-import/SKILL.md +20 -0
- package/dist/plugin/skills/muggle-test-prepare/SKILL.md +276 -0
- package/dist/plugin/skills/muggle-test-regenerate-missing/SKILL.md +18 -0
- package/dist/release-manifest.json +4 -4
- package/dist/src-7GB7WIFT.js +1 -0
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +8 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/agents/acceptance-tester.md +103 -0
- package/plugin/scripts/ensure-electron-app.sh +37 -1
- package/plugin/skills/muggle/SKILL.md +24 -8
- package/plugin/skills/muggle-pr-visual-walkthrough/SKILL.md +17 -0
- package/plugin/skills/muggle-preferences/SKILL.md +82 -0
- package/plugin/skills/muggle-status/SKILL.md +17 -0
- package/plugin/skills/muggle-test/SKILL.md +26 -0
- package/plugin/skills/muggle-test-feature-local/SKILL.md +50 -19
- package/plugin/skills/muggle-test-import/SKILL.md +20 -0
- package/plugin/skills/muggle-test-prepare/SKILL.md +276 -0
- package/plugin/skills/muggle-test-regenerate-missing/SKILL.md +18 -0
- package/dist/src-ZRUONWKV.js +0 -1
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: muggle-test-prepare
|
|
3
|
+
description: "Make sure dev servers and sibling services are ready on the user's machine before running E2E acceptance tests. Checks which services need to be running, discovers sibling directories by folder name, verifies what's already listening, and offers to start anything that's missing — with the user's approval at every step. Use this skill whenever the user needs to prepare their local environment for E2E testing, verify their services are up, get their local dev stack ready, or when other muggle skills detect that required services are not listening on common ports. Triggers on: 'prepare for testing', 'make sure my services are running', 'check my local env', 'get ready for tests', 'are my services up', 'prepare local environment', 'spin up services', 'set up for E2E', 'verify my setup'. Also use when muggle-test, muggle-do, or muggle-test-feature-local need services running."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Muggle Test Prepare
|
|
7
|
+
|
|
8
|
+
Make sure the local services a user needs for E2E acceptance testing are up and ready. Check what's already running, discover sibling service directories by folder name, and offer to start anything that's missing — always with the user in control.
|
|
9
|
+
|
|
10
|
+
Some users start their own services (tmux scripts, docker-compose, a terminal per service). Others want help launching them. This skill handles both: it verifies readiness first, and only offers to start things when something is missing.
|
|
11
|
+
|
|
12
|
+
## Privacy Boundary
|
|
13
|
+
|
|
14
|
+
This skill touches the user's local machine — processes, ports, directories outside the current repo. Every action is explicit and confirmed.
|
|
15
|
+
|
|
16
|
+
- **Folder names are public.** You may list directory names in a parent folder to discover sibling services.
|
|
17
|
+
- **File contents are private until confirmed.** Never read files inside a directory the user hasn't explicitly identified as a service to start. Once confirmed, you may inspect only top-level project indicator files (`package.json`, `Makefile`, `Cargo.toml`, `go.mod`, `pyproject.toml`, `docker-compose.yml`) to determine the start command.
|
|
18
|
+
- **Never traverse upward more than one level** from the current working directory to list folders.
|
|
19
|
+
|
|
20
|
+
## PID Tracking
|
|
21
|
+
|
|
22
|
+
All launched processes are tracked in `/tmp/muggle-test-prepare.json`:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"session_started": "2025-01-15T10:30:00Z",
|
|
27
|
+
"testing_scope": "frontend",
|
|
28
|
+
"excluded_services": [
|
|
29
|
+
{"name": "payment-gateway", "reason": "Needs production certificates"}
|
|
30
|
+
],
|
|
31
|
+
"services": [
|
|
32
|
+
{
|
|
33
|
+
"name": "backend-api",
|
|
34
|
+
"dir": "/Users/user/Github/backend-api",
|
|
35
|
+
"command": "npm run dev",
|
|
36
|
+
"pid": 12345,
|
|
37
|
+
"port": 3001,
|
|
38
|
+
"log": "/tmp/muggle-prepare-backend-api.log"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The `testing_scope` field records what the user is testing (from Step 1). The `excluded_services` field records services the user said can't run locally (from Step 2), so other skills understand what's intentionally absent vs. forgotten.
|
|
45
|
+
|
|
46
|
+
**On every invocation**, check this file first. If it exists with live PIDs (verify with `kill -0`), present the running services and ask:
|
|
47
|
+
|
|
48
|
+
Use `AskQuestion`:
|
|
49
|
+
- Option 1: "Keep them running — skip to testing"
|
|
50
|
+
- Option 2: "Tear down and start fresh"
|
|
51
|
+
- Option 3: "Add more services to the running set"
|
|
52
|
+
|
|
53
|
+
Prune any dead PIDs silently (the process crashed on its own — no point asking about it).
|
|
54
|
+
|
|
55
|
+
## Workflow
|
|
56
|
+
|
|
57
|
+
### Step 1: What Are You Testing?
|
|
58
|
+
|
|
59
|
+
Before discovering services, understand the shape of the testing so you can scope correctly. Use `AskQuestion`:
|
|
60
|
+
|
|
61
|
+
> "What are you testing locally?"
|
|
62
|
+
|
|
63
|
+
- Option 1: "A frontend feature — I need the UI and its backend dependencies running"
|
|
64
|
+
- Option 2: "A backend API — I just need the API server running"
|
|
65
|
+
- Option 3: "The full stack — everything needs to be up"
|
|
66
|
+
|
|
67
|
+
This scopes the rest of the workflow. If the user is testing a backend API, they probably don't need a frontend dev server. If they're testing a frontend feature, they need the frontend plus whatever backends it talks to. Keep this answer in mind when presenting service candidates in Step 3 — pre-check the ones that match and leave the rest unchecked.
|
|
68
|
+
|
|
69
|
+
### Step 2: Viability Check
|
|
70
|
+
|
|
71
|
+
Some services can't run on a developer's machine by design — they need production secrets, HSMs, specific certificates, or cloud-only infrastructure. Don't waste time trying to discover or start them.
|
|
72
|
+
|
|
73
|
+
**If the user already volunteered this information** in their initial message (e.g., "the payment-gateway can't run locally"), acknowledge it and skip the question — don't re-ask what they already answered.
|
|
74
|
+
|
|
75
|
+
Otherwise, use `AskQuestion`:
|
|
76
|
+
|
|
77
|
+
> "Are there any services in your stack that **can't** run locally? (e.g., needs production secrets, specific certificates, or cloud-only infra)"
|
|
78
|
+
|
|
79
|
+
- Option 1: "All my services can run locally"
|
|
80
|
+
- Option 2: "Some can't — I'll tell you which"
|
|
81
|
+
|
|
82
|
+
If the user picks option 2, collect the names. Acknowledge them and exclude from discovery.
|
|
83
|
+
|
|
84
|
+
If an excluded service is a hard dependency for the app under test, **suggest testing in a preview/staging environment instead** — the user can merge first and use `/muggle-test` in remote mode, where everything is already up and running. Frame it as an alternative, not a dead end:
|
|
85
|
+
|
|
86
|
+
> "Since **payment-gateway** can't run locally, you might get better coverage by merging and running `/muggle-test` against your preview environment — everything's wired up there. Want to continue with a partial local setup, or switch to remote testing?"
|
|
87
|
+
|
|
88
|
+
- Option 1: "Continue locally — I'll work around the missing service"
|
|
89
|
+
- Option 2: "Switch to remote — I'll merge and test on preview"
|
|
90
|
+
|
|
91
|
+
If the user chooses remote, hand off to `/muggle-test` in remote mode and exit this skill.
|
|
92
|
+
|
|
93
|
+
### Step 3: Identify Required Services & How to Start Them
|
|
94
|
+
|
|
95
|
+
Figure out which services need to be running. Start by listing folder names in the **parent directory** of the current working directory — these are the most likely candidates.
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
ls -d "$(dirname "$PWD")"/*/ | xargs -I{} basename {}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Present folder names only (not contents) as candidates. Use `AskQuestion` with `multiSelect: true`:
|
|
102
|
+
|
|
103
|
+
> "Which of these need to be running for your tests?"
|
|
104
|
+
|
|
105
|
+
List each folder name as an option. Pre-check the ones that match the testing scope from Step 1 (e.g., if testing a frontend feature, pre-check the frontend and likely backends). Always include these fixed tail options:
|
|
106
|
+
- "Just the current project (no other services needed)"
|
|
107
|
+
- "None of these — I'll tell you what I need"
|
|
108
|
+
|
|
109
|
+
If the user provides manual paths, verify they exist before continuing. If a path doesn't exist, report it and ask for correction.
|
|
110
|
+
|
|
111
|
+
**Include the current working directory as a candidate** — the user might be editing the backend but also need the frontend (a sibling) started, or vice versa.
|
|
112
|
+
|
|
113
|
+
**Immediately after the user selects services**, ask how they want to handle startup. This avoids making someone who prefers their own scripts wait through command detection before they get to say "I'll handle it."
|
|
114
|
+
|
|
115
|
+
Use `AskQuestion`:
|
|
116
|
+
|
|
117
|
+
> "How do you want to handle these?"
|
|
118
|
+
|
|
119
|
+
- Option 1: "Check what's running, start what's missing for me"
|
|
120
|
+
- Option 2: "I'll start them myself — just verify they're up when I'm done"
|
|
121
|
+
|
|
122
|
+
If the user picks **option 2**: skip Steps 4-6. Wait for them to confirm they're ready, then go straight to Step 4 (Check What's Already Running) to verify everything is listening, and report readiness (Step 7).
|
|
123
|
+
|
|
124
|
+
If the user picks **option 1**: proceed through Steps 4-7 as normal.
|
|
125
|
+
|
|
126
|
+
### Step 4: Check What's Already Running
|
|
127
|
+
|
|
128
|
+
Before offering to start anything, check what's already listening on common dev ports:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
lsof -iTCP -sTCP:LISTEN -nP 2>/dev/null | grep -E ':(3000|3001|3002|4200|5173|5174|8080|8081|8000|8888|4000|9000)'
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Cross-reference against the selected service directories. If a selected service appears to already be running (match by port or by the process's working directory), report it as ready:
|
|
135
|
+
|
|
136
|
+
> "**backend-api** is already listening on port 3001 (PID 54321) — looks good."
|
|
137
|
+
|
|
138
|
+
If **all** required services are already running, report readiness and skip straight to Step 7. No need to go through Steps 5-6.
|
|
139
|
+
|
|
140
|
+
If some are running and some aren't, acknowledge the running ones and continue to Step 5 only for the missing services. Use `AskQuestion` for any already-running service the user might want restarted:
|
|
141
|
+
- Option 1: "It's fine, keep it"
|
|
142
|
+
- Option 2: "Restart it"
|
|
143
|
+
|
|
144
|
+
For services that are already running and the user wants to keep, add them to the PID tracking file so cleanup can find them later, but mark them as `external: true` so cleanup knows not to kill them (the user started them independently).
|
|
145
|
+
|
|
146
|
+
### Step 5: Determine Start Commands
|
|
147
|
+
|
|
148
|
+
For each required service that isn't already running, figure out how to start it. Propose the command so there's a shared understanding.
|
|
149
|
+
|
|
150
|
+
Read **only** the indicator file that exists — don't read additional files.
|
|
151
|
+
|
|
152
|
+
**Detection order:**
|
|
153
|
+
|
|
154
|
+
| Indicator | Stack | Default command | What to check |
|
|
155
|
+
|:----------|:------|:----------------|:--------------|
|
|
156
|
+
| `package.json` | Node.js | `npm run dev` | Read `scripts` field: prefer `dev` > `start` > `serve` |
|
|
157
|
+
| `Makefile` | Various | `make dev` | Just check existence; propose `make dev` or `make run` |
|
|
158
|
+
| `Cargo.toml` | Rust | `cargo run` | Just check existence |
|
|
159
|
+
| `go.mod` | Go | `go run .` | Just check existence |
|
|
160
|
+
| `pyproject.toml` | Python | Check for framework | Read `[project.scripts]` or `[tool.poetry.scripts]` if present |
|
|
161
|
+
| `requirements.txt` | Python | `python app.py` | Just check existence |
|
|
162
|
+
| `docker-compose.yml` | Docker | `docker compose up` | Just check existence |
|
|
163
|
+
|
|
164
|
+
If no indicator file is found, tell the user and ask them to provide the start command manually.
|
|
165
|
+
|
|
166
|
+
**Present all proposed commands in a single summary:**
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
Service Directory Command
|
|
170
|
+
────────────────────────────────────────────────────────────────
|
|
171
|
+
backend-api ~/Github/backend-api npm run dev
|
|
172
|
+
auth-service ~/Github/auth-service go run .
|
|
173
|
+
frontend ~/Github/frontend npm run dev
|
|
174
|
+
────────────────────────────────────────────────────────────────
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Use `AskQuestion`:
|
|
178
|
+
- Option 1: "Looks good, start them"
|
|
179
|
+
- Option 2: "I need to edit some commands"
|
|
180
|
+
|
|
181
|
+
If the user needs edits, collect corrections and re-present.
|
|
182
|
+
|
|
183
|
+
### Step 6: Start Services
|
|
184
|
+
|
|
185
|
+
For each service, launch in the background:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
cd "<service-dir>" && nohup <command> > /tmp/muggle-prepare-<service-name>.log 2>&1 &
|
|
189
|
+
echo $!
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Capture the PID. Write all service entries to `/tmp/muggle-test-prepare.json`.
|
|
193
|
+
|
|
194
|
+
**Startup verification** — after a short pause (~3-5 seconds per service), check:
|
|
195
|
+
|
|
196
|
+
1. PID is alive: `kill -0 <pid> 2>/dev/null`
|
|
197
|
+
2. Port is listening (if known): `lsof -iTCP:<port> -sTCP:LISTEN -nP 2>/dev/null`
|
|
198
|
+
|
|
199
|
+
If a service's PID dies immediately, read the last 20 lines of its log and show the user:
|
|
200
|
+
|
|
201
|
+
> "**backend-api** exited right after starting. Here's the tail of its log:"
|
|
202
|
+
|
|
203
|
+
Then ask how to proceed:
|
|
204
|
+
- Option 1: "Skip it and continue with the others"
|
|
205
|
+
- Option 2: "Let me fix it — I'll re-invoke later"
|
|
206
|
+
|
|
207
|
+
**Port discovery** — if the port isn't known upfront, after the service starts, re-scan listening ports and try to identify which new port appeared. Record it in the tracking file if found. If not found within ~10 seconds, note the port as unknown — the service may take longer to boot.
|
|
208
|
+
|
|
209
|
+
### Step 7: Report Readiness
|
|
210
|
+
|
|
211
|
+
Whether you started the services or the user did, confirm that everything is listening:
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
Service PID Port Status
|
|
215
|
+
──────────────────────────────────────────────
|
|
216
|
+
backend-api 12345 3001 Running
|
|
217
|
+
auth-service 12346 8080 Running
|
|
218
|
+
frontend 12347 3000 Running
|
|
219
|
+
──────────────────────────────────────────────
|
|
220
|
+
All 3 services verified. Ready for E2E testing.
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
If you launched the services, also show:
|
|
224
|
+
```
|
|
225
|
+
Logs: /tmp/muggle-prepare-*.log
|
|
226
|
+
Cleanup: say "stop services" or re-invoke this skill.
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Cleanup
|
|
230
|
+
|
|
231
|
+
Cleanup is triggered when:
|
|
232
|
+
- The user says "stop services", "tear down", "clean up", or "I'm done testing"
|
|
233
|
+
- Another skill signals that a test run is complete
|
|
234
|
+
- This skill is re-invoked and the user chooses "tear down and start fresh"
|
|
235
|
+
|
|
236
|
+
**Cleanup steps:**
|
|
237
|
+
|
|
238
|
+
1. Read `/tmp/muggle-test-prepare.json`
|
|
239
|
+
2. Skip any services marked `external: true` (the user started them independently)
|
|
240
|
+
3. For each managed service, send `SIGTERM`: `kill <pid>`
|
|
241
|
+
4. Wait ~2 seconds, verify with `kill -0`
|
|
242
|
+
5. If still alive, `kill -9 <pid>`
|
|
243
|
+
6. Remove log files: `rm -f /tmp/muggle-prepare-*.log`
|
|
244
|
+
7. Remove the tracking file: `rm -f /tmp/muggle-test-prepare.json`
|
|
245
|
+
|
|
246
|
+
Report:
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
Stopped 3 services:
|
|
250
|
+
backend-api (PID 12345)
|
|
251
|
+
auth-service (PID 12346)
|
|
252
|
+
frontend (PID 12347)
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Integration Contract (for other skills)
|
|
256
|
+
|
|
257
|
+
When `muggle-test`, `muggle-do`, or `muggle-test-feature-local` want to check if services are ready:
|
|
258
|
+
|
|
259
|
+
1. Check if `/tmp/muggle-test-prepare.json` exists
|
|
260
|
+
2. Verify PIDs are alive with `kill -0`
|
|
261
|
+
3. If all live → services are ready, proceed to test execution
|
|
262
|
+
4. If missing or stale → invoke `muggle-test-prepare`
|
|
263
|
+
|
|
264
|
+
After a test run completes, the calling skill can invoke cleanup by re-invoking this skill with cleanup intent, or leave services running for the next run (the user chose lifecycle management, not clean-state resets).
|
|
265
|
+
|
|
266
|
+
## Guardrails
|
|
267
|
+
|
|
268
|
+
- **Verify first, offer to start second** — always check what's already running before proposing to start anything. If everything is up, just confirm readiness and move on.
|
|
269
|
+
- **The user may prefer to start services themselves** — always offer that option. Some developers have their own startup scripts, tmux layouts, or docker-compose setups they'd rather use.
|
|
270
|
+
- **Never start a process the user didn't approve** — every command is presented and confirmed before execution.
|
|
271
|
+
- **Never read file contents outside confirmed directories** — folder names are discoverable; file contents require explicit user selection.
|
|
272
|
+
- **Never leave orphan processes untracked** — every background PID goes into the tracking file.
|
|
273
|
+
- **Never kill a process the user started independently** — services marked `external: true` survive cleanup.
|
|
274
|
+
- **Never assume start commands** — always verify by checking project indicator files; always confirm with the user.
|
|
275
|
+
- **Bail early on non-viable services** — don't attempt to start something the user said can't run locally.
|
|
276
|
+
- **Idempotent** — if services are already tracked and alive, offer to keep them rather than double-starting.
|
|
@@ -9,6 +9,24 @@ A bulk maintenance skill for Muggle AI projects. It finds every test case in a p
|
|
|
9
9
|
|
|
10
10
|
Execution is **remote only** — Muggle's cloud generates the scripts in parallel against the project URL. The user's machine is not involved beyond making API calls.
|
|
11
11
|
|
|
12
|
+
## Preferences
|
|
13
|
+
|
|
14
|
+
User preferences are available in the session context (injected at session start). Look for the line starting with `Muggle Preferences` — it contains key=value pairs like `autoLogin=ask showElectronBrowser=always ...`.
|
|
15
|
+
|
|
16
|
+
If no preferences line is present, treat all preferences as `"ask"`.
|
|
17
|
+
|
|
18
|
+
When you reach a decision gated by a preference:
|
|
19
|
+
- **`always`** → proceed without asking the user
|
|
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 |
|
|
29
|
+
|
|
12
30
|
## Concept: what counts as "no active script"
|
|
13
31
|
|
|
14
32
|
In the Muggle data model, a test case carries a status that reflects whether it has a usable script attached:
|
package/dist/src-ZRUONWKV.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { buildElectronAppChecksumsUrl, buildElectronAppReleaseAssetUrl, buildElectronAppReleaseTag, calculateFileChecksum, createApiKeyWithToken, createChildLogger, deleteApiKeyData, deleteCredentials, e2e_exports as e2e, getApiKey, getApiKeyFilePath, getAuthService, getBundledElectronAppVersion, getCallerCredentials, getCallerCredentialsAsync, getChecksumForPlatform, getConfig, getCredentialsFilePath, getDataDir, getDownloadBaseUrl, getElectronAppChecksums, getElectronAppDir, getElectronAppVersion, getElectronAppVersionSource, getLocalQaTools, getLogger, getPlatformKey, getQaTools, getValidApiKeyData, getValidCredentials, hasApiKey, isElectronAppInstalled, loadApiKeyData, loadCredentials, local_exports as localQa, mcp_exports as mcp, openBrowserUrl, performLogin, performLogout, pollDeviceCode, e2e_exports as qa, resetConfig, resetLogger, saveApiKey, saveApiKeyData, saveCredentials, startDeviceCodeFlow, toolRequiresAuth, verifyFileChecksum } from './chunk-44I5ROCB.js';
|