fix(workspaces): clear sync row on close so overview doesn't tag closed workspaces as "other device"#43
Merged
Merged
Conversation
… just-closed workspace as "other device" After closing a workspace on this device, opening the Workspaces overview briefly rendered the closed workspace as "lives on another device" until the background reconcile loop caught up ~30s later. Two changes: 1. Close paths now reconcile + push immediately. Both `close_workspace_with_worktree_impl` and `close_workspace` now call `reconcile_from_snapshot` right after the in-memory state mutation and before the optimistic frontend emit, then best-effort `try_sync_with_app` so sibling devices learn about the close without waiting on the 30s tick. Errors are non-fatal (logged) — the close itself already succeeded. 2. Frontend defense in depth. `useOverviewItems` step 2 now skips sync rows whose `workspace_id` is non-null — those are self-orphans from a recently-closed workspace, NOT sibling-device rows. True sibling-device rows always have `workspace_id === null` until adoption. Without this guard, any future code path that forgets to reconcile would re-introduce the same UI bug. Tests: - `reconcile_inserts_row_for_new_workspace` — baseline. - `reconcile_soft_deletes_row_when_workspace_closed` — regression guard for the exact bug. - `reconcile_preserves_pulled_only_rows` — make sure sibling-device rows aren't collateral damage. - `use-overview-items.test.ts` — five scenarios covering kind:local / kind:remote classification and the self-orphan skip. Incidental: package-lock.json picks up the 0.6.1 -> 0.7.0 version follow-on from the previous `chore: bump version` commit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
commands/workspace.rsremoved the workspace fromapp_stateand emitted to the frontend, but never reconciledworkspaces_sync. The orphan sync row (now with aworkspace_idthat no longer matched any live workspace) was then classified askind: "remote"byuseOverviewItemsand rendered with the "other device" badge.close_workspace_with_worktree_implandclose_workspacenowreconcile_from_snapshotimmediately afterstate.close_workspace(...)so the orphan row is soft-deleted in the same tick the frontend re-renders, then best-efforttry_sync_with_appso sibling devices learn about the close without waiting for the 30 s tick. Failures are non-fatal (logged) — the close itself already succeeded.useOverviewItemsstep 2 now skips sync rows whoseworkspace_idis non-null. True sibling-device rows always haveworkspace_id === nulluntil adoption, so a non-nullworkspace_idwith no matching local workspace can only be a self-orphan, never an actual sibling-device row.Test plan
cargo check --manifest-path src-tauri/Cargo.tomlcargo test --manifest-path src-tauri/Cargo.toml --lib workspaces_sync::tests::— 9/9 pass, including 3 new ones:reconcile_inserts_row_for_new_workspacereconcile_soft_deletes_row_when_workspace_closed(regression guard)reconcile_preserves_pulled_only_rowsnpm run check(tsc) — cleannpm run test— 1766 tests pass, including 5 new ones inuse-overview-items.test.tscovering kind:local / kind:remote classification and the self-orphan skipPre-existing failing test on
origin/mainnot introduced by this PR:commands::mcp::tests::project_codemux_entry_is_filtered_out(reproduces on a clean checkout ofmain).Incidental
package-lock.jsonpicks up the 0.6.1 → 0.7.0 version follow-on from commit20f539a chore: bump version to 0.7.0.