@flamingo-stack/openframe-frontend-core 0.0.518-1663.4312.1 → 0.0.519

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 (160) hide show
  1. package/dist/chat-protocol/events.d.ts +15 -1
  2. package/dist/chat-protocol/events.d.ts.map +1 -1
  3. package/dist/chat-protocol/index.cjs +25 -0
  4. package/dist/chat-protocol/index.cjs.map +1 -1
  5. package/dist/chat-protocol/index.js +25 -1
  6. package/dist/chat-protocol/index.js.map +1 -1
  7. package/dist/chat-protocol/nats-decoder.d.ts +5 -0
  8. package/dist/chat-protocol/nats-decoder.d.ts.map +1 -1
  9. package/dist/{chunk-UBTOOE55.js → chunk-5OGHZNY5.js} +10 -1
  10. package/dist/chunk-5OGHZNY5.js.map +1 -0
  11. package/dist/{chunk-KW7GDLSG.cjs → chunk-5PMRHRMM.cjs} +14 -14
  12. package/dist/{chunk-KW7GDLSG.cjs.map → chunk-5PMRHRMM.cjs.map} +1 -1
  13. package/dist/{chunk-MKN6S7SU.cjs → chunk-6FLRFCK4.cjs} +1352 -1152
  14. package/dist/chunk-6FLRFCK4.cjs.map +1 -0
  15. package/dist/{chunk-KRBH3PI4.js → chunk-6WQN7NLD.js} +4 -4
  16. package/dist/{chunk-IIPBTWQR.cjs → chunk-7INXXQVK.cjs} +10 -1
  17. package/dist/{chunk-IIPBTWQR.cjs.map → chunk-7INXXQVK.cjs.map} +1 -1
  18. package/dist/{chunk-IVTENGMF.js → chunk-7J4DGFHZ.js} +2 -2
  19. package/dist/{chunk-WQDDSJWN.cjs → chunk-BFCBR277.cjs} +11 -11
  20. package/dist/{chunk-WQDDSJWN.cjs.map → chunk-BFCBR277.cjs.map} +1 -1
  21. package/dist/{chunk-RJU7YCN3.js → chunk-BUZOZOQ2.js} +2 -2
  22. package/dist/{chunk-URU6YKOA.cjs → chunk-CCK2MFIQ.cjs} +28 -28
  23. package/dist/{chunk-URU6YKOA.cjs.map → chunk-CCK2MFIQ.cjs.map} +1 -1
  24. package/dist/{chunk-PV3LXEHJ.js → chunk-CRJRVUWB.js} +3 -3
  25. package/dist/{chunk-O4XLTA5G.cjs → chunk-FWCENA3G.cjs} +31 -31
  26. package/dist/{chunk-O4XLTA5G.cjs.map → chunk-FWCENA3G.cjs.map} +1 -1
  27. package/dist/{chunk-RLVJISO4.cjs → chunk-GLFQSFYV.cjs} +61 -61
  28. package/dist/{chunk-RLVJISO4.cjs.map → chunk-GLFQSFYV.cjs.map} +1 -1
  29. package/dist/{chunk-P6M5MN3L.js → chunk-HVXGSQ4V.js} +6 -6
  30. package/dist/{chunk-MVY3WDFZ.js → chunk-HWA3NZPK.js} +2 -2
  31. package/dist/{chunk-TFIPJAA5.js → chunk-JMGVYERE.js} +3 -3
  32. package/dist/{chunk-25JSVBPR.cjs → chunk-KCDKQXE5.cjs} +12 -12
  33. package/dist/{chunk-25JSVBPR.cjs.map → chunk-KCDKQXE5.cjs.map} +1 -1
  34. package/dist/{chunk-YUQNJXSC.js → chunk-MEWHQVOU.js} +2 -2
  35. package/dist/{chunk-K26W23C2.cjs → chunk-MKPJYEOR.cjs} +6 -6
  36. package/dist/{chunk-K26W23C2.cjs.map → chunk-MKPJYEOR.cjs.map} +1 -1
  37. package/dist/{chunk-BQXHC336.cjs → chunk-OBJSXQ67.cjs} +3 -3
  38. package/dist/{chunk-BQXHC336.cjs.map → chunk-OBJSXQ67.cjs.map} +1 -1
  39. package/dist/{chunk-QJHBYNHI.js → chunk-OQHHJDUB.js} +4 -4
  40. package/dist/{chunk-LQ2R7IA2.cjs → chunk-QEGGWVFV.cjs} +26 -26
  41. package/dist/{chunk-LQ2R7IA2.cjs.map → chunk-QEGGWVFV.cjs.map} +1 -1
  42. package/dist/{chunk-I6IWT62M.cjs → chunk-QGLEI6T2.cjs} +5 -5
  43. package/dist/{chunk-I6IWT62M.cjs.map → chunk-QGLEI6T2.cjs.map} +1 -1
  44. package/dist/{chunk-YH627NWE.cjs → chunk-QQZWLTYU.cjs} +9 -9
  45. package/dist/{chunk-YH627NWE.cjs.map → chunk-QQZWLTYU.cjs.map} +1 -1
  46. package/dist/{chunk-NJJWY7SO.js → chunk-S4OAWVKF.js} +2 -2
  47. package/dist/{chunk-MOZUJ7IN.js → chunk-SAPKMN4W.js} +2 -2
  48. package/dist/{chunk-MI7WNVWX.js → chunk-UBT2KBK7.js} +6 -6
  49. package/dist/{chunk-DN3GKQ47.cjs → chunk-V3MAG3G5.cjs} +98 -98
  50. package/dist/{chunk-DN3GKQ47.cjs.map → chunk-V3MAG3G5.cjs.map} +1 -1
  51. package/dist/{chunk-XARCNHWZ.js → chunk-VH7BOHRG.js} +3 -3
  52. package/dist/{chunk-CHMQCXYO.cjs → chunk-WEPJKF65.cjs} +37 -37
  53. package/dist/{chunk-CHMQCXYO.cjs.map → chunk-WEPJKF65.cjs.map} +1 -1
  54. package/dist/{chunk-PUBL2NCH.js → chunk-YACGPO7I.js} +2 -2
  55. package/dist/{chunk-LL4C2NXG.js → chunk-ZA5PFNHR.js} +6073 -5873
  56. package/dist/chunk-ZA5PFNHR.js.map +1 -0
  57. package/dist/{chunk-GH5YZSQQ.cjs → chunk-ZGGI4XMF.cjs} +9 -9
  58. package/dist/{chunk-GH5YZSQQ.cjs.map → chunk-ZGGI4XMF.cjs.map} +1 -1
  59. package/dist/components/calendar.cjs +3 -3
  60. package/dist/components/calendar.js +2 -2
  61. package/dist/components/case-studies/index.cjs +9 -9
  62. package/dist/components/case-studies/index.js +3 -3
  63. package/dist/components/chat/ask-display.d.ts +24 -0
  64. package/dist/components/chat/ask-display.d.ts.map +1 -0
  65. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  66. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  67. package/dist/components/chat/hooks/use-jetstream-dialog-subscription.d.ts +1 -7
  68. package/dist/components/chat/hooks/use-jetstream-dialog-subscription.d.ts.map +1 -1
  69. package/dist/components/chat/index.cjs +3 -3
  70. package/dist/components/chat/index.cjs.map +1 -1
  71. package/dist/components/chat/index.d.ts +1 -0
  72. package/dist/components/chat/index.d.ts.map +1 -1
  73. package/dist/components/chat/index.js +4 -4
  74. package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +1 -1
  75. package/dist/components/chat/types/api.types.d.ts +4 -22
  76. package/dist/components/chat/types/api.types.d.ts.map +1 -1
  77. package/dist/components/chat/types/component.types.d.ts +25 -1
  78. package/dist/components/chat/types/component.types.d.ts.map +1 -1
  79. package/dist/components/chat/types/message.types.d.ts +32 -2
  80. package/dist/components/chat/types/message.types.d.ts.map +1 -1
  81. package/dist/components/chat/utils/message-segment-accumulator.d.ts +8 -1
  82. package/dist/components/chat/utils/message-segment-accumulator.d.ts.map +1 -1
  83. package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
  84. package/dist/components/contact/index.cjs +4 -4
  85. package/dist/components/contact/index.js +3 -3
  86. package/dist/components/docs/index.cjs +6 -6
  87. package/dist/components/docs/index.js +5 -5
  88. package/dist/components/embeds/index.cjs +4 -4
  89. package/dist/components/embeds/index.js +3 -3
  90. package/dist/components/faq/index.cjs +4 -4
  91. package/dist/components/faq/index.js +3 -3
  92. package/dist/components/features/index.cjs +3 -3
  93. package/dist/components/features/index.js +2 -2
  94. package/dist/components/help-center-pages/index.cjs +23 -23
  95. package/dist/components/help-center-pages/index.js +14 -14
  96. package/dist/components/index.cjs +150 -150
  97. package/dist/components/index.js +14 -14
  98. package/dist/components/meeting-scheduler/index.cjs +41 -41
  99. package/dist/components/meeting-scheduler/index.js +5 -5
  100. package/dist/components/navigation/index.cjs +3 -3
  101. package/dist/components/navigation/index.js +2 -2
  102. package/dist/components/onboarding-guides/index.cjs +6 -6
  103. package/dist/components/onboarding-guides/index.js +5 -5
  104. package/dist/components/related-content/index.cjs +4 -4
  105. package/dist/components/related-content/index.js +3 -3
  106. package/dist/components/tickets/index.cjs +7 -7
  107. package/dist/components/tickets/index.js +6 -6
  108. package/dist/components/ui/button/button.d.ts +1 -1
  109. package/dist/components/ui/button/button.d.ts.map +1 -1
  110. package/dist/components/ui/file-manager/index.cjs +15 -15
  111. package/dist/components/ui/file-manager/index.js +1 -1
  112. package/dist/components/ui/index.cjs +3 -3
  113. package/dist/components/ui/index.cjs.map +1 -1
  114. package/dist/components/ui/index.js +4 -4
  115. package/dist/index.cjs +3 -3
  116. package/dist/index.cjs.map +1 -1
  117. package/dist/index.js +4 -4
  118. package/dist/utils/index.cjs.map +1 -1
  119. package/dist/utils/index.js.map +1 -1
  120. package/package.json +1 -1
  121. package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +30 -0
  122. package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +23 -0
  123. package/src/chat-protocol/events.ts +20 -0
  124. package/src/chat-protocol/nats-decoder.ts +32 -0
  125. package/src/components/chat/__tests__/ask-display.test.tsx +101 -0
  126. package/src/components/chat/__tests__/chat-message-list-ask.test.tsx +100 -0
  127. package/src/components/chat/ask-display.tsx +151 -0
  128. package/src/components/chat/chat-message-enhanced.tsx +39 -2
  129. package/src/components/chat/chat-message-list.tsx +18 -1
  130. package/src/components/chat/embeddable-chat.tsx +22 -0
  131. package/src/components/chat/hooks/.use-jetstream-dialog-subscription.md +4 -11
  132. package/src/components/chat/hooks/use-jetstream-dialog-subscription.ts +6 -71
  133. package/src/components/chat/index.ts +1 -0
  134. package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +72 -0
  135. package/src/components/chat/stream/chat-stream-reducer.ts +27 -0
  136. package/src/components/chat/types/api.types.ts +4 -22
  137. package/src/components/chat/types/component.types.ts +28 -1
  138. package/src/components/chat/types/message.types.ts +35 -1
  139. package/src/components/chat/utils/__tests__/history-merge.test.ts +0 -99
  140. package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +74 -0
  141. package/src/components/chat/utils/message-segment-accumulator.ts +15 -0
  142. package/src/components/chat/utils/process-historical-messages.ts +26 -0
  143. package/src/components/ui/button/button.tsx +9 -0
  144. package/dist/chunk-LL4C2NXG.js.map +0 -1
  145. package/dist/chunk-MKN6S7SU.cjs.map +0 -1
  146. package/dist/chunk-UBTOOE55.js.map +0 -1
  147. /package/dist/{chunk-KRBH3PI4.js.map → chunk-6WQN7NLD.js.map} +0 -0
  148. /package/dist/{chunk-IVTENGMF.js.map → chunk-7J4DGFHZ.js.map} +0 -0
  149. /package/dist/{chunk-RJU7YCN3.js.map → chunk-BUZOZOQ2.js.map} +0 -0
  150. /package/dist/{chunk-PV3LXEHJ.js.map → chunk-CRJRVUWB.js.map} +0 -0
  151. /package/dist/{chunk-P6M5MN3L.js.map → chunk-HVXGSQ4V.js.map} +0 -0
  152. /package/dist/{chunk-MVY3WDFZ.js.map → chunk-HWA3NZPK.js.map} +0 -0
  153. /package/dist/{chunk-TFIPJAA5.js.map → chunk-JMGVYERE.js.map} +0 -0
  154. /package/dist/{chunk-YUQNJXSC.js.map → chunk-MEWHQVOU.js.map} +0 -0
  155. /package/dist/{chunk-QJHBYNHI.js.map → chunk-OQHHJDUB.js.map} +0 -0
  156. /package/dist/{chunk-NJJWY7SO.js.map → chunk-S4OAWVKF.js.map} +0 -0
  157. /package/dist/{chunk-MOZUJ7IN.js.map → chunk-SAPKMN4W.js.map} +0 -0
  158. /package/dist/{chunk-MI7WNVWX.js.map → chunk-UBT2KBK7.js.map} +0 -0
  159. /package/dist/{chunk-XARCNHWZ.js.map → chunk-VH7BOHRG.js.map} +0 -0
  160. /package/dist/{chunk-PUBL2NCH.js.map → chunk-YACGPO7I.js.map} +0 -0
