Skip to content

fix(workspaces): clear sync row on close so overview doesn't tag closed workspaces as "other device"#43

Merged
Zeus-Deus merged 1 commit into
mainfrom
check-workspaces-session
May 27, 2026
Merged

fix(workspaces): clear sync row on close so overview doesn't tag closed workspaces as "other device"#43
Zeus-Deus merged 1 commit into
mainfrom
check-workspaces-session

Conversation

@Zeus-Deus

Copy link
Copy Markdown
Owner

Summary

  • After closing a workspace, the Workspaces overview briefly rendered the just-closed workspace as "lives on another device" until the 30 s background reconcile loop caught up.
  • Root cause: both close paths in commands/workspace.rs removed the workspace from app_state and emitted to the frontend, but never reconciled workspaces_sync. The orphan sync row (now with a workspace_id that no longer matched any live workspace) was then classified as kind: "remote" by useOverviewItems and rendered with the "other device" badge.
  • Fix:
    1. Backend (root cause)close_workspace_with_worktree_impl and close_workspace now reconcile_from_snapshot immediately after state.close_workspace(...) so the orphan row is soft-deleted in the same tick the frontend re-renders, then best-effort try_sync_with_app so sibling devices learn about the close without waiting for the 30 s tick. Failures 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. True sibling-device rows always have workspace_id === null until adoption, so a non-null workspace_id with 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.toml
  • cargo test --manifest-path src-tauri/Cargo.toml --lib workspaces_sync::tests:: — 9/9 pass, including 3 new ones:
    • reconcile_inserts_row_for_new_workspace
    • reconcile_soft_deletes_row_when_workspace_closed (regression guard)
    • reconcile_preserves_pulled_only_rows
  • npm run check (tsc) — clean
  • npm run test — 1766 tests pass, including 5 new ones in use-overview-items.test.ts covering kind:local / kind:remote classification and the self-orphan skip
  • Manual reproduction: closing a workspace no longer shows it as "other device" in the overview

Pre-existing failing test on origin/main not introduced by this PR: commands::mcp::tests::project_codemux_entry_is_filtered_out (reproduces on a clean checkout of main).

Incidental

package-lock.json picks up the 0.6.1 → 0.7.0 version follow-on from commit 20f539a chore: bump version to 0.7.0.

… 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.
@Zeus-Deus Zeus-Deus merged commit 90c1b3e into main May 27, 2026
2 checks passed
@Zeus-Deus Zeus-Deus deleted the check-workspaces-session branch May 27, 2026 12:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant