@astrasyncai/verification-gateway 5.10.0 → 5.12.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 (106) hide show
  1. package/README.md +4 -0
  2. package/dist/adapters/express.d.mts +1 -1
  3. package/dist/adapters/express.d.ts +1 -1
  4. package/dist/adapters/express.js +359 -30
  5. package/dist/adapters/express.js.map +1 -1
  6. package/dist/adapters/express.mjs +359 -30
  7. package/dist/adapters/express.mjs.map +1 -1
  8. package/dist/adapters/mcp.d.mts +5 -1
  9. package/dist/adapters/mcp.d.ts +5 -1
  10. package/dist/adapters/mcp.js +168 -41
  11. package/dist/adapters/mcp.js.map +1 -1
  12. package/dist/adapters/mcp.mjs +168 -41
  13. package/dist/adapters/mcp.mjs.map +1 -1
  14. package/dist/adapters/nextjs.d.mts +1 -1
  15. package/dist/adapters/nextjs.d.ts +1 -1
  16. package/dist/adapters/nextjs.js +352 -13
  17. package/dist/adapters/nextjs.js.map +1 -1
  18. package/dist/adapters/nextjs.mjs +352 -13
  19. package/dist/adapters/nextjs.mjs.map +1 -1
  20. package/dist/adapters/sdk.d.mts +9 -1
  21. package/dist/adapters/sdk.d.ts +9 -1
  22. package/dist/adapters/sdk.js +100 -8
  23. package/dist/adapters/sdk.js.map +1 -1
  24. package/dist/adapters/sdk.mjs +100 -8
  25. package/dist/adapters/sdk.mjs.map +1 -1
  26. package/dist/agent/index.js +1 -1
  27. package/dist/agent/index.js.map +1 -1
  28. package/dist/agent/index.mjs +1 -1
  29. package/dist/agent/index.mjs.map +1 -1
  30. package/dist/bin/astrasync-claude-hook.js +805 -16
  31. package/dist/bin/astrasync-codex-hook.js +805 -16
  32. package/dist/bin/astrasync-guard.js +894 -71
  33. package/dist/bin/astrasync.js +951 -74
  34. package/dist/browser/background.js +284 -7
  35. package/dist/browser/background.js.map +1 -1
  36. package/dist/browser/background.mjs +284 -7
  37. package/dist/browser/background.mjs.map +1 -1
  38. package/dist/cli/index.d.mts +8 -8
  39. package/dist/cli/index.d.ts +8 -8
  40. package/dist/cli/index.js +22 -64
  41. package/dist/cli/index.js.map +1 -1
  42. package/dist/cli/index.mjs +22 -64
  43. package/dist/cli/index.mjs.map +1 -1
  44. package/dist/codex/index.d.mts +5 -0
  45. package/dist/codex/index.d.ts +5 -0
  46. package/dist/codex/index.js +821 -24
  47. package/dist/codex/index.js.map +1 -1
  48. package/dist/codex/index.mjs +823 -26
  49. package/dist/codex/index.mjs.map +1 -1
  50. package/dist/cursor/extension.d.mts +9 -2
  51. package/dist/cursor/extension.d.ts +9 -2
  52. package/dist/cursor/extension.js +787 -11
  53. package/dist/cursor/extension.js.map +1 -1
  54. package/dist/cursor/extension.mjs +789 -11
  55. package/dist/cursor/extension.mjs.map +1 -1
  56. package/dist/edge-config.d.mts +1 -1
  57. package/dist/edge-config.d.ts +1 -1
  58. package/dist/edge-config.js +1 -1
  59. package/dist/edge-config.js.map +1 -1
  60. package/dist/edge-config.mjs +1 -1
  61. package/dist/edge-config.mjs.map +1 -1
  62. package/dist/edge-core/index.d.mts +128 -13
  63. package/dist/edge-core/index.d.ts +128 -13
  64. package/dist/edge-core/index.js +337 -55
  65. package/dist/edge-core/index.js.map +1 -1
  66. package/dist/edge-core/index.mjs +334 -55
  67. package/dist/edge-core/index.mjs.map +1 -1
  68. package/dist/enrolment-store-8DyaIOLe.d.mts +26 -0
  69. package/dist/enrolment-store-8DyaIOLe.d.ts +26 -0
  70. package/dist/gateway/gateway.js +284 -7
  71. package/dist/gateway/gateway.js.map +1 -1
  72. package/dist/gateway/gateway.mjs +284 -7
  73. package/dist/gateway/gateway.mjs.map +1 -1
  74. package/dist/git-trigger/git-hooks.d.mts +1 -1
  75. package/dist/git-trigger/git-hooks.d.ts +1 -1
  76. package/dist/index.d.mts +215 -5
  77. package/dist/index.d.ts +215 -5
  78. package/dist/index.js +3756 -80
  79. package/dist/index.js.map +1 -1
  80. package/dist/index.mjs +3748 -80
  81. package/dist/index.mjs.map +1 -1
  82. package/dist/platform-signatures.js +4 -1
  83. package/dist/platform-signatures.js.map +1 -1
  84. package/dist/platform-signatures.mjs +4 -1
  85. package/dist/platform-signatures.mjs.map +1 -1
  86. package/dist/registration/index.js +1 -1
  87. package/dist/registration/index.js.map +1 -1
  88. package/dist/registration/index.mjs +1 -1
  89. package/dist/registration/index.mjs.map +1 -1
  90. package/dist/transport/index.js +1 -1
  91. package/dist/transport/index.js.map +1 -1
  92. package/dist/transport/index.mjs +1 -1
  93. package/dist/transport/index.mjs.map +1 -1
  94. package/dist/{types-CTmUpNpS.d.mts → types-BCkwBA84.d.mts} +12 -0
  95. package/dist/{types-CTmUpNpS.d.ts → types-BCkwBA84.d.ts} +12 -0
  96. package/dist/{types-CtFXmDzm.d.ts → types-C_b4QTyO.d.ts} +18 -0
  97. package/dist/{types-DQrn_kei.d.mts → types-DlshIIR-.d.mts} +18 -0
  98. package/dist/ui/index.d.mts +1 -1
  99. package/dist/ui/index.d.ts +1 -1
  100. package/dist/verify.d.mts +35 -4
  101. package/dist/verify.d.ts +35 -4
  102. package/dist/verify.js +130 -16
  103. package/dist/verify.js.map +1 -1
  104. package/dist/verify.mjs +129 -16
  105. package/dist/verify.mjs.map +1 -1
  106. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { T as TrustLevel, S as SDKOptions, d as VerificationResult, c as VerificationRequest } from '../types-CTmUpNpS.mjs';
