kroki 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/kroki.js +63 -10
- package/package.json +1 -1
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();
|
|
@@ -149,10 +160,18 @@ class RealtimeConnection {
|
|
|
149
160
|
|
|
150
161
|
if (onEvent) onEvent(envelope);
|
|
151
162
|
|
|
152
|
-
if (
|
|
163
|
+
if (
|
|
164
|
+
envelope.kind === 'chat_task_complete' ||
|
|
165
|
+
envelope.kind === 'workflow_complete' ||
|
|
166
|
+
envelope.kind === 'pair_approved'
|
|
167
|
+
) {
|
|
153
168
|
clearTimeout(timer);
|
|
154
169
|
this.ws.removeEventListener('message', handler);
|
|
155
170
|
resolve(envelope.payload);
|
|
171
|
+
} else if (envelope.kind === 'pair_rejected') {
|
|
172
|
+
clearTimeout(timer);
|
|
173
|
+
this.ws.removeEventListener('message', handler);
|
|
174
|
+
reject(new Error('Pairing request was rejected in Kroki browser.'));
|
|
156
175
|
} else if (envelope.kind === 'error') {
|
|
157
176
|
clearTimeout(timer);
|
|
158
177
|
this.ws.removeEventListener('message', handler);
|
|
@@ -173,6 +192,7 @@ class RealtimeConnection {
|
|
|
173
192
|
payload: command,
|
|
174
193
|
},
|
|
175
194
|
ref: msgRef,
|
|
195
|
+
join_ref: this.joinRef,
|
|
176
196
|
};
|
|
177
197
|
|
|
178
198
|
this.ws.send(JSON.stringify(packet));
|
|
@@ -180,6 +200,10 @@ class RealtimeConnection {
|
|
|
180
200
|
}
|
|
181
201
|
|
|
182
202
|
close() {
|
|
203
|
+
if (this.heartbeatTimer) {
|
|
204
|
+
clearInterval(this.heartbeatTimer);
|
|
205
|
+
this.heartbeatTimer = null;
|
|
206
|
+
}
|
|
183
207
|
if (this.ws) {
|
|
184
208
|
try {
|
|
185
209
|
this.ws.close();
|
|
@@ -211,6 +235,28 @@ Requires an active \x1b[33mUltra\x1b[0m plan.
|
|
|
211
235
|
const conn = new RealtimeConnection(payload);
|
|
212
236
|
await conn.connect();
|
|
213
237
|
|
|
238
|
+
console.log(`\x1b[33mWaiting for confirmation in Kroki browser (click "Разрешить")...\x1b[0m`);
|
|
239
|
+
|
|
240
|
+
const pairCmd = {
|
|
241
|
+
v: 1,
|
|
242
|
+
id: `pair-${Date.now()}`,
|
|
243
|
+
kind: 'pair_request',
|
|
244
|
+
targetDeviceId: payload.deviceId,
|
|
245
|
+
taskId: `pair-${Date.now()}`,
|
|
246
|
+
issuedAt: Date.now(),
|
|
247
|
+
payload: {
|
|
248
|
+
clientName: 'Antigravity CLI',
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
try {
|
|
253
|
+
await conn.sendCommand(pairCmd, undefined, 60000);
|
|
254
|
+
} catch (err) {
|
|
255
|
+
conn.close();
|
|
256
|
+
console.error(`\x1b[31m✖ ${err.message}\x1b[0m`);
|
|
257
|
+
process.exit(1);
|
|
258
|
+
}
|
|
259
|
+
|
|
214
260
|
saveActiveSession({
|
|
215
261
|
...payload,
|
|
216
262
|
pairedAt: Date.now(),
|
|
@@ -252,13 +298,19 @@ async function taskCommand(taskText) {
|
|
|
252
298
|
console.log(`\x1b[36m[Kroki: ${session.deviceName || 'Browser'}]\x1b[0m Running: "${taskText}"...`);
|
|
253
299
|
const result = await conn.sendCommand(command, ev => {
|
|
254
300
|
if (ev.kind === 'execution') {
|
|
255
|
-
const
|
|
256
|
-
if (
|
|
301
|
+
const details = ev.payload?.data?.details || ev.payload?.title || ev.payload?.type;
|
|
302
|
+
if (details && typeof details === 'string') {
|
|
303
|
+
const firstLine = details.split('\n')[0].trim();
|
|
304
|
+
if (firstLine) console.log(` \x1b[90m→ ${firstLine.slice(0, 80)}\x1b[0m`);
|
|
305
|
+
}
|
|
257
306
|
}
|
|
258
307
|
});
|
|
259
308
|
|
|
260
309
|
console.log('\x1b[32m✔ Task completed.\x1b[0m');
|
|
261
310
|
if (result && typeof result === 'object') {
|
|
311
|
+
if (result.message) {
|
|
312
|
+
console.log(`\n\x1b[1m${result.message}\x1b[0m\n`);
|
|
313
|
+
}
|
|
262
314
|
console.log(JSON.stringify(result, null, 2));
|
|
263
315
|
}
|
|
264
316
|
} finally {
|
|
@@ -323,7 +375,9 @@ function statusCommand() {
|
|
|
323
375
|
console.log(' npx kroki pair <CODE>');
|
|
324
376
|
return;
|
|
325
377
|
}
|
|
326
|
-
console.log(
|
|
378
|
+
console.log(
|
|
379
|
+
`\x1b[32m✔ Paired\x1b[0m with "${session.deviceName || session.deviceId}" (${session.platform || 'browser'})`,
|
|
380
|
+
);
|
|
327
381
|
console.log(` Device ID: ${session.deviceId}`);
|
|
328
382
|
}
|
|
329
383
|
|
|
@@ -388,4 +442,3 @@ switch (first) {
|
|
|
388
442
|
});
|
|
389
443
|
break;
|
|
390
444
|
}
|
|
391
|
-
|