run402 4.121.0 → 4.122.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 (49) hide show
  1. package/lib/pay.mjs +9 -1
  2. package/lib/vault-capabilities.mjs +1 -1
  3. package/package.json +1 -1
  4. package/sdk/dist/namespaces/deploy.d.ts.map +1 -1
  5. package/sdk/dist/namespaces/deploy.js +87 -31
  6. package/sdk/dist/namespaces/deploy.js.map +1 -1
  7. package/sdk/dist/namespaces/deploy.types.d.ts +4 -2
  8. package/sdk/dist/namespaces/deploy.types.d.ts.map +1 -1
  9. package/sdk/dist/namespaces/deploy.types.js +4 -0
  10. package/sdk/dist/namespaces/deploy.types.js.map +1 -1
  11. package/sdk/dist/namespaces/pay.d.ts +7 -0
  12. package/sdk/dist/namespaces/pay.d.ts.map +1 -1
  13. package/sdk/dist/namespaces/pay.js +5 -0
  14. package/sdk/dist/namespaces/pay.js.map +1 -1
  15. package/sdk/dist/namespaces/projects.d.ts +6 -2
  16. package/sdk/dist/namespaces/projects.d.ts.map +1 -1
  17. package/sdk/dist/namespaces/projects.js +46 -31
  18. package/sdk/dist/namespaces/projects.js.map +1 -1
  19. package/sdk/dist/namespaces/projects.types.d.ts +14 -8
  20. package/sdk/dist/namespaces/projects.types.d.ts.map +1 -1
  21. package/sdk/dist/node/_paid-stack.d.ts +8 -3
  22. package/sdk/dist/node/_paid-stack.d.ts.map +1 -1
  23. package/sdk/dist/node/_paid-stack.js.map +1 -1
  24. package/sdk/dist/node/lightning-paid-fetch.d.ts.map +1 -1
  25. package/sdk/dist/node/lightning-paid-fetch.js +2 -0
  26. package/sdk/dist/node/lightning-paid-fetch.js.map +1 -1
  27. package/sdk/dist/node/mpp-pay-executor.d.ts +40 -0
  28. package/sdk/dist/node/mpp-pay-executor.d.ts.map +1 -0
  29. package/sdk/dist/node/mpp-pay-executor.js +352 -0
  30. package/sdk/dist/node/mpp-pay-executor.js.map +1 -0
  31. package/sdk/dist/node/paid-fetch.d.ts +2 -1
  32. package/sdk/dist/node/paid-fetch.d.ts.map +1 -1
  33. package/sdk/dist/node/paid-fetch.js +44 -18
  34. package/sdk/dist/node/paid-fetch.js.map +1 -1
  35. package/sdk/dist/node/payment-attempts.d.ts +2 -2
  36. package/sdk/dist/node/payment-attempts.d.ts.map +1 -1
  37. package/sdk/dist/node/payment-attempts.js +2 -2
  38. package/sdk/dist/node/payment-attempts.js.map +1 -1
  39. package/sdk/dist/node/payment-offers.d.ts +35 -0
  40. package/sdk/dist/node/payment-offers.d.ts.map +1 -0
  41. package/sdk/dist/node/payment-offers.js +145 -0
  42. package/sdk/dist/node/payment-offers.js.map +1 -0
  43. package/sdk/dist/stale-project-key.d.ts +14 -0
  44. package/sdk/dist/stale-project-key.d.ts.map +1 -0
  45. package/sdk/dist/stale-project-key.js +88 -0
  46. package/sdk/dist/stale-project-key.js.map +1 -0
  47. package/sdk/dist/type-contract.d.ts.map +1 -1
  48. package/sdk/dist/type-contract.js.map +1 -1
  49. package/vault-surface.json +1 -1
package/lib/pay.mjs CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  positionalArgs,
12
12
  } from "./argparse.mjs";
13
13
 
14
- const HELP = `run402 pay — Call an x402-priced URL
14
+ const HELP = `run402 pay — Call an x402- or MPP-priced URL
15
15
 
16
16
  Usage:
17
17
  run402 pay <url> [options]
@@ -45,6 +45,14 @@ The command uses the same wallet and bounded buyer as the SDK. On the lightning
45
45
  rail a 402 naming an lnbtc entry on the wallet's network is paid in sats; one on
46
46
  another network is refused (LIGHTNING_NETWORK_MISMATCH) unless
47
47
  --lightning-pairing names a pairing on that network.
