@atbash/sdk 0.16.2-dev.0 → 0.16.4-dev.0

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.
@@ -1079,6 +1079,13 @@ interface ClassifyMemoryWriteOptions {
1079
1079
  *
1080
1080
  * Empty-content writes return `null`: they can't carry a poisoning
1081
1081
  * payload, and the regular audit path still sees them.
1082
+ *
1083
+ * THROWS on host input it cannot read without side effects: a proxy, an accessor where a data
1084
+ * property is expected, a value with no safe projection, or one past the size bounds. Refusing is
1085
+ * deliberate - a silent `null` would report "not a memory write" for a call nobody could classify,
1086
+ * and memory protection would be skipped exactly where the input was strange. Callers that sit in a
1087
+ * host hook MUST catch it and turn it into a decision; `guardMemoryWrite` and
1088
+ * `MemoryGuardManager.handleBeforeToolCall` already do.
1082
1089
  */
1083
1090
  declare function classifyMemoryWrite(event: unknown, ctx: unknown, opts?: ClassifyMemoryWriteOptions): MemoryEntry | null;
1084
1091
 
@@ -1247,6 +1254,13 @@ interface ClassifyMemoryReadOptions {
1247
1254
  * Caller-supplied `patterns` are MERGED with the defaults (matches
1248
1255
  * Node's original behavior — extending in one plugin doesn't disable
1249
1256
  * standard coverage).
1257
+ *
1258
+ * THROWS on host input it cannot read without side effects: a proxy, an accessor where a data
1259
+ * property is expected, a value with no safe projection, or one past the size bounds. Refusing is
1260
+ * deliberate - a silent `null` would report "not a memory write" for a call nobody could classify,
1261
+ * and memory protection would be skipped exactly where the input was strange. Callers that sit in a
1262
+ * host hook MUST catch it and turn it into a decision; `guardMemoryWrite` and
1263
+ * `MemoryGuardManager.handleBeforeToolCall` already do.
1250
1264
  */
1251
1265
  declare function classifyMemoryRead(event: unknown, ctx: unknown, opts?: ClassifyMemoryReadOptions): boolean;
1252
1266
 
package/dist/browser.mjs CHANGED
@@ -10054,8 +10054,8 @@ Reporter$3.prototype.wrapResult = function wrapResult(result) {
10054
10054
  errors: state2.errors
10055
10055
  };
10056
10056
  };
10057
- function ReporterError$1(path4, msg) {
10058
- this.path = path4;
10057
+ function ReporterError$1(path3, msg) {
10058
+ this.path = path3;
10059
10059
  this.rethrow(msg);
10060
10060
  }
10061
10061
  inherits$v(ReporterError$1, Error);
@@ -12126,7 +12126,7 @@ function requireBuffer_list() {
12126
12126
  }
12127
12127
  }, {
12128
12128
  key: "join",
12129
- value: function join3(s2) {
12129
+ value: function join2(s2) {
12130
12130
  if (this.length === 0) return "";
12131
12131
  var p = this.head;
12132
12132
  var ret = "" + p.data;
@@ -16208,7 +16208,7 @@ function requireBufferList() {
16208
16208
  this.head = this.tail = null;
16209
16209
  this.length = 0;
16210
16210
  };
16211
- BufferList2.prototype.join = function join3(s2) {
16211
+ BufferList2.prototype.join = function join2(s2) {
16212
16212
  if (this.length === 0) return "";
16213
16213
  var p = this.head;
16214
16214
  var ret = "" + p.data;
@@ -30276,8 +30276,8 @@ Reporter.prototype.wrapResult = function wrapResult2(result) {
30276
30276
  errors: state2.errors
30277
30277
  };
30278
30278
  };
30279
- function ReporterError(path4, msg) {
30280
- this.path = path4;
30279
+ function ReporterError(path3, msg) {
30280
+ this.path = path3;
30281
30281
  this.rethrow(msg);
30282
30282
  }
30283
30283
  inherits(ReporterError, Error);
@@ -30372,7 +30372,7 @@ function requireBuffer() {
30372
30372
  }
30373
30373
  }
30374
30374
  buffer.EncoderBuffer = EncoderBuffer2;
30375
- EncoderBuffer2.prototype.join = function join3(out, offset) {
30375
+ EncoderBuffer2.prototype.join = function join2(out, offset) {
30376
30376
  if (!out)
30377
30377
  out = new Buffer5(this.length);
30378
30378
  if (!offset)
@@ -33307,8 +33307,8 @@ var parseUtil = {};
33307
33307
  const errors_js_12 = errors$3;
33308
33308
  const en_js_12 = __importDefault2(en);
33309
33309
  const makeIssue = (params) => {
33310
- const { data, path: path4, errorMaps, issueData } = params;
33311
- const fullPath = [...path4, ...issueData.path || []];
33310
+ const { data, path: path3, errorMaps, issueData } = params;
33311
+ const fullPath = [...path3, ...issueData.path || []];
33312
33312
  const fullIssue = {
33313
33313
  ...issueData,
33314
33314
  path: fullPath
@@ -33445,11 +33445,11 @@ var errorUtil_js_1 = errorUtil$1;
33445
33445
  var parseUtil_js_1 = parseUtil;
33446
33446
  var util_js_1 = util;
33447
33447
  var ParseInputLazyPath = class {
33448
- constructor(parent, value, path4, key3) {
33448
+ constructor(parent, value, path3, key3) {
33449
33449
  this._cachedPath = [];
33450
33450
  this.parent = parent;
33451
33451
  this.data = value;
33452
- this._path = path4;
33452
+ this._path = path3;
33453
33453
  this._key = key3;
33454
33454
  }
33455
33455
  get path() {
@@ -40355,21 +40355,21 @@ function createTimeoutController(timeout) {
40355
40355
  const timeoutId = setTimeout(() => controller.abort(timeoutError), timeout);
40356
40356
  return { controller, timeoutId };
40357
40357
  }
40358
- function handleRequest(method, path4, endpoint, timeout, postObject) {
40358
+ function handleRequest(method, path3, endpoint, timeout, postObject) {
40359
40359
  return __awaiter$2(this, void 0, void 0, function* () {
40360
40360
  if (method == enums_1$2.Method.GET) {
40361
- return yield get(path4, endpoint, timeout);
40361
+ return yield get(path3, endpoint, timeout);
40362
40362
  } else {
40363
- return yield post(path4, endpoint, timeout, postObject);
40363
+ return yield post(path3, endpoint, timeout, postObject);
40364
40364
  }
40365
40365
  });
40366
40366
  }
40367
- function get(path4, endpoint, timeout) {
40367
+ function get(path3, endpoint, timeout) {
40368
40368
  return __awaiter$2(this, void 0, void 0, function* () {
40369
- logger.debug(`GET URL ${new URL(path4, endpoint).href}`);
40369
+ logger.debug(`GET URL ${new URL(path3, endpoint).href}`);
40370
40370
  try {
40371
40371
  const { controller, timeoutId } = createTimeoutController(timeout);
40372
- const response = yield fetch(new URL(path4, endpoint).href, {
40372
+ const response = yield fetch(new URL(path3, endpoint).href, {
40373
40373
  signal: controller === null || controller === void 0 ? void 0 : controller.signal
40374
40374
  });
40375
40375
  if (timeoutId)
@@ -40407,9 +40407,9 @@ function constructBufferResponseBody(response) {
40407
40407
  return responseText ? responseText : response.statusText;
40408
40408
  });
40409
40409
  }
40410
- function post(path4, endpoint, timeout, requestBody) {
40410
+ function post(path3, endpoint, timeout, requestBody) {
40411
40411
  return __awaiter$2(this, void 0, void 0, function* () {
40412
- logger.debug(`POST URL ${new URL(path4, endpoint).href}`);
40412
+ logger.debug(`POST URL ${new URL(path3, endpoint).href}`);
40413
40413
  logger.debug(`POST body ${JSON.stringify(requestBody)}`);
40414
40414
  if (buffer_1.Buffer.isBuffer(requestBody)) {
40415
40415
  try {
@@ -40423,7 +40423,7 @@ function post(path4, endpoint, timeout, requestBody) {
40423
40423
  },
40424
40424
  signal: controller === null || controller === void 0 ? void 0 : controller.signal
40425
40425
  };
40426
- const response = yield fetch(new URL(path4, endpoint).href, requestOptions);
40426
+ const response = yield fetch(new URL(path3, endpoint).href, requestOptions);
40427
40427
  if (timeoutId)
40428
40428
  clearTimeout(timeoutId);
40429
40429
  const transactionTimestamp = response.headers.get("X-Transaction-Timestamp");
@@ -40434,7 +40434,7 @@ function post(path4, endpoint, timeout, requestBody) {
40434
40434
  } else {
40435
40435
  try {
40436
40436
  const { controller, timeoutId } = createTimeoutController(timeout);
40437
- const response = yield fetch(new URL(path4, endpoint).href, {
40437
+ const response = yield fetch(new URL(path3, endpoint).href, {
40438
40438
  method: "post",
40439
40439
  body: JSON.stringify(requestBody),
40440
40440
  headers: {
@@ -40614,10 +40614,10 @@ function requireFailoverStrategies() {
40614
40614
  }
40615
40615
  }
40616
40616
  function abortOnError(_a2) {
40617
- return __awaiter2(this, arguments, void 0, function* ({ method, path: path4, config: config2, postObject, timeoutOverride }) {
40617
+ return __awaiter2(this, arguments, void 0, function* ({ method, path: path3, config: config2, postObject, timeoutOverride }) {
40618
40618
  return yield retryRequest({
40619
40619
  method,
40620
- path: path4,
40620
+ path: path3,
40621
40621
  config: config2,
40622
40622
  postObject,
40623
40623
  timeoutOverride,
@@ -40628,10 +40628,10 @@ function requireFailoverStrategies() {
40628
40628
  });
40629
40629
  }
40630
40630
  function tryNextOnError(_a2) {
40631
- return __awaiter2(this, arguments, void 0, function* ({ method, path: path4, config: config2, postObject, timeoutOverride }) {
40631
+ return __awaiter2(this, arguments, void 0, function* ({ method, path: path3, config: config2, postObject, timeoutOverride }) {
40632
40632
  return yield retryRequest({
40633
40633
  method,
40634
- path: path4,
40634
+ path: path3,
40635
40635
  config: config2,
40636
40636
  postObject,
40637
40637
  timeoutOverride,
@@ -40647,7 +40647,7 @@ function requireFailoverStrategies() {
40647
40647
  return endpointPoolLength - (endpointPoolLength - 1) / 3;
40648
40648
  }
40649
40649
  function queryMajority(_a2) {
40650
- return __awaiter2(this, arguments, void 0, function* ({ method, path: path4, config: config2, postObject, timeoutOverride }) {
40650
+ return __awaiter2(this, arguments, void 0, function* ({ method, path: path3, config: config2, postObject, timeoutOverride }) {
40651
40651
  var _b;
40652
40652
  const bftMajorityThreshold = calculateBftMajorityThreshold(config2.endpointPool.length);
40653
40653
  const failureThreshold = config2.endpointPool.length - bftMajorityThreshold + 1;
@@ -40658,7 +40658,7 @@ function requireFailoverStrategies() {
40658
40658
  const promises = availableNodes.map((node2) => __awaiter2(this, void 0, void 0, function* () {
40659
40659
  try {
40660
40660
  const requestTimeout = timeoutOverride !== null && timeoutOverride !== void 0 ? timeoutOverride : config2.responseTimeout;
40661
- const response = yield (0, httpUtil_1.handleRequest)(method, path4, node2.url, requestTimeout, postObject);
40661
+ const response = yield (0, httpUtil_1.handleRequest)(method, path3, node2.url, requestTimeout, postObject);
40662
40662
  const { statusCode } = response;
40663
40663
  if (statusCode && (0, http_utils_1.isSuccessfulStatusCode)(statusCode)) {
40664
40664
  outcomes.push({ type: "SUCCESS", result: response });
@@ -40705,7 +40705,7 @@ function requireFailoverStrategies() {
40705
40705
  });
40706
40706
  }
40707
40707
  function singleEndpoint(_a2) {
40708
- return __awaiter2(this, arguments, void 0, function* ({ method, path: path4, config: config2, postObject, timeoutOverride }) {
40708
+ return __awaiter2(this, arguments, void 0, function* ({ method, path: path3, config: config2, postObject, timeoutOverride }) {
40709
40709
  let statusCode = null;
40710
40710
  let rspBody = null;
40711
40711
  let error4 = null;
@@ -40716,7 +40716,7 @@ function requireFailoverStrategies() {
40716
40716
  }
40717
40717
  for (let attempt = 0; attempt < config2.attemptsPerEndpoint; attempt++) {
40718
40718
  const requestTimeout = timeoutOverride !== null && timeoutOverride !== void 0 ? timeoutOverride : config2.responseTimeout;
40719
- const response = yield (0, httpUtil_1.handleRequest)(method, path4, endpoint.url, requestTimeout, postObject);
40719
+ const response = yield (0, httpUtil_1.handleRequest)(method, path3, endpoint.url, requestTimeout, postObject);
40720
40720
  if (response) {
40721
40721
  ({ error: error4, statusCode, rspBody, transactionTimestamp } = response);
40722
40722
  }
@@ -40731,7 +40731,7 @@ function requireFailoverStrategies() {
40731
40731
  });
40732
40732
  }
40733
40733
  function retryRequest(_a2) {
40734
- return __awaiter2(this, arguments, void 0, function* ({ method, path: path4, config: config2, postObject, useNextNodeOnError, recoveryThreshold, timeoutOverride }) {
40734
+ return __awaiter2(this, arguments, void 0, function* ({ method, path: path3, config: config2, postObject, useNextNodeOnError, recoveryThreshold, timeoutOverride }) {
40735
40735
  var _b, _c, _d;
40736
40736
  let statusCode = null;
40737
40737
  let rspBody = null;
@@ -40742,7 +40742,7 @@ function requireFailoverStrategies() {
40742
40742
  for (const node2 of availableNodes) {
40743
40743
  for (let attempt = 0; attempt < config2.attemptsPerEndpoint; attempt++) {
40744
40744
  const requestTimeout = timeoutOverride !== null && timeoutOverride !== void 0 ? timeoutOverride : config2.responseTimeout;
40745
- const response = yield (0, httpUtil_1.handleRequest)(method, path4, node2.url, requestTimeout, postObject);
40745
+ const response = yield (0, httpUtil_1.handleRequest)(method, path3, node2.url, requestTimeout, postObject);
40746
40746
  error4 = (_b = response === null || response === void 0 ? void 0 : response.error) !== null && _b !== void 0 ? _b : null;
40747
40747
  statusCode = (_c = response === null || response === void 0 ? void 0 : response.statusCode) !== null && _c !== void 0 ? _c : null;
40748
40748
  rspBody = (_d = response === null || response === void 0 ? void 0 : response.rspBody) !== null && _d !== void 0 ? _d : null;
@@ -40885,19 +40885,19 @@ function requireRequestWithFailoverStrategy() {
40885
40885
  const enums_12 = enums;
40886
40886
  const failoverStrategies_1 = requireFailoverStrategies();
40887
40887
  function requestWithFailoverStrategy$1(method_1, path_1, config_1, postObject_1) {
40888
- return __awaiter2(this, arguments, void 0, function* (method, path4, config2, postObject, forceSingleEndpoint = false, timeoutOverride) {
40888
+ return __awaiter2(this, arguments, void 0, function* (method, path3, config2, postObject, forceSingleEndpoint = false, timeoutOverride) {
40889
40889
  switch (config2.failoverStrategy) {
40890
40890
  case enums_12.FailoverStrategy.AbortOnError:
40891
- return yield (0, failoverStrategies_1.abortOnError)({ method, path: path4, config: config2, postObject, timeoutOverride });
40891
+ return yield (0, failoverStrategies_1.abortOnError)({ method, path: path3, config: config2, postObject, timeoutOverride });
40892
40892
  case enums_12.FailoverStrategy.TryNextOnError:
40893
- return yield (0, failoverStrategies_1.tryNextOnError)({ method, path: path4, config: config2, postObject, timeoutOverride });
40893
+ return yield (0, failoverStrategies_1.tryNextOnError)({ method, path: path3, config: config2, postObject, timeoutOverride });
40894
40894
  case enums_12.FailoverStrategy.SingleEndpoint:
40895
- return yield (0, failoverStrategies_1.singleEndpoint)({ method, path: path4, config: config2, postObject, timeoutOverride });
40895
+ return yield (0, failoverStrategies_1.singleEndpoint)({ method, path: path3, config: config2, postObject, timeoutOverride });
40896
40896
  case enums_12.FailoverStrategy.QueryMajority:
40897
40897
  if (forceSingleEndpoint) {
40898
- return yield (0, failoverStrategies_1.singleEndpoint)({ method, path: path4, config: config2, postObject, timeoutOverride });
40898
+ return yield (0, failoverStrategies_1.singleEndpoint)({ method, path: path3, config: config2, postObject, timeoutOverride });
40899
40899
  }
40900
- return yield (0, failoverStrategies_1.queryMajority)({ method, path: path4, config: config2, postObject, timeoutOverride });
40900
+ return yield (0, failoverStrategies_1.queryMajority)({ method, path: path3, config: config2, postObject, timeoutOverride });
40901
40901
  default:
40902
40902
  throw new Error(`Unsupported failover strategy: ${config2.failoverStrategy}`);
40903
40903
  }
@@ -42096,7 +42096,7 @@ var networkSettings = {};
42096
42096
  const restNetworkSettingsValidationContext = RestNetworkSettingsSchema.safeParse(networkSettings2);
42097
42097
  if ("error" in restNetworkSettingsValidationContext) {
42098
42098
  const { error: { issues } = {} } = restNetworkSettingsValidationContext;
42099
- const errorMessage2 = issues === null || issues === void 0 ? void 0 : issues.map(({ message, path: path4 }) => `${path4[0]}: ${message}`).join(", ");
42099
+ const errorMessage2 = issues === null || issues === void 0 ? void 0 : issues.map(({ message, path: path3 }) => `${path3[0]}: ${message}`).join(", ");
42100
42100
  if (throwOnError) {
42101
42101
  throw new Error(errorMessage2);
42102
42102
  }
@@ -44420,12 +44420,12 @@ var AtbashAPIError = class extends Error {
44420
44420
  * ran does not carry. The path is the fact that settles it.
44421
44421
  */
44422
44422
  path;
44423
- constructor(status, body, statusText = "", endpoint = DEFAULT_ENDPOINT, path4) {
44424
- super(enrich(status, body, statusText, endpoint, path4));
44423
+ constructor(status, body, statusText = "", endpoint = DEFAULT_ENDPOINT, path3) {
44424
+ super(enrich(status, body, statusText, endpoint, path3));
44425
44425
  this.name = "AtbashAPIError";
44426
44426
  this.status = status;
44427
44427
  this.body = body;
44428
- this.path = path4;
44428
+ this.path = path3;
44429
44429
  }
44430
44430
  };
44431
44431
  var SignatureVerificationError = class extends Error {
@@ -44434,9 +44434,9 @@ var SignatureVerificationError = class extends Error {
44434
44434
  this.name = "SignatureVerificationError";
44435
44435
  }
44436
44436
  };
44437
- function enrich(status, body, statusText, endpoint, path4) {
44437
+ function enrich(status, body, statusText, endpoint, path3) {
44438
44438
  const dashboard = endpoint.replace(/\/+$/, "") || DEFAULT_ENDPOINT;
44439
- let msg = `API error ${status}${path4 ? ` from ${path4}` : ""}: ${body || statusText}`;
44439
+ let msg = `API error ${status}${path3 ? ` from ${path3}` : ""}: ${body || statusText}`;
44440
44440
  const lowered = body.toLowerCase();
44441
44441
  if (lowered.includes("agent not registered")) {
44442
44442
  msg += `
@@ -44467,8 +44467,8 @@ var HttpClient = class {
44467
44467
  this.baseUrl = baseUrl.replace(/\/+$/, "");
44468
44468
  this.timeoutMs = timeoutMs;
44469
44469
  }
44470
- buildUrl(path4, query) {
44471
- const url = new URL(this.baseUrl + path4);
44470
+ buildUrl(path3, query) {
44471
+ const url = new URL(this.baseUrl + path3);
44472
44472
  if (query) {
44473
44473
  for (const [k, v] of Object.entries(query)) {
44474
44474
  if (v !== void 0 && v !== null && v !== "") {
@@ -44478,14 +44478,14 @@ var HttpClient = class {
44478
44478
  }
44479
44479
  return url.toString();
44480
44480
  }
44481
- async get(path4, query, headers) {
44482
- return this.fetch(this.buildUrl(path4, query), {
44481
+ async get(path3, query, headers) {
44482
+ return this.fetch(this.buildUrl(path3, query), {
44483
44483
  method: "GET",
44484
44484
  ...headers && { headers }
44485
44485
  });
44486
44486
  }
44487
- async post(path4, body, headers) {
44488
- return this.fetch(this.buildUrl(path4), {
44487
+ async post(path3, body, headers) {
44488
+ return this.fetch(this.buildUrl(path3), {
44489
44489
  method: "POST",
44490
44490
  headers: { "Content-Type": "application/json", ...headers },
44491
44491
  body: JSON.stringify(body)
@@ -44528,6 +44528,13 @@ function classifyTransportError(err, url, method, timeoutMs) {
44528
44528
  { cause: err }
44529
44529
  );
44530
44530
  }
44531
+ if (code2 === "UND_ERR_CONNECT_TIMEOUT") {
44532
+ return new HttpTransportError(
44533
+ "timeout",
44534
+ `${method} ${url} could not establish a connection before the transport deadline \u2014 check the endpoint and network`,
44535
+ { cause: err }
44536
+ );
44537
+ }
44531
44538
  if (code2 === "ENOTFOUND" || code2 === "EAI_AGAIN") {
44532
44539
  return new HttpTransportError(
44533
44540
  "dns",
@@ -44792,7 +44799,6 @@ var Atbash = class _Atbash {
44792
44799
  try {
44793
44800
  setupTelemetry({
44794
44801
  enabled: true,
44795
- source: "sdk",
44796
44802
  endpoint: this.endpoint,
44797
44803
  getAuthHeaders: () => this.authHeaders()
44798
44804
  });
@@ -45619,8 +45625,8 @@ var Atbash = class _Atbash {
45619
45625
  async riskEnginePost(body, network, brid) {
45620
45626
  let resp;
45621
45627
  try {
45622
- const path4 = network ? `/api/risk-engine?network=${encodeURIComponent(network)}` : "/api/risk-engine";
45623
- resp = await this.http.post(path4, body, this.authHeaders(brid));
45628
+ const path3 = network ? `/api/risk-engine?network=${encodeURIComponent(network)}` : "/api/risk-engine";
45629
+ resp = await this.http.post(path3, body, this.authHeaders(brid));
45624
45630
  } catch (err) {
45625
45631
  throw this.transportError(err);
45626
45632
  }
@@ -45860,27 +45866,18 @@ function truncate(text, limit = MAX_ACTION_LEN) {
45860
45866
  return text.slice(0, limit) + "\u2026";
45861
45867
  }
45862
45868
 
45863
- // src-ts/key-path.ts
45869
+ // src-ts/browser/key-path.ts
45864
45870
  init_define_ATBASH_CHROMIA_NODE_URLS();
45865
45871
  init_define_ATBASH_PRIVATE_NODE_URLS();
45866
- import { homedir } from "os";
45867
- import { join as join2 } from "path";
45868
- var KEY_DIR_REL = ".config/atbash";
45869
45872
  var KEY_FILENAMES = ["guard-client-key", "atbash-client-key"];
45870
- function home() {
45871
- return process.env.HOME || homedir() || "";
45872
- }
45873
- function expandHome(p) {
45874
- if (!p.startsWith("~/")) return p;
45875
- return join2(home(), p.slice(2));
45876
- }
45873
+ var unavailable = (name2) => {
45874
+ throw new Error(`${name2} is not available in the browser bundle`);
45875
+ };
45877
45876
  function keyPathCandidates() {
45878
- return KEY_FILENAMES.map((name2) => join2(home(), KEY_DIR_REL, name2));
45877
+ return unavailable("keyPathCandidates");
45879
45878
  }
45880
- function chooseKeyPath(input, exists) {
45881
- if (input) return expandHome(input);
45882
- const candidates = keyPathCandidates();
45883
- return candidates.find(exists) ?? candidates[0];
45879
+ function chooseKeyPath(_input, _exists) {
45880
+ return unavailable("chooseKeyPath");
45884
45881
  }
45885
45882
 
45886
45883
  // src-ts/redact.ts
@@ -46100,112 +46097,12 @@ function classifyMemoryWrite(_event, _ctx, _opts = {}) {
46100
46097
  throw new Error(`classifyMemoryWrite ${STUB_MSG4}`);
46101
46098
  }
46102
46099
 
46103
- // src-ts/memory/guard.ts
46100
+ // src-ts/browser/memory-guard.ts
46104
46101
  init_define_ATBASH_CHROMIA_NODE_URLS();
46105
46102
  init_define_ATBASH_PRIVATE_NODE_URLS();
46106
- import path3 from "path";
46107
- function emitDebugProbe(event, ctx, memEntry, logger2) {
46108
- if (!logger2?.info) return;
46109
- const ev = event ?? {};
46110
- const c = ctx ?? {};
46111
- const argsCandidate = ev.params ?? c.params ?? ev.args ?? c.args ?? ev.arguments ?? c.arguments;
46112
- const argsObj = argsCandidate && typeof argsCandidate === "object" ? argsCandidate : {};
46113
- const argsKeys = Object.keys(argsObj).slice(0, 20);
46114
- const pickedPath = typeof argsObj.file_path === "string" && argsObj.file_path || typeof argsObj.path === "string" && argsObj.path || typeof argsObj.filename === "string" && argsObj.filename || null;
46115
- const editsArr = Array.isArray(argsObj.edits) ? argsObj.edits : null;
46116
- const firstEditKeys = editsArr && editsArr[0] && typeof editsArr[0] === "object" ? Object.keys(editsArr[0]).slice(0, 10) : null;
46117
- const tool = ev.toolName ?? c.tool?.name ?? c.toolName ?? c.name ?? "(none)";
46118
- logger2.info("[atbash][probe] before_tool_call", {
46119
- toolName: tool,
46120
- eventKeys: Object.keys(ev).slice(0, 20),
46121
- ctxKeys: Object.keys(c).slice(0, 20),
46122
- argsKeys,
46123
- pickedPath,
46124
- firstEditKeys,
46125
- editsCount: editsArr?.length,
46126
- memoryWrite: !!memEntry,
46127
- memoryPath: memEntry?.key
46128
- });
46129
- }
46130
- async function guardMemoryWrite(input) {
46131
- const {
46132
- event,
46133
- ctx,
46134
- auth,
46135
- endpoint,
46136
- verifyPubKey,
46137
- orgName,
46138
- threshold,
46139
- patterns,
46140
- toolNames,
46141
- enforce = true,
46142
- debug: debug2 = false,
46143
- logger: logger2
46144
- } = input;
46145
- const memEntry = classifyMemoryWrite(event, ctx, { patterns, toolNames });
46146
- if (debug2) emitDebugProbe(event, ctx, memEntry, logger2);
46147
- if (!memEntry) return { handled: false };
46148
- let scanResult;
46149
- try {
46150
- scanResult = await scanMemory(memEntry, auth, {
46151
- endpoint,
46152
- verifyPubKey,
46153
- orgName,
46154
- threshold
46155
- });
46156
- } catch (err) {
46157
- const reason = err instanceof Error ? err.message : String(err);
46158
- logger2?.warn?.("[atbash] memory scan failed", {
46159
- path: memEntry.key,
46160
- reason
46161
- });
46162
- return {
46163
- handled: true,
46164
- decision: enforce ? { allow: false, block: true, reason } : { allow: true }
46165
- };
46166
- }
46167
- if (scanResult.verdict === "red") {
46168
- logger2?.warn?.("[atbash] memory BLOCK", {
46169
- path: memEntry.key,
46170
- reason: scanResult.reason
46171
- });
46172
- return {
46173
- handled: true,
46174
- decision: enforce ? { allow: false, block: true, reason: scanResult.reason } : { allow: true },
46175
- scanResult,
46176
- committed: false
46177
- };
46178
- }
46179
- const filePath = path3.basename(memEntry.key);
46180
- commitMemoryVersion(memEntry.value, auth, {
46181
- score: scanResult.score,
46182
- filePath,
46183
- orgName,
46184
- endpoint,
46185
- verifyPubKey
46186
- }).catch((err) => {
46187
- const reason = err instanceof Error ? err.message : String(err);
46188
- logger2?.warn?.("[atbash] memory commit to chain failed", {
46189
- path: memEntry.key,
46190
- filePath,
46191
- reason
46192
- });
46193
- });
46194
- logger2?.info?.(
46195
- scanResult.verdict === "yellow" ? "[atbash] memory HOLD" : "[atbash] memory ALLOW",
46196
- {
46197
- path: memEntry.key,
46198
- filePath,
46199
- score: scanResult.score,
46200
- reason: scanResult.reason
46201
- }
46202
- );
46203
- return {
46204
- handled: true,
46205
- decision: { allow: true },
46206
- scanResult,
46207
- committed: true
46208
- };
46103
+ var STUB_MSG5 = "not available in @atbash/sdk browser bundle \u2014 guard memory writes agent-side";
46104
+ async function guardMemoryWrite(_input) {
46105
+ throw new Error(`guardMemoryWrite ${STUB_MSG5}`);
46209
46106
  }
46210
46107
 
46211
46108
  // src-ts/memory/sync.ts
@@ -46245,7 +46142,7 @@ async function syncLocalMemory(auth, pointer, opts = {}) {
46245
46142
  // src-ts/browser/memory-pointer-store.ts
46246
46143
  init_define_ATBASH_CHROMIA_NODE_URLS();
46247
46144
  init_define_ATBASH_PRIVATE_NODE_URLS();
46248
- var unavailable = (name2) => {
46145
+ var unavailable2 = (name2) => {
46249
46146
  throw new Error(`${name2} is not available in the browser bundle`);
46250
46147
  };
46251
46148
  var PointerStore = class {
@@ -46259,38 +46156,38 @@ var PointerStore = class {
46259
46156
  }
46260
46157
  };
46261
46158
  function defaultPointerPath(_workspaceDir) {
46262
- return unavailable("defaultPointerPath");
46159
+ return unavailable2("defaultPointerPath");
46263
46160
  }
46264
46161
 
46265
46162
  // src-ts/browser/memory-file-logger.ts
46266
46163
  init_define_ATBASH_CHROMIA_NODE_URLS();
46267
46164
  init_define_ATBASH_PRIVATE_NODE_URLS();
46268
- var unavailable2 = (name2) => {
46165
+ var unavailable3 = (name2) => {
46269
46166
  throw new Error(`${name2} is not available in the browser bundle`);
46270
46167
  };
46271
46168
  function createFileLogger(_logFilePath, _hostLogger) {
46272
- return unavailable2("createFileLogger");
46169
+ return unavailable3("createFileLogger");
46273
46170
  }
46274
46171
  function defaultPluginLogPath(_workspaceDir) {
46275
- return unavailable2("defaultPluginLogPath");
46172
+ return unavailable3("defaultPluginLogPath");
46276
46173
  }
46277
46174
 
46278
46175
  // src-ts/browser/memory-read-classifier.ts
46279
46176
  init_define_ATBASH_CHROMIA_NODE_URLS();
46280
46177
  init_define_ATBASH_PRIVATE_NODE_URLS();
46281
- var STUB_MSG5 = "not available in @atbash/sdk browser bundle \u2014 classify memory reads server-side";
46178
+ var STUB_MSG6 = "not available in @atbash/sdk browser bundle \u2014 classify memory reads server-side";
46282
46179
  var DEFAULT_MEMORY_READ_TOOL_NAMES = [
46283
46180
  "memory_search",
46284
46181
  "memory_get"
46285
46182
  ];
46286
46183
  function classifyMemoryRead(_event, _ctx, _opts = {}) {
46287
- throw new Error(`classifyMemoryRead ${STUB_MSG5}`);
46184
+ throw new Error(`classifyMemoryRead ${STUB_MSG6}`);
46288
46185
  }
46289
46186
 
46290
46187
  // src-ts/browser/memory-guard-manager.ts
46291
46188
  init_define_ATBASH_CHROMIA_NODE_URLS();
46292
46189
  init_define_ATBASH_PRIVATE_NODE_URLS();
46293
- var unavailable3 = (name2) => {
46190
+ var unavailable4 = (name2) => {
46294
46191
  throw new Error(`${name2} is not available in the browser bundle`);
46295
46192
  };
46296
46193
  var MemoryGuardManager = class {
@@ -46310,7 +46207,7 @@ var MemoryGuardManager = class {
46310
46207
  }
46311
46208
  };
46312
46209
  function createMemoryGuardManager(_opts) {
46313
- return unavailable3("createMemoryGuardManager");
46210
+ return unavailable4("createMemoryGuardManager");
46314
46211
  }
46315
46212
 
46316
46213
  // src-ts/index.ts
package/dist/index.d.mts CHANGED
@@ -1079,6 +1079,13 @@ interface ClassifyMemoryWriteOptions {
1079
1079
  *
1080
1080
  * Empty-content writes return `null`: they can't carry a poisoning
1081
1081
  * payload, and the regular audit path still sees them.
1082
+ *
1083
+ * THROWS on host input it cannot read without side effects: a proxy, an accessor where a data
1084
+ * property is expected, a value with no safe projection, or one past the size bounds. Refusing is
1085
+ * deliberate - a silent `null` would report "not a memory write" for a call nobody could classify,
1086
+ * and memory protection would be skipped exactly where the input was strange. Callers that sit in a
1087
+ * host hook MUST catch it and turn it into a decision; `guardMemoryWrite` and
1088
+ * `MemoryGuardManager.handleBeforeToolCall` already do.
1082
1089
  */
1083
1090
  declare function classifyMemoryWrite(event: unknown, ctx: unknown, opts?: ClassifyMemoryWriteOptions): MemoryEntry | null;
1084
1091
 
@@ -1247,6 +1254,13 @@ interface ClassifyMemoryReadOptions {
1247
1254
  * Caller-supplied `patterns` are MERGED with the defaults (matches
1248
1255
  * Node's original behavior — extending in one plugin doesn't disable
1249
1256
  * standard coverage).
1257
+ *
1258
+ * THROWS on host input it cannot read without side effects: a proxy, an accessor where a data
1259
+ * property is expected, a value with no safe projection, or one past the size bounds. Refusing is
1260
+ * deliberate - a silent `null` would report "not a memory write" for a call nobody could classify,
1261
+ * and memory protection would be skipped exactly where the input was strange. Callers that sit in a
1262
+ * host hook MUST catch it and turn it into a decision; `guardMemoryWrite` and
1263
+ * `MemoryGuardManager.handleBeforeToolCall` already do.
1250
1264
  */
1251
1265
  declare function classifyMemoryRead(event: unknown, ctx: unknown, opts?: ClassifyMemoryReadOptions): boolean;
1252
1266
 
package/dist/index.d.ts CHANGED
@@ -1079,6 +1079,13 @@ interface ClassifyMemoryWriteOptions {
1079
1079
  *
1080
1080
  * Empty-content writes return `null`: they can't carry a poisoning
1081
1081
  * payload, and the regular audit path still sees them.
1082
+ *
1083
+ * THROWS on host input it cannot read without side effects: a proxy, an accessor where a data
1084
+ * property is expected, a value with no safe projection, or one past the size bounds. Refusing is
1085
+ * deliberate - a silent `null` would report "not a memory write" for a call nobody could classify,
1086
+ * and memory protection would be skipped exactly where the input was strange. Callers that sit in a
1087
+ * host hook MUST catch it and turn it into a decision; `guardMemoryWrite` and
1088
+ * `MemoryGuardManager.handleBeforeToolCall` already do.
1082
1089
  */
1083
1090
  declare function classifyMemoryWrite(event: unknown, ctx: unknown, opts?: ClassifyMemoryWriteOptions): MemoryEntry | null;
1084
1091
 
@@ -1247,6 +1254,13 @@ interface ClassifyMemoryReadOptions {
1247
1254
  * Caller-supplied `patterns` are MERGED with the defaults (matches
1248
1255
  * Node's original behavior — extending in one plugin doesn't disable
1249
1256
  * standard coverage).
1257
+ *
1258
+ * THROWS on host input it cannot read without side effects: a proxy, an accessor where a data
1259
+ * property is expected, a value with no safe projection, or one past the size bounds. Refusing is
1260
+ * deliberate - a silent `null` would report "not a memory write" for a call nobody could classify,
1261
+ * and memory protection would be skipped exactly where the input was strange. Callers that sit in a
1262
+ * host hook MUST catch it and turn it into a decision; `guardMemoryWrite` and
1263
+ * `MemoryGuardManager.handleBeforeToolCall` already do.
1250
1264
  */
1251
1265
  declare function classifyMemoryRead(event: unknown, ctx: unknown, opts?: ClassifyMemoryReadOptions): boolean;
1252
1266
 
package/dist/index.js CHANGED
@@ -3190,6 +3190,13 @@ function classifyTransportError(err, url, method, timeoutMs) {
3190
3190
  { cause: err }
3191
3191
  );
3192
3192
  }
3193
+ if (code2 === "UND_ERR_CONNECT_TIMEOUT") {
3194
+ return new HttpTransportError(
3195
+ "timeout",
3196
+ `${method} ${url} could not establish a connection before the transport deadline \u2014 check the endpoint and network`,
3197
+ { cause: err }
3198
+ );
3199
+ }
3193
3200
  if (code2 === "ENOTFOUND" || code2 === "EAI_AGAIN") {
3194
3201
  return new HttpTransportError(
3195
3202
  "dns",
@@ -3354,6 +3361,7 @@ var meterProvider = null;
3354
3361
  var callCounter = null;
3355
3362
  var durationHistogram = null;
3356
3363
  var defaultSource = "sdk";
3364
+ var sourceExplicitlySet = false;
3357
3365
  function isTelemetryOptedOut() {
3358
3366
  const disabled = process.env.ATBASH_TELEMETRY_DISABLED?.trim().toLowerCase();
3359
3367
  if (disabled && ["1", "true", "yes", "on"].includes(disabled)) {
@@ -3377,11 +3385,14 @@ function autoInit() {
3377
3385
  }
3378
3386
  function setupTelemetry(config2) {
3379
3387
  if (!config2.enabled) return;
3380
- if (meterProvider) return;
3381
3388
  if (isTelemetryOptedOut()) return;
3389
+ if (config2.source && !sourceExplicitlySet) {
3390
+ defaultSource = config2.source;
3391
+ sourceExplicitlySet = true;
3392
+ }
3393
+ if (meterProvider) return;
3382
3394
  if (!config2.endpoint || !config2.getAuthHeaders) return;
3383
3395
  if (/^https?:\/\/(localhost|127\.0\.0\.1|0\.0\.0\.0)(:|\/|$)/i.test(config2.endpoint)) return;
3384
- defaultSource = config2.source ?? "sdk";
3385
3396
  const proxyUrl = `${config2.endpoint.replace(/\/+$/, "")}/api/telemetry`;
3386
3397
  const getAuthHeaders = config2.getAuthHeaders;
3387
3398
  const exporter = new import_exporter_metrics_otlp_http.OTLPMetricExporter({
@@ -3434,6 +3445,8 @@ async function shutdownTelemetry() {
3434
3445
  meterProvider = null;
3435
3446
  callCounter = null;
3436
3447
  durationHistogram = null;
3448
+ defaultSource = "sdk";
3449
+ sourceExplicitlySet = false;
3437
3450
  }
3438
3451
 
3439
3452
  // src-ts/userConfig.ts
@@ -3624,7 +3637,6 @@ var Atbash = class _Atbash {
3624
3637
  try {
3625
3638
  setupTelemetry({
3626
3639
  enabled: true,
3627
- source: "sdk",
3628
3640
  endpoint: this.endpoint,
3629
3641
  getAuthHeaders: () => this.authHeaders()
3630
3642
  });
@@ -35320,9 +35332,9 @@ var ZodUnion = class extends ZodType {
35320
35332
  }
35321
35333
  };
35322
35334
  types.ZodUnion = ZodUnion;
35323
- ZodUnion.create = (types2, params) => {
35335
+ ZodUnion.create = (types3, params) => {
35324
35336
  return new ZodUnion({
35325
- options: types2,
35337
+ options: types3,
35326
35338
  typeName: ZodFirstPartyTypeKind.ZodUnion,
35327
35339
  ...processCreateParams(params)
35328
35340
  });
@@ -38779,9 +38791,9 @@ _nodeUtil.exports;
38779
38791
  var freeProcess = moduleExports && freeGlobal2.process;
38780
38792
  var nodeUtil2 = (function() {
38781
38793
  try {
38782
- var types2 = freeModule && freeModule.require && freeModule.require("util").types;
38783
- if (types2) {
38784
- return types2;
38794
+ var types3 = freeModule && freeModule.require && freeModule.require("util").types;
38795
+ if (types3) {
38796
+ return types3;
38785
38797
  }
38786
38798
  return freeProcess && freeProcess.binding && freeProcess.binding("util");
38787
38799
  } catch (e) {
@@ -43161,12 +43173,96 @@ async function rollbackMemory(toId, reason, auth, opts) {
43161
43173
  }
43162
43174
 
43163
43175
  // src-ts/memory/_json_safe.ts
43176
+ var import_node_util = require("util");
43177
+ var replacementKeys = [
43178
+ "newText",
43179
+ "new_string",
43180
+ "new_str",
43181
+ "newStr",
43182
+ "replacement"
43183
+ ];
43184
+ var argumentKeys = [
43185
+ "file_path",
43186
+ "path",
43187
+ "filename",
43188
+ "target",
43189
+ "file",
43190
+ "filePath",
43191
+ "content",
43192
+ ...replacementKeys,
43193
+ "value",
43194
+ "text"
43195
+ ];
43196
+ var maxPrototypeDepth = 32;
43197
+ var maxEditSlots = 65536;
43198
+ var maxTextUnits = 16 * 1024 * 1024;
43199
+ function invalid() {
43200
+ throw new TypeError("Unreadable or unsupported memory classifier input");
43201
+ }
43202
+ function dataProperty(value, key3) {
43203
+ let current = value;
43204
+ for (let depth = 0; current !== null; depth++) {
43205
+ if (depth >= maxPrototypeDepth || import_node_util.types.isProxy(current)) invalid();
43206
+ const descriptor = Object.getOwnPropertyDescriptor(current, key3);
43207
+ if (descriptor) {
43208
+ if (!("value" in descriptor)) invalid();
43209
+ return descriptor.value;
43210
+ }
43211
+ current = Object.getPrototypeOf(current);
43212
+ }
43213
+ return void 0;
43214
+ }
43164
43215
  function toJsonSafe(value) {
43165
- try {
43166
- return JSON.parse(JSON.stringify(value ?? null));
43167
- } catch {
43168
- return null;
43216
+ let textUnits = 0;
43217
+ function scalar(input) {
43218
+ if (input == null) return null;
43219
+ if (typeof input === "string") {
43220
+ textUnits += input.length;
43221
+ if (textUnits > maxTextUnits) invalid();
43222
+ return input;
43223
+ }
43224
+ if (typeof input === "boolean") return input;
43225
+ if (typeof input === "number" && Number.isFinite(input)) return input;
43226
+ return invalid();
43227
+ }
43228
+ function project(input, shape) {
43229
+ if (input == null || typeof input !== "object") return scalar(input);
43230
+ if (import_node_util.types.isProxy(input) || Array.isArray(input)) invalid();
43231
+ const output = /* @__PURE__ */ Object.create(null);
43232
+ const keys2 = shape === "envelope" ? ["toolName", "name"] : shape === "tool" ? ["name"] : shape === "args" ? argumentKeys : replacementKeys;
43233
+ for (const key3 of keys2) {
43234
+ const field = dataProperty(input, key3);
43235
+ if (field !== void 0) output[key3] = scalar(field);
43236
+ }
43237
+ if (shape === "envelope") {
43238
+ for (const key3 of ["params", "args", "arguments", "tool"]) {
43239
+ const field = dataProperty(input, key3);
43240
+ if (field !== void 0)
43241
+ output[key3] = project(field, key3 === "tool" ? "tool" : "args");
43242
+ }
43243
+ }
43244
+ if (shape === "args") {
43245
+ const edits = dataProperty(input, "edits");
43246
+ if (edits !== void 0) {
43247
+ if (edits !== null && typeof edits === "object" && import_node_util.types.isProxy(edits))
43248
+ invalid();
43249
+ if (Array.isArray(edits)) {
43250
+ const length = dataProperty(edits, "length");
43251
+ if (typeof length !== "number" || !Number.isInteger(length) || length < 0 || length > maxEditSlots)
43252
+ invalid();
43253
+ const entries = [];
43254
+ for (let index2 = 0; index2 < length; index2++) {
43255
+ entries.push(project(dataProperty(edits, String(index2)), "edit"));
43256
+ }
43257
+ output.edits = entries;
43258
+ } else {
43259
+ output.edits = scalar(edits);
43260
+ }
43261
+ }
43262
+ }
43263
+ return output;
43169
43264
  }
43265
+ return project(value, "envelope");
43170
43266
  }
43171
43267
 
43172
43268
  // src-ts/memory/classifier.ts
@@ -43219,7 +43315,22 @@ async function guardMemoryWrite(input) {
43219
43315
  debug: debug2 = false,
43220
43316
  logger: logger2
43221
43317
  } = input;
43222
- const memEntry = classifyMemoryWrite(event, ctx, { patterns, toolNames });
43318
+ let memEntry;
43319
+ try {
43320
+ memEntry = classifyMemoryWrite(event, ctx, { patterns, toolNames });
43321
+ } catch (err) {
43322
+ const why = err instanceof Error ? err.message : String(err);
43323
+ logger2?.warn?.("[atbash] memory classifier refused this tool call's input", { reason: why });
43324
+ if (!enforce) return { handled: false };
43325
+ return {
43326
+ handled: true,
43327
+ decision: {
43328
+ allow: false,
43329
+ block: true,
43330
+ reason: `Memory protection could not read this tool call (${why}); blocked because it could not be checked.`
43331
+ }
43332
+ };
43333
+ }
43223
43334
  if (debug2) emitDebugProbe(event, ctx, memEntry, logger2);
43224
43335
  if (!memEntry) return { handled: false };
43225
43336
  let scanResult;
@@ -43563,7 +43674,21 @@ var MemoryGuardManager = class {
43563
43674
  * that allows is a call the host still needs to judge.
43564
43675
  */
43565
43676
  async handleBeforeToolCall(event, ctx) {
43566
- if (classifyMemoryRead(event, ctx, this.opts.memoryReadClassifier)) {
43677
+ let isMemoryRead;
43678
+ try {
43679
+ isMemoryRead = classifyMemoryRead(event, ctx, this.opts.memoryReadClassifier);
43680
+ } catch (err) {
43681
+ const why = err instanceof Error ? err.message : String(err);
43682
+ this.logger.warn("[atbash] memory classifier refused this tool call's input", { reason: why });
43683
+ if (!this.enforce) return null;
43684
+ return {
43685
+ allow: false,
43686
+ block: true,
43687
+ blockReason: `Memory protection could not read this tool call (${why}); blocked because it could not be checked.`,
43688
+ audited: true
43689
+ };
43690
+ }
43691
+ if (isMemoryRead) {
43567
43692
  this.logger.info("[atbash] memory read intercepted \u2014 running sync check");
43568
43693
  return await this.handleMemoryRead(event, ctx);
43569
43694
  }
package/dist/index.mjs CHANGED
@@ -3094,6 +3094,13 @@ function classifyTransportError(err, url, method, timeoutMs) {
3094
3094
  { cause: err }
3095
3095
  );
3096
3096
  }
3097
+ if (code2 === "UND_ERR_CONNECT_TIMEOUT") {
3098
+ return new HttpTransportError(
3099
+ "timeout",
3100
+ `${method} ${url} could not establish a connection before the transport deadline \u2014 check the endpoint and network`,
3101
+ { cause: err }
3102
+ );
3103
+ }
3097
3104
  if (code2 === "ENOTFOUND" || code2 === "EAI_AGAIN") {
3098
3105
  return new HttpTransportError(
3099
3106
  "dns",
@@ -3261,6 +3268,7 @@ var meterProvider = null;
3261
3268
  var callCounter = null;
3262
3269
  var durationHistogram = null;
3263
3270
  var defaultSource = "sdk";
3271
+ var sourceExplicitlySet = false;
3264
3272
  function isTelemetryOptedOut() {
3265
3273
  const disabled = process.env.ATBASH_TELEMETRY_DISABLED?.trim().toLowerCase();
3266
3274
  if (disabled && ["1", "true", "yes", "on"].includes(disabled)) {
@@ -3284,11 +3292,14 @@ function autoInit() {
3284
3292
  }
3285
3293
  function setupTelemetry(config2) {
3286
3294
  if (!config2.enabled) return;
3287
- if (meterProvider) return;
3288
3295
  if (isTelemetryOptedOut()) return;
3296
+ if (config2.source && !sourceExplicitlySet) {
3297
+ defaultSource = config2.source;
3298
+ sourceExplicitlySet = true;
3299
+ }
3300
+ if (meterProvider) return;
3289
3301
  if (!config2.endpoint || !config2.getAuthHeaders) return;
3290
3302
  if (/^https?:\/\/(localhost|127\.0\.0\.1|0\.0\.0\.0)(:|\/|$)/i.test(config2.endpoint)) return;
3291
- defaultSource = config2.source ?? "sdk";
3292
3303
  const proxyUrl = `${config2.endpoint.replace(/\/+$/, "")}/api/telemetry`;
3293
3304
  const getAuthHeaders = config2.getAuthHeaders;
3294
3305
  const exporter = new OTLPMetricExporter({
@@ -3341,6 +3352,8 @@ async function shutdownTelemetry() {
3341
3352
  meterProvider = null;
3342
3353
  callCounter = null;
3343
3354
  durationHistogram = null;
3355
+ defaultSource = "sdk";
3356
+ sourceExplicitlySet = false;
3344
3357
  }
3345
3358
 
3346
3359
  // src-ts/userConfig.ts
@@ -3537,7 +3550,6 @@ var Atbash = class _Atbash {
3537
3550
  try {
3538
3551
  setupTelemetry({
3539
3552
  enabled: true,
3540
- source: "sdk",
3541
3553
  endpoint: this.endpoint,
3542
3554
  getAuthHeaders: () => this.authHeaders()
3543
3555
  });
@@ -35233,9 +35245,9 @@ var ZodUnion = class extends ZodType {
35233
35245
  }
35234
35246
  };
35235
35247
  types.ZodUnion = ZodUnion;
35236
- ZodUnion.create = (types2, params) => {
35248
+ ZodUnion.create = (types3, params) => {
35237
35249
  return new ZodUnion({
35238
- options: types2,
35250
+ options: types3,
35239
35251
  typeName: ZodFirstPartyTypeKind.ZodUnion,
35240
35252
  ...processCreateParams(params)
35241
35253
  });
@@ -38692,9 +38704,9 @@ _nodeUtil.exports;
38692
38704
  var freeProcess = moduleExports && freeGlobal2.process;
38693
38705
  var nodeUtil2 = (function() {
38694
38706
  try {
38695
- var types2 = freeModule && freeModule.require && freeModule.require("util").types;
38696
- if (types2) {
38697
- return types2;
38707
+ var types3 = freeModule && freeModule.require && freeModule.require("util").types;
38708
+ if (types3) {
38709
+ return types3;
38698
38710
  }
38699
38711
  return freeProcess && freeProcess.binding && freeProcess.binding("util");
38700
38712
  } catch (e) {
@@ -43074,12 +43086,96 @@ async function rollbackMemory(toId, reason, auth, opts) {
43074
43086
  }
43075
43087
 
43076
43088
  // src-ts/memory/_json_safe.ts
43089
+ import { types as types2 } from "util";
43090
+ var replacementKeys = [
43091
+ "newText",
43092
+ "new_string",
43093
+ "new_str",
43094
+ "newStr",
43095
+ "replacement"
43096
+ ];
43097
+ var argumentKeys = [
43098
+ "file_path",
43099
+ "path",
43100
+ "filename",
43101
+ "target",
43102
+ "file",
43103
+ "filePath",
43104
+ "content",
43105
+ ...replacementKeys,
43106
+ "value",
43107
+ "text"
43108
+ ];
43109
+ var maxPrototypeDepth = 32;
43110
+ var maxEditSlots = 65536;
43111
+ var maxTextUnits = 16 * 1024 * 1024;
43112
+ function invalid() {
43113
+ throw new TypeError("Unreadable or unsupported memory classifier input");
43114
+ }
43115
+ function dataProperty(value, key3) {
43116
+ let current = value;
43117
+ for (let depth = 0; current !== null; depth++) {
43118
+ if (depth >= maxPrototypeDepth || types2.isProxy(current)) invalid();
43119
+ const descriptor = Object.getOwnPropertyDescriptor(current, key3);
43120
+ if (descriptor) {
43121
+ if (!("value" in descriptor)) invalid();
43122
+ return descriptor.value;
43123
+ }
43124
+ current = Object.getPrototypeOf(current);
43125
+ }
43126
+ return void 0;
43127
+ }
43077
43128
  function toJsonSafe(value) {
43078
- try {
43079
- return JSON.parse(JSON.stringify(value ?? null));
43080
- } catch {
43081
- return null;
43129
+ let textUnits = 0;
43130
+ function scalar(input) {
43131
+ if (input == null) return null;
43132
+ if (typeof input === "string") {
43133
+ textUnits += input.length;
43134
+ if (textUnits > maxTextUnits) invalid();
43135
+ return input;
43136
+ }
43137
+ if (typeof input === "boolean") return input;
43138
+ if (typeof input === "number" && Number.isFinite(input)) return input;
43139
+ return invalid();
43140
+ }
43141
+ function project(input, shape) {
43142
+ if (input == null || typeof input !== "object") return scalar(input);
43143
+ if (types2.isProxy(input) || Array.isArray(input)) invalid();
43144
+ const output = /* @__PURE__ */ Object.create(null);
43145
+ const keys2 = shape === "envelope" ? ["toolName", "name"] : shape === "tool" ? ["name"] : shape === "args" ? argumentKeys : replacementKeys;
43146
+ for (const key3 of keys2) {
43147
+ const field = dataProperty(input, key3);
43148
+ if (field !== void 0) output[key3] = scalar(field);
43149
+ }
43150
+ if (shape === "envelope") {
43151
+ for (const key3 of ["params", "args", "arguments", "tool"]) {
43152
+ const field = dataProperty(input, key3);
43153
+ if (field !== void 0)
43154
+ output[key3] = project(field, key3 === "tool" ? "tool" : "args");
43155
+ }
43156
+ }
43157
+ if (shape === "args") {
43158
+ const edits = dataProperty(input, "edits");
43159
+ if (edits !== void 0) {
43160
+ if (edits !== null && typeof edits === "object" && types2.isProxy(edits))
43161
+ invalid();
43162
+ if (Array.isArray(edits)) {
43163
+ const length = dataProperty(edits, "length");
43164
+ if (typeof length !== "number" || !Number.isInteger(length) || length < 0 || length > maxEditSlots)
43165
+ invalid();
43166
+ const entries = [];
43167
+ for (let index2 = 0; index2 < length; index2++) {
43168
+ entries.push(project(dataProperty(edits, String(index2)), "edit"));
43169
+ }
43170
+ output.edits = entries;
43171
+ } else {
43172
+ output.edits = scalar(edits);
43173
+ }
43174
+ }
43175
+ }
43176
+ return output;
43082
43177
  }
43178
+ return project(value, "envelope");
43083
43179
  }
43084
43180
 
43085
43181
  // src-ts/memory/classifier.ts
@@ -43132,7 +43228,22 @@ async function guardMemoryWrite(input) {
43132
43228
  debug: debug2 = false,
43133
43229
  logger: logger2
43134
43230
  } = input;
43135
- const memEntry = classifyMemoryWrite(event, ctx, { patterns, toolNames });
43231
+ let memEntry;
43232
+ try {
43233
+ memEntry = classifyMemoryWrite(event, ctx, { patterns, toolNames });
43234
+ } catch (err) {
43235
+ const why = err instanceof Error ? err.message : String(err);
43236
+ logger2?.warn?.("[atbash] memory classifier refused this tool call's input", { reason: why });
43237
+ if (!enforce) return { handled: false };
43238
+ return {
43239
+ handled: true,
43240
+ decision: {
43241
+ allow: false,
43242
+ block: true,
43243
+ reason: `Memory protection could not read this tool call (${why}); blocked because it could not be checked.`
43244
+ }
43245
+ };
43246
+ }
43136
43247
  if (debug2) emitDebugProbe(event, ctx, memEntry, logger2);
43137
43248
  if (!memEntry) return { handled: false };
43138
43249
  let scanResult;
@@ -43476,7 +43587,21 @@ var MemoryGuardManager = class {
43476
43587
  * that allows is a call the host still needs to judge.
43477
43588
  */
43478
43589
  async handleBeforeToolCall(event, ctx) {
43479
- if (classifyMemoryRead(event, ctx, this.opts.memoryReadClassifier)) {
43590
+ let isMemoryRead;
43591
+ try {
43592
+ isMemoryRead = classifyMemoryRead(event, ctx, this.opts.memoryReadClassifier);
43593
+ } catch (err) {
43594
+ const why = err instanceof Error ? err.message : String(err);
43595
+ this.logger.warn("[atbash] memory classifier refused this tool call's input", { reason: why });
43596
+ if (!this.enforce) return null;
43597
+ return {
43598
+ allow: false,
43599
+ block: true,
43600
+ blockReason: `Memory protection could not read this tool call (${why}); blocked because it could not be checked.`,
43601
+ audited: true
43602
+ };
43603
+ }
43604
+ if (isMemoryRead) {
43480
43605
  this.logger.info("[atbash] memory read intercepted \u2014 running sync check");
43481
43606
  return await this.handleMemoryRead(event, ctx);
43482
43607
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atbash/sdk",
3
- "version": "0.16.2-dev.0",
3
+ "version": "0.16.4-dev.0",
4
4
  "description": "TypeScript SDK for Atbash — the safety layer that evaluates AI agent actions against operator-defined policies before execution.",
5
5
  "keywords": [
6
6
  "atbash",
@@ -54,7 +54,7 @@
54
54
  "build:native": "napi build --platform --release",
55
55
  "build:native:debug": "napi build --platform",
56
56
  "gen:http": "openapi-typescript ../../spec/openapi.yaml -o src-ts/http/schema.ts",
57
- "build:ts": "tsup",
57
+ "build:ts": "tsup && node scripts/assert-browser-bundle-clean.mjs",
58
58
  "build": "npm run build:native && npm run build:ts",
59
59
  "test:native": "node --test __test__/vector_parity.test.mjs",
60
60
  "test:sdk": "node --test __test__/*.sdk.test.mjs",
@@ -89,10 +89,10 @@
89
89
  "typescript-eslint": "^8.62.1"
90
90
  },
91
91
  "optionalDependencies": {
92
- "@atbash/sdk-linux-x64-gnu": "0.16.2-dev.0",
93
- "@atbash/sdk-linux-arm64-gnu": "0.16.2-dev.0",
94
- "@atbash/sdk-linux-x64-musl": "0.16.2-dev.0",
95
- "@atbash/sdk-darwin-arm64": "0.16.2-dev.0",
96
- "@atbash/sdk-win32-x64-msvc": "0.16.2-dev.0"
92
+ "@atbash/sdk-linux-x64-gnu": "0.16.4-dev.0",
93
+ "@atbash/sdk-linux-arm64-gnu": "0.16.4-dev.0",
94
+ "@atbash/sdk-linux-x64-musl": "0.16.4-dev.0",
95
+ "@atbash/sdk-darwin-arm64": "0.16.4-dev.0",
96
+ "@atbash/sdk-win32-x64-msvc": "0.16.4-dev.0"
97
97
  }
98
98
  }