@kya-os/contracts 1.5.4-canary.2 → 1.6.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.
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Related Spec: MCP-I Phase 0 Implementation Plan
8
8
  */
9
- import { z } from 'zod';
9
+ import { z } from "zod";
10
10
  /**
11
11
  * Consent Branding Schema
12
12
  */
@@ -165,13 +165,14 @@ export type OAuthIdentity = z.infer<typeof oauthIdentitySchema>;
165
165
  /**
166
166
  * Consent Page Config Schema
167
167
  */
168
- export declare const consentPageConfigSchema: z.ZodObject<{
168
+ export declare const consentPageConfigSchema: z.ZodEffects<z.ZodObject<{
169
169
  tool: z.ZodString;
170
170
  toolDescription: z.ZodString;
171
171
  scopes: z.ZodArray<z.ZodString, "many">;
172
172
  agentDid: z.ZodString;
173
173
  sessionId: z.ZodString;
174
174
  projectId: z.ZodString;
175
+ provider: z.ZodOptional<z.ZodString>;
175
176
  branding: z.ZodOptional<z.ZodObject<{
176
177
  primaryColor: z.ZodOptional<z.ZodString>;
177
178
  logoUrl: z.ZodOptional<z.ZodString>;
@@ -268,6 +269,16 @@ export declare const consentPageConfigSchema: z.ZodObject<{
268
269
  }>, "many">>;
269
270
  serverUrl: z.ZodString;
270
271
  autoClose: z.ZodOptional<z.ZodBoolean>;
272
+ /**
273
+ * Whether OAuth authorization is required immediately
274
+ * If true, the consent page will act as a landing page before redirecting
275
+ */
276
+ oauthRequired: z.ZodOptional<z.ZodBoolean>;
277
+ /**
278
+ * The OAuth authorization URL to redirect to
279
+ * Required if oauthRequired is true
280
+ */
281
+ oauthUrl: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodLiteral<"">]>>;
271
282
  }, "strip", z.ZodTypeAny, {
272
283
  tool: string;
273
284
  toolDescription: string;
@@ -276,6 +287,79 @@ export declare const consentPageConfigSchema: z.ZodObject<{
276
287
  sessionId: string;
277
288
  projectId: string;
278
289
  serverUrl: string;
290
+ provider?: string | undefined;
291
+ branding?: {
292
+ primaryColor?: string | undefined;
293
+ logoUrl?: string | undefined;
294
+ companyName?: string | undefined;
295
+ theme?: "light" | "dark" | "auto" | undefined;
296
+ } | undefined;
297
+ terms?: {
298
+ required: boolean;
299
+ text?: string | undefined;
300
+ url?: string | undefined;
301
+ version?: string | undefined;
302
+ } | undefined;
303
+ customFields?: {
304
+ type: "text" | "textarea" | "checkbox" | "select";
305
+ required: boolean;
306
+ label: string;
307
+ name: string;
308
+ options?: {
309
+ value: string;
310
+ label: string;
311
+ }[] | undefined;
312
+ placeholder?: string | undefined;
313
+ pattern?: string | undefined;
314
+ }[] | undefined;
315
+ autoClose?: boolean | undefined;
316
+ oauthRequired?: boolean | undefined;
317
+ oauthUrl?: string | undefined;
318
+ }, {
319
+ tool: string;
320
+ toolDescription: string;
321
+ scopes: string[];
322
+ agentDid: string;
323
+ sessionId: string;
324
+ projectId: string;
325
+ serverUrl: string;
326
+ provider?: string | undefined;
327
+ branding?: {
328
+ primaryColor?: string | undefined;
329
+ logoUrl?: string | undefined;
330
+ companyName?: string | undefined;
331
+ theme?: "light" | "dark" | "auto" | undefined;
332
+ } | undefined;
333
+ terms?: {
334
+ text?: string | undefined;
335
+ url?: string | undefined;
336
+ version?: string | undefined;
337
+ required?: boolean | undefined;
338
+ } | undefined;
339
+ customFields?: {
340
+ type: "text" | "textarea" | "checkbox" | "select";
341
+ required: boolean;
342
+ label: string;
343
+ name: string;
344
+ options?: {
345
+ value: string;
346
+ label: string;
347
+ }[] | undefined;
348
+ placeholder?: string | undefined;
349
+ pattern?: string | undefined;
350
+ }[] | undefined;
351
+ autoClose?: boolean | undefined;
352
+ oauthRequired?: boolean | undefined;
353
+ oauthUrl?: string | undefined;
354
+ }>, {
355
+ tool: string;
356
+ toolDescription: string;
357
+ scopes: string[];
358
+ agentDid: string;
359
+ sessionId: string;
360
+ projectId: string;
361
+ serverUrl: string;
362
+ provider?: string | undefined;
279
363
  branding?: {
280
364
  primaryColor?: string | undefined;
281
365
  logoUrl?: string | undefined;
@@ -301,6 +385,8 @@ export declare const consentPageConfigSchema: z.ZodObject<{
301
385
  pattern?: string | undefined;
302
386
  }[] | undefined;
303
387
  autoClose?: boolean | undefined;
388
+ oauthRequired?: boolean | undefined;
389
+ oauthUrl?: string | undefined;
304
390
  }, {
305
391
  tool: string;
306
392
  toolDescription: string;
@@ -309,6 +395,7 @@ export declare const consentPageConfigSchema: z.ZodObject<{
309
395
  sessionId: string;
310
396
  projectId: string;
311
397
  serverUrl: string;
398
+ provider?: string | undefined;
312
399
  branding?: {
313
400
  primaryColor?: string | undefined;
314
401
  logoUrl?: string | undefined;
@@ -334,6 +421,8 @@ export declare const consentPageConfigSchema: z.ZodObject<{
334
421
  pattern?: string | undefined;
335
422
  }[] | undefined;
336
423
  autoClose?: boolean | undefined;
424
+ oauthRequired?: boolean | undefined;
425
+ oauthUrl?: string | undefined;
337
426
  }>;
338
427
  export type ConsentPageConfig = z.infer<typeof consentPageConfigSchema>;
339
428
  /**
@@ -355,9 +444,11 @@ export declare const consentApprovalRequestSchema: z.ZodObject<{
355
444
  termsVersion: z.ZodOptional<z.ZodString>;
356
445
  customFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodBoolean]>>>;
357
446
  /**
358
- * OAuth provider identity information (optional, can be null)
447
+ * OAuth provider identity information (optional)
359
448
  * Used to link OAuth accounts to persistent User DIDs
360
- * Can be null when OAuth is not configured or user hasn't authenticated
449
+ *
450
+ * CRITICAL: Uses .nullish() to accept null, undefined, or OAuthIdentity
451
+ * This matches JSON parsing behavior where missing fields become null
361
452
  */
362
453
  oauth_identity: z.ZodOptional<z.ZodNullable<z.ZodObject<{
363
454
  /**
@@ -658,6 +749,7 @@ export declare function validateConsentPageConfig(config: unknown): z.SafeParseR
658
749
  sessionId: string;
659
750
  projectId: string;
660
751
  serverUrl: string;
752
+ provider?: string | undefined;
661
753
  branding?: {
662
754
  primaryColor?: string | undefined;
663
755
  logoUrl?: string | undefined;
@@ -683,6 +775,8 @@ export declare function validateConsentPageConfig(config: unknown): z.SafeParseR
683
775
  pattern?: string | undefined;
684
776
  }[] | undefined;
685
777
  autoClose?: boolean | undefined;
778
+ oauthRequired?: boolean | undefined;
779
+ oauthUrl?: string | undefined;
686
780
  }, {
687
781
  tool: string;
688
782
  toolDescription: string;
@@ -691,6 +785,7 @@ export declare function validateConsentPageConfig(config: unknown): z.SafeParseR
691
785
  sessionId: string;
692
786
  projectId: string;
693
787
  serverUrl: string;
788
+ provider?: string | undefined;
694
789
  branding?: {
695
790
  primaryColor?: string | undefined;
696
791
  logoUrl?: string | undefined;
@@ -716,6 +811,8 @@ export declare function validateConsentPageConfig(config: unknown): z.SafeParseR
716
811
  pattern?: string | undefined;
717
812
  }[] | undefined;
718
813
  autoClose?: boolean | undefined;
814
+ oauthRequired?: boolean | undefined;
815
+ oauthUrl?: string | undefined;
719
816
  }>;
720
817
  /**
721
818
  * Validate a consent approval request
@@ -20,58 +20,79 @@ const zod_1 = require("zod");
20
20
  exports.consentBrandingSchema = zod_1.z.object({
21
21
  primaryColor: zod_1.z
22
22
  .string()
23
- .regex(/^#[0-9A-Fa-f]{6}$/, 'Must be a valid hex color (e.g., #0066CC)')
23
+ .regex(/^#[0-9A-Fa-f]{6}$/, "Must be a valid hex color (e.g., #0066CC)")
24
24
  .optional(),
25
- logoUrl: zod_1.z.string().url('Must be a valid URL').optional(),
26
- companyName: zod_1.z.string().max(100, 'Company name must be 100 characters or less').optional(),
27
- theme: zod_1.z.enum(['light', 'dark', 'auto']).optional(),
25
+ logoUrl: zod_1.z.string().url("Must be a valid URL").optional(),
26
+ companyName: zod_1.z
27
+ .string()
28
+ .max(100, "Company name must be 100 characters or less")
29
+ .optional(),
30
+ theme: zod_1.z.enum(["light", "dark", "auto"]).optional(),
28
31
  });
29
32
  /**
30
33
  * Consent Terms Schema
31
34
  */
32
35
  exports.consentTermsSchema = zod_1.z.object({
33
- text: zod_1.z.string().max(10000, 'Terms text must be 10000 characters or less').optional(),
34
- url: zod_1.z.string().url('Must be a valid URL').optional(),
35
- version: zod_1.z.string().max(50, 'Version must be 50 characters or less').optional(),
36
+ text: zod_1.z
37
+ .string()
38
+ .max(10000, "Terms text must be 10000 characters or less")
39
+ .optional(),
40
+ url: zod_1.z.string().url("Must be a valid URL").optional(),
41
+ version: zod_1.z
42
+ .string()
43
+ .max(50, "Version must be 50 characters or less")
44
+ .optional(),
36
45
  required: zod_1.z.boolean().default(true),
37
46
  });
38
47
  /**
39
48
  * Consent Custom Field Option Schema
40
49
  */
41
50
  exports.consentCustomFieldOptionSchema = zod_1.z.object({
42
- value: zod_1.z.string().max(100, 'Option value must be 100 characters or less'),
43
- label: zod_1.z.string().max(100, 'Option label must be 100 characters or less'),
51
+ value: zod_1.z.string().max(100, "Option value must be 100 characters or less"),
52
+ label: zod_1.z.string().max(100, "Option label must be 100 characters or less"),
44
53
  });
45
54
  /**
46
55
  * Consent Custom Field Schema
47
56
  */
48
- exports.consentCustomFieldSchema = zod_1.z.object({
57
+ exports.consentCustomFieldSchema = zod_1.z
58
+ .object({
49
59
  name: zod_1.z
50
60
  .string()
51
- .min(1, 'Field name is required')
52
- .max(50, 'Field name must be 50 characters or less')
53
- .regex(/^[a-zA-Z0-9_]+$/, 'Field name must contain only letters, numbers, and underscores'),
54
- label: zod_1.z.string().min(1, 'Field label is required').max(100, 'Field label must be 100 characters or less'),
55
- type: zod_1.z.enum(['text', 'textarea', 'checkbox', 'select']),
61
+ .min(1, "Field name is required")
62
+ .max(50, "Field name must be 50 characters or less")
63
+ .regex(/^[a-zA-Z0-9_]+$/, "Field name must contain only letters, numbers, and underscores"),
64
+ label: zod_1.z
65
+ .string()
66
+ .min(1, "Field label is required")
67
+ .max(100, "Field label must be 100 characters or less"),
68
+ type: zod_1.z.enum(["text", "textarea", "checkbox", "select"]),
56
69
  required: zod_1.z.boolean(),
57
- placeholder: zod_1.z.string().max(200, 'Placeholder must be 200 characters or less').optional(),
70
+ placeholder: zod_1.z
71
+ .string()
72
+ .max(200, "Placeholder must be 200 characters or less")
73
+ .optional(),
58
74
  options: zod_1.z
59
75
  .array(exports.consentCustomFieldOptionSchema)
60
- .min(1, 'Select fields must have at least one option')
76
+ .min(1, "Select fields must have at least one option")
77
+ .optional(),
78
+ pattern: zod_1.z
79
+ .string()
80
+ .max(500, "Pattern must be 500 characters or less")
61
81
  .optional(),
62
- pattern: zod_1.z.string().max(500, 'Pattern must be 500 characters or less').optional(),
63
- }).refine((data) => {
82
+ })
83
+ .refine((data) => {
64
84
  // Select fields must have options
65
- if (data.type === 'select' && (!data.options || data.options.length === 0)) {
85
+ if (data.type === "select" &&
86
+ (!data.options || data.options.length === 0)) {
66
87
  return false;
67
88
  }
68
89
  // Non-select fields should not have options
69
- if (data.type !== 'select' && data.options) {
90
+ if (data.type !== "select" && data.options) {
70
91
  return false;
71
92
  }
72
93
  return true;
73
94
  }, {
74
- message: 'Select fields must have options, and non-select fields must not have options',
95
+ message: "Select fields must have options, and non-select fields must not have options",
75
96
  });
76
97
  /**
77
98
  * OAuth Identity Schema
@@ -83,48 +104,89 @@ exports.oauthIdentitySchema = zod_1.z.object({
83
104
  /**
84
105
  * OAuth provider name (e.g., "google", "github", "microsoft")
85
106
  */
86
- provider: zod_1.z.string()
87
- .min(1, 'Provider is required')
88
- .max(50, 'Provider name must be 50 characters or less'),
107
+ provider: zod_1.z
108
+ .string()
109
+ .min(1, "Provider is required")
110
+ .max(50, "Provider name must be 50 characters or less"),
89
111
  /**
90
112
  * OAuth subject identifier (unique user ID from provider)
91
113
  * @example "123456789" (Google), "github-user-id" (GitHub)
92
114
  */
93
- subject: zod_1.z.string()
94
- .min(1, 'Subject is required')
95
- .max(255, 'Subject must be 255 characters or less'),
115
+ subject: zod_1.z
116
+ .string()
117
+ .min(1, "Subject is required")
118
+ .max(255, "Subject must be 255 characters or less"),
96
119
  /**
97
120
  * User's email address from OAuth provider (optional)
98
121
  */
99
- email: zod_1.z.string()
100
- .email('Must be a valid email address')
101
- .max(255, 'Email must be 255 characters or less')
122
+ email: zod_1.z
123
+ .string()
124
+ .email("Must be a valid email address")
125
+ .max(255, "Email must be 255 characters or less")
102
126
  .optional(),
103
127
  /**
104
128
  * User's display name from OAuth provider (optional)
105
129
  */
106
- name: zod_1.z.string()
107
- .max(255, 'Name must be 255 characters or less')
108
- .optional(),
130
+ name: zod_1.z.string().max(255, "Name must be 255 characters or less").optional(),
109
131
  });
110
132
  /**
111
133
  * Consent Page Config Schema
112
134
  */
113
- exports.consentPageConfigSchema = zod_1.z.object({
114
- tool: zod_1.z.string().min(1, 'Tool name is required'),
115
- toolDescription: zod_1.z.string().max(500, 'Tool description must be 500 characters or less'),
116
- scopes: zod_1.z.array(zod_1.z.string()).min(0, 'Scopes array cannot be negative'),
117
- agentDid: zod_1.z.string().min(1, 'Agent DID is required'),
118
- sessionId: zod_1.z.string().min(1, 'Session ID is required'),
119
- projectId: zod_1.z.string().min(1, 'Project ID is required'),
135
+ exports.consentPageConfigSchema = zod_1.z
136
+ .object({
137
+ tool: zod_1.z.string().min(1, "Tool name is required"),
138
+ toolDescription: zod_1.z
139
+ .string()
140
+ .max(500, "Tool description must be 500 characters or less"),
141
+ scopes: zod_1.z.array(zod_1.z.string()).min(0, "Scopes array cannot be negative"),
142
+ agentDid: zod_1.z.string().min(1, "Agent DID is required"),
143
+ sessionId: zod_1.z.string().min(1, "Session ID is required"),
144
+ projectId: zod_1.z.string().min(1, "Project ID is required"),
145
+ provider: zod_1.z.string().optional(), // Phase 2: OAuth provider name (e.g., "github", "google")
120
146
  branding: exports.consentBrandingSchema.optional(),
121
147
  terms: exports.consentTermsSchema.optional(),
122
148
  customFields: zod_1.z
123
149
  .array(exports.consentCustomFieldSchema)
124
- .max(10, 'Maximum 10 custom fields allowed')
150
+ .max(10, "Maximum 10 custom fields allowed")
125
151
  .optional(),
126
- serverUrl: zod_1.z.string().url('Server URL must be a valid URL'),
152
+ serverUrl: zod_1.z.string().url("Server URL must be a valid URL"),
127
153
  autoClose: zod_1.z.boolean().optional(),
154
+ /**
155
+ * Whether OAuth authorization is required immediately
156
+ * If true, the consent page will act as a landing page before redirecting
157
+ */
158
+ oauthRequired: zod_1.z.boolean().optional(),
159
+ /**
160
+ * The OAuth authorization URL to redirect to
161
+ * Required if oauthRequired is true
162
+ */
163
+ oauthUrl: zod_1.z
164
+ .union([
165
+ zod_1.z.string().url(),
166
+ zod_1.z.literal(""), // Allow empty string to catch it in refine with better error
167
+ ])
168
+ .optional(),
169
+ })
170
+ .superRefine((data, ctx) => {
171
+ // If oauthRequired is true, oauthUrl must be provided and non-empty
172
+ if (data.oauthRequired === true) {
173
+ if (data.oauthUrl === undefined || data.oauthUrl === "") {
174
+ ctx.addIssue({
175
+ code: zod_1.z.ZodIssueCode.custom,
176
+ message: "oauthUrl is required when oauthRequired is true",
177
+ path: ["oauthUrl"],
178
+ });
179
+ return;
180
+ }
181
+ }
182
+ // If oauthUrl is provided (not undefined), it must be a valid URL (not empty)
183
+ if (data.oauthUrl !== undefined && data.oauthUrl === "") {
184
+ ctx.addIssue({
185
+ code: zod_1.z.ZodIssueCode.custom,
186
+ message: "oauthUrl must be a valid URL",
187
+ path: ["oauthUrl"],
188
+ });
189
+ }
128
190
  });
129
191
  /**
130
192
  * Consent Approval Request Schema
@@ -136,23 +198,24 @@ exports.consentPageConfigSchema = zod_1.z.object({
136
198
  * - user_did: Optional User DID for persistent identity (if already known)
137
199
  */
138
200
  exports.consentApprovalRequestSchema = zod_1.z.object({
139
- tool: zod_1.z.string().min(1, 'Tool name is required'),
140
- scopes: zod_1.z.array(zod_1.z.string()).min(0, 'Scopes array cannot be negative'),
141
- agent_did: zod_1.z.string().min(1, 'Agent DID is required'),
142
- session_id: zod_1.z.string().min(1, 'Session ID is required'),
143
- project_id: zod_1.z.string().min(1, 'Project ID is required'),
201
+ tool: zod_1.z.string().min(1, "Tool name is required"),
202
+ scopes: zod_1.z.array(zod_1.z.string()).min(0, "Scopes array cannot be negative"),
203
+ agent_did: zod_1.z.string().min(1, "Agent DID is required"),
204
+ session_id: zod_1.z.string().min(1, "Session ID is required"),
205
+ project_id: zod_1.z.string().min(1, "Project ID is required"),
144
206
  termsAccepted: zod_1.z.boolean(),
145
- termsVersion: zod_1.z.string()
146
- .max(50, 'Terms version must be 50 characters or less')
147
- .optional(),
148
- customFields: zod_1.z
149
- .record(zod_1.z.union([zod_1.z.string(), zod_1.z.boolean()]))
207
+ termsVersion: zod_1.z
208
+ .string()
209
+ .max(50, "Terms version must be 50 characters or less")
150
210
  .optional(),
211
+ customFields: zod_1.z.record(zod_1.z.union([zod_1.z.string(), zod_1.z.boolean()])).optional(),
151
212
  // Phase 4: OAuth identity linking
152
213
  /**
153
- * OAuth provider identity information (optional, can be null)
214
+ * OAuth provider identity information (optional)
154
215
  * Used to link OAuth accounts to persistent User DIDs
155
- * Can be null when OAuth is not configured or user hasn't authenticated
216
+ *
217
+ * CRITICAL: Uses .nullish() to accept null, undefined, or OAuthIdentity
218
+ * This matches JSON parsing behavior where missing fields become null
156
219
  */
157
220
  oauth_identity: exports.oauthIdentitySchema.nullish(),
158
221
  /**
@@ -160,21 +223,24 @@ exports.consentApprovalRequestSchema = zod_1.z.object({
160
223
  * If provided, represents the persistent User DID for this user
161
224
  * Format: did:key:... or did:web:...
162
225
  */
163
- user_did: zod_1.z.string()
164
- .regex(/^did:/, 'Must be a valid DID format (starting with did:)')
165
- .max(500, 'DID must be 500 characters or less')
226
+ user_did: zod_1.z
227
+ .string()
228
+ .regex(/^did:/, "Must be a valid DID format (starting with did:)")
229
+ .max(500, "DID must be 500 characters or less")
166
230
  .optional(),
167
231
  });
168
232
  /**
169
233
  * Consent Approval Response Schema
170
234
  */
171
- exports.consentApprovalResponseSchema = zod_1.z.object({
235
+ exports.consentApprovalResponseSchema = zod_1.z
236
+ .object({
172
237
  success: zod_1.z.boolean(),
173
238
  delegation_id: zod_1.z.string().min(1).optional(),
174
239
  delegation_token: zod_1.z.string().min(1).optional(),
175
240
  error: zod_1.z.string().optional(),
176
241
  error_code: zod_1.z.string().optional(),
177
- }).refine((data) => {
242
+ })
243
+ .refine((data) => {
178
244
  // If success is true, must have delegation_id and delegation_token
179
245
  if (data.success) {
180
246
  return !!data.delegation_id && !!data.delegation_token;
@@ -182,7 +248,7 @@ exports.consentApprovalResponseSchema = zod_1.z.object({
182
248
  // If success is false, must have error or error_code
183
249
  return !!data.error || !!data.error_code;
184
250
  }, {
185
- message: 'Successful responses must include delegation_id and delegation_token. Failed responses must include error or error_code',
251
+ message: "Successful responses must include delegation_id and delegation_token. Failed responses must include error or error_code",
186
252
  });
187
253
  /**
188
254
  * Consent Config Schema
@@ -192,14 +258,21 @@ exports.consentConfigSchema = zod_1.z.object({
192
258
  terms: exports.consentTermsSchema.optional(),
193
259
  customFields: zod_1.z
194
260
  .array(exports.consentCustomFieldSchema)
195
- .max(10, 'Maximum 10 custom fields allowed')
261
+ .max(10, "Maximum 10 custom fields allowed")
196
262
  .optional(),
197
- ui: zod_1.z.object({
198
- theme: zod_1.z.enum(['light', 'dark', 'auto']).optional(),
263
+ ui: zod_1.z
264
+ .object({
265
+ theme: zod_1.z.enum(["light", "dark", "auto"]).optional(),
199
266
  popupEnabled: zod_1.z.boolean().optional(),
200
267
  autoClose: zod_1.z.boolean().optional(),
201
- autoCloseDelay: zod_1.z.number().int().positive().max(60000, 'Auto-close delay must be 60000ms or less').optional(),
202
- }).optional(),
268
+ autoCloseDelay: zod_1.z
269
+ .number()
270
+ .int()
271
+ .positive()
272
+ .max(60000, "Auto-close delay must be 60000ms or less")
273
+ .optional(),
274
+ })
275
+ .optional(),
203
276
  });
204
277
  /**
205
278
  * Validation Helpers