@agentvault/claude-bridge 0.7.0 → 0.7.1
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/host-trust.d.ts +23 -1
- package/dist/index.js +32 -13
- package/package.json +1 -1
package/dist/host-trust.d.ts
CHANGED
|
@@ -19,8 +19,30 @@ export declare function trustDir(root?: string): string;
|
|
|
19
19
|
*/
|
|
20
20
|
export declare function isTrusted(deviceId: string, root?: string): boolean;
|
|
21
21
|
export declare function grant(deviceId: string, root?: string): void;
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Returns true only if a real marker was actually removed.
|
|
24
|
+
*
|
|
25
|
+
* M1. This used `existsSync` + `rmSync(p, { force: true, recursive: true })`.
|
|
26
|
+
* `existsSync` is true for a DIRECTORY, so a directory squatting at a marker
|
|
27
|
+
* path was recursively deleted — contents and all — and reported as a
|
|
28
|
+
* successful revoke. Reached in practice through `untrust-host --all`
|
|
29
|
+
* (approve-cli.ts:131), which revokes everything `listTrusted()` returns.
|
|
30
|
+
*
|
|
31
|
+
* Only a regular file is a marker, which is already `isTrusted`'s rule; `lstat`
|
|
32
|
+
* so a symlink is never followed or counted. Anything else was never a grant,
|
|
33
|
+
* so removing it is not this function's job — and refusing keeps `recursive`
|
|
34
|
+
* out of this file entirely.
|
|
35
|
+
*
|
|
36
|
+
* The invariant callers actually depend on is preserved: after `revoke()`,
|
|
37
|
+
* `isTrusted()` is false, because it rejects non-files too.
|
|
38
|
+
*/
|
|
23
39
|
export declare function revoke(deviceId: string, root?: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Filtered through `isTrusted` rather than the filename alone, so the listing
|
|
42
|
+
* cannot disagree with the decision. A name-only filter reported directories
|
|
43
|
+
* and symlinks as trusted devices, which both over-stated trust to an operator
|
|
44
|
+
* reading the list and fed non-markers to `revoke()` in the `--all` path.
|
|
45
|
+
*/
|
|
24
46
|
export declare function listTrusted(root?: string): string[];
|
|
25
47
|
/**
|
|
26
48
|
* Resolve this agent's device-id from its persisted identity. `trust-host` runs
|
package/dist/index.js
CHANGED
|
@@ -349,7 +349,7 @@ var init_systemd = __esm({
|
|
|
349
349
|
|
|
350
350
|
// src/service/backend.ts
|
|
351
351
|
import { spawnSync } from "node:child_process";
|
|
352
|
-
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync3, rmSync as rmSync4, existsSync as
|
|
352
|
+
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync3, rmSync as rmSync4, existsSync as existsSync4, chmodSync as chmodSync3 } from "node:fs";
|
|
353
353
|
import { userInfo } from "node:os";
|
|
354
354
|
function defaultDeps() {
|
|
355
355
|
return {
|
|
@@ -362,9 +362,9 @@ function defaultDeps() {
|
|
|
362
362
|
},
|
|
363
363
|
writeFile: (p2, d10) => writeFileSync3(p2, d10),
|
|
364
364
|
mkdir: (p2) => mkdirSync5(p2, { recursive: true }),
|
|
365
|
-
chmod: (p2, m6) =>
|
|
365
|
+
chmod: (p2, m6) => chmodSync3(p2, m6),
|
|
366
366
|
rm: (p2) => rmSync4(p2, { force: true }),
|
|
367
|
-
exists: (p2) =>
|
|
367
|
+
exists: (p2) => existsSync4(p2)
|
|
368
368
|
};
|
|
369
369
|
}
|
|
370
370
|
function selectBackend(platform, deps) {
|
|
@@ -118702,10 +118702,12 @@ import { realpathSync as realpathSync2 } from "node:fs";
|
|
|
118702
118702
|
import { resolve as resolve3, dirname as dirname2, basename, sep as sep2, isAbsolute } from "node:path";
|
|
118703
118703
|
|
|
118704
118704
|
// src/host-trust.ts
|
|
118705
|
-
import { mkdirSync as mkdirSync3, writeFileSync, rmSync as rmSync2,
|
|
118705
|
+
import { mkdirSync as mkdirSync3, writeFileSync, rmSync as rmSync2, readdirSync as readdirSync2, lstatSync as lstatSync2, readFileSync as readFileSync4, chmodSync as chmodSync2 } from "node:fs";
|
|
118706
118706
|
import { join as join6 } from "node:path";
|
|
118707
118707
|
import { homedir, hostname as hostname3 } from "node:os";
|
|
118708
118708
|
var TRUST_SUBDIR = "host-trust";
|
|
118709
|
+
var DIR_MODE3 = 448;
|
|
118710
|
+
var FILE_MODE3 = 384;
|
|
118709
118711
|
var ID_RE = /^[A-Za-z0-9_-]{1,128}$/;
|
|
118710
118712
|
var IDENTITY_FILES = ["agentvault.json", "secure-channel.json", "agentvault.json.bak"];
|
|
118711
118713
|
var HostTrustError = class extends Error {
|
|
@@ -118731,23 +118733,33 @@ function isTrusted(deviceId, root3) {
|
|
|
118731
118733
|
function grant(deviceId, root3) {
|
|
118732
118734
|
const id = sanitize(deviceId);
|
|
118733
118735
|
const dir = trustDir(root3);
|
|
118734
|
-
|
|
118736
|
+
const p2 = join6(dir, id);
|
|
118737
|
+
mkdirSync3(dir, { recursive: true, mode: DIR_MODE3 });
|
|
118735
118738
|
writeFileSync(
|
|
118736
|
-
|
|
118739
|
+
p2,
|
|
118737
118740
|
`granted_at=${(/* @__PURE__ */ new Date()).toISOString()} host=${hostname3()}
|
|
118738
|
-
|
|
118741
|
+
`,
|
|
118742
|
+
{ mode: FILE_MODE3 }
|
|
118739
118743
|
);
|
|
118744
|
+
chmodSync2(dir, DIR_MODE3);
|
|
118745
|
+
chmodSync2(p2, FILE_MODE3);
|
|
118740
118746
|
}
|
|
118741
118747
|
function revoke(deviceId, root3) {
|
|
118742
118748
|
const id = sanitize(deviceId);
|
|
118743
118749
|
const p2 = join6(trustDir(root3), id);
|
|
118744
|
-
|
|
118745
|
-
|
|
118750
|
+
try {
|
|
118751
|
+
if (!lstatSync2(p2).isFile()) return false;
|
|
118752
|
+
} catch {
|
|
118753
|
+
return false;
|
|
118754
|
+
}
|
|
118755
|
+
rmSync2(p2, { force: true });
|
|
118746
118756
|
return true;
|
|
118747
118757
|
}
|
|
118748
118758
|
function listTrusted(root3) {
|
|
118749
118759
|
try {
|
|
118750
|
-
return readdirSync2(trustDir(root3)).filter(
|
|
118760
|
+
return readdirSync2(trustDir(root3)).filter(
|
|
118761
|
+
(n10) => ID_RE.test(n10) && isTrusted(n10, root3)
|
|
118762
|
+
);
|
|
118751
118763
|
} catch {
|
|
118752
118764
|
return [];
|
|
118753
118765
|
}
|
|
@@ -133227,7 +133239,7 @@ var ArmingState = class {
|
|
|
133227
133239
|
};
|
|
133228
133240
|
|
|
133229
133241
|
// src/approve-cli.ts
|
|
133230
|
-
import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync2, readFileSync as readFileSync5, readdirSync as readdirSync3, rmSync as rmSync3, existsSync as
|
|
133242
|
+
import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync2, readFileSync as readFileSync5, readdirSync as readdirSync3, rmSync as rmSync3, existsSync as existsSync3 } from "node:fs";
|
|
133231
133243
|
import { join as join7 } from "node:path";
|
|
133232
133244
|
var APPROVALS_SUBDIR = "arm-approvals";
|
|
133233
133245
|
var ID_RE2 = /^[A-Za-z0-9_-]{1,128}$/;
|
|
@@ -133254,7 +133266,7 @@ function writeApproval(dataDir, requestId, roomId) {
|
|
|
133254
133266
|
}
|
|
133255
133267
|
function drainApprovals(dataDir) {
|
|
133256
133268
|
const dir = join7(dataDir, APPROVALS_SUBDIR);
|
|
133257
|
-
if (!
|
|
133269
|
+
if (!existsSync3(dir)) return [];
|
|
133258
133270
|
const out = [];
|
|
133259
133271
|
for (const name of readdirSync3(dir)) {
|
|
133260
133272
|
if (!ID_RE2.test(name)) continue;
|
|
@@ -133473,7 +133485,14 @@ function wireBridge(channel, session, target, opts = {}) {
|
|
|
133473
133485
|
e7.hushedUntil ? `room ${e7.roomId.slice(0, 8)} hushed until ${e7.hushedUntil} \u2014 holding` : `room ${e7.roomId.slice(0, 8)} hush cleared`
|
|
133474
133486
|
);
|
|
133475
133487
|
});
|
|
133488
|
+
let warnedMissingSenderIsAgent = false;
|
|
133476
133489
|
channel.on("room_message", (e7) => {
|
|
133490
|
+
if (typeof e7.senderIsAgent !== "boolean" && !warnedMissingSenderIsAgent) {
|
|
133491
|
+
warnedMissingSenderIsAgent = true;
|
|
133492
|
+
log(
|
|
133493
|
+
"WARNING: inbound room_message has no `senderIsAgent` \u2014 replies to humans in rooms will be DROPPED whenever the model answers in plain text instead of calling say (#630). Most likely cause: a stale bundled plugin dist. Rebuild the bridge (npm run build in packages/claude-room-bridge) and reinstall."
|
|
133494
|
+
);
|
|
133495
|
+
}
|
|
133477
133496
|
if (opts.roomFilter && e7.roomId !== opts.roomFilter) return;
|
|
133478
133497
|
if (hush.isHushed(e7.roomId)) {
|
|
133479
133498
|
log(`inbound from ${e7.senderName} in ${e7.roomId.slice(0, 8)} \u2014 room hushed, holding (not replying)`);
|
|
@@ -133632,7 +133651,7 @@ async function main() {
|
|
|
133632
133651
|
"[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"
|
|
133633
133652
|
);
|
|
133634
133653
|
}
|
|
133635
|
-
console.error(`[bridge] version: ${true ? "0.7.
|
|
133654
|
+
console.error(`[bridge] version: ${true ? "0.7.1" : "dev"}`);
|
|
133636
133655
|
console.error(`[bridge] data dir: ${cfg.dataDir} (${cfg.dataDirSource})`);
|
|
133637
133656
|
console.error(`[bridge] workspace: ${cfg.workspaceDir} \xB7 permissions: ${cfg.permissionMode} \xB7 enclave dir fenced`);
|
|
133638
133657
|
if (cfg.armRoom) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentvault/claude-bridge",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
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",
|