@@ -392,3 +392,77 @@ describe('processHistoricalMessages — GUIDE rows', () => {
392
392
  expect(processHistoricalMessages(empty).messages).toEqual([])
393
393
  })
394
394
  })
395
+
396
+ // ─── ASK rows ──────────────────────────────────────────────────────────────
397
+ //
398
+ // Same contract as GUIDE above: history must replay a persisted `ASK` row into
399
+ // the SAME shape the live `ASK` chunk produces — the intro sentence as answer
400
+ // text, then the card — or a reloaded dialog loses the clarification the user
401
+ // was about to answer.
402
+
403
+ describe('processHistoricalMessages — ASK rows', () => {
404
+ const askRow = {
405
+ type: 'ASK',
406
+ text: 'Do you want the docs, or your own workspace?',
407
+ question: 'What do you want to work on?',
408
+ options: [
409
+ { label: 'Find documentation', description: 'How scripting works and how to set it up' },
410
+ { label: 'Your scripts', description: 'List, edit or run the scripts in your workspace' },
411
+ ],
412
+ }
413
+
414
+ it('replays an ASK row as intro text followed by the card', () => {
415
+ const dialog: HistoricalMessage[] = [
416
+ {
417
+ id: 'a1',
418
+ chatType: 'CLIENT_CHAT',
419
+ createdAt: '2026-07-19T09:00:05Z',
420
+ owner: { type: 'ASSISTANT' },
421
+ messageData: [askRow as any],
422
+ },
423
+ ]
424
+ expect(processHistoricalMessages(dialog).messages[0].content).toEqual([
425
+ { type: 'text', text: 'Do you want the docs, or your own workspace?' },
426
+ {
427
+ type: 'ask',
428
+ question: 'What do you want to work on?',
429
+ options: [
430
+ { label: 'Find documentation', description: 'How scripting works and how to set it up' },
431
+ { label: 'Your scripts', description: 'List, edit or run the scripts in your workspace' },
432
+ ],
433
+ },
434
+ ])
435
+ })
436
+
437
+ it('keeps consecutive ASK rows as SEPARATE segments (the card pages them)', () => {
438
+ const dialog: HistoricalMessage[] = [
439
+ {
440
+ id: 'a1',
441
+ chatType: 'CLIENT_CHAT',
442
+ createdAt: '2026-07-19T09:00:05Z',
443
+ owner: { type: 'ASSISTANT' },
444
+ messageData: [
445
+ { type: 'ASK', question: 'First?', options: [{ label: 'A' }] } as any,
446
+ { type: 'ASK', question: 'Second?', options: [{ label: 'B' }] } as any,
447
+ ],
448
+ },
449
+ ]
450
+ expect(processHistoricalMessages(dialog).messages[0].content).toEqual([
451
+ { type: 'ask', question: 'First?', options: [{ label: 'A', description: undefined }] },
452
+ { type: 'ask', question: 'Second?', options: [{ label: 'B', description: undefined }] },
453
+ ])
454
+ })
455
+
456
+ it('an ASK row with no answerable options decodes to nothing', () => {
457
+ const dialog: HistoricalMessage[] = [
458
+ {
459
+ id: 'a1',
460
+ chatType: 'CLIENT_CHAT',
461
+ createdAt: '2026-07-19T09:00:05Z',
462
+ owner: { type: 'ASSISTANT' },
463
+ messageData: [{ type: 'ASK', question: 'Which one?', options: [{ description: 'no label' }] } as any],
464
+ },
465
+ ]
466
+ expect(processHistoricalMessages(dialog).messages).toEqual([])
467
+ })
468
+ })
@@ -9,6 +9,7 @@
9
9
  */
