forked from retoor/devplacepy
The old sync compared only the two live sides (project rows vs workspace files), so a file present in the project but missing on disk was indistinguishable from "never materialized here yet" - it always got re-exported, which is why deleting a file inside a container made it come back. The mirror direction had the same bug: a file deleted from the project's file editor was silently re-imported from the container's stale copy on the next tick. Fixes it with a persisted per-file sync baseline (new project_file_sync_state table: db_epoch/fs_epoch as they stood right after the previous sync), the same role a rsync/Unison state file plays in any real bidirectional sync. Deleting on either side now propagates to the other, unless the deleted side's counterpart was edited after the last sync, in which case the edit wins and the file is restored. A read-only project always exports (never imports, including on tie) and always removes a workspace's stale local copy, so it stays a faithful mirror. Sync of an unchanged file is now a true no-op (zero writes) instead of rewriting it every ~60s tick forever. sync_dir_bidirectional's return dict gains deleted_in_project/ deleted_in_workspace alongside exported/imported; both API call sites already pass the whole dict through untouched. The instance sync toast now summarizes all four counts instead of just imports. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TjdKTWgWpW2SMNW8SFqxz5