@elevasis/ui 2.72.0 → 2.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/api/index.js +3 -3
  2. package/dist/app/index.d.ts +114 -20
  3. package/dist/app/index.js +8 -8
  4. package/dist/auth/index.js +4 -4
  5. package/dist/charts/index.js +4 -4
  6. package/dist/{chunk-A3JHFZDP.js → chunk-3TS5U5BL.js} +1 -1
  7. package/dist/{chunk-IXBRUIYI.js → chunk-4CW2C5BD.js} +1 -1
  8. package/dist/{chunk-753MKWFV.js → chunk-5B2ZFO44.js} +1 -1
  9. package/dist/{chunk-DJWIIPKW.js → chunk-AJOVWB47.js} +3 -3
  10. package/dist/{chunk-RRS2QR3W.js → chunk-CJ2232PQ.js} +1 -1
  11. package/dist/{chunk-2454MK7P.js → chunk-ETN3TTRT.js} +7 -7
  12. package/dist/{chunk-Q3O3WY7Q.js → chunk-IBCEAVB2.js} +33 -13
  13. package/dist/{chunk-7ESZKTQG.js → chunk-IGBPWD6S.js} +3 -3
  14. package/dist/{chunk-UZ5JO5TK.js → chunk-JYBJMVNY.js} +1 -1
  15. package/dist/{chunk-LCHL5SM2.js → chunk-LEPYXLJ2.js} +1 -1
  16. package/dist/{chunk-LEQGGX2U.js → chunk-LZT2H2MA.js} +4 -4
  17. package/dist/{chunk-Z2W5VNN3.js → chunk-NHNTX6ZL.js} +1 -1
  18. package/dist/{chunk-AFBFSXP3.js → chunk-NI37YNRP.js} +4 -4
  19. package/dist/{chunk-KIDZXZM5.js → chunk-OCVSPAKM.js} +501 -25
  20. package/dist/{chunk-IMZTRDY2.js → chunk-PQ4B62HH.js} +2 -2
  21. package/dist/{chunk-SV4M2BUI.js → chunk-SWKAH2YM.js} +52 -20
  22. package/dist/{chunk-XZIOCB5D.js → chunk-U2H3TIHD.js} +1 -1
  23. package/dist/{chunk-DKVGO6RJ.js → chunk-Z4ICFQXG.js} +1 -1
  24. package/dist/{chunk-ZBXCEWKF.js → chunk-ZDKPHFTH.js} +3 -3
  25. package/dist/components/index.d.ts +305 -22
  26. package/dist/components/index.js +316 -26
  27. package/dist/components/navigation/index.js +5 -5
  28. package/dist/features/auth/index.d.ts +76 -0
  29. package/dist/features/auth/index.js +6 -6
  30. package/dist/features/clients/index.js +5 -5
  31. package/dist/features/content/index.d.ts +494 -31
  32. package/dist/features/content/index.js +1090 -44
  33. package/dist/features/crm/index.d.ts +114 -20
  34. package/dist/features/crm/index.js +6 -6
  35. package/dist/features/dashboard/index.d.ts +19 -10
  36. package/dist/features/dashboard/index.js +6 -6
  37. package/dist/features/delivery/index.d.ts +76 -0
  38. package/dist/features/delivery/index.js +5 -5
  39. package/dist/features/knowledge/index.js +4 -4
  40. package/dist/features/lead-gen/index.d.ts +38 -20
  41. package/dist/features/lead-gen/index.js +6 -6
  42. package/dist/features/monitoring/index.js +7 -7
  43. package/dist/features/monitoring/requests/index.js +5 -5
  44. package/dist/features/operations/index.d.ts +38 -20
  45. package/dist/features/operations/index.js +9 -9
  46. package/dist/features/settings/index.d.ts +76 -0
  47. package/dist/features/settings/index.js +6 -6
  48. package/dist/hooks/access/index.js +4 -4
  49. package/dist/hooks/delivery/index.d.ts +76 -0
  50. package/dist/hooks/delivery/index.js +2 -2
  51. package/dist/hooks/index.d.ts +1248 -28
  52. package/dist/hooks/index.js +4 -4
  53. package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +19 -10
  54. package/dist/hooks/published.d.ts +1248 -28
  55. package/dist/hooks/published.js +4 -4
  56. package/dist/initialization/index.d.ts +76 -0
  57. package/dist/knowledge/index.d.ts +38 -20
  58. package/dist/knowledge/index.js +8 -8
  59. package/dist/layout/index.js +7 -7
  60. package/dist/profile/index.d.ts +76 -0
  61. package/dist/provider/index.d.ts +114 -20
  62. package/dist/provider/index.js +4 -4
  63. package/dist/provider/published.d.ts +114 -20
  64. package/dist/provider/published.js +4 -4
  65. package/dist/supabase/index.d.ts +149 -0
  66. package/dist/test-utils/index.js +3 -3
  67. package/dist/types/index.d.ts +125 -13
  68. package/dist/utils/index.d.ts +19 -10
  69. package/dist/utils/index.js +1 -1
  70. package/package.json +5 -5
@@ -18,7 +18,9 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
18
18
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
19
19
  properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
20
20
  storage: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
21
- }, z.core.$loose>>>>;
21
+ rowSchema: z.ZodOptional<z.ZodString>;
22
+ stateCatalogId: z.ZodOptional<z.ZodString>;
23
+ }, z.core.$strict>>>>;
22
24
  linkTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
23
25
  id: z.ZodString;
24
26
  label: z.ZodOptional<z.ZodString>;
@@ -29,7 +31,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
29
31
  to: z.ZodString;
30
32
  cardinality: z.ZodOptional<z.ZodString>;
31
33
  via: z.ZodOptional<z.ZodString>;
32
- }, z.core.$loose>>>>;
34
+ }, z.core.$strict>>>>;
33
35
  actionTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
34
36
  id: z.ZodString;
35
37
  label: z.ZodOptional<z.ZodString>;
@@ -39,7 +41,11 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
39
41
  actsOn: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
40
42
  input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
41
43
  effects: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
42
- }, z.core.$loose>>>>;
44
+ resourceId: z.ZodOptional<z.ZodString>;
45
+ invocations: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
46
+ lifecycle: z.ZodOptional<z.ZodString>;
47
+ legacyActionId: z.ZodOptional<z.ZodString>;
48
+ }, z.core.$strict>>>>;
43
49
  catalogTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
