Skip to content

Session Info: Remote Control's row draws a pointer, not a phone outline - #30273

Merged
teamleaderleo merged 4 commits into
feat-cmux-nextfrom
lane/si-remote-control-icon
Nov 1, 2026
Merged

teamleaderleo merged 4 commits into
feat-cmux-nextfrom
lane/si-remote-control-icon

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

Leo, 2026-11-01: "i think we should rethink what symbol we have for remote control at least."

Stacked on #30251 (the optical icon fit). Until that lands, this diff includes its commit. Only the last commit is this PR's.

What

Remote Control's row drew device.phone, a bare phone outline that was taller and narrower than every other row icon. It now draws computeruse.click, a pointer, which is how Claude Code desktop marks its Remote Control row (Leo: "i think it's fine to follow what claude has"). REMOTE_CONTROL_ICON in EnvironmentSection names it, and remoteControlIcon lets the gallery show the alternatives.

Gallery (SessionInfo), each with Remote Control on:

  • environment-remote-control / -on: shipped, the pointer.
  • environment-remote-control-icon-phone-waves (mobile.pair): says "from your phone" more plainly, but it's still a phone first, and the waves get busy at row size.
  • environment-remote-control-icon-display (remote.display): reads as a second machine next to the machine row.
  • environment-remote-control-icon-phone (device.phone): the replaced one.
  • environment-remote-control-icon-link (link): reads as a URL row next to the repository and branch links.

Why the pointer: it matches the reference Leo pointed at. It is the one candidate that reads as "control" rather than "a device". It fits the shared icon box without looking like another machine row.

Spec: leo-workspace design/session-info.md and session-panel.md, updated in the same pass.

Changelog

  • Changed: Session Info's Remote Control row uses a pointer icon.

Observed / Not run

  • New test Remote Control's row draws a pointer, not a phone outline: fails on base (device.phone), passes on head. session-info-environment.test.tsx: 9 pass.
  • scripts/web-lint.sh: passed.
  • I rendered all candidates in the fitted icon column locally (headless Chromium). Not run: a gallery capture through CI.

Risk: small, a one-icon swap plus gallery states.

Agent session: agent session

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Changes Session Info's Remote Control row to draw a pointer instead of a bare phone outline, following Claude Code desktop's Remote Control row. Also introduces an optical fit for row icons in Session Info, so mixed glyphs share one ink box, centre, and stroke.

  • New fit prop on Icon with row scales each glyph's ink to a shared box and rescales strokes to keep pack weight.
  • The pointer is the shipped icon; a remoteControlIcon prop lets the gallery and tests exercise alternatives.
  • The old device.phone was taller and narrower than every other row icon.

Written for commit 43ce9b0. Summary will update on new commits.

View guided diff Turn on auto-fix

