@agentvault/agentvault 0.13.6 → 0.13.8

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.
@@ -0,0 +1,32 @@
1
+ export interface HttpCallReport {
2
+ method: string;
3
+ url: string;
4
+ statusCode: number;
5
+ latencyMs: number;
6
+ traceId?: string;
7
+ parentSpanId?: string;
8
+ }
9
+ export interface TraceContext {
10
+ traceId: string;
11
+ parentSpanId: string;
12
+ }
13
+ export interface FetchInterceptorOptions {
14
+ onHttpCall: (report: HttpCallReport) => void;
15
+ skipPatterns?: RegExp[];
16
+ }
17
+ /**
18
+ * Install HTTP interceptor using both undici diagnostics channels and
19
+ * globalThis.fetch monkey-patching. Idempotent.
20
+ */
21
+ export declare function installFetchInterceptor(opts: FetchInterceptorOptions): void;
22
+ /**
23
+ * Uninstall all interceptors. Safe to call even if not installed.
24
+ */
25
+ export declare function uninstallFetchInterceptor(): void;
26
+ /**
27
+ * Run an async function with trace context attached via AsyncLocalStorage.
28
+ * Any HTTP calls made within `fn` (via undici or fetch) will include
29
+ * traceId/parentSpanId in their HttpCallReport.
30
+ */
31
+ export declare function runWithTraceContext<T>(ctx: TraceContext, fn: () => T | Promise<T>): Promise<T>;
32
+ //# sourceMappingURL=fetch-interceptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-interceptor.d.ts","sourceRoot":"","sources":["../src/fetch-interceptor.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AA0CD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,uBAAuB,GAAG,IAAI,CAmK3E;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAkBhD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,GAAG,EAAE,YAAY,EACjB,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACvB,OAAO,CAAC,CAAC,CAAC,CAEZ"}
package/dist/index.d.ts CHANGED
@@ -5,5 +5,5 @@ export type { ResolvedAccount } from "./account-config.js";
5
5
  export { agentVaultPlugin, setOcRuntime, getActiveChannel } from "./openclaw-plugin.js";
6
6
  export { sendToOwner, checkGateway } from "./gateway-send.js";
7
7
  export type { GatewaySendOptions, GatewaySendResult, GatewayStatusResult, } from "./gateway-send.js";
8
- export declare const VERSION = "0.11.0";
8
+ export declare const VERSION = "0.13.8";
9
9
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -45443,14 +45443,16 @@ var TelemetryReporter = class {
45443
45443
  };
45444
45444
 
45445
45445
  // src/state.ts
45446
- import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
45446
+ import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
45447
45447
  import { join } from "node:path";
45448
45448
  var STATE_FILE = "agentvault.json";
45449
45449
  var LEGACY_STATE_FILE = "secure-channel.json";
