Skip to content

Commit 794c56a

Browse files
ihwooclaude
authored andcommitted
Add --db-path option to setup CLI and install script for consistent DB paths v0.5.1
The OpenClaw extension was spawning the MCP server without passing AIMEMORY_DB_PATH, causing it to create a separate DB in the OpenClaw workspace directory instead of the project's memory_db. This led to the live viewer and MCP server reading different databases. - Add --db-path flag to aimemory-setup (openclaw/claude subcommands) - Add --db-path flag to scripts/install_openclaw.sh - Inject DB_PATH constant into OpenClaw extension template at install time - Extension spawn env now passes AIMEMORY_DB_PATH with fallback chain - Update README with custom DB path documentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent cd93c32 commit 794c56a

File tree

5 files changed

+102
-23
lines changed

5 files changed

+102
-23
lines changed

README.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,32 @@ aimemory-setup claude
7373

7474
This injects memory usage instructions into your client's configuration files (`SOUL.md`/`TOOLS.md` for OpenClaw, `CLAUDE.md` for Claude Code). Re-run anytime to update.
7575

76+
<details>
77+
<summary>Custom database path</summary>
78+
79+
By default, memories are stored in `./memory_db` (resolved to an absolute path at install time). To use a custom location:
80+
81+
```bash
82+
# OpenClaw — sets the DB path in the extension and mcporter config
83+
aimemory-setup openclaw --db-path /path/to/my/memory_db
84+
85+
# Claude Code
86+
aimemory-setup claude --db-path /path/to/my/memory_db
87+
88+
# Shell script (OpenClaw)
89+
bash scripts/install_openclaw.sh --db-path /path/to/my/memory_db
90+
```
91+
92+
You can also set the `AIMEMORY_DB_PATH` environment variable, which all components respect:
93+
94+
```bash
95+
export AIMEMORY_DB_PATH=/path/to/my/memory_db
96+
aimemory-setup openclaw # picks up the env var automatically
97+
```
98+
99+
All components (MCP server, live viewer, OpenClaw extension) will use the same absolute path, ensuring data consistency.
100+
</details>
101+
76102
### 3. Connect to OpenClaw
77103

78104
```bash
@@ -159,7 +185,10 @@ aimemory-mcp --with-live
159185
# Option 2: standalone server
160186
aimemory-live --port 8765
161187

162-
# Option 3: via environment variable
188+
# Option 3: standalone with custom DB path
189+
aimemory-live --db-path /path/to/memory_db
190+
191+
# Option 4: via environment variable
163192
AIMEMORY_LIVE=1 aimemory-mcp
164193
```
165194

@@ -198,7 +227,7 @@ All settings via environment variables:
198227

199228
| Variable | Default | Description |
200229
|----------|---------|-------------|
201-
| `AIMEMORY_DB_PATH` | `./memory_db` | ChromaDB persistence directory |
230+
| `AIMEMORY_DB_PATH` | `./memory_db` | ChromaDB persistence directory (use absolute path to ensure all components share the same DB) |
202231
| `AIMEMORY_LANGUAGE` | `ko` | Language for pattern matching (`ko` / `en`) |
203232
| `AIMEMORY_EMBEDDING_MODEL` | `intfloat/multilingual-e5-small` | Sentence-transformer model |
204233
| `AIMEMORY_LOG_LEVEL` | `INFO` | Logging level |

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "long-term-memory"
3-
version = "0.5.0"
3+
version = "0.5.1"
44
description = "Long-term memory system for AI assistants — persistent, searchable, self-organizing memory powered by semantic search, knowledge graphs, and reinforcement learning"
55
requires-python = ">=3.11,<3.14"
66
license = "MIT"

scripts/install_openclaw.sh

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,35 @@
22
# AIMemory MCP Server — OpenClaw 자동 설치 스크립트
33
#
44
# Usage:
5-
# bash scripts/install_openclaw.sh # 설치
6-
# bash scripts/install_openclaw.sh --remove # 제거
5+
# bash scripts/install_openclaw.sh [--db-path /absolute/path/to/db] # 설치
6+
# bash scripts/install_openclaw.sh --remove # 제거
77

88
set -euo pipefail
99

