Guest page: watch a shared agent chat in any browser (carries #28837)
Leo: "also what about the group chats for inviting people to see my sessions?" and "can this be a proper feat inside acpmux/the multiplayer and team situation?"
Carries #28837 (Guest page: watch a shared agent chat in any browser, itself a carry of #26779) onto current feat-cmux-next. #28837's commits are kept as they were, same author, plus one merge of feat-cmux-next. #28837 had gone conflicting with base and its lane has been idle since 2026-10-31 06:28 UTC.
The share op it pairs with (cmux share chat, Share Chat with Guest) already landed as #27959; this is the browser side a guest opens from that link.
Merge resolution (the only lines not from #28837)
acpmux/App.tsx: base droppedtext=fromReceivedActions; the read-only guard from #28837 stays around it (readOnly ? undefined : <ReceivedActions row more />).acpmux/chips/ReplyImage.tsx: base added an early return for template paths;useTranscriptReadOnly()is called before it, so the hook order is the same on every render, and the import list keeps bothisTemplatePathanduseTranscriptReadOnly.acpmux/Localizable.xcstrings: base's text kept byte for byte, with #28837's 18guest.*keys inserted unchanged.
Security
The page is a client only. Access is decided by the room (the daemon's chat-share redeem and guest socket, already on base): the secret comes from the URL fragment, is removed from the address bar at once, is kept in sessionStorage only until redeem, and the guest socket authenticates with the room's cookie. Room frames are validated before they reach the transcript reducer. A read-only transcript never loads the owner's local files (ReplyImage shows a chip) and makes no host calls (guest-no-host-calls.test.tsx).
No Chief code.
Agent session: agent session
🤖 Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Carries #28837 onto feat-cmux-next: a standalone page where a guest of a shared agent chat watches the transcript live in any browser, no install.
- Adds join, live, and ended states, fed by the room's
cmux.share/1socket (snapshot first, seq dedupe, reconnect with backoff, end/kicked); a fed client draws what it is fed until disposed, and room frames are validated before reaching the transcript reducer. - Imposes a read-only transcript boundary: no row or control draws anything that acts on the owner's machine or daemon, and no hook asks the owner's host (
GuestActionsBoundary,readOnly.ts,guestHost.ts);guest-no-host-calls.test.tsxspies on every host route and expects zero calls. - The share secret is read from the URL fragment, removed from the address bar at once, and kept in sessionStorage only until redeem.
- Adds
build-guest-page-web.shandvite.config.guest-page.mjsso the hosted room can serve the bundle at/g/<share_id>. - Merge resolutions stay limited to
App.tsx,ReplyImage.tsx, andLocalizable.xcstrings; the latest merge resolved onlyApp.tsx.ShellRownow draws no Stop or Open without a shell-actions context, so its test provides the owner's actions and exercises the read-only row without them.