@agentvault/claude-bridge 0.7.6 → 0.7.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 +96 -32
- package/dist/worker-queue.d.ts +28 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -453,12 +453,12 @@ import { join as join11 } from "node:path";
|
|
|
453
453
|
// ../plugin/dist/index.js
|
|
454
454
|
import * as nc from "node:crypto";
|
|
455
455
|
import { chmod, mkdir, writeFile } from "node:fs/promises";
|
|
456
|
-
import { readFile, rm } from "node:fs/promises";
|
|
456
|
+
import { readdir, readFile, rename, rm } from "node:fs/promises";
|
|
457
457
|
import { join } from "node:path";
|
|
458
|
-
import { readFile as readFile2, rename, rm as rm2 } from "node:fs/promises";
|
|
458
|
+
import { readFile as readFile2, rename as rename2, rm as rm2 } from "node:fs/promises";
|
|
459
459
|
import { join as join2 } from "node:path";
|
|
460
460
|
import { Readable } from "node:stream";
|
|
461
|
-
import { readdir, readFile as readFile3, writeFile as writeFile2, rename as
|
|
461
|
+
import { readdir as readdir2, readFile as readFile3, writeFile as writeFile2, rename as rename3, stat, unlink, mkdir as mkdir2 } from "node:fs/promises";
|
|
462
462
|
import { join as join3 } from "node:path";
|
|
463
463
|
import { randomUUID } from "node:crypto";
|
|
464
464
|
import { EventEmitter } from "node:events";
|
|
@@ -63991,7 +63991,7 @@ async function backupState(dataDir) {
|
|
|
63991
63991
|
try {
|
|
63992
63992
|
const data = await readFile2(src, "utf-8");
|
|
63993
63993
|
await writeSecureFile(tmp, data);
|
|
63994
|
-
await
|
|
63994
|
+
await rename2(tmp, bak);
|
|
63995
63995
|
} catch {
|
|
63996
63996
|
}
|
|
63997
63997
|
}
|
|
@@ -64126,19 +64126,30 @@ var init_transport2 = __esm2({
|
|
|
64126
64126
|
});
|
|
64127
64127
|
var openclaw_compat_exports = {};
|
|
64128
64128
|
__export2(openclaw_compat_exports, {
|
|
64129
|
+
AGENT_EVENT_CANDIDATES: () => AGENT_EVENT_CANDIDATES,
|
|
64130
|
+
HEARTBEAT_CANDIDATES: () => HEARTBEAT_CANDIDATES,
|
|
64131
|
+
TRANSCRIPT_CANDIDATES: () => TRANSCRIPT_CANDIDATES,
|
|
64132
|
+
_resetCompatCacheForTest: () => _resetCompatCacheForTest,
|
|
64129
64133
|
onAgentEvent: () => onAgentEvent,
|
|
64130
64134
|
onSessionTranscriptUpdate: () => onSessionTranscriptUpdate,
|
|
64131
|
-
requestHeartbeatNow: () => requestHeartbeatNow
|
|
64135
|
+
requestHeartbeatNow: () => requestHeartbeatNow,
|
|
64136
|
+
resolveSdkFn: () => resolveSdkFn
|
|
64132
64137
|
});
|
|
64133
|
-
async function
|
|
64134
|
-
|
|
64138
|
+
async function resolveSdkFn(candidates, importer = defaultImporter) {
|
|
64139
|
+
for (const { specifier, symbol: symbol22 } of candidates) {
|
|
64135
64140
|
try {
|
|
64136
|
-
const mod4 = await
|
|
64137
|
-
|
|
64141
|
+
const mod4 = await importer(specifier);
|
|
64142
|
+
const found = mod4?.[symbol22] ?? mod4?.default?.[symbol22];
|
|
64143
|
+
if (typeof found === "function") return found;
|
|
64138
64144
|
} catch {
|
|
64139
|
-
_heartbeatFn = false;
|
|
64140
64145
|
}
|
|
64141
64146
|
}
|
|
64147
|
+
return false;
|
|
64148
|
+
}
|
|
64149
|
+
async function requestHeartbeatNow(opts) {
|
|
64150
|
+
if (_heartbeatFn === null) {
|
|
64151
|
+
_heartbeatFn = await resolveSdkFn(HEARTBEAT_CANDIDATES);
|
|
64152
|
+
}
|
|
64142
64153
|
if (typeof _heartbeatFn === "function") {
|
|
64143
64154
|
try {
|
|
64144
64155
|
await _heartbeatFn(opts);
|
|
@@ -64151,12 +64162,7 @@ async function requestHeartbeatNow(opts) {
|
|
|
64151
64162
|
}
|
|
64152
64163
|
async function onAgentEvent(callback) {
|
|
64153
64164
|
if (_agentEventFn === null) {
|
|
64154
|
-
|
|
64155
|
-
const mod4 = await import("openclaw/dist/plugin-sdk/infra/agent-events.js");
|
|
64156
|
-
_agentEventFn = mod4.onAgentEvent ?? mod4.default?.onAgentEvent ?? false;
|
|
64157
|
-
} catch {
|
|
64158
|
-
_agentEventFn = false;
|
|
64159
|
-
}
|
|
64165
|
+
_agentEventFn = await resolveSdkFn(AGENT_EVENT_CANDIDATES);
|
|
64160
64166
|
}
|
|
64161
64167
|
if (typeof _agentEventFn === "function") {
|
|
64162
64168
|
try {
|
|
@@ -64171,12 +64177,7 @@ async function onAgentEvent(callback) {
|
|
|
64171
64177
|
}
|
|
64172
64178
|
async function onSessionTranscriptUpdate(callback) {
|
|
64173
64179
|
if (_transcriptFn === null) {
|
|
64174
|
-
|
|
64175
|
-
const mod4 = await import("openclaw/dist/plugin-sdk/sessions/transcript-events.js");
|
|
64176
|
-
_transcriptFn = mod4.onSessionTranscriptUpdate ?? mod4.default?.onSessionTranscriptUpdate ?? false;
|
|
64177
|
-
} catch {
|
|
64178
|
-
_transcriptFn = false;
|
|
64179
|
-
}
|
|
64180
|
+
_transcriptFn = await resolveSdkFn(TRANSCRIPT_CANDIDATES);
|
|
64180
64181
|
}
|
|
64181
64182
|
if (typeof _transcriptFn === "function") {
|
|
64182
64183
|
try {
|
|
@@ -64189,12 +64190,45 @@ async function onSessionTranscriptUpdate(callback) {
|
|
|
64189
64190
|
return () => {
|
|
64190
64191
|
};
|
|
64191
64192
|
}
|
|
64193
|
+
function _resetCompatCacheForTest() {
|
|
64194
|
+
_heartbeatFn = null;
|
|
64195
|
+
_agentEventFn = null;
|
|
64196
|
+
_transcriptFn = null;
|
|
64197
|
+
}
|
|
64198
|
+
var defaultImporter;
|
|
64199
|
+
var HEARTBEAT_CANDIDATES;
|
|
64200
|
+
var AGENT_EVENT_CANDIDATES;
|
|
64201
|
+
var TRANSCRIPT_CANDIDATES;
|
|
64192
64202
|
var _heartbeatFn;
|
|
64193
64203
|
var _agentEventFn;
|
|
64194
64204
|
var _transcriptFn;
|
|
64195
64205
|
var init_openclaw_compat = __esm2({
|
|
64196
64206
|
"src/openclaw-compat.ts"() {
|
|
64197
64207
|
"use strict";
|
|
64208
|
+
defaultImporter = (specifier) => import(
|
|
64209
|
+
/* @vite-ignore */
|
|
64210
|
+
specifier
|
|
64211
|
+
);
|
|
64212
|
+
HEARTBEAT_CANDIDATES = [
|
|
64213
|
+
// 2026.7.x — exported subpath, and the symbol lost its `Now` suffix.
|
|
64214
|
+
{ specifier: "openclaw/plugin-sdk/heartbeat-runtime", symbol: "requestHeartbeat" },
|
|
64215
|
+
// <=2026.6.x — deep dist path, original name.
|
|
64216
|
+
{ specifier: "openclaw/dist/plugin-sdk/infra/heartbeat-wake.js", symbol: "requestHeartbeatNow" }
|
|
64217
|
+
];
|
|
64218
|
+
AGENT_EVENT_CANDIDATES = [
|
|
64219
|
+
{ specifier: "openclaw/plugin-sdk/agent-harness", symbol: "onAgentEvent" },
|
|
64220
|
+
{ specifier: "openclaw/dist/plugin-sdk/infra/agent-events.js", symbol: "onAgentEvent" }
|
|
64221
|
+
];
|
|
64222
|
+
TRANSCRIPT_CANDIDATES = [
|
|
64223
|
+
{
|
|
64224
|
+
specifier: "openclaw/plugin-sdk/memory-core-host-engine-foundation",
|
|
64225
|
+
symbol: "onSessionTranscriptUpdate"
|
|
64226
|
+
},
|
|
64227
|
+
{
|
|
64228
|
+
specifier: "openclaw/dist/plugin-sdk/sessions/transcript-events.js",
|
|
64229
|
+
symbol: "onSessionTranscriptUpdate"
|
|
64230
|
+
}
|
|
64231
|
+
];
|
|
64198
64232
|
_heartbeatFn = null;
|
|
64199
64233
|
_agentEventFn = null;
|
|
64200
64234
|
_transcriptFn = null;
|
|
@@ -64509,7 +64543,7 @@ async function handleWorkspaceUpload(data, workspaceDir) {
|
|
|
64509
64543
|
const tempPath = join3(workspaceDir, `.tmp_${randomUUID()}_${data.filename}`);
|
|
64510
64544
|
try {
|
|
64511
64545
|
await writeFile2(tempPath, data.content, "utf-8");
|
|
64512
|
-
await
|
|
64546
|
+
await rename3(tempPath, targetPath);
|
|
64513
64547
|
} catch (err) {
|
|
64514
64548
|
try {
|
|
64515
64549
|
await unlink(tempPath);
|
|
@@ -64526,7 +64560,7 @@ async function handleWorkspaceUpload(data, workspaceDir) {
|
|
|
64526
64560
|
}
|
|
64527
64561
|
async function handleWorkspaceList(workspaceDir) {
|
|
64528
64562
|
try {
|
|
64529
|
-
const entries = await
|
|
64563
|
+
const entries = await readdir2(workspaceDir);
|
|
64530
64564
|
const files = [];
|
|
64531
64565
|
for (const entry of entries) {
|
|
64532
64566
|
if (!entry.endsWith(".md")) continue;
|
|
@@ -65687,7 +65721,7 @@ var init_channel = __esm2({
|
|
|
65687
65721
|
*/
|
|
65688
65722
|
sendActivitySpan(spanData) {
|
|
65689
65723
|
if (!this._ws || this._ws.readyState !== WebSocket2.OPEN) return;
|
|
65690
|
-
const pluginVersion = true ? "0.23.
|
|
65724
|
+
const pluginVersion = true ? "0.23.19" : "0.0.0-dev";
|
|
65691
65725
|
const agentName = this.config.agentName ?? "Agent";
|
|
65692
65726
|
const resource = {
|
|
65693
65727
|
"service.name": "agentvault-agent",
|
|
@@ -67552,7 +67586,7 @@ var init_channel = __esm2({
|
|
|
67552
67586
|
agentVersion: this.config.agentVersion ?? "0.0.0",
|
|
67553
67587
|
// __AV_VERSION__ is injected by esbuild from package.json at build time.
|
|
67554
67588
|
// Falls back to "0.0.0-dev" in non-bundled contexts (tests).
|
|
67555
|
-
pluginVersion: true ? "0.23.
|
|
67589
|
+
pluginVersion: true ? "0.23.19" : "0.0.0-dev"
|
|
67556
67590
|
});
|
|
67557
67591
|
this._telemetryReporter.startAutoFlush(3e4);
|
|
67558
67592
|
}
|
|
@@ -67875,7 +67909,7 @@ var init_channel = __esm2({
|
|
|
67875
67909
|
agentVersion: this.config.agentVersion ?? "0.0.0",
|
|
67876
67910
|
// __AV_VERSION__ is injected by esbuild from package.json at build time.
|
|
67877
67911
|
// Falls back to "0.0.0-dev" in non-bundled contexts (tests).
|
|
67878
|
-
pluginVersion: true ? "0.23.
|
|
67912
|
+
pluginVersion: true ? "0.23.19" : "0.0.0-dev"
|
|
67879
67913
|
});
|
|
67880
67914
|
this._telemetryReporter.startAutoFlush(3e4);
|
|
67881
67915
|
}
|
|
@@ -71697,6 +71731,11 @@ var init_tool_audit = __esm2({
|
|
|
71697
71731
|
"use strict";
|
|
71698
71732
|
}
|
|
71699
71733
|
});
|
|
71734
|
+
var init_harness_compat = __esm2({
|
|
71735
|
+
"src/harness-compat.ts"() {
|
|
71736
|
+
"use strict";
|
|
71737
|
+
}
|
|
71738
|
+
});
|
|
71700
71739
|
var isUsingManagedRoutes;
|
|
71701
71740
|
var init_openclaw_entry = __esm2({
|
|
71702
71741
|
"src/openclaw-entry.ts"() {
|
|
@@ -71707,6 +71746,7 @@ var init_openclaw_entry = __esm2({
|
|
|
71707
71746
|
init_openclaw_compat();
|
|
71708
71747
|
init_lifecycle();
|
|
71709
71748
|
init_tool_audit();
|
|
71749
|
+
init_harness_compat();
|
|
71710
71750
|
init_types();
|
|
71711
71751
|
isUsingManagedRoutes = false;
|
|
71712
71752
|
}
|
|
@@ -97758,7 +97798,7 @@ var init_index = __esm2({
|
|
|
97758
97798
|
init_skill_invoker();
|
|
97759
97799
|
await init_skill_telemetry();
|
|
97760
97800
|
await init_policy_enforcer();
|
|
97761
|
-
VERSION = true ? "0.23.
|
|
97801
|
+
VERSION = true ? "0.23.19" : "0.0.0-dev";
|
|
97762
97802
|
}
|
|
97763
97803
|
});
|
|
97764
97804
|
await init_index();
|
|
@@ -133398,6 +133438,16 @@ var WorkerQueue = class {
|
|
|
133398
133438
|
this.running = false;
|
|
133399
133439
|
}
|
|
133400
133440
|
}
|
|
133441
|
+
/**
|
|
133442
|
+
* What the worker had produced, when the session can report it. Read on BOTH the
|
|
133443
|
+
* clean and the failing path: on a clean turn `said: false` with a non-zero
|
|
133444
|
+
* `composedChars` is the "composed but could never ship it" signature (agent-
|
|
133445
|
+
* authored room traffic, where `replyExpected` is false), which is otherwise
|
|
133446
|
+
* indistinguishable from a turn that did nothing.
|
|
133447
|
+
*/
|
|
133448
|
+
snapshotOf(session) {
|
|
133449
|
+
return session?.snapshot?.();
|
|
133450
|
+
}
|
|
133401
133451
|
/** Best-effort trap emit. A broken sink must never break the queue. */
|
|
133402
133452
|
emitIncident(rec) {
|
|
133403
133453
|
try {
|
|
@@ -133429,10 +133479,23 @@ var WorkerQueue = class {
|
|
|
133429
133479
|
}, this.deps.timeoutMs);
|
|
133430
133480
|
});
|
|
133431
133481
|
await Promise.race([session.start(), timeout]);
|
|
133482
|
+
const okSnap = this.snapshotOf(session);
|
|
133483
|
+
this.emitIncident({
|
|
133484
|
+
at: new Date(startedAt).toISOString(),
|
|
133485
|
+
outcome: "ok",
|
|
133486
|
+
waitedMs,
|
|
133487
|
+
ranMs: Date.now() - startedAt,
|
|
133488
|
+
timeoutMs: this.deps.timeoutMs,
|
|
133489
|
+
queueDepthAtEnqueue: entry.queueDepthAtEnqueue,
|
|
133490
|
+
queueDepthAtStart,
|
|
133491
|
+
instructionChars: task.instruction.length,
|
|
133492
|
+
replyExpected: task.replyExpected,
|
|
133493
|
+
...okSnap ? { session: okSnap } : {}
|
|
133494
|
+
});
|
|
133432
133495
|
} catch (e7) {
|
|
133433
133496
|
const err = e7;
|
|
133434
133497
|
this.deps.log(`[worker-queue] task failed: ${err.message}`);
|
|
133435
|
-
const snap = session
|
|
133498
|
+
const snap = this.snapshotOf(session);
|
|
133436
133499
|
this.emitIncident({
|
|
133437
133500
|
at: new Date(startedAt).toISOString(),
|
|
133438
133501
|
outcome: timedOut ? "timeout" : "error",
|
|
@@ -133443,6 +133506,7 @@ var WorkerQueue = class {
|
|
|
133443
133506
|
queueDepthAtEnqueue: entry.queueDepthAtEnqueue,
|
|
133444
133507
|
queueDepthAtStart,
|
|
133445
133508
|
instructionChars: task.instruction.length,
|
|
133509
|
+
replyExpected: task.replyExpected,
|
|
133446
133510
|
...snap ? { session: snap } : {}
|
|
133447
133511
|
});
|
|
133448
133512
|
session?.abort();
|
|
@@ -133464,7 +133528,7 @@ function makeRouter(deps) {
|
|
|
133464
133528
|
const replySink = reply ?? (() => {
|
|
133465
133529
|
});
|
|
133466
133530
|
const isOwnerDm = opts?.autoReplyOnText === true && opts?.armed === void 0 && deps.workAllowed();
|
|
133467
|
-
const isArmedRoom = opts?.armed?.() === true && deps.workAllowed();
|
|
133531
|
+
const isArmedRoom = opts?.armed?.() === true && deps.workAllowed() && opts?.replyExpected !== false;
|
|
133468
133532
|
if (isOwnerDm) {
|
|
133469
133533
|
deps.queue.enqueue({
|
|
133470
133534
|
instruction: text,
|
|
@@ -134027,7 +134091,7 @@ async function main() {
|
|
|
134027
134091
|
"[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"
|
|
134028
134092
|
);
|
|
134029
134093
|
}
|
|
134030
|
-
console.error(`[bridge] version: ${true ? "0.7.
|
|
134094
|
+
console.error(`[bridge] version: ${true ? "0.7.7" : "dev"}`);
|
|
134031
134095
|
console.error(`[bridge] data dir: ${cfg.dataDir} (${cfg.dataDirSource})`);
|
|
134032
134096
|
console.error(`[bridge] workspace: ${cfg.workspaceDir} \xB7 permissions: ${cfg.permissionMode} \xB7 enclave dir fenced`);
|
|
134033
134097
|
if (cfg.armRoom) {
|
|
@@ -134110,7 +134174,7 @@ async function main() {
|
|
|
134110
134174
|
// incident is visible in bridge.error.log at the moment it happens.
|
|
134111
134175
|
onIncident: (rec) => {
|
|
134112
134176
|
console.error(
|
|
134113
|
-
`[worker-trap] ${rec.at} ${rec.outcome} after ${rec.ranMs}ms (waited ${rec.waitedMs}ms behind ${rec.queueDepthAtEnqueue}, ${rec.queueDepthAtStart} still queued)` + (rec.session ? ` composed=${rec.session.composedChars} result=${rec.session.sawResult} said=${rec.session.said}` : "")
|
|
134177
|
+
`[worker-trap] ${rec.at} ${rec.outcome} after ${rec.ranMs}ms (waited ${rec.waitedMs}ms behind ${rec.queueDepthAtEnqueue}, ${rec.queueDepthAtStart} still queued) replyExpected=${rec.replyExpected}` + (rec.session ? ` composed=${rec.session.composedChars} result=${rec.session.sawResult} said=${rec.session.said}` : "")
|
|
134114
134178
|
);
|
|
134115
134179
|
try {
|
|
134116
134180
|
const dir = join11(cfg.dataDir, "logs");
|
package/dist/worker-queue.d.ts
CHANGED
|
@@ -17,19 +17,27 @@ export type WorkerTask = {
|
|
|
17
17
|
armed?: () => boolean;
|
|
18
18
|
};
|
|
19
19
|
/**
|
|
20
|
-
* Forensic record of
|
|
20
|
+
* Forensic record of EVERY task the queue runs — clean or not.
|
|
21
21
|
*
|
|
22
22
|
* Exists because the 2026-07-24 "loopita went quiet for 5 minutes" incident was
|
|
23
23
|
* diagnosable only by coincidence: the drop-trap happened to capture that the
|
|
24
24
|
* reply landed 300.016s after the ack, and 300s is `WORKER_TIMEOUT_MS` exactly.
|
|
25
25
|
* Nothing in the bridge recorded WHY the worker hung, and the logs carry no
|
|
26
26
|
* timestamps at all, so the evidence was gone by the time we looked.
|
|
27
|
+
*
|
|
28
|
+
* 2026-08-06: widened from failures-only to every turn. Recording only failures
|
|
29
|
+
* made the SLOW case unmeasurable, and slow is the common case: loopita answered
|
|
30
|
+
* Ballroom2 in 21s when the room was quiet and 81s when a second agent was
|
|
31
|
+
* talking, and nothing said whether the extra 60s was `waitedMs` or `ranMs`.
|
|
32
|
+
* Those are different bugs with identical symptoms. A trap that only reports
|
|
33
|
+
* when it breaks cannot tell you it is the reason things are slow.
|
|
27
34
|
*/
|
|
28
35
|
export type WorkerIncident = {
|
|
29
36
|
/** ISO timestamp — the bridge's own logs are unstamped, so this is the anchor. */
|
|
30
37
|
at: string;
|
|
31
|
-
outcome: "timeout" | "error";
|
|
32
|
-
|
|
38
|
+
outcome: "ok" | "timeout" | "error";
|
|
39
|
+
/** Absent on a clean turn — its presence is what marks a real incident. */
|
|
40
|
+
error?: string;
|
|
33
41
|
/**
|
|
34
42
|
* enqueue -> start. THE load-bearing field: it separates "this task hung" from
|
|
35
43
|
* "this task was stuck behind one that hung". Both look identical to the owner
|
|
@@ -44,6 +52,15 @@ export type WorkerIncident = {
|
|
|
44
52
|
/** Depth still waiting when this task began — the blast radius of this hang. */
|
|
45
53
|
queueDepthAtStart: number;
|
|
46
54
|
instructionChars: number;
|
|
55
|
+
/**
|
|
56
|
+
* Whether a reply was expected of this turn — mirrors `WorkerTask.replyExpected`,
|
|
57
|
+
* i.e. `senderIsAgent === false` upstream. Without it a silent turn
|
|
58
|
+
* (composed=0, said=false) is unattributable: it could be agent-authored traffic
|
|
59
|
+
* that was never going to answer, or a turn that waited so long the previous one
|
|
60
|
+
* already answered. Ballroom2 on 2026-08-06 produced both readings and the record
|
|
61
|
+
* could not separate them.
|
|
62
|
+
*/
|
|
63
|
+
replyExpected?: boolean;
|
|
47
64
|
/** What the worker had produced when it died, when the session can report it. */
|
|
48
65
|
session?: {
|
|
49
66
|
composedChars: number;
|
|
@@ -91,6 +108,14 @@ export declare class WorkerQueue {
|
|
|
91
108
|
/** Resolves when the queue has processed everything enqueued so far. */
|
|
92
109
|
whenDrained(): Promise<void>;
|
|
93
110
|
private drain;
|
|
111
|
+
/**
|
|
112
|
+
* What the worker had produced, when the session can report it. Read on BOTH the
|
|
113
|
+
* clean and the failing path: on a clean turn `said: false` with a non-zero
|
|
114
|
+
* `composedChars` is the "composed but could never ship it" signature (agent-
|
|
115
|
+
* authored room traffic, where `replyExpected` is false), which is otherwise
|
|
116
|
+
* indistinguishable from a turn that did nothing.
|
|
117
|
+
*/
|
|
118
|
+
private snapshotOf;
|
|
94
119
|
/** Best-effort trap emit. A broken sink must never break the queue. */
|
|
95
120
|
private emitIncident;
|
|
96
121
|
private runOne;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentvault/claude-bridge",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.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",
|