@agentvault/claude-bridge 0.8.10 → 0.8.12
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 +49 -11
- package/dist/session.d.ts +5 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -52059,10 +52059,12 @@ async function applyProposals(state, proposals, committerLeafIndex, pskSearch, s
|
|
|
52059
52059
|
const [mutatedTree, addedLeafNodes] = await applyTreeMutations(state.ratchetTree, grouped, state.groupContext, sentByClient, state.clientConfig.authService, state.clientConfig.lifetimeConfig, cs.signature);
|
|
52060
52060
|
const [updatedPskSecret, pskIds] = await accumulatePskSecret(grouped.psk.map((p2) => p2.proposal.psk.preSharedKeyId), pskSearch, cs, zeroes);
|
|
52061
52061
|
const selfRemoved = mutatedTree[leafToNodeIndex(toLeafIndex(state.privatePath.leafIndex))] === void 0;
|
|
52062
|
-
const
|
|
52062
|
+
const pathRequiredByRfc = allProposals.length === 0 || allProposals.some(({ proposal }) => {
|
|
52063
52063
|
const t22 = proposal.proposalType;
|
|
52064
52064
|
return t22 !== "add" && t22 !== "psk" && t22 !== "reinit";
|
|
52065
52065
|
});
|
|
52066
|
+
const pathRequiredLegacy = allProposals.length === 0 || Object.values(grouped.update).length > 1 || Object.values(grouped.remove).length > 1;
|
|
52067
|
+
const needsUpdatePath = sentByClient ? pathRequiredByRfc : pathRequiredLegacy;
|
|
52066
52068
|
return {
|
|
52067
52069
|
tree: mutatedTree,
|
|
52068
52070
|
pskSecret: updatedPskSecret,
|
|
@@ -64610,11 +64612,11 @@ var init_mls_kp_pool = __esm2({
|
|
|
64610
64612
|
}
|
|
64611
64613
|
});
|
|
64612
64614
|
function ownIdentity() {
|
|
64613
|
-
const v22 = true ? "0.23.
|
|
64615
|
+
const v22 = true ? "0.23.39" : FALLBACK;
|
|
64614
64616
|
return `${PACKAGE}@${v22}`;
|
|
64615
64617
|
}
|
|
64616
64618
|
function buildSha() {
|
|
64617
|
-
const raw = true ? "
|
|
64619
|
+
const raw = true ? "9982fc8-dirty" : "";
|
|
64618
64620
|
const cleaned = (raw ?? "").trim();
|
|
64619
64621
|
return !cleaned || cleaned === "unknown" ? null : cleaned;
|
|
64620
64622
|
}
|
|
@@ -65717,6 +65719,27 @@ var init_channel = __esm2({
|
|
|
65717
65719
|
* this process (GH #366). Cleared on (re)join so the next first message
|
|
65718
65720
|
* re-fetches the authoritative roster. Prevents per-message refetch storms. */
|
|
65719
65721
|
_roomRosterRefreshed = /* @__PURE__ */ new Set();
|
|
65722
|
+
/**
|
|
65723
|
+
* #1181: the last attachment saved per room, so the NEXT room turn can name
|
|
65724
|
+
* it. wren saved an un-mentioned file (no reply, #1107), was asked "@wren can
|
|
65725
|
+
* you read this file?" 14 s later, and answered "I don't see a file
|
|
65726
|
+
* attached" — the note lived only in the prior history line. Hermes defers
|
|
65727
|
+
* un-mentioned attachments and fetches on the next addressed turn (#1162);
|
|
65728
|
+
* this is the plugin's equivalent surface. In-memory: a restart forgets it,
|
|
65729
|
+
* which is the right default for "this file".
|
|
65730
|
+
*/
|
|
65731
|
+
_recentRoomAttachments = /* @__PURE__ */ new Map();
|
|
65732
|
+
static RECENT_ROOM_ATTACHMENT_MS = 10 * 60 * 1e3;
|
|
65733
|
+
/** #1181: prefix a room turn that carries no attachment with the one saved in this room recently. */
|
|
65734
|
+
_withRecentRoomAttachmentNote(roomId, text) {
|
|
65735
|
+
const recent = this._recentRoomAttachments.get(roomId);
|
|
65736
|
+
if (!recent) return text;
|
|
65737
|
+
const ageMs = Date.now() - recent.at;
|
|
65738
|
+
if (ageMs > _SecureChannel.RECENT_ROOM_ATTACHMENT_MS) return text;
|
|
65739
|
+
return `[Most recent file in this room: ${recent.filePath} (${recent.name}, received ${Math.round(ageMs / 1e3)}s ago). If this message refers to "the file" or "this file", it means that one \u2014 use your Read tool on it.]
|
|
65740
|
+
|
|
65741
|
+
${text}`;
|
|
65742
|
+
}
|
|
65720
65743
|
/** In-flight roster-refresh promises (per room) — dedup concurrent refreshes. */
|
|
65721
65744
|
_roomRosterRefreshInFlight = /* @__PURE__ */ new Map();
|
|
65722
65745
|
/** Dedup buffer for A2A message IDs (prevents double-delivery via direct + Redis) */
|
|
@@ -66812,7 +66835,7 @@ var init_channel = __esm2({
|
|
|
66812
66835
|
*/
|
|
66813
66836
|
sendActivitySpan(spanData) {
|
|
66814
66837
|
if (!this._ws || this._ws.readyState !== WebSocket2.OPEN) return;
|
|
66815
|
-
const pluginVersion = true ? "0.23.
|
|
66838
|
+
const pluginVersion = true ? "0.23.39" : "0.0.0-dev";
|
|
66816
66839
|
const agentName = this.config.agentName ?? "Agent";
|
|
66817
66840
|
const resource = {
|
|
66818
66841
|
"service.name": "agentvault-agent",
|
|
@@ -68750,7 +68773,7 @@ var init_channel = __esm2({
|
|
|
68750
68773
|
agentVersion: this.config.agentVersion ?? "0.0.0",
|
|
68751
68774
|
// __AV_VERSION__ is injected by esbuild from package.json at build time.
|
|
68752
68775
|
// Falls back to "0.0.0-dev" in non-bundled contexts (tests).
|
|
68753
|
-
pluginVersion: true ? "0.23.
|
|
68776
|
+
pluginVersion: true ? "0.23.39" : "0.0.0-dev"
|
|
68754
68777
|
});
|
|
68755
68778
|
this._telemetryReporter.startAutoFlush(3e4);
|
|
68756
68779
|
}
|
|
@@ -69074,7 +69097,7 @@ var init_channel = __esm2({
|
|
|
69074
69097
|
agentVersion: this.config.agentVersion ?? "0.0.0",
|
|
69075
69098
|
// __AV_VERSION__ is injected by esbuild from package.json at build time.
|
|
69076
69099
|
// Falls back to "0.0.0-dev" in non-bundled contexts (tests).
|
|
69077
|
-
pluginVersion: true ? "0.23.
|
|
69100
|
+
pluginVersion: true ? "0.23.39" : "0.0.0-dev"
|
|
69078
69101
|
});
|
|
69079
69102
|
this._telemetryReporter.startAutoFlush(3e4);
|
|
69080
69103
|
}
|
|
@@ -69847,12 +69870,13 @@ ${messageText}`;
|
|
|
69847
69870
|
* Returns the text unchanged when there is no attachment or the fetch fails —
|
|
69848
69871
|
* but a failure is LOGGED and announced in the text, never silent.
|
|
69849
69872
|
*/
|
|
69850
|
-
async _augmentWithAttachment(attachmentInfo, baseText) {
|
|
69873
|
+
async _augmentWithAttachment(attachmentInfo, baseText, roomId) {
|
|
69851
69874
|
if (!attachmentInfo) return baseText;
|
|
69852
69875
|
try {
|
|
69853
69876
|
const { filePath, decrypted } = await this._downloadAndDecryptAttachment(attachmentInfo);
|
|
69854
69877
|
const mime = String(attachmentInfo.mime ?? "application/octet-stream");
|
|
69855
69878
|
const name = String(attachmentInfo.filename ?? "attachment");
|
|
69879
|
+
if (roomId) this._recentRoomAttachments.set(roomId, { filePath, name, at: Date.now() });
|
|
69856
69880
|
const textMimes = ["text/", "application/json", "application/xml", "application/csv"];
|
|
69857
69881
|
if (textMimes.some((m22) => mime.startsWith(m22))) {
|
|
69858
69882
|
const content = new TextDecoder().decode(decrypted);
|
|
@@ -70482,7 +70506,9 @@ ${baseText}`;
|
|
|
70482
70506
|
}
|
|
70483
70507
|
}
|
|
70484
70508
|
if (roomAttachment) {
|
|
70485
|
-
messageText = await this._augmentWithAttachment(roomAttachment, messageText);
|
|
70509
|
+
messageText = await this._augmentWithAttachment(roomAttachment, messageText, resolvedRoomId);
|
|
70510
|
+
} else {
|
|
70511
|
+
messageText = this._withRecentRoomAttachmentNote(resolvedRoomId, messageText);
|
|
70486
70512
|
}
|
|
70487
70513
|
const roomMembers = this._persisted?.rooms?.[resolvedRoomId]?.members ?? [];
|
|
70488
70514
|
const senderMember = roomMembers.find((m22) => m22.deviceId === senderDeviceId);
|
|
@@ -99524,7 +99550,7 @@ var init_index = __esm2({
|
|
|
99524
99550
|
await init_skill_telemetry();
|
|
99525
99551
|
await init_policy_enforcer();
|
|
99526
99552
|
init_room_protocol();
|
|
99527
|
-
VERSION = true ? "0.23.
|
|
99553
|
+
VERSION = true ? "0.23.39" : "0.0.0-dev";
|
|
99528
99554
|
}
|
|
99529
99555
|
});
|
|
99530
99556
|
await init_index();
|
|
@@ -134886,6 +134912,11 @@ var PersistentClaudeSession = class {
|
|
|
134886
134912
|
* which also prevents agent↔agent reply loops. Tool access is unaffected: it
|
|
134887
134913
|
* stays gated on currentAutoReply (owner DM) OR currentArmedGetter (armed room). */
|
|
134888
134914
|
currentReplyExpected = false;
|
|
134915
|
+
/** #1180: whether the say tool may deliver on this turn. Rooms pass an explicit
|
|
134916
|
+
* `replyExpected` (#1107: no @ → nobody replies) and that decides it; a 1:1 DM
|
|
134917
|
+
* passes none and say stays allowed there. Distinct from `currentReplyExpected`,
|
|
134918
|
+
* which drives only the #416 prose fallback and is false for un-attested DMs. */
|
|
134919
|
+
currentSayAllowed = true;
|
|
134889
134920
|
saidThisTurn = false;
|
|
134890
134921
|
turnText = "";
|
|
134891
134922
|
/** #630 drop-probe: did a `result` event arrive for the CURRENT turn? Reset per
|
|
@@ -134958,6 +134989,12 @@ var PersistentClaudeSession = class {
|
|
|
134958
134989
|
* back to opts.onSay. This is what closes the DM→room leak: the destination is
|
|
134959
134990
|
* the one captured for the message being answered, not a live global target. */
|
|
134960
134991
|
async deliver(text) {
|
|
134992
|
+
if (!this.currentSayAllowed) {
|
|
134993
|
+
logLine(
|
|
134994
|
+
`[session] say during a turn this agent does not owe (no @mention) \u2014 SUPPRESSED: ${JSON.stringify(text.slice(0, 80))}`
|
|
134995
|
+
);
|
|
134996
|
+
return;
|
|
134997
|
+
}
|
|
134961
134998
|
this.saidThisTurn = true;
|
|
134962
134999
|
if (this.activeReply) await this.activeReply(text);
|
|
134963
135000
|
else if (this.opts.onSay) await this.opts.onSay(text);
|
|
@@ -134999,6 +135036,7 @@ var PersistentClaudeSession = class {
|
|
|
134999
135036
|
this.activeReply = item.reply;
|
|
135000
135037
|
this.currentAutoReply = item.autoReplyOnText ?? false;
|
|
135001
135038
|
this.currentReplyExpected = item.replyExpected ?? item.autoReplyOnText ?? false;
|
|
135039
|
+
this.currentSayAllowed = item.replyExpected ?? true;
|
|
135002
135040
|
this.currentArmedGetter = item.armed ?? (() => false);
|
|
135003
135041
|
this.saidThisTurn = false;
|
|
135004
135042
|
this.turnText = "";
|
|
@@ -135928,7 +135966,7 @@ async function main() {
|
|
|
135928
135966
|
"[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"
|
|
135929
135967
|
);
|
|
135930
135968
|
}
|
|
135931
|
-
logLine(`[bridge] version: ${true ? "0.8.
|
|
135969
|
+
logLine(`[bridge] version: ${true ? "0.8.12" : "dev"}`);
|
|
135932
135970
|
logLine(`[bridge] data dir: ${cfg.dataDir} (${cfg.dataDirSource})`);
|
|
135933
135971
|
logLine(`[bridge] workspace: ${cfg.workspaceDir} \xB7 permissions: ${cfg.permissionMode} \xB7 enclave dir fenced`);
|
|
135934
135972
|
if (cfg.armRoom) {
|
|
@@ -135960,7 +135998,7 @@ async function main() {
|
|
|
135960
135998
|
// its default would render "@agentvault/agentvault@0.7.x" — the wrong
|
|
135961
135999
|
// package name attached to the bridge's version number, which is worse
|
|
135962
136000
|
// than either alone.
|
|
135963
|
-
clientVersion: `@agentvault/claude-bridge@${true ? "0.8.
|
|
136001
|
+
clientVersion: `@agentvault/claude-bridge@${true ? "0.8.12" : "dev"}`
|
|
135964
136002
|
});
|
|
135965
136003
|
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.`;
|
|
135966
136004
|
const deviceJwt = () => {
|
package/dist/session.d.ts
CHANGED
|
@@ -135,6 +135,11 @@ export declare class PersistentClaudeSession {
|
|
|
135
135
|
* which also prevents agent↔agent reply loops. Tool access is unaffected: it
|
|
136
136
|
* stays gated on currentAutoReply (owner DM) OR currentArmedGetter (armed room). */
|
|
137
137
|
private currentReplyExpected;
|
|
138
|
+
/** #1180: whether the say tool may deliver on this turn. Rooms pass an explicit
|
|
139
|
+
* `replyExpected` (#1107: no @ → nobody replies) and that decides it; a 1:1 DM
|
|
140
|
+
* passes none and say stays allowed there. Distinct from `currentReplyExpected`,
|
|
141
|
+
* which drives only the #416 prose fallback and is false for un-attested DMs. */
|
|
142
|
+
private currentSayAllowed;
|
|
138
143
|
private saidThisTurn;
|
|
139
144
|
private turnText;
|
|
140
145
|
/** #630 drop-probe: did a `result` event arrive for the CURRENT turn? Reset per
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentvault/claude-bridge",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.12",
|
|
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",
|