Repository navigation
Open chat visuals full screen on iOS and Android (Remote revision 35) - #514
Conversation
Phones keep the inline snapshot; with the new chat-visual-viewer-v1 token,
tapping it opens the visual in a locked-down web view. The Mac serves
GET /chats/{chatId}/visuals/{visualId}/document: one self-contained HTML
document built from a new viewer bundle (render_ui via AidenUiBlock,
render_artifact as the sandboxed guest with only the libraries it uses).
Follow-ups and links go to the phone, which confirms; prompts only fill
the composer.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KPgvZHFWvJ95VRjuu4p9LL
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPgvZHFWvJ95VRjuu4p9LL
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPgvZHFWvJ95VRjuu4p9LL
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPgvZHFWvJ95VRjuu4p9LL
Main took revision 34 for speech-request-gzip-v1. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPgvZHFWvJ95VRjuu4p9LL
There was a problem hiding this comment.
Important
Tall visuals cannot be scrolled, Android treats revoked access as an offline cache hit, and iOS cannot reopen cached visuals after an offline relaunch.
Reviewed changes
Reviewed the complete phone visual viewer implementation and its Remote revision 35 contract.
- Remote document endpoint: Authenticated visual lookup, bounded self-contained HTML, appearance queries, feature negotiation, CSP, ETags, and gzip.
- Shared viewer: A new bundled React page reuses native visual components, hosts sandboxed HTML, forwards follow-ups and links, and shares library inlining with exports.
- Native clients: iOS and Android full-screen WebViews add confirmation flows, snapshot fallback, appearance selection, and bounded offline document caches.
- Integration and coverage: Build/CI registration, Xcode shipping inventory, protocol/OpenAPI updates, documentation, and focused server, browser, and mobile tests.
Validation: the viewer build, 221 focused TypeScript tests, both new Chromium tests, TypeScript checking, iOS release-policy checks, and Swift syntax parsing passed. Local Android execution was blocked by unavailable offline runtime dependencies; native XCTest requires macOS. Hosted Android, iOS, and required CI checks are green on the reviewed head.
gpt-6.1-sol | 𝕏
Hermes Review BotConfidence: 5 Engine: SummaryRemote contract revision 35 introduces interactive full-screen rendering for inline visuals ( Confidence Score: 5/5Full end-to-end trace verified across Mac document generation, desktop router gating, WebKit/WebView sandbox configurations, native bridge message parsing/throttling, and LRU cache eviction and generation fencing on both iOS and Android. 📁 Important Files Changed
FindingsNo findings. Sequence DiagramsequenceDiagram
autonumber
participant App as Mobile App (iOS / Android)
participant Mac as Aiden Host (Mac)
participant WebView as Sandboxed WebView
App->>Mac: GET /chats/{chatId}/visuals/{visualId}/document?scheme&theme
Mac-->>App: 200 text/html (Self-contained viewer document + CSP)
App->>App: Cache document in AidenVisualDocumentCache
App->>WebView: Load HTML string (opaque origin, no network/storage)
WebView->>WebView: Render visual (AidenUiBlock / sandboxed srcdoc iframe)
WebView->>App: Post message: ready
App->>App: Clear loading indicator and reveal content
opt Suggested follow-up prompt
WebView->>App: Post message: prompt(text)
App->>App: Display native confirmation dialog/banner
App->>App: Append confirmed prompt to composer draft
end
opt External link action
WebView->>App: Post message: openUrl(https URL)
App->>App: Display native confirmation prompt
App->>App: Open URL in external browser
end
[]
|
…able offline on iOS - The viewer scrolls inside its own full-viewport surface, since the desktop stylesheet pins html/body/#root with overflow hidden. - Android: the visual document cache belongs to the coordinator and is purged whenever a pairing is removed; a revoked credential removes the pairing; only an unreachable Mac falls back to the saved copy, and a purge during a load keeps the document from being written back. - iOS: before any live /server answer, a pairing with saved documents keeps its visuals openable after a cold start without the Mac. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPgvZHFWvJ95VRjuu4p9LL
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Reviewed f516bf369 against the prior reviewed head 29fb57cca, focusing on the three fixes and their behavioral coverage.
- Enabled full-content scrolling: Added a viewer-owned scroll surface and a phone-sized browser test that reaches and activates bottom actions in both native and HTML visuals.
- Enforced Android cache cleanup: Moved cache ownership to the coordinator, rejected cached fallback after explicit refusals, handled credential revocation, and fenced late cache writes after removal.
- Restored iOS offline access: Allowed saved visual documents to remain openable after a cold offline launch while preserving authoritative live feature gating.
Validation passed: viewer production build, all three Chromium viewer tests, six document-builder tests, the four focused Android viewer/client/cache/removal suites, TypeScript checking, and changed Swift syntax parsing. Native iOS XCTest was not run locally because this runner is Linux; hosted iOS, Android, and other CI jobs were still pending or running at the last check.
gpt-6.1-sol | 𝕏
very-hermes-bot
left a comment
There was a problem hiding this comment.
Inline review — 1 finding(s) anchored to the diff. See the pinned summary comment for the overview.
The URL is opened with a lowercase scheme, since browser intent filters match the scheme case-sensitively. iOS already compares case-insensitively. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPgvZHFWvJ95VRjuu4p9LL
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Reviewed db36b8986 against the prior reviewed head f516bf369, tracing Android visual links from bridge parsing through confirmation and browser dispatch.
- Accepted mixed-case HTTPS schemes: Made scheme validation case-insensitive and normalized the accepted scheme to lowercase for Android browser intents, while preserving the existing host, credential, and input restrictions.
- Extended behavioral coverage: Added an assertion that
HTTPS://Example.com/Abecomeshttps://Example.com/Awithout changing host or path casing.
Validation: all six AidenVisualViewerModelTest tests passed locally. Hosted CI is not yet green: the Android job failed during emulator SDK installation with Error on ZipFile unknown archive, before product tests; other jobs remain running or queued.
gpt-6.1-sol | 𝕏
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPgvZHFWvJ95VRjuu4p9LL
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Reviewed merge 0a6527970 against the previously reviewed head db36b8986, focusing on integration with the newly merged main changes.
- Merged shared visual components: Checked compatibility with workspace-artifact actions in
AidenUiBlockand the AUM compiler; the phone viewer retains its existing confirmation bridge and gains no command-execution authority. - Preserved viewer integration: Verified that the clean merge retains the viewer build prerequisite, both branches' test registrations, Remote revision 35, and the previously reviewed mobile fixes.
Validation passed: viewer production build, 201 focused behavioral tests, all three Chromium viewer tests, TypeScript checking, and 63 CI-policy tests. Chromium initially could not launch because the runner lacked its executable; after installation, all three tests passed with retries disabled. Native sources are unchanged by this merge and were not retested locally. Hosted CI on this exact head is still queued or running, including the native mobile jobs, so merge readiness is not yet established.
gpt-6.1-sol | 𝕏

Requested by sbt · project thread
Before: on iOS and Android, charts and widgets in a reply are a still, light-theme picture from the Mac. Tapping one only opens the image viewer.
After: when the paired Mac runs this build, tapping a visual opens it full screen in a locked-down web view. Tooltips, tabs, sliders and Plotly interactions work, in the phone's own theme, light or dark.
It works for both kinds of visual:
render_uiis drawn by the sameAidenUiBlockthe desktop uses.render_artifactHTML runs in the same opaque-origin sandbox and CSP as on desktop, with only the libraries it calls inlined.How
Mac: new
GET /chats/{chatId}/visuals/{visualId}/document?scheme&themebehind feature tokenchat-visual-viewer-v1.speech-request-gzip-v1. It is provisional and gets re-claimed at merge.main/services/visual-viewer-document.tsfrom a new viewer bundle.vite.visual-viewer.config.tsbuilds that bundle intobuild/renderer/visual-viewer/as part ofnpm run build.no-store, with a strong ETag and gzip.Bridge: the page talks to the phone through one channel only,
aidenVisualon iOS andAidenVisualBridgeon Android. It carries three message types:ready,promptandopenUrl.AidenUiBlockgainsonFollowUp, so the viewer hands prompts to the phone instead of drawing its own Send chip.ExternalLinkOpenerProvider.httpsin any letter case and opens the link with a lowercase scheme.Export refactor: library inlining moved into
inlineGenerativeUiHostLibraries, which export and the CLI also use. It now replaces with a function, so$&in library source stays literal.iOS and Android: each app has a full-screen viewer:
The image viewer is still reachable from the viewer.
/serveranswer decides.CI: the viewer's Vite build is registered as a
generative-ui-chromiumprerequisite, and the new iOS sources are on the shipping allowlist.Docs: the plan is in
docs/plans/phone-visual-viewer-plan.md. The API notes and OpenAPI are updated.Testing
Builder units, chat-service lookups, router register-and-invoke (auth, query validation, 304, gzip, feature gating) and OpenAPI path coverage.
A Chromium spec loads the real built document with the network blocked. It checks:
iOS and Android unit tests cover:
Both pass in CI (iOS simulator XCTest, Android verify and Compose UI tests).
Flaky test record
scripts/verify-macos-package.test.mjs, test "package verifier requires a bounded packed subagent inference worker", failed once on macOS in the renderer-other lane.subagent-inference-worker.jsfailed to parse at line 1 (SyntaxError: Invalid or unexpected token).sdkmanagerfailed to unzip the emulator download (Error on ZipFile unknown archive).AidenMessageVisualSnapshotLayoutTests.testVisualSnapshotKeepsItsHeightAlongsideAnImageDeck()(from main's 7e60757) failed once after 8.3 s on the merge commit 0a65279.(ipc/mig) server diedlater in the same run.🤖 Generated with Claude Code
https://claude.ai/code/session_01KPgvZHFWvJ95VRjuu4p9LL