@agentvault/claude-bridge 0.7.6 → 0.7.8
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 +243 -157
- package/dist/log.d.ts +22 -0
- package/dist/worker-queue.d.ts +28 -3
- package/package.json +2 -2
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";
|
|
@@ -53073,8 +53073,8 @@ var init_dhkem = __esm2({
|
|
|
53073
53073
|
async deserializePrivateKey(key) {
|
|
53074
53074
|
return await this._prim.deserializePrivateKey(toArrayBuffer(key));
|
|
53075
53075
|
}
|
|
53076
|
-
async importKey(
|
|
53077
|
-
return await this._prim.importKey(
|
|
53076
|
+
async importKey(format2, key, isPublic = true) {
|
|
53077
|
+
return await this._prim.importKey(format2, key, isPublic);
|
|
53078
53078
|
}
|
|
53079
53079
|
async generateKeyPair() {
|
|
53080
53080
|
return await this._prim.generateKeyPair();
|
|
@@ -53717,10 +53717,10 @@ var init_ec = __esm2({
|
|
|
53717
53717
|
throw new DeserializeError(e7);
|
|
53718
53718
|
}
|
|
53719
53719
|
}
|
|
53720
|
-
async importKey(
|
|
53720
|
+
async importKey(format2, key, isPublic) {
|
|
53721
53721
|
await this._setup();
|
|
53722
53722
|
try {
|
|
53723
|
-
if (
|
|
53723
|
+
if (format2 === "raw") {
|
|
53724
53724
|
return await this._importRawKey(key, isPublic);
|
|
53725
53725
|
}
|
|
53726
53726
|
if (key instanceof ArrayBuffer) {
|
|
@@ -55107,10 +55107,10 @@ var init_x25519 = __esm2({
|
|
|
55107
55107
|
throw new DeserializeError(e7);
|
|
55108
55108
|
}
|
|
55109
55109
|
}
|
|
55110
|
-
async importKey(
|
|
55110
|
+
async importKey(format2, key, isPublic) {
|
|
55111
55111
|
await this._setup();
|
|
55112
55112
|
try {
|
|
55113
|
-
if (
|
|
55113
|
+
if (format2 === "raw") {
|
|
55114
55114
|
return await this._importRawKey(key, isPublic);
|
|
55115
55115
|
}
|
|
55116
55116
|
if (key instanceof ArrayBuffer) {
|
|
@@ -60045,10 +60045,10 @@ function _splitEndoScalar(k2, basis, n22) {
|
|
|
60045
60045
|
}
|
|
60046
60046
|
return { k1neg, k1: k12, k2neg, k2: k22 };
|
|
60047
60047
|
}
|
|
60048
|
-
function validateSigFormat(
|
|
60049
|
-
if (!["compact", "recovered", "der"].includes(
|
|
60048
|
+
function validateSigFormat(format2) {
|
|
60049
|
+
if (!["compact", "recovered", "der"].includes(format2))
|
|
60050
60050
|
throw new Error('Signature format must be "compact", "recovered", or "der"');
|
|
60051
|
-
return
|
|
60051
|
+
return format2;
|
|
60052
60052
|
}
|
|
60053
60053
|
function validateSigOpts(opts, def) {
|
|
60054
60054
|
const optsn = {};
|
|
@@ -60736,11 +60736,11 @@ function ecdsa(Point, hash22, ecdsaOpts = {}) {
|
|
|
60736
60736
|
throw new Error(`invalid signature ${title}: out of range 1..Point.Fn.ORDER`);
|
|
60737
60737
|
return num;
|
|
60738
60738
|
}
|
|
60739
|
-
function validateSigLength(bytes,
|
|
60740
|
-
validateSigFormat(
|
|
60739
|
+
function validateSigLength(bytes, format2) {
|
|
60740
|
+
validateSigFormat(format2);
|
|
60741
60741
|
const size = lengths.signature;
|
|
60742
|
-
const sizer =
|
|
60743
|
-
return _abytes2(bytes, sizer, `${
|
|
60742
|
+
const sizer = format2 === "compact" ? size : format2 === "recovered" ? size + 1 : void 0;
|
|
60743
|
+
return _abytes2(bytes, sizer, `${format2} signature`);
|
|
60744
60744
|
}
|
|
60745
60745
|
class Signature {
|
|
60746
60746
|
constructor(r22, s22, recovery) {
|
|
@@ -60750,16 +60750,16 @@ function ecdsa(Point, hash22, ecdsaOpts = {}) {
|
|
|
60750
60750
|
this.recovery = recovery;
|
|
60751
60751
|
Object.freeze(this);
|
|
60752
60752
|
}
|
|
60753
|
-
static fromBytes(bytes,
|
|
60754
|
-
validateSigLength(bytes,
|
|
60753
|
+
static fromBytes(bytes, format2 = defaultSigOpts_format) {
|
|
60754
|
+
validateSigLength(bytes, format2);
|
|
60755
60755
|
let recid;
|
|
60756
|
-
if (
|
|
60756
|
+
if (format2 === "der") {
|
|
60757
60757
|
const { r: r32, s: s32 } = DER.toSig(_abytes2(bytes));
|
|
60758
60758
|
return new Signature(r32, s32);
|
|
60759
60759
|
}
|
|
60760
|
-
if (
|
|
60760
|
+
if (format2 === "recovered") {
|
|
60761
60761
|
recid = bytes[0];
|
|
60762
|
-
|
|
60762
|
+
format2 = "compact";
|
|
60763
60763
|
bytes = bytes.subarray(1);
|
|
60764
60764
|
}
|
|
60765
60765
|
const L22 = Fn3.BYTES;
|
|
@@ -60767,8 +60767,8 @@ function ecdsa(Point, hash22, ecdsaOpts = {}) {
|
|
|
60767
60767
|
const s22 = bytes.subarray(L22, L22 * 2);
|
|
60768
60768
|
return new Signature(Fn3.fromBytes(r22), Fn3.fromBytes(s22), recid);
|
|
60769
60769
|
}
|
|
60770
|
-
static fromHex(hex32,
|
|
60771
|
-
return this.fromBytes(hexToBytes4(hex32),
|
|
60770
|
+
static fromHex(hex32, format2) {
|
|
60771
|
+
return this.fromBytes(hexToBytes4(hex32), format2);
|
|
60772
60772
|
}
|
|
60773
60773
|
addRecoveryBit(recovery) {
|
|
60774
60774
|
return new Signature(this.r, this.s, recovery);
|
|
@@ -60800,21 +60800,21 @@ function ecdsa(Point, hash22, ecdsaOpts = {}) {
|
|
|
60800
60800
|
hasHighS() {
|
|
60801
60801
|
return isBiggerThanHalfOrder(this.s);
|
|
60802
60802
|
}
|
|
60803
|
-
toBytes(
|
|
60804
|
-
validateSigFormat(
|
|
60805
|
-
if (
|
|
60803
|
+
toBytes(format2 = defaultSigOpts_format) {
|
|
60804
|
+
validateSigFormat(format2);
|
|
60805
|
+
if (format2 === "der")
|
|
60806
60806
|
return hexToBytes4(DER.hexFromSig(this));
|
|
60807
60807
|
const r22 = Fn3.toBytes(this.r);
|
|
60808
60808
|
const s22 = Fn3.toBytes(this.s);
|
|
60809
|
-
if (
|
|
60809
|
+
if (format2 === "recovered") {
|
|
60810
60810
|
if (this.recovery == null)
|
|
60811
60811
|
throw new Error("recovery bit must be present");
|
|
60812
60812
|
return concatBytes2(Uint8Array.of(this.recovery), r22, s22);
|
|
60813
60813
|
}
|
|
60814
60814
|
return concatBytes2(r22, s22);
|
|
60815
60815
|
}
|
|
60816
|
-
toHex(
|
|
60817
|
-
return bytesToHex4(this.toBytes(
|
|
60816
|
+
toHex(format2) {
|
|
60817
|
+
return bytesToHex4(this.toBytes(format2));
|
|
60818
60818
|
}
|
|
60819
60819
|
// TODO: remove
|
|
60820
60820
|
assertValidity() {
|
|
@@ -60931,12 +60931,12 @@ function ecdsa(Point, hash22, ecdsaOpts = {}) {
|
|
|
60931
60931
|
return sig;
|
|
60932
60932
|
}
|
|
60933
60933
|
function verify(signature, message, publicKey, opts = {}) {
|
|
60934
|
-
const { lowS, prehash, format } = validateSigOpts(opts, defaultSigOpts);
|
|
60934
|
+
const { lowS, prehash, format: format2 } = validateSigOpts(opts, defaultSigOpts);
|
|
60935
60935
|
publicKey = ensureBytes("publicKey", publicKey);
|
|
60936
60936
|
message = validateMsgAndHash(ensureBytes("message", message), prehash);
|
|
60937
60937
|
if ("strict" in opts)
|
|
60938
60938
|
throw new Error("options.strict was renamed to lowS");
|
|
60939
|
-
const sig =
|
|
60939
|
+
const sig = format2 === void 0 ? tryParsingSig(signature) : Signature.fromBytes(ensureBytes("sig", signature), format2);
|
|
60940
60940
|
if (sig === false)
|
|
60941
60941
|
return false;
|
|
60942
60942
|
try {
|
|
@@ -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
|
}
|
|
@@ -80824,13 +80864,13 @@ function _stringbool(Classes, _params) {
|
|
|
80824
80864
|
return codec22;
|
|
80825
80865
|
}
|
|
80826
80866
|
// @__NO_SIDE_EFFECTS__
|
|
80827
|
-
function _stringFormat(Class22,
|
|
80867
|
+
function _stringFormat(Class22, format2, fnOrRegex, _params = {}) {
|
|
80828
80868
|
const params = normalizeParams(_params);
|
|
80829
80869
|
const def = {
|
|
80830
80870
|
...normalizeParams(_params),
|
|
80831
80871
|
check: "string_format",
|
|
80832
80872
|
type: "string",
|
|
80833
|
-
format,
|
|
80873
|
+
format: format2,
|
|
80834
80874
|
fn: typeof fnOrRegex === "function" ? fnOrRegex : (val) => fnOrRegex.test(val),
|
|
80835
80875
|
...params
|
|
80836
80876
|
};
|
|
@@ -81295,16 +81335,16 @@ var init_json_schema_processors = __esm2({
|
|
|
81295
81335
|
stringProcessor = (schema, ctx, _json, _params) => {
|
|
81296
81336
|
const json22 = _json;
|
|
81297
81337
|
json22.type = "string";
|
|
81298
|
-
const { minimum, maximum, format, patterns, contentEncoding } = schema._zod.bag;
|
|
81338
|
+
const { minimum, maximum, format: format2, patterns, contentEncoding } = schema._zod.bag;
|
|
81299
81339
|
if (typeof minimum === "number")
|
|
81300
81340
|
json22.minLength = minimum;
|
|
81301
81341
|
if (typeof maximum === "number")
|
|
81302
81342
|
json22.maxLength = maximum;
|
|
81303
|
-
if (
|
|
81304
|
-
json22.format = formatMap[
|
|
81343
|
+
if (format2) {
|
|
81344
|
+
json22.format = formatMap[format2] ?? format2;
|
|
81305
81345
|
if (json22.format === "")
|
|
81306
81346
|
delete json22.format;
|
|
81307
|
-
if (
|
|
81347
|
+
if (format2 === "time") {
|
|
81308
81348
|
delete json22.format;
|
|
81309
81349
|
}
|
|
81310
81350
|
}
|
|
@@ -81326,8 +81366,8 @@ var init_json_schema_processors = __esm2({
|
|
|
81326
81366
|
};
|
|
81327
81367
|
numberProcessor = (schema, ctx, _json, _params) => {
|
|
81328
81368
|
const json22 = _json;
|
|
81329
|
-
const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
|
|
81330
|
-
if (typeof
|
|
81369
|
+
const { minimum, maximum, format: format2, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
|
|
81370
|
+
if (typeof format2 === "string" && format2.includes("int"))
|
|
81331
81371
|
json22.type = "integer";
|
|
81332
81372
|
else
|
|
81333
81373
|
json22.type = "number";
|
|
@@ -82482,8 +82522,8 @@ function e1642(params) {
|
|
|
82482
82522
|
function jwt(params) {
|
|
82483
82523
|
return /* @__PURE__ */ _jwt(ZodJWT, params);
|
|
82484
82524
|
}
|
|
82485
|
-
function stringFormat(
|
|
82486
|
-
return /* @__PURE__ */ _stringFormat(ZodCustomStringFormat,
|
|
82525
|
+
function stringFormat(format2, fnOrRegex, _params = {}) {
|
|
82526
|
+
return /* @__PURE__ */ _stringFormat(ZodCustomStringFormat, format2, fnOrRegex, _params);
|
|
82487
82527
|
}
|
|
82488
82528
|
function hostname2(_params) {
|
|
82489
82529
|
return /* @__PURE__ */ _stringFormat(ZodCustomStringFormat, "hostname", regexes_exports.hostname, _params);
|
|
@@ -82493,11 +82533,11 @@ function hex2(_params) {
|
|
|
82493
82533
|
}
|
|
82494
82534
|
function hash(alg, params) {
|
|
82495
82535
|
const enc = params?.enc ?? "hex";
|
|
82496
|
-
const
|
|
82497
|
-
const regex = regexes_exports[
|
|
82536
|
+
const format2 = `${alg}_${enc}`;
|
|
82537
|
+
const regex = regexes_exports[format2];
|
|
82498
82538
|
if (!regex)
|
|
82499
|
-
throw new Error(`Unrecognized hash format: ${
|
|
82500
|
-
return /* @__PURE__ */ _stringFormat(ZodCustomStringFormat,
|
|
82539
|
+
throw new Error(`Unrecognized hash format: ${format2}`);
|
|
82540
|
+
return /* @__PURE__ */ _stringFormat(ZodCustomStringFormat, format2, regex, params);
|
|
82501
82541
|
}
|
|
82502
82542
|
function number2(params) {
|
|
82503
82543
|
return /* @__PURE__ */ _number(ZodNumber2, params);
|
|
@@ -91980,10 +92020,10 @@ var require_core = __commonJS({
|
|
|
91980
92020
|
return this;
|
|
91981
92021
|
}
|
|
91982
92022
|
// Add format
|
|
91983
|
-
addFormat(name,
|
|
91984
|
-
if (typeof
|
|
91985
|
-
|
|
91986
|
-
this.formats[name] =
|
|
92023
|
+
addFormat(name, format2) {
|
|
92024
|
+
if (typeof format2 == "string")
|
|
92025
|
+
format2 = new RegExp(format2);
|
|
92026
|
+
this.formats[name] = format2;
|
|
91987
92027
|
return this;
|
|
91988
92028
|
}
|
|
91989
92029
|
errorsText(errors = this.errors, { separator = ", ", dataVar = "data" } = {}) {
|
|
@@ -92101,9 +92141,9 @@ var require_core = __commonJS({
|
|
|
92101
92141
|
}
|
|
92102
92142
|
function addInitialFormats() {
|
|
92103
92143
|
for (const name in this.opts.formats) {
|
|
92104
|
-
const
|
|
92105
|
-
if (
|
|
92106
|
-
this.addFormat(name,
|
|
92144
|
+
const format2 = this.opts.formats[name];
|
|
92145
|
+
if (format2)
|
|
92146
|
+
this.addFormat(name, format2);
|
|
92107
92147
|
}
|
|
92108
92148
|
}
|
|
92109
92149
|
function addInitialKeywords(defs) {
|
|
@@ -93718,18 +93758,18 @@ var require_format = __commonJS({
|
|
|
93718
93758
|
});
|
|
93719
93759
|
const fDef = gen.const("fDef", (0, codegen_1._)`${fmts}[${schemaCode}]`);
|
|
93720
93760
|
const fType = gen.let("fType");
|
|
93721
|
-
const
|
|
93722
|
-
gen.if((0, codegen_1._)`typeof ${fDef} == "object" && !(${fDef} instanceof RegExp)`, () => gen.assign(fType, (0, codegen_1._)`${fDef}.type || "string"`).assign(
|
|
93761
|
+
const format2 = gen.let("format");
|
|
93762
|
+
gen.if((0, codegen_1._)`typeof ${fDef} == "object" && !(${fDef} instanceof RegExp)`, () => gen.assign(fType, (0, codegen_1._)`${fDef}.type || "string"`).assign(format2, (0, codegen_1._)`${fDef}.validate`), () => gen.assign(fType, (0, codegen_1._)`"string"`).assign(format2, fDef));
|
|
93723
93763
|
cxt.fail$data((0, codegen_1.or)(unknownFmt(), invalidFmt()));
|
|
93724
93764
|
function unknownFmt() {
|
|
93725
93765
|
if (opts.strictSchema === false)
|
|
93726
93766
|
return codegen_1.nil;
|
|
93727
|
-
return (0, codegen_1._)`${schemaCode} && !${
|
|
93767
|
+
return (0, codegen_1._)`${schemaCode} && !${format2}`;
|
|
93728
93768
|
}
|
|
93729
93769
|
function invalidFmt() {
|
|
93730
|
-
const callFormat = schemaEnv.$async ? (0, codegen_1._)`(${fDef}.async ? await ${
|
|
93731
|
-
const validData = (0, codegen_1._)`(typeof ${
|
|
93732
|
-
return (0, codegen_1._)`${
|
|
93770
|
+
const callFormat = schemaEnv.$async ? (0, codegen_1._)`(${fDef}.async ? await ${format2}(${data}) : ${format2}(${data}))` : (0, codegen_1._)`${format2}(${data})`;
|
|
93771
|
+
const validData = (0, codegen_1._)`(typeof ${format2} == "function" ? ${callFormat} : ${format2}.test(${data}))`;
|
|
93772
|
+
return (0, codegen_1._)`${format2} && ${format2} !== true && ${fType} === ${ruleType} && !${validData}`;
|
|
93733
93773
|
}
|
|
93734
93774
|
}
|
|
93735
93775
|
function validateFormat() {
|
|
@@ -93740,7 +93780,7 @@ var require_format = __commonJS({
|
|
|
93740
93780
|
}
|
|
93741
93781
|
if (formatDef === true)
|
|
93742
93782
|
return;
|
|
93743
|
-
const [fmtType,
|
|
93783
|
+
const [fmtType, format2, fmtRef] = getFormat(formatDef);
|
|
93744
93784
|
if (fmtType === ruleType)
|
|
93745
93785
|
cxt.pass(validCondition());
|
|
93746
93786
|
function unknownFormat() {
|
|
@@ -93767,7 +93807,7 @@ var require_format = __commonJS({
|
|
|
93767
93807
|
throw new Error("async format in sync schema");
|
|
93768
93808
|
return (0, codegen_1._)`await ${fmtRef}(${data})`;
|
|
93769
93809
|
}
|
|
93770
|
-
return typeof
|
|
93810
|
+
return typeof format2 == "function" ? (0, codegen_1._)`${fmtRef}(${data})` : (0, codegen_1._)`${fmtRef}.test(${data})`;
|
|
93771
93811
|
}
|
|
93772
93812
|
}
|
|
93773
93813
|
}
|
|
@@ -93780,8 +93820,8 @@ var require_format2 = __commonJS({
|
|
|
93780
93820
|
"use strict";
|
|
93781
93821
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
93782
93822
|
var format_1 = require_format();
|
|
93783
|
-
var
|
|
93784
|
-
exports.default =
|
|
93823
|
+
var format2 = [format_1.default];
|
|
93824
|
+
exports.default = format2;
|
|
93785
93825
|
}
|
|
93786
93826
|
});
|
|
93787
93827
|
var require_metadata = __commonJS({
|
|
@@ -94407,17 +94447,17 @@ var require_limit = __commonJS({
|
|
|
94407
94447
|
cxt.fail$data((0, codegen_1.or)((0, codegen_1._)`typeof ${fmt} != "object"`, (0, codegen_1._)`${fmt} instanceof RegExp`, (0, codegen_1._)`typeof ${fmt}.compare != "function"`, compareCode(fmt)));
|
|
94408
94448
|
}
|
|
94409
94449
|
function validateFormat() {
|
|
94410
|
-
const
|
|
94411
|
-
const fmtDef = self2.formats[
|
|
94450
|
+
const format2 = fCxt.schema;
|
|
94451
|
+
const fmtDef = self2.formats[format2];
|
|
94412
94452
|
if (!fmtDef || fmtDef === true)
|
|
94413
94453
|
return;
|
|
94414
94454
|
if (typeof fmtDef != "object" || fmtDef instanceof RegExp || typeof fmtDef.compare != "function") {
|
|
94415
|
-
throw new Error(`"${keyword}": format "${
|
|
94455
|
+
throw new Error(`"${keyword}": format "${format2}" does not define "compare" function`);
|
|
94416
94456
|
}
|
|
94417
94457
|
const fmt = gen.scopeValue("formats", {
|
|
94418
|
-
key:
|
|
94458
|
+
key: format2,
|
|
94419
94459
|
ref: fmtDef,
|
|
94420
|
-
code: opts.code.formats ? (0, codegen_1._)`${opts.code.formats}${(0, codegen_1.getProperty)(
|
|
94460
|
+
code: opts.code.formats ? (0, codegen_1._)`${opts.code.formats}${(0, codegen_1.getProperty)(format2)}` : void 0
|
|
94421
94461
|
});
|
|
94422
94462
|
cxt.fail$data(compareCode(fmt));
|
|
94423
94463
|
}
|
|
@@ -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();
|
|
@@ -119140,6 +119180,16 @@ function readDeviceId(dataDir) {
|
|
|
119140
119180
|
);
|
|
119141
119181
|
}
|
|
119142
119182
|
|
|
119183
|
+
// src/log.ts
|
|
119184
|
+
import { format } from "node:util";
|
|
119185
|
+
function stamp(message) {
|
|
119186
|
+
const ts2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
119187
|
+
return message.split("\n").map((line) => `${ts2} ${line}`).join("\n");
|
|
119188
|
+
}
|
|
119189
|
+
function logLine(...args) {
|
|
119190
|
+
console.error(stamp(format(...args)));
|
|
119191
|
+
}
|
|
119192
|
+
|
|
119143
119193
|
// src/worker-permission.ts
|
|
119144
119194
|
var PATH_FIELDS = ["file_path", "path", "notebook_path"];
|
|
119145
119195
|
function canonical(p2) {
|
|
@@ -119246,7 +119296,7 @@ function makeWorkerPreToolUseHook(opts) {
|
|
|
119246
119296
|
}
|
|
119247
119297
|
}
|
|
119248
119298
|
if (verdict.deny) {
|
|
119249
|
-
|
|
119299
|
+
logLine(`[worker-gate] DENY ${toolName} \u2014 ${verdict.reason}`);
|
|
119250
119300
|
return {
|
|
119251
119301
|
hookSpecificOutput: {
|
|
119252
119302
|
hookEventName: "PreToolUse",
|
|
@@ -119264,7 +119314,7 @@ function makeWorkerPermission(opts) {
|
|
|
119264
119314
|
return async (toolName, input) => {
|
|
119265
119315
|
const verdict = gateDecision(toolName, input, opts);
|
|
119266
119316
|
if (verdict.deny) {
|
|
119267
|
-
|
|
119317
|
+
logLine(`[worker-gate] DENY ${toolName} \u2014 ${verdict.reason}`);
|
|
119268
119318
|
return { behavior: "deny", message: verdict.reason };
|
|
119269
119319
|
}
|
|
119270
119320
|
return { behavior: "allow", updatedInput: input };
|
|
@@ -130162,13 +130212,13 @@ function _stringbool2(Classes, _params) {
|
|
|
130162
130212
|
return codec3;
|
|
130163
130213
|
}
|
|
130164
130214
|
// @__NO_SIDE_EFFECTS__
|
|
130165
|
-
function _stringFormat2(Class3,
|
|
130215
|
+
function _stringFormat2(Class3, format2, fnOrRegex, _params = {}) {
|
|
130166
130216
|
const params = normalizeParams2(_params);
|
|
130167
130217
|
const def = {
|
|
130168
130218
|
...normalizeParams2(_params),
|
|
130169
130219
|
check: "string_format",
|
|
130170
130220
|
type: "string",
|
|
130171
|
-
format,
|
|
130221
|
+
format: format2,
|
|
130172
130222
|
fn: typeof fnOrRegex === "function" ? fnOrRegex : (val) => fnOrRegex.test(val),
|
|
130173
130223
|
...params
|
|
130174
130224
|
};
|
|
@@ -130543,16 +130593,16 @@ var formatMap2 = {
|
|
|
130543
130593
|
var stringProcessor2 = (schema, ctx, _json, _params) => {
|
|
130544
130594
|
const json3 = _json;
|
|
130545
130595
|
json3.type = "string";
|
|
130546
|
-
const { minimum, maximum, format, patterns, contentEncoding } = schema._zod.bag;
|
|
130596
|
+
const { minimum, maximum, format: format2, patterns, contentEncoding } = schema._zod.bag;
|
|
130547
130597
|
if (typeof minimum === "number")
|
|
130548
130598
|
json3.minLength = minimum;
|
|
130549
130599
|
if (typeof maximum === "number")
|
|
130550
130600
|
json3.maxLength = maximum;
|
|
130551
|
-
if (
|
|
130552
|
-
json3.format = formatMap2[
|
|
130601
|
+
if (format2) {
|
|
130602
|
+
json3.format = formatMap2[format2] ?? format2;
|
|
130553
130603
|
if (json3.format === "")
|
|
130554
130604
|
delete json3.format;
|
|
130555
|
-
if (
|
|
130605
|
+
if (format2 === "time") {
|
|
130556
130606
|
delete json3.format;
|
|
130557
130607
|
}
|
|
130558
130608
|
}
|
|
@@ -130574,8 +130624,8 @@ var stringProcessor2 = (schema, ctx, _json, _params) => {
|
|
|
130574
130624
|
};
|
|
130575
130625
|
var numberProcessor2 = (schema, ctx, _json, _params) => {
|
|
130576
130626
|
const json3 = _json;
|
|
130577
|
-
const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
|
|
130578
|
-
if (typeof
|
|
130627
|
+
const { minimum, maximum, format: format2, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
|
|
130628
|
+
if (typeof format2 === "string" && format2.includes("int"))
|
|
130579
130629
|
json3.type = "integer";
|
|
130580
130630
|
else
|
|
130581
130631
|
json3.type = "number";
|
|
@@ -131764,8 +131814,8 @@ var ZodCustomStringFormat2 = /* @__PURE__ */ $constructor2("ZodCustomStringForma
|
|
|
131764
131814
|
$ZodCustomStringFormat2.init(inst, def);
|
|
131765
131815
|
ZodStringFormat2.init(inst, def);
|
|
131766
131816
|
});
|
|
131767
|
-
function stringFormat2(
|
|
131768
|
-
return _stringFormat2(ZodCustomStringFormat2,
|
|
131817
|
+
function stringFormat2(format2, fnOrRegex, _params = {}) {
|
|
131818
|
+
return _stringFormat2(ZodCustomStringFormat2, format2, fnOrRegex, _params);
|
|
131769
131819
|
}
|
|
131770
131820
|
function hostname5(_params) {
|
|
131771
131821
|
return _stringFormat2(ZodCustomStringFormat2, "hostname", regexes_exports2.hostname, _params);
|
|
@@ -131775,11 +131825,11 @@ function hex4(_params) {
|
|
|
131775
131825
|
}
|
|
131776
131826
|
function hash2(alg, params) {
|
|
131777
131827
|
const enc = params?.enc ?? "hex";
|
|
131778
|
-
const
|
|
131779
|
-
const regex = regexes_exports2[
|
|
131828
|
+
const format2 = `${alg}_${enc}`;
|
|
131829
|
+
const regex = regexes_exports2[format2];
|
|
131780
131830
|
if (!regex)
|
|
131781
|
-
throw new Error(`Unrecognized hash format: ${
|
|
131782
|
-
return _stringFormat2(ZodCustomStringFormat2,
|
|
131831
|
+
throw new Error(`Unrecognized hash format: ${format2}`);
|
|
131832
|
+
return _stringFormat2(ZodCustomStringFormat2, format2, regex, params);
|
|
131783
131833
|
}
|
|
131784
131834
|
var ZodNumber3 = /* @__PURE__ */ $constructor2("ZodNumber", (inst, def) => {
|
|
131785
131835
|
$ZodNumber2.init(inst, def);
|
|
@@ -132755,52 +132805,52 @@ function convertBaseSchema(schema, ctx) {
|
|
|
132755
132805
|
case "string": {
|
|
132756
132806
|
let stringSchema = z4.string();
|
|
132757
132807
|
if (schema.format) {
|
|
132758
|
-
const
|
|
132759
|
-
if (
|
|
132808
|
+
const format2 = schema.format;
|
|
132809
|
+
if (format2 === "email") {
|
|
132760
132810
|
stringSchema = stringSchema.check(z4.email());
|
|
132761
|
-
} else if (
|
|
132811
|
+
} else if (format2 === "uri" || format2 === "uri-reference") {
|
|
132762
132812
|
stringSchema = stringSchema.check(z4.url());
|
|
132763
|
-
} else if (
|
|
132813
|
+
} else if (format2 === "uuid" || format2 === "guid") {
|
|
132764
132814
|
stringSchema = stringSchema.check(z4.uuid());
|
|
132765
|
-
} else if (
|
|
132815
|
+
} else if (format2 === "date-time") {
|
|
132766
132816
|
stringSchema = stringSchema.check(z4.iso.datetime());
|
|
132767
|
-
} else if (
|
|
132817
|
+
} else if (format2 === "date") {
|
|
132768
132818
|
stringSchema = stringSchema.check(z4.iso.date());
|
|
132769
|
-
} else if (
|
|
132819
|
+
} else if (format2 === "time") {
|
|
132770
132820
|
stringSchema = stringSchema.check(z4.iso.time());
|
|
132771
|
-
} else if (
|
|
132821
|
+
} else if (format2 === "duration") {
|
|
132772
132822
|
stringSchema = stringSchema.check(z4.iso.duration());
|
|
132773
|
-
} else if (
|
|
132823
|
+
} else if (format2 === "ipv4") {
|
|
132774
132824
|
stringSchema = stringSchema.check(z4.ipv4());
|
|
132775
|
-
} else if (
|
|
132825
|
+
} else if (format2 === "ipv6") {
|
|
132776
132826
|
stringSchema = stringSchema.check(z4.ipv6());
|
|
132777
|
-
} else if (
|
|
132827
|
+
} else if (format2 === "mac") {
|
|
132778
132828
|
stringSchema = stringSchema.check(z4.mac());
|
|
132779
|
-
} else if (
|
|
132829
|
+
} else if (format2 === "cidr") {
|
|
132780
132830
|
stringSchema = stringSchema.check(z4.cidrv4());
|
|
132781
|
-
} else if (
|
|
132831
|
+
} else if (format2 === "cidr-v6") {
|
|
132782
132832
|
stringSchema = stringSchema.check(z4.cidrv6());
|
|
132783
|
-
} else if (
|
|
132833
|
+
} else if (format2 === "base64") {
|
|
132784
132834
|
stringSchema = stringSchema.check(z4.base64());
|
|
132785
|
-
} else if (
|
|
132835
|
+
} else if (format2 === "base64url") {
|
|
132786
132836
|
stringSchema = stringSchema.check(z4.base64url());
|
|
132787
|
-
} else if (
|
|
132837
|
+
} else if (format2 === "e164") {
|
|
132788
132838
|
stringSchema = stringSchema.check(z4.e164());
|
|
132789
|
-
} else if (
|
|
132839
|
+
} else if (format2 === "jwt") {
|
|
132790
132840
|
stringSchema = stringSchema.check(z4.jwt());
|
|
132791
|
-
} else if (
|
|
132841
|
+
} else if (format2 === "emoji") {
|
|
132792
132842
|
stringSchema = stringSchema.check(z4.emoji());
|
|
132793
|
-
} else if (
|
|
132843
|
+
} else if (format2 === "nanoid") {
|
|
132794
132844
|
stringSchema = stringSchema.check(z4.nanoid());
|
|
132795
|
-
} else if (
|
|
132845
|
+
} else if (format2 === "cuid") {
|
|
132796
132846
|
stringSchema = stringSchema.check(z4.cuid());
|
|
132797
|
-
} else if (
|
|
132847
|
+
} else if (format2 === "cuid2") {
|
|
132798
132848
|
stringSchema = stringSchema.check(z4.cuid2());
|
|
132799
|
-
} else if (
|
|
132849
|
+
} else if (format2 === "ulid") {
|
|
132800
132850
|
stringSchema = stringSchema.check(z4.ulid());
|
|
132801
|
-
} else if (
|
|
132851
|
+
} else if (format2 === "xid") {
|
|
132802
132852
|
stringSchema = stringSchema.check(z4.xid());
|
|
132803
|
-
} else if (
|
|
132853
|
+
} else if (format2 === "ksuid") {
|
|
132804
132854
|
stringSchema = stringSchema.check(z4.ksuid());
|
|
132805
132855
|
}
|
|
132806
132856
|
}
|
|
@@ -133279,7 +133329,7 @@ var PersistentClaudeSession = class {
|
|
|
133279
133329
|
});
|
|
133280
133330
|
}
|
|
133281
133331
|
};
|
|
133282
|
-
|
|
133332
|
+
logLine(
|
|
133283
133333
|
`[worker-gate] active \u2014 1:1 owner DM: FULL access, no allowlist, no workspace fence. Armed room: FULL access whenever "Remove all gates" is on (live, owner-controlled, off by default); otherwise allowlist, workspace=${this.opts.workspaceDir ?? "(none: file tools disabled)"}, bash=${this.opts.osIsolated ? "enabled (OS-isolated)" : "disabled"}`
|
|
133284
133334
|
);
|
|
133285
133335
|
return {
|
|
@@ -133320,7 +133370,19 @@ var PersistentClaudeSession = class {
|
|
|
133320
133370
|
this.roomServer = _s({
|
|
133321
133371
|
name: "room",
|
|
133322
133372
|
version: "0.2.0",
|
|
133323
|
-
tools: [makeRoomSayTool((text) => this.deliver(text))]
|
|
133373
|
+
tools: [makeRoomSayTool((text) => this.deliver(text))],
|
|
133374
|
+
// LOAD-BEARING for turn latency. The SDK defers MCP tools behind tool
|
|
133375
|
+
// search by default, so the WORKER (which gets the full built-in toolset
|
|
133376
|
+
// for owner DMs) could not see its own voice without first spending a
|
|
133377
|
+
// model round-trip on `ToolSearch {"query":"select:mcp__room__say"}` —
|
|
133378
|
+
// measured on 175 of 175 worker sessions, ~2-5s of a ~20s turn, for a tool
|
|
133379
|
+
// already in `allowedTools`. The listener escaped it only by accident, via
|
|
133380
|
+
// `tools: []`. Set on BOTH lanes so the listener stays correct if its
|
|
133381
|
+
// toolset ever widens.
|
|
133382
|
+
//
|
|
133383
|
+
// NOT a permission change: room_say is already allowed on every session.
|
|
133384
|
+
// This stops HIDING it, it does not grant it.
|
|
133385
|
+
alwaysLoad: true
|
|
133324
133386
|
});
|
|
133325
133387
|
const sdkOptions = this.buildSdkOptions();
|
|
133326
133388
|
const q10 = this.opts.queryImpl ? this.opts.queryImpl({
|
|
@@ -133346,7 +133408,7 @@ var PersistentClaudeSession = class {
|
|
|
133346
133408
|
if (reply) {
|
|
133347
133409
|
void reply(this.turnText);
|
|
133348
133410
|
} else {
|
|
133349
|
-
|
|
133411
|
+
logLine(
|
|
133350
133412
|
`[drop-probe] BLOCKED at result: composed ${this.turnText.length} chars, reply expected but activeReply unset \u2014 reply DROPPED`
|
|
133351
133413
|
);
|
|
133352
133414
|
}
|
|
@@ -133355,7 +133417,7 @@ var PersistentClaudeSession = class {
|
|
|
133355
133417
|
}
|
|
133356
133418
|
} finally {
|
|
133357
133419
|
if (this.currentReplyExpected && !this.saidThisTurn && !this.sawResultThisTurn && this.turnText.trim()) {
|
|
133358
|
-
|
|
133420
|
+
logLine(
|
|
133359
133421
|
`[drop-probe] STREAM ENDED before result: composed ${this.turnText.length} chars, reply expected, said=false \u2014 reply DROPPED (no result event)`
|
|
133360
133422
|
);
|
|
133361
133423
|
}
|
|
@@ -133398,6 +133460,16 @@ var WorkerQueue = class {
|
|
|
133398
133460
|
this.running = false;
|
|
133399
133461
|
}
|
|
133400
133462
|
}
|
|
133463
|
+
/**
|
|
133464
|
+
* What the worker had produced, when the session can report it. Read on BOTH the
|
|
133465
|
+
* clean and the failing path: on a clean turn `said: false` with a non-zero
|
|
133466
|
+
* `composedChars` is the "composed but could never ship it" signature (agent-
|
|
133467
|
+
* authored room traffic, where `replyExpected` is false), which is otherwise
|
|
133468
|
+
* indistinguishable from a turn that did nothing.
|
|
133469
|
+
*/
|
|
133470
|
+
snapshotOf(session) {
|
|
133471
|
+
return session?.snapshot?.();
|
|
133472
|
+
}
|
|
133401
133473
|
/** Best-effort trap emit. A broken sink must never break the queue. */
|
|
133402
133474
|
emitIncident(rec) {
|
|
133403
133475
|
try {
|
|
@@ -133429,10 +133501,23 @@ var WorkerQueue = class {
|
|
|
133429
133501
|
}, this.deps.timeoutMs);
|
|
133430
133502
|
});
|
|
133431
133503
|
await Promise.race([session.start(), timeout]);
|
|
133504
|
+
const okSnap = this.snapshotOf(session);
|
|
133505
|
+
this.emitIncident({
|
|
133506
|
+
at: new Date(startedAt).toISOString(),
|
|
133507
|
+
outcome: "ok",
|
|
133508
|
+
waitedMs,
|
|
133509
|
+
ranMs: Date.now() - startedAt,
|
|
133510
|
+
timeoutMs: this.deps.timeoutMs,
|
|
133511
|
+
queueDepthAtEnqueue: entry.queueDepthAtEnqueue,
|
|
133512
|
+
queueDepthAtStart,
|
|
133513
|
+
instructionChars: task.instruction.length,
|
|
133514
|
+
replyExpected: task.replyExpected,
|
|
133515
|
+
...okSnap ? { session: okSnap } : {}
|
|
133516
|
+
});
|
|
133432
133517
|
} catch (e7) {
|
|
133433
133518
|
const err = e7;
|
|
133434
133519
|
this.deps.log(`[worker-queue] task failed: ${err.message}`);
|
|
133435
|
-
const snap = session
|
|
133520
|
+
const snap = this.snapshotOf(session);
|
|
133436
133521
|
this.emitIncident({
|
|
133437
133522
|
at: new Date(startedAt).toISOString(),
|
|
133438
133523
|
outcome: timedOut ? "timeout" : "error",
|
|
@@ -133443,6 +133528,7 @@ var WorkerQueue = class {
|
|
|
133443
133528
|
queueDepthAtEnqueue: entry.queueDepthAtEnqueue,
|
|
133444
133529
|
queueDepthAtStart,
|
|
133445
133530
|
instructionChars: task.instruction.length,
|
|
133531
|
+
replyExpected: task.replyExpected,
|
|
133446
133532
|
...snap ? { session: snap } : {}
|
|
133447
133533
|
});
|
|
133448
133534
|
session?.abort();
|
|
@@ -133464,7 +133550,7 @@ function makeRouter(deps) {
|
|
|
133464
133550
|
const replySink = reply ?? (() => {
|
|
133465
133551
|
});
|
|
133466
133552
|
const isOwnerDm = opts?.autoReplyOnText === true && opts?.armed === void 0 && deps.workAllowed();
|
|
133467
|
-
const isArmedRoom = opts?.armed?.() === true && deps.workAllowed();
|
|
133553
|
+
const isArmedRoom = opts?.armed?.() === true && deps.workAllowed() && opts?.replyExpected !== false;
|
|
133468
133554
|
if (isOwnerDm) {
|
|
133469
133555
|
deps.queue.enqueue({
|
|
133470
133556
|
instruction: text,
|
|
@@ -134023,22 +134109,22 @@ async function main() {
|
|
|
134023
134109
|
const cfg = loadConfig(process.env, process.argv.slice(2));
|
|
134024
134110
|
const firstArg = process.argv.slice(2)[0];
|
|
134025
134111
|
if (firstArg && !firstArg.startsWith("-") && firstArg === cfg.inviteToken) {
|
|
134026
|
-
|
|
134112
|
+
logLine(
|
|
134027
134113
|
"[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
134114
|
);
|
|
134029
134115
|
}
|
|
134030
|
-
|
|
134031
|
-
|
|
134032
|
-
|
|
134116
|
+
logLine(`[bridge] version: ${true ? "0.7.8" : "dev"}`);
|
|
134117
|
+
logLine(`[bridge] data dir: ${cfg.dataDir} (${cfg.dataDirSource})`);
|
|
134118
|
+
logLine(`[bridge] workspace: ${cfg.workspaceDir} \xB7 permissions: ${cfg.permissionMode} \xB7 enclave dir fenced`);
|
|
134033
134119
|
if (cfg.armRoom) {
|
|
134034
|
-
|
|
134120
|
+
logLine(
|
|
134035
134121
|
`[bridge] ARMED ROOM ${cfg.roomFilter} \u2014 worker tools are enabled on this room's turns. The enclave key dir stays fenced; the workspace dir is ADVISORY (the SDK does not confine file ops to it \u2014 they root in $HOME). Blast radius = whatever this host/environment exposes.`
|
|
134036
134122
|
);
|
|
134037
|
-
|
|
134123
|
+
logLine(
|
|
134038
134124
|
"[bridge] ARMED ROOM WARNING: this room contains agents you do not control. A room peer's message can drive your agent's tools. The directory is NOT a sandbox \u2014 run this bridge in an owner-provisioned confined environment (dedicated droplet / container / OS-user) with no connected accounts or ambient credentials. See the Slice 2 hardening guide."
|
|
134039
134125
|
);
|
|
134040
134126
|
} else {
|
|
134041
|
-
|
|
134127
|
+
logLine(
|
|
134042
134128
|
'[bridge] 1:1 owner DMs run with FULL tool access when "Allow tools" is on for this agent (dashboard switch, default off): any command, any file this user account can reach, network, skills and subagents \u2014 equivalent to a terminal on this machine, with no per-action prompt. Rooms are NOT affected: they stay say-only unless armed (AV_ARM_ROOM=1 with a pinned AV_ROOM_ID), and an armed room keeps the confined allowlist. Each tool-enabled turn runs in a fresh session seeded with only that one message, so room text cannot leak into a DM turn.'
|
|
134043
134129
|
);
|
|
134044
134130
|
}
|
|
@@ -134069,7 +134155,7 @@ async function main() {
|
|
|
134069
134155
|
// per-message binding is what prevents a private 1:1 reply from leaking into a
|
|
134070
134156
|
// room when room traffic arrives mid-compose.
|
|
134071
134157
|
// Assistant reasoning that wasn't sent — log a short trace only.
|
|
134072
|
-
onObserve: (text) =>
|
|
134158
|
+
onObserve: (text) => logLine(`[bridge] observed (${text.length} chars, not sent)`),
|
|
134073
134159
|
worker: false
|
|
134074
134160
|
});
|
|
134075
134161
|
const WORKER_MAX_TURNS = 20;
|
|
@@ -134078,7 +134164,7 @@ async function main() {
|
|
|
134078
134164
|
makeSession: (task) => new PersistentClaudeSession({
|
|
134079
134165
|
model: cfg.model,
|
|
134080
134166
|
systemPrompt: agentSystemPrompt,
|
|
134081
|
-
onObserve: (text) =>
|
|
134167
|
+
onObserve: (text) => logLine(`[worker] observed (${text.length} chars, not sent)`),
|
|
134082
134168
|
worker: true,
|
|
134083
134169
|
// Task 4: the hard backstop — no tool runs on any worker turn (owner DM or
|
|
134084
134170
|
// armed room) unless Work is on. Read live per tool decision.
|
|
@@ -134101,7 +134187,7 @@ async function main() {
|
|
|
134101
134187
|
deviceJwt
|
|
134102
134188
|
}),
|
|
134103
134189
|
timeoutMs: WORKER_TIMEOUT_MS,
|
|
134104
|
-
log: (m6) =>
|
|
134190
|
+
log: (m6) => logLine(m6),
|
|
134105
134191
|
// TRAP (2026-07-25). The 07-24 five-minute silence was diagnosable only by
|
|
134106
134192
|
// luck — the drop-trap happened to record a reply landing 300.016s after the
|
|
134107
134193
|
// ack, and 300s is WORKER_TIMEOUT_MS exactly. Nothing recorded WHY the worker
|
|
@@ -134109,15 +134195,15 @@ async function main() {
|
|
|
134109
134195
|
// Append-only JSONL beside the logs, plus one stamped console line so the
|
|
134110
134196
|
// incident is visible in bridge.error.log at the moment it happens.
|
|
134111
134197
|
onIncident: (rec) => {
|
|
134112
|
-
|
|
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}` : "")
|
|
134198
|
+
logLine(
|
|
134199
|
+
`[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
134200
|
);
|
|
134115
134201
|
try {
|
|
134116
134202
|
const dir = join11(cfg.dataDir, "logs");
|
|
134117
134203
|
mkdirSync6(dir, { recursive: true });
|
|
134118
134204
|
appendFileSync2(join11(dir, "worker-incidents.jsonl"), JSON.stringify(rec) + "\n");
|
|
134119
134205
|
} catch (err) {
|
|
134120
|
-
|
|
134206
|
+
logLine(`[worker-trap] could not persist incident: ${err.message}`);
|
|
134121
134207
|
}
|
|
134122
134208
|
}
|
|
134123
134209
|
});
|
|
@@ -134129,7 +134215,7 @@ async function main() {
|
|
|
134129
134215
|
{
|
|
134130
134216
|
roomFilter: cfg.roomFilter,
|
|
134131
134217
|
armRoom: cfg.armRoom,
|
|
134132
|
-
log: (m6) =>
|
|
134218
|
+
log: (m6) => logLine("[bridge] " + m6),
|
|
134133
134219
|
// Slice 2 Plan C (T11): live arm/disarm + local-approval poll + heartbeat.
|
|
134134
134220
|
workspaceDir: cfg.workspaceDir,
|
|
134135
134221
|
dataDir: cfg.dataDir,
|
|
@@ -134145,21 +134231,21 @@ async function main() {
|
|
|
134145
134231
|
}
|
|
134146
134232
|
);
|
|
134147
134233
|
attachLifecycle2(channel, {
|
|
134148
|
-
log: (m6) =>
|
|
134234
|
+
log: (m6) => logLine("[bridge] " + m6)
|
|
134149
134235
|
});
|
|
134150
|
-
channel.on("state", (s10) =>
|
|
134236
|
+
channel.on("state", (s10) => logLine(`[bridge] channel state: ${JSON.stringify(s10)}`));
|
|
134151
134237
|
channel.on(
|
|
134152
134238
|
"room_joined",
|
|
134153
|
-
(e7) =>
|
|
134239
|
+
(e7) => logLine(`[bridge] joined room ${e7.name} (${e7.roomId})`)
|
|
134154
134240
|
);
|
|
134155
134241
|
listener.start().catch((err) => {
|
|
134156
|
-
|
|
134242
|
+
logLine("[bridge] fatal:", err);
|
|
134157
134243
|
process.exit(1);
|
|
134158
134244
|
});
|
|
134159
134245
|
await channel.start();
|
|
134160
134246
|
}
|
|
134161
134247
|
main().catch((err) => {
|
|
134162
|
-
|
|
134248
|
+
logLine("[bridge] fatal:", err);
|
|
134163
134249
|
process.exit(1);
|
|
134164
134250
|
});
|
|
134165
134251
|
/*! Bundled license information:
|
package/dist/log.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prefix every line of `message` with an ISO-8601 UTC timestamp.
|
|
3
|
+
*
|
|
4
|
+
* Per-LINE, not per-call, on purpose: `logLine("[bridge] fatal:", err)` renders a
|
|
5
|
+
* multi-line stack trace, and a first-line-only stamp would leave every frame
|
|
6
|
+
* unanchored — the case where the clock matters most. The acceptance criterion
|
|
7
|
+
* on #790 is "every line in the file", so this reads it literally.
|
|
8
|
+
*/
|
|
9
|
+
export declare function stamp(message: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Write one stamped record to stderr.
|
|
12
|
+
*
|
|
13
|
+
* stderr (not stdout) because the launchd/systemd unit routes both, and the
|
|
14
|
+
* bridge's existing sinks were already `console.error` — keeping the stream the
|
|
15
|
+
* same means this change alters the CONTENT of the logs and nothing else.
|
|
16
|
+
*
|
|
17
|
+
* Multi-arg is supported via `util.format`, which is what `console.error` uses
|
|
18
|
+
* internally, so `logLine("[bridge] fatal:", err)` renders exactly as before —
|
|
19
|
+
* just anchored to a clock.
|
|
20
|
+
*/
|
|
21
|
+
export declare function logLine(...args: unknown[]): void;
|
|
22
|
+
//# sourceMappingURL=log.d.ts.map
|
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,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentvault/claude-bridge",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.8",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "AgentVault Claude Bridge
|
|
5
|
+
"description": "AgentVault Claude Bridge \u2014 daemon for bridging a Claude agent into secure E2E-encrypted AgentVault 1:1 direct messages and rooms.",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"bin": {
|