Separate clide windows are isolated (own process, per-root IPC socket,
per-repo deterministic session id), so parallel repos in separate windows
were already fine. But switching the workspace in place (Open Project /
Open Folder) only emitted ProjectOpened — nothing rebound the Claude
session, so the primary pane kept the PREVIOUS repo's conversation.
Two compounding causes, fixed in layers:
- ClaudeSessionOrchestrator.spawn() was idempotent on the literal key
'primary' without checking cwd, so it handed the old repo's session to
the new repo. It now reuses a cached session only when its cwd matches
the spec; a mismatch tears the stale one down and spawns fresh.
- The primary ClaudePane is built once behind a GlobalKey and spawns once,
so it never re-resolved. It now listens for ProjectOpened and rebinds:
close its orchestrator entry, drop the cached session id + repo root, and
respawn against the now-active repo. Secondaries don't self-rebind.
- ClaudeSessionHost drops the old repo's secondary/fork tabs on a switch,
so a switched workspace starts like a fresh launch (lone primary).
- The extension closes any remaining sessions whose cwd != the new root,
catching team/non-pane sessions no pane owns.
Tested at the orchestrator: cwd-aware idempotency (reuse on cwd match,
teardown + respawn on mismatch). Pane/host widget coverage is intentionally
deferred — claude_pane.dart has no widget-test harness yet and pulling it
into coverage piecemeal would drop the gate; tracked separately.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Renders broker traffic as a chat timeline and makes the user a first-class
participant. The broker grows a Stream<TeamMessage> and a recipient field,
auto-registers a virtual `user` member, and gains sendAsUser. A Flutter-free
TeamChatModel (owned by the orchestrator) accumulates the feed and exposes
postAsUser with @-routing (a new at_commands helper mirroring slash) and an
optional interrupt that cancels the target's turn before delivery. One model
backs two surfaces: a compact cockpit widget that pops out into a full
workspace chat pane. CLI parity via clide.team-chat.open / .post.
T-180.
Co-Authored-By: Claude <noreply@anthropic.com>
Session lifecycle now runs entirely on the stream-json model: argv
selection picks --resume <id> for an existing transcript and
--session-id <uuid> for a fresh one, and the managed-session orchestrator
owns spawn/close. With the transport off tmux, remove the tmux session
lifecycle (reaping, kill-all-for-repo) and the tmux-polling team observer;
kill-all-sessions now closes sessions through the orchestrator. Team
membership is orchestrator-driven since the coordination broker landed.
Amends D-41 (tmux persistence -> --resume). T-167.
Co-Authored-By: Claude <noreply@anthropic.com>