@grampro/kit 0.0.0-stage → 2.4.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 (505) hide show
  1. package/.gbs/skills/gbs-components/SKILL.md +190 -0
  2. package/.gbs/skills/gbs-components/references/accessibility.md +102 -0
  3. package/.gbs/skills/gbs-components/references/data-display.md +185 -0
  4. package/.gbs/skills/gbs-components/references/data-grid.md +116 -0
  5. package/.gbs/skills/gbs-components/references/forms.md +202 -0
  6. package/.gbs/skills/gbs-components/references/install.md +211 -0
  7. package/.gbs/skills/gbs-components/references/overlays.md +206 -0
  8. package/.gbs/skills/gbs-components/references/pickers.md +83 -0
  9. package/.gbs/skills/gbs-components/references/styling.md +246 -0
  10. package/.gbs/skills/gbs-components/references/toaster.md +57 -0
  11. package/CHANGELOG.md +139 -0
  12. package/LICENSE +15 -0
  13. package/README.md +193 -2
  14. package/index.cjs +1370 -0
  15. package/package.json +74 -4
  16. package/schema/passport-v1.schema.json +204 -0
  17. package/source/components/accordion/README.md +45 -0
  18. package/source/components/accordion/core/index.ts +2 -0
  19. package/source/components/accordion/core/open.ts +56 -0
  20. package/source/components/accordion/core/types.ts +17 -0
  21. package/source/components/accordion/index.ts +8 -0
  22. package/source/components/accordion/passport.json +259 -0
  23. package/source/components/accordion/react/Accordion.tsx +133 -0
  24. package/source/components/accordion/react/AccordionItem.tsx +120 -0
  25. package/source/components/accordion/react/context.ts +20 -0
  26. package/source/components/accordion/react/props.ts +13 -0
  27. package/source/components/accordion/styles.css +207 -0
  28. package/source/components/alert/README.md +39 -0
  29. package/source/components/alert/core/index.ts +2 -0
  30. package/source/components/alert/core/live.ts +25 -0
  31. package/source/components/alert/core/types.ts +7 -0
  32. package/source/components/alert/index.ts +5 -0
  33. package/source/components/alert/passport.json +250 -0
  34. package/source/components/alert/react/Alert.tsx +113 -0
  35. package/source/components/alert/react/icons.tsx +21 -0
  36. package/source/components/alert/react/locale.ts +5 -0
  37. package/source/components/alert/react/props.ts +11 -0
  38. package/source/components/alert/styles.css +154 -0
  39. package/source/components/avatar/core/identity.ts +103 -0
  40. package/source/components/avatar/core/index.ts +2 -0
  41. package/source/components/avatar/core/types.ts +12 -0
  42. package/source/components/avatar/index.ts +7 -0
  43. package/source/components/avatar/passport.json +294 -0
  44. package/source/components/avatar/react/Avatar.tsx +118 -0
  45. package/source/components/avatar/react/AvatarGroup.tsx +74 -0
  46. package/source/components/avatar/react/locale.ts +11 -0
  47. package/source/components/avatar/react/props.ts +6 -0
  48. package/source/components/avatar/styles.css +225 -0
  49. package/source/components/badge/README.md +37 -0
  50. package/source/components/badge/core/count.ts +37 -0
  51. package/source/components/badge/core/index.ts +2 -0
  52. package/source/components/badge/core/types.ts +11 -0
  53. package/source/components/badge/index.ts +7 -0
  54. package/source/components/badge/passport.json +332 -0
  55. package/source/components/badge/react/Badge.tsx +89 -0
  56. package/source/components/badge/react/Tag.tsx +82 -0
  57. package/source/components/badge/react/locale.ts +5 -0
  58. package/source/components/badge/react/props.ts +6 -0
  59. package/source/components/badge/styles.css +203 -0
  60. package/source/components/breadcrumb/README.md +34 -0
  61. package/source/components/breadcrumb/core/index.ts +4 -0
  62. package/source/components/breadcrumb/core/trail.ts +42 -0
  63. package/source/components/breadcrumb/core/types.ts +20 -0
  64. package/source/components/breadcrumb/index.ts +5 -0
  65. package/source/components/breadcrumb/passport.json +243 -0
  66. package/source/components/breadcrumb/react/Breadcrumb.tsx +177 -0
  67. package/source/components/breadcrumb/react/locale.ts +6 -0
  68. package/source/components/breadcrumb/react/props.ts +14 -0
  69. package/source/components/breadcrumb/styles.css +138 -0
  70. package/source/components/button/README.md +32 -0
  71. package/source/components/button/core/index.ts +3 -0
  72. package/source/components/button/core/state.ts +16 -0
  73. package/source/components/button/core/types.ts +28 -0
  74. package/source/components/button/index.ts +5 -0
  75. package/source/components/button/passport.json +402 -0
  76. package/source/components/button/passport.manual.json +31 -0
  77. package/source/components/button/react/Button.tsx +173 -0
  78. package/source/components/button/react/locale.ts +5 -0
  79. package/source/components/button/react/props.ts +23 -0
  80. package/source/components/button/styles.css +232 -0
  81. package/source/components/card/README.md +60 -0
  82. package/source/components/card/core/index.ts +4 -0
  83. package/source/components/card/core/trend.ts +32 -0
  84. package/source/components/card/core/types.ts +5 -0
  85. package/source/components/card/index.ts +5 -0
  86. package/source/components/card/passport.json +337 -0
  87. package/source/components/card/react/Card.tsx +133 -0
  88. package/source/components/card/react/Stat.tsx +127 -0
  89. package/source/components/card/react/props.ts +4 -0
  90. package/source/components/card/styles.css +230 -0
  91. package/source/components/checkbox/README.md +36 -0
  92. package/source/components/checkbox/core/group.ts +30 -0
  93. package/source/components/checkbox/core/index.ts +3 -0
  94. package/source/components/checkbox/core/types.ts +17 -0
  95. package/source/components/checkbox/index.ts +9 -0
  96. package/source/components/checkbox/passport.json +456 -0
  97. package/source/components/checkbox/react/Checkbox.tsx +147 -0
  98. package/source/components/checkbox/react/CheckboxGroup.tsx +149 -0
  99. package/source/components/checkbox/react/context.ts +16 -0
  100. package/source/components/checkbox/react/locale.ts +5 -0
  101. package/source/components/checkbox/react/props.ts +6 -0
  102. package/source/components/checkbox/styles.css +211 -0
  103. package/source/components/combobox/README.md +170 -0
  104. package/source/components/combobox/core/filter.ts +155 -0
  105. package/source/components/combobox/core/index.ts +16 -0
  106. package/source/components/combobox/core/types.ts +48 -0
  107. package/source/components/combobox/core/virtual.ts +67 -0
  108. package/source/components/combobox/index.ts +13 -0
  109. package/source/components/combobox/passport.json +456 -0
  110. package/source/components/combobox/react/Listbox.tsx +310 -0
  111. package/source/components/combobox/react/MultiSelect.tsx +265 -0
  112. package/source/components/combobox/react/Popover.tsx +38 -0
  113. package/source/components/combobox/react/Select.tsx +200 -0
  114. package/source/components/combobox/react/icons.tsx +11 -0
  115. package/source/components/combobox/react/locale.ts +16 -0
  116. package/source/components/combobox/react/props.ts +88 -0
  117. package/source/components/combobox/react/useCombobox.ts +409 -0
  118. package/source/components/combobox/styles.css +419 -0
  119. package/source/components/data-grid/README.md +233 -0
  120. package/source/components/data-grid/agent/coerce.ts +368 -0
  121. package/source/components/data-grid/agent/contract.ts +410 -0
  122. package/source/components/data-grid/agent/dataset.ts +92 -0
  123. package/source/components/data-grid/agent/engine.ts +470 -0
  124. package/source/components/data-grid/agent/executors.ts +155 -0
  125. package/source/components/data-grid/agent/index.ts +79 -0
  126. package/source/components/data-grid/agent/intent.ts +324 -0
  127. package/source/components/data-grid/agent/operations.ts +335 -0
  128. package/source/components/data-grid/agent/validate.ts +630 -0
  129. package/source/components/data-grid/agent/webmcp.ts +107 -0
  130. package/source/components/data-grid/core/columnHelper.ts +21 -0
  131. package/source/components/data-grid/core/columns.ts +288 -0
  132. package/source/components/data-grid/core/filtering.ts +237 -0
  133. package/source/components/data-grid/core/grid.ts +638 -0
  134. package/source/components/data-grid/core/index.ts +14 -0
  135. package/source/components/data-grid/core/rows.ts +64 -0
  136. package/source/components/data-grid/core/sorting.ts +133 -0
  137. package/source/components/data-grid/core/state.ts +82 -0
  138. package/source/components/data-grid/core/store.ts +52 -0
  139. package/source/components/data-grid/core/types.ts +302 -0
  140. package/source/components/data-grid/core/values.ts +98 -0
  141. package/source/components/data-grid/core/virtual.ts +85 -0
  142. package/source/components/data-grid/export/csv.ts +32 -0
  143. package/source/components/data-grid/export/download.ts +12 -0
  144. package/source/components/data-grid/export/pdf-font.ts +139 -0
  145. package/source/components/data-grid/export/pdf-writer.ts +113 -0
  146. package/source/components/data-grid/export/pdf.ts +379 -0
  147. package/source/components/data-grid/export/table.ts +73 -0
  148. package/source/components/data-grid/export/xlsx.ts +145 -0
  149. package/source/components/data-grid/export/zip.ts +87 -0
  150. package/source/components/data-grid/index.ts +14 -0
  151. package/source/components/data-grid/passport.json +1051 -0
  152. package/source/components/data-grid/passport.manual.json +255 -0
  153. package/source/components/data-grid/react/AskGrid.tsx +164 -0
  154. package/source/components/data-grid/react/Cell.tsx +282 -0
  155. package/source/components/data-grid/react/ColumnMenu.tsx +135 -0
  156. package/source/components/data-grid/react/DataGrid.tsx +335 -0
  157. package/source/components/data-grid/react/FilterForm.tsx +142 -0
  158. package/source/components/data-grid/react/HeaderRow.tsx +332 -0
  159. package/source/components/data-grid/react/Pagination.tsx +107 -0
  160. package/source/components/data-grid/react/Popover.tsx +35 -0
  161. package/source/components/data-grid/react/Row.tsx +85 -0
  162. package/source/components/data-grid/react/Toolbar.tsx +267 -0
  163. package/source/components/data-grid/react/Viewport.tsx +167 -0
  164. package/source/components/data-grid/react/context.ts +57 -0
  165. package/source/components/data-grid/react/hooks.ts +83 -0
  166. package/source/components/data-grid/react/icons.tsx +45 -0
  167. package/source/components/data-grid/react/keyboard.ts +110 -0
  168. package/source/components/data-grid/react/locale.ts +130 -0
  169. package/source/components/data-grid/styles.css +874 -0
  170. package/source/components/date-picker/README.md +141 -0
  171. package/source/components/date-picker/core/calendar.ts +266 -0
  172. package/source/components/date-picker/core/format.ts +170 -0
  173. package/source/components/date-picker/core/index.ts +41 -0
  174. package/source/components/date-picker/core/today.ts +72 -0
  175. package/source/components/date-picker/core/types.ts +68 -0
  176. package/source/components/date-picker/index.ts +16 -0
  177. package/source/components/date-picker/passport.json +407 -0
  178. package/source/components/date-picker/react/Calendar.tsx +160 -0
  179. package/source/components/date-picker/react/CalendarPanel.tsx +170 -0
  180. package/source/components/date-picker/react/DatePicker.tsx +249 -0
  181. package/source/components/date-picker/react/DateRangePicker.tsx +291 -0
  182. package/source/components/date-picker/react/MonthYearPanels.tsx +123 -0
  183. package/source/components/date-picker/react/Popover.tsx +45 -0
  184. package/source/components/date-picker/react/icons.tsx +15 -0
  185. package/source/components/date-picker/react/locale.ts +23 -0
  186. package/source/components/date-picker/react/props.ts +76 -0
  187. package/source/components/date-picker/react/useDatePicker.ts +557 -0
  188. package/source/components/date-picker/styles.css +445 -0
  189. package/source/components/dialog/README.md +39 -0
  190. package/source/components/dialog/core/api.ts +34 -0
  191. package/source/components/dialog/core/dialog.ts +11 -0
  192. package/source/components/dialog/core/index.ts +7 -0
  193. package/source/components/dialog/core/store.ts +81 -0
  194. package/source/components/dialog/core/types.ts +59 -0
  195. package/source/components/dialog/index.ts +7 -0
  196. package/source/components/dialog/passport.json +344 -0
  197. package/source/components/dialog/react/Dialog.tsx +279 -0
  198. package/source/components/dialog/react/DialogHost.tsx +45 -0
  199. package/source/components/dialog/react/icons.tsx +20 -0
  200. package/source/components/dialog/react/locale.ts +8 -0
  201. package/source/components/dialog/react/props.ts +13 -0
  202. package/source/components/dialog/styles.css +280 -0
  203. package/source/components/file-uploader/README.md +99 -0
  204. package/source/components/file-uploader/core/format.ts +79 -0
  205. package/source/components/file-uploader/core/index.ts +26 -0
  206. package/source/components/file-uploader/core/store.ts +432 -0
  207. package/source/components/file-uploader/core/transport.ts +154 -0
  208. package/source/components/file-uploader/core/types.ts +126 -0
  209. package/source/components/file-uploader/core/validate.ts +83 -0
  210. package/source/components/file-uploader/index.ts +7 -0
  211. package/source/components/file-uploader/passport.json +518 -0
  212. package/source/components/file-uploader/react/FileRow.tsx +268 -0
  213. package/source/components/file-uploader/react/FileUploader.tsx +511 -0
  214. package/source/components/file-uploader/react/icons.tsx +60 -0
  215. package/source/components/file-uploader/react/locale.ts +33 -0
  216. package/source/components/file-uploader/react/props.ts +31 -0
  217. package/source/components/file-uploader/react/useFileUploader.ts +32 -0
  218. package/source/components/file-uploader/styles.css +394 -0
  219. package/source/components/input/README.md +44 -0
  220. package/source/components/input/core/count.ts +5 -0
  221. package/source/components/input/core/index.ts +11 -0
  222. package/source/components/input/core/otp.ts +64 -0
  223. package/source/components/input/core/types.ts +14 -0
  224. package/source/components/input/index.ts +8 -0
  225. package/source/components/input/passport.json +536 -0
  226. package/source/components/input/react/Input.tsx +219 -0
  227. package/source/components/input/react/OtpInput.tsx +256 -0
  228. package/source/components/input/react/dom.ts +10 -0
  229. package/source/components/input/react/icons.tsx +17 -0
  230. package/source/components/input/react/locale.ts +9 -0
  231. package/source/components/input/react/props.ts +6 -0
  232. package/source/components/input/styles.css +295 -0
  233. package/source/components/menu/README.md +68 -0
  234. package/source/components/menu/core/index.ts +11 -0
  235. package/source/components/menu/core/navigation.ts +84 -0
  236. package/source/components/menu/core/types.ts +32 -0
  237. package/source/components/menu/index.ts +19 -0
  238. package/source/components/menu/passport.json +322 -0
  239. package/source/components/menu/react/Menu.tsx +371 -0
  240. package/source/components/menu/react/context.ts +31 -0
  241. package/source/components/menu/react/items.tsx +268 -0
  242. package/source/components/menu/react/locale.ts +6 -0
  243. package/source/components/menu/react/props.ts +4 -0
  244. package/source/components/menu/react/useMenuKeys.ts +124 -0
  245. package/source/components/menu/styles.css +224 -0
  246. package/source/components/modal/README.md +51 -0
  247. package/source/components/modal/core/dismiss.ts +29 -0
  248. package/source/components/modal/core/index.ts +3 -0
  249. package/source/components/modal/core/types.ts +27 -0
  250. package/source/components/modal/index.ts +5 -0
  251. package/source/components/modal/passport.json +289 -0
  252. package/source/components/modal/react/Modal.tsx +242 -0
  253. package/source/components/modal/react/icons.tsx +1 -0
  254. package/source/components/modal/react/locale.ts +5 -0
  255. package/source/components/modal/react/props.ts +17 -0
  256. package/source/components/modal/styles.css +241 -0
  257. package/source/components/number-input/README.md +53 -0
  258. package/source/components/number-input/core/format.ts +37 -0
  259. package/source/components/number-input/core/index.ts +4 -0
  260. package/source/components/number-input/core/parse.ts +118 -0
  261. package/source/components/number-input/core/step.ts +73 -0
  262. package/source/components/number-input/core/types.ts +32 -0
  263. package/source/components/number-input/index.ts +5 -0
  264. package/source/components/number-input/passport.json +541 -0
  265. package/source/components/number-input/react/NumberInput.tsx +465 -0
  266. package/source/components/number-input/react/icons.tsx +17 -0
  267. package/source/components/number-input/react/locale.ts +7 -0
  268. package/source/components/number-input/react/props.ts +11 -0
  269. package/source/components/number-input/styles.css +230 -0
  270. package/source/components/popover/README.md +44 -0
  271. package/source/components/popover/core/index.ts +2 -0
  272. package/source/components/popover/core/types.ts +12 -0
  273. package/source/components/popover/index.ts +4 -0
  274. package/source/components/popover/passport.json +238 -0
  275. package/source/components/popover/react/Popover.tsx +202 -0
  276. package/source/components/popover/react/locale.ts +5 -0
  277. package/source/components/popover/react/props.ts +4 -0
  278. package/source/components/popover/styles.css +148 -0
  279. package/source/components/progress/README.md +38 -0
  280. package/source/components/progress/core/index.ts +2 -0
  281. package/source/components/progress/core/progress.ts +40 -0
  282. package/source/components/progress/core/types.ts +23 -0
  283. package/source/components/progress/index.ts +7 -0
  284. package/source/components/progress/passport.json +270 -0
  285. package/source/components/progress/react/CircularProgress.tsx +106 -0
  286. package/source/components/progress/react/Progress.tsx +113 -0
  287. package/source/components/progress/react/locale.ts +7 -0
  288. package/source/components/progress/react/props.ts +6 -0
  289. package/source/components/progress/styles.css +200 -0
  290. package/source/components/radio-group/README.md +58 -0
  291. package/source/components/radio-group/core/group.ts +36 -0
  292. package/source/components/radio-group/core/index.ts +2 -0
  293. package/source/components/radio-group/core/types.ts +20 -0
  294. package/source/components/radio-group/index.ts +9 -0
  295. package/source/components/radio-group/passport.json +477 -0
  296. package/source/components/radio-group/react/Radio.tsx +144 -0
  297. package/source/components/radio-group/react/RadioGroup.tsx +179 -0
  298. package/source/components/radio-group/react/context.ts +18 -0
  299. package/source/components/radio-group/react/locale.ts +5 -0
  300. package/source/components/radio-group/react/props.ts +12 -0
  301. package/source/components/radio-group/styles.css +269 -0
  302. package/source/components/shared/README.md +54 -0
  303. package/source/components/shared/core/agent/adapter.ts +65 -0
  304. package/source/components/shared/core/agent/history.ts +120 -0
  305. package/source/components/shared/core/agent/index.ts +46 -0
  306. package/source/components/shared/core/agent/numbers.ts +217 -0
  307. package/source/components/shared/core/agent/schema.ts +180 -0
  308. package/source/components/shared/core/agent/types.ts +169 -0
  309. package/source/components/shared/core/agent/webmcp.ts +328 -0
  310. package/source/components/shared/core/cx.ts +9 -0
  311. package/source/components/shared/core/field.ts +35 -0
  312. package/source/components/shared/core/position.ts +124 -0
  313. package/source/components/shared/core/text.ts +14 -0
  314. package/source/components/shared/index.ts +17 -0
  315. package/source/components/shared/react/GramproAIProvider.tsx +50 -0
  316. package/source/components/shared/react/Popover.tsx +189 -0
  317. package/source/components/shared/react/icons.tsx +74 -0
  318. package/source/components/shared/react/useAskAgent.ts +217 -0
  319. package/source/components/shared/react/useControllableState.ts +42 -0
  320. package/source/components/shared/styles.css +79 -0
  321. package/source/components/shared/version.json +4 -0
  322. package/source/components/shared/version.ts +6 -0
  323. package/source/components/skeleton/README.md +58 -0
  324. package/source/components/skeleton/core/index.ts +3 -0
  325. package/source/components/skeleton/core/lines.ts +25 -0
  326. package/source/components/skeleton/core/types.ts +5 -0
  327. package/source/components/skeleton/index.ts +5 -0
  328. package/source/components/skeleton/passport.json +251 -0
  329. package/source/components/skeleton/react/Empty.tsx +51 -0
  330. package/source/components/skeleton/react/Skeleton.tsx +92 -0
  331. package/source/components/skeleton/react/props.ts +4 -0
  332. package/source/components/skeleton/styles.css +185 -0
  333. package/source/components/spinner/README.md +29 -0
  334. package/source/components/spinner/core/index.ts +3 -0
  335. package/source/components/spinner/core/types.ts +28 -0
  336. package/source/components/spinner/core/visibility.ts +34 -0
  337. package/source/components/spinner/index.ts +6 -0
  338. package/source/components/spinner/passport.json +245 -0
  339. package/source/components/spinner/react/Spinner.tsx +96 -0
  340. package/source/components/spinner/react/locale.ts +5 -0
  341. package/source/components/spinner/react/props.ts +4 -0
  342. package/source/components/spinner/react/useDelayedLoading.ts +39 -0
  343. package/source/components/spinner/styles.css +173 -0
  344. package/source/components/switch/README.md +46 -0
  345. package/source/components/switch/core/index.ts +2 -0
  346. package/source/components/switch/core/toggle.ts +54 -0
  347. package/source/components/switch/core/types.ts +9 -0
  348. package/source/components/switch/index.ts +5 -0
  349. package/source/components/switch/passport.json +421 -0
  350. package/source/components/switch/react/Switch.tsx +219 -0
  351. package/source/components/switch/react/locale.ts +5 -0
  352. package/source/components/switch/react/props.ts +12 -0
  353. package/source/components/switch/styles.css +227 -0
  354. package/source/components/tabs/README.md +32 -0
  355. package/source/components/tabs/core/index.ts +3 -0
  356. package/source/components/tabs/core/navigation.ts +54 -0
  357. package/source/components/tabs/core/types.ts +16 -0
  358. package/source/components/tabs/index.ts +5 -0
  359. package/source/components/tabs/passport.json +315 -0
  360. package/source/components/tabs/react/Tabs.tsx +306 -0
  361. package/source/components/tabs/react/context.ts +21 -0
  362. package/source/components/tabs/styles.css +263 -0
  363. package/source/components/textarea/README.md +39 -0
  364. package/source/components/textarea/core/count.ts +5 -0
  365. package/source/components/textarea/core/index.ts +4 -0
  366. package/source/components/textarea/core/size.ts +23 -0
  367. package/source/components/textarea/core/types.ts +17 -0
  368. package/source/components/textarea/index.ts +5 -0
  369. package/source/components/textarea/passport.json +382 -0
  370. package/source/components/textarea/react/Textarea.tsx +208 -0
  371. package/source/components/textarea/react/locale.ts +5 -0
  372. package/source/components/textarea/react/props.ts +4 -0
  373. package/source/components/textarea/styles.css +158 -0
  374. package/source/components/toaster/README.md +128 -0
  375. package/source/components/toaster/core/api.ts +87 -0
  376. package/source/components/toaster/core/index.ts +14 -0
  377. package/source/components/toaster/core/store.ts +211 -0
  378. package/source/components/toaster/core/toast.ts +12 -0
  379. package/source/components/toaster/core/types.ts +78 -0
  380. package/source/components/toaster/index.ts +6 -0
  381. package/source/components/toaster/passport.json +221 -0
  382. package/source/components/toaster/react/ToastItem.tsx +164 -0
  383. package/source/components/toaster/react/Toaster.tsx +187 -0
  384. package/source/components/toaster/react/icons.tsx +23 -0
  385. package/source/components/toaster/react/locale.ts +6 -0
  386. package/source/components/toaster/react/props.ts +15 -0
  387. package/source/components/toaster/react/useToasts.ts +11 -0
  388. package/source/components/toaster/styles.css +282 -0
  389. package/source/components/tooltip/README.md +43 -0
  390. package/source/components/tooltip/core/index.ts +4 -0
  391. package/source/components/tooltip/core/types.ts +4 -0
  392. package/source/components/tooltip/core/visibility.ts +34 -0
  393. package/source/components/tooltip/index.ts +3 -0
  394. package/source/components/tooltip/passport.json +170 -0
  395. package/source/components/tooltip/react/Tooltip.tsx +196 -0
  396. package/source/components/tooltip/react/props.ts +4 -0
  397. package/source/components/tooltip/styles.css +71 -0
  398. package/source/fallback/index.tsx +11 -0
  399. package/source/globalStyle.ts +74 -0
  400. package/source/hooks/SelectionHooks/type.ts +4 -0
  401. package/source/hooks/SelectionHooks/useClickOutside.ts +22 -0
  402. package/source/hooks/SelectionHooks/useMultiSelectState.ts +64 -0
  403. package/source/hooks/SelectionHooks/useSelectData.ts +58 -0
  404. package/source/hooks/SelectionHooks/useSelectState.ts +36 -0
  405. package/source/icon/Icon.tsx +102 -0
  406. package/source/icon/iconPaths.ts +206 -0
  407. package/source/legacy-components/bargraph/index.tsx +95 -0
  408. package/source/legacy-components/bargraph/type.ts +12 -0
  409. package/source/legacy-components/breadcrumb/index.tsx +66 -0
  410. package/source/legacy-components/breadcrumb/types.ts +10 -0
  411. package/source/legacy-components/button/index.tsx +42 -0
  412. package/source/legacy-components/card/index.tsx +31 -0
  413. package/source/legacy-components/checkbox/index.tsx +25 -0
  414. package/source/legacy-components/contextmenu/ContextMenu.tsx +87 -0
  415. package/source/legacy-components/contextmenu/ContextMenuItem.tsx +30 -0
  416. package/source/legacy-components/contextmenu/index.ts +2 -0
  417. package/source/legacy-components/contextmenu/types.ts +19 -0
  418. package/source/legacy-components/darkmode/index.tsx +55 -0
  419. package/source/legacy-components/datagrid/context/GridContext.tsx +215 -0
  420. package/source/legacy-components/datagrid/createTemplate.tsx +82 -0
  421. package/source/legacy-components/datagrid/hooks/index.ts +6 -0
  422. package/source/legacy-components/datagrid/hooks/useColumns.ts +33 -0
  423. package/source/legacy-components/datagrid/hooks/useDataSource.ts +54 -0
  424. package/source/legacy-components/datagrid/hooks/useFiltering.ts +169 -0
  425. package/source/legacy-components/datagrid/hooks/usePagination.ts +112 -0
  426. package/source/legacy-components/datagrid/hooks/useRowSelection.ts +48 -0
  427. package/source/legacy-components/datagrid/hooks/useSearch.ts +90 -0
  428. package/source/legacy-components/datagrid/index.tsx +28 -0
  429. package/source/legacy-components/datagrid/layout/FilterPopup.tsx +92 -0
  430. package/source/legacy-components/datagrid/layout/GridBody.tsx +184 -0
  431. package/source/legacy-components/datagrid/layout/GridPagination.tsx +119 -0
  432. package/source/legacy-components/datagrid/layout/GridToolbar.tsx +109 -0
  433. package/source/legacy-components/datagrid/layout/index.tsx +68 -0
  434. package/source/legacy-components/datagrid/type.ts +198 -0
  435. package/source/legacy-components/datepicker/index.tsx +365 -0
  436. package/source/legacy-components/datepicker/types.ts +12 -0
  437. package/source/legacy-components/dialog/index.tsx +44 -0
  438. package/source/legacy-components/dialog/types.ts +12 -0
  439. package/source/legacy-components/formrenderer/componentHandles/CheckBoxHandles.tsx +80 -0
  440. package/source/legacy-components/formrenderer/componentHandles/DatePickerHandles.tsx +93 -0
  441. package/source/legacy-components/formrenderer/componentHandles/InputHandles.tsx +106 -0
  442. package/source/legacy-components/formrenderer/componentHandles/MultiHandles.tsx +93 -0
  443. package/source/legacy-components/formrenderer/componentHandles/SelectHandles.tsx +95 -0
  444. package/source/legacy-components/formrenderer/helperFunctions.ts +72 -0
  445. package/source/legacy-components/formrenderer/index.tsx +93 -0
  446. package/source/legacy-components/formrenderer/types.ts +127 -0
  447. package/source/legacy-components/input/index.tsx +142 -0
  448. package/source/legacy-components/input/types.ts +10 -0
  449. package/source/legacy-components/materialInput/index.tsx +138 -0
  450. package/source/legacy-components/materialInput/types.ts +16 -0
  451. package/source/legacy-components/modal/index.tsx +152 -0
  452. package/source/legacy-components/modal/types.ts +19 -0
  453. package/source/legacy-components/multiselect/PortalDropDown.tsx +44 -0
  454. package/source/legacy-components/multiselect/index.tsx +269 -0
  455. package/source/legacy-components/multiselect/types.ts +26 -0
  456. package/source/legacy-components/navbar/AuthSection.tsx +98 -0
  457. package/source/legacy-components/navbar/MobileToggle.tsx +31 -0
  458. package/source/legacy-components/navbar/NavItemComponent.tsx +119 -0
  459. package/source/legacy-components/navbar/SearchBar.tsx +55 -0
  460. package/source/legacy-components/navbar/helperFunctions.ts +27 -0
  461. package/source/legacy-components/navbar/index.tsx +156 -0
  462. package/source/legacy-components/navbar/types.ts +69 -0
  463. package/source/legacy-components/select/PortalDropDown.tsx +59 -0
  464. package/source/legacy-components/select/index.tsx +249 -0
  465. package/source/legacy-components/select/types.ts +29 -0
  466. package/source/legacy-components/sidebar/components/MenuItem.tsx +101 -0
  467. package/source/legacy-components/sidebar/components/MenuSection.tsx +34 -0
  468. package/source/legacy-components/sidebar/components/SidebarFooter.tsx +50 -0
  469. package/source/legacy-components/sidebar/components/SidebarLogo.tsx +24 -0
  470. package/source/legacy-components/sidebar/components/SidebarMenu.tsx +29 -0
  471. package/source/legacy-components/sidebar/components/UserProfile.tsx +31 -0
  472. package/source/legacy-components/sidebar/hooks/useSidebarState.ts +41 -0
  473. package/source/legacy-components/sidebar/index.tsx +77 -0
  474. package/source/legacy-components/sidebar/type.ts +42 -0
  475. package/source/legacy-components/spinner/Stroke.tsx +89 -0
  476. package/source/legacy-components/spinner/index.tsx +54 -0
  477. package/source/legacy-components/spinner/types.ts +9 -0
  478. package/source/legacy-components/tabs/index.tsx +71 -0
  479. package/source/legacy-components/tabs/types.ts +16 -0
  480. package/source/legacy-components/textarea/index.tsx +123 -0
  481. package/source/legacy-components/textarea/types.ts +15 -0
  482. package/source/legacy-components/toast/ToastComponent.tsx +101 -0
  483. package/source/legacy-components/toast/ToastIcon.tsx +61 -0
  484. package/source/legacy-components/toast/index.tsx +42 -0
  485. package/source/legacy-components/toast/toastStore.ts +42 -0
  486. package/source/legacy-components/toast/types.ts +18 -0
  487. package/source/legacy-components/toast/useToast.ts +12 -0
  488. package/source/legacy-components/uploader/ProgressAnimation.tsx +50 -0
  489. package/source/legacy-components/uploader/UploadedFilePreview.tsx +130 -0
  490. package/source/legacy-components/uploader/index.tsx +311 -0
  491. package/source/legacy-components/uploader/types.ts +30 -0
  492. package/source/legacy-components/uploader/uploaderIcon.tsx +72 -0
  493. package/source/legacy-components/uploader/uploaderService.ts +134 -0
  494. package/source/legacy-components/useUploader/useUploader.tsx +310 -0
  495. package/source/legacy-components/usepaginateddata/usePaginatedData.ts +174 -0
  496. package/source/theme.ts +40 -0
  497. package/source/utils.ts +10 -0
  498. package/tools/env.cjs +61 -0
  499. package/tools/passport/cli.cjs +79 -0
  500. package/tools/passport/extract.cjs +493 -0
  501. package/tools/passport/index.cjs +185 -0
  502. package/tools/passport/merge.cjs +131 -0
  503. package/tools/passport/policy.cjs +65 -0
  504. package/tools/passport/validate.cjs +277 -0
  505. package/tools/ts-require.cjs +79 -0
