@tai42/studio-sdk 25.0.1 → 27.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 (262) hide show
  1. package/README.md +143 -26
  2. package/dist/components/action-menu.d.ts +30 -0
  3. package/dist/components/action-menu.d.ts.map +1 -0
  4. package/dist/components/action-menu.js +101 -0
  5. package/dist/components/action-menu.js.map +1 -0
  6. package/dist/components/agent-picker.d.ts +22 -0
  7. package/dist/components/agent-picker.d.ts.map +1 -0
  8. package/dist/components/agent-picker.js +17 -0
  9. package/dist/components/agent-picker.js.map +1 -0
  10. package/dist/components/channel-picker.d.ts +27 -0
  11. package/dist/components/channel-picker.d.ts.map +1 -0
  12. package/dist/components/channel-picker.js +26 -0
  13. package/dist/components/channel-picker.js.map +1 -0
  14. package/dist/components/components.css +226 -8
  15. package/dist/components/confirm-dialog.d.ts +3 -1
  16. package/dist/components/confirm-dialog.d.ts.map +1 -1
  17. package/dist/components/confirm-dialog.js +2 -2
  18. package/dist/components/confirm-dialog.js.map +1 -1
  19. package/dist/components/execution-key-picker.d.ts +26 -10
  20. package/dist/components/execution-key-picker.d.ts.map +1 -1
  21. package/dist/components/execution-key-picker.js +134 -15
  22. package/dist/components/execution-key-picker.js.map +1 -1
  23. package/dist/components/extension-combo-builder.d.ts +7 -7
  24. package/dist/components/extension-combo-builder.d.ts.map +1 -1
  25. package/dist/components/extension-combo-builder.js +42 -16
  26. package/dist/components/extension-combo-builder.js.map +1 -1
  27. package/dist/components/extension-combo-parts.d.ts +13 -11
  28. package/dist/components/extension-combo-parts.d.ts.map +1 -1
  29. package/dist/components/extension-combo-parts.js +10 -19
  30. package/dist/components/extension-combo-parts.js.map +1 -1
  31. package/dist/components/extension-config-editor.d.ts +33 -0
  32. package/dist/components/extension-config-editor.d.ts.map +1 -0
  33. package/dist/components/extension-config-editor.js +190 -0
  34. package/dist/components/extension-config-editor.js.map +1 -0
  35. package/dist/components/extension-grouping.d.ts +4 -41
  36. package/dist/components/extension-grouping.d.ts.map +1 -1
  37. package/dist/components/extension-grouping.js +1 -48
  38. package/dist/components/extension-grouping.js.map +1 -1
  39. package/dist/components/extension-picker.d.ts +4 -3
  40. package/dist/components/extension-picker.d.ts.map +1 -1
  41. package/dist/components/extension-picker.js +6 -6
  42. package/dist/components/extension-picker.js.map +1 -1
  43. package/dist/components/fleet-report.d.ts +8 -3
  44. package/dist/components/fleet-report.d.ts.map +1 -1
  45. package/dist/components/fleet-report.js +12 -2
  46. package/dist/components/fleet-report.js.map +1 -1
  47. package/dist/components/holder-kinds.d.ts +18 -0
  48. package/dist/components/holder-kinds.d.ts.map +1 -0
  49. package/dist/components/holder-kinds.js +41 -0
  50. package/dist/components/holder-kinds.js.map +1 -0
  51. package/dist/components/holder-list.d.ts +58 -0
  52. package/dist/components/holder-list.d.ts.map +1 -0
  53. package/dist/components/holder-list.js +77 -0
  54. package/dist/components/holder-list.js.map +1 -0
  55. package/dist/components/icons/index.d.ts +1 -1
  56. package/dist/components/icons/index.d.ts.map +1 -1
  57. package/dist/components/icons/index.js +1 -1
  58. package/dist/components/icons/index.js.map +1 -1
  59. package/dist/components/icons/nav-map.d.ts.map +1 -1
  60. package/dist/components/icons/nav-map.js +1 -3
  61. package/dist/components/icons/nav-map.js.map +1 -1
  62. package/dist/components/icons/nav-marks.d.ts +0 -4
  63. package/dist/components/icons/nav-marks.d.ts.map +1 -1
  64. package/dist/components/icons/nav-marks.js +0 -4
  65. package/dist/components/icons/nav-marks.js.map +1 -1
  66. package/dist/components/named-list-picker.d.ts +39 -0
  67. package/dist/components/named-list-picker.d.ts.map +1 -0
  68. package/dist/components/named-list-picker.js +61 -0
  69. package/dist/components/named-list-picker.js.map +1 -0
  70. package/dist/components/named-list-test-utils.d.ts +23 -0
  71. package/dist/components/named-list-test-utils.d.ts.map +1 -0
  72. package/dist/components/named-list-test-utils.js +33 -0
  73. package/dist/components/named-list-test-utils.js.map +1 -0
  74. package/dist/components/recycle-roll.d.ts +23 -0
  75. package/dist/components/recycle-roll.d.ts.map +1 -0
  76. package/dist/components/recycle-roll.js +47 -0
  77. package/dist/components/recycle-roll.js.map +1 -0
  78. package/dist/components/stepper.d.ts +28 -0
  79. package/dist/components/stepper.d.ts.map +1 -0
  80. package/dist/components/stepper.js +33 -0
  81. package/dist/components/stepper.js.map +1 -0
  82. package/dist/components/subject-section.d.ts +2 -1
  83. package/dist/components/subject-section.d.ts.map +1 -1
  84. package/dist/components/subject-section.js +10 -5
  85. package/dist/components/subject-section.js.map +1 -1
  86. package/dist/components/tokens.css +31 -41
  87. package/dist/components/tokens.d.ts +3 -4
  88. package/dist/components/tokens.d.ts.map +1 -1
  89. package/dist/components/tokens.js +5 -13
  90. package/dist/components/tokens.js.map +1 -1
  91. package/dist/components/tool-picker-parts.d.ts +5 -1
  92. package/dist/components/tool-picker-parts.d.ts.map +1 -1
  93. package/dist/components/tool-picker-parts.js +8 -6
  94. package/dist/components/tool-picker-parts.js.map +1 -1
  95. package/dist/components/tool-picker.d.ts +77 -2
  96. package/dist/components/tool-picker.d.ts.map +1 -1
  97. package/dist/components/tool-picker.js +87 -29
  98. package/dist/components/tool-picker.js.map +1 -1
  99. package/dist/components/version-history-panel.d.ts +7 -1
  100. package/dist/components/version-history-panel.d.ts.map +1 -1
  101. package/dist/components/version-history-panel.js +2 -2
  102. package/dist/components/version-history-panel.js.map +1 -1
  103. package/dist/components/version-history-rows.d.ts +4 -2
  104. package/dist/components/version-history-rows.d.ts.map +1 -1
  105. package/dist/components/version-history-rows.js +14 -2
  106. package/dist/components/version-history-rows.js.map +1 -1
  107. package/dist/errors.d.ts +5 -0
  108. package/dist/errors.d.ts.map +1 -1
  109. package/dist/errors.js +7 -0
  110. package/dist/errors.js.map +1 -1
  111. package/dist/hooks/useApi.d.ts +524 -197
  112. package/dist/hooks/useApi.d.ts.map +1 -1
  113. package/dist/hooks/useCapabilities.d.ts +43 -10
  114. package/dist/hooks/useCapabilities.d.ts.map +1 -1
  115. package/dist/hooks/useCapabilities.js +39 -10
  116. package/dist/hooks/useCapabilities.js.map +1 -1
  117. package/dist/index.d.ts +25 -12
  118. package/dist/index.d.ts.map +1 -1
  119. package/dist/index.js +14 -6
  120. package/dist/index.js.map +1 -1
  121. package/dist/marketplace-install/env-var-fields.d.ts +17 -0
  122. package/dist/marketplace-install/env-var-fields.d.ts.map +1 -0
  123. package/dist/marketplace-install/env-var-fields.js +22 -0
  124. package/dist/marketplace-install/env-var-fields.js.map +1 -0
  125. package/dist/marketplace-install/index.d.ts +18 -0
  126. package/dist/marketplace-install/index.d.ts.map +1 -0
  127. package/dist/marketplace-install/index.js +8 -0
  128. package/dist/marketplace-install/index.js.map +1 -0
  129. package/dist/marketplace-install/install-env.d.ts +21 -0
  130. package/dist/marketplace-install/install-env.d.ts.map +1 -0
  131. package/dist/marketplace-install/install-env.js +22 -0
  132. package/dist/marketplace-install/install-env.js.map +1 -0
  133. package/dist/marketplace-install/install-mount.d.ts +42 -0
  134. package/dist/marketplace-install/install-mount.d.ts.map +1 -0
  135. package/dist/marketplace-install/install-mount.js +62 -0
  136. package/dist/marketplace-install/install-mount.js.map +1 -0
  137. package/dist/marketplace-install/install-report.d.ts +14 -0
  138. package/dist/marketplace-install/install-report.d.ts.map +1 -0
  139. package/dist/marketplace-install/install-report.js +19 -0
  140. package/dist/marketplace-install/install-report.js.map +1 -0
  141. package/dist/marketplace-install/install-shell.d.ts +34 -0
  142. package/dist/marketplace-install/install-shell.d.ts.map +1 -0
  143. package/dist/marketplace-install/install-shell.js +32 -0
  144. package/dist/marketplace-install/install-shell.js.map +1 -0
  145. package/dist/marketplace-install/mount-install.d.ts +41 -0
  146. package/dist/marketplace-install/mount-install.d.ts.map +1 -0
  147. package/dist/marketplace-install/mount-install.js +90 -0
  148. package/dist/marketplace-install/mount-install.js.map +1 -0
  149. package/dist/marketplace-install/plugin-detail.d.ts +17 -0
  150. package/dist/marketplace-install/plugin-detail.d.ts.map +1 -0
  151. package/dist/marketplace-install/plugin-detail.js +41 -0
  152. package/dist/marketplace-install/plugin-detail.js.map +1 -0
  153. package/dist/marketplace-install/plugin-install.d.ts +27 -0
  154. package/dist/marketplace-install/plugin-install.d.ts.map +1 -0
  155. package/dist/marketplace-install/plugin-install.js +89 -0
  156. package/dist/marketplace-install/plugin-install.js.map +1 -0
  157. package/dist/marketplace-install/route-items.d.ts +14 -0
  158. package/dist/marketplace-install/route-items.d.ts.map +1 -0
  159. package/dist/marketplace-install/route-items.js +11 -0
  160. package/dist/marketplace-install/route-items.js.map +1 -0
  161. package/dist/marketplace-install/use-debounced-value.d.ts +6 -0
  162. package/dist/marketplace-install/use-debounced-value.d.ts.map +1 -0
  163. package/dist/marketplace-install/use-debounced-value.js +18 -0
  164. package/dist/marketplace-install/use-debounced-value.js.map +1 -0
  165. package/dist/marketplace-install/use-install-action.d.ts +26 -0
  166. package/dist/marketplace-install/use-install-action.d.ts.map +1 -0
  167. package/dist/marketplace-install/use-install-action.js +35 -0
  168. package/dist/marketplace-install/use-install-action.js.map +1 -0
  169. package/dist/marketplace-install/use-install-preview.d.ts +33 -0
  170. package/dist/marketplace-install/use-install-preview.d.ts.map +1 -0
  171. package/dist/marketplace-install/use-install-preview.js +44 -0
  172. package/dist/marketplace-install/use-install-preview.js.map +1 -0
  173. package/dist/marketplace-install/use-mount-install.d.ts +80 -0
  174. package/dist/marketplace-install/use-mount-install.d.ts.map +1 -0
  175. package/dist/marketplace-install/use-mount-install.js +75 -0
  176. package/dist/marketplace-install/use-mount-install.js.map +1 -0
  177. package/dist/navigation/index.d.ts +1 -1
  178. package/dist/navigation/index.d.ts.map +1 -1
  179. package/dist/navigation/index.js.map +1 -1
  180. package/dist/navigation/types.d.ts +23 -7
  181. package/dist/navigation/types.d.ts.map +1 -1
  182. package/dist/plugin/registry.d.ts +0 -8
  183. package/dist/plugin/registry.d.ts.map +1 -1
  184. package/dist/plugin/registry.js +25 -1
  185. package/dist/plugin/registry.js.map +1 -1
  186. package/dist/plugin/types.d.ts +36 -12
  187. package/dist/plugin/types.d.ts.map +1 -1
  188. package/dist/plugin/version.d.ts +6 -4
  189. package/dist/plugin/version.d.ts.map +1 -1
  190. package/dist/plugin/version.js +6 -4
  191. package/dist/plugin/version.js.map +1 -1
  192. package/dist/query-keys.d.ts +45 -4
  193. package/dist/query-keys.d.ts.map +1 -1
  194. package/dist/query-keys.js +52 -4
  195. package/dist/query-keys.js.map +1 -1
  196. package/dist/schema-form/json-schema-meta.d.ts +3 -0
  197. package/dist/schema-form/json-schema-meta.d.ts.map +1 -0
  198. package/dist/schema-form/json-schema-meta.js +3 -0
  199. package/dist/schema-form/json-schema-meta.js.map +1 -0
  200. package/dist/testing.d.ts +2 -0
  201. package/dist/testing.d.ts.map +1 -1
  202. package/dist/testing.js +2 -0
  203. package/dist/testing.js.map +1 -1
  204. package/dist/token-rules.d.ts +26 -0
  205. package/dist/token-rules.d.ts.map +1 -0
  206. package/dist/token-rules.js +64 -0
  207. package/dist/token-rules.js.map +1 -0
  208. package/package.json +2 -2
  209. package/src/components/action-menu.tsx +160 -0
  210. package/src/components/agent-picker.tsx +53 -0
  211. package/src/components/channel-picker.tsx +68 -0
  212. package/src/components/components.css +226 -8
  213. package/src/components/confirm-dialog.tsx +4 -1
  214. package/src/components/execution-key-picker.tsx +252 -36
  215. package/src/components/extension-combo-builder.tsx +61 -29
  216. package/src/components/extension-combo-parts.tsx +28 -38
  217. package/src/components/extension-config-editor.tsx +307 -0
  218. package/src/components/extension-grouping.ts +4 -73
  219. package/src/components/extension-picker.tsx +13 -13
  220. package/src/components/fleet-report.tsx +38 -4
  221. package/src/components/holder-kinds.ts +60 -0
  222. package/src/components/holder-list.tsx +163 -0
  223. package/src/components/icons/index.ts +0 -2
  224. package/src/components/icons/nav-map.ts +0 -4
  225. package/src/components/icons/nav-marks.tsx +0 -15
  226. package/src/components/named-list-picker.tsx +182 -0
  227. package/src/components/named-list-test-utils.tsx +47 -0
  228. package/src/components/recycle-roll.tsx +120 -0
  229. package/src/components/stepper.tsx +111 -0
  230. package/src/components/subject-section.tsx +10 -5
  231. package/src/components/tokens.css +31 -41
  232. package/src/components/tokens.ts +5 -13
  233. package/src/components/tool-picker-parts.tsx +17 -6
  234. package/src/components/tool-picker.tsx +215 -41
  235. package/src/components/version-history-panel.tsx +8 -0
  236. package/src/components/version-history-rows.tsx +14 -2
  237. package/src/errors.ts +10 -0
  238. package/src/hooks/useCapabilities.ts +59 -10
  239. package/src/index.ts +54 -14
  240. package/src/marketplace-install/env-var-fields.tsx +59 -0
  241. package/src/marketplace-install/index.ts +17 -0
  242. package/src/marketplace-install/install-env.ts +39 -0
  243. package/src/marketplace-install/install-mount.ts +96 -0
  244. package/src/marketplace-install/install-report.tsx +54 -0
  245. package/src/marketplace-install/install-shell.tsx +99 -0
  246. package/src/marketplace-install/mount-install.tsx +290 -0
  247. package/src/marketplace-install/plugin-detail.ts +60 -0
  248. package/src/marketplace-install/plugin-install.tsx +221 -0
  249. package/src/marketplace-install/route-items.ts +20 -0
  250. package/src/marketplace-install/use-debounced-value.ts +18 -0
  251. package/src/marketplace-install/use-install-action.ts +60 -0
  252. package/src/marketplace-install/use-install-preview.ts +74 -0
  253. package/src/marketplace-install/use-mount-install.ts +116 -0
  254. package/src/navigation/index.ts +1 -0
  255. package/src/navigation/types.ts +27 -7
  256. package/src/plugin/registry.ts +19 -1
  257. package/src/plugin/types.ts +40 -12
  258. package/src/plugin/version.ts +6 -4
  259. package/src/query-keys.ts +71 -4
  260. package/src/schema-form/json-schema-meta.ts +2 -0
  261. package/src/testing.ts +2 -0
  262. package/src/token-rules.ts +66 -0
