@dokobot/cli 1.0.2 → 1.1.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 CHANGED
@@ -1,79 +1,121 @@
1
1
  # @dokobot/cli
2
2
 
3
- Connect your Chrome browser to [Dokobot](https://dokobot.ai) as a **doko** — letting AI agents browse, interact with, and extract content from the real web.
3
+ Extract structured data from any web page using AI. Powered by [Dokobot](https://dokobot.ai).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm i -g @dokobot/cli
9
+ ```
4
10
 
5
11
  ## Quick Start
6
12
 
7
13
  ```bash
8
- npx @dokobot/cli connect
14
+ # Extract data from a web page
15
+ dokobot crawl create \
16
+ --url https://news.ycombinator.com \
17
+ --name "HN Front Page" \
18
+ --goal "Extract article titles, points, and comment counts" \
19
+ --fields '[{"name":"title","type":"string","required":true},{"name":"points","type":"number","required":true}]' \
20
+ --format csv
21
+
22
+ # Check task progress
23
+ dokobot crawl status <taskId>
24
+
25
+ # Download results
26
+ dokobot crawl result <taskId> --output data.csv
9
27
  ```
10
28
 
11
- The CLI will guide you through setup automatically no manual configuration needed.
29
+ Requires a connected doko (browser extension or `dokobot doko connect`). See [Doko](#doko) below.
12
30
 
13
- ## Prerequisites
31
+ ## Commands
14
32
 
15
- - **Node.js** 18+
16
- - **Chrome** with remote debugging enabled:
17
- 1. Open `chrome://inspect/#remote-debugging`
18
- 2. Check **"Allow remote debugging for this browser instance"**
33
+ ### `crawl`
19
34
 
20
- ## Install
35
+ Extract structured data from web pages using AI.
21
36
 
22
- ```bash
23
- # Run directly (no install needed)
24
- npx @dokobot/cli connect
37
+ #### `crawl create`
25
38
 
26
- # Or install globally
27
- npm i -g @dokobot/cli
28
- dokobot connect
39
+ Create a new crawl task.
40
+
41
+ ```bash
42
+ dokobot crawl create \
43
+ --url https://example.com \
44
+ --name "My Task" \
45
+ --goal "Extract product names and prices" \
46
+ --fields '[{"name":"product","type":"string","required":true},{"name":"price","type":"number","required":true}]' \
47
+ --format csv
29
48
  ```
30
49
 
31
- ## Commands
50
+ | Option | Description |
51
+ |--------|-------------|
52
+ | `--url <urls...>` | Target URLs (multiple allowed) |
53
+ | `--name <text>` | Task name |
54
+ | `--goal <text>` | What to extract |
55
+ | `--fields <json>` | Extraction field definitions |
56
+ | `--format <type>` | Output format: `csv`, `json`, or `markdown` (default: `csv`) |
57
+ | `--max-items <n>` | Max items per page (default: `50`) |
58
+ | `--device <id>` | Specific doko device ID |
32
59
 
33
- ### `connect`
60
+ All options can also be provided interactively when omitted.
34
61
 
35
- Connect a Chrome browser to Dokobot.
62
+ #### `crawl list`
36
63
 
37
64
  ```bash
38
- dokobot connect # Interactive setup
39
- dokobot connect --name "Work Chrome" # Name your doko
40
- dokobot connect --browser-url http://127.0.0.1:9222 # Custom Chrome instance
41
- dokobot connect --device-id <id> # Reconnect an existing doko
65
+ dokobot crawl list # List recent tasks
66
+ dokobot crawl list --status running --limit 5
42
67
  ```
43
68
 
44
- ### `list`
69
+ #### `crawl status <taskId>`
70
+
71
+ Show task details, progress, and per-page extraction results.
45
72
 
46
- List all registered dokos on this machine.
73
+ #### `crawl result <taskId>`
74
+
75
+ Download extracted data.
47
76
 
48
77
  ```bash
49
- dokobot list
78
+ dokobot crawl result <taskId> # Print to stdout
79
+ dokobot crawl result <taskId> --output data.csv # Save to file
50
80
  ```
51
81
 
52
- ### `remove`
82
+ #### `crawl cancel <taskId>`
53
83
 
54
- Remove a registered doko.
84
+ Cancel a running task.
55
85
 
56
- ```bash
57
- dokobot remove <device-id>
58
- ```
86
+ ### `doko`
59
87
 
60
- ### `config`
88
+ Manage doko devices — connect your Chrome browser so AI agents can access real web pages, including SPAs, login-gated sites, and dynamic content.
61
89
 
62
- Configure API key and server URL interactively.
90
+ #### `doko connect`
63
91
 
64
92
  ```bash
65
- dokobot config
93
+ dokobot doko connect # Interactive setup
94
+ dokobot doko connect --name "Work Chrome" # Name your doko
95
+ dokobot doko connect --browser-url http://127.0.0.1:9222 # Custom Chrome instance
96
+ dokobot doko connect --device-id <id> # Reconnect an existing doko
66
97
  ```
67
98
 
68
- ### `update`
99
+ **Prerequisites:** Chrome with remote debugging enabled:
100
+ 1. Open `chrome://inspect/#remote-debugging`
101
+ 2. Check **"Allow remote debugging for this browser instance"**
69
102
 
70
- Check for CLI updates.
103
+ #### `doko list`
104
+
105
+ List all registered doko devices on this machine.
106
+
107
+ #### `doko remove <id>`
108
+
109
+ Remove a registered doko device.
110
+
111
+ ### Other commands
71
112
 
72
113
  ```bash
73
- dokobot update
114
+ dokobot config # Configure API key and server URL
115
+ dokobot update # Check for updates
74
116
  ```
75
117
 
76
- ## Options
118
+ ## Global Options
77
119
 
78
120
  | Option | Description |
79
121
  |--------|-------------|
@@ -81,12 +123,6 @@ dokobot update
81
123
  | `--server <url>` | Server URL (default: `https://dokobot.ai`) |
82
124
  | `--verbose` | Enable verbose logging |
83
125
 
84
- ## How It Works
85
-
86
- 1. The CLI connects to your local Chrome via [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/)
87
- 2. It registers your browser as a **doko** on the Dokobot server
88
- 3. AI agents can then send commands to your browser — navigating pages, clicking elements, extracting content, and more
89
-
90
126
  ## License
91
127
 
92
128
  MIT
package/dist/src/cli.js CHANGED
@@ -1,61 +1,19 @@
1
1
  import { Command } from 'commander';
2
- import { input, select } from '@inquirer/prompts';
3
- import { McpClient } from './mcp-client.js';
4
- import { ServerClient } from './server-client.js';
5
- import { CommandPoller } from './command-poller.js';
6
- import { Heartbeat } from './heartbeat.js';
7
- import { Executor } from './executor.js';
8
- import { getApiKey, getServerUrl, loadConfig, saveConfig, saveDevice, listDevices, removeDevice, findDeviceByName, } from './config.js';
9
- import { setLogLevel } from './logger.js';
2
+ import { input } from '@inquirer/prompts';
3
+ import { loadConfig, saveConfig } from './config.js';
10
4
  import { getCurrentVersion } from './version.js';
11
- import { getUpdateResult, checkForUpdateNow, formatUpdateNotification } from './update-checker.js';
5
+ import { checkForUpdateNow, formatUpdateNotification } from './update-checker.js';
6
+ import { registerCrawlCommands } from './crawl.js';
7
+ import { registerDokoCommands } from './doko.js';
12
8
  export function createProgram() {
13
9
  const program = new Command();
14
10
  program
15
11
  .name('dokobot')
16
- .description('Dokobot CLI - Connect Chrome browser as a doko')
12
+ .description('Dokobot CLI - Extract structured data from any web page')
17
13
  .version(getCurrentVersion())
18
14
  .option('--api-key <key>', 'API key (or set DOKO_API_KEY env)')
19
15
  .option('--server <url>', 'Server URL (default: https://dokobot.ai)')
20
16
  .option('--verbose', 'Enable verbose logging');
21
- program
22
- .command('connect')
23
- .description('Connect a Chrome browser via Chrome DevTools MCP')
24
- .option('--name <name>', 'Name for the doko')
25
- .option('--device-id <id>', 'Reuse an existing device ID')
26
- .option('--browser-url <url>', 'Connect to a running Chrome instance (e.g. http://127.0.0.1:9222)')
27
- .option('--mcp-args <args>', 'Extra arguments for chrome-devtools-mcp (comma-separated)')
28
- .action(async (options) => {
29
- const globalOpts = program.opts();
30
- if (globalOpts.verbose)
31
- setLogLevel('debug');
32
- await connectCommand(globalOpts, options);
33
- });
34
- program
35
- .command('list')
36
- .description('List registered devices')
37
- .action(() => {
38
- const devices = listDevices();
39
- if (devices.length === 0) {
40
- console.log('No registered devices.');
41
- return;
42
- }
43
- console.log('Registered devices:');
44
- for (const d of devices) {
45
- console.log(` ${d.name} (${d.id}) [${d.type}]`);
46
- }
47
- });
48
- program
49
- .command('remove <id>')
50
- .description('Remove a registered device')
51
- .action((id) => {
52
- if (removeDevice(id)) {
53
- console.log(`Removed device: ${id}`);
54
- }
55
- else {
56
- console.log(`Device not found: ${id}`);
57
- }
58
- });
59
17
  program
60
18
  .command('config')
61
19
  .description('Configure API key and server URL')
@@ -85,172 +43,8 @@ export function createProgram() {
85
43
  console.log(`You're on the latest version (${getCurrentVersion()}).`);
86
44
  }
87
45
  });
46
+ registerCrawlCommands(program);
47
+ registerDokoCommands(program);
88
48
  return program;
89
49
  }
