Skip to content

fix(activity panel): handle back navigation#1487

Open
tellaho wants to merge 3 commits into
mainfrom
tho/activity-back-history
Open

fix(activity panel): handle back navigation#1487
tellaho wants to merge 3 commits into
mainfrom
tho/activity-back-history

Conversation

@tellaho

@tellaho tellaho commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator
Screen.Recording.2026-07-02.at.8.27.43.PM.mov

Category: fix
User Impact: Users returning from an agent Activity panel land back in the thread or profile pane they were inspecting, while Activity opened without a prior pane shows only a close affordance.
Problem: In a deep thread, opening an agent's Activity panel and pressing the header back arrow could jump to the agent profile because the panel had no explicit memory of the pane it replaced. Activity also showed a back arrow when opened from the composer or a restored direct URL, even though there was no meaningful pane to return to.
Solution: Capture a one-shot return target when Activity opens over another right-side pane, then consume that target on Activity back instead of popping app/browser history or hard-coding profile navigation. The shared breadcrumb store now exposes reactive target presence so the Activity back arrow only renders when there is a real thread/profile return target; no-target states use the normal close affordance.

File changes

desktop/src/features/channels/ui/AgentSessionThreadPanel.tsx
Makes the Activity header back callback optional so the panel can omit the back arrow when there is no captured return target.

desktop/src/features/channels/ui/ChannelPane.tsx
Routes Activity back through the channel-level return handler, and passes it only when a real return target exists.

desktop/src/features/channels/ui/ChannelPane.types.ts
Updates the channel pane contract for optional Activity back handling.

desktop/src/features/channels/ui/ChannelScreen.tsx
Connects Activity open/back state to the current effective thread and profile pane, and uses return-target presence to control back-arrow visibility.

desktop/src/features/channels/ui/agentSessionSelection.test.mjs
Covers return-target resolution for thread, profile, thread-over-profile priority, and no-pane Activity opens.

desktop/src/features/channels/ui/agentSessionSelection.ts
Defines the typed Activity return target and resolves which existing pane Activity is replacing.

desktop/src/features/channels/ui/useChannelAgentSessions.ts
Captures Activity's return target on closed-to-open transitions, consumes it on back, clears it on close/thread jumps/stale Activity params/channel switches, and exposes whether a target exists.

desktop/src/shared/hooks/usePanelReturnTarget.ts
Adds a React hook wrapper around the return-target store with reset-key cleanup and a reactive hasTarget snapshot.

desktop/src/shared/lib/panelReturnTarget.test.mjs
Verifies one-shot consume, overwrite, clear/reset, null capture, peek, and subscription semantics for the reusable breadcrumb store.

desktop/src/shared/lib/panelReturnTarget.ts
Adds the reusable one-shot breadcrumb store, including subscriptions for conditional affordances without coupling callers to React state.

desktop/tests/e2e/channels.spec.ts
Adds coverage that composer/no-pane Activity opens do not show the back arrow.

desktop/tests/e2e/profile.spec.ts
Adds coverage that restored direct Activity URLs hide the back arrow while profile-to-Activity still shows it.

Reproduction Steps

  1. Open a channel thread, preferably one with enough depth that losing context is obvious.
  2. Open an agent's Activity panel from that thread.
  3. Confirm the Activity back arrow is present, then press it and confirm the original thread pane is restored.
  4. Open an agent profile, then open Activity from that profile.
  5. Confirm the Activity back arrow is present, then press it and confirm the profile pane is restored.
  6. Open Activity without an existing right-side pane and confirm there is no back arrow, only the close X.
  7. Restore or reload a URL with agentSession and no captured return target, then confirm there is no back arrow and the close X exits Activity.

Validation

  • biome check .
  • file-sizes + px-text checks
  • tsc
  • unit tests: 1560/1560 passing
  • targeted Playwright coverage for thread → Activity → back, profile → Activity → back, composer/no-pane Activity with no arrow, and restored direct Activity URL with no arrow

npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w and others added 2 commits July 2, 2026 19:05
The Activity panel back arrow was hardwired to open the agent profile,
so opening the activity log from a thread and pressing back dumped the
user on the profile instead of returning to the thread.

Capture an explicit return target when the Activity panel opens (thread
or profile, matching right-pane render priority) and consume it exactly
once on back. Opened from the composer with no pane, or restored from a
direct agentSession URL, back simply closes the panel — never a blind
app/browser history pop. Switching agents while the panel is open keeps
the original breadcrumb; plain close, thread-jump, and stale-param
cleanup all clear it, and channel switches drop it via the reset key.

The breadcrumb lives in a reusable pure store
(shared/lib/panelReturnTarget) with a render-silent React binding
(shared/hooks/usePanelReturnTarget) so future mutually-exclusive pane
transitions can adopt the same pattern.

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Opened from the composer with no prior pane, or restored from a direct
agentSession URL, the Activity panel showed a back arrow that could only
close the panel — a misleading affordance next to the real close button.

Make the return-target store subscribable and surface a reactive
hasTarget from usePanelReturnTarget, then pass onBack to the Activity
panel only when a captured pane exists. AuxiliaryPanelHeaderGroup
already hides the arrow when onBack is undefined, so composer/no-pane
opens and deep-linked/restored URLs now show close as the only
affordance while thread/profile returns keep their arrow.

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
@tellaho tellaho marked this pull request as ready for review July 3, 2026 04:50
@tellaho tellaho changed the title fix activity panel back navigation fix(activity panel): handle back navigation Jul 3, 2026
@tellaho tellaho enabled auto-merge (squash) July 3, 2026 07:11
Keep both intents in useChannelAgentSessions.ts openAgentSession: main's
channel-context signature (channelId param + setOpenAgentSessionChannelId
reset) and the PR's one-shot breadcrumb capture guarded by
isAgentSessionOpen. Merged deps array already held the union.

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant