@agentvault/claude-bridge 0.8.5 → 0.8.7
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/dist/index.js +111 -55
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -64612,11 +64612,11 @@ var init_mls_kp_pool = __esm2({
|
|
|
64612
64612
|
}
|
|
64613
64613
|
});
|
|
64614
64614
|
function ownIdentity() {
|
|
64615
|
-
const v22 = true ? "0.23.
|
|
64615
|
+
const v22 = true ? "0.23.34" : FALLBACK;
|
|
64616
64616
|
return `${PACKAGE}@${v22}`;
|
|
64617
64617
|
}
|
|
64618
64618
|
function buildSha() {
|
|
64619
|
-
const raw = true ? "
|
|
64619
|
+
const raw = true ? "6b305ca-dirty" : "";
|
|
64620
64620
|
const cleaned = (raw ?? "").trim();
|
|
64621
64621
|
return !cleaned || cleaned === "unknown" ? null : cleaned;
|
|
64622
64622
|
}
|
|
@@ -65531,6 +65531,7 @@ var OUTBOUND_DEDUPE_MAX;
|
|
|
65531
65531
|
var OUTBOUND_DEDUPE_TYPES;
|
|
65532
65532
|
var RETRY_CANDIDATE_TTL_MS;
|
|
65533
65533
|
var RETRY_CANDIDATE_MAX;
|
|
65534
|
+
var ROOM_FULFIL_COOLDOWN_MS;
|
|
65534
65535
|
var SecureChannel;
|
|
65535
65536
|
var init_channel = __esm2({
|
|
65536
65537
|
async "src/channel.ts"() {
|
|
@@ -65576,6 +65577,7 @@ var init_channel = __esm2({
|
|
|
65576
65577
|
OUTBOUND_DEDUPE_TYPES = /* @__PURE__ */ new Set(["text", "status_alert", "artifact", "attachment"]);
|
|
65577
65578
|
RETRY_CANDIDATE_TTL_MS = 6e4;
|
|
65578
65579
|
RETRY_CANDIDATE_MAX = 32;
|
|
65580
|
+
ROOM_FULFIL_COOLDOWN_MS = 6e4;
|
|
65579
65581
|
SecureChannel = class _SecureChannel extends EventEmitter {
|
|
65580
65582
|
constructor(config22) {
|
|
65581
65583
|
super();
|
|
@@ -65645,6 +65647,8 @@ var init_channel = __esm2({
|
|
|
65645
65647
|
_drDeliveryPulling = false;
|
|
65646
65648
|
/** MLS group managers per room/conversation (roomId or conv:conversationId or 1to1-group:groupId -> MLSGroupManager) */
|
|
65647
65649
|
_mlsGroups = /* @__PURE__ */ new Map();
|
|
65650
|
+
/** `${mlsGroupId}:${deviceId}` -> last re-admit ms (#1171). */
|
|
65651
|
+
_roomFulfilCooldown = /* @__PURE__ */ new Map();
|
|
65648
65652
|
/** Maps conversationId -> conversation_group_id for shared 1:1 MLS groups */
|
|
65649
65653
|
_sessionGroupIds = /* @__PURE__ */ new Map();
|
|
65650
65654
|
/** Consecutive MLS decrypt failure count per group key for epoch recovery. */
|
|
@@ -66810,7 +66814,7 @@ var init_channel = __esm2({
|
|
|
66810
66814
|
*/
|
|
66811
66815
|
sendActivitySpan(spanData) {
|
|
66812
66816
|
if (!this._ws || this._ws.readyState !== WebSocket2.OPEN) return;
|
|
66813
|
-
const pluginVersion = true ? "0.23.
|
|
66817
|
+
const pluginVersion = true ? "0.23.34" : "0.0.0-dev";
|
|
66814
66818
|
const agentName = this.config.agentName ?? "Agent";
|
|
66815
66819
|
const resource = {
|
|
66816
66820
|
"service.name": "agentvault-agent",
|
|
@@ -68748,7 +68752,7 @@ var init_channel = __esm2({
|
|
|
68748
68752
|
agentVersion: this.config.agentVersion ?? "0.0.0",
|
|
68749
68753
|
// __AV_VERSION__ is injected by esbuild from package.json at build time.
|
|
68750
68754
|
// Falls back to "0.0.0-dev" in non-bundled contexts (tests).
|
|
68751
|
-
pluginVersion: true ? "0.23.
|
|
68755
|
+
pluginVersion: true ? "0.23.34" : "0.0.0-dev"
|
|
68752
68756
|
});
|
|
68753
68757
|
this._telemetryReporter.startAutoFlush(3e4);
|
|
68754
68758
|
}
|
|
@@ -69072,7 +69076,7 @@ var init_channel = __esm2({
|
|
|
69072
69076
|
agentVersion: this.config.agentVersion ?? "0.0.0",
|
|
69073
69077
|
// __AV_VERSION__ is injected by esbuild from package.json at build time.
|
|
69074
69078
|
// Falls back to "0.0.0-dev" in non-bundled contexts (tests).
|
|
69075
|
-
pluginVersion: true ? "0.23.
|
|
69079
|
+
pluginVersion: true ? "0.23.34" : "0.0.0-dev"
|
|
69076
69080
|
});
|
|
69077
69081
|
this._telemetryReporter.startAutoFlush(3e4);
|
|
69078
69082
|
}
|
|
@@ -69476,6 +69480,7 @@ var init_channel = __esm2({
|
|
|
69476
69480
|
try {
|
|
69477
69481
|
const cipherBytes = new Uint8Array(Buffer.from(data.payload, "hex"));
|
|
69478
69482
|
const result = await mgr.decrypt(cipherBytes);
|
|
69483
|
+
if (mgrKey) this._mlsDecryptFailCounts.delete(mgrKey);
|
|
69479
69484
|
const mlsGroupId = (convGroupId ? this._persisted?.mlsGroups?.[convGroupId]?.mlsGroupId : null) ?? this._persisted?.mlsConversations?.[convId]?.mlsGroupId ?? groupId;
|
|
69480
69485
|
if (mlsGroupId) {
|
|
69481
69486
|
await saveMlsState(this.config.dataDir, mlsGroupId, JSON.stringify(mgr.exportState()));
|
|
@@ -69580,6 +69585,10 @@ var init_channel = __esm2({
|
|
|
69580
69585
|
this.config.onMessage(text, metadata);
|
|
69581
69586
|
}
|
|
69582
69587
|
} catch (decryptErr) {
|
|
69588
|
+
if (classifyCommitFailure(data.epoch, mgr?.epoch) === "already-applied") {
|
|
69589
|
+
console.debug(`[SecureChannel] MLS 1:1 message at epoch ${String(data.epoch)} predates our epoch ${String(mgr?.epoch)} \u2014 cannot decrypt, ignoring`);
|
|
69590
|
+
return;
|
|
69591
|
+
}
|
|
69583
69592
|
const failKey = mgrKey || `unknown:${groupId}`;
|
|
69584
69593
|
const count = (this._mlsDecryptFailCounts.get(failKey) ?? 0) + 1;
|
|
69585
69594
|
this._mlsDecryptFailCounts.set(failKey, count);
|
|
@@ -70421,6 +70430,7 @@ ${baseText}`;
|
|
|
70421
70430
|
try {
|
|
70422
70431
|
const ciphertext = Buffer.from(data.payload, "hex");
|
|
70423
70432
|
const result = await mlsGroup.decrypt(new Uint8Array(ciphertext));
|
|
70433
|
+
this._mlsDecryptFailCounts.delete(resolvedRoomId);
|
|
70424
70434
|
await saveMlsState(this.config.dataDir, groupId, JSON.stringify(mlsGroup.exportState()));
|
|
70425
70435
|
if (result.isHandshake || !result.plaintext) {
|
|
70426
70436
|
return;
|
|
@@ -70510,6 +70520,10 @@ ${baseText}`;
|
|
|
70510
70520
|
console.error("[SecureChannel] onMessage callback error (MLS):", err);
|
|
70511
70521
|
});
|
|
70512
70522
|
} catch (err) {
|
|
70523
|
+
if (classifyCommitFailure(data.epoch, mlsGroup.epoch) === "already-applied") {
|
|
70524
|
+
console.debug(`[SecureChannel] MLS room message at epoch ${String(data.epoch)} predates our epoch ${String(mlsGroup.epoch)} for ${resolvedRoomId.slice(0, 8)} \u2014 cannot decrypt, ignoring`);
|
|
70525
|
+
return;
|
|
70526
|
+
}
|
|
70513
70527
|
const failKey = resolvedRoomId;
|
|
70514
70528
|
const count = (this._mlsDecryptFailCounts.get(failKey) ?? 0) + 1;
|
|
70515
70529
|
this._mlsDecryptFailCounts.set(failKey, count);
|
|
@@ -70761,13 +70775,7 @@ ${baseText}`;
|
|
|
70761
70775
|
console.warn(`[SecureChannel] MLS epoch recovery for ${groupKey} (${mlsGroupId.slice(0, 8)})`);
|
|
70762
70776
|
this._mlsGroups.delete(groupKey);
|
|
70763
70777
|
this._mlsDecryptFailCounts.delete(groupKey);
|
|
70764
|
-
|
|
70765
|
-
const { unlink: unlink2 } = await import("fs/promises");
|
|
70766
|
-
const path2 = `${this.config.dataDir}/.mls-state/${mlsGroupId}.json`;
|
|
70767
|
-
await unlink2(path2).catch(() => {
|
|
70768
|
-
});
|
|
70769
|
-
} catch {
|
|
70770
|
-
}
|
|
70778
|
+
await deleteMlsState(this.config.dataDir, mlsGroupId);
|
|
70771
70779
|
try {
|
|
70772
70780
|
const mgr = new MLSGroupManager();
|
|
70773
70781
|
const identity = new TextEncoder().encode(this._deviceId);
|
|
@@ -70842,19 +70850,26 @@ ${baseText}`;
|
|
|
70842
70850
|
return 0;
|
|
70843
70851
|
}
|
|
70844
70852
|
const snapshot = mlsGroup.exportState();
|
|
70845
|
-
const {
|
|
70846
|
-
|
|
70847
|
-
|
|
70848
|
-
|
|
70849
|
-
|
|
70850
|
-
|
|
70851
|
-
|
|
70852
|
-
|
|
70853
|
-
|
|
70854
|
-
|
|
70855
|
-
|
|
70856
|
-
|
|
70857
|
-
|
|
70853
|
+
const { commits, welcome } = await mlsGroup.reAdmitMembers(targets.map((t22) => t22.keyPackage));
|
|
70854
|
+
let sentCommits = 0;
|
|
70855
|
+
for (const c22 of commits) {
|
|
70856
|
+
const ok2 = await this._sendFrameConfirmed(
|
|
70857
|
+
{
|
|
70858
|
+
event: "mls_commit",
|
|
70859
|
+
data: {
|
|
70860
|
+
group_id: mlsGroupId,
|
|
70861
|
+
// The epoch this commit PRODUCED. After two commits the manager
|
|
70862
|
+
// only knows the last one, which is why the result carries them.
|
|
70863
|
+
epoch: Number(c22.epoch),
|
|
70864
|
+
payload: Buffer.from(c22.commit).toString("hex")
|
|
70865
|
+
}
|
|
70866
|
+
},
|
|
70867
|
+
`${label} commit ${sentCommits + 1}/${commits.length}`
|
|
70868
|
+
);
|
|
70869
|
+
if (!ok2) break;
|
|
70870
|
+
sentCommits++;
|
|
70871
|
+
}
|
|
70872
|
+
if (sentCommits === 0) {
|
|
70858
70873
|
mlsGroup.importState(snapshot);
|
|
70859
70874
|
console.warn(
|
|
70860
70875
|
`[SecureChannel] ${label}: commit was NOT written \u2014 rolled back to epoch ${Number(mlsGroup.epoch)}, nothing fulfilled, requests stay pending`
|
|
@@ -70862,6 +70877,12 @@ ${baseText}`;
|
|
|
70862
70877
|
return 0;
|
|
70863
70878
|
}
|
|
70864
70879
|
await saveMlsState(this.config.dataDir, mlsGroupId, JSON.stringify(mlsGroup.exportState()));
|
|
70880
|
+
if (sentCommits < commits.length) {
|
|
70881
|
+
console.warn(
|
|
70882
|
+
`[SecureChannel] ${label}: only ${sentCommits}/${commits.length} commits reached the wire \u2014 requests stay PENDING for the next pull`
|
|
70883
|
+
);
|
|
70884
|
+
return 0;
|
|
70885
|
+
}
|
|
70865
70886
|
if (!welcome) {
|
|
70866
70887
|
console.warn(
|
|
70867
70888
|
`[SecureChannel] ${label}: addMembers produced NO Welcome \u2014 ${targets.length} request(s) left pending rather than marked fulfilled`
|
|
@@ -71542,6 +71563,11 @@ ${baseText}`;
|
|
|
71542
71563
|
nackedIds.push(msg.queue_id);
|
|
71543
71564
|
if (msg.group_id && (msg.message_type === "commit" || msg.message_type === "application")) {
|
|
71544
71565
|
const failKey = msg.conversation_group_id ? `1to1-group:${msg.conversation_group_id}` : `group:${msg.group_id}`;
|
|
71566
|
+
const localMgr = msg.room_id && this._mlsGroups.get(msg.room_id) || this._mlsGroups.get(failKey);
|
|
71567
|
+
if (classifyCommitFailure(msg.epoch, localMgr?.epoch) === "already-applied") {
|
|
71568
|
+
console.debug(`[SecureChannel] Delivery ${msg.message_type} at epoch ${String(msg.epoch)} predates our epoch ${String(localMgr?.epoch)} \u2014 not counting toward recovery`);
|
|
71569
|
+
continue;
|
|
71570
|
+
}
|
|
71545
71571
|
const count = (this._mlsDecryptFailCounts.get(failKey) ?? 0) + 1;
|
|
71546
71572
|
this._mlsDecryptFailCounts.set(failKey, count);
|
|
71547
71573
|
if (count >= _SecureChannel.MAX_MLS_DECRYPT_FAILS) {
|
|
@@ -71590,38 +71616,63 @@ ${baseText}`;
|
|
|
71590
71616
|
{ headers: { Authorization: `Bearer ${this._deviceJwt}` } }
|
|
71591
71617
|
);
|
|
71592
71618
|
if (!pendingRes.ok) continue;
|
|
71593
|
-
|
|
71619
|
+
let pending = await pendingRes.json();
|
|
71594
71620
|
if (pending.length === 0) continue;
|
|
71595
71621
|
console.log(`[SecureChannel] ${pending.length} pending Welcome requests for room ${roomId.slice(0, 8)}`);
|
|
71622
|
+
const nowMs = Date.now();
|
|
71623
|
+
const fresh = pending.filter((r22) => {
|
|
71624
|
+
const key = `${roomState.mlsGroupId}:${r22.requesting_device_id}`;
|
|
71625
|
+
const last = this._roomFulfilCooldown.get(key) ?? 0;
|
|
71626
|
+
if (nowMs - last < ROOM_FULFIL_COOLDOWN_MS) {
|
|
71627
|
+
console.log(
|
|
71628
|
+
`[SecureChannel] skipping ${r22.requesting_device_id.slice(0, 8)} in room ${roomId.slice(0, 8)} \u2014 re-admitted ${Math.round((nowMs - last) / 1e3)}s ago`
|
|
71629
|
+
);
|
|
71630
|
+
return false;
|
|
71631
|
+
}
|
|
71632
|
+
return true;
|
|
71633
|
+
});
|
|
71634
|
+
if (fresh.length === 0) continue;
|
|
71635
|
+
for (const r22 of fresh) {
|
|
71636
|
+
this._roomFulfilCooldown.set(`${roomState.mlsGroupId}:${r22.requesting_device_id}`, nowMs);
|
|
71637
|
+
}
|
|
71638
|
+
pending = fresh;
|
|
71639
|
+
const deviceIds = pending.map((r22) => r22.requesting_device_id);
|
|
71640
|
+
const kpRes = await fetch(
|
|
71641
|
+
`${this.config.apiUrl}/api/v1/mls/key-packages/batch?device_ids=${deviceIds.join(",")}`,
|
|
71642
|
+
{ headers: { Authorization: `Bearer ${this._deviceJwt}` } }
|
|
71643
|
+
);
|
|
71644
|
+
if (!kpRes.ok) continue;
|
|
71645
|
+
const kpData = await kpRes.json();
|
|
71646
|
+
const roomTargets = [];
|
|
71596
71647
|
for (const req of pending) {
|
|
71597
|
-
|
|
71598
|
-
|
|
71599
|
-
|
|
71600
|
-
|
|
71648
|
+
const kpHex = kpData[req.requesting_device_id];
|
|
71649
|
+
if (!kpHex) {
|
|
71650
|
+
console.warn(`[SecureChannel] No KeyPackage for ${req.requesting_device_id.slice(0, 8)}, skipping`);
|
|
71651
|
+
continue;
|
|
71652
|
+
}
|
|
71653
|
+
const kpBytes = new Uint8Array(Buffer.from(kpHex, "hex"));
|
|
71654
|
+
roomTargets.push({
|
|
71655
|
+
requestId: req.id,
|
|
71656
|
+
deviceId: req.requesting_device_id,
|
|
71657
|
+
keyPackage: MLSGroupManager.deserializeKeyPackage(kpBytes)
|
|
71658
|
+
});
|
|
71659
|
+
}
|
|
71660
|
+
if (roomTargets.length === 0) continue;
|
|
71661
|
+
try {
|
|
71662
|
+
const done = await this._fulfilWelcomeRequests({
|
|
71663
|
+
mlsGroup,
|
|
71664
|
+
mlsGroupId: roomState.mlsGroupId,
|
|
71665
|
+
label: `room ${roomId.slice(0, 8)}`,
|
|
71666
|
+
welcomeFields: { room_id: roomId },
|
|
71667
|
+
targets: roomTargets
|
|
71668
|
+
});
|
|
71669
|
+
if (done > 0) {
|
|
71670
|
+
console.log(
|
|
71671
|
+
`[SecureChannel] Batched Welcome for ${done}/${roomTargets.length} device(s) in room ${roomId.slice(0, 8)} (epoch=${mlsGroup.epoch})`
|
|
71601
71672
|
);
|
|
71602
|
-
if (!kpRes.ok) continue;
|
|
71603
|
-
const kpData = await kpRes.json();
|
|
71604
|
-
const kpHex = kpData[req.requesting_device_id];
|
|
71605
|
-
if (!kpHex) continue;
|
|
71606
|
-
const kpBytes = new Uint8Array(Buffer.from(kpHex, "hex"));
|
|
71607
|
-
const memberKp = MLSGroupManager.deserializeKeyPackage(kpBytes);
|
|
71608
|
-
const done = await this._fulfilWelcomeRequests({
|
|
71609
|
-
mlsGroup,
|
|
71610
|
-
mlsGroupId: roomState.mlsGroupId,
|
|
71611
|
-
label: `room ${roomId.slice(0, 8)}`,
|
|
71612
|
-
welcomeFields: { room_id: roomId },
|
|
71613
|
-
targets: [{
|
|
71614
|
-
requestId: req.id,
|
|
71615
|
-
deviceId: req.requesting_device_id,
|
|
71616
|
-
keyPackage: memberKp
|
|
71617
|
-
}]
|
|
71618
|
-
});
|
|
71619
|
-
if (done > 0) {
|
|
71620
|
-
console.log(`[SecureChannel] Fulfilled Welcome for ${req.requesting_device_id.slice(0, 8)} in room ${roomId.slice(0, 8)}`);
|
|
71621
|
-
}
|
|
71622
|
-
} catch (fulfillErr) {
|
|
71623
|
-
console.warn(`[SecureChannel] Welcome fulfill failed for ${req.requesting_device_id.slice(0, 8)}:`, fulfillErr);
|
|
71624
71673
|
}
|
|
71674
|
+
} catch (fulfillErr) {
|
|
71675
|
+
console.warn(`[SecureChannel] Batched Welcome failed for room ${roomId.slice(0, 8)}:`, fulfillErr);
|
|
71625
71676
|
}
|
|
71626
71677
|
} catch {
|
|
71627
71678
|
}
|
|
@@ -72194,6 +72245,7 @@ ${baseText}`;
|
|
|
72194
72245
|
try {
|
|
72195
72246
|
const ciphertext = new Uint8Array(Buffer.from(data.payload, "hex"));
|
|
72196
72247
|
const result = await mlsGroup.decrypt(ciphertext);
|
|
72248
|
+
this._mlsDecryptFailCounts.delete(`a2a:${a2aChannelId}`);
|
|
72197
72249
|
await saveMlsState(this.config.dataDir, groupId, JSON.stringify(mlsGroup.exportState()));
|
|
72198
72250
|
if (result.isHandshake || !result.plaintext) {
|
|
72199
72251
|
return;
|
|
@@ -72214,6 +72266,10 @@ ${baseText}`;
|
|
|
72214
72266
|
this.config.onA2AMessage(a2aMsg);
|
|
72215
72267
|
}
|
|
72216
72268
|
} catch (err) {
|
|
72269
|
+
if (classifyCommitFailure(data.epoch, mlsGroup?.epoch) === "already-applied") {
|
|
72270
|
+
console.debug(`[SecureChannel] MLS A2A message at epoch ${String(data.epoch)} predates our epoch ${String(mlsGroup?.epoch)} for ${a2aChannelId.slice(0, 8)} \u2014 cannot decrypt, ignoring`);
|
|
72271
|
+
return;
|
|
72272
|
+
}
|
|
72217
72273
|
const failKey = `a2a:${a2aChannelId}`;
|
|
72218
72274
|
const count = (this._mlsDecryptFailCounts.get(failKey) ?? 0) + 1;
|
|
72219
72275
|
this._mlsDecryptFailCounts.set(failKey, count);
|
|
@@ -99432,7 +99488,7 @@ var init_index = __esm2({
|
|
|
99432
99488
|
await init_skill_telemetry();
|
|
99433
99489
|
await init_policy_enforcer();
|
|
99434
99490
|
init_room_protocol();
|
|
99435
|
-
VERSION = true ? "0.23.
|
|
99491
|
+
VERSION = true ? "0.23.34" : "0.0.0-dev";
|
|
99436
99492
|
}
|
|
99437
99493
|
});
|
|
99438
99494
|
await init_index();
|
|
@@ -135836,7 +135892,7 @@ async function main() {
|
|
|
135836
135892
|
"[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"
|
|
135837
135893
|
);
|
|
135838
135894
|
}
|
|
135839
|
-
logLine(`[bridge] version: ${true ? "0.8.
|
|
135895
|
+
logLine(`[bridge] version: ${true ? "0.8.7" : "dev"}`);
|
|
135840
135896
|
logLine(`[bridge] data dir: ${cfg.dataDir} (${cfg.dataDirSource})`);
|
|
135841
135897
|
logLine(`[bridge] workspace: ${cfg.workspaceDir} \xB7 permissions: ${cfg.permissionMode} \xB7 enclave dir fenced`);
|
|
135842
135898
|
if (cfg.armRoom) {
|
|
@@ -135868,7 +135924,7 @@ async function main() {
|
|
|
135868
135924
|
// its default would render "@agentvault/agentvault@0.7.x" — the wrong
|
|
135869
135925
|
// package name attached to the bridge's version number, which is worse
|
|
135870
135926
|
// than either alone.
|
|
135871
|
-
clientVersion: `@agentvault/claude-bridge@${true ? "0.8.
|
|
135927
|
+
clientVersion: `@agentvault/claude-bridge@${true ? "0.8.7" : "dev"}`
|
|
135872
135928
|
});
|
|
135873
135929
|
const agentSystemPrompt = cfg.systemPrompt ?? `You are ${cfg.agentName}, an AI agent on AgentVault. You talk with your owner in 1:1 direct messages and collaborate with other agents in shared rooms. That is your identity \u2014 introduce yourself by that name and do not claim to be any other agent. To speak, call the say tool. In a 1:1 with your owner, reply to what they say. In a room you see every message \u2014 call say only when you have something worth adding, and otherwise stay silent. Keep messages concise.`;
|
|
135874
135930
|
const deviceJwt = () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentvault/claude-bridge",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
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",
|