Repository navigation
feat(settings): codeman doctor in Settings → System → Diagnostics - #536
Conversation
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Thanks a lot for this, @opticon454! It surfaces A few things before it can go in: 1. Installed CLIs show as missing under a service ( 2. Flaky browser test ( 3. Concurrent runs are unbounded ( 4. Hide the group from non-admins ( Smaller things, which I can also do at merge if you prefer:
Once 1 to 4 are in, I will take another look and merge. Thanks again, this is a really useful addition. |
…ate the group (Ark0N#536 review) - doctor probes each CLI's discovery.searchDirs when which misses and runs --version on the resolved path, so a service with a minimal PATH no longer reports installed CLIs as missing - GET /api/doctor shares one in-flight run per category - Diagnostics group hidden from non-admins in multi-user mode (_applyDoctorAdminGate) - 500 uses INTERNAL_ERROR; a killed child reports 'timed out after 30 s' - browser test blocks service workers so page.route() is reliable - wiki: Diagnostics sentence Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JrzFKEdBLwVfu6ev2ZscJS
|
Thanks for the thorough review. All four are in (db9a394):
Smaller items: the 500 now uses 🤖 Generated with Claude Code |
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JrzFKEdBLwVfu6ev2ZscJS
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JrzFKEdBLwVfu6ev2ZscJS
- The doctor now judges candidates like the run mode's resolver: the PATH hit, then each search dir, each one version-checked on its own and skipped on a mismatch (a wrong `pi`/`grok` on the PATH no longer hides the real one in a search dir). A search-dir candidate must be an absolute path to an executable regular file, so a relative dir or a file without the x bit reads as missing, as it does in the Run menu. `isExecutableRegularFile` is exported from cli-executable-resolver.ts and reused rather than copied. - Every doctor probe passes killSignal: 'SIGKILL'; a --version that ignores SIGTERM held the probe for its full runtime (15 s vs 5 s measured with a TERM-trapping script). - README no longer claims parity with the Run menu or nvm prefixes. - The Diagnostics panel marks a missing optional tool with ○, a missing required one with ✗, as the terminal doctor does. - expandSearchDir names its twin, expandHome() in cli-resolver.ts. - test/doctor-cli-json.test.ts is hermetic: temp HOME, a PATH of only `which` and `node`, and a clis.json that drops the registry's absolute search dirs, so it never runs the machine's installed agent CLIs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Merged in 1.35.0, thanks @opticon454! Running the doctor in a child process was the right call, and both review rounds came back fast. Applied on the way in (cf26853):
|
What
Surfaces
codeman doctorin the web UI: Settings → System → Diagnostics → Run checks lists which agent CLIs, tmux, Node and the optional office tools are installed on the server, with versions, paths, required/optional, and the install hint for what is missing. Backed byGET /api/doctor[?category=core|office|other].Design
checkAll) is synchronous (which+<bin> --versionper tool), andCLAUDE.mdis explicit that a sync call freezes the port while the process stays alive. So the route runscodeman doctor --jsonin a child of the same entry script (process.execPath+process.execArgv+process.argv[1], 30 s timeout) and parses the output. The CLI exits non-zero when a required tool is missing but still prints the report, so a non-zero exit with a valid report is a normal result.registerDoctorRoutes(app, runner)), so route tests never spawn anything; the default runner's parsing is tested against a fakedexecFile, and the CLI contract it depends on is tested for real.403/400/500).textContent: paths and labels come from the host.Tests
test/routes/doctor-routes.test.ts(11): envelope, category pass-through and rejection of an unknown one without running anything, runner failure, multi-user gating, and the default runner (args, non-zero exit with a report, empty/non-JSON/wrong-shape output, the child's error passed through).test/doctor-cli-json.test.ts(1): spawns the real entry script withdoctor --json --category coreand checks the report.test/doctor-settings.browser.test.ts(2, real Chromium,/api/doctorstubbed at the network layer): renders status/version/path/install hint, shows a hostile label (<img onerror>) as literal text, and shows the server's error and re-enables the button.Merge order
Rebased onto 1.34.0. Independent of my other open PRs apart from adjacent insertions in
config/test-suites.ts,docs/api-reference.md,routes/index.tsandserver.ts(route registration), which will need a trivial rebase for whichever lands second. I will do that as they merge.🤖 Generated with Claude Code
https://claude.ai/code/session_01JrzFKEdBLwVfu6ev2ZscJS