Archived
* Persist notification images so history keeps avatars Persisted popup and history entries stored image/appIcon as URLs into resources that die with the live notification: Chromium-family senders (every Omarchy web app, WhatsApp included) pass avatars as files in a scoped /tmp dir deleted when the notification closes, and raw image-data hints surface as in-process image:// URLs that die with the server object. Replaying history then found dead references and hid the icon. Copy file-backed images into the notification state dir when persisting, keyed by the entry's file stem, and reference the copies from the JSON. Blank dead image:// URLs so the card falls back to the app icon. The copies die with their JSON: superseded-popup deletes, history trims and clears remove them, and a startup sweep collects copies orphaned by a restart killing a queued job mid-write. Hold DND-silenced notifications open until their history write has run, since untracking tells the sender to delete its avatar file, and carry replayed on-screen rows over via their persisted copies, since the replay dismisses their live notifications first. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Coalesce silenced updates and bound image copies through temp files A replaces_id update lands on a held DND notification without a second onNotification, so releasing after the first write could persist a stale snapshot. Re-snapshot when the write completes and write again until the content is stable, reusing the original file identity. The image copy reopened the sender-controlled path after checking it, so a file growing or becoming a FIFO mid-copy defeated the size bound. Read through head -c under a timeout into a temp file, validate its size, and rename it into place; the startup sweep clears temp files a killed job leaves behind. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>