8b26bf2ac3
* fix: disambiguate hook block reasons to name MemPalace explicitly (#666) Replace "your memory system" with explicit MemPalace references and tool names (mempalace_diary_write, mempalace_add_drawer, mempalace_kg_add) in stop and precompact hook block reasons. This prevents Claude Code from misinterpreting the hook as a native auto-memory save instruction. Updated in both Python (hooks_cli.py) and standalone shell scripts. Also fix CONTRIBUTING.md Getting Started to show the fork-first workflow, matching the PR Guidelines section. * fix: remove chromadb <0.7 upper bound — blocks 1.x installs The current constraint `chromadb>=0.5.0,<0.7` forces pip to install chromadb 0.6.x, but palaces created with chromadb 1.x (which is what the mempalace dev environment actually uses — 1.5.7 per uv.lock) have an incompatible SQLite schema. Specifically, chromadb 0.6.x fails with `KeyError: '_type'` when opening a collection written by 1.x. This means a fresh `pip install mempalace` gives users a chromadb version that cannot read palaces created in the maintainer's own environment. The fix removes the upper bound so pip can resolve to the current stable chromadb release. Reproduction: python3 -m venv .venv && source .venv/bin/activate pip install mempalace # installs chromadb 0.6.3 # Try opening a palace created with chromadb 1.x: # -> _get_collection() returns None, tool_status() returns "No palace found" pip install chromadb==1.5.7 # force upgrade # -> tool_status() returns real data (26k drawers in our case) --------- Co-authored-by: z3tz3r0 <kittipan.wang@gmail.com> Co-authored-by: AlyciaBHZ <50111876+AlyciaBHZ@users.noreply.github.com> Co-authored-by: Ben Sigman <1872138+bensig@users.noreply.github.com>
78 lines
2.9 KiB
Bash
Executable File
78 lines
2.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# MEMPALACE PRE-COMPACT HOOK — Emergency save before compaction
|
|
#
|
|
# Claude Code "PreCompact" hook. Fires RIGHT BEFORE the conversation
|
|
# gets compressed to free up context window space.
|
|
#
|
|
# This is the safety net. When compaction happens, the AI loses detailed
|
|
# context about what was discussed. This hook forces one final save of
|
|
# EVERYTHING before that happens.
|
|
#
|
|
# Unlike the save hook (which triggers every N exchanges), this ALWAYS
|
|
# blocks — because compaction is always worth saving before.
|
|
#
|
|
# === INSTALL ===
|
|
# Add to .claude/settings.local.json:
|
|
#
|
|
# "hooks": {
|
|
# "PreCompact": [{
|
|
# "hooks": [{
|
|
# "type": "command",
|
|
# "command": "/absolute/path/to/mempal_precompact_hook.sh",
|
|
# "timeout": 30
|
|
# }]
|
|
# }]
|
|
# }
|
|
#
|
|
# For Codex CLI, add to .codex/hooks.json:
|
|
#
|
|
# "PreCompact": [{
|
|
# "type": "command",
|
|
# "command": "/absolute/path/to/mempal_precompact_hook.sh",
|
|
# "timeout": 30
|
|
# }]
|
|
#
|
|
# === HOW IT WORKS ===
|
|
#
|
|
# Claude Code sends JSON on stdin with:
|
|
# session_id — unique session identifier
|
|
#
|
|
# We always return decision: "block" with a reason telling the AI
|
|
# to save everything. After the AI saves, compaction proceeds normally.
|
|
#
|
|
# === MEMPALACE CLI ===
|
|
# This repo uses: mempalace mine <dir>
|
|
# or: mempalace mine <dir> --mode convos
|
|
# Set MEMPAL_DIR below if you want the hook to auto-ingest before compaction.
|
|
# Leave blank to rely on the AI's own save instructions.
|
|
|
|
STATE_DIR="$HOME/.mempalace/hook_state"
|
|
mkdir -p "$STATE_DIR"
|
|
|
|
# Optional: set to the directory you want auto-ingested before compaction.
|
|
# Example: MEMPAL_DIR="$HOME/conversations"
|
|
# Leave empty to skip auto-ingest (AI handles saving via the block reason).
|
|
MEMPAL_DIR=""
|
|
|
|
# Read JSON input from stdin
|
|
INPUT=$(cat)
|
|
|
|
SESSION_ID=$(echo "$INPUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('session_id','unknown'))" 2>/dev/null)
|
|
|
|
echo "[$(date '+%H:%M:%S')] PRE-COMPACT triggered for session $SESSION_ID" >> "$STATE_DIR/hook.log"
|
|
|
|
# Optional: run mempalace ingest synchronously so memories land before compaction
|
|
if [ -n "$MEMPAL_DIR" ] && [ -d "$MEMPAL_DIR" ]; then
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_DIR="$(dirname "$SCRIPT_DIR")"
|
|
python3 -m mempalace mine "$MEMPAL_DIR" >> "$STATE_DIR/hook.log" 2>&1
|
|
fi
|
|
|
|
# Always block — compaction = save everything
|
|
cat << 'HOOKJSON'
|
|
{
|
|
"decision": "block",
|
|
"reason": "COMPACTION IMMINENT (MemPalace). Save ALL session content before context is lost:\n1. mempalace_diary_write — thorough AAAK-compressed session summary\n2. mempalace_add_drawer — ALL verbatim quotes, decisions, code, context\n3. mempalace_kg_add — entity relationships (optional)\nBe thorough — after compaction, detailed context will be lost. Do NOT write to Claude Code's native auto-memory (.md files). Save everything to MemPalace, then allow compaction to proceed."
|
|
}
|
|
HOOKJSON
|