* feat(backend): key user shells by TaskEnvironmentID
Sessions in the same task share a TaskEnvironment. Re-key the user shell
runner so terminals are scoped per env, not per session — switching between
sessions of the same task now sees the same shell list.
- Add TaskEnvironmentID to AgentExecution / LaunchRequest / ExecutorCreateRequest
/ executor.LaunchAgentRequest, propagated through ToAgentExecution and the
orchestrator launch path.
- Add Manager.ResolveScopeKey(sessionID) — returns env when execution carries
it, falls back to sessionID for legacy paths.
- Rename runner param sessionID -> scopeID in interactive_shells.go; map keys
are now scopeID:terminalID.
- Shell handlers + WS terminal handler resolve sid -> scopeID via
ResolveScopeKey before calling the runner.
* feat(web): key dockview layout + portals to TaskEnvironmentID
Switching between sessions of the same task no longer rebuilds the dockview
layout — terminals and panels persist because layouts are env-scoped, not
session-scoped. The bottom terminal also reuses a stable sessionId across
same-env switches so it doesn't reconnect to a different shell.
- Rename layout persistence: setSessionLayout/getSessionLayout/*SessionMaximizeState
-> setEnvLayout/getEnvLayout/*EnvMaximizeState (kandev.dockview.env-layout. prefix).
- Rename dockview-session-switch.ts -> dockview-env-switch.ts; performSessionSwitch
-> performEnvSwitch with oldEnvId/newEnvId/activeSessionId.
- dockview-store.ts: currentLayoutSessionId -> currentLayoutEnvId; switchSessionLayout
-> switchEnvLayout(oldEnvId, newEnvId, activeSessionId). Same-env switches no-op.
Drop _skipLayoutSwitchForSession + consumeSkipFlag — env-keyed action handles it
structurally.
- panel-portal-manager: PortalEntry.envId; releaseBySession -> releaseByEnv.
ENV_SCOPED_COMPONENTS in dockview-desktop-layout (renamed from SESSION_SCOPED).
- useEnvSwitchCleanup replaces useSessionSwitchCleanup; tracks env changes only.
- All performLayoutSwitch callers (sidebar, dropdown, header, dialog) resolve
sid -> envId via environmentIdBySessionId before switching.
- bottom-terminal-panel: drop sessionId prop, use useEnvironmentSessionId().
- cleanupTaskStorage now takes envIds[] alongside sessionIds[] for env-scoped
layout/maximize cleanup.
* test: add coverage for env-keyed terminals + layout
Playwright e2e (terminal-env-keyed.spec.ts) — switching between sessions of
the same task keeps terminal scrollback intact and asserts both sessions
share one task_environment_id. Update the comment in
sessionless-task-switch.spec.ts to reference performEnvSwitch.
* fix: address env layout PR feedback
* test: fix flaky handshake auth check
* fix: address env scope review findings