* fix(web): fix dock view task-switching regressions
Three bugs caused broken UI when switching tasks in the dock view:
1. Environment key migration was dead code — data stored under fallback
sessionId keys became invisible when the environmentIdBySessionId
mapping was later set, because migrateEnvKeyedData was never called
in production (only in tests via registerSessionEnvironment).
2. Orphaned portals leaked on every fast-path session switch — the
isRestoringLayout guard in setupPortalCleanup blocked portal release
for panels removed during the fast path, accumulating invisible React
trees with live WS subscriptions.
3. Chat panel gap during fast-path transition — old session tab was
removed synchronously but new tab was deferred to a useEffect,
leaving a brief layout gap.
* fix(web): remove superfluous args in test helper
Address CodeQL finding — createSessionSlice only takes `set`, not
`get` and `api`.
* fix(web): add addPanel test assertions and doc comment
Address claude-review blocker: assert that fast-path creates the
session panel with correct id/params, and skips creation when it
already exists. Add doc comment noting syncEnvironmentMapping
requires the combined store draft.
* test(web): add PanelPortalManager.reconcile tests
Export PanelPortalManager class for testability and add tests covering
reconcile removal, no-op, and listener notification paths.
* fix(web): recalculate dockview layout after fast-path session switch
The fast path in tryFastSessionSwitch removed ephemeral panels but
never called api.layout() to redistribute column widths, leaving a
gap on the right side of the screen. Both slow-path branches already
make this call.
* test(web): add regression test for fast-path layout call
Verifies that performSessionSwitch calls api.layout() on both the
fast path and slow path, preventing the squished-layout regression.
* test(web): cover saved-layout fast path branch
* fix(web): replace no-explicit-any cast in test
* fix(web): fix test isolation with mockReturnValueOnce
Use mockReturnValueOnce and clearAllMocks for proper test isolation
between fast-path and slow-path test cases.
* test(web): fix mock shape to match LayoutGroupIds type