Files
logseq/docs/agent-guide/073-logseq-cli-debug-command.md
2026-04-01 23:39:10 +08:00

12 KiB

Logseq CLI debug Command Implementation Plan

Goal: Add a new debug command group with debug pull for low-level Datascript entity inspection via db-worker-node.

Goal: debug pull must support --graph <name> or default to current graph resolution already used by existing commands.

Goal: In global help (logseq --help), show debug under Utilities and do not show debug subcommands (same top-level-only behavior as example).

Architecture: Keep command parsing, validation, and output behavior in logseq-cli, and reuse existing db-worker-node invoke API :thread-api/pull with selector [*].

Architecture: Avoid adding new worker thread APIs unless we discover a hard blocker; current worker already exposes :thread-api/pull and supports lookup refs.

Tech Stack: ClojureScript, babashka.cli dispatch table, existing command pipeline in logseq.cli.commands (parse-args -> build-action -> execute), and existing CLI e2e spec harness.

Related:

  • /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/commands.cljs
  • /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/core.cljs
  • /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/show.cljs
  • /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/id.cljs
  • /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/transport.cljs
  • /Users/rcmerci/gh-repos/logseq/src/main/frontend/worker/db_core.cljs
  • /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/commands_test.cljs
  • /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/completion_generator_test.cljs
  • /Users/rcmerci/gh-repos/logseq/cli-e2e/spec/non_sync_inventory.edn
  • /Users/rcmerci/gh-repos/logseq/cli-e2e/spec/non_sync_cases.edn

Problem statement

Today we have user-facing inspection commands (show, query), but no direct debug command that exposes a raw pull for a single entity selector path.

For debugging schema/data issues, we need a predictable command that can fetch one entity using either db id, uuid, or ident and return raw entity data.

The requested command is:

logseq debug pull --id <db-id>
logseq debug pull --uuid <uuid>
logseq debug pull --ident <db-ident>

with selector fixed to [*] and data source being the current graph DB served by db-worker-node.

Requested behavior contract

Area Requirement
Command shape Add top-level debug group with subcommand pull.
Graph selection Accept --graph globally; if omitted, use current graph resolution (same as existing commands using pick-graph).
Target selector debug pull accepts exactly one of --id, --uuid, --ident.
Pull behavior Execute :thread-api/pull with selector [*] and resolved lookup value.
Global help logseq --help shows debug in Utilities and does not list debug pull there.
Group help logseq debug and logseq debug --help show debug pull as subcommand.

Current baseline

  • Top-level help grouping is implemented in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/core.cljs with Utilities currently configured as top-level-only and already hiding example subcommands.
  • Graph fallback is implemented centrally via logseq.cli.command.core/pick-graph and is already used in build-action for graph-scoped commands.
  • db-worker-node already provides :thread-api/pull in /Users/rcmerci/gh-repos/logseq/src/main/frontend/worker/db_core.cljs:
    • accepts (repo selector id)
    • supports integer ids and lookup refs (e.g. [:db/ident kw], [:block/uuid uuid])
  • Existing command modules (show, query) already demonstrate ensure-server + invoke flow and can be reused as implementation patterns.

Conclusion: this feature should be mostly CLI-side wiring; worker protocol changes are likely unnecessary.

CLI design proposal

1) New command namespace

Add /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/debug.cljs.

Planned entry:

  • debug pull (:debug-pull)

Planned command options:

  • --id (db id)
  • --uuid (UUID string)
  • --ident (strict EDN keyword string, e.g. :logseq.class/Tag)

Global options (--graph, --output, etc.) continue to come from command-entry merged global spec.

2) Selector normalization

debug pull resolves exactly one lookup target:

  • --id -> numeric entity id
  • --uuid -> lookup ref [:block/uuid <uuid>]
  • --ident -> lookup ref [:db/ident <keyword>]

Validation rules:

  • exactly one of --id, --uuid, --ident is required
  • reject multiple selectors with clear invalid-options message
  • reject invalid uuid / invalid id / invalid ident formats
  • --ident accepts only strict EDN keyword syntax with leading :

3) Action model

build-action output shape:

{:type :debug-pull
 :repo <resolved repo>
 :lookup <id-or-lookup-ref>
 :selector '[*]}

repo resolution should reuse existing command pipeline behavior:

  • --graph first
  • then config current graph
  • then repo fallback from config

4) Execute model

Execution pattern:

  1. ensure server for repo (cli-server/ensure-server!)
  2. invoke worker :thread-api/pull with [repo selector lookup]
  3. return structured data payload (include selector metadata for traceability)

Suggested success payload:

