fix(hooks): use mempalace shim instead of bare python3 -m mempalace - #325
fix(hooks): use mempalace shim instead of bare python3 -m mempalace#325naiyanat wants to merge 1 commit into
python3 -m mempalace#325Conversation
The hook scripts invoke the mempalace CLI via `python3 -m mempalace`, which
breaks whenever `$PATH` resolves `python3` to a Python venv that doesn't have
the mempalace module installed.
This is not hypothetical: on any machine where a Python tool has been installed
via `uv tool install` (kimi-cli, llm, aider, etc.), `~/.local/share/uv/tools/
<tool>/bin` sits earlier in `$PATH` than `/opt/homebrew/bin` or `/usr/bin`, so
bare `python3` resolves to that tool's isolated venv. The venv has no
mempalace, so every hook invocation fails with:
python3: No module named mempalace
which silently breaks auto-save on Stop and PreCompact.
The fix is to call the `mempalace` shim directly. pipx/pip/uv all install a
wrapper in `~/.local/bin/mempalace` (or equivalent) that internally dispatches
to the correct venv's Python — so it's immune to `$PATH` ordering for `python3`
itself and survives Python version upgrades.
This matches what the hook comments already document as the intended CLI:
# === MEMPALACE CLI ===
# This repo uses: mempalace mine <dir>
The five affected scripts are thin wrappers, so the change is a pure
text-substitution with no behavioural difference on machines where both forms
already work, and a fix on machines where only the shim works.
Relates to MemPalace#323 (hook subcommand error).
web3guru888
left a comment
There was a problem hiding this comment.
Excellent PR. The bug report is thorough — the uv tool install PATH hijack is real and increasingly common as uv adoption grows. The fix is minimal and correct.
Why this is right:
mempalaceshim resolves to the correct venv regardless of$PATHordering forpython3- The shim is installed by all standard methods (pip, pipx, uv, Claude Code plugin)
- The 5-line diff is pure text substitution in shell scripts — zero risk of Python regressions
- The intentional exclusions are well-reasoned (absolute-path
.venv/bin/python3, stdlib-onlypython3 -ccalls)
Overlap note: This PR is orthogonal to #340 (MCP entry point for pipx/uv) and #410 (PEP 668 entry point fix) — #325 fixes hook scripts, while #340/#410 fix the MCP server and CLI entry points. All three could land independently.
One edge case: If someone installed mempalace via git clone + pip install -e . but didn't install it as a system shim (just uses python3 -m mempalace), the hooks would break. But that's an uncommon dev-only setup, and the fix is just pip install -e . which creates the shim anyway. Worth a note in the hook comments, but not a blocker.
Clean, focused, well-documented. +1
🔭 Reviewed as part of the MemPalace-AGI integration project — autonomous research with perfect memory. Community interaction updates are posted regularly on the dashboard.
|
Hi, thanks for the contribution. This PR has merge conflicts with Could you rebase onto If this change is no longer relevant, feel free to close the PR. (This message is part of a periodic backlog pass, sent to all open PRs that match this state.) |
Summary
Replaces
python3 -m mempalacewith themempalaceshim in all 5 hook scripts. This fixes silent auto-save failures on any machine where$PATHresolvespython3to a venv that doesn't have mempalace installed.The Bug
Hook scripts invoke the CLI via:
On any machine where a Python tool has been installed via
uv tool install(e.g.kimi-cli,llm,aider),~/.local/share/uv/tools/<tool>/binsits earlier in$PATHthan/opt/homebrew/binor/usr/bin. Barepython3then resolves to that tool's isolated venv, which has no mempalace, and every hook fires:On Claude Code this shows up as a Stop hook error on every conversation exit, which silently breaks auto-save. I hit this on a Mac Mini with
kimi-cliinstalled viauv tool install kimi-cli. I'd expect it to be common —uvis mainstream now anduv toolis the recommended install path for Python CLIs.The Fix
Call the
mempalaceshim directly. pipx, pip, and uv all install a wrapper at~/.local/bin/mempalace(or equivalent) that internally dispatches to the correct venv's Python — so it's immune to$PATHordering forpython3itself and survives Python version upgrades.This also matches what the hook comments already document as the intended CLI:
So the shell was diverging from its own documentation. The PR just brings them back into alignment.
Files Changed
5 files, 5 lines — pure text substitution:
.claude-plugin/hooks/mempal-stop-hook.shmempalace hook run --hook stop --harness claude-code.claude-plugin/hooks/mempal-precompact-hook.shmempalace hook run --hook precompact --harness claude-code.codex-plugin/hooks/mempal-hook.shmempalace hook run --hook "$HOOK_NAME" --harness codexhooks/mempal_save_hook.shmempalace mine "$MEMPAL_DIR"(optional auto-ingest block)hooks/mempal_precompact_hook.shmempalace mine "$MEMPAL_DIR"(optional auto-ingest block)Intentionally left alone:
examples/gemini_cli_setup.md— uses.venv/bin/python3 -m mempalace, an absolute path which is immune to the hijackmempalace/onboarding.py— thepython3 -m mempalace.onboardingstring is a user-facing hint in a docstring, not a runtime callpython3 -ccalls inhooks/mempal_*.sh— these only need stdlib (sys,json), which any python3 has, so they're not affected by the hijackCompatibility
python3already resolves to a python with mempalace installed.mempalaceshim on$PATH— which is the case for anyone who installed viapip install mempalace,pipx install mempalace,uv tool install mempalace, or the Claude Code plugin's bundled install.Relates To
hooksubcommand #323 —mempal-stop-hook.sh calls nonexistent hook subcommand. That issue is a different failure mode (running against mempalace 3.0.0 from PyPI, which doesn't have thehooksubcommand yet — 3.0.14+ does). This PR is orthogonal: it fixes the$PATHhijack that triggers before the subcommand even runs. Both need to be resolved for the plugin to work out of the box.Bundle hook scripts in pip package. That's the long-term architectural fix. This PR is a minimal stopgap that unblocks users today without touching package layout.Test Plan
grep -r "python3 -m mempalace" .claude-plugin .codex-plugin hooksreturns no matches{}with exit 0 instead of theNo module named mempalaceerror)pytest tests/irrelevant for this change, but happy to run it if CI requestsThanks for mempalace — it's been great!