The upload route had inline millisecond literals (4000, 12000, 3000,
10000, 500, 1500) scattered through its two attach strategies. Replace
them with named UPLOAD_*_MS constants declared next to the route, and
expose the overall wait budget as an optional `timeout` request field.
- UPLOAD_UI_TIMEOUT_MS (default 12000) backs the request's `timeout`:
the budget to wait for an upload UI (panel input or native chooser).
Non-numeric / <= 0 values fall back to the default.
- The panel-poll window derives from that budget minus
UPLOAD_PANEL_MARGIN_MS, preserving the original 10000/12000 split so a
late native chooser is still caught after polling stops.
- UPLOAD_INPUT/FOCUS/CLICK/REFS/POLL/SETTLE_MS name the per-call bounds.
Defaults reproduce the previous behavior exactly. OpenAPI documents the
new `timeout` field; tests cover timeout resolution and assert the route
carries no bare millisecond literals.
Attach a file to an upload control without going through the native OS
file dialog. Two strategies are tried in order:
1. If an <input type="file"> is already present, call Playwright
setInputFiles on it directly (works for hidden inputs).
2. Otherwise arm a filechooser listener, activate the trigger element
(ref or selector) via keyboard (focus + Enter) with a forced click
as fallback, and setFiles on the resulting chooser. Also polls for
an in-app panel <input type=file> that mounts after activation.
The panel-input path is preferred over the native chooser so a control
that surfaces both (e.g. LinkedIn's media picker) attaches the file
exactly once rather than producing a duplicate.
Paths must be visible inside the container (e.g. a bind-mounted dir);
the route guards with fs.existsSync and returns 400 file_not_found
otherwise. Runs under the same per-user and per-tab locks as the other
interaction routes.
Includes OpenAPI documentation and unit tests (request validation +
source-contract assertions).
POST /pressure/cleanup closes tabs observed idle across multiple checks
while preserving active, locked, queued, and recently-active tabs.
Defaults to dry-run mode. Privacy-safe: responses use hashed identifiers.
Co-authored-by: nicha16 <nicha16@users.noreply.github.com>
Adds endpoint wrapping Playwright's page.setViewportSize() to trigger
real CSS layout reflows. window.resizeTo() is a no-op on non-popup
windows in modern browsers — this is the correct headless primitive.
- Input validation: width/height must be finite numbers in 100..4000
- 150ms settle delay for SPAs (media queries, ResizeObserver)
- Emits tab:viewport plugin event
- Returns { ok, width, height } with rounded values
Tests: 17 unit (validation) + 4 e2e (mobile/desktop/invalid/reflow).
Improved validation over original PR: uses Number.isFinite() to also
reject NaN and Infinity (which bypass typeof+range checks).
Co-authored-by: cunninghambe <cunninghambe@users.noreply.github.com>
Replace all Unicode characters (em-dash, arrows, bullets, box-drawing,
curly quotes, checkmarks, emoji) with ASCII equivalents across all
49 files that ship in the npm package.
The ClawHub scanner generates SKILL.md from package contents and
flagged unicode control characters as a potential prompt-injection
pattern. All shipped files are now pure ASCII.
Note: path-depth markers in reporter.js JSDoc comments changed from
the original bullet (U+2022) to [path] -- using * would create
nested block comment syntax errors.
- Fix BLOCKER: routes with authMiddleware() (traces, storage_state)
became unreachable when both ACCESS_KEY and API_KEY were set to
different values — single Authorization header can't satisfy both.
requireAuth() now accepts access key as alternative superkey.
- Extract inline access-key middleware from server.js into
accessKeyMiddleware() in lib/auth.js for testability and consistency.
- Replace 5 heavyweight integration tests (spawn full server, 120s
timeouts) with 37 unit tests using mock req/res (~80ms total).
Covers: happy path, backward compat, all exemptions, empty bearer,
Basic scheme rejection, double-auth chain simulation, route coverage.
- Add AccessKeyAuth security scheme to OpenAPI spec, regenerate
openapi.json.