Skip to content

Keep window navigation and saved layouts from overwriting each other #45

Description

@iamnbutler

Two Ace windows in the same browser profile can hold different live tab names but overwrite the same saved channel layout. During dogfooding of #43, ordinary reload persistence passed, but a later acknowledged rename was replaced by the other window's older name after navigating away and back.

Observed reproduction

  1. Open the same channel with a Terminal tab in two browser windows sharing one profile and origin.
  2. Use the tab API to give the tab different names in the two explicitly selected windows. In the observed run, the first window showed Agent check and the second showed API checks. Live isolation worked: renaming one window did not change the other's visible label.
  3. Reload persistence had already passed earlier in this run with the first window named Only this window and the second named API checks, before the real agent renamed the first to Agent check.
  4. Open the second window's Channels sidebar and switch it to another channel. Both windows follow that navigation because selected-channel state is synchronized across the profile.
  5. Close the second window, then return the first window to the original channel.
  6. The first window restores API checks, replacing its acknowledged Agent check label.

The rename command completed against the intended live window. The loss happens later through the existing shared persistence and navigation behavior.

Existing ownership

apps/app/src/layout/storage.ts reads and writes the entire layout under ace:channel-layout:<channel-id> in localStorage. The record includes tab names, pane state, and terminal IDs; there is no window identity in the key.

Each mounted layout reads that record once into independent React state (apps/app/src/layout/layout.tsx, around line 651). It rewrites the whole saved record when its split state, tab metadata, or automatic-diff flag changes (around line 669). Those writes have no conflict detection or merge, and layouts do not subscribe to each other's saved-layout updates. Consequently, a later write from a window with older metadata can replace a newer saved tab name.

Navigation has a different policy: the app uses useLocalStorage for the current page, project, and selected channels, and that hook subscribes to cross-window storage events. This makes navigating in one window also move another window and remount its channel layout from the shared record.

Expected work

  • Decide and document ownership for window navigation and saved tab layouts. If windows are independent live views, their restoration behavior must preserve that independence; if any state is intentionally shared, synchronize it consistently rather than letting stale whole-record writes win.
  • A change acknowledged in one window must not be silently lost through unrelated activity in another window.
  • Verify two windows with different tab labels, navigation, reload, closing either window, and reconnect. Check single-window restoration and existing saved layouts remain usable.
  • Keep this client UI state outside durable channel history. Handle any saved-format change explicitly; do not reset existing layouts to bypass the issue.

This is separate from the focused API/CLI work in #43, which retains the existing layout storage. Current documentation should state that names persist in the shared browser-profile layout and competing windows can overwrite it; successful live targeting does not yet imply independent saved layouts.

No matching open or closed issue was found when checking the repository's issues on October 4, 2026. Tracked by #5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions