@cohesivesystems/presentation-react-shadcn 0.1.0-alpha.1

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 (262) hide show
  1. package/LICENSE +55 -0
  2. package/dist/document-workspace-surface-slot-renderers.d.ts +58 -0
  3. package/dist/document-workspace-surface-slot-renderers.d.ts.map +1 -0
  4. package/dist/document-workspace-surface-slot-renderers.js +206 -0
  5. package/dist/document-workspace-surface-slot-renderers.js.map +1 -0
  6. package/dist/index.d.ts +53 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +53 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/navigation-shell-frame-renderer-registry.d.ts +8 -0
  11. package/dist/navigation-shell-frame-renderer-registry.d.ts.map +1 -0
  12. package/dist/navigation-shell-frame-renderer-registry.js +2 -0
  13. package/dist/navigation-shell-frame-renderer-registry.js.map +1 -0
  14. package/dist/navigation-shell-slot-renderer-registry.d.ts +9 -0
  15. package/dist/navigation-shell-slot-renderer-registry.d.ts.map +1 -0
  16. package/dist/navigation-shell-slot-renderer-registry.js +2 -0
  17. package/dist/navigation-shell-slot-renderer-registry.js.map +1 -0
  18. package/dist/page-host-unavailable-renderer.d.ts +10 -0
  19. package/dist/page-host-unavailable-renderer.d.ts.map +1 -0
  20. package/dist/page-host-unavailable-renderer.js +27 -0
  21. package/dist/page-host-unavailable-renderer.js.map +1 -0
  22. package/dist/presentation-action-group.d.ts +99 -0
  23. package/dist/presentation-action-group.d.ts.map +1 -0
  24. package/dist/presentation-action-group.js +214 -0
  25. package/dist/presentation-action-group.js.map +1 -0
  26. package/dist/presentation-badge-target-interpreter.d.ts +26 -0
  27. package/dist/presentation-badge-target-interpreter.d.ts.map +1 -0
  28. package/dist/presentation-badge-target-interpreter.js +17 -0
  29. package/dist/presentation-badge-target-interpreter.js.map +1 -0
  30. package/dist/presentation-component-groups.d.ts +968 -0
  31. package/dist/presentation-component-groups.d.ts.map +1 -0
  32. package/dist/presentation-component-groups.js +505 -0
  33. package/dist/presentation-component-groups.js.map +1 -0
  34. package/dist/presentation-component-system-diagnostics.d.ts +27 -0
  35. package/dist/presentation-component-system-diagnostics.d.ts.map +1 -0
  36. package/dist/presentation-component-system-diagnostics.js +399 -0
  37. package/dist/presentation-component-system-diagnostics.js.map +1 -0
  38. package/dist/presentation-component-system.d.ts +31 -0
  39. package/dist/presentation-component-system.d.ts.map +1 -0
  40. package/dist/presentation-component-system.js +61 -0
  41. package/dist/presentation-component-system.js.map +1 -0
  42. package/dist/presentation-icon-diagnostics.d.ts +12 -0
  43. package/dist/presentation-icon-diagnostics.d.ts.map +1 -0
  44. package/dist/presentation-icon-diagnostics.js +17 -0
  45. package/dist/presentation-icon-diagnostics.js.map +1 -0
  46. package/dist/presentation-icon-registry.d.ts +28 -0
  47. package/dist/presentation-icon-registry.d.ts.map +1 -0
  48. package/dist/presentation-icon-registry.js +80 -0
  49. package/dist/presentation-icon-registry.js.map +1 -0
  50. package/dist/presentation-projection-trace-panel.d.ts +10 -0
  51. package/dist/presentation-projection-trace-panel.d.ts.map +1 -0
  52. package/dist/presentation-projection-trace-panel.js +48 -0
  53. package/dist/presentation-projection-trace-panel.js.map +1 -0
  54. package/dist/presentation-routed-surface-host.d.ts +19 -0
  55. package/dist/presentation-routed-surface-host.d.ts.map +1 -0
  56. package/dist/presentation-routed-surface-host.js +12 -0
  57. package/dist/presentation-routed-surface-host.js.map +1 -0
  58. package/dist/presentation-shadcn-component-system.d.ts +22 -0
  59. package/dist/presentation-shadcn-component-system.d.ts.map +1 -0
  60. package/dist/presentation-shadcn-component-system.js +2 -0
  61. package/dist/presentation-shadcn-component-system.js.map +1 -0
  62. package/dist/presentation-standard-renderers.d.ts +168 -0
  63. package/dist/presentation-standard-renderers.d.ts.map +1 -0
  64. package/dist/presentation-standard-renderers.js +440 -0
  65. package/dist/presentation-standard-renderers.js.map +1 -0
  66. package/dist/presentation-surface-renderer.d.ts +23 -0
  67. package/dist/presentation-surface-renderer.d.ts.map +1 -0
  68. package/dist/presentation-surface-renderer.js +119 -0
  69. package/dist/presentation-surface-renderer.js.map +1 -0
  70. package/dist/presentation-value-renderers.d.ts +10 -0
  71. package/dist/presentation-value-renderers.d.ts.map +1 -0
  72. package/dist/presentation-value-renderers.js +14 -0
  73. package/dist/presentation-value-renderers.js.map +1 -0
  74. package/dist/process-task-icons.d.ts +49 -0
  75. package/dist/process-task-icons.d.ts.map +1 -0
  76. package/dist/process-task-icons.js +154 -0
  77. package/dist/process-task-icons.js.map +1 -0
  78. package/dist/projected-activity-state.d.ts +17 -0
  79. package/dist/projected-activity-state.d.ts.map +1 -0
  80. package/dist/projected-activity-state.js +22 -0
  81. package/dist/projected-activity-state.js.map +1 -0
  82. package/dist/projected-collection-action-runtime-diagnostics.d.ts +4 -0
  83. package/dist/projected-collection-action-runtime-diagnostics.d.ts.map +1 -0
  84. package/dist/projected-collection-action-runtime-diagnostics.js +9 -0
  85. package/dist/projected-collection-action-runtime-diagnostics.js.map +1 -0
  86. package/dist/projected-collection-view.d.ts +90 -0
  87. package/dist/projected-collection-view.d.ts.map +1 -0
  88. package/dist/projected-collection-view.js +532 -0
  89. package/dist/projected-collection-view.js.map +1 -0
  90. package/dist/projected-document-action-status-notices.d.ts +15 -0
  91. package/dist/projected-document-action-status-notices.d.ts.map +1 -0
  92. package/dist/projected-document-action-status-notices.js +33 -0
  93. package/dist/projected-document-action-status-notices.js.map +1 -0
  94. package/dist/projected-document-badges.d.ts +24 -0
  95. package/dist/projected-document-badges.d.ts.map +1 -0
  96. package/dist/projected-document-badges.js +53 -0
  97. package/dist/projected-document-badges.js.map +1 -0
  98. package/dist/projected-document-editor-surface.d.ts +46 -0
  99. package/dist/projected-document-editor-surface.d.ts.map +1 -0
  100. package/dist/projected-document-editor-surface.js +399 -0
  101. package/dist/projected-document-editor-surface.js.map +1 -0
  102. package/dist/projected-document-workspace-notices.d.ts +24 -0
  103. package/dist/projected-document-workspace-notices.d.ts.map +1 -0
  104. package/dist/projected-document-workspace-notices.js +14 -0
  105. package/dist/projected-document-workspace-notices.js.map +1 -0
  106. package/dist/projected-document-workspace-prompt-child-view-registry.d.ts +25 -0
  107. package/dist/projected-document-workspace-prompt-child-view-registry.d.ts.map +1 -0
  108. package/dist/projected-document-workspace-prompt-child-view-registry.js +41 -0
  109. package/dist/projected-document-workspace-prompt-child-view-registry.js.map +1 -0
  110. package/dist/projected-document-workspace-prompt-child-view-renderers.d.ts +32 -0
  111. package/dist/projected-document-workspace-prompt-child-view-renderers.d.ts.map +1 -0
  112. package/dist/projected-document-workspace-prompt-child-view-renderers.js +77 -0
  113. package/dist/projected-document-workspace-prompt-child-view-renderers.js.map +1 -0
  114. package/dist/projected-document-workspace-shell.d.ts +100 -0
  115. package/dist/projected-document-workspace-shell.d.ts.map +1 -0
  116. package/dist/projected-document-workspace-shell.js +153 -0
  117. package/dist/projected-document-workspace-shell.js.map +1 -0
  118. package/dist/projected-document-workspace.d.ts +39 -0
  119. package/dist/projected-document-workspace.d.ts.map +1 -0
  120. package/dist/projected-document-workspace.js +63 -0
  121. package/dist/projected-document-workspace.js.map +1 -0
  122. package/dist/projected-field-value-rendering.d.ts +94 -0
  123. package/dist/projected-field-value-rendering.d.ts.map +1 -0
  124. package/dist/projected-field-value-rendering.js +377 -0
  125. package/dist/projected-field-value-rendering.js.map +1 -0
  126. package/dist/projected-inline-list.d.ts +20 -0
  127. package/dist/projected-inline-list.d.ts.map +1 -0
  128. package/dist/projected-inline-list.js +149 -0
  129. package/dist/projected-inline-list.js.map +1 -0
  130. package/dist/projected-input-form.d.ts +143 -0
  131. package/dist/projected-input-form.d.ts.map +1 -0
  132. package/dist/projected-input-form.js +612 -0
  133. package/dist/projected-input-form.js.map +1 -0
  134. package/dist/projected-metric-dashboard.d.ts +26 -0
  135. package/dist/projected-metric-dashboard.d.ts.map +1 -0
  136. package/dist/projected-metric-dashboard.js +20 -0
  137. package/dist/projected-metric-dashboard.js.map +1 -0
  138. package/dist/projected-metric-strip.d.ts +20 -0
  139. package/dist/projected-metric-strip.d.ts.map +1 -0
  140. package/dist/projected-metric-strip.js +131 -0
  141. package/dist/projected-metric-strip.js.map +1 -0
  142. package/dist/projected-navigation-shell-view-host.d.ts +34 -0
  143. package/dist/projected-navigation-shell-view-host.d.ts.map +1 -0
  144. package/dist/projected-navigation-shell-view-host.js +75 -0
  145. package/dist/projected-navigation-shell-view-host.js.map +1 -0
  146. package/dist/projected-navigation-shell.d.ts +33 -0
  147. package/dist/projected-navigation-shell.d.ts.map +1 -0
  148. package/dist/projected-navigation-shell.js +112 -0
  149. package/dist/projected-navigation-shell.js.map +1 -0
  150. package/dist/projected-presentation-badges.d.ts +34 -0
  151. package/dist/projected-presentation-badges.d.ts.map +1 -0
  152. package/dist/projected-presentation-badges.js +22 -0
  153. package/dist/projected-presentation-badges.js.map +1 -0
  154. package/dist/projected-presentation-diagnostics.d.ts +10 -0
  155. package/dist/projected-presentation-diagnostics.d.ts.map +1 -0
  156. package/dist/projected-presentation-diagnostics.js +40 -0
  157. package/dist/projected-presentation-diagnostics.js.map +1 -0
  158. package/dist/projected-presentation-flow-layer.d.ts +33 -0
  159. package/dist/projected-presentation-flow-layer.d.ts.map +1 -0
  160. package/dist/projected-presentation-flow-layer.js +71 -0
  161. package/dist/projected-presentation-flow-layer.js.map +1 -0
  162. package/dist/projected-process-task-notices.d.ts +37 -0
  163. package/dist/projected-process-task-notices.d.ts.map +1 -0
  164. package/dist/projected-process-task-notices.js +225 -0
  165. package/dist/projected-process-task-notices.js.map +1 -0
  166. package/dist/projected-prompt-child-view-renderer.d.ts +101 -0
  167. package/dist/projected-prompt-child-view-renderer.d.ts.map +1 -0
  168. package/dist/projected-prompt-child-view-renderer.js +442 -0
  169. package/dist/projected-prompt-child-view-renderer.js.map +1 -0
  170. package/dist/projected-prompt-document-preview.d.ts +39 -0
  171. package/dist/projected-prompt-document-preview.d.ts.map +1 -0
  172. package/dist/projected-prompt-document-preview.js +50 -0
  173. package/dist/projected-prompt-document-preview.js.map +1 -0
  174. package/dist/projected-prompt-view.d.ts +35 -0
  175. package/dist/projected-prompt-view.d.ts.map +1 -0
  176. package/dist/projected-prompt-view.js +292 -0
  177. package/dist/projected-prompt-view.js.map +1 -0
  178. package/dist/projected-query-form.d.ts +56 -0
  179. package/dist/projected-query-form.d.ts.map +1 -0
  180. package/dist/projected-query-form.js +100 -0
  181. package/dist/projected-query-form.js.map +1 -0
  182. package/dist/projected-record-details.d.ts +20 -0
  183. package/dist/projected-record-details.d.ts.map +1 -0
  184. package/dist/projected-record-details.js +60 -0
  185. package/dist/projected-record-details.js.map +1 -0
  186. package/dist/projected-routed-surface-runtime.d.ts +86 -0
  187. package/dist/projected-routed-surface-runtime.d.ts.map +1 -0
  188. package/dist/projected-routed-surface-runtime.js +332 -0
  189. package/dist/projected-routed-surface-runtime.js.map +1 -0
  190. package/dist/projected-tabs-view.d.ts +21 -0
  191. package/dist/projected-tabs-view.d.ts.map +1 -0
  192. package/dist/projected-tabs-view.js +140 -0
  193. package/dist/projected-tabs-view.js.map +1 -0
  194. package/dist/projected-view-chrome.d.ts +15 -0
  195. package/dist/projected-view-chrome.d.ts.map +1 -0
  196. package/dist/projected-view-chrome.js +67 -0
  197. package/dist/projected-view-chrome.js.map +1 -0
  198. package/dist/projected-view-surface.d.ts +34 -0
  199. package/dist/projected-view-surface.d.ts.map +1 -0
  200. package/dist/projected-view-surface.js +40 -0
  201. package/dist/projected-view-surface.js.map +1 -0
  202. package/dist/standard-collection-chrome-slot-renderers.d.ts +26 -0
  203. package/dist/standard-collection-chrome-slot-renderers.d.ts.map +1 -0
  204. package/dist/standard-collection-chrome-slot-renderers.js +250 -0
  205. package/dist/standard-collection-chrome-slot-renderers.js.map +1 -0
  206. package/dist/standard-view-chrome-slot-renderers.d.ts +57 -0
  207. package/dist/standard-view-chrome-slot-renderers.d.ts.map +1 -0
  208. package/dist/standard-view-chrome-slot-renderers.js +614 -0
  209. package/dist/standard-view-chrome-slot-renderers.js.map +1 -0
  210. package/package.json +68 -0
  211. package/src/document-workspace-surface-slot-renderers.tsx +395 -0
  212. package/src/index.ts +53 -0
  213. package/src/navigation-shell-frame-renderer-registry.ts +29 -0
  214. package/src/navigation-shell-slot-renderer-registry.ts +46 -0
  215. package/src/page-host-unavailable-renderer.tsx +79 -0
  216. package/src/presentation-action-group.tsx +475 -0
  217. package/src/presentation-badge-target-interpreter.ts +54 -0
  218. package/src/presentation-component-groups.ts +2505 -0
  219. package/src/presentation-component-system-diagnostics.ts +848 -0
  220. package/src/presentation-component-system.ts +365 -0
  221. package/src/presentation-icon-diagnostics.ts +53 -0
  222. package/src/presentation-icon-registry.tsx +181 -0
  223. package/src/presentation-projection-trace-panel.tsx +140 -0
  224. package/src/presentation-routed-surface-host.tsx +48 -0
  225. package/src/presentation-shadcn-component-system.ts +102 -0
  226. package/src/presentation-standard-renderers.tsx +1290 -0
  227. package/src/presentation-surface-renderer.tsx +263 -0
  228. package/src/presentation-value-renderers.tsx +40 -0
  229. package/src/process-task-icons.tsx +258 -0
  230. package/src/projected-activity-state.tsx +63 -0
  231. package/src/projected-collection-action-runtime-diagnostics.ts +22 -0
  232. package/src/projected-collection-view.tsx +1273 -0
  233. package/src/projected-document-action-status-notices.tsx +66 -0
  234. package/src/projected-document-badges.tsx +134 -0
  235. package/src/projected-document-editor-surface.tsx +808 -0
  236. package/src/projected-document-workspace-notices.tsx +77 -0
  237. package/src/projected-document-workspace-prompt-child-view-registry.ts +99 -0
  238. package/src/projected-document-workspace-prompt-child-view-renderers.tsx +205 -0
  239. package/src/projected-document-workspace-shell.tsx +427 -0
  240. package/src/projected-document-workspace.tsx +216 -0
  241. package/src/projected-field-value-rendering.tsx +704 -0
  242. package/src/projected-inline-list.tsx +434 -0
  243. package/src/projected-input-form.tsx +1218 -0
  244. package/src/projected-metric-dashboard.tsx +106 -0
  245. package/src/projected-metric-strip.tsx +244 -0
  246. package/src/projected-navigation-shell-view-host.tsx +177 -0
  247. package/src/projected-navigation-shell.tsx +219 -0
  248. package/src/projected-presentation-badges.tsx +95 -0
  249. package/src/projected-presentation-diagnostics.tsx +120 -0
  250. package/src/projected-presentation-flow-layer.tsx +186 -0
  251. package/src/projected-process-task-notices.tsx +501 -0
  252. package/src/projected-prompt-child-view-renderer.tsx +698 -0
  253. package/src/projected-prompt-document-preview.tsx +197 -0
  254. package/src/projected-prompt-view.tsx +592 -0
  255. package/src/projected-query-form.tsx +286 -0
  256. package/src/projected-record-details.tsx +133 -0
  257. package/src/projected-routed-surface-runtime.tsx +713 -0
  258. package/src/projected-tabs-view.tsx +308 -0
  259. package/src/projected-view-chrome.tsx +148 -0
  260. package/src/projected-view-surface.tsx +131 -0
  261. package/src/standard-collection-chrome-slot-renderers.tsx +391 -0
  262. package/src/standard-view-chrome-slot-renderers.tsx +1064 -0
