@saiden/browse 0.2.11 → 0.2.13-pre.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 +155 -98
- package/dist/browser.d.ts +67 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +525 -0
- package/dist/browser.js.map +1 -1
- package/dist/cli.js +4 -32
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +317 -0
- package/dist/mcp.js.map +1 -1
- package/dist/types.d.ts +173 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -5
package/README.md
CHANGED
|
@@ -6,96 +6,22 @@
|
|
|
6
6
|
[](https://nodejs.org)
|
|
7
7
|
|
|
8
8
|
#### Headless browser automation for Claude Code using Playwright WebKit.
|
|
9
|
-
## Installation
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
npm install @saiden/browse
|
|
13
|
-
npx playwright install webkit
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## CLI Usage
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
# Take a screenshot
|
|
20
|
-
browse https://example.com
|
|
21
|
-
|
|
22
|
-
# Custom viewport and output
|
|
23
|
-
browse -o page.png -w 1920 -h 1080 https://example.com
|
|
24
|
-
|
|
25
|
-
# Query elements
|
|
26
|
-
browse -q "a[href]" https://example.com
|
|
27
|
-
browse -q "img" -j https://example.com # JSON output
|
|
28
|
-
|
|
29
|
-
# Click and interact
|
|
30
|
-
browse -c "button.submit" https://example.com
|
|
31
|
-
browse -t "input[name=q]=hello" -c "button[type=submit]" https://google.com
|
|
32
|
-
|
|
33
|
-
# Chain actions
|
|
34
|
-
browse -c ".cookie-accept" -c "a.nav-link" -q "h1" https://example.com
|
|
35
|
-
|
|
36
|
-
# Interactive mode (visible browser)
|
|
37
|
-
browse -i --headed https://example.com
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Server Mode
|
|
41
|
-
|
|
42
|
-
Start a persistent browser server that accepts commands via HTTP:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
browse -s 3000 # headless
|
|
46
|
-
browse -s 3000 --headed # visible browser
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Send commands:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
# Navigate
|
|
53
|
-
curl -X POST localhost:3000 -d '{"cmd":"goto","url":"https://example.com"}'
|
|
54
|
-
|
|
55
|
-
# Click
|
|
56
|
-
curl -X POST localhost:3000 -d '{"cmd":"click","selector":"button.submit"}'
|
|
57
|
-
|
|
58
|
-
# Type
|
|
59
|
-
curl -X POST localhost:3000 -d '{"cmd":"type","selector":"#search","text":"hello"}'
|
|
60
|
-
|
|
61
|
-
# Query elements
|
|
62
|
-
curl -X POST localhost:3000 -d '{"cmd":"query","selector":"a[href]"}'
|
|
63
|
-
|
|
64
|
-
# Screenshot
|
|
65
|
-
curl -X POST localhost:3000 -d '{"cmd":"screenshot","path":"page.png"}'
|
|
66
|
-
|
|
67
|
-
# Get current URL
|
|
68
|
-
curl -X POST localhost:3000 -d '{"cmd":"url"}'
|
|
69
|
-
|
|
70
|
-
# Get page HTML
|
|
71
|
-
curl -X POST localhost:3000 -d '{"cmd":"html"}'
|
|
72
|
-
|
|
73
|
-
# Navigation
|
|
74
|
-
curl -X POST localhost:3000 -d '{"cmd":"back"}'
|
|
75
|
-
curl -X POST localhost:3000 -d '{"cmd":"forward"}'
|
|
76
|
-
curl -X POST localhost:3000 -d '{"cmd":"reload"}'
|
|
77
|
-
|
|
78
|
-
# Wait
|
|
79
|
-
curl -X POST localhost:3000 -d '{"cmd":"wait","ms":2000}'
|
|
80
|
-
|
|
81
|
-
# Close server
|
|
82
|
-
curl -X POST localhost:3000 -d '{"cmd":"close"}'
|
|
83
|
-
```
|
|
84
|
-
|
|
85
9
|
## Claude Code Plugin (Recommended)
|
|
86
10
|
|
|
87
11
|
Install as a Claude Code plugin for the best integration:
|
|
88
12
|
|
|
89
13
|
```bash
|
|
90
|
-
#
|
|
14
|
+
# Add the saiden marketplace (one-time)
|
|
91
15
|
claude plugin marketplace add https://github.com/saiden-dev/claude-plugins
|
|
92
|
-
claude plugin install browse
|
|
93
16
|
|
|
94
|
-
#
|
|
95
|
-
claude plugin install
|
|
17
|
+
# Install the plugin
|
|
18
|
+
claude plugin install browse@saiden
|
|
19
|
+
|
|
20
|
+
# Update to latest version
|
|
21
|
+
claude plugin marketplace update saiden && claude plugin update browse@saiden
|
|
96
22
|
```
|
|
97
23
|
|
|
98
|
-
**Prerequisites:** Node.js 18
|
|
24
|
+
**Prerequisites:** Node.js 18+, Playwright WebKit (`npx playwright install webkit`)
|
|
99
25
|
|
|
100
26
|
### Plugin Features
|
|
101
27
|
|
|
@@ -124,6 +50,39 @@ claude plugin install github:saiden-dev/browse
|
|
|
124
50
|
| `@browse:browser://html/full` | Complete page HTML |
|
|
125
51
|
| `@browse:browser://screenshot` | Page screenshot as base64 PNG |
|
|
126
52
|
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Installation (npm)
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm install @saiden/browse
|
|
59
|
+
npx playwright install webkit
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## CLI Usage
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Take a screenshot
|
|
66
|
+
browse https://example.com
|
|
67
|
+
|
|
68
|
+
# Custom viewport and output
|
|
69
|
+
browse -o page.png -w 1920 -h 1080 https://example.com
|
|
70
|
+
|
|
71
|
+
# Query elements
|
|
72
|
+
browse -q "a[href]" https://example.com
|
|
73
|
+
browse -q "img" -j https://example.com # JSON output
|
|
74
|
+
|
|
75
|
+
# Click and interact
|
|
76
|
+
browse -c "button.submit" https://example.com
|
|
77
|
+
browse -t "input[name=q]=hello" -c "button[type=submit]" https://google.com
|
|
78
|
+
|
|
79
|
+
# Chain actions
|
|
80
|
+
browse -c ".cookie-accept" -c "a.nav-link" -q "h1" https://example.com
|
|
81
|
+
|
|
82
|
+
# Interactive mode (visible browser)
|
|
83
|
+
browse -i --headed https://example.com
|
|
84
|
+
```
|
|
85
|
+
|
|
127
86
|
## MCP Server (Standalone)
|
|
128
87
|
|
|
129
88
|
Use with any MCP-compatible client:
|
|
@@ -145,16 +104,86 @@ Add to Claude Code's MCP config (`~/.claude/settings.json`):
|
|
|
145
104
|
}
|
|
146
105
|
```
|
|
147
106
|
|
|
148
|
-
|
|
107
|
+
### MCP Tools Reference
|
|
108
|
+
|
|
109
|
+
**Navigation & Interaction:**
|
|
110
|
+
| Tool | Description |
|
|
111
|
+
|------|-------------|
|
|
112
|
+
| `goto` | Navigate to a URL |
|
|
113
|
+
| `click` | Click on an element |
|
|
114
|
+
| `type` | Type text into an input field |
|
|
115
|
+
| `hover` | Hover over an element |
|
|
116
|
+
| `select` | Select option(s) in a dropdown |
|
|
117
|
+
| `keys` | Send keyboard shortcuts (e.g., "Enter", "Control+a") |
|
|
118
|
+
| `scroll` | Scroll page or element into view |
|
|
119
|
+
| `upload` | Upload files to a file input |
|
|
120
|
+
| `back`, `forward`, `reload` | Browser navigation |
|
|
121
|
+
| `wait` | Wait for a specified time |
|
|
122
|
+
| `close` | Close the browser and end session |
|
|
123
|
+
|
|
124
|
+
**Debugging & Inspection:**
|
|
125
|
+
| Tool | Description |
|
|
126
|
+
|------|-------------|
|
|
127
|
+
| `console` | Get captured console messages (log, warn, error, etc.) |
|
|
128
|
+
| `errors` | Get page errors (uncaught exceptions) |
|
|
129
|
+
| `network` | Get captured network requests/responses |
|
|
130
|
+
| `intercept` | Block or mock network requests |
|
|
131
|
+
| `metrics` | Get performance metrics and DOM statistics |
|
|
132
|
+
| `a11y` | Get accessibility tree snapshot |
|
|
133
|
+
|
|
134
|
+
**Page Content:**
|
|
135
|
+
| Tool | Description |
|
|
136
|
+
|------|-------------|
|
|
137
|
+
| `query` | Query elements by CSS selector |
|
|
138
|
+
| `screenshot` | Take a screenshot |
|
|
139
|
+
| `url` | Get current URL and title |
|
|
140
|
+
| `html` | Get page HTML content |
|
|
141
|
+
| `eval` | Execute JavaScript in browser context |
|
|
142
|
+
|
|
143
|
+
**Storage & Session:**
|
|
144
|
+
| Tool | Description |
|
|
145
|
+
|------|-------------|
|
|
146
|
+
| `cookies` | Get, set, delete, or clear cookies |
|
|
147
|
+
| `storage` | Access localStorage or sessionStorage |
|
|
148
|
+
| `dialog` | Configure how browser dialogs are handled |
|
|
149
|
+
| `session_save` | Save session state to file |
|
|
150
|
+
| `session_restore` | Restore session from file |
|
|
151
|
+
|
|
152
|
+
**Viewport & Emulation:**
|
|
153
|
+
| Tool | Description |
|
|
154
|
+
|------|-------------|
|
|
155
|
+
| `viewport` | Resize browser viewport |
|
|
156
|
+
| `emulate` | Emulate a mobile device |
|
|
157
|
+
|
|
158
|
+
**Image Processing:**
|
|
159
|
+
| Tool | Description |
|
|
160
|
+
|------|-------------|
|
|
161
|
+
| `favicon` | Generate favicon set from image |
|
|
162
|
+
| `convert` | Convert image format |
|
|
163
|
+
| `resize` | Resize image |
|
|
164
|
+
| `crop` | Crop image |
|
|
165
|
+
| `compress` | Compress image |
|
|
166
|
+
| `thumbnail` | Create thumbnail |
|
|
167
|
+
|
|
168
|
+
### MCP Resources
|
|
149
169
|
|
|
150
|
-
|
|
170
|
+
| Resource | Description |
|
|
171
|
+
|----------|-------------|
|
|
172
|
+
| `browser://state` | Browser state (URL, title, launched) |
|
|
173
|
+
| `browser://html` | Page HTML (truncated to 10KB) |
|
|
174
|
+
| `browser://html/full` | Complete page HTML |
|
|
175
|
+
| `browser://console` | Captured console messages |
|
|
176
|
+
| `browser://network` | All network requests |
|
|
177
|
+
| `browser://network/failed` | Failed requests only |
|
|
178
|
+
| `browser://errors` | Page errors |
|
|
179
|
+
| `browser://a11y` | Accessibility tree |
|
|
180
|
+
| `browser://screenshot` | Page screenshot as base64 PNG |
|
|
151
181
|
|
|
152
182
|
## Programmatic Usage
|
|
153
183
|
|
|
154
184
|
```typescript
|
|
155
|
-
import { ClaudeBrowser
|
|
185
|
+
import { ClaudeBrowser } from '@saiden/browse';
|
|
156
186
|
|
|
157
|
-
// Direct browser control
|
|
158
187
|
const browser = new ClaudeBrowser({
|
|
159
188
|
headless: true,
|
|
160
189
|
width: 1280,
|
|
@@ -172,36 +201,64 @@ await browser.type('#input', 'hello');
|
|
|
172
201
|
await browser.screenshot('page.png');
|
|
173
202
|
|
|
174
203
|
await browser.close();
|
|
175
|
-
|
|
176
|
-
// Or start a server
|
|
177
|
-
const server = await startServer({ port: 3000, headless: false });
|
|
178
|
-
// Server runs until closed via HTTP or SIGINT
|
|
179
204
|
```
|
|
180
205
|
|
|
181
206
|
## API
|
|
182
207
|
|
|
183
208
|
### ClaudeBrowser
|
|
184
209
|
|
|
210
|
+
**Lifecycle:**
|
|
185
211
|
- `launch()` - Launch the browser
|
|
186
212
|
- `close()` - Close the browser
|
|
213
|
+
- `newPage()` - Open new page
|
|
214
|
+
|
|
215
|
+
**Navigation:**
|
|
187
216
|
- `goto(url)` - Navigate to URL
|
|
217
|
+
- `back()` / `forward()` / `reload()` - Browser navigation
|
|
218
|
+
- `wait(ms)` - Wait for timeout
|
|
219
|
+
|
|
220
|
+
**Interaction:**
|
|
188
221
|
- `click(selector)` - Click element
|
|
189
222
|
- `type(selector, text)` - Type into input
|
|
223
|
+
- `hover(selector)` - Hover over element
|
|
224
|
+
- `select(selector, value)` - Select dropdown option(s)
|
|
225
|
+
- `keys(keys)` - Press keyboard keys
|
|
226
|
+
- `scroll(selector?, x?, y?)` - Scroll page or element
|
|
227
|
+
- `upload(selector, files)` - Upload files
|
|
228
|
+
|
|
229
|
+
**Content:**
|
|
190
230
|
- `query(selector)` - Query elements, returns attributes
|
|
191
231
|
- `screenshot(path?, fullPage?)` - Take screenshot
|
|
192
232
|
- `getUrl()` - Get current URL and title
|
|
193
233
|
- `getHtml(full?)` - Get page HTML
|
|
194
|
-
- `
|
|
195
|
-
|
|
196
|
-
|
|
234
|
+
- `eval(script)` - Execute JavaScript
|
|
235
|
+
|
|
236
|
+
**Debugging:**
|
|
237
|
+
- `getConsole(level?, clear?)` - Get console messages
|
|
238
|
+
- `getErrors(clear?)` - Get page errors
|
|
239
|
+
- `getNetwork(filter?, clear?)` - Get network requests
|
|
240
|
+
- `getMetrics(includeResources?)` - Get performance metrics
|
|
241
|
+
- `getA11y(selector?)` - Get accessibility tree
|
|
242
|
+
|
|
243
|
+
**Storage:**
|
|
244
|
+
- `getCookies(name?)` - Get cookies
|
|
245
|
+
- `setCookie(name, value, url?)` - Set cookie
|
|
246
|
+
- `deleteCookie(name)` / `clearCookies()` - Remove cookies
|
|
247
|
+
- `getStorage(type, key?)` - Get localStorage/sessionStorage
|
|
248
|
+
- `setStorage(type, key, value)` - Set storage item
|
|
249
|
+
- `deleteStorage(type, key)` / `clearStorage(type)` - Remove storage
|
|
250
|
+
|
|
251
|
+
**Interception:**
|
|
252
|
+
- `addIntercept(pattern, action, response?)` - Block or mock requests
|
|
253
|
+
- `clearIntercepts()` - Remove all intercepts
|
|
254
|
+
|
|
255
|
+
**Viewport:**
|
|
256
|
+
- `setViewport(width, height)` - Resize viewport
|
|
257
|
+
- `emulate(device)` - Emulate device (e.g., 'iPhone 13')
|
|
258
|
+
|
|
259
|
+
**Commands:**
|
|
197
260
|
- `executeCommand(cmd)` - Execute a command object
|
|
198
261
|
|
|
199
|
-
### BrowserServer
|
|
200
|
-
|
|
201
|
-
- `start()` - Start HTTP server
|
|
202
|
-
- `stop()` - Stop server and close browser
|
|
203
|
-
- `getPort()` - Get server port
|
|
204
|
-
|
|
205
262
|
## License
|
|
206
263
|
|
|
207
264
|
MIT
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import { type BrowserContext, type Page } from 'playwright';
|
|
2
|
-
import type { BrowserCommand, BrowserOptions, CommandResponse, ElementInfo } from './types.js';
|
|
2
|
+
import type { A11yNode, BrowserCommand, BrowserOptions, CommandResponse, ConsoleMessage, DialogEntry, ElementInfo, MetricsData, NetworkEntry, PageError } from './types.js';
|
|
3
3
|
export declare class ClaudeBrowser {
|
|
4
4
|
private browser;
|
|
5
5
|
private context;
|
|
6
6
|
private page;
|
|
7
7
|
private options;
|
|
8
|
+
private consoleMessages;
|
|
9
|
+
private networkEntries;
|
|
10
|
+
private pageErrors;
|
|
11
|
+
private dialogHistory;
|
|
12
|
+
private dialogConfig;
|
|
13
|
+
private interceptPatterns;
|
|
8
14
|
constructor(options?: BrowserOptions);
|
|
9
15
|
launch(): Promise<void>;
|
|
16
|
+
private setupErrorListener;
|
|
17
|
+
private setupDialogListener;
|
|
18
|
+
private setupConsoleListener;
|
|
19
|
+
private setupNetworkListener;
|
|
10
20
|
close(): Promise<void>;
|
|
11
21
|
private ensurePage;
|
|
12
22
|
/** Get the current page instance (for advanced usage) */
|
|
@@ -43,6 +53,62 @@ export declare class ClaudeBrowser {
|
|
|
43
53
|
wait(ms?: number): Promise<void>;
|
|
44
54
|
newPage(): Promise<void>;
|
|
45
55
|
eval(script: string): Promise<unknown>;
|
|
56
|
+
getConsole(level?: string, clear?: boolean): ConsoleMessage[];
|
|
57
|
+
clearConsole(): void;
|
|
58
|
+
getNetwork(filter?: string, clear?: boolean): NetworkEntry[];
|
|
59
|
+
clearNetwork(): void;
|
|
60
|
+
getErrors(clear?: boolean): PageError[];
|
|
61
|
+
clearErrors(): void;
|
|
62
|
+
getMetrics(includeResources?: boolean): Promise<MetricsData>;
|
|
63
|
+
getA11y(selector?: string): Promise<A11yNode | null>;
|
|
64
|
+
getDialogs(): DialogEntry[];
|
|
65
|
+
clearDialogs(): void;
|
|
66
|
+
setDialogConfig(config: {
|
|
67
|
+
autoAccept?: boolean;
|
|
68
|
+
autoDismiss?: boolean;
|
|
69
|
+
text?: string;
|
|
70
|
+
}): void;
|
|
71
|
+
getDialogConfig(): {
|
|
72
|
+
autoAccept: boolean;
|
|
73
|
+
autoDismiss: boolean;
|
|
74
|
+
};
|
|
75
|
+
addIntercept(pattern: string, action: 'block' | 'mock', response?: {
|
|
76
|
+
status?: number;
|
|
77
|
+
body?: string;
|
|
78
|
+
contentType?: string;
|
|
79
|
+
}): Promise<void>;
|
|
80
|
+
private handleIntercept;
|
|
81
|
+
clearIntercepts(): Promise<void>;
|
|
82
|
+
getInterceptPatterns(): string[];
|
|
83
|
+
getCookies(name?: string): Promise<Array<{
|
|
84
|
+
name: string;
|
|
85
|
+
value: string;
|
|
86
|
+
domain: string;
|
|
87
|
+
path: string;
|
|
88
|
+
}>>;
|
|
89
|
+
setCookie(name: string, value: string, url?: string): Promise<void>;
|
|
90
|
+
deleteCookie(name: string): Promise<void>;
|
|
91
|
+
clearCookies(): Promise<void>;
|
|
92
|
+
getStorage(type: 'local' | 'session', key?: string): Promise<Record<string, string>>;
|
|
93
|
+
setStorage(type: 'local' | 'session', key: string, value: string): Promise<void>;
|
|
94
|
+
deleteStorage(type: 'local' | 'session', key: string): Promise<void>;
|
|
95
|
+
clearStorage(type: 'local' | 'session'): Promise<void>;
|
|
96
|
+
hover(selector: string): Promise<void>;
|
|
97
|
+
select(selector: string, value: string | string[]): Promise<string[]>;
|
|
98
|
+
keys(keys: string): Promise<void>;
|
|
99
|
+
upload(selector: string, files: string[]): Promise<void>;
|
|
100
|
+
scroll(selector?: string, x?: number, y?: number): Promise<void>;
|
|
101
|
+
setViewport(width: number, height: number): Promise<{
|
|
102
|
+
width: number;
|
|
103
|
+
height: number;
|
|
104
|
+
}>;
|
|
105
|
+
emulate(device: string): Promise<{
|
|
106
|
+
width: number;
|
|
107
|
+
height: number;
|
|
108
|
+
}>;
|
|
109
|
+
private handleDialogCommand;
|
|
110
|
+
private handleCookiesCommand;
|
|
111
|
+
private handleStorageCommand;
|
|
46
112
|
executeCommand(cmd: BrowserCommand): Promise<CommandResponse>;
|
|
47
113
|
}
|
|
48
114
|
//# sourceMappingURL=browser.d.ts.map
|
package/dist/browser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,cAAc,EAAE,KAAK,IAAI,
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}
|