Repository navigation
Conversation
When Claude opens a browser with playwright-cli, the plugin now injects @replayio-app-building/session-recorder into every page of the session and shows the run as a player in place of that Bash call's result: live while the browser runs, then scrubbable (seek bar, play/pause, +/-10s) once it closes. Save video renders an .mp4 and .rrweb.json into .replay/live/, and /replay-live lists or opens every saved recording. - hooks/register.tsx: Claude Code hooks module (listed under `modules` in hooks/hooks.json beside the existing command hooks) - live/relay.mjs: zero-dependency local relay that stores recordings, renders players in headless Chrome and exports MP4s with ffmpeg - live/tracer.js, live/vendor/: built from npm by live/build.mjs - registry.json: ship the new files with the claude-pro item Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Caution Review the following alerts detected in dependencies. According to your organization's Security Policy, you must resolve all "Block" alerts before proceeding. It is recommended to resolve "Warn" alerts too. Learn more about Socket for GitHub.
|
…marketplace - Live players link each browser session to the Replay Chromium recordings made while it ran; the player row and library offer Upload, Open in Replay, and Debug with Claude (prefills a Replay MCP prompt). - The players replay in headless Replay Chromium (recording off), so no separate Chrome install is needed. - MP4 capture is opt-in: browser-open.js and the lifecycle hook capture only with --output / REPLAYIO_MP4_PATH / REPLAYIO_RECORD_VIDEO=1. - Signed out, uploads no longer block on replayio's interactive sign-in: the hooks leave recordings local, the player's Upload starts `replayio login` and returns, and the skill tells Claude to start the sign-in in the background and wait for the user to confirm. - Slash command renamed to /replayio. - .claude-plugin/marketplace.json: install with `claude plugin marketplace add replayio/plugins` and `claude plugin install replayio@replayio`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each Replay MCP call (mcp__plugin_replayio_replay__* or a hand-added
mcp__replay__* server) now replaces its transcript row with a card built
from the markdown Claude read, following the replay-mcpui PRD: header with
status and scope, 1-3 facts, one evidence preview (console/network tables,
stack frames, source with hit counts, render-cost bars, component trees,
the screenshot), collapsible consumed-data/related/raw sections, and
actions (open in Replay, prefill the tool's next step, copy).
- hooks/mcp/card.ts: card model and markdown helpers
- hooks/mcp/tools/{overview,code,react}.ts: a parser per tool (all 30)
- hooks/mcp/render.tsx: terminal renderer, ToolGroup unfolding
- hooks/mcp/fixtures.ts + cards.test.ts: outputs recorded from a real
session (paths scrubbed) and tests over them
- live/relay.mjs: /image converts Replay's JPEG screenshots to PNG for
the terminal (rendered in headless Replay Chromium)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
playwright-cli keeps a session per working directory, so a command such as `cd /tmp && playwright-cli --session=x open ...` opened a browser the plugin could not see from Claude's own directory: the recording was created but the tracer was never injected and no events arrived. - detect.ts follows `cd` (relative, absolute, `..`; `~` and variables are reported as unknown) and returns the directory each command ran in. - register.tsx runs the injection with that cwd, remembers the session's starting directory, and when injection fails marks the recording ended and shows a toast with the reason instead of leaving an empty live player. - relay.mjs records the browser's directory, so Save video writes under it. Found by running a headless `claude -p --plugin-dir` against three command shapes; all three now record events. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…the call row
The player never appeared for runs an agent wrote as `pw(){ npx -y
@playwright/cli "$@"; }; pw open ...` or with `agent-browser`, and the player
was drawn on a result row the engine does not raise inside a folded shell
group.
- detect.ts: recognizes `npx @playwright/cli`, shell-function/alias/variable
wrappers, and `agent-browser` (skipping its flag values, session from
--session or AGENT_BROWSER_SESSION); falls back to the CLI's own output
(`Browser x opened`) when the text hides the CLI.
- relay.mjs: attaches to browsers it did not launch over CDP (agent-browser's
endpoint): binding, new-document script and evaluate, so CSP cannot block it
and later navigations and tabs are followed.
- register.tsx: handles opens/closes in command order, skips attaching when a
call opens and closes the same session, treats agent-browser `open` on a
live session as navigation, draws the player on the ToolUse row and unfolds
groups that hold one.
Tested headless (`claude -p --plugin-dir`) with the wrapper and an
agent-browser/Replay Chromium command; both record events.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Renders the brand mark (https://www.replay.io/images/logo.svg) to assets/replay-logo.png and draws it, 2 cells wide, at the start of each card header and player headline; terminals without image support keep the diamond. Also ignore local playwright-cli and Replay live output in the plugin folder. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
session-recorder calls crypto.randomUUID, which exists only in secure contexts, and wraps localStorage, which throws on an opaque origin. On a file:// page (and a plain-http LAN address) startSession threw while starting, the tracer was injected but produced no packets, and the player read "0 events". - build.mjs: the tracer entry polyfills crypto.randomUUID, falls back to in-memory local/sessionStorage when access throws, and reports a start failure as a detected error instead of failing silently. - register.tsx: a session that ends with no events now says so on the player row, with the reason when the tracer reported one. - live/tracer.js rebuilt. Reproduced headlessly (file:// gave 0 events, http://localhost gave events); both now record. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
What
When Claude opens a browser with
playwright-cli(raw,$PWCLI, orscripts/browser-open.js), thereplayioClaude Code plugin now shows that run as a player inside the transcript, in place of the Bash call's result:<project>/.replay/live/<start>-<session>.mp4and.rrweb.json./replayiolists recordings across sessions./replayio libraryopens a page with all of them, and/replayio save <session|latest>saves one.~/.claude/replayio-live/, so players in scrollback keep working after a restart.How
hooks/register.tsxis a Claude Code hooks module. It is listed undermodulesinhooks/hooks.json, next to the existingPostToolUse/Stopcommand hooks, andclaude plugin validateaccepts both in one file.open, it runsplaywright-cli run-codewith a script that adds a binding and an init script. Every document in the session then streams@replayio-app-building/session-recorderpackets (rrweb, network, storage, websockets) through the playwright daemon, so page CSP can't block them.live/relay.mjsis a zero-dependency local server. It stores recordings, plays them with rrweb'sReplayerin headless Replay Chromium, and screencasts PNG frames that the module draws as an inlineImage. MP4 export seeks frame by frame and pipes the frames to ffmpeg.live/tracer.jsandlive/vendor/are committed build output fromlive/build.mjs(npm install && npm run build): session-recorder 0.17.1 and rrweb 2.0.0-alpha.18.registry.jsonships the new files with theclaude-proitem, and the version is bumped to 0.2.0.Also in this PR
Claude Code marketplace:
.claude-plugin/marketplace.json. Install withclaude plugin marketplace add replayio/pluginsandclaude plugin install replayio@replayio. Tested from this branch in a cleanHOME.Replay recording links: when a browser closes, the player and the library link it to the Replay Chromium recordings made while it ran, with Upload, Open in Replay, and Debug with Claude (pre-fills a Replay MCP prompt).
No extra browser to install: players replay in headless Replay Chromium with recording off (checked: no extra local recordings are created).
MP4s are opt-in:
browser-open.jsand the lifecycle hook capture video only with--output,REPLAYIO_MP4_PATH, orREPLAYIO_RECORD_VIDEO=1. Previously every rawplaywright-cli openstarted capture.Signed-out uploads don't block:
replayio uploadsigned out starts an interactive sign-in and waits for it.browser-close.jsnow skip the upload and leave recordings local.replayio loginand returns.SKILL.mdtells Claude to run the sign-in in the background, then stop and wait for the user to confirm.Replay MCP cards: every Replay MCP tool result (all 30 tools) is drawn as a card in place of its transcript row, following the replay-mcpui PRD. Each card has:
Cards are parsed from the markdown Claude reads, with no extra server calls. They are tested against outputs recorded from a real session (
hooks/mcp/fixtures.ts, local paths scrubbed). Screenshots render through the relay's new/imageendpoint, which turns Replay's JPEG into a PNG in headless Replay Chromium.Slash command renamed to
/replayio(/replayio,/replayio library,/replayio save <session|latest>).Requirements
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1, plus a kitty-graphics terminal (Ghostty, kitty) for the inline picture. Without them the existing plugin behaves exactly as before.Testing
playwright-cli openattached a player to its own row, frames streamed live, and the recording ended onclose.claude plugin validate,tscandshadcn registry validateall pass.Note
@replayio-app-building/session-recorderdeclares nolicensein its package.json. Please confirm it's fine to commit its bundled build (live/tracer.js) to this public repo.Docs PR with install instructions: replayio/docs#265.
🤖 Generated with Claude Code