reticle doctor collapses the setup failure modes into one command. It is the first thing to run when something is wrong.
Flags
What it prints
Human-readable lines on stdout, not the JSON log. A healthy setup (rows that print only on a condition are absent):sessions line fails and the daemon’s own diagnosis is appended under the checklist. Real capture, against a daemon on a scratch port that no app had dialled, with the diagnosis wrapped for width and trimmed at the ellipsis:
The chromium line
Playwright pins one Chromium revision per version, and the daemon launches that one and no other. So the check is not “is a Chromium there” but “is this revision there”, and the three answers have three different fixes. All three captures below are real, taken by pointingPLAYWRIGHT_BROWSERS_PATH at a full root, a stale root, and an empty one.
✓ installed means the wanted revision is on disk. Nothing to do.
✓ using the installed Google Chrome (or Microsoft Edge) means the pinned build is absent and Reticle drives the browser you already have instead, through Playwright’s channel. Nothing to do: the line also names the command that adds Playwright’s own build, if you want it.
✓ using <path> (RETICLE_CHROMIUM_PATH) means you named the browser with RETICLE_CHROMIUM_PATH, so the bundled revision is not checked at all. If the path does not exist, is not a file (a directory, say), or is not executable, the line says which instead, and offers no install command, because installing would not fix a wrong path:
verify, a drive) runs the bundled Playwright’s own pinned install for you, announced on stderr so reticle mcp’s stdout stays clean. The two ✗ lines below are what you see when that has not happened yet, or failed.
✗ wrong revision means builds are installed and none of them is the wanted one. One pinned download away. The line names the revision Playwright wants, then every revision the root actually holds, then the exact command:
✗ missing means the browsers root holds no Chromium at all. It prints the full executable path it looked for, so you can see which root it searched. If that is not where your browsers live, PLAYWRIGHT_BROWSERS_PATH is what moves it:
.... The revision number and the pinned Playwright version come from the build you are running, so yours may differ from these; use the ones your own doctor prints.
The wanted revision and the root are both read back off the path Playwright itself resolves, so PLAYWRIGHT_BROWSERS_PATH and every platform default (including %LOCALAPPDATA%\ms-playwright on Windows) are honoured without this command keeping its own table of roots.
Repair with —fix
When a row has a safe repair, a plaindoctor run ends with one more line:
reticle doctor --fix prints the checks, applies the safe repairs in a fixed order, runs the checks again, and prints one line for each repair and one for each row that still fails. A repair changes only Reticle’s own state:
Each repair checks again before it acts, so a second
--fix finds nothing to do and changes nothing.
--fix never repairs a row that needs a change to your app, a process that Reticle cannot prove is its own daemon, or an action only you can do. For those rows it prints the step that the row names: for example reticle init for project, starting your agent for a stopped daemon, reticle hook install for prompts, a CSP or desktop change, or a version skew (restart the daemon when no other agent uses it).
mcp is fixed.
Exit codes
A plaindoctor always exits 0. It reports; it does not gate.
doctor --fix exits 0 only when no row fails after the repairs, and 1 otherwise.
Worked example
Deeper debugging
Reading the daemon log, and what
RETICLE_TRACE=1 adds to it.