90
- const G = '\x1b[32m';
91
- const W = '\x1b[97;1m';
92
- const B = '\x1b[1m';
93
- const D = '\x1b[2m';
94
- const R = '\x1b[0m';
95
- const BANNER = `
96
- ${G}▄████████▄${R}
97
- ${G}███${W}██${R}${G}█${W}██${R}${G}███${R} ${B}Dokobot CLI${R} ${D}v${getCurrentVersion()}${R}
98
- ${G}███████████${R} ${D}Open the full web to AI agent${R}
99
- ${G}▀████████▀${R}
100
- `;
101
- async function connectCommand(globalOpts, options) {
102
- console.log(BANNER);
103
- const serverUrl = getServerUrl(globalOpts.server);
104
- let deviceId = options.deviceId;
105
- let deviceName = options.name;
106
- let apiKey = getApiKey(globalOpts.apiKey);
107
- if (!apiKey) {
108
- if (deviceId) {
109
- const guideUrl = `${serverUrl}/guide?source=cli&deviceId=${deviceId}`;
110
- console.log(` No API key found. Opening setup guide...`);
111
- console.log(` ${D}${guideUrl}${R}`);
112
- console.log('');
113
- const { exec } = await import('child_process');
114
- exec(`open "${guideUrl}"`);
115
- apiKey = await input({ message: 'Paste your API key:' });
116
- if (!apiKey) {
117
- console.error('API key is required.');
118
- process.exit(1);
119
- }
120
- const config = loadConfig();
121
- saveConfig({ ...config, apiKey });
122
- console.log(' ✓ API key saved');
123
- }
124
- else {
125
- const { randomUUID } = await import('crypto');
126
- const preferredId = randomUUID();
127
- const guideUrl = `${serverUrl}/guide?source=cli&deviceId=${preferredId}`;
128
- console.log(` No API key found. Opening setup guide...`);
129
- console.log(` ${D}${guideUrl}${R}`);
130
- console.log('');
131
- console.log(' Follow the guide to complete the setup.');
132
- const { exec } = await import('child_process');
133
- exec(`open "${guideUrl}"`);
134
- process.exit(0);
135
- }
136
- }
137
- const serverClient = new ServerClient(serverUrl, apiKey);
138
- if (!deviceId && deviceName) {
139
- const existing = findDeviceByName(deviceName);
140
- if (existing) {
141
- deviceId = existing.id;
142
- }
143
- }
144
- if (!deviceId && !deviceName) {
145
- const devices = listDevices();
146
- const choices = [
147
- { name: '+ Create new doko', value: '__new__' },
148
- ...devices.map(d => ({ name: `${d.name} (${d.id})`, value: d.id })),
149
- ];
150
- const selected = await select({
151
- message: 'Choose a doko:',
152
- choices,
153
- });
154
- if (selected === '__new__') {
155
- deviceName = await input({
156
- message: 'Name your new doko:',
157
- default: 'My Chrome',
158
- });
159
- }
160
- else {
161
- deviceId = selected;
162
- const existing = devices.find(d => d.id === deviceId);
163
- deviceName = existing?.name;
164
- }
165
- }
166
- const mcpExtraArgs = options.mcpArgs ? options.mcpArgs.split(',') : [];
167
- const mcpClient = new McpClient();
168
- console.log(' Connecting to Chrome...');
169
- try {
170
- await mcpClient.connect({
171
- browserUrl: options.browserUrl,
172
- extraArgs: mcpExtraArgs,
173
- });
174
- }
175
- catch (error) {
176
- console.error('Failed to connect to Chrome DevTools MCP:', error instanceof Error ? error.message : error);
177
- process.exit(1);
178
- }
179
- let tools;
180
- try {
181
- tools = await mcpClient.listTools();
182
- }
183
- catch (error) {
184
- console.error(' ✗ Failed to connect to Chrome DevTools MCP:', error instanceof Error ? error.message : error);
185
- await mcpClient.disconnect();
186
- process.exit(1);
187
- }
188
- try {
189
- const check = await mcpClient.callTool('list_pages', {});
190
- if (check.isError) {
191
- const msg = check.content?.[0]?.text ?? '';
192
- console.error(' ✗ Chrome is not reachable.');
193
- console.error('');
194
- console.error(' Please enable remote debugging in Chrome:');
195
- console.error(' 1. Open chrome://inspect/#remote-debugging');
196
- console.error(' 2. Check "Allow remote debugging for this browser instance"');
197
- console.error(' 3. Re-run this command');
198
- console.error('');
199
- console.error(` Detail: ${msg}`);
200
- await mcpClient.disconnect();
201
- process.exit(1);
202
- }
203
- console.log(` ✓ Connected to Chrome (${tools.length} tools available)`);
204
- }
205
- catch (error) {
206
- console.error(' ✗ Chrome health check failed:', error instanceof Error ? error.message : error);
207
- await mcpClient.disconnect();
208
- process.exit(1);
209
- }
210
- try {
211
- const result = await serverClient.connect({
212
- type: 'chrome',
213
- deviceId,
214
- name: deviceName,
215
- tools,
216
- });
217
- deviceId = result.deviceId;
218
- deviceName = result.name;
219
- saveDevice({
220
- id: result.deviceId,
221
- name: result.name,
222
- type: result.type,
223
- createdAt: Date.now(),
224
- });
225
- console.log(` ✓ Registered "${deviceName}" (${deviceId})`);
226
- }
227
- catch (error) {
228
- console.error('Registration failed:', error instanceof Error ? error.message : error);
229
- await mcpClient.disconnect();
230
- process.exit(1);
231
- }
232
- const executor = new Executor(mcpClient);
233
- const heartbeat = new Heartbeat(serverClient, deviceId);
234
- const poller = new CommandPoller(serverClient, executor, deviceId);
235
- heartbeat.start();
236
- poller.start();
237
- const updateInfo = getUpdateResult();
238
- if (updateInfo) {
239
- console.error(formatUpdateNotification(updateInfo));
240
- }
241
- console.log('');
242
- process.stdout.write(` ${G}●${R} Listening for commands... (Ctrl+C to quit)`);
243
- const shutdown = async () => {
244
- process.stdout.write(`\r\x1b[2K`);
245
- console.log(' Shutting down...');
246
- poller.stop();
247
- heartbeat.stop();
248
- await serverClient.disconnect(deviceId);
249
- await mcpClient.disconnect();
250
- process.exit(0);
251
- };
252
- process.on('SIGINT', shutdown);
253
- process.on('SIGTERM', shutdown);
254
- await new Promise(() => { });
255
- }
256
50
  //# sourceMappingURL=cli.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAEjD,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,SAAS,CAAC;SACf,WAAW,CAAC,yDAAyD,CAAC;SACtE,OAAO,CAAC,iBAAiB,EAAE,CAAC;SAC5B,MAAM,CAAC,iBAAiB,EAAE,mCAAmC,CAAC;SAC9D,MAAM,CAAC,gBAAgB,EAAE,0CAA0C,CAAC;SACpE,MAAM,CAAC,WAAW,EAAE,wBAAwB,CAAC,CAAC;IAEjD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,kCAAkC,CAAC;SAC/C,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC;YACzB,OAAO,EAAE,UAAU;YACnB,OAAO,EAAE,MAAM,CAAC,MAAM;SACvB,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC;YAC5B,OAAO,EAAE,aAAa;YACtB,OAAO,EAAE,MAAM,CAAC,SAAS,IAAI,oBAAoB;SAClD,CAAC,CAAC;QACH,UAAU,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,uBAAuB,CAAC;SACpC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,MAAM,iBAAiB,EAAE,CAAC;QACvC,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,iCAAiC,iBAAiB,EAAE,IAAI,CAAC,CAAC;QACxE,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAE9B,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -7,7 +7,11 @@ export declare class CommandPoller {
