Skip to content

Commit 896138b

Browse files
authored
Merge branch 'main' into fix-issue-71-20250406012335
2 parents 3d55674 + 248214c commit 896138b

File tree

5 files changed

+120
-8
lines changed

5 files changed

+120
-8
lines changed

.github/workflows/test.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ on:
55
branches: [ "main" ]
66
pull_request:
77
branches: [ "main" ]
8+
# pull_request_target runs on the BASE of the PR, not the merge result.
9+
# It has write permissions and access to secrets.
10+
# It's useful for PRs from forks or automated PRs but requires careful use for security reasons.
11+
# See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target
12+
pull_request_target:
13+
branches: [ "main" ]
814

915
jobs:
1016
test:

README.md

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ Basic Memory lets you build persistent knowledge through natural conversations w
1313
Claude, while keeping everything in simple Markdown files on your computer. It uses the Model Context Protocol (MCP) to
1414
enable any compatible LLM to read and write to your local knowledge base.
1515

16-
- Website: http://basicmachines.co
17-
- Documentation: http://memory.basicmachines.co
16+
- Website: https://basicmachines.co
17+
- Documentation: https://memory.basicmachines.co
1818

1919
## Pick up your conversation right where you left off
2020

@@ -262,6 +262,43 @@ Examples of relations:
262262
- documented_in [[Coffee Journal]]
263263
```
264264

265+
## Using with VS Code
266+
For one-click installation, click one of the install buttons below...
267+
268+
[![Install with UV in VS Code](https://img.shields.io/badge/VS_Code-UV-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=basic-memory&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22basic-memory%22%2C%22mcp%22%5D%7D) [![Install with UV in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-UV-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=basic-memory&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22basic-memory%22%2C%22mcp%22%5D%7D&quality=insiders)
269+
270+
You can use Basic Memory with VS Code to easily retrieve and store information while coding. Click the installation buttons above for one-click setup, or follow the manual installation instructions below.
271+
272+
### Manual Installation
273+
274+
Add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open User Settings (JSON)`.
275+
276+
```json
277+
{
278+
"mcp": {
279+
"servers": {
280+
"basic-memory": {
281+
"command": "uvx",
282+
"args": ["basic-memory", "mcp"]
283+
}
284+
}
285+
}
286+
}
287+
```
288+
289+
Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
290+
291+
```json
292+
{
293+
"servers": {
294+
"basic-memory": {
295+
"command": "uvx",
296+
"args": ["basic-memory", "mcp"]
297+
}
298+
}
299+
}
300+
```
301+
265302
## Using with Claude Desktop
266303

267304
Basic Memory is built using the MCP (Model Context Protocol) and works with the Claude desktop app (https://claude.ai/):

src/basic_memory/mcp/server.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
from mcp.server.fastmcp.utilities.logging import configure_logging
55

66
# mcp console logging
7-
configure_logging(level="INFO")
7+
configure_logging(level="ERROR")
88

99

1010
# Create the shared server instance
11-
mcp = FastMCP("Basic Memory")
11+
mcp = FastMCP("Basic Memory", log_level="ERROR")

src/basic_memory/sync/sync_service.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,18 +362,25 @@ async def sync_markdown_file(self, path: str, new: bool = True) -> Tuple[Optiona
362362
# Update relations and search index
363363
entity = await self.entity_service.update_entity_relations(path, entity_markdown)
364364

365+
# After updating relations, we need to compute the checksum again
366+
# This is necessary for files with wikilinks to ensure consistent checksums
367+
# after relation processing is complete
368+
final_checksum = await self.file_service.compute_checksum(path)
369+
365370
# set checksum
366-
await self.entity_repository.update(entity.id, {"checksum": checksum})
367-
371+
await self.entity_repository.update(entity.id, {"checksum": final_checksum})
372+
368373
logger.debug(
369374
"Markdown sync completed",
370375
path=path,
371376
entity_id=entity.id,
372377
observation_count=len(entity.observations),
373378
relation_count=len(entity.relations),
379+
checksum=final_checksum,
374380
)
375-
376-
return entity, checksum
381+
382+
# Return the final checksum to ensure everything is consistent
383+
return entity, final_checksum
377384

378385
async def sync_regular_file(self, path: str, new: bool = True) -> Tuple[Optional[Entity], str]:
379386
"""Sync a non-markdown file with basic tracking.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
"""Test for issue #72 - notes with wikilinks staying in modified status."""
2+
3+
import pytest
4+
from pathlib import Path
5+
6+
from basic_memory.sync.sync_service import SyncService
7+
8+
9+
async def create_test_file(path: Path, content: str) -> None:
10+
"""Create a test file with given content."""
11+
path.parent.mkdir(parents=True, exist_ok=True)
12+
path.write_text(content)
13+
14+
15+
@pytest.mark.asyncio
16+
async def test_wikilink_modified_status_issue(sync_service: SyncService, test_config):
17+
"""Test that files with wikilinks don't remain in modified status after sync."""
18+
project_dir = test_config.home
19+
20+
# Create a file with a wikilink
21+
content = """---
22+
title: Test Wikilink
23+
type: note
24+
---
25+
# Test File
26+
27+
This file contains a wikilink to [[another-file]].
28+
"""
29+
test_file_path = project_dir / "test_wikilink.md"
30+
await create_test_file(test_file_path, content)
31+
32+
# Initial sync
33+
report1 = await sync_service.sync(test_config.home, show_progress=False)
34+
assert "test_wikilink.md" in report1.new
35+
assert "test_wikilink.md" not in report1.modified
36+
37+
# Sync again without changing the file - should not be modified
38+
report2 = await sync_service.sync(test_config.home, show_progress=False)
39+
assert "test_wikilink.md" not in report2.new
40+
assert "test_wikilink.md" not in report2.modified
41+
42+
# Create the target file
43+
target_content = """---
44+
title: Another File
45+
type: note
46+
---
47+
# Another File
48+
49+
This is the target file.
50+
"""
51+
target_file_path = project_dir / "another_file.md"
52+
await create_test_file(target_file_path, content)
53+
54+
# Sync again after adding target file
55+
report3 = await sync_service.sync(test_config.home, show_progress=False)
56+
assert "another_file.md" in report3.new
57+
assert "test_wikilink.md" not in report3.modified
58+
59+
# Sync one more time - both files should now be stable
60+
report4 = await sync_service.sync(test_config.home, show_progress=False)
61+
assert "test_wikilink.md" not in report4.modified
62+
assert "another_file.md" not in report4.modified

0 commit comments

Comments
 (0)