{:entity <pulled-entity>
 :lookup <normalized lookup>
 :selector '[*]}

For missing entity, return a clear typed error (e.g. :entity-not-found) instead of silently returning nil.

Global help behavior plan

Update top-level-summary groups in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/core.cljs:

  • add debug to Utilities command set
  • keep :top-level-only? true for Utilities
  • add desc-overrides entry for debug so top-level help renders stable one-line description (instead of inheriting from debug pull text)

Expected top-level help effect:

  • shows debug
  • does not show debug pull
  • remains consistent with current example visibility behavior

Testing Plan (TDD)

I will follow @test-driven-development and write failing tests first.

Phase 1: Parser and help RED tests

  1. Extend /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/commands_test.cljs:
    • top-level help includes debug
    • top-level help does not include debug pull
    • Utilities section still lists example and completion
  2. Add group-help tests:
    • parse-args ["debug"] returns help summary containing debug pull
  3. Add parse success tests:
    • debug pull --id 1
    • debug pull --uuid <uuid>
    • debug pull --ident :logseq.class/Tag
  4. Add parse failure tests:
    • no selector
    • multiple selectors
    • malformed id / uuid / ident

Phase 2: Action and execute RED tests

  1. Add build-action tests in commands_test.cljs:
    • uses --graph when provided
    • falls back to current graph from config when --graph omitted
    • returns missing-repo when neither explicit nor current graph exists
  2. Add execute tests (new file suggested: /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/command/debug_test.cljs):
    • verifies invoke contract :thread-api/pull with selector [*]
    • verifies id/uuid/ident normalization to lookup argument
    • verifies entity-not-found behavior

Phase 3: GREEN implementation

  1. Implement new namespace command/debug.cljs with entries + build + execute.
  2. Wire into /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/commands.cljs:
    • include debug-command/entries in base table
    • finalize-command validation branch for selector constraints
    • build-action case :debug-pull
    • execute case :debug-pull
  3. Update /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/core.cljs top-level group config for Utilities to include debug (hidden subcommands at global help).

Phase 4: Completion and e2e coverage

  1. Update completion tests in /Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/completion_generator_test.cljs:
    • includes debug group and pull subcommand completion.
  2. Update inventory in /Users/rcmerci/gh-repos/logseq/cli-e2e/spec/non_sync_inventory.edn:
    • add :debug scope with command debug pull
    • add options --id, --uuid, --ident
  3. Add e2e cases in /Users/rcmerci/gh-repos/logseq/cli-e2e/spec/non_sync_cases.edn:
    • id-based pull
    • uuid-based pull
    • ident-based pull
    • one case proving current-graph fallback (no --graph on debug call after config/graph setup)

Phase 5: Formatter and docs

  1. Add explicit human formatting branch in /Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/format.cljs for :debug-pull:
    • pretty-print entity as EDN for readable debugging output
    • include compact header context (selector and lookup)
  2. Update /Users/rcmerci/gh-repos/logseq/docs/cli/logseq-cli.md with debug pull usage and examples.

File-by-file change map

File Planned change
/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/debug.cljs New command namespace (entries, validation helpers, build-action, execute-debug-pull).
/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/commands.cljs Register debug entries; add parse/finalize validation, build-action route, and execute dispatch.
/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/core.cljs Add debug under Utilities top-level-only group and description override to hide subcommands in global help.
/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/format.cljs Add explicit human formatter for debug output with pretty-printed EDN entity payload.
/Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/commands_test.cljs Add parser/help/build coverage for debug command and utilities help visibility rules.
/Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/command/debug_test.cljs New execute/normalization tests for debug pull invoke contract.
/Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/completion_generator_test.cljs Add completion coverage for debug pull.
/Users/rcmerci/gh-repos/logseq/cli-e2e/spec/non_sync_inventory.edn Add debug scope and option coverage metadata.
/Users/rcmerci/gh-repos/logseq/cli-e2e/spec/non_sync_cases.edn Add non-sync end-to-end cases for id/uuid/ident and graph fallback behavior.
/Users/rcmerci/gh-repos/logseq/docs/cli/logseq-cli.md Document debug pull usage and selector examples.

db-worker-node impact

No new worker API is required for the requested scope.

Reason:

  • :thread-api/pull already exists and already performs Datascript d/pull.
  • selector [*] is legal and directly maps to requested debug behavior.
  • lookup refs for :db/ident and :block/uuid are already supported by Datascript pull semantics.

Potential worker-side follow-up is only needed if we later want:

  • multi-entity pull
  • custom selectors from CLI input
  • stricter nil/not-found error signaling at worker layer

Edge cases to explicitly cover

Scenario Expected behavior
debug pull with no selector flags Error: exactly one selector required.
debug pull --id 1 --uuid ... Error: only one of --id, --uuid, --ident allowed.
debug pull --ident logseq.class/Tag (without leading :) Error with explicit invalid ident message (--ident requires strict EDN keyword).
debug pull without --graph and no current graph configured Error: missing repo/graph.
entity not found Return typed error (:entity-not-found) instead of ambiguous success with nil.
logseq --help Shows debug under Utilities, not debug pull.

Verification commands

bb dev:test -v logseq.cli.commands-test
bb dev:test -v logseq.cli.command.debug-test
bb dev:test -v logseq.cli.completion-generator-test
bb -f cli-e2e/bb.edn test --skip-build
bb dev:lint-and-test

Expected outcome: parser/help behavior, invoke contract, completion, and e2e coverage all green.

Resolved decisions

  1. --ident accepts only strict EDN keyword input.
  2. Not-found is a hard error (:entity-not-found).
  3. Human output for debug pull uses pretty-printed EDN.