@byokit/openclaw 0.5.1 → 0.6.2
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/CHANGELOG.md +56 -3
- package/README.md +205 -15
- package/SECURITY.md +6 -6
- package/dist/auth-store.d.ts +6 -0
- package/dist/auth-store.js +58 -15
- package/dist/bridge.d.ts +10 -2
- package/dist/bridge.js +61 -14
- package/dist/browser/broker.d.ts +63 -0
- package/dist/browser/broker.js +1003 -0
- package/dist/browser/host.d.ts +98 -0
- package/dist/browser/host.js +945 -0
- package/dist/browser/resume.d.ts +10 -0
- package/dist/browser/resume.js +23 -0
- package/dist/browser/store.d.ts +25 -0
- package/dist/browser/store.js +151 -0
- package/dist/browser/verify.d.ts +17 -0
- package/dist/browser/verify.js +38 -0
- package/dist/browser.d.ts +212 -0
- package/dist/browser.js +4 -0
- package/dist/config.d.ts +28 -0
- package/dist/config.js +130 -0
- package/dist/day-usage.d.ts +78 -0
- package/dist/day-usage.js +104 -0
- package/dist/device.d.ts +38 -5
- package/dist/device.js +224 -4
- package/dist/engine-patches.d.ts +36 -0
- package/dist/engine-patches.js +320 -0
- package/dist/engine-status.d.ts +13 -0
- package/dist/engine-status.js +31 -0
- package/dist/engine.d.ts +13 -1
- package/dist/engine.js +99 -52
- package/dist/index.d.ts +9 -1
- package/dist/index.js +2 -0
- package/dist/kit.d.ts +28 -3
- package/dist/kit.js +319 -12
- package/dist/link.d.ts +16 -5
- package/dist/link.js +333 -6
- package/dist/routes.d.ts +19 -8
- package/dist/routes.js +44 -11
- package/dist/routes.json +3775 -356
- package/dist/runs.js +8 -2
- package/dist/signin.d.ts +1 -1
- package/dist/signin.js +19 -4
- package/dist/testing/browser.d.ts +50 -0
- package/dist/testing/browser.js +166 -0
- package/dist/testing/contract.js +1 -2
- package/dist/testing/fake-gateway.d.ts +14 -7
- package/dist/testing/fake-gateway.js +8 -6
- package/dist/testing/index.d.ts +3 -2
- package/dist/testing/index.js +1 -0
- package/dist/testing/model-stub.d.ts +15 -1
- package/dist/testing/model-stub.js +11 -11
- package/dist/types.d.ts +50 -3
- package/dist/usage-boots.d.ts +8 -0
- package/dist/usage-boots.js +26 -0
- package/dist/usage.d.ts +53 -0
- package/dist/usage.js +60 -0
- package/dist/words.json +42 -0
- package/engine/OPENCLAW-LICENSE +24 -0
- package/engine/patches.json +59 -0
- package/engine/patches.schema.json +41 -0
- package/package.json +12 -4
- package/plugin/index.js +78 -5
- package/plugin/usage.js +125 -0
package/dist/bridge.js
CHANGED
|
@@ -41,7 +41,7 @@ export function writePlugin(dir, o) {
|
|
|
41
41
|
id: o.id,
|
|
42
42
|
name: 'BYOKit bridge',
|
|
43
43
|
activation: { onStartup: true },
|
|
44
|
-
contracts: { tools: o.tools.map((t) => t.name) },
|
|
44
|
+
contracts: { tools: o.tools.map((t) => t.name), ...(o.browser ? { agentToolResultMiddleware: ['openclaw', 'codex'] } : {}) },
|
|
45
45
|
configSchema: { type: 'object', additionalProperties: false },
|
|
46
46
|
};
|
|
47
47
|
const table = {
|
|
@@ -50,6 +50,7 @@ export function writePlugin(dir, o) {
|
|
|
50
50
|
permitParam,
|
|
51
51
|
// true: engine builtins (web_fetch, memory, ...) are gated too, not only the app's tools.
|
|
52
52
|
gateBuiltins: o.gateBuiltins,
|
|
53
|
+
...(o.browser ? { browser: true } : {}),
|
|
53
54
|
tools: o.tools.map((t) => ({ name: t.name, description: t.description, parameters: t.parameters })),
|
|
54
55
|
};
|
|
55
56
|
for (const [file, data] of [['openclaw.plugin.json', manifest], ['tools.json', table]]) {
|
|
@@ -67,7 +68,11 @@ export class Bridge {
|
|
|
67
68
|
approvalTimeoutMs;
|
|
68
69
|
onAsk;
|
|
69
70
|
onAskGone;
|
|
71
|
+
beforeAgentRun;
|
|
72
|
+
browserCapabilities;
|
|
70
73
|
server;
|
|
74
|
+
closing = Promise.resolve();
|
|
75
|
+
sockets = new Set();
|
|
71
76
|
runs = new Map();
|
|
72
77
|
// Every live registration per session key, each with its run's subset of the app's tools (RunSpec.tools; none: all
|
|
73
78
|
// of them). Runs sharing a key share the narrowest: a tool must be in every live subset.
|
|
@@ -85,18 +90,28 @@ export class Bridge {
|
|
|
85
90
|
this.approvalTimeoutMs = Math.min(o.approvalTimeoutMs, MAX_APPROVAL_TIMEOUT_MS);
|
|
86
91
|
this.onAsk = o.onAsk;
|
|
87
92
|
this.onAskGone = o.onAskGone;
|
|
93
|
+
this.beforeAgentRun = o.beforeAgentRun;
|
|
94
|
+
this.browserCapabilities = o.browserCapabilities;
|
|
88
95
|
}
|
|
89
|
-
start() {
|
|
96
|
+
async start() {
|
|
90
97
|
if (this.server)
|
|
91
|
-
return
|
|
98
|
+
return;
|
|
92
99
|
this.stopped = false;
|
|
93
|
-
|
|
100
|
+
await this.closing;
|
|
101
|
+
if (this.stopped || this.server)
|
|
102
|
+
return;
|
|
103
|
+
// Old listener teardown must finish before it can unlink a newly rebound Unix socket.
|
|
94
104
|
rmSync(this.path, { force: true });
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
this.
|
|
99
|
-
|
|
105
|
+
const server = createServer(socket => {
|
|
106
|
+
this.sockets.add(socket);
|
|
107
|
+
socket.once('close', () => this.sockets.delete(socket));
|
|
108
|
+
this.serve(socket);
|
|
109
|
+
});
|
|
110
|
+
this.server = server;
|
|
111
|
+
await new Promise((resolve, reject) => {
|
|
112
|
+
server.once('error', reject);
|
|
113
|
+
server.listen(this.path, () => {
|
|
114
|
+
server.removeListener('error', reject);
|
|
100
115
|
resolve();
|
|
101
116
|
});
|
|
102
117
|
});
|
|
@@ -110,14 +125,28 @@ export class Bridge {
|
|
|
110
125
|
this.onAskGone(id);
|
|
111
126
|
}
|
|
112
127
|
this.parked.clear();
|
|
113
|
-
|
|
128
|
+
// Tool subsets survive reconnect (B3); submission authority does not survive a lost engine transport.
|
|
129
|
+
for (const entries of this.live.values())
|
|
130
|
+
for (const entry of entries)
|
|
131
|
+
entry.runId = undefined;
|
|
132
|
+
// Preserve already-ended refusal replies; abort outstanding calls through their close signal (N7).
|
|
133
|
+
for (const socket of this.sockets)
|
|
134
|
+
if (!socket.writableEnded)
|
|
135
|
+
socket.destroy();
|
|
136
|
+
const server = this.server;
|
|
114
137
|
this.server = undefined;
|
|
115
|
-
|
|
138
|
+
if (server)
|
|
139
|
+
this.closing = new Promise(resolve => server.close(() => resolve()))
|
|
140
|
+
.then(() => rm(this.path, { force: true }).catch(() => { }));
|
|
116
141
|
}
|
|
117
|
-
|
|
118
|
-
|
|
142
|
+
isRegisteredRun(key, runId) {
|
|
143
|
+
return !this.stopped && typeof runId === 'string' && !!runId
|
|
144
|
+
&& (this.live.get(key) ?? []).some(entry => entry.runId === runId);
|
|
145
|
+
}
|
|
146
|
+
/** Register one run; release revokes only this exact registration, even when sessions overlap. */
|
|
147
|
+
register(run, tools, runId) {
|
|
119
148
|
this.runs.set(run.sessionKey, run);
|
|
120
|
-
const entry = tools ? { tools: new Set(tools) } : {};
|
|
149
|
+
const entry = { ...(tools ? { tools: new Set(tools) } : {}), runId };
|
|
121
150
|
const list = this.live.get(run.sessionKey);
|
|
122
151
|
if (list)
|
|
123
152
|
list.push(entry);
|
|
@@ -225,6 +254,24 @@ export class Bridge {
|
|
|
225
254
|
}
|
|
226
255
|
if (!isRecord(message) || typeof message.kind !== 'string')
|
|
227
256
|
return this.deny(socket, 'not a gate request');
|
|
257
|
+
if (message.kind === 'browser-capabilities') {
|
|
258
|
+
if (!this.browserCapabilities || this.stopped)
|
|
259
|
+
return this.deny(socket, 'browser unavailable');
|
|
260
|
+
try {
|
|
261
|
+
this.reply(socket, { capabilities: this.browserCapabilities() });
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
this.deny(socket, 'browser unavailable');
|
|
265
|
+
}
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (message.kind === 'before-agent-run') {
|
|
269
|
+
if (typeof message.key !== 'string' || !message.key || !this.beforeAgentRun)
|
|
270
|
+
return this.deny(socket, 'run unavailable');
|
|
271
|
+
void this.beforeAgentRun(message.key, typeof message.runId === 'string' ? message.runId : undefined)
|
|
272
|
+
.then(allow => this.reply(socket, { allow }), () => this.deny(socket, 'run unavailable'));
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
228
275
|
if (message.kind === 'gate')
|
|
229
276
|
return void this.gate(socket, message);
|
|
230
277
|
if (message.kind === 'call')
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Member } from '../types.ts';
|
|
2
|
+
import type { LiveFrame, LiveInput } from '../browser.ts';
|
|
3
|
+
export type BrokerOptions = {
|
|
4
|
+
executablePath: string;
|
|
5
|
+
profileDir: string;
|
|
6
|
+
member: Member;
|
|
7
|
+
onExit(code: number | null): void;
|
|
8
|
+
};
|
|
9
|
+
export type LeaseBinding = {
|
|
10
|
+
epoch: number;
|
|
11
|
+
nonce: string;
|
|
12
|
+
origin: string;
|
|
13
|
+
knownIdps: string[];
|
|
14
|
+
};
|
|
15
|
+
export type PrivateState = {
|
|
16
|
+
origin: string;
|
|
17
|
+
secure: boolean;
|
|
18
|
+
offOrigin: boolean;
|
|
19
|
+
} | undefined;
|
|
20
|
+
export type Broker = {
|
|
21
|
+
bindLease(l: LeaseBinding | null): void;
|
|
22
|
+
confirmOrigin(l: {
|
|
23
|
+
epoch: number;
|
|
24
|
+
nonce: string;
|
|
25
|
+
}, origin: string): boolean;
|
|
26
|
+
privateState(): PrivateState;
|
|
27
|
+
clearSite(origins: string[]): Promise<void>;
|
|
28
|
+
endpoint(): {
|
|
29
|
+
cdpUrl: string;
|
|
30
|
+
};
|
|
31
|
+
fence(on: boolean): Promise<void>;
|
|
32
|
+
agentTab(): string | undefined;
|
|
33
|
+
originOf(targetId: string): Promise<string>;
|
|
34
|
+
openPrivate(url: string): Promise<string>;
|
|
35
|
+
closePrivate(): Promise<void>;
|
|
36
|
+
probe(url: string, verify: (p: Probe) => Promise<boolean>, timeoutMs: number): Promise<'ok' | 'fail' | 'timeout'>;
|
|
37
|
+
attachViewer(o: {
|
|
38
|
+
lease?: {
|
|
39
|
+
epoch: number;
|
|
40
|
+
nonce: string;
|
|
41
|
+
};
|
|
42
|
+
maxWidth?: number;
|
|
43
|
+
}): ViewerSession;
|
|
44
|
+
navigateAgent(url: string | 'reload'): Promise<void>;
|
|
45
|
+
close(): Promise<void>;
|
|
46
|
+
};
|
|
47
|
+
export type Probe = {
|
|
48
|
+
url: string;
|
|
49
|
+
status: number;
|
|
50
|
+
exists(selector: string): Promise<boolean>;
|
|
51
|
+
};
|
|
52
|
+
export type ViewerSession = {
|
|
53
|
+
frames: AsyncIterable<LiveFrame>;
|
|
54
|
+
states: AsyncIterable<NonNullable<PrivateState>>;
|
|
55
|
+
input(i: LiveInput): void;
|
|
56
|
+
close(): void;
|
|
57
|
+
};
|
|
58
|
+
/** Chromium refused to start without its sandbox (e.g. unprivileged user namespaces disabled). The broker never runs it unsandboxed. */
|
|
59
|
+
export declare class BrowserSandboxUnavailable extends Error {
|
|
60
|
+
readonly reason = "sandbox-unavailable";
|
|
61
|
+
constructor();
|
|
62
|
+
}
|
|
63
|
+
export declare function launchBroker(o: BrokerOptions): Promise<Broker>;
|