package/README.md CHANGED
@@ -27,8 +27,9 @@ pnpm add @tai42/studio-sdk
27
27
  - `@tai42/studio-sdk/schema-form` — a form-only `SchemaForm` entry for bundling
28
28
  consumers that want the form without the barrel. It imports no CSS by design —
29
29
  a subpath consumer loads `tokens.css` and `components.css` explicitly.
30
- - `@tai42/studio-sdk/testing` — test-only helpers: a registry reset and
31
- `installJsdomStubs()`, which fills the browser APIs jsdom omits.
30
+ - `@tai42/studio-sdk/testing` — test-only helpers: a registry reset,
31
+ `installJsdomStubs()`, which fills the browser APIs jsdom omits, and
32
+ `destructiveColorOffences()`, the destructive-emphasis rule below.
32
33
  - `@tai42/studio-sdk/tokens.css` — the design-token stylesheet. It also emits the
33
34
  canonical `@layer` order, so a host imports it FIRST.
34
35
  - `@tai42/studio-sdk/fonts.css` — the self-hosted Inter Variable and Geist Mono
@@ -107,8 +108,8 @@ than the SDK — it compiles Tailwind v4, whose output needs `@property` and
107
108
 
108
109
  `tokens.css` is the styling API: a plugin styles against these names and gets
