@drip-apex/apex-cli 0.12.0 → 0.12.1

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.
Files changed (3) hide show
  1. package/README.md +26 -2
  2. package/dist/cli.js +47 -5
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -352,5 +352,29 @@ config-fetch p50/p95 (milliseconds), and inline/cache/network/none counts.
352
352
  JSON output includes the API body in the standard envelope and assignment-ready
353
353
  percentiles. Fewer than five measured samples have null percentiles. Natural
354
354
  loads are shop-wide non-QA loads without forced IDs; a QA-session bucket can
355
- overlap forced loads. Analytics failures return errors. Preload and anti-flicker
356
- changes remain under evaluation pending the first report.
355
+ overlap forced loads. Analytics failures return errors. The API position is
356
+ `runtime_inline_no_change`.
357
+
358
+ The runtime remains unchanged. Natural runtime decides within tens of milliseconds
359
+ of SDK start when config ships inline with the snippet (measured p50 12 ms /
360
+ p95 54 ms on a large storefront). QA previews, screenshot-mode previews and
361
+ cookie-forced sessions take the QA config lane and fetch fresh config over the
362
+ network (measured p50 1.3 s / p95 7 s); they are not representative of launch
363
+ behaviour. URL-forced sessions without a `qa` parameter keep the inline or cached
364
+ config, so these measurements do not describe them. No config preload or
365
+ anti-flicker hold is planned.
366
+
367
+ ### Connection troubleshooting
368
+
369
+ Connection errors retain the underlying failure. JSON output exposes
370
+ `error.details.reason` and, when available, `error.details.code`; the numeric
371
+ `error.code` remains the CLI exit code.
372
+
373
+ | Reason | Meaning and usual fix |
374
+ | --- | --- |
375
+ | `dns` | The host could not be resolved. Check `APEX_BASE_URL` (or `DRIP_BASE_URL`), DNS, and whether your sandbox permits network access. |
376
+ | `refused` | The host rejected the connection. Check the base URL, port, and whether the server is running. |
377
+ | `reset` | The connection was interrupted. Check network stability and proxy settings before retrying. |
378
+ | `tls` | Certificate or TLS validation failed. Check expired certificates and your corporate TLS proxy's trusted CA configuration. |
379
+ | `timeout` | The request was aborted or exceeded its deadline. Check server availability and network access. |
380
+ | `unknown` | Another network failure occurred. Use the included cause message to diagnose network or sandbox restrictions. |
package/dist/cli.js CHANGED
@@ -7112,7 +7112,7 @@ var import_node_os3 = __toESM(require("node:os"));
7112
7112
  // package.json
