Problem
The stop hook fires every 15 messages and returns a blocking instruction that tells Claude to make 3-4 MCP tool calls (mempalace_diary_write + multiple mempalace_add_drawer). Each call renders as an expanded indented JSON block in the terminal — parameters in, response out.
On narrow terminals (or any terminal), this is a significant amount of visual noise that interrupts the conversation flow. The user didn't ask to save — it's an automatic checkpoint — yet it takes over the screen for several seconds.
Proposed Solution
Have the stop hook save directly via the Python API instead of blocking and asking Claude to save via MCP:
- Extract recent user messages from the transcript (already available via
transcript_path)
- Build a compressed diary entry
- Write it directly using
tool_diary_write() as a Python function call (no MCP round-trip)
- Return
{} (non-blocking) — Claude's flow is never interrupted
- Show a single-line terminal notification (ANSI-colored, on stderr) + desktop toast via
notify-send
Before (current): 3-4 indented MCP tool blocks every 15 messages
After (proposed): ✦ MemPalace Checkpoint saved — 30 messages archived — one line, done
The precompact hook would still block, since compaction is rare and warrants a thorough AI-driven save.
Changes
hooks_cli.py: Add _extract_recent_messages(), _save_diary_direct(), _notify() helpers; change hook_stop to save directly and never block
tests/test_hooks_cli.py: Update stop hook tests (no longer expects blocking), add tests for _extract_recent_messages
- No new dependencies (
notify-send is standard on Linux, fails silently elsewhere)
Problem
The stop hook fires every 15 messages and returns a blocking instruction that tells Claude to make 3-4 MCP tool calls (
mempalace_diary_write+ multiplemempalace_add_drawer). Each call renders as an expanded indented JSON block in the terminal — parameters in, response out.On narrow terminals (or any terminal), this is a significant amount of visual noise that interrupts the conversation flow. The user didn't ask to save — it's an automatic checkpoint — yet it takes over the screen for several seconds.
Proposed Solution
Have the stop hook save directly via the Python API instead of blocking and asking Claude to save via MCP:
transcript_path)tool_diary_write()as a Python function call (no MCP round-trip){}(non-blocking) — Claude's flow is never interruptednotify-sendBefore (current): 3-4 indented MCP tool blocks every 15 messages
After (proposed):
✦ MemPalace Checkpoint saved — 30 messages archived— one line, doneThe precompact hook would still block, since compaction is rare and warrants a thorough AI-driven save.
Changes
hooks_cli.py: Add_extract_recent_messages(),_save_diary_direct(),_notify()helpers; changehook_stopto save directly and never blocktests/test_hooks_cli.py: Update stop hook tests (no longer expects blocking), add tests for_extract_recent_messagesnotify-sendis standard on Linux, fails silently elsewhere)