Inline Persistent Watchers¶
How #wb/cmd/* tags declared persistent install a PersistentWatcher that survives Obsidian restarts
Details¶
Persistent watchers¶
When a handler declares persistent=True, a detected #wb/cmd/<name> tag does NOT invoke the handler immediately. Instead, the dispatcher registers a PersistentWatcher row in data/agents/inline.db.
Reconciliation (sidecar_jobs/inline-sync.md)¶
Runs every 10 min via the sidecar, calls inline_sync:
- For each persistent command, scan the vault for files containing its tag via
work_buddy.obsidian.tags.search_by_tag(..., mode="prefix"). - For each vault-present tag not in the store → create a watcher (heals drift if live detection missed one).
- For each stored watcher whose tag is no longer in its file → delete the watcher.
- For each enabled watcher that is due per its schedule → enqueue for execution.
This is the same vault-is-canonical discipline used by sidecar_jobs/task-sync.md.
Live cancellation¶
The Obsidian plugin POSTs to /inline/tag-removed when metadataCache.changed shows a previously-tracked tag is gone, so watchers are cancelled immediately (the sync job catches anything the live path misses).
Schema (inline_watchers table)¶
watcher_id(pk)command_namefile_path,tag,tag_lineparams(JSON)schedule(cron str or null)created_at,last_run_atenabled