Skip to content

fix(desktop): switch to chat when resuming the open session from a full-page tab (#66875) - #66880

Closed
PRATHAMESH75 wants to merge 1 commit into
NousResearch:mainfrom
PRATHAMESH75:fix/desktop-resume-session-from-page
Closed

fix(desktop): switch to chat when resuming the open session from a full-page tab (#66875)#66880
PRATHAMESH75 wants to merge 1 commit into
NousResearch:mainfrom
PRATHAMESH75:fix/desktop-resume-session-from-page

Conversation

@PRATHAMESH75

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes a desktop-app dead click: selecting the most recent session in the sidebar did nothing when a full-page route (Plugins / Artifacts / Messaging / Skills) was on screen. Selecting an older session worked, which is what made the bug so confusing.

Root cause. onResumeSession (in apps/desktop/src/app/contrib/wiring.tsx) calls focusOpenSession(sessionId) and only navigates when it returns false:

onResumeSession: sessionId => {
  if (!focusOpenSession(sessionId)) {
    navigate(sessionRoute(sessionId))
  }
},

The most recent session is almost always the main session, so focusOpenSession returns true — it fronts that session's pane inside the chat layout (revealTreePane('workspace')). But when a full-page route is showing, the chat layout is hidden behind that page, so fronting a pane in it is invisible and the top-level route never leaves /artifacts (etc.). Older sessions are neither the main session nor an open tile, so focusOpenSession returns false and the handler navigates to chat — hence they worked.

Fix. Extract the navigation decision into a pure, tested resumeSessionNavTarget helper. When the session is already open and the current route isn't the chat view, route back to chat via the main session's own route. Targeting the main session (not the clicked id) keeps an already-open tile a tile — focusOpenSession has already fronted it — instead of promoting it to main. Navigating to the main session's own route is a view-only switch: useRouteResume treats it as alreadyActive and does not re-resume, so there is no reload.

Related Issue

Fixes #66875

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • apps/desktop/src/app/routes.ts — new pure resumeSessionNavTarget(sessionId, alreadyOpen, pathname, mainSessionId) helper deciding where a sidebar session click should route (or null for "stay put").
  • apps/desktop/src/app/contrib/wiring.tsxonResumeSession now uses the helper, so an already-open session clicked from a full-page route routes back to chat.
  • apps/desktop/src/app/routes.resume-nav.test.ts — regression tests for the helper (not-open → own route; open on chat → no-op; open main from a page → back to chat; open tile from a page → main, not the tile; no main → fall back to clicked id).

How to Test

Automated (desktop workspace):

cd apps/desktop
npx vitest run src/app/routes.resume-nav.test.ts   # 5 passed
npx eslint src/app/routes.ts src/app/contrib/wiring.tsx src/app/routes.resume-nav.test.ts   # clean
npx tsc --noEmit -p tsconfig.json   # 0 errors

Manual reproduction (from the issue):

  1. Open the Chat tab with an active session.
  2. Click Plugins (or Artifacts / Messaging / Skills) in the left sidebar.
  3. Click the topmost (most recent) session in the sessions list.
  4. Before: nothing happens — the main screen stays on Plugins/Artifacts. After: the app switches back to Chat with that session.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass — N/A, desktop-only TypeScript change; verified with vitest / tsc / eslint (see How to Test)
  • I've added tests for my changes
  • I've tested on my platform: macOS (Apple Silicon)

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) — or N/A (pure routing logic, no platform-specific code)
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

@alt-glitch alt-glitch added type/bug Something isn't working comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 18, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused regression fix. The premise is confirmed on current main: apps/desktop/src/app/contrib/wiring.tsx:753-756 navigates only when focusOpenSession is false, while apps/desktop/src/store/session-states.ts:440-444 returns true for the loaded main session. That leaves a non-chat route visible after the click.

The proposed decision helper preserves the existing focus operation and restores a chat route only for an already-open session outside chat. Routing through the main session avoids promoting an open tile; apps/desktop/src/app/session/hooks/use-route-resume.ts:118-150 confirms an already-active route does not trigger another resume. The focused helper tests in c39e7273c1e4d3743004a17831cf2a8cfe383828 cover the relevant main, tile, and no-main decisions, and the desktop CI job passed.

Automated hermes-sweeper review.

@teknium1 teknium1 added the sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform label Jul 19, 2026
@teknium1 teknium1 added the area/sessions Session lifecycle, resume, persistence, history label Jul 19, 2026
@apoapostolov

Copy link
Copy Markdown

Win11 Desktop still hits this from Capabilities (/skills) on current main — same onResumeSession / focusOpenSession short-circuit with the full-page route covering the chat layout. Confirmed + notes on #66875. Would love a merge/retest when this is ready.

@PRATHAMESH75

Copy link
Copy Markdown
Contributor Author

@apoapostolov thanks for the Win11 confirmation on Capabilities (/skills) — that path is already covered by this PR.

/skills resolves to a non-chat AppView (appViewForPath('/skills') === 'skills'), so when you click an already-open session from Capabilities, resumeSessionNavTarget takes the same "route back to chat" branch it uses for Plugins/Artifacts/Messaging. The regression test loops '/skills' explicitly in the "route back to chat when the open MAIN session is clicked from a full page" case, so your repro is guarded, not just Artifacts.

To retest on Win11 once you're on this branch:

  1. cd apps/desktop && npx vitest run src/app/routes.resume-nav.test.ts — should show 5 passed (the /skills case is in there).
  2. Manual: open Chat with an active session → click Capabilities in the sidebar → click the topmost (most recent) session. Before: nothing happens, the Capabilities page stays up. After: the app switches back to Chat with that session.
  3. Also worth a quick pass clicking an older (non-main) session from Capabilities — it should land you in Chat without promoting that session to the main pane.

Appreciate the extra platform coverage — let me know if anything still sticks on Windows.

…ll-page tab

Clicking the most recent session in the sidebar did nothing when a
full-page route (Plugins/Artifacts/Messaging/Skills) was showing. That
session is usually the main session, so onResumeSession's focusOpenSession
call returned true (it fronts the session's pane inside the chat layout)
and the handler then skipped navigation — but the chat layout is hidden
behind the full page, so nothing visibly changed. Older sessions worked
because they are neither the main session nor an open tile, so
focusOpenSession returned false and the handler navigated to chat.

Extract the navigation decision into a pure resumeSessionNavTarget helper:
when the session is already open but the current route is not the chat
view, route back to chat via the MAIN session's own route. That keeps an
open tile a tile (focusOpenSession already fronted it) instead of
promoting it to main, and useRouteResume treats the main session's own
route as alreadyActive so no re-resume is triggered.

@erict16 erict16 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (Win11 Desktop / Capabilities path)

Reproduced the same dead-click on current main from Capabilities (/skills):

  1. Open Chat with the active (main) session highlighted
  2. Open Capabilities (page rail → full-page /skills)
  3. Click that same / top session in the sidebar
  4. Before: main pane stays on Capabilities (focusOpenSession returns true → no navigate)
  5. After this PR: should route back via sessionRoute(main) so the chat layout is visible again

Code review

  • Root cause match is correct: wiring.tsx onResumeSession only navigates when !focusOpenSession(...), while the main session is almost always already open, so full-page routes (skills / artifacts / messaging / extensions) hide the fronted pane.
  • Extracting resumeSessionNavTarget is the right shape — pure helper, easy to test, keeps tile-vs-main semantics (route to MAIN when an open tile was fronted, don't promote the tile).
  • useRouteResume treating the main session's own route as alreadyActive means this is a view-only switch (no double-resume) — good.
  • Tests cover main-from-full-page (including /skills), tile preservation, chat no-op, and no-main fallback.

Nit (non-blocking)

/cron is an overlay view (OVERLAY_VIEWS), not a full page like Capabilities. Routing back to chat from overlays is still reasonable UX when the user explicitly clicks a session; just noting the helper uses appViewForPath !== 'chat' for both full pages and overlays. No change required unless maintainers want overlay clicks to only dismiss the overlay without a route change.

LGTM from a Win11 daily-driver perspective — Capabilities is a frequent path. Would love this merged; happy to retest after land.

(Could not click GitHub “Approve” — no write access on the upstream repo; this is a substantive review comment instead.)

@erict16

erict16 commented Jul 23, 2026

Copy link
Copy Markdown

Simpler take (Win11 + Capabilities)

What breaks: On Capabilities, clicking the latest session does nothing. You stay on Capabilities. Older sessions still work.

Why: That session is already open behind the page. The app tries to “show” it without leaving Capabilities, so the click looks dead.

What this PR does: If the session is already open and you’re not on Chat, it switches back to Chat so you can actually see it. Tests cover Capabilities (/skills). Tile behavior stays correct.

Verdict: Looks good — please merge. Happy to retest on Win11 after it lands.

(Earlier review comment was more technical; this is the plain-language version.)

@PRATHAMESH75

Copy link
Copy Markdown
Contributor Author

Closing this as superseded by upstream. main now fixes the same #66875 dead-click in ecf8ef970 ("fix(desktop): clicking the active session from a full page returns to the chat", merged via #71901).

The upstream fix routes the resume through a dedicated helper, focusedSessionNeedsRoute(focusOpenSession(sessionId), workspaceIsPage) (apps/desktop/src/store/session-states.ts), wired into onResumeSession in contrib/wiring.tsx:

export function focusedSessionNeedsRoute(focused: 'main' | 'tile' | null, workspaceIsPage: boolean): boolean {
  return !focused || (focused === 'main' && workspaceIsPage)
}

That covers everything this PR did:

So the branch is now redundant and conflicts with main. Closing rather than force-rebasing dead code. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/sessions Session lifecycle, resume, persistence, history comp/desktop Electron desktop app (apps/desktop/*) P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Latest session does not switch after navigating to Plugins/Artifacts tab and back

5 participants