surf-cli 2.5.2 → 2.7.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.
@@ -0,0 +1,575 @@
1
+ ---
2
+ name: surf
3
+ description: Control Chrome browser via CLI for testing, automation, and debugging. Use when the user needs browser automation, screenshots, form filling, page inspection, network/CPU emulation, DevTools streaming, or AI queries via ChatGPT/Gemini/Perplexity/Grok/AI Studio.
4
+ ---
5
+
6
+ # Surf Browser Automation
7
+
8
+ Control Chrome browser via CLI or Unix socket.
9
+
10
+ ## CLI Quick Reference
11
+
12
+ ```bash
13
+ surf --help # Full help
14
+ surf <group> # Group help (tab, scroll, page, wait, dialog, emulate, form, perf, ai)
15
+ surf --help-full # All commands
16
+ surf --find <term> # Search tools
17
+ surf --help-topic <topic> # Topic guide (refs, semantic, frames, devices, windows)
18
+ ```
19
+
20
+ ## Core Workflow
21
+
22
+ ```bash
23
+ # 1. Navigate to page
24
+ surf navigate "https://example.com"
25
+
26
+ # 2. Read page to get element refs
27
+ surf page.read
28
+
29
+ # 3. Click by ref or coordinates
30
+ surf click --ref "e1"
31
+ surf click --x 100 --y 200
32
+
33
+ # 4. Type text
34
+ surf type --text "hello"
35
+
36
+ # 5. Screenshot
37
+ surf screenshot --output /tmp/shot.png
38
+ ```
39
+
40
+ ## AI Assistants (No API Keys)
41
+
42
+ Query AI models using your browser's logged-in session. Must be logged into the respective service in Chrome.
43
+
44
+ ### ChatGPT
45
+ ```bash
46
+ surf chatgpt "explain this code"
47
+ surf chatgpt "summarize" --with-page # Include current page context
48
+ surf chatgpt "review" --model gpt-4o # Specify model
49
+ surf chatgpt "analyze" --file document.pdf # With file attachment
50
+ ```
51
+
52
+ ### Gemini
53
+ ```bash
54
+ surf gemini "explain quantum computing"
55
+ surf gemini "summarize" --with-page # Include page context
56
+ surf gemini "analyze" --file data.csv # Attach file
57
+ surf gemini "a robot surfing" --generate-image /tmp/robot.png
58
+ surf gemini "add sunglasses" --edit-image photo.jpg --output out.jpg
59
+ surf gemini "summarize" --youtube "https://youtube.com/..."
60
+ surf gemini "hello" --model gemini-2.5-flash # Models: gemini-3-pro (default), gemini-2.5-pro, gemini-2.5-flash
61
+ surf gemini "wide banner" --generate-image /tmp/banner.png --aspect-ratio 16:9
62
+ ```
63
+
64
+ ### Perplexity
65
+ ```bash
66
+ surf perplexity "what is quantum computing"
67
+ surf perplexity "explain this page" --with-page # Include page context
68
+ surf perplexity "deep dive" --mode research # Research mode (Pro)
69
+ surf perplexity "latest news" --model sonar # Model selection (Pro)
70
+ ```
71
+
72
+ ### Grok (via x.com - requires X.com login in Chrome)
73
+ ```bash
74
+ surf grok "what are the latest AI trends on X" # Search X posts
75
+ surf grok "analyze @username recent activity" # Profile analysis
76
+ surf grok "summarize this page" --with-page # Include page context
77
+ surf grok "find viral AI posts" --deep-search # DeepSearch mode
78
+ surf grok "quick question" --model fast # Models: auto, fast, expert, thinking (default)
79
+ ```
80
+
81
+ **Grok Validation & Troubleshooting:**
82
+ ```bash
83
+ # Validate Grok UI and check available models (no query sent)
84
+ surf grok --validate
85
+
86
+ # If models changed, save discovered models to surf.json config
87
+ surf grok --validate --save-models
88
+ ```
89
+
90
+ ### AI Studio (via aistudio.google.com - requires Google login in Chrome)
91
+ ```bash
92
+ surf aistudio "explain quantum computing"
93
+ surf aistudio "redteam this" --with-page # Include current page context
94
+ surf aistudio "quick answer" --model gemini-3-flash-preview # Model selection
95
+ surf aistudio "analyze" --timeout 600 # Custom timeout (default: 300s)
96
+ ```
97
+
98
+ **Why AI Studio over Gemini?** AI Studio gives access to less restricted Gemini models. For Gemini 3 Pro the difference can be significant with certain prompts. Downside: aggressive per-day rate limits on Pro and Flash models.
99
+
100
+ **Model selection is best-effort:** Pass any AI Studio model id (e.g. `gemini-3.1-pro-preview`, `gemini-3-flash-preview`, `gemini-flash-lite-latest`). If the model isn't found, AI Studio uses whatever model was last selected in the UI.
101
+
102
+ ### AI Studio App Builder
103
+ ```bash
104
+ surf aistudio.build "build a portfolio site"
105
+ surf aistudio.build "todo app" --model gemini-3.1-pro-preview # Model override
106
+ surf aistudio.build "crm dashboard" --output ./out # Extract zip to directory
107
+ surf aistudio.build "game" --keep-open --timeout 600 # Keep tab open, 10min timeout
108
+ ```
109
+
110
+ Automates AI Studio's App Builder at `aistudio.google.com/apps`. Types your prompt, clicks Build, waits for completion, downloads the generated zip, and optionally extracts it.
111
+
112
+ - `--output <dir>` extracts the zip to a directory
113
+ - `--model <id>` overrides the model in Advanced Settings
114
+ - `--timeout <seconds>` build timeout (default: 600s)
115
+ - `--keep-open` leaves the AI Studio tab open after completion
116
+
117
+ Returns `zipPath`, `extractedPath`, `model`, `buildDuration`, and `tookMs`.
118
+
119
+ ### AI Tool Troubleshooting
120
+
121
+ When AI queries fail, check these common issues:
122
+
123
+ 1. **Not logged in**: The error "login required" means you need to log into the service in Chrome (chatgpt.com, gemini.google.com, perplexity.ai, x.com, or aistudio.google.com)
124
+ 2. **Model selection failed**: The UI may have changed. Run `surf grok --validate` to check
125
+ 3. **Response timeout**: Thinking models (ChatGPT o1, Grok thinking) can take 45+ seconds. AI Studio builds can take several minutes.
126
+ 4. **Element not found**: The service's UI changed. Check for surf-cli updates
127
+
128
+ **Debugging workflow for agents:**
129
+ ```bash
130
+ # 1. Check if the service is accessible and UI is valid
131
+ surf grok --validate
132
+
133
+ # 2. If models mismatch, update the local settings
134
+ surf grok --validate --save-models
135
+
136
+ # 3. Retry with explicit model name from validation output
137
+ surf grok "query" --model <model-from-validation>
138
+
139
+ # 4. If still failing, try with longer timeout
140
+ surf grok "query" --timeout 600
141
+ ```
142
+
143
+ ## Tab Management
144
+
145
+ ```bash
146
+ surf tab.list
147
+ surf tab.new "https://google.com"
148
+ surf tab.switch 12345
149
+ surf tab.close 12345
150
+ surf tab.reload # Reload current tab
151
+
152
+ # Named tabs (aliases)
153
+ surf tab.name myapp # Name current tab
154
+ surf tab.switch myapp # Switch by name
155
+ surf tab.named # List named tabs
156
+ surf tab.unname myapp # Remove name
157
+
158
+ # Tab groups
159
+ surf tab.group # Create/add to tab group
160
+ surf tab.ungroup # Remove from group
161
+ surf tab.groups # List all tab groups
162
+ ```
163
+
164
+ ## Window Management
165
+
166
+ ```bash
167
+ surf window.list # List all windows
168
+ surf window.list --tabs # Include tab details
169
+ surf window.new # New window
170
+ surf window.new --url "https://example.com" # New window with URL
171
+ surf window.new --incognito # New incognito window
172
+ surf window.new --unfocused # Don't focus new window
173
+ surf window.focus 12345 # Focus window by ID
174
+ surf window.close 12345 # Close window
175
+ surf window.resize --id 123 --width 1920 --height 1080
176
+ surf window.resize --id 123 --state maximized # States: normal, minimized, maximized, fullscreen
177
+ ```
178
+
179
+ **Window isolation for agents:**
180
+ ```bash
181
+ # Create isolated window for agent work
182
+ surf window.new "https://example.com"
183
+ # Returns window ID, use with subsequent commands:
184
+ surf --window-id 123 tab.list
185
+ surf --window-id 123 go "https://other.com"
186
+ ```
187
+
188
+ ## Input Methods
189
+
190
+ ```bash
191
+ # CDP method (real events) - default
192
+ surf type --text "hello"
193
+ surf click --x 100 --y 200
194
+
195
+ # JS method (DOM manipulation) - for contenteditable
196
+ surf type --text "hello" --selector "#input" --method js
197
+
198
+ # Keys
199
+ surf key Enter
200
+ surf key "cmd+a"
201
+ surf key.repeat --key Tab --count 5 # Repeat key presses
202
+
203
+ # Hover and drag
204
+ surf hover --ref e5
205
+ surf drag --from-x 100 --from-y 100 --to-x 200 --to-y 200
206
+ ```
207
+
208
+ ## Page Inspection
209
+
210
+ ```bash
211
+ surf page.read # Accessibility tree with refs + page text
212
+ surf page.read --no-text # Interactive elements only (no text content)
213
+ surf page.read --ref e5 # Get specific element details
214
+ surf page.read --depth 3 # Limit tree depth
215
+ surf page.read --compact # Minimal output for LLM efficiency
216
+ surf page.text # Plain text content only
217
+ surf page.state # Modals, loading state, scroll info
218
+ ```
219
+
220
+ ## Semantic Element Location
221
+
222
+ Find and act on elements by role, text, or label instead of refs:
223
+
224
+ ```bash
225
+ # Find by ARIA role
226
+ surf locate.role button --name "Submit" --action click
227
+ surf locate.role textbox --name "Email" --action fill --value "test@example.com"
228
+ surf locate.role link --all # Return all matches
229
+
230
+ # Find by text content
231
+ surf locate.text "Sign In" --action click
232
+ surf locate.text "Accept" --exact --action click
233
+
234
+ # Find form field by label
235
+ surf locate.label "Username" --action fill --value "john"
236
+ surf locate.label "Password" --action fill --value "secret"
237
+ ```
238
+
239
+ **Actions:** `click`, `fill`, `hover`, `text` (get text content)
240
+
241
+ ## Text Search
242
+
243
+ ```bash
244
+ surf search "login" # Find text in page
245
+ surf search "Error" --case-sensitive # Case-sensitive
246
+ surf search "button" --limit 5 # Limit results
247
+ surf find "login" # Alias for search
248
+ ```
249
+
250
+ ## Element Inspection
251
+
252
+ ```bash
253
+ surf element.styles e5 # Get computed styles by ref
254
+ surf element.styles ".card" # Or by CSS selector
255
+ # Returns: font, color, background, border, padding, bounding box
256
+ ```
257
+
258
+ ## Scrolling
259
+
260
+ ```bash
261
+ surf scroll.bottom
262
+ surf scroll.top
263
+ surf scroll.to --y 500 # Scroll to Y position
264
+ surf scroll.to --ref e5 # Scroll element into view
265
+ surf scroll.by --y 200 # Scroll by amount
266
+ surf scroll.info # Get scroll position
267
+ ```
268
+
269
+ ## Waiting
270
+
271
+ ```bash
272
+ surf wait 2 # Wait 2 seconds
273
+ surf wait.element ".loaded" # Wait for element
274
+ surf wait.network # Wait for network idle
275
+ surf wait.url "/success" # Wait for URL pattern
276
+ surf wait.dom --stable 100 # Wait for DOM stability
277
+ surf wait.load # Wait for page load complete
278
+ ```
279
+
280
+ ## Dialog Handling
281
+
282
+ ```bash
283
+ surf dialog.info # Get current dialog type/message
284
+ surf dialog.accept # Accept (OK)
285
+ surf dialog.accept --text "response" # Accept prompt with text
286
+ surf dialog.dismiss # Dismiss (Cancel)
287
+ ```
288
+
289
+ ## Device/Network Emulation
290
+
291
+ ```bash
292
+ # Network throttling
293
+ surf emulate.network slow-3g # Presets: slow-3g, fast-3g, 4g, offline
294
+ surf emulate.network reset # Disable throttling
295
+
296
+ # CPU throttling
297
+ surf emulate.cpu 4 # 4x slower
298
+ surf emulate.cpu 1 # Reset
299
+
300
+ # Device emulation (19 presets)
301
+ surf emulate.device "iPhone 14"
302
+ surf emulate.device "Pixel 7"
303
+ surf emulate.device --list # List available devices
304
+
305
+ # Custom viewport
306
+ surf emulate.viewport --width 1280 --height 720
307
+ surf emulate.touch --enable # Enable touch emulation
308
+
309
+ # Geolocation
310
+ surf emulate.geo --lat 37.7749 --lon -122.4194
311
+ surf emulate.geo --clear
312
+ ```
313
+
314
+ ## Form Automation
315
+
316
+ ```bash
317
+ surf page.read # Get element refs first
318
+
319
+ # Fill by ref
320
+ surf form.fill --data '[{"ref":"e1","value":"John"},{"ref":"e2","value":"john@example.com"}]'
321
+
322
+ # Checkboxes: true/false
323
+ surf form.fill --data '[{"ref":"e7","value":true}]'
324
+
325
+ # Dropdown selection
326
+ surf select e5 "Option A" # By value (default)
327
+ surf select e5 "Option A" "Option B" # Multi-select
328
+ surf select e5 --by label "Display Text" # By visible label
329
+ surf select e5 --by index 2 # By index (0-based)
330
+ ```
331
+
332
+ ## File Upload
333
+
334
+ ```bash
335
+ surf upload --ref e5 --files "/path/to/file.txt"
336
+ surf upload --ref e5 --files "/path/file1.txt,/path/file2.txt"
337
+ ```
338
+
339
+ ## Iframe Handling
340
+
341
+ ```bash
342
+ surf frame.list # List frames with IDs
343
+ surf frame.switch "FRAME_ID" # Switch to iframe context
344
+ surf frame.main # Return to main frame
345
+ surf frame.js --id "FRAME_ID" --code "return document.title"
346
+
347
+ # After frame.switch, subsequent commands target that frame:
348
+ surf frame.switch "iframe-1"
349
+ surf page.read # Reads iframe content
350
+ surf click e5 # Clicks in iframe
351
+ surf frame.main # Back to main page
352
+ ```
353
+
354
+ ## Network Inspection
355
+
356
+ ```bash
357
+ surf network # List captured requests
358
+ surf network --stream # Real-time network events
359
+ surf network.get --id "req-123" # Full request details
360
+ surf network.body --id "req-123" # Get response body
361
+ surf network.curl --id "req-123" # Generate curl command
362
+ surf network.origins # List origins with stats
363
+ surf network.stats # Capture statistics
364
+ surf network.export # Export all requests
365
+ surf network.clear # Clear captured requests
366
+ ```
367
+
368
+ ## Console
369
+
370
+ ```bash
371
+ surf console # Get console messages
372
+ surf console --stream # Real-time console
373
+ surf console --stream --level error # Errors only
374
+ ```
375
+
376
+ ## JavaScript Execution
377
+
378
+ ```bash
379
+ surf js "return document.title"
380
+ surf js "document.querySelector('.btn').click()"
381
+ ```
382
+
383
+ ## Performance
384
+
385
+ ```bash
386
+ surf perf.metrics # Current metrics snapshot
387
+ surf perf.start # Start trace
388
+ surf perf.stop # Stop and get results
389
+ ```
390
+
391
+ ## Screenshots
392
+
393
+ ```bash
394
+ surf screenshot # Auto-saves to /tmp/surf-snap-*.png
395
+ surf screenshot --output /tmp/shot.png # Save to specific file
396
+ surf screenshot --selector ".card" # Element only
397
+ surf screenshot --full-page # Full page scroll capture
398
+ surf screenshot --no-save # Return base64 only, don't save file
399
+ ```
400
+
401
+ ## Zoom
402
+
403
+ ```bash
404
+ surf zoom # Get current zoom level
405
+ surf zoom 1.5 # Set zoom to 150%
406
+ surf zoom 1 # Reset to 100%
407
+ ```
408
+
409
+ ## Cookies & Storage
410
+
411
+ ```bash
412
+ surf cookie.list # List cookies for current page
413
+ surf cookie.list --domain .google.com
414
+ surf cookie.set --name "token" --value "abc123"
415
+ surf cookie.get --name "token"
416
+ surf cookie.clear # Clear all cookies
417
+ ```
418
+
419
+ ## History & Bookmarks
420
+
421
+ ```bash
422
+ surf history --query "github" --max 20
423
+ surf bookmarks --query "docs"
424
+ surf bookmark.add --url "https://..." --title "My Bookmark"
425
+ surf bookmark.remove
426
+ ```
427
+
428
+ ## Health Checks & Smoke Tests
429
+
430
+ ```bash
431
+ surf health --url "http://localhost:3000"
432
+ surf smoke --urls "http://localhost:3000" "http://localhost:3000/about"
433
+ surf smoke --urls "..." --screenshot /tmp/smoke
434
+ ```
435
+
436
+ ## Workflows
437
+
438
+ Execute multi-step browser automation as a single command with smart auto-waits.
439
+
440
+ ### Inline Workflows
441
+
442
+ ```bash
443
+ # Pipe-separated commands
444
+ surf do 'go "https://example.com" | click e5 | screenshot'
445
+
446
+ # Multi-step login flow
447
+ surf do 'go "https://example.com/login" | type "user@example.com" --selector "#email" | type "pass" --selector "#password" | click --selector "button[type=submit]"'
448
+
449
+ # Validate without executing
450
+ surf do 'go "url" | click e5' --dry-run
451
+ ```
452
+
453
+ ### Named Workflows
454
+
455
+ Save workflows as JSON files in `~/.surf/workflows/` (user) or `./.surf/workflows/` (project):
456
+
457
+ ```bash
458
+ # List available workflows
459
+ surf workflow.list
460
+
461
+ # Show workflow details
462
+ surf workflow.info my-workflow
463
+
464
+ # Run by name with arguments
465
+ surf do my-workflow --email "user@example.com" --password "secret"
466
+
467
+ # Validate workflow file
468
+ surf workflow.validate workflow.json
469
+ ```
470
+
471
+ ### Workflow JSON Format
472
+
473
+ ```json
474
+ {
475
+ "name": "Login Flow",
476
+ "description": "Automate login process",
477
+ "args": {
478
+ "email": { "required": true },
479
+ "password": { "required": true },
480
+ "url": { "default": "https://example.com/login" }
481
+ },
482
+ "steps": [
483
+ { "tool": "navigate", "args": { "url": "%{url}" } },
484
+ { "tool": "type", "args": { "text": "%{email}", "selector": "input[name=email]" } },
485
+ { "tool": "type", "args": { "text": "%{password}", "selector": "input[name=password]" } },
486
+ { "tool": "click", "args": { "selector": "button[type=submit]" } },
487
+ { "tool": "screenshot", "args": {}, "as": "result" }
488
+ ]
489
+ }
490
+ ```
491
+
492
+ ### Loops and Step Outputs
493
+
494
+ ```json
495
+ {
496
+ "steps": [
497
+ // Capture step output for later use
498
+ { "tool": "js", "args": { "code": "return [1,2,3]" }, "as": "items" },
499
+
500
+ // Fixed iterations
501
+ { "repeat": 5, "steps": [
502
+ { "tool": "click", "args": { "ref": "e5" } }
503
+ ]},
504
+
505
+ // Iterate over array
506
+ { "each": "%{items}", "as": "item", "steps": [
507
+ { "tool": "js", "args": { "code": "console.log('%{item}')" } }
508
+ ]},
509
+
510
+ // Repeat until condition
511
+ { "repeat": 20, "until": { "tool": "js", "args": { "code": "return done" } }, "steps": [...] }
512
+ ]
513
+ }
514
+ ```
515
+
516
+ ### Workflow Options
517
+
518
+ ```bash
519
+ --file, -f <path> # Load from JSON file
520
+ --dry-run # Parse and validate without executing
521
+ --on-error stop|continue # Error handling (default: stop)
522
+ --step-delay <ms> # Delay between steps (default: 100, 0 to disable)
523
+ --no-auto-wait # Disable automatic waits
524
+ --json # Structured JSON output
525
+ ```
526
+
527
+ **Auto-waits:** Commands automatically wait for completion:
528
+ - Navigation (`go`, `back`, `forward`) → waits for page load
529
+ - Clicks, key presses, form fills → waits for DOM stability
530
+ - Tab switches → waits for tab to load
531
+
532
+ **Why use `do`?** Instead of 6-8 separate CLI calls with LLM orchestration between each, a workflow executes deterministically. Faster, cheaper, and more reliable.
533
+
534
+ ## Error Diagnostics
535
+
536
+ ```bash
537
+ # Auto-capture screenshot + console on failure
538
+ surf wait.element ".missing" --auto-capture --timeout 2000
539
+ # Saves to /tmp/surf-error-*.png
540
+ ```
541
+
542
+ ## Common Options
543
+
544
+ ```bash
545
+ --tab-id <id> # Target specific tab
546
+ --window-id <id> # Target specific window
547
+ --json # Raw JSON output
548
+ --auto-capture # Screenshot + console on error
549
+ --timeout <ms> # Override default timeout
550
+ ```
551
+
552
+ ## Tips
553
+
554
+ 1. **First CDP operation is slow** (~5-8s) - debugger attachment overhead, subsequent calls fast
555
+ 2. **Use refs from page.read** for reliable element targeting over CSS selectors
556
+ 3. **JS method for contenteditable** - Modern editors (ChatGPT, Claude, Notion) need `--method js`
557
+ 4. **Named tabs for workflows** - `tab.name app` then `tab.switch app`
558
+ 5. **Auto-capture for debugging** - `--auto-capture` saves diagnostics on failure
559
+ 6. **AI tools use browser session** - Must be logged into the service (ChatGPT, Gemini, Perplexity, Grok, AI Studio), no API keys needed
560
+ 7. **Grok validation** - Run `surf grok --validate` if queries fail to check UI changes
561
+ 8. **Long timeouts for thinking models** - ChatGPT o1, Grok thinking can take 60+ seconds. AI Studio builds default to 600s.
562
+ 9. **AI Studio for unrestricted Gemini** - `surf aistudio` gives less filtered responses than `surf gemini` for the same models
563
+ 10. **Use `surf do` for multi-step tasks** - Reduces token overhead and improves reliability
564
+ 11. **Dry-run workflows first** - `surf do '...' --dry-run` validates without executing
565
+ 12. **Window isolation** - Use `window.new` + `--window-id` to keep agent work separate from your browsing
566
+ 13. **Semantic locators** - `locate.role`, `locate.text`, `locate.label` for more robust element finding
567
+ 14. **Frame context** - Use `frame.switch` before interacting with iframe content
568
+
569
+ ## Socket API
570
+
571
+ For programmatic access:
572
+
573
+ ```bash
574
+ echo '{"type":"tool_request","method":"execute_tool","params":{"tool":"tab.list","args":{}},"id":"1"}' | nc -U /tmp/surf.sock
575
+ ```