Skip to content

feat(m3.3): headless one-shot, extraction, and capture - #30

Merged
ralyodio merged 1 commit into
worktree-m3.1-managed-sessionsfrom
worktree-m3.3-headless-extract
Jul 4, 2026
Merged

feat(m3.3): headless one-shot, extraction, and capture#30
ralyodio merged 1 commit into
worktree-m3.1-managed-sessionsfrom
worktree-m3.3-headless-extract

Conversation

@ralyodio

@ralyodio ralyodio commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Implements M3.3 — headless and extraction. Stacked on the M3.1 branch (which now contains M3.1+M3.2 after #29 merged into it); merges to main behind #28.

tron headless <url> --snapshot|--screenshot out.png|--pdf out.pdf|--extract links
tron extract text|links|forms|tables|main
tron extract '.card' --field title='.title' --field url='a@href'
tron screenshot page.png [--full-page]
tron pdf page.pdf

What's here

  • extract-script.ts — in-page extractors returning deterministic JSON. Relative href/src → absolute; password values omitted; hidden inputs skipped. Built-in modes + custom selector with --field name=sel[@attr].
  • capture.tsPage.captureScreenshot / Page.printToPDF → bytes.
  • page.tsgoto() (navigate + wait for load) and extract().
  • automate-cli.tsextract/screenshot/pdf + a headless one-shot in its own isolated temp TRONBROWSER_DATA (never touches an interactive session), launching/closing via the tron-session engine (TRON_SESSION_BIN), always tearing down — even on failure.
  • install.sh — dispatcher routes the new subcommands to Node and passes TRON_SESSION_BIN.

Acceptance criteria (PRD §22)

  • ✅ One-shot headless (isolated ephemeral profile, torn down).
  • ✅ Extraction returns deterministic JSON.
  • ✅ Screenshots (and PDF) via CDP.
  • ✅ No persistent profile unless requested.

Verification — +20 tests (98 in the package; 78 shown after rebase excludes M3.1/M3.2 desktop suites)

  • Extraction against a real DOM (happy-dom): links (abs URLs), forms (labels/required/password-omitted/hidden-skipped), tables, custom selector+fields, main text.
  • CLI for extract/screenshot/pdf/headless with fakes, including cleanup-on-failure and usage/exit codes.
  • End-to-end over the real HTTP+WebSocket transport for extract and screenshot.
  • Dispatcher routing verified; typecheck/lint clean.

Scope

Requires Node ≥22; PDF requires headless. Full tron headless against a real browser isn't in CI (no Chromium in sandbox) — every seam is covered by layered tests. See docs/headless-and-extraction.md.

🤖 Generated with Claude Code

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

@ralyodio
ralyodio marked this pull request as ready for review July 4, 2026 12:17
@ralyodio
ralyodio merged commit 619e52e into worktree-m3.1-managed-sessions Jul 4, 2026
6 checks passed
@ralyodio
ralyodio deleted the worktree-m3.3-headless-extract branch July 4, 2026 12:17
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