@flamingo-stack/openframe-frontend-core 0.0.204 → 0.0.205

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 (509) hide show
  1. package/dist/{chunk-4CWSZPXH.cjs → chunk-24KCAECR.cjs} +9 -9
  2. package/dist/{chunk-4CWSZPXH.cjs.map → chunk-24KCAECR.cjs.map} +1 -1
  3. package/dist/chunk-27APPAJN.cjs +24 -0
  4. package/dist/chunk-27APPAJN.cjs.map +1 -0
  5. package/dist/{chunk-UC43NICZ.cjs → chunk-664KA5FI.cjs} +2 -35
  6. package/dist/chunk-664KA5FI.cjs.map +1 -0
  7. package/dist/chunk-6RZYJICV.cjs +24 -0
  8. package/dist/chunk-6RZYJICV.cjs.map +1 -0
  9. package/dist/chunk-7L4DWM7P.js +24 -0
  10. package/dist/chunk-7L4DWM7P.js.map +1 -0
  11. package/dist/chunk-BZFW3FOF.cjs +21 -0
  12. package/dist/chunk-BZFW3FOF.cjs.map +1 -0
  13. package/dist/{chunk-N57KWHDB.js → chunk-CIPO6DXK.js} +5 -5
  14. package/dist/chunk-EL5YVPD5.js +21 -0
  15. package/dist/chunk-EL5YVPD5.js.map +1 -0
  16. package/dist/{chunk-ARQ4XP64.cjs → chunk-FDCFI7YT.cjs} +40080 -31492
  17. package/dist/chunk-FDCFI7YT.cjs.map +1 -0
  18. package/dist/chunk-G7UE6RKV.cjs +121 -0
  19. package/dist/chunk-G7UE6RKV.cjs.map +1 -0
  20. package/dist/{chunk-25LVV26X.cjs → chunk-JUZGUQMX.cjs} +178 -50
  21. package/dist/chunk-JUZGUQMX.cjs.map +1 -0
  22. package/dist/{chunk-SZPJ5R5B.js → chunk-KSOOKNBG.js} +1 -34
  23. package/dist/chunk-KSOOKNBG.js.map +1 -0
  24. package/dist/{chunk-RMB5DVED.cjs → chunk-KUZGEA7U.cjs} +83 -66
  25. package/dist/chunk-KUZGEA7U.cjs.map +1 -0
  26. package/dist/chunk-LXC6P2EO.js +63 -0
  27. package/dist/chunk-LXC6P2EO.js.map +1 -0
  28. package/dist/chunk-MJNXIEV2.js +24 -0
  29. package/dist/chunk-MJNXIEV2.js.map +1 -0
  30. package/dist/{chunk-CPXLQ57U.js → chunk-MVGGXOFA.js} +37 -20
  31. package/dist/chunk-MVGGXOFA.js.map +1 -0
  32. package/dist/{chunk-LY34ORX6.js → chunk-O55ZUAX7.js} +39920 -31332
  33. package/dist/chunk-O55ZUAX7.js.map +1 -0
  34. package/dist/chunk-OHPI2HRK.js +47 -0
  35. package/dist/chunk-OHPI2HRK.js.map +1 -0
  36. package/dist/chunk-PLJLE4A4.js +121 -0
  37. package/dist/chunk-PLJLE4A4.js.map +1 -0
  38. package/dist/{chunk-XGL5FKIK.js → chunk-SCN5WFIZ.js} +148 -20
  39. package/dist/chunk-SCN5WFIZ.js.map +1 -0
  40. package/dist/chunk-WBR7H6E3.cjs +47 -0
  41. package/dist/chunk-WBR7H6E3.cjs.map +1 -0
  42. package/dist/chunk-XL4V2PYG.cjs +63 -0
  43. package/dist/chunk-XL4V2PYG.cjs.map +1 -0
  44. package/dist/components/announcement-bar.d.ts.map +1 -1
  45. package/dist/components/chat/chat-attachment-bar.d.ts +66 -0
  46. package/dist/components/chat/chat-attachment-bar.d.ts.map +1 -0
  47. package/dist/components/chat/chat-container.d.ts +21 -1
  48. package/dist/components/chat/chat-container.d.ts.map +1 -1
  49. package/dist/components/chat/chat-input.d.ts.map +1 -1
  50. package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
  51. package/dist/components/chat/chat-message-list.d.ts.map +1 -1
  52. package/dist/components/chat/chat-panel-context.d.ts +9 -0
  53. package/dist/components/chat/chat-panel-context.d.ts.map +1 -0
  54. package/dist/components/chat/chat-ticket-list.d.ts +1 -1
  55. package/dist/components/chat/chat-ticket-list.d.ts.map +1 -1
  56. package/dist/components/chat/embeddable-chat.d.ts +42 -0
  57. package/dist/components/chat/embeddable-chat.d.ts.map +1 -0
  58. package/dist/components/chat/entity-cards/admin-content-card.d.ts +34 -0
  59. package/dist/components/chat/entity-cards/admin-content-card.d.ts.map +1 -0
  60. package/dist/components/chat/entity-cards/block-card.d.ts.map +1 -0
  61. package/dist/components/chat/entity-cards/blog-card.d.ts +30 -0
  62. package/dist/components/chat/entity-cards/blog-card.d.ts.map +1 -0
  63. package/dist/components/chat/entity-cards/blog-image-placeholder.d.ts +26 -0
  64. package/dist/components/chat/entity-cards/blog-image-placeholder.d.ts.map +1 -0
  65. package/dist/components/chat/entity-cards/campaign-card-admin.d.ts +33 -0
  66. package/dist/components/chat/entity-cards/campaign-card-admin.d.ts.map +1 -0
  67. package/dist/components/chat/entity-cards/case-study-card.d.ts +20 -0
  68. package/dist/components/chat/entity-cards/case-study-card.d.ts.map +1 -0
  69. package/dist/components/chat/entity-cards/chat-ticket-item.d.ts.map +1 -0
  70. package/dist/components/chat/{chat-video-entity-card.d.ts → entity-cards/chat-video-entity-card.d.ts} +1 -1
  71. package/dist/components/chat/entity-cards/chat-video-entity-card.d.ts.map +1 -0
  72. package/dist/components/chat/entity-cards/customer-interview-card.d.ts +19 -0
  73. package/dist/components/chat/entity-cards/customer-interview-card.d.ts.map +1 -0
  74. package/dist/components/chat/entity-cards/data-room-doc-card.d.ts +47 -0
  75. package/dist/components/chat/entity-cards/data-room-doc-card.d.ts.map +1 -0
  76. package/dist/components/chat/entity-cards/dispatch.d.ts +119 -0
  77. package/dist/components/chat/entity-cards/dispatch.d.ts.map +1 -0
  78. package/dist/components/chat/entity-cards/entity-author-card.d.ts +87 -0
  79. package/dist/components/chat/entity-cards/entity-author-card.d.ts.map +1 -0
  80. package/dist/components/chat/entity-cards/generic-entity-card.d.ts +42 -0
  81. package/dist/components/chat/entity-cards/generic-entity-card.d.ts.map +1 -0
  82. package/dist/components/chat/entity-cards/github-activity-card.d.ts +37 -0
  83. package/dist/components/chat/entity-cards/github-activity-card.d.ts.map +1 -0
  84. package/dist/components/chat/entity-cards/hubspot-ticket-card.d.ts +28 -0
  85. package/dist/components/chat/entity-cards/hubspot-ticket-card.d.ts.map +1 -0
  86. package/dist/components/chat/entity-cards/index.d.ts +32 -0
  87. package/dist/components/chat/entity-cards/index.d.ts.map +1 -0
  88. package/dist/components/chat/entity-cards/investor-update-card.d.ts +19 -0
  89. package/dist/components/chat/entity-cards/investor-update-card.d.ts.map +1 -0
  90. package/dist/components/chat/entity-cards/onboarding-guide-card.d.ts +20 -0
  91. package/dist/components/chat/entity-cards/onboarding-guide-card.d.ts.map +1 -0
  92. package/dist/components/chat/entity-cards/product-release-card-defaults.d.ts +21 -0
  93. package/dist/components/chat/entity-cards/product-release-card-defaults.d.ts.map +1 -0
  94. package/dist/components/chat/entity-cards/product-release-card.d.ts +12 -0
  95. package/dist/components/chat/entity-cards/product-release-card.d.ts.map +1 -0
  96. package/dist/components/chat/entity-cards/program-card-defaults.d.ts +32 -0
  97. package/dist/components/chat/entity-cards/program-card-defaults.d.ts.map +1 -0
  98. package/dist/components/chat/entity-cards/program-card.d.ts +37 -0
  99. package/dist/components/chat/entity-cards/program-card.d.ts.map +1 -0
  100. package/dist/components/chat/entity-cards/roadmap-card.d.ts +28 -0
  101. package/dist/components/chat/entity-cards/roadmap-card.d.ts.map +1 -0
  102. package/dist/components/chat/entity-cards/roadmap-vote-button.d.ts +12 -0
  103. package/dist/components/chat/entity-cards/roadmap-vote-button.d.ts.map +1 -0
  104. package/dist/components/chat/entity-cards/slack-message-card.d.ts +28 -0
  105. package/dist/components/chat/entity-cards/slack-message-card.d.ts.map +1 -0
  106. package/dist/components/chat/entity-cards/task-type-icon.d.ts +6 -0
  107. package/dist/components/chat/entity-cards/task-type-icon.d.ts.map +1 -0
  108. package/dist/components/chat/hooks/index.d.ts +10 -0
  109. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  110. package/dist/components/chat/hooks/use-chat-attachment-image-gallery.d.ts +5 -0
  111. package/dist/components/chat/hooks/use-chat-attachment-image-gallery.d.ts.map +1 -0
  112. package/dist/components/chat/hooks/use-chat-attachments.d.ts +33 -0
  113. package/dist/components/chat/hooks/use-chat-attachments.d.ts.map +1 -0
  114. package/dist/components/chat/hooks/use-chat-card-item.d.ts +7 -0
  115. package/dist/components/chat/hooks/use-chat-card-item.d.ts.map +1 -0
  116. package/dist/components/chat/hooks/use-chat-identity.d.ts +44 -0
  117. package/dist/components/chat/hooks/use-chat-identity.d.ts.map +1 -0
  118. package/dist/components/chat/hooks/use-chat.d.ts +30 -0
  119. package/dist/components/chat/hooks/use-chat.d.ts.map +1 -0
  120. package/dist/components/chat/hooks/use-close-on-navigation.d.ts +2 -0
  121. package/dist/components/chat/hooks/use-close-on-navigation.d.ts.map +1 -0
  122. package/dist/components/chat/hooks/use-embedded-chat.d.ts +174 -0
  123. package/dist/components/chat/hooks/use-embedded-chat.d.ts.map +1 -0
  124. package/dist/components/chat/hooks/use-proxied-image-url.d.ts +18 -0
  125. package/dist/components/chat/hooks/use-proxied-image-url.d.ts.map +1 -0
  126. package/dist/components/chat/hooks/use-slash-commands.d.ts +32 -0
  127. package/dist/components/chat/hooks/use-slash-commands.d.ts.map +1 -0
  128. package/dist/components/chat/hooks/use-sse.d.ts +57 -0
  129. package/dist/components/chat/hooks/use-sse.d.ts.map +1 -0
  130. package/dist/components/chat/index.cjs +393 -0
  131. package/dist/components/chat/index.cjs.map +1 -0
  132. package/dist/components/chat/index.d.ts +5 -3
  133. package/dist/components/chat/index.d.ts.map +1 -1
  134. package/dist/components/chat/index.js +393 -0
  135. package/dist/components/chat/index.js.map +1 -0
  136. package/dist/components/chat/nav-link-anchor-via-runtime.d.ts +33 -0
  137. package/dist/components/chat/nav-link-anchor-via-runtime.d.ts.map +1 -0
  138. package/dist/components/chat/source-action-button.d.ts +39 -0
  139. package/dist/components/chat/source-action-button.d.ts.map +1 -0
  140. package/dist/components/chat/types/chat.types.d.ts +36 -0
  141. package/dist/components/chat/types/chat.types.d.ts.map +1 -1
  142. package/dist/components/chat/types/component.types.d.ts +56 -11
  143. package/dist/components/chat/types/component.types.d.ts.map +1 -1
  144. package/dist/components/chat/types/entities/blog.d.ts +14 -0
  145. package/dist/components/chat/types/entities/blog.d.ts.map +1 -0
  146. package/dist/components/chat/types/entities/case-study.d.ts +10 -0
  147. package/dist/components/chat/types/entities/case-study.d.ts.map +1 -0
  148. package/dist/components/chat/types/entities/content-ref.d.ts +23 -0
  149. package/dist/components/chat/types/entities/content-ref.d.ts.map +1 -0
  150. package/dist/components/chat/types/entities/customer-interview.d.ts +10 -0
  151. package/dist/components/chat/types/entities/customer-interview.d.ts.map +1 -0
  152. package/dist/components/chat/types/entities/data-room-doc.d.ts +37 -0
  153. package/dist/components/chat/types/entities/data-room-doc.d.ts.map +1 -0
  154. package/dist/components/chat/types/entities/github-activity.d.ts +29 -0
  155. package/dist/components/chat/types/entities/github-activity.d.ts.map +1 -0
  156. package/dist/components/chat/types/entities/hubspot-ticket.d.ts +39 -0
  157. package/dist/components/chat/types/entities/hubspot-ticket.d.ts.map +1 -0
  158. package/dist/components/chat/types/entities/index.d.ts +28 -0
  159. package/dist/components/chat/types/entities/index.d.ts.map +1 -0
  160. package/dist/components/chat/types/entities/investor-update.d.ts +83 -0
  161. package/dist/components/chat/types/entities/investor-update.d.ts.map +1 -0
  162. package/dist/components/chat/types/entities/onboarding-guide.d.ts +79 -0
  163. package/dist/components/chat/types/entities/onboarding-guide.d.ts.map +1 -0
  164. package/dist/components/chat/types/entities/program-types.d.ts +303 -0
  165. package/dist/components/chat/types/entities/program-types.d.ts.map +1 -0
  166. package/dist/components/chat/types/entities/roadmap-item.d.ts +41 -0
  167. package/dist/components/chat/types/entities/roadmap-item.d.ts.map +1 -0
  168. package/dist/components/chat/types/entities/slack-message.d.ts +28 -0
  169. package/dist/components/chat/types/entities/slack-message.d.ts.map +1 -0
  170. package/dist/components/chat/types/index.d.ts +1 -0
  171. package/dist/components/chat/types/index.d.ts.map +1 -1
  172. package/dist/components/chat/utils/agent-status-message.d.ts +18 -0
  173. package/dist/components/chat/utils/agent-status-message.d.ts.map +1 -0
  174. package/dist/components/chat/utils/auto-continuation-directive.d.ts +38 -0
  175. package/dist/components/chat/utils/auto-continuation-directive.d.ts.map +1 -0
  176. package/dist/components/chat/utils/chat-attachment-markdown.d.ts +114 -0
  177. package/dist/components/chat/utils/chat-attachment-markdown.d.ts.map +1 -0
  178. package/dist/components/chat/utils/chat-authed-fetch.d.ts +13 -0
  179. package/dist/components/chat/utils/chat-authed-fetch.d.ts.map +1 -0
  180. package/dist/components/chat/utils/chat-nav-resolution.d.ts +72 -0
  181. package/dist/components/chat/utils/chat-nav-resolution.d.ts.map +1 -0
  182. package/dist/components/chat/utils/chat-proxy-auth-storage.d.ts +43 -0
  183. package/dist/components/chat/utils/chat-proxy-auth-storage.d.ts.map +1 -0
  184. package/dist/components/chat/utils/chip-action-class.d.ts +16 -0
  185. package/dist/components/chat/utils/chip-action-class.d.ts.map +1 -0
  186. package/dist/components/chat/utils/chip-styles.d.ts +32 -0
  187. package/dist/components/chat/utils/chip-styles.d.ts.map +1 -0
  188. package/dist/components/chat/utils/clickup-task-type-utils.d.ts +38 -0
  189. package/dist/components/chat/utils/clickup-task-type-utils.d.ts.map +1 -0
  190. package/dist/components/chat/utils/compact-card-classes.d.ts +50 -0
  191. package/dist/components/chat/utils/compact-card-classes.d.ts.map +1 -0
  192. package/dist/components/chat/utils/decide-new-tab.d.ts +39 -0
  193. package/dist/components/chat/utils/decide-new-tab.d.ts.map +1 -0
  194. package/dist/components/chat/utils/external-app-urls.d.ts +14 -0
  195. package/dist/components/chat/utils/external-app-urls.d.ts.map +1 -0
  196. package/dist/components/chat/utils/flatten-assistant-content.d.ts +25 -0
  197. package/dist/components/chat/utils/flatten-assistant-content.d.ts.map +1 -0
  198. package/dist/components/chat/utils/icon-registry.d.ts +67 -0
  199. package/dist/components/chat/utils/icon-registry.d.ts.map +1 -0
  200. package/dist/components/chat/utils/index.d.ts +21 -0
  201. package/dist/components/chat/utils/index.d.ts.map +1 -1
  202. package/dist/components/chat/utils/is-cross-origin-url.d.ts +22 -0
  203. package/dist/components/chat/utils/is-cross-origin-url.d.ts.map +1 -0
  204. package/dist/components/chat/utils/nav-anchor-props.d.ts +54 -0
  205. package/dist/components/chat/utils/nav-anchor-props.d.ts.map +1 -0
  206. package/dist/components/chat/utils/nav-click-handler.d.ts +51 -0
  207. package/dist/components/chat/utils/nav-click-handler.d.ts.map +1 -0
  208. package/dist/components/chat/utils/scroll-anchor.d.ts +30 -0
  209. package/dist/components/chat/utils/scroll-anchor.d.ts.map +1 -0
  210. package/dist/components/chat/utils/slash-dispatch-utils.d.ts +109 -0
  211. package/dist/components/chat/utils/slash-dispatch-utils.d.ts.map +1 -0
  212. package/dist/components/chat/utils/source-icons.d.ts +8 -0
  213. package/dist/components/chat/utils/source-icons.d.ts.map +1 -0
  214. package/dist/components/chat/utils/source-row-cta.d.ts +111 -0
  215. package/dist/components/chat/utils/source-row-cta.d.ts.map +1 -0
  216. package/dist/components/features/figma-prototype-viewer.d.ts.map +1 -1
  217. package/dist/components/features/index.cjs +12 -6
  218. package/dist/components/features/index.cjs.map +1 -1
  219. package/dist/components/features/index.js +11 -5
  220. package/dist/components/features/video.d.ts.map +1 -1
  221. package/dist/components/icons/index.cjs +3 -3
  222. package/dist/components/icons/index.js +2 -2
  223. package/dist/components/index.cjs +274 -8
  224. package/dist/components/index.cjs.map +1 -1
  225. package/dist/components/index.js +273 -7
  226. package/dist/components/interactive-wrapper.d.ts +3 -3
  227. package/dist/components/navigation/index.cjs +12 -6
  228. package/dist/components/navigation/index.cjs.map +1 -1
  229. package/dist/components/navigation/index.js +11 -5
  230. package/dist/components/resizable.d.ts +1 -1
  231. package/dist/components/shared/product-release/product-release-card-skeleton.d.ts +1 -1
  232. package/dist/components/shared/product-release/product-release-card-skeleton.d.ts.map +1 -1
  233. package/dist/components/shared/product-release/product-release-card.d.ts +19 -12
  234. package/dist/components/shared/product-release/product-release-card.d.ts.map +1 -1
  235. package/dist/components/shared/product-release/release-detail-page.d.ts +2 -4
  236. package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
  237. package/dist/components/ui/button/button.d.ts +13 -0
  238. package/dist/components/ui/button/button.d.ts.map +1 -1
  239. package/dist/components/ui/dashboard-info-card.d.ts.map +1 -1
  240. package/dist/components/ui/entity-image.d.ts.map +1 -1
  241. package/dist/components/ui/file-manager/index.cjs +71 -70
  242. package/dist/components/ui/file-manager/index.cjs.map +1 -1
  243. package/dist/components/ui/file-manager/index.js +6 -5
  244. package/dist/components/ui/file-manager/index.js.map +1 -1
  245. package/dist/components/ui/hover-dropdown.d.ts +66 -0
  246. package/dist/components/ui/hover-dropdown.d.ts.map +1 -0
  247. package/dist/components/ui/index.cjs +276 -6
  248. package/dist/components/ui/index.cjs.map +1 -1
  249. package/dist/components/ui/index.d.ts +1 -0
  250. package/dist/components/ui/index.d.ts.map +1 -1
  251. package/dist/components/ui/index.js +278 -8
  252. package/dist/components/ui/simple-markdown-renderer.d.ts.map +1 -1
  253. package/dist/components/ui/square-avatar.d.ts.map +1 -1
  254. package/dist/contexts/chat-runtime-context.d.ts +109 -0
  255. package/dist/contexts/chat-runtime-context.d.ts.map +1 -0
  256. package/dist/contexts/endpoints-runtime-context.d.ts +28 -0
  257. package/dist/contexts/endpoints-runtime-context.d.ts.map +1 -0
  258. package/dist/contexts/index.cjs +30 -0
  259. package/dist/contexts/index.cjs.map +1 -0
  260. package/dist/contexts/index.d.ts +26 -0
  261. package/dist/contexts/index.d.ts.map +1 -0
  262. package/dist/contexts/index.js +30 -0
  263. package/dist/contexts/index.js.map +1 -0
  264. package/dist/contexts/use-outer-or-default.d.ts +29 -0
  265. package/dist/contexts/use-outer-or-default.d.ts.map +1 -0
  266. package/dist/embed-shims/index.cjs +51 -0
  267. package/dist/embed-shims/index.cjs.map +1 -0
  268. package/dist/embed-shims/index.d.ts +31 -0
  269. package/dist/embed-shims/index.d.ts.map +1 -0
  270. package/dist/embed-shims/index.js +51 -0
  271. package/dist/embed-shims/index.js.map +1 -0
  272. package/dist/embed-shims/next-dynamic.cjs +12 -0
  273. package/dist/embed-shims/next-dynamic.cjs.map +1 -0
  274. package/dist/embed-shims/next-dynamic.d.ts +47 -0
  275. package/dist/embed-shims/next-dynamic.d.ts.map +1 -0
  276. package/dist/embed-shims/next-dynamic.js +12 -0
  277. package/dist/embed-shims/next-dynamic.js.map +1 -0
  278. package/dist/embed-shims/next-image.cjs +12 -0
  279. package/dist/embed-shims/next-image.cjs.map +1 -0
  280. package/dist/embed-shims/next-image.d.ts +28 -0
  281. package/dist/embed-shims/next-image.d.ts.map +1 -0
  282. package/dist/embed-shims/next-image.js +12 -0
  283. package/dist/embed-shims/next-image.js.map +1 -0
  284. package/dist/embed-shims/next-link.cjs +14 -0
  285. package/dist/embed-shims/next-link.cjs.map +1 -0
  286. package/dist/embed-shims/next-link.d.ts +22 -0
  287. package/dist/embed-shims/next-link.d.ts.map +1 -0
  288. package/dist/embed-shims/next-link.js +14 -0
  289. package/dist/embed-shims/next-link.js.map +1 -0
  290. package/dist/embed-shims/next-navigation.cjs +30 -0
  291. package/dist/embed-shims/next-navigation.cjs.map +1 -0
  292. package/dist/embed-shims/next-navigation.d.ts +46 -0
  293. package/dist/embed-shims/next-navigation.d.ts.map +1 -0
  294. package/dist/embed-shims/next-navigation.js +30 -0
  295. package/dist/embed-shims/next-navigation.js.map +1 -0
  296. package/dist/hooks/index.cjs +10 -4
  297. package/dist/hooks/index.cjs.map +1 -1
  298. package/dist/hooks/index.d.ts +2 -0
  299. package/dist/hooks/index.d.ts.map +1 -1
  300. package/dist/hooks/index.js +9 -3
  301. package/dist/hooks/use-access-code-integration.d.ts +48 -0
  302. package/dist/hooks/use-access-code-integration.d.ts.map +1 -0
  303. package/dist/hooks/use-contact-submission.d.ts.map +1 -1
  304. package/dist/hooks/use-og-placeholder.d.ts +31 -0
  305. package/dist/hooks/use-og-placeholder.d.ts.map +1 -0
  306. package/dist/hooks/use-toast.d.ts +1 -1
  307. package/dist/index.cjs +367 -7
  308. package/dist/index.cjs.map +1 -1
  309. package/dist/index.js +378 -18
  310. package/dist/types/index.cjs.map +1 -1
  311. package/dist/types/index.js.map +1 -1
  312. package/dist/utils/access-code-client.d.ts +21 -37
  313. package/dist/utils/access-code-client.d.ts.map +1 -1
  314. package/dist/utils/cn.d.ts +0 -27
  315. package/dist/utils/cn.d.ts.map +1 -1
  316. package/dist/utils/color-analysis.d.ts +33 -0
  317. package/dist/utils/color-analysis.d.ts.map +1 -0
  318. package/dist/utils/date-formatters.d.ts +16 -5
  319. package/dist/utils/date-formatters.d.ts.map +1 -1
  320. package/dist/utils/fetch-priority.d.ts +3 -0
  321. package/dist/utils/fetch-priority.d.ts.map +1 -0
  322. package/dist/utils/format.d.ts +192 -1
  323. package/dist/utils/format.d.ts.map +1 -1
  324. package/dist/utils/image-proxy.d.ts +67 -2
  325. package/dist/utils/image-proxy.d.ts.map +1 -1
  326. package/dist/utils/index.cjs +1274 -155
  327. package/dist/utils/index.cjs.map +1 -1
  328. package/dist/utils/index.d.ts +19 -3
  329. package/dist/utils/index.d.ts.map +1 -1
  330. package/dist/utils/index.js +1200 -157
  331. package/dist/utils/index.js.map +1 -1
  332. package/dist/utils/local-storage-adapter.d.ts +46 -0
  333. package/dist/utils/local-storage-adapter.d.ts.map +1 -0
  334. package/dist/utils/source-icons.d.ts +78 -0
  335. package/dist/utils/source-icons.d.ts.map +1 -0
  336. package/package.json +29 -2
  337. package/src/components/announcement-bar.tsx +26 -4
  338. package/src/components/categories-cart.tsx +1 -1
  339. package/src/components/chat/chat-attachment-bar.tsx +323 -0
  340. package/src/components/chat/chat-container.tsx +39 -5
  341. package/src/components/chat/chat-input.tsx +7 -1
  342. package/src/components/chat/chat-message-enhanced.tsx +32 -22
  343. package/src/components/chat/chat-message-list.tsx +53 -4
  344. package/src/components/chat/chat-panel-context.tsx +37 -0
  345. package/src/components/chat/chat-ticket-list.tsx +1 -1
  346. package/src/components/chat/embeddable-chat.tsx +1106 -0
  347. package/src/components/chat/entity-cards/admin-content-card.tsx +155 -0
  348. package/src/components/chat/entity-cards/blog-card.tsx +259 -0
  349. package/src/components/chat/entity-cards/blog-image-placeholder.tsx +52 -0
  350. package/src/components/chat/entity-cards/campaign-card-admin.tsx +113 -0
  351. package/src/components/chat/entity-cards/case-study-card.tsx +192 -0
  352. package/src/components/chat/{chat-ticket-item.tsx → entity-cards/chat-ticket-item.tsx} +2 -2
  353. package/src/components/chat/{chat-video-entity-card.tsx → entity-cards/chat-video-entity-card.tsx} +2 -2
  354. package/src/components/chat/entity-cards/customer-interview-card.tsx +211 -0
  355. package/src/components/chat/entity-cards/data-room-doc-card.tsx +120 -0
  356. package/src/components/chat/entity-cards/dispatch.tsx +1093 -0
  357. package/src/components/chat/entity-cards/entity-author-card.tsx +193 -0
  358. package/src/components/chat/entity-cards/generic-entity-card.tsx +144 -0
  359. package/src/components/chat/entity-cards/github-activity-card.tsx +305 -0
  360. package/src/components/chat/entity-cards/hubspot-ticket-card.tsx +205 -0
  361. package/src/components/chat/entity-cards/index.ts +125 -0
  362. package/src/components/chat/entity-cards/investor-update-card.tsx +150 -0
  363. package/src/components/chat/entity-cards/onboarding-guide-card.tsx +326 -0
  364. package/src/components/chat/entity-cards/product-release-card-defaults.ts +57 -0
  365. package/src/components/chat/entity-cards/product-release-card.tsx +19 -0
  366. package/src/components/chat/entity-cards/program-card-defaults.ts +62 -0
  367. package/src/components/chat/entity-cards/program-card.tsx +451 -0
  368. package/src/components/chat/entity-cards/roadmap-card.tsx +356 -0
  369. package/src/components/chat/entity-cards/roadmap-vote-button.tsx +54 -0
  370. package/src/components/chat/entity-cards/slack-message-card.tsx +182 -0
  371. package/src/components/chat/entity-cards/task-type-icon.tsx +60 -0
  372. package/src/components/chat/hooks/index.ts +22 -0
  373. package/src/components/chat/hooks/use-chat-attachment-image-gallery.tsx +114 -0
  374. package/src/components/chat/hooks/use-chat-attachments.ts +429 -0
  375. package/src/components/chat/hooks/use-chat-card-item.ts +102 -0
  376. package/src/components/chat/hooks/use-chat-identity.ts +139 -0
  377. package/src/components/chat/hooks/use-chat.ts +501 -0
  378. package/src/components/chat/hooks/use-close-on-navigation.ts +87 -0
  379. package/src/components/chat/hooks/use-embedded-chat.ts +1023 -0
  380. package/src/components/chat/hooks/use-proxied-image-url.ts +31 -0
  381. package/src/components/chat/hooks/use-slash-commands.ts +106 -0
  382. package/src/components/chat/hooks/use-sse.ts +143 -0
  383. package/src/components/chat/index.ts +30 -4
  384. package/src/components/chat/nav-link-anchor-via-runtime.tsx +72 -0
  385. package/src/components/chat/source-action-button.tsx +120 -0
  386. package/src/components/chat/types/chat.types.ts +61 -0
  387. package/src/components/chat/types/component.types.ts +57 -11
  388. package/src/components/chat/types/entities/blog.ts +27 -0
  389. package/src/components/chat/types/entities/case-study.ts +14 -0
  390. package/src/components/chat/types/entities/content-ref.ts +23 -0
  391. package/src/components/chat/types/entities/customer-interview.ts +15 -0
  392. package/src/components/chat/types/entities/data-room-doc.ts +37 -0
  393. package/src/components/chat/types/entities/github-activity.ts +36 -0
  394. package/src/components/chat/types/entities/hubspot-ticket.ts +39 -0
  395. package/src/components/chat/types/entities/index.ts +28 -0
  396. package/src/components/chat/types/entities/investor-update.ts +100 -0
  397. package/src/components/chat/types/entities/onboarding-guide.ts +101 -0
  398. package/src/components/chat/types/entities/program-types.ts +433 -0
  399. package/src/components/chat/types/entities/roadmap-item.ts +42 -0
  400. package/src/components/chat/types/entities/slack-message.ts +28 -0
  401. package/src/components/chat/types/index.ts +1 -0
  402. package/src/components/chat/utils/agent-status-message.ts +52 -0
  403. package/src/components/chat/utils/auto-continuation-directive.ts +70 -0
  404. package/src/components/chat/utils/chat-attachment-markdown.ts +190 -0
  405. package/src/components/chat/utils/chat-authed-fetch.ts +73 -0
  406. package/src/components/chat/utils/chat-nav-resolution.ts +151 -0
  407. package/src/components/chat/utils/chat-proxy-auth-storage.ts +148 -0
  408. package/src/components/chat/utils/chip-action-class.ts +19 -0
  409. package/src/components/chat/utils/chip-styles.ts +51 -0
  410. package/src/components/chat/utils/clickup-task-type-utils.ts +59 -0
  411. package/src/components/chat/utils/compact-card-classes.ts +97 -0
  412. package/src/components/chat/utils/decide-new-tab.ts +57 -0
  413. package/src/components/chat/utils/external-app-urls.ts +19 -0
  414. package/src/components/chat/utils/flatten-assistant-content.ts +35 -0
  415. package/src/components/chat/utils/icon-registry.ts +297 -0
  416. package/src/components/chat/utils/index.ts +133 -0
  417. package/src/components/chat/utils/is-cross-origin-url.ts +28 -0
  418. package/src/components/chat/utils/nav-anchor-props.ts +78 -0
  419. package/src/components/chat/utils/nav-click-handler.ts +81 -0
  420. package/src/components/chat/utils/scroll-anchor.ts +35 -0
  421. package/src/components/chat/utils/slash-dispatch-utils.ts +183 -0
  422. package/src/components/chat/utils/source-icons.ts +14 -0
  423. package/src/components/chat/utils/source-row-cta.ts +215 -0
  424. package/src/components/empty-state.tsx +1 -1
  425. package/src/components/features/board/ticket-card.tsx +1 -1
  426. package/src/components/features/figma-prototype-viewer.tsx +2 -1
  427. package/src/components/features/media-gallery-manager.tsx +1 -1
  428. package/src/components/features/parallax-image-showcase.tsx +1 -1
  429. package/src/components/features/release-media-manager.tsx +1 -1
  430. package/src/components/features/seo-editor-preview.tsx +1 -1
  431. package/src/components/features/video.tsx +54 -3
  432. package/src/components/footer-waitlist-button.tsx +1 -1
  433. package/src/components/navigation/header.tsx +1 -1
  434. package/src/components/shared/onboarding/onboarding-step-card.tsx +1 -1
  435. package/src/components/shared/product-release/product-release-card-skeleton.tsx +8 -44
  436. package/src/components/shared/product-release/product-release-card.tsx +31 -116
  437. package/src/components/shared/product-release/release-detail-page.tsx +12 -16
  438. package/src/components/ui/actions-menu.tsx +1 -1
  439. package/src/components/ui/button/button.tsx +41 -11
  440. package/src/components/ui/button/split-button.tsx +1 -1
  441. package/src/components/ui/dashboard-info-card.tsx +2 -3
  442. package/src/components/ui/data-table/data-table-row.tsx +1 -1
  443. package/src/components/ui/entity-image.tsx +2 -8
  444. package/src/components/ui/hover-dropdown.tsx +258 -0
  445. package/src/components/ui/image-gallery-modal.tsx +1 -1
  446. package/src/components/ui/index.ts +1 -0
  447. package/src/components/ui/markdown-editor.tsx +1 -1
  448. package/src/components/ui/more-actions-menu.tsx +1 -1
  449. package/src/components/ui/organization-card.tsx +1 -1
  450. package/src/components/ui/simple-markdown-renderer.tsx +53 -5
  451. package/src/components/ui/square-avatar.tsx +3 -12
  452. package/src/components/ui/tab-navigation.tsx +1 -1
  453. package/src/components/ui/table/table-row.tsx +1 -1
  454. package/src/components/unified-filter-logic.tsx +1 -1
  455. package/src/components/unified-pagination.tsx +1 -1
  456. package/src/components/user-summary-stub.tsx +1 -1
  457. package/src/components/vendor-display-button.tsx +1 -1
  458. package/src/components/vendor-icon.tsx +1 -1
  459. package/src/contexts/chat-runtime-context.tsx +163 -0
  460. package/src/contexts/endpoints-runtime-context.tsx +68 -0
  461. package/src/contexts/index.ts +38 -0
  462. package/src/contexts/use-outer-or-default.ts +42 -0
  463. package/src/embed-shims/index.ts +42 -0
  464. package/src/embed-shims/next-dynamic.tsx +70 -0
  465. package/src/embed-shims/next-image.tsx +114 -0
  466. package/src/embed-shims/next-link.tsx +91 -0
  467. package/src/embed-shims/next-navigation.tsx +201 -0
  468. package/src/hooks/index.ts +9 -0
  469. package/src/hooks/state/use-api-params.ts +1 -1
  470. package/src/hooks/state/use-query-params.ts +1 -1
  471. package/src/hooks/use-access-code-integration.ts +107 -0
  472. package/src/hooks/use-contact-submission.ts +7 -3
  473. package/src/hooks/use-og-placeholder.ts +45 -0
  474. package/src/stories/OnboardingStepCard.stories.tsx +140 -0
  475. package/src/styles/chat-animations.css +65 -0
  476. package/src/styles/index.css +1 -0
  477. package/src/utils/access-code-client.ts +32 -75
  478. package/src/utils/cn.ts +0 -65
  479. package/src/utils/color-analysis.ts +205 -0
  480. package/src/utils/date-formatters.ts +54 -11
  481. package/src/utils/fetch-priority.ts +41 -0
  482. package/src/utils/format.ts +525 -1
  483. package/src/utils/image-proxy.ts +127 -7
  484. package/src/utils/index.ts +145 -5
  485. package/src/utils/local-storage-adapter.ts +105 -0
  486. package/src/utils/source-icons.ts +219 -0
  487. package/dist/chunk-25LVV26X.cjs.map +0 -1
  488. package/dist/chunk-ARQ4XP64.cjs.map +0 -1
  489. package/dist/chunk-CPXLQ57U.js.map +0 -1
  490. package/dist/chunk-LY34ORX6.js.map +0 -1
  491. package/dist/chunk-RMB5DVED.cjs.map +0 -1
  492. package/dist/chunk-SZPJ5R5B.js.map +0 -1
  493. package/dist/chunk-UC43NICZ.cjs.map +0 -1
  494. package/dist/chunk-XGL5FKIK.js.map +0 -1
  495. package/dist/components/chat/block-card.d.ts.map +0 -1
  496. package/dist/components/chat/chat-ticket-item.d.ts.map +0 -1
  497. package/dist/components/chat/chat-video-entity-card.d.ts.map +0 -1
  498. package/dist/utils/dynamic-icons.d.ts +0 -26
  499. package/dist/utils/dynamic-icons.d.ts.map +0 -1
  500. package/dist/utils/format-relative-time.d.ts +0 -21
  501. package/dist/utils/format-relative-time.d.ts.map +0 -1
  502. package/src/utils/.dynamic-icons.md +0 -30
  503. package/src/utils/.format-relative-time.md +0 -36
  504. package/src/utils/dynamic-icons.tsx +0 -120
  505. package/src/utils/format-relative-time.ts +0 -52
  506. /package/dist/{chunk-N57KWHDB.js.map → chunk-CIPO6DXK.js.map} +0 -0
  507. /package/dist/components/chat/{block-card.d.ts → entity-cards/block-card.d.ts} +0 -0
  508. /package/dist/components/chat/{chat-ticket-item.d.ts → entity-cards/chat-ticket-item.d.ts} +0 -0
  509. /package/src/components/chat/{block-card.tsx → entity-cards/block-card.tsx} +0 -0
