@kya-os/consent 0.1.23 → 0.1.24

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 (149) hide show
  1. package/dist/bundle/index.d.ts +44 -0
  2. package/dist/bundle/shell.d.ts +126 -0
  3. package/dist/bundle/shell.js +295 -0
  4. package/dist/bundle/shell.js.map +1 -0
  5. package/dist/components/consent-button.d.ts +61 -0
  6. package/dist/components/consent-button.js +177 -0
  7. package/dist/components/consent-button.js.map +1 -0
  8. package/dist/components/consent-checkbox.d.ts +61 -0
  9. package/dist/components/consent-checkbox.js +220 -0
  10. package/dist/components/consent-checkbox.js.map +1 -0
  11. package/dist/components/consent-input.d.ts +91 -0
  12. package/dist/components/consent-input.js +332 -0
  13. package/dist/components/consent-input.js.map +1 -0
  14. package/dist/components/consent-oauth-button.d.ts +87 -0
  15. package/dist/components/consent-oauth-button.js +389 -0
  16. package/dist/components/consent-oauth-button.js.map +1 -0
  17. package/dist/components/consent-otp-input.d.ts +92 -0
  18. package/dist/components/consent-otp-input.js +385 -0
  19. package/dist/components/consent-otp-input.js.map +1 -0
  20. package/dist/components/consent-permissions.d.ts +104 -0
  21. package/dist/components/consent-permissions.js +430 -0
  22. package/dist/components/consent-permissions.js.map +1 -0
  23. package/dist/components/consent-shell.d.ts +72 -0
  24. package/dist/components/consent-shell.js +231 -0
  25. package/dist/components/consent-shell.js.map +1 -0
  26. package/dist/components/consent-terms.d.ts +89 -0
  27. package/dist/components/consent-terms.js +284 -0
  28. package/dist/components/consent-terms.js.map +1 -0
  29. package/dist/components/index.d.ts +19 -0
  30. package/dist/constants/auth-modes.d.ts +59 -0
  31. package/dist/constants/auth-modes.js +120 -0
  32. package/dist/constants/auth-modes.js.map +1 -0
  33. package/dist/constants/colors.d.ts +38 -0
  34. package/dist/constants/colors.js +37 -0
  35. package/dist/constants/colors.js.map +1 -0
  36. package/dist/constants/defaults.d.ts +112 -0
  37. package/dist/constants/defaults.js +143 -0
  38. package/dist/constants/defaults.js.map +1 -0
  39. package/dist/constants/index.d.ts +12 -0
  40. package/dist/constants/index.js +16 -0
  41. package/dist/constants/index.js.map +1 -0
  42. package/dist/index.d.ts +19 -0
  43. package/dist/index.js +28 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/react/index.d.ts +123 -0
  46. package/dist/resolution/index.d.ts +12 -0
  47. package/dist/resolution/index.js +12 -0
  48. package/dist/resolution/index.js.map +1 -0
  49. package/dist/resolution/resolve-branding.d.ts +70 -0
  50. package/dist/resolution/resolve-branding.js +149 -0
  51. package/dist/resolution/resolve-branding.js.map +1 -0
  52. package/dist/resolution/resolve-config.d.ts +81 -0
  53. package/dist/resolution/resolve-config.js +258 -0
  54. package/dist/resolution/resolve-config.js.map +1 -0
  55. package/dist/resolution/resolve-copy.d.ts +53 -0
  56. package/dist/resolution/resolve-copy.js +128 -0
  57. package/dist/resolution/resolve-copy.js.map +1 -0
  58. package/dist/schemas/api.schemas.d.ts +122 -122
  59. package/dist/schemas/api.schemas.js +162 -0
  60. package/dist/schemas/api.schemas.js.map +1 -0
  61. package/dist/schemas/branding.schemas.d.ts +100 -0
  62. package/dist/schemas/branding.schemas.js +54 -0
  63. package/dist/schemas/branding.schemas.js.map +1 -0
  64. package/dist/schemas/config.schemas.d.ts +110 -110
  65. package/dist/schemas/config.schemas.js +141 -0
  66. package/dist/schemas/config.schemas.js.map +1 -0
  67. package/dist/schemas/index.d.ts +13 -0
  68. package/dist/schemas/index.js +13 -0
  69. package/dist/schemas/index.js.map +1 -0
  70. package/dist/schemas/modes.schemas.d.ts +28 -28
  71. package/dist/schemas/modes.schemas.js +104 -0
  72. package/dist/schemas/modes.schemas.js.map +1 -0
  73. package/dist/security/escape.d.ts +114 -0
  74. package/dist/security/escape.js +197 -0
  75. package/dist/security/escape.js.map +1 -0
  76. package/dist/security/index.d.ts +10 -0
  77. package/dist/security/index.js +10 -0
  78. package/dist/security/index.js.map +1 -0
  79. package/dist/security/validators.d.ts +98 -0
  80. package/dist/security/validators.js +199 -0
  81. package/dist/security/validators.js.map +1 -0
  82. package/dist/styles/css-variables.d.ts +78 -0
  83. package/dist/styles/css-variables.js +120 -0
  84. package/dist/styles/css-variables.js.map +1 -0
  85. package/dist/styles/index.d.ts +12 -0
  86. package/dist/styles/index.js +12 -0
  87. package/dist/styles/index.js.map +1 -0
  88. package/dist/styles/stylesheet.d.ts +57 -0
  89. package/dist/styles/stylesheet.js +197 -0
  90. package/dist/styles/stylesheet.js.map +1 -0
  91. package/dist/styles/tokens.d.ts +141 -0
  92. package/dist/styles/tokens.js +180 -0
  93. package/dist/styles/tokens.js.map +1 -0
  94. package/dist/templates/base/base-template.d.ts +81 -0
  95. package/dist/templates/base/base-template.js +278 -0
  96. package/dist/templates/base/base-template.js.map +1 -0
  97. package/dist/templates/base/components.d.ts +120 -0
  98. package/dist/templates/base/components.js +279 -0
  99. package/dist/templates/base/components.js.map +1 -0
  100. package/dist/templates/base/index.d.ts +8 -0
  101. package/dist/templates/base/index.js +8 -0
  102. package/dist/templates/base/index.js.map +1 -0
  103. package/dist/templates/index.d.ts +18 -0
  104. package/dist/templates/index.js +18 -0
  105. package/dist/templates/index.js.map +1 -0
  106. package/dist/templates/modes/consent-only.template.d.ts +36 -0
  107. package/dist/templates/modes/consent-only.template.js +70 -0
  108. package/dist/templates/modes/consent-only.template.js.map +1 -0
  109. package/dist/templates/modes/credentials.template.d.ts +65 -0
  110. package/dist/templates/modes/credentials.template.js +410 -0
  111. package/dist/templates/modes/credentials.template.js.map +1 -0
  112. package/dist/templates/modes/index.d.ts +14 -0
  113. package/dist/templates/modes/index.js +14 -0
  114. package/dist/templates/modes/index.js.map +1 -0
  115. package/dist/templates/modes/magic-link.template.d.ts +33 -0
  116. package/dist/templates/modes/magic-link.template.js +192 -0
  117. package/dist/templates/modes/magic-link.template.js.map +1 -0
  118. package/dist/templates/modes/oauth.template.d.ts +32 -0
  119. package/dist/templates/modes/oauth.template.js +121 -0
  120. package/dist/templates/modes/oauth.template.js.map +1 -0
  121. package/dist/templates/modes/otp.template.d.ts +35 -0
  122. package/dist/templates/modes/otp.template.js +312 -0
  123. package/dist/templates/modes/otp.template.js.map +1 -0
  124. package/dist/templates/modes/success.template.d.ts +41 -0
  125. package/dist/templates/registry.d.ts +68 -0
  126. package/dist/templates/registry.js +125 -0
  127. package/dist/templates/registry.js.map +1 -0
  128. package/dist/types/api.types.d.ts +147 -0
  129. package/dist/types/api.types.js +9 -0
  130. package/dist/types/api.types.js.map +1 -0
  131. package/dist/types/branding.types.d.ts +53 -0
  132. package/dist/types/branding.types.js +9 -0
  133. package/dist/types/branding.types.js.map +1 -0
  134. package/dist/types/config.types.d.ts +201 -0
  135. package/dist/types/config.types.js +9 -0
  136. package/dist/types/config.types.js.map +1 -0
  137. package/dist/types/copy.types.d.ts +109 -0
  138. package/dist/types/copy.types.js +9 -0
  139. package/dist/types/copy.types.js.map +1 -0
  140. package/dist/types/index.d.ts +15 -0
  141. package/dist/types/index.js +15 -0
  142. package/dist/types/index.js.map +1 -0
  143. package/dist/types/modes.types.d.ts +287 -0
  144. package/dist/types/modes.types.js +136 -0
  145. package/dist/types/modes.types.js.map +1 -0
  146. package/dist/types/page.types.d.ts +120 -0
  147. package/dist/types/page.types.js +9 -0
  148. package/dist/types/page.types.js.map +1 -0
  149. package/package.json +1 -1
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Consent Bundle Entry Point
3
+ *
4
+ * This file serves as the entry point for bundling all consent components
5
+ * into a single file (consent.js) that can be served by Workers.
6
+ *
7
+ * When bundled with esbuild, this creates a self-contained script that:
8
+ * 1. Imports Lit and all dependencies
9
+ * 2. Registers all custom elements
10
+ * 3. Makes <mcp-consent> and all sub-components available in the browser
11
+ *
12
+ * Usage in Worker:
13
+ * ```typescript
14
+ * // Serve consent.js at /consent.js
15
+ * import CONSENT_BUNDLE from './consent.bundle.js';
16
+ *
17
+ * app.get('/consent.js', () => new Response(CONSENT_BUNDLE, {
18
+ * headers: { 'Content-Type': 'application/javascript' }
19
+ * }));
20
+ * ```
21
+ *
22
+ * @module @kya-os/consent/bundle
23
+ */
24
+ import '../components/consent-button.js';
25
+ import '../components/consent-checkbox.js';
26
+ import '../components/consent-input.js';
27
+ import '../components/consent-shell.js';
28
+ import '../components/consent-permissions.js';
29
+ import '../components/consent-terms.js';
30
+ import '../components/consent-oauth-button.js';
31
+ import '../components/consent-otp-input.js';
32
+ import '../components/mcp-consent.js';
33
+ export { McpConsent } from '../components/mcp-consent.js';
34
+ export { ConsentButton } from '../components/consent-button.js';
35
+ export { ConsentCheckbox } from '../components/consent-checkbox.js';
36
+ export { ConsentInput } from '../components/consent-input.js';
37
+ export { ConsentShell } from '../components/consent-shell.js';
38
+ export { ConsentPermissions } from '../components/consent-permissions.js';
39
+ export { ConsentTerms } from '../components/consent-terms.js';
40
+ export { ConsentOAuthButton } from '../components/consent-oauth-button.js';
41
+ export { ConsentOTPInput } from '../components/consent-otp-input.js';
42
+ export type { ConsentConfig, ResolvedConsentConfig } from '../types/config.types.js';
43
+ export type { OAuthIdentity } from '../types/api.types.js';
44
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Consent HTML Shell Generator
3
+ *
4
+ * Generates the minimal HTML shell that Workers serve for consent pages.
5
+ * The shell loads the bundled consent.js and renders <mcp-consent>.
6
+ *
7
+ * Architecture:
8
+ * 1. Worker receives consent page request
9
+ * 2. Worker calls generateConsentShell() with config
10
+ * 3. Browser loads HTML, fetches consent.js
11
+ * 4. Lit components render the consent UI
12
+ * 5. Form submission posts back to Worker
13
+ *
14
+ * @module @kya-os/consent/bundle/shell
15
+ */
16
+ import type { ConsentConfig } from '../types/config.types.js';
17
+ import type { OAuthIdentity } from '../types/api.types.js';
18
+ /**
19
+ * Options for generating the consent HTML shell
20
+ */
21
+ export interface ConsentShellOptions {
22
+ /** Consent page configuration (from AgentShield remote config) */
23
+ config: ConsentConfig;
24
+ /** Tool being requested */
25
+ tool: string;
26
+ /** Permission scopes requested */
27
+ scopes: string[];
28
+ /** Agent's DID */
29
+ agentDid: string;
30
+ /** Session identifier */
31
+ sessionId: string;
32
+ /** Project identifier */
33
+ projectId: string;
34
+ /** Server URL for form submission */
35
+ serverUrl: string;
36
+ /** OAuth identity if already authenticated */
37
+ oauthIdentity?: OAuthIdentity;
38
+ /** Path to consent.js bundle (defaults to '/consent.js') */
39
+ bundlePath?: string;
40
+ /** Custom page title */
41
+ pageTitle?: string;
42
+ /** CSP nonce for inline scripts/styles */
43
+ nonce?: string;
44
+ /** Authentication mode (consent-only, credentials, oauth, magic-link, otp) */
45
+ authMode?: string;
46
+ /** Provider name for credentials/oauth flows */
47
+ provider?: string;
48
+ /** CSRF token for form security (required for credential auth) */
49
+ csrfToken?: string;
50
+ /** Credential provider type from prior auth step (for 3-screen flow) */
51
+ credentialProviderType?: string;
52
+ /** Credential provider name from prior auth step (for 3-screen flow) */
53
+ credentialProvider?: string;
54
+ /**
55
+ * User DID from prior auth step
56
+ * CRITICAL: Bypasses KV eventual consistency issues by passing directly
57
+ */
58
+ userDid?: string;
59
+ /**
60
+ * User email from credential provider response
61
+ * Used for human-readable display in AgentShield dashboard (user_identifier)
62
+ */
63
+ credentialUserEmail?: string;
64
+ /**
65
+ * Provider's internal user ID from credential provider response
66
+ * Used for business reference (e.g., Hardware World customer ID 696395)
67
+ */
68
+ credentialProviderUserId?: string;
69
+ /**
70
+ * Pre-built OAuth authorization URL
71
+ * When provided, the OAuth button will link directly to this URL instead of
72
+ * constructing a URL like /oauth/:provider which may not exist.
73
+ * Example: https://github.com/login/oauth/authorize?client_id=...&redirect_uri=...
74
+ */
75
+ oauthUrl?: string;
76
+ /**
77
+ * Authorization type from tool protection config
78
+ * Determines the provider_type sent in credential form submissions
79
+ * Values: 'password', 'oauth2', 'none', etc.
80
+ * Default: 'password' for credential flows
81
+ */
82
+ authorizationType?: string;
83
+ }
84
+ /**
85
+ * Generate the consent page HTML shell
86
+ *
87
+ * This produces a minimal HTML document that:
88
+ * - Loads the bundled consent.js
89
+ * - Renders the <mcp-consent> web component
90
+ * - Includes a loading skeleton for perceived performance
91
+ * - Has a no-JS fallback form
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * const html = generateConsentShell({
96
+ * config: remoteConfig,
97
+ * tool: 'purchase',
98
+ * scopes: ['billing:read', 'orders:write'],
99
+ * agentDid: 'did:key:z6Mk...',
100
+ * sessionId: 'sess_abc123',
101
+ * projectId: 'proj_xyz',
102
+ * serverUrl: 'https://api.example.com',
103
+ * });
104
+ *
105
+ * return new Response(html, {
106
+ * headers: { 'Content-Type': 'text/html' }
107
+ * });
108
+ * ```
109
+ */
110
+ export declare function generateConsentShell(options: ConsentShellOptions): string;
111
+ /**
112
+ * Generate inline consent component (no external bundle)
113
+ *
114
+ * For scenarios where you want to inline everything into a single HTML response.
115
+ * This is useful for:
116
+ * - Offline/embedded scenarios
117
+ * - Single-request consent pages
118
+ * - Testing/debugging
119
+ *
120
+ * Note: This requires the consent bundle to be inlined as a string.
121
+ *
122
+ * @param options - Shell options
123
+ * @param bundleSource - The bundled consent.js source code
124
+ */
125
+ export declare function generateInlineConsentShell(options: Omit<ConsentShellOptions, 'bundlePath'>, bundleSource: string): string;
126
+ //# sourceMappingURL=shell.d.ts.map
@@ -0,0 +1,295 @@
1
+ /**
2
+ * Consent HTML Shell Generator
3
+ *
4
+ * Generates the minimal HTML shell that Workers serve for consent pages.
5
+ * The shell loads the bundled consent.js and renders <mcp-consent>.
6
+ *
7
+ * Architecture:
8
+ * 1. Worker receives consent page request
9
+ * 2. Worker calls generateConsentShell() with config
10
+ * 3. Browser loads HTML, fetches consent.js
11
+ * 4. Lit components render the consent UI
12
+ * 5. Form submission posts back to Worker
13
+ *
14
+ * @module @kya-os/consent/bundle/shell
15
+ */
16
+ import { escapeHtml, escapeAttr } from '../security/escape.js';
17
+ /**
18
+ * Generate the consent page HTML shell
19
+ *
20
+ * This produces a minimal HTML document that:
21
+ * - Loads the bundled consent.js
22
+ * - Renders the <mcp-consent> web component
23
+ * - Includes a loading skeleton for perceived performance
24
+ * - Has a no-JS fallback form
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const html = generateConsentShell({
29
+ * config: remoteConfig,
30
+ * tool: 'purchase',
31
+ * scopes: ['billing:read', 'orders:write'],
32
+ * agentDid: 'did:key:z6Mk...',
33
+ * sessionId: 'sess_abc123',
34
+ * projectId: 'proj_xyz',
35
+ * serverUrl: 'https://api.example.com',
36
+ * });
37
+ *
38
+ * return new Response(html, {
39
+ * headers: { 'Content-Type': 'text/html' }
40
+ * });
41
+ * ```
42
+ */
43
+ export function generateConsentShell(options) {
44
+ const { config, tool, scopes, agentDid, sessionId, projectId, serverUrl, oauthIdentity, bundlePath = '/consent.js', pageTitle = 'Permission Request', nonce, authMode, provider, csrfToken, credentialProviderType, credentialProvider, userDid, // CRITICAL: Bypasses KV consistency issues
45
+ credentialUserEmail, // User email from credential provider
46
+ credentialProviderUserId, // Provider's user ID (e.g., customer ID)
47
+ oauthUrl, // Pre-built OAuth authorization URL
48
+ authorizationType, // Dynamic authorization type from tool protection
49
+ } = options;
50
+ // Safely serialize config as JSON for attribute
51
+ const configJson = JSON.stringify(config);
52
+ const scopesJson = JSON.stringify(scopes);
53
+ const oauthJson = oauthIdentity ? JSON.stringify(oauthIdentity) : null;
54
+ // Build nonce attribute if provided
55
+ const nonceAttr = nonce ? ` nonce="${escapeAttr(nonce)}"` : '';
56
+ return `<!DOCTYPE html>
57
+ <html lang="en">
58
+ <head>
59
+ <meta charset="UTF-8">
60
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
61
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
62
+ <title>${escapeHtml(pageTitle)}</title>
63
+
64
+ <!-- Preload the bundle for faster loading -->
65
+ <link rel="preload" href="${escapeAttr(bundlePath)}" as="script" crossorigin>
66
+
67
+ <!-- Load consent components bundle -->
68
+ <script type="module" src="${escapeAttr(bundlePath)}"${nonceAttr}></script>
69
+
70
+ <style${nonceAttr}>
71
+ /* Base styles */
72
+ *, *::before, *::after {
73
+ box-sizing: border-box;
74
+ }
75
+
76
+ body {
77
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
78
+ background: #f3f4f6;
79
+ min-height: 100vh;
80
+ margin: 0;
81
+ display: flex;
82
+ align-items: center;
83
+ justify-content: center;
84
+ padding: 1rem;
85
+ }
86
+
87
+ /* Loading skeleton - shown while component loads */
88
+ .loading-skeleton {
89
+ max-width: 512px;
90
+ width: 100%;
91
+ background: white;
92
+ border-radius: 20px;
93
+ padding: 2rem;
94
+ box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
95
+ }
96
+
97
+ .skeleton-header {
98
+ display: flex;
99
+ align-items: center;
100
+ gap: 1rem;
101
+ margin-bottom: 1.5rem;
102
+ }
103
+
104
+ .skeleton-avatar {
105
+ width: 48px;
106
+ height: 48px;
107
+ background: #e5e7eb;
108
+ border-radius: 12px;
109
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
110
+ }
111
+
112
+ .skeleton-line {
113
+ height: 1rem;
114
+ background: #e5e7eb;
115
+ border-radius: 0.25rem;
116
+ margin-bottom: 0.75rem;
117
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
118
+ }
119
+
120
+ .skeleton-line.short { width: 60%; }
121
+ .skeleton-line.medium { width: 80%; }
122
+ .skeleton-line.full { width: 100%; }
123
+
124
+ .skeleton-button {
125
+ height: 44px;
126
+ background: #e5e7eb;
127
+ border-radius: 8px;
128
+ margin-top: 1.5rem;
129
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
130
+ }
131
+
132
+ @keyframes pulse {
133
+ 0%, 100% { opacity: 1; }
134
+ 50% { opacity: 0.5; }
135
+ }
136
+
137
+ /* Hide skeleton when component is defined */
138
+ mcp-consent:defined + .loading-skeleton {
139
+ display: none;
140
+ }
141
+
142
+ /* No-JS fallback styling */
143
+ noscript .fallback-form {
144
+ max-width: 512px;
145
+ width: 100%;
146
+ background: white;
147
+ border-radius: 20px;
148
+ padding: 2rem;
149
+ box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
150
+ }
151
+
152
+ noscript h1 {
153
+ font-size: 1.25rem;
154
+ font-weight: 600;
155
+ color: #111827;
156
+ margin: 0 0 1rem;
157
+ }
158
+
159
+ noscript p {
160
+ color: #6b7280;
161
+ margin: 0 0 1.5rem;
162
+ }
163
+
164
+ noscript button {
165
+ width: 100%;
166
+ padding: 0.75rem 1rem;
167
+ background: #2563eb;
168
+ color: white;
169
+ border: none;
170
+ border-radius: 8px;
171
+ font-size: 0.875rem;
172
+ font-weight: 500;
173
+ cursor: pointer;
174
+ }
175
+
176
+ noscript button:hover {
177
+ background: #1d4ed8;
178
+ }
179
+ </style>
180
+ </head>
181
+ <body>
182
+ <!-- Main consent component -->
183
+ <mcp-consent
184
+ config='${escapeAttr(configJson)}'
185
+ tool="${escapeAttr(tool)}"
186
+ scopes='${escapeAttr(scopesJson)}'
187
+ agent-did="${escapeAttr(agentDid)}"
188
+ session-id="${escapeAttr(sessionId)}"
189
+ project-id="${escapeAttr(projectId)}"
190
+ server-url="${escapeAttr(serverUrl)}"
191
+ ${oauthJson ? `oauth-identity='${escapeAttr(oauthJson)}'` : ''}
192
+ ${authMode ? `auth-mode="${escapeAttr(authMode)}"` : ''}
193
+ ${provider ? `provider="${escapeAttr(provider)}"` : ''}
194
+ ${csrfToken ? `csrf-token="${escapeAttr(csrfToken)}"` : ''}
195
+ ${credentialProviderType ? `credential-provider-type="${escapeAttr(credentialProviderType)}"` : ''}
196
+ ${credentialProvider ? `credential-provider="${escapeAttr(credentialProvider)}"` : ''}
197
+ ${userDid ? `user-did="${escapeAttr(userDid)}"` : ''}
198
+ ${credentialUserEmail ? `credential-user-email="${escapeAttr(credentialUserEmail)}"` : ''}
199
+ ${credentialProviderUserId ? `credential-provider-user-id="${escapeAttr(credentialProviderUserId)}"` : ''}
200
+ ${oauthUrl ? `oauth-url="${escapeAttr(oauthUrl)}"` : ''}
201
+ ${authorizationType ? `authorization-type="${escapeAttr(authorizationType)}"` : ''}
202
+ ></mcp-consent>
203
+
204
+ <!-- Loading skeleton (hidden once component is defined) -->
205
+ <div class="loading-skeleton" aria-hidden="true">
206
+ <div class="skeleton-header">
207
+ <div class="skeleton-avatar"></div>
208
+ <div style="flex: 1">
209
+ <div class="skeleton-line short"></div>
210
+ <div class="skeleton-line medium" style="margin-bottom: 0; height: 0.75rem;"></div>
211
+ </div>
212
+ </div>
213
+ <div class="skeleton-line full"></div>
214
+ <div class="skeleton-line medium"></div>
215
+ <div class="skeleton-line short"></div>
216
+ <div class="skeleton-button"></div>
217
+ </div>
218
+
219
+ <!-- No-JS fallback - basic form submission -->
220
+ <noscript>
221
+ <form class="fallback-form" method="POST" action="${escapeAttr(serverUrl)}/consent/approve">
222
+ <h1>Permission Request</h1>
223
+ <p>JavaScript is required for the full consent experience. You can still approve basic access below.</p>
224
+
225
+ <input type="hidden" name="tool" value="${escapeAttr(tool)}">
226
+ <input type="hidden" name="scopes" value="${escapeAttr(scopesJson)}">
227
+ <input type="hidden" name="agent_did" value="${escapeAttr(agentDid)}">
228
+ <input type="hidden" name="session_id" value="${escapeAttr(sessionId)}">
229
+ <input type="hidden" name="project_id" value="${escapeAttr(projectId)}">
230
+ <input type="hidden" name="auth_mode" value="consent-only">
231
+ <input type="hidden" name="provider_type" value="none">
232
+
233
+ <button type="submit">Allow Basic Access</button>
234
+ </form>
235
+ </noscript>
236
+ </body>
237
+ </html>`;
238
+ }
239
+ /**
240
+ * Generate inline consent component (no external bundle)
241
+ *
242
+ * For scenarios where you want to inline everything into a single HTML response.
243
+ * This is useful for:
244
+ * - Offline/embedded scenarios
245
+ * - Single-request consent pages
246
+ * - Testing/debugging
247
+ *
248
+ * Note: This requires the consent bundle to be inlined as a string.
249
+ *
250
+ * @param options - Shell options
251
+ * @param bundleSource - The bundled consent.js source code
252
+ */
253
+ export function generateInlineConsentShell(options, bundleSource) {
254
+ const { config, tool, scopes, agentDid, sessionId, projectId, serverUrl, oauthIdentity, pageTitle = 'Permission Request', nonce, } = options;
255
+ const configJson = JSON.stringify(config);
256
+ const scopesJson = JSON.stringify(scopes);
257
+ const oauthJson = oauthIdentity ? JSON.stringify(oauthIdentity) : null;
258
+ const nonceAttr = nonce ? ` nonce="${escapeAttr(nonce)}"` : '';
259
+ return `<!DOCTYPE html>
260
+ <html lang="en">
261
+ <head>
262
+ <meta charset="UTF-8">
263
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
264
+ <title>${escapeHtml(pageTitle)}</title>
265
+ <script type="module"${nonceAttr}>
266
+ ${bundleSource}
267
+ </script>
268
+ <style${nonceAttr}>
269
+ body {
270
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
271
+ background: #f3f4f6;
272
+ min-height: 100vh;
273
+ margin: 0;
274
+ display: flex;
275
+ align-items: center;
276
+ justify-content: center;
277
+ padding: 1rem;
278
+ }
279
+ </style>
280
+ </head>
281
+ <body>
282
+ <mcp-consent
283
+ config='${escapeAttr(configJson)}'
284
+ tool="${escapeAttr(tool)}"
285
+ scopes='${escapeAttr(scopesJson)}'
286
+ agent-did="${escapeAttr(agentDid)}"
287
+ session-id="${escapeAttr(sessionId)}"
288
+ project-id="${escapeAttr(projectId)}"
289
+ server-url="${escapeAttr(serverUrl)}"
290
+ ${oauthJson ? `oauth-identity='${escapeAttr(oauthJson)}'` : ''}
291
+ ></mcp-consent>
292
+ </body>
293
+ </html>`;
294
+ }
295
+ //# sourceMappingURL=shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/bundle/shell.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Consent Button Web Component
3
+ *
4
+ * A styled button for consent pages that works in:
5
+ * - Browser (vanilla HTML)
6
+ * - React (via @lit/react wrapper)
7
+ * - SSR (Declarative Shadow DOM)
8
+ *
9
+ * @module components/consent-button
10
+ */
11
+ import { LitElement } from 'lit';
12
+ /**
13
+ * Button variants matching AgentShield design system
14
+ */
15
+ export type ButtonVariant = 'primary' | 'secondary';
16
+ /**
17
+ * ConsentButton - A themed button component
18
+ *
19
+ * @example
20
+ * ```html
21
+ * <consent-button variant="primary">Allow Access</consent-button>
22
+ * <consent-button variant="secondary">Cancel</consent-button>
23
+ * ```
24
+ *
25
+ * @csspart button - The native button element
26
+ * @cssprop --consent-primary - Primary brand color (default: #2563EB)
27
+ */
28
+ export declare class ConsentButton extends LitElement {
29
+ static formAssociated: boolean;
30
+ private internals;
31
+ constructor();
32
+ /**
33
+ * Button variant - 'primary' (filled) or 'secondary' (outlined)
34
+ */
35
+ variant: ButtonVariant;
36
+ /**
37
+ * Button type attribute (button, submit, reset)
38
+ */
39
+ type: 'button' | 'submit' | 'reset';
40
+ /**
41
+ * Disabled state
42
+ */
43
+ disabled: boolean;
44
+ /**
45
+ * Full width mode
46
+ */
47
+ fullWidth: boolean;
48
+ /**
49
+ * Loading state - shows spinner and disables button
50
+ */
51
+ loading: boolean;
52
+ static styles: import("lit").CSSResult;
53
+ private handleClick;
54
+ render(): import("lit").TemplateResult<1>;
55
+ }
56
+ declare global {
57
+ interface HTMLElementTagNameMap {
58
+ 'consent-button': ConsentButton;
59
+ }
60
+ }
61
+ //# sourceMappingURL=consent-button.d.ts.map