10
10
 
11
11
  import type {
12
+ AskOptionData,
12
13
  MessageSegment,
13
14
  ToolExecutionSegment,
14
15
  ApprovalRequestSegment,
@@ -163,6 +164,17 @@ export class MessageSegmentAccumulator {
163
164
  return this.getSegments()
164
165
  }
165
166
 
167
+ /**
168
+ * Add a clarification (ask) card. Unlike the three delta streams an ask
169
+ * arrives whole in one chunk, so it is always a NEW segment — never merged
170
+ * into a trailing one. Consecutive cards stay separate segments; the renderer
171
+ * is what pages through a run of them.
172
+ */
173
+ addAsk(question: string, options: AskOptionData[]): MessageSegment[] {
174
+ this.segments.push({ type: 'ask', question, options })
175
+ return this.getSegments()
176
+ }
177
+
166
178
  /**
167
179
  * Add a tool execution segment.
168
180
  *
@@ -530,6 +542,9 @@ export class MessageSegmentAccumulator {
530
542
  case 'guide':
531
543
  if (segment.text) this.appendGuide(segment.text)
532
544
  break
545
+ case 'ask':
546
+ this.addAsk(segment.question, segment.options)
547
+ break
533
548
  case 'tool_execution':
534
549
  this.addToolExecution(segment)
535
550
  break
@@ -38,6 +38,9 @@ import {
38
38
  type MessageOwner,
39
39
  } from '../types'
40
40
  import type { ChatStreamEvent } from '../../../chat-protocol/events'
41
+ // One normalizer for ask rows, shared with the live decoder — history and the
42
+ // stream must agree on which options are usable.
43
+ import { normalizeAskOptions } from '../../../chat-protocol/nats-decoder'
41
44
  import { MessageSegmentAccumulator, createMessageSegmentAccumulator } from './message-segment-accumulator'
42
45
  import { getCommandText } from './tool-call-helpers'
43
46
 
@@ -117,6 +120,22 @@ export function decodeHistoricalMessageData(data: MessageData): ChatStreamEvent
117
120
  }
118
121
  return null
119
122
 
123
+ // Same completeness gate as the live decoder (`decodeNatsChunk`): a
124
+ // persisted row without a question or without options is not a card the
125
+ // user can answer, so it replays as nothing rather than as empty chrome.
126
+ case MESSAGE_TYPE.ASK: {
127
+ if (!('question' in data)) return null
128
+ const question = typeof data.question === 'string' ? data.question.trim() : ''
129
+ const options = normalizeAskOptions(data.options)
130
+ if (!question || options.length === 0) return null
131
+ return {
132
+ type: 'ask',
133
+ ...(data.text ? { text: data.text } : {}),
134
+ question,
135
+ options,
136
+ }
137
+ }
138
+
120
139
  case MESSAGE_TYPE.EXECUTING_TOOL:
121
140
  if ('integratedToolType' in data) {
122
141
  return {
@@ -252,6 +271,13 @@ function applyHistoryEvent(
252
271
  accumulator.appendGuide(event.text)
253
272
  break
254
273
 
274
+ // Mirror of the live path: the intro sentence replays as answer text in
275
+ // front of the card, so a reloaded thread reads exactly like the stream did.
276
+ case 'ask':
277
+ if (event.text) accumulator.appendText(event.text)
278
+ accumulator.addAsk(event.question, event.options)
279
+ break
280
+
255
281
  case 'tool-execution':
256
282
  accumulator.addToolExecution({ type: 'tool_execution', data: event.data })
257
283
  break
@@ -55,6 +55,15 @@ const buttonVariants = cva(
55
55
  // metadata rather than CTAs — author-page social rows, share rows.
56
56
  // Pair with variant="transparent" for the ghost treatment.
57
57
  'icon-sm': 'p-[var(--spacing-system-xxs)] h-8 w-8 [&_svg]:h-4 [&_svg]:w-4',
58
+ // 20px inline glyph for affordances that sit INSIDE a line of text —
59
+ // an info hint beside a badge, a copy glyph after an id. `icon-sm`'s
60
+ // 32px target is correct for a metadata row but visually swamps a
61
+ // 10px badge or a 14px label, so hosts were reaching for className
62
+ // overrides to shrink it. Below the WCAG 2.5.8 target floor on purpose:
63
+ // this is only for glyphs whose information is ALSO available another
64
+ // way (tooltip content mirrored into an aria-describedby node), never
65
+ // for a sole means of performing an action.
66
+ 'icon-inline': 'p-0 h-5 w-5 min-h-0 min-w-0 shrink-0 [&_svg]:h-3.5 [&_svg]:w-3.5',
58
67
  // Bare 56px media glyph (play / unmute over video). A size variant so
59
68
  // hosts stop re-implementing a <button> to escape the 20px svg cap.
60
69
  'icon-glyph': 'p-0 h-14 w-14 [&_svg]:h-14 [&_svg]:w-14',