feat(agents-mobile): session comments (desktop parity)#4587
Conversation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add comments to the native app: a prompt/comment mode in the native composer, tap-a-row-to-reply forwarded from the embed timeline over a new Expo-DOM callback, and a dedicated comments-only view reachable from the session menu. Reading comment bubbles already worked via the shared chat-log embed; this adds the write + reply + dedicated-view surface. No server/runtime changes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4587 +/- ##
==========================================
+ Coverage 57.31% 58.83% +1.52%
==========================================
Files 341 384 +43
Lines 39765 42510 +2745
Branches 11559 12183 +624
==========================================
+ Hits 22791 25011 +2220
- Misses 16934 17421 +487
- Partials 40 78 +38
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Electric Agents Mobile BuildLocal mobile checks ran for commit The EAS Android preview build was skipped because the |
- Compact, right-aligned Message/Comment toggle pill (was a full-width
orphaned row).
- Reset to prompt mode when editing a queued message so the comment
branch can't hijack an edit (mirrors desktop startEditing).
- Match desktop reply-banner wording ("Reply to ...").
- Document the native/embed cross-context gap: optimistic comments
render after stream sync, not instantly (follow-up: comment bridge).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nner - Bridge optimistic comments from the native composer's db into the embed timeline (mirrors the inlineQueuedMessages bridge): forward still-pending comments and project them, deduped by key against synced comments. A posted comment now renders immediately and reconciles in place instead of popping in only after stream sync — desktop parity (shared ordering untouched). - Render the Message/Comment switch above the reply banner. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ity; move switch atop composer - Revert the optimistic-comment bridge: it appended projected comments rather than letting the shared createEntityTimelineQuery sort them, diverging from desktop ordering. Mobile now uses the identical shared timeline path, so message/comment ordering matches the desktop app. (Trade-off, accepted: on a device a posted comment appears on stream sync rather than optimistically.) - Move the Message/Comment switch to the top of the composer card so it no longer sits in the seam between the queued drawer and the input. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The reply banner sat between the queued drawer's open bottom and the input, breaking that connection. Render it above the drawer so the drawer connects directly to the input again: toggle, reply banner, drawer, input. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restore the optimistic-comment bridge so a posted comment renders immediately instead of waiting for the embed's stream to sync. The native composer's optimistic insert lands in its own (native) db; the still-pending comments are forwarded across the Expo-DOM boundary and projected into the embed timeline (deduped by key against synced rows), mirroring the existing inlineQueuedMessages bridge. The `~pending` orders keep them in the same bottom band the shared query uses, so ordering still matches desktop. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude Code ReviewSummaryIncremental review of commit Review of the new commit (7f02888)
No new correctness, security, or convention concerns. Both Issues FoundCritical (Must Fix)None. Important (Should Fix)None — both iteration-2 Important/Suggestion items are now addressed. Suggestions (Nice to Have)Carried over from earlier iterations, still low priority and unchanged by this commit:
Issue ConformanceNo linked issue (soft warning per convention). PR body is thorough and accurate; scope matches. The one documented known limitation (comments-only view target-click doesn't scroll to non-comment rows) is acknowledged as a follow-up. Previous Review Status
With these resolved, the PR looks ready from a correctness and conventions standpoint. Review iteration: 3 | 2026-06-16 |
…banner label Address review feedback: - showStop now excludes comment mode (mirrors desktop MessageInput), so the Post button on the comments surface never becomes a Stop-generating control while the agent is running. - Move formatReplyBannerLabel into shared lib/comments.ts and import it on both desktop and mobile instead of duplicating; add a unit test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for the review — addressed in 7f02888. Fixed
Deferred (reasoning)
Verified locally: both packages typecheck, ESLint + Prettier clean, full suites pass (agents-server-ui 104, agents-mobile 84). |
The native shell always passes the reply callback to the chat-log embed, so the timeline showed a reply button even for entity types that don't declare the comments contract. Gate onReplyToRow/onCommentTargetClick on commentsEnabled in ChatLogView, mirroring desktop GenericChatBody. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
✅ Deploy Preview for electric-next ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
The native composer stops forwarding an optimistic comment as soon as its own stream syncs it, but the embed renders off its own (separate) stream — so if native synced first the projected row blinked out before the embed's authoritative row arrived. ChatLogView now latches optimistic comments and only drops one once THIS embed's stream delivers it (with a timeout safety net for a failed POST). Render = (incoming union latched) minus synced, so a posted comment shows on the first frame and survives the hand-off without flicker. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
msfstef
left a comment
There was a problem hiding this comment.
Looks reasonable but it needs a rebase and also I would appreciate screenshots/video for the feature
Summary
Brings session comments to
agents-mobile, closing the parity gap with the desktop UI (comments shipped in #4551). Part of the agents-mobile ↔ agents-desktop parity track (follows #4564, #4553).The mobile session timeline is a shared web component (
SessionChatLogDomEmbed) rendered inside an Expo-DOM WebView, while the composer is native. Because the embed already merges comments viauseEntityTimelineand rendersCommentBubble, reading comment bubbles already worked on mobile — this PR adds the missing write, reply, and dedicated-view surface.What's included
Message / Commenttoggle (top of the composer), shown only when the entity type declares the comments collection and the user haswriteaccess. Comment mode reuses the desktop'screateSendCommentActionverbatim (optimistic insert + authenticatedPOST /collections/comments), disables attachments/slash, and posts plain-text comments. Editing a queued message resets to prompt mode (mirrors desktop) so the comment path can't hijack an edit.onRequestReplyToComment(target)is threadedSessionChatLogDomEmbed → EmbedApp → ChatLogView → EntityTimeline.onReplyToRow. Tapping "reply" on a timeline row forwards theSelectedCommentTarget(plain JSON) to the native shell, which switches the composer to comment mode, focuses the input, and shows a reply banner.dbs, so the optimistic row inserted on the native side isn't visible in the embed on its own. Still-pending comments are forwarded across the boundary and projected into the embed timeline (deduped by key against synced rows), mirroring the existinginlineQueuedMessagesbridge — so a posted comment renders immediately. Their~pendingorders keep them in the same bottom band the shared query uses, so ordering matches desktop.commentsEmbedViewIdrendersbuildCommentsTimeline(via acommentsOnlyprop on the chat-log embed) with a comment-locked native composer, reachable from a new gated Comments entry in the session menu.The shared
agents-server-uichanges are additive and optional — desktop callers ofChatLogView(embed-only) are unaffected. No server / runtime changes.Test plan
@electric-ax/agents-mobile+@electric-ax/agents-server-ui— typecheck cleancomments.test.ts(send action,buildCommentsTimeline, target encode/decode)Known limitation
🤖 Generated with Claude Code