mirror of
https://github.com/logseq/logseq.git
synced 2026-05-18 18:02:35 +00:00
590 lines
24 KiB
Markdown
590 lines
24 KiB
Markdown
# Show Library Page Implementation Plan
|
|
|
|
Goal: Make `logseq show --page Library` display the special Logseq Library page in the same semantic shape as the Desktop App: the `Library` root plus its page hierarchy, not ordinary page content blocks.
|
|
|
|
Architecture: Keep `show` orchestration inside the existing CLI show command namespace.
|
|
Architecture: Reuse the current `db-worker-node` transport APIs, especially `:thread-api/pull` and `:thread-api/q`; do not add a new thread API unless implementation proves these APIs cannot fetch the required parent-page tree.
|
|
Architecture: Detect the built-in `Library` page, fetch children through `:block/parent`, filter children with Desktop Library semantics, and render the result through the existing `show` tree formatter and structured-output sanitizer.
|
|
|
|
Tech Stack: ClojureScript, Logseq CLI `show`, Datascript queries through `db-worker-node`, `logseq.db` entity predicates, Promesa, CLI unit tests, CLI formatter tests if output shape changes, and CLI e2e manifests.
|
|
|
|
Related: Builds on `/Users/rcmerci/gh-repos/logseq/docs/agent-guide/logseq-cli/001-logseq-cli.md`, `/Users/rcmerci/gh-repos/logseq/docs/agent-guide/logseq-cli/006-show-block-link-rendering.md`, and the current `show` implementation in `/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/show.cljs`.
|
|
|
|
## Problem statement
|
|
|
|
The Desktop App treats `Library` as a special built-in page.
|
|
|
|
The current CLI `show` command treats every page as a regular page whose visible tree is built from blocks found through `:block/page`.
|
|
|
|
That ordinary page path is incorrect for `Library` because Library membership is represented by child page entities whose `:block/parent` points at the Library page.
|
|
|
|
As a result, `logseq show --page Library` can show the Library root but miss the page hierarchy that users see in the Desktop App.
|
|
|
|
The new behavior should make CLI `show` useful for inspecting Library contents from headless workflows while preserving existing `show` behavior for normal pages, blocks, linked blocks, linked references, properties, UUID references, and structured output.
|
|
|
|
This feature should not add a public CLI option.
|
|
|
|
This feature should not add a new `db-worker-node` thread API unless the existing `:thread-api/pull` and `:thread-api/q` calls cannot satisfy the implementation after concrete verification.
|
|
|
|
After implementation, review the change with `logseq-review-workflow` before considering the work complete.
|
|
|
|
## Current implementation snapshot
|
|
|
|
The current show command lives in `/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/show.cljs`.
|
|
|
|
The current CLI flow is:
|
|
|
|
```text
|
|
show action
|
|
-> execute-show
|
|
-> build-tree-data
|
|
-> fetch-tree
|
|
-> resolve-linked-blocks-in-tree-data
|
|
-> fetch-linked-references when enabled
|
|
-> resolve-linked-blocks-in-linked-references when enabled
|
|
-> collect-uuid-refs
|
|
-> uuid-refs/fetch-uuid-entities
|
|
-> resolve-uuid-refs-in-tree-data
|
|
-> render-tree-text-with-properties for human output
|
|
-> sanitize-structured-tree for JSON and EDN output
|
|
```
|
|
|
|
The current page target path in `fetch-tree` pulls a page by `[:block/name page]` and then calls `fetch-tree-for-entity`.
|
|
|
|
The current `fetch-tree-for-entity` treats an entity without `[:block/page :db/id]` as a page and fetches blocks by page id:
|
|
|
|
```text
|
|
fetch-blocks-for-page
|
|
-> :thread-api/q with [?b :block/page ?page-id]
|
|
-> build-tree grouped by [:block/parent :db/id]
|
|
```
|
|
|
|
This is correct for normal page content blocks.
|
|
|
|
This is not enough for `Library` because Library page membership is stored as page entities with `:block/parent` set to the Library page, not as blocks with `:block/page` set to the Library page.
|
|
|
|
The current selectors relevant to `show` are `link-target-selector`, `show-root-selector`, `tree-block-selector`, and `linked-ref-selector`.
|
|
|
|
The current page target selector in the `:page` branch includes `:db/id`, `:db/ident`, `:block/uuid`, `:block/title`, `:logseq.property/deleted-at`, `:logseq.property/status`, and `:block/tags`.
|
|
|
|
The current page target selector does not include `:block/name` or `:logseq.property/built-in?`, which are useful for robust Library detection and structured output consistency.
|
|
|
|
The current `db-worker-node` implementation in `/Users/rcmerci/gh-repos/logseq/src/main/frontend/worker/db_core.cljs` exposes:
|
|
|
|
```text
|
|
:thread-api/pull
|
|
-> Datascript d/pull with a caller-provided selector
|
|
-> common-initial-data/with-parent
|
|
|
|
:thread-api/q
|
|
-> Datascript d/q with caller-provided query and inputs
|
|
|
|
:thread-api/get-block-refs
|
|
-> linked references for a selected entity id
|
|
```
|
|
|
|
The existing APIs can fetch the Library page and its `:block/parent` children, so the first implementation should not add a new thread API.
|
|
|
|
## Library model research
|
|
|
|
The Library page name is defined in `/Users/rcmerci/gh-repos/logseq/deps/common/src/logseq/common/config.cljs`:
|
|
|
|
```clojure
|
|
(defonce library-page-name "Library")
|
|
```
|
|
|
|
New DB graphs create Library as a built-in page in `/Users/rcmerci/gh-repos/logseq/deps/db/src/logseq/db/sqlite/create_graph.cljs`:
|
|
|
|
```text
|
|
built-in-pages-names
|
|
-> includes common-config/library-page-name
|
|
-> build-graph-initial-data creates default pages
|
|
-> mark-block-as-built-in sets :logseq.property/built-in? true
|
|
```
|
|
|
|
A new page created by `/Users/rcmerci/gh-repos/logseq/deps/db/src/logseq/db/sqlite/util.cljs` has the shape:
|
|
|
|
```text
|
|
:block/name = lower-case sanitized title
|
|
:block/title = original title
|
|
:block/uuid = generated from the title for built-in pages when used by graph creation
|
|
:block/tags = #{:logseq.class/Page}
|
|
```
|
|
|
|
The public DB helper aliases in `/Users/rcmerci/gh-repos/logseq/deps/db/src/logseq/db.cljs` include:
|
|
|
|
```text
|
|
ldb/get-built-in-page
|
|
ldb/library?
|
|
ldb/get-library-page
|
|
ldb/page-in-library?
|
|
```
|
|
|
|
The relevant behavior is:
|
|
|
|
```text
|
|
ldb/get-built-in-page db "Library"
|
|
-> looks up the stable built-in UUID generated from the title
|
|
|
|
ldb/library? page
|
|
-> true when the entity is built-in and :block/title is "Library"
|
|
|
|
ldb/page-in-library? db page
|
|
-> follows :block/parent recursively until it reaches the Library page
|
|
```
|
|
|
|
Library membership is therefore represented by `:block/parent`, not by a Library tag or Library property.
|
|
|
|
There is no special `:logseq.class/Library` class and no dedicated Library property.
|
|
|
|
## Desktop App behavior to mirror
|
|
|
|
The Desktop App page rendering path in `/Users/rcmerci/gh-repos/logseq/src/main/frontend/components/page.cljs` detects Library and passes `:library? true` into block rendering:
|
|
|
|
```text
|
|
config = assoc config :library? (ldb/library? block)
|
|
```
|
|
|
|
The same page rendering path adds the Library-specific add-pages UI:
|
|
|
|
```text
|
|
when ldb/library? page
|
|
-> frontend.components.library/add-pages
|
|
```
|
|
|
|
The add-pages component in `/Users/rcmerci/gh-repos/logseq/src/main/frontend/components/library.cljs` searches for existing pages using:
|
|
|
|
```text
|
|
:built-in? false
|
|
:page-only? true
|
|
:library-page-search? true
|
|
```
|
|
|
|
When a page is chosen, the Desktop App moves that page under the Library page by setting `:block/parent` through `editor-handler/move-blocks!`.
|
|
|
|
When a page is unchosen, the Desktop App retracts that page's `:block/parent`.
|
|
|
|
The Library display filter lives in `/Users/rcmerci/gh-repos/logseq/src/main/frontend/components/block.cljs` inside `block-children`.
|
|
|
|
When `:library?` is true, the Desktop App keeps only children that satisfy:
|
|
|
|
```clojure
|
|
(and (ldb/page? child)
|
|
(not (or (ldb/class? child)
|
|
(ldb/property? child))))
|
|
```
|
|
|
|
This means Desktop Library display shows ordinary page entities and hides class/property pages.
|
|
|
|
Because `:library?` is part of the rendering config, the same page-only filtering applies recursively to nested Library page children.
|
|
|
|
Desktop Library display does not render the ordinary content blocks of each child page inside the Library tree.
|
|
|
|
The CLI should mirror those semantics rather than treating Library as a regular page content tree.
|
|
|
|
## Desired CLI behavior
|
|
|
|
`logseq show --page Library` should render the Library root and its Library page hierarchy.
|
|
|
|
The root row should be the built-in `Library` page.
|
|
|
|
Child rows should be direct child page entities whose `:block/parent` points at Library.
|
|
|
|
Nested rows should be child page entities whose `:block/parent` points at another page already displayed in the Library tree.
|
|
|
|
Children should be ordered by `:block/order`, matching the existing block tree ordering convention and Desktop `ldb/sort-by-order` behavior.
|
|
|
|
Children should be filtered with the Desktop Library rule:
|
|
|
|
```text
|
|
show ordinary pages
|
|
hide classes
|
|
hide properties
|
|
hide non-page blocks
|
|
```
|
|
|
|
The Library tree should not include normal page content blocks from child pages.
|
|
|
|
For example, if `Project Alpha` is under Library and has ordinary note blocks on the `Project Alpha` page, then `show --page Library` should show `Project Alpha` as a child page but should not inline `Project Alpha` page content blocks.
|
|
|
|
`--level` should limit the Library page hierarchy just as it limits normal `show` trees.
|
|
|
|
`--output human` should reuse the existing `tree->text` visual format.
|
|
|
|
`--output json` and `--output edn` should expose the same Library tree under `[:data :root]` and `:block/children` without adding human-only labels.
|
|
|
|
`--id <library-db-id>` and `--uuid <library-uuid>` should behave like `--page Library` when the selected entity is the built-in Library page.
|
|
|
|
Normal pages must keep the current `:block/page` content-tree behavior.
|
|
|
|
Normal blocks must keep the current block subtree behavior.
|
|
|
|
Linked block resolution must keep the current behavior.
|
|
|
|
Linked references should keep the current default behavior: if linked references are enabled, fetch references for the rendered Library root id.
|
|
|
|
If the Library page is not found, the command should continue to use the existing page/entity not found errors from the target resolution path.
|
|
|
|
If malformed graph data creates a parent cycle inside the Library hierarchy, the CLI should fail fast with an actionable error instead of recursing indefinitely.
|
|
|
|
## Recommended implementation approach
|
|
|
|
Keep the implementation in `/Users/rcmerci/gh-repos/logseq/src/main/logseq/cli/command/show.cljs`.
|
|
|
|
Do not create a new command or flag.
|
|
|
|
Do not add a new `db-worker-node` thread API for the first implementation.
|
|
|
|
Use existing worker transport calls:
|
|
|
|
```text
|
|
:thread-api/pull
|
|
-> fetch selected page/block entities
|
|
|
|
:thread-api/q
|
|
-> fetch Library child page entities by :block/parent
|
|
|
|
:thread-api/get-block-refs
|
|
-> keep existing linked-reference behavior
|
|
```
|
|
|
|
Add `logseq.common.config` to the show namespace if direct access to `common-config/library-page-name` is clearer than comparing against the string literal.
|
|
|
|
Prefer a small local predicate such as:
|
|
|
|
```text
|
|
library-page? entity
|
|
-> ldb/library? entity
|
|
-> requires :logseq.property/built-in? and :block/title in the pulled entity
|
|
```
|
|
|
|
Avoid adding compatibility fallbacks that treat any page titled `Library` as the special Library page.
|
|
|
|
Library is a built-in page; the implementation should require the built-in marker so a user-created non-built-in page title collision does not silently get special behavior.
|
|
|
|
### Selector changes
|
|
|
|
Add or refactor a page/root selector that includes the fields needed by Library detection and Library rendering:
|
|
|
|
```text
|
|
:db/id
|
|
:db/ident
|
|
:block/name
|
|
:block/uuid
|
|
:block/title
|
|
:logseq.property/built-in?
|
|
:logseq.property/deleted-at
|
|
:logseq.property/status
|
|
:block/tags
|
|
:block/parent
|
|
:block/order
|
|
```
|
|
|
|
The `:block/tags` nested selector must include `:db/ident` because `ldb/page?`, `ldb/class?`, and `ldb/property?` work on tag idents.
|
|
|
|
Use this selector for the page target branch so `ldb/library?` can be evaluated without another round trip.
|
|
|
|
For Library child pulls, use a selector that includes at least:
|
|
|
|
```text
|
|
:db/id
|
|
:db/ident
|
|
:block/name
|
|
:block/uuid
|
|
:block/title
|
|
:block/order
|
|
:logseq.property/built-in?
|
|
{:logseq.property/status [:db/ident :block/title]}
|
|
{:block/parent [:db/id :block/name :block/title :block/uuid]}
|
|
{:block/tags [:db/id :db/ident :block/name :block/title :block/uuid]}
|
|
{:block/link link-target-selector}
|
|
```
|
|
|
|
Keep selectors shallow.
|
|
|
|
Do not try to fetch the entire Library hierarchy through one recursive Datascript pull selector.
|
|
|
|
### Fetching Library children
|
|
|
|
Add a function similar to:
|
|
|
|
```text
|
|
fetch-library-children config repo parent-id
|
|
-> :thread-api/q
|
|
[:find (pull ?child library-child-selector)
|
|
:in $ ?parent-id
|
|
:where [?child :block/parent ?parent-id]]
|
|
-> map first
|
|
-> attach-user-properties if Library page rows should display user properties
|
|
-> filter ordinary Library page children
|
|
-> sort by :block/order
|
|
```
|
|
|
|
Filtering should happen in the CLI after pull so it can reuse `ldb/page?`, `ldb/class?`, and `ldb/property?` against the same pulled map shape used elsewhere.
|
|
|
|
Use `attach-user-properties` for displayed Library child page nodes if the existing `show` contract is that rows can render user properties.
|
|
|
|
If user properties for Library child page rows are not desired, explicitly document and test that Library display mirrors Desktop's hidden properties behavior; however, the lower-risk CLI-consistency default is to preserve the current `show` property rendering behavior for displayed nodes.
|
|
|
|
### Building the Library tree
|
|
|
|
Add a function similar to:
|
|
|
|
```text
|
|
fetch-library-tree-for-entity config repo library-entity max-depth
|
|
-> recursively fetch :block/parent children
|
|
-> filter to ordinary pages, not classes/properties
|
|
-> attach children under :block/children
|
|
-> stop when depth reaches max-depth
|
|
-> guard visited ids to detect cycles
|
|
```
|
|
|
|
Depth should align with `build-tree`:
|
|
|
|
```text
|
|
root depth = 1
|
|
children are omitted when depth >= max-depth
|
|
```
|
|
|
|
A practical recursive shape is:
|
|
|
|
```text
|
|
build-library-node node depth visited
|
|
if node id is already visited
|
|
throw {:code :library-parent-cycle}
|
|
if max-depth and depth >= max-depth
|
|
return node without fetching children
|
|
children = fetch-library-children node-id
|
|
children* = p/all build-library-node child (inc depth) visited*
|
|
assoc node :block/children children* when children* is non-empty
|
|
```
|
|
|
|
Use a clear error code if cycle protection is needed, for example `:library-parent-cycle`.
|
|
|
|
The exact code name can differ, but it should be asserted in tests and should not be swallowed.
|
|
|
|
### Integrating with existing `fetch-tree-for-entity`
|
|
|
|
Route Library before the ordinary page content path:
|
|
|
|
```text
|
|
fetch-tree-for-entity config repo entity max-depth
|
|
if library-page? entity
|
|
fetch-library-tree-for-entity
|
|
else if entity has [:block/page :db/id]
|
|
existing block tree path
|
|
else
|
|
existing normal page tree path
|
|
```
|
|
|
|
This keeps the special behavior scoped to the built-in Library page only.
|
|
|
|
Do not change normal page behavior for pages that happen to have child pages through `:block/parent` unless they are the built-in Library page.
|
|
|
|
### Linked block interaction
|
|
|
|
The current linked-block resolver calls `fetch-tree-for-entity` for the resolved target.
|
|
|
|
Once `fetch-tree-for-entity` knows how to handle Library, a linked block pointing at Library should naturally render the Library tree with the existing linked display marker.
|
|
|
|
Add a targeted test only if this behavior is considered part of the feature contract.
|
|
|
|
Do not add Library-specific logic inside the linked block resolver unless the shared `fetch-tree-for-entity` route is insufficient.
|
|
|
|
### Structured output sanitization
|
|
|
|
The existing structured output path removes `:block/uuid` and `:show/*` internal keys.
|
|
|
|
If new internal keys are added for Library traversal, put them under the `:show/*` namespace so `strip-show-internal-data` removes them automatically.
|
|
|
|
Do not add human-only text such as `Add pages`, `Add existing pages to Library`, or a Library marker to structured output.
|
|
|
|
Do not add translation keys for this CLI behavior; the CLI should render stored graph titles and existing command output, not new shipped UI text.
|
|
|
|
## Implementation steps
|
|
|
|
1. Add Library detection support to `show.cljs`.
|
|
- Require `logseq.common.config` if needed.
|
|
- Ensure the page target selector includes `:block/name` and `:logseq.property/built-in?`.
|
|
- Add a private `library-page?` helper or use `ldb/library?` directly where clear.
|
|
|
|
2. Add Library child fetching.
|
|
- Define a `library-child-selector` or reuse/refactor existing selectors safely.
|
|
- Add `fetch-library-children` backed by `:thread-api/q` and `:block/parent`.
|
|
- Filter using Desktop semantics: `ldb/page?`, not `ldb/class?`, not `ldb/property?`.
|
|
- Sort by `:block/order`.
|
|
|
|
3. Add Library tree building.
|
|
- Add `fetch-library-tree-for-entity` or equivalent.
|
|
- Respect `--level` with the same root-depth convention as `build-tree`.
|
|
- Add cycle protection.
|
|
- Preserve row maps so existing property rendering, tag suffix rendering, UUID ref replacement, and structured-output sanitization still work.
|
|
|
|
4. Wire the special path into `fetch-tree-for-entity`.
|
|
- Check Library before the normal page path.
|
|
- Keep the existing block path and normal page path unchanged.
|
|
|
|
5. Verify linked references and UUID references still run after Library tree construction.
|
|
- No special linked-reference code should be necessary if the root id remains the Library page id.
|
|
- No special UUID-ref code should be necessary if Library child titles/properties are ordinary strings and maps.
|
|
|
|
6. Update CLI documentation only if the implementation changes operator-visible behavior enough to warrant it.
|
|
- Candidate file: `/Users/rcmerci/gh-repos/logseq/docs/cli/logseq-cli.md`.
|
|
- Keep any added prose concise and focused on `show --page Library` displaying Library page hierarchy.
|
|
|
|
7. After implementation and tests, run `logseq-review-workflow`.
|
|
- Apply repository-wide rules.
|
|
- Apply the Logseq CLI module rules.
|
|
- Apply Datascript and Promesa library rules because the change touches Datalog queries and promise composition.
|
|
- Apply DB model rules because the change depends on built-in page identity and `:block/parent` hierarchy semantics.
|
|
|
|
## Testing Plan
|
|
|
|
Implementation should follow @Test-Driven Development.
|
|
|
|
I will add failing execution tests in `/Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/command/show_test.cljs` before implementation.
|
|
|
|
I will add a test proving `show --page Library` renders direct child pages whose `:block/parent` is Library.
|
|
|
|
That test will mock `:thread-api/pull` returning a built-in Library page with `:logseq.property/built-in? true` and `:block/title "Library"`, mock `:thread-api/q` returning child page rows for the Library parent id, execute `show`, strip ANSI, and assert that the output contains `Library` and the child page titles.
|
|
|
|
I will add a test proving `show --page Library` filters children with Desktop semantics.
|
|
|
|
That test will include one ordinary page, one class page tagged `:logseq.class/Tag`, one property page tagged `:logseq.class/Property`, and one non-page block under Library.
|
|
|
|
The assertion will verify that only the ordinary page appears.
|
|
|
|
I will add a test proving nested Library pages render recursively through `:block/parent`.
|
|
|
|
That test will arrange `Library -> Projects -> Alpha` and assert that `Alpha` appears as a child of `Projects`, not as page content.
|
|
|
|
I will add a test proving Library display does not inline ordinary content blocks from child pages.
|
|
|
|
That test will arrange a child page under Library and also arrange ordinary blocks whose `:block/page` is the child page id.
|
|
|
|
The assertion will verify that those page content blocks do not appear in `show --page Library`.
|
|
|
|
I will add a test proving `--level` limits the Library hierarchy.
|
|
|
|
That test will run `show --page Library --level 2` against `Library -> Projects -> Alpha` and assert that `Projects` appears while `Alpha` does not.
|
|
|
|
I will add a test proving `show --id <library-id>` and `show --uuid <library-uuid>` use the same Library display path as `show --page Library`.
|
|
|
|
I will add a structured-output test proving `--output json show --page Library` returns child pages under `[:data :root :block/children]` and does not include non-page, class, or property children.
|
|
|
|
I will add a structured-output test proving no Library traversal internals leak into JSON or EDN output if implementation adds internal keys.
|
|
|
|
I will add a test proving normal page behavior is unchanged.
|
|
|
|
That test will execute `show --page Home` with a regular page entity and assert that the implementation still queries blocks by `:block/page`, renders page content blocks, and does not use the Library child query path.
|
|
|
|
I will add a test proving no new thread API is used.
|
|
|
|
That test can record invoked method keywords and assert that Library display uses only existing methods such as `:thread-api/pull`, `:thread-api/q`, `:thread-api/get-block-refs`, and `:thread-api/get-block-parents` when applicable.
|
|
|
|
I will add a cycle test if the implementation includes explicit Library parent cycle detection.
|
|
|
|
That test will arrange a malformed parent chain such as `Library -> A -> B -> A` and assert that execution rejects with the chosen cycle error code.
|
|
|
|
I will update formatter tests in `/Users/rcmerci/gh-repos/logseq/src/test/logseq/cli/commands_test.cljs` only if the shared `tree->text` formatting contract changes.
|
|
|
|
The preferred implementation should not require formatter changes because Library should produce ordinary tree data consumed by the existing formatter.
|
|
|
|
I will add CLI e2e coverage in `/Users/rcmerci/gh-repos/logseq/cli-e2e/spec/non_sync_cases.edn`.
|
|
|
|
The e2e should create or import a graph with pages under Library, run:
|
|
|
|
```text
|
|
logseq show --graph <graph> --page Library --output human --linked-references false
|
|
```
|
|
|
|
and assert that stdout contains `Library` and the expected Library child page titles.
|
|
|
|
The e2e should assert that stdout does not contain class/property pages that are parented under Library for the fixture, if the fixture can create that shape reliably.
|
|
|
|
Add a JSON e2e assertion for:
|
|
|
|
```text
|
|
logseq show --graph <graph> --page Library --output json --linked-references false
|
|
```
|
|
|
|
and assert the child page title at `[:data :root :block/children 0 :block/title]` or another stable JSON path.
|
|
|
|
If the e2e fixture cannot directly parent pages under Library, use namespace-page creation/import behavior after verifying it creates Library parent relationships in the current graph importer.
|
|
|
|
I will update `/Users/rcmerci/gh-repos/logseq/cli-e2e/spec/non_sync_inventory.edn` if the new e2e cases extend command/option coverage.
|
|
|
|
Before implementation, I will run the new focused tests and expect them to fail.
|
|
|
|
After implementation, I will run:
|
|
|
|
```text
|
|
bb dev:test -v logseq.cli.command.show-test
|
|
```
|
|
|
|
and expect all show command tests to pass.
|
|
|
|
If formatter tests are changed, I will run:
|
|
|
|
```text
|
|
bb dev:test -v logseq.cli.commands-test
|
|
```
|
|
|
|
and expect all command formatter tests to pass.
|
|
|
|
After adding e2e coverage and rebuilding the CLI when needed, I will run the relevant CLI e2e case or suite, for example:
|
|
|
|
```text
|
|
bb -f cli-e2e/bb.edn test --skip-build
|
|
```
|
|
|
|
Before submitting, I will run:
|
|
|
|
```text
|
|
bb dev:lint-and-test
|
|
```
|
|
|
|
when the local environment can support the full test suite.
|
|
|
|
NOTE: I will write all behavior tests before adding implementation code.
|
|
|
|
## Review plan after implementation
|
|
|
|
Run `logseq-review-workflow` after the implementation and tests are complete.
|
|
|
|
The review scope should include every changed file, likely:
|
|
|
|
```text
|
|
src/main/logseq/cli/command/show.cljs
|
|
src/test/logseq/cli/command/show_test.cljs
|
|
src/test/logseq/cli/commands_test.cljs if changed
|
|
cli-e2e/spec/non_sync_cases.edn if changed
|
|
cli-e2e/spec/non_sync_inventory.edn if changed
|
|
docs/cli/logseq-cli.md if changed
|
|
```
|
|
|
|
The review should load and apply:
|
|
|
|
```text
|
|
rules/common.md
|
|
rules/modules/logseq-cli.md
|
|
rules/libraries/clojure-cljs.md
|
|
rules/libraries/datascript.md
|
|
rules/libraries/promesa.md
|
|
rules/modules/db-model.md
|
|
```
|
|
|
|
The review should specifically check:
|
|
|
|
- The implementation did not add a new thread API without a documented necessity.
|
|
- The implementation only special-cases the built-in Library page, not arbitrary pages titled `Library`.
|
|
- Normal `show --page`, `show --id`, `show --uuid`, multi-id, linked block, linked references, property rendering, UUID-ref footer, JSON, and EDN paths still behave as before.
|
|
- Library child filtering matches Desktop semantics: ordinary pages only, excluding classes, properties, and non-page blocks.
|
|
- Library tree building cannot recurse forever on malformed parent cycles.
|
|
- Datascript queries are scoped by parent id and do not scan more data than necessary.
|
|
- Promise composition returns promises consistently and does not accidentally return unresolved nested promises.
|
|
- Structured output does not leak internal traversal metadata.
|
|
- Tests cover behavior and failure modes rather than only implementation details.
|
|
|
|
If the review finds issues, fix them and rerun the focused tests before finalizing the implementation.
|