Wire optimistic updates through useDirectory via an overlay layer
useTreeMutation had always accepted an optimisticUpdate transform, but
the transform only wrote to the react-query cache — a surface no
subscription-based consumer reads from. The live UI (FileView et al.)
renders from useDirectory, which subscribes to FileManager.watchDirectory
and reads nothing from react-query. So every "optimistic" delete,
upload, rename, or move was silently invisible, and users waited ~1s
for the SSE echo before seeing their own action.
Introduce an OptimisticOverlay: a per-scope (cabinet or keyring URI)
store of snapshot-transforming patches. OpakeProvider owns one per
Opake instance. useDirectory projects the overlay onto the base
snapshot at render; the projection is a no-op when no patches are
active, so scopes that never see mutations pay nothing.
useTreeMutation pushes the same optimisticUpdate transform into the
overlay on onMutate and releases it after the mutation settles. Error
releases immediately; success delays the release by 2s so the SSE
echo has time to update the base snapshot before the patch drops —
otherwise the UI flickers back to the pre-mutation state in the gap
between PDS write and indexer broadcast.
The existing react-query cache path stays for useTree, which still
reads from that cache.