@learncard/react 3.0.3 → 3.0.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.
Files changed (69) hide show
  1. package/dist/cjs/{BoostGenericCard-dd6ee2ee.js → BoostGenericCard-7f8c99e8.js} +2 -2
  2. package/dist/cjs/{BoostGenericCard-dd6ee2ee.js.map → BoostGenericCard-7f8c99e8.js.map} +1 -1
  3. package/dist/cjs/{CertificateDisplayCard-e61d6a67.js → CertificateDisplayCard-b5bc9b13.js} +3 -3
  4. package/dist/cjs/{CertificateDisplayCard-e61d6a67.js.map → CertificateDisplayCard-b5bc9b13.js.map} +1 -1
  5. package/dist/cjs/{MeritBadgeDisplayCard-c2828cd3.js → MeritBadgeDisplayCard-e5adf548.js} +3 -3
  6. package/dist/cjs/{MeritBadgeDisplayCard-c2828cd3.js.map → MeritBadgeDisplayCard-e5adf548.js.map} +1 -1
  7. package/dist/cjs/{MeritBadgeSkillsCount-49ad7127.js → MeritBadgeSkillsCount-e5b5090e.js} +2 -2
  8. package/dist/cjs/{MeritBadgeSkillsCount-49ad7127.js.map → MeritBadgeSkillsCount-e5b5090e.js.map} +1 -1
  9. package/dist/cjs/{VCCard-90275f9d.js → VCCard-fe6cb0da.js} +3 -3
  10. package/dist/cjs/{VCCard-90275f9d.js.map → VCCard-fe6cb0da.js.map} +1 -1
  11. package/dist/cjs/{VCDisplayBackFace-98de13be.js → VCDisplayBackFace-9afda05a.js} +3 -3
  12. package/dist/cjs/{VCDisplayBackFace-98de13be.js.map → VCDisplayBackFace-9afda05a.js.map} +1 -1
  13. package/dist/cjs/{VCDisplayCard-ab2bf298.js → VCDisplayCard-cbe71ecd.js} +3 -3
  14. package/dist/cjs/{VCDisplayCard-ab2bf298.js.map → VCDisplayCard-cbe71ecd.js.map} +1 -1
  15. package/dist/cjs/{VCDisplayCard2-dd3c011e.js → VCDisplayCard2-4324e97c.js} +5 -5
  16. package/dist/cjs/{VCDisplayCard2-dd3c011e.js.map → VCDisplayCard2-4324e97c.js.map} +1 -1
  17. package/dist/cjs/{VCVerificationPill-008c25aa.js → VCVerificationPill-e6b52da2.js} +2 -2
  18. package/dist/cjs/{VCVerificationPill-008c25aa.js.map → VCVerificationPill-e6b52da2.js.map} +1 -1
  19. package/dist/cjs/{credential.helpers-c4f9d5be.js → credential.helpers-9849239f.js} +2 -2
  20. package/dist/cjs/{credential.helpers-c4f9d5be.js.map → credential.helpers-9849239f.js.map} +1 -1
  21. package/dist/cjs/index.js +11 -11
  22. package/dist/cjs/index14.js +11 -11
  23. package/dist/cjs/index22.js +4 -4
  24. package/dist/cjs/index39.js +9 -9
  25. package/dist/cjs/index4.js +3 -3
  26. package/dist/cjs/index40.js +4 -4
  27. package/dist/cjs/index41.js +5 -5
  28. package/dist/cjs/index42.js +5 -5
  29. package/dist/cjs/index43.js +1 -1
  30. package/dist/cjs/index46.js +2 -2
  31. package/dist/cjs/index7.js +3 -3
  32. package/dist/cjs/{types.esm-95ade0c0.js → types.esm-56901371.js} +596 -53
  33. package/dist/cjs/types.esm-56901371.js.map +1 -0
  34. package/dist/esm/{BoostGenericCard-c28f8b30.js → BoostGenericCard-9c79cb20.js} +2 -2
  35. package/dist/esm/{BoostGenericCard-c28f8b30.js.map → BoostGenericCard-9c79cb20.js.map} +1 -1
  36. package/dist/esm/{CertificateDisplayCard-109f14c5.js → CertificateDisplayCard-c97f00ab.js} +3 -3
  37. package/dist/esm/{CertificateDisplayCard-109f14c5.js.map → CertificateDisplayCard-c97f00ab.js.map} +1 -1
  38. package/dist/esm/{MeritBadgeDisplayCard-eafb2e2d.js → MeritBadgeDisplayCard-f863388b.js} +3 -3
  39. package/dist/esm/{MeritBadgeDisplayCard-eafb2e2d.js.map → MeritBadgeDisplayCard-f863388b.js.map} +1 -1
  40. package/dist/esm/{MeritBadgeSkillsCount-4715deb0.js → MeritBadgeSkillsCount-f0012302.js} +2 -2
  41. package/dist/esm/{MeritBadgeSkillsCount-4715deb0.js.map → MeritBadgeSkillsCount-f0012302.js.map} +1 -1
  42. package/dist/esm/{VCCard-d9789c00.js → VCCard-d63736c5.js} +3 -3
  43. package/dist/esm/{VCCard-d9789c00.js.map → VCCard-d63736c5.js.map} +1 -1
  44. package/dist/esm/{VCDisplayBackFace-1ca3bf88.js → VCDisplayBackFace-0ede9620.js} +3 -3
  45. package/dist/esm/{VCDisplayBackFace-1ca3bf88.js.map → VCDisplayBackFace-0ede9620.js.map} +1 -1
  46. package/dist/esm/{VCDisplayCard-915308ce.js → VCDisplayCard-7504227f.js} +3 -3
  47. package/dist/esm/{VCDisplayCard-915308ce.js.map → VCDisplayCard-7504227f.js.map} +1 -1
  48. package/dist/esm/{VCDisplayCard2-40b36e67.js → VCDisplayCard2-1c1413b9.js} +5 -5
  49. package/dist/esm/{VCDisplayCard2-40b36e67.js.map → VCDisplayCard2-1c1413b9.js.map} +1 -1
  50. package/dist/esm/{VCVerificationPill-be4fcdd3.js → VCVerificationPill-f111195c.js} +2 -2
  51. package/dist/esm/{VCVerificationPill-be4fcdd3.js.map → VCVerificationPill-f111195c.js.map} +1 -1
  52. package/dist/esm/{credential.helpers-a7b12dd7.js → credential.helpers-688d1a6d.js} +2 -2
  53. package/dist/esm/{credential.helpers-a7b12dd7.js.map → credential.helpers-688d1a6d.js.map} +1 -1
  54. package/dist/esm/index.js +11 -11
  55. package/dist/esm/index14.js +11 -11
  56. package/dist/esm/index22.js +4 -4
  57. package/dist/esm/index39.js +9 -9
  58. package/dist/esm/index4.js +3 -3
  59. package/dist/esm/index40.js +4 -4
  60. package/dist/esm/index41.js +5 -5
  61. package/dist/esm/index42.js +5 -5
  62. package/dist/esm/index43.js +1 -1
  63. package/dist/esm/index46.js +2 -2
  64. package/dist/esm/index7.js +3 -3
  65. package/dist/esm/{types.esm-80957345.js → types.esm-b1fb8920.js} +596 -53
  66. package/dist/esm/types.esm-b1fb8920.js.map +1 -0
  67. package/package.json +4 -4
  68. package/dist/cjs/types.esm-95ade0c0.js.map +0 -1
  69. package/dist/esm/types.esm-80957345.js.map +0 -1