7
7
  private polling;
8
8
  private abortController;
9
9
  private backoffMs;
10
- constructor(serverClient: ServerClient, executor: Executor, deviceId: string);
10
+ private hadError;
11
+ private onReconnect?;
12
+ constructor(serverClient: ServerClient, executor: Executor, deviceId: string, options?: {
13
+ onReconnect?: () => void;
14
+ });
11
15
  start(): void;
12
16
  stop(): void;
13
17
  private pollLoop;
@@ -7,10 +7,13 @@ export class CommandPoller {
7
7
  polling = false;
8
8
  abortController = null;
9
9
  backoffMs = 1000;
10
- constructor(serverClient, executor, deviceId) {
10
+ hadError = false;
11
+ onReconnect;
12
+ constructor(serverClient, executor, deviceId, options) {
11
13
  this.serverClient = serverClient;
12
14
  this.executor = executor;
13
15
  this.deviceId = deviceId;
16
+ this.onReconnect = options?.onReconnect;
14
17
  }
15
18
  start() {
16
19
  if (this.polling)
@@ -33,6 +36,10 @@ export class CommandPoller {
33
36
  const command = await this.serverClient.pollCommand(this.deviceId, this.abortController.signal);
34
37
  if (!this.polling)
35
38
  break;
39
+ if (this.hadError) {
40
+ this.hadError = false;
41
+ this.onReconnect?.();
42
+ }
36
43
  if (command === null) {
37
44
  this.backoffMs = 1000;
38
45
  continue;
@@ -49,6 +56,7 @@ export class CommandPoller {
49
56
  continue;
50
57
  const msg = error instanceof Error ? error.message : String(error);
51
58
  const isTimeout = msg.includes('TimeoutError') || msg.includes('Timeout') || msg.includes('fetch failed');
59
+ this.hadError = true;
52
60
  if (isTimeout) {
53
61
  logger.warn(`Poll timeout, retrying in ${this.backoffMs}ms`);
54
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"command-poller.js","sourceRoot":"","sources":["../../src/command-poller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"command-poller.js","sourceRoot":"","sources":["../../src/command-poller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerCrawlCommands(program: Command): void;