@byokit/openclaw 0.5.0 → 0.6.1

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +174 -2
  3. package/dist/auth-store.js +1 -1
  4. package/dist/bridge.d.ts +10 -2
  5. package/dist/bridge.js +61 -14
  6. package/dist/browser/broker.d.ts +63 -0
  7. package/dist/browser/broker.js +990 -0
  8. package/dist/browser/host.d.ts +98 -0
  9. package/dist/browser/host.js +945 -0
  10. package/dist/browser/resume.d.ts +10 -0
  11. package/dist/browser/resume.js +23 -0
  12. package/dist/browser/store.d.ts +25 -0
  13. package/dist/browser/store.js +151 -0
  14. package/dist/browser/verify.d.ts +17 -0
  15. package/dist/browser/verify.js +38 -0
  16. package/dist/browser.d.ts +212 -0
  17. package/dist/browser.js +4 -0
  18. package/dist/config.d.ts +28 -0
  19. package/dist/config.js +130 -0
  20. package/dist/day-usage.d.ts +76 -0
  21. package/dist/day-usage.js +104 -0
  22. package/dist/device.d.ts +32 -2
  23. package/dist/device.js +224 -4
  24. package/dist/engine-patches.d.ts +36 -0
  25. package/dist/engine-patches.js +320 -0
  26. package/dist/engine-status.d.ts +13 -0
  27. package/dist/engine-status.js +31 -0
  28. package/dist/engine.d.ts +13 -1
  29. package/dist/engine.js +99 -52
  30. package/dist/index.d.ts +6 -1
  31. package/dist/index.js +2 -0
  32. package/dist/kit.d.ts +29 -3
  33. package/dist/kit.js +324 -13
  34. package/dist/link.d.ts +5 -2
  35. package/dist/link.js +333 -4
  36. package/dist/routes.d.ts +19 -8
  37. package/dist/routes.js +44 -11
  38. package/dist/routes.json +3775 -356
  39. package/dist/runs.js +8 -2
  40. package/dist/signin.d.ts +2 -1
  41. package/dist/signin.js +103 -7
  42. package/dist/testing/browser.d.ts +50 -0
  43. package/dist/testing/browser.js +166 -0
  44. package/dist/testing/index.d.ts +1 -0
  45. package/dist/testing/index.js +1 -0
  46. package/dist/testing/model-stub.d.ts +1 -0
  47. package/dist/testing/model-stub.js +3 -1
  48. package/dist/types.d.ts +50 -3
  49. package/dist/usage-boots.d.ts +8 -0
  50. package/dist/usage-boots.js +26 -0
  51. package/dist/usage.d.ts +51 -0
  52. package/dist/usage.js +61 -0
  53. package/dist/words.json +42 -0
  54. package/engine/OPENCLAW-LICENSE +24 -0
  55. package/engine/patches.json +59 -0
  56. package/engine/patches.schema.json +41 -0
  57. package/package.json +12 -4
  58. package/plugin/index.js +78 -5
  59. package/plugin/usage.js +125 -0
package/dist/engine.js CHANGED
@@ -1,14 +1,16 @@
1
1
  import { spawn, spawnSync } from 'node:child_process';
2
- import { randomBytes, generateKeyPairSync } from 'node:crypto';
2
+ import { randomBytes, generateKeyPairSync, randomUUID } from 'node:crypto';
3
3
  import { closeSync, existsSync, mkdirSync, openSync, readFileSync, writeFileSync, copyFileSync, rmSync, realpathSync, statSync } from 'node:fs';
4
4
  import { createServer } from 'node:net';
5
5
  import { join, dirname } from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
  import { setTimeout as delay } from 'node:timers/promises';
8
8
  import { AuthStore } from "./auth-store.js";
9
- import { EngineAlreadyRunningError, pidAlive } from "./engine-status.js";
9
+ import { EngineAlreadyRunningError, pidAlive, StartedProcesses } from "./engine-status.js";
10
+ import { EnginePatchError, atomic, prepareEngineSet, processStartTime, readPatchSet, verifyEngineSet } from "./engine-patches.js";
10
11
  import { ENGINE_VERSION } from "./constants.js";
