Skip to content

Commit 3bffb2e

Browse files
committed
Add updated getting started docs and utf8 test
Signed-off-by: phernandez <paul@basicmachines.co>
1 parent 9fe34dc commit 3bffb2e

3 files changed

Lines changed: 255 additions & 21 deletions

File tree

docs/AI Assistant Guide.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ type: note
44
permalink: docs/ai-assistant-guide
55
---
66
> Note: This is an optional document that can be copy/pasted into the project knowledge for an LLM to provide a full description of how it can work with Basic Memory. It is provided as a helpful resource. The tools contain extensive usage description prompts with enable the LLM to understand them.
7+
8+
You can [download](https://github.com/basicmachines-co/basic-memory/blob/main/docs/AI%20Assistant%20Guide.md) the contents of this file from GitHub
79
# AI Assistant Guide for Basic Memory
810

911
This guide helps you, the AI assistant, use Basic Memory tools effectively when working with users. It covers reading, writing, and navigating knowledge through the Model Context Protocol (MCP).

docs/Getting Started with Basic Memory.md

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ It can be used with any service that supports the MCP, but Claude Desktop works
1414

1515
## Installation
1616

17+
### Prerequisites
18+
19+
The easiest way to install basic memory is via `uv`. See the [uv installation guide](https://docs.astral.sh/uv/getting-started/installation/).
20+
1721
### 1. Install Basic Memory
1822

1923
```bash
@@ -26,14 +30,32 @@ pip install basic-memory
2630

2731
> **Important**: You need to install Basic Memory using one of the commands above to use the command line tools.
2832
29-
Using `uv tool install` will install the basic-memory package in a standalone virtual environment.
30-
See the [UV docs](https://docs.astral.sh/uv/concepts/tools/) for more info.
33+
Using `uv tool install` will install the basic-memory package in a standalone virtual environment. See the [UV docs](https://docs.astral.sh/uv/concepts/tools/) for more info.
3134

3235
### 2. Configure Claude Desktop
3336

34-
Claude Desktop often has trouble finding executables in your user path. Follow these steps for a reliable setup:
37+
Edit your Claude Desktop config, located at `~/Library/Application Support/Claude/claude_desktop_config.json`:
38+
39+
```json
40+
{
41+
"mcpServers": {
42+
"basic-memory": {
43+
"command": "uvx",
44+
"args": [
45+
"basic-memory",
46+
"mcp"
47+
]
48+
}
49+
}
50+
}
51+
```
52+
53+
**Restart Claude Desktop**. You should see Basic Memory tools available in the "tools" menu in Claude Desktop (the little hammer icon in the bottom-right corner of the chat interface). Click it to view available tools.
54+
#### Fix Path to uv
55+
56+
If you get an error that says `ENOENT` , this most likely means Claude Desktop could not find your `uv` installation. Make sure that you have `uv` installed per the instructions above, then:
3557

36-
#### Step 1: Find the absolute path to uvx
58+
**Step 1: Find the absolute path to uvx**
3759

3860
Open Terminal and run:
3961

@@ -43,9 +65,9 @@ which uvx
4365

4466
This will show you the full path (e.g., `/Users/yourusername/.cargo/bin/uvx`).
4567

46-
#### Step 2: Edit Claude Desktop Configuration
68+
**Step 2: Edit Claude Desktop Configuration**
4769

48-
Edit the configuration file located at `~/Library/Application Support/Claude/claude_desktop_config.json`:
70+
Edit the Claude Desktop config:
4971

5072
```json
5173
{
@@ -63,14 +85,14 @@ Edit the configuration file located at `~/Library/Application Support/Claude/cla
6385

6486
Replace `/absolute/path/to/uvx` with the actual path you found in Step 1.
6587

66-
> **Note**: Using absolute paths is necessary because Claude Desktop cannot access binaries in your user PATH.
67-
68-
#### Step 3: Restart Claude Desktop
88+
**Step 3: Restart Claude Desktop**
6989

7090
Close and reopen Claude Desktop for the changes to take effect.
7191

7292
### 3. Start the Sync Service
7393

94+
> Note the sync service is optional. You can run it if you want your local change to be available in Claude Desktop
95+
7496
Start the sync service to monitor your files for changes:
7597

7698
```bash
@@ -81,7 +103,7 @@ basic-memory sync
81103
basic-memory sync --watch
82104
```
83105

84-
The `--watch` flag enables automatic detection of file changes, keeping your knowledge base current.
106+
The `--watch` flag enables automatic detection of file changes, updating your knowledge in real time.
85107

86108
### 4. Staying Updated
87109

@@ -97,6 +119,21 @@ pip install --upgrade basic-memory
97119

98120
> **Note**: After updating, you'll need to restart Claude Desktop and your sync process for changes to take effect.
99121
122+
### 5. Change the default project directory
123+
124+
By default, Basic Memory will create a project in the `basic-memory` folder in your home directory. You can change this via the `project` [[CLI Reference#project|cli command]].
125+
126+
```
127+
# Add a new project
128+
basic-memory project add work ~/work-basic-memory
129+
130+
# Set the default project
131+
basic-memory project default work
132+
133+
# List all configured projects
134+
basic-memory project list
135+
```
136+
100137
## Troubleshooting Installation
101138

102139
### Common Issues
@@ -119,30 +156,24 @@ If you encounter permission errors:
119156

120157
## Creating Your First Knowledge Note
121158

122-
1. **Start the sync process** in a Terminal window:
123-
```bash
124-
basic-memory sync --watch
125-
```
126-
Keep this running in the background.
159+
1. **Open Claude Desktop** and start a new conversation.
127160

128-
2. **Open Claude Desktop** and start a new conversation.
129-
130-
3. **Have a natural conversation** about any topic:
161+
2. **Have a natural conversation** about any topic:
131162
```
132163
You: "Let's talk about coffee brewing methods I've been experimenting with."
133164
Claude: "I'd be happy to discuss coffee brewing methods..."
134165
You: "I've found that pour over gives more flavor clarity than French press..."
135166
```
136167

137-
4. **Ask Claude to create a note**:
168+
3. **Ask Claude to create a note**:
138169
```
139170
You: "Could you create a note summarizing what we've discussed about coffee brewing?"
140171
```
141172

142-
5. **Confirm note creation**:
173+
4. **Confirm note creation**:
143174
Claude will confirm when the note has been created and where it's stored.
144175

145-
6. **View the created file** in your `~/basic-memory` directory using any text editor or Obsidian.
176+
5. **View the created file** in your `~/basic-memory` directory using any text editor or Obsidian.
146177
The file structure will look similar to:
147178
```markdown
148179
---
@@ -160,6 +191,12 @@ If you encounter permission errors:
160191
- relates_to [[Other Coffee Topics]]
161192
```
162193

194+
5. **Start the sync process** in a Terminal window (optional):
195+
```bash
196+
basic-memory sync --watch
197+
```
198+
Keep this running in the background.
199+
163200
## Using Special Prompts
164201

165202
Basic Memory includes special prompts that help you start conversations with context from your knowledge base:

tests/utils/test_utf8_handling.py

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
"""Test UTF-8 character handling in file operations."""
2+
3+
import pytest
4+
5+
from basic_memory import file_utils
6+
from basic_memory.file_utils import write_file_atomic, compute_checksum
7+
8+
9+
@pytest.mark.asyncio
10+
async def test_write_utf8_characters(tmp_path):
11+
"""Test writing files with UTF-8 characters."""
12+
# Create a test file with various UTF-8 characters
13+
test_path = tmp_path / "utf8_test.md"
14+
15+
# Include characters from various scripts
16+
utf8_content = """# UTF-8 Test Document
17+
18+
## Cyrillic
19+
Привет мир! (Hello world in Russian)
20+
21+
## Greek
22+
Γειά σου Κόσμε! (Hello world in Greek)
23+
24+
## Chinese
25+
你好世界! (Hello world in Chinese)
26+
27+
## Japanese
28+
こんにちは世界! (Hello world in Japanese)
29+
30+
## Arabic
31+
مرحبا بالعالم! (Hello world in Arabic)
32+
33+
## Emoji
34+
🌍 🌎 🌏 🌐 🗺️ 🧭
35+
"""
36+
37+
# Test the atomic write function with UTF-8 content
38+
await write_file_atomic(test_path, utf8_content)
39+
40+
# Verify the file was written correctly
41+
assert test_path.exists()
42+
43+
# Read the file back and verify content
44+
content = test_path.read_text(encoding="utf-8")
45+
assert "Привет мир!" in content
46+
assert "Γειά σου Κόσμε!" in content
47+
assert "你好世界" in content
48+
assert "こんにちは世界" in content
49+
assert "مرحبا بالعالم" in content
50+
assert "🌍 🌎 🌏" in content
51+
52+
# Verify checksums match
53+
checksum1 = await compute_checksum(utf8_content)
54+
checksum2 = await compute_checksum(content)
55+
assert checksum1 == checksum2
56+
57+
58+
@pytest.mark.asyncio
59+
async def test_frontmatter_with_utf8(tmp_path):
60+
"""Test handling of frontmatter with UTF-8 characters."""
61+
# Create a test file with frontmatter containing UTF-8
62+
test_path = tmp_path / "frontmatter_utf8.md"
63+
64+
# Create content with UTF-8 in frontmatter
65+
content = """---
66+
title: UTF-8 测试文件 (Test File)
67+
author: José García
68+
keywords:
69+
- тестирование
70+
- 테스트
71+
- 测试
72+
---
73+
74+
# UTF-8 Support Test
75+
76+
This file has UTF-8 characters in the frontmatter.
77+
"""
78+
79+
# Write the file
80+
await write_file_atomic(test_path, content)
81+
82+
# Update frontmatter with more UTF-8
83+
await file_utils.update_frontmatter(
84+
test_path,
85+
{
86+
"description": "这是一个测试文件 (This is a test file)",
87+
"tags": ["国际化", "юникод", "🔤"],
88+
},
89+
)
90+
91+
# Read back and check
92+
updated_content = test_path.read_text(encoding="utf-8")
93+
94+
# Original values should be preserved
95+
assert "title: UTF-8 测试文件" in updated_content
96+
assert "author: José García" in updated_content
97+
98+
# New values should be added
99+
assert "description: 这是一个测试文件" in updated_content
100+
assert "国际化" in updated_content
101+
assert "юникод" in updated_content
102+
assert "🔤" in updated_content
103+
104+
105+
@pytest.mark.asyncio
106+
async def test_utf8_in_entity_sync(sync_service, test_config):
107+
"""Test syncing an entity with UTF-8 content."""
108+
project_dir = test_config.home
109+
110+
# Create a test file with UTF-8 characters
111+
test_file = project_dir / "utf8_entity.md"
112+
utf8_content = """---
113+
type: knowledge
114+
permalink: i18n/utf8-document
115+
---
116+
# UTF-8 测试文档
117+
118+
## Observations
119+
- [language] العربية (Arabic) is written right-to-left
120+
- [language] 日本語 (Japanese) uses three writing systems
121+
- [encoding] UTF-8 可以编码所有 Unicode 字符
122+
123+
## Relations
124+
- relates_to [[i18n/Ελληνικά]]
125+
- relates_to [[i18n/Русский]]
126+
"""
127+
128+
# Write the file
129+
test_file.parent.mkdir(parents=True, exist_ok=True)
130+
test_file.write_text(utf8_content, encoding="utf-8")
131+
132+
# Sync the file
133+
await sync_service.sync(test_config.home, show_progress=False)
134+
135+
# Verify entity was created
136+
entity = await sync_service.entity_service.get_by_permalink("i18n/utf8-document")
137+
assert entity is not None
138+
139+
# Verify observations were created with UTF-8 content
140+
assert len(entity.observations) == 3
141+
142+
# Check observation content
143+
obs_categories = [o.category for o in entity.observations]
144+
obs_content = [o.content for o in entity.observations]
145+
146+
assert "language" in obs_categories
147+
assert "encoding" in obs_categories
148+
assert any("العربية" in c for c in obs_content)
149+
assert any("日本語" in c for c in obs_content)
150+
assert any("Unicode" in c for c in obs_content)
151+
152+
# Check relations
153+
assert len(entity.relations) == 2
154+
relation_names = [r.to_name for r in entity.relations]
155+
assert "i18n/Ελληνικά" in relation_names
156+
assert "i18n/Русский" in relation_names
157+
158+
159+
@pytest.mark.asyncio
160+
async def test_write_file_service_utf8(sync_service, test_config):
161+
"""Test FileService handling of UTF-8 content."""
162+
file_service = sync_service.file_service
163+
164+
# Test writing UTF-8 content through the file service
165+
test_path = "utf8_service_test.md"
166+
utf8_content = """---
167+
title: FileService UTF-8 Test
168+
---
169+
# UTF-8 通过 FileService 测试
170+
171+
Testing FileService with UTF-8:
172+
* Português: Olá mundo!
173+
* Thai: สวัสดีชาวโลก
174+
* Korean: 안녕하세요 세계
175+
* Hindi: नमस्ते दुनिया
176+
"""
177+
178+
# Use the file service to write the file
179+
checksum = await file_service.write_file(test_path, utf8_content)
180+
181+
# Verify file exists
182+
full_path = file_service.base_path / test_path
183+
assert full_path.exists()
184+
185+
# Read back content and verify
186+
content, read_checksum = await file_service.read_file(test_path)
187+
188+
assert "通过" in content
189+
assert "Português" in content
190+
assert "สวัสดีชาวโลก" in content
191+
assert "안녕하세요" in content
192+
assert "नमस्ते" in content
193+
194+
# Checksums should match
195+
assert checksum == read_checksum

0 commit comments

Comments
 (0)