@flanksource/clicky-ui 0.2.19 → 0.2.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (417) hide show
  1. package/dist/ai.cjs +26 -0
  2. package/dist/ai.cjs.map +1 -0
  3. package/dist/ai.d.ts +2 -0
  4. package/dist/ai.d.ts.map +1 -0
  5. package/dist/ai.js +26 -0
  6. package/dist/ai.js.map +1 -0
  7. package/dist/chat.cjs +7 -0
  8. package/dist/chat.cjs.map +1 -1
  9. package/dist/chat.js +7 -0
  10. package/dist/chat.js.map +1 -1
  11. package/dist/components/FilterBar.cjs +49 -18
  12. package/dist/components/FilterBar.cjs.map +1 -1
  13. package/dist/components/FilterBar.d.ts +0 -2
  14. package/dist/components/FilterBar.d.ts.map +1 -1
  15. package/dist/components/FilterBar.js +50 -19
  16. package/dist/components/FilterBar.js.map +1 -1
  17. package/dist/components/SearchInput.cjs +63 -0
  18. package/dist/components/SearchInput.cjs.map +1 -0
  19. package/dist/components/SearchInput.d.ts +31 -0
  20. package/dist/components/SearchInput.d.ts.map +1 -0
  21. package/dist/components/SearchInput.js +63 -0
  22. package/dist/components/SearchInput.js.map +1 -0
  23. package/dist/components/SegmentedControl.cjs +88 -0
  24. package/dist/components/SegmentedControl.cjs.map +1 -0
  25. package/dist/components/SegmentedControl.d.ts +38 -0
  26. package/dist/components/SegmentedControl.d.ts.map +1 -0
  27. package/dist/components/SegmentedControl.js +88 -0
  28. package/dist/components/SegmentedControl.js.map +1 -0
  29. package/dist/components/Switch.cjs +51 -0
  30. package/dist/components/Switch.cjs.map +1 -0
  31. package/dist/components/Switch.d.ts +23 -0
  32. package/dist/components/Switch.d.ts.map +1 -0
  33. package/dist/components/Switch.js +51 -0
  34. package/dist/components/Switch.js.map +1 -0
  35. package/dist/components/TimeRange.cjs +53 -45
  36. package/dist/components/TimeRange.cjs.map +1 -1
  37. package/dist/components/TimeRange.d.ts.map +1 -1
  38. package/dist/components/TimeRange.js +53 -45
  39. package/dist/components/TimeRange.js.map +1 -1
  40. package/dist/components/TreePickerField.cjs +5 -1
  41. package/dist/components/TreePickerField.cjs.map +1 -1
  42. package/dist/components/TreePickerField.d.ts.map +1 -1
  43. package/dist/components/TreePickerField.js +5 -1
  44. package/dist/components/TreePickerField.js.map +1 -1
  45. package/dist/components/filter-bar-utils.cjs +5 -0
  46. package/dist/components/filter-bar-utils.cjs.map +1 -1
  47. package/dist/components/filter-bar-utils.d.ts +2 -0
  48. package/dist/components/filter-bar-utils.d.ts.map +1 -1
  49. package/dist/components/filter-bar-utils.js +5 -0
  50. package/dist/components/filter-bar-utils.js.map +1 -1
  51. package/dist/components/json-schema-form-fields.cjs +8 -2
  52. package/dist/components/json-schema-form-fields.cjs.map +1 -1
  53. package/dist/components/json-schema-form-fields.d.ts.map +1 -1
  54. package/dist/components/json-schema-form-fields.js +8 -2
  55. package/dist/components/json-schema-form-fields.js.map +1 -1
  56. package/dist/components/json-schema-form-resolve.cjs +1 -1
  57. package/dist/components/json-schema-form-resolve.cjs.map +1 -1
  58. package/dist/components/json-schema-form-resolve.js +1 -1
  59. package/dist/components/json-schema-form-resolve.js.map +1 -1
  60. package/dist/components.cjs +15 -1
  61. package/dist/components.cjs.map +1 -1
  62. package/dist/components.d.ts +8 -1
  63. package/dist/components.d.ts.map +1 -1
  64. package/dist/components.js +15 -1
  65. package/dist/components.js.map +1 -1
  66. package/dist/data/Clicky.cjs +33 -44
  67. package/dist/data/Clicky.cjs.map +1 -1
  68. package/dist/data/Clicky.d.ts +0 -9
  69. package/dist/data/Clicky.d.ts.map +1 -1
  70. package/dist/data/Clicky.js +31 -42
  71. package/dist/data/Clicky.js.map +1 -1
  72. package/dist/data/DataTable.cjs +73 -50
  73. package/dist/data/DataTable.cjs.map +1 -1
  74. package/dist/data/DataTable.d.ts +4 -0
  75. package/dist/data/DataTable.d.ts.map +1 -1
  76. package/dist/data/DataTable.js +73 -50
  77. package/dist/data/DataTable.js.map +1 -1
  78. package/dist/data/Icon.cjs +2 -5
  79. package/dist/data/Icon.cjs.map +1 -1
  80. package/dist/data/Icon.d.ts +1 -21
  81. package/dist/data/Icon.d.ts.map +1 -1
  82. package/dist/data/Icon.js +3 -6
  83. package/dist/data/Icon.js.map +1 -1
  84. package/dist/data/MatrixTable.cjs +4 -4
  85. package/dist/data/MatrixTable.cjs.map +1 -1
  86. package/dist/data/MatrixTable.js +4 -4
  87. package/dist/data/MatrixTable.js.map +1 -1
  88. package/dist/data/RadialGauge.cjs +76 -0
  89. package/dist/data/RadialGauge.cjs.map +1 -0
  90. package/dist/data/RadialGauge.d.ts +24 -0
  91. package/dist/data/RadialGauge.d.ts.map +1 -0
  92. package/dist/data/RadialGauge.js +76 -0
  93. package/dist/data/RadialGauge.js.map +1 -0
  94. package/dist/data/StatusBreakdown.cjs +0 -4
  95. package/dist/data/StatusBreakdown.cjs.map +1 -1
  96. package/dist/data/StatusBreakdown.d.ts +0 -2
  97. package/dist/data/StatusBreakdown.d.ts.map +1 -1
  98. package/dist/data/StatusBreakdown.js +1 -5
  99. package/dist/data/StatusBreakdown.js.map +1 -1
  100. package/dist/data/Timeline.cjs +61 -0
  101. package/dist/data/Timeline.cjs.map +1 -0
  102. package/dist/data/Timeline.d.ts +36 -0
  103. package/dist/data/Timeline.d.ts.map +1 -0
  104. package/dist/data/Timeline.js +61 -0
  105. package/dist/data/Timeline.js.map +1 -0
  106. package/dist/data/TimeseriesCoreBars.cjs +2 -25
  107. package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
  108. package/dist/data/TimeseriesCoreBars.d.ts +0 -19
  109. package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
  110. package/dist/data/TimeseriesCoreBars.js +2 -25
  111. package/dist/data/TimeseriesCoreBars.js.map +1 -1
  112. package/dist/data/TimeseriesCoreBars.model.cjs +27 -0
  113. package/dist/data/TimeseriesCoreBars.model.cjs.map +1 -0
  114. package/dist/data/TimeseriesCoreBars.model.d.ts +20 -0
  115. package/dist/data/TimeseriesCoreBars.model.d.ts.map +1 -0
  116. package/dist/data/TimeseriesCoreBars.model.js +27 -0
  117. package/dist/data/TimeseriesCoreBars.model.js.map +1 -0
  118. package/dist/data/TimeseriesPanel.axes.cjs.map +1 -1
  119. package/dist/data/TimeseriesPanel.axes.d.ts +1 -1
  120. package/dist/data/TimeseriesPanel.axes.d.ts.map +1 -1
  121. package/dist/data/TimeseriesPanel.axes.js.map +1 -1
  122. package/dist/data/TimeseriesPanel.cjs +4 -54
  123. package/dist/data/TimeseriesPanel.cjs.map +1 -1
  124. package/dist/data/TimeseriesPanel.d.ts +2 -138
  125. package/dist/data/TimeseriesPanel.d.ts.map +1 -1
  126. package/dist/data/TimeseriesPanel.js +2 -52
  127. package/dist/data/TimeseriesPanel.js.map +1 -1
  128. package/dist/data/TimeseriesPanel.model.cjs +53 -0
  129. package/dist/data/TimeseriesPanel.model.cjs.map +1 -0
  130. package/dist/data/TimeseriesPanel.model.d.ts +88 -0
  131. package/dist/data/TimeseriesPanel.model.d.ts.map +1 -0
  132. package/dist/data/TimeseriesPanel.model.js +53 -0
  133. package/dist/data/TimeseriesPanel.model.js.map +1 -0
  134. package/dist/data/Tree.cjs +1 -1
  135. package/dist/data/Tree.cjs.map +1 -1
  136. package/dist/data/Tree.js +1 -1
  137. package/dist/data/Tree.js.map +1 -1
  138. package/dist/data/ai/ChatFab.cjs +29 -0
  139. package/dist/data/ai/ChatFab.cjs.map +1 -0
  140. package/dist/data/ai/ChatFab.d.ts +12 -0
  141. package/dist/data/ai/ChatFab.d.ts.map +1 -0
  142. package/dist/data/ai/ChatFab.js +29 -0
  143. package/dist/data/ai/ChatFab.js.map +1 -0
  144. package/dist/data/ai/ChatWindow.cjs +178 -0
  145. package/dist/data/ai/ChatWindow.cjs.map +1 -0
  146. package/dist/data/ai/ChatWindow.d.ts +38 -0
  147. package/dist/data/ai/ChatWindow.d.ts.map +1 -0
  148. package/dist/data/ai/ChatWindow.js +156 -0
  149. package/dist/data/ai/ChatWindow.js.map +1 -0
  150. package/dist/data/ai/ChatWindowManager.cjs +139 -0
  151. package/dist/data/ai/ChatWindowManager.cjs.map +1 -0
  152. package/dist/data/ai/ChatWindowManager.d.ts +12 -0
  153. package/dist/data/ai/ChatWindowManager.d.ts.map +1 -0
  154. package/dist/data/ai/ChatWindowManager.js +139 -0
  155. package/dist/data/ai/ChatWindowManager.js.map +1 -0
  156. package/dist/data/ai/ContextBadges.cjs +74 -0
  157. package/dist/data/ai/ContextBadges.cjs.map +1 -0
  158. package/dist/data/ai/ContextBadges.d.ts +16 -0
  159. package/dist/data/ai/ContextBadges.d.ts.map +1 -0
  160. package/dist/data/ai/ContextBadges.js +74 -0
  161. package/dist/data/ai/ContextBadges.js.map +1 -0
  162. package/dist/data/ai/ThreadPicker.cjs +148 -0
  163. package/dist/data/ai/ThreadPicker.cjs.map +1 -0
  164. package/dist/data/ai/ThreadPicker.d.ts +37 -0
  165. package/dist/data/ai/ThreadPicker.d.ts.map +1 -0
  166. package/dist/data/ai/ThreadPicker.js +148 -0
  167. package/dist/data/ai/ThreadPicker.js.map +1 -0
  168. package/dist/data/ai/ToolPreferences.cjs +80 -0
  169. package/dist/data/ai/ToolPreferences.cjs.map +1 -0
  170. package/dist/data/ai/ToolPreferences.d.ts +19 -0
  171. package/dist/data/ai/ToolPreferences.d.ts.map +1 -0
  172. package/dist/data/ai/ToolPreferences.js +80 -0
  173. package/dist/data/ai/ToolPreferences.js.map +1 -0
  174. package/dist/data/ai/chat-window-context.cjs +78 -0
  175. package/dist/data/ai/chat-window-context.cjs.map +1 -0
  176. package/dist/data/ai/chat-window-context.d.ts +57 -0
  177. package/dist/data/ai/chat-window-context.d.ts.map +1 -0
  178. package/dist/data/ai/chat-window-context.js +78 -0
  179. package/dist/data/ai/chat-window-context.js.map +1 -0
  180. package/dist/data/ai/context.cjs +43 -0
  181. package/dist/data/ai/context.cjs.map +1 -0
  182. package/dist/data/ai/context.d.ts +35 -0
  183. package/dist/data/ai/context.d.ts.map +1 -0
  184. package/dist/data/ai/context.js +43 -0
  185. package/dist/data/ai/context.js.map +1 -0
  186. package/dist/data/ai/index.d.ts +10 -0
  187. package/dist/data/ai/index.d.ts.map +1 -0
  188. package/dist/data/cache-browser/CacheDetailPanel.cjs +15 -0
  189. package/dist/data/cache-browser/CacheDetailPanel.cjs.map +1 -1
  190. package/dist/data/cache-browser/CacheDetailPanel.d.ts.map +1 -1
  191. package/dist/data/cache-browser/CacheDetailPanel.js +15 -0
  192. package/dist/data/cache-browser/CacheDetailPanel.js.map +1 -1
  193. package/dist/data/cache-browser/cache-browser.fixtures.d.ts +10 -0
  194. package/dist/data/cache-browser/cache-browser.fixtures.d.ts.map +1 -0
  195. package/dist/data/cache-browser/download.cjs +13 -0
  196. package/dist/data/cache-browser/download.cjs.map +1 -0
  197. package/dist/data/cache-browser/download.d.ts +3 -0
  198. package/dist/data/cache-browser/download.d.ts.map +1 -0
  199. package/dist/data/cache-browser/download.js +13 -0
  200. package/dist/data/cache-browser/download.js.map +1 -0
  201. package/dist/data/chat/Chat.cjs +40 -2
  202. package/dist/data/chat/Chat.cjs.map +1 -1
  203. package/dist/data/chat/Chat.d.ts +5 -2
  204. package/dist/data/chat/Chat.d.ts.map +1 -1
  205. package/dist/data/chat/Chat.fixtures.cjs +86 -0
  206. package/dist/data/chat/Chat.fixtures.cjs.map +1 -0
  207. package/dist/data/chat/Chat.fixtures.d.ts +4 -0
  208. package/dist/data/chat/Chat.fixtures.d.ts.map +1 -1
  209. package/dist/data/chat/Chat.fixtures.js +86 -0
  210. package/dist/data/chat/Chat.fixtures.js.map +1 -0
  211. package/dist/data/chat/Chat.js +41 -3
  212. package/dist/data/chat/Chat.js.map +1 -1
  213. package/dist/data/chat/ContextUsage.cjs +99 -0
  214. package/dist/data/chat/ContextUsage.cjs.map +1 -0
  215. package/dist/data/chat/ContextUsage.d.ts +19 -0
  216. package/dist/data/chat/ContextUsage.d.ts.map +1 -0
  217. package/dist/data/chat/ContextUsage.js +99 -0
  218. package/dist/data/chat/ContextUsage.js.map +1 -0
  219. package/dist/data/chat/ModelSelector.cjs +28 -14
  220. package/dist/data/chat/ModelSelector.cjs.map +1 -1
  221. package/dist/data/chat/ModelSelector.d.ts +5 -4
  222. package/dist/data/chat/ModelSelector.d.ts.map +1 -1
  223. package/dist/data/chat/ModelSelector.js +28 -14
  224. package/dist/data/chat/ModelSelector.js.map +1 -1
  225. package/dist/data/chat/clickyOperationsToTools.cjs +21 -1
  226. package/dist/data/chat/clickyOperationsToTools.cjs.map +1 -1
  227. package/dist/data/chat/clickyOperationsToTools.d.ts +5 -4
  228. package/dist/data/chat/clickyOperationsToTools.d.ts.map +1 -1
  229. package/dist/data/chat/clickyOperationsToTools.js +21 -1
  230. package/dist/data/chat/clickyOperationsToTools.js.map +1 -1
  231. package/dist/data/chat/index.d.ts +4 -1
  232. package/dist/data/chat/index.d.ts.map +1 -1
  233. package/dist/data/chat/provider-icons.cjs +15 -0
  234. package/dist/data/chat/provider-icons.cjs.map +1 -0
  235. package/dist/data/chat/provider-icons.d.ts +7 -0
  236. package/dist/data/chat/provider-icons.d.ts.map +1 -0
  237. package/dist/data/chat/provider-icons.js +15 -0
  238. package/dist/data/chat/provider-icons.js.map +1 -0
  239. package/dist/data/chat/types.cjs.map +1 -1
  240. package/dist/data/chat/types.d.ts +41 -9
  241. package/dist/data/chat/types.d.ts.map +1 -1
  242. package/dist/data/chat/types.js.map +1 -1
  243. package/dist/data/clicky-parse.cjs +42 -0
  244. package/dist/data/clicky-parse.cjs.map +1 -0
  245. package/dist/data/clicky-parse.d.ts +11 -0
  246. package/dist/data/clicky-parse.d.ts.map +1 -0
  247. package/dist/data/clicky-parse.js +42 -0
  248. package/dist/data/clicky-parse.js.map +1 -0
  249. package/dist/data/diagnostics/FrameSourceWindow.cjs +0 -4
  250. package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
  251. package/dist/data/diagnostics/FrameSourceWindow.d.ts +1 -11
  252. package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
  253. package/dist/data/diagnostics/FrameSourceWindow.js +1 -5
  254. package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
  255. package/dist/data/diagnostics/FrameSourceWindow.utils.cjs +7 -0
  256. package/dist/data/diagnostics/FrameSourceWindow.utils.cjs.map +1 -0
  257. package/dist/data/diagnostics/FrameSourceWindow.utils.d.ts +12 -0
  258. package/dist/data/diagnostics/FrameSourceWindow.utils.d.ts.map +1 -0
  259. package/dist/data/diagnostics/FrameSourceWindow.utils.js +7 -0
  260. package/dist/data/diagnostics/FrameSourceWindow.utils.js.map +1 -0
  261. package/dist/data/diagnostics/JvmStackTrace.cjs +2 -1
  262. package/dist/data/diagnostics/JvmStackTrace.cjs.map +1 -1
  263. package/dist/data/diagnostics/JvmStackTrace.d.ts.map +1 -1
  264. package/dist/data/diagnostics/JvmStackTrace.js +2 -1
  265. package/dist/data/diagnostics/JvmStackTrace.js.map +1 -1
  266. package/dist/data/icon-fallback.cjs +12 -0
  267. package/dist/data/icon-fallback.cjs.map +1 -0
  268. package/dist/data/icon-fallback.d.ts +19 -0
  269. package/dist/data/icon-fallback.d.ts.map +1 -0
  270. package/dist/data/icon-fallback.js +12 -0
  271. package/dist/data/icon-fallback.js.map +1 -0
  272. package/dist/data/status-breakdown-utils.cjs +7 -0
  273. package/dist/data/status-breakdown-utils.cjs.map +1 -0
  274. package/dist/data/status-breakdown-utils.d.ts +4 -0
  275. package/dist/data/status-breakdown-utils.d.ts.map +1 -0
  276. package/dist/data/status-breakdown-utils.js +7 -0
  277. package/dist/data/status-breakdown-utils.js.map +1 -0
  278. package/dist/data/test-runner/TestRunSummary.cjs +36 -0
  279. package/dist/data/test-runner/TestRunSummary.cjs.map +1 -1
  280. package/dist/data/test-runner/TestRunSummary.d.ts +7 -1
  281. package/dist/data/test-runner/TestRunSummary.d.ts.map +1 -1
  282. package/dist/data/test-runner/TestRunSummary.js +36 -0
  283. package/dist/data/test-runner/TestRunSummary.js.map +1 -1
  284. package/dist/data/test-runner/TestRunner.cjs +5 -3
  285. package/dist/data/test-runner/TestRunner.cjs.map +1 -1
  286. package/dist/data/test-runner/TestRunner.d.ts +13 -1
  287. package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
  288. package/dist/data/test-runner/TestRunner.js +5 -3
  289. package/dist/data/test-runner/TestRunner.js.map +1 -1
  290. package/dist/data/version-info.cjs +2 -2
  291. package/dist/data/version-info.js +2 -2
  292. package/dist/data.cjs +19 -6
  293. package/dist/data.cjs.map +1 -1
  294. package/dist/data.d.ts +13 -5
  295. package/dist/data.d.ts.map +1 -1
  296. package/dist/data.js +18 -5
  297. package/dist/data.js.map +1 -1
  298. package/dist/index.cjs +51 -7
  299. package/dist/index.cjs.map +1 -1
  300. package/dist/index.js +50 -6
  301. package/dist/index.js.map +1 -1
  302. package/dist/layout/AppShell.cjs +179 -29
  303. package/dist/layout/AppShell.cjs.map +1 -1
  304. package/dist/layout/AppShell.d.ts +5 -5
  305. package/dist/layout/AppShell.d.ts.map +1 -1
  306. package/dist/layout/AppShell.js +179 -29
  307. package/dist/layout/AppShell.js.map +1 -1
  308. package/dist/layout/AppSidebar.cjs +239 -0
  309. package/dist/layout/AppSidebar.cjs.map +1 -0
  310. package/dist/layout/AppSidebar.d.ts +62 -0
  311. package/dist/layout/AppSidebar.d.ts.map +1 -0
  312. package/dist/layout/AppSidebar.js +239 -0
  313. package/dist/layout/AppSidebar.js.map +1 -0
  314. package/dist/overlay/DropdownMenu.cjs.map +1 -1
  315. package/dist/overlay/DropdownMenu.d.ts.map +1 -1
  316. package/dist/overlay/DropdownMenu.js.map +1 -1
  317. package/dist/overlay/Modal.cjs +4 -2
  318. package/dist/overlay/Modal.cjs.map +1 -1
  319. package/dist/overlay/Modal.d.ts +1 -1
  320. package/dist/overlay/Modal.d.ts.map +1 -1
  321. package/dist/overlay/Modal.js +4 -2
  322. package/dist/overlay/Modal.js.map +1 -1
  323. package/dist/overlay/Toast.cjs +89 -0
  324. package/dist/overlay/Toast.cjs.map +1 -0
  325. package/dist/overlay/Toast.d.ts +14 -0
  326. package/dist/overlay/Toast.d.ts.map +1 -0
  327. package/dist/overlay/Toast.js +89 -0
  328. package/dist/overlay/Toast.js.map +1 -0
  329. package/dist/overlay/toast-context.cjs +12 -0
  330. package/dist/overlay/toast-context.cjs.map +1 -0
  331. package/dist/overlay/toast-context.d.ts +24 -0
  332. package/dist/overlay/toast-context.d.ts.map +1 -0
  333. package/dist/overlay/toast-context.js +12 -0
  334. package/dist/overlay/toast-context.js.map +1 -0
  335. package/dist/rpc/AcceptPicker.cjs +81 -58
  336. package/dist/rpc/AcceptPicker.cjs.map +1 -1
  337. package/dist/rpc/AcceptPicker.d.ts.map +1 -1
  338. package/dist/rpc/AcceptPicker.js +81 -58
  339. package/dist/rpc/AcceptPicker.js.map +1 -1
  340. package/dist/rpc/CommandForm.cjs +5 -35
  341. package/dist/rpc/CommandForm.cjs.map +1 -1
  342. package/dist/rpc/CommandForm.d.ts +0 -3
  343. package/dist/rpc/CommandForm.d.ts.map +1 -1
  344. package/dist/rpc/CommandForm.js +2 -32
  345. package/dist/rpc/CommandForm.js.map +1 -1
  346. package/dist/rpc/CommandOutput.cjs +2 -1
  347. package/dist/rpc/CommandOutput.cjs.map +1 -1
  348. package/dist/rpc/CommandOutput.d.ts.map +1 -1
  349. package/dist/rpc/CommandOutput.js +2 -1
  350. package/dist/rpc/CommandOutput.js.map +1 -1
  351. package/dist/rpc/EntityExplorerApp.cjs +28 -83
  352. package/dist/rpc/EntityExplorerApp.cjs.map +1 -1
  353. package/dist/rpc/EntityExplorerApp.d.ts +1 -4
  354. package/dist/rpc/EntityExplorerApp.d.ts.map +1 -1
  355. package/dist/rpc/EntityExplorerApp.js +13 -68
  356. package/dist/rpc/EntityExplorerApp.js.map +1 -1
  357. package/dist/rpc/OperationCatalog.cjs +2 -2
  358. package/dist/rpc/OperationCatalog.cjs.map +1 -1
  359. package/dist/rpc/OperationCatalog.d.ts +1 -1
  360. package/dist/rpc/OperationCatalog.d.ts.map +1 -1
  361. package/dist/rpc/OperationCatalog.js +1 -1
  362. package/dist/rpc/OperationCatalog.js.map +1 -1
  363. package/dist/rpc/OperationCommandPage.cjs +6 -4
  364. package/dist/rpc/OperationCommandPage.cjs.map +1 -1
  365. package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
  366. package/dist/rpc/OperationCommandPage.js +3 -1
  367. package/dist/rpc/OperationCommandPage.js.map +1 -1
  368. package/dist/rpc/RouterProvider.cjs +10 -0
  369. package/dist/rpc/RouterProvider.cjs.map +1 -0
  370. package/dist/rpc/RouterProvider.d.ts +10 -0
  371. package/dist/rpc/RouterProvider.d.ts.map +1 -0
  372. package/dist/rpc/RouterProvider.js +10 -0
  373. package/dist/rpc/RouterProvider.js.map +1 -0
  374. package/dist/rpc/apiClient.cjs +4 -4
  375. package/dist/rpc/apiClient.cjs.map +1 -1
  376. package/dist/rpc/apiClient.js +4 -4
  377. package/dist/rpc/apiClient.js.map +1 -1
  378. package/dist/rpc/command-form-utils.cjs +43 -0
  379. package/dist/rpc/command-form-utils.cjs.map +1 -0
  380. package/dist/rpc/command-form-utils.d.ts +5 -0
  381. package/dist/rpc/command-form-utils.d.ts.map +1 -0
  382. package/dist/rpc/command-form-utils.js +43 -0
  383. package/dist/rpc/command-form-utils.js.map +1 -0
  384. package/dist/rpc/commandHref.cjs +62 -0
  385. package/dist/rpc/commandHref.cjs.map +1 -0
  386. package/dist/rpc/commandHref.d.ts +7 -0
  387. package/dist/rpc/commandHref.d.ts.map +1 -0
  388. package/dist/rpc/commandHref.js +62 -0
  389. package/dist/rpc/commandHref.js.map +1 -0
  390. package/dist/rpc/formMetadata.cjs +1 -1
  391. package/dist/rpc/formMetadata.cjs.map +1 -1
  392. package/dist/rpc/formMetadata.js +1 -1
  393. package/dist/rpc/formMetadata.js.map +1 -1
  394. package/dist/rpc/router.cjs +83 -0
  395. package/dist/rpc/router.cjs.map +1 -0
  396. package/dist/rpc/router.d.ts +24 -0
  397. package/dist/rpc/router.d.ts.map +1 -0
  398. package/dist/rpc/router.js +83 -0
  399. package/dist/rpc/router.js.map +1 -0
  400. package/dist/rpc/rpc-story-fixtures/orders.fixture.d.ts +3 -0
  401. package/dist/rpc/rpc-story-fixtures/orders.fixture.d.ts.map +1 -0
  402. package/dist/rpc/rpc-story-fixtures/services.fixture.d.ts +3 -0
  403. package/dist/rpc/rpc-story-fixtures/services.fixture.d.ts.map +1 -0
  404. package/dist/rpc/rpc-story-fixtures/surface-fixture.d.ts +24 -0
  405. package/dist/rpc/rpc-story-fixtures/surface-fixture.d.ts.map +1 -0
  406. package/dist/rpc/rpc-story-fixtures/widgets.fixture.d.ts +3 -0
  407. package/dist/rpc/rpc-story-fixtures/widgets.fixture.d.ts.map +1 -0
  408. package/dist/rpc/rpc-story.fixtures.d.ts +16 -0
  409. package/dist/rpc/rpc-story.fixtures.d.ts.map +1 -0
  410. package/dist/rpc.cjs +17 -0
  411. package/dist/rpc.cjs.map +1 -1
  412. package/dist/rpc.d.ts +5 -0
  413. package/dist/rpc.d.ts.map +1 -1
  414. package/dist/rpc.js +18 -1
  415. package/dist/rpc.js.map +1 -1
  416. package/dist/styles.css +1 -1
  417. package/package.json +11 -1
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const utils = require("../../lib/utils.cjs");
6
+ const DropdownMenu = require("../../overlay/DropdownMenu.cjs");
7
+ const Icon = require("../Icon.cjs");
8
+ const UiAdd = require("../../icons/components/UiAdd.cjs");
9
+ const UiComment = require("../../icons/components/UiComment.cjs");
10
+ const UiTrash = require("../../icons/components/UiTrash.cjs");
11
+ const UiChevronDown = require("../../icons/components/UiChevronDown.cjs");
12
+ function ThreadPicker({
13
+ threadId,
14
+ onSelect,
15
+ onNew,
16
+ api = "/api/chat/threads",
17
+ source,
18
+ query,
19
+ className = ""
20
+ }) {
21
+ const [threads, setThreads] = react.useState([]);
22
+ const [loading, setLoading] = react.useState(false);
23
+ const listUrl = query ? `${api}?${query}` : api;
24
+ const fetchThreads = react.useCallback(async () => {
25
+ setLoading(true);
26
+ try {
27
+ if (source) {
28
+ setThreads(await source.load());
29
+ } else {
30
+ const res = await fetch(listUrl);
31
+ if (res.ok) setThreads(await res.json());
32
+ }
33
+ } catch (err) {
34
+ console.warn("clicky-ui: failed to load threads", err);
35
+ } finally {
36
+ setLoading(false);
37
+ }
38
+ }, [source, listUrl]);
39
+ react.useEffect(() => {
40
+ void fetchThreads();
41
+ }, [fetchThreads]);
42
+ const handleDelete = react.useCallback(
43
+ async (id, e) => {
44
+ var _a;
45
+ e.stopPropagation();
46
+ try {
47
+ if (source) {
48
+ await ((_a = source.remove) == null ? void 0 : _a.call(source, id));
49
+ } else {
50
+ await fetch(`${api}/${id}`, { method: "DELETE" });
51
+ }
52
+ setThreads((prev) => prev.filter((t) => t.id !== id));
53
+ if (id === threadId) onNew();
54
+ } catch (err) {
55
+ console.warn("clicky-ui: failed to delete thread", err);
56
+ }
57
+ },
58
+ [source, api, threadId, onNew]
59
+ );
60
+ const current = threads.find((t) => t.id === threadId);
61
+ const label = (current == null ? void 0 : current.title) || "New Chat";
62
+ return /* @__PURE__ */ jsxRuntime.jsx(
63
+ DropdownMenu.DropdownMenu,
64
+ {
65
+ align: "left",
66
+ className,
67
+ onOpenChange: (open) => {
68
+ if (open) void fetchThreads();
69
+ },
70
+ menuClassName: "min-w-[220px] max-w-[320px] max-h-72 overflow-y-auto",
71
+ trigger: /* @__PURE__ */ jsxRuntime.jsxs(
72
+ "button",
73
+ {
74
+ type: "button",
75
+ className: "flex max-w-[200px] items-center gap-1 truncate rounded px-2 py-1 text-sm font-medium hover:bg-muted",
76
+ children: [
77
+ /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiComment.UiComment, className: "size-3.5 shrink-0" }),
78
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: label }),
79
+ /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiChevronDown.UiChevronDown, className: "size-3 shrink-0 opacity-50" })
80
+ ]
81
+ }
82
+ ),
83
+ children: (closeMenu) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-1", children: [
84
+ /* @__PURE__ */ jsxRuntime.jsxs(
85
+ "button",
86
+ {
87
+ type: "button",
88
+ className: "flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-popover-foreground hover:bg-accent",
89
+ onClick: () => {
90
+ onNew();
91
+ closeMenu();
92
+ },
93
+ children: [
94
+ /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiAdd.UiAdd, className: "size-3" }),
95
+ " New Chat"
96
+ ]
97
+ }
98
+ ),
99
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "my-1 border-t border-border" }),
100
+ loading && threads.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1.5 text-xs text-muted-foreground", children: "Loading…" }),
101
+ threads.length === 0 && !loading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-1.5 text-xs text-muted-foreground", children: "No previous conversations" }),
102
+ threads.map((t) => /* @__PURE__ */ jsxRuntime.jsxs(
103
+ "div",
104
+ {
105
+ role: "button",
106
+ tabIndex: 0,
107
+ className: utils.cn(
108
+ "group/thread flex w-full cursor-pointer items-center gap-2 px-3 py-1.5 text-left text-xs hover:bg-accent",
109
+ t.id === threadId && "font-semibold"
110
+ ),
111
+ onClick: () => {
112
+ onSelect(t.id);
113
+ closeMenu();
114
+ },
115
+ onKeyDown: (e) => {
116
+ if (e.key === "Enter" || e.key === " ") {
117
+ e.preventDefault();
118
+ onSelect(t.id);
119
+ closeMenu();
120
+ }
121
+ },
122
+ children: [
123
+ /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiComment.UiComment, className: "size-3 shrink-0" }),
124
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: t.title || "Untitled" }),
125
+ t.totalCostUsd != null && t.totalCostUsd > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: [
126
+ "$",
127
+ t.totalCostUsd.toFixed(2)
128
+ ] }),
129
+ /* @__PURE__ */ jsxRuntime.jsx(
130
+ "button",
131
+ {
132
+ type: "button",
133
+ "aria-label": "Delete conversation",
134
+ className: "shrink-0 rounded p-0.5 text-muted-foreground opacity-0 hover:text-destructive group-hover/thread:opacity-100",
135
+ onClick: (e) => void handleDelete(t.id, e),
136
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiTrash.UiTrash, className: "size-3" })
137
+ }
138
+ )
139
+ ]
140
+ },
141
+ t.id
142
+ ))
143
+ ] })
144
+ }
145
+ );
146
+ }
147
+ exports.ThreadPicker = ThreadPicker;
148
+ //# sourceMappingURL=ThreadPicker.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThreadPicker.cjs","sources":["../../../src/data/ai/ThreadPicker.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { DropdownMenu } from \"../../overlay/DropdownMenu\";\nimport { Icon } from \"../Icon\";\nimport { UiComment, UiAdd, UiTrash, UiChevronDown } from \"../../icons\";\n\n/** One conversation as returned by the threads endpoint. Only `id` is required;\n * `title`/cost are rendered when present so the picker works against minimal\n * backends (e.g. clicky's in-memory ThreadStore, which has no cost). */\nexport interface ThreadSummary {\n id: string;\n title?: string | null;\n totalCostUsd?: number | null;\n updatedAt?: string;\n}\n\n/** An injectable thread data source, for apps that load conversations through\n * their own client (e.g. react-query) rather than a plain `${api}` fetch — and\n * for backend-free stories/demos. When supplied it replaces the `api` calls. */\nexport interface ThreadSource {\n /** Returns the conversation list (re-invoked whenever the menu opens). */\n load: () => Promise<ThreadSummary[]>;\n /** Deletes a conversation. Omit to hide the delete affordance's effect. */\n remove?: (id: string) => Promise<void>;\n}\n\nexport type ThreadPickerProps = {\n /** Currently selected thread, or null for an unsaved/new conversation. */\n threadId: string | null;\n onSelect: (threadId: string) => void;\n onNew: () => void;\n /** Base endpoint for thread CRUD. GET lists, `${api}/${id}` DELETE removes.\n * Defaults to clicky's \"/api/chat/threads\". Ignored when `source` is set. */\n api?: string;\n /** Inject the thread list/delete directly instead of fetching `api`. */\n source?: ThreadSource;\n /** Optional query string appended to the list request (e.g. a scope id). */\n query?: string;\n className?: string;\n};\n\n/** A dropdown to switch between, create, and delete conversation threads. The\n * list is (re)fetched whenever the menu opens, so newly-persisted threads\n * appear without a manual refresh. */\nexport function ThreadPicker({\n threadId,\n onSelect,\n onNew,\n api = \"/api/chat/threads\",\n source,\n query,\n className = \"\",\n}: ThreadPickerProps) {\n const [threads, setThreads] = useState<ThreadSummary[]>([]);\n const [loading, setLoading] = useState(false);\n\n const listUrl = query ? `${api}?${query}` : api;\n\n const fetchThreads = useCallback(async () => {\n setLoading(true);\n try {\n if (source) {\n setThreads(await source.load());\n } else {\n const res = await fetch(listUrl);\n if (res.ok) setThreads(await res.json());\n }\n } catch (err) {\n console.warn(\"clicky-ui: failed to load threads\", err);\n } finally {\n setLoading(false);\n }\n }, [source, listUrl]);\n\n useEffect(() => {\n void fetchThreads();\n }, [fetchThreads]);\n\n const handleDelete = useCallback(\n async (id: string, e: React.MouseEvent) => {\n e.stopPropagation();\n try {\n if (source) {\n await source.remove?.(id);\n } else {\n await fetch(`${api}/${id}`, { method: \"DELETE\" });\n }\n setThreads((prev) => prev.filter((t) => t.id !== id));\n if (id === threadId) onNew();\n } catch (err) {\n console.warn(\"clicky-ui: failed to delete thread\", err);\n }\n },\n [source, api, threadId, onNew],\n );\n\n const current = threads.find((t) => t.id === threadId);\n const label = current?.title || \"New Chat\";\n\n return (\n <DropdownMenu\n align=\"left\"\n className={className}\n onOpenChange={(open) => {\n if (open) void fetchThreads();\n }}\n menuClassName=\"min-w-[220px] max-w-[320px] max-h-72 overflow-y-auto\"\n trigger={\n <button\n type=\"button\"\n className=\"flex max-w-[200px] items-center gap-1 truncate rounded px-2 py-1 text-sm font-medium hover:bg-muted\"\n >\n <Icon icon={UiComment} className=\"size-3.5 shrink-0\" />\n <span className=\"truncate\">{label}</span>\n <Icon icon={UiChevronDown} className=\"size-3 shrink-0 opacity-50\" />\n </button>\n }\n >\n {(closeMenu) => (\n <div className=\"py-1\">\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-popover-foreground hover:bg-accent\"\n onClick={() => {\n onNew();\n closeMenu();\n }}\n >\n <Icon icon={UiAdd} className=\"size-3\" /> New Chat\n </button>\n <div className=\"my-1 border-t border-border\" />\n {loading && threads.length === 0 && (\n <div className=\"px-3 py-1.5 text-xs text-muted-foreground\">Loading…</div>\n )}\n {threads.length === 0 && !loading && (\n <div className=\"px-3 py-1.5 text-xs text-muted-foreground\">No previous conversations</div>\n )}\n {threads.map((t) => (\n <div\n key={t.id}\n role=\"button\"\n tabIndex={0}\n className={cn(\n \"group/thread flex w-full cursor-pointer items-center gap-2 px-3 py-1.5 text-left text-xs hover:bg-accent\",\n t.id === threadId && \"font-semibold\",\n )}\n onClick={() => {\n onSelect(t.id);\n closeMenu();\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelect(t.id);\n closeMenu();\n }\n }}\n >\n <Icon icon={UiComment} className=\"size-3 shrink-0\" />\n <span className=\"flex-1 truncate\">{t.title || \"Untitled\"}</span>\n {t.totalCostUsd != null && t.totalCostUsd > 0 && (\n <span className=\"shrink-0 text-[10px] text-muted-foreground\">\n ${t.totalCostUsd.toFixed(2)}\n </span>\n )}\n <button\n type=\"button\"\n aria-label=\"Delete conversation\"\n className=\"shrink-0 rounded p-0.5 text-muted-foreground opacity-0 hover:text-destructive group-hover/thread:opacity-100\"\n onClick={(e) => void handleDelete(t.id, e)}\n >\n <Icon icon={UiTrash} className=\"size-3\" />\n </button>\n </div>\n ))}\n </div>\n )}\n </DropdownMenu>\n );\n}\n"],"names":["useState","useCallback","useEffect","jsx","DropdownMenu","jsxs","Icon","UiComment","UiChevronDown","UiAdd","cn","UiTrash"],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /** One conversation as returned by the threads endpoint. Only `id` is required;
2
+ * `title`/cost are rendered when present so the picker works against minimal
3
+ * backends (e.g. clicky's in-memory ThreadStore, which has no cost). */
4
+ export interface ThreadSummary {
5
+ id: string;
6
+ title?: string | null;
7
+ totalCostUsd?: number | null;
8
+ updatedAt?: string;
9
+ }
10
+ /** An injectable thread data source, for apps that load conversations through
11
+ * their own client (e.g. react-query) rather than a plain `${api}` fetch — and
12
+ * for backend-free stories/demos. When supplied it replaces the `api` calls. */
13
+ export interface ThreadSource {
14
+ /** Returns the conversation list (re-invoked whenever the menu opens). */
15
+ load: () => Promise<ThreadSummary[]>;
16
+ /** Deletes a conversation. Omit to hide the delete affordance's effect. */
17
+ remove?: (id: string) => Promise<void>;
18
+ }
19
+ export type ThreadPickerProps = {
20
+ /** Currently selected thread, or null for an unsaved/new conversation. */
21
+ threadId: string | null;
22
+ onSelect: (threadId: string) => void;
23
+ onNew: () => void;
24
+ /** Base endpoint for thread CRUD. GET lists, `${api}/${id}` DELETE removes.
25
+ * Defaults to clicky's "/api/chat/threads". Ignored when `source` is set. */
26
+ api?: string;
27
+ /** Inject the thread list/delete directly instead of fetching `api`. */
28
+ source?: ThreadSource;
29
+ /** Optional query string appended to the list request (e.g. a scope id). */
30
+ query?: string;
31
+ className?: string;
32
+ };
33
+ /** A dropdown to switch between, create, and delete conversation threads. The
34
+ * list is (re)fetched whenever the menu opens, so newly-persisted threads
35
+ * appear without a manual refresh. */
36
+ export declare function ThreadPicker({ threadId, onSelect, onNew, api, source, query, className, }: ThreadPickerProps): import("react/jsx-runtime").JSX.Element;
37
+ //# sourceMappingURL=ThreadPicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThreadPicker.d.ts","sourceRoot":"","sources":["../../../src/data/ai/ThreadPicker.tsx"],"names":[],"mappings":"AAMA;;yEAEyE;AACzE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;iFAEiF;AACjF,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACrC,2EAA2E;IAC3E,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB;kFAC8E;IAC9E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;uCAEuC;AACvC,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,GAAyB,EACzB,MAAM,EACN,KAAK,EACL,SAAc,GACf,EAAE,iBAAiB,2CA+HnB"}
@@ -0,0 +1,148 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useState, useCallback, useEffect } from "react";
3
+ import { cn } from "../../lib/utils.js";
4
+ import { DropdownMenu } from "../../overlay/DropdownMenu.js";
5
+ import { Icon } from "../Icon.js";
6
+ import { UiAdd } from "../../icons/components/UiAdd.js";
7
+ import { UiComment } from "../../icons/components/UiComment.js";
8
+ import { UiTrash } from "../../icons/components/UiTrash.js";
9
+ import { UiChevronDown } from "../../icons/components/UiChevronDown.js";
10
+ function ThreadPicker({
11
+ threadId,
12
+ onSelect,
13
+ onNew,
14
+ api = "/api/chat/threads",
15
+ source,
16
+ query,
17
+ className = ""
18
+ }) {
19
+ const [threads, setThreads] = useState([]);
20
+ const [loading, setLoading] = useState(false);
21
+ const listUrl = query ? `${api}?${query}` : api;
22
+ const fetchThreads = useCallback(async () => {
23
+ setLoading(true);
24
+ try {
25
+ if (source) {
26
+ setThreads(await source.load());
27
+ } else {
28
+ const res = await fetch(listUrl);
29
+ if (res.ok) setThreads(await res.json());
30
+ }
31
+ } catch (err) {
32
+ console.warn("clicky-ui: failed to load threads", err);
33
+ } finally {
34
+ setLoading(false);
35
+ }
36
+ }, [source, listUrl]);
37
+ useEffect(() => {
38
+ void fetchThreads();
39
+ }, [fetchThreads]);
40
+ const handleDelete = useCallback(
41
+ async (id, e) => {
42
+ var _a;
43
+ e.stopPropagation();
44
+ try {
45
+ if (source) {
46
+ await ((_a = source.remove) == null ? void 0 : _a.call(source, id));
47
+ } else {
48
+ await fetch(`${api}/${id}`, { method: "DELETE" });
49
+ }
50
+ setThreads((prev) => prev.filter((t) => t.id !== id));
51
+ if (id === threadId) onNew();
52
+ } catch (err) {
53
+ console.warn("clicky-ui: failed to delete thread", err);
54
+ }
55
+ },
56
+ [source, api, threadId, onNew]
57
+ );
58
+ const current = threads.find((t) => t.id === threadId);
59
+ const label = (current == null ? void 0 : current.title) || "New Chat";
60
+ return /* @__PURE__ */ jsx(
61
+ DropdownMenu,
62
+ {
63
+ align: "left",
64
+ className,
65
+ onOpenChange: (open) => {
66
+ if (open) void fetchThreads();
67
+ },
68
+ menuClassName: "min-w-[220px] max-w-[320px] max-h-72 overflow-y-auto",
69
+ trigger: /* @__PURE__ */ jsxs(
70
+ "button",
71
+ {
72
+ type: "button",
73
+ className: "flex max-w-[200px] items-center gap-1 truncate rounded px-2 py-1 text-sm font-medium hover:bg-muted",
74
+ children: [
75
+ /* @__PURE__ */ jsx(Icon, { icon: UiComment, className: "size-3.5 shrink-0" }),
76
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: label }),
77
+ /* @__PURE__ */ jsx(Icon, { icon: UiChevronDown, className: "size-3 shrink-0 opacity-50" })
78
+ ]
79
+ }
80
+ ),
81
+ children: (closeMenu) => /* @__PURE__ */ jsxs("div", { className: "py-1", children: [
82
+ /* @__PURE__ */ jsxs(
83
+ "button",
84
+ {
85
+ type: "button",
86
+ className: "flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-popover-foreground hover:bg-accent",
87
+ onClick: () => {
88
+ onNew();
89
+ closeMenu();
90
+ },
91
+ children: [
92
+ /* @__PURE__ */ jsx(Icon, { icon: UiAdd, className: "size-3" }),
93
+ " New Chat"
94
+ ]
95
+ }
96
+ ),
97
+ /* @__PURE__ */ jsx("div", { className: "my-1 border-t border-border" }),
98
+ loading && threads.length === 0 && /* @__PURE__ */ jsx("div", { className: "px-3 py-1.5 text-xs text-muted-foreground", children: "Loading…" }),
99
+ threads.length === 0 && !loading && /* @__PURE__ */ jsx("div", { className: "px-3 py-1.5 text-xs text-muted-foreground", children: "No previous conversations" }),
100
+ threads.map((t) => /* @__PURE__ */ jsxs(
101
+ "div",
102
+ {
103
+ role: "button",
104
+ tabIndex: 0,
105
+ className: cn(
106
+ "group/thread flex w-full cursor-pointer items-center gap-2 px-3 py-1.5 text-left text-xs hover:bg-accent",
107
+ t.id === threadId && "font-semibold"
108
+ ),
109
+ onClick: () => {
110
+ onSelect(t.id);
111
+ closeMenu();
112
+ },
113
+ onKeyDown: (e) => {
114
+ if (e.key === "Enter" || e.key === " ") {
115
+ e.preventDefault();
116
+ onSelect(t.id);
117
+ closeMenu();
118
+ }
119
+ },
120
+ children: [
121
+ /* @__PURE__ */ jsx(Icon, { icon: UiComment, className: "size-3 shrink-0" }),
122
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: t.title || "Untitled" }),
123
+ t.totalCostUsd != null && t.totalCostUsd > 0 && /* @__PURE__ */ jsxs("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: [
124
+ "$",
125
+ t.totalCostUsd.toFixed(2)
126
+ ] }),
127
+ /* @__PURE__ */ jsx(
128
+ "button",
129
+ {
130
+ type: "button",
131
+ "aria-label": "Delete conversation",
132
+ className: "shrink-0 rounded p-0.5 text-muted-foreground opacity-0 hover:text-destructive group-hover/thread:opacity-100",
133
+ onClick: (e) => void handleDelete(t.id, e),
134
+ children: /* @__PURE__ */ jsx(Icon, { icon: UiTrash, className: "size-3" })
135
+ }
136
+ )
137
+ ]
138
+ },
139
+ t.id
140
+ ))
141
+ ] })
142
+ }
143
+ );
144
+ }
145
+ export {
146
+ ThreadPicker
147
+ };
148
+ //# sourceMappingURL=ThreadPicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThreadPicker.js","sources":["../../../src/data/ai/ThreadPicker.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { DropdownMenu } from \"../../overlay/DropdownMenu\";\nimport { Icon } from \"../Icon\";\nimport { UiComment, UiAdd, UiTrash, UiChevronDown } from \"../../icons\";\n\n/** One conversation as returned by the threads endpoint. Only `id` is required;\n * `title`/cost are rendered when present so the picker works against minimal\n * backends (e.g. clicky's in-memory ThreadStore, which has no cost). */\nexport interface ThreadSummary {\n id: string;\n title?: string | null;\n totalCostUsd?: number | null;\n updatedAt?: string;\n}\n\n/** An injectable thread data source, for apps that load conversations through\n * their own client (e.g. react-query) rather than a plain `${api}` fetch — and\n * for backend-free stories/demos. When supplied it replaces the `api` calls. */\nexport interface ThreadSource {\n /** Returns the conversation list (re-invoked whenever the menu opens). */\n load: () => Promise<ThreadSummary[]>;\n /** Deletes a conversation. Omit to hide the delete affordance's effect. */\n remove?: (id: string) => Promise<void>;\n}\n\nexport type ThreadPickerProps = {\n /** Currently selected thread, or null for an unsaved/new conversation. */\n threadId: string | null;\n onSelect: (threadId: string) => void;\n onNew: () => void;\n /** Base endpoint for thread CRUD. GET lists, `${api}/${id}` DELETE removes.\n * Defaults to clicky's \"/api/chat/threads\". Ignored when `source` is set. */\n api?: string;\n /** Inject the thread list/delete directly instead of fetching `api`. */\n source?: ThreadSource;\n /** Optional query string appended to the list request (e.g. a scope id). */\n query?: string;\n className?: string;\n};\n\n/** A dropdown to switch between, create, and delete conversation threads. The\n * list is (re)fetched whenever the menu opens, so newly-persisted threads\n * appear without a manual refresh. */\nexport function ThreadPicker({\n threadId,\n onSelect,\n onNew,\n api = \"/api/chat/threads\",\n source,\n query,\n className = \"\",\n}: ThreadPickerProps) {\n const [threads, setThreads] = useState<ThreadSummary[]>([]);\n const [loading, setLoading] = useState(false);\n\n const listUrl = query ? `${api}?${query}` : api;\n\n const fetchThreads = useCallback(async () => {\n setLoading(true);\n try {\n if (source) {\n setThreads(await source.load());\n } else {\n const res = await fetch(listUrl);\n if (res.ok) setThreads(await res.json());\n }\n } catch (err) {\n console.warn(\"clicky-ui: failed to load threads\", err);\n } finally {\n setLoading(false);\n }\n }, [source, listUrl]);\n\n useEffect(() => {\n void fetchThreads();\n }, [fetchThreads]);\n\n const handleDelete = useCallback(\n async (id: string, e: React.MouseEvent) => {\n e.stopPropagation();\n try {\n if (source) {\n await source.remove?.(id);\n } else {\n await fetch(`${api}/${id}`, { method: \"DELETE\" });\n }\n setThreads((prev) => prev.filter((t) => t.id !== id));\n if (id === threadId) onNew();\n } catch (err) {\n console.warn(\"clicky-ui: failed to delete thread\", err);\n }\n },\n [source, api, threadId, onNew],\n );\n\n const current = threads.find((t) => t.id === threadId);\n const label = current?.title || \"New Chat\";\n\n return (\n <DropdownMenu\n align=\"left\"\n className={className}\n onOpenChange={(open) => {\n if (open) void fetchThreads();\n }}\n menuClassName=\"min-w-[220px] max-w-[320px] max-h-72 overflow-y-auto\"\n trigger={\n <button\n type=\"button\"\n className=\"flex max-w-[200px] items-center gap-1 truncate rounded px-2 py-1 text-sm font-medium hover:bg-muted\"\n >\n <Icon icon={UiComment} className=\"size-3.5 shrink-0\" />\n <span className=\"truncate\">{label}</span>\n <Icon icon={UiChevronDown} className=\"size-3 shrink-0 opacity-50\" />\n </button>\n }\n >\n {(closeMenu) => (\n <div className=\"py-1\">\n <button\n type=\"button\"\n className=\"flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs text-popover-foreground hover:bg-accent\"\n onClick={() => {\n onNew();\n closeMenu();\n }}\n >\n <Icon icon={UiAdd} className=\"size-3\" /> New Chat\n </button>\n <div className=\"my-1 border-t border-border\" />\n {loading && threads.length === 0 && (\n <div className=\"px-3 py-1.5 text-xs text-muted-foreground\">Loading…</div>\n )}\n {threads.length === 0 && !loading && (\n <div className=\"px-3 py-1.5 text-xs text-muted-foreground\">No previous conversations</div>\n )}\n {threads.map((t) => (\n <div\n key={t.id}\n role=\"button\"\n tabIndex={0}\n className={cn(\n \"group/thread flex w-full cursor-pointer items-center gap-2 px-3 py-1.5 text-left text-xs hover:bg-accent\",\n t.id === threadId && \"font-semibold\",\n )}\n onClick={() => {\n onSelect(t.id);\n closeMenu();\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelect(t.id);\n closeMenu();\n }\n }}\n >\n <Icon icon={UiComment} className=\"size-3 shrink-0\" />\n <span className=\"flex-1 truncate\">{t.title || \"Untitled\"}</span>\n {t.totalCostUsd != null && t.totalCostUsd > 0 && (\n <span className=\"shrink-0 text-[10px] text-muted-foreground\">\n ${t.totalCostUsd.toFixed(2)}\n </span>\n )}\n <button\n type=\"button\"\n aria-label=\"Delete conversation\"\n className=\"shrink-0 rounded p-0.5 text-muted-foreground opacity-0 hover:text-destructive group-hover/thread:opacity-100\"\n onClick={(e) => void handleDelete(t.id, e)}\n >\n <Icon icon={UiTrash} className=\"size-3\" />\n </button>\n </div>\n ))}\n </div>\n )}\n </DropdownMenu>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const utils = require("../../lib/utils.cjs");
6
+ const DropdownMenu = require("../../overlay/DropdownMenu.cjs");
7
+ const button = require("../../components/button.cjs");
8
+ const Icon = require("../Icon.cjs");
9
+ const UiSliders = require("../../icons/components/UiSliders.cjs");
10
+ const MODE_CYCLE = ["enabled", "ask", "disabled"];
11
+ const MODE_LABEL = { enabled: "Auto", ask: "Ask", disabled: "Off" };
12
+ function ToolRow({
13
+ meta,
14
+ mode,
15
+ onToggle
16
+ }) {
17
+ return /* @__PURE__ */ jsxRuntime.jsxs(
18
+ "button",
19
+ {
20
+ type: "button",
21
+ className: "flex w-full items-center justify-between rounded px-2 py-1 text-left hover:bg-accent",
22
+ onClick: () => onToggle(meta.name),
23
+ children: [
24
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: utils.cn("text-xs", mode === "disabled" && "text-muted-foreground line-through"), children: meta.label }),
25
+ /* @__PURE__ */ jsxRuntime.jsx(
26
+ "span",
27
+ {
28
+ className: utils.cn(
29
+ "rounded px-1.5 py-0.5 text-[10px] font-medium",
30
+ mode === "enabled" && "bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300",
31
+ mode === "ask" && "bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300",
32
+ mode === "disabled" && "bg-muted text-muted-foreground"
33
+ ),
34
+ children: MODE_LABEL[mode]
35
+ }
36
+ )
37
+ ]
38
+ }
39
+ );
40
+ }
41
+ function ToolPreferences({ tools, value, onChange, className = "" }) {
42
+ const groups = react.useMemo(() => {
43
+ var _a;
44
+ const g = {};
45
+ for (const meta of tools) (g[_a = meta.group ?? "Tools"] ?? (g[_a] = [])).push(meta);
46
+ return g;
47
+ }, [tools]);
48
+ const handleToggle = (name) => {
49
+ const current = value[name] ?? "enabled";
50
+ const next = MODE_CYCLE[(MODE_CYCLE.indexOf(current) + 1) % MODE_CYCLE.length];
51
+ onChange({ ...value, [name]: next });
52
+ };
53
+ return /* @__PURE__ */ jsxRuntime.jsx(
54
+ DropdownMenu.DropdownMenu,
55
+ {
56
+ align: "right",
57
+ className,
58
+ menuClassName: "w-64 max-h-[400px] overflow-y-auto p-3",
59
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(button.Button, { variant: "ghost", size: "icon", title: "Tool preferences", "data-testid": "tool-preferences-btn", children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiSliders.UiSliders, className: "size-4" }) }),
60
+ children: () => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
61
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 text-xs font-semibold", children: "Tool Preferences" }),
62
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 text-[10px] text-muted-foreground", children: "Click to cycle: Auto → Ask → Off" }),
63
+ Object.entries(groups).map(([group, metas]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-2", children: [
64
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-0.5 px-2 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: group }),
65
+ metas.map((meta) => /* @__PURE__ */ jsxRuntime.jsx(
66
+ ToolRow,
67
+ {
68
+ meta,
69
+ mode: value[meta.name] ?? "enabled",
70
+ onToggle: handleToggle
71
+ },
72
+ meta.name
73
+ ))
74
+ ] }, group))
75
+ ] })
76
+ }
77
+ );
78
+ }
79
+ exports.ToolPreferences = ToolPreferences;
80
+ //# sourceMappingURL=ToolPreferences.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolPreferences.cjs","sources":["../../../src/data/ai/ToolPreferences.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { DropdownMenu } from \"../../overlay/DropdownMenu\";\nimport { Button } from \"../../components/button\";\nimport { Icon } from \"../Icon\";\nimport { UiSliders } from \"../../icons\";\nimport type { ToolMeta } from \"../chat/types\";\n\nexport type { ToolMeta };\n\n/** How a tool may be invoked: run automatically, pause for approval, or be\n * hidden from the model entirely. */\nexport type ToolMode = \"enabled\" | \"ask\" | \"disabled\";\n\nconst MODE_CYCLE: ToolMode[] = [\"enabled\", \"ask\", \"disabled\"];\nconst MODE_LABEL: Record<ToolMode, string> = { enabled: \"Auto\", ask: \"Ask\", disabled: \"Off\" };\n\nexport type ToolPreferencesProps = {\n /** The tools to list. Replaces ai-financials' global registry — callers pass\n * whatever their backend exposes. */\n tools: ToolMeta[];\n /** Current per-tool mode. Missing entries default to \"enabled\". */\n value: Record<string, ToolMode>;\n onChange: (prefs: Record<string, ToolMode>) => void;\n className?: string;\n};\n\nfunction ToolRow({\n meta,\n mode,\n onToggle,\n}: {\n meta: ToolMeta;\n mode: ToolMode;\n onToggle: (name: string) => void;\n}) {\n return (\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between rounded px-2 py-1 text-left hover:bg-accent\"\n onClick={() => onToggle(meta.name)}\n >\n <span className={cn(\"text-xs\", mode === \"disabled\" && \"text-muted-foreground line-through\")}>\n {meta.label}\n </span>\n <span\n className={cn(\n \"rounded px-1.5 py-0.5 text-[10px] font-medium\",\n mode === \"enabled\" &&\n \"bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300\",\n mode === \"ask\" && \"bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300\",\n mode === \"disabled\" && \"bg-muted text-muted-foreground\",\n )}\n >\n {MODE_LABEL[mode]}\n </span>\n </button>\n );\n}\n\n/** A popover that cycles each tool through Auto → Ask → Off. The resulting\n * `Record<name, ToolMode>` is meant to be forwarded to the backend (e.g. via\n * `<Chat body={{ toolPreferences }}>`). */\nexport function ToolPreferences({ tools, value, onChange, className = \"\" }: ToolPreferencesProps) {\n const groups = useMemo(() => {\n const g: Record<string, ToolMeta[]> = {};\n for (const meta of tools) (g[meta.group ?? \"Tools\"] ??= []).push(meta);\n return g;\n }, [tools]);\n\n const handleToggle = (name: string) => {\n const current = value[name] ?? \"enabled\";\n const next = MODE_CYCLE[(MODE_CYCLE.indexOf(current) + 1) % MODE_CYCLE.length]!;\n onChange({ ...value, [name]: next });\n };\n\n return (\n <DropdownMenu\n align=\"right\"\n className={className}\n menuClassName=\"w-64 max-h-[400px] overflow-y-auto p-3\"\n trigger={\n <Button variant=\"ghost\" size=\"icon\" title=\"Tool preferences\" data-testid=\"tool-preferences-btn\">\n <Icon icon={UiSliders} className=\"size-4\" />\n </Button>\n }\n >\n {() => (\n <div>\n <div className=\"mb-2 text-xs font-semibold\">Tool Preferences</div>\n <p className=\"mb-2 text-[10px] text-muted-foreground\">Click to cycle: Auto → Ask → Off</p>\n {Object.entries(groups).map(([group, metas]) => (\n <div key={group} className=\"mb-2\">\n <div className=\"mb-0.5 px-2 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground\">\n {group}\n </div>\n {metas.map((meta) => (\n <ToolRow\n key={meta.name}\n meta={meta}\n mode={value[meta.name] ?? \"enabled\"}\n onToggle={handleToggle}\n />\n ))}\n </div>\n ))}\n </div>\n )}\n </DropdownMenu>\n );\n}\n"],"names":["jsxs","jsx","cn","useMemo","DropdownMenu","Button","Icon","UiSliders"],"mappings":";;;;;;;;;AAcA,MAAM,aAAyB,CAAC,WAAW,OAAO,UAAU;AAC5D,MAAM,aAAuC,EAAE,SAAS,QAAQ,KAAK,OAAO,UAAU,MAAA;AAYtF,SAAS,QAAQ;AAAA,EACf;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SACEA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MACV,SAAS,MAAM,SAAS,KAAK,IAAI;AAAA,MAEjC,UAAA;AAAA,QAAAC,2BAAAA,IAAC,QAAA,EAAK,WAAWC,MAAAA,GAAG,WAAW,SAAS,cAAc,oCAAoC,GACvF,UAAA,KAAK,MAAA,CACR;AAAA,QACAD,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWC,MAAAA;AAAAA,cACT;AAAA,cACA,SAAS,aACP;AAAA,cACF,SAAS,SAAS;AAAA,cAClB,SAAS,cAAc;AAAA,YAAA;AAAA,YAGxB,qBAAW,IAAI;AAAA,UAAA;AAAA,QAAA;AAAA,MAClB;AAAA,IAAA;AAAA,EAAA;AAGN;AAKO,SAAS,gBAAgB,EAAE,OAAO,OAAO,UAAU,YAAY,MAA4B;AAChG,QAAM,SAASC,MAAAA,QAAQ,MAAM;;AAC3B,UAAM,IAAgC,CAAA;AACtC,eAAW,QAAQ,MAAO,EAAC,OAAE,KAAK,SAAS,aAAhB,QAA6B,KAAI,KAAK,IAAI;AACrE,WAAO;AAAA,EACT,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,eAAe,CAAC,SAAiB;AACrC,UAAM,UAAU,MAAM,IAAI,KAAK;AAC/B,UAAM,OAAO,YAAY,WAAW,QAAQ,OAAO,IAAI,KAAK,WAAW,MAAM;AAC7E,aAAS,EAAE,GAAG,OAAO,CAAC,IAAI,GAAG,MAAM;AAAA,EACrC;AAEA,SACEF,2BAAAA;AAAAA,IAACG,aAAAA;AAAAA,IAAA;AAAA,MACC,OAAM;AAAA,MACN;AAAA,MACA,eAAc;AAAA,MACd,SACEH,2BAAAA,IAACI,OAAAA,QAAA,EAAO,SAAQ,SAAQ,MAAK,QAAO,OAAM,oBAAmB,eAAY,wBACvE,UAAAJ,+BAACK,KAAAA,MAAA,EAAK,MAAMC,UAAAA,WAAW,WAAU,UAAS,GAC5C;AAAA,MAGD,UAAA,sCACE,OAAA,EACC,UAAA;AAAA,QAAAN,2BAAAA,IAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,oBAAgB;AAAA,QAC5DA,2BAAAA,IAAC,KAAA,EAAE,WAAU,0CAAyC,UAAA,oCAAgC;AAAA,QACrF,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,OAAO,KAAK,MACxCD,2BAAAA,KAAC,OAAA,EAAgB,WAAU,QACzB,UAAA;AAAA,UAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,wFACZ,UAAA,OACH;AAAA,UACC,MAAM,IAAI,CAAC,SACVA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cAEC;AAAA,cACA,MAAM,MAAM,KAAK,IAAI,KAAK;AAAA,cAC1B,UAAU;AAAA,YAAA;AAAA,YAHL,KAAK;AAAA,UAAA,CAKb;AAAA,QAAA,EAAA,GAXO,KAYV,CACD;AAAA,MAAA,EAAA,CACH;AAAA,IAAA;AAAA,EAAA;AAIR;;"}
@@ -0,0 +1,19 @@
1
+ import { ToolMeta } from '../chat/types';
2
+ export type { ToolMeta };
3
+ /** How a tool may be invoked: run automatically, pause for approval, or be
4
+ * hidden from the model entirely. */
5
+ export type ToolMode = "enabled" | "ask" | "disabled";
6
+ export type ToolPreferencesProps = {
7
+ /** The tools to list. Replaces ai-financials' global registry — callers pass
8
+ * whatever their backend exposes. */
9
+ tools: ToolMeta[];
10
+ /** Current per-tool mode. Missing entries default to "enabled". */
11
+ value: Record<string, ToolMode>;
12
+ onChange: (prefs: Record<string, ToolMode>) => void;
13
+ className?: string;
14
+ };
15
+ /** A popover that cycles each tool through Auto → Ask → Off. The resulting
16
+ * `Record<name, ToolMode>` is meant to be forwarded to the backend (e.g. via
17
+ * `<Chat body={{ toolPreferences }}>`). */
18
+ export declare function ToolPreferences({ tools, value, onChange, className }: ToolPreferencesProps): import("react/jsx-runtime").JSX.Element;
19
+ //# sourceMappingURL=ToolPreferences.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolPreferences.d.ts","sourceRoot":"","sources":["../../../src/data/ai/ToolPreferences.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,YAAY,EAAE,QAAQ,EAAE,CAAC;AAEzB;sCACsC;AACtC,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,UAAU,CAAC;AAKtD,MAAM,MAAM,oBAAoB,GAAG;IACjC;0CACsC;IACtC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,IAAI,CAAC;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAmCF;;4CAE4C;AAC5C,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAc,EAAE,EAAE,oBAAoB,2CA+C/F"}
@@ -0,0 +1,80 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { cn } from "../../lib/utils.js";
4
+ import { DropdownMenu } from "../../overlay/DropdownMenu.js";
5
+ import { Button } from "../../components/button.js";
6
+ import { Icon } from "../Icon.js";
7
+ import { UiSliders } from "../../icons/components/UiSliders.js";
8
+ const MODE_CYCLE = ["enabled", "ask", "disabled"];
9
+ const MODE_LABEL = { enabled: "Auto", ask: "Ask", disabled: "Off" };
10
+ function ToolRow({
11
+ meta,
12
+ mode,
13
+ onToggle
14
+ }) {
15
+ return /* @__PURE__ */ jsxs(
16
+ "button",
17
+ {
18
+ type: "button",
19
+ className: "flex w-full items-center justify-between rounded px-2 py-1 text-left hover:bg-accent",
20
+ onClick: () => onToggle(meta.name),
21
+ children: [
22
+ /* @__PURE__ */ jsx("span", { className: cn("text-xs", mode === "disabled" && "text-muted-foreground line-through"), children: meta.label }),
23
+ /* @__PURE__ */ jsx(
24
+ "span",
25
+ {
26
+ className: cn(
27
+ "rounded px-1.5 py-0.5 text-[10px] font-medium",
28
+ mode === "enabled" && "bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300",
29
+ mode === "ask" && "bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300",
30
+ mode === "disabled" && "bg-muted text-muted-foreground"
31
+ ),
32
+ children: MODE_LABEL[mode]
33
+ }
34
+ )
35
+ ]
36
+ }
37
+ );
38
+ }
39
+ function ToolPreferences({ tools, value, onChange, className = "" }) {
40
+ const groups = useMemo(() => {
41
+ var _a;
42
+ const g = {};
43
+ for (const meta of tools) (g[_a = meta.group ?? "Tools"] ?? (g[_a] = [])).push(meta);
44
+ return g;
45
+ }, [tools]);
46
+ const handleToggle = (name) => {
47
+ const current = value[name] ?? "enabled";
48
+ const next = MODE_CYCLE[(MODE_CYCLE.indexOf(current) + 1) % MODE_CYCLE.length];
49
+ onChange({ ...value, [name]: next });
50
+ };
51
+ return /* @__PURE__ */ jsx(
52
+ DropdownMenu,
53
+ {
54
+ align: "right",
55
+ className,
56
+ menuClassName: "w-64 max-h-[400px] overflow-y-auto p-3",
57
+ trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", title: "Tool preferences", "data-testid": "tool-preferences-btn", children: /* @__PURE__ */ jsx(Icon, { icon: UiSliders, className: "size-4" }) }),
58
+ children: () => /* @__PURE__ */ jsxs("div", { children: [
59
+ /* @__PURE__ */ jsx("div", { className: "mb-2 text-xs font-semibold", children: "Tool Preferences" }),
60
+ /* @__PURE__ */ jsx("p", { className: "mb-2 text-[10px] text-muted-foreground", children: "Click to cycle: Auto → Ask → Off" }),
61
+ Object.entries(groups).map(([group, metas]) => /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
62
+ /* @__PURE__ */ jsx("div", { className: "mb-0.5 px-2 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: group }),
63
+ metas.map((meta) => /* @__PURE__ */ jsx(
64
+ ToolRow,
65
+ {
66
+ meta,
67
+ mode: value[meta.name] ?? "enabled",
68
+ onToggle: handleToggle
69
+ },
70
+ meta.name
71
+ ))
72
+ ] }, group))
73
+ ] })
74
+ }
75
+ );
76
+ }
77
+ export {
78
+ ToolPreferences
79
+ };
80
+ //# sourceMappingURL=ToolPreferences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolPreferences.js","sources":["../../../src/data/ai/ToolPreferences.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { DropdownMenu } from \"../../overlay/DropdownMenu\";\nimport { Button } from \"../../components/button\";\nimport { Icon } from \"../Icon\";\nimport { UiSliders } from \"../../icons\";\nimport type { ToolMeta } from \"../chat/types\";\n\nexport type { ToolMeta };\n\n/** How a tool may be invoked: run automatically, pause for approval, or be\n * hidden from the model entirely. */\nexport type ToolMode = \"enabled\" | \"ask\" | \"disabled\";\n\nconst MODE_CYCLE: ToolMode[] = [\"enabled\", \"ask\", \"disabled\"];\nconst MODE_LABEL: Record<ToolMode, string> = { enabled: \"Auto\", ask: \"Ask\", disabled: \"Off\" };\n\nexport type ToolPreferencesProps = {\n /** The tools to list. Replaces ai-financials' global registry — callers pass\n * whatever their backend exposes. */\n tools: ToolMeta[];\n /** Current per-tool mode. Missing entries default to \"enabled\". */\n value: Record<string, ToolMode>;\n onChange: (prefs: Record<string, ToolMode>) => void;\n className?: string;\n};\n\nfunction ToolRow({\n meta,\n mode,\n onToggle,\n}: {\n meta: ToolMeta;\n mode: ToolMode;\n onToggle: (name: string) => void;\n}) {\n return (\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between rounded px-2 py-1 text-left hover:bg-accent\"\n onClick={() => onToggle(meta.name)}\n >\n <span className={cn(\"text-xs\", mode === \"disabled\" && \"text-muted-foreground line-through\")}>\n {meta.label}\n </span>\n <span\n className={cn(\n \"rounded px-1.5 py-0.5 text-[10px] font-medium\",\n mode === \"enabled\" &&\n \"bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300\",\n mode === \"ask\" && \"bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300\",\n mode === \"disabled\" && \"bg-muted text-muted-foreground\",\n )}\n >\n {MODE_LABEL[mode]}\n </span>\n </button>\n );\n}\n\n/** A popover that cycles each tool through Auto → Ask → Off. The resulting\n * `Record<name, ToolMode>` is meant to be forwarded to the backend (e.g. via\n * `<Chat body={{ toolPreferences }}>`). */\nexport function ToolPreferences({ tools, value, onChange, className = \"\" }: ToolPreferencesProps) {\n const groups = useMemo(() => {\n const g: Record<string, ToolMeta[]> = {};\n for (const meta of tools) (g[meta.group ?? \"Tools\"] ??= []).push(meta);\n return g;\n }, [tools]);\n\n const handleToggle = (name: string) => {\n const current = value[name] ?? \"enabled\";\n const next = MODE_CYCLE[(MODE_CYCLE.indexOf(current) + 1) % MODE_CYCLE.length]!;\n onChange({ ...value, [name]: next });\n };\n\n return (\n <DropdownMenu\n align=\"right\"\n className={className}\n menuClassName=\"w-64 max-h-[400px] overflow-y-auto p-3\"\n trigger={\n <Button variant=\"ghost\" size=\"icon\" title=\"Tool preferences\" data-testid=\"tool-preferences-btn\">\n <Icon icon={UiSliders} className=\"size-4\" />\n </Button>\n }\n >\n {() => (\n <div>\n <div className=\"mb-2 text-xs font-semibold\">Tool Preferences</div>\n <p className=\"mb-2 text-[10px] text-muted-foreground\">Click to cycle: Auto → Ask → Off</p>\n {Object.entries(groups).map(([group, metas]) => (\n <div key={group} className=\"mb-2\">\n <div className=\"mb-0.5 px-2 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground\">\n {group}\n </div>\n {metas.map((meta) => (\n <ToolRow\n key={meta.name}\n meta={meta}\n mode={value[meta.name] ?? \"enabled\"}\n onToggle={handleToggle}\n />\n ))}\n </div>\n ))}\n </div>\n )}\n </DropdownMenu>\n );\n}\n"],"names":[],"mappings":";;;;;;;AAcA,MAAM,aAAyB,CAAC,WAAW,OAAO,UAAU;AAC5D,MAAM,aAAuC,EAAE,SAAS,QAAQ,KAAK,OAAO,UAAU,MAAA;AAYtF,SAAS,QAAQ;AAAA,EACf;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAU;AAAA,MACV,SAAS,MAAM,SAAS,KAAK,IAAI;AAAA,MAEjC,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,WAAW,GAAG,WAAW,SAAS,cAAc,oCAAoC,GACvF,UAAA,KAAK,MAAA,CACR;AAAA,QACA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAW;AAAA,cACT;AAAA,cACA,SAAS,aACP;AAAA,cACF,SAAS,SAAS;AAAA,cAClB,SAAS,cAAc;AAAA,YAAA;AAAA,YAGxB,qBAAW,IAAI;AAAA,UAAA;AAAA,QAAA;AAAA,MAClB;AAAA,IAAA;AAAA,EAAA;AAGN;AAKO,SAAS,gBAAgB,EAAE,OAAO,OAAO,UAAU,YAAY,MAA4B;AAChG,QAAM,SAAS,QAAQ,MAAM;;AAC3B,UAAM,IAAgC,CAAA;AACtC,eAAW,QAAQ,MAAO,EAAC,OAAE,KAAK,SAAS,aAAhB,QAA6B,KAAI,KAAK,IAAI;AACrE,WAAO;AAAA,EACT,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,eAAe,CAAC,SAAiB;AACrC,UAAM,UAAU,MAAM,IAAI,KAAK;AAC/B,UAAM,OAAO,YAAY,WAAW,QAAQ,OAAO,IAAI,KAAK,WAAW,MAAM;AAC7E,aAAS,EAAE,GAAG,OAAO,CAAC,IAAI,GAAG,MAAM;AAAA,EACrC;AAEA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAM;AAAA,MACN;AAAA,MACA,eAAc;AAAA,MACd,SACE,oBAAC,QAAA,EAAO,SAAQ,SAAQ,MAAK,QAAO,OAAM,oBAAmB,eAAY,wBACvE,UAAA,oBAAC,MAAA,EAAK,MAAM,WAAW,WAAU,UAAS,GAC5C;AAAA,MAGD,UAAA,2BACE,OAAA,EACC,UAAA;AAAA,QAAA,oBAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,oBAAgB;AAAA,QAC5D,oBAAC,KAAA,EAAE,WAAU,0CAAyC,UAAA,oCAAgC;AAAA,QACrF,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,OAAO,KAAK,MACxC,qBAAC,OAAA,EAAgB,WAAU,QACzB,UAAA;AAAA,UAAA,oBAAC,OAAA,EAAI,WAAU,wFACZ,UAAA,OACH;AAAA,UACC,MAAM,IAAI,CAAC,SACV;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC;AAAA,cACA,MAAM,MAAM,KAAK,IAAI,KAAK;AAAA,cAC1B,UAAU;AAAA,YAAA;AAAA,YAHL,KAAK;AAAA,UAAA,CAKb;AAAA,QAAA,EAAA,GAXO,KAYV,CACD;AAAA,MAAA,EAAA,CACH;AAAA,IAAA;AAAA,EAAA;AAIR;"}