032-logseq-cli-show-property-key-bold.md

This commit is contained in:
rcmerci
2026-02-08 20:52:12 +08:00
parent 4c10100aa6
commit 0b377364ae
4 changed files with 163 additions and 10 deletions

View File

@@ -0,0 +1,119 @@
# Logseq CLI Show Property Key Bold Implementation Plan
Goal: Make `<property-key>` render in bold in `show` human output while keeping the existing `property-kvs` layout and values unchanged.
Architecture: Keep db-worker-node data fetching and property title resolution unchanged, and only add styling at the final text rendering layer in `logseq.cli.command.show`.
Tech Stack: ClojureScript, logseq-cli show renderer, db-worker-node transport/thread-api, cljs.test.
Related: Relates to `docs/agent-guide/029-logseq-cli-show-properties.md` and `docs/agent-guide/023-logseq-cli-help-show-styling.md`.
## Problem statement
The current `show` human output prints property lines as plain text in the form `<property-key>: <property-value>`.
`property-kvs` are already rendered in the correct position and indentation under each block, but `<property-key>` does not have visual emphasis.
The requested behavior is to bold only `<property-key>` while preserving `:`, value text, multiline/list formatting, and tree alignment.
Because logseq-cli `show` depends on db-worker-node data, this change must not alter db-worker-node API contracts, pull results, or non-human output formats.
## Testing Plan
I will add a unit test that verifies a single-value property line styles only the property key with ANSI bold when color is enabled.
I will add a unit test that verifies multi-value property blocks style the property key heading in bold while list item rows remain non-bold.
I will update existing property rendering tests to keep `strip-ansi` expectations unchanged so layout behavior is locked.
I will add a format-level test to ensure human `show` output preserves the new bold key styling through `format/format-result`.
I will run one integration test for show properties to confirm db-worker-node end-to-end behavior remains unchanged after ANSI stripping.
NOTE: I will write *all* tests before I add any implementation behavior.
## Scope and non-goals
In scope is styling `<property-key>` in human output generated by `show`.
Out of scope is changing property query logic, property sorting rules, property value normalization, and db-worker-node request/response schemas.
Out of scope is any change to JSON or EDN output.
## Files to touch
| File path | Purpose |
| --- | --- |
| `src/main/logseq/cli/command/show.cljs` | Apply bold style to `<property-key>` in property line formatter only. |
| `src/test/logseq/cli/commands_test.cljs` | Add renderer-focused tests for ANSI bold presence and unchanged stripped layout. |
| `src/test/logseq/cli/format_test.cljs` | Verify formatted human output keeps bold property-key styling. |
| `src/test/logseq/cli/integration_test.cljs` | Confirm end-to-end show property output remains stable after strip-ansi. |
## Implementation plan
1. Follow `@test-driven-development` and `@prompts/review.md` before code edits.
2. Add failing renderer unit tests in `src/test/logseq/cli/commands_test.cljs` for bold `<property-key>` in single and multi-value property output.
3. Run targeted tests and confirm they fail for missing styling behavior and not for test setup errors.
4. Update `format-property-lines` in `src/main/logseq/cli/command/show.cljs` to wrap only the property title segment with `style/bold`.
5. Keep `indent`, colon placement, and value rendering unchanged so current tree alignment remains intact.
6. Add or update `src/test/logseq/cli/format_test.cljs` to ensure `format/format-result` does not strip the new bold style in human output.
7. Run targeted unit tests again and confirm all new assertions pass.
8. Run the existing integration test that covers show properties and confirm stripped output still matches the same textual content.
9. Run full lint and unit test suite for regression coverage.
## Verification commands
```bash
bb dev:test -v 'logseq.cli.commands-test/test-tree->text-renders-properties-single-value'
bb dev:test -v 'logseq.cli.commands-test/test-tree->text-renders-properties-multi-value'
bb dev:test -v 'logseq.cli.format-test/test-human-output-show'
bb dev:test -v 'logseq.cli.integration-test/test-cli-show-properties-human-output'
bb dev:lint-and-test
```
Expected outcome is that new property-key bold tests pass, pre-existing strip-ansi assertions remain unchanged, integration behavior remains stable, and the full lint/test command exits successfully.
## Edge cases
When color is disabled, output should remain plain text and still include `<property-key>: <property-value>` with no ANSI codes.
For multiline block titles, property-key bold styling must not shift spacing or tree glyph alignment.
For multi-value properties, only the heading key line should be bold and bullet item values should remain unchanged.
If a property title is missing or blank, existing skip behavior should remain unchanged.
## Rollout and risk
Risk is low because the change is limited to a string formatting helper used only by human output.
The main regression risk is accidental styling leakage into values or alignment shifts caused by ANSI code placement.
This risk is controlled by preserving existing strip-ansi golden assertions and adding explicit ANSI presence tests.
## Testing Details
The tests verify behavior at three levels, which are renderer output, formatter passthrough, and db-worker-node integration stability.
Renderer tests assert exact ANSI bold placement around property keys and unchanged plain text after stripping ANSI.
Formatter tests confirm human output still carries ANSI styling while JSON and EDN behavior is unchanged.
Integration coverage confirms end-to-end property visibility still works with the same stripped output content.
## Implementation Details
- Reuse `logseq.cli.style/bold` instead of introducing a new styling helper.
- Change only `format-property-lines` and avoid modifying property discovery helpers.
- Keep sorted property order logic exactly as-is.
- Keep `property-value->string` and `normalize-property-values` untouched.
- Preserve the existing list format for multi-value properties.
- Preserve root and child indentation prefixes from `tree->text`.
- Avoid any db-worker-node API or transport changes.
- Ensure ANSI checks in tests use existing helpers like `style/strip-ansi` or regex.
- Keep all JSON and EDN output paths unchanged.
## Question
Only the heading key should be considered the full `<property-key>` target, so `Criteria` should be bold while `- One` and `- Two` should remain non-bold.
---

