@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
@@ -34,25 +34,20 @@
34
34
  *
35
35
  * SAFETY: an extension name is server-supplied, so every name renders as TEXT through
36
36
  * the DS `Badge`/`Checkbox` (React escapes it) — never an HTML sink.
37
- *
38
- * Geometry and ink come from the design-system classes: each committed combo is a
39
- * `tai-card` row, the invalid notes are `tai-field-error` (icon + message, never
40
- * color alone), and Remove is a labelled `Button` carrying `CloseIcon` beside the
41
- * word, under an accessible name that names the combo it removes.
42
37
  */
43
- import { Fragment, useEffect, useState, type ReactNode } from 'react';
44
-
45
38
  import type { Extension, PresetExtensionElement } from '@tai42/api-client';
39
+ import { type ReactNode, useEffect, useState } from 'react';
46
40
 
47
41
  import { comboElementNames, extensionElementName } from '../extension-combos';
48
- import { SchemaEditor, type SchemaEditorChange } from '../schema-editor';
49
- import { Badge } from './badge';
50
- import { ExtensionPicker } from './extension-picker';
51
- import { CloseIcon, XCircleIcon } from './icons';
52
- import { Button } from './primitives';
53
-
54
- /** The one config-taking extension this builder authors inline. */
55
- const OUTPUT_SCHEMA = 'output_schema';
42
+ import { type SchemaEditorChange } from '../schema-editor';
43
+ import {
44
+ ComboDraftEditor,
45
+ CommittedComboList,
46
+ OUTPUT_SCHEMA,
47
+ outputSchemaConfig,
48
+ sameNames,
49
+ unknownNames,
50
+ } from './extension-combo-parts';
56
51
 
