diff --git a/docs/agent-guide/032-logseq-cli-show-property-key-bold.md b/docs/agent-guide/032-logseq-cli-show-property-key-bold.md new file mode 100644 index 0000000000..703f9a84d5 --- /dev/null +++ b/docs/agent-guide/032-logseq-cli-show-property-key-bold.md @@ -0,0 +1,119 @@ +# Logseq CLI Show Property Key Bold Implementation Plan + +Goal: Make `` 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-kvs` are already rendered in the correct position and indentation under each block, but `` does not have visual emphasis. + +The requested behavior is to bold only `` 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 `` 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 `` 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 `` 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 `: ` 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 `` target, so `Criteria` should be bold while `- One` and `- Two` should remain non-bold. + +--- diff --git a/src/main/logseq/cli/command/show.cljs b/src/main/logseq/cli/command/show.cljs index 95c7d72c5f..a22aebdd2c 100644 --- a/src/main/logseq/cli/command/show.cljs +++ b/src/main/logseq/cli/command/show.cljs @@ -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] diff --git a/src/test/logseq/cli/commands_test.cljs b/src/test/logseq/cli/commands_test.cljs index 7f19013492..4fa96bcbad 100644 --- a/src/test/logseq/cli/commands_test.cljs +++ b/src/test/logseq/cli/commands_test.cljs @@ -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" diff --git a/src/test/logseq/cli/format_test.cljs b/src/test/logseq/cli/format_test.cljs index 9da6987cb3..bfd3aec065 100644 --- a/src/test/logseq/cli/format_test.cljs +++ b/src/test/logseq/cli/format_test.cljs @@ -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