Skip to content

Commit 3f4d9e4

Browse files
authored
fix: write_note preserves frontmatter fields in content (#84)
1 parent 00c8633 commit 3f4d9e4

2 files changed

Lines changed: 58 additions & 5 deletions

File tree

src/basic_memory/markdown/utils.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from frontmatter import Post
77

8-
from basic_memory.file_utils import has_frontmatter, remove_frontmatter
8+
from basic_memory.file_utils import has_frontmatter, remove_frontmatter, parse_frontmatter
99
from basic_memory.markdown import EntityMarkdown
1010
from basic_memory.models import Entity
1111
from basic_memory.models import Observation as ObservationModel
@@ -74,15 +74,21 @@ async def schema_to_markdown(schema: Any) -> Post:
7474
"""
7575
# Extract content and metadata
7676
content = schema.content or ""
77-
frontmatter_metadata = dict(schema.entity_metadata or {})
77+
entity_metadata = dict(schema.entity_metadata or {})
7878

7979
# if the content contains frontmatter, remove it and merge
8080
if has_frontmatter(content):
81+
content_frontmatter = parse_frontmatter(content)
8182
content = remove_frontmatter(content)
8283

84+
# Merge content frontmatter with entity metadata
85+
# (entity_metadata takes precedence for conflicts)
86+
content_frontmatter.update(entity_metadata)
87+
entity_metadata = content_frontmatter
88+
8389
# Remove special fields for ordered frontmatter
8490
for field in ["type", "title", "permalink"]:
85-
frontmatter_metadata.pop(field, None)
91+
entity_metadata.pop(field, None)
8692

8793
# Create Post with fields ordered by insert order
8894
post = Post(
@@ -94,7 +100,7 @@ async def schema_to_markdown(schema: Any) -> Post:
94100
if schema.permalink:
95101
post.metadata["permalink"] = schema.permalink
96102

97-
if frontmatter_metadata:
98-
post.metadata.update(frontmatter_metadata)
103+
if entity_metadata:
104+
post.metadata.update(entity_metadata)
99105

100106
return post

tests/mcp/test_tool_write_note.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,3 +330,50 @@ async def test_write_note_preserves_custom_metadata(app, test_config):
330330
# And tags should be updated
331331
assert "'#test'" in content
332332
assert "'#updated'" in content
333+
334+
335+
@pytest.mark.asyncio
336+
async def test_write_note_preserves_content_frontmatter(app):
337+
"""Test creating a new note."""
338+
await write_note(
339+
title="Test Note",
340+
folder="test",
341+
content=dedent(
342+
"""
343+
---
344+
title: Test Note
345+
type: note
346+
version: 1.0
347+
author: name
348+
---
349+
# Test
350+
351+
This is a test note
352+
"""
353+
),
354+
tags=["test", "documentation"],
355+
)
356+
357+
# Try reading it back via permalink
358+
content = await read_note("test/test-note")
359+
assert (
360+
dedent(
361+
"""
362+
---
363+
title: Test Note
364+
type: note
365+
permalink: test/test-note
366+
version: 1.0
367+
author: name
368+
tags:
369+
- '#test'
370+
- '#documentation'
371+
---
372+
373+
# Test
374+
375+
This is a test note
376+
"""
377+
).strip()
378+
in content
379+
)

0 commit comments

Comments
 (0)