11
- import { reconcileConfig } from "./config.js";
12
+ import { appendUsageBoot } from "./usage-boots.js";
13
+ import { reconcileConfig, appRecoveryPrefixes } from "./config.js";
12
14
  import { writePlugin, resolveBridge } from "./bridge.js";
13
15
  const kitDir = dirname(dirname(fileURLToPath(import.meta.url)));
14
16
  const putOnce = (path, data) => { if (!existsSync(path))
@@ -17,14 +19,6 @@ const putChanged = (path, data) => {
17
19
  if (!existsSync(path) || readFileSync(path, 'utf8') !== data)
18
20
  writeFileSync(path, data, { mode: 0o600 });
19
21
  };
20
- function processStartTime(pid) {
21
- const stat = readFileSync(`/proc/${pid}/stat`, 'utf8');
22
- // comm can contain spaces and parentheses; field 22 is index 19 after its final ')'.
23
- const startTime = stat.slice(stat.lastIndexOf(')') + 2).split(' ')[19];
24
- if (!startTime || !/^\d+$/.test(startTime))
25
- throw new Error('unverifiable engine start time');
26
- return startTime;
27
- }
28
22
  const supports = (list, value) => !list ||
29
23
  (!list.includes(`!${value}`) && (list.includes('any') || list.every(item => item.startsWith('!')) || list.includes(value)));
30
24
  function installMatches(dir) {
@@ -57,18 +51,24 @@ export class Engine {
57
51
  root;
58
52
  bridgeSock;
59
53
  dir;
54
+ setDir;
55
+ wantedSet;
60
56
  child;
57
+ started = new StartedProcesses();
61
58
  starting;
62
59
  authStore;
63
60
  stopping = false;
64
61
  credentialsLocked = false;
65
62
  repaired = false;
66
63
  prepared;
64
+ patchSet;
67
65
  port = 0;
68
66
  token = '';
69
67
  o;
70
68
  paramPrefix;
69
+ appOwnedSessionPrefixes;
71
70
  constructor(o) {
71
+ this.appOwnedSessionPrefixes = appRecoveryPrefixes(o.appOwnedSessions);
72
72
  this.o = o;
73
73
  const bridge = resolveBridge(o.bridge);
74
74
  this.root = join(o.stateDir, 'openclaw');
@@ -77,8 +77,12 @@ export class Engine {
77
77
  this.paramPrefix = bridge.paramPrefix;
78
78
  this.authStore = new AuthStore({ root: this.root, stateDir: o.stateDir, engineDir: this.dir, seal: o.authSeal, log: o.log });
79
79
  }
80
- state(phase, why, retryAt) { this.o.onState({ phase, ...(why ? { why } : {}), ...(retryAt ? { retryAt } : {}) }); }
81
- get entry() { return join(this.dir, 'node_modules', 'openclaw', 'openclaw.mjs'); }
80
+ state(phase, why, retryAt) { this.o.onState({ phase, ...(why ? { why } : {}), ...(retryAt ? { retryAt } : {}), ...(this.patchSet !== undefined ? { patchSet: this.patchSet } : {}) }); }
81
+ get entry() {
82
+ if (this.o.spawnEngine && !this.setDir)
83
+ throw new EnginePatchError('spec', 'engine-set');
84
+ return join(this.setDir ?? this.dir, 'node_modules', 'openclaw', 'openclaw.mjs');
85
+ }
82
86
  async freePort() {
83
87
  const server = createServer();
84
88
  return new Promise((resolve, reject) => {
@@ -93,7 +97,13 @@ export class Engine {
93
97
  prepare() {
94
98
  if (this.prepared)
95
99
  return this.prepared;
96
- const pending = this.prepareOnce();
100
+ const pending = this.prepareOnce().catch(error => {
101
+ if (error instanceof EnginePatchError) {
102
+ this.patchSet = null;
103
+ this.state('failed', 'engine-patch');
104
+ }
105
+ throw error;
106
+ });
97
107
  this.prepared = pending;
98
108
  void pending.finally(() => { if (this.prepared === pending)
99
109
  this.prepared = undefined; }).catch(() => { });
@@ -103,7 +113,7 @@ export class Engine {
103
113
  if (!this.o.authSeal && existsSync(join(this.root, 'auth-store.sealed')))
104
114
  throw new Error('authSeal required for sealed credential store');
105
115
  await this.recoverOrphan();
106
- for (const d of [this.root, ...(!this.o.authSeal ? [join(this.root, 'home'), join(this.root, 'state')] : []), join(this.root, 'tmp'), join(this.root, 'install-home'), join(this.root, 'npm-cache'), join(this.o.stateDir, 'logs'), this.dir])
116
+ for (const d of [this.root, ...(!this.o.authSeal ? [join(this.root, 'home'), join(this.root, 'state')] : []), join(this.root, 'tmp'), join(this.root, 'usage'), join(this.root, 'install-home'), join(this.root, 'npm-cache'), join(this.o.stateDir, 'logs')])
107
117
  mkdirSync(d, { recursive: true, mode: 0o700 });
108
118
  try {
109
119
  await this.authStore.prepare();
@@ -115,25 +125,38 @@ export class Engine {
115
125
  throw error;
116
126
  }
117
127
  if (this.o.spawnEngine) {
118
- const versionPath = join(this.dir, 'node_modules', 'openclaw', 'package.json');
119
- if (!existsSync(this.entry) || !installMatches(this.dir)) {
128
+ const lock = JSON.parse(readFileSync(join(kitDir, 'engine/package-lock.json'), 'utf8'));
129
+ const patches = readPatchSet(join(kitDir, 'engine/patches.json'), ENGINE_VERSION, lock.packages['node_modules/openclaw'].integrity);
130
+ const install = async (dir) => {
120
131
  this.state('installing');
121
- rmSync(join(this.dir, 'node_modules'), { recursive: true, force: true });
122
132
  for (const f of ['package.json', 'package-lock.json'])
123
- copyFileSync(join(kitDir, 'engine', f), join(this.dir, f));
124
- const result = spawnSync(this.o.npmPath ?? 'npm', ['ci', '--ignore-scripts', '--no-audit', '--no-fund', '--prefix', this.dir], {
125
- env: { PATH: process.env.PATH ?? '/usr/bin:/bin', HOME: join(this.root, 'install-home'), npm_config_cache: join(this.root, 'npm-cache'), OPENCLAW_DISABLE_BUNDLED_PLUGIN_POSTINSTALL: '1' },
126
- timeout: 300_000, stdio: 'pipe', encoding: 'utf8', maxBuffer: 1024 * 1024,
133
+ copyFileSync(join(kitDir, 'engine', f), join(dir, f));
134
+ await new Promise((resolve, reject) => {
135
+ const child = spawn(this.o.npmPath ?? 'npm', ['ci', '--ignore-scripts', '--no-audit', '--no-fund', '--prefix', dir], {
136
+ env: { PATH: process.env.PATH ?? '/usr/bin:/bin', HOME: join(this.root, 'install-home'), npm_config_cache: join(this.root, 'npm-cache'), OPENCLAW_DISABLE_BUNDLED_PLUGIN_POSTINSTALL: '1' },
137
+ stdio: ['ignore', 'ignore', 'pipe'],
138
+ });
139
+ let stderr = '', expired = false;
140
+ this.started.add(child);
141
+ child.stderr.on('data', chunk => { stderr = (stderr + chunk).slice(-500); });
142
+ const timer = setTimeout(() => { expired = true; child.kill('SIGKILL'); }, 300_000);
143
+ child.once('error', error => { clearTimeout(timer); this.started.forget(child); reject(error); });
144
+ child.once('exit', code => {
145
+ clearTimeout(timer);
146
+ this.started.forget(child);
147
+ if (code === 0 && !expired)
148
+ resolve();
149
+ else {
150
+ this.state('failed', 'install');
151
+ reject(new Error(`engine install: ${expired ? 'timeout' : stderr}`));
152
+ }
153
+ });
127
154
  });
128
- if (result.status !== 0) {
129
- this.state('failed', 'install');
130
- throw new Error(`engine install: ${result.error ?? result.stderr?.slice(-500)}`);
131
- }
132
- }
133
- if (!existsSync(this.entry) || JSON.parse(readFileSync(versionPath, 'utf8')).version !== ENGINE_VERSION) {
134
- this.state('needs-update', 'version');
135
- throw new Error('engine version mismatch');
136
- }
155
+ };
156
+ this.setDir = await prepareEngineSet(this.dir, patches, install, installMatches);
157
+ this.wantedSet = patches;
158
+ atomic(join(this.root, 'engine-set'), this.setDir);
159
+ this.patchSet = patches.id;
137
160
  }
138
161
  const tokenFile = join(this.root, 'token');
139
162
  putOnce(tokenFile, randomBytes(32).toString('hex'));
@@ -148,17 +171,18 @@ export class Engine {
148
171
  const pluginDir = join(this.root, 'plugin');
149
172
  mkdirSync(pluginDir, { recursive: true, mode: 0o700 });
150
173
  // The shipped plugin follows the kit on every prepare too: a state dir from an older kit must not keep its gate.
151
- for (const f of ['package.json', 'index.js', 'keys.js']) {
174
+ for (const f of ['package.json', 'index.js', 'keys.js', 'usage.js']) {
152
175
  const source = join(kitDir, 'plugin', f);
153
176
  putChanged(join(pluginDir, f), readFileSync(source, 'utf8'));
154
177
  }
155
178
  // The bridge manifest and tool table follow the app's tools on every prepare (O5).
156
179
  writePlugin(pluginDir, { id: this.o.pluginId, tools: this.o.tools, paramPrefix: this.paramPrefix,
157
- gateBuiltins: this.o.gateBuiltins !== false });
180
+ gateBuiltins: this.o.gateBuiltins !== false, browser: !!this.o.browserConfig });
158
181
  const path = join(this.root, 'openclaw.json');
159
182
  const saved = existsSync(path) ? JSON.parse(readFileSync(path, 'utf8')) : undefined;
160
183
  const config = reconcileConfig(saved, { root: this.root, stateDir: this.o.stateDir, port: this.port, pluginId: this.o.pluginId,
161
- pluginDir, policyPath: join(kitDir, 'policy', 'policy.mjs'), app: this.o.config, installPolicy: this.o.installPolicy });
184
+ pluginDir, policyPath: join(kitDir, 'policy', 'policy.mjs'), app: this.o.config, installPolicy: this.o.installPolicy,
185
+ browser: this.o.browserConfig?.() });
162
186
  putChanged(path, JSON.stringify(config, null, 2) + '\n');
163
187
  }
164
188
  doctorContext() {
@@ -171,11 +195,16 @@ export class Engine {
171
195
  TMPDIR: join(this.root, 'tmp'), OPENCLAW_NO_RESPAWN: '1', OPENCLAW_SKIP_CHANNELS: '1', OPENCLAW_DISABLE_BONJOUR: '1',
172
196
  OPENCLAW_EXEC_SHELL_SNAPSHOT: '0', OPENCLAW_LOAD_SHELL_ENV: '0', OPENCLAW_GATEWAY_TOKEN: this.token,
173
197
  BYOKIT_BRIDGE_SOCK: this.bridgeSock,
198
+ BYOKIT_APP_OWNED_SESSION_PREFIXES: JSON.stringify(this.appOwnedSessionPrefixes),
174
199
  } };
175
200
  }
176
201
  doctor(timeoutMs) {
177
202
  const { entry, env } = this.doctorContext();
203
+ if (this.o.spawnEngine)
204
+ verifyEngineSet(this.setDir, this.wantedSet, installMatches);
178
205
  const result = spawnSync(process.execPath, [entry, 'doctor', '--fix', '--yes', '--non-interactive'], { cwd: env.HOME, env, timeout: timeoutMs, stdio: 'pipe' });
206
+ if (this.o.spawnEngine)
207
+ verifyEngineSet(this.setDir, this.wantedSet, installMatches);
179
208
  return { status: result.status };
180
209
  }
181
210
  verifiedOrphan(pid) {
@@ -286,17 +315,49 @@ export class Engine {
286
315
  return { port: this.port, token: this.token, identityPath };
287
316
  if (this.child && this.child.exitCode === null)
288
317
  return { port: this.port, token: this.token, identityPath };
318
+ try {
319
+ verifyEngineSet(this.setDir, this.wantedSet, installMatches);
320
+ }
321
+ catch (error) {
322
+ this.patchSet = null;
323
+ this.state('failed', 'engine-patch');
324
+ throw error;
325
+ }
289
326
  this.state('starting');
290
327
  const { entry, env } = this.doctorContext();
291
328
  const fd = openSync(join(this.o.stateDir, 'logs', 'openclaw.log'), 'a', 0o600);
329
+ const usageDir = join(this.root, 'usage'), bootId = randomUUID();
292
330
  try {
293
- this.child = spawn(process.execPath, [entry, 'gateway', '--port', String(this.port)], { cwd: env.HOME, env, detached: true, stdio: ['ignore', fd, fd] });
331
+ const accounted = this.wantedSet.files.some(file => file.path === 'dist/experience-review-default-6DPIIJds.js');
332
+ if (accounted) {
333
+ appendUsageBoot(usageDir, { bootId, startedAt: Date.now() });
334
+ env.BYOKIT_ENGINE_USAGE_LEDGER = usageDir;
335
+ env.BYOKIT_ENGINE_BOOT = bootId;
336
+ }
337
+ // Detached keeps the engine out of the host's session; stop() still signals its pid alone, never its group.
338
+ try {
339
+ this.child = spawn(process.execPath, [entry, 'gateway', '--port', String(this.port)], { cwd: env.HOME, env, detached: true, stdio: ['ignore', fd, fd] });
340
+ }
341
+ catch (error) {
342
+ if (env.BYOKIT_ENGINE_BOOT)
343
+ appendUsageBoot(usageDir, { bootId, failedAt: Date.now(), spawned: false });
344
+ throw error;
345
+ }
294
346
  }
295
347
  finally {
296
348
  closeSync(fd);
297
349
  }
298
350
  const child = this.child;
351
+ this.started.add(child);
299
352
  child.on('error', () => {
353
+ this.started.forget(child);
354
+ // Only absence of a pid proves no engine could have attempted a ledger write.
355
+ if (!child.pid && env.BYOKIT_ENGINE_BOOT) {
356
+ try {
357
+ appendUsageBoot(usageDir, { bootId, failedAt: Date.now(), spawned: false });
358
+ }
359
+ catch { /* unclosed boot remains incomplete */ }
360
+ }
300
361
  if (this.child !== child || this.stopping)
301
362
  return;
302
363
  this.child = undefined;
@@ -307,10 +368,11 @@ export class Engine {
307
368
  throw new Error('engine spawn failed');
308
369
  }
309
370
  if (process.platform === 'linux') {
310
- writeFileSync(join(this.root, 'gateway.identity'), JSON.stringify({ pid: child.pid, startTime: processStartTime(child.pid) }), { mode: 0o600 });
371
+ writeFileSync(join(this.root, 'gateway.identity'), JSON.stringify({ pid: child.pid, startTime: processStartTime(child.pid), ...(env.BYOKIT_ENGINE_BOOT ? { bootId } : {}) }), { mode: 0o600 });
311
372
  }
312
373
  writeFileSync(join(this.root, 'gateway.pid'), String(child.pid), { mode: 0o600 });
313
374
  child.once('exit', (code) => {
375
+ this.started.forget(child);
314
376
  if (this.child !== child || this.stopping)
315
377
  return;
316
378
  this.child = undefined;
@@ -346,22 +408,7 @@ export class Engine {
346
408
  this.stopping = true;
347
409
  await this.starting?.catch(() => { });
348
410
  const child = this.child;
349
- if (child?.pid && child.exitCode === null) {
350
- try {
351
- process.kill(-child.pid, 'SIGTERM');
352
- }
353
- catch { /* already gone */ }
354
- for (let i = 0; i < 15 && child.exitCode === null && child.signalCode === null; i++)
355
- await delay(200);
356
- if (child.exitCode === null && child.signalCode === null) {
357
- try {
358
- process.kill(-child.pid, 'SIGKILL');
359
- }
360
- catch { /* already gone */ }
361
- }
362
- for (let i = 0; i < 15 && child.exitCode === null && child.signalCode === null; i++)
363
- await delay(200);
364
- }
411
+ await this.started.terminate(delay);
365
412
  if (child && child.exitCode === null && child.signalCode === null)
366
413
  throw new Error('engine did not stop; credential store still in use');
367
414
  this.child = undefined;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,11 @@
1
1
  export { ENGINE_VERSION, OPERATOR_SCOPES, PROTOCOL_VERSION } from './constants.ts';
2
- export type { Approval, CallOptions, Decision, GatewayEventName, GatewayEventPayload, GatewayMethod, GatewayParams, GatewayResult, GatewayTransport, GateResult, Hello, KitState, Member, PlanWindow, Route, RunEnd, RunEvent, RunRef, RunSpec, OutputSchema, SchemaOutput, RunUsage, SignInOptions, SignInView, ToolHost, ToolSpec, } from './types.ts';
2
+ export type { Approval, CallOptions, Decision, GatewayEventName, GatewayEventPayload, GatewayMethod, GatewayParams, GatewayResult, GatewayTransport, GateResult, Hello, KitState, KitEventName, KitEventPayload, BrowserPing, Member, PlanWindow, Route, RunEnd, RunEvent, RunRef, RunSpec, OutputSchema, SchemaOutput, RunUsage, SignInOptions, SignInView, ToolHost, ToolSpec, } from './types.ts';
3
3
  export { OpenClawKit, type KitOptions, type RetainedLogin } from './kit.ts';
4
4
  export type { AddKeyResult } from './keys.ts';
5
5
  export { stateWords, toAccountView, words, type AccountView, type WordKey } from './words.ts';
6
6
  export { EngineAlreadyRunningError } from './engine-status.ts';
7
+ export { readAgentDayUsage } from './day-usage.ts';
8
+ export type { AgentDayUsage, EngineStartedCharge, EngineStartedKind } from './day-usage.ts';
9
+ export { readAgentUsage, agentUsageOf } from './usage.ts';
10
+ export type { AgentUsageReading, LedgerUsageTotals, UsageCache, UsageWindow } from './usage.ts';
11
+ export type { LiveSource, BrowserState, SignInMethodHint, SignInReason, SignInChoice, SettledState, SettledReason, ResumeState, NeedSignIn, TakeoverLease, LiveViewState, LiveFrame, LiveInput, ThumbnailResult, SignInRefusedWhy, BrowserOptions, SiteVerifier, BrowserHost, BrowserDevice } from './browser.ts';
package/dist/index.js CHANGED
@@ -4,3 +4,5 @@ export { ENGINE_VERSION, OPERATOR_SCOPES, PROTOCOL_VERSION } from "./constants.j
4
4
  export { OpenClawKit } from "./kit.js";
5
5
  export { stateWords, toAccountView, words } from "./words.js";
6
6
  export { EngineAlreadyRunningError } from "./engine-status.js";
7
+ export { readAgentDayUsage } from "./day-usage.js";
8
+ export { readAgentUsage, agentUsageOf } from "./usage.js";
package/dist/kit.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import type { SealingAdapter } from '@byokit/secrets';
2
2
  import { type AddKeyResult } from './keys.ts';
3
- import type { Approval, CallOptions, Decision, GatewayEventName, GatewayEventPayload, GatewayMethod, GatewayParams, GatewayResult, GatewayTransport, Hello, KitState, Member, Route, RunEnd, RunEvent, RunSpec, OutputSchema, SchemaOutput, SignInOptions, SignInView, ToolHost, ToolSpec } from './types.ts';
3
+ import { type RouteView } from './routes.ts';
4
+ import type { BrowserHost, BrowserOptions } from './browser.ts';
5
+ import type { Approval, CallOptions, Decision, GatewayMethod, GatewayParams, GatewayResult, GatewayTransport, Hello, KitState, KitEventName, KitEventPayload, Member, RunEnd, RunEvent, RunSpec, OutputSchema, SchemaOutput, SignInOptions, SignInView, ToolHost, ToolSpec } from './types.ts';
4
6
  export type KitOptions = {
5
7
  stateDir: string;
6
8
  authSeal?: SealingAdapter;
@@ -19,6 +21,10 @@ export type KitOptions = {
19
21
  permitted?: (tool: string) => boolean;
20
22
  gateBuiltins?: boolean;
21
23
  config?: object;
24
+ appOwnedSessions?: {
25
+ keyPrefixes: string[];
26
+ };
27
+ browser?: BrowserOptions;
22
28
  installPolicy?: {
23
29
  trustedSkills: string;
24
30
  ownRoots: string[];
@@ -52,9 +58,26 @@ export declare class OpenClawKit {
52
58
  private readonly approvalsCtl;
53
59
  private listeners;
54
60
  private off;
61
+ private signInDisconnects;
55
62
  private starting?;
56
63
  private stopping;
57
64
  private failures;
65
+ browser?: BrowserHost;
66
+ private browserHost?;
67
+ private readonly brokers;
68
+ private browserSafe;
69
+ private readonly browserAttaching;
70
+ private readonly browserPolicySessions;
71
+ private readonly browserProfiles;
72
+ private readonly browserCapabilities;
73
+ private browserConfig;
74
+ private launchBrowser;
75
+ private prepareBrowsers;
76
+ private publishBrowserProfile;
77
+ private browserMember;
78
+ private browserState;
79
+ private checkBrowserTools;
80
+ private browserGate;
58
81
  constructor(o: KitOptions);
59
82
  private setState;
60
83
  get state(): KitState;
@@ -64,17 +87,18 @@ export declare class OpenClawKit {
64
87
  private disconnect;
65
88
  private closed;
66
89
  stop(): Promise<void>;
90
+ private closeBrowsers;
67
91
  private request;
68
92
  call<M extends GatewayMethod>(method: M, params: GatewayParams<M>, o?: CallOptions): Promise<GatewayResult<M>>;
69
93
  callDynamic(method: string, params?: unknown, o?: CallOptions): Promise<unknown>;
70
94
  get hello(): Hello | undefined;
71
- onEvent<E extends GatewayEventName>(event: E | '*', fn: (payload: GatewayEventPayload<E>, event: E) => void): () => void;
95
+ onEvent<E extends KitEventName>(event: E | '*', fn: (payload: KitEventPayload<E>, event: E) => void): () => void;
72
96
  ensureMember(member: Member): Promise<{
73
97
  agentId: string;
74
98
  workspace: string;
75
99
  }>;
76
100
  private signInCtx;
77
- routes(): Route[];
101
+ routes(): RouteView[];
78
102
  providers(member: Member): Promise<string[]>;
79
103
  signedIn(member: Member, provider: string): Promise<boolean>;
80
104
  signIn(member: Member, o: SignInOptions, on: (v: SignInView) => void): {
@@ -114,6 +138,8 @@ export declare class OpenClawKit {
114
138
  agentId?: string;
115
139
  }): Promise<void>;
116
140
  memoryLimited(member: Member): boolean;
141
+ getConfigKey(key: string): unknown;
142
+ setConfigKey(key: string, value: unknown): unknown;
117
143
  doctorContext(): {
118
144
  entry: string;
119
145
  env: Record<string, string>;