Files
kandev/apps/web/lib/ws
José Almeida b2dcd29818 fix(web): tab session bugs — primary star drift + tab close re-creation (#800)
* fix(web): preserve primarySessionId across kanban.update broadcasts

The kanban.update WS handler rebuilt kanban.tasks without
primarySessionId / primarySessionState, wiping values set by
task.updated. After any board refresh the primary star vanished and
selectTaskWithLayout fell into the slower async fallback path. Move
task building inside setState so existing values are preserved in both
single and multi snapshots.

* fix(web): prevent deleted session panel from being re-created

handleDelete called removeTaskSession before containerApi.removePanel,
which let useAutoSessionTab re-run with effectiveSessionId still
pointing at the deleted session and re-create its panel. The
setupChatPanelSafetyNet had a matching gap — it re-added a panel for
activeSessionId without checking the session still existed.

Switch the active session (or clear it) before removeTaskSession so
effectiveSessionId updates first. Add guards to useAutoSessionTab and
the safety net so neither creates a panel for a session that is no
longer in the store.

* test(web): add session tab management regression suite

Cover the three bugs fixed in this branch end-to-end: deleting a
non-active session keeps it gone, deleting the active session switches
focus to the remainder, deleting then immediately switching tasks does
not resurrect the tab, and the primary star survives both a
kanban.update broadcast (triggered via apiClient.moveTask) and a
task-switch round trip.

* fix(web): hand off deletion to newest remaining session, document multi-snapshot fallback

- session-tab.tsx: sort remaining sessions by started_at DESC and
  pick the newest, instead of relying on the unspecified store ordering.
- kanban.ts: comment the multi-snapshot primarySessionId fallback so
  the double lookup does not look like redundancy.

Both per Claude review feedback on #800.

* fix(web): preserve explicit-null primary, abort delete on WS failure

- kanban.ts: switch the multi-snapshot fallback from `??` to an
  explicit `=== undefined` check. An explicitly-cleared null primary
  must NOT be replaced by a stale snapshot value, only an absent key.
- session-tab.tsx: wsAction now returns a boolean; handleDelete bails
  out before mutating the store / dockview when the backend
  session.delete request fails. Prevents client/server desync from a
  transient WS failure.
- kanban.test.ts: add regression covering the null-vs-undefined merge.

Per CodeRabbit and Greptile review on #800.

* style(web): drop redundant .slice() in session deletion sort chain

filter() already returns a fresh array, so the subsequent sort() does
not mutate shared store state. Per Greptile review on #800.
2026-05-03 17:32:29 +01:00
..
2026-02-19 22:18:01 +00:00