@@ -9721,12 +9721,46 @@ var StringQuery = union([
9721
9721
  $or: BaseStringQuery.array()
9722
9722
  })
9723
9723
  ]);
9724
+ var BITSTRING_STATUS_PURPOSES = ["revocation", "suspension"];
9725
+ var BitstringStatusPurposeValidator = _enum(BITSTRING_STATUS_PURPOSES);
9726
+ var BitstringStatusListEntryValidator = object({
9727
+ id: string().optional(),
9728
+ type: literal("BitstringStatusListEntry"),
9729
+ statusPurpose: BitstringStatusPurposeValidator,
9730
+ statusListIndex: string().or(number().int().nonnegative()),
9731
+ statusListCredential: string()
9732
+ });
9733
+ BitstringStatusListEntryValidator.extend({
9734
+ id: string()
9735
+ });
9736
+ object({
9737
+ id: string().optional(),
9738
+ type: literal("BitstringStatusList"),
9739
+ statusPurpose: BitstringStatusPurposeValidator,
9740
+ encodedList: string()
9741
+ });
9742
+ object({
9743
+ statusPurposes: array(BitstringStatusPurposeValidator).optional(),
9744
+ listSize: number().int().positive().optional()
9745
+ }).default({});
9746
+ object({
9747
+ refreshId: string().min(1),
9748
+ credentialStatus: CredentialStatusValidator.or(CredentialStatusValidator.array()).nullable()
9749
+ });
9724
9750
  var LearnCardRefreshAuthorizationValidator = object({ type: literal("LearnCardDIDAuth") }).catchall(any());
9725
9751
  var ManagedCredentialRefreshServiceValidator = object({
9726
9752
  id: string().min(1),
9727
9753
  type: literal("LearnCardCredentialRefresh2026"),
9728
9754
  authorization: LearnCardRefreshAuthorizationValidator.optional()
9729
9755
  }).catchall(any());
