@tai42/studio-sdk 16.0.0 → 17.0.0

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 (486) hide show
  1. package/dist/components/code-block.js +1 -1
  2. package/dist/components/code-block.js.map +1 -1
  3. package/dist/components/confirm-dialog.js +1 -1
  4. package/dist/components/confirm-dialog.js.map +1 -1
  5. package/dist/components/copy-field.js +1 -1
  6. package/dist/components/copy-field.js.map +1 -1
  7. package/dist/components/date-range-picker.d.ts.map +1 -1
  8. package/dist/components/date-range-picker.js.map +1 -1
  9. package/dist/components/dialog.d.ts.map +1 -1
  10. package/dist/components/dialog.js.map +1 -1
  11. package/dist/components/dirty-guard.d.ts.map +1 -1
  12. package/dist/components/dirty-guard.js +1 -1
  13. package/dist/components/dirty-guard.js.map +1 -1
  14. package/dist/components/explorer-body.d.ts +49 -0
  15. package/dist/components/explorer-body.d.ts.map +1 -0
  16. package/dist/components/explorer-body.js +67 -0
  17. package/dist/components/explorer-body.js.map +1 -0
  18. package/dist/components/explorer-page-size.d.ts +4 -0
  19. package/dist/components/explorer-page-size.d.ts.map +1 -0
  20. package/dist/components/explorer-page-size.js +36 -0
  21. package/dist/components/explorer-page-size.js.map +1 -0
  22. package/dist/components/explorer-tag-filter.d.ts +17 -0
  23. package/dist/components/explorer-tag-filter.d.ts.map +1 -0
  24. package/dist/components/explorer-tag-filter.js +29 -0
  25. package/dist/components/explorer-tag-filter.js.map +1 -0
  26. package/dist/components/explorer-tags.d.ts +22 -0
  27. package/dist/components/explorer-tags.d.ts.map +1 -0
  28. package/dist/components/explorer-tags.js +51 -0
  29. package/dist/components/explorer-tags.js.map +1 -0
  30. package/dist/components/explorer-view.d.ts +3 -17
  31. package/dist/components/explorer-view.d.ts.map +1 -1
  32. package/dist/components/explorer-view.js +53 -170
  33. package/dist/components/explorer-view.js.map +1 -1
  34. package/dist/components/extension-combo-builder.d.ts +1 -6
  35. package/dist/components/extension-combo-builder.d.ts.map +1 -1
  36. package/dist/components/extension-combo-builder.js +4 -79
  37. package/dist/components/extension-combo-builder.js.map +1 -1
  38. package/dist/components/extension-combo-parts.d.ts +44 -0
  39. package/dist/components/extension-combo-parts.d.ts.map +1 -0
  40. package/dist/components/extension-combo-parts.js +52 -0
  41. package/dist/components/extension-combo-parts.js.map +1 -0
  42. package/dist/components/field.d.ts +8 -0
  43. package/dist/components/field.d.ts.map +1 -1
  44. package/dist/components/field.js +0 -8
  45. package/dist/components/field.js.map +1 -1
  46. package/dist/components/fleet-report.d.ts +1 -1
  47. package/dist/components/fleet-report.d.ts.map +1 -1
  48. package/dist/components/fleet-report.js +51 -37
  49. package/dist/components/fleet-report.js.map +1 -1
  50. package/dist/components/folder-nav.d.ts.map +1 -1
  51. package/dist/components/folder-nav.js +1 -1
  52. package/dist/components/folder-nav.js.map +1 -1
  53. package/dist/components/form-dialog.d.ts.map +1 -1
  54. package/dist/components/form-dialog.js +1 -1
  55. package/dist/components/form-dialog.js.map +1 -1
  56. package/dist/components/icons/chrome-marks.d.ts +50 -0
  57. package/dist/components/icons/chrome-marks.d.ts.map +1 -0
  58. package/dist/components/icons/chrome-marks.js +51 -0
  59. package/dist/components/icons/chrome-marks.js.map +1 -0
  60. package/dist/components/icons/icon-frame.d.ts +29 -0
  61. package/dist/components/icons/icon-frame.d.ts.map +1 -0
  62. package/dist/components/icons/icon-frame.js +19 -0
  63. package/dist/components/icons/icon-frame.js.map +1 -0
  64. package/dist/components/icons/index.d.ts +40 -0
  65. package/dist/components/icons/index.d.ts.map +1 -0
  66. package/dist/components/icons/index.js +39 -0
  67. package/dist/components/icons/index.js.map +1 -0
  68. package/dist/components/icons/nav-map.d.ts +14 -0
  69. package/dist/components/icons/nav-map.d.ts.map +1 -0
  70. package/dist/components/icons/nav-map.js +28 -0
  71. package/dist/components/icons/nav-map.js.map +1 -0
  72. package/dist/components/icons/nav-marks.d.ts +44 -0
  73. package/dist/components/icons/nav-marks.d.ts.map +1 -0
  74. package/dist/components/icons/nav-marks.js +45 -0
  75. package/dist/components/icons/nav-marks.js.map +1 -0
  76. package/dist/components/icons/status-marks.d.ts +21 -0
  77. package/dist/components/icons/status-marks.d.ts.map +1 -0
  78. package/dist/components/icons/status-marks.js +22 -0
  79. package/dist/components/icons/status-marks.js.map +1 -0
  80. package/dist/components/icons/theme-marks.d.ts +9 -0
  81. package/dist/components/icons/theme-marks.d.ts.map +1 -0
  82. package/dist/components/icons/theme-marks.js +10 -0
  83. package/dist/components/icons/theme-marks.js.map +1 -0
  84. package/dist/components/inputs.js.map +1 -1
  85. package/dist/components/json-diff.d.ts.map +1 -1
  86. package/dist/components/json-diff.js +1 -3
  87. package/dist/components/json-diff.js.map +1 -1
  88. package/dist/components/json-tree-context.d.ts +13 -0
  89. package/dist/components/json-tree-context.d.ts.map +1 -0
  90. package/dist/components/json-tree-context.js +15 -0
  91. package/dist/components/json-tree-context.js.map +1 -0
  92. package/dist/components/json-tree-model.d.ts +56 -0
  93. package/dist/components/json-tree-model.d.ts.map +1 -0
  94. package/dist/components/json-tree-model.js +125 -0
  95. package/dist/components/json-tree-model.js.map +1 -0
  96. package/dist/components/json-tree-nodes.d.ts +35 -0
  97. package/dist/components/json-tree-nodes.d.ts.map +1 -0
  98. package/dist/components/json-tree-nodes.js +113 -0
  99. package/dist/components/json-tree-nodes.js.map +1 -0
  100. package/dist/components/json-tree.d.ts +20 -0
  101. package/dist/components/json-tree.d.ts.map +1 -1
  102. package/dist/components/json-tree.js +7 -315
  103. package/dist/components/json-tree.js.map +1 -1
  104. package/dist/components/json-value-format.d.ts +20 -0
  105. package/dist/components/json-value-format.d.ts.map +1 -0
  106. package/dist/components/json-value-format.js +63 -0
  107. package/dist/components/json-value-format.js.map +1 -0
  108. package/dist/components/markdown-blocks.d.ts +38 -0
  109. package/dist/components/markdown-blocks.d.ts.map +1 -0
  110. package/dist/components/markdown-blocks.js +168 -0
  111. package/dist/components/markdown-blocks.js.map +1 -0
  112. package/dist/components/markdown-inline.d.ts +24 -0
  113. package/dist/components/markdown-inline.d.ts.map +1 -0
  114. package/dist/components/markdown-inline.js +257 -0
  115. package/dist/components/markdown-inline.js.map +1 -0
  116. package/dist/components/markdown.d.ts +3 -52
  117. package/dist/components/markdown.d.ts.map +1 -1
  118. package/dist/components/markdown.js +4 -376
  119. package/dist/components/markdown.js.map +1 -1
  120. package/dist/components/observer-registry.d.ts +38 -0
  121. package/dist/components/observer-registry.d.ts.map +1 -0
  122. package/dist/components/observer-registry.js +131 -0
  123. package/dist/components/observer-registry.js.map +1 -0
  124. package/dist/components/overflow-measure.d.ts +38 -0
  125. package/dist/components/overflow-measure.d.ts.map +1 -0
  126. package/dist/components/overflow-measure.js +54 -0
  127. package/dist/components/overflow-measure.js.map +1 -0
  128. package/dist/components/page-fill.d.ts.map +1 -1
  129. package/dist/components/page-fill.js.map +1 -1
  130. package/dist/components/prose-regions.d.ts +81 -0
  131. package/dist/components/prose-regions.d.ts.map +1 -0
  132. package/dist/components/prose-regions.js +128 -0
  133. package/dist/components/prose-regions.js.map +1 -0
  134. package/dist/components/radio-group.d.ts.map +1 -1
  135. package/dist/components/radio-group.js.map +1 -1
  136. package/dist/components/scroll-region.d.ts +24 -0
  137. package/dist/components/scroll-region.d.ts.map +1 -1
  138. package/dist/components/scroll-region.js +3 -322
  139. package/dist/components/scroll-region.js.map +1 -1
  140. package/dist/components/tab-stop-parse.d.ts +53 -0
  141. package/dist/components/tab-stop-parse.d.ts.map +1 -0
  142. package/dist/components/tab-stop-parse.js +202 -0
  143. package/dist/components/tab-stop-parse.js.map +1 -0
  144. package/dist/components/table.d.ts +1 -1
  145. package/dist/components/table.d.ts.map +1 -1
  146. package/dist/components/tags.d.ts.map +1 -1
  147. package/dist/components/tags.js +1 -1
  148. package/dist/components/tags.js.map +1 -1
  149. package/dist/components/templated-text-field.d.ts +1 -1
  150. package/dist/components/templated-text-field.d.ts.map +1 -1
  151. package/dist/components/templated-text-field.js +10 -174
  152. package/dist/components/templated-text-field.js.map +1 -1
  153. package/dist/components/templated-text-kwargs-editor.d.ts +24 -0
  154. package/dist/components/templated-text-kwargs-editor.d.ts.map +1 -0
  155. package/dist/components/templated-text-kwargs-editor.js +48 -0
  156. package/dist/components/templated-text-kwargs-editor.js.map +1 -0
  157. package/dist/components/templated-text-kwargs.d.ts +37 -0
  158. package/dist/components/templated-text-kwargs.d.ts.map +1 -0
  159. package/dist/components/templated-text-kwargs.js +66 -0
  160. package/dist/components/templated-text-kwargs.js.map +1 -0
  161. package/dist/components/templated-text-source.d.ts +33 -0
  162. package/dist/components/templated-text-source.d.ts.map +1 -0
  163. package/dist/components/templated-text-source.js +53 -0
  164. package/dist/components/templated-text-source.js.map +1 -0
  165. package/dist/components/tool-picker-parts.d.ts +39 -0
  166. package/dist/components/tool-picker-parts.d.ts.map +1 -0
  167. package/dist/components/tool-picker-parts.js +87 -0
  168. package/dist/components/tool-picker-parts.js.map +1 -0
  169. package/dist/components/tool-picker.d.ts +1 -2
  170. package/dist/components/tool-picker.d.ts.map +1 -1
  171. package/dist/components/tool-picker.js +4 -66
  172. package/dist/components/tool-picker.js.map +1 -1
  173. package/dist/components/version-history-panel.d.ts.map +1 -1
  174. package/dist/components/version-history-panel.js +7 -34
  175. package/dist/components/version-history-panel.js.map +1 -1
  176. package/dist/components/version-history-rows.d.ts +48 -0
  177. package/dist/components/version-history-rows.d.ts.map +1 -0
  178. package/dist/components/version-history-rows.js +51 -0
  179. package/dist/components/version-history-rows.js.map +1 -0
  180. package/dist/components/view-toggle.d.ts.map +1 -1
  181. package/dist/components/view-toggle.js.map +1 -1
  182. package/dist/element-slot.d.ts +11 -0
  183. package/dist/element-slot.d.ts.map +1 -1
  184. package/dist/element-slot.js +0 -11
  185. package/dist/element-slot.js.map +1 -1
  186. package/dist/guards.d.ts +6 -0
  187. package/dist/guards.d.ts.map +1 -0
  188. package/dist/guards.js +8 -0
  189. package/dist/guards.js.map +1 -0
  190. package/dist/hooks/interactions-connection.d.ts +43 -0
  191. package/dist/hooks/interactions-connection.d.ts.map +1 -0
  192. package/dist/hooks/interactions-connection.js +171 -0
  193. package/dist/hooks/interactions-connection.js.map +1 -0
  194. package/dist/hooks/interactions-stream.d.ts +80 -0
  195. package/dist/hooks/interactions-stream.d.ts.map +1 -0
  196. package/dist/hooks/interactions-stream.js +233 -0
  197. package/dist/hooks/interactions-stream.js.map +1 -0
  198. package/dist/hooks/useApi.d.ts +2259 -2189
  199. package/dist/hooks/useApi.d.ts.map +1 -1
  200. package/dist/hooks/useApi.js +0 -11
  201. package/dist/hooks/useApi.js.map +1 -1
  202. package/dist/hooks/useAuth.d.ts +6 -0
  203. package/dist/hooks/useAuth.d.ts.map +1 -1
  204. package/dist/hooks/useAuth.js +0 -6
  205. package/dist/hooks/useAuth.js.map +1 -1
  206. package/dist/hooks/useCapabilities.d.ts +18 -2
  207. package/dist/hooks/useCapabilities.d.ts.map +1 -1
  208. package/dist/hooks/useCapabilities.js +1 -17
  209. package/dist/hooks/useCapabilities.js.map +1 -1
  210. package/dist/hooks/useSse.d.ts +34 -6
  211. package/dist/hooks/useSse.d.ts.map +1 -1
  212. package/dist/hooks/useSse.js +27 -471
  213. package/dist/hooks/useSse.js.map +1 -1
  214. package/dist/hooks/useSystemKinds.d.ts +1 -1
  215. package/dist/hooks/useSystemKinds.d.ts.map +1 -1
  216. package/dist/hooks/useSystemKinds.js +0 -18
  217. package/dist/hooks/useSystemKinds.js.map +1 -1
  218. package/dist/hooks/useTheme.d.ts +15 -0
  219. package/dist/hooks/useTheme.d.ts.map +1 -1
  220. package/dist/hooks/useTheme.js +0 -15
  221. package/dist/hooks/useTheme.js.map +1 -1
  222. package/dist/hooks/useToolDisplayNames.d.ts +0 -14
  223. package/dist/hooks/useToolDisplayNames.d.ts.map +1 -1
  224. package/dist/hooks/useToolDisplayNames.js +0 -14
  225. package/dist/hooks/useToolDisplayNames.js.map +1 -1
  226. package/dist/host.d.ts +3 -3
  227. package/dist/host.d.ts.map +1 -1
  228. package/dist/host.js +2 -9
  229. package/dist/host.js.map +1 -1
  230. package/dist/index.d.ts +103 -103
  231. package/dist/index.d.ts.map +1 -1
  232. package/dist/index.js +49 -62
  233. package/dist/index.js.map +1 -1
  234. package/dist/navigation/app-link.d.ts +25 -0
  235. package/dist/navigation/app-link.d.ts.map +1 -0
  236. package/dist/navigation/app-link.js +33 -0
  237. package/dist/navigation/app-link.js.map +1 -0
  238. package/dist/navigation/context.d.ts +3 -20
  239. package/dist/navigation/context.d.ts.map +1 -1
  240. package/dist/navigation/context.js +7 -267
  241. package/dist/navigation/context.js.map +1 -1
  242. package/dist/navigation/entry-state.d.ts +23 -0
  243. package/dist/navigation/entry-state.d.ts.map +1 -0
  244. package/dist/navigation/entry-state.js +39 -0
  245. package/dist/navigation/entry-state.js.map +1 -0
  246. package/dist/navigation/guard-registry.d.ts +30 -0
  247. package/dist/navigation/guard-registry.d.ts.map +1 -0
  248. package/dist/navigation/guard-registry.js +46 -0
  249. package/dist/navigation/guard-registry.js.map +1 -0
  250. package/dist/navigation/guarded-navigation.d.ts +24 -0
  251. package/dist/navigation/guarded-navigation.d.ts.map +1 -0
  252. package/dist/navigation/guarded-navigation.js +102 -0
  253. package/dist/navigation/guarded-navigation.js.map +1 -0
  254. package/dist/navigation/index.d.ts +5 -4
  255. package/dist/navigation/index.d.ts.map +1 -1
  256. package/dist/navigation/index.js +2 -1
  257. package/dist/navigation/index.js.map +1 -1
  258. package/dist/navigation/types.d.ts +8 -11
  259. package/dist/navigation/types.d.ts.map +1 -1
  260. package/dist/navigation/use-back-forward-guard.d.ts +12 -0
  261. package/dist/navigation/use-back-forward-guard.d.ts.map +1 -0
  262. package/dist/navigation/use-back-forward-guard.js +75 -0
  263. package/dist/navigation/use-back-forward-guard.js.map +1 -0
  264. package/dist/navigation/use-search-commit.d.ts.map +1 -1
  265. package/dist/navigation/use-search-commit.js.map +1 -1
  266. package/dist/plugin/host-state.d.ts.map +1 -1
  267. package/dist/plugin/host-state.js.map +1 -1
  268. package/dist/plugin/registry.d.ts +6 -15
  269. package/dist/plugin/registry.d.ts.map +1 -1
  270. package/dist/plugin/registry.js +83 -75
  271. package/dist/plugin/registry.js.map +1 -1
  272. package/dist/schema-editor/SchemaEditor.d.ts.map +1 -1
  273. package/dist/schema-editor/SchemaEditor.js.map +1 -1
  274. package/dist/schema-editor/index.d.ts +3 -3
  275. package/dist/schema-editor/index.d.ts.map +1 -1
  276. package/dist/schema-editor/index.js +1 -6
  277. package/dist/schema-editor/index.js.map +1 -1
  278. package/dist/schema-form/SecretRefField.d.ts +18 -3
  279. package/dist/schema-form/SecretRefField.d.ts.map +1 -1
  280. package/dist/schema-form/SecretRefField.js +21 -26
  281. package/dist/schema-form/SecretRefField.js.map +1 -1
  282. package/dist/schema-form/classify.d.ts +1 -113
  283. package/dist/schema-form/classify.d.ts.map +1 -1
  284. package/dist/schema-form/classify.js +174 -246
  285. package/dist/schema-form/classify.js.map +1 -1
  286. package/dist/schema-form/context.d.ts +6 -0
  287. package/dist/schema-form/context.d.ts.map +1 -1
  288. package/dist/schema-form/context.js +0 -6
  289. package/dist/schema-form/context.js.map +1 -1
  290. package/dist/schema-form/default-value.d.ts.map +1 -1
  291. package/dist/schema-form/default-value.js +42 -19
  292. package/dist/schema-form/default-value.js.map +1 -1
  293. package/dist/schema-form/enum-field.d.ts +1 -1
  294. package/dist/schema-form/enum-field.d.ts.map +1 -1
  295. package/dist/schema-form/field-group.d.ts +6 -0
  296. package/dist/schema-form/field-group.d.ts.map +1 -1
  297. package/dist/schema-form/field-group.js +0 -6
  298. package/dist/schema-form/field-group.js.map +1 -1
  299. package/dist/schema-form/field-model.d.ts +121 -0
  300. package/dist/schema-form/field-model.d.ts.map +1 -0
  301. package/dist/schema-form/field-model.js +2 -0
  302. package/dist/schema-form/field-model.js.map +1 -0
  303. package/dist/schema-form/field-node.d.ts.map +1 -1
  304. package/dist/schema-form/field-node.js +25 -14
  305. package/dist/schema-form/field-node.js.map +1 -1
  306. package/dist/schema-form/index.d.ts +8 -8
  307. package/dist/schema-form/index.d.ts.map +1 -1
  308. package/dist/schema-form/index.js +3 -34
  309. package/dist/schema-form/index.js.map +1 -1
  310. package/dist/schema-form/json-field.d.ts +19 -0
  311. package/dist/schema-form/json-field.d.ts.map +1 -1
  312. package/dist/schema-form/json-field.js +0 -19
  313. package/dist/schema-form/json-field.js.map +1 -1
  314. package/dist/schema-form/media-field.d.ts +1 -1
  315. package/dist/schema-form/media-field.d.ts.map +1 -1
  316. package/dist/schema-form/media-field.js +49 -30
  317. package/dist/schema-form/media-field.js.map +1 -1
  318. package/dist/schema-form/record-field.d.ts +12 -0
  319. package/dist/schema-form/record-field.d.ts.map +1 -1
  320. package/dist/schema-form/record-field.js +1 -13
  321. package/dist/schema-form/record-field.js.map +1 -1
  322. package/dist/schema-form/string-annotations.d.ts +20 -0
  323. package/dist/schema-form/string-annotations.d.ts.map +1 -0
  324. package/dist/schema-form/string-annotations.js +105 -0
  325. package/dist/schema-form/string-annotations.js.map +1 -0
  326. package/dist/schema-form/string-field.d.ts +1 -1
  327. package/dist/schema-form/string-field.d.ts.map +1 -1
  328. package/dist/schema-form/string-field.js +1 -1
  329. package/dist/schema-form/string-field.js.map +1 -1
  330. package/dist/schema-form/union-field.d.ts +1 -1
  331. package/dist/schema-form/union-field.d.ts.map +1 -1
  332. package/dist/schema-form/union-field.js.map +1 -1
  333. package/dist/schema-form/union.d.ts +8 -1
  334. package/dist/schema-form/union.d.ts.map +1 -1
  335. package/dist/schema-form/union.js +0 -7
  336. package/dist/schema-form/union.js.map +1 -1
  337. package/dist/schema-form/validate.d.ts.map +1 -1
  338. package/dist/schema-form/validate.js +126 -105
  339. package/dist/schema-form/validate.js.map +1 -1
  340. package/dist/state-binding/AdapterMapping.d.ts.map +1 -1
  341. package/dist/state-binding/AdapterMapping.js +0 -0
  342. package/dist/state-binding/AdapterMapping.js.map +1 -1
  343. package/dist/state-binding/BindingJqField.d.ts.map +1 -1
  344. package/dist/state-binding/BindingJqField.js +2 -2
  345. package/dist/state-binding/BindingJqField.js.map +1 -1
  346. package/dist/state-binding/InputInjectionRow.d.ts.map +1 -1
  347. package/dist/state-binding/InputInjectionRow.js +3 -3
  348. package/dist/state-binding/InputInjectionRow.js.map +1 -1
  349. package/dist/state-binding/StateAttachRow.d.ts.map +1 -1
  350. package/dist/state-binding/StateAttachRow.js +57 -41
  351. package/dist/state-binding/StateAttachRow.js.map +1 -1
  352. package/dist/state-binding/StateBindingSection.d.ts.map +1 -1
  353. package/dist/state-binding/StateBindingSection.js.map +1 -1
  354. package/dist/state-binding/SubjectScopeFields.d.ts.map +1 -1
  355. package/dist/state-binding/SubjectScopeFields.js.map +1 -1
  356. package/dist/state-binding/UpdateRow.d.ts.map +1 -1
  357. package/dist/state-binding/UpdateRow.js +2 -2
  358. package/dist/state-binding/UpdateRow.js.map +1 -1
  359. package/dist/state-binding/adapter-mapping-row.d.ts +17 -0
  360. package/dist/state-binding/adapter-mapping-row.d.ts.map +1 -0
  361. package/dist/state-binding/adapter-mapping-row.js +87 -0
  362. package/dist/state-binding/adapter-mapping-row.js.map +1 -0
  363. package/dist/state-binding/index.d.ts +21 -21
  364. package/dist/state-binding/index.d.ts.map +1 -1
  365. package/dist/state-binding/index.js +9 -15
  366. package/dist/state-binding/index.js.map +1 -1
  367. package/dist/state-binding/templated-text-catalog.d.ts.map +1 -1
  368. package/dist/state-binding/templated-text-catalog.js.map +1 -1
  369. package/dist/state-binding/types.d.ts +2 -2
  370. package/dist/state-binding/types.d.ts.map +1 -1
  371. package/dist/structured-output/StructuredOutput.d.ts.map +1 -1
  372. package/dist/structured-output/StructuredOutput.js +1 -3
  373. package/dist/structured-output/StructuredOutput.js.map +1 -1
  374. package/package.json +2 -2
  375. package/src/components/code-block.tsx +1 -1
  376. package/src/components/confirm-dialog.tsx +1 -1
  377. package/src/components/copy-field.tsx +1 -1
  378. package/src/components/date-range-picker.tsx +1 -1
  379. package/src/components/dialog.tsx +1 -1
  380. package/src/components/dirty-guard.tsx +3 -3
  381. package/src/components/explorer-body.tsx +239 -0
  382. package/src/components/explorer-page-size.ts +39 -0
  383. package/src/components/explorer-tag-filter.tsx +80 -0
  384. package/src/components/explorer-tags.ts +64 -0
  385. package/src/components/explorer-view.tsx +115 -367
  386. package/src/components/extension-combo-builder.tsx +35 -153
  387. package/src/components/extension-combo-parts.tsx +236 -0
  388. package/src/components/field.tsx +1 -1
  389. package/src/components/fleet-report.tsx +98 -55
  390. package/src/components/folder-nav.tsx +2 -2
  391. package/src/components/form-dialog.tsx +2 -2
  392. package/src/components/icons/chrome-marks.tsx +195 -0
  393. package/src/components/icons/icon-frame.tsx +50 -0
  394. package/src/components/icons/index.ts +84 -0
  395. package/src/components/icons/nav-map.ts +55 -0
  396. package/src/components/icons/nav-marks.tsx +205 -0
  397. package/src/components/icons/status-marks.tsx +46 -0
  398. package/src/components/icons/theme-marks.tsx +33 -0
  399. package/src/components/inputs.tsx +1 -1
  400. package/src/components/json-diff.tsx +1 -4
  401. package/src/components/json-tree-context.ts +26 -0
  402. package/src/components/json-tree-model.ts +139 -0
  403. package/src/components/json-tree-nodes.tsx +224 -0
  404. package/src/components/json-tree.tsx +15 -434
  405. package/src/components/json-value-format.ts +64 -0
  406. package/src/components/markdown-blocks.ts +198 -0
  407. package/src/components/markdown-inline.tsx +365 -0
  408. package/src/components/markdown.tsx +6 -472
  409. package/src/components/observer-registry.ts +139 -0
  410. package/src/components/overflow-measure.ts +69 -0
  411. package/src/components/page-fill.tsx +1 -1
  412. package/src/components/prose-regions.ts +153 -0
  413. package/src/components/radio-group.tsx +1 -1
  414. package/src/components/scroll-region.tsx +22 -361
  415. package/src/components/tab-stop-parse.ts +217 -0
  416. package/src/components/table.tsx +1 -1
  417. package/src/components/tags.tsx +2 -2
  418. package/src/components/templated-text-field.tsx +39 -332
  419. package/src/components/templated-text-kwargs-editor.tsx +147 -0
  420. package/src/components/templated-text-kwargs.ts +92 -0
  421. package/src/components/templated-text-source.tsx +226 -0
  422. package/src/components/tool-picker-parts.tsx +184 -0
  423. package/src/components/tool-picker.tsx +22 -114
  424. package/src/components/version-history-panel.tsx +39 -143
  425. package/src/components/version-history-rows.tsx +220 -0
  426. package/src/components/view-toggle.tsx +1 -1
  427. package/src/element-slot.ts +1 -1
  428. package/src/guards.ts +7 -0
  429. package/src/hooks/interactions-connection.ts +227 -0
  430. package/src/hooks/interactions-stream.ts +274 -0
  431. package/src/hooks/useApi.ts +1 -1
  432. package/src/hooks/useAuth.ts +1 -1
  433. package/src/hooks/useCapabilities.ts +3 -3
  434. package/src/hooks/useSse.ts +51 -478
  435. package/src/hooks/useSystemKinds.tsx +2 -2
  436. package/src/hooks/useTheme.ts +1 -1
  437. package/src/hooks/useToolDisplayNames.tsx +2 -2
  438. package/src/host.ts +7 -7
  439. package/src/index.ts +292 -292
  440. package/src/navigation/app-link.tsx +70 -0
  441. package/src/navigation/context.tsx +12 -331
  442. package/src/navigation/entry-state.ts +42 -0
  443. package/src/navigation/guard-registry.ts +65 -0
  444. package/src/navigation/guarded-navigation.ts +147 -0
  445. package/src/navigation/index.ts +14 -14
  446. package/src/navigation/types.ts +8 -11
  447. package/src/navigation/use-back-forward-guard.ts +90 -0
  448. package/src/navigation/use-search-commit.ts +1 -1
  449. package/src/plugin/host-state.ts +1 -1
  450. package/src/plugin/registry.ts +111 -90
  451. package/src/schema-editor/SchemaEditor.tsx +1 -1
  452. package/src/schema-editor/index.ts +3 -3
  453. package/src/schema-form/SecretRefField.tsx +122 -72
  454. package/src/schema-form/classify.ts +245 -396
  455. package/src/schema-form/context.ts +1 -1
  456. package/src/schema-form/default-value.ts +48 -17
  457. package/src/schema-form/enum-field.tsx +1 -1
  458. package/src/schema-form/field-group.tsx +1 -1
  459. package/src/schema-form/field-model.ts +133 -0
  460. package/src/schema-form/field-node.tsx +95 -39
  461. package/src/schema-form/index.ts +10 -10
  462. package/src/schema-form/json-field.tsx +1 -1
  463. package/src/schema-form/media-field.tsx +136 -67
  464. package/src/schema-form/record-field.tsx +2 -2
  465. package/src/schema-form/string-annotations.ts +111 -0
  466. package/src/schema-form/string-field.tsx +2 -2
  467. package/src/schema-form/union-field.tsx +3 -2
  468. package/src/schema-form/union.ts +1 -1
  469. package/src/schema-form/validate.ts +185 -104
  470. package/src/state-binding/AdapterMapping.tsx +0 -0
  471. package/src/state-binding/BindingJqField.tsx +3 -3
  472. package/src/state-binding/InputInjectionRow.tsx +4 -4
  473. package/src/state-binding/StateAttachRow.tsx +229 -154
  474. package/src/state-binding/StateBindingSection.tsx +1 -1
  475. package/src/state-binding/SubjectScopeFields.tsx +1 -1
  476. package/src/state-binding/UpdateRow.tsx +3 -3
  477. package/src/state-binding/adapter-mapping-row.tsx +232 -0
  478. package/src/state-binding/index.ts +43 -43
  479. package/src/state-binding/templated-text-catalog.ts +0 -1
  480. package/src/state-binding/types.ts +2 -2
  481. package/src/structured-output/StructuredOutput.tsx +1 -4
  482. package/dist/components/icons.d.ts +0 -160
  483. package/dist/components/icons.d.ts.map +0 -1
  484. package/dist/components/icons.js +0 -160
  485. package/dist/components/icons.js.map +0 -1
  486. package/src/components/icons.tsx +0 -586
