gm-oc 2.0.376 → 2.0.378
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/package.json +1 -1
- package/skills/browser/SKILL.md +120 -33
package/package.json
CHANGED
package/skills/browser/SKILL.md
CHANGED
|
@@ -1,83 +1,170 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: browser
|
|
3
|
-
description: Browser automation. Use when user needs to interact with websites, navigate pages, fill forms, click buttons, take screenshots, extract data, test web apps, or automate any browser task.
|
|
4
|
-
allowed-tools: Bash(exec:browser*)
|
|
3
|
+
description: Browser automation via playwriter. Use when user needs to interact with websites, navigate pages, fill forms, click buttons, take screenshots, extract data, test web apps, or automate any browser task.
|
|
4
|
+
allowed-tools: Bash(browser:*), Bash(exec:browser*)
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# Browser Automation
|
|
7
|
+
# Browser Automation with playwriter
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Two Pathways
|
|
10
|
+
|
|
11
|
+
**Session commands** (`browser:` prefix) — manage multi-step sessions via playwriter CLI. Each `browser:` block runs its commands sequentially.
|
|
12
|
+
|
|
13
|
+
**JS execution** (`exec:browser`) — run JavaScript directly against `page`. State persists across calls.
|
|
14
|
+
|
|
15
|
+
**CRITICAL**: Never mix these two pathways. Each `browser:` block is a separate Bash call. Each `exec:browser` block is a separate Bash call.
|
|
16
|
+
|
|
17
|
+
## Session Pathway (`browser:`)
|
|
18
|
+
|
|
19
|
+
Create a session first, use `--direct` for CDP mode (requires Chrome with remote debugging):
|
|
10
20
|
|
|
11
21
|
```
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
await snapshot({ page })
|
|
22
|
+
browser:
|
|
23
|
+
playwriter session new --direct
|
|
15
24
|
```
|
|
16
25
|
|
|
17
|
-
|
|
26
|
+
Returns a numeric session ID (e.g. `1`). Use that ID for all subsequent calls. **Each command must be a separate Bash call:**
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
browser:
|
|
30
|
+
playwriter -s 1 -e 'await page.goto("http://example.com")'
|
|
31
|
+
```
|
|
18
32
|
|
|
19
|
-
|
|
33
|
+
```
|
|
34
|
+
browser:
|
|
35
|
+
playwriter -s 1 -e 'await snapshot({ page })'
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
browser:
|
|
40
|
+
playwriter -s 1 -e 'await screenshotWithAccessibilityLabels({ page })'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
State persists across session calls:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
browser:
|
|
47
|
+
playwriter -s 1 -e 'state.x = 1'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
browser:
|
|
52
|
+
playwriter -s 1 -e 'console.log(state.x)'
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
List active sessions:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
browser:
|
|
59
|
+
playwriter session list
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**RULE**: The `-e` argument must use single quotes. The JS inside must use double quotes for strings.
|
|
63
|
+
|
|
64
|
+
**RULE**: Never chain multiple `playwriter` commands in one `browser:` block — run one command per block.
|
|
65
|
+
|
|
66
|
+
## JS Execution Pathway (`exec:browser`)
|
|
67
|
+
|
|
68
|
+
For direct page access, DOM queries, and data extraction. The runtime provides `page`, `snapshot`, `screenshotWithAccessibilityLabels`, and `state` as globals.
|
|
20
69
|
|
|
21
70
|
```
|
|
22
71
|
exec:browser
|
|
23
|
-
await page.goto('https://example.com
|
|
24
|
-
await snapshot({ page })
|
|
25
|
-
await page.fill('[name=email]', 'user@example.com')
|
|
26
|
-
await page.click('[type=submit]')
|
|
27
|
-
await page.waitForLoadState('networkidle')
|
|
72
|
+
await page.goto('https://example.com')
|
|
28
73
|
await snapshot({ page })
|
|
29
74
|
```
|
|
30
75
|
|
|
76
|
+
```
|
|
77
|
+
exec:browser
|
|
78
|
+
const title = await page.title()
|
|
79
|
+
console.log(title)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Never add shell quoting — write plain JavaScript directly.
|
|
83
|
+
|
|
84
|
+
## Core Workflow
|
|
85
|
+
|
|
86
|
+
1. **Create session**: `browser:\nplaywriter session new --direct`
|
|
87
|
+
2. **Navigate** (one call per command): `browser:\nplaywriter -s 1 -e 'await page.goto("url")'`
|
|
88
|
+
3. **Snapshot**: `browser:\nplaywriter -s 1 -e 'await snapshot({ page })'`
|
|
89
|
+
4. **Interact**: click, fill, type — each as a separate browser: call
|
|
90
|
+
5. **Extract data**: use `exec:browser` for JS queries
|
|
91
|
+
|
|
31
92
|
## Common Patterns
|
|
32
93
|
|
|
33
|
-
### Screenshot
|
|
94
|
+
### Screenshot
|
|
34
95
|
|
|
35
96
|
```
|
|
36
|
-
|
|
37
|
-
await screenshotWithAccessibilityLabels({ page })
|
|
97
|
+
browser:
|
|
98
|
+
playwriter -s 1 -e 'await screenshotWithAccessibilityLabels({ page })'
|
|
38
99
|
```
|
|
39
100
|
|
|
40
|
-
### Data Extraction
|
|
101
|
+
### Data Extraction (use exec:browser)
|
|
41
102
|
|
|
42
103
|
```
|
|
43
104
|
exec:browser
|
|
44
|
-
await page.goto('https://example.com/products')
|
|
45
105
|
const items = await page.$$eval('.product-title', els => els.map(e => e.textContent))
|
|
46
106
|
console.log(JSON.stringify(items))
|
|
47
107
|
```
|
|
48
108
|
|
|
49
|
-
###
|
|
109
|
+
### Console Monitoring (exec:browser)
|
|
50
110
|
|
|
51
111
|
```
|
|
52
112
|
exec:browser
|
|
53
|
-
state.
|
|
54
|
-
|
|
55
|
-
state.
|
|
113
|
+
state.consoleMsgs = []
|
|
114
|
+
page.on('console', msg => state.consoleMsgs.push({ type: msg.type(), text: msg.text() }))
|
|
115
|
+
page.on('pageerror', e => state.consoleMsgs.push({ type: 'error', text: e.message }))
|
|
56
116
|
```
|
|
57
117
|
|
|
58
118
|
```
|
|
59
119
|
exec:browser
|
|
60
|
-
console.log(
|
|
120
|
+
console.log(JSON.stringify(state.consoleMsgs))
|
|
61
121
|
```
|
|
62
122
|
|
|
63
|
-
### Console Monitoring
|
|
123
|
+
### Web Worker Console Monitoring
|
|
64
124
|
|
|
65
125
|
```
|
|
66
126
|
exec:browser
|
|
67
|
-
state.
|
|
68
|
-
|
|
69
|
-
|
|
127
|
+
state.workerMsgs = []
|
|
128
|
+
for (const w of page.workers()) {
|
|
129
|
+
w.evaluate(() => {
|
|
130
|
+
const o = console.log.bind(console)
|
|
131
|
+
console.log = (...a) => { o(...a) }
|
|
132
|
+
}).catch(() => {})
|
|
133
|
+
}
|
|
134
|
+
page.on('worker', w => {
|
|
135
|
+
state.workerMsgs.push('[worker] ' + w.url())
|
|
136
|
+
})
|
|
70
137
|
```
|
|
71
138
|
|
|
72
139
|
```
|
|
73
140
|
exec:browser
|
|
74
|
-
|
|
141
|
+
const workers = page.workers()
|
|
142
|
+
console.log('Workers:', workers.length, workers.map(w => w.url()).join(', '))
|
|
75
143
|
```
|
|
76
144
|
|
|
77
|
-
|
|
145
|
+
```
|
|
146
|
+
exec:browser
|
|
147
|
+
if (page.workers().length > 0) {
|
|
148
|
+
const r = await page.workers()[0].evaluate(() => JSON.stringify({ type: 'worker alive' }))
|
|
149
|
+
console.log(r)
|
|
150
|
+
}
|
|
151
|
+
```
|
|
78
152
|
|
|
79
|
-
|
|
153
|
+
### Access window.debug globals
|
|
80
154
|
|
|
81
|
-
|
|
155
|
+
```
|
|
156
|
+
exec:browser
|
|
157
|
+
const result = await page.evaluate(() => JSON.stringify({
|
|
158
|
+
entityCount: window.debug?.scene?.children?.length,
|
|
159
|
+
playerId: window.debug?.client?.playerId
|
|
160
|
+
}))
|
|
161
|
+
console.log(result)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Key Rules
|
|
82
165
|
|
|
83
|
-
|
|
166
|
+
- `browser:` prefix → playwriter session management (one command per block)
|
|
167
|
+
- `exec:browser` → JS in page context (multi-line JS allowed)
|
|
168
|
+
- Never mix pathways in the same Bash call
|
|
169
|
+
- `-e` argument: single quotes on outside, double quotes inside for JS strings
|
|
170
|
+
- One `playwriter` command per `browser:` block
|