surf-cli 2.17.0 → 2.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,8 @@ description: Control Chrome browser via CLI for testing, automation, and debuggi
7
7
 
8
8
  Control Chrome browser via CLI or Unix socket.
9
9
 
10
+ Ordinary socket-backed CLI commands report top-level host tool-response errors on stderr with a supplied `[code]` on the first line and exit 1. `--json` additionally writes `{error:{code,message,details?}}` on stdout (missing code becomes `"error"`). `--soft-fail` instead keeps the original stderr warning, empty stdout and exit 0, even with `--json`. This does not cover local validation, transport/parser failures or compound-command errors: do not assume every failure produces JSON. Connection failures remain stderr-only and exit 1, including with `--soft-fail`.
11
+
10
12
  ## Native Host / Socket Notes
11
13
 
12
14
  For WSL2 with Windows Chrome, run `surf install <extension-id>` inside WSL2. Surf detects WSL2 and writes the Windows-side native messaging manifest plus a wrapper that launches the WSL host. Use `surf install <extension-id> --target linux` only for Linux browsers running inside WSLg.
@@ -15,6 +17,8 @@ On macOS, Chrome reads the native messaging manifest at `~/Library/Application S
15
17
 
16
18
  If a command reports `Socket connect failed`, run `surf doctor` first, then check the `Attempted socket:` line. Default sockets are `/tmp/surf.sock` on macOS/Linux/WSL2 and `//./pipe/surf` on Windows. If `SURF_SOCKET` is set, the browser-launched host and the shell running `surf` must use the same value.
17
19
 
20
+ For opt-in POSIX group sharing, install with `surf install <extension-id> --socket-mode 660 --socket-group <group>`. The default remains `0600`; mode `660` grants every member of that group full Surf authority, so use a dedicated narrow group. Re-run `surf install` without those flags to clear the wrapper settings. Remote Surf credentials remain the revocable per-client alternative.
21
+
18
22
  ## Remote Surf
19
23
 
20
24
  Remote clients require a per-client credential; Tailnet reachability alone is not authorization. On the POSIX browser host, authorize the client before installing the listener:
@@ -32,9 +36,18 @@ surf --remote 100.101.102.103:4321 \
32
36
  --remote-credential ~/.config/surf/agent-macbook.json \
33
37
  page.read
34
38
 
39
+ # TLS is client-side and requires a TLS-terminating reverse proxy in front of SURF_LISTEN
40
+ surf --remote surf.example.com:443 --remote-tls \
41
+ --remote-tls-ca ~/.config/surf/private-ca.pem \
42
+ --remote-credential ~/.config/surf/agent-macbook.json page.read
43
+
35
44
  surf remote revoke agent-macbook # Run on the browser host
