Per-file ambient notes for Claude Code, stored in .DS_Store under a custom record code (llMD).
The OS already maintains a B-tree keyed by filename in every directory you've ever opened in Finder. This plugin uses it as a sidecar-free, agent-managed documentation store.
- Notes auto-inject into context when the agent reads a file.
- The agent gets nudged to refresh the note after edits that invalidate it.
- Delete the file → the note orphans → self-cleaning lifecycle. No stale docs.
- No
.claude.mdsidecars. No inline comment pollution. NoCLAUDE.mdper directory.
The trick: there is already a per-directory, per-filename, B-tree-indexed metadata store on every macOS machine. We're just reusing it for a payload it was not designed for.
/plugin marketplace add brysontang/.DS_Store
/plugin install dsstore-notes@dsstore
Or local dev:
git clone git@github.com:brysontang/.DS_Store.git ~/code/dsstore-notes
claude --plugin-dir ~/code/dsstore-notesRequirements: macOS, uv on PATH. Hook commands invoke uv run against the bundled pyproject.toml; the project auto-syncs on first invocation, no manual install step.
- Agent calls
Read(file_path=…). - PreToolUse hook (
dsstore-inject) fires. - Hook opens
<dir>/.DS_Store, looks up thellMDrecord for that filename. - If found, hook emits
additionalContextso the note appears in the agent's context for that turn — no separate read action needed.
- Agent calls
Edit | Write | MultiEdit(file_path=…). - PostToolUse hook (
dsstore-breadcrumb) fires:- Drops a breadcrumb at
$TMPDIR/claude_dsstore_breadcrumbwith the resolved path. - Emits
additionalContext: the current note + a nudge to callupdate_recent_noteif the edit invalidated it.
- Drops a breadcrumb at
- Agent calls
update_recent_note(note: str). The MCP tool reads the breadcrumb to know which file — the agent never specifies the path. That narrowness is the behavioral nudge: post-write, calling this tool is the cheapest available action. Good behavior becomes the path of least resistance.
| Tool | Args | Purpose |
|---|---|---|
update_recent_note |
note: str |
Set the note on the file you most recently modified (path inferred from the breadcrumb). Empty string deletes. |
read_ambient_note |
file_path: str |
Explicit lookup for any file. Escape hatch. |
.DS_Store/ # the repo (also the marketplace)
├── .claude-plugin/
│ ├── marketplace.json # single-plugin marketplace catalog
│ └── plugin.json # Claude Code plugin manifest
├── .mcp.json # MCP server registration
├── hooks/hooks.json # PreToolUse + PostToolUse bindings
├── dsstore_notes/ # Python package (uv project)
│ ├── store.py # ds_store lib wrapper, llMD record I/O
│ ├── inject.py # PreToolUse hook (Read)
│ ├── breadcrumb.py # PostToolUse hook (Edit/Write/MultiEdit)
│ └── server.py # FastMCP server
├── pyproject.toml
└── .DS_Store # this repo's own notes — eat your own dogfood
The committed .DS_Store files in this repo carry their own llMD notes for the source files. Load the plugin and read dsstore_notes/store.py — you'll see the note about ds_store lib quirks inject into context. The plugin demos itself.
- macOS only.
.DS_Storeis a Finder format. Theds-storePython lib runs on Linux, but.DS_Storefiles only naturally exist on macOS. - Finder also writes here. Opening a directory in Finder rewrites
.DS_Storewith window state (Iloc,bwsp,icvp). Unknown record types likellMDare preserved, but if the repo's.DS_Storeis committed, expect diff noise from any Finder click. Tradeoff for the demo. - Trust-the-agent design. The agent owns cleanup. If your edits invalidate the note, you're expected to refresh it. If you can't trust the agent for that, the whole architecture collapses — but if you can't, agentic coding has bigger problems than stale notes.
ds-storeis lightly maintained. Works fine for the round-trips this plugin performs.- Codex support is partial. The MCP tools work anywhere MCP is supported. The auto-inject-on-read hook is Claude-Code-specific (Codex doesn't fire hooks on file reads as of this writing).
.DS_Store records are keyed by 4-byte codes. llMD = "LLM metadata" — generic for any agent framework, distinct from codes Finder uses (Iloc, BKGD, bwsp, icvp, etc.).
Do things because they're funny. The joke is the mnemonic.