Skip to content

Agent chat: a video shows its poster, play button and length, plays on a click, and opens in its own tab - #24112

Merged
teamleaderleo merged 9 commits into
feat-cmux-nextfrom
inline-media-video
Oct 22, 2026
Merged

teamleaderleo merged 9 commits into
feat-cmux-nextfrom
inline-media-video

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Leo (2026-10-21, relayed by claude-sr2): "this watch is kind aass also id like to be able to watch .mp4s direclty in cmux next somehow (chromium?)"

Leo-ask: watch-mp4-inline (relayed by claude-sr2)

Takes back #24082: it doesn't. #24082's one-line covers: list in InlineMedia.gallery.ts is re-wrapped onto several lines with two more covers (ReplyMedia.tsx#VideoThumbnail, icons.tsx#OpenTab). #24082's change, dropping the inlineMedia.ts module cover, is kept.

Summary

A video in an agent reply or a tool's output used to draw as a bare <video> box. Until it played, it was black (with preload="metadata" WebKit paints no frame), with no length and no clear way to play it. Now it draws as a thumbnail that plays in place:

  • Thumbnail: the poster frame (the player seeks to 0.1 s once the metadata loads, so WebKit paints that frame), a round glass play button in the middle, and the length (1:05, 1:02:05) in the corner.
  • Click to play: a click plays it from the start, with sound and WebKit's controls. With the pointer resting on it, it still previews muted, as before.
  • Open in tab (a new glass button beside Expand) opens the video the way a link opens:
    • a file goes through the path chip's link.openPath. The host checks the path again (deny list, roots, gesture) and opens it in cmux's file pages. LocalFileHandoff sends mp4/mov/m4v to a WebKit tab, which plays it.
    • a web video (https only) goes through browser.openIn with cmux, which opens a cmux browser tab.
    • Placement comes from the host's shared open request. Once Agent chat: links open on the right, never over the chat #23908 ("links open in the rightmost split, never over the chat") lands, this follows the "Open new tabs and links" setting with no change here.
  • Expand: the large player opens paused with the same poster and Play button. Only Play starts it with sound; it never autoplays. Before, it mounted an unmuted <video autoPlay>.
  • Motion: the play button's and the action bar's hover transitions run only under prefers-reduced-motion: no-preference, timed by the motion-scale token --cmux-motion-micro.
  • Pointer: the play button, Open in tab, Expand, and a playing video's controls all show the pointing hand.
  • No parallel path: this extends the existing Play a video or recording an agent writes inline in the chat #18402 path (media.load, the unguessable cmux-agent://pane/__media/ grant, the byte-range scheme handler, CSP media-src 'self'). It adds no new host method, CSP change or Swift.

Codec path: WebKit <video>, no native overlay

  • Inline: the agent pane is a WKWebView, and WebKit's <video> plays H.264, HEVC and AAC through AVFoundation. It plays the mp4/m4v/mov/webm files the host already grants, so no AVPlayerView overlay is needed. An overlay would also have to track scrolling and clipping inside the transcript.
  • Tab: files open in WebKit (LocalFileHandoff). Web videos open in the cmux browser tab. The CEF fork does enable proprietary codecs:
    • scripts/cmux-next/cef-manifest.json pins cef-154.0.28-cmux.28.
    • plans/cmux-next/browser.md item 6 says that since cmux.28 (2026-10-17) the fork builds with proprietary_codecs=true ffmpeg_branding=Chrome. It was verified 2026-10-19 with MP4 H.264/AAC.
    • The comments in BrowserProtectedMedia.swift and BrowserSiteEngines.swift saying proprietary_codecs is off predate cmux.28.

Coverage

Source Inline Tab
Local file inside the chat's folders yes yes (link.openPath, file pages)
https URL (nightly reels, PR media, GitHub attachments), after Load or with images.remote = always yes (host's checked copy) yes (cmux browser tab)
File on an ssh peer's chat no, see Not run no

Tests

  • webviews/test/inline-video.test.tsx (new, 24 tests):
    • URL and path classification (mp4/mov/webm/m4v by path, file URL and https; audio; non-video);
    • https-only web media;
    • the open request per source (file → link.openPath, https → browser.openIn cmux, http:/javascript:/a remote file:///the deny list → none);
    • length formatting;
    • the rendered player: poster seek, glass play button, length label and aria label "Play video, 1:05". A click turns on sound and controls and plays. Open in tab sends the reply's path, never the granted URL;
    • cursor: pointer on the play button, the actions and a playing video's controls;
    • Expand opens paused: no autoplay and nothing playing after a hover preview; Play in the large player plays with sound. At the red commit 6c56706 this fails (autoplay present); at 3046a71 it passes;
    • the hover transitions sit inside prefers-reduced-motion: no-preference (red at 6c56706, green at 3046a71).
  • Gallery: agent-pane.inline-media gets video-thumbnail (a local recording) and web-video-thumbnail (a nightly reel link with images.remote = always).

Observed / Not run

  • Observed (cmux16):
    • at 6c56706 (red tests only): bun test inline-video 22 pass, 2 fail;
    • at 3046a71: bun test inline-video 24 pass, 0 fail; test/inline-media.test.tsx 52 pass; prepush-gate.py: no new violations.
    • bun run check in webviews/ passes (Oxfmt, Oxlint with the type check, catalog keys, layers, type scale, acpmux protocol).
  • CI at b7de7c3 (includes base 6acda7a): test/inline-video.test.tsx passes in react-apps-check. Every red there is a base red: test/composer-row-layout.test.ts type errors (Row.muted), the Swift namespace convention errors in AgentPaneNeedsYouSetting.swift and AttentionHighlightLook.swift, other test files in shard 1, gallery health's agent-pane.composer#steer-read-hover, the release rails migration tests, and the release-notary guard.
  • Base reds (not this PR's):
    • test/ui-rules.test.ts fails at 5e70632dca on VoiceInputCard.tsx, ChiefViewsPage.tsx and AppsPage.tsx.
    • test/gallery-coverage.test.ts also fails at 5e70632dca: inlineMedia.ts/safeTail.ts covers, plus 13 base components with no entry. This PR's two new names (VideoThumbnail, OpenTab) are covered.
  • Not run:
    • Recording. Leo asked for one: a video playing inline and in a right-side tab. I couldn't take it within this slice's deadline: the inline player is webview-only, and the right-side tab needs a fleet build plus a capture mini (cmux-ci capture). A follow-up push will add it. The gallery advisory run renders both new variants.
    • Peer-host files. A chat on an ssh peer resolves reply paths on this Mac (AgentPaneReplyPaths), and the pane has no binary file read from a peer: acpmux has putFile for uploads but no download. Peer videos (and peer images) still show as their name. They need a new acpmux file-read route; that's a follow-up.
    • raw.githubusercontent.com in a tab. That host may serve .mp4 as application/octet-stream, so a top-level browser tab may download it instead of playing it. Inline playback is unaffected, because the host sniffs the bytes.
    • No Swift changed, so no cmux-ci compile-check.

Changelog

  • Added: Videos in agent chat replies show a thumbnail with a play button and their length, play in place on a click, and open in their own tab.

🤖 Generated with Claude Code

Agent session: cosmic-gray

teamleaderleo and others added 2 commits October 21, 2026 19:38
…ays on a click and opens in a tab

Leo 2026-10-21: "id like to be able to watch .mp4s direclty in cmux next somehow (chromium?)".

A reply's or a tool's video (a file, or a web video the host fetched) now draws as its poster
frame with a glass play button and its length, previews muted under the pointer as before, and
plays with sound and controls on a click. Open in tab opens it the way a link opens: a file
through link.openPath (cmux's file pages), a web video in a cmux browser tab. Every control
shows the pointing hand.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a1602e-25ea-7611-8c79-d16df0c4058f&host=cosmic-gray
@teamleaderleo teamleaderleo added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 22, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by inline-media on cosmic-gray · session

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

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

Review 457f6cb: 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=pr24112 -f ref=inline-media-video -f platform=macos -f backend_mode=local

Gallery before/after for 457f6cb: 16 states rendered, 5 images differ, 1593 more touched states not rendered. Images are in the run's artifact, not on this public PR.

gh run download 39866295032 -R manaflow-ai/cmux -n gallery-advisory-24112-457f6cbc6ea048e44c6bfafe71c03e140b80c786 (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.composer/new-chat Apple System Colors Light unchanged 0% own icons.tsx
agent-pane.composer/new-chat Apple System Colors unchanged 0% own icons.tsx
agent-pane.composer/side-session Apple System Colors Light unchanged 0% own icons.tsx
agent-pane.composer/side-session Apple System Colors unchanged 0% own icons.tsx
agent-pane.composer/new-chat-suggest-open Apple System Colors Light unchanged 0% own icons.tsx
agent-pane.composer/new-chat-suggest-open Apple System Colors unchanged 0% own icons.tsx
agent-pane.composer/new-chat-suggest-failing Apple System Colors Light unchanged 0% own icons.tsx
agent-pane.composer/new-chat-suggest-failing Apple System Colors unchanged 0% own icons.tsx
agent-pane.composer/new-chat-suggest-draft Apple System Colors Light unchanged 0% own icons.tsx
agent-pane.composer/new-chat-suggest-draft Apple System Colors unchanged 0% own icons.tsx
agent-pane.composer/new-chat-reasoning Apple System Colors Light unchanged 0% own icons.tsx
agent-pane.composer/new-chat-reasoning Apple System Colors unchanged 0% own icons.tsx
agent-pane.composer/agent-home Apple System Colors Light unchanged 0% own icons.tsx
agent-pane.composer/agent-home Apple System Colors unchanged 0% own icons.tsx
agent-pane.composer/agent-home-path Apple System Colors Light changed 0% own icons.tsx
agent-pane.composer/agent-home-path Apple System Colors unchanged 0% own icons.tsx
agent-pane.inline-media/video-thumbnail Apple System Colors Light new 0% own ReplyMedia.tsx
agent-pane.inline-media/video-thumbnail Apple System Colors new 0% own ReplyMedia.tsx
agent-pane.inline-media/web-video-thumbnail Apple System Colors Light new 0% own ReplyMedia.tsx
agent-pane.inline-media/web-video-thumbnail Apple System Colors new 0% own ReplyMedia.tsx
agent-pane.inline-media/before-after Apple System Colors Light unchanged 0% own ReplyMedia.tsx
agent-pane.inline-media/before-after Apple System Colors unchanged 0% own ReplyMedia.tsx
agent-pane.inline-media/labelled-lines Apple System Colors Light unchanged 0% own ReplyMedia.tsx
agent-pane.inline-media/labelled-lines Apple System Colors unchanged 0% own ReplyMedia.tsx
agent-pane.inline-media/path-in-sentence Apple System Colors Light unchanged 0% own ReplyMedia.tsx
agent-pane.inline-media/path-in-sentence Apple System Colors unchanged 0% own ReplyMedia.tsx
agent-pane.inline-media/pr-media Apple System Colors Light unchanged 0% own ReplyMedia.tsx
agent-pane.inline-media/pr-media Apple System Colors unchanged 0% own ReplyMedia.tsx
agent-pane.open-in-menu/closed Apple System Colors Light unchanged 0% own chips.css
agent-pane.open-in-menu/closed Apple System Colors unchanged 0% own chips.css
agent-pane.open-in-menu/several-browsers Apple System Colors Light unchanged 0% own chips.css
agent-pane.open-in-menu/several-browsers Apple System Colors unchanged 0% own chips.css

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

Passes: CI passes on 457f6cbc6e.

CI passes on 457f6cbc6e (run 39866295239 attempt 1).

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

red: cmux-next checks (god files, concurrency, crash safety, l10n); no finished base run on 84d5d32 to compare; do not merge until green; see lane-rules

Tour of 457f6cbc6e (run): no media. The tour did not run: only webview code changed (6 path(s)), which the gallery advisory run checks in Linux Chromium on the pull request (its artifact holds any captures); add the media-tour-mac label, then re-add media-tour, to tour it on a Mac.

@blacksmith-sh

blacksmith-sh Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Found 11 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmpn1wx8a81/summary-fail.json (live):/summary-fail.json (live): View Logs
/tmp/tmpw5sw6cpn/summary-missing.json (live):/summary-missing.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
convention violations found (ERROR lines above)./
convention violations found (ERROR lines above).
View Logs
test_base_passes (main.NoticesPairTests.test_base_passes)/
test_base_passes (main.NoticesPairTests.test_base_passes)
View Logs
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules)/
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules)
View Logs
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules) (job='web-bundles')/
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules) (job='web-bundles')
View Logs

...and 1 more test failures. View all on Blacksmith

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

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-nyakc created for this PR by the cmux coordinator.

teamleaderleo and others added 3 commits October 21, 2026 21:39
…t with sound); hover transitions follow reduced motion

