kroki 1.0.1 → 1.0.3
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 +23 -72
- package/bin/kroki.js +47 -11
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Kroki CLI
|
|
2
2
|
|
|
3
|
-
> **Browser Automation & AI Agent Bridge for Google Chrome
|
|
4
|
-
> Control live browser tabs, run deterministic workflows, and extract web data from your terminal or
|
|
3
|
+
> **Browser Automation & AI Agent Bridge for Google Chrome**
|
|
4
|
+
> Control live browser tabs, run deterministic workflows, and extract web data from your terminal or AI Coding Agents (Antigravity, Cursor, Claude Code, Windsurf).
|
|
5
5
|
|
|
6
6
|
[](https://www.npmjs.com/package/kroki)
|
|
7
7
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -11,82 +11,40 @@
|
|
|
11
11
|
|
|
12
12
|
## ⚡ Quick Start
|
|
13
13
|
|
|
14
|
-
No installation required
|
|
14
|
+
No installation required — run directly with `npx`:
|
|
15
15
|
|
|
16
16
|
### 1. Pair with your browser profile
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
2. Find your active Chrome or Dolphin{anty} profile.
|
|
21
|
-
3. Click **"Скопировать код для AI"**.
|
|
22
|
-
4. Run:
|
|
23
|
-
|
|
17
|
+
1. Open [https://kroki.ai/#/devices](https://kroki.ai/#/devices) *(Ultra plan required)*.
|
|
18
|
+
2. Click **"Скопировать код для AI"** next to your active browser profile.
|
|
19
|
+
3. Pair:
|
|
24
20
|
```bash
|
|
25
21
|
npx kroki pair <YOUR_PAIRING_CODE>
|
|
26
22
|
```
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
Connecting to profile [Dolphin WB-Bot]...
|
|
30
|
-
✔ Successfully paired with "Dolphin WB-Bot".
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### 2. Send an AI task to the live browser
|
|
34
|
-
|
|
24
|
+
### 2. Control browser or run workflows
|
|
35
25
|
```bash
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
Kroki's built-in Planner & Navigator subagent will navigate to the page, interact with elements, extract the requested information, and stream the result back to your terminal.
|
|
26
|
+
# Autonomous browser task (Planner + Navigator)
|
|
27
|
+
npx kroki "open github.com/trending and list the top 3 repositories"
|
|
40
28
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
```bash
|
|
29
|
+
# Run a saved deterministic workflow
|
|
44
30
|
npx kroki run "Export Leads" '{"query": "CTO", "limit": 20}'
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
## 📦 Global Installation (Optional)
|
|
50
|
-
|
|
51
|
-
If you prefer using `kroki` without typing `npx` every time:
|
|
52
31
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
Now you can just run:
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
kroki pair <CODE>
|
|
61
|
-
kroki "scrape the current page"
|
|
62
|
-
kroki run "My Workflow"
|
|
32
|
+
# Check status or disconnect
|
|
33
|
+
npx kroki status
|
|
34
|
+
npx kroki clear
|
|
63
35
|
```
|
|
64
36
|
|
|
65
37
|
---
|
|
66
38
|
|
|
67
39
|
## 🤖 Using with AI Agents (Antigravity, Claude Code, Cursor)
|
|
68
40
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
### In Antigravity CLI
|
|
72
|
-
|
|
73
|
-
Whenever you mention **kroki** in the chat, the agent automatically knows how to use this CLI:
|
|
74
|
-
|
|
75
|
-
> **You:** `kroki pair kroki_eyJh...`
|
|
76
|
-
> **Agent:** Pairs with the specified profile and confirms readiness.
|
|
77
|
-
>
|
|
78
|
-
> **You:** `kroki найди на Avito Mac mini M4 и выпиши самые дешевые цены`
|
|
79
|
-
> **Agent:** Executes `kroki "<task>"`, waits for Kroki in the browser to finish, and summarizes the findings.
|
|
80
|
-
|
|
81
|
-
### In Cursor / Claude Code
|
|
82
|
-
|
|
83
|
-
Add the following to your agent prompt or rule file (`.cursorrules` or `CLAUDE.md`):
|
|
41
|
+
Add the following to your project's agent instructions (`.cursorrules`, `CLAUDE.md`, or system prompt):
|
|
84
42
|
|
|
85
43
|
```markdown
|
|
86
|
-
When
|
|
87
|
-
1.
|
|
88
|
-
2. Pair
|
|
89
|
-
3.
|
|
44
|
+
When asked to automate the browser or run Kroki workflows:
|
|
45
|
+
1. Check pairing: `npx kroki status`. If not paired, ask user for pairing code from https://kroki.ai/#/devices.
|
|
46
|
+
2. Pair: `npx kroki pair <CODE>`.
|
|
47
|
+
3. Execute: `npx kroki "<task>"` or `npx kroki run "<workflow>" '[vars]'`.
|
|
90
48
|
```
|
|
91
49
|
|
|
92
50
|
---
|
|
@@ -95,18 +53,11 @@ When the user requests live browser interaction or running Kroki workflows:
|
|
|
95
53
|
|
|
96
54
|
| Command | Description |
|
|
97
55
|
| :--- | :--- |
|
|
98
|
-
| `npx kroki pair <
|
|
99
|
-
| `npx kroki "<
|
|
100
|
-
| `npx kroki run "<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
## 🔒 Security Architecture
|
|
105
|
-
|
|
106
|
-
- **Zero Global Credentials**: Pairing codes are session-bound and scoped strictly to your selected browser window (`targetDeviceId`).
|
|
107
|
-
- **Confirmation Gate**: The extension prompts you for confirmation on your computer when a connection attempt is made.
|
|
108
|
-
- **Ultra Plan Scoped**: Cloud control channels require an active Ultra entitlement.
|
|
109
|
-
- **Pure Native Node.js**: Zero third-party npm dependencies. Clean, audited, and lightweight.
|
|
56
|
+
| `npx kroki pair <CODE>` | Pair with active browser profile |
|
|
57
|
+
| `npx kroki "<task>"` | Execute browser task via autonomous Planner & Navigator |
|
|
58
|
+
| `npx kroki run "<name>" [json]` | Execute a saved Kroki deterministic workflow |
|
|
59
|
+
| `npx kroki status` | View active paired profile and device info |
|
|
60
|
+
| `npx kroki clear` | Clear active pairing session |
|
|
110
61
|
|
|
111
62
|
---
|
|
112
63
|
|
package/bin/kroki.js
CHANGED
|
@@ -70,7 +70,9 @@ class RealtimeConnection {
|
|
|
70
70
|
this.deviceId = config.deviceId;
|
|
71
71
|
this.topic = `realtime:control:${this.googleId}`;
|
|
72
72
|
this.ref = 0;
|
|
73
|
+
this.joinRef = null;
|
|
73
74
|
this.ws = null;
|
|
75
|
+
this.heartbeatTimer = null;
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
nextRef() {
|
|
@@ -90,7 +92,16 @@ class RealtimeConnection {
|
|
|
90
92
|
this.ws.onopen = () => {
|
|
91
93
|
clearTimeout(timer);
|
|
92
94
|
this.joinChannel()
|
|
93
|
-
.then(() =>
|
|
95
|
+
.then(() => {
|
|
96
|
+
this.heartbeatTimer = setInterval(() => {
|
|
97
|
+
if (this.ws && this.ws.readyState === globalThis.WebSocket.OPEN) {
|
|
98
|
+
this.ws.send(
|
|
99
|
+
JSON.stringify({ topic: 'phoenix', event: 'heartbeat', payload: {}, ref: this.nextRef() }),
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}, 25000);
|
|
103
|
+
resolve(this);
|
|
104
|
+
})
|
|
94
105
|
.catch(reject);
|
|
95
106
|
};
|
|
96
107
|
|
|
@@ -103,21 +114,21 @@ class RealtimeConnection {
|
|
|
103
114
|
|
|
104
115
|
joinChannel() {
|
|
105
116
|
return new Promise((resolve, reject) => {
|
|
106
|
-
|
|
117
|
+
this.joinRef = this.nextRef();
|
|
107
118
|
const payload = {
|
|
108
119
|
topic: this.topic,
|
|
109
120
|
event: 'phx_join',
|
|
110
121
|
payload: {
|
|
111
|
-
config: { broadcast: { self: false } },
|
|
122
|
+
config: { private: true, broadcast: { self: false } },
|
|
112
123
|
access_token: this.token,
|
|
113
124
|
},
|
|
114
|
-
ref: joinRef,
|
|
125
|
+
ref: this.joinRef,
|
|
115
126
|
};
|
|
116
127
|
|
|
117
128
|
const handler = event => {
|
|
118
129
|
try {
|
|
119
130
|
const msg = JSON.parse(event.data);
|
|
120
|
-
if (msg.ref === joinRef) {
|
|
131
|
+
if (msg.ref === this.joinRef) {
|
|
121
132
|
this.ws.removeEventListener('message', handler);
|
|
122
133
|
if (msg.payload?.status === 'ok') {
|
|
123
134
|
resolve();
|
|
@@ -173,6 +184,7 @@ class RealtimeConnection {
|
|
|
173
184
|
payload: command,
|
|
174
185
|
},
|
|
175
186
|
ref: msgRef,
|
|
187
|
+
join_ref: this.joinRef,
|
|
176
188
|
};
|
|
177
189
|
|
|
178
190
|
this.ws.send(JSON.stringify(packet));
|
|
@@ -180,6 +192,10 @@ class RealtimeConnection {
|
|
|
180
192
|
}
|
|
181
193
|
|
|
182
194
|
close() {
|
|
195
|
+
if (this.heartbeatTimer) {
|
|
196
|
+
clearInterval(this.heartbeatTimer);
|
|
197
|
+
this.heartbeatTimer = null;
|
|
198
|
+
}
|
|
183
199
|
if (this.ws) {
|
|
184
200
|
try {
|
|
185
201
|
this.ws.close();
|
|
@@ -196,7 +212,7 @@ async function pairCommand(code) {
|
|
|
196
212
|
Requires an active \x1b[33mUltra\x1b[0m plan.
|
|
197
213
|
|
|
198
214
|
1. Log in at \x1b[36mhttps://kroki.ai/#/devices\x1b[0m
|
|
199
|
-
2. Find your active browser profile
|
|
215
|
+
2. Find your active browser profile
|
|
200
216
|
3. Click \x1b[32m"Скопировать код для AI"\x1b[0m
|
|
201
217
|
4. Run:
|
|
202
218
|
\x1b[33mnpx kroki pair <YOUR_CODE>\x1b[0m
|
|
@@ -315,16 +331,32 @@ async function workflowCommand(nameOrId, varsJson) {
|
|
|
315
331
|
}
|
|
316
332
|
}
|
|
317
333
|
|
|
334
|
+
function statusCommand() {
|
|
335
|
+
const session = getActiveSession();
|
|
336
|
+
if (!session) {
|
|
337
|
+
console.log('No active paired profile.');
|
|
338
|
+
console.log('To pair, get a code from https://kroki.ai/#/devices and run:');
|
|
339
|
+
console.log(' npx kroki pair <CODE>');
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
console.log(
|
|
343
|
+
`\x1b[32m✔ Paired\x1b[0m with "${session.deviceName || session.deviceId}" (${session.platform || 'browser'})`,
|
|
344
|
+
);
|
|
345
|
+
console.log(` Device ID: ${session.deviceId}`);
|
|
346
|
+
}
|
|
347
|
+
|
|
318
348
|
function helpCommand() {
|
|
319
349
|
console.log(`
|
|
320
|
-
\x1b[1mKroki CLI\x1b[0m — Browser Automation & AI Agent Bridge for Chrome
|
|
350
|
+
\x1b[1mKroki CLI\x1b[0m — Browser Automation & AI Agent Bridge for Google Chrome
|
|
321
351
|
|
|
322
352
|
\x1b[1mUsage:\x1b[0m
|
|
323
|
-
npx kroki pair <
|
|
324
|
-
npx kroki "<
|
|
325
|
-
npx kroki run "<
|
|
353
|
+
npx kroki pair <CODE> Pair with a browser profile (from https://kroki.ai/#/devices)
|
|
354
|
+
npx kroki "<task>" Send an AI task to the live browser
|
|
355
|
+
npx kroki run "<workflow>" [json] Execute a saved workflow
|
|
356
|
+
npx kroki status View paired profile and status
|
|
357
|
+
npx kroki clear Disconnect active pairing session
|
|
326
358
|
|
|
327
|
-
\x1b[
|
|
359
|
+
\x1b[1mDashboard:\x1b[0m
|
|
328
360
|
https://kroki.ai/#/devices
|
|
329
361
|
`);
|
|
330
362
|
}
|
|
@@ -343,6 +375,10 @@ switch (first) {
|
|
|
343
375
|
});
|
|
344
376
|
break;
|
|
345
377
|
|
|
378
|
+
case 'status':
|
|
379
|
+
statusCommand();
|
|
380
|
+
break;
|
|
381
|
+
|
|
346
382
|
case 'run':
|
|
347
383
|
case 'workflow':
|
|
348
384
|
workflowCommand(rawArgs[1], rawArgs[2]).catch(e => {
|
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kroki",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Kroki Browser Automation CLI — Control Chrome
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "Kroki Browser Automation CLI — Control Chrome from terminal and AI agents",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"kroki",
|
|
7
7
|
"browser-automation",
|
|
8
8
|
"ai-agent",
|
|
9
9
|
"antigravity",
|
|
10
|
-
"dolphin-anty",
|
|
11
10
|
"chrome",
|
|
12
11
|
"mcp",
|
|
13
12
|
"cli"
|