36
45
  ```
37
46
 
47
+ Environment equivalents are `SURF_REMOTE_TLS=1`, `SURF_REMOTE_TLS_CA`, and
48
+ `SURF_REMOTE_TLS_SERVER_NAME`. A custom CA replaces system roots; Ed25519 credentials remain
49
+ mandatory after TLS validation.
50
+
38
51
  Remote paths are client-local by default. `local:./file` is explicit client-local syntax; only `remote:/absolute/path` accesses the browser host directly. Remote transfer supports one upload or ChatGPT/Gemini input and one screenshot, network-export, or Gemini image output. Limits are 256 MiB per file, 512 MiB and 32 files per connection, and 256 KiB decoded chunks. `record`, `aistudio.build`, smoke screenshot directories, directories, and multi-file inputs are not supported remotely. Successful action screenshots and failure `--auto-capture` diagnostics are transferred back to client-local paths.
39
52
 
40
53
  ## CLI Quick Reference
@@ -112,11 +125,13 @@ surf oracle result <job-id> --wait --json
112
125
 
113
126
  `status` reads persisted state without touching Chrome. `result` attempts to harvest the answer and returns the job object with `response` once its state is `captured`. A Ctrl-C during waiting exits with status 130 and prints `Recover with: surf oracle result <id>`. Once the job is `awaiting`, the persisted ChatGPT conversation URL is its durable key, so `surf oracle result <id>` can recover after CLI exit, native-host restart, or Chrome restart by reopening that conversation.
114
127
 
115
- Treat Pro quota as scarce. Oracle never selects Pro effort implicitly; request it with `--effort pro`. ChatGPT model aliases include `instant`, `thinking`, `pro`, `gpt-5.5`, and `gpt-5.6-sol`. Accepted `--effort` values are `light`, `standard`, `extended`, `heavy`, and `pro`. Use `--model gpt-5.6-sol --effort pro` for GPT-5.6 Sol with Pro effort. Requested model and effort selections are read back before submission, and an unverifiable selection fails with `model_verification_failed` instead of silently continuing. Capacity is one non-terminal oracle job. A `capacity` error includes the in-flight job ID; poll that job or wait for it to finish rather than submitting the same consult again.
128
+ Treat Pro quota as scarce. Oracle never selects Pro effort implicitly; request it with `--effort pro`. ChatGPT model aliases include `gpt-6-astra`, `latest`, `gpt-5.6-sol`, and `gpt-5.5`; `latest` is an explicit floating choice, while `gpt-6-astra` must read back as model 6 before submission. Accepted `--effort` values are `instant`, `medium`, `high`, `xhigh`/`extra-high`, and `pro`. Use `--model gpt-6-astra --effort pro` for GPT-6 Astra with Pro effort. Requested model and effort selections are read back before submission, and an unverifiable selection fails with `model_verification_failed` instead of silently continuing. Capacity is one non-terminal oracle job. A `capacity` error includes the in-flight job ID; poll that job or wait for it to finish rather than submitting the same consult again.
129
+
130
+ ChatGPT can hide the model version at lower effort settings. Use `--model latest` if floating model selection is intended; do not retry an unverifiable `gpt-6-astra` request as `latest` without the user's approval.
116
131
 
117
- When loaded as a Pi extension, Surf also registers a `surf-oracle` external-job provider when the runtime exposes that bridge. The provider maps `start`, `status`, `result`, and `reattach` to durable Surf Oracle jobs and returns pi-subagents' external-job contract shape: `providerJobId`, a contract state (`queued`, `running`, `completed`, `failed`), the conversation URL, the captured result text as `output`, and failure code and message. It honors `options.model`, `options.effort`, `options.file`, and `options.github` for starts and follow-ups, so `model: gpt-5.6-sol` plus `effort: pro` selects ChatGPT GPT-5.6 Sol with Pro effort through the browser, while `github: true` requires Chat mode and the connected GitHub tool. `reattach` only harvests an existing job by ID; it never submits the prompt again.
132
+ When loaded as a Pi extension, Surf also registers a `surf-oracle` external-job provider when the runtime exposes that bridge. The provider maps `start`, `status`, `result`, and `reattach` to durable Surf Oracle jobs and returns pi-subagents' external-job contract shape: `providerJobId`, a contract state (`queued`, `running`, `completed`, `failed`), the conversation URL, the captured result text as `output`, and failure code and message. It honors `options.model`, `options.effort`, `options.file`, and `options.github` for starts and follow-ups, so `model: gpt-6-astra` plus `effort: pro` selects ChatGPT GPT-6 Astra with Pro effort through the browser, while `github: true` requires Chat mode and the connected GitHub tool. `reattach` only harvests an existing job by ID; it never submits the prompt again.
118
133
 
119
- When Surf is installed as a Pi package, it exposes an optional `gpt-pro` package agent for `pi-subagents`. That profile uses `runner.type: external-job`, provider `surf-oracle`, `options.model: gpt-5.6-sol`, and `options.effort: pro`. Surf remains useful without Pi or `pi-subagents`.
134
+ When Surf is installed as a Pi package, it exposes an optional `gpt-pro` package agent for `pi-subagents`. That profile uses `runner.type: external-job`, provider `surf-oracle`, `options.model: gpt-6-astra`, and `options.effort: pro`. Surf remains useful without Pi or `pi-subagents`.
120
135
 
121
136
  Context comes from repeatable `--files` globs. Use `--file <path>` for one additional local attachment; `--github` requires Chat mode and a connected GitHub tool. Surf fails closed when a glob matches nothing or a matched file is unreadable, binary, or invalid UTF-8. It also blocks gitignored files and basenames matching `.env*`, `*.pem`, `*.key`, `id_rsa*`, `id_ed25519*`, `*.p12`, `*.pfx`, `credentials*`, or `secrets*`. Use `--allow-sensitive` only after intentionally reviewing those files; it overrides the block rather than redacting content. Context up to 60,000 evidence characters is inserted inline, while larger context becomes one private text attachment. The assembly manifest records each path, byte count, SHA-256, inline or bundle disposition, and deny-list outcome.
122
137
 
@@ -317,6 +332,7 @@ surf page.text # Plain text content only
317
332
  surf page.html --strip-scripts # Rendered HTML without scripts
318
333
  surf page.save --selector "#artifact" --strip-scripts --output page.html # Save one static element
319
334
  surf page.state # Modals, loading state, scroll info
335
+ surf frame.diagnose # Why a selector misses: DOM iframes (incl. open shadow roots) vs extension frames vs CDP tree, with warnings; out-of-process frames need frame.switch, not frame.js
320
336
  ```
321
337
 
322
338
  ### Export Rendered HTML
@@ -394,8 +410,14 @@ surf wait.network # Wait for network idle
394
410
  surf wait.url "/success" # Wait for URL pattern
395
411
  surf wait.dom --stable 100 # Wait for DOM stability
396
412
  surf wait.load # Wait for page load complete
413
+ surf wait.ready --selector ".results" # Ready, or fail fast: login / challenge / not-found / error
414
+ surf wait.ready --url-prefix "https://app.example.com/" --empty-text "No results" # empty vs blocked
415
+ surf wait.ready --accept login --json # Return the negative state instead of failing
416
+ surf page.readiness --json # Classify the current page once (state + evidence)
397
417
  ```
398
418
 
419
+ Typed readiness states replace "the selector never appeared": exit codes carry `page_login`, `page_challenge`, `page_not_found`, `page_error` or `page_timeout`. Detection uses visible UI (a rendered password field, a login route, the page's wording, a URL outside `--url-prefix`), not site selectors.
420
+
399
421
  ## Dialog Handling
400
422
 
401
423
  ```bash