001-logseq-cli.md 8.8 KB

Logseq CLI Implementation Plan

Goal: Build a new Logseq CLI in ClojureScript that runs on Node.js and connects to the db-worker-node server.

Architecture: The CLI is a Node-targeted ClojureScript program built via shadow-cljs and packaged with a small JavaScript launcher. The CLI speaks a simple request and response protocol to the existing db-worker-node HTTP or WebSocket API and exposes high-level subcommands for users.

Tech Stack: ClojureScript, shadow-cljs :node-script target, Node.js runtime, existing db-worker-node server.

Related: Relates to docs/agent-guide/task--basic-logseq-cli.md and docs/agent-guide/task--db-worker-nodejs-compatible.md.

Problem statement

We need a new Logseq CLI that is independent of any existing CLI code in the repo. The CLI must run in Node.js, be written in ClojureScript, and connect to the db-worker-node server started from static/db-worker-node.js. The CLI should provide a stable interface for scripting and troubleshooting, and it should be easy to extend with new commands.

Testing Plan

I will add an integration test that starts db-worker-node on a test port and verifies the CLI can connect and run a simple graph/content request. I will add unit tests for command parsing, configuration precedence, and error formatting. I will add unit tests for the client transport layer to ensure timeouts and retries behave correctly. I will add unit tests for new graph/content commands (parsing, validation, and request mapping). I will add integration tests for graph lifecycle commands and content commands against a real db-worker-node. I will follow @test-driven-development for all behavior changes. NOTE: I will write all tests before I add any implementation behavior.

Architecture sketch

The CLI is a Node program that parses flags, loads config, and sends requests to db-worker-node. The db-worker-node server is already built from the :db-worker-node shadow-cljs target and listens on a TCP port.

ASCII diagram:

+--------------+ HTTP or WS +---------------------+ | logseq-cli | -----------------------> | db-worker-node | | node script | <----------------------- | server on port 9101 | +--------------+ +---------------------+

Assumptions

The db-worker-node server exposes a stable API for a small set of requests needed by the CLI. The CLI will default to localhost:9101 unless configured otherwise. The CLI will use JSON for request and response bodies for ease of scripting.

Implementation plan

  1. Use tool(update_plan) to track the full task list and include the @test-driven-development red-green-refactor steps.
  2. Read @test-driven-development guidelines and confirm the red phase will include all CLI tests first.
  3. Identify existing db-worker-node request handlers and document their request and response shapes.
  4. Define the initial CLI command surface as a table that includes command, input, output, and errors.
  5. Decide on transport protocol based on db-worker-node capabilities and document the selection.
  6. Add a new shadow-cljs build target named :logseq-cli with :target :node-script and a dedicated output file in static/.
  7. Create a new namespace for the CLI entrypoint in src/main/cli/main.cljs and wire it as the :main for the build.
  8. Create src/main/cli/config.cljs with config resolution order of CLI flags, env vars, then config file.
  9. Create src/main/cli/transport.cljs with a small client that can send requests and parse responses.
  10. Create src/main/cli/commands.cljs with pure functions that map parsed args to transport requests.
  11. Create src/main/cli/format.cljs that formats success and error output for human and machine usage.
  12. Add unit tests in src/test/logseq/cli for config precedence, command parsing, and error formatting behavior.
  13. Add integration tests in src/test/logseq/cli that start db-worker-node and invoke the CLI entrypoint.
  14. Run tests in red phase with bb dev:test -v and confirm failures are behavior-related.
  15. Implement the minimal code to make the tests pass and re-run in green phase.
  16. Refactor for naming and reuse while keeping tests green.
  17. Document how to build and run the CLI in a short section in README.md.

Current status (2026-01-14)

Implemented:

  • CLI build target, entrypoint, config resolution, transport, formatting, and command wiring.
  • Graph commands: list/create/switch/remove/validate/info.
  • Content commands: add/remove/search/tree.
  • Unit tests for config/commands/format/transport and integration tests for graph/content commands.
  • CLI docs moved to docs/cli/logseq-cli.md and linked from README.

Not fully aligned with plan:

  • Red-first TDD sequence was not strictly followed (some tests added after initial implementation).
  • README section was replaced by a link to the dedicated doc.
  • search currently queries :block/title only (no page name/content search).

Open follow-ups (optional):

  • Expand search to include page name/content and update tests.
  • Add any additional graph metadata to graph-info beyond :logseq.kv/graph-created-at and :logseq.kv/schema-version.

Command surface definition

Command Input Output Errors
graph-list none list of graphs server unavailable, timeout
graph-create graph name created graph + set current graph invalid name, server unavailable
graph-switch graph name switched graph + set current graph missing graph, server unavailable
graph-remove graph name removal confirmation missing graph, server unavailable
graph-validate graph name or current graph validation result missing graph, server unavailable
graph-info graph name or current graph graph metadata/info missing graph, server unavailable
add block/page payload created block IDs invalid input, server unavailable
remove block/page id or name removal confirmation invalid input, server unavailable
search text query matched blocks/pages invalid input, server unavailable
tree block/page id or name hierarchical tree output invalid input, server unavailable

Edge cases

The db-worker-node server is not running or is listening on a different port. The response payload is invalid JSON or missing fields. The request times out or the server closes the connection early. The user passes incompatible flags or unknown commands. The CLI is run on Windows where path and quoting rules differ. Graph commands are invoked without a current graph configured. Content commands are invoked without specifying a graph and no current graph is set. Content commands refer to missing pages/blocks. Graph removal is attempted while a graph is open.

Testing commands and expected output

Run a single unit test in red phase.

bb dev:test -v logseq.cli.config-test/test-config-precedence

Expected output includes a failing assertion and ends with a non-zero exit code.

Run the full unit test suite in green phase.

bb dev:test -v logseq.cli.*

Expected output includes 0 failures and 0 errors.

Run lint and unit tests when all work is complete.

bb dev:lint-and-test

Expected output includes successful linting and tests with exit code 0.

Testing Details

I will add behavior-driven tests that verify the CLI connects to a real db-worker-node process and that each command returns the expected output for valid input. I will keep unit tests focused on pure functions like parsing, formatting, and config resolution, and avoid mocking internal implementation details.

Implementation Details

  • Add a new shadow-cljs build target for the CLI with a node-script output in static/.
  • Create a dedicated CLI entrypoint namespace that handles args, logging, and exit codes.
  • Implement config resolution for flags, env vars, and optional config file.
  • Implement a transport client with timeouts and explicit error mapping.
  • Define a small command map with functions that return request objects and output renderers.
  • Add structured JSON output mode for scripting alongside human-readable output.
  • Ensure the CLI exits with non-zero status codes on errors.
  • Document build and run steps, including starting db-worker-node first.
  • Add graph management commands that map to db-worker thread-apis.
  • Add graph content commands (add/remove/search/tree) with clear input formats and output.
  • Persist/resolve a “current graph” for commands that default to current context.

Question

Which exact db-worker-node endpoints and request schemas should the CLI use for graph/content commands.

  • Answer: all thread-apis are available in http endpoint, check @src/main/frontend/worker/db_worker_node.cljs

Do we want WebSocket or HTTP as the default transport for the CLI.

  • HTTP

Can I consult the clojure-expert and research-agent agents for architecture and reference implementations as required by the planning guidelines.

  • yes ---