@agentvault/claude-bridge 0.5.4 → 0.5.5
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 +71 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -65502,7 +65502,7 @@ var init_channel = __esm2({
|
|
|
65502
65502
|
*/
|
|
65503
65503
|
sendActivitySpan(spanData) {
|
|
65504
65504
|
if (!this._ws || this._ws.readyState !== WebSocket2.OPEN) return;
|
|
65505
|
-
const pluginVersion = true ? "0.23.
|
|
65505
|
+
const pluginVersion = true ? "0.23.2" : "0.0.0-dev";
|
|
65506
65506
|
const agentName = this.config.agentName ?? "Agent";
|
|
65507
65507
|
const resource = {
|
|
65508
65508
|
"service.name": "agentvault-agent",
|
|
@@ -67119,7 +67119,7 @@ var init_channel = __esm2({
|
|
|
67119
67119
|
agentVersion: this.config.agentVersion ?? "0.0.0",
|
|
67120
67120
|
// __AV_VERSION__ is injected by esbuild from package.json at build time.
|
|
67121
67121
|
// Falls back to "0.0.0-dev" in non-bundled contexts (tests).
|
|
67122
|
-
pluginVersion: true ? "0.23.
|
|
67122
|
+
pluginVersion: true ? "0.23.2" : "0.0.0-dev"
|
|
67123
67123
|
});
|
|
67124
67124
|
this._telemetryReporter.startAutoFlush(3e4);
|
|
67125
67125
|
}
|
|
@@ -67195,7 +67195,7 @@ var init_channel = __esm2({
|
|
|
67195
67195
|
return;
|
|
67196
67196
|
}
|
|
67197
67197
|
if (data.event === "device_revoked") {
|
|
67198
|
-
this._handleDeviceRevoked();
|
|
67198
|
+
await this._handleDeviceRevoked();
|
|
67199
67199
|
return;
|
|
67200
67200
|
}
|
|
67201
67201
|
if (data.event === "device_linked") {
|
|
@@ -67429,7 +67429,7 @@ var init_channel = __esm2({
|
|
|
67429
67429
|
agentVersion: this.config.agentVersion ?? "0.0.0",
|
|
67430
67430
|
// __AV_VERSION__ is injected by esbuild from package.json at build time.
|
|
67431
67431
|
// Falls back to "0.0.0-dev" in non-bundled contexts (tests).
|
|
67432
|
-
pluginVersion: true ? "0.23.
|
|
67432
|
+
pluginVersion: true ? "0.23.2" : "0.0.0-dev"
|
|
67433
67433
|
});
|
|
67434
67434
|
this._telemetryReporter.startAutoFlush(3e4);
|
|
67435
67435
|
}
|
|
@@ -70594,22 +70594,74 @@ ${messageText}`;
|
|
|
70594
70594
|
this._setState("error");
|
|
70595
70595
|
this.emit("error", err);
|
|
70596
70596
|
}
|
|
70597
|
+
// Phase 2 — rolling-window timestamps of device_revoked self-heal reconnects,
|
|
70598
|
+
// used as a war cap so a takeover war or a server status/WS inconsistency can't
|
|
70599
|
+
// thrash forever.
|
|
70600
|
+
_revokeRecoveries = [];
|
|
70601
|
+
static REVOKE_RECOVERY_MAX = 3;
|
|
70602
|
+
static REVOKE_RECOVERY_WINDOW_MS = 12e4;
|
|
70597
70603
|
/**
|
|
70598
|
-
* Handle a WS `device_revoked` event.
|
|
70599
|
-
* attachLifecycle stops the channel — but does NOT delete credentials.
|
|
70604
|
+
* Handle a WS `device_revoked` event.
|
|
70600
70605
|
*
|
|
70601
|
-
*
|
|
70602
|
-
* session-takeover of a device that is still ACTIVE
|
|
70603
|
-
* text even reads "or another session has taken over"
|
|
70604
|
-
*
|
|
70605
|
-
*
|
|
70606
|
-
*
|
|
70607
|
-
*
|
|
70608
|
-
*
|
|
70609
|
-
*
|
|
70610
|
-
*
|
|
70606
|
+
* The signal is ambiguous: the server sends it both for a genuine owner revoke
|
|
70607
|
+
* AND for a transient/racy session-takeover of a device that is still ACTIVE
|
|
70608
|
+
* (the error text even reads "or another session has taken over" — loopita's
|
|
70609
|
+
* case, where the device stayed ACTIVE on the server). So we do NOT terminate
|
|
70610
|
+
* blindly. We ask the PUBLIC /devices/{id}/status endpoint (no JWT needed, so
|
|
70611
|
+
* it answers even when our device JWT is being rejected):
|
|
70612
|
+
* - ACTIVE -> reconnect in place (transient); stay online.
|
|
70613
|
+
* - non-ACTIVE -> terminal (genuinely revoked; operator must re-enroll).
|
|
70614
|
+
* - unreachable/429 -> reconnect (inconclusive; a network blip shouldn't
|
|
70615
|
+
* permanently kill a healthy agent — the WS is down too,
|
|
70616
|
+
* so normal backoff handles it, and the war cap bounds
|
|
70617
|
+
* thrash if the device really is dead).
|
|
70618
|
+
*
|
|
70619
|
+
* A rolling-window cap (REVOKE_RECOVERY_MAX self-heals per WINDOW_MS) gives up
|
|
70620
|
+
* (terminal) on a repeating loop. Never clears credentials in any branch —
|
|
70621
|
+
* re-enrollment, which SHOULD wipe creds, goes through setup --force /
|
|
70622
|
+
* _forceReEnroll in start().
|
|
70611
70623
|
*/
|
|
70612
|
-
_handleDeviceRevoked() {
|
|
70624
|
+
async _handleDeviceRevoked() {
|
|
70625
|
+
const now = Date.now();
|
|
70626
|
+
this._revokeRecoveries = this._revokeRecoveries.filter(
|
|
70627
|
+
(t22) => now - t22 < _SecureChannel.REVOKE_RECOVERY_WINDOW_MS
|
|
70628
|
+
);
|
|
70629
|
+
if (this._revokeRecoveries.length >= _SecureChannel.REVOKE_RECOVERY_MAX) {
|
|
70630
|
+
console.warn(
|
|
70631
|
+
"[SecureChannel] device_revoked self-healed too many times in a short window \u2014 giving up (terminal)"
|
|
70632
|
+
);
|
|
70633
|
+
this._handleError(new Error("Device was revoked"));
|
|
70634
|
+
return;
|
|
70635
|
+
}
|
|
70636
|
+
const deviceId = this._deviceId ?? this._persisted?.deviceId;
|
|
70637
|
+
if (!deviceId) {
|
|
70638
|
+
this._handleError(new Error("Device was revoked"));
|
|
70639
|
+
return;
|
|
70640
|
+
}
|
|
70641
|
+
let reconnect;
|
|
70642
|
+
try {
|
|
70643
|
+
const status = await pollDeviceStatus(this.config.apiUrl, deviceId);
|
|
70644
|
+
reconnect = status.rateLimited === true || status.status === "ACTIVE";
|
|
70645
|
+
if (!reconnect) {
|
|
70646
|
+
console.warn(
|
|
70647
|
+
`[SecureChannel] device_revoked confirmed by server (status=${status.status}) \u2014 terminal`
|
|
70648
|
+
);
|
|
70649
|
+
}
|
|
70650
|
+
} catch (err) {
|
|
70651
|
+
console.warn(
|
|
70652
|
+
"[SecureChannel] device_revoked status check failed; reconnecting (inconclusive):",
|
|
70653
|
+
err
|
|
70654
|
+
);
|
|
70655
|
+
reconnect = true;
|
|
70656
|
+
}
|
|
70657
|
+
if (reconnect) {
|
|
70658
|
+
this._revokeRecoveries.push(now);
|
|
70659
|
+
console.log(
|
|
70660
|
+
"[SecureChannel] device_revoked but device not confirmed dead \u2014 reconnecting (self-heal)"
|
|
70661
|
+
);
|
|
70662
|
+
this._scheduleReconnect();
|
|
70663
|
+
return;
|
|
70664
|
+
}
|
|
70613
70665
|
this._handleError(new Error("Device was revoked"));
|
|
70614
70666
|
}
|
|
70615
70667
|
/**
|
|
@@ -97124,7 +97176,7 @@ var init_index = __esm2({
|
|
|
97124
97176
|
init_skill_invoker();
|
|
97125
97177
|
await init_skill_telemetry();
|
|
97126
97178
|
await init_policy_enforcer();
|
|
97127
|
-
VERSION = true ? "0.23.
|
|
97179
|
+
VERSION = true ? "0.23.2" : "0.0.0-dev";
|
|
97128
97180
|
}
|
|
97129
97181
|
});
|
|
97130
97182
|
await init_index();
|
|
@@ -132866,7 +132918,7 @@ async function main() {
|
|
|
132866
132918
|
"[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"
|
|
132867
132919
|
);
|
|
132868
132920
|
}
|
|
132869
|
-
console.error(`[bridge] version: ${true ? "0.5.
|
|
132921
|
+
console.error(`[bridge] version: ${true ? "0.5.5" : "dev"}`);
|
|
132870
132922
|
console.error(`[bridge] data dir: ${cfg.dataDir} (${cfg.dataDirSource})`);
|
|
132871
132923
|
if (cfg.worker) {
|
|
132872
132924
|
console.error(`[bridge] WORKER MODE \u2014 workspace: ${cfg.workspaceDir} \xB7 permissions: ${cfg.permissionMode} \xB7 enclave dir fenced`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentvault/claude-bridge",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.5",
|
|
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",
|