Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,16 @@ or `~/.qoder/`. QoderWork uses its native user config at `~/.qoderwork/`.
Both integrations register `SessionStart`, `UserPromptSubmit`, and `Stop`
hooks in `settings.json`.

### [CodeBuddy](https://www.codebuddy.cn/)

```bash
mnemon setup --target codebuddy --yes
```

CodeBuddy deploys the mnemon skill, prompt files, and native hooks to
`.codebuddy/` or `~/.codebuddy/`. The integration registers `SessionStart`,
`UserPromptSubmit`, and `Stop` hooks in `settings.json`.

### [OpenClaw](https://github.com/openclaw/openclaw)

```bash
Expand Down Expand Up @@ -233,7 +243,7 @@ memory is useful.

- **Zero user-side operation** — install once; supported runtimes can use hooks, minimal runtimes can use persistent rules
- **LLM-supervised** — the host LLM decides what to remember, update, and forget; no embedded LLM, no API keys
- **Multi-framework support** — Claude Code, Codex, Cursor, TRAE/TRAE Work, Qoder/QoderWork, and Hermes Agent (hooks), OpenClaw (plugins), Pi (extensions), Nanobot (skills), and more
- **Multi-framework support** — Claude Code, Codex, Cursor, TRAE/TRAE Work, Qoder/QoderWork, CodeBuddy, and Hermes Agent (hooks), OpenClaw (plugins), Pi (extensions), Nanobot (skills), and more
- **Markdown-installable harness** — `SKILL.md`, `INSTALL.md`, `GUIDELINE.md`, and four lifecycle reminders
- **Four-graph architecture** — temporal, entity, causal, and semantic edges, not just vector similarity
- **Intent-native protocol** — three primitives (`remember`, `link`, `recall`) map to the LLM's cognitive vocabulary, not database syntax; structured JSON output with signal transparency
Expand Down Expand Up @@ -262,6 +272,8 @@ All your local agentic AIs — across sessions and frameworks — sharing one po
QoderWork ────┤
CodeBuddy ────┤
Hermes Agent ─┤
OpenClaw ─────┤
Expand All @@ -279,11 +291,11 @@ All your local agentic AIs — across sessions and frameworks — sharing one po

The foundation is in place: a single `~/.mnemon` database that any agent can
read and write. Claude Code, Codex, Cursor, TRAE/TRAE Work, Qoder/QoderWork,
and Hermes Agent setup automate hook installation; OpenClaw can use plugin
hooks; Pi integrates via native skills and TypeScript lifecycle extensions;
Nanobot integrates via skill files; NanoClaw integrates via container skills and
volume mounts. The same harness can be installed in any LLM CLI that supports
skills, rules, system prompts, or event hooks.
CodeBuddy, and Hermes Agent setup automate hook installation; OpenClaw can use
plugin hooks; Pi integrates via native skills and TypeScript lifecycle
extensions; Nanobot integrates via skill files; NanoClaw integrates via
container skills and volume mounts. The same harness can be installed in any LLM
CLI that supports skills, rules, system prompts, or event hooks.

The longer-term direction is a **memory gateway**: protocol decoupled from storage engine. The current SQLite backend is the first adapter; the protocol surface (`remember / link / recall`) can sit on top of PostgreSQL, Neo4j, or any graph database. Agent-side optimization (when to recall, what to remember) and storage-side optimization (indexing, graph algorithms) evolve independently. See [Future Direction](docs/design/08-decisions.md#82-future-direction) for details.

Expand Down
101 changes: 94 additions & 7 deletions cmd/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ var setupCmd = &cobra.Command{
Short: "Deploy mnemon into LLM CLI environments",
Long: `Detect installed LLM CLIs and deploy mnemon integration.

