9.2 KiB
1. Plugin directory and config
- 1.1 Create plugin directory structure:
~/.claude/plugins/memory/withhooks/andskills/subdirectories - 1.2 Write
~/.claude/plugins/memory/config.yamlwith configurable fields: vault path (~/Documents/SecondBrain), Graphify output dir, Ollama model (qwen25-coder-7b-16k), num_ctx (8192), stale threshold (7 days), and env vars (OLLAMA_FLASH_ATTENTION=1,GRAPHIFY_OLLAMA_NUM_CTX=8192,GRAPHIFY_OLLAMA_KEEP_ALIVE=5) - 1.3 Write a
README.mdfor the plugin documenting: thereasoning_effort:"none"patch requirement, the pinned Graphify version (v0.8.31), the Modelfile-baked context approach (qwen25-coder-7b-16k), and how to verify the patch is present after anypip upgrade
2. SessionStart hook
- 2.1 Write
~/.claude/plugins/memory/hooks/session-start.sh: read stdin JSON viajq(fields:.cwd,.source); source config; check~/.cache/graphify/vault-rebuild.stampmtime vs. threshold — if stale or absent AND no lock file at~/.cache/graphify/vault-rebuild.lock, spawnnohup graphify extract <vault-path> --backend ollama --model <model> --force >> <logfile> 2>&1 &as a detached background process, write the lock file (background process removes it on completion), and continue immediately; do NOT wait for the rebuild (SessionStart blocks the session — it must return sub-second on the synchronous path). Log that a background rebuild was triggered. - 2.2 Extend
session-start.sh: inject vault god-node summary — read fromGRAPH_REPORT.mdor equivalent at the configured output dir; assemble context string (compact "map of what's known" block, not rawgraph.json) - 2.3 Extend
session-start.sh: injectconvention/*note summaries — attemptgraphify query "convention" --budget 500; fall back togrep -rl "convention/" <vault-path> | xargs grep -h "^summary:"if graph query returns empty; omit section silently if no convention notes found - 2.4 Extend
session-start.sh: inject episodic journal pointer — compute today's journal path (<vault-path>/journal/YYYY-MM-DD.md) and add as a one-line pointer; inject project graph path (<project-root>/graphify-out/graph.json) if that file exists (read.cwdfrom stdin JSON as working directory base; usegit rev-parse --show-toplevelfrom there or$CLAUDE_PROJECT_DIRconvention) - 2.5 Emit all injected content to stdout as
{"additionalContext": "<assembled-text>"}JSON and exit 0 — this is the confirmed Claude Code mechanism for hook-to-model context injection (Claude Code hooks documentation) - 2.6 Test
session-start.shstandalone (not via Claude Code harness): supply mock stdin JSON (echo '{"cwd":"/tmp","source":"startup"}' | ./session-start.sh); run with a clean stamp, a stale stamp (confirm background spawn, no block), a lock file already present (confirm no duplicate spawn), and a missing vault — confirm each path behaves as specified inmemory-plugin-hooks/spec.md
3. PostToolUse hook
- 3.1 Write
~/.claude/plugins/memory/hooks/post-tool-use-write.sh: source config; read stdin JSON viajq— extractFILE_PATH=$(jq -r '.tool_input.file_path')andTOOL_NAME=$(jq -r '.tool_name'); guard clause — skip if$FILE_PATHdoes not match<vault-path>/**/*.md; if it matches, rungraphify update --file "$FILE_PATH"; log error but do NOT block on non-zero exit (exit 0 always); also append$FILE_PATHto per-session temp log (see task 4.2)Deviation (2026-06-05):
graphify update --filedoes not exist in Graphify v0.8.31. The correct incremental update for markdown/doc files isgraphify extract <vault-path> --update --backend ollama --model <model>which uses SHA-256 content hashing to skip unchanged files. Running this synchronously in PostToolUse would block on Ollama. Adopted approach: PostToolUse deletes~/.cache/graphify/vault-rebuild.stamp(invalidates freshness). Next SessionStart detects the missing stamp and spawnsgraphify extract --updateas a detached background process, refreshing only changed files. Graph freshness is deferred by at most one session start, not immediate. - 3.2 Test
post-tool-use-write.shstandalone: supply mock stdin JSON (echo '{"tool_name":"Write","tool_input":{"file_path":"<vault-path>/test.md"}}' | ./post-tool-use-write.sh); test with a vault.mdpath (confirm graphify update fires), a non-vault path (confirm nothing fires), and a path where graphify returns non-zero (confirm error is logged, script exits 0)
4. SessionEnd hook
- 4.1 Write
~/.claude/plugins/memory/hooks/session-end.sh: read stdin JSON viajq— extractSESSION_ID=$(jq -r '.session_id')andREASON=$(jq -r '.reason'); source config; compute today's journal path; if file does not exist, create it with minimal frontmatter (summary:,scope/global,type/log); append a timestamped entry with: current project (from$CLAUDE_PROJECT_DIRorgit rev-parse --show-toplevel), vault notes touched this session (read from temp log at/tmp/claude-vault-touched-$SESSION_ID— see task 4.2), UTC timestamp. Note: SessionEnd has no decision control (exit code ignored); use for cleanup/logging only. - 4.2 Extend
post-tool-use-write.shto append successfully-updated vault note paths to a per-session temp file/tmp/claude-vault-touched-$SESSION_IDwhereSESSION_IDis read from stdin JSON viajq -r '.session_id';session-end.shreads this same file using its own stdinsession_id. (Confirmed available:session_idis a field on stdin JSON for both PostToolUse and SessionEnd — Claude Code hooks documentation.) - 4.3 Test
session-end.shstandalone: supply mock stdin JSON (echo '{"session_id":"test-123","reason":"exit"}' | ./session-end.sh); run with notes in the temp file at/tmp/claude-vault-touched-test-123(confirm journal entry created with paths), run with no temp file (confirm minimal entry is still appended), run twice in one day (confirm append-only, no overwrite)
5. Skills authoring
- 5.1 Write
~/.claude/plugins/memory/skills/memory-query.md: cover all patterns frommemory-plugin-skills/spec.md— god-node-first discipline,graphify query/path/explainwith--budget/--dfs/--graph, cross-client lookups, explicit call-out that tag-based graph traversal is unverified (ADR-014), episodic questions → memsearch - 5.2 Write
~/.claude/plugins/memory/skills/memory-write.md: cover all rules from the spec — evergreen vs. ephemeral test, required frontmatter contract (summarywritten now,scope/, at least one facet tag), vault-not-repo rule, note that PostToolUse hook fires automatically on vault writes - 5.3 Write
~/.claude/plugins/memory/skills/memory-reorganize.md: cover the spec — plan-mode-only rule, three triggers (duplicate, recurrence-promotion, oversized note), consolidation procedure,--forcerebuild requirement after reorganization, ghost-node explanation - 5.4 Register the three skills in the plugin manifest (or
~/.claude/settings.json) so they are available as on-demand skills in Claude Code sessions- Note (2026-06-05): Skills in
~/.claude/plugins/memory/skills/require a marketplace entry to be auto-discovered viaenabledPlugins. The.claude-plugin/plugin.jsonmanifest is in place; a marketplace registration in~/.claude/settings.jsonextraKnownMarketplacespointing to~/.claude/plugins/is needed to complete skill auto-loading. Hooks fire independently of this.
- Note (2026-06-05): Skills in
6. Hook registration
- 6.1 Register
session-start.shas a SessionStart hook in~/.claude/settings.json - 6.2 Register
post-tool-use-write.shas a PostToolUse hook forWriteandEdittool calls in~/.claude/settings.json - 6.3 Register
session-end.shas a SessionEnd hook in~/.claude/settings.json
7. End-to-end validation against fixture set (ADR-013)
- 7.1 Start a Claude Code session in the fixture project — confirm SessionStart injects god-node list, at least one convention summary (if present), journal pointer, and project graph path
- 7.2 Write a test vault note during the session — confirm PostToolUse fires
graphify update --file(verify from hook log or graph.json mtime)Clarification (2026-06-05): PostToolUse fires stamp invalidation (deletes
~/.cache/graphify/vault-rebuild.stamp), triggering deferred incremental update on next SessionStart, per deviation note in task 3.1. - 7.3 End the session — confirm SessionEnd appended a journal entry to
<vault-path>/journal/YYYY-MM-DD.mdwith the note paths touched - 7.4 Trigger a stale rebuild: backdate the stamp file (or delete it) and restart the session — confirm SessionStart returns immediately (no freeze), background rebuild process spawns (check process list / logfile), lock file appears then clears, stamp is updated when rebuild completes; start a second concurrent session during rebuild and confirm the lock prevents a duplicate spawn
- 7.5 Test the convention-injection fallback: temporarily remove the vault graph and restart the session — confirm the grep fallback surfaces convention summaries (or the section is cleanly omitted if none exist)
- 7.6 Run each of the three skills (
/memory-query,/memory-write,/memory-reorganize) in a session and confirm the guidance loads and is coherent with the fixture set context