mirror of
https://github.com/logseq/logseq.git
synced 2026-05-24 04:34:14 +00:00
feat(cli): add 'debug pull' cmd
This commit is contained in:
258
docs/agent-guide/073-logseq-cli-debug-command.md
Normal file
258
docs/agent-guide/073-logseq-cli-debug-command.md
Normal file
@@ -0,0 +1,258 @@
|
||||
# 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:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```clojure
|
||||
{: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:
|
||||
|
||||
```clojure
|
||||
{: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
|
||||
|
||||
5. 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
|
||||
6. 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
|
||||
|
||||
7. Implement new namespace `command/debug.cljs` with entries + build + execute.
|
||||
8. 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`
|
||||
9. 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
|
||||
|
||||
10. Update completion tests in `/Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/completion_generator_test.cljs`:
|
||||
- includes `debug` group and `pull` subcommand completion.
|
||||
11. 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`
|
||||
12. 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
|
||||
|
||||
13. 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)
|
||||
14. 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
|
||||
|
||||
```bash
|
||||
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.
|
||||
Reference in New Issue
Block a user