@dokobot/cli 1.0.2 → 1.2.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,115 @@
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
4
 
5
- ## Quick Start
5
+ ## Install
6
6
 
7
7
  ```bash
8
- npx @dokobot/cli connect
8
+ npm i -g @dokobot/cli
9
9
  ```
10
10
 
11
- The CLI will guide you through setup automatically — no manual configuration needed.
12
-
13
- ## Prerequisites
14
-
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"**
19
-
20
- ## Install
11
+ ## Quick Start
21
12
 
22
13
  ```bash
23
- # Run directly (no install needed)
24
- npx @dokobot/cli connect
14
+ # Extract data from a web page
15
+ dokobot crawl create \
16
+ --url https://news.ycombinator.com \
17
+ --fields '[{"name":"title","type":"string","required":true},{"name":"points","type":"number","required":true}]' \
18
+ --format csv
25
19
 
26
- # Or install globally
27
- npm i -g @dokobot/cli
28
- dokobot connect
20
+ # Check task progress
21
+ dokobot crawl status <taskId>
22
+
23
+ # Download results
24
+ dokobot crawl result <taskId> --output data.csv
29
25
  ```
30
26
 
27
+ Requires a connected doko (browser extension or `dokobot doko connect`). See [Doko](#doko) below.
28
+
31
29
  ## Commands
32
30
 
33
- ### `connect`
31
+ ### `crawl`
34
32
 
35
- Connect a Chrome browser to Dokobot.
33
+ Extract structured data from web pages using AI.
34
+
35
+ #### `crawl create`
36
+
37
+ Create a new crawl task.
36
38
 
37
39
  ```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
40
+ dokobot crawl create \
41
+ --url https://example.com \
42
+ --fields '[{"name":"product","type":"string","required":true},{"name":"price","type":"number","required":true}]' \
43
+ --format csv
42
44
  ```
43
45
 
44
- ### `list`
46
+ | Option | Description |
47
+ |--------|-------------|
48
+ | `--url <urls...>` | Target URLs (multiple allowed) |
49
+ | `--fields <json>` | Extraction field definitions |
50
+ | `--format <type>` | Output format: `csv`, `json`, or `markdown` (default: `csv`) |
51
+ | `--max-items <n>` | Max items per page (default: `50`) |
52
+ | `--device <id>` | Specific doko device ID |
53
+
54
+ All options can also be provided interactively when omitted.
45
55
 
46
- List all registered dokos on this machine.
56
+ #### `crawl list`
47
57
 
48
58
  ```bash
49
- dokobot list
59
+ dokobot crawl list # List recent tasks
60
+ dokobot crawl list --status running --limit 5
50
61
  ```
51
62
 
52
- ### `remove`
63
+ #### `crawl status <taskId>`
64
+
65
+ Show task details, progress, and per-page extraction results.
66
+
67
+ #### `crawl result <taskId>`
53
68
 
54
- Remove a registered doko.
69
+ Download extracted data.
55
70
 
56
71
  ```bash
57
- dokobot remove <device-id>
72
+ dokobot crawl result <taskId> # Print to stdout
73
+ dokobot crawl result <taskId> --output data.csv # Save to file
58
74
  ```
59
75
 
60
- ### `config`
76
+ #### `crawl cancel <taskId>`
77
+
78
+ Cancel a running task.
79
+
80
+ ### `doko`
81
+
82
+ Manage doko devices — connect your Chrome browser so AI agents can access real web pages, including SPAs, login-gated sites, and dynamic content.
61
83
 
62
- Configure API key and server URL interactively.
84
+ #### `doko connect`
63
85
 
64
86
  ```bash
65
- dokobot config
87
+ dokobot doko connect # Interactive setup
88
+ dokobot doko connect --name "Work Chrome" # Name your doko
89
+ dokobot doko connect --browser-url http://127.0.0.1:9222 # Custom Chrome instance
90
+ dokobot doko connect --device-id <id> # Reconnect an existing doko
66
91
  ```
67
92
 
68
- ### `update`
93
+ **Prerequisites:** Chrome with remote debugging enabled:
94
+ 1. Open `chrome://inspect/#remote-debugging`
95
+ 2. Check **"Allow remote debugging for this browser instance"**
69
96
 
70
- Check for CLI updates.
97
+ #### `doko list`
98
+
99
+ List all registered doko devices on this machine.
100
+
101
+ #### `doko remove <id>`
102
+
103
+ Remove a registered doko device.
104
+
105
+ ### Other commands
71
106
 
72
107
  ```bash
73
- dokobot update
108
+ dokobot config # Configure API key and server URL
109
+ dokobot update # Check for updates
74
110
  ```
75
111
 
76
- ## Options
112
+ ## Global Options
77
113
 
78
114
  | Option | Description |
79
115
  |--------|-------------|
@@ -81,12 +117,6 @@ dokobot update
81
117
  | `--server <url>` | Server URL (default: `https://dokobot.ai`) |
82
118
  | `--verbose` | Enable verbose logging |
83
119
 
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
120
  ## License
91
121
 
92
122
  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;