@flamingo-stack/openframe-frontend-core 0.0.489 → 0.0.490-1506.3944.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 (280) hide show
  1. package/dist/chat-protocol/decode.d.ts +58 -0
  2. package/dist/chat-protocol/decode.d.ts.map +1 -0
  3. package/dist/chat-protocol/encode.d.ts +44 -0
  4. package/dist/chat-protocol/encode.d.ts.map +1 -0
  5. package/dist/chat-protocol/env-flag.d.ts +35 -0
  6. package/dist/chat-protocol/env-flag.d.ts.map +1 -0
  7. package/dist/chat-protocol/events.d.ts +196 -0
  8. package/dist/chat-protocol/events.d.ts.map +1 -0
  9. package/dist/chat-protocol/frames.d.ts +213 -0
  10. package/dist/chat-protocol/frames.d.ts.map +1 -0
  11. package/dist/chat-protocol/index.cjs +494 -0
  12. package/dist/chat-protocol/index.cjs.map +1 -0
  13. package/dist/chat-protocol/index.d.ts +18 -0
  14. package/dist/chat-protocol/index.d.ts.map +1 -0
  15. package/dist/chat-protocol/index.js +478 -0
  16. package/dist/chat-protocol/index.js.map +1 -0
  17. package/dist/chat-protocol/ip-normalize.d.ts +44 -0
  18. package/dist/chat-protocol/ip-normalize.d.ts.map +1 -0
  19. package/dist/chat-protocol/nats-decoder.d.ts +26 -0
  20. package/dist/chat-protocol/nats-decoder.d.ts.map +1 -0
  21. package/dist/{chunk-K7MNWYYI.js → chunk-4NWARV5I.js} +2 -2
  22. package/dist/{chunk-2RNJYJWO.cjs → chunk-5CJR2GZ4.cjs} +31 -31
  23. package/dist/{chunk-2RNJYJWO.cjs.map → chunk-5CJR2GZ4.cjs.map} +1 -1
  24. package/dist/{chunk-H3YRJ3LZ.cjs → chunk-5EYRXSY5.cjs} +9 -9
  25. package/dist/{chunk-H3YRJ3LZ.cjs.map → chunk-5EYRXSY5.cjs.map} +1 -1
  26. package/dist/{chunk-IN4IO7BL.cjs → chunk-5LMGFI4J.cjs} +6930 -4755
  27. package/dist/chunk-5LMGFI4J.cjs.map +1 -0
  28. package/dist/{chunk-YMJZOANX.js → chunk-BE6DK7QY.js} +12228 -10053
  29. package/dist/chunk-BE6DK7QY.js.map +1 -0
  30. package/dist/{chunk-TWGYBXYV.js → chunk-CORIBKHG.js} +2 -2
  31. package/dist/{chunk-RO7Q56ZK.cjs → chunk-CSYSYJCF.cjs} +37 -37
  32. package/dist/{chunk-RO7Q56ZK.cjs.map → chunk-CSYSYJCF.cjs.map} +1 -1
  33. package/dist/{chunk-Z7Y63IFU.cjs → chunk-DSDZ5T4P.cjs} +5 -5
  34. package/dist/{chunk-Z7Y63IFU.cjs.map → chunk-DSDZ5T4P.cjs.map} +1 -1
  35. package/dist/{chunk-EU6QNO4S.js → chunk-GTWO5NAY.js} +2 -2
  36. package/dist/{chunk-BGWDDB7Y.js → chunk-HSACATCD.js} +2 -2
  37. package/dist/{chunk-3OIB763B.cjs → chunk-NWX7MMF5.cjs} +15 -15
  38. package/dist/{chunk-3OIB763B.cjs.map → chunk-NWX7MMF5.cjs.map} +1 -1
  39. package/dist/{chunk-J7H32E3R.cjs → chunk-P4WTZU6L.cjs} +11 -11
  40. package/dist/{chunk-J7H32E3R.cjs.map → chunk-P4WTZU6L.cjs.map} +1 -1
  41. package/dist/{chunk-VLOE7MI2.cjs → chunk-Q6E7VJ4W.cjs} +28 -27
  42. package/dist/chunk-Q6E7VJ4W.cjs.map +1 -0
  43. package/dist/{chunk-ZIAS5NNL.cjs → chunk-QSCHCZL3.cjs} +7 -7
  44. package/dist/{chunk-ZIAS5NNL.cjs.map → chunk-QSCHCZL3.cjs.map} +1 -1
  45. package/dist/{chunk-VL4LUO32.js → chunk-RQLBHKXN.js} +2 -2
  46. package/dist/{chunk-5YMY4BAW.cjs → chunk-S2NHJDKQ.cjs} +62 -62
  47. package/dist/{chunk-5YMY4BAW.cjs.map → chunk-S2NHJDKQ.cjs.map} +1 -1
  48. package/dist/{chunk-N4MTNTSX.js → chunk-T2EGSZFN.js} +6 -5
  49. package/dist/chunk-T2EGSZFN.js.map +1 -0
  50. package/dist/{chunk-W6ZUOWSB.js → chunk-TKN5667N.js} +10 -10
  51. package/dist/chunk-TKN5667N.js.map +1 -0
  52. package/dist/{chunk-B4YR342L.js → chunk-UUYRJPGJ.js} +4 -4
  53. package/dist/{chunk-FKPXFTZT.js → chunk-VHG6AX5V.js} +2 -2
  54. package/dist/{chunk-2IHN7NNB.cjs → chunk-VQ523ORK.cjs} +26 -26
  55. package/dist/{chunk-2IHN7NNB.cjs.map → chunk-VQ523ORK.cjs.map} +1 -1
  56. package/dist/{chunk-X2YF5TJS.js → chunk-XQ2B74SI.js} +2 -2
  57. package/dist/{chunk-LLEDO4P7.cjs → chunk-YHOIAA2E.cjs} +60 -60
  58. package/dist/chunk-YHOIAA2E.cjs.map +1 -0
  59. package/dist/{chunk-5VSEMWWE.js → chunk-YZ2OIYQ3.js} +4 -4
  60. package/dist/components/case-studies/index.cjs +8 -8
  61. package/dist/components/case-studies/index.js +2 -2
  62. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  63. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  64. package/dist/components/chat/hooks/index.d.ts +0 -1
  65. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  66. package/dist/components/chat/hooks/use-chat.d.ts.map +1 -1
  67. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +15 -48
  68. package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
  69. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +10 -57
  70. package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
  71. package/dist/components/chat/index.cjs +10 -2
  72. package/dist/components/chat/index.cjs.map +1 -1
  73. package/dist/components/chat/index.d.ts +1 -0
  74. package/dist/components/chat/index.d.ts.map +1 -1
  75. package/dist/components/chat/index.js +21 -13
  76. package/dist/components/chat/stream/chat-dialog-store.d.ts +184 -0
  77. package/dist/components/chat/stream/chat-dialog-store.d.ts.map +1 -0
  78. package/dist/components/chat/stream/chat-stream-reducer.d.ts +367 -0
  79. package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +1 -0
  80. package/dist/components/chat/stream/delta-batcher.d.ts +51 -0
  81. package/dist/components/chat/stream/delta-batcher.d.ts.map +1 -0
  82. package/dist/components/chat/stream/index.d.ts +17 -0
  83. package/dist/components/chat/stream/index.d.ts.map +1 -0
  84. package/dist/components/chat/stream/message-mutations.d.ts +77 -0
  85. package/dist/components/chat/stream/message-mutations.d.ts.map +1 -0
  86. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts +22 -0
  87. package/dist/components/chat/stream/use-chat-stream-reducer.d.ts.map +1 -0
  88. package/dist/components/chat/types/api.types.d.ts +1 -81
  89. package/dist/components/chat/types/api.types.d.ts.map +1 -1
  90. package/dist/components/chat/types/processing.types.d.ts +2 -90
  91. package/dist/components/chat/types/processing.types.d.ts.map +1 -1
  92. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts +34 -6
  93. package/dist/components/chat/utils/extract-incomplete-message-state.d.ts.map +1 -1
  94. package/dist/components/chat/utils/index.d.ts +2 -3
  95. package/dist/components/chat/utils/index.d.ts.map +1 -1
  96. package/dist/components/chat/utils/process-historical-messages.d.ts +59 -11
  97. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  98. package/dist/components/contact/index.cjs +3 -3
  99. package/dist/components/contact/index.js +2 -2
  100. package/dist/components/docs/index.cjs +5 -5
  101. package/dist/components/docs/index.js +4 -4
  102. package/dist/components/embeds/index.cjs +3 -3
  103. package/dist/components/embeds/index.js +2 -2
  104. package/dist/components/faq/index.cjs +3 -3
  105. package/dist/components/faq/index.js +2 -2
  106. package/dist/components/features/index.cjs +2 -2
  107. package/dist/components/features/index.js +1 -1
  108. package/dist/components/help-center-pages/index.cjs +20 -20
  109. package/dist/components/help-center-pages/index.js +11 -11
  110. package/dist/components/index.cjs +172 -130
  111. package/dist/components/index.cjs.map +1 -1
  112. package/dist/components/index.js +63 -21
  113. package/dist/components/index.js.map +1 -1
  114. package/dist/components/navigation/index.cjs +2 -2
  115. package/dist/components/navigation/index.js +1 -1
  116. package/dist/components/onboarding-guides/index.cjs +5 -5
  117. package/dist/components/onboarding-guides/index.js +4 -4
  118. package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
  119. package/dist/components/related-content/index.cjs +3 -3
  120. package/dist/components/related-content/index.js +2 -2
  121. package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
  122. package/dist/components/tickets/index.cjs +5 -5
  123. package/dist/components/tickets/index.js +4 -4
  124. package/dist/components/ui/index.cjs +44 -2
  125. package/dist/components/ui/index.cjs.map +1 -1
  126. package/dist/components/ui/index.d.ts +1 -2
  127. package/dist/components/ui/index.d.ts.map +1 -1
  128. package/dist/components/ui/index.js +55 -13
  129. package/dist/components/ui/markdown/base-components.d.ts +51 -0
  130. package/dist/components/ui/markdown/base-components.d.ts.map +1 -0
  131. package/dist/components/ui/markdown/engine.d.ts +99 -0
  132. package/dist/components/ui/markdown/engine.d.ts.map +1 -0
  133. package/dist/components/ui/markdown/heading-ids.d.ts +65 -0
  134. package/dist/components/ui/markdown/heading-ids.d.ts.map +1 -0
  135. package/dist/components/ui/markdown/index.d.ts +18 -0
  136. package/dist/components/ui/markdown/index.d.ts.map +1 -0
  137. package/dist/components/ui/markdown/mermaid-diagram.d.ts +79 -0
  138. package/dist/components/ui/markdown/mermaid-diagram.d.ts.map +1 -0
  139. package/dist/components/ui/markdown/rich/embed-overrides.d.ts +14 -0
  140. package/dist/components/ui/markdown/rich/embed-overrides.d.ts.map +1 -0
  141. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts +40 -0
  142. package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +1 -0
  143. package/dist/components/ui/markdown/rich/shortcodes.d.ts +8 -0
  144. package/dist/components/ui/markdown/rich/shortcodes.d.ts.map +1 -0
  145. package/dist/components/ui/markdown/sanitize.d.ts +153 -0
  146. package/dist/components/ui/markdown/sanitize.d.ts.map +1 -0
  147. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts +23 -0
  148. package/dist/components/ui/markdown/simple-markdown-renderer.d.ts.map +1 -0
  149. package/dist/components/ui/markdown/streaming.d.ts +78 -0
  150. package/dist/components/ui/markdown/streaming.d.ts.map +1 -0
  151. package/dist/components/ui/markdown/text-size.d.ts +34 -0
  152. package/dist/components/ui/markdown/text-size.d.ts.map +1 -0
  153. package/dist/index.cjs +60 -2
  154. package/dist/index.cjs.map +1 -1
  155. package/dist/index.js +71 -13
  156. package/dist/utils/index.cjs +169 -40
  157. package/dist/utils/index.cjs.map +1 -1
  158. package/dist/utils/index.d.ts +1 -0
  159. package/dist/utils/index.d.ts.map +1 -1
  160. package/dist/utils/index.js +162 -41
  161. package/dist/utils/index.js.map +1 -1
  162. package/dist/utils/markdown-fences.d.ts +42 -0
  163. package/dist/utils/markdown-fences.d.ts.map +1 -0
  164. package/dist/utils/markdown-heading-id.d.ts +85 -0
  165. package/dist/utils/markdown-heading-id.d.ts.map +1 -0
  166. package/dist/utils/markdown-section-extractor.d.ts.map +1 -1
  167. package/package.json +7 -1
  168. package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +307 -0
  169. package/src/chat-protocol/__tests__/chat-protocol.test.ts +516 -0
  170. package/src/chat-protocol/__tests__/env-flag.test.ts +52 -0
  171. package/src/chat-protocol/__tests__/ip-normalize.test.ts +136 -0
  172. package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +228 -0
  173. package/src/chat-protocol/decode.ts +278 -0
  174. package/src/chat-protocol/encode.ts +71 -0
  175. package/src/chat-protocol/env-flag.ts +39 -0
  176. package/src/chat-protocol/events.ts +232 -0
  177. package/src/chat-protocol/frames.ts +245 -0
  178. package/src/chat-protocol/index.ts +21 -0
  179. package/src/chat-protocol/ip-normalize.ts +146 -0
  180. package/src/chat-protocol/nats-decoder.ts +252 -0
  181. package/src/components/chat/__tests__/chat-message-list.test.tsx +293 -5
  182. package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +207 -0
  183. package/src/components/chat/__tests__/chat-pending-turn.test.tsx +209 -0
  184. package/src/components/chat/chat-message-enhanced.tsx +111 -17
  185. package/src/components/chat/chat-message-list.tsx +358 -109
  186. package/src/components/chat/embeddable-chat.tsx +6 -0
  187. package/src/components/chat/hooks/.index.md +30 -33
  188. package/src/components/chat/hooks/.use-nats-chat-adapter.md +36 -55
  189. package/src/components/chat/hooks/__tests__/__snapshots__/conversation-id-persistence-golden.test.ts.snap +37 -0
  190. package/src/components/chat/hooks/__tests__/__snapshots__/sse-stream-golden.test.ts.snap +0 -0
  191. package/src/components/chat/hooks/__tests__/conversation-id-persistence-golden.test.ts +438 -0
  192. package/src/components/chat/hooks/__tests__/sse-stream-golden.test.ts +318 -0
  193. package/src/components/chat/hooks/index.ts +0 -1
  194. package/src/components/chat/hooks/use-chat.ts +8 -0
  195. package/src/components/chat/hooks/use-nats-chat-adapter.ts +243 -823
  196. package/src/components/chat/hooks/use-sse-chat-adapter.ts +380 -684
  197. package/src/components/chat/index.ts +5 -0
  198. package/src/components/chat/stream/__tests__/__snapshots__/chat-stream-reducer-golden.test.ts.snap +940 -0
  199. package/src/components/chat/stream/__tests__/chat-dialog-store.test.ts +756 -0
  200. package/src/components/chat/stream/__tests__/chat-stream-reducer-golden.test.ts +460 -0
  201. package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +894 -0
  202. package/src/components/chat/stream/__tests__/delta-batcher.test.ts +255 -0
  203. package/src/components/chat/stream/__tests__/use-chat-stream-reducer.test.ts +98 -0
  204. package/src/components/chat/stream/chat-dialog-store.ts +536 -0
  205. package/src/components/chat/stream/chat-stream-reducer.ts +1796 -0
  206. package/src/components/chat/stream/delta-batcher.ts +159 -0
  207. package/src/components/chat/stream/index.ts +55 -0
  208. package/src/components/chat/stream/message-mutations.ts +338 -0
  209. package/src/components/chat/stream/use-chat-stream-reducer.ts +126 -0
  210. package/src/components/chat/thinking-display.tsx +1 -1
  211. package/src/components/chat/types/.api.types.md +39 -49
  212. package/src/components/chat/types/.processing.types.md +29 -58
  213. package/src/components/chat/types/api.types.ts +6 -73
  214. package/src/components/chat/types/processing.types.ts +11 -52
  215. package/src/components/chat/utils/.index.md +31 -40
  216. package/src/components/chat/utils/__tests__/__snapshots__/process-historical-messages-golden.test.ts.snap +420 -0
  217. package/src/components/chat/utils/__tests__/__snapshots__/segment-accumulator-golden.test.ts.snap +605 -0
  218. package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +317 -0
  219. package/src/components/chat/utils/__tests__/segment-accumulator-golden.test.ts +270 -0
  220. package/src/components/chat/utils/extract-incomplete-message-state.ts +63 -5
  221. package/src/components/chat/utils/index.ts +5 -8
  222. package/src/components/chat/utils/process-historical-messages.ts +352 -384
  223. package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +22 -4
  224. package/src/components/shared/legal-document/legal-document-page.tsx +1 -1
  225. package/src/components/shared/product-release/release-detail-page.tsx +19 -4
  226. package/src/components/ui/__tests__/__snapshots__/markdown-parity.test.tsx.snap +2420 -0
  227. package/src/components/ui/__tests__/markdown-parity.test.tsx +2528 -0
  228. package/src/components/ui/index.ts +1 -2
  229. package/src/components/ui/markdown/__tests__/mermaid-security.test.ts +115 -0
  230. package/src/components/ui/markdown/__tests__/mermaid-stale-render.test.tsx +95 -0
  231. package/src/components/ui/markdown/__tests__/sanitize-invariant.test.ts +309 -0
  232. package/src/components/ui/markdown/__tests__/streaming.test.tsx +388 -0
  233. package/src/components/ui/markdown/base-components.tsx +360 -0
  234. package/src/components/ui/markdown/engine.tsx +315 -0
  235. package/src/components/ui/markdown/heading-ids.ts +239 -0
  236. package/src/components/ui/markdown/index.ts +49 -0
  237. package/src/components/ui/markdown/mermaid-diagram.tsx +291 -0
  238. package/src/components/ui/markdown/rich/embed-overrides.tsx +199 -0
  239. package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +184 -0
  240. package/src/components/ui/markdown/rich/shortcodes.ts +170 -0
  241. package/src/components/ui/markdown/sanitize.ts +3499 -0
  242. package/src/components/ui/markdown/simple-markdown-renderer.tsx +28 -0
  243. package/src/components/ui/markdown/streaming.ts +362 -0
  244. package/src/components/ui/markdown/text-size.ts +106 -0
  245. package/src/components/ui/release-changelog-section.tsx +1 -1
  246. package/src/components/ui/ticket-info-section.tsx +1 -1
  247. package/src/utils/index.ts +1 -0
  248. package/src/utils/markdown-fences.ts +127 -0
  249. package/src/utils/markdown-heading-id.ts +348 -0
  250. package/src/utils/markdown-section-extractor.ts +41 -56
  251. package/dist/chunk-IN4IO7BL.cjs.map +0 -1
  252. package/dist/chunk-LLEDO4P7.cjs.map +0 -1
  253. package/dist/chunk-N4MTNTSX.js.map +0 -1
  254. package/dist/chunk-VLOE7MI2.cjs.map +0 -1
  255. package/dist/chunk-W6ZUOWSB.js.map +0 -1
  256. package/dist/chunk-YMJZOANX.js.map +0 -1
  257. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts +0 -6
  258. package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +0 -1
  259. package/dist/components/chat/utils/chunk-parser.d.ts +0 -25
  260. package/dist/components/chat/utils/chunk-parser.d.ts.map +0 -1
  261. package/dist/components/ui/rich-markdown-renderer.d.ts +0 -34
  262. package/dist/components/ui/rich-markdown-renderer.d.ts.map +0 -1
  263. package/dist/components/ui/simple-markdown-renderer.d.ts +0 -73
  264. package/dist/components/ui/simple-markdown-renderer.d.ts.map +0 -1
  265. package/src/components/chat/hooks/.use-realtime-chunk-processor.md +0 -77
  266. package/src/components/chat/hooks/use-realtime-chunk-processor.ts +0 -479
  267. package/src/components/chat/utils/.chunk-parser.md +0 -62
  268. package/src/components/chat/utils/chunk-parser.ts +0 -256
  269. package/src/components/ui/.simple-markdown-renderer.md +0 -52
  270. package/src/components/ui/rich-markdown-renderer.tsx +0 -1223
  271. package/src/components/ui/simple-markdown-renderer.tsx +0 -964
  272. /package/dist/{chunk-K7MNWYYI.js.map → chunk-4NWARV5I.js.map} +0 -0
  273. /package/dist/{chunk-TWGYBXYV.js.map → chunk-CORIBKHG.js.map} +0 -0
  274. /package/dist/{chunk-EU6QNO4S.js.map → chunk-GTWO5NAY.js.map} +0 -0
  275. /package/dist/{chunk-BGWDDB7Y.js.map → chunk-HSACATCD.js.map} +0 -0
  276. /package/dist/{chunk-VL4LUO32.js.map → chunk-RQLBHKXN.js.map} +0 -0
  277. /package/dist/{chunk-B4YR342L.js.map → chunk-UUYRJPGJ.js.map} +0 -0
  278. /package/dist/{chunk-FKPXFTZT.js.map → chunk-VHG6AX5V.js.map} +0 -0
  279. /package/dist/{chunk-X2YF5TJS.js.map → chunk-XQ2B74SI.js.map} +0 -0
  280. /package/dist/{chunk-5VSEMWWE.js.map → chunk-YZ2OIYQ3.js.map} +0 -0