1
+ import { T as TrustLevel, S as SDKOptions, d as VerificationResult, c as VerificationRequest } from '../types-BCkwBA84.mjs';
2
2
 
3
3
  /**
4
4
  * AstraSync Universal Verification Gateway — Trust Level helpers.
@@ -101,6 +101,12 @@ declare class VerificationGatewayClient {
101
101
  * fulfil against it only once the order is settled / pending_merchant. An
102
102
  * explicit `buyerEmail` (here or on the bridge handoff body) wins over the
103
103
  * account default.
104
+ *
105
+ * 5.12.0 approval binding: pass the bridge handoff body's `attemptId` (and
106
+ * the same `checkoutSessionId`) so a step-up approval minted for this cart
107
+ * is matched to — and only to — this confirm. A held cart's approval is
108
+ * bound to its checkout session and exact value; a confirm for any other
109
+ * cart is held for its own approval.
104
110
  */
105
111
  confirmCheckout(options: {
106
112
  astraId?: string;
@@ -112,6 +118,8 @@ declare class VerificationGatewayClient {
112
118
  currency?: string;
113
119
  checkoutSessionId?: string;
114
120
  checkoutItems?: VerificationRequest['checkoutItems'];
121
+ /** 5.12.0: the `att_…` attempt-chain id from the bridge handoff body. */
122
+ attemptId?: string;
115
123
  /** 5.6.0: alternate receipt/delivery email (transit-only) — omit to let
116
124
  * the platform default `fulfilment.email` to the buyer's account email. */
117
125
  buyerEmail?: string;
@@ -1,4 +1,4 @@
1
- import { T as TrustLevel, S as SDKOptions, d as VerificationResult, c as VerificationRequest } from '../types-CTmUpNpS.js';
1
+ import { T as TrustLevel, S as SDKOptions, d as VerificationResult, c as VerificationRequest } from '../types-BCkwBA84.js';
2
2
 
3
3
  /**
4
4
  * AstraSync Universal Verification Gateway — Trust Level helpers.
@@ -101,6 +101,12 @@ declare class VerificationGatewayClient {
101
101
  * fulfil against it only once the order is settled / pending_merchant. An
102
102
  * explicit `buyerEmail` (here or on the bridge handoff body) wins over the
103
103
  * account default.
104
+ *
105
+ * 5.12.0 approval binding: pass the bridge handoff body's `attemptId` (and
106
+ * the same `checkoutSessionId`) so a step-up approval minted for this cart
107
+ * is matched to — and only to — this confirm. A held cart's approval is
108
+ * bound to its checkout session and exact value; a confirm for any other
109
+ * cart is held for its own approval.
104
110
  */
105
111
  confirmCheckout(options: {
106
112
  astraId?: string;
@@ -112,6 +118,8 @@ declare class VerificationGatewayClient {
112
118
  currency?: string;
113
119
  checkoutSessionId?: string;
114
120
  checkoutItems?: VerificationRequest['checkoutItems'];
121
+ /** 5.12.0: the `att_…` attempt-chain id from the bridge handoff body. */
122
+ attemptId?: string;
115
123
  /** 5.6.0: alternate receipt/delivery email (transit-only) — omit to let
116
124
  * the platform default `fulfilment.email` to the buyer's account email. */
117
125
  buyerEmail?: string;
@@ -28,7 +28,7 @@ __export(sdk_exports, {
28
28
  module.exports = __toCommonJS(sdk_exports);
29
29
 
30
30
  // src/version.ts
31
- var SDK_VERSION = "5.10.0";
31
+ var SDK_VERSION = "5.12.0";
32
32
 
33
33
  // src/http.ts
34
34
  var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
@@ -63,6 +63,29 @@ function getCachedWellKnownUrls(apiBaseUrl) {
63
63
  return cache.get(apiBaseUrl)?.data;
64
64
  }
65
65
 
66
+ // src/failure-posture.ts
67
+ var DEFAULT_UNAVAILABLE_RETRY_AFTER_S = 30;
68
+ var REJECTED_IDENTITY_DIMENSIONS = /* @__PURE__ */ new Set([
69
+ "identity.invalid_agent_id",
70
+ "identity.unknown_agent",
71
+ "agent.lookup"
72
+ ]);
73
+ var UNKNOWN_AGENT_GUIDANCE = "Register your agent with AstraSync (or, inside an MCP host, add the AstraSync MCP connector for keyless, human-approved registration), then present the canonical ASTRA-* id issued after owner approval.";
74
+ var UNAVAILABLE_DIMENSIONS = /* @__PURE__ */ new Set([
75
+ "verify_access.api_error",
76
+ "middleware.internal_error"
77
+ ]);
78
+ function isVerificationUnavailable(result) {
79
+ if (result.misconfigured) return false;
80
+ return (result.failures ?? []).some((f) => UNAVAILABLE_DIMENSIONS.has(f.dimension));
81
+ }
82
+ function unavailableRetryAfterSeconds(result) {
83
+ if (typeof result.retryAfterMs === "number" && Number.isFinite(result.retryAfterMs)) {
84
+ return Math.max(1, Math.ceil(result.retryAfterMs / 1e3));
85
+ }
86
+ return DEFAULT_UNAVAILABLE_RETRY_AFTER_S;
87
+ }
88
+
66
89
  // src/verify.ts
67
90
  var DEFAULT_CONFIG = {
68
91
  apiBaseUrl: "https://astrasync.ai/api",
@@ -277,11 +300,44 @@ function createGuidanceResponse(_config, reason, options = {}) {
277
300
  // coercing the absent recommendation to a policy 'deny'. Misconfig is
278
301
  // deterministic and intentionally NOT marked retryable.
279
302
  ...isApiError && { retryable: true },
303
+ ...options.httpStatus !== void 0 && { httpStatus: options.httpStatus },
304
+ ...options.retryAfterMs !== void 0 && { retryAfterMs: options.retryAfterMs },
280
305
  correlationId: options.correlationId,
281
306
  attemptId: options.attemptId,
282
307
  verifiedAt: /* @__PURE__ */ new Date()
283
308
  };
284
309
  }
310
+ async function readJsonSafe(response) {
311
+ try {
312
+ const parsed = await response.json();
313
+ return parsed && typeof parsed === "object" ? parsed : {};
314
+ } catch {
315
+ return {};
316
+ }
317
+ }
318
+ function rejectedIdentityGuidance(failures) {
319
+ const f = failures?.find((x) => REJECTED_IDENTITY_DIMENSIONS.has(x.dimension));
320
+ if (!f) return void 0;
321
+ if (f.dimension === "agent.lookup") {
322
+ return `The presented agent identifier is not registered with AstraSync. ${UNKNOWN_AGENT_GUIDANCE}`;
323
+ }
324
+ return f.guidance ? `${f.message} ${f.guidance}` : f.message;
325
+ }
326
+ var MAX_RETRY_AFTER_MS = 15 * 60 * 1e3;
327
+ function parseRetryAfterMs(response) {
328
+ const raw = response.headers?.get?.("retry-after");
329
+ if (!raw) return void 0;
330
+ const trimmed = raw.trim();
331
+ let ms;
332
+ if (/^\d+(\.\d+)?$/.test(trimmed)) {
333
+ ms = Number(trimmed) * 1e3;
334
+ } else {
335
+ const at = Date.parse(trimmed);
336
+ if (Number.isNaN(at)) return void 0;
337
+ ms = at - Date.now();
338
+ }
339
+ return Math.min(MAX_RETRY_AFTER_MS, Math.max(0, Math.round(ms)));
340
+ }
285
341
  async function callVerifyAccessAPI(config, request) {
286
342
  const { credentials, ...requestData } = request;
287
343
  const body = {
@@ -338,7 +394,8 @@ async function callVerifyAccessAPI(config, request) {
338
394
  body: JSON.stringify(body),
339
395
  signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
340
396
  });
341
- const data = await response.json();
397
+ const data = await readJsonSafe(response);
398
+ const retryAfterMs = parseRetryAfterMs(response);
342
399
  if (response.status === 410) {
343
400
  return {
344
401
  success: true,
@@ -376,6 +433,23 @@ async function callVerifyAccessAPI(config, request) {
376
433
  }
377
434
  };
378
435
  }
436
+ if (response.status === 404 && credentials.astraId && (data?.error === "AGENT_NOT_FOUND" || typeof data?.message === "string" && /agent/i.test(data.message))) {
437
+ return {
438
+ success: true,
439
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
440
+ access: {
441
+ allowed: false,
442
+ reason: "unknown_agent",
443
+ failures: [
444
+ {
445
+ dimension: "identity.unknown_agent",
446
+ message: "The presented agent identifier is not registered with AstraSync.",
447
+ guidance: UNKNOWN_AGENT_GUIDANCE
448
+ }
449
+ ]
450
+ }
451
+ };
452
+ }
379
453
  if (!response.ok) {
380
454
  if (response.status === 401) {
381
455
  return {
@@ -390,9 +464,11 @@ async function callVerifyAccessAPI(config, request) {
390
464
  }
391
465
  return {
392
466
  success: false,
393
- error: data.message || data.error || `API returned ${response.status}`,
467
+ error: typeof data?.message === "string" && data.message || typeof data?.error === "string" && data.error || `API returned ${response.status}`,
394
468
  correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
395
- attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
469
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
470
+ httpStatus: response.status,
471
+ ...retryAfterMs !== void 0 && { retryAfterMs }
396
472
  };
397
473
  }
398
474
  return data;
@@ -464,12 +540,14 @@ async function verify(config, request, options) {
464
540
  correlationId: apiResponse.correlationId,
465
541
  attemptId: apiResponse.attemptId,
466
542
  remediation: apiResponse.remediation,
543
+ httpStatus: apiResponse.httpStatus,
544
+ retryAfterMs: apiResponse.retryAfterMs,
467
545
  urls
468
546
  });
469
547
  }
470
548
  if (!apiResponse.access?.allowed) {
471
549
  const aggregatedFailures = apiResponse.access?.failures;
472
- const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true;
550
+ const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true && !aggregatedFailures?.some((f) => REJECTED_IDENTITY_DIMENSIONS.has(f.dimension));
473
551
  const result2 = {
474
552
  identityVerified: idVerifiedFromBackend,
475
553
  policyAllowed: false,
@@ -481,7 +559,10 @@ async function verify(config, request, options) {
481
559
  requiresStepUp: apiResponse.access?.requiresStepUp,
482
560
  requiresApproval: apiResponse.access?.requiresApproval,
483
561
  guidance: {
484
- message: apiResponse.access?.reason || "Access denied by PDLSS policy",
562
+ // 5.12.0: a presented-but-rejected id (malformed / unknown) carries
563
+ // actionable registration guidance on its failure — surface it
564
+ // instead of the bare machine reason ('unknown_agent').
565
+ message: rejectedIdentityGuidance(aggregatedFailures) ?? (apiResponse.access?.reason || "Access denied by PDLSS policy"),
485
566
  registrationUrl: urls?.registrationUrl ?? "",
486
567
  documentationUrl: urls?.documentationUrl ?? "",
487
568
  // 5.1.0: anonymous callers land on this branch — steer MCP-hosted
@@ -581,7 +662,7 @@ async function verify(config, request, options) {
581
662
  registrationUrl: urls?.registrationUrl ?? "",
582
663
  documentationUrl: urls?.documentationUrl ?? ""
583
664
  };
584
- } else if (result.recommendation === "step_up_required") {
665
+ } else if (result.recommendation === "step_up_required" && result.identityVerified) {
585
666
  result.requiresStepUp = true;
586
667
  result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
587
668
  }
@@ -599,7 +680,11 @@ async function quickVerify(config, credentials) {
599
680
  return {
600
681
  identityVerified: result.identityVerified,
601
682
  policyAllowed: result.policyAllowed,
602
- reason: result.denialReasons?.[0]
683
+ reason: result.denialReasons?.[0],
684
+ ...isVerificationUnavailable(result) && {
685
+ unavailable: true,
686
+ retryAfterMs: unavailableRetryAfterSeconds(result) * 1e3
687
+ }
603
688
  };
604
689
  }
605
690
 
@@ -685,6 +770,12 @@ var VerificationGatewayClient = class {
685
770
  * fulfil against it only once the order is settled / pending_merchant. An
686
771
  * explicit `buyerEmail` (here or on the bridge handoff body) wins over the
687
772
  * account default.
773
+ *
774
+ * 5.12.0 approval binding: pass the bridge handoff body's `attemptId` (and
775
+ * the same `checkoutSessionId`) so a step-up approval minted for this cart
776
+ * is matched to — and only to — this confirm. A held cart's approval is
777
+ * bound to its checkout session and exact value; a confirm for any other
778
+ * cart is held for its own approval.
688
779
  */
689
780
  async confirmCheckout(options) {
690
781
  const credentials = {
@@ -704,6 +795,7 @@ var VerificationGatewayClient = class {
704
795
  commercePhase: "confirm",
705
796
  checkoutSessionId: options.checkoutSessionId,
706
797
  checkoutItems: options.checkoutItems,
798
+ ...options.attemptId && { attemptId: options.attemptId },
707
799
  buyerEmail: options.buyerEmail,
708
800
  counterpartyUrl: options.counterpartyUrl,
709
801
  counterpartyType: options.counterpartyType