@parall/daemon 1.32.1 → 1.34.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/bundle/bb-browser-daemon.js +15628 -0
- package/bundle/buildDomTree.js +1501 -0
- package/bundle/manifest.json +19 -11
- package/bundle/parall-claude-agent.js +185 -25
- package/bundle/parall-codex-agent.js +185 -25
- package/bundle/parall-daemon.js +4647 -2856
- package/bundle/parall-openclaw-agent.js +4 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +8 -2
- package/dist/clip-runtime/browser-dependency.d.ts +20 -0
- package/dist/clip-runtime/browser-dependency.d.ts.map +1 -0
- package/dist/clip-runtime/browser-dependency.js +52 -0
- package/dist/clip-runtime/browser-profile-manager.d.ts +70 -0
- package/dist/clip-runtime/browser-profile-manager.d.ts.map +1 -0
- package/dist/clip-runtime/browser-profile-manager.js +608 -0
- package/dist/clip-runtime/clip-provider.d.ts +10 -1
- package/dist/clip-runtime/clip-provider.d.ts.map +1 -1
- package/dist/clip-runtime/clip-provider.js +63 -21
- package/dist/clip-runtime/hub-client.d.ts +79 -0
- package/dist/clip-runtime/hub-client.d.ts.map +1 -0
- package/dist/clip-runtime/hub-client.js +320 -0
- package/dist/clip-runtime/index.d.ts +2 -0
- package/dist/clip-runtime/index.d.ts.map +1 -1
- package/dist/clip-runtime/index.js +2 -0
- package/dist/clip-runtime/ipc.d.ts +6 -0
- package/dist/clip-runtime/ipc.d.ts.map +1 -1
- package/dist/clip-runtime/manifest.d.ts +16 -8
- package/dist/clip-runtime/manifest.d.ts.map +1 -1
- package/dist/clip-runtime/manifest.js +13 -0
- package/dist/clip-runtime/process-manager.d.ts +55 -3
- package/dist/clip-runtime/process-manager.d.ts.map +1 -1
- package/dist/clip-runtime/process-manager.js +226 -48
- package/dist/clip-runtime/process.d.ts +15 -1
- package/dist/clip-runtime/process.d.ts.map +1 -1
- package/dist/clip-runtime/process.js +73 -10
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -0
- package/dist/index.js +46 -5
- package/dist/runtime-bin-resolver.d.ts +7 -0
- package/dist/runtime-bin-resolver.d.ts.map +1 -0
- package/dist/runtime-bin-resolver.js +292 -0
- package/dist/supervisor.d.ts +53 -4
- package/dist/supervisor.d.ts.map +1 -1
- package/dist/supervisor.js +449 -117
- package/package.json +7 -6
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import * as http2 from 'node:http2';
|
|
17
17
|
import { ClipCommandError } from './process.js';
|
|
18
|
+
import { isBrowserDependencyName } from './browser-dependency.js';
|
|
18
19
|
// ---------------------------------------------------------------------------
|
|
19
20
|
// Connect envelope helpers
|
|
20
21
|
// ---------------------------------------------------------------------------
|
|
@@ -66,10 +67,17 @@ export class ClipProvider {
|
|
|
66
67
|
statusUnsubscribe = null;
|
|
67
68
|
manifestUnsubscribe = null;
|
|
68
69
|
needsReregister = false;
|
|
69
|
-
|
|
70
|
+
// Monotonic stream id, bumped by openStream(). Handlers from a stream that a
|
|
71
|
+
// newer openStream() has superseded bail in handleDisconnect(gen), so their
|
|
72
|
+
// late close/end/error can't reconnect against the healthy replacement.
|
|
73
|
+
streamGeneration = 0;
|
|
70
74
|
static RECONNECT_BASE_MS = 5_000;
|
|
71
75
|
static RECONNECT_MAX_MS = 60_000;
|
|
72
76
|
static HEARTBEAT_INTERVAL_MS = 30_000;
|
|
77
|
+
// After this many consecutive reconnect failures (and every multiple
|
|
78
|
+
// thereafter), ask the supervisor to refetch the endpoint. See
|
|
79
|
+
// onPersistentFailure.
|
|
80
|
+
static PERSISTENT_FAILURE_ATTEMPT = 3;
|
|
73
81
|
constructor(opts) {
|
|
74
82
|
this.opts = opts;
|
|
75
83
|
}
|
|
@@ -99,6 +107,8 @@ export class ClipProvider {
|
|
|
99
107
|
async openStream() {
|
|
100
108
|
if (this.stopped)
|
|
101
109
|
return;
|
|
110
|
+
// Bind this stream's handlers to a fresh generation; older streams go stale.
|
|
111
|
+
const gen = ++this.streamGeneration;
|
|
102
112
|
try {
|
|
103
113
|
this.closeStream();
|
|
104
114
|
this.closeSession();
|
|
@@ -107,10 +117,10 @@ export class ClipProvider {
|
|
|
107
117
|
this.session = http2.connect(authority);
|
|
108
118
|
this.session.on('error', (err) => {
|
|
109
119
|
this.opts.log.warn(`[clip-provider] h2 session error: ${String(err)}`);
|
|
110
|
-
this.handleDisconnect();
|
|
120
|
+
this.handleDisconnect(gen);
|
|
111
121
|
});
|
|
112
122
|
this.session.on('close', () => {
|
|
113
|
-
this.handleDisconnect();
|
|
123
|
+
this.handleDisconnect(gen);
|
|
114
124
|
});
|
|
115
125
|
this.stream = this.session.request({
|
|
116
126
|
':method': 'POST',
|
|
@@ -121,7 +131,7 @@ export class ClipProvider {
|
|
|
121
131
|
});
|
|
122
132
|
this.stream.on('error', (err) => {
|
|
123
133
|
this.opts.log.warn(`[clip-provider] stream error: ${String(err)}`);
|
|
124
|
-
this.handleDisconnect();
|
|
134
|
+
this.handleDisconnect(gen);
|
|
125
135
|
});
|
|
126
136
|
// Read response envelopes
|
|
127
137
|
const decoder = new EnvelopeDecoder();
|
|
@@ -144,21 +154,23 @@ export class ClipProvider {
|
|
|
144
154
|
});
|
|
145
155
|
this.stream.on('end', () => {
|
|
146
156
|
this.opts.log.info('[clip-provider] stream ended by hub');
|
|
147
|
-
this.handleDisconnect();
|
|
157
|
+
this.handleDisconnect(gen);
|
|
148
158
|
});
|
|
149
159
|
this.stream.on('close', () => {
|
|
150
|
-
this.handleDisconnect();
|
|
160
|
+
this.handleDisconnect(gen);
|
|
151
161
|
});
|
|
152
162
|
// Send RegisterRequest as the first message.
|
|
153
163
|
await this.sendRegister();
|
|
154
164
|
}
|
|
155
165
|
catch (err) {
|
|
156
166
|
this.opts.log.warn(`[clip-provider] connect failed: ${String(err)}`);
|
|
157
|
-
this.
|
|
167
|
+
this.handleDisconnect(gen);
|
|
158
168
|
}
|
|
159
169
|
}
|
|
160
|
-
handleDisconnect() {
|
|
161
|
-
if (
|
|
170
|
+
handleDisconnect(gen) {
|
|
171
|
+
if (gen !== this.streamGeneration)
|
|
172
|
+
return; // stale event from a superseded stream
|
|
173
|
+
if (this.stopped)
|
|
162
174
|
return;
|
|
163
175
|
if (!this.connected && this.reconnectTimer)
|
|
164
176
|
return; // already scheduling
|
|
@@ -172,6 +184,19 @@ export class ClipProvider {
|
|
|
172
184
|
const delay = Math.min(ClipProvider.RECONNECT_BASE_MS * Math.pow(2, this.reconnectAttempt), ClipProvider.RECONNECT_MAX_MS);
|
|
173
185
|
this.reconnectAttempt++;
|
|
174
186
|
this.opts.log.info(`[clip-provider] reconnecting in ${delay}ms (attempt ${this.reconnectAttempt})`);
|
|
187
|
+
if (this.reconnectAttempt % ClipProvider.PERSISTENT_FAILURE_ATTEMPT === 0) {
|
|
188
|
+
// The endpoint may have changed server-side since we booted (e.g.
|
|
189
|
+
// clip_provider_url rolled out while our ws-gateway WS never bounced to
|
|
190
|
+
// re-trigger machine.hello). Ask the supervisor to refetch machine config;
|
|
191
|
+
// if the URL changed, applyClipProviderState rebuilds this provider against
|
|
192
|
+
// the new endpoint. Backoff naturally throttles these refetches.
|
|
193
|
+
try {
|
|
194
|
+
this.opts.onPersistentFailure?.();
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
this.opts.log.warn(`[clip-provider] onPersistentFailure threw: ${String(err)}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
175
200
|
this.reconnectTimer = setTimeout(() => {
|
|
176
201
|
this.reconnectTimer = null;
|
|
177
202
|
void this.openStream();
|
|
@@ -198,13 +223,11 @@ export class ClipProvider {
|
|
|
198
223
|
if (this.needsReregister) {
|
|
199
224
|
this.needsReregister = false;
|
|
200
225
|
this.opts.log.info('[clip-provider] manifest updated — reconnecting to re-register clips');
|
|
201
|
-
this.intentionalClose = true;
|
|
202
|
-
this.closeStream();
|
|
203
|
-
this.closeSession();
|
|
204
|
-
this.intentionalClose = false;
|
|
205
226
|
this.connected = false;
|
|
206
227
|
this.clearHeartbeatTimer();
|
|
207
228
|
this.clearReconnectTimer();
|
|
229
|
+
// openStream() bumps the generation before closing the old stream, so its
|
|
230
|
+
// late close events fail the gen check (closing inline would re-arm the flap).
|
|
208
231
|
void this.openStream();
|
|
209
232
|
return;
|
|
210
233
|
}
|
|
@@ -313,9 +336,25 @@ export class ClipProvider {
|
|
|
313
336
|
input = decoded;
|
|
314
337
|
}
|
|
315
338
|
}
|
|
339
|
+
// Two routing shapes share this handler, distinguished by clip_name:
|
|
340
|
+
// - "browser" capability (cross-machine host hop): clip_token is the
|
|
341
|
+
// PLAINTEXT browser_profile_id (used directly as the bb-browser
|
|
342
|
+
// account). No local subprocess — serve it against the host
|
|
343
|
+
// BrowserProfileManager.
|
|
344
|
+
// - ordinary main invoke (this machine is the execution machine): the
|
|
345
|
+
// hub carries the executing clip_id in clip_token (Pinix wire
|
|
346
|
+
// compatibility — no dedicated field). It shards the process pool and
|
|
347
|
+
// fixes the caller identity so the clip's nested browser dependency
|
|
348
|
+
// invoke can resolve its binding via the hub. Empty clip_token (plain
|
|
349
|
+
// non-browser clips) falls back to the default unsharded process.
|
|
350
|
+
const invocation = isBrowserDependencyName(clipName)
|
|
351
|
+
? this.opts.clipManager.invokeBrowserCapability(cmd.clipToken ?? '', command, input)
|
|
352
|
+
: this.opts.clipManager.invoke(clipName, command, input, {
|
|
353
|
+
clipId: cmd.clipToken || undefined,
|
|
354
|
+
});
|
|
316
355
|
let timer;
|
|
317
356
|
const output = await Promise.race([
|
|
318
|
-
|
|
357
|
+
invocation,
|
|
319
358
|
new Promise((_, reject) => {
|
|
320
359
|
timer = setTimeout(() => reject(new Error('invoke timeout')), timeoutMs);
|
|
321
360
|
}),
|
|
@@ -378,7 +417,10 @@ export class ClipProvider {
|
|
|
378
417
|
// Clip registration helpers
|
|
379
418
|
// ---------------------------------------------------------------------------
|
|
380
419
|
buildClipRegistrations() {
|
|
381
|
-
|
|
420
|
+
// getProviderClips() appends the synthetic "browser" capability on hosts
|
|
421
|
+
// that can serve BrowserProfiles, so the hub can route cross-machine
|
|
422
|
+
// browser invokes to this provider.
|
|
423
|
+
const clips = this.opts.clipManager.getProviderClips();
|
|
382
424
|
return clips.map((clip) => this.clipConfigToRegistration(clip));
|
|
383
425
|
}
|
|
384
426
|
clipConfigToRegistration(clip) {
|
|
@@ -394,7 +436,7 @@ export class ClipProvider {
|
|
|
394
436
|
domain: manifest?.domain,
|
|
395
437
|
commands,
|
|
396
438
|
hasWeb: manifest?.hasWeb ?? false,
|
|
397
|
-
dependencies: this.dependencyNames(manifest?.dependencies),
|
|
439
|
+
dependencies: this.dependencyNames(manifest?.dependencies, manifest?.dependencySlots),
|
|
398
440
|
tokenProtected: Boolean(clip.token),
|
|
399
441
|
name: pkg,
|
|
400
442
|
patterns: manifest?.patterns,
|
|
@@ -410,13 +452,13 @@ export class ClipProvider {
|
|
|
410
452
|
output: detail.output,
|
|
411
453
|
};
|
|
412
454
|
}
|
|
413
|
-
dependencyNames(
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
const names = Object.entries(deps)
|
|
455
|
+
dependencyNames(...depMaps) {
|
|
456
|
+
const names = depMaps
|
|
457
|
+
.flatMap((deps) => (deps ? Object.entries(deps) : []))
|
|
417
458
|
.map(([slot, dep]) => dep.package ?? slot)
|
|
418
459
|
.filter((name) => name.length > 0);
|
|
419
|
-
|
|
460
|
+
const uniqueNames = Array.from(new Set(names));
|
|
461
|
+
return uniqueNames.length > 0 ? uniqueNames : undefined;
|
|
420
462
|
}
|
|
421
463
|
stringEntities(entities) {
|
|
422
464
|
if (!entities)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HubClient — Connect-RPC unary/server-streaming client the execution-side
|
|
3
|
+
* daemon uses to resolve cross-machine dependency bindings and forward
|
|
4
|
+
* dependency invokes through the Clip Service (Hub).
|
|
5
|
+
*
|
|
6
|
+
* The execution daemon (machine A) does NOT verify the binding's clip_token —
|
|
7
|
+
* it reads its binding via GetBindings, then passes clip_token straight to
|
|
8
|
+
* Invoke(clip_name="browser", ...). The hub verifies the signed token, resolves
|
|
9
|
+
* the bound BrowserProfile's host machine (B), and forwards the InvokeCommand
|
|
10
|
+
* there. See docs/engineering-design/browser-profile-clip-integration.md §11.3.
|
|
11
|
+
*
|
|
12
|
+
* Protocol (same Connect envelope framing as clip-provider.ts):
|
|
13
|
+
* POST /clip.v1.ClipHubService/GetBindings (unary)
|
|
14
|
+
* POST /clip.v1.ClipHubService/Invoke (server-streaming)
|
|
15
|
+
* Content-Type: application/connect+json
|
|
16
|
+
* Authorization: Bearer mck_xxx (scope-gated to the caller's
|
|
17
|
+
* own executing Clip)
|
|
18
|
+
* Body / Response: envelope-framed JSON
|
|
19
|
+
* [flags:1][length:4 big-endian][JSON payload]
|
|
20
|
+
* flags=0x00 data, flags=0x02 end-of-stream (trailers)
|
|
21
|
+
*/
|
|
22
|
+
/** Pinix v2 ClipBinding — a resolved dependency-slot target. */
|
|
23
|
+
export interface ClipBinding {
|
|
24
|
+
alias?: string;
|
|
25
|
+
hub?: string;
|
|
26
|
+
hubToken?: string;
|
|
27
|
+
clipToken?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Error surfaced by a hub Invoke that the hub flagged as a clip
|
|
31
|
+
* application-level rejection (errorIsCommand=true). The execution-side IPC
|
|
32
|
+
* layer maps this to a non-fatal ClipCommandError so the calling clip is not
|
|
33
|
+
* crashed by a recoverable browser command failure.
|
|
34
|
+
*/
|
|
35
|
+
export declare class HubCommandError extends Error {
|
|
36
|
+
readonly code?: string;
|
|
37
|
+
constructor(message: string, code?: string);
|
|
38
|
+
}
|
|
39
|
+
export interface HubClientOptions {
|
|
40
|
+
/** Clip Service URL (grey-cloud clip-rpc host for BYOC). */
|
|
41
|
+
serviceUrl: string;
|
|
42
|
+
/** mck_xxx machine key — scope-gated by the hub to this machine's Clips. */
|
|
43
|
+
authKey: string;
|
|
44
|
+
/** Optional per-request timeout. */
|
|
45
|
+
requestTimeoutMs?: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Stateless Connect-RPC client. Each call opens a short-lived HTTP/2 session;
|
|
49
|
+
* dependency invokes are infrequent relative to the agent dispatch loop, so a
|
|
50
|
+
* pooled session is not worth the lifecycle complexity here.
|
|
51
|
+
*/
|
|
52
|
+
export declare class HubClient {
|
|
53
|
+
private readonly opts;
|
|
54
|
+
constructor(opts: HubClientOptions);
|
|
55
|
+
/**
|
|
56
|
+
* GetBindings(clip_name=clipId) → slot→binding map. The hub gates
|
|
57
|
+
* this to Clips the caller machine actually executes. GetBindings is a
|
|
58
|
+
* UNARY Connect RPC, so it uses raw JSON framing (not the streaming envelope).
|
|
59
|
+
*/
|
|
60
|
+
getBindings(clipId: string): Promise<Record<string, ClipBinding>>;
|
|
61
|
+
/**
|
|
62
|
+
* Invoke a clip command through the hub, passing the binding's clip_token
|
|
63
|
+
* through untouched. Aggregates server-streamed output chunks into one value.
|
|
64
|
+
* The execution daemon does not verify clip_token — the hub does.
|
|
65
|
+
*/
|
|
66
|
+
invoke(clipName: string, command: string, input: unknown, clipToken: string): Promise<unknown>;
|
|
67
|
+
/**
|
|
68
|
+
* Unary Connect call: raw JSON body (no envelope), Content-Type
|
|
69
|
+
* application/json. The response is raw JSON; a non-2xx status carries a
|
|
70
|
+
* Connect error envelope ({code,message}) in the body.
|
|
71
|
+
*/
|
|
72
|
+
private unary;
|
|
73
|
+
/**
|
|
74
|
+
* Server-streaming Connect call: enveloped frames over
|
|
75
|
+
* application/connect+json. Collects all response envelopes.
|
|
76
|
+
*/
|
|
77
|
+
private serverStream;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=hub-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub-client.d.ts","sourceRoot":"","sources":["../../src/clip-runtime/hub-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAgDH,gEAAgE;AAChE,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAaD;;;;;GAKG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;gBACX,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;CAK3C;AAED,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;GAIG;AACH,qBAAa,SAAS;IACR,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,gBAAgB;IAEnD;;;;OAIG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAOvE;;;;OAIG;IACG,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC;IAgCnB;;;;OAIG;IACH,OAAO,CAAC,KAAK;IAgEb;;;OAGG;IACH,OAAO,CAAC,YAAY;CAiGrB"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HubClient — Connect-RPC unary/server-streaming client the execution-side
|
|
3
|
+
* daemon uses to resolve cross-machine dependency bindings and forward
|
|
4
|
+
* dependency invokes through the Clip Service (Hub).
|
|
5
|
+
*
|
|
6
|
+
* The execution daemon (machine A) does NOT verify the binding's clip_token —
|
|
7
|
+
* it reads its binding via GetBindings, then passes clip_token straight to
|
|
8
|
+
* Invoke(clip_name="browser", ...). The hub verifies the signed token, resolves
|
|
9
|
+
* the bound BrowserProfile's host machine (B), and forwards the InvokeCommand
|
|
10
|
+
* there. See docs/engineering-design/browser-profile-clip-integration.md §11.3.
|
|
11
|
+
*
|
|
12
|
+
* Protocol (same Connect envelope framing as clip-provider.ts):
|
|
13
|
+
* POST /clip.v1.ClipHubService/GetBindings (unary)
|
|
14
|
+
* POST /clip.v1.ClipHubService/Invoke (server-streaming)
|
|
15
|
+
* Content-Type: application/connect+json
|
|
16
|
+
* Authorization: Bearer mck_xxx (scope-gated to the caller's
|
|
17
|
+
* own executing Clip)
|
|
18
|
+
* Body / Response: envelope-framed JSON
|
|
19
|
+
* [flags:1][length:4 big-endian][JSON payload]
|
|
20
|
+
* flags=0x00 data, flags=0x02 end-of-stream (trailers)
|
|
21
|
+
*/
|
|
22
|
+
import * as http2 from 'node:http2';
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Connect envelope helpers (mirror clip-provider.ts; JSON mode)
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
const ENVELOPE_FLAG_DATA = 0x00;
|
|
27
|
+
const ENVELOPE_FLAG_TRAILER = 0x02;
|
|
28
|
+
const MAX_FRAME_LENGTH = 16 * 1024 * 1024; // 16 MiB
|
|
29
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
|
|
30
|
+
function encodeEnvelope(msg) {
|
|
31
|
+
const json = Buffer.from(JSON.stringify(msg), 'utf-8');
|
|
32
|
+
const header = Buffer.alloc(5);
|
|
33
|
+
header[0] = ENVELOPE_FLAG_DATA;
|
|
34
|
+
header.writeUInt32BE(json.length, 1);
|
|
35
|
+
return Buffer.concat([header, json]);
|
|
36
|
+
}
|
|
37
|
+
class EnvelopeDecoder {
|
|
38
|
+
buf = Buffer.alloc(0);
|
|
39
|
+
push(chunk) {
|
|
40
|
+
this.buf = this.buf.length === 0 ? Buffer.from(chunk) : Buffer.concat([this.buf, chunk]);
|
|
41
|
+
}
|
|
42
|
+
*flush() {
|
|
43
|
+
while (this.buf.length >= 5) {
|
|
44
|
+
const flags = this.buf[0];
|
|
45
|
+
const length = this.buf.readUInt32BE(1);
|
|
46
|
+
if (length > MAX_FRAME_LENGTH) {
|
|
47
|
+
this.buf = Buffer.alloc(0);
|
|
48
|
+
throw new Error(`envelope frame too large: ${length} bytes`);
|
|
49
|
+
}
|
|
50
|
+
if (this.buf.length < 5 + length)
|
|
51
|
+
break; // incomplete frame
|
|
52
|
+
const payload = this.buf.subarray(5, 5 + length);
|
|
53
|
+
this.buf = Buffer.from(this.buf.subarray(5 + length));
|
|
54
|
+
yield { flags, payload };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Error surfaced by a hub Invoke that the hub flagged as a clip
|
|
60
|
+
* application-level rejection (errorIsCommand=true). The execution-side IPC
|
|
61
|
+
* layer maps this to a non-fatal ClipCommandError so the calling clip is not
|
|
62
|
+
* crashed by a recoverable browser command failure.
|
|
63
|
+
*/
|
|
64
|
+
export class HubCommandError extends Error {
|
|
65
|
+
code;
|
|
66
|
+
constructor(message, code) {
|
|
67
|
+
super(message);
|
|
68
|
+
this.name = 'HubCommandError';
|
|
69
|
+
this.code = code;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Stateless Connect-RPC client. Each call opens a short-lived HTTP/2 session;
|
|
74
|
+
* dependency invokes are infrequent relative to the agent dispatch loop, so a
|
|
75
|
+
* pooled session is not worth the lifecycle complexity here.
|
|
76
|
+
*/
|
|
77
|
+
export class HubClient {
|
|
78
|
+
opts;
|
|
79
|
+
constructor(opts) {
|
|
80
|
+
this.opts = opts;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* GetBindings(clip_name=clipId) → slot→binding map. The hub gates
|
|
84
|
+
* this to Clips the caller machine actually executes. GetBindings is a
|
|
85
|
+
* UNARY Connect RPC, so it uses raw JSON framing (not the streaming envelope).
|
|
86
|
+
*/
|
|
87
|
+
async getBindings(clipId) {
|
|
88
|
+
const res = await this.unary('GetBindings', {
|
|
89
|
+
clipName: clipId,
|
|
90
|
+
});
|
|
91
|
+
return res.bindings ?? {};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Invoke a clip command through the hub, passing the binding's clip_token
|
|
95
|
+
* through untouched. Aggregates server-streamed output chunks into one value.
|
|
96
|
+
* The execution daemon does not verify clip_token — the hub does.
|
|
97
|
+
*/
|
|
98
|
+
async invoke(clipName, command, input, clipToken) {
|
|
99
|
+
const inputBytes = Buffer.from(input === undefined ? '{}' : JSON.stringify(input), 'utf-8').toString('base64');
|
|
100
|
+
const responses = await this.serverStream('Invoke', {
|
|
101
|
+
clipName,
|
|
102
|
+
command,
|
|
103
|
+
input: inputBytes,
|
|
104
|
+
clipToken,
|
|
105
|
+
});
|
|
106
|
+
const chunks = [];
|
|
107
|
+
for (const resp of responses) {
|
|
108
|
+
if (resp.error) {
|
|
109
|
+
const message = resp.error.message || 'hub invoke failed';
|
|
110
|
+
if (resp.errorIsCommand)
|
|
111
|
+
throw new HubCommandError(message, resp.error.code);
|
|
112
|
+
throw new Error(message);
|
|
113
|
+
}
|
|
114
|
+
if (resp.output)
|
|
115
|
+
chunks.push(decodeOutput(resp.output));
|
|
116
|
+
}
|
|
117
|
+
if (chunks.length === 0)
|
|
118
|
+
return null;
|
|
119
|
+
if (chunks.length === 1)
|
|
120
|
+
return chunks[0];
|
|
121
|
+
return chunks;
|
|
122
|
+
}
|
|
123
|
+
// -------------------------------------------------------------------------
|
|
124
|
+
// Transport
|
|
125
|
+
// -------------------------------------------------------------------------
|
|
126
|
+
/**
|
|
127
|
+
* Unary Connect call: raw JSON body (no envelope), Content-Type
|
|
128
|
+
* application/json. The response is raw JSON; a non-2xx status carries a
|
|
129
|
+
* Connect error envelope ({code,message}) in the body.
|
|
130
|
+
*/
|
|
131
|
+
unary(method, request) {
|
|
132
|
+
const timeoutMs = this.opts.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
133
|
+
const url = new URL(this.opts.serviceUrl);
|
|
134
|
+
return new Promise((resolve, reject) => {
|
|
135
|
+
let settled = false;
|
|
136
|
+
const session = http2.connect(url.origin);
|
|
137
|
+
const chunks = [];
|
|
138
|
+
let status = 0;
|
|
139
|
+
const cleanup = () => {
|
|
140
|
+
clearTimeout(timer);
|
|
141
|
+
try {
|
|
142
|
+
session.close();
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
/* already closed */
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
const fail = (err) => {
|
|
149
|
+
if (settled)
|
|
150
|
+
return;
|
|
151
|
+
settled = true;
|
|
152
|
+
cleanup();
|
|
153
|
+
reject(err);
|
|
154
|
+
};
|
|
155
|
+
const timer = setTimeout(() => fail(new Error(`hub ${method} timed out`)), timeoutMs);
|
|
156
|
+
timer.unref?.();
|
|
157
|
+
session.on('error', (err) => fail(new Error(`hub h2 session error: ${String(err)}`)));
|
|
158
|
+
const body = Buffer.from(JSON.stringify(request), 'utf-8');
|
|
159
|
+
const stream = session.request({
|
|
160
|
+
':method': 'POST',
|
|
161
|
+
':path': `/clip.v1.ClipHubService/${method}`,
|
|
162
|
+
'content-type': 'application/json',
|
|
163
|
+
'connect-protocol-version': '1',
|
|
164
|
+
authorization: `Bearer ${this.opts.authKey}`,
|
|
165
|
+
});
|
|
166
|
+
stream.on('response', (headers) => {
|
|
167
|
+
status = Number(headers[':status'] ?? 0);
|
|
168
|
+
});
|
|
169
|
+
stream.on('error', (err) => fail(new Error(`hub ${method} stream error: ${String(err)}`)));
|
|
170
|
+
stream.on('data', (chunk) => chunks.push(chunk));
|
|
171
|
+
stream.on('end', () => {
|
|
172
|
+
if (settled)
|
|
173
|
+
return;
|
|
174
|
+
settled = true;
|
|
175
|
+
cleanup();
|
|
176
|
+
const text = Buffer.concat(chunks).toString('utf-8');
|
|
177
|
+
if (status < 200 || status >= 300) {
|
|
178
|
+
reject(new Error(`hub ${method} failed (${status}): ${connectErrorMessage(text)}`));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
try {
|
|
182
|
+
resolve((text ? JSON.parse(text) : {}));
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
reject(new Error(`hub ${method} bad response: ${String(err)}`));
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
stream.end(body);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Server-streaming Connect call: enveloped frames over
|
|
193
|
+
* application/connect+json. Collects all response envelopes.
|
|
194
|
+
*/
|
|
195
|
+
serverStream(method, request) {
|
|
196
|
+
const timeoutMs = this.opts.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
197
|
+
const url = new URL(this.opts.serviceUrl);
|
|
198
|
+
return new Promise((resolve, reject) => {
|
|
199
|
+
let settled = false;
|
|
200
|
+
const session = http2.connect(url.origin);
|
|
201
|
+
const decoder = new EnvelopeDecoder();
|
|
202
|
+
const messages = [];
|
|
203
|
+
const rawChunks = [];
|
|
204
|
+
let status = 0;
|
|
205
|
+
const cleanup = () => {
|
|
206
|
+
clearTimeout(timer);
|
|
207
|
+
try {
|
|
208
|
+
session.close();
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
/* already closed */
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
const fail = (err) => {
|
|
215
|
+
if (settled)
|
|
216
|
+
return;
|
|
217
|
+
settled = true;
|
|
218
|
+
cleanup();
|
|
219
|
+
reject(err);
|
|
220
|
+
};
|
|
221
|
+
const succeed = () => {
|
|
222
|
+
if (settled)
|
|
223
|
+
return;
|
|
224
|
+
settled = true;
|
|
225
|
+
cleanup();
|
|
226
|
+
resolve(messages);
|
|
227
|
+
};
|
|
228
|
+
const timer = setTimeout(() => fail(new Error(`hub ${method} timed out`)), timeoutMs);
|
|
229
|
+
timer.unref?.();
|
|
230
|
+
session.on('error', (err) => fail(new Error(`hub h2 session error: ${String(err)}`)));
|
|
231
|
+
const stream = session.request({
|
|
232
|
+
':method': 'POST',
|
|
233
|
+
':path': `/clip.v1.ClipHubService/${method}`,
|
|
234
|
+
'content-type': 'application/connect+json',
|
|
235
|
+
'connect-protocol-version': '1',
|
|
236
|
+
authorization: `Bearer ${this.opts.authKey}`,
|
|
237
|
+
});
|
|
238
|
+
stream.on('response', (headers) => {
|
|
239
|
+
status = Number(headers[':status'] ?? 0);
|
|
240
|
+
});
|
|
241
|
+
stream.on('error', (err) => fail(new Error(`hub ${method} stream error: ${String(err)}`)));
|
|
242
|
+
stream.on('data', (chunk) => {
|
|
243
|
+
try {
|
|
244
|
+
// A non-2xx response is NOT a Connect envelope stream (auth/arg/server
|
|
245
|
+
// failures return a JSON error body); buffer it raw so we surface the
|
|
246
|
+
// hub's code/message instead of a misleading frame-decode error.
|
|
247
|
+
if (status < 200 || status >= 300) {
|
|
248
|
+
rawChunks.push(chunk);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
decoder.push(chunk);
|
|
252
|
+
for (const envelope of decoder.flush()) {
|
|
253
|
+
if (envelope.flags === ENVELOPE_FLAG_TRAILER) {
|
|
254
|
+
const trailer = parseTrailer(envelope.payload);
|
|
255
|
+
if (trailer?.error) {
|
|
256
|
+
fail(new Error(`hub ${method} error: ${trailer.error}`));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
messages.push(JSON.parse(envelope.payload.toString('utf-8')));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
catch (err) {
|
|
265
|
+
fail(err instanceof Error ? err : new Error(String(err)));
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
const finish = () => {
|
|
269
|
+
if (status !== 0 && (status < 200 || status >= 300)) {
|
|
270
|
+
fail(new Error(`hub ${method} failed (${status}): ${connectErrorMessage(Buffer.concat(rawChunks).toString('utf-8'))}`));
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
succeed();
|
|
274
|
+
};
|
|
275
|
+
stream.on('end', finish);
|
|
276
|
+
stream.on('close', finish);
|
|
277
|
+
stream.end(encodeEnvelope(request));
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Connect unary errors carry a JSON body {"code","message"} alongside the HTTP
|
|
283
|
+
* status. Surface the message (with code) so a hub rejection is actionable.
|
|
284
|
+
*/
|
|
285
|
+
function connectErrorMessage(text) {
|
|
286
|
+
try {
|
|
287
|
+
const obj = JSON.parse(text);
|
|
288
|
+
if (obj?.message)
|
|
289
|
+
return obj.code ? `${obj.code}: ${obj.message}` : obj.message;
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
/* not JSON */
|
|
293
|
+
}
|
|
294
|
+
return text || 'unknown error';
|
|
295
|
+
}
|
|
296
|
+
function decodeOutput(output) {
|
|
297
|
+
const decoded = Buffer.from(output, 'base64').toString('utf-8');
|
|
298
|
+
try {
|
|
299
|
+
return JSON.parse(decoded);
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
return decoded;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Connect end-of-stream trailers carry an `error` object when the RPC failed.
|
|
307
|
+
* Surface its message so a hub-level rejection (e.g. 403 BROWSER_BINDING_INVALID)
|
|
308
|
+
* does not silently resolve to an empty stream.
|
|
309
|
+
*/
|
|
310
|
+
function parseTrailer(payload) {
|
|
311
|
+
try {
|
|
312
|
+
const obj = JSON.parse(payload.toString('utf-8'));
|
|
313
|
+
if (obj?.error)
|
|
314
|
+
return { error: obj.error.message || 'hub error' };
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
@@ -3,5 +3,7 @@ export { ClipProcess, ClipCommandError, type ClipProcessStatus, type InvokeEvent
|
|
|
3
3
|
export { type IpcMessage, type IpcManifest, type ListClipInfo, type ListCommandInfo, type IpcError, MessageType, NdjsonReader, NdjsonWriter, } from './ipc.js';
|
|
4
4
|
export { type ClipConfig, type ManifestCache, type CommandDetail, type ClipJson, } from './manifest.js';
|
|
5
5
|
export { ClipProvider, type ClipProviderOptions } from './clip-provider.js';
|
|
6
|
+
export { HubClient, HubCommandError, type HubClientOptions, type ClipBinding, } from './hub-client.js';
|
|
7
|
+
export { BrowserProfileManager } from './browser-profile-manager.js';
|
|
6
8
|
export { installClip, removeClip, parseSource, type InstallOptions, type InstallResult, } from './clip-installer.js';
|
|
7
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/clip-runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,YAAY,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,QAAQ,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,WAAW,EACX,UAAU,EACV,WAAW,EACX,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/clip-runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,YAAY,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,WAAW,EACX,YAAY,EACZ,YAAY,GACb,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,QAAQ,GACd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,SAAS,EACT,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,WAAW,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EACL,WAAW,EACX,UAAU,EACV,WAAW,EACX,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,qBAAqB,CAAC"}
|
|
@@ -2,4 +2,6 @@ export { ClipProcessManager } from './process-manager.js';
|
|
|
2
2
|
export { ClipProcess, ClipCommandError, } from './process.js';
|
|
3
3
|
export { MessageType, NdjsonReader, NdjsonWriter, } from './ipc.js';
|
|
4
4
|
export { ClipProvider } from './clip-provider.js';
|
|
5
|
+
export { HubClient, HubCommandError, } from './hub-client.js';
|
|
6
|
+
export { BrowserProfileManager } from './browser-profile-manager.js';
|
|
5
7
|
export { installClip, removeClip, parseSource, } from './clip-installer.js';
|
|
@@ -22,6 +22,8 @@ export interface IpcMessage {
|
|
|
22
22
|
input?: unknown;
|
|
23
23
|
output?: unknown;
|
|
24
24
|
error?: string;
|
|
25
|
+
processExit?: boolean;
|
|
26
|
+
process_exit?: boolean;
|
|
25
27
|
manifest?: IpcManifest;
|
|
26
28
|
clips?: ListClipInfo[];
|
|
27
29
|
operation?: string;
|
|
@@ -43,6 +45,10 @@ export interface IpcManifest {
|
|
|
43
45
|
package?: string;
|
|
44
46
|
version?: string;
|
|
45
47
|
}>;
|
|
48
|
+
dependency_slots?: Record<string, {
|
|
49
|
+
package?: string;
|
|
50
|
+
version?: string;
|
|
51
|
+
}>;
|
|
46
52
|
patterns?: string[];
|
|
47
53
|
entities?: Record<string, unknown>;
|
|
48
54
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ipc.d.ts","sourceRoot":"","sources":["../../src/clip-runtime/ipc.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ipc.d.ts","sourceRoot":"","sources":["../../src/clip-runtime/ipc.ts"],"names":[],"mappings":"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"}
|