@agentvault/claude-bridge 0.6.2 → 0.6.3

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 (2) hide show
  1. package/dist/index.js +74 -5
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -65555,7 +65555,7 @@ var init_channel = __esm2({
65555
65555
  */
65556
65556
  sendActivitySpan(spanData) {
65557
65557
  if (!this._ws || this._ws.readyState !== WebSocket2.OPEN) return;
65558
- const pluginVersion = true ? "0.23.8" : "0.0.0-dev";
65558
+ const pluginVersion = true ? "0.23.9" : "0.0.0-dev";
65559
65559
  const agentName = this.config.agentName ?? "Agent";
65560
65560
  const resource = {
65561
65561
  "service.name": "agentvault-agent",
@@ -65796,10 +65796,76 @@ var init_channel = __esm2({
65796
65796
  this._sessions.delete(convId);
65797
65797
  delete this._persisted.sessions[convId];
65798
65798
  }
65799
+ if (room.mlsGroupId) {
65800
+ try {
65801
+ await deleteMlsState(this.config.dataDir, room.mlsGroupId);
65802
+ } catch {
65803
+ }
65804
+ }
65805
+ this._mlsGroups.delete(roomId);
65799
65806
  delete this._persisted.rooms[roomId];
65800
65807
  await this._persistState();
65801
65808
  this.emit("room_left", { roomId });
65802
65809
  }
65810
+ /**
65811
+ * #629 recurrence fix — reconcile local room state against the server on
65812
+ * connect.
65813
+ *
65814
+ * On disband the server marks each member ``"left"`` and sets
65815
+ * ``room.status="disbanded"`` but sends NO WS event to the agent's bridge, so a
65816
+ * disbanded/left room lingers in local state and replays dead MLS commit
65817
+ * history on every reconnect ("Desired gen in the past" / "invalid ghash tag").
65818
+ * ``GET /rooms`` returns ONLY active rooms the caller is a member of, so any
65819
+ * locally-persisted room ABSENT from it is terminal — prune its MLS state
65820
+ * (file + in-memory group, keyed by roomId), its sessions, and the room entry.
65821
+ *
65822
+ * Fail-safe: a failed fetch / non-ok / non-array response prunes NOTHING, so a
65823
+ * transient error can never over-prune a live room.
65824
+ */
65825
+ async _reconcileRoomsWithServer() {
65826
+ const local = this._persisted?.rooms;
65827
+ if (!local || Object.keys(local).length === 0) return;
65828
+ if (!this._deviceJwt) return;
65829
+ let activeIds;
65830
+ try {
65831
+ const res = await fetch(`${this.config.apiUrl}/api/v1/rooms`, {
65832
+ headers: { Authorization: `Bearer ${this._deviceJwt}` }
65833
+ });
65834
+ if (!res.ok) return;
65835
+ const list = await res.json();
65836
+ if (!Array.isArray(list)) return;
65837
+ activeIds = new Set(
65838
+ list.map((r22) => r22?.id).filter((id) => !!id)
65839
+ );
65840
+ } catch (err) {
65841
+ console.warn(
65842
+ `[SecureChannel] room reconcile skipped (fetch failed, pruning nothing): ${err instanceof Error ? err.message : String(err)}`
65843
+ );
65844
+ return;
65845
+ }
65846
+ const stale = Object.keys(local).filter((rid) => !activeIds.has(rid));
65847
+ if (stale.length === 0) return;
65848
+ for (const rid of stale) {
65849
+ const room = local[rid];
65850
+ if (room?.mlsGroupId) {
65851
+ try {
65852
+ await deleteMlsState(this.config.dataDir, room.mlsGroupId);
65853
+ } catch {
65854
+ }
65855
+ }
65856
+ this._mlsGroups.delete(rid);
65857
+ for (const convId of room?.conversationIds ?? []) {
65858
+ this._sessions.delete(convId);
65859
+ if (this._persisted?.sessions) delete this._persisted.sessions[convId];
65860
+ }
65861
+ delete local[rid];
65862
+ }
65863
+ await this._persistState();
65864
+ console.log(
65865
+ `[SecureChannel] Room reconcile: pruned ${stale.length} disbanded/left room(s) from local state (${stale.map((r22) => r22.slice(0, 8)).join(", ")})`
65866
+ );
65867
+ this.emit("rooms_reconciled", { pruned: stale });
65868
+ }
65803
65869
  /**
65804
65870
  * Return info for all joined rooms.
65805
65871
  */
@@ -67150,6 +67216,9 @@ var init_channel = __esm2({
67150
67216
  await this._pullDrDeliveryQueue();
67151
67217
  await this._flushOutboundQueue();
67152
67218
  this._setState("ready");
67219
+ void this._reconcileRoomsWithServer().catch(
67220
+ (err) => console.warn(`[SecureChannel] room reconcile failed (ignored): ${err instanceof Error ? err.message : String(err)}`)
67221
+ );
67153
67222
  if (this.config.enableScanning) {
67154
67223
  this._scanEngine = new ScanEngine();
67155
67224
  await this._fetchScanRules();
@@ -67172,7 +67241,7 @@ var init_channel = __esm2({
67172
67241
  agentVersion: this.config.agentVersion ?? "0.0.0",
67173
67242
  // __AV_VERSION__ is injected by esbuild from package.json at build time.
67174
67243
  // Falls back to "0.0.0-dev" in non-bundled contexts (tests).
67175
- pluginVersion: true ? "0.23.8" : "0.0.0-dev"
67244
+ pluginVersion: true ? "0.23.9" : "0.0.0-dev"
67176
67245
  });
67177
67246
  this._telemetryReporter.startAutoFlush(3e4);
67178
67247
  }
@@ -67490,7 +67559,7 @@ var init_channel = __esm2({
67490
67559
  agentVersion: this.config.agentVersion ?? "0.0.0",
67491
67560
  // __AV_VERSION__ is injected by esbuild from package.json at build time.
67492
67561
  // Falls back to "0.0.0-dev" in non-bundled contexts (tests).
67493
- pluginVersion: true ? "0.23.8" : "0.0.0-dev"
67562
+ pluginVersion: true ? "0.23.9" : "0.0.0-dev"
67494
67563
  });
67495
67564
  this._telemetryReporter.startAutoFlush(3e4);
67496
67565
  }
@@ -97268,7 +97337,7 @@ var init_index = __esm2({
97268
97337
  init_skill_invoker();
97269
97338
  await init_skill_telemetry();
97270
97339
  await init_policy_enforcer();
97271
- VERSION = true ? "0.23.8" : "0.0.0-dev";
97340
+ VERSION = true ? "0.23.9" : "0.0.0-dev";
97272
97341
  }
97273
97342
  });
97274
97343
  await init_index();
@@ -133303,7 +133372,7 @@ async function main() {
133303
133372
  "[bridge] warning: passing the invite token on the command line is visible to other local users via 'ps'. Prefer: AV_INVITE_TOKEN=\u2026 npx @agentvault/claude-bridge"
133304
133373
  );
133305
133374
  }
133306
- console.error(`[bridge] version: ${true ? "0.6.2" : "dev"}`);
133375
+ console.error(`[bridge] version: ${true ? "0.6.3" : "dev"}`);
133307
133376
  console.error(`[bridge] data dir: ${cfg.dataDir} (${cfg.dataDirSource})`);
133308
133377
  console.error(`[bridge] workspace: ${cfg.workspaceDir} \xB7 permissions: ${cfg.permissionMode} \xB7 enclave dir fenced`);
133309
133378
  if (cfg.armRoom) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentvault/claude-bridge",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "type": "module",
5
5
  "description": "AgentVault Claude Bridge — daemon for bridging a Claude agent into secure E2E-encrypted AgentVault 1:1 direct messages and rooms.",
6
6
  "main": "dist/index.js",