First half of the autosave/recovery feature — the write side.
Every ~45s while the document is dirty, write the full current state into a
per-session recovery .beam in the app data dir (directories::ProjectDirs data
dir + /recovery/session-<uuid>.beam). Fully background: reuses the existing file
worker, so the pool serialization / encode / DB write all happen off the UI
thread. The only UI-thread cost is one document clone — and build_save_command
now stamps the UI layout onto the *snapshot clone* rather than the live document
(the old prepare_document_for_save mutated live state via Arc::make_mut, which
could deep-clone the whole document mid-frame). Removed that dead helper.
Dirtiness is tracked centrally via ActionExecutor::epoch() (now also bumped on
undo/redo, not just execute) plus a pending_event flag set by non-action changes
(imports, finished recordings). The baseline is rebased on new/load/manual-save
so a freshly-loaded or just-saved project stays quiet. Idle-after-edit still gets
one snapshot via a single request_repaint_after wakeup; completion is polled
lazily (no forced repaints during the write).
on_exit deletes the session's recovery file, so a leftover file on next launch
means an unclean shutdown — the hook the recovery prompt (next commit) keys on.