# Dw Doctor

> Read-only environment diagnostic for a solo-lane repo: whether the tools the hooks and skills assume are installed, and whether the guardrails and the pre-commit really fire here or are silently skipping, each gap reported with a copy-paste fix.

- Skill: `dominikwozniak/dw-doctor` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add dominikwozniak/dw-doctor`
- Raw SKILL.md: https://api.skillmd.com/api/skills/dominikwozniak/dw-doctor/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: dominikwozniak (https://skillmd.com/u/dominikwozniak)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/dominikwozniak/dw-doctor

---


# dw-doctor — read-only environment diagnostic

Confirm the machine actually has what this repo's hooks and skills assume, and that the wiring
resolves — before a missing tool silently degrades things. The sharpest case: every
`.claude/hooks/*.sh` that parses a payload opens with `command -v jq >/dev/null || exit 0` —
`bash-guard.sh`, the dispatcher every Bash guard hangs off, among them — so without `jq` the
dangerous-command block, `.env` protection, pnpm enforcement, and lint-on-edit/typecheck-on-commit hooks
**all quietly no-op** and nobody notices. Same failure class for a missing `pnpm`, a
`settings.json` pointing at a hook that isn't executable, or a typecheck hook with no `tsc` to
call.

**Read-only, and it takes no arguments:** it probes (`command -v`, `--version`) and reads files,
then reports. It never installs a tool, never edits a file, never runs the fixes it suggests —
applying them is your call.

## What it reads

It diagnoses the **current git repo** (resolved via `git rev-parse --show-toplevel`), not the
skill's own location. Checks are conditional on what the repo declares, so nothing about a stack is
assumed:

- `package.json` — the Node pin (`devEngines.runtime` first, then `engines.node`), the pnpm pin
  (`devEngines.packageManager` first, then the older `packageManager`), declared deps, and
  `scripts.typecheck` (drives the JS/TS checks).
- `tsconfig.json`, `.nvmrc` — presence informs the `tsc` check and whether the node fix hint names
  `.nvmrc` at all; a repo pinning through `devEngines.runtime` has no such file.
- `.claude/settings.json` — parsed for every wired hook command; each referenced `*.sh` is checked
  for existence, the executable bit, and **drift** against this plugin's `templates/hooks/`, since a
  stale vendored copy passes the first two while missing what the template learned since. `WARN`,
  never `FAIL` — a patched hook is a legitimate choice; a hook with no template is the repo's own.
- `.ai/work/` — the scaffold this lane runs on; its absence points at `dw-init`, and a `.ai/runs/`
  directory is flagged as the other lane's repo rather than half-checked.
- `docs/decisions/` and `CONTEXT.md` — the promotion targets `dw-land` writes into. Presence only:
  the record contract is prose `dw-land` reads while writing one, not something this skill parses.
- **`AGENTS.md` — the one always-loaded file, and the block worth the most here.** Present? Does it
  declare a `Budget:` line, is that line parseable, and is the file inside it? Is there a
  `## Task Router` with rows, and does every `docs/agents/*.md` have one? Did a `{{PLACEHOLDER}}`
  survive the render? Is `CLAUDE.md` the **symlink** to it rather than a second copy that will
  diverge? And is `scripts/check-agents-docs.mjs` there to enforce any of it.
- **The checker's opt-in size gates — the corpus ratchet, the record ceiling, the topic and term
  budgets.** Each says nothing when switched off, which is right for a gate and blinding for a
  diagnostic, so each is reported here with the line or command that turns it on. `info`, not `warn`:
  declining one is a choice, and only the layers a repo actually keeps are mentioned at all.
- **The `- **Lint command**:` / `- **Typecheck command**:` bullets**, resolved in the hooks' own
  order — `AGENTS.md`, then a legacy `CLAUDE.local.md` — and **extracted the way the hooks extract
  them**, first backticked span else the rest of the line. Reporting a command the hook would not
  actually run is the one failure mode a diagnostic cannot afford. A value of `none` reports OK: it
  is what tells the hook to skip.
- `CLAUDE.local.md` — informational only. Nothing writes it any more; where one exists it is a
  legacy fallback, not a gap.
- `.claude-plugin/marketplace.json` — only if present (a marketplace repo); a light
  plugin/version-sync glance.
- Tool presence on `PATH` via `command -v`: `git`, `jq`, `gh`, `codex`, `node`, `pnpm`, and the
  project-local `agnix` / `prettier` / `tsc` binaries. `codex` is WARN-tier and **never** FAIL — the
  loop works without it, only `dw-check`'s outside reviewer and `dw-land`'s review offer on the PR degrade —
  and the check stops at "installed": probing auth would mean a network call from a read-only
  diagnostic.
- **The `dw-solo-extras` plugin**, found by its cache directory rather than on `PATH`. It ships
  `dw-decisions`, which `dw-land`, `dw-grill` and `dw-shape` each route to "where installed" without
  being able to look — so the answer belongs here. WARN-tier like `codex`, and stopping at
  "installed": whether it is _enabled_ lives in the user's global settings, which a repo diagnostic
  does not read.

## Workflow

### 1. Run the bundled script

From anywhere inside the target repo, run the script shipped with this skill:

```
bash "<this-skill-dir>/scripts/doctor.sh"
```

`<this-skill-dir>` is the directory holding this `SKILL.md` (e.g. `skills/dw-doctor` in source, or
the installed plugin's `skills/dw-doctor`). The script resolves the repo itself, so the working
directory only needs to be somewhere inside the repo you want diagnosed.

### 2. Relay the report

The script prints grouped `OK` / `WARN` / `FAIL` lines with a one-line fix on each non-OK.
Summarize it for the user and **lead with any `FAIL`** — especially `jq` or `git`, since those gate
everything else. Surface the install commands it prints (e.g. `brew install jq`,
`corepack enable`, `pnpm install`) verbatim so they can copy-paste, but do not run them yourself.

### 3. Stop

Report and hand off. Fixing the environment is the user's action; `dw-doctor` only diagnoses. If
the report shows `.ai/runs/`, the repo runs the team lane from the other marketplace — say so
plainly instead of pointing anywhere in this one.

## Guardrails

- **Stack-adaptive.** JS/TS checks run only when `package.json` exists; `tsc` only when the repo asks
  for typechecking. The marketplace check fires only when `marketplace.json` is present.
- **Never guesses.** It reports observed state and the consequence of each gap; it doesn't infer
  intent or "fix" anything for you.

**Next:** `dw-init` if the scaffold is incomplete, else `dw-shape` for a new change or `dw-next` to
pick the active one back up.

