fix(hooks): always mine the active transcript as convos, additive to MEMPAL_DIR
#1230 fixed --mode convos for the case where MEMPAL_DIR was unset, but left two configurations broken: - MEMPAL_DIR set to a project dir: convos never mined (MEMPAL_DIR overrode the transcript path); only project files were ingested. - MEMPAL_DIR set to a conversations dir per the old hooks/README: the projects miner ran on JSONL — same wrong-miner behaviour. The shell hooks (mempal_save_hook.sh, mempal_precompact_hook.sh) had the same MEMPAL_DIR-overrides-transcript bug AND were missing --mode on every spawned `mempalace mine` call. Make the auto-ingest *additive*. _get_mine_dir → _get_mine_targets, returning a list of (dir, mode) pairs: - MEMPAL_DIR (when valid) contributes (dir, "projects") - A valid transcript JSONL contributes (parent, "convos") - Both can appear together; the hook spawns one ingest per target Same change applied to the shell save and precompact hooks. Precompact also gained transcript_path parsing so it can run the convos mine synchronously before context is compressed. hooks/README.md updated to describe MEMPAL_DIR as a project-files target, never a convos target.
This commit is contained in:
@@ -41,17 +41,18 @@
|
||||
# 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.
|
||||
# The hook ALWAYS mines the active conversation transcript synchronously
|
||||
# before compaction (via `mempalace mine <transcript-dir> --mode convos`).
|
||||
# MEMPAL_DIR is an *additional*, optional target for project files — it
|
||||
# does not replace the conversation mine.
|
||||
|
||||
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).
|
||||
# Optional: project directory (code / notes / docs) to also mine before
|
||||
# compaction. Mined with `--mode projects`. The conversation transcript
|
||||
# is always mined regardless — this is purely additive.
|
||||
# Example: MEMPAL_DIR="$HOME/projects/my_app"
|
||||
MEMPAL_DIR=""
|
||||
|
||||
# Resolve the Python interpreter. Same contract as mempal_save_hook.sh:
|
||||
@@ -64,15 +65,34 @@ fi
|
||||
# Read JSON input from stdin
|
||||
INPUT=$(cat)
|
||||
|
||||
SESSION_ID=$(echo "$INPUT" | "$MEMPAL_PYTHON_BIN" -c "import sys,json; print(json.load(sys.stdin).get('session_id','unknown'))" 2>/dev/null)
|
||||
# Parse session_id and transcript_path in one call. Sanitize both before
|
||||
# interpolating into shell — same contract as mempal_save_hook.sh.
|
||||
eval $(echo "$INPUT" | "$MEMPAL_PYTHON_BIN" -c "
|
||||
import sys, json, re
|
||||
data = json.load(sys.stdin)
|
||||
sid = data.get('session_id', 'unknown')
|
||||
tp = data.get('transcript_path', '')
|
||||
safe = lambda s: re.sub(r'[^a-zA-Z0-9_/.\-~]', '', str(s))
|
||||
print(f'SESSION_ID=\"{safe(sid)}\"')
|
||||
print(f'TRANSCRIPT_PATH=\"{safe(tp)}\"')
|
||||
" 2>/dev/null)
|
||||
|
||||
# Expand ~ in path
|
||||
TRANSCRIPT_PATH="${TRANSCRIPT_PATH/#\~/$HOME}"
|
||||
|
||||
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
|
||||
# Run ingest synchronously so memories land before compaction. Two
|
||||
# independent targets — both run if both are set:
|
||||
# 1. TRANSCRIPT_PATH (from Claude Code) → parent dir, --mode convos
|
||||
# 2. MEMPAL_DIR → --mode projects
|
||||
if [ -n "$TRANSCRIPT_PATH" ] && [ -f "$TRANSCRIPT_PATH" ]; then
|
||||
mempalace mine "$(dirname "$TRANSCRIPT_PATH")" --mode convos \
|
||||
>> "$STATE_DIR/hook.log" 2>&1
|
||||
fi
|
||||
if [ -n "$MEMPAL_DIR" ] && [ -d "$MEMPAL_DIR" ]; then
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
mempalace mine "$MEMPAL_DIR" >> "$STATE_DIR/hook.log" 2>&1
|
||||
mempalace mine "$MEMPAL_DIR" --mode projects \
|
||||
>> "$STATE_DIR/hook.log" 2>&1
|
||||
fi
|
||||
|
||||
# Silent: return empty JSON to not block. "decision": "allow" is invalid —
|
||||
|
||||
Reference in New Issue
Block a user