From a5114aec83e5e578f845431e402122afd0df8b3e Mon Sep 17 00:00:00 2001 From: Drew Cain Date: Fri, 12 Jun 2026 10:56:36 -0500 Subject: [PATCH] fix(cli): trim frontmatter-strip newlines in plain read-note body The API content field keeps the blank line left by frontmatter stripping; plain print() rendered it as a double gap under the header. JSON mode stays byte-faithful. Co-Authored-By: Claude Signed-off-by: Drew Cain --- src/basic_memory/cli/commands/tool.py | 7 +++++-- tests/cli/test_cli_tool_rich_output.py | 10 ++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/basic_memory/cli/commands/tool.py b/src/basic_memory/cli/commands/tool.py index bf12f91b..8fe60a29 100644 --- a/src/basic_memory/cli/commands/tool.py +++ b/src/basic_memory/cli/commands/tool.py @@ -401,8 +401,11 @@ def _plain_read_note(result: dict[str, Any], *, include_frontmatter: bool = Fals print(f"{key}: {value}") print() - if content: - print(content) + # The API's content field keeps the blank line left by frontmatter + # stripping; trim newlines so the header gap stays a single blank line. + body = content.strip("\n") if content else "" + if body: + print(body) else: print("(no content)") diff --git a/tests/cli/test_cli_tool_rich_output.py b/tests/cli/test_cli_tool_rich_output.py index 608296ed..0ec65eff 100644 --- a/tests/cli/test_cli_tool_rich_output.py +++ b/tests/cli/test_cli_tool_rich_output.py @@ -23,7 +23,8 @@ READ_NOTE_RESULT = { "title": "Test Note", "permalink": "notes/test-note", "file_path": "notes/Test Note.md", - "content": "# Test Note\n\nhello world", + # Real payloads keep the leading newline left by frontmatter stripping. + "content": "\n# Test Note\n\nhello world", "frontmatter": {"title": "Test Note", "tags": ["test"]}, } @@ -263,7 +264,9 @@ def test_read_note_json_flag_overrides_tty(mock_mcp): assert result.exit_code == 0, f"CLI failed: {result.output}" data = json.loads(result.output) assert data["title"] == "Test Note" - assert data["content"] == "# Test Note\n\nhello world" + # JSON mode is byte-faithful: the payload's leading newline (frontmatter-strip + # artifact) is preserved here even though display modes trim it. + assert data["content"] == "\n# Test Note\n\nhello world" @patch( @@ -747,6 +750,9 @@ def test_read_note_plain_output(mock_mcp): assert "hello world" in result.output # No frontmatter without the flag assert "tags:" not in result.output + # Exactly one blank line between header and body: the payload's leading + # newline (frontmatter-strip artifact) must not stack with the renderer's. + assert "Test Note [notes/test-note]\n\n# Test Note" in result.output @patch(