Files
apple-notes-cli/.github/workflows
ingjieyeandClaude Opus 5 a8615b3c45 Read Apple Notes directly from its SQLite store
Splits the original single-file exporter into a package and adds a query
layer, so notes can be searched and read live instead of only exported.

Reading the Core Data store rather than driving Notes.app through AppleScript
is what makes full-text search practical. Measured on an 818-note store,
osascript needs ~0.325s per note body (`first note whose id is` is an
unindexed linear scan), so searching everything costs minutes; decoding every
gzipped protobuf body here takes 0.11s total. No cache, so results are always
current.

- store.py   read-only SQLite access, folder tree, attachments
- parser.py  gzip + protobuf decoding and Markdown rendering (moved verbatim)
- search.py  search, recency listing, single-note reads
- export.py  Markdown output and the incremental manifest

Three correctness details found while building this:

- Open with mode=ro, never immutable=1. The immutable flag makes SQLite skip
  the -wal file and silently serve a stale snapshot; the live store routinely
  carries megabytes of un-checkpointed WAL.
- Recently Deleted is ZFOLDERTYPE = 1, and notes in it keep
  ZMARKEDFORDELETION = 0, so the existing filter still surfaced them. Matching
  the folder type is also language-independent. Now excluded by default.
- Creation timestamps live in whichever of ZCREATIONDATE..3 is populated, so
  every candidate column is read.

Export no longer writes a CLAUDE.md into the output directory unless asked
with --write-claude-md.

tests/test_parity.py keeps the original suite byte-for-byte as a regression
check on the split; test_search.py covers the new query layer against a
synthetic store. 48 tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 16:38:00 +08:00
..