This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
claude-code-auto-memory - A Claude Code plugin that automatically maintains CLAUDE.md files (or AGENTS.md for multi-agent repos) as codebases evolve. Tracks file changes via hooks, spawns agents to update memory, and provides skills for codebase analysis.
Key features:
- Real-time file tracking via PostToolUse hooks
- Stop hook integration to trigger memory updates
- Codebase analyzer skill for initial setup
- Memory processor skill for ongoing updates
- AGENTS.md support for multi-agent workflows (OpenAI Codex, Gemini, etc.)
# Install dependencies
uv sync
# Run tests
uv run pytest tests/ -v
# Run single test file
uv run pytest tests/test_hooks.py -v
# Lint code
uv run ruff check .
# Format code
uv run ruff format .
# Type check
uv run mypy scripts/.claude-plugin/ # Plugin manifest
plugin.json # Plugin metadata and version
agents/
memory-updater.md # Agent that updates CLAUDE.md files
commands/
init.md # /auto-memory:init command
calibrate.md # /auto-memory:calibrate command
status.md # /auto-memory:status command
sync.md # /auto-memory:sync command
hooks/
hooks.json # Hook registration
scripts/
post-tool-use.py # Tracks file edits to dirty-files
trigger.py # Consolidated handler for PreToolUse, Stop, and SubagentStop
skills/
codebase-analyzer/ # Initial CLAUDE.md generation
memory-processor/ # Ongoing CLAUDE.md updates
shared/ # Shared references
tests/
test_hooks.py # PostToolUse hook behavior tests
test_trigger.py # trigger.py unit tests
test_integration.py # Plugin structure tests
test_skills.py # Skill validation tests
Data flow:
- User edits files via Edit/Write tools or git operations (rm, mv)
- PostToolUse hook appends paths to session-specific
.claude/auto-memory/dirty-files-{session_id}(falls back todirty-fileswithout session_id) - PreToolUse hook (gitmode only) denies git commit until dirty files processed
- Stop hook detects dirty files, blocks Claude, requests agent spawn
- memory-updater agent processes files and updates CLAUDE.md
- SubagentStop hook auto-commits CLAUDE.md (if configured), clears dirty-files, cleans up stale session files
Configuration:
- Trigger modes:
default(after every turn) orgitmode(only after git commits) memoryFiles: Array specifying which memory file(s) to maintain -["CLAUDE.md"](default),["AGENTS.md"], or["CLAUDE.md", "AGENTS.md"](AGENTS.md holds content, CLAUDE.md redirects)autoCommit: When true, auto-commits memory file changes after memory-updater completesautoPush: When true (requires autoCommit), pushes commits to remote- Config stored in
.claude/auto-memory/config.json - Init wizard interactively configures triggerMode, memoryFiles, autoCommit, and autoPush, then updates
.gitignoreto excludedirty-files*tracking files
- Python: 3.9+ with type hints, snake_case naming
- Imports: Group stdlib, then third-party, then local
- Docstrings: Module-level docstrings explain purpose
- Hooks: Zero output for PostToolUse/SubagentStop (token cost), JSON output for Stop/PreToolUse
- Hook routing: Use hook_event_name from stdin JSON to differentiate behavior
- Hook commands: Use python3 with fallback (
python3 script.py || python script.py) for cross-platform compatibility - Skills/Commands: YAML frontmatter with name/description
- Line length: 100 characters (ruff config)
- Testing: pytest with descriptive test names (test_verb_condition)
- Hook Consolidation Pattern: Single trigger.py handles PreToolUse, Stop, and SubagentStop hooks, routing based on hook_event_name
- Initialization Guard Pattern:
plugin_initialized()in post-tool-use.py, handle_stop(), and handle_pre_tool_use() gates all activity on config.json existence — projects that never ran /auto-memory:init are fully inert - Hook Lifecycle Pattern: PostToolUse tracks → Stop/PreToolUse blocks → Agent spawns → SubagentStop cleans up (cleanup gated on dirty-files only, not config.json, to prevent infinite loops)
- Separation of Concerns: PostToolUse (silent tracking) vs Stop/PreToolUse (blocking with output) vs SubagentStop (cleanup)
- Dirty File Pattern: Dict-keyed deduplication (path as key), batch processing at turn end, session-isolated via
dirty-files-{session_id}; commit context entries overwrite plain path entries when present - Skill Pattern: YAML frontmatter + markdown body with algorithm sections
- Template Pattern: AUTO-MANAGED markers for updatable sections
- Config Pattern: JSON config in
.claude/auto-memory/config.jsonwithtriggerMode,autoCommit,autoPush - Inline Commit Context: Commit hash and message stored inline with file paths in dirty-files (
/path/to/file [hash: message]) - Session Isolation Pattern:
session_idfrom hook stdin JSON used to scope dirty-files per session, with fallback to shared file for backwards compatibility - Stale Session Cleanup Pattern:
cleanup_stale_session_files()removes orphaned session dirty-files older than 24h on each SubagentStop - Dirty-Files Read Order: memory-updater reads plain
dirty-filesfirst; checks session-specificdirty-files-*files only if plain file is empty or missing - Gitignore Management Pattern:
/auto-memory:initappends.claude/auto-memory/dirty-files*to.gitignore(creates file if absent) so tracking files are never committed - Bash Tracking Scope Pattern:
extract_files_from_bash()only tracks explicit file-destructive commands (rm, git rm, mv, git mv, unlink); all other Bash commands (read-only, build tools, package managers) are skipped; parser stops at shell operators (&&,||,;,|) and redirects - Test Init Helper Pattern:
_init_config(tmp_path)creates.claude/auto-memory/config.jsonin tests to satisfy theplugin_initialized()guard; tests that verify inert behavior deliberately omit this call - Memory File Selection Pattern:
memoryFilesin config.json determines active memory file; memory-updater reads config to findAGENTS.mdorCLAUDE.mdinstances; skills and commands all respect this config rather than hardcoding CLAUDE.md - AGENTS.md Redirect Pattern: When both CLAUDE.md and AGENTS.md are configured, CLAUDE.md contains a single-line redirect (
Read AGENTS.md in this directory for project context.); memory-processor skips updating redirect files - Multi-Agent Memory Pattern: AGENTS.md support enables shared memory across Claude Code, OpenAI Codex, Gemini, and other agents that read AGENTS.md; auto-commit message uses
chore: update memory files [auto-memory]when AGENTS.md is involved
Recent design decisions from commit history:
- Hook consolidation: stop.py removed, functionality merged into trigger.py for simpler maintenance
- SubagentStop hook added to automate dirty-files cleanup after agent completion
- Agent simplification: memory-updater.md no longer handles cleanup (delegated to SubagentStop)
- PreToolUse hook added for gitmode to intercept commits before they happen
- Template enforcement added to ensure consistent CLAUDE.md structure
- Git commit context enrichment for better change tracking
- Configurable trigger modes (default vs gitmode)
- Windows compatibility: python3/python fallback pattern in hook commands
- Default mode optimization: Skip git commit tracking (files already tracked via Edit/Write)
- SubagentStop cleanup gated on dirty-files only (not config.json): requiring config.json caused infinite Stop-hook loops on uninitialized projects where dirty-files never got cleared
- Initialization guard added (#17): plugin_initialized() check in PostToolUse, Stop, and PreToolUse keeps the plugin fully inert on projects that never ran /auto-memory:init
- Type annotations tightened: dict[str, Any] generics, typed main() -> None, narrowed handle_git_commit return type
- Session-aware dirty-files (#16): session_id from hook stdin JSON scopes dirty-files per session, preventing cross-session interference in concurrent workflows
- Auto-commit/push toggle (#18): autoCommit and autoPush config options in SubagentStop handler, commits only CLAUDE.md files with graceful failure handling
- handle_subagent_stop signature changed from (project_dir) to (input_data, project_dir) to receive session_id and support auto-commit config loading
- SubagentStop cleanup fix (#28/#29): build_spawn_reason() now explicitly passes subagent_type='auto-memory:memory-updater' in Task tool spawn instructions - omitting it caused SubagentStop to not fire and dirty-files to never be cleared
- AGENTS.md support added (#14, v0.9.2):
memoryFilesconfig option enables maintaining AGENTS.md instead of or alongside CLAUDE.md; init wizard, status, sync, codebase-analyzer, and memory-processor all updated to respect this config; CLAUDE.md redirect file generated when both are configured
From Claude Code documentation:
- Keep CLAUDE.md concise and focused on actionable guidance
- Use AUTO-MANAGED markers for sections that should be auto-updated
- Use MANUAL section for custom notes that persist across updates
- Subtree CLAUDE.md files inherit from root and add module-specific context
Add project-specific notes here. This section is never auto-modified.