diff --git a/mem0-plugin/hooks/hooks.json b/mem0-plugin/hooks/hooks.json index 7a2a9664e..70d6575db 100644 --- a/mem0-plugin/hooks/hooks.json +++ b/mem0-plugin/hooks/hooks.json @@ -1,5 +1,18 @@ { "hooks": { + "Setup": [ + { + "matcher": "init|maintenance", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/ensure_deps.sh", + "statusMessage": "Installing mem0 SDK...", + "timeout": 120 + } + ] + } + ], "SessionStart": [ { "hooks": [ @@ -31,6 +44,16 @@ "command": "${CLAUDE_PLUGIN_ROOT}/scripts/block_memory_write.sh" } ] + }, + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/on_git_commit_capture.sh", + "timeout": 5 + } + ] } ], "PostToolUse": [ diff --git a/mem0-plugin/scripts/on_git_commit_capture.sh b/mem0-plugin/scripts/on_git_commit_capture.sh new file mode 100755 index 000000000..1ced327a0 --- /dev/null +++ b/mem0-plugin/scripts/on_git_commit_capture.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Hook: PreToolUse (matcher: Bash) +# +# Detects `git commit` commands and fires on_pre_commit.py in the background +# to capture staged changes as a mem0 memory. Never blocks the commit. +# +# Input: JSON on stdin with tool_name, tool_input +# Output: none (always exit 0) + +set -euo pipefail + +INPUT=$(cat) + +COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""' 2>/dev/null || echo "") + +if [ -z "$COMMAND" ]; then + exit 0 +fi + +case "$COMMAND" in + *"git commit"*|*"git merge"*|*"git rebase"*) + ;; + *) + exit 0 + ;; +esac + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + +if [ ! -x "$SCRIPT_DIR/on_pre_commit.py" ] && [ ! -f "$SCRIPT_DIR/on_pre_commit.py" ]; then + exit 0 +fi + +API_KEY="${MEM0_API_KEY:-${CLAUDE_PLUGIN_OPTION_MEM0_API_KEY:-}}" +if [ -z "$API_KEY" ]; then + exit 0 +fi + +git diff --cached --stat 2>/dev/null | python3 "$SCRIPT_DIR/on_pre_commit.py" & + +exit 0 diff --git a/mem0-plugin/skills/mem0-mcp/SKILL.md b/mem0-plugin/skills/mem0-mcp/SKILL.md index f0f95939c..4f560081e 100644 --- a/mem0-plugin/skills/mem0-mcp/SKILL.md +++ b/mem0-plugin/skills/mem0-mcp/SKILL.md @@ -276,14 +276,20 @@ add_memory( ### Access counter: track memory usage -When you retrieve a memory via `search_memories` and **actually use it** in your response (i.e., it informed your answer or you cited it), increment its access counter by calling: +When you retrieve a memory via `search_memories` and **actually use it** in your response (i.e., it informed your answer or you cited it), increment its access counter and update the last-accessed timestamp by calling: ```python # 1. Read current state mem = get_memory(memory_id=) current_text = mem["content"] # or mem["memory"], depending on response shape +current_meta = mem.get("metadata", {}) -# 2. Update with access_count bump +# 2. Bump access_count and set last_accessed +import datetime +current_meta["access_count"] = current_meta.get("access_count", 0) + 1 +current_meta["last_accessed"] = datetime.datetime.now(datetime.timezone.utc).isoformat() + +# 3. Update with preserved content update_memory( memory_id=, data=current_text, # preserve original text — required parameter @@ -294,4 +300,4 @@ update_memory( **When to increment:** Only when you actually used the memory to answer. Don't bump on every search hit — that inflates counts for memories that were returned but irrelevant. Aim for 1-3 bumps per response at most. -**Why:** Access counts feed into `/mem0:dream` pruning decisions. Memories that are never accessed after creation are candidates for cleanup. Frequently accessed memories are protected from pruning regardless of age. +**Why:** `access_count` and `last_accessed` feed into `/mem0:dream` pruning decisions. Memories that are never accessed after creation are candidates for cleanup. Frequently accessed memories are protected from pruning regardless of age.