44
50
  id: z.ZodString;
45
51
  label: z.ZodOptional<z.ZodString>;
@@ -49,7 +55,10 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
49
55
  kind: z.ZodOptional<z.ZodString>;
50
56
  appliesTo: z.ZodOptional<z.ZodString>;
51
57
  entries: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
52
- }, z.core.$loose>>>>;
58
+ legacyCatalogKey: z.ZodOptional<z.ZodString>;
59
+ legacyPipelineKey: z.ZodOptional<z.ZodString>;
60
+ legacyEntityKey: z.ZodOptional<z.ZodString>;
61
+ }, z.core.$strict>>>>;
53
62
  eventTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
54
63
  id: z.ZodString;
55
64
  label: z.ZodOptional<z.ZodString>;
@@ -57,7 +66,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
57
66
  ownerSystemId: z.ZodOptional<z.ZodString>;
58
67
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
59
68
  payload: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
60
- }, z.core.$loose>>>>;
69
+ }, z.core.$strict>>>>;
61
70
  interfaceTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
62
71
  id: z.ZodString;
63
72
  label: z.ZodOptional<z.ZodString>;
@@ -65,7 +74,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
65
74
  ownerSystemId: z.ZodOptional<z.ZodString>;
66
75
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
67
76
  properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
68
- }, z.core.$loose>>>>;
77
+ }, z.core.$strict>>>>;
69
78
  valueTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
70
79
  id: z.ZodString;
71
80
  label: z.ZodOptional<z.ZodString>;
@@ -73,7 +82,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
73
82
  ownerSystemId: z.ZodOptional<z.ZodString>;
74
83
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
75
84
  primitive: z.ZodOptional<z.ZodString>;
76
- }, z.core.$loose>>>>;
85
+ }, z.core.$strict>>>>;
77
86
  sharedProperties: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
78
87
  id: z.ZodString;
79
88
  label: z.ZodOptional<z.ZodString>;
@@ -83,7 +92,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
83
92
  valueType: z.ZodOptional<z.ZodString>;
84
93
  searchable: z.ZodOptional<z.ZodBoolean>;
85
94
  pii: z.ZodOptional<z.ZodBoolean>;
86
- }, z.core.$loose>>>>;
95
+ }, z.core.$strict>>>>;
87
96
  groups: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
88
97
  id: z.ZodString;
89
98
  label: z.ZodOptional<z.ZodString>;
@@ -91,7 +100,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
91
100
  ownerSystemId: z.ZodOptional<z.ZodString>;
92
101
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
93
102
  members: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
94
- }, z.core.$loose>>>>;
103
+ }, z.core.$strict>>>>;
95
104
  endpoints: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
96
105
  id: z.ZodString;
97
106
  label: z.ZodOptional<z.ZodString>;
@@ -99,7 +108,7 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
99
108
  ownerSystemId: z.ZodOptional<z.ZodString>;
100
109
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
101
110
  route: z.ZodOptional<z.ZodString>;
102
- }, z.core.$loose>>>>;
111
+ }, z.core.$strict>>>>;
103
112
  }, z.core.$strict>>;
104
113
  type OntologyScope = z.infer<typeof OntologyScopeSchema>;
105
114
 
@@ -198,11 +207,24 @@ declare const ContentPipelineStepActorSchema: z.ZodEnum<{
198
207
  vendor: "vendor";
199
208
  }>;
200
209
  type ContentPipelineStepActor = z.infer<typeof ContentPipelineStepActorSchema>;
201
- /** D5: how a human reviews a content pipeline step's output. */
210
+ /**
211
+ * D5: whether a human decision gates this step's output.
212
+ *
213
+ * Two values, deliberately. This field used to be `'live' | 'queued' | 'none'`,
214
+ * which encoded two independent facts in one enum -- whether a person reviews,
215
+ * and where they do it. `'live'` and `'queued'` differed only in the second, and
216
+ * the second was already stored as `workspaceRoute`. One fact written twice in
217
+ * two vocabularies is what let two review rules disagree on exactly one value
218
+ * and render a false warning on a live tenant.
219
+ *
220
+ * Where review happens is now derived rather than declared -- see
221
+ * `resolveContentReviewVenue`. Kept a string enum rather than a boolean so a
222
+ * genuine third mode later (an automated check that gates progression without a
223
+ * person) is an added member rather than a second schema break on this field.
224
+ */
202
225
  declare const ContentPipelineStepReviewModeSchema: z.ZodEnum<{
226
+ required: "required";
203
227
  none: "none";
204
- live: "live";
205
- queued: "queued";
206
228
  }>;
207
229
  type ContentPipelineStepReviewMode = z.infer<typeof ContentPipelineStepReviewModeSchema>;
208
230
  /** D17: one entry in a step's template-declared serializable payload field list. */
@@ -220,6 +242,17 @@ declare const ContentPayloadFieldDeclarationSchema: z.ZodObject<{
220
242
  required: z.ZodOptional<z.ZodBoolean>;
221
243
  }, z.core.$strip>;
222
244
  type ContentPayloadFieldDeclaration = z.infer<typeof ContentPayloadFieldDeclarationSchema>;
245
+ /**
246
+ * Where the human decision a step gates on is actually made. Derived from
247
+ * `reviewMode` plus the resolved Workspace route -- see
248
+ * `resolveContentReviewVenue`. Never declared in a catalog.
249
+ *
250
+ * - `'none'` -- nobody is owed a decision on this step.
251
+ * - `'queue'` -- the shared review queue. The platform's own surfaces clear it.
252
+ * - `'workspace'` -- the tenant's own screen, named by `workspaceRoute`. The
253
+ * shared surfaces display state and link out; they do not clear it.
254
+ */
255
+ type ContentReviewVenue = 'none' | 'queue' | 'workspace';
223
256
  /** One step in a resolved content pipeline, as returned by `getContentBuildTemplates`. */
