From 88204417fd33c08f96d967bf0402a8e460963954 Mon Sep 17 00:00:00 2001 From: bm-clawd Date: Thu, 26 Feb 2026 22:02:47 -0600 Subject: [PATCH 1/4] feat: add /bm-setup slash command to install/update BM CLI Registers a /bm-setup command that runs scripts/setup-bm.sh, letting users trigger BM CLI installation on demand instead of only at service start. --- commands/slash.ts | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/commands/slash.ts b/commands/slash.ts index 9ba21f8..1c22324 100644 --- a/commands/slash.ts +++ b/commands/slash.ts @@ -1,11 +1,44 @@ +import { execSync } from "node:child_process" +import { resolve, dirname } from "node:path" +import { fileURLToPath } from "node:url" import type { OpenClawPluginApi } from "openclaw/plugin-sdk" import type { BmClient } from "../bm-client.ts" import { log } from "../logger.ts" +const __dirname = dirname(fileURLToPath(import.meta.url)) + export function registerCommands( api: OpenClawPluginApi, client: BmClient, ): void { + api.registerCommand({ + name: "bm-setup", + description: + "Install or update the Basic Memory CLI (requires uv)", + requireAuth: true, + handler: async () => { + const scriptPath = resolve(__dirname, "..", "scripts", "setup-bm.sh") + log.info(`/bm-setup: running ${scriptPath}`) + + try { + const output = execSync(`bash "${scriptPath}"`, { + encoding: "utf-8", + timeout: 180_000, + stdio: "pipe", + env: { ...process.env }, + }) + return { text: output.trim() } + } catch (err: unknown) { + const execErr = err as { stderr?: string; stdout?: string } + const detail = execErr.stderr || execErr.stdout || String(err) + log.error("/bm-setup failed", err) + return { + text: `Setup failed:\n${detail.trim()}`, + } + } + }, + }) + api.registerCommand({ name: "remember", description: "Save something to the Basic Memory knowledge graph", From 2fdad505f32fb965b700493ea4a67ca339a35e45 Mon Sep 17 00:00:00 2001 From: bm-clawd Date: Thu, 26 Feb 2026 22:03:18 -0600 Subject: [PATCH 2/4] docs: add /bm-setup to slash commands table --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d493f17..7d49623 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,7 @@ All tools accept an optional `project` parameter for cross-project operations. | Command | Description | |---------|-------------| +| `/bm-setup` | Install or update the Basic Memory CLI | | `/remember ` | Save a quick note | | `/recall ` | Search the knowledge graph | | `/tasks [args]` | Create, track, resume structured tasks | From 56acb8da159a6d1286c243a1e3f975f43a8690e5 Mon Sep 17 00:00:00 2001 From: bm-clawd Date: Thu, 26 Feb 2026 22:18:49 -0600 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20biome=20lint=20=E2=80=94=20import=20?= =?UTF-8?q?order=20and=20description=20formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- commands/slash.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/commands/slash.ts b/commands/slash.ts index 1c22324..4595fd2 100644 --- a/commands/slash.ts +++ b/commands/slash.ts @@ -1,5 +1,5 @@ import { execSync } from "node:child_process" -import { resolve, dirname } from "node:path" +import { dirname, resolve } from "node:path" import { fileURLToPath } from "node:url" import type { OpenClawPluginApi } from "openclaw/plugin-sdk" import type { BmClient } from "../bm-client.ts" @@ -13,8 +13,7 @@ export function registerCommands( ): void { api.registerCommand({ name: "bm-setup", - description: - "Install or update the Basic Memory CLI (requires uv)", + description: "Install or update the Basic Memory CLI (requires uv)", requireAuth: true, handler: async () => { const scriptPath = resolve(__dirname, "..", "scripts", "setup-bm.sh") From 82375b673733fe154474cbbfe8fd0d07dddfcdb7 Mon Sep 17 00:00:00 2001 From: bm-clawd Date: Thu, 26 Feb 2026 22:24:52 -0600 Subject: [PATCH 4/4] docs: add write_note safety warnings to memory-notes and memory-reflect skills write_note silently overwrites existing notes. Agents need clear guidance to use edit_note for files that accumulate content (daily notes, MEMORY.md, logs). This prevents accidental data loss. Refs: basicmachines-co/basic-memory#625 --- skills/memory-notes/SKILL.md | 25 +++++++++++++++++++++++++ skills/memory-reflect/SKILL.md | 15 +++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/skills/memory-notes/SKILL.md b/skills/memory-notes/SKILL.md index c5a4a3b..515e82f 100644 --- a/skills/memory-notes/SKILL.md +++ b/skills/memory-notes/SKILL.md @@ -248,3 +248,28 @@ edit_note( 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. 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. + +## ⚠️ write_note vs edit_note — Avoiding Data Loss + +**`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. + +### Rules + +- **New notes**: Use `write_note` — it creates the file and frontmatter correctly. +- **Existing notes**: Use `edit_note` — it modifies without replacing. + - `operation: "append"` — add content to the end + - `operation: "prepend"` — add content to the beginning + - `operation: "find_replace"` — surgical text replacement + - `operation: "replace_section"` — replace a specific heading section + +### Common Mistake + +``` +# ❌ WRONG — destroys existing daily note content +write_note(title="2026-02-26", folder="memory", content="## New Section\n...") + +# ✅ RIGHT — appends to existing daily note +edit_note(identifier="2026-02-26", operation="append", content="\n## New Section\n...") +``` + +**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. diff --git a/skills/memory-reflect/SKILL.md b/skills/memory-reflect/SKILL.md index 0fb352c..b93d0fb 100644 --- a/skills/memory-reflect/SKILL.md +++ b/skills/memory-reflect/SKILL.md @@ -61,3 +61,18 @@ Append a brief entry to today's daily note: - **Flag uncertainty.** If something seems important but you're not sure, add it with a note like "(needs confirmation)" rather than skipping it entirely. - **Restructure over time.** If MEMORY.md is a chronological dump, restructure it into topical sections during reflection. Curated knowledge > raw logs. - **Check for filesystem issues.** Look for recursive nesting (memory/memory/memory/...), orphaned files, or bloat while gathering material. + +## ⚠️ Safe Writing Pattern + +**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: + +``` +# ✅ Update a section in MEMORY.md +edit_note(identifier="MEMORY", operation="replace_section", section="About Me", content="...") + +# ✅ Append reflection log to today's daily note +edit_note(identifier="2026-02-26", operation="append", content="\n## Reflection (22:00)\n...") + +# ❌ NEVER do this — destroys the existing file +write_note(title="2026-02-26", folder="memory", content="...") +```