109
110
  whichever half the viewer's theme resolves to. The names are also exported as
110
- `TOKEN_NAMES` (86 of them), and the list grows additively — a rename or a removal
111
- bumps the SDK compatibility version.
111
+ `TOKEN_NAMES` (79 of them). A new name is not a break; a rename or a removal is a
112
+ breaking change that bumps `STUDIO_PLUGIN_API_VERSION`.
112
113
 
113
114
  The light value is the token; the dark value sits beside it under a
114
115
  `--tai-dark-` name that a plugin never reads. Two blocks put the dark half into
@@ -172,8 +173,8 @@ icons; the `-fill` members are for fills and charts and carry `on-fill` ink.
172
173
 
173
174
  | Token | Light | Dark |
174
175
  | ----------------------- | ------------------------- | --------------------------- |
175
- | `--tai-color-ok-text` | `#047857` | `#34d399` |
176
- | `--tai-color-err-text` | `#b91c1c` | `#f87171` |
176
+ | `--tai-color-ok-text` | `#065f46` | `#34d399` |
177
+ | `--tai-color-err-text` | `#b91c1c` | `#fca5a5` |
177
178
  | `--tai-color-warn-text` | `#92400e` | `#fbbf24` |
178
179
  | `--tai-color-ok-fill` | `#10b981` | `#34d399` |