@@ -15,7 +15,7 @@
15
15
  * renderer with extra plugins.
16
16
  */
17
17
 
18
- import { type ComponentType, type ReactNode } from 'react'
18
+ import { Fragment, type ComponentType, type ReactNode } from 'react'
19
19
  import { PageLayout } from '../layout/page-layout'
20
20
 
21
21
  import { useRouter } from '../../embed-shims'
@@ -30,7 +30,7 @@ import { VideoBitesStrip } from '../features/video-bites-strip'
30
30
  import { toStripProfile } from '../features/video-bites-shared'
31
31
  import { useVideoWarmup } from '../features/use-video-warmup'
32
32
  import { getCaptionsUrl } from '../features/captions-url'
33
- import { RichMarkdownRenderer } from '../ui/rich-markdown-renderer'
33
+ import { RichMarkdownRenderer } from '../ui/markdown'
34
34
  import { EntityTagBadges } from '../features/entity-tag-badges'
35
35
  import { LoadError } from '../ui/error-state'
36
36
  import { ArticleAuthorByline } from '../shared/article-author-byline'
@@ -244,8 +244,26 @@ export function OnboardingGuideDetailView({
244
244
  </div>
245
245
  )}
246
246
 
247
- {/* Host slot — cross-type related-content / FAQ rail. */}
248
- {relatedContent}
247
+ {/*
248
+ * Host slot — cross-type related-content / FAQ rail.
249
+ *
250
+ * KEYED DELIBERATELY. This is one member of PageLayout's static children
251
+ * array, and the only member whose element may be created in a SERVER
252
+ * component and crossed over the RSC boundary. Static JSX children are
253
+ * normally exempt from the key warning because `jsxs` runs
254
+ * `validateChildKeys` and stamps `_store.validated = 1` on each element —
255
+ * but a slot arriving over the wire is referenced as a lazy chunk wrapper,
256
+ * so validation marks the WRAPPER and the fulfilled path never copies the
257
+ * flag onto the revived element. It reaches the reconciler with
258
+ * `validated: 0, key: null` and warns, blaming PageLayout (the owner of the
259
+ * enclosing element) rather than anything actually at fault.
260
+ *
261
+ * A keyed Fragment emits no DOM, so rendered output is byte-identical.
262
+ * Do NOT "fix" this in PageLayout via `React.Children.toArray` — that would
263
+ * auto-key every consumer's children and change reconciliation identity for
264
+ * all of them, and that file carries an explicit FROZEN contract.
265
+ */}
266
+ <Fragment key="related-content">{relatedContent}</Fragment>
249
267
  </PageLayout>
