@flanksource/clicky-ui 0.2.18 → 0.2.20

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 (445) hide show
  1. package/dist/ai.cjs +26 -0
  2. package/dist/ai.cjs.map +1 -0
  3. package/dist/ai.d.ts +2 -0
  4. package/dist/ai.d.ts.map +1 -0
  5. package/dist/ai.js +26 -0
  6. package/dist/ai.js.map +1 -0
  7. package/dist/chat.cjs +7 -0
  8. package/dist/chat.cjs.map +1 -1
  9. package/dist/chat.js +7 -0
  10. package/dist/chat.js.map +1 -1
  11. package/dist/components/FilterBar.cjs +49 -18
  12. package/dist/components/FilterBar.cjs.map +1 -1
  13. package/dist/components/FilterBar.d.ts +0 -2
  14. package/dist/components/FilterBar.d.ts.map +1 -1
  15. package/dist/components/FilterBar.js +50 -19
  16. package/dist/components/FilterBar.js.map +1 -1
  17. package/dist/components/SearchInput.cjs +63 -0
  18. package/dist/components/SearchInput.cjs.map +1 -0
  19. package/dist/components/SearchInput.d.ts +31 -0
  20. package/dist/components/SearchInput.d.ts.map +1 -0
  21. package/dist/components/SearchInput.js +63 -0
  22. package/dist/components/SearchInput.js.map +1 -0
  23. package/dist/components/SegmentedControl.cjs +88 -0
  24. package/dist/components/SegmentedControl.cjs.map +1 -0
  25. package/dist/components/SegmentedControl.d.ts +38 -0
  26. package/dist/components/SegmentedControl.d.ts.map +1 -0
  27. package/dist/components/SegmentedControl.js +88 -0
  28. package/dist/components/SegmentedControl.js.map +1 -0
  29. package/dist/components/Switch.cjs +51 -0
  30. package/dist/components/Switch.cjs.map +1 -0
  31. package/dist/components/Switch.d.ts +23 -0
  32. package/dist/components/Switch.d.ts.map +1 -0
  33. package/dist/components/Switch.js +51 -0
  34. package/dist/components/Switch.js.map +1 -0
  35. package/dist/components/TimeRange.cjs +53 -45
  36. package/dist/components/TimeRange.cjs.map +1 -1
  37. package/dist/components/TimeRange.d.ts.map +1 -1
  38. package/dist/components/TimeRange.js +53 -45
  39. package/dist/components/TimeRange.js.map +1 -1
  40. package/dist/components/TreePickerField.cjs +5 -1
  41. package/dist/components/TreePickerField.cjs.map +1 -1
  42. package/dist/components/TreePickerField.d.ts.map +1 -1
  43. package/dist/components/TreePickerField.js +5 -1
  44. package/dist/components/TreePickerField.js.map +1 -1
  45. package/dist/components/filter-bar-utils.cjs +5 -0
  46. package/dist/components/filter-bar-utils.cjs.map +1 -1
  47. package/dist/components/filter-bar-utils.d.ts +2 -0
  48. package/dist/components/filter-bar-utils.d.ts.map +1 -1
  49. package/dist/components/filter-bar-utils.js +5 -0
  50. package/dist/components/filter-bar-utils.js.map +1 -1
  51. package/dist/components/json-schema-form-fields.cjs +8 -2
  52. package/dist/components/json-schema-form-fields.cjs.map +1 -1
  53. package/dist/components/json-schema-form-fields.d.ts.map +1 -1
  54. package/dist/components/json-schema-form-fields.js +8 -2
  55. package/dist/components/json-schema-form-fields.js.map +1 -1
  56. package/dist/components/json-schema-form-resolve.cjs +1 -1
  57. package/dist/components/json-schema-form-resolve.cjs.map +1 -1
  58. package/dist/components/json-schema-form-resolve.js +1 -1
  59. package/dist/components/json-schema-form-resolve.js.map +1 -1
  60. package/dist/components.cjs +21 -1
  61. package/dist/components.cjs.map +1 -1
  62. package/dist/components.d.ts +11 -1
  63. package/dist/components.d.ts.map +1 -1
  64. package/dist/components.js +21 -1
  65. package/dist/components.js.map +1 -1
  66. package/dist/data/Clicky.cjs +33 -44
  67. package/dist/data/Clicky.cjs.map +1 -1
  68. package/dist/data/Clicky.d.ts +0 -9
  69. package/dist/data/Clicky.d.ts.map +1 -1
  70. package/dist/data/Clicky.js +31 -42
  71. package/dist/data/Clicky.js.map +1 -1
  72. package/dist/data/DataTable.cjs +73 -50
  73. package/dist/data/DataTable.cjs.map +1 -1
  74. package/dist/data/DataTable.d.ts +4 -0
  75. package/dist/data/DataTable.d.ts.map +1 -1
  76. package/dist/data/DataTable.js +73 -50
  77. package/dist/data/DataTable.js.map +1 -1
  78. package/dist/data/Icon.cjs +2 -5
  79. package/dist/data/Icon.cjs.map +1 -1
  80. package/dist/data/Icon.d.ts +1 -21
  81. package/dist/data/Icon.d.ts.map +1 -1
  82. package/dist/data/Icon.js +3 -6
  83. package/dist/data/Icon.js.map +1 -1
  84. package/dist/data/MatrixTable.cjs +4 -4
  85. package/dist/data/MatrixTable.cjs.map +1 -1
  86. package/dist/data/MatrixTable.js +4 -4
  87. package/dist/data/MatrixTable.js.map +1 -1
  88. package/dist/data/RadialGauge.cjs +76 -0
  89. package/dist/data/RadialGauge.cjs.map +1 -0
  90. package/dist/data/RadialGauge.d.ts +24 -0
  91. package/dist/data/RadialGauge.d.ts.map +1 -0
  92. package/dist/data/RadialGauge.js +76 -0
  93. package/dist/data/RadialGauge.js.map +1 -0
  94. package/dist/data/StatusBreakdown.cjs +0 -4
  95. package/dist/data/StatusBreakdown.cjs.map +1 -1
  96. package/dist/data/StatusBreakdown.d.ts +0 -2
  97. package/dist/data/StatusBreakdown.d.ts.map +1 -1
  98. package/dist/data/StatusBreakdown.js +1 -5
  99. package/dist/data/StatusBreakdown.js.map +1 -1
  100. package/dist/data/TabButton.cjs +17 -2
  101. package/dist/data/TabButton.cjs.map +1 -1
  102. package/dist/data/TabButton.d.ts +5 -1
  103. package/dist/data/TabButton.d.ts.map +1 -1
  104. package/dist/data/TabButton.js +17 -2
  105. package/dist/data/TabButton.js.map +1 -1
  106. package/dist/data/Timeline.cjs +61 -0
  107. package/dist/data/Timeline.cjs.map +1 -0
  108. package/dist/data/Timeline.d.ts +36 -0
  109. package/dist/data/Timeline.d.ts.map +1 -0
  110. package/dist/data/Timeline.js +61 -0
  111. package/dist/data/Timeline.js.map +1 -0
  112. package/dist/data/TimeseriesCoreBars.cjs +2 -25
  113. package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
  114. package/dist/data/TimeseriesCoreBars.d.ts +0 -19
  115. package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
  116. package/dist/data/TimeseriesCoreBars.js +2 -25
  117. package/dist/data/TimeseriesCoreBars.js.map +1 -1
  118. package/dist/data/TimeseriesCoreBars.model.cjs +27 -0
  119. package/dist/data/TimeseriesCoreBars.model.cjs.map +1 -0
  120. package/dist/data/TimeseriesCoreBars.model.d.ts +20 -0
  121. package/dist/data/TimeseriesCoreBars.model.d.ts.map +1 -0
  122. package/dist/data/TimeseriesCoreBars.model.js +27 -0
  123. package/dist/data/TimeseriesCoreBars.model.js.map +1 -0
  124. package/dist/data/TimeseriesPanel.axes.cjs.map +1 -1
  125. package/dist/data/TimeseriesPanel.axes.d.ts +1 -1
  126. package/dist/data/TimeseriesPanel.axes.d.ts.map +1 -1
  127. package/dist/data/TimeseriesPanel.axes.js.map +1 -1
  128. package/dist/data/TimeseriesPanel.cjs +4 -54
  129. package/dist/data/TimeseriesPanel.cjs.map +1 -1
  130. package/dist/data/TimeseriesPanel.d.ts +2 -138
  131. package/dist/data/TimeseriesPanel.d.ts.map +1 -1
  132. package/dist/data/TimeseriesPanel.js +2 -52
  133. package/dist/data/TimeseriesPanel.js.map +1 -1
  134. package/dist/data/TimeseriesPanel.model.cjs +53 -0
  135. package/dist/data/TimeseriesPanel.model.cjs.map +1 -0
  136. package/dist/data/TimeseriesPanel.model.d.ts +88 -0
  137. package/dist/data/TimeseriesPanel.model.d.ts.map +1 -0
  138. package/dist/data/TimeseriesPanel.model.js +53 -0
  139. package/dist/data/TimeseriesPanel.model.js.map +1 -0
  140. package/dist/data/Tree.cjs +1 -1
  141. package/dist/data/Tree.cjs.map +1 -1
  142. package/dist/data/Tree.js +1 -1
  143. package/dist/data/Tree.js.map +1 -1
  144. package/dist/data/ai/ChatFab.cjs +29 -0
  145. package/dist/data/ai/ChatFab.cjs.map +1 -0
  146. package/dist/data/ai/ChatFab.d.ts +12 -0
  147. package/dist/data/ai/ChatFab.d.ts.map +1 -0
  148. package/dist/data/ai/ChatFab.js +29 -0
  149. package/dist/data/ai/ChatFab.js.map +1 -0
  150. package/dist/data/ai/ChatWindow.cjs +178 -0
  151. package/dist/data/ai/ChatWindow.cjs.map +1 -0
  152. package/dist/data/ai/ChatWindow.d.ts +38 -0
  153. package/dist/data/ai/ChatWindow.d.ts.map +1 -0
  154. package/dist/data/ai/ChatWindow.js +156 -0
  155. package/dist/data/ai/ChatWindow.js.map +1 -0
  156. package/dist/data/ai/ChatWindowManager.cjs +139 -0
  157. package/dist/data/ai/ChatWindowManager.cjs.map +1 -0
  158. package/dist/data/ai/ChatWindowManager.d.ts +12 -0
  159. package/dist/data/ai/ChatWindowManager.d.ts.map +1 -0
  160. package/dist/data/ai/ChatWindowManager.js +139 -0
  161. package/dist/data/ai/ChatWindowManager.js.map +1 -0
  162. package/dist/data/ai/ContextBadges.cjs +74 -0
  163. package/dist/data/ai/ContextBadges.cjs.map +1 -0
  164. package/dist/data/ai/ContextBadges.d.ts +16 -0
  165. package/dist/data/ai/ContextBadges.d.ts.map +1 -0
  166. package/dist/data/ai/ContextBadges.js +74 -0
  167. package/dist/data/ai/ContextBadges.js.map +1 -0
  168. package/dist/data/ai/ThreadPicker.cjs +148 -0
  169. package/dist/data/ai/ThreadPicker.cjs.map +1 -0
  170. package/dist/data/ai/ThreadPicker.d.ts +37 -0
  171. package/dist/data/ai/ThreadPicker.d.ts.map +1 -0
  172. package/dist/data/ai/ThreadPicker.js +148 -0
  173. package/dist/data/ai/ThreadPicker.js.map +1 -0
  174. package/dist/data/ai/ToolPreferences.cjs +80 -0
  175. package/dist/data/ai/ToolPreferences.cjs.map +1 -0
  176. package/dist/data/ai/ToolPreferences.d.ts +19 -0
  177. package/dist/data/ai/ToolPreferences.d.ts.map +1 -0
  178. package/dist/data/ai/ToolPreferences.js +80 -0
  179. package/dist/data/ai/ToolPreferences.js.map +1 -0
  180. package/dist/data/ai/chat-window-context.cjs +78 -0
  181. package/dist/data/ai/chat-window-context.cjs.map +1 -0
  182. package/dist/data/ai/chat-window-context.d.ts +57 -0
  183. package/dist/data/ai/chat-window-context.d.ts.map +1 -0
  184. package/dist/data/ai/chat-window-context.js +78 -0
  185. package/dist/data/ai/chat-window-context.js.map +1 -0
  186. package/dist/data/ai/context.cjs +43 -0
  187. package/dist/data/ai/context.cjs.map +1 -0
  188. package/dist/data/ai/context.d.ts +35 -0
  189. package/dist/data/ai/context.d.ts.map +1 -0
  190. package/dist/data/ai/context.js +43 -0
  191. package/dist/data/ai/context.js.map +1 -0
  192. package/dist/data/ai/index.d.ts +10 -0
  193. package/dist/data/ai/index.d.ts.map +1 -0
  194. package/dist/data/cache-browser/CacheDetailPanel.cjs +15 -0
  195. package/dist/data/cache-browser/CacheDetailPanel.cjs.map +1 -1
  196. package/dist/data/cache-browser/CacheDetailPanel.d.ts.map +1 -1
  197. package/dist/data/cache-browser/CacheDetailPanel.js +15 -0
  198. package/dist/data/cache-browser/CacheDetailPanel.js.map +1 -1
  199. package/dist/data/cache-browser/cache-browser.fixtures.d.ts +10 -0
  200. package/dist/data/cache-browser/cache-browser.fixtures.d.ts.map +1 -0
  201. package/dist/data/cache-browser/download.cjs +13 -0
  202. package/dist/data/cache-browser/download.cjs.map +1 -0
  203. package/dist/data/cache-browser/download.d.ts +3 -0
  204. package/dist/data/cache-browser/download.d.ts.map +1 -0
  205. package/dist/data/cache-browser/download.js +13 -0
  206. package/dist/data/cache-browser/download.js.map +1 -0
  207. package/dist/data/chat/Chat.cjs +40 -2
  208. package/dist/data/chat/Chat.cjs.map +1 -1
  209. package/dist/data/chat/Chat.d.ts +5 -2
  210. package/dist/data/chat/Chat.d.ts.map +1 -1
  211. package/dist/data/chat/Chat.fixtures.cjs +86 -0
  212. package/dist/data/chat/Chat.fixtures.cjs.map +1 -0
  213. package/dist/data/chat/Chat.fixtures.d.ts +4 -0
  214. package/dist/data/chat/Chat.fixtures.d.ts.map +1 -1
  215. package/dist/data/chat/Chat.fixtures.js +86 -0
  216. package/dist/data/chat/Chat.fixtures.js.map +1 -0
  217. package/dist/data/chat/Chat.js +41 -3
  218. package/dist/data/chat/Chat.js.map +1 -1
  219. package/dist/data/chat/ContextUsage.cjs +99 -0
  220. package/dist/data/chat/ContextUsage.cjs.map +1 -0
  221. package/dist/data/chat/ContextUsage.d.ts +19 -0
  222. package/dist/data/chat/ContextUsage.d.ts.map +1 -0
  223. package/dist/data/chat/ContextUsage.js +99 -0
  224. package/dist/data/chat/ContextUsage.js.map +1 -0
  225. package/dist/data/chat/ModelSelector.cjs +28 -14
  226. package/dist/data/chat/ModelSelector.cjs.map +1 -1
  227. package/dist/data/chat/ModelSelector.d.ts +5 -4
  228. package/dist/data/chat/ModelSelector.d.ts.map +1 -1
  229. package/dist/data/chat/ModelSelector.js +28 -14
  230. package/dist/data/chat/ModelSelector.js.map +1 -1
  231. package/dist/data/chat/clickyOperationsToTools.cjs +21 -1
  232. package/dist/data/chat/clickyOperationsToTools.cjs.map +1 -1
  233. package/dist/data/chat/clickyOperationsToTools.d.ts +5 -4
  234. package/dist/data/chat/clickyOperationsToTools.d.ts.map +1 -1
  235. package/dist/data/chat/clickyOperationsToTools.js +21 -1
  236. package/dist/data/chat/clickyOperationsToTools.js.map +1 -1
  237. package/dist/data/chat/index.d.ts +4 -1
  238. package/dist/data/chat/index.d.ts.map +1 -1
  239. package/dist/data/chat/provider-icons.cjs +15 -0
  240. package/dist/data/chat/provider-icons.cjs.map +1 -0
  241. package/dist/data/chat/provider-icons.d.ts +7 -0
  242. package/dist/data/chat/provider-icons.d.ts.map +1 -0
  243. package/dist/data/chat/provider-icons.js +15 -0
  244. package/dist/data/chat/provider-icons.js.map +1 -0
  245. package/dist/data/chat/types.cjs.map +1 -1
  246. package/dist/data/chat/types.d.ts +41 -9
  247. package/dist/data/chat/types.d.ts.map +1 -1
  248. package/dist/data/chat/types.js.map +1 -1
  249. package/dist/data/clicky-parse.cjs +42 -0
  250. package/dist/data/clicky-parse.cjs.map +1 -0
  251. package/dist/data/clicky-parse.d.ts +11 -0
  252. package/dist/data/clicky-parse.d.ts.map +1 -0
  253. package/dist/data/clicky-parse.js +42 -0
  254. package/dist/data/clicky-parse.js.map +1 -0
  255. package/dist/data/diagnostics/FrameSourceWindow.cjs +0 -4
  256. package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
  257. package/dist/data/diagnostics/FrameSourceWindow.d.ts +1 -11
  258. package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
  259. package/dist/data/diagnostics/FrameSourceWindow.js +1 -5
  260. package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
  261. package/dist/data/diagnostics/FrameSourceWindow.utils.cjs +7 -0
  262. package/dist/data/diagnostics/FrameSourceWindow.utils.cjs.map +1 -0
  263. package/dist/data/diagnostics/FrameSourceWindow.utils.d.ts +12 -0
  264. package/dist/data/diagnostics/FrameSourceWindow.utils.d.ts.map +1 -0
  265. package/dist/data/diagnostics/FrameSourceWindow.utils.js +7 -0
  266. package/dist/data/diagnostics/FrameSourceWindow.utils.js.map +1 -0
  267. package/dist/data/diagnostics/JvmStackTrace.cjs +2 -1
  268. package/dist/data/diagnostics/JvmStackTrace.cjs.map +1 -1
  269. package/dist/data/diagnostics/JvmStackTrace.d.ts.map +1 -1
  270. package/dist/data/diagnostics/JvmStackTrace.js +2 -1
  271. package/dist/data/diagnostics/JvmStackTrace.js.map +1 -1
  272. package/dist/data/icon-fallback.cjs +12 -0
  273. package/dist/data/icon-fallback.cjs.map +1 -0
  274. package/dist/data/icon-fallback.d.ts +19 -0
  275. package/dist/data/icon-fallback.d.ts.map +1 -0
  276. package/dist/data/icon-fallback.js +12 -0
  277. package/dist/data/icon-fallback.js.map +1 -0
  278. package/dist/data/status-breakdown-utils.cjs +7 -0
  279. package/dist/data/status-breakdown-utils.cjs.map +1 -0
  280. package/dist/data/status-breakdown-utils.d.ts +4 -0
  281. package/dist/data/status-breakdown-utils.d.ts.map +1 -0
  282. package/dist/data/status-breakdown-utils.js +7 -0
  283. package/dist/data/status-breakdown-utils.js.map +1 -0
  284. package/dist/data/test-runner/TestRunSummary.cjs +36 -0
  285. package/dist/data/test-runner/TestRunSummary.cjs.map +1 -1
  286. package/dist/data/test-runner/TestRunSummary.d.ts +7 -1
  287. package/dist/data/test-runner/TestRunSummary.d.ts.map +1 -1
  288. package/dist/data/test-runner/TestRunSummary.js +36 -0
  289. package/dist/data/test-runner/TestRunSummary.js.map +1 -1
  290. package/dist/data/test-runner/TestRunner.cjs +5 -3
  291. package/dist/data/test-runner/TestRunner.cjs.map +1 -1
  292. package/dist/data/test-runner/TestRunner.d.ts +13 -1
  293. package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
  294. package/dist/data/test-runner/TestRunner.js +5 -3
  295. package/dist/data/test-runner/TestRunner.js.map +1 -1
  296. package/dist/data/version-info.cjs +3 -3
  297. package/dist/data/version-info.js +3 -3
  298. package/dist/data.cjs +19 -6
  299. package/dist/data.cjs.map +1 -1
  300. package/dist/data.d.ts +14 -6
  301. package/dist/data.d.ts.map +1 -1
  302. package/dist/data.js +18 -5
  303. package/dist/data.js.map +1 -1
  304. package/dist/index.cjs +57 -7
  305. package/dist/index.cjs.map +1 -1
  306. package/dist/index.js +56 -6
  307. package/dist/index.js.map +1 -1
  308. package/dist/layout/AppShell.cjs +332 -0
  309. package/dist/layout/AppShell.cjs.map +1 -0
  310. package/dist/layout/AppShell.d.ts +75 -0
  311. package/dist/layout/AppShell.d.ts.map +1 -0
  312. package/dist/layout/AppShell.js +332 -0
  313. package/dist/layout/AppShell.js.map +1 -0
  314. package/dist/layout/AppSidebar.cjs +239 -0
  315. package/dist/layout/AppSidebar.cjs.map +1 -0
  316. package/dist/layout/AppSidebar.d.ts +62 -0
  317. package/dist/layout/AppSidebar.d.ts.map +1 -0
  318. package/dist/layout/AppSidebar.js +239 -0
  319. package/dist/layout/AppSidebar.js.map +1 -0
  320. package/dist/layout/Panel.cjs +66 -0
  321. package/dist/layout/Panel.cjs.map +1 -0
  322. package/dist/layout/Panel.d.ts +34 -0
  323. package/dist/layout/Panel.d.ts.map +1 -0
  324. package/dist/layout/Panel.js +66 -0
  325. package/dist/layout/Panel.js.map +1 -0
  326. package/dist/layout/Tabs.cjs +36 -0
  327. package/dist/layout/Tabs.cjs.map +1 -0
  328. package/dist/layout/Tabs.d.ts +36 -0
  329. package/dist/layout/Tabs.d.ts.map +1 -0
  330. package/dist/layout/Tabs.js +36 -0
  331. package/dist/layout/Tabs.js.map +1 -0
  332. package/dist/overlay/DropdownMenu.cjs.map +1 -1
  333. package/dist/overlay/DropdownMenu.d.ts.map +1 -1
  334. package/dist/overlay/DropdownMenu.js.map +1 -1
  335. package/dist/overlay/Modal.cjs +4 -2
  336. package/dist/overlay/Modal.cjs.map +1 -1
  337. package/dist/overlay/Modal.d.ts +1 -1
  338. package/dist/overlay/Modal.d.ts.map +1 -1
  339. package/dist/overlay/Modal.js +4 -2
  340. package/dist/overlay/Modal.js.map +1 -1
  341. package/dist/overlay/Toast.cjs +89 -0
  342. package/dist/overlay/Toast.cjs.map +1 -0
  343. package/dist/overlay/Toast.d.ts +14 -0
  344. package/dist/overlay/Toast.d.ts.map +1 -0
  345. package/dist/overlay/Toast.js +89 -0
  346. package/dist/overlay/Toast.js.map +1 -0
  347. package/dist/overlay/toast-context.cjs +12 -0
  348. package/dist/overlay/toast-context.cjs.map +1 -0
  349. package/dist/overlay/toast-context.d.ts +24 -0
  350. package/dist/overlay/toast-context.d.ts.map +1 -0
  351. package/dist/overlay/toast-context.js +12 -0
  352. package/dist/overlay/toast-context.js.map +1 -0
  353. package/dist/rpc/AcceptPicker.cjs +81 -58
  354. package/dist/rpc/AcceptPicker.cjs.map +1 -1
  355. package/dist/rpc/AcceptPicker.d.ts.map +1 -1
  356. package/dist/rpc/AcceptPicker.js +81 -58
  357. package/dist/rpc/AcceptPicker.js.map +1 -1
  358. package/dist/rpc/CommandForm.cjs +5 -35
  359. package/dist/rpc/CommandForm.cjs.map +1 -1
  360. package/dist/rpc/CommandForm.d.ts +0 -3
  361. package/dist/rpc/CommandForm.d.ts.map +1 -1
  362. package/dist/rpc/CommandForm.js +2 -32
  363. package/dist/rpc/CommandForm.js.map +1 -1
  364. package/dist/rpc/CommandOutput.cjs +2 -1
  365. package/dist/rpc/CommandOutput.cjs.map +1 -1
  366. package/dist/rpc/CommandOutput.d.ts.map +1 -1
  367. package/dist/rpc/CommandOutput.js +2 -1
  368. package/dist/rpc/CommandOutput.js.map +1 -1
  369. package/dist/rpc/EntityExplorerApp.cjs +28 -83
  370. package/dist/rpc/EntityExplorerApp.cjs.map +1 -1
  371. package/dist/rpc/EntityExplorerApp.d.ts +1 -4
  372. package/dist/rpc/EntityExplorerApp.d.ts.map +1 -1
  373. package/dist/rpc/EntityExplorerApp.js +13 -68
  374. package/dist/rpc/EntityExplorerApp.js.map +1 -1
  375. package/dist/rpc/OperationCatalog.cjs +2 -2
  376. package/dist/rpc/OperationCatalog.cjs.map +1 -1
  377. package/dist/rpc/OperationCatalog.d.ts +1 -1
  378. package/dist/rpc/OperationCatalog.d.ts.map +1 -1
  379. package/dist/rpc/OperationCatalog.js +1 -1
  380. package/dist/rpc/OperationCatalog.js.map +1 -1
  381. package/dist/rpc/OperationCommandPage.cjs +6 -4
  382. package/dist/rpc/OperationCommandPage.cjs.map +1 -1
  383. package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
  384. package/dist/rpc/OperationCommandPage.js +3 -1
  385. package/dist/rpc/OperationCommandPage.js.map +1 -1
  386. package/dist/rpc/RouterProvider.cjs +10 -0
  387. package/dist/rpc/RouterProvider.cjs.map +1 -0
  388. package/dist/rpc/RouterProvider.d.ts +10 -0
  389. package/dist/rpc/RouterProvider.d.ts.map +1 -0
  390. package/dist/rpc/RouterProvider.js +10 -0
  391. package/dist/rpc/RouterProvider.js.map +1 -0
  392. package/dist/rpc/apiClient.cjs +4 -4
  393. package/dist/rpc/apiClient.cjs.map +1 -1
  394. package/dist/rpc/apiClient.js +4 -4
  395. package/dist/rpc/apiClient.js.map +1 -1
  396. package/dist/rpc/command-form-utils.cjs +43 -0
  397. package/dist/rpc/command-form-utils.cjs.map +1 -0
  398. package/dist/rpc/command-form-utils.d.ts +5 -0
  399. package/dist/rpc/command-form-utils.d.ts.map +1 -0
  400. package/dist/rpc/command-form-utils.js +43 -0
  401. package/dist/rpc/command-form-utils.js.map +1 -0
  402. package/dist/rpc/commandHref.cjs +62 -0
  403. package/dist/rpc/commandHref.cjs.map +1 -0
  404. package/dist/rpc/commandHref.d.ts +7 -0
  405. package/dist/rpc/commandHref.d.ts.map +1 -0
  406. package/dist/rpc/commandHref.js +62 -0
  407. package/dist/rpc/commandHref.js.map +1 -0
  408. package/dist/rpc/formMetadata.cjs +1 -1
  409. package/dist/rpc/formMetadata.cjs.map +1 -1
  410. package/dist/rpc/formMetadata.js +1 -1
  411. package/dist/rpc/formMetadata.js.map +1 -1
  412. package/dist/rpc/router.cjs +83 -0
  413. package/dist/rpc/router.cjs.map +1 -0
  414. package/dist/rpc/router.d.ts +24 -0
  415. package/dist/rpc/router.d.ts.map +1 -0
  416. package/dist/rpc/router.js +83 -0
  417. package/dist/rpc/router.js.map +1 -0
  418. package/dist/rpc/rpc-story-fixtures/orders.fixture.d.ts +3 -0
  419. package/dist/rpc/rpc-story-fixtures/orders.fixture.d.ts.map +1 -0
  420. package/dist/rpc/rpc-story-fixtures/services.fixture.d.ts +3 -0
  421. package/dist/rpc/rpc-story-fixtures/services.fixture.d.ts.map +1 -0
  422. package/dist/rpc/rpc-story-fixtures/surface-fixture.d.ts +24 -0
  423. package/dist/rpc/rpc-story-fixtures/surface-fixture.d.ts.map +1 -0
  424. package/dist/rpc/rpc-story-fixtures/widgets.fixture.d.ts +3 -0
  425. package/dist/rpc/rpc-story-fixtures/widgets.fixture.d.ts.map +1 -0
  426. package/dist/rpc/rpc-story.fixtures.d.ts +16 -0
  427. package/dist/rpc/rpc-story.fixtures.d.ts.map +1 -0
  428. package/dist/rpc.cjs +17 -0
  429. package/dist/rpc.cjs.map +1 -1
  430. package/dist/rpc.d.ts +5 -0
  431. package/dist/rpc.d.ts.map +1 -1
  432. package/dist/rpc.js +18 -1
  433. package/dist/rpc.js.map +1 -1
  434. package/dist/styles.cjs +1 -0
  435. package/dist/styles.cjs.map +1 -1
  436. package/dist/styles.css +1 -1
  437. package/dist/styles.d.ts.map +1 -1
  438. package/dist/styles.js +1 -0
  439. package/dist/styles.js.map +1 -1
  440. package/dist/tailwind-preset.cjs +36 -19
  441. package/dist/tailwind-preset.cjs.map +1 -1
  442. package/dist/tailwind-preset.d.ts.map +1 -1
  443. package/dist/tailwind-preset.js +36 -19
  444. package/dist/tailwind-preset.js.map +1 -1
  445. package/package.json +11 -1
