lua-cli 3.23.2 → 3.24.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.
package/dist/index.js CHANGED
@@ -12890,17 +12890,42 @@ var init_custom_data_api_service = __esm({
12890
12890
  this.agentId = agentId;
12891
12891
  }
12892
12892
  /**
12893
+ * Lists the agent's data collections with entry counts, timestamps, and —
12894
+ * when declared — managed index status (fields, pending/building/ready/
12895
+ * failed/rejected, error reason). The place to diagnose index declarations.
12896
+ * @returns Promise resolving to the collections listing
12897
+ */
12898
+ async collections() {
12899
+ const response = await this.httpGet(`/developer/agents/${this.agentId}/custom-data`, {
12900
+ Authorization: `Bearer ${this.apiKey}`
12901
+ });
12902
+ if (response.success && response.data) {
12903
+ return response.data;
12904
+ }
12905
+ throw new Error(response.error?.message || "Failed to list custom data collections");
12906
+ }
12907
+ /**
12893
12908
  * Creates a new custom data entry in a specified collection
12894
12909
  * @param collectionName - The name of the collection to create the entry in
12895
12910
  * @param data - The data object to store in the entry
12896
- * @param searchText - Optional text to be used for semantic search indexing
12911
+ * @param optionsOrSearchText - Either a searchText string (legacy form) or an
12912
+ * options object: `searchText` for semantic search indexing, and `index` to
12913
+ * declare data fields this agent filters on (e.g. `['business_id']` or
12914
+ * compounds like `[['country', 'business_id']]`). Declared fields get
12915
+ * agent-scoped database indexes maintained by the platform: created when
12916
+ * first declared, removed automatically ~14 days after the code stops
12917
+ * declaring them. Declaring on every write is the intended, idempotent use.
12897
12918
  * @returns Promise resolving to a DataEntryInstance representing the created entry
12898
12919
  * @throws Error if the entry creation fails or the API request is unsuccessful
12899
12920
  */
12900
- async create(collectionName, data, searchText) {
12921
+ async create(collectionName, data, optionsOrSearchText) {
12922
+ const options = typeof optionsOrSearchText === "string" ? {
12923
+ searchText: optionsOrSearchText
12924
+ } : optionsOrSearchText ?? {};
12901
12925
  const response = await this.httpPost(`/developer/agents/${this.agentId}/custom-data/${collectionName}`, {
12902
12926
  data,
12903
- searchText
12927
+ searchText: options.searchText,
12928
+ index: options.index
12904
12929
  }, {
12905
12930
  Authorization: `Bearer ${this.apiKey}`
12906
12931
  });
@@ -12953,14 +12978,19 @@ var init_custom_data_api_service = __esm({
12953
12978
  * @param collectionName - The name of the collection containing the entry
12954
12979
  * @param entryId - The unique identifier of the entry to update
12955
12980
  * @param data - The data object to update
12956
- * @param searchText - Optional text to be used for semantic search indexing
12981
+ * @param optionsOrSearchText - searchText string (legacy) or { searchText?, index? };
12982
+ * `index` refreshes this agent's index declarations (same semantics as create)
12957
12983
  * @returns Promise resolving to an UpdateCustomDataResponse with the updated entry details
12958
12984
  * @throws Error if the entry is not found or the update fails
12959
12985
  */
12960
- async update(collectionName, entryId, data, searchText) {
12986
+ async update(collectionName, entryId, data, optionsOrSearchText) {
12987
+ const options = typeof optionsOrSearchText === "string" ? {
12988
+ searchText: optionsOrSearchText
12989
+ } : optionsOrSearchText ?? {};
12961
12990
  const response = await this.httpPut(`/developer/agents/${this.agentId}/custom-data/${collectionName}/${entryId}`, {
12962
12991
  data,
12963
- searchText
12992
+ searchText: options.searchText,
12993
+ index: options.index
12964
12994
  }, {
12965
12995
  Authorization: `Bearer ${this.apiKey}`
12966
12996
  });
@@ -20723,6 +20753,14 @@ var DEFAULT_BLOCK_CIDRS = [
20723
20753
  "fe80::/10",
20724
20754
  "fc00::/7"
20725
20755
  ];
20756
+ var HOSTNAME_NON_OVERRIDABLE_CIDRS = [
20757
+ "127.0.0.0/8",
20758
+ "169.254.0.0/16",
20759
+ "0.0.0.0/8",
20760
+ "::1/128",
20761
+ "fe80::/10",
20762
+ "fd00:ec2::254/128"
20763
+ ];
20726
20764
  function ipv4ToInt(ip) {
20727
20765
  const parts = ip.split(".").map(Number);
20728
20766
  if (parts.length !== 4 || parts.some((n) => Number.isNaN(n) || n < 0 || n > 255)) {
@@ -20824,24 +20862,50 @@ function ipInCidr(ip, cidrs) {
20824
20862
  }
20825
20863
  __name(ipInCidr, "ipInCidr");
20826
20864
  __name4(ipInCidr, "ipInCidr");
20865
+ function normalizeHostname(hostname) {
20866
+ return stripBrackets(hostname.trim()).toLowerCase().replace(/\.$/, "");
20867
+ }
20868
+ __name(normalizeHostname, "normalizeHostname");
20869
+ __name4(normalizeHostname, "normalizeHostname");
20870
+ function parseAllowedHostname(value) {
20871
+ const hostname = normalizeHostname(value);
20872
+ if (!hostname || net.isIP(hostname) || /[\s*/:\\?#]/.test(hostname)) {
20873
+ throw new Error(`Invalid sandbox egress hostname allowlist entry: ${JSON.stringify(value)}. Use an exact hostname without a wildcard, URL, port, or IP literal.`);
20874
+ }
20875
+ return hostname;
20876
+ }
20877
+ __name(parseAllowedHostname, "parseAllowedHostname");
20878
+ __name4(parseAllowedHostname, "parseAllowedHostname");
20827
20879
  function compile2(opts) {
20828
20880
  return {
20829
20881
  blockCidrs: DEFAULT_BLOCK_CIDRS.map(parseCidr),
20830
20882
  allowCidrs: (opts.extraAllowedCidrs ?? []).map(parseCidr),
20883
+ allowHostnames: new Set((opts.extraAllowedHostnames ?? []).map(parseAllowedHostname)),
20884
+ hostnameNonOverridableCidrs: HOSTNAME_NON_OVERRIDABLE_CIDRS.map(parseCidr),
20831
20885
  mode: opts.mode,
20832
20886
  onEvent: opts.onSecurityEvent
20833
20887
  };
20834
20888
  }
20835
20889
  __name(compile2, "compile");
20836
20890
  __name4(compile2, "compile");
20837
- function checkAddress(address, guard) {
20838
- if (ipInCidr(address, guard.allowCidrs)) return null;
20891
+ function isAllowedHostname(hostname, guard) {
20892
+ return !net.isIP(hostname) && guard.allowHostnames.has(normalizeHostname(hostname));
20893
+ }
20894
+ __name(isAllowedHostname, "isAllowedHostname");
20895
+ __name4(isAllowedHostname, "isAllowedHostname");
20896
+ function checkAddress(address, guard, allowedByHostname = false) {
20897
+ const v4 = ipv4MappedFromIpv6(address);
20898
+ if (ipInCidr(address, guard.allowCidrs) || v4 !== null && ipInCidr(v4, guard.allowCidrs)) return null;
20899
+ if (allowedByHostname) {
20900
+ if (ipInCidr(address, guard.hostnameNonOverridableCidrs) || v4 !== null && ipInCidr(v4, guard.hostnameNonOverridableCidrs)) {
20901
+ return `address ${address} is protected from sandbox hostname allowances`;
20902
+ }
20903
+ return null;
20904
+ }
20839
20905
  if (ipInCidr(address, guard.blockCidrs)) {
20840
20906
  return `address ${address} is in the sandbox egress block list`;
20841
20907
  }
20842
- const v4 = ipv4MappedFromIpv6(address);
20843
20908
  if (v4) {
20844
- if (ipInCidr(v4, guard.allowCidrs)) return null;
20845
20909
  if (ipInCidr(v4, guard.blockCidrs)) {
20846
20910
  return `address ${address} (IPv4-mapped: ${v4}) is in the sandbox egress block list`;
20847
20911
  }
@@ -20866,8 +20930,9 @@ async function resolveAndCheck(hostname, guard) {
20866
20930
  } catch {
20867
20931
  return null;
20868
20932
  }
20933
+ const allowedByHostname = isAllowedHostname(hostname, guard);
20869
20934
  for (const { address } of addresses) {
20870
- const reason = checkAddress(address, guard);
20935
+ const reason = checkAddress(address, guard, allowedByHostname);
20871
20936
  if (reason) return {
20872
20937
  reason,
20873
20938
  address
@@ -20978,8 +21043,9 @@ function buildBlockingLookup(guard, target) {
20978
21043
  }, (err, addresses) => {
20979
21044
  if (err) return cb(err);
20980
21045
  const list = addresses;
21046
+ const allowedByHostname = isAllowedHostname(hostname, guard);
20981
21047
  for (const { address } of list) {
20982
- const reason = checkAddress(address, guard);
21048
+ const reason = checkAddress(address, guard, allowedByHostname);
20983
21049
  if (reason) {
20984
21050
  emit(guard, target, reason, address);
20985
21051
  if (guard.mode === "enforce") {
@@ -21275,6 +21341,7 @@ function createBaseSandboxContext(opts) {
21275
21341
  const egressOpts = {
21276
21342
  mode: egressMode,
21277
21343
  extraAllowedCidrs: opts.egressExtraAllowedCidrs,
21344
+ extraAllowedHostnames: opts.egressExtraAllowedHostnames,
21278
21345
  onSecurityEvent: onSecurityEvent ? (evt) => onSecurityEvent(evt) : void 0
21279
21346
  };
21280
21347
  const wrappedModuleCache = /* @__PURE__ */ new Map();
@@ -21338,6 +21405,13 @@ function resolveExtraAllowedCidrs() {
21338
21405
  }
21339
21406
  __name(resolveExtraAllowedCidrs, "resolveExtraAllowedCidrs");
21340
21407
  __name4(resolveExtraAllowedCidrs, "resolveExtraAllowedCidrs");
21408
+ function resolveExtraAllowedHostnames() {
21409
+ const csv = process.env.LUA_ALLOWED_EGRESS_HOSTNAMES;
21410
+ if (!csv) return [];
21411
+ return csv.split(",").map((s) => s.trim()).filter(Boolean);
21412
+ }
21413
+ __name(resolveExtraAllowedHostnames, "resolveExtraAllowedHostnames");
21414
+ __name4(resolveExtraAllowedHostnames, "resolveExtraAllowedHostnames");
21341
21415
  function wrapBundleAsCjsModule(source) {
21342
21416
  return "(function(module, exports, require) {\n" + source + "\n})(module, module.exports, require);";
21343
21417
  }
@@ -21571,6 +21645,12 @@ function resolveExtraAllowedCidrs2() {
21571
21645
  return csv.split(",").map((s) => s.trim()).filter(Boolean);
21572
21646
  }
21573
21647
  __name(resolveExtraAllowedCidrs2, "resolveExtraAllowedCidrs");
21648
+ function resolveExtraAllowedHostnames2() {
21649
+ const csv = process.env.LUA_ALLOWED_EGRESS_HOSTNAMES;
21650
+ if (!csv) return [];
21651
+ return csv.split(",").map((s) => s.trim()).filter(Boolean);
21652
+ }
21653
+ __name(resolveExtraAllowedHostnames2, "resolveExtraAllowedHostnames");
21574
21654
  function defaultSecurityEventLogger(evt) {
21575
21655
  console.warn("[sandbox]", JSON.stringify(evt));
21576
21656
  }
@@ -21759,6 +21839,7 @@ function createSandbox(options) {
21759
21839
  requireMode: resolveRequireMode(),
21760
21840
  egressMode: resolveEgressMode(),
21761
21841
  egressExtraAllowedCidrs: resolveExtraAllowedCidrs2(),
21842
+ egressExtraAllowedHostnames: resolveExtraAllowedHostnames2(),
21762
21843
  onSecurityEvent: defaultSecurityEventLogger
21763
21844
  });
21764
21845
  }