@flanksource/clicky-ui 0.3.5 → 0.3.7

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 (277) hide show
  1. package/README.md +42 -0
  2. package/dist/ai.cjs +15 -0
  3. package/dist/ai.cjs.map +1 -1
  4. package/dist/ai.js +15 -0
  5. package/dist/ai.js.map +1 -1
  6. package/dist/components/DateField.d.ts +1 -1
  7. package/dist/components/DatePicker.d.ts +1 -1
  8. package/dist/components/DateTimePicker.d.ts +1 -1
  9. package/dist/components/FormLookupProvider.cjs +12 -0
  10. package/dist/components/FormLookupProvider.cjs.map +1 -0
  11. package/dist/components/FormLookupProvider.d.ts +7 -0
  12. package/dist/components/FormLookupProvider.d.ts.map +1 -0
  13. package/dist/components/FormLookupProvider.js +12 -0
  14. package/dist/components/FormLookupProvider.js.map +1 -0
  15. package/dist/components/JsonSchemaForm.cjs +2 -2
  16. package/dist/components/JsonSchemaForm.cjs.map +1 -1
  17. package/dist/components/JsonSchemaForm.js +1 -1
  18. package/dist/components/JsonSchemaForm.js.map +1 -1
  19. package/dist/components/ListMenu.cjs +145 -0
  20. package/dist/components/ListMenu.cjs.map +1 -0
  21. package/dist/components/ListMenu.d.ts +54 -0
  22. package/dist/components/ListMenu.d.ts.map +1 -0
  23. package/dist/components/ListMenu.js +145 -0
  24. package/dist/components/ListMenu.js.map +1 -0
  25. package/dist/components/MdxEditorField.cjs +128 -0
  26. package/dist/components/MdxEditorField.cjs.map +1 -0
  27. package/dist/components/MdxEditorField.d.ts +4 -0
  28. package/dist/components/MdxEditorField.d.ts.map +1 -0
  29. package/dist/components/MdxEditorField.js +106 -0
  30. package/dist/components/MdxEditorField.js.map +1 -0
  31. package/dist/components/MdxEditorToolbar.cjs +76 -0
  32. package/dist/components/MdxEditorToolbar.cjs.map +1 -0
  33. package/dist/components/MdxEditorToolbar.d.ts +8 -0
  34. package/dist/components/MdxEditorToolbar.d.ts.map +1 -0
  35. package/dist/components/MdxEditorToolbar.js +76 -0
  36. package/dist/components/MdxEditorToolbar.js.map +1 -0
  37. package/dist/components/button-variants.d.ts +1 -1
  38. package/dist/components/button.d.ts +1 -1
  39. package/dist/components/form-lookup-context.cjs +1 -8
  40. package/dist/components/form-lookup-context.cjs.map +1 -1
  41. package/dist/components/form-lookup-context.d.ts +1 -5
  42. package/dist/components/form-lookup-context.d.ts.map +1 -1
  43. package/dist/components/form-lookup-context.js +1 -8
  44. package/dist/components/form-lookup-context.js.map +1 -1
  45. package/dist/components/jotai-bindings-core.cjs +197 -0
  46. package/dist/components/jotai-bindings-core.cjs.map +1 -0
  47. package/dist/components/jotai-bindings-core.d.ts +45 -0
  48. package/dist/components/jotai-bindings-core.d.ts.map +1 -0
  49. package/dist/components/jotai-bindings-core.js +197 -0
  50. package/dist/components/jotai-bindings-core.js.map +1 -0
  51. package/dist/components/jotai-bindings.cjs +17 -0
  52. package/dist/components/jotai-bindings.cjs.map +1 -0
  53. package/dist/components/jotai-bindings.d.ts +4 -0
  54. package/dist/components/jotai-bindings.d.ts.map +1 -0
  55. package/dist/components/jotai-bindings.js +17 -0
  56. package/dist/components/jotai-bindings.js.map +1 -0
  57. package/dist/components/json-schema-form-fields.cjs +37 -0
  58. package/dist/components/json-schema-form-fields.cjs.map +1 -1
  59. package/dist/components/json-schema-form-fields.d.ts +6 -0
  60. package/dist/components/json-schema-form-fields.d.ts.map +1 -1
  61. package/dist/components/json-schema-form-fields.js +38 -1
  62. package/dist/components/json-schema-form-fields.js.map +1 -1
  63. package/dist/components/json-schema-form-render.cjs +3 -1
  64. package/dist/components/json-schema-form-render.cjs.map +1 -1
  65. package/dist/components/json-schema-form-render.d.ts.map +1 -1
  66. package/dist/components/json-schema-form-render.js +4 -2
  67. package/dist/components/json-schema-form-render.js.map +1 -1
  68. package/dist/components/json-schema-form-resolve.cjs +9 -0
  69. package/dist/components/json-schema-form-resolve.cjs.map +1 -1
  70. package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
  71. package/dist/components/json-schema-form-resolve.js +9 -0
  72. package/dist/components/json-schema-form-resolve.js.map +1 -1
  73. package/dist/components/json-schema-form-types.d.ts +4 -1
  74. package/dist/components/json-schema-form-types.d.ts.map +1 -1
  75. package/dist/components/mdx-editor-field-plugins.cjs +124 -0
  76. package/dist/components/mdx-editor-field-plugins.cjs.map +1 -0
  77. package/dist/components/mdx-editor-field-plugins.d.ts +6 -0
  78. package/dist/components/mdx-editor-field-plugins.d.ts.map +1 -0
  79. package/dist/components/mdx-editor-field-plugins.js +124 -0
  80. package/dist/components/mdx-editor-field-plugins.js.map +1 -0
  81. package/dist/components/mdx-editor-options.d.ts +77 -0
  82. package/dist/components/mdx-editor-options.d.ts.map +1 -0
  83. package/dist/components/use-list-menu-selection.cjs +77 -0
  84. package/dist/components/use-list-menu-selection.cjs.map +1 -0
  85. package/dist/components/use-list-menu-selection.d.ts +40 -0
  86. package/dist/components/use-list-menu-selection.d.ts.map +1 -0
  87. package/dist/components/use-list-menu-selection.js +77 -0
  88. package/dist/components/use-list-menu-selection.js.map +1 -0
  89. package/dist/components.cjs +10 -1
  90. package/dist/components.cjs.map +1 -1
  91. package/dist/components.d.ts +4 -1
  92. package/dist/components.d.ts.map +1 -1
  93. package/dist/components.js +10 -1
  94. package/dist/components.js.map +1 -1
  95. package/dist/data/MarkdownEditor.model.d.ts +1 -1
  96. package/dist/data/ProgressBars.cjs +194 -0
  97. package/dist/data/ProgressBars.cjs.map +1 -0
  98. package/dist/data/ProgressBars.d.ts +85 -0
  99. package/dist/data/ProgressBars.d.ts.map +1 -0
  100. package/dist/data/ProgressBars.js +194 -0
  101. package/dist/data/ProgressBars.js.map +1 -0
  102. package/dist/data/ProgressBars.model.cjs +27 -0
  103. package/dist/data/ProgressBars.model.cjs.map +1 -0
  104. package/dist/data/ProgressBars.model.d.ts +20 -0
  105. package/dist/data/ProgressBars.model.d.ts.map +1 -0
  106. package/dist/data/ProgressBars.model.js +27 -0
  107. package/dist/data/ProgressBars.model.js.map +1 -0
  108. package/dist/data/PromptBanner.cjs +199 -0
  109. package/dist/data/PromptBanner.cjs.map +1 -0
  110. package/dist/data/PromptBanner.d.ts +17 -0
  111. package/dist/data/PromptBanner.d.ts.map +1 -0
  112. package/dist/data/PromptBanner.js +199 -0
  113. package/dist/data/PromptBanner.js.map +1 -0
  114. package/dist/data/PromptBanner.model.cjs +132 -0
  115. package/dist/data/PromptBanner.model.cjs.map +1 -0
  116. package/dist/data/PromptBanner.model.d.ts +23 -0
  117. package/dist/data/PromptBanner.model.d.ts.map +1 -0
  118. package/dist/data/PromptBanner.model.js +132 -0
  119. package/dist/data/PromptBanner.model.js.map +1 -0
  120. package/dist/data/PromptDialog.cjs +43 -0
  121. package/dist/data/PromptDialog.cjs.map +1 -0
  122. package/dist/data/PromptDialog.d.ts +14 -0
  123. package/dist/data/PromptDialog.d.ts.map +1 -0
  124. package/dist/data/PromptDialog.js +43 -0
  125. package/dist/data/PromptDialog.js.map +1 -0
  126. package/dist/data/TaskManager.cjs +8 -1
  127. package/dist/data/TaskManager.cjs.map +1 -1
  128. package/dist/data/TaskManager.d.ts.map +1 -1
  129. package/dist/data/TaskManager.js +8 -1
  130. package/dist/data/TaskManager.js.map +1 -1
  131. package/dist/data/TaskProgress.cjs +15 -2
  132. package/dist/data/TaskProgress.cjs.map +1 -1
  133. package/dist/data/TaskProgress.d.ts +0 -10
  134. package/dist/data/TaskProgress.d.ts.map +1 -1
  135. package/dist/data/TaskProgress.js +15 -2
  136. package/dist/data/TaskProgress.js.map +1 -1
  137. package/dist/data/TimeseriesCoreBars.cjs +19 -173
  138. package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
  139. package/dist/data/TimeseriesCoreBars.d.ts +9 -26
  140. package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
  141. package/dist/data/TimeseriesCoreBars.js +20 -174
  142. package/dist/data/TimeseriesCoreBars.js.map +1 -1
  143. package/dist/data/WorkloadCard.model.cjs.map +1 -1
  144. package/dist/data/WorkloadCard.model.d.ts +2 -2
  145. package/dist/data/WorkloadCard.model.d.ts.map +1 -1
  146. package/dist/data/WorkloadCard.model.js.map +1 -1
  147. package/dist/data/ai/ChatWindow.cjs +53 -9
  148. package/dist/data/ai/ChatWindow.cjs.map +1 -1
  149. package/dist/data/ai/ChatWindow.d.ts.map +1 -1
  150. package/dist/data/ai/ChatWindow.js +53 -9
  151. package/dist/data/ai/ChatWindow.js.map +1 -1
  152. package/dist/data/ai/SessionViewer.cjs +275 -0
  153. package/dist/data/ai/SessionViewer.cjs.map +1 -0
  154. package/dist/data/ai/SessionViewer.d.ts +33 -0
  155. package/dist/data/ai/SessionViewer.d.ts.map +1 -0
  156. package/dist/data/ai/SessionViewer.fixtures.d.ts +4 -0
  157. package/dist/data/ai/SessionViewer.fixtures.d.ts.map +1 -0
  158. package/dist/data/ai/SessionViewer.js +275 -0
  159. package/dist/data/ai/SessionViewer.js.map +1 -0
  160. package/dist/data/ai/SessionViewer.model.cjs +275 -0
  161. package/dist/data/ai/SessionViewer.model.cjs.map +1 -0
  162. package/dist/data/ai/SessionViewer.model.d.ts +87 -0
  163. package/dist/data/ai/SessionViewer.model.d.ts.map +1 -0
  164. package/dist/data/ai/SessionViewer.model.js +275 -0
  165. package/dist/data/ai/SessionViewer.model.js.map +1 -0
  166. package/dist/data/ai/SessionViewerMenu.cjs +190 -0
  167. package/dist/data/ai/SessionViewerMenu.cjs.map +1 -0
  168. package/dist/data/ai/SessionViewerMenu.d.ts +24 -0
  169. package/dist/data/ai/SessionViewerMenu.d.ts.map +1 -0
  170. package/dist/data/ai/SessionViewerMenu.js +190 -0
  171. package/dist/data/ai/SessionViewerMenu.js.map +1 -0
  172. package/dist/data/ai/ToolPreferences.cjs +232 -39
  173. package/dist/data/ai/ToolPreferences.cjs.map +1 -1
  174. package/dist/data/ai/ToolPreferences.d.ts +4 -7
  175. package/dist/data/ai/ToolPreferences.d.ts.map +1 -1
  176. package/dist/data/ai/ToolPreferences.js +234 -41
  177. package/dist/data/ai/ToolPreferences.js.map +1 -1
  178. package/dist/data/ai/index.d.ts +3 -0
  179. package/dist/data/ai/index.d.ts.map +1 -1
  180. package/dist/data/ai/session-categories.cjs +219 -0
  181. package/dist/data/ai/session-categories.cjs.map +1 -0
  182. package/dist/data/ai/session-categories.d.ts +36 -0
  183. package/dist/data/ai/session-categories.d.ts.map +1 -0
  184. package/dist/data/ai/session-categories.js +219 -0
  185. package/dist/data/ai/session-categories.js.map +1 -0
  186. package/dist/data/chat/clickyOperationsToTools.cjs +89 -3
  187. package/dist/data/chat/clickyOperationsToTools.cjs.map +1 -1
  188. package/dist/data/chat/clickyOperationsToTools.d.ts +1 -1
  189. package/dist/data/chat/clickyOperationsToTools.d.ts.map +1 -1
  190. package/dist/data/chat/clickyOperationsToTools.js +89 -3
  191. package/dist/data/chat/clickyOperationsToTools.js.map +1 -1
  192. package/dist/data/chat/types.cjs.map +1 -1
  193. package/dist/data/chat/types.d.ts +7 -1
  194. package/dist/data/chat/types.d.ts.map +1 -1
  195. package/dist/data/chat/types.js.map +1 -1
  196. package/dist/data/task-status.cjs +19 -12
  197. package/dist/data/task-status.cjs.map +1 -1
  198. package/dist/data/task-status.d.ts +2 -1
  199. package/dist/data/task-status.d.ts.map +1 -1
  200. package/dist/data/task-status.js +19 -12
  201. package/dist/data/task-status.js.map +1 -1
  202. package/dist/data/test-runner/TestRunner.fixtures.d.ts +11 -4
  203. package/dist/data/test-runner/TestRunner.fixtures.d.ts.map +1 -1
  204. package/dist/data/version-info.cjs +3 -3
  205. package/dist/data/version-info.cjs.map +1 -1
  206. package/dist/data/version-info.js +3 -3
  207. package/dist/data/version-info.js.map +1 -1
  208. package/dist/data.cjs +11 -2
  209. package/dist/data.cjs.map +1 -1
  210. package/dist/data.d.ts +6 -2
  211. package/dist/data.d.ts.map +1 -1
  212. package/dist/data.js +11 -2
  213. package/dist/data.js.map +1 -1
  214. package/dist/hooks/use-prompts.cjs +83 -0
  215. package/dist/hooks/use-prompts.cjs.map +1 -0
  216. package/dist/hooks/use-prompts.d.ts +43 -0
  217. package/dist/hooks/use-prompts.d.ts.map +1 -0
  218. package/dist/hooks/use-prompts.js +83 -0
  219. package/dist/hooks/use-prompts.js.map +1 -0
  220. package/dist/hooks.cjs +3 -0
  221. package/dist/hooks.cjs.map +1 -1
  222. package/dist/hooks.d.ts +1 -0
  223. package/dist/hooks.d.ts.map +1 -1
  224. package/dist/hooks.js +3 -0
  225. package/dist/hooks.js.map +1 -1
  226. package/dist/index.cjs +21 -3
  227. package/dist/index.cjs.map +1 -1
  228. package/dist/index.js +21 -3
  229. package/dist/index.js.map +1 -1
  230. package/dist/jotai.cjs +9 -0
  231. package/dist/jotai.cjs.map +1 -0
  232. package/dist/jotai.d.ts +4 -0
  233. package/dist/jotai.d.ts.map +1 -0
  234. package/dist/jotai.js +9 -0
  235. package/dist/jotai.js.map +1 -0
  236. package/dist/lib/utils.cjs +18 -1
  237. package/dist/lib/utils.cjs.map +1 -1
  238. package/dist/lib/utils.d.ts.map +1 -1
  239. package/dist/lib/utils.js +18 -1
  240. package/dist/lib/utils.js.map +1 -1
  241. package/dist/mdx-editor.cjs +5 -0
  242. package/dist/mdx-editor.cjs.map +1 -0
  243. package/dist/mdx-editor.css +2 -0
  244. package/dist/mdx-editor.d.ts +2 -0
  245. package/dist/mdx-editor.d.ts.map +1 -0
  246. package/dist/mdx-editor.js +5 -0
  247. package/dist/mdx-editor.js.map +1 -0
  248. package/dist/rpc/apiClient.cjs +1 -1
  249. package/dist/rpc/apiClient.cjs.map +1 -1
  250. package/dist/rpc/apiClient.js +1 -1
  251. package/dist/rpc/apiClient.js.map +1 -1
  252. package/dist/rpc/surfaceIconMap.cjs +12 -1
  253. package/dist/rpc/surfaceIconMap.cjs.map +1 -1
  254. package/dist/rpc/surfaceIconMap.d.ts.map +1 -1
  255. package/dist/rpc/surfaceIconMap.js +12 -1
  256. package/dist/rpc/surfaceIconMap.js.map +1 -1
  257. package/dist/rpc/types.cjs.map +1 -1
  258. package/dist/rpc/types.d.ts +1 -0
  259. package/dist/rpc/types.d.ts.map +1 -1
  260. package/dist/rpc/types.js.map +1 -1
  261. package/dist/styles.css +1 -1
  262. package/oxlint-plugins/README.md +148 -0
  263. package/oxlint-plugins/clicky-ui-no-adhoc-overlay.js +88 -0
  264. package/oxlint-plugins/clicky-ui-prefer-components.js +46 -0
  265. package/oxlint-plugins/clicky-ui-prefer-icons.js +121 -0
  266. package/oxlint-plugins/clicky-ui-prefer-tailwind.js +98 -0
  267. package/oxlint-plugins/clicky-ui-prefer-theme.js +134 -0
  268. package/oxlint-plugins/clicky-ui-shared.js +132 -0
  269. package/oxlint-plugins/clicky-ui.js +34 -0
  270. package/oxlint-plugins/no-iconify-names.js +37 -0
  271. package/package.json +21 -1
  272. package/dist/data/TimeseriesCoreBars.model.cjs +0 -27
  273. package/dist/data/TimeseriesCoreBars.model.cjs.map +0 -1
  274. package/dist/data/TimeseriesCoreBars.model.d.ts +0 -20
  275. package/dist/data/TimeseriesCoreBars.model.d.ts.map +0 -1
  276. package/dist/data/TimeseriesCoreBars.model.js +0 -27
  277. package/dist/data/TimeseriesCoreBars.model.js.map +0 -1