@@ -1,8 +1,8 @@
1
1
  import { clsx } from 'clsx';
2
2
  import { extendTailwindMerge } from 'tailwind-merge';
3
3
  import { jsx, jsxs } from 'react/jsx-runtime';
4
- import React2 from 'react';
5
- import { Globe, Twitter, Video, Send, MessageCircle, Github, PenSquare, FileText } from 'lucide-react';
4
+ import React2, { createElement } from 'react';
5
+ import { Youtube, Video, Users, Twitter, TrendingUp, TableProperties, Star, Shield, Send, Search, Rocket, PenSquare, Package, Newspaper, MessageSquare, MessageCircle, Megaphone, Mail, Instagram, Info, Headphones, GraduationCap, Globe, Github, FileText, Facebook, DollarSign, CheckSquare, Calendar, Briefcase, Box, BookOpen, Bell, Banknote, Activity } from 'lucide-react';
6
6
  import { isValidPhoneNumber, parsePhoneNumber, getCountryCallingCode, getCountries } from 'libphonenumber-js';
7
7
 
8
8
  // src/utils/cn.ts
@@ -16,35 +16,6 @@ var twMerge = extendTailwindMerge({
16
16
  function cn(...inputs) {
17
17
  return twMerge(clsx(inputs));
18
18
  }
19
- function formatDate(date, options = {
20
- year: "numeric",
21
- month: "long",
22
- day: "numeric"
23
- }) {
24
- const dateObj = typeof date === "string" ? new Date(date) : date;
25
- if (isNaN(dateObj.getTime())) {
26
- console.warn("Invalid date provided to formatDate:", date);
27
- return "Invalid Date";
28
- }
29
- return dateObj.toLocaleDateString("en-US", options);
30
- }
31
- function formatNumber(num) {
32
- return num.toLocaleString();
33
- }
34
- function formatPrice(price, currency = "USD") {
35
- return new Intl.NumberFormat("en-US", {
36
- style: "currency",
37
- currency
38
- }).format(price);
39
- }
40
- function formatBytes(bytes, decimals = 2) {
41
- if (bytes === 0) return "0 Bytes";
42
- const k = 1024;
43
- const dm = decimals < 0 ? 0 : decimals;
44
- const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
45
- const i = Math.floor(Math.log(bytes) / Math.log(k));
46
- return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
47
- }
48
19
  function getPlatformProductionUrl(platform) {
49
20
  switch (platform) {
50
21
  // *-hub platforms — env var convention: NEXT_PUBLIC_<NAME>_HUB_URL
@@ -127,6 +98,304 @@ function getBaseUrl(platform) {
127
98
  }
128
99
  return "https://www.openmsp.ai";
129
100
  }
101
+
102
+ // src/utils/format.ts
103
+ function formatDate(date, options = {
104
+ year: "numeric",
105
+ month: "long",
106
+ day: "numeric"
107
+ }) {
108
+ const dateObj = typeof date === "string" ? new Date(date) : date;
109
+ if (isNaN(dateObj.getTime())) {
110
+ console.warn("Invalid date provided to formatDate:", date);
111
+ return "Invalid Date";
112
+ }
113
+ return dateObj.toLocaleDateString("en-US", options);
114
+ }
115
+ function formatNumber(num) {
116
+ return num.toLocaleString();
117
+ }
118
+ function formatPrice(price, currency = "USD") {
119
+ return new Intl.NumberFormat("en-US", {
120
+ style: "currency",
121
+ currency
122
+ }).format(price);
123
+ }
124
+ function formatBytes(bytes, decimals = 2) {
125
+ if (bytes === 0) return "0 Bytes";
126
+ const k = 1024;
127
+ const dm = decimals < 0 ? 0 : decimals;
128
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
129
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
130
+ return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
131
+ }
132
+ function formatBytesShort(bytes) {
133
+ if (bytes === 0) return "0 B";
134
+ const k = 1024;
135
+ const sizes = ["B", "KB", "MB", "GB", "TB"];
136
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
137
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
138
+ }
139
+ function formatLargeNumber(num) {
140
+ if (num === 0) return "0";
141
+ const isNegative = num < 0;
142
+ const absNum = Math.abs(num);
143
+ let result;
144
+ if (absNum >= 1e9) {
145
+ result = `${Math.floor(absNum / 1e9)}B`;
146
+ } else if (absNum >= 1e6) {
147
+ result = `${Math.floor(absNum / 1e6)}M`;
148
+ } else if (absNum >= 1e3) {
149
+ result = `${Math.floor(absNum / 1e3)}K`;
150
+ } else {
151
+ result = Math.floor(absNum).toString();
152
+ }
153
+ return isNegative ? `-${result}` : result;
154
+ }
155
+ function formatAbbreviatedNumber(n) {
156
+ if (n >= 1e9) {
157
+ const value = n / 1e9;
158
+ return `${Number.isInteger(value) ? value.toFixed(0) : value.toFixed(1)}B`;
159
+ }
160
+ if (n >= 1e6) {
161
+ const value = n / 1e6;
162
+ return `${Number.isInteger(value) ? value.toFixed(0) : value.toFixed(1)}M`;
163
+ }
164
+ if (n >= 1e3) {
165
+ const value = n / 1e3;
166
+ return `${Number.isInteger(value) ? value.toFixed(0) : value.toFixed(1)}K`;
167
+ }
168
+ return n.toLocaleString();
169
+ }
170
+ function getFirstLastInitials(name) {
171
+ if (!name) return "";
172
+ const words = name.trim().split(/\s+/);
173
+ if (words.length === 0 || !words[0]) return "";
174
+ if (words.length === 1) return words[0].charAt(0).toUpperCase();
175
+ return (words[0].charAt(0) + words[words.length - 1].charAt(0)).toUpperCase();
176
+ }
177
+ function nameInitials(name, fallback = "E") {
178
+ const source = typeof name === "string" ? name.trim() : "";
179
+ const words = source.length > 0 ? source.split(/\s+/) : [];
180
+ const letters = words.map((w) => w[0]).filter(Boolean).slice(0, 2).join("");
181
+ return (letters || fallback).toUpperCase();
182
+ }
183
+ function formatDurationMMSS(seconds) {
184
+ if (!seconds) return "";
185
+ const hours = Math.floor(seconds / 3600);
186
+ const minutes = Math.floor(seconds % 3600 / 60);
187
+ const secs = Math.floor(seconds % 60);
188
+ if (hours > 0) {
189
+ return `${hours}:${minutes.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
190
+ }
191
+ return `${minutes}:${secs.toString().padStart(2, "0")}`;
192
+ }
193
+ function formatDurationCompact(seconds) {
194
+ if (!seconds) return "";
195
+ const hours = Math.floor(seconds / 3600);
196
+ const minutes = Math.floor(seconds % 3600 / 60);
197
+ if (hours > 0) {
198
+ return `${hours}h ${minutes}m`;
199
+ }
200
+ return `${minutes} min`;
201
+ }
202
+ function formatTimeWithTimezone(date, timezone) {
203
+ if (!date) return "";
204
+ const dateObj = typeof date === "string" ? new Date(date) : date;
205
+ const timeStr = dateObj.toLocaleTimeString("en-US", {
206
+ hour: "numeric",
207
+ minute: "2-digit",
208
+ hour12: true
209
+ });
210
+ return timezone ? `${timeStr} ${timezone}` : timeStr;
211
+ }
212
+ function formatDurationFromRange(startAt, endAt) {
213
+ if (!startAt || !endAt) return "";
214
+ const start = typeof startAt === "string" ? new Date(startAt) : startAt;
215
+ const end = typeof endAt === "string" ? new Date(endAt) : endAt;
216
+ const durationMs = end.getTime() - start.getTime();
217
+ const minutes = Math.round(durationMs / 6e4);
218
+ if (minutes >= 60) {
219
+ const hours = Math.floor(minutes / 60);
220
+ const mins = minutes % 60;
221
+ return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
222
+ }
223
+ return `${minutes}m`;
224
+ }
225
+ function formatDateUTC(value, options = {}) {
226
+ const { fallback = "N/A", timezone = "UTC" } = options;
227
+ if (value === null || value === void 0 || value === "") return fallback;
228
+ let ms;
229
+ if (typeof value === "number") {
230
+ ms = value;
231
+ } else {
232
+ const n = Number(value);
233
+ if (Number.isFinite(n) && n > 0 && /^-?\d+(\.\d+)?$/.test(value.trim())) {
234
+ ms = n;
235
+ } else {
236
+ ms = Date.parse(value.includes("T") ? value : value + "T00:00:00Z");
237
+ }
238
+ }
239
+ if (!Number.isFinite(ms)) return fallback;
240
+ return new Date(ms).toLocaleDateString("en-US", {
241
+ year: "numeric",
242
+ month: "short",
243
+ day: "numeric",
244
+ timeZone: timezone === "local" ? void 0 : "UTC"
245
+ });
246
+ }
247
+ function formatLegalDate(dateInput) {
248
+ return new Intl.DateTimeFormat("en-US", {
249
+ year: "numeric",
250
+ month: "2-digit",
251
+ day: "2-digit"
252
+ }).format(new Date(dateInput));
253
+ }
254
+ function formatCurrency(value) {
255
+ if (value == null) return "N/A";
256
+ return new Intl.NumberFormat("en-US", {
257
+ style: "currency",
258
+ currency: "USD",
259
+ maximumFractionDigits: 0
260
+ }).format(value);
261
+ }
262
+ function formatPercent(value) {
263
+ if (value == null) return "N/A";
264
+ return `${value.toFixed(2)}%`;
265
+ }
266
+ function formatWholeDollars(price, currency = "USD") {
267
+ return new Intl.NumberFormat("en-US", {
268
+ style: "currency",
269
+ currency,
270
+ maximumFractionDigits: 0
271
+ }).format(price);
272
+ }
273
+ function formatCompactMetric(value, format = "number", options) {
274
+ if (value === 0 || value === null || value === void 0) {
275
+ if (format === "currency") return `${options?.prefix || "$"}0`;
276
+ if (format === "percentage") return "0%";
277
+ if (format === "months") return `0 ${options?.suffix || "months"}`;
278
+ return "0";
279
+ }
280
+ const absValue = Math.abs(value);
281
+ const sign = value < 0 ? "-" : "";
282
+ if (format === "currency") {
283
+ const prefix = options?.prefix || "$";
284
+ const compact = (val, divisor, suffix) => {
285
+ const divided = val / divisor;
286
+ const formatted = divided % 1 === 0 ? divided.toFixed(0) : divided.toFixed(1);
287
+ return `${sign}${prefix}${formatted}${suffix}`;
288
+ };
289
+ if (absValue >= 1e9) return compact(absValue, 1e9, "B");
290
+ if (absValue >= 1e6) return compact(absValue, 1e6, "M");
291
+ if (absValue >= 1e3) return `${sign}${prefix}${(absValue / 1e3).toFixed(0)}K`;
292
+ return `${sign}${prefix}${absValue.toLocaleString()}`;
293
+ }
294
+ if (format === "percentage") {
295
+ return `${sign}${absValue}%`;
296
+ }
297
+ if (format === "months") {
298
+ const rounded = Math.round(value * 10) / 10;
299
+ return `${rounded} ${options?.suffix || "months"}`;
300
+ }
301
+ if (absValue >= 1e6) return `${sign}${(absValue / 1e6).toFixed(1)}M`;
302
+ if (absValue >= 1e3) return `${sign}${(absValue / 1e3).toFixed(1)}K`;
303
+ return value.toLocaleString();
304
+ }
305
+ function getTrendColors(direction, polarity = "positive") {
306
+ if (direction === "neutral" || polarity === "neutral") {
307
+ return {
308
+ textClass: "text-ods-text-secondary",
309
+ badgeClass: "bg-ods-border text-ods-text-secondary"
310
+ };
311
+ }
312
+ const isPositiveOutcome = direction === "up" && polarity === "positive" || direction === "down" && polarity === "negative";
313
+ if (isPositiveOutcome) {
314
+ return {
315
+ textClass: "text-ods-success",
316
+ badgeClass: "bg-ods-success-secondary text-ods-success"
317
+ };
318
+ }
319
+ return {
320
+ textClass: "text-ods-error",
321
+ badgeClass: "bg-ods-error-secondary text-ods-error"
322
+ };
323
+ }
324
+ function formatDateRange(start, end) {
325
+ if (!start || !end) return "";
326
+ const fmt = (s) => {
327
+ const bareMatch = /^(\d{4})-(\d{2})-(\d{2})$/.exec(s);
328
+ const d = bareMatch ? new Date(Number(bareMatch[1]), Number(bareMatch[2]) - 1, Number(bareMatch[3])) : new Date(s);
329
+ if (Number.isNaN(d.getTime())) return s;
330
+ return d.toLocaleDateString(void 0, {
331
+ month: "short",
332
+ day: "numeric",
333
+ year: "numeric"
334
+ });
335
+ };
336
+ return `${fmt(start)} \u2014 ${fmt(end)}`;
337
+ }
338
+ function formatDateTimeAt(dateString) {
339
+ const date = new Date(dateString);
340
+ const dateStr = date.toLocaleDateString("en-US", {
341
+ month: "short",
342
+ day: "numeric",
343
+ year: "numeric"
344
+ });
345
+ const timeStr = date.toLocaleTimeString("en-US", {
346
+ hour: "numeric",
347
+ minute: "2-digit",
348
+ hour12: true
349
+ });
350
+ return `${dateStr} at ${timeStr}`;
351
+ }
352
+ function formatDurationFromMs(ms) {
353
+ if (!ms || isNaN(ms) || ms < 0) return "0ms";
354
+ if (ms < 1e3) return `${ms}ms`;
355
+ if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
356
+ return `${(ms / 6e4).toFixed(1)}m`;
357
+ }
358
+ function formatDuration(seconds) {
359
+ if (seconds < 60) return `${seconds} seconds`;
360
+ if (seconds < 3600) return `${Math.floor(seconds / 60)} minutes`;
361
+ const hours = Math.floor(seconds / 3600);
362
+ const minutes = Math.floor(seconds % 3600 / 60);
363
+ if (minutes === 0) return `${hours} hour${hours > 1 ? "s" : ""}`;
364
+ return `${hours} hour${hours > 1 ? "s" : ""} ${minutes} minute${minutes > 1 ? "s" : ""}`;
365
+ }
366
+ function formatUnderscoreText(text) {
367
+ return text.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
368
+ }
369
+ function stripHtml(html) {
370
+ let noTags = html;
371
+ let prev;
372
+ do {
373
+ prev = noTags;
374
+ noTags = noTags.replace(/<[^<>]*>/g, "");
375
+ } while (noTags !== prev);
376
+ return noTags.replace(/&nbsp;/g, " ").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&#x27;/g, "'").replace(/&apos;/g, "'").replace(/&amp;/g, "&").replace(/\s+/g, " ").trim();
377
+ }
378
+ function formatClassification(classification) {
379
+ const customMappings = {
380
+ openframe_selected: "OpenFrame Selected"
381
+ };
382
+ return customMappings[classification] || formatUnderscoreText(classification);
383
+ }
384
+ function formatPricingModel(pricingModel) {
385
+ const customMappings = {
386
+ one_time: "One-time Purchase",
387
+ self_hosted: "Self-hosted"
388
+ };
389
+ return customMappings[pricingModel] || formatUnderscoreText(pricingModel);
390
+ }
391
+ function formatBioText(aboutHtml, fallback = "") {
392
+ if (!aboutHtml || !aboutHtml.trim()) return fallback;
393
+ if (aboutHtml.includes("<p")) {
394
+ const paragraphs = aboutHtml.split(/<p[^<>]*>/).slice(1).map((part) => part.split("</p>")[0]).map((text) => stripHtml(text).trim()).filter((text) => text.length > 0);
395
+ if (paragraphs.length > 0) return paragraphs.join(" ");
396
+ }
397
+ return stripHtml(aboutHtml).trim() || fallback;
398
+ }
130
399
  var PLAY_ICON_PATH = "M4.875 5.006c0-2.501 2.793-3.989 4.87-2.592l9.78 6.578c2.135 1.437 2.135 4.58 0 6.016l-9.78 6.579c-2.077 1.396-4.87-.091-4.87-2.593zm2.25 13.988c0 .7.783 1.118 1.364.727l9.78-6.58c.81-.545.81-1.738 0-2.283L8.488 4.28a.875.875 0 0 0-1.364.726v13.988Z";
131
400
 
132
401
  // src/utils/ods-color-utils.ts
@@ -369,6 +638,25 @@ function ShellIcon({ className = "w-5 h-5", size = 22, color = "white" }) {
369
638
  }
370
639
  );
371
640
  }
641
+ var GitHubIcon = ({
642
+ className = "",
643
+ width = 15,
644
+ height = 14,
645
+ color = "white"
646
+ }) => {
647
+ return /* @__PURE__ */ jsx(
648
+ "svg",
649
+ {
650
+ width,
651
+ height,
652
+ viewBox: "0 0 15 14",
653
+ fill: "none",
654
+ xmlns: "http://www.w3.org/2000/svg",
655
+ className,
656
+ children: /* @__PURE__ */ jsx("path", { d: "M7.18173 0.333008C3.40523 0.333008 0.346436 3.3918 0.346436 7.1683C0.346436 10.1929 2.30304 12.7476 5.02007 13.6533C5.36183 13.7131 5.48999 13.508 5.48999 13.3286C5.48999 13.1663 5.48145 12.628 5.48145 12.0555C3.76408 12.3717 3.31979 11.6369 3.18308 11.2524C3.10618 11.0559 2.77296 10.4492 2.48246 10.2869C2.24323 10.1587 1.90146 9.84261 2.47392 9.83406C3.0122 9.82552 3.39668 10.3296 3.52485 10.5347C4.14002 11.5685 5.1226 11.278 5.51563 11.0986C5.57543 10.6543 5.75486 10.3553 5.95137 10.1844C4.43052 10.0135 2.84132 9.42395 2.84132 6.80945C2.84132 6.06611 3.10618 5.45093 3.54193 4.97246C3.47358 4.80158 3.23435 4.10096 3.61029 3.16111C3.61029 3.16111 4.18274 2.98168 5.48999 3.86173C6.03682 3.70793 6.61782 3.63104 7.19882 3.63104C7.77982 3.63104 8.36082 3.70793 8.90764 3.86173C10.2149 2.97314 10.7873 3.16111 10.7873 3.16111C11.1633 4.10096 10.9241 4.80158 10.8557 4.97246C11.2914 5.45093 11.5563 6.05757 11.5563 6.80945C11.5563 9.43249 9.95856 10.0135 8.43771 10.1844C8.68549 10.398 8.8991 10.8081 8.8991 11.4489C8.8991 12.3631 8.89055 13.0979 8.89055 13.3286C8.89055 13.508 9.01871 13.7216 9.36048 13.6533C10.7174 13.1952 11.8965 12.3231 12.7318 11.1597C13.5671 9.99643 14.0166 8.60046 14.017 7.1683C14.017 3.3918 10.9582 0.333008 7.18173 0.333008Z", fill: color })
657
+ }
658
+ );
659
+ };
372
660
  function SlackIcon({
373
661
  width = 24,
374
662
  height = 24,
@@ -421,6 +709,53 @@ function SlackIcon({
421
709
  }
422
710
  );
423
711
  }
712
+ function ClickUpIcon({
713
+ width = 24,
714
+ height = 24,
715
+ className = ""
716
+ }) {
717
+ return /* @__PURE__ */ jsxs(
718
+ "svg",
719
+ {
720
+ width,
721
+ height,
722
+ viewBox: "0 0 54.8 65.8",
723
+ fill: "none",
724
+ xmlns: "http://www.w3.org/2000/svg",
725
+ className,
726
+ children: [
727
+ /* @__PURE__ */ jsxs("defs", { children: [
728
+ /* @__PURE__ */ jsxs("linearGradient", { id: "clickup-grad-1", gradientUnits: "userSpaceOnUse", x1: "0", y1: "15.0492", x2: "54.8446", y2: "15.0492", gradientTransform: "matrix(1 0 0 -1 0 69.3604)", children: [
729
+ /* @__PURE__ */ jsx("stop", { offset: "0", stopColor: "#8930FD" }),
730
+ /* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#49CCF9" })
731
+ ] }),
732
+ /* @__PURE__ */ jsxs("linearGradient", { id: "clickup-grad-2", gradientUnits: "userSpaceOnUse", x1: "1.1953", y1: "53.166", x2: "53.7447", y2: "53.166", gradientTransform: "matrix(1 0 0 -1 0 69.3604)", children: [
733
+ /* @__PURE__ */ jsx("stop", { offset: "0", stopColor: "#FF02F0" }),
734
+ /* @__PURE__ */ jsx("stop", { offset: "1", stopColor: "#FFC800" })
735
+ ] })
736
+ ] }),
737
+ /* @__PURE__ */ jsx(
738
+ "path",
739
+ {
740
+ fillRule: "evenodd",
741
+ clipRule: "evenodd",
742
+ d: "M0,50.6l10.1-7.8c5.4,7,11.1,10.3,17.4,10.3c6.3,0,11.9-3.2,17-10.2l10.3,7.6c-7.4,10-16.6,15.3-27.3,15.3 C16.9,65.8,7.6,60.5,0,50.6z",
743
+ fill: "url(#clickup-grad-1)"
744
+ }
745
+ ),
746
+ /* @__PURE__ */ jsx(
747
+ "path",
748
+ {
749
+ fillRule: "evenodd",
750
+ clipRule: "evenodd",
751
+ d: "M27.5,16.9l-18,15.5l-8.3-9.7L27.6,0l26.2,22.7l-8.4,9.6L27.5,16.9z",
752
+ fill: "url(#clickup-grad-2)"
753
+ }
754
+ )
755
+ ]
756
+ }
757
+ );
758
+ }
424
759
  function XLogo({ className = "", color = "white", ...props }) {
425
760
  return /* @__PURE__ */ jsxs(
426
761
  "svg",
@@ -439,6 +774,19 @@ function XLogo({ className = "", color = "white", ...props }) {
439
774
  }
440
775
  );
441
776
  }
777
+ function HubspotIcon({ className, fill = "#FF7A59", ...props }) {
778
+ return /* @__PURE__ */ jsx(
779
+ "svg",
780
+ {
781
+ xmlns: "http://www.w3.org/2000/svg",
782
+ viewBox: "0 0 512 512",
783
+ fill,
784
+ className: cn("inline-block", className),
785
+ ...props,
786
+ children: /* @__PURE__ */ jsx("path", { d: "M266.197 216.109c-22.551 21.293-36.655 51.48-36.655 84.991 0 26.326 8.714 50.582 23.359 70.08l-44.473 44.74c-3.953-1.438-8.176-2.245-12.579-2.245-9.702 0-18.776 3.774-25.605 10.602-6.828 6.827-10.602 15.989-10.602 25.696 0 9.701 3.773 18.775 10.602 25.605 6.829 6.826 15.993 10.42 25.605 10.42 9.703 0 18.777-3.505 25.695-10.42 6.829-6.83 10.602-15.994 10.602-25.605 0-3.774-.538-7.369-1.707-10.873l44.923-45.102c19.765 15.183 44.381 24.169 71.244 24.169 64.599 0 116.797-52.38 116.797-116.977 0-58.578-42.854-107.093-99.007-115.628v-55.343c15.723-6.65 25.335-21.384 25.335-38.545 0-23.449-18.777-43.034-42.227-43.034-23.448 0-41.956 19.585-41.956 43.034 0 17.161 9.613 31.895 25.335 38.545v54.983c-13.655 1.887-26.593 6.019-38.362 12.219-24.796-18.778-105.565-76.997-151.746-112.126 1.078-3.953 1.798-8.085 1.798-12.397 0-25.875-21.113-46.898-47.078-46.898-25.875 0-46.898 21.023-46.898 46.898 0 25.965 21.023 46.988 46.898 46.988 8.805 0 16.98-2.606 24.078-6.828L266.197 216.109zM346.606 363.095c-34.229 0-61.991-27.763-61.991-61.994 0-34.229 27.762-61.99 61.991-61.99 34.23 0 61.992 27.761 61.992 61.99 0 34.231-27.762 61.994-61.992 61.994z" })
787
+ }
788
+ );
789
+ }
442
790
  function LinkedInIcon({ className = "", size = 24, color = "white", ...props }) {
443
791
  return /* @__PURE__ */ jsx(
444
792
  "svg",
@@ -860,9 +1208,11 @@ var OS_PLATFORMS = [
860
1208
  { id: "darwin", name: "MacOS", icon: MacOSIcon }
861
1209
  ];
862
1210
  var DEFAULT_OS_PLATFORM = "windows";
863
- async function validateAccessCode(email, code) {
1211
+
1212
+ // src/utils/access-code-client.ts
1213
+ async function validateAccessCode(email, code, endpoints) {
864
1214
  try {
865
- const response = await fetch("/api/validate-access-code", {
1215
+ const response = await fetch(endpoints.validateUrl, {
866
1216
  method: "POST",
867
1217
  headers: {
868
1218
  "Content-Type": "application/json"
@@ -881,9 +1231,9 @@ async function validateAccessCode(email, code) {
881
1231
  };
882
1232
  }
883
1233
  }
884
- async function consumeAccessCode(email, code) {
1234
+ async function consumeAccessCode(email, code, endpoints) {
885
1235
  try {
886
- const response = await fetch("/api/consume-access-code", {
1236
+ const response = await fetch(endpoints.consumeUrl, {
887
1237
  method: "POST",
888
1238
  headers: {
889
1239
  "Content-Type": "application/json"
@@ -903,56 +1253,18 @@ async function consumeAccessCode(email, code) {
903
1253
  };
904
1254
  }
905
1255
  }
906
- async function validateAndConsumeAccessCode(email, code) {
907
- const validation = await validateAccessCode(email, code);
1256
+ async function validateAndConsumeAccessCode(email, code, endpoints) {
1257
+ const validation = await validateAccessCode(email, code, endpoints);
908
1258
  if (!validation.valid) {
909
1259
  return validation;
910
1260
  }
911
- const consumption = await consumeAccessCode(email, code);
1261
+ const consumption = await consumeAccessCode(email, code, endpoints);
912
1262
  return {
913
1263
  ...validation,
914
1264
  consumed: consumption.consumed,
915
1265
  message: consumption.consumed ? `Access granted for ${validation.cohort_name}` : consumption.message || validation.message
916
1266
  };
917
1267
  }
918
- function useAccessCodeIntegration() {
919
- const [isValidating, setIsValidating] = React2.useState(false);
920
- const [isConsuming, setIsConsuming] = React2.useState(false);
921
- const validate = async (email, code) => {
922
- setIsValidating(true);
923
- try {
924
- return await validateAccessCode(email, code);
925
- } finally {
926
- setIsValidating(false);
927
- }
928
- };
929
- const consume = async (email, code) => {
930
- setIsConsuming(true);
931
- try {
932
- return await consumeAccessCode(email, code);
933
- } finally {
934
- setIsConsuming(false);
935
- }
936
- };
937
- const validateAndConsume = async (email, code) => {
938
- setIsValidating(true);
939
- setIsConsuming(true);
940
- try {
941
- return await validateAndConsumeAccessCode(email, code);
942
- } finally {
943
- setIsValidating(false);
944
- setIsConsuming(false);
945
- }
946
- };
947
- return {
948
- validate,
949
- consume,
950
- validateAndConsume,
951
- isValidating,
952
- isConsuming,
953
- isProcessing: isValidating || isConsuming
954
- };
955
- }
956
1268
 
957
1269
  // src/utils/validation-utils.ts
958
1270
  function isValidEmailDomain(domain) {
@@ -1067,51 +1379,173 @@ function getConfidenceLabel(confidence) {
1067
1379
  }
1068
1380
 
1069
1381
  // src/utils/date-formatters.ts
1382
+ var MONTHS_LONG = [
1383
+ "January",
1384
+ "February",
1385
+ "March",
1386
+ "April",
1387
+ "May",
1388
+ "June",
1389
+ "July",
1390
+ "August",
1391
+ "September",
1392
+ "October",
1393
+ "November",
1394
+ "December"
1395
+ ];
1396
+ var MONTHS_SHORT = [
1397
+ "Jan",
1398
+ "Feb",
1399
+ "Mar",
1400
+ "Apr",
1401
+ "May",
1402
+ "Jun",
1403
+ "Jul",
1404
+ "Aug",
1405
+ "Sep",
1406
+ "Oct",
1407
+ "Nov",
1408
+ "Dec"
1409
+ ];
1410
+ function splitYmd(dateString) {
1411
+ const head = dateString.split("T")[0];
1412
+ const parts = head.split("-");
1413
+ if (parts.length !== 3) return null;
1414
+ return [parts[0], parts[1], parts[2]];
1415
+ }
1070
1416
  function formatReleaseDate(dateString) {
1071
- const [year, month, day] = dateString.split("T")[0].split("-");
1072
- const monthNames = [
1073
- "January",
1074
- "February",
1075
- "March",
1076
- "April",
1077
- "May",
1078
- "June",
1079
- "July",
1080
- "August",
1081
- "September",
1082
- "October",
1083
- "November",
1084
- "December"
1085
- ];
1086
- return `${monthNames[parseInt(month) - 1]} ${parseInt(day)}, ${year}`;
1417
+ const ymd = splitYmd(dateString);
1418
+ if (!ymd) return dateString;
1419
+ const [year, month, day] = ymd;
1420
+ return `${MONTHS_LONG[parseInt(month) - 1]} ${parseInt(day)}, ${year}`;
1421
+ }
1422
+ function formatDateShort(dateString) {
1423
+ const ymd = splitYmd(dateString);
1424
+ if (!ymd) return dateString;
1425
+ const [year, month, day] = ymd;
1426
+ return `${MONTHS_SHORT[parseInt(month) - 1]} ${parseInt(day)}, ${year}`;
1427
+ }
1428
+ function formatDateSlashUTC(dateString) {
1429
+ const ymd = splitYmd(dateString);
1430
+ if (!ymd) return dateString;
1431
+ const [year, month, day] = ymd;
1432
+ return `${month}/${day}/${year}`;
1433
+ }
1434
+ var OpenFrameLogoIcon = ({ className }) => createElement(OpenFrameLogo, { className, upperPathColor: "currentColor" });
1435
+ var ICON_REGISTRY = {
1436
+ // lucide-react (kebab-case)
1437
+ activity: Activity,
1438
+ banknote: Banknote,
1439
+ bell: Bell,
1440
+ "book-open": BookOpen,
1441
+ box: Box,
1442
+ briefcase: Briefcase,
1443
+ calendar: Calendar,
1444
+ "check-square": CheckSquare,
1445
+ "dollar-sign": DollarSign,
1446
+ // For brand-vs-lucide variants the kebab key is the BRAND (most-common
1447
+ // social-platform intent); `'<name>-lucide'` carries the lucide outline.
1448
+ facebook: FacebookIcon,
1449
+ "facebook-lucide": Facebook,
1450
+ "file-text": FileText,
1451
+ // `'github-lucide'` is the lucide outline glyph (used by
1452
+ // `social_platforms.icon_name='Github'`); `'github'` is the brand icon
1453
+ // (used by `chat_admin_slash_commands.icon_name='github'`). The PascalCase
1454
+ // alias `'Github' → 'github-lucide'` routes the lucide glyph for
1455
+ // social-platform DB rows; `'GitHubIcon' → 'github'` keeps brand routing
1456
+ // consistent for callers that store the PascalCase component name.
1457
+ github: GitHubIcon,
1458
+ "github-lucide": Github,
1459
+ globe: Globe,
1460
+ "graduation-cap": GraduationCap,
1461
+ headphones: Headphones,
1462
+ info: Info,
1463
+ instagram: InstagramIcon,
1464
+ "instagram-lucide": Instagram,
1465
+ mail: Mail,
1466
+ megaphone: Megaphone,
1467
+ "message-circle": MessageCircle,
1468
+ "message-square": MessageSquare,
1469
+ newspaper: Newspaper,
1470
+ package: Package,
1471
+ "pen-square": PenSquare,
1472
+ rocket: Rocket,
1473
+ search: Search,
1474
+ send: Send,
1475
+ shield: Shield,
1476
+ star: Star,
1477
+ table: TableProperties,
1478
+ "trending-up": TrendingUp,
1479
+ twitter: Twitter,
1480
+ users: Users,
1481
+ video: Video,
1482
+ youtube: YouTubeIcon,
1483
+ "youtube-lucide": Youtube,
1484
+ // brand-only icons (no lucide variant in current use)
1485
+ slack: SlackIcon,
1486
+ clickup: ClickUpIcon,
1487
+ hubspot: HubspotIcon,
1488
+ linkedin: LinkedInIcon,
1489
+ x: XLogo,
1490
+ openframe: OpenFrameLogoIcon
1491
+ };
1492
+ var PASCAL_TO_KEBAB_ALIASES = {
1493
+ // Lucide PascalCase names → kebab equivalents
1494
+ Activity: "activity",
1495
+ Banknote: "banknote",
1496
+ Bell: "bell",
1497
+ BookOpen: "book-open",
1498
+ Box: "box",
1499
+ Briefcase: "briefcase",
1500
+ Calendar: "calendar",
1501
+ CheckSquare: "check-square",
1502
+ DollarSign: "dollar-sign",
1503
+ // Lucide PascalCase → the `-lucide` kebab variant (kebab default is the
1504
+ // brand icon for the social-platform names below).
1505
+ Facebook: "facebook-lucide",
1506
+ FileText: "file-text",
1507
+ Github: "github-lucide",
1508
+ Globe: "globe",
1509
+ GraduationCap: "graduation-cap",
1510
+ Headphones: "headphones",
1511
+ Info: "info",
1512
+ Instagram: "instagram-lucide",
1513
+ Mail: "mail",
1514
+ Megaphone: "megaphone",
1515
+ MessageCircle: "message-circle",
1516
+ MessageSquare: "message-square",
1517
+ Newspaper: "newspaper",
1518
+ Package: "package",
1519
+ PenSquare: "pen-square",
1520
+ Rocket: "rocket",
1521
+ Search: "search",
1522
+ Send: "send",
1523
+ Shield: "shield",
1524
+ Star: "star",
1525
+ TableProperties: "table",
1526
+ TrendingUp: "trending-up",
1527
+ Twitter: "twitter",
1528
+ Users: "users",
1529
+ Video: "video",
1530
+ Youtube: "youtube-lucide",
1531
+ // Brand-icon PascalCase exports → kebab (kebab default is the brand)
1532
+ SlackIcon: "slack",
1533
+ GitHubIcon: "github",
1534
+ ClickUpIcon: "clickup",
1535
+ HubspotIcon: "hubspot",
1536
+ LinkedInIcon: "linkedin",
1537
+ FacebookIcon: "facebook",
1538
+ InstagramIcon: "instagram",
1539
+ YouTubeIcon: "youtube",
1540
+ XLogo: "x",
1541
+ OpenFrameLogo: "openframe"
1542
+ };
1543
+ function normalizeIconKey(key) {
1544
+ return PASCAL_TO_KEBAB_ALIASES[key] ?? key;
1087
1545
  }
1088
-
1089
- // src/utils/format-relative-time.ts
1090
- function formatRelativeTime(timestamp) {
1091
- if (!timestamp) return "Not scheduled";
1092
- const date = new Date(timestamp);
1093
- if (isNaN(date.getTime())) return "Invalid date";
1094
- const now = /* @__PURE__ */ new Date();
1095
- const diffMs = now.getTime() - date.getTime();
1096
- const diffSecs = Math.floor(diffMs / 1e3);
1097
- const diffMins = Math.floor(diffSecs / 60);
1098
- const diffHours = Math.floor(diffMins / 60);
1099
- const diffDays = Math.floor(diffHours / 24);
1100
- if (diffMs < 0) {
1101
- const absDiffSecs = Math.abs(diffSecs);
1102
- const absDiffMins = Math.floor(absDiffSecs / 60);
1103
- const absDiffHours = Math.floor(absDiffMins / 60);
1104
- const absDiffDays = Math.floor(absDiffHours / 24);
1105
- if (absDiffDays > 0) return `in ${absDiffDays} day${absDiffDays === 1 ? "" : "s"}`;
1106
- if (absDiffHours > 0) return `in ${absDiffHours} hour${absDiffHours === 1 ? "" : "s"}`;
1107
- if (absDiffMins > 0) return `in ${absDiffMins} minute${absDiffMins === 1 ? "" : "s"}`;
1108
- return `in ${absDiffSecs} second${absDiffSecs === 1 ? "" : "s"}`;
1109
- }
1110
- if (diffDays > 0) return `${diffDays} day${diffDays === 1 ? "" : "s"} ago`;
1111
- if (diffHours > 0) return `${diffHours} hour${diffHours === 1 ? "" : "s"} ago`;
1112
- if (diffMins > 0) return `${diffMins} minute${diffMins === 1 ? "" : "s"} ago`;
1113
- if (diffSecs > 0) return `${diffSecs} second${diffSecs === 1 ? "" : "s"}`;
1114
- return "just now";
1546
+ function getIconComponent(iconName) {
1547
+ if (!iconName) return FileText;
1548
+ return ICON_REGISTRY[normalizeIconKey(iconName)] ?? FileText;
1115
1549
  }
1116
1550
  var SIZE_CLASSES = {
1117
1551
  xs: "w-3 h-3",
@@ -1126,52 +1560,28 @@ var SIZE_CLASSES = {
1126
1560
  // 48px
1127
1561
  };
1128
1562
  var ICON_COLORS = {
1129
- LinkedInIcon: { color: "#0A66C2" },
1130
- FacebookIcon: { color: "#1877F2" },
1131
- YouTubeIcon: { color: "#FF0000" },
1132
- OpenFrameLogo: {
1133
- /* Uses component defaults */
1134
- }
1135
- };
1136
- var ICON_REGISTRY = {
1137
- // UI Kit social platform icons (from @flamingo/ui-kit/components/icons)
1138
- LinkedInIcon,
1139
- FacebookIcon,
1140
- InstagramIcon,
1141
- YouTubeIcon,
1142
- SlackIcon,
1143
- XLogo,
1144
- // Lucide icons (from lucide-react)
1145
- Globe: Globe,
1146
- FileText,
1147
- // Blog Posts icon (internal-blogging)
1148
- PenSquare,
1149
- // Alternative blog icon
1150
- Github,
1151
- // GitHub platform
1152
- MessageCircle,
1153
- // Discord platform
1154
- Send,
1155
- // Telegram platform
1156
- Video,
1157
- // TikTok platform
1158
- Twitter
1159
- // Twitter/X platform
1563
+ linkedin: { color: "#0A66C2" },
1564
+ facebook: { color: "#1877F2" },
1565
+ youtube: { color: "#FF0000" }
1160
1566
  };
1161
1567
  function getDynamicIcon(iconName, size = "md", className) {
1162
1568
  if (!iconName) {
1163
1569
  console.warn("[getDynamicIcon] No iconName provided, using Globe fallback");
1164
- return /* @__PURE__ */ jsx(Globe, { className: SIZE_CLASSES[size] });
1570
+ return createElement(Globe, { className: SIZE_CLASSES[size] });
1165
1571
  }
1166
1572
  const sizeClass = SIZE_CLASSES[size];
1167
1573
  const finalClassName = className ? `${sizeClass} ${className}` : sizeClass;
1168
- const IconComponent = ICON_REGISTRY[iconName];
1574
+ const canonicalKey = normalizeIconKey(iconName);
1575
+ const IconComponent = ICON_REGISTRY[canonicalKey];
1169
1576
  if (IconComponent) {
1170
- const colorConfig = ICON_COLORS[iconName] || {};
1171
- return /* @__PURE__ */ jsx(IconComponent, { className: finalClassName, ...colorConfig });
1577
+ const colorConfig = ICON_COLORS[canonicalKey] || {};
1578
+ return createElement(IconComponent, { className: finalClassName, ...colorConfig });
1172
1579
  }
1173
- console.error(`[getDynamicIcon] Icon NOT found in registry: "${iconName}". Available icons:`, Object.keys(ICON_REGISTRY));
1174
- return /* @__PURE__ */ jsx(Globe, { className: finalClassName });
1580
+ console.error(
1581
+ `[getDynamicIcon] Icon NOT found in registry: "${iconName}" (normalized to "${canonicalKey}"). Available icons:`,
1582
+ Object.keys(ICON_REGISTRY)
1583
+ );
1584
+ return createElement(Globe, { className: finalClassName });
1175
1585
  }
1176
1586
 
1177
1587
  // src/types/tool.types.ts
@@ -1661,6 +2071,639 @@ function isGenericWebsiteDomain(website) {
1661
2071
  return isGenericDomain(normalizeDomain(website));
1662
2072
  }
1663
2073
 
1664
- export { DEFAULT_OS_PLATFORM, GENERIC_EMAIL_DOMAINS, OS_PLATFORMS, PLAY_ICON_PATH, cleanEmailDomain, cn, consumeAccessCode, deepClone, delay, extractDomainFromEmail, formatBytes, formatDate, formatNumber, formatPhoneE164, formatPrice, formatRelativeTime, formatReleaseDate, generateRandomString, getAllPlatformBaseDomains, getBaseUrl, getConfidenceBgClass, getConfidenceBorderClass, getConfidenceColorClass, getConfidenceLabel, getConfidenceLevel, getConfidenceTextClass, getCountryByCode, getCountryPhoneData, getCurrentPlatform, getDefaultColorForPlatform, getDefaultIconForPlatform, getDynamicIcon, getOSIcon, getOSLabel, getOSPlatformId, getOSTypeDefinition, getPlatformAccentColor, getPlatformColor, getPlatformDescription, getPlatformDisplayName, getPlatformIcon, getPlatformIconComponent, getPlatformIconComponent as getPlatformLogo, getPlatformProductionUrl, getPlatformSlogan, getShellIcon, getShellLabel, getSlackCommunityJoinUrl, getSmallPlatformIcon, getToolLabel, getToolTypeAliases, hasGenericEmailDomain, isGenericDomain, isGenericWebsiteDomain, isOSPlatform, isValidEmailDomain, isValidToolType, normalizeDomain, normalizeOSType, normalizeToolType, normalizeToolTypeWithFallback, platformColors, platformDescriptions, platformDisplayNames, platformHexColors, platformIconNames, platformIcons, platformSlogans, toToolLabel, transformPlatformConfigsToOptions, truncateString, useAccessCodeIntegration, validateAccessCode, validateAndConsumeAccessCode, validateEmailDomain, validateEmailDomainList, validatePhoneNumber };
2074
+ // src/utils/color-analysis.ts
2075
+ var DESIGN_PALETTE = [
2076
+ { name: "yellow", hex: "#FFC008", rgb: [255, 192, 8] },
2077
+ { name: "black", hex: "#161616", rgb: [22, 22, 22] },
2078
+ { name: "gray", hex: "#888888", rgb: [136, 136, 136] }
2079
+ ];
2080
+ function hexToRgb(hex) {
2081
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
2082
+ return result ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)] : [0, 0, 0];
2083
+ }
2084
+ function getLuminance(rgb) {
2085
+ const [r, g, b] = rgb.map((c) => {
2086
+ c = c / 255;
2087
+ return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
2088
+ });
2089
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
2090
+ }
2091
+ function getContrastRatio(color1, color2) {
2092
+ const lum1 = getLuminance(color1);
2093
+ const lum2 = getLuminance(color2);
2094
+ const brightest = Math.max(lum1, lum2);
2095
+ const darkest = Math.min(lum1, lum2);
2096
+ return (brightest + 0.05) / (darkest + 0.05);
2097
+ }
2098
+ function extractDominantColor(canvas) {
2099
+ const ctx = canvas.getContext("2d");
2100
+ if (!ctx) return [128, 128, 128];
2101
+ const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
2102
+ const data = imageData.data;
2103
+ const sampleSize = Math.max(1, Math.floor(data.length / (4 * 1e3)));
2104
+ const colorCounts = {};
2105
+ for (let i = 0; i < data.length; i += 4 * sampleSize) {
2106
+ const r = data[i];
2107
+ const g = data[i + 1];
2108
+ const b = data[i + 2];
2109
+ const alpha = data[i + 3];
2110
+ if (alpha < 128) continue;
2111
+ const bucketR = Math.round(r / 32) * 32;
2112
+ const bucketG = Math.round(g / 32) * 32;
2113
+ const bucketB = Math.round(b / 32) * 32;
2114
+ const key = `${bucketR},${bucketG},${bucketB}`;
2115
+ colorCounts[key] = (colorCounts[key] || 0) + 1;
2116
+ }
2117
+ let maxCount = 0;
2118
+ let dominantColor = [128, 128, 128];
2119
+ for (const [colorKey, count] of Object.entries(colorCounts)) {
2120
+ if (count > maxCount) {
2121
+ maxCount = count;
2122
+ const [r, g, b] = colorKey.split(",").map(Number);
2123
+ dominantColor = [r, g, b];
2124
+ }
2125
+ }
2126
+ return dominantColor;
2127
+ }
2128
+ function getBestContrastColor(imageColor) {
2129
+ let bestColor = DESIGN_PALETTE[0];
2130
+ let bestContrast = 0;
2131
+ for (const color of DESIGN_PALETTE) {
2132
+ const contrast = getContrastRatio(imageColor, color.rgb);
2133
+ if (contrast > bestContrast) {
2134
+ bestContrast = contrast;
2135
+ bestColor = color;
2136
+ }
2137
+ }
2138
+ return bestContrast >= 3 ? bestColor : DESIGN_PALETTE.find((c) => c.name === "black") || bestColor;
2139
+ }
2140
+ function analyzeImageColor(imageSrc) {
2141
+ return new Promise((resolve, reject) => {
2142
+ const img = new Image();
2143
+ img.crossOrigin = "anonymous";
2144
+ img.onload = () => {
2145
+ try {
2146
+ const canvas = document.createElement("canvas");
2147
+ const ctx = canvas.getContext("2d");
2148
+ if (!ctx) {
2149
+ reject(new Error("Could not get canvas context"));
2150
+ return;
2151
+ }
2152
+ const maxSize = 100;
2153
+ const scale = Math.min(maxSize / img.width, maxSize / img.height);
2154
+ canvas.width = img.width * scale;
2155
+ canvas.height = img.height * scale;
2156
+ ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
2157
+ const dominantColor = extractDominantColor(canvas);
2158
+ const bestContrastColor = getBestContrastColor(dominantColor);
2159
+ resolve(bestContrastColor);
2160
+ } catch (error) {
2161
+ reject(error);
2162
+ }
2163
+ };
2164
+ img.onerror = () => reject(new Error("Failed to load image"));
2165
+ img.src = imageSrc;
2166
+ });
2167
+ }
2168
+ async function extractImageEdgeColorAsync(imageUrl) {
2169
+ return new Promise((resolve) => {
2170
+ if (typeof window === "undefined") {
2171
+ resolve("#000000");
2172
+ return;
2173
+ }
2174
+ const img = new Image();
2175
+ img.crossOrigin = "anonymous";
2176
+ img.onload = () => {
2177
+ try {
2178
+ const canvas = document.createElement("canvas");
2179
+ const ctx = canvas.getContext("2d");
2180
+ if (!ctx) {
2181
+ resolve("#000000");
2182
+ return;
2183
+ }
2184
+ const maxSize = 50;
2185
+ const scale = Math.min(maxSize / img.naturalWidth, maxSize / img.naturalHeight);
2186
+ const w = Math.round(img.naturalWidth * scale);
2187
+ const h = Math.round(img.naturalHeight * scale);
2188
+ canvas.width = w;
2189
+ canvas.height = h;
2190
+ ctx.drawImage(img, 0, 0, w, h);
2191
+ const data = ctx.getImageData(0, 0, w, h).data;
2192
+ const edgeW = Math.max(2, Math.round(w * 0.15));
2193
+ const edgeH = Math.max(2, Math.round(h * 0.15));
2194
+ const bucketSize = 32;
2195
+ const buckets = /* @__PURE__ */ new Map();
2196
+ for (let y = 0; y < h; y++) {
2197
+ for (let x = 0; x < w; x++) {
2198
+ if (!(x < edgeW || x >= w - edgeW || y < edgeH || y >= h - edgeH)) continue;
2199
+ const i = (y * w + x) * 4;
2200
+ if (data[i + 3] < 128) continue;
2201
+ const br = Math.floor(data[i] / bucketSize) * bucketSize;
2202
+ const bg = Math.floor(data[i + 1] / bucketSize) * bucketSize;
2203
+ const bb = Math.floor(data[i + 2] / bucketSize) * bucketSize;
2204
+ const key = `${br},${bg},${bb}`;
2205
+ const existing = buckets.get(key);
2206
+ if (existing) {
2207
+ existing.r += data[i];
2208
+ existing.g += data[i + 1];
2209
+ existing.b += data[i + 2];
2210
+ existing.count++;
2211
+ } else {
2212
+ buckets.set(key, { r: data[i], g: data[i + 1], b: data[i + 2], count: 1 });
2213
+ }
2214
+ }
2215
+ }
2216
+ let best = { r: 0, g: 0, b: 0, count: 0 };
2217
+ for (const b2 of buckets.values()) {
2218
+ if (b2.count > best.count) best = b2;
2219
+ }
2220
+ if (best.count === 0) {
2221
+ resolve("#000000");
2222
+ return;
2223
+ }
2224
+ const r = Math.round(best.r / best.count), g = Math.round(best.g / best.count), b = Math.round(best.b / best.count);
2225
+ resolve(`#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`);
2226
+ } catch {
2227
+ resolve("#000000");
2228
+ }
2229
+ };
2230
+ img.onerror = () => resolve("#000000");
2231
+ img.src = imageUrl;
2232
+ });
2233
+ }
2234
+
2235
+ // src/utils/image-proxy.ts
2236
+ function getProxiedImageUrl(imageUrl, options) {
2237
+ if (!imageUrl) return null;
2238
+ const proxyPrefix = options?.proxyPrefix;
2239
+ const skipDomains = options?.skipDomains ?? [];
2240
+ const directHttps = options?.directHttps ?? false;
2241
+ if (proxyPrefix && imageUrl.includes(proxyPrefix)) {
2242
+ return imageUrl;
2243
+ }
2244
+ if (!imageUrl.startsWith("http://") && !imageUrl.startsWith("https://")) {
2245
+ return imageUrl;
2246
+ }
2247
+ if (directHttps && imageUrl.startsWith("https://")) {
2248
+ return imageUrl;
2249
+ }
2250
+ if (!proxyPrefix) {
2251
+ return imageUrl;
2252
+ }
2253
+ for (const domain of skipDomains) {
2254
+ if (imageUrl.includes(domain)) {
2255
+ return imageUrl;
2256
+ }
2257
+ }
2258
+ return `${proxyPrefix}?url=${encodeURIComponent(imageUrl)}`;
2259
+ }
2260
+ function urlPathLooksLikeSvg(imageUrl) {
2261
+ try {
2262
+ return /\.svg$/i.test(new URL(imageUrl).pathname);
2263
+ } catch {
2264
+ return /\.svg(\?|#|$)/i.test(imageUrl);
2265
+ }
2266
+ }
2267
+ function shouldProxyImage(imageUrl, proxyPrefix) {
2268
+ if (!imageUrl) return false;
2269
+ if (!imageUrl.startsWith("http://") && !imageUrl.startsWith("https://")) return false;
2270
+ if (proxyPrefix && imageUrl.includes(proxyPrefix)) return false;
2271
+ return true;
2272
+ }
2273
+ function generateImageSizes(_url) {
2274
+ return `(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw`;
2275
+ }
2276
+
2277
+ // src/utils/date-utils.ts
2278
+ function formatRelativeTime(timestamp) {
2279
+ const now = /* @__PURE__ */ new Date();
2280
+ const targetTime = typeof timestamp === "string" ? new Date(timestamp) : timestamp;
2281
+ if (isNaN(targetTime.getTime())) {
2282
+ console.warn("\u26A0\uFE0F Invalid timestamp in formatRelativeTime:", timestamp);
2283
+ return "Unknown time";
2284
+ }
2285
+ const diffInMs = now.getTime() - targetTime.getTime();
2286
+ const diffInMinutes = Math.floor(diffInMs / (1e3 * 60));
2287
+ if (diffInMinutes < 0) {
2288
+ return "Just now";
2289
+ }
2290
+ if (diffInMinutes < 1) return "Just now";
2291
+ if (diffInMinutes < 60) return `${diffInMinutes}m ago`;
2292
+ const diffInHours = Math.floor(diffInMinutes / 60);
2293
+ if (diffInHours < 24) return `${diffInHours}h ago`;
2294
+ const diffInDays = Math.floor(diffInHours / 24);
2295
+ if (diffInDays < 7) return `${diffInDays}d ago`;
2296
+ if (diffInDays < 30) {
2297
+ const weeks = Math.floor(diffInDays / 7);
2298
+ return `${weeks}w ago`;
2299
+ }
2300
+ return targetTime.toLocaleDateString("en-US", {
2301
+ month: "short",
2302
+ day: "numeric",
2303
+ year: targetTime.getFullYear() !== now.getFullYear() ? "numeric" : void 0
2304
+ });
2305
+ }
2306
+ function formatAbsoluteDate(timestamp, options = {}) {
2307
+ const targetTime = typeof timestamp === "string" ? new Date(timestamp) : timestamp;
2308
+ if (isNaN(targetTime.getTime())) {
2309
+ console.warn("\u26A0\uFE0F Invalid timestamp in formatAbsoluteDate:", timestamp);
2310
+ return "Invalid date";
2311
+ }
2312
+ const defaultOptions = {
2313
+ year: "numeric",
2314
+ month: "short",
2315
+ day: "numeric",
2316
+ ...options
2317
+ };
2318
+ return targetTime.toLocaleDateString("en-US", defaultOptions);
2319
+ }
2320
+ function formatDateTime(timestamp, options = {}) {
2321
+ const targetTime = typeof timestamp === "string" ? new Date(timestamp) : timestamp;
2322
+ if (isNaN(targetTime.getTime())) {
2323
+ console.warn("\u26A0\uFE0F Invalid timestamp in formatDateTime:", timestamp);
2324
+ return "Invalid date";
2325
+ }
2326
+ const defaultOptions = {
2327
+ year: "numeric",
2328
+ month: "short",
2329
+ day: "numeric",
2330
+ hour: "numeric",
2331
+ minute: "2-digit",
2332
+ ...options
2333
+ };
2334
+ return targetTime.toLocaleDateString("en-US", defaultOptions);
2335
+ }
2336
+ function getDetailedTimeDifference(timestamp) {
2337
+ const now = /* @__PURE__ */ new Date();
2338
+ const targetTime = typeof timestamp === "string" ? new Date(timestamp) : timestamp;
2339
+ if (isNaN(targetTime.getTime())) {
2340
+ return "Invalid date";
2341
+ }
2342
+ const diffInMs = now.getTime() - targetTime.getTime();
2343
+ const diffInSeconds = Math.floor(diffInMs / 1e3);
2344
+ const diffInMinutes = Math.floor(diffInSeconds / 60);
2345
+ const diffInHours = Math.floor(diffInMinutes / 60);
2346
+ const diffInDays = Math.floor(diffInHours / 24);
2347
+ if (diffInSeconds < 60) return `${diffInSeconds} seconds ago`;
2348
+ if (diffInMinutes < 60) return `${diffInMinutes} minutes ago`;
2349
+ if (diffInHours < 24) return `${diffInHours} hours ago`;
2350
+ if (diffInDays < 30) return `${diffInDays} days ago`;
2351
+ const diffInMonths = Math.floor(diffInDays / 30);
2352
+ if (diffInMonths < 12) return `${diffInMonths} months ago`;
2353
+ const diffInYears = Math.floor(diffInDays / 365);
2354
+ return `${diffInYears} years ago`;
2355
+ }
2356
+ function isToday(timestamp) {
2357
+ const today = /* @__PURE__ */ new Date();
2358
+ const targetTime = typeof timestamp === "string" ? new Date(timestamp) : timestamp;
2359
+ return today.toDateString() === targetTime.toDateString();
2360
+ }
2361
+ function isWithinMinutes(timestamp, minutes) {
2362
+ const now = /* @__PURE__ */ new Date();
2363
+ const targetTime = typeof timestamp === "string" ? new Date(timestamp) : timestamp;
2364
+ const diffInMs = now.getTime() - targetTime.getTime();
2365
+ const diffInMinutes = diffInMs / (1e3 * 60);
2366
+ return diffInMinutes <= minutes && diffInMinutes >= 0;
2367
+ }
2368
+ function createUTCTimestamp() {
2369
+ return (/* @__PURE__ */ new Date()).toISOString();
2370
+ }
2371
+
2372
+ // src/utils/source-icons.ts
2373
+ var SOURCE_ICON_NAMES = {
2374
+ // Doc tables
2375
+ "openframe-docs": "openframe",
2376
+ "data-room-docs": "shield",
2377
+ // CMS / programs
2378
+ "blog-posts": "newspaper",
2379
+ "product-releases": "rocket",
2380
+ "case-studies": "briefcase",
2381
+ "onboarding-guides": "graduation-cap",
2382
+ webinars: "video",
2383
+ events: "calendar",
2384
+ podcasts: "headphones",
2385
+ "customer-interviews": "users",
2386
+ // Financials
2387
+ "investor-updates": "mail",
2388
+ "financial-kpis": "activity",
2389
+ "financial-cap-table": "table",
2390
+ "financial-pnl": "trending-up",
2391
+ "financial-balance-sheet": "dollar-sign",
2392
+ "financial-cash-flow": "banknote",
2393
+ // ClickUp
2394
+ "clickup-roadmap": "clickup",
2395
+ "clickup-delivery": "clickup",
2396
+ "clickup-tasks-internal": "clickup",
2397
+ // GitHub
2398
+ "github-commits": "github",
2399
+ "github-pull-requests": "github",
2400
+ "github-pr-reviews": "github",
2401
+ "github-commits-public": "github",
2402
+ "github-pull-requests-public": "github",
2403
+ "github-pr-reviews-public": "github",
2404
+ // HubSpot
2405
+ "hubspot-tickets": "hubspot",
2406
+ "hubspot-tickets-anon": "hubspot",
2407
+ "hubspot-tickets-self": "hubspot",
2408
+ // Communications
2409
+ "slack-messages": "slack"
2410
+ };
2411
+ function getSourceIconName(tableId) {
2412
+ if (!tableId) return void 0;
2413
+ return SOURCE_ICON_NAMES[tableId];
2414
+ }
2415
+ var SOURCE_LABELS_BY_TABLE = {
2416
+ // Doc tables
2417
+ "openframe-docs": "OpenFrame Docs",
2418
+ "data-room-docs": "Data Room",
2419
+ // CMS / programs
2420
+ "blog-posts": "Blog Posts",
2421
+ "product-releases": "Product Releases",
2422
+ "case-studies": "Case Studies",
2423
+ "onboarding-guides": "Onboarding Guides",
2424
+ webinars: "Webinars",
2425
+ events: "Events",
2426
+ podcasts: "Podcasts",
2427
+ "customer-interviews": "Customer Interviews",
2428
+ // Financials
2429
+ "investor-updates": "Investor Updates",
2430
+ "financial-kpis": "Financial KPIs",
2431
+ "financial-cap-table": "Cap Table",
2432
+ "financial-pnl": "Profit & Loss",
2433
+ "financial-balance-sheet": "Balance Sheet",
2434
+ "financial-cash-flow": "Cash Flow",
2435
+ // ClickUp
2436
+ "clickup-roadmap": "ClickUp Roadmap",
2437
+ "clickup-delivery": "ClickUp Delivery",
2438
+ "clickup-tasks-internal": "ClickUp Tasks",
2439
+ // GitHub
2440
+ "github-commits": "GitHub Commits",
2441
+ "github-pull-requests": "GitHub Pull Requests",
2442
+ "github-pr-reviews": "GitHub PR Reviews",
2443
+ "github-commits-public": "OpenFrame Commits",
2444
+ "github-pull-requests-public": "OpenFrame Pull Requests",
2445
+ "github-pr-reviews-public": "OpenFrame PR Reviews",
2446
+ // HubSpot
2447
+ "hubspot-tickets": "HubSpot Tickets",
2448
+ "hubspot-tickets-anon": "Known Issues",
2449
+ "hubspot-tickets-self": "My Tickets",
2450
+ // Communications
2451
+ "slack-messages": "OpenMSP Community"
2452
+ };
2453
+ function getSourceLabel(tableId) {
2454
+ return SOURCE_LABELS_BY_TABLE[tableId] ?? tableId;
2455
+ }
2456
+
2457
+ // src/components/chat/utils/chat-attachment-markdown.ts
2458
+ var CHAT_ATTACHMENT_VIEW_URL_PREFIX = "/api/storage/view/chat-attachments/";
2459
+ var CHAT_ATTACHMENT_VIEW_TOKEN_QUERY_PARAM = "t";
2460
+ var ANTHROPIC_SUPPORTED_IMAGE_MIME = [
2461
+ "image/jpeg",
2462
+ "image/png",
2463
+ "image/webp",
2464
+ "image/gif"
2465
+ ];
2466
+ function buildChatAttachmentViewUrl(viewUrlPrefix, storagePath, viewToken) {
2467
+ return `${viewUrlPrefix}${storagePath}?${CHAT_ATTACHMENT_VIEW_TOKEN_QUERY_PARAM}=${encodeURIComponent(viewToken)}`;
2468
+ }
2469
+ function escapeMarkdownInline(text) {
2470
+ return text.replace(/[[\]()\\\n\r<>"]/g, (ch) => {
2471
+ switch (ch) {
2472
+ case "\n":
2473
+ return " ";
2474
+ case "\r":
2475
+ return "";
2476
+ default:
2477
+ return `\\${ch}`;
2478
+ }
2479
+ });
2480
+ }
2481
+ function formatChatAttachmentMarkdownForBubble(att, viewUrlPrefix) {
2482
+ const safeName = escapeMarkdownInline(att.fileName);
2483
+ const url = buildChatAttachmentViewUrl(viewUrlPrefix, att.storagePath, att.viewToken);
2484
+ const isImage = ANTHROPIC_SUPPORTED_IMAGE_MIME.includes(att.contentType);
2485
+ return isImage ? `
2486
+
2487
+ ![${safeName}](${url})` : `
2488
+
2489
+ [Attached: ${safeName}](${url})`;
2490
+ }
2491
+ var CHAT_ATTACHMENT_VIEW_URL_PREFIX_REGEX_ESCAPED = CHAT_ATTACHMENT_VIEW_URL_PREFIX.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2492
+ var CHAT_ATTACHMENT_MARKDOWN_PATTERN = new RegExp(
2493
+ `^\\s*!?\\[[^\\]]*\\]\\(${CHAT_ATTACHMENT_VIEW_URL_PREFIX_REGEX_ESCAPED}[^)]+\\)\\s*$`,
2494
+ "gm"
2495
+ );
2496
+ function stripChatAttachmentMarkdown(text) {
2497
+ const storagePaths = [];
2498
+ const pathExtract = new RegExp(
2499
+ `\\(${CHAT_ATTACHMENT_VIEW_URL_PREFIX_REGEX_ESCAPED}([^?)]+)`
2500
+ );
2501
+ const stripped = text.replace(CHAT_ATTACHMENT_MARKDOWN_PATTERN, (match) => {
2502
+ const m = match.match(pathExtract);
2503
+ if (m && m[1]) storagePaths.push(m[1]);
2504
+ return "";
2505
+ });
2506
+ return {
2507
+ stripped: stripped.replace(/\n{3,}/g, "\n\n").trim(),
2508
+ storagePaths
2509
+ };
2510
+ }
2511
+
2512
+ // src/components/chat/utils/auto-continuation-directive.ts
2513
+ var AUTO_CONTINUATION_DIRECTIVE_PREFIX = "[internal-auto-continuation]";
2514
+ function buildAutoContinuationDirective(toolName, opts = {}) {
2515
+ const ticketRef = opts.ticketId ? ` (ticket #${opts.ticketId})` : "";
2516
+ const ticketHash = opts.ticketId ? ` #${opts.ticketId}` : "";
2517
+ const isClose = toolName === "update_ticket" && opts.status?.toUpperCase() === "CLOSED";
2518
+ if (toolName === "create_ticket") {
2519
+ return `${AUTO_CONTINUATION_DIRECTIVE_PREFIX} The user just approved create_ticket${ticketRef}. Per ticket-protocol \xA71a, ask 2-4 SHORT, issue-specific diagnostic follow-up questions tailored to the symptom they reported in their original message. When they answer, propose an update_ticket with content_addendum carrying a clean Q&A digest. Do NOT call any tool in this turn \u2014 just write the questions as prose.`;
2520
+ }
2521
+ if (isClose) {
2522
+ return `${AUTO_CONTINUATION_DIRECTIVE_PREFIX} The user just approved closing ticket${ticketHash}. Per ticket-protocol \xA71b, ask ONE short question: "How was this resolved? I'll add it to the ticket as a closing note." Phrase kindly even if the user was curt. When they answer, propose an update_ticket with content_addendum="[Resolution] <their words>". Do NOT call any tool in this turn \u2014 just write the prose ask.`;
2523
+ }
2524
+ return `${AUTO_CONTINUATION_DIRECTIVE_PREFIX} The user just approved update_ticket${ticketHash}. Acknowledge the change in ONE short sentence; if anything else looks like it needs attention, ask. Do NOT call any tool in this turn.`;
2525
+ }
2526
+
2527
+ // src/components/chat/utils/flatten-assistant-content.ts
2528
+ function flattenAssistantContent(raw) {
2529
+ if (typeof raw === "string") return raw;
2530
+ if (!Array.isArray(raw)) return "";
2531
+ const parts = [];
2532
+ for (const seg of raw) {
2533
+ if (seg && typeof seg === "object" && seg.type === "text") {
2534
+ const t = seg.text;
2535
+ if (typeof t === "string" && t.length > 0) parts.push(t);
2536
+ }
2537
+ }
2538
+ return parts.join("\n\n");
2539
+ }
2540
+
2541
+ // src/components/chat/types/message.types.ts
2542
+ var SCROLL_ANCHOR = { TOP: "top", BOTTOM: "bottom" };
2543
+
2544
+ // src/components/chat/utils/scroll-anchor.ts
2545
+ var SCROLL_ANCHOR_WIRE_KEY = "scrollAnchor";
2546
+ function parseScrollAnchor(raw) {
2547
+ return raw === SCROLL_ANCHOR.TOP || raw === SCROLL_ANCHOR.BOTTOM ? raw : null;
2548
+ }
2549
+
2550
+ // src/components/chat/utils/slash-dispatch-utils.ts
2551
+ var WIRE_TABLE_ID_REGEX = /^[a-z][a-z0-9-]*$/;
2552
+ var WIRE_ID_REGEX = /^[A-Za-z0-9._:/-]+$/;
2553
+ var WIRE_TABLE_ID_MAX = 60;
2554
+ var WIRE_ID_MAX = 200;
2555
+ var WIRE_QUERY_MAX = 2e3;
2556
+ function parseWireCommandOverride(raw) {
2557
+ if (!raw || typeof raw !== "object") return null;
2558
+ const out = {};
2559
+ const r = raw;
2560
+ if (r.entityIdFilter && typeof r.entityIdFilter === "object") {
2561
+ const f = r.entityIdFilter;
2562
+ if (typeof f.tableId === "string" && f.tableId.length > 0 && f.tableId.length <= WIRE_TABLE_ID_MAX && WIRE_TABLE_ID_REGEX.test(f.tableId) && typeof f.id === "string" && f.id.length > 0 && f.id.length <= WIRE_ID_MAX && WIRE_ID_REGEX.test(f.id)) {
2563
+ out.entityIdFilter = { tableId: f.tableId, id: f.id };
2564
+ }
2565
+ }
2566
+ if (typeof r.retrievalQueryOverride === "string" && r.retrievalQueryOverride.length > 0 && r.retrievalQueryOverride.length <= WIRE_QUERY_MAX) {
2567
+ out.retrievalQueryOverride = r.retrievalQueryOverride;
2568
+ }
2569
+ if (out.entityIdFilter === void 0 && out.retrievalQueryOverride === void 0) {
2570
+ return null;
2571
+ }
2572
+ return out;
2573
+ }
2574
+ function sanitizeTitleForChat(value) {
2575
+ return (value ?? "").replace(/[\r\n\t]+/g, " ").trim();
2576
+ }
2577
+ function formatSingularLookupInvocation(cmdId, value) {
2578
+ const safe = sanitizeTitleForChat(value).replace(/\\/g, "\\\\").replace(/"/g, '\\"');
2579
+ return safe ? `/${cmdId} "${safe}"` : `/${cmdId}`;
2580
+ }
2581
+ function extractEntityIdFilter(override, expectedTableId) {
2582
+ const f = override?.entityIdFilter;
2583
+ if (!f) return null;
2584
+ const tableId = typeof f.tableId === "string" ? f.tableId : "";
2585
+ const id = typeof f.id === "string" ? f.id : "";
2586
+ if (!tableId || !id) return null;
2587
+ if (expectedTableId && tableId !== expectedTableId) return null;
2588
+ return { tableId, id };
2589
+ }
2590
+ function buildDiscussAddendum(args) {
2591
+ const idTag = args.id.length > 24 ? args.id.slice(0, 24) + "\u2026" : args.id;
2592
+ return `Ask drill-in for row id="${args.id}" in table "${args.tableId}". Focus the answer on this single record. If retrieval returns 0 rows (privacy filter), say so plainly per Rule 5b.
2593
+
2594
+ OPEN with the inline card on the FIRST line, immediately followed by the chip and a mono-font id tag \u2014 no prose before the card:
2595
+ [card://<type>:${args.id}] [N] \`${args.tableId} \xB7 ${idTag}\`
2596
+ Use the EXACT <type> from the row's <document type="..." id="${args.id}"> tag.
2597
+
2598
+ SURFACE EVERY FIELD PRESENT in the retrieved record \u2014 the user already knows the title from the card; the value of Ask is the BODY (description, status, vote counts, dates, linked URLs, \u2026). Walk each non-empty field. Don't invent fields, don't hallucinate values, silently omit absent fields.
2599
+
2600
+ FORMAT: card+chip+id-tag opener, then ONE framing sentence, then a compact bulleted "**Field** \u2014 value" list. Don't restate fields already in the list.`;
2601
+ }
2602
+
2603
+ // src/components/chat/utils/clickup-task-type-utils.ts
2604
+ var CUSTOM_ITEM_ID = {
2605
+ TASK: 1e3,
2606
+ MILESTONE: 1001,
2607
+ RECURRING: 1002,
2608
+ SUBTASK: 1003,
2609
+ FORM: 1004,
2610
+ PLAN: 1006,
2611
+ STRATEGY: 1007,
2612
+ BUG: 1008,
2613
+ REQUEST: 1009,
2614
+ FEATURE: 1010,
2615
+ STORY: 1011,
2616
+ EPIC: 1012,
2617
+ COMPONENT: 1013,
2618
+ INITIATIVE: 1014
2619
+ };
2620
+ function getTaskTypeLabel(customItemId) {
2621
+ switch (customItemId) {
2622
+ case CUSTOM_ITEM_ID.TASK:
2623
+ return "Task";
2624
+ case CUSTOM_ITEM_ID.MILESTONE:
2625
+ return "Milestone";
2626
+ case CUSTOM_ITEM_ID.RECURRING:
2627
+ return "Recurring";
2628
+ case CUSTOM_ITEM_ID.SUBTASK:
2629
+ return "Subtask";
2630
+ case CUSTOM_ITEM_ID.FORM:
2631
+ return "Form";
2632
+ case CUSTOM_ITEM_ID.PLAN:
2633
+ return "Plan";
2634
+ case CUSTOM_ITEM_ID.STRATEGY:
2635
+ return "Strategy";
2636
+ case CUSTOM_ITEM_ID.BUG:
2637
+ return "Bug";
2638
+ case CUSTOM_ITEM_ID.REQUEST:
2639
+ return "Request";
2640
+ case CUSTOM_ITEM_ID.FEATURE:
2641
+ return "Feature";
2642
+ case CUSTOM_ITEM_ID.STORY:
2643
+ return "Story";
2644
+ case CUSTOM_ITEM_ID.EPIC:
2645
+ return "Epic";
2646
+ case CUSTOM_ITEM_ID.COMPONENT:
2647
+ return "Component";
2648
+ case CUSTOM_ITEM_ID.INITIATIVE:
2649
+ return "Initiative";
2650
+ default:
2651
+ return null;
2652
+ }
2653
+ }
2654
+
2655
+ // src/components/chat/utils/agent-status-message.ts
2656
+ function getStatusColorScheme(status) {
2657
+ const s = status?.toLowerCase() || "";
2658
+ switch (status) {
2659
+ case "completed":
2660
+ case "success":
2661
+ case "active":
2662
+ return "success";
2663
+ case "failed":
2664
+ case "failure":
2665
+ case "cancelled":
2666
+ case "error":
2667
+ return "error";
2668
+ case "running":
2669
+ case "processing":
2670
+ case "closed":
2671
+ return "cyan";
2672
+ case "pending":
2673
+ case "warning":
2674
+ return "warning";
2675
+ case "draft":
2676
+ // review cycles not yet opened to reviewers
2677
+ case "info":
2678
+ return "default";
2679
+ }
2680
+ if (s.includes("complete") || s.includes("done")) return "success";
2681
+ if (s.includes("review")) return "cyan";
2682
+ if (s.includes("working") || s.includes("progress")) return "warning";
2683
+ if (s.includes("blocked") || s.includes("failed")) return "error";
2684
+ return "default";
2685
+ }
2686
+
2687
+ // src/components/chat/utils/external-app-urls.ts
2688
+ var CLICKUP_APP_BASE = "https://app.clickup.com";
2689
+ function clickupTaskUrl(externalId) {
2690
+ if (!externalId) return null;
2691
+ return `${CLICKUP_APP_BASE}/t/${externalId}`;
2692
+ }
2693
+
2694
+ // src/components/chat/utils/is-cross-origin-url.ts
2695
+ function isCrossOriginUrl(url) {
2696
+ if (!url) return false;
2697
+ if (url.startsWith("/") && !url.startsWith("//")) return false;
2698
+ return true;
2699
+ }
2700
+ var REACT_MAJOR = parseInt((React2.version || "0").split(".")[0], 10);
2701
+ var USE_CAMEL_CASE_FETCH_PRIORITY = REACT_MAJOR >= 19;
2702
+ function fetchPriorityProp(priority) {
2703
+ const value = priority === void 0 ? "auto" : typeof priority === "boolean" ? priority ? "high" : "low" : priority;
2704
+ return USE_CAMEL_CASE_FETCH_PRIORITY ? { fetchPriority: value } : { fetchpriority: value };
2705
+ }
2706
+
2707
+ export { ANTHROPIC_SUPPORTED_IMAGE_MIME, AUTO_CONTINUATION_DIRECTIVE_PREFIX, CHAT_ATTACHMENT_MARKDOWN_PATTERN, CHAT_ATTACHMENT_VIEW_TOKEN_QUERY_PARAM, CHAT_ATTACHMENT_VIEW_URL_PREFIX, CHAT_ATTACHMENT_VIEW_URL_PREFIX_REGEX_ESCAPED, CUSTOM_ITEM_ID, DEFAULT_OS_PLATFORM, DESIGN_PALETTE, GENERIC_EMAIL_DOMAINS, ICON_REGISTRY, OS_PLATFORMS, PLAY_ICON_PATH, SCROLL_ANCHOR, SCROLL_ANCHOR_WIRE_KEY, SOURCE_ICON_NAMES, SOURCE_LABELS_BY_TABLE, analyzeImageColor, buildAutoContinuationDirective, buildChatAttachmentViewUrl, buildDiscussAddendum, cleanEmailDomain, clickupTaskUrl, cn, consumeAccessCode, createUTCTimestamp, deepClone, delay, escapeMarkdownInline, extractDomainFromEmail, extractDominantColor, extractEntityIdFilter, extractImageEdgeColorAsync, fetchPriorityProp, flattenAssistantContent, formatAbbreviatedNumber, formatAbsoluteDate, formatBioText, formatBytes, formatBytesShort, formatChatAttachmentMarkdownForBubble, formatClassification, formatCompactMetric, formatCurrency, formatDate, formatDateRange, formatDateShort, formatDateSlashUTC, formatDateTime, formatDateTimeAt, formatDateUTC, formatDuration, formatDurationCompact, formatDurationFromMs, formatDurationFromRange, formatDurationMMSS, formatLargeNumber, formatLegalDate, formatNumber, formatPercent, formatPhoneE164, formatPrice, formatPricingModel, formatRelativeTime, formatReleaseDate, formatSingularLookupInvocation, formatTimeWithTimezone, formatUnderscoreText, formatWholeDollars, generateImageSizes, generateRandomString, getAllPlatformBaseDomains, getBaseUrl, getBestContrastColor, getConfidenceBgClass, getConfidenceBorderClass, getConfidenceColorClass, getConfidenceLabel, getConfidenceLevel, getConfidenceTextClass, getContrastRatio, getCountryByCode, getCountryPhoneData, getCurrentPlatform, getDefaultColorForPlatform, getDefaultIconForPlatform, getDetailedTimeDifference, getDynamicIcon, getFirstLastInitials, getIconComponent, getOSIcon, getOSLabel, getOSPlatformId, getOSTypeDefinition, getPlatformAccentColor, getPlatformColor, getPlatformDescription, getPlatformDisplayName, getPlatformIcon, getPlatformIconComponent, getPlatformIconComponent as getPlatformLogo, getPlatformProductionUrl, getPlatformSlogan, getProxiedImageUrl, getShellIcon, getShellLabel, getSlackCommunityJoinUrl, getSmallPlatformIcon, getSourceIconName, getSourceLabel, getStatusColorScheme, getTaskTypeLabel, getToolLabel, getToolTypeAliases, getTrendColors, hasGenericEmailDomain, hexToRgb, isCrossOriginUrl, isGenericDomain, isGenericWebsiteDomain, isOSPlatform, isToday, isValidEmailDomain, isValidToolType, isWithinMinutes, nameInitials, normalizeDomain, normalizeIconKey, normalizeOSType, normalizeToolType, normalizeToolTypeWithFallback, parseScrollAnchor, parseWireCommandOverride, platformColors, platformDescriptions, platformDisplayNames, platformHexColors, platformIconNames, platformIcons, platformSlogans, sanitizeTitleForChat, shouldProxyImage, stripChatAttachmentMarkdown, stripHtml, toToolLabel, transformPlatformConfigsToOptions, truncateString, urlPathLooksLikeSvg, validateAccessCode, validateAndConsumeAccessCode, validateEmailDomain, validateEmailDomainList, validatePhoneNumber };
1665
2708
  //# sourceMappingURL=index.js.map
1666
2709
  //# sourceMappingURL=index.js.map