@@ -0,0 +1,169 @@
1
+ /*
2
+ * The vocabulary an agent-operable component shares with its callers.
3
+ *
4
+ * Four things are kept apart on purpose, because they change for different
5
+ * reasons and at different times:
6
+ *
7
+ * OperationDefinition what a component knows how to do (static, from the passport)
8
+ * RuntimeContract what this instance can do, right now (per instance, per render)
9
+ * Intent what the caller is asking for (untrusted input)
10
+ * OperationExecutor how this instance actually performs it (per application)
11
+ *
12
+ * The last one is the reason this file exists. An operation must not be
13
+ * welded to an imperative handle: a grid performs `filter` by calling
14
+ * `GridApi.setFilter`, while a controlled component would perform its
15
+ * equivalent by calling the host's `onChange`. Same operation, same schema,
16
+ * different executor. Nothing here mentions either.
17
+ */
18
+
19
+ // ---------------------------------------------------------------- JSON Schema
20
+
21
+ /**
22
+ * The slice of JSON Schema this library emits and checks. Deliberately small:
23
+ * it is what a constrained decoder and a validator both need, and no more.
24
+ */
25
+ export interface JsonSchema {
26
+ $schema?: string;
27
+ title?: string;
28
+ description?: string;
29
+ type?: JsonSchemaType | readonly JsonSchemaType[];
30
+ const?: unknown;
31
+ enum?: readonly unknown[];
32
+ properties?: Readonly<Record<string, JsonSchema>>;
33
+ required?: readonly string[];
34
+ additionalProperties?: boolean | JsonSchema;
35
+ items?: JsonSchema;
36
+ minItems?: number;
37
+ maxItems?: number;
38
+ minLength?: number;
39
+ maxLength?: number;
40
+ minimum?: number;
41
+ maximum?: number;
42
+ pattern?: string;
43
+ oneOf?: readonly JsonSchema[];
44
+ anyOf?: readonly JsonSchema[];
45
+ default?: unknown;
46
+ examples?: readonly unknown[];
47
+ }
48
+
49
+ export type JsonSchemaType =
50
+ | "object"
51
+ | "array"
52
+ | "string"
53
+ | "number"
54
+ | "integer"
55
+ | "boolean"
56
+ | "null";
57
+
58
+ // ----------------------------------------------------------------- operations
59
+
60
+ /**
61
+ * One thing a component can be asked to do. This is the static half of the
62
+ * contract and mirrors the component's `passport.json` `operations` block.
63
+ */
64
+ export interface OperationDefinition {
65
+ readonly name: string;
66
+ readonly summary: string;
67
+ /** JSON Schema for the operation's input, minus the `action` discriminator. */
68
+ readonly input?: JsonSchema;
69
+ /** Plain-language consequences, for a confirmation prompt. */
70
+ readonly effects?: readonly string[];
71
+ /** Whether undoing it is a matter of restoring the previous state. */
72
+ readonly reversible: boolean;
73
+ /** Leaves the page: downloads, prints, writes to the clipboard. */
74
+ readonly requiresConfirmation?: boolean;
75
+ /**
76
+ * The imperative method that happens to back this operation, when one does.
77
+ * Metadata only — never required. An operation performed through host state
78
+ * has no API method, and that is a normal case, not a gap.
79
+ */
80
+ readonly apiMethod?: string;
81
+ }
82
+
83
+ export interface ExecutionContext<TContract = unknown> {
84
+ readonly contract: TContract;
85
+ /** Report what would happen and change nothing. */
86
+ readonly dryRun: boolean;
87
+ readonly signal?: AbortSignal;
88
+ }
89
+
90
+ /**
91
+ * How one instance performs one operation.
92
+ *
93
+ * Implementations close over whatever they need — an imperative handle, a
94
+ * state setter, a transport — and the rest of the pipeline never learns which.
95
+ */
96
+ export interface OperationExecutor<TInput, TContract = unknown, TResult = void> {
97
+ readonly operation: string;
98
+ /** Set only when `execute` really does call that method. */
99
+ readonly apiMethod?: string;
100
+ execute(input: TInput, context: ExecutionContext<TContract>): TResult | Promise<TResult>;
101
+ }
102
+
103
+ /**
104
+ * An executor in a heterogeneous registry. `never` as the input type is sound
105
+ * here: a function taking a specific input is assignable to one taking
106
+ * `never`, so concrete executors slot in without a cast. Callers cast at the
107
+ * point of dispatch, where the validator has already proved the shape.
108
+ */
109
+ export type RegisteredExecutor<TContract = unknown> = OperationExecutor<never, TContract, unknown>;
110
+
111
+ export type ExecutorRegistry<TContract = unknown> = ReadonlyMap<string, RegisteredExecutor<TContract>>;
112
+
113
+ // ----------------------------------------------------------------- validation
114
+
115
+ export type ValidationLayer =
116
+ | "schema"
117
+ | "reference"
118
+ | "coercion"
119
+ | "policy"
120
+ | "plausibility";
121
+
122
+ export interface ValidationIssue {
123
+ layer: ValidationLayer;
124
+ /** Stable, machine-readable. Messages may be reworded; codes may not. */
125
+ code: string;
126
+ message: string;
127
+ /** JSON pointer-ish path into the intent, when the issue has a location. */
128
+ path?: string;
129
+ suggestion?: string;
130
+ }
131
+
132
+ /** Something the caller should see and agree to before the command runs. */
133
+ export interface ConfirmRequest {
134
+ code: string;
135
+ message: string;
136
+ }
137
+
138
+ export type ValidationResult<TCommand> =
139
+ | {
140
+ ok: true;
141
+ command: TCommand;
142
+ /** Non-blocking: coercions applied, plausibility notes. */
143
+ warnings: ValidationIssue[];
144
+ confirm: ConfirmRequest | null;
145
+ }
146
+ | {
147
+ ok: false;
148
+ /** The issue that stopped it, flattened for display. */
149
+ reason: string;
150
+ code: string;
151
+ layer: ValidationLayer;
152
+ suggestion?: string;
153
+ issues: ValidationIssue[];
154
+ };
155
+
156
+ export const ok = <T>(
157
+ command: T,
158
+ warnings: ValidationIssue[] = [],
159
+ confirm: ConfirmRequest | null = null,
160
+ ): ValidationResult<T> => ({ ok: true, command, warnings, confirm });
161
+
162
+ export const fail = <T>(issue: ValidationIssue, issues: ValidationIssue[] = []): ValidationResult<T> => ({
163
+ ok: false,
164
+ reason: issue.message,
165
+ code: issue.code,
166
+ layer: issue.layer,
167
+ ...(issue.suggestion ? { suggestion: issue.suggestion } : {}),
168
+ issues: issues.length > 0 ? issues : [issue],
169
+ });
@@ -0,0 +1,328 @@
1
+ /*
2
+ * WebMCP projection: exposing an already-validated command boundary to
3
+ * whatever agent is driving the browser.
4
+ *
5
+ * This is an adapter and nothing else. It owns no schema, no semantics and no
6
+ * execution path. The chain stays:
7
+ *
8
+ * component source → passport → runtime contract → intent schema
9
+ * → [this file] → the component's validator → its executors → the component
10
+ *
11
+ * Nothing here knows about a grid. A component's agent satisfies
12
+ * `ProjectableAgent` structurally, and everything component-specific arrives
13
+ * through `describe` and `summarise`.
14
+ *
15
+ * Why one tool and not one per operation: the operation list is not the
16
+ * agent's interface — the generated intent schema is, because that is where
17
+ * the contract and the validation layers already meet. Twenty-one operations
18
+ * exposed separately would be twenty-one schemas to keep in step with a
19
+ * contract that already describes itself.
20
+ *
21
+ * Surface notes, each of which cost a wrong run to learn:
22
+ *
23
+ * - It is `document.modelContext`. `navigator.modelContext` was the early
24
+ * spelling and is deprecated since Chromium 150.
25
+ * - Chrome hands `inputSchema` to the agent as a JSON *string*, and returns
26
+ * a tool result as a JSON string. That is the browser's wire format, not
27
+ * something to pre-serialise here.
28
+ * - It needs `--enable-features=WebMCPTesting`, the
29
+ * `chrome://flags/#enable-webmcp-testing` flag, or an origin-trial token.
30
+ *
31
+ * The specification is a Draft Community Group Report and is not on the W3C
32
+ * standards track, so this module is deliberately small and replaceable.
33
+ */
34
+
35
+ import type { ConfirmRequest, JsonSchema, ValidationIssue, ValidationLayer } from "./types";
36
+
37
+ // ----------------------------------------------------------- browser surface
38
+
39
+ /** One command the validator accepted, in the form this projection reports. */
40
+ export interface ProjectedCommand {
41
+ readonly intent: unknown;
42
+ readonly explain: { readonly summary: string };
43
+ }
44
+
45
+ /**
46
+ * What the validator answers. Mirrors the component-level execution result;
47
+ * a component may carry extra fields, which are ignored here.
48
+ */
49
+ export type ProjectedOutcome =
50
+ | { status: "done"; commands: readonly ProjectedCommand[]; warnings: readonly ValidationIssue[] }
51
+ | {
52
+ status: "needs-confirmation";
53
+ commands: readonly ProjectedCommand[];
54
+ warnings: readonly ValidationIssue[];
55
+ confirm: ConfirmRequest;
56
+ }
57
+ | {
58
+ status: "rejected";
59
+ reason: string;
60
+ code: string;
61
+ layer: ValidationLayer;
62
+ suggestion?: string;
63
+ }
64
+ | { status: "clarify"; question: string; options?: readonly string[] }
65
+ | { status: "declined"; reason: string };
66
+
67
+ /**
68
+ * The part of a component's agent this projection uses.
69
+ *
70
+ * Structural on purpose: a DataGrid agent, a DatePicker agent or a test double
71
+ * satisfies it without importing anything from here.
72
+ */
73
+ export interface ProjectableAgent {
74
+ /** The generated per-instance schema for one intent. */
75
+ schema(): JsonSchema;
76
+ /** Validate without changing anything. */
77
+ validate(intent: unknown): ProjectedOutcome;
78
+ execute(intent: unknown, options?: { confirm?: boolean }): Promise<ProjectedOutcome>;
79
+ }
80
+
81
+ /** The slice of the WebMCP surface this projection touches. */
82
+ export interface ModelContext {
83
+ registerTool(descriptor: {
84
+ name: string;
85
+ description: string;
86
+ inputSchema: unknown;
87
+ execute(input: unknown): Promise<unknown>;
88
+ }): void | Promise<void>;
89
+ getTools?(): unknown;
90
+ executeTool?(tool: unknown, input: unknown): Promise<unknown>;
91
+ }
92
+
93
+ declare global {
94
+ interface Document {
95
+ modelContext?: ModelContext;
96
+ }
97
+ }
98
+
99
+ // -------------------------------------------------------------------- result
100
+
101
+ /** What the agent gets back, before the MCP content envelope is put round it. */
102
+ export interface ToolResultPayload extends Record<string, unknown> {
103
+ ok: boolean;
104
+ status: string;
105
+ message: string;
106
+ }
107
+
108
+ export interface ToolCallLog {
109
+ readonly input: unknown;
110
+ readonly result: ToolResultPayload;
111
+ }
112
+
113
+ export interface RegistrationResult {
114
+ registered: boolean;
115
+ toolName: string;
116
+ /** Why not, when `registered` is false. Safe to show a developer. */
117
+ reason?: string;
118
+ /** The schema handed to the agent, for inspection in a test or a UI. */
119
+ inputSchema?: JsonSchema;
120
+ }
121
+
122
+ export interface RegisterAgentToolOptions<TAgent extends ProjectableAgent> {
123
+ /** The tool name the agent sees. One per page. */
124
+ name: string;
125
+ /** Natural-language description, built from the live contract. */
126
+ describe: (agent: TAgent) => string;
127
+ /** Extra fields merged into a successful result — row counts, undo state. */
128
+ summarise?: (agent: TAgent) => Record<string, unknown>;
129
+ /** How many operations may be sent in one call. Default 8. */
130
+ maxIntents?: number;
131
+ /** Description for the `intents` array itself. */
132
+ intentsDescription?: string;
133
+ /** Observe every call, for a UI log or a test. Must not throw. */
134
+ onCall?: (entry: ToolCallLog) => void;
135
+ /**
136
+ * Where to register. Defaults to `document.modelContext`. Supplying one is
137
+ * for tests and for hosts that polyfill the surface elsewhere.
138
+ */
139
+ modelContext?: ModelContext;
140
+ }
141
+
142
+ const UNAVAILABLE =
143
+ "document.modelContext is unavailable. Chrome needs --enable-features=WebMCPTesting, " +
144
+ "the chrome://flags/#enable-webmcp-testing flag, or an origin-trial token.";
145
+
146
+ /**
147
+ * Whether this page can register WebMCP tools at all.
148
+ *
149
+ * Guards `document` rather than assuming it: this module is imported by code
150
+ * that also runs during server rendering, where touching `document` throws.
151
+ */
152
+ export function webmcpAvailable(modelContext?: ModelContext): boolean {
153
+ const target = modelContext ?? (typeof document === "undefined" ? undefined : document.modelContext);
154
+ return typeof target?.registerTool === "function";
155
+ }
156
+
157
+ /**
158
+ * The tool's input schema, derived from the live contract.
159
+ *
160
+ * Not hand-written. `agent.schema()` is the generated per-instance schema, so
161
+ * a tool registered against a component with different columns, operators or
162
+ * policy advertises different arguments automatically.
163
+ */
164
+ export function buildToolInputSchema(
165
+ agent: ProjectableAgent,
166
+ options: { maxIntents?: number; intentsDescription?: string } = {},
167
+ ): JsonSchema {
168
+ return {
169
+ type: "object",
170
+ additionalProperties: false,
171
+ required: ["intents"],
172
+ properties: {
173
+ intents: {
174
+ type: "array",
175
+ minItems: 1,
176
+ maxItems: options.maxIntents ?? 8,
177
+ description:
178
+ options.intentsDescription ??
179
+ "Operations to apply in order. Several filters on different fields combine with AND.",
180
+ items: agent.schema(),
181
+ },
182
+ },
183
+ };
184
+ }
185
+
186
+ /**
187
+ * Registers one tool, if the browser has WebMCP.
188
+ *
189
+ * `execute` runs the production pipeline and nothing else:
190
+ *
191
+ * validate → a refusal is returned as the validator wrote it
192
+ * confirm → anything irreversible stops here and asks, rather than running
193
+ * execute → only after validation passed
194
+ *
195
+ * There is no repair, no retry, and no path that exists only for WebMCP. An
196
+ * agent sending something the component cannot do gets the same refusal, with
197
+ * the same code and layer, that a form would have got.
198
+ */
199
+ export function registerAgentTool<TAgent extends ProjectableAgent>(
200
+ agent: TAgent,
201
+ options: RegisterAgentToolOptions<TAgent>,
202
+ ): RegistrationResult {
203
+ const modelContext =
204
+ options.modelContext ?? (typeof document === "undefined" ? undefined : document.modelContext);
205
+
206
+ if (typeof modelContext?.registerTool !== "function") {
207
+ return { registered: false, toolName: options.name, reason: UNAVAILABLE };
208
+ }
209
+
210
+ const inputSchema = buildToolInputSchema(agent, options);
211
+
212
+ modelContext.registerTool({
213
+ name: options.name,
214
+ description: options.describe(agent),
215
+ inputSchema,
216
+
217
+ async execute(rawInput: unknown) {
218
+ const intents = (rawInput as { intents?: unknown } | null | undefined)?.intents;
219
+
220
+ const reply = (payload: ToolResultPayload) => {
221
+ try {
222
+ options.onCall?.({ input: rawInput, result: payload });
223
+ } catch {
224
+ /* A broken observer must not turn a good command into an error. */
225
+ }
226
+ return {
227
+ // MCP's content shape, so an agent reading text gets something useful…
228
+ content: [{ type: "text", text: payload.message }],
229
+ // …and the structured result for anything that wants to inspect it.
230
+ structuredContent: payload,
231
+ isError: payload.ok === false,
232
+ };
233
+ };
234
+
235
+ if (!Array.isArray(intents) || intents.length === 0) {
236
+ return reply({
237
+ ok: false,
238
+ status: "rejected",
239
+ code: "missing-intents",
240
+ message: '"intents" must be a non-empty array of operations.',
241
+ });
242
+ }
243
+
244
+ /* Layer one of the real pipeline. Nothing has touched the component yet. */
245
+ let checked: ProjectedOutcome;
246
+ try {
247
+ checked = agent.validate(intents);
248
+ } catch (error) {
249
+ return reply({
250
+ ok: false,
251
+ status: "rejected",
252
+ code: "validator-threw",
253
+ message: error instanceof Error ? error.message : String(error),
254
+ });
255
+ }
256
+
257
+ if (checked.status === "rejected") {
258
+ return reply({
259
+ ok: false,
260
+ status: "rejected",
261
+ code: checked.code,
262
+ layer: checked.layer,
263
+ suggestion: checked.suggestion,
264
+ message: checked.reason,
265
+ });
266
+ }
267
+
268
+ if (checked.status === "clarify") {
269
+ return reply({
270
+ ok: false,
271
+ status: "clarify",
272
+ message: checked.question,
273
+ options: checked.options,
274
+ });
275
+ }
276
+
277
+ if (checked.status === "declined") {
278
+ return reply({ ok: false, status: "declined", message: checked.reason });
279
+ }
280
+
281
+ if (checked.status === "needs-confirmation") {
282
+ /*
283
+ * An agent does not get to skip a confirmation a person would see. The
284
+ * component is left untouched and the request is handed back.
285
+ */
286
+ return reply({
287
+ ok: false,
288
+ status: "needs-confirmation",
289
+ code: checked.confirm.code,
290
+ message: checked.confirm.message,
291
+ explain: checked.commands.map((command) => command.explain.summary),
292
+ });
293
+ }
294
+
295
+ let run: ProjectedOutcome;
296
+ try {
297
+ run = await agent.execute(intents);
298
+ } catch (error) {
299
+ return reply({
300
+ ok: false,
301
+ status: "failed",
302
+ code: "executor-threw",
303
+ message: error instanceof Error ? error.message : String(error),
304
+ });
305
+ }
306
+
307
+ if (run.status !== "done") {
308
+ return reply({
309
+ ok: false,
310
+ status: run.status,
311
+ message:
312
+ "reason" in run ? run.reason : "question" in run ? run.question : run.status,
313
+ });
314
+ }
315
+
316
+ return reply({
317
+ ok: true,
318
+ status: "done",
319
+ message: run.commands.map((command) => command.explain.summary).join("; "),
320
+ applied: run.commands.map((command) => command.intent),
321
+ warnings: run.warnings.map((warning) => `${warning.code}: ${warning.message}`),
322
+ ...(options.summarise?.(agent) ?? {}),
323
+ });
324
+ },
325
+ });
326
+
327
+ return { registered: true, toolName: options.name, inputSchema };
328
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Joins class names, dropping anything falsy.
3
+ *
4
+ * Every component builds its class strings with this, so a `className` or
5
+ * `classNames` prop that is `undefined` contributes nothing rather than the
6
+ * string "undefined".
7
+ */
8
+ export const cx = (...names: (string | false | null | undefined)[]) =>
9
+ names.filter(Boolean).join(" ");
@@ -0,0 +1,35 @@
1
+ import { cx } from "./cx";
2
+
3
+ export interface DescribedByParts {
4
+ /** An `aria-describedby` the caller passed in; kept first so it reads first. */
5
+ extra?: string;
6
+ /** Renders `#{id}-hint`. */
7
+ hint?: unknown;
8
+ /** Renders `#{id}-description`. */
9
+ description?: unknown;
10
+ /** Renders `#{id}-error`. */
11
+ error?: unknown;
12
+ }
13
+
14
+ /**
15
+ * The `aria-describedby` for a form control, built from whichever of its hint,
16
+ * description and error are actually rendered.
17
+ *
18
+ * Every control derives the ids the same way (`{id}-description`, `{id}-error`),
19
+ * so the helper owns both the ids and their order: a screen reader reads the
20
+ * caller's own description first, then the hint, then ours, and the error last,
21
+ * which is the part that changes and that the listener is waiting for.
22
+ *
23
+ * Returns `undefined` rather than `""` when nothing is described, because an
24
+ * empty `aria-describedby` still points at nothing and confuses some readers.
25
+ */
26
+ export function describeField(id: string, parts: DescribedByParts): string | undefined {
27
+ return (
28
+ cx(
29
+ typeof parts.extra === "string" ? parts.extra : "",
30
+ parts.hint ? `${id}-hint` : "",
31
+ parts.description ? `${id}-description` : "",
32
+ parts.error ? `${id}-error` : "",
33
+ ) || undefined
34
+ );
35
+ }
@@ -0,0 +1,124 @@
1
+ /** The side of the anchor a popover is placed on. */
2
+ export type Side = "top" | "bottom" | "left" | "right";
3
+
4
+ /**
5
+ * Which edge of the anchor the popover lines up with, in reading order, or
6
+ * `center` to share its midpoint.
7
+ */
8
+ export type Align = "start" | "center" | "end";
9
+
10
+ export interface Size {
11
+ width: number;
12
+ height: number;
13
+ }
14
+
15
+ export interface AnchorRect extends Size {
16
+ top: number;
17
+ right: number;
18
+ bottom: number;
19
+ left: number;
20
+ }
21
+
22
+ export interface PlacementOptions {
23
+ /** The side to try first. */
24
+ side: Side;
25
+ align: Align;
26
+ /** Distance between the anchor and the popover. */
27
+ gap: number;
28
+ /** Space kept between the popover and the edge of the viewport. */
29
+ edge: number;
30
+ /** Mirrors `left`/`right` and swaps which edge `align` means. */
31
+ rtl: boolean;
32
+ /**
33
+ * The content scrolls, so the popover may be capped to the space available
34
+ * and should prefer whichever side has more of it. Fixed-size panels leave
35
+ * this off and only move when they fully fit on the other side.
36
+ */
37
+ fitHeight: boolean;
38
+ /** Floor for the cap, so a cramped viewport still shows something. */
39
+ minHeight: number;
40
+ }
41
+
42
+ export interface Placement {
43
+ left: number;
44
+ top: number;
45
+ /** Where it actually ended up, which is not the requested side after a flip. */
46
+ side: Side;
47
+ /** Only when `fitHeight` asked for one. */
48
+ maxHeight?: number;
49
+ }
50
+
51
+ const clamp = (value: number, min: number, max: number) =>
52
+ Math.min(Math.max(value, min), Math.max(min, max));
53
+
54
+ /**
55
+ * Where to put a popover: on the requested side of its anchor, moved to the
56
+ * opposite side when there is no room, and kept inside the viewport.
57
+ *
58
+ * Pure arithmetic, so the rules can be tested without a browser. The caller
59
+ * measures, this decides, the caller writes the styles.
60
+ */
61
+ export function placePopover(
62
+ anchor: AnchorRect,
63
+ size: Size,
64
+ viewport: Size,
65
+ options: PlacementOptions,
66
+ ): Placement {
67
+ const { side, align, gap, edge, rtl, fitHeight, minHeight } = options;
68
+ const alignEnd = (align === "end") !== rtl;
69
+
70
+ /** The cross-axis offset: centred, or against one edge of the anchor. */
71
+ const across = (start: number, length: number, extent: number) =>
72
+ align === "center"
73
+ ? start + (length - extent) / 2
74
+ : alignEnd
75
+ ? start + length - extent
76
+ : start;
77
+
78
+ if (side === "top" || side === "bottom") {
79
+ const roomBelow = viewport.height - anchor.bottom - gap - edge;
80
+ const roomAbove = anchor.top - gap - edge;
81
+ const prefersBelow = side === "bottom";
82
+ const roomPreferred = prefersBelow ? roomBelow : roomAbove;
83
+ const roomOther = prefersBelow ? roomAbove : roomBelow;
84
+
85
+ const flip =
86
+ size.height > roomPreferred &&
87
+ (fitHeight ? roomOther > roomPreferred : size.height <= roomOther);
88
+ const below = prefersBelow !== flip;
89
+
90
+ return {
91
+ side: below ? "bottom" : "top",
92
+ left: clamp(
93
+ across(anchor.left, anchor.width, size.width),
94
+ edge,
95
+ viewport.width - size.width - edge,
96
+ ),
97
+ top: Math.max(edge, below ? anchor.bottom + gap : anchor.top - gap - size.height),
98
+ maxHeight: fitHeight
99
+ ? Math.max(minHeight, below ? roomBelow : roomAbove)
100
+ : undefined,
101
+ };
102
+ }
103
+
104
+ const roomRight = viewport.width - anchor.right - gap - edge;
105
+ const roomLeft = anchor.left - gap - edge;
106
+ const prefersRight = (side === "right") !== rtl;
107
+ const roomPreferred = prefersRight ? roomRight : roomLeft;
108
+ const roomOther = prefersRight ? roomLeft : roomRight;
109
+
110
+ // Sideways there is nothing to scroll, so it only moves when it fully fits.
111
+ const flip = size.width > roomPreferred && size.width <= roomOther;
112
+ const right = prefersRight !== flip;
113
+
114
+ return {
115
+ side: right ? "right" : "left",
116
+ left: Math.max(edge, right ? anchor.right + gap : anchor.left - gap - size.width),
117
+ top: clamp(
118
+ across(anchor.top, anchor.height, size.height),
119
+ edge,
120
+ viewport.height - size.height - edge,
121
+ ),
122
+ maxHeight: fitHeight ? Math.max(minHeight, viewport.height - 2 * edge) : undefined,
123
+ };
124
+ }
@@ -0,0 +1,14 @@
1
+ let segmenter: Intl.Segmenter | null | undefined;
2
+
3
+ /**
4
+ * Characters as a person counts them. `"👍🏽".length` is 4 and `"é"` can be 2,
5
+ * but each is one character here. Falls back to code points where
6
+ * `Intl.Segmenter` is missing.
7
+ */
8
+ export function countCharacters(value: string): number {
9
+ if (!value) return 0;
10
+ if (segmenter === undefined) {
11
+ segmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter() : null;
12
+ }
13
+ return segmenter ? Array.from(segmenter.segment(value)).length : Array.from(value).length;
14
+ }
@@ -0,0 +1,17 @@
1
+ export { cx } from "./core/cx";
2
+ export { countCharacters } from "./core/text";
3
+ export { describeField, type DescribedByParts } from "./core/field";
4
+ export { useControllableState } from "./react/useControllableState";
5
+ export { AnchoredPopover, type AnchoredPopoverProps } from "./react/Popover";
6
+ export { placePopover, type Align, type Placement, type Side } from "./core/position";
7
+ export * as icons from "./react/icons";
8
+ export { version as sharedVersion } from "./version";
9
+
10
+ // Agent runtime: the component-agnostic operation/validation/history layer.
11
+ export * from "./core/agent";
12
+ export {
13
+ GramproAIProvider,
14
+ useAgentAdapter,
15
+ type GramproAIProviderProps,
16
+ } from "./react/GramproAIProvider";
17
+ export { useAskAgent, type AskableAgent, type AskExecution, type UseAskAgent } from "./react/useAskAgent";