@flanksource/clicky-ui 0.3.1 → 0.3.3

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 (382) hide show
  1. package/dist/comments/CommentAuthor.cjs +58 -0
  2. package/dist/comments/CommentAuthor.cjs.map +1 -0
  3. package/dist/comments/CommentAuthor.d.ts +17 -0
  4. package/dist/comments/CommentAuthor.d.ts.map +1 -0
  5. package/dist/comments/CommentAuthor.js +58 -0
  6. package/dist/comments/CommentAuthor.js.map +1 -0
  7. package/dist/comments/CommentCard.cjs +343 -0
  8. package/dist/comments/CommentCard.cjs.map +1 -0
  9. package/dist/comments/CommentCard.d.ts +27 -0
  10. package/dist/comments/CommentCard.d.ts.map +1 -0
  11. package/dist/comments/CommentCard.js +343 -0
  12. package/dist/comments/CommentCard.js.map +1 -0
  13. package/dist/comments/CommentComposer.cjs +207 -0
  14. package/dist/comments/CommentComposer.cjs.map +1 -0
  15. package/dist/comments/CommentComposer.d.ts +23 -0
  16. package/dist/comments/CommentComposer.d.ts.map +1 -0
  17. package/dist/comments/CommentComposer.js +207 -0
  18. package/dist/comments/CommentComposer.js.map +1 -0
  19. package/dist/comments/CommentFilterBar.cjs +145 -0
  20. package/dist/comments/CommentFilterBar.cjs.map +1 -0
  21. package/dist/comments/CommentFilterBar.d.ts +15 -0
  22. package/dist/comments/CommentFilterBar.d.ts.map +1 -0
  23. package/dist/comments/CommentFilterBar.js +145 -0
  24. package/dist/comments/CommentFilterBar.js.map +1 -0
  25. package/dist/comments/CommentMarkdown.cjs +156 -0
  26. package/dist/comments/CommentMarkdown.cjs.map +1 -0
  27. package/dist/comments/CommentMarkdown.d.ts +13 -0
  28. package/dist/comments/CommentMarkdown.d.ts.map +1 -0
  29. package/dist/comments/CommentMarkdown.js +156 -0
  30. package/dist/comments/CommentMarkdown.js.map +1 -0
  31. package/dist/comments/CommentProgress.cjs +86 -0
  32. package/dist/comments/CommentProgress.cjs.map +1 -0
  33. package/dist/comments/CommentProgress.d.ts +16 -0
  34. package/dist/comments/CommentProgress.d.ts.map +1 -0
  35. package/dist/comments/CommentProgress.js +86 -0
  36. package/dist/comments/CommentProgress.js.map +1 -0
  37. package/dist/comments/CommentProvider.cjs +99 -0
  38. package/dist/comments/CommentProvider.cjs.map +1 -0
  39. package/dist/comments/CommentProvider.d.ts +19 -0
  40. package/dist/comments/CommentProvider.d.ts.map +1 -0
  41. package/dist/comments/CommentProvider.js +99 -0
  42. package/dist/comments/CommentProvider.js.map +1 -0
  43. package/dist/comments/CommentSidePanel.cjs +219 -0
  44. package/dist/comments/CommentSidePanel.cjs.map +1 -0
  45. package/dist/comments/CommentSidePanel.d.ts +16 -0
  46. package/dist/comments/CommentSidePanel.d.ts.map +1 -0
  47. package/dist/comments/CommentSidePanel.js +219 -0
  48. package/dist/comments/CommentSidePanel.js.map +1 -0
  49. package/dist/comments/CommentThread.cjs +57 -0
  50. package/dist/comments/CommentThread.cjs.map +1 -0
  51. package/dist/comments/CommentThread.d.ts +24 -0
  52. package/dist/comments/CommentThread.d.ts.map +1 -0
  53. package/dist/comments/CommentThread.js +57 -0
  54. package/dist/comments/CommentThread.js.map +1 -0
  55. package/dist/comments/CommentThreadList.cjs +124 -0
  56. package/dist/comments/CommentThreadList.cjs.map +1 -0
  57. package/dist/comments/CommentThreadList.d.ts +25 -0
  58. package/dist/comments/CommentThreadList.d.ts.map +1 -0
  59. package/dist/comments/CommentThreadList.js +124 -0
  60. package/dist/comments/CommentThreadList.js.map +1 -0
  61. package/dist/comments/GroupedComments.cjs +74 -0
  62. package/dist/comments/GroupedComments.cjs.map +1 -0
  63. package/dist/comments/GroupedComments.d.ts +18 -0
  64. package/dist/comments/GroupedComments.d.ts.map +1 -0
  65. package/dist/comments/GroupedComments.js +74 -0
  66. package/dist/comments/GroupedComments.js.map +1 -0
  67. package/dist/comments/MentionTextarea.cjs +253 -0
  68. package/dist/comments/MentionTextarea.cjs.map +1 -0
  69. package/dist/comments/MentionTextarea.d.ts +28 -0
  70. package/dist/comments/MentionTextarea.d.ts.map +1 -0
  71. package/dist/comments/MentionTextarea.js +253 -0
  72. package/dist/comments/MentionTextarea.js.map +1 -0
  73. package/dist/comments/comment-context.cjs +33 -0
  74. package/dist/comments/comment-context.cjs.map +1 -0
  75. package/dist/comments/comment-context.d.ts +32 -0
  76. package/dist/comments/comment-context.d.ts.map +1 -0
  77. package/dist/comments/comment-context.js +33 -0
  78. package/dist/comments/comment-context.js.map +1 -0
  79. package/dist/comments/comment-fixtures.d.ts +11 -0
  80. package/dist/comments/comment-fixtures.d.ts.map +1 -0
  81. package/dist/comments/comment-types.cjs +19 -0
  82. package/dist/comments/comment-types.cjs.map +1 -0
  83. package/dist/comments/comment-types.d.ts +170 -0
  84. package/dist/comments/comment-types.d.ts.map +1 -0
  85. package/dist/comments/comment-types.js +19 -0
  86. package/dist/comments/comment-types.js.map +1 -0
  87. package/dist/comments/comment-utils.cjs +216 -0
  88. package/dist/comments/comment-utils.cjs.map +1 -0
  89. package/dist/comments/comment-utils.d.ts +59 -0
  90. package/dist/comments/comment-utils.d.ts.map +1 -0
  91. package/dist/comments/comment-utils.js +216 -0
  92. package/dist/comments/comment-utils.js.map +1 -0
  93. package/dist/comments.cjs +57 -0
  94. package/dist/comments.cjs.map +1 -0
  95. package/dist/comments.d.ts +16 -0
  96. package/dist/comments.d.ts.map +1 -0
  97. package/dist/comments.js +57 -0
  98. package/dist/comments.js.map +1 -0
  99. package/dist/components/FilterBar.cjs +13 -3
  100. package/dist/components/FilterBar.cjs.map +1 -1
  101. package/dist/components/FilterBar.js +13 -3
  102. package/dist/components/FilterBar.js.map +1 -1
  103. package/dist/components/JsonSchemaForm.cjs +20 -6
  104. package/dist/components/JsonSchemaForm.cjs.map +1 -1
  105. package/dist/components/JsonSchemaForm.d.ts +1 -1
  106. package/dist/components/JsonSchemaForm.d.ts.map +1 -1
  107. package/dist/components/JsonSchemaForm.js +22 -8
  108. package/dist/components/JsonSchemaForm.js.map +1 -1
  109. package/dist/components/NamespacePicker.cjs +52 -0
  110. package/dist/components/NamespacePicker.cjs.map +1 -0
  111. package/dist/components/NamespacePicker.d.ts +17 -0
  112. package/dist/components/NamespacePicker.d.ts.map +1 -0
  113. package/dist/components/NamespacePicker.js +52 -0
  114. package/dist/components/NamespacePicker.js.map +1 -0
  115. package/dist/components/form-lookup-context.cjs +36 -0
  116. package/dist/components/form-lookup-context.cjs.map +1 -0
  117. package/dist/components/form-lookup-context.d.ts +9 -0
  118. package/dist/components/form-lookup-context.d.ts.map +1 -0
  119. package/dist/components/form-lookup-context.js +36 -0
  120. package/dist/components/form-lookup-context.js.map +1 -0
  121. package/dist/components/json-schema-form-discriminator.cjs +67 -0
  122. package/dist/components/json-schema-form-discriminator.cjs.map +1 -0
  123. package/dist/components/json-schema-form-discriminator.d.ts +10 -0
  124. package/dist/components/json-schema-form-discriminator.d.ts.map +1 -0
  125. package/dist/components/json-schema-form-discriminator.js +67 -0
  126. package/dist/components/json-schema-form-discriminator.js.map +1 -0
  127. package/dist/components/json-schema-form-fields.cjs +66 -1
  128. package/dist/components/json-schema-form-fields.cjs.map +1 -1
  129. package/dist/components/json-schema-form-fields.d.ts +7 -0
  130. package/dist/components/json-schema-form-fields.d.ts.map +1 -1
  131. package/dist/components/json-schema-form-fields.js +66 -1
  132. package/dist/components/json-schema-form-fields.js.map +1 -1
  133. package/dist/components/json-schema-form-grid.cjs +92 -0
  134. package/dist/components/json-schema-form-grid.cjs.map +1 -0
  135. package/dist/components/json-schema-form-grid.d.ts +9 -0
  136. package/dist/components/json-schema-form-grid.d.ts.map +1 -0
  137. package/dist/components/json-schema-form-grid.js +92 -0
  138. package/dist/components/json-schema-form-grid.js.map +1 -0
  139. package/dist/components/json-schema-form-render.cjs +20 -3
  140. package/dist/components/json-schema-form-render.cjs.map +1 -1
  141. package/dist/components/json-schema-form-render.d.ts.map +1 -1
  142. package/dist/components/json-schema-form-render.js +22 -5
  143. package/dist/components/json-schema-form-render.js.map +1 -1
  144. package/dist/components/json-schema-form-resolve.cjs +24 -2
  145. package/dist/components/json-schema-form-resolve.cjs.map +1 -1
  146. package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
  147. package/dist/components/json-schema-form-resolve.js +24 -2
  148. package/dist/components/json-schema-form-resolve.js.map +1 -1
  149. package/dist/components/json-schema-form-types.d.ts +37 -2
  150. package/dist/components/json-schema-form-types.d.ts.map +1 -1
  151. package/dist/components/json-schema-form-utils.cjs +8 -0
  152. package/dist/components/json-schema-form-utils.cjs.map +1 -1
  153. package/dist/components/json-schema-form-utils.d.ts +1 -0
  154. package/dist/components/json-schema-form-utils.d.ts.map +1 -1
  155. package/dist/components/json-schema-form-utils.js +8 -0
  156. package/dist/components/json-schema-form-utils.js.map +1 -1
  157. package/dist/components/workload-picker-utils.cjs.map +1 -1
  158. package/dist/components/workload-picker-utils.d.ts +11 -1
  159. package/dist/components/workload-picker-utils.d.ts.map +1 -1
  160. package/dist/components/workload-picker-utils.js.map +1 -1
  161. package/dist/components.cjs +6 -0
  162. package/dist/components.cjs.map +1 -1
  163. package/dist/components.d.ts +4 -2
  164. package/dist/components.d.ts.map +1 -1
  165. package/dist/components.js +6 -0
  166. package/dist/components.js.map +1 -1
  167. package/dist/data/Clicky.cjs +225 -60
  168. package/dist/data/Clicky.cjs.map +1 -1
  169. package/dist/data/Clicky.d.ts +7 -1
  170. package/dist/data/Clicky.d.ts.map +1 -1
  171. package/dist/data/Clicky.fixtures.d.ts +3 -1
  172. package/dist/data/Clicky.fixtures.d.ts.map +1 -1
  173. package/dist/data/Clicky.js +226 -61
  174. package/dist/data/Clicky.js.map +1 -1
  175. package/dist/data/ExecutionTree.cjs +68 -0
  176. package/dist/data/ExecutionTree.cjs.map +1 -0
  177. package/dist/data/ExecutionTree.d.ts +40 -0
  178. package/dist/data/ExecutionTree.d.ts.map +1 -0
  179. package/dist/data/ExecutionTree.js +68 -0
  180. package/dist/data/ExecutionTree.js.map +1 -0
  181. package/dist/data/GaugeHoverCard.cjs +35 -0
  182. package/dist/data/GaugeHoverCard.cjs.map +1 -0
  183. package/dist/data/GaugeHoverCard.d.ts +25 -0
  184. package/dist/data/GaugeHoverCard.d.ts.map +1 -0
  185. package/dist/data/GaugeHoverCard.js +35 -0
  186. package/dist/data/GaugeHoverCard.js.map +1 -0
  187. package/dist/data/MarkdownEditor.cjs +616 -0
  188. package/dist/data/MarkdownEditor.cjs.map +1 -0
  189. package/dist/data/MarkdownEditor.d.ts +61 -0
  190. package/dist/data/MarkdownEditor.d.ts.map +1 -0
  191. package/dist/data/MarkdownEditor.js +616 -0
  192. package/dist/data/MarkdownEditor.js.map +1 -0
  193. package/dist/data/MarkdownEditor.model.cjs +27 -0
  194. package/dist/data/MarkdownEditor.model.cjs.map +1 -0
  195. package/dist/data/MarkdownEditor.model.d.ts +38 -0
  196. package/dist/data/MarkdownEditor.model.d.ts.map +1 -0
  197. package/dist/data/MarkdownEditor.model.js +27 -0
  198. package/dist/data/MarkdownEditor.model.js.map +1 -0
  199. package/dist/data/ObjectGraph.cjs +44 -0
  200. package/dist/data/ObjectGraph.cjs.map +1 -0
  201. package/dist/data/ObjectGraph.d.ts +39 -0
  202. package/dist/data/ObjectGraph.d.ts.map +1 -0
  203. package/dist/data/ObjectGraph.js +44 -0
  204. package/dist/data/ObjectGraph.js.map +1 -0
  205. package/dist/data/SchemaViewer.cjs +152 -0
  206. package/dist/data/SchemaViewer.cjs.map +1 -0
  207. package/dist/data/SchemaViewer.d.ts +27 -0
  208. package/dist/data/SchemaViewer.d.ts.map +1 -0
  209. package/dist/data/SchemaViewer.js +152 -0
  210. package/dist/data/SchemaViewer.js.map +1 -0
  211. package/dist/data/TimeseriesCoreBars.cjs +51 -12
  212. package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
  213. package/dist/data/TimeseriesCoreBars.d.ts +32 -5
  214. package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
  215. package/dist/data/TimeseriesCoreBars.js +51 -12
  216. package/dist/data/TimeseriesCoreBars.js.map +1 -1
  217. package/dist/data/TimeseriesCoreBars.model.cjs +5 -5
  218. package/dist/data/TimeseriesCoreBars.model.cjs.map +1 -1
  219. package/dist/data/TimeseriesCoreBars.model.d.ts +4 -4
  220. package/dist/data/TimeseriesCoreBars.model.d.ts.map +1 -1
  221. package/dist/data/TimeseriesCoreBars.model.js +5 -5
  222. package/dist/data/TimeseriesCoreBars.model.js.map +1 -1
  223. package/dist/data/TimeseriesGauge.cjs +103 -65
  224. package/dist/data/TimeseriesGauge.cjs.map +1 -1
  225. package/dist/data/TimeseriesGauge.d.ts +10 -1
  226. package/dist/data/TimeseriesGauge.d.ts.map +1 -1
  227. package/dist/data/TimeseriesGauge.js +104 -66
  228. package/dist/data/TimeseriesGauge.js.map +1 -1
  229. package/dist/data/WorkloadCard.cjs +4 -4
  230. package/dist/data/WorkloadCard.cjs.map +1 -1
  231. package/dist/data/WorkloadCard.d.ts +3 -2
  232. package/dist/data/WorkloadCard.d.ts.map +1 -1
  233. package/dist/data/WorkloadCard.js +4 -4
  234. package/dist/data/WorkloadCard.js.map +1 -1
  235. package/dist/data/ai/ChatWindow.cjs +11 -19
  236. package/dist/data/ai/ChatWindow.cjs.map +1 -1
  237. package/dist/data/ai/ChatWindow.d.ts +1 -7
  238. package/dist/data/ai/ChatWindow.d.ts.map +1 -1
  239. package/dist/data/ai/ChatWindow.js +11 -19
  240. package/dist/data/ai/ChatWindow.js.map +1 -1
  241. package/dist/data/ai/ChatWindowRequestBody.cjs +20 -0
  242. package/dist/data/ai/ChatWindowRequestBody.cjs.map +1 -0
  243. package/dist/data/ai/ChatWindowRequestBody.d.ts +9 -0
  244. package/dist/data/ai/ChatWindowRequestBody.d.ts.map +1 -0
  245. package/dist/data/ai/ChatWindowRequestBody.js +20 -0
  246. package/dist/data/ai/ChatWindowRequestBody.js.map +1 -0
  247. package/dist/data/chat/Chat.cjs +12 -0
  248. package/dist/data/chat/Chat.cjs.map +1 -1
  249. package/dist/data/chat/Chat.d.ts +8 -1
  250. package/dist/data/chat/Chat.d.ts.map +1 -1
  251. package/dist/data/chat/Chat.js +12 -0
  252. package/dist/data/chat/Chat.js.map +1 -1
  253. package/dist/data/gauge-stats.cjs +19 -0
  254. package/dist/data/gauge-stats.cjs.map +1 -0
  255. package/dist/data/gauge-stats.d.ts +15 -0
  256. package/dist/data/gauge-stats.d.ts.map +1 -0
  257. package/dist/data/gauge-stats.js +19 -0
  258. package/dist/data/gauge-stats.js.map +1 -0
  259. package/dist/data/schema-viewer-model.cjs +436 -0
  260. package/dist/data/schema-viewer-model.cjs.map +1 -0
  261. package/dist/data/schema-viewer-model.d.ts +64 -0
  262. package/dist/data/schema-viewer-model.d.ts.map +1 -0
  263. package/dist/data/schema-viewer-model.js +436 -0
  264. package/dist/data/schema-viewer-model.js.map +1 -0
  265. package/dist/data/version-info.cjs +2 -2
  266. package/dist/data/version-info.js +2 -2
  267. package/dist/data.cjs +23 -0
  268. package/dist/data.cjs.map +1 -1
  269. package/dist/data.d.ts +11 -3
  270. package/dist/data.d.ts.map +1 -1
  271. package/dist/data.js +23 -0
  272. package/dist/data.js.map +1 -1
  273. package/dist/index.cjs +87 -2
  274. package/dist/index.cjs.map +1 -1
  275. package/dist/index.d.ts +1 -0
  276. package/dist/index.d.ts.map +1 -1
  277. package/dist/index.js +87 -2
  278. package/dist/index.js.map +1 -1
  279. package/dist/rpc/EntityExplorerApp.cjs +102 -143
  280. package/dist/rpc/EntityExplorerApp.cjs.map +1 -1
  281. package/dist/rpc/EntityExplorerApp.d.ts +34 -1
  282. package/dist/rpc/EntityExplorerApp.d.ts.map +1 -1
  283. package/dist/rpc/EntityExplorerApp.js +105 -146
  284. package/dist/rpc/EntityExplorerApp.js.map +1 -1
  285. package/dist/rpc/OperationActionBar.cjs +135 -0
  286. package/dist/rpc/OperationActionBar.cjs.map +1 -0
  287. package/dist/rpc/OperationActionBar.d.ts +20 -0
  288. package/dist/rpc/OperationActionBar.d.ts.map +1 -0
  289. package/dist/rpc/OperationActionBar.js +135 -0
  290. package/dist/rpc/OperationActionBar.js.map +1 -0
  291. package/dist/rpc/OperationCatalog.cjs +79 -116
  292. package/dist/rpc/OperationCatalog.cjs.map +1 -1
  293. package/dist/rpc/OperationCatalog.d.ts +8 -1
  294. package/dist/rpc/OperationCatalog.d.ts.map +1 -1
  295. package/dist/rpc/OperationCatalog.js +80 -117
  296. package/dist/rpc/OperationCatalog.js.map +1 -1
  297. package/dist/rpc/OperationCommandPage.cjs +134 -223
  298. package/dist/rpc/OperationCommandPage.cjs.map +1 -1
  299. package/dist/rpc/OperationCommandPage.d.ts +1 -1
  300. package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
  301. package/dist/rpc/OperationCommandPage.js +135 -224
  302. package/dist/rpc/OperationCommandPage.js.map +1 -1
  303. package/dist/rpc/OperationEntityPage.cjs +49 -100
  304. package/dist/rpc/OperationEntityPage.cjs.map +1 -1
  305. package/dist/rpc/OperationEntityPage.d.ts +6 -1
  306. package/dist/rpc/OperationEntityPage.d.ts.map +1 -1
  307. package/dist/rpc/OperationEntityPage.js +50 -101
  308. package/dist/rpc/OperationEntityPage.js.map +1 -1
  309. package/dist/rpc/OperationResultView.cjs +43 -0
  310. package/dist/rpc/OperationResultView.cjs.map +1 -0
  311. package/dist/rpc/OperationResultView.d.ts +30 -0
  312. package/dist/rpc/OperationResultView.d.ts.map +1 -0
  313. package/dist/rpc/OperationResultView.js +43 -0
  314. package/dist/rpc/OperationResultView.js.map +1 -0
  315. package/dist/rpc/SchemaActionForm.cjs +102 -0
  316. package/dist/rpc/SchemaActionForm.cjs.map +1 -0
  317. package/dist/rpc/SchemaActionForm.d.ts +23 -0
  318. package/dist/rpc/SchemaActionForm.d.ts.map +1 -0
  319. package/dist/rpc/SchemaActionForm.js +102 -0
  320. package/dist/rpc/SchemaActionForm.js.map +1 -0
  321. package/dist/rpc/accept-options.cjs.map +1 -1
  322. package/dist/rpc/accept-options.d.ts +0 -1
  323. package/dist/rpc/accept-options.d.ts.map +1 -1
  324. package/dist/rpc/accept-options.js.map +1 -1
  325. package/dist/rpc/apiClient.cjs +34 -2
  326. package/dist/rpc/apiClient.cjs.map +1 -1
  327. package/dist/rpc/apiClient.d.ts +4 -1
  328. package/dist/rpc/apiClient.d.ts.map +1 -1
  329. package/dist/rpc/apiClient.js +34 -2
  330. package/dist/rpc/apiClient.js.map +1 -1
  331. package/dist/rpc/clickyMetadata.cjs +4 -4
  332. package/dist/rpc/clickyMetadata.cjs.map +1 -1
  333. package/dist/rpc/clickyMetadata.d.ts +0 -1
  334. package/dist/rpc/clickyMetadata.d.ts.map +1 -1
  335. package/dist/rpc/clickyMetadata.js +4 -4
  336. package/dist/rpc/clickyMetadata.js.map +1 -1
  337. package/dist/rpc/formMetadata.cjs +1 -0
  338. package/dist/rpc/formMetadata.cjs.map +1 -1
  339. package/dist/rpc/formMetadata.d.ts +6 -1
  340. package/dist/rpc/formMetadata.d.ts.map +1 -1
  341. package/dist/rpc/formMetadata.js +1 -0
  342. package/dist/rpc/formMetadata.js.map +1 -1
  343. package/dist/rpc/rowNavigation.cjs +86 -0
  344. package/dist/rpc/rowNavigation.cjs.map +1 -0
  345. package/dist/rpc/rowNavigation.d.ts +14 -0
  346. package/dist/rpc/rowNavigation.d.ts.map +1 -0
  347. package/dist/rpc/rowNavigation.js +86 -0
  348. package/dist/rpc/rowNavigation.js.map +1 -0
  349. package/dist/rpc/schemaActionPath.cjs +22 -0
  350. package/dist/rpc/schemaActionPath.cjs.map +1 -0
  351. package/dist/rpc/schemaActionPath.d.ts +4 -0
  352. package/dist/rpc/schemaActionPath.d.ts.map +1 -0
  353. package/dist/rpc/schemaActionPath.js +22 -0
  354. package/dist/rpc/schemaActionPath.js.map +1 -0
  355. package/dist/rpc/surfaceIconMap.cjs +35 -0
  356. package/dist/rpc/surfaceIconMap.cjs.map +1 -0
  357. package/dist/rpc/surfaceIconMap.d.ts +3 -0
  358. package/dist/rpc/surfaceIconMap.d.ts.map +1 -0
  359. package/dist/rpc/surfaceIconMap.js +35 -0
  360. package/dist/rpc/surfaceIconMap.js.map +1 -0
  361. package/dist/rpc/types.cjs.map +1 -1
  362. package/dist/rpc/types.d.ts +2 -0
  363. package/dist/rpc/types.d.ts.map +1 -1
  364. package/dist/rpc/types.js.map +1 -1
  365. package/dist/rpc/useOperations.cjs.map +1 -1
  366. package/dist/rpc/useOperations.d.ts +4 -1
  367. package/dist/rpc/useOperations.d.ts.map +1 -1
  368. package/dist/rpc/useOperations.js.map +1 -1
  369. package/dist/rpc.cjs +4 -2
  370. package/dist/rpc.cjs.map +1 -1
  371. package/dist/rpc.d.ts +7 -6
  372. package/dist/rpc.d.ts.map +1 -1
  373. package/dist/rpc.js +4 -2
  374. package/dist/rpc.js.map +1 -1
  375. package/dist/styles.css +1 -1
  376. package/package.json +6 -1
  377. package/dist/rpc/AcceptPicker.cjs +0 -137
  378. package/dist/rpc/AcceptPicker.cjs.map +0 -1
  379. package/dist/rpc/AcceptPicker.d.ts +0 -12
  380. package/dist/rpc/AcceptPicker.d.ts.map +0 -1
  381. package/dist/rpc/AcceptPicker.js +0 -137
  382. package/dist/rpc/AcceptPicker.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"WorkloadCard.js","sources":["../../src/data/WorkloadCard.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from \"react\";\nimport {\n K8SDeployment,\n K8SIngress,\n K8SPod,\n K8SService,\n K8SStatefulset,\n} from \"@flanksource/icons/mi\";\nimport { cn } from \"../lib/utils\";\nimport { Modal } from \"../overlay/Modal\";\nimport { Badge } from \"./Badge\";\nimport { Timestamp } from \"./cells/Timestamp\";\nimport { Icon, type StaticIconComponent } from \"./Icon\";\nimport { TimeseriesCoreBars } from \"./TimeseriesCoreBars\";\nimport { TimeseriesGauge } from \"./TimeseriesGauge\";\nimport {\n TimeseriesPanel,\n type TimeseriesResponse,\n type TimeseriesSeries,\n} from \"./TimeseriesPanel\";\nimport { UiChip, UiFullscreen, UiHardDrive, UiMemoryStick } from \"../icons\";\nimport {\n formatReplicaCounts,\n workloadKindLabel,\n workloadStatusLabel,\n workloadStatusTone,\n type WorkloadCardIcon,\n type WorkloadCardKind,\n type WorkloadCardMetrics,\n type WorkloadCardResourceMetric,\n type WorkloadCardWorkload,\n} from \"./WorkloadCard.model\";\n\nexport interface WorkloadCardProps {\n workload: WorkloadCardWorkload;\n metrics: WorkloadCardMetrics;\n baseUrl?: string;\n range?: string;\n refreshMs?: number;\n expandable?: boolean;\n size?: WorkloadCardSize;\n variant?: WorkloadCardVariant;\n fetcher?: (url: string) => Promise<TimeseriesResponse>;\n className?: string;\n}\n\nexport type WorkloadCardSize = \"sm\" | \"md\" | \"lg\";\nexport type WorkloadCardVariant =\n | \"default\"\n | \"outline\"\n | \"subtle\"\n | \"elevated\"\n | \"ghost\";\n\ntype MetricKey = keyof WorkloadCardMetrics;\n\ntype PanelMetric = {\n key: MetricKey;\n title: string;\n unit?: string;\n icon: WorkloadCardIcon;\n metric: WorkloadCardResourceMetric;\n};\n\nconst KIND_ICONS: Record<WorkloadCardKind, StaticIconComponent> = {\n service: K8SService,\n ingress: K8SIngress,\n deployment: K8SDeployment,\n statefulset: K8SStatefulset,\n pod: K8SPod,\n};\n\ntype WorkloadCardSizeClasses = {\n root: string;\n header: string;\n titleGap: string;\n icon: string;\n name: string;\n meta: string;\n statusSize: \"xxs\" | \"xs\" | \"sm\";\n action: string;\n actionIcon: number;\n metricGrid: string;\n metricVariant: \"default\" | \"cell\";\n empty: string;\n};\n\nconst SIZE_CLASSES: Record<WorkloadCardSize, WorkloadCardSizeClasses> = {\n sm: {\n root: \"p-2\",\n header: \"mb-2 gap-2\",\n titleGap: \"gap-1\",\n icon: \"h-3.5 w-3.5\",\n name: \"text-xs\",\n meta: \"mt-0.5 gap-x-1.5 gap-y-0.5 text-[11px] leading-4\",\n statusSize: \"xxs\",\n action: \"h-5 w-5\",\n actionIcon: 12,\n metricGrid: \"grid-cols-1 gap-1.5\",\n metricVariant: \"cell\",\n empty: \"px-2 py-3 text-[11px]\",\n },\n md: {\n root: \"p-3\",\n header: \"mb-3 gap-2\",\n titleGap: \"gap-1.5\",\n icon: \"h-4 w-4\",\n name: \"text-sm\",\n meta: \"mt-0.5 gap-x-2 gap-y-0.5 text-xs\",\n statusSize: \"xs\",\n action: \"h-6 w-6\",\n actionIcon: 14,\n metricGrid: \"gap-3\",\n metricVariant: \"default\",\n empty: \"px-3 py-4 text-xs\",\n },\n lg: {\n root: \"p-4\",\n header: \"mb-4 gap-3\",\n titleGap: \"gap-2\",\n icon: \"h-5 w-5\",\n name: \"text-base\",\n meta: \"mt-1 gap-x-2 gap-y-1 text-xs\",\n statusSize: \"sm\",\n action: \"h-7 w-7\",\n actionIcon: 16,\n metricGrid: \"gap-4\",\n metricVariant: \"default\",\n empty: \"px-4 py-6 text-sm\",\n },\n};\n\nconst VARIANT_CLASSES: Record<WorkloadCardVariant, string> = {\n default: \"border-border bg-card text-card-foreground\",\n outline: \"border-border bg-background text-foreground\",\n subtle: \"border-transparent bg-muted/35 text-foreground\",\n elevated: \"border-border/70 bg-card text-card-foreground shadow-sm\",\n ghost: \"border-transparent bg-transparent text-foreground\",\n};\n\nfunction metricGridClass(count: number): string {\n if (count <= 1) return \"grid-cols-1\";\n if (count === 2) return \"grid-cols-2\";\n return \"grid-cols-3\";\n}\n\nfunction WorkloadIcon({\n icon,\n title,\n className,\n}: {\n icon: WorkloadCardIcon;\n title: string;\n className?: string;\n}) {\n if (typeof icon === \"string\") {\n return (\n <Icon name={icon} title={title} {...(className ? { className } : {})} />\n );\n }\n return (\n <Icon icon={icon} title={title} {...(className ? { className } : {})} />\n );\n}\n\nfunction metricSeries(metric: WorkloadCardResourceMetric): TimeseriesSeries[] {\n const series: TimeseriesSeries[] = [\n {\n id: metric.value.id,\n label: metric.valueLabel ?? \"usage\",\n ...(metric.value.transform ? { transform: metric.value.transform } : {}),\n },\n ];\n if (typeof metric.max === \"object\") {\n series.push({\n id: metric.max.id,\n label: metric.maxLabel ?? \"limit\",\n ...(metric.max.transform ? { transform: metric.max.transform } : {}),\n });\n }\n return series;\n}\n\nfunction hasMetric(metrics: WorkloadCardMetrics): boolean {\n return Boolean(metrics.cpu || metrics.memory || metrics.disk);\n}\n\nfunction HeaderMeta({ children }: { children: ReactNode }) {\n return (\n <span className=\"inline-flex min-w-0 items-center gap-1\">\n <span\n className=\"h-1 w-1 shrink-0 rounded-full bg-muted-foreground/40\"\n aria-hidden\n />\n <span className=\"min-w-0 truncate\">{children}</span>\n </span>\n );\n}\n\n/**\n * WorkloadCard is a compact resource card for Kubernetes-style workloads. It\n * shows workload identity, status, replica/age metadata, and CPU/memory/disk\n * utilization backed by the existing time-series primitives. Callers own the\n * metric ids; the card only composes the supplied series.\n */\nexport function WorkloadCard({\n workload,\n metrics,\n baseUrl,\n range = \"1h\",\n refreshMs = 5000,\n expandable = true,\n size = \"md\",\n variant = \"default\",\n fetcher,\n className,\n}: WorkloadCardProps) {\n const [expanded, setExpanded] = useState(false);\n const kindLabel = workloadKindLabel(workload.kind);\n const statusLabel = workloadStatusLabel(workload.status);\n const replicaText = formatReplicaCounts(workload.replicas);\n const workloadIcon = workload.icon ?? KIND_ICONS[workload.kind];\n const sizeClasses = SIZE_CLASSES[size];\n\n const panelMetrics = useMemo(() => {\n const list: PanelMetric[] = [];\n if (metrics.cpu) {\n list.push({\n key: \"cpu\",\n title: metrics.cpu.title ?? \"CPU\",\n unit: metrics.cpu.unit ?? \"short\",\n icon: metrics.cpu.icon ?? UiChip,\n metric: metrics.cpu,\n });\n }\n if (metrics.memory) {\n list.push({\n key: \"memory\",\n title: metrics.memory.title ?? \"Memory\",\n unit: metrics.memory.unit ?? \"bytes\",\n icon: metrics.memory.icon ?? UiMemoryStick,\n metric: metrics.memory,\n });\n }\n if (metrics.disk) {\n list.push({\n key: \"disk\",\n title: metrics.disk.title ?? \"Disk\",\n unit: metrics.disk.unit ?? \"bytes\",\n icon: metrics.disk.icon ?? UiHardDrive,\n metric: metrics.disk,\n });\n }\n return list;\n }, [metrics]);\n\n const metricProps = {\n ...(baseUrl !== undefined ? { baseUrl } : {}),\n range,\n refreshMs,\n ...(fetcher !== undefined ? { fetcher } : {}),\n };\n const canExpand = expandable && hasMetric(metrics);\n\n return (\n <div\n className={cn(\n \"w-full rounded-md border\",\n VARIANT_CLASSES[variant],\n sizeClasses.root,\n className,\n )}\n data-size={size}\n data-variant={variant}\n >\n <div\n className={cn(\"flex items-start justify-between\", sizeClasses.header)}\n >\n <div className=\"min-w-0\">\n <div\n className={cn(\"flex min-w-0 items-center\", sizeClasses.titleGap)}\n >\n <WorkloadIcon\n icon={workloadIcon}\n title={kindLabel}\n className={cn(\"shrink-0 text-muted-foreground\", sizeClasses.icon)}\n />\n <span\n className={cn(\"min-w-0 truncate font-medium\", sizeClasses.name)}\n title={workload.name}\n >\n {workload.name}\n </span>\n </div>\n <div\n className={cn(\n \"flex flex-wrap items-center text-muted-foreground\",\n sizeClasses.meta,\n )}\n >\n <span>{kindLabel}</span>\n {workload.namespace ? (\n <HeaderMeta>{workload.namespace}</HeaderMeta>\n ) : null}\n {workload.role ? <HeaderMeta>{workload.role}</HeaderMeta> : null}\n {replicaText ? <HeaderMeta>{replicaText}</HeaderMeta> : null}\n {workload.createdAt !== undefined ? (\n <HeaderMeta>\n age <Timestamp value={workload.createdAt} format=\"relative\" />\n </HeaderMeta>\n ) : null}\n </div>\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n {statusLabel ? (\n <span title={workload.status?.message}>\n <Badge\n tone={workloadStatusTone(workload.status)}\n variant=\"soft\"\n size={sizeClasses.statusSize}\n >\n {statusLabel}\n </Badge>\n </span>\n ) : null}\n {canExpand ? (\n <button\n type=\"button\"\n aria-label={`Open ${workload.name} history`}\n title=\"History\"\n onClick={() => setExpanded(true)}\n className={cn(\n \"inline-flex items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\",\n sizeClasses.action,\n )}\n >\n <Icon\n icon={UiFullscreen}\n width={sizeClasses.actionIcon}\n height={sizeClasses.actionIcon}\n />\n </button>\n ) : null}\n </div>\n </div>\n\n {hasMetric(metrics) ? (\n <div\n className={cn(\n \"grid items-start gap-3\",\n sizeClasses.metricVariant === \"cell\"\n ? sizeClasses.metricGrid\n : cn(\n metricGridClass(panelMetrics.length),\n sizeClasses.metricGrid,\n ),\n )}\n >\n {metrics.cpu ? (\n <TimeseriesCoreBars\n title={metrics.cpu.title ?? \"CPU\"}\n icon={metrics.cpu.icon ?? UiChip}\n value={metrics.cpu.value}\n {...(metrics.cpu.max !== undefined\n ? { max: metrics.cpu.max }\n : {})}\n {...(metrics.cpu.thresholds\n ? { thresholds: metrics.cpu.thresholds }\n : {})}\n {...(metrics.cpu.orientation\n ? { orientation: metrics.cpu.orientation }\n : {})}\n {...(metrics.cpu.showValue !== undefined\n ? { showValue: metrics.cpu.showValue }\n : {})}\n variant={sizeClasses.metricVariant}\n {...metricProps}\n />\n ) : null}\n {metrics.memory ? (\n <TimeseriesGauge\n title={metrics.memory.title ?? \"Memory\"}\n icon={metrics.memory.icon ?? UiMemoryStick}\n value={metrics.memory.value}\n unit={metrics.memory.unit ?? \"bytes\"}\n expandable={false}\n centerDisplay={metrics.memory.centerDisplay ?? \"value\"}\n variant={sizeClasses.metricVariant}\n {...(metrics.memory.max !== undefined\n ? { max: metrics.memory.max }\n : {})}\n {...(metrics.memory.thresholds\n ? { thresholds: metrics.memory.thresholds }\n : {})}\n {...metricProps}\n />\n ) : null}\n {metrics.disk ? (\n <TimeseriesGauge\n title={metrics.disk.title ?? \"Disk\"}\n icon={metrics.disk.icon ?? UiHardDrive}\n value={metrics.disk.value}\n unit={metrics.disk.unit ?? \"bytes\"}\n expandable={false}\n centerDisplay={metrics.disk.centerDisplay ?? \"value\"}\n variant={sizeClasses.metricVariant}\n {...(metrics.disk.max !== undefined\n ? { max: metrics.disk.max }\n : {})}\n {...(metrics.disk.thresholds\n ? { thresholds: metrics.disk.thresholds }\n : {})}\n {...metricProps}\n />\n ) : null}\n </div>\n ) : (\n <div\n className={cn(\n \"rounded-md border border-dashed border-border text-center text-muted-foreground\",\n sizeClasses.empty,\n )}\n >\n No metrics configured\n </div>\n )}\n\n <Modal\n open={expanded}\n onClose={() => setExpanded(false)}\n title={`${workload.name} history`}\n size=\"xl\"\n >\n <div className=\"flex flex-col gap-3\">\n {panelMetrics.map(({ key, title, unit, icon, metric }) => (\n <TimeseriesPanel\n key={key}\n title={title}\n icon={icon}\n series={metricSeries(metric)}\n {...(unit ? { unit } : {})}\n {...metricProps}\n expandable={false}\n />\n ))}\n </div>\n </Modal>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WorkloadCard.js","sources":["../../src/data/WorkloadCard.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from \"react\";\nimport {\n K8SDeployment,\n K8SIngress,\n K8SPod,\n K8SService,\n K8SStatefulset,\n} from \"@flanksource/icons/mi\";\nimport { cn } from \"../lib/utils\";\nimport { Modal } from \"../overlay/Modal\";\nimport { Badge } from \"./Badge\";\nimport { Timestamp } from \"./cells/Timestamp\";\nimport { Icon, type StaticIconComponent } from \"./Icon\";\nimport { TimeseriesCoreBars } from \"./TimeseriesCoreBars\";\nimport { TimeseriesGauge } from \"./TimeseriesGauge\";\nimport {\n TimeseriesPanel,\n type TimeseriesResponse,\n type TimeseriesSeries,\n} from \"./TimeseriesPanel\";\nimport { UiChip, UiFullscreen, UiHardDrive, UiMemoryStick } from \"../icons\";\nimport {\n formatReplicaCounts,\n workloadKindLabel,\n workloadStatusLabel,\n workloadStatusTone,\n type WorkloadCardIcon,\n type WorkloadCardKind,\n type WorkloadCardMetrics,\n type WorkloadCardResourceMetric,\n type WorkloadCardWorkload,\n} from \"./WorkloadCard.model\";\n\nexport interface WorkloadCardProps {\n workload: WorkloadCardWorkload;\n metrics: WorkloadCardMetrics;\n baseUrl?: string;\n range?: string;\n refreshMs?: number;\n expandable?: boolean;\n size?: WorkloadCardSize;\n variant?: WorkloadCardVariant;\n fetcher?: (url: string) => Promise<TimeseriesResponse>;\n className?: string;\n}\n\nexport type WorkloadCardSize = \"sm\" | \"md\" | \"lg\";\nexport type WorkloadCardVariant =\n | \"default\"\n | \"outline\"\n | \"subtle\"\n | \"elevated\"\n | \"ghost\";\n\ntype MetricKey = keyof WorkloadCardMetrics;\n\ntype PanelMetric = {\n key: MetricKey;\n title: string;\n unit?: string;\n icon: WorkloadCardIcon;\n metric: WorkloadCardResourceMetric;\n};\n\nconst KIND_ICONS: Record<WorkloadCardKind, StaticIconComponent> = {\n service: K8SService,\n ingress: K8SIngress,\n deployment: K8SDeployment,\n statefulset: K8SStatefulset,\n pod: K8SPod,\n};\n\ntype WorkloadCardSizeClasses = {\n root: string;\n header: string;\n titleGap: string;\n icon: string;\n name: string;\n meta: string;\n statusSize: \"xxs\" | \"xs\" | \"sm\";\n action: string;\n actionIcon: number;\n metricGrid: string;\n metricVariant: \"default\" | \"cell\";\n empty: string;\n};\n\nconst SIZE_CLASSES: Record<WorkloadCardSize, WorkloadCardSizeClasses> = {\n sm: {\n root: \"p-2\",\n header: \"mb-2 gap-2\",\n titleGap: \"gap-1\",\n icon: \"h-3.5 w-3.5\",\n name: \"text-xs\",\n meta: \"mt-0.5 gap-x-1.5 gap-y-0.5 text-[11px] leading-4\",\n statusSize: \"xxs\",\n action: \"h-5 w-5\",\n actionIcon: 12,\n metricGrid: \"grid-cols-1 gap-1.5\",\n metricVariant: \"cell\",\n empty: \"px-2 py-3 text-[11px]\",\n },\n md: {\n root: \"p-3\",\n header: \"mb-3 gap-2\",\n titleGap: \"gap-1.5\",\n icon: \"h-4 w-4\",\n name: \"text-sm\",\n meta: \"mt-0.5 gap-x-2 gap-y-0.5 text-xs\",\n statusSize: \"xs\",\n action: \"h-6 w-6\",\n actionIcon: 14,\n metricGrid: \"gap-3\",\n metricVariant: \"default\",\n empty: \"px-3 py-4 text-xs\",\n },\n lg: {\n root: \"p-4\",\n header: \"mb-4 gap-3\",\n titleGap: \"gap-2\",\n icon: \"h-5 w-5\",\n name: \"text-base\",\n meta: \"mt-1 gap-x-2 gap-y-1 text-xs\",\n statusSize: \"sm\",\n action: \"h-7 w-7\",\n actionIcon: 16,\n metricGrid: \"gap-4\",\n metricVariant: \"default\",\n empty: \"px-4 py-6 text-sm\",\n },\n};\n\nconst VARIANT_CLASSES: Record<WorkloadCardVariant, string> = {\n default: \"border-border bg-card text-card-foreground\",\n outline: \"border-border bg-background text-foreground\",\n subtle: \"border-transparent bg-muted/35 text-foreground\",\n elevated: \"border-border/70 bg-card text-card-foreground shadow-sm\",\n ghost: \"border-transparent bg-transparent text-foreground\",\n};\n\nfunction metricGridClass(count: number): string {\n if (count <= 1) return \"grid-cols-1\";\n if (count === 2) return \"grid-cols-2\";\n return \"grid-cols-3\";\n}\n\n// Memory renders as cores-style bars at one bar per gigabyte, matching CPU; bytes\n// are fed raw and TimeseriesCoreBars divides by perBar so captions read \"x GB\".\nconst MEMORY_BAR_UNIT = { perBar: 1024 ** 3, label: \"GB\", barLabel: \"GB\" };\n\nfunction WorkloadIcon({\n icon,\n title,\n className,\n}: {\n icon: WorkloadCardIcon;\n title: string;\n className?: string;\n}) {\n if (typeof icon === \"string\") {\n return (\n <Icon name={icon} title={title} {...(className ? { className } : {})} />\n );\n }\n return (\n <Icon icon={icon} title={title} {...(className ? { className } : {})} />\n );\n}\n\nfunction metricSeries(metric: WorkloadCardResourceMetric): TimeseriesSeries[] {\n const series: TimeseriesSeries[] = [\n {\n id: metric.value.id,\n label: metric.valueLabel ?? \"usage\",\n ...(metric.value.transform ? { transform: metric.value.transform } : {}),\n },\n ];\n if (typeof metric.max === \"object\") {\n series.push({\n id: metric.max.id,\n label: metric.maxLabel ?? \"limit\",\n ...(metric.max.transform ? { transform: metric.max.transform } : {}),\n });\n }\n return series;\n}\n\nfunction hasMetric(metrics: WorkloadCardMetrics): boolean {\n return Boolean(metrics.cpu || metrics.memory || metrics.disk);\n}\n\nfunction HeaderMeta({ children }: { children: ReactNode }) {\n return (\n <span className=\"inline-flex min-w-0 items-center gap-1\">\n <span\n className=\"h-1 w-1 shrink-0 rounded-full bg-muted-foreground/40\"\n aria-hidden\n />\n <span className=\"min-w-0 truncate\">{children}</span>\n </span>\n );\n}\n\n/**\n * WorkloadCard is a compact resource card for Kubernetes-style workloads. It\n * shows workload identity, status, replica/age metadata, and CPU/memory/disk\n * utilization backed by the existing time-series primitives: CPU and memory as\n * core-style bars (memory at one bar per GB) and disk as a linear progress bar.\n * Callers own the metric ids; the card only composes the supplied series.\n */\nexport function WorkloadCard({\n workload,\n metrics,\n baseUrl,\n range = \"1h\",\n refreshMs = 5000,\n expandable = true,\n size = \"md\",\n variant = \"default\",\n fetcher,\n className,\n}: WorkloadCardProps) {\n const [expanded, setExpanded] = useState(false);\n const kindLabel = workloadKindLabel(workload.kind);\n const statusLabel = workloadStatusLabel(workload.status);\n const replicaText = formatReplicaCounts(workload.replicas);\n const workloadIcon = workload.icon ?? KIND_ICONS[workload.kind];\n const sizeClasses = SIZE_CLASSES[size];\n\n const panelMetrics = useMemo(() => {\n const list: PanelMetric[] = [];\n if (metrics.cpu) {\n list.push({\n key: \"cpu\",\n title: metrics.cpu.title ?? \"CPU\",\n unit: metrics.cpu.unit ?? \"short\",\n icon: metrics.cpu.icon ?? UiChip,\n metric: metrics.cpu,\n });\n }\n if (metrics.memory) {\n list.push({\n key: \"memory\",\n title: metrics.memory.title ?? \"Memory\",\n unit: metrics.memory.unit ?? \"bytes\",\n icon: metrics.memory.icon ?? UiMemoryStick,\n metric: metrics.memory,\n });\n }\n if (metrics.disk) {\n list.push({\n key: \"disk\",\n title: metrics.disk.title ?? \"Disk\",\n unit: metrics.disk.unit ?? \"bytes\",\n icon: metrics.disk.icon ?? UiHardDrive,\n metric: metrics.disk,\n });\n }\n return list;\n }, [metrics]);\n\n const metricProps = {\n ...(baseUrl !== undefined ? { baseUrl } : {}),\n range,\n refreshMs,\n ...(fetcher !== undefined ? { fetcher } : {}),\n };\n const canExpand = expandable && hasMetric(metrics);\n\n return (\n <div\n className={cn(\n \"w-full rounded-md border\",\n VARIANT_CLASSES[variant],\n sizeClasses.root,\n className,\n )}\n data-size={size}\n data-variant={variant}\n >\n <div\n className={cn(\"flex items-start justify-between\", sizeClasses.header)}\n >\n <div className=\"min-w-0\">\n <div\n className={cn(\"flex min-w-0 items-center\", sizeClasses.titleGap)}\n >\n <WorkloadIcon\n icon={workloadIcon}\n title={kindLabel}\n className={cn(\"shrink-0 text-muted-foreground\", sizeClasses.icon)}\n />\n <span\n className={cn(\"min-w-0 truncate font-medium\", sizeClasses.name)}\n title={workload.name}\n >\n {workload.name}\n </span>\n </div>\n <div\n className={cn(\n \"flex flex-wrap items-center text-muted-foreground\",\n sizeClasses.meta,\n )}\n >\n <span>{kindLabel}</span>\n {workload.namespace ? (\n <HeaderMeta>{workload.namespace}</HeaderMeta>\n ) : null}\n {workload.role ? <HeaderMeta>{workload.role}</HeaderMeta> : null}\n {replicaText ? <HeaderMeta>{replicaText}</HeaderMeta> : null}\n {workload.createdAt !== undefined ? (\n <HeaderMeta>\n age <Timestamp value={workload.createdAt} format=\"relative\" />\n </HeaderMeta>\n ) : null}\n </div>\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n {statusLabel ? (\n <span title={workload.status?.message}>\n <Badge\n tone={workloadStatusTone(workload.status)}\n variant=\"soft\"\n size={sizeClasses.statusSize}\n >\n {statusLabel}\n </Badge>\n </span>\n ) : null}\n {canExpand ? (\n <button\n type=\"button\"\n aria-label={`Open ${workload.name} history`}\n title=\"History\"\n onClick={() => setExpanded(true)}\n className={cn(\n \"inline-flex items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\",\n sizeClasses.action,\n )}\n >\n <Icon\n icon={UiFullscreen}\n width={sizeClasses.actionIcon}\n height={sizeClasses.actionIcon}\n />\n </button>\n ) : null}\n </div>\n </div>\n\n {hasMetric(metrics) ? (\n <div\n className={cn(\n \"grid items-start gap-3\",\n sizeClasses.metricVariant === \"cell\"\n ? sizeClasses.metricGrid\n : cn(\n metricGridClass(panelMetrics.length),\n sizeClasses.metricGrid,\n ),\n )}\n >\n {metrics.cpu ? (\n <TimeseriesCoreBars\n title={metrics.cpu.title ?? \"CPU\"}\n icon={metrics.cpu.icon ?? UiChip}\n value={metrics.cpu.value}\n {...(metrics.cpu.max !== undefined\n ? { max: metrics.cpu.max }\n : {})}\n {...(metrics.cpu.thresholds\n ? { thresholds: metrics.cpu.thresholds }\n : {})}\n {...(metrics.cpu.orientation\n ? { orientation: metrics.cpu.orientation }\n : {})}\n {...(metrics.cpu.showValue !== undefined\n ? { showValue: metrics.cpu.showValue }\n : {})}\n variant={sizeClasses.metricVariant}\n {...metricProps}\n />\n ) : null}\n {metrics.memory ? (\n <TimeseriesCoreBars\n title={metrics.memory.title ?? \"Memory\"}\n icon={metrics.memory.icon ?? UiMemoryStick}\n value={metrics.memory.value}\n unit={MEMORY_BAR_UNIT}\n variant={sizeClasses.metricVariant}\n {...(metrics.memory.max !== undefined\n ? { max: metrics.memory.max }\n : {})}\n {...(metrics.memory.thresholds\n ? { thresholds: metrics.memory.thresholds }\n : {})}\n {...metricProps}\n />\n ) : null}\n {metrics.disk ? (\n <TimeseriesGauge\n title={metrics.disk.title ?? \"Disk\"}\n icon={metrics.disk.icon ?? UiHardDrive}\n value={metrics.disk.value}\n unit={metrics.disk.unit ?? \"bytes\"}\n shape=\"linear\"\n expandable={false}\n centerDisplay={metrics.disk.centerDisplay ?? \"value\"}\n variant={sizeClasses.metricVariant}\n {...(metrics.disk.max !== undefined\n ? { max: metrics.disk.max }\n : {})}\n {...(metrics.disk.thresholds\n ? { thresholds: metrics.disk.thresholds }\n : {})}\n {...metricProps}\n />\n ) : null}\n </div>\n ) : (\n <div\n className={cn(\n \"rounded-md border border-dashed border-border text-center text-muted-foreground\",\n sizeClasses.empty,\n )}\n >\n No metrics configured\n </div>\n )}\n\n <Modal\n open={expanded}\n onClose={() => setExpanded(false)}\n title={`${workload.name} history`}\n size=\"xl\"\n >\n <div className=\"flex flex-col gap-3\">\n {panelMetrics.map(({ key, title, unit, icon, metric }) => (\n <TimeseriesPanel\n key={key}\n title={title}\n icon={icon}\n series={metricSeries(metric)}\n {...(unit ? { unit } : {})}\n {...metricProps}\n expandable={false}\n />\n ))}\n </div>\n </Modal>\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -32,7 +32,7 @@ const chatWindowContext = require("./chat-window-context.cjs");
32
32
  const ThreadPicker = require("./ThreadPicker.cjs");
33
33
  const ContextBadges = require("./ContextBadges.cjs");
34
34
  const ToolPreferences = require("./ToolPreferences.cjs");
35
- const context = require("./context.cjs");
35
+ const ChatWindowRequestBody = require("./ChatWindowRequestBody.cjs");
36
36
  const UiAdd = require("../../icons/components/UiAdd.cjs");
37
37
  const UiFullscreen = require("../../icons/components/UiFullscreen.cjs");
38
38
  const UiClose = require("../../icons/components/UiClose.cjs");
@@ -44,21 +44,6 @@ const MAXIMIZE_CSS = `
44
44
  inset: 0 !important;
45
45
  position: absolute !important;
46
46
  }`;
47
- function chatWindowRequestBody({
48
- base,
49
- contextItems,
50
- tools,
51
- toolPrefs
52
- }) {
53
- return {
54
- ...base,
55
- ...contextItems.length ? {
56
- context: context.serializeContext(contextItems),
57
- contextItems
58
- } : {},
59
- ...tools ? { toolPreferences: toolPrefs ?? {} } : {}
60
- };
61
- }
62
47
  function ChatWindow({
63
48
  panel,
64
49
  chat,
@@ -100,12 +85,18 @@ function ChatWindow({
100
85
  (id) => updatePanel(panel.id, { contextItems: panel.contextItems.filter((c) => c.id !== id) }),
101
86
  [updatePanel, panel.id, panel.contextItems]
102
87
  );
103
- const mergedBody = chatWindowRequestBody({
88
+ const mergedBody = ChatWindowRequestBody.chatWindowRequestBody({
104
89
  base: chat == null ? void 0 : chat.body,
105
90
  contextItems: panel.contextItems,
106
91
  tools,
107
92
  toolPrefs
108
93
  });
94
+ const initialPrompt = panel.initialPrompt ?? (chat == null ? void 0 : chat.initialPrompt) ?? null;
95
+ const handleInitialPromptSent = react.useCallback(() => {
96
+ var _a;
97
+ if (panel.initialPrompt) updatePanel(panel.id, { initialPrompt: null });
98
+ (_a = chat == null ? void 0 : chat.onInitialPromptSent) == null ? void 0 : _a.call(chat);
99
+ }, [chat, panel.id, panel.initialPrompt, updatePanel]);
109
100
  const header = /* @__PURE__ */ jsxRuntime.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: [
110
101
  threadsSource != null || threadsApi !== null ? /* @__PURE__ */ jsxRuntime.jsx(
111
102
  ThreadPicker.ThreadPicker,
@@ -147,7 +138,9 @@ function ChatWindow({
147
138
  {
148
139
  ...chat,
149
140
  ...panel.threadId ? { threadId: panel.threadId } : {},
150
- body: mergedBody
141
+ body: mergedBody,
142
+ initialPrompt,
143
+ onInitialPromptSent: handleInitialPromptSent
151
144
  }
152
145
  ) })
153
146
  ] });
@@ -192,5 +185,4 @@ function ChatWindowLayer(props) {
192
185
  }
193
186
  exports.ChatWindow = ChatWindow;
194
187
  exports.ChatWindowLayer = ChatWindowLayer;
195
- exports.chatWindowRequestBody = chatWindowRequestBody;
196
188
  //# sourceMappingURL=ChatWindow.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChatWindow.cjs","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 ChatContextItem, 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 /** Initial mode assigned to tools when they first load. Defaults to \"ask\". */\n defaultToolMode?: ToolMode;\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\nexport function chatWindowRequestBody({\n base,\n contextItems,\n tools,\n toolPrefs,\n}: {\n base?: Record<string, unknown> | undefined;\n contextItems: ChatContextItem[];\n tools?: ToolMeta[] | undefined;\n toolPrefs?: Record<string, ToolMode> | undefined;\n}): Record<string, unknown> {\n return {\n ...base,\n ...(contextItems.length ? {\n context: serializeContext(contextItems),\n contextItems,\n } : {}),\n ...(tools ? { toolPreferences: toolPrefs ?? {} } : {}),\n };\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 defaultToolMode = \"ask\",\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] = defaultToolMode;\n changed = true;\n }\n }\n return changed ? next : prev;\n });\n }, [defaultToolMode, 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 = chatWindowRequestBody({\n base: chat?.body,\n contextItems: panel.contextItems,\n tools,\n 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":["serializeContext","useChatWindowManager","useState","useEffect","useCallback","jsxs","jsx","ThreadPicker","ToolPreferences","Button","Icon","UiAdd","UiFullscreen","UiClose","ContextBadges","Chat","cn","Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"ChatWindow.cjs","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 type { ContextTypeConfig } from \"./context\";\nimport { chatWindowRequestBody } from \"./ChatWindowRequestBody\";\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 /** Initial mode assigned to tools when they first load. Defaults to \"ask\". */\n defaultToolMode?: ToolMode;\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 defaultToolMode = \"ask\",\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] = defaultToolMode;\n changed = true;\n }\n }\n return changed ? next : prev;\n });\n }, [defaultToolMode, 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 = chatWindowRequestBody({\n base: chat?.body,\n contextItems: panel.contextItems,\n tools,\n toolPrefs,\n });\n\n const initialPrompt = panel.initialPrompt ?? chat?.initialPrompt ?? null;\n const handleInitialPromptSent = useCallback(() => {\n if (panel.initialPrompt) updatePanel(panel.id, { initialPrompt: null });\n chat?.onInitialPromptSent?.();\n }, [chat, panel.id, panel.initialPrompt, updatePanel]);\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 initialPrompt={initialPrompt}\n onInitialPromptSent={handleInitialPromptSent}\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":["useChatWindowManager","useState","useEffect","useCallback","chatWindowRequestBody","jsxs","jsx","ThreadPicker","ToolPreferences","Button","Icon","UiAdd","UiFullscreen","UiClose","ContextBadges","Chat","cn","Fragment"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { ChatProps } from '../chat/Chat';
3
3
  import { ChatWindowState } from './chat-window-context';
4
4
  import { ThreadSource } from './ThreadPicker';
5
5
  import { ToolMeta, ToolMode } from './ToolPreferences';
6
- import { ChatContextItem, ContextTypeConfig } from './context';
6
+ import { ContextTypeConfig } from './context';
7
7
  export type ChatWindowProps = {
8
8
  panel: ChatWindowState;
9
9
  /** Props forwarded to the inner <Chat>. The window manages `threadId` and
@@ -29,12 +29,6 @@ export type ChatWindowProps = {
29
29
  /** Extra controls rendered in the header, e.g. a <ContextUsage/> gauge. */
30
30
  headerExtras?: ReactNode;
31
31
  };
32
- export declare function chatWindowRequestBody({ base, contextItems, tools, toolPrefs, }: {
33
- base?: Record<string, unknown> | undefined;
34
- contextItems: ChatContextItem[];
35
- tools?: ToolMeta[] | undefined;
36
- toolPrefs?: Record<string, ToolMode> | undefined;
37
- }): Record<string, unknown>;
38
32
  /** A draggable, resizable floating chat window. It lazy-loads `react-rnd` (an
39
33
  * optional dependency, so consumers of just the inner <Chat> never pull it)
40
34
  * and renders the existing <Chat> beneath a drag-handle header with thread
@@ -1 +1 @@
1
- {"version":3,"file":"ChatWindow.d.ts","sourceRoot":"","sources":["../../../src/data/ai/ChatWindow.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKzE,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,EAAmB,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAAoB,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE3F,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,eAAe,CAAC;IACvB;kFAC8E;IAC9E,IAAI,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1B,6DAA6D;IAC7D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;oEACgE;IAChE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;6CAEyC;IACzC,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;iEAE6D;IAC7D,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,8EAA8E;IAC9E,eAAe,CAAC,EAAE,QAAQ,CAAC;IAC3B,2EAA2E;IAC3E,YAAY,CAAC,EAAE,SAAS,CAAC;CAC1B,CAAC;AAWF,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,SAAS,GACV,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC3C,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,KAAK,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,SAAS,CAAC;CAClD,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAS1B;AAED;;;oEAGoE;AACpE,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,IAAI,EACJ,KAAmB,EACnB,UAAgC,EAChC,aAAa,EACb,iBAAiB,EACjB,KAAK,EACL,eAAuB,EACvB,YAAY,GACb,EAAE,eAAe,2CAkJjB;AAED;8DAC8D;AAC9D,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,2CASpE"}
1
+ {"version":3,"file":"ChatWindow.d.ts","sourceRoot":"","sources":["../../../src/data/ai/ChatWindow.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKzE,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,EAAmB,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAGnD,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,eAAe,CAAC;IACvB;kFAC8E;IAC9E,IAAI,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1B,6DAA6D;IAC7D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;oEACgE;IAChE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;6CAEyC;IACzC,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;iEAE6D;IAC7D,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,8EAA8E;IAC9E,eAAe,CAAC,EAAE,QAAQ,CAAC;IAC3B,2EAA2E;IAC3E,YAAY,CAAC,EAAE,SAAS,CAAC;CAC1B,CAAC;AAWF;;;oEAGoE;AACpE,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,IAAI,EACJ,KAAmB,EACnB,UAAgC,EAChC,aAAa,EACb,iBAAiB,EACjB,KAAK,EACL,eAAuB,EACvB,YAAY,GACb,EAAE,eAAe,2CA0JjB;AAED;8DAC8D;AAC9D,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,2CASpE"}
@@ -8,7 +8,7 @@ import { useChatWindowManager } from "./chat-window-context.js";
8
8
  import { ThreadPicker } from "./ThreadPicker.js";
9
9
  import { ContextBadges } from "./ContextBadges.js";
10
10
  import { ToolPreferences } from "./ToolPreferences.js";
11
- import { serializeContext } from "./context.js";
11
+ import { chatWindowRequestBody } from "./ChatWindowRequestBody.js";
12
12
  import { UiAdd } from "../../icons/components/UiAdd.js";
13
13
  import { UiFullscreen } from "../../icons/components/UiFullscreen.js";
14
14
  import { UiClose } from "../../icons/components/UiClose.js";
@@ -20,21 +20,6 @@ const MAXIMIZE_CSS = `
20
20
  inset: 0 !important;
21
21
  position: absolute !important;
22
22
  }`;
23
- function chatWindowRequestBody({
24
- base,
25
- contextItems,
26
- tools,
27
- toolPrefs
28
- }) {
29
- return {
30
- ...base,
31
- ...contextItems.length ? {
32
- context: serializeContext(contextItems),
33
- contextItems
34
- } : {},
35
- ...tools ? { toolPreferences: toolPrefs ?? {} } : {}
36
- };
37
- }
38
23
  function ChatWindow({
39
24
  panel,
40
25
  chat,
@@ -82,6 +67,12 @@ function ChatWindow({
82
67
  tools,
83
68
  toolPrefs
84
69
  });
70
+ const initialPrompt = panel.initialPrompt ?? (chat == null ? void 0 : chat.initialPrompt) ?? null;
71
+ const handleInitialPromptSent = useCallback(() => {
72
+ var _a;
73
+ if (panel.initialPrompt) updatePanel(panel.id, { initialPrompt: null });
74
+ (_a = chat == null ? void 0 : chat.onInitialPromptSent) == null ? void 0 : _a.call(chat);
75
+ }, [chat, panel.id, panel.initialPrompt, updatePanel]);
85
76
  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: [
86
77
  threadsSource != null || threadsApi !== null ? /* @__PURE__ */ jsx(
87
78
  ThreadPicker,
@@ -123,7 +114,9 @@ function ChatWindow({
123
114
  {
124
115
  ...chat,
125
116
  ...panel.threadId ? { threadId: panel.threadId } : {},
126
- body: mergedBody
117
+ body: mergedBody,
118
+ initialPrompt,
119
+ onInitialPromptSent: handleInitialPromptSent
127
120
  }
128
121
  ) })
129
122
  ] });
@@ -168,7 +161,6 @@ function ChatWindowLayer(props) {
168
161
  }
169
162
  export {
170
163
  ChatWindow,
171
- ChatWindowLayer,
172
- chatWindowRequestBody
164
+ ChatWindowLayer
173
165
  };
174
166
  //# sourceMappingURL=ChatWindow.js.map
@@ -1 +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 ChatContextItem, 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 /** Initial mode assigned to tools when they first load. Defaults to \"ask\". */\n defaultToolMode?: ToolMode;\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\nexport function chatWindowRequestBody({\n base,\n contextItems,\n tools,\n toolPrefs,\n}: {\n base?: Record<string, unknown> | undefined;\n contextItems: ChatContextItem[];\n tools?: ToolMeta[] | undefined;\n toolPrefs?: Record<string, ToolMode> | undefined;\n}): Record<string, unknown> {\n return {\n ...base,\n ...(contextItems.length ? {\n context: serializeContext(contextItems),\n contextItems,\n } : {}),\n ...(tools ? { toolPreferences: toolPrefs ?? {} } : {}),\n };\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 defaultToolMode = \"ask\",\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] = defaultToolMode;\n changed = true;\n }\n }\n return changed ? next : prev;\n });\n }, [defaultToolMode, 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 = chatWindowRequestBody({\n base: chat?.body,\n contextItems: panel.contextItems,\n tools,\n 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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"}
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 type { ContextTypeConfig } from \"./context\";\nimport { chatWindowRequestBody } from \"./ChatWindowRequestBody\";\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 /** Initial mode assigned to tools when they first load. Defaults to \"ask\". */\n defaultToolMode?: ToolMode;\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 defaultToolMode = \"ask\",\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] = defaultToolMode;\n changed = true;\n }\n }\n return changed ? next : prev;\n });\n }, [defaultToolMode, 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 = chatWindowRequestBody({\n base: chat?.body,\n contextItems: panel.contextItems,\n tools,\n toolPrefs,\n });\n\n const initialPrompt = panel.initialPrompt ?? chat?.initialPrompt ?? null;\n const handleInitialPromptSent = useCallback(() => {\n if (panel.initialPrompt) updatePanel(panel.id, { initialPrompt: null });\n chat?.onInitialPromptSent?.();\n }, [chat, panel.id, panel.initialPrompt, updatePanel]);\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 initialPrompt={initialPrompt}\n onInitialPromptSent={handleInitialPromptSent}\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,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const context = require("./context.cjs");
4
+ function chatWindowRequestBody({
5
+ base,
6
+ contextItems,
7
+ tools,
8
+ toolPrefs
9
+ }) {
10
+ return {
11
+ ...base,
12
+ ...contextItems.length ? {
13
+ context: context.serializeContext(contextItems),
14
+ contextItems
15
+ } : {},
16
+ ...tools ? { toolPreferences: toolPrefs ?? {} } : {}
17
+ };
18
+ }
19
+ exports.chatWindowRequestBody = chatWindowRequestBody;
20
+ //# sourceMappingURL=ChatWindowRequestBody.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatWindowRequestBody.cjs","sources":["../../../src/data/ai/ChatWindowRequestBody.ts"],"sourcesContent":["import { serializeContext, type ChatContextItem } from \"./context\";\nimport type { ToolMeta, ToolMode } from \"./ToolPreferences\";\n\nexport function chatWindowRequestBody({\n base,\n contextItems,\n tools,\n toolPrefs,\n}: {\n base?: Record<string, unknown> | undefined;\n contextItems: ChatContextItem[];\n tools?: ToolMeta[] | undefined;\n toolPrefs?: Record<string, ToolMode> | undefined;\n}): Record<string, unknown> {\n return {\n ...base,\n ...(contextItems.length ? {\n context: serializeContext(contextItems),\n contextItems,\n } : {}),\n ...(tools ? { toolPreferences: toolPrefs ?? {} } : {}),\n };\n}\n"],"names":["serializeContext"],"mappings":";;;AAGO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAK4B;AAC1B,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,aAAa,SAAS;AAAA,MACxB,SAASA,QAAAA,iBAAiB,YAAY;AAAA,MACtC;AAAA,IAAA,IACE,CAAA;AAAA,IACJ,GAAI,QAAQ,EAAE,iBAAiB,aAAa,CAAA,EAAC,IAAM,CAAA;AAAA,EAAC;AAExD;;"}
@@ -0,0 +1,9 @@
1
+ import { ChatContextItem } from './context';
2
+ import { ToolMeta, ToolMode } from './ToolPreferences';
3
+ export declare function chatWindowRequestBody({ base, contextItems, tools, toolPrefs, }: {
4
+ base?: Record<string, unknown> | undefined;
5
+ contextItems: ChatContextItem[];
6
+ tools?: ToolMeta[] | undefined;
7
+ toolPrefs?: Record<string, ToolMode> | undefined;
8
+ }): Record<string, unknown>;
9
+ //# sourceMappingURL=ChatWindowRequestBody.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatWindowRequestBody.d.ts","sourceRoot":"","sources":["../../../src/data/ai/ChatWindowRequestBody.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE5D,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,SAAS,GACV,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IAC3C,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,KAAK,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,SAAS,CAAC;CAClD,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAS1B"}
@@ -0,0 +1,20 @@
1
+ import { serializeContext } from "./context.js";
2
+ function chatWindowRequestBody({
3
+ base,
4
+ contextItems,
5
+ tools,
6
+ toolPrefs
7
+ }) {
8
+ return {
9
+ ...base,
10
+ ...contextItems.length ? {
11
+ context: serializeContext(contextItems),
12
+ contextItems
13
+ } : {},
14
+ ...tools ? { toolPreferences: toolPrefs ?? {} } : {}
15
+ };
16
+ }
17
+ export {
18
+ chatWindowRequestBody
19
+ };
20
+ //# sourceMappingURL=ChatWindowRequestBody.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatWindowRequestBody.js","sources":["../../../src/data/ai/ChatWindowRequestBody.ts"],"sourcesContent":["import { serializeContext, type ChatContextItem } from \"./context\";\nimport type { ToolMeta, ToolMode } from \"./ToolPreferences\";\n\nexport function chatWindowRequestBody({\n base,\n contextItems,\n tools,\n toolPrefs,\n}: {\n base?: Record<string, unknown> | undefined;\n contextItems: ChatContextItem[];\n tools?: ToolMeta[] | undefined;\n toolPrefs?: Record<string, ToolMode> | undefined;\n}): Record<string, unknown> {\n return {\n ...base,\n ...(contextItems.length ? {\n context: serializeContext(contextItems),\n contextItems,\n } : {}),\n ...(tools ? { toolPreferences: toolPrefs ?? {} } : {}),\n };\n}\n"],"names":[],"mappings":";AAGO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAK4B;AAC1B,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,aAAa,SAAS;AAAA,MACxB,SAAS,iBAAiB,YAAY;AAAA,MACtC;AAAA,IAAA,IACE,CAAA;AAAA,IACJ,GAAI,QAAQ,EAAE,iBAAiB,aAAa,CAAA,EAAC,IAAM,CAAA;AAAA,EAAC;AAExD;"}
@@ -29,6 +29,8 @@ function Chat({
29
29
  body,
30
30
  transport,
31
31
  initialMessages,
32
+ initialPrompt,
33
+ onInitialPromptSent,
32
34
  placeholder,
33
35
  emptyState,
34
36
  className
@@ -38,6 +40,7 @@ function Chat({
38
40
  const [effort, setEffort] = react.useState(defaultReasoningEffort);
39
41
  const [usage, setUsage] = react.useState(null);
40
42
  const lastDefaultModel = react.useRef(defaultModel);
43
+ const sentInitialPromptId = react.useRef(null);
41
44
  react.useEffect(() => {
42
45
  if (modelsProp || !modelsApi) return;
43
46
  let cancelled = false;
@@ -77,6 +80,15 @@ function Chat({
77
80
  sendAutomaticallyWhen: ai.lastAssistantMessageIsCompleteWithApprovalResponses,
78
81
  ...initialMessages ? { messages: initialMessages } : {}
79
82
  });
83
+ react.useEffect(() => {
84
+ if (!initialPrompt || status !== "ready") return;
85
+ if (sentInitialPromptId.current === initialPrompt.id) return;
86
+ const text = initialPrompt.text.trim();
87
+ if (!text) return;
88
+ sentInitialPromptId.current = initialPrompt.id;
89
+ void sendMessage({ text });
90
+ onInitialPromptSent == null ? void 0 : onInitialPromptSent();
91
+ }, [initialPrompt, onInitialPromptSent, sendMessage, status]);
80
92
  const onUsageRef = react.useRef(onUsage);
81
93
  onUsageRef.current = onUsage;
82
94
  react.useEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"Chat.cjs","sources":["../../../src/data/chat/Chat.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useChat } from \"@ai-sdk/react\";\nimport {\n DefaultChatTransport,\n lastAssistantMessageIsCompleteWithApprovalResponses,\n type ChatTransport,\n type UIMessage,\n} from \"ai\";\nimport { cn } from \"../../lib/utils\";\nimport { Conversation } from \"./Conversation\";\nimport { PromptInput } from \"./PromptInput\";\nimport { Suggestions } from \"./Suggestion\";\nimport { ModelSelector, EffortSelector } from \"./ModelSelector\";\nimport { providerIcon } from \"./provider-icons\";\nimport { ContextUsage } from \"./ContextUsage\";\nimport type { ChatModel, ChatMessageMetadata, ChatUsageSummary, Suggestion, ToolResultRenderer } from \"./types\";\n\n/** Assistant messages carry token usage + cost the backend rode on the finish\n * part's `messageMetadata`. */\ntype ChatUIMessage = UIMessage<ChatMessageMetadata>;\n\nexport type ChatProps = {\n /** Endpoint that speaks the AI SDK v6 UI Message Stream protocol.\n * Ignored when `transport` is supplied. Defaults to \"/api/chat\". */\n api?: string;\n /** Model menu. When omitted and `modelsApi` is set, it is fetched. */\n models?: ChatModel[];\n /** Endpoint returning the model menu (ModelInfo[]). Defaults to\n * \"/api/chat/models\". Set to null to disable fetching. */\n modelsApi?: string | null;\n /** Initially selected model id; otherwise the first configured model. */\n defaultModel?: string;\n /** Reasoning-effort options for capable models. */\n reasoningEfforts?: string[];\n /** Initially selected reasoning effort (\"\" = none). */\n defaultReasoningEffort?: string;\n /** Notified when the user changes the model. */\n onModelChange?: (id: string) => void;\n /** Notified after each assistant turn with a usage snapshot (tokens used out\n * of the model's context window + cumulative cost), for a usage gauge. */\n onUsage?: (usage: ChatUsageSummary) => void;\n /** Suggested prompts shown on the empty state. */\n suggestions?: Suggestion[];\n /** Enables file/image attachments. */\n enableAttachments?: boolean;\n /** \"manual\" forwards a tool-approval policy hint to the backend. */\n toolApproval?: \"auto\" | \"manual\";\n /** Thread id to persist this conversation under (forwarded in the body). */\n threadId?: string;\n /** Optional host renderer for recognized completed tool outputs. */\n renderToolResult?: ToolResultRenderer;\n /** Extra fields merged into every request body. */\n body?: Record<string, unknown>;\n /** Pre-built transport (e.g. a mock for stories/tests). */\n transport?: ChatTransport<UIMessage>;\n /** Initial messages to seed the conversation. */\n initialMessages?: UIMessage[];\n placeholder?: string;\n emptyState?: React.ReactNode;\n className?: string;\n};\n\nconst DEFAULT_EFFORTS = [\"low\", \"medium\", \"high\"];\n\n/** Self-contained AI chat over a v6-compatible `/api/chat`: a streaming\n * conversation with model/effort selectors, suggestions, attachments,\n * per-message copy/regenerate, and human-in-the-loop tool approvals. The\n * backend owns model selection and tool execution; the selected model,\n * effort, approval policy and thread id are forwarded in the request body. */\nexport function Chat({\n api = \"/api/chat\",\n models: modelsProp,\n modelsApi = \"/api/chat/models\",\n defaultModel,\n reasoningEfforts = DEFAULT_EFFORTS,\n defaultReasoningEffort = \"\",\n onModelChange,\n onUsage,\n suggestions,\n enableAttachments = false,\n toolApproval,\n threadId,\n renderToolResult,\n body,\n transport,\n initialMessages,\n placeholder,\n emptyState,\n className,\n}: ChatProps) {\n const [models, setModels] = useState<ChatModel[]>(modelsProp ?? []);\n const [model, setModel] = useState<string | undefined>(defaultModel);\n const [effort, setEffort] = useState(defaultReasoningEffort);\n const [usage, setUsage] = useState<ChatUsageSummary | null>(null);\n const lastDefaultModel = useRef(defaultModel);\n\n // Fetch the model menu unless one was supplied or fetching is disabled.\n useEffect(() => {\n if (modelsProp || !modelsApi) return;\n let cancelled = false;\n fetch(modelsApi)\n .then((r) => (r.ok ? r.json() : Promise.reject(new Error(`models ${r.status}`))))\n .then((data: ChatModel[]) => {\n if (cancelled) return;\n setModels(data);\n setModel((m) => m ?? data.find((d) => d.configured !== false)?.id);\n })\n .catch((err) => console.warn(\"clicky-ui: failed to load chat models\", err));\n return () => {\n cancelled = true;\n };\n }, [modelsProp, modelsApi]);\n\n useEffect(() => {\n if (!defaultModel || defaultModel === lastDefaultModel.current) return;\n lastDefaultModel.current = defaultModel;\n setModel(defaultModel);\n }, [defaultModel]);\n\n const selectedModel = models.find((m) => m.id === model);\n const showEffort = !selectedModel || selectedModel.reasoning;\n\n // A function body keeps the transport stable while always sending the latest\n // model/effort/policy selections.\n const bodyRef = useRef<Record<string, unknown>>({});\n bodyRef.current = {\n ...body,\n ...(model ? { model } : {}),\n ...(effort ? { reasoningEffort: effort } : {}),\n ...(toolApproval ? { toolApproval } : {}),\n ...(threadId ? { threadId } : {}),\n };\n\n const resolvedTransport = useMemo<ChatTransport<UIMessage>>(\n () => transport ?? new DefaultChatTransport({ api, body: () => bodyRef.current }),\n [transport, api],\n );\n\n const { messages, sendMessage, regenerate, addToolApprovalResponse, status, error, clearError, stop } =\n useChat<ChatUIMessage>({\n transport: resolvedTransport,\n sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithApprovalResponses,\n ...(initialMessages ? { messages: initialMessages as ChatUIMessage[] } : {}),\n });\n\n // Surface a usage snapshot after each settled assistant turn. The backend\n // rides usage/cost on the finish part's messageMetadata; we read it off the\n // last assistant message and resolve maxTokens from the selected model.\n const onUsageRef = useRef(onUsage);\n onUsageRef.current = onUsage;\n useEffect(() => {\n if (status !== \"ready\") return;\n const last = [...messages].reverse().find((m) => m.role === \"assistant\");\n const meta = last?.metadata;\n if (!meta) return;\n const cost = meta.threadCostUsd ?? meta.cost;\n const snapshot: ChatUsageSummary = {\n usedTokens: meta.contextTokens ?? meta.usage?.totalTokens ?? 0,\n maxTokens: selectedModel?.contextWindow ?? 0,\n messageCount: messages.length,\n ...(cost != null ? { cost } : {}),\n ...(selectedModel?.label ? { modelLabel: selectedModel.label } : {}),\n };\n setUsage(snapshot);\n onUsageRef.current?.(snapshot);\n }, [messages, status, selectedModel]);\n\n const onModelSelect = (id: string) => {\n setModel(id);\n onModelChange?.(id);\n };\n\n const ModelGlyph = providerIcon(selectedModel?.provider);\n const toolbar = models.length > 0 || showEffort || (usage && usage.maxTokens > 0) ? (\n <div className=\"flex flex-1 items-center gap-2\">\n <ModelSelector models={models} value={model} onChange={onModelSelect} />\n {showEffort && (\n <EffortSelector efforts={reasoningEfforts} value={effort} onChange={setEffort} />\n )}\n {usage && usage.maxTokens > 0 && (\n <>\n <div className=\"flex-1\" />\n <ContextUsage\n usedTokens={usage.usedTokens}\n maxTokens={usage.maxTokens}\n {...(usage.messageCount != null ? { messageCount: usage.messageCount } : {})}\n {...(usage.cost != null ? { cost: usage.cost } : {})}\n {...(usage.modelLabel ? { modelLabel: usage.modelLabel } : {})}\n {...(ModelGlyph ? { modelIcon: ModelGlyph } : {})}\n />\n </>\n )}\n </div>\n ) : undefined;\n\n const empty = (messages.length === 0 && (emptyState || suggestions?.length)) ? (\n <div className=\"flex flex-col items-center gap-4\">\n {emptyState}\n {suggestions && suggestions.length > 0 && (\n <Suggestions suggestions={suggestions} onSelect={(text) => void sendMessage({ text })} />\n )}\n </div>\n ) : undefined;\n\n return (\n <div className={cn(\"flex h-full flex-col\", className)}>\n <Conversation\n messages={messages}\n status={status}\n error={error}\n onClearError={clearError}\n emptyState={empty}\n onRegenerate={(messageId) => void regenerate({ messageId })}\n onApprove={(id, approved, reason) =>\n void addToolApprovalResponse(reason ? { id, approved, reason } : { id, approved })\n }\n {...(renderToolResult ? { renderToolResult } : {})}\n />\n <div className=\"p-4 pt-0\">\n <PromptInput\n status={status}\n onStop={() => void stop()}\n placeholder={placeholder}\n enableAttachments={enableAttachments}\n toolbar={toolbar}\n onSubmit={(text, files) => void sendMessage({ text, files })}\n />\n </div>\n </div>\n );\n}\n"],"names":["useState","useRef","useEffect","useMemo","DefaultChatTransport","useChat","lastAssistantMessageIsCompleteWithApprovalResponses","providerIcon","jsxs","jsx","ModelSelector","EffortSelector","Fragment","ContextUsage","Suggestions","cn","Conversation","PromptInput"],"mappings":"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"}
1
+ {"version":3,"file":"Chat.cjs","sources":["../../../src/data/chat/Chat.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useChat } from \"@ai-sdk/react\";\nimport {\n DefaultChatTransport,\n lastAssistantMessageIsCompleteWithApprovalResponses,\n type ChatTransport,\n type UIMessage,\n} from \"ai\";\nimport { cn } from \"../../lib/utils\";\nimport { Conversation } from \"./Conversation\";\nimport { PromptInput } from \"./PromptInput\";\nimport { Suggestions } from \"./Suggestion\";\nimport { ModelSelector, EffortSelector } from \"./ModelSelector\";\nimport { providerIcon } from \"./provider-icons\";\nimport { ContextUsage } from \"./ContextUsage\";\nimport type { ChatModel, ChatMessageMetadata, ChatUsageSummary, Suggestion, ToolResultRenderer } from \"./types\";\n\n/** Assistant messages carry token usage + cost the backend rode on the finish\n * part's `messageMetadata`. */\ntype ChatUIMessage = UIMessage<ChatMessageMetadata>;\n\nexport type ChatProps = {\n /** Endpoint that speaks the AI SDK v6 UI Message Stream protocol.\n * Ignored when `transport` is supplied. Defaults to \"/api/chat\". */\n api?: string;\n /** Model menu. When omitted and `modelsApi` is set, it is fetched. */\n models?: ChatModel[];\n /** Endpoint returning the model menu (ModelInfo[]). Defaults to\n * \"/api/chat/models\". Set to null to disable fetching. */\n modelsApi?: string | null;\n /** Initially selected model id; otherwise the first configured model. */\n defaultModel?: string;\n /** Reasoning-effort options for capable models. */\n reasoningEfforts?: string[];\n /** Initially selected reasoning effort (\"\" = none). */\n defaultReasoningEffort?: string;\n /** Notified when the user changes the model. */\n onModelChange?: (id: string) => void;\n /** Notified after each assistant turn with a usage snapshot (tokens used out\n * of the model's context window + cumulative cost), for a usage gauge. */\n onUsage?: (usage: ChatUsageSummary) => void;\n /** Suggested prompts shown on the empty state. */\n suggestions?: Suggestion[];\n /** Enables file/image attachments. */\n enableAttachments?: boolean;\n /** \"manual\" forwards a tool-approval policy hint to the backend. */\n toolApproval?: \"auto\" | \"manual\";\n /** Thread id to persist this conversation under (forwarded in the body). */\n threadId?: string;\n /** Optional host renderer for recognized completed tool outputs. */\n renderToolResult?: ToolResultRenderer;\n /** Extra fields merged into every request body. */\n body?: Record<string, unknown>;\n /** Pre-built transport (e.g. a mock for stories/tests). */\n transport?: ChatTransport<UIMessage>;\n /** Initial messages to seed the conversation. */\n initialMessages?: UIMessage[];\n /** Prompt to send automatically once. A new `id` sends even when text repeats. */\n initialPrompt?: { id: number; text: string } | null;\n /** Called after `initialPrompt` has been handed to the chat transport. */\n onInitialPromptSent?: () => void;\n placeholder?: string;\n emptyState?: React.ReactNode;\n className?: string;\n};\n\nconst DEFAULT_EFFORTS = [\"low\", \"medium\", \"high\"];\n\n/** Self-contained AI chat over a v6-compatible `/api/chat`: a streaming\n * conversation with model/effort selectors, suggestions, attachments,\n * per-message copy/regenerate, and human-in-the-loop tool approvals. The\n * backend owns model selection and tool execution; the selected model,\n * effort, approval policy and thread id are forwarded in the request body. */\nexport function Chat({\n api = \"/api/chat\",\n models: modelsProp,\n modelsApi = \"/api/chat/models\",\n defaultModel,\n reasoningEfforts = DEFAULT_EFFORTS,\n defaultReasoningEffort = \"\",\n onModelChange,\n onUsage,\n suggestions,\n enableAttachments = false,\n toolApproval,\n threadId,\n renderToolResult,\n body,\n transport,\n initialMessages,\n initialPrompt,\n onInitialPromptSent,\n placeholder,\n emptyState,\n className,\n}: ChatProps) {\n const [models, setModels] = useState<ChatModel[]>(modelsProp ?? []);\n const [model, setModel] = useState<string | undefined>(defaultModel);\n const [effort, setEffort] = useState(defaultReasoningEffort);\n const [usage, setUsage] = useState<ChatUsageSummary | null>(null);\n const lastDefaultModel = useRef(defaultModel);\n const sentInitialPromptId = useRef<number | null>(null);\n\n // Fetch the model menu unless one was supplied or fetching is disabled.\n useEffect(() => {\n if (modelsProp || !modelsApi) return;\n let cancelled = false;\n fetch(modelsApi)\n .then((r) => (r.ok ? r.json() : Promise.reject(new Error(`models ${r.status}`))))\n .then((data: ChatModel[]) => {\n if (cancelled) return;\n setModels(data);\n setModel((m) => m ?? data.find((d) => d.configured !== false)?.id);\n })\n .catch((err) => console.warn(\"clicky-ui: failed to load chat models\", err));\n return () => {\n cancelled = true;\n };\n }, [modelsProp, modelsApi]);\n\n useEffect(() => {\n if (!defaultModel || defaultModel === lastDefaultModel.current) return;\n lastDefaultModel.current = defaultModel;\n setModel(defaultModel);\n }, [defaultModel]);\n\n const selectedModel = models.find((m) => m.id === model);\n const showEffort = !selectedModel || selectedModel.reasoning;\n\n // A function body keeps the transport stable while always sending the latest\n // model/effort/policy selections.\n const bodyRef = useRef<Record<string, unknown>>({});\n bodyRef.current = {\n ...body,\n ...(model ? { model } : {}),\n ...(effort ? { reasoningEffort: effort } : {}),\n ...(toolApproval ? { toolApproval } : {}),\n ...(threadId ? { threadId } : {}),\n };\n\n const resolvedTransport = useMemo<ChatTransport<UIMessage>>(\n () => transport ?? new DefaultChatTransport({ api, body: () => bodyRef.current }),\n [transport, api],\n );\n\n const { messages, sendMessage, regenerate, addToolApprovalResponse, status, error, clearError, stop } =\n useChat<ChatUIMessage>({\n transport: resolvedTransport,\n sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithApprovalResponses,\n ...(initialMessages ? { messages: initialMessages as ChatUIMessage[] } : {}),\n });\n\n useEffect(() => {\n if (!initialPrompt || status !== \"ready\") return;\n if (sentInitialPromptId.current === initialPrompt.id) return;\n const text = initialPrompt.text.trim();\n if (!text) return;\n sentInitialPromptId.current = initialPrompt.id;\n void sendMessage({ text });\n onInitialPromptSent?.();\n }, [initialPrompt, onInitialPromptSent, sendMessage, status]);\n\n // Surface a usage snapshot after each settled assistant turn. The backend\n // rides usage/cost on the finish part's messageMetadata; we read it off the\n // last assistant message and resolve maxTokens from the selected model.\n const onUsageRef = useRef(onUsage);\n onUsageRef.current = onUsage;\n useEffect(() => {\n if (status !== \"ready\") return;\n const last = [...messages].reverse().find((m) => m.role === \"assistant\");\n const meta = last?.metadata;\n if (!meta) return;\n const cost = meta.threadCostUsd ?? meta.cost;\n const snapshot: ChatUsageSummary = {\n usedTokens: meta.contextTokens ?? meta.usage?.totalTokens ?? 0,\n maxTokens: selectedModel?.contextWindow ?? 0,\n messageCount: messages.length,\n ...(cost != null ? { cost } : {}),\n ...(selectedModel?.label ? { modelLabel: selectedModel.label } : {}),\n };\n setUsage(snapshot);\n onUsageRef.current?.(snapshot);\n }, [messages, status, selectedModel]);\n\n const onModelSelect = (id: string) => {\n setModel(id);\n onModelChange?.(id);\n };\n\n const ModelGlyph = providerIcon(selectedModel?.provider);\n const toolbar = models.length > 0 || showEffort || (usage && usage.maxTokens > 0) ? (\n <div className=\"flex flex-1 items-center gap-2\">\n <ModelSelector models={models} value={model} onChange={onModelSelect} />\n {showEffort && (\n <EffortSelector efforts={reasoningEfforts} value={effort} onChange={setEffort} />\n )}\n {usage && usage.maxTokens > 0 && (\n <>\n <div className=\"flex-1\" />\n <ContextUsage\n usedTokens={usage.usedTokens}\n maxTokens={usage.maxTokens}\n {...(usage.messageCount != null ? { messageCount: usage.messageCount } : {})}\n {...(usage.cost != null ? { cost: usage.cost } : {})}\n {...(usage.modelLabel ? { modelLabel: usage.modelLabel } : {})}\n {...(ModelGlyph ? { modelIcon: ModelGlyph } : {})}\n />\n </>\n )}\n </div>\n ) : undefined;\n\n const empty = (messages.length === 0 && (emptyState || suggestions?.length)) ? (\n <div className=\"flex flex-col items-center gap-4\">\n {emptyState}\n {suggestions && suggestions.length > 0 && (\n <Suggestions suggestions={suggestions} onSelect={(text) => void sendMessage({ text })} />\n )}\n </div>\n ) : undefined;\n\n return (\n <div className={cn(\"flex h-full flex-col\", className)}>\n <Conversation\n messages={messages}\n status={status}\n error={error}\n onClearError={clearError}\n emptyState={empty}\n onRegenerate={(messageId) => void regenerate({ messageId })}\n onApprove={(id, approved, reason) =>\n void addToolApprovalResponse(reason ? { id, approved, reason } : { id, approved })\n }\n {...(renderToolResult ? { renderToolResult } : {})}\n />\n <div className=\"p-4 pt-0\">\n <PromptInput\n status={status}\n onStop={() => void stop()}\n placeholder={placeholder}\n enableAttachments={enableAttachments}\n toolbar={toolbar}\n onSubmit={(text, files) => void sendMessage({ text, files })}\n />\n </div>\n </div>\n );\n}\n"],"names":["useState","useRef","useEffect","useMemo","DefaultChatTransport","useChat","lastAssistantMessageIsCompleteWithApprovalResponses","providerIcon","jsxs","jsx","ModelSelector","EffortSelector","Fragment","ContextUsage","Suggestions","cn","Conversation","PromptInput"],"mappings":"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"}
@@ -36,6 +36,13 @@ export type ChatProps = {
36
36
  transport?: ChatTransport<UIMessage>;
37
37
  /** Initial messages to seed the conversation. */
38
38
  initialMessages?: UIMessage[];
39
+ /** Prompt to send automatically once. A new `id` sends even when text repeats. */
40
+ initialPrompt?: {
41
+ id: number;
42
+ text: string;
43
+ } | null;
44
+ /** Called after `initialPrompt` has been handed to the chat transport. */
45
+ onInitialPromptSent?: () => void;
39
46
  placeholder?: string;
40
47
  emptyState?: React.ReactNode;
41
48
  className?: string;
@@ -45,5 +52,5 @@ export type ChatProps = {
45
52
  * per-message copy/regenerate, and human-in-the-loop tool approvals. The
46
53
  * backend owns model selection and tool execution; the selected model,
47
54
  * effort, approval policy and thread id are forwarded in the request body. */
48
- export declare function Chat({ api, models: modelsProp, modelsApi, defaultModel, reasoningEfforts, defaultReasoningEffort, onModelChange, onUsage, suggestions, enableAttachments, toolApproval, threadId, renderToolResult, body, transport, initialMessages, placeholder, emptyState, className, }: ChatProps): import("react/jsx-runtime").JSX.Element;
55
+ export declare function Chat({ api, models: modelsProp, modelsApi, defaultModel, reasoningEfforts, defaultReasoningEffort, onModelChange, onUsage, suggestions, enableAttachments, toolApproval, threadId, renderToolResult, body, transport, initialMessages, initialPrompt, onInitialPromptSent, placeholder, emptyState, className, }: ChatProps): import("react/jsx-runtime").JSX.Element;
49
56
  //# sourceMappingURL=Chat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/data/chat/Chat.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,IAAI,CAAC;AAQZ,OAAO,KAAK,EAAE,SAAS,EAAuB,gBAAgB,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAMhH,MAAM,MAAM,SAAS,GAAG;IACtB;yEACqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB;+DAC2D;IAC3D,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,uDAAuD;IACvD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gDAAgD;IAChD,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;+EAC2E;IAC3E,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC5C,kDAAkD;IAClD,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,sCAAsC;IACtC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IACjC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,2DAA2D;IAC3D,SAAS,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACrC,iDAAiD;IACjD,eAAe,CAAC,EAAE,SAAS,EAAE,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF;;;;+EAI+E;AAC/E,wBAAgB,IAAI,CAAC,EACnB,GAAiB,EACjB,MAAM,EAAE,UAAU,EAClB,SAA8B,EAC9B,YAAY,EACZ,gBAAkC,EAClC,sBAA2B,EAC3B,aAAa,EACb,OAAO,EACP,WAAW,EACX,iBAAyB,EACzB,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAChB,IAAI,EACJ,SAAS,EACT,eAAe,EACf,WAAW,EACX,UAAU,EACV,SAAS,GACV,EAAE,SAAS,2CA6IX"}
1
+ {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/data/chat/Chat.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,IAAI,CAAC;AAQZ,OAAO,KAAK,EAAE,SAAS,EAAuB,gBAAgB,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAMhH,MAAM,MAAM,SAAS,GAAG;IACtB;yEACqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB;+DAC2D;IAC3D,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,uDAAuD;IACvD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gDAAgD;IAChD,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;+EAC2E;IAC3E,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC5C,kDAAkD;IAClD,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,sCAAsC;IACtC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IACjC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,2DAA2D;IAC3D,SAAS,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACrC,iDAAiD;IACjD,eAAe,CAAC,EAAE,SAAS,EAAE,CAAC;IAC9B,kFAAkF;IAClF,aAAa,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACpD,0EAA0E;IAC1E,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF;;;;+EAI+E;AAC/E,wBAAgB,IAAI,CAAC,EACnB,GAAiB,EACjB,MAAM,EAAE,UAAU,EAClB,SAA8B,EAC9B,YAAY,EACZ,gBAAkC,EAClC,sBAA2B,EAC3B,aAAa,EACb,OAAO,EACP,WAAW,EACX,iBAAyB,EACzB,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAChB,IAAI,EACJ,SAAS,EACT,eAAe,EACf,aAAa,EACb,mBAAmB,EACnB,WAAW,EACX,UAAU,EACV,SAAS,GACV,EAAE,SAAS,2CAwJX"}