@zeroxyz/cli 1.33.0 → 1.34.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 +298 -62
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -93043,7 +93043,7 @@ init_esm_shims();
93043
93043
  // ../sdk/dist/index.js
93044
93044
  init_esm_shims();
93045
93045
 
93046
- // ../sdk/dist/chunk-QNTZREQD.js
93046
+ // ../sdk/dist/chunk-C5F7JW77.js
93047
93047
  init_esm_shims();
93048
93048
 
93049
93049
  // ../../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
@@ -166742,6 +166742,7 @@ var FetchDiagnosticContext = class {
166742
166742
  issues = [];
166743
166743
  stageDurationsMs = {};
166744
166744
  paymentProtocol = null;
166745
+ paymentFallback = null;
166745
166746
  paymentMode = null;
166746
166747
  fundingSource = null;
166747
166748
  constructor(fetchId) {
@@ -166771,6 +166772,17 @@ var FetchDiagnosticContext = class {
166771
166772
  this.failureCode = code;
166772
166773
  }
166773
166774
  };
166775
+ // A failed preferred rail is non-terminal when an advertised fallback is
166776
+ // still safe to try. Retain its issue for observability, but let a later MPP
166777
+ // failure become the primary failure (or leave the completed fetch clean).
166778
+ recoverFailureForFallback = () => {
166779
+ this.failureStage = null;
166780
+ this.failureCode = null;
166781
+ };
166782
+ recordPaymentFallback = (fallback2) => {
166783
+ this.issue(fallback2.stage, fallback2.code);
166784
+ this.paymentFallback ??= { ...fallback2 };
166785
+ };
166774
166786
  selectPaymentProtocol = (protocol) => {
166775
166787
  this.paymentProtocol = protocol;
166776
166788
  };
@@ -166785,6 +166797,7 @@ var FetchDiagnosticContext = class {
166785
166797
  failureCode: this.failureCode,
166786
166798
  issues: this.issues.map((issue3) => ({ ...issue3 })),
166787
166799
  paymentProtocol: this.paymentProtocol,
166800
+ paymentFallback: this.paymentFallback === null ? null : { ...this.paymentFallback },
166788
166801
  paymentMode: this.paymentMode,
166789
166802
  fundingSource: this.fundingSource,
166790
166803
  stageDurationsMs: { ...this.stageDurationsMs }
@@ -166839,7 +166852,7 @@ var redactUrl = (raw) => {
166839
166852
  };
166840
166853
  var truncateError = (raw) => raw.length > ERROR_MAX ? `${raw.slice(0, ERROR_MAX)}\u2026` : raw;
166841
166854
  var package_default = {
166842
- version: "0.26.0"
166855
+ version: "0.27.0"
166843
166856
  };
166844
166857
  var SDK_VERSION2 = package_default.version;
166845
166858
  var ZeroError = class extends Error {
@@ -166893,6 +166906,14 @@ var ZeroPaymentError = class extends ZeroError {
166893
166906
  this.name = "ZeroPaymentError";
166894
166907
  }
166895
166908
  };
166909
+ var PAYMENT_NOT_ATTEMPTED_ERRORS = /* @__PURE__ */ new WeakSet();
166910
+ var markPaymentNotAttempted = (error98) => {
166911
+ if (typeof error98 === "object" && error98 !== null || typeof error98 === "function") {
166912
+ PAYMENT_NOT_ATTEMPTED_ERRORS.add(error98);
166913
+ }
166914
+ return error98;
166915
+ };
166916
+ var isPaymentNotAttemptedError = (error98) => (typeof error98 === "object" && error98 !== null || typeof error98 === "function") && PAYMENT_NOT_ATTEMPTED_ERRORS.has(error98);
166896
166917
  var ZeroPermit2AllowanceError = class extends ZeroPaymentError {
166897
166918
  constructor(message2, options) {
166898
166919
  super(message2, options);
@@ -167913,7 +167934,11 @@ var FETCH_WARNINGS = Object.freeze({
167913
167934
  // Response body exceeded maxResponseBytes — bodyRaw / body / bodyEncoding
167914
167935
  // reflect the clipped prefix; consumers that wrote the body to disk got
167915
167936
  // a truncated file. Particularly bad for paid binary fetches.
167916
- bodyTruncated: "body_truncated"
167937
+ bodyTruncated: "body_truncated",
167938
+ // The caller's `Authorization: Bearer` could not ride the MPP paid retry:
167939
+ // the Payment credential replaces Authorization and the 402 advertised no
167940
+ // alternate header to move the bearer into, so it was dropped.
167941
+ authorizationBearerDroppedByMpp: "authorization_bearer_dropped_by_mpp"
167917
167942
  });
167918
167943
  var FETCH_SKIP_REASONS = Object.freeze({
167919
167944
  // The body was lost, but the capability executed (and may have charged) —
@@ -168120,6 +168145,7 @@ var Payments = class {
168120
168145
  let pendingAmountUnits = 0n;
168121
168146
  let identityChallengeHandled = false;
168122
168147
  let paidChallengeHandled = false;
168148
+ let positivePaymentReplayAttempted = false;
168123
168149
  let capturedNetwork;
168124
168150
  let capturedScheme = null;
168125
168151
  let capturedCeilingUnits = null;
@@ -168353,6 +168379,9 @@ var Payments = class {
168353
168379
  "Access-Control-Expose-Headers",
168354
168380
  "PAYMENT-RESPONSE,X-PAYMENT-RESPONSE"
168355
168381
  );
168382
+ if (pendingAmountUnits > 0n) {
168383
+ positivePaymentReplayAttempted = true;
168384
+ }
168356
168385
  response = await measureDiagnostic(
168357
168386
  input.diagnostics,
168358
168387
  "paid_replay",
@@ -168389,11 +168418,14 @@ var Payments = class {
168389
168418
  FETCH_DIAGNOSTIC_CODES.paymentFailed
168390
168419
  );
168391
168420
  }
168392
- if (err instanceof ZeroError) throw err;
168393
- throw new ZeroPaymentError(
168421
+ if (err instanceof ZeroError) {
168422
+ throw !positivePaymentReplayAttempted && !isCallerAbortError(err) ? markPaymentNotAttempted(err) : err;
168423
+ }
168424
+ const paymentError = new ZeroPaymentError(
168394
168425
  `x402 payment failed: ${err instanceof Error ? err.message : String(err)}`,
168395
168426
  { cause: err }
168396
168427
  );
168428
+ throw !positivePaymentReplayAttempted && !isCallerAbortError(err) ? markPaymentNotAttempted(paymentError) : paymentError;
168397
168429
  }
168398
168430
  const isUpto = capturedScheme === "upto" && paidChallengeHandled;
168399
168431
  let txHash = null;
@@ -169205,6 +169237,38 @@ var Payments = class {
169205
169237
  };
169206
169238
  };
169207
169239
  };
169240
+ var BEARER_VALUE = /^bearer\s+\S+$/i;
169241
+ var relocateBearerForMpp = (headers, alternateHeader) => {
169242
+ if (!headers) return { headers, relocated: false, dropped: false };
169243
+ const entries = Object.entries(headers);
169244
+ const authorization = entries.find(
169245
+ ([name]) => name.toLowerCase() === "authorization"
169246
+ );
169247
+ const value = authorization?.[1].trim();
169248
+ if (!value || !BEARER_VALUE.test(value)) {
169249
+ return { headers, relocated: false, dropped: false };
169250
+ }
169251
+ if (!alternateHeader) return { headers, relocated: false, dropped: true };
169252
+ const alternate = alternateHeader.toLowerCase();
169253
+ if (entries.some(([name]) => name.toLowerCase() === alternate)) {
169254
+ return { headers, relocated: false, dropped: false };
169255
+ }
169256
+ const next = Object.fromEntries(
169257
+ entries.filter(([name]) => name.toLowerCase() !== "authorization")
169258
+ );
169259
+ next[alternateHeader] = value;
169260
+ return { headers: next, relocated: true, dropped: false };
169261
+ };
169262
+ var alternateBearerHeaderFromChallengeBody = (body) => {
169263
+ if (!body || typeof body !== "object") return void 0;
169264
+ const presentation = body.auth?.presentation;
169265
+ if (!presentation || typeof presentation !== "object") return void 0;
169266
+ const { scheme, alternateHeader } = presentation;
169267
+ if (typeof scheme === "string" && scheme.toLowerCase() !== "bearer") {
169268
+ return void 0;
169269
+ }
169270
+ return typeof alternateHeader === "string" && /^[A-Za-z0-9-]+$/.test(alternateHeader) ? alternateHeader : void 0;
169271
+ };
169208
169272
  var isShortToken = (id) => id.startsWith("z_") && id.indexOf(".", 2) !== -1;
169209
169273
  var MAX_402_PROBE_BYTES = 1024 * 1024;
169210
169274
  var MAX_RESPONSE_BYTES = 10 * 1024 * 1024;
@@ -169336,9 +169400,27 @@ var detectPaymentRequirement = async (response, preferredProtocol) => {
169336
169400
  const scheme = challenge2.trim().split(/\s+/)[0]?.toLowerCase() ?? "";
169337
169401
  return MPP_SCHEME_TOKENS.has(scheme);
169338
169402
  }) : false;
169403
+ const mppRequirement = (alternateBearerHeader, paymentFallback) => ({
169404
+ protocol: "mpp",
169405
+ raw: { "www-authenticate": wwwAuth },
169406
+ ...alternateBearerHeader ? { alternateBearerHeader } : {},
169407
+ ...paymentFallback ? { paymentFallback } : {}
169408
+ });
169409
+ const x402Fallback = (stage, code) => ({ from: "x402", to: "mpp", stage, code });
169410
+ const readMppBearerHint = async () => {
169411
+ try {
169412
+ const text = await readClippedText(response, MAX_402_PROBE_BYTES);
169413
+ return text ? alternateBearerHeaderFromChallengeBody(JSON.parse(text)) : void 0;
169414
+ } catch {
169415
+ return void 0;
169416
+ }
169417
+ };
169339
169418
  if (preferredProtocol === "mpp") {
169340
- cancelBody2(response);
169341
- return advertisesMpp ? { protocol: "mpp", raw: { "www-authenticate": wwwAuth } } : { protocol: "unknown", raw: { requestedProtocol: "mpp" } };
169419
+ if (!advertisesMpp) {
169420
+ cancelBody2(response);
169421
+ return { protocol: "unknown", raw: { requestedProtocol: "mpp" } };
169422
+ }
169423
+ return mppRequirement(await readMppBearerHint());
169342
169424
  }
169343
169425
  const canSettleX402 = (raw) => {
169344
169426
  if (!raw || typeof raw !== "object") return false;
@@ -169351,47 +169433,71 @@ var detectPaymentRequirement = async (response, preferredProtocol) => {
169351
169433
  return selectSettleableX402Requirement(accepts, void 0, x402Version2) !== null;
169352
169434
  };
169353
169435
  const preferMppFallback = (raw) => preferredProtocol === void 0 && advertisesMpp && !canSettleX402(raw);
169354
- const selectedX402 = (raw) => ({
169436
+ const selectedX402 = (raw, alternateBearerHeader) => ({
169355
169437
  protocol: "x402",
169356
169438
  raw,
169357
- ...preferredProtocol === void 0 && advertisesMpp ? { fallbackProtocol: "mpp" } : {}
169439
+ ...preferredProtocol === void 0 && advertisesMpp ? {
169440
+ fallbackProtocol: "mpp",
169441
+ ...alternateBearerHeader ? { alternateBearerHeader } : {}
169442
+ } : {}
169358
169443
  });
169359
169444
  const x402Header = response.headers.get("payment-required") ?? response.headers.get("x-payment-required");
169360
169445
  if (x402Header) {
169361
- cancelBody2(response);
169446
+ let decoded;
169447
+ let decodable = true;
169362
169448
  try {
169363
- const decoded = JSON.parse(
169364
- Buffer.from(x402Header, "base64").toString("utf8")
169365
- );
169366
- if (preferMppFallback(decoded)) {
169367
- return { protocol: "mpp", raw: { "www-authenticate": wwwAuth } };
169368
- }
169369
- return selectedX402(decoded);
169449
+ decoded = JSON.parse(Buffer.from(x402Header, "base64").toString("utf8"));
169370
169450
  } catch {
169451
+ decodable = false;
169452
+ }
169453
+ if (!decodable) {
169371
169454
  if (preferredProtocol === void 0 && advertisesMpp) {
169372
- return { protocol: "mpp", raw: { "www-authenticate": wwwAuth } };
169455
+ return mppRequirement(
169456
+ await readMppBearerHint(),
169457
+ x402Fallback(
169458
+ "challenge_decode",
169459
+ FETCH_DIAGNOSTIC_CODES.challengeDecodeFailed
169460
+ )
169461
+ );
169373
169462
  }
169463
+ cancelBody2(response);
169374
169464
  return selectedX402({ encoded: x402Header });
169375
169465
  }
169466
+ if (preferMppFallback(decoded)) {
169467
+ return mppRequirement(
169468
+ await readMppBearerHint(),
169469
+ x402Fallback(
169470
+ "rail_select",
169471
+ FETCH_DIAGNOSTIC_CODES.unsupportedPaymentRail
169472
+ )
169473
+ );
169474
+ }
169475
+ cancelBody2(response);
169476
+ return selectedX402(decoded);
169376
169477
  }
169377
169478
  const declaredLen = Number.parseInt(
169378
169479
  response.headers.get("content-length") ?? "",
169379
169480
  10
169380
169481
  );
169381
169482
  const bodyFits = !Number.isFinite(declaredLen) || declaredLen <= MAX_402_PROBE_BYTES;
169483
+ let bodyBearerHint;
169382
169484
  if (bodyFits) {
169383
169485
  try {
169384
169486
  const text = await readClippedText(response, MAX_402_PROBE_BYTES);
169385
169487
  if (text) {
169386
169488
  const parsed = JSON.parse(text);
169489
+ bodyBearerHint = alternateBearerHeaderFromChallengeBody(parsed);
169387
169490
  if (looksLikeX402Body(parsed)) {
169388
169491
  if (preferMppFallback(parsed)) {
169389
- return {
169390
- protocol: "mpp",
169391
- raw: { "www-authenticate": wwwAuth }
169392
- };
169492
+ return mppRequirement(
169493
+ bodyBearerHint,
169494
+ x402Fallback(
169495
+ "rail_select",
169496
+ FETCH_DIAGNOSTIC_CODES.unsupportedPaymentRail
169497
+ )
169498
+ );
169393
169499
  }
169394
- return selectedX402(parsed);
169500
+ return selectedX402(parsed, bodyBearerHint);
169395
169501
  }
169396
169502
  }
169397
169503
  } catch {
@@ -169403,7 +169509,7 @@ var detectPaymentRequirement = async (response, preferredProtocol) => {
169403
169509
  }
169404
169510
  if (advertisesMpp) {
169405
169511
  cancelBody2(response);
169406
- return { protocol: "mpp", raw: { "www-authenticate": wwwAuth } };
169512
+ return mppRequirement(bodyBearerHint);
169407
169513
  }
169408
169514
  cancelBody2(response);
169409
169515
  return { protocol: "unknown", raw: {} };
@@ -169695,6 +169801,7 @@ var recordErrorFetchRun = async (client, opts, result, diagnostics, capabilityId
169695
169801
  failureStage: diagnostics.snapshot().failureStage ?? void 0,
169696
169802
  failureCode: diagnostics.snapshot().failureCode ?? void 0,
169697
169803
  paymentProtocol: diagnostics.snapshot().paymentProtocol ?? void 0,
169804
+ paymentFallback: diagnostics.snapshot().paymentFallback ?? void 0,
169698
169805
  paymentMode: diagnostics.snapshot().paymentMode ?? void 0,
169699
169806
  fundingSource: diagnostics.snapshot().fundingSource ?? void 0,
169700
169807
  stageDurationsMs: diagnostics.snapshot().stageDurationsMs,
@@ -169877,17 +169984,28 @@ var clientFetch = async (client, url4, opts = {}, diagnostics) => {
169877
169984
  });
169878
169985
  if (requirement?.protocol === "x402" || requirement?.protocol === "mpp") {
169879
169986
  diagnostics.selectPaymentProtocol(requirement.protocol);
169987
+ if (requirement.paymentFallback) {
169988
+ diagnostics.recordPaymentFallback(requirement.paymentFallback);
169989
+ }
169880
169990
  const payCall = requirement.protocol === "x402" ? client.payments.pay : client.payments.payMpp;
169881
169991
  try {
169992
+ const paidLegHeaders = withDefaultUserAgent(
169993
+ withDefaultContentType(opts.headers, requestBody)
169994
+ );
169995
+ const mppLegHeaders = () => {
169996
+ const relocation = relocateBearerForMpp(
169997
+ paidLegHeaders,
169998
+ requirement.alternateBearerHeader
169999
+ );
170000
+ if (relocation.dropped) {
170001
+ warnings.push(FETCH_WARNINGS.authorizationBearerDroppedByMpp);
170002
+ }
170003
+ return relocation.headers;
170004
+ };
169882
170005
  const paymentInput = {
169883
170006
  url: requestUrl,
169884
170007
  method,
169885
- // Fresh clone for the paid retry — same rationale as
169886
- // the probe-side clone above. Re-derives the default
169887
- // Content-Type so the paid leg matches the probe.
169888
- headers: withDefaultUserAgent(
169889
- withDefaultContentType(opts.headers, requestBody)
169890
- ),
170008
+ headers: requirement.protocol === "mpp" ? mppLegHeaders() : paidLegHeaders,
169891
170009
  body: requestBody,
169892
170010
  maxPay: opts.maxPay,
169893
170011
  account: opts.account,
@@ -169909,13 +170027,31 @@ var clientFetch = async (client, url4, opts = {}, diagnostics) => {
169909
170027
  try {
169910
170028
  paid = await payCall(paymentInput);
169911
170029
  } catch (error98) {
169912
- if ((error98 instanceof ZeroInsufficientFundsError || error98 instanceof ZeroPermit2AllowanceError) && requirement.protocol === "x402" && requirement.fallbackProtocol === "mpp") {
169913
- diagnostics.issue(
169914
- error98 instanceof ZeroInsufficientFundsError ? "balance_check" : "paid_replay",
169915
- error98 instanceof ZeroInsufficientFundsError ? FETCH_DIAGNOSTIC_CODES.insufficientFunds : FETCH_DIAGNOSTIC_CODES.permit2AllowanceRequired
169916
- );
170030
+ if ((error98 instanceof ZeroInsufficientFundsError || error98 instanceof ZeroPermit2AllowanceError || isPaymentNotAttemptedError(error98)) && requirement.protocol === "x402" && requirement.fallbackProtocol === "mpp") {
170031
+ if (error98 instanceof ZeroInsufficientFundsError) {
170032
+ diagnostics.issue(
170033
+ "balance_check",
170034
+ FETCH_DIAGNOSTIC_CODES.insufficientFunds
170035
+ );
170036
+ } else if (error98 instanceof ZeroPermit2AllowanceError) {
170037
+ diagnostics.issue(
170038
+ "paid_replay",
170039
+ FETCH_DIAGNOSTIC_CODES.permit2AllowanceRequired
170040
+ );
170041
+ }
170042
+ const failedX402 = diagnostics.snapshot();
170043
+ diagnostics.recordPaymentFallback({
170044
+ from: "x402",
170045
+ to: "mpp",
170046
+ stage: error98 instanceof ZeroInsufficientFundsError ? "balance_check" : error98 instanceof ZeroPermit2AllowanceError ? "paid_replay" : failedX402.failureStage ?? "paid_replay",
170047
+ code: error98 instanceof ZeroInsufficientFundsError ? FETCH_DIAGNOSTIC_CODES.insufficientFunds : error98 instanceof ZeroPermit2AllowanceError ? FETCH_DIAGNOSTIC_CODES.permit2AllowanceRequired : failedX402.failureCode ?? FETCH_DIAGNOSTIC_CODES.paymentFailed
170048
+ });
170049
+ diagnostics.recoverFailureForFallback();
169917
170050
  diagnostics.selectPaymentProtocol("mpp");
169918
- paid = await client.payments.payMpp(paymentInput);
170051
+ paid = await client.payments.payMpp({
170052
+ ...paymentInput,
170053
+ headers: mppLegHeaders()
170054
+ });
169919
170055
  } else {
169920
170056
  throw error98;
169921
170057
  }
@@ -170241,6 +170377,7 @@ var clientFetch = async (client, url4, opts = {}, diagnostics) => {
170241
170377
  ),
170242
170378
  failureStage: diagnostics.snapshot().failureStage ?? void 0,
170243
170379
  failureCode: diagnostics.snapshot().failureCode ?? void 0,
170380
+ paymentFallback: diagnostics.snapshot().paymentFallback ?? void 0,
170244
170381
  fundingSource: diagnostics.snapshot().fundingSource ?? void 0,
170245
170382
  stageDurationsMs: diagnostics.snapshot().stageDurationsMs,
170246
170383
  warningCodes: warnings.length > 0 ? warnings : void 0,
@@ -170901,11 +171038,25 @@ var idJagMintResponseSchema = external_exports3.object({
170901
171038
  issuedTokenType: raw.issued_token_type ?? ID_JAG_TOKEN_TYPE,
170902
171039
  expiresIn: raw.expires_in ?? null
170903
171040
  }));
171041
+ var alternateBearerHeaderSchema = external_exports3.object({
171042
+ scheme: external_exports3.string().optional(),
171043
+ header: external_exports3.string(),
171044
+ use_when: external_exports3.string().optional()
171045
+ }).loose();
170904
171046
  var protectedResourceMetadataSchema = external_exports3.object({
170905
171047
  resource: external_exports3.string().optional(),
170906
171048
  resource_name: external_exports3.string().optional(),
170907
- authorization_servers: external_exports3.array(external_exports3.string()).optional()
171049
+ authorization_servers: external_exports3.array(external_exports3.string()).optional(),
171050
+ zeroclick_agent_authorization: alternateBearerHeaderSchema.optional()
170908
171051
  }).loose();
171052
+ var HEADER_NAME = /^[A-Za-z0-9-]+$/;
171053
+ var alternateBearerHeaderFrom = (advertised) => {
171054
+ if (!advertised) return null;
171055
+ if (advertised.scheme && advertised.scheme.toLowerCase() !== "bearer") {
171056
+ return null;
171057
+ }
171058
+ return HEADER_NAME.test(advertised.header) ? advertised.header : null;
171059
+ };
170909
171060
  var serviceAuthMetadataSchema = external_exports3.object({
170910
171061
  resource: external_exports3.string().optional(),
170911
171062
  resource_name: external_exports3.string().optional(),
@@ -171000,7 +171151,10 @@ var AuthIdentity = class {
171000
171151
  tokenEndpoint: metadata.token_endpoint ?? `${trimSlash(server)}/oauth2/token`,
171001
171152
  identityAssertionSupported: (agentAuth.identity_types_supported ?? []).includes(
171002
171153
  IDENTITY_ASSERTION_TYPE
171003
- ) && (assertionTypes ? assertionTypes.includes(ID_JAG_TOKEN_TYPE) : true)
171154
+ ) && (assertionTypes ? assertionTypes.includes(ID_JAG_TOKEN_TYPE) : true),
171155
+ alternateBearerHeader: alternateBearerHeaderFrom(
171156
+ prm.zeroclick_agent_authorization
171157
+ )
171004
171158
  };
171005
171159
  } catch (err) {
171006
171160
  lastError = err;
@@ -171656,14 +171810,30 @@ var paymentSessionSchema = external_exports3.object({
171656
171810
  recipient: external_exports3.string().regex(/^0x[0-9a-fA-F]{40}$/).nullable(),
171657
171811
  cumulativeAmount: external_exports3.string().regex(/^(?:0|[1-9]\d*)$/)
171658
171812
  }).strict();
171813
+ var paymentFallbackSchema = external_exports3.object({
171814
+ from: external_exports3.string(),
171815
+ to: external_exports3.string(),
171816
+ stage: external_exports3.string(),
171817
+ code: external_exports3.string()
171818
+ }).strict();
171659
171819
  var createRunResponseSchema = external_exports3.object({
171660
171820
  runId: external_exports3.string()
171661
171821
  });
171662
171822
  var runListItemSchema = external_exports3.object({
171663
171823
  uid: external_exports3.string(),
171664
- capabilityUid: external_exports3.string(),
171665
- capabilitySlug: external_exports3.string(),
171666
- capabilityName: external_exports3.string(),
171824
+ // ZERO-844 — null on an unattributed (direct-URL) run. Those are only
171825
+ // returned when the caller passes `includeUnattributed`, so a caller that
171826
+ // doesn't opt in never sees a null here.
171827
+ capabilityUid: external_exports3.string().nullable(),
171828
+ capabilitySlug: external_exports3.string().nullable(),
171829
+ capabilityName: external_exports3.string().nullable(),
171830
+ // The redacted unindexed target, populated only when there is no capability.
171831
+ // Older servers omit these; default rather than require so the SDK stays
171832
+ // forward- and backward-compatible.
171833
+ requestHost: external_exports3.string().nullable().optional().default(null),
171834
+ requestPathTemplate: external_exports3.string().nullable().optional().default(null),
171835
+ requestMethod: external_exports3.string().nullable().optional().default(null),
171836
+ attributed: external_exports3.boolean().optional().default(true),
171667
171837
  status: external_exports3.number().nullable(),
171668
171838
  latencyMs: external_exports3.number().nullable(),
171669
171839
  cost: external_exports3.object({ amount: external_exports3.string(), asset: external_exports3.string().nullable() }).nullable(),
@@ -171674,6 +171844,7 @@ var runListItemSchema = external_exports3.object({
171674
171844
  mode: external_exports3.string().nullable(),
171675
171845
  session: paymentSessionSchema.nullable().optional().default(null)
171676
171846
  }).nullable(),
171847
+ paymentFallback: paymentFallbackSchema.nullable().optional().default(null),
171677
171848
  createdAt: external_exports3.coerce.date(),
171678
171849
  reviewed: external_exports3.boolean()
171679
171850
  });
@@ -171695,6 +171866,9 @@ var runDetailSchema = external_exports3.object({
171695
171866
  mode: external_exports3.string().nullable(),
171696
171867
  session: paymentSessionSchema.nullable().optional().default(null)
171697
171868
  }).nullable(),
171869
+ paymentFallback: paymentFallbackSchema.nullable().optional().default(null),
171870
+ // ZERO-844 — null on an unattributed (direct-URL) run, which the server only
171871
+ // returns when `includeUnattributed` is passed.
171698
171872
  capability: external_exports3.object({
171699
171873
  uid: external_exports3.string(),
171700
171874
  slug: external_exports3.string(),
@@ -171703,7 +171877,14 @@ var runDetailSchema = external_exports3.object({
171703
171877
  method: external_exports3.string(),
171704
171878
  whatItDoes: external_exports3.string().nullable(),
171705
171879
  tags: external_exports3.array(external_exports3.string())
171706
- }),
171880
+ }).nullable(),
171881
+ // The redacted unindexed target — the counterpart to `capability` for a run
171882
+ // that has none. Exactly one of the two is non-null.
171883
+ target: external_exports3.object({
171884
+ host: external_exports3.string().nullable(),
171885
+ pathTemplate: external_exports3.string().nullable(),
171886
+ method: external_exports3.string().nullable()
171887
+ }).nullable().optional().default(null),
171707
171888
  reviewed: external_exports3.boolean()
171708
171889
  });
171709
171890
  var createReviewResponseSchema = external_exports3.object({
@@ -171749,6 +171930,8 @@ var Runs = class _Runs {
171749
171930
  * unattributed runs, which it can't do if we strip the target as well.
171750
171931
  */
171751
171932
  static FIELD_GENERATIONS = [
171933
+ // Structured trace of a safe payment-rail fallback.
171934
+ ["paymentFallback"],
171752
171935
  // MPP channel anchor for close-failure reconciliation. Peels first so a
171753
171936
  // newer SDK still records all prior diagnostics against an older API.
171754
171937
  ["paymentSession"],
@@ -171844,6 +172027,8 @@ var Runs = class _Runs {
171844
172027
  if (params2.capabilityId !== void 0)
171845
172028
  query.capabilityId = params2.capabilityId;
171846
172029
  if (params2.unreviewed !== void 0) query.unreviewed = params2.unreviewed;
172030
+ if (params2.includeUnattributed !== void 0)
172031
+ query.includeUnattributed = params2.includeUnattributed;
171847
172032
  if (params2.limit !== void 0) query.limit = params2.limit;
171848
172033
  if (params2.cursor !== void 0) query.cursor = params2.cursor;
171849
172034
  if (params2.walletAddress !== void 0) {
@@ -171865,6 +172050,8 @@ var Runs = class _Runs {
171865
172050
  {
171866
172051
  method: "GET",
171867
172052
  path: `/v1/runs/${runId}`,
172053
+ // ZERO-844 — without this an unattributed (direct-URL) run 404s.
172054
+ query: opts.includeUnattributed !== void 0 ? { includeUnattributed: opts.includeUnattributed } : {},
171868
172055
  signal: opts.signal
171869
172056
  },
171870
172057
  runDetailSchema
@@ -172374,6 +172561,10 @@ var AnalyticsEmitter = class {
172374
172561
  latency_ms: res.latencyMs,
172375
172562
  has_payment: res.payment !== null,
172376
172563
  payment_protocol: res.payment?.protocol ?? res.diagnostics?.paymentProtocol ?? null,
172564
+ payment_fallback_from: res.diagnostics?.paymentFallback?.from ?? null,
172565
+ payment_fallback_to: res.diagnostics?.paymentFallback?.to ?? null,
172566
+ payment_fallback_stage: res.diagnostics?.paymentFallback?.stage ?? null,
172567
+ payment_fallback_code: res.diagnostics?.paymentFallback?.code ?? null,
172377
172568
  funding_source: res.diagnostics?.fundingSource ?? null,
172378
172569
  payment_amount: res.payment?.amount ?? null,
172379
172570
  payment_chain: res.payment?.chain ?? null,
@@ -172414,6 +172605,10 @@ var AnalyticsEmitter = class {
172414
172605
  failure_stage: diagnostics?.failureStage ?? null,
172415
172606
  failure_code: diagnostics?.failureCode ?? null,
172416
172607
  payment_protocol: diagnostics?.paymentProtocol ?? null,
172608
+ payment_fallback_from: diagnostics?.paymentFallback?.from ?? null,
172609
+ payment_fallback_to: diagnostics?.paymentFallback?.to ?? null,
172610
+ payment_fallback_stage: diagnostics?.paymentFallback?.stage ?? null,
172611
+ payment_fallback_code: diagnostics?.paymentFallback?.code ?? null,
172417
172612
  payment_mode: diagnostics?.paymentMode ?? null,
172418
172613
  funding_source: diagnostics?.fundingSource ?? null,
172419
172614
  diagnostic_codes: diagnostics?.issues.map((issue3) => issue3.code) ?? [],
@@ -176664,7 +176859,7 @@ var placeholderFor = (fieldName, propSchema) => String(sampleValueFor(fieldName,
176664
176859
  // package.json
176665
176860
  var package_default2 = {
176666
176861
  name: "@zeroxyz/cli",
176667
- version: "1.33.0",
176862
+ version: "1.34.0",
176668
176863
  type: "module",
176669
176864
  bin: {
176670
176865
  zero: "dist/index.js",
@@ -177405,6 +177600,7 @@ var emitAccessToken = (accessToken, discovery, host, json3, reused) => {
177405
177600
  resource: discovery.resource,
177406
177601
  resourceName: discovery.resourceName,
177407
177602
  tokenEndpoint: discovery.tokenEndpoint,
177603
+ alternateBearerHeader: discovery.alternateBearerHeader,
177408
177604
  reused
177409
177605
  })}
177410
177606
  `
@@ -177416,6 +177612,11 @@ var emitAccessToken = (accessToken, discovery, host, json3, reused) => {
177416
177612
  `Signed in to ${discovery.resourceName ?? host} with your Zero identity.`,
177417
177613
  "The bearer token below is short-lived \u2014 use it right away:",
177418
177614
  ` zero fetch <url> -H "Authorization: Bearer <token>"`,
177615
+ ...discovery.alternateBearerHeader ? [
177616
+ "Paying over MPP (a 402 answered with a Payment credential)? The payment takes Authorization, so send the token as:",
177617
+ ` zero fetch <url> -H "${discovery.alternateBearerHeader}: Bearer <token>"`,
177618
+ "(zero fetch moves a Bearer Authorization there itself when the 402 advertises it.)"
177619
+ ] : [],
177419
177620
  `Re-run this command for a fresh token; it reuses the stored registration.`,
177420
177621
  ""
177421
177622
  ].join("\n")
@@ -178663,7 +178864,7 @@ Bulk bug-report complete: ${ok} ok, ${failed} failed`
178663
178864
  const [latest] = list2.runs;
178664
178865
  if (latest) {
178665
178866
  run = latest.uid;
178666
- capability = capability ?? latest.capabilityUid;
178867
+ capability = capability ?? latest.capabilityUid ?? void 0;
178667
178868
  }
178668
178869
  } catch {
178669
178870
  }
@@ -178767,6 +178968,7 @@ init_esm_shims();
178767
178968
  var MAX_INLINE_REQUEST_BODY_BYTES = 10 * 1024 * 1024;
178768
178969
  var MAX_FILE_REQUEST_BODY_BYTES = 500 * 1024 * 1024;
178769
178970
  var MAX_RESPONSE_BYTES2 = MAX_FILE_REQUEST_BODY_BYTES;
178971
+ var paymentFallbackFor = (diagnostics) => diagnostics?.paymentFallback ?? null;
178770
178972
  var formatPaymentLine = (payment) => {
178771
178973
  const base2 = `Paid ${payment.amount} ${payment.asset} via ${payment.protocol} on ${payment.chain}`;
178772
178974
  return payment.authorizedAmount && payment.authorizedAmount !== payment.amount ? `${base2} (authorized up to ${payment.authorizedAmount})` : base2;
@@ -178989,7 +179191,6 @@ var fetchCommand = (appContext) => new Command("fetch").description(
178989
179191
  let searchId;
178990
179192
  let displayCostAmount;
178991
179193
  let fetchOrigin;
178992
- let runIsAttributed = true;
178993
179194
  if (fromToken) {
178994
179195
  capabilityUid = capFromNoUrl?.uid ?? null;
178995
179196
  capabilityId = options.capability ?? "";
@@ -179092,12 +179293,19 @@ var fetchCommand = (appContext) => new Command("fetch").description(
179092
179293
  } catch (err) {
179093
179294
  const message2 = err instanceof Error ? err.message : "Fetch failed";
179094
179295
  const fetchContext = fetchErrorContext(err);
179296
+ const paymentFallback2 = paymentFallbackFor(
179297
+ fetchContext.diagnostics
179298
+ );
179095
179299
  analyticsService.capture("fetch_error", {
179096
179300
  cliErrorClass: "network",
179097
179301
  fetchId: fetchContext.fetchId,
179098
179302
  failureStage: fetchContext.diagnostics?.failureStage,
179099
179303
  failureCode: fetchContext.diagnostics?.failureCode,
179100
179304
  paymentProtocol: fetchContext.diagnostics?.paymentProtocol,
179305
+ paymentFallbackFrom: paymentFallback2?.from,
179306
+ paymentFallbackTo: paymentFallback2?.to,
179307
+ paymentFallbackStage: paymentFallback2?.stage,
179308
+ paymentFallbackCode: paymentFallback2?.code,
179101
179309
  paymentMode: fetchContext.diagnostics?.paymentMode,
179102
179310
  fundingSource: fetchContext.diagnostics?.fundingSource,
179103
179311
  diagnosticCodes: fetchContext.diagnostics?.issues?.map(
@@ -179129,11 +179337,17 @@ var fetchCommand = (appContext) => new Command("fetch").description(
179129
179337
  settlementState,
179130
179338
  diagnostics
179131
179339
  } = result;
179340
+ const paymentFallback = paymentFallbackFor(diagnostics);
179132
179341
  const isBinary = bodyEncoding === "base64";
179133
179342
  const bodyBytes = isBinary && bodyRaw ? Buffer.from(bodyRaw, "base64") : void 0;
179134
179343
  if (payment && payment.amount !== "unknown" && outcome !== "payment_close_failed") {
179135
179344
  log2(formatPaymentLine(payment));
179136
179345
  }
179346
+ if (paymentFallback && !options.json) {
179347
+ console.error(
179348
+ ` Payment fallback: ${paymentFallback.from} \u2192 ${paymentFallback.to} (${paymentFallback.stage}: ${paymentFallback.code})`
179349
+ );
179350
+ }
179137
179351
  if (payment?.session && outcome === "success") {
179138
179352
  const recipient = payment.session.recipient;
179139
179353
  const recipientLabel = recipient ? `\u2192 ${recipient.slice(0, 8)}...` : "\u2192 (unknown recipient)";
@@ -179192,6 +179406,13 @@ var fetchCommand = (appContext) => new Command("fetch").description(
179192
179406
  `
179193
179407
  );
179194
179408
  }
179409
+ if (sdkWarnings?.includes(
179410
+ FETCH_WARNINGS.authorizationBearerDroppedByMpp
179411
+ ) && !options.json) {
179412
+ console.error(
179413
+ "\n WARNING: your `Authorization: Bearer` header did not reach the service: the MPP payment credential takes Authorization on the paid retry, and the 402 advertised no alternate header for the bearer. If the service accepts it elsewhere (its /.well-known/oauth-protected-resource or auth.md says where), send it in that header instead.\n"
179414
+ );
179415
+ }
179195
179416
  if (sdkWarnings?.length && outcome !== "payment_close_failed" && !options.json) {
179196
179417
  for (const w of sdkWarnings) {
179197
179418
  if (w === FETCH_WARNINGS.bodyTruncated) continue;
@@ -179210,10 +179431,9 @@ var fetchCommand = (appContext) => new Command("fetch").description(
179210
179431
  matchedVia: capabilityResolution.matchedVia
179211
179432
  });
179212
179433
  } else {
179213
- runIsAttributed = false;
179214
179434
  if (walletAddress && !runId) {
179215
179435
  cliSkipReasons.push(
179216
- "no capability resolved \u2014 pass --capability <uid|slug|token> or run `zero search` first so the URL can be matched"
179436
+ "no run was recorded for this call \u2014 retry, or pass --capability <uid|slug|token> so the URL can be matched"
179217
179437
  );
179218
179438
  }
179219
179439
  analyticsService.capture("capability_resolution_missed", {
@@ -179236,6 +179456,10 @@ var fetchCommand = (appContext) => new Command("fetch").description(
179236
179456
  failureStage: diagnostics?.failureStage,
179237
179457
  failureCode: diagnostics?.failureCode,
179238
179458
  paymentProtocol: diagnostics?.paymentProtocol,
179459
+ paymentFallbackFrom: paymentFallback?.from,
179460
+ paymentFallbackTo: paymentFallback?.to,
179461
+ paymentFallbackStage: paymentFallback?.stage,
179462
+ paymentFallbackCode: paymentFallback?.code,
179239
179463
  paymentMode: diagnostics?.paymentMode,
179240
179464
  fundingSource: diagnostics?.fundingSource,
179241
179465
  diagnosticCodes: diagnostics?.issues.map((issue3) => issue3.code),
@@ -179335,7 +179559,7 @@ var fetchCommand = (appContext) => new Command("fetch").description(
179335
179559
  ...sdkWarnings?.length && { warnings: sdkWarnings }
179336
179560
  })
179337
179561
  );
179338
- } else if (runId && outcomeInfo.reviewable && runIsAttributed) {
179562
+ } else if (runId && outcomeInfo.reviewable) {
179339
179563
  const isTTY = process.stderr.isTTY;
179340
179564
  const responded2xx = status !== null && status >= 200 && status < 300;
179341
179565
  console.error(`
@@ -179375,12 +179599,6 @@ var fetchCommand = (appContext) => new Command("fetch").description(
179375
179599
  } else {
179376
179600
  console.error(` zero review ${runId} --no-success`);
179377
179601
  }
179378
- } else if (runId && !runIsAttributed) {
179379
- console.error(`
179380
- Run ID: ${runId}`);
179381
- console.error(
179382
- ` 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.`
179383
- );
179384
179602
  } else if (!runId && cliSkipReasons.length > 0) {
179385
179603
  console.error(
179386
179604
  `
@@ -180899,12 +181117,19 @@ var formatDetail = (r) => {
180899
181117
  lines.push(`Result: ${r.errorClass ?? "\u2014"}`);
180900
181118
  lines.push(`Reviewed: ${r.reviewed ? "yes" : "no"}`);
180901
181119
  lines.push("");
180902
- lines.push(`Capability: ${r.capability.name} (${r.capability.slug})`);
180903
- lines.push(`URL: ${r.capability.method} ${r.capability.url}`);
180904
- if (r.capability.whatItDoes)
180905
- lines.push(`What: ${r.capability.whatItDoes}`);
180906
- if (r.capability.tags.length > 0)
180907
- lines.push(`Tags: ${r.capability.tags.join(", ")}`);
181120
+ if (r.capability) {
181121
+ lines.push(`Capability: ${r.capability.name} (${r.capability.slug})`);
181122
+ lines.push(`URL: ${r.capability.method} ${r.capability.url}`);
181123
+ if (r.capability.whatItDoes)
181124
+ lines.push(`What: ${r.capability.whatItDoes}`);
181125
+ if (r.capability.tags.length > 0)
181126
+ lines.push(`Tags: ${r.capability.tags.join(", ")}`);
181127
+ } else {
181128
+ lines.push(`Capability: \u2014 (direct URL, not indexed)`);
181129
+ lines.push(
181130
+ `Target: ${[r.target?.method, r.target?.host, r.target?.pathTemplate].filter(Boolean).join(" ") || "\u2014"}`
181131
+ );
181132
+ }
180908
181133
  if (r.cost) {
180909
181134
  const { amount: amount2, asset } = r.cost;
180910
181135
  lines.push(`Cost: ${asset ? `${amount2} ${asset}` : amount2}`);
@@ -180921,7 +181146,9 @@ var runsDetailCommand = (appContext) => new Command("detail").description("Show
180921
181146
  const { json: json3 } = cmd.opts();
180922
181147
  try {
180923
181148
  const { client } = appContext.services;
180924
- const run = await client.runs.get(runId);
181149
+ const run = await client.runs.get(runId, {
181150
+ includeUnattributed: true
181151
+ });
180925
181152
  if (json3) {
180926
181153
  console.log(JSON.stringify(run, null, 2));
180927
181154
  return;
@@ -180963,6 +181190,10 @@ Examples:
180963
181190
  const result = await client.runs.list({
180964
181191
  capabilityId: options.capability,
180965
181192
  unreviewed: options.unreviewed,
181193
+ // ZERO-844 — direct-URL runs are reviewable, so they belong in
181194
+ // the list an agent sweeps before finishing a task. Always on
181195
+ // here; the flag exists for older SDK consumers, not for us.
181196
+ includeUnattributed: true,
180966
181197
  ...options.walletAddress ? { walletAddress: options.walletAddress } : {},
180967
181198
  limit: options.limit
180968
181199
  });
@@ -180981,8 +181212,9 @@ Examples:
180981
181212
  const latency = r.latencyMs != null ? `${r.latencyMs}ms` : "\u2014";
180982
181213
  const cost = formatCost2(r.cost);
180983
181214
  const payment = formatPayment(r.payment);
181215
+ const label = r.capabilitySlug ?? [r.requestMethod, r.requestHost, r.requestPathTemplate].filter(Boolean).join(" ") ?? "(direct URL)";
180984
181216
  console.log(
180985
- `[${mark2}] ${r.uid} ${r.capabilitySlug} status=${status} ${latency} ${cost} ${payment} ${when}`
181217
+ `[${mark2}] ${r.uid} ${label} status=${status} ${latency} ${cost} ${payment} ${when}`
180986
181218
  );
180987
181219
  }
180988
181220
  if (result.nextCursor) {
@@ -185993,6 +186225,10 @@ var mapSdkEventToCliEvent = (event) => {
185993
186225
  latencyMs: p.latency_ms,
185994
186226
  hasPayment: p.has_payment,
185995
186227
  paymentProtocol: orUndef(p.payment_protocol),
186228
+ paymentFallbackFrom: orUndef(p.payment_fallback_from),
186229
+ paymentFallbackTo: orUndef(p.payment_fallback_to),
186230
+ paymentFallbackStage: orUndef(p.payment_fallback_stage),
186231
+ paymentFallbackCode: orUndef(p.payment_fallback_code),
185996
186232
  fundingSource: orUndef(p.funding_source),
185997
186233
  paymentAmount: dropUnknownAmount(p.payment_amount),
185998
186234
  paymentChain: orUndef(p.payment_chain),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeroxyz/cli",
3
- "version": "1.33.0",
3
+ "version": "1.34.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "zero": "dist/index.js",