45450
+ var DIR_MODE = 448;
45451
+ var FILE_MODE = 384;
45450
45452
  async function saveState(dataDir, state) {
45451
- await mkdir(dataDir, { recursive: true });
45453
+ await mkdir(dataDir, { recursive: true, mode: DIR_MODE });
45452
45454
  const filePath = join(dataDir, STATE_FILE);
45453
- await writeFile(filePath, JSON.stringify(state, null, 2), "utf-8");
45455
+ await writeFile(filePath, JSON.stringify(state, null, 2), { encoding: "utf-8", mode: FILE_MODE });
45454
45456
  try {
45455
45457
  await rm(join(dataDir, LEGACY_STATE_FILE));
45456
45458
  } catch {
@@ -45467,14 +45469,52 @@ async function loadState(dataDir) {
45467
45469
  try {
45468
45470
  const raw = await readFile(legacyPath, "utf-8");
45469
45471
  const parsed = JSON.parse(raw);
45470
- await mkdir(dataDir, { recursive: true });
45471
- await writeFile(filePath, JSON.stringify(parsed, null, 2), "utf-8");
45472
+ await mkdir(dataDir, { recursive: true, mode: DIR_MODE });
45473
+ await writeFile(filePath, JSON.stringify(parsed, null, 2), { encoding: "utf-8", mode: FILE_MODE });
45472
45474
  await rm(legacyPath);
45473
45475
  return parsed;
45474
45476
  } catch {
45475
45477
  return null;
45476
45478
  }
45477
45479
  }
45480
+ async function isStateValid(dataDir) {
45481
+ try {
45482
+ const filePath = join(dataDir, STATE_FILE);
45483
+ const raw = await readFile(filePath, "utf-8");
45484
+ const parsed = JSON.parse(raw);
45485
+ return !!(parsed && parsed.deviceId && parsed.deviceJwt && parsed.sessions && Object.keys(parsed.sessions).length > 0);
45486
+ } catch {
45487
+ return false;
45488
+ }
45489
+ }
45490
+ async function backupState(dataDir) {
45491
+ const src = join(dataDir, STATE_FILE);
45492
+ const bak = join(dataDir, `${STATE_FILE}.bak`);
45493
+ const tmp = join(dataDir, `${STATE_FILE}.bak.tmp`);
45494
+ try {
45495
+ const data = await readFile(src, "utf-8");
45496
+ await writeFile(tmp, data, { encoding: "utf-8", mode: FILE_MODE });
45497
+ await rename(tmp, bak);
45498
+ } catch {
45499
+ }
45500
+ }
45501
+ async function restoreState(dataDir) {
45502
+ const primaryValid = await isStateValid(dataDir);
45503
+ if (primaryValid) return false;
45504
+ const bak = join(dataDir, `${STATE_FILE}.bak`);
45505
+ try {
45506
+ const data = await readFile(bak, "utf-8");
45507
+ const parsed = JSON.parse(data);
45508
+ if (!parsed || !parsed.deviceId || !parsed.deviceJwt || !parsed.sessions || Object.keys(parsed.sessions).length === 0) {
45509
+ return false;
45510
+ }
45511
+ await mkdir(dataDir, { recursive: true, mode: DIR_MODE });
45512
+ await writeFile(join(dataDir, STATE_FILE), data, { encoding: "utf-8", mode: FILE_MODE });
45513
+ return true;
45514
+ } catch {
45515
+ return false;
45516
+ }
45517
+ }
45478
45518
  async function clearState(dataDir) {
45479
45519
  for (const filename of [STATE_FILE, LEGACY_STATE_FILE]) {
45480
45520
  try {
@@ -45629,6 +45669,7 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
45629
45669
  await libsodium_wrappers_default.ready;
45630
45670
  const raw = await loadState(this.config.dataDir);
45631
45671
  if (raw) {
45672
+ await backupState(this.config.dataDir);
45632
45673
  this._persisted = migratePersistedState(raw);
45633
45674
  if (!this._persisted.messageHistory) {
45634
45675
  this._persisted.messageHistory = [];
@@ -45652,6 +45693,30 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
45652
45693
  this._connect();
45653
45694
  return;
45654
45695
  }
45696
+ const restored = await restoreState(this.config.dataDir);
45697
+ if (restored) {
45698
+ console.log("[SecureChannel] Restored state from backup");
45699
+ const restoredRaw = await loadState(this.config.dataDir);
45700
+ if (restoredRaw) {
45701
+ this._persisted = migratePersistedState(restoredRaw);
45702
+ if (!this._persisted.messageHistory) this._persisted.messageHistory = [];
45703
+ this._deviceId = this._persisted.deviceId;
45704
+ this._deviceJwt = this._persisted.deviceJwt;
45705
+ this._primaryConversationId = this._persisted.primaryConversationId;
45706
+ this._fingerprint = this._persisted.fingerprint;
45707
+ for (const [convId, sd] of Object.entries(this._persisted.sessions)) {
45708
+ if (sd.ratchetState) {
45709
+ this._sessions.set(convId, {
45710
+ ownerDeviceId: sd.ownerDeviceId,
45711
+ ratchet: DoubleRatchet.deserialize(sd.ratchetState),
45712
+ activated: sd.activated ?? false
45713
+ });
45714
+ }
45715
+ }
45716
+ this._connect();
45717
+ return;
45718
+ }
45719
+ }
45655
45720
  await this._enroll();
45656
45721
  }
45657
45722
  /**
@@ -45998,7 +46063,9 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
45998
46063
  data: {
45999
46064
  room_id: roomId,
46000
46065
  recipients,
46001
- message_type: messageType
46066
+ message_type: messageType,
46067
+ priority: opts?.priority ?? "normal",
46068
+ metadata: opts?.metadata
46002
46069
  }
46003
46070
  })
46004
46071
  );
@@ -46012,7 +46079,12 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
46012
46079
  "Content-Type": "application/json",
46013
46080
  Authorization: `Bearer ${this._deviceJwt}`
46014
46081
  },
46015
- body: JSON.stringify({ recipients, message_type: messageType })
46082
+ body: JSON.stringify({
46083
+ recipients,
46084
+ message_type: messageType,
46085
+ priority: opts?.priority ?? "normal",
46086
+ metadata: opts?.metadata
46087
+ })
46016
46088
  }
46017
46089
  );
46018
46090
  if (!res.ok) {
@@ -46157,6 +46229,27 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
46157
46229
  }
46158
46230
  );
46159
46231
  }
46232
+ async sendActionConfirmationToRoom(roomId, confirmation) {
46233
+ const envelope = {
46234
+ type: "action_confirmation",
46235
+ action: confirmation.action,
46236
+ status: confirmation.status
46237
+ };
46238
+ if (confirmation.decisionId !== void 0) envelope.decision_id = confirmation.decisionId;
46239
+ if (confirmation.detail !== void 0) envelope.detail = confirmation.detail;
46240
+ const metadata = {
46241
+ action: confirmation.action,
46242
+ status: confirmation.status
46243
+ };
46244
+ if (confirmation.estimated_cost !== void 0) {
46245
+ metadata.estimated_cost = confirmation.estimated_cost;
46246
+ }
46247
+ await this.sendToRoom(roomId, JSON.stringify(envelope), {
46248
+ messageType: "action_confirmation",
46249
+ priority: "high",
46250
+ metadata
46251
+ });
46252
+ }
46160
46253
  _sendHeartbeat() {
46161
46254
  if (this._state !== "ready" || !this._heartbeatCallback) return;
46162
46255
  const status = this._heartbeatCallback();
@@ -46231,10 +46324,52 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
46231
46324
  res.end(JSON.stringify({ ok: false, error: "Missing 'text' field" }));
46232
46325
  return;
46233
46326
  }
46234
- if (parsed.file_path && typeof parsed.file_path === "string") {
46327
+ if (parsed.room_id && typeof parsed.room_id === "string") {
46328
+ await this.sendToRoom(parsed.room_id, text, {
46329
+ messageType: parsed.message_type,
46330
+ priority: parsed.priority,
46331
+ metadata: parsed.metadata
46332
+ });
46333
+ } else if (parsed.file_path && typeof parsed.file_path === "string") {
46235
46334
  await this.sendWithAttachment(text, parsed.file_path, { topicId: parsed.topicId });
46236
46335
  } else {
46237
- await this.send(text, { topicId: parsed.topicId });
46336
+ await this.send(text, {
46337
+ topicId: parsed.topicId,
46338
+ messageType: parsed.message_type,
46339
+ metadata: parsed.metadata
46340
+ });
46341
+ }
46342
+ res.writeHead(200, { "Content-Type": "application/json" });
46343
+ res.end(JSON.stringify({ ok: true }));
46344
+ } catch (err) {
46345
+ res.writeHead(500, { "Content-Type": "application/json" });
46346
+ res.end(JSON.stringify({ ok: false, error: String(err) }));
46347
+ }
46348
+ });
46349
+ } else if (req.method === "POST" && req.url === "/action") {
46350
+ let body = "";
46351
+ req.on("data", (chunk) => {
46352
+ body += chunk.toString();
46353
+ });
46354
+ req.on("end", async () => {
46355
+ try {
46356
+ const parsed = JSON.parse(body);
46357
+ if (!parsed.action || typeof parsed.action !== "string") {
46358
+ res.writeHead(400, { "Content-Type": "application/json" });
46359
+ res.end(JSON.stringify({ ok: false, error: "Missing 'action' field" }));
46360
+ return;
46361
+ }
46362
+ const confirmation = {
46363
+ action: parsed.action,
46364
+ status: parsed.status ?? "completed",
46365
+ decisionId: parsed.decision_id,
46366
+ detail: parsed.detail,
46367
+ estimated_cost: parsed.estimated_cost
46368
+ };
46369
+ if (parsed.room_id && typeof parsed.room_id === "string") {
46370
+ await this.sendActionConfirmationToRoom(parsed.room_id, confirmation);
46371
+ } else {
46372
+ await this.sendActionConfirmation(confirmation);
46238
46373
  }
46239
46374
  res.writeHead(200, { "Content-Type": "application/json" });
46240
46375
  res.end(JSON.stringify({ ok: true }));
@@ -46253,7 +46388,7 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
46253
46388
  }));
46254
46389
  } else {
46255
46390
  res.writeHead(404, { "Content-Type": "application/json" });
46256
- res.end(JSON.stringify({ ok: false, error: "Not found. Use POST /send or GET /status" }));
46391
+ res.end(JSON.stringify({ ok: false, error: "Not found. Use POST /send, POST /action, or GET /status" }));
46257
46392
  }
46258
46393
  });
46259
46394
  this._httpServer.listen(port, "127.0.0.1", () => {
@@ -47047,7 +47182,15 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
47047
47182
  nonce: hexToBytes(msgData.nonce)
47048
47183
  };
47049
47184
  const ratchet = DoubleRatchet.deserialize(channelEntry.session.ratchetState);
47050
- const plaintext = ratchet.decrypt(encryptedMessage);
47185
+ const ratchetSnapshot = channelEntry.session.ratchetState;
47186
+ let a2aPlaintext;
47187
+ try {
47188
+ a2aPlaintext = ratchet.decrypt(encryptedMessage);
47189
+ } catch (decryptErr) {
47190
+ console.error(`[SecureChannel] A2A decrypt failed \u2014 restoring ratchet state:`, decryptErr);
47191
+ channelEntry.session.ratchetState = ratchetSnapshot;
47192
+ return;
47193
+ }
47051
47194
  channelEntry.session.ratchetState = ratchet.serialize();
47052
47195
  if (channelEntry.role === "responder" && !channelEntry.session.activated) {
47053
47196
  channelEntry.session.activated = true;
@@ -47070,7 +47213,7 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
47070
47213
  }
47071
47214
  await this._persistState();
47072
47215
  const a2aMsg = {
47073
- text: plaintext,
47216
+ text: a2aPlaintext,
47074
47217
  fromHubAddress: msgData.from_hub_address || msgData.hub_address || "",
47075
47218
  channelId,
47076
47219
  conversationId: msgData.conversation_id || "",
@@ -47141,7 +47284,19 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
47141
47284
  header_blob: msgData.header_blob,
47142
47285
  ciphertext: msgData.ciphertext
47143
47286
  });
47144
- const plaintext = session.ratchet.decrypt(encrypted);
47287
+ const ratchetSnapshot = session.ratchet.serialize();
47288
+ let plaintext;
47289
+ try {
47290
+ plaintext = session.ratchet.decrypt(encrypted);
47291
+ } catch (decryptErr) {
47292
+ console.error(`[SecureChannel] Decrypt failed for conv ${convId.slice(0, 8)}... \u2014 restoring ratchet:`, decryptErr);
47293
+ try {
47294
+ session.ratchet = DoubleRatchet.deserialize(ratchetSnapshot);
47295
+ } catch (restoreErr) {
47296
+ console.error("[SecureChannel] Ratchet restore failed:", restoreErr);
47297
+ }
47298
+ return;
47299
+ }
47145
47300
  this._sendAck(msgData.message_id);
47146
47301
  if (!session.activated) {
47147
47302
  session.activated = true;
@@ -47529,9 +47684,14 @@ ${messageText}`;
47529
47684
  ciphertext: msgData.ciphertext
47530
47685
  });
47531
47686
  let plaintext;
47687
+ const ratchetSnapshot = session.ratchet.serialize();
47532
47688
  try {
47533
47689
  plaintext = session.ratchet.decrypt(encrypted);
47534
47690
  } catch (decryptErr) {
47691
+ try {
47692
+ session.ratchet = DoubleRatchet.deserialize(ratchetSnapshot);
47693
+ } catch {
47694
+ }
47535
47695
  console.warn(
47536
47696
  `[SecureChannel] Room decrypt failed for conv ${convId.slice(0, 8)}...: ${String(decryptErr)}, re-initializing ratchet`
47537
47697
  );
@@ -47677,7 +47837,20 @@ ${messageText}`;
47677
47837
  header_blob: msg.header_blob,
47678
47838
  ciphertext: msg.ciphertext
47679
47839
  });
47680
- const plaintext = session.ratchet.decrypt(encrypted);
47840
+ const ratchetSnapshot = session.ratchet.serialize();
47841
+ let plaintext;
47842
+ try {
47843
+ plaintext = session.ratchet.decrypt(encrypted);
47844
+ } catch (decryptErr) {
47845
+ console.error(`[SecureChannel] Sync decrypt failed for ${msg.conversation_id.slice(0, 8)}... \u2014 restoring ratchet:`, decryptErr);
47846
+ try {
47847
+ session.ratchet = DoubleRatchet.deserialize(ratchetSnapshot);
47848
+ } catch {
47849
+ }
47850
+ this._persisted.lastMessageTimestamp = msg.created_at;
47851
+ since = msg.created_at;
47852
+ continue;
47853
+ }
47681
47854
  this._sendAck(msg.id);
47682
47855
  if (!session.activated) {
47683
47856
  session.activated = true;
@@ -47712,7 +47885,7 @@ ${messageText}`;
47712
47885
  totalProcessed++;
47713
47886
  } catch (err) {
47714
47887
  console.warn(
47715
- `[SecureChannel] Sync decrypt failed for msg ${msg.id.slice(0, 8)}... in conv ${msg.conversation_id.slice(0, 8)}...: ${String(err)}`
47888
+ `[SecureChannel] Sync failed for msg ${msg.id.slice(0, 8)}... in conv ${msg.conversation_id.slice(0, 8)}...: ${String(err)}`
47716
47889
  );
47717
47890
  this._persisted.lastMessageTimestamp = msg.created_at;
47718
47891
  since = msg.created_at;
@@ -47908,7 +48081,18 @@ ${messageText}`;
47908
48081
  header_blob: msg.header_blob,
47909
48082
  ciphertext: msg.ciphertext
47910
48083
  });
47911
- const plaintext = session.ratchet.decrypt(encrypted);
48084
+ const ratchetSnapshot = session.ratchet.serialize();
48085
+ let plaintext;
48086
+ try {
48087
+ plaintext = session.ratchet.decrypt(encrypted);
48088
+ } catch (decryptErr) {
48089
+ console.error(`[SecureChannel] Room sync decrypt failed for ${msg.conversation_id.slice(0, 8)}... \u2014 restoring ratchet:`, decryptErr);
48090
+ try {
48091
+ session.ratchet = DoubleRatchet.deserialize(ratchetSnapshot);
48092
+ } catch {
48093
+ }
48094
+ continue;
48095
+ }
47912
48096
  if (!session.activated) {
47913
48097
  session.activated = true;
47914
48098
  }
@@ -47988,6 +48172,7 @@ ${messageText}`;
47988
48172
  };
47989
48173
  }
47990
48174
  await saveState(this.config.dataDir, this._persisted);
48175
+ await backupState(this.config.dataDir);
47991
48176
  }
47992
48177
  };
47993
48178
 
@@ -48014,8 +48199,7 @@ function resolveAccount(cfg, accountId) {
48014
48199
  apiUrl: av.apiUrl ?? DEFAULT_API_URL,
48015
48200
  agentName: id,
48016
48201
  httpPort: DEFAULT_HTTP_PORT,
48017
- configured: false,
48018
- inviteToken: ""
48202
+ configured: false
48019
48203
  };
48020
48204
  }
48021
48205
  let httpPort = acct.httpPort;
@@ -48030,8 +48214,7 @@ function resolveAccount(cfg, accountId) {
48030
48214
  apiUrl: acct.apiUrl ?? av.apiUrl ?? DEFAULT_API_URL,
48031
48215
  agentName: acct.agentName ?? id,
48032
48216
  httpPort,
48033
- configured: Boolean(acct.dataDir),
48034
- inviteToken: acct.inviteToken ?? ""
48217
+ configured: Boolean(acct.dataDir)
48035
48218
  };
48036
48219
  }
48037
48220
  return {
@@ -48040,8 +48223,7 @@ function resolveAccount(cfg, accountId) {
48040
48223
  apiUrl: av.apiUrl ?? DEFAULT_API_URL,
48041
48224
  agentName: av.agentName ?? "OpenClaw Agent",
48042
48225
  httpPort: av.httpPort ?? DEFAULT_HTTP_PORT,
48043
- configured: Boolean(av.dataDir),
48044
- inviteToken: av.inviteToken ?? ""
48226
+ configured: Boolean(av.dataDir)
48045
48227
  };
48046
48228
  }
48047
48229
 
@@ -48082,43 +48264,46 @@ var agentVaultPlugin = {
48082
48264
  }
48083
48265
  const dataDir = resolve(account.dataDir.replace(/^~/, process.env.HOME ?? "~"));
48084
48266
  log?.(`[AgentVault] starting channel (dataDir=${dataDir})`);
48085
- const channel = new SecureChannel({
48086
- // No invite token needed — resuming from persisted enrolled state
48087
- inviteToken: "",
48088
- dataDir,
48089
- apiUrl: account.apiUrl,
48090
- agentName: account.agentName,
48091
- onMessage: async (plaintext, metadata) => {
48092
- if (!_ocRuntime) {
48093
- log?.("[AgentVault] runtime not ready \u2014 dropping inbound message");
48094
- return;
48095
- }
48096
- try {
48097
- await _handleInbound({ plaintext, metadata, channel, account, cfg });
48098
- } catch (err) {
48099
- log?.(`[AgentVault] inbound dispatch error: ${String(err)}`);
48267
+ await new Promise((resolvePromise, reject) => {
48268
+ const channel = new SecureChannel({
48269
+ inviteToken: "",
48270
+ dataDir,
48271
+ apiUrl: account.apiUrl,
48272
+ agentName: account.agentName,
48273
+ onMessage: async (plaintext, metadata) => {
48274
+ if (!_ocRuntime) {
48275
+ log?.("[AgentVault] runtime not ready \u2014 dropping inbound message");
48276
+ return;
48277
+ }
48278
+ try {
48279
+ await _handleInbound({ plaintext, metadata, channel, account, cfg });
48280
+ } catch (err) {
48281
+ log?.(`[AgentVault] inbound dispatch error: ${String(err)}`);
48282
+ }
48283
+ },
48284
+ onStateChange: (state) => {
48285
+ log?.(`[AgentVault] state \u2192 ${state}`);
48286
+ if (state === "error") reject(new Error("AgentVault channel permanent error"));
48100
48287
  }
48101
- },
48102
- onStateChange: (state) => {
48103
- log?.(`[AgentVault] state \u2192 ${state}`);
48104
- }
48105
- });
48106
- _channels.set(account.accountId, channel);
48107
- const httpPort = account.httpPort;
48108
- channel.on("ready", () => {
48109
- channel.startHttpServer(httpPort);
48110
- log?.(`[AgentVault] HTTP send server listening on http://127.0.0.1:${httpPort}`);
48111
- });
48112
- abortSignal?.addEventListener("abort", () => {
48113
- _channels.delete(account.accountId);
48114
- });
48115
- await channel.start();
48116
- return {
48117
- stop: async () => {
48288
+ });
48289
+ _channels.set(account.accountId, channel);
48290
+ channel.on("error", (err) => {
48291
+ log?.(`[AgentVault] channel error (non-fatal): ${String(err)}`);
48292
+ });
48293
+ const httpPort = account.httpPort;
48294
+ channel.on("ready", () => {
48295
+ channel.startHttpServer(httpPort);
48296
+ log?.(`[AgentVault] HTTP send server listening on http://127.0.0.1:${httpPort}`);
48297
+ });
48298
+ abortSignal?.addEventListener("abort", async () => {
48118
48299
  await channel.stop();
48119
48300
  _channels.delete(account.accountId);
48120
- }
48121
- };
48301
+ resolvePromise();
48302
+ });
48303
+ channel.start().catch(reject);
48304
+ });
48305
+ return { stop: async () => {
48306
+ } };
48122
48307
  }
48123
48308
  },
48124
48309
  outbound: {
@@ -48283,7 +48468,7 @@ async function checkGateway(options) {
48283
48468
  }
48284
48469
 
48285
48470
  // src/index.ts
48286
- var VERSION = "0.11.0";
48471
+ var VERSION = "0.13.8";
48287
48472
  export {
48288
48473
  SecureChannel,
48289
48474
  VERSION,