Cloud presence: teammates' pointers and highlights on shared terminals - #12300
Cloud presence: teammates' pointers and highlights on shared terminals#12300lawrencecchen wants to merge 4 commits into
Conversation
… the daemon Adds a presence hub to cmux-tui-core: presence-update, presence-clear, presence-list commands and a coalesced presence-changed subscribe event under capability presence-v1. Presence is never journaled, is cleared on disconnect or surface exit, and is rate limited per connection. Spec in spec/presence.md; raw bindings regenerated. Claude-Session: https://claude.ai/code/session_012DpfpRex9MYKKZBz3Lv5sq
|
All contributors have signed the CLA ✍️ ✅ |
|
Warning Review limit reachedNext included review available in 8 minutes. View limit detailsLimit details: You’ve used all 10 included reviews currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: ⛔ Files ignored due to path filters (25)
📒 Files selected for processing (57)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…terminal panes One presence-only cmux-tui link per machine (identify, set-client-info with presence-v1, subscribe presence_only). The Ghostty view publishes the hovered cell as a presence-update and a Cmd+Shift drag as a laser highlight; a click-through overlay above each cloud pane draws other clients' pointers, name pills, and highlights, shifting rows by scrollback offset. Daemon gains subscribe.presence_only so the link never receives tree or output traffic. Claude-Session: https://claude.ai/code/session_012DpfpRex9MYKKZBz3Lv5sq
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 4 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 41195f4. Configure here.
| highlight: cloudPresenceHighlight | ||
| ) | ||
| return true | ||
| } |
There was a problem hiding this comment.
Laser highlight never fades
High Severity
finishCloudPresenceHighlight leaves cloudPresenceHighlight set, and every later pointer publish resends that laser. The daemon then refreshes updated_at_ms on the whole entry, so viewers age the laser from the latest pointer move and it never fades while the publisher keeps hovering.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 41195f4. Configure here.
| ) | ||
| NSBezierPath(roundedRect: rect.insetBy(dx: -1, dy: -0.5), xRadius: 2, yRadius: 2).fill() | ||
| } | ||
| } |
There was a problem hiding this comment.
Highlight ignores end scroll offset
Medium Severity
drawHighlight shifts both ends by the start cell’s scroll_offset and drops the end anchor’s offset. Start and end are captured at different times, so a mid-drag scroll or live output that changes rowsBelowViewport maps the range to the wrong rows.
Reviewed by Cursor Bugbot for commit 41195f4. Configure here.
| return machineEntries.values | ||
| .filter { $0.surface == pane.remoteSurfaceID } | ||
| .sorted { $0.client < $1.client } | ||
| } |
There was a problem hiding this comment.
Own pointer drawn on overlay
Medium Severity
entries(forPane:) returns every live entry on the pane’s surface, including this Mac’s own presence-changed echo. The overlay is meant to draw teammates only, so the local user gets a duplicate arrow and name pill on their cursor.
Reviewed by Cursor Bugbot for commit 41195f4. Configure here.
| if entries.removeValue(forKey: link.machineID) != nil { | ||
| post(machineID: link.machineID) | ||
| } | ||
| } |
There was a problem hiding this comment.
Presence link does not reconnect
Medium Severity
A dropped presence socket is left disconnected until the next publish. updateSocketPath no-ops when the path is unchanged, so after a machine blip or daemon restart a viewer who is not hovering never redials and teammates’ pointers stay gone.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 41195f4. Configure here.


Lets people attached to one cmux-tui session point at a cell and highlight a line in a shared terminal while they talk, from the Mac app.
Daemon (
cmux-tui): a presence hub with commandspresence-update,presence-clear,presence-list, a coalescedpresence-changedsubscribe event, andsubscribe.presence_onlyso a presence link never receives tree or output traffic. Capabilitypresence-v1. Anchors are surface coordinates (cell {row,col,scroll_offset}orpoint {x,y}); highlights arelaser(fade) orpin(stay). Presence is never journaled and never touches the registry lock; the hub keeps only the latest state per connection, rate limits at 240/s, and clears on disconnect,presence-clear, or surface exit. Identity is the connection plus itsset-client-infolabels; authenticated actor identity is a later contract. Spec:cmux-tui/spec/presence.md. Raw bindings regenerated (109 commands, 49 events).Mac: one presence-only link per cloud machine (
CloudPresenceLink,CloudPresenceStore). The Ghostty view publishes the hovered cell; Cmd+Shift-drag publishes a laser highlight without making a local selection. A click-through overlay above each cloud pane (CloudPresenceOverlayView) draws other clients' arrow, name pill, cell frame, and highlights, shifting rows by scrollback offset difference.Tests: hub unit tests; in-process server tests (coalescing, disconnect clear, surface-exit clear); a WebSocket end-to-end test with a
presence_onlyviewer, a pointer, and a late joiner; Swift Testing coverage for decoding, command shapes, and row mapping (cmuxTests/CloudPresenceTests.swift).Verified live on tag
prsnc: the branch daemon swapped into a dev-stack Freestyle VM (baseline CPU build), a synthetic second client inside the VM pointed and pinned a highlight on the pane's surface, and the tagged Mac app drew it at the right cells;list-clientsshowed the Mac presence link as kindmac. Testbox: presence tests, clippy-D warningsoncmux-tui-coreandcmux-tui, schema and inventory checks, Go/Rust/Python/TypeScript binding tests.workspace_registry::tests::startup_repairs_legacy_terminal_close_dangling_resource_rowsfails identically on main 4aa03bc and is unrelated.Known limits: terminal panes only (browser panes have no daemon surface id yet); a late joiner sees a pointer on its next move rather than through
presence-list; names are self-asserted until actor identity lands.Found on the way: #12308 (
vm pushchunk exceeds the Freestyle command cap).https://claude.ai/code/session_012DpfpRex9MYKKZBz3Lv5sq
Note
Medium Risk
Touches terminal mouse routing and a second socket per cloud machine; mistakes could steal input or leak stale overlays, but scope is limited to presence-enabled cloud panes and optional
presence-v1capability.Overview
Adds collaboration presence on the Mac app for cloud manual-mirror panes: teammates see each other’s cell pointers and highlights over the same remote terminal surface.
The Mac side introduces models and wire decoding for
presence-changed, a presence-onlyCloudPresenceLinkper cloud machine (subscribewithpresence_only, throttledpresence-update/presence-clear), andCloudPresenceStoreto register panes, fan in remote entries, and publish local state. Manual-I/O gainspresence-v1commands and frame decoding (including clears withsurface: null); the mirror byte stream ignores presence frames.Ghostty publishes the hovered grid cell (with scroll offset) for registered panes; Cmd+Shift-drag starts a fading laser highlight without taking over normal selection. A click-through
CloudPresenceOverlayViewdraws remote arrows, name pills, and selection-style highlights with scroll-offset correction. Cloud surface providers register/unregister panes and keep surface/socket IDs in sync on reconnect.cmux-tui SDK bindings (C++/Go) are regenerated for
presence-update,presence-clear,presence-list,presence-changed, andsubscribe.presence_only.Reviewed by Cursor Bugbot for commit 41195f4. Bugbot is set up for automated code reviews on this repo. Configure here.