fastbrowser_cli 1.0.2 → 1.0.4
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 +118 -0
- package/dist/fastbrowser_cli/fastbrowser_cli.d.ts +3 -0
- package/dist/fastbrowser_cli/fastbrowser_cli.d.ts.map +1 -0
- package/dist/fastbrowser_cli/fastbrowser_cli.js +288 -0
- package/dist/fastbrowser_cli/fastbrowser_cli.js.map +1 -0
- package/dist/fastbrowser_cli/libs/http-client.d.ts +7 -0
- package/dist/fastbrowser_cli/libs/http-client.d.ts.map +1 -0
- package/dist/fastbrowser_cli/libs/http-client.js +51 -0
- package/dist/fastbrowser_cli/libs/http-client.js.map +1 -0
- package/dist/fastbrowser_cli/libs/server-manager.d.ts +12 -0
- package/dist/fastbrowser_cli/libs/server-manager.d.ts.map +1 -0
- package/dist/fastbrowser_cli/libs/server-manager.js +194 -0
- package/dist/fastbrowser_cli/libs/server-manager.js.map +1 -0
- package/dist/fastbrowser_httpd/fastbrowser_httpd.d.ts +3 -0
- package/dist/fastbrowser_httpd/fastbrowser_httpd.d.ts.map +1 -0
- package/dist/fastbrowser_httpd/fastbrowser_httpd.js +82 -0
- package/dist/fastbrowser_httpd/fastbrowser_httpd.js.map +1 -0
- package/dist/fastbrowser_httpd/libs/routes.d.ts +6 -0
- package/dist/fastbrowser_httpd/libs/routes.d.ts.map +1 -0
- package/dist/fastbrowser_httpd/libs/routes.js +41 -0
- package/dist/fastbrowser_httpd/libs/routes.js.map +1 -0
- package/dist/fastbrowser_httpd/libs/tool-schemas.d.ts +72 -0
- package/dist/fastbrowser_httpd/libs/tool-schemas.d.ts.map +1 -0
- package/dist/fastbrowser_httpd/libs/tool-schemas.js +65 -0
- package/dist/fastbrowser_httpd/libs/tool-schemas.js.map +1 -0
- package/dist/fastbrowser_mcp/fastbrowser_mcp.d.ts +4 -0
- package/dist/fastbrowser_mcp/fastbrowser_mcp.d.ts.map +1 -0
- package/dist/fastbrowser_mcp/fastbrowser_mcp.js +417 -0
- package/dist/fastbrowser_mcp/fastbrowser_mcp.js.map +1 -0
- package/dist/fastbrowser_mcp/libs/mcp_client.d.ts +120 -0
- package/dist/fastbrowser_mcp/libs/mcp_client.d.ts.map +1 -0
- package/dist/fastbrowser_mcp/libs/mcp_client.js +83 -0
- package/dist/fastbrowser_mcp/libs/mcp_client.js.map +1 -0
- package/dist/fastbrowser_mcp/libs/mcp_proxy.d.ts +10 -0
- package/dist/fastbrowser_mcp/libs/mcp_proxy.d.ts.map +1 -0
- package/dist/fastbrowser_mcp/libs/mcp_proxy.js +45 -0
- package/dist/fastbrowser_mcp/libs/mcp_proxy.js.map +1 -0
- package/dist/fastbrowser_mcp/libs/schemas.d.ts +28 -0
- package/dist/fastbrowser_mcp/libs/schemas.d.ts.map +1 -0
- package/dist/fastbrowser_mcp/libs/schemas.js +38 -0
- package/dist/fastbrowser_mcp/libs/schemas.js.map +1 -0
- package/docs/brainstorm_scrap_by_ai.md +1 -1
- package/docs/feature_support_cli.md +27 -27
- package/package.json +7 -7
- package/{tmp/.claude/skills/fastweb → skills/fastbrowser}/SKILL.md +22 -22
- package/src/{fastweb_cli/fastweb_cli.ts → fastbrowser_cli/fastbrowser_cli.ts} +49 -15
- package/src/{fastweb_cli → fastbrowser_cli}/libs/http-client.ts +2 -2
- package/src/{fastweb_cli → fastbrowser_cli}/libs/server-manager.ts +8 -8
- package/src/{fastweb_http_server/fastweb_http_server.ts → fastbrowser_httpd/fastbrowser_httpd.ts} +10 -10
- package/src/{fastweb_http_server → fastbrowser_httpd}/libs/routes.ts +1 -1
- package/src/{fastweb_http_server → fastbrowser_httpd}/libs/tool-schemas.ts +4 -4
- package/src/{fastweb_mcp → fastbrowser_mcp}/libs/mcp_proxy.ts +1 -1
- package/src/{fastweb_mcp → fastbrowser_mcp}/libs/schemas.ts +1 -1
- package/tmp/.claude/.claude/settings.local.json +7 -0
- package/tmp/.claude/skills/fastbrowser/SKILL.md +214 -0
- /package/src/{fastweb_mcp/fastweb_mcp.ts → fastbrowser_mcp/fastbrowser_mcp.ts} +0 -0
- /package/src/{fastweb_mcp → fastbrowser_mcp}/libs/mcp_client.ts +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// local imports
|
|
2
|
-
import { ToolResponseSchema, type ToolResponse } from '../../
|
|
2
|
+
import { ToolResponseSchema, type ToolResponse } from '../../fastbrowser_httpd/libs/tool-schemas.js';
|
|
3
3
|
|
|
4
4
|
///////////////////////////////////////////////////////////////////////////////
|
|
5
5
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -10,7 +10,7 @@ import { ToolResponseSchema, type ToolResponse } from '../../fastweb_http_server
|
|
|
10
10
|
export class HttpClient {
|
|
11
11
|
static getServerUrl(overrideUrl: string | undefined): string {
|
|
12
12
|
if (overrideUrl !== undefined && overrideUrl !== '') return overrideUrl;
|
|
13
|
-
const envUrl = process.env.
|
|
13
|
+
const envUrl = process.env.FASTBROWSER_SERVER;
|
|
14
14
|
if (envUrl !== undefined && envUrl !== '') return envUrl;
|
|
15
15
|
return 'http://localhost:8787';
|
|
16
16
|
}
|
|
@@ -16,7 +16,7 @@ type PidFile = {
|
|
|
16
16
|
startedAt: string;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
const STATE_DIR = Path.join(Os.homedir(), '.
|
|
19
|
+
const STATE_DIR = Path.join(Os.homedir(), '.fastbrowser_cli');
|
|
20
20
|
const PID_FILE = Path.join(STATE_DIR, 'server.json');
|
|
21
21
|
const LOG_FILE = Path.join(STATE_DIR, 'server.log');
|
|
22
22
|
|
|
@@ -47,7 +47,7 @@ export class ServerManager {
|
|
|
47
47
|
if (state === 'running') return;
|
|
48
48
|
|
|
49
49
|
if (ServerManager.isLocalUrl(serverUrl) === false) {
|
|
50
|
-
throw new Error(`
|
|
50
|
+
throw new Error(`fastbrowser server at ${serverUrl} is not reachable and cannot be auto-started (non-local URL)`);
|
|
51
51
|
}
|
|
52
52
|
await ServerManager.start(serverUrl);
|
|
53
53
|
}
|
|
@@ -55,7 +55,7 @@ export class ServerManager {
|
|
|
55
55
|
static async start(serverUrl: string): Promise<void> {
|
|
56
56
|
const existing = await ServerManager.status(serverUrl);
|
|
57
57
|
if (existing === 'running') {
|
|
58
|
-
console.error(`
|
|
58
|
+
console.error(`fastbrowser server already running at ${serverUrl}`);
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -64,7 +64,7 @@ export class ServerManager {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
const port = ServerManager.parsePort(serverUrl);
|
|
67
|
-
const entryPath = Path.resolve(__dirname, '..', '..', '
|
|
67
|
+
const entryPath = Path.resolve(__dirname, '..', '..', 'fastbrowser_httpd', 'fastbrowser_httpd.ts');
|
|
68
68
|
const packageRoot = Path.resolve(__dirname, '..', '..', '..');
|
|
69
69
|
|
|
70
70
|
Fs.mkdirSync(STATE_DIR, { recursive: true });
|
|
@@ -81,7 +81,7 @@ export class ServerManager {
|
|
|
81
81
|
const pid = child.pid;
|
|
82
82
|
if (pid === undefined) {
|
|
83
83
|
Fs.closeSync(logFd);
|
|
84
|
-
throw new Error('Failed to spawn
|
|
84
|
+
throw new Error('Failed to spawn fastbrowser-httpd (no pid)');
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
const pidFile: PidFile = {
|
|
@@ -96,7 +96,7 @@ export class ServerManager {
|
|
|
96
96
|
const state = await ServerManager.status(serverUrl);
|
|
97
97
|
if (state === 'running') {
|
|
98
98
|
Fs.closeSync(logFd);
|
|
99
|
-
console.error(`
|
|
99
|
+
console.error(`fastbrowser server started (pid=${pid}, port=${port})`);
|
|
100
100
|
return;
|
|
101
101
|
}
|
|
102
102
|
await ServerManager.sleep(500);
|
|
@@ -104,7 +104,7 @@ export class ServerManager {
|
|
|
104
104
|
|
|
105
105
|
Fs.closeSync(logFd);
|
|
106
106
|
const tail = ServerManager.readLogTail(50);
|
|
107
|
-
throw new Error(`
|
|
107
|
+
throw new Error(`fastbrowser server did not become healthy within 10s. Log tail:\n${tail}`);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
static async stop(serverUrl: string): Promise<void> {
|
|
@@ -157,7 +157,7 @@ export class ServerManager {
|
|
|
157
157
|
console.error(`warning: process ${pid} killed but ${serverUrl} still responds to /health`);
|
|
158
158
|
return;
|
|
159
159
|
}
|
|
160
|
-
console.error('
|
|
160
|
+
console.error('fastbrowser server stopped');
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
private static isLocalUrl(serverUrl: string): boolean {
|
package/src/{fastweb_http_server/fastweb_http_server.ts → fastbrowser_httpd/fastbrowser_httpd.ts}
RENAMED
|
@@ -8,7 +8,7 @@ import { Command } from 'commander';
|
|
|
8
8
|
import express from 'express';
|
|
9
9
|
|
|
10
10
|
// local imports
|
|
11
|
-
import { McpClient } from '../
|
|
11
|
+
import { McpClient } from '../fastbrowser_mcp/libs/mcp_client.js';
|
|
12
12
|
import { Routes } from './libs/routes.js';
|
|
13
13
|
|
|
14
14
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -25,25 +25,25 @@ class MainHelper {
|
|
|
25
25
|
port: number;
|
|
26
26
|
verbose?: boolean;
|
|
27
27
|
}): Promise<void> {
|
|
28
|
-
// Spawn
|
|
29
|
-
const
|
|
28
|
+
// Spawn fastbrowser-mcp as a subprocess and hold a persistent MCP client to it.
|
|
29
|
+
const fastbrowserMcpEntry = Path.resolve(__dirname, '..', 'fastbrowser_mcp', 'fastbrowser_mcp.ts');
|
|
30
30
|
const mcpClient = new McpClient({
|
|
31
|
-
name: '
|
|
31
|
+
name: 'fastbrowser-httpd',
|
|
32
32
|
version: '1.0.0',
|
|
33
33
|
transport: {
|
|
34
34
|
type: 'stdio',
|
|
35
35
|
command: 'npx',
|
|
36
|
-
args: ['tsx',
|
|
36
|
+
args: ['tsx', fastbrowserMcpEntry, 'mcp_server'],
|
|
37
37
|
},
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
console.error('Connecting to
|
|
40
|
+
console.error('Connecting to fastbrowser-mcp ...');
|
|
41
41
|
await mcpClient.connect();
|
|
42
42
|
console.error('MCP client connected');
|
|
43
43
|
|
|
44
44
|
if (verbose) {
|
|
45
45
|
const tools = await mcpClient.listTools();
|
|
46
|
-
console.error('Tools available in
|
|
46
|
+
console.error('Tools available in fastbrowser-mcp:');
|
|
47
47
|
for (const tool of tools) {
|
|
48
48
|
console.error(`- ${tool.name}`);
|
|
49
49
|
}
|
|
@@ -54,7 +54,7 @@ class MainHelper {
|
|
|
54
54
|
Routes.register(app, mcpClient);
|
|
55
55
|
|
|
56
56
|
const server = app.listen(port, () => {
|
|
57
|
-
console.error(`
|
|
57
|
+
console.error(`fastbrowser-httpd listening on http://localhost:${port}`);
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
const shutdown = async (signal: string): Promise<void> => {
|
|
@@ -78,8 +78,8 @@ async function main(): Promise<void> {
|
|
|
78
78
|
const program = new Command();
|
|
79
79
|
|
|
80
80
|
program
|
|
81
|
-
.name('
|
|
82
|
-
.description('Persistent HTTP server fronting
|
|
81
|
+
.name('fastbrowser-httpd')
|
|
82
|
+
.description('Persistent HTTP server fronting fastbrowser-mcp')
|
|
83
83
|
.option('-p, --port <number>', 'Port to listen on', '8787')
|
|
84
84
|
.option('-v, --verbose', 'Enable verbose logging')
|
|
85
85
|
.action(async (opts: { port: string; verbose?: boolean }) => {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { Express, Request, Response } from 'express';
|
|
3
3
|
|
|
4
4
|
// local imports
|
|
5
|
-
import { McpClient } from '../../
|
|
5
|
+
import { McpClient } from '../../fastbrowser_mcp/libs/mcp_client.js';
|
|
6
6
|
import { TOOL_SCHEMAS, ToolResponseSchema } from './tool-schemas.js';
|
|
7
7
|
|
|
8
8
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
// local imports - reuse the authoritative query selector schemas
|
|
5
|
-
import { QuerySelectorsInputSchema, QuerySelectorsFirstInputSchema } from '../../
|
|
6
|
-
export type { QuerySelectorInput, QuerySelectorsInput, QuerySelectorFirstInput, QuerySelectorsFirstInput } from '../../
|
|
5
|
+
import { QuerySelectorsInputSchema, QuerySelectorsFirstInputSchema } from '../../fastbrowser_mcp/libs/schemas.js';
|
|
6
|
+
export type { QuerySelectorInput, QuerySelectorsInput, QuerySelectorFirstInput, QuerySelectorsFirstInput } from '../../fastbrowser_mcp/libs/schemas.js';
|
|
7
7
|
|
|
8
8
|
///////////////////////////////////////////////////////////////////////////////
|
|
9
9
|
///////////////////////////////////////////////////////////////////////////////
|
|
10
10
|
// Request schemas — one per tool. Shapes mirror what the underlying
|
|
11
|
-
//
|
|
11
|
+
// fastbrowser-mcp tools accept. For the proxied chrome-devtools-mcp tools,
|
|
12
12
|
// the shapes come from chrome-devtools-mcp's tool reference.
|
|
13
13
|
///////////////////////////////////////////////////////////////////////////////
|
|
14
14
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -85,7 +85,7 @@ export type ToolResponse = z.infer<typeof ToolResponseSchema>;
|
|
|
85
85
|
///////////////////////////////////////////////////////////////////////////////
|
|
86
86
|
|
|
87
87
|
// The REST route name (snake_case, matches the CLI command) is distinct from
|
|
88
|
-
// the underlying MCP tool name (which may be camelCase for
|
|
88
|
+
// the underlying MCP tool name (which may be camelCase for fastbrowser-mcp's own
|
|
89
89
|
// tools). `mcpToolName` is what we send over MCP; `routeName` is the URL path.
|
|
90
90
|
export type ToolSchemaEntry = {
|
|
91
91
|
routeName: string;
|
|
@@ -4,7 +4,7 @@ import { z } from 'zod';
|
|
|
4
4
|
///////////////////////////////////////////////////////////////////////////////
|
|
5
5
|
///////////////////////////////////////////////////////////////////////////////
|
|
6
6
|
// Authoritative query selector schemas — shared between the MCP server
|
|
7
|
-
// and the HTTP/CLI layer. Kept out of the
|
|
7
|
+
// and the HTTP/CLI layer. Kept out of the fastbrowser_mcp.ts entrypoint so
|
|
8
8
|
// importing the schemas does not execute the CLI's top-level `main()`.
|
|
9
9
|
///////////////////////////////////////////////////////////////////////////////
|
|
10
10
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fastbrowser
|
|
3
|
+
description: >
|
|
4
|
+
Control a live browser from the command line: navigate, click, fill forms, and query the accessibility tree with CSS-like selectors. Lighter alternative to Chrome DevTools MCP or Puppeteer. Triggers on: navigate/click/fill actions, page snapshots, or mentions of fastbrowser.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# fastbrowser Skill
|
|
8
|
+
|
|
9
|
+
`fastbrowser-cli` is a command-line client for the FastWeb HTTP server, which keeps a persistent
|
|
10
|
+
MCP connection to a Chrome browser alive so commands incur minimal latency. Each command
|
|
11
|
+
maps 1-to-1 to a FastWeb tool and returns the tool's response on stdout.
|
|
12
|
+
|
|
13
|
+
## Invocation
|
|
14
|
+
|
|
15
|
+
Run the CLI directly via `tsx`:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx fastbrowser_cli <command> [flags]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Typical Workflow
|
|
22
|
+
|
|
23
|
+
1. **Query** the accessibility tree for specific nodes: `query_selectors` (first match per selector) or `query_selectors_all` (every match per selector).
|
|
24
|
+
2. **Act** on an element by its accessibility selector: `click`, `fill_form`, `press_keys`. The selector can be a direct uid reference (e.g. `#1_42`, fastest path) or any CSS-like selector (e.g. `button[name="Submit"]`), which is resolved to a uid internally.
|
|
25
|
+
|
|
26
|
+
Snapshot output looks like:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
uid=1_0 RootWebArea "Example Domain" url="https://example.com/"
|
|
30
|
+
uid=1_1 heading "Example Domain" level="1"
|
|
31
|
+
uid=1_2 link "More information..." url="https://www.iana.org/..."
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Page Management
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# List all open browser pages
|
|
38
|
+
npx fastbrowser_cli list_pages
|
|
39
|
+
|
|
40
|
+
# Open a new page at a URL
|
|
41
|
+
npx fastbrowser_cli new_page --url https://example.com
|
|
42
|
+
|
|
43
|
+
# Close a page by its numeric id
|
|
44
|
+
npx fastbrowser_cli close_page --page-id 1
|
|
45
|
+
|
|
46
|
+
# Navigate the current page to a URL
|
|
47
|
+
npx fastbrowser_cli navigate_page --url https://example.com
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
## Selector Language
|
|
52
|
+
|
|
53
|
+
The selector syntax is modelled on CSS selectors, adapted for accessibility tree structures.
|
|
54
|
+
|
|
55
|
+
### Role selector
|
|
56
|
+
|
|
57
|
+
Matches nodes by their accessibility role.
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
button
|
|
61
|
+
link
|
|
62
|
+
comboxbox
|
|
63
|
+
searchbox
|
|
64
|
+
heading
|
|
65
|
+
WebArea
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Universal selector
|
|
69
|
+
|
|
70
|
+
Matches any node.
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
*
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### UID selector
|
|
77
|
+
|
|
78
|
+
Matches a node by its exact unique identifier.
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
#4
|
|
82
|
+
#1_3
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Attribute selectors
|
|
86
|
+
|
|
87
|
+
Attribute selectors match values inside `node.attributes`. The special virtual attribute `name` maps to `node.name`.
|
|
88
|
+
|
|
89
|
+
| Syntax | Semantics |
|
|
90
|
+
|--------|-----------|
|
|
91
|
+
| `[attr]` | attribute is present |
|
|
92
|
+
| `[attr="value"]` | exact match |
|
|
93
|
+
| `[attr^="prefix"]` | starts with |
|
|
94
|
+
| `[attr$="suffix"]` | ends with |
|
|
95
|
+
| `[attr*="sub"]` | contains substring |
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
link[href]
|
|
99
|
+
button[disabled="true"]
|
|
100
|
+
link[href^="https"]
|
|
101
|
+
link[href$=".com"]
|
|
102
|
+
link[href*="example"]
|
|
103
|
+
heading[name="Welcome"]
|
|
104
|
+
link[name="Click \"here\""]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Combinators
|
|
108
|
+
|
|
109
|
+
| Syntax | Semantics |
|
|
110
|
+
|--------|-----------|
|
|
111
|
+
| `A B` | B is a descendant of A (any depth) |
|
|
112
|
+
| `A > B` | B is a direct child of A |
|
|
113
|
+
| `A, B` | union — matches A or B |
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
WebArea link
|
|
117
|
+
main > button
|
|
118
|
+
heading, button
|
|
119
|
+
RootWebArea > link[href^="https"]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Examples
|
|
123
|
+
|
|
124
|
+
Sample accessibility tree:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
uid=1 WebArea "Main Page"
|
|
128
|
+
uid=2 main
|
|
129
|
+
uid=3 heading "Welcome"
|
|
130
|
+
uid=4 link "Click here" href="https://example.com"
|
|
131
|
+
uid=5 button "Submit" disabled="true"
|
|
132
|
+
uid=6 navigation
|
|
133
|
+
uid=7 link "Home" href="/"
|
|
134
|
+
uid=8 link "About" href="/about"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Example queries on it:
|
|
138
|
+
- `link` matches all the links (uid=4, uid=7, uid=8)
|
|
139
|
+
- 'navigation > link' matches only the links that are direct children of navigation (uid=7, uid=8)
|
|
140
|
+
- `link[href^="https"]` matches links with an external href (uid=4)
|
|
141
|
+
- `button[name="Submit"]` matches the submit button by name (uid=5)
|
|
142
|
+
- `*[disabled="true"]` matches any disabled element (uid=5)
|
|
143
|
+
- `heading, button` matches both headings and buttons in one query (uid=3, uid=5)
|
|
144
|
+
- `#7` matches a node by its UID (uid=7)
|
|
145
|
+
|
|
146
|
+
## Inspection
|
|
147
|
+
|
|
148
|
+
- `query_selectors` and `query_selectors_all` are the most efficient way to get specific elements or data from the page. Use them instead of `take_snapshot` whenever possible.
|
|
149
|
+
- Prefer `query_selectors` when you only need the first match per selector (cheaper, less output); use `query_selectors_all` when you need every match or want to cap with `--limit`.
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Query the accessibility tree returning the FIRST match per selector (--selector is repeatable)
|
|
153
|
+
npx fastbrowser_cli query_selectors --selector "button" --selector "link"
|
|
154
|
+
|
|
155
|
+
# Exclude ancestor nodes from the result
|
|
156
|
+
npx fastbrowser_cli query_selectors --selector 'heading[level="1"]' --no-with-ancestors
|
|
157
|
+
|
|
158
|
+
# Per-selector control over withAncestors via JSON
|
|
159
|
+
npx fastbrowser_cli query_selectors \
|
|
160
|
+
--selectors-json '[{"selector":"button","withAncestors":true},{"selector":"link","withAncestors":false}]'
|
|
161
|
+
|
|
162
|
+
# Query the accessibility tree returning ALL matches per selector (--selector is repeatable)
|
|
163
|
+
npx fastbrowser_cli query_selectors_all --selector "button" --selector "link" --limit 5
|
|
164
|
+
|
|
165
|
+
# Exclude ancestor nodes from the result
|
|
166
|
+
npx fastbrowser_cli query_selectors_all --selector 'heading[level="1"]' --no-with-ancestors
|
|
167
|
+
|
|
168
|
+
# Per-selector control over limit / withAncestors via JSON
|
|
169
|
+
npx fastbrowser_cli query_selectors_all \
|
|
170
|
+
--selectors-json '[{"selector":"button","limit":3,"withAncestors":true},{"selector":"link","limit":0,"withAncestors":false}]'
|
|
171
|
+
|
|
172
|
+
# Take an accessibility-tree full page snapshot of the current page - very expensive, prefer targeted queries when possible
|
|
173
|
+
npx fastbrowser_cli take_snapshot
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Interaction
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Click by a direct uid reference (fast path - no accessibility-tree lookup)
|
|
180
|
+
npx fastbrowser_cli click --selector "#1_42"
|
|
181
|
+
|
|
182
|
+
# Click by any CSS-like selector - resolved to a uid internally
|
|
183
|
+
npx fastbrowser_cli click -s 'button[name="Submit"]'
|
|
184
|
+
|
|
185
|
+
# Fill a single form field - selector can be a uid (#1_7) or any CSS-like selector
|
|
186
|
+
npx fastbrowser_cli fill_form -s 'textbox[name="Email"]' --value "hello@example.com"
|
|
187
|
+
|
|
188
|
+
# Press a comma-separated sequence of keys (literals and named keys both work)
|
|
189
|
+
npx fastbrowser_cli press_keys --keys "Tab, Tab, Enter"
|
|
190
|
+
npx fastbrowser_cli press_keys --keys "Hello, Tab, Enter"
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Command Reference
|
|
194
|
+
|
|
195
|
+
| Command | Purpose | Required flags |
|
|
196
|
+
|---------|---------|----------------|
|
|
197
|
+
| `list_pages` | List open browser pages | — |
|
|
198
|
+
| `new_page` | Open a new page at a URL | `--url` |
|
|
199
|
+
| `close_page` | Close a page by id | `--page-id` |
|
|
200
|
+
| `navigate_page` | Navigate current page to a URL | `--url` |
|
|
201
|
+
| `take_snapshot` | Dump the accessibility tree of the whole page - very expensive, prefer targeted queries (`query_selectors` / `query_selectors_all`) when possible | — |
|
|
202
|
+
| `query_selectors` | Query a11y tree by CSS-like selector, returning the first match per selector | `--selector` or `--selectors-json` |
|
|
203
|
+
| `query_selectors_all` | Query a11y tree by CSS-like selector, returning every match per selector | `--selector` or `--selectors-json` |
|
|
204
|
+
| `click` | Click an element by accessibility selector | `--selector` / `-s` |
|
|
205
|
+
| `fill_form` | Fill a form field by accessibility selector | `--selector` / `-s`, `--value` |
|
|
206
|
+
| `press_keys` | Press a comma-separated key sequence | `--keys` |
|
|
207
|
+
| `server start` | Start the HTTP server daemon | — |
|
|
208
|
+
| `server status` | Report server running/stopped | — |
|
|
209
|
+
| `server stop` | Stop the HTTP server | — |
|
|
210
|
+
|
|
211
|
+
## Output & Errors
|
|
212
|
+
|
|
213
|
+
Tool output is written to **stdout** — one line per response content part. On failure the
|
|
214
|
+
CLI writes `fastbrowser-cli error: <message>` to **stderr** and exits with code 1.
|
|
File without changes
|
|
File without changes
|