View File

@@ -232,12 +232,13 @@
(defn- format-property-lines
[indent title values]
(when (seq values)
(if (= 1 (count values))
[(str indent title ": " (first values))]
(let [item-indent (str indent " ")]
(into [(str indent title ":")]
(map #(str item-indent "- " %) values))))))
(let [title* (style/bold title)]
(when (seq values)
(if (= 1 (count values))
[(str indent title* ": " (first values))]
(let [item-indent (str indent " ")]
(into [(str indent title* ":")]
(map #(str item-indent "- " %) values)))))))
(defn- node-property-lines
[node property-titles property-value-labels indent]

View File

@@ -386,6 +386,7 @@
:property-titles {:user.property/background "Background"}}
output (binding [style/*color-enabled?* true]
(tree->text tree-data))]
(is (contains-bold? output "Background"))
(is (= (str "1 Root\n"
"2 ├── Child A\n"
" │ Background: Because\n"
@@ -406,6 +407,9 @@
:property-titles {:user.property/criteria "Criteria"}}
output (binding [style/*color-enabled?* true]
(tree->text tree-data))]
(is (contains-bold? output "Criteria"))
(is (not (contains-bold? output "- One")))
(is (not (contains-bold? output "- Two")))
(is (= (str "1 Root\n"
"2 ├── Child A\n"
" │ Criteria:\n"
@@ -459,10 +463,11 @@
:user.property/background "Child"}
:property-titles {:user.property/background "Background"}}
output (binding [style/*color-enabled?* true]
(tree->text tree-data))]
(is (string/includes? output "Background: Child"))
(is (not (string/includes? output "└── Child")))
(is (not (string/includes? output "── Child"))))))
(tree->text tree-data))
output* (strip-ansi output)]
(is (string/includes? output* "Background: Child"))
(is (not (string/includes? output* "── Child")))
(is (not (string/includes? output* "├── Child"))))))
(deftest test-tree->text-prefixes-status
(testing "show tree text prefixes status before block titles"

View File

@@ -243,6 +243,34 @@
"2 └── TODO Child #TagA")
(style/strip-ansi result))))))
(deftest test-human-output-show-styled-property-keys
(testing "show preserves styled property keys in human output"
(let [tree->text #'show-command/tree->text
tree-data {:root {:db/id 1
:block/title "Root"
:block/children [{:db/id 2
:block/title "Child"
:user.property/acceptance-criteria ["One" "Two"]}
{:db/id 3
:block/title "Sibling"}]}
:property-titles {:user.property/acceptance-criteria "Acceptance Criteria"}}
styled (binding [style/*color-enabled?* true]
(tree->text tree-data))
result (format/format-result {:status :ok
:command :show
:data {:message styled}}
{:output-format nil})]
(is (re-find #"\u001b\[[0-9;]*mAcceptance Criteria\u001b\[[0-9;]*m" result))
(is (not (re-find #"\u001b\[[0-9;]*m- One\u001b\[[0-9;]*m" result)))
(is (not (re-find #"\u001b\[[0-9;]*m- Two\u001b\[[0-9;]*m" result)))
(is (= (str "1 Root\n"
"2 ├── Child\n"
" │ Acceptance Criteria:\n"
" │ - One\n"
" │ - Two\n"
"3 └── Sibling")
(style/strip-ansi result))))))
(deftest test-human-output-show-preserves-styling
(testing "show returns styled text without stripping ANSI"
(let [tree->text #'show-command/tree->text