By default, installs to project-local config (.claude/, .codex/, .cursor/, .trae/, .qoder/, .openclaw/, .nanobot/, .pi/).
Use --global to install to user-wide config (~/.claude/, ~/.codex/, ~/.cursor/, ~/.trae/, ~/.qoder/, ~/.openclaw/, ~/.nanobot/workspace/, ~/.pi/agent/).
By default, installs to project-local config (.claude/, .codex/, .cursor/, .trae/, .qoder/, .codebuddy/, .openclaw/, .nanobot/, .pi/).
Use --global to install to user-wide config (~/.claude/, ~/.codex/, ~/.cursor/, ~/.trae/, ~/.qoder/, ~/.codebuddy/, ~/.openclaw/, ~/.nanobot/workspace/, ~/.pi/agent/).
Hermes Agent and QoderWork use their native user config at ~/.hermes/ and ~/.qoderwork/.

Supported environments: Claude Code, Codex, Cursor, Trae, Qoder, QoderWork, OpenClaw, Nanobot, Pi, Hermes Agent.
Supported environments: Claude Code, Codex, Cursor, Trae, Qoder, QoderWork, CodeBuddy, OpenClaw, Nanobot, Pi, Hermes Agent.

Examples:
mnemon setup # Interactive: project-local install
Expand All @@ -36,6 +36,7 @@ Examples:
mnemon setup --target trae # Non-interactive: Trae skill and hooks
mnemon setup --target qoder # Non-interactive: Qoder skill and hooks
mnemon setup --target qoderwork # Non-interactive: QoderWork skill and hooks
mnemon setup --target codebuddy # Non-interactive: CodeBuddy skill and hooks
mnemon setup --target hermes # Non-interactive: Hermes Agent only
mnemon setup --eject # Interactive: remove integrations
mnemon setup --eject --target claude-code # Non-interactive: remove Claude Code only
Expand All @@ -44,16 +45,16 @@ Examples:
}

func init() {
setupCmd.Flags().StringVar(&setupTarget, "target", "", "target environment (claude-code, codex, cursor, trae, qoder, qoderwork, openclaw, nanobot, pi, hermes)")
setupCmd.Flags().StringVar(&setupTarget, "target", "", "target environment (claude-code, codex, cursor, trae, qoder, qoderwork, codebuddy, openclaw, nanobot, pi, hermes)")
setupCmd.Flags().BoolVar(&setupEject, "eject", false, "remove mnemon integrations")
setupCmd.Flags().BoolVar(&setupYes, "yes", false, "auto-confirm all prompts (CI-friendly)")
setupCmd.Flags().BoolVar(&setupGlobal, "global", false, "install to user-wide config instead of project-local config")
rootCmd.AddCommand(setupCmd)
}

