Show "Fork from here" button on the mobile chat#4413
Merged
Conversation
5a459e3 to
56c6823
Compare
Contributor
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## kevin/fork-at-message #4413 +/- ##
==========================================================
- Coverage 47.36% 35.47% -11.90%
==========================================================
Files 253 184 -69
Lines 19797 13822 -5975
Branches 6230 4674 -1556
==========================================================
- Hits 9377 4903 -4474
+ Misses 10401 8904 -1497
+ Partials 19 15 -4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
msfstef
approved these changes
May 26, 2026
Contributor
msfstef
left a comment
There was a problem hiding this comment.
can probably have smaller comments
f8313f9 to
0be3760
Compare
1e0c3f1 to
5e2d693
Compare
5997c95 to
2085be1
Compare
Two pieces:
1. `ChatLogView` (the view the mobile DOM embed mounts under
`view='chat-log'`) now computes the same `forkFromHereByInboxKey`
map that `ChatView` has on the web. Without this the embed's
`EntityTimeline` received no per-row callbacks and `UserMessage`
stayed without the button regardless of any CSS.
2. `UserMessage.module.css` gains a scoped reveal —
`:global(html[data-electric-mobile-dom='true']) .forkButton { opacity: 1 }`
— so the button is visible by default on touch (the web's
`.bubble:hover` rule never fires there). Placing the rule inside
the CSS module (rather than in a sibling stylesheet that targets
the hashed class by substring) means whichever bundler is in play
— Vite for the web/desktop bundles, Metro for the Expo DOM embed —
hashes `.forkButton` consistently with the JSX.
The mobile package itself doesn't change. The embed already mounts
`ChatView` → `EntityTimeline` → `UserMessage`, the fork POST already
routes through `serverFetch()` in the embed's JS context, and
post-fork navigation already routes through `onRequestOpenEntity` →
`openSession(target)`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5e2d693 to
b30d2c9
Compare
Contributor
Electric Agents Mobile BuildAndroid preview build for commit
|
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.
Follow-up to #4410: extends the per-message "Fork from here" affordance to the mobile chat (and any other surface that mounts agents-server-ui via an Expo "use dom" embed).
What changes
Two source files, both in
packages/agents-server-ui:src/components/views/ChatView.tsx—ChatLogView(the view the mobile embed mounts underview='chat-log') now computes the sameforkFromHereByInboxKeymap thatChatViewalready had on the web side. It pullsdbfromuseEntityTimeline,forkEntityfromuseElectricAgents, walksvisibleRowsto find the latest preceding completedrunsrow's pointer, and threads the per-row callback toEntityTimeline. Without this,UserMessagerendered in the mobile embed never received anonForkFromHereprop and the button stayed off the DOM regardless of CSS.src/components/UserMessage.module.css— adds a touch-targeted reveal rule scoped via:global(html[data-electric-mobile-dom='true']) .forkButton { opacity: 1 }. Touch devices don't fire:hover, and.bubble:focus-withinonly kicks in after a tap, so without the override the button stayed invisible until interaction. The reveal lives inside the CSS module (rather than a sibling stylesheet that targets the hashed class by substring) so whichever pipeline is in play — Vite for the web/desktop bundles, Metro for the Expo DOM embed — hashes.forkButtonconsistently with the JSX.The mobile package itself doesn't change. The embed already mounts
ChatView→EntityTimeline→UserMessage, the fork POST already routes throughserverFetch()running in the embed's JS context, and post-fork navigation already routes throughonRequestOpenEntity→openSession(target). OnceChatLogViewproduces the callback map and CSS makes the button visible, the whole flow lights up.Why split from #4410
#4410 was framed as the web/desktop release. The mobile surface depends on the same wiring but ships separately so the web work can land without being held by mobile-specific UX polish. Once both merge, the affordance is uniform across web, desktop, and mobile.
Test plan
pnpm -C packages/agents-mobile ios.-fork-<hash>; the new session contains only the first exchange.✓ done.data-electric-mobile-domattribute the embed sets).🤖 Generated with Claude Code