opensteer 0.6.13 → 0.7.1
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 +256 -184
- package/dist/chunk-7QTHGTGN.js +32589 -0
- package/dist/chunk-7QTHGTGN.js.map +1 -0
- package/dist/cli/bin.cjs +38219 -0
- package/dist/cli/bin.cjs.map +1 -0
- package/dist/cli/bin.d.cts +1 -0
- package/dist/cli/bin.d.ts +1 -0
- package/dist/cli/bin.js +5612 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/index.cjs +31327 -16009
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +4440 -670
- package/dist/index.d.ts +4440 -670
- package/dist/index.js +438 -378
- package/dist/index.js.map +1 -0
- package/package.json +58 -62
- package/skills/README.md +21 -20
- package/skills/opensteer/SKILL.md +60 -194
- package/skills/opensteer/references/cli-reference.md +69 -113
- package/skills/opensteer/references/request-workflow.md +81 -0
- package/skills/opensteer/references/sdk-reference.md +101 -154
- package/CHANGELOG.md +0 -75
- package/bin/opensteer.mjs +0 -1423
- package/dist/browser-profile-client-CGXc0-P9.d.cts +0 -228
- package/dist/browser-profile-client-DHLzMf-K.d.ts +0 -228
- package/dist/chunk-2ES46WCO.js +0 -1437
- package/dist/chunk-3H5RRIMZ.js +0 -69
- package/dist/chunk-AVXUMEDG.js +0 -62
- package/dist/chunk-DN3GI5CH.js +0 -57
- package/dist/chunk-FAHE5DB2.js +0 -190
- package/dist/chunk-HBTSQ2V4.js +0 -15259
- package/dist/chunk-K5CL76MG.js +0 -81
- package/dist/chunk-U724TBY6.js +0 -1262
- package/dist/chunk-ZRCFF546.js +0 -77
- package/dist/cli/auth.cjs +0 -2022
- package/dist/cli/auth.d.cts +0 -114
- package/dist/cli/auth.d.ts +0 -114
- package/dist/cli/auth.js +0 -15
- package/dist/cli/local-profile.cjs +0 -197
- package/dist/cli/local-profile.d.cts +0 -18
- package/dist/cli/local-profile.d.ts +0 -18
- package/dist/cli/local-profile.js +0 -97
- package/dist/cli/profile.cjs +0 -18548
- package/dist/cli/profile.d.cts +0 -79
- package/dist/cli/profile.d.ts +0 -79
- package/dist/cli/profile.js +0 -1328
- package/dist/cli/server.cjs +0 -17232
- package/dist/cli/server.d.cts +0 -2
- package/dist/cli/server.d.ts +0 -2
- package/dist/cli/server.js +0 -977
- package/dist/cli/skills-installer.cjs +0 -230
- package/dist/cli/skills-installer.d.cts +0 -28
- package/dist/cli/skills-installer.d.ts +0 -28
- package/dist/cli/skills-installer.js +0 -201
- package/dist/extractor-4Q3TFZJB.js +0 -8
- package/dist/resolver-MGN64KCP.js +0 -7
- package/dist/types-Cr10igF3.d.cts +0 -345
- package/dist/types-Cr10igF3.d.ts +0 -345
- package/skills/electron/SKILL.md +0 -87
- package/skills/electron/references/opensteer-electron-recipes.md +0 -88
- package/skills/electron/references/opensteer-electron-workflow.md +0 -85
- package/skills/opensteer/references/examples.md +0 -118
|
@@ -1,159 +1,115 @@
|
|
|
1
|
-
# Opensteer CLI
|
|
1
|
+
# Opensteer CLI Reference
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use the CLI when you need a fast, stateful loop against a live browser session.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
export OPENSTEER_SESSION=my-session
|
|
7
|
-
# Or for non-interactive runners:
|
|
8
|
-
export OPENSTEER_CLIENT_ID=agent-1
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Global flags: `--session <id>`, `--name <namespace>`, `--headless`, `--description <text>`.
|
|
12
|
-
|
|
13
|
-
## Navigation
|
|
5
|
+
## Session Loop
|
|
14
6
|
|
|
15
7
|
```bash
|
|
16
|
-
opensteer open
|
|
17
|
-
opensteer
|
|
18
|
-
opensteer
|
|
19
|
-
opensteer
|
|
20
|
-
opensteer
|
|
21
|
-
opensteer
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
opensteer
|
|
25
|
-
opensteer back # Go back in history
|
|
26
|
-
opensteer forward # Go forward in history
|
|
27
|
-
opensteer reload # Reload page
|
|
28
|
-
opensteer close # Close browser and stop server
|
|
29
|
-
opensteer close --all # Close all active sessions
|
|
30
|
-
opensteer sessions # List active sessions
|
|
31
|
-
opensteer status # Show resolved session/name state
|
|
8
|
+
opensteer open https://example.com --name demo
|
|
9
|
+
opensteer snapshot action --name demo
|
|
10
|
+
opensteer click 3 --name demo --description "primary button"
|
|
11
|
+
opensteer input 7 "search term" --name demo --press-enter --description "search input"
|
|
12
|
+
opensteer snapshot extraction --name demo
|
|
13
|
+
opensteer extract --name demo \
|
|
14
|
+
--description "page summary" \
|
|
15
|
+
--schema '{"title":{"selector":"title"},"url":{"source":"current_url"}}'
|
|
16
|
+
opensteer close --name demo
|
|
32
17
|
```
|
|
33
18
|
|
|
34
|
-
|
|
19
|
+
## Core Rules
|
|
20
|
+
|
|
21
|
+
- Keep `--name` stable for the whole workflow.
|
|
22
|
+
- Use `snapshot action` before counter-based interactions.
|
|
23
|
+
- Re-snapshot after any navigation or DOM-changing action before reusing counters.
|
|
24
|
+
- Use `--description` when the interaction or extraction should become replayable later.
|
|
25
|
+
- CLI commands return JSON for machine-readable actions and data commands.
|
|
35
26
|
|
|
36
|
-
##
|
|
27
|
+
## Navigation And Data
|
|
37
28
|
|
|
38
29
|
```bash
|
|
39
|
-
opensteer
|
|
40
|
-
opensteer snapshot
|
|
41
|
-
opensteer snapshot
|
|
42
|
-
opensteer
|
|
43
|
-
opensteer snapshot full # Minimal cleaning, full HTML
|
|
44
|
-
opensteer state # URL + title + cleaned HTML
|
|
45
|
-
opensteer screenshot # Save screenshot to screenshot.png
|
|
46
|
-
opensteer screenshot output.png # Save to specific file
|
|
47
|
-
opensteer screenshot --fullPage # Full page screenshot
|
|
30
|
+
opensteer goto https://example.com/products --name demo
|
|
31
|
+
opensteer snapshot action --name demo
|
|
32
|
+
opensteer snapshot extraction --name demo
|
|
33
|
+
opensteer extract --name demo --schema '{"items":[{"title":{"selector":"h2"}}]}'
|
|
48
34
|
```
|
|
49
35
|
|
|
50
|
-
##
|
|
36
|
+
## Browser Connection Modes
|
|
51
37
|
|
|
52
|
-
|
|
38
|
+
Open a brand-new browser:
|
|
53
39
|
|
|
54
40
|
```bash
|
|
55
|
-
opensteer
|
|
56
|
-
opensteer click --description "the submit button" # By cached description
|
|
57
|
-
opensteer click 5 --button right # Right-click
|
|
58
|
-
opensteer click 5 --clickCount 2 # Double-click
|
|
59
|
-
opensteer hover 4 # Hover over element
|
|
60
|
-
opensteer hover --description "the user menu" # Hover by description
|
|
41
|
+
opensteer open https://example.com --name demo --headless true
|
|
61
42
|
```
|
|
62
43
|
|
|
63
|
-
|
|
44
|
+
Attach to a live Chromium instance:
|
|
64
45
|
|
|
65
46
|
```bash
|
|
66
|
-
opensteer
|
|
67
|
-
opensteer
|
|
68
|
-
opensteer
|
|
69
|
-
opensteer input --description "the search input" --text "query" --pressEnter
|
|
47
|
+
opensteer open https://example.com --name demo --browser attach-live --attach-endpoint 9222
|
|
48
|
+
opensteer browser discover
|
|
49
|
+
opensteer browser inspect --endpoint 9222
|
|
70
50
|
```
|
|
71
51
|
|
|
72
|
-
|
|
52
|
+
Launch from a copied local profile:
|
|
73
53
|
|
|
74
54
|
```bash
|
|
75
|
-
opensteer
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
opensteer scroll # Scroll page down (default)
|
|
79
|
-
opensteer scroll --direction up # Scroll up
|
|
80
|
-
opensteer scroll --direction down --amount 1000
|
|
81
|
-
opensteer scroll 12 # Scroll within container element
|
|
55
|
+
opensteer open https://example.com --name demo --browser snapshot-session \
|
|
56
|
+
--source-user-data-dir "~/Library/Application Support/Google/Chrome" \
|
|
57
|
+
--source-profile-directory Default
|
|
82
58
|
```
|
|
83
59
|
|
|
84
|
-
|
|
60
|
+
Launch from a copied authenticated profile:
|
|
85
61
|
|
|
86
62
|
```bash
|
|
87
|
-
opensteer
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
opensteer press "Control+a"
|
|
91
|
-
opensteer type "Hello World" # Type into focused element
|
|
63
|
+
opensteer open https://example.com --name demo --browser snapshot-authenticated \
|
|
64
|
+
--source-user-data-dir "~/Library/Application Support/Google/Chrome" \
|
|
65
|
+
--source-profile-directory "Profile 1"
|
|
92
66
|
```
|
|
93
67
|
|
|
94
|
-
##
|
|
68
|
+
## Local Browser Profile Helpers
|
|
95
69
|
|
|
96
70
|
```bash
|
|
97
|
-
opensteer
|
|
98
|
-
opensteer
|
|
99
|
-
opensteer
|
|
100
|
-
opensteer get-attrs 5 # Get all HTML attributes
|
|
101
|
-
opensteer get-html # Full page HTML
|
|
102
|
-
opensteer get-html "main" # HTML of element matching selector
|
|
71
|
+
opensteer local-profile list
|
|
72
|
+
opensteer local-profile inspect --user-data-dir "~/Library/Application Support/Opensteer Chrome"
|
|
73
|
+
opensteer local-profile unlock --user-data-dir "~/Library/Application Support/Opensteer Chrome"
|
|
103
74
|
```
|
|
104
75
|
|
|
105
|
-
##
|
|
76
|
+
## Cloud Profile Cookie Sync
|
|
106
77
|
|
|
107
78
|
```bash
|
|
108
|
-
opensteer
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
opensteer tab-close # Close current tab
|
|
113
|
-
opensteer tab-close 2 # Close specific tab
|
|
79
|
+
opensteer profile sync \
|
|
80
|
+
--profile-id bp_123 \
|
|
81
|
+
--attach-endpoint 9222 \
|
|
82
|
+
--domain github.com
|
|
114
83
|
```
|
|
115
84
|
|
|
116
|
-
##
|
|
85
|
+
## Network Capture
|
|
117
86
|
|
|
118
|
-
|
|
119
|
-
opensteer cookies # Get all cookies
|
|
120
|
-
opensteer cookies --url https://example.com # Cookies for specific URL
|
|
121
|
-
opensteer cookie-set --name token --value abc123
|
|
122
|
-
opensteer cookies-clear # Clear all cookies
|
|
123
|
-
opensteer cookies-export /tmp/cookies.json # Export to file
|
|
124
|
-
opensteer cookies-import /tmp/cookies.json # Import from file
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## Utility
|
|
87
|
+
Inspect the traffic triggered by a session:
|
|
128
88
|
|
|
129
89
|
```bash
|
|
130
|
-
opensteer
|
|
131
|
-
opensteer
|
|
132
|
-
opensteer
|
|
133
|
-
opensteer
|
|
90
|
+
opensteer network query --name demo --include-bodies --limit 20
|
|
91
|
+
opensteer network save --name demo --tag login-flow
|
|
92
|
+
opensteer network diff --name demo --left rec_a --right rec_b
|
|
93
|
+
opensteer network probe --name demo --record-id rec_123
|
|
94
|
+
opensteer network minimize --name demo --record-id rec_123 --transport context-http
|
|
134
95
|
```
|
|
135
96
|
|
|
136
|
-
##
|
|
97
|
+
## Request Plans
|
|
137
98
|
|
|
138
|
-
|
|
99
|
+
Infer a plan from a captured record, then execute it:
|
|
139
100
|
|
|
140
101
|
```bash
|
|
141
|
-
opensteer
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
opensteer extract '{"title":{"element":3},"price":{"element":7}}'
|
|
146
|
-
opensteer extract '{"url":{"element":5,"attribute":"href"}}'
|
|
147
|
-
opensteer extract '{"pageUrl":{"source":"current_url"},"title":{"element":3}}'
|
|
148
|
-
|
|
149
|
-
# Explicit array bindings: include multiple items to identify the repeating pattern
|
|
150
|
-
opensteer extract '{"results":[{"title":{"element":11},"url":{"element":10,"attribute":"href"}},{"title":{"element":16},"url":{"element":15,"attribute":"href"}}]}'
|
|
151
|
-
|
|
152
|
-
# Semantic extraction: use the output shape plus description/prompt
|
|
153
|
-
opensteer extract '{"title":"string","price":"string"}' --description "product details"
|
|
154
|
-
opensteer extract '{"images":[{"imageUrl":"string","alt":"string","caption":"string","credit":"string"}]}' \
|
|
155
|
-
--description "article images with captions and credits" \
|
|
156
|
-
--prompt "For each image, return the image URL, alt text, caption, and credit. Prefer caption and credit from the same figure. If missing, look at sibling text, then parent/container text, then nearby alt/data-* attributes."
|
|
102
|
+
opensteer plan infer --name demo --record-id rec_123 --key products.search --version v1
|
|
103
|
+
opensteer plan get --name demo products.search
|
|
104
|
+
opensteer request execute --name demo products.search --query q=laptop
|
|
105
|
+
opensteer request raw --name demo https://example.com/api/search --transport context-http
|
|
157
106
|
```
|
|
158
107
|
|
|
159
|
-
|
|
108
|
+
## Execution Modes
|
|
109
|
+
|
|
110
|
+
- `managed`: Opensteer launches and owns a fresh browser.
|
|
111
|
+
- `attach-live`: Opensteer attaches to an already running Chromium browser.
|
|
112
|
+
- `snapshot-session`: Opensteer copies an existing profile into an isolated owned session.
|
|
113
|
+
- `snapshot-authenticated`: Opensteer copies a profile while preserving harder authenticated state.
|
|
114
|
+
|
|
115
|
+
Use `--engine abp` on `open` only when the optional `@opensteer/engine-abp` package is installed.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Opensteer Request Workflow
|
|
2
|
+
|
|
3
|
+
Use this workflow when the deliverable is a custom API, a replayable request plan, or a lower-overhead path than full browser automation.
|
|
4
|
+
|
|
5
|
+
## Transport Selection
|
|
6
|
+
|
|
7
|
+
- `direct-http`: the request is replayable without a browser.
|
|
8
|
+
- `context-http`: browser session state matters, but the request does not need to execute inside page JavaScript.
|
|
9
|
+
- `page-http`: the request must execute inside the live page JavaScript world.
|
|
10
|
+
- `session-http`: use a stored request plan that still depends on a live browser session.
|
|
11
|
+
|
|
12
|
+
When in doubt, start with browser-backed capture first. Opensteer treats browser-backed replay as a first-class path, not a fallback.
|
|
13
|
+
|
|
14
|
+
## SDK Flow
|
|
15
|
+
|
|
16
|
+
1. Trigger the request from a real page.
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
await opensteer.open("https://example.com/app");
|
|
20
|
+
await opensteer.click({
|
|
21
|
+
description: "load products",
|
|
22
|
+
networkTag: "products-load",
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
2. Inspect the captured traffic.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
const records = await opensteer.queryNetwork({
|
|
30
|
+
tag: "products-load",
|
|
31
|
+
includeBodies: true,
|
|
32
|
+
limit: 20,
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
3. Test the request directly.
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
const response = await opensteer.rawRequest({
|
|
40
|
+
transport: "context-http",
|
|
41
|
+
url: "https://example.com/api/products",
|
|
42
|
+
method: "POST",
|
|
43
|
+
body: {
|
|
44
|
+
json: { page: 1 },
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
4. Promote a captured record into a request plan.
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
await opensteer.inferRequestPlan({
|
|
53
|
+
recordId: records.records[0]!.id,
|
|
54
|
+
key: "products.search",
|
|
55
|
+
version: "v1",
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
5. Replay the plan from code.
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
const result = await opensteer.request("products.search", {
|
|
63
|
+
query: { q: "laptop" },
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## CLI Equivalents
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
opensteer network query --name demo --tag products-load --include-bodies --limit 20
|
|
71
|
+
opensteer request raw --name demo https://example.com/api/products --transport context-http
|
|
72
|
+
opensteer plan infer --name demo --record-id rec_123 --key products.search --version v1
|
|
73
|
+
opensteer request execute --name demo products.search --query q=laptop
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Practical Guidance
|
|
77
|
+
|
|
78
|
+
- Capture the browser action first if authentication, cookies, or minted tokens may matter.
|
|
79
|
+
- Save or tag the useful traffic before minimizing or diffing it.
|
|
80
|
+
- Prefer `direct-http` only after proving the request no longer depends on live browser state.
|
|
81
|
+
- Use recipes when the request plan needs deterministic auth refresh or setup work.
|
|
@@ -1,174 +1,121 @@
|
|
|
1
|
-
# Opensteer SDK
|
|
1
|
+
# Opensteer SDK Reference
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use the SDK when the workflow should become reusable TypeScript code in the repository.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Session Ownership
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
const opensteer = new Opensteer({
|
|
9
|
-
name: "my-scraper",
|
|
10
|
-
storage: { rootDir: process.cwd() },
|
|
11
|
-
});
|
|
12
|
-
await opensteer.launch({ headless: false });
|
|
13
|
-
await opensteer.close();
|
|
7
|
+
Owned session:
|
|
14
8
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
name: "my-scraper",
|
|
18
|
-
browser: {
|
|
19
|
-
mode: "real",
|
|
20
|
-
profileDirectory: "Default",
|
|
21
|
-
headless: false,
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
await opensteer.launch();
|
|
9
|
+
```ts
|
|
10
|
+
import { Opensteer } from "opensteer";
|
|
25
11
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
headless: false,
|
|
12
|
+
const opensteer = new Opensteer({
|
|
13
|
+
name: "demo",
|
|
14
|
+
rootDir: process.cwd(),
|
|
15
|
+
browser: { headless: true },
|
|
31
16
|
});
|
|
32
|
-
|
|
33
|
-
// Wrap an existing page instance:
|
|
34
|
-
const opensteer = Opensteer.from(existingPage, { name: "my-scraper" });
|
|
35
17
|
```
|
|
36
18
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
opensteer.page; // Low-level page handle (see "Advanced: Direct Page Access" in SKILL.md)
|
|
41
|
-
opensteer.context; // Low-level browser context handle
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Navigation
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
await opensteer.goto(url); // Navigate + waitForVisualStability
|
|
48
|
-
await opensteer.goto(url, { timeout: 60000 }); // Custom timeout
|
|
49
|
-
```
|
|
19
|
+
Attached session:
|
|
50
20
|
|
|
51
|
-
|
|
21
|
+
```ts
|
|
22
|
+
import { Opensteer } from "opensteer";
|
|
52
23
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const buffer = await opensteer.screenshot(); // PNG buffer
|
|
58
|
-
const jpeg = await opensteer.screenshot({ type: "jpeg", fullPage: true });
|
|
24
|
+
const opensteer = Opensteer.attach({
|
|
25
|
+
name: "demo",
|
|
26
|
+
rootDir: process.cwd(),
|
|
27
|
+
});
|
|
59
28
|
```
|
|
60
29
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
await opensteer.click({ element: 5 });
|
|
65
|
-
await opensteer.click({ description: "the submit button" });
|
|
66
|
-
await opensteer.click({ selector: "#btn" });
|
|
67
|
-
await opensteer.dblclick({ element: 7 });
|
|
68
|
-
await opensteer.rightclick({ element: 7 });
|
|
69
|
-
await opensteer.hover({ element: 4 });
|
|
70
|
-
await opensteer.input({ element: 3, text: "Hello" });
|
|
71
|
-
await opensteer.input({ description: "search", text: "q", pressEnter: true });
|
|
72
|
-
await opensteer.select({ element: 9, label: "Option A" });
|
|
73
|
-
await opensteer.scroll();
|
|
74
|
-
await opensteer.scroll({ direction: "up", amount: 500 });
|
|
75
|
-
```
|
|
30
|
+
Use `close()` for owned sessions. Use `disconnect()` for attached sessions.
|
|
76
31
|
|
|
77
|
-
##
|
|
32
|
+
## Core Browser Flow
|
|
78
33
|
|
|
79
|
-
```
|
|
80
|
-
|
|
34
|
+
```ts
|
|
35
|
+
await opensteer.open("https://example.com");
|
|
36
|
+
await opensteer.goto("https://example.com/products");
|
|
37
|
+
await opensteer.snapshot("action");
|
|
38
|
+
await opensteer.click({ description: "primary button" });
|
|
39
|
+
await opensteer.input({ description: "search input", text: "laptop", pressEnter: true });
|
|
40
|
+
await opensteer.hover({ description: "price filter" });
|
|
41
|
+
await opensteer.scroll({ direction: "down", amount: 600 });
|
|
81
42
|
const data = await opensteer.extract({
|
|
82
|
-
description: "
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
// Semantic extraction: schema is the output shape
|
|
86
|
-
const images = await opensteer.extract({
|
|
87
|
-
description: "article images with captions and credits",
|
|
88
|
-
prompt: "For each image, return the image URL, alt text, caption, and credit. Prefer caption and credit from the same figure. If missing, look at sibling text, then parent/container text, then nearby alt/data-* attributes.",
|
|
43
|
+
description: "page summary",
|
|
89
44
|
schema: {
|
|
90
|
-
|
|
45
|
+
title: { selector: "title" },
|
|
46
|
+
url: { source: "current_url" },
|
|
91
47
|
},
|
|
92
48
|
});
|
|
93
|
-
|
|
94
|
-
// Explicit bindings (during exploration or when no cache exists)
|
|
95
|
-
const data = await opensteer.extract({
|
|
96
|
-
schema: { title: { element: 3 }, price: { element: 7 } },
|
|
97
|
-
description: "product details",
|
|
98
|
-
});
|
|
99
49
|
```
|
|
100
50
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
| Wait for content | `opensteer.waitForText()` |
|
|
173
|
-
|
|
174
|
-
> **SDK Rule**: Every browser action in a script MUST use an `opensteer.*` method.
|
|
51
|
+
## Common Methods
|
|
52
|
+
|
|
53
|
+
Session and page control:
|
|
54
|
+
|
|
55
|
+
- `Opensteer.attach({ name?, rootDir? })`
|
|
56
|
+
- `open(url | { url?, name?, browser?, context? })`
|
|
57
|
+
- `goto(url | { url, networkTag? })`
|
|
58
|
+
- `listPages()`
|
|
59
|
+
- `newPage({ url?, openerPageRef? })`
|
|
60
|
+
- `activatePage({ pageRef })`
|
|
61
|
+
- `closePage({ pageRef })`
|
|
62
|
+
- `waitForPage({ openerPageRef?, urlIncludes?, timeoutMs? })`
|
|
63
|
+
|
|
64
|
+
Interaction and extraction:
|
|
65
|
+
|
|
66
|
+
- `snapshot("action" | "extraction")`
|
|
67
|
+
- `click({ element | selector | description, networkTag? })`
|
|
68
|
+
- `hover({ element | selector | description, networkTag? })`
|
|
69
|
+
- `input({ element | selector | description, text, pressEnter?, networkTag? })`
|
|
70
|
+
- `scroll({ element | selector | description, direction, amount, networkTag? })`
|
|
71
|
+
- `extract({ description, schema? })`
|
|
72
|
+
|
|
73
|
+
Inspection and evaluation:
|
|
74
|
+
|
|
75
|
+
- `evaluate(script | { script, pageRef?, args? })`
|
|
76
|
+
- `evaluateJson({ script, pageRef?, args? })`
|
|
77
|
+
- `waitForNetwork({ ...filters, pageRef?, includeBodies?, timeoutMs? })`
|
|
78
|
+
- `waitForResponse({ ...filters, pageRef?, includeBodies?, timeoutMs? })`
|
|
79
|
+
- `queryNetwork({ ...filters, includeBodies?, limit? })`
|
|
80
|
+
- `saveNetwork({ tag, ...filters })`
|
|
81
|
+
- `clearNetwork({ tag? })`
|
|
82
|
+
|
|
83
|
+
Request capture and replay:
|
|
84
|
+
|
|
85
|
+
- `rawRequest({ transport?, pageRef?, url, method?, headers?, body?, followRedirects? })`
|
|
86
|
+
- `inferRequestPlan({ recordId, key, version, lifecycle? })`
|
|
87
|
+
- `writeRequestPlan({ key, version, payload, lifecycle?, tags?, provenance?, freshness? })`
|
|
88
|
+
- `getRequestPlan({ key, version? })`
|
|
89
|
+
- `listRequestPlans({ key? })`
|
|
90
|
+
- `request(key, { path?, query?, headers?, body? })`
|
|
91
|
+
- `writeRecipe({ key, version, payload, tags?, provenance? })`
|
|
92
|
+
- `getRecipe({ key, version? })`
|
|
93
|
+
- `listRecipes({ key? })`
|
|
94
|
+
- `runRecipe({ key, version?, input? })`
|
|
95
|
+
|
|
96
|
+
Instrumentation:
|
|
97
|
+
|
|
98
|
+
- `captureScripts({ pageRef?, includeInline?, includeExternal?, includeDynamic?, includeWorkers?, urlFilter?, persist? })`
|
|
99
|
+
- `addInitScript({ script, args?, pageRef? })`
|
|
100
|
+
- `route({ urlPattern, resourceTypes?, times?, handler })`
|
|
101
|
+
- `interceptScript({ urlPattern, handler, times? })`
|
|
102
|
+
|
|
103
|
+
Browser and profile helpers:
|
|
104
|
+
|
|
105
|
+
- `discoverLocalCdpBrowsers({ timeoutMs? })`
|
|
106
|
+
- `inspectCdpEndpoint({ endpoint, headers?, timeoutMs? })`
|
|
107
|
+
- `inspectLocalBrowserProfile({ userDataDir? })`
|
|
108
|
+
- `unlockLocalBrowserProfile({ userDataDir })`
|
|
109
|
+
|
|
110
|
+
Lifecycle:
|
|
111
|
+
|
|
112
|
+
- `disconnect()`
|
|
113
|
+
- `close()`
|
|
114
|
+
|
|
115
|
+
## Rules
|
|
116
|
+
|
|
117
|
+
- Wrap owned sessions in `try/finally` and call `close()`.
|
|
118
|
+
- Use `networkTag` on actions that trigger requests you may inspect later.
|
|
119
|
+
- Use `description` when the interaction should be replayable across sessions.
|
|
120
|
+
- Use `element` targets only with a fresh snapshot from the same live session.
|
|
121
|
+
- Prefer Opensteer methods over raw Playwright so browser, extraction, and replay semantics stay consistent.
|