@agentvault/claude-bridge 0.7.7 → 0.7.9

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 CHANGED
@@ -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(format, key, isPublic = true) {
53077
- return await this._prim.importKey(format, key, isPublic);
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(format, key, isPublic) {
53720
+ async importKey(format2, key, isPublic) {
53721
53721
  await this._setup();
53722
53722
  try {
53723
- if (format === "raw") {
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(format, key, isPublic) {
55110
+ async importKey(format2, key, isPublic) {
55111
55111
  await this._setup();
55112
55112
  try {
55113
- if (format === "raw") {
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(format) {
60049
- if (!["compact", "recovered", "der"].includes(format))
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 format;
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, format) {
60740
- validateSigFormat(format);
60739
+ function validateSigLength(bytes, format2) {
60740
+ validateSigFormat(format2);
60741
60741
  const size = lengths.signature;
60742
- const sizer = format === "compact" ? size : format === "recovered" ? size + 1 : void 0;
60743
- return _abytes2(bytes, sizer, `${format} signature`);
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, format = defaultSigOpts_format) {
60754
- validateSigLength(bytes, format);
60753
+ static fromBytes(bytes, format2 = defaultSigOpts_format) {
60754
+ validateSigLength(bytes, format2);
60755
60755
  let recid;
60756
- if (format === "der") {
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 (format === "recovered") {
60760
+ if (format2 === "recovered") {
60761
60761
  recid = bytes[0];
60762
- format = "compact";
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, format) {
60771
- return this.fromBytes(hexToBytes4(hex32), format);
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(format = defaultSigOpts_format) {
60804
- validateSigFormat(format);
60805
- if (format === "der")
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 (format === "recovered") {
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(format) {
60817
- return bytesToHex4(this.toBytes(format));
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 = format === void 0 ? tryParsingSig(signature) : Signature.fromBytes(ensureBytes("sig", signature), format);
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 {
@@ -80864,13 +80864,13 @@ function _stringbool(Classes, _params) {
80864
80864
  return codec22;
80865
80865
  }
80866
80866
  // @__NO_SIDE_EFFECTS__
80867
- function _stringFormat(Class22, format, fnOrRegex, _params = {}) {
80867
+ function _stringFormat(Class22, format2, fnOrRegex, _params = {}) {
80868
80868
  const params = normalizeParams(_params);
80869
80869
  const def = {
80870
80870
  ...normalizeParams(_params),
80871
80871
  check: "string_format",
80872
80872
  type: "string",
80873
- format,
80873
+ format: format2,
80874
80874
  fn: typeof fnOrRegex === "function" ? fnOrRegex : (val) => fnOrRegex.test(val),
80875
80875
  ...params
80876
80876
  };
@@ -81335,16 +81335,16 @@ var init_json_schema_processors = __esm2({
81335
81335
  stringProcessor = (schema, ctx, _json, _params) => {
81336
81336
  const json22 = _json;
81337
81337
  json22.type = "string";
81338
- const { minimum, maximum, format, patterns, contentEncoding } = schema._zod.bag;
81338
+ const { minimum, maximum, format: format2, patterns, contentEncoding } = schema._zod.bag;
81339
81339
  if (typeof minimum === "number")
81340
81340
  json22.minLength = minimum;
81341
81341
  if (typeof maximum === "number")
81342
81342
  json22.maxLength = maximum;
81343
- if (format) {
81344
- json22.format = formatMap[format] ?? format;
81343
+ if (format2) {
81344
+ json22.format = formatMap[format2] ?? format2;
81345
81345
  if (json22.format === "")
81346
81346
  delete json22.format;
81347
- if (format === "time") {
81347
+ if (format2 === "time") {
81348
81348
  delete json22.format;
81349
81349
  }
81350
81350
  }
@@ -81366,8 +81366,8 @@ var init_json_schema_processors = __esm2({
81366
81366
  };
81367
81367
  numberProcessor = (schema, ctx, _json, _params) => {
81368
81368
  const json22 = _json;
81369
- const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
81370
- if (typeof format === "string" && format.includes("int"))
81369
+ const { minimum, maximum, format: format2, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
81370
+ if (typeof format2 === "string" && format2.includes("int"))
81371
81371
  json22.type = "integer";
81372
81372
  else
81373
81373
  json22.type = "number";
@@ -82522,8 +82522,8 @@ function e1642(params) {
82522
82522
  function jwt(params) {
82523
82523
  return /* @__PURE__ */ _jwt(ZodJWT, params);
82524
82524
  }
82525
- function stringFormat(format, fnOrRegex, _params = {}) {
82526
- return /* @__PURE__ */ _stringFormat(ZodCustomStringFormat, format, fnOrRegex, _params);
82525
+ function stringFormat(format2, fnOrRegex, _params = {}) {
82526
+ return /* @__PURE__ */ _stringFormat(ZodCustomStringFormat, format2, fnOrRegex, _params);
82527
82527
  }
82528
82528
  function hostname2(_params) {
82529
82529
  return /* @__PURE__ */ _stringFormat(ZodCustomStringFormat, "hostname", regexes_exports.hostname, _params);
@@ -82533,11 +82533,11 @@ function hex2(_params) {
82533
82533
  }
82534
82534
  function hash(alg, params) {
82535
82535
  const enc = params?.enc ?? "hex";
82536
- const format = `${alg}_${enc}`;
82537
- const regex = regexes_exports[format];
82536
+ const format2 = `${alg}_${enc}`;
82537
+ const regex = regexes_exports[format2];
82538
82538
  if (!regex)
82539
- throw new Error(`Unrecognized hash format: ${format}`);
82540
- return /* @__PURE__ */ _stringFormat(ZodCustomStringFormat, format, regex, params);
82539
+ throw new Error(`Unrecognized hash format: ${format2}`);
82540
+ return /* @__PURE__ */ _stringFormat(ZodCustomStringFormat, format2, regex, params);
82541
82541
  }
82542
82542
  function number2(params) {
82543
82543
  return /* @__PURE__ */ _number(ZodNumber2, params);
@@ -92020,10 +92020,10 @@ var require_core = __commonJS({
92020
92020
  return this;
92021
92021
  }
92022
92022
  // Add format
92023
- addFormat(name, format) {
92024
- if (typeof format == "string")
92025
- format = new RegExp(format);
92026
- this.formats[name] = format;
92023
+ addFormat(name, format2) {
92024
+ if (typeof format2 == "string")
92025
+ format2 = new RegExp(format2);
92026
+ this.formats[name] = format2;
92027
92027
  return this;
92028
92028
  }
92029
92029
  errorsText(errors = this.errors, { separator = ", ", dataVar = "data" } = {}) {
@@ -92141,9 +92141,9 @@ var require_core = __commonJS({
92141
92141
  }
92142
92142
  function addInitialFormats() {
92143
92143
  for (const name in this.opts.formats) {
92144
- const format = this.opts.formats[name];
92145
- if (format)
92146
- this.addFormat(name, format);
92144
+ const format2 = this.opts.formats[name];
92145
+ if (format2)
92146
+ this.addFormat(name, format2);
92147
92147
  }
92148
92148
  }
92149
92149
  function addInitialKeywords(defs) {
@@ -93758,18 +93758,18 @@ var require_format = __commonJS({
93758
93758
  });
93759
93759
  const fDef = gen.const("fDef", (0, codegen_1._)`${fmts}[${schemaCode}]`);
93760
93760
  const fType = gen.let("fType");
93761
- const format = 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(format, (0, codegen_1._)`${fDef}.validate`), () => gen.assign(fType, (0, codegen_1._)`"string"`).assign(format, fDef));
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));
93763
93763
  cxt.fail$data((0, codegen_1.or)(unknownFmt(), invalidFmt()));
93764
93764
  function unknownFmt() {
93765
93765
  if (opts.strictSchema === false)
93766
93766
  return codegen_1.nil;
93767
- return (0, codegen_1._)`${schemaCode} && !${format}`;
93767
+ return (0, codegen_1._)`${schemaCode} && !${format2}`;
93768
93768
  }
93769
93769
  function invalidFmt() {
93770
- const callFormat = schemaEnv.$async ? (0, codegen_1._)`(${fDef}.async ? await ${format}(${data}) : ${format}(${data}))` : (0, codegen_1._)`${format}(${data})`;
93771
- const validData = (0, codegen_1._)`(typeof ${format} == "function" ? ${callFormat} : ${format}.test(${data}))`;
93772
- return (0, codegen_1._)`${format} && ${format} !== true && ${fType} === ${ruleType} && !${validData}`;
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}`;
93773
93773
  }
93774
93774
  }
93775
93775
  function validateFormat() {
@@ -93780,7 +93780,7 @@ var require_format = __commonJS({
93780
93780
  }
93781
93781
  if (formatDef === true)
93782
93782
  return;
93783
- const [fmtType, format, fmtRef] = getFormat(formatDef);
93783
+ const [fmtType, format2, fmtRef] = getFormat(formatDef);
93784
93784
  if (fmtType === ruleType)
93785
93785
  cxt.pass(validCondition());
93786
93786
  function unknownFormat() {
@@ -93807,7 +93807,7 @@ var require_format = __commonJS({
93807
93807
  throw new Error("async format in sync schema");
93808
93808
  return (0, codegen_1._)`await ${fmtRef}(${data})`;
93809
93809
  }
93810
- return typeof format == "function" ? (0, codegen_1._)`${fmtRef}(${data})` : (0, codegen_1._)`${fmtRef}.test(${data})`;
93810
+ return typeof format2 == "function" ? (0, codegen_1._)`${fmtRef}(${data})` : (0, codegen_1._)`${fmtRef}.test(${data})`;
93811
93811
  }
93812
93812
  }
93813
93813
  }
@@ -93820,8 +93820,8 @@ var require_format2 = __commonJS({
93820
93820
  "use strict";
93821
93821
  Object.defineProperty(exports, "__esModule", { value: true });
93822
93822
  var format_1 = require_format();
93823
- var format = [format_1.default];
93824
- exports.default = format;
93823
+ var format2 = [format_1.default];
93824
+ exports.default = format2;
93825
93825
  }
93826
93826
  });
93827
93827
  var require_metadata = __commonJS({
@@ -94447,17 +94447,17 @@ var require_limit = __commonJS({
94447
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)));
94448
94448
  }
94449
94449
  function validateFormat() {
94450
- const format = fCxt.schema;
94451
- const fmtDef = self2.formats[format];
94450
+ const format2 = fCxt.schema;
94451
+ const fmtDef = self2.formats[format2];
94452
94452
  if (!fmtDef || fmtDef === true)
94453
94453
  return;
94454
94454
  if (typeof fmtDef != "object" || fmtDef instanceof RegExp || typeof fmtDef.compare != "function") {
94455
- throw new Error(`"${keyword}": format "${format}" does not define "compare" function`);
94455
+ throw new Error(`"${keyword}": format "${format2}" does not define "compare" function`);
94456
94456
  }
94457
94457
  const fmt = gen.scopeValue("formats", {
94458
- key: format,
94458
+ key: format2,
94459
94459
  ref: fmtDef,
94460
- code: opts.code.formats ? (0, codegen_1._)`${opts.code.formats}${(0, codegen_1.getProperty)(format)}` : void 0
94460
+ code: opts.code.formats ? (0, codegen_1._)`${opts.code.formats}${(0, codegen_1.getProperty)(format2)}` : void 0
94461
94461
  });
94462
94462
  cxt.fail$data(compareCode(fmt));
94463
94463
  }
@@ -119180,6 +119180,16 @@ function readDeviceId(dataDir) {
119180
119180
  );
119181
119181
  }
119182
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
+
119183
119193
  // src/worker-permission.ts
119184
119194
  var PATH_FIELDS = ["file_path", "path", "notebook_path"];
119185
119195
  function canonical(p2) {
@@ -119286,7 +119296,7 @@ function makeWorkerPreToolUseHook(opts) {
119286
119296
  }
119287
119297
  }
119288
119298
  if (verdict.deny) {
119289
- console.error(`[worker-gate] DENY ${toolName} \u2014 ${verdict.reason}`);
119299
+ logLine(`[worker-gate] DENY ${toolName} \u2014 ${verdict.reason}`);
119290
119300
  return {
119291
119301
  hookSpecificOutput: {
119292
119302
  hookEventName: "PreToolUse",
@@ -119304,7 +119314,7 @@ function makeWorkerPermission(opts) {
119304
119314
  return async (toolName, input) => {
119305
119315
  const verdict = gateDecision(toolName, input, opts);
119306
119316
  if (verdict.deny) {
119307
- console.error(`[worker-gate] DENY ${toolName} \u2014 ${verdict.reason}`);
119317
+ logLine(`[worker-gate] DENY ${toolName} \u2014 ${verdict.reason}`);
119308
119318
  return { behavior: "deny", message: verdict.reason };
119309
119319
  }
119310
119320
  return { behavior: "allow", updatedInput: input };
@@ -130202,13 +130212,13 @@ function _stringbool2(Classes, _params) {
130202
130212
  return codec3;
130203
130213
  }
130204
130214
  // @__NO_SIDE_EFFECTS__
130205
- function _stringFormat2(Class3, format, fnOrRegex, _params = {}) {
130215
+ function _stringFormat2(Class3, format2, fnOrRegex, _params = {}) {
130206
130216
  const params = normalizeParams2(_params);
130207
130217
  const def = {
130208
130218
  ...normalizeParams2(_params),
130209
130219
  check: "string_format",
130210
130220
  type: "string",
130211
- format,
130221
+ format: format2,
130212
130222
  fn: typeof fnOrRegex === "function" ? fnOrRegex : (val) => fnOrRegex.test(val),
130213
130223
  ...params
130214
130224
  };
@@ -130583,16 +130593,16 @@ var formatMap2 = {
130583
130593
  var stringProcessor2 = (schema, ctx, _json, _params) => {
130584
130594
  const json3 = _json;
130585
130595
  json3.type = "string";
130586
- const { minimum, maximum, format, patterns, contentEncoding } = schema._zod.bag;
130596
+ const { minimum, maximum, format: format2, patterns, contentEncoding } = schema._zod.bag;
130587
130597
  if (typeof minimum === "number")
130588
130598
  json3.minLength = minimum;
130589
130599
  if (typeof maximum === "number")
130590
130600
  json3.maxLength = maximum;
130591
- if (format) {
130592
- json3.format = formatMap2[format] ?? format;
130601
+ if (format2) {
130602
+ json3.format = formatMap2[format2] ?? format2;
130593
130603
  if (json3.format === "")
130594
130604
  delete json3.format;
130595
- if (format === "time") {
130605
+ if (format2 === "time") {
130596
130606
  delete json3.format;
130597
130607
  }
130598
130608
  }
@@ -130614,8 +130624,8 @@ var stringProcessor2 = (schema, ctx, _json, _params) => {
130614
130624
  };
130615
130625
  var numberProcessor2 = (schema, ctx, _json, _params) => {
130616
130626
  const json3 = _json;
130617
- const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
130618
- if (typeof format === "string" && format.includes("int"))
130627
+ const { minimum, maximum, format: format2, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
130628
+ if (typeof format2 === "string" && format2.includes("int"))
130619
130629
  json3.type = "integer";
130620
130630
  else
130621
130631
  json3.type = "number";
@@ -131804,8 +131814,8 @@ var ZodCustomStringFormat2 = /* @__PURE__ */ $constructor2("ZodCustomStringForma
131804
131814
  $ZodCustomStringFormat2.init(inst, def);
131805
131815
  ZodStringFormat2.init(inst, def);
131806
131816
  });
131807
- function stringFormat2(format, fnOrRegex, _params = {}) {
131808
- return _stringFormat2(ZodCustomStringFormat2, format, fnOrRegex, _params);
131817
+ function stringFormat2(format2, fnOrRegex, _params = {}) {
131818
+ return _stringFormat2(ZodCustomStringFormat2, format2, fnOrRegex, _params);
131809
131819
  }
131810
131820
  function hostname5(_params) {
131811
131821
  return _stringFormat2(ZodCustomStringFormat2, "hostname", regexes_exports2.hostname, _params);
@@ -131815,11 +131825,11 @@ function hex4(_params) {
131815
131825
  }
131816
131826
  function hash2(alg, params) {
131817
131827
  const enc = params?.enc ?? "hex";
131818
- const format = `${alg}_${enc}`;
131819
- const regex = regexes_exports2[format];
131828
+ const format2 = `${alg}_${enc}`;
131829
+ const regex = regexes_exports2[format2];
131820
131830
  if (!regex)
131821
- throw new Error(`Unrecognized hash format: ${format}`);
131822
- return _stringFormat2(ZodCustomStringFormat2, format, regex, params);
131831
+ throw new Error(`Unrecognized hash format: ${format2}`);
131832
+ return _stringFormat2(ZodCustomStringFormat2, format2, regex, params);
131823
131833
  }
131824
131834
  var ZodNumber3 = /* @__PURE__ */ $constructor2("ZodNumber", (inst, def) => {
131825
131835
  $ZodNumber2.init(inst, def);
@@ -132795,52 +132805,52 @@ function convertBaseSchema(schema, ctx) {
132795
132805
  case "string": {
132796
132806
  let stringSchema = z4.string();
132797
132807
  if (schema.format) {
132798
- const format = schema.format;
132799
- if (format === "email") {
132808
+ const format2 = schema.format;
132809
+ if (format2 === "email") {
132800
132810
  stringSchema = stringSchema.check(z4.email());
132801
- } else if (format === "uri" || format === "uri-reference") {
132811
+ } else if (format2 === "uri" || format2 === "uri-reference") {
132802
132812
  stringSchema = stringSchema.check(z4.url());
132803
- } else if (format === "uuid" || format === "guid") {
132813
+ } else if (format2 === "uuid" || format2 === "guid") {
132804
132814
  stringSchema = stringSchema.check(z4.uuid());
132805
- } else if (format === "date-time") {
132815
+ } else if (format2 === "date-time") {
132806
132816
  stringSchema = stringSchema.check(z4.iso.datetime());
132807
- } else if (format === "date") {
132817
+ } else if (format2 === "date") {
132808
132818
  stringSchema = stringSchema.check(z4.iso.date());
132809
- } else if (format === "time") {
132819
+ } else if (format2 === "time") {
132810
132820
  stringSchema = stringSchema.check(z4.iso.time());
132811
- } else if (format === "duration") {
132821
+ } else if (format2 === "duration") {
132812
132822
  stringSchema = stringSchema.check(z4.iso.duration());
132813
- } else if (format === "ipv4") {
132823
+ } else if (format2 === "ipv4") {
132814
132824
  stringSchema = stringSchema.check(z4.ipv4());
132815
- } else if (format === "ipv6") {
132825
+ } else if (format2 === "ipv6") {
132816
132826
  stringSchema = stringSchema.check(z4.ipv6());
132817
- } else if (format === "mac") {
132827
+ } else if (format2 === "mac") {
132818
132828
  stringSchema = stringSchema.check(z4.mac());
132819
- } else if (format === "cidr") {
132829
+ } else if (format2 === "cidr") {
132820
132830
  stringSchema = stringSchema.check(z4.cidrv4());
132821
- } else if (format === "cidr-v6") {
132831
+ } else if (format2 === "cidr-v6") {
132822
132832
  stringSchema = stringSchema.check(z4.cidrv6());
132823
- } else if (format === "base64") {
132833
+ } else if (format2 === "base64") {
132824
132834
  stringSchema = stringSchema.check(z4.base64());
132825
- } else if (format === "base64url") {
132835
+ } else if (format2 === "base64url") {
132826
132836
  stringSchema = stringSchema.check(z4.base64url());
132827
- } else if (format === "e164") {
132837
+ } else if (format2 === "e164") {
132828
132838
  stringSchema = stringSchema.check(z4.e164());
132829
- } else if (format === "jwt") {
132839
+ } else if (format2 === "jwt") {
132830
132840
  stringSchema = stringSchema.check(z4.jwt());
132831
- } else if (format === "emoji") {
132841
+ } else if (format2 === "emoji") {
132832
132842
  stringSchema = stringSchema.check(z4.emoji());
132833
- } else if (format === "nanoid") {
132843
+ } else if (format2 === "nanoid") {
132834
132844
  stringSchema = stringSchema.check(z4.nanoid());
132835
- } else if (format === "cuid") {
132845
+ } else if (format2 === "cuid") {
132836
132846
  stringSchema = stringSchema.check(z4.cuid());
132837
- } else if (format === "cuid2") {
132847
+ } else if (format2 === "cuid2") {
132838
132848
  stringSchema = stringSchema.check(z4.cuid2());
132839
- } else if (format === "ulid") {
132849
+ } else if (format2 === "ulid") {
132840
132850
  stringSchema = stringSchema.check(z4.ulid());
132841
- } else if (format === "xid") {
132851
+ } else if (format2 === "xid") {
132842
132852
  stringSchema = stringSchema.check(z4.xid());
132843
- } else if (format === "ksuid") {
132853
+ } else if (format2 === "ksuid") {
132844
132854
  stringSchema = stringSchema.check(z4.ksuid());
132845
132855
  }
132846
132856
  }
@@ -133165,6 +133175,28 @@ var PersistentClaudeSession = class {
133165
133175
  * #416 fallback delivery (which delivers via `void reply(...)` WITHOUT setting
133166
133176
  * saidThisTurn, so !saidThisTurn alone would false-flag it). */
133167
133177
  sawResultThisTurn = false;
133178
+ /**
133179
+ * Per-turn telemetry lifted off the SDK's `result` message.
133180
+ *
133181
+ * The message arrives on EVERY turn and we kept one boolean from it
133182
+ * (`sawResultThisTurn`), discarding the rest. That is the #791 shape: data
133183
+ * delivered on the healthy path that nothing reads.
133184
+ *
133185
+ * It costs us a real answer. A turn that produced nothing (`composed=0,
133186
+ * said=false`) could be the model choosing silence, the turn cap being hit, or
133187
+ * the provider returning 429 — three different bugs with one symptom, and
133188
+ * `subtype`/`apiErrorStatus` are what separate them. 4 of 12 turns on
133189
+ * 2026-08-07 were silent and could not be attributed.
133190
+ *
133191
+ * `durationApiMs` vs `durationMs` also gives the model-time / SDK-overhead
133192
+ * split directly. That split previously had to be reconstructed by joining
133193
+ * `WorkerIncident.ranMs` against SDK transcripts on disk by wall clock.
133194
+ *
133195
+ * Every field is OPTIONAL and left undefined when no result arrives (abort or
133196
+ * crash mid-turn): absent must read as absent, never as a zero that looks like
133197
+ * a real measurement.
133198
+ */
133199
+ resultTelemetry = {};
133168
133200
  /** In-process room MCP server — hoisted so buildSdkOptions can reference it. */
133169
133201
  roomServer;
133170
133202
  /** AbortController for the in-flight query(); abort() triggers it (queue timeout). */
@@ -133229,7 +133261,8 @@ var PersistentClaudeSession = class {
133229
133261
  return {
133230
133262
  composedChars: this.turnText.length,
133231
133263
  sawResult: this.sawResultThisTurn,
133232
- said: this.saidThisTurn
133264
+ said: this.saidThisTurn,
133265
+ ...this.resultTelemetry
133233
133266
  };
133234
133267
  }
133235
133268
  async *input() {
@@ -133251,6 +133284,7 @@ var PersistentClaudeSession = class {
133251
133284
  this.saidThisTurn = false;
133252
133285
  this.turnText = "";
133253
133286
  this.sawResultThisTurn = false;
133287
+ this.resultTelemetry = {};
133254
133288
  yield item.msg;
133255
133289
  }
133256
133290
  }
@@ -133319,7 +133353,7 @@ var PersistentClaudeSession = class {
133319
133353
  });
133320
133354
  }
133321
133355
  };
133322
- console.error(
133356
+ logLine(
133323
133357
  `[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"}`
133324
133358
  );
133325
133359
  return {
@@ -133360,7 +133394,19 @@ var PersistentClaudeSession = class {
133360
133394
  this.roomServer = _s({
133361
133395
  name: "room",
133362
133396
  version: "0.2.0",
133363
- tools: [makeRoomSayTool((text) => this.deliver(text))]
133397
+ tools: [makeRoomSayTool((text) => this.deliver(text))],
133398
+ // LOAD-BEARING for turn latency. The SDK defers MCP tools behind tool
133399
+ // search by default, so the WORKER (which gets the full built-in toolset
133400
+ // for owner DMs) could not see its own voice without first spending a
133401
+ // model round-trip on `ToolSearch {"query":"select:mcp__room__say"}` —
133402
+ // measured on 175 of 175 worker sessions, ~2-5s of a ~20s turn, for a tool
133403
+ // already in `allowedTools`. The listener escaped it only by accident, via
133404
+ // `tools: []`. Set on BOTH lanes so the listener stays correct if its
133405
+ // toolset ever widens.
133406
+ //
133407
+ // NOT a permission change: room_say is already allowed on every session.
133408
+ // This stops HIDING it, it does not grant it.
133409
+ alwaysLoad: true
133364
133410
  });
133365
133411
  const sdkOptions = this.buildSdkOptions();
133366
133412
  const q10 = this.opts.queryImpl ? this.opts.queryImpl({
@@ -133381,12 +133427,23 @@ var PersistentClaudeSession = class {
133381
133427
  }
133382
133428
  } else if (m6.type === "result") {
133383
133429
  this.sawResultThisTurn = true;
133430
+ const r7 = m6;
133431
+ const num = (k2) => typeof r7[k2] === "number" ? r7[k2] : void 0;
133432
+ const str = (k2) => typeof r7[k2] === "string" ? r7[k2] : void 0;
133433
+ this.resultTelemetry = {
133434
+ durationMs: num("duration_ms"),
133435
+ durationApiMs: num("duration_api_ms"),
133436
+ numTurns: num("num_turns"),
133437
+ subtype: str("subtype"),
133438
+ stopReason: str("stop_reason"),
133439
+ apiErrorStatus: num("api_error_status")
133440
+ };
133384
133441
  const reply = this.activeReply;
133385
133442
  if (this.currentReplyExpected && !this.saidThisTurn && this.turnText.trim()) {
133386
133443
  if (reply) {
133387
133444
  void reply(this.turnText);
133388
133445
  } else {
133389
- console.error(
133446
+ logLine(
133390
133447
  `[drop-probe] BLOCKED at result: composed ${this.turnText.length} chars, reply expected but activeReply unset \u2014 reply DROPPED`
133391
133448
  );
133392
133449
  }
@@ -133395,7 +133452,7 @@ var PersistentClaudeSession = class {
133395
133452
  }
133396
133453
  } finally {
133397
133454
  if (this.currentReplyExpected && !this.saidThisTurn && !this.sawResultThisTurn && this.turnText.trim()) {
133398
- console.error(
133455
+ logLine(
133399
133456
  `[drop-probe] STREAM ENDED before result: composed ${this.turnText.length} chars, reply expected, said=false \u2014 reply DROPPED (no result event)`
133400
133457
  );
133401
133458
  }
@@ -134087,22 +134144,22 @@ async function main() {
134087
134144
  const cfg = loadConfig(process.env, process.argv.slice(2));
134088
134145
  const firstArg = process.argv.slice(2)[0];
134089
134146
  if (firstArg && !firstArg.startsWith("-") && firstArg === cfg.inviteToken) {
134090
- console.error(
134147
+ logLine(
134091
134148
  "[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"
134092
134149
  );
134093
134150
  }
134094
- console.error(`[bridge] version: ${true ? "0.7.7" : "dev"}`);
134095
- console.error(`[bridge] data dir: ${cfg.dataDir} (${cfg.dataDirSource})`);
134096
- console.error(`[bridge] workspace: ${cfg.workspaceDir} \xB7 permissions: ${cfg.permissionMode} \xB7 enclave dir fenced`);
134151
+ logLine(`[bridge] version: ${true ? "0.7.9" : "dev"}`);
134152
+ logLine(`[bridge] data dir: ${cfg.dataDir} (${cfg.dataDirSource})`);
134153
+ logLine(`[bridge] workspace: ${cfg.workspaceDir} \xB7 permissions: ${cfg.permissionMode} \xB7 enclave dir fenced`);
134097
134154
  if (cfg.armRoom) {
134098
- console.error(
134155
+ logLine(
134099
134156
  `[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.`
134100
134157
  );
134101
- console.error(
134158
+ logLine(
134102
134159
  "[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."
134103
134160
  );
134104
134161
  } else {
134105
- console.error(
134162
+ logLine(
134106
134163
  '[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.'
134107
134164
  );
134108
134165
  }
@@ -134133,7 +134190,7 @@ async function main() {
134133
134190
  // per-message binding is what prevents a private 1:1 reply from leaking into a
134134
134191
  // room when room traffic arrives mid-compose.
134135
134192
  // Assistant reasoning that wasn't sent — log a short trace only.
134136
- onObserve: (text) => console.error(`[bridge] observed (${text.length} chars, not sent)`),
134193
+ onObserve: (text) => logLine(`[bridge] observed (${text.length} chars, not sent)`),
134137
134194
  worker: false
134138
134195
  });
134139
134196
  const WORKER_MAX_TURNS = 20;
@@ -134142,7 +134199,7 @@ async function main() {
134142
134199
  makeSession: (task) => new PersistentClaudeSession({
134143
134200
  model: cfg.model,
134144
134201
  systemPrompt: agentSystemPrompt,
134145
- onObserve: (text) => console.error(`[worker] observed (${text.length} chars, not sent)`),
134202
+ onObserve: (text) => logLine(`[worker] observed (${text.length} chars, not sent)`),
134146
134203
  worker: true,
134147
134204
  // Task 4: the hard backstop — no tool runs on any worker turn (owner DM or
134148
134205
  // armed room) unless Work is on. Read live per tool decision.
@@ -134165,7 +134222,7 @@ async function main() {
134165
134222
  deviceJwt
134166
134223
  }),
134167
134224
  timeoutMs: WORKER_TIMEOUT_MS,
134168
- log: (m6) => console.error(m6),
134225
+ log: (m6) => logLine(m6),
134169
134226
  // TRAP (2026-07-25). The 07-24 five-minute silence was diagnosable only by
134170
134227
  // luck — the drop-trap happened to record a reply landing 300.016s after the
134171
134228
  // ack, and 300s is WORKER_TIMEOUT_MS exactly. Nothing recorded WHY the worker
@@ -134173,7 +134230,7 @@ async function main() {
134173
134230
  // Append-only JSONL beside the logs, plus one stamped console line so the
134174
134231
  // incident is visible in bridge.error.log at the moment it happens.
134175
134232
  onIncident: (rec) => {
134176
- console.error(
134233
+ logLine(
134177
134234
  `[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}` : "")
134178
134235
  );
134179
134236
  try {
@@ -134181,7 +134238,7 @@ async function main() {
134181
134238
  mkdirSync6(dir, { recursive: true });
134182
134239
  appendFileSync2(join11(dir, "worker-incidents.jsonl"), JSON.stringify(rec) + "\n");
134183
134240
  } catch (err) {
134184
- console.error(`[worker-trap] could not persist incident: ${err.message}`);
134241
+ logLine(`[worker-trap] could not persist incident: ${err.message}`);
134185
134242
  }
134186
134243
  }
134187
134244
  });
@@ -134193,7 +134250,7 @@ async function main() {
134193
134250
  {
134194
134251
  roomFilter: cfg.roomFilter,
134195
134252
  armRoom: cfg.armRoom,
134196
- log: (m6) => console.error("[bridge] " + m6),
134253
+ log: (m6) => logLine("[bridge] " + m6),
134197
134254
  // Slice 2 Plan C (T11): live arm/disarm + local-approval poll + heartbeat.
134198
134255
  workspaceDir: cfg.workspaceDir,
134199
134256
  dataDir: cfg.dataDir,
@@ -134209,21 +134266,21 @@ async function main() {
134209
134266
  }
134210
134267
  );
134211
134268
  attachLifecycle2(channel, {
134212
- log: (m6) => console.error("[bridge] " + m6)
134269
+ log: (m6) => logLine("[bridge] " + m6)
134213
134270
  });
134214
- channel.on("state", (s10) => console.error(`[bridge] channel state: ${JSON.stringify(s10)}`));
134271
+ channel.on("state", (s10) => logLine(`[bridge] channel state: ${JSON.stringify(s10)}`));
134215
134272
  channel.on(
134216
134273
  "room_joined",
134217
- (e7) => console.error(`[bridge] joined room ${e7.name} (${e7.roomId})`)
134274
+ (e7) => logLine(`[bridge] joined room ${e7.name} (${e7.roomId})`)
134218
134275
  );
134219
134276
  listener.start().catch((err) => {
134220
- console.error("[bridge] fatal:", err);
134277
+ logLine("[bridge] fatal:", err);
134221
134278
  process.exit(1);
134222
134279
  });
134223
134280
  await channel.start();
134224
134281
  }
134225
134282
  main().catch((err) => {
134226
- console.error("[bridge] fatal:", err);
134283
+ logLine("[bridge] fatal:", err);
134227
134284
  process.exit(1);
134228
134285
  });
134229
134286
  /*! 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/session.d.ts CHANGED
@@ -143,6 +143,28 @@ export declare class PersistentClaudeSession {
143
143
  * #416 fallback delivery (which delivers via `void reply(...)` WITHOUT setting
144
144
  * saidThisTurn, so !saidThisTurn alone would false-flag it). */
145
145
  private sawResultThisTurn;
146
+ /**
147
+ * Per-turn telemetry lifted off the SDK's `result` message.
148
+ *
149
+ * The message arrives on EVERY turn and we kept one boolean from it
150
+ * (`sawResultThisTurn`), discarding the rest. That is the #791 shape: data
151
+ * delivered on the healthy path that nothing reads.
152
+ *
153
+ * It costs us a real answer. A turn that produced nothing (`composed=0,
154
+ * said=false`) could be the model choosing silence, the turn cap being hit, or
155
+ * the provider returning 429 — three different bugs with one symptom, and
156
+ * `subtype`/`apiErrorStatus` are what separate them. 4 of 12 turns on
157
+ * 2026-08-07 were silent and could not be attributed.
158
+ *
159
+ * `durationApiMs` vs `durationMs` also gives the model-time / SDK-overhead
160
+ * split directly. That split previously had to be reconstructed by joining
161
+ * `WorkerIncident.ranMs` against SDK transcripts on disk by wall clock.
162
+ *
163
+ * Every field is OPTIONAL and left undefined when no result arrives (abort or
164
+ * crash mid-turn): absent must read as absent, never as a zero that looks like
165
+ * a real measurement.
166
+ */
167
+ private resultTelemetry;
146
168
  /** In-process room MCP server — hoisted so buildSdkOptions can reference it. */
147
169
  private roomServer;
148
170
  /** AbortController for the in-flight query(); abort() triggers it (queue timeout). */
@@ -185,6 +207,12 @@ export declare class PersistentClaudeSession {
185
207
  composedChars: number;
186
208
  sawResult: boolean;
187
209
  said: boolean;
210
+ durationMs?: number;
211
+ durationApiMs?: number;
212
+ numTurns?: number;
213
+ subtype?: string;
214
+ stopReason?: string;
215
+ apiErrorStatus?: number;
188
216
  };
189
217
  private input;
190
218
  /**
@@ -61,11 +61,27 @@ export type WorkerIncident = {
61
61
  * could not separate them.
62
62
  */
63
63
  replyExpected?: boolean;
64
- /** What the worker had produced when it died, when the session can report it. */
64
+ /**
65
+ * What the worker had produced when it died, when the session can report it.
66
+ *
67
+ * The `duration*`/`numTurns`/`subtype`/`stopReason`/`apiErrorStatus` fields are
68
+ * lifted off the SDK's `result` message (see `PersistentClaudeSession`). They
69
+ * are what makes a SILENT turn attributable: `composed=0, said=false` is
70
+ * produced identically by the model choosing silence (`subtype: success`), the
71
+ * turn cap (`error_max_turns`) and a provider error (`apiErrorStatus: 429`).
72
+ * Absent on any turn that never reached a result boundary — undefined means
73
+ * "no result arrived", never zero.
74
+ */
65
75
  session?: {
66
76
  composedChars: number;
67
77
  sawResult: boolean;
68
78
  said: boolean;
79
+ durationMs?: number;
80
+ durationApiMs?: number;
81
+ numTurns?: number;
82
+ subtype?: string;
83
+ stopReason?: string;
84
+ apiErrorStatus?: number;
69
85
  };
70
86
  };
71
87
  export interface WorkerQueueDeps {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@agentvault/claude-bridge",
3
- "version": "0.7.7",
3
+ "version": "0.7.9",
4
4
  "type": "module",
5
- "description": "AgentVault Claude Bridge daemon for bridging a Claude agent into secure E2E-encrypted AgentVault 1:1 direct messages and rooms.",
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": {