Commit Graph

1029 Commits

Author SHA1 Message Date
Tommy D. Rossi 95ed4a1f04 release: playwriter@0.3.1 playwriter@0.3.1 2026-06-13 17:40:55 +02:00
Tommy D. Rossi b3cb99e37e Remove obsolete downlevelIteration option
Remove downlevelIteration from the shared TypeScript base config because modern tsgolint rejects the option before it can build a TS program.

TypeScript typecheck still passes after removing the option. lintcn now gets past tsconfig parsing and reports regular source lint findings instead of failing on configuration.

Session: ses_13e63a376ffeFVwrB0h7PF3D5h
2026-06-13 17:34:47 +02:00
Tommy D. Rossi c1112964e6 Enable Playwriter auto pages by default
Auto page creation is now the default policy instead of per-client plumbing. MCP and CLI both create an initial blank tab when no Playwriter-enabled pages are available, which prevents a connected extension with zero targets from failing before the agent can act.

PLAYWRITER_AUTO_ENABLE=false is the single opt-out. The relay and executor both consult the same shouldAutoEnablePlaywriter helper so Target.setAutoAttach auto-creation and executor fallback page creation stay aligned.

This removes the earlier CLI-only autoEnable request flow from session creation and CDP URLs because auto-enable is no longer a special CLI capability.

Session: ses_143538111ffe2cKnv4TqZ7ZoqQ
2026-06-13 17:32:07 +02:00
Tommy D. Rossi 1088381e9f release: playwriter@0.3.0
Release Playwriter 0.3.0 with the pending user-facing changes since 0.2.0.

Included release notes:

1. Add `sinceLastCall` to `getLatestLogs()` so agents can inspect only new browser logs after each action.
2. Rotate `~/.playwriter/cdp.jsonl` automatically to prevent unbounded disk growth.
3. Include page runtime errors and related frame target logs in `getLatestLogs({ page })`.
4. Let CLI-created sessions auto-open initial extension tabs when MCP owns the shared relay.
5. Send bearer tokens on remote extension status checks.
6. Handle concurrent relay startup races without surfacing `EADDRINUSE` crashes.
7. Improve browser names in multi-browser session selection.
8. Document `getLatestLogs()` as the preferred page diagnostics API for agents.

Fixes #75
Fixes #85
Fixes #92

Session: ses_unknown
playwriter@0.3.0
2026-06-13 17:21:11 +02:00
Tommy D. Rossi 036d19c17b chore: update website dependencies
Update the website dependency set before publishing Playwriter so the workspace starts from a clean tree.

- update @holocron.so/vite to 0.16.0
- update spiceflow RSC build to 1.26.0-rsc.1
- update wrangler and workerd through the lockfile
- allow workerd as an approved built dependency for pnpm

Session: ses_unknown
2026-06-13 17:20:09 +02:00
Tommy D. Rossi a7af83b7c0 Fix CLI auto-enable when MCP owns relay
CLI sessions requested auto-enable only by setting PLAYWRITER_AUTO_ENABLE when they spawned the relay process. That fails when MCP already owns the shared relay, because the CLI reuses the existing process and no per-session intent reaches the CDP connection.

Send an explicit autoEnable flag when creating CLI extension sessions, carry it through the generated CDP URL, and let the relay auto-create an initial tab for that specific Playwright client even if the process env was not set at startup.

This keeps MCP behavior unchanged while making CLI sessions resilient after the last enabled tab is closed.

Session: ses_143538111ffe2cKnv4TqZ7ZoqQ
2026-06-13 17:17:46 +02:00
Tommy D. Rossi 2bd7c3725b Improve extension browser name detection
Use full user-agent client hints when the browser exposes them so the extension can report more specific Chromium-family names before falling back to low-entropy brands and the user agent string.

This keeps detection inside the browser instead of guessing from local filesystem installs. If a browser only exposes the generic Google Chrome brand, Playwriter keeps showing Chrome.

Bump the extension manifest to 0.0.95 and add a playwriter patch changeset for the browser list improvement.

