# Web Dev MCP Server — Implementation Plan

## 1. Goal

Build a general-purpose **Model Context Protocol (MCP) server** that gives any MCP-compatible AI agent (Cursor, Claude Desktop, etc.) a full toolkit for web development: scaffolding code, running the dev workflow (install/build/test/lint/deploy), running/managing Docker containers for containerized dev & testing, inspecting a live app in a real browser, and looking up framework/library/API docs. The generic tool layer stays framework-agnostic (Vue, Svelte, plain HTML/CSS/JS, etc.), with **first-class, dedicated support for Laravel and CodeIgniter (PHP backends) and React (JS/TS frontend)** — including combined setups (e.g. Laravel/CodeIgniter API backend + React frontend).

- **Framework detection & adapters:** the server auto-detects the project type (`composer.json` + `artisan` → Laravel; `spark` CLI + `app/Config` → CodeIgniter 4; `package.json` with `react` dependency → React/Vite/CRA/Next) and exposes both generic tools (dispatched through the right adapter) and framework-specific tools (`artisan_*`/`spark_*`, React component/hook generators).

- **Language/runtime:** Node.js + TypeScript
- **Transports:** stdio (local, for Cursor/Claude Desktop) **and** HTTP/SSE (Streamable HTTP) for remote/shared use
- **SDK:** `@modelcontextprotocol/sdk` (official TypeScript SDK)

## 2. High-Level Architecture

```
web-dev-mcp/
├── src/
│   ├── server.ts              # MCP server bootstrap, tool/resource registration
│   ├── transports/
│   │   ├── stdio.ts           # stdio transport entrypoint (bin)
│   │   └── http.ts            # Streamable HTTP/SSE transport (Express)
│   ├── tools/
│   │   ├── scaffold/          # project & code generation tools
│   │   ├── workflow/          # install/build/test/lint/run/deploy
│   │   ├── browser/           # Playwright-backed inspection tools
│   │   ├── docker/            # Docker image/container tools
│   │   ├── laravel/           # artisan/composer-backed Laravel tools
│   │   ├── codeigniter/       # spark/composer-backed CodeIgniter tools
│   │   ├── react/             # React component/hook/route generators
│   │   ├── docs/              # docs/package lookup tools
│   │   └── fs/                # safe file read/write/search helpers
│   ├── resources/             # MCP resources (e.g. exposing project files, logs)
│   ├── prompts/                # reusable prompt templates (e.g. "new component")
│   ├── lib/
│   │   ├── processManager.ts  # tracks long-running child processes (dev servers)
│   │   ├── containerManager.ts # tracks Docker containers started by the server
│   │   ├── sandbox.ts         # path/command allow-listing & workspace confinement
│   │   ├── frameworks/
│   │   │   ├── types.ts       # FrameworkAdapter interface
│   │   │   ├── detect.ts      # inspects the workspace, returns detected framework(s)
│   │   │   ├── laravel.ts     # Laravel adapter (composer, artisan, phpunit/pest)
│   │   │   ├── codeigniter.ts # CodeIgniter adapter (composer, spark CLI, phpunit)
│   │   │   ├── react.ts       # React adapter (vite/CRA/Next-aware, npm/pnpm/yarn)
│   │   │   └── generic.ts     # fallback adapter for unrecognized projects
│   │   └── logger.ts
│   └── config.ts              # env vars, workspace root, allow-lists
├── test/
├── package.json
├── tsconfig.json
├── Dockerfile
└── README.md
```

Core design principles:

- **Workspace-scoped**: every tool operates relative to a configured project root; no path may escape it (prevent path traversal).
- **Stateless tool calls, stateful process registry**: dev servers/watchers started by a tool persist in an in-memory `processManager` keyed by an id returned to the agent, so the agent can `logs`/`stop` them later.
- **Composable, small tools** rather than a few "do everything" mega-tools, so the agent can chain them and results stay predictable.
- **Adapter pattern for frameworks**: generic tools (`run_install`, `start_dev_server`, `run_tests`, `run_lint`, `build_project`) delegate to a `FrameworkAdapter` resolved via `detect.ts`. `LaravelAdapter`, `CodeIgniterAdapter`, and `ReactAdapter` are first-class, purpose-built implementations; anything else falls back to `GenericAdapter` (plain npm-script/Makefile heuristics). A project can have **two active adapters at once** (e.g. Laravel or CodeIgniter API + separate React SPA, or Laravel + Inertia/React in `resources/js`), in which case tools accept a `target: "backend" | "frontend"` argument to disambiguate. Laravel and CodeIgniter share a common `PhpFrameworkAdapter` base (Composer install/require, PHPUnit test running) and each override the CLI-specific bits (`artisan` vs `spark`).

## 3. Tool Catalog

### 3.1 Scaffolding & Code Generation
- `scaffold_project` — create a new project from a template: `laravel` (`composer create-project laravel/laravel`), `codeigniter` (`composer create-project codeigniter4/appstarter`), `laravel-react`/`codeigniter-react` (PHP API backend + a separate `vite-react` frontend in a sibling folder, or Laravel + Inertia/React starter kit), `vite-react`, `vite-vue`, `next`, `express-api`, `static-html`, etc.
- `generate_component` — generic UI component generator for non-React frameworks (Vue SFC, Svelte, etc.); for React projects this delegates to `generate_react_component` (§3.7) so React gets its richer, convention-aware generator.
- `generate_api_route` — scaffold a backend route/handler for the detected framework (Laravel route + controller, CodeIgniter route + controller via `spark make:controller`, Next.js API route, Express router, Fastify, etc.).
- `add_dependency` — add/remove a dependency, auto-detecting npm/pnpm/yarn (`package.json`) vs. Composer (`composer.json`) from lockfiles/manifest presence; for combined projects takes an explicit `ecosystem: "npm" | "composer"` argument.