250
268
  )
251
269
  }
@@ -19,7 +19,7 @@
19
19
 
20
20
  import type { ComponentType } from 'react';
21
21
  import { PageShell, PageLayout } from '../../ui';
22
- import { RichMarkdownRenderer } from '../../ui/rich-markdown-renderer';
22
+ import { RichMarkdownRenderer } from '../../ui/markdown';
23
23
  import { useRouter } from '../../../embed-shims/next-navigation';
24
24
  import { useLegalDocs, type LegalDocument } from './use-legal-docs';
25
25
  import { formatLegalDate } from '../../../utils/format';
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { useState, useEffect, ComponentType, type ReactNode } from 'react';
3
+ import { useState, useEffect, Fragment, ComponentType, type ReactNode } from 'react';
4
4
  import Link from '../../../embed-shims/next-link';
5
5
  import { useRouter } from '../../../embed-shims/next-navigation';
6
6
  import { Card, CardContent } from '../../ui/card';
@@ -11,7 +11,7 @@ import { PageShell } from '../../layout/article-detail-layout';
11
11
  import { PageLayout } from '../../layout/page-layout';
12
12
  import { FadePreview } from '../../ui/fade-preview';
13
13
  import { ReleaseChangelogSection } from '../../ui/release-changelog-section';
