feat(ui): unify Chat + Session into one Chat tab with a session-mode toggle (#1112)#1340
Merged
Merged
Conversation
…toggle (#1112) Collapse the redundant Chat + Session tabs on Agent Detail into a single "Chat" tab carrying a "Session mode" toggle (default ON), keeping the legacy stateless surface as a first-class user-selectable mode rather than dead code. - AgentDetail.vue: single `{ id: 'chat' }` tab (drop the separate Session entry). New `chatMode` ref ('session'|'legacy', default 'session') persisted per-user in localStorage['trinity.chatMode']. `sessionAvailable` = feature flag on AND runtime has --resume (not Codex); `effectiveChatMode` forces legacy when the Session surface is unavailable and hides the toggle. The toggle swaps SessionPanel ↔ ChatPanel in-place (v-if). isFullscreenTab keys on the single 'chat' id; `?tab=session` aliases to 'chat' (hinting session mode). - Execution-resume: ExecutionDetail "continue as chat" (?tab=chat&resumeSessionId) forces legacy ChatPanel (which owns resume) via a transient, non-persisted routeForcedMode — without rewriting the user's saved preference. - No backend change (session_tab_enabled already exists). MobileAdmin unaffected: its openChat is a self-contained mobile chat overlay, not an AgentDetail deep-link, so there is nothing to repoint. - docs: architecture Session Tab block + requirements §5.8 note. Related to #1112 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
vybe
approved these changes
Jun 24, 2026
vybe
left a comment
Contributor
There was a problem hiding this comment.
Validated via /validate-pr: base=dev, conventional commit, focused UI feature (AgentDetail.vue) with architecture.md + requirements.md both updated. Security-clean, no enterprise-doc leak in arch hunk, build green. Note: e2e not triggered (no ui label) — relying on build + thorough acceptance criteria. Approving.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Collapses the redundant Chat + Session tabs on Agent Detail into a single "Chat" tab carrying a "Session mode" toggle (default ON). The legacy stateless surface stays a first-class, user-selectable mode rather than dead code.
theme-ui-ux. No backend change.Behavior
SessionPanel.vue(--resumecontinuity: memory, tool-result + reasoning state across turns). OFF → legacy statelessChatPanel.vue. Swaps in-place (v-ifoneffectiveChatMode), no page nav.localStorage['trinity.chatMode'], defaultsession.session_tab_enabledis off or the runtime lacks--resume(Codex, Codex harness MVP — pluggable agentic execution engine alongside Claude Code #1187), the toggle is hidden and the tab renders legacyChatPanelonly — never zero chat surfaces.isFullscreenTabnow keys on the single'chat'id (both modes).Routing
?tab=sessionaliases to thechattab (TAB_ALIASES) and hints session mode;?tab=chatresolves as before. Both land on the unified tab.?tab=chat&resumeSessionId=…) forces legacyChatPanel(which ownsresumeSessionId) for that landing via a transient, non-persistedrouteForcedMode— so an execution-resume doesn't rewrite the user's saved preference. The toggle reflects the forced mode and clicking it clears the override.Acceptance criteria
?tab=chatand?tab=sessionboth resolve to the unified Chat tabisFullscreenTab(single id, both modes)Notes
openChatis a self-contained mobile chat overlay (API-driven,/chat/sessions+/task), not an AgentDetail tab deep-link — so the tab unification can't land it on a dead surface. (The issue listed it as a deep-link; the code shows otherwise.)Validation
SFC compiles (
vue/compiler-sfcparse +compileScript); design-token check passes. Fullvite buildis blocked locally only by an unrelated missingmermaiddep inAgentWorkspace.vue(declared inpackage.json, absent from this checkout'snode_modules) — CI builds with full deps. UI e2e (uilabel) exercises the live surface.Related to #1112
🤖 Generated with Claude Code