feat(web): select a dashboard session from a #session=<id> link - #507
Merged
Ark0N merged 1 commit intoOct 1, 2026
Merged
Conversation
A page that keeps one Codeman window open, such as a task board, could only show a session by sending that window to /session/<id>, which loads the whole app again for every click. The dashboard now reads a #session=<id> fragment when it loads and on hashchange, selects that session, and removes the fragment with history.replaceState so the next identical link is still a change. Re-pointing a window that already shows the dashboard changes only the fragment, so the page stays loaded and the switch is a tab change. A link can name a session the dashboard does not list yet, because the page that created it may link before session:created arrives. The id waits until that event names it, and picking another tab yourself retires it. Following a link is an app selection (`auto: true`). The page that set the fragment may be a script, so it must not spend the session's idle alert. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
irisitymichaelgrundberg
marked this pull request as ready for review
September 29, 2026 16:09
Ark0N
pushed a commit
that referenced
this pull request
Oct 1, 2026
…eb tab (#507 review) - A #session=<id> link whose session never appears (closed, a typo, or another user's session in multi-user mode) is dropped after URL_SESSION_WAIT_MS (30 s) with a "Session not found" toast instead of waiting forever. One stored timer per link, cleared whenever the link is followed, replaced by a newer link, or retired. - goHome() and opening a web tab now retire a waiting link, so a session that turns up later no longer takes the screen. App-made web tab opens (frame self-recovery, the fallback after the active web tab closes) pass auto: true and keep it, as selectSession() does. - zh-CN translation for the new toast. - selectSession's auto: true comment now lists the #session=<id> link. - docs: the 30 s bound, a win.location.replace() tip that avoids piling up history entries, and the fragment declared a stable SemVer surface in versioning-policy.md. - Tests: timeout drops and toasts, an early arrival is still selected, the wait does not restart, goHome and a web tab retire it, an auto web tab open keeps it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Owner
|
Merged, thanks @irisitymichaelgrundberg! This ships in 1.33.3. The design reads well: one fragment, I folded the review items into one commit at merge time (846c62f), so here's what changed on top of yours:
|
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.
An outside page that keeps one Codeman window open can now switch that window between sessions without reloading it. It links to the dashboard as
/#session=<id>, and the dashboard selects that tab.This adds a small new integration surface, so I'm opening it as a draft. I'm happy to move the design to an issue first if you'd prefer that.
Why
I run a task board that opens each agent's session in one reused browser window. The only per-session URL today is the solo page at
/session/<id>, and every click on it loads the whole app again: the HTML shell, the scripts, the event stream and the terminal buffer. Switching between a few sessions waiting on me took a few seconds each time. The dashboard already switches tabs quickly, and it draws a cached terminal for a session it has shown before, so the only thing missing was a way to tell an open dashboard which tab to show.What it does
sessionIdFromFragment()inconstants.jsreadssession=<id>from the fragment. The dashboard reads it at construction and on everyhashchange, then removes the fragment withhistory.replaceState. A later link to the same session is therefore still a change the browser reports, even after the user has clicked away to another tab.selectSession.session:createdreaches this window. The id waits in_urlSessionIduntil_onSessionCreatednames it.handleInitalso checks it before restoring the last active tab, so a fresh page load lands on the linked session.auto, the waiting id is dropped. Without that, a session that turned up late would take the tab from you.{ auto: true }. The page that set the fragment may be a script, and the window may not be in front, so following a link is not a human looking at the session. The alert clears as it does today, on a click or on input.docs/architecture-invariants.mdand the source guard intest/session-select-ack-gate.test.tslist this call among the app-made selections.docs/extending-codeman.mdhas a short section on linking to a session from an outside page, under Seam 3.Testing
npm testpasses, as do lint, format,check:frontend-syntaxandcheck:public-assets.test/url-session-fragment.test.tscovers the parser, and it loadsCodemanAppthroughvm, like the ack-gate test, to cover:session:created;autoselection keeping it;CODEMAN_INSTANCE=beta), with the board opening sessions in one named window. Switching between three shell sessions took about 90–250 ms with the fragment link and about 500–700 ms with/session/<id>, and a marker set on the window survived every switch. Sessions with long transcripts should gain more.Known limit
A link to a session that another dashboard has popped out goes through the existing detached path. That path posts a
focus-requeston the window channel, and the pop-out callswindow.focus(). Chromium browsers bring the pop-out forward, and I checked that by hand. Firefox may refuse a focus request without a user gesture in that window, in which case the linking window keeps showing its current tab. I haven't tested Firefox.No changeset, following the repository's convention for contributors.
🤖 Generated with Claude Code