@@ -1,78 +1,271 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { useMemo } from "react";
1
+ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
+ import { useState, useMemo } from "react";
3
3
  import { cn } from "../../lib/utils.js";
4
4
  import { DropdownMenu } from "../../overlay/DropdownMenu.js";
5
+ import { HoverCard } from "../../overlay/HoverCard.js";
6
+ import { Modal } from "../../overlay/Modal.js";
5
7
  import { Button } from "../../components/button.js";
6
8
  import { Icon } from "../Icon.js";
7
9
  import { UiSliders } from "../../icons/components/UiSliders.js";
10
+ import { UiInfo } from "../../icons/components/UiInfo.js";
8
11
  const MODE_CYCLE = ["enabled", "ask", "disabled"];
9
- const MODE_LABEL = { enabled: "Auto", ask: "Ask", disabled: "Off" };
12
+ const MODE_LABEL = {
13
+ enabled: "Auto",
14
+ ask: "Ask",
15
+ disabled: "Off"
16
+ };
10
17
  function ToolRow({
11
- meta,
18
+ entry,
12
19
  mode,
13
20
  onToggle
14
21
  }) {
22
+ var _a;
23
+ const title = entry.tools.length > 1 ? `${entry.tools.length} tools` : (_a = entry.tools[0]) == null ? void 0 : _a.description;
15
24
  return /* @__PURE__ */ jsxs(
16
25
  "button",
17
26
  {
18
27
  type: "button",
19
28
  className: "flex w-full items-center justify-between rounded px-2 py-1 text-left hover:bg-accent",
20
- onClick: () => onToggle(meta.name),
29
+ title,
30
+ onClick: () => onToggle(entry.key, mode),
21
31
  children: [
22
- /* @__PURE__ */ jsx("span", { className: cn("text-xs", mode === "disabled" && "text-muted-foreground line-through"), children: meta.label }),
23
32
  /* @__PURE__ */ jsx(
24
33
  "span",
25
34
  {
26
35
  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"
36
+ "text-xs",
37
+ mode === "disabled" && "text-muted-foreground line-through"
31
38
  ),
32
- children: MODE_LABEL[mode]
39
+ children: entry.label
33
40
  }
34
- )
41
+ ),
42
+ /* @__PURE__ */ jsx(ModeBadge, { mode })
43
+ ]
44
+ }
45
+ );
46
+ }
47
+ function AdvancedToolRow({
48
+ tool,
49
+ mode,
50
+ onToggle
51
+ }) {
52
+ var _a;
53
+ const description = ((_a = tool.description) == null ? void 0 : _a.trim()) || "No description";
54
+ return /* @__PURE__ */ jsxs(
55
+ "button",
56
+ {
57
+ type: "button",
58
+ className: "grid h-9 w-full grid-cols-[minmax(0,1fr)_4rem] items-center gap-3 border-b border-border px-2 text-left hover:bg-accent",
59
+ title: description,
60
+ onClick: () => onToggle(tool.name, mode),
61
+ children: [
62
+ /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-1.5", children: [
63
+ /* @__PURE__ */ jsx(
64
+ "span",
65
+ {
66
+ className: cn(
67
+ "min-w-0 truncate font-mono text-xs",
68
+ mode === "disabled" && "text-muted-foreground line-through"
69
+ ),
70
+ children: tool.name
71
+ }
72
+ ),
73
+ /* @__PURE__ */ jsx(
74
+ HoverCard,
75
+ {
76
+ placement: "top",
77
+ delay: 120,
78
+ trigger: /* @__PURE__ */ jsx(
79
+ "span",
80
+ {
81
+ "aria-label": `Description for ${tool.name}`,
82
+ className: "inline-flex shrink-0 text-muted-foreground",
83
+ title: description,
84
+ children: /* @__PURE__ */ jsx(Icon, { icon: UiInfo, className: "size-3.5" })
85
+ }
86
+ ),
87
+ cardClassName: "max-w-xs whitespace-normal",
88
+ children: description
89
+ }
90
+ )
91
+ ] }),
92
+ /* @__PURE__ */ jsx("span", { className: "justify-self-end", children: /* @__PURE__ */ jsx(ModeBadge, { mode }) })
35
93
  ]
