@ulpi/browse 2.3.4 → 2.4.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.
- package/README.md +8 -2
- package/dist/browse.cjs +2889 -1265
- package/dist/lib.mjs +29504 -0
- package/dist/types/a11y.d.ts +32 -0
- package/dist/types/a11y.d.ts.map +1 -0
- package/dist/types/app/android/bridge.d.ts +41 -0
- package/dist/types/app/android/bridge.d.ts.map +1 -0
- package/dist/types/app/android/emulator.d.ts +32 -0
- package/dist/types/app/android/emulator.d.ts.map +1 -0
- package/dist/types/app/android/manager.d.ts +62 -0
- package/dist/types/app/android/manager.d.ts.map +1 -0
- package/dist/types/app/android/protocol.d.ts +162 -0
- package/dist/types/app/android/protocol.d.ts.map +1 -0
- package/dist/types/app/android/sim-service.d.ts +33 -0
- package/dist/types/app/android/sim-service.d.ts.map +1 -0
- package/dist/types/app/index.d.ts +15 -0
- package/dist/types/app/index.d.ts.map +1 -0
- package/dist/types/app/ios/bridge.d.ts +53 -0
- package/dist/types/app/ios/bridge.d.ts.map +1 -0
- package/dist/types/app/ios/controller.d.ts +131 -0
- package/dist/types/app/ios/controller.d.ts.map +1 -0
- package/dist/types/app/ios/manager.d.ts +96 -0
- package/dist/types/app/ios/manager.d.ts.map +1 -0
- package/dist/types/app/ios/protocol.d.ts +122 -0
- package/dist/types/app/ios/protocol.d.ts.map +1 -0
- package/dist/types/app/ios/sim-service.d.ts +37 -0
- package/dist/types/app/ios/sim-service.d.ts.map +1 -0
- package/dist/types/app/macos/bridge.d.ts +22 -0
- package/dist/types/app/macos/bridge.d.ts.map +1 -0
- package/dist/types/app/manager.d.ts +50 -0
- package/dist/types/app/manager.d.ts.map +1 -0
- package/dist/types/app/normalize.d.ts +27 -0
- package/dist/types/app/normalize.d.ts.map +1 -0
- package/dist/types/app/resolve-app.d.ts +31 -0
- package/dist/types/app/resolve-app.d.ts.map +1 -0
- package/dist/types/app/types.d.ts +77 -0
- package/dist/types/app/types.d.ts.map +1 -0
- package/dist/types/automation/action-context.d.ts +110 -0
- package/dist/types/automation/action-context.d.ts.map +1 -0
- package/dist/types/automation/command.d.ts +138 -0
- package/dist/types/automation/command.d.ts.map +1 -0
- package/dist/types/automation/events.d.ts +72 -0
- package/dist/types/automation/events.d.ts.map +1 -0
- package/dist/types/automation/executor.d.ts +39 -0
- package/dist/types/automation/executor.d.ts.map +1 -0
- package/dist/types/automation/index.d.ts +11 -0
- package/dist/types/automation/index.d.ts.map +1 -0
- package/dist/types/automation/registry.d.ts +38 -0
- package/dist/types/automation/registry.d.ts.map +1 -0
- package/dist/types/automation/rules.d.ts +52 -0
- package/dist/types/automation/rules.d.ts.map +1 -0
- package/dist/types/automation/target.d.ts +76 -0
- package/dist/types/automation/target.d.ts.map +1 -0
- package/dist/types/browser/consent.d.ts +13 -0
- package/dist/types/browser/consent.d.ts.map +1 -0
- package/dist/types/browser/cookie-import.d.ts +94 -0
- package/dist/types/browser/cookie-import.d.ts.map +1 -0
- package/dist/types/browser/detection.d.ts +22 -0
- package/dist/types/browser/detection.d.ts.map +1 -0
- package/dist/types/browser/emulation.d.ts +30 -0
- package/dist/types/browser/emulation.d.ts.map +1 -0
- package/dist/types/browser/events.d.ts +19 -0
- package/dist/types/browser/events.d.ts.map +1 -0
- package/dist/types/browser/index.d.ts +17 -0
- package/dist/types/browser/index.d.ts.map +1 -0
- package/dist/types/browser/macros.d.ts +9 -0
- package/dist/types/browser/macros.d.ts.map +1 -0
- package/dist/types/browser/manager.d.ts +272 -0
- package/dist/types/browser/manager.d.ts.map +1 -0
- package/dist/types/browser/png-compare.d.ts +36 -0
- package/dist/types/browser/png-compare.d.ts.map +1 -0
- package/dist/types/browser/profiles.d.ts +29 -0
- package/dist/types/browser/profiles.d.ts.map +1 -0
- package/dist/types/browser/react-devtools.d.ts +75 -0
- package/dist/types/browser/react-devtools.d.ts.map +1 -0
- package/dist/types/browser/readiness.d.ts +19 -0
- package/dist/types/browser/readiness.d.ts.map +1 -0
- package/dist/types/browser/refs.d.ts +70 -0
- package/dist/types/browser/refs.d.ts.map +1 -0
- package/dist/types/browser/serp.d.ts +16 -0
- package/dist/types/browser/serp.d.ts.map +1 -0
- package/dist/types/browser/snapshot-window.d.ts +31 -0
- package/dist/types/browser/snapshot-window.d.ts.map +1 -0
- package/dist/types/browser/snapshot.d.ts +41 -0
- package/dist/types/browser/snapshot.d.ts.map +1 -0
- package/dist/types/browser/tabs.d.ts +67 -0
- package/dist/types/browser/tabs.d.ts.map +1 -0
- package/dist/types/browser/target.d.ts +106 -0
- package/dist/types/browser/target.d.ts.map +1 -0
- package/dist/types/browser/youtube.d.ts +26 -0
- package/dist/types/browser/youtube.d.ts.map +1 -0
- package/dist/types/cli.d.ts +14 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/cloud/auth.d.ts +80 -0
- package/dist/types/cloud/auth.d.ts.map +1 -0
- package/dist/types/cloud/docker.d.ts +76 -0
- package/dist/types/cloud/docker.d.ts.map +1 -0
- package/dist/types/cloud/firecracker.d.ts +142 -0
- package/dist/types/cloud/firecracker.d.ts.map +1 -0
- package/dist/types/cloud/golden-snapshot.d.ts +122 -0
- package/dist/types/cloud/golden-snapshot.d.ts.map +1 -0
- package/dist/types/cloud/index.d.ts +26 -0
- package/dist/types/cloud/index.d.ts.map +1 -0
- package/dist/types/cloud/orchestrator-interface.d.ts +63 -0
- package/dist/types/cloud/orchestrator-interface.d.ts.map +1 -0
- package/dist/types/cloud/orchestrator.d.ts +58 -0
- package/dist/types/cloud/orchestrator.d.ts.map +1 -0
- package/dist/types/cloud/proxy.d.ts +34 -0
- package/dist/types/cloud/proxy.d.ts.map +1 -0
- package/dist/types/cloud/reaper.d.ts +49 -0
- package/dist/types/cloud/reaper.d.ts.map +1 -0
- package/dist/types/cloud/server.d.ts +19 -0
- package/dist/types/cloud/server.d.ts.map +1 -0
- package/dist/types/cloud/sessions.d.ts +85 -0
- package/dist/types/cloud/sessions.d.ts.map +1 -0
- package/dist/types/cloud/vm-orchestrator.d.ts +133 -0
- package/dist/types/cloud/vm-orchestrator.d.ts.map +1 -0
- package/dist/types/cloud/vm-warm-pool.d.ts +104 -0
- package/dist/types/cloud/vm-warm-pool.d.ts.map +1 -0
- package/dist/types/cloud/warm-pool.d.ts +85 -0
- package/dist/types/cloud/warm-pool.d.ts.map +1 -0
- package/dist/types/cloud/ws.d.ts +61 -0
- package/dist/types/cloud/ws.d.ts.map +1 -0
- package/dist/types/commands/meta/auth.d.ts +6 -0
- package/dist/types/commands/meta/auth.d.ts.map +1 -0
- package/dist/types/commands/meta/flows.d.ts +15 -0
- package/dist/types/commands/meta/flows.d.ts.map +1 -0
- package/dist/types/commands/meta/index.d.ts +14 -0
- package/dist/types/commands/meta/index.d.ts.map +1 -0
- package/dist/types/commands/meta/inspection.d.ts +7 -0
- package/dist/types/commands/meta/inspection.d.ts.map +1 -0
- package/dist/types/commands/meta/profile.d.ts +11 -0
- package/dist/types/commands/meta/profile.d.ts.map +1 -0
- package/dist/types/commands/meta/recording.d.ts +7 -0
- package/dist/types/commands/meta/recording.d.ts.map +1 -0
- package/dist/types/commands/meta/screenshots.d.ts +7 -0
- package/dist/types/commands/meta/screenshots.d.ts.map +1 -0
- package/dist/types/commands/meta/sessions.d.ts +7 -0
- package/dist/types/commands/meta/sessions.d.ts.map +1 -0
- package/dist/types/commands/meta/sim.d.ts +10 -0
- package/dist/types/commands/meta/sim.d.ts.map +1 -0
- package/dist/types/commands/meta/system.d.ts +8 -0
- package/dist/types/commands/meta/system.d.ts.map +1 -0
- package/dist/types/commands/meta/tabs.d.ts +6 -0
- package/dist/types/commands/meta/tabs.d.ts.map +1 -0
- package/dist/types/commands/meta/youtube.d.ts +7 -0
- package/dist/types/commands/meta/youtube.d.ts.map +1 -0
- package/dist/types/commands/read.d.ts +16 -0
- package/dist/types/commands/read.d.ts.map +1 -0
- package/dist/types/commands/write.d.ts +17 -0
- package/dist/types/commands/write.d.ts.map +1 -0
- package/dist/types/config.d.ts +101 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/constants.d.ts +36 -0
- package/dist/types/constants.d.ts.map +1 -0
- package/dist/types/detection/frameworks.d.ts +27 -0
- package/dist/types/detection/frameworks.d.ts.map +1 -0
- package/dist/types/detection/index.d.ts +64 -0
- package/dist/types/detection/index.d.ts.map +1 -0
- package/dist/types/detection/infrastructure.d.ts +82 -0
- package/dist/types/detection/infrastructure.d.ts.map +1 -0
- package/dist/types/detection/saas.d.ts +39 -0
- package/dist/types/detection/saas.d.ts.map +1 -0
- package/dist/types/enable.d.ts +10 -0
- package/dist/types/enable.d.ts.map +1 -0
- package/dist/types/engine/chrome.d.ts +45 -0
- package/dist/types/engine/chrome.d.ts.map +1 -0
- package/dist/types/engine/index.d.ts +9 -0
- package/dist/types/engine/index.d.ts.map +1 -0
- package/dist/types/engine/providers.d.ts +36 -0
- package/dist/types/engine/providers.d.ts.map +1 -0
- package/dist/types/engine/resolver.d.ts +36 -0
- package/dist/types/engine/resolver.d.ts.map +1 -0
- package/dist/types/expect.d.ts +68 -0
- package/dist/types/expect.d.ts.map +1 -0
- package/dist/types/export/index.d.ts +8 -0
- package/dist/types/export/index.d.ts.map +1 -0
- package/dist/types/export/record.d.ts +28 -0
- package/dist/types/export/record.d.ts.map +1 -0
- package/dist/types/export/replay.d.ts +9 -0
- package/dist/types/export/replay.d.ts.map +1 -0
- package/dist/types/flow-parser.d.ts +32 -0
- package/dist/types/flow-parser.d.ts.map +1 -0
- package/dist/types/install-skill.d.ts +8 -0
- package/dist/types/install-skill.d.ts.map +1 -0
- package/dist/types/lib.d.ts +27 -0
- package/dist/types/lib.d.ts.map +1 -0
- package/dist/types/mcp/index.d.ts +10 -0
- package/dist/types/mcp/index.d.ts.map +1 -0
- package/dist/types/mcp/server.d.ts +9 -0
- package/dist/types/mcp/server.d.ts.map +1 -0
- package/dist/types/mcp/tools/index.d.ts +36 -0
- package/dist/types/mcp/tools/index.d.ts.map +1 -0
- package/dist/types/network/buffers.d.ts +53 -0
- package/dist/types/network/buffers.d.ts.map +1 -0
- package/dist/types/network/har.d.ts +10 -0
- package/dist/types/network/har.d.ts.map +1 -0
- package/dist/types/network/index.d.ts +6 -0
- package/dist/types/network/index.d.ts.map +1 -0
- package/dist/types/perf-audit/diff.d.ts +43 -0
- package/dist/types/perf-audit/diff.d.ts.map +1 -0
- package/dist/types/perf-audit/dom-analysis.d.ts +74 -0
- package/dist/types/perf-audit/dom-analysis.d.ts.map +1 -0
- package/dist/types/perf-audit/formatter.d.ts +34 -0
- package/dist/types/perf-audit/formatter.d.ts.map +1 -0
- package/dist/types/perf-audit/index.d.ts +128 -0
- package/dist/types/perf-audit/index.d.ts.map +1 -0
- package/dist/types/perf-audit/persist.d.ts +40 -0
- package/dist/types/perf-audit/persist.d.ts.map +1 -0
- package/dist/types/perf-audit/recommendations.d.ts +18 -0
- package/dist/types/perf-audit/recommendations.d.ts.map +1 -0
- package/dist/types/perf-audit/resource-analyzer.d.ts +46 -0
- package/dist/types/perf-audit/resource-analyzer.d.ts.map +1 -0
- package/dist/types/perf-audit/web-vitals.d.ts +73 -0
- package/dist/types/perf-audit/web-vitals.d.ts.map +1 -0
- package/dist/types/proxy/index.d.ts +6 -0
- package/dist/types/proxy/index.d.ts.map +1 -0
- package/dist/types/proxy/pool.d.ts +44 -0
- package/dist/types/proxy/pool.d.ts.map +1 -0
- package/dist/types/proxy/providers.d.ts +32 -0
- package/dist/types/proxy/providers.d.ts.map +1 -0
- package/dist/types/sdk/client.d.ts +37 -0
- package/dist/types/sdk/client.d.ts.map +1 -0
- package/dist/types/sdk/index.d.ts +17 -0
- package/dist/types/sdk/index.d.ts.map +1 -0
- package/dist/types/sdk/session.d.ts +95 -0
- package/dist/types/sdk/session.d.ts.map +1 -0
- package/dist/types/sdk/transports/cloud.d.ts +89 -0
- package/dist/types/sdk/transports/cloud.d.ts.map +1 -0
- package/dist/types/sdk/transports/index.d.ts +3 -0
- package/dist/types/sdk/transports/index.d.ts.map +1 -0
- package/dist/types/sdk/transports/local.d.ts +56 -0
- package/dist/types/sdk/transports/local.d.ts.map +1 -0
- package/dist/types/sdk.d.ts +35 -0
- package/dist/types/sdk.d.ts.map +1 -0
- package/dist/types/security/auth-vault.d.ts +32 -0
- package/dist/types/security/auth-vault.d.ts.map +1 -0
- package/dist/types/security/domain-filter.d.ts +31 -0
- package/dist/types/security/domain-filter.d.ts.map +1 -0
- package/dist/types/security/index.d.ts +10 -0
- package/dist/types/security/index.d.ts.map +1 -0
- package/dist/types/security/policy.d.ts +20 -0
- package/dist/types/security/policy.d.ts.map +1 -0
- package/dist/types/security/sanitize.d.ts +6 -0
- package/dist/types/security/sanitize.d.ts.map +1 -0
- package/dist/types/server.d.ts +13 -0
- package/dist/types/server.d.ts.map +1 -0
- package/dist/types/session/concurrency.d.ts +28 -0
- package/dist/types/session/concurrency.d.ts.map +1 -0
- package/dist/types/session/encryption.d.ts +8 -0
- package/dist/types/session/encryption.d.ts.map +1 -0
- package/dist/types/session/index.d.ts +7 -0
- package/dist/types/session/index.d.ts.map +1 -0
- package/dist/types/session/manager.d.ts +110 -0
- package/dist/types/session/manager.d.ts.map +1 -0
- package/dist/types/session/persist.d.ts +87 -0
- package/dist/types/session/persist.d.ts.map +1 -0
- package/dist/types/session/tab-lock.d.ts +26 -0
- package/dist/types/session/tab-lock.d.ts.map +1 -0
- package/dist/types/session/target-factory.d.ts +88 -0
- package/dist/types/session/target-factory.d.ts.map +1 -0
- package/dist/types/sim-cli.d.ts +8 -0
- package/dist/types/sim-cli.d.ts.map +1 -0
- package/dist/types/types.d.ts +45 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/visual.d.ts +79 -0
- package/dist/types/visual.d.ts.map +1 -0
- package/package.json +22 -3
- package/skill/browse/SKILL.md +192 -481
- package/skill/browse/references/commands.md +203 -18
- package/skill/browse-aeo/SKILL.md +148 -0
- package/skill/browse-config/SKILL.md +200 -0
- package/skill/browse-geo/SKILL.md +225 -0
- package/skill/browse-qa/SKILL.md +134 -290
- package/skill/browse-seo/SKILL.md +188 -0
- package/skill/browse-stealth/SKILL.md +246 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: browse-seo
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: |
|
|
5
|
+
SEO auditing for AI agents using the browse CLI. Extracts meta tags, headings, structured data,
|
|
6
|
+
performance metrics, link structure, and mobile rendering. Generates actionable audit reports
|
|
7
|
+
with findings and recommendations. Works with any URL.
|
|
8
|
+
allowed-tools:
|
|
9
|
+
- Bash
|
|
10
|
+
- Read
|
|
11
|
+
argument-hint: "[URL to audit]"
|
|
12
|
+
arguments:
|
|
13
|
+
- request
|
|
14
|
+
when_to_use: |
|
|
15
|
+
Use when the user asks for an SEO audit, SEO check, SEO analysis, on-page SEO review,
|
|
16
|
+
or says /browse-seo. Signs you should use this skill:
|
|
17
|
+
- User wants to check meta tags, structured data, or heading hierarchy
|
|
18
|
+
- User wants a technical SEO report for a page or site
|
|
19
|
+
- User asks about Open Graph tags, Twitter cards, or schema markup
|
|
20
|
+
- User wants to check mobile-friendliness or Core Web Vitals
|
|
21
|
+
Do NOT use for general browsing, form filling, or non-SEO tasks.
|
|
22
|
+
effort: medium
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# browse-seo: SEO Audit for AI Agents
|
|
26
|
+
|
|
27
|
+
## Goal
|
|
28
|
+
|
|
29
|
+
Run a complete on-page SEO audit for a target URL using the `browse` CLI. Extract technical
|
|
30
|
+
SEO signals, analyze them, and produce a report with findings and recommendations.
|
|
31
|
+
|
|
32
|
+
## Step 0: Consider stealth setup (optional)
|
|
33
|
+
|
|
34
|
+
If the audit target is behind bot detection (Cloudflare, competitor sites), use camoufox:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
browse --runtime camoufox --headed goto <url>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
For most public pages, the default Chromium runtime is sufficient. Skip unless you hit blocks.
|
|
41
|
+
|
|
42
|
+
## Step 1: Navigate to the target URL
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
browse goto <url>
|
|
46
|
+
browse wait --network-idle
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Verify the page loaded. Note any redirects -- redirect chains matter for SEO. If the page
|
|
50
|
+
returns 403 or a challenge, switch to camoufox (Step 0).
|
|
51
|
+
|
|
52
|
+
## Step 2: Extract meta tags
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
browse meta
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Returns title, description, canonical, OG tags, Twitter Card, robots, and viewport. Check:
|
|
59
|
+
|
|
60
|
+
- **Title**: present, under 60 chars, contains target keywords
|
|
61
|
+
- **Description**: present, 120-160 chars, compelling and unique
|
|
62
|
+
- **Canonical**: present, correct URL (trailing slashes, www vs non-www)
|
|
63
|
+
- **Robots**: no accidental `noindex` or `nofollow`
|
|
64
|
+
- **Viewport**: `width=device-width, initial-scale=1` for mobile
|
|
65
|
+
- **OG tags**: `og:title`, `og:description`, `og:image`, `og:url` all present
|
|
66
|
+
- **Twitter Card**: `twitter:card`, `twitter:title`, `twitter:description` present
|
|
67
|
+
|
|
68
|
+
## Step 3: Check heading structure
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
browse headings
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Returns H1-H6 hierarchy with counts. Check:
|
|
75
|
+
|
|
76
|
+
- **Exactly one H1**: multiple H1s dilute the primary topic signal
|
|
77
|
+
- **H1 matches topic**: should contain the primary keyword
|
|
78
|
+
- **Logical nesting**: H2 under H1, H3 under H2 -- no skipped levels
|
|
79
|
+
- **Keyword presence**: target keywords in H1 and H2 tags
|
|
80
|
+
|
|
81
|
+
## Step 4: Extract structured data
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
browse schema
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Extracts JSON-LD, Microdata, and RDFa from the page. Check:
|
|
88
|
+
|
|
89
|
+
- **Presence**: at least one schema type (Article, Product, Organization, etc.)
|
|
90
|
+
- **Required properties**: each type needs required fields per Google's docs
|
|
91
|
+
- **Valid JSON-LD**: no syntax errors or malformed objects
|
|
92
|
+
- **Correct @type**: matches actual page content
|
|
93
|
+
- **Missing opportunities**: FAQ, HowTo, Breadcrumb, Review where content supports it
|
|
94
|
+
|
|
95
|
+
## Step 5: Check performance
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
browse perf
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Returns navigation timing (DNS, TTFB, DOM load, full load). Check:
|
|
102
|
+
|
|
103
|
+
- **TTFB**: under 200ms good, over 600ms problem
|
|
104
|
+
- **DOM Content Loaded**: under 1.5s acceptable
|
|
105
|
+
- **Full load**: under 3s for good UX
|
|
106
|
+
- **DNS**: near zero with proper prefetching
|
|
107
|
+
|
|
108
|
+
Use `browse network` to inspect render-blocking resources, large assets, and request counts.
|
|
109
|
+
|
|
110
|
+
## Step 6: Analyze link structure
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
browse links
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Returns all anchor elements with text and href. Check:
|
|
117
|
+
|
|
118
|
+
- **Internal links**: sufficient linking for crawlability
|
|
119
|
+
- **Anchor text**: descriptive, not "click here" or bare URLs
|
|
120
|
+
- **External links**: appropriate outbound links, nofollow where needed
|
|
121
|
+
- **Broken links**: anything pointing to 404 or error pages
|
|
122
|
+
|
|
123
|
+
## Step 7: Check mobile rendering
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
browse responsive
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Captures screenshots at mobile (375px), tablet (768px), and desktop (1440px). Review for:
|
|
130
|
+
|
|
131
|
+
- **Mobile layout**: no horizontal scrolling, readable without zooming
|
|
132
|
+
- **Tap targets**: 48px minimum for touch
|
|
133
|
+
- **Content parity**: mobile has same critical content as desktop
|
|
134
|
+
- **Font size**: 16px minimum base font
|
|
135
|
+
|
|
136
|
+
Use `browse screenshot` for a single full-page capture if needed.
|
|
137
|
+
|
|
138
|
+
## Step 8: Custom checks via JavaScript
|
|
139
|
+
|
|
140
|
+
Run targeted checks the built-in commands do not cover:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Image alt tags
|
|
144
|
+
browse js "const imgs=[...document.querySelectorAll('img')]; const missing=imgs.filter(i=>!i.alt&&!i.getAttribute('role')); JSON.stringify({total:imgs.length,missingAlt:missing.length,examples:missing.slice(0,5).map(i=>i.src.slice(-60))})"
|
|
145
|
+
|
|
146
|
+
# Duplicate meta tags
|
|
147
|
+
browse js "JSON.stringify({titles:document.querySelectorAll('title').length,descriptions:document.querySelectorAll('meta[name=description]').length,canonicals:document.querySelectorAll('link[rel=canonical]').length})"
|
|
148
|
+
|
|
149
|
+
# Hreflang tags
|
|
150
|
+
browse js "JSON.stringify([...document.querySelectorAll('link[rel=alternate][hreflang]')].map(t=>({lang:t.hreflang,href:t.href})))"
|
|
151
|
+
|
|
152
|
+
# Lazy images without dimensions
|
|
153
|
+
browse js "const lazy=[...document.querySelectorAll('img[loading=lazy]')]; const noDims=lazy.filter(i=>!i.width&&!i.height&&!i.getAttribute('width')); JSON.stringify({lazyImages:lazy.length,missingDimensions:noDims.length})"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Check robots.txt and sitemap:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
browse goto <origin>/robots.txt
|
|
160
|
+
browse text
|
|
161
|
+
browse goto <origin>/sitemap.xml
|
|
162
|
+
browse text
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Step 9: Generate the audit report
|
|
166
|
+
|
|
167
|
+
After collecting data from Steps 2-8, produce a structured report:
|
|
168
|
+
|
|
169
|
+
1. **Summary**: one-paragraph overview with pass/fail/warning counts
|
|
170
|
+
2. **Meta Tags**: title, description, canonical, robots, OG, Twitter -- each rated
|
|
171
|
+
3. **Heading Structure**: H1 count, nesting issues, keyword presence
|
|
172
|
+
4. **Structured Data**: schema types found, missing opportunities, validation issues
|
|
173
|
+
5. **Performance**: TTFB, load times, blocking resources
|
|
174
|
+
6. **Link Analysis**: internal/external ratio, broken links, anchor text quality
|
|
175
|
+
7. **Mobile Friendliness**: viewport tag, responsive screenshots, tap target issues
|
|
176
|
+
8. **Images**: alt tag coverage, lazy loading, dimension attributes
|
|
177
|
+
9. **Recommendations**: prioritized fixes (critical, important, nice-to-have)
|
|
178
|
+
|
|
179
|
+
Rate each section as PASS, WARNING, or FAIL. Prioritize recommendations by impact.
|
|
180
|
+
|
|
181
|
+
## Important Rules
|
|
182
|
+
|
|
183
|
+
- The browser persists between commands. Cookies, tabs, and session state carry over.
|
|
184
|
+
- After `goto`, always `wait --network-idle` before extracting data.
|
|
185
|
+
- The agent interprets all results. Browse extracts raw data; analysis is your job.
|
|
186
|
+
- Do not install anything automatically.
|
|
187
|
+
- Save screenshots under `.browse/` directories.
|
|
188
|
+
- For sites that block bots, use `--runtime camoufox --headed`.
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: browse-stealth
|
|
3
|
+
version: 2.0.0
|
|
4
|
+
description: |
|
|
5
|
+
Stealth browsing with the camoufox runtime for AI agents. Covers Cloudflare Turnstile bypass,
|
|
6
|
+
Google anti-bot evasion, authenticated sessions, and proxy rotation. Uses the browse CLI with
|
|
7
|
+
--runtime camoufox and named camoufox profiles.
|
|
8
|
+
allowed-tools:
|
|
9
|
+
- Bash
|
|
10
|
+
- Read
|
|
11
|
+
argument-hint: "[URL or site that blocks normal browsers]"
|
|
12
|
+
arguments:
|
|
13
|
+
- request
|
|
14
|
+
when_to_use: |
|
|
15
|
+
Use when the user asks for stealth browsing, anti-detection, bot bypass, Turnstile, or says
|
|
16
|
+
/browse-stealth. Signs you need this:
|
|
17
|
+
- Page shows CAPTCHA or "verify you are human" challenge
|
|
18
|
+
- Page returns blank/403/challenge page instead of content
|
|
19
|
+
- Google shows "unusual traffic" block
|
|
20
|
+
- Site uses Cloudflare, DataDome, PerimeterX, or similar bot protection
|
|
21
|
+
Do NOT use for sites that load fine with regular browse -- camoufox is slower to start.
|
|
22
|
+
effort: high
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# browse-stealth: Stealth Browsing with Camoufox
|
|
26
|
+
|
|
27
|
+
## Step 0: Setup via /browse-config
|
|
28
|
+
|
|
29
|
+
Before launching a stealth session, generate a camoufox configuration profile.
|
|
30
|
+
|
|
31
|
+
Run `/browse-config` to generate a stealth profile, or use the Google-safe preset.
|
|
32
|
+
|
|
33
|
+
Presets available in /browse-config:
|
|
34
|
+
- **Stealth browsing** -- geoip + humanize for general anti-detection
|
|
35
|
+
- **Google-safe** -- geoip + humanize + random OS for Google searches
|
|
36
|
+
- **Fast scraping** -- blocks images, WebRTC, WebGL; enables cache
|
|
37
|
+
- **Custom** -- interactive walkthrough of all options
|
|
38
|
+
|
|
39
|
+
The `--camoufox-profile` flag only applies when starting a NEW server. If a browse server is already running, stop it first with `browse stop` before switching profiles.
|
|
40
|
+
|
|
41
|
+
## Step 1: Launch with camoufox
|
|
42
|
+
|
|
43
|
+
Stop any existing server, then launch with the camoufox runtime:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
browse stop # stop any running server
|
|
47
|
+
browse --runtime camoufox --camoufox-profile <name> goto <url>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Replace `<name>` with the profile created in Step 0 (e.g. "stealth", "google"). If no named profile exists, the `camoufox` section in `browse.json` is used automatically:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
browse stop
|
|
54
|
+
browse --runtime camoufox goto <url>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
After navigation, stabilize the page before reading or interacting:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
browse wait --network-idle
|
|
61
|
+
browse snapshot -i
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Step 2: Cloudflare Turnstile bypass
|
|
65
|
+
|
|
66
|
+
### Navigate and identify the Turnstile widget
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
browse --runtime camoufox --camoufox-profile <name> goto https://target-site.com/login
|
|
70
|
+
browse snapshot -i
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Look in the snapshot output for a Turnstile iframe or checkbox. Common patterns:
|
|
74
|
+
- An iframe with `challenges.cloudflare.com` in the src
|
|
75
|
+
- A checkbox labeled "Verify you are human"
|
|
76
|
+
- Elements with `cf-turnstile` in their class or ID
|
|
77
|
+
|
|
78
|
+
### Wait for Turnstile to auto-resolve
|
|
79
|
+
|
|
80
|
+
Many Turnstile challenges resolve automatically when humanize is enabled in the profile. Wait for it:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
browse wait --network-idle
|
|
84
|
+
browse snapshot -i
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Check if the page has advanced past the challenge. If the form or main content is now visible, Turnstile passed.
|
|
88
|
+
|
|
89
|
+
### Click the checkbox if Turnstile persists
|
|
90
|
+
|
|
91
|
+
If the challenge is still showing after the wait:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
browse click @eN # use the @ref from snapshot
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Replace `@eN` with the ref pointing to the Turnstile checkbox from the snapshot.
|
|
98
|
+
|
|
99
|
+
### Verify and retry
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
browse snapshot -i
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
If Turnstile still blocks, increase humanize delay in the profile (set humanize to a higher value like 2.0), stop the server, and relaunch:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
browse stop
|
|
109
|
+
browse --runtime camoufox --camoufox-profile <name> goto https://target-site.com/login
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Step 3: Google anti-bot bypass
|
|
113
|
+
|
|
114
|
+
### Configure the profile
|
|
115
|
+
|
|
116
|
+
Use the Google-safe preset from /browse-config, which enables:
|
|
117
|
+
- `geoip: true` -- spoofs location based on exit IP
|
|
118
|
+
- `humanize: true` -- adds random delays to interactions
|
|
119
|
+
- `os: ["windows", "macos", "linux"]` -- random OS fingerprint per launch
|
|
120
|
+
|
|
121
|
+
### Navigate to Google
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
browse stop
|
|
125
|
+
browse --runtime camoufox --camoufox-profile google goto "https://www.google.com/search?q=your+query"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Or use the search macro:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
browse --runtime camoufox --camoufox-profile google goto @google "your query"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Check for blocks
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
browse snapshot -i
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Look for CAPTCHA screens or consent dialogs. If blocked:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
browse text
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Confirm the block message (e.g. "unusual traffic from your computer network").
|
|
147
|
+
|
|
148
|
+
### Handle consent screens
|
|
149
|
+
|
|
150
|
+
Google often shows a consent/cookie dialog before search results. Dismiss it:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
browse snapshot -i # find the Accept button ref
|
|
154
|
+
browse click @eN # click Accept/Agree
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Add delays between requests
|
|
158
|
+
|
|
159
|
+
When making multiple Google searches, add waits between them to avoid rate limiting:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
browse wait --network-idle
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
If still blocked after multiple attempts, the IP may be flagged. Switch to a different proxy (see Step 5).
|
|
166
|
+
|
|
167
|
+
## Step 4: Authenticated sessions
|
|
168
|
+
|
|
169
|
+
### Persistent browser profiles
|
|
170
|
+
|
|
171
|
+
Use `--profile` for a persistent browser identity. Cookies, localStorage, and session data survive server restarts:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
browse stop
|
|
175
|
+
browse --runtime camoufox --camoufox-profile stealth --profile mysite goto https://target-site.com/login
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Login once through the normal flow (fill credentials, click submit). On subsequent launches with the same `--profile`, cookies persist and you skip the login:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
browse stop
|
|
182
|
+
browse --runtime camoufox --camoufox-profile stealth --profile mysite goto https://target-site.com/dashboard
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Credential vault
|
|
186
|
+
|
|
187
|
+
For automated login flows, save credentials to the encrypted vault:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
browse auth save mysite https://target-site.com/login myuser --password-stdin <<< "mypassword"
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Then login automatically:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
browse auth login mysite
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
The vault uses AES-256-GCM encryption. Passwords are stored in `.browse/auth/` with mode 0o600.
|
|
200
|
+
|
|
201
|
+
## Step 5: Proxy rotation
|
|
202
|
+
|
|
203
|
+
### Configure proxy in the camoufox profile
|
|
204
|
+
|
|
205
|
+
Add proxy settings to the profile JSON (via /browse-config custom mode or by editing the file directly):
|
|
206
|
+
|
|
207
|
+
```json
|
|
208
|
+
{
|
|
209
|
+
"geoip": true,
|
|
210
|
+
"humanize": true,
|
|
211
|
+
"proxy": {
|
|
212
|
+
"server": "http://proxy:8080",
|
|
213
|
+
"username": "user",
|
|
214
|
+
"password": "pass"
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Save this as a named profile, e.g. `.browse/camoufox-profiles/proxy-us.json`.
|
|
220
|
+
|
|
221
|
+
### Switch proxies by switching profiles
|
|
222
|
+
|
|
223
|
+
Create multiple profiles with different proxy endpoints:
|
|
224
|
+
|
|
225
|
+
- `.browse/camoufox-profiles/proxy-us.json` -- US proxy
|
|
226
|
+
- `.browse/camoufox-profiles/proxy-eu.json` -- EU proxy
|
|
227
|
+
- `.browse/camoufox-profiles/proxy-asia.json` -- Asia proxy
|
|
228
|
+
|
|
229
|
+
To rotate, stop the server and relaunch with a different profile:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
browse stop
|
|
233
|
+
browse --runtime camoufox --camoufox-profile proxy-eu goto <url>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Each profile switch requires a server restart because the proxy is configured at browser launch time.
|
|
237
|
+
|
|
238
|
+
## Key Rules
|
|
239
|
+
|
|
240
|
+
1. **`--camoufox-profile` is server-spawn-only.** Switching profiles requires `browse stop` first. The profile is read once at server startup.
|
|
241
|
+
2. **`--runtime camoufox` selects the Firefox-based anti-detection engine.** It replaces the default Chromium with a hardened Firefox that spoofs fingerprints at the C++ level.
|
|
242
|
+
3. **humanize adds random delays to clicks and typing.** Set to `true` for default delays, or a number (0.5-2.0) to control speed. Higher values mean slower, more human-like behavior.
|
|
243
|
+
4. **geoip spoofs location based on exit IP.** When using a proxy, geoip derives timezone, locale, and geolocation from the proxy's IP address.
|
|
244
|
+
5. **Never mix `--profile` (persistent browser data) with `--session` (shared Chromium multiplexing).** They serve different purposes. `--profile` persists cookies across restarts. `--session` isolates parallel agents within a single server.
|
|
245
|
+
6. **IP reputation matters.** Fingerprint spoofing alone does not bypass IP-based blocks. Use residential proxies for heavily protected sites.
|
|
246
|
+
7. **Headed mode is recommended.** Headless Firefox is easier to detect. Use `--headed` when anti-detection is critical, or set `headless: false` in the profile.
|