@agentvault/claude-bridge 0.3.3 → 0.3.4
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/config.d.ts +3 -0
- package/dist/index.js +168 -38
- package/dist/session.d.ts +28 -1
- package/dist/worker-permission.d.ts +22 -0
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
|
@@ -8,6 +8,9 @@ export interface BridgeConfig {
|
|
|
8
8
|
roomFilter?: string;
|
|
9
9
|
model?: string;
|
|
10
10
|
systemPrompt?: string;
|
|
11
|
+
worker: boolean;
|
|
12
|
+
workspaceDir?: string;
|
|
13
|
+
permissionMode: "auto" | "acceptEdits" | "bypassPermissions";
|
|
11
14
|
}
|
|
12
15
|
export declare function loadConfig(env: NodeJS.ProcessEnv, argv?: string[]): BridgeConfig;
|
|
13
16
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -45248,20 +45248,20 @@ function multibaseToPublicKey(multibase) {
|
|
|
45248
45248
|
}
|
|
45249
45249
|
async function signDocument(document, privateKey) {
|
|
45250
45250
|
await libsodium_wrappers_default.ready;
|
|
45251
|
-
const
|
|
45251
|
+
const canonical2 = canonicalize(document);
|
|
45252
45252
|
const domainPrefix = libsodium_wrappers_default.from_string(DOMAIN_DID_DOCUMENT);
|
|
45253
|
-
const message = new Uint8Array(domainPrefix.length +
|
|
45253
|
+
const message = new Uint8Array(domainPrefix.length + canonical2.length);
|
|
45254
45254
|
message.set(domainPrefix);
|
|
45255
|
-
message.set(
|
|
45255
|
+
message.set(canonical2, domainPrefix.length);
|
|
45256
45256
|
return libsodium_wrappers_default.crypto_sign_detached(message, privateKey);
|
|
45257
45257
|
}
|
|
45258
45258
|
async function verifyDocumentSignature(document, signature, publicKey) {
|
|
45259
45259
|
await libsodium_wrappers_default.ready;
|
|
45260
|
-
const
|
|
45260
|
+
const canonical2 = canonicalize(document);
|
|
45261
45261
|
const domainPrefix = libsodium_wrappers_default.from_string(DOMAIN_DID_DOCUMENT);
|
|
45262
|
-
const message = new Uint8Array(domainPrefix.length +
|
|
45262
|
+
const message = new Uint8Array(domainPrefix.length + canonical2.length);
|
|
45263
45263
|
message.set(domainPrefix);
|
|
45264
|
-
message.set(
|
|
45264
|
+
message.set(canonical2, domainPrefix.length);
|
|
45265
45265
|
try {
|
|
45266
45266
|
return libsodium_wrappers_default.crypto_sign_verify_detached(signature, message, publicKey);
|
|
45267
45267
|
} catch {
|
|
@@ -96449,6 +96449,20 @@ function resolveDataDir(env) {
|
|
|
96449
96449
|
function loadConfig(env, argv = []) {
|
|
96450
96450
|
const { dataDir, source: dataDirSource } = resolveDataDir(env);
|
|
96451
96451
|
const inviteToken = (argv[0] && !argv[0].startsWith("-") ? argv[0] : "") || env.AV_INVITE_TOKEN || "";
|
|
96452
|
+
const worker = env.AV_WORKER === "1" || env.AV_WORKER === "true";
|
|
96453
|
+
const workspaceDir = env.AV_WORKSPACE_DIR || void 0;
|
|
96454
|
+
const PERMISSION_MODES = ["auto", "acceptEdits", "bypassPermissions"];
|
|
96455
|
+
const permissionMode = env.AV_PERMISSION_MODE ?? "auto";
|
|
96456
|
+
if (!PERMISSION_MODES.includes(permissionMode)) {
|
|
96457
|
+
throw new Error(
|
|
96458
|
+
`invalid AV_PERMISSION_MODE: ${env.AV_PERMISSION_MODE} (expected one of ${PERMISSION_MODES.join(", ")})`
|
|
96459
|
+
);
|
|
96460
|
+
}
|
|
96461
|
+
if (worker && !workspaceDir) {
|
|
96462
|
+
throw new Error(
|
|
96463
|
+
"worker mode requires AV_WORKSPACE_DIR (the project directory the agent works in)"
|
|
96464
|
+
);
|
|
96465
|
+
}
|
|
96452
96466
|
if (!inviteToken && !hasPersistedCreds(dataDir)) {
|
|
96453
96467
|
throw new Error(
|
|
96454
96468
|
"invite token required: pass it as the first argument or set AV_INVITE_TOKEN (or start from a data dir with existing credentials to reconnect)"
|
|
@@ -96465,7 +96479,10 @@ function loadConfig(env, argv = []) {
|
|
|
96465
96479
|
agentName: env.AV_AGENT_NAME ?? "Claude",
|
|
96466
96480
|
roomFilter: env.AV_ROOM_ID || void 0,
|
|
96467
96481
|
model: env.AV_CLAUDE_MODEL || void 0,
|
|
96468
|
-
systemPrompt: env.AV_SYSTEM_PROMPT || void 0
|
|
96482
|
+
systemPrompt: env.AV_SYSTEM_PROMPT || void 0,
|
|
96483
|
+
worker,
|
|
96484
|
+
workspaceDir,
|
|
96485
|
+
permissionMode
|
|
96469
96486
|
};
|
|
96470
96487
|
}
|
|
96471
96488
|
|
|
@@ -117763,6 +117780,81 @@ function Z_($10, Q4) {
|
|
|
117763
117780
|
return null;
|
|
117764
117781
|
}
|
|
117765
117782
|
|
|
117783
|
+
// src/worker-permission.ts
|
|
117784
|
+
import { realpathSync as realpathSync2 } from "node:fs";
|
|
117785
|
+
import { resolve as resolve2, dirname, basename, sep } from "node:path";
|
|
117786
|
+
var PATH_FIELDS = ["file_path", "path", "notebook_path"];
|
|
117787
|
+
function canonical(p2) {
|
|
117788
|
+
const abs = resolve2(p2);
|
|
117789
|
+
try {
|
|
117790
|
+
return realpathSync2(abs);
|
|
117791
|
+
} catch {
|
|
117792
|
+
try {
|
|
117793
|
+
return resolve2(realpathSync2(dirname(abs)), basename(abs));
|
|
117794
|
+
} catch {
|
|
117795
|
+
return abs;
|
|
117796
|
+
}
|
|
117797
|
+
}
|
|
117798
|
+
}
|
|
117799
|
+
function targetsDataDir(_toolName, input, dataDir) {
|
|
117800
|
+
const canonDir = canonical(dataDir);
|
|
117801
|
+
for (const f7 of PATH_FIELDS) {
|
|
117802
|
+
const v5 = input[f7];
|
|
117803
|
+
if (typeof v5 === "string") {
|
|
117804
|
+
const canon = canonical(v5);
|
|
117805
|
+
if (canon === canonDir || canon.startsWith(canonDir + sep)) return true;
|
|
117806
|
+
}
|
|
117807
|
+
}
|
|
117808
|
+
const cmd = input.command;
|
|
117809
|
+
if (typeof cmd === "string" && cmd.includes(canonDir)) return true;
|
|
117810
|
+
return false;
|
|
117811
|
+
}
|
|
117812
|
+
function gateDecision(toolName, input, opts) {
|
|
117813
|
+
if (toolName === ROOM_SAY_TOOL_NAME) return { deny: false };
|
|
117814
|
+
if (!opts.isOwnerTurn()) {
|
|
117815
|
+
return { deny: true, reason: "tools are disabled in rooms; reply with the say tool only" };
|
|
117816
|
+
}
|
|
117817
|
+
if (targetsDataDir(toolName, input, opts.dataDir)) {
|
|
117818
|
+
return { deny: true, reason: "access to the AgentVault key directory is not permitted" };
|
|
117819
|
+
}
|
|
117820
|
+
return { deny: false };
|
|
117821
|
+
}
|
|
117822
|
+
function makeWorkerPreToolUseHook(opts) {
|
|
117823
|
+
return {
|
|
117824
|
+
hooks: [
|
|
117825
|
+
async (input) => {
|
|
117826
|
+
const i2 = input;
|
|
117827
|
+
const verdict = gateDecision(
|
|
117828
|
+
i2.tool_name ?? "",
|
|
117829
|
+
i2.tool_input ?? {},
|
|
117830
|
+
opts
|
|
117831
|
+
);
|
|
117832
|
+
if (verdict.deny) {
|
|
117833
|
+
console.error(`[worker-gate] DENY ${i2.tool_name} \u2014 ${verdict.reason}`);
|
|
117834
|
+
return {
|
|
117835
|
+
hookSpecificOutput: {
|
|
117836
|
+
hookEventName: "PreToolUse",
|
|
117837
|
+
permissionDecision: "deny",
|
|
117838
|
+
permissionDecisionReason: verdict.reason
|
|
117839
|
+
}
|
|
117840
|
+
};
|
|
117841
|
+
}
|
|
117842
|
+
return {};
|
|
117843
|
+
}
|
|
117844
|
+
]
|
|
117845
|
+
};
|
|
117846
|
+
}
|
|
117847
|
+
function makeWorkerPermission(opts) {
|
|
117848
|
+
return async (toolName, input) => {
|
|
117849
|
+
const verdict = gateDecision(toolName, input, opts);
|
|
117850
|
+
if (verdict.deny) {
|
|
117851
|
+
console.error(`[worker-gate] DENY ${toolName} \u2014 ${verdict.reason}`);
|
|
117852
|
+
return { behavior: "deny", message: verdict.reason };
|
|
117853
|
+
}
|
|
117854
|
+
return { behavior: "allow", updatedInput: input };
|
|
117855
|
+
};
|
|
117856
|
+
}
|
|
117857
|
+
|
|
117766
117858
|
// ../../node_modules/zod/v4/classic/external.js
|
|
117767
117859
|
var external_exports = {};
|
|
117768
117860
|
__export(external_exports, {
|
|
@@ -131554,10 +131646,21 @@ var PersistentClaudeSession = class {
|
|
|
131554
131646
|
/** Reply sink bound to the message currently being processed. Set as each
|
|
131555
131647
|
* message is handed to the model so the say tool routes to the right place. */
|
|
131556
131648
|
activeReply;
|
|
131557
|
-
/**
|
|
131649
|
+
/**
|
|
131650
|
+
* Per-turn state for the #416 DM auto-reply fallback.
|
|
131651
|
+
*
|
|
131652
|
+
* LOAD-BEARING for the worker tool gate: `currentAutoReply` is true ONLY on
|
|
131653
|
+
* owner DM turns (`autoReplyOnText:true` from wireBridge) and false on room
|
|
131654
|
+
* turns (`autoReplyOnText:false`). `makeWorkerPermission` calls
|
|
131655
|
+
* `isOwnerTurn: () => this.currentAutoReply` to decide whether tools are
|
|
131656
|
+
* allowed. A room-origin turn MUST keep this false or untrusted input gains
|
|
131657
|
+
* full tool access. See worker-permission.test.ts for the covering assertion.
|
|
131658
|
+
*/
|
|
131558
131659
|
currentAutoReply = false;
|
|
131559
131660
|
saidThisTurn = false;
|
|
131560
131661
|
turnText = "";
|
|
131662
|
+
/** In-process room MCP server — hoisted so buildSdkOptions can reference it. */
|
|
131663
|
+
roomServer;
|
|
131561
131664
|
/**
|
|
131562
131665
|
* Queue an inbound message for the model.
|
|
131563
131666
|
* @param opts.autoReplyOnText — for 1:1 DMs (where the owner always expects a
|
|
@@ -131591,8 +131694,8 @@ var PersistentClaudeSession = class {
|
|
|
131591
131694
|
}
|
|
131592
131695
|
async *input() {
|
|
131593
131696
|
while (true) {
|
|
131594
|
-
const item = this.pending.length > 0 ? this.pending.shift() : await new Promise((
|
|
131595
|
-
this.waiting =
|
|
131697
|
+
const item = this.pending.length > 0 ? this.pending.shift() : await new Promise((resolve3) => {
|
|
131698
|
+
this.waiting = resolve3;
|
|
131596
131699
|
});
|
|
131597
131700
|
this.activeReply = item.reply;
|
|
131598
131701
|
this.currentAutoReply = item.autoReplyOnText ?? false;
|
|
@@ -131601,38 +131704,54 @@ var PersistentClaudeSession = class {
|
|
|
131601
131704
|
yield item.msg;
|
|
131602
131705
|
}
|
|
131603
131706
|
}
|
|
131707
|
+
/**
|
|
131708
|
+
* Build the SDK options for this session. Locked mode (default) is safe for
|
|
131709
|
+
* untrusted inbound room messages. Worker mode (opts.worker=true) enables full
|
|
131710
|
+
* toolset on owner DMs, project context, workspace cwd, and an AV data-dir
|
|
131711
|
+
* fence via canUseTool.
|
|
131712
|
+
*/
|
|
131713
|
+
buildSdkOptions() {
|
|
131714
|
+
const base = {
|
|
131715
|
+
model: this.opts.model,
|
|
131716
|
+
systemPrompt: this.opts.systemPrompt,
|
|
131717
|
+
mcpServers: { room: this.roomServer },
|
|
131718
|
+
allowedTools: [ROOM_SAY_TOOL_NAME]
|
|
131719
|
+
};
|
|
131720
|
+
if (!this.opts.worker) {
|
|
131721
|
+
return {
|
|
131722
|
+
...base,
|
|
131723
|
+
permissionMode: "dontAsk",
|
|
131724
|
+
tools: [],
|
|
131725
|
+
settingSources: []
|
|
131726
|
+
};
|
|
131727
|
+
}
|
|
131728
|
+
const gateOpts = {
|
|
131729
|
+
dataDir: this.opts.dataDir ?? "",
|
|
131730
|
+
// LOAD-BEARING: this.currentAutoReply is true only on owner DM turns.
|
|
131731
|
+
// A room turn must keep it false or untrusted input gains full tool access.
|
|
131732
|
+
// See worker-permission.test.ts for the covering assertion.
|
|
131733
|
+
isOwnerTurn: () => this.currentAutoReply
|
|
131734
|
+
};
|
|
131735
|
+
return {
|
|
131736
|
+
...base,
|
|
131737
|
+
permissionMode: this.opts.permissionMode ?? "auto",
|
|
131738
|
+
settingSources: ["user", "project"],
|
|
131739
|
+
cwd: this.opts.workspaceDir,
|
|
131740
|
+
// PRIMARY gate: a PreToolUse hook fires on EVERY tool call regardless of
|
|
131741
|
+
// permissionMode. canUseTool alone is bypassed in "auto" mode (the SDK's
|
|
131742
|
+
// classifier auto-approves without hitting the "ask" path) — verified live.
|
|
131743
|
+
hooks: { PreToolUse: [makeWorkerPreToolUseHook(gateOpts)] },
|
|
131744
|
+
// Secondary (defense-in-depth): covers the "ask" path in default/dontAsk modes.
|
|
131745
|
+
canUseTool: makeWorkerPermission(gateOpts)
|
|
131746
|
+
};
|
|
131747
|
+
}
|
|
131604
131748
|
async start() {
|
|
131605
|
-
|
|
131749
|
+
this.roomServer = _s({
|
|
131606
131750
|
name: "room",
|
|
131607
131751
|
version: "0.2.0",
|
|
131608
131752
|
tools: [makeRoomSayTool((text) => this.deliver(text))]
|
|
131609
131753
|
});
|
|
131610
|
-
const sdkOptions =
|
|
131611
|
-
model: this.opts.model,
|
|
131612
|
-
systemPrompt: this.opts.systemPrompt,
|
|
131613
|
-
// SECURITY: this session is driven by UNTRUSTED inbound room messages from
|
|
131614
|
-
// other agents. It must NOT be able to run general tools (shell/file/network)
|
|
131615
|
-
// — that would be a prompt-injection → RCE / key-exfil path on the host. The
|
|
131616
|
-
// ONLY tool it gets is room_say (post text to the active room), which has no
|
|
131617
|
-
// such reach. Defense is capability REMOVAL first, permission mode second:
|
|
131618
|
-
// - tools [] : remove ALL built-in tools (Bash/Read/Write/...) at the
|
|
131619
|
-
// source so an injection can't even reach the permission layer. The
|
|
131620
|
-
// room_say MCP tool comes via mcpServers and is unaffected by this.
|
|
131621
|
-
// - permissionMode "dontAsk" (NEVER "bypassPermissions"): deny anything not
|
|
131622
|
-
// pre-approved — no reliance on a no-TTY-implies-denial assumption.
|
|
131623
|
-
// - allowedTools [ROOM_SAY_TOOL_NAME] : pre-approve ONLY room_say.
|
|
131624
|
-
// - settingSources [] : do not load CLAUDE.md / project agents / skills
|
|
131625
|
-
// from disk into an untrusted-input session.
|
|
131626
|
-
// When CClaude later becomes a tool-using coder, additional tools must only
|
|
131627
|
-
// be enabled INSIDE an isolation boundary (sandboxed dev droplet, no prod/
|
|
131628
|
-
// network access, no access to the device-key dir) AND gated by canUseTool.
|
|
131629
|
-
permissionMode: "dontAsk",
|
|
131630
|
-
tools: [],
|
|
131631
|
-
allowedTools: [ROOM_SAY_TOOL_NAME],
|
|
131632
|
-
mcpServers: { room: roomServer },
|
|
131633
|
-
settingSources: []
|
|
131634
|
-
// maxTurns left unset → persistent multi-turn (NOT maxTurns:1)
|
|
131635
|
-
};
|
|
131754
|
+
const sdkOptions = this.buildSdkOptions();
|
|
131636
131755
|
const q5 = this.opts.queryImpl ? this.opts.queryImpl({
|
|
131637
131756
|
prompt: this.input(),
|
|
131638
131757
|
options: sdkOptions
|
|
@@ -131779,7 +131898,14 @@ async function main() {
|
|
|
131779
131898
|
"[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"
|
|
131780
131899
|
);
|
|
131781
131900
|
}
|
|
131901
|
+
console.error(`[bridge] version: ${true ? "0.3.4" : "dev"}`);
|
|
131782
131902
|
console.error(`[bridge] data dir: ${cfg.dataDir} (${cfg.dataDirSource})`);
|
|
131903
|
+
if (cfg.worker) {
|
|
131904
|
+
console.error(`[bridge] WORKER MODE \u2014 workspace: ${cfg.workspaceDir} \xB7 permissions: ${cfg.permissionMode} \xB7 enclave dir fenced`);
|
|
131905
|
+
console.error(
|
|
131906
|
+
"[bridge] WORKER MODE WARNING: worker mode mixes untrusted room context with trusted owner DM turns in one persistent session. The turn-scoped gate (isOwnerTurn) prevents tool use ON a room turn, but does NOT prevent a room message from planting an instruction that fires on a later owner DM turn when tools are enabled (cross-turn injection). Until Slice 2: run a worker bridge DM-only (no room traffic) or under OS-user isolation."
|
|
131907
|
+
);
|
|
131908
|
+
}
|
|
131783
131909
|
const target = new ActiveTarget();
|
|
131784
131910
|
if (cfg.roomFilter) target.setRoom(cfg.roomFilter);
|
|
131785
131911
|
const channel = new SecureChannel({
|
|
@@ -131798,7 +131924,11 @@ async function main() {
|
|
|
131798
131924
|
// per-message binding is what prevents a private 1:1 reply from leaking into a
|
|
131799
131925
|
// room when room traffic arrives mid-compose.
|
|
131800
131926
|
// Assistant reasoning that wasn't sent — log a short trace only.
|
|
131801
|
-
onObserve: (text) => console.error(`[bridge] observed (${text.length} chars, not sent)`)
|
|
131927
|
+
onObserve: (text) => console.error(`[bridge] observed (${text.length} chars, not sent)`),
|
|
131928
|
+
worker: cfg.worker,
|
|
131929
|
+
workspaceDir: cfg.workspaceDir,
|
|
131930
|
+
permissionMode: cfg.permissionMode,
|
|
131931
|
+
dataDir: cfg.dataDir
|
|
131802
131932
|
});
|
|
131803
131933
|
wireBridge(
|
|
131804
131934
|
channel,
|
package/dist/session.d.ts
CHANGED
|
@@ -55,6 +55,15 @@ export interface SessionOpts {
|
|
|
55
55
|
model?: string;
|
|
56
56
|
systemPrompt?: string;
|
|
57
57
|
queryImpl?: QueryFn;
|
|
58
|
+
/** When true, session runs as a worker agent: full toolset on owner DMs,
|
|
59
|
+
* project context loaded, workspace cwd set, AV data dir fenced off. */
|
|
60
|
+
worker?: boolean;
|
|
61
|
+
/** Workspace directory to set as cwd in worker mode. */
|
|
62
|
+
workspaceDir?: string;
|
|
63
|
+
/** Claude permission mode for worker turns (default: "auto"). */
|
|
64
|
+
permissionMode?: "auto" | "acceptEdits" | "bypassPermissions";
|
|
65
|
+
/** AgentVault data directory — fenced off from worker tool access. */
|
|
66
|
+
dataDir?: string;
|
|
58
67
|
}
|
|
59
68
|
export declare class PersistentClaudeSession {
|
|
60
69
|
private opts;
|
|
@@ -63,10 +72,21 @@ export declare class PersistentClaudeSession {
|
|
|
63
72
|
/** Reply sink bound to the message currently being processed. Set as each
|
|
64
73
|
* message is handed to the model so the say tool routes to the right place. */
|
|
65
74
|
private activeReply?;
|
|
66
|
-
/**
|
|
75
|
+
/**
|
|
76
|
+
* Per-turn state for the #416 DM auto-reply fallback.
|
|
77
|
+
*
|
|
78
|
+
* LOAD-BEARING for the worker tool gate: `currentAutoReply` is true ONLY on
|
|
79
|
+
* owner DM turns (`autoReplyOnText:true` from wireBridge) and false on room
|
|
80
|
+
* turns (`autoReplyOnText:false`). `makeWorkerPermission` calls
|
|
81
|
+
* `isOwnerTurn: () => this.currentAutoReply` to decide whether tools are
|
|
82
|
+
* allowed. A room-origin turn MUST keep this false or untrusted input gains
|
|
83
|
+
* full tool access. See worker-permission.test.ts for the covering assertion.
|
|
84
|
+
*/
|
|
67
85
|
private currentAutoReply;
|
|
68
86
|
private saidThisTurn;
|
|
69
87
|
private turnText;
|
|
88
|
+
/** In-process room MCP server — hoisted so buildSdkOptions can reference it. */
|
|
89
|
+
private roomServer;
|
|
70
90
|
constructor(opts: SessionOpts);
|
|
71
91
|
/**
|
|
72
92
|
* Queue an inbound message for the model.
|
|
@@ -83,6 +103,13 @@ export declare class PersistentClaudeSession {
|
|
|
83
103
|
* the one captured for the message being answered, not a live global target. */
|
|
84
104
|
deliver(text: string): Promise<void>;
|
|
85
105
|
private input;
|
|
106
|
+
/**
|
|
107
|
+
* Build the SDK options for this session. Locked mode (default) is safe for
|
|
108
|
+
* untrusted inbound room messages. Worker mode (opts.worker=true) enables full
|
|
109
|
+
* toolset on owner DMs, project context, workspace cwd, and an AV data-dir
|
|
110
|
+
* fence via canUseTool.
|
|
111
|
+
*/
|
|
112
|
+
private buildSdkOptions;
|
|
86
113
|
start(): Promise<void>;
|
|
87
114
|
}
|
|
88
115
|
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CanUseTool, HookCallbackMatcher } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
+
/**
|
|
3
|
+
* PRIMARY enforcement: a PreToolUse hook. Unlike canUseTool (the SDK's "ask"
|
|
4
|
+
* path, which `permissionMode:"auto"` BYPASSES by auto-approving benign tools via
|
|
5
|
+
* its classifier — verified live: the canUseTool gate never fired in auto mode),
|
|
6
|
+
* a PreToolUse `deny` fires on EVERY tool call regardless of permission mode.
|
|
7
|
+
* This is what actually enforces the gate at runtime.
|
|
8
|
+
*/
|
|
9
|
+
export declare function makeWorkerPreToolUseHook(opts: {
|
|
10
|
+
dataDir: string;
|
|
11
|
+
isOwnerTurn: () => boolean;
|
|
12
|
+
}): HookCallbackMatcher;
|
|
13
|
+
/**
|
|
14
|
+
* SECONDARY (defense-in-depth): the canUseTool callback covers the SDK's "ask"
|
|
15
|
+
* path (permissionMode `"default"`/`"dontAsk"`). Shares gateDecision with the
|
|
16
|
+
* PreToolUse hook above, so a deny in one is a deny in the other.
|
|
17
|
+
*/
|
|
18
|
+
export declare function makeWorkerPermission(opts: {
|
|
19
|
+
dataDir: string;
|
|
20
|
+
isOwnerTurn: () => boolean;
|
|
21
|
+
}): CanUseTool;
|
|
22
|
+
//# sourceMappingURL=worker-permission.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentvault/claude-bridge",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
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",
|