7113
7113
  var package_default = {
7114
7114
  name: "@drip-apex/apex-cli",
7115
- version: "0.12.0",
7115
+ version: "0.12.1",
7116
7116
  license: "MIT",
7117
7117
  description: "Apex CLI for managing experiments, approved roadmap ideas, and draft workspaces.",
7118
7118
  private: false,
@@ -7666,7 +7666,16 @@ function createHttpClient(creds, options) {
7666
7666
  try {
7667
7667
  response = await fetch(`${creds.baseUrl}${path24}`, { method, headers, body: form ? body5 : body5 ? JSON.stringify(body5) : void 0, signal: AbortSignal.timeout(timeoutMs) });
7668
7668
  } catch (error) {
7669
- return options.onNetworkError({ baseUrl: creds.baseUrl, timeoutMs, cause: error instanceof Error ? error.message : String(error) });
7669
+ const outer = error && typeof error === "object" ? error : void 0;
7670
+ const nested = outer?.cause && typeof outer.cause === "object" ? outer.cause : void 0;
7671
+ return options.onNetworkError({
7672
+ baseUrl: creds.baseUrl,
7673
+ timeoutMs,
7674
+ cause: error instanceof Error ? error.message : String(error),
7675
+ code: typeof nested?.code === "string" ? nested.code : typeof outer?.code === "string" ? outer.code : void 0,
7676
+ name: typeof outer?.name === "string" ? outer.name : void 0,
7677
+ causeMessage: typeof nested?.message === "string" ? nested.message : void 0
7678
+ });
7670
7679
  }
7671
7680
  inspectVersion(response.headers);
7672
7681
  const json = await response.json().catch(() => null);
@@ -7739,10 +7748,42 @@ function sharedClient(creds) {
7739
7748
  transport: testTransport,
7740
7749
  testTransportVersion: () => testTransport ? process.env[["APEX", "CLI", "MOCK", "API", "VERSION"].join("_")] : void 0,
7741
7750
  onNetworkError: (info) => {
7751
+ let url;
7752
+ try {
7753
+ url = new URL(info.baseUrl);
7754
+ } catch {
7755
+ }
7756
+ const host = url?.hostname ?? info.baseUrl;
7757
+ const code = info.code;
7758
+ let reason = "unknown";
7759
+ let message = info.causeMessage ?? info.cause;
7760
+ if (info.name === "TimeoutError" || info.name === "AbortError" || code === "UND_ERR_CONNECT_TIMEOUT") {
7761
+ reason = "timeout";
7762
+ message = `server did not respond within ${info.timeoutMs / 1e3}s`;
7763
+ } else if (code === "ENOTFOUND" || code === "EAI_AGAIN") {
7764
+ reason = "dns";
7765
+ message = `could not resolve host ${host}`;
7766
+ } else if (code === "ECONNREFUSED") {
7767
+ reason = "refused";
7768
+ message = `connection refused by ${host}:${url?.port || (url?.protocol === "https:" ? "443" : "80")}`;
7769
+ } else if (code === "ECONNRESET" || code === "EPIPE") {
7770
+ reason = "reset";
7771
+ message = `connection reset by ${host}`;
7772
+ } else if (code?.startsWith("CERT_") || code?.startsWith("ERR_TLS_") || [
7773
+ "DEPTH_ZERO_SELF_SIGNED_CERT",
7774
+ "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
7775
+ "SELF_SIGNED_CERT_IN_CHAIN",
7776
+ "UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
7777
+ "UNABLE_TO_GET_ISSUER_CERT",
7778
+ "HOSTNAME_MISMATCH"
7779
+ ].includes(code ?? "")) {
7780
+ reason = "tls";
7781
+ message = `TLS error (${code})`;
7782
+ }
7742
7783
  throw new CliError(
7743
- `Could not reach ${info.baseUrl}: check APEX_BASE_URL (or DRIP_BASE_URL) / network; server did not respond within ${info.timeoutMs / 1e3}s.`,
7784
+ `Could not reach ${info.baseUrl}: check APEX_BASE_URL (or DRIP_BASE_URL) / network; ${message}.`,
7744
7785
  EXIT_CODES.general,
7745
- { ...info }
7786
+ { reason, code, name: info.name, baseUrl: info.baseUrl, timeoutMs: info.timeoutMs }
7746
7787
  );
7747
7788
  }
7748
7789
  });
@@ -13153,8 +13194,9 @@ trackingCommand.command("latency").description("Measure forced-preview versus na
13153
13194
  ].join("/")
13154
13195
  ])
13155
13196
  );
13197
+ console.log("Times in ms. Fewer than 5 measured samples: -.");
13156
13198
  console.log(
13157
- "Times in ms. Fewer than 5 measured samples: -. Preload/anti-flicker position: under evaluation."
13199
+ "Position: runtime unchanged (inline config decides within tens of ms; forced previews fetch config over the network and are not representative)"
13158
13200
  );
13159
13201
  });
13160
13202
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drip-apex/apex-cli",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "license": "MIT",
5
5
  "description": "Apex CLI for managing experiments, approved roadmap ideas, and draft workspaces.",
6
6
  "private": false,