5.2 KiB
Logseq CLI Built-in Status/Priority Queries Plan
Goal: Add built-in query names list-status and list-priority that return the available Status/Priority options from a graph.
Architecture: Keep the existing logseq-cli → db-worker-node transport and thread-api usage; implement list-status/list-priority via :thread-api/q rather than adding a dedicated thread-api.
Tech Stack: ClojureScript, logseq-cli, db-worker-node, Datascript, logseq.db.frontend.property.
Related: src/main/logseq/cli/command/query.cljs, src/main/frontend/worker/db_core.cljs, deps/db/src/logseq/db/frontend/property.cljs.
Problem Statement
Logseq CLI’s query built-ins are limited to Datascript queries. Users cannot easily discover valid Status or Priority options for a graph (e.g., TODO/DOING/DONE, Urgent/High/Low) without knowing the property internals or running custom queries. We need simple built-ins that list the closed values configured for Status and Priority.
Non-Goals
- Changing property schemas or defaults.
- Replacing the existing Datascript query flow.
- Adding new UI commands outside
queryor changing CLI output formats.
Current Behavior (Key Points)
- Built-in queries are defined in
built-in-query-specsinsrc/main/logseq/cli/command/query.cljsand executed via:thread-api/q. - Status and Priority options are stored as closed values on
:logseq.property/statusand:logseq.property/priority(seelogseq.db.frontend.property/get-closed-property-values). - There is no CLI helper to list those closed values.
Proposed Changes
-
Use
:thread-api/qfor closed values- Implement
list-status/list-priorityby issuing a Datascript query via:thread-api/q. - Return a vector of maps with
:db/identand:db/id. - Use
:findwith an ellipsis form to return a vector, e.g.:find [(pull ?e [:db/ident :db/id]) ...](instead of:find (pull ?e [:db/ident :db/id])).
- Implement
-
Add built-in query names
list-statusandlist-priority- Add entries to
built-in-query-specsthat specify a non-Datascript execution path (e.g.,:method/:handlermetadata). - Wire
build-actionto create a dedicated action type when these names are used. - Update
execute-queryto call the new thread API and return results as{:result ["TODO" ...]}so existing output formatting works unchanged.
- Add entries to
-
Expose built-ins in
query list- Ensure
query listincludes the new entries (withdocandinputs: []). - Keep existing “custom overrides built-in” semantics.
- Ensure
Implementation Plan
-
db-worker-node API
- No new thread-api should be added; use
:thread-api/qonly.
- No new thread-api should be added; use
-
CLI built-in wiring
- Extend
built-in-query-specsinsrc/main/logseq/cli/command/query.cljs:list-status→:property-ident :logseq.property/statuslist-priority→:property-ident :logseq.property/priority- Include
:docand:inputs [].
- Update
normalize-query-entry/find-queryhandling to preserve the extra metadata. - Update
build-action:- When the built-in includes a
:property-ident(or:method), create an action like{:type :query-closed-values :repo ... :property-ident ...}.
- When the built-in includes a
- Update
execute-query: - Branch on the new action type to call
transport/invokewith:thread-api/qand return{:result values}(vector of maps with:db/identand:db/id).
- Extend
-
Output and docs
- No change to formatters;
format-query-resultsalready prints vectors. - Update CLI docs if needed (e.g.,
docs/cli/logseq-cli.md) to mention the two built-ins.
- No change to formatters;
Testing Plan
-
Unit tests (
src/test/logseq/cli/command/query_test.cljs):list-queriesincludeslist-statusandlist-prioritywith empty inputs.build-actionfor--name list-statusreturns:query-closed-valuesaction with property ident.- Custom query overrides built-in name still works.
-
db-worker-node tests: no new thread-api, so no additional db-worker-node test needed.
-
Integration (
src/test/logseq/cli/integration_test.cljs):- Start a graph, run
logseq query --name list-status/list-priority, assert statusokand a non-empty vector. - If stable defaults are known, assert a known value is present; otherwise, seed closed values in the test graph.
- Start a graph, run
Edge Cases
- Property has no closed values → return an empty vector (not an error).
- Closed values may be stored in either
:block/titleor:logseq.property/value; if:db/identis absent, the map should still include the key with a nil value. - Ensure ordering follows
:block/orderfromget-closed-property-values.
Files to Touch
src/main/frontend/worker/db_core.cljs(no new thread-api)src/main/logseq/cli/command/query.cljs(built-in specs, build-action branching, execute-query)src/test/logseq/cli/command/query_test.cljs(unit coverage)src/test/frontend/worker/db_worker_node_test.cljsor a db-core test (not required for new thread-api)src/test/logseq/cli/integration_test.cljs(CLI end-to-end)docs/cli/logseq-cli.md(optional docs update)
Open Questions
- Use
:thread-api/qto return structured values:{:db/ident .., :db/id ..}. - Expose
list-status/list-priorityviaquery --nameonly (no dedicated subcommands).