feat(agents-mobile): pin sessions via long-press context menu#4507
feat(agents-mobile): pin sessions via long-press context menu#4507msfstef wants to merge 3 commits into
Conversation
Port the web sidebar's session pinning to mobile. Long-pressing a root row opens a bottom sheet with the entity info (the web hover card's fields: title, session id, type/status, subagent count, runner, sandbox, spawned, last active) and a Pin/Unpin action. Pinned sessions render in a Pinned section above the date/type/status groups and are removed from the groups and subtrees below, matching the web's semantics; pin state is per-device (AsyncStorage array of urls, the mobile mirror of the web's localStorage model). To resolve runner/sandbox labels the mobile shapes now sync dispatch_policy + sandbox (entities) and sandbox_profiles (runners), and the entityRuntime helper runner params are loosened to structural subsets so mobile reuses them without casts. 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 #4507 +/- ##
=======================================
Coverage ? 33.42%
=======================================
Files ? 206
Lines ? 16914
Branches ? 5917
=======================================
Hits ? 5653
Misses ? 11242
Partials ? 19
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 |
Claude Code ReviewSummaryIteration 2 review. Since the last review the author has (1) addressed all three suggestions from iteration 1 and (2) added two new entry points for pinning: long-press on search results at any depth, and a Pin/Unpin item in the in-session kebab menu ( Previous Review StatusAll three iteration-1 suggestions are resolved:
What's Working Well (new in this iteration)
Issues FoundCritical (Must Fix)None. Important (Should Fix)None. Suggestions (Nice to Have)Nothing new. The remaining open item is unchanged from iteration 1 and already acknowledged by the author: there's no RN component-test harness, so the UI wiring — now including the two new entry points (pin from a search result, pin/unpin from the in-session menu) — is verified by review + screenshots rather than automated tests. Worth folding into the manual Expo pass before merge. Issue ConformanceNo linked issue (per Review iteration: 2 | 2026-06-04 |
Two pin surfaces that were missing relative to desktop: - Search results now support long-press, opening the same context sheet (info + pin) as tree roots — at any depth, like the desktop tile menu. Previously a searched-for session could not be pinned at all. - The in-session kebab menu gains a Pin/Unpin item, mirroring the desktop tile menu's Pin/Unpin and the ⌘K "Pin current entity" action. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Re-resolve the long-pressed entity from the live query while the sheet is open (snapshot fallback if it leaves the collection), so the header tracks status/title updates like the child count already did. - Mount the runners live query only while the sheet has an entity, instead of subscribing for the screen's whole lifetime. - Announce the long-press affordance to screen readers via an accessibilityHint on rows that have a context menu. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>




Intent
The web sidebar lets users pin sessions so frequently-used ones stay at the top regardless of grouping; mobile had no equivalent, so important sessions sink into the date buckets. This ports the pinning feature to the mobile app, adapted for touch — and folds the web's row hover info card into the same surface, since mobile had no way to see session metadata from the list either.
UX
SidebarRowInfo): title, mono session id,type · status · N subagents, Runner (only when a runner is pinned), Sandbox (incl. the implicit "Local" default), Spawned (absolute), Last active (relative) — using the same shared formatters/helpers, so values match the web exactly.SidebarTree), ordered by recency like the web.Deliberate divergences from the web (touch context)
Implementation choices
electric-agents-mobile.pinned-entities) — the mobile mirror of the web'slocalStoragemodel; not synced to the server. Module-level store likesidebarPrefs.ts/savedServers.ts(whole-set subscription — a pin toggle changes list composition, so per-url listener buckets à laexpandedTree.tswould buy nothing), incl. thedirty-guarded hydration merge so a toggle during the startup window isn't clobbered. Unit-tested (vitest, gated AsyncStorage mock that genuinely exercises the pre-hydration path).dispatch_policy+sandbox, runners syncsandbox_profiles(zod defs mirrored fromElectricAgentsProvider.tsx) so the menu can resolve runner/sandbox labels.formatTime+entityRuntimehelpers fromagents-server-ui. The only shared-file change is type-level —entityRuntime's runner params are loosened to a structuralPicksubset (RunnerLike) since mobile's runner schema is narrower; entity params were left untouched (mobile's entity type is fully assignable).onLongPressRootisn't forwarded into theSessionTreerecursion, so child subtree rows can't get a menu;pinnedSetis forwarded so pinned entities are filtered out of subtrees before child-count/connector geometry is computed. Search rows wire the long-press directly (flat list, any depth) — safe because the subtree filtering above already handles pinned children.SessionScreen), closing the sheet on toggle like the row menu does.accessibilityHintso the long-press affordance is announced to screen readers.Testing
pnpm --filter @electric-ax/agents-mobile typecheck && test— 26 passed (7 new for the pin store)pnpm --filter @electric-ax/agents-server-ui typecheck && test— 66 passed (type-only change)🤖 Generated with Claude Code