diff --git a/docs/agent-guide/004-logseq-cli-verb-subcommands.md b/docs/agent-guide/004-logseq-cli-verb-subcommands.md index f4367ac223..44fad77d27 100644 --- a/docs/agent-guide/004-logseq-cli-verb-subcommands.md +++ b/docs/agent-guide/004-logseq-cli-verb-subcommands.md @@ -67,7 +67,7 @@ Common list options: | --limit N | page, tag, property | Limit results | Implemented in CLI after fetch unless server supports it. | | --offset N | page, tag, property | Offset results | Implemented in CLI after fetch unless server supports it. | | --sort FIELD | page, tag, property | Sort results | Field whitelist per type. | -| --order asc|desc | page, tag, property | Sort direction | Defaults to asc. | +| --order asc|desc | page, tag, property | Sort direction | Defaults to desc. | | --output FORMAT | all | Output format | Existing output handling. | List page options: diff --git a/docs/cli/logseq-cli.md b/docs/cli/logseq-cli.md index 2679b43ea3..8e42e39c97 100644 --- a/docs/cli/logseq-cli.md +++ b/docs/cli/logseq-cli.md @@ -242,15 +242,15 @@ E2EE password persistence locations: - Node runtime stores refresh-token-encrypted password payload at `~/logseq/e2ee-password`. Inspect and edit commands: -- `list page [--expand] [--limit ] [--offset ] [--sort ] [--order asc|desc]` - list pages (defaults to `--sort updated-at`) -- `list tag [--expand] [--limit ] [--offset ] [--sort ] [--order asc|desc]` - list tags (defaults to `--sort updated-at`) -- `list property [--expand] [--limit ] [--offset ] [--sort ] [--order asc|desc]` - list properties (defaults to `--sort updated-at`; `TYPE` and `CARDINALITY` are included by default even without `--expand`; missing schema cardinality is treated as `one`) -- `list task [--status ] [--priority ] [-c|--content ] [--fields ] [--limit ] [--offset ] [--sort ] [--order asc|desc]` - list task nodes tagged with `#Task` (supports both pages and blocks; defaults to `--sort updated-at`) +- `list page [--expand] [--limit ] [--offset ] [--sort ] [--order asc|desc]` - list pages (defaults to `--sort updated-at --order desc`) +- `list tag [--expand] [--limit ] [--offset ] [--sort ] [--order asc|desc]` - list tags (defaults to `--sort updated-at --order desc`) +- `list property [--expand] [--limit ] [--offset ] [--sort ] [--order asc|desc]` - list properties (defaults to `--sort updated-at --order desc`; `TYPE` and `CARDINALITY` are included by default even without `--expand`; missing schema cardinality is treated as `one`) +- `list task [--status ] [--priority ] [-c|--content ] [--fields ] [--limit ] [--offset ] [--sort ] [--order asc|desc]` - list task nodes tagged with `#Task` (supports both pages and blocks; defaults to `--sort updated-at --order desc`) - `--status` is validated at runtime using values from the current graph; invalid values return an error that includes available values from that graph. -- `list node [--tags ] [--properties ] [--fields ] [--limit ] [--offset ] [--sort ] [--order asc|desc]` - list ordinary nodes (pages and blocks) filtered by tags/properties (supports selector forms id/uuid/ident/name; at least one of `--tags` or `--properties` is required; defaults to `--sort updated-at`) +- `list node [--tags ] [--properties ] [--fields ] [--limit ] [--offset ] [--sort ] [--order asc|desc]` - list ordinary nodes (pages and blocks) filtered by tags/properties (supports selector forms id/uuid/ident/name; at least one of `--tags` or `--properties` is required; defaults to `--sort updated-at --order desc`) - `--tags` and `--properties` use **all-of** semantics, and when both are present they are combined with **AND**. - CSV tokens are trimmed and empty tokens are ignored; if a provided filter becomes empty after normalization, CLI returns `invalid-options`. -- `list asset [--fields ] [--limit ] [--offset ] [--sort ] [--order asc|desc]` - list nodes tagged with `#Asset` (`:logseq.class/Asset`; defaults to `--sort updated-at`) +- `list asset [--fields ] [--limit ] [--offset ] [--sort ] [--order asc|desc]` - list nodes tagged with `#Asset` (`:logseq.class/Asset`; defaults to `--sort updated-at --order desc`) - `upsert block --content [--target-page |--target-id |--target-uuid ] [--pos first-child|last-child|sibling]` - create blocks; defaults to today’s journal page if no target is given - `upsert block --blocks [--target-page |--target-id |--target-uuid ] [--pos first-child|last-child|sibling]` - insert blocks via EDN vector - `upsert block --blocks-file [--target-page |--target-id |--target-uuid ] [--pos first-child|last-child|sibling]` - insert blocks from an EDN file diff --git a/src/main/logseq/cli/command/list.cljs b/src/main/logseq/cli/command/list.cljs index e47e66bb5a..03e5850348 100644 --- a/src/main/logseq/cli/command/list.cljs +++ b/src/main/logseq/cli/command/list.cljs @@ -20,7 +20,7 @@ :coerce :long} :sort {:desc "Sort field. Default: updated-at" :alias :s} - :order {:desc "Sort order. Default: asc" + :order {:desc "Sort order. Default: desc" :validate #{"asc" "desc"}}}) ;; Common for all page-related subcommands @@ -330,7 +330,7 @@ items (transport/invoke cfg :thread-api/cli-list-pages false [(:repo action) options]) sort-field (effective-sort-field options) - order (or (:order options) "asc") + order (or (:order options) "desc") fields (parse-field-list (:fields options)) sorted (apply-sort items sort-field order list-page-field-map) limited (apply-offset-limit sorted (:offset options) (:limit options)) @@ -347,7 +347,7 @@ items (transport/invoke cfg :thread-api/cli-list-tags false [(:repo action) options]) sort-field (effective-sort-field options) - order (or (:order options) "asc") + order (or (:order options) "desc") fields (parse-field-list (:fields options)) prepared (mapv #(prepare-tag-item % options) items) sorted (apply-sort prepared sort-field order list-tag-field-map) @@ -364,7 +364,7 @@ items (transport/invoke cfg :thread-api/cli-list-properties false [(:repo action) options]) sort-field (effective-sort-field options) - order (or (:order options) "asc") + order (or (:order options) "desc") fields (parse-field-list (:fields options)) prepared (mapv #(prepare-property-item % options) items) sorted (apply-sort prepared sort-field order list-property-field-map) @@ -419,7 +419,7 @@ items (transport/invoke cfg :thread-api/cli-list-nodes false [(:repo action) worker-options]) sort-field (effective-sort-field options) - order (or (:order options) "asc") + order (or (:order options) "desc") fields (parse-field-list (:fields options)) sorted (apply-sort items sort-field order list-node-field-map) limited (apply-offset-limit sorted (:offset options) (:limit options)) @@ -448,7 +448,7 @@ items (transport/invoke cfg :thread-api/cli-list-nodes false [(:repo action) worker-options]) sort-field (effective-sort-field options) - order (or (:order options) "asc") + order (or (:order options) "desc") fields (parse-field-list (:fields options)) sorted (apply-sort items sort-field order list-asset-field-map) limited (apply-offset-limit sorted (:offset options) (:limit options)) @@ -485,7 +485,7 @@ (p/let [items (transport/invoke cfg :thread-api/cli-list-tasks false [(:repo action) normalized-options]) sort-field (effective-sort-field normalized-options) - order (or (:order normalized-options) "asc") + order (or (:order normalized-options) "desc") fields (parse-field-list (:fields normalized-options)) sorted (apply-sort items sort-field order list-task-field-map) limited (apply-offset-limit sorted (:offset normalized-options) (:limit normalized-options)) diff --git a/src/test/logseq/cli/commands_test.cljs b/src/test/logseq/cli/commands_test.cljs index ff2d883865..2676d3a9ea 100644 --- a/src/test/logseq/cli/commands_test.cljs +++ b/src/test/logseq/cli/commands_test.cljs @@ -1204,7 +1204,14 @@ (is (= 5 (get-in result [:options :limit]))) (is (= 1 (get-in result [:options :offset]))) (is (= "updated-at" (get-in result [:options :sort]))) - (is (= "desc" (get-in result [:options :order])))))) + (is (= "desc" (get-in result [:options :order]))))) + + (testing "list command help shows default sort and order" + (let [result (binding [style/*color-enabled?* true] + (commands/parse-args ["list" "page" "--help"])) + summary (strip-ansi (:summary result))] + (is (string/includes? summary "Sort field. Default: updated-at")) + (is (string/includes? summary "Sort order. Default: desc"))))) (deftest test-search-subcommand-parse (testing "search block parses --content option" @@ -1359,13 +1366,35 @@ :thread-api/cli-list-properties [{:db/id 8 :block/title "Property C" :block/updated-at 9} {:db/id 6 :block/title "Property B" :block/updated-at 3} {:db/id 1 :block/title "Property A" :block/updated-at 3}] + :thread-api/cli-list-tasks [{:db/id 14 :block/title "Task C" :block/updated-at 12} + {:db/id 12 :block/title "Task B" :block/updated-at 4} + {:db/id 10 :block/title "Task A" :block/updated-at 4}] (throw (ex-info "unexpected invoke" {:method method}))))] (p/let [page-result (list-command/execute-list-page {:repo "demo" :options {}} {}) tag-result (list-command/execute-list-tag {:repo "demo" :options {}} {}) - property-result (list-command/execute-list-property {:repo "demo" :options {}} {})] - (is (= [5 7 11] (item-ids page-result))) - (is (= [2 9 4] (item-ids tag-result))) - (is (= [1 6 8] (item-ids property-result))))) + property-result (list-command/execute-list-property {:repo "demo" :options {}} {}) + task-result (list-command/execute-list-task {:repo "demo" :options {}} {})] + (is (= [11 7 5] (item-ids page-result))) + (is (= [4 9 2] (item-ids tag-result))) + (is (= [8 6 1] (item-ids property-result))) + (is (= [14 12 10] (item-ids task-result))))) + (p/catch (fn [e] + (is false (str "unexpected error: " e)))) + (p/finally done)))) + +(deftest test-list-execute-default-limit-returns-newest-records + (async done + (-> (p/with-redefs [cli-server/ensure-server! (fn [_ _] {:base-url "http://example"}) + transport/invoke (fn [_ method _ _] + (case method + :thread-api/cli-list-pages (mapv (fn [id] + {:db/id id + :block/title (str "Page " id) + :block/updated-at id}) + [4 12 1 8 3 11 2 10 5 9 6 7]) + (throw (ex-info "unexpected invoke" {:method method}))))] + (p/let [result (list-command/execute-list-page {:repo "demo" :options {:limit 10}} {})] + (is (= [12 11 10 9 8 7 6 5 4 3] (item-ids result))))) (p/catch (fn [e] (is false (str "unexpected error: " e)))) (p/finally done)))) @@ -1375,14 +1404,16 @@ (-> (p/with-redefs [cli-server/ensure-server! (fn [_ _] {:base-url "http://example"}) transport/invoke (fn [_ method _ _] (case method - :thread-api/cli-list-pages [{:db/id 3 :block/title "Gamma" :block/updated-at 20} - {:db/id 2 :block/title "Alpha" :block/updated-at 5} - {:db/id 1 :block/title "Beta" :block/updated-at 10}] + :thread-api/cli-list-pages [{:db/id 3 :block/title "Beta" :block/updated-at 20} + {:db/id 2 :block/title "Gamma" :block/updated-at 5} + {:db/id 1 :block/title "Alpha" :block/updated-at 10}] (throw (ex-info "unexpected invoke" {:method method}))))] - (p/let [desc-default-result (list-command/execute-list-page {:repo "demo" :options {:order "desc"}} {}) + (p/let [default-result (list-command/execute-list-page {:repo "demo" :options {}} {}) + explicit-order-result (list-command/execute-list-page {:repo "demo" :options {:order "asc"}} {}) explicit-sort-result (list-command/execute-list-page {:repo "demo" :options {:sort "title"}} {})] - (is (= [3 1 2] (item-ids desc-default-result))) - (is (= [2 1 3] (item-ids explicit-sort-result))))) + (is (= [3 1 2] (item-ids default-result))) + (is (= [2 1 3] (item-ids explicit-order-result))) + (is (= [2 3 1] (item-ids explicit-sort-result))))) (p/catch (fn [e] (is false (str "unexpected error: " e)))) (p/finally done)))) @@ -1408,7 +1439,7 @@ :fields "id,title,cardinality"}} {}) items (get-in result [:data :items])] - (is (= [10 20 30] (mapv :db/id items))) + (is (= [30 20 10] (mapv :db/id items))) (is (= [#{:db/id :block/title :db/cardinality} #{:db/id :block/title :db/cardinality} #{:db/id :block/title :db/cardinality}] @@ -1440,7 +1471,7 @@ (throw (ex-info "unexpected invoke" {:method method :args args}))))] (p/let [result (list-command/execute-list-asset {:repo "demo" - :options {:sort "updated-at" :order "desc" :limit 1}} + :options {:limit 1}} {}) items (get-in result [:data :items]) list-call (some #(when (= :thread-api/cli-list-nodes (:method %)) %) @calls*)]