@muggleai/works 4.12.2 → 4.12.4
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-I4VLYJ7M.js → chunk-CPF6AR2I.js} +499 -147
- package/dist/{chunk-2DVZ2LYO.js → chunk-JNI7INIO.js} +2 -2
- 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/skills/_shared/dev-server-readiness.md +39 -0
- package/dist/plugin/skills/_shared/failure-mode-handling.md +19 -4
- package/dist/plugin/skills/_shared/github-cli-recipes/submitted-reviews.md +1 -0
- package/dist/plugin/skills/_shared/pr-branch-worktree.md +31 -0
- package/dist/plugin/skills/_shared/pr-followup-helpers/allow-list.md +1 -1
- package/dist/plugin/skills/muggle-feedback/ops/submit.md +1 -1
- package/dist/plugin/skills/muggle-pr-followup/contract.md +3 -2
- package/dist/plugin/skills/muggle-test/SKILL.md +7 -3
- package/dist/plugin/skills/muggle-test-feature-local/SKILL.md +6 -1
- package/dist/plugin/skills/muggle-test-prepare/SKILL.md +40 -256
- package/dist/plugin/skills/muggle-test-prepare/steps/check-running.md +31 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/env-file.md +18 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/fresh-install.md +20 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/identify-services.md +28 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/readiness-report.md +26 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/rebase-check.md +3 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/scope.md +11 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/smoke-test.md +26 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/start-commands.md +29 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/start-services.md +21 -0
- package/dist/plugin/skills/muggle-test-prepare/steps/viability-check.md +21 -0
- package/dist/release-manifest.json +4 -4
- package/dist/{src-ARTTHWNP.js → src-YR5UKLPC.js} +1 -1
- package/package.json +6 -6
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.cursor-plugin/plugin.json +1 -1
- package/plugin/skills/_shared/dev-server-readiness.md +39 -0
- package/plugin/skills/_shared/failure-mode-handling.md +19 -4
- package/plugin/skills/_shared/github-cli-recipes/submitted-reviews.md +1 -0
- package/plugin/skills/_shared/pr-branch-worktree.md +31 -0
- package/plugin/skills/_shared/pr-followup-helpers/allow-list.md +1 -1
- package/plugin/skills/muggle-feedback/ops/submit.md +1 -1
- package/plugin/skills/muggle-pr-followup/contract.md +3 -2
- package/plugin/skills/muggle-test/SKILL.md +7 -3
- package/plugin/skills/muggle-test-feature-local/SKILL.md +6 -1
- package/plugin/skills/muggle-test-prepare/SKILL.md +40 -256
- package/plugin/skills/muggle-test-prepare/steps/check-running.md +31 -0
- package/plugin/skills/muggle-test-prepare/steps/env-file.md +18 -0
- package/plugin/skills/muggle-test-prepare/steps/fresh-install.md +20 -0
- package/plugin/skills/muggle-test-prepare/steps/identify-services.md +28 -0
- package/plugin/skills/muggle-test-prepare/steps/readiness-report.md +26 -0
- package/plugin/skills/muggle-test-prepare/steps/rebase-check.md +3 -0
- package/plugin/skills/muggle-test-prepare/steps/scope.md +11 -0
- package/plugin/skills/muggle-test-prepare/steps/smoke-test.md +26 -0
- package/plugin/skills/muggle-test-prepare/steps/start-commands.md +29 -0
- package/plugin/skills/muggle-test-prepare/steps/start-services.md +21 -0
- package/plugin/skills/muggle-test-prepare/steps/viability-check.md +21 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Check what's already running
|
|
2
|
+
|
|
3
|
+
Run port detection and (when an app declares a backend URL) backend-health probe per [`../../_shared/dev-server-readiness.md`](../../_shared/dev-server-readiness.md). Cross-reference hits against selected service directories.
|
|
4
|
+
|
|
5
|
+
> "**backend-api** is already listening on port 3001 (PID 54321) — looks good."
|
|
6
|
+
|
|
7
|
+
If **all** required services are running, skip straight to [smoke-test](./smoke-test.md) — don't trust port-listening alone.
|
|
8
|
+
|
|
9
|
+
If some are running, acknowledge and continue to [start-commands](./start-commands.md) only for the missing ones. For already-running services:
|
|
10
|
+
- Option 1: "It's fine, keep it"
|
|
11
|
+
- Option 2: "Restart it"
|
|
12
|
+
|
|
13
|
+
Mark kept services as `external: true` in the tracking file so cleanup leaves them alone.
|
|
14
|
+
|
|
15
|
+
## Port already held
|
|
16
|
+
|
|
17
|
+
When the user wants a port held by a process they did **not** select (typically a stale dev server from a sibling worktree):
|
|
18
|
+
|
|
19
|
+
> "Port 3999 is held by PID 87421 (you didn't select this process). How do you want to proceed?"
|
|
20
|
+
|
|
21
|
+
- Option 1: "Use the next available port" (recommended — non-destructive)
|
|
22
|
+
- Option 2: "Force-kill PID 87421 and claim port 3999"
|
|
23
|
+
- Option 3: "Abort"
|
|
24
|
+
|
|
25
|
+
**Option 1**: probe `3999 + N` for `N = 1, 2, …` until nothing listens. Record the new port and any env file edit (`PORT=` in `.env.local` etc.). Dev server may need restart to pick up.
|
|
26
|
+
|
|
27
|
+
**Option 2 — force-kill (destructive):**
|
|
28
|
+
- **Windows PowerShell:** `Get-NetTCPConnection -LocalPort <port> -ErrorAction SilentlyContinue | ForEach-Object { try { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue } catch { } }`
|
|
29
|
+
- **POSIX:** `lsof -ti:<port> 2>/dev/null | xargs -r kill -9`
|
|
30
|
+
|
|
31
|
+
Re-verify the port is free before continuing.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Environment file sanity
|
|
2
|
+
|
|
3
|
+
The env file is **per-repo** — don't hardcode `.env.local`. Detect by scanning `package.json` `scripts/*` for `.env*` literals and known port vars (`PORT=`, `VITE_PORT=`); check framework config (`next.config.*`, `vite.config.*`).
|
|
4
|
+
|
|
5
|
+
When a dependency on an env file exists:
|
|
6
|
+
|
|
7
|
+
1. Check `<cwd>/<envfile>` exists — if yes, no-op.
|
|
8
|
+
2. If absent, `git worktree list --porcelain` and check each sibling for the same filename.
|
|
9
|
+
3. If found:
|
|
10
|
+
|
|
11
|
+
> "`<envfile>` is missing in this worktree but exists at `<sibling>/<envfile>`. Copy it before starting services?"
|
|
12
|
+
|
|
13
|
+
- Option 1: "Yes — copy from `<sibling>`"
|
|
14
|
+
- Option 2: "No — I'll provide it another way"
|
|
15
|
+
|
|
16
|
+
4. If not found anywhere, report and ask.
|
|
17
|
+
|
|
18
|
+
Skip silently when no env file is referenced.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Fresh install (clean-start default)
|
|
2
|
+
|
|
3
|
+
Detect stack by indicator file, decide if install is missing/stale, run automatically (notify, don't ask). Only opt-out is aborting the skill.
|
|
4
|
+
|
|
5
|
+
| Indicator | Stack | Stale check | Install command |
|
|
6
|
+
|:----------|:------|:------------|:----------------|
|
|
7
|
+
| `package.json` | Node | `node_modules/` missing OR `package-lock.json` newer than `node_modules/.package-lock.json` | `npm install --prefer-offline --no-audit --no-fund` |
|
|
8
|
+
| `pyproject.toml` w/ `[tool.poetry]` | Poetry | `poetry.lock` newer than `.venv/pyvenv.cfg` (or `.venv/` missing) | `poetry install --no-interaction` |
|
|
9
|
+
| `pyproject.toml` (PEP 621) + `uv.lock` | uv | `uv.lock` newer than `.venv/pyvenv.cfg` | `uv sync` |
|
|
10
|
+
| `requirements.txt` | pip | `requirements.txt` newer than `.venv/pyvenv.cfg` (or `.venv/` missing) | `pip install -r requirements.txt` |
|
|
11
|
+
| `Gemfile` | Bundler | `Gemfile.lock` newer than `vendor/bundle/` mtime | `bundle install` |
|
|
12
|
+
| `composer.json` | Composer | `composer.lock` newer than `vendor/autoload.php` | `composer install --no-interaction` |
|
|
13
|
+
| `pom.xml` | Maven | always (heavy — opt-in via `AskUserQuestion`) | `mvn -DskipTests install` |
|
|
14
|
+
| `build.gradle*` | Gradle | always (heavy — opt-in via `AskUserQuestion`) | `gradle build -x test` |
|
|
15
|
+
| `go.mod` | Go | skip — `go run`/`go build` handle deps | |
|
|
16
|
+
| `Cargo.toml` | Rust | skip — `cargo run`/`cargo build` handle deps | |
|
|
17
|
+
|
|
18
|
+
Notify one-liner: `Installing <service-name> (<stack>: <missing|stale>)…`.
|
|
19
|
+
|
|
20
|
+
**Never symlink dep dirs** (`node_modules/`, `.venv/`, `vendor/bundle/`) from a sibling worktree — webpack rewrites paths via `resolve.symlinks: true` and Python/Ruby tooling has analogous issues. Run a real per-worktree install.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Identify required services & startup mode
|
|
2
|
+
|
|
3
|
+
List folder names in the **parent directory** of the current working directory:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
ls -d "$(dirname "$PWD")"/*/ | xargs -I{} basename {}
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Present folder names only (not contents). `AskUserQuestion` with `multiSelect: true`:
|
|
10
|
+
|
|
11
|
+
> "Which of these need to be running for your tests?"
|
|
12
|
+
|
|
13
|
+
Pre-check the ones matching the testing scope from [scope](./scope.md). Always include:
|
|
14
|
+
- "Just the current project (no other services needed)"
|
|
15
|
+
- "None of these — I'll tell you what I need"
|
|
16
|
+
|
|
17
|
+
Include the current working directory as a candidate. If the user provides manual paths, verify they exist.
|
|
18
|
+
|
|
19
|
+
**Immediately after selection**, ask startup mode:
|
|
20
|
+
|
|
21
|
+
> "How do you want to handle these?"
|
|
22
|
+
|
|
23
|
+
- Option 1: "Check what's running, start what's missing for me"
|
|
24
|
+
- Option 2: "I'll start them myself — just verify they're up when I'm done"
|
|
25
|
+
|
|
26
|
+
**Option 2**: skip [start-commands](./start-commands.md), [fresh-install](./fresh-install.md), [start-services](./start-services.md). Wait for ready signal, then [check-running](./check-running.md), run [smoke-test](./smoke-test.md) against everything (the user-started case is exactly where the smoke test matters most), then [readiness-report](./readiness-report.md).
|
|
27
|
+
|
|
28
|
+
**Option 1**: proceed through the normal flow.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Final readiness report
|
|
2
|
+
|
|
3
|
+
Only after every service passes [smoke-test](./smoke-test.md) or is skipped.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
Service PID Port Status Smoke Test
|
|
7
|
+
─────────────────────────────────────────────────────────────────
|
|
8
|
+
backend-api 12345 3001 Running ✓
|
|
9
|
+
auth-service 12346 8080 Running ✓
|
|
10
|
+
frontend 12347 3000 Running ✓
|
|
11
|
+
─────────────────────────────────────────────────────────────────
|
|
12
|
+
All services verified. Ready for E2E.
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Surface skipped services so the caller knows the gap:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
Skipped: payment-gateway — HTTP 500 on /
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
If you launched the services:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Logs: /tmp/muggle-prepare-*.log
|
|
25
|
+
Cleanup: say "stop services" or re-invoke this skill.
|
|
26
|
+
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Scope (what are you testing?)
|
|
2
|
+
|
|
3
|
+
`AskUserQuestion`:
|
|
4
|
+
|
|
5
|
+
> "What are you testing locally?"
|
|
6
|
+
|
|
7
|
+
- Option 1: "A frontend feature — I need the UI and its backend dependencies running"
|
|
8
|
+
- Option 2: "A backend API — I just need the API server running"
|
|
9
|
+
- Option 3: "The full stack — everything needs to be up"
|
|
10
|
+
|
|
11
|
+
Scopes the rest of the workflow. Record under `testing_scope` in the tracking file. Use it later to pre-check matching service candidates in [identify-services](./identify-services.md).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Comprehensive smoke test
|
|
2
|
+
|
|
3
|
+
Runs for **every** service in the tracking file, including `external: true`. Port-listening is not proof a service works — a stale dev server binds and returns 200 with a webpack error overlay.
|
|
4
|
+
|
|
5
|
+
All three probes must pass:
|
|
6
|
+
|
|
7
|
+
1. **HTTP** — `GET <serviceUrl>`, 3 s timeout, accept `2xx`/`3xx` (one redirect).
|
|
8
|
+
2. **Body sniff** — match response body against broken-build markers in [`../../_shared/dev-server-readiness.md`](../../_shared/dev-server-readiness.md) → "Body sniff patterns".
|
|
9
|
+
3. **Log tail** — scan last 200 lines of `/tmp/muggle-prepare-<service-name>.log` for failure patterns after the latest ready signal. Skip for `external: true` (no log).
|
|
10
|
+
|
|
11
|
+
Use the primitives in `dev-server-readiness.md`. Don't re-implement.
|
|
12
|
+
|
|
13
|
+
## Diagnose-and-fix loop
|
|
14
|
+
|
|
15
|
+
On failure, show the concrete signal (HTTP code, sniff hit, or log line) and `AskUserQuestion`:
|
|
16
|
+
|
|
17
|
+
> "**<service-name>** isn't healthy: `<signal>`. How do you want to proceed?"
|
|
18
|
+
|
|
19
|
+
- Option 1: **Clean restart** (Recommended) — kill + [fresh-install](./fresh-install.md) + [start-services](./start-services.md) + re-run this step
|
|
20
|
+
- Option 2: **Restart only** — kill + start-services + re-run this step
|
|
21
|
+
- Option 3: **I'll fix it manually** — pause; re-run on user signal
|
|
22
|
+
- Option 4: **Skip** — append to `excluded_services` with reason, continue
|
|
23
|
+
|
|
24
|
+
Loop per service until pass or skip. Cap at **3 iterations** — then force a manual-intervention pause.
|
|
25
|
+
|
|
26
|
+
For `external: true`, only Options 3 and 4 apply.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Determine start commands
|
|
2
|
+
|
|
3
|
+
For each required service not already running, figure out how to start it. Read **only** the indicator file that exists.
|
|
4
|
+
|
|
5
|
+
| Indicator | Stack | Default command | What to check |
|
|
6
|
+
|:----------|:------|:----------------|:--------------|
|
|
7
|
+
| `package.json` | Node.js | `npm run dev` | Read `scripts`: prefer `dev` > `start` > `serve` |
|
|
8
|
+
| `Makefile` | Various | `make dev` | Existence; propose `make dev` or `make run` |
|
|
9
|
+
| `Cargo.toml` | Rust | `cargo run` | Existence |
|
|
10
|
+
| `go.mod` | Go | `go run .` | Existence |
|
|
11
|
+
| `pyproject.toml` | Python | Check for framework | Read `[project.scripts]` or `[tool.poetry.scripts]` if present |
|
|
12
|
+
| `requirements.txt` | Python | `python app.py` | Existence |
|
|
13
|
+
| `docker-compose.yml` | Docker | `docker compose up` | Existence |
|
|
14
|
+
|
|
15
|
+
If no indicator found, ask the user for the start command.
|
|
16
|
+
|
|
17
|
+
Present all commands in a single summary:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
Service Directory Command
|
|
21
|
+
────────────────────────────────────────────────────────────────
|
|
22
|
+
backend-api ~/Github/backend-api npm run dev
|
|
23
|
+
auth-service ~/Github/auth-service go run .
|
|
24
|
+
frontend ~/Github/frontend npm run dev
|
|
25
|
+
────────────────────────────────────────────────────────────────
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- Option 1: "Looks good, start them"
|
|
29
|
+
- Option 2: "I need to edit some commands"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Start services
|
|
2
|
+
|
|
3
|
+
For each service, launch in the background:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
cd "<service-dir>" && nohup <command> > /tmp/muggle-prepare-<service-name>.log 2>&1 &
|
|
7
|
+
echo $!
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Capture the PID. Write all service entries to `/tmp/muggle-test-prepare.json`.
|
|
11
|
+
|
|
12
|
+
**Startup verification** — confirm PID alive (`kill -0 <pid> 2>/dev/null`), then run the two-stage readiness probe per [`../../_shared/dev-server-readiness.md`](../../_shared/dev-server-readiness.md) against the log. Cap log-tail at 60 s. Halt on whatever surfaces.
|
|
13
|
+
|
|
14
|
+
If a PID dies immediately, show the last 20 log lines:
|
|
15
|
+
|
|
16
|
+
> "**backend-api** exited right after starting. Here's the tail of its log:"
|
|
17
|
+
|
|
18
|
+
- Option 1: "Skip it and continue with the others"
|
|
19
|
+
- Option 2: "Let me fix it — I'll re-invoke later"
|
|
20
|
+
|
|
21
|
+
**Port discovery** — if the port wasn't known upfront, re-scan listening ports after startup. Record in tracking file. If not found within ~10 s, mark port unknown.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Viability check
|
|
2
|
+
|
|
3
|
+
Some services can't run on a developer's machine by design — production secrets, HSMs, specific certificates, cloud-only infra. Don't waste time trying to start them.
|
|
4
|
+
|
|
5
|
+
If the user volunteered this in their initial message, acknowledge and skip the question. Otherwise:
|
|
6
|
+
|
|
7
|
+
> "Are there any services in your stack that **can't** run locally? (e.g., needs production secrets, specific certificates, or cloud-only infra)"
|
|
8
|
+
|
|
9
|
+
- Option 1: "All my services can run locally"
|
|
10
|
+
- Option 2: "Some can't — I'll tell you which"
|
|
11
|
+
|
|
12
|
+
If option 2, collect names and exclude from discovery.
|
|
13
|
+
|
|
14
|
+
If an excluded service is a hard dependency for the app under test, suggest remote testing:
|
|
15
|
+
|
|
16
|
+
> "Since **payment-gateway** can't run locally, you might get better coverage by merging and running `/muggle-test` against your preview environment. Want to continue with a partial local setup, or switch to remote testing?"
|
|
17
|
+
|
|
18
|
+
- Option 1: "Continue locally — I'll work around the missing service"
|
|
19
|
+
- Option 2: "Switch to remote — I'll merge and test on preview"
|
|
20
|
+
|
|
21
|
+
If remote, hand off to `/muggle-test` in remote mode and exit.
|