The expanded player mounted an unmuted <video autoPlay>, so expanding a hovered thumbnail started
it with sound before anyone pressed Play. It now reuses the thumbnail: poster, Play, length, and
no autoplay. The play button's and the action bar's transitions run only under
prefers-reduced-motion: no-preference and use the motion scale token.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a1602e-25ea-7611-8c79-d16df0c4058f&host=cosmic-gray
…a-video

# Conflicts:
#	webviews/src/agent-session/acpmux/conversation/InlineMedia.gallery.ts
@cursor

cursor Bot commented Oct 22, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot 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.

teamleaderleo and others added 3 commits October 21, 2026 22:42
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent, correctness first): SHIP at 9580bab

Different-model review (Codex xhigh via acpmux, diff only) returned SHIP at this head; compile at this head is green.

@teamleaderleo teamleaderleo added the ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds label Oct 22, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Orphaned: no activity for 15 h, and no lane holds a lease on it. Adopted by the orphan sweep: merged feat-cmux-next in at 457f6cb. A later pass queues it for the merge hub if it is reviewed, small and red only on base reds.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next guards / nightly-guards / workflow-guard-tests / release-notary is red on 19 of 19 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next / cmux-next checks (god files, concurrency, crash safety, l10n) › Checks job structure is red on 17 of 17 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next / cmux-next checks (god files, concurrency, crash safety, l10n) › No fleet host names in gallery fixtures is red on 15 of 17 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (Codex xhigh, re-pinned after base update): SHIP at 457f6cb

  • The Codex xhigh review passed at 9580babd82be0b072625d61a9ae6e5acf14c25cf (Agent chat: a video shows its poster, play button and length, plays on a click, and opens in its own tab #24112 (comment)). 457f6cbc6e merges feat-cmux-next into the branch, with parents 9580babd82 and base, and adds no other commits.
  • The PR's own diff against base at 457f6cbc6e matches the reviewed diff line for line (the added and removed lines hash the same), so the reviewed code is unchanged.
  • This PR changes only webviews files, so the app compile is routed off. fast gates, cmux-next fast tier (cargo) and the web checks pass at this head.
  • The remaining reds fail the same way on base: release-notary / Guard status (workflow-guard-tests), and cmux-next checks.

@teamleaderleo
teamleaderleo merged commit a662c3f into feat-cmux-next Oct 22, 2026
130 of 134 checks passed
@teamleaderleo
teamleaderleo deleted the inline-media-video branch October 22, 2026 23:55
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant