diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index bd14f65..af7bc0b 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -134,7 +134,7 @@ What it drops: source code (`.py`, `.ts`, `.go`, `.rs`, …), lockfiles, `.git`, ## 4. Setup recipe (new machine) -Assumes: opencode already installed, `~/.local/share/opencode/opencode.db` exists, `mempalace` CLI installed (v3.3.3+). +Assumes: opencode already installed, `~/.local/share/opencode/opencode.db` exists, `mempalace` CLI installed (v3.3.3+). If mempalace isn't installed yet, [`README.md`](README.md#installing-mempalace-itself-prerequisite) covers the `uv tool install mempalace` flow for both personal machines and the `/opt/uv-tools/` container pattern used by opencode-devbox. ```bash # 1. Clone mempalace-toolkit (holds the two wrappers in bin/) diff --git a/README.md b/README.md index bee218c..7d9b0ff 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,126 @@ See [`ARCHITECTURE.md`](ARCHITECTURE.md) §6 for the full upstream roadmap. ### Prerequisites -- [MemPalace](https://github.com/MemPalace/mempalace) CLI v3.3.3+ +- [MemPalace](https://github.com/MemPalace/mempalace) CLI v3.3.3+ — **see [Installing mempalace itself](#installing-mempalace-itself-prerequisite) below if you haven't already**. - Python 3 (stdlib `sqlite3` only — no extra deps) - [opencode](https://github.com/anomalyco/opencode) with an active session DB at `~/.local/share/opencode/opencode.db` *(only needed for `mempalace-session`)* -### Install +### Installing mempalace itself (prerequisite) + +mempalace-toolkit wraps the mempalace CLI but does not bundle it. The upstream [MemPalace repo](https://github.com/MemPalace/mempalace) documents `pip install mempalace` as the install method; `uv tool install` is cleaner and is the flow used in production containers like [opencode-devbox](https://gitea.jordbo.se/joakimp/opencode-devbox). + +**Why uv over pip:** +- Isolated venv per tool — mempalace's dependencies (chromadb, embedding model runtime, …) don't leak into system Python or your project venvs. +- No PEP 668 fight — modern Debian / Ubuntu / Homebrew Python all refuse `pip install` into the system site-packages. `uv tool install` sidesteps this entirely. +- The shim (`~/.local/bin/mempalace` by default) is a thin wrapper that automatically activates the isolated venv on invocation, so `mempalace` is available from any bash or zsh terminal without manual `source venv/bin/activate`. + +**Install uv** if it's not already on the machine: + +```bash +# macOS / Linux, official installer — puts uv in ~/.local/bin +curl -LsSf https://astral.sh/uv/install.sh | sh + +# Or: Homebrew on macOS +brew install uv + +# Verify +uv --version +``` + +#### Personal machine (recommended default) + +```bash +# Installs mempalace into an isolated venv under ~/.local/share/uv/tools/mempalace/, +# puts the `mempalace` shim into ~/.local/bin/. +uv tool install mempalace + +# Make sure ~/.local/bin is on $PATH (uv prints this if it isn't) +export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc or ~/.zshrc + +# Verify +mempalace --version # should print the installed version +which mempalace # should point into ~/.local/bin/ +``` + +After this, `mempalace` works the same from any bash or zsh terminal — interactive shell, script, cron, systemd user service, launchd agent, all fine. + +To upgrade later: `uv tool upgrade mempalace` (or `--all`). +To uninstall: `uv tool uninstall mempalace`. + +#### System-wide / container install (opencode-devbox pattern) + +For a Docker image or a multi-user box where the shim should live on the system `PATH` rather than in each user's `~/.local/bin`, use `UV_TOOL_DIR` + `UV_TOOL_BIN_DIR` to relocate both the venv and the shim: + +```bash +# In the Dockerfile — this is the pattern used by opencode-devbox +ENV UV_TOOL_DIR=/opt/uv-tools +ENV UV_TOOL_BIN_DIR=/usr/local/bin + +RUN mkdir -p /opt/uv-tools && \ + uv tool install --no-cache mempalace && \ + /opt/uv-tools/mempalace/bin/python -c "import mempalace; print('mempalace installed')" +``` + +After this: +- `/opt/uv-tools/mempalace/` — the isolated venv. +- `/usr/local/bin/mempalace` — the CLI shim (globally on `PATH`, works for every user). + +The last `python -c` line in the RUN step is a build-time sanity check: if the install silently failed, the build fails here rather than at runtime. + +See [opencode-devbox/Dockerfile](https://gitea.jordbo.se/joakimp/opencode-devbox/src/branch/main/Dockerfile) §"MemPalace install" for the full production version (adds `INSTALL_MEMPALACE=true` build arg so the install can be skipped to shave ~300 MB off the image). + +#### MCP server wrapper (required for MCP clients on a system install) + +MCP clients (opencode, Claude Code, Kiro) spawn the mempalace MCP server as a subprocess. On a *personal-machine* install the command is just `mempalace-mcp` — the uv tool shim finds the venv's Python automatically. + +**Pitfall that bit us during the first opencode-devbox attempt:** on a *system install* with `UV_TOOL_DIR=/opt/uv-tools`, the system `python3` cannot import `mempalace` because the modules live in the isolated venv under `/opt/uv-tools/mempalace/lib/...`, not in system site-packages. Any MCP config that reads + +```json +{ "command": ["python3", "-m", "mempalace.mcp_server"] } +``` + +will fail at spawn with `ModuleNotFoundError: No module named 'mempalace'` — and because MCP failures are reported as "server unavailable" rather than surfacing the stderr, the root cause is easy to miss. + +**Fix:** ship a thin wrapper on `PATH` that exec's the venv's own Python. opencode-devbox ships this as `/usr/local/bin/mempalace-mcp-server`: + +```sh +#!/bin/sh +# Launcher for the MemPalace MCP server on a uv-tool install. +# System python3 cannot import mempalace from the isolated venv, +# so exec the venv's python directly with the mcp_server module. +exec /opt/uv-tools/mempalace/bin/python -m mempalace.mcp_server "$@" +``` + +…and MCP configs reference the wrapper instead: + +```json +{ "command": ["mempalace-mcp-server"] } +``` + +If you're on a personal-machine install (default `uv tool install` paths), you don't need the wrapper — `mempalace-mcp` is already a shim that does the right thing. The wrapper is specifically the workaround for the non-default `UV_TOOL_DIR` setup. + +See [opencode-devbox/AGENTS.md](https://gitea.jordbo.se/joakimp/opencode-devbox/src/branch/main/AGENTS.md) ("Critical conventions" → "MemPalace install path") for the authoritative reference. + +#### Verification checklist + +After any install (personal or system-wide), confirm: + +```bash +# CLI reachable from PATH +which mempalace # → a shim path +mempalace --version # → v3.3.3+ without import errors + +# CLI can import its own modules (catches venv vs site-packages mismatch) +mempalace status 2>&1 | head -3 # → either palace stats or "No palace found" — not a Python traceback + +# MCP server reachable (system install — only relevant if you set up the wrapper) +which mempalace-mcp-server # personal install: skip, uses `mempalace-mcp` directly +mempalace-mcp-server --help 2>&1 | head -5 # should show MCP server help, not import error +``` + +If any of these produce `ModuleNotFoundError`, you've hit the venv-mismatch pitfall. Re-read the MCP wrapper section above. + +### Install mempalace-toolkit ```bash git clone ssh://git@gitea.jordbo.se:2222/joakimp/mempalace-toolkit.git ~/mempalace-toolkit diff --git a/SKILL.md b/SKILL.md index 97ef932..6aa4f0f 100644 --- a/SKILL.md +++ b/SKILL.md @@ -33,6 +33,8 @@ Both follow the same **stage-to-cache-then-mine** idiom — they curate input in Prerequisites: `opencode` installed with an active DB at `~/.local/share/opencode/opencode.db`, `mempalace` CLI v3.3.3+, Python 3 (stdlib `sqlite3` only — no extra deps). +**If mempalace itself isn't installed yet**, suggest `uv tool install mempalace` (not `pip install mempalace` — it fights PEP 668 on modern distros and leaks deps into system site-packages). For a system-wide install on a container or shared box, set `UV_TOOL_DIR=/opt/uv-tools` + `UV_TOOL_BIN_DIR=/usr/local/bin` before `uv tool install`, and ship an MCP wrapper on `PATH` that exec's the venv's Python — otherwise MCP clients fail silently with `ModuleNotFoundError`. Full recipe in `mempalace-toolkit/README.md#installing-mempalace-itself-prerequisite`. + ```bash # 1. Clone mempalace-toolkit (holds the two wrappers in bin/) git clone ssh://git@gitea.jordbo.se:2222/joakimp/mempalace-toolkit.git ~/mempalace-toolkit