teamleaderleo and others added 2 commits November 1, 2026 05:59
Leo, 2026-11-01: "the symbols we have are a little strange looking in terms of
alignment". The row glyphs shared a 16px slot and a 1.5-unit stroke, but their
ink did not: the phone ran 20 units tall (past the row's 19-unit crop), the Mac
13, and the folder and the puzzle piece sat below the slot's centre.

Icon's new `fit` (with `row`) measures each glyph's exact ink bounds, centres
them on the slot, scales the longer side to one 17-unit ink box and widens or
narrows each stroke by the inverse scale, so every glyph draws at the pack's
weight. Session Info's Environment rows, Remote Control and the Context and
Connectors heads use it.

Test: bun test src/agent-session/acpmux/icons/opticalFit.test.ts (12 pass);
session-info environment/info/connectors/context suites pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-7a7568197607c3cdfb81
Leo, 2026-11-01: "i think we should rethink what symbol we have for remote
control at least". The row drew device.phone, a bare phone outline taller and
narrower than every other row icon. It now draws computeruse.click, a pointer,
as Claude Code desktop marks its Remote Control row. The gallery keeps four
others beside it (phone with waves, display, the replaced phone, link).

Test: bun test test/session-info-environment.test.tsx (9 pass; the new
pointer test fails on base, which draws device.phone).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-7a7568197607c3cdfb81
@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 43ce9b0: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr30273 -f ref=lane/si-remote-control-icon -f platform=macos -f backend_mode=local

Gallery before/after for 43ce9b0: 16 states rendered, 17 images differ, 370 more touched states not rendered. Images are in the run's artifact, not on this public PR; the independent review of this head reads them on its own, so the PR needs no hand-made screenshots of these states.

gh run download 41288126717 -R manaflow-ai/cmux -n gallery-advisory-30273-43ce9b04f59ba5cdb85447df119ef50c101488bc (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.chat-inspector/environment-remote-control-icon-phone-waves Apple System Colors Light new 0% own EnvironmentSection.tsx
agent-pane.chat-inspector/environment-remote-control-icon-phone-waves Apple System Colors new 0% own EnvironmentSection.tsx
agent-pane.chat-inspector/environment-remote-control-icon-display Apple System Colors Light new 0% own EnvironmentSection.tsx
agent-pane.chat-inspector/environment-remote-control-icon-display Apple System Colors new 0% own EnvironmentSection.tsx
agent-pane.chat-inspector/environment-remote-control-icon-phone Apple System Colors Light new 0% own EnvironmentSection.tsx
agent-pane.chat-inspector/environment-remote-control-icon-phone Apple System Colors new 0% own EnvironmentSection.tsx
agent-pane.chat-inspector/environment-remote-control-icon-link Apple System Colors Light new 0% own EnvironmentSection.tsx
agent-pane.chat-inspector/environment-remote-control-icon-link Apple System Colors new 0% own EnvironmentSection.tsx
agent-pane.chat-inspector/full Apple System Colors Light changed 0.0338% own EnvironmentSection.tsx
agent-pane.chat-inspector/full Apple System Colors changed 0.0332% own EnvironmentSection.tsx
agent-pane.chat-inspector/workflow-running Apple System Colors Light changed 0.0387% own EnvironmentSection.tsx
agent-pane.chat-inspector/workflow-running Apple System Colors changed 0.0371% own EnvironmentSection.tsx
agent-pane.chat-inspector/workflow-finished Apple System Colors Light changed 0.0337% own EnvironmentSection.tsx
agent-pane.chat-inspector/workflow-finished Apple System Colors changed 0.0332% own EnvironmentSection.tsx
agent-pane.chat-inspector/workflow-agent-row-compact Apple System Colors Light changed 0.0385% own EnvironmentSection.tsx
agent-pane.chat-inspector/workflow-agent-row-compact Apple System Colors changed 0.0372% own EnvironmentSection.tsx
agent-pane.chat-inspector-surfaces/transcript Apple System Colors Light unchanged 0% own SessionInfo.tsx
agent-pane.chat-inspector-surfaces/transcript Apple System Colors unchanged 0% own SessionInfo.tsx
agent-pane.chat-inspector-surfaces/diff-in-place Apple System Colors Light unchanged 0% own SessionInfo.tsx
agent-pane.chat-inspector-surfaces/diff-in-place Apple System Colors unchanged 0% own SessionInfo.tsx
agent-pane.chat-inspector-surfaces/document-beside Apple System Colors Light unchanged 0% own SessionInfo.tsx
agent-pane.chat-inspector-surfaces/document-beside Apple System Colors unchanged 0% own SessionInfo.tsx
agent-pane.chat-inspector-surfaces/diff-closed Apple System Colors Light changed 0% own SessionInfo.tsx
agent-pane.chat-inspector-surfaces/diff-closed Apple System Colors unchanged 0% own SessionInfo.tsx
agent-pane.environment-save/success Apple System Colors Light unchanged 0% own EnvironmentSection.tsx
agent-pane.environment-save/success Apple System Colors unchanged 0% own EnvironmentSection.tsx
agent-pane.environment-save/refused Apple System Colors Light unchanged 0% own EnvironmentSection.tsx
agent-pane.environment-save/refused Apple System Colors unchanged 0% own EnvironmentSection.tsx
agent-pane.inspector-composer-foot/animated Apple System Colors Light unchanged 0% own SessionInfo.tsx
agent-pane.inspector-composer-foot/animated Apple System Colors unchanged 0% own SessionInfo.tsx
agent-pane.inspector-composer-foot/jump Apple System Colors Light unchanged 0% own SessionInfo.tsx
agent-pane.inspector-composer-foot/jump Apple System Colors unchanged 0% own SessionInfo.tsx

Pick other states with a Gallery: entry.id, entry.id/variant line in the PR body.

red: cmux-next checks (god files, concurrency, crash safety, l10n); NEW: red check: Daemon capabilities export is fresh (+4 more) is not red on the base 6cce044; do not merge until green; see lane-rules

Shipped in:

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 8 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="webviews/src/agent-session/acpmux/icons/opticalFit.ts">

<violation number="1" location="webviews/src/agent-session/acpmux/icons/opticalFit.ts:8">
P3: `ROW_SPAN` repeats `ROW_VIEWBOX`'s width as a literal. Derive it from the constant so a crop change cannot desynchronise the fit.</violation>

<violation number="2" location="webviews/src/agent-session/acpmux/icons/opticalFit.ts:89">
P3: Fitting each style separately means a row's icon changes size and centre when selected, for example git.branch and machine.mac. That undercuts the single shared ink box the fit is meant to give a column. Derive the fit from the Line drawing and apply it to Solid, or confirm the size change is intended.</violation>

<violation number="3" location="webviews/src/agent-session/acpmux/icons/opticalFit.ts:107">
P3: Fitting changes the viewBox scale but only compensates `w`, so fitted dashed strokes get shorter dashes relative to their stroke weight. Scale `dash` and `dashPhase` by the same factor when cloning stroke layers.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

/// spans INK_BOX units of the row crop, with every stroke widened or narrowed by the inverse scale so
/// it draws at the pack's weight. Glyphs drawn to different extents (a short Mac, a phone taller than
/// the crop) then share one optical size, centre and stroke.
export function opticalRowFit(layers: IconLayer[]): { viewBox: string; layers: IconLayer[] } {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Fitting each style separately means a row's icon changes size and centre when selected, for example git.branch and machine.mac. That undercuts the single shared ink box the fit is meant to give a column. Derive the fit from the Line drawing and apply it to Solid, or confirm the size change is intended.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/agent-session/acpmux/icons/opticalFit.ts, line 89:

<comment>Fitting each style separately means a row's icon changes size and centre when selected, for example git.branch and machine.mac. That undercuts the single shared ink box the fit is meant to give a column. Derive the fit from the Line drawing and apply it to Solid, or confirm the size change is intended.</comment>

<file context>
@@ -0,0 +1,114 @@
+/// spans INK_BOX units of the row crop, with every stroke widened or narrowed by the inverse scale so
+/// it draws at the pack's weight. Glyphs drawn to different extents (a short Mac, a phone taller than
+/// the crop) then share one optical size, centre and stroke.
+export function opticalRowFit(layers: IconLayer[]): { viewBox: string; layers: IconLayer[] } {
+  const cached = fits.get(layers);
+  if (cached) return cached;
</file context>

/// longer side, so a wide glyph (a Mac) and a tall one (a phone) read as one size in an icon column.
export const INK_BOX = 17;
/// The crop a row icon draws in (ROW_VIEWBOX's width).
const ROW_SPAN = 19;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: ROW_SPAN repeats ROW_VIEWBOX's width as a literal. Derive it from the constant so a crop change cannot desynchronise the fit.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/agent-session/acpmux/icons/opticalFit.ts, line 8:

<comment>`ROW_SPAN` repeats `ROW_VIEWBOX`'s width as a literal. Derive it from the constant so a crop change cannot desynchronise the fit.</comment>

<file context>
@@ -0,0 +1,114 @@
+/// longer side, so a wide glyph (a Mac) and a tall one (a phone) read as one size in an icon column.
+export const INK_BOX = 17;
+/// The crop a row icon draws in (ROW_VIEWBOX's width).
+const ROW_SPAN = 19;
+const DEFAULT_STROKE = 1.5;
+
</file context>

viewBox: [cx - span / 2, cy - span / 2, span, span].map(round).join(" "),
layers: layers.map((layer) =>
layer.op === "stroke" || layer.op === "clearStroke"
? { ...layer, w: round((layer.w ?? DEFAULT_STROKE) * scale) }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Fitting changes the viewBox scale but only compensates w, so fitted dashed strokes get shorter dashes relative to their stroke weight. Scale dash and dashPhase by the same factor when cloning stroke layers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/agent-session/acpmux/icons/opticalFit.ts, line 107:

<comment>Fitting changes the viewBox scale but only compensates `w`, so fitted dashed strokes get shorter dashes relative to their stroke weight. Scale `dash` and `dashPhase` by the same factor when cloning stroke layers.</comment>

<file context>
@@ -0,0 +1,114 @@
+      viewBox: [cx - span / 2, cy - span / 2, span, span].map(round).join(" "),
+      layers: layers.map((layer) =>
+        layer.op === "stroke" || layer.op === "clearStroke"
+          ? { ...layer, w: round((layer.w ?? DEFAULT_STROKE) * scale) }
+          : layer,
+      ),
</file context>
Suggested change
? { ...layer, w: round((layer.w ?? DEFAULT_STROKE) * scale) }
? {
...layer,
w: round((layer.w ?? DEFAULT_STROKE) * scale),
dash: layer.dash?.map((value) => round(value * scale)),
dashPhase: layer.dashPhase === undefined ? undefined : round(layer.dashPhase * scale),
}

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent claude-opus-5-5 medium): SHIP at 45e2950

This PR's own commit (HEAD~1..HEAD; #30251 reviewed separately). REMOTE_CONTROL_ICON defaults through; all five candidate names exist in the bundled pack, and the custom family falls back to it. Gallery props type-check against ComponentProps. Swift supplies only the on/off state, not the icon. session-info-environment 9 pass; icons + other session-info tests 38 pass.

Follow-ups:

  • [follow-up] confirm the pointer in a rendered gallery state (done locally in headless Chromium in the fitted column; a CI gallery capture is still pending)

@teamleaderleo teamleaderleo added the risk:low Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026
@github-actions github-actions Bot removed the risk:low Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026
@blacksmith-sh

blacksmith-sh Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Found 14 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmpc_6huhnj/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmph6akh0bf/summary-fail.json (live):/summary-fail.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs
nightly must build and hand off the macOS 26 helper and Xcode 26.5 app before publishin
g/
nightly must build and hand off the macOS 26 helper and Xcode 26.5 app before publishin
g
View Logs
test_helper_never_takes_a_hosted_mac_and_skips_compile_on_hit (main.WorkflowTests.t
est_helper_never_takes_a_hosted_mac_and_skips_compile_on_hit)/
test_helper_never_takes_a_hosted_mac_and_skips_compile_on_hit (main.WorkflowTests.t
est_helper_never_takes_a_hosted_mac_and_skips_compile_on_hit)
View Logs
test_no_suite_runs_page_javascript_on_a_built_bundle (main.BundleInputs.test_no_sui
te_runs_page_javascript_on_a_built_bundle)/
test_no_suite_runs_page_javascript_on_a_built_bundle (main.BundleInputs.test_no_sui
te_runs_page_javascript_on_a_built_bundle)
View Logs
test_the_nightly_is_covered (main.NightlyStepCoverageTests.test_the_nightly_is_cove
red)/
test_the_nightly_is_covered (main.NightlyStepCoverageTests.test_the_nightly_is_cove
red)
View Logs

...and 4 more test failures. View all on Blacksmith: run 41288126709, run 41288126665

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

…ote-control-icon

# Conflicts:
#	webviews/src/agent-session/acpmux/session-info/EnvironmentSection.tsx
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent claude-opus-5-5 medium): SHIP at 55d151e

Delta after SHIP at 45e2950: merge of feat-cmux-next (c5f935b) resolving one hunk in EnvironmentSection.tsx. It keeps REMOTE_CONTROL_ICON and #29826's MACHINE_KIND_LABELS, with no duplication. The machine Icon keeps row fit and machineColor, and the remoteControlIcon prop and its gallery alternatives are intact. The PR's diff against base is identical before and after the merge. session-info-environment + session-info: 40 pass; tsc clean for session-info and icons.

Follow-ups: none

…ote-control-icon

# Conflicts:
#	webviews/src/agent-session/acpmux/session-info/EnvironmentSection.tsx
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent claude-opus-5-5 medium): SHIP at 43ce9b0

Delta after SHIP at 55d151e: a re-merge of feat-cmux-next after #30251 landed. The single conflict keeps this PR's <Icon name={remoteControlIcon} size={ROW_ICON} row fit /> over base's device.phone line. The PR's diff against base is now only its own four files. session-info-environment 10/10; tsc clean for session-info.

Follow-ups: none

@teamleaderleo
teamleaderleo merged commit 7399502 into feat-cmux-next Nov 1, 2026
94 of 101 checks passed
@teamleaderleo
teamleaderleo deleted the lane/si-remote-control-icon branch November 1, 2026 09:41

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 43ce9b04 Deployed Nov 1, 2026 by teamleaderleo via wait for same-key tree publisher #94889
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant