@cerefox/memory 1.10.1 → 1.12.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.
@@ -7440,7 +7440,7 @@ var exports_meta = {};
7440
7440
  __export(exports_meta, {
7441
7441
  PKG_VERSION: () => PKG_VERSION
7442
7442
  });
7443
- var PKG_VERSION = "1.10.1";
7443
+ var PKG_VERSION = "1.12.0";
7444
7444
  var init_meta = () => {};
7445
7445
 
7446
7446
  // ../../_shared/config/paths.ts
@@ -7468,12 +7468,12 @@ function resolveConfigDir(opts = {}) {
7468
7468
  }
7469
7469
  const here = opts.cwd ?? processCwd();
7470
7470
  const cwdEnv = join(here, ".env");
7471
- if (existsSync(cwdEnv) && cwdEnvHasCerefoxKey(cwdEnv)) {
7471
+ if (existsSync(cwdEnv) && envFileHasCerefoxKey(cwdEnv)) {
7472
7472
  return resolvePath(here);
7473
7473
  }
7474
7474
  return userState;
7475
7475
  }
7476
- function cwdEnvHasCerefoxKey(envPath) {
7476
+ function envFileHasCerefoxKey(envPath) {
7477
7477
  try {
7478
7478
  const contents = readFileSync(envPath, "utf8");
7479
7479
  return /^\s*CEREFOX_[A-Z0-9_]+\s*=/m.test(contents);
@@ -7494,7 +7494,7 @@ function isDevMode(opts = {}) {
7494
7494
  return false;
7495
7495
  const here = opts.cwd ?? processCwd();
7496
7496
  const cwdEnv = join(here, ".env");
7497
- return existsSync(cwdEnv) && cwdEnvHasCerefoxKey(cwdEnv);
7497
+ return existsSync(cwdEnv) && envFileHasCerefoxKey(cwdEnv);
7498
7498
  }
7499
7499
  var USER_STATE_DIR_NAME = ".cerefox";
7500
7500
  var init_paths = () => {};
@@ -7520,11 +7520,11 @@ function parseDotenv(content) {
7520
7520
  return result;
7521
7521
  }
7522
7522
  function loadEnv(opts = {}) {
7523
- if (_loaded) {
7523
+ const envPath = resolveEnvFile(opts);
7524
+ if (_loadedPath === envPath) {
7524
7525
  return { path: "(already loaded)", vars: 0 };
7525
7526
  }
7526
- _loaded = true;
7527
- const envPath = resolveEnvFile(opts);
7527
+ _loadedPath = envPath;
7528
7528
  let content;
7529
7529
  try {
7530
7530
  content = readFileSync2(envPath, "utf8");
@@ -7555,7 +7555,7 @@ function loadSettings(opts = {}) {
7555
7555
  fireworksApiKey: env2.CEREFOX_FIREWORKS_API_KEY ?? ""
7556
7556
  };
7557
7557
  }
7558
- var KV_LINE, _loaded = false;
7558
+ var KV_LINE, _loadedPath = null;
7559
7559
  var init_env = __esm(() => {
7560
7560
  init_paths();
7561
7561
  KV_LINE = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/;
@@ -7565,6 +7565,7 @@ var init_env = __esm(() => {
7565
7565
  var exports_config = {};
7566
7566
  __export(exports_config, {
7567
7567
  USER_STATE_DIR_NAME: () => USER_STATE_DIR_NAME,
7568
+ envFileHasCerefoxKey: () => envFileHasCerefoxKey,
7568
7569
  isDevMode: () => isDevMode,
7569
7570
  loadEnv: () => loadEnv,
7570
7571
  loadSettings: () => loadSettings,
@@ -26002,7 +26003,7 @@ var init_bundled_docs = __esm(() => {
26002
26003
  });
26003
26004
 
26004
26005
  // ../../_shared/ef-meta/index.ts
26005
- var EF_VERSION = "1.10.1", CEREFOX_VERSION = "1.10.1", EF_LAST_CHANGED = "1.10.1";
26006
+ var EF_VERSION = "1.12.0", CEREFOX_VERSION = "1.12.0", EF_LAST_CHANGED = "1.11.0";
26006
26007
  var init_ef_meta = () => {};
26007
26008
 
26008
26009
  // ../../_shared/compatibility/index.ts
@@ -43253,7 +43254,7 @@ var require_nodes = __commonJS(function(exports) {
43253
43254
  }
43254
43255
  });
43255
43256
 
43256
- // ../../node_modules/.bun/@xmldom+xmldom@0.8.13/node_modules/@xmldom/xmldom/lib/conventions.js
43257
+ // ../../node_modules/.bun/@xmldom+xmldom@0.8.15/node_modules/@xmldom/xmldom/lib/conventions.js
43257
43258
  var require_conventions = __commonJS(function(exports) {
43258
43259
  function find(list, predicate, ac) {
43259
43260
  if (ac === undefined) {
@@ -43307,18 +43308,25 @@ var require_conventions = __commonJS(function(exports) {
43307
43308
  XML: "http://www.w3.org/XML/1998/namespace",
43308
43309
  XMLNS: "http://www.w3.org/2000/xmlns/"
43309
43310
  });
43311
+ var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/;
43312
+ var nameChar = new RegExp("[\\-\\.0-9" + nameStartChar.source.slice(1, -1) + "\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
43313
+ var tagNamePattern = new RegExp("^" + nameStartChar.source + nameChar.source + "*(?::" + nameStartChar.source + nameChar.source + "*)?$");
43310
43314
  exports.assign = assign;
43311
43315
  exports.find = find;
43312
43316
  exports.freeze = freeze;
43313
43317
  exports.MIME_TYPE = MIME_TYPE;
43314
43318
  exports.NAMESPACE = NAMESPACE;
43319
+ exports.nameStartChar = nameStartChar;
43320
+ exports.nameChar = nameChar;
43321
+ exports.tagNamePattern = tagNamePattern;
43315
43322
  });
43316
43323
 
43317
- // ../../node_modules/.bun/@xmldom+xmldom@0.8.13/node_modules/@xmldom/xmldom/lib/dom.js
43324
+ // ../../node_modules/.bun/@xmldom+xmldom@0.8.15/node_modules/@xmldom/xmldom/lib/dom.js
43318
43325
  var require_dom = __commonJS(function(exports) {
43319
43326
  var conventions = require_conventions();
43320
43327
  var find = conventions.find;
43321
43328
  var NAMESPACE = conventions.NAMESPACE;
43329
+ var tagNamePattern = conventions.tagNamePattern;
43322
43330
  function notEmptyString(input) {
43323
43331
  return input !== "";
43324
43332
  }
@@ -43459,7 +43467,9 @@ var require_dom = __commonJS(function(exports) {
43459
43467
  return this[i] || null;
43460
43468
  };
43461
43469
  _extends(LiveNodeList, NodeList);
43462
- function NamedNodeMap() {}
43470
+ function NamedNodeMap() {
43471
+ this._nameIndex = Object.create(null);
43472
+ }
43463
43473
  function _findNodeIndex(list, node) {
43464
43474
  var i = list.length;
43465
43475
  while (i--) {
@@ -43468,12 +43478,22 @@ var require_dom = __commonJS(function(exports) {
43468
43478
  }
43469
43479
  }
43470
43480
  }
43481
+ function _nnmIndexAdd(list, attr) {
43482
+ list._nameIndex[attr.nodeName] = attr;
43483
+ }
43484
+ function _nnmIndexRemove(list, attr) {
43485
+ if (list._nameIndex[attr.nodeName] === attr) {
43486
+ delete list._nameIndex[attr.nodeName];
43487
+ }
43488
+ }
43471
43489
  function _addNamedNode(el, list, newAttr, oldAttr) {
43472
43490
  if (oldAttr) {
43473
43491
  list[_findNodeIndex(list, oldAttr)] = newAttr;
43492
+ _nnmIndexRemove(list, oldAttr);
43474
43493
  } else {
43475
43494
  list[list.length++] = newAttr;
43476
43495
  }
43496
+ _nnmIndexAdd(list, newAttr);
43477
43497
  if (el) {
43478
43498
  newAttr.ownerElement = el;
43479
43499
  var doc = el.ownerDocument;
@@ -43491,6 +43511,7 @@ var require_dom = __commonJS(function(exports) {
43491
43511
  list[i] = list[++i];
43492
43512
  }
43493
43513
  list.length = lastIndex;
43514
+ _nnmIndexRemove(list, attr);
43494
43515
  if (el) {
43495
43516
  var doc = el.ownerDocument;
43496
43517
  if (doc) {
@@ -43519,7 +43540,7 @@ var require_dom = __commonJS(function(exports) {
43519
43540
  if (el && el != this._ownerElement) {
43520
43541
  throw new DOMException(INUSE_ATTRIBUTE_ERR);
43521
43542
  }
43522
- var oldAttr = this.getNamedItem(attr.nodeName);
43543
+ var oldAttr = this._nameIndex[attr.nodeName];
43523
43544
  _addNamedNode(this._ownerElement, this, attr, oldAttr);
43524
43545
  return oldAttr;
43525
43546
  },
@@ -43623,8 +43644,29 @@ var require_dom = __commonJS(function(exports) {
43623
43644
  while (child) {
43624
43645
  var next = child.nextSibling;
43625
43646
  if (next !== null && next.nodeType === TEXT_NODE && child.nodeType === TEXT_NODE) {
43626
- node.removeChild(next);
43627
- child.appendData(next.data);
43647
+ var tail = [];
43648
+ var sibling = next;
43649
+ while (sibling !== null && sibling.nodeType === TEXT_NODE) {
43650
+ tail.push(sibling.data);
43651
+ sibling = sibling.nextSibling;
43652
+ }
43653
+ var removed = child.nextSibling;
43654
+ while (removed !== sibling) {
43655
+ var following = removed.nextSibling;
43656
+ removed.parentNode = null;
43657
+ removed.previousSibling = null;
43658
+ removed.nextSibling = null;
43659
+ removed = following;
43660
+ }
43661
+ child.nextSibling = sibling;
43662
+ if (sibling !== null) {
43663
+ sibling.previousSibling = child;
43664
+ } else {
43665
+ node.lastChild = child;
43666
+ }
43667
+ child.appendData(tail.join(""));
43668
+ _onUpdateChild(node.ownerDocument, node);
43669
+ child = sibling;
43628
43670
  } else {
43629
43671
  child = next;
43630
43672
  }
@@ -44082,6 +44124,9 @@ var require_dom = __commonJS(function(exports) {
44082
44124
  return node;
44083
44125
  },
44084
44126
  createEntityReference: function(name) {
44127
+ if (!tagNamePattern.test(name)) {
44128
+ throw new DOMException(INVALID_CHARACTER_ERR, 'not a valid xml name "' + name + '"');
44129
+ }
44085
44130
  var node = new EntityReference;
44086
44131
  node.ownerDocument = this;
44087
44132
  node.nodeName = name;
@@ -44329,7 +44374,10 @@ var require_dom = __commonJS(function(exports) {
44329
44374
  }
44330
44375
  return true;
44331
44376
  }
44332
- function addSerializedAttribute(buf, qualifiedName, value) {
44377
+ function addSerializedAttribute(buf, qualifiedName, value, requireWellFormed) {
44378
+ if (requireWellFormed && !tagNamePattern.test(qualifiedName)) {
44379
+ throw new DOMException(INVALID_STATE_ERR, 'The attribute name "' + qualifiedName + '" is not a valid XML QName');
44380
+ }
44333
44381
  buf.push(" ", qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"');
44334
44382
  }
44335
44383
  function serializeToString(node, buf, isHTML, nodeFilter, visibleNamespaces, requireWellFormed) {
@@ -44387,6 +44435,9 @@ var require_dom = __commonJS(function(exports) {
44387
44435
  }
44388
44436
  }
44389
44437
  }
44438
+ if (requireWellFormed && !tagNamePattern.test(prefixedNodeName)) {
44439
+ throw new DOMException(INVALID_STATE_ERR, 'The element name "' + prefixedNodeName + '" is not a valid XML QName');
44440
+ }
44390
44441
  buf.push("<", prefixedNodeName);
44391
44442
  var childNs = ns.slice();
44392
44443
  for (var i = 0;i < len; i++) {
@@ -44402,7 +44453,7 @@ var require_dom = __commonJS(function(exports) {
44402
44453
  if (needNamespaceDefine(attr, html, childNs)) {
44403
44454
  var attrPrefix = attr.prefix || "";
44404
44455
  var uri = attr.namespaceURI;
44405
- addSerializedAttribute(buf, attrPrefix ? "xmlns:" + attrPrefix : "xmlns", uri);
44456
+ addSerializedAttribute(buf, attrPrefix ? "xmlns:" + attrPrefix : "xmlns", uri, requireWellFormed);
44406
44457
  childNs.push({ prefix: attrPrefix, namespace: uri });
44407
44458
  }
44408
44459
  var filteredAttr = nodeFilter ? nodeFilter(attr) : attr;
@@ -44410,14 +44461,14 @@ var require_dom = __commonJS(function(exports) {
44410
44461
  if (typeof filteredAttr === "string") {
44411
44462
  buf.push(filteredAttr);
44412
44463
  } else {
44413
- addSerializedAttribute(buf, filteredAttr.name, filteredAttr.value);
44464
+ addSerializedAttribute(buf, filteredAttr.name, filteredAttr.value, requireWellFormed);
44414
44465
  }
44415
44466
  }
44416
44467
  }
44417
44468
  if (nodeName === prefixedNodeName && needNamespaceDefine(n, html, childNs)) {
44418
44469
  var nodePrefix = n.prefix || "";
44419
44470
  var uri = n.namespaceURI;
44420
- addSerializedAttribute(buf, nodePrefix ? "xmlns:" + nodePrefix : "xmlns", uri);
44471
+ addSerializedAttribute(buf, nodePrefix ? "xmlns:" + nodePrefix : "xmlns", uri, requireWellFormed);
44421
44472
  childNs.push({ prefix: nodePrefix, namespace: uri });
44422
44473
  }
44423
44474
  var child = n.firstChild;
@@ -44444,7 +44495,7 @@ var require_dom = __commonJS(function(exports) {
44444
44495
  case DOCUMENT_FRAGMENT_NODE:
44445
44496
  return { ns: ns.slice(), isHTML: html, tag: null };
44446
44497
  case ATTRIBUTE_NODE:
44447
- addSerializedAttribute(buf, n.name, n.value);
44498
+ addSerializedAttribute(buf, n.name, n.value, requireWellFormed);
44448
44499
  return null;
44449
44500
  case TEXT_NODE:
44450
44501
  buf.push(n.data.replace(/[<&>]/g, _xmlEncoder));
@@ -44463,6 +44514,9 @@ var require_dom = __commonJS(function(exports) {
44463
44514
  return null;
44464
44515
  case DOCUMENT_TYPE_NODE:
44465
44516
  if (requireWellFormed) {
44517
+ if (!tagNamePattern.test(n.name)) {
44518
+ throw new DOMException(INVALID_STATE_ERR, 'The doctype name "' + n.name + '" is not a valid XML Name');
44519
+ }
44466
44520
  if (n.publicId && !/^("[\x20\r\na-zA-Z0-9\-()+,.\/:=?;!*#@$_%']*"|'[\x20\r\na-zA-Z0-9\-()+,.\/:=?;!*#@$_%'"]*')$/.test(n.publicId)) {
44467
44521
  throw new DOMException(INVALID_STATE_ERR, "DocumentType publicId is not a valid PubidLiteral");
44468
44522
  }
@@ -44493,12 +44547,20 @@ var require_dom = __commonJS(function(exports) {
44493
44547
  }
44494
44548
  return null;
44495
44549
  case PROCESSING_INSTRUCTION_NODE:
44496
- if (requireWellFormed && n.data.indexOf("?>") !== -1) {
44497
- throw new DOMException(INVALID_STATE_ERR, 'The ProcessingInstruction data contains "?>"');
44550
+ if (requireWellFormed) {
44551
+ if (!tagNamePattern.test(n.target) || n.target.indexOf(":") !== -1 || n.target.toLowerCase() === "xml") {
44552
+ throw new DOMException(INVALID_STATE_ERR, 'The processing instruction target "' + n.target + '" is not a valid XML NCName or is reserved');
44553
+ }
44554
+ if (n.data.indexOf("?>") !== -1) {
44555
+ throw new DOMException(INVALID_STATE_ERR, 'The ProcessingInstruction data contains "?>"');
44556
+ }
44498
44557
  }
44499
44558
  buf.push("<?", n.target, " ", n.data, "?>");
44500
44559
  return null;
44501
44560
  case ENTITY_REFERENCE_NODE:
44561
+ if (requireWellFormed && !tagNamePattern.test(n.nodeName)) {
44562
+ throw new DOMException(INVALID_STATE_ERR, 'The entity reference name "' + n.nodeName + '" is not a valid XML Name');
44563
+ }
44502
44564
  buf.push("&", n.nodeName, ";");
44503
44565
  return null;
44504
44566
  default:
@@ -44637,7 +44699,7 @@ var require_dom = __commonJS(function(exports) {
44637
44699
  exports.XMLSerializer = XMLSerializer;
44638
44700
  });
44639
44701
 
44640
- // ../../node_modules/.bun/@xmldom+xmldom@0.8.13/node_modules/@xmldom/xmldom/lib/entities.js
44702
+ // ../../node_modules/.bun/@xmldom+xmldom@0.8.15/node_modules/@xmldom/xmldom/lib/entities.js
44641
44703
  var require_entities = __commonJS(function(exports) {
44642
44704
  var freeze = require_conventions().freeze;
44643
44705
  exports.XML_ENTITIES = freeze({
@@ -46778,12 +46840,10 @@ var require_entities = __commonJS(function(exports) {
46778
46840
  exports.entityMap = exports.HTML_ENTITIES;
46779
46841
  });
46780
46842
 
46781
- // ../../node_modules/.bun/@xmldom+xmldom@0.8.13/node_modules/@xmldom/xmldom/lib/sax.js
46843
+ // ../../node_modules/.bun/@xmldom+xmldom@0.8.15/node_modules/@xmldom/xmldom/lib/sax.js
46782
46844
  var require_sax = __commonJS(function(exports) {
46783
46845
  var NAMESPACE = require_conventions().NAMESPACE;
46784
- var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/;
46785
- var nameChar = new RegExp("[\\-\\.0-9" + nameStartChar.source.slice(1, -1) + "\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
46786
- var tagNamePattern = new RegExp("^" + nameStartChar.source + nameChar.source + "*(?::" + nameStartChar.source + nameChar.source + "*)?$");
46846
+ var tagNamePattern = require_conventions().tagNamePattern;
46787
46847
  var S_TAG = 0;
46788
46848
  var S_ATTR = 1;
46789
46849
  var S_ATTR_SPACE = 2;
@@ -46872,7 +46932,7 @@ var require_sax = __commonJS(function(exports) {
46872
46932
  switch (source.charAt(tagStart + 1)) {
46873
46933
  case "/":
46874
46934
  var end = source.indexOf(">", tagStart + 3);
46875
- var tagName = source.substring(tagStart + 2, end).replace(/[ \t\n\r]+$/g, "");
46935
+ var tagName = source.substring(tagStart + 2, end).replace(/^([\s\S]*?[^ \t\n\r])?[ \t\n\r]*$/, "$1");
46876
46936
  var config = parseStack.pop();
46877
46937
  if (end < 0) {
46878
46938
  tagName = source.substring(tagStart + 2).replace(/[\s<].*/, "");
@@ -46882,6 +46942,8 @@ var require_sax = __commonJS(function(exports) {
46882
46942
  tagName = tagName.replace(/[\s<].*/, "");
46883
46943
  errorHandler.error("end tag name: " + tagName + " maybe not complete");
46884
46944
  end = tagStart + 1 + tagName.length;
46945
+ } else if (/[ \t\n\r]/.test(tagName) && tagNamePattern.test(tagName.split(/[ \t\n\r]/)[0])) {
46946
+ errorHandler.error('end tag name is followed by whitespace and trailing content: "' + tagName + '"');
46885
46947
  }
46886
46948
  var localNSMap = config.localNSMap;
46887
46949
  var endMatch = config.tagName == tagName;
@@ -46978,6 +47040,9 @@ var require_sax = __commonJS(function(exports) {
46978
47040
  var s = S_TAG;
46979
47041
  while (true) {
46980
47042
  var c2 = source.charAt(p);
47043
+ if (s === S_TAG && c2 === "<") {
47044
+ throw new Error("unexpected < in tag name: " + source.slice(start, p));
47045
+ }
46981
47046
  switch (c2) {
46982
47047
  case "=":
46983
47048
  if (s === S_ATTR) {
@@ -47145,7 +47210,7 @@ var require_sax = __commonJS(function(exports) {
47145
47210
  if (nsPrefix !== false) {
47146
47211
  if (localNSMap == null) {
47147
47212
  localNSMap = {};
47148
- _copy(currentNSMap, currentNSMap = {});
47213
+ currentNSMap = Object.create(currentNSMap);
47149
47214
  }
47150
47215
  currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
47151
47216
  a.uri = NAMESPACE.XMLNS;
@@ -47334,7 +47399,7 @@ var require_sax = __commonJS(function(exports) {
47334
47399
  exports.ParseError = ParseError;
47335
47400
  });
47336
47401
 
47337
- // ../../node_modules/.bun/@xmldom+xmldom@0.8.13/node_modules/@xmldom/xmldom/lib/dom-parser.js
47402
+ // ../../node_modules/.bun/@xmldom+xmldom@0.8.15/node_modules/@xmldom/xmldom/lib/dom-parser.js
47338
47403
  var require_dom_parser = __commonJS(function(exports) {
47339
47404
  var conventions = require_conventions();
47340
47405
  var dom = require_dom();
@@ -47537,7 +47602,7 @@ var require_dom_parser = __commonJS(function(exports) {
47537
47602
  exports.DOMParser = DOMParser;
47538
47603
  });
47539
47604
 
47540
- // ../../node_modules/.bun/@xmldom+xmldom@0.8.13/node_modules/@xmldom/xmldom/lib/index.js
47605
+ // ../../node_modules/.bun/@xmldom+xmldom@0.8.15/node_modules/@xmldom/xmldom/lib/index.js
47541
47606
  var require_lib5 = __commonJS(function(exports) {
47542
47607
  var dom = require_dom();
47543
47608
  exports.DOMImplementation = dom.DOMImplementation;
@@ -55096,9 +55161,13 @@ var init_audit_log = __esm(() => {
55096
55161
  };
55097
55162
  });
55098
55163
 
55164
+ // ../../_shared/mcp-tools/access-paths.ts
55165
+ var init_access_paths = () => {};
55166
+
55099
55167
  // ../../_shared/mcp-tools/types.ts
55100
55168
  var McpInvalidParams;
55101
55169
  var init_types3 = __esm(() => {
55170
+ init_access_paths();
55102
55171
  McpInvalidParams = class McpInvalidParams extends Error {
55103
55172
  constructor(message) {
55104
55173
  super(message);
@@ -66863,13 +66932,32 @@ var require_data = __commonJS(function(exports, module) {
66863
66932
  };
66864
66933
  });
66865
66934
 
66866
- // ../../node_modules/.bun/fast-uri@3.1.5/node_modules/fast-uri/lib/utils.js
66935
+ // ../../node_modules/.bun/fast-uri@3.1.7/node_modules/fast-uri/lib/utils.js
66867
66936
  var require_utils2 = __commonJS(function(exports, module) {
66868
66937
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
66869
66938
  var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
66939
+ var isPort = RegExp.prototype.test.bind(/^\d*$/u);
66870
66940
  var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
66871
66941
  var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
66872
- var isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);
66942
+ var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
66943
+ var isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/?]$/u);
66944
+ var isUserinfoCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:]$/u);
66945
+ var BYTE_HEX = new Array(256);
66946
+ {
66947
+ const HEX_DIGITS = "0123456789ABCDEF";
66948
+ for (let i = 0;i < 256; i++) {
66949
+ BYTE_HEX[i] = "%" + HEX_DIGITS[i >> 4] + HEX_DIGITS[i & 15];
66950
+ }
66951
+ }
66952
+ function percentEncodeNonAscii(cp) {
66953
+ if (cp < 2048) {
66954
+ return BYTE_HEX[192 | cp >> 6] + BYTE_HEX[128 | cp & 63];
66955
+ }
66956
+ if (cp < 65536) {
66957
+ return BYTE_HEX[224 | cp >> 12] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
66958
+ }
66959
+ return BYTE_HEX[240 | cp >> 18] + BYTE_HEX[128 | cp >> 12 & 63] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
66960
+ }
66873
66961
  function stringArrayToHexStripped(input) {
66874
66962
  let acc = "";
66875
66963
  let code = 0;
@@ -66894,91 +66982,122 @@ var require_utils2 = __commonJS(function(exports, module) {
66894
66982
  }
66895
66983
  return acc;
66896
66984
  }
66985
+ var isHextet = RegExp.prototype.test.bind(/^[\dA-Fa-f]{1,4}$/);
66986
+ var isIPvFuture = RegExp.prototype.test.bind(/^[vV][\dA-Fa-f]+\.[A-Za-z\d\-._~!$&'()*+,;=:]+$/);
66987
+ var isZoneCharacter = RegExp.prototype.test.bind(/^[A-Za-z\d\-._~]$/);
66897
66988
  var nonSimpleDomain = RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);
66898
- function consumeIsZone(buffer2) {
66899
- buffer2.length = 0;
66900
- return true;
66901
- }
66902
- function consumeHextets(buffer2, address, output) {
66903
- if (buffer2.length) {
66904
- const hex = stringArrayToHexStripped(buffer2);
66905
- if (hex !== "") {
66906
- address.push(hex);
66907
- } else {
66908
- output.error = true;
66909
- return false;
66989
+ function isZoneIdentifier(zone) {
66990
+ if (zone.length === 0)
66991
+ return false;
66992
+ for (let i = 0;i < zone.length; i++) {
66993
+ if (isZoneCharacter(zone[i]))
66994
+ continue;
66995
+ if (zone[i] === "%" && i + 2 < zone.length && isHexPair(zone.slice(i + 1, i + 3))) {
66996
+ i += 2;
66997
+ continue;
66910
66998
  }
66911
- buffer2.length = 0;
66999
+ return false;
66912
67000
  }
66913
67001
  return true;
66914
67002
  }
66915
- function getIPV6(input) {
66916
- let tokenCount = 0;
66917
- const output = { error: false, address: "", zone: "" };
66918
- const address = [];
66919
- const buffer2 = [];
66920
- let endipv6Encountered = false;
66921
- let endIpv6 = false;
66922
- let consume = consumeHextets;
66923
- for (let i = 0;i < input.length; i++) {
66924
- const cursor = input[i];
66925
- if (cursor === "[" || cursor === "]") {
66926
- continue;
66927
- }
66928
- if (cursor === ":") {
66929
- if (endipv6Encountered === true) {
66930
- endIpv6 = true;
66931
- }
66932
- if (!consume(buffer2, address, output)) {
66933
- break;
66934
- }
66935
- if (++tokenCount > 7) {
66936
- output.error = true;
66937
- break;
67003
+ function compressIPv6ZeroRun(hextets) {
67004
+ let bestStart = -1;
67005
+ let bestLength = 0;
67006
+ let runStart = -1;
67007
+ let runLength = 0;
67008
+ for (let i = 0;i < hextets.length; i++) {
67009
+ if (hextets[i] === "0") {
67010
+ if (runStart === -1)
67011
+ runStart = i;
67012
+ runLength++;
67013
+ if (runLength > bestLength) {
67014
+ bestLength = runLength;
67015
+ bestStart = runStart;
66938
67016
  }
66939
- if (i > 0 && input[i - 1] === ":") {
66940
- endipv6Encountered = true;
66941
- }
66942
- address.push(":");
66943
- continue;
66944
- } else if (cursor === "%") {
66945
- if (!consume(buffer2, address, output)) {
66946
- break;
66947
- }
66948
- consume = consumeIsZone;
66949
67017
  } else {
66950
- buffer2.push(cursor);
66951
- continue;
67018
+ runStart = -1;
67019
+ runLength = 0;
66952
67020
  }
66953
67021
  }
66954
- if (buffer2.length) {
66955
- if (consume === consumeIsZone) {
66956
- output.zone = buffer2.join("");
66957
- } else if (endIpv6) {
66958
- address.push(buffer2.join(""));
66959
- } else {
66960
- address.push(stringArrayToHexStripped(buffer2));
67022
+ if (bestLength < 2)
67023
+ return hextets.join(":");
67024
+ const head2 = hextets.slice(0, bestStart).join(":");
67025
+ const tail = hextets.slice(bestStart + bestLength).join(":");
67026
+ return head2 + "::" + tail;
67027
+ }
67028
+ function normalizeIPv6Address(input) {
67029
+ const compression = input.indexOf("::");
67030
+ if (compression !== -1 && input.indexOf("::", compression + 1) !== -1)
67031
+ return;
67032
+ const left = compression === -1 ? input.split(":") : input.slice(0, compression).split(":");
67033
+ const right = compression === -1 ? [] : input.slice(compression + 2).split(":");
67034
+ if (compression !== -1) {
67035
+ if (left.length === 1 && left[0] === "")
67036
+ left.length = 0;
67037
+ if (right.length === 1 && right[0] === "")
67038
+ right.length = 0;
67039
+ }
67040
+ const parts = left.concat(right);
67041
+ let hextetCount = 0;
67042
+ for (let i = 0;i < parts.length; i++) {
67043
+ const part = parts[i];
67044
+ if (part === "")
67045
+ return;
67046
+ if (part.indexOf(".") !== -1) {
67047
+ if (i !== parts.length - 1 || compression !== -1 && right.length === 0 || !isIPv4(part))
67048
+ return;
67049
+ hextetCount += 2;
67050
+ continue;
66961
67051
  }
67052
+ if (!isHextet(part))
67053
+ return;
67054
+ parts[i] = parseInt(part, 16).toString(16);
67055
+ hextetCount++;
66962
67056
  }
66963
- output.address = address.join("");
66964
- return output;
67057
+ if (compression === -1) {
67058
+ if (hextetCount !== 8)
67059
+ return;
67060
+ return compressIPv6ZeroRun(parts);
67061
+ }
67062
+ if (hextetCount >= 8)
67063
+ return;
67064
+ const expanded = parts.slice(0, left.length);
67065
+ for (let i = hextetCount;i < 8; i++)
67066
+ expanded.push("0");
67067
+ for (let i = left.length;i < parts.length; i++)
67068
+ expanded.push(parts[i]);
67069
+ return compressIPv6ZeroRun(expanded);
66965
67070
  }
66966
67071
  function normalizeIPv6(host) {
66967
- if (findToken(host, ":") < 2) {
66968
- return { host, isIPV6: false };
66969
- }
66970
- const ipv62 = getIPV6(host);
66971
- if (!ipv62.error) {
66972
- let newHost = ipv62.address;
66973
- let escapedHost = ipv62.address;
66974
- if (ipv62.zone) {
66975
- newHost += "%" + ipv62.zone;
66976
- escapedHost += "%25" + ipv62.zone;
66977
- }
66978
- return { host: newHost, isIPV6: true, escapedHost };
66979
- } else {
66980
- return { host, isIPV6: false };
66981
- }
67072
+ const bracketed = host[0] === "[" && host[host.length - 1] === "]";
67073
+ const hasBracket = host[0] === "[" || host[host.length - 1] === "]";
67074
+ if (hasBracket && !bracketed)
67075
+ return { host, isIPV6: false, error: true };
67076
+ let input = bracketed ? host.slice(1, -1) : host;
67077
+ if (bracketed && isIPvFuture(input)) {
67078
+ input = input.toLowerCase();
67079
+ return { host: `[${input}]`, escapedHost: input, isIPV6: false, isIPVFuture: true };
67080
+ }
67081
+ if (findToken(input, ":") < 2) {
67082
+ return { host, isIPV6: false, error: bracketed };
67083
+ }
67084
+ let zoneIdentifier = "";
67085
+ const zoneSeparator = input.indexOf("%");
67086
+ if (zoneSeparator !== -1) {
67087
+ const separatorLength = input.slice(zoneSeparator, zoneSeparator + 3).toLowerCase() === "%25" ? 3 : 1;
67088
+ zoneIdentifier = input.slice(zoneSeparator + separatorLength);
67089
+ if (!isZoneIdentifier(zoneIdentifier))
67090
+ return { host, isIPV6: false, error: true };
67091
+ input = input.slice(0, zoneSeparator);
67092
+ }
67093
+ const address = normalizeIPv6Address(input);
67094
+ if (address === undefined)
67095
+ return { host, isIPV6: false, error: true };
67096
+ return {
67097
+ host: address + (zoneIdentifier ? "%" + zoneIdentifier : ""),
67098
+ escapedHost: address + (zoneIdentifier ? "%25" + zoneIdentifier : ""),
67099
+ isIPV6: true
67100
+ };
66982
67101
  }
66983
67102
  function findToken(str, token) {
66984
67103
  let ind = 0;
@@ -67098,7 +67217,8 @@ var require_utils2 = __commonJS(function(exports, module) {
67098
67217
  function normalizePathEncoding(input) {
67099
67218
  let output = "";
67100
67219
  for (let i = 0;i < input.length; i++) {
67101
- if (input[i] === "%" && i + 2 < input.length) {
67220
+ const ch = input[i];
67221
+ if (ch === "%" && i + 2 < input.length) {
67102
67222
  const hex = input.slice(i + 1, i + 3);
67103
67223
  if (isHexPair(hex)) {
67104
67224
  const normalizedHex = hex.toUpperCase();
@@ -67112,10 +67232,152 @@ var require_utils2 = __commonJS(function(exports, module) {
67112
67232
  continue;
67113
67233
  }
67114
67234
  }
67115
- if (isPathCharacter(input[i])) {
67116
- output += input[i];
67235
+ if (isPathCharacter(ch)) {
67236
+ output += ch;
67237
+ } else {
67238
+ const code = input.charCodeAt(i);
67239
+ if (code < 128) {
67240
+ output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
67241
+ } else if (code < 55296 || code > 57343) {
67242
+ output += percentEncodeNonAscii(code);
67243
+ } else if (code <= 56319 && i + 1 < input.length) {
67244
+ const low = input.charCodeAt(i + 1);
67245
+ if (low >= 56320 && low <= 57343) {
67246
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
67247
+ i++;
67248
+ } else {
67249
+ output += percentEncodeNonAscii(65533);
67250
+ }
67251
+ } else {
67252
+ output += percentEncodeNonAscii(65533);
67253
+ }
67254
+ }
67255
+ }
67256
+ return output;
67257
+ }
67258
+ function serializePathEncoding(input, pathNoScheme = false) {
67259
+ let output = "";
67260
+ let firstSegment = pathNoScheme && input[0] !== "/";
67261
+ for (let i = 0;i < input.length; i++) {
67262
+ const ch = input[i];
67263
+ if (ch === "%" && i + 2 < input.length) {
67264
+ const hex = input.slice(i + 1, i + 3);
67265
+ if (isHexPair(hex)) {
67266
+ output += "%" + hex.toUpperCase();
67267
+ i += 2;
67268
+ continue;
67269
+ }
67270
+ }
67271
+ if (ch === "/") {
67272
+ firstSegment = false;
67273
+ }
67274
+ if (isPathCharacter(ch) && (ch !== ":" || !firstSegment)) {
67275
+ output += ch;
67276
+ } else {
67277
+ const code = input.charCodeAt(i);
67278
+ if (code < 128) {
67279
+ output += BYTE_HEX[code];
67280
+ } else if (code < 55296 || code > 57343) {
67281
+ output += percentEncodeNonAscii(code);
67282
+ } else if (code <= 56319 && i + 1 < input.length) {
67283
+ const low = input.charCodeAt(i + 1);
67284
+ if (low >= 56320 && low <= 57343) {
67285
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
67286
+ i++;
67287
+ } else {
67288
+ output += percentEncodeNonAscii(65533);
67289
+ }
67290
+ } else {
67291
+ output += percentEncodeNonAscii(65533);
67292
+ }
67293
+ }
67294
+ }
67295
+ return output;
67296
+ }
67297
+ function encodeComponent(input, isAllowed) {
67298
+ let output = "";
67299
+ for (let i = 0;i < input.length; i++) {
67300
+ const ch = input[i];
67301
+ if (ch === "%" && i + 2 < input.length) {
67302
+ const hex = input.slice(i + 1, i + 3);
67303
+ if (isHexPair(hex)) {
67304
+ output += "%" + hex.toUpperCase();
67305
+ i += 2;
67306
+ continue;
67307
+ }
67308
+ }
67309
+ if (isAllowed(ch)) {
67310
+ output += ch;
67311
+ } else {
67312
+ const code = input.charCodeAt(i);
67313
+ if (code < 128) {
67314
+ output += BYTE_HEX[code];
67315
+ } else if (code < 55296 || code > 57343) {
67316
+ output += percentEncodeNonAscii(code);
67317
+ } else if (code <= 56319 && i + 1 < input.length) {
67318
+ const low = input.charCodeAt(i + 1);
67319
+ if (low >= 56320 && low <= 57343) {
67320
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
67321
+ i++;
67322
+ } else {
67323
+ output += percentEncodeNonAscii(65533);
67324
+ }
67325
+ } else {
67326
+ output += percentEncodeNonAscii(65533);
67327
+ }
67328
+ }
67329
+ }
67330
+ return output;
67331
+ }
67332
+ function encodeUserinfo(input) {
67333
+ return encodeComponent(input, isUserinfoCharacter);
67334
+ }
67335
+ function encodeQuery(input) {
67336
+ return encodeComponent(input, isQueryFragmentCharacter);
67337
+ }
67338
+ function encodeFragment(input) {
67339
+ return encodeComponent(input, isQueryFragmentCharacter);
67340
+ }
67341
+ function isEscapeSafe(cp) {
67342
+ return cp >= 48 && cp <= 57 || cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122 || cp === 42 || cp === 43 || cp === 45 || cp === 46 || cp === 47 || cp === 64 || cp === 95;
67343
+ }
67344
+ function normalizeQueryFragmentEncoding(input) {
67345
+ let output = "";
67346
+ for (let i = 0;i < input.length; i++) {
67347
+ const ch = input[i];
67348
+ if (ch === "%" && i + 2 < input.length) {
67349
+ const hex = input.slice(i + 1, i + 3);
67350
+ if (isHexPair(hex)) {
67351
+ const normalizedHex = hex.toUpperCase();
67352
+ const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
67353
+ if (isUnreserved(decoded)) {
67354
+ output += decoded;
67355
+ } else {
67356
+ output += "%" + normalizedHex;
67357
+ }
67358
+ i += 2;
67359
+ continue;
67360
+ }
67361
+ }
67362
+ if (isQueryFragmentCharacter(ch)) {
67363
+ output += ch;
67117
67364
  } else {
67118
- output += escape(input[i]);
67365
+ const code = input.charCodeAt(i);
67366
+ if (code < 128) {
67367
+ output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
67368
+ } else if (code < 55296 || code > 57343) {
67369
+ output += percentEncodeNonAscii(code);
67370
+ } else if (code <= 56319 && i + 1 < input.length) {
67371
+ const low = input.charCodeAt(i + 1);
67372
+ if (low >= 56320 && low <= 57343) {
67373
+ output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
67374
+ i++;
67375
+ } else {
67376
+ output += percentEncodeNonAscii(65533);
67377
+ }
67378
+ } else {
67379
+ output += percentEncodeNonAscii(65533);
67380
+ }
67119
67381
  }
67120
67382
  }
67121
67383
  return output;
@@ -67138,14 +67400,18 @@ var require_utils2 = __commonJS(function(exports, module) {
67138
67400
  function recomposeAuthority(component) {
67139
67401
  const uriTokens = [];
67140
67402
  if (component.userinfo !== undefined) {
67141
- uriTokens.push(component.userinfo);
67403
+ uriTokens.push(encodeUserinfo(component.userinfo));
67142
67404
  uriTokens.push("@");
67143
67405
  }
67144
67406
  if (component.host !== undefined) {
67145
- let host = unescape(component.host);
67407
+ let host = component.host;
67146
67408
  if (!isIPv4(host)) {
67147
- const ipV6res = normalizeIPv6(host);
67148
- if (ipV6res.isIPV6 === true) {
67409
+ let ipV6res = normalizeIPv6(host);
67410
+ if (ipV6res.isIPV6 !== true && ipV6res.isIPVFuture !== true) {
67411
+ host = normalizePercentEncoding(host, true);
67412
+ ipV6res = normalizeIPv6(host);
67413
+ }
67414
+ if (ipV6res.isIPV6 === true || ipV6res.isIPVFuture === true) {
67149
67415
  host = `[${ipV6res.escapedHost}]`;
67150
67416
  } else {
67151
67417
  host = reescapeHostDelimiters(host, false);
@@ -67154,8 +67420,12 @@ var require_utils2 = __commonJS(function(exports, module) {
67154
67420
  uriTokens.push(host);
67155
67421
  }
67156
67422
  if (typeof component.port === "number" || typeof component.port === "string") {
67423
+ const port = String(component.port);
67424
+ if (!isPort(port)) {
67425
+ throw new TypeError("URI port is malformed.");
67426
+ }
67157
67427
  uriTokens.push(":");
67158
- uriTokens.push(String(component.port));
67428
+ uriTokens.push(port);
67159
67429
  }
67160
67430
  return uriTokens.length ? uriTokens.join("") : undefined;
67161
67431
  }
@@ -67165,6 +67435,11 @@ var require_utils2 = __commonJS(function(exports, module) {
67165
67435
  reescapeHostDelimiters,
67166
67436
  normalizePercentEncoding,
67167
67437
  normalizePathEncoding,
67438
+ serializePathEncoding,
67439
+ normalizeQueryFragmentEncoding,
67440
+ encodeUserinfo,
67441
+ encodeQuery,
67442
+ encodeFragment,
67168
67443
  escapePreservingEscapes,
67169
67444
  removeDotSegments,
67170
67445
  isIPv4,
@@ -67174,10 +67449,10 @@ var require_utils2 = __commonJS(function(exports, module) {
67174
67449
  };
67175
67450
  });
67176
67451
 
67177
- // ../../node_modules/.bun/fast-uri@3.1.5/node_modules/fast-uri/lib/schemes.js
67452
+ // ../../node_modules/.bun/fast-uri@3.1.7/node_modules/fast-uri/lib/schemes.js
67178
67453
  var require_schemes = __commonJS(function(exports, module) {
67179
67454
  var { isUUID } = require_utils2();
67180
- var URN_REG = /([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-.:;=@]|%[\da-f]{2})+)/iu;
67455
+ var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
67181
67456
  var supportedSchemeNames = [
67182
67457
  "http",
67183
67458
  "https",
@@ -67232,9 +67507,10 @@ var require_schemes = __commonJS(function(exports, module) {
67232
67507
  wsComponent.secure = undefined;
67233
67508
  }
67234
67509
  if (wsComponent.resourceName) {
67235
- const [path, query] = wsComponent.resourceName.split("?");
67510
+ const queryIndex = wsComponent.resourceName.indexOf("?");
67511
+ const path = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
67236
67512
  wsComponent.path = path && path !== "/" ? path : undefined;
67237
- wsComponent.query = query;
67513
+ wsComponent.query = queryIndex === -1 ? undefined : wsComponent.resourceName.slice(queryIndex + 1);
67238
67514
  wsComponent.resourceName = undefined;
67239
67515
  }
67240
67516
  wsComponent.fragment = undefined;
@@ -67246,7 +67522,7 @@ var require_schemes = __commonJS(function(exports, module) {
67246
67522
  return urnComponent;
67247
67523
  }
67248
67524
  const matches = urnComponent.path.match(URN_REG);
67249
- if (matches) {
67525
+ if (matches && matches[0] === urnComponent.path) {
67250
67526
  const scheme = options.scheme || urnComponent.scheme || "urn";
67251
67527
  urnComponent.nid = matches[1].toLowerCase();
67252
67528
  urnComponent.nss = matches[2];
@@ -67348,10 +67624,19 @@ var require_schemes = __commonJS(function(exports, module) {
67348
67624
  };
67349
67625
  });
67350
67626
 
67351
- // ../../node_modules/.bun/fast-uri@3.1.5/node_modules/fast-uri/index.js
67627
+ // ../../node_modules/.bun/fast-uri@3.1.7/node_modules/fast-uri/index.js
67352
67628
  var require_fast_uri = __commonJS(function(exports, module) {
67353
- var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils2();
67629
+ var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils2();
67354
67630
  var { SCHEMES, getSchemeHandler } = require_schemes();
67631
+ var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
67632
+ var MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
67633
+ function decodeValidScheme(scheme) {
67634
+ const decodedScheme = unescape(String(scheme));
67635
+ if (!VALID_SCHEME.test(decodedScheme)) {
67636
+ throw new TypeError(MALFORMED_SCHEME_ERROR);
67637
+ }
67638
+ return decodedScheme;
67639
+ }
67355
67640
  function normalize(uri, options) {
67356
67641
  if (typeof uri === "string") {
67357
67642
  uri = normalizeString(uri, options);
@@ -67362,12 +67647,34 @@ var require_fast_uri = __commonJS(function(exports, module) {
67362
67647
  }
67363
67648
  function resolve4(baseURI, relativeURI, options) {
67364
67649
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
67365
- const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions);
67366
- const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions);
67367
- if (baseMalformed || relativeMalformed) {
67650
+ const {
67651
+ parsed: baseParsed,
67652
+ malformedAuthorityOrPort: baseMalformed,
67653
+ malformedPercentEncoding: baseMalformedPercentEncoding,
67654
+ malformedSchemeSpecific: baseMalformedSchemeSpecific,
67655
+ malformedHost: baseMalformedHost,
67656
+ malformedScheme: baseMalformedScheme
67657
+ } = parseWithStatus(baseURI, schemelessOptions);
67658
+ const {
67659
+ parsed: relativeParsed,
67660
+ malformedAuthorityOrPort: relativeMalformed,
67661
+ malformedPercentEncoding: relativeMalformedPercentEncoding,
67662
+ malformedSchemeSpecific: relativeMalformedSchemeSpecific,
67663
+ malformedHost: relativeMalformedHost,
67664
+ malformedScheme: relativeMalformedScheme
67665
+ } = parseWithStatus(relativeURI, schemelessOptions);
67666
+ if (baseMalformed || relativeMalformed || baseMalformedPercentEncoding || relativeMalformedPercentEncoding || baseMalformedSchemeSpecific || relativeMalformedSchemeSpecific || baseMalformedHost || relativeMalformedHost || baseMalformedScheme || relativeMalformedScheme) {
67368
67667
  throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
67369
67668
  }
67370
67669
  const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
67670
+ const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
67671
+ const resolvedHost = resolved.host;
67672
+ const resolvedHostIsIP = resolvedHost !== undefined && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
67673
+ canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
67674
+ const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !/\P{ASCII}/u.test(resolvedHost);
67675
+ if (resolved.error && !encodedASCIIHost) {
67676
+ throw new Error(resolved.error);
67677
+ }
67371
67678
  schemelessOptions.skipEscape = true;
67372
67679
  return serialize(resolved, schemelessOptions);
67373
67680
  }
@@ -67427,7 +67734,7 @@ var require_fast_uri = __commonJS(function(exports, module) {
67427
67734
  function equal(uriA, uriB, options) {
67428
67735
  const normalizedA = normalizeComparableURI(uriA, options);
67429
67736
  const normalizedB = normalizeComparableURI(uriB, options);
67430
- return normalizedA !== undefined && normalizedB !== undefined && normalizedA.toLowerCase() === normalizedB.toLowerCase();
67737
+ return normalizedA !== undefined && normalizedB !== undefined && normalizedA === normalizedB;
67431
67738
  }
67432
67739
  function serialize(cmpts, opts) {
67433
67740
  const component = {
@@ -67448,20 +67755,23 @@ var require_fast_uri = __commonJS(function(exports, module) {
67448
67755
  };
67449
67756
  const options = Object.assign({}, opts);
67450
67757
  const uriTokens = [];
67758
+ if (component.scheme) {
67759
+ component.scheme = decodeValidScheme(component.scheme);
67760
+ }
67451
67761
  const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
67452
67762
  if (schemeHandler && schemeHandler.serialize)
67453
67763
  schemeHandler.serialize(component, options);
67764
+ const hasAuthority = component.userinfo !== undefined || component.host !== undefined || component.port !== undefined;
67765
+ const pathNoScheme = !options.skipEscape && component.scheme === undefined && !hasAuthority;
67454
67766
  if (component.path !== undefined) {
67455
67767
  if (!options.skipEscape) {
67456
- component.path = escapePreservingEscapes(component.path);
67457
- if (component.scheme !== undefined) {
67458
- component.path = component.path.split("%3A").join(":");
67459
- }
67768
+ component.path = serializePathEncoding(component.path, pathNoScheme);
67460
67769
  } else {
67461
67770
  component.path = normalizePercentEncoding(component.path);
67462
67771
  }
67463
67772
  }
67464
67773
  if (options.reference !== "suffix" && component.scheme) {
67774
+ component.scheme = decodeValidScheme(component.scheme);
67465
67775
  uriTokens.push(component.scheme, ":");
67466
67776
  }
67467
67777
  const authority = recomposeAuthority(component);
@@ -67479,16 +67789,19 @@ var require_fast_uri = __commonJS(function(exports, module) {
67479
67789
  if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
67480
67790
  s = removeDotSegments(s);
67481
67791
  }
67792
+ if (pathNoScheme) {
67793
+ s = serializePathEncoding(s, true);
67794
+ }
67482
67795
  if (authority === undefined && s[0] === "/" && s[1] === "/") {
67483
67796
  s = "/%2F" + s.slice(2);
67484
67797
  }
67485
67798
  uriTokens.push(s);
67486
67799
  }
67487
67800
  if (component.query !== undefined) {
67488
- uriTokens.push("?", component.query);
67801
+ uriTokens.push("?", encodeQuery(component.query));
67489
67802
  }
67490
67803
  if (component.fragment !== undefined) {
67491
- uriTokens.push("#", component.fragment);
67804
+ uriTokens.push("#", encodeFragment(component.fragment));
67492
67805
  }
67493
67806
  return uriTokens.join("");
67494
67807
  }
@@ -67504,6 +67817,36 @@ var require_fast_uri = __commonJS(function(exports, module) {
67504
67817
  }
67505
67818
  return;
67506
67819
  }
67820
+ function hasMalformedPercentEncoding(component) {
67821
+ if (component === undefined)
67822
+ return false;
67823
+ let percent = component.indexOf("%");
67824
+ while (percent !== -1) {
67825
+ if (percent + 2 >= component.length || !/^[\da-f]{2}$/iu.test(component.slice(percent + 1, percent + 3))) {
67826
+ return true;
67827
+ }
67828
+ percent = component.indexOf("%", percent + 3);
67829
+ }
67830
+ return false;
67831
+ }
67832
+ function isIPLiteral(host) {
67833
+ return host[0] === "[" && host[host.length - 1] === "]";
67834
+ }
67835
+ function hasMalformedComponentPercentEncoding(matches) {
67836
+ const host = matches[4];
67837
+ return hasMalformedPercentEncoding(matches[3]) || host !== undefined && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
67838
+ }
67839
+ function canonicalizeHost(parsed, options, schemeHandler, isIP) {
67840
+ if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
67841
+ try {
67842
+ parsed.host = new URL("http://" + parsed.host).hostname;
67843
+ } catch (e) {
67844
+ parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
67845
+ return true;
67846
+ }
67847
+ }
67848
+ return false;
67849
+ }
67507
67850
  function parseWithStatus(uri, opts) {
67508
67851
  const options = Object.assign({}, opts);
67509
67852
  const parsed = {
@@ -67516,6 +67859,11 @@ var require_fast_uri = __commonJS(function(exports, module) {
67516
67859
  fragment: undefined
67517
67860
  };
67518
67861
  let malformedAuthorityOrPort = false;
67862
+ let malformedPercentEncoding = false;
67863
+ let malformedSchemeSpecific = false;
67864
+ let malformedHost = false;
67865
+ let malformedIPLiteral = false;
67866
+ let malformedScheme = false;
67519
67867
  let isIP = false;
67520
67868
  if (options.reference === "suffix") {
67521
67869
  if (options.scheme) {
@@ -67552,6 +67900,19 @@ var require_fast_uri = __commonJS(function(exports, module) {
67552
67900
  parsed.path = matches[6] || "";
67553
67901
  parsed.query = matches[7];
67554
67902
  parsed.fragment = matches[8];
67903
+ if (parsed.scheme !== undefined) {
67904
+ const decodedScheme = unescape(parsed.scheme);
67905
+ if (VALID_SCHEME.test(decodedScheme)) {
67906
+ parsed.scheme = decodedScheme.toLowerCase();
67907
+ } else {
67908
+ parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
67909
+ malformedScheme = true;
67910
+ }
67911
+ }
67912
+ malformedPercentEncoding = hasMalformedComponentPercentEncoding(matches);
67913
+ if (malformedPercentEncoding) {
67914
+ parsed.error = parsed.error || "URI contains malformed percent-encoding.";
67915
+ }
67555
67916
  if (isNaN(parsed.port)) {
67556
67917
  parsed.port = matches[5];
67557
67918
  }
@@ -67563,9 +67924,16 @@ var require_fast_uri = __commonJS(function(exports, module) {
67563
67924
  if (parsed.host) {
67564
67925
  const ipv4result = isIPv4(parsed.host);
67565
67926
  if (ipv4result === false) {
67927
+ const bracketedIPLiteral = isIPLiteral(parsed.host);
67928
+ const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
67566
67929
  const ipv6result = normalizeIPv6(parsed.host);
67567
- parsed.host = ipv6result.host.toLowerCase();
67568
- isIP = ipv6result.isIPV6;
67930
+ isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
67931
+ malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
67932
+ parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
67933
+ if (malformedIPLiteral) {
67934
+ parsed.error = parsed.error || "URI host is malformed.";
67935
+ malformedAuthorityOrPort = true;
67936
+ }
67569
67937
  } else {
67570
67938
  isIP = true;
67571
67939
  }
@@ -67583,42 +67951,36 @@ var require_fast_uri = __commonJS(function(exports, module) {
67583
67951
  parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
67584
67952
  }
67585
67953
  const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
67586
- if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
67587
- if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
67588
- try {
67589
- parsed.host = new URL("http://" + parsed.host).hostname;
67590
- } catch (e) {
67591
- parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
67592
- }
67593
- }
67954
+ if (!malformedIPLiteral) {
67955
+ malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
67594
67956
  }
67595
67957
  if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
67596
67958
  if (uri.indexOf("%") !== -1) {
67597
- if (parsed.scheme !== undefined) {
67598
- parsed.scheme = unescape(parsed.scheme);
67599
- }
67600
- if (parsed.host !== undefined) {
67601
- parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP);
67959
+ if (parsed.host !== undefined && !malformedIPLiteral) {
67960
+ const host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
67961
+ parsed.host = reescapeHostDelimiters(host, isIP);
67602
67962
  }
67603
67963
  }
67604
67964
  if (parsed.path) {
67605
67965
  parsed.path = normalizePathEncoding(parsed.path);
67606
67966
  }
67967
+ if (parsed.query) {
67968
+ parsed.query = normalizeQueryFragmentEncoding(parsed.query);
67969
+ }
67607
67970
  if (parsed.fragment) {
67608
- try {
67609
- parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
67610
- } catch {
67611
- parsed.error = parsed.error || "URI malformed";
67612
- }
67971
+ parsed.fragment = normalizeQueryFragmentEncoding(parsed.fragment);
67613
67972
  }
67614
67973
  }
67615
67974
  if (schemeHandler && schemeHandler.parse) {
67616
67975
  schemeHandler.parse(parsed, options);
67976
+ if (schemeHandler === SCHEMES.urn && parsed.nid === undefined) {
67977
+ malformedSchemeSpecific = true;
67978
+ }
67617
67979
  }
67618
67980
  } else {
67619
67981
  parsed.error = parsed.error || "URI can not be parsed.";
67620
67982
  }
67621
- return { parsed, malformedAuthorityOrPort };
67983
+ return { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme };
67622
67984
  }
67623
67985
  function parse8(uri, opts) {
67624
67986
  return parseWithStatus(uri, opts).parsed;
@@ -67627,20 +67989,28 @@ var require_fast_uri = __commonJS(function(exports, module) {
67627
67989
  return normalizeStringWithStatus(uri, opts).normalized;
67628
67990
  }
67629
67991
  function normalizeStringWithStatus(uri, opts) {
67630
- const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
67992
+ const { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = parseWithStatus(uri, opts);
67631
67993
  return {
67632
- normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
67633
- malformedAuthorityOrPort
67994
+ normalized: malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? uri : serialize(parsed, opts),
67995
+ malformedAuthorityOrPort,
67996
+ malformedPercentEncoding,
67997
+ malformedSchemeSpecific,
67998
+ malformedHost,
67999
+ malformedScheme
67634
68000
  };
67635
68001
  }
67636
68002
  function normalizeComparableURI(uri, opts) {
67637
- if (typeof uri === "string") {
67638
- const { normalized, malformedAuthorityOrPort } = normalizeStringWithStatus(uri, opts);
67639
- return malformedAuthorityOrPort ? undefined : normalized;
68003
+ if (typeof uri !== "string" && typeof uri !== "object") {
68004
+ return;
67640
68005
  }
67641
- if (typeof uri === "object") {
67642
- return serialize(uri, opts);
68006
+ let value;
68007
+ try {
68008
+ value = typeof uri === "string" ? uri : serialize(uri, opts);
68009
+ } catch {
68010
+ return;
67643
68011
  }
68012
+ const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(value, opts);
68013
+ return malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? undefined : normalized;
67644
68014
  }
67645
68015
  var fastUri = {
67646
68016
  SCHEMES,
@@ -73587,6 +73957,7 @@ Proceed with deployment to Supabase?`, true);
73587
73957
  ▶ Deploying ${efNames.length} Edge Function(s)…`));
73588
73958
  let efOk = 0;
73589
73959
  const efFailed = [];
73960
+ const efOutput = [];
73590
73961
  for (const ef of efNames) {
73591
73962
  info(` deploying ${ef}…`);
73592
73963
  const workdir = assets.functionsDir.replace(/\/functions$/, "").replace(/\/supabase$/, "");
@@ -73599,19 +73970,40 @@ Proceed with deployment to Supabase?`, true);
73599
73970
  }
73600
73971
  const r = spawnSync2("npx", args, {
73601
73972
  encoding: "utf8",
73602
- stdio: "inherit",
73973
+ stdio: ["inherit", "pipe", "pipe"],
73603
73974
  cwd: workdir,
73604
73975
  timeout: 120000
73605
73976
  });
73977
+ if (r.stdout)
73978
+ process.stdout.write(r.stdout);
73979
+ if (r.stderr)
73980
+ process.stderr.write(r.stderr);
73606
73981
  if (r.status === 0)
73607
73982
  efOk++;
73608
- else
73983
+ else {
73609
73984
  efFailed.push(ef);
73985
+ efOutput.push(`${r.stdout ?? ""}
73986
+ ${r.stderr ?? ""}`);
73987
+ }
73610
73988
  }
73611
73989
  if (efFailed.length > 0) {
73612
73990
  eprintln(c.red(`
73613
73991
  ✗ ${efFailed.length} Edge Function(s) failed: ${efFailed.join(", ")}`));
73614
- eprintln(c.dim(" Re-run `cerefox server deploy --functions-only` after fixing the cause."));
73992
+ if (upstreamRegistryRace(efOutput.join(`
73993
+ `))) {
73994
+ eprintln("");
73995
+ eprintln(c.yellow(" This looks like an UPSTREAM package-registry race, not a problem"));
73996
+ eprintln(c.yellow(" with your Cerefox install:"));
73997
+ eprintln(c.dim(" The Edge Functions import `jsr:@supabase/supabase-js@2`. When Supabase"));
73998
+ eprintln(c.dim(" publishes a new version, JSR and npm do not land at the same instant;"));
73999
+ eprintln(c.dim(" a deploy in that gap resolves a JSR package whose npm dependency is not"));
74000
+ eprintln(c.dim(" published yet, and bundling fails."));
74001
+ eprintln(c.dim(" Your deployed functions were NOT changed — the previous version is"));
74002
+ eprintln(c.dim(" still serving, so nothing is down."));
74003
+ eprintln(c.cyan(" → Wait a few minutes, then re-run: cerefox server deploy --functions-only"));
74004
+ } else {
74005
+ eprintln(c.dim(" Re-run `cerefox server deploy --functions-only` after fixing the cause."));
74006
+ }
73615
74007
  process.exit(1);
73616
74008
  }
73617
74009
  println(c.green(` ✓ Deployed ${efOk} Edge Function(s).`));
@@ -73639,6 +74031,9 @@ Proceed with deployment to Supabase?`, true);
73639
74031
  println(c.dim("Verify with: cerefox doctor"));
73640
74032
  println(c.dim("Refresh the bundled guides: cerefox guides ingest"));
73641
74033
  }
74034
+ function upstreamRegistryRace(output) {
74035
+ return /Failed to bundle the function/i.test(output) && /Could not find npm package/i.test(output);
74036
+ }
73642
74037
  function registerDeployServer(program2) {
73643
74038
  program2.command("deploy-server").description("Deploy/update the Cerefox server side (schema + RPCs + Edge Functions) on Supabase.").option("--dry-run", "Print the plan + pre-flight without deploying.").option("--schema-only", "Deploy/update only the schema + RPCs (skip Edge Functions).").option("--functions-only", "Deploy only the Edge Functions (skip the schema/RPCs).").option("--project-ref <ref>", "Supabase project ref for Edge Function deploys (default: derived from CEREFOX_SUPABASE_URL).").option("--yes", "Non-interactive (skip the deployment confirmation).").action(action10);
73644
74039
  }
@@ -77982,21 +78377,22 @@ function checkMcpConfigs() {
77982
78377
  detail: found.join(", ")
77983
78378
  };
77984
78379
  }
77985
- function checkLegacyShadowEnv() {
77986
- const home = homedir6();
77987
- const homeEnv = join9(home, USER_STATE_DIR_NAME, ".env");
77988
- const cwdEnv = join9(process.cwd(), ".env");
77989
- if (!existsSync10(homeEnv) || !existsSync10(cwdEnv))
78380
+ function checkLegacyShadowEnv(opts = {}) {
78381
+ const activeEnv = resolveEnvFile(opts);
78382
+ const cwdEnv = join9(opts.cwd ?? process.cwd(), ".env");
78383
+ if (!existsSync10(activeEnv) || !existsSync10(cwdEnv))
77990
78384
  return null;
77991
78385
  try {
77992
- if (realpathSync(homeEnv) === realpathSync(cwdEnv))
78386
+ if (realpathSync(activeEnv) === realpathSync(cwdEnv))
77993
78387
  return null;
77994
78388
  } catch {}
78389
+ if (!envFileHasCerefoxKey(cwdEnv))
78390
+ return null;
77995
78391
  return {
77996
78392
  name: "legacy env",
77997
78393
  status: "skipped",
77998
- detail: `${cwdEnv} (shadowed by ~/.cerefox/.env)`,
77999
- hint: "Shadowed by ~/.cerefox/.env and no longer read by anything (Python was removed at v1.0.0). Safe to delete."
78394
+ detail: `${cwdEnv} (shadowed by ${activeEnv})`,
78395
+ hint: `Shadowed by ${activeEnv} and no longer read by anything (Python was removed at v1.0.0). Safe to delete.`
78000
78396
  };
78001
78397
  }
78002
78398
  async function checkPostgres() {
@@ -80929,11 +81325,10 @@ function registerStatus(program2) {
80929
81325
  program2.command("status").description("Quick sanity check (fast subset of `cerefox doctor`).").option("--json", "Emit machine-readable JSON.").action(action34);
80930
81326
  }
80931
81327
 
80932
- // src/cli/commands/token.ts
81328
+ // src/cli/commands/api-key.ts
80933
81329
  init_cli_core();
80934
81330
  init_config();
80935
81331
  import { randomBytes } from "node:crypto";
80936
- import { spawnSync as spawnSync7 } from "node:child_process";
80937
81332
 
80938
81333
  // src/cli/util/env-file.ts
80939
81334
  import { copyFileSync as copyFileSync3, existsSync as existsSync14, readFileSync as readFileSync15, writeFileSync as writeFileSync5 } from "node:fs";
@@ -80998,14 +81393,214 @@ function envGitignoreWarning(path) {
80998
81393
  }
80999
81394
  }
81000
81395
 
81396
+ // ../../node_modules/.bun/@hono+node-server@2.0.12+19b9adbcbc3b652f/node_modules/@hono/node-server/dist/conninfo.mjs
81397
+ var getConnInfo = (c2) => {
81398
+ const bindings = c2.env.server ? c2.env.server : c2.env;
81399
+ const address = bindings.incoming.socket.remoteAddress;
81400
+ const port = bindings.incoming.socket.remotePort;
81401
+ const family = bindings.incoming.socket.remoteFamily;
81402
+ return { remote: {
81403
+ address,
81404
+ port,
81405
+ addressType: family === "IPv4" ? "IPv4" : family === "IPv6" ? "IPv6" : undefined
81406
+ } };
81407
+ };
81408
+
81409
+ // ../../_shared/mcp-auth/index.ts
81410
+ function constantTimeEqual(a, b2) {
81411
+ const ab = new TextEncoder().encode(a);
81412
+ const bb = new TextEncoder().encode(b2);
81413
+ const len = Math.max(ab.length, bb.length);
81414
+ let diff = ab.length ^ bb.length;
81415
+ for (let i = 0;i < len; i++) {
81416
+ diff |= (ab[i] ?? 0) ^ (bb[i] ?? 0);
81417
+ }
81418
+ return diff === 0;
81419
+ }
81420
+
81421
+ // ../../_shared/ef-auth/index.ts
81422
+ function parseAccessTokens(raw) {
81423
+ if (!raw)
81424
+ return [];
81425
+ return raw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
81426
+ }
81427
+ var BEARER_PREFIX = "Bearer ";
81428
+ function checkAccessToken(authorizationHeader, config2) {
81429
+ if (!authorizationHeader || !authorizationHeader.startsWith(BEARER_PREFIX)) {
81430
+ return { ok: false, reason: "no_token" };
81431
+ }
81432
+ const token = authorizationHeader.slice(BEARER_PREFIX.length).trim();
81433
+ if (!token)
81434
+ return { ok: false, reason: "no_token" };
81435
+ if (config2.tokens.length === 0) {
81436
+ return {
81437
+ ok: false,
81438
+ reason: "no_tokens_configured",
81439
+ detail: "CEREFOX_ACCESS_TOKENS is unset/empty; refusing to accept-all"
81440
+ };
81441
+ }
81442
+ let matched = false;
81443
+ for (const accepted of config2.tokens) {
81444
+ if (constantTimeEqual(token, accepted))
81445
+ matched = true;
81446
+ }
81447
+ return matched ? { ok: true } : { ok: false, reason: "bad_token" };
81448
+ }
81449
+
81450
+ // src/web/auth.ts
81451
+ var API_KEY_PREFIX = "cfx_lak_";
81452
+ var LOOPBACK_ADDRESSES = new Set([
81453
+ "127.0.0.1",
81454
+ "::1",
81455
+ "::ffff:127.0.0.1"
81456
+ ]);
81457
+ function isLoopbackAddress(address) {
81458
+ if (!address)
81459
+ return false;
81460
+ return LOOPBACK_ADDRESSES.has(address.trim().toLowerCase());
81461
+ }
81462
+ function decideAuth(input) {
81463
+ const keys = input.configuredKeys.trim();
81464
+ if (!keys)
81465
+ return { allow: true, reason: "disabled" };
81466
+ const local = isLoopbackAddress(input.remoteAddress);
81467
+ if (local && !input.requireKeyEverywhere) {
81468
+ return { allow: true, reason: "loopback" };
81469
+ }
81470
+ const result = checkAccessToken(input.authorization, {
81471
+ tokens: parseAccessTokens(keys)
81472
+ });
81473
+ if (result.ok)
81474
+ return { allow: true, reason: "valid_key" };
81475
+ if (result.reason === "no_token") {
81476
+ return {
81477
+ allow: false,
81478
+ reason: "no_key",
81479
+ message: local ? "This server requires an API key on every request (CEREFOX_API_REQUIRE_KEY is set). " + "Send it as `Authorization: Bearer <key>`." : "This request did not come from the local machine, so it needs the server's API key " + "as `Authorization: Bearer <key>`. Print it with `cerefox api-key show` " + "(or `cerefox-local api-key` for a container install)."
81480
+ };
81481
+ }
81482
+ return {
81483
+ allow: false,
81484
+ reason: "bad_key",
81485
+ message: "The API key presented is not valid for this server."
81486
+ };
81487
+ }
81488
+ function apiAuth() {
81489
+ return async (c2, next) => {
81490
+ const decision = decideAuth({
81491
+ remoteAddress: remoteAddressOf(c2),
81492
+ authorization: c2.req.header("Authorization") ?? null,
81493
+ configuredKeys: process.env.CEREFOX_API_KEY ?? "",
81494
+ requireKeyEverywhere: (process.env.CEREFOX_API_REQUIRE_KEY ?? "") === "1"
81495
+ });
81496
+ if (decision.allow)
81497
+ return next();
81498
+ return c2.json({ detail: decision.message }, 401, {
81499
+ "WWW-Authenticate": 'Bearer realm="cerefox"'
81500
+ });
81501
+ };
81502
+ }
81503
+ function remoteAddressOf(c2) {
81504
+ try {
81505
+ return getConnInfo(c2).remote.address;
81506
+ } catch {
81507
+ return;
81508
+ }
81509
+ }
81510
+
81511
+ // src/cli/commands/api-key.ts
81512
+ var ENV_NAME = "CEREFOX_API_KEY";
81513
+ function mint() {
81514
+ return API_KEY_PREFIX + randomBytes(32).toString("base64url");
81515
+ }
81516
+ function mask(key) {
81517
+ const body = key.startsWith(API_KEY_PREFIX) ? key.slice(API_KEY_PREFIX.length) : key;
81518
+ if (body.length <= 8)
81519
+ return `${API_KEY_PREFIX}****`;
81520
+ return `${API_KEY_PREFIX}${body.slice(0, 4)}…${body.slice(-4)}`;
81521
+ }
81522
+ function containerHint() {
81523
+ eprintln(c.dim(` Running Cerefox Local (Docker)? This is not the command you want — the
81524
+ ` + " container mints its own key at boot. Read it with: cerefox-local api-key"));
81525
+ }
81526
+ function writeKey(key, opts, verb) {
81527
+ const envPath = resolveEnvFile();
81528
+ if (opts.dryRun) {
81529
+ println(c.dim(`DRY-RUN: would ${verb} ${ENV_NAME} in ${envPath}`));
81530
+ return;
81531
+ }
81532
+ const result = upsertEnvVar(envPath, ENV_NAME, key, {
81533
+ noBackup: !opts.backup,
81534
+ comment: "Local API key for /api/v1 + /rest/v1 (cerefox api-key). Never sent to Supabase."
81535
+ });
81536
+ println(` ${result.action} ${c.bold(ENV_NAME)} in ${envPath}`);
81537
+ if (result.backupPath)
81538
+ println(c.dim(` backup: ${result.backupPath}`));
81539
+ println("");
81540
+ println(c.bold(" Your API key (shown once, in full):"));
81541
+ println(` ${c.green(key)}`);
81542
+ println("");
81543
+ println(c.dim(` A caller that is NOT on this machine sends it as:
81544
+ ` + ` Authorization: Bearer <key>
81545
+ ` + " Callers on this machine (the web UI, local agents) need nothing."));
81546
+ envGitignoreWarning(envPath);
81547
+ }
81548
+ function generateAction(opts) {
81549
+ const envPath = resolveEnvFile();
81550
+ const existing = readEnvVar(envPath, ENV_NAME);
81551
+ if (existing) {
81552
+ throw userError(`${ENV_NAME} is already set in ${envPath} (${mask(existing)}).`, "Use `cerefox api-key show` to see it, or `cerefox api-key rotate` to replace it. " + "Refusing to overwrite silently: any client already configured with the old key " + "would start getting 401s with no indication why.");
81553
+ }
81554
+ println(c.bold("Minting a local API key"));
81555
+ writeKey(mint(), opts, "write");
81556
+ containerHint();
81557
+ }
81558
+ function rotateAction(opts) {
81559
+ const envPath = resolveEnvFile();
81560
+ const existing = readEnvVar(envPath, ENV_NAME);
81561
+ if (!existing) {
81562
+ throw userError(`No ${ENV_NAME} in ${envPath} — nothing to rotate.`, "Run `cerefox api-key generate` first.");
81563
+ }
81564
+ println(c.bold("Rotating the local API key"));
81565
+ println(c.dim(` replacing ${mask(existing)}`));
81566
+ writeKey(mint(), opts, "replace");
81567
+ println(c.yellow(` The previous key stops working as soon as the server restarts.
81568
+ ` + " Update every remote client, then: cerefox web restart"));
81569
+ }
81570
+ function showAction2() {
81571
+ const envPath = resolveEnvFile();
81572
+ const key = readEnvVar(envPath, ENV_NAME);
81573
+ println(c.bold("Local API key"));
81574
+ if (!key) {
81575
+ println(c.dim(` none set in ${envPath}`));
81576
+ println(c.dim(` The server is not gated: callers from any interface it is bound to can
81577
+ ` + ` reach it without a credential. That is fine while it binds 127.0.0.1.
81578
+ ` + " Mint one with: cerefox api-key generate"));
81579
+ containerHint();
81580
+ return;
81581
+ }
81582
+ println(` ${c.green(key)} ${c.dim(`(${ENV_NAME} in ${envPath})`)}`);
81583
+ println(c.dim(" Remote callers send: Authorization: Bearer <key>"));
81584
+ }
81585
+ function registerApiKey(program2) {
81586
+ const group = program2.command("api-key").description("Manage the local API key for /api/v1 (loopback callers need none).");
81587
+ group.command("generate").description("Mint a local API key and write it to .env. Refuses if one exists.").option("--no-backup", "Skip the .pre-cerefox.bak backup of an existing .env.").option("--dry-run", "Print the plan without minting or writing anything.").action(generateAction);
81588
+ group.command("rotate").description("Replace the existing key. Remote clients must be updated.").option("--no-backup", "Skip the .pre-cerefox.bak backup of an existing .env.").option("--dry-run", "Print the plan without minting or writing anything.").action(rotateAction);
81589
+ group.command("show").description("Print the local API key, in full, for pasting into a client.").action(showAction2);
81590
+ }
81591
+
81001
81592
  // src/cli/commands/token.ts
81593
+ init_cli_core();
81594
+ init_config();
81595
+ import { randomBytes as randomBytes2 } from "node:crypto";
81596
+ import { spawnSync as spawnSync7 } from "node:child_process";
81002
81597
  var SECRET_NAME = "CEREFOX_ACCESS_TOKENS";
81003
81598
  var LOCAL_NAME = "CEREFOX_ACCESS_TOKEN";
81004
81599
  var PREFIX = "cfx_pat_";
81005
81600
  function mintToken() {
81006
- return PREFIX + randomBytes(32).toString("base64url");
81601
+ return PREFIX + randomBytes2(32).toString("base64url");
81007
81602
  }
81008
- function mask(token) {
81603
+ function mask2(token) {
81009
81604
  return token.length <= 16 ? "…" : `${token.slice(0, PREFIX.length + 4)}…${token.slice(-4)}`;
81010
81605
  }
81011
81606
  function parseProjectRef2(supabaseUrl) {
@@ -81023,7 +81618,7 @@ function setSecret(setValue, projectRef, dryRun) {
81023
81618
  if (projectRef)
81024
81619
  args.push("--project-ref", projectRef);
81025
81620
  if (dryRun) {
81026
- const shown = setValue.split(",").map(mask).join(",");
81621
+ const shown = setValue.split(",").map(mask2).join(",");
81027
81622
  println(c.dim(` (dry-run) npx supabase secrets set ${SECRET_NAME}=${shown}` + (projectRef ? ` --project-ref ${projectRef}` : "")));
81028
81623
  return;
81029
81624
  }
@@ -81063,7 +81658,7 @@ function printTokenOnce(token) {
81063
81658
  println(c.dim(" If the GPT Actions schema changed this release, re-paste it too"));
81064
81659
  println(c.dim(" (see docs/guides/connect-agents.md). Lose the token → `cerefox token rotate`."));
81065
81660
  }
81066
- function generateAction(opts) {
81661
+ function generateAction2(opts) {
81067
81662
  const projectRef = opts.projectRef ?? parseProjectRef2(loadSettings().supabaseUrl);
81068
81663
  const token = mintToken();
81069
81664
  println(c.bold("Generating a Cerefox access token…"));
@@ -81072,7 +81667,7 @@ function generateAction(opts) {
81072
81667
  if (!opts.dryRun)
81073
81668
  printTokenOnce(token);
81074
81669
  }
81075
- function rotateAction(opts) {
81670
+ function rotateAction2(opts) {
81076
81671
  const projectRef = opts.projectRef ?? parseProjectRef2(loadSettings().supabaseUrl);
81077
81672
  const envPath = resolveEnvFile();
81078
81673
  const current = readEnvVar(envPath, LOCAL_NAME);
@@ -81102,14 +81697,14 @@ function listAction2() {
81102
81697
  const envPath = resolveEnvFile();
81103
81698
  const local = readEnvVar(envPath, LOCAL_NAME);
81104
81699
  println(c.bold("Cerefox access token"));
81105
- println(local ? ` local (${LOCAL_NAME} in ${envPath}): ${c.green(mask(local))}` : c.dim(` no ${LOCAL_NAME} in ${envPath} — run \`cerefox token generate\``));
81700
+ println(local ? ` local (${LOCAL_NAME} in ${envPath}): ${c.green(mask2(local))}` : c.dim(` no ${LOCAL_NAME} in ${envPath} — run \`cerefox token generate\``));
81106
81701
  println(c.dim(` The server-side accepted set (${SECRET_NAME}) is write-only; list names/digests
81107
81702
  ` + " with: npx supabase secrets list"));
81108
81703
  }
81109
81704
  function registerToken(program2) {
81110
81705
  const token = program2.command("token").description("Manage the Cerefox Edge Function access token(s).");
81111
- token.command("generate").description("Mint a token, set the Supabase secret, and write it to .env.").option("--project-ref <ref>", "Supabase project ref (default: derived from CEREFOX_SUPABASE_URL).").option("--no-env", "Do not write CEREFOX_ACCESS_TOKEN to .env.").option("--no-backup", "Skip the .pre-cerefox.bak backup of an existing .env.").option("--dry-run", "Print the plan without minting or writing anything.").action(generateAction);
81112
- token.command("rotate").description("Mint a new token accepted alongside the old (zero-downtime); --finalize drops the old.").option("--finalize", "Stop accepting the previous token (run after clients migrate).").option("--project-ref <ref>", "Supabase project ref (default: derived from CEREFOX_SUPABASE_URL).").option("--no-env", "Do not write CEREFOX_ACCESS_TOKEN to .env.").option("--no-backup", "Skip the .pre-cerefox.bak backup of an existing .env.").option("--dry-run", "Print the plan without minting or writing anything.").action(rotateAction);
81706
+ token.command("generate").description("Mint a token, set the Supabase secret, and write it to .env.").option("--project-ref <ref>", "Supabase project ref (default: derived from CEREFOX_SUPABASE_URL).").option("--no-env", "Do not write CEREFOX_ACCESS_TOKEN to .env.").option("--no-backup", "Skip the .pre-cerefox.bak backup of an existing .env.").option("--dry-run", "Print the plan without minting or writing anything.").action(generateAction2);
81707
+ token.command("rotate").description("Mint a new token accepted alongside the old (zero-downtime); --finalize drops the old.").option("--finalize", "Stop accepting the previous token (run after clients migrate).").option("--project-ref <ref>", "Supabase project ref (default: derived from CEREFOX_SUPABASE_URL).").option("--no-env", "Do not write CEREFOX_ACCESS_TOKEN to .env.").option("--no-backup", "Skip the .pre-cerefox.bak backup of an existing .env.").option("--dry-run", "Print the plan without minting or writing anything.").action(rotateAction2);
81113
81708
  token.command("list").description("Show the local token (masked) and where the server-side set lives.").action(listAction2);
81114
81709
  }
81115
81710
 
@@ -84457,7 +85052,7 @@ var CONFIG_CATALOG = [
84457
85052
  },
84458
85053
  {
84459
85054
  key: "require_requestor_identity",
84460
- description: "Require a requestor/author on MCP tool calls.",
85055
+ description: "Require a requestor/author. Enforced on the Edge Functions (incl. remote MCP) ONLY — not local MCP, /api/v1 or the CLI.",
84461
85056
  kind: "boolean",
84462
85057
  defaultValue: "false",
84463
85058
  group: "Governance",
@@ -84569,6 +85164,78 @@ function validateConfigValue(key, value) {
84569
85164
 
84570
85165
  // src/web/routes/config.ts
84571
85166
  init_config();
85167
+
85168
+ // src/web/identity.ts
85169
+ var DEFAULT_WEB_AUTHOR = "web-ui";
85170
+ var DEFAULT_WEB_AUTHOR_TYPE = "user";
85171
+ var WEB_UI_IDENTITY = {
85172
+ author: DEFAULT_WEB_AUTHOR,
85173
+ authorType: DEFAULT_WEB_AUTHOR_TYPE,
85174
+ requestor: DEFAULT_WEB_AUTHOR,
85175
+ accessPath: "webapp",
85176
+ named: false
85177
+ };
85178
+ var HEADER = {
85179
+ author: "x-cerefox-author",
85180
+ authorType: "x-cerefox-author-type",
85181
+ requestor: "x-cerefox-requestor"
85182
+ };
85183
+ function readField(c2, headerName, body, bodyKey) {
85184
+ const header = c2.req.header(headerName);
85185
+ if (header !== undefined) {
85186
+ if (header.trim() === "") {
85187
+ return { ok: false, detail: `${headerName} must not be blank.` };
85188
+ }
85189
+ return { ok: true, value: header.trim() };
85190
+ }
85191
+ if (body && bodyKey in body) {
85192
+ const raw2 = body[bodyKey];
85193
+ if (raw2 === null || raw2 === undefined)
85194
+ return { ok: true, value: undefined };
85195
+ if (typeof raw2 !== "string") {
85196
+ return { ok: false, detail: `${bodyKey} must be a string.` };
85197
+ }
85198
+ if (raw2.trim() === "") {
85199
+ return { ok: false, detail: `${bodyKey} must not be blank.` };
85200
+ }
85201
+ return { ok: true, value: raw2.trim() };
85202
+ }
85203
+ return { ok: true, value: undefined };
85204
+ }
85205
+ function resolveCallerIdentity(c2, body) {
85206
+ const author = readField(c2, HEADER.author, body, "author");
85207
+ if (!author.ok)
85208
+ return author;
85209
+ const requestor = readField(c2, HEADER.requestor, body, "requestor");
85210
+ if (!requestor.ok)
85211
+ return requestor;
85212
+ const authorType = readField(c2, HEADER.authorType, body, "author_type");
85213
+ if (!authorType.ok)
85214
+ return authorType;
85215
+ if (authorType.value !== undefined && authorType.value !== "user" && authorType.value !== "agent") {
85216
+ return {
85217
+ ok: false,
85218
+ detail: `author_type must be "user" or "agent" (got ${JSON.stringify(authorType.value)}).`
85219
+ };
85220
+ }
85221
+ const named = author.value !== undefined || requestor.value !== undefined || authorType.value !== undefined;
85222
+ if (!named)
85223
+ return { ok: true, identity: WEB_UI_IDENTITY };
85224
+ const resolvedAuthor = author.value ?? requestor.value ?? DEFAULT_WEB_AUTHOR;
85225
+ const resolvedRequestor = requestor.value ?? author.value ?? DEFAULT_WEB_AUTHOR;
85226
+ return {
85227
+ ok: true,
85228
+ identity: {
85229
+ author: resolvedAuthor,
85230
+ authorType: authorType.value ?? DEFAULT_WEB_AUTHOR_TYPE,
85231
+ requestor: resolvedRequestor,
85232
+ accessPath: "api",
85233
+ named: true
85234
+ }
85235
+ };
85236
+ }
85237
+
85238
+ // src/web/routes/config.ts
84572
85239
  init__utils();
84573
85240
  function unwrapScalarRpc(data) {
84574
85241
  if (typeof data === "string")
@@ -84640,11 +85307,14 @@ function registerConfigRoutes(app, ctx) {
84640
85307
  const invalid = validateConfigValue(key, value);
84641
85308
  if (invalid)
84642
85309
  return c2.json({ detail: invalid }, 400);
85310
+ const who = resolveCallerIdentity(c2, body);
85311
+ if (!who.ok)
85312
+ return c2.json({ detail: who.detail }, 400);
84643
85313
  const { error: error3 } = await ctx.supabase.rpc("cerefox_set_config", {
84644
85314
  p_key: key,
84645
85315
  p_value: value,
84646
- p_author: "web-ui",
84647
- p_author_type: "user"
85316
+ p_author: who.identity.author,
85317
+ p_author_type: who.identity.authorType
84648
85318
  });
84649
85319
  if (error3) {
84650
85320
  const remediation = storeWriteRemediation(error3.message ?? "", "cerefox_set_config");
@@ -84662,8 +85332,8 @@ init__utils();
84662
85332
  function logWebUsage(ctx, params) {
84663
85333
  Promise.resolve(ctx.supabase.rpc("cerefox_log_usage", {
84664
85334
  p_operation: params.operation,
84665
- p_access_path: "webapp",
84666
- p_requestor: params.requestor ?? "web-ui",
85335
+ p_access_path: params.access_path ?? "webapp",
85336
+ p_requestor: params.requestor ?? DEFAULT_WEB_AUTHOR,
84667
85337
  p_document_id: params.document_id ?? null,
84668
85338
  p_project_id: params.project_id ?? null,
84669
85339
  p_query_text: params.query_text ?? null,
@@ -84989,7 +85659,16 @@ function registerDiscoveryRoutes(app, ctx) {
84989
85659
  results = results.filter((r) => statusMap.get(r.document_id) === reviewStatus);
84990
85660
  }
84991
85661
  }
84992
- logWebUsage(ctx, { operation: "search", query_text: q, result_count: results.length });
85662
+ const who = resolveCallerIdentity(c2);
85663
+ if (!who.ok)
85664
+ return c2.json({ detail: who.detail }, 400);
85665
+ logWebUsage(ctx, {
85666
+ operation: "search",
85667
+ query_text: q,
85668
+ result_count: results.length,
85669
+ requestor: who.identity.requestor,
85670
+ access_path: who.identity.accessPath
85671
+ });
84993
85672
  return c2.json({
84994
85673
  results,
84995
85674
  query: q,
@@ -85314,7 +85993,15 @@ function registerDocumentReadRoutes(app, ctx) {
85314
85993
  const meta = await getDocumentRow(ctx, documentId);
85315
85994
  const projectIds = await listDocumentProjectIds(ctx, documentId);
85316
85995
  const versions3 = await listDocumentVersions(ctx, documentId);
85317
- logWebUsage(ctx, { operation: "get-document", document_id: documentId });
85996
+ const who = resolveCallerIdentity(c2);
85997
+ if (!who.ok)
85998
+ return c2.json({ detail: who.detail }, 400);
85999
+ logWebUsage(ctx, {
86000
+ operation: "get-document",
86001
+ document_id: documentId,
86002
+ requestor: who.identity.requestor,
86003
+ access_path: who.identity.accessPath
86004
+ });
85318
86005
  return c2.json({
85319
86006
  document_id: documentId,
85320
86007
  full_content: doc2.full_content ?? "",
@@ -85451,6 +86138,9 @@ function registerDocumentWriteRoutes(app, ctx) {
85451
86138
  } catch {
85452
86139
  return c2.json({ success: false, error: "Invalid JSON body" }, 400);
85453
86140
  }
86141
+ const who = resolveCallerIdentity(c2, body);
86142
+ if (!who.ok)
86143
+ return c2.json({ detail: who.detail }, 400);
85454
86144
  const title = String(body.title ?? "").trim();
85455
86145
  const content = String(body.content ?? "");
85456
86146
  const projectIds = Array.isArray(body.project_ids) ? body.project_ids : [];
@@ -85491,8 +86181,8 @@ function registerDocumentWriteRoutes(app, ctx) {
85491
86181
  source: "manual",
85492
86182
  projectIds: Array.isArray(body.project_ids) ? body.project_ids : undefined,
85493
86183
  metadata: body.metadata != null ? metadata : undefined,
85494
- author: "web-ui",
85495
- authorType: "user",
86184
+ author: who.identity.author,
86185
+ authorType: who.identity.authorType,
85496
86186
  expectedContentHash: typeof body.expected_content_hash === "string" ? body.expected_content_hash : null
85497
86187
  });
85498
86188
  return c2.json({ success: true, reindexed: result.reindexed });
@@ -85537,9 +86227,9 @@ function registerDocumentWriteRoutes(app, ctx) {
85537
86227
  title: body.title !== undefined && title !== doc2.title ? title : undefined,
85538
86228
  metadata: body.metadata != null ? metadata : undefined,
85539
86229
  projectIds: Array.isArray(body.project_ids) ? projectIds : undefined,
85540
- author: "web-ui",
85541
- authorType: "user",
85542
- accessPath: "webapp"
86230
+ author: who.identity.author,
86231
+ authorType: who.identity.authorType,
86232
+ accessPath: who.identity.accessPath
85543
86233
  });
85544
86234
  return c2.json({ success: true, reindexed: false, ...facets });
85545
86235
  } catch (err) {
@@ -85556,10 +86246,20 @@ function registerDocumentWriteRoutes(app, ctx) {
85556
86246
  });
85557
86247
  app.delete("/api/v1/documents/:document_id", async (c2) => {
85558
86248
  const documentId = c2.req.param("document_id");
86249
+ const who = resolveCallerIdentity(c2);
86250
+ if (!who.ok)
86251
+ return c2.json({ detail: who.detail }, 400);
86252
+ const expectedHash = (c2.req.header("x-cerefox-expected-content-hash") ?? c2.req.query("expected_content_hash") ?? "").trim();
86253
+ if (who.identity.named && expectedHash === "") {
86254
+ return c2.json({
86255
+ detail: "CEREFOX_TOKEN_REQUIRED: an identified caller must send the content_hash it read, " + "as the X-Cerefox-Expected-Content-Hash header or an expected_content_hash query " + "parameter. A delete must follow a read."
86256
+ }, 400);
86257
+ }
85559
86258
  const { data, error: error3 } = await ctx.supabase.rpc("cerefox_delete_document", {
85560
86259
  p_document_id: documentId,
85561
- p_author: "web-ui",
85562
- p_author_type: "user"
86260
+ p_author: who.identity.author,
86261
+ p_author_type: who.identity.authorType,
86262
+ p_expected_content_hash: expectedHash === "" ? null : expectedHash
85563
86263
  });
85564
86264
  if (error3) {
85565
86265
  if (isDocumentNotFoundError(error3)) {
@@ -85572,10 +86272,13 @@ function registerDocumentWriteRoutes(app, ctx) {
85572
86272
  });
85573
86273
  app.post("/api/v1/documents/:document_id/restore", async (c2) => {
85574
86274
  const documentId = c2.req.param("document_id");
86275
+ const who = resolveCallerIdentity(c2);
86276
+ if (!who.ok)
86277
+ return c2.json({ detail: who.detail }, 400);
85575
86278
  const { data, error: error3 } = await ctx.supabase.rpc("cerefox_restore_document", {
85576
86279
  p_document_id: documentId,
85577
- p_author: "web-ui",
85578
- p_author_type: "user"
86280
+ p_author: who.identity.author,
86281
+ p_author_type: who.identity.authorType
85579
86282
  });
85580
86283
  if (error3) {
85581
86284
  if (isDocumentNotFoundError(error3)) {
@@ -85588,10 +86291,13 @@ function registerDocumentWriteRoutes(app, ctx) {
85588
86291
  });
85589
86292
  app.delete("/api/v1/documents/:document_id/purge", async (c2) => {
85590
86293
  const documentId = c2.req.param("document_id");
86294
+ const who = resolveCallerIdentity(c2);
86295
+ if (!who.ok)
86296
+ return c2.json({ detail: who.detail }, 400);
85591
86297
  const { error: error3 } = await ctx.supabase.rpc("cerefox_purge_document", {
85592
86298
  p_document_id: documentId,
85593
- p_author: "web-ui",
85594
- p_author_type: "user"
86299
+ p_author: who.identity.author,
86300
+ p_author_type: who.identity.authorType
85595
86301
  });
85596
86302
  if (error3)
85597
86303
  return c2.json({ detail: error3.message }, 500);
@@ -85605,6 +86311,9 @@ function registerDocumentWriteRoutes(app, ctx) {
85605
86311
  } catch {
85606
86312
  return c2.json({ detail: "Invalid JSON body" }, 400);
85607
86313
  }
86314
+ const who = resolveCallerIdentity(c2, body);
86315
+ if (!who.ok)
86316
+ return c2.json({ detail: who.detail }, 400);
85608
86317
  const status = body.status;
85609
86318
  if (status !== "approved" && status !== "pending_review") {
85610
86319
  return c2.json({ detail: `Invalid status: ${JSON.stringify(status)}` }, 400);
@@ -85619,7 +86328,8 @@ function registerDocumentWriteRoutes(app, ctx) {
85619
86328
  return c2.json({ detail: error3.message }, 500);
85620
86329
  await createAuditEntry(ctx, {
85621
86330
  operation: "status-change",
85622
- author: "user",
86331
+ author: who.identity.author,
86332
+ authorType: who.identity.authorType,
85623
86333
  documentId,
85624
86334
  description: `Review status changed from '${oldStatus}' to '${status}'`
85625
86335
  });
@@ -85634,6 +86344,9 @@ function registerDocumentWriteRoutes(app, ctx) {
85634
86344
  } catch {
85635
86345
  return c2.json({ detail: "Invalid JSON body" }, 400);
85636
86346
  }
86347
+ const who = resolveCallerIdentity(c2, body);
86348
+ if (!who.ok)
86349
+ return c2.json({ detail: who.detail }, 400);
85637
86350
  const archived = Boolean(body.archived);
85638
86351
  const { data, error: error3 } = await ctx.supabase.from("cerefox_document_versions").update({ archived }).eq("id", versionId).select("document_id, version_number").maybeSingle();
85639
86352
  if (error3)
@@ -85642,7 +86355,8 @@ function registerDocumentWriteRoutes(app, ctx) {
85642
86355
  const op = archived ? "archive" : "unarchive";
85643
86356
  await createAuditEntry(ctx, {
85644
86357
  operation: op,
85645
- author: "user",
86358
+ author: who.identity.author,
86359
+ authorType: who.identity.authorType,
85646
86360
  documentId: ver?.document_id ?? documentId,
85647
86361
  versionId,
85648
86362
  description: `Version ${ver?.version_number ?? "?"} ${op}d`
@@ -85652,7 +86366,22 @@ function registerDocumentWriteRoutes(app, ctx) {
85652
86366
  }
85653
86367
  // src/web/routes/ingest.ts
85654
86368
  function notReady(error3) {
85655
- return { success: false, error: error3 };
86369
+ return { success: false, error: error3, detail: error3 };
86370
+ }
86371
+ function ingestFailure(err) {
86372
+ if (err instanceof ConcurrencyConflictError) {
86373
+ return [
86374
+ {
86375
+ ...notReady(err.message),
86376
+ ...err.currentHash ? { current_hash: err.currentHash } : {}
86377
+ },
86378
+ 409
86379
+ ];
86380
+ }
86381
+ if (err instanceof ConcurrencyTokenRequiredError) {
86382
+ return [notReady(err.message), 400];
86383
+ }
86384
+ return [notReady(err instanceof Error ? err.message : String(err)), 500];
85656
86385
  }
85657
86386
  function registerIngestRoutes(app, ctx) {
85658
86387
  app.post("/api/v1/ingest", async (c2) => {
@@ -85671,6 +86400,9 @@ function registerIngestRoutes(app, ctx) {
85671
86400
  return c2.json(notReady("Title is required."), 200);
85672
86401
  if (!content.trim())
85673
86402
  return c2.json(notReady("Content cannot be empty."), 200);
86403
+ const who = resolveCallerIdentity(c2, body);
86404
+ if (!who.ok)
86405
+ return c2.json({ detail: who.detail }, 400);
85674
86406
  try {
85675
86407
  const pipeline2 = new IngestionPipeline({
85676
86408
  supabase: ctx.supabase,
@@ -85684,8 +86416,8 @@ function registerIngestRoutes(app, ctx) {
85684
86416
  metadata: body.metadata ?? null,
85685
86417
  updateExisting: Boolean(body.update_existing),
85686
86418
  documentId: body.document_id ?? null,
85687
- author: "web-ui",
85688
- authorType: "user"
86419
+ author: who.identity.author,
86420
+ authorType: who.identity.authorType
85689
86421
  });
85690
86422
  const skipped = result.action === "skipped";
85691
86423
  const resp = {
@@ -85697,10 +86429,16 @@ function registerIngestRoutes(app, ctx) {
85697
86429
  };
85698
86430
  if (result.note)
85699
86431
  resp.note = result.note;
85700
- logWebUsage(ctx, { operation: "ingest", document_id: result.documentId });
86432
+ logWebUsage(ctx, {
86433
+ operation: "ingest",
86434
+ document_id: result.documentId,
86435
+ requestor: who.identity.requestor,
86436
+ access_path: who.identity.accessPath
86437
+ });
85701
86438
  return c2.json(resp, 200);
85702
86439
  } catch (err) {
85703
- return c2.json(notReady(err instanceof Error ? err.message : String(err)), 200);
86440
+ const [body2, status] = ingestFailure(err);
86441
+ return c2.json(body2, status);
85704
86442
  }
85705
86443
  });
85706
86444
  app.post("/api/v1/ingest/file", async (c2) => {
@@ -85736,6 +86474,9 @@ function registerIngestRoutes(app, ctx) {
85736
86474
  metadata = null;
85737
86475
  }
85738
86476
  }
86477
+ const who = resolveCallerIdentity(c2, form);
86478
+ if (!who.ok)
86479
+ return c2.json({ detail: who.detail }, 400);
85739
86480
  try {
85740
86481
  const pipeline2 = new IngestionPipeline({
85741
86482
  supabase: ctx.supabase,
@@ -85749,11 +86490,16 @@ function registerIngestRoutes(app, ctx) {
85749
86490
  projectIds,
85750
86491
  metadata,
85751
86492
  updateExisting,
85752
- author: "web-ui",
85753
- authorType: "user"
86493
+ author: who.identity.author,
86494
+ authorType: who.identity.authorType
85754
86495
  });
85755
86496
  const skipped = result.action === "skipped";
85756
- logWebUsage(ctx, { operation: "ingest", document_id: result.documentId });
86497
+ logWebUsage(ctx, {
86498
+ operation: "ingest",
86499
+ document_id: result.documentId,
86500
+ requestor: who.identity.requestor,
86501
+ access_path: who.identity.accessPath
86502
+ });
85757
86503
  return c2.json({
85758
86504
  success: !skipped,
85759
86505
  document_id: result.documentId,
@@ -85763,7 +86509,8 @@ function registerIngestRoutes(app, ctx) {
85763
86509
  ...result.note ? { note: result.note } : {}
85764
86510
  }, 200);
85765
86511
  } catch (err) {
85766
- return c2.json(notReady(err instanceof Error ? err.message : String(err)), 200);
86512
+ const [body, status] = ingestFailure(err);
86513
+ return c2.json(body, status);
85767
86514
  }
85768
86515
  });
85769
86516
  app.post("/api/v1/documents/:document_id/upload", async (c2) => {
@@ -85790,6 +86537,9 @@ function registerIngestRoutes(app, ctx) {
85790
86537
  if (!existing)
85791
86538
  return c2.json(notReady("Document not found"), 404);
85792
86539
  const title = existing.title || file.name || "Untitled";
86540
+ const who = resolveCallerIdentity(c2, form);
86541
+ if (!who.ok)
86542
+ return c2.json({ detail: who.detail }, 400);
85793
86543
  try {
85794
86544
  const pipeline2 = new IngestionPipeline({
85795
86545
  supabase: ctx.supabase,
@@ -85800,10 +86550,17 @@ function registerIngestRoutes(app, ctx) {
85800
86550
  text,
85801
86551
  title,
85802
86552
  source: "file",
85803
- author: "web-ui",
85804
- authorType: "user"
86553
+ author: who.identity.author,
86554
+ authorType: who.identity.authorType,
86555
+ expectedContentHash: typeof form.expected_content_hash === "string" && form.expected_content_hash.trim() !== "" ? form.expected_content_hash.trim() : null,
86556
+ lastWriteWins: String(form.last_write_wins ?? "") === "true"
86557
+ });
86558
+ logWebUsage(ctx, {
86559
+ operation: "ingest",
86560
+ document_id: result.documentId,
86561
+ requestor: who.identity.requestor,
86562
+ access_path: who.identity.accessPath
85805
86563
  });
85806
- logWebUsage(ctx, { operation: "ingest", document_id: result.documentId });
85807
86564
  return c2.json({
85808
86565
  success: true,
85809
86566
  document_id: result.documentId,
@@ -85811,7 +86568,8 @@ function registerIngestRoutes(app, ctx) {
85811
86568
  updated: result.reindexed
85812
86569
  }, 200);
85813
86570
  } catch (err) {
85814
- return c2.json(notReady(err instanceof Error ? err.message : String(err)), 200);
86571
+ const [body, status] = ingestFailure(err);
86572
+ return c2.json(body, status);
85815
86573
  }
85816
86574
  });
85817
86575
  }
@@ -86154,11 +86912,14 @@ function registerProjectsRoutes(app, ctx) {
86154
86912
  if (!name)
86155
86913
  return c2.json({ detail: "Project name is required" }, 400);
86156
86914
  const description = String(body.description ?? "").trim();
86915
+ const who = resolveCallerIdentity(c2, body);
86916
+ if (!who.ok)
86917
+ return c2.json({ detail: who.detail }, 400);
86157
86918
  const { data, error: error3 } = await ctx.supabase.rpc("cerefox_create_project", {
86158
86919
  p_name: name,
86159
86920
  p_description: description,
86160
- p_author: "web-ui",
86161
- p_author_type: "user"
86921
+ p_author: who.identity.author,
86922
+ p_author_type: who.identity.authorType
86162
86923
  });
86163
86924
  if (error3) {
86164
86925
  const msg = error3.message ?? "";
@@ -86194,12 +86955,15 @@ function registerProjectsRoutes(app, ctx) {
86194
86955
  if (Object.keys(update).length === 0) {
86195
86956
  return c2.json({ detail: "Nothing to update — pass name and/or description" }, 400);
86196
86957
  }
86958
+ const who = resolveCallerIdentity(c2, body);
86959
+ if (!who.ok)
86960
+ return c2.json({ detail: who.detail }, 400);
86197
86961
  const { data, error: error3 } = await ctx.supabase.rpc("cerefox_update_project", {
86198
86962
  p_project_id: projectId,
86199
86963
  p_name: update.name ?? null,
86200
86964
  p_description: update.description ?? null,
86201
- p_author: "web-ui",
86202
- p_author_type: "user"
86965
+ p_author: who.identity.author,
86966
+ p_author_type: who.identity.authorType
86203
86967
  });
86204
86968
  if (error3) {
86205
86969
  const msg = error3.message ?? "";
@@ -86217,10 +86981,13 @@ function registerProjectsRoutes(app, ctx) {
86217
86981
  });
86218
86982
  app.delete("/api/v1/projects/:project_id", async (c2) => {
86219
86983
  const projectId = c2.req.param("project_id");
86984
+ const who = resolveCallerIdentity(c2);
86985
+ if (!who.ok)
86986
+ return c2.json({ detail: who.detail }, 400);
86220
86987
  const { data, error: error3 } = await ctx.supabase.rpc("cerefox_delete_project", {
86221
86988
  p_project_id: projectId,
86222
- p_author: "web-ui",
86223
- p_author_type: "user"
86989
+ p_author: who.identity.author,
86990
+ p_author_type: who.identity.authorType
86224
86991
  });
86225
86992
  if (error3)
86226
86993
  return c2.json({ detail: error3.message }, 500);
@@ -86313,6 +87080,8 @@ function buildApp(ctx = buildWebContext()) {
86313
87080
  if (true) {
86314
87081
  app.use(logger((message, ...rest) => console.log(`${localTimestamp()} ${message}`, ...rest)));
86315
87082
  }
87083
+ app.use("/api/v1/*", apiAuth());
87084
+ app.use("/rest/v1/*", apiAuth());
86316
87085
  registerMetaRoutes(app, ctx);
86317
87086
  registerPreferencesRoutes(app);
86318
87087
  if (ctx) {
@@ -86395,6 +87164,14 @@ async function buildWebServer(options = {}) {
86395
87164
  const host = options.host ?? "127.0.0.1";
86396
87165
  const port = options.port ?? 8000;
86397
87166
  await assertServerCompatible();
87167
+ if (!isLoopbackAddress(host) && !(process.env.CEREFOX_API_KEY ?? "").trim()) {
87168
+ console.warn(`
87169
+ ⚠ Binding ${host} with NO API key configured.
87170
+ ` + ` Every read, write, delete and purge on this server is reachable by
87171
+ ` + ` anything that can connect to port ${port}, with no credential.
87172
+ ` + ` Mint one: cerefox api-key generate
87173
+ `);
87174
+ }
86398
87175
  const app = buildApp();
86399
87176
  const server = serve({ fetch: app.fetch, hostname: host, port });
86400
87177
  return {
@@ -86769,6 +87546,7 @@ Learn more:
86769
87546
  registerWeb(program2);
86770
87547
  registerCompletion(program2);
86771
87548
  registerToken(program2);
87549
+ registerApiKey(program2);
86772
87550
  const document2 = program2.command("document").description("Documents: get, list, edit, delete, restore, ingest, ingest-dir, version.");
86773
87551
  moveInto(document2, registerGetDoc, "get");
86774
87552
  moveInto(document2, registerListDocs, "list");