@tai42/studio-sdk 16.0.0 → 16.0.1

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 (317) hide show
  1. package/dist/components/explorer-body.d.ts +49 -0
  2. package/dist/components/explorer-body.d.ts.map +1 -0
  3. package/dist/components/explorer-body.js +67 -0
  4. package/dist/components/explorer-body.js.map +1 -0
  5. package/dist/components/explorer-page-size.d.ts +4 -0
  6. package/dist/components/explorer-page-size.d.ts.map +1 -0
  7. package/dist/components/explorer-page-size.js +36 -0
  8. package/dist/components/explorer-page-size.js.map +1 -0
  9. package/dist/components/explorer-tag-filter.d.ts +17 -0
  10. package/dist/components/explorer-tag-filter.d.ts.map +1 -0
  11. package/dist/components/explorer-tag-filter.js +29 -0
  12. package/dist/components/explorer-tag-filter.js.map +1 -0
  13. package/dist/components/explorer-tags.d.ts +22 -0
  14. package/dist/components/explorer-tags.d.ts.map +1 -0
  15. package/dist/components/explorer-tags.js +51 -0
  16. package/dist/components/explorer-tags.js.map +1 -0
  17. package/dist/components/explorer-view.d.ts +3 -17
  18. package/dist/components/explorer-view.d.ts.map +1 -1
  19. package/dist/components/explorer-view.js +53 -170
  20. package/dist/components/explorer-view.js.map +1 -1
  21. package/dist/components/extension-combo-builder.d.ts +0 -5
  22. package/dist/components/extension-combo-builder.d.ts.map +1 -1
  23. package/dist/components/extension-combo-builder.js +4 -42
  24. package/dist/components/extension-combo-builder.js.map +1 -1
  25. package/dist/components/extension-combo-parts.d.ts +44 -0
  26. package/dist/components/extension-combo-parts.d.ts.map +1 -0
  27. package/dist/components/extension-combo-parts.js +57 -0
  28. package/dist/components/extension-combo-parts.js.map +1 -0
  29. package/dist/components/fleet-report.d.ts.map +1 -1
  30. package/dist/components/fleet-report.js +51 -37
  31. package/dist/components/fleet-report.js.map +1 -1
  32. package/dist/components/icons/chrome-marks.d.ts +50 -0
  33. package/dist/components/icons/chrome-marks.d.ts.map +1 -0
  34. package/dist/components/icons/chrome-marks.js +51 -0
  35. package/dist/components/icons/chrome-marks.js.map +1 -0
  36. package/dist/components/icons/icon-frame.d.ts +29 -0
  37. package/dist/components/icons/icon-frame.d.ts.map +1 -0
  38. package/dist/components/icons/icon-frame.js +19 -0
  39. package/dist/components/icons/icon-frame.js.map +1 -0
  40. package/dist/components/icons/index.d.ts +40 -0
  41. package/dist/components/icons/index.d.ts.map +1 -0
  42. package/dist/components/icons/index.js +6 -0
  43. package/dist/components/icons/index.js.map +1 -0
  44. package/dist/components/icons/nav-map.d.ts +14 -0
  45. package/dist/components/icons/nav-map.d.ts.map +1 -0
  46. package/dist/components/icons/nav-map.js +28 -0
  47. package/dist/components/icons/nav-map.js.map +1 -0
  48. package/dist/components/icons/nav-marks.d.ts +44 -0
  49. package/dist/components/icons/nav-marks.d.ts.map +1 -0
  50. package/dist/components/icons/nav-marks.js +45 -0
  51. package/dist/components/icons/nav-marks.js.map +1 -0
  52. package/dist/components/icons/status-marks.d.ts +21 -0
  53. package/dist/components/icons/status-marks.d.ts.map +1 -0
  54. package/dist/components/icons/status-marks.js +22 -0
  55. package/dist/components/icons/status-marks.js.map +1 -0
  56. package/dist/components/icons/theme-marks.d.ts +9 -0
  57. package/dist/components/icons/theme-marks.d.ts.map +1 -0
  58. package/dist/components/icons/theme-marks.js +10 -0
  59. package/dist/components/icons/theme-marks.js.map +1 -0
  60. package/dist/components/json-diff.d.ts.map +1 -1
  61. package/dist/components/json-diff.js +1 -3
  62. package/dist/components/json-diff.js.map +1 -1
  63. package/dist/components/json-tree-context.d.ts +13 -0
  64. package/dist/components/json-tree-context.d.ts.map +1 -0
  65. package/dist/components/json-tree-context.js +15 -0
  66. package/dist/components/json-tree-context.js.map +1 -0
  67. package/dist/components/json-tree-model.d.ts +56 -0
  68. package/dist/components/json-tree-model.d.ts.map +1 -0
  69. package/dist/components/json-tree-model.js +125 -0
  70. package/dist/components/json-tree-model.js.map +1 -0
  71. package/dist/components/json-tree-nodes.d.ts +30 -0
  72. package/dist/components/json-tree-nodes.d.ts.map +1 -0
  73. package/dist/components/json-tree-nodes.js +118 -0
  74. package/dist/components/json-tree-nodes.js.map +1 -0
  75. package/dist/components/json-tree.d.ts.map +1 -1
  76. package/dist/components/json-tree.js +7 -295
  77. package/dist/components/json-tree.js.map +1 -1
  78. package/dist/components/json-value-format.d.ts +20 -0
  79. package/dist/components/json-value-format.d.ts.map +1 -0
  80. package/dist/components/json-value-format.js +63 -0
  81. package/dist/components/json-value-format.js.map +1 -0
  82. package/dist/components/markdown-blocks.d.ts +38 -0
  83. package/dist/components/markdown-blocks.d.ts.map +1 -0
  84. package/dist/components/markdown-blocks.js +168 -0
  85. package/dist/components/markdown-blocks.js.map +1 -0
  86. package/dist/components/markdown-inline.d.ts +24 -0
  87. package/dist/components/markdown-inline.d.ts.map +1 -0
  88. package/dist/components/markdown-inline.js +257 -0
  89. package/dist/components/markdown-inline.js.map +1 -0
  90. package/dist/components/markdown.d.ts +3 -52
  91. package/dist/components/markdown.d.ts.map +1 -1
  92. package/dist/components/markdown.js +4 -376
  93. package/dist/components/markdown.js.map +1 -1
  94. package/dist/components/observer-registry.d.ts +38 -0
  95. package/dist/components/observer-registry.d.ts.map +1 -0
  96. package/dist/components/observer-registry.js +131 -0
  97. package/dist/components/observer-registry.js.map +1 -0
  98. package/dist/components/overflow-measure.d.ts +38 -0
  99. package/dist/components/overflow-measure.d.ts.map +1 -0
  100. package/dist/components/overflow-measure.js +54 -0
  101. package/dist/components/overflow-measure.js.map +1 -0
  102. package/dist/components/prose-regions.d.ts +81 -0
  103. package/dist/components/prose-regions.d.ts.map +1 -0
  104. package/dist/components/prose-regions.js +128 -0
  105. package/dist/components/prose-regions.js.map +1 -0
  106. package/dist/components/scroll-region.d.ts.map +1 -1
  107. package/dist/components/scroll-region.js +3 -298
  108. package/dist/components/scroll-region.js.map +1 -1
  109. package/dist/components/tab-stop-parse.d.ts +53 -0
  110. package/dist/components/tab-stop-parse.d.ts.map +1 -0
  111. package/dist/components/tab-stop-parse.js +202 -0
  112. package/dist/components/tab-stop-parse.js.map +1 -0
  113. package/dist/components/templated-text-field.d.ts.map +1 -1
  114. package/dist/components/templated-text-field.js +10 -148
  115. package/dist/components/templated-text-field.js.map +1 -1
  116. package/dist/components/templated-text-kwargs-editor.d.ts +24 -0
  117. package/dist/components/templated-text-kwargs-editor.d.ts.map +1 -0
  118. package/dist/components/templated-text-kwargs-editor.js +48 -0
  119. package/dist/components/templated-text-kwargs-editor.js.map +1 -0
  120. package/dist/components/templated-text-kwargs.d.ts +37 -0
  121. package/dist/components/templated-text-kwargs.d.ts.map +1 -0
  122. package/dist/components/templated-text-kwargs.js +66 -0
  123. package/dist/components/templated-text-kwargs.js.map +1 -0
  124. package/dist/components/templated-text-source.d.ts +33 -0
  125. package/dist/components/templated-text-source.d.ts.map +1 -0
  126. package/dist/components/templated-text-source.js +53 -0
  127. package/dist/components/templated-text-source.js.map +1 -0
  128. package/dist/components/tool-picker-parts.d.ts +39 -0
  129. package/dist/components/tool-picker-parts.d.ts.map +1 -0
  130. package/dist/components/tool-picker-parts.js +87 -0
  131. package/dist/components/tool-picker-parts.js.map +1 -0
  132. package/dist/components/tool-picker.d.ts +1 -2
  133. package/dist/components/tool-picker.d.ts.map +1 -1
  134. package/dist/components/tool-picker.js +4 -66
  135. package/dist/components/tool-picker.js.map +1 -1
  136. package/dist/components/version-history-panel.d.ts.map +1 -1
  137. package/dist/components/version-history-panel.js +7 -34
  138. package/dist/components/version-history-panel.js.map +1 -1
  139. package/dist/components/version-history-rows.d.ts +48 -0
  140. package/dist/components/version-history-rows.d.ts.map +1 -0
  141. package/dist/components/version-history-rows.js +51 -0
  142. package/dist/components/version-history-rows.js.map +1 -0
  143. package/dist/guards.d.ts +6 -0
  144. package/dist/guards.d.ts.map +1 -0
  145. package/dist/guards.js +8 -0
  146. package/dist/guards.js.map +1 -0
  147. package/dist/hooks/interactions-connection.d.ts +43 -0
  148. package/dist/hooks/interactions-connection.d.ts.map +1 -0
  149. package/dist/hooks/interactions-connection.js +171 -0
  150. package/dist/hooks/interactions-connection.js.map +1 -0
  151. package/dist/hooks/interactions-stream.d.ts +80 -0
  152. package/dist/hooks/interactions-stream.d.ts.map +1 -0
  153. package/dist/hooks/interactions-stream.js +233 -0
  154. package/dist/hooks/interactions-stream.js.map +1 -0
  155. package/dist/hooks/useApi.d.ts +2192 -2192
  156. package/dist/hooks/useApi.d.ts.map +1 -1
  157. package/dist/hooks/useSse.d.ts +3 -6
  158. package/dist/hooks/useSse.d.ts.map +1 -1
  159. package/dist/hooks/useSse.js +38 -451
  160. package/dist/hooks/useSse.js.map +1 -1
  161. package/dist/navigation/app-link.d.ts +25 -0
  162. package/dist/navigation/app-link.d.ts.map +1 -0
  163. package/dist/navigation/app-link.js +33 -0
  164. package/dist/navigation/app-link.js.map +1 -0
  165. package/dist/navigation/context.d.ts +3 -20
  166. package/dist/navigation/context.d.ts.map +1 -1
  167. package/dist/navigation/context.js +7 -267
  168. package/dist/navigation/context.js.map +1 -1
  169. package/dist/navigation/entry-state.d.ts +23 -0
  170. package/dist/navigation/entry-state.d.ts.map +1 -0
  171. package/dist/navigation/entry-state.js +39 -0
  172. package/dist/navigation/entry-state.js.map +1 -0
  173. package/dist/navigation/guard-registry.d.ts +30 -0
  174. package/dist/navigation/guard-registry.d.ts.map +1 -0
  175. package/dist/navigation/guard-registry.js +46 -0
  176. package/dist/navigation/guard-registry.js.map +1 -0
  177. package/dist/navigation/guarded-navigation.d.ts +24 -0
  178. package/dist/navigation/guarded-navigation.d.ts.map +1 -0
  179. package/dist/navigation/guarded-navigation.js +102 -0
  180. package/dist/navigation/guarded-navigation.js.map +1 -0
  181. package/dist/navigation/index.d.ts +3 -2
  182. package/dist/navigation/index.d.ts.map +1 -1
  183. package/dist/navigation/index.js +2 -1
  184. package/dist/navigation/index.js.map +1 -1
  185. package/dist/navigation/types.d.ts +8 -11
  186. package/dist/navigation/types.d.ts.map +1 -1
  187. package/dist/navigation/use-back-forward-guard.d.ts +5 -0
  188. package/dist/navigation/use-back-forward-guard.d.ts.map +1 -0
  189. package/dist/navigation/use-back-forward-guard.js +82 -0
  190. package/dist/navigation/use-back-forward-guard.js.map +1 -0
  191. package/dist/plugin/registry.d.ts +6 -15
  192. package/dist/plugin/registry.d.ts.map +1 -1
  193. package/dist/plugin/registry.js +83 -75
  194. package/dist/plugin/registry.js.map +1 -1
  195. package/dist/schema-form/SecretRefField.d.ts +2 -3
  196. package/dist/schema-form/SecretRefField.d.ts.map +1 -1
  197. package/dist/schema-form/SecretRefField.js +23 -12
  198. package/dist/schema-form/SecretRefField.js.map +1 -1
  199. package/dist/schema-form/classify.d.ts +1 -122
  200. package/dist/schema-form/classify.d.ts.map +1 -1
  201. package/dist/schema-form/classify.js +174 -237
  202. package/dist/schema-form/classify.js.map +1 -1
  203. package/dist/schema-form/default-value.d.ts.map +1 -1
  204. package/dist/schema-form/default-value.js +42 -19
  205. package/dist/schema-form/default-value.js.map +1 -1
  206. package/dist/schema-form/enum-field.d.ts +1 -1
  207. package/dist/schema-form/enum-field.d.ts.map +1 -1
  208. package/dist/schema-form/field-model.d.ts +121 -0
  209. package/dist/schema-form/field-model.d.ts.map +1 -0
  210. package/dist/schema-form/field-model.js +2 -0
  211. package/dist/schema-form/field-model.js.map +1 -0
  212. package/dist/schema-form/field-node.d.ts.map +1 -1
  213. package/dist/schema-form/field-node.js +25 -14
  214. package/dist/schema-form/field-node.js.map +1 -1
  215. package/dist/schema-form/media-field.d.ts +1 -1
  216. package/dist/schema-form/media-field.d.ts.map +1 -1
  217. package/dist/schema-form/media-field.js +47 -28
  218. package/dist/schema-form/media-field.js.map +1 -1
  219. package/dist/schema-form/string-annotations.d.ts +20 -0
  220. package/dist/schema-form/string-annotations.d.ts.map +1 -0
  221. package/dist/schema-form/string-annotations.js +105 -0
  222. package/dist/schema-form/string-annotations.js.map +1 -0
  223. package/dist/schema-form/string-field.d.ts +1 -1
  224. package/dist/schema-form/string-field.d.ts.map +1 -1
  225. package/dist/schema-form/union-field.d.ts +1 -1
  226. package/dist/schema-form/union-field.d.ts.map +1 -1
  227. package/dist/schema-form/union-field.js.map +1 -1
  228. package/dist/schema-form/union.d.ts +1 -1
  229. package/dist/schema-form/union.d.ts.map +1 -1
  230. package/dist/schema-form/validate.d.ts.map +1 -1
  231. package/dist/schema-form/validate.js +126 -105
  232. package/dist/schema-form/validate.js.map +1 -1
  233. package/dist/state-binding/AdapterMapping.d.ts.map +1 -1
  234. package/dist/state-binding/AdapterMapping.js +0 -0
  235. package/dist/state-binding/AdapterMapping.js.map +1 -1
  236. package/dist/state-binding/StateAttachRow.d.ts.map +1 -1
  237. package/dist/state-binding/StateAttachRow.js +52 -36
  238. package/dist/state-binding/StateAttachRow.js.map +1 -1
  239. package/dist/state-binding/adapter-mapping-row.d.ts +17 -0
  240. package/dist/state-binding/adapter-mapping-row.d.ts.map +1 -0
  241. package/dist/state-binding/adapter-mapping-row.js +87 -0
  242. package/dist/state-binding/adapter-mapping-row.js.map +1 -0
  243. package/dist/structured-output/StructuredOutput.d.ts.map +1 -1
  244. package/dist/structured-output/StructuredOutput.js +1 -3
  245. package/dist/structured-output/StructuredOutput.js.map +1 -1
  246. package/package.json +2 -2
  247. package/src/components/explorer-body.tsx +239 -0
  248. package/src/components/explorer-page-size.ts +39 -0
  249. package/src/components/explorer-tag-filter.tsx +80 -0
  250. package/src/components/explorer-tags.ts +64 -0
  251. package/src/components/explorer-view.tsx +114 -366
  252. package/src/components/extension-combo-builder.tsx +35 -152
  253. package/src/components/extension-combo-parts.tsx +237 -0
  254. package/src/components/fleet-report.tsx +97 -54
  255. package/src/components/icons/chrome-marks.tsx +195 -0
  256. package/src/components/icons/icon-frame.tsx +50 -0
  257. package/src/components/icons/index.ts +84 -0
  258. package/src/components/icons/nav-map.ts +55 -0
  259. package/src/components/icons/nav-marks.tsx +205 -0
  260. package/src/components/icons/status-marks.tsx +46 -0
  261. package/src/components/icons/theme-marks.tsx +33 -0
  262. package/src/components/json-diff.tsx +1 -4
  263. package/src/components/json-tree-context.ts +26 -0
  264. package/src/components/json-tree-model.ts +139 -0
  265. package/src/components/json-tree-nodes.tsx +224 -0
  266. package/src/components/json-tree.tsx +15 -434
  267. package/src/components/json-value-format.ts +64 -0
  268. package/src/components/markdown-blocks.ts +198 -0
  269. package/src/components/markdown-inline.tsx +365 -0
  270. package/src/components/markdown.tsx +5 -471
  271. package/src/components/observer-registry.ts +139 -0
  272. package/src/components/overflow-measure.ts +69 -0
  273. package/src/components/prose-regions.ts +153 -0
  274. package/src/components/scroll-region.tsx +20 -360
  275. package/src/components/tab-stop-parse.ts +217 -0
  276. package/src/components/templated-text-field.tsx +38 -330
  277. package/src/components/templated-text-kwargs-editor.tsx +147 -0
  278. package/src/components/templated-text-kwargs.ts +92 -0
  279. package/src/components/templated-text-source.tsx +226 -0
  280. package/src/components/tool-picker-parts.tsx +184 -0
  281. package/src/components/tool-picker.tsx +22 -114
  282. package/src/components/version-history-panel.tsx +38 -142
  283. package/src/components/version-history-rows.tsx +220 -0
  284. package/src/guards.ts +7 -0
  285. package/src/hooks/interactions-connection.ts +227 -0
  286. package/src/hooks/interactions-stream.ts +274 -0
  287. package/src/hooks/useSse.ts +50 -477
  288. package/src/navigation/app-link.tsx +70 -0
  289. package/src/navigation/context.tsx +11 -330
  290. package/src/navigation/entry-state.ts +42 -0
  291. package/src/navigation/guard-registry.ts +65 -0
  292. package/src/navigation/guarded-navigation.ts +147 -0
  293. package/src/navigation/index.ts +2 -2
  294. package/src/navigation/types.ts +8 -11
  295. package/src/navigation/use-back-forward-guard.ts +90 -0
  296. package/src/plugin/registry.ts +111 -90
  297. package/src/schema-form/SecretRefField.tsx +121 -71
  298. package/src/schema-form/classify.ts +244 -395
  299. package/src/schema-form/default-value.ts +48 -17
  300. package/src/schema-form/enum-field.tsx +1 -1
  301. package/src/schema-form/field-model.ts +133 -0
  302. package/src/schema-form/field-node.tsx +94 -38
  303. package/src/schema-form/media-field.tsx +134 -65
  304. package/src/schema-form/string-annotations.ts +111 -0
  305. package/src/schema-form/string-field.tsx +1 -1
  306. package/src/schema-form/union-field.tsx +2 -1
  307. package/src/schema-form/union.ts +1 -1
  308. package/src/schema-form/validate.ts +184 -103
  309. package/src/state-binding/AdapterMapping.tsx +0 -0
  310. package/src/state-binding/StateAttachRow.tsx +222 -147
  311. package/src/state-binding/adapter-mapping-row.tsx +232 -0
  312. package/src/structured-output/StructuredOutput.tsx +1 -4
  313. package/dist/components/icons.d.ts +0 -160
  314. package/dist/components/icons.d.ts.map +0 -1
  315. package/dist/components/icons.js +0 -160
  316. package/dist/components/icons.js.map +0 -1
  317. package/src/components/icons.tsx +0 -586