179
180
  | `--tai-color-err-fill` | `#ef4444` | `#f87171` |
@@ -196,22 +197,18 @@ icons; the `-fill` members are for fills and charts and carry `on-fill` ink.
196
197
  | `--tai-color-syntax-number` | `var(--tai-color-accent)` | _(same)_ |
197
198
  | `--tai-color-syntax-bool` | `var(--tai-color-warn-text)` | _(same)_ |
198
199
 
199
- **Legacy slots.** The names a plugin already styles against. `primary`,
200
- `success` and `warning` re-point at the members of the contract above that keep
201
- them legible; `danger` is its own destructive emphasis — a deep red that runs
202
- darker than the brand accent in both themes so a destructive control is never
203
- mistaken for the primary one, with a white label and a hover a shade deeper.
204
-
205
- | Token | Light | Dark |
206
- | ---------------------------- | ---------------------------- | --------- |
207
- | `--tai-color-primary` | `var(--tai-color-accent)` | _(same)_ |
208
- | `--tai-color-primary-text` | `var(--tai-color-on-accent)` | _(same)_ |
209
- | `--tai-color-danger` | `#991b1b` | `#dc2626` |
210
- | `--tai-color-danger-text` | `#ffffff` | `#ffffff` |
211
- | `--tai-color-danger-hover` | `#7f1d1d` | `#b91c1c` |
212
- | `--tai-color-danger-surface` | `var(--tai-color-err-tint)` | _(same)_ |
213
- | `--tai-color-success` | `var(--tai-color-ok-text)` | _(same)_ |
214
- | `--tai-color-warning` | `var(--tai-color-warn-text)` | _(same)_ |
200
+ **Destructive emphasis.** A fill for the destructive button only, never text:
201
+ error text takes `--tai-color-err-text`. It is a deep red that runs darker than
202
+ the brand accent in both themes, so a destructive control is never mistaken for
203
+ the primary one, with a white label and a hover a shade deeper. A plugin checks its
204
+ own styles against this rule with `destructiveColorOffences()` from
205
+ `@tai42/studio-sdk/testing`.
206
+
207
+ | Token | Light | Dark |
208
+ | ------------------------------- | --------- | --------- |
209
+ | `--tai-color-destructive` | `#991b1b` | `#dc2626` |
210
+ | `--tai-color-destructive-hover` | `#7f1d1d` | `#b91c1c` |
211
+ | `--tai-color-on-destructive` | `#ffffff` | `#ffffff` |
215
212
 
216
213
  **Spacing** (n × 4; there is deliberately no `space-7`). Authored in `rem` so a
217
214
  viewer's font-size preference scales them; the px column is the rendered size at
@@ -262,8 +259,7 @@ preference without reading the media query.
262
259
  | `--tai-motion-base` | `250ms` |
263
260
 
264
261
  **Elevation.** Only the shadow COLOUR varies by theme; the geometry is written
265
- once, so a dark override cannot silently move an offset or a blur. `shadow-sm`
266
- and `shadow-md` are legacy slots that now alias the lift and overlay geometry.
262
+ once, so a dark override cannot silently move an offset or a blur.
267
263
 
268
264
  | Token | Light | Dark |
269
265
  | ---------------------------- | --------------------------------------------- | ------------------- |
@@ -271,8 +267,6 @@ and `shadow-md` are legacy slots that now alias the lift and overlay geometry.
271
267
  | `--tai-shadow-overlay-color` | `rgb(0 0 0 / 0.16)` | `rgb(0 0 0 / 0.6)` |