@@ -0,0 +1,156 @@
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
+ import { useState, useEffect, useCallback } from "react";
3
+ import { cn } from "../../lib/utils.js";
4
+ import { Button } from "../../components/button.js";
5
+ import { Icon } from "../Icon.js";
6
+ import { Chat } from "../chat/Chat.js";
7
+ import { useChatWindowManager } from "./chat-window-context.js";
8
+ import { ThreadPicker } from "./ThreadPicker.js";
9
+ import { ContextBadges } from "./ContextBadges.js";
10
+ import { ToolPreferences } from "./ToolPreferences.js";
11
+ import { serializeContext } from "./context.js";
12
+ import { UiAdd } from "../../icons/components/UiAdd.js";
13
+ import { UiFullscreen } from "../../icons/components/UiFullscreen.js";
14
+ import { UiClose } from "../../icons/components/UiClose.js";
15
+ const MAXIMIZE_CSS = `
16
+ .chat-maximized .react-draggable {
17
+ transform: none !important;
18
+ width: auto !important;
19
+ height: auto !important;
20
+ inset: 0 !important;
21
+ position: absolute !important;
22
+ }`;
23
+ function ChatWindow({
24
+ panel,
25
+ chat,
26
+ title = "Assistant",
27
+ threadsApi = "/api/chat/threads",
28
+ threadsSource,
29
+ contextTypeConfig,
30
+ tools,
31
+ headerExtras
32
+ }) {
33
+ const { updatePanel, closePanel, bringToFront, maximizePanel, openPanel } = useChatWindowManager();
34
+ const [Rnd, setRnd] = useState(null);
35
+ const [toolPrefs, setToolPrefs] = useState({});
36
+ useEffect(() => {
37
+ if (!(tools == null ? void 0 : tools.length)) return;
38
+ setToolPrefs((prev) => {
39
+ const next = { ...prev };
40
+ let changed = false;
41
+ for (const t of tools) {
42
+ if (next[t.name] === void 0) {
43
+ next[t.name] = "ask";
44
+ changed = true;
45
+ }
46
+ }
47
+ return changed ? next : prev;
48
+ });
49
+ }, [tools]);
50
+ useEffect(() => {
51
+ let active = true;
52
+ import("react-rnd").then((m) => {
53
+ if (active) setRnd(() => m.Rnd);
54
+ });
55
+ return () => {
56
+ active = false;
57
+ };
58
+ }, []);
59
+ const removeContext = useCallback(
60
+ (id) => updatePanel(panel.id, { contextItems: panel.contextItems.filter((c) => c.id !== id) }),
61
+ [updatePanel, panel.id, panel.contextItems]
62
+ );
63
+ const mergedBody = {
64
+ ...chat == null ? void 0 : chat.body,
65
+ ...panel.contextItems.length ? { context: serializeContext(panel.contextItems) } : {},
66
+ ...tools ? { toolPreferences: toolPrefs } : {}
67
+ };
68
+ const header = /* @__PURE__ */ jsxs("div", { className: "chat-drag-handle flex cursor-move items-center gap-1 border-b border-border bg-muted/40 px-2 py-1.5", children: [
69
+ threadsSource != null || threadsApi !== null ? /* @__PURE__ */ jsx(
70
+ ThreadPicker,
71
+ {
72
+ threadId: panel.threadId,
73
+ onSelect: (tid) => updatePanel(panel.id, { threadId: tid }),
74
+ onNew: () => updatePanel(panel.id, { threadId: null }),
75
+ ...threadsSource ? { source: threadsSource } : threadsApi !== null ? { api: threadsApi } : {}
76
+ }
77
+ ) : /* @__PURE__ */ jsx("span", { className: "px-1 text-sm font-medium", children: title }),
78
+ /* @__PURE__ */ jsx("div", { className: "flex-1" }),
79
+ headerExtras,
80
+ tools && /* @__PURE__ */ jsx(ToolPreferences, { tools, value: toolPrefs, onChange: setToolPrefs }),
81
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", title: "New window", onClick: () => openPanel(), children: /* @__PURE__ */ jsx(Icon, { icon: UiAdd, className: "size-4" }) }),
82
+ /* @__PURE__ */ jsx(
83
+ Button,
84
+ {
85
+ variant: "ghost",
86
+ size: "icon",
87
+ title: panel.maximized ? "Restore" : "Maximize",
88
+ onClick: () => maximizePanel(panel.id),
89
+ children: /* @__PURE__ */ jsx(Icon, { icon: UiFullscreen, className: "size-4" })
90
+ }
91
+ ),
92
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", title: "Close", onClick: () => closePanel(panel.id), children: /* @__PURE__ */ jsx(Icon, { icon: UiClose, className: "size-4" }) })
93
+ ] });
94
+ const frame = /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl", children: [
95
+ header,
96
+ /* @__PURE__ */ jsx(
97
+ ContextBadges,
98
+ {
99
+ items: panel.contextItems,
100
+ onRemove: removeContext,
101
+ ...contextTypeConfig ? { typeConfig: contextTypeConfig } : {}
102
+ }
103
+ ),
104
+ /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsx(
105
+ Chat,
106
+ {
107
+ ...chat,
108
+ ...panel.threadId ? { threadId: panel.threadId } : {},
109
+ body: mergedBody
110
+ }
111
+ ) })
112
+ ] });
113
+ const outerClass = cn(
114
+ "fixed pointer-events-none",
115
+ panel.maximized ? "inset-4 chat-maximized" : "inset-0"
116
+ );
117
+ if (!Rnd) {
118
+ return /* @__PURE__ */ jsx("div", { className: outerClass, style: { zIndex: panel.zIndex }, children: /* @__PURE__ */ jsx(
119
+ "div",
120
+ {
121
+ className: "pointer-events-auto h-full",
122
+ style: panel.maximized ? { position: "relative", width: "100%", height: "100%" } : { position: "absolute", left: panel.x, top: panel.y, width: panel.width, height: panel.height },
123
+ children: frame
124
+ }
125
+ ) });
126
+ }
127
+ return /* @__PURE__ */ jsxs("div", { className: outerClass, style: { zIndex: panel.zIndex }, children: [
128
+ /* @__PURE__ */ jsx("style", { children: MAXIMIZE_CSS }),
129
+ /* @__PURE__ */ jsx(
130
+ Rnd,
131
+ {
132
+ default: { x: panel.x, y: panel.y, width: panel.width, height: panel.height },
133
+ style: { pointerEvents: "auto" },
134
+ minWidth: 360,
135
+ minHeight: 400,
136
+ bounds: "parent",
137
+ dragHandleClassName: "chat-drag-handle",
138
+ disableDragging: panel.maximized,
139
+ enableResizing: !panel.maximized,
140
+ onDragStart: () => bringToFront(panel.id),
141
+ onDragStop: (_e, d) => updatePanel(panel.id, { x: d.x, y: d.y }),
142
+ onResizeStop: (_e, _dir, ref, _delta, pos) => updatePanel(panel.id, { width: ref.offsetWidth, height: ref.offsetHeight, x: pos.x, y: pos.y }),
143
+ children: frame
144
+ }
145
+ )
146
+ ] });
147
+ }
148
+ function ChatWindowLayer(props) {
149
+ const { panels } = useChatWindowManager();
150
+ return /* @__PURE__ */ jsx(Fragment, { children: panels.map((panel) => /* @__PURE__ */ jsx(ChatWindow, { panel, ...props }, panel.id)) });
151
+ }
152
+ export {
153
+ ChatWindow,
154
+ ChatWindowLayer
155
+ };
156
+ //# sourceMappingURL=ChatWindow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatWindow.js","sources":["../../../src/data/ai/ChatWindow.tsx"],"sourcesContent":["import { useCallback, useEffect, useState, type ReactNode } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../../components/button\";\nimport { Icon } from \"../Icon\";\nimport { UiAdd, UiClose, UiFullscreen } from \"../../icons\";\nimport { Chat, type ChatProps } from \"../chat/Chat\";\nimport { useChatWindowManager, type ChatWindowState } from \"./chat-window-context\";\nimport { ThreadPicker, type ThreadSource } from \"./ThreadPicker\";\nimport { ContextBadges } from \"./ContextBadges\";\nimport { ToolPreferences, type ToolMeta, type ToolMode } from \"./ToolPreferences\";\nimport { serializeContext, type ContextTypeConfig } from \"./context\";\n\nexport type ChatWindowProps = {\n panel: ChatWindowState;\n /** Props forwarded to the inner <Chat>. The window manages `threadId` and\n * merges attached context / tool preferences into `body` on top of these. */\n chat?: Partial<ChatProps>;\n /** Header title shown when the thread picker is disabled. */\n title?: ReactNode;\n /** Thread switcher endpoint, or null to hide the picker. Defaults to\n * \"/api/chat/threads\". Ignored when `threadsSource` is set. */\n threadsApi?: string | null;\n /** Inject the thread list/delete directly instead of fetching `threadsApi`\n * (e.g. an app that loads conversations via its own client). Shows the\n * picker regardless of `threadsApi`. */\n threadsSource?: ThreadSource;\n /** Maps context item `type` to an icon/colour for the badge row. */\n contextTypeConfig?: ContextTypeConfig;\n /** When provided, a tool-preferences popover is shown and forwarded as\n * `body.toolPreferences`. Tools default to \"ask\" (approval required); the\n * user can switch any tool to Auto/Off from the popover. */\n tools?: ToolMeta[];\n /** Extra controls rendered in the header, e.g. a <ContextUsage/> gauge. */\n headerExtras?: ReactNode;\n};\n\nconst MAXIMIZE_CSS = `\n.chat-maximized .react-draggable {\n transform: none !important;\n width: auto !important;\n height: auto !important;\n inset: 0 !important;\n position: absolute !important;\n}`;\n\n/** A draggable, resizable floating chat window. It lazy-loads `react-rnd` (an\n * optional dependency, so consumers of just the inner <Chat> never pull it)\n * and renders the existing <Chat> beneath a drag-handle header with thread\n * switching, a context-badge row and optional tool preferences. */\nexport function ChatWindow({\n panel,\n chat,\n title = \"Assistant\",\n threadsApi = \"/api/chat/threads\",\n threadsSource,\n contextTypeConfig,\n tools,\n headerExtras,\n}: ChatWindowProps) {\n const { updatePanel, closePanel, bringToFront, maximizePanel, openPanel } = useChatWindowManager();\n const [Rnd, setRnd] = useState<typeof import(\"react-rnd\").Rnd | null>(null);\n const [toolPrefs, setToolPrefs] = useState<Record<string, ToolMode>>({});\n\n // Tools default to \"ask\" (human-in-the-loop approval) on chat windows. Seed\n // any tool the user hasn't configured yet; existing choices are preserved.\n // Handles tools that load asynchronously after mount.\n useEffect(() => {\n if (!tools?.length) return;\n setToolPrefs((prev) => {\n const next = { ...prev };\n let changed = false;\n for (const t of tools) {\n if (next[t.name] === undefined) {\n next[t.name] = \"ask\";\n changed = true;\n }\n }\n return changed ? next : prev;\n });\n }, [tools]);\n\n useEffect(() => {\n let active = true;\n import(\"react-rnd\").then((m) => {\n if (active) setRnd(() => m.Rnd);\n });\n return () => {\n active = false;\n };\n }, []);\n\n const removeContext = useCallback(\n (id: string) =>\n updatePanel(panel.id, { contextItems: panel.contextItems.filter((c) => c.id !== id) }),\n [updatePanel, panel.id, panel.contextItems],\n );\n\n const mergedBody: Record<string, unknown> = {\n ...chat?.body,\n ...(panel.contextItems.length ? { context: serializeContext(panel.contextItems) } : {}),\n ...(tools ? { toolPreferences: toolPrefs } : {}),\n };\n\n const header = (\n <div className=\"chat-drag-handle flex cursor-move items-center gap-1 border-b border-border bg-muted/40 px-2 py-1.5\">\n {threadsSource != null || threadsApi !== null ? (\n <ThreadPicker\n threadId={panel.threadId}\n onSelect={(tid) => updatePanel(panel.id, { threadId: tid })}\n onNew={() => updatePanel(panel.id, { threadId: null })}\n {...(threadsSource\n ? { source: threadsSource }\n : threadsApi !== null\n ? { api: threadsApi }\n : {})}\n />\n ) : (\n <span className=\"px-1 text-sm font-medium\">{title}</span>\n )}\n <div className=\"flex-1\" />\n {headerExtras}\n {tools && <ToolPreferences tools={tools} value={toolPrefs} onChange={setToolPrefs} />}\n <Button variant=\"ghost\" size=\"icon\" title=\"New window\" onClick={() => openPanel()}>\n <Icon icon={UiAdd} className=\"size-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n title={panel.maximized ? \"Restore\" : \"Maximize\"}\n onClick={() => maximizePanel(panel.id)}\n >\n <Icon icon={UiFullscreen} className=\"size-4\" />\n </Button>\n <Button variant=\"ghost\" size=\"icon\" title=\"Close\" onClick={() => closePanel(panel.id)}>\n <Icon icon={UiClose} className=\"size-4\" />\n </Button>\n </div>\n );\n\n const frame = (\n <div className=\"flex h-full flex-col overflow-hidden rounded-lg border border-border bg-background shadow-xl\">\n {header}\n <ContextBadges\n items={panel.contextItems}\n onRemove={removeContext}\n {...(contextTypeConfig ? { typeConfig: contextTypeConfig } : {})}\n />\n <div className=\"min-h-0 flex-1\">\n <Chat\n {...chat}\n {...(panel.threadId ? { threadId: panel.threadId } : {})}\n body={mergedBody}\n />\n </div>\n </div>\n );\n\n const outerClass = cn(\n \"fixed pointer-events-none\",\n panel.maximized ? \"inset-4 chat-maximized\" : \"inset-0\",\n );\n\n // Until react-rnd loads (and as a graceful fallback if it never does) the\n // window is statically positioned — still usable, just not draggable.\n if (!Rnd) {\n return (\n <div className={outerClass} style={{ zIndex: panel.zIndex }}>\n <div\n className=\"pointer-events-auto h-full\"\n style={\n panel.maximized\n ? { position: \"relative\", width: \"100%\", height: \"100%\" }\n : { position: \"absolute\", left: panel.x, top: panel.y, width: panel.width, height: panel.height }\n }\n >\n {frame}\n </div>\n </div>\n );\n }\n\n return (\n <div className={outerClass} style={{ zIndex: panel.zIndex }}>\n <style>{MAXIMIZE_CSS}</style>\n <Rnd\n default={{ x: panel.x, y: panel.y, width: panel.width, height: panel.height }}\n style={{ pointerEvents: \"auto\" }}\n minWidth={360}\n minHeight={400}\n bounds=\"parent\"\n dragHandleClassName=\"chat-drag-handle\"\n disableDragging={panel.maximized}\n enableResizing={!panel.maximized}\n onDragStart={() => bringToFront(panel.id)}\n onDragStop={(_e, d) => updatePanel(panel.id, { x: d.x, y: d.y })}\n onResizeStop={(_e, _dir, ref, _delta, pos) =>\n updatePanel(panel.id, { width: ref.offsetWidth, height: ref.offsetHeight, x: pos.x, y: pos.y })\n }\n >\n {frame}\n </Rnd>\n </div>\n );\n}\n\n/** Renders every open window for the current {@link useChatWindowManager}.\n * Drop one of these near the root alongside a <ChatFab/>. */\nexport function ChatWindowLayer(props: Omit<ChatWindowProps, \"panel\">) {\n const { panels } = useChatWindowManager();\n return (\n <>\n {panels.map((panel) => (\n <ChatWindow key={panel.id} panel={panel} {...props} />\n ))}\n </>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const chatWindowContext = require("./chat-window-context.cjs");
6
+ function ChatWindowManagerProvider({
7
+ storageId = "default",
8
+ children
9
+ }) {
10
+ const [panels, setPanels] = react.useState([]);
11
+ const hydratedRef = react.useRef(false);
12
+ const saveTimerRef = react.useRef(null);
13
+ react.useEffect(() => {
14
+ if (hydratedRef.current) return;
15
+ hydratedRef.current = true;
16
+ const loaded = chatWindowContext.loadPanels(storageId);
17
+ if (loaded.length > 0) setPanels(loaded);
18
+ }, [storageId]);
19
+ const scheduleSave = react.useCallback(
20
+ (updated) => {
21
+ if (saveTimerRef.current) clearTimeout(saveTimerRef.current);
22
+ saveTimerRef.current = setTimeout(() => chatWindowContext.savePanels(storageId, updated), 1e3);
23
+ },
24
+ [storageId]
25
+ );
26
+ react.useEffect(
27
+ () => () => {
28
+ if (saveTimerRef.current) clearTimeout(saveTimerRef.current);
29
+ },
30
+ []
31
+ );
32
+ const defaultPosition = react.useCallback((panelCount) => {
33
+ const vw = typeof window !== "undefined" ? window.innerWidth : 1200;
34
+ const vh = typeof window !== "undefined" ? window.innerHeight : 800;
35
+ return {
36
+ x: Math.max(40, vw - chatWindowContext.DEFAULT_WIDTH - 16 - panelCount * chatWindowContext.CASCADE_OFFSET),
37
+ y: Math.max(40, vh - chatWindowContext.DEFAULT_HEIGHT - 16 - panelCount * chatWindowContext.CASCADE_OFFSET)
38
+ };
39
+ }, []);
40
+ const openPanel = react.useCallback(
41
+ (opts) => {
42
+ const id = chatWindowContext.nextPanelId();
43
+ setPanels((prev) => {
44
+ if (prev.length >= chatWindowContext.MAX_PANELS) return prev;
45
+ const pos = defaultPosition(prev.length);
46
+ const panel = {
47
+ id,
48
+ threadId: (opts == null ? void 0 : opts.threadId) ?? null,
49
+ initialModel: (opts == null ? void 0 : opts.initialModel) ?? null,
50
+ x: pos.x,
51
+ y: pos.y,
52
+ width: chatWindowContext.DEFAULT_WIDTH,
53
+ height: chatWindowContext.DEFAULT_HEIGHT,
54
+ zIndex: chatWindowContext.Z_BASE,
55
+ maximized: false,
56
+ initialPrompt: (opts == null ? void 0 : opts.initialPrompt) ?? null,
57
+ contextItems: (opts == null ? void 0 : opts.contextItems) ?? []
58
+ };
59
+ const updated = chatWindowContext.reindex([...prev, panel], id);
60
+ scheduleSave(updated);
61
+ return updated;
62
+ });
63
+ return id;
64
+ },
65
+ [defaultPosition, scheduleSave]
66
+ );
67
+ const closePanel = react.useCallback(
68
+ (id) => {
69
+ setPanels((prev) => {
70
+ const updated = prev.filter((p) => p.id !== id);
71
+ scheduleSave(updated);
72
+ return updated;
73
+ });
74
+ },
75
+ [scheduleSave]
76
+ );
77
+ const updatePanel = react.useCallback(
78
+ (id, partial) => {
79
+ setPanels((prev) => {
80
+ const updated = prev.map((p) => p.id === id ? { ...p, ...partial } : p);
81
+ scheduleSave(updated);
82
+ return updated;
83
+ });
84
+ },
85
+ [scheduleSave]
86
+ );
87
+ const bringToFront = react.useCallback((id) => {
88
+ setPanels((prev) => chatWindowContext.reindex(prev, id));
89
+ }, []);
90
+ const maximizePanel = react.useCallback(
91
+ (id) => {
92
+ setPanels((prev) => {
93
+ const target = prev.find((p) => p.id === id);
94
+ if (!target) return prev;
95
+ const willMaximize = !target.maximized;
96
+ const toggled = prev.map((p) => {
97
+ if (p.id === id) return { ...p, maximized: willMaximize };
98
+ if (willMaximize && p.maximized) return { ...p, maximized: false };
99
+ return p;
100
+ });
101
+ const updated = chatWindowContext.reindex(toggled, id);
102
+ scheduleSave(updated);
103
+ return updated;
104
+ });
105
+ },
106
+ [scheduleSave]
107
+ );
108
+ const findOrCreatePanel = react.useCallback(
109
+ (opts) => {
110
+ var _a;
111
+ const existing = panels[panels.length - 1];
112
+ if (!existing) return openPanel(opts);
113
+ const partial = {};
114
+ if (opts == null ? void 0 : opts.initialPrompt) partial.initialPrompt = opts.initialPrompt;
115
+ if ((_a = opts == null ? void 0 : opts.contextItems) == null ? void 0 : _a.length) {
116
+ partial.contextItems = [
117
+ ...existing.contextItems,
118
+ ...opts.contextItems.filter((c) => !existing.contextItems.some((e) => e.id === c.id))
119
+ ];
120
+ }
121
+ updatePanel(existing.id, partial);
122
+ bringToFront(existing.id);
123
+ return existing.id;
124
+ },
125
+ [panels, openPanel, updatePanel, bringToFront]
126
+ );
127
+ const value = {
128
+ panels,
129
+ openPanel,
130
+ closePanel,
131
+ updatePanel,
132
+ bringToFront,
133
+ maximizePanel,
134
+ findOrCreatePanel
135
+ };
136
+ return /* @__PURE__ */ jsxRuntime.jsx(chatWindowContext.ChatWindowManagerContext.Provider, { value, children });
137
+ }
138
+ exports.ChatWindowManagerProvider = ChatWindowManagerProvider;
139
+ //# sourceMappingURL=ChatWindowManager.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatWindowManager.cjs","sources":["../../../src/data/ai/ChatWindowManager.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState, type ReactNode } from \"react\";\nimport {\n ChatWindowManagerContext,\n loadPanels,\n savePanels,\n nextPanelId,\n reindex,\n MAX_PANELS,\n DEFAULT_WIDTH,\n DEFAULT_HEIGHT,\n CASCADE_OFFSET,\n Z_BASE,\n type ChatWindowManagerValue,\n type ChatWindowState,\n type OpenPanelOpts,\n} from \"./chat-window-context\";\n\nexport type ChatWindowManagerProviderProps = {\n /** Namespaces the localStorage layout so distinct surfaces keep separate\n * window arrangements. Defaults to \"default\". */\n storageId?: string;\n children: ReactNode;\n};\n\n/** Owns the set of open chat windows: creation, focus (z-index), maximize and\n * debounced localStorage persistence of their layout. Wrap the app subtree in\n * this and read it via {@link useChatWindowManager}. */\nexport function ChatWindowManagerProvider({\n storageId = \"default\",\n children,\n}: ChatWindowManagerProviderProps) {\n const [panels, setPanels] = useState<ChatWindowState[]>([]);\n const hydratedRef = useRef(false);\n const saveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (hydratedRef.current) return;\n hydratedRef.current = true;\n const loaded = loadPanels(storageId);\n if (loaded.length > 0) setPanels(loaded);\n }, [storageId]);\n\n const scheduleSave = useCallback(\n (updated: ChatWindowState[]) => {\n if (saveTimerRef.current) clearTimeout(saveTimerRef.current);\n saveTimerRef.current = setTimeout(() => savePanels(storageId, updated), 1000);\n },\n [storageId],\n );\n\n useEffect(\n () => () => {\n if (saveTimerRef.current) clearTimeout(saveTimerRef.current);\n },\n [],\n );\n\n const defaultPosition = useCallback((panelCount: number) => {\n const vw = typeof window !== \"undefined\" ? window.innerWidth : 1200;\n const vh = typeof window !== \"undefined\" ? window.innerHeight : 800;\n return {\n x: Math.max(40, vw - DEFAULT_WIDTH - 16 - panelCount * CASCADE_OFFSET),\n y: Math.max(40, vh - DEFAULT_HEIGHT - 16 - panelCount * CASCADE_OFFSET),\n };\n }, []);\n\n const openPanel = useCallback(\n (opts?: OpenPanelOpts): string => {\n const id = nextPanelId();\n setPanels((prev) => {\n if (prev.length >= MAX_PANELS) return prev;\n const pos = defaultPosition(prev.length);\n const panel: ChatWindowState = {\n id,\n threadId: opts?.threadId ?? null,\n initialModel: opts?.initialModel ?? null,\n x: pos.x,\n y: pos.y,\n width: DEFAULT_WIDTH,\n height: DEFAULT_HEIGHT,\n zIndex: Z_BASE,\n maximized: false,\n initialPrompt: opts?.initialPrompt ?? null,\n contextItems: opts?.contextItems ?? [],\n };\n const updated = reindex([...prev, panel], id);\n scheduleSave(updated);\n return updated;\n });\n return id;\n },\n [defaultPosition, scheduleSave],\n );\n\n const closePanel = useCallback(\n (id: string) => {\n setPanels((prev) => {\n const updated = prev.filter((p) => p.id !== id);\n scheduleSave(updated);\n return updated;\n });\n },\n [scheduleSave],\n );\n\n const updatePanel = useCallback(\n (id: string, partial: Partial<ChatWindowState>) => {\n setPanels((prev) => {\n const updated = prev.map((p) => (p.id === id ? { ...p, ...partial } : p));\n scheduleSave(updated);\n return updated;\n });\n },\n [scheduleSave],\n );\n\n const bringToFront = useCallback((id: string) => {\n setPanels((prev) => reindex(prev, id));\n }, []);\n\n const maximizePanel = useCallback(\n (id: string) => {\n setPanels((prev) => {\n const target = prev.find((p) => p.id === id);\n if (!target) return prev;\n const willMaximize = !target.maximized;\n const toggled = prev.map((p) => {\n if (p.id === id) return { ...p, maximized: willMaximize };\n if (willMaximize && p.maximized) return { ...p, maximized: false };\n return p;\n });\n const updated = reindex(toggled, id);\n scheduleSave(updated);\n return updated;\n });\n },\n [scheduleSave],\n );\n\n const findOrCreatePanel = useCallback(\n (opts?: OpenPanelOpts): string => {\n const existing = panels[panels.length - 1];\n if (!existing) return openPanel(opts);\n const partial: Partial<ChatWindowState> = {};\n if (opts?.initialPrompt) partial.initialPrompt = opts.initialPrompt;\n if (opts?.contextItems?.length) {\n partial.contextItems = [\n ...existing.contextItems,\n ...opts.contextItems.filter((c) => !existing.contextItems.some((e) => e.id === c.id)),\n ];\n }\n updatePanel(existing.id, partial);\n bringToFront(existing.id);\n return existing.id;\n },\n [panels, openPanel, updatePanel, bringToFront],\n );\n\n const value: ChatWindowManagerValue = {\n panels,\n openPanel,\n closePanel,\n updatePanel,\n bringToFront,\n maximizePanel,\n findOrCreatePanel,\n };\n\n return (\n <ChatWindowManagerContext.Provider value={value}>{children}</ChatWindowManagerContext.Provider>\n );\n}\n"],"names":["useState","useRef","useEffect","loadPanels","useCallback","savePanels","DEFAULT_WIDTH","CASCADE_OFFSET","DEFAULT_HEIGHT","nextPanelId","MAX_PANELS","Z_BASE","reindex","jsx","ChatWindowManagerContext"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { ReactNode } from 'react';
2
+ export type ChatWindowManagerProviderProps = {
3
+ /** Namespaces the localStorage layout so distinct surfaces keep separate
4
+ * window arrangements. Defaults to "default". */
5
+ storageId?: string;
6
+ children: ReactNode;
7
+ };
8
+ /** Owns the set of open chat windows: creation, focus (z-index), maximize and
9
+ * debounced localStorage persistence of their layout. Wrap the app subtree in
10
+ * this and read it via {@link useChatWindowManager}. */
11
+ export declare function ChatWindowManagerProvider({ storageId, children, }: ChatWindowManagerProviderProps): import("react/jsx-runtime").JSX.Element;
12
+ //# sourceMappingURL=ChatWindowManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatWindowManager.d.ts","sourceRoot":"","sources":["../../../src/data/ai/ChatWindowManager.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAiBjF,MAAM,MAAM,8BAA8B,GAAG;IAC3C;sDACkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;yDAEyD;AACzD,wBAAgB,yBAAyB,CAAC,EACxC,SAAqB,EACrB,QAAQ,GACT,EAAE,8BAA8B,2CA6IhC"}
@@ -0,0 +1,139 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useState, useRef, useEffect, useCallback } from "react";
3
+ import { loadPanels, savePanels, DEFAULT_HEIGHT, CASCADE_OFFSET, DEFAULT_WIDTH, MAX_PANELS, reindex, Z_BASE, ChatWindowManagerContext, nextPanelId } from "./chat-window-context.js";
4
+ function ChatWindowManagerProvider({
5
+ storageId = "default",
6
+ children
7
+ }) {
8
+ const [panels, setPanels] = useState([]);
9
+ const hydratedRef = useRef(false);
10
+ const saveTimerRef = useRef(null);
11
+ useEffect(() => {
12
+ if (hydratedRef.current) return;
13
+ hydratedRef.current = true;
14
+ const loaded = loadPanels(storageId);
15
+ if (loaded.length > 0) setPanels(loaded);
16
+ }, [storageId]);
17
+ const scheduleSave = useCallback(
18
+ (updated) => {
19
+ if (saveTimerRef.current) clearTimeout(saveTimerRef.current);
20
+ saveTimerRef.current = setTimeout(() => savePanels(storageId, updated), 1e3);
21
+ },
22
+ [storageId]
23
+ );
24
+ useEffect(
25
+ () => () => {
26
+ if (saveTimerRef.current) clearTimeout(saveTimerRef.current);
27
+ },
28
+ []
29
+ );
30
+ const defaultPosition = useCallback((panelCount) => {
31
+ const vw = typeof window !== "undefined" ? window.innerWidth : 1200;
32
+ const vh = typeof window !== "undefined" ? window.innerHeight : 800;
33
+ return {
34
+ x: Math.max(40, vw - DEFAULT_WIDTH - 16 - panelCount * CASCADE_OFFSET),
35
+ y: Math.max(40, vh - DEFAULT_HEIGHT - 16 - panelCount * CASCADE_OFFSET)
36
+ };
37
+ }, []);
38
+ const openPanel = useCallback(
39
+ (opts) => {
40
+ const id = nextPanelId();
41
+ setPanels((prev) => {
42
+ if (prev.length >= MAX_PANELS) return prev;
43
+ const pos = defaultPosition(prev.length);
44
+ const panel = {
45
+ id,
46
+ threadId: (opts == null ? void 0 : opts.threadId) ?? null,
47
+ initialModel: (opts == null ? void 0 : opts.initialModel) ?? null,
48
+ x: pos.x,
49
+ y: pos.y,
50
+ width: DEFAULT_WIDTH,
51
+ height: DEFAULT_HEIGHT,
52
+ zIndex: Z_BASE,
53
+ maximized: false,
54
+ initialPrompt: (opts == null ? void 0 : opts.initialPrompt) ?? null,
55
+ contextItems: (opts == null ? void 0 : opts.contextItems) ?? []
56
+ };
57
+ const updated = reindex([...prev, panel], id);
58
+ scheduleSave(updated);
59
+ return updated;
60
+ });
61
+ return id;
62
+ },
63
+ [defaultPosition, scheduleSave]
64
+ );
65
+ const closePanel = useCallback(
66
+ (id) => {
67
+ setPanels((prev) => {
68
+ const updated = prev.filter((p) => p.id !== id);
69
+ scheduleSave(updated);
70
+ return updated;
71
+ });
72
+ },
73
+ [scheduleSave]
74
+ );
75
+ const updatePanel = useCallback(
76
+ (id, partial) => {
77
+ setPanels((prev) => {
78
+ const updated = prev.map((p) => p.id === id ? { ...p, ...partial } : p);
79
+ scheduleSave(updated);
80
+ return updated;
81
+ });
82
+ },
83
+ [scheduleSave]
84
+ );
85
+ const bringToFront = useCallback((id) => {
86
+ setPanels((prev) => reindex(prev, id));
87
+ }, []);
88
+ const maximizePanel = useCallback(
89
+ (id) => {
90
+ setPanels((prev) => {
91
+ const target = prev.find((p) => p.id === id);
92
+ if (!target) return prev;
93
+ const willMaximize = !target.maximized;
94
+ const toggled = prev.map((p) => {
95
+ if (p.id === id) return { ...p, maximized: willMaximize };
96
+ if (willMaximize && p.maximized) return { ...p, maximized: false };
97
+ return p;
98
+ });
99
+ const updated = reindex(toggled, id);
100
+ scheduleSave(updated);
101
+ return updated;
102
+ });
103
+ },
104
+ [scheduleSave]
105
+ );
106
+ const findOrCreatePanel = useCallback(
107
+ (opts) => {
108
+ var _a;
109
+ const existing = panels[panels.length - 1];
110
+ if (!existing) return openPanel(opts);
111
+ const partial = {};
112
+ if (opts == null ? void 0 : opts.initialPrompt) partial.initialPrompt = opts.initialPrompt;
113
+ if ((_a = opts == null ? void 0 : opts.contextItems) == null ? void 0 : _a.length) {
114
+ partial.contextItems = [
115
+ ...existing.contextItems,
116
+ ...opts.contextItems.filter((c) => !existing.contextItems.some((e) => e.id === c.id))
117
+ ];
118
+ }
119
+ updatePanel(existing.id, partial);
120
+ bringToFront(existing.id);
121
+ return existing.id;
122
+ },
123
+ [panels, openPanel, updatePanel, bringToFront]
124
+ );
125
+ const value = {
126
+ panels,
127
+ openPanel,
128
+ closePanel,
129
+ updatePanel,
130
+ bringToFront,
131
+ maximizePanel,
132
+ findOrCreatePanel
133
+ };
134
+ return /* @__PURE__ */ jsx(ChatWindowManagerContext.Provider, { value, children });
135
+ }
136
+ export {
137
+ ChatWindowManagerProvider
138
+ };
139
+ //# sourceMappingURL=ChatWindowManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatWindowManager.js","sources":["../../../src/data/ai/ChatWindowManager.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState, type ReactNode } from \"react\";\nimport {\n ChatWindowManagerContext,\n loadPanels,\n savePanels,\n nextPanelId,\n reindex,\n MAX_PANELS,\n DEFAULT_WIDTH,\n DEFAULT_HEIGHT,\n CASCADE_OFFSET,\n Z_BASE,\n type ChatWindowManagerValue,\n type ChatWindowState,\n type OpenPanelOpts,\n} from \"./chat-window-context\";\n\nexport type ChatWindowManagerProviderProps = {\n /** Namespaces the localStorage layout so distinct surfaces keep separate\n * window arrangements. Defaults to \"default\". */\n storageId?: string;\n children: ReactNode;\n};\n\n/** Owns the set of open chat windows: creation, focus (z-index), maximize and\n * debounced localStorage persistence of their layout. Wrap the app subtree in\n * this and read it via {@link useChatWindowManager}. */\nexport function ChatWindowManagerProvider({\n storageId = \"default\",\n children,\n}: ChatWindowManagerProviderProps) {\n const [panels, setPanels] = useState<ChatWindowState[]>([]);\n const hydratedRef = useRef(false);\n const saveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (hydratedRef.current) return;\n hydratedRef.current = true;\n const loaded = loadPanels(storageId);\n if (loaded.length > 0) setPanels(loaded);\n }, [storageId]);\n\n const scheduleSave = useCallback(\n (updated: ChatWindowState[]) => {\n if (saveTimerRef.current) clearTimeout(saveTimerRef.current);\n saveTimerRef.current = setTimeout(() => savePanels(storageId, updated), 1000);\n },\n [storageId],\n );\n\n useEffect(\n () => () => {\n if (saveTimerRef.current) clearTimeout(saveTimerRef.current);\n },\n [],\n );\n\n const defaultPosition = useCallback((panelCount: number) => {\n const vw = typeof window !== \"undefined\" ? window.innerWidth : 1200;\n const vh = typeof window !== \"undefined\" ? window.innerHeight : 800;\n return {\n x: Math.max(40, vw - DEFAULT_WIDTH - 16 - panelCount * CASCADE_OFFSET),\n y: Math.max(40, vh - DEFAULT_HEIGHT - 16 - panelCount * CASCADE_OFFSET),\n };\n }, []);\n\n const openPanel = useCallback(\n (opts?: OpenPanelOpts): string => {\n const id = nextPanelId();\n setPanels((prev) => {\n if (prev.length >= MAX_PANELS) return prev;\n const pos = defaultPosition(prev.length);\n const panel: ChatWindowState = {\n id,\n threadId: opts?.threadId ?? null,\n initialModel: opts?.initialModel ?? null,\n x: pos.x,\n y: pos.y,\n width: DEFAULT_WIDTH,\n height: DEFAULT_HEIGHT,\n zIndex: Z_BASE,\n maximized: false,\n initialPrompt: opts?.initialPrompt ?? null,\n contextItems: opts?.contextItems ?? [],\n };\n const updated = reindex([...prev, panel], id);\n scheduleSave(updated);\n return updated;\n });\n return id;\n },\n [defaultPosition, scheduleSave],\n );\n\n const closePanel = useCallback(\n (id: string) => {\n setPanels((prev) => {\n const updated = prev.filter((p) => p.id !== id);\n scheduleSave(updated);\n return updated;\n });\n },\n [scheduleSave],\n );\n\n const updatePanel = useCallback(\n (id: string, partial: Partial<ChatWindowState>) => {\n setPanels((prev) => {\n const updated = prev.map((p) => (p.id === id ? { ...p, ...partial } : p));\n scheduleSave(updated);\n return updated;\n });\n },\n [scheduleSave],\n );\n\n const bringToFront = useCallback((id: string) => {\n setPanels((prev) => reindex(prev, id));\n }, []);\n\n const maximizePanel = useCallback(\n (id: string) => {\n setPanels((prev) => {\n const target = prev.find((p) => p.id === id);\n if (!target) return prev;\n const willMaximize = !target.maximized;\n const toggled = prev.map((p) => {\n if (p.id === id) return { ...p, maximized: willMaximize };\n if (willMaximize && p.maximized) return { ...p, maximized: false };\n return p;\n });\n const updated = reindex(toggled, id);\n scheduleSave(updated);\n return updated;\n });\n },\n [scheduleSave],\n );\n\n const findOrCreatePanel = useCallback(\n (opts?: OpenPanelOpts): string => {\n const existing = panels[panels.length - 1];\n if (!existing) return openPanel(opts);\n const partial: Partial<ChatWindowState> = {};\n if (opts?.initialPrompt) partial.initialPrompt = opts.initialPrompt;\n if (opts?.contextItems?.length) {\n partial.contextItems = [\n ...existing.contextItems,\n ...opts.contextItems.filter((c) => !existing.contextItems.some((e) => e.id === c.id)),\n ];\n }\n updatePanel(existing.id, partial);\n bringToFront(existing.id);\n return existing.id;\n },\n [panels, openPanel, updatePanel, bringToFront],\n );\n\n const value: ChatWindowManagerValue = {\n panels,\n openPanel,\n closePanel,\n updatePanel,\n bringToFront,\n maximizePanel,\n findOrCreatePanel,\n };\n\n return (\n <ChatWindowManagerContext.Provider value={value}>{children}</ChatWindowManagerContext.Provider>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const utils = require("../../lib/utils.cjs");
5
+ const Icon = require("../Icon.cjs");
6
+ const UiClose = require("../../icons/components/UiClose.cjs");
7
+ const DEFAULT_STYLE = {
8
+ className: "text-muted-foreground bg-muted"
9
+ };
10
+ function styleFor(type, config) {
11
+ return (config == null ? void 0 : config[type]) ?? DEFAULT_STYLE;
12
+ }
13
+ function detail(item) {
14
+ const fields = item.fields;
15
+ if (!fields) return "";
16
+ return Object.entries(fields).filter(([, v]) => v != null && v !== "").map(([, v]) => v).join(" ");
17
+ }
18
+ function ContextBadges({ items, onRemove, typeConfig, className }) {
19
+ if (items.length === 0) return null;
20
+ const readonly = !onRemove;
21
+ return /* @__PURE__ */ jsxRuntime.jsx(
22
+ "div",
23
+ {
24
+ className: utils.cn(
25
+ readonly ? "flex flex-wrap gap-1" : "flex flex-wrap gap-1.5 px-2 py-1.5",
26
+ className
27
+ ),
28
+ children: items.map((item) => {
29
+ const style = styleFor(item.type, typeConfig);
30
+ const d = detail(item);
31
+ return /* @__PURE__ */ jsxRuntime.jsxs(
32
+ "span",
33
+ {
34
+ "data-testid": `context-badge-${item.type}`,
35
+ className: utils.cn(
36
+ "inline-flex items-center gap-1.5 rounded-lg border",
37
+ readonly ? "px-1.5 py-0.5 text-[10px]" : "px-2 py-1 text-xs",
38
+ style.className
39
+ ),
40
+ children: [
41
+ style.icon && /* @__PURE__ */ jsxRuntime.jsx(
42
+ Icon.Icon,
43
+ {
44
+ ...typeof style.icon === "string" ? { name: style.icon } : { icon: style.icon },
45
+ className: "size-3.5 shrink-0"
46
+ }
47
+ ),
48
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium truncate max-w-[180px]", children: item.label }),
49
+ d && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-70 truncate max-w-[100px]", children: d }),
50
+ onRemove && /* @__PURE__ */ jsxRuntime.jsx(
51
+ "button",
52
+ {
53
+ type: "button",
54
+ "data-testid": "context-badge-remove",
55
+ "aria-label": `Remove ${item.label}`,
56
+ onClick: () => onRemove(item.id),
57
+ className: "ml-0.5 opacity-60 hover:opacity-100",
58
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiClose.UiClose, className: "size-3" })
59
+ }
60
+ )
61
+ ]
62
+ },
63
+ item.id
64
+ );
65
+ })
66
+ }
67
+ );
68
+ }
69
+ function ContextBadgesReadonly(props) {
70
+ return /* @__PURE__ */ jsxRuntime.jsx(ContextBadges, { ...props });
71
+ }
72
+ exports.ContextBadges = ContextBadges;
73
+ exports.ContextBadgesReadonly = ContextBadgesReadonly;
74
+ //# sourceMappingURL=ContextBadges.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextBadges.cjs","sources":["../../../src/data/ai/ContextBadges.tsx"],"sourcesContent":["import { cn } from \"../../lib/utils\";\nimport { Icon } from \"../Icon\";\nimport { UiClose } from \"../../icons\";\nimport type { ChatContextItem, ContextTypeConfig, ContextTypeStyle } from \"./context\";\n\nconst DEFAULT_STYLE: ContextTypeStyle = {\n className: \"text-muted-foreground bg-muted\",\n};\n\nfunction styleFor(type: string, config?: ContextTypeConfig): ContextTypeStyle {\n return config?.[type] ?? DEFAULT_STYLE;\n}\n\nfunction detail(item: ChatContextItem): string {\n const fields = item.fields;\n if (!fields) return \"\";\n return Object.entries(fields)\n .filter(([, v]) => v != null && v !== \"\")\n .map(([, v]) => v)\n .join(\" \");\n}\n\nexport type ContextBadgesProps = {\n items: ChatContextItem[];\n /** Removes the badge with the given id. When omitted the badges are read-only. */\n onRemove?: (id: string) => void;\n /** Maps each item `type` to an icon/colour; falls back to a neutral style. */\n typeConfig?: ContextTypeConfig;\n className?: string;\n};\n\n/** A wrapping row of context chips. Interactive (each removable) when `onRemove`\n * is supplied, otherwise static. The financial type→colour map lives entirely\n * in the caller-supplied `typeConfig`, so this is domain-agnostic. */\nexport function ContextBadges({ items, onRemove, typeConfig, className }: ContextBadgesProps) {\n if (items.length === 0) return null;\n const readonly = !onRemove;\n return (\n <div\n className={cn(\n readonly ? \"flex flex-wrap gap-1\" : \"flex flex-wrap gap-1.5 px-2 py-1.5\",\n className,\n )}\n >\n {items.map((item) => {\n const style = styleFor(item.type, typeConfig);\n const d = detail(item);\n return (\n <span\n key={item.id}\n data-testid={`context-badge-${item.type}`}\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-lg border\",\n readonly ? \"px-1.5 py-0.5 text-[10px]\" : \"px-2 py-1 text-xs\",\n style.className,\n )}\n >\n {style.icon && (\n <Icon\n {...(typeof style.icon === \"string\" ? { name: style.icon } : { icon: style.icon })}\n className=\"size-3.5 shrink-0\"\n />\n )}\n <span className=\"font-medium truncate max-w-[180px]\">{item.label}</span>\n {d && <span className=\"opacity-70 truncate max-w-[100px]\">{d}</span>}\n {onRemove && (\n <button\n type=\"button\"\n data-testid=\"context-badge-remove\"\n aria-label={`Remove ${item.label}`}\n onClick={() => onRemove(item.id)}\n className=\"ml-0.5 opacity-60 hover:opacity-100\"\n >\n <Icon icon={UiClose} className=\"size-3\" />\n </button>\n )}\n </span>\n );\n })}\n </div>\n );\n}\n\n/** Convenience alias for static context chips (no remove control). */\nexport function ContextBadgesReadonly(props: Omit<ContextBadgesProps, \"onRemove\">) {\n return <ContextBadges {...props} />;\n}\n"],"names":["jsx","cn","jsxs","Icon","UiClose"],"mappings":";;;;;;AAKA,MAAM,gBAAkC;AAAA,EACtC,WAAW;AACb;AAEA,SAAS,SAAS,MAAc,QAA8C;AAC5E,UAAO,iCAAS,UAAS;AAC3B;AAEA,SAAS,OAAO,MAA+B;AAC7C,QAAM,SAAS,KAAK;AACpB,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,OAAO,QAAQ,MAAM,EACzB,OAAO,CAAC,CAAA,EAAG,CAAC,MAAM,KAAK,QAAQ,MAAM,EAAE,EACvC,IAAI,CAAC,CAAA,EAAG,CAAC,MAAM,CAAC,EAChB,KAAK,GAAG;AACb;AAcO,SAAS,cAAc,EAAE,OAAO,UAAU,YAAY,aAAiC;AAC5F,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAM,WAAW,CAAC;AAClB,SACEA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,MAAAA;AAAAA,QACT,WAAW,yBAAyB;AAAA,QACpC;AAAA,MAAA;AAAA,MAGD,UAAA,MAAM,IAAI,CAAC,SAAS;AACnB,cAAM,QAAQ,SAAS,KAAK,MAAM,UAAU;AAC5C,cAAM,IAAI,OAAO,IAAI;AACrB,eACEC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YAEC,eAAa,iBAAiB,KAAK,IAAI;AAAA,YACvC,WAAWD,MAAAA;AAAAA,cACT;AAAA,cACA,WAAW,8BAA8B;AAAA,cACzC,MAAM;AAAA,YAAA;AAAA,YAGP,UAAA;AAAA,cAAA,MAAM,QACLD,2BAAAA;AAAAA,gBAACG,KAAAA;AAAAA,gBAAA;AAAA,kBACE,GAAI,OAAO,MAAM,SAAS,WAAW,EAAE,MAAM,MAAM,SAAS,EAAE,MAAM,MAAM,KAAA;AAAA,kBAC3E,WAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGdH,2BAAAA,IAAC,QAAA,EAAK,WAAU,sCAAsC,eAAK,OAAM;AAAA,cAChE,KAAKA,2BAAAA,IAAC,QAAA,EAAK,WAAU,qCAAqC,UAAA,GAAE;AAAA,cAC5D,YACCA,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,eAAY;AAAA,kBACZ,cAAY,UAAU,KAAK,KAAK;AAAA,kBAChC,SAAS,MAAM,SAAS,KAAK,EAAE;AAAA,kBAC/B,WAAU;AAAA,kBAEV,UAAAA,2BAAAA,IAACG,WAAA,EAAK,MAAMC,QAAAA,SAAS,WAAU,SAAA,CAAS;AAAA,gBAAA;AAAA,cAAA;AAAA,YAC1C;AAAA,UAAA;AAAA,UAzBG,KAAK;AAAA,QAAA;AAAA,MA6BhB,CAAC;AAAA,IAAA;AAAA,EAAA;AAGP;AAGO,SAAS,sBAAsB,OAA6C;AACjF,SAAOJ,+BAAC,eAAA,EAAe,GAAG,MAAA,CAAO;AACnC;;;"}
@@ -0,0 +1,16 @@
1
+ import { ChatContextItem, ContextTypeConfig } from './context';
2
+ export type ContextBadgesProps = {
3
+ items: ChatContextItem[];
4
+ /** Removes the badge with the given id. When omitted the badges are read-only. */
5
+ onRemove?: (id: string) => void;
6
+ /** Maps each item `type` to an icon/colour; falls back to a neutral style. */
7
+ typeConfig?: ContextTypeConfig;
8
+ className?: string;
9
+ };
10
+ /** A wrapping row of context chips. Interactive (each removable) when `onRemove`
11
+ * is supplied, otherwise static. The financial type→colour map lives entirely
12
+ * in the caller-supplied `typeConfig`, so this is domain-agnostic. */
13
+ export declare function ContextBadges({ items, onRemove, typeConfig, className }: ContextBadgesProps): import("react/jsx-runtime").JSX.Element | null;
14
+ /** Convenience alias for static context chips (no remove control). */
15
+ export declare function ContextBadgesReadonly(props: Omit<ContextBadgesProps, "onRemove">): import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=ContextBadges.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextBadges.d.ts","sourceRoot":"","sources":["../../../src/data/ai/ContextBadges.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAoB,MAAM,WAAW,CAAC;AAmBtF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,8EAA8E;IAC9E,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;uEAEuE;AACvE,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,kBAAkB,kDA+C3F;AAED,sEAAsE;AACtE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,2CAEhF"}