224
257
  interface ContentPipelineStepEntry {
225
258
  /** Matches the catalog entry id (the step's local id within its step catalog). */
@@ -232,8 +265,21 @@ interface ContentPipelineStepEntry {
232
265
  order: number;
233
266
  /** D5: who/what executes this step. */
234
267
  actor: ContentPipelineStepActor;
235
- /** D5: how a human reviews this step's output. */
268
+ /** D5: whether a human decision gates this step's output. */
236
269
  reviewMode: ContentPipelineStepReviewMode;
270
+ /**
271
+ * Where that decision is made -- **derived, never authored.** Resolved once by
272
+ * `getContentBuildTemplates` via `resolveContentReviewVenue`, at the one
273
+ * boundary where a raw catalog becomes a resolved template and both the
274
+ * pipeline and the step are in hand. `ContentPipelineStepDeclarationSchema`
275
+ * has no such field, so no tenant can declare it and no second encoding of it
276
+ * can exist.
277
+ *
278
+ * Read this rather than re-deriving from `reviewMode` + `workspaceRoute` at a
279
+ * call site; recombining those two with `&&` at the point of use is the exact
280
+ * defect the content-review consolidation removed.
281
+ */
282
+ reviewVenue: ContentReviewVenue;
237
283
  /** D5: the step key this step advances to. Absent on a terminal step. */
238
284
  advancesTo?: string;
239
285
  /**
@@ -274,6 +320,15 @@ interface ContentStageCatalogEntry {
274
320
  description: string;
275
321
  order: number;
276
322
  color?: string;
323
+ /**
324
+ * The entry's own `semanticClass` -- `'open' | 'active' | 'completed'` on the
325
+ * status catalog, absent on catalogs that do not declare one.
326
+ *
327
+ * Carried through so a consumer can ask "is this item finished?" without
328
+ * hardcoding which status ids mean finished. A tenant renaming `distributed`
329
+ * or adding a fifth status keeps working; a hardcoded id list would not.
330
+ */
331
+ semanticClass?: string;
277
332
  }
278
333
 
279
334
  declare const OrganizationModelSchema: z.ZodObject<{
@@ -726,7 +781,9 @@ declare const OrganizationModelSchema: z.ZodObject<{
726
781
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
727
782
  properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
728
783
  storage: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
729
- }, z.core.$loose>>>>;
784
+ rowSchema: z.ZodOptional<z.ZodString>;
785
+ stateCatalogId: z.ZodOptional<z.ZodString>;
786
+ }, z.core.$strict>>>>;
730
787
  linkTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
731
788
  id: z.ZodString;
732
789
  label: z.ZodOptional<z.ZodString>;
@@ -737,7 +794,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
737
794
  to: z.ZodString;
738
795
  cardinality: z.ZodOptional<z.ZodString>;
739
796
  via: z.ZodOptional<z.ZodString>;
740
- }, z.core.$loose>>>>;
797
+ }, z.core.$strict>>>>;
741
798
  actionTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
742
799
  id: z.ZodString;
743
800
  label: z.ZodOptional<z.ZodString>;
@@ -747,7 +804,11 @@ declare const OrganizationModelSchema: z.ZodObject<{
747
804
  actsOn: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
748
805
  input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
749
806
  effects: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
750
- }, z.core.$loose>>>>;
807
+ resourceId: z.ZodOptional<z.ZodString>;
808
+ invocations: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
809
+ lifecycle: z.ZodOptional<z.ZodString>;
810
+ legacyActionId: z.ZodOptional<z.ZodString>;
811
+ }, z.core.$strict>>>>;
751
812
  catalogTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
752
813
  id: z.ZodString;
753
814
  label: z.ZodOptional<z.ZodString>;
@@ -757,7 +818,10 @@ declare const OrganizationModelSchema: z.ZodObject<{
757
818
  kind: z.ZodOptional<z.ZodString>;
758
819
  appliesTo: z.ZodOptional<z.ZodString>;
759
820
  entries: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
760
- }, z.core.$loose>>>>;
821
+ legacyCatalogKey: z.ZodOptional<z.ZodString>;
822
+ legacyPipelineKey: z.ZodOptional<z.ZodString>;
823
+ legacyEntityKey: z.ZodOptional<z.ZodString>;
824
+ }, z.core.$strict>>>>;
761
825
  eventTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
762
826
  id: z.ZodString;
763
827
  label: z.ZodOptional<z.ZodString>;
@@ -765,7 +829,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
765
829
  ownerSystemId: z.ZodOptional<z.ZodString>;
766
830
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
767
831
  payload: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
768
- }, z.core.$loose>>>>;
832
+ }, z.core.$strict>>>>;
769
833
  interfaceTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
770
834
  id: z.ZodString;
771
835
  label: z.ZodOptional<z.ZodString>;
@@ -773,7 +837,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
773
837
  ownerSystemId: z.ZodOptional<z.ZodString>;
774
838
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
775
839
  properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
776
- }, z.core.$loose>>>>;
840
+ }, z.core.$strict>>>>;
777
841
  valueTypes: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
778
842
  id: z.ZodString;
779
843
  label: z.ZodOptional<z.ZodString>;
@@ -781,7 +845,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
781
845
  ownerSystemId: z.ZodOptional<z.ZodString>;
782
846
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
783
847
  primitive: z.ZodOptional<z.ZodString>;
784
- }, z.core.$loose>>>>;
848
+ }, z.core.$strict>>>>;
785
849
  sharedProperties: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
786
850
  id: z.ZodString;
787
851
  label: z.ZodOptional<z.ZodString>;
@@ -791,7 +855,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
791
855
  valueType: z.ZodOptional<z.ZodString>;
792
856
  searchable: z.ZodOptional<z.ZodBoolean>;
793
857
  pii: z.ZodOptional<z.ZodBoolean>;
794
- }, z.core.$loose>>>>;
858
+ }, z.core.$strict>>>>;
795
859
  groups: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
796
860
  id: z.ZodString;
797
861
  label: z.ZodOptional<z.ZodString>;
@@ -799,7 +863,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
799
863
  ownerSystemId: z.ZodOptional<z.ZodString>;
800
864
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
801
865
  members: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
802
- }, z.core.$loose>>>>;
866
+ }, z.core.$strict>>>>;
803
867
  endpoints: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
804
868
  id: z.ZodString;
805
869
  label: z.ZodOptional<z.ZodString>;
@@ -807,7 +871,7 @@ declare const OrganizationModelSchema: z.ZodObject<{
807
871
  ownerSystemId: z.ZodOptional<z.ZodString>;
808
872
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
809
873
  route: z.ZodOptional<z.ZodString>;
810
- }, z.core.$loose>>>>;
874
+ }, z.core.$strict>>>>;
811
875
  }, z.core.$strict>>>;
812
876
  resources: z.ZodDefault<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