272
268
  | `--tai-shadow-lift` | `0 12px 32px var(--tai-shadow-lift-color)` | _(same)_ |
273
269
  | `--tai-shadow-overlay` | `0 24px 48px var(--tai-shadow-overlay-color)` | _(same)_ |
274
- | `--tai-shadow-sm` | `var(--tai-shadow-lift)` | _(same)_ |
275
- | `--tai-shadow-md` | `var(--tai-shadow-overlay)` | _(same)_ |
276
270
 
277
271
  **Stacking.** `popover` and `tooltip` sit ABOVE the modal layers on purpose: both
278
272
  portal to the document body as siblings of a dialog and have to clear its scrim
@@ -350,6 +344,129 @@ is something the sheet can supply for you:
350
344
  9. **`--shell-topbar-height` is private to the sheet**, deliberately outside the
351
345
  `--tai-*` contract. Do not read it; it is not part of the published API.
352
346
 
347
+ ## Design rules
348
+
349
+ These rules hold for every Studio screen and for a plugin page that wants to sit
350
+ beside them. They name the SDK pieces each case is built from, so a screen reads
351
+ the same way wherever it comes from.
352
+
353
+ **Tokens.** Colour, space, radius, type, motion and elevation come only from the
354
+ names in `TOKEN_NAMES`; a literal colour is never written. Every colour pair is
355
+ checked in both themes, the light `--tai-color-*` and the dark
356
+ `--tai-dark-color-*` values. A status is never told by hue alone: an icon or a word
357
+ sits beside it. The accent is the brand colour only, never a status.
358
+
359
+ **Spacing.** A page is padded by `.tai-page`. Vertical rhythm is `.tai-stack`
360
+ (space-4); inside a group it is `.tai-stack-2`, between groups in a card
361
+ `.tai-stack-3`, and between the sections of a page `.tai-stack-6`. A row of
362
+ controls is `.tai-row`.
363
+
364
+ **Screen patterns.** A new screen uses one of these patterns. A screen with tabs
365
+ under its header (Settings, Dashboard, Marketplace, the Conversations landing)
366
+ takes a pattern per tab.
367
+
368
+ - **Browse and inspect.** A split list and detail (`.tai-split`), with the
369
+ selection held in the URL search. Tools, whose list pane is an `ExplorerView`;
370
+ Presets; States; Storage; a Conversations route, its threads beside the open
371
+ transcript.
372
+ - **Catalog.** A directory of cards with search and filters. Connectors and the
373
+ Tools card view, through `ExplorerView`; the Marketplace Browse tab, a card grid
374
+ with facet filters and Load more.
375
+ - **Registry.** Tables or lists of records in cards. Create and the row actions
376
+ open a dialog built on `Dialog` (`FormDialog` or the screen's own); edit opens
377
+ one too or happens in place; a destructive action is confirmed before it runs.
378
+ Scheduling, Members, the Conversations routes and per-target configs, the
379
+ Marketplace Installed tab, and the Profiles, API keys and Roles tabs of
380
+ Settings.
381
+ - **Registry with inline create.** The records list first, then the create forms
382
+ in cards on the page below them; edit, where a record has one, in a `Dialog`; a
383
+ destructive action confirmed before it runs. Hooks, Served endpoints.
384
+ - **Replaced detail.** A search param swaps the page or the tab for one item. The
385
+ Marketplace plugin page, a trace in the Dashboard Tracing tab, a state template
386
+ or a state's records.
387
+ - **Run surface.** A list, then the run view in its place. Agents.
388
+ - **Inbox.** Newest-first cards, the rest paged in by a button at the foot: Load
389
+ more where the server pages (Interactions), Show more where the whole feed is
390
+ already loaded (Notifications).
391
+ - **Status and configuration.** Stacked cards of read-only views and in-place
392
+ editors, no create dialog; a destructive or fleet-wide action is confirmed in a
393
+ `ConfirmDialog`. Manifest, System, the Dashboard tab of Dashboard, the Settings,
394
+ Environment and Backup tabs of Settings, and the Failed deliveries tab of the
395
+ Conversations landing (one read-only card that re-reads itself).
396
+
397
+ A multi-step create is a `Stepper` inside a `Dialog`.
398
+
399
+ **States.** A page or a region (a card, a pane, a tab) shows one state at a time,
400
+ each drawn by its SDK piece:
401
+
402
+ - loading: a `Skeleton` in the shape of the content, or a labelled `Spinner` where
403
+ the content has no fixed shape;
404
+ - empty: an `EmptyState` whose title says what is missing and whose `action`
405
+ gives the next step;
406
+ - off, when the server answers that the feature is not configured:
407
+ `FeatureDisabled`;
408
+ - no grant: as below;
409
+ - failed: an `ErrorState`, with `onRetry` when a retry can succeed;
410
+ - then the content.
411
+
412
+ Content already drawn stays when a later read fails (the next page, a secondary
413
+ read): the failure is shown beside it, as an `ErrorState` or a muted line saying
414
+ what could not be read and why. A control inside a form follows the picker rules
415
+ instead.
416
+
417
+ **No grant.** What the caller's access does not reach is not drawn. A write
418
+ control is hidden through `useCanWrite`, never shown disabled, and in its place,
419
+ where the reader would look for it, a muted `role="status"` line says what is out
420
+ of reach and, where the screen knows it, the access it needs ("Running this tool
421
+ is outside your access — it is shown read-only."). A whole region the caller
422
+ cannot read is an `EmptyState` whose title says it is not available and whose
423
+ description says what it would show and the access it needs. A no-grant state
424
+ has no Retry and never wears the error ground: a refusal is an answer, not a
425
+ failure. Readable content stays, read-only. A secondary control (a row's Delete)
426
+ is hidden without a line. A screen the caller cannot reach leaves the sidebar;
427
+ its URL still renders, and a refusal the screen did not expect is an
428
+ `ErrorState`.
429
+
430
+ **Disabled controls and results.** A control disabled for a reason the screen
431
+ does not otherwise show says the reason in text beside it. There is no toast: a
432
+ result is shown inline next to the control that caused it, a `role="status"` line
433
+ for an outcome and `role="alert"` (or an `ErrorState`) for a failure.
434
+
435
+ **Pickers.** A picker is an SDK component wrapped in `Field` with a visible
436
+ label. It reads a structural query interface
437
+ (`{ data, isPending, isError, isSuccess, error, refetch }`, the shape
438
+ `ExecutionKeyPicker` takes) and names no query library. Pending is the control
439
+ disabled with the placeholder "Loading <plural noun>…"; error is an `ErrorState`
440
+ with retry inside the field (`group` set); empty is a muted `role="status"` line
441
+ naming where to create one; no grant to read the list is the no-grant line in
442
+ place of the control. Values render as text, never HTML. A picker is composed
443
+ outside `SchemaForm`. Two cases differ:
444
+
445
+ - A picker that is one control of a larger group on its host (a `fieldset` whose
446
+ `legend` names the group) takes no label of its own: its control carries an
447
+ `aria-label` that names it within the group (the legend, then what the control
448
+ picks), and its states render in the same place without a `Field`.
449
+ - When the read behind the list fails and the same failure is already shown once,
450
+ with retry, elsewhere on the same surface, the picker draws no second
451
+ `ErrorState`: in place of the control it shows a muted `role="status"` line
452
+ saying the list could not be read and where that error is shown, with no retry.
453
+ A surface shows one failure with retry once.
454
+
455
+ **Stepper.** An ordered list in a labelled `nav`, with `aria-current="step"` on
456
+ the current step and each step's status spoken in visually hidden text. Done,
457
+ current, upcoming and error are told apart by marker shape and icon as well as
458
+ colour, filled with the ok and err tokens (never the accent, never a destructive
459
+ token). Tab and Enter or Space reach only the steps that can be revisited. Below
460
+ the narrow breakpoint (640 px) the list collapses to "Step n of m: <label>".
461
+ Motion follows the reduced-motion rule, and targets are 44 px on coarse pointers.
462
+
463
+ **Keyboard and accessibility.** There are no global shortcuts. Every interactive
464
+ element is reachable by Tab in reading order; Enter and Space work on custom rows;
465
+ the focus-visible ring comes from the five-state contract. A route change moves
466
+ focus to the page `<h1>`; dialogs trap focus and return it. The bar is WCAG
467
+ 2.0/2.1 A and AA in both themes, enforced by an axe audit over every route and by
468
+ the SDK's guard tests.
469
+
353
470
  ## Usage
354
471
 
355
472
  ```ts
@@ -0,0 +1,30 @@
1
+ /**
2
+ * `ActionMenu` — a row's or a card's overflow menu: a ghost "Actions" button
3
+ * whose accessible name the caller completes ("Actions for <name>", which keeps
4
+ * the visible word at its start) that opens a `role="menu"` list of
5
+ * `role="menuitem"` buttons, the WAI-ARIA menu-button pattern.
6
+ *
7
+ * Opening moves focus to the first item; ArrowDown/ArrowUp move between items
8
+ * (wrapping), Home/End jump to the ends, Escape closes and returns focus to the
9
+ * trigger, Tab closes. Activating an item closes the menu, returns focus to the
10
+ * trigger, then runs the item's action, so a dialog the action opens takes focus
11
+ * from a settled trigger. A pointer press outside the menu closes it.
12
+ *
13
+ * The caller passes only the items the session may use; with none the menu is
14
+ * not drawn at all (a hidden control takes no line).
15
+ */
16
+ import { type ReactNode } from 'react';
17
+ export interface ActionMenuItem {
18
+ readonly id: string;
19
+ readonly label: string;
20
+ readonly onSelect: () => void;
21
+ /** Paints the item in the error tone (a destructive action). */
22
+ readonly danger?: boolean;
23
+ }
24
+ export interface ActionMenuProps {
25
+ /** The trigger's accessible name, e.g. "Actions for Acme". */
26
+ readonly label: string;
27
+ readonly items: readonly ActionMenuItem[];
28
+ }
29
+ export declare function ActionMenu({ label, items }: ActionMenuProps): ReactNode;
30
+ //# sourceMappingURL=action-menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-menu.d.ts","sourceRoot":"","sources":["../../src/components/action-menu.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAsB,KAAK,SAAS,EAAsC,MAAM,OAAO,CAAC;AAI/F,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;IAC9B,gEAAgE;IAChE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;CAC3C;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,eAAe,GAAG,SAAS,CA8HvE"}
@@ -0,0 +1,101 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * `ActionMenu` — a row's or a card's overflow menu: a ghost "Actions" button
4
+ * whose accessible name the caller completes ("Actions for <name>", which keeps
5
+ * the visible word at its start) that opens a `role="menu"` list of
6
+ * `role="menuitem"` buttons, the WAI-ARIA menu-button pattern.
7
+ *
8
+ * Opening moves focus to the first item; ArrowDown/ArrowUp move between items
9
+ * (wrapping), Home/End jump to the ends, Escape closes and returns focus to the
10
+ * trigger, Tab closes. Activating an item closes the menu, returns focus to the
11
+ * trigger, then runs the item's action, so a dialog the action opens takes focus
12
+ * from a settled trigger. A pointer press outside the menu closes it.
13
+ *
14
+ * The caller passes only the items the session may use; with none the menu is
15
+ * not drawn at all (a hidden control takes no line).
16
+ */
17
+ import { useEffect, useId, useRef, useState } from 'react';
18
+ import { ChevronDownIcon } from './icons';
19
+ export function ActionMenu({ label, items }) {
20
+ const [open, setOpen] = useState(false);
21
+ const menuId = useId();
22
+ const triggerRef = useRef(null);
23
+ const menuRef = useRef(null);
24
+ const itemRefs = useRef([]);
25
+ useEffect(() => {
26
+ if (!open)
27
+ return undefined;
28
+ itemRefs.current[0]?.focus();
29
+ const onPointerDown = (event) => {
30
+ const target = event.target;
31
+ if (target === null)
32
+ return;
33
+ if (menuRef.current?.contains(target) === true)
34
+ return;
35
+ if (triggerRef.current?.contains(target) === true)
36
+ return;
37
+ setOpen(false);
38
+ };
39
+ document.addEventListener('pointerdown', onPointerDown);
40
+ return () => {
41
+ document.removeEventListener('pointerdown', onPointerDown);
42
+ };
43
+ }, [open]);
44
+ if (items.length === 0)
45
+ return null;
46
+ const close = () => {
47
+ setOpen(false);
48
+ triggerRef.current?.focus();
49
+ };
50
+ const focusItem = (index) => {
51
+ const count = items.length;
52
+ itemRefs.current[((index % count) + count) % count]?.focus();
53
+ };
54
+ const onMenuKeyDown = (event) => {
55
+ const current = itemRefs.current.findIndex((item) => item === document.activeElement);
56
+ switch (event.key) {
57
+ case 'ArrowDown':
58
+ event.preventDefault();
59
+ focusItem(current + 1);
60
+ break;
61
+ case 'ArrowUp':
62
+ event.preventDefault();
63
+ focusItem(current - 1);
64
+ break;
65
+ case 'Home':
66
+ event.preventDefault();
67
+ focusItem(0);
68
+ break;
69
+ case 'End':
70
+ event.preventDefault();
71
+ focusItem(items.length - 1);
72
+ break;
73
+ case 'Escape':
74
+ event.preventDefault();
75
+ event.stopPropagation();
76
+ close();
77
+ break;
78
+ case 'Tab':
79
+ setOpen(false);
80
+ break;
81
+ default:
82
+ break;
83
+ }
84
+ };
85
+ return (_jsxs("div", { className: "tai-action-menu", children: [_jsxs("button", { ref: triggerRef, type: "button", className: "tai-btn tai-btn-ghost", "aria-label": label, "aria-haspopup": "menu", "aria-expanded": open, "aria-controls": open ? menuId : undefined, onClick: () => {
86
+ setOpen((was) => !was);
87
+ }, onKeyDown: (event) => {
88
+ if (event.key === 'ArrowDown' && !open) {
89
+ event.preventDefault();
90
+ setOpen(true);
91
+ }
92
+ }, children: ["Actions", _jsx(ChevronDownIcon, {})] }), open ? (_jsx("div", { ref: menuRef, id: menuId, role: "menu", tabIndex: -1, "aria-label": label, className: "tai-action-menu-list", onKeyDown: onMenuKeyDown, children: items.map((item, index) => (_jsx("button", { ref: (node) => {
93
+ itemRefs.current[index] = node;
94
+ }, type: "button", role: "menuitem", tabIndex: -1, className: item.danger === true
95
+ ? 'tai-action-menu-item tai-action-menu-item-danger'
96
+ : 'tai-action-menu-item', onClick: () => {
97
+ close();
98
+ item.onSelect();
99
+ }, children: item.label }, item.id))) })) : null] }));
100
+ }
101
+ //# sourceMappingURL=action-menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-menu.js","sourceRoot":"","sources":["../../src/components/action-menu.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `AgentPicker` — picks a registered agent by name from the agent list read
3
+ * (`GET /api/agents`) the host owns and hands in. Presentational: it fetches nothing
4
+ * and names no query library. It draws the read's states and its own copy, and flags
5
+ * a stored agent the loaded list does not hold as "not registered".
6
+ */
7
+ import type { AgentListing } from '@tai42/api-client';
8
+ import type { ReactNode } from 'react';
9
+ import { type ListReadFlags } from './named-list-picker';
10
+ /** The subset of the agent list read this picker reads; a TanStack query result satisfies it. */
11
+ export interface AgentListQuery extends ListReadFlags {
12
+ readonly data: AgentListing | undefined;
13
+ }
14
+ export interface AgentPickerProps {
15
+ readonly query: AgentListQuery;
16
+ readonly value: string;
17
+ readonly onValueChange: (value: string) => void;
18
+ /** The host form's field error, shown under the control while a `Select` renders. */
19
+ readonly error?: string | undefined;
20
+ }
21
+ export declare function AgentPicker({ query, value, onValueChange, error }: AgentPickerProps): ReactNode;
22
+ //# sourceMappingURL=agent-picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-picker.d.ts","sourceRoot":"","sources":["../../src/components/agent-picker.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,EAAE,KAAK,aAAa,EAAuC,MAAM,qBAAqB,CAAC;AAE9F,iGAAiG;AACjG,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,CAAC;CACzC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,qFAAqF;IACrF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAiBD,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,gBAAgB,GAAG,SAAS,CAY/F"}
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { AppLink } from '../navigation/app-link';
3
+ import { NamedListPicker } from './named-list-picker';
4
+ const COPY = {
5
+ label: 'Agent',
6
+ loadingPlaceholder: 'Loading agents…',
7
+ placeholder: 'Select an agent',
8
+ forbiddenNote: 'This session cannot list agents. Picking one needs read access to GET /api/agents; ask an administrator to grant it.',
9
+ emptyNote: 'No agents are registered on this deployment.',
10
+ emptyAction: (_jsx(AppLink, { to: "agents", className: "tai-link", children: "Open the Agents screen" })),
11
+ unlistedLabel: 'not registered',
12
+ };
13
+ export function AgentPicker({ query, value, onValueChange, error }) {
14
+ const names = (query.data?.items ?? []).map((item) => item.name);
15
+ return (_jsx(NamedListPicker, { query: query, names: names, value: value, onValueChange: onValueChange, error: error, copy: COPY }));
16
+ }
17
+ //# sourceMappingURL=agent-picker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-picker.js","sourceRoot":"","sources":["../../src/components/agent-picker.tsx"],"names":[],"mappings":";AASA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAA0C,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAe9F,MAAM,IAAI,GAAkB;IAC1B,KAAK,EAAE,OAAO;IACd,kBAAkB,EAAE,iBAAiB;IACrC,WAAW,EAAE,iBAAiB;IAC9B,aAAa,EACX,sHAAsH;IACxH,SAAS,EAAE,8CAA8C;IACzD,WAAW,EAAE,CACX,KAAC,OAAO,IAAC,EAAE,EAAC,QAAQ,EAAC,SAAS,EAAC,UAAU,uCAE/B,CACX;IACD,aAAa,EAAE,gBAAgB;CAChC,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAoB;IAClF,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjE,OAAO,CACL,KAAC,eAAe,IACd,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,aAAa,EAAE,aAAa,EAC5B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,IAAI,GACV,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * `ChannelPicker` — picks an installed channel plugin by name from the channel list
3
+ * read (`GET /api/channels`) the host owns and hands in. Presentational: it fetches
4
+ * nothing and names no query library. It draws the read's states and its own copy,
5
+ * and flags a stored channel the loaded list does not hold as "not installed".
6
+ */
7
+ import type { Channels } from '@tai42/api-client';
8
+ import type { ReactNode } from 'react';
9
+ import { type ListReadFlags } from './named-list-picker';
10
+ /** The subset of the channel list read this picker reads; a TanStack query result satisfies it. */
11
+ export interface ChannelListQuery extends ListReadFlags {
12
+ readonly data: Channels | undefined;
13
+ }
14
+ export interface ChannelPickerProps {
15
+ readonly query: ChannelListQuery;
16
+ readonly value: string;
17
+ readonly onValueChange: (value: string) => void;
18
+ /** The host form's field error, shown under the control while a `Select` renders. */
19
+ readonly error?: string | undefined;
20
+ }
21
+ /**
22
+ * The named channel's declared hint for a route's identity: the hint, `null` for a
23
+ * listed channel that declares none, `undefined` when the name is not listed.
24
+ */
25
+ export declare function channelIdentityHint(data: Channels, name: string): string | null | undefined;
26
+ export declare function ChannelPicker({ query, value, onValueChange, error, }: ChannelPickerProps): ReactNode;
27
+ //# sourceMappingURL=channel-picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-picker.d.ts","sourceRoot":"","sources":["../../src/components/channel-picker.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,EAAE,KAAK,aAAa,EAAuC,MAAM,qBAAqB,CAAC;AAE9F,mGAAmG;AACnG,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,qFAAqF;IACrF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAG3F;AAkBD,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,aAAa,EACb,KAAK,GACN,EAAE,kBAAkB,GAAG,SAAS,CAYhC"}
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { AppLink } from '../navigation/app-link';
3
+ import { NamedListPicker } from './named-list-picker';
4
+ /**
5
+ * The named channel's declared hint for a route's identity: the hint, `null` for a
6
+ * listed channel that declares none, `undefined` when the name is not listed.
7
+ */
8
+ export function channelIdentityHint(data, name) {
9
+ const entry = data.channels.find((channel) => channel.name === name);
10
+ return entry === undefined ? undefined : entry.identity_hint;
11
+ }
12
+ const COPY = {
13
+ label: 'Channel',
14
+ description: 'An installed channel plugin; the answer goes back on the same channel.',
15
+ loadingPlaceholder: 'Loading channels…',
16
+ placeholder: 'Select a channel',
17
+ forbiddenNote: 'This session cannot list channels. Picking one needs read access to GET /api/channels; ask an administrator to grant it.',
18
+ emptyNote: 'No channels are installed on this deployment.',
19
+ emptyAction: (_jsx(AppLink, { to: "marketplace", search: { kind: 'channel' }, className: "tai-link", children: "Browse channel plugins" })),
20
+ unlistedLabel: 'not installed',
21
+ };
22
+ export function ChannelPicker({ query, value, onValueChange, error, }) {
23
+ const names = (query.data?.channels ?? []).map((channel) => channel.name);
24
+ return (_jsx(NamedListPicker, { query: query, names: names, value: value, onValueChange: onValueChange, error: error, copy: COPY }));
25
+ }
26
+ //# sourceMappingURL=channel-picker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-picker.js","sourceRoot":"","sources":["../../src/components/channel-picker.tsx"],"names":[],"mappings":";AASA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAA0C,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAe9F;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAc,EAAE,IAAY;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACrE,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC;AAC/D,CAAC;AAED,MAAM,IAAI,GAAkB;IAC1B,KAAK,EAAE,SAAS;IAChB,WAAW,EAAE,wEAAwE;IACrF,kBAAkB,EAAE,mBAAmB;IACvC,WAAW,EAAE,kBAAkB;IAC/B,aAAa,EACX,0HAA0H;IAC5H,SAAS,EAAE,+CAA+C;IAC1D,WAAW,EAAE,CACX,KAAC,OAAO,IAAC,EAAE,EAAC,aAAa,EAAC,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,SAAS,EAAC,UAAU,uCAEjE,CACX;IACD,aAAa,EAAE,eAAe;CAC/B,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,aAAa,EACb,KAAK,GACc;IACnB,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,OAAO,CACL,KAAC,eAAe,IACd,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,aAAa,EAAE,aAAa,EAC5B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,IAAI,GACV,CACH,CAAC;AACJ,CAAC"}