@@ -0,0 +1,87 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * One row of the adapter mapping form: it picks ONE of three value sources for a
4
+ * declared input key — a picked field (from the run's output / input schema), a
5
+ * hardcoded literal, or a jq expression — and shows the row's own compiled jq on
6
+ * demand. {@link AdapterMapping} composes one editor per declared key.
7
+ */
8
+ import { useState } from 'react';
9
+ import { Badge } from '../components/badge';
10
+ import { Button, Skeleton } from '../components/primitives';
11
+ import { Field } from '../components/field';
12
+ import { Select } from '../components/select';
13
+ import { TextInput } from '../components/inputs';
14
+ import { BindingJqField } from './BindingJqField';
15
+ import { rowValueJq } from './adapter';
16
+ const ROOT_OPTIONS = [
17
+ { value: 'output', label: 'Run output' },
18
+ { value: 'input', label: 'Run input' },
19
+ ];
20
+ const SOURCE_OPTIONS = [
21
+ { value: 'field', label: 'Field' },
22
+ { value: 'literal', label: 'Literal' },
23
+ { value: 'jq', label: 'Jq' },
24
+ ];
25
+ function fieldsFor(root, sources) {
26
+ if (root === 'output')
27
+ return sources?.output ?? [];
28
+ return sources?.input ?? [];
29
+ }
30
+ /** The value control for one row's picked-field source: a Select where a schema is known, else a path input. */
31
+ function FieldSourceControl({ root, path, onRootChange, onPathChange, fields, loading = false, error, }) {
32
+ const pathInput = (_jsx(TextInput, { "aria-label": "Field path", placeholder: "path.into.value", value: path.join('.'), onChange: (event) => {
33
+ const text = event.target.value.trim();
34
+ onPathChange(text === '' ? [] : text.split('.'));
35
+ } }));
36
+ return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 'var(--tai-space-1)' }, children: [_jsxs("div", { style: { display: 'flex', gap: 'var(--tai-space-2)', flexWrap: 'wrap' }, children: [_jsx(Field, { label: "Field root", hideLabel: true, children: _jsx(Select, { value: root, onValueChange: (next) => {
37
+ onRootChange(next);
38
+ }, options: ROOT_OPTIONS.map((option) => ({ value: option.value, label: option.label })) }) }), loading ? (_jsx(Skeleton, { height: 32, width: 220 })) : fields.length > 0 ? (_jsx(Field, { label: "Field", hideLabel: true, children: _jsx(Select, { placeholder: "Choose a field", value: path.length === 0 ? '' : JSON.stringify(path), onValueChange: (next) => {
39
+ onPathChange(next === '' ? [] : JSON.parse(next));
40
+ }, options: [
41
+ { value: '', label: '(whole value)' },
42
+ ...fields.map((field) => ({
43
+ value: JSON.stringify(field.path),
44
+ label: field.label,
45
+ })),
46
+ ] }) })) : (pathInput)] }), error !== undefined && !loading ? (_jsx("span", { role: "status", style: { color: 'var(--tai-color-text-muted)', fontSize: 'var(--tai-text-sm)' }, children: error })) : null] }));
47
+ }
48
+ export function MappingRowEditor({ row, onChange, sources, suggestions, }) {
49
+ const [showJq, setShowJq] = useState(false);
50
+ const source = row.source;
51
+ const preview = rowValueJq(source);
52
+ const setSource = (next) => {
53
+ onChange({ ...row, source: next });
54
+ };
55
+ const changeKind = (kind) => {
56
+ if (kind === 'field')
57
+ setSource({ kind: 'field', root: 'output', path: [] });
58
+ else if (kind === 'literal')
59
+ setSource({ kind: 'literal', json: '' });
60
+ else
61
+ setSource({ kind: 'jq', expr: '' });
62
+ };
63
+ return (_jsxs("div", { "data-testid": `adapter-row-${row.target}`, style: {
64
+ display: 'flex',
65
+ flexDirection: 'column',
66
+ gap: 'var(--tai-space-1)',
67
+ padding: 'var(--tai-space-2)',
68
+ border: '1px solid var(--tai-color-border)',
69
+ borderRadius: 'var(--tai-radius-md)',
70
+ }, children: [_jsxs("div", { style: {
71
+ display: 'flex',
72
+ alignItems: 'center',
73
+ gap: 'var(--tai-space-2)',
74
+ flexWrap: 'wrap',
75
+ }, children: [_jsx(Badge, { variant: "neutral", children: row.target }), _jsx(Field, { label: `Source for ${row.target}`, hideLabel: true, children: _jsx(Select, { "aria-label": `Source for ${row.target}`, value: source.kind, onValueChange: changeKind, options: SOURCE_OPTIONS }) })] }), source.kind === 'field' ? (_jsx(FieldSourceControl, { root: source.root, path: source.path, fields: fieldsFor(source.root, sources), loading: sources?.loading, error: sources?.error, onRootChange: (nextRoot) => {
76
+ setSource({ kind: 'field', root: nextRoot, path: [] });
77
+ }, onPathChange: (nextPath) => {
78
+ setSource({ kind: 'field', root: source.root, path: nextPath });
79
+ } })) : source.kind === 'literal' ? (_jsx(Field, { label: `Literal for ${row.target}`, hideLabel: true, error: preview.ok ? undefined : preview.error, children: _jsx(TextInput, { "aria-label": `Literal for ${row.target}`, placeholder: '"a string", 42, true, or {"k":1}', value: source.json, onChange: (event) => {
80
+ setSource({ kind: 'literal', json: event.target.value });
81
+ } }) })) : (_jsx(BindingJqField, { label: `Jq for ${row.target}`, value: source.expr, onChange: (next) => {
82
+ setSource({ kind: 'jq', expr: next });
83
+ }, error: preview.ok ? undefined : preview.error, suggestions: suggestions })), _jsxs("div", { children: [_jsx(Button, { type: "button", variant: "ghost", "aria-expanded": showJq, onClick: () => {
84
+ setShowJq((open) => !open);
85
+ }, children: showJq ? 'Hide jq' : 'Show jq' }), showJq ? (_jsx("pre", { "data-testid": `adapter-row-jq-${row.target}`, style: { margin: 0, fontFamily: 'var(--tai-font-mono)', whiteSpace: 'pre-wrap' }, children: preview.ok ? preview.jq : preview.error })) : null] })] }));
86
+ }
87
+ //# sourceMappingURL=adapter-mapping-row.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-mapping-row.js","sourceRoot":"","sources":["../../src/state-binding/adapter-mapping-row.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"StructuredOutput.d.ts","sourceRoot":"","sources":["../../src/structured-output/StructuredOutput.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,WAAW,qBAAqB;IACpC,qDAAqD;IACrD,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;IAC7B,kDAAkD;IAClD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAoBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,qBAAqB,GAAG,SAAS,CAgCtF"}
1
+ {"version":3,"file":"StructuredOutput.d.ts","sourceRoot":"","sources":["../../src/structured-output/StructuredOutput.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGvD,MAAM,WAAW,qBAAqB;IACpC,qDAAqD;IACrD,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;IAC7B,kDAAkD;IAClD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAgBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,qBAAqB,GAAG,SAAS,CAgCtF"}
@@ -1,11 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { JsonTree } from '../components/json-tree';
3
3
  import { resolveRef } from '../schema-form/resolve';
4
+ import { isRecord } from '../guards';
4
5
  /** The pane's name when the payload has no schema to name it by. */
5
6
  const RAW_OUTPUT_LABEL = 'Structured output';
6
- function isRecord(value) {
7
- return typeof value === 'object' && value !== null && !Array.isArray(value);
8
- }
9
7
  function isObjectSchema(schema, root) {
10
8
  if (!schema || !root)
11
9
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"StructuredOutput.js","sourceRoot":"","sources":["../../src/structured-output/StructuredOutput.tsx"],"names":[],"mappings":";AAaA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAUpD,oEAAoE;AACpE,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;AAE7C,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,cAAc,CACrB,MAA8B,EAC9B,IAA4B;IAE5B,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACjE,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;IAC3B,MAAM,QAAQ,GAAG,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvF,OAAO,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAyB;IACzE,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1D,OAAO,CAGL,6BAAiB,uBAAuB,YACtC,KAAC,QAAQ,IAAC,IAAI,EAAE,OAAO,EAAE,eAAe,QAAC,KAAK,EAAE,gBAAgB,GAAI,GAChE,CACP,CAAC;IACJ,CAAC;IAED,wDAAwD;IACxD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACnE,0EAA0E;IAC1E,+BAA+B;IAC/B,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,IAAI,EAAE,CAAC;IAE7C,OAAO,CACL,cAAK,SAAS,EAAC,uBAAuB,iBAAa,mBAAmB,YACnE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,EAAE;YACpD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;YAC5E,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,IAAI,GAAG,CAAC;YAChC,OAAO,CACL,eAAe,SAAS,EAAC,WAAW,aAClC,eAAM,SAAS,EAAC,iBAAiB,YAAE,IAAI,GAAQ,EAE/C,KAAC,QAAQ,IAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,eAAe,QAAC,KAAK,EAAE,IAAI,GAAI,KAHrD,GAAG,CAIP,CACP,CAAC;QACJ,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"StructuredOutput.js","sourceRoot":"","sources":["../../src/structured-output/StructuredOutput.tsx"],"names":[],"mappings":";AAaA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AASrC,oEAAoE;AACpE,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;AAE7C,SAAS,cAAc,CACrB,MAA8B,EAC9B,IAA4B;IAE5B,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACjE,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;IAC3B,MAAM,QAAQ,GAAG,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvF,OAAO,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAyB;IACzE,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1D,OAAO,CAGL,6BAAiB,uBAAuB,YACtC,KAAC,QAAQ,IAAC,IAAI,EAAE,OAAO,EAAE,eAAe,QAAC,KAAK,EAAE,gBAAgB,GAAI,GAChE,CACP,CAAC;IACJ,CAAC;IAED,wDAAwD;IACxD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACnE,0EAA0E;IAC1E,+BAA+B;IAC/B,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,IAAI,EAAE,CAAC;IAE7C,OAAO,CACL,cAAK,SAAS,EAAC,uBAAuB,iBAAa,mBAAmB,YACnE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,EAAE;YACpD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;YAC5E,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,IAAI,GAAG,CAAC;YAChC,OAAO,CACL,eAAe,SAAS,EAAC,WAAW,aAClC,eAAM,SAAS,EAAC,iBAAiB,YAAE,IAAI,GAAQ,EAE/C,KAAC,QAAQ,IAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,eAAe,QAAC,KAAK,EAAE,IAAI,GAAI,KAHrD,GAAG,CAIP,CACP,CAAC;QACJ,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tai42/studio-sdk",
3
- "version": "16.0.0",
3
+ "version": "16.0.1",
4
4
  "description": "The Studio plugin contract, shared UI components, and hooks that every feature builds on.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "tai42 <oss@tai42.ai>",
@@ -96,7 +96,7 @@
96
96
  "@radix-ui/react-select": "^2.3.2",
97
97
  "@radix-ui/react-tabs": "^1.1.21",
98
98
  "@radix-ui/react-tooltip": "^1.2.11",
99
- "@tai42/api-client": "16.0.0"
99
+ "@tai42/api-client": "16.0.1"
100
100
  },
101
101
  "scripts": {
102
102
  "build": "tsc -b tsconfig.build.json && node scripts/copy-assets.mjs",
@@ -0,0 +1,239 @@
1
+ /**
2
+ * The explorer's directory body: the empty-state ladder, the card grid and the
3
+ * scrolling table (folders sorted above items in both), and the page footer. The
4
+ * pagination MATH lives in `ExplorerView`; this renders the result.
5
+ */
6
+ import type { ReactNode } from 'react';
7
+
8
+ import { EntityCardGrid } from './entity-card-grid';
9
+ import { FolderRow, type Folder } from './folder-nav';
10
+ import { type OpenTargetProps } from './open-target';
11
+ import { Button, Card, EmptyState } from './primitives';
12
+ import { ScrollRegion } from './scroll-region';
13
+ import { Select } from './select';
14
+ import { Table, TBody, TD, TH, THead, TR } from './table';
15
+ import type { ViewMode } from './view-toggle';
16
+ import { PAGE_SIZES } from './explorer-page-size';
17
+ import type { ExplorerColumn, ExplorerEmptyStates } from './explorer-view';
18
+
19
+ /** One page entry: a subfolder (sorted first) or a filtered item, in one array. */
20
+ export type ExplorerEntry<T> =
21
+ | { readonly kind: 'folder'; readonly folder: Folder }
22
+ | { readonly kind: 'item'; readonly item: T };
23
+
24
+ /** A first-class folder entry — a `FolderRow` (icon + name, navigates inward)
25
+ * beside its optional actions, in the layout shared by the row cell and the card. */
26
+ function FolderEntry({
27
+ folder,
28
+ onNavigate,
29
+ renderFolderActions,
30
+ }: {
31
+ readonly folder: Folder;
32
+ readonly onNavigate: (folderId: string | null) => void;
33
+ readonly renderFolderActions: ((folder: Folder) => ReactNode) | undefined;
34
+ }): ReactNode {
35
+ return (
36
+ <div className="tai-explorer-folder">
37
+ <FolderRow folder={folder} onOpen={onNavigate} />
38
+ {renderFolderActions ? renderFolderActions(folder) : null}
39
+ </div>
40
+ );
41
+ }
42
+
43
+ interface ExplorerPagerProps {
44
+ readonly label: string;
45
+ readonly pageStart: number;
46
+ readonly pageSize: number;
47
+ readonly total: number;
48
+ readonly effectivePage: number;
49
+ readonly pageCount: number;
50
+ readonly onPageChange: (page: number) => void;
51
+ readonly onPageSizeChange: (size: number) => void;
52
+ }
53
+
54
+ function ExplorerPager({
55
+ label,
56
+ pageStart,
57
+ pageSize,
58
+ total,
59
+ effectivePage,
60
+ pageCount,
61
+ onPageChange,
62
+ onPageSizeChange,
63
+ }: ExplorerPagerProps): ReactNode {
64
+ return (
65
+ <nav className="tai-explorer-pagination" aria-label={`${label} pagination`}>
66
+ {/* The pager counts ENTRIES — subfolders plus filtered items in the
67
+ current directory — which is a different unit from the header's total
68
+ item count across every folder. Naming the unit keeps the two honest:
69
+ "1–4 of 4 entries" here versus "7 templates" above. */}
70
+ <span className="tai-muted">{`${String(pageStart + 1)}–${String(Math.min(pageStart + pageSize, total))} of ${String(total)} entries`}</span>
71
+ <div className="tai-row">
72
+ <Select
73
+ aria-label="Items per page"
74
+ value={String(pageSize)}
75
+ onValueChange={(value) => {
76
+ onPageSizeChange(Number(value));
77
+ }}
78
+ options={PAGE_SIZES.map((size) => ({
79
+ value: String(size),
80
+ label: `${String(size)} per page`,
81
+ }))}
82
+ />
83
+ {/* aria-disabled, never the disabled attribute: a button removed from
84
+ the tab order at the bound drops focus to the body (WCAG 2.4.3).
85
+ The click guard makes activation at the bound an inert no-op. */}
86
+ <Button
87
+ variant="ghost"
88
+ aria-label="Previous page"
89
+ aria-disabled={effectivePage <= 1}
90
+ onClick={() => {
91
+ if (effectivePage <= 1) return;
92
+ onPageChange(effectivePage - 1);
93
+ }}
94
+ >
95
+ Prev
96
+ </Button>
97
+ <Button
98
+ variant="ghost"
99
+ aria-label="Next page"
100
+ aria-disabled={effectivePage >= pageCount}
101
+ onClick={() => {
102
+ if (effectivePage >= pageCount) return;
103
+ onPageChange(effectivePage + 1);
104
+ }}
105
+ >
106
+ Next
107
+ </Button>
108
+ <span className="tai-muted">{`Page ${String(effectivePage)} of ${String(pageCount)}`}</span>
109
+ </div>
110
+ </nav>
111
+ );
112
+ }
113
+
114
+ export interface ExplorerBodyProps<T> {
115
+ readonly hasEntries: boolean;
116
+ /** Items in the current folder before filtering, so the empty ladder can tell
117
+ * "filter emptied it" (>0 → no-match) from "genuinely empty". */
118
+ readonly inFolderCount: number;
119
+ readonly emptyStates: ExplorerEmptyStates;
120
+ readonly viewMode: ViewMode;
121
+ readonly label: string;
122
+ readonly columns: readonly ExplorerColumn[];
123
+ readonly pageEntries: readonly ExplorerEntry<T>[];
124
+ readonly getItemKey: (item: T) => string;
125
+ readonly renderRow: (item: T) => ReactNode;
126
+ readonly renderCard: (item: T) => ReactNode;
127
+ readonly openProps: (item: T) => OpenTargetProps;
128
+ readonly onNavigate: (folderId: string | null) => void;
129
+ readonly renderFolderActions: ((folder: Folder) => ReactNode) | undefined;
130
+ readonly pager: ExplorerPagerProps;
131
+ }
132
+
133
+ /** A card entry (folder card or item card) for the grid view. */
134
+ function CardEntry<T>(
135
+ props: ExplorerBodyProps<T> & { readonly entry: ExplorerEntry<T> },
136
+ ): ReactNode {
137
+ const { entry, onNavigate, renderFolderActions, getItemKey, renderCard, openProps } = props;
138
+ if (entry.kind === 'folder') {
139
+ return (
140
+ <div role="listitem" key={`folder:${entry.folder.id}`}>
141
+ <Card interactive>
142
+ <FolderEntry
143
+ folder={entry.folder}
144
+ onNavigate={onNavigate}
145
+ renderFolderActions={renderFolderActions}
146
+ />
147
+ </Card>
148
+ </div>
149
+ );
150
+ }
151
+ return (
152
+ <div role="listitem" key={`item:${getItemKey(entry.item)}`} {...openProps(entry.item)}>
153
+ {renderCard(entry.item)}
154
+ </div>
155
+ );
156
+ }
157
+
158
+ /** A table row (folder row spanning all columns, or item row) for the list view. */
159
+ function RowEntry<T>(
160
+ props: ExplorerBodyProps<T> & { readonly entry: ExplorerEntry<T> },
161
+ ): ReactNode {
162
+ const { entry, columns, onNavigate, renderFolderActions, getItemKey, renderRow, openProps } =
163
+ props;
164
+ if (entry.kind === 'folder') {
165
+ return (
166
+ <TR key={`folder:${entry.folder.id}`}>
167
+ <TD colSpan={columns.length}>
168
+ <FolderEntry
169
+ folder={entry.folder}
170
+ onNavigate={onNavigate}
171
+ renderFolderActions={renderFolderActions}
172
+ />
173
+ </TD>
174
+ </TR>
175
+ );
176
+ }
177
+ return (
178
+ <TR key={`item:${getItemKey(entry.item)}`} {...openProps(entry.item)}>
179
+ {renderRow(entry.item)}
180
+ </TR>
181
+ );
182
+ }
183
+
184
+ export function ExplorerBody<T>(props: ExplorerBodyProps<T>): ReactNode {
185
+ const { hasEntries, inFolderCount, emptyStates, viewMode, label, columns, pageEntries, pager } =
186
+ props;
187
+
188
+ if (!hasEntries) {
189
+ // The current folder renders nothing. A filter emptied it (`inFolderCount` > 0)
190
+ // → "no match"; otherwise the folder is genuinely empty. The ladder decides on
191
+ // the full, unsliced sets, never on a page.
192
+ return <EmptyState {...(inFolderCount > 0 ? emptyStates.noMatch : emptyStates.emptyFolder)} />;
193
+ }
194
+
195
+ if (viewMode === 'cards') {
196
+ return (
197
+ <>
198
+ <EntityCardGrid aria-label={label}>
199
+ {pageEntries.map((entry) => (
200
+ <CardEntry key={entryKey(entry, props.getItemKey)} {...props} entry={entry} />
201
+ ))}
202
+ </EntityCardGrid>
203
+ <ExplorerPager {...pager} />
204
+ </>
205
+ );
206
+ }
207
+
208
+ // Folder rows share the item table, spanning every column, sorted above items —
209
+ // so a folder-with-only-subfolders is folder ROWS, never a header-only table.
210
+ // A too-wide table scrolls inside its own box rather than widening the page.
211
+ return (
212
+ <>
213
+ <ScrollRegion label={label}>
214
+ <Table>
215
+ <THead>
216
+ <TR>
217
+ {columns.map((column) => (
218
+ <TH key={column.key} numeric={column.numeric}>
219
+ {column.header}
220
+ </TH>
221
+ ))}
222
+ </TR>
223
+ </THead>
224
+ <TBody>
225
+ {pageEntries.map((entry) => (
226
+ <RowEntry key={entryKey(entry, props.getItemKey)} {...props} entry={entry} />
227
+ ))}
228
+ </TBody>
229
+ </Table>
230
+ </ScrollRegion>
231
+ <ExplorerPager {...pager} />
232
+ </>
233
+ );
234
+ }
235
+
236
+ /** The stable React key for a page entry, folder or item. */
237
+ function entryKey<T>(entry: ExplorerEntry<T>, getItemKey: (item: T) => string): string {
238
+ return entry.kind === 'folder' ? `folder:${entry.folder.id}` : `item:${getItemKey(entry.item)}`;
239
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The explorer's persisted page size, per view surface. Mirrors `useViewMode`: an
3
+ * invalid or absent stored value degrades to the default, and a storage failure
4
+ * degrades to in-memory only — never a thrown boot.
5
+ */
6
+ import { useCallback, useState } from 'react';
7
+
8
+ /** The page-size choices, and the default. */
9
+ export const PAGE_SIZES = [12, 24, 48, 96] as const;
10
+ const DEFAULT_PAGE_SIZE = 24;
11
+
12
+ const PAGE_SIZE_STORAGE_PREFIX = 'tai-studio.page-size.';
13
+
14
+ function readStoredPageSize(surface: string): number {
15
+ try {
16
+ const raw = globalThis.localStorage.getItem(PAGE_SIZE_STORAGE_PREFIX + surface);
17
+ const parsed = raw === null ? Number.NaN : Number(raw);
18
+ if ((PAGE_SIZES as readonly number[]).includes(parsed)) return parsed;
19
+ } catch {
20
+ // No storage (private mode / non-browser) — fall back to the default.
21
+ }
22
+ return DEFAULT_PAGE_SIZE;
23
+ }
24
+
25
+ export function usePageSize(surface: string): readonly [number, (size: number) => void] {
26
+ const [size, setSizeState] = useState<number>(() => readStoredPageSize(surface));
27
+ const setSize = useCallback(
28
+ (next: number) => {
29
+ setSizeState(next);
30
+ try {
31
+ globalThis.localStorage.setItem(PAGE_SIZE_STORAGE_PREFIX + surface, String(next));
32
+ } catch {
33
+ // Storage unavailable — the choice still applies for this session.
34
+ }
35
+ },
36
+ [surface],
37
+ );
38
+ return [size, setSize];
39
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * The explorer's tag filter row: a togglable chip per vocabulary entry, with the
3
+ * unselected chips beyond the cap collapsed into a static "+N more" count.
4
+ */
5
+ import type { ReactNode } from 'react';
6
+
7
+ import type { TagVocabularyEntry } from './explorer-tags';
8
+
9
+ /** A togglable tag chip; `aria-pressed` reflects whether the tag filters the list. */
10
+ function TagChip({
11
+ entry,
12
+ active,
13
+ onToggle,
14
+ }: {
15
+ readonly entry: TagVocabularyEntry;
16
+ readonly active: boolean;
17
+ readonly onToggle: () => void;
18
+ }): ReactNode {
19
+ return (
20
+ <button
21
+ type="button"
22
+ className="tai-chip"
23
+ aria-pressed={active}
24
+ aria-label={`${entry.label} (${String(entry.count)})`}
25
+ onClick={onToggle}
26
+ >
27
+ <span>{entry.label}</span>
28
+ <span>{entry.count}</span>
29
+ </button>
30
+ );
31
+ }
32
+
33
+ /** The filter row: every selected chip plus as many unselected chips as fit under
34
+ * the cap, with the remainder collapsed into a STATIC "+N more" count. An unset
35
+ * cap shows every chip. */
36
+ export function TagFilterRow({
37
+ vocabulary,
38
+ selectedSet,
39
+ onToggle,
40
+ filterLabel,
41
+ maxVisibleTags,
42
+ }: {
43
+ readonly vocabulary: readonly TagVocabularyEntry[];
44
+ readonly selectedSet: ReadonlySet<string>;
45
+ readonly onToggle: (token: string) => void;
46
+ readonly filterLabel: string;
47
+ readonly maxVisibleTags: number | undefined;
48
+ }): ReactNode {
49
+ const visible: TagVocabularyEntry[] = [];
50
+ let hidden = 0;
51
+ let unselectedShown = 0;
52
+ for (const entry of vocabulary) {
53
+ if (selectedSet.has(entry.token)) {
54
+ visible.push(entry);
55
+ } else if (maxVisibleTags === undefined || unselectedShown < maxVisibleTags) {
56
+ visible.push(entry);
57
+ unselectedShown += 1;
58
+ } else {
59
+ hidden += 1;
60
+ }
61
+ }
62
+
63
+ return (
64
+ <div role="group" aria-label={filterLabel} className="tai-row">
65
+ {visible.map((entry) => (
66
+ <TagChip
67
+ key={entry.token}
68
+ entry={entry}
69
+ active={selectedSet.has(entry.token)}
70
+ onToggle={() => {
71
+ onToggle(entry.token);
72
+ }}
73
+ />
74
+ ))}
75
+ {hidden > 0 ? (
76
+ <span className="tai-chip tai-chip-static">{`+${String(hidden)} more`}</span>
77
+ ) : null}
78
+ </div>
79
+ );
80
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * The tag glue every explorer screen shares: the untagged sentinel, the tag
3
+ * vocabulary builder, and the OR-match rule — one vocabulary/untagged/OR
4
+ * definition rather than a copy per screen.
5
+ */
6
+
7
+ /** Reserved filter token for items carrying NO tag; namespaced so it never
8
+ * collides with a real tag. */
9
+ export const UNTAGGED_TOKEN = '__untagged__';
10
+
11
+ export interface TagVocabularyEntry {
12
+ readonly token: string;
13
+ readonly label: string;
14
+ readonly count: number;
15
+ }
16
+
17
+ /** The tag vocabulary over `items`, name-sorted, plus an untagged pseudo-tag
18
+ * (labelled `untaggedLabel`) when any item is untagged; a selected token whose
19
+ * items vanished still appears (count 0) so it can be cleared. */
20
+ export function buildTagVocabulary<T>(
21
+ items: readonly T[],
22
+ getTags: (item: T) => readonly string[],
23
+ selectedTags: readonly string[],
24
+ untaggedLabel: string,
25
+ ): TagVocabularyEntry[] {
26
+ const counts = new Map<string, number>();
27
+ let untagged = 0;
28
+ for (const item of items) {
29
+ const tags = getTags(item);
30
+ if (tags.length === 0) {
31
+ untagged += 1;
32
+ continue;
33
+ }
34
+ for (const tag of tags) counts.set(tag, (counts.get(tag) ?? 0) + 1);
35
+ }
36
+ const vocabulary: TagVocabularyEntry[] = [...counts.entries()]
37
+ .sort(([a], [b]) => a.localeCompare(b))
38
+ .map(([label, count]) => ({ token: label, label, count }));
39
+ if (untagged > 0) {
40
+ vocabulary.push({ token: UNTAGGED_TOKEN, label: untaggedLabel, count: untagged });
41
+ }
42
+ for (const token of selectedTags) {
43
+ if (!vocabulary.some((entry) => entry.token === token)) {
44
+ vocabulary.push({
45
+ token,
46
+ label: token === UNTAGGED_TOKEN ? untaggedLabel : token,
47
+ count: 0,
48
+ });
49
+ }
50
+ }
51
+ return vocabulary;
52
+ }
53
+
54
+ /** OR semantics: an empty selection matches everything; otherwise an item
55
+ * matches when it carries any selected tag, or is untagged and UNTAGGED_TOKEN
56
+ * is selected. */
57
+ export function matchesSelectedTags(
58
+ itemTags: readonly string[],
59
+ selected: ReadonlySet<string>,
60
+ ): boolean {
61
+ if (selected.size === 0) return true;
62
+ if (itemTags.length === 0) return selected.has(UNTAGGED_TOKEN);
63
+ return itemTags.some((tag) => selected.has(tag));
64
+ }