@kya-os/create-mcpi-app 1.11.3 → 1.11.5

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @kya-os/create-mcpi-app@1.11.3 build /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app
2
+ > @kya-os/create-mcpi-app@1.11.5 build /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app
3
3
  > tsc && chmod +x dist/index.js && node --import tsx scripts/build-bundles.ts
4
4
 
5
5
  🔨 Building template bundles...
@@ -7,23 +7,23 @@
7
7
 
8
8
  📦 Building template: blank
9
9
  ✅ Source files written to /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app/dist/.tmp-bundles/blank
10
- ✅ Bundle built: 8170758 bytes, hash: sha256:72e778e39a337...
10
+ ✅ Bundle built: 8185156 bytes, hash: sha256:5355d615d55b1...
11
11
 
12
12
  📦 Building template: hardware-world
13
13
  ✅ Source files written to /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app/dist/.tmp-bundles/hardware-world
14
- ✅ Bundle built: 8183177 bytes, hash: sha256:1edd8330eddd7...
14
+ ✅ Bundle built: 8197575 bytes, hash: sha256:9a767e0eb1c34...
15
15
 
16
16
  📦 Building template: ecommerce
17
17
  ✅ Source files written to /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app/dist/.tmp-bundles/ecommerce
18
- ✅ Bundle built: 8172452 bytes, hash: sha256:09a58de753d02...
18
+ ✅ Bundle built: 8186850 bytes, hash: sha256:18b9a8622a500...
19
19
 
20
20
  📦 Building template: mix-station
21
21
  ✅ Source files written to /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app/dist/.tmp-bundles/mix-station
22
- ✅ Bundle built: 8185802 bytes, hash: sha256:0c29ba4e04375...
22
+ ✅ Bundle built: 8200200 bytes, hash: sha256:a6fffe48032f7...
23
23
 
24
24
  ✅ All bundles built successfully!
25
25
  Output: /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app/dist/bundles
26
- Version: 1.11.3
27
- Framework: 1.14.3
26
+ Version: 1.11.5
27
+ Framework: 1.14.6
28
28
  Templates: blank, hardware-world, ecommerce, mix-station
29
29
  Manifest: /home/runner/work/xmcp-i/xmcp-i/packages/create-mcpi-app/dist/bundles/manifest.json