813
877
  id: z.ZodString;
@@ -1263,6 +1327,13 @@ declare const OrganizationModelSchema: z.ZodObject<{
1263
1327
  type OrganizationModel = z.infer<typeof OrganizationModelSchema>;
1264
1328
  type OrganizationModelResourceKind = z.infer<typeof ResourceKindSchema>;
1265
1329
 
1330
+ /** Response-side crop: unknown keys are stripped, not rejected, like every other response schema here. */
1331
+ declare const ContentAssetCropSchema: z.ZodObject<{
1332
+ x: z.ZodNumber;
1333
+ y: z.ZodNumber;
1334
+ width: z.ZodNumber;
1335
+ height: z.ZodNumber;
1336
+ }, z.core.$strip>;
1266
1337
  declare const ContentItemResponseSchema: z.ZodObject<{
1267
1338
  id: z.ZodString;
1268
1339
  organizationId: z.ZodString;
@@ -1274,6 +1345,29 @@ declare const ContentItemResponseSchema: z.ZodObject<{
1274
1345
  pipelineId: z.ZodNullable<z.ZodString>;
1275
1346
  clientId: z.ZodNullable<z.ZodString>;
1276
1347
  sourceAssetId: z.ZodNullable<z.ZodString>;
1348
+ sourceAssets: z.ZodOptional<z.ZodArray<z.ZodObject<{
1349
+ id: z.ZodString;
1350
+ organizationId: z.ZodString;
1351
+ contentItemId: z.ZodString;
1352
+ sourceAssetId: z.ZodString;
1353
+ position: z.ZodNumber;
1354
+ crop: z.ZodNullable<z.ZodObject<{
1355
+ x: z.ZodNumber;
1356
+ y: z.ZodNumber;
1357
+ width: z.ZodNumber;
1358
+ height: z.ZodNumber;
1359
+ }, z.core.$strip>>;
1360
+ altText: z.ZodNullable<z.ZodString>;
1361
+ derivativePath: z.ZodNullable<z.ZodString>;
1362
+ derivativeCrop: z.ZodNullable<z.ZodObject<{
1363
+ x: z.ZodNumber;
1364
+ y: z.ZodNumber;
1365
+ width: z.ZodNumber;
1366
+ height: z.ZodNumber;
1367
+ }, z.core.$strip>>;
1368
+ derivativeRenderedAt: z.ZodNullable<z.ZodString>;
1369
+ createdAt: z.ZodString;
1370
+ }, z.core.$strip>>>;
1277
1371
  processingState: z.ZodRecord<z.ZodString, z.ZodObject<{
1278
1372
  status: z.ZodEnum<{
1279
1373
  error: "error";
@@ -1296,7 +1390,35 @@ declare const ContentItemResponseSchema: z.ZodObject<{
1296
1390
  createdAt: z.ZodString;
1297
1391
  updatedAt: z.ZodString;
1298
1392
  }, z.core.$strip>;
1393
+ declare const ContentSourceAssetResponseSchema: z.ZodObject<{
1394
+ id: z.ZodString;
1395
+ organizationId: z.ZodString;
1396
+ kind: z.ZodString;
1397
+ title: z.ZodString;
1398
+ externalUrl: z.ZodNullable<z.ZodString>;
1399
+ storagePath: z.ZodNullable<z.ZodString>;
1400
+ durationSeconds: z.ZodNullable<z.ZodNumber>;
1401
+ metadata: z.ZodUnknown;
1402
+ payload: z.ZodUnknown;
1403
+ processingState: z.ZodRecord<z.ZodString, z.ZodObject<{
1404
+ status: z.ZodEnum<{
1405
+ error: "error";
1406
+ success: "success";
1407
+ running: "running";
1408
+ no_result: "no_result";
1409
+ skipped: "skipped";
1410
+ }>;
1411
+ attemptId: z.ZodString;
1412
+ executionId: z.ZodNullable<z.ZodString>;
1413
+ attemptedAt: z.ZodString;
1414
+ data: z.ZodOptional<z.ZodUnknown>;
1415
+ }, z.core.$loose>>;
1416
+ createdAt: z.ZodString;
1417
+ updatedAt: z.ZodString;
1418
+ }, z.core.$strip>;
1419
+ type ContentAssetCrop = z.infer<typeof ContentAssetCropSchema>;
1299
1420
  type ContentItemResponse = z.infer<typeof ContentItemResponseSchema>;
1421
+ type ContentSourceAssetResponse = z.infer<typeof ContentSourceAssetResponseSchema>;
1300
1422
 
1301
1423
  /**
1302
1424
  * `deriveContentBoard` -- a pure function of `(items, pipeline, now)`. No React, no
@@ -1344,15 +1466,23 @@ interface ContentBoardCard {
1344
1466
  awaitingReview: boolean;
1345
1467
  }
1346
1468
  interface ContentBoardGate {
1347
- /** The review mode of the step this gate follows. Never 'none' -- a 'none' step has no gate. */
1348
- reviewMode: Exclude<ContentPipelineStepReviewMode, 'none'>;
1469
+ /**
1470
+ * Where this gate's review happens. Never `'none'` -- a step nobody reviews
1471
+ * has no gate at all.
1472
+ *
1473
+ * This replaced a `reviewMode` field when the enum collapsed to
1474
+ * `'none' | 'required'`, which would have left every gate reporting the same
1475
+ * constant. Venue is the fact a consumer actually renders: the CLI's board
1476
+ * label and the UI's column header both need to say *where*, not *whether*.
1477
+ */
1478
+ venue: Exclude<ContentReviewVenue, 'none'>;
1349
1479
  /** How many cards in the preceding column are awaiting review. */
1350
1480
  waitingCount: number;
1351
1481
  }
1352
1482
  interface ContentBoardColumn {
1353
1483
  step: ContentPipelineStepEntry;
1354
1484
  cards: ContentBoardCard[];
1355
- /** Present when this step's reviewMode is 'live' or 'queued'. Absent on a 'none' step. */
1485
+ /** Present when this step's `reviewVenue` is not `'none'`. A step nobody reviews has no gate. */
1356
1486
  gate?: ContentBoardGate;
1357
1487
  }
1358
1488
  interface ContentBoard {
@@ -1388,6 +1518,39 @@ declare function deriveContentBoard(items: ContentItemResponse[], pipeline: Cont
1388
1518
  */
1389
1519
  declare function getContentItemIdentity(item: Pick<ContentItemResponse, 'title' | 'body' | 'payload'>, payloadFields?: ContentPayloadFieldDeclaration[], maxLength?: number): string;
1390
1520
 
1521
+ /**
1522
+ * Storage-neutral file descriptor.
1523
+ *
1524
+ * Dropbox and Google Drive (the foreseeable second provider) both ship
1525
+ * their own file/metadata shapes. Consumers on both sides of the wire —
1526
+ * a UI file browser and the API route that talks to the provider — need
1527
+ * to agree on one normalized shape, which is why it lives here instead
1528
+ * of being duplicated in each consumer.
1529
+ *
1530
+ * Adapters (`createDropboxAdapter`, a future Drive adapter) stay concrete
1531
+ * and keep their own provider-shaped responses. Normalization into this
1532
+ * type happens at the route/hook boundary — a few lines per provider,
1533
+ * not behind a shared `CloudStorageAdapter` interface.
1534
+ */
1535
+ interface CloudStorageFile {
1536
+ id: string;
1537
+ name: string;
1538
+ kind: 'file' | 'folder';
1539
+ path?: string;
1540
+ mimeType?: string;
1541
+ sizeBytes?: number;
1542
+ width?: number;
1543
+ height?: number;
1544
+ /** ISO 8601 timestamp the asset was captured (e.g. photo EXIF date), when the provider exposes one. */
1545
+ capturedAt?: string;
1546
+ /**
1547
+ * Optional on purpose. Dropbox does not produce a thumbnail for HEIC or
1548
+ * for anything over 20 MB — "no thumbnail" is a normal state a consumer
1549
+ * renders a fallback for, not an error.
1550
+ */
1551
+ thumbnailUrl?: string;
1552
+ }
1553
+
1391
1554
  type SystemSidebarComponent = ComponentType;
1392
1555
  type SystemIconComponent = ComponentType<{
1393
1556
  size?: number;
@@ -1807,6 +1970,306 @@ interface ContentReviewCardProps {
1807
1970
  */
1808
1971
  declare function ContentReviewCard({ title, body, onBodyChange, originalBody, onReset, payload, payloadFields, fidelity, checkFirst, hookOptions, closeOptions, onMoreHooks, onMoreCloses, alternatesRunning, alternatesElapsed, processingSteps, actions, onAction, actionsPending, readOnly }: ContentReviewCardProps): react_jsx_runtime.JSX.Element;
1809
1972
 
1973
+ interface SelectedAssetStripProps {
1974
+ /**
1975
+ * The selection, in carousel order. Index 0 is the cover slide -- there is no
1976
+ * separate `isCover` flag to keep in sync, because the planned
1977
+ * `content_item_source_assets` link table persists this same array as a `position`
1978
+ * column where `position = 0` IS the cover by definition.
1979
+ */
1980
+ assets: CloudStorageFile[];
1981
+ /** Fires with the full reordered array whenever the user drags a slide to a new position. */
1982
+ onReorder: (assets: CloudStorageFile[]) => void;
1983
+ }
1984
+ /**
1985
+ * Ordered strip of the assets selected for a multi-asset content item (an Instagram
1986
+ * carousel post's slides). Presentational -- data in via `assets`, order changes out
1987
+ * via `onReorder`, no fetching. Drag-reorder uses native HTML5 drag events, matching
1988
+ * the pattern already established for `KanbanBoard` / `DealKanbanCard` rather than
1989
+ * introducing a new drag-and-drop dependency for one strip.
1990
+ */
1991
+ declare function SelectedAssetStrip({ assets, onReorder }: SelectedAssetStripProps): react_jsx_runtime.JSX.Element;
1992
+
1993
+ interface SourceAssetsPanelProps {
1994
+ /** The content item whose membership this panel reads and writes. */
1995
+ itemId: string;
1996
+ }
1997
+ /**
1998
+ * Operator surface for a content item's ordered source-asset membership -- the
1999
+ * carousel. Reads `content_item_source_assets` and drives all four membership
2000
+ * writes: link, unlink, reorder, and per-slide alt text.
2001
+ *
2002
+ * This exists because the membership write path had no surface at all: it is not on
2003
+ * the CLI, the external API-key routes were deliberately not extended (Open Decision
2004
+ * 10), and the seed workflow still creates items through the legacy singular
2005
+ * `sourceAssetId`. Everything below the hooks was therefore covered by unit tests
2006
+ * only and had never been executed end to end. A basic table is enough to fix that,
2007
+ * and a tenant that wants a picture-first carousel editor builds its own on the same
2008
+ * hooks.
2009
+ *
2010
+ * Two ordering surfaces on purpose. `SelectedAssetStrip` is the picture-first one and
2011
+ * is what tenants get from the `./features/content` subpath, so it is mounted here
2012
+ * against real persisted membership rather than left to render only under test. The
2013
+ * table underneath keeps move up / move down because drag is unusable by keyboard and
2014
+ * unavailable to a screen reader. Both send the identical complete ordered list.
2015
+ *
2016
+ * The strip takes `CloudStorageFile`, which a membership is not -- the mapping below is
2017
+ * the whole adapter. Content source assets carry no thumbnail yet (that arrives with
2018
+ * Dropbox intake), so every tile renders the strip's no-thumbnail fallback today.
2019
+ *
2020
+ * The crop column opens `AssetCropEditor` against the original's bytes, resolved
2021
+ * one file at a time while the modal is open. Only an asset carrying a
2022
+ * cloud-storage reference can be cropped -- there is nothing to crop against
2023
+ * otherwise -- so a seeded or text-backed asset shows the button disabled.
2024
+ *
2025
+ * Positions are shown as stored, not as row indexes. Non-contiguous positions are
2026
+ * legal -- only uniqueness within an item is enforced -- so an item assembled by
2027
+ * individual links can legitimately have no `position` 0, and the cover is the lowest
2028
+ * position present rather than a literal 0.
2029
+ */
2030
+ declare function SourceAssetsPanel({ itemId }: SourceAssetsPanelProps): react_jsx_runtime.JSX.Element;
2031
+
2032
+ /**
2033
+ * A carousel aspect option. `ratio` is width / height in PIXELS -- `null` means
2034
+ * "whatever the source already is", which is the only option that never crops.
2035
+ */
2036
+ interface CropAspectOption {
2037
+ value: string;
2038
+ label: string;
2039
+ ratio: number | null;
2040
+ }
2041
+ /**
2042
+ * The three shapes a photo post actually takes, plus the uncropped original.
2043
+ * Portrait 4:5 leads because it is the tallest a feed will show without
2044
+ * cropping the image itself, so it is the default for a carousel.
2045
+ */
2046
+ declare const CROP_ASPECT_OPTIONS: CropAspectOption[];
2047
+ interface AssetCropEditorProps {
2048
+ /**
2049
+ * The FULL-RESOLUTION image. A thumbnail will not do: the crop is stored as
2050
+ * fractions of the source, and a downsampled copy shows the operator a
2051
+ * different frame from the one that gets published.
2052
+ */
2053
+ imageUrl: string | null;
2054
+ /** The stored crop, or `null` for "uncropped". */
2055
+ value: ContentAssetCrop | null;
2056
+ /** Fires on every committed change. `null` clears the crop back to the full frame. */
2057
+ onChange: (crop: ContentAssetCrop | null) => void;
2058
+ /** Which aspect the control starts on. Defaults to the source's own shape. */
2059
+ defaultAspect?: string;
2060
+ /** Locks the aspect selector -- a carousel wants one ratio across every slide. */
2061
+ aspect?: string;
2062
+ disabled?: boolean;
2063
+ /** Shown above the frame, e.g. `Slide 1`. */
2064
+ label?: string;
2065
+ }
2066
+ /**
2067
+ * Picks the crop box out of a normalized frame, over the image itself.
2068
+ *
2069
+ * The emitted value is exactly what `ContentAssetCropInputSchema` validates:
2070
+ * `{ x, y, width, height }` as fractions of the source, `0,0` at the top-left.
2071
+ * Fractions rather than pixels because the same crop has to survive a resized
2072
+ * derivative, which is also why this needs the original rather than a thumbnail.
2073
+ *
2074
+ * **Aspect is expressed in pixels and stored in fractions**, and the two are not
2075
+ * the same number on a non-square image -- a 1:1 crop of a 4000x3000 photo is
2076
+ * `width: 0.75, height: 1`. `fitBox` is the whole of that conversion.
2077
+ *
2078
+ * Two controls, not a free-form rubber band: an aspect and a size, with the frame
2079
+ * dragged into place. A free rectangle lets an operator produce a shape no feed
2080
+ * will render, and the failure only shows up after posting.
2081
+ */
2082
+ declare function AssetCropEditor({ imageUrl, value, onChange, defaultAspect, aspect, disabled, label }: AssetCropEditorProps): react_jsx_runtime.JSX.Element;
2083
+
2084
+ /** One slide, in carousel order. */
2085
+ interface PostPreviewSlide {
2086
+ /** Stable per-slide key -- the source asset id, or the storage file id before one exists. */
2087
+ id: string;
2088
+ /** The full-resolution image. `null` renders the empty frame rather than a broken one. */
2089
+ imageUrl: string | null;
2090
+ /** The stored crop, or `null` for the uncropped original. */
2091
+ crop?: ContentAssetCrop | null;
2092
+ altText?: string | null;
2093
+ }
2094
+ interface PostPreviewProps {
2095
+ slides: PostPreviewSlide[];
2096
+ /** The caption as it would post. `null` renders the "no caption yet" line. */
2097
+ caption?: string | null;
2098
+ hashtags?: string[];
2099
+ /** Frame shape, width / height in pixels. Defaults to the 4:5 portrait a carousel uses. */
2100
+ aspectRatio?: number;
2101
+ /** Shown above the frame, e.g. the item title. */
2102
+ title?: string;
2103
+ }
2104
+ /**
2105
+ * The carousel as it will actually post: slides in position order, each one
2106
+ * showing only the part its crop keeps, with the caption underneath.
2107
+ *
2108
+ * **The crop is applied here, not baked into any file.** Nothing in this
2109
+ * pipeline writes a cropped derivative -- `content_item_source_assets.crop` is
2110
+ * a normalized box, and every surface that renders a slide applies it. This
2111
+ * component is the reference implementation of that, and the reason it is
2112
+ * shared rather than page-local.
2113
+ *
2114
+ * The technique is an oversized absolutely-positioned image inside an
2115
+ * overflow-hidden frame: an image scaled to `1 / crop.width` of the frame and
2116
+ * offset by `-crop.x / crop.width` puts exactly the kept region in view, in
2117
+ * pure CSS and with no canvas step. `object-fit: cover` stays on so a slide
2118
+ * whose crop aspect does not match the frame is trimmed rather than stretched.
2119
+ */
2120
+ declare function PostPreview({ slides, caption, hashtags, aspectRatio, title }: PostPreviewProps): react_jsx_runtime.JSX.Element;
2121
+ /**
2122
+ * Positions the image so the frame shows only the crop's region.
2123
+ *
2124
+ * Exported for the unit test: the arithmetic is the one part of this component
2125
+ * that can be silently wrong, and asserting it through a rendered style string
2126
+ * is what catches an inverted sign.
2127
+ */
2128
+ declare function cropStyle(crop: ContentAssetCrop | null): React.CSSProperties;
2129
+
2130
+ /**
2131
+ * Rendering a crop to an actual file.
2132
+ *
2133
+ * `cropStyle` in `PostPreview` renders the same crop with CSS, which is right for
2134
+ * a preview and useless for posting: the cropped image never exists as bytes, so
2135
+ * there is nothing to download and nothing to hand a platform. This module is the
2136
+ * other half -- the same four normalized numbers, resolved into a JPEG.
2137
+ *
2138
+ * It runs in the browser on purpose. The pixels are already decoded there (the
2139
+ * crop editor and the preview share one download of the original), the source is
2140
+ * a short-lived provider link the server would have to re-fetch, and no image
2141
+ * library exists anywhere in this monorepo -- putting this on the server would
2142
+ * mean adding the first native image binary to a service whose build is a no-op.
2143
+ * A spike on 2026-08-19 confirmed Dropbox's temporary-link hosts send permissive
2144
+ * CORS, so the canvas is not tainted and `toBlob` succeeds.
2145
+ */
2146
+ /** The private, org-scoped, RLS-gated bucket derivatives live in. */
2147
+ declare const CONTENT_DERIVATIVES_BUCKET = "content-derivatives";
2148
+ /**
2149
+ * Widest edge a derivative is encoded at.
2150
+ *
2151
+ * 1080 is what Instagram renders a feed image at; anything wider is downsampled on
2152
+ * upload, so the extra bytes buy nothing. A crop smaller than this is never
2153
+ * upscaled to reach it -- see `renderCropToJpeg`.
2154
+ */
2155
+ declare const DERIVATIVE_MAX_WIDTH = 1080;
2156
+ /** JPEG quality. 0.9 measured at 84-104 KB for a 1080x1350 slide. */
2157
+ declare const DERIVATIVE_JPEG_QUALITY = 0.9;
2158
+ /**
2159
+ * Object key for one slide's derivative, WITHOUT the `{organizationId}/` prefix --
2160
+ * `StorageService.buildPath` prepends that server-side, and the `storage.objects`
2161
+ * policies read the org back out of it.
2162
+ *
2163
+ * Keyed by item and source asset rather than by membership id so a re-render
2164
+ * overwrites the previous derivative instead of accumulating one file per edit.
2165
+ * The pair is unique within an item by database constraint, which is what makes
2166
+ * that safe.
2167
+ */
2168
+ declare function derivativeObjectKey(contentItemId: string, sourceAssetId: string): string;
2169
+ /**
2170
+ * Whether the stored derivative no longer matches the crop it is supposed to show.
2171
+ *
2172
+ * Derived, never stored: a `derivativeIsStale` column would be a second encoding of
2173
+ * what these two values already say, and the two could disagree. A membership with
2174
+ * no crop has nothing to render, and one with no derivative is missing rather than
2175
+ * stale -- both return false, because neither is a file that needs replacing.
2176
+ */
2177
+ declare function isDerivativeStale(crop: ContentAssetCrop | null, derivativeCrop: ContentAssetCrop | null, derivativePath: string | null): boolean;
2178
+ interface RenderCropOptions {
2179
+ /** Widest edge to encode at. Defaults to `DERIVATIVE_MAX_WIDTH`. */
2180
+ maxWidth?: number;
2181
+ /** JPEG quality, 0-1. Defaults to `DERIVATIVE_JPEG_QUALITY`. */
2182
+ quality?: number;
2183
+ }
2184
+ /**
2185
+ * Render a crop box against its source image and return the cropped JPEG.
2186
+ *
2187
+ * `crop` is normalized fractions of the source, exactly as stored -- so this
2188
+ * survives the source being a different pixel size than it was when the crop was
2189
+ * drawn. A `null` crop renders the whole frame, which still does real work: it
2190
+ * normalizes the format and caps the size.
2191
+ *
2192
+ * The output is never upscaled past the cropped region's own pixel count. A tight
2193
+ * crop of a small original produces a smaller file rather than a blurry 1080px
2194
+ * one, and a platform that wants 1080 will upscale it either way.
2195
+ *
2196
+ * Throws rather than returning null on a tainted canvas or an unloadable URL:
2197
+ * silently storing no derivative is indistinguishable from never having tried.
2198
+ */
2199
+ declare function renderCropToJpeg(imageUrl: string, crop: ContentAssetCrop | null, options?: RenderCropOptions): Promise<Blob>;
2200
+
2201
+ /** The `content:catalog/photo-carousel-steps` entry this panel drives. */
2202
+ declare const CAPTION_STEP_KEY = "caption-generation";
2203
+ /** The OM Resource bound to `content:action/caption-generation`. */
2204
+ declare const CAPTION_WORKFLOW_ID = "cnt-caption-generation-workflow";
2205
+ interface CaptionPanelProps {
2206
+ itemId: string;
2207
+ /** The item's current `body`, so the panel can mark which attempt is the live caption. */
2208
+ body?: string | null;
2209
+ /**
2210
+ * Called on every keystroke with the unsaved caption text.
2211
+ *
2212
+ * This exists so a preview rendered beside the editor updates as the operator
2213
+ * types rather than one autosave later. Consumers that only care about the
2214
+ * persisted value can ignore it and read `body` as before.
2215
+ */
2216
+ onDraftChange?: (draft: string) => void;
2217
+ }
2218
+ /**
2219
+ * Generate a caption for a carousel, regenerate it, and pick which one becomes
2220
+ * the item's body.
2221
+ *
2222
+ * **Regeneration does not overwrite.** Every run of
2223
+ * `cnt-caption-generation-workflow` writes its own `content_item_attempts` row,
2224
+ * so a second caption competes with the first rather than replacing it, and the
2225
+ * one the operator liked stays reachable after they try something else. Nothing
2226
+ * here is promoted automatically: `content_items.body` changes only when someone
2227
+ * presses Use, which is exactly what the step's `reviewMode: 'required'` means.
2228
+ *
2229
+ * The workflow runs asynchronously and the panel polls its execution, because
2230
+ * a vision-informed caption over several slides regularly outruns the API's
2231
+ * 60-second synchronous request timeout.
2232
+ */
2233
+ declare function CaptionPanel({ itemId, body, onDraftChange }: CaptionPanelProps): react_jsx_runtime.JSX.Element;
2234
+
2235
+ /** The OM Resource bound to `content:action/image-analysis`. */
2236
+ declare const IMAGE_ANALYSIS_WORKFLOW_ID = "cnt-image-analysis-workflow";
2237
+ interface SlideAnalysisPanelProps {
2238
+ itemId: string;
2239
+ }
2240
+ /**
2241
+ * What `cnt-image-analysis-workflow` writes to `content_source_assets.metadata.analysis`.
2242
+ * Every field is read defensively: the column is free-form jsonb, so an older row, a
2243
+ * hand-edited one, or one written by a future version of the workflow may carry
2244
+ * anything at all.
2245
+ */
2246
+ interface StoredSlideAnalysis {
2247
+ description?: string;
2248
+ subjects?: string[];
2249
+ setting?: string;
2250
+ mood?: string;
2251
+ textInImage?: string;
2252
+ altText?: string;
2253
+ model?: string;
2254
+ generatedAt?: string;
2255
+ }
2256
+ /** Reads the analysis off an asset, or `null` when it has never been analysed. */
2257
+ declare function readStoredAnalysis(asset: ContentSourceAssetResponse | undefined): StoredSlideAnalysis | null;
2258
+ /**
2259
+ * Runs image analysis over a carousel's slides and shows what came back.
2260
+ *
2261
+ * **The analysis lives on the ASSET, not on the membership** (Open Decision 14).
2262
+ * It describes the photograph, so it is written once per photo and every item
2263
+ * that uses that photo reads the same description -- and a re-crop does not
2264
+ * invalidate it. The per-slide fields beside it (`crop`, `altText`) stay on the
2265
+ * membership, where a slide's role in one particular carousel belongs.
2266
+ *
2267
+ * Re-running is a plain overwrite here, unlike captions: there is no competing
2268
+ * "which description is better" judgement to preserve, and an analysis is an
2269
+ * input to the caption rather than something anyone publishes.
2270
+ */
2271
+ declare function SlideAnalysisPanel({ itemId }: SlideAnalysisPanelProps): react_jsx_runtime.JSX.Element;
2272
+
1810
2273
  /** A single tenant-facing noun with singular and plural forms, e.g. `{ singular: 'Post', plural: 'Posts' }`. */
1811
2274
  interface ContentNoun {
1812
2275
  singular: string;
@@ -2038,8 +2501,8 @@ interface MyReviewQueuePanelProps {
2038
2501
  * cross-pipeline "what needs review" view rather than a panel beside a table browser.
2039
2502
  *
2040
2503
  * The `/content/items` route accepts no "pending review" filter (only `reviewedBy`, not
2041
- * a reviewed/unreviewed flag), so this fetches a page of items and filters to
2042
- * `reviewedAt === null` client-side. A future backend addition could push this
2504
+ * a reviewed/unreviewed flag), so this fetches a page of items and filters to the ones
2505
+ * `isAwaitingReview` client-side. A future backend addition could push this
2043
2506
  * server-side; documenting the gap here rather than silently over-claiming precision.
2044
2507
  *
2045
2508
  * Rows are ordered oldest-first by `updatedAt` -- finding 6 is that nothing on the
@@ -2048,5 +2511,5 @@ interface MyReviewQueuePanelProps {
2048
2511
  */
2049
2512
  declare function MyReviewQueuePanel({ onItemClick, onSeeAll, showSectionLabel }: MyReviewQueuePanelProps): react_jsx_runtime.JSX.Element;
2050
2513
 
2051
- export { AlternatesPanel, CONTENT_ITEMS, ContentDistributionDetailPage, ContentDistributionsPage, ContentItemReviewPage, ContentItemsPage, ContentOverviewPage, ContentPipelineBoardPage, ContentPipelineBoardPage as ContentPipelineWorkspacePage, ContentPipelinesPage, ContentReviewCard, ContentSidebar, ContentSidebarMiddle, DEFAULT_CONTENT_VOCABULARY, MyReviewQueuePanel, PayloadBody, ProcessingStateStrip, ReviewActionBar, contentManifest, deriveContentBoard, firstLine, formatElapsed, getContentItemIdentity, lastLine, resolveContentStepResource, resolveContentVocabulary, swapFirstLine, swapLastLine, useContentConfig };
2052
- export type { AlternatesPanelProps, ContentAlternateOption, ContentBoard, ContentBoardCard, ContentBoardColumn, ContentBoardGate, ContentConfig, ContentDistributionDetailPageSlots, ContentDistributionsPageSlots, ContentFidelityCheck, ContentItemReviewPageSlots, ContentItemsPageSlots, ContentNoun, ContentOverviewPageSlots, ContentPayloadField, ContentPipelineBoardPageSlots, ContentPipelineBoardPageSlots as ContentPipelineWorkspacePageSlots, ContentPipelinesPageSlots, ContentProcessingStatus, ContentProcessingStep, ContentReviewAction, ContentReviewCardProps, ContentSidebarMiddleProps, ContentSidebarProps, ContentStepResourceBinding, ContentVocabulary, MyReviewQueuePanelProps, PayloadBodyProps, ProcessingStateStripProps, ReviewActionBarProps, ReviewMode };
2514
+ export { AlternatesPanel, AssetCropEditor, CAPTION_STEP_KEY, CAPTION_WORKFLOW_ID, CONTENT_DERIVATIVES_BUCKET, CONTENT_ITEMS, CROP_ASPECT_OPTIONS, CaptionPanel, ContentDistributionDetailPage, ContentDistributionsPage, ContentItemReviewPage, ContentItemsPage, ContentOverviewPage, ContentPipelineBoardPage, ContentPipelineBoardPage as ContentPipelineWorkspacePage, ContentPipelinesPage, ContentReviewCard, ContentSidebar, ContentSidebarMiddle, DEFAULT_CONTENT_VOCABULARY, DERIVATIVE_JPEG_QUALITY, DERIVATIVE_MAX_WIDTH, IMAGE_ANALYSIS_WORKFLOW_ID, MyReviewQueuePanel, PayloadBody, PostPreview, ProcessingStateStrip, ReviewActionBar, SelectedAssetStrip, SlideAnalysisPanel, SourceAssetsPanel, contentManifest, cropStyle, derivativeObjectKey, deriveContentBoard, firstLine, formatElapsed, getContentItemIdentity, isDerivativeStale, lastLine, readStoredAnalysis, renderCropToJpeg, resolveContentStepResource, resolveContentVocabulary, swapFirstLine, swapLastLine, useContentConfig };
2515
+ export type { AlternatesPanelProps, AssetCropEditorProps, CaptionPanelProps, ContentAlternateOption, ContentBoard, ContentBoardCard, ContentBoardColumn, ContentBoardGate, ContentConfig, ContentDistributionDetailPageSlots, ContentDistributionsPageSlots, ContentFidelityCheck, ContentItemReviewPageSlots, ContentItemsPageSlots, ContentNoun, ContentOverviewPageSlots, ContentPayloadField, ContentPipelineBoardPageSlots, ContentPipelineBoardPageSlots as ContentPipelineWorkspacePageSlots, ContentPipelinesPageSlots, ContentProcessingStatus, ContentProcessingStep, ContentReviewAction, ContentReviewCardProps, ContentSidebarMiddleProps, ContentSidebarProps, ContentStepResourceBinding, ContentVocabulary, CropAspectOption, MyReviewQueuePanelProps, PayloadBodyProps, PostPreviewProps, PostPreviewSlide, ProcessingStateStripProps, RenderCropOptions, ReviewActionBarProps, ReviewMode, SelectedAssetStripProps, SlideAnalysisPanelProps, SourceAssetsPanelProps, StoredSlideAnalysis };