Skip to content

Commit ab6cf74

Browse files
authored
Merge pull request #26 from basicmachines-co/claw/bm-setup-command
feat: add /bm-setup slash command
2 parents e946894 + 82375b6 commit ab6cf74

File tree

4 files changed

+73
-0
lines changed

4 files changed

+73
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ All tools accept an optional `project` parameter for cross-project operations.
152152

153153
| Command | Description |
154154
|---------|-------------|
155+
| `/bm-setup` | Install or update the Basic Memory CLI |
155156
| `/remember <text>` | Save a quick note |
156157
| `/recall <query>` | Search the knowledge graph |
157158
| `/tasks [args]` | Create, track, resume structured tasks |

commands/slash.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,43 @@
1+
import { execSync } from "node:child_process"
2+
import { dirname, resolve } from "node:path"
3+
import { fileURLToPath } from "node:url"
14
import type { OpenClawPluginApi } from "openclaw/plugin-sdk"
25
import type { BmClient } from "../bm-client.ts"
36
import { log } from "../logger.ts"
47

8+
const __dirname = dirname(fileURLToPath(import.meta.url))
9+
510
export function registerCommands(
611
api: OpenClawPluginApi,
712
client: BmClient,
813
): void {
14+
api.registerCommand({
15+
name: "bm-setup",
16+
description: "Install or update the Basic Memory CLI (requires uv)",
17+
requireAuth: true,
18+
handler: async () => {
19+
const scriptPath = resolve(__dirname, "..", "scripts", "setup-bm.sh")
20+
log.info(`/bm-setup: running ${scriptPath}`)
21+
22+
try {
23+
const output = execSync(`bash "${scriptPath}"`, {
24+
encoding: "utf-8",
25+
timeout: 180_000,
26+
stdio: "pipe",
27+
env: { ...process.env },
28+
})
29+
return { text: output.trim() }
30+
} catch (err: unknown) {
31+
const execErr = err as { stderr?: string; stdout?: string }
32+
const detail = execErr.stderr || execErr.stdout || String(err)
33+
log.error("/bm-setup failed", err)
34+
return {
35+
text: `Setup failed:\n${detail.trim()}`,
36+
}
37+
}
38+
},
39+
})
40+
941
api.registerCommand({
1042
name: "remember",
1143
description: "Save something to the Basic Memory knowledge graph",

skills/memory-notes/SKILL.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,28 @@ edit_note(
248248
6. **Link related concepts.** The value of a knowledge graph compounds with connections. A note with zero relations is an island — useful, but not as powerful as a connected one.
249249

250250
7. **Let the graph grow naturally.** Don't try to design a perfect taxonomy upfront. Write notes as you work, add relations as connections emerge, and periodically use `/reflect` or `/defrag` to consolidate.
251+
252+
## ⚠️ write_note vs edit_note — Avoiding Data Loss
253+
254+
**`write_note` is destructive.** If a note with the same title already exists, `write_note` silently replaces it. This will destroy accumulated content in daily notes, logs, or any file that grows over time.
255+
256+
### Rules
257+
258+
- **New notes**: Use `write_note` — it creates the file and frontmatter correctly.
259+
- **Existing notes**: Use `edit_note` — it modifies without replacing.
260+
- `operation: "append"` — add content to the end
261+
- `operation: "prepend"` — add content to the beginning
262+
- `operation: "find_replace"` — surgical text replacement
263+
- `operation: "replace_section"` — replace a specific heading section
264+
265+
### Common Mistake
266+
267+
```
268+
# ❌ WRONG — destroys existing daily note content
269+
write_note(title="2026-02-26", folder="memory", content="## New Section\n...")
270+
271+
# ✅ RIGHT — appends to existing daily note
272+
edit_note(identifier="2026-02-26", operation="append", content="\n## New Section\n...")
273+
```
274+
275+
**When in doubt, use `edit_note`.** It's always safe. `write_note` is only safe when you're certain the note doesn't exist yet or you intentionally want to replace it entirely.

skills/memory-reflect/SKILL.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,18 @@ Append a brief entry to today's daily note:
6161
- **Flag uncertainty.** If something seems important but you're not sure, add it with a note like "(needs confirmation)" rather than skipping it entirely.
6262
- **Restructure over time.** If MEMORY.md is a chronological dump, restructure it into topical sections during reflection. Curated knowledge > raw logs.
6363
- **Check for filesystem issues.** Look for recursive nesting (memory/memory/memory/...), orphaned files, or bloat while gathering material.
64+
65+
## ⚠️ Safe Writing Pattern
66+
67+
**Never use `write_note` on daily notes or MEMORY.md.** These files accumulate content throughout the day. `write_note` replaces the entire file — use `edit_note` instead:
68+
69+
```
70+
# ✅ Update a section in MEMORY.md
71+
edit_note(identifier="MEMORY", operation="replace_section", section="About Me", content="...")
72+
73+
# ✅ Append reflection log to today's daily note
74+
edit_note(identifier="2026-02-26", operation="append", content="\n## Reflection (22:00)\n...")
75+
76+
# ❌ NEVER do this — destroys the existing file
77+
write_note(title="2026-02-26", folder="memory", content="...")
78+
```

0 commit comments

Comments
 (0)