@@ -0,0 +1,147 @@
1
+ /**
2
+ * The render-parameters UI for `TemplatedTextField`: the add/remove editor
3
+ * (`KwargsEditor`) for editable values, and the read-only listing
4
+ * (`ReadOnlyKwargs`) shown beside a read-only stored id.
5
+ */
6
+ import { type ReactNode, useState } from 'react';
7
+
8
+ import { CloseIcon } from './icons';
9
+ import { TextInput } from './inputs';
10
+ import { Button } from './primitives';
11
+ import type { KwargRow } from './templated-text-kwargs';
12
+
13
+ /** The add/remove kwargs editor, revealed on demand and open when kwargs already exist. */
14
+ export function KwargsEditor({
15
+ label,
16
+ rows,
17
+ disabled,
18
+ onChange,
19
+ }: {
20
+ readonly label: string;
21
+ readonly rows: readonly KwargRow[];
22
+ readonly disabled: boolean;
23
+ readonly onChange: (rows: KwargRow[]) => void;
24
+ }): ReactNode {
25
+ const [open, setOpen] = useState(rows.length > 0);
26
+ const groupLabel = `${label} render parameters`;
27
+
28
+ if (!open) {
29
+ // Wrapped so the ghost button keeps its content width and stays left-aligned
30
+ // in the field's column, marking it as this field's own disclosure rather than
31
+ // a full-width control floating between two fields.
32
+ return (
33
+ <div>
34
+ <Button
35
+ type="button"
36
+ variant="ghost"
37
+ disabled={disabled}
38
+ onClick={() => {
39
+ setOpen(true);
40
+ onChange([...rows, { key: '', value: '' }]);
41
+ }}
42
+ >
43
+ Add render parameters
44
+ </Button>
45
+ </div>
46
+ );
47
+ }
48
+
49
+ return (
50
+ <div
51
+ role="group"
52
+ aria-label={groupLabel}
53
+ style={{ display: 'flex', flexDirection: 'column', gap: 'var(--tai-space-2)' }}
54
+ >
55
+ <span style={{ fontSize: 'var(--tai-text-sm)', color: 'var(--tai-color-text-muted)' }}>
56
+ Render parameters
57
+ </span>
58
+ {rows.map((row, index) => (
59
+ <div
60
+ key={index}
61
+ style={{ display: 'flex', gap: 'var(--tai-space-2)', alignItems: 'center' }}
62
+ >
63
+ <TextInput
64
+ aria-label={`${groupLabel} key ${String(index + 1)}`}
65
+ placeholder="name"
66
+ value={row.key}
67
+ autoComplete="off"
68
+ disabled={disabled}
69
+ onChange={(event) => {
70
+ const next = [...rows];
71
+ next[index] = { ...row, key: event.target.value };
72
+ onChange(next);
73
+ }}
74
+ />
75
+ <TextInput
76
+ aria-label={`${groupLabel} value ${String(index + 1)}`}
77
+ placeholder="value"
78
+ value={row.value}
79
+ autoComplete="off"
80
+ disabled={disabled}
81
+ onChange={(event) => {
82
+ const next = [...rows];
83
+ next[index] = { ...row, value: event.target.value };
84
+ onChange(next);
85
+ }}
86
+ />
87
+ <Button
88
+ type="button"
89
+ variant="ghost"
90
+ aria-label={`Remove ${groupLabel} ${String(index + 1)}`}
91
+ disabled={disabled}
92
+ onClick={() => {
93
+ onChange(rows.filter((_, position) => position !== index));
94
+ }}
95
+ >
96
+ <CloseIcon aria-hidden="true" />
97
+ </Button>
98
+ </div>
99
+ ))}
100
+ <div>
101
+ <Button
102
+ type="button"
103
+ variant="ghost"
104
+ disabled={disabled}
105
+ onClick={() => {
106
+ onChange([...rows, { key: '', value: '' }]);
107
+ }}
108
+ >
109
+ Add parameter
110
+ </Button>
111
+ </div>
112
+ </div>
113
+ );
114
+ }
115
+
116
+ /**
117
+ * The render parameters of a read-only stored value, as read-only text — the
118
+ * values in normal weight, NOT the muted disabled inputs a reader could mistake
119
+ * for empty placeholders. Renders nothing when there are no kwargs.
120
+ */
121
+ export function ReadOnlyKwargs({
122
+ label,
123
+ rows,
124
+ }: {
125
+ readonly label: string;
126
+ readonly rows: readonly KwargRow[];
127
+ }): ReactNode {
128
+ if (rows.length === 0) return null;
129
+ return (
130
+ <div
131
+ role="group"
132
+ aria-label={`${label} render parameters`}
133
+ style={{ display: 'flex', flexDirection: 'column', gap: 'var(--tai-space-1)' }}
134
+ >
135
+ <span style={{ fontSize: 'var(--tai-text-sm)', color: 'var(--tai-color-text-muted)' }}>
136
+ Render parameters
137
+ </span>
138
+ {rows.map((row) => (
139
+ <div key={row.key} style={{ fontFamily: 'var(--tai-font-mono)', wordBreak: 'break-all' }}>
140
+ <code>{row.key}</code>
141
+ <span style={{ color: 'var(--tai-color-text-muted)' }}>: </span>
142
+ <code>{row.value}</code>
143
+ </div>
144
+ ))}
145
+ </div>
146
+ );
147
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * The render-kwargs model behind `TemplatedTextField`: the row shape, the
3
+ * round-trip between stored kwargs and editable rows, and the normalized
4
+ * `TemplatedText` value the field emits. Pure — no React.
5
+ */
6
+ import type { TemplatedText } from '@tai42/api-client';
7
+
8
+ /** Whether the value's source is inline authored text or a stored template id. */
9
+ export type Mode = 'inline' | 'stored';
10
+
11
+ export interface KwargRow {
12
+ readonly key: string;
13
+ readonly value: string;
14
+ /**
15
+ * The stored value this row was seeded from, kept so an UNTOUCHED row re-emits it
16
+ * BYTE-FOR-BYTE: the row form cannot tell a stored string `"7"` from the number `7`,
17
+ * so re-parsing an untouched row would silently coerce the stored type. `undefined`
18
+ * for a row the author added.
19
+ */
20
+ readonly original?: unknown;
21
+ }
22
+
23
+ /** The row's canonical string form, matched against `value` to detect an untouched row. */
24
+ export function stringifyRowValue(raw: unknown): string {
25
+ return typeof raw === 'string' ? raw : JSON.stringify(raw);
26
+ }
27
+
28
+ /** Parse a cell as JSON when it can be (numbers/bools/objects), else keep the string. */
29
+ export function parseCellValue(raw: string): unknown {
30
+ const trimmed = raw.trim();
31
+ if (trimmed.length === 0) return '';
32
+ try {
33
+ return JSON.parse(trimmed);
34
+ } catch {
35
+ return raw;
36
+ }
37
+ }
38
+
39
+ /** Collapse the kwargs rows into an object, dropping rows with a blank key. */
40
+ export function rowsToObject(rows: readonly KwargRow[]): Record<string, unknown> {
41
+ const out: Record<string, unknown> = {};
42
+ for (const row of rows) {
43
+ const key = row.key.trim();
44
+ if (key.length === 0) continue;
45
+ // An untouched seeded row re-emits its stored value verbatim (no JSON-type coerce);
46
+ // an edited or added row is parsed from the cell text.
47
+ out[key] =
48
+ row.original !== undefined && stringifyRowValue(row.original) === row.value
49
+ ? row.original
50
+ : parseCellValue(row.value);
51
+ }
52
+ return out;
53
+ }
54
+
55
+ /** Seed rows from a stored kwargs object (stringifying non-string values). */
56
+ export function objectToRows(kwargs: Record<string, unknown> | undefined): KwargRow[] {
57
+ if (kwargs === undefined) return [];
58
+ return Object.entries(kwargs).map(([key, raw]) => ({
59
+ key,
60
+ value: stringifyRowValue(raw),
61
+ original: raw,
62
+ }));
63
+ }
64
+
65
+ /** The initial mode: stored when the seed carries an `id`, inline otherwise. */
66
+ export function initialMode(value: TemplatedText | null): Mode {
67
+ return value?.id !== undefined ? 'stored' : 'inline';
68
+ }
69
+
70
+ /**
71
+ * The normalized value for a given source/mode and kwargs. The two sources are
72
+ * mutually exclusive by construction (`content` XOR `id`); an empty source emits
73
+ * `null` unless `required`, in which case an empty source is emitted so the
74
+ * schema guard refuses the save.
75
+ */
76
+ export function templatedValueFrom(
77
+ mode: Mode,
78
+ inline: string,
79
+ stored: string,
80
+ rows: readonly KwargRow[],
81
+ required: boolean,
82
+ ): TemplatedText | null {
83
+ const kwargs = rowsToObject(rows);
84
+ const kw = Object.keys(kwargs).length > 0 ? { kwargs } : {};
85
+ if (mode === 'stored') {
86
+ const id = stored.trim();
87
+ if (id === '') return required ? { id: '', ...kw } : null;
88
+ return { id, ...kw };
89
+ }
90
+ if (inline.trim() === '') return required ? { content: '', ...kw } : null;
91
+ return { content: inline, ...kw };
92
+ }
@@ -0,0 +1,226 @@
1
+ /**
2
+ * The source region of `TemplatedTextField`: the inline/stored toggle and its
3
+ * editors while storage is present, a stand-in while presence is unknown, and the
4
+ * read-only stored reference (never converted, dropped, or blanked) when storage
5
+ * is absent.
6
+ */
7
+ import type { ReactNode } from 'react';
8
+
9
+ import { Field } from './field';
10
+ import { Textarea } from './inputs';
11
+ import { ErrorState, Skeleton } from './primitives';
12
+ import { RadioGroup } from './radio-group';
13
+ import { Select } from './select';
14
+ import type { TemplatedTextInlineProps, TemplatedTextTemplateOption } from './templated-text-field';
15
+ import type { Mode } from './templated-text-kwargs';
16
+
17
+ /** A labeled read-only reference to a stored template id, plus the note that
18
+ * stored templates are unavailable here — NOT an editable field. */
19
+ function ReadOnlyStoredReference({ id }: { readonly id: string }): ReactNode {
20
+ return (
21
+ <>
22
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--tai-space-1)' }}>
23
+ <span style={{ fontSize: 'var(--tai-text-sm)', color: 'var(--tai-color-text-muted)' }}>
24
+ Stored template
25
+ </span>
26
+ <code style={{ fontFamily: 'var(--tai-font-mono)', wordBreak: 'break-all' }}>{id}</code>
27
+ </div>
28
+ <p
29
+ style={{ margin: 0, fontSize: 'var(--tai-text-sm)', color: 'var(--tai-color-text-muted)' }}
30
+ >
31
+ Stored templates are unavailable — this deployment has no storage backend.
32
+ </p>
33
+ </>
34
+ );
35
+ }
36
+
37
+ interface PresentStorageSourceProps {
38
+ readonly label: string;
39
+ readonly mode: Mode;
40
+ readonly disabled: boolean;
41
+ readonly inlineEditor: ReactNode;
42
+ readonly error?: string;
43
+ readonly storedDraft: string;
44
+ readonly templates: readonly TemplatedTextTemplateOption[];
45
+ readonly templateOptions: readonly { value: string; label: string }[];
46
+ readonly templatesLoading: boolean;
47
+ readonly templatesError?: string;
48
+ readonly onTemplatesRetry?: () => void;
49
+ readonly unresolvedId?: string;
50
+ readonly resolveError?: string;
51
+ readonly onModeChange: (mode: Mode) => void;
52
+ readonly onStoredChange: (stored: string) => void;
53
+ }
54
+
55
+ /** The inline/stored toggle, the mode's editor, and the unresolved-id note, for
56
+ * the storage-present configuration. */
57
+ function PresentStorageSource({
58
+ label,
59
+ mode,
60
+ disabled,
61
+ inlineEditor,
62
+ error,
63
+ storedDraft,
64
+ templates,
65
+ templateOptions,
66
+ templatesLoading,
67
+ templatesError,
68
+ onTemplatesRetry,
69
+ unresolvedId,
70
+ resolveError,
71
+ onModeChange,
72
+ onStoredChange,
73
+ }: PresentStorageSourceProps): ReactNode {
74
+ return (
75
+ <>
76
+ <RadioGroup
77
+ aria-label={`${label} source`}
78
+ variant="segmented"
79
+ value={mode}
80
+ disabled={disabled}
81
+ options={[
82
+ { value: 'inline', label: 'Inline text' },
83
+ { value: 'stored', label: 'Stored template' },
84
+ ]}
85
+ onValueChange={(next) => {
86
+ onModeChange(next as Mode);
87
+ }}
88
+ />
89
+
90
+ {mode === 'inline' ? (
91
+ inlineEditor
92
+ ) : templatesError !== undefined ? (
93
+ <ErrorState message={templatesError} onRetry={onTemplatesRetry} />
94
+ ) : templatesLoading ? (
95
+ <Skeleton height={36} />
96
+ ) : (
97
+ <Field label={label} hideLabel error={error}>
98
+ <Select
99
+ placeholder={templates.length === 0 ? 'No templates available' : 'Select a template'}
100
+ value={storedDraft}
101
+ disabled={disabled || templates.length === 0}
102
+ options={templateOptions}
103
+ onValueChange={onStoredChange}
104
+ />
105
+ </Field>
106
+ )}
107
+
108
+ {unresolvedId !== undefined ? (
109
+ <p role="alert" style={{ margin: 0, color: 'var(--tai-color-err-text)' }}>
110
+ {resolveError ?? `The stored template "${unresolvedId}" is not available.`}
111
+ </p>
112
+ ) : null}
113
+ </>
114
+ );
115
+ }
116
+
117
+ export interface TemplatedTextSourceProps {
118
+ readonly label: string;
119
+ readonly mode: Mode;
120
+ readonly inlineDraft: string;
121
+ readonly storedDraft: string;
122
+ readonly error?: string;
123
+ readonly disabled: boolean;
124
+ readonly placeholder?: string;
125
+ readonly renderInline?: (props: TemplatedTextInlineProps) => ReactNode;
126
+ readonly templates: readonly TemplatedTextTemplateOption[];
127
+ readonly templatesLoading: boolean;
128
+ readonly templatesError?: string;
129
+ readonly onTemplatesRetry?: () => void;
130
+ readonly resolveError?: string;
131
+ readonly storageAbsent: boolean;
132
+ readonly storagePresenceLoading: boolean;
133
+ /** The `id` already authored on the value, shown read-only when storage is absent. */
134
+ readonly authoredStoredId?: string;
135
+ readonly onModeChange: (mode: Mode) => void;
136
+ readonly onInlineChange: (value: string) => void;
137
+ readonly onStoredChange: (stored: string) => void;
138
+ }
139
+
140
+ export function TemplatedTextSource({
141
+ label,
142
+ mode,
143
+ inlineDraft,
144
+ storedDraft,
145
+ error,
146
+ disabled,
147
+ placeholder,
148
+ renderInline,
149
+ templates,
150
+ templatesLoading,
151
+ templatesError,
152
+ onTemplatesRetry,
153
+ resolveError,
154
+ storageAbsent,
155
+ storagePresenceLoading,
156
+ authoredStoredId,
157
+ onModeChange,
158
+ onInlineChange,
159
+ onStoredChange,
160
+ }: TemplatedTextSourceProps): ReactNode {
161
+ const templateOptions = templates.map((template) => ({
162
+ value: template.id,
163
+ label: template.label ?? template.id,
164
+ }));
165
+ // A stored id the catalog does not offer cannot be picked from the list; it is
166
+ // shown as an unresolved note rather than silently blanked.
167
+ const unresolvedId =
168
+ mode === 'stored' &&
169
+ storedDraft.trim() !== '' &&
170
+ !templatesLoading &&
171
+ templatesError === undefined &&
172
+ !templates.some((template) => template.id === storedDraft.trim())
173
+ ? storedDraft.trim()
174
+ : undefined;
175
+
176
+ // The inline editor, shared by the present-storage inline mode and the
177
+ // absent-storage inline-only rendering: the caller's rich editor when supplied,
178
+ // else a plain textarea.
179
+ const inlineEditor =
180
+ renderInline !== undefined ? (
181
+ renderInline({ label, value: inlineDraft, onChange: onInlineChange, error, hideLabel: true })
182
+ ) : (
183
+ <Field label={label} hideLabel error={error}>
184
+ <Textarea
185
+ value={inlineDraft}
186
+ placeholder={placeholder}
187
+ disabled={disabled}
188
+ onChange={(event) => {
189
+ onInlineChange(event.target.value);
190
+ }}
191
+ />
192
+ </Field>
193
+ );
194
+
195
+ // While presence is unknown a placeholder stands in, so the toggle is never
196
+ // shown and then removed. With storage absent the stored source cannot work and
197
+ // is not offered: an inline or empty value edits inline; a value carrying an
198
+ // `id` is shown read-only. With storage present the full toggle and picker render.
199
+ if (storagePresenceLoading) return <Skeleton height={36} />;
200
+ if (storageAbsent) {
201
+ return authoredStoredId !== undefined ? (
202
+ <ReadOnlyStoredReference id={authoredStoredId} />
203
+ ) : (
204
+ inlineEditor
205
+ );
206
+ }
207
+ return (
208
+ <PresentStorageSource
209
+ label={label}
210
+ mode={mode}
211
+ disabled={disabled}
212
+ inlineEditor={inlineEditor}
213
+ error={error}
214
+ storedDraft={storedDraft}
215
+ templates={templates}
216
+ templateOptions={templateOptions}
217
+ templatesLoading={templatesLoading}
218
+ templatesError={templatesError}
219
+ onTemplatesRetry={onTemplatesRetry}
220
+ unresolvedId={unresolvedId}
221
+ resolveError={resolveError}
222
+ onModeChange={onModeChange}
223
+ onStoredChange={onStoredChange}
224
+ />
225
+ );
226
+ }
@@ -0,0 +1,184 @@
1
+ /**
2
+ * The pieces of `ToolPicker`: the tool `Select` itself (grouped or flat), the tag
3
+ * filter field, and the selected tool's capability badges. The picker owns the
4
+ * state and composes these; the option-label and grouping helpers live here too.
5
+ */
6
+ import type { ReactNode } from 'react';
7
+
8
+ import { toolDisplayLabel } from '../hooks/useToolDisplayNames';
9
+ import { Badge } from './badge';
10
+ import { Field } from './field';
11
+ import { Select, type SelectGroup } from './select';
12
+ import { Tooltip } from './tooltip';
13
+
14
+ /** The shared informational note every badge surface carries: declared, never enforced. */
15
+ export const BADGES_NOTE =
16
+ 'Declared capability labels — informational only. They describe what the tool touches; the server never enforces them.';
17
+
18
+ const NO_DISPLAY_NAMES: Readonly<Record<string, string>> = {};
19
+ const UNTAGGED = 'Untagged';
20
+ // Radix `Select.Item` forbids an empty-string value, so the "no filter" choice
21
+ // uses a sentinel rather than ''. A tool literally tagged this string would just
22
+ // never be filtered out — harmless for a UI convenience whose authority is the server.
23
+ export const ALL_TAGS = '__all_tags__';
24
+
25
+ /** The group a tool sorts into: its alphabetically-first tag, else "Untagged". */
26
+ function groupFor(name: string, tagsByTool: Readonly<Record<string, readonly string[]>>): string {
27
+ const tags = [...(tagsByTool[name] ?? [])].sort((a, b) => a.localeCompare(b));
28
+ return tags[0] ?? UNTAGGED;
29
+ }
30
+
31
+ /**
32
+ * The option label: `Display Name (raw)` when a distinct non-empty display name maps
33
+ * the name, else the bare name; either way suffixed " (agent)" for an agent run tool.
34
+ */
35
+ function optionLabel(
36
+ name: string,
37
+ displayNames: Readonly<Record<string, string>> | undefined,
38
+ agentToolNames: ReadonlySet<string> | undefined,
39
+ ): string {
40
+ const base = toolDisplayLabel(displayNames ?? NO_DISPLAY_NAMES, name);
41
+ return agentToolNames?.has(name) === true ? `${base} (agent)` : base;
42
+ }
43
+
44
+ /** Build the grouped option clusters (sorted group labels, "Untagged" last). */
45
+ function buildGroups(
46
+ names: readonly string[],
47
+ tagsByTool: Readonly<Record<string, readonly string[]>>,
48
+ displayNames: Readonly<Record<string, string>> | undefined,
49
+ agentToolNames: ReadonlySet<string> | undefined,
50
+ ): SelectGroup[] {
51
+ const byGroup = new Map<string, string[]>();
52
+ for (const name of names) {
53
+ const group = groupFor(name, tagsByTool);
54
+ const bucket = byGroup.get(group) ?? [];
55
+ bucket.push(name);
56
+ byGroup.set(group, bucket);
57
+ }
58
+ return [...byGroup.entries()]
59
+ .sort(([a], [b]) => {
60
+ if (a === UNTAGGED) return 1;
61
+ if (b === UNTAGGED) return -1;
62
+ return a.localeCompare(b);
63
+ })
64
+ .map(([label, groupNames]) => ({
65
+ label,
66
+ options: groupNames.map((name) => ({
67
+ value: name,
68
+ label: optionLabel(name, displayNames, agentToolNames),
69
+ })),
70
+ }));
71
+ }
72
+
73
+ interface ToolSelectProps {
74
+ readonly tagsByTool: Readonly<Record<string, readonly string[]>> | undefined;
75
+ readonly filtered: readonly string[];
76
+ readonly value: string | null;
77
+ readonly onChange: (toolName: string) => void;
78
+ readonly placeholder: string;
79
+ readonly ariaLabel: string | undefined;
80
+ readonly disabled: boolean | undefined;
81
+ readonly displayNames: Readonly<Record<string, string>> | undefined;
82
+ readonly agentToolNames: ReadonlySet<string> | undefined;
83
+ }
84
+
85
+ /** The tool select: grouped by tag when `tagsByTool` is present, else a flat list.
86
+ * Either branch is a `Select`, which claims the enclosing `Field`'s control id. */
87
+ export function ToolSelect({
88
+ tagsByTool,
89
+ filtered,
90
+ value,
91
+ onChange,
92
+ placeholder,
93
+ ariaLabel,
94
+ disabled,
95
+ displayNames,
96
+ agentToolNames,
97
+ }: ToolSelectProps): ReactNode {
98
+ if (tagsByTool !== undefined) {
99
+ return (
100
+ <Select
101
+ groups={buildGroups(filtered, tagsByTool, displayNames, agentToolNames)}
102
+ value={value ?? ''}
103
+ onValueChange={onChange}
104
+ placeholder={placeholder}
105
+ aria-label={ariaLabel}
106
+ disabled={disabled}
107
+ />
108
+ );
109
+ }
110
+ return (
111
+ <Select
112
+ // Keep Radix controlled even when the caller's value is null: `''` matches no
113
+ // item (placeholder still shows) and avoids the uncontrolled→controlled warning
114
+ // a subsequent selection would otherwise trigger.
115
+ options={filtered.map((name) => ({
116
+ value: name,
117
+ label: optionLabel(name, displayNames, agentToolNames),
118
+ }))}
119
+ value={value ?? ''}
120
+ onValueChange={onChange}
121
+ placeholder={placeholder}
122
+ aria-label={ariaLabel}
123
+ disabled={disabled}
124
+ />
125
+ );
126
+ }
127
+
128
+ /** The tag filter: an "All tags" sentinel plus one option per distinct tag. */
129
+ export function TagFilterField({
130
+ allTags,
131
+ tagFilter,
132
+ onTagFilterChange,
133
+ disabled,
134
+ }: {
135
+ readonly allTags: readonly string[];
136
+ readonly tagFilter: string;
137
+ readonly onTagFilterChange: (value: string) => void;
138
+ readonly disabled: boolean | undefined;
139
+ }): ReactNode {
140
+ return (
141
+ <Field label="Filter by tag">
142
+ <Select
143
+ options={[
144
+ { value: ALL_TAGS, label: 'All tags' },
145
+ ...allTags.map((tag) => ({ value: tag, label: tag })),
146
+ ]}
147
+ value={tagFilter}
148
+ onValueChange={onTagFilterChange}
149
+ disabled={disabled}
150
+ />
151
+ </Field>
152
+ );
153
+ }
154
+
155
+ /** The selected tool's DECLARED capability badges, read-only and informational.
156
+ * Renders nothing unless the selected tool carries badges. */
157
+ export function SelectedToolBadges({
158
+ value,
159
+ badgesByTool,
160
+ idPrefix,
161
+ }: {
162
+ readonly value: string | null;
163
+ readonly badgesByTool: Readonly<Record<string, readonly string[]>> | undefined;
164
+ readonly idPrefix: string;
165
+ }): ReactNode {
166
+ if (value === null || badgesByTool === undefined || (badgesByTool[value]?.length ?? 0) === 0) {
167
+ return null;
168
+ }
169
+ return (
170
+ <Tooltip content={BADGES_NOTE}>
171
+ <span
172
+ className="tai-row"
173
+ data-testid={`${idPrefix}-badges`}
174
+ style={{ gap: 'var(--tai-space-1)' }}
175
+ >
176
+ {(badgesByTool[value] ?? []).map((badge) => (
177
+ <Badge key={badge} variant="neutral">
178
+ {badge}
179
+ </Badge>
180
+ ))}
181
+ </span>
182
+ </Tooltip>
183
+ );
184
+ }