feat(m3.2): page snapshots and ref actions - #29
Conversation
Adds CDP-driven page automation on the M3.1 managed session (PRD M3.2): tron snapshot [--json] [--include-hidden] tron click @e3 tron fill @E4 "hi@example.com" Runtime pivot: snapshots/actions need programmatic CDP over a WebSocket, which the PRD's TS package layout (browser-core/sdk) already assumes. So these subcommands are implemented in TypeScript/Node and the shell `tron` dispatcher delegates to them, attaching to the session via the descriptor's webSocketDebuggerUrl (the M3.1 attach point). packages/browser-core/src/automation: - cdp-client.ts CDP JSON-RPC over Node's global WebSocket (no dependency). - snapshot-script.ts / action-script.ts in-page scripts. Snapshot tags each element with data-tron-ref so a later `tron click @e3` (a separate process) resolves the ref by attribute selector; a vanished element -> STALE_REF. - page.ts evaluate + StaleRefError + compact text formatting. - page-target.ts pick the session's current page target to drive. packages/browser-core/src/automate-cli.ts + automate-bin.ts: the `tron-automate` Node entry (snapshot/click/fill), deps injectable. Packaging: build-release.sh ships browser-core's self-contained dist tree as `automate/` (with a {"type":"module"} marker); the dispatcher runs it via node. Tests (37 new): CDP client over a real WebSocket, the in-page scripts against a real DOM (happy-dom), orchestration + CLI with fakes, and an end-to-end run of the real fetch + CdpClient transport against a mock DevTools server. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
* feat(m3.1): managed browser sessions for the tron CLI Adds CDP-driven managed automation sessions (PRD M3.1) without a new binary or repo — everything routes through the existing `tron` CLI. New commands (via a `tron-session` engine shipped next to the shim): tron browser launch [--headless] [--profile <name|ephemeral>] tron browser status [--json] / tabs [--json] / use <id> / current / close tron open <url> # opens in the managed session, else legacy launch - packages/browser-core/src/automation: portable, unit-tested contract — SessionDescriptor schema, CDP endpoint URL builders, and the target→tab / current-tab mapping the shell engine mirrors (21 vitest cases). - apps/desktop/launcher/tron-session: the running engine. Drives the session over the DevTools HTTP endpoints (curl + python3, both already CLI deps); writes ~/.tronbrowser/automation/session.json recording the port, pid, profile and webSocketDebuggerUrl (the M3.2 attach point). - apps/desktop/launcher/tronbrowser: additive automation-mode flags (--remote-debugging-port, --headless=new) gated on env; the normal `tron <url>` launch path is unchanged. - install.sh dispatcher: `browser` case + `open` prefers a running session and falls back to the classic launch when none exists. - build-release.sh: ship tron-session in the launcher payload. - docs/managed-sessions.md. Launch uses --remote-debugging-port=0 so Chromium picks a free loopback port (read from DevToolsActivePort); the endpoint is 127.0.0.1-only. Headless defaults to an ephemeral profile removed on close. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(m3.1): integration tests for the tron-session engine Regression coverage for the running shell implementation (previously only verified ad-hoc). Drives the real `tron-session` CLI against a Node CDP mock via child_process: launch + live descriptor (incl. webSocketDebuggerUrl), tabs/current, open-as-new-tab, use, already-running guard, headless→ephemeral profile cleanup, close, and the rc-3 no-session `open` fallback signal. Skips gracefully when curl/python3 are unavailable. 8 cases, wired into the existing `pnpm -r test` / vitest suite. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(m3.2): page snapshots and ref actions (tron snapshot/click/fill) (#29) Adds CDP-driven page automation on the M3.1 managed session (PRD M3.2): tron snapshot [--json] [--include-hidden] tron click @e3 tron fill @E4 "hi@example.com" Runtime pivot: snapshots/actions need programmatic CDP over a WebSocket, which the PRD's TS package layout (browser-core/sdk) already assumes. So these subcommands are implemented in TypeScript/Node and the shell `tron` dispatcher delegates to them, attaching to the session via the descriptor's webSocketDebuggerUrl (the M3.1 attach point). packages/browser-core/src/automation: - cdp-client.ts CDP JSON-RPC over Node's global WebSocket (no dependency). - snapshot-script.ts / action-script.ts in-page scripts. Snapshot tags each element with data-tron-ref so a later `tron click @e3` (a separate process) resolves the ref by attribute selector; a vanished element -> STALE_REF. - page.ts evaluate + StaleRefError + compact text formatting. - page-target.ts pick the session's current page target to drive. packages/browser-core/src/automate-cli.ts + automate-bin.ts: the `tron-automate` Node entry (snapshot/click/fill), deps injectable. Packaging: build-release.sh ships browser-core's self-contained dist tree as `automate/` (with a {"type":"module"} marker); the dispatcher runs it via node. Tests (37 new): CDP client over a real WebSocket, the in-page scripts against a real DOM (happy-dom), orchestration + CLI with fakes, and an end-to-end run of the real fetch + CdpClient transport against a mock DevTools server. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * feat(m3.3): headless one-shot, extraction, and capture (#30) Adds one-shot headless automation and structured extraction on the managed session (PRD M3.3), extending the M3.2 Node runtime: tron headless <url> --snapshot|--screenshot <p>|--pdf <p>|--extract <mode> [--json] tron extract <text|links|forms|tables|main|selector> [--field n=sel[@attr]] tron screenshot <path> [--full-page] tron pdf <path> - extract-script.ts: in-page extractors returning deterministic JSON; relative href/src resolve to absolute; password values omitted; hidden inputs skipped. - capture.ts: Page.captureScreenshot / Page.printToPDF -> bytes. - page.ts: goto() (navigate + wait for load) and extract(). - automate-cli.ts: extract/screenshot/pdf commands + a `headless` one-shot that runs in its own isolated temp TRONBROWSER_DATA (never touching an interactive session), launches/closes via the tron-session engine (TRON_SESSION_BIN), and always tears down (profile included), even on failure. - install.sh dispatcher routes the new subcommands to the Node runtime and passes TRON_SESSION_BIN so `tron headless` can manage its one-shot session. Tests (+20): extraction against a real DOM (happy-dom) for links/forms/tables/ custom fields, CLI for extract/screenshot/pdf/headless with injected fakes (incl. cleanup-on-failure), and extract + screenshot over the real HTTP+WS transport. 78 browser-core tests pass; dispatcher routing verified. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Implements M3.2 — snapshots and refs from the M3 PRD. Stacked on #28 (M3.1) — review/merge that first; the base will retarget to
mainonce #28 lands.Runtime pivot (design note)
M3.1's session lifecycle fit in shell+python. Snapshots/actions need programmatic CDP over a WebSocket, which the PRD's TS package layout (
browser-core,sdk) and later deliverables (@tronbrowser/sdk,tron run *.ts, MCP) already assume is Node. So from M3.2 these subcommands are TypeScript/Node, delegated to by the shell dispatcher, attaching to the session via the descriptor'swebSocketDebuggerUrl— the exact attach point M3.1 was built around.What's here (
packages/browser-core/src/automation/)cdp-client.ts— CDP JSON-RPC over Node's globalWebSocket(Node ≥22, no dependency).snapshot-script.ts/action-script.ts— the in-page scripts. Snapshot tags each element withdata-tron-ref, so a latertron click @e3(a separate process) resolves the ref by attribute selector; a vanished element → recoverable STALE_REF (exit 5). Password values are never echoed.page.ts— evaluate +StaleRefError+ compact text formatting.page-target.ts— selects the session's current page target.automate-cli.ts+automate-bin.ts— thetron-automateNode entry; deps injectable for testing.Packaging + wiring
build-release.shships browser-core's self-containeddisttree asautomate/(source has no runtime deps) with a{"type":"module"}marker; thetrondispatcher runs it vianode.install.shdispatcher routessnapshot|click|fill|typeto the Node runtime, with clear errors if Node or the runtime is absent.Acceptance criteria (PRD §22)
@eN).--json).Verification — 37 new tests (95 across the two packages)
CdpError, event dispatch, close-rejects-pending.fetch+CdpClienttransport against a mock DevTools server (this caught a CDP double-nesting detail — the source was correct, the mock wasn't).tronCLI.browser-coretypecheck/lint clean; desktop suite still green.Scope
Requires Node ≥22 + a running managed session. Shadow DOM / cross-origin iframes deferred. See
docs/snapshots-and-refs.md.🤖 Generated with Claude Code