36
94
  }
37
95
  );
38
96
  }
39
- function ToolPreferences({ tools, value, onChange, className = "" }) {
97
+ function ModeBadge({ mode }) {
98
+ return /* @__PURE__ */ jsx(
99
+ "span",
100
+ {
101
+ className: cn(
102
+ "rounded px-1.5 py-0.5 text-[10px] font-medium",
103
+ mode === "enabled" && "bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300",
104
+ mode === "ask" && "bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300",
105
+ mode === "disabled" && "bg-muted text-muted-foreground"
106
+ ),
107
+ children: MODE_LABEL[mode]
108
+ }
109
+ );
110
+ }
111
+ function ToolPreferences({
112
+ tools,
113
+ value,
114
+ onChange,
115
+ className = ""
116
+ }) {
117
+ const [advancedOpen, setAdvancedOpen] = useState(false);
40
118
  const groups = useMemo(() => {
41
- var _a;
119
+ const maps = {};
120
+ for (const meta of tools) {
121
+ const group = toolGroup(meta);
122
+ const key = toolPreferenceKey(meta);
123
+ const map = maps[group] ?? (maps[group] = /* @__PURE__ */ new Map());
124
+ let entry = map.get(key);
125
+ if (!entry) {
126
+ entry = {
127
+ key,
128
+ label: key === meta.name ? meta.label : key,
129
+ group,
130
+ tools: [],
131
+ defaultMode: toolDefaultMode(meta)
132
+ };
133
+ map.set(key, entry);
134
+ }
135
+ entry.tools.push(meta);
136
+ entry.defaultMode = mostRestrictiveMode(
137
+ entry.defaultMode,
138
+ toolDefaultMode(meta)
139
+ );
140
+ }
42
141
  const g = {};
43
- for (const meta of tools) (g[_a = meta.group ?? "Tools"] ?? (g[_a] = [])).push(meta);
142
+ for (const [group, map] of Object.entries(maps)) {
143
+ g[group] = [...map.values()].sort((a, b) => a.label.localeCompare(b.label));
144
+ }
44
145
  return g;
45
146
  }, [tools]);
46
- const handleToggle = (name) => {
47
- const current = value[name] ?? "enabled";
147
+ const advancedGroups = useMemo(
148
+ () => groupedToolMetas(tools),
149
+ [tools]
150
+ );
151
+ const handleToggle = (name, current) => {
48
152
  const next = MODE_CYCLE[(MODE_CYCLE.indexOf(current) + 1) % MODE_CYCLE.length];
49
153
  onChange({ ...value, [name]: next });
50
154
  };
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,
155
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
156
+ /* @__PURE__ */ jsx(
157
+ DropdownMenu,
158
+ {
159
+ align: "right",
160
+ className,
161
+ menuClassName: "w-64 max-h-[400px] overflow-y-auto p-3",
162
+ trigger: /* @__PURE__ */ jsx(
163
+ Button,
164
+ {
165
+ variant: "ghost",
166
+ size: "icon",
167
+ title: "Tool preferences",
168
+ "data-testid": "tool-preferences-btn",
169
+ children: /* @__PURE__ */ jsx(Icon, { icon: UiSliders, className: "size-4" })
170
+ }
171
+ ),
172
+ children: (closeMenu) => /* @__PURE__ */ jsxs("div", { children: [
173
+ /* @__PURE__ */ jsx("div", { className: "mb-2 text-xs font-semibold", children: "Tool Preferences" }),
174
+ Object.entries(groups).sort(([a], [b]) => a.localeCompare(b)).map(([group, metas]) => /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
175
+ /* @__PURE__ */ jsx("div", { className: "mb-0.5 px-2 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: group }),
176
+ metas.map((entry) => {
177
+ const mode = value[entry.key] ?? entry.defaultMode;
178
+ return /* @__PURE__ */ jsx(
179
+ ToolRow,
180
+ {
181
+ entry,
182
+ mode,
183
+ onToggle: handleToggle
184
+ },
185
+ entry.key
186
+ );
187
+ })
188
+ ] }, group)),
189
+ /* @__PURE__ */ jsx("div", { className: "mt-2 border-t border-border pt-2", children: /* @__PURE__ */ jsx(
190
+ "button",
65
191
  {
66
- meta,
67
- mode: value[meta.name] ?? "enabled",
68
- onToggle: handleToggle
69
- },
70
- meta.name
71
- ))
72
- ] }, group))
73
- ] })
74
- }
75
- );
192
+ type: "button",
193
+ className: "w-full rounded px-2 py-1.5 text-left text-xs hover:bg-accent",
194
+ onClick: () => {
195
+ closeMenu();
196
+ setAdvancedOpen(true);
197
+ },
198
+ children: "Advanced"
199
+ }
200
+ ) })
201
+ ] })
202
+ }
203
+ ),
204
+ /* @__PURE__ */ jsx(
205
+ Modal,
206
+ {
207
+ open: advancedOpen,
208
+ onClose: () => setAdvancedOpen(false),
209
+ title: "Advanced Tool Preferences",
210
+ size: "xl",
211
+ children: /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded border border-border", children: [
212
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_4rem] gap-3 border-b border-border bg-muted/40 px-2 py-1.5 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: [
213
+ /* @__PURE__ */ jsx("span", { children: "Name" }),
214
+ /* @__PURE__ */ jsx("span", { className: "text-right", children: "Mode" })
215
+ ] }),
216
+ /* @__PURE__ */ jsx("div", { className: "max-h-[60vh] overflow-y-auto", children: advancedGroups.length > 0 ? advancedGroups.map(([group, groupTools]) => /* @__PURE__ */ jsxs("div", { children: [
217
+ /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-[1] border-b border-border bg-muted/60 px-2 py-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: group }),
218
+ groupTools.map((tool) => {
219
+ const mode = toolMode(tool, value);
220
+ return /* @__PURE__ */ jsx(
221
+ AdvancedToolRow,
222
+ {
223
+ tool,
224
+ mode,
225
+ onToggle: handleToggle
226
+ },
227
+ tool.name
228
+ );
229
+ })
230
+ ] }, group)) : /* @__PURE__ */ jsx("div", { className: "px-2 py-6 text-center text-xs text-muted-foreground", children: "No tools" }) })
231
+ ] })
232
+ }
233
+ )
234
+ ] });
235
+ }
236
+ function toolGroup(meta) {
237
+ return meta.group ?? "Tools";
238
+ }
239
+ function groupedToolMetas(tools) {
240
+ var _a;
241
+ const groups = {};
242
+ for (const tool of tools) {
243
+ (groups[_a = toolGroup(tool)] ?? (groups[_a] = [])).push(tool);
244
+ }
245
+ return Object.entries(groups).map(([group, groupTools]) => [
246
+ group,
247
+ [...groupTools].sort((a, b) => a.name.localeCompare(b.name))
248
+ ]).sort(([a], [b]) => a.localeCompare(b));
249
+ }
250
+ function toolPreferenceKey(meta) {
251
+ return meta.preferenceKey ?? meta.name;
252
+ }
253
+ function toolDefaultMode(meta) {
254
+ return meta.defaultMode ?? "enabled";
255
+ }
256
+ function toolMode(meta, value) {
257
+ const own = value[meta.name];
258
+ if (own) return own;
259
+ const key = toolPreferenceKey(meta);
260
+ if (key !== meta.name) {
261
+ const grouped = value[key];
262
+ if (grouped) return grouped;
263
+ }
264
+ return toolDefaultMode(meta);
265
+ }
266
+ function mostRestrictiveMode(a, b) {
267
+ const rank = { enabled: 0, ask: 1, disabled: 2 };
268
+ return rank[a] >= rank[b] ? a : b;
76
269
  }
77
270
  export {
78
271
  ToolPreferences
@@ -1 +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;"}
1
+ {"version":3,"file":"ToolPreferences.js","sources":["../../../src/data/ai/ToolPreferences.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { DropdownMenu } from \"../../overlay/DropdownMenu\";\nimport { HoverCard } from \"../../overlay/HoverCard\";\nimport { Modal } from \"../../overlay/Modal\";\nimport { Button } from \"../../components/button\";\nimport { Icon } from \"../Icon\";\nimport { UiInfo, UiSliders } from \"../../icons\";\nimport type { ToolMeta, ToolMode } from \"../chat/types\";\n\nexport type { ToolMeta, ToolMode };\n\n/** How a tool may be invoked: run automatically, pause for approval, or be\n * hidden from the model entirely. */\nconst MODE_CYCLE: ToolMode[] = [\"enabled\", \"ask\", \"disabled\"];\nconst MODE_LABEL: Record<ToolMode, string> = {\n enabled: \"Auto\",\n ask: \"Ask\",\n disabled: \"Off\",\n};\n\ntype ToolPreferenceEntry = {\n key: string;\n label: string;\n group: string;\n tools: ToolMeta[];\n defaultMode: ToolMode;\n};\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 entry,\n mode,\n onToggle,\n}: {\n entry: ToolPreferenceEntry;\n mode: ToolMode;\n onToggle: (name: string, current: ToolMode) => void;\n}) {\n const title =\n entry.tools.length > 1\n ? `${entry.tools.length} tools`\n : entry.tools[0]?.description;\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 title={title}\n onClick={() => onToggle(entry.key, mode)}\n >\n <span\n className={cn(\n \"text-xs\",\n mode === \"disabled\" && \"text-muted-foreground line-through\",\n )}\n >\n {entry.label}\n </span>\n <ModeBadge mode={mode} />\n </button>\n );\n}\n\nfunction AdvancedToolRow({\n tool,\n mode,\n onToggle,\n}: {\n tool: ToolMeta;\n mode: ToolMode;\n onToggle: (name: string, current: ToolMode) => void;\n}) {\n const description = tool.description?.trim() || \"No description\";\n return (\n <button\n type=\"button\"\n className=\"grid h-9 w-full grid-cols-[minmax(0,1fr)_4rem] items-center gap-3 border-b border-border px-2 text-left hover:bg-accent\"\n title={description}\n onClick={() => onToggle(tool.name, mode)}\n >\n <span className=\"flex min-w-0 items-center gap-1.5\">\n <span\n className={cn(\n \"min-w-0 truncate font-mono text-xs\",\n mode === \"disabled\" && \"text-muted-foreground line-through\",\n )}\n >\n {tool.name}\n </span>\n <HoverCard\n placement=\"top\"\n delay={120}\n trigger={\n <span\n aria-label={`Description for ${tool.name}`}\n className=\"inline-flex shrink-0 text-muted-foreground\"\n title={description}\n >\n <Icon icon={UiInfo} className=\"size-3.5\" />\n </span>\n }\n cardClassName=\"max-w-xs whitespace-normal\"\n >\n {description}\n </HoverCard>\n </span>\n <span className=\"justify-self-end\">\n <ModeBadge mode={mode} />\n </span>\n </button>\n );\n}\n\nfunction ModeBadge({ mode }: { mode: ToolMode }) {\n return (\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\" &&\n \"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 );\n}\n\n/** A popover that cycles each tool/group 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({\n tools,\n value,\n onChange,\n className = \"\",\n}: ToolPreferencesProps) {\n const [advancedOpen, setAdvancedOpen] = useState(false);\n const groups = useMemo(() => {\n const maps: Record<string, Map<string, ToolPreferenceEntry>> = {};\n for (const meta of tools) {\n const group = toolGroup(meta);\n const key = toolPreferenceKey(meta);\n const map = (maps[group] ??= new Map());\n let entry = map.get(key);\n if (!entry) {\n entry = {\n key,\n label: key === meta.name ? meta.label : key,\n group,\n tools: [],\n defaultMode: toolDefaultMode(meta),\n };\n map.set(key, entry);\n }\n entry.tools.push(meta);\n entry.defaultMode = mostRestrictiveMode(\n entry.defaultMode,\n toolDefaultMode(meta),\n );\n }\n const g: Record<string, ToolPreferenceEntry[]> = {};\n for (const [group, map] of Object.entries(maps)) {\n g[group] = [...map.values()].sort((a, b) => a.label.localeCompare(b.label));\n }\n return g;\n }, [tools]);\n\n const advancedGroups = useMemo(\n () => groupedToolMetas(tools),\n [tools],\n );\n\n const handleToggle = (name: string, current: ToolMode) => {\n const next =\n MODE_CYCLE[(MODE_CYCLE.indexOf(current) + 1) % MODE_CYCLE.length]!;\n onChange({ ...value, [name]: next });\n };\n\n return (\n <>\n <DropdownMenu\n align=\"right\"\n className={className}\n menuClassName=\"w-64 max-h-[400px] overflow-y-auto p-3\"\n trigger={\n <Button\n variant=\"ghost\"\n size=\"icon\"\n title=\"Tool preferences\"\n data-testid=\"tool-preferences-btn\"\n >\n <Icon icon={UiSliders} className=\"size-4\" />\n </Button>\n }\n >\n {(closeMenu) => (\n <div>\n <div className=\"mb-2 text-xs font-semibold\">Tool Preferences</div>\n {Object.entries(groups)\n .sort(([a], [b]) => a.localeCompare(b))\n .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((entry) => {\n const mode = value[entry.key] ?? entry.defaultMode;\n return (\n <ToolRow\n key={entry.key}\n entry={entry}\n mode={mode}\n onToggle={handleToggle}\n />\n );\n })}\n </div>\n ))}\n <div className=\"mt-2 border-t border-border pt-2\">\n <button\n type=\"button\"\n className=\"w-full rounded px-2 py-1.5 text-left text-xs hover:bg-accent\"\n onClick={() => {\n closeMenu();\n setAdvancedOpen(true);\n }}\n >\n Advanced\n </button>\n </div>\n </div>\n )}\n </DropdownMenu>\n <Modal\n open={advancedOpen}\n onClose={() => setAdvancedOpen(false)}\n title=\"Advanced Tool Preferences\"\n size=\"xl\"\n >\n <div className=\"overflow-hidden rounded border border-border\">\n <div className=\"grid grid-cols-[minmax(0,1fr)_4rem] gap-3 border-b border-border bg-muted/40 px-2 py-1.5 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground\">\n <span>Name</span>\n <span className=\"text-right\">Mode</span>\n </div>\n <div className=\"max-h-[60vh] overflow-y-auto\">\n {advancedGroups.length > 0 ? (\n advancedGroups.map(([group, groupTools]) => (\n <div key={group}>\n <div className=\"sticky top-0 z-[1] border-b border-border bg-muted/60 px-2 py-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground\">\n {group}\n </div>\n {groupTools.map((tool) => {\n const mode = toolMode(tool, value);\n return (\n <AdvancedToolRow\n key={tool.name}\n tool={tool}\n mode={mode}\n onToggle={handleToggle}\n />\n );\n })}\n </div>\n ))\n ) : (\n <div className=\"px-2 py-6 text-center text-xs text-muted-foreground\">\n No tools\n </div>\n )}\n </div>\n </div>\n </Modal>\n </>\n );\n}\n\nfunction toolGroup(meta: ToolMeta): string {\n return meta.group ?? \"Tools\";\n}\n\nfunction groupedToolMetas(tools: ToolMeta[]): Array<[string, ToolMeta[]]> {\n const groups: Record<string, ToolMeta[]> = {};\n for (const tool of tools) {\n (groups[toolGroup(tool)] ??= []).push(tool);\n }\n return Object.entries(groups)\n .map(([group, groupTools]) => [\n group,\n [...groupTools].sort((a, b) => a.name.localeCompare(b.name)),\n ] as [string, ToolMeta[]])\n .sort(([a], [b]) => a.localeCompare(b));\n}\n\nfunction toolPreferenceKey(meta: ToolMeta): string {\n return meta.preferenceKey ?? meta.name;\n}\n\nfunction toolDefaultMode(meta: ToolMeta): ToolMode {\n return meta.defaultMode ?? \"enabled\";\n}\n\nfunction toolMode(meta: ToolMeta, value: Record<string, ToolMode>): ToolMode {\n const own = value[meta.name];\n if (own) return own;\n const key = toolPreferenceKey(meta);\n if (key !== meta.name) {\n const grouped = value[key];\n if (grouped) return grouped;\n }\n return toolDefaultMode(meta);\n}\n\nfunction mostRestrictiveMode(a: ToolMode, b: ToolMode): ToolMode {\n const rank: Record<ToolMode, number> = { enabled: 0, ask: 1, disabled: 2 };\n return rank[a] >= rank[b] ? a : b;\n}\n"],"names":[],"mappings":"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"}
@@ -7,4 +7,7 @@ export { ContextBadges, ContextBadgesReadonly, type ContextBadgesProps, } from '
7
7
  export { ToolPreferences, type ToolPreferencesProps, type ToolMeta, type ToolMode, } from './ToolPreferences';
8
8
  export { ContextUsage, type ContextUsageProps } from '../chat/ContextUsage';
9
9
  export { serializeContext, parseContextPrefix, makeContextId, type ChatContextItem, type ContextTypeConfig, type ContextTypeStyle, } from './context';
10
+ export { SessionViewer, type SessionViewerProps, type SessionEntry, type SessionEvent, type SessionInput, type SessionThemeOverride, } from './SessionViewer';
11
+ export { getSessionAction, normalizeSession, splitMcpTool, summarizeSession, summarizeToolInput, type SessionActionMeta, type SessionEventKind, type SessionToolUse, type SessionMessage, type SessionContent, type SessionTone, } from './SessionViewer.model';
12
+ export { CATEGORY_LABELS, classifyCommand, classifyToolCategory, collectSessionFilters, eventCategory, isEventVisible, type SessionCategory, type SessionFilters, type SessionVisibility, } from './session-categories';
10
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data/ai/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,yBAAyB,EACzB,KAAK,8BAA8B,GACpC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,KAAK,kBAAkB,GACxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,eAAe,EACf,KAAK,oBAAoB,EACzB,KAAK,QAAQ,EACb,KAAK,QAAQ,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data/ai/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,yBAAyB,EACzB,KAAK,8BAA8B,GACpC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,YAAY,EACZ,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,KAAK,kBAAkB,GACxB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,eAAe,EACf,KAAK,oBAAoB,EACzB,KAAK,QAAQ,EACb,KAAK,QAAQ,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,oBAAoB,GAC1B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,WAAW,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,EACb,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,iBAAiB,GACvB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const SessionViewer_model = require("./SessionViewer.model.cjs");
4
+ const CATEGORY_LABELS = {
5
+ build: "Build",
6
+ test: "Test",
7
+ install: "Install",
8
+ explore: "Explore",
9
+ lint: "Lint",
10
+ cleanup: "Cleanup",
11
+ git: "Git",
12
+ docker: "Docker",
13
+ k8s: "Kubernetes",
14
+ run: "Run",
15
+ plan: "Plan",
16
+ edit: "Edit",
17
+ clarify: "Clarify",
18
+ read: "Read",
19
+ other: "Other"
20
+ };
21
+ const CATEGORY_PRIORITY = {
22
+ install: 100,
23
+ edit: 90,
24
+ run: 80,
25
+ test: 70,
26
+ build: 60,
27
+ cleanup: 50,
28
+ docker: 40,
29
+ k8s: 40,
30
+ git: 30,
31
+ explore: 20,
32
+ lint: 20,
33
+ plan: 20,
34
+ read: 15,
35
+ clarify: 10,
36
+ other: 0
37
+ };
38
+ const CATEGORY_CONFIG = [
39
+ [
40
+ "build",
41
+ {
42
+ commands: ["go build", "make build", "make all", "cargo build", "npm run build", "yarn build", "task build", "gradle build", "mvn compile", "mvn package", "dotnet build", "pnpm build", "bun build", "mage", "bazel build", "nx build", "turbo build", "javac"],
43
+ patterns: [".*gradle.*(build|compile|bootJar|jar).*", ".*mvn.*(compile|package)", "^go build", "^make\\s*$", "^make\\s+(build|all)\\b", "^cargo build", "^task build"]
44
+ }
45
+ ],
46
+ [
47
+ "test",
48
+ {
49
+ commands: ["go test", "pytest", "npm test", "yarn test", "task test", "make test", "cargo test", "mvn test", "gradle test", "vitest", "jest", "bun test", "dotnet test", "ginkgo", "gotestsum", "zig test"],
50
+ patterns: [".*gradle.*test", ".*mvn.*test", "^go test", "^pytest", "^npm (run )?test", "^make\\s+test", "^vitest", "^jest", "^bun test", "^ginkgo", "^gotestsum"]
51
+ }
52
+ ],
53
+ [
54
+ "install",
55
+ {
56
+ commands: ["npm install", "npm i", "yarn install", "yarn add", "go mod tidy", "go mod download", "go get", "pip install", "pip3 install", "cargo add", "brew install", "apt install", "apt-get install", "pnpm install", "pnpm add", "bun install", "bun add", "poetry install", "poetry add", "uv pip install", "pdm install", "pdm add"],
57
+ patterns: ["^npm (install|i)\\b", "^yarn (install|add)\\b", "^pip3? install", "^go (mod tidy|mod download|get)", "^pnpm (install|add)\\b", "^bun (install|add)\\b", "^poetry (install|add)\\b", "^uv pip install", "^pdm (install|add)\\b"]
58
+ }
59
+ ],
60
+ [
61
+ "explore",
62
+ {
63
+ tools: ["Read", "Grep", "Glob", "LSP", "WebFetch", "WebSearch"],
64
+ commands: ["ls", "md5", "echo", "find", "grep", "rg", "ag", "cat", "head", "tail", "less", "more", "tree", "wc", "file", "stat", "du", "df", "pwd", "which", "whereis", "type", "fd", "bat", "exa", "eza", "fzf", "jq", "yq", "ripgrep", "sd", "diff", "go list", "git status", "git diff", "git log", "ps", "printenv", "sed"],
65
+ patterns: ["^ls\\b", "^find\\b", "^grep\\b", "^rg\\b", "^cat\\b", "^head\\b", "^tail\\b", "^tree\\b", "^fd\\b", "^bat\\b", "^exa\\b", "^eza\\b", "^jq\\b", "^yq\\b", "^diff\\b", "^go list\\b", "^git\\s+(status|diff|log)\\b"]
66
+ }
67
+ ],
68
+ [
69
+ "lint",
70
+ {
71
+ commands: ["golangci-lint", "eslint", "gofmt", "go fmt", "prettier", "black", "flake8", "pylint", "rubocop", "shellcheck", "task fmt", "make fmt", "make lint", "biome", "ruff", "mypy", "staticcheck", "buf lint", "deno lint", "oxlint"],
72
+ patterns: ["lint", "^go fmt", "^gofmt", "^prettier", "^black\\b", "^biome\\b", "^ruff\\b", "^mypy\\b", "^staticcheck\\b"]
73
+ }
74
+ ],
75
+ [
76
+ "cleanup",
77
+ {
78
+ commands: ["rm", "rmdir", "git clean", "make clean", "cargo clean", "go clean", "npm cache clean", "docker prune", "docker system prune"],
79
+ patterns: ["^rm\\b", "^rmdir\\b", "clean\\b", "prune\\b"]
80
+ }
81
+ ],
82
+ [
83
+ "git",
84
+ {
85
+ commands: ["git show", "git branch", "git checkout", "git switch", "git commit", "git push", "git pull", "git fetch", "git merge", "git rebase", "git stash", "git add", "git reset", "git clone", "git remote", "git tag"],
86
+ patterns: ["^git\\b"]
87
+ }
88
+ ],
89
+ [
90
+ "docker",
91
+ {
92
+ commands: ["docker run", "docker build", "docker push", "docker pull", "docker ps", "docker images", "docker logs", "docker exec", "docker stop", "docker start", "docker rm", "docker rmi", "docker-compose", "podman"],
93
+ patterns: ["^docker\\b", "^docker-compose\\b", "^podman\\b"]
94
+ }
95
+ ],
96
+ [
97
+ "k8s",
98
+ {
99
+ commands: ["kubectl", "helm", "k9s", "kubectx", "kubens", "kustomize", "minikube", "kind"],
100
+ patterns: ["^kubectl\\b", "^helm\\b", "^k9s\\b", "^kubectx\\b", "^kubens\\b", "^kustomize\\b", "^minikube\\b", "^kind\\b"]
101
+ }
102
+ ],
103
+ [
104
+ "run",
105
+ {
106
+ tools: ["KillShell"],
107
+ commands: ["go run", "python", "python3", "node", "bun run", "deno run", "ruby", "perl", "php", "java"],
108
+ patterns: [".*gradle.*run.*", "^go run\\b", "^python3?\\b", "^node\\b", "^bun run\\b", "^deno run\\b", "^ruby\\b", "^perl\\b", "^php\\b", "^java\\s+-jar\\b", "^\\./[\\w.-]+\\.(sh|bash|py|rb|pl)$", "^bash\\s+\\S+\\.sh"]
109
+ }
110
+ ],
111
+ [
112
+ "plan",
113
+ {
114
+ tools: ["Task", "TodoWrite", "EnterPlanMode"],
115
+ commands: ["task", "make help", "task explore", "task plan", "task todos", "task todo"],
116
+ patterns: ["^task\\s*$", "^task\\s+--list", "^make\\s+help"]
117
+ }
118
+ ],
119
+ [
120
+ "edit",
121
+ {
122
+ tools: ["Edit", "Write", "NotebookEdit"],
123
+ commands: ["mkdir"],
124
+ patterns: ["sed.* -i"]
125
+ }
126
+ ],
127
+ ["clarify", { tools: ["AskUserQuestion", "ExitPlanMode", "TaskOutput"] }]
128
+ ];
129
+ const COMPILED = CATEGORY_CONFIG.map(([cat, rule]) => [
130
+ cat,
131
+ (rule.patterns ?? []).map((p) => new RegExp(p))
132
+ ]);
133
+ function chooseBetterMatch(current, candidate) {
134
+ if (!candidate.matched || candidate.category === "other") return current;
135
+ if (!current.matched || current.category === "other") return candidate;
136
+ if (candidate.specificity > current.specificity) return candidate;
137
+ if (candidate.specificity < current.specificity) return current;
138
+ const cp = CATEGORY_PRIORITY[candidate.category];
139
+ const kp = CATEGORY_PRIORITY[current.category];
140
+ if (cp > kp) return candidate;
141
+ if (cp < kp) return current;
142
+ return candidate.category < current.category ? candidate : current;
143
+ }
144
+ function classifyCommand(command) {
145
+ const cmd = command.trim();
146
+ if (!cmd) return "other";
147
+ let best = { category: "other", specificity: 0, matched: false };
148
+ for (const [cat, rule] of CATEGORY_CONFIG) {
149
+ for (const prefix of rule.commands ?? []) {
150
+ if (cmd === prefix || cmd.startsWith(`${prefix} `)) {
151
+ best = chooseBetterMatch(best, { category: cat, specificity: prefix.length, matched: true });
152
+ }
153
+ }
154
+ }
155
+ for (const [cat, regexps] of COMPILED) {
156
+ for (const re of regexps) {
157
+ if (re.test(cmd)) {
158
+ best = chooseBetterMatch(best, { category: cat, specificity: re.source.length, matched: true });
159
+ }
160
+ }
161
+ }
162
+ return best.category;
163
+ }
164
+ function classifyTool(tool) {
165
+ var _a;
166
+ for (const [cat, rule] of CATEGORY_CONFIG) {
167
+ if ((_a = rule.tools) == null ? void 0 : _a.includes(tool)) return cat;
168
+ }
169
+ return "other";
170
+ }
171
+ function inputString(input, key) {
172
+ return typeof (input == null ? void 0 : input[key]) === "string" ? input[key] : "";
173
+ }
174
+ function classifyToolCategory(tool, input) {
175
+ const filePath = inputString(input, "file_path") || inputString(input, "notebook_path") || inputString(input, "path");
176
+ if (filePath.includes("/.claude/plans/")) return "plan";
177
+ const cat = classifyTool(tool);
178
+ if (cat === "other" && tool === "Bash") return classifyCommand(inputString(input, "command"));
179
+ return cat;
180
+ }
181
+ function eventCategory(event) {
182
+ if (event.kind !== "tool") return null;
183
+ return classifyToolCategory(event.tool ?? "", event.toolInput);
184
+ }
185
+ function isEventVisible(event, v) {
186
+ if (event.kind === "thinking") return v.showThinking;
187
+ if (event.kind !== "tool") return true;
188
+ const tool = event.tool ?? "";
189
+ if (v.hiddenTools.has(tool)) return false;
190
+ if (v.hiddenCategories.has(classifyToolCategory(tool, event.toolInput))) return false;
191
+ if (event.source && v.hiddenSources.has(event.source)) return false;
192
+ return true;
193
+ }
194
+ function collectSessionFilters(events) {
195
+ const categories = /* @__PURE__ */ new Set();
196
+ const tools = /* @__PURE__ */ new Map();
197
+ const sources = /* @__PURE__ */ new Set();
198
+ for (const event of events) {
199
+ if (event.kind !== "tool") continue;
200
+ const tool = event.tool ?? "";
201
+ categories.add(classifyToolCategory(tool, event.toolInput));
202
+ if (!tools.has(tool)) tools.set(tool, SessionViewer_model.getSessionAction(tool).label);
203
+ if (event.source) sources.add(event.source);
204
+ }
205
+ return {
206
+ categories: [...categories].sort(
207
+ (a, b) => CATEGORY_PRIORITY[b] - CATEGORY_PRIORITY[a] || a.localeCompare(b)
208
+ ),
209
+ tools: [...tools].map(([key, label]) => ({ key, label })).sort((a, b) => a.label.localeCompare(b.label)),
210
+ sources: [...sources].sort()
211
+ };
212
+ }
213
+ exports.CATEGORY_LABELS = CATEGORY_LABELS;
214
+ exports.classifyCommand = classifyCommand;
215
+ exports.classifyToolCategory = classifyToolCategory;
216
+ exports.collectSessionFilters = collectSessionFilters;
217
+ exports.eventCategory = eventCategory;
218
+ exports.isEventVisible = isEventVisible;
219
+ //# sourceMappingURL=session-categories.cjs.map