Session: ses_143f600f9ffe0ftfzwvYK56gQV
extension@0.0.95
2026-06-12 16:24:27 +02:00
Tommy D. Rossi dade84e7bd Address oracle review: atomic rotation, flush(), input validation, changeset
Oracle review fixes for CDP log rotation:
- Wrap rotate() in try/catch so failures do not break the write queue
- Use temp file + fs.rename for atomic rotation (no corruption on crash)
- Add resolvePositiveInt() to validate maxEntries from env/options
- Remove redundant `rotating` flag (queue serialization is sufficient)
- Expose flush() on CdpLogger so tests can await the queue
- Rewrite tests to use flush() instead of setTimeout (14ms vs 1.3s)
- Assert exact retained entry IDs via inline snapshot
- Add test for atomic rename (no .tmp file left behind)
- Add patch changeset for playwriter package

Session: ses_1545c4395ffeRR6V3ko2KSiVHT
2026-06-09 11:16:50 +02:00
Tommy D. Rossi d6176d484d Add CDP log rotation to prevent unbounded cdp.jsonl growth (#92)
The cdp.jsonl file grew without bound during long relay sessions,
causing disk exhaustion (5.7 GB reported in issue #92).

Added rotation logic to createCdpLogger:
- New `maxEntries` option (default 10,000, env PLAYWRITER_CDP_LOG_MAX_ENTRIES)
- When line count exceeds maxEntries, file is trimmed to keep the last half
- Rotation is chained on the async write queue, safe with concurrent writes
- File oscillates between maxEntries/2 and maxEntries lines

Added unit tests:
- Rotation triggers correctly at threshold
- No rotation when under limit
- Multiple rotations work with small maxEntries

Fixes #92

Session: ses_1545c4395ffeRR6V3ko2KSiVHT
2026-06-09 11:12:52 +02:00
Tommy D. Rossi 0ac72e189d fix clearAllLogs stale cursor bug, add changeset for sinceLastCall
clearAllLogs() now also clears pageLogCursor so subsequent sinceLastCall
calls do not see stale cursors that would cause them to return empty arrays.

Added changeset describing the sinceLastCall option and persistent logs
behavior change.

Session: ses_154681872ffeqje784ZqFUspy5
2026-06-09 11:12:01 +02:00
Tommy D. Rossi cbf0d6ce35 add sinceLastCall option to getLatestLogs, persist logs across navigation
getLatestLogs() now supports a sinceLastCall option that returns only new
console logs and page errors since the previous call. The first call returns
all buffered logs including pre-existing ones. This lets agents check for
errors after every action without seeing duplicates.

Browser console logs no longer clear on page navigation (framenavigated).
Logs persist across gotos and reloads so errors from page transitions are
never missed. The existing 5000-entry-per-page cap prevents unbounded growth.
When entries are shifted out at the cap, per-page cursors are decremented to
stay in sync.

Updated skill.md interaction feedback loop to instruct agents to always call
getLatestLogs({ page: state.page, sinceLastCall: true }) after every action
(goto, click, submit) to catch hydration errors, failed network requests,
and runtime exceptions.

Updated tests: two assertions that expected logs to be cleared on reload now
expect logs to persist (lines 831 and 978).

Session: ses_154681872ffeqje784ZqFUspy5
2026-06-09 11:07:41 +02:00
Tommy D. Rossi 7235248b4d block process.exit() and process.chdir() in sandbox
process.exit() would kill the relay server, affecting all sessions.
process.chdir() would change the relay cwd, affecting all sessions.

Both now throw descriptive errors instead.
Also simplified the Proxy: always use it (no conditional on sessionCwd),
falling back to real process.cwd() when sessionCwd is null.

Session: ses_16234add5ffeXGeXpSdt8Jttuc
2026-06-06 19:06:45 +02:00
Tommy D. Rossi 27728bb8bc expose process global in sandbox with correct session cwd
- Add `process` to usefulGlobals so it is available in the VM sandbox
- Override `process.cwd()` via Proxy to return the session cwd
  (where `playwriter session new` was invoked) instead of the
  relay server cwd
- Document `process` in the skill.md context variables section
- Document sandboxed fs write restrictions (only session cwd,
  /tmp, os.tmpdir() are writable)
- Document unavailable globals: __dirname, __filename, import

Session: ses_16234add5ffeXGeXpSdt8Jttuc
2026-06-06 19:05:07 +02:00
Tommy D. Rossi e39122bc5b fix: handle EADDRINUSE race on first relay startup (#75)
When two CLI/MCP commands start simultaneously with no relay running,
both detect the relay is down and both spawn one. The second process
crashes with EADDRINUSE on port 19988.

Three changes fix this:

1. cdp-relay.ts: switch from serve() to createAdaptorServer() so we
   inject WebSocket upgrade handlers before binding, then explicitly
   call server.listen() with once(listening)/once(error) handlers.
   EADDRINUSE is now a catchable promise rejection instead of an
   unhandled async error event.

2. start-relay-server.ts: catch EADDRINUSE in the spawned relay
   process. Poll /version for up to 2 seconds to check if another
   relay won the race. If yes, exit cleanly (code 0) instead of
   crashing with a scary error in the logs.

3. relay-client.ts: add module-level promise dedup so concurrent
   ensureRelayServer() calls within the same process only spawn once.
   When a process is found on the port but /version does not respond,
   poll /version for 2 seconds before killing it (prevents accidentally
   killing a relay that is still starting during a race).

Shared waitForRelayVersion() helper extracted to avoid duplicating the
poll loop in two places.

Session: ses_16355a286ffekJzHDlexPGKG56
2026-06-06 13:40:58 +02:00
Tommy D. Rossi 25dc876686 document getLatestLogs for browser log inspection
Update the Playwriter skill to tell agents to use getLatestLogs when inspecting browser logs instead of manually attaching page.on('console') listeners.

Manual console listeners only see future events, which can miss logs emitted during page startup or React hydration. The docs now explain that getLatestLogs captures browser console logs and pageerror entries from page start, and the examples now show page-scoped and hydration-error lookups.

Also add a playwriter patch changeset for the docs change.

Verification:
- pnpm typecheck

Known local check limitations:
- lintcn still reports pre-existing unrelated errors in aria-snapshot.ts, cdp-relay.ts, mcp.ts, and wait-for-page-load.ts

Session: ses_1913ab7ecffeHGoDq9rqCrGbCK
2026-05-28 15:49:16 +02:00
Tommy D. Rossi d9226b66cf fix getLatestLogs page error capture
Capture uncaught page runtime errors in getLatestLogs by listening to Playwright pageerror events and storing browser logs by Page object instead of target id.

This fixes page-scoped log lookup for pages where useful runtime errors surface outside the main page target, including React hydration failures on unframer.co.

Also add a regression assertion for pageerror entries and a playwriter patch changeset.

Verification:
- pnpm typecheck
- manual playwriter CLI check on https://unframer.co/ returns [pageerror] Minified React error #418

Known local check limitations:
- targeted Vitest could not launch because the local Playwright Chromium binary is missing
- lintcn still reports pre-existing unrelated errors in other files

Session: ses_1913ab7ecffeHGoDq9rqCrGbCK
2026-05-28 15:41:06 +02:00
Tommy D. Rossi 4e84428694 zip extension contents directly, rename to playwriter-VERSION.zip
Release script now zips the contents of dist-release/ instead of the folder
itself, so unzipping produces the extension files at the top level. Zip is
named playwriter-VERSION.zip (e.g. playwriter-0.0.94.zip) instead of
extension.zip. Updated AGENTS.md instructions to match.

Session: ses_197aa7c50ffeN6KEKgB6WOZPOZ
2026-05-27 12:01:31 +02:00
Tommy D. Rossi 9d837c0a8c update website deps and simplify hero image markup
- bump @holocron.so/vite ^0.10.1 -> ^0.15.0
- bump spiceflow 1.25.3-rsc.0 -> 1.26.0-rsc.0
- bump wrangler ^4.92.0 -> ^4.94.0
- bump vite ^8.0.12 -> ^8.0.13 in playwright submodule
- remove Bleed/Frame wrappers around hero screenshot in index.mdx
- lockfile updates (ws 8.21.0, goke 6.12.2)

Session: ses_197224bbeffeBKeRiLJeqwd1YX
2026-05-27 11:57:35 +02:00
Tommy D. Rossi 1c45f65503 Update docs.json 2026-05-27 11:53:06 +02:00
Tommy D. Rossi 9ba0d462d7 extension release notes should use changelog content, not install instructions
Session: ses_197aa7c50ffeN6KEKgB6WOZPOZ
2026-05-27 09:56:30 +02:00
Tommy D. Rossi 0265afabb1 add GitHub release instructions for CLI and extension to AGENTS.md
Agents should create a CLI GitHub release (--latest) after every npm publish,
and an extension release (--latest=false) with extension.zip attached whenever
extension/ code changed. Extension releases use --latest=false so they do not
override the CLI as the "Latest" GitHub release.

Session: ses_197aa7c50ffeN6KEKgB6WOZPOZ
2026-05-27 09:51:57 +02:00
Tommy D. Rossi e9339a3ecc fix: send auth token on remote status check routes
When using `--token` with a remote `--host`, the CLI and executor
status check fetches (`/extensions/status`, `/extension/status`) were
not sending the bearer token. The host validation middleware rejects
non-localhost requests without a valid token, so remote `session new`
and `session list` would silently fail with "no connected browsers".

**cli.ts**: `fetchExtensionsStatus` now accepts `{ host, token }` and
passes auth headers via `buildAuthHeaders` to both status endpoints.

**executor.ts**: `checkExtensionStatus` reads `token` from
`this.cdpConfig` (falling back to `PLAYWRITER_TOKEN` env) and attaches
`Authorization: Bearer` header to all status fetch calls.

`relay-client.ts` left unchanged since those functions are hardcoded
to `127.0.0.1` (local-only, always passes host validation).

Closes #91
Fixes #85

Session: ses_1b4c572a4ffev2Dct63TjK77gJ
extension@0.0.94
2026-05-21 17:53:18 +02:00
Tommy D. Rossi 613f6b99d9 updates 2026-05-19 16:11:58 +02:00
Tommy D. Rossi bc0e044095 updates 2026-05-19 16:07:16 +02:00
Tommy D. Rossi 70f8deac7b Add Host header validation to prevent DNS rebinding attacks
DNS rebinding lets an attacker serve a page from http://evil.com:19988,
then rebind the DNS to 127.0.0.1. The browser treats subsequent requests
as same-origin, bypassing Sec-Fetch-Site, CORS preflight, and
Content-Type enforcement. This gives full access to privileged HTTP
routes like /cli/execute without any existing defense catching it.

The new global middleware rejects requests whose Host header hostname is
not localhost, 127.0.0.1, [::1], or ::1. Requests carrying a valid
bearer/query token bypass the check so remote clients still work.

The Host parser handles IPv6 brackets, bare ::1, case-insensitive
hostnames, and port suffixes via indexOf instead of a fragile regex.

Unit tests use raw http module (Node fetch forbids overriding Host) to
verify evil.com is rejected and all localhost variants pass, including
uppercase LOCALHOST.

Session: ses_1bfec4b08ffeL3NJunw0EC9plq
2026-05-19 14:03:02 +02:00
Tommy D. Rossi 668d97eb00 release: playwriter@0.2.0
Merges all changes since 0.1.0 (last published npm version):

- New -f/--file flag for executing JS from files
- React component inspection for pinned elements
- Performance profiling guide resource
- Shell tab completions via goke
- Security: token required on all requests regardless of source
- --token works on every remote subcommand
- Fixed Next.js webpack layer prefixes in React source paths
- Skill docs require absolute paths for saved artifacts

Session: ses_1bff6e68fffe5Ls42bfN8RUyVp
playwriter@0.2.0
2026-05-19 13:46:21 +02:00
Tommy D. Rossi c49d3e5d60 Update index.mdx 2026-05-18 19:34:17 +02:00
Tommy D. Rossi 6a3f2c481c Update docs.json 2026-05-18 19:34:15 +02:00
Tommy D. Rossi 7eafb25c3c Update index.mdx 2026-05-18 18:54:32 +02:00
Tommy D. Rossi 614087dab6 Update docs.json 2026-05-18 18:51:49 +02:00
Tommy D. Rossi 23fe8be8ef updates 2026-05-18 18:50:12 +02:00
Tommy D. Rossi 5e247bce25 updates 2026-05-18 17:37:04 +02:00
Tommy D. Rossi aa1183c23d feat(extension): update pin copy toast to guide users toward agent prompt usage
The old toast just said "Copied pin #N" which gave no hint about what to do next. Now it says "Copied playwriter element reference, use it in your agent prompt" so users know to paste it into their AI agent.

Bump extension to 0.0.94.

Session: ses_1d03be05affeS58tMdQDs6GMbj
2026-05-16 09:52:49 +02:00
Tommy D. Rossi 014fd520ce docs(skill): add -f/--file execute-from-file section
Add "Execute from file" subsection to skill.md documenting the -f flag
for executing JavaScript from a file instead of inline -e code.

Session: ses_1d0419706ffelv53Gc4OrfwZ4L
2026-05-16 09:48:52 +02:00
Tommy D. Rossi a77f5ad861 chore(deps): bump vite ^8.0.3 to ^8.0.12 and update lockfile
Update vite in root and extension packages from ^8.0.3 to ^8.0.12.

Lockfile reflects all transitive dependency updates from this session:
goke 6.12.1, @holocron.so/vite 0.8.0, dompurify 3.4.3, katex 0.16.46,
and various @csstools patches.
2026-05-16 09:45:37 +02:00
Tommy D. Rossi a9f8a0770f feat(website): upgrade @holocron.so/vite to 0.8.0 and update docs
Upgrade @holocron.so/vite from ^0.7.1 to ^0.8.0.

Use the new `<Logo>` component in the hero section instead of a plain
`<h1>`, and switch `<img>` to the framework `<Image>` component.

Add icon fields to the GitHub and Releases anchors in docs.json
(github, log). Fix docs.json indentation.

Add website/styles.css with Tailwind `@source` directive for the
new holocron vite plugin version.
2026-05-16 09:45:33 +02:00
Tommy D. Rossi d02fa5df17 feat(cli): add -f/--file flag, shell completions, and unknown command errors
Add `-f, --file <path>` option so users can execute JavaScript from a file
instead of inline `-e` strings. The two flags are mutually exclusive.

Enable `cli.completions()` from goke for shell tab completion support.

Change `cli.parse()` to `await cli.parse()` so async command actions
properly propagate errors and exit codes.

Add tests for unknown command and unknown subcommand error handling,
verifying they exit with code 1 and print helpful messages.

Bump goke from ^6.6.0 to ^6.12.1 which includes the completions API
and improved error messages for unknown commands.
2026-05-16 09:45:25 +02:00
Tommy D. Rossi 4de435ef21 update playwright submodule pointer: vite ^8.0.12
Session: ses_1da6d3925ffeK4qAOv03OUyIfl
2026-05-14 11:20:37 +02:00
Tommy D. Rossi d49afbb845 update pnpm-lock.yaml after website migration
Lockfile reflects:
- removed holocron local package and its deps
- added @holocron.so/vite and transitive deps (mermaid, holocron components, etc.)
- updated spiceflow 1.18.0-rsc.22 -> 1.25.1-rsc.0
- updated vite 8.0.3 -> 8.0.12 (rolldown 1.0.0-rc.12 -> 1.0.0)
- updated react 19.2.3 -> 19.2.6
- various transitive dep bumps

Session: ses_1da6d3925ffeK4qAOv03OUyIfl
2026-05-14 10:35:42 +02:00
Tommy D. Rossi 9e94ada7d7 migrate website to @holocron.so/vite
Replaced the custom editorial page (spiceflow + tailwind + safe-mdx + prism)
with the published @holocron.so/vite docs framework.

Changes:
- vite.config.ts: replaced spiceflow/tailwind/tsconfigPaths plugins with holocron()
- package.json: swapped deps (removed safe-mdx, prismjs, tailwind, sharp, image-size,
  orama; added @holocron.so/vite and zod). Updated spiceflow to 1.25.1-rsc.0
- Added docs.json holocron config (logo, nav, colors, footer)
- Added src/index.mdx as the single docs page (Hero, Install, Quick start, etc.)
- tsconfig.json: simplified (removed paths, allowJs, allowArbitraryExtensions)
- .gitignore: added /dist, removed .react-router

Session: ses_1da6d3925ffeK4qAOv03OUyIfl
2026-05-14 10:35:35 +02:00
Tommy D. Rossi e2dab3d8e8 remove local holocron/ package
The holocron docs framework has been published as @holocron.so/vite on npm.
The local package is no longer needed in this repo.

Removed files:
- holocron/src/ (vite plugin, components, styles, config, sync, mdx processing)
- holocron/AGENTS.md
- holocron/package.json, tsconfig.json, schema.json

Session: ses_1da6d3925ffeK4qAOv03OUyIfl
2026-05-14 10:35:23 +02:00
Tommy D. Rossi bcd1e25ea2 docs: document changesets workflow for agents
Replace the old changelog instructions with the repo changesets workflow so future package changes add .changeset entries instead of editing generated CHANGELOG.md files or manually bumping public package versions.

Keep the Chrome extension manifest bump requirement separate because extension releases are not driven by npm changesets, and add a .changeset/readme.md so agents can quickly see what belongs in the folder.

Move the pending playwriter typecheck emit change into a changeset and revert the manual package version bump from the prior commit, leaving version updates to the publish flow.

Session: ses_1f763e4ecffenZcbrWQbx0Oh5F
2026-05-09 08:38:06 +02:00
Tommy D. Rossi a3ce2146ff fix: keep playwriter typecheck emitting dist
Run the playwriter package typecheck script through plain tsc instead of tsc --noEmit so local validation keeps compiled dist files up to date.

Bump the package version to 0.1.7 so the local dist-backed shim reports the updated package version after rebuilding.

Session: ses_1f763e4ecffenZcbrWQbx0Oh5F
2026-05-08 19:43:31 +02:00
Tommy D. Rossi d1346e7ca4 docs: add profano CPU profiling tips to performance resource
Mention .cpuprofile recording via CDP Profiler.* commands and
profano CLI for inspecting hot functions when vitals alone are
not enough to diagnose performance issues.

Session: ses_208943d84ffenqdbjxK0cO0iak
2026-05-05 11:39:01 +02:00
Tommy D. Rossi 7195359b22 fix: strip Next.js webpack layer prefixes from React source paths
bippy.normalizeFileName strips "/app-pages-browser/" but not the
parenthesized form "/(app-pages-browser)/" that Next.js webpack
actually uses in source maps. Added cleanFileName/cleanName that
runs after normalizeFileName and strips any /(layer-name)/ prefix
using regex, plus trailing "./".

Covers all Next.js webpack layer names: (app-pages-browser), (ssr),
(rsc), (action-browser), (pages-dir-browser), (pages-dir-edge),
(pages-dir-node).

Applied in both:
- Extension context menu handler (background.ts)
- MCP react-source.ts (getReactSource + getReactComponentInfo)

Also applied oracle review fixes:
- userGesture: true on clipboard Runtime.evaluate calls to prevent
  NotAllowedError when page loses focus after context menu
- Defensive fileName null check before building clipboard text

Session: ses_208943d84ffenqdbjxK0cO0iak
2026-05-05 11:38:36 +02:00
Tommy D. Rossi d0c93e0f3a feat(extension): add "Copy React Component Source Path" right-click menu item
New context menu item that copies the React component source file path
to clipboard when right-clicking an element on a React page.

Uses bippy (React fiber introspection library) to walk the fiber tree
from the right-clicked DOM element up to the nearest composite component
with source location info. Tries getSource() first (direct __source prop
from JSX transform), then falls back to getOwnerStack() for builds with
source maps.

Copies "path/to/file.tsx:42" format to clipboard on success (green flash),
shows red flash if the element is not part of a React app or no source
maps are available.

Also refactored all inline JS strings in the context menu handlers to use
string-dedent with descriptive variable names for syntax highlighting.

extension@0.0.93

Session: ses_208943d84ffenqdbjxK0cO0iak
2026-05-05 11:24:28 +02:00
Tommy D. Rossi 10790c7392 auth: drop loopback bypass, attach token from env in in-process callers
Reviewer flagged the loopback-bypass added in 0.1.5 as a full auth
bypass under the recommended remote-access topology: tunnel agents
(traforo, ngrok, cloudflared) run as local processes and forward
public traffic to localhost:19988, so every public request reaches
the relay from 127.0.0.1. The bypass made `/cli/execute` (RCE),
`/cli/session/*`, `/recording/*` (file writes via outputPath), and
`/mcp-log` callable by anyone with the public tunnel URL.

Fix
---
1. cdp-relay.ts: privilegedRouteMiddleware now requires the token on
   every request, regardless of source. Loopback bypass removed.
2. cli.ts (`serve` action): exports `process.env.PLAYWRITER_TOKEN` at
   startup so in-process callers can attach Authorization: Bearer ...
   when calling the relay's own privileged endpoints.
3. screen-recording.ts: new `recordingHeaders()` helper reads
   PLAYWRITER_TOKEN from env and attaches the Bearer header to all
   four /recording/* calls (start, stop, status, cancel). Mirrors
   what mcp.ts already does for /mcp-log.
4. cli.ts (`executeCode`): refactored the inline header-build into
   the shared `buildAuthHeaders` helper so the six /cli/* fetch
   sites stay in sync.
5. connect-cdp-demo.ts: replaced the hardcoded 'secret_token'
   fallback with a hard error so the demo can never accidentally be
   the source of a leaked credential warning.

Bumps playwriter to 0.1.6 + CHANGELOG entry. Adds a MEMORY.md note
so the next person doesn't re-introduce the bypass.

Session: ses_20d25dcc7ffeJhVK7aC8Zh7OkW
2026-05-04 17:09:28 +02:00
Tommy D. Rossi db3280d8e7 Regenerate AGENTS.md with changesets workflow
Replaces old CHANGELOG.md instructions with changesets. Also picks up
latest shared snippet updates from agentsdotmd@1.1.5.

Session: ses_20d092d48ffey0lmjedA7ZMTed
2026-05-04 15:21:26 +02:00
Tommy D. Rossi 3d6f2d4239 auth: thread token through every remote CLI command + protect /mcp-log
Builds on Ivan Leo's auth-header pass with the missing pieces needed to
actually run `playwriter serve --token` end to end against a remote relay.

Fixes
-----
1. `--token` (or PLAYWRITER_TOKEN) now plumbed through every remote
   subcommand: `session new/list/delete/reset` and `browser list`. Until
   now only `playwriter -e` sent the Bearer header, so against a token-
   protected relay every other subcommand returned 401.
2. In-process `ExecutorManager` carries `token` in its `cdpConfig`, so the
   executor's own `chromium.connectOverCDP(ws://127.0.0.1:19988/cdp/<id>)`
   call passes the relay's own auth check.
3. `/mcp-log` is now under `privilegedRouteMiddleware`. Previously open,
   so any reachable client could spam the log file.
4. `mcp.ts` `sendLogToRelayServer` sends `Authorization: Bearer …` when
   `PLAYWRITER_TOKEN` is set.
5. Loopback connections (127.0.0.1, ::1, ::ffff:127.0.0.1) bypass the
   token check on `/cli/*`, `/recording/*`, and `/mcp-log`. They can only
   originate from in-process executor code which already runs downstream
   of an authenticated `/cdp/*` WebSocket, so re-checking the token would
   mean smuggling it into every internal helper for no real security
   gain. Resolves the broken `/recording/*` calls from
   `screen-recording.ts`.
6. New `connect-cdp-demo.ts` script: minimal example showing an external
   Playwright client connecting through `/cdp/<id>?token=<token>` over a
   tunnel.

Bumps `playwriter` to 0.1.5 and updates CHANGELOG.

Co-authored-by: Ivan Leo <ivanleomk@gmail.com>

Session: ses_20d25dcc7ffeJhVK7aC8Zh7OkW
2026-05-04 14:10:42 +02:00
Tommy D. Rossi ae136e91ec fix: copy pinned element command directly
Remove the natural-language wrapper around pinned element clipboard text so toolbar and context-menu pins copy a shell-ready playwriter command. This keeps the copied text compact while still delegating DOM and React inspection to inspectPinnedElement.

Session: ses_221fdd7c5ffexkyCmOtfmgwjoI
2026-04-30 17:26:21 +02:00