57
52
  export interface ExtensionComboBuilderProps {
58
53
  /** The extension catalog the combos are drawn from (caller-fetched). */
@@ -79,34 +74,6 @@ export interface ExtensionComboBuilderProps {
79
74
  readonly availableReady?: boolean;
80
75
  }
81
76
 
82
- /** Two combos are equal when their NAME sequences match (config is not part of identity). */
83
- function sameNames(a: readonly string[], b: readonly string[]): boolean {
84
- return a.length === b.length && a.every((name, index) => name === b[index]);
85
- }
86
-
87
- /** The stored `output_schema` config schema for a combo, if it carries one. */
88
- function outputSchemaConfig(
89
- combo: readonly PresetExtensionElement[],
90
- ): Record<string, unknown> | null {
91
- for (const element of combo) {
92
- if (typeof element !== 'string' && element.name === OUTPUT_SCHEMA) {
93
- const schema = element.config.schema;
94
- return typeof schema === 'object' && schema !== null && !Array.isArray(schema)
95
- ? (schema as Record<string, unknown>)
96
- : {};
97
- }
98
- }
99
- return null;
100
- }
101
-
102
- /** The element names in a combo that are absent from the known catalog. */
103
- function unknownNames(
104
- combo: readonly PresetExtensionElement[],
105
- availableNames: ReadonlySet<string>,
106
- ): string[] {
107
- return comboElementNames(combo).filter((name) => !availableNames.has(name));
108
- }
109
-
110
77
  export function ExtensionComboBuilder({
111
78
  available,
112
79
  value,
@@ -192,116 +159,31 @@ export function ExtensionComboBuilder({
192
159
 
193
160
  return (
194
161
  <div data-testid={idPrefix} className="tai-stack">
195
- {value.length > 0 ? (
196
- <ul className="tai-stack tai-stack-2">
197
- {value.map((combo, index) => {
198
- const names = comboElementNames(combo);
199
- const unknown = availableReady ? unknownNames(combo, availableNames) : [];
200
- return (
201
- // The index IS the identity here: the list mutates by append, in-place
202
- // update, and remove-by-index (no reorder), and a combo has no stable id
203
- // of its own — so an index key is stable and cannot collide.
204
- <li key={index} className="tai-card tai-stack tai-stack-2">
205
- <div className="tai-row">
206
- {/* The badges take the row's spare width so the Edit/Remove pair
207
- pins to a stable trailing edge across combos of varied length. */}
208
- <span className="tai-row" style={{ flex: 1 }}>
209
- {names.map((name, position) => (
210
- <Fragment key={`${name}-${String(position)}`}>
211
- {position > 0 ? (
212
- <span aria-hidden className="tai-muted">
213
- +
214
- </span>
215
- ) : null}
216
- <Badge variant={unknown.includes(name) ? 'danger' : 'primary'}>
217
- {name}
218
- </Badge>
219
- </Fragment>
220
- ))}
221
- </span>
222
- <Button
223
- type="button"
224
- // The name starts with the words the button is SHOWING, which
225
- // is what WCAG 2.5.3 (Label in Name) asks: a constant "Edit …"
226
- // would leave a button reading "Editing" named "Edit", and a
227
- // voice-control user naming a control they cannot see.
228
- aria-label={`${editing === index ? 'Editing' : 'Edit'} extension set ${names.join('+')}`}
229
- disabled={disabled === true || editing === index}
230
- onClick={() => {
231
- startEdit(index);
232
- }}
233
- >
234
- {editing === index ? 'Editing' : 'Edit'}
235
- </Button>
236
- <Button
237
- type="button"
238
- aria-label={`Remove extension set ${names.join('+')}`}
239
- disabled={disabled}
240
- onClick={() => {
241
- removeCombo(index);
242
- }}
243
- >
244
- <CloseIcon />
245
- Remove
246
- </Button>
247
- </div>
248
- {unknown.length > 0 ? (
249
- <p role="alert" className="tai-field-error">
250
- <XCircleIcon />
251
- {unknown.length === 1 ? 'Unknown extension: ' : 'Unknown extensions: '}
252
- {unknown.join(', ')}.
253
- </p>
254
- ) : null}
255
- </li>
256
- );
257
- })}
258
- </ul>
259
- ) : (
260
- <p className="tai-muted">No extension sets.</p>
261
- )}
262
-
263
- <div className="tai-stack tai-stack-2">
264
- <ExtensionPicker
265
- available={available}
266
- value={draft}
267
- onChange={setDraft}
268
- disabled={disabled}
269
- idPrefix={`${idPrefix}-draft`}
270
- />
271
-
272
- {draftHasOutputSchema ? (
273
- <SchemaEditor
274
- value={draftConfig.schema}
275
- onChange={setDraftConfig}
276
- requireTitle={false}
277
- label="Output schema"
278
- description="The JSON Schema the output_schema extension enforces on this extension set's result."
279
- disabled={disabled}
280
- idPrefix={`${idPrefix}-output-schema`}
281
- // Re-seed the editor when the draft target changes (a new draft vs a
282
- // specific combo pulled in for edit).
283
- key={editing === null ? 'new' : `edit-${String(editing)}`}
284
- />
285
- ) : null}
286
-
287
- {isDuplicate ? (
288
- <p role="alert" className="tai-field-error">
289
- <XCircleIcon />
290
- This extension set is already added.
291
- </p>
292
- ) : null}
293
-
294
- <div className="tai-row">
295
- <Button type="button" variant="primary" onClick={commitCombo} disabled={!canAdd}>
296
- {editing === null ? 'Add extension set' : 'Update extension set'}
297
- </Button>
298
- {editing !== null ? (
299
- <Button type="button" onClick={resetDraft} disabled={disabled}>
300
- Cancel edit
301
- </Button>
302
- ) : null}
303
- </div>
304
- </div>
162
+ <CommittedComboList
163
+ value={value}
164
+ availableReady={availableReady}
165
+ availableNames={availableNames}
166
+ editing={editing}
167
+ disabled={disabled}
168
+ onEdit={startEdit}
169
+ onRemove={removeCombo}
170
+ />
171
+
172
+ <ComboDraftEditor
173
+ available={available}
174
+ draft={draft}
175
+ onDraftChange={setDraft}
176
+ draftHasOutputSchema={draftHasOutputSchema}
177
+ draftConfig={draftConfig}
178
+ onDraftConfigChange={setDraftConfig}
179
+ isDuplicate={isDuplicate}
180
+ canAdd={canAdd}
181
+ editing={editing}
182
+ disabled={disabled}
183
+ idPrefix={idPrefix}
184
+ onCommit={commitCombo}
185
+ onReset={resetDraft}
186
+ />
305
187
  </div>
306
188
  );
307
189
  }
@@ -0,0 +1,236 @@
1
+ /**
2
+ * The pieces of `ExtensionComboBuilder`: the committed-combo list
3
+ * (`CommittedComboList`), the under-construction combo editor (`ComboDraftEditor`),
4
+ * and the shared combo helpers. The builder owns the state and composes these.
5
+ */
6
+ import type { Extension, PresetExtensionElement } from '@tai42/api-client';
7
+ import { Fragment, type ReactNode } from 'react';
8
+
9
+ import { comboElementNames } from '../extension-combos';
10
+ import { SchemaEditor, type SchemaEditorChange } from '../schema-editor';
11
+ import { Badge } from './badge';
12
+ import { ExtensionPicker } from './extension-picker';
13
+ import { CloseIcon, XCircleIcon } from './icons';
14
+ import { Button } from './primitives';
15
+
16
+ /** The one config-taking extension this builder authors inline. */
17
+ export const OUTPUT_SCHEMA = 'output_schema';
18
+
19
+ /** Two combos are equal when their NAME sequences match (config is not part of identity). */
20
+ export function sameNames(a: readonly string[], b: readonly string[]): boolean {
21
+ return a.length === b.length && a.every((name, index) => name === b[index]);
22
+ }
23
+
24
+ /** The stored `output_schema` config schema for a combo, if it carries one. */
25
+ export function outputSchemaConfig(
26
+ combo: readonly PresetExtensionElement[],
27
+ ): Record<string, unknown> | null {
28
+ for (const element of combo) {
29
+ if (typeof element !== 'string' && element.name === OUTPUT_SCHEMA) {
30
+ const schema = element.config.schema;
31
+ return typeof schema === 'object' && schema !== null && !Array.isArray(schema)
32
+ ? (schema as Record<string, unknown>)
33
+ : {};
34
+ }
35
+ }
36
+ return null;
37
+ }
38
+
39
+ /** The element names in a combo that are absent from the known catalog. */
40
+ export function unknownNames(
41
+ combo: readonly PresetExtensionElement[],
42
+ availableNames: ReadonlySet<string>,
43
+ ): string[] {
44
+ return comboElementNames(combo).filter((name) => !availableNames.has(name));
45
+ }
46
+
47
+ /** One committed combo's row: its name badges and the Edit / Remove pair, with an
48
+ * inline unknown-name note. */
49
+ function CommittedComboRow({
50
+ combo,
51
+ index,
52
+ editing,
53
+ disabled,
54
+ unknown,
55
+ onEdit,
56
+ onRemove,
57
+ }: {
58
+ readonly combo: readonly PresetExtensionElement[];
59
+ readonly index: number;
60
+ readonly editing: number | null;
61
+ readonly disabled: boolean | undefined;
62
+ readonly unknown: readonly string[];
63
+ readonly onEdit: (index: number) => void;
64
+ readonly onRemove: (index: number) => void;
65
+ }): ReactNode {
66
+ const names = comboElementNames(combo);
67
+ return (
68
+ <li className="tai-card tai-stack tai-stack-2">
69
+ <div className="tai-row">
70
+ {/* The badges take the row's spare width so the Edit/Remove pair pins to a
71
+ stable trailing edge across combos of varied length. */}
72
+ <span className="tai-row" style={{ flex: 1 }}>
73
+ {names.map((name, position) => (
74
+ <Fragment key={`${name}-${String(position)}`}>
75
+ {position > 0 ? (
76
+ <span aria-hidden className="tai-muted">
77
+ +
78
+ </span>
79
+ ) : null}
80
+ <Badge variant={unknown.includes(name) ? 'danger' : 'primary'}>{name}</Badge>
81
+ </Fragment>
82
+ ))}
83
+ </span>
84
+ <Button
85
+ type="button"
86
+ // The name starts with the words the button is SHOWING, which is what WCAG
87
+ // 2.5.3 (Label in Name) asks: a constant "Edit …" would leave a button
88
+ // reading "Editing" named "Edit", and a voice-control user naming a control
89
+ // they cannot see.
90
+ aria-label={`${editing === index ? 'Editing' : 'Edit'} extension set ${names.join('+')}`}
91
+ disabled={disabled === true || editing === index}
92
+ onClick={() => {
93
+ onEdit(index);
94
+ }}
95
+ >
96
+ {editing === index ? 'Editing' : 'Edit'}
97
+ </Button>
98
+ <Button
99
+ type="button"
100
+ aria-label={`Remove extension set ${names.join('+')}`}
101
+ disabled={disabled}
102
+ onClick={() => {
103
+ onRemove(index);
104
+ }}
105
+ >
106
+ <CloseIcon />
107
+ Remove
108
+ </Button>
109
+ </div>
110
+ {unknown.length > 0 ? (
111
+ <p role="alert" className="tai-field-error">
112
+ <XCircleIcon />
113
+ {unknown.length === 1 ? 'Unknown extension: ' : 'Unknown extensions: '}
114
+ {unknown.join(', ')}.
115
+ </p>
116
+ ) : null}
117
+ </li>
118
+ );
119
+ }
120
+
121
+ /** The current combos, each a row of name badges with per-combo Edit and Remove. */
122
+ export function CommittedComboList({
123
+ value,
124
+ availableReady,
125
+ availableNames,
126
+ editing,
127
+ disabled,
128
+ onEdit,
129
+ onRemove,
130
+ }: {
131
+ readonly value: readonly PresetExtensionElement[][];
132
+ readonly availableReady: boolean;
133
+ readonly availableNames: ReadonlySet<string>;
134
+ readonly editing: number | null;
135
+ readonly disabled: boolean | undefined;
136
+ readonly onEdit: (index: number) => void;
137
+ readonly onRemove: (index: number) => void;
138
+ }): ReactNode {
139
+ if (value.length === 0) return <p className="tai-muted">No extension sets.</p>;
140
+ return (
141
+ <ul className="tai-stack tai-stack-2">
142
+ {value.map((combo, index) => (
143
+ // The index IS the identity here: the list mutates by append, in-place update,
144
+ // and remove-by-index (no reorder), and a combo has no stable id of its own —
145
+ // so an index key is stable and cannot collide.
146
+ <CommittedComboRow
147
+ key={index}
148
+ combo={combo}
149
+ index={index}
150
+ editing={editing}
151
+ disabled={disabled}
152
+ unknown={availableReady ? unknownNames(combo, availableNames) : []}
153
+ onEdit={onEdit}
154
+ onRemove={onRemove}
155
+ />
156
+ ))}
157
+ </ul>
158
+ );
159
+ }
160
+
161
+ /** The combo under construction: the extension picker, the inline output-schema
162
+ * editor when present, the duplicate note, and the Add/Update + Cancel actions. */
163
+ export function ComboDraftEditor({
164
+ available,
165
+ draft,
166
+ onDraftChange,
167
+ draftHasOutputSchema,
168
+ draftConfig,
169
+ onDraftConfigChange,
170
+ isDuplicate,
171
+ canAdd,
172
+ editing,
173
+ disabled,
174
+ idPrefix,
175
+ onCommit,
176
+ onReset,
177
+ }: {
178
+ readonly available: readonly Extension[];
179
+ readonly draft: string[];
180
+ readonly onDraftChange: (draft: string[]) => void;
181
+ readonly draftHasOutputSchema: boolean;
182
+ readonly draftConfig: SchemaEditorChange;
183
+ readonly onDraftConfigChange: (change: SchemaEditorChange) => void;
184
+ readonly isDuplicate: boolean;
185
+ readonly canAdd: boolean;
186
+ readonly editing: number | null;
187
+ readonly disabled: boolean | undefined;
188
+ readonly idPrefix: string;
189
+ readonly onCommit: () => void;
190
+ readonly onReset: () => void;
191
+ }): ReactNode {
192
+ return (
193
+ <div className="tai-stack tai-stack-2">
194
+ <ExtensionPicker
195
+ available={available}
196
+ value={draft}
197
+ onChange={onDraftChange}
198
+ disabled={disabled}
199
+ idPrefix={`${idPrefix}-draft`}
200
+ />
201
+
202
+ {draftHasOutputSchema ? (
203
+ <SchemaEditor
204
+ value={draftConfig.schema}
205
+ onChange={onDraftConfigChange}
206
+ requireTitle={false}
207
+ label="Output schema"
208
+ description="The JSON Schema the output_schema extension enforces on this extension set's result."
209
+ disabled={disabled}
210
+ idPrefix={`${idPrefix}-output-schema`}
211
+ // Re-seed the editor when the draft target changes (a new draft vs a
212
+ // specific combo pulled in for edit).
213
+ key={editing === null ? 'new' : `edit-${String(editing)}`}
214
+ />
215
+ ) : null}
216
+
217
+ {isDuplicate ? (
218
+ <p role="alert" className="tai-field-error">
219
+ <XCircleIcon />
220
+ This extension set is already added.
221
+ </p>
222
+ ) : null}
223
+
224
+ <div className="tai-row">
225
+ <Button type="button" variant="primary" onClick={onCommit} disabled={!canAdd}>
226
+ {editing === null ? 'Add extension set' : 'Update extension set'}
227
+ </Button>
228
+ {editing !== null ? (
229
+ <Button type="button" onClick={onReset} disabled={disabled}>
230
+ Cancel edit
231
+ </Button>
232
+ ) : null}
233
+ </div>
234
+ </div>
235
+ );
236
+ }
@@ -6,8 +6,8 @@
6
6
  * `aria-describedby`, and its `aria-invalid` stay wired without the caller
7
7
  * threading ids by hand.
8
8
  */
9
- import { createContext, useContext, useId } from 'react';
10
9
  import type { CSSProperties, ReactNode } from 'react';
10
+ import { createContext, useContext, useId } from 'react';
11
11
 
12
12
  import { XCircleIcon } from './icons';
13
13
 
@@ -27,10 +27,14 @@
27
27
  * icon MARK plus a word LABEL, with the tone color only reinforcing them, so the
28
28
  * report is readable without color perception.
29
29
  */
30
+ import type {
31
+ FleetFailureOutcome,
32
+ FleetReportSummary,
33
+ FleetWorkerFailure,
34
+ } from '@tai42/api-client';
30
35
  import type { ReactNode } from 'react';
31
- import type { FleetReportSummary, FleetFailureOutcome } from '@tai42/api-client';
32
36
 
33
- import { AlertTriangleIcon, PendingIcon, XCircleIcon, type IconComponent } from './icons';
37
+ import { AlertTriangleIcon, type IconComponent, PendingIcon, XCircleIcon } from './icons';
34
38
 
35
39
  /** Human labels for the per-worker non-applied outcomes. */
36
40
  const OUTCOME_LABEL: Record<FleetFailureOutcome, string> = {
@@ -86,62 +90,75 @@ export interface FleetReportProps {
86
90
  readonly action?: 'save' | 'reload' | 'deregister' | 'remove';
87
91
  }
88
92
 
89
- export function FleetReport({ summary, action = 'save' }: FleetReportProps): ReactNode {
90
- if (summary === null || summary.status === 'converged') return null;
91
-
92
- // Only a saved config change carries the "Change saved" framing; a reload or a
93
- // deregister saved nothing.
94
- const savedFraming = action === 'save';
93
+ type FleetAction = NonNullable<FleetReportProps['action']>;
95
94
 
96
- if (summary.status === 'unreachable') {
97
- // Where to send the operator once the bus is back: re-run the same op, except a
98
- // saved change reloads from the System page.
99
- const unreachableRemediation =
100
- action === 'deregister'
101
- ? 'Re-run the deregister once the bus is back.'
102
- : action === 'remove'
103
- ? 'Re-run the remove once the bus is back.'
104
- : action === 'reload'
105
- ? 'Re-run the reload once the bus is back.'
106
- : 'Re-run the reload from the System page once the bus is back.';
107
- return (
108
- <div role="alert" className="tai-error-state tai-stack tai-stack-2">
109
- <strong className="tai-status tai-status-err">
110
- <XCircleIcon />
111
- {savedFraming
112
- ? 'Change saved, but the worker fleet was not reached'
113
- : 'The worker fleet was not reached'}
114
- </strong>
115
- <p>
116
- {`The worker bus was unreachable, so other workers may still be running the old config. ${unreachableRemediation}`}
117
- </p>
118
- {/* The bus error is a message, not a listing: it wraps rather than scrolls. */}
119
- {summary.error !== null ? (
120
- <p className="tai-code-block tai-code-block-wrap">{summary.error}</p>
121
- ) : null}
122
- </div>
123
- );
95
+ /**
96
+ * Where to send the operator, per action and phase. On `unreachable` the copy
97
+ * is a full sentence ending "once the bus is back."; on `degraded` it is the
98
+ * verb phrase spliced into the sentence the panel builds. A saved change reloads
99
+ * from the System page; a detach re-runs itself, since a reload would re-attach.
100
+ */
101
+ function remediationText(action: FleetAction, phase: FleetReportStatusPhase): string {
102
+ if (phase === 'unreachable') {
103
+ if (action === 'deregister') return 'Re-run the deregister once the bus is back.';
104
+ if (action === 'remove') return 'Re-run the remove once the bus is back.';
105
+ if (action === 'reload') return 'Re-run the reload once the bus is back.';
106
+ return 'Re-run the reload from the System page once the bus is back.';
124
107
  }
108
+ if (action === 'deregister') return 're-run the deregister';
109
+ if (action === 'remove') return 're-run the remove';
110
+ if (action === 'reload') return 're-run the reload';
111
+ return 'reload the fleet from the System page';
112
+ }
113
+
114
+ type FleetReportStatusPhase = 'unreachable' | 'degraded';
115
+
116
+ /** The loud panel for a bus that could not be reached: no sibling was told. */
117
+ function UnreachableReport({
118
+ error,
119
+ savedFraming,
120
+ remediation,
121
+ }: {
122
+ readonly error: string | null;
123
+ readonly savedFraming: boolean;
124
+ readonly remediation: string;
125
+ }): ReactNode {
126
+ return (
127
+ <div role="alert" className="tai-error-state tai-stack tai-stack-2">
128
+ <strong className="tai-status tai-status-err">
129
+ <XCircleIcon />
130
+ {savedFraming
131
+ ? 'Change saved, but the worker fleet was not reached'
132
+ : 'The worker fleet was not reached'}
133
+ </strong>
134
+ <p>
135
+ {`The worker bus was unreachable, so other workers may still be running the old config. ${remediation}`}
136
+ </p>
137
+ {/* The bus error is a message, not a listing: it wraps rather than scrolls. */}
138
+ {error !== null ? <p className="tai-code-block tai-code-block-wrap">{error}</p> : null}
139
+ </div>
140
+ );
141
+ }
125
142
 
126
- // degraded — the bus was reached but named workers did not converge. That is a
127
- // warning, not a failure, so it takes the warning surface: a warn-toned
128
- // headline inside an error-toned panel would state two different severities.
129
- //
130
- // A count and its noun agree. `worker(s)` is machine output at the one moment
131
- // an operator is being told something went wrong, and a single unconverged
132
- // worker is the commonest degraded fleet there is.
133
- const count = summary.failures.length;
143
+ /**
144
+ * The loud panel for a reachable bus whose named workers did not converge. A
145
+ * warning, not a failure, so it takes the warning surface: a warn-toned headline
146
+ * inside an error-toned panel would state two different severities.
147
+ */
148
+ function DegradedReport({
149
+ failures,
150
+ savedFraming,
151
+ remediation,
152
+ }: {
153
+ readonly failures: readonly FleetWorkerFailure[];
154
+ readonly savedFraming: boolean;
155
+ readonly remediation: string;
156
+ }): ReactNode {
157
+ // A count and its noun agree. `worker(s)` is machine output at the one moment an
158
+ // operator is being told something went wrong, and a single unconverged worker
159
+ // is the commonest degraded fleet there is.
160
+ const count = failures.length;
134
161
  const workers = `${String(count)} worker${count === 1 ? '' : 's'}`;
135
- // How the operator converges the stranded workers: re-run the same op, except a
136
- // saved change reloads the fleet from the System page.
137
- const remediation =
138
- action === 'deregister'
139
- ? 're-run the deregister'
140
- : action === 'remove'
141
- ? 're-run the remove'
142
- : action === 'reload'
143
- ? 're-run the reload'
144
- : 'reload the fleet from the System page';
145
162
  return (
146
163
  <div role="alert" className="tai-warn-state tai-stack tai-stack-2">
147
164
  <strong className="tai-status tai-status-warn">
@@ -156,7 +173,7 @@ export function FleetReport({ summary, action = 'save' }: FleetReportProps): Rea
156
173
  ` to converge ${count === 1 ? 'it' : 'them'}.`}
157
174
  </p>
158
175
  <ul className="tai-stack tai-stack-2">
159
- {summary.failures.map((failure) => {
176
+ {failures.map((failure) => {
160
177
  const { tone, Icon } = OUTCOME_STATUS[failure.outcome];
161
178
  return (
162
179
  <li key={failure.name} className="tai-row">
@@ -175,3 +192,29 @@ export function FleetReport({ summary, action = 'save' }: FleetReportProps): Rea
175
192
  </div>
176
193
  );
177
194
  }
195
+
196
+ export function FleetReport({ summary, action = 'save' }: FleetReportProps): ReactNode {
197
+ if (summary === null || summary.status === 'converged') return null;
198
+
199
+ // Only a saved config change carries the "Change saved" framing; a reload or a
200
+ // deregister saved nothing.
201
+ const savedFraming = action === 'save';
202
+
203
+ if (summary.status === 'unreachable') {
204
+ return (
205
+ <UnreachableReport
206
+ error={summary.error}
207
+ savedFraming={savedFraming}
208
+ remediation={remediationText(action, 'unreachable')}
209
+ />
210
+ );
211
+ }
212
+
213
+ return (
214
+ <DegradedReport
215
+ failures={summary.failures}
216
+ savedFraming={savedFraming}
217
+ remediation={remediationText(action, 'degraded')}
218
+ />
219
+ );
220
+ }
@@ -13,12 +13,12 @@
13
13
  * BOTH consuming screens through this one component — never a flows-page-only
14
14
  * affordance.
15
15
  */
16
- import { useState, type ReactNode } from 'react';
16
+ import { type ReactNode, useState } from 'react';
17
17
 
18
18
  import { ChevronRightIcon, FolderIcon } from './icons';
19
+ import { TextInput } from './inputs';
19
20
  import { Button } from './primitives';
20
21
  import { Select } from './select';
21
- import { TextInput } from './inputs';
22
22
 
23
23
  /** A folder in the tree, in the SDK's camelCase UI shape (`parentId`, `null` = root). */
24
24
  export interface Folder {
@@ -12,11 +12,11 @@
12
12
  * (Cancel, Escape, overlay) calls `onClose`. `submitDisabled` blocks submission by
13
13
  * click AND by Enter — a disabled default button is not an implicit-submission target.
14
14
  */
15
- import { useEffect, useRef, useState, type ReactNode, type SyntheticEvent } from 'react';
15
+ import { type ReactNode, type SyntheticEvent, useEffect, useRef, useState } from 'react';
16
16
 
17
+ import { errorMessage } from '../errors';
17
18
  import { Dialog } from './dialog';
18
19
  import { Button, ErrorState, Spinner } from './primitives';
19
- import { errorMessage } from '../errors';
20
20
 
21
21
  export interface FormDialogProps {
22
22
  readonly title: string;