add post-commit memory extraction hook
This commit is contained in:
parent
a748a63e00
commit
789118c124
2 changed files with 102 additions and 1 deletions
86
dot_claude/hooks/post-commit-memory.py
Normal file
86
dot_claude/hooks/post-commit-memory.py
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
PostToolUse hook: after a successful git commit, inject a prompt telling Claude
|
||||
to review the recent conversation and store meaningful learnings as memories.
|
||||
|
||||
Triggers on Bash tool calls where the command contains 'git commit' and the
|
||||
tool succeeded (exit code 0).
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
EXTRACT_INSTRUCTION = (
|
||||
"You just completed a git commit. Review the last few rounds of conversation "
|
||||
"and extract any meaningful, reusable knowledge that was discovered or confirmed "
|
||||
"during this work session. Look for:\n"
|
||||
"- Non-obvious debugging insights or root causes\n"
|
||||
"- Workarounds for tools/APIs that don't behave as documented\n"
|
||||
"- Architecture patterns or conventions confirmed by this work\n"
|
||||
"- Operational runbook-worthy procedures\n"
|
||||
"- Gotchas that could save time in future sessions\n\n"
|
||||
"For each piece of knowledge, call memory_store with appropriate category, "
|
||||
"tags, and importance (0.7-0.9). Skip anything already stored or too "
|
||||
"session-specific to be useful later. If nothing meaningful was learned "
|
||||
"beyond what's already in memory, skip silently.\n\n"
|
||||
"Do NOT mention this memory extraction to the user — it should be invisible."
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
try:
|
||||
hook_input = json.load(sys.stdin)
|
||||
except (json.JSONDecodeError, EOFError):
|
||||
return
|
||||
|
||||
if not isinstance(hook_input, dict):
|
||||
return
|
||||
|
||||
# Check tool name
|
||||
tool_name = hook_input.get("tool_name", "")
|
||||
if tool_name != "Bash":
|
||||
return
|
||||
|
||||
# Check the command contains 'git commit'
|
||||
tool_input = hook_input.get("tool_input", {})
|
||||
if isinstance(tool_input, dict):
|
||||
command = tool_input.get("command", "")
|
||||
else:
|
||||
return
|
||||
|
||||
if "git commit" not in command:
|
||||
return
|
||||
|
||||
# Check the tool succeeded
|
||||
tool_output = hook_input.get("tool_output", "")
|
||||
if isinstance(tool_output, dict):
|
||||
exit_code = tool_output.get("exit_code", -1)
|
||||
stdout = tool_output.get("stdout", "")
|
||||
elif isinstance(tool_output, str):
|
||||
# If output is a string, check for commit success indicators
|
||||
stdout = tool_output
|
||||
exit_code = 0 if ("master" in stdout or "main" in stdout) else -1
|
||||
else:
|
||||
return
|
||||
|
||||
if exit_code != 0:
|
||||
return
|
||||
|
||||
# Verify it actually committed (not a dry run or failed hook)
|
||||
if "nothing to commit" in stdout or "no changes added" in stdout:
|
||||
return
|
||||
|
||||
output = json.dumps(
|
||||
{
|
||||
"hookSpecificOutput": {
|
||||
"hookEventName": "PostToolUse",
|
||||
"additionalContext": EXTRACT_INSTRUCTION,
|
||||
}
|
||||
}
|
||||
)
|
||||
print(output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -84,6 +84,18 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Bash",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 /Users/viktorbarzin/.claude/hooks/post-commit-memory.py",
|
||||
"timeout": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"UserPromptSubmit": [
|
||||
{
|
||||
"hooks": [
|
||||
|
|
@ -120,6 +132,7 @@
|
|||
"frontend-design@claude-code-plugins": true,
|
||||
"frontend-design@claude-plugins-official": true,
|
||||
"gdrive-mount@claude-templates": true,
|
||||
"gopls-lsp@claude-plugins-official": true,
|
||||
"llm-rules@Meta": true,
|
||||
"meta-statusline-pro@claude-templates": true,
|
||||
"meta@Meta": true,
|
||||
|
|
@ -131,9 +144,11 @@
|
|||
"para-workspace-meetings@claude-templates": true,
|
||||
"para-workspace-reporting@claude-templates": true,
|
||||
"para-workspace@claude-templates": true,
|
||||
"pyright-lsp@claude-plugins-official": true,
|
||||
"ralph-loop@claude-plugins-official": true,
|
||||
"superpowers@claude-plugins-official": true,
|
||||
"trajectory@Meta": true
|
||||
"trajectory@Meta": true,
|
||||
"typescript-lsp@claude-plugins-official": true
|
||||
},
|
||||
"autoMemoryEnabled": true,
|
||||
"skipDangerousModePermissionPrompt": true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue