fastbrowser_cli 1.0.10 → 1.0.12
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 +4 -1
- package/dist/fastbrowser_cli/fastbrowser_cli.js +177 -188
- package/dist/fastbrowser_cli/fastbrowser_cli.js.map +1 -1
- package/package.json +6 -1
- package/src/fastbrowser_cli/fastbrowser_cli.ts +193 -207
- package/tmp/.claude/.claude/settings.local.json +0 -7
- package/tmp/.claude/settings.local.json +0 -7
- /package/tmp/{.claude → dotclaude}/skills/fastbrowser/SKILL.md +0 -0
package/README.md
CHANGED
|
@@ -5,6 +5,8 @@ Control a live Chrome browser from the command line: navigate, click, fill forms
|
|
|
5
5
|
A lighter alternative to Chrome DevTools MCP or Puppeteer, designed for AI agents and shell workflows. A persistent HTTP daemon keeps an MCP connection to the browser alive so each command incurs minimal latency.
|
|
6
6
|
|
|
7
7
|
- rely on [chrome-devtools-mcp](https://github.com/ChromeDevTools/chrome-devtools-mcp) for robust browser control
|
|
8
|
+
- rely on [a11y_parse](https://github.com/jeromeetienne/skillmd_collection/tree/main/packages/a11y_parse) for accessibility tree parsing and querying.
|
|
9
|
+
Especially a CSS-like selector syntax optimized for the accessibility tree.
|
|
8
10
|
- expose a curated, efficient toolset optimized for AI agent use cases
|
|
9
11
|
- minimize the required round-trips and boilerplate to perform common tasks
|
|
10
12
|
- minimize the output size, thus reducing LLM input size and parsing complexity.
|
|
@@ -32,7 +34,7 @@ npm install -g fastbrowser_cli
|
|
|
32
34
|
Or install just the SKILL.md into an agent folder so an AI agent can use it:
|
|
33
35
|
|
|
34
36
|
```bash
|
|
35
|
-
npx fastbrowser_cli
|
|
37
|
+
npx fastbrowser_cli install <skill-folder>
|
|
36
38
|
```
|
|
37
39
|
|
|
38
40
|
This copies `SKILL.md` to `<skill-folder>/skills/fastbrowser/SKILL.md`.
|
|
@@ -64,6 +66,7 @@ npx fastbrowser_cli click -s 'link[name="More information..."]'
|
|
|
64
66
|
| `click` | Click an element by accessibility selector | `-s, --selector` |
|
|
65
67
|
| `fill_form` | Fill a form field by accessibility selector | `-s, --selector`, `--value` |
|
|
66
68
|
| `press_keys` | Press a comma-separated key sequence | `--keys` |
|
|
69
|
+
| `install [skill-folder]` | Install SKILL.md into `<skill-folder>/skills/fastbrowser` (default: `.`) | — |
|
|
67
70
|
| `server start` | Start the HTTP daemon | — |
|
|
68
71
|
| `server status` | Report daemon running/stopped | — |
|
|
69
72
|
| `server stop` | Stop the HTTP daemon | — |
|
|
@@ -4,13 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
5
|
};
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
// node imports
|
|
8
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
-
// npm imports
|
|
11
9
|
const commander_1 = require("commander");
|
|
12
10
|
const string_argv_1 = __importDefault(require("string-argv"));
|
|
13
|
-
// local imports
|
|
14
11
|
const http_client_js_1 = require("./libs/http-client.js");
|
|
15
12
|
const server_manager_js_1 = require("./libs/server-manager.js");
|
|
16
13
|
class SilentExitError extends Error {
|
|
@@ -18,123 +15,175 @@ class SilentExitError extends Error {
|
|
|
18
15
|
super('silent-exit');
|
|
19
16
|
}
|
|
20
17
|
}
|
|
21
|
-
function getServerFromCmd(cmd) {
|
|
22
|
-
const globalOpts = cmd.optsWithGlobals();
|
|
23
|
-
return http_client_js_1.HttpClient.getServerUrl(globalOpts.server);
|
|
24
|
-
}
|
|
25
|
-
function getAutostartFromCmd(cmd) {
|
|
26
|
-
const globalOpts = cmd.optsWithGlobals();
|
|
27
|
-
return globalOpts.autostart !== false;
|
|
28
|
-
}
|
|
29
|
-
async function runTool(cmd, routeName, body) {
|
|
30
|
-
const server = getServerFromCmd(cmd);
|
|
31
|
-
if (getAutostartFromCmd(cmd) === true) {
|
|
32
|
-
await server_manager_js_1.ServerManager.ensureRunning(server);
|
|
33
|
-
}
|
|
34
|
-
const response = await http_client_js_1.HttpClient.postTool(server, routeName, body);
|
|
35
|
-
http_client_js_1.HttpClient.printResponse(response);
|
|
36
|
-
}
|
|
37
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
38
18
|
///////////////////////////////////////////////////////////////////////////////
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
19
|
+
class MainHelper {
|
|
20
|
+
static getServerFromCmd(cmd) {
|
|
21
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
22
|
+
return http_client_js_1.HttpClient.getServerUrl(globalOpts.server);
|
|
23
|
+
}
|
|
24
|
+
static getAutostartFromCmd(cmd) {
|
|
25
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
26
|
+
return globalOpts.autostart !== false;
|
|
27
|
+
}
|
|
28
|
+
static async runTool(cmd, routeName, body) {
|
|
29
|
+
const server = MainHelper.getServerFromCmd(cmd);
|
|
30
|
+
if (MainHelper.getAutostartFromCmd(cmd) === true) {
|
|
31
|
+
await server_manager_js_1.ServerManager.ensureRunning(server);
|
|
47
32
|
}
|
|
48
|
-
|
|
49
|
-
|
|
33
|
+
const response = await http_client_js_1.HttpClient.postTool(server, routeName, body);
|
|
34
|
+
http_client_js_1.HttpClient.printResponse(response);
|
|
35
|
+
}
|
|
36
|
+
static buildQuerySelectorsBody(opts) {
|
|
37
|
+
if (opts.selectorsJson !== undefined && opts.selectorsJson !== '') {
|
|
38
|
+
let parsed;
|
|
39
|
+
try {
|
|
40
|
+
parsed = JSON.parse(opts.selectorsJson);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
throw new Error(`--selectors-json is not valid JSON: ${err.message}`);
|
|
44
|
+
}
|
|
45
|
+
if (Array.isArray(parsed) === false) {
|
|
46
|
+
throw new Error('--selectors-json must be a JSON array');
|
|
47
|
+
}
|
|
48
|
+
return { selectors: parsed };
|
|
50
49
|
}
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
const selectorList = opts.selector ?? [];
|
|
51
|
+
if (selectorList.length === 0) {
|
|
52
|
+
throw new Error('At least one --selector or --selectors-json is required');
|
|
53
53
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
const limit = opts.limit === undefined ? 0 : Number.parseInt(opts.limit, 10);
|
|
55
|
+
if (Number.isNaN(limit) === true) {
|
|
56
|
+
throw new Error(`Invalid --limit: ${opts.limit}`);
|
|
57
|
+
}
|
|
58
|
+
const withAncestors = opts.withAncestors !== false;
|
|
59
|
+
const selectors = selectorList.map((selector) => ({
|
|
60
|
+
selector,
|
|
61
|
+
limit,
|
|
62
|
+
withAncestors,
|
|
63
|
+
}));
|
|
64
|
+
return { selectors };
|
|
59
65
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
static buildQuerySelectorFirstBody(opts) {
|
|
67
|
+
if (opts.selectorsJson !== undefined && opts.selectorsJson !== '') {
|
|
68
|
+
let parsed;
|
|
69
|
+
try {
|
|
70
|
+
parsed = JSON.parse(opts.selectorsJson);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
throw new Error(`--selectors-json is not valid JSON: ${err.message}`);
|
|
74
|
+
}
|
|
75
|
+
if (Array.isArray(parsed) === false) {
|
|
76
|
+
throw new Error('--selectors-json must be a JSON array');
|
|
77
|
+
}
|
|
78
|
+
return { selectors: parsed };
|
|
79
|
+
}
|
|
80
|
+
const selectorList = opts.selector ?? [];
|
|
81
|
+
if (selectorList.length === 0) {
|
|
82
|
+
throw new Error('At least one --selector or --selectors-json is required');
|
|
83
|
+
}
|
|
84
|
+
const withAncestors = opts.withAncestors !== false;
|
|
85
|
+
const selectors = selectorList.map((selector) => ({
|
|
86
|
+
selector,
|
|
87
|
+
withAncestors,
|
|
88
|
+
}));
|
|
89
|
+
return { selectors };
|
|
63
90
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
withAncestors,
|
|
69
|
-
}));
|
|
70
|
-
return { selectors };
|
|
71
|
-
}
|
|
72
|
-
function buildQuerySelectorFirstBody(opts) {
|
|
73
|
-
if (opts.selectorsJson !== undefined && opts.selectorsJson !== '') {
|
|
74
|
-
let parsed;
|
|
91
|
+
static async runInstall(skillFolder) {
|
|
92
|
+
const sourceSkillMd = node_path_1.default.resolve(__dirname, '../../skills/fastbrowser/SKILL.md');
|
|
93
|
+
const targetDir = node_path_1.default.resolve(skillFolder, 'skills', 'fastbrowser');
|
|
94
|
+
const targetSkillMd = node_path_1.default.join(targetDir, 'SKILL.md');
|
|
75
95
|
try {
|
|
76
|
-
|
|
96
|
+
await node_fs_1.default.promises.mkdir(targetDir, { recursive: true });
|
|
97
|
+
await node_fs_1.default.promises.copyFile(sourceSkillMd, targetSkillMd);
|
|
98
|
+
console.log(`Installed fastbrowser SKILL.md at ${targetSkillMd}`);
|
|
77
99
|
}
|
|
78
100
|
catch (err) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
throw new Error('--selectors-json must be a JSON array');
|
|
101
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
102
|
+
console.error(`fastbrowser-cli error: ${message}`);
|
|
103
|
+
process.exit(1);
|
|
83
104
|
}
|
|
84
|
-
return { selectors: parsed };
|
|
85
105
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
106
|
+
static async readBatchSource(file, inlineScript) {
|
|
107
|
+
if (inlineScript !== undefined && inlineScript !== '') {
|
|
108
|
+
return inlineScript;
|
|
109
|
+
}
|
|
110
|
+
if (file !== undefined && file !== '') {
|
|
111
|
+
return await node_fs_1.default.promises.readFile(file, 'utf-8');
|
|
112
|
+
}
|
|
113
|
+
if (process.stdin.isTTY === true) {
|
|
114
|
+
throw new Error('batch: no input. Provide a file path, --script, or pipe commands on stdin.');
|
|
115
|
+
}
|
|
116
|
+
return await MainHelper.readStdinToString();
|
|
89
117
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
98
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
99
|
-
//
|
|
100
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
101
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
102
|
-
async function runInstall(skillFolder) {
|
|
103
|
-
const sourceSkillMd = node_path_1.default.resolve(__dirname, '../../skills/fastbrowser/SKILL.md');
|
|
104
|
-
const targetDir = node_path_1.default.resolve(skillFolder, 'skills', 'fastbrowser');
|
|
105
|
-
const targetSkillMd = node_path_1.default.join(targetDir, 'SKILL.md');
|
|
106
|
-
try {
|
|
107
|
-
await node_fs_1.default.promises.mkdir(targetDir, { recursive: true });
|
|
108
|
-
await node_fs_1.default.promises.copyFile(sourceSkillMd, targetSkillMd);
|
|
109
|
-
console.log(`Installed fastbrowser SKILL.md at ${targetSkillMd}`);
|
|
118
|
+
static async readStdinToString() {
|
|
119
|
+
const chunks = [];
|
|
120
|
+
return await new Promise((resolve, reject) => {
|
|
121
|
+
process.stdin.on('data', (chunk) => chunks.push(chunk));
|
|
122
|
+
process.stdin.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
|
|
123
|
+
process.stdin.on('error', (err) => reject(err));
|
|
124
|
+
});
|
|
110
125
|
}
|
|
111
|
-
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
126
|
+
static async runBatch(program, source, stopOnError, batchCmd) {
|
|
127
|
+
const globalOpts = batchCmd.optsWithGlobals();
|
|
128
|
+
const globalFlags = [];
|
|
129
|
+
if (globalOpts.server !== undefined) {
|
|
130
|
+
globalFlags.push('--server', globalOpts.server);
|
|
131
|
+
}
|
|
132
|
+
if (globalOpts.autostart === false) {
|
|
133
|
+
globalFlags.push('--no-autostart');
|
|
134
|
+
}
|
|
135
|
+
const lines = source.split('\n');
|
|
136
|
+
let ok = 0;
|
|
137
|
+
let failed = 0;
|
|
138
|
+
for (const rawLine of lines) {
|
|
139
|
+
const line = rawLine.trim();
|
|
140
|
+
if (line === '' || line.startsWith('#') === true)
|
|
141
|
+
continue;
|
|
142
|
+
const argv = (0, string_argv_1.default)(line);
|
|
143
|
+
if (argv.length === 0)
|
|
144
|
+
continue;
|
|
145
|
+
console.log(`> ${line}`);
|
|
146
|
+
try {
|
|
147
|
+
await program.parseAsync([...globalFlags, ...argv], { from: 'user' });
|
|
148
|
+
ok += 1;
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
failed += 1;
|
|
152
|
+
if (err instanceof SilentExitError === false && err instanceof commander_1.CommanderError === false) {
|
|
153
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
154
|
+
console.error(`fastbrowser-cli error: ${message}`);
|
|
155
|
+
}
|
|
156
|
+
if (stopOnError === true) {
|
|
157
|
+
throw new SilentExitError();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (stopOnError === false) {
|
|
162
|
+
console.log(`batch: ${ok} ok, ${failed} failed`);
|
|
163
|
+
}
|
|
164
|
+
if (failed > 0) {
|
|
165
|
+
throw new SilentExitError();
|
|
166
|
+
}
|
|
115
167
|
}
|
|
116
168
|
}
|
|
117
169
|
///////////////////////////////////////////////////////////////////////////////
|
|
118
170
|
///////////////////////////////////////////////////////////////////////////////
|
|
119
|
-
//
|
|
171
|
+
//
|
|
120
172
|
///////////////////////////////////////////////////////////////////////////////
|
|
121
173
|
///////////////////////////////////////////////////////////////////////////////
|
|
122
174
|
async function main() {
|
|
123
|
-
const installIdx = process.argv.indexOf('--install');
|
|
124
|
-
if (installIdx !== -1) {
|
|
125
|
-
const next = process.argv[installIdx + 1];
|
|
126
|
-
const skillFolder = (next !== undefined && next.startsWith('-') === false) ? next : '.';
|
|
127
|
-
await runInstall(skillFolder);
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
175
|
const program = new commander_1.Command();
|
|
131
176
|
program
|
|
132
177
|
.name('fastbrowser-cli')
|
|
133
178
|
.description('CLI client for fastbrowser')
|
|
134
179
|
.option('--server <url>', 'fastbrowser-httpd URL (default: env FASTBROWSER_SERVER or http://localhost:8787)')
|
|
135
180
|
.option('--autostart', 'Auto-start the server before a command if it is not running', true)
|
|
136
|
-
.option('--no-autostart', 'Do not auto-start the server before a command')
|
|
137
|
-
|
|
181
|
+
.option('--no-autostart', 'Do not auto-start the server before a command');
|
|
182
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
183
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
184
|
+
//
|
|
185
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
186
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
138
187
|
const serverCmd = program
|
|
139
188
|
.command('server')
|
|
140
189
|
.description('Manage the fastbrowser HTTP server');
|
|
@@ -142,38 +191,43 @@ async function main() {
|
|
|
142
191
|
.command('start')
|
|
143
192
|
.description('Start the fastbrowser HTTP server as a detached daemon')
|
|
144
193
|
.action(async (_opts, cmd) => {
|
|
145
|
-
const server = getServerFromCmd(cmd);
|
|
194
|
+
const server = MainHelper.getServerFromCmd(cmd);
|
|
146
195
|
await server_manager_js_1.ServerManager.start(server);
|
|
147
196
|
});
|
|
148
197
|
serverCmd
|
|
149
198
|
.command('stop')
|
|
150
199
|
.description('Stop the fastbrowser HTTP server')
|
|
151
200
|
.action(async (_opts, cmd) => {
|
|
152
|
-
const server = getServerFromCmd(cmd);
|
|
201
|
+
const server = MainHelper.getServerFromCmd(cmd);
|
|
153
202
|
await server_manager_js_1.ServerManager.stop(server);
|
|
154
203
|
});
|
|
155
204
|
serverCmd
|
|
156
205
|
.command('status')
|
|
157
206
|
.description('Report whether the fastbrowser HTTP server is running')
|
|
158
207
|
.action(async (_opts, cmd) => {
|
|
159
|
-
const server = getServerFromCmd(cmd);
|
|
208
|
+
const server = MainHelper.getServerFromCmd(cmd);
|
|
160
209
|
const state = await server_manager_js_1.ServerManager.status(server);
|
|
161
210
|
console.log(`fastbrowser server at ${server}: ${state}`);
|
|
162
211
|
if (state === 'stopped')
|
|
163
212
|
throw new SilentExitError();
|
|
164
213
|
});
|
|
214
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
215
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
216
|
+
//
|
|
217
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
218
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
165
219
|
program
|
|
166
220
|
.command('list_pages')
|
|
167
221
|
.description('List all open browser pages')
|
|
168
222
|
.action(async (_opts, cmd) => {
|
|
169
|
-
await runTool(cmd, 'list_pages', {});
|
|
223
|
+
await MainHelper.runTool(cmd, 'list_pages', {});
|
|
170
224
|
});
|
|
171
225
|
program
|
|
172
226
|
.command('new_page')
|
|
173
227
|
.description('Open a new browser page')
|
|
174
228
|
.requiredOption('--url <url>', 'URL to open')
|
|
175
229
|
.action(async (opts, cmd) => {
|
|
176
|
-
await runTool(cmd, 'new_page', { url: opts.url });
|
|
230
|
+
await MainHelper.runTool(cmd, 'new_page', { url: opts.url });
|
|
177
231
|
});
|
|
178
232
|
program
|
|
179
233
|
.command('close_page')
|
|
@@ -184,21 +238,21 @@ async function main() {
|
|
|
184
238
|
if (Number.isNaN(pageId) === true) {
|
|
185
239
|
throw new Error(`Invalid --page-id: ${opts.pageId}`);
|
|
186
240
|
}
|
|
187
|
-
await runTool(cmd, 'close_page', { pageId });
|
|
241
|
+
await MainHelper.runTool(cmd, 'close_page', { pageId });
|
|
188
242
|
});
|
|
189
243
|
program
|
|
190
244
|
.command('navigate_page')
|
|
191
245
|
.description('Navigate the current page to a URL')
|
|
192
246
|
.requiredOption('--url <url>', 'URL to navigate to')
|
|
193
247
|
.action(async (opts, cmd) => {
|
|
194
|
-
await runTool(cmd, 'navigate_page', { url: opts.url });
|
|
248
|
+
await MainHelper.runTool(cmd, 'navigate_page', { url: opts.url });
|
|
195
249
|
});
|
|
196
250
|
program
|
|
197
251
|
.command('click')
|
|
198
252
|
.description('Click an element by its accessibility selector')
|
|
199
253
|
.requiredOption('-s, --selector <selector>', 'Accessibility selector (e.g. "#1_3" or \'button[name="Submit"]\')')
|
|
200
254
|
.action(async (opts, cmd) => {
|
|
201
|
-
await runTool(cmd, 'click', { selector: opts.selector });
|
|
255
|
+
await MainHelper.runTool(cmd, 'click', { selector: opts.selector });
|
|
202
256
|
});
|
|
203
257
|
program
|
|
204
258
|
.command('fill_form')
|
|
@@ -206,7 +260,7 @@ async function main() {
|
|
|
206
260
|
.requiredOption('-s, --selector <selector>', 'Accessibility selector (e.g. "#1_3" or \'textbox[name="Email"]\')')
|
|
207
261
|
.requiredOption('-v, --value <value>', 'Value to fill')
|
|
208
262
|
.action(async (opts, cmd) => {
|
|
209
|
-
await runTool(cmd, 'fill_form', {
|
|
263
|
+
await MainHelper.runTool(cmd, 'fill_form', {
|
|
210
264
|
elements: [{ selector: opts.selector, value: opts.value }],
|
|
211
265
|
});
|
|
212
266
|
});
|
|
@@ -222,8 +276,8 @@ async function main() {
|
|
|
222
276
|
.option('--no-with-ancestors', 'Exclude ancestor nodes')
|
|
223
277
|
.option('--selectors-json <json>', 'JSON array of {selector,limit,withAncestors} for per-selector control')
|
|
224
278
|
.action(async (opts, cmd) => {
|
|
225
|
-
const body = buildQuerySelectorsBody(opts);
|
|
226
|
-
await runTool(cmd, 'query_selectors_all', body);
|
|
279
|
+
const body = MainHelper.buildQuerySelectorsBody(opts);
|
|
280
|
+
await MainHelper.runTool(cmd, 'query_selectors_all', body);
|
|
227
281
|
});
|
|
228
282
|
program
|
|
229
283
|
.command('query_selectors')
|
|
@@ -236,21 +290,27 @@ async function main() {
|
|
|
236
290
|
.option('--no-with-ancestors', 'Exclude ancestor nodes')
|
|
237
291
|
.option('--selectors-json <json>', 'JSON array of {selector,withAncestors} for per-selector control')
|
|
238
292
|
.action(async (opts, cmd) => {
|
|
239
|
-
const body = buildQuerySelectorFirstBody(opts);
|
|
240
|
-
await runTool(cmd, 'query_selectors', body);
|
|
293
|
+
const body = MainHelper.buildQuerySelectorFirstBody(opts);
|
|
294
|
+
await MainHelper.runTool(cmd, 'query_selectors', body);
|
|
241
295
|
});
|
|
242
296
|
program
|
|
243
297
|
.command('take_snapshot')
|
|
244
298
|
.description('Take an accessibility-tree snapshot of the current page')
|
|
245
299
|
.action(async (_opts, cmd) => {
|
|
246
|
-
await runTool(cmd, 'take_snapshot', {});
|
|
300
|
+
await MainHelper.runTool(cmd, 'take_snapshot', {});
|
|
247
301
|
});
|
|
248
302
|
program
|
|
249
303
|
.command('press_keys')
|
|
250
304
|
.description('Press a sequence of keys')
|
|
251
305
|
.requiredOption('--keys <keys>', "Comma-separated keys. E.g. 'Hello, Tab, Enter'")
|
|
252
306
|
.action(async (opts, cmd) => {
|
|
253
|
-
await runTool(cmd, 'press_keys', { keys: opts.keys });
|
|
307
|
+
await MainHelper.runTool(cmd, 'press_keys', { keys: opts.keys });
|
|
308
|
+
});
|
|
309
|
+
program
|
|
310
|
+
.command('install [skill-folder]')
|
|
311
|
+
.description('Install SKILL.md into <skill-folder>/skills/fastbrowser (default: .)')
|
|
312
|
+
.action(async (skillFolder) => {
|
|
313
|
+
await MainHelper.runInstall(skillFolder ?? '.');
|
|
254
314
|
});
|
|
255
315
|
program
|
|
256
316
|
.command('batch [file]')
|
|
@@ -258,86 +318,15 @@ async function main() {
|
|
|
258
318
|
.option('--script <script>', 'Inline multi-line script (overrides [file] and stdin)')
|
|
259
319
|
.option('--no-stop-on-error', 'Continue running subsequent lines after a failure (default: stop on first error)')
|
|
260
320
|
.action(async (file, opts, cmd) => {
|
|
261
|
-
const source = await readBatchSource(file, opts.script);
|
|
262
|
-
await runBatch(program, source, opts.stopOnError !== false, cmd);
|
|
263
|
-
});
|
|
264
|
-
program.exitOverride();
|
|
265
|
-
try {
|
|
266
|
-
await program.parseAsync(process.argv);
|
|
267
|
-
}
|
|
268
|
-
catch (err) {
|
|
269
|
-
if (err instanceof SilentExitError) {
|
|
270
|
-
process.exit(1);
|
|
271
|
-
}
|
|
272
|
-
if (err instanceof commander_1.CommanderError) {
|
|
273
|
-
process.exit(err.exitCode === undefined ? 1 : err.exitCode);
|
|
274
|
-
}
|
|
275
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
276
|
-
console.error(`fastbrowser-cli error: ${message}`);
|
|
277
|
-
process.exit(1);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
async function readBatchSource(file, inlineScript) {
|
|
281
|
-
if (inlineScript !== undefined && inlineScript !== '') {
|
|
282
|
-
return inlineScript;
|
|
283
|
-
}
|
|
284
|
-
if (file !== undefined && file !== '') {
|
|
285
|
-
return await node_fs_1.default.promises.readFile(file, 'utf-8');
|
|
286
|
-
}
|
|
287
|
-
if (process.stdin.isTTY === true) {
|
|
288
|
-
throw new Error('batch: no input. Provide a file path, --script, or pipe commands on stdin.');
|
|
289
|
-
}
|
|
290
|
-
return await readStdinToString();
|
|
291
|
-
}
|
|
292
|
-
async function readStdinToString() {
|
|
293
|
-
const chunks = [];
|
|
294
|
-
return await new Promise((resolve, reject) => {
|
|
295
|
-
process.stdin.on('data', (chunk) => chunks.push(chunk));
|
|
296
|
-
process.stdin.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
|
|
297
|
-
process.stdin.on('error', (err) => reject(err));
|
|
321
|
+
const source = await MainHelper.readBatchSource(file, opts.script);
|
|
322
|
+
await MainHelper.runBatch(program, source, opts.stopOnError !== false, cmd);
|
|
298
323
|
});
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
if (globalOpts.autostart === false) {
|
|
307
|
-
globalFlags.push('--no-autostart');
|
|
308
|
-
}
|
|
309
|
-
const lines = source.split('\n');
|
|
310
|
-
let ok = 0;
|
|
311
|
-
let failed = 0;
|
|
312
|
-
for (const rawLine of lines) {
|
|
313
|
-
const line = rawLine.trim();
|
|
314
|
-
if (line === '' || line.startsWith('#') === true)
|
|
315
|
-
continue;
|
|
316
|
-
const argv = (0, string_argv_1.default)(line);
|
|
317
|
-
if (argv.length === 0)
|
|
318
|
-
continue;
|
|
319
|
-
console.log(`> ${line}`);
|
|
320
|
-
try {
|
|
321
|
-
await program.parseAsync([...globalFlags, ...argv], { from: 'user' });
|
|
322
|
-
ok += 1;
|
|
323
|
-
}
|
|
324
|
-
catch (err) {
|
|
325
|
-
failed += 1;
|
|
326
|
-
if (err instanceof SilentExitError === false && err instanceof commander_1.CommanderError === false) {
|
|
327
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
328
|
-
console.error(`fastbrowser-cli error: ${message}`);
|
|
329
|
-
}
|
|
330
|
-
if (stopOnError === true) {
|
|
331
|
-
throw new SilentExitError();
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
if (stopOnError === false) {
|
|
336
|
-
console.log(`batch: ${ok} ok, ${failed} failed`);
|
|
337
|
-
}
|
|
338
|
-
if (failed > 0) {
|
|
339
|
-
throw new SilentExitError();
|
|
340
|
-
}
|
|
324
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
325
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
326
|
+
//
|
|
327
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
328
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
329
|
+
await program.parseAsync();
|
|
341
330
|
}
|
|
342
331
|
void main();
|
|
343
332
|
//# sourceMappingURL=fastbrowser_cli.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fastbrowser_cli.js","sourceRoot":"","sources":["../../src/fastbrowser_cli/fastbrowser_cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fastbrowser_cli.js","sourceRoot":"","sources":["../../src/fastbrowser_cli/fastbrowser_cli.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastbrowser_cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/fastbrowser_cli/fastbrowser_cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -19,6 +19,11 @@
|
|
|
19
19
|
"keywords": [],
|
|
20
20
|
"author": "",
|
|
21
21
|
"license": "MIT",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/jeromeetienne/skillmd_collecetion.git"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/jeromeetienne/skillmd_collection/packages/fastbrowser_cli#readme",
|
|
22
27
|
"type": "commonjs",
|
|
23
28
|
"dependencies": {
|
|
24
29
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// node imports
|
|
4
3
|
import fs from 'node:fs';
|
|
5
4
|
import path from 'node:path';
|
|
6
5
|
|
|
7
|
-
// npm imports
|
|
8
6
|
import { Command, CommanderError } from 'commander';
|
|
9
7
|
import stringArgv from 'string-argv';
|
|
10
8
|
|
|
11
|
-
// local imports
|
|
12
9
|
import { HttpClient } from './libs/http-client.js';
|
|
13
10
|
import { ServerManager } from './libs/server-manager.js';
|
|
14
11
|
import type { QuerySelectorInput, QuerySelectorFirstInput, QuerySelectorsAllRequest, QuerySelectorRequest } from '../fastbrowser_httpd/libs/tool-schemas.js';
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
18
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
19
|
-
//
|
|
20
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
21
13
|
///////////////////////////////////////////////////////////////////////////////
|
|
22
14
|
|
|
23
15
|
type GlobalOpts = {
|
|
@@ -31,145 +23,200 @@ class SilentExitError extends Error {
|
|
|
31
23
|
}
|
|
32
24
|
}
|
|
33
25
|
|
|
34
|
-
|
|
35
|
-
const globalOpts = cmd.optsWithGlobals<GlobalOpts>();
|
|
36
|
-
return HttpClient.getServerUrl(globalOpts.server);
|
|
37
|
-
}
|
|
26
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
38
27
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
28
|
+
class MainHelper {
|
|
29
|
+
static getServerFromCmd(cmd: Command): string {
|
|
30
|
+
const globalOpts = cmd.optsWithGlobals<GlobalOpts>();
|
|
31
|
+
return HttpClient.getServerUrl(globalOpts.server);
|
|
32
|
+
}
|
|
43
33
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
await ServerManager.ensureRunning(server);
|
|
34
|
+
static getAutostartFromCmd(cmd: Command): boolean {
|
|
35
|
+
const globalOpts = cmd.optsWithGlobals<GlobalOpts>();
|
|
36
|
+
return globalOpts.autostart !== false;
|
|
48
37
|
}
|
|
49
|
-
const response = await HttpClient.postTool(server, routeName, body);
|
|
50
|
-
HttpClient.printResponse(response);
|
|
51
|
-
}
|
|
52
38
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
39
|
+
static async runTool(cmd: Command, routeName: string, body: unknown): Promise<void> {
|
|
40
|
+
const server = MainHelper.getServerFromCmd(cmd);
|
|
41
|
+
if (MainHelper.getAutostartFromCmd(cmd) === true) {
|
|
42
|
+
await ServerManager.ensureRunning(server);
|
|
43
|
+
}
|
|
44
|
+
const response = await HttpClient.postTool(server, routeName, body);
|
|
45
|
+
HttpClient.printResponse(response);
|
|
46
|
+
}
|
|
58
47
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}): QuerySelectorsAllRequest {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
48
|
+
static buildQuerySelectorsBody(opts: {
|
|
49
|
+
selector?: string[];
|
|
50
|
+
limit?: string;
|
|
51
|
+
withAncestors?: boolean;
|
|
52
|
+
selectorsJson?: string;
|
|
53
|
+
}): QuerySelectorsAllRequest {
|
|
54
|
+
if (opts.selectorsJson !== undefined && opts.selectorsJson !== '') {
|
|
55
|
+
let parsed: unknown;
|
|
56
|
+
try {
|
|
57
|
+
parsed = JSON.parse(opts.selectorsJson);
|
|
58
|
+
} catch (err) {
|
|
59
|
+
throw new Error(`--selectors-json is not valid JSON: ${(err as Error).message}`);
|
|
60
|
+
}
|
|
61
|
+
if (Array.isArray(parsed) === false) {
|
|
62
|
+
throw new Error('--selectors-json must be a JSON array');
|
|
63
|
+
}
|
|
64
|
+
return { selectors: parsed as QuerySelectorInput[] };
|
|
71
65
|
}
|
|
72
|
-
|
|
73
|
-
|
|
66
|
+
|
|
67
|
+
const selectorList = opts.selector ?? [];
|
|
68
|
+
if (selectorList.length === 0) {
|
|
69
|
+
throw new Error('At least one --selector or --selectors-json is required');
|
|
74
70
|
}
|
|
75
|
-
return { selectors: parsed as QuerySelectorInput[] };
|
|
76
|
-
}
|
|
77
71
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
72
|
+
const limit = opts.limit === undefined ? 0 : Number.parseInt(opts.limit, 10);
|
|
73
|
+
if (Number.isNaN(limit) === true) {
|
|
74
|
+
throw new Error(`Invalid --limit: ${opts.limit}`);
|
|
75
|
+
}
|
|
76
|
+
const withAncestors = opts.withAncestors !== false;
|
|
77
|
+
|
|
78
|
+
const selectors: QuerySelectorInput[] = selectorList.map((selector) => ({
|
|
79
|
+
selector,
|
|
80
|
+
limit,
|
|
81
|
+
withAncestors,
|
|
82
|
+
}));
|
|
83
|
+
return { selectors };
|
|
81
84
|
}
|
|
82
85
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
static buildQuerySelectorFirstBody(opts: {
|
|
87
|
+
selector?: string[];
|
|
88
|
+
withAncestors?: boolean;
|
|
89
|
+
selectorsJson?: string;
|
|
90
|
+
}): QuerySelectorRequest {
|
|
91
|
+
if (opts.selectorsJson !== undefined && opts.selectorsJson !== '') {
|
|
92
|
+
let parsed: unknown;
|
|
93
|
+
try {
|
|
94
|
+
parsed = JSON.parse(opts.selectorsJson);
|
|
95
|
+
} catch (err) {
|
|
96
|
+
throw new Error(`--selectors-json is not valid JSON: ${(err as Error).message}`);
|
|
97
|
+
}
|
|
98
|
+
if (Array.isArray(parsed) === false) {
|
|
99
|
+
throw new Error('--selectors-json must be a JSON array');
|
|
100
|
+
}
|
|
101
|
+
return { selectors: parsed as QuerySelectorFirstInput[] };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const selectorList = opts.selector ?? [];
|
|
105
|
+
if (selectorList.length === 0) {
|
|
106
|
+
throw new Error('At least one --selector or --selectors-json is required');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const withAncestors = opts.withAncestors !== false;
|
|
110
|
+
|
|
111
|
+
const selectors: QuerySelectorFirstInput[] = selectorList.map((selector) => ({
|
|
112
|
+
selector,
|
|
113
|
+
withAncestors,
|
|
114
|
+
}));
|
|
115
|
+
return { selectors };
|
|
86
116
|
}
|
|
87
|
-
const withAncestors = opts.withAncestors !== false;
|
|
88
|
-
|
|
89
|
-
const selectors: QuerySelectorInput[] = selectorList.map((selector) => ({
|
|
90
|
-
selector,
|
|
91
|
-
limit,
|
|
92
|
-
withAncestors,
|
|
93
|
-
}));
|
|
94
|
-
return { selectors };
|
|
95
|
-
}
|
|
96
117
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}): QuerySelectorRequest {
|
|
102
|
-
if (opts.selectorsJson !== undefined && opts.selectorsJson !== '') {
|
|
103
|
-
let parsed: unknown;
|
|
118
|
+
static async runInstall(skillFolder: string): Promise<void> {
|
|
119
|
+
const sourceSkillMd = path.resolve(__dirname, '../../skills/fastbrowser/SKILL.md');
|
|
120
|
+
const targetDir = path.resolve(skillFolder, 'skills', 'fastbrowser');
|
|
121
|
+
const targetSkillMd = path.join(targetDir, 'SKILL.md');
|
|
104
122
|
try {
|
|
105
|
-
|
|
123
|
+
await fs.promises.mkdir(targetDir, { recursive: true });
|
|
124
|
+
await fs.promises.copyFile(sourceSkillMd, targetSkillMd);
|
|
125
|
+
console.log(`Installed fastbrowser SKILL.md at ${targetSkillMd}`);
|
|
106
126
|
} catch (err) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
throw new Error('--selectors-json must be a JSON array');
|
|
127
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
128
|
+
console.error(`fastbrowser-cli error: ${message}`);
|
|
129
|
+
process.exit(1);
|
|
111
130
|
}
|
|
112
|
-
return { selectors: parsed as QuerySelectorFirstInput[] };
|
|
113
131
|
}
|
|
114
132
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
133
|
+
static async readBatchSource(file: string | undefined, inlineScript: string | undefined): Promise<string> {
|
|
134
|
+
if (inlineScript !== undefined && inlineScript !== '') {
|
|
135
|
+
return inlineScript;
|
|
136
|
+
}
|
|
137
|
+
if (file !== undefined && file !== '') {
|
|
138
|
+
return await fs.promises.readFile(file, 'utf-8');
|
|
139
|
+
}
|
|
140
|
+
if (process.stdin.isTTY === true) {
|
|
141
|
+
throw new Error('batch: no input. Provide a file path, --script, or pipe commands on stdin.');
|
|
142
|
+
}
|
|
143
|
+
return await MainHelper.readStdinToString();
|
|
118
144
|
}
|
|
119
145
|
|
|
120
|
-
|
|
146
|
+
static async readStdinToString(): Promise<string> {
|
|
147
|
+
const chunks: Buffer[] = [];
|
|
148
|
+
return await new Promise((resolve, reject) => {
|
|
149
|
+
process.stdin.on('data', (chunk) => chunks.push(chunk as Buffer));
|
|
150
|
+
process.stdin.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
|
|
151
|
+
process.stdin.on('error', (err) => reject(err));
|
|
152
|
+
});
|
|
153
|
+
}
|
|
121
154
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
155
|
+
static async runBatch(program: Command, source: string, stopOnError: boolean, batchCmd: Command): Promise<void> {
|
|
156
|
+
const globalOpts = batchCmd.optsWithGlobals<GlobalOpts>();
|
|
157
|
+
const globalFlags: string[] = [];
|
|
158
|
+
if (globalOpts.server !== undefined) {
|
|
159
|
+
globalFlags.push('--server', globalOpts.server);
|
|
160
|
+
}
|
|
161
|
+
if (globalOpts.autostart === false) {
|
|
162
|
+
globalFlags.push('--no-autostart');
|
|
163
|
+
}
|
|
128
164
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
165
|
+
const lines = source.split('\n');
|
|
166
|
+
let ok = 0;
|
|
167
|
+
let failed = 0;
|
|
168
|
+
for (const rawLine of lines) {
|
|
169
|
+
const line = rawLine.trim();
|
|
170
|
+
if (line === '' || line.startsWith('#') === true) continue;
|
|
171
|
+
|
|
172
|
+
const argv = stringArgv(line);
|
|
173
|
+
if (argv.length === 0) continue;
|
|
174
|
+
|
|
175
|
+
console.log(`> ${line}`);
|
|
176
|
+
try {
|
|
177
|
+
await program.parseAsync([...globalFlags, ...argv], { from: 'user' });
|
|
178
|
+
ok += 1;
|
|
179
|
+
} catch (err) {
|
|
180
|
+
failed += 1;
|
|
181
|
+
if (err instanceof SilentExitError === false && err instanceof CommanderError === false) {
|
|
182
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
183
|
+
console.error(`fastbrowser-cli error: ${message}`);
|
|
184
|
+
}
|
|
185
|
+
if (stopOnError === true) {
|
|
186
|
+
throw new SilentExitError();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
134
190
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
await fs.promises.copyFile(sourceSkillMd, targetSkillMd);
|
|
142
|
-
console.log(`Installed fastbrowser SKILL.md at ${targetSkillMd}`);
|
|
143
|
-
} catch (err) {
|
|
144
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
145
|
-
console.error(`fastbrowser-cli error: ${message}`);
|
|
146
|
-
process.exit(1);
|
|
191
|
+
if (stopOnError === false) {
|
|
192
|
+
console.log(`batch: ${ok} ok, ${failed} failed`);
|
|
193
|
+
}
|
|
194
|
+
if (failed > 0) {
|
|
195
|
+
throw new SilentExitError();
|
|
196
|
+
}
|
|
147
197
|
}
|
|
148
198
|
}
|
|
149
199
|
|
|
150
200
|
///////////////////////////////////////////////////////////////////////////////
|
|
151
201
|
///////////////////////////////////////////////////////////////////////////////
|
|
152
|
-
//
|
|
202
|
+
//
|
|
153
203
|
///////////////////////////////////////////////////////////////////////////////
|
|
154
204
|
///////////////////////////////////////////////////////////////////////////////
|
|
155
205
|
|
|
156
206
|
async function main(): Promise<void> {
|
|
157
|
-
const installIdx = process.argv.indexOf('--install');
|
|
158
|
-
if (installIdx !== -1) {
|
|
159
|
-
const next = process.argv[installIdx + 1];
|
|
160
|
-
const skillFolder = (next !== undefined && next.startsWith('-') === false) ? next : '.';
|
|
161
|
-
await runInstall(skillFolder);
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
207
|
const program = new Command();
|
|
166
208
|
program
|
|
167
209
|
.name('fastbrowser-cli')
|
|
168
210
|
.description('CLI client for fastbrowser')
|
|
169
211
|
.option('--server <url>', 'fastbrowser-httpd URL (default: env FASTBROWSER_SERVER or http://localhost:8787)')
|
|
170
212
|
.option('--autostart', 'Auto-start the server before a command if it is not running', true)
|
|
171
|
-
.option('--no-autostart', 'Do not auto-start the server before a command')
|
|
172
|
-
|
|
213
|
+
.option('--no-autostart', 'Do not auto-start the server before a command');
|
|
214
|
+
|
|
215
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
216
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
217
|
+
//
|
|
218
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
219
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
173
220
|
|
|
174
221
|
const serverCmd = program
|
|
175
222
|
.command('server')
|
|
@@ -179,7 +226,7 @@ async function main(): Promise<void> {
|
|
|
179
226
|
.command('start')
|
|
180
227
|
.description('Start the fastbrowser HTTP server as a detached daemon')
|
|
181
228
|
.action(async (_opts, cmd: Command) => {
|
|
182
|
-
const server = getServerFromCmd(cmd);
|
|
229
|
+
const server = MainHelper.getServerFromCmd(cmd);
|
|
183
230
|
await ServerManager.start(server);
|
|
184
231
|
});
|
|
185
232
|
|
|
@@ -187,7 +234,7 @@ async function main(): Promise<void> {
|
|
|
187
234
|
.command('stop')
|
|
188
235
|
.description('Stop the fastbrowser HTTP server')
|
|
189
236
|
.action(async (_opts, cmd: Command) => {
|
|
190
|
-
const server = getServerFromCmd(cmd);
|
|
237
|
+
const server = MainHelper.getServerFromCmd(cmd);
|
|
191
238
|
await ServerManager.stop(server);
|
|
192
239
|
});
|
|
193
240
|
|
|
@@ -195,17 +242,23 @@ async function main(): Promise<void> {
|
|
|
195
242
|
.command('status')
|
|
196
243
|
.description('Report whether the fastbrowser HTTP server is running')
|
|
197
244
|
.action(async (_opts, cmd: Command) => {
|
|
198
|
-
const server = getServerFromCmd(cmd);
|
|
245
|
+
const server = MainHelper.getServerFromCmd(cmd);
|
|
199
246
|
const state = await ServerManager.status(server);
|
|
200
247
|
console.log(`fastbrowser server at ${server}: ${state}`);
|
|
201
248
|
if (state === 'stopped') throw new SilentExitError();
|
|
202
249
|
});
|
|
203
250
|
|
|
251
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
252
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
253
|
+
//
|
|
254
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
255
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
256
|
+
|
|
204
257
|
program
|
|
205
258
|
.command('list_pages')
|
|
206
259
|
.description('List all open browser pages')
|
|
207
260
|
.action(async (_opts, cmd: Command) => {
|
|
208
|
-
await runTool(cmd, 'list_pages', {});
|
|
261
|
+
await MainHelper.runTool(cmd, 'list_pages', {});
|
|
209
262
|
});
|
|
210
263
|
|
|
211
264
|
program
|
|
@@ -213,7 +266,7 @@ async function main(): Promise<void> {
|
|
|
213
266
|
.description('Open a new browser page')
|
|
214
267
|
.requiredOption('--url <url>', 'URL to open')
|
|
215
268
|
.action(async (opts: { url: string }, cmd: Command) => {
|
|
216
|
-
await runTool(cmd, 'new_page', { url: opts.url });
|
|
269
|
+
await MainHelper.runTool(cmd, 'new_page', { url: opts.url });
|
|
217
270
|
});
|
|
218
271
|
|
|
219
272
|
program
|
|
@@ -225,7 +278,7 @@ async function main(): Promise<void> {
|
|
|
225
278
|
if (Number.isNaN(pageId) === true) {
|
|
226
279
|
throw new Error(`Invalid --page-id: ${opts.pageId}`);
|
|
227
280
|
}
|
|
228
|
-
await runTool(cmd, 'close_page', { pageId });
|
|
281
|
+
await MainHelper.runTool(cmd, 'close_page', { pageId });
|
|
229
282
|
});
|
|
230
283
|
|
|
231
284
|
program
|
|
@@ -233,7 +286,7 @@ async function main(): Promise<void> {
|
|
|
233
286
|
.description('Navigate the current page to a URL')
|
|
234
287
|
.requiredOption('--url <url>', 'URL to navigate to')
|
|
235
288
|
.action(async (opts: { url: string }, cmd: Command) => {
|
|
236
|
-
await runTool(cmd, 'navigate_page', { url: opts.url });
|
|
289
|
+
await MainHelper.runTool(cmd, 'navigate_page', { url: opts.url });
|
|
237
290
|
});
|
|
238
291
|
|
|
239
292
|
program
|
|
@@ -241,7 +294,7 @@ async function main(): Promise<void> {
|
|
|
241
294
|
.description('Click an element by its accessibility selector')
|
|
242
295
|
.requiredOption('-s, --selector <selector>', 'Accessibility selector (e.g. "#1_3" or \'button[name="Submit"]\')')
|
|
243
296
|
.action(async (opts: { selector: string }, cmd: Command) => {
|
|
244
|
-
await runTool(cmd, 'click', { selector: opts.selector });
|
|
297
|
+
await MainHelper.runTool(cmd, 'click', { selector: opts.selector });
|
|
245
298
|
});
|
|
246
299
|
|
|
247
300
|
program
|
|
@@ -250,7 +303,7 @@ async function main(): Promise<void> {
|
|
|
250
303
|
.requiredOption('-s, --selector <selector>', 'Accessibility selector (e.g. "#1_3" or \'textbox[name="Email"]\')')
|
|
251
304
|
.requiredOption('-v, --value <value>', 'Value to fill')
|
|
252
305
|
.action(async (opts: { selector: string; value: string }, cmd: Command) => {
|
|
253
|
-
await runTool(cmd, 'fill_form', {
|
|
306
|
+
await MainHelper.runTool(cmd, 'fill_form', {
|
|
254
307
|
elements: [{ selector: opts.selector, value: opts.value }],
|
|
255
308
|
});
|
|
256
309
|
});
|
|
@@ -272,8 +325,8 @@ async function main(): Promise<void> {
|
|
|
272
325
|
withAncestors?: boolean;
|
|
273
326
|
selectorsJson?: string;
|
|
274
327
|
}, cmd: Command) => {
|
|
275
|
-
const body = buildQuerySelectorsBody(opts);
|
|
276
|
-
await runTool(cmd, 'query_selectors_all', body);
|
|
328
|
+
const body = MainHelper.buildQuerySelectorsBody(opts);
|
|
329
|
+
await MainHelper.runTool(cmd, 'query_selectors_all', body);
|
|
277
330
|
});
|
|
278
331
|
|
|
279
332
|
program
|
|
@@ -291,15 +344,15 @@ async function main(): Promise<void> {
|
|
|
291
344
|
withAncestors?: boolean;
|
|
292
345
|
selectorsJson?: string;
|
|
293
346
|
}, cmd: Command) => {
|
|
294
|
-
const body = buildQuerySelectorFirstBody(opts);
|
|
295
|
-
await runTool(cmd, 'query_selectors', body);
|
|
347
|
+
const body = MainHelper.buildQuerySelectorFirstBody(opts);
|
|
348
|
+
await MainHelper.runTool(cmd, 'query_selectors', body);
|
|
296
349
|
});
|
|
297
350
|
|
|
298
351
|
program
|
|
299
352
|
.command('take_snapshot')
|
|
300
353
|
.description('Take an accessibility-tree snapshot of the current page')
|
|
301
354
|
.action(async (_opts, cmd: Command) => {
|
|
302
|
-
await runTool(cmd, 'take_snapshot', {});
|
|
355
|
+
await MainHelper.runTool(cmd, 'take_snapshot', {});
|
|
303
356
|
});
|
|
304
357
|
|
|
305
358
|
program
|
|
@@ -307,7 +360,14 @@ async function main(): Promise<void> {
|
|
|
307
360
|
.description('Press a sequence of keys')
|
|
308
361
|
.requiredOption('--keys <keys>', "Comma-separated keys. E.g. 'Hello, Tab, Enter'")
|
|
309
362
|
.action(async (opts: { keys: string }, cmd: Command) => {
|
|
310
|
-
await runTool(cmd, 'press_keys', { keys: opts.keys });
|
|
363
|
+
await MainHelper.runTool(cmd, 'press_keys', { keys: opts.keys });
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
program
|
|
367
|
+
.command('install [skill-folder]')
|
|
368
|
+
.description('Install SKILL.md into <skill-folder>/skills/fastbrowser (default: .)')
|
|
369
|
+
.action(async (skillFolder: string | undefined) => {
|
|
370
|
+
await MainHelper.runInstall(skillFolder ?? '.');
|
|
311
371
|
});
|
|
312
372
|
|
|
313
373
|
program
|
|
@@ -316,91 +376,17 @@ async function main(): Promise<void> {
|
|
|
316
376
|
.option('--script <script>', 'Inline multi-line script (overrides [file] and stdin)')
|
|
317
377
|
.option('--no-stop-on-error', 'Continue running subsequent lines after a failure (default: stop on first error)')
|
|
318
378
|
.action(async (file: string | undefined, opts: { script?: string; stopOnError: boolean }, cmd: Command) => {
|
|
319
|
-
const source = await readBatchSource(file, opts.script);
|
|
320
|
-
await runBatch(program, source, opts.stopOnError !== false, cmd);
|
|
379
|
+
const source = await MainHelper.readBatchSource(file, opts.script);
|
|
380
|
+
await MainHelper.runBatch(program, source, opts.stopOnError !== false, cmd);
|
|
321
381
|
});
|
|
322
382
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
if (err instanceof SilentExitError) {
|
|
329
|
-
process.exit(1);
|
|
330
|
-
}
|
|
331
|
-
if (err instanceof CommanderError) {
|
|
332
|
-
process.exit(err.exitCode === undefined ? 1 : err.exitCode);
|
|
333
|
-
}
|
|
334
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
335
|
-
console.error(`fastbrowser-cli error: ${message}`);
|
|
336
|
-
process.exit(1);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
383
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
384
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
385
|
+
//
|
|
386
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
387
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
339
388
|
|
|
340
|
-
|
|
341
|
-
if (inlineScript !== undefined && inlineScript !== '') {
|
|
342
|
-
return inlineScript;
|
|
343
|
-
}
|
|
344
|
-
if (file !== undefined && file !== '') {
|
|
345
|
-
return await fs.promises.readFile(file, 'utf-8');
|
|
346
|
-
}
|
|
347
|
-
if (process.stdin.isTTY === true) {
|
|
348
|
-
throw new Error('batch: no input. Provide a file path, --script, or pipe commands on stdin.');
|
|
349
|
-
}
|
|
350
|
-
return await readStdinToString();
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
async function readStdinToString(): Promise<string> {
|
|
354
|
-
const chunks: Buffer[] = [];
|
|
355
|
-
return await new Promise((resolve, reject) => {
|
|
356
|
-
process.stdin.on('data', (chunk) => chunks.push(chunk as Buffer));
|
|
357
|
-
process.stdin.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
|
|
358
|
-
process.stdin.on('error', (err) => reject(err));
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
async function runBatch(program: Command, source: string, stopOnError: boolean, batchCmd: Command): Promise<void> {
|
|
363
|
-
const globalOpts = batchCmd.optsWithGlobals<GlobalOpts>();
|
|
364
|
-
const globalFlags: string[] = [];
|
|
365
|
-
if (globalOpts.server !== undefined) {
|
|
366
|
-
globalFlags.push('--server', globalOpts.server);
|
|
367
|
-
}
|
|
368
|
-
if (globalOpts.autostart === false) {
|
|
369
|
-
globalFlags.push('--no-autostart');
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
const lines = source.split('\n');
|
|
373
|
-
let ok = 0;
|
|
374
|
-
let failed = 0;
|
|
375
|
-
for (const rawLine of lines) {
|
|
376
|
-
const line = rawLine.trim();
|
|
377
|
-
if (line === '' || line.startsWith('#') === true) continue;
|
|
378
|
-
|
|
379
|
-
const argv = stringArgv(line);
|
|
380
|
-
if (argv.length === 0) continue;
|
|
381
|
-
|
|
382
|
-
console.log(`> ${line}`);
|
|
383
|
-
try {
|
|
384
|
-
await program.parseAsync([...globalFlags, ...argv], { from: 'user' });
|
|
385
|
-
ok += 1;
|
|
386
|
-
} catch (err) {
|
|
387
|
-
failed += 1;
|
|
388
|
-
if (err instanceof SilentExitError === false && err instanceof CommanderError === false) {
|
|
389
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
390
|
-
console.error(`fastbrowser-cli error: ${message}`);
|
|
391
|
-
}
|
|
392
|
-
if (stopOnError === true) {
|
|
393
|
-
throw new SilentExitError();
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
if (stopOnError === false) {
|
|
399
|
-
console.log(`batch: ${ok} ok, ${failed} failed`);
|
|
400
|
-
}
|
|
401
|
-
if (failed > 0) {
|
|
402
|
-
throw new SilentExitError();
|
|
403
|
-
}
|
|
389
|
+
await program.parseAsync();
|
|
404
390
|
}
|
|
405
391
|
|
|
406
392
|
void main();
|
|
File without changes
|