### 3.2 Dev Workflow
- `detect_framework` — inspect the workspace and return the detected adapter(s) (`laravel`, `codeigniter`, `react`, a combination like `laravel+react`, or `generic`) plus key metadata (PHP/Composer version, Node/package-manager, Vite/CRA/Next/Inertia presence).
- `run_install` — install dependencies for the detected project(s): `composer install` for Laravel/CodeIgniter, `npm`/`pnpm`/`yarn`/`bun install` for React; runs **both** when a project has `composer.json` and `package.json` side by side.
- `run_script` — run a `package.json` script (e.g. `dev`, `build`, `test`) as a tracked background or foreground process.
- `start_dev_server` — start the dev server, wait for the "ready" URL/port, return the URL + process id. For Laravel: `php artisan serve` (or Laravel Sail via `docker_compose_up`). For CodeIgniter: `php spark serve`. For React: the framework's own dev server (Vite/CRA/Next).
- `stop_process` / `get_process_logs` — manage previously started long-running processes.
- `run_lint` / `run_format` — run ESLint/Prettier for React, Laravel Pint/PHP-CS-Fixer for Laravel, or PHP_CodeSniffer/PHP-CS-Fixer for CodeIgniter (whichever is configured), and return structured diagnostics.
- `run_tests` — run the test runner: Vitest/Jest/Playwright for React, PHPUnit/Pest for Laravel, PHPUnit (with CIUnit test case support) for CodeIgniter; returns parsed pass/fail results either way, with a `target` argument for combined projects.
- `build_project` — production build, surfacing build errors/warnings (JS bundle build for React; `composer install --no-dev --optimize-autoloader` plus `artisan config:cache`/`route:cache`/`view:cache` for Laravel, or CodeIgniter's equivalent config/route caching where applicable).
- `deploy_project` — optional pluggable deploy step (Vercel/Netlify CLI for React, Forge/Envoyer/custom script for Laravel, or a generic PHP-hosting/rsync script for CodeIgniter) behind explicit opt-in config.

### 3.3 Browser Preview & Inspection (Playwright-backed)
- `browser_navigate` — open a URL (e.g. the local dev server) in a headless/headed browser session.
- `browser_screenshot` — capture a screenshot (full page or element selector) for visual verification.
- `browser_get_console_logs` — return console/network errors captured since navigation.
- `browser_inspect_dom` — query the DOM (selector → outerHTML/text/computed styles) for a given page.
- `browser_click` / `browser_fill` / `browser_eval` — minimal interaction primitives for smoke-testing UI flows.

### 3.4 Docker (Container Management)
- `docker_build_image` — build an image from a Dockerfile in the workspace (`docker build`), streaming build output back to the agent.
- `docker_run_container` — run a container from an image (a locally built one, or an allow-listed base image like `node`, `nginx`, `postgres`), with port mapping, env vars, and volume mounts restricted to `WORKSPACE_ROOT`; returns a container id.
- `docker_list_containers` — list containers started by this server (id, image, status, ports).
- `docker_get_container_logs` — tail logs from a running/stopped container.
- `docker_exec` — run a one-off command inside a running container (e.g. `npm test` inside the container) and return stdout/stderr.
- `docker_stop_container` / `docker_remove_container` — stop/remove a previously started container.
- `docker_compose_up` / `docker_compose_down` — optional: bring up/down a `docker-compose.yml`-defined stack for multi-service local dev (app + DB + cache, etc.).

Use case: let the agent validate that the app builds and runs correctly in a clean containerized environment (not just the host machine), or spin up dependent services (Postgres, Redis) for local development/testing. Also doubles as the runtime for **Laravel Sail** — `docker_compose_up` on a Sail-generated `docker-compose.yml` gives Laravel projects PHP/MySQL/Redis without any local PHP install.

### 3.5 Laravel Tools (PHP backend)
- `artisan` — run a whitelisted `php artisan` subcommand and return stdout/stderr; allow-listed commands include `make:controller`, `make:model`, `make:migration`, `make:seeder`, `make:factory`, `make:request`, `make:resource`, `make:middleware`, `migrate`, `migrate:rollback`, `migrate:fresh` (requires `confirm: true`), `db:seed`, `route:list`, `config:clear`, `cache:clear`, `queue:work` (tracked as a background process like a dev server).
- `generate_laravel_resource` — one-shot scaffold of a full resource (model + migration + factory + seeder + `apiResource`/`resource` controller) for a given name, wrapping the relevant `artisan make:*` calls and wiring the route.
- `composer_require` / `composer_remove` — add/remove a Composer dependency (mirrors `add_dependency` but for PHP packages).
- `run_phpunit` / `run_pest` — run the Laravel test suite (auto-picked based on which is configured in `composer.json`/`phpunit.xml`), returning parsed pass/fail results.
- `laravel_tinker_eval` — evaluate a short PHP expression/snippet via `artisan tinker --execute` for quick data/model inspection (read-only by convention; write operations require `confirm: true`).

### 3.6 CodeIgniter Tools (PHP backend)
- `spark` — run a whitelisted `php spark` subcommand and return stdout/stderr; allow-listed commands include `make:controller`, `make:model`, `make:migration`, `make:seeder`, `make:entity`, `make:filter`, `make:command`, `make:validation`, `migrate`, `migrate:rollback`, `migrate:refresh` (requires `confirm: true`), `db:seed`, `routes` (list routes), `cache:clear`.
- `generate_codeigniter_resource` — one-shot scaffold of a full resource (model + migration + seeder + `ResourceController`) for a given name, wrapping the relevant `spark make:*` calls and wiring the route in `app/Config/Routes.php`.
- `run_codeigniter_tests` — thin wrapper over `run_tests` for CodeIgniter's PHPUnit-based test suite (`CIUnitTestCase`), returning parsed pass/fail results.

CodeIgniter shares `composer_require`/`composer_remove` (§3.5) and `search_package_docs`/`get_package_info` (§3.7) with Laravel, since both are Composer-based PHP frameworks — only the CLI (`spark` vs `artisan`) and generated file conventions differ.

### 3.7 React Tools (JS/TS frontend)
- `generate_react_component` — scaffold a function component (TSX/JSX, matching the project's existing TS/JS + styling convention — CSS Modules/Tailwind/styled-components) with an optional colocated test file (React Testing Library) and Storybook story.
- `generate_react_hook` — scaffold a custom hook file (`useXyz.ts`) plus a matching test.
- `add_react_route` — add a route entry for the detected router (`react-router`, Next.js App/Pages Router file conventions, or TanStack Router).
- `run_react_tests` — thin wrapper over `run_tests` specialized to parse Jest/Vitest + React Testing Library output (e.g. surfacing which assertions/queries failed).
- `analyze_react_component` — static scan of a component file for common issues (missing `key` in lists, hook-rule violations, unused props) as a fast pre-check before/instead of a full lint run.

### 3.8 Docs & Package Lookup
- `search_package_docs` — fetch README/docs for an npm **or Composer/Packagist** package to ground the agent in the actual installed version's API.
- `search_mdn` — look up a web platform API on MDN.
- `search_laravel_docs` — look up a topic in the Laravel documentation, version-matched to the project's `laravel/framework` constraint in `composer.json`.
- `search_codeigniter_docs` — look up a topic in the CodeIgniter 4 user guide, version-matched to the project's `codeigniter4/framework` constraint in `composer.json`.
- `get_package_info` — installed version, available scripts/artisan/spark commands, and key deps from `package.json`/`composer.json` (whichever applies).

### 3.9 Filesystem Helpers (sandboxed to workspace root)
- `read_file` / `write_file` / `list_dir` / `search_code` — thin, sandboxed wrappers (useful when this server is used standalone, without an IDE's native file tools).

### 3.10 Resources & Prompts
- Resource: `workspace://project.json` — exposes detected project metadata (framework/adapter(s), package manager, scripts, PHP/Node versions) so the agent doesn't need a tool round-trip.
- Resource: `workspace://logs/{processId}` — live log tail for a running process.
- Resource: `workspace://containers/{containerId}/logs` — live log tail for a running container.
- Prompt: `new-feature` — a template prompt guiding the agent through scaffold → implement → test → verify-in-browser.
- Prompt: `new-laravel-resource` — guides the agent through `generate_laravel_resource` → migrate → write feature test → verify via `route:list`/tinker.
- Prompt: `new-codeigniter-resource` — guides the agent through `generate_codeigniter_resource` → migrate → write a PHPUnit test → verify via `spark routes`.
- Prompt: `new-react-component` — guides the agent through `generate_react_component` → wire into a route/page → verify via browser screenshot.

## 4. Transport Design

- **stdio**: default entrypoint (`bin/web-dev-mcp`), used when launched by Cursor/Claude Desktop via their MCP config (`command` + `args`). No auth needed (local process).
- **HTTP/SSE (Streamable HTTP)**: `src/transports/http.ts` runs an Express app exposing the MCP Streamable HTTP endpoint, so the same tool implementations can be reused remotely (e.g. a shared team server, or containerized in CI). Add a lightweight bearer-token auth middleware for this mode since it's network-reachable.
- Both transports share the same `createServer()` factory from `src/server.ts` — only the transport wiring differs.

## 5. Safety & Sandboxing

- All filesystem/tool paths resolved against a configured `WORKSPACE_ROOT` and rejected if they resolve outside it.
- Shell/process execution restricted to an allow-list of known package-manager/tool binaries (npm, pnpm, yarn, node, npx, git, php, composer, artisan-via-php, spark-via-php) — no arbitrary shell strings from the model.
- `artisan`, `spark`, and `composer_require`/`composer_remove` further restrict *which subcommands* may run via their own allow-lists (see §3.5/§3.6); anything destructive (`migrate:fresh`, `migrate:reset`, `migrate:refresh`, `db:wipe`) requires `confirm: true`.
- Long-running processes (dev servers) capped with idle/max-lifetime timeouts and a max concurrent count.
- Destructive operations (`deploy_project`, dependency removal, `git` write ops) require an explicit `confirm: true` argument in the tool schema, so the agent must deliberately opt in.
- HTTP transport requires an auth token env var (`MCP_HTTP_TOKEN`); refuses to bind to non-localhost without it set.
- **Docker-specific guardrails:**
  - Volume mounts are restricted to paths inside `WORKSPACE_ROOT` (read-write) — no mounting of arbitrary host paths.
  - `docker_run_container` rejects `--privileged`, host network mode, and host PID/IPC namespace sharing.
  - Non-locally-built images are restricted to a configurable allow-list (e.g. `node`, `nginx`, `postgres`, `redis`) to reduce supply-chain risk; running an arbitrary/unlisted image requires `confirm: true`.
  - Default CPU/memory limits applied to every container unless overridden; a max-concurrent-container cap is enforced.
  - All containers started by the server are tracked in `containerManager` and force-stopped/removed on server shutdown.
  - Tool calls fail fast with a clear error if the Docker daemon isn't running/reachable, rather than hanging.

## 6. Tech Stack

| Concern | Choice |
|---|---|
| MCP SDK | `@modelcontextprotocol/sdk` |
| Language | TypeScript (strict mode), compiled to ESM |
| HTTP server | Express (for the HTTP/SSE transport) |
| Browser automation | Playwright |
| Container management | `dockerode` (Docker Engine API client) — falls back to a clear error if the Docker daemon/socket isn't available |
| Process management | `execa` (child process handling) |
| Schema validation | `zod` (tool input schemas) |
| Testing | Vitest |
| Linting/formatting | ESLint + Prettier |
| Packaging | npm package with a `bin` entry; optional Docker image for the HTTP mode |

> **Prerequisite for Docker tools:** Docker Engine (Docker Desktop or `dockerd`) must be installed and running on the host; the server talks to it via the local Docker socket/named pipe. This is a runtime dependency of the *tools*, not of the MCP server process itself.
>
> **Prerequisite for Laravel/CodeIgniter tools:** PHP (matching the project's `composer.json` constraint) and Composer must be on `PATH`, **or** the project uses Laravel Sail/a `docker-compose.yml` and all `artisan`/`spark`/`composer_*`/test calls are transparently routed through `docker_exec` into the app container instead of the host shell. The adapter picks whichever is available at `detect_framework` time. CodeIgniter has no Sail-equivalent bundled, but the same Docker routing applies if the project ships its own `docker-compose.yml`.
>
> **Prerequisite for React tools:** none beyond Node.js — React itself is just an npm dependency, so the React adapter reuses the same Node/npm/pnpm/yarn tooling as the generic JS workflow tools, with Vite/CRA/Next-specific conventions layered on top.

## 7. Implementation Milestones

1. **Bootstrap** — repo scaffold, `package.json`, TS config, MCP server skeleton that registers zero tools and runs over stdio; verify it connects in Cursor.
2. **Framework adapter foundation** — `FrameworkAdapter` interface, shared `PhpFrameworkAdapter` base, `detect.ts` (Laravel/CodeIgniter/React/generic detection), `GenericAdapter`, `ReactAdapter`, `LaravelAdapter`, `CodeIgniterAdapter` skeletons, and `detect_framework` tool.
3. **Core workflow tools** — `run_install`, `run_script`, `start_dev_server`, `stop_process`, `get_process_logs`, `run_lint`, `run_tests`, `build_project`, all dispatched through the resolved adapter(s). Includes the `processManager` and sandbox path/command guards.
4. **Scaffolding tools** — `scaffold_project` (incl. `laravel`/`codeigniter`/`laravel-react`/`codeigniter-react` templates), `generate_component`, `generate_api_route`, `add_dependency`.
5. **Laravel tools** — `artisan` (with its subcommand allow-list), `generate_laravel_resource`, `composer_require`/`composer_remove`, `run_phpunit`/`run_pest`, `laravel_tinker_eval`.
6. **CodeIgniter tools** — `spark` (with its subcommand allow-list), `generate_codeigniter_resource`, `run_codeigniter_tests` (reusing `composer_require`/`composer_remove` from the Laravel milestone via the shared `PhpFrameworkAdapter` base).
7. **React tools** — `generate_react_component`, `generate_react_hook`, `add_react_route`, `run_react_tests`, `analyze_react_component`.
8. **Browser tools** — integrate Playwright, implement `browser_navigate`, `browser_screenshot`, `browser_get_console_logs`, `browser_inspect_dom`, interaction primitives.
9. **Docker tools** — integrate `dockerode`, implement `containerManager`, `docker_build_image`, `docker_run_container`, `docker_list_containers`, `docker_get_container_logs`, `docker_exec`, `docker_stop_container`/`docker_remove_container`, and `docker_compose_up`/`docker_compose_down` (incl. Laravel Sail routing); enforce the Docker-specific guardrails from §5.
10. **Docs/package lookup tools** — `search_package_docs`, `search_mdn`, `search_laravel_docs`, `search_codeigniter_docs`, `get_package_info`.
11. **Resources & prompts** — project metadata resource, process/container log-tail resources, `new-feature`/`new-laravel-resource`/`new-codeigniter-resource`/`new-react-component` prompt templates.
12. **HTTP/SSE transport** — Express wiring, auth token middleware, containerization (Dockerfile).
13. **Hardening & tests** — Vitest suite per tool (mocking child processes/Playwright/dockerode/artisan/spark calls), confirm-flag enforcement tests, path-traversal tests, Docker guardrail tests, Laravel/CodeIgniter subcommand allow-list tests.
14. **Docs & distribution** — README with Cursor/Claude Desktop config snippets, publish as an npm package (`npx web-dev-mcp`).

## 8. Example Cursor MCP Config (stdio mode, post-implementation)

```json
{
  "mcpServers": {
    "web-dev": {
      "command": "npx",
      "args": ["-y", "web-dev-mcp"],
      "env": { "WORKSPACE_ROOT": "${workspaceFolder}" }
    }
  }
}
```

## 9. Post-v1 Enhancements

### 9.0 Goal

Extend `web-dev-mcp` beyond v1 without breaking existing tools/adapters. Work ships in phased releases **v1.1–v1.5**. Each phase adds tools that reuse the existing sandbox, `processManager`, `FrameworkAdapter`, and `confirm: true` patterns.

### 9.1 Architecture deltas

- **New `FrameworkKind` values** (v1.4): `vue`, `nuxt`, `django`, `rails`, `symfony`.
- **Monorepo model** (v1.3): `DetectedWorkspace { root, packages: DetectedPackage[] }` alongside today’s `DetectedProject`; workflow tools gain an optional `package` / scoped `cwd` still confined to `WORKSPACE_ROOT`.
- **Screenshot baseline store** (v1.1): PNGs under `.web-dev-mcp/baselines/{name}.png`, resolved via sandbox helpers.
- **Audit binary allow-list** (v1.1): `lighthouse` (and `npx`) for performance audits.
- **Sail-aware Laravel** (v1.5): when `laravel/sail` + compose file exist, prefer Sail/`docker compose` for `devCommand`.

### 9.2 Tool catalog — v1.1 Agent productivity

| Tool | Behavior |
|------|----------|
| `git_status` | `git status --porcelain=v1` + branch + ahead/behind; read-only |
| `git_diff` | staged/unstaged/file-scoped diff; truncated via `maxToolOutputChars` |
| `git_log` | recent commits (`-n`, optional path); read-only |
| `git_branch` | list or create branch (`create` requires `confirm: true`) |
| `git_commit` | stage workspace-only paths + commit message; **`confirm: true`**; no amend/force |
| `browser_screenshot_baseline` | save current page/element PNG under `.web-dev-mcp/baselines/{name}.png` |
| `browser_visual_diff` | compare live screenshot vs baseline (pixelmatch); return diff PNG + mismatch % |
| `lighthouse_audit` | run Lighthouse headless against a URL; return category scores + top opportunities |

### 9.3 Tool catalog — v1.2 Framework depth

**Next.js** (still `kind: 'react'`): enrich `describe()` with `router` / `rsc`; `generate_next_page` / `generate_next_layout`; `clientComponent` on generators; RSC-aware `analyze_react_component`.

**Laravel:** `generate_eloquent_relation`; `generate_filament_resource` / `generate_nova_resource` (detect package or hint install); expanded artisan allow-list (`queue:*`, `reverb:start` as background); `laravel_queue_status`.

**CodeIgniter:** `generate_codeigniter_shield_auth` (`confirm` + package detect); versioned `ResourceController` options on resource generator; `spark_discover` (filtered `php spark list`).

### 9.4 Tool catalog — v1.3 Platform

| Tool / change | Behavior |
|---------------|----------|
| `detect_workspace` / enhanced `detect_framework` | Scan `apps/*`, `packages/*`, composer paths; list packages + adapters |
| `package` / scoped `cwd` on workflow tools | Scope install/dev/test/build to one package root |
| `generate_dockerfile` | Emit stack-aware Dockerfile templates |
| `generate_compose` | Emit `docker-compose.yml` (app + db + redis presets) |
| `generate_sail` | Wrap `php artisan sail:install` when Laravel detected |
| `docker_push_image` | Push local/allow-listed image; **`confirm: true`**; credentials via env |
| `deploy_project` | Optional `registryPush` after build; keep script + confirm |

### 9.5 Tool catalog — v1.4 New adapters

- Detect Vue (`vue` / `.vue` + Vite) and Nuxt (`nuxt` / `nuxt.config.*`); adapters implement `FrameworkAdapter`.
- Wire SFC-aware `generate_component`; reuse existing `vite-vue` scaffold template.
- Django / Rails / Symfony: detection + install/dev/test first; deeper generators later.

### 9.6 Tool catalog — v1.5 Polish

| Tool / change | Behavior |
|---------------|----------|
| Laravel Sail `devCommand` | When `laravel/sail` + compose file exist, `start_dev_server` runs `vendor/bin/sail up` (else `docker compose up`) |
| `git_diff_summarize` | Read-only `git diff --numstat` summary: per-file + total insertions/deletions |
| `lighthouse_audit` (richer) | Returns category details, cross-category opportunities, `failingByCategory` |
| `visual-diff-ci` prompt | Baseline create / visual-diff / threshold pass-fail CI helper |
| `generate_django_resource` | File stubs: models/views/urls/admin for a Django app |
| `generate_rails_resource` | File stubs: model + controller + optional routes.rb wire |
| `generate_symfony_resource` | File stubs: Entity + Repository + Controller |

### 9.7 Safety (all post-v1 phases)

- Workspace path confinement for every file/baseline/git path argument.
- Binary allow-list only; no arbitrary shell strings.
- Destructive / write ops (`git_commit`, branch create, `docker_push_image`, Shield install, deploy) require `confirm: true`.
- Never `git push --force`; never mount the Docker socket.
- No secrets in tool args — registry auth via environment only.

### 9.8 Milestones

1. **v1.1** — Git helpers, screenshot baselines, visual diff, Lighthouse audit (+ tests/docs).
2. **v1.2** — Next.js App Router depth; Laravel Eloquent/Filament/Nova/queue; CodeIgniter Shield/versioning/`spark_discover`.
3. **v1.3** — Monorepo detection/scoping; Dockerfile/compose/Sail generators; `docker_push_image`.
4. **v1.4** — Vue/Nuxt adapters (+ Django/Rails/Symfony detection stubs or full adapters).
5. **v1.5** — Sail-default dev, polish prompts/summaries, remaining framework generators.