func runSetup(cmd *cobra.Command, args []string) error {
if setupTarget != "" && setupTarget != "claude-code" && setupTarget != "codex" && setupTarget != "cursor" && setupTarget != "trae" && setupTarget != "qoder" && setupTarget != "qoderwork" && setupTarget != "openclaw" && setupTarget != "nanobot" && setupTarget != "pi" && setupTarget != "hermes" {
return fmt.Errorf("invalid target %q (must be claude-code, codex, cursor, trae, qoder, qoderwork, openclaw, nanobot, pi, or hermes)", setupTarget)
if setupTarget != "" && setupTarget != "claude-code" && setupTarget != "codex" && setupTarget != "cursor" && setupTarget != "trae" && setupTarget != "qoder" && setupTarget != "qoderwork" && setupTarget != "codebuddy" && setupTarget != "openclaw" && setupTarget != "nanobot" && setupTarget != "pi" && setupTarget != "hermes" {
return fmt.Errorf("invalid target %q (must be claude-code, codex, cursor, trae, qoder, qoderwork, codebuddy, openclaw, nanobot, pi, or hermes)", setupTarget)
}

envs := setup.DetectEnvironments(setupGlobal)
Expand Down Expand Up @@ -89,7 +90,7 @@ func runInstallFlow(envs []setup.Environment) error {

if len(detected) == 0 {
fmt.Println("\nNo supported LLM CLI environments detected.")
fmt.Println("Install Claude Code, Codex, Cursor, Trae, Qoder, QoderWork, OpenClaw, Nanobot, Pi, or Hermes Agent, then run 'mnemon setup' again.")
fmt.Println("Install Claude Code, Codex, Cursor, Trae, Qoder, QoderWork, CodeBuddy, OpenClaw, Nanobot, Pi, or Hermes Agent, then run 'mnemon setup' again.")
return nil
}

Expand Down Expand Up @@ -141,6 +142,8 @@ func installEnv(env *setup.Environment) error {
err = installQoder(env)
case "qoderwork":
err = installQoderWork(env)
case "codebuddy":
err = installCodeBuddy(env)
case "openclaw":
err = installOpenClaw(env)
case "nanobot":
Expand Down Expand Up @@ -678,6 +681,83 @@ func installQoderLike(configDir string, writeSkill func(string) (string, error),
return nil
}

// ─── CodeBuddy ──────────────────────────────────────────────────────

func installCodeBuddy(env *setup.Environment) error {
configDir := env.ConfigDir

if !setupGlobal && !setupYes && setup.IsInteractive() {
home := setup.HomeDir()
localDir := ".codebuddy"
globalDir := home + "/.codebuddy"
idx := setup.SelectOne("Install scope",
[]string{
fmt.Sprintf("Local — this project only (%s/)", localDir),
fmt.Sprintf("Global — all projects (%s/)", globalDir),
}, 0)
if idx == 1 {
configDir = globalDir
} else {
configDir = localDir
}
}

fmt.Printf("\nSetting up CodeBuddy (%s)...\n", configDir)

fmt.Println("\n[1/3] Skill")
if path, err := setup.CodeBuddyWriteSkill(configDir); err != nil {
setup.StatusError(0, 0, "Skill", err)
return err
} else {
setup.StatusOK(0, 0, "Skill", path)
}

fmt.Println("\n[2/3] Prompts")
var promptPath string
if path, err := setup.WritePromptFiles(); err != nil {
setup.StatusError(0, 0, "Prompts", err)
return err
} else {
setup.StatusOK(0, 0, "Prompts", path)
promptPath = path
}

fmt.Println("\n[3/3] Hooks")
for _, hook := range []struct {
label string
filename string
content []byte
}{
{"Hook: prime", "prime.sh", assets.CodeBuddyPrimeHook},
{"Hook: remind", "user_prompt.sh", assets.CodeBuddyUserPromptHook},
{"Hook: nudge", "stop.sh", assets.CodeBuddyStopHook},
} {
if path, err := setup.CodeBuddyWriteHook(configDir, hook.filename, hook.content); err != nil {
setup.StatusError(0, 0, hook.label, err)
return err
} else {
setup.StatusOK(0, 0, hook.label, path)
}
}
if path, err := setup.CodeBuddyRegisterHooks(configDir); err != nil {
setup.StatusError(0, 0, "Settings", err)
return err
} else {
setup.StatusUpdated(0, 0, "Settings", path)
}

fmt.Println()
fmt.Println("Setup complete!")
fmt.Printf(" Skill %s/skills/mnemon/SKILL.md\n", configDir)
fmt.Printf(" Hooks %s/settings.json (SessionStart, UserPromptSubmit, Stop)\n", configDir)
fmt.Printf(" Prompts %s/ (guide.md, skill.md)\n", promptPath)
fmt.Println()
fmt.Println("Restart CodeBuddy Code to activate the mnemon skill and hooks.")
fmt.Println("Run 'mnemon setup --eject --target codebuddy' to remove.")

return nil
}

// ─── OpenClaw ───────────────────────────────────────────────────────

func installOpenClaw(env *setup.Environment) error {
Expand Down Expand Up @@ -1133,6 +1213,13 @@ func ejectEnv(env *setup.Environment) error {
return errs[0]
}

case "codebuddy":
errs := setup.CodeBuddyEject(env.ConfigDir)
ejectMarkdown("AGENTS.md", "Remove memory guidance from ./AGENTS.md?")
if len(errs) > 0 {
return errs[0]
}

case "openclaw":
errs := setup.OpenClawEject(env.ConfigDir)
ejectMarkdown("AGENTS.md", "Remove memory guidance from ./AGENTS.md?")
Expand Down
3 changes: 2 additions & 1 deletion docs/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ mnemon setup --target cursor
mnemon setup --target trae
mnemon setup --target qoder
mnemon setup --target qoderwork
mnemon setup --target codebuddy
mnemon setup --target openclaw
mnemon setup --target pi
mnemon setup --target nanobot --global
Expand All @@ -50,7 +51,7 @@ mnemon setup --eject --target claude-code
| Flag | Default | Description |
|---|---|---|
| `--global` | `false` | Install to user-wide config instead of project-local (recommended for Nanobot: installs to `~/.nanobot/workspace/`; Pi installs to `~/.pi/agent/`; Hermes installs to `~/.hermes/`; QoderWork installs to `~/.qoderwork/`) |
| `--target <name>` | (auto-detect) | Target environment: `claude-code`, `codex`, `cursor`, `trae`, `qoder`, `qoderwork`, `openclaw`, `nanobot`, `pi`, or `hermes` |
| `--target <name>` | (auto-detect) | Target environment: `claude-code`, `codex`, `cursor`, `trae`, `qoder`, `qoderwork`, `codebuddy`, `openclaw`, `nanobot`, `pi`, or `hermes` |
| `--eject` | `false` | Remove mnemon integrations |
| `--yes` | `false` | Auto-confirm all prompts |

Expand Down
16 changes: 14 additions & 2 deletions docs/zh/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,16 @@ Qoder 会将 mnemon skill、prompt 文件和原生 hooks 部署到 `.qoder/` 或
`~/.qoder/`。QoderWork 使用原生用户级配置 `~/.qoderwork/`。两者都会在
`settings.json` 中注册 `SessionStart`、`UserPromptSubmit` 和 `Stop` hooks。

### [CodeBuddy](https://www.codebuddy.cn/)

```bash
mnemon setup --target codebuddy --yes
```

CodeBuddy 会将 mnemon skill、prompt 文件和原生 hooks 部署到 `.codebuddy/`
或 `~/.codebuddy/`。该集成会在 `settings.json` 中注册 `SessionStart`、
`UserPromptSubmit` 和 `Stop` hooks。

### [OpenClaw](https://github.com/openclaw/openclaw)

```bash
Expand Down Expand Up @@ -196,7 +206,7 @@ Agent 工作,并且只在有用时调用 Mnemon

- **零用户操作** — 安装一次;支持 hook 的 runtime 可用 hook,minimal runtime 可用持久规则
- **LLM 监督式** — 宿主 LLM 主动决定记什么、更新什么、遗忘什么;无内嵌 LLM,无 API 密钥
- **多框架支持** — Claude Code、Codex、Cursor、TRAE/TRAE Work、Qoder/QoderWork 和 Hermes Agent(hooks)、OpenClaw(plugins)、Pi(extensions)、Nanobot(skills)等
- **多框架支持** — Claude Code、Codex、Cursor、TRAE/TRAE Work、Qoder/QoderWork、CodeBuddy 和 Hermes Agent(hooks)、OpenClaw(plugins)、Pi(extensions)、Nanobot(skills)等
- **Markdown 可安装 harness** — `SKILL.md`、`INSTALL.md`、`GUIDELINE.md` 和四个生命周期提醒
- **四图架构** — 时序、实体、因果、语义四种边,不仅仅是向量相似度
- **意图原生协议** — 三个原语(`remember`、`link`、`recall`)映射到 LLM 的认知词汇而非数据库语法;结构化 JSON 输出,带信号透明度
Expand Down Expand Up @@ -224,6 +234,8 @@ Agent 工作,并且只在有用时调用 Mnemon
QoderWork ────┤
CodeBuddy ────┤
Hermes Agent ─┤
OpenClaw ─────┤
Expand All @@ -239,7 +251,7 @@ Agent 工作,并且只在有用时调用 Mnemon
Gemini CLI ───┘
```

基础已就绪:一个 `~/.mnemon` 数据库,任何 agent 都可以读写。Claude Code、Codex、Cursor、TRAE/TRAE Work、Qoder/QoderWork 和 Hermes Agent setup 可自动安装 hook;OpenClaw 可以使用 plugin hooks;Pi 通过原生 skill 和 TypeScript lifecycle extension 集成;Nanobot 通过 skill 文件集成;NanoClaw 通过容器技能和卷挂载集成。同一个 harness 可以安装到任何支持 skill、rule、system prompt 或 event hook 的 LLM CLI。
基础已就绪:一个 `~/.mnemon` 数据库,任何 agent 都可以读写。Claude Code、Codex、Cursor、TRAE/TRAE Work、Qoder/QoderWork、CodeBuddy 和 Hermes Agent setup 可自动安装 hook;OpenClaw 可以使用 plugin hooks;Pi 通过原生 skill 和 TypeScript lifecycle extension 集成;Nanobot 通过 skill 文件集成;NanoClaw 通过容器技能和卷挂载集成。同一个 harness 可以安装到任何支持 skill、rule、system prompt 或 event hook 的 LLM CLI。

更长远的方向是**记忆网关**:协议层与存储引擎解耦。当前 SQLite 后端是第一个适配器;协议面(`remember / link / recall`)可运行在 PostgreSQL、Neo4j 或任何图数据库之上。Agent 侧优化(何时召回、记什么)与存储侧优化(索引、图算法)独立演进。详见[未来方向](design/08-decisions.md#82-未来方向)。

Expand Down
3 changes: 2 additions & 1 deletion docs/zh/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ mnemon setup --target cursor
mnemon setup --target trae
mnemon setup --target qoder
mnemon setup --target qoderwork
mnemon setup --target codebuddy
mnemon setup --target openclaw
mnemon setup --target pi
mnemon setup --target nanobot --global
Expand All @@ -50,7 +51,7 @@ mnemon setup --eject --target claude-code
| 标志 | 默认值 | 说明 |
|---|---|---|
| `--global` | `false` | 安装到用户级配置而非项目本地(Nanobot 推荐安装到 `~/.nanobot/workspace/`;Pi 安装到 `~/.pi/agent/`;Hermes 安装到 `~/.hermes/`;QoderWork 安装到 `~/.qoderwork/`) |
| `--target <name>` | (自动检测) | 目标环境:`claude-code`、`codex`、`cursor`、`trae`、`qoder`、`qoderwork`、`openclaw`、`nanobot`、`pi` 或 `hermes` |
| `--target <name>` | (自动检测) | 目标环境:`claude-code`、`codex`、`cursor`、`trae`、`qoder`、`qoderwork`、`codebuddy`、`openclaw`、`nanobot`、`pi` 或 `hermes` |
| `--eject` | `false` | 移除 mnemon 集成 |
| `--yes` | `false` | 自动确认所有提示 |

Expand Down
14 changes: 13 additions & 1 deletion internal/setup/assets/assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ var QoderUserPromptHook []byte
//go:embed qoder/stop.sh
var QoderStopHook []byte

//go:embed codebuddy/SKILL.md
var CodeBuddySkill []byte

//go:embed codebuddy/prime.sh
var CodeBuddyPrimeHook []byte

//go:embed codebuddy/user_prompt.sh
var CodeBuddyUserPromptHook []byte

//go:embed codebuddy/stop.sh
var CodeBuddyStopHook []byte

//go:embed openclaw/SKILL.md
var OpenClawSkill []byte

Expand Down Expand Up @@ -121,5 +133,5 @@ var HermesCompactHook []byte

// All returns the embedded filesystem for inspection.
//
//go:embed claude codex cursor trae qoder qoderwork openclaw nanoclaw nanobot pi hermes
//go:embed claude codex cursor trae qoder qoderwork codebuddy openclaw nanoclaw nanobot pi hermes
var All embed.FS
46 changes: 46 additions & 0 deletions internal/setup/assets/codebuddy/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
name: mnemon
description: Persistent memory CLI for CodeBuddy. Store facts, recall past knowledge, link related memories, manage lifecycle.
---

# mnemon

## Workflow

1. **Remember**: `mnemon remember "<fact>" --cat <cat> --imp <1-5> --entities "e1,e2" --source agent`
- Diff is built in: duplicates are skipped, conflicts are auto-replaced.
- Output includes `action` (added/updated/skipped), `semantic_candidates`, and `causal_candidates`.
2. **Link** (evaluate candidates from step 1 using judgment):
- Review `causal_candidates`: link only when the memories are genuinely causally related.
- Review `semantic_candidates`: high `similarity` alone is not enough; skip unrelated keyword matches.
- Syntax: `mnemon link <id> <candidate> --type <causal|semantic> --weight <0-1> [--meta '<json>']`
3. **Recall**: `mnemon recall "<query>" --limit 10`

## Commands

```bash
mnemon remember "<fact>" --cat <cat> --imp <1-5> --entities "e1,e2" --source agent
mnemon link <id1> <id2> --type <type> --weight <0-1> [--meta '<json>']
mnemon recall "<query>" --limit 10
mnemon search "<query>" --limit 10
mnemon import --dry-run <file>
mnemon import <file>
mnemon forget <id>
mnemon related <id> --edge causal
mnemon gc --threshold 0.4
mnemon gc --keep <id>
mnemon status
mnemon log
mnemon store list
mnemon store create <name>
mnemon store set <name>
mnemon store remove <name>
```

## Guardrails

- Use memory only when it can materially improve continuity or task quality.
- Do not store secrets, passwords, tokens, private keys, or short-lived operational noise.
- Categories: `preference`, `decision`, `insight`, `fact`, `context`
- Edge types: `temporal`, `semantic`, `causal`, `entity`
- Max 8,000 chars per insight.
22 changes: 22 additions & 0 deletions internal/setup/assets/codebuddy/prime.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash
PROMPT_DIR="${MNEMON_DATA_DIR:-$HOME/.mnemon}/prompt"
if [ ! -f "${PROMPT_DIR}/guide.md" ] && [ -f "${HOME}/.mnemon/prompt/guide.md" ]; then
PROMPT_DIR="${HOME}/.mnemon/prompt"
fi

if ! command -v mnemon >/dev/null 2>&1; then
echo "[mnemon] Warning: mnemon not found in PATH."
[ -f "${PROMPT_DIR}/guide.md" ] && cat "${PROMPT_DIR}/guide.md"
exit 0
fi

STATS=$(mnemon status 2>/dev/null)
if [ -n "$STATS" ]; then
INSIGHTS=$(echo "$STATS" | sed -n 's/.*"total_insights": *\([0-9]*\).*/\1/p' | head -1)
EDGES=$(echo "$STATS" | sed -n 's/.*"edge_count": *\([0-9]*\).*/\1/p' | head -1)
echo "[mnemon] Memory active (${INSIGHTS:-0} insights, ${EDGES:-0} edges)."
else
echo "[mnemon] Memory active."
fi

[ -f "${PROMPT_DIR}/guide.md" ] && cat "${PROMPT_DIR}/guide.md"
Loading
Loading