14
- import { RichMarkdownRenderer } from '../../ui/rich-markdown-renderer';
14
+ import { RichMarkdownRenderer } from '../../ui/markdown';
15
15
  import { EntityTagBadges } from '../../features/entity-tag-badges';
16
16
  import { EntityMetadataAuthorCell } from '../../chat/entity-cards/entity-author-card';
17
17
  import type { EntityAuthor } from '../../../types/entity-author';
@@ -582,8 +582,23 @@ export function ReleaseDetailPage({
582
582
  )}
583
583
  </div>
584
584
 
585
- {/* Host slot — end-of-article byline + related-content / FAQ rail. */}
586
- {relatedContent}
585
+ {/*
586
+ * Host slot — end-of-article byline + related-content / FAQ rail.
587
+ *
588
+ * KEYED for the same reason as `onboarding-guide-detail-view.tsx`: this is a
589
+ * member of PageLayout's static children array, and a slot element built in a
590
+ * SERVER component crosses the RSC boundary as a lazy chunk wrapper, so
591
+ * `validateChildKeys` marks the wrapper and the fulfilled path never copies
592
+ * `_store.validated` onto the revived element — it reaches the reconciler
593
+ * unvalidated and warns.
594
+ *
595
+ * Today the hub's only consumer of this view is a `'use client'` wrapper that
596
+ * builds the slot locally, so no element actually crosses the boundary and
597
+ * this is pre-emptive. It is kept because the trap is invisible from here: a
598
+ * future server-built slot would warn with no clue pointing at this line.
599
+ * A keyed Fragment emits no DOM, so output is byte-identical either way.
600
+ */}
601
+ <Fragment key="related-content">{relatedContent}</Fragment>
587
602
  </PageLayout>
588
603
  );
589
604
  }