@@ -0,0 +1,698 @@
1
+ import type { ReactNode } from 'react'
2
+
3
+ import {
4
+ createPresentationEnumDiscriminator,
5
+ createPresentationProjectionDiagnostic,
6
+ defaultPresentationComponentSet,
7
+ findPresentationView,
8
+ getPresentationViewSemanticRole,
9
+ resolvePresentationComponentBinding,
10
+ type PresentationBindingDefinition,
11
+ type PresentationModuleDefinition,
12
+ type PresentationProjectionDiagnostic,
13
+ type PresentationDataSourceResolver,
14
+ type ViewDefinition,
15
+ } from '@cohesivesystems/presentation-core'
16
+ import type {
17
+ PresentationShadcnComponentSystem as PresentationComponentSystem,
18
+ } from './presentation-shadcn-component-system'
19
+ import type {
20
+ PresentationDesignSystem,
21
+ } from '@cohesivesystems/presentation-tailwind'
22
+ import { ProjectedStatusBlock } from './projected-activity-state'
23
+ import {
24
+ presentationBindingKinds,
25
+ presentationTargetKinds,
26
+ type ViewKind,
27
+ viewKindLabels,
28
+ } from '@cohesivesystems/presentation-contracts'
29
+
30
+ export interface ProjectedPromptChildViewRenderContext<TContext> {
31
+ readonly componentKey: string | null
32
+ readonly componentRole: string | null
33
+ readonly componentSystem: PresentationComponentSystem
34
+ readonly context: TContext
35
+ readonly dataSourceResolver: PresentationDataSourceResolver
36
+ readonly designSystem: PresentationDesignSystem
37
+ readonly module: PresentationModuleDefinition
38
+ readonly promptView: ViewDefinition
39
+ readonly renderView: (viewId: string) => ReactNode
40
+ readonly resolutionSource: ProjectedPromptChildViewRendererResolutionSource | null
41
+ readonly view: ViewDefinition
42
+ readonly viewId: string
43
+ }
44
+
45
+ /**
46
+ * Renders one child view declared inside a prompt region. Returning undefined
47
+ * lets a later fallback renderer handle the view.
48
+ */
49
+ export type ProjectedPromptChildViewRenderer<TContext> = (
50
+ context: ProjectedPromptChildViewRenderContext<TContext>,
51
+ ) => ReactNode | undefined
52
+
53
+ /**
54
+ * Semantic roles that prompt child views can expose through view contracts.
55
+ * These roles are target-independent; frontend registries attach local React
56
+ * interpretations to them.
57
+ */
58
+ export const promptChildViewSemanticRoles = {
59
+ jsonDocumentDiff: 'json-document-diff',
60
+ promptDocumentPreview: 'prompt-document-preview',
61
+ } as const
62
+
63
+ /**
64
+ * Prompt-scoped renderer registry. Resolution prefers semantic roles and view
65
+ * kinds before component-key and view-id escape hatches.
66
+ */
67
+ export interface ProjectedPromptChildViewRendererRegistry<TContext> {
68
+ readonly byComponentRole?: Readonly<Record<string, ProjectedPromptChildViewRenderer<TContext>>>
69
+ readonly byComponentKey?: Readonly<Record<string, ProjectedPromptChildViewRenderer<TContext>>>
70
+ readonly bySemanticRole?: Readonly<Record<string, ProjectedPromptChildViewRenderer<TContext>>>
71
+ readonly byViewId?: Readonly<Record<string, ProjectedPromptChildViewRenderer<TContext>>>
72
+ readonly byViewKind?: Readonly<Record<string, ProjectedPromptChildViewRenderer<TContext>>>
73
+ readonly fallback?: ProjectedPromptChildViewRenderer<TContext>
74
+ }
75
+
76
+ export interface ProjectedPromptUnknownChildViewRenderContext<TContext> {
77
+ readonly componentKey: string | null
78
+ readonly componentRole: string | null
79
+ readonly context: TContext
80
+ readonly dataSourceResolver: PresentationDataSourceResolver
81
+ readonly module: PresentationModuleDefinition
82
+ readonly promptView: ViewDefinition
83
+ readonly reason: 'missing-renderer' | 'missing-view'
84
+ readonly resolutionSource: ProjectedPromptChildViewRendererResolutionSource | null
85
+ readonly semanticRole: string | null
86
+ readonly view: ViewDefinition | null
87
+ readonly viewId: string
88
+ }
89
+
90
+ export type ProjectedPromptUnknownChildViewRenderer<TContext> = (
91
+ context: ProjectedPromptUnknownChildViewRenderContext<TContext>,
92
+ ) => ReactNode
93
+
94
+ /**
95
+ * Builds a recursive child-view renderer for projected prompt bodies. Flow
96
+ * hosts can supply a small registry for form views, preview views, or richer
97
+ * document panels while ProjectedPromptView keeps owning region traversal.
98
+ */
99
+ export interface CreateProjectedPromptChildViewRendererOptions<TContext> {
100
+ readonly componentSet?: string
101
+ readonly componentSystem: PresentationComponentSystem
102
+ readonly context: TContext
103
+ readonly dataSourceResolver: PresentationDataSourceResolver
104
+ readonly designSystem: PresentationDesignSystem
105
+ readonly module: PresentationModuleDefinition
106
+ readonly promptView: ViewDefinition
107
+ readonly registry: ProjectedPromptChildViewRendererRegistry<TContext>
108
+ readonly renderUnknownView?: ProjectedPromptUnknownChildViewRenderer<TContext>
109
+ }
110
+
111
+ export type ProjectedPromptChildViewRendererResolutionSource =
112
+ | 'component-key'
113
+ | 'component-role'
114
+ | 'fallback'
115
+ | 'semantic-role'
116
+ | 'view-id'
117
+ | 'view-kind'
118
+
119
+ export interface ProjectedPromptChildViewRendererResolution<TContext> {
120
+ readonly componentKey: string | null
121
+ readonly componentRole: string | null
122
+ readonly renderer: ProjectedPromptChildViewRenderer<TContext> | null
123
+ readonly resolutionSource: ProjectedPromptChildViewRendererResolutionSource | null
124
+ readonly semanticRole: string
125
+ readonly targetBinding: PresentationBindingDefinition | null
126
+ }
127
+
128
+ export interface ProjectPromptChildViewRendererDiagnosticsOptions<TContext> {
129
+ readonly componentSet?: string
130
+ readonly module: PresentationModuleDefinition
131
+ readonly promptView: ViewDefinition
132
+ readonly registry: ProjectedPromptChildViewRendererRegistry<TContext>
133
+ readonly sourceId?: string
134
+ }
135
+
136
+ export function createProjectedPromptChildViewRenderer<TContext>({
137
+ componentSet = defaultPresentationComponentSet,
138
+ componentSystem,
139
+ context,
140
+ dataSourceResolver,
141
+ designSystem,
142
+ module,
143
+ promptView,
144
+ registry,
145
+ renderUnknownView = renderDefaultUnknownPromptChildView,
146
+ }: CreateProjectedPromptChildViewRendererOptions<TContext>) {
147
+ const renderView = (viewId: string): ReactNode => {
148
+ const view = findPresentationView<ViewDefinition>(module, viewId)
149
+ if (!view) {
150
+ return renderUnknownView({
151
+ componentKey: null,
152
+ componentRole: null,
153
+ context,
154
+ dataSourceResolver,
155
+ module,
156
+ promptView,
157
+ reason: 'missing-view',
158
+ resolutionSource: null,
159
+ semanticRole: null,
160
+ view: null,
161
+ viewId,
162
+ })
163
+ }
164
+
165
+ const { componentKey, componentRole, renderer, resolutionSource, semanticRole } = resolvePromptChildViewRenderer({
166
+ componentSet,
167
+ module,
168
+ registry,
169
+ view,
170
+ })
171
+ if (!renderer) {
172
+ return renderUnknownView({
173
+ componentKey,
174
+ componentRole,
175
+ context,
176
+ dataSourceResolver,
177
+ module,
178
+ promptView,
179
+ reason: 'missing-renderer',
180
+ resolutionSource,
181
+ semanticRole,
182
+ view,
183
+ viewId,
184
+ })
185
+ }
186
+
187
+ return renderer({
188
+ componentKey,
189
+ componentRole,
190
+ componentSystem,
191
+ context,
192
+ dataSourceResolver,
193
+ designSystem,
194
+ module,
195
+ promptView,
196
+ renderView,
197
+ resolutionSource,
198
+ view,
199
+ viewId,
200
+ })
201
+ }
202
+
203
+ return renderView
204
+ }
205
+
206
+ export function mergeProjectedPromptChildViewRendererRegistries<TContext>(
207
+ ...registries: readonly ProjectedPromptChildViewRendererRegistry<TContext>[]
208
+ ): ProjectedPromptChildViewRendererRegistry<TContext> {
209
+ return {
210
+ byComponentRole: mergeRendererMaps(registries.map((registry) => registry.byComponentRole)),
211
+ byComponentKey: mergeRendererMaps(registries.map((registry) => registry.byComponentKey)),
212
+ bySemanticRole: mergeRendererMaps(registries.map((registry) => registry.bySemanticRole)),
213
+ byViewId: mergeRendererMaps(registries.map((registry) => registry.byViewId)),
214
+ byViewKind: mergeRendererMaps(registries.map((registry) => registry.byViewKind)),
215
+ fallback: [...registries].reverse().find((registry) => registry.fallback)?.fallback,
216
+ }
217
+ }
218
+
219
+ function mergeRendererMaps<TContext>(
220
+ maps: readonly (
221
+ | Readonly<Record<string, ProjectedPromptChildViewRenderer<TContext>>>
222
+ | undefined
223
+ )[],
224
+ ) {
225
+ const merged: Record<string, ProjectedPromptChildViewRenderer<TContext>> = {}
226
+ for (const map of maps) {
227
+ if (map) {
228
+ Object.assign(merged, map)
229
+ }
230
+ }
231
+
232
+ return Object.keys(merged).length > 0 ? merged : undefined
233
+ }
234
+
235
+ export function resolvePromptChildViewRenderer<TContext>({
236
+ componentSet,
237
+ module,
238
+ registry,
239
+ view,
240
+ }: {
241
+ readonly componentSet: string
242
+ readonly module: PresentationModuleDefinition
243
+ readonly registry: ProjectedPromptChildViewRendererRegistry<TContext>
244
+ readonly view: ViewDefinition
245
+ }): ProjectedPromptChildViewRendererResolution<TContext> {
246
+ const componentBinding = resolvePromptChildViewComponentBinding({
247
+ componentSet,
248
+ module,
249
+ view,
250
+ })
251
+ const componentKey = componentBinding.componentKey
252
+ const componentRole = componentBinding.componentRole
253
+ const semanticRole = getPromptChildViewSemanticRole(view)
254
+ const semanticRoleRenderer = registry.bySemanticRole?.[semanticRole]
255
+ if (semanticRoleRenderer) {
256
+ return {
257
+ componentKey,
258
+ componentRole,
259
+ renderer: semanticRoleRenderer,
260
+ resolutionSource: 'semantic-role',
261
+ semanticRole,
262
+ targetBinding: componentBinding.binding,
263
+ }
264
+ }
265
+
266
+ const viewKindRenderer = findViewKindRenderer(registry, view)
267
+ if (viewKindRenderer) {
268
+ return {
269
+ componentKey,
270
+ componentRole,
271
+ renderer: viewKindRenderer,
272
+ resolutionSource: 'view-kind',
273
+ semanticRole,
274
+ targetBinding: componentBinding.binding,
275
+ }
276
+ }
277
+
278
+ const componentRoleRenderer = componentRole
279
+ ? registry.byComponentRole?.[componentRole]
280
+ : undefined
281
+ if (componentRoleRenderer) {
282
+ return {
283
+ componentKey,
284
+ componentRole,
285
+ renderer: componentRoleRenderer,
286
+ resolutionSource: 'component-role',
287
+ semanticRole,
288
+ targetBinding: componentBinding.binding,
289
+ }
290
+ }
291
+
292
+ const componentRenderer = componentKey
293
+ ? registry.byComponentKey?.[componentKey]
294
+ : undefined
295
+ if (componentRenderer) {
296
+ return {
297
+ componentKey,
298
+ componentRole,
299
+ renderer: componentRenderer,
300
+ resolutionSource: 'component-key',
301
+ semanticRole,
302
+ targetBinding: componentBinding.binding,
303
+ }
304
+ }
305
+
306
+ const viewIdRenderer = registry.byViewId?.[view.Id]
307
+ if (viewIdRenderer) {
308
+ return {
309
+ componentKey,
310
+ componentRole,
311
+ renderer: viewIdRenderer,
312
+ resolutionSource: 'view-id',
313
+ semanticRole,
314
+ targetBinding: componentBinding.binding,
315
+ }
316
+ }
317
+
318
+ if (registry.fallback) {
319
+ return {
320
+ componentKey,
321
+ componentRole,
322
+ renderer: registry.fallback,
323
+ resolutionSource: 'fallback',
324
+ semanticRole,
325
+ targetBinding: componentBinding.binding,
326
+ }
327
+ }
328
+
329
+ return {
330
+ componentKey,
331
+ componentRole,
332
+ renderer: null,
333
+ resolutionSource: null,
334
+ semanticRole,
335
+ targetBinding: componentBinding.binding,
336
+ }
337
+ }
338
+
339
+ function resolvePromptChildViewComponentBinding({
340
+ componentSet,
341
+ module,
342
+ view,
343
+ }: {
344
+ readonly componentSet: string
345
+ readonly module: PresentationModuleDefinition
346
+ readonly view: ViewDefinition
347
+ }) {
348
+ return resolvePresentationComponentBinding(module, {
349
+ bindingKind: createPresentationEnumDiscriminator(
350
+ presentationBindingKinds,
351
+ 'viewComponent',
352
+ 'ViewComponent',
353
+ ),
354
+ componentSet,
355
+ id: view.Id,
356
+ targetKind: createPresentationEnumDiscriminator(
357
+ presentationTargetKinds,
358
+ 'react',
359
+ 'React',
360
+ ),
361
+ })
362
+ }
363
+
364
+ export function projectPromptChildViewRendererDiagnostics<TContext>({
365
+ componentSet = defaultPresentationComponentSet,
366
+ module,
367
+ promptView,
368
+ registry,
369
+ sourceId = `prompt-child-view-renderers.${promptView.Id}`,
370
+ }: ProjectPromptChildViewRendererDiagnosticsOptions<TContext>): readonly PresentationProjectionDiagnostic[] {
371
+ return promptView.Regions.flatMap((region) =>
372
+ region.ViewIds.flatMap((viewId) => {
373
+ const view = findPresentationView<ViewDefinition>(module, viewId)
374
+ if (!view) {
375
+ return [
376
+ createPresentationProjectionDiagnostic({
377
+ category: 'missing-definition',
378
+ details: {
379
+ promptViewId: promptView.Id,
380
+ regionId: region.Id,
381
+ viewId,
382
+ },
383
+ id: `prompt-child-view.${promptView.Id}.${viewId}.missing-view`,
384
+ interpretation: {
385
+ status: 'unbound',
386
+ target: 'prompt-child-view-renderer',
387
+ },
388
+ message:
389
+ `Prompt '${promptView.Name}' references child view '${viewId}', ` +
390
+ 'but that view is not present in the presentation module.',
391
+ severity: 'warning',
392
+ source: sourceId,
393
+ subject: {
394
+ id: viewId,
395
+ kind: 'prompt-child-view',
396
+ },
397
+ }),
398
+ ]
399
+ }
400
+
401
+ const resolution = resolvePromptChildViewRenderer({
402
+ componentSet,
403
+ module,
404
+ registry,
405
+ view,
406
+ })
407
+ const diagnostics: PresentationProjectionDiagnostic[] = []
408
+ const componentRoleBound = resolution.componentRole
409
+ ? Boolean(registry.byComponentRole?.[resolution.componentRole])
410
+ : false
411
+
412
+ if (!resolution.targetBinding) {
413
+ diagnostics.push(
414
+ createPresentationProjectionDiagnostic({
415
+ category: 'missing-binding',
416
+ details: {
417
+ promptViewId: promptView.Id,
418
+ regionId: region.Id,
419
+ semanticRole: resolution.semanticRole,
420
+ viewId,
421
+ viewKind: view.Kind,
422
+ },
423
+ id: `prompt-child-view.${promptView.Id}.${viewId}.missing-target-binding`,
424
+ interpretation: {
425
+ status: 'unbound',
426
+ target: 'prompt-child-view-component-role',
427
+ },
428
+ message:
429
+ `Prompt child view '${view.Name}' has no ViewComponent target ` +
430
+ 'binding for the active frontend target.',
431
+ severity: 'warning',
432
+ source: sourceId,
433
+ subject: {
434
+ id: view.Id,
435
+ kind: 'prompt-child-view',
436
+ name: view.Name,
437
+ },
438
+ suggestedNextStep:
439
+ 'Declare a ViewComponent target binding with ComponentRole for this prompt child view.',
440
+ }),
441
+ )
442
+ }
443
+
444
+ if (resolution.componentKey) {
445
+ diagnostics.push(
446
+ createPresentationProjectionDiagnostic({
447
+ category: 'escape-hatch',
448
+ details: createPromptChildViewDiagnosticDetails({
449
+ promptViewId: promptView.Id,
450
+ regionId: region.Id,
451
+ resolution,
452
+ view,
453
+ viewId,
454
+ }),
455
+ id: `prompt-child-view.${promptView.Id}.${viewId}.component-key-escape-hatch`,
456
+ interpretation: {
457
+ status: 'escape-hatch',
458
+ target: 'prompt-child-view-component-key',
459
+ },
460
+ message:
461
+ `Prompt child view '${view.Name}' declares concrete component ` +
462
+ `key '${resolution.componentKey}'.`,
463
+ severity: 'warning',
464
+ source: sourceId,
465
+ subject: {
466
+ id: view.Id,
467
+ kind: 'prompt-child-view',
468
+ name: view.Name,
469
+ },
470
+ suggestedNextStep:
471
+ 'Prefer ViewComponent ComponentRole for prompt child views and reserve ComponentKey for adapter-specific overrides.',
472
+ }),
473
+ )
474
+ }
475
+
476
+ if (resolution.targetBinding && !resolution.componentRole) {
477
+ diagnostics.push(
478
+ createPresentationProjectionDiagnostic({
479
+ category: 'missing-binding',
480
+ details: createPromptChildViewDiagnosticDetails({
481
+ promptViewId: promptView.Id,
482
+ regionId: region.Id,
483
+ resolution,
484
+ view,
485
+ viewId,
486
+ }),
487
+ id: `prompt-child-view.${promptView.Id}.${viewId}.missing-component-role`,
488
+ interpretation: {
489
+ status: 'unbound',
490
+ target: 'prompt-child-view-component-role',
491
+ },
492
+ message:
493
+ `Prompt child view '${view.Name}' ViewComponent target binding ` +
494
+ 'does not declare a component role.',
495
+ severity: 'warning',
496
+ source: sourceId,
497
+ subject: {
498
+ id: view.Id,
499
+ kind: 'prompt-child-view',
500
+ name: view.Name,
501
+ },
502
+ suggestedNextStep:
503
+ 'Set ComponentRole on the prompt child ViewComponent target binding.',
504
+ }),
505
+ )
506
+ }
507
+
508
+ if (resolution.componentRole) {
509
+ diagnostics.push(
510
+ createPresentationProjectionDiagnostic({
511
+ category: componentRoleBound ? 'local-interpretation' : 'missing-binding',
512
+ details: {
513
+ ...createPromptChildViewDiagnosticDetails({
514
+ promptViewId: promptView.Id,
515
+ regionId: region.Id,
516
+ resolution,
517
+ view,
518
+ viewId,
519
+ }),
520
+ componentRoleBound,
521
+ },
522
+ id: `prompt-child-view.${promptView.Id}.${viewId}.component-role-coverage`,
523
+ interpretation: {
524
+ status: componentRoleBound ? 'locally-interpreted' : 'unbound',
525
+ target: 'prompt-child-view-component-role',
526
+ },
527
+ message: componentRoleBound
528
+ ? `Prompt child view '${view.Name}' component role ` +
529
+ `'${resolution.componentRole}' is interpreted by the local prompt child renderer registry.`
530
+ : `Prompt child view '${view.Name}' component role ` +
531
+ `'${resolution.componentRole}' is not interpreted by the local prompt child renderer registry.`,
532
+ severity: componentRoleBound ? 'info' : 'warning',
533
+ source: sourceId,
534
+ subject: {
535
+ id: view.Id,
536
+ kind: 'prompt-child-view',
537
+ name: view.Name,
538
+ },
539
+ suggestedNextStep: componentRoleBound
540
+ ? undefined
541
+ : `Bind prompt child component role '${resolution.componentRole}' in the frontend registry.`,
542
+ }),
543
+ )
544
+ }
545
+
546
+ if (!resolution.renderer) {
547
+ diagnostics.push(
548
+ createPresentationProjectionDiagnostic({
549
+ category: 'missing-binding',
550
+ details: createPromptChildViewDiagnosticDetails({
551
+ promptViewId: promptView.Id,
552
+ regionId: region.Id,
553
+ resolution,
554
+ view,
555
+ viewId,
556
+ }),
557
+ id: `prompt-child-view.${promptView.Id}.${viewId}.missing-renderer`,
558
+ interpretation: {
559
+ status: 'unbound',
560
+ target: 'prompt-child-view-renderer',
561
+ },
562
+ message:
563
+ `Prompt child view '${view.Name}' has no frontend renderer binding.`,
564
+ severity: 'warning',
565
+ source: sourceId,
566
+ subject: {
567
+ id: view.Id,
568
+ kind: 'prompt-child-view',
569
+ name: view.Name,
570
+ },
571
+ suggestedNextStep:
572
+ 'Declare a semantic prompt child-view role or bind a standard view-kind renderer.',
573
+ }),
574
+ )
575
+ }
576
+
577
+ if (
578
+ resolution.renderer &&
579
+ resolution.resolutionSource === 'view-id'
580
+ ) {
581
+ diagnostics.push(
582
+ createPresentationProjectionDiagnostic({
583
+ category: 'escape-hatch',
584
+ details: createPromptChildViewDiagnosticDetails({
585
+ promptViewId: promptView.Id,
586
+ regionId: region.Id,
587
+ resolution,
588
+ view,
589
+ viewId,
590
+ }),
591
+ id: `prompt-child-view.${promptView.Id}.${viewId}.view-id-escape-hatch`,
592
+ interpretation: {
593
+ status: 'escape-hatch',
594
+ target: 'prompt-child-view-renderer',
595
+ },
596
+ message:
597
+ `Prompt child view '${view.Name}' rendered through ` +
598
+ 'view-id as an escape hatch.',
599
+ severity: 'warning',
600
+ source: sourceId,
601
+ subject: {
602
+ id: view.Id,
603
+ kind: 'prompt-child-view',
604
+ name: view.Name,
605
+ },
606
+ suggestedNextStep:
607
+ 'Move this prompt child view onto semantic-role, component-role, or view-kind renderer resolution.',
608
+ }),
609
+ )
610
+ }
611
+
612
+ return diagnostics
613
+ }))
614
+ }
615
+
616
+ function createPromptChildViewDiagnosticDetails<TContext>({
617
+ promptViewId,
618
+ regionId,
619
+ resolution,
620
+ view,
621
+ viewId,
622
+ }: {
623
+ readonly promptViewId: string
624
+ readonly regionId: string
625
+ readonly resolution: ProjectedPromptChildViewRendererResolution<TContext>
626
+ readonly view: ViewDefinition
627
+ readonly viewId: string
628
+ }) {
629
+ return {
630
+ componentKey: resolution.componentKey,
631
+ componentRole: resolution.componentRole,
632
+ hasTargetBinding: Boolean(resolution.targetBinding),
633
+ promptViewId,
634
+ regionId,
635
+ resolutionSource: resolution.resolutionSource,
636
+ semanticRole: resolution.semanticRole,
637
+ viewId,
638
+ viewKind: view.Kind,
639
+ }
640
+ }
641
+
642
+ export function getPromptChildViewSemanticRole(view: ViewDefinition) {
643
+ if (view.PromptDocumentPreview) {
644
+ return promptChildViewSemanticRoles.promptDocumentPreview
645
+ }
646
+
647
+ const designRole = view.Design?.Role
648
+ if (designRole === 'diff' && view.Design?.Variant === 'json-document') {
649
+ return promptChildViewSemanticRoles.jsonDocumentDiff
650
+ }
651
+
652
+ return designRole ?? getPresentationViewSemanticRole(view)
653
+ }
654
+
655
+ function findViewKindRenderer<TContext>(
656
+ registry: ProjectedPromptChildViewRendererRegistry<TContext>,
657
+ view: ViewDefinition,
658
+ ) {
659
+ for (const key of getViewKindKeys(view.Kind)) {
660
+ const renderer = registry.byViewKind?.[key]
661
+ if (renderer) {
662
+ return renderer
663
+ }
664
+ }
665
+
666
+ return undefined
667
+ }
668
+
669
+ function getViewKindKeys(kind: ViewDefinition['Kind']) {
670
+ const keys = [String(kind)]
671
+ const label = viewKindLabels[kind as ViewKind]
672
+ if (label) {
673
+ keys.push(label)
674
+ keys.push(label.charAt(0).toLowerCase() + label.slice(1))
675
+ }
676
+
677
+ return keys
678
+ }
679
+
680
+ function renderDefaultUnknownPromptChildView<TContext>({
681
+ componentKey,
682
+ componentRole,
683
+ reason,
684
+ resolutionSource,
685
+ semanticRole,
686
+ view,
687
+ viewId,
688
+ }: ProjectedPromptUnknownChildViewRenderContext<TContext>) {
689
+ if (reason === 'missing-view') {
690
+ return <ProjectedStatusBlock label={`Prompt child view '${viewId}' is not available.`} />
691
+ }
692
+
693
+ return (
694
+ <ProjectedStatusBlock
695
+ label={`Prompt child view '${view?.Name ?? viewId}' has no renderer for component role '${componentRole ?? 'none'}', component key '${componentKey ?? 'none'}', role '${semanticRole ?? 'unknown'}', and source '${resolutionSource ?? 'none'}'.`}
696
+ />
697
+ )
698
+ }