Files
logseq/docs/agent-guide/031-logseq-cli-doctor-command.md
2026-03-12 15:12:33 +08:00

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.

  1. Add failing assertions in /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/commands_test.cljs that top-level help includes doctor and bold-styled doctor command text.
  2. Add a failing parse test in /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/commands_test.cljs for commands/parse-args ["doctor"] returning :ok? true with command :doctor.
  3. Add a failing build-action test in /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/commands_test.cljs for {:command :doctor} producing action type :doctor.
  4. Run bb dev:test -v 'logseq.cli.commands-test' and confirm failures are specifically on new doctor assertions.

Phase 2: RED for doctor behavior.

  1. Create /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/command/doctor_test.cljs with namespace and fixtures consistent with existing command tests.
  2. Add a failing test that marks script check as failed when static/db-worker-node.js path does not exist.
  3. Add a failing test that marks data-dir check as failed when ensure-data-dir! throws :data-dir-permission.
  4. Add a failing test that returns all checks passed when script and data-dir are both valid and no running server is unready.
  5. Add a failing test that reports runtime warning or failure when list-servers includes entries with status :starting.
  6. 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.

  1. Add /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/doctor.cljs with entries, build-action, and execute-doctor returning structured check results.
  2. Wire doctor namespace into /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/commands.cljs requires and append doctor-command/entries into table.
  3. Add :doctor branch in build-action inside /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/commands.cljs.
  4. Add :doctor branch in execute inside /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/commands.cljs.
  5. Update top-level command grouping in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/core.cljs to show doctor in help output.
  6. Run bb dev:test -v 'logseq.cli.commands-test' and confirm doctor parse and help tests are green.

Phase 4: GREEN for doctor checks.

  1. Extract or add a shared db-worker script path helper in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/server.cljs so spawn and doctor share one source of truth.
  2. Implement script existence and readability check in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/doctor.cljs using Node fs metadata checks.
  3. Implement data-dir check in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/doctor.cljs by invoking logseq.cli.data-dir/ensure-data-dir!.
  4. Implement running-server readiness check in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/doctor.cljs using logseq.cli.server/list-servers.
  5. Return deterministic check ordering and include actionable message per check in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/doctor.cljs.
  6. 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.

  1. Add failing output tests in /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/format_test.cljs for human summary rendering of doctor checks.
  2. Add failing output tests in /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/format_test.cljs for json and edn output preserving structured check payload.
  3. Implement doctor-specific human formatter in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/format.cljs.
  4. Ensure doctor output includes overall status and per-check status in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/format.cljs.
  5. Update /Users/rcmerci/gh-repos/logseq/docs/cli/logseq-cli.md with doctor command description, examples, and expected failure hints.
  6. 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.

  1. Run bb dev:test -v 'logseq.cli.commands-test' and ensure no regressions in help parsing and action dispatch.
  2. Run bb dev:test -v 'logseq.cli.command.doctor-test' and ensure all doctor checks are behavior-driven and stable.
  3. Run bb dev:test -v 'logseq.cli.main-test' to confirm entrypoint behavior remains compatible.
  4. Run bb dev:test -v 'logseq.cli.server-test' to verify shared script path changes do not break server startup assumptions.
  5. Run bb dev:test -v 'logseq.cli.format-test' to validate output contracts.
  6. Run bb dev:lint-and-test and confirm zero failures and zero errors.
  7. Review changed code against @prompts/review.md before 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 doctor as 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-servers behavior.
  • 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-development and @prompts/review.md throughout 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.