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