Repository navigation
agent cursor visibility: the rules in Rust (cmux-focus-core) and the app FFI op (B9 step A) - #31934
Conversation
…Rust rules (failing) The Rust home of the agent cursor visibility rules (backlog B9) gets its types and the replay of schemas/agent-cursor-visibility/vectors.json, ported from the deleted Swift AgentCursorVisibilityVectorTests, plus the page scale case. The resolver is a stub that answers notDrawn(tabClosed): 25 of 26 vectors fail until the rules move in the next commit.
The rules of CmuxNextAgentCursorVisibility's AgentCursorVisibilityResolver, moved as they are: the window that shows (else lists) the target's workspace, minimized and other-Space windows draw nothing, another workspace anchors at its sidebar row (else the window edge), a pane off the active screen at the window edge, a scrolled-out column or page at the strip edge it left through, a background tab at its chip (else the strip), and a shown page draws in its viewport with its clip, zoom and scale. CGRect semantics: sizes are standardized, intersection is none when the rects do not meet. No behavior change; the Swift copy goes in PR 2.
…SON channel
cmux_layout_reducer_json answers agent_cursor_visibility ({target,
snapshot} in, the visibility in the vectors' expect shape out) from
cmux-focus-core's rules. cmux-app-ffi links this crate already, so the next
CCmuxAppFFI release carries the op; the Swift resolver calls it in PR 2.
The C ABI test sends every vector through the op.
…y wire as strings (failing) The app's JSONEncoder refuses non-finite numbers, and a CGRect.null the snapshot builder converts has infinite x and y. The Swift rules gave a result for such a snapshot; the Rust rules must give the same one. (cherry picked from commit 390575f)
…y wire as "inf", "-inf", "nan" Every number of the snapshot and of the answer reads and writes the strings the Swift side's JSONEncoder/JSONDecoder convertToString and convertFromString strategies use, so a snapshot with a converted CGRect.null or an infinite scale gets the result the Swift rules gave it. (cherry picked from commit f21ff3a)
…nite wire strings
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
red: cmux-next checks (god files, concurrency, crash safety, l10n); no finished base run on 9e1c48f to compare; do not merge until green; see lane-rules Shipped in:
The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/41407469077 at 7b24abd failed: cmux-next checks (god files, concurrency, crash safety, l10n). |
… warnings) clippy (changed cmux-tui packages), run 41403471881 job 125140181043, failed on redundant_clone at agent_cursor_visibility.rs:158.
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
|
Review (claude-review-subagent): SHIP at 0355b6f Checked (independent review, correctness first):
Non-blocking notes:
|
Step A of a two-step FFI move (rust-migration backlog B9). This PR replaces #31781. The agent cursor's visibility rules now exist in Rust, in
cmux-focus-core, and the app FFI's JSON channel answers them as theagent_cursor_visibilityop. The rules decide where the cursor for a target browser tab draws: on its page, at an anchor in its window, or nowhere.There are no Swift changes and no behavior change: the app keeps its Swift resolver until step B. Step B is the Swift thin call, its vector suite on a Mac and the deletion of the Swift rules. It is on
rust-migration/cursor-visibility-step-band lands after the bot's CCmuxAppFFI re-pin is on feat-cmux-next.Check the app FFI pin: expected, step A of a two-step FFI move.
What moves
cmux-tui/crates/cmux-focus-core/src/agent_cursor_visibility.rsports the rules ofPackages/macOS/CmuxNext/Sources/CmuxNextAgentCursorVisibility/AgentCursorVisibilityResolver.swiftas they are:Rects follow
CGRectrules: sizes are standardized, an intersection is null when the rects don't meet, and "shows" means more than half a point of overlap on both axes.JSON has no non-finite numbers, and a
CGRect.nullthat the app converts has infinite x and y. So non-finite numbers travel as"inf","-inf"and"nan"in both directions. Step B's Swift encoder and decoder use the same strings, so such a snapshot keeps the result the Swift rules gave it.The op is in
cmux-layout-reducer-ffi/src/lib.rs(cmux-app-ffialready links that crate). The request is{"target", "snapshot"}, where the snapshot isAgentCursorVisibilitySnapshot's Codable shape. The answer is the vectors'expectshape plusscale. A malformed request returnsERR_INVALID.Why the JSON channel and not a typed C ABI: the app resolves once per agent input event, and again on layout or window changes only while a target is tracked. The snapshot holds at most one pane, one chip and one sidebar row per window. Step B runs the perf A/B.
Also: the cmux-tui tree key now lists
schemas/agent-cursor-visibility/vectors.json, which the new tests embed (tree-key-embeds.test.shfails without it).Changelog
none
Observed / Not run
Observed. Head 0355b6f (feat-cmux-next 9e1c48f merged in). This branch is #31781's Rust commits, re-applied with no Swift history. Every proof commit has a
cmux-tuitree identical to the commit the step ran at, checked withgit rev-parse <sha>:cmux-tui.cmux-tui-rust-check.sh test agent_cursor_visibility: stepe8bcaea8fadd17bff9d01e80failed. 3 ran, 2 failed: "25 of 26 vectors differ", and the scale case.ff2f9d6976777a31aba6dd0epassed, 3 of 3.f443e12824c30e91ff7c5fe6failed. 4 ran, 3 passed;agent_cursor_visibility_non_finite_numbers_cross_the_wirefailed in the full run and again alone.1c9f201aabde9547145ae87cpassed, 4 of 4.cmux-layout-reducer-ffi: step30c4eaa5853744cee8d63021passed, 5 of 5 (2 of them in that crate). It ran on the never-merge proof refrust-migration/cursor-visibility-ffiproof, which builds that crate inside the cmux-tui workspace (the crate is its own Cargo workspace, so the fleet script never builds it). The op and its test are unchanged since.91d7f28d21a10dbb5c8001b1and clippy step418b1fe10b7fb6d1e91f86f7. PENDINGredundant_clonein the new test (run 41403471881). 0355b6f fixes it.tree-key-embeds.test.shpasses. The pre-push gate passes on the pushed range.Not run:
swift-logic-lines.pyneedsplans/cmux-next/swift-logic-classes.tsvat the revision, and this branch's base (0511de2) predates it. With no Swift file changed, the row can't move. Step B reports both rows.Differences from the Swift rules that no vector covers (the review flagged them; neither can occur with what the app sends):
viewportand theworkspaceRowrect; Swift returned them as given. They differ only for a negative size, and the app'sAgentCursorRect(CGRect)always has a non-negative size.f64::minandmaxskip NaN, while CoreGraphics passes it through. The app builds no NaN rect (AppKit view rects andCGRect.null, which is infinite, not NaN).Non-green checks, classified:
acpmux tests (lib, hub_integration),tooling-testsdisplay suites, nightly-guards release-notary, andrust workspaces/plan(scripts/journeys/tui-kit/rustfrom journeys tui-kit: tk-gradient, the 120 fps gradient in compiled Rust (byte-identical, rate verdict) #31748; its author was told).