48
+ On the mpp rail a 402 carrying an MPP Tempo charge (WWW-Authenticate: Payment)
49
+ is paid in pathUSD on the first offered Tempo chain the wallet covers; the
50
+ result carries payment.protocol "mpp" and payment.method "tempo". A 402 that
51
+ offers nothing the wallet's rail pays fails PAYMENT_NETWORK_UNSUPPORTED with
52
+ details.offers and the "run402 init <rail> --switch-rail" that would pay it.
53
+ Over MPP the --idempotency-key is correlation only: an unknown outcome is
54
+ resolved by repeating this identical command from the same client, which
55
+ re-presents the same credential and is never charged twice.
48
56
  An unpriced URL is passed through with payment: null.
49
57
  On trusted Run402 PAYMENT_INTENT_PENDING, wait for Retry-After and repeat this
50
58
  identical command with the same payer and --idempotency-key. Never change the key.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * vault-capabilities.mjs — the capability ledger for the KyGit
3
- * marketing surface (openspec/changes/kygit-page-truth-gate, design D1).
3
+ * marketing surface (kygit-page-truth-gate, design D1).
4
4
  *
5
5
  * THIS FILE IS MARKETING-CLAIM GROUND TRUTH. run402-private's page-truth
6
6
  * gate (`scripts/check-kygit-page-truth.mjs`) resolves the PUBLISHED
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "run402",
3
- "version": "4.121.0",
3
+ "version": "4.122.1",
4
4
  "description": "CLI for Run402 — full-stack backend infrastructure for AI agents: Postgres, auth, storage, serverless functions and atomic deploys. Paid with x402/MPP. Includes $0.03 image generation.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/namespaces/deploy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/namespaces/deploy.ts"],"names":[],"mappings":"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"}
@@ -33,6 +33,9 @@ const COMMIT_POLL_INITIAL_MS = 1_000;
33
33
  const COMMIT_POLL_MAX_MS = 30_000;
34
34
  const COMMIT_POLL_BACKOFF_AFTER_MS = 30_000;
35
35
  const COMMIT_POLL_TIMEOUT_MS = 10 * 60 * 1000;
36
+ const REHEARSAL_POLL_INITIAL_MS = 1_000;
37
+ const REHEARSAL_POLL_MAX_MS = 10_000;
38
+ const REHEARSAL_POLL_TIMEOUT_MS = 30 * 60 * 1000;
36
39
  const APPLY_RETRY_DEFAULT_MAX_RETRIES = 2;
37
40
  const APPLY_RETRY_BASE_DELAY_MS = 250;
38
41
  const APPLY_RETRY_MAX_DELAY_MS = 2_000;
@@ -221,25 +224,7 @@ export class Deploy {
221
224
  const body = {};
222
225
  if (opts.teardown !== undefined)
223
226
  body.teardown = opts.teardown;
224
- try {
225
- return await this.client.request(`/apply/v1/plans/${encodeURIComponent(planId)}/rehearse`, {
226
- method: "POST",
227
- body,
228
- ...(opts.project
229
- ? {
230
- authMeta: {
231
- method: "deploy.rehearse",
232
- capability: "project.deploy",
233
- target: { project_id: opts.project },
234
- },
235
- }
236
- : {}),
237
- context: "rehearsing deploy plan",
238
- });
239
- }
240
- catch (err) {
241
- throw translateDeployError(err, "rehearsal", planId, null);
242
- }
227
+ return await requestRehearsal(this.client, planId, body, opts.project);
243
228
  }
