| name | muggle-test-prepare |
| model | opus |
| 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. |
Muggle Test Prepare
Telemetry first step: see _shared/telemetry-emit.md. Use skillName: "muggle-test-prepare".
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.
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.
Privacy Boundary
This skill touches the user's local machine — processes, ports, directories outside the current repo. Every action is explicit and confirmed.
- Folder names are public. You may list directory names in a parent folder to discover sibling services.
- 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.
- Never traverse upward more than one level from the current working directory to list folders.
PID Tracking
All launched processes are tracked in /tmp/muggle-test-prepare.json:
{
"session_started": "2025-01-15T10:30:00Z",
"testing_scope": "frontend",
"excluded_services": [
{"name": "payment-gateway", "reason": "Needs production certificates"}
],
"services": [
{
"name": "backend-api",
"dir": "/Users/user/Github/backend-api",
"command": "npm run dev",
"pid": 12345,
"port": 3001,
"log": "/tmp/muggle-prepare-backend-api.log"
}
]
}
testing_scope records what the user is testing (from scope). excluded_services records services the user said can't run locally (from viability-check).
This file is ephemeral runtime state, not the saved recipe. The durable plan lives at <repo>/.muggle-ai/prepare-plan.json (or the parent-dir-keyed entry in ~/.muggle-ai/prepare-plans.json) and is consulted in reuse-plan before any other stage. The two files never merge.
On every invocation, check this file first. If it exists with live PIDs (verify with kill -0), AskUserQuestion:
- Option 1: "Keep them running — skip to testing"
- Option 2: "Tear down and start fresh"
- Option 3: "Add more services to the running set"
Prune dead PIDs silently.
Preferences
Gates run per preference-gates/README.md.
| Preference | Gates |
|---|
autoRebase | rebase-check — rebase onto origin/<default> before starting dev servers |
reusePreparePlan | reuse-plan — reuse the saved prepare plan for this stack, or rediscover |
autoSelectLocalHost | check-running — reuse the recorded dev-server URL silently, or confirm it each run |
Workflow
Run the stages in this order. The sequence number is display-only — it lives only in this table for at-a-glance ordering; detail files and cross-references use slugs. Each row links to its detail file; read the file when you reach the stage.
Cleanup
Triggered when the user says "stop services", "tear down", "clean up", "I'm done testing", another skill signals run complete, or this skill is re-invoked with "tear down and start fresh".
- Read
/tmp/muggle-test-prepare.json
- Skip services marked
external: true
- For each managed service:
kill <pid> (SIGTERM)
- Wait ~2 s, verify with
kill -0
- If still alive:
kill -9 <pid>
rm -f /tmp/muggle-prepare-*.log
rm -f /tmp/muggle-test-prepare.json
Report:
Stopped 3 services:
backend-api (PID 12345)
auth-service (PID 12346)
frontend (PID 12347)
Integration Contract (for other skills)
muggle-test-feature-local, muggle-do, and local-mode muggle-test MUST invoke this skill before any workflow step. Idempotent — fast exit when healthy. Treat success as short-lived; re-invoke if more than a few minutes pass before testing. Never bypass on "the user knows their stack is up" — that assumption is why this skill exists.
After a test run, the caller can re-invoke for cleanup or leave services running for the next run.
Guardrails
- Never invent or default a host/port — the dev-server URL is a recorded value, not a guess. Resolve it from
<repo>/.muggle-ai/last-host.json (the autoSelectLocalHost cache) before probing ports; a framework default like :3000 is never a fallback. See check-running.
- No silent auto-selection without a gate — when no preference authorizes a silent choice (host, restart, kill), confirm with the user. A gate set to
always is the only license to skip the question; absent that, ask.
- Verify first, offer to start second — check what's already running before proposing to start anything.
- The user may prefer to start services themselves — always offer that option.
- Never start a process the user didn't approve.
- Never read file contents outside confirmed directories — folder names are discoverable; file contents require explicit user selection.
- Never leave orphan processes untracked — every background PID goes into the tracking file.
- Never kill a process the user started independently —
external: true survives cleanup.
- Never assume start commands — verify via indicator file; confirm with user.
- Bail early on non-viable services — don't start what can't run locally.
- Idempotent — already-tracked alive services are kept; smoke-test still runs against them.
- Port-listening is never enough — smoke-test (HTTP + body sniff + log tail) is mandatory before the final report.
- Clean Restart is the recommended fix — first option in the smoke-test diagnose-and-fix loop; lint/build/missing-deps issues need nuke-and-reinstall.
- Fresh install is automatic — fresh-install notifies, doesn't ask.