9756
+ var ManagedCredentialRefreshBindingValidator = ManagedCredentialRefreshServiceValidator.or(
9757
+ RefreshServiceValidator.array().refine(
9758
+ (services) => services.some(
9759
+ (service) => ManagedCredentialRefreshServiceValidator.safeParse(service).success
9760
+ ),
9761
+ "A managed refresh service is required"
9762
+ )
9763
+ );
9730
9764
  var StandardCredentialRefreshServiceValidator = object({
9731
9765
  id: string().min(1),
9732
9766
  type: literal("1EdTechCredentialRefresh")
@@ -9750,7 +9784,9 @@ object({
9750
9784
  });
9751
9785
  var ManagedCredentialRefreshReceiptValidator = object({
9752
9786
  refreshId: string().min(1),
9753
- refreshService: ManagedCredentialRefreshServiceValidator,
9787
+ refreshService: ManagedCredentialRefreshBindingValidator,
9788
+ /** Legacy receipts authenticate only the allocated managed entry, not other services. */
9789
+ refreshServiceBinding: literal("managed-entry").optional(),
9754
9790
  credentialId: string().min(1),
9755
9791
  issuerDid: string().min(1),
9756
9792
  holderDid: string().min(1),
@@ -9758,14 +9794,43 @@ var ManagedCredentialRefreshReceiptValidator = object({
9758
9794
  CredentialStatusValidator.array()
9759
9795
  ).optional()
9760
9796
  }).strip();
9797
+ object({ uri: string().min(1) });
9798
+ ManagedCredentialRefreshReceiptValidator.extend({
9799
+ encryptionMode: _enum(["network", "holder"])
9800
+ });
9801
+ var HolderEncryptedHandoffValidator = object({
9802
+ refreshId: string().min(1),
9803
+ credentialId: string().min(1),
9804
+ holderDid: string().min(1),
9805
+ issuerDid: string().min(1),
9806
+ credentialStatus: CredentialStatusValidator.or(CredentialStatusValidator.array()),
9807
+ refreshService: ManagedCredentialRefreshBindingValidator.optional(),
9808
+ jwe: JWEValidator
9809
+ }).strict();
9810
+ object({
9811
+ handoff: HolderEncryptedHandoffValidator,
9812
+ idempotencyKey: string().min(1).optional(),
9813
+ boostUri: string().optional(),
9814
+ skipNotification: boolean().optional()
9815
+ });
9816
+ object({ refreshId: string().min(1) });
9817
+ object({
9818
+ recipientKeyIds: array(string())
9819
+ });
9761
9820
  var InboxCredentialRefreshReceiptValidator = ManagedCredentialRefreshReceiptValidator.omit(
9762
9821
  { holderDid: true }
9763
9822
  ).extend({ holderDid: string().min(1).optional() });
9764
9823
  var CredentialRefreshSigningModeValidator = _enum(["issuer-signed", "signing-authority"]);
9824
+ var CredentialRefreshUpdateReasonValidator = _enum(["corrected", "updated", "reissued"]);
9765
9825
  var PublishCredentialRefreshBaseFields = {
9766
9826
  refreshId: string().min(1),
9767
9827
  notifyHolder: boolean().optional(),
9768
- updateSummary: string().optional(),
9828
+ updateSummary: string().max(280).optional().describe(
9829
+ "Public legacy update summary. Do not include private claims; prefer updateReason."
9830
+ ),
9831
+ updateReason: CredentialRefreshUpdateReasonValidator.optional().describe(
9832
+ "Public reason for this update"
9833
+ ),
9769
9834
  idempotencyKey: string().optional()
9770
9835
  };
9771
9836
  object(__spreadProps(__spreadValues({}, PublishCredentialRefreshBaseFields), {
@@ -9838,13 +9903,25 @@ object({
9838
9903
  publishedAt: string().min(1),
9839
9904
  notification: PublishCredentialRefreshNotificationValidator
9840
9905
  });
9906
+ object({
9907
+ handoff: HolderEncryptedHandoffValidator,
9908
+ notify: boolean(),
9909
+ updateSummary: string().max(280).optional().describe(
9910
+ "Public legacy update summary. Do not include private claims; prefer updateReason."
9911
+ ),
9912
+ updateReason: CredentialRefreshUpdateReasonValidator.optional().describe(
9913
+ "Public reason for this update"
9914
+ ),
9915
+ idempotencyKey: string().optional()
9916
+ });
9841
9917
  var CredentialRefreshVersionMetadataValidator = object({
9842
9918
  version: number().int().positive(),
9843
9919
  publishedAt: string().min(1),
9844
9920
  effectiveAt: string().optional(),
9845
9921
  etag: string().optional(),
9846
9922
  signingMode: CredentialRefreshSigningModeValidator.optional(),
9847
- updateSummary: string().optional()
9923
+ updateSummary: string().optional(),
9924
+ updateReason: CredentialRefreshUpdateReasonValidator.optional()
9848
9925
  });
9849
9926
  object({
9850
9927
  refreshId: string().min(1),
@@ -9887,6 +9964,7 @@ var CredentialRefreshFailureCodeValidator = _enum([
9887
9964
  "INVALID_PROOF",
9888
9965
  "ISSUER_MISMATCH",
9889
9966
  "ID_MISMATCH",
9967
+ "BINDING_MISMATCH",
9890
9968
  "ROLLBACK",
9891
9969
  "REVOKED",
9892
9970
  "UNSAFE_ENDPOINT"
@@ -10204,13 +10282,18 @@ object({
10204
10282
  isPrimary: boolean().optional()
10205
10283
  })
10206
10284
  });
10207
- object({
10285
+ var AutoBoostConfigValidator = object({
10208
10286
  boostUri: string(),
10209
10287
  signingAuthority: object({
10210
10288
  endpoint: string(),
10211
10289
  name: string()
10212
10290
  })
10213
10291
  });
10292
+ var CredentialDisplayValidator = object({
10293
+ name: string().trim().min(1).max(280).optional(),
10294
+ category: string().max(280).optional(),
10295
+ image: string().max(2048).url().refine((url) => url.startsWith("https://"), { message: "Image URL must use https" }).optional()
10296
+ });
10214
10297
  var SendBoostTemplateValidator = BoostValidator.partial().omit({ uri: true, claimPermissions: true }).extend({
10215
10298
  credential: VCValidator.or(UnsignedVCValidator),
10216
10299
  claimPermissions: BoostPermissionsValidator.partial().optional(),
@@ -10249,6 +10332,10 @@ var SendBoostInputValidator = object({
10249
10332
  templateUri: string().optional(),
10250
10333
  template: SendBoostTemplateValidator.optional(),
10251
10334
  signedCredential: VCValidator.optional(),
10335
+ display: CredentialDisplayValidator.optional().describe(
10336
+ "Public display metadata for managed and signed-only sends. Nothing is inferred from credential content; omitted names use generic copy. The exception is category: when display.category is omitted for an inline template, the template's category is copied, since consent-flow write authorization is keyed on it."
10337
+ ),
10338
+ statusPurposes: array(BitstringStatusPurposeValidator).optional(),
10252
10339
  options: SendOptionsValidator.optional().describe(
10253
10340
  "Options for email/phone recipients (Universal Inbox)"
10254
10341
  ),
@@ -10288,7 +10375,10 @@ var SendInboxResponseValidator = object({
10288
10375
  "Present when guardianEmail was specified"
10289
10376
  )
10290
10377
  });
10378
+ var StatusManagementValidator = _enum(["network", "external", "mixed", "none"]);
10291
10379
  var SendBoostResponseValidator = object({
10380
+ /** Public status providers for a managed send; external entries require provider-side updates. */
10381
+ statusManagement: StatusManagementValidator.optional(),
10292
10382
  type: literal("boost"),
10293
10383
  credentialUri: string(),
10294
10384
  uri: string(),
@@ -10301,19 +10391,33 @@ var SendBoostResponseValidator = object({
10301
10391
  )
10302
10392
  });
10303
10393
  object({
10394
+ /** Opt in to signing the server-bound statusEntries; omission preserves client allocation. */
10395
+ statusBinding: literal("server").optional(),
10396
+ statusPurposes: array(BitstringStatusPurposeValidator).optional(),
10304
10397
  recipient: string(),
10305
10398
  templateUri: string().optional(),
10306
10399
  template: SendBoostTemplateValidator.optional(),
10400
+ display: CredentialDisplayValidator.optional().describe("Public display metadata only"),
10307
10401
  contractUri: string().optional(),
10308
10402
  templateData: record(string(), unknown()).optional(),
10309
10403
  integrationId: string().optional(),
10310
10404
  /** Credential ID to allocate for; generated server-side when omitted. */
10311
10405
  credentialId: string().min(1).optional(),
10312
- idempotencyKey: string().min(1).max(200).optional()
10313
- }).refine((data) => Boolean(data.templateUri) !== Boolean(data.template), {
10314
- message: "Provide exactly one of templateUri or template."
10406
+ idempotencyKey: string().min(1).max(200).optional(),
10407
+ /**
10408
+ * `'holder'` requests student-only encryption (LC-2345): the SDK signs and
10409
+ * encrypts locally and the server never receives plaintext. Requires a
10410
+ * profile or DID recipient; rejected for signedCredential-only sends and for
10411
+ * inbox (email/phone) recipients. Defaults to `'network'`.
10412
+ */
10413
+ encryption: _enum(["network", "holder"]).optional()
10414
+ }).refine((data) => !(data.templateUri && data.template), {
10415
+ message: "Provide at most one of templateUri or template."
10315
10416
  });
10316
10417
  object({
10418
+ /** Public status providers known at preparation; final send reports the signed entries. */
10419
+ statusManagement: StatusManagementValidator.optional(),
10420
+ statusEntries: array(BitstringStatusListEntryValidator).optional(),
10317
10421
  boostUri: string(),
10318
10422
  credentialId: string(),
10319
10423
  refreshId: string(),
@@ -10321,11 +10425,110 @@ object({
10321
10425
  /** The DID to use as credentialSubject.id (recipient DID, or the profile's did:web). */
10322
10426
  holderDid: string(),
10323
10427
  /** Present when this idempotencyKey already completed: return it without signing. */
10324
- completed: SendBoostResponseValidator.optional()
10428
+ completed: SendBoostResponseValidator.optional(),
10429
+ /**
10430
+ * Present only when `encryption: 'holder'` was requested: the exact
10431
+ * key-agreement verification-method ids (holder + current managers) the SDK
10432
+ * must encrypt to. Recomputed on every call, so a later manager change can
10433
+ * make a previously-prepared set stale (see `credentialRefresh.sendHolderEncryptedRefreshable`
10434
+ * and `credentialRefresh.getEncryptionRecipients`).
10435
+ */
10436
+ recipientKeyIds: array(string()).optional()
10325
10437
  });
10326
10438
  discriminatedUnion("type", [SendBoostInputValidator]);
10327
10439
  discriminatedUnion("type", [SendBoostResponseValidator]);
10328
- var ConsentFlowTermsStatusValidator = _enum(["live", "stale", "withdrawn"]);
10440
+ var ConsentFlowTermsStatusValidator = _enum([
10441
+ "live",
10442
+ "consumed",
10443
+ "withdrawn",
10444
+ "needs_reconsent",
10445
+ "suspended"
10446
+ ]);
10447
+ var ConsentFlowContractChangeKindValidator = _enum([
10448
+ "relaxed",
10449
+ "expanded_optional",
10450
+ "requires_consent"
10451
+ ]);
10452
+ var ConsentFlowContractScopeValidator = object({
10453
+ area: _enum(["read", "write"]),
10454
+ type: _enum(["credential", "personal"]),
10455
+ key: string(),
10456
+ required: boolean(),
10457
+ reason: string().optional()
10458
+ });
10459
+ var ConsentFlowContractDetailValueValidator = union([
10460
+ string(),
10461
+ boolean(),
10462
+ string().array()
10463
+ ]);
10464
+ var ConsentFlowContractDetailChangeValidator = object({
10465
+ field: _enum([
10466
+ "name",
10467
+ "subtitle",
10468
+ "description",
10469
+ "reasonForAccessing",
10470
+ "image",
10471
+ "needsGuardianConsent",
10472
+ "redirectUrl",
10473
+ "frontDoorBoostUri",
10474
+ "expiresAt",
10475
+ "writers",
10476
+ "autoboosts"
10477
+ ]),
10478
+ before: ConsentFlowContractDetailValueValidator.optional(),
10479
+ after: ConsentFlowContractDetailValueValidator.optional()
10480
+ });
10481
+ var ConsentFlowContractDiffValidator = object({
10482
+ added: ConsentFlowContractScopeValidator.array(),
10483
+ removed: ConsentFlowContractScopeValidator.array(),
10484
+ changed: ConsentFlowContractScopeValidator.array(),
10485
+ details: ConsentFlowContractDetailChangeValidator.array().optional()
10486
+ });
10487
+ var ConsentFlowContractUpdatePreviewValidator = object({
10488
+ headline: string(),
10489
+ subhead: string(),
10490
+ rows: array(
10491
+ object({
10492
+ scope: ConsentFlowContractScopeValidator,
10493
+ change: _enum(["added", "removed", "changed"]),
10494
+ label: string(),
10495
+ subtitle: string()
10496
+ })
10497
+ ),
10498
+ primaryLabel: string()
10499
+ });
10500
+ var ConsentFlowContractStatusValidator = _enum(["active", "retired"]);
10501
+ object({
10502
+ version: number().int().positive(),
10503
+ createdAt: string(),
10504
+ reason: string().optional(),
10505
+ kind: ConsentFlowContractChangeKindValidator.optional()
10506
+ });
10507
+ object({
10508
+ version: number().int().positive(),
10509
+ kind: ConsentFlowContractChangeKindValidator,
10510
+ affectedUsers: number().int().nonnegative(),
10511
+ preview: ConsentFlowContractUpdatePreviewValidator
10512
+ });
10513
+ object({
10514
+ status: ConsentFlowTermsStatusValidator.or(literal("not_consented")),
10515
+ consentedVersion: number().int().positive().optional(),
10516
+ currentVersion: number().int().positive(),
10517
+ needsReconsent: boolean(),
10518
+ reviewUrl: string().optional()
10519
+ });
10520
+ object({
10521
+ contractUri: string(),
10522
+ contractName: string().optional(),
10523
+ fromVersion: number().int().positive(),
10524
+ toVersion: number().int().positive(),
10525
+ kind: ConsentFlowContractChangeKindValidator,
10526
+ reason: string().optional(),
10527
+ diff: ConsentFlowContractDiffValidator,
10528
+ reconsentDeadline: string().optional(),
10529
+ reviewUrl: string(),
10530
+ preview: ConsentFlowContractUpdatePreviewValidator.optional()
10531
+ });
10329
10532
  var ConsentFlowContractValidator = object({
10330
10533
  read: object({
10331
10534
  anonymize: boolean().optional(),
@@ -10334,13 +10537,18 @@ var ConsentFlowContractValidator = object({
10334
10537
  string(),
10335
10538
  object({
10336
10539
  required: boolean(),
10337
- defaultEnabled: boolean().optional()
10540
+ defaultEnabled: boolean().optional(),
10541
+ reason: string().optional()
10338
10542
  })
10339
10543
  ).default({})
10340
10544
  }).prefault({ categories: {} }),
10341
10545
  personal: record(
10342
10546
  string(),
10343
- object({ required: boolean(), defaultEnabled: boolean().optional() })
10547
+ object({
10548
+ required: boolean(),
10549
+ defaultEnabled: boolean().optional(),
10550
+ reason: string().optional()
10551
+ })
10344
10552
  ).default({})
10345
10553
  }).prefault({ credentials: { categories: {} }, personal: {} }),
10346
10554
  write: object({
@@ -10349,16 +10557,55 @@ var ConsentFlowContractValidator = object({
10349
10557
  string(),
10350
10558
  object({
10351
10559
  required: boolean(),
10352
- defaultEnabled: boolean().optional()
10560
+ defaultEnabled: boolean().optional(),
10561
+ reason: string().optional()
10353
10562
  })
10354
10563
  ).default({})
10355
10564
  }).prefault({ categories: {} }),
10356
10565
  personal: record(
10357
10566
  string(),
10358
- object({ required: boolean(), defaultEnabled: boolean().optional() })
10567
+ object({
10568
+ required: boolean(),
10569
+ defaultEnabled: boolean().optional(),
10570
+ reason: string().optional()
10571
+ })
10359
10572
  ).default({})
10360
10573
  }).prefault({ credentials: { categories: {} }, personal: {} })
10361
10574
  });
10575
+ var ConsentFlowContractScopePatchValidator = object({
10576
+ required: boolean(),
10577
+ defaultEnabled: boolean().optional(),
10578
+ reason: string().optional()
10579
+ }).nullable();
10580
+ object({
10581
+ contract: object({
10582
+ read: object({
10583
+ anonymize: boolean().optional(),
10584
+ credentials: object({
10585
+ categories: record(string(), ConsentFlowContractScopePatchValidator).optional()
10586
+ }).optional(),
10587
+ personal: record(string(), ConsentFlowContractScopePatchValidator).optional()
10588
+ }).optional(),
10589
+ write: object({
10590
+ credentials: object({
10591
+ categories: record(string(), ConsentFlowContractScopePatchValidator).optional()
10592
+ }).optional(),
10593
+ personal: record(string(), ConsentFlowContractScopePatchValidator).optional()
10594
+ }).optional()
10595
+ }).optional(),
10596
+ name: string().optional(),
10597
+ subtitle: string().optional(),
10598
+ description: string().optional(),
10599
+ reasonForAccessing: string().optional(),
10600
+ image: string().optional(),
10601
+ needsGuardianConsent: boolean().optional(),
10602
+ redirectUrl: string().optional(),
10603
+ frontDoorBoostUri: string().optional(),
10604
+ expiresAt: string().nullable().optional(),
10605
+ autoboosts: AutoBoostConfigValidator.array().optional(),
10606
+ writers: string().array().optional(),
10607
+ recipients: string().array().optional()
10608
+ });
10362
10609
  var ConsentFlowContractDetailsValidator = object({
10363
10610
  contract: ConsentFlowContractValidator,
10364
10611
  owner: LCNProfileValidator,
@@ -10377,7 +10624,19 @@ var ConsentFlowContractDetailsValidator = object({
10377
10624
  autoBoosts: string().array().optional(),
10378
10625
  writers: array(LCNProfileValidator).optional(),
10379
10626
  recipients: array(LCNPublicProfileValidator.extend({ did: string() })).optional(),
10380
- audienceVersion: number().int().nonnegative().optional()
10627
+ audienceVersion: number().int().nonnegative().optional(),
10628
+ version: number().int().positive(),
10629
+ status: ConsentFlowContractStatusValidator.optional(),
10630
+ latestUpdate: object({
10631
+ fromVersion: number().int().positive(),
10632
+ toVersion: number().int().positive(),
10633
+ kind: ConsentFlowContractChangeKindValidator,
10634
+ reason: string().optional(),
10635
+ diff: ConsentFlowContractDiffValidator,
10636
+ reconsentDeadline: string().optional(),
10637
+ createdAt: string(),
10638
+ preview: ConsentFlowContractUpdatePreviewValidator
10639
+ }).optional()
10381
10640
  });
10382
10641
  var ConsentFlowContractRequestStatusValidator = _enum(["pending", "accepted", "denied", "cancelled"]).nullable();
10383
10642
  var ConsentFlowContractRequestReadStatusValidator = _enum(["unseen", "seen"]).nullable();
@@ -10466,7 +10725,12 @@ PaginationResponseValidator.extend({
10466
10725
  contract: ConsentFlowContractDetailsValidator,
10467
10726
  uri: string(),
10468
10727
  consenter: LCNProfileValidator,
10469
- status: ConsentFlowTermsStatusValidator
10728
+ status: ConsentFlowTermsStatusValidator,
10729
+ consentedVersion: number().int().positive(),
10730
+ lastReviewedVersion: number().int().positive().optional(),
10731
+ reconsentDeadline: string().optional(),
10732
+ newOptionsUntil: string().optional(),
10733
+ cumulativeUpdate: ConsentFlowContractDetailsValidator.shape.latestUpdate
10470
10734
  }).array()
10471
10735
  });
10472
10736
  var ConsentFlowGuardianApprovalValidator = object({
@@ -10542,7 +10806,8 @@ var ConsentFlowTransactionActionValidator = _enum([
10542
10806
  "update",
10543
10807
  "sync",
10544
10808
  "withdraw",
10545
- "write"
10809
+ "write",
10810
+ "reconsent"
10546
10811
  ]);
10547
10812
  object({
10548
10813
  terms: ConsentFlowTermsQueryValidator.optional(),
@@ -10561,8 +10826,12 @@ var ConsentFlowTransactionValidator = object({
10561
10826
  referral: ConsentFlowReferralValidator.optional(),
10562
10827
  id: string(),
10563
10828
  action: ConsentFlowTransactionActionValidator,
10829
+ kind: ConsentFlowContractChangeKindValidator.optional(),
10564
10830
  date: string(),
10565
- uris: string().array().optional()
10831
+ uris: string().array().optional(),
10832
+ consentedVersion: number().int().positive().optional(),
10833
+ reconsentDeadline: string().optional(),
10834
+ newOptionsUntil: string().optional()
10566
10835
  });
10567
10836
  var HolderExportConsentRecordValidator = object({
10568
10837
  termsUri: string(),
@@ -10570,6 +10839,10 @@ var HolderExportConsentRecordValidator = object({
10570
10839
  contract: ConsentFlowContractDetailsValidator,
10571
10840
  terms: ConsentFlowTermsValidator,
10572
10841
  referral: ConsentFlowReferralValidator.optional(),
10842
+ consentedVersion: number().int().positive(),
10843
+ reconsentDeadline: string().optional(),
10844
+ newOptionsUntil: string().optional(),
10845
+ cumulativeUpdate: ConsentFlowContractDetailsValidator.shape.latestUpdate,
10573
10846
  transactions: ConsentFlowTransactionValidator.array()
10574
10847
  });
10575
10848
  object({
@@ -10630,10 +10903,12 @@ var LCNNotificationTypeEnumValidator = _enum([
10630
10903
  "GUARDIAN_APPROVED",
10631
10904
  "GUARDIAN_REJECTED",
10632
10905
  "APP_NOTIFICATION",
10906
+ "ANNOUNCEMENT",
10633
10907
  "CREDENTIAL_REVOKED",
10634
10908
  "CREDENTIAL_SUSPENDED",
10635
10909
  "CREDENTIAL_UNSUSPENDED",
10636
- "CREDENTIAL_REFRESHED"
10910
+ "CREDENTIAL_REFRESHED",
10911
+ "CONSENT_FLOW_CONTRACT_UPDATED"
10637
10912
  ]);
10638
10913
  var LCNNotificationMessageValidator = object({
10639
10914
  title: string().optional(),
@@ -10662,12 +10937,26 @@ var LCNNotificationInboxValidator = object({
10662
10937
  timestamp: datetime().optional()
10663
10938
  });
10664
10939
  var LCNNotificationMetadataValidator = object({
10665
- connectionPrompt: LCNConnectionPromptMetadataValidator.optional()
10940
+ connectionPrompt: LCNConnectionPromptMetadataValidator.optional(),
10941
+ campaignId: string().regex(/^[a-z0-9-]{3,64}$/).optional(),
10942
+ campaignCreatedAt: datetime().optional(),
10943
+ campaignHasInApp: boolean().optional(),
10944
+ campaignTestId: uuid().optional()
10666
10945
  }).catchall(unknown());
10667
10946
  var LCNNotificationDataValidator = object({
10668
10947
  vcUris: array(string()).optional(),
10669
10948
  vpUris: array(string()).optional(),
10670
10949
  transaction: ConsentFlowTransactionValidator.optional(),
10950
+ contractUri: string().optional(),
10951
+ contractName: string().optional(),
10952
+ fromVersion: number().int().positive().optional(),
10953
+ toVersion: number().int().positive().optional(),
10954
+ kind: ConsentFlowContractChangeKindValidator.optional(),
10955
+ reason: string().optional(),
10956
+ diff: ConsentFlowContractDiffValidator.optional(),
10957
+ reconsentDeadline: string().optional(),
10958
+ reviewUrl: string().optional(),
10959
+ preview: ConsentFlowContractUpdatePreviewValidator.optional(),
10671
10960
  inbox: LCNNotificationInboxValidator.optional(),
10672
10961
  metadata: LCNNotificationMetadataValidator.optional()
10673
10962
  }).loose();
@@ -11766,28 +12055,6 @@ object({
11766
12055
  */
11767
12056
  wrongAttempts: number().int().nonnegative().optional()
11768
12057
  });
11769
- var BITSTRING_STATUS_PURPOSES = ["revocation", "suspension"];
11770
- var BitstringStatusPurposeValidator = _enum(BITSTRING_STATUS_PURPOSES);
11771
- var BitstringStatusListEntryValidator = object({
11772
- id: string().optional(),
11773
- type: literal("BitstringStatusListEntry"),
11774
- statusPurpose: BitstringStatusPurposeValidator,
11775
- statusListIndex: string().or(number().int().nonnegative()),
11776
- statusListCredential: string()
11777
- });
11778
- BitstringStatusListEntryValidator.extend({
11779
- id: string()
11780
- });
11781
- object({
11782
- id: string().optional(),
11783
- type: literal("BitstringStatusList"),
11784
- statusPurpose: BitstringStatusPurposeValidator,
11785
- encodedList: string()
11786
- });
11787
- object({
11788
- statusPurposes: array(BitstringStatusPurposeValidator).optional(),
11789
- listSize: number().int().positive().optional()
11790
- }).default({});
11791
12058
  var isSafeInAppMessagePath = /* @__PURE__ */ __name((path) => {
11792
12059
  let decoded = path;
11793
12060
  for (let depth = 0; depth < 5; depth += 1) {
@@ -12068,24 +12335,46 @@ object({
12068
12335
  }).passthrough();
12069
12336
  var CampaignIdValidator = string().regex(/^[a-z0-9-]{3,64}$/);
12070
12337
  var CampaignStatusValidator = _enum(["draft", "live", "paused", "archived"]);
12071
- var CampaignChannelValidator = _enum(["inApp", "notify"]);
12338
+ var CampaignChannelValidator = _enum(["inApp", "notify", "email"]);
12072
12339
  _enum(["shown", "clicked", "dismissed", "converted"]);
12073
- var timestamp = datetime({ offset: true }).overwrite((value) => new Date(value).toISOString());
12340
+ var timestamp = datetime({ offset: true }).overwrite((value) => {
12341
+ const date = new Date(value);
12342
+ return Number.isFinite(date.getTime()) ? date.toISOString() : value;
12343
+ });
12074
12344
  var notification = object({ title: string().min(1), body: string().min(1) }).strict();
12075
- var channels = array(CampaignChannelValidator).min(1).max(2).refine((values) => new Set(values).size === values.length, "Channels must be unique");
12345
+ var CampaignEmailValidator = object({
12346
+ subject: string().trim().min(1).max(200).regex(/^[^\r\n]+$/),
12347
+ title: string().trim().min(1).max(200),
12348
+ body: string().trim().min(1).max(2e4),
12349
+ heroImageUrl: url().startsWith("https://").max(2048).optional(),
12350
+ ctaLabel: string().trim().min(1).max(100)
12351
+ }).strict();
12352
+ object({
12353
+ announcementEmailOptOut: boolean(),
12354
+ announcementPushOptOut: boolean()
12355
+ }).strict();
12356
+ var channels = array(CampaignChannelValidator).min(1).max(3).refine((values) => new Set(values).size === values.length, "Channels must be unique");
12076
12357
  var campaignDefinition = object({
12077
12358
  id: CampaignIdValidator,
12078
12359
  name: string().trim().min(1).max(200),
12079
12360
  status: CampaignStatusValidator.default("draft"),
12080
12361
  channels,
12081
- message: inAppMessageValidator,
12362
+ message: inAppMessageValidator.optional(),
12082
12363
  notification: notification.optional(),
12364
+ email: CampaignEmailValidator.optional(),
12083
12365
  startsAt: timestamp.optional(),
12084
12366
  endsAt: timestamp.optional(),
12085
12367
  excludeMinors: boolean().default(true),
12086
12368
  selfEnroll: boolean().default(false)
12087
12369
  }).strict();
12088
12370
  var validDefinition = /* @__PURE__ */ __name((value, ctx) => {
12371
+ if (value.channels.includes("inApp") && !value.message) {
12372
+ ctx.addIssue({
12373
+ code: "custom",
12374
+ path: ["message"],
12375
+ message: "In-app requires a message"
12376
+ });
12377
+ }
12089
12378
  if (value.channels.includes("notify") && !value.notification) {
12090
12379
  ctx.addIssue({
12091
12380
  code: "custom",
@@ -12093,15 +12382,23 @@ var validDefinition = /* @__PURE__ */ __name((value, ctx) => {
12093
12382
  message: "Notify requires a title and body"
12094
12383
  });
12095
12384
  }
12385
+ if (value.channels.includes("email") && !value.email) {
12386
+ ctx.addIssue({
12387
+ code: "custom",
12388
+ path: ["email"],
12389
+ message: "Email requires announcement content"
12390
+ });
12391
+ }
12096
12392
  if (value.startsAt && value.endsAt && value.startsAt >= value.endsAt) {
12097
12393
  ctx.addIssue({ code: "custom", path: ["endsAt"], message: "End must be after start" });
12098
12394
  }
12099
12395
  }, "validDefinition");
12100
12396
  var CampaignValidator = campaignDefinition.extend({
12397
+ tenantId: string().optional(),
12101
12398
  createdAt: timestamp,
12102
12399
  updatedAt: timestamp
12103
12400
  }).superRefine(validDefinition).superRefine((value, ctx) => {
12104
- if (value.message.id !== value.id) {
12401
+ if (value.message && value.message.id !== value.id) {
12105
12402
  ctx.addIssue({
12106
12403
  code: "custom",
12107
12404
  path: ["message", "id"],
@@ -12110,21 +12407,23 @@ var CampaignValidator = campaignDefinition.extend({
12110
12407
  }
12111
12408
  });
12112
12409
  campaignDefinition.extend({
12113
- message: inAppMessageAuthoringValidator
12410
+ message: inAppMessageAuthoringValidator.optional()
12114
12411
  }).superRefine(validDefinition);
12115
12412
  var CampaignUpdatesValidator = campaignDefinition.omit({ id: true }).partial().extend({
12116
12413
  // A PATCH must not apply creation defaults to fields the caller omitted.
12117
12414
  status: CampaignStatusValidator.optional(),
12118
12415
  excludeMinors: boolean().optional(),
12119
12416
  selfEnroll: boolean().optional(),
12120
- message: inAppMessageAuthoringValidator.optional(),
12417
+ message: inAppMessageAuthoringValidator.nullable().optional(),
12121
12418
  notification: notification.nullable().optional(),
12419
+ email: CampaignEmailValidator.nullable().optional(),
12122
12420
  startsAt: timestamp.nullable().optional(),
12123
12421
  endsAt: timestamp.nullable().optional()
12124
12422
  }).strict();
12125
12423
  object({
12126
12424
  campaignId: CampaignIdValidator,
12127
- updates: CampaignUpdatesValidator
12425
+ updates: CampaignUpdatesValidator,
12426
+ expectedUpdatedAt: timestamp.optional()
12128
12427
  }).strict();
12129
12428
  var identifier = string().trim().min(1).max(2048);
12130
12429
  var metadataKey = string().regex(/^[a-zA-Z_][a-zA-Z0-9_.-]{0,63}$/).refine(
@@ -12176,7 +12475,8 @@ var CampaignUserStateValidator = object({
12176
12475
  clickedAt: timestamp.optional(),
12177
12476
  dismissedAt: timestamp.optional(),
12178
12477
  convertedAt: timestamp.optional(),
12179
- notifiedAt: timestamp.optional()
12478
+ notifiedAt: timestamp.optional(),
12479
+ emailedAt: timestamp.optional()
12180
12480
  });
12181
12481
  object({
12182
12482
  campaign: campaignDefinition.pick({
@@ -12185,12 +12485,19 @@ object({
12185
12485
  startsAt: true,
12186
12486
  endsAt: true,
12187
12487
  selfEnroll: true
12188
- }),
12189
- state: CampaignUserStateValidator
12488
+ }).extend({ message: inAppMessageValidator }),
12489
+ state: CampaignUserStateValidator,
12490
+ testId: uuid().optional()
12491
+ });
12492
+ object({
12493
+ id: uuid(),
12494
+ campaignId: CampaignIdValidator,
12495
+ message: inAppMessageValidator
12190
12496
  });
12191
12497
  object({
12192
12498
  audience: number().int().nonnegative(),
12193
12499
  notified: number().int().nonnegative(),
12500
+ emailed: number().int().nonnegative(),
12194
12501
  shown: number().int().nonnegative(),
12195
12502
  clicked: number().int().nonnegative(),
12196
12503
  dismissed: number().int().nonnegative(),
@@ -12217,6 +12524,31 @@ object({
12217
12524
  hasMore: boolean(),
12218
12525
  cursor: string().optional()
12219
12526
  });
12527
+ var CampaignDispatchPreviewValidator = object({
12528
+ campaignId: CampaignIdValidator,
12529
+ audienceCount: number().int().nonnegative(),
12530
+ alreadyNotifiedCount: number().int().nonnegative(),
12531
+ recipientCount: number().int().nonnegative(),
12532
+ notificationRecipientCount: number().int().nonnegative().optional(),
12533
+ emailRecipientCount: number().int().nonnegative().optional(),
12534
+ previewToken: string().regex(/^[a-f0-9]{64}$/),
12535
+ blockedReason: _enum([
12536
+ "not_live",
12537
+ "notify_disabled",
12538
+ "email_confirmation_required",
12539
+ "not_started",
12540
+ "ended",
12541
+ "no_recipients"
12542
+ ]).optional()
12543
+ });
12544
+ object({
12545
+ expectedPreviewToken: CampaignDispatchPreviewValidator.shape.previewToken.optional()
12546
+ }).strict();
12547
+ object({
12548
+ count: number().int().nonnegative(),
12549
+ added: number().int().nonnegative(),
12550
+ notFound: array(string())
12551
+ });
12220
12552
  var SHARE_LINK_ID_BYTES = 16;
12221
12553
  var SHARE_CONTENT_KEY_BYTES = 32;
12222
12554
  var SHARE_IV_BYTES = 12;
@@ -12743,6 +13075,217 @@ var SkillIconNamesValidator = array(string().nonempty()).min(1).max(SKILL_ICON_M
12743
13075
  }
12744
13076
  );
12745
13077
  object({ names: SkillIconNamesValidator });
13078
+ var RoleValidator = _enum(["user", "assistant", "tool", "system"]);
13079
+ var AiSessionMode = {
13080
+ tutor: "ai-tutor",
13081
+ insights: "ai-insights"
13082
+ };
13083
+ var AiSessionModeValidator = _enum([AiSessionMode.tutor, AiSessionMode.insights]);
13084
+ object({
13085
+ notes: string().optional(),
13086
+ questions: array(string())
13087
+ });
13088
+ var IntroStreamModeValidator = _enum(["formatted", "structured"]);
13089
+ var ChatMessageValidator = object({
13090
+ role: RoleValidator,
13091
+ content: string().nullable(),
13092
+ tool_call_id: string().optional(),
13093
+ tool_calls: array(
13094
+ object({
13095
+ id: string(),
13096
+ type: literal("function"),
13097
+ function: object({
13098
+ name: string(),
13099
+ arguments: string()
13100
+ })
13101
+ })
13102
+ ).optional()
13103
+ });
13104
+ var InsightArtifactValidator = object({
13105
+ title: string(),
13106
+ summary: string(),
13107
+ category: string(),
13108
+ question: string(),
13109
+ narrative: string()
13110
+ });
13111
+ var ArtifactSuggestionValidator = object({
13112
+ artifact: InsightArtifactValidator,
13113
+ source_text: string().optional(),
13114
+ created_at: string()
13115
+ });
13116
+ var ThreadCredentialContextValidator = object({
13117
+ uri: string(),
13118
+ type: string(),
13119
+ context: string(),
13120
+ score: number(),
13121
+ strongestScore: number().optional(),
13122
+ averageScore: number().optional(),
13123
+ matchCount: number().optional(),
13124
+ title: string().optional()
13125
+ });
13126
+ object({
13127
+ id: string(),
13128
+ did: string(),
13129
+ topicCredentialUri: string().nullable().optional(),
13130
+ title: string(),
13131
+ created_at: string(),
13132
+ last_message_at: string(),
13133
+ active: boolean().optional(),
13134
+ ended_at: string().optional(),
13135
+ plan_started_at: string().optional(),
13136
+ summaries: array(
13137
+ object({
13138
+ summary_data: string(),
13139
+ credential_uri: string(),
13140
+ created_at: string()
13141
+ })
13142
+ ).optional(),
13143
+ plans: array(
13144
+ object({
13145
+ plan_data: string(),
13146
+ created_at: string(),
13147
+ consentRevision: string().optional()
13148
+ })
13149
+ ).optional(),
13150
+ credentials: array(ThreadCredentialContextValidator).optional(),
13151
+ credentialSearchTopic: string().optional(),
13152
+ credentialContextStatus: _enum(["pending", "ready", "empty", "error"]).optional(),
13153
+ mode: AiSessionModeValidator.optional(),
13154
+ artifactSuggestions: array(ArtifactSuggestionValidator).optional()
13155
+ });
13156
+ var CredentialVerificationMetadataValidator = object({
13157
+ credentialUri: string(),
13158
+ contentHash: string().regex(/^[a-f0-9]{64}$/),
13159
+ status: _enum(["valid", "invalid"]),
13160
+ checkedAt: string().datetime(),
13161
+ verifier: object({
13162
+ name: string(),
13163
+ version: string()
13164
+ }),
13165
+ verifiedPayload: _enum(["credential", "boostCredential"]),
13166
+ checks: array(string()),
13167
+ errors: array(string()),
13168
+ warnings: array(string()),
13169
+ provenance: object({
13170
+ source: _enum(["wallet", "generated"]),
13171
+ retrievedAt: string().datetime()
13172
+ }),
13173
+ consent: object({
13174
+ contractUri: string(),
13175
+ receiptId: string().min(1),
13176
+ grantedAt: string().datetime().optional(),
13177
+ updatedAt: string().datetime(),
13178
+ contractUpdatedAt: string().min(1),
13179
+ status: literal("live"),
13180
+ expiresAt: string().datetime().optional(),
13181
+ contractExpiresAt: string().datetime().optional(),
13182
+ categories: array(string()),
13183
+ credentialUris: array(string()),
13184
+ personalFields: array(string()),
13185
+ purpose: _enum(["credential-ingestion", "model-inference", "embedding"]),
13186
+ revision: string().min(1),
13187
+ guardian: object({ required: boolean(), approved: boolean() })
13188
+ })
13189
+ });
13190
+ var ModelSafeCredentialFactValidator = object({
13191
+ kind: _enum([
13192
+ "skill",
13193
+ "goal",
13194
+ "achievement",
13195
+ "course",
13196
+ "experience",
13197
+ "competency",
13198
+ "title",
13199
+ "summary",
13200
+ "assessment",
13201
+ "grade",
13202
+ "date",
13203
+ "alignment",
13204
+ "criteria",
13205
+ "pathway",
13206
+ "topic"
13207
+ ]),
13208
+ value: string().min(1).max(240),
13209
+ label: string().min(1).max(120).optional()
13210
+ });
13211
+ var ModelSafeCredentialProjectionValidator = object({
13212
+ schemaVersion: literal("1"),
13213
+ category: string().min(1).max(120),
13214
+ credentialTypes: array(string().min(1).max(120)).max(20),
13215
+ facts: array(ModelSafeCredentialFactValidator).max(100),
13216
+ // Present only on credentials that are past their expiry, so the model can
13217
+ // tell a lapsed credential from a current one.
13218
+ expired: literal(true).optional(),
13219
+ expirationDate: string().datetime().optional()
13220
+ });
13221
+ object({
13222
+ id: string(),
13223
+ uri: string(),
13224
+ category: string(),
13225
+ credential: VCValidator,
13226
+ aiContext: string(),
13227
+ generalSummary: string().optional(),
13228
+ createdAt: string(),
13229
+ verification: CredentialVerificationMetadataValidator.optional(),
13230
+ projection: ModelSafeCredentialProjectionValidator.optional()
13231
+ });
13232
+ object({
13233
+ message: ChatMessageValidator.optional(),
13234
+ threadId: string().optional(),
13235
+ selectedQuestion: string().optional(),
13236
+ action: _enum([
13237
+ "start_topic",
13238
+ "continue_plan",
13239
+ "start_topic_uri",
13240
+ "start_learning_pathway",
13241
+ "start_insights_session",
13242
+ "close_insights_session",
13243
+ "artifact_suggestion"
13244
+ ]).optional(),
13245
+ topic: string().optional(),
13246
+ topicUri: string().optional(),
13247
+ pathwayUri: string().optional(),
13248
+ mode: AiSessionModeValidator.optional(),
13249
+ introStreamMode: IntroStreamModeValidator.optional(),
13250
+ // BCP-47 language for AI responses (LC-1901). This has to live on the
13251
+ // validator, not just the inferred type — z.object strips unknown keys, so an
13252
+ // undeclared `locale` would be dropped before the WS handler ever saw it.
13253
+ locale: string().nullish()
13254
+ });
13255
+ object({
13256
+ operation: string(),
13257
+ collection: string(),
13258
+ input: unknown().optional(),
13259
+ output: unknown().optional(),
13260
+ timestamp: string(),
13261
+ duration: number().optional()
13262
+ });
13263
+ object({
13264
+ event: literal("timing"),
13265
+ operation: string(),
13266
+ phase: _enum(["start", "end", "complete"]),
13267
+ duration: number().optional(),
13268
+ metadata: record(string(), unknown()).optional(),
13269
+ timestamp: string()
13270
+ });
13271
+ object({
13272
+ id: string(),
13273
+ learningPathway: object({
13274
+ stepIndex: number(),
13275
+ step: object({
13276
+ title: string(),
13277
+ description: string(),
13278
+ summary: string(),
13279
+ learned: array(string()),
13280
+ skills: array(
13281
+ object({
13282
+ title: string(),
13283
+ description: string()
13284
+ })
13285
+ )
13286
+ })
13287
+ })
13288
+ });
12746
13289
 
12747
13290
  exports.VerificationStatusEnum = VerificationStatusEnum;
12748
- //# sourceMappingURL=types.esm-95ade0c0.js.map
13291
+ //# sourceMappingURL=types.esm-56901371.js.map