244
229
  /**
245
230
  * Resume an operation in `schema_settling` or `activation_pending`. The
@@ -610,18 +595,7 @@ async function rehearseBeforeCommit(client, plan, planId, project, opts, emit) {
610
595
  if (unchanged)
611
596
  return skip(unchanged);
612
597
  emit({ type: "rehearsal.started", planId });
613
- let rehearsed;
614
- try {
615
- rehearsed = await client.request(`/apply/v1/plans/${encodeURIComponent(planId)}/rehearse`, {
616
- method: "POST",
617
- body: {},
618
- authMeta: { method: "deploy.rehearse", capability: "project.deploy", target: { project_id: project } },
619
- context: "rehearsing deploy plan",
620
- });
621
- }
622
- catch (err) {
623
- throw translateDeployError(err, "rehearsal", planId, null);
624
- }
598
+ const rehearsed = await requestRehearsal(client, planId, {}, project, emit);
625
599
  const report = rehearsed.report;
626
600
  emit({
627
601
  type: "rehearsal.finished",
@@ -653,6 +627,85 @@ async function rehearseBeforeCommit(client, plan, planId, project, opts, emit) {
653
627
  ...(bound ? { requiredPlan: { planId: bound.plan_id, planFingerprint: bound.plan_fingerprint } } : {}),
654
628
  };
655
629
  }
630
+ /**
631
+ * Start a rehearsal and return its report. The gateway runs a rehearsal as an
632
+ * operation, detached from the request (a snapshot can take minutes). With a
633
+ * project to poll as, the request asks for the asynchronous shape
634
+ * (`Prefer: respond-async`), gets the operation at once, and polls it until
635
+ * the report is there, relaying its recorded `rehearsal.phase` events; every
636
+ * failure from then on carries the rehearsal's operation id. A gateway that
637
+ * answers with the report inline is used as is, and without a project the
638
+ * response waits for the report.
639
+ */
640
+ async function requestRehearsal(client, planId, body, project, emit) {
641
+ let started;
642
+ try {
643
+ started = await client.request(`/apply/v1/plans/${encodeURIComponent(planId)}/rehearse`, {
644
+ method: "POST",
645
+ body,
646
+ ...(project
647
+ ? {
648
+ headers: { Prefer: "respond-async" },
649
+ authMeta: {
650
+ method: "deploy.rehearse",
651
+ capability: "project.deploy",
652
+ target: { project_id: project },
653
+ },
654
+ }
655
+ : {}),
656
+ context: "rehearsing deploy plan",
657
+ });
658
+ }
659
+ catch (err) {
660
+ throw translateDeployError(err, "rehearsal", planId, null);
661
+ }
662
+ if (started.report || !project)
663
+ return started;
664
+ return await pollRehearsal(client, planId, started.operation_id, project, emit);
665
+ }
666
+ async function pollRehearsal(client, planId, operationId, project, emit) {
667
+ const pollUrl = `/apply/v1/operations/${encodeURIComponent(operationId)}`;
668
+ const headers = await apikeyHeaders(client, project);
669
+ const start = Date.now();
670
+ let interval = REHEARSAL_POLL_INITIAL_MS;
671
+ let eventCursor = null;
672
+ let eventsSupported = Boolean(emit);
673
+ for (;;) {
674
+ await sleep(interval);
675
+ let snapshot;
676
+ try {
677
+ // A poll lost to a 502/503/504 (a gateway rollout) says nothing about
678
+ // the rehearsal, which keeps running on the gateway; read it again.
679
+ snapshot = await requestWithTransientRetry(() => client.request(pollUrl, { headers, context: "polling rehearsal operation" }));
680
+ }
681
+ catch (err) {
682
+ throw translateDeployError(err, "rehearsal", planId, operationId);
683
+ }
684
+ if (emit && eventsSupported) {
685
+ const recorded = await emitRecordedOperationEvents(client, operationId, headers, eventCursor, emit);
686
+ eventsSupported = recorded.supported;
687
+ eventCursor = recorded.cursor;
688
+ }
689
+ if (TERMINAL_STATUSES.includes(snapshot.status)) {
690
+ if (snapshot.rehearsal_report) {
691
+ return { operation_id: operationId, status: snapshot.status, poll_url: pollUrl, report: snapshot.rehearsal_report };
692
+ }
693
+ throw translateGatewayError(snapshot.error, "rehearsal", planId, operationId);
694
+ }
695
+ if (Date.now() - start > REHEARSAL_POLL_TIMEOUT_MS) {
696
+ throw new Run402DeployError(`Timed out waiting for rehearsal operation ${operationId} to finish`, {
697
+ code: "INTERNAL_ERROR",
698
+ phase: "rehearsal",
699
+ retryable: true,
700
+ operationId,
701
+ planId,
702
+ status: 504,
703
+ context: "polling rehearsal",
704
+ });
705
+ }
706
+ interval = Math.min(Math.floor(interval * 1.5), REHEARSAL_POLL_MAX_MS);
707
+ }
708
+ }
656
709
  /**
657
710
  * `"migrations_unchanged"` when the plan carries modern migration buckets and
658
711
  * none are new (all noop); `"no_migrations"` when the buckets are both empty;
@@ -2904,6 +2957,9 @@ function validateRoutePricing(pricing, resource, targetType) {
2904
2957
  if (obj.receipt === "on_fulfillment" && hasLightning) {
2905
2958
  throw invalidRouteSpec(`ReleaseSpec.${resource}.pricing.receipt covers EVM entries only; merchant evidence is not issued for Lightning networks`, `${resource}.pricing.receipt`);
2906
2959
  }
2960
+ if (obj.receipt === "on_fulfillment" && networks.some((network) => network === "tempo" || network === "tempo-testnet")) {
2961
+ throw invalidRouteSpec(`ReleaseSpec.${resource}.pricing.receipt covers x402 EVM entries only; merchant evidence is not issued for Tempo`, `${resource}.pricing.receipt`);
2962
+ }
2907
2963
  }
2908
2964
  /** The declared pricing networks, validated; `["mainnet"]` when omitted. */
2909
2965
  function validateRoutePricingNetworks(networks, resource) {