@drip-apex/apex-cli 0.16.0 → 0.17.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/cli.js CHANGED
@@ -127,11 +127,11 @@ var require_argument = __commonJS({
127
127
  /**
128
128
  * @package
129
129
  */
130
- _concatValue(value, previous) {
130
+ _concatValue(value2, previous) {
131
131
  if (previous === this.defaultValue || !Array.isArray(previous)) {
132
- return [value];
132
+ return [value2];
133
133
  }
134
- return previous.concat(value);
134
+ return previous.concat(value2);
135
135
  }
136
136
  /**
137
137
  * Set the default value, and optionally supply the description to be displayed in the help.
@@ -140,8 +140,8 @@ var require_argument = __commonJS({
140
140
  * @param {string} [description]
141
141
  * @return {Argument}
142
142
  */
143
- default(value, description) {
144
- this.defaultValue = value;
143
+ default(value2, description) {
144
+ this.defaultValue = value2;
145
145
  this.defaultValueDescription = description;
146
146
  return this;
147
147
  }
@@ -815,8 +815,8 @@ var require_option = __commonJS({
815
815
  * @param {string} [description]
816
816
  * @return {Option}
817
817
  */
818
- default(value, description) {
819
- this.defaultValue = value;
818
+ default(value2, description) {
819
+ this.defaultValue = value2;
820
820
  this.defaultValueDescription = description;
821
821
  return this;
822
822
  }
@@ -917,11 +917,11 @@ var require_option = __commonJS({
917
917
  /**
918
918
  * @package
919
919
  */
920
- _concatValue(value, previous) {
920
+ _concatValue(value2, previous) {
921
921
  if (previous === this.defaultValue || !Array.isArray(previous)) {
922
- return [value];
922
+ return [value2];
923
923
  }
924
- return previous.concat(value);
924
+ return previous.concat(value2);
925
925
  }
926
926
  /**
927
927
  * Only allow option value to be one of choices.
@@ -1004,7 +1004,7 @@ var require_option = __commonJS({
1004
1004
  this.positiveOptions.set(option.attributeName(), option);
1005
1005
  }
1006
1006
  });
1007
- this.negativeOptions.forEach((value, key) => {
1007
+ this.negativeOptions.forEach((value2, key) => {
1008
1008
  if (this.positiveOptions.has(key)) {
1009
1009
  this.dualOptions.add(key);
1010
1010
  }
@@ -1017,12 +1017,12 @@ var require_option = __commonJS({
1017
1017
  * @param {Option} option
1018
1018
  * @returns {boolean}
1019
1019
  */
1020
- valueFromOption(value, option) {
1020
+ valueFromOption(value2, option) {
1021
1021
  const optionKey = option.attributeName();
1022
1022
  if (!this.dualOptions.has(optionKey)) return true;
1023
1023
  const preset = this.negativeOptions.get(optionKey).presetArg;
1024
1024
  const negativeValue = preset !== void 0 ? preset : false;
1025
- return option.negate === (negativeValue === value);
1025
+ return option.negate === (negativeValue === value2);
1026
1026
  }
1027
1027
  };
1028
1028
  function camelcase(str) {
@@ -1159,8 +1159,8 @@ var require_command = __commonJS({
1159
1159
  "node_modules/commander/lib/command.js"(exports2) {
1160
1160
  var EventEmitter = require("node:events").EventEmitter;
1161
1161
  var childProcess2 = require("node:child_process");
1162
- var path26 = require("node:path");
1163
- var fs30 = require("node:fs");
1162
+ var path27 = require("node:path");
1163
+ var fs31 = require("node:fs");
1164
1164
  var process16 = require("node:process");
1165
1165
  var { Argument: Argument2, humanReadableArgName } = require_argument();
1166
1166
  var { CommanderError: CommanderError2 } = require_error();
@@ -1650,9 +1650,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
1650
1650
  * @param {string} invalidArgumentMessage
1651
1651
  * @private
1652
1652
  */
1653
- _callParseArg(target, value, previous, invalidArgumentMessage) {
1653
+ _callParseArg(target, value2, previous, invalidArgumentMessage) {
1654
1654
  try {
1655
- return target.parseArg(value, previous);
1655
+ return target.parseArg(value2, previous);
1656
1656
  } catch (err) {
1657
1657
  if (err.code === "commander.invalidArgument") {
1658
1658
  const message = `${invalidArgumentMessage} ${err.message}`;
@@ -1937,8 +1937,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
1937
1937
  * @param {object} value
1938
1938
  * @return {Command} `this` command for chaining
1939
1939
  */
1940
- setOptionValue(key, value) {
1941
- return this.setOptionValueWithSource(key, value, void 0);
1940
+ setOptionValue(key, value2) {
1941
+ return this.setOptionValueWithSource(key, value2, void 0);
1942
1942
  }
1943
1943
  /**
1944
1944
  * Store option value and where the value came from.
@@ -1948,11 +1948,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
1948
1948
  * @param {string} source - expected values are default/config/env/cli/implied
1949
1949
  * @return {Command} `this` command for chaining
1950
1950
  */
1951
- setOptionValueWithSource(key, value, source) {
1951
+ setOptionValueWithSource(key, value2, source) {
1952
1952
  if (this._storeOptionsAsProperties) {
1953
- this[key] = value;
1953
+ this[key] = value2;
1954
1954
  } else {
1955
- this._optionValues[key] = value;
1955
+ this._optionValues[key] = value2;
1956
1956
  }
1957
1957
  this._optionValueSources[key] = source;
1958
1958
  return this;
@@ -2141,7 +2141,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2141
2141
  * @param {string} subcommandName
2142
2142
  */
2143
2143
  _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
2144
- if (fs30.existsSync(executableFile)) return;
2144
+ if (fs31.existsSync(executableFile)) return;
2145
2145
  const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
2146
2146
  const executableMissing = `'${executableFile}' does not exist
2147
2147
  - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
@@ -2159,11 +2159,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
2159
2159
  let launchWithNode = false;
2160
2160
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
2161
2161
  function findFile(baseDir, baseName) {
2162
- const localBin = path26.resolve(baseDir, baseName);
2163
- if (fs30.existsSync(localBin)) return localBin;
2164
- if (sourceExt.includes(path26.extname(baseName))) return void 0;
2162
+ const localBin = path27.resolve(baseDir, baseName);
2163
+ if (fs31.existsSync(localBin)) return localBin;
2164
+ if (sourceExt.includes(path27.extname(baseName))) return void 0;
2165
2165
  const foundExt = sourceExt.find(
2166
- (ext) => fs30.existsSync(`${localBin}${ext}`)
2166
+ (ext) => fs31.existsSync(`${localBin}${ext}`)
2167
2167
  );
2168
2168
  if (foundExt) return `${localBin}${foundExt}`;
2169
2169
  return void 0;
@@ -2175,21 +2175,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
2175
2175
  if (this._scriptPath) {
2176
2176
  let resolvedScriptPath;
2177
2177
  try {
2178
- resolvedScriptPath = fs30.realpathSync(this._scriptPath);
2178
+ resolvedScriptPath = fs31.realpathSync(this._scriptPath);
2179
2179
  } catch {
2180
2180
  resolvedScriptPath = this._scriptPath;
2181
2181
  }
2182
- executableDir = path26.resolve(
2183
- path26.dirname(resolvedScriptPath),
2182
+ executableDir = path27.resolve(
2183
+ path27.dirname(resolvedScriptPath),
2184
2184
  executableDir
2185
2185
  );
2186
2186
  }
2187
2187
  if (executableDir) {
2188
2188
  let localFile = findFile(executableDir, executableFile);
2189
2189
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
2190
- const legacyName = path26.basename(
2190
+ const legacyName = path27.basename(
2191
2191
  this._scriptPath,
2192
- path26.extname(this._scriptPath)
2192
+ path27.extname(this._scriptPath)
2193
2193
  );
2194
2194
  if (legacyName !== this._name) {
2195
2195
  localFile = findFile(
@@ -2200,7 +2200,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2200
2200
  }
2201
2201
  executableFile = localFile || executableFile;
2202
2202
  }
2203
- launchWithNode = sourceExt.includes(path26.extname(executableFile));
2203
+ launchWithNode = sourceExt.includes(path27.extname(executableFile));
2204
2204
  let proc;
2205
2205
  if (process16.platform !== "win32") {
2206
2206
  if (launchWithNode) {
@@ -2335,13 +2335,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
2335
2335
  * @private
2336
2336
  */
2337
2337
  _processArguments() {
2338
- const myParseArg = (argument, value, previous) => {
2339
- let parsedValue = value;
2340
- if (value !== null && argument.parseArg) {
2341
- const invalidValueMessage = `error: command-argument value '${value}' is invalid for argument '${argument.name()}'.`;
2338
+ const myParseArg = (argument, value2, previous) => {
2339
+ let parsedValue = value2;
2340
+ if (value2 !== null && argument.parseArg) {
2341
+ const invalidValueMessage = `error: command-argument value '${value2}' is invalid for argument '${argument.name()}'.`;
2342
2342
  parsedValue = this._callParseArg(
2343
2343
  argument,
2344
- value,
2344
+ value2,
2345
2345
  previous,
2346
2346
  invalidValueMessage
2347
2347
  );
@@ -2351,25 +2351,25 @@ Expecting one of '${allowedValues.join("', '")}'`);
2351
2351
  this._checkNumberOfArguments();
2352
2352
  const processedArgs = [];
2353
2353
  this.registeredArguments.forEach((declaredArg, index) => {
2354
- let value = declaredArg.defaultValue;
2354
+ let value2 = declaredArg.defaultValue;
2355
2355
  if (declaredArg.variadic) {
2356
2356
  if (index < this.args.length) {
2357
- value = this.args.slice(index);
2357
+ value2 = this.args.slice(index);
2358
2358
  if (declaredArg.parseArg) {
2359
- value = value.reduce((processed, v) => {
2359
+ value2 = value2.reduce((processed, v) => {
2360
2360
  return myParseArg(declaredArg, v, processed);
2361
2361
  }, declaredArg.defaultValue);
2362
2362
  }
2363
- } else if (value === void 0) {
2364
- value = [];
2363
+ } else if (value2 === void 0) {
2364
+ value2 = [];
2365
2365
  }
2366
2366
  } else if (index < this.args.length) {
2367
- value = this.args[index];
2367
+ value2 = this.args[index];
2368
2368
  if (declaredArg.parseArg) {
2369
- value = myParseArg(declaredArg, value, declaredArg.defaultValue);
2369
+ value2 = myParseArg(declaredArg, value2, declaredArg.defaultValue);
2370
2370
  }
2371
2371
  }
2372
- processedArgs[index] = value;
2372
+ processedArgs[index] = value2;
2373
2373
  });
2374
2374
  this.processedArgs = processedArgs;
2375
2375
  }
@@ -2626,15 +2626,15 @@ Expecting one of '${allowedValues.join("', '")}'`);
2626
2626
  const option = this._findOption(arg);
2627
2627
  if (option) {
2628
2628
  if (option.required) {
2629
- const value = args.shift();
2630
- if (value === void 0) this.optionMissingArgument(option);
2631
- this.emit(`option:${option.name()}`, value);
2629
+ const value2 = args.shift();
2630
+ if (value2 === void 0) this.optionMissingArgument(option);
2631
+ this.emit(`option:${option.name()}`, value2);
2632
2632
  } else if (option.optional) {
2633
- let value = null;
2633
+ let value2 = null;
2634
2634
  if (args.length > 0 && !maybeOption(args[0])) {
2635
- value = args.shift();
2635
+ value2 = args.shift();
2636
2636
  }
2637
- this.emit(`option:${option.name()}`, value);
2637
+ this.emit(`option:${option.name()}`, value2);
2638
2638
  } else {
2639
2639
  this.emit(`option:${option.name()}`);
2640
2640
  }
@@ -3047,7 +3047,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
3047
3047
  * @return {Command}
3048
3048
  */
3049
3049
  nameFromFilename(filename) {
3050
- this._name = path26.basename(filename, path26.extname(filename));
3050
+ this._name = path27.basename(filename, path27.extname(filename));
3051
3051
  return this;
3052
3052
  }
3053
3053
  /**
@@ -3061,9 +3061,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
3061
3061
  * @param {string} [path]
3062
3062
  * @return {(string|null|Command)}
3063
3063
  */
3064
- executableDir(path27) {
3065
- if (path27 === void 0) return this._executableDir;
3066
- this._executableDir = path27;
3064
+ executableDir(path28) {
3065
+ if (path28 === void 0) return this._executableDir;
3066
+ this._executableDir = path28;
3067
3067
  return this;
3068
3068
  }
3069
3069
  /**
@@ -3427,12 +3427,12 @@ function assembleStyles() {
3427
3427
  green = Math.floor(remainder / 6) / 5;
3428
3428
  blue = remainder % 6 / 5;
3429
3429
  }
3430
- const value = Math.max(red, green, blue) * 2;
3431
- if (value === 0) {
3430
+ const value2 = Math.max(red, green, blue) * 2;
3431
+ if (value2 === 0) {
3432
3432
  return 30;
3433
3433
  }
3434
3434
  let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
3435
- if (value === 2) {
3435
+ if (value2 === 2) {
3436
3436
  result += 60;
3437
3437
  }
3438
3438
  return result;
@@ -6295,22 +6295,22 @@ var init_ora = __esm({
6295
6295
  get text() {
6296
6296
  return this.#text;
6297
6297
  }
6298
- set text(value = "") {
6299
- this.#text = value;
6298
+ set text(value2 = "") {
6299
+ this.#text = value2;
6300
6300
  this.#updateLineCount();
6301
6301
  }
6302
6302
  get prefixText() {
6303
6303
  return this.#prefixText;
6304
6304
  }
6305
- set prefixText(value = "") {
6306
- this.#prefixText = value;
6305
+ set prefixText(value2 = "") {
6306
+ this.#prefixText = value2;
6307
6307
  this.#updateLineCount();
6308
6308
  }
6309
6309
  get suffixText() {
6310
6310
  return this.#suffixText;
6311
6311
  }
6312
- set suffixText(value = "") {
6313
- this.#suffixText = value;
6312
+ set suffixText(value2 = "") {
6313
+ this.#suffixText = value2;
6314
6314
  this.#updateLineCount();
6315
6315
  }
6316
6316
  get isSpinning() {
@@ -6347,20 +6347,20 @@ var init_ora = __esm({
6347
6347
  get isEnabled() {
6348
6348
  return this.#isEnabled && !this.#isSilent;
6349
6349
  }
6350
- set isEnabled(value) {
6351
- if (typeof value !== "boolean") {
6350
+ set isEnabled(value2) {
6351
+ if (typeof value2 !== "boolean") {
6352
6352
  throw new TypeError("The `isEnabled` option must be a boolean");
6353
6353
  }
6354
- this.#isEnabled = value;
6354
+ this.#isEnabled = value2;
6355
6355
  }
6356
6356
  get isSilent() {
6357
6357
  return this.#isSilent;
6358
6358
  }
6359
- set isSilent(value) {
6360
- if (typeof value !== "boolean") {
6359
+ set isSilent(value2) {
6360
+ if (typeof value2 !== "boolean") {
6361
6361
  throw new TypeError("The `isSilent` option must be a boolean");
6362
6362
  }
6363
- this.#isSilent = value;
6363
+ this.#isSilent = value2;
6364
6364
  }
6365
6365
  frame() {
6366
6366
  const now = Date.now();
@@ -6613,7 +6613,7 @@ var init_wsl_utils = __esm({
6613
6613
 
6614
6614
  // node_modules/define-lazy-prop/index.js
6615
6615
  function defineLazyProperty(object, propertyName, valueGetter) {
6616
- const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
6616
+ const define = (value2) => Object.defineProperty(object, propertyName, { value: value2, enumerable: true, writable: true });
6617
6617
  Object.defineProperty(object, propertyName, {
6618
6618
  configurable: true,
6619
6619
  enumerable: true,
@@ -6622,8 +6622,8 @@ function defineLazyProperty(object, propertyName, valueGetter) {
6622
6622
  define(result);
6623
6623
  return result;
6624
6624
  },
6625
- set(value) {
6626
- define(value);
6625
+ set(value2) {
6626
+ define(value2);
6627
6627
  }
6628
6628
  });
6629
6629
  return object;
@@ -7092,8 +7092,8 @@ var import_node_crypto2 = require("node:crypto");
7092
7092
  var import_node_crypto = require("node:crypto");
7093
7093
  var invocationId = (0, import_node_crypto.randomUUID)();
7094
7094
  var identity;
7095
- function setClientIdentity(value) {
7096
- identity = { ...value, invocationId };
7095
+ function setClientIdentity(value2) {
7096
+ identity = { ...value2, invocationId };
7097
7097
  }
7098
7098
  function getClientIdentity() {
7099
7099
  return identity ? { ...identity } : void 0;
@@ -7124,7 +7124,7 @@ function extractErrorDetails(json) {
7124
7124
  if (!json) return void 0;
7125
7125
  const nested = json.error && typeof json.error === "object" && !Array.isArray(json.error) ? json.error : null;
7126
7126
  const code = typeof json.code === "string" ? json.code : typeof nested?.code === "string" ? nested.code : void 0;
7127
- for (const value of [json.details, json.meta, nested?.details]) if (value && typeof value === "object" && !Array.isArray(value)) return { ...value, ...code ? { code } : {} };
7127
+ for (const value2 of [json.details, json.meta, nested?.details]) if (value2 && typeof value2 === "object" && !Array.isArray(value2)) return { ...value2, ...code ? { code } : {} };
7128
7128
  const details = Object.fromEntries(["limit", "current", "max", "actual", "field", "code"].filter((key) => key in json).map((key) => [key, json[key]]));
7129
7129
  if (code) details.code = code;
7130
7130
  return Object.keys(details).length ? details : void 0;
@@ -7133,23 +7133,23 @@ var warnedAboutVersionSkew = false;
7133
7133
  function createHttpClient(creds, options) {
7134
7134
  const warn3 = options.warn ?? ((message) => process.stderr.write(message));
7135
7135
  function inspectVersion(headers) {
7136
- const value = headers.get(APEX_API_VERSION_HEADER);
7137
- if (!value || warnedAboutVersionSkew) return;
7138
- const version = Number(value);
7136
+ const value2 = headers.get(APEX_API_VERSION_HEADER);
7137
+ if (!value2 || warnedAboutVersionSkew) return;
7138
+ const version = Number(value2);
7139
7139
  if (!Number.isFinite(version) || version === Number(SUPPORTED_APEX_API_VERSION)) return;
7140
7140
  warnedAboutVersionSkew = true;
7141
7141
  warn3(version > 1 ? "CLI is behind the server \u2014 update.\n" : "Server API is older than this CLI supports.\n");
7142
7142
  }
7143
- async function request2(method, path26, body5, requestTimeoutMs, form = false, requestOptions) {
7143
+ async function request2(method, path27, body5, requestTimeoutMs, form = false, requestOptions) {
7144
7144
  const started2 = performance.now();
7145
7145
  const observe = (status4, requestId2, errorCode, responseHeaders) => {
7146
7146
  const semver = (name) => {
7147
- const value = responseHeaders?.get(name) ?? void 0;
7148
- return value && /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(value) ? value : void 0;
7147
+ const value2 = responseHeaders?.get(name) ?? void 0;
7148
+ return value2 && /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(value2) ? value2 : void 0;
7149
7149
  };
7150
7150
  const serverTiming = responseHeaders?.get("server-timing");
7151
7151
  try {
7152
- options.onResponse?.({ method, path: path26, status: status4, requestId: requestId2, errorCode: typeof errorCode === "string" ? errorCode : void 0, durationMs: Math.max(0, Math.round(performance.now() - started2)), serverTiming: serverTiming?.slice(0, 300) || void 0, cliLatest: semver("x-apex-cli-latest"), cliMinimum: semver("x-apex-cli-minimum") });
7152
+ options.onResponse?.({ method, path: path27, status: status4, requestId: requestId2, errorCode: typeof errorCode === "string" ? errorCode : void 0, durationMs: Math.max(0, Math.round(performance.now() - started2)), serverTiming: serverTiming?.slice(0, 300) || void 0, cliLatest: semver("x-apex-cli-latest"), cliMinimum: semver("x-apex-cli-minimum") });
7153
7153
  } catch {
7154
7154
  }
7155
7155
  };
@@ -7165,7 +7165,7 @@ function createHttpClient(creds, options) {
7165
7165
  if (creds.resolvedContext?.orgId) headers["X-Apex-Org"] = creds.resolvedContext.orgId;
7166
7166
  if (creds.resolvedContext?.shopId) headers["X-Apex-Shop"] = creds.resolvedContext.shopId;
7167
7167
  }
7168
- const mock = options.transport?.(method, path26, body5, headers);
7168
+ const mock = options.transport?.(method, path27, body5, headers);
7169
7169
  if (mock !== void 0) {
7170
7170
  const version = options.testTransportVersion?.();
7171
7171
  if (version) inspectVersion(new Headers({ [APEX_API_VERSION_HEADER]: version }));
@@ -7174,7 +7174,7 @@ function createHttpClient(creds, options) {
7174
7174
  }
7175
7175
  let response;
7176
7176
  try {
7177
- response = await fetch(`${creds.baseUrl}${path26}`, { method, headers, body: form ? body5 : body5 ? JSON.stringify(body5) : void 0, signal: AbortSignal.timeout(timeoutMs) });
7177
+ response = await fetch(`${creds.baseUrl}${path27}`, { method, headers, body: form ? body5 : body5 ? JSON.stringify(body5) : void 0, signal: AbortSignal.timeout(timeoutMs) });
7178
7178
  } catch (error) {
7179
7179
  const outer = error && typeof error === "object" ? error : void 0;
7180
7180
  const nested = outer?.cause && typeof outer.cause === "object" ? outer.cause : void 0;
@@ -7195,7 +7195,7 @@ function createHttpClient(creds, options) {
7195
7195
  if (!response.ok) return { ok: false, status: response.status, data: json, error: extractErrorMessage(json, response.status), errorDetails: extractErrorDetails(json), requestId, retryAfter: response.headers.get("retry-after"), rateLimit: { limit: response.headers.get("x-ratelimit-limit"), remaining: response.headers.get("x-ratelimit-remaining"), reset: response.headers.get("x-ratelimit-reset") } };
7196
7196
  return { ok: true, status: response.status, data: json };
7197
7197
  }
7198
- return { request: (method, path26, body5, timeoutMs, requestOptions) => request2(method, path26, body5, timeoutMs, false, requestOptions), requestForm: (method, path26, body5) => request2(method, path26, body5, void 0, true) };
7198
+ return { request: (method, path27, body5, timeoutMs, requestOptions) => request2(method, path27, body5, timeoutMs, false, requestOptions), requestForm: (method, path27, body5) => request2(method, path27, body5, void 0, true) };
7199
7199
  }
7200
7200
 
7201
7201
  // ../api-client/src/credentials.ts
@@ -7286,18 +7286,18 @@ function compareVersions(left, right) {
7286
7286
  }
7287
7287
  function readCache() {
7288
7288
  try {
7289
- const value = JSON.parse((0, import_node_fs2.readFileSync)(cachePath(), "utf8"));
7290
- return value && typeof value === "object" ? value : {};
7289
+ const value2 = JSON.parse((0, import_node_fs2.readFileSync)(cachePath(), "utf8"));
7290
+ return value2 && typeof value2 === "object" ? value2 : {};
7291
7291
  } catch {
7292
7292
  return {};
7293
7293
  }
7294
7294
  }
7295
7295
  function writeCache(patch, remove5 = []) {
7296
7296
  try {
7297
- const value = { ...readCache(), ...patch };
7298
- for (const key of remove5) delete value[key];
7297
+ const value2 = { ...readCache(), ...patch };
7298
+ for (const key of remove5) delete value2[key];
7299
7299
  (0, import_node_fs2.mkdirSync)(import_node_path2.default.dirname(cachePath()), { recursive: true });
7300
- (0, import_node_fs2.writeFileSync)(cachePath(), JSON.stringify(value), { mode: 384 });
7300
+ (0, import_node_fs2.writeFileSync)(cachePath(), JSON.stringify(value2), { mode: 384 });
7301
7301
  } catch {
7302
7302
  }
7303
7303
  }
@@ -7362,7 +7362,7 @@ function clearUpdateCache() {
7362
7362
  function currentUpdateState(current, minimumOverride) {
7363
7363
  if (minimumOverride && versionParts(minimumOverride))
7364
7364
  recordServerCliPolicy({ cliMinimum: minimumOverride });
7365
- const latest = [npmLatest, serverLatest, serverMinimum, current].filter((value) => Boolean(value)).reduce((highest, value) => compareVersions(value, highest) > 0 ? value : highest, current);
7365
+ const latest = [npmLatest, serverLatest, serverMinimum, current].filter((value2) => Boolean(value2)).reduce((highest, value2) => compareVersions(value2, highest) > 0 ? value2 : highest, current);
7366
7366
  const minimum = serverMinimum;
7367
7367
  const required = Boolean(minimum && compareVersions(current, minimum) < 0);
7368
7368
  if (!required && process.env.APEX_NO_UPDATE_CHECK === "1") return;
@@ -7423,7 +7423,7 @@ async function checkForUpdate(current) {
7423
7423
  // package.json
7424
7424
  var package_default = {
7425
7425
  name: "@drip-apex/apex-cli",
7426
- version: "0.16.0",
7426
+ version: "0.17.0",
7427
7427
  license: "MIT",
7428
7428
  description: "Apex CLI for managing experiments, approved roadmap ideas, and draft workspaces.",
7429
7429
  private: false,
@@ -7771,8 +7771,8 @@ process.on?.("beforeExit", writePendingUpdateNotice);
7771
7771
  function minimumFromError(error, reason2) {
7772
7772
  if (reason2 !== "cli_upgrade_required") return;
7773
7773
  const api = error.api?.body;
7774
- const value = error.details?.minimum ?? api?.error?.details?.minimum;
7775
- return typeof value === "string" ? value : void 0;
7774
+ const value2 = error.details?.minimum ?? api?.error?.details?.minimum;
7775
+ return typeof value2 === "string" ? value2 : void 0;
7776
7776
  }
7777
7777
  async function handleCliError(err, command) {
7778
7778
  if (err && typeof err === "object" && "exitCode" in err && err.exitCode === 0) {
@@ -8384,9 +8384,9 @@ var staticRouteSegments = /* @__PURE__ */ new Set([
8384
8384
  "webhooks",
8385
8385
  "workspace"
8386
8386
  ]);
8387
- function normalizeRoute(path26) {
8388
- if (!path26.startsWith("/api/")) return ":route";
8389
- const parts = path26.split(/[?#]/, 1)[0].split("/");
8387
+ function normalizeRoute(path27) {
8388
+ if (!path27.startsWith("/api/")) return ":route";
8389
+ const parts = path27.split(/[?#]/, 1)[0].split("/");
8390
8390
  const files = parts.indexOf("files");
8391
8391
  if (files !== -1 && parts.length > files + 1) parts.splice(files + 1, parts.length, ":id");
8392
8392
  return parts.map((part) => !part || staticRouteSegments.has(part) ? part : ":id").join("/");
@@ -8438,19 +8438,19 @@ function classifyError(exitCode, error, status4) {
8438
8438
  function redactAttempted(token) {
8439
8439
  return /^(?:apx_|sk_|pk_|rk_|ghp_|gho_|xox|Bearer)/.test(token) || /^[A-Za-z0-9_-]{24,}$/.test(token) || /:\/\/|[/\\@=]/.test(token) || token.length > 40 ? "(redacted)" : token;
8440
8440
  }
8441
- function normalizeErrorCode(value, exitCode) {
8442
- const normalized = value.toLowerCase();
8441
+ function normalizeErrorCode(value2, exitCode) {
8442
+ const normalized = value2.toLowerCase();
8443
8443
  return normalized.length <= 64 && /^[a-z0-9._-]+$/.test(normalized) ? normalized : `exit_${exitCode}`;
8444
8444
  }
8445
8445
  function invocationErrorCode(exitCode, error, commanderExit) {
8446
8446
  if (exitCode === 0) return void 0;
8447
- let value = firstError?.errorCode;
8448
- if (!value && firstError)
8449
- value = firstError.status === 410 ? "gone" : `http_${firstError.status}`;
8447
+ let value2 = firstError?.errorCode;
8448
+ if (!value2 && firstError)
8449
+ value2 = firstError.status === 410 ? "gone" : `http_${firstError.status}`;
8450
8450
  const detail5 = error && typeof error === "object" ? error : {};
8451
- if (!value && typeof detail5.details?.reason === "string" && !detail5.api) {
8451
+ if (!value2 && typeof detail5.details?.reason === "string" && !detail5.api) {
8452
8452
  const reason2 = detail5.details.reason.toLowerCase();
8453
- value = [
8453
+ value2 = [
8454
8454
  "network",
8455
8455
  "dns",
8456
8456
  "timeout",
@@ -8461,20 +8461,20 @@ function invocationErrorCode(exitCode, error, commanderExit) {
8461
8461
  "unknown"
8462
8462
  ].includes(reason2) ? `network_${reason2}` : reason2 || void 0;
8463
8463
  }
8464
- if (!value && commanderExit && typeof detail5.code === "string")
8465
- value = detail5.code.slice("commander.".length).replace(/([a-z])([A-Z])/g, "$1_$2");
8466
- if (!value) {
8464
+ if (!value2 && commanderExit && typeof detail5.code === "string")
8465
+ value2 = detail5.code.slice("commander.".length).replace(/([a-z])([A-Z])/g, "$1_$2");
8466
+ if (!value2) {
8467
8467
  const apiCode = detail5.api?.body?.code ?? detail5.api?.body?.error?.code ?? detail5.details?.code;
8468
- if (typeof apiCode === "string" && apiCode) value = apiCode;
8469
- else if (detail5.api?.status === 401 || exitCode === 2) value = "auth_required";
8470
- else if (detail5.api?.status === 403) value = "auth_forbidden";
8471
- else if (detail5.api?.status === 404) value = "not_found";
8472
- else if (detail5.api?.status === 429) value = "rate_limited";
8473
- else if (detail5.api?.status === 409 || exitCode === 5) value = "conflict";
8474
- else if (exitCode === 4) value = "confirmation_required";
8475
- else if (exitCode === 3) value = "validation_failed";
8468
+ if (typeof apiCode === "string" && apiCode) value2 = apiCode;
8469
+ else if (detail5.api?.status === 401 || exitCode === 2) value2 = "auth_required";
8470
+ else if (detail5.api?.status === 403) value2 = "auth_forbidden";
8471
+ else if (detail5.api?.status === 404) value2 = "not_found";
8472
+ else if (detail5.api?.status === 429) value2 = "rate_limited";
8473
+ else if (detail5.api?.status === 409 || exitCode === 5) value2 = "conflict";
8474
+ else if (exitCode === 4) value2 = "confirmation_required";
8475
+ else if (exitCode === 3) value2 = "validation_failed";
8476
8476
  }
8477
- return normalizeErrorCode(value ?? `exit_${exitCode}`, exitCode);
8477
+ return normalizeErrorCode(value2 ?? `exit_${exitCode}`, exitCode);
8478
8478
  }
8479
8479
  async function finishInvocation({
8480
8480
  exitCode: rawExitCode,
@@ -8563,8 +8563,8 @@ function pagePath(id, action78) {
8563
8563
  return `/api/v1/landing-pages/${encodeURIComponent(id)}${action78 ? `/${action78}` : ""}`;
8564
8564
  }
8565
8565
  function landingPagesApi(request2) {
8566
- const call = async (method, path26, body5) => {
8567
- const response = await request2(method, path26, body5);
8566
+ const call = async (method, path27, body5) => {
8567
+ const response = await request2(method, path27, body5);
8568
8568
  return { ...response, data: response.data?.data };
8569
8569
  };
8570
8570
  return {
@@ -8650,6 +8650,19 @@ function validateLandingPageLocalFiles(files) {
8650
8650
  }
8651
8651
 
8652
8652
  // src/api.ts
8653
+ function lookupCommerceCatalog(creds, params) {
8654
+ const query = new URLSearchParams();
8655
+ if (params.query) query.set("q", params.query);
8656
+ if (params.handle) query.set("handle", params.handle);
8657
+ if (params.product_id) query.set("product_id", params.product_id);
8658
+ if (params.cursor) query.set("cursor", params.cursor);
8659
+ if (params.limit !== void 0) query.set("limit", String(params.limit));
8660
+ return request(
8661
+ creds,
8662
+ "GET",
8663
+ `/api/v1/commerce/catalog${query.size ? `?${query}` : ""}`
8664
+ );
8665
+ }
8653
8666
  function simulateTriggers(creds, body5) {
8654
8667
  return request(creds, "POST", "/api/v1/tracking/simulate-trigger", body5);
8655
8668
  }
@@ -8673,11 +8686,11 @@ function getUserKeyIdentity(creds) {
8673
8686
  function getAccountContext(creds) {
8674
8687
  return userRequest(creds, "GET", "/api/v1/me/context");
8675
8688
  }
8676
- function userRequest(creds, method, path26, body5) {
8689
+ function userRequest(creds, method, path27, body5) {
8677
8690
  return request(
8678
8691
  { ...creds, apiKey: creds.userApiKey ?? "", baseUrl: creds.userBaseUrl ?? creds.baseUrl },
8679
8692
  method,
8680
- path26,
8693
+ path27,
8681
8694
  body5
8682
8695
  );
8683
8696
  }
@@ -8763,10 +8776,10 @@ function sharedClient(creds) {
8763
8776
  }
8764
8777
  return client;
8765
8778
  }
8766
- async function request(creds, method, path26, body5, requestTimeoutMs, options) {
8779
+ async function request(creds, method, path27, body5, requestTimeoutMs, options) {
8767
8780
  const response = await sharedClient(creds).request(
8768
8781
  method,
8769
- path26,
8782
+ path27,
8770
8783
  body5,
8771
8784
  requestTimeoutMs,
8772
8785
  options
@@ -8774,8 +8787,8 @@ async function request(creds, method, path26, body5, requestTimeoutMs, options)
8774
8787
  recordApiResponse(response);
8775
8788
  return response;
8776
8789
  }
8777
- async function requestForm(creds, method, path26, body5) {
8778
- const response = await sharedClient(creds).requestForm(method, path26, body5);
8790
+ async function requestForm(creds, method, path27, body5) {
8791
+ const response = await sharedClient(creds).requestForm(method, path27, body5);
8779
8792
  recordApiResponse(response);
8780
8793
  return response;
8781
8794
  }
@@ -9299,6 +9312,17 @@ function getAdminQuarantine(creds) {
9299
9312
  "/api/v1/admin/tracking/quarantine"
9300
9313
  );
9301
9314
  }
9315
+ function getAdminShopSettings(creds, shopRef) {
9316
+ return request(
9317
+ userCredentials(creds),
9318
+ "GET",
9319
+ `/api/v1/admin/shops/${encodeURIComponent(shopRef)}/settings`
9320
+ );
9321
+ }
9322
+ function setAdminShopSetting(creds, shopId, body5) {
9323
+ const pinned = { ...userCredentials(creds), resolvedContext: { shopId } };
9324
+ return request(pinned, "PATCH", `/api/v1/admin/shops/${encodeURIComponent(shopId)}/settings`, body5);
9325
+ }
9302
9326
  function archiveAdminShop(creds, shopId) {
9303
9327
  return request(
9304
9328
  userCredentials(creds),
@@ -9318,8 +9342,8 @@ function requestTargetingResource(creds, method, kind5, id, body5, limit, cursor
9318
9342
  if (limit) params.set("limit", String(limit));
9319
9343
  if (cursor) params.set("cursor", cursor);
9320
9344
  const query = params.toString();
9321
- const path26 = `/api/v1/${kind5}${id ? `/${id.split("/").map(encodeURIComponent).join("/")}` : ""}${query ? `?${query}` : ""}`;
9322
- return request(creds, method, path26, body5);
9345
+ const path27 = `/api/v1/${kind5}${id ? `/${id.split("/").map(encodeURIComponent).join("/")}` : ""}${query ? `?${query}` : ""}`;
9346
+ return request(creds, method, path27, body5);
9323
9347
  }
9324
9348
  function managedPath(kind5, id, action78) {
9325
9349
  return `/api/v1/${kind5}${id ? `/${encodeURIComponent(id)}` : ""}${action78 ? `/${action78}` : ""}`;
@@ -9355,7 +9379,7 @@ function getConfigResource(creds, family, id) {
9355
9379
  }
9356
9380
  function landingPages(creds) {
9357
9381
  return landingPagesApi(
9358
- (method, path26, body5) => request(creds, method, path26, body5)
9382
+ (method, path27, body5) => request(creds, method, path27, body5)
9359
9383
  );
9360
9384
  }
9361
9385
  function deleteAsset(creds, id) {
@@ -9600,26 +9624,26 @@ function moveAdminCustomerStores(creds, orgId, body5) {
9600
9624
 
9601
9625
  // src/context.ts
9602
9626
  var import_node_readline = __toESM(require("node:readline"));
9603
- function match(value, rows, kind5) {
9604
- const byId = rows.find((row) => row.id === value);
9627
+ function match(value2, rows, kind5) {
9628
+ const byId = rows.find((row) => row.id === value2);
9605
9629
  if (byId) return byId;
9606
- const exact = rows.filter((row) => row.name.toLowerCase() === value.toLowerCase());
9630
+ const exact = rows.filter((row) => row.name.toLowerCase() === value2.toLowerCase());
9607
9631
  if (exact.length === 1) return exact[0];
9608
9632
  if (exact.length > 1)
9609
9633
  throw new CliError(
9610
- `Ambiguous ${kind5} "${value}". Candidates: ${exact.map((row) => `${row.name} (${row.id})`).join(", ")}`,
9634
+ `Ambiguous ${kind5} "${value2}". Candidates: ${exact.map((row) => `${row.name} (${row.id})`).join(", ")}`,
9611
9635
  EXIT_CODES.validation,
9612
9636
  { code: "ambiguous_context", candidates: exact.map(({ id, name }) => ({ id, name })) }
9613
9637
  );
9614
- const candidates = rows.filter((row) => row.name.toLowerCase().startsWith(value.toLowerCase()));
9638
+ const candidates = rows.filter((row) => row.name.toLowerCase().startsWith(value2.toLowerCase()));
9615
9639
  if (candidates.length === 1) return candidates[0];
9616
9640
  if (candidates.length > 1)
9617
9641
  throw new CliError(
9618
- `Ambiguous ${kind5} "${value}". Candidates: ${candidates.map((row) => `${row.name} (${row.id})`).join(", ")}`,
9642
+ `Ambiguous ${kind5} "${value2}". Candidates: ${candidates.map((row) => `${row.name} (${row.id})`).join(", ")}`,
9619
9643
  EXIT_CODES.validation,
9620
9644
  { code: "ambiguous_context", candidates: candidates.map(({ id, name }) => ({ id, name })) }
9621
9645
  );
9622
- throw new CliError(`Unknown ${kind5} "${value}".`, EXIT_CODES.validation);
9646
+ throw new CliError(`Unknown ${kind5} "${value2}".`, EXIT_CODES.validation);
9623
9647
  }
9624
9648
  function resolveSelection(tree, input) {
9625
9649
  const [orgValue, shopValue, extra] = input.split("/");
@@ -10188,12 +10212,12 @@ var evidenceKinds = [
10188
10212
  ];
10189
10213
 
10190
10214
  // src/lib/experiment-handover.ts
10191
- function summarizeHandoverQa(value) {
10192
- const record4 = (value2) => value2 !== null && typeof value2 === "object" && !Array.isArray(value2) ? value2 : {};
10193
- const qa3 = record4(value);
10194
- const run3 = record4(qa3.latestRun);
10195
- const summary = record4(run3.summary);
10196
- const count2 = (value2) => typeof value2 === "number" && Number.isInteger(value2) && value2 >= 0 ? value2 : null;
10215
+ function summarizeHandoverQa(value2) {
10216
+ const record4 = (value3) => value3 !== null && typeof value3 === "object" && !Array.isArray(value3) ? value3 : {};
10217
+ const qa3 = record4(value2);
10218
+ const run4 = record4(qa3.latestRun);
10219
+ const summary = record4(run4.summary);
10220
+ const count2 = (value3) => typeof value3 === "number" && Number.isInteger(value3) && value3 >= 0 ? value3 : null;
10197
10221
  let requiredDone = count2(summary.completedRequired);
10198
10222
  let requiredTotal = count2(summary.required);
10199
10223
  if (requiredDone !== null && requiredTotal !== null && requiredDone > requiredTotal) {
@@ -10203,7 +10227,7 @@ function summarizeHandoverQa(value) {
10203
10227
  const blockers = Array.isArray(summary.blockers) && summary.blockers.every((item) => typeof item === "string") ? summary.blockers : null;
10204
10228
  const approvedAt = typeof qa3.qaApprovedAt === "string" ? Date.parse(qa3.qaApprovedAt) : Number.NaN;
10205
10229
  return {
10206
- run_status: typeof run3.status === "string" ? run3.status : null,
10230
+ run_status: typeof run4.status === "string" ? run4.status : null,
10207
10231
  required_done: requiredDone,
10208
10232
  required_total: requiredTotal,
10209
10233
  blockers,
@@ -10276,13 +10300,13 @@ function deviceLabel(targeting) {
10276
10300
  var ALL_PAGES_LABEL = "All pages";
10277
10301
  var CHECKOUT_LABEL = "Checkout";
10278
10302
  var UNKNOWN_PAGE_NAME = "Saved Page";
10279
- function isRecord(value) {
10280
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
10303
+ function isRecord(value2) {
10304
+ return Boolean(value2 && typeof value2 === "object" && !Array.isArray(value2));
10281
10305
  }
10282
- function arrayOf(value) {
10283
- if (Array.isArray(value)) return value;
10284
- if (value === void 0 || value === null) return [];
10285
- return [value];
10306
+ function arrayOf(value2) {
10307
+ if (Array.isArray(value2)) return value2;
10308
+ if (value2 === void 0 || value2 === null) return [];
10309
+ return [value2];
10286
10310
  }
10287
10311
  function ruleKey(rule) {
10288
10312
  if (typeof rule === "string") return JSON.stringify(["include", "simple", rule.trim(), ""]);
@@ -10360,11 +10384,11 @@ function classifyIdeaReference(reference) {
10360
10384
 
10361
10385
  // ../api-client/src/experiments.ts
10362
10386
  var ID_REFERENCE = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|[1-9][0-9]{9})$/i;
10363
- function isExperimentTestKey(value) {
10364
- return /^([A-Z0-9]{2,8})-(\d+)$/.test(value);
10387
+ function isExperimentTestKey(value2) {
10388
+ return /^([A-Z0-9]{2,8})-(\d+)$/.test(value2);
10365
10389
  }
10366
- function record(value) {
10367
- return value && typeof value === "object" && !Array.isArray(value) ? value : {};
10390
+ function record(value2) {
10391
+ return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : {};
10368
10392
  }
10369
10393
  async function resolveExperimentReference(request2, idOrSlug, variationRef) {
10370
10394
  const explicitSlug = idOrSlug.startsWith("slug:");
@@ -10448,9 +10472,9 @@ function summarizeResults(payload) {
10448
10472
  degraded: Object.values(degradedFlags).some(Boolean),
10449
10473
  degradedFlags,
10450
10474
  missingMetrics: [...missing],
10451
- warnings: Array.isArray(data.warnings) ? data.warnings.map((value) => ({
10452
- message: record(value).message,
10453
- value
10475
+ warnings: Array.isArray(data.warnings) ? data.warnings.map((value2) => ({
10476
+ message: record(value2).message,
10477
+ value: value2
10454
10478
  })) : [],
10455
10479
  metrics: Array.isArray(data.metrics) ? data.metrics.map(record) : [],
10456
10480
  resultsWeekdays: data.results_weekdays,
@@ -10514,25 +10538,25 @@ function extensionForMimeType(mimeType) {
10514
10538
  const safeSubtype = subtype?.replace(/[^a-z0-9.+-]/g, "");
10515
10539
  return safeSubtype ? `.${safeSubtype}` : ".bin";
10516
10540
  }
10517
- function dataUriFromMatch(value, match2) {
10541
+ function dataUriFromMatch(value2, match2) {
10518
10542
  let uri = match2[0];
10519
10543
  const start = match2.index ?? 0;
10520
- if (/url\(\s*$/i.test(value.slice(0, start))) {
10544
+ if (/url\(\s*$/i.test(value2.slice(0, start))) {
10521
10545
  const closingParenthesis = uri.indexOf(")");
10522
10546
  if (closingParenthesis >= 0) uri = uri.slice(0, closingParenthesis);
10523
10547
  }
10524
10548
  return uri;
10525
10549
  }
10526
- function surroundingNonWhitespaceNonQuoteRun(value, start, end) {
10527
- const before = value.slice(0, start).match(/[^\s"']*$/)?.[0] ?? "";
10528
- const after = value.slice(end).match(/^[^\s"']*/)?.[0] ?? "";
10529
- return `${before}${value.slice(start, end)}${after}`;
10550
+ function surroundingNonWhitespaceNonQuoteRun(value2, start, end) {
10551
+ const before = value2.slice(0, start).match(/[^\s"']*$/)?.[0] ?? "";
10552
+ const after = value2.slice(end).match(/^[^\s"']*/)?.[0] ?? "";
10553
+ return `${before}${value2.slice(start, end)}${after}`;
10530
10554
  }
10531
10555
  function isInsideRange(start, end, ranges) {
10532
10556
  return ranges.some((range) => start >= range.start && end <= range.end);
10533
10557
  }
10534
- function applyReplacements(value, replacements) {
10535
- let rewritten = value;
10558
+ function applyReplacements(value2, replacements) {
10559
+ let rewritten = value2;
10536
10560
  for (const replacement of replacements.sort((a, b) => b.start - a.start)) {
10537
10561
  rewritten = rewritten.slice(0, replacement.start) + replacement.value + rewritten.slice(replacement.end);
10538
10562
  }
@@ -10563,9 +10587,9 @@ function createAssetReferenceRewriter(options) {
10563
10587
  }
10564
10588
  return pending;
10565
10589
  };
10566
- const rewrite = async (value, baseDir = options.baseDir) => {
10567
- if (options.enabled === false || !value) return value;
10568
- let rewritten = value;
10590
+ const rewrite = async (value2, baseDir = options.baseDir) => {
10591
+ if (options.enabled === false || !value2) return value2;
10592
+ let rewritten = value2;
10569
10593
  const inlineMatches = [...rewritten.matchAll(DATA_IMAGE_URI_PATTERN)].map((match2) => ({ match: match2, uri: dataUriFromMatch(rewritten, match2) })).filter(({ uri }) => uri.length > INLINE_DATA_URI_MAX_CHARS);
10570
10594
  for (const { uri } of inlineMatches) {
10571
10595
  const commaIndex = uri.indexOf(",");
@@ -10640,22 +10664,22 @@ function createAssetReferenceRewriter(options) {
10640
10664
  }
10641
10665
  return applyReplacements(rewritten, bareReplacements);
10642
10666
  };
10643
- const rewriteUnknown = async (value, baseDir = options.baseDir) => {
10644
- if (typeof value === "string") return rewrite(value, baseDir);
10645
- if (Array.isArray(value)) {
10646
- return Promise.all(value.map((entry) => rewriteUnknown(entry, baseDir)));
10667
+ const rewriteUnknown = async (value2, baseDir = options.baseDir) => {
10668
+ if (typeof value2 === "string") return rewrite(value2, baseDir);
10669
+ if (Array.isArray(value2)) {
10670
+ return Promise.all(value2.map((entry) => rewriteUnknown(entry, baseDir)));
10647
10671
  }
10648
- if (value !== null && typeof value === "object") {
10672
+ if (value2 !== null && typeof value2 === "object") {
10649
10673
  return Object.fromEntries(
10650
10674
  await Promise.all(
10651
- Object.entries(value).map(async ([key, entry]) => [
10675
+ Object.entries(value2).map(async ([key, entry]) => [
10652
10676
  key,
10653
10677
  await rewriteUnknown(entry, baseDir)
10654
10678
  ])
10655
10679
  )
10656
10680
  );
10657
10681
  }
10658
- return value;
10682
+ return value2;
10659
10683
  };
10660
10684
  return { rewrite, rewriteUnknown };
10661
10685
  }
@@ -12862,27 +12886,27 @@ function printExperiment(exp, dashboardUrl = null) {
12862
12886
  }
12863
12887
  console.log();
12864
12888
  }
12865
- function formatPct(value, digits = 1) {
12866
- return typeof value === "number" && Number.isFinite(value) ? `${value.toFixed(digits)}%` : "-";
12889
+ function formatPct(value2, digits = 1) {
12890
+ return typeof value2 === "number" && Number.isFinite(value2) ? `${value2.toFixed(digits)}%` : "-";
12867
12891
  }
12868
- function confidenceBasisLabel(value) {
12869
- if (value === "fixed_horizon") return "fixed-horizon";
12870
- if (value === "sequential") return "always-valid";
12892
+ function confidenceBasisLabel(value2) {
12893
+ if (value2 === "fixed_horizon") return "fixed-horizon";
12894
+ if (value2 === "sequential") return "always-valid";
12871
12895
  return "unknown";
12872
12896
  }
12873
- function statisticsStateLabel(value) {
12874
- return value === "untrustworthy" ? "verdict withheld" : String(value ?? "unknown");
12897
+ function statisticsStateLabel(value2) {
12898
+ return value2 === "untrustworthy" ? "verdict withheld" : String(value2 ?? "unknown");
12875
12899
  }
12876
- function formatRevenue(value, currency) {
12877
- if (value === null || value === void 0) return "\u2014";
12878
- if (!currency || typeof value !== "number" || !Number.isFinite(value)) return String(value);
12900
+ function formatRevenue(value2, currency) {
12901
+ if (value2 === null || value2 === void 0) return "\u2014";
12902
+ if (!currency || typeof value2 !== "number" || !Number.isFinite(value2)) return String(value2);
12879
12903
  try {
12880
12904
  return new Intl.NumberFormat("en-US", {
12881
12905
  style: "currency",
12882
12906
  currency: currency.trim().toUpperCase()
12883
- }).format(value);
12907
+ }).format(value2);
12884
12908
  } catch {
12885
- return String(value);
12909
+ return String(value2);
12886
12910
  }
12887
12911
  }
12888
12912
  function audienceLine(segmentApplied) {
@@ -12971,8 +12995,8 @@ function printExperimentResults(results2, currency) {
12971
12995
  const deltas = arm.deltaVsControl;
12972
12996
  const cm = deltas?.cm;
12973
12997
  const ci = cm?.ci95;
12974
- const count2 = (value) => typeof value === "number" && Number.isFinite(value) ? String(value) : "-";
12975
- const money = (value) => typeof value === "number" ? formatRevenue(value, String(plane.currency ?? currency ?? "")) : "-";
12998
+ const count2 = (value2) => typeof value2 === "number" && Number.isFinite(value2) ? String(value2) : "-";
12999
+ const money = (value2) => typeof value2 === "number" ? formatRevenue(value2, String(plane.currency ?? currency ?? "")) : "-";
12976
13000
  return [
12977
13001
  String(arm.name ?? arm.variationId ?? "-"),
12978
13002
  // Fail closed: a missing count is unavailable, never a measured 0.
@@ -13025,13 +13049,13 @@ var EXPERIMENT_FILESYSTEM_PATH_SCHEMA = {
13025
13049
  variation: filesystemPaths.filter((entry) => entry.startsWith("variations/*/")).map((entry) => entry.slice("variations/*/".length))
13026
13050
  };
13027
13051
  var SERVER_OWNED_EXPERIMENT_FILES = /* @__PURE__ */ new Set(["qa.json", "launch.json"]);
13028
- var escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
13052
+ var escapeRegex = (value2) => value2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
13029
13053
  var pathAlternation = (paths) => paths.map(escapeRegex).join("|");
13030
13054
  var FILESYSTEM_FILE_RE = new RegExp(
13031
13055
  `^(?:${pathAlternation(EXPERIMENT_FILESYSTEM_PATH_SCHEMA.topLevel)}|experiment/(?:${pathAlternation(EXPERIMENT_FILESYSTEM_PATH_SCHEMA.experiment)})|commerce/(?:${pathAlternation(EXPERIMENT_FILESYSTEM_PATH_SCHEMA.commerce)})|variations/[^/]+/(?:${pathAlternation(EXPERIMENT_FILESYSTEM_PATH_SCHEMA.variation)}))$`
13032
13056
  );
13033
- function sha256Text(value) {
13034
- return import_node_crypto6.default.createHash("sha256").update(value).digest("hex");
13057
+ function sha256Text(value2) {
13058
+ return import_node_crypto6.default.createHash("sha256").update(value2).digest("hex");
13035
13059
  }
13036
13060
  function folderPath(folder) {
13037
13061
  return import_node_path6.default.resolve(process.cwd(), folder);
@@ -13216,6 +13240,19 @@ function printFilesystemPlan(plan2) {
13216
13240
  console.log(` - [${issue.code}] ${issue.message}${context ? ` (${context})` : ""}`);
13217
13241
  });
13218
13242
  }
13243
+ if ((plan2.commerceLaunchPreview?.length ?? 0) > 0) {
13244
+ console.log(source_default.bold("\nLaunch preview"));
13245
+ for (const preview2 of plan2.commerceLaunchPreview ?? []) {
13246
+ console.log(` ${preview2.kind} (${preview2.path})`);
13247
+ for (const issue of preview2.issues) {
13248
+ const variation = issue.variation ? ` (variation: ${issue.variation})` : "";
13249
+ console.log(source_default.yellow(` - [${issue.code}] ${issue.message}${variation}`));
13250
+ }
13251
+ console.log(` Checked at plan: ${preview2.checked.join(", ") || "none"}`);
13252
+ for (const item of preview2.launchOnly)
13253
+ console.log(` Checked at ${item.when ?? "launch"}: ${item.check}: ${item.reason}`);
13254
+ }
13255
+ }
13219
13256
  console.log(source_default.bold("\nChanges"));
13220
13257
  if (plan2.changes.length === 0) {
13221
13258
  console.log(source_default.dim(" No changes."));
@@ -13299,38 +13336,38 @@ function printQaPreviewUrls(experimentId, result) {
13299
13336
  );
13300
13337
  }
13301
13338
  }
13302
- function qaVersionMarker(value) {
13303
- const version = value;
13339
+ function qaVersionMarker(value2) {
13340
+ const version = value2;
13304
13341
  return version.stale ? " [stale: checked against an earlier version]" : version.unversioned ? " [unversioned]" : "";
13305
13342
  }
13306
- function printQaRun(run3) {
13343
+ function printQaRun(run4) {
13307
13344
  console.log();
13308
- console.log(source_default.bold(`QA run ${run3.id}`));
13309
- console.log(` computedAt: ${run3.computedAt}`);
13310
- console.log(` Status: ${statusBadge(run3.summary.status)}`);
13311
- console.log(` Required: ${run3.summary.completedRequired}/${run3.summary.required}`);
13312
- if (run3.approvedAt) console.log(` Approved: ${run3.approvedAt}`);
13313
- if (run3.completedAt) console.log(` Complete: ${run3.completedAt}`);
13314
- if (run3.summary.blockers.length > 0) {
13345
+ console.log(source_default.bold(`QA run ${run4.id}`));
13346
+ console.log(` computedAt: ${run4.computedAt}`);
13347
+ console.log(` Status: ${statusBadge(run4.summary.status)}`);
13348
+ console.log(` Required: ${run4.summary.completedRequired}/${run4.summary.required}`);
13349
+ if (run4.approvedAt) console.log(` Approved: ${run4.approvedAt}`);
13350
+ if (run4.completedAt) console.log(` Complete: ${run4.completedAt}`);
13351
+ if (run4.summary.blockers.length > 0) {
13315
13352
  console.log(source_default.yellow("\nBlockers"));
13316
- run3.summary.blockers.forEach((blocker) => console.log(` - ${blocker}`));
13353
+ run4.summary.blockers.forEach((blocker) => console.log(` - ${blocker}`));
13317
13354
  }
13318
13355
  console.log(source_default.bold("\nChecklist"));
13319
- for (const item of run3.checklist) {
13356
+ for (const item of run4.checklist) {
13320
13357
  const required = item.required ? source_default.yellow(" required") : "";
13321
13358
  const notes = item.notes ? source_default.dim(` \u2014 ${item.notes}`) : "";
13322
13359
  console.log(` ${statusBadge(item.status)} ${item.id}${required}${qaVersionMarker(item)}`);
13323
13360
  console.log(` ${item.title}${notes}`);
13324
13361
  }
13325
- if (run3.urls.length > 0) {
13362
+ if (run4.urls.length > 0) {
13326
13363
  console.log(source_default.bold("\nQA URLs"));
13327
- run3.urls.forEach((url) => {
13364
+ run4.urls.forEach((url) => {
13328
13365
  console.log(` - ${url.label}: ${source_default.cyan(url.url)}`);
13329
13366
  });
13330
13367
  }
13331
- if ((run3.evidenceRecords ?? []).length > 0) {
13368
+ if ((run4.evidenceRecords ?? []).length > 0) {
13332
13369
  console.log(source_default.bold("\nEvidence records"));
13333
- for (const record4 of run3.evidenceRecords ?? []) {
13370
+ for (const record4 of run4.evidenceRecords ?? []) {
13334
13371
  const device = record4.device ? ` \xB7 ${record4.device}` : "";
13335
13372
  console.log(
13336
13373
  ` - ${record4.kind} \xB7 ${record4.label} \xB7 ${record4.status}${device} \xB7 ${record4.capturedAt}${qaVersionMarker(record4)}`
@@ -13343,18 +13380,18 @@ async function confirmApply(message) {
13343
13380
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
13344
13381
  return null;
13345
13382
  }
13346
- const readline3 = await import("node:readline");
13347
- const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
13383
+ const readline4 = await import("node:readline");
13384
+ const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
13348
13385
  const answer = await new Promise((resolve2) => {
13349
13386
  rl.question(source_default.yellow(`${message} [y/N] `), resolve2);
13350
13387
  });
13351
13388
  rl.close();
13352
13389
  return answer.toLowerCase() === "y";
13353
13390
  }
13354
- function parseEvidenceInput(value) {
13355
- if (!value) return void 0;
13356
- const source = value.startsWith("@") ? value.slice(1) : value;
13357
- const text2 = value.startsWith("@") || import_node_fs8.default.existsSync(source) ? import_node_fs8.default.readFileSync(import_node_path6.default.resolve(process.cwd(), source), "utf8") : value;
13391
+ function parseEvidenceInput(value2) {
13392
+ if (!value2) return void 0;
13393
+ const source = value2.startsWith("@") ? value2.slice(1) : value2;
13394
+ const text2 = value2.startsWith("@") || import_node_fs8.default.existsSync(source) ? import_node_fs8.default.readFileSync(import_node_path6.default.resolve(process.cwd(), source), "utf8") : value2;
13358
13395
  const parsed = JSON.parse(text2);
13359
13396
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
13360
13397
  throw new Error("QA evidence must be a JSON object");
@@ -13362,24 +13399,24 @@ function parseEvidenceInput(value) {
13362
13399
  return parsed;
13363
13400
  }
13364
13401
  function qaChoice(flags, description, choices) {
13365
- return new Option(flags, description).choices([...choices]).argParser((value) => value);
13402
+ return new Option(flags, description).choices([...choices]).argParser((value2) => value2);
13366
13403
  }
13367
- function validateQaChoice(command, option, value, allowed2) {
13368
- if (value !== void 0 && !allowed2.includes(value)) {
13369
- fail(command, `Invalid ${option}: ${value}`, EXIT_CODES.validation, {
13404
+ function validateQaChoice(command, option, value2, allowed2) {
13405
+ if (value2 !== void 0 && !allowed2.includes(value2)) {
13406
+ fail(command, `Invalid ${option}: ${value2}`, EXIT_CODES.validation, {
13370
13407
  option,
13371
13408
  allowedValues: [...allowed2]
13372
13409
  });
13373
13410
  }
13374
13411
  }
13375
- function qaSummary(run3, changed) {
13412
+ function qaSummary(run4, changed) {
13376
13413
  return {
13377
13414
  run: {
13378
- id: run3.id,
13379
- status: run3.status,
13380
- summary: run3.summary,
13381
- approvedAt: run3.approvedAt,
13382
- updatedAt: run3.updatedAt
13415
+ id: run4.id,
13416
+ status: run4.status,
13417
+ summary: run4.summary,
13418
+ approvedAt: run4.approvedAt,
13419
+ updatedAt: run4.updatedAt
13383
13420
  },
13384
13421
  changed,
13385
13422
  validationErrors: []
@@ -13392,8 +13429,8 @@ function tryReadFilesystemSession(folder) {
13392
13429
  return null;
13393
13430
  }
13394
13431
  }
13395
- async function resolveExperimentForFilesystemOrId(value) {
13396
- const candidate = folderPath(value);
13432
+ async function resolveExperimentForFilesystemOrId(value2) {
13433
+ const candidate = folderPath(value2);
13397
13434
  const session = tryReadFilesystemSession(candidate);
13398
13435
  if (session) {
13399
13436
  return {
@@ -13402,8 +13439,8 @@ async function resolveExperimentForFilesystemOrId(value) {
13402
13439
  label: import_node_path6.default.basename(candidate)
13403
13440
  };
13404
13441
  }
13405
- const exp = await resolveExperiment(value);
13406
- if (!exp) throw new Error(`Experiment "${value}" not found.`);
13442
+ const exp = await resolveExperiment(value2);
13443
+ if (!exp) throw new Error(`Experiment "${value2}" not found.`);
13407
13444
  return { experimentId: exp.id, folder: null, label: exp.name };
13408
13445
  }
13409
13446
  async function refreshExperimentFilesystemFolderIfNeeded(creds, folder, experimentId) {
@@ -13525,8 +13562,8 @@ var list = new Command("list").alias("ls").description(
13525
13562
  fields3.map((field) => field.toUpperCase()),
13526
13563
  experiments.map(
13527
13564
  (experiment2) => fields3.map((field) => {
13528
- const value = experiment2[field];
13529
- return value == null ? "-" : typeof value === "object" ? JSON.stringify(value) : String(value);
13565
+ const value2 = experiment2[field];
13566
+ return value2 == null ? "-" : typeof value2 === "object" ? JSON.stringify(value2) : String(value2);
13530
13567
  })
13531
13568
  )
13532
13569
  );
@@ -13769,17 +13806,17 @@ var update = new Command("update").description("Update an experiment").addOption
13769
13806
  );
13770
13807
  });
13771
13808
  });
13772
- function collectCreateOption(value, previous) {
13773
- return [...previous, value];
13809
+ function collectCreateOption(value2, previous) {
13810
+ return [...previous, value2];
13774
13811
  }
13775
- function parseHttpDestination(value) {
13776
- const trimmed = value.trim();
13812
+ function parseHttpDestination(value2) {
13813
+ const trimmed = value2.trim();
13777
13814
  try {
13778
13815
  const url = new URL(trimmed);
13779
13816
  if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error();
13780
13817
  } catch {
13781
13818
  throw new CliError(
13782
- `Invalid redirect destination "${value}": expected an HTTP(S) URL.`,
13819
+ `Invalid redirect destination "${value2}": expected an HTTP(S) URL.`,
13783
13820
  EXIT_CODES.validation
13784
13821
  );
13785
13822
  }
@@ -13823,8 +13860,8 @@ function normalizeNewGoalKey(key) {
13823
13860
  const normalized = key.trim().toLowerCase().replace(/-/g, "_");
13824
13861
  return normalized === "page" ? "page_id" : normalized;
13825
13862
  }
13826
- function validateNewGoal(command, value, body5) {
13827
- const invalid = (reason2) => fail(command, `Invalid --goal "new:${value}"; ${reason2}`, EXIT_CODES.validation);
13863
+ function validateNewGoal(command, value2, body5) {
13864
+ const invalid = (reason2) => fail(command, `Invalid --goal "new:${value2}"; ${reason2}`, EXIT_CODES.validation);
13828
13865
  const text2 = (field) => {
13829
13866
  const raw = body5[field];
13830
13867
  return typeof raw === "string" && raw.length > 0 ? raw : void 0;
@@ -13872,20 +13909,20 @@ function validateNewGoal(command, value, body5) {
13872
13909
  if (valueUnit && !GOAL_VALUE_UNITS.includes(valueUnit))
13873
13910
  invalid(`value-unit must be one of ${GOAL_VALUE_UNITS.join(", ")}`);
13874
13911
  }
13875
- function parseNewGoal(command, value) {
13912
+ function parseNewGoal(command, value2) {
13876
13913
  const body5 = {};
13877
- for (const field of value.split(",")) {
13914
+ for (const field of value2.split(",")) {
13878
13915
  const separator = field.indexOf("=");
13879
13916
  if (separator <= 0 || separator === field.length - 1) {
13880
13917
  fail(
13881
13918
  command,
13882
- `Invalid --goal "new:${value}"; use new:type=<type>,selector=<css>,name=<text>`,
13919
+ `Invalid --goal "new:${value2}"; use new:type=<type>,selector=<css>,name=<text>`,
13883
13920
  EXIT_CODES.validation
13884
13921
  );
13885
13922
  }
13886
13923
  body5[normalizeNewGoalKey(field.slice(0, separator))] = field.slice(separator + 1).trim();
13887
13924
  }
13888
- validateNewGoal(command, value, body5);
13925
+ validateNewGoal(command, value2, body5);
13889
13926
  return body5;
13890
13927
  }
13891
13928
  async function resolveNewGoalPages(command, creds, goals, interactive) {
@@ -13928,8 +13965,8 @@ async function resolveNewGoalPages(command, creds, goals, interactive) {
13928
13965
  }
13929
13966
  }
13930
13967
  async function askCreate(question) {
13931
- const readline3 = await import("node:readline");
13932
- const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
13968
+ const readline4 = await import("node:readline");
13969
+ const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
13933
13970
  return new Promise(
13934
13971
  (resolve2) => rl.question(question, (answer) => {
13935
13972
  rl.close();
@@ -14026,8 +14063,8 @@ var create = new Command("create").description(
14026
14063
  if (!Number.isFinite(traffic) || traffic < 0 || traffic > 100) {
14027
14064
  fail(this, "--traffic must be a number from 0 to 100", EXIT_CODES.validation);
14028
14065
  }
14029
- const sourceRules = [...opts.sourceUrl, ...opts.pageUrl].map((value) => value.trim());
14030
- if (sourceRules.some((value) => value.length === 0)) {
14066
+ const sourceRules = [...opts.sourceUrl, ...opts.pageUrl].map((value2) => value2.trim());
14067
+ if (sourceRules.some((value2) => value2.length === 0)) {
14031
14068
  fail(this, "--source-url/--page-url cannot be empty", EXIT_CODES.validation);
14032
14069
  }
14033
14070
  if (opts.type !== "redirect" && opts.destination.length > 0) {
@@ -14330,8 +14367,8 @@ var del = new Command("delete").alias("rm").description("Delete an experiment").
14330
14367
  `apex experiments delete ${idOrSlug} --force`
14331
14368
  );
14332
14369
  }
14333
- const readline3 = await import("node:readline");
14334
- const rl = readline3.createInterface({
14370
+ const readline4 = await import("node:readline");
14371
+ const rl = readline4.createInterface({
14335
14372
  input: process.stdin,
14336
14373
  output: process.stderr
14337
14374
  });
@@ -14946,7 +14983,7 @@ var applyFilesystem = new Command("apply").option(
14946
14983
  );
14947
14984
  for (const variation of receipt.variations) {
14948
14985
  console.log(
14949
- ` ${variation.name} (${variation.slug}): ${Object.entries(variation.digests).map(([key, value]) => `${key}=${value ?? "null"}`).join(" ")}`
14986
+ ` ${variation.name} (${variation.slug}): ${Object.entries(variation.digests).map(([key, value2]) => `${key}=${value2 ?? "null"}`).join(" ")}`
14950
14987
  );
14951
14988
  }
14952
14989
  }
@@ -15019,18 +15056,18 @@ var qaCheck = new Command("check").description("Update one QA checklist item wit
15019
15056
  classifyStatus(res.status),
15020
15057
  res.errorDetails
15021
15058
  );
15022
- const run3 = res.data.run;
15059
+ const run4 = res.data.run;
15023
15060
  await refreshExperimentFilesystemFolderIfNeeded(
15024
15061
  creds,
15025
15062
  resolved.folder,
15026
15063
  resolved.experimentId
15027
15064
  );
15028
- const data = opts.summary ? qaSummary(run3, run3.checklist.find((item) => item.id === opts.item) ?? null) : res.data;
15065
+ const data = opts.summary ? qaSummary(run4, run4.checklist.find((item) => item.id === opts.item) ?? null) : res.data;
15029
15066
  output(this, data, () => {
15030
15067
  spinner.succeed("Updated QA checklist");
15031
15068
  if (opts.summary) process.stdout.write(`${JSON.stringify(data, null, 2)}
15032
15069
  `);
15033
- else printQaRun(run3);
15070
+ else printQaRun(run4);
15034
15071
  });
15035
15072
  } catch (error) {
15036
15073
  spinner.fail("Failed to update QA checklist");
@@ -15065,21 +15102,21 @@ var qaNotes = new Command("notes").description("Update QA run notes or acceptanc
15065
15102
  classifyStatus(res.status),
15066
15103
  res.errorDetails
15067
15104
  );
15068
- const run3 = res.data.run;
15105
+ const run4 = res.data.run;
15069
15106
  await refreshExperimentFilesystemFolderIfNeeded(
15070
15107
  creds,
15071
15108
  resolved.folder,
15072
15109
  resolved.experimentId
15073
15110
  );
15074
- const data = opts.summary ? qaSummary(run3, {
15075
- notes: run3.notes,
15076
- acceptanceCriteriaSummary: run3.acceptanceCriteriaSummary
15111
+ const data = opts.summary ? qaSummary(run4, {
15112
+ notes: run4.notes,
15113
+ acceptanceCriteriaSummary: run4.acceptanceCriteriaSummary
15077
15114
  }) : res.data;
15078
15115
  output(this, data, () => {
15079
15116
  spinner.succeed("Updated QA notes");
15080
15117
  if (opts.summary) process.stdout.write(`${JSON.stringify(data, null, 2)}
15081
15118
  `);
15082
- else printQaRun(run3);
15119
+ else printQaRun(run4);
15083
15120
  });
15084
15121
  } catch (error) {
15085
15122
  spinner.fail("Failed to update QA notes");
@@ -15119,9 +15156,9 @@ var qaApprove = new Command("approve").description("Approve QA and move the expe
15119
15156
  }
15120
15157
  if (typeof details.split_hash === "string" && details.split_hash.length > 0) {
15121
15158
  const weights = Array.isArray(details.variation_weights) ? details.variation_weights : [];
15122
- for (const value of weights) {
15123
- if (value && typeof value === "object") {
15124
- const variation = value;
15159
+ for (const value2 of weights) {
15160
+ if (value2 && typeof value2 === "object") {
15161
+ const variation = value2;
15125
15162
  process.stderr.write(
15126
15163
  `${variation.name ?? variation.id ?? "Variation"}: ${(variation.weight ?? 0) * 100}%${variation.weight === 0 ? " (no traffic)" : ""}
15127
15164
  `
@@ -15197,17 +15234,17 @@ var qaReopen = new Command("reopen").description("Reopen QA and clear scheduled
15197
15234
  throw error;
15198
15235
  }
15199
15236
  });
15200
- function parseJsonValue(value) {
15201
- const source = value.startsWith("@") ? value.slice(1) : value;
15202
- const text2 = value.startsWith("@") || import_node_fs8.default.existsSync(source) ? import_node_fs8.default.readFileSync(import_node_path6.default.resolve(process.cwd(), source), "utf8") : value;
15237
+ function parseJsonValue(value2) {
15238
+ const source = value2.startsWith("@") ? value2.slice(1) : value2;
15239
+ const text2 = value2.startsWith("@") || import_node_fs8.default.existsSync(source) ? import_node_fs8.default.readFileSync(import_node_path6.default.resolve(process.cwd(), source), "utf8") : value2;
15203
15240
  return JSON.parse(text2);
15204
15241
  }
15205
- function collectFile(value, previous = []) {
15206
- return [...previous, value];
15242
+ function collectFile(value2, previous = []) {
15243
+ return [...previous, value2];
15207
15244
  }
15208
- function normalizeEvidenceDevice(value) {
15209
- if (!value) return void 0;
15210
- const normalized = value.trim().toLowerCase();
15245
+ function normalizeEvidenceDevice(value2) {
15246
+ if (!value2) return void 0;
15247
+ const normalized = value2.trim().toLowerCase();
15211
15248
  if (normalized === "desktop_chrome" || normalized === "desktop_safari") return "desktop";
15212
15249
  if (normalized === "iphone_15_pro" || normalized === "galaxy_s24") return "mobile";
15213
15250
  if (normalized === "ipad_pro") return "tablet";
@@ -15294,15 +15331,15 @@ var qaEvidence = new Command("evidence").description("Attach screenshot jobs or
15294
15331
  );
15295
15332
  }
15296
15333
  spinner.stop();
15297
- const run3 = response.data.run;
15334
+ const run4 = response.data.run;
15298
15335
  const data = opts.summary ? qaSummary(
15299
- run3,
15300
- run3.evidenceRecords.filter((record4) => !previousIds.has(record4.id))
15336
+ run4,
15337
+ run4.evidenceRecords.filter((record4) => !previousIds.has(record4.id))
15301
15338
  ) : response.data;
15302
15339
  output(this, data, () => {
15303
15340
  if (opts.summary) process.stdout.write(`${JSON.stringify(data, null, 2)}
15304
15341
  `);
15305
- else printQaRun(run3);
15342
+ else printQaRun(run4);
15306
15343
  });
15307
15344
  } catch (error) {
15308
15345
  spinner.fail("Failed to write QA evidence");
@@ -15334,14 +15371,14 @@ var qa = new Command("qa").description("Manage experiment QA runs from the CLI")
15334
15371
  data,
15335
15372
  () => printTable(
15336
15373
  ["KIND", "STATE", "SUMMARY"],
15337
- Object.entries(data.kinds).map(([kind5, value]) => [
15374
+ Object.entries(data.kinds).map(([kind5, value2]) => [
15338
15375
  kind5,
15339
- value.evidence.state,
15340
- value.result?.summary ?? value.evidence.reasons[0] ?? "Saved evidence is current."
15376
+ value2.evidence.state,
15377
+ value2.result?.summary ?? value2.evidence.reasons[0] ?? "Saved evidence is current."
15341
15378
  ])
15342
15379
  )
15343
15380
  );
15344
- const states = Object.values(data.kinds).map((value) => value?.evidence.state);
15381
+ const states = Object.values(data.kinds).map((value2) => value2?.evidence.state);
15345
15382
  if (states.some((state) => state !== "pass")) {
15346
15383
  console.error(
15347
15384
  "Next: fix stale, pending, or failing evidence and run apex experiments qa probe again."
@@ -15405,11 +15442,11 @@ var SCREENSHOT_DEVICES = [
15405
15442
  "ipad_pro",
15406
15443
  "desktop_safari"
15407
15444
  ];
15408
- var safeFilenamePart = (value) => value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "screenshot";
15409
- var commaList = (value) => value.split(",").map((item) => item.trim()).filter(Boolean);
15410
- function shellQuote(value) {
15411
- if (value.length > 0 && /^[A-Za-z0-9_@%+=:,./-]+$/.test(value)) return value;
15412
- return `'${value.replaceAll("'", "'\\''")}'`;
15445
+ var safeFilenamePart = (value2) => value2.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "screenshot";
15446
+ var commaList = (value2) => value2.split(",").map((item) => item.trim()).filter(Boolean);
15447
+ function shellQuote(value2) {
15448
+ if (value2.length > 0 && /^[A-Za-z0-9_@%+=:,./-]+$/.test(value2)) return value2;
15449
+ return `'${value2.replaceAll("'", "'\\''")}'`;
15413
15450
  }
15414
15451
  function isTransientResumeStatus(status4) {
15415
15452
  return status4 === 429 || status4 !== void 0 && status4 >= 500;
@@ -15794,11 +15831,197 @@ Examples:
15794
15831
  `
15795
15832
  );
15796
15833
 
15834
+ // src/commands/results.ts
15835
+ var import_node_fs9 = __toESM(require("node:fs"));
15836
+ var import_node_path7 = __toESM(require("node:path"));
15837
+ var import_promises3 = __toESM(require("node:readline/promises"));
15838
+ var OUTCOMES = /* @__PURE__ */ new Set(["won", "lost", "inconclusive"]);
15839
+ function collect(value2, previous) {
15840
+ return [...previous, value2];
15841
+ }
15842
+ function pair(command, value2, flag) {
15843
+ const index = value2.indexOf("=");
15844
+ if (index <= 0 || index === value2.length - 1)
15845
+ fail(command, `Invalid ${flag} "${value2}": use left=right.`, EXIT_CODES.validation);
15846
+ return [value2.slice(0, index).trim(), value2.slice(index + 1).trim()];
15847
+ }
15848
+ function apiFailure(command, response) {
15849
+ const body5 = response.data;
15850
+ fail(
15851
+ command,
15852
+ body5?.error?.message ?? response.error ?? `Request failed (HTTP ${response.status})`,
15853
+ classifyStatus(response.status),
15854
+ void 0,
15855
+ { status: response.status, body: response.data }
15856
+ );
15857
+ }
15858
+ function value(row, key) {
15859
+ const item = row[key];
15860
+ return item == null ? "-" : String(item);
15861
+ }
15862
+ function printPreview(preview2) {
15863
+ printTable(
15864
+ ["ROW", "TITLE", "OUTCOME", "METRIC", "LIFT", "SAMPLE", "CONF", "DEVICE", "DATES", "LEARNING"],
15865
+ preview2.rows.map((row, index) => [
15866
+ String(row.source_row ?? index + 1),
15867
+ value(row, "title"),
15868
+ value(row, "outcome"),
15869
+ value(row, "primary_metric"),
15870
+ value(row, "primary_lift"),
15871
+ value(row, "sample_size"),
15872
+ value(row, "confidence"),
15873
+ value(row, "device"),
15874
+ [row.started_at, row.ended_at].filter(Boolean).join(" \u2013 ") || "-",
15875
+ value(row, "learning").slice(0, 60)
15876
+ ])
15877
+ );
15878
+ for (const error of preview2.error_rows ?? [])
15879
+ console.error(`${error.source_name}:${error.source_row} ${error.field}: ${error.error}`);
15880
+ for (const warning of preview2.warnings ?? [])
15881
+ console.error(`Warning: ${typeof warning === "string" ? warning : JSON.stringify(warning)}`);
15882
+ }
15883
+ var importCommand = new Command("import").description("Upload past test results from CSV or JSON files").requiredOption("--file <path>", "CSV or JSON file (repeatable)", collect, []).option(
15884
+ "--map <column=field>",
15885
+ "Map a file column to an Apex field (repeatable). Fields: title, outcome, learning, primary_lift, sample_size, page_url, page_label, device, description, started_at, ended_at, legacy_id",
15886
+ collect,
15887
+ []
15888
+ ).option(
15889
+ "--outcome-value <value=outcome>",
15890
+ "Map a value of the outcome column to won, lost or inconclusive (repeatable)",
15891
+ collect,
15892
+ []
15893
+ ).option("--source <name>", "Source name stored on every imported row (default: the file name)").option("--dry-run", "Inspect and preview without importing").option("--yes", "Confirm the import without prompting").action(async function(options) {
15894
+ const creds = requireCredentials();
15895
+ const shopId = creds.resolvedContext?.shopId;
15896
+ const shopCredentials = creds;
15897
+ const shopLabel = shopCredentials.shopDomain ?? shopCredentials.domain ?? shopId ?? "the selected shop";
15898
+ const makeForm = () => {
15899
+ const form = new FormData();
15900
+ for (const fileArg of options.file) {
15901
+ const resolved = import_node_path7.default.resolve(fileArg);
15902
+ let bytes;
15903
+ try {
15904
+ bytes = import_node_fs9.default.readFileSync(resolved);
15905
+ } catch (error) {
15906
+ fail(
15907
+ this,
15908
+ `Could not read ${fileArg}: ${error instanceof Error ? error.message : String(error)}`,
15909
+ EXIT_CODES.validation,
15910
+ { code: "local_file_error" }
15911
+ );
15912
+ }
15913
+ form.append("files", new Blob([bytes]), import_node_path7.default.basename(resolved));
15914
+ }
15915
+ return form;
15916
+ };
15917
+ const inspected = await requestForm(creds, "POST", "/api/v1/test-results/import/inspect", makeForm());
15918
+ if (!inspected.ok || !inspected.data) apiFailure(this, inspected);
15919
+ const mapping = { ...inspected.data.data.suggested_mapping.columns };
15920
+ for (const raw of options.map) {
15921
+ const [column, field] = pair(this, raw, "--map");
15922
+ mapping[field] = column;
15923
+ }
15924
+ const outcomeValues = { ...inspected.data.data.suggested_mapping.outcome_values };
15925
+ for (const raw of options.outcomeValue) {
15926
+ const [source, outcome] = pair(this, raw, "--outcome-value");
15927
+ if (!OUTCOMES.has(outcome))
15928
+ fail(
15929
+ this,
15930
+ `Invalid outcome "${outcome}": use won, lost, or inconclusive.`,
15931
+ EXIT_CODES.validation
15932
+ );
15933
+ outcomeValues[source] = outcome;
15934
+ }
15935
+ const missing = ["title", "outcome", "learning"].filter((field) => !mapping[field]);
15936
+ if (missing.length)
15937
+ fail(
15938
+ this,
15939
+ `Unmapped required columns: ${missing.join(", ")}. Use --map <column=field>.`,
15940
+ EXIT_CODES.validation
15941
+ );
15942
+ const previewForm = makeForm();
15943
+ previewForm.append(
15944
+ "mapping",
15945
+ JSON.stringify({ columns: mapping, outcome_values: outcomeValues })
15946
+ );
15947
+ const previewResponse = await requestForm(
15948
+ creds,
15949
+ "POST",
15950
+ "/api/v1/test-results/import/preview",
15951
+ previewForm
15952
+ );
15953
+ if (!previewResponse.ok || !previewResponse.data) apiFailure(this, previewResponse);
15954
+ const preview2 = previewResponse.data.data;
15955
+ if (preview2.error_rows?.length) {
15956
+ if (!shouldUseJson(this)) printPreview(preview2);
15957
+ fail(
15958
+ this,
15959
+ `Preview found ${preview2.error_rows.length} row error(s); nothing was imported.`,
15960
+ EXIT_CODES.validation,
15961
+ { preview: preview2 }
15962
+ );
15963
+ }
15964
+ if (options.dryRun) {
15965
+ output(this, previewResponse.data, () => printPreview(preview2));
15966
+ return;
15967
+ }
15968
+ if (!shouldUseJson(this)) printPreview(preview2);
15969
+ if (!options.yes) {
15970
+ const globals = this.optsWithGlobals();
15971
+ const retryArgs = [
15972
+ ...options.file.map((file) => `--file ${JSON.stringify(file)}`),
15973
+ ...options.map.map((value2) => `--map ${JSON.stringify(value2)}`),
15974
+ ...options.outcomeValue.map((value2) => `--outcome-value ${JSON.stringify(value2)}`),
15975
+ ...options.source !== void 0 ? [`--source ${JSON.stringify(options.source)}`] : [],
15976
+ ...globals.shop ? [`--shop ${JSON.stringify(globals.shop)}`] : [],
15977
+ ...globals.org ? [`--org ${JSON.stringify(globals.org)}`] : []
15978
+ ];
15979
+ const retry = `apex results import ${retryArgs.join(" ")} --yes`;
15980
+ if (!process.stdin.isTTY)
15981
+ confirmationRequired(
15982
+ this,
15983
+ "Import confirmation is required in non-TTY mode; rerun with --yes.",
15984
+ retry
15985
+ );
15986
+ const rl = import_promises3.default.createInterface({ input: process.stdin, output: process.stderr });
15987
+ const answer = await rl.question(
15988
+ `Import ${preview2.rows.length} rows into ${shopLabel}? [y/N] `
15989
+ );
15990
+ rl.close();
15991
+ if (!/^y(es)?$/i.test(answer.trim()))
15992
+ confirmationRequired(this, "Import cancelled; rerun with --yes to confirm.", retry);
15993
+ }
15994
+ const merged = { imported: 0, skipped: 0, test_results: [] };
15995
+ for (let offset = 0; offset < preview2.rows.length; offset += 500) {
15996
+ const response = await request(
15997
+ creds,
15998
+ "POST",
15999
+ "/api/v1/test-results/import/confirm",
16000
+ {
16001
+ rows: preview2.rows.slice(offset, offset + 500).map((row) => options.source ? { ...row, source_name: options.source } : row)
16002
+ }
16003
+ );
16004
+ if (!response.ok || !response.data) apiFailure(this, response);
16005
+ merged.imported += response.data.data.imported;
16006
+ merged.skipped += response.data.data.skipped;
16007
+ merged.test_results.push(...response.data.data.test_results);
16008
+ }
16009
+ for (const row of merged.test_results)
16010
+ if (row.shop_id != null)
16011
+ assertResponseShop(String(row.shop_id), shopId, creds.credentialKind);
16012
+ output(
16013
+ this,
16014
+ merged,
16015
+ () => console.log(`Imported ${merged.imported}, skipped ${merged.skipped} (already present).`)
16016
+ );
16017
+ });
16018
+ var resultsCommand = new Command("results").description("Import and manage test results").addCommand(importCommand);
16019
+
15797
16020
  // src/commands/push.ts
15798
16021
  init_source();
15799
- var import_node_fs9 = __toESM(require("node:fs"));
16022
+ var import_node_fs10 = __toESM(require("node:fs"));
15800
16023
  var import_node_os7 = __toESM(require("node:os"));
15801
- var import_node_path7 = __toESM(require("node:path"));
16024
+ var import_node_path8 = __toESM(require("node:path"));
15802
16025
  var import_node_url2 = require("node:url");
15803
16026
  function toApiBody(exp) {
15804
16027
  return {
@@ -15839,7 +16062,7 @@ async function rewriteExperimentAssets(exp, rewrite, baseDir) {
15839
16062
  };
15840
16063
  }
15841
16064
  async function importConfigModule(absPath) {
15842
- const ext = import_node_path7.default.extname(absPath).toLowerCase();
16065
+ const ext = import_node_path8.default.extname(absPath).toLowerCase();
15843
16066
  if (ext === ".js" || ext === ".mjs" || ext === ".cjs") {
15844
16067
  return await import((0, import_node_url2.pathToFileURL)(absPath).href);
15845
16068
  }
@@ -15853,8 +16076,8 @@ async function importConfigModule(absPath) {
15853
16076
  ` + (err instanceof Error ? err.message : String(err))
15854
16077
  );
15855
16078
  }
15856
- const tmpDir = import_node_fs9.default.mkdtempSync(import_node_path7.default.join(import_node_os7.default.tmpdir(), "drip-config-"));
15857
- const outFile = import_node_path7.default.join(tmpDir, "config.mjs");
16079
+ const tmpDir = import_node_fs10.default.mkdtempSync(import_node_path8.default.join(import_node_os7.default.tmpdir(), "drip-config-"));
16080
+ const outFile = import_node_path8.default.join(tmpDir, "config.mjs");
15858
16081
  try {
15859
16082
  await esbuild.build({
15860
16083
  entryPoints: [absPath],
@@ -15870,15 +16093,15 @@ async function importConfigModule(absPath) {
15870
16093
  return await import(href);
15871
16094
  } finally {
15872
16095
  try {
15873
- import_node_fs9.default.rmSync(tmpDir, { recursive: true, force: true });
16096
+ import_node_fs10.default.rmSync(tmpDir, { recursive: true, force: true });
15874
16097
  } catch {
15875
16098
  }
15876
16099
  }
15877
16100
  }
15878
16101
  throw new Error(`Unsupported config extension "${ext}". Use .drip.config.ts or .drip.config.js.`);
15879
16102
  }
15880
- function isRecord2(value) {
15881
- return !!value && typeof value === "object" && !Array.isArray(value);
16103
+ function isRecord2(value2) {
16104
+ return !!value2 && typeof value2 === "object" && !Array.isArray(value2);
15882
16105
  }
15883
16106
  var pushCommand = new Command("push").description("Push experiment definitions from config file to the API (idempotent by slug)").option("-c, --config <path>", "Config file path").option("--dry-run", "Show what would be pushed without making changes").option("--no-asset-upload", "Keep inline and local image references unchanged").action(async function action23(opts) {
15884
16107
  const creds = requireCredentials();
@@ -15891,7 +16114,7 @@ var pushCommand = new Command("push").description("Push experiment definitions f
15891
16114
  );
15892
16115
  }
15893
16116
  const spinner = process.stderr.isTTY ? await createSpinner(`Loading config from ${source_default.cyan(configPath)}...`) : null;
15894
- const absoluteConfigPath = import_node_path7.default.resolve(configPath);
16117
+ const absoluteConfigPath = import_node_path8.default.resolve(configPath);
15895
16118
  let experiments;
15896
16119
  try {
15897
16120
  const mod = await importConfigModule(absoluteConfigPath);
@@ -15958,7 +16181,7 @@ var pushCommand = new Command("push").description("Push experiment definitions f
15958
16181
  return;
15959
16182
  }
15960
16183
  const assetRewriter = createAssetReferenceRewriter({
15961
- baseDir: import_node_path7.default.dirname(absoluteConfigPath),
16184
+ baseDir: import_node_path8.default.dirname(absoluteConfigPath),
15962
16185
  baseUrl: creds.baseUrl,
15963
16186
  enabled: opts.assetUpload !== false,
15964
16187
  upload: async (file) => {
@@ -15988,7 +16211,7 @@ var pushCommand = new Command("push").description("Push experiment definitions f
15988
16211
  let body5;
15989
16212
  try {
15990
16213
  body5 = toApiBody(
15991
- await rewriteExperimentAssets(exp, assetRewriter, import_node_path7.default.dirname(absoluteConfigPath))
16214
+ await rewriteExperimentAssets(exp, assetRewriter, import_node_path8.default.dirname(absoluteConfigPath))
15992
16215
  );
15993
16216
  } catch (error) {
15994
16217
  const message = error instanceof Error ? error.message : String(error);
@@ -16110,9 +16333,9 @@ var previewCommand = new Command("preview").description(
16110
16333
  );
16111
16334
  const expiresAt = new Date(data.expires_at);
16112
16335
  const remainingMs = expiresAt.getTime() - Date.now();
16113
- const value = remainingMs < 864e5 ? Math.max(1, Math.round(remainingMs / 36e5)) : Math.round(remainingMs / 864e5);
16336
+ const value2 = remainingMs < 864e5 ? Math.max(1, Math.round(remainingMs / 36e5)) : Math.round(remainingMs / 864e5);
16114
16337
  const unit = remainingMs < 864e5 ? "hour" : "day";
16115
- const duration = `${value} ${unit}${value === 1 ? "" : "s"}`;
16338
+ const duration = `${value2} ${unit}${value2 === 1 ? "" : "s"}`;
16116
16339
  console.log(
16117
16340
  `Valid until ${expiresAt.toISOString()} (${duration}). Re-run this command for a fresh link.`
16118
16341
  );
@@ -16191,8 +16414,8 @@ var previewCommand = new Command("preview").description(
16191
16414
  const qaFile = snapshot.data.files.find((file) => file.path === "qa.json");
16192
16415
  if (qaFile) {
16193
16416
  try {
16194
- const run3 = JSON.parse(qaFile.content)?.latestRun;
16195
- if (run3 && typeof run3.id === "string" && run3.id.trim()) qaRun = run3;
16417
+ const run4 = JSON.parse(qaFile.content)?.latestRun;
16418
+ if (run4 && typeof run4.id === "string" && run4.id.trim()) qaRun = run4;
16196
16419
  } catch {
16197
16420
  }
16198
16421
  }
@@ -16258,25 +16481,25 @@ var previewCommand = new Command("preview").description(
16258
16481
 
16259
16482
  // src/commands/harness.ts
16260
16483
  init_source();
16261
- var import_node_fs10 = __toESM(require("node:fs"));
16262
- var import_node_path8 = __toESM(require("node:path"));
16484
+ var import_node_fs11 = __toESM(require("node:fs"));
16485
+ var import_node_path9 = __toESM(require("node:path"));
16263
16486
  var import_node_child_process6 = require("node:child_process");
16264
- function slugify(value, fallback2 = "variation") {
16265
- const slug = value.normalize("NFKD").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
16487
+ function slugify(value2, fallback2 = "variation") {
16488
+ const slug = value2.normalize("NFKD").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
16266
16489
  return slug || fallback2;
16267
16490
  }
16268
16491
  function readJson(filePath) {
16269
- if (!import_node_fs10.default.existsSync(filePath)) return null;
16270
- return JSON.parse(import_node_fs10.default.readFileSync(filePath, "utf8"));
16492
+ if (!import_node_fs11.default.existsSync(filePath)) return null;
16493
+ return JSON.parse(import_node_fs11.default.readFileSync(filePath, "utf8"));
16271
16494
  }
16272
16495
  function resolveFolder(folder) {
16273
- return import_node_path8.default.resolve(process.cwd(), folder);
16496
+ return import_node_path9.default.resolve(process.cwd(), folder);
16274
16497
  }
16275
16498
  function experimentConfigPath(folder) {
16276
- return import_node_path8.default.join(folder, "experiment.config.json");
16499
+ return import_node_path9.default.join(folder, "experiment.config.json");
16277
16500
  }
16278
16501
  function apexConfigPath(folder) {
16279
- return import_node_path8.default.join(folder, "apex.harness.json");
16502
+ return import_node_path9.default.join(folder, "apex.harness.json");
16280
16503
  }
16281
16504
  function loadHarnessConfig(folder) {
16282
16505
  const experiment2 = readJson(experimentConfigPath(folder)) ?? {};
@@ -16285,8 +16508,8 @@ function loadHarnessConfig(folder) {
16285
16508
  const targetOrigin = experiment2.targetOrigin?.replace(/\/+$/, "") ?? "";
16286
16509
  const defaultPath = experiment2.defaultPath ?? "/";
16287
16510
  const targetUrl = targetOrigin ? new URL(defaultPath, targetOrigin).toString() : "";
16288
- const id = experiment2.id ?? import_node_path8.default.basename(import_node_path8.default.dirname(folder));
16289
- const variation = import_node_path8.default.basename(folder);
16511
+ const id = experiment2.id ?? import_node_path9.default.basename(import_node_path9.default.dirname(folder));
16512
+ const variation = import_node_path9.default.basename(folder);
16290
16513
  return {
16291
16514
  experiment: experiment2,
16292
16515
  apex: {
@@ -16320,37 +16543,37 @@ function runAbHarness(args, cwd) {
16320
16543
  function artifactPaths(folder, experiment2) {
16321
16544
  const variant = experiment2.variant;
16322
16545
  if (variant?.endsWith(".bundle.js")) {
16323
- const jsPath = import_node_path8.default.join(folder, variant.replace(/\.bundle\.js$/, ".js"));
16324
- const cssPath = import_node_path8.default.join(folder, variant.replace(/\.bundle\.js$/, ".css"));
16325
- return { jsPath, cssPath: import_node_fs10.default.existsSync(cssPath) ? cssPath : null };
16546
+ const jsPath = import_node_path9.default.join(folder, variant.replace(/\.bundle\.js$/, ".js"));
16547
+ const cssPath = import_node_path9.default.join(folder, variant.replace(/\.bundle\.js$/, ".css"));
16548
+ return { jsPath, cssPath: import_node_fs11.default.existsSync(cssPath) ? cssPath : null };
16326
16549
  }
16327
- const buildDir = import_node_path8.default.join(folder, "build");
16328
- const files = import_node_fs10.default.existsSync(buildDir) ? import_node_fs10.default.readdirSync(buildDir) : [];
16550
+ const buildDir = import_node_path9.default.join(folder, "build");
16551
+ const files = import_node_fs11.default.existsSync(buildDir) ? import_node_fs11.default.readdirSync(buildDir) : [];
16329
16552
  const js = files.find(
16330
16553
  (file) => file.endsWith(".js") && !file.endsWith(".bundle.js") && !file.endsWith(".min.js")
16331
16554
  );
16332
16555
  const css = files.find((file) => file.endsWith(".css") && !file.endsWith(".min.css"));
16333
16556
  if (!js) throw new Error("Could not find harness JS artifact in build/");
16334
16557
  return {
16335
- jsPath: import_node_path8.default.join(buildDir, js),
16336
- cssPath: css ? import_node_path8.default.join(buildDir, css) : null
16558
+ jsPath: import_node_path9.default.join(buildDir, js),
16559
+ cssPath: css ? import_node_path9.default.join(buildDir, css) : null
16337
16560
  };
16338
16561
  }
16339
16562
  async function uploadVersion(params) {
16340
16563
  const creds = requireCredentials();
16341
16564
  const { jsPath, cssPath } = artifactPaths(params.folder, params.experiment);
16342
- if (!import_node_fs10.default.existsSync(jsPath)) throw new Error(`Missing JS artifact: ${jsPath}`);
16565
+ if (!import_node_fs11.default.existsSync(jsPath)) throw new Error(`Missing JS artifact: ${jsPath}`);
16343
16566
  const form = new FormData();
16344
16567
  form.append(
16345
16568
  "js",
16346
- new Blob([import_node_fs10.default.readFileSync(jsPath)], { type: "application/javascript" }),
16347
- import_node_path8.default.basename(jsPath)
16569
+ new Blob([import_node_fs11.default.readFileSync(jsPath)], { type: "application/javascript" }),
16570
+ import_node_path9.default.basename(jsPath)
16348
16571
  );
16349
- if (cssPath && import_node_fs10.default.existsSync(cssPath) && import_node_fs10.default.statSync(cssPath).size > 0) {
16572
+ if (cssPath && import_node_fs11.default.existsSync(cssPath) && import_node_fs11.default.statSync(cssPath).size > 0) {
16350
16573
  form.append(
16351
16574
  "css",
16352
- new Blob([import_node_fs10.default.readFileSync(cssPath)], { type: "text/css" }),
16353
- import_node_path8.default.basename(cssPath)
16575
+ new Blob([import_node_fs11.default.readFileSync(cssPath)], { type: "text/css" }),
16576
+ import_node_path9.default.basename(cssPath)
16354
16577
  );
16355
16578
  }
16356
16579
  form.append(
@@ -16359,8 +16582,8 @@ async function uploadVersion(params) {
16359
16582
  ...params.apex,
16360
16583
  resetJs: cleanupResetJs(params.experiment),
16361
16584
  builtAt: (/* @__PURE__ */ new Date()).toISOString(),
16362
- jsPath: import_node_path8.default.relative(params.folder, jsPath),
16363
- cssPath: cssPath ? import_node_path8.default.relative(params.folder, cssPath) : null
16585
+ jsPath: import_node_path9.default.relative(params.folder, jsPath),
16586
+ cssPath: cssPath ? import_node_path9.default.relative(params.folder, cssPath) : null
16364
16587
  })
16365
16588
  );
16366
16589
  const res = await uploadHarnessVersion(creds, params.session.sessionId, form);
@@ -16402,11 +16625,11 @@ var harnessCommand = new Command("harness").description(
16402
16625
  harnessCommand.command("init").argument("<folder>", "AB Test Harness experiment folder").option("--force", "Overwrite existing apex.harness.json").action(function action24(folderArg, opts) {
16403
16626
  const folder = resolveFolder(folderArg);
16404
16627
  const targetPath = apexConfigPath(folder);
16405
- if (import_node_fs10.default.existsSync(targetPath) && !opts.force) {
16628
+ if (import_node_fs11.default.existsSync(targetPath) && !opts.force) {
16406
16629
  fail(this, `${targetPath} already exists. Use --force to overwrite.`, EXIT_CODES.conflict);
16407
16630
  }
16408
16631
  const { apex } = loadHarnessConfig(folder);
16409
- import_node_fs10.default.writeFileSync(targetPath, `${JSON.stringify(apex, null, 2)}
16632
+ import_node_fs11.default.writeFileSync(targetPath, `${JSON.stringify(apex, null, 2)}
16410
16633
  `, "utf8");
16411
16634
  output(
16412
16635
  this,
@@ -16472,7 +16695,7 @@ harnessCommand.command("dev").argument("<folder>", "AB Test Harness experiment f
16472
16695
  }
16473
16696
  };
16474
16697
  let debounce = null;
16475
- const watcher = import_node_fs10.default.watch(folder, { recursive: true }, (_event, filename) => {
16698
+ const watcher = import_node_fs11.default.watch(folder, { recursive: true }, (_event, filename) => {
16476
16699
  const name = String(filename ?? "");
16477
16700
  if (!name || name.startsWith("build/") || name.includes("/build/")) return;
16478
16701
  if (debounce) clearTimeout(debounce);
@@ -16515,8 +16738,8 @@ harnessCommand.command("publish").argument("<folder>", "AB Test Harness experime
16515
16738
  // src/commands/operator.ts
16516
16739
  init_source();
16517
16740
  var import_node_crypto7 = __toESM(require("node:crypto"));
16518
- var import_node_fs11 = __toESM(require("node:fs"));
16519
- var import_node_path9 = __toESM(require("node:path"));
16741
+ var import_node_fs12 = __toESM(require("node:fs"));
16742
+ var import_node_path10 = __toESM(require("node:path"));
16520
16743
  var CANONICAL_FILE_RE = /^(src\/(?:index\.js|index\.scss|info\.js|mutations\.json)|experiment\.config\.json|metrics\.json|targeting\.json|dev-doc\.md|brand\.md|goals\/[a-zA-Z0-9_.-]+\.json|segments\/[a-zA-Z0-9_.-]+\.json|network\/[a-zA-Z0-9_.-]+\.recipe\.json)$/;
16521
16744
  function workspaceIssueFile(field, evidence) {
16522
16745
  if (field === "custom_js" || field === "reset_js") return "src/index.js";
@@ -16530,9 +16753,9 @@ function workspaceIssueFile(field, evidence) {
16530
16753
  if (field === "anti_flicker_selectors") return "experiment.config.json";
16531
16754
  return null;
16532
16755
  }
16533
- function formatWorkspaceBlockingIssues(value) {
16534
- if (!value || typeof value !== "object") return null;
16535
- const issues = value.blockingIssues;
16756
+ function formatWorkspaceBlockingIssues(value2) {
16757
+ if (!value2 || typeof value2 !== "object") return null;
16758
+ const issues = value2.blockingIssues;
16536
16759
  if (!Array.isArray(issues) || issues.length === 0) return null;
16537
16760
  return issues.map((rawIssue, index) => {
16538
16761
  const issue = rawIssue && typeof rawIssue === "object" ? rawIssue : {};
@@ -16564,39 +16787,39 @@ function formatHarnessRefusal(message, details) {
16564
16787
  return issues ? `${message}
16565
16788
  ${issues}` : message;
16566
16789
  }
16567
- function sha256Text2(value) {
16568
- return import_node_crypto7.default.createHash("sha256").update(value).digest("hex");
16790
+ function sha256Text2(value2) {
16791
+ return import_node_crypto7.default.createHash("sha256").update(value2).digest("hex");
16569
16792
  }
16570
- function byteLength(value) {
16571
- return Buffer.byteLength(value, "utf8");
16793
+ function byteLength(value2) {
16794
+ return Buffer.byteLength(value2, "utf8");
16572
16795
  }
16573
- function slugify2(value, fallback2 = "operator") {
16574
- const slug = value.normalize("NFKD").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
16796
+ function slugify2(value2, fallback2 = "operator") {
16797
+ const slug = value2.normalize("NFKD").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
16575
16798
  return slug || fallback2;
16576
16799
  }
16577
16800
  function folderPath2(folder) {
16578
- return import_node_path9.default.resolve(process.cwd(), folder);
16801
+ return import_node_path10.default.resolve(process.cwd(), folder);
16579
16802
  }
16580
16803
  function apexDir(folder) {
16581
- return import_node_path9.default.join(folder, ".apex");
16804
+ return import_node_path10.default.join(folder, ".apex");
16582
16805
  }
16583
16806
  function sessionPath(folder) {
16584
- return import_node_path9.default.join(apexDir(folder), "session.json");
16807
+ return import_node_path10.default.join(apexDir(folder), "session.json");
16585
16808
  }
16586
16809
  function readJsonFile(filePath) {
16587
- if (!import_node_fs11.default.existsSync(filePath)) return null;
16588
- return JSON.parse(import_node_fs11.default.readFileSync(filePath, "utf8"));
16810
+ if (!import_node_fs12.default.existsSync(filePath)) return null;
16811
+ return JSON.parse(import_node_fs12.default.readFileSync(filePath, "utf8"));
16589
16812
  }
16590
- function writeJsonFile(filePath, value) {
16591
- import_node_fs11.default.mkdirSync(import_node_path9.default.dirname(filePath), { recursive: true });
16592
- import_node_fs11.default.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}
16813
+ function writeJsonFile(filePath, value2) {
16814
+ import_node_fs12.default.mkdirSync(import_node_path10.default.dirname(filePath), { recursive: true });
16815
+ import_node_fs12.default.writeFileSync(filePath, `${JSON.stringify(value2, null, 2)}
16593
16816
  `, "utf8");
16594
16817
  }
16595
16818
  function readSession(folder) {
16596
16819
  const session = readJsonFile(sessionPath(folder));
16597
16820
  if (!session) {
16598
- const filesystemMarker = import_node_path9.default.join(apexDir(folder), "experiment-filesystem.json");
16599
- if (import_node_fs11.default.existsSync(filesystemMarker)) {
16821
+ const filesystemMarker = import_node_path10.default.join(apexDir(folder), "experiment-filesystem.json");
16822
+ if (import_node_fs12.default.existsSync(filesystemMarker)) {
16600
16823
  throw new CliError(
16601
16824
  "This folder is an experiment filesystem (apex experiments \u2026), not an operator workspace \u2014 run `apex experiments plan` here, or `apex workspace checkout` into a different folder.",
16602
16825
  EXIT_CODES.general,
@@ -16626,9 +16849,9 @@ function readSession(folder) {
16626
16849
  return session;
16627
16850
  }
16628
16851
  function writeSession(folder, session) {
16629
- import_node_fs11.default.mkdirSync(apexDir(folder), { recursive: true });
16630
- import_node_fs11.default.writeFileSync(
16631
- import_node_path9.default.join(apexDir(folder), ".gitignore"),
16852
+ import_node_fs12.default.mkdirSync(apexDir(folder), { recursive: true });
16853
+ import_node_fs12.default.writeFileSync(
16854
+ import_node_path10.default.join(apexDir(folder), ".gitignore"),
16632
16855
  "session.json\nharness-session.json\n",
16633
16856
  "utf8"
16634
16857
  );
@@ -16652,15 +16875,15 @@ function listLocalWorkspaceFiles(folder) {
16652
16875
  "brand.md"
16653
16876
  ];
16654
16877
  function visit2(dir) {
16655
- if (!import_node_fs11.default.existsSync(dir)) return;
16656
- for (const entry of import_node_fs11.default.readdirSync(dir, { withFileTypes: true })) {
16657
- const absPath = import_node_path9.default.join(dir, entry.name);
16878
+ if (!import_node_fs12.default.existsSync(dir)) return;
16879
+ for (const entry of import_node_fs12.default.readdirSync(dir, { withFileTypes: true })) {
16880
+ const absPath = import_node_path10.default.join(dir, entry.name);
16658
16881
  if (entry.isDirectory()) {
16659
16882
  visit2(absPath);
16660
16883
  continue;
16661
16884
  }
16662
- const relativePath = validateCanonicalPath(import_node_path9.default.relative(folder, absPath));
16663
- const content = import_node_fs11.default.readFileSync(absPath, "utf8");
16885
+ const relativePath = validateCanonicalPath(import_node_path10.default.relative(folder, absPath));
16886
+ const content = import_node_fs12.default.readFileSync(absPath, "utf8");
16664
16887
  files.push({
16665
16888
  path: relativePath,
16666
16889
  absPath,
@@ -16670,11 +16893,11 @@ function listLocalWorkspaceFiles(folder) {
16670
16893
  });
16671
16894
  }
16672
16895
  }
16673
- for (const root of roots) visit2(import_node_path9.default.join(folder, root));
16896
+ for (const root of roots) visit2(import_node_path10.default.join(folder, root));
16674
16897
  for (const file of topLevel) {
16675
- const absPath = import_node_path9.default.join(folder, file);
16676
- if (!import_node_fs11.default.existsSync(absPath)) continue;
16677
- const content = import_node_fs11.default.readFileSync(absPath, "utf8");
16898
+ const absPath = import_node_path10.default.join(folder, file);
16899
+ if (!import_node_fs12.default.existsSync(absPath)) continue;
16900
+ const content = import_node_fs12.default.readFileSync(absPath, "utf8");
16678
16901
  files.push({
16679
16902
  path: file,
16680
16903
  absPath,
@@ -16698,7 +16921,7 @@ function validateJsonFiles(files) {
16698
16921
  }
16699
16922
  }
16700
16923
  function readExperimentConfig(folder) {
16701
- return readJsonFile(import_node_path9.default.join(folder, "experiment.config.json")) ?? {};
16924
+ return readJsonFile(import_node_path10.default.join(folder, "experiment.config.json")) ?? {};
16702
16925
  }
16703
16926
  function resolveVariation(exp, variationArg) {
16704
16927
  const variations = exp.variations ?? [];
@@ -16715,9 +16938,9 @@ function resolveVariation(exp, variationArg) {
16715
16938
  function writeWorkspaceFiles(folder, workspace) {
16716
16939
  for (const file of workspace.files) {
16717
16940
  const relativePath = validateCanonicalPath(file.path);
16718
- const absPath = import_node_path9.default.join(folder, relativePath);
16719
- import_node_fs11.default.mkdirSync(import_node_path9.default.dirname(absPath), { recursive: true });
16720
- import_node_fs11.default.writeFileSync(absPath, file.content, "utf8");
16941
+ const absPath = import_node_path10.default.join(folder, relativePath);
16942
+ import_node_fs12.default.mkdirSync(import_node_path10.default.dirname(absPath), { recursive: true });
16943
+ import_node_fs12.default.writeFileSync(absPath, file.content, "utf8");
16721
16944
  }
16722
16945
  }
16723
16946
  function sessionFromWorkspace(input) {
@@ -16785,10 +17008,10 @@ async function uploadCurrentArtifactVersion(folder, sessionId) {
16785
17008
  form.append(
16786
17009
  "js",
16787
17010
  new Blob([js.content], { type: "application/javascript" }),
16788
- import_node_path9.default.basename(js.path)
17011
+ import_node_path10.default.basename(js.path)
16789
17012
  );
16790
17013
  if (css && css.content.trim()) {
16791
- form.append("css", new Blob([css.content], { type: "text/css" }), import_node_path9.default.basename(css.path));
17014
+ form.append("css", new Blob([css.content], { type: "text/css" }), import_node_path10.default.basename(css.path));
16792
17015
  }
16793
17016
  form.append("manifest", JSON.stringify(manifest));
16794
17017
  const res = await uploadHarnessVersion(creds, sessionId, form);
@@ -16915,7 +17138,7 @@ operatorCommand.command("checkout").argument("<experiment-id>", "Apex experiment
16915
17138
  classifyStatus(workspace.status),
16916
17139
  workspace.errorDetails
16917
17140
  );
16918
- import_node_fs11.default.mkdirSync(folder, { recursive: true });
17141
+ import_node_fs12.default.mkdirSync(folder, { recursive: true });
16919
17142
  writeWorkspaceFiles(folder, workspace.data);
16920
17143
  writeSession(
16921
17144
  folder,
@@ -16982,8 +17205,8 @@ operatorCommand.command("dev").argument("[folder]", "Operator workspace folder",
16982
17205
  const session = readSession(folder);
16983
17206
  const harnessSession = await createExactHarnessSession(folder, session);
16984
17207
  const version = await uploadCurrentArtifactVersion(folder, harnessSession.sessionId);
16985
- import_node_fs11.default.mkdirSync(apexDir(folder), { recursive: true });
16986
- writeJsonFile(import_node_path9.default.join(apexDir(folder), "harness-session.json"), {
17208
+ import_node_fs12.default.mkdirSync(apexDir(folder), { recursive: true });
17209
+ writeJsonFile(import_node_path10.default.join(apexDir(folder), "harness-session.json"), {
16987
17210
  sessionId: harnessSession.sessionId,
16988
17211
  experimentId: harnessSession.experimentId,
16989
17212
  variationId: harnessSession.variationId,
@@ -17038,7 +17261,7 @@ operatorCommand.command("dev").argument("[folder]", "Operator workspace folder",
17038
17261
  }
17039
17262
  };
17040
17263
  let timer = null;
17041
- const watcher = import_node_fs11.default.watch(folder, { recursive: true }, (_event, filename) => {
17264
+ const watcher = import_node_fs12.default.watch(folder, { recursive: true }, (_event, filename) => {
17042
17265
  const name = String(filename ?? "");
17043
17266
  if (!name || name.startsWith(".apex/") || name.includes("/.apex/")) return;
17044
17267
  if (timer) clearTimeout(timer);
@@ -17073,17 +17296,17 @@ operatorCommand.command("publish").argument("[folder]", "Operator workspace fold
17073
17296
 
17074
17297
  // src/commands/roadmap.ts
17075
17298
  init_source();
17076
- var import_node_fs12 = __toESM(require("node:fs"));
17077
- var import_node_path10 = __toESM(require("node:path"));
17299
+ var import_node_fs13 = __toESM(require("node:fs"));
17300
+ var import_node_path11 = __toESM(require("node:path"));
17078
17301
  var LEGACY_OUTPUT_REMOVAL_VERSION = "0.7.0";
17079
- function truncate(value, max) {
17080
- const text2 = typeof value === "string" ? value : value == null ? "" : String(value);
17302
+ function truncate(value2, max) {
17303
+ const text2 = typeof value2 === "string" ? value2 : value2 == null ? "" : String(value2);
17081
17304
  if (text2.length <= max) return text2;
17082
17305
  return `${text2.slice(0, Math.max(0, max - 3))}...`;
17083
17306
  }
17084
- function score(value) {
17085
- if (typeof value !== "number" || !Number.isFinite(value)) return "-";
17086
- return Number.isInteger(value) ? String(value) : value.toFixed(1);
17307
+ function score(value2) {
17308
+ if (typeof value2 !== "number" || !Number.isFinite(value2)) return "-";
17309
+ return Number.isInteger(value2) ? String(value2) : value2.toFixed(1);
17087
17310
  }
17088
17311
  function experimentState(item) {
17089
17312
  const linked = item.linked_experiments ?? [];
@@ -17184,9 +17407,9 @@ var handoff = new Command("handoff").description(
17184
17407
  `;
17185
17408
  const outputData = opts.instructions ? { roadmapItemId: id, instructions: String(payload.instructions ?? "") } : payload;
17186
17409
  if (opts.out || opts.output) {
17187
- const target = import_node_path10.default.resolve(process.cwd(), opts.out ?? opts.output);
17188
- import_node_fs12.default.mkdirSync(import_node_path10.default.dirname(target), { recursive: true });
17189
- import_node_fs12.default.writeFileSync(target, rendered, "utf8");
17410
+ const target = import_node_path11.default.resolve(process.cwd(), opts.out ?? opts.output);
17411
+ import_node_fs13.default.mkdirSync(import_node_path11.default.dirname(target), { recursive: true });
17412
+ import_node_fs13.default.writeFileSync(target, rendered, "utf8");
17190
17413
  output(this, { path: target, roadmapItemId: id }, () => printSuccess(`Wrote ${target}`));
17191
17414
  return;
17192
17415
  }
@@ -17200,13 +17423,13 @@ roadmapCommand.addCommand(handoff);
17200
17423
 
17201
17424
  // src/commands/tracking.ts
17202
17425
  init_source();
17203
- var import_node_fs13 = __toESM(require("node:fs"));
17204
- var import_node_path11 = __toESM(require("node:path"));
17426
+ var import_node_fs14 = __toESM(require("node:fs"));
17427
+ var import_node_path12 = __toESM(require("node:path"));
17205
17428
  function normalizeUrl(input) {
17206
- const value = input.trim();
17207
- if (!value) throw new Error("URL cannot be empty");
17429
+ const value2 = input.trim();
17430
+ if (!value2) throw new Error("URL cannot be empty");
17208
17431
  try {
17209
- return new URL(value.includes("://") ? value : `https://${value}`);
17432
+ return new URL(value2.includes("://") ? value2 : `https://${value2}`);
17210
17433
  } catch {
17211
17434
  throw new Error(`Invalid URL: ${input}`);
17212
17435
  }
@@ -17248,14 +17471,14 @@ function commonCookieDomain(hostnames) {
17248
17471
  }
17249
17472
  var DEFAULT_MANIFEST_PATH = ".apex/tracking-manifest.json";
17250
17473
  function readManifest(filePath) {
17251
- if (!import_node_fs13.default.existsSync(filePath)) throw new Error(`Manifest not found: ${filePath}`);
17252
- const parsed = JSON.parse(import_node_fs13.default.readFileSync(filePath, "utf8"));
17474
+ if (!import_node_fs14.default.existsSync(filePath)) throw new Error(`Manifest not found: ${filePath}`);
17475
+ const parsed = JSON.parse(import_node_fs14.default.readFileSync(filePath, "utf8"));
17253
17476
  if (parsed.schemaVersion !== 1) throw new Error("Unsupported tracking manifest schema");
17254
17477
  return parsed;
17255
17478
  }
17256
17479
  function writeManifest(filePath, manifest) {
17257
- import_node_fs13.default.mkdirSync(import_node_path11.default.dirname(filePath), { recursive: true });
17258
- import_node_fs13.default.writeFileSync(filePath, `${JSON.stringify(manifest, null, 2)}
17480
+ import_node_fs14.default.mkdirSync(import_node_path12.default.dirname(filePath), { recursive: true });
17481
+ import_node_fs14.default.writeFileSync(filePath, `${JSON.stringify(manifest, null, 2)}
17259
17482
  `, "utf8");
17260
17483
  }
17261
17484
  function buildSnippet(shopId, endpoint) {
@@ -17322,7 +17545,7 @@ function buildManifest(urlArgs, opts) {
17322
17545
  };
17323
17546
  }
17324
17547
  function manifestPath(input) {
17325
- return import_node_path11.default.resolve(process.cwd(), input ?? DEFAULT_MANIFEST_PATH);
17548
+ return import_node_path12.default.resolve(process.cwd(), input ?? DEFAULT_MANIFEST_PATH);
17326
17549
  }
17327
17550
  function printManifestPlan(manifest) {
17328
17551
  console.log(source_default.bold("Apex tracking ingestion plan"));
@@ -17472,7 +17695,7 @@ trackingCommand.command("latency").description("Measure forced-preview versus na
17472
17695
  ["natural", summary.natural],
17473
17696
  ...summary.qa_session ? [["qa_session", summary.qa_session]] : []
17474
17697
  ];
17475
- const ms = (value) => value === null ? "-" : String(Math.round(value));
17698
+ const ms = (value2) => value2 === null ? "-" : String(Math.round(value2));
17476
17699
  printTable(
17477
17700
  [
17478
17701
  "Bucket",
@@ -17508,7 +17731,7 @@ trackingCommand.command("latency").description("Measure forced-preview versus na
17508
17731
  });
17509
17732
 
17510
17733
  // src/commands/events.ts
17511
- var import_node_fs14 = __toESM(require("node:fs"));
17734
+ var import_node_fs15 = __toESM(require("node:fs"));
17512
17735
  var maxWindowMs = 31 * 864e5;
17513
17736
  function correctedWindowStep(opts, nowMs) {
17514
17737
  const fromMs = Date.parse(opts.from);
@@ -17519,7 +17742,7 @@ function correctedWindowStep(opts, nowMs) {
17519
17742
  why: "No valid export window exists from this start; --to must be after --from and at or before now."
17520
17743
  };
17521
17744
  }
17522
- const quote = (value) => `'${value.replace(/'/g, "'\\''")}'`;
17745
+ const quote = (value2) => `'${value2.replace(/'/g, "'\\''")}'`;
17523
17746
  const args = [
17524
17747
  "apex events export",
17525
17748
  `--from ${quote(opts.from)}`,
@@ -17611,7 +17834,7 @@ eventsCommand.command("export").description(
17611
17834
  if (opts.jsonSummary && !opts.out) {
17612
17835
  fail(command, "--json-summary requires --out for the event rows", EXIT_CODES.validation);
17613
17836
  }
17614
- const output2 = opts.out ? import_node_fs14.default.createWriteStream(opts.out, { flags: "wx" }) : null;
17837
+ const output2 = opts.out ? import_node_fs15.default.createWriteStream(opts.out, { flags: "wx" }) : null;
17615
17838
  let outputError = null;
17616
17839
  output2?.on("error", (error) => {
17617
17840
  outputError = error;
@@ -17659,7 +17882,7 @@ eventsCommand.command("export").description(
17659
17882
  from: opts.from,
17660
17883
  to: opts.to,
17661
17884
  experiment: opts.experiment,
17662
- eventTypes: opts.eventType?.split(",").map((value) => value.trim()).filter(Boolean),
17885
+ eventTypes: opts.eventType?.split(",").map((value2) => value2.trim()).filter(Boolean),
17663
17886
  qa: opts.qa,
17664
17887
  limit,
17665
17888
  cursor
@@ -17750,7 +17973,7 @@ eventsCommand.command("export").description(
17750
17973
  } catch (error) {
17751
17974
  if (output2 && opts.out) {
17752
17975
  output2.destroy();
17753
- import_node_fs14.default.rmSync(opts.out, { force: true });
17976
+ import_node_fs15.default.rmSync(opts.out, { force: true });
17754
17977
  const suffix = `The partial file ${opts.out} was removed.`;
17755
17978
  if (error instanceof CliError)
17756
17979
  throw new CliError(
@@ -17771,8 +17994,8 @@ eventsCommand.command("export").description(
17771
17994
 
17772
17995
  // src/commands/goals.ts
17773
17996
  init_source();
17774
- var import_node_fs15 = __toESM(require("node:fs"));
17775
- var import_node_path12 = __toESM(require("node:path"));
17997
+ var import_node_fs16 = __toESM(require("node:fs"));
17998
+ var import_node_path13 = __toESM(require("node:path"));
17776
17999
 
17777
18000
  // ../sdk/src/safe-regex.ts
17778
18001
  var MAX_PATTERN_LENGTH = 1024;
@@ -17949,10 +18172,10 @@ function printSuggestions(data) {
17949
18172
  for (const trigger of data.triggers) console.log(`- ${trigger.page}: ${trigger.description}`);
17950
18173
  }
17951
18174
  }
17952
- function parseCapture(command, value) {
17953
- if (!value) return void 0;
17954
- const source = value.startsWith("@") ? value.slice(1) : value;
17955
- const text2 = value.startsWith("@") || import_node_fs15.default.existsSync(source) ? import_node_fs15.default.readFileSync(import_node_path12.default.resolve(process.cwd(), source), "utf8") : value;
18175
+ function parseCapture(command, value2) {
18176
+ if (!value2) return void 0;
18177
+ const source = value2.startsWith("@") ? value2.slice(1) : value2;
18178
+ const text2 = value2.startsWith("@") || import_node_fs16.default.existsSync(source) ? import_node_fs16.default.readFileSync(import_node_path13.default.resolve(process.cwd(), source), "utf8") : value2;
17956
18179
  try {
17957
18180
  return JSON.parse(text2);
17958
18181
  } catch (error) {
@@ -17961,10 +18184,10 @@ function parseCapture(command, value) {
17961
18184
  }
17962
18185
  }
17963
18186
  function cleanBody(input) {
17964
- return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0));
18187
+ return Object.fromEntries(Object.entries(input).filter(([, value2]) => value2 !== void 0));
17965
18188
  }
17966
- async function resolveGoalPageId(command, creds, value) {
17967
- if (UUID_V1_TO_V8.test(value)) return value;
18189
+ async function resolveGoalPageId(command, creds, value2) {
18190
+ if (UUID_V1_TO_V8.test(value2)) return value2;
17968
18191
  let cursor;
17969
18192
  for (let page = 0; page < MAX_PAGE_LOOKUP_PAGES; page += 1) {
17970
18193
  const response = await requestTargetingResource(
@@ -18002,7 +18225,7 @@ async function resolveGoalPageId(command, creds, value) {
18002
18225
  }
18003
18226
  if (!("data" in response.data) || !Array.isArray(response.data.data)) break;
18004
18227
  const pageData = response.data;
18005
- const match2 = pageData.data.find((item) => item.key === value);
18228
+ const match2 = pageData.data.find((item) => item.key === value2);
18006
18229
  if (match2) return match2.id;
18007
18230
  const next = pageData.pagination?.next_cursor ?? null;
18008
18231
  if (!pageData.pagination?.has_more || !next || next === cursor) break;
@@ -18010,7 +18233,7 @@ async function resolveGoalPageId(command, creds, value) {
18010
18233
  }
18011
18234
  fail(
18012
18235
  command,
18013
- `No active page with key ${value} in this shop; list pages with apex pages list`,
18236
+ `No active page with key ${value2} in this shop; list pages with apex pages list`,
18014
18237
  EXIT_CODES.validation,
18015
18238
  { code: "page_not_found", next_steps: PAGE_NEXT_STEPS }
18016
18239
  );
@@ -18235,8 +18458,8 @@ var suggest = new Command("suggest").description("Suggest goals and funnels from
18235
18458
  "Confirmation required; rerun with --yes to create suggested goals.",
18236
18459
  EXIT_CODES.confirmationRequired
18237
18460
  );
18238
- const readline3 = await import("node:readline");
18239
- const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
18461
+ const readline4 = await import("node:readline");
18462
+ const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
18240
18463
  const answer = await new Promise(
18241
18464
  (resolve2) => rl.question(source_default.yellow("Create this goal? [y/N] "), resolve2)
18242
18465
  );
@@ -18275,12 +18498,12 @@ Examples:
18275
18498
 
18276
18499
  // src/commands/funnels.ts
18277
18500
  init_source();
18278
- var import_node_fs16 = __toESM(require("node:fs"));
18279
- var import_node_path13 = __toESM(require("node:path"));
18501
+ var import_node_fs17 = __toESM(require("node:fs"));
18502
+ var import_node_path14 = __toESM(require("node:path"));
18280
18503
  function readSteps(command, file) {
18281
18504
  let parsed;
18282
18505
  try {
18283
- parsed = JSON.parse(import_node_fs16.default.readFileSync(import_node_path13.default.resolve(process.cwd(), file), "utf8"));
18506
+ parsed = JSON.parse(import_node_fs17.default.readFileSync(import_node_path14.default.resolve(process.cwd(), file), "utf8"));
18284
18507
  } catch (error) {
18285
18508
  fail(
18286
18509
  command,
@@ -18410,8 +18633,8 @@ function printEnvironments(items) {
18410
18633
  [24, 32, 8, 64]
18411
18634
  );
18412
18635
  }
18413
- function normalizeEnvironmentDomain(value) {
18414
- const candidate = value.trim().toLowerCase();
18636
+ function normalizeEnvironmentDomain(value2) {
18637
+ const candidate = value2.trim().toLowerCase();
18415
18638
  if (!candidate) return "";
18416
18639
  try {
18417
18640
  const parsed = new URL(
@@ -18470,11 +18693,11 @@ var setDomain = new Command("set-domain").description("Map a domain to a runtime
18470
18693
  ...item,
18471
18694
  domains: item.key === opts.environment ? [
18472
18695
  ...item.domains.filter(
18473
- (value) => normalizeEnvironmentDomain(value) !== normalizedDomain
18696
+ (value2) => normalizeEnvironmentDomain(value2) !== normalizedDomain
18474
18697
  ),
18475
18698
  normalizedDomain
18476
18699
  ] : item.domains.filter(
18477
- (value) => normalizeEnvironmentDomain(value) !== normalizedDomain
18700
+ (value2) => normalizeEnvironmentDomain(value2) !== normalizedDomain
18478
18701
  )
18479
18702
  }));
18480
18703
  result = await updateEnvironments(requireCredentials(), {
@@ -18505,7 +18728,7 @@ var removeDomain = new Command("remove-domain").description("Remove a domain map
18505
18728
  const items = current.environments.items.map((item) => ({
18506
18729
  ...item,
18507
18730
  domains: item.domains.filter(
18508
- (value) => normalizeEnvironmentDomain(value) !== normalizedDomain
18731
+ (value2) => normalizeEnvironmentDomain(value2) !== normalizedDomain
18509
18732
  )
18510
18733
  }));
18511
18734
  result = await updateEnvironments(requireCredentials(), {
@@ -18594,8 +18817,8 @@ var off = new Command("off").description("Disable consent gating").action(async
18594
18817
  var consentCommand = new Command("consent").description("Manage consent gating").addCommand(get2).addCommand(set).addCommand(off);
18595
18818
 
18596
18819
  // src/commands/project-code.ts
18597
- var import_node_fs17 = require("node:fs");
18598
- var import_node_path14 = require("node:path");
18820
+ var import_node_fs18 = require("node:fs");
18821
+ var import_node_path15 = require("node:path");
18599
18822
 
18600
18823
  // src/commands/runtime-settings-shop.ts
18601
18824
  var uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
@@ -18640,17 +18863,17 @@ var fields = ["enabled", "css", "helperJs", "js"];
18640
18863
  function readPatch(command, file) {
18641
18864
  let input;
18642
18865
  try {
18643
- input = JSON.parse((0, import_node_fs17.readFileSync)(file, "utf8"));
18866
+ input = JSON.parse((0, import_node_fs18.readFileSync)(file, "utf8"));
18644
18867
  } catch (error) {
18645
18868
  fail(command, `Cannot read project code JSON: ${String(error)}`, EXIT_CODES.validation);
18646
18869
  }
18647
18870
  if (!input || typeof input !== "object" || Array.isArray(input) || Object.keys(input).length === 0) {
18648
18871
  fail(command, "Project code must be a nonempty partial object", EXIT_CODES.validation);
18649
18872
  }
18650
- for (const [key, value] of Object.entries(input)) {
18873
+ for (const [key, value2] of Object.entries(input)) {
18651
18874
  if (!fields.includes(key))
18652
18875
  fail(command, `Unknown project code field: ${key}`, EXIT_CODES.validation);
18653
- if (key === "enabled" ? typeof value !== "boolean" : value !== null && (typeof value !== "string" || value.length > 2e4)) {
18876
+ if (key === "enabled" ? typeof value2 !== "boolean" : value2 !== null && (typeof value2 !== "string" || value2.length > 2e4)) {
18654
18877
  fail(
18655
18878
  command,
18656
18879
  `${key} must be ${key === "enabled" ? "a boolean" : "null or a string of at most 20,000 characters"}`,
@@ -18743,9 +18966,9 @@ for (const mode of ["diff", "set"]) {
18743
18966
  );
18744
18967
  return;
18745
18968
  }
18746
- const backupPath = (0, import_node_path14.resolve)(options.backup);
18969
+ const backupPath = (0, import_node_path15.resolve)(options.backup);
18747
18970
  try {
18748
- (0, import_node_fs17.writeFileSync)(
18971
+ (0, import_node_fs18.writeFileSync)(
18749
18972
  backupPath,
18750
18973
  `${JSON.stringify({ ...identity2, ...current, capturedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2)}
18751
18974
  `,
@@ -18804,17 +19027,17 @@ for (const mode of ["diff", "set"]) {
18804
19027
  }
18805
19028
 
18806
19029
  // src/commands/triggers.ts
18807
- var import_node_fs18 = __toESM(require("node:fs"));
18808
- var import_node_path15 = __toESM(require("node:path"));
19030
+ var import_node_fs19 = __toESM(require("node:fs"));
19031
+ var import_node_path16 = __toESM(require("node:path"));
18809
19032
 
18810
19033
  // src/trigger-proposal.ts
18811
- function runtimePath(path26) {
18812
- return path26.replaceAll("[]", ".0");
19034
+ function runtimePath(path27) {
19035
+ return path27.replaceAll("[]", ".0");
18813
19036
  }
18814
- function fieldsFrom(value, prefix = "", descriptorList = false) {
18815
- if (!value || typeof value !== "object") return [];
18816
- if (Array.isArray(value)) {
18817
- return value.flatMap(
19037
+ function fieldsFrom(value2, prefix = "", descriptorList = false) {
19038
+ if (!value2 || typeof value2 !== "object") return [];
19039
+ if (Array.isArray(value2)) {
19040
+ return value2.flatMap(
18818
19041
  (item, index) => fieldsFrom(
18819
19042
  item,
18820
19043
  descriptorList ? prefix : prefix ? `${prefix}.${index}` : String(index),
@@ -18822,7 +19045,7 @@ function fieldsFrom(value, prefix = "", descriptorList = false) {
18822
19045
  )
18823
19046
  );
18824
19047
  }
18825
- const record4 = value;
19048
+ const record4 = value2;
18826
19049
  const explicitPath = typeof record4.path === "string" ? record4.path : void 0;
18827
19050
  if (descriptorList && explicitPath) {
18828
19051
  const rawValues = record4.values ?? record4.samples ?? record4.examples ?? record4.example;
@@ -18849,7 +19072,7 @@ function fieldsFrom(value, prefix = "", descriptorList = false) {
18849
19072
  return fieldsFrom(child, next);
18850
19073
  });
18851
19074
  }
18852
- function isDescriptorArray(value) {
19075
+ function isDescriptorArray(value2) {
18853
19076
  const descriptorKeys = /* @__PURE__ */ new Set([
18854
19077
  "path",
18855
19078
  "values",
@@ -18864,7 +19087,7 @@ function isDescriptorArray(value) {
18864
19087
  "seen",
18865
19088
  "type_collision"
18866
19089
  ]);
18867
- return Array.isArray(value) && value.length > 0 && value.every((item) => {
19090
+ return Array.isArray(value2) && value2.length > 0 && value2.every((item) => {
18868
19091
  if (!item || typeof item !== "object" || Array.isArray(item)) return false;
18869
19092
  const record4 = item;
18870
19093
  return typeof record4.path === "string" && record4.path.length > 0 && Object.keys(record4).every((key) => descriptorKeys.has(key));
@@ -18887,15 +19110,15 @@ function candidatesFrom(report) {
18887
19110
  }
18888
19111
  return [root];
18889
19112
  }
18890
- function score2(path26, patterns) {
19113
+ function score2(path27, patterns) {
18891
19114
  return patterns.reduce(
18892
- (total, pattern, index) => total + (pattern.test(path26) ? patterns.length - index : 0),
19115
+ (total, pattern, index) => total + (pattern.test(path27) ? patterns.length - index : 0),
18893
19116
  0
18894
19117
  );
18895
19118
  }
18896
19119
  function best(fields3, patterns, numeric2 = false) {
18897
19120
  const ranked = fields3.filter(
18898
- (field) => !numeric2 || field.numericType === true || field.values.some((value) => typeof value === "number") || field.magnitude !== void 0
19121
+ (field) => !numeric2 || field.numericType === true || field.values.some((value2) => typeof value2 === "number") || field.magnitude !== void 0
18899
19122
  ).map((field) => ({ field, score: score2(field.path.toLowerCase(), patterns) })).filter((item) => item.score > 0).sort((a, b) => b.score - a.score || (b.field.magnitude ?? 0) - (a.field.magnitude ?? 0));
18900
19123
  if (!ranked.length) return [];
18901
19124
  const top = ranked[0].score;
@@ -19020,55 +19243,55 @@ var pathPattern = new RegExp(runtime_settings_trigger_constants_default.dotPathP
19020
19243
  var signalPathPattern = new RegExp(runtime_settings_trigger_constants_default.signalPathPattern);
19021
19244
  var valueTypes = new Set(runtime_settings_trigger_constants_default.valueTypes);
19022
19245
  var whenOps = new Set(runtime_settings_trigger_constants_default.whenOps);
19023
- function strictObject(value, location, keys) {
19024
- if (!value || typeof value !== "object" || Array.isArray(value))
19246
+ function strictObject(value2, location, keys) {
19247
+ if (!value2 || typeof value2 !== "object" || Array.isArray(value2))
19025
19248
  throw new Error(`${location} must be an object`);
19026
- const record4 = value;
19249
+ const record4 = value2;
19027
19250
  for (const key of Object.keys(record4))
19028
19251
  if (!keys.has(key)) throw new Error(`${location}.${key} is not allowed`);
19029
19252
  return record4;
19030
19253
  }
19031
- function optionalType(value, type, location) {
19032
- if (value !== void 0 && typeof value !== type)
19254
+ function optionalType(value2, type, location) {
19255
+ if (value2 !== void 0 && typeof value2 !== type)
19033
19256
  throw new Error(`${location} must be a ${type}`);
19034
19257
  }
19035
- function strictPath(value, location, required = false) {
19036
- if (value === void 0 && !required) return;
19037
- if (typeof value !== "string" || !pathPattern.test(value))
19258
+ function strictPath(value2, location, required = false) {
19259
+ if (value2 === void 0 && !required) return;
19260
+ if (typeof value2 !== "string" || !pathPattern.test(value2))
19038
19261
  throw new Error(
19039
19262
  `${location} must use dot-path syntax with property or array-index segments (for example: ecommerce.items.0.price); bracket syntax is not accepted`
19040
19263
  );
19041
19264
  }
19042
- function strictSource(value, location, allowSignal, required = false) {
19043
- if (value === void 0 && !required) return;
19044
- const sources = Array.isArray(value) ? value : [value];
19045
- if (Array.isArray(value) && (value.length < 1 || value.length > runtime_settings_trigger_constants_default.maxSourcePaths))
19265
+ function strictSource(value2, location, allowSignal, required = false) {
19266
+ if (value2 === void 0 && !required) return;
19267
+ const sources = Array.isArray(value2) ? value2 : [value2];
19268
+ if (Array.isArray(value2) && (value2.length < 1 || value2.length > runtime_settings_trigger_constants_default.maxSourcePaths))
19046
19269
  throw new Error(`${location} must contain 1 to ${runtime_settings_trigger_constants_default.maxSourcePaths} paths`);
19047
19270
  sources.forEach((source, index) => {
19048
- const sourceLocation = Array.isArray(value) ? `${location}[${index}]` : location;
19271
+ const sourceLocation = Array.isArray(value2) ? `${location}[${index}]` : location;
19049
19272
  if (allowSignal && typeof source === "string" && signalPathPattern.test(source)) return;
19050
19273
  strictPath(source, sourceLocation, true);
19051
19274
  });
19052
19275
  }
19053
- function defaultMatchesValueType(value, valueType) {
19276
+ function defaultMatchesValueType(value2, valueType) {
19054
19277
  if (valueType === "number") {
19055
- if (typeof value !== "string") return Number.isFinite(Number(value));
19056
- const text2 = String(value).trim();
19278
+ if (typeof value2 !== "string") return Number.isFinite(Number(value2));
19279
+ const text2 = String(value2).trim();
19057
19280
  const normalized = /^-?\d{1,3}(\.\d{3})+,\d+$/.test(text2) ? text2.replace(/\./g, "").replace(",", ".") : /^-?\d+,\d+$/.test(text2) ? text2.replace(",", ".") : text2;
19058
19281
  return Number.isFinite(Number(normalized));
19059
19282
  }
19060
19283
  if (valueType === "boolean") {
19061
- if (typeof value === "boolean") return true;
19284
+ if (typeof value2 === "boolean") return true;
19062
19285
  return ["1", "true", "yes", "on", "0", "false", "no", "off"].includes(
19063
- String(value).trim().toLowerCase()
19286
+ String(value2).trim().toLowerCase()
19064
19287
  );
19065
19288
  }
19066
19289
  return true;
19067
19290
  }
19068
- function strictTransform(value, valueType, location) {
19069
- if (value === void 0) return;
19291
+ function strictTransform(value2, valueType, location) {
19292
+ if (value2 === void 0) return;
19070
19293
  const transform = strictObject(
19071
- value,
19294
+ value2,
19072
19295
  location,
19073
19296
  /* @__PURE__ */ new Set(["trim", "lowercase", "map", "scale", "default"])
19074
19297
  );
@@ -19101,7 +19324,7 @@ function strictTransform(value, valueType, location) {
19101
19324
  if (transform.default !== void 0 && !defaultMatchesValueType(transform.default, valueType))
19102
19325
  throw new Error(`${location}.default must coerce to the mapping valueType`);
19103
19326
  }
19104
- function strictMapping(value, location, revenueProperty) {
19327
+ function strictMapping(value2, location, revenueProperty) {
19105
19328
  const keys = /* @__PURE__ */ new Set([
19106
19329
  "from",
19107
19330
  "to",
@@ -19109,7 +19332,7 @@ function strictMapping(value, location, revenueProperty) {
19109
19332
  "transform",
19110
19333
  ...revenueProperty ? [] : ["ttlDays", "persist"]
19111
19334
  ]);
19112
- const mapping = strictObject(value, location, keys);
19335
+ const mapping = strictObject(value2, location, keys);
19113
19336
  strictSource(mapping.from, `${location}.from`, revenueProperty, true);
19114
19337
  strictPath(mapping.to, `${location}.to`, true);
19115
19338
  if (mapping.valueType !== void 0 && !valueTypes.has(String(mapping.valueType)))
@@ -19120,12 +19343,12 @@ function strictMapping(value, location, revenueProperty) {
19120
19343
  optionalType(mapping.persist, "boolean", `${location}.persist`);
19121
19344
  }
19122
19345
  }
19123
- function strictWhen(value, location) {
19124
- if (value === void 0) return;
19125
- if (!Array.isArray(value) || value.length < 1 || value.length > runtime_settings_trigger_constants_default.maxWhenEntries) {
19346
+ function strictWhen(value2, location) {
19347
+ if (value2 === void 0) return;
19348
+ if (!Array.isArray(value2) || value2.length < 1 || value2.length > runtime_settings_trigger_constants_default.maxWhenEntries) {
19126
19349
  throw new Error(`${location} must contain 1 to ${runtime_settings_trigger_constants_default.maxWhenEntries} entries`);
19127
19350
  }
19128
- value.forEach((entry, index) => {
19351
+ value2.forEach((entry, index) => {
19129
19352
  const entryLocation = `${location}[${index}]`;
19130
19353
  const condition = strictObject(entry, entryLocation, /* @__PURE__ */ new Set(["path", "op", "value"]));
19131
19354
  strictPath(condition.path, `${entryLocation}.path`, true);
@@ -19154,12 +19377,12 @@ function strictWhen(value, location) {
19154
19377
  }
19155
19378
  });
19156
19379
  }
19157
- function strictTriggers(value) {
19158
- if (!Array.isArray(value) || value.length > runtime_settings_trigger_constants_default.maxTriggers)
19380
+ function strictTriggers(value2) {
19381
+ if (!Array.isArray(value2) || value2.length > runtime_settings_trigger_constants_default.maxTriggers)
19159
19382
  throw new Error(
19160
19383
  `trigger file must contain an array of at most ${runtime_settings_trigger_constants_default.maxTriggers} triggers`
19161
19384
  );
19162
- return value.map((item, index) => {
19385
+ return value2.map((item, index) => {
19163
19386
  if (!item || typeof item !== "object" || Array.isArray(item))
19164
19387
  throw new Error(`trigger[${index}] must be an object`);
19165
19388
  const record4 = item;
@@ -19314,7 +19537,7 @@ var get3 = new Command("get").description("Get data layer triggers").requiredOpt
19314
19537
  var set2 = new Command("set").requiredOption("--file <json>", "JSON trigger array").requiredOption("--shop <domain-or-id>", "Shop domain or Apex shop ID").action(async function(opts) {
19315
19538
  let triggers;
19316
19539
  try {
19317
- triggers = strictTriggers(JSON.parse(import_node_fs18.default.readFileSync(import_node_path15.default.resolve(opts.file), "utf8")));
19540
+ triggers = strictTriggers(JSON.parse(import_node_fs19.default.readFileSync(import_node_path16.default.resolve(opts.file), "utf8")));
19318
19541
  } catch (error) {
19319
19542
  fail(
19320
19543
  this,
@@ -19341,7 +19564,7 @@ var propose = new Command("propose").requiredOption("--from-file <u2-report.json
19341
19564
  let proposals;
19342
19565
  let report;
19343
19566
  try {
19344
- report = JSON.parse(import_node_fs18.default.readFileSync(import_node_path15.default.resolve(opts.fromFile), "utf8"));
19567
+ report = JSON.parse(import_node_fs19.default.readFileSync(import_node_path16.default.resolve(opts.fromFile), "utf8"));
19345
19568
  proposals = proposeTriggers(report);
19346
19569
  } catch (error) {
19347
19570
  fail(this, error instanceof Error ? error.message : String(error), EXIT_CODES.validation);
@@ -19369,28 +19592,28 @@ var propose = new Command("propose").requiredOption("--from-file <u2-report.json
19369
19592
  `);
19370
19593
  });
19371
19594
  });
19372
- function collect(value, previous) {
19373
- return [...previous, value];
19595
+ function collect2(value2, previous) {
19596
+ return [...previous, value2];
19374
19597
  }
19375
- function parseParamValue(value) {
19376
- if (!value.startsWith("[") && !value.startsWith("{")) return value;
19598
+ function parseParamValue(value2) {
19599
+ if (!value2.startsWith("[") && !value2.startsWith("{")) return value2;
19377
19600
  try {
19378
- return JSON.parse(value);
19601
+ return JSON.parse(value2);
19379
19602
  } catch {
19380
- return value;
19603
+ return value2;
19381
19604
  }
19382
19605
  }
19383
- var recipe = new Command("apply-recipe").argument("<recipeId>").requiredOption("--shop <domain-or-id>", "Shop domain or Apex shop ID").option("--param <k=v>", "Recipe parameter", collect, []).action(async function(recipeId, opts) {
19606
+ var recipe = new Command("apply-recipe").argument("<recipeId>").requiredOption("--shop <domain-or-id>", "Shop domain or Apex shop ID").option("--param <k=v>", "Recipe parameter", collect2, []).action(async function(recipeId, opts) {
19384
19607
  const params = Object.fromEntries(
19385
- opts.param.map((pair) => {
19386
- const i = pair.indexOf("=");
19608
+ opts.param.map((pair2) => {
19609
+ const i = pair2.indexOf("=");
19387
19610
  if (i < 1)
19388
19611
  fail(
19389
19612
  this,
19390
- `TRIGGERS_CONFIG_ABSENT: invalid --param ${pair}; expected k=v`,
19613
+ `TRIGGERS_CONFIG_ABSENT: invalid --param ${pair2}; expected k=v`,
19391
19614
  EXIT_CODES.validation
19392
19615
  );
19393
- return [pair.slice(0, i), parseParamValue(pair.slice(i + 1))];
19616
+ return [pair2.slice(0, i), parseParamValue(pair2.slice(i + 1))];
19394
19617
  })
19395
19618
  );
19396
19619
  const identity2 = await identify(this, opts.shop);
@@ -19417,7 +19640,7 @@ var recipe = new Command("apply-recipe").argument("<recipeId>").requiredOption("
19417
19640
  writeWarnings(result);
19418
19641
  });
19419
19642
  });
19420
- var enable = new Command("enable-capture").requiredOption("--hours <n>").requiredOption("--shop <domain-or-id>", "Shop domain or Apex shop ID").option("--url-pattern <p>", "URL pattern", collect, []).action(async function(opts) {
19643
+ var enable = new Command("enable-capture").requiredOption("--hours <n>").requiredOption("--shop <domain-or-id>", "Shop domain or Apex shop ID").option("--url-pattern <p>", "URL pattern", collect2, []).action(async function(opts) {
19421
19644
  const hours = Number(opts.hours);
19422
19645
  if (!Number.isFinite(hours) || hours <= 0 || hours > 48)
19423
19646
  fail(
@@ -19461,11 +19684,11 @@ var triggersCommand = new Command("triggers").description("Manage runtime data l
19461
19684
 
19462
19685
  // src/commands/domains.ts
19463
19686
  init_source();
19464
- function normalizeDomain(value) {
19465
- return value.trim().replace(/^https?:\/\//i, "").replace(/[/?#].*$/, "").replace(/\.$/, "").toLowerCase();
19687
+ function normalizeDomain(value2) {
19688
+ return value2.trim().replace(/^https?:\/\//i, "").replace(/[/?#].*$/, "").replace(/\.$/, "").toLowerCase();
19466
19689
  }
19467
- function landingHost(value) {
19468
- const trimmed = value.trim();
19690
+ function landingHost(value2) {
19691
+ const trimmed = value2.trim();
19469
19692
  try {
19470
19693
  const withScheme = /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
19471
19694
  return new URL(withScheme).hostname.toLowerCase().replace(/\.$/, "") || normalizeDomain(trimmed);
@@ -19643,8 +19866,8 @@ var register = new Command("register").description("Register a new domain on the
19643
19866
  `apex domains register ${host} --years ${years} --confirm-price "${quote.total} ${quote.currency}"`
19644
19867
  );
19645
19868
  }
19646
- const readline3 = await import("node:readline");
19647
- const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
19869
+ const readline4 = await import("node:readline");
19870
+ const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
19648
19871
  console.error(describeQuote(quote));
19649
19872
  const answer = await new Promise(
19650
19873
  (resolve2) => rl.question(
@@ -19731,9 +19954,9 @@ var domainsCommand = new Command("domains").description("Manage install domains
19731
19954
 
19732
19955
  // src/commands/handover.ts
19733
19956
  init_source();
19734
- function normalizeDomain2(value) {
19957
+ function normalizeDomain2(value2) {
19735
19958
  try {
19736
- const candidate = value.trim().toLowerCase();
19959
+ const candidate = value2.trim().toLowerCase();
19737
19960
  const parsed = new URL(
19738
19961
  /^[a-z][a-z0-9+.-]*:\/\//.test(candidate) ? candidate : `http://${candidate}`
19739
19962
  );
@@ -19756,8 +19979,8 @@ var NAMED_HTML_ENTITIES = {
19756
19979
  apos: "'",
19757
19980
  nbsp: "\xA0"
19758
19981
  };
19759
- function decodeHtmlEntities(value) {
19760
- return value.replace(/&(#[0-9]+|#[xX][0-9a-fA-F]+|[a-zA-Z]+);/g, (match2, entity2) => {
19982
+ function decodeHtmlEntities(value2) {
19983
+ return value2.replace(/&(#[0-9]+|#[xX][0-9a-fA-F]+|[a-zA-Z]+);/g, (match2, entity2) => {
19761
19984
  if (entity2.startsWith("#")) {
19762
19985
  const hex = entity2[1] === "x" || entity2[1] === "X";
19763
19986
  const code = Number.parseInt(hex ? entity2.slice(2) : entity2.slice(1), hex ? 16 : 10);
@@ -19917,9 +20140,9 @@ var qa2 = new Command("qa").description("Check static link/form handover paramet
19917
20140
  var handoverCommand = new Command("handover").description("Manage cross-domain identity handover").addCommand(get4).addCommand(set4).addCommand(off2).addCommand(qa2);
19918
20141
 
19919
20142
  // src/commands/order-journey.ts
19920
- function instant(value) {
20143
+ function instant(value2) {
19921
20144
  const m = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d+))?)?(Z|[+-]\d{2}:\d{2})$/.exec(
19922
- value
20145
+ value2
19923
20146
  );
19924
20147
  if (!m) return null;
19925
20148
  const year = Number(m[1]), month = Number(m[2]), day = Number(m[3]);
@@ -20223,22 +20446,22 @@ var CAVEAT = "Labeled estimate only: fail-closed consent tracking makes decliner
20223
20446
  var PRODUCTION_WORKER_BASE_URL = "https://events.drip-apex.com";
20224
20447
  var PRODUCTION_ENVIRONMENT_KEY = "production";
20225
20448
  var VISITOR_SERIES_DAYS = 60;
20226
- function hostOnly(value) {
20227
- if (!value) return null;
20449
+ function hostOnly(value2) {
20450
+ if (!value2) return null;
20228
20451
  try {
20229
- return new URL(value.includes("://") ? value : `https://${value}`).hostname.toLowerCase();
20452
+ return new URL(value2.includes("://") ? value2 : `https://${value2}`).hostname.toLowerCase();
20230
20453
  } catch {
20231
- return value.toLowerCase().replace(/^https?:\/\//, "").split("/")[0] || null;
20454
+ return value2.toLowerCase().replace(/^https?:\/\//, "").split("/")[0] || null;
20232
20455
  }
20233
20456
  }
20234
20457
  function configuredHosts(domains, envs) {
20235
20458
  const set7 = /* @__PURE__ */ new Set();
20236
- for (const value of [
20459
+ for (const value2 of [
20237
20460
  domains.domain,
20238
20461
  ...domains.additionalDomains ?? [],
20239
20462
  ...domains.storeOrigins ?? []
20240
20463
  ]) {
20241
- const host = hostOnly(value);
20464
+ const host = hostOnly(value2);
20242
20465
  if (host) set7.add(host);
20243
20466
  }
20244
20467
  for (const env2 of envs?.environments.items ?? [])
@@ -20339,8 +20562,8 @@ var PURCHASE_CADENCE_WINDOW_MINUTES = PURCHASE_WINDOW_MINUTES * 4;
20339
20562
  var MIN_CAPTURE_WINDOW_MINUTES = 60;
20340
20563
  var DUPLICATE_RATE_THRESHOLD = 0.02;
20341
20564
  var MAGNITUDE_TOLERANCE_RATE = 0.1;
20342
- function record3(value) {
20343
- return value && typeof value === "object" && !Array.isArray(value) ? value : null;
20565
+ function record3(value2) {
20566
+ return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
20344
20567
  }
20345
20568
  function purchasePlane(config) {
20346
20569
  if (!config) return { present: false, names: [] };
@@ -20355,13 +20578,13 @@ function purchasePlane(config) {
20355
20578
  return { present: names.length > 0, names };
20356
20579
  }
20357
20580
  function publicationTime(config) {
20358
- for (const value of [
20581
+ for (const value2 of [
20359
20582
  config?.generated_at,
20360
20583
  config?.publicationTimestamp,
20361
20584
  config?.publishedAt,
20362
20585
  config?.updatedAt
20363
20586
  ]) {
20364
- if (typeof value === "string" && Number.isFinite(Date.parse(value))) return Date.parse(value);
20587
+ if (typeof value2 === "string" && Number.isFinite(Date.parse(value2))) return Date.parse(value2);
20365
20588
  }
20366
20589
  return null;
20367
20590
  }
@@ -20382,14 +20605,14 @@ function eventTime(event) {
20382
20605
  const raw = event.timestamp;
20383
20606
  return typeof raw === "string" && Number.isFinite(Date.parse(raw)) ? Date.parse(raw) : null;
20384
20607
  }
20385
- function numeric(value) {
20386
- const parsed = typeof value === "number" ? value : typeof value === "string" && value.trim() !== "" ? Number(value) : NaN;
20608
+ function numeric(value2) {
20609
+ const parsed = typeof value2 === "number" ? value2 : typeof value2 === "string" && value2.trim() !== "" ? Number(value2) : NaN;
20387
20610
  return Number.isFinite(parsed) ? parsed : null;
20388
20611
  }
20389
- function lineItemSum(value) {
20390
- if (!Array.isArray(value)) return null;
20612
+ function lineItemSum(value2) {
20613
+ if (!Array.isArray(value2)) return null;
20391
20614
  let sum = 0;
20392
- for (const item of value) {
20615
+ for (const item of value2) {
20393
20616
  const row = record3(item);
20394
20617
  const price = numeric(row?.price);
20395
20618
  if (price === null) return null;
@@ -20592,8 +20815,8 @@ async function fetchServedConfig(workerBase, shopId) {
20592
20815
  }
20593
20816
  function originHosts(values) {
20594
20817
  const set7 = /* @__PURE__ */ new Set();
20595
- for (const value of values) {
20596
- const host = hostOnly(value);
20818
+ for (const value2 of values) {
20819
+ const host = hostOnly(value2);
20597
20820
  if (host) set7.add(host);
20598
20821
  }
20599
20822
  return [...set7].sort();
@@ -20970,15 +21193,15 @@ function withCaveat(check, caveat) {
20970
21193
  return caveat.length ? { ...check, evidence: [...check.evidence, ...caveat] } : check;
20971
21194
  }
20972
21195
  var DAY_MS = 864e5;
20973
- function parseDay(value) {
20974
- const text2 = value?.trim();
21196
+ function parseDay(value2) {
21197
+ const text2 = value2?.trim();
20975
21198
  if (!text2 || !/^\d{4}-\d{2}-\d{2}$/.test(text2)) return null;
20976
21199
  const parsed = Date.parse(`${text2}T00:00:00.000Z`);
20977
21200
  if (Number.isNaN(parsed)) return null;
20978
21201
  return toDay(parsed) === text2 ? parsed : null;
20979
21202
  }
20980
- function toDay(value) {
20981
- return new Date(value).toISOString().slice(0, 10);
21203
+ function toDay(value2) {
21204
+ return new Date(value2).toISOString().slice(0, 10);
20982
21205
  }
20983
21206
  function windowDays(from, to) {
20984
21207
  return to < from ? 0 : Math.round((to - from) / DAY_MS) + 1;
@@ -21085,18 +21308,18 @@ ${CAVEAT}`
21085
21308
  });
21086
21309
 
21087
21310
  // src/commands/analytics.ts
21088
- function display(value) {
21089
- if (value === null || value === void 0) return "\u2014";
21090
- if (typeof value === "object") return JSON.stringify(value);
21091
- return String(value);
21092
- }
21093
- function positiveInteger(command, value, option) {
21094
- if (value === void 0) return void 0;
21095
- const parsed = Number(value);
21311
+ function display(value2) {
21312
+ if (value2 === null || value2 === void 0) return "\u2014";
21313
+ if (typeof value2 === "object") return JSON.stringify(value2);
21314
+ return String(value2);
21315
+ }
21316
+ function positiveInteger(command, value2, option) {
21317
+ if (value2 === void 0) return void 0;
21318
+ const parsed = Number(value2);
21096
21319
  if (!Number.isInteger(parsed) || parsed <= 0)
21097
21320
  fail(command, `${option} must be a positive integer`, EXIT_CODES.validation, {
21098
21321
  field: option.slice(2),
21099
- actual: value
21322
+ actual: value2
21100
21323
  });
21101
21324
  return parsed;
21102
21325
  }
@@ -21227,7 +21450,7 @@ Examples:
21227
21450
  );
21228
21451
 
21229
21452
  // src/commands/install.ts
21230
- var import_promises3 = require("node:dns/promises");
21453
+ var import_promises4 = require("node:dns/promises");
21231
21454
  var import_node_http2 = require("node:http");
21232
21455
  var import_node_https = require("node:https");
21233
21456
  var import_node_net = require("node:net");
@@ -21285,7 +21508,7 @@ var testResolver;
21285
21508
  var testFetch;
21286
21509
  async function resolveHost(hostname) {
21287
21510
  const mocked = testResolver?.(hostname) ?? null;
21288
- const addresses = mocked ?? await (0, import_promises3.lookup)(hostname, { all: true });
21511
+ const addresses = mocked ?? await (0, import_promises4.lookup)(hostname, { all: true });
21289
21512
  return addresses.map((entry) => entry.address);
21290
21513
  }
21291
21514
  async function validateUrl(raw, allowedHosts) {
@@ -21334,8 +21557,8 @@ function decoderFor(encoding) {
21334
21557
  return (0, import_node_zlib.createBrotliDecompress)();
21335
21558
  }
21336
21559
  function normalizeEncoding(header) {
21337
- const value = (header ?? "").trim().toLowerCase();
21338
- return !value || value === "identity" ? null : value;
21560
+ const value2 = (header ?? "").trim().toLowerCase();
21561
+ return !value2 || value2 === "identity" ? null : value2;
21339
21562
  }
21340
21563
  function decodeBody(raw, header, limits, hostname, inputTruncated = false) {
21341
21564
  const encoding = normalizeEncoding(header);
@@ -21398,9 +21621,9 @@ function overLimitMessage(hostname, maxBytes) {
21398
21621
  function responseFromIncoming(res, body5, decoded) {
21399
21622
  const status4 = res.statusCode ?? 0;
21400
21623
  const headers = new Headers();
21401
- for (const [key, value] of Object.entries(res.headers)) {
21402
- if (Array.isArray(value)) for (const entry of value) headers.append(key, entry);
21403
- else if (typeof value === "string") headers.set(key, value);
21624
+ for (const [key, value2] of Object.entries(res.headers)) {
21625
+ if (Array.isArray(value2)) for (const entry of value2) headers.append(key, entry);
21626
+ else if (typeof value2 === "string") headers.set(key, value2);
21404
21627
  }
21405
21628
  if (decoded) {
21406
21629
  headers.delete("content-encoding");
@@ -21651,11 +21874,11 @@ function buildConfigUrl(workerBaseUrl, shopId, environmentKey) {
21651
21874
  if (normalized && normalized !== "production") url.searchParams.set("env", normalized);
21652
21875
  return url.toString();
21653
21876
  }
21654
- function readNumber(value) {
21655
- return typeof value === "number" && Number.isFinite(value) ? value : null;
21877
+ function readNumber(value2) {
21878
+ return typeof value2 === "number" && Number.isFinite(value2) ? value2 : null;
21656
21879
  }
21657
- function readString(value) {
21658
- return typeof value === "string" && value.trim() ? value : null;
21880
+ function readString(value2) {
21881
+ return typeof value2 === "string" && value2.trim() ? value2 : null;
21659
21882
  }
21660
21883
  function isRecognizedConfig(config) {
21661
21884
  const hasRevision = readNumber(config.publicationRevision) !== null || readNumber(config.publication_revision) !== null;
@@ -21927,7 +22150,7 @@ var installCommand = new Command("install").description("Check Apex storefront i
21927
22150
  "trackRevenue.enabled",
21928
22151
  servedConfig.revenueTriggerEnabled === null ? "unknown" : servedConfig.revenueTriggerEnabled ? "yes" : "no"
21929
22152
  ]
21930
- ].map(([field, value]) => [String(field), String(value)])
22153
+ ].map(([field, value2]) => [String(field), String(value2)])
21931
22154
  );
21932
22155
  if (warnings.length)
21933
22156
  printTable(
@@ -21961,15 +22184,15 @@ var installCommand = new Command("install").description("Check Apex storefront i
21961
22184
 
21962
22185
  // src/commands/flags.ts
21963
22186
  init_source();
21964
- var import_node_fs19 = __toESM(require("node:fs"));
21965
- var import_node_path16 = __toESM(require("node:path"));
22187
+ var import_node_fs20 = __toESM(require("node:fs"));
22188
+ var import_node_path17 = __toESM(require("node:path"));
21966
22189
 
21967
22190
  // src/edge-status.ts
21968
22191
  function getEdgeDeliveryStatus(deliveryType, expectedWorstCaseSeconds = 360) {
21969
22192
  return deliveryType === "api" ? { edge_delivery: "not_applicable", message: `API-delivered flag \u2014 edge delivery is not applicable. A previously cached visual payload may remain at some PoPs for up to ~${expectedWorstCaseSeconds}s; a single-vantage status cannot prove global propagation.` } : { edge_delivery: "applicable", message: null };
21970
22193
  }
21971
- function parsePublicationMetadata(value) {
21972
- const record4 = value && typeof value === "object" ? value : {};
22194
+ function parsePublicationMetadata(value2) {
22195
+ const record4 = value2 && typeof value2 === "object" ? value2 : {};
21973
22196
  return {
21974
22197
  publication_revision: Number.isSafeInteger(record4.publication_revision) && record4.publication_revision >= 0 ? record4.publication_revision : null,
21975
22198
  generated_at: typeof record4.generated_at === "string" && !Number.isNaN(Date.parse(record4.generated_at)) ? record4.generated_at : null
@@ -22000,11 +22223,11 @@ function formatEdgePropagationStatus(status4) {
22000
22223
 
22001
22224
  // src/commands/flags.ts
22002
22225
  var kind = "flags";
22003
- function body(command, value, opts) {
22226
+ function body(command, value2, opts) {
22004
22227
  let parsed = {};
22005
- if (value) {
22006
- const source = value.startsWith("@") ? value.slice(1) : value;
22007
- const text2 = value.startsWith("@") || import_node_fs19.default.existsSync(source) ? import_node_fs19.default.readFileSync(import_node_path16.default.resolve(process.cwd(), source), "utf8") : value;
22228
+ if (value2) {
22229
+ const source = value2.startsWith("@") ? value2.slice(1) : value2;
22230
+ const text2 = value2.startsWith("@") || import_node_fs20.default.existsSync(source) ? import_node_fs20.default.readFileSync(import_node_path17.default.resolve(process.cwd(), source), "utf8") : value2;
22008
22231
  try {
22009
22232
  parsed = JSON.parse(text2);
22010
22233
  } catch (e) {
@@ -22106,8 +22329,8 @@ function write(name) {
22106
22329
  c.action(async function(...args) {
22107
22330
  const o = this.opts();
22108
22331
  const id = name === "update" ? String(args[0]) : void 0;
22109
- const value = o.file ? `@${o.file}` : String(args[name === "update" ? 1 : 0] ?? "") || void 0;
22110
- const b = body(this, value, o);
22332
+ const value2 = o.file ? `@${o.file}` : String(args[name === "update" ? 1 : 0] ?? "") || void 0;
22333
+ const b = body(this, value2, o);
22111
22334
  if (name === "update" && !Object.keys(b).length)
22112
22335
  fail(this, "Provide at least one field to update.", EXIT_CODES.validation);
22113
22336
  const r = name === "create" ? await createManagedDelivery(requireCredentials(), kind, b) : await updateManagedDelivery(requireCredentials(), kind, id, b);
@@ -22137,16 +22360,16 @@ Examples:
22137
22360
  );
22138
22361
 
22139
22362
  // src/commands/backlog.ts
22140
- var import_node_fs20 = __toESM(require("node:fs"));
22141
- var import_node_path17 = __toESM(require("node:path"));
22363
+ var import_node_fs21 = __toESM(require("node:fs"));
22364
+ var import_node_path18 = __toESM(require("node:path"));
22142
22365
  init_source();
22143
22366
  var kind2 = "backlog";
22144
22367
  var singular = "backlog item";
22145
- function parse(command, value) {
22146
- if (!value) return {};
22368
+ function parse(command, value2) {
22369
+ if (!value2) return {};
22147
22370
  try {
22148
- const source = value.startsWith("@") ? value.slice(1) : value;
22149
- const text2 = value.startsWith("@") || import_node_fs20.default.existsSync(source) ? import_node_fs20.default.readFileSync(import_node_path17.default.resolve(process.cwd(), source), "utf8") : value;
22371
+ const source = value2.startsWith("@") ? value2.slice(1) : value2;
22372
+ const text2 = value2.startsWith("@") || import_node_fs21.default.existsSync(source) ? import_node_fs21.default.readFileSync(import_node_path18.default.resolve(process.cwd(), source), "utf8") : value2;
22150
22373
  const body5 = JSON.parse(text2);
22151
22374
  if (!body5 || typeof body5 !== "object" || Array.isArray(body5))
22152
22375
  throw new Error("body must be an object");
@@ -22159,11 +22382,11 @@ function parse(command, value) {
22159
22382
  );
22160
22383
  }
22161
22384
  }
22162
- function collect2(value, previous) {
22163
- return [...previous, value];
22385
+ function collect3(value2, previous) {
22386
+ return [...previous, value2];
22164
22387
  }
22165
- function customFieldsRecord(value) {
22166
- return value && typeof value === "object" && !Array.isArray(value) ? value : {};
22388
+ function customFieldsRecord(value2) {
22389
+ return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : {};
22167
22390
  }
22168
22391
  function typedFieldValue(definition, raw) {
22169
22392
  if (raw === "null") return null;
@@ -22185,11 +22408,11 @@ function typedFieldValue(definition, raw) {
22185
22408
  }
22186
22409
  async function customFieldsFromPairs(command, pairs) {
22187
22410
  if (pairs.length === 0) return void 0;
22188
- const parsedPairs = pairs.map((pair) => {
22189
- const separator = pair.indexOf("=");
22411
+ const parsedPairs = pairs.map((pair2) => {
22412
+ const separator = pair2.indexOf("=");
22190
22413
  if (separator <= 0)
22191
- fail(command, `Invalid --field "${pair}": use key=value.`, EXIT_CODES.validation);
22192
- return { key: pair.slice(0, separator), raw: pair.slice(separator + 1) };
22414
+ fail(command, `Invalid --field "${pair2}": use key=value.`, EXIT_CODES.validation);
22415
+ return { key: pair2.slice(0, separator), raw: pair2.slice(separator + 1) };
22193
22416
  });
22194
22417
  const fields3 = await listBacklogFields(requireCredentials());
22195
22418
  if (!fields3.ok || !fields3.data) {
@@ -22213,8 +22436,8 @@ function detail2(x, labels) {
22213
22436
  const custom = customFieldsRecord(x.custom_fields);
22214
22437
  if (Object.keys(custom).length > 0) {
22215
22438
  console.log();
22216
- for (const [key, value] of Object.entries(custom)) {
22217
- console.log(` ${labels.get(key) ?? key}: ${value === null ? "-" : String(value)}`);
22439
+ for (const [key, value2] of Object.entries(custom)) {
22440
+ console.log(` ${labels.get(key) ?? key}: ${value2 === null ? "-" : String(value2)}`);
22218
22441
  }
22219
22442
  }
22220
22443
  console.log();
@@ -22266,7 +22489,7 @@ function write2(action78) {
22266
22489
  c.argument("[json]", "Inline JSON, @file, or file path").option("--file <path>", "JSON body file").option(
22267
22490
  "--field <key=value>",
22268
22491
  "Set one of the shop's own fields; repeatable. Use key=null to clear it.",
22269
- collect2,
22492
+ collect3,
22270
22493
  []
22271
22494
  );
22272
22495
  c.action(async function(...args) {
@@ -22312,8 +22535,8 @@ var remove = new Command("delete").description("Delete a backlog item").argument
22312
22535
  "Deleting a backlog item requires confirmation in non-TTY mode.",
22313
22536
  `apex backlog delete ${id} --force`
22314
22537
  );
22315
- const readline3 = await import("node:readline");
22316
- const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
22538
+ const readline4 = await import("node:readline");
22539
+ const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
22317
22540
  const answer = await new Promise(
22318
22541
  (resolve2) => rl.question(source_default.yellow(`Delete backlog item ${id}? [y/N] `), resolve2)
22319
22542
  );
@@ -22340,12 +22563,12 @@ function fieldDetail(field) {
22340
22563
  if (field.archived_at) console.log(` Archived: ${field.archived_at}`);
22341
22564
  console.log();
22342
22565
  }
22343
- function boolOption(command, flag, value) {
22344
- if (value === void 0) return void 0;
22345
- const trimmed = value.trim().toLowerCase();
22566
+ function boolOption(command, flag, value2) {
22567
+ if (value2 === void 0) return void 0;
22568
+ const trimmed = value2.trim().toLowerCase();
22346
22569
  if (["true", "yes", "y", "1"].includes(trimmed)) return true;
22347
22570
  if (["false", "no", "n", "0"].includes(trimmed)) return false;
22348
- fail(command, `Invalid ${flag} "${value}": use true or false.`, EXIT_CODES.validation);
22571
+ fail(command, `Invalid ${flag} "${value2}": use true or false.`, EXIT_CODES.validation);
22349
22572
  }
22350
22573
  var fieldsList = new Command("list").alias("ls").description("List the shop's idea fields").option("--include-archived", "Include archived fields").action(async function(o) {
22351
22574
  const r = await listBacklogFields(requireCredentials(), o.includeArchived);
@@ -22373,7 +22596,7 @@ var fieldsCreate = new Command("create").description("Add an idea field").requir
22373
22596
  ).option("--key <key>", "Field key; derived from the label when omitted").option(
22374
22597
  "--option <value>",
22375
22598
  "A choice for a single_choice field; repeatable",
22376
- collect2,
22599
+ collect3,
22377
22600
  []
22378
22601
  ).option("--required <true|false>", "Every idea must carry a value").option("--client-visible <true|false>", "Share the value with the client").action(async function(o) {
22379
22602
  const required = boolOption(this, "--required", o.required);
@@ -22393,7 +22616,7 @@ var fieldsCreate = new Command("create").description("Add an idea field").requir
22393
22616
  var fieldsUpdate = new Command("update").description("Update an idea field").argument("<id>", "field ID").option("--label <text>", "What the field is called").option(
22394
22617
  "--option <value>",
22395
22618
  "Replace the choices of a single_choice field; repeatable",
22396
- collect2,
22619
+ collect3,
22397
22620
  []
22398
22621
  ).option("--required <true|false>", "Every idea must carry a value").option("--client-visible <true|false>", "Share the value with the client").option("--archived <true|false>", "Archive or restore the field").action(async function(id, o) {
22399
22622
  const required = boolOption(this, "--required", o.required);
@@ -22423,16 +22646,16 @@ var fields2 = new Command("fields").description("Manage the shop's own idea fiel
22423
22646
  var backlogCommand = new Command("backlog").description("Manage backlog").addCommand(list7).addCommand(get6).addCommand(write2("create")).addCommand(write2("update")).addCommand(archive).addCommand(restore).addCommand(remove).addCommand(fields2);
22424
22647
 
22425
22648
  // src/commands/signals.ts
22426
- var import_node_fs21 = __toESM(require("node:fs"));
22427
- var import_node_path18 = __toESM(require("node:path"));
22649
+ var import_node_fs22 = __toESM(require("node:fs"));
22650
+ var import_node_path19 = __toESM(require("node:path"));
22428
22651
  init_source();
22429
22652
  var kind3 = "signals";
22430
22653
  var singular2 = "signal";
22431
- function parse2(command, value) {
22432
- if (!value) return {};
22654
+ function parse2(command, value2) {
22655
+ if (!value2) return {};
22433
22656
  try {
22434
- const source = value.startsWith("@") ? value.slice(1) : value;
22435
- const text2 = value.startsWith("@") || import_node_fs21.default.existsSync(source) ? import_node_fs21.default.readFileSync(import_node_path18.default.resolve(process.cwd(), source), "utf8") : value;
22657
+ const source = value2.startsWith("@") ? value2.slice(1) : value2;
22658
+ const text2 = value2.startsWith("@") || import_node_fs22.default.existsSync(source) ? import_node_fs22.default.readFileSync(import_node_path19.default.resolve(process.cwd(), source), "utf8") : value2;
22436
22659
  const body5 = JSON.parse(text2);
22437
22660
  if (!body5 || typeof body5 !== "object" || Array.isArray(body5))
22438
22661
  throw new Error("body must be an object");
@@ -22514,14 +22737,14 @@ var signalsCommand = new Command("signals").description("Manage signals").addCom
22514
22737
 
22515
22738
  // src/commands/personalizations.ts
22516
22739
  init_source();
22517
- var import_node_fs22 = __toESM(require("node:fs"));
22518
- var import_node_path19 = __toESM(require("node:path"));
22740
+ var import_node_fs23 = __toESM(require("node:fs"));
22741
+ var import_node_path20 = __toESM(require("node:path"));
22519
22742
  var kind4 = "personalizations";
22520
- function body2(command, value, opts) {
22743
+ function body2(command, value2, opts) {
22521
22744
  let parsed = {};
22522
- if (value) {
22523
- const source = value.startsWith("@") ? value.slice(1) : value;
22524
- const text2 = value.startsWith("@") || import_node_fs22.default.existsSync(source) ? import_node_fs22.default.readFileSync(import_node_path19.default.resolve(process.cwd(), source), "utf8") : value;
22745
+ if (value2) {
22746
+ const source = value2.startsWith("@") ? value2.slice(1) : value2;
22747
+ const text2 = value2.startsWith("@") || import_node_fs23.default.existsSync(source) ? import_node_fs23.default.readFileSync(import_node_path20.default.resolve(process.cwd(), source), "utf8") : value2;
22525
22748
  try {
22526
22749
  parsed = JSON.parse(text2);
22527
22750
  } catch (e) {
@@ -22580,8 +22803,8 @@ function write4(name) {
22580
22803
  c.action(async function(...args) {
22581
22804
  const o = this.opts();
22582
22805
  const id = name === "update" ? String(args[0]) : void 0;
22583
- const value = o.file ? `@${o.file}` : String(args[name === "update" ? 1 : 0] ?? "") || void 0;
22584
- const b = body2(this, value, o);
22806
+ const value2 = o.file ? `@${o.file}` : String(args[name === "update" ? 1 : 0] ?? "") || void 0;
22807
+ const b = body2(this, value2, o);
22585
22808
  if (name === "update" && !Object.keys(b).length)
22586
22809
  fail(this, "Provide at least one field to update.", EXIT_CODES.validation);
22587
22810
  const r = name === "create" ? await createManagedDelivery(requireCredentials(), kind4, b) : await updateManagedDelivery(requireCredentials(), kind4, id, b);
@@ -22603,8 +22826,8 @@ var personalizationsCommand = new Command("personalizations").description("Manag
22603
22826
 
22604
22827
  // src/commands/targeting-resources.ts
22605
22828
  init_source();
22606
- var import_node_fs23 = __toESM(require("node:fs"));
22607
- var import_node_path20 = __toESM(require("node:path"));
22829
+ var import_node_fs24 = __toESM(require("node:fs"));
22830
+ var import_node_path21 = __toESM(require("node:path"));
22608
22831
 
22609
22832
  // src/generated/exclusion-group-body.schema.json
22610
22833
  var exclusion_group_body_schema_default = {
@@ -22857,11 +23080,11 @@ function exclusionFailureDetails(kind5, action78, status4, details) {
22857
23080
  ]
22858
23081
  };
22859
23082
  }
22860
- function body3(command, value) {
22861
- if (!value) return {};
22862
- const source = value.startsWith("@") ? value.slice(1) : value;
23083
+ function body3(command, value2) {
23084
+ if (!value2) return {};
23085
+ const source = value2.startsWith("@") ? value2.slice(1) : value2;
22863
23086
  try {
22864
- const text2 = value.startsWith("@") || import_node_fs23.default.existsSync(source) ? import_node_fs23.default.readFileSync(import_node_path20.default.resolve(process.cwd(), source), "utf8") : value;
23087
+ const text2 = value2.startsWith("@") || import_node_fs24.default.existsSync(source) ? import_node_fs24.default.readFileSync(import_node_path21.default.resolve(process.cwd(), source), "utf8") : value2;
22865
23088
  return JSON.parse(text2);
22866
23089
  } catch (error) {
22867
23090
  fail(
@@ -22940,8 +23163,8 @@ function targetingResourceCommand(kind5) {
22940
23163
  ).option("--file <path>", "JSON body file").action(async function(...args) {
22941
23164
  const opts = this.opts();
22942
23165
  const id = action78 === "update" ? String(args[0]) : void 0;
22943
- const value = opts.file ? `@${opts.file}` : String(args[action78 === "update" ? 1 : 0] ?? "") || void 0;
22944
- const requestBody = body3(this, value);
23166
+ const value2 = opts.file ? `@${opts.file}` : String(args[action78 === "update" ? 1 : 0] ?? "") || void 0;
23167
+ const requestBody = body3(this, value2);
22945
23168
  if (action78 === "update" && typeof requestBody === "object" && requestBody !== null && !Array.isArray(requestBody) && Object.keys(requestBody).length === 0)
22946
23169
  fail(this, `Updating a ${singular3} requires at least one field.`, EXIT_CODES.validation);
22947
23170
  const response = await requestTargetingResource(
@@ -22974,8 +23197,8 @@ function targetingResourceCommand(kind5) {
22974
23197
  "Deleting an exclusion group requires confirmation in non-TTY mode.",
22975
23198
  `apex exclusion-groups delete ${id} --force`
22976
23199
  );
22977
- const readline3 = await import("node:readline");
22978
- const rl = readline3.createInterface({
23200
+ const readline4 = await import("node:readline");
23201
+ const rl = readline4.createInterface({
22979
23202
  input: process.stdin,
22980
23203
  output: process.stderr
22981
23204
  });
@@ -23001,13 +23224,13 @@ function targetingResourceCommand(kind5) {
23001
23224
  );
23002
23225
  if (kind5 === "exclusion-groups") {
23003
23226
  root.addCommand(
23004
- new Command("replace-members").description("Replace exclusion group members").argument("<id>").argument("<json>", "Request body as inline JSON, @file, or a file path (shape below)").action(async function(id, value) {
23227
+ new Command("replace-members").description("Replace exclusion group members").argument("<id>").argument("<json>", "Request body as inline JSON, @file, or a file path (shape below)").action(async function(id, value2) {
23005
23228
  const response = await requestTargetingResource(
23006
23229
  requireCredentials(),
23007
23230
  "PUT",
23008
23231
  kind5,
23009
23232
  `${id}/members`,
23010
- body3(this, value)
23233
+ body3(this, value2)
23011
23234
  );
23012
23235
  if (!response.ok || !response.data)
23013
23236
  fail(
@@ -23116,8 +23339,8 @@ var targetingCommand = new Command("targeting").description("Test experiment tar
23116
23339
  // src/commands/sos.ts
23117
23340
  var import_node_crypto8 = require("node:crypto");
23118
23341
  init_source();
23119
- var import_node_fs24 = __toESM(require("node:fs"));
23120
- var import_node_path21 = __toESM(require("node:path"));
23342
+ var import_node_fs25 = __toESM(require("node:fs"));
23343
+ var import_node_path22 = __toESM(require("node:path"));
23121
23344
  var SOS_TYPES = /* @__PURE__ */ new Set([
23122
23345
  "full_handover",
23123
23346
  "design",
@@ -23127,10 +23350,10 @@ var SOS_TYPES = /* @__PURE__ */ new Set([
23127
23350
  "bug",
23128
23351
  "help"
23129
23352
  ]);
23130
- function readText(value) {
23131
- if (!value) return void 0;
23132
- if (!value.startsWith("@")) return value;
23133
- return import_node_fs24.default.readFileSync(import_node_path21.default.resolve(process.cwd(), value.slice(1)), "utf8");
23353
+ function readText(value2) {
23354
+ if (!value2) return void 0;
23355
+ if (!value2.startsWith("@")) return value2;
23356
+ return import_node_fs25.default.readFileSync(import_node_path22.default.resolve(process.cwd(), value2.slice(1)), "utf8");
23134
23357
  }
23135
23358
  function printTicket(ticket, reused) {
23136
23359
  console.log();
@@ -23184,12 +23407,12 @@ var create4 = new Command("create").description("Create an Apex SOS ticket").opt
23184
23407
  };
23185
23408
  if (opts.attach.length > 5) fail(this, "Attach no more than 5 files", 3);
23186
23409
  const files = opts.attach.map((file) => {
23187
- const filename = import_node_path21.default.basename(file);
23188
- const content_type = mediaTypes[import_node_path21.default.extname(file).toLowerCase()];
23410
+ const filename = import_node_path22.default.basename(file);
23411
+ const content_type = mediaTypes[import_node_path22.default.extname(file).toLowerCase()];
23189
23412
  if (!content_type) fail(this, "Unsupported attachment type", 3);
23190
23413
  let size;
23191
23414
  try {
23192
- size = import_node_fs24.default.statSync(file).size;
23415
+ size = import_node_fs25.default.statSync(file).size;
23193
23416
  } catch {
23194
23417
  fail(this, `Attachment not found: ${file}`, 3);
23195
23418
  }
@@ -23197,7 +23420,7 @@ var create4 = new Command("create").description("Create an Apex SOS ticket").opt
23197
23420
  if (size <= 0 || size > cap) fail(this, "Attachment exceeds its size limit or is empty", 3);
23198
23421
  let bytes;
23199
23422
  try {
23200
- bytes = import_node_fs24.default.readFileSync(file);
23423
+ bytes = import_node_fs25.default.readFileSync(file);
23201
23424
  } catch {
23202
23425
  fail(this, `Attachment not found: ${file}`, 3);
23203
23426
  }
@@ -23333,17 +23556,17 @@ var markRead = new Command("mark-read").option("--channel <key>", "Mark one chan
23333
23556
  var inboxCommand = new Command("inbox").description("Read and send inbox messages").addCommand(list11).addCommand(send2).addCommand(markRead);
23334
23557
 
23335
23558
  // src/commands/shops.ts
23336
- var import_node_fs25 = __toESM(require("node:fs"));
23337
- var import_node_path22 = __toESM(require("node:path"));
23559
+ var import_node_fs26 = __toESM(require("node:fs"));
23560
+ var import_node_path23 = __toESM(require("node:path"));
23338
23561
  function body4(command, raw) {
23339
23562
  if (!raw) return {};
23340
23563
  try {
23341
23564
  const source = raw.startsWith("@") ? raw.slice(1) : raw;
23342
- const text2 = raw.startsWith("@") || import_node_fs25.default.existsSync(source) ? import_node_fs25.default.readFileSync(import_node_path22.default.resolve(source), "utf8") : raw;
23343
- const value = JSON.parse(text2);
23344
- if (!value || typeof value !== "object" || Array.isArray(value))
23565
+ const text2 = raw.startsWith("@") || import_node_fs26.default.existsSync(source) ? import_node_fs26.default.readFileSync(import_node_path23.default.resolve(source), "utf8") : raw;
23566
+ const value2 = JSON.parse(text2);
23567
+ if (!value2 || typeof value2 !== "object" || Array.isArray(value2))
23345
23568
  throw new Error("body must be an object");
23346
- return value;
23569
+ return value2;
23347
23570
  } catch (e) {
23348
23571
  fail(
23349
23572
  command,
@@ -23448,15 +23671,15 @@ function settings(name, description, toggle) {
23448
23671
  }
23449
23672
  var profile = new Command("store-profile").description("Read and review a store profile");
23450
23673
  function printStoreProfile(data) {
23451
- const value = data;
23674
+ const value2 = data;
23452
23675
  console.log(
23453
- `${value.shop?.name ?? "Store profile"}${value.shop?.domain ? ` (${value.shop.domain})` : ""}`
23676
+ `${value2.shop?.name ?? "Store profile"}${value2.shop?.domain ? ` (${value2.shop.domain})` : ""}`
23454
23677
  );
23455
23678
  console.log(
23456
- `Audit: ${value.latestRun?.status ?? "not run"}; findings: ${value.findings?.length ?? 0} (${value.unreviewedCount ?? 0} unreviewed)`
23679
+ `Audit: ${value2.latestRun?.status ?? "not run"}; findings: ${value2.findings?.length ?? 0} (${value2.unreviewedCount ?? 0} unreviewed)`
23457
23680
  );
23458
- console.log(`Facts: ${value.facts?.length ?? 0}; open reviews: ${value.openReviewCount ?? 0}`);
23459
- console.log(`Learning run: ${value.latestLearningRun?.status ?? "none"}`);
23681
+ console.log(`Facts: ${value2.facts?.length ?? 0}; open reviews: ${value2.openReviewCount ?? 0}`);
23682
+ console.log(`Learning run: ${value2.latestLearningRun?.status ?? "none"}`);
23460
23683
  }
23461
23684
  profile.addCommand(
23462
23685
  new Command("get").argument("<id>").action(async function(id) {
@@ -23603,13 +23826,13 @@ function dataJson(source) {
23603
23826
  error: { code: "malformed_container", message: "GTM container data is not balanced JSON" }
23604
23827
  };
23605
23828
  }
23606
- function visit(value, callback) {
23607
- if (!value || typeof value !== "object") return;
23608
- if (Array.isArray(value)) {
23609
- for (const item of value) visit(item, callback);
23829
+ function visit(value2, callback) {
23830
+ if (!value2 || typeof value2 !== "object") return;
23831
+ if (Array.isArray(value2)) {
23832
+ for (const item of value2) visit(item, callback);
23610
23833
  return;
23611
23834
  }
23612
- const object = value;
23835
+ const object = value2;
23613
23836
  callback(object);
23614
23837
  for (const nested of Object.values(object)) visit(nested, callback);
23615
23838
  }
@@ -23656,13 +23879,13 @@ function parseContainer(source, id, dataLayerName = "dataLayer") {
23656
23879
  for (const rule of rules) {
23657
23880
  if (!Array.isArray(rule)) continue;
23658
23881
  const predicateIndexes = rule.flatMap(
23659
- (part) => Array.isArray(part) && part[0] === "if" ? part.slice(1).filter((value) => typeof value === "number") : []
23882
+ (part) => Array.isArray(part) && part[0] === "if" ? part.slice(1).filter((value2) => typeof value2 === "number") : []
23660
23883
  );
23661
23884
  const predicateText = predicateIndexes.map((index) => JSON.stringify(predicates[index] ?? "")).join(" ");
23662
23885
  if (!/consent/i.test(predicateText) || !purchaseRelevantEventNames.some((name) => predicateText.includes(name)))
23663
23886
  continue;
23664
23887
  const tagIndexes = rule.flatMap(
23665
- (part) => Array.isArray(part) && part[0] === "add" ? part.slice(1).filter((value) => typeof value === "number") : []
23888
+ (part) => Array.isArray(part) && part[0] === "add" ? part.slice(1).filter((value2) => typeof value2 === "number") : []
23666
23889
  );
23667
23890
  for (const index of tagIndexes) {
23668
23891
  const tag = recordObject(tags[index]);
@@ -23682,12 +23905,12 @@ function parseContainer(source, id, dataLayerName = "dataLayer") {
23682
23905
  vtpPaths,
23683
23906
  ecommerceFrom: [...ecommerce][0] ?? null,
23684
23907
  serverContainerUrl: [...serverUrls][0] ?? null,
23685
- piiPaths: vtpPaths.filter((path26) => /email|phone|address|name/i.test(path26))
23908
+ piiPaths: vtpPaths.filter((path27) => /email|phone|address|name/i.test(path27))
23686
23909
  }
23687
23910
  };
23688
23911
  }
23689
- function recordObject(value) {
23690
- return value && typeof value === "object" && !Array.isArray(value) ? value : null;
23912
+ function recordObject(value2) {
23913
+ return value2 && typeof value2 === "object" && !Array.isArray(value2) ? value2 : null;
23691
23914
  }
23692
23915
  async function mineGtm(input, fetcher = fetch, explicitContainerUrl = false) {
23693
23916
  let refs;
@@ -23732,11 +23955,11 @@ async function mineGtm(input, fetcher = fetch, explicitContainerUrl = false) {
23732
23955
  }
23733
23956
 
23734
23957
  // src/commands/discover.ts
23735
- function minutesValue(value) {
23736
- if (value === void 0) return void 0;
23737
- if (!/^\d+$/.test(value))
23958
+ function minutesValue(value2) {
23959
+ if (value2 === void 0) return void 0;
23960
+ if (!/^\d+$/.test(value2))
23738
23961
  throw new CliError("--minutes must be an integer between 1 and 20160", EXIT_CODES.validation);
23739
- const parsed = Number(value);
23962
+ const parsed = Number(value2);
23740
23963
  if (!Number.isSafeInteger(parsed) || parsed < 1 || parsed > 20160)
23741
23964
  throw new CliError("--minutes must be an integer between 1 and 20160", EXIT_CODES.validation);
23742
23965
  return parsed;
@@ -23751,11 +23974,11 @@ function isContainerField(field) {
23751
23974
  const types = baseFieldTypes(field);
23752
23975
  return types.has("obj") || types.has("arr");
23753
23976
  }
23754
- function hasSyntheticPlaceholder(path26) {
23755
- return path26.split(".").map((segment) => segment.replace(/\[\]$/, "")).some((segment) => /^<[^>]+>$/.test(segment));
23977
+ function hasSyntheticPlaceholder(path27) {
23978
+ return path27.split(".").map((segment) => segment.replace(/\[\]$/, "")).some((segment) => /^<[^>]+>$/.test(segment));
23756
23979
  }
23757
- function ambiguousDottedPrefix(event, path26) {
23758
- const segments = path26.split(".");
23980
+ function ambiguousDottedPrefix(event, path27) {
23981
+ const segments = path27.split(".");
23759
23982
  for (let index = 1; index < segments.length; index += 1) {
23760
23983
  const prefix = segments.slice(0, index).join(".");
23761
23984
  const parent = event.fields.find((field) => field.path === prefix);
@@ -23764,42 +23987,42 @@ function ambiguousDottedPrefix(event, path26) {
23764
23987
  return void 0;
23765
23988
  }
23766
23989
  function dimensionEligibility(event, field) {
23767
- const path26 = field.path;
23768
- if (hasSyntheticPlaceholder(path26)) {
23990
+ const path27 = field.path;
23991
+ if (hasSyntheticPlaceholder(path27)) {
23769
23992
  return {
23770
23993
  eligible: false,
23771
- message: `Path ${JSON.stringify(path26)} is a synthetic placeholder and cannot create a dimension. Choose an observed scalar path.`
23994
+ message: `Path ${JSON.stringify(path27)} is a synthetic placeholder and cannot create a dimension. Choose an observed scalar path.`
23772
23995
  };
23773
23996
  }
23774
23997
  if (isContainerField(field)) {
23775
23998
  return {
23776
23999
  eligible: false,
23777
- message: `Path ${JSON.stringify(path26)} is container-typed. Choose an observed scalar path.`
24000
+ message: `Path ${JSON.stringify(path27)} is container-typed. Choose an observed scalar path.`
23778
24001
  };
23779
24002
  }
23780
- if (path26.includes("[]")) {
24003
+ if (path27.includes("[]")) {
23781
24004
  return {
23782
24005
  eligible: false,
23783
- message: `Path ${JSON.stringify(path26)} includes an array-element segment and cannot create a reliable dimension. Choose a scalar path outside an array.`
24006
+ message: `Path ${JSON.stringify(path27)} includes an array-element segment and cannot create a reliable dimension. Choose a scalar path outside an array.`
23784
24007
  };
23785
24008
  }
23786
24009
  if (!isStableField(field)) {
23787
24010
  return {
23788
24011
  eligible: false,
23789
- message: `Path ${JSON.stringify(path26)} does not have a stable observed type. Choose a path without a type collision.`
24012
+ message: `Path ${JSON.stringify(path27)} does not have a stable observed type. Choose a path without a type collision.`
23790
24013
  };
23791
24014
  }
23792
24015
  if (!event.event) {
23793
24016
  return {
23794
24017
  eligible: false,
23795
- message: `Path ${JSON.stringify(path26)} has no observed event name. Choose a path from a named event.`
24018
+ message: `Path ${JSON.stringify(path27)} has no observed event name. Choose a path from a named event.`
23796
24019
  };
23797
24020
  }
23798
- const ambiguousPrefix = ambiguousDottedPrefix(event, path26);
24021
+ const ambiguousPrefix = ambiguousDottedPrefix(event, path27);
23799
24022
  if (ambiguousPrefix) {
23800
24023
  return {
23801
24024
  eligible: false,
23802
- message: `Path ${JSON.stringify(path26)} could be a literal key containing dots because the discovery report has no observed container at ${JSON.stringify(ambiguousPrefix)}. Apex cannot safely create a capture for it.`
24025
+ message: `Path ${JSON.stringify(path27)} could be a literal key containing dots because the discovery report has no observed container at ${JSON.stringify(ambiguousPrefix)}. Apex cannot safely create a capture for it.`
23803
24026
  };
23804
24027
  }
23805
24028
  return { eligible: true };
@@ -23808,24 +24031,24 @@ function isNumericField(field) {
23808
24031
  const numericTypes = /* @__PURE__ */ new Set(["num", "numstr", "numstr_comma"]);
23809
24032
  return field.types.length > 0 && field.types.every((type) => numericTypes.has(type.split(":")[0]));
23810
24033
  }
23811
- function defaultDimensionLabel(path26) {
23812
- const words = path26.split(/[._-]+/).filter(Boolean).join(" ");
23813
- return words ? `${words[0].toUpperCase()}${words.slice(1)}` : path26;
24034
+ function defaultDimensionLabel(path27) {
24035
+ const words = path27.split(/[._-]+/).filter(Boolean).join(" ");
24036
+ return words ? `${words[0].toUpperCase()}${words.slice(1)}` : path27;
23814
24037
  }
23815
- function quoteShellArgument(value) {
23816
- return "'" + value.replaceAll("'", "'\\''") + "'";
24038
+ function quoteShellArgument(value2) {
24039
+ return "'" + value2.replaceAll("'", "'\\''") + "'";
23817
24040
  }
23818
- function createDimensionInvocation(path26, eventName) {
23819
- return `apex discover --create-dimension ${quoteShellArgument(path26)} --event ${quoteShellArgument(eventName)}`;
24041
+ function createDimensionInvocation(path27, eventName) {
24042
+ return `apex discover --create-dimension ${quoteShellArgument(path27)} --event ${quoteShellArgument(eventName)}`;
23820
24043
  }
23821
- function resolveDimensionObservation(command, report, path26, eventName) {
24044
+ function resolveDimensionObservation(command, report, path27, eventName) {
23822
24045
  const matches = report.data_layer.flatMap(
23823
- (event) => event.fields.filter((field) => field.path === path26).map((field) => ({ event, field }))
24046
+ (event) => event.fields.filter((field) => field.path === path27).map((field) => ({ event, field }))
23824
24047
  );
23825
24048
  if (!matches.length) {
23826
24049
  fail(
23827
24050
  command,
23828
- `Path ${JSON.stringify(path26)} was not found in the current discovery report. Run apex discover and copy an observed path exactly.`,
24051
+ `Path ${JSON.stringify(path27)} was not found in the current discovery report. Run apex discover and copy an observed path exactly.`,
23829
24052
  EXIT_CODES.validation
23830
24053
  );
23831
24054
  }
@@ -23835,7 +24058,7 @@ function resolveDimensionObservation(command, report, path26, eventName) {
23835
24058
  if (!eventMatches.length) {
23836
24059
  fail(
23837
24060
  command,
23838
- `Path ${JSON.stringify(path26)} was not observed on event ${JSON.stringify(eventName)}. Run apex discover and copy the event name exactly.`,
24061
+ `Path ${JSON.stringify(path27)} was not observed on event ${JSON.stringify(eventName)}. Run apex discover and copy the event name exactly.`,
23839
24062
  EXIT_CODES.validation
23840
24063
  );
23841
24064
  }
@@ -23843,7 +24066,7 @@ function resolveDimensionObservation(command, report, path26, eventName) {
23843
24066
  if (layers.length > 1) {
23844
24067
  fail(
23845
24068
  command,
23846
- `Path ${JSON.stringify(path26)} on event ${JSON.stringify(eventName)} was observed on multiple data layers: ${layers.join(", ")}. Dimensions bind to one layer; this ambiguity cannot be resolved automatically \u2014 capture the value under one layer, or define the dimension in the dashboard with the data layer name set explicitly.`,
24069
+ `Path ${JSON.stringify(path27)} on event ${JSON.stringify(eventName)} was observed on multiple data layers: ${layers.join(", ")}. Dimensions bind to one layer; this ambiguity cannot be resolved automatically \u2014 capture the value under one layer, or define the dimension in the dashboard with the data layer name set explicitly.`,
23847
24070
  EXIT_CODES.validation
23848
24071
  );
23849
24072
  }
@@ -23855,7 +24078,7 @@ function resolveDimensionObservation(command, report, path26, eventName) {
23855
24078
  if (namedEvents.length > 1) {
23856
24079
  fail(
23857
24080
  command,
23858
- `Path ${JSON.stringify(path26)} was observed on multiple events: ${namedEvents.join(", ")}. Retry with --event <name>.`,
24081
+ `Path ${JSON.stringify(path27)} was observed on multiple events: ${namedEvents.join(", ")}. Retry with --event <name>.`,
23859
24082
  EXIT_CODES.validation
23860
24083
  );
23861
24084
  }
@@ -23864,7 +24087,7 @@ function resolveDimensionObservation(command, report, path26, eventName) {
23864
24087
  if (layers.length > 1) {
23865
24088
  fail(
23866
24089
  command,
23867
- `Path ${JSON.stringify(path26)} on event ${JSON.stringify(namedEvents[0] ?? "")} was observed on multiple data layers: ${layers.join(", ")}. Dimensions bind to one layer; this ambiguity cannot be resolved automatically \u2014 capture the value under one layer, or define the dimension in the dashboard with the data layer name set explicitly.`,
24090
+ `Path ${JSON.stringify(path27)} on event ${JSON.stringify(namedEvents[0] ?? "")} was observed on multiple data layers: ${layers.join(", ")}. Dimensions bind to one layer; this ambiguity cannot be resolved automatically \u2014 capture the value under one layer, or define the dimension in the dashboard with the data layer name set explicitly.`,
23868
24091
  EXIT_CODES.validation
23869
24092
  );
23870
24093
  }
@@ -23899,9 +24122,9 @@ function renderDiscovery(report) {
23899
24122
  `
23900
24123
  ${event.event || "(unnamed event)"} [${event.dlName}] \u2014 ${event.count} observation(s)${event.matched ? " \u2014 matched" : ""}; t_ms p50=${event.t_ms_p50 ?? "n/a"}, p95=${event.t_ms_p95 ?? "n/a"}, pre-init=${event.pre_init_count}`
23901
24124
  );
23902
- for (const path26 of event.paths)
24125
+ for (const path27 of event.paths)
23903
24126
  lines.push(
23904
- ` URL ${path26.path}: ${path26.pageviews} pageviews, ${path26.count} pushes, ${path26.pspReturn_count} PSP returns`
24127
+ ` URL ${path27.path}: ${path27.pageviews} pageviews, ${path27.count} pushes, ${path27.pspReturn_count} PSP returns`
23905
24128
  );
23906
24129
  for (const field of event.fields) {
23907
24130
  lines.push(
@@ -23964,7 +24187,7 @@ var discoverCommand = new Command("discover").description("Read back the trackin
23964
24187
  let report;
23965
24188
  let apiSucceeded = false;
23966
24189
  let discoveryCredentials;
23967
- let apiFailure2;
24190
+ let apiFailure3;
23968
24191
  try {
23969
24192
  discoveryCredentials = requireCredentials();
23970
24193
  const result = await discoverTrackingSchema(discoveryCredentials, minutes);
@@ -23972,24 +24195,24 @@ var discoverCommand = new Command("discover").description("Read back the trackin
23972
24195
  report = result.data;
23973
24196
  apiSucceeded = true;
23974
24197
  } else
23975
- apiFailure2 = {
24198
+ apiFailure3 = {
23976
24199
  message: result.error ?? "Discovery API unavailable",
23977
24200
  status: result.status,
23978
24201
  details: result.errorDetails
23979
24202
  };
23980
24203
  } catch (error) {
23981
- apiFailure2 = {
24204
+ apiFailure3 = {
23982
24205
  message: error instanceof Error ? error.message : String(error),
23983
24206
  ...error instanceof CliError ? { details: error.details, cliError: error } : {}
23984
24207
  };
23985
24208
  }
23986
24209
  if (!report && (!gtmInput || opts.createDimension)) {
23987
- if (apiFailure2?.cliError) throw apiFailure2.cliError;
24210
+ if (apiFailure3?.cliError) throw apiFailure3.cliError;
23988
24211
  fail(
23989
24212
  this,
23990
- apiFailure2?.message ?? "Failed to discover tracking schema",
23991
- classifyStatus(apiFailure2?.status ?? 0),
23992
- apiFailure2?.details
24213
+ apiFailure3?.message ?? "Failed to discover tracking schema",
24214
+ classifyStatus(apiFailure3?.status ?? 0),
24215
+ apiFailure3?.details
23993
24216
  );
23994
24217
  }
23995
24218
  report ??= {
@@ -24004,7 +24227,7 @@ var discoverCommand = new Command("discover").description("Read back the trackin
24004
24227
  trigger_diagnoses: [],
24005
24228
  storage: [],
24006
24229
  notes: [
24007
- `GTM static analysis completed without discovery API data: ${apiFailure2?.message ?? "platform credentials were not provided"}`
24230
+ `GTM static analysis completed without discovery API data: ${apiFailure3?.message ?? "platform credentials were not provided"}`
24008
24231
  ]
24009
24232
  };
24010
24233
  if (gtmInput) {
@@ -24042,9 +24265,9 @@ var discoverCommand = new Command("discover").description("Read back the trackin
24042
24265
  if (!apiSucceeded || !discoveryCredentials) {
24043
24266
  fail(
24044
24267
  this,
24045
- apiFailure2?.message ?? "Discovery API data is required to create a dimension",
24046
- classifyStatus(apiFailure2?.status ?? 0),
24047
- apiFailure2?.details
24268
+ apiFailure3?.message ?? "Discovery API data is required to create a dimension",
24269
+ classifyStatus(apiFailure3?.status ?? 0),
24270
+ apiFailure3?.details
24048
24271
  );
24049
24272
  }
24050
24273
  const observation = resolveDimensionObservation(
@@ -24114,16 +24337,16 @@ var discoverCommand = new Command("discover").description("Read back the trackin
24114
24337
  });
24115
24338
 
24116
24339
  // src/commands/skills.ts
24117
- var import_node_fs26 = __toESM(require("node:fs"));
24118
- var import_node_path23 = __toESM(require("node:path"));
24340
+ var import_node_fs27 = __toESM(require("node:fs"));
24341
+ var import_node_path24 = __toESM(require("node:path"));
24119
24342
  function packageRoot() {
24120
24343
  const candidates = [
24121
- import_node_path23.default.resolve(__dirname, ".."),
24122
- import_node_path23.default.resolve(import_node_path23.default.dirname(process.argv[1] ?? process.cwd()), ".."),
24123
- import_node_path23.default.resolve(process.cwd(), "packages/cli")
24344
+ import_node_path24.default.resolve(__dirname, ".."),
24345
+ import_node_path24.default.resolve(import_node_path24.default.dirname(process.argv[1] ?? process.cwd()), ".."),
24346
+ import_node_path24.default.resolve(process.cwd(), "packages/cli")
24124
24347
  ];
24125
24348
  for (const candidate of candidates) {
24126
- if (import_node_fs26.default.existsSync(import_node_path23.default.join(candidate, "AGENTS.md"))) return candidate;
24349
+ if (import_node_fs27.default.existsSync(import_node_path24.default.join(candidate, "AGENTS.md"))) return candidate;
24127
24350
  }
24128
24351
  throw new Error(
24129
24352
  `Apex CLI package files not found. Looked for AGENTS.md in: ${candidates.join(", ")}`
@@ -24132,19 +24355,19 @@ function packageRoot() {
24132
24355
  function skillPaths() {
24133
24356
  const root = packageRoot();
24134
24357
  return {
24135
- agents: import_node_path23.default.join(root, "AGENTS.md"),
24136
- skill: import_node_path23.default.join(root, "skills", "apex-cli", "SKILL.md")
24358
+ agents: import_node_path24.default.join(root, "AGENTS.md"),
24359
+ skill: import_node_path24.default.join(root, "skills", "apex-cli", "SKILL.md")
24137
24360
  };
24138
24361
  }
24139
24362
  function installSkill(paths, targetRoot) {
24140
- const missing = [paths.skill, paths.agents].filter((filePath) => !import_node_fs26.default.existsSync(filePath));
24363
+ const missing = [paths.skill, paths.agents].filter((filePath) => !import_node_fs27.default.existsSync(filePath));
24141
24364
  if (missing.length > 0) {
24142
24365
  throw new Error(`Apex CLI package files not found. Missing: ${missing.join(", ")}`);
24143
24366
  }
24144
- const target = import_node_path23.default.resolve(targetRoot, "apex-cli");
24145
- import_node_fs26.default.mkdirSync(target, { recursive: true });
24146
- import_node_fs26.default.copyFileSync(paths.skill, import_node_path23.default.join(target, "SKILL.md"));
24147
- import_node_fs26.default.copyFileSync(paths.agents, import_node_path23.default.join(target, "AGENTS.md"));
24367
+ const target = import_node_path24.default.resolve(targetRoot, "apex-cli");
24368
+ import_node_fs27.default.mkdirSync(target, { recursive: true });
24369
+ import_node_fs27.default.copyFileSync(paths.skill, import_node_path24.default.join(target, "SKILL.md"));
24370
+ import_node_fs27.default.copyFileSync(paths.agents, import_node_path24.default.join(target, "AGENTS.md"));
24148
24371
  return target;
24149
24372
  }
24150
24373
  var skillsCommand = new Command("skills").description("Print or install the Apex CLI agent skill files").option("--install", "Copy the Apex CLI skill into ./.claude/skills/apex-cli").option("--target <dir>", "Install target skills directory", ".claude/skills").option("--json", "Print JSON").action(function action71(opts) {
@@ -24179,9 +24402,9 @@ function validateMoveInput(shopIds, toOrgId) {
24179
24402
 
24180
24403
  // src/commands/admin.ts
24181
24404
  var uuid2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
24182
- function switchValue(value) {
24183
- if (value === "on") return true;
24184
- if (value === "off") return false;
24405
+ function switchValue(value2) {
24406
+ if (value2 === "on") return true;
24407
+ if (value2 === "off") return false;
24185
24408
  throw new Error("Use on or off");
24186
24409
  }
24187
24410
  var settingsGet = new Command("settings").description("Show platform operator settings").action(async function() {
@@ -24250,8 +24473,8 @@ async function confirmArchive(command, shopId, force) {
24250
24473
  `apex admin shops archive ${JSON.stringify(shopId)} --force`
24251
24474
  );
24252
24475
  }
24253
- const readline3 = await import("node:readline");
24254
- const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
24476
+ const readline4 = await import("node:readline");
24477
+ const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
24255
24478
  const answer = await new Promise((resolve2) => {
24256
24479
  rl.question("Archive this shop? Apex delivery will be disabled. [y/N] ", resolve2);
24257
24480
  });
@@ -24292,7 +24515,115 @@ var restore2 = new Command("restore").description("Restore an archived shop").ar
24292
24515
  () => console.log("Shop restored. Delivery remains controlled by the kill switch.")
24293
24516
  );
24294
24517
  });
24295
- var shops = new Command("shops").description("Archive and restore shops on the platform admin plane").addCommand(archive2).addCommand(restore2);
24518
+ function settingValueText(value2) {
24519
+ return value2 === null ? "null" : typeof value2 === "object" ? JSON.stringify(value2) : String(value2);
24520
+ }
24521
+ function printShopSettings(settings2) {
24522
+ printTable(
24523
+ ["KEY", "VALUE", "OVERRIDE", "GROUP"],
24524
+ settings2.map((entry) => [
24525
+ entry.key,
24526
+ settingValueText(entry.value),
24527
+ settingValueText(entry.override),
24528
+ entry.group
24529
+ ])
24530
+ );
24531
+ }
24532
+ async function loadShopSettings(command, shopRef) {
24533
+ const res = await getAdminShopSettings(requireUserCredentials(), shopRef);
24534
+ if (!res.ok || !res.data) {
24535
+ const candidates = res.errorDetails?.candidates;
24536
+ const hint = res.status === 409 && Array.isArray(candidates) ? ` Candidate IDs: ${candidates.join(", ")}. Use --shop <uuid>.` : "";
24537
+ fail(
24538
+ command,
24539
+ `${res.error ?? "Failed to read shop settings"}${hint}`,
24540
+ classifyStatus(res.status),
24541
+ res.errorDetails
24542
+ );
24543
+ }
24544
+ return res.data;
24545
+ }
24546
+ function findShopSetting(command, settings2, key) {
24547
+ const entry = settings2.find((setting) => setting.key === key);
24548
+ if (!entry)
24549
+ fail(
24550
+ command,
24551
+ `Unknown shop setting ${key}. Registry keys: ${settings2.map((setting) => setting.key).join(", ")}`,
24552
+ 3
24553
+ );
24554
+ return entry;
24555
+ }
24556
+ var shopSettings = new Command("settings").description(
24557
+ "Read and write registered per-shop settings"
24558
+ );
24559
+ shopSettings.addCommand(
24560
+ new Command("list").description("List every registered shop setting").requiredOption("--shop <uuid-or-domain>").option("--json", "Output JSON").action(async function(opts) {
24561
+ const res = await loadShopSettings(this, opts.shop);
24562
+ output(this, res, () => printShopSettings(res.data.settings));
24563
+ })
24564
+ );
24565
+ shopSettings.addCommand(
24566
+ new Command("get").description("Read one registered shop setting").requiredOption("--shop <uuid-or-domain>").requiredOption("--key <key>").option("--json", "Output JSON").action(async function(opts) {
24567
+ const res = await loadShopSettings(this, opts.shop);
24568
+ const entry = findShopSetting(this, res.data.settings, opts.key);
24569
+ output(this, { data: { ...res.data, settings: [entry] } }, () => printShopSettings([entry]));
24570
+ })
24571
+ );
24572
+ shopSettings.addCommand(
24573
+ new Command("set").description("Write a registered shop setting through the audited admin path").requiredOption("--shop <uuid-or-domain>").requiredOption("--key <key>").requiredOption("--value <value>").option("--reason <text>", "Audit reason").option("--expected-version <v>", "Expected storage version").option("--confirm", "Confirm sensitive setting change").option("--json", "Output JSON").action(async function(opts) {
24574
+ const resolved = (await loadShopSettings(this, opts.shop)).data;
24575
+ const entry = findShopSetting(this, resolved.settings, opts.key);
24576
+ let value2 = opts.value;
24577
+ if (opts.value === "null") value2 = null;
24578
+ else if (entry.value_type === "boolean") {
24579
+ if (["on", "true"].includes(opts.value)) value2 = true;
24580
+ else if (["off", "false"].includes(opts.value)) value2 = false;
24581
+ else fail(this, "Boolean values must be on, off, true or false", 3);
24582
+ } else if (entry.value_type === "number") {
24583
+ if (!opts.value.trim() || !Number.isFinite(Number(opts.value)))
24584
+ fail(this, "Number values must be finite numbers", 3);
24585
+ value2 = Number(opts.value);
24586
+ }
24587
+ if (entry.sensitive && !opts.confirm) {
24588
+ const quote = (text2) => "'" + text2.replaceAll("'", `'"'"'`) + "'";
24589
+ const args = [
24590
+ `--shop ${quote(resolved.shop_id)}`,
24591
+ `--key ${quote(opts.key)}`,
24592
+ `--value ${quote(opts.value)}`
24593
+ ];
24594
+ if (opts.reason !== void 0) args.push(`--reason ${quote(opts.reason)}`);
24595
+ if (opts.expectedVersion !== void 0)
24596
+ args.push(`--expected-version ${quote(opts.expectedVersion)}`);
24597
+ if (this.optsWithGlobals().json) args.push("--json");
24598
+ confirmationRequired(
24599
+ this,
24600
+ "--confirm is required because this changes a sensitive shop setting",
24601
+ `apex admin shops settings set ${args.join(" ")} --confirm`
24602
+ );
24603
+ }
24604
+ const res = await setAdminShopSetting(requireUserCredentials(), resolved.shop_id, {
24605
+ key: opts.key,
24606
+ value: value2,
24607
+ ...opts.reason !== void 0 ? { reason: opts.reason } : {},
24608
+ ...opts.expectedVersion !== void 0 ? { expectedVersion: opts.expectedVersion } : {}
24609
+ });
24610
+ if (!res.ok || !res.data)
24611
+ fail(
24612
+ this,
24613
+ res.error ?? "Failed to write shop setting",
24614
+ classifyStatus(res.status),
24615
+ res.errorDetails
24616
+ );
24617
+ if (res.data.data?.shop_id !== resolved.shop_id)
24618
+ fail(this, "The write response has a different shop identity", 2);
24619
+ output(
24620
+ this,
24621
+ res.data,
24622
+ () => console.log(`Setting ${opts.key} set to ${settingValueText(value2)} on ${resolved.domain}.`)
24623
+ );
24624
+ })
24625
+ );
24626
+ var shops = new Command("shops").description("Manage shops and their settings on the platform admin plane").addCommand(archive2).addCommand(restore2).addCommand(shopSettings);
24296
24627
  var create6 = new Command("create").description("Create an internal, demo or dogfood account").requiredOption("--name <text>").requiredOption("--category <category>", "internal, demo or dogfood").option("--type <type>", "company or agency", "company").option("--plan <plan>", "self_managed, apex_managed or drip_managed", "self_managed").option("--domain <host>").option("--platform <platform>", "shopify, shopware, woo or other").option("--claim-shop <uuid>").option("--owner <email>").option("--consultant <uuid>", "Platform access ID").option("--consultant-title <text>").requiredOption("--reason <text>", "Audit reason, 8 to 500 characters").option("--confirm", "Confirm account creation").option("--json", "Output JSON").action(async function(opts) {
24297
24628
  if (opts.category === "customer") fail(this, "Create customer accounts in Admin, Links", 3);
24298
24629
  if (!["internal", "demo", "dogfood"].includes(opts.category))
@@ -24346,7 +24677,7 @@ var create6 = new Command("create").description("Create an internal, demo or dog
24346
24677
  ["consultant", opts.consultant],
24347
24678
  ["consultant-title", opts.consultantTitle]
24348
24679
  ];
24349
- const retry = flags.filter((entry) => entry[1] !== void 0).map(([flag, value]) => `--${flag} '${value.replaceAll("'", "'\\''")}'`).join(" ");
24680
+ const retry = flags.filter((entry) => entry[1] !== void 0).map(([flag, value2]) => `--${flag} '${value2.replaceAll("'", "'\\''")}'`).join(" ");
24350
24681
  confirmationRequired(
24351
24682
  this,
24352
24683
  "--confirm is required to create an account",
@@ -24398,7 +24729,7 @@ var setCategory = new Command("set-category").description("Change an existing ac
24398
24729
  if (reason2.length < 8 || reason2.length > 500)
24399
24730
  fail(this, "--reason must be 8 to 500 characters", 3);
24400
24731
  if (!opts.confirm) {
24401
- const quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
24732
+ const quote = (value2) => `'${value2.replaceAll("'", "'\\''")}'`;
24402
24733
  confirmationRequired(
24403
24734
  this,
24404
24735
  "--confirm is required to change an account category",
@@ -24430,7 +24761,7 @@ var setManagedBy = new Command("set-managed-by").description("Assign or clear a
24430
24761
  if (reason2.length < 8 || reason2.length > 500)
24431
24762
  fail(this, "--reason must be 8 to 500 characters", 3);
24432
24763
  if (!opts.confirm) {
24433
- const quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
24764
+ const quote = (value2) => `'${value2.replaceAll("'", "'\\''")}'`;
24434
24765
  confirmationRequired(
24435
24766
  this,
24436
24767
  "--confirm is required to change a managing agency",
@@ -24465,7 +24796,7 @@ var setWorkspaceType = new Command("set-workspace-type").description("Change a w
24465
24796
  if (reason2.length < 8 || reason2.length > 500)
24466
24797
  fail(this, "--reason must be 8 to 500 characters", 3);
24467
24798
  if (!opts.confirm) {
24468
- const quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
24799
+ const quote = (value2) => `'${value2.replaceAll("'", "'\\''")}'`;
24469
24800
  confirmationRequired(
24470
24801
  this,
24471
24802
  "--confirm is required to change a workspace type",
@@ -24510,7 +24841,7 @@ function storeMoveRequest(opts) {
24510
24841
  var moveStores = new Command("move-stores").description("Preview or confirm an audited set of store moves").requiredOption("--to <org-id>", "Destination organization UUID").requiredOption(
24511
24842
  "--shop <shop-id>",
24512
24843
  "Store UUID, repeat for each store",
24513
- (value, previous) => [...previous, value],
24844
+ (value2, previous) => [...previous, value2],
24514
24845
  []
24515
24846
  ).requiredOption("--reason <text>", "Audit reason, 8 to 500 characters").option("--keep-grants", "Preserve explicit store roles and overrides").option("--confirm", "Perform the move; otherwise return a read-only plan").option("--json", "Output JSON").action(async function(opts) {
24516
24847
  let request2;
@@ -24534,7 +24865,7 @@ var moveStores = new Command("move-stores").description("Preview or confirm an a
24534
24865
  output(this, res.data, () => {
24535
24866
  printTable(
24536
24867
  ["FIELD", "VALUE"],
24537
- Object.entries(res.data.data).map(([key, value]) => [key, JSON.stringify(value)])
24868
+ Object.entries(res.data.data).map(([key, value2]) => [key, JSON.stringify(value2)])
24538
24869
  );
24539
24870
  });
24540
24871
  });
@@ -24560,8 +24891,8 @@ async function confirm(c, force, label, retry) {
24560
24891
  if (force) return true;
24561
24892
  if (!process.stdin.isTTY || !process.stdout.isTTY)
24562
24893
  confirmationRequired(c, `${label} requires confirmation in non-TTY mode.`, retry);
24563
- const readline3 = await import("node:readline");
24564
- const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
24894
+ const readline4 = await import("node:readline");
24895
+ const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
24565
24896
  const answer = await new Promise(
24566
24897
  (resolve2) => rl.question(source_default.yellow(`${label}? [y/N] `), resolve2)
24567
24898
  );
@@ -24800,6 +25131,48 @@ ${res.data.data.avatarDataUrl ?? "(no avatar)"}`
24800
25131
  }).addCommand(set6);
24801
25132
  var accountCommand = new Command("account").description("Manage your Apex account").addCommand(profile2);
24802
25133
 
25134
+ // src/commands/commerce.ts
25135
+ async function run3(command, params) {
25136
+ const response = await lookupCommerceCatalog(requireCredentials(), params);
25137
+ if (!response.ok || !response.data)
25138
+ fail(
25139
+ command,
25140
+ response.error ?? "Catalog lookup failed",
25141
+ classifyStatus(response.status),
25142
+ response.errorDetails
25143
+ );
25144
+ output(command, response.data, () => {
25145
+ const data = response.data.data;
25146
+ const products = data.mode === "product" ? [data.product] : data.products;
25147
+ const rows = products.flatMap(
25148
+ (product) => product.variants.map((variant) => [
25149
+ variant.id,
25150
+ variant.title,
25151
+ variant.sku ?? "",
25152
+ variant.price,
25153
+ variant.unit_cost ?? "unknown",
25154
+ // Search results carry no exclusion data; never present them as eligible.
25155
+ variant.price_test_exclusion ?? "unknown"
25156
+ ])
25157
+ );
25158
+ printTable(
25159
+ ["GID", "TITLE", "SKU", "PRICE", "COST", "EXCLUSION"],
25160
+ rows,
25161
+ [42, 24, 18, 12, 12, 14]
25162
+ );
25163
+ });
25164
+ }
25165
+ var search = new Command("search").description("Search the commerce product catalog").argument("[query]", "Product search query").option("--cursor <cursor>").option("--limit <limit>", "Products per page", (v) => Number(v)).action(async function(query, opts) {
25166
+ await run3(this, { query, ...opts });
25167
+ });
25168
+ var get10 = new Command("get").description("Get one product and its variants").argument("[handle]", "Exact product handle").option("--product-id <id>", "Shopify product ID").option("--cursor <cursor>").action(async function(handle, opts) {
25169
+ if (!handle && !opts.productId || handle && opts.productId)
25170
+ fail(this, "Provide exactly one of <handle> or --product-id", 3);
25171
+ await run3(this, { handle, product_id: opts.productId, cursor: opts.cursor });
25172
+ });
25173
+ var catalog = new Command("catalog").description("Look up products for commerce drafts").addCommand(search).addCommand(get10);
25174
+ var commerceCommand = new Command("commerce").description("Commerce catalog tools").addCommand(catalog);
25175
+
24803
25176
  // src/commands/keys.ts
24804
25177
  function selected() {
24805
25178
  const credentials = requireUserCredentials();
@@ -24884,17 +25257,17 @@ async function readResponseText(res) {
24884
25257
  let totalBytes = 0;
24885
25258
  try {
24886
25259
  while (totalBytes < MAX_RESPONSE_BYTES) {
24887
- const { done: done2, value } = await reader.read();
25260
+ const { done: done2, value: value2 } = await reader.read();
24888
25261
  if (done2) break;
24889
25262
  const remainingBytes = MAX_RESPONSE_BYTES - totalBytes;
24890
- if (value.byteLength >= remainingBytes) {
24891
- chunks.push(value.byteLength === remainingBytes ? value : value.slice(0, remainingBytes));
25263
+ if (value2.byteLength >= remainingBytes) {
25264
+ chunks.push(value2.byteLength === remainingBytes ? value2 : value2.slice(0, remainingBytes));
24892
25265
  totalBytes += remainingBytes;
24893
25266
  await reader.cancel().catch(() => void 0);
24894
25267
  break;
24895
25268
  }
24896
- chunks.push(value);
24897
- totalBytes += value.byteLength;
25269
+ chunks.push(value2);
25270
+ totalBytes += value2.byteLength;
24898
25271
  }
24899
25272
  } finally {
24900
25273
  reader.releaseLock();
@@ -24924,8 +25297,8 @@ async function fetchText(url) {
24924
25297
  });
24925
25298
  return { status: res.status, text: await readResponseText(res), finalUrl: res.url };
24926
25299
  }
24927
- function abs(base, path26) {
24928
- return new URL(path26, base).toString();
25300
+ function abs(base, path27) {
25301
+ return new URL(path27, base).toString();
24929
25302
  }
24930
25303
  function looksLikeShopifyCart(text2) {
24931
25304
  try {
@@ -24945,9 +25318,9 @@ async function collectSignals(url) {
24945
25318
  const chunks = [`__apex_primary_status_${primary.status}__`, primary.text];
24946
25319
  const protectedHit = primary.status === 403 || primary.status === 429 || matchDetectionMarkers(primary.text, "protected").length > 0;
24947
25320
  if (!protectedHit) {
24948
- for (const path26 of ["/cart.js"]) {
25321
+ for (const path27 of ["/cart.js"]) {
24949
25322
  try {
24950
- const secondary = await fetchText(abs(primary.finalUrl || url, path26));
25323
+ const secondary = await fetchText(abs(primary.finalUrl || url, path27));
24951
25324
  if (secondary.status >= 200 && secondary.status < 300 && looksLikeShopifyCart(secondary.text)) {
24952
25325
  chunks.push("__apex_secondary_shopify_cart_js__", secondary.text.slice(0, 2e3));
24953
25326
  }
@@ -25133,7 +25506,7 @@ var list14 = new Command("list").alias("ls").description(
25133
25506
  var create8 = new Command("create").description(`Create a webhook. Prints the signing secret once. Signature docs: ${SIGNATURE_DOC}`).requiredOption("--url <url>", "HTTPS callback URL").option(
25134
25507
  "--event <event>",
25135
25508
  "Webhook event to subscribe to; repeat for multiple events",
25136
- (value, previous = []) => [...previous, value],
25509
+ (value2, previous = []) => [...previous, value2],
25137
25510
  []
25138
25511
  ).action(async function action73(opts) {
25139
25512
  const events = selectedEvents(opts);
@@ -25188,7 +25561,7 @@ var deliveries = new Command("deliveries").description("List webhook deliveries
25188
25561
  var update5 = new Command("update").description("Update a webhook URL, events, or active state").argument("<id>", "Webhook id").option("--url <url>", "HTTPS callback URL").option(
25189
25562
  "--event <event>",
25190
25563
  "Replacement event; repeat for multiple events",
25191
- (value, previous = []) => [...previous, value],
25564
+ (value2, previous = []) => [...previous, value2],
25192
25565
  []
25193
25566
  ).option("--active", "Enable the webhook").option("--inactive", "Disable the webhook").action(async function action76(id, opts) {
25194
25567
  if (opts.active && opts.inactive)
@@ -25242,10 +25615,10 @@ var webhooksCommand = new Command("webhooks").description("Manage shop webhooks"
25242
25615
 
25243
25616
  // src/commands/simulate.ts
25244
25617
  init_source();
25245
- var import_node_fs27 = __toESM(require("node:fs"));
25246
- var import_node_path24 = __toESM(require("node:path"));
25618
+ var import_node_fs28 = __toESM(require("node:fs"));
25619
+ var import_node_path25 = __toESM(require("node:path"));
25247
25620
  function readJson2(file) {
25248
- const text2 = file === "-" ? import_node_fs27.default.readFileSync(0, "utf8") : import_node_fs27.default.readFileSync(import_node_path24.default.resolve(file), "utf8");
25621
+ const text2 = file === "-" ? import_node_fs28.default.readFileSync(0, "utf8") : import_node_fs28.default.readFileSync(import_node_path25.default.resolve(file), "utf8");
25249
25622
  try {
25250
25623
  return JSON.parse(text2);
25251
25624
  } catch (error) {
@@ -25257,21 +25630,21 @@ function readJson2(file) {
25257
25630
  function plural(count2, singular3) {
25258
25631
  return `${count2} ${singular3}${count2 === 1 ? "" : "s"}`;
25259
25632
  }
25260
- function isGtagEventTuple(value) {
25261
- return Array.isArray(value) && value[0] === "event" && typeof value[1] === "string";
25633
+ function isGtagEventTuple(value2) {
25634
+ return Array.isArray(value2) && value2[0] === "event" && typeof value2[1] === "string";
25262
25635
  }
25263
- function isPlainObject(value) {
25264
- if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
25265
- const prototype = Object.getPrototypeOf(value);
25636
+ function isPlainObject(value2) {
25637
+ if (value2 === null || typeof value2 !== "object" || Array.isArray(value2)) return false;
25638
+ const prototype = Object.getPrototypeOf(value2);
25266
25639
  return prototype === Object.prototype || prototype === null;
25267
25640
  }
25268
- function isExplicitPayloadBatch(value) {
25269
- if (!Array.isArray(value) || isGtagEventTuple(value)) return false;
25270
- if (value.length > 0 && value.every((entry) => isPlainObject(entry) || isGtagEventTuple(entry))) {
25641
+ function isExplicitPayloadBatch(value2) {
25642
+ if (!Array.isArray(value2) || isGtagEventTuple(value2)) return false;
25643
+ if (value2.length > 0 && value2.every((entry) => isPlainObject(entry) || isGtagEventTuple(entry))) {
25271
25644
  return true;
25272
25645
  }
25273
- if (value.length > 0 && typeof value[0] === "string") return false;
25274
- return value.some((entry) => isPlainObject(entry) || isGtagEventTuple(entry));
25646
+ if (value2.length > 0 && typeof value2[0] === "string") return false;
25647
+ return value2.some((entry) => isPlainObject(entry) || isGtagEventTuple(entry));
25275
25648
  }
25276
25649
  var simulateCommand = new Command("simulate").description("Simulate data-layer triggers without emitting events").option("--config <file>", "Trigger config JSON file").requiredOption("--payload <file|->", "Payload JSON file or stdin").option("--from-shop", "Load live triggers from the selected shop").action(async function(opts) {
25277
25650
  if (Boolean(opts.config) === Boolean(opts.fromShop)) {
@@ -25354,7 +25727,7 @@ var simulateCommand = new Command("simulate").description("Simulate data-layer t
25354
25727
  }
25355
25728
  if (!result.matches.length) {
25356
25729
  const numericPaths = result.diagnostics.numericPaths.map(
25357
- ({ path: numericPath, value }) => `${numericPath}=${value}`
25730
+ ({ path: numericPath, value: value2 }) => `${numericPath}=${value2}`
25358
25731
  ).join(", ");
25359
25732
  console.log(` numeric paths: ${numericPaths || "none"}`);
25360
25733
  }
@@ -25367,14 +25740,14 @@ var simulateCommand = new Command("simulate").description("Simulate data-layer t
25367
25740
  });
25368
25741
 
25369
25742
  // src/commands/config-resources.ts
25370
- var import_node_fs29 = __toESM(require("node:fs"));
25371
- var import_node_path26 = __toESM(require("node:path"));
25743
+ var import_node_fs30 = __toESM(require("node:fs"));
25744
+ var import_node_path27 = __toESM(require("node:path"));
25372
25745
 
25373
25746
  // src/commands/landing-pages.ts
25374
25747
  var import_node_crypto9 = __toESM(require("node:crypto"));
25375
- var import_node_fs28 = __toESM(require("node:fs"));
25376
- var import_node_path25 = __toESM(require("node:path"));
25377
- function apiFailure(command, response, fallback2) {
25748
+ var import_node_fs29 = __toESM(require("node:fs"));
25749
+ var import_node_path26 = __toESM(require("node:path"));
25750
+ function apiFailure2(command, response, fallback2) {
25378
25751
  if (!response.ok || response.data === void 0) {
25379
25752
  fail(
25380
25753
  command,
@@ -25388,13 +25761,13 @@ function sha256(body5) {
25388
25761
  return import_node_crypto9.default.createHash("sha256").update(body5).digest("hex");
25389
25762
  }
25390
25763
  function markerPath(folder) {
25391
- return import_node_path25.default.join(folder, LANDING_PAGE_CHECKOUT_MARKER);
25764
+ return import_node_path26.default.join(folder, LANDING_PAGE_CHECKOUT_MARKER);
25392
25765
  }
25393
25766
  function readMarker(folder) {
25394
25767
  const file = markerPath(folder);
25395
- if (!import_node_fs28.default.existsSync(file)) return null;
25768
+ if (!import_node_fs29.default.existsSync(file)) return null;
25396
25769
  try {
25397
- return JSON.parse(import_node_fs28.default.readFileSync(file, "utf8"));
25770
+ return JSON.parse(import_node_fs29.default.readFileSync(file, "utf8"));
25398
25771
  } catch (error) {
25399
25772
  throw new CliError(
25400
25773
  `${LANDING_PAGE_CHECKOUT_MARKER} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
@@ -25412,14 +25785,14 @@ function readMarker(folder) {
25412
25785
  }
25413
25786
  }
25414
25787
  function writeMarker(folder, marker) {
25415
- import_node_fs28.default.mkdirSync(import_node_path25.default.dirname(markerPath(folder)), { recursive: true });
25416
- import_node_fs28.default.writeFileSync(import_node_path25.default.join(folder, ".apex", ".gitignore"), "landing-page.json\n", "utf8");
25417
- import_node_fs28.default.writeFileSync(markerPath(folder), `${JSON.stringify(marker, null, 2)}
25788
+ import_node_fs29.default.mkdirSync(import_node_path26.default.dirname(markerPath(folder)), { recursive: true });
25789
+ import_node_fs29.default.writeFileSync(import_node_path26.default.join(folder, ".apex", ".gitignore"), "landing-page.json\n", "utf8");
25790
+ import_node_fs29.default.writeFileSync(markerPath(folder), `${JSON.stringify(marker, null, 2)}
25418
25791
  `, "utf8");
25419
25792
  }
25420
25793
  function requireCheckout(command, folderArg) {
25421
- const folder = import_node_path25.default.resolve(process.cwd(), folderArg);
25422
- const marker = import_node_fs28.default.existsSync(folder) && import_node_fs28.default.statSync(folder).isDirectory() ? readMarker(folder) : null;
25794
+ const folder = import_node_path26.default.resolve(process.cwd(), folderArg);
25795
+ const marker = import_node_fs29.default.existsSync(folder) && import_node_fs29.default.statSync(folder).isDirectory() ? readMarker(folder) : null;
25423
25796
  if (!marker) {
25424
25797
  fail(command, `${folderArg} is not a landing-page checkout.`, EXIT_CODES.validation, {
25425
25798
  code: "validation_failed",
@@ -25431,8 +25804,8 @@ function requireCheckout(command, folderArg) {
25431
25804
  return { folder, marker };
25432
25805
  }
25433
25806
  function resolvePageId(target) {
25434
- const folder = import_node_path25.default.resolve(process.cwd(), target);
25435
- if (import_node_fs28.default.existsSync(folder) && import_node_fs28.default.statSync(folder).isDirectory()) {
25807
+ const folder = import_node_path26.default.resolve(process.cwd(), target);
25808
+ if (import_node_fs29.default.existsSync(folder) && import_node_fs29.default.statSync(folder).isDirectory()) {
25436
25809
  const marker = readMarker(folder);
25437
25810
  if (marker) return marker.landingPageId;
25438
25811
  throw new CliError(
@@ -25454,16 +25827,16 @@ function resolvePageId(target) {
25454
25827
  function readCheckoutFiles(folder) {
25455
25828
  const files = [];
25456
25829
  const visit2 = (directory) => {
25457
- for (const entry of import_node_fs28.default.readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
25458
- const absolute = import_node_path25.default.join(directory, entry.name);
25459
- const relative = import_node_path25.default.relative(folder, absolute).split(import_node_path25.default.sep).join("/");
25830
+ for (const entry of import_node_fs29.default.readdirSync(directory, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
25831
+ const absolute = import_node_path26.default.join(directory, entry.name);
25832
+ const relative = import_node_path26.default.relative(folder, absolute).split(import_node_path26.default.sep).join("/");
25460
25833
  if (!isLandingPageCheckoutPath(relative)) continue;
25461
25834
  if (entry.isDirectory()) visit2(absolute);
25462
25835
  else if (entry.isFile()) {
25463
25836
  try {
25464
25837
  validateLandingPageLocalFiles([
25465
25838
  ...files,
25466
- { path: relative, bytes: import_node_fs28.default.statSync(absolute).size, sha256: "" }
25839
+ { path: relative, bytes: import_node_fs29.default.statSync(absolute).size, sha256: "" }
25467
25840
  ]);
25468
25841
  } catch (error) {
25469
25842
  throw new CliError(
@@ -25471,7 +25844,7 @@ function readCheckoutFiles(folder) {
25471
25844
  EXIT_CODES.validation
25472
25845
  );
25473
25846
  }
25474
- const body5 = import_node_fs28.default.readFileSync(absolute);
25847
+ const body5 = import_node_fs29.default.readFileSync(absolute);
25475
25848
  files.push({ path: relative, sha256: sha256(body5), bytes: body5.byteLength, body: body5 });
25476
25849
  }
25477
25850
  }
@@ -25488,8 +25861,8 @@ function readCheckoutFiles(folder) {
25488
25861
  return files;
25489
25862
  }
25490
25863
  function readManifest2(command, folder) {
25491
- const file = import_node_path25.default.join(folder, LANDING_PAGE_MANIFEST_FILE);
25492
- if (!import_node_fs28.default.existsSync(file)) {
25864
+ const file = import_node_path26.default.join(folder, LANDING_PAGE_MANIFEST_FILE);
25865
+ if (!import_node_fs29.default.existsSync(file)) {
25493
25866
  fail(
25494
25867
  command,
25495
25868
  `${LANDING_PAGE_MANIFEST_FILE} is missing from the checkout.`,
@@ -25500,7 +25873,7 @@ function readManifest2(command, folder) {
25500
25873
  );
25501
25874
  }
25502
25875
  try {
25503
- return JSON.parse(import_node_fs28.default.readFileSync(file, "utf8"));
25876
+ return JSON.parse(import_node_fs29.default.readFileSync(file, "utf8"));
25504
25877
  } catch (error) {
25505
25878
  fail(
25506
25879
  command,
@@ -25546,15 +25919,15 @@ function printPlan(plan2) {
25546
25919
  }
25547
25920
  async function confirm2(message) {
25548
25921
  if (!process.stdin.isTTY || !process.stdout.isTTY) return null;
25549
- const readline3 = await import("node:readline");
25550
- const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
25922
+ const readline4 = await import("node:readline");
25923
+ const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
25551
25924
  const answer = await new Promise((resolve2) => rl.question(`${message} [y/N] `, resolve2));
25552
25925
  rl.close();
25553
25926
  return answer.trim().toLowerCase() === "y";
25554
25927
  }
25555
25928
  function manifestDigest(folder) {
25556
- const file = import_node_path25.default.join(folder, LANDING_PAGE_MANIFEST_FILE);
25557
- return import_node_fs28.default.existsSync(file) ? sha256(import_node_fs28.default.readFileSync(file)) : null;
25929
+ const file = import_node_path26.default.join(folder, LANDING_PAGE_MANIFEST_FILE);
25930
+ return import_node_fs29.default.existsSync(file) ? sha256(import_node_fs29.default.readFileSync(file)) : null;
25558
25931
  }
25559
25932
  function localChanges(folder, marker) {
25560
25933
  const local = new Map(readCheckoutFiles(folder).map((file) => [file.path, file.sha256]));
@@ -25572,8 +25945,8 @@ function removeStaleFiles(folder, previous, next, added = []) {
25572
25945
  if (!previous) return;
25573
25946
  for (const file of [...Object.keys(previous.files), ...added]) {
25574
25947
  if (next.has(file) || !isLandingPageCheckoutPath(file)) continue;
25575
- const absolute = import_node_path25.default.resolve(folder, file);
25576
- if (absolute.startsWith(folder + import_node_path25.default.sep) && import_node_fs28.default.existsSync(absolute)) import_node_fs28.default.rmSync(absolute);
25948
+ const absolute = import_node_path26.default.resolve(folder, file);
25949
+ if (absolute.startsWith(folder + import_node_path26.default.sep) && import_node_fs29.default.existsSync(absolute)) import_node_fs29.default.rmSync(absolute);
25577
25950
  }
25578
25951
  }
25579
25952
  async function pullCheckout(command, creds, id, folder, force = false) {
@@ -25612,8 +25985,8 @@ async function pullCheckout(command, creds, id, folder, force = false) {
25612
25985
  }
25613
25986
  const api = landingPages(creds);
25614
25987
  const listing = await api.checkout(id);
25615
- apiFailure(command, listing, "Failed to pull landing page");
25616
- import_node_fs28.default.mkdirSync(folder, { recursive: true });
25988
+ apiFailure2(command, listing, "Failed to pull landing page");
25989
+ import_node_fs29.default.mkdirSync(folder, { recursive: true });
25617
25990
  const written = {};
25618
25991
  const downloaded = [];
25619
25992
  for (const batch of landingPageBatches(listing.data.files, (file) => file.bytes)) {
@@ -25621,14 +25994,14 @@ async function pullCheckout(command, creds, id, folder, force = false) {
25621
25994
  id,
25622
25995
  batch.map((file) => file.path)
25623
25996
  );
25624
- apiFailure(command, contents, "Failed to pull landing page files");
25997
+ apiFailure2(command, contents, "Failed to pull landing page files");
25625
25998
  const returned2 = new Set(contents.data.files.map((file) => file.path));
25626
25999
  const missing = batch.filter((file) => !returned2.has(file.path)).map((file) => file.path);
25627
26000
  if (missing.length)
25628
26001
  fail(command, `The server did not return ${missing.slice(0, 5).join(", ")}. Pull again.`);
25629
26002
  for (const file of contents.data.files) {
25630
- const target = import_node_path25.default.resolve(folder, file.path);
25631
- if (!target.startsWith(folder + import_node_path25.default.sep))
26003
+ const target = import_node_path26.default.resolve(folder, file.path);
26004
+ if (!target.startsWith(folder + import_node_path26.default.sep))
25632
26005
  fail(command, `Refusing to write outside the checkout: ${file.path}`);
25633
26006
  const download = file.download_url ? await fetch(file.download_url, { signal: AbortSignal.timeout(6e4) }) : null;
25634
26007
  if (download && !download.ok)
@@ -25641,7 +26014,7 @@ async function pullCheckout(command, creds, id, folder, force = false) {
25641
26014
  }
25642
26015
  if (!existing && !force) {
25643
26016
  const clobbered = downloaded.filter(
25644
- ({ target, sha256: digest }) => import_node_fs28.default.existsSync(target) && sha256(import_node_fs28.default.readFileSync(target)) !== digest
26017
+ ({ target, sha256: digest }) => import_node_fs29.default.existsSync(target) && sha256(import_node_fs29.default.readFileSync(target)) !== digest
25645
26018
  ).map((file) => file.path);
25646
26019
  if (clobbered.length) {
25647
26020
  fail(
@@ -25665,8 +26038,8 @@ async function pullCheckout(command, creds, id, folder, force = false) {
25665
26038
  }
25666
26039
  }
25667
26040
  for (const file of downloaded) {
25668
- import_node_fs28.default.mkdirSync(import_node_path25.default.dirname(file.target), { recursive: true });
25669
- import_node_fs28.default.writeFileSync(file.target, file.body);
26041
+ import_node_fs29.default.mkdirSync(import_node_path26.default.dirname(file.target), { recursive: true });
26042
+ import_node_fs29.default.writeFileSync(file.target, file.body);
25670
26043
  written[file.path] = file.sha256;
25671
26044
  }
25672
26045
  removeStaleFiles(
@@ -25675,24 +26048,24 @@ async function pullCheckout(command, creds, id, folder, force = false) {
25675
26048
  new Set(Object.keys(written)),
25676
26049
  force ? readCheckoutFiles(folder).map((file) => file.path) : []
25677
26050
  );
25678
- import_node_fs28.default.writeFileSync(
25679
- import_node_path25.default.join(folder, LANDING_PAGE_MANIFEST_FILE),
26051
+ import_node_fs29.default.writeFileSync(
26052
+ import_node_path26.default.join(folder, LANDING_PAGE_MANIFEST_FILE),
25680
26053
  `${JSON.stringify(listing.data.manifest ?? {}, null, 2)}
25681
26054
  `,
25682
26055
  "utf8"
25683
26056
  );
25684
- const contextDir = import_node_path25.default.join(folder, LANDING_PAGE_CONTEXT_DIR);
25685
- import_node_fs28.default.mkdirSync(contextDir, { recursive: true });
26057
+ const contextDir = import_node_path26.default.join(folder, LANDING_PAGE_CONTEXT_DIR);
26058
+ import_node_fs29.default.mkdirSync(contextDir, { recursive: true });
25686
26059
  const contextName = /^[a-z0-9_-]+\.json$/i;
25687
26060
  const contextEntries = Object.entries(listing.data.context ?? {}).filter(
25688
26061
  ([name]) => contextName.test(name)
25689
26062
  );
25690
26063
  const returned = new Set(contextEntries.map(([name]) => name));
25691
- for (const name of import_node_fs28.default.readdirSync(contextDir)) {
25692
- if (contextName.test(name) && !returned.has(name)) import_node_fs28.default.rmSync(import_node_path25.default.join(contextDir, name));
26064
+ for (const name of import_node_fs29.default.readdirSync(contextDir)) {
26065
+ if (contextName.test(name) && !returned.has(name)) import_node_fs29.default.rmSync(import_node_path26.default.join(contextDir, name));
25693
26066
  }
25694
- for (const [name, value] of contextEntries) {
25695
- import_node_fs28.default.writeFileSync(import_node_path25.default.join(contextDir, name), `${JSON.stringify(value, null, 2)}
26067
+ for (const [name, value2] of contextEntries) {
26068
+ import_node_fs29.default.writeFileSync(import_node_path26.default.join(contextDir, name), `${JSON.stringify(value2, null, 2)}
25696
26069
  `, "utf8");
25697
26070
  }
25698
26071
  writeMarker(folder, {
@@ -25723,8 +26096,8 @@ var create9 = new Command("create").description("Create a landing page to build
25723
26096
  ...opts.slug ? { slug: opts.slug } : {},
25724
26097
  ...opts.idea ? { idea_key: opts.idea } : {}
25725
26098
  });
25726
- apiFailure(this, created, "Failed to create landing page");
25727
- const pulled = opts.out ? await pullCheckout(this, creds, created.data.id, import_node_path25.default.resolve(process.cwd(), opts.out)) : null;
26099
+ apiFailure2(this, created, "Failed to create landing page");
26100
+ const pulled = opts.out ? await pullCheckout(this, creds, created.data.id, import_node_path26.default.resolve(process.cwd(), opts.out)) : null;
25728
26101
  output(
25729
26102
  this,
25730
26103
  { landing_page: created.data, ...pulled ? { folder: pulled.folder } : {} },
@@ -25736,7 +26109,7 @@ var create9 = new Command("create").description("Create a landing page to build
25736
26109
  });
25737
26110
  var pull = new Command("pull").description("Pull a landing page into a checkout folder").argument("<id>", "Landing page id").option("--out <folder>", "Target folder (default: a folder named after the id)").option("--force", "Overwrite changes in the checkout that are not applied").action(async function(id, opts) {
25738
26111
  const creds = requireCredentials();
25739
- const folder = import_node_path25.default.resolve(process.cwd(), opts.out ?? id);
26112
+ const folder = import_node_path26.default.resolve(process.cwd(), opts.out ?? id);
25740
26113
  const result = await pullCheckout(this, creds, id, folder, opts.force === true);
25741
26114
  output(this, result, () => {
25742
26115
  console.log(
@@ -25754,7 +26127,7 @@ var plan = new Command("plan").description("Show what applying a checkout would
25754
26127
  manifest: readManifest2(this, folder),
25755
26128
  files: declared(files)
25756
26129
  });
25757
- apiFailure(this, response, "Failed to plan landing page");
26130
+ apiFailure2(this, response, "Failed to plan landing page");
25758
26131
  output(
25759
26132
  this,
25760
26133
  { folder, landingPageId: marker.landingPageId, plan: response.data },
@@ -25768,7 +26141,7 @@ var apply = new Command("apply").description("Apply a checkout as a new version"
25768
26141
  const files = readCheckoutFiles(folder);
25769
26142
  const manifest = readManifest2(this, folder);
25770
26143
  const planned = await api.plan(marker.landingPageId, { manifest, files: declared(files) });
25771
- apiFailure(this, planned, "Failed to plan landing page");
26144
+ apiFailure2(this, planned, "Failed to plan landing page");
25772
26145
  if (!planned.data.would_change) {
25773
26146
  output(
25774
26147
  this,
@@ -25801,7 +26174,7 @@ var apply = new Command("apply").description("Apply a checkout as a new version"
25801
26174
  sha256: file.sha256,
25802
26175
  base_version_id: planned.data.base_version_id
25803
26176
  });
25804
- apiFailure(this, granted, "Failed to grant video upload");
26177
+ apiFailure2(this, granted, "Failed to grant video upload");
25805
26178
  await uploadLandingVideo(granted.data, file.body, {
25806
26179
  progress: (uploaded, total) => {
25807
26180
  console.error(`Uploading ${file.path}: ${uploaded}/${total} bytes`);
@@ -25820,7 +26193,7 @@ var apply = new Command("apply").description("Apply a checkout as a new version"
25820
26193
  encoding: "base64"
25821
26194
  }))
25822
26195
  );
25823
- apiFailure(this, uploaded, "Failed to upload landing page files");
26196
+ apiFailure2(this, uploaded, "Failed to upload landing page files");
25824
26197
  }
25825
26198
  const applied = await api.apply(marker.landingPageId, {
25826
26199
  manifest,
@@ -25847,7 +26220,7 @@ var apply = new Command("apply").description("Apply a checkout as a new version"
25847
26220
  }
25848
26221
  );
25849
26222
  }
25850
- apiFailure(this, applied, "Failed to apply landing page");
26223
+ apiFailure2(this, applied, "Failed to apply landing page");
25851
26224
  writeMarker(folder, {
25852
26225
  ...marker,
25853
26226
  versionId: applied.data.version_id,
@@ -25873,7 +26246,7 @@ var preview = new Command("preview").description("Print a signed preview link (v
25873
26246
  resolvePageId(target),
25874
26247
  versionNumber
25875
26248
  );
25876
- apiFailure(this, response, "Failed to get preview link");
26249
+ apiFailure2(this, response, "Failed to get preview link");
25877
26250
  output(this, response.data, () => console.log(response.data.preview_url));
25878
26251
  });
25879
26252
  async function versionIdFor(command, creds, id, raw) {
@@ -25882,7 +26255,7 @@ async function versionIdFor(command, creds, id, raw) {
25882
26255
  if (!Number.isInteger(number) || number < 1)
25883
26256
  fail(command, "--version must be a version number.", EXIT_CODES.validation);
25884
26257
  const versions2 = await landingPages(creds).versions(id);
25885
- apiFailure(command, versions2, "Failed to list versions");
26258
+ apiFailure2(command, versions2, "Failed to list versions");
25886
26259
  const match2 = versions2.data.find((version) => version.version_number === number);
25887
26260
  if (!match2) fail(command, `Version ${number} not found.`, EXIT_CODES.validation);
25888
26261
  return match2.id;
@@ -25902,7 +26275,7 @@ var deploy = new Command("deploy").description(
25902
26275
  ...opts.host ? { host: opts.host } : {},
25903
26276
  ...opts.path ? { path: opts.path } : {}
25904
26277
  });
25905
- apiFailure(this, response, "Failed to deploy landing page");
26278
+ apiFailure2(this, response, "Failed to deploy landing page");
25906
26279
  output(this, response.data, () => {
25907
26280
  console.log(response.data.url);
25908
26281
  console.log(`Version ${response.data.version_number} is live.`);
@@ -25910,7 +26283,7 @@ var deploy = new Command("deploy").description(
25910
26283
  }).addHelpText("after", SPLIT_KEEPS_SERVING_HELP);
25911
26284
  var versions = new Command("versions").description("List versions").argument("[folder-or-id]", "Checkout folder or landing page id", ".").action(async function(target) {
25912
26285
  const response = await landingPages(requireCredentials()).versions(resolvePageId(target));
25913
- apiFailure(this, response, "Failed to list versions");
26286
+ apiFailure2(this, response, "Failed to list versions");
25914
26287
  output(
25915
26288
  this,
25916
26289
  response.data,
@@ -25935,7 +26308,7 @@ var rollback = new Command("rollback").description("Deploy an earlier version to
25935
26308
  const response = await landingPages(requireCredentials()).rollback(resolvePageId(target), {
25936
26309
  version_number: number
25937
26310
  });
25938
- apiFailure(this, response, "Failed to roll back landing page");
26311
+ apiFailure2(this, response, "Failed to roll back landing page");
25939
26312
  output(this, response.data, () => {
25940
26313
  console.log(response.data.url);
25941
26314
  console.log(`Version ${response.data.version_number} is live.`);
@@ -25948,8 +26321,8 @@ var experiment = new Command("experiment").description("Create a draft experimen
25948
26321
  "--variant <number>",
25949
26322
  "Variant version number (default: the manifest's experiment.variant)"
25950
26323
  ).option("--name <name>", "Experiment name").option("--primary-goal <key>", "Manifest goal key to make primary (default: the first goal)").action(async function(target, opts) {
25951
- const folder = import_node_path25.default.resolve(process.cwd(), target);
25952
- const fromManifest = import_node_fs28.default.existsSync(import_node_path25.default.join(folder, LANDING_PAGE_MANIFEST_FILE)) ? readManifest2(this, folder)?.experiment ?? {} : {};
26324
+ const folder = import_node_path26.default.resolve(process.cwd(), target);
26325
+ const fromManifest = import_node_fs29.default.existsSync(import_node_path26.default.join(folder, LANDING_PAGE_MANIFEST_FILE)) ? readManifest2(this, folder)?.experiment ?? {} : {};
25953
26326
  const control = Number(opts.control ?? fromManifest.control);
25954
26327
  const variant = Number(opts.variant ?? fromManifest.variant);
25955
26328
  if (!Number.isInteger(control) || !Number.isInteger(variant) || control < 1 || variant < 1) {
@@ -25965,7 +26338,7 @@ var experiment = new Command("experiment").description("Create a draft experimen
25965
26338
  ...opts.name ? { name: opts.name } : {},
25966
26339
  ...opts.primaryGoal ? { primary_goal: opts.primaryGoal } : {}
25967
26340
  });
25968
- apiFailure(this, response, "Failed to create experiment");
26341
+ apiFailure2(this, response, "Failed to create experiment");
25969
26342
  output(this, response.data, () => {
25970
26343
  console.log(`Draft experiment ${String(response.data.experiment.id)} created.`);
25971
26344
  console.log("Start it in the Apex dashboard when it is ready.");
@@ -26009,8 +26382,8 @@ var ALLOWED_ASSET_EXTENSIONS = Object.keys(ASSET_MIME_TYPES).join(", ");
26009
26382
  var MAX_ASSET_SIZE_BYTES = 10 * 1024 * 1024;
26010
26383
  async function confirmAssetDelete(id) {
26011
26384
  if (!process.stdin.isTTY || !process.stdout.isTTY) return null;
26012
- const readline3 = await import("node:readline");
26013
- const rl = readline3.createInterface({
26385
+ const readline4 = await import("node:readline");
26386
+ const rl = readline4.createInterface({
26014
26387
  input: process.stdin,
26015
26388
  output: process.stderr
26016
26389
  });
@@ -26044,22 +26417,22 @@ function readFamily(family, label) {
26044
26417
  )
26045
26418
  );
26046
26419
  });
26047
- const get10 = new Command("get").description(`Get one ${label.slice(0, -1)}`).argument("<id>").action(async function(id) {
26420
+ const get11 = new Command("get").description(`Get one ${label.slice(0, -1)}`).argument("<id>").action(async function(id) {
26048
26421
  const r = await getConfigResource(requireCredentials(), family, id);
26049
26422
  if (!r.ok || !r.data)
26050
26423
  fail(this, r.error ?? "Failed to get resource", classifyStatus(r.status), r.errorDetails);
26051
26424
  output(this, r.data, () => show(r.data));
26052
26425
  });
26053
- return { list: list15, get: get10 };
26426
+ return { list: list15, get: get11 };
26054
26427
  }
26055
26428
  var assetReads = readFamily("assets", "assets");
26056
26429
  var upload = new Command("upload").description("Upload an asset").argument("<file>").action(async function(file) {
26057
- const absolute = import_node_path26.default.resolve(process.cwd(), file);
26058
- if (!import_node_fs29.default.existsSync(absolute)) fail(this, `File not found: ${file}`, 3);
26059
- const fileStat = import_node_fs29.default.statSync(absolute);
26430
+ const absolute = import_node_path27.default.resolve(process.cwd(), file);
26431
+ if (!import_node_fs30.default.existsSync(absolute)) fail(this, `File not found: ${file}`, 3);
26432
+ const fileStat = import_node_fs30.default.statSync(absolute);
26060
26433
  if (!fileStat.isFile()) fail(this, `File not found: ${file}`, 3);
26061
26434
  if (fileStat.size > MAX_ASSET_SIZE_BYTES) fail(this, `${file} is larger than 10 MB`, 3);
26062
- const mimeType = ASSET_MIME_TYPES[import_node_path26.default.extname(absolute).toLowerCase()];
26435
+ const mimeType = ASSET_MIME_TYPES[import_node_path27.default.extname(absolute).toLowerCase()];
26063
26436
  if (!mimeType)
26064
26437
  fail(
26065
26438
  this,
@@ -26068,8 +26441,8 @@ var upload = new Command("upload").description("Upload an asset").argument("<fil
26068
26441
  );
26069
26442
  const r = await uploadAssets(requireCredentials(), [
26070
26443
  {
26071
- name: import_node_path26.default.basename(absolute),
26072
- bytes: import_node_fs29.default.readFileSync(absolute),
26444
+ name: import_node_path27.default.basename(absolute),
26445
+ bytes: import_node_fs30.default.readFileSync(absolute),
26073
26446
  type: mimeType
26074
26447
  }
26075
26448
  ]);
@@ -26101,7 +26474,7 @@ var landingPagesCommand = new Command("landing-pages").description(
26101
26474
  for (const command of landingPageWorkspaceCommands) landingPagesCommand.addCommand(command);
26102
26475
  var snippet = new Command("snippet").description("Generate an external purchase pixel snippet").option("--provider <name>").option("--handover-param <name>").option("--global-name <name>").action(async function(opts) {
26103
26476
  const body5 = Object.fromEntries(
26104
- Object.entries(opts).filter(([, value]) => value !== void 0)
26477
+ Object.entries(opts).filter(([, value2]) => value2 !== void 0)
26105
26478
  );
26106
26479
  const r = await generateExternalPixelSnippet(requireCredentials(), body5);
26107
26480
  if (!r.ok || !r.data)
@@ -26154,6 +26527,8 @@ program2.addCommand(prospectCommand, { hidden: true });
26154
26527
  program2.addCommand(webhooksCommand);
26155
26528
  program2.addCommand(simulateCommand);
26156
26529
  program2.addCommand(experimentsCommand);
26530
+ program2.addCommand(resultsCommand);
26531
+ program2.addCommand(commerceCommand);
26157
26532
  program2.addCommand(pushCommand);
26158
26533
  program2.addCommand(previewCommand);
26159
26534
  program2.addCommand(roadmapCommand);
@@ -26227,11 +26602,11 @@ function isExplicitJsonVersionRequest(args) {
26227
26602
  } else if (arg === "--version" || arg === "-V") {
26228
26603
  hasVersion = true;
26229
26604
  } else if (arg === "--org" || arg === "--shop") {
26230
- const value = args[++index];
26231
- if (!value || value.startsWith("-")) return false;
26605
+ const value2 = args[++index];
26606
+ if (!value2 || value2.startsWith("-")) return false;
26232
26607
  } else if (arg.startsWith("--org=") || arg.startsWith("--shop=")) {
26233
- const value = arg.slice(arg.indexOf("=") + 1);
26234
- if (!value || value.startsWith("-")) return false;
26608
+ const value2 = arg.slice(arg.indexOf("=") + 1);
26609
+ if (!value2 || value2.startsWith("-")) return false;
26235
26610
  } else {
26236
26611
  return false;
26237
26612
  }