---
name: precommit
description: Run precommit checks (lint, format, tests) on the mycelium codebase. Use when the user says /precommit or wants to check code quality before committing.
---

# Precommit Checks

Run all quality checks on the mycelium codebase. Auto-fix issues where possible.

## Steps

1. **Lint + format** — Fix lint and format issues automatically:
   ```bash
   cd fastapi-backend && uv run ruff check --fix . && uv run ruff format .
   cd mycelium-cli && uv run ruff check --fix . && uv run ruff format .
   ```

2. **Type check (ty)** — Both backend and CLI must come back clean. CI gates on this:
   ```bash
   cd fastapi-backend && uv run ty check .
   cd mycelium-cli && uv run ty check .
   ```
   Generated client (`mycelium-cli/src/mycelium_backend_client/`) is excluded via `[tool.ty.src]` since openapi-python-client templates produce diagnostics we can't fix without forking the generator. New diagnostics outside that path must be resolved before commit — don't paper over with `# ty: ignore` unless the underlying issue is a typeshed/library bug (CORSMiddleware add_middleware is the canonical example).

3. **Backend tests** — Run pytest:
   ```bash
   cd fastapi-backend && uv run pytest tests/ -x -q
   ```

4. **Frontend** — Type-check, test, and build. All three: `tsc` and `next build` between them prove the app compiles, not that it behaves, and the component suite is where the interaction bugs actually get caught.
   ```bash
   cd mycelium-frontend && npx tsc --noEmit && npx vitest run && npx next build
   ```
   `npm run lint` is `tsc --noEmit` — there's no separate ESLint pass. The suite should come back fully green; a failure that looks environmental (missing DOM API, a global the runtime shapes differently) belongs in `vitest.setup.ts` as a guarded stub next to the others, not left failing for the next person to rediscover.

5. **CLI docs** — If any CLI command files were changed (`mycelium-cli/src/mycelium/commands/`):
   - Ensure new commands have `@doc_ref` decorators
   - Run `/generate-cli-docs` to regenerate the HTML CLI reference
   - If markdown source files changed (`mycelium-cli/src/mycelium/docs/**/*.md`), also run `cd mycelium-cli && uv run python ../docs/generate_docs.py` to regenerate the docs site (`docs/index.html`, `docs/adapters.html`, `docs/reference.html`, plus `docs/search-index.js` and `docs/llms-full.txt`). `--page <start|adapters|reference>` limits what gets written; every page is still assembled, because the persistent nav and the search index span the whole site. The script reads `<!-- keep -->`-marked hand-coded sections from the existing HTML — don't delete those files between edits.

6. **Generated OpenAPI clients** — Two clients are vendored from live OpenAPI specs. CI gates on the mycelium one being current; the CFN one is regenerated by hand when we bump the image.

   **Mycelium backend → CLI client.** If any backend schemas or routes changed (`fastapi-backend/app/schemas.py`, `fastapi-backend/app/routes/`), regenerate. The backend must be running locally first.
   ```bash
   docker compose -f mycelium-cli/src/mycelium/docker/compose.yml up -d mycelium-backend
   ./scripts/gen-mycelium-client.sh
   ```
   Writes to `mycelium-client/mycelium_backend_client/` and `mycelium-cli/src/mycelium_backend_client/`. CI fails if the committed copy drifts from live `/openapi.json`.

   **CFN client.** `app/services/cfn_negotiation.py` uses the generated typed `ioc_cfn_svc_api_client` (from `fastapi-backend/cfn_swagger.json`). If the CFN image was bumped in `mycelium-cli/src/mycelium/docker/compose.yml`, refresh + regenerate: `CFN_URL=http://localhost:9002 ./scripts/gen-cfn-client.sh` (or point at the ioc-cfn-svc repo's `docs/swagger.json`), then `cd fastapi-backend && uv run ty check .`. Type errors at call sites mean the CFN contract changed. **The typecheck IS the contract test.** (`cfn_knowledge.py` stays on httpx by design: json.RawMessage payload + graph endpoints absent from swagger.)

7. **Docs consistency** — If any user-facing behavior changed (commands renamed, new features, API changes), grep for stale references and fix them in:
   - `docs/index.html` (Guide), `docs/adapters.html`, `docs/reference.html` — main docs site (3 pages, generated), plus `docs/search-index.js`
   - `docs/mycelium-dataflow.html` — scrolly presentation deck
   - `docs/demo-script.md` — live demo script
   - `README.md` — quickstart and overview
   - `mycelium-cli/src/mycelium/docs/` — built-in CLI docs
   - Adapter skills (`mycelium-cli/src/mycelium/integrations/*/assets/skills/`)

8. **Doctor sanity check** — If any file under `mycelium-cli/src/mycelium/commands/doctor.py`, `mycelium-cli/src/mycelium/commands/adapter.py`, or an adapter's shipped assets (`mycelium-cli/src/mycelium/integrations/claude_code/assets/`, `.../cursor/assets/`) was changed, run `mycelium doctor` to verify every check still passes against the current install:
   ```bash
   mycelium doctor
   ```
   All checks should be green (`✓`). If any come back as warnings (`~`) or errors (`✗`), act on them before committing — doctor is the fastest way to catch adapter-install regressions (stale manifests, drift between installed vs packaged plugin, channel config issues).

   If you added new failure modes that doctor should catch, add a new check function to `doctor.py` following the `_check_*() -> CheckResult` pattern and register it in `_run_all_checks()`. Doctor is the user's first debugging tool — new silent-failure classes should land here alongside their fix.

9. **Report** — Summarize what was fixed and any remaining issues.