1010
PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
1111
MCPORTER_CONFIG="${HOME}/.mcporter/mcporter.json"
1212
TOOLS_MD="${HOME}/.openclaw/workspace/TOOLS.md"
1313
SERVER_NAME="aimemory"
14+
DB_PATH=""
1415

1516
TOOLS_BLOCK_START="## AIMemory"
1617
TOOLS_BLOCK_END="<!-- \/aimemory -->"
1718

1819
TOOLS_CONTENT_FILE="${PROJECT_DIR}/scripts/tools_content.md"
1920

2021
install() {
22+
# DB 경로 결정: --db-path > AIMEMORY_DB_PATH env > 프로젝트/memory_db
23+
if [ -z "$DB_PATH" ]; then
24+
DB_PATH="${AIMEMORY_DB_PATH:-${PROJECT_DIR}/memory_db}"
25+
fi
26+
# 상대경로면 절대경로로 변환
27+
case "$DB_PATH" in
28+
/*) ;; # 이미 절대경로
29+
*) DB_PATH="$(cd "$(dirname "$DB_PATH")" 2>/dev/null && pwd)/$(basename "$DB_PATH")" ;;
30+
esac
31+
2132
echo "🧠 AIMemory MCP 서버 설치 중..."
33+
echo " DB 경로: ${DB_PATH}"
2234

2335
# 1. 의존성 확인
2436
if ! command -v mcporter &>/dev/null; then
@@ -57,7 +69,7 @@ install() {
5769
--arg python \
5870
--arg -m \
5971
--arg aimemory.mcp \
60-
--env "AIMEMORY_DB_PATH=${PROJECT_DIR}/memory_db" \
72+
--env "AIMEMORY_DB_PATH=${DB_PATH}" \
6173
--env "AIMEMORY_LANGUAGE=ko" \
6274
--env "AIMEMORY_EMBEDDING_MODEL=intfloat/multilingual-e5-small" \
6375
--env "AIMEMORY_LOG_LEVEL=INFO" \
@@ -115,11 +127,18 @@ remove() {
115127
echo "✅ 제거 완료"
116128
}
117129

118-
case "${1:-}" in
119-
--remove|--uninstall|-r)
120-
remove
121-
;;
122-
*)
123-
install
124-
;;
125-
esac
130+
ACTION="install"
131+
while [ $# -gt 0 ]; do
132+
case "$1" in
133+
--remove|--uninstall|-r)
134+
ACTION="remove"; shift ;;
135+
--db-path)
136+
DB_PATH="$2"; shift 2 ;;
137+
--db-path=*)
138+
DB_PATH="${1#*=}"; shift ;;
139+
*)
140+
echo "Unknown option: $1"; exit 1 ;;
141+
esac
142+
done
143+
144+
"$ACTION"

src/aimemory/setup_client.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,21 @@ def _find_aimemory_mcp_command() -> str:
6969
return "aimemory-mcp"
7070

7171

72-
def _install_openclaw_extension(openclaw_dir: Path) -> None:
72+
def _resolve_db_path(db_path: str | None) -> str:
73+
"""Resolve the database path to an absolute path.
74+
75+
Priority:
76+
1. Explicitly provided ``db_path`` argument
77+
2. ``AIMEMORY_DB_PATH`` environment variable
78+
3. ``./memory_db`` relative to cwd (resolved to absolute)
79+
"""
80+
import os
81+
82+
path = db_path or os.environ.get("AIMEMORY_DB_PATH") or "./memory_db"
83+
return str(Path(path).resolve())
84+
85+
86+
def _install_openclaw_extension(openclaw_dir: Path, *, db_path: str) -> None:
7387
"""Install the AIMemory extension into OpenClaw's extensions directory.
7488
7589
Creates ~/.openclaw/extensions/aimemory/ with the plugin files that
@@ -111,16 +125,18 @@ def _install_openclaw_extension(openclaw_dir: Path) -> None:
111125

112126
# index.ts — bridge plugin
113127
index_ts = _load_template("openclaw_extension.ts")
114-
# Inject the resolved MCP command path
115128
index_ts = index_ts.replace("__AIMEMORY_MCP_COMMAND__", mcp_command)
129+
index_ts = index_ts.replace("__AIMEMORY_DB_PATH__", db_path)
116130
(ext_dir / "index.ts").write_text(index_ts, encoding="utf-8")
117131

118132
print(f" Installed extension to {ext_dir}")
133+
print(f" DB path: {db_path}")
119134

120135

121-
def setup_openclaw(workspace: Path) -> None:
136+
def setup_openclaw(workspace: Path, *, db_path: str | None = None) -> None:
122137
"""Inject AIMemory instructions into OpenClaw workspace files."""
123138
workspace = workspace.expanduser()
139+
resolved_db_path = _resolve_db_path(db_path)
124140

125141
# SOUL.md — Memory Continuity section
126142
soul_path = workspace / "SOUL.md"
@@ -136,16 +152,18 @@ def setup_openclaw(workspace: Path) -> None:
136152

137153
# Install OpenClaw extension
138154
openclaw_dir = workspace.parent
139-
_install_openclaw_extension(openclaw_dir)
155+
_install_openclaw_extension(openclaw_dir, db_path=resolved_db_path)
140156

141157

142-
def setup_claude(claude_dir: Path) -> None:
158+
def setup_claude(claude_dir: Path, *, db_path: str | None = None) -> None:
143159
"""Inject AIMemory instructions into Claude Code's CLAUDE.md."""
144160
claude_dir = claude_dir.expanduser()
161+
resolved_db_path = _resolve_db_path(db_path)
145162
claude_md = claude_dir / "CLAUDE.md"
146163
claude_content = _load_template("claude.md")
147164
_inject_block(claude_md, claude_content)
148165
print(f" Updated {claude_md}")
166+
print(f" DB path: {resolved_db_path}")
149167

150168

151169
def main() -> None:
@@ -156,16 +174,25 @@ def main() -> None:
156174
)
157175
subparsers = parser.add_subparsers(dest="client")
158176

177+
# Common argument for db-path
178+
db_path_help = (
179+
"Absolute path to the ChromaDB database directory. "
180+
"All clients (MCP server, live viewer, extension) will use this path. "
181+
"(default: $AIMEMORY_DB_PATH or ./memory_db resolved to absolute)"
182+
)
183+
159184
# openclaw subcommand
160185
oc = subparsers.add_parser("openclaw", help="Setup for OpenClaw")
161186
oc.add_argument(
162187
"--workspace",
163188
default="~/.openclaw/workspace",
164189
help="OpenClaw workspace path (default: ~/.openclaw/workspace)",
165190
)
191+
oc.add_argument("--db-path", default=None, help=db_path_help)
166192

167193
# claude subcommand
168-
subparsers.add_parser("claude", help="Setup for Claude Code")
194+
cl = subparsers.add_parser("claude", help="Setup for Claude Code")
195+
cl.add_argument("--db-path", default=None, help=db_path_help)
169196

170197
args = parser.parse_args()
171198

@@ -176,9 +203,9 @@ def main() -> None:
176203
print(f"Setting up AIMemory for {args.client}...")
177204

178205
if args.client == "openclaw":
179-
setup_openclaw(Path(args.workspace))
206+
setup_openclaw(Path(args.workspace), db_path=args.db_path)
180207
elif args.client == "claude":
181-
setup_claude(Path("~/.claude"))
208+
setup_claude(Path("~/.claude"), db_path=args.db_path)
182209

183210
print("Done!")
184211

src/aimemory/setup_instructions/openclaw_extension.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { createInterface } from "node:readline";
44
// ── MCP stdio client ────────────────────────────────────────────────
55

66
const MCP_COMMAND = "__AIMEMORY_MCP_COMMAND__";
7+
const DB_PATH = "__AIMEMORY_DB_PATH__";
78

89
interface JsonRpcRequest {
910
jsonrpc: "2.0";
@@ -33,7 +34,10 @@ function ensureMcp(): ChildProcess {
3334

3435
mcpProcess = spawn(MCP_COMMAND, [], {
3536
stdio: ["pipe", "pipe", "pipe"],
36-
env: { ...process.env },
37+
env: {
38+
...process.env,
39+
AIMEMORY_DB_PATH: process.env.AIMEMORY_DB_PATH || DB_PATH,
40+
},
3741
});
3842

3943
const rl = createInterface({ input: mcpProcess.stdout! });

0 commit comments

Comments
 (0)