@@ -52578,12 +52578,12 @@ function parseAuditConsistencyProofResponse(input2) {
52578
52578
  function toAuditHeadResponse(head) {
52579
52579
  return { schema: AUDIT_HEAD_RESPONSE_SCHEMA_ID, head };
52580
52580
  }
52581
- function toAuditListEntriesResponse(page2) {
52581
+ function toAuditListEntriesResponse(page) {
52582
52582
  return {
52583
52583
  schema: AUDIT_LIST_ENTRIES_RESPONSE_SCHEMA_ID,
52584
- entries: page2.entries,
52585
- head: page2.head,
52586
- nextAfterSequence: page2.nextAfterSequence
52584
+ entries: page.entries,
52585
+ head: page.head,
52586
+ nextAfterSequence: page.nextAfterSequence
52587
52587
  };
52588
52588
  }
52589
52589
  function toAuditInclusionProofResponse(proof) {
@@ -79323,6 +79323,38 @@ var init_idp_scopes = __esm({
79323
79323
  }
79324
79324
  });
79325
79325
 
79326
+ // ../contracts/dist/consent/authorization-progress.js
79327
+ var require_authorization_progress = __commonJS({
79328
+ "../contracts/dist/consent/authorization-progress.js"(exports) {
79329
+ "use strict";
79330
+ Object.defineProperty(exports, "__esModule", { value: true });
79331
+ exports.ConsentPreparationStatusSchema = exports.AuthorizationProgressSchema = void 0;
79332
+ var zod_1 = require_cjs();
79333
+ exports.AuthorizationProgressSchema = zod_1.z.discriminatedUnion("state", [
79334
+ zod_1.z.object({
79335
+ state: zod_1.z.literal("preparation_required"),
79336
+ approval_ready: zod_1.z.literal(false)
79337
+ }).strict(),
79338
+ zod_1.z.object({
79339
+ state: zod_1.z.literal("approval_ready"),
79340
+ approval_ready: zod_1.z.literal(true)
79341
+ }).strict(),
79342
+ zod_1.z.object({ state: zod_1.z.literal("completed"), approval_ready: zod_1.z.literal(false) }).strict(),
79343
+ zod_1.z.object({ state: zod_1.z.literal("expired"), approval_ready: zod_1.z.literal(false) }).strict(),
79344
+ zod_1.z.object({ state: zod_1.z.literal("not_found"), approval_ready: zod_1.z.literal(false) }).strict(),
79345
+ zod_1.z.object({
79346
+ state: zod_1.z.literal("unavailable"),
79347
+ approval_ready: zod_1.z.literal(false)
79348
+ }).strict()
79349
+ ]);
79350
+ exports.ConsentPreparationStatusSchema = zod_1.z.object({
79351
+ authorization: exports.AuthorizationProgressSchema,
79352
+ expires_in: zod_1.z.number().int().min(0).max(600),
79353
+ poll_interval_s: zod_1.z.literal(3)
79354
+ }).strict();
79355
+ }
79356
+ });
79357
+
79326
79358
  // ../consent/dist/cjs/types/config.types.js
79327
79359
  var require_config_types = __commonJS({
79328
79360
  "../consent/dist/cjs/types/config.types.js"(exports) {
@@ -83950,8 +83982,15 @@ var require_consent = __commonJS({
83950
83982
  "../contracts/dist/consent/index.js"(exports) {
83951
83983
  "use strict";
83952
83984
  Object.defineProperty(exports, "__esModule", { value: true });
83953
- exports.AUTH_MODE_REGISTRY = exports.AUTH_MODES = exports.DEFAULT_COLORS = exports.DEFAULT_EXPIRATION_DAYS = exports.DEFAULT_METADATA = exports.DEFAULT_SUCCESS = exports.DEFAULT_TERMS = exports.DEFAULT_UI = exports.DEFAULT_BRANDING = exports.validateAgentMetadata = exports.validateCapabilityGroup = exports.validateCapability = exports.CedarTemplateContextSchema = exports.CedarPolicySchema = exports.RiskLevelSchema = exports.ConsentThemeSchema = exports.AgentMetadataSchema = exports.CapabilityIconSchema = exports.CapabilityGroupSchema = exports.CapabilitySchema = exports.validateCustomField = exports.validateConsentBranding = exports.validateConsentConfig = exports.validateConsentPageConfig = exports.validateOAuthIdentity = exports.validateConsentApprovalResponse = exports.validateConsentApprovalRequest = exports.CredentialAuthResponseSchema = exports.CredentialAuthRequestSchema = exports.ConsentPageConfigSchema = exports.ConsentApprovalResponseSchema = exports.ConsentApprovalRequestSchema = exports.OAuthIdentitySchema = exports.IDVConfigSchema = exports.PasskeyConfigSchema = exports.QRCodeConfigSchema = exports.OTPConfigSchema = exports.MagicLinkConfigSchema = exports.OAuthConfigSchema = exports.CredentialsConfigSchema = exports.AuthModeSchema = exports.ConsentBrandingSchema = exports.ConsentMetadataSchema = exports.ConsentSuccessSchema = exports.ConsentUISchema = exports.ConsentTermsSchema = exports.ConsentCustomFieldOptionSchema = exports.ConsentCustomFieldSchema = exports.ConsentConfigWithMetaSchema = exports.ConsentConfigSchema = void 0;
83954
- exports.oauthIdentitySchema = exports.consentApprovalResponseSchema = exports.consentApprovalRequestSchema = exports.consentPageConfigSchema = exports.consentCustomFieldOptionSchema = exports.consentCustomFieldSchema = exports.consentConfigSchema = exports.consentTermsSchema = exports.consentBrandingSchema = exports.collectsCredentials = exports.requiresExternalAuth = exports.isAuthModeImplemented = exports.getImplementedAuthModes = exports.getAuthModeMetadata = void 0;
83985
+ exports.DEFAULT_COLORS = exports.DEFAULT_EXPIRATION_DAYS = exports.DEFAULT_METADATA = exports.DEFAULT_SUCCESS = exports.DEFAULT_TERMS = exports.DEFAULT_UI = exports.DEFAULT_BRANDING = exports.validateAgentMetadata = exports.validateCapabilityGroup = exports.validateCapability = exports.CedarTemplateContextSchema = exports.CedarPolicySchema = exports.RiskLevelSchema = exports.ConsentThemeSchema = exports.AgentMetadataSchema = exports.CapabilityIconSchema = exports.CapabilityGroupSchema = exports.CapabilitySchema = exports.validateCustomField = exports.validateConsentBranding = exports.validateConsentConfig = exports.validateConsentPageConfig = exports.validateOAuthIdentity = exports.validateConsentApprovalResponse = exports.validateConsentApprovalRequest = exports.CredentialAuthResponseSchema = exports.CredentialAuthRequestSchema = exports.ConsentPageConfigSchema = exports.ConsentApprovalResponseSchema = exports.ConsentApprovalRequestSchema = exports.OAuthIdentitySchema = exports.IDVConfigSchema = exports.PasskeyConfigSchema = exports.QRCodeConfigSchema = exports.OTPConfigSchema = exports.MagicLinkConfigSchema = exports.OAuthConfigSchema = exports.CredentialsConfigSchema = exports.AuthModeSchema = exports.ConsentBrandingSchema = exports.ConsentMetadataSchema = exports.ConsentSuccessSchema = exports.ConsentUISchema = exports.ConsentTermsSchema = exports.ConsentCustomFieldOptionSchema = exports.ConsentCustomFieldSchema = exports.ConsentConfigWithMetaSchema = exports.ConsentConfigSchema = exports.ConsentPreparationStatusSchema = exports.AuthorizationProgressSchema = void 0;
83986
+ exports.oauthIdentitySchema = exports.consentApprovalResponseSchema = exports.consentApprovalRequestSchema = exports.consentPageConfigSchema = exports.consentCustomFieldOptionSchema = exports.consentCustomFieldSchema = exports.consentConfigSchema = exports.consentTermsSchema = exports.consentBrandingSchema = exports.collectsCredentials = exports.requiresExternalAuth = exports.isAuthModeImplemented = exports.getImplementedAuthModes = exports.getAuthModeMetadata = exports.AUTH_MODE_REGISTRY = exports.AUTH_MODES = void 0;
83987
+ var authorization_progress_1 = require_authorization_progress();
83988
+ Object.defineProperty(exports, "AuthorizationProgressSchema", { enumerable: true, get: function() {
83989
+ return authorization_progress_1.AuthorizationProgressSchema;
83990
+ } });
83991
+ Object.defineProperty(exports, "ConsentPreparationStatusSchema", { enumerable: true, get: function() {
83992
+ return authorization_progress_1.ConsentPreparationStatusSchema;
83993
+ } });
83955
83994
  var consent_1 = require_cjs2();
83956
83995
  Object.defineProperty(exports, "ConsentConfigSchema", { enumerable: true, get: function() {
83957
83996
  return consent_1.ConsentConfigSchema;
@@ -159646,7 +159685,19 @@ function anchorSnapshot(rec) {
159646
159685
  nativePolicyRevision: rec.nativePolicyRevision
159647
159686
  };
159648
159687
  }
159649
- var pendingBody = () => ({ status: "pending" });
159688
+ var pendingBody = (rec, now2) => ({
159689
+ status: "pending",
159690
+ // This is the remaining authorization-session lifetime, not the future VC's
159691
+ // lifetime. Preserve the frozen legacy response and the original DO deadline.
159692
+ ...rec.nativeHttp ? {
159693
+ expires_in: Math.max(0, Math.floor((rec.expiresAt - now2) / 1e3)),
159694
+ // Presentation only, emitted after the verified poll pins/matches its holder.
159695
+ authorization: rec.expiresAt - now2 < 1e3 ? { state: "expired", approval_ready: false } : {
159696
+ state: "approval_ready",
159697
+ approval_ready: true
159698
+ }
159699
+ } : {}
159700
+ });
159650
159701
  var pinnedErr = () => ({ error: KYAOS_ERRORS.pickupPinned });
159651
159702
  var invalidSessionErr = () => ({ error: KYAOS_ERRORS.invalidSession });
159652
159703
  var pickupExpiredErr = () => ({ error: KYAOS_ERRORS.pickupExpired });
@@ -159750,7 +159801,7 @@ function reducePoll(rec, holder, now2) {
159750
159801
  }
159751
159802
  return {
159752
159803
  record: { ...working, lastPollAt: now2 },
159753
- response: { status: 202, body: pendingBody() }
159804
+ response: { status: 202, body: pendingBody(working, now2) }
159754
159805
  };
159755
159806
  }
159756
159807
  function reduceApprove(rec, input2, now2) {
@@ -159900,7 +159951,7 @@ async function handlePickupInternal(ctx, request, now2) {
159900
159951
  // ../mcp-i-cloudflare/package.json
159901
159952
  var package_default = {
159902
159953
  name: "@kya-os/mcp-i-cloudflare",
159903
- version: "1.14.3",
159954
+ version: "1.14.6",
159904
159955
  description: "Cloudflare Workers adapter for MCP-I framework",
159905
159956
  main: "dist/index.js",
159906
159957
  types: "dist/index.d.ts",
@@ -159918,6 +159969,7 @@ var package_default = {
159918
159969
  "test:workers": "vitest run --config vitest.workers.config.ts",
159919
159970
  "test:workers:watch": "vitest --config vitest.workers.config.ts",
159920
159971
  "test:e2e": "playwright test",
159972
+ "test:preparation-browser": "playwright test --config playwright.preparation.config.ts",
159921
159973
  "test:e2e:headed": "playwright test --headed",
159922
159974
  "test:e2e:ui": "playwright test --ui",
159923
159975
  "test:e2e:debug": "playwright test --debug",
@@ -159930,7 +159982,7 @@ var package_default = {
159930
159982
  },
159931
159983
  dependencies: {
159932
159984
  "@kya-os/consent": "^0.1.47",
159933
- "@kya-os/contracts": "^1.12.1",
159985
+ "@kya-os/contracts": "^1.12.3",
159934
159986
  "@kya-os/mcp": "1.15.0",
159935
159987
  "@kya-os/mcp-i-core": "^1.9.2",
159936
159988
  "@kya-os/mcp-i-runtime": "^1.2.4",
@@ -166104,6 +166156,166 @@ function nativeCapabilitiesForScopes(groups, scopes) {
166104
166156
  return result;
166105
166157
  }
166106
166158
 
166159
+ // ../mcp-i-cloudflare/dist/delegation-http/consent-preparation-page.js
166160
+ init_escape2();
166161
+ var RECOVERY_MESSAGES = {
166162
+ expired: [
166163
+ "Authorization link expired",
166164
+ "Return to your chat and ask your agent to start a new authorization request. This page cannot renew the expired request."
166165
+ ],
166166
+ not_found: [
166167
+ "Authorization request not found",
166168
+ "Return to your chat and ask your agent for a new authorization request."
166169
+ ],
166170
+ completed: [
166171
+ "This request has been approved",
166172
+ "Return to your chat. Your agent can retrieve the delegation using the key it prepared."
166173
+ ],
166174
+ unavailable: [
166175
+ "Unable to check this request",
166176
+ "Automatic checks have stopped. Try Check again, or ask your agent to check the request. No access was granted by this page."
166177
+ ]
166178
+ };
166179
+ function consentPreparationPage(options) {
166180
+ const nonce = crypto.randomUUID();
166181
+ const path = `/consent?sid=${encodeURIComponent(options.sid)}`;
166182
+ const branding = options.branding;
166183
+ const color = /^#[0-9a-f]{6}$/i.test(branding?.primaryColor ?? "") ? branding.primaryColor : "#6750a4";
166184
+ let logo = "";
166185
+ try {
166186
+ const url3 = new URL(branding?.logoUrl ?? "");
166187
+ if (url3.protocol === "https:" && !url3.username && !url3.password)
166188
+ logo = `<img class="logo" src="${escapeHtml2(url3.href)}" alt="" referrerpolicy="no-referrer">`;
166189
+ } catch {
166190
+ }
166191
+ const seconds = Number.isFinite(options.expiresIn) ? Math.max(0, Math.min(600, Math.floor(options.expiresIn))) : 0;
166192
+ const terminal = options.terminalState ?? (seconds === 0 ? "expired" : void 0);
166193
+ const title = terminal ? RECOVERY_MESSAGES[terminal][0] : "Preparing your authorization request";
166194
+ const message3 = terminal ? RECOVERY_MESSAGES[terminal][1] : "Waiting for your agent. This page will continue automatically when the request is ready.";
166195
+ const html = `<!doctype html>
166196
+ <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
166197
+ <title>${escapeHtml2(title)}</title>
166198
+ <style nonce="${nonce}">
166199
+ :root { color-scheme: light; font-family: system-ui, -apple-system, sans-serif; color: #24212b; background: #f7f6fa; --brand: ${color}; }
166200
+ * { box-sizing: border-box; } [hidden] { display: none !important; } body { margin: 0; min-height: 100vh; display: grid; place-items: center; padding: 28px 16px; }
166201
+ main { width: 100%; max-width: 512px; background: white; border: 1px solid #e5e2eb; border-radius: 20px; padding: 32px; box-shadow: 0 16px 48px #24123b0b; }
166202
+ .brand { display: flex; align-items: center; gap: 12px; font-weight: 650; font-size: 15px; overflow-wrap: anywhere; } .logo { max-width: 112px; max-height: 36px; object-fit: contain; }
166203
+ .badge { color: #5f586d; font-size: 12px; text-transform: uppercase; letter-spacing: .07em; margin-top: 30px; }
166204
+ h1 { font-size: 27px; line-height: 1.2; letter-spacing: -.025em; margin: 12px 0; } p { font-size: 15px; line-height: 1.6; color: #625b6b; }
166205
+ ol { padding: 0; list-style: none; display: grid; gap: 16px; margin: 28px 0; } li { display: flex; align-items: center; gap: 12px; font-size: 14px; }
166206
+ .number { border: 1px solid #ded9e7; border-radius: 50%; display: grid; place-items: center; width: 28px; height: 28px; flex: none; color: #756b84; } li:first-child .number { border-color: var(--brand); color: var(--brand); }
166207
+ .status { padding: 16px; border-radius: 12px; background: #f7f6fa; border: 1px solid #eeebf3; } .status p { margin: 0; } #countdown { font-size: 13px; margin-top: 8px; }
166208
+ details { margin-top: 20px; font-size: 14px; } summary { cursor: pointer; font-weight: 600; } details p { font-size: 14px; } code { overflow-wrap: anywhere; }
166209
+ .reload { display: block; text-align: center; border: 1px solid #d4cede; padding: 12px; border-radius: 8px; margin-top: 24px; color: #393142; text-decoration: none; font-weight: 600; font-size: 14px; }
166210
+ a:focus-visible, summary:focus-visible { outline: 3px solid var(--brand); outline-offset: 4px; } .foot { font-size: 12px; margin: 20px 0 0; text-align: center; }
166211
+ @media(max-width: 420px) { main { padding: 24px; } h1 { font-size: 24px; } }
166212
+ </style></head><body><main>
166213
+ <div class="brand">${logo}<span>${escapeHtml2(branding?.companyName || "KYA-OS")}</span></div>
166214
+ <div class="badge">Secure authorization</div>
166215
+ <h1 id="title">${escapeHtml2(title)}</h1>
166216
+ <p id="intro" ${terminal ? "hidden" : ""}>Your agent needs to prepare its secure connection before you can sign in and approve access. No access has been granted.</p>
166217
+ <ol id="steps" aria-label="Authorization steps" ${terminal ? "hidden" : ""}><li><span class="number">1</span>Agent prepares the request</li><li><span class="number">2</span>You sign in and review permissions</li><li><span class="number">3</span>Agent receives your approved access</li></ol>
166218
+ <div class="status" role="status" aria-live="polite"><p id="status">${escapeHtml2(message3)}</p></div>
166219
+ <p id="countdown" aria-live="off" ${terminal ? "hidden" : ""}>This request expires in ${seconds} seconds.</p>
166220
+ <details><summary>Taking longer than expected?</summary>
166221
+ <p>Return to your chat and ask your agent to finish preparing this authorization request. This page cannot prepare it on the agent\u2019s behalf.</p>
166222
+ <p>If its tools cannot sign requests, this flow cannot be completed in that tool. Do not send your password or browser cookies to the agent.</p>
166223
+ <p>Requested permissions: ${options.scopes.map((scope) => `<code>${escapeHtml2(scope)}</code>`).join(", ")}</p></details>
166224
+ <a class="reload" id="reload" href="${escapeHtml2(path)}" ${terminal && terminal !== "unavailable" ? "hidden" : ""}>Check again</a>
166225
+ <noscript><p>Automatic updates need JavaScript. Once your agent has prepared the request, select Check again.</p></noscript>
166226
+ <p class="foot">Preparation does not approve access. You decide what to allow.</p>
166227
+ </main>${terminal ? "" : `<script nonce="${nonce}">
166228
+ (() => {
166229
+ const consentPath = ${JSON.stringify(path)};
166230
+ const statusPath = consentPath + '&view=preparation';
166231
+ const deadline = performance.now() + ${seconds * 1e3};
166232
+ const wallDeadline = Date.now() + ${seconds * 1e3};
166233
+ const title = document.getElementById('title');
166234
+ const intro = document.getElementById('intro');
166235
+ const status = document.getElementById('status');
166236
+ const countdown = document.getElementById('countdown');
166237
+ const reload = document.getElementById('reload');
166238
+ let stopped = false, suspended = false, generation = 0, timer, expiryTimer, requestTimer, controller, failures = 0;
166239
+ function remaining() {
166240
+ // The original lifetime must also elapse while browser timers are frozen.
166241
+ return Math.min(deadline - performance.now(), wallDeadline - Date.now());
166242
+ }
166243
+ function cancelChecks() {
166244
+ generation++;
166245
+ clearTimeout(timer); clearTimeout(expiryTimer); clearTimeout(requestTimer);
166246
+ if (controller) controller.abort();
166247
+ }
166248
+ function stop(kind) {
166249
+ if (stopped) return;
166250
+ stopped = true;
166251
+ cancelChecks();
166252
+ countdown.hidden = true;
166253
+ if (kind === 'ready') { location.replace(consentPath); return; }
166254
+ const messages = ${JSON.stringify(RECOVERY_MESSAGES)};
166255
+ const message = messages[kind] || messages.unavailable;
166256
+ title.textContent = message[0]; status.textContent = message[1];
166257
+ intro.hidden = true;
166258
+ document.getElementById('steps').hidden = true;
166259
+ reload.hidden = kind !== 'unavailable';
166260
+ }
166261
+ async function poll() {
166262
+ if (stopped || suspended) return;
166263
+ if (remaining() <= 0) { stop('expired'); return; }
166264
+ const requestGeneration = generation;
166265
+ const isCurrent = () => !stopped && !suspended && requestGeneration === generation;
166266
+ const requestController = new AbortController();
166267
+ controller = requestController;
166268
+ const timeout = setTimeout(() => requestController.abort(), 5000);
166269
+ requestTimer = timeout;
166270
+ try {
166271
+ const response = await fetch(statusPath, { headers: { Accept: 'application/json' }, credentials: 'omit', cache: 'no-store', redirect: 'error', signal: requestController.signal });
166272
+ if (!isCurrent()) return;
166273
+ if (response.status === 410) { stop('expired'); return; }
166274
+ if (response.status === 404) { stop('not_found'); return; }
166275
+ if (!response.ok) throw new Error('Unavailable');
166276
+ const body = await response.json();
166277
+ if (!isCurrent()) return;
166278
+ if (remaining() <= 0 || body.expires_in === 0) { stop('expired'); return; }
166279
+ if (!Number.isInteger(body.expires_in) || body.expires_in < 0 || body.expires_in > 600 || body.poll_interval_s !== 3) throw new Error('Invalid lifetime');
166280
+ const auth = body.authorization;
166281
+ if (auth?.state === 'approval_ready' && auth.approval_ready === true) { stop('ready'); return; }
166282
+ if (auth?.state === 'completed' && auth.approval_ready === false) { stop('completed'); return; }
166283
+ if (auth?.state !== 'preparation_required' || auth.approval_ready !== false) throw new Error('Invalid state');
166284
+ failures = 0;
166285
+ status.textContent = 'Waiting for your agent. This page will continue automatically when the request is ready.';
166286
+ countdown.textContent = 'Request expires in ' + Math.min(body.expires_in, Math.ceil(remaining() / 1000)) + ' seconds.';
166287
+ } catch {
166288
+ if (!isCurrent()) return;
166289
+ failures++;
166290
+ if (failures >= 3) { stop('unavailable'); return; }
166291
+ status.textContent = 'Connection interrupted. Checking again shortly\u2026';
166292
+ } finally { clearTimeout(timeout); }
166293
+ if (isCurrent()) timer = setTimeout(poll, 3000);
166294
+ }
166295
+ window.addEventListener('pagehide', () => { suspended = true; cancelChecks(); });
166296
+ window.addEventListener('pageshow', (event) => {
166297
+ if (!event.persisted || !suspended || stopped) return;
166298
+ suspended = false;
166299
+ if (remaining() <= 0) { stop('expired'); return; }
166300
+ expiryTimer = setTimeout(() => stop('expired'), remaining());
166301
+ poll();
166302
+ });
166303
+ expiryTimer = setTimeout(() => stop('expired'), Math.max(0, remaining()));
166304
+ timer = setTimeout(poll, 3000);
166305
+ })();
166306
+ <\/script>`}</body></html>`;
166307
+ return new Response(html, {
166308
+ status: options.status ?? (terminal === "expired" ? 410 : 409),
166309
+ headers: {
166310
+ "Content-Type": "text/html; charset=utf-8",
166311
+ "Cache-Control": "no-store",
166312
+ "Referrer-Policy": "no-referrer",
166313
+ "X-Content-Type-Options": "nosniff",
166314
+ "Content-Security-Policy": `default-src 'none'; script-src 'nonce-${nonce}'; style-src 'nonce-${nonce}'; connect-src 'self'; img-src https:; base-uri 'none'; form-action 'none'; frame-ancestors 'none'`
166315
+ }
166316
+ });
166317
+ }
166318
+
166107
166319
  // ../mcp-i-cloudflare/dist/delegation-http/consent-anchor-bridge.js
166108
166320
  init_crypto3();
166109
166321
  init_storage();
@@ -166359,36 +166571,34 @@ function jsonResponse(body, status) {
166359
166571
  }
166360
166572
  });
166361
166573
  }
166362
- function page(title, bodyInner) {
166363
- return `<!DOCTYPE html>
166364
- <html lang="en">
166365
- <head>
166366
- <meta charset="UTF-8">
166367
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
166368
- <title>${escapeHtml2(title)}</title>
166369
- </head>
166370
- <body>
166371
- ${bodyInner}
166372
- </body>
166373
- </html>`;
166374
- }
166375
- function expiredPage() {
166376
- return htmlResponse(page("Authorization link expired", `<main class="kya-consent-expired">
166377
- <h1>Authorization link expired</h1>
166378
- <p>This authorization request is no longer valid. Please start over to request a new one.</p>
166379
- </main>`), 410);
166380
- }
166381
- function notFoundPage() {
166382
- return htmlResponse(page("Authorization request not found", `<main class="kya-consent-notfound">
166383
- <h1>Authorization request not found</h1>
166384
- <p>We could not find this authorization request. It may have already completed or been cancelled.</p>
166385
- </main>`), 404);
166574
+ var REQUEST_NOT_PREPARED = {
166575
+ title: "Your agent has not prepared this request yet",
166576
+ body: "Before you can approve, your agent must establish the secure key that will receive your permission. No access has been granted.",
166577
+ nextStep: "Return to your chat and ask your agent to finish preparing this authorization request before sharing the approval link.",
166578
+ unsupported: "If the agent's tools cannot sign requests, this flow cannot be completed in that tool. Do not send your password or browser cookies to the agent."
166579
+ };
166580
+ function preparationStatus(state, status = 200, expiresAt = Date.now()) {
166581
+ const body = {
166582
+ authorization: state === "approval_ready" ? { state, approval_ready: true } : { state, approval_ready: false },
166583
+ expires_in: Math.max(0, Math.min(600, Math.floor((expiresAt - Date.now()) / 1e3))),
166584
+ poll_interval_s: 3
166585
+ };
166586
+ return jsonResponse(body, status);
166386
166587
  }
166387
- function approvalFailedPage(message3, status = 410) {
166388
- return htmlResponse(page("Authorization failed", `<main class="kya-consent-failed">
166389
- <h1>Authorization failed</h1>
166390
- <p>${escapeHtml2(message3)}</p>
166391
- </main>`), status);
166588
+ async function preparationBranding(env2) {
166589
+ let timeout;
166590
+ try {
166591
+ return await Promise.race([
166592
+ new ConsentConfigService(env2).getConsentConfig(env2.AGENTSHIELD_PROJECT_ID || "").then((config4) => config4.branding),
166593
+ new Promise((resolve2) => {
166594
+ timeout = setTimeout(() => resolve2(void 0), 1500);
166595
+ })
166596
+ ]);
166597
+ } catch {
166598
+ return void 0;
166599
+ } finally {
166600
+ clearTimeout(timeout);
166601
+ }
166392
166602
  }
166393
166603
  function notFoundJson() {
166394
166604
  return jsonResponse({
@@ -166719,29 +166929,63 @@ async function mintDelegationVcJwt(env2, sid, info, expiresInS, authorizedUser,
166719
166929
  };
166720
166930
  }
166721
166931
  async function handleAnchorConsentGet(c, sid, env2, cfg) {
166722
- const infoResponse = await callAnchor2(env2, sid, INTERNAL_PICKUP_INFO, {
166723
- sid
166932
+ const statusOnly = c.req.query("view") === "preparation";
166933
+ const recovery = async (state, status) => statusOnly ? preparationStatus(state, status) : consentPreparationPage({
166934
+ sid,
166935
+ expiresIn: 0,
166936
+ scopes: [],
166937
+ terminalState: state,
166938
+ status,
166939
+ branding: await preparationBranding(env2)
166724
166940
  });
166941
+ let infoResponse;
166942
+ try {
166943
+ infoResponse = await callAnchor2(env2, sid, INTERNAL_PICKUP_INFO, { sid });
166944
+ } catch {
166945
+ return recovery("unavailable", 502);
166946
+ }
166725
166947
  if (infoResponse.status === 404)
166726
- return notFoundPage();
166948
+ return recovery("not_found", 404);
166727
166949
  if (infoResponse.status === 410)
166728
- return expiredPage();
166950
+ return recovery("expired", 410);
166729
166951
  if (!infoResponse.ok) {
166730
- return approvalFailedPage("This authorization request could not be loaded. Please start over.", 502);
166952
+ return recovery("unavailable", 502);
166731
166953
  }
166732
- const info = await infoResponse.json();
166733
- if (info.nativeHttp && (!info.holderKeyId || info.status === "pending")) {
166734
- return approvalFailedPage("The agent must establish its pickup key before you approve.", 409);
166954
+ let info;
166955
+ try {
166956
+ info = await infoResponse.json();
166957
+ } catch {
166958
+ return recovery("unavailable", 502);
166735
166959
  }
166960
+ if (!info || !Number.isFinite(info.expiresAt) || !["pending", "pinned", "approved"].includes(info.status))
166961
+ return recovery("unavailable", 502);
166736
166962
  if (info.nativeHttp && (!cfg.native || info.nativeIssuerDid !== cfg.native.issuerDid))
166737
- return nativeUnavailable();
166963
+ return recovery("unavailable", 503);
166964
+ if (info.nativeHttp && Date.now() >= info.expiresAt)
166965
+ return recovery("expired", 410);
166966
+ if (info.nativeHttp && (!info.holderKeyId || info.status === "pending")) {
166967
+ if (statusOnly)
166968
+ return preparationStatus("preparation_required", 200, info.expiresAt);
166969
+ const branding = await preparationBranding(env2);
166970
+ return consentPreparationPage({
166971
+ sid,
166972
+ branding,
166973
+ scopes: info.requiredScopes,
166974
+ expiresIn: Math.max(0, Math.floor((info.expiresAt - Date.now()) / 1e3))
166975
+ });
166976
+ }
166738
166977
  if (info.nativeHttp) {
166739
166978
  try {
166740
166979
  info.agentDid = (await nativeHolderBinding(info.holderKeyId)).did;
166741
166980
  } catch {
166742
- return nativeUnavailable();
166981
+ return recovery("unavailable", 503);
166743
166982
  }
166744
166983
  }
166984
+ if (statusOnly) {
166985
+ if (!info.nativeHttp)
166986
+ return preparationStatus("unavailable", 404);
166987
+ return preparationStatus(info.status === "approved" ? "completed" : "approval_ready", 200, info.expiresAt);
166988
+ }
166745
166989
  const csrfToken = await mintCsrfToken(env2, sid);
166746
166990
  const projectId = env2.AGENTSHIELD_PROJECT_ID || "";
166747
166991
  const consentConfig = await new ConsentConfigService(env2).getConsentConfig(projectId);
@@ -166809,7 +167053,7 @@ async function handleAnchorConsentApprove(c, sid, env2, cfg) {
166809
167053
  }
166810
167054
  const info = await infoResponse.json();
166811
167055
  if (info.nativeHttp && (!info.holderKeyId || info.status === "pending")) {
166812
- return approvalFailedJson("The agent must establish its pickup key before you approve.", 409);
167056
+ return approvalFailedJson(`${REQUEST_NOT_PREPARED.title}. ${REQUEST_NOT_PREPARED.body} ${REQUEST_NOT_PREPARED.nextStep} ${REQUEST_NOT_PREPARED.unsupported}`, 409);
166813
167057
  }
166814
167058
  if (info.nativeHttp && (!cfg.native || info.nativeIssuerDid !== cfg.native.issuerDid))
166815
167059
  return nativeUnavailable();