@zeroxyz/cli 1.22.0 → 1.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +256 -50
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -78449,7 +78449,7 @@ init_esm_shims();
78449
78449
  // ../sdk/dist/index.js
78450
78450
  init_esm_shims();
78451
78451
 
78452
- // ../sdk/dist/chunk-4FP2DRQJ.js
78452
+ // ../sdk/dist/chunk-76JAOSJC.js
78453
78453
  init_esm_shims();
78454
78454
 
78455
78455
  // ../../node_modules/.pnpm/viem@2.52.2_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@6.0.6_zod@4.3.6/node_modules/viem/_esm/index.js
@@ -143768,7 +143768,7 @@ config(en_default2());
143768
143768
  // ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/index.js
143769
143769
  var zod_default = external_exports3;
143770
143770
 
143771
- // ../sdk/dist/chunk-4FP2DRQJ.js
143771
+ // ../sdk/dist/chunk-76JAOSJC.js
143772
143772
  var createManagedAccount = (client, address2, opts = {}) => {
143773
143773
  const signOptions = {
143774
143774
  // expectedAddress pins verification to this adapter's frozen address.
@@ -144269,7 +144269,13 @@ var tempoChainLabelFromId = (chainId2) => {
144269
144269
  };
144270
144270
  var paymentHasAnchor = (payment) => payment !== null && (payment.txHash !== null || payment.session !== void 0);
144271
144271
  var FETCH_WARNINGS = Object.freeze({
144272
- paidButStill402NotRecorded: "paid_but_still_402_not_recorded",
144272
+ // Settlement landed on-chain but upstream still answered 402 (facilitator
144273
+ // lag / race). Still a warning worth surfacing for reconciliation — but the
144274
+ // run IS now recorded (it was the most expensive hole in run capture: a
144275
+ // confirmed txHash with nothing pointing at what it bought). The old key
144276
+ // was `paid_but_still_402_not_recorded`; the "not_recorded" half is no
144277
+ // longer true.
144278
+ paidButStill402: "paid_but_still_402",
144273
144279
  paymentSettlementUnconfirmed: "payment_settlement_unconfirmed",
144274
144280
  paymentAmountUnknown: "payment_amount_unknown",
144275
144281
  mppSessionCloseFailed: "mpp_session_close_failed",
@@ -144283,9 +144289,12 @@ var FETCH_WARNINGS = Object.freeze({
144283
144289
  bodyTruncated: "body_truncated"
144284
144290
  });
144285
144291
  var FETCH_SKIP_REASONS = Object.freeze({
144292
+ // The body was lost, but the capability executed (and may have charged) —
144293
+ // so this is a warning ON a recorded run now, not a reason to drop it.
144286
144294
  bodyReadFailed: "body_read_failed",
144287
- mppSessionCloseFailedNotRecorded: "mpp_session_close_failed_not_recorded",
144288
- paidButStill402NotRecorded: FETCH_WARNINGS.paidButStill402NotRecorded,
144295
+ // The paid leg threw something other than a typed timeout/payment error —
144296
+ // most importantly a caller abort, which can land after the money moved.
144297
+ paidLegFailed: "paid_leg_failed",
144289
144298
  paymentSettlementUnconfirmed: FETCH_WARNINGS.paymentSettlementUnconfirmed,
144290
144299
  // Pre-sign abort: deliberately NOT recorded as a run — the wallet was
144291
144300
  // empty before we reached the capability, so charging it as a 402 would
@@ -145383,8 +145392,9 @@ var computeOutcome = (status, payment, warnings) => {
145383
145392
  if (status >= 400) return "server_error";
145384
145393
  return "success";
145385
145394
  };
145386
- var errorFetchResult = (startedAt, error48, skipReason, capabilityIdRequested, outcome, status = null) => {
145395
+ var errorFetchResult = (fetchId, startedAt, error48, skipReason, capabilityIdRequested, outcome, status = null) => {
145387
145396
  const result = {
145397
+ fetchId,
145388
145398
  runId: null,
145389
145399
  ok: false,
145390
145400
  status,
@@ -145398,25 +145408,50 @@ var errorFetchResult = (startedAt, error48, skipReason, capabilityIdRequested, o
145398
145408
  if (capabilityIdRequested) result.runTrackingSkipped = [skipReason];
145399
145409
  return result;
145400
145410
  };
145411
+ var settlementFields = (payment) => {
145412
+ if (payment === null) return {};
145413
+ const knownAmount = payment.amount !== "unknown";
145414
+ return {
145415
+ ...knownAmount && {
145416
+ costAmount: payment.amount,
145417
+ costAsset: payment.asset
145418
+ },
145419
+ paymentProtocol: payment.protocol,
145420
+ paymentChain: payment.chain,
145421
+ paymentTxHash: payment.txHash ?? void 0,
145422
+ paymentMode: payment.session ? "session" : "charge"
145423
+ };
145424
+ };
145401
145425
  var resolveRecordingClient = (client, opts) => {
145402
145426
  const credentials = client.getCredentials();
145403
145427
  const recordingClient = opts.account ? client.withAccount(opts.account) : client;
145404
145428
  const canRecord = opts.account !== void 0 || credentials.kind === "account" || credentials.kind === "session";
145405
145429
  return { recordingClient, canRecord };
145406
145430
  };
145407
- var recordErrorFetchRun = async (client, opts, result, capabilityIdOverride) => {
145408
- const effectiveCapId = opts.capabilityId;
145409
- if (effectiveCapId === void 0) return;
145431
+ var recordErrorFetchRun = async (client, opts, result, capabilityIdOverride, requestUrl, requestMethod) => {
145432
+ const effectiveCapId = capabilityIdOverride ?? opts.capabilityId;
145433
+ const urlTarget = requestUrl ? {
145434
+ requestUrl: redactUrl(requestUrl),
145435
+ ...requestMethod && { requestMethod }
145436
+ } : void 0;
145437
+ const runTarget = effectiveCapId !== void 0 ? { capabilityId: effectiveCapId, ...urlTarget } : urlTarget ?? null;
145438
+ if (runTarget === null) return;
145410
145439
  const { recordingClient, canRecord } = resolveRecordingClient(client, opts);
145411
145440
  if (!canRecord) return;
145412
- const fetchOriginForRecord = opts.capabilityId === void 0 ? "direct_url" : isShortToken(effectiveCapId) ? "from_search" : opts.fetchOrigin;
145441
+ const fetchOriginForRecord = opts.capabilityId === void 0 ? "direct_url" : effectiveCapId !== void 0 && isShortToken(effectiveCapId) ? "from_search" : opts.fetchOrigin;
145413
145442
  try {
145414
145443
  const created = await recordingClient.runs.create({
145415
- capabilityId: effectiveCapId,
145444
+ ...runTarget,
145445
+ fetchId: result.fetchId,
145416
145446
  ...opts.searchId && { searchId: opts.searchId },
145417
145447
  ...fetchOriginForRecord && { fetchOrigin: fetchOriginForRecord },
145418
145448
  ...result.status !== null && { status: result.status },
145449
+ // The SDK's verdict. HTTP status alone can't say "the capability
145450
+ // answered 200 but the caller got nothing" — outcome can.
145451
+ outcome: result.outcome,
145419
145452
  latencyMs: result.latencyMs,
145453
+ // Carry the settlement when the failure happened AFTER we paid.
145454
+ ...settlementFields(result.payment),
145420
145455
  ...opts.requestSchema && { requestSchema: opts.requestSchema },
145421
145456
  ...opts.walletAddress && !opts.account && { walletAddress: opts.walletAddress }
145422
145457
  });
@@ -145425,15 +145460,23 @@ var recordErrorFetchRun = async (client, opts, result, capabilityIdOverride) =>
145425
145460
  } catch {
145426
145461
  }
145427
145462
  };
145428
- var recordTimeoutRun = async (client, opts, err, startedAt, capabilityIdRequested, capabilityIdOverride) => {
145463
+ var recordTimeoutRun = async (client, opts, fetchId, err, startedAt, capabilityIdRequested, capabilityIdOverride, requestUrl, requestMethod) => {
145429
145464
  const result = errorFetchResult(
145465
+ fetchId,
145430
145466
  startedAt,
145431
145467
  err.message,
145432
145468
  "timeout",
145433
145469
  capabilityIdRequested,
145434
145470
  "network_error"
145435
145471
  );
145436
- await recordErrorFetchRun(client, opts, result);
145472
+ await recordErrorFetchRun(
145473
+ client,
145474
+ opts,
145475
+ result,
145476
+ capabilityIdOverride,
145477
+ requestUrl,
145478
+ requestMethod
145479
+ );
145437
145480
  };
145438
145481
  var sniffJsonShapeBytes = (buf) => {
145439
145482
  let i = 0;
@@ -145460,6 +145503,7 @@ var withDefaultContentType = (headers, body) => {
145460
145503
  };
145461
145504
  var clientFetch = async (client, url4, opts = {}) => {
145462
145505
  const startedAt = Date.now();
145506
+ const fetchId = randomUUID();
145463
145507
  const capabilityIdRequested = opts.capabilityId !== void 0;
145464
145508
  const normalized = normalizeTransportEnvelopeRequest(url4, {
145465
145509
  method: opts.method,
@@ -145494,22 +145538,34 @@ var clientFetch = async (client, url4, opts = {}) => {
145494
145538
  await recordTimeoutRun(
145495
145539
  client,
145496
145540
  opts,
145541
+ fetchId,
145497
145542
  err,
145498
145543
  startedAt,
145499
- capabilityIdRequested
145544
+ capabilityIdRequested,
145545
+ void 0,
145546
+ requestUrl,
145547
+ method
145500
145548
  );
145501
145549
  throw err;
145502
145550
  }
145503
145551
  if (err instanceof ZeroError) throw err;
145504
145552
  const errMessage = err instanceof Error ? err.message : String(err);
145505
145553
  const result2 = errorFetchResult(
145554
+ fetchId,
145506
145555
  startedAt,
145507
145556
  errMessage,
145508
145557
  "fetch_failed_before_response",
145509
145558
  capabilityIdRequested,
145510
145559
  "network_error"
145511
145560
  );
145512
- await recordErrorFetchRun(client, opts, result2);
145561
+ await recordErrorFetchRun(
145562
+ client,
145563
+ opts,
145564
+ result2,
145565
+ void 0,
145566
+ requestUrl,
145567
+ method
145568
+ );
145513
145569
  return result2;
145514
145570
  }
145515
145571
  if (response.status === 402) {
@@ -145554,6 +145610,7 @@ var clientFetch = async (client, url4, opts = {}) => {
145554
145610
  warnings.push(FETCH_WARNINGS.mppSessionCloseFailed);
145555
145611
  } else if (err instanceof ZeroInsufficientFundsError) {
145556
145612
  return errorFetchResult(
145613
+ fetchId,
145557
145614
  startedAt,
145558
145615
  err.message,
145559
145616
  FETCH_SKIP_REASONS.insufficientFunds,
@@ -145563,6 +145620,7 @@ var clientFetch = async (client, url4, opts = {}) => {
145563
145620
  );
145564
145621
  } else if (err instanceof ZeroPaymentError || err instanceof ZeroAuthError) {
145565
145622
  const result2 = errorFetchResult(
145623
+ fetchId,
145566
145624
  startedAt,
145567
145625
  err.message,
145568
145626
  "payment_failed",
@@ -145570,23 +145628,51 @@ var clientFetch = async (client, url4, opts = {}) => {
145570
145628
  "payment_failed",
145571
145629
  402
145572
145630
  );
145573
- await recordErrorFetchRun(client, opts, result2);
145631
+ await recordErrorFetchRun(
145632
+ client,
145633
+ opts,
145634
+ result2,
145635
+ void 0,
145636
+ requestUrl,
145637
+ method
145638
+ );
145574
145639
  return result2;
145575
145640
  } else if (err instanceof ZeroTimeoutError) {
145576
145641
  await recordTimeoutRun(
145577
145642
  client,
145578
145643
  opts,
145644
+ fetchId,
145579
145645
  err,
145580
145646
  startedAt,
145581
- capabilityIdRequested
145647
+ capabilityIdRequested,
145648
+ void 0,
145649
+ requestUrl,
145650
+ method
145582
145651
  );
145583
145652
  throw err;
145584
145653
  } else {
145654
+ const failed = errorFetchResult(
145655
+ fetchId,
145656
+ startedAt,
145657
+ err instanceof Error ? err.message : String(err),
145658
+ FETCH_SKIP_REASONS.paidLegFailed,
145659
+ capabilityIdRequested,
145660
+ "network_error"
145661
+ );
145662
+ await recordErrorFetchRun(
145663
+ client,
145664
+ opts,
145665
+ failed,
145666
+ void 0,
145667
+ requestUrl,
145668
+ method
145669
+ );
145585
145670
  throw err;
145586
145671
  }
145587
145672
  }
145588
145673
  } else if (requirement?.protocol === "unknown") {
145589
145674
  const result2 = errorFetchResult(
145675
+ fetchId,
145590
145676
  startedAt,
145591
145677
  opts.paymentProtocol ? `Capability did not advertise the requested ${opts.paymentProtocol} payment protocol.` : "Capability returned 402 with an unrecognized payment protocol. Neither x402 nor MPP markers were detected in the response headers or body.",
145592
145678
  "unrecognized_402_protocol",
@@ -145594,7 +145680,14 @@ var clientFetch = async (client, url4, opts = {}) => {
145594
145680
  "payment_failed",
145595
145681
  402
145596
145682
  );
145597
- await recordErrorFetchRun(client, opts, result2);
145683
+ await recordErrorFetchRun(
145684
+ client,
145685
+ opts,
145686
+ result2,
145687
+ void 0,
145688
+ requestUrl,
145689
+ method
145690
+ );
145598
145691
  return result2;
145599
145692
  }
145600
145693
  }
@@ -145611,6 +145704,26 @@ var clientFetch = async (client, url4, opts = {}) => {
145611
145704
  if (parsed.truncated) warnings.push(FETCH_WARNINGS.bodyTruncated);
145612
145705
  } catch (err) {
145613
145706
  if (err instanceof Error && err.name === "AbortError") {
145707
+ const aborted2 = {
145708
+ fetchId,
145709
+ runId: null,
145710
+ ok: false,
145711
+ status: response.status,
145712
+ latencyMs: Date.now() - startedAt,
145713
+ payment,
145714
+ outcome: "network_error",
145715
+ body: null,
145716
+ bodyRaw: null,
145717
+ error: "Request aborted by caller"
145718
+ };
145719
+ await recordErrorFetchRun(
145720
+ client,
145721
+ opts,
145722
+ aborted2,
145723
+ (await resolvePromise.catch(() => null))?.capabilityId,
145724
+ requestUrl,
145725
+ method
145726
+ );
145614
145727
  throw new ZeroApiError("Request aborted by caller", {
145615
145728
  status: 0,
145616
145729
  cause: err
@@ -145620,8 +145733,8 @@ var clientFetch = async (client, url4, opts = {}) => {
145620
145733
  const skips = [];
145621
145734
  const settledLocally = paymentHasAnchor(payment);
145622
145735
  if (settledLocally && response.status === 402) {
145623
- warnings.push(FETCH_WARNINGS.paidButStill402NotRecorded);
145624
- skips.push(FETCH_WARNINGS.paidButStill402NotRecorded);
145736
+ warnings.push(FETCH_WARNINGS.paidButStill402);
145737
+ skips.push(FETCH_WARNINGS.paidButStill402);
145625
145738
  }
145626
145739
  if (payment !== null && !settledLocally) {
145627
145740
  warnings.push(FETCH_WARNINGS.paymentSettlementUnconfirmed);
@@ -145632,42 +145745,52 @@ var clientFetch = async (client, url4, opts = {}) => {
145632
145745
  }
145633
145746
  skips.push(FETCH_SKIP_REASONS.bodyReadFailed);
145634
145747
  const result2 = {
145748
+ fetchId,
145635
145749
  runId: null,
145636
145750
  ok: false,
145637
145751
  status: response.status,
145638
145752
  latencyMs: Date.now() - startedAt,
145639
145753
  payment,
145640
- outcome: computeOutcome(response.status, payment, warnings),
145754
+ // The body never arrived, so this is NOT a success even when the wire
145755
+ // said 2xx — `ok: false` with `outcome: "success"` was a contradiction,
145756
+ // and it's what let these rows land in the DB as clean successes.
145757
+ // Only the bogus "success" is overridden: a more specific verdict (an
145758
+ // MPP close-fail whose body then dropped) must survive intact.
145759
+ outcome: (() => {
145760
+ const computed = computeOutcome(response.status, payment, warnings);
145761
+ return computed === "success" ? "network_error" : computed;
145762
+ })(),
145641
145763
  body: null,
145642
145764
  bodyRaw: null,
145643
145765
  error: message2
145644
145766
  };
145645
145767
  if (capabilityIdRequested) result2.runTrackingSkipped = skips;
145646
145768
  if (warnings.length > 0) result2.warnings = warnings;
145769
+ await recordErrorFetchRun(
145770
+ client,
145771
+ opts,
145772
+ result2,
145773
+ (await resolvePromise.catch(() => null))?.capabilityId,
145774
+ requestUrl,
145775
+ method
145776
+ );
145647
145777
  return result2;
145648
145778
  }
145649
145779
  const settled = paymentHasAnchor(payment);
145650
145780
  const paidButStill402 = settled && response.status === 402;
145651
145781
  const settlementUnconfirmed = payment !== null && !settled;
145652
- if (paidButStill402) warnings.push(FETCH_WARNINGS.paidButStill402NotRecorded);
145782
+ if (paidButStill402) warnings.push(FETCH_WARNINGS.paidButStill402);
145653
145783
  if (settlementUnconfirmed)
145654
145784
  warnings.push(FETCH_WARNINGS.paymentSettlementUnconfirmed);
145655
145785
  if (payment !== null && payment.amount === "unknown") {
145656
145786
  warnings.push(FETCH_WARNINGS.paymentAmountUnknown);
145657
145787
  }
145658
145788
  let runId = null;
145659
- const closeFailed = warnings.includes(FETCH_WARNINGS.mppSessionCloseFailed);
145660
145789
  const upstreamErrorForRecord = buildUpstreamError(
145661
145790
  response.status,
145662
145791
  bodyRaw,
145663
145792
  bodyEncoding
145664
145793
  );
145665
- if (capabilityIdRequested) {
145666
- if (paidButStill402)
145667
- skipReasons.push(FETCH_WARNINGS.paidButStill402NotRecorded);
145668
- else if (closeFailed)
145669
- skipReasons.push(FETCH_SKIP_REASONS.mppSessionCloseFailedNotRecorded);
145670
- }
145671
145794
  const resolvedCap = await resolvePromise;
145672
145795
  const effectiveCapabilityId = opts.capabilityId ?? resolvedCap?.capabilityId;
145673
145796
  const capabilityResolution = !capabilityIdRequested && canRecordForResolve ? resolvedCap !== null ? {
@@ -145676,7 +145799,13 @@ var clientFetch = async (client, url4, opts = {}) => {
145676
145799
  capabilitySlug: resolvedCap.capabilitySlug,
145677
145800
  matchedVia: resolvedCap.matchedVia
145678
145801
  } : { resolved: false } : void 0;
145679
- if (effectiveCapabilityId !== void 0 && !paidButStill402 && !closeFailed) {
145802
+ const runTarget = effectiveCapabilityId !== void 0 ? {
145803
+ capabilityId: effectiveCapabilityId,
145804
+ requestUrl: redactUrl(requestUrl),
145805
+ requestMethod: method
145806
+ } : { requestUrl: redactUrl(requestUrl), requestMethod: method };
145807
+ const fetchOutcome = computeOutcome(response.status, payment, warnings);
145808
+ {
145680
145809
  const { recordingClient, canRecord } = resolveRecordingClient(client, opts);
145681
145810
  if (!canRecord) {
145682
145811
  skipReasons.push("no_credentials");
@@ -145696,12 +145825,17 @@ var clientFetch = async (client, url4, opts = {}) => {
145696
145825
  }
145697
145826
  }
145698
145827
  const result2 = await recordingClient.runs.create({
145699
- capabilityId: effectiveCapabilityId,
145828
+ ...runTarget,
145829
+ fetchId,
145700
145830
  searchId: opts.searchId,
145701
145831
  // Auto-resolved runs are always direct_url — they only fire when
145702
145832
  // no capabilityId was supplied (the direct_url path by definition).
145703
145833
  ...opts.capabilityId === void 0 ? { fetchOrigin: "direct_url" } : opts.fetchOrigin && { fetchOrigin: opts.fetchOrigin },
145704
145834
  status: response.status,
145835
+ // The SDK's verdict alongside the raw status. A close-fail or a
145836
+ // dropped body answers 200 while the caller got nothing — the
145837
+ // server must not read that as a clean success.
145838
+ outcome: fetchOutcome,
145705
145839
  latencyMs,
145706
145840
  // Attribute to the selected wallet in session mode. Skipped when a
145707
145841
  // per-call `account` override records the run — that account's own
@@ -145746,12 +145880,13 @@ var clientFetch = async (client, url4, opts = {}) => {
145746
145880
  }
145747
145881
  }
145748
145882
  const result = {
145883
+ fetchId,
145749
145884
  runId,
145750
145885
  ok: response.ok,
145751
145886
  status: response.status,
145752
145887
  latencyMs,
145753
145888
  payment,
145754
- outcome: computeOutcome(response.status, payment, warnings),
145889
+ outcome: fetchOutcome,
145755
145890
  body,
145756
145891
  bodyRaw
145757
145892
  };
@@ -145761,7 +145896,7 @@ var clientFetch = async (client, url4, opts = {}) => {
145761
145896
  result.error = candidate !== null && !requestBodyEchoed(candidate, opts.body) ? candidate : `HTTP ${response.status}`;
145762
145897
  if (upstreamErrorForRecord) result.upstreamError = upstreamErrorForRecord;
145763
145898
  }
145764
- if (capabilityIdRequested && skipReasons.length > 0) {
145899
+ if (skipReasons.length > 0) {
145765
145900
  result.runTrackingSkipped = skipReasons;
145766
145901
  }
145767
145902
  if (warnings.length > 0) result.warnings = warnings;
@@ -145770,7 +145905,7 @@ var clientFetch = async (client, url4, opts = {}) => {
145770
145905
  return result;
145771
145906
  };
145772
145907
  var package_default = {
145773
- version: "0.15.0"
145908
+ version: "0.17.0"
145774
145909
  };
145775
145910
  var SDK_VERSION2 = package_default.version;
145776
145911
  var agentAuthMetadataSchema = external_exports3.object({
@@ -146875,20 +147010,80 @@ var batchReviewResponseSchema = external_exports3.object({
146875
147010
  failed: external_exports3.number()
146876
147011
  })
146877
147012
  });
146878
- var Runs = class {
147013
+ var Runs = class _Runs {
146879
147014
  constructor(client) {
146880
147015
  this.client = client;
146881
147016
  }
146882
- create = (input, opts = {}) => request2(
146883
- this.client,
146884
- {
146885
- method: "POST",
146886
- path: "/v1/runs",
146887
- body: input,
146888
- signal: opts.signal
146889
- },
146890
- createRunResponseSchema
146891
- );
147017
+ /**
147018
+ * Field generations, newest first. `/v1/runs` validates `.strict()`, so an
147019
+ * unknown key is a 400 — not a warning. An SDK newer than its API would
147020
+ * therefore have its run REJECTED and lost, which is precisely backwards:
147021
+ * these fields exist to stop losing runs.
147022
+ *
147023
+ * So we degrade one generation at a time rather than all at once — an API
147024
+ * that knows `requestUrl` (ZERO-536) but not `fetchId` must keep recording
147025
+ * unattributed runs, which it can't do if we strip the target as well.
147026
+ */
147027
+ static FIELD_GENERATIONS = [
147028
+ // Newest: correlation + honest classification.
147029
+ ["fetchId", "outcome"],
147030
+ // ZERO-536: the direct-URL target. Dropping this loses attribution for an
147031
+ // unattributed run entirely — only worth trying against a truly old API.
147032
+ ["requestUrl", "requestMethod"]
147033
+ ];
147034
+ /**
147035
+ * Record a run, degrading to whatever the server actually understands.
147036
+ *
147037
+ * On a 400/422 we peel off one generation of newer fields and retry, so SDK
147038
+ * and API can be deployed in ANY order (and a self-hosted or staging API that
147039
+ * lags still records runs). The only unrescuable case is an unattributed run
147040
+ * against an API that predates ZERO-536: strip `requestUrl` and there is no
147041
+ * target left to name, so that server could never have recorded it.
147042
+ */
147043
+ create = async (input, opts = {}) => {
147044
+ const post = (body) => request2(
147045
+ this.client,
147046
+ {
147047
+ method: "POST",
147048
+ path: "/v1/runs",
147049
+ body,
147050
+ signal: opts.signal
147051
+ },
147052
+ createRunResponseSchema
147053
+ );
147054
+ let payload = { ...input };
147055
+ let generation = 0;
147056
+ for (; ; ) {
147057
+ try {
147058
+ return await post(payload);
147059
+ } catch (err) {
147060
+ const rejected = err instanceof ZeroApiError && (err.status === 400 || err.status === 422);
147061
+ if (!rejected) throw err;
147062
+ let next = null;
147063
+ let dropped = [];
147064
+ while (generation < _Runs.FIELD_GENERATIONS.length) {
147065
+ const fields = _Runs.FIELD_GENERATIONS[generation++];
147066
+ const present = (fields ?? []).filter(
147067
+ (f) => payload[f] !== void 0
147068
+ );
147069
+ if (present.length === 0) continue;
147070
+ next = { ...payload };
147071
+ for (const field of present) delete next[field];
147072
+ dropped = present;
147073
+ break;
147074
+ }
147075
+ if (!next || next.capabilityId === void 0 && next.requestUrl === void 0) {
147076
+ throw err;
147077
+ }
147078
+ payload = next;
147079
+ this.client.logger?.({
147080
+ level: "warn",
147081
+ message: "runs.create rejected by an older Zero API; retrying without newer fields",
147082
+ meta: { droppedFields: dropped }
147083
+ });
147084
+ }
147085
+ }
147086
+ };
146892
147087
  list = (params = {}, opts = {}) => {
146893
147088
  if (params.limit === 0) {
146894
147089
  if (opts.signal?.aborted) {
@@ -147912,7 +148107,7 @@ var placeholderFor = (fieldName, propSchema) => String(sampleValueFor(fieldName,
147912
148107
 
147913
148108
  // package.json
147914
148109
  var package_default2 = {
147915
- version: "1.22.0"};
148110
+ version: "1.24.0"};
147916
148111
 
147917
148112
  // src/app.ts
147918
148113
  init_esm_shims();
@@ -149648,6 +149843,7 @@ var fetchCommand = (appContext) => new Command("fetch").description(
149648
149843
  let searchId;
149649
149844
  let displayCostAmount;
149650
149845
  let fetchOrigin;
149846
+ let runIsAttributed = true;
149651
149847
  if (fromToken) {
149652
149848
  capabilityUid = capFromNoUrl?.uid ?? null;
149653
149849
  capabilityId = options.capability ?? "";
@@ -149661,9 +149857,6 @@ var fetchCommand = (appContext) => new Command("fetch").description(
149661
149857
  displayCostAmount = capFromNoUrl?.displayCostAmount;
149662
149858
  fetchOrigin = "direct_slug";
149663
149859
  } else {
149664
- const resolved = await client.capabilities.resolveByUrl(resolvedUrl, options.method ?? "GET").catch(() => null);
149665
- capabilityUid = resolved?.capabilityId ?? null;
149666
- capabilityId = capabilityUid;
149667
149860
  fetchOrigin = "direct_url";
149668
149861
  }
149669
149862
  const resultRank = void 0;
@@ -149747,6 +149940,7 @@ var fetchCommand = (appContext) => new Command("fetch").description(
149747
149940
  return;
149748
149941
  }
149749
149942
  const {
149943
+ fetchId,
149750
149944
  runId,
149751
149945
  status,
149752
149946
  latencyMs,
@@ -149844,6 +150038,7 @@ var fetchCommand = (appContext) => new Command("fetch").description(
149844
150038
  matchedVia: capabilityResolution.matchedVia
149845
150039
  });
149846
150040
  } else {
150041
+ runIsAttributed = false;
149847
150042
  if (walletAddress && !runId) {
149848
150043
  cliSkipReasons.push(
149849
150044
  "no capability resolved \u2014 pass --capability <uid|slug|token> or run `zero search` first so the URL can be matched"
@@ -149856,6 +150051,11 @@ var fetchCommand = (appContext) => new Command("fetch").description(
149856
150051
  }
149857
150052
  }
149858
150053
  analyticsService.capture("fetch_executed", {
150054
+ // The correlation key: joins this client event to the server's
150055
+ // run_started / run_completed / payment_processed, and to the run
150056
+ // row itself. Works even when runId is null — i.e. exactly when
150057
+ // the run failed to record, which is what we most need to trace.
150058
+ fetchId,
149859
150059
  url: redactUrl2(resolvedUrl),
149860
150060
  status: status ?? void 0,
149861
150061
  outcome,
@@ -149978,7 +150178,7 @@ var fetchCommand = (appContext) => new Command("fetch").description(
149978
150178
  ...sdkWarnings?.length && { warnings: sdkWarnings }
149979
150179
  })
149980
150180
  );
149981
- } else if (runId && outcomeInfo.reviewable) {
150181
+ } else if (runId && outcomeInfo.reviewable && runIsAttributed) {
149982
150182
  const isTTY = process.stderr.isTTY;
149983
150183
  const responded2xx = status !== null && status >= 200 && status < 300;
149984
150184
  console.error(`
@@ -150018,6 +150218,12 @@ var fetchCommand = (appContext) => new Command("fetch").description(
150018
150218
  } else {
150019
150219
  console.error(` zero review ${runId} --no-success`);
150020
150220
  }
150221
+ } else if (runId && !runIsAttributed) {
150222
+ console.error(`
150223
+ Run ID: ${runId}`);
150224
+ console.error(
150225
+ ` This URL isn't an indexed capability, so the run can't be reviewed. Pass --capability <uid|slug> or run \`zero search\` first to bind it to one.`
150226
+ );
150021
150227
  } else if (!runId && cliSkipReasons.length > 0) {
150022
150228
  console.error(
150023
150229
  `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeroxyz/cli",
3
- "version": "1.22.0",
3
+ "version": "1.24.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "zero": "dist/index.js",