13 KiB
Logseq CLI Doctor Command Implementation Plan
Goal: Add a doctor command that verifies logseq-cli runtime availability before normal command execution, including db-worker-node.js existence and data-dir read and write readiness.
Architecture: Add a dedicated logseq.cli.command.doctor namespace and wire it into the existing parse-args -> build-action -> execute pipeline in logseq.cli.commands.
Architecture: Reuse existing helpers in logseq.cli.data-dir and logseq.cli.server for permission checks and daemon liveness probes, then return one structured diagnostics report.
Tech Stack: ClojureScript, babashka.cli command table, Node.js fs and path, Promesa, existing CLI formatter and test harness.
Related: Builds on docs/agent-guide/019-logseq-cli-data-dir-permissions.md.
Related: Relates to docs/agent-guide/015-logseq-cli-db-worker-node-housekeeping.md.
Related: Relates to docs/agent-guide/017-logseq-cli-db-worker-node-housekeeping-2.md.
Related: Relates to docs/agent-guide/030-logseq-cli-db-graph-default-dir-locking.md.
Problem statement
The current CLI fails only when a concrete command touches startup paths, so users discover environment problems late.
We need a fast explicit health command that confirms whether logseq-cli can run reliably in the current machine context.
The minimum required checks are the presence of db-worker-node.js and read and write access for data-dir.
Note: dist/db-worker-node.js is a thin entry wrapper that loads static/db-worker-node.js. Doctor should validate the actual runtime target in static/ rather than only the dist/ wrapper.
We should also surface practical runtime risks already modeled by current code, especially stale or unready db-worker instances discovered from lock files and health endpoints.
This plan keeps scope to diagnostics and does not change daemon lifecycle semantics, lock protocol, or graph migration behavior.
Testing Plan
I will follow @test-driven-development and write all failing tests before adding implementation behavior.
I will add parser and action-dispatch tests for doctor in commands_test so command discovery and help output are guarded.
I will add dedicated doctor command tests that cover success, missing script file, and data-dir permission failure behavior.
I will add format tests to ensure human and machine-readable output for doctor are stable and useful.
I will run focused test namespaces first to validate RED and GREEN transitions, then run the full lint and test suite.
NOTE: I will write all tests before I add any implementation behavior.
Current behavior map
| Area | Current implementation | Required change |
|---|---|---|
| Runtime script path | spawn-server! in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/server.cljs starts ../dist/db-worker-node.js, which delegates to ../static/db-worker-node.js, but no explicit diagnostic command validates that runtime target path readiness. |
Add doctor check that validates the effective script file existence and readability before startup commands fail. |
| Data-dir readiness | /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/data_dir.cljs enforces directory creation and read or write access in ensure-data-dir!. |
Reuse ensure-data-dir! inside doctor and report a dedicated failing check item. |
| Daemon liveness visibility | /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/server.cljs has list-servers, server-status, ready?, and healthy?, but no consolidated health summary command. |
Add optional runtime checks in doctor that flag non-ready running servers discovered from lock files. |
| CLI discoverability | Top-level help and command table in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/commands.cljs and /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/core.cljs do not include diagnostics entrypoint. |
Add doctor to command entries and help summaries. |
Proposed doctor checks
| Check id | Behavior | Existing helper to reuse | Failure signal |
|---|---|---|---|
db-worker-script |
Verify ../static/db-worker-node.js exists and is readable as a file (and optionally verify ../dist/db-worker-node.js wrapper exists). |
New shared path helper in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/server.cljs plus Node fs checks in doctor command. |
:doctor-script-missing or :doctor-script-unreadable. |
data-dir |
Verify configured or default data dir can be created and is read and write accessible. | logseq.cli.data-dir/ensure-data-dir! in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/data_dir.cljs. |
Existing :data-dir-permission surfaced as doctor failure detail. |
running-servers |
Verify currently locked db-worker instances are reachable on readiness endpoint. | logseq.cli.server/list-servers status derivation in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/server.cljs. |
:doctor-server-not-ready for any server reported as :starting. |
Integration sketch
logseq doctor
-> parse-args (commands table)
-> build-action {:type :doctor}
-> execute-doctor
1) check effective db-worker-node.js runtime path (`static/db-worker-node.js`).
2) check data-dir accessibility.
3) inspect running server readiness.
-> format result for human/json/edn.
Implementation plan
Phase 1: RED for command plumbing.
- Add failing assertions in
/Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/commands_test.cljsthat top-level help includesdoctorand bold-styleddoctorcommand text. - Add a failing parse test in
/Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/commands_test.cljsforcommands/parse-args ["doctor"]returning:ok? truewith command:doctor. - Add a failing build-action test in
/Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/commands_test.cljsfor{:command :doctor}producing action type:doctor. - Run
bb dev:test -v 'logseq.cli.commands-test'and confirm failures are specifically on new doctor assertions.
Phase 2: RED for doctor behavior.
- Create
/Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/command/doctor_test.cljswith namespace and fixtures consistent with existing command tests. - Add a failing test that marks script check as failed when
static/db-worker-node.jspath does not exist. - Add a failing test that marks data-dir check as failed when
ensure-data-dir!throws:data-dir-permission. - Add a failing test that returns all checks passed when script and data-dir are both valid and no running server is unready.
- Add a failing test that reports runtime warning or failure when
list-serversincludes entries with status:starting. - Run
bb dev:test -v 'logseq.cli.command.doctor-test'and confirm all new tests fail for expected reasons.
Phase 3: GREEN for command integration.
- Add
/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/doctor.cljswithentries,build-action, andexecute-doctorreturning structured check results. - Wire doctor namespace into
/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/commands.cljsrequires and appenddoctor-command/entriesintotable. - Add
:doctorbranch inbuild-actioninside/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/commands.cljs. - Add
:doctorbranch inexecuteinside/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/commands.cljs. - Update top-level command grouping in
/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/core.cljsto showdoctorin help output. - Run
bb dev:test -v 'logseq.cli.commands-test'and confirm doctor parse and help tests are green.
Phase 4: GREEN for doctor checks.
- Extract or add a shared db-worker script path helper in
/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/server.cljsso spawn and doctor share one source of truth. - Implement script existence and readability check in
/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/doctor.cljsusing Nodefsmetadata checks. - Implement data-dir check in
/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/doctor.cljsby invokinglogseq.cli.data-dir/ensure-data-dir!. - Implement running-server readiness check in
/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/doctor.cljsusinglogseq.cli.server/list-servers. - Return deterministic check ordering and include actionable message per check in
/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/doctor.cljs. - Re-run
bb dev:test -v 'logseq.cli.command.doctor-test'and confirm all doctor behavior tests are green.
Phase 5: RED and GREEN for formatting and docs.
- Add failing output tests in
/Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/format_test.cljsfor human summary rendering of doctor checks. - Add failing output tests in
/Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/format_test.cljsfor json and edn output preserving structured check payload. - Implement doctor-specific human formatter in
/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/format.cljs. - Ensure
doctoroutput includes overall status and per-check status in/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/format.cljs. - Update
/Users/rcmerci/gh-repos/logseq/docs/cli/logseq-cli.mdwithdoctorcommand description, examples, and expected failure hints. - Run
bb dev:test -v 'logseq.cli.format-test'and confirm new doctor formatting tests are green.
Phase 6: Verify RED to GREEN cycle completion, refactor, and full validation.
- Run
bb dev:test -v 'logseq.cli.commands-test'and ensure no regressions in help parsing and action dispatch. - Run
bb dev:test -v 'logseq.cli.command.doctor-test'and ensure all doctor checks are behavior-driven and stable. - Run
bb dev:test -v 'logseq.cli.main-test'to confirm entrypoint behavior remains compatible. - Run
bb dev:test -v 'logseq.cli.server-test'to verify shared script path changes do not break server startup assumptions. - Run
bb dev:test -v 'logseq.cli.format-test'to validate output contracts. - Run
bb dev:lint-and-testand confirm zero failures and zero errors. - Review changed code against
@prompts/review.mdbefore merge.
Edge cases to cover
| Scenario | Expected behavior |
|---|---|
static/db-worker-node.js path exists but points to a directory. |
doctor reports script check failure with explicit path and reason. |
data-dir path points to a file. |
doctor fails with :data-dir-permission detail and does not continue to misleading pass status. |
data-dir is readable but not writable. |
doctor fails data-dir check and returns actionable permission hint. |
Running server lock exists but /readyz is not healthy. |
doctor reports runtime check as failed for that repo. |
| No running server exists. | Runtime server check passes with empty server list and does not force daemon startup. |
--output json is used. |
Doctor returns stable machine-readable check list for scripts and automation. |
Verification commands and expected outputs
bb dev:test -v 'logseq.cli.commands-test'
bb dev:test -v 'logseq.cli.command.doctor-test'
bb dev:test -v 'logseq.cli.server-test'
bb dev:test -v 'logseq.cli.format-test'
bb dev:test -v 'logseq.cli.main-test'
bb dev:lint-and-test
Each command should finish with zero failures and zero errors in GREEN phase.
Each RED phase run should fail on newly added doctor assertions and not on unrelated setup errors.
Testing Details
The tests focus on command behavior and diagnostics outcomes through public parser and executor boundaries.
The tests avoid implementation-detail assertions and instead validate user-observable results for success and failure cases.
The formatter tests ensure the same doctor payload is usable for both human troubleshooting and automation output modes.
Implementation Details
- Keep
doctoras a first-class command in the existing CLI command table. - Reuse
ensure-data-dir!instead of reimplementing permission checks. - Reuse server health status discovery through existing
list-serversbehavior. - Keep check execution deterministic and output stable for CI parsing.
- Keep command scope read-only for diagnostics and avoid auto-remediation side effects.
- Return explicit error codes for script and runtime health failures.
- Preserve current graph and repo naming semantics and lock protocol behavior.
- Add targeted formatter support so human output is concise and actionable.
- Verify all changes via focused tests before full lint and test pass.
- Follow
@test-driven-developmentand@prompts/review.mdthroughout implementation.
Question
Resolved: doctor will fail fast on the first failed check.
Resolved: doctor will treat :starting servers as warnings when script and data-dir checks pass.
Resolved: doctor will support a future --repo scoped deep check that verifies per-graph lock path and repo directory access without starting the daemon.