- reader: list_memories() queries memory_meta; lookup_memories() uses FTS5 with
fallback to JSON index substring search
- writer: write_memory() and append_memory() upsert to DB after every file write
- dirs: bootstrap() calls init_db() + migrate_from_files() on startup
Existing .md files remain the canonical store; SQLite is the search index.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Gives Pyra an active memory brain: memory_index.json tracks summary +
keywords per file (like an inode table), and three built-in tools let
the AI look up, read, and overwrite memory mid-session. write_memory
accepts summary/keywords; update_index() merges the JSON index without
losing existing metadata.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
_MEMORY_ROOT was defined independently in reader.py, writer.py, and
index.py. Moved to memory/__init__.py; all three import from there.
Also fixes a bug in append_memory where path.write_text() was called
before path.parent.mkdir(), which would crash when creating a file in
a new subdirectory.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- memory/index.py: auto-regenerate MEMORY_INDEX.md on every write
- memory/reader.py: list_memories(), read_memory(), load_context_for_session()
all go through assert_safe_path() + relative_to check
- memory/writer.py: write_memory(), append_memory() — relative names only,
no absolute paths or traversal, calls update_index() after every write
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>