Skip to content

feat(m3.2): page snapshots and ref actions - #29

Merged
ralyodio merged 1 commit into
worktree-m3.1-managed-sessionsfrom
worktree-m3.2-snapshots
Jul 4, 2026
Merged

feat(m3.2): page snapshots and ref actions#29
ralyodio merged 1 commit into
worktree-m3.1-managed-sessionsfrom
worktree-m3.2-snapshots

Conversation

@ralyodio

@ralyodio ralyodio commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Implements M3.2 — snapshots and refs from the M3 PRD. Stacked on #28 (M3.1) — review/merge that first; the base will retarget to main once #28 lands.

tron snapshot [--json] [--include-hidden]
tron click @e3
tron fill @e4 "hi@example.com"

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's webSocketDebuggerUrl — 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 global WebSocket (Node ≥22, no dependency).
  • snapshot-script.ts / action-script.ts — the 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 → 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 — the tron-automate Node entry; deps injectable for testing.

Packaging + wiring

  • build-release.sh ships browser-core's self-contained dist tree as automate/ (source has no runtime deps) with a {"type":"module"} marker; the tron dispatcher runs it via node.
  • install.sh dispatcher routes snapshot|click|fill|type to the Node runtime, with clear errors if Node or the runtime is absent.

Acceptance criteria (PRD §22)

  • ✅ Stable refs for visible interactive elements (document order, @eN).
  • ✅ Click/fill by ref work on test pages.
  • ✅ Stale refs → recoverable error.
  • ✅ Snapshot output compact enough for LLM use (text + --json).

Verification — 37 new tests (95 across the two packages)

  • CDP client over a real WebSocket (dependency-free mock WS server): id-matching, CdpError, event dispatch, close-rejects-pending.
  • In-page scripts against a real DOM (happy-dom): refs/roles/names, password redaction, visibility filtering, focus, click, fill+events, stale ref.
  • Orchestration + CLI with injected fakes; exit codes (no-session=4, stale=5, usage=2).
  • End-to-end: the CLI's real fetch + CdpClient transport against a mock DevTools server (this caught a CDP double-nesting detail — the source was correct, the mock wasn't).
  • Shipped entry smoke-tested standalone; dispatcher routing verified via the extracted tron CLI. browser-core typecheck/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

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>
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown

vu1nz Security Review

0 finding(s) in PR #?

No security issues found.

@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedhappy-dom@​20.10.6661008895100

View full report

@socket-security

Copy link
Copy Markdown

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.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm happy-dom is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: packages/browser-core/package.jsonnpm/happy-dom@20.10.6

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/happy-dom@20.10.6. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@ralyodio
ralyodio marked this pull request as ready for review July 4, 2026 11:59
@ralyodio
ralyodio merged commit 8929357 into worktree-m3.1-managed-sessions Jul 4, 2026
7 checks passed
@ralyodio
ralyodio deleted the worktree-m3.2-snapshots branch July 4, 2026 11:59
ralyodio added a commit that referenced this pull request Jul 4, 2026
* 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant