bitboss-ui 3.0.0-beta.37 → 3.0.0-beta.41

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 (463) hide show
  1. package/README.md +32 -9
  2. package/bin/bitboss-ui-mcp.mjs +328 -19
  3. package/bin/bitboss-ui.mjs +275 -20
  4. package/dist/ai/BbAccordion.md +6 -2
  5. package/dist/ai/BbAlert.md +8 -4
  6. package/dist/ai/BbAsterisk.md +8 -4
  7. package/dist/ai/BbAvatar.md +47 -62
  8. package/dist/ai/BbBadge.md +11 -3
  9. package/dist/ai/BbBadgeButton.md +4 -4
  10. package/dist/ai/BbBaseButton.md +8 -4
  11. package/dist/ai/BbBaseCheckboxIcon.md +6 -2
  12. package/dist/ai/BbBaseRadioIcon.md +6 -2
  13. package/dist/ai/BbBaseSwitchIcon.md +6 -2
  14. package/dist/ai/BbBreadcrumbs.md +17 -6
  15. package/dist/ai/BbButton.md +13 -3
  16. package/dist/ai/BbCalendar.md +52 -15
  17. package/dist/ai/BbCheckbox.md +13 -13
  18. package/dist/ai/BbCheckboxGroup.md +38 -21
  19. package/dist/ai/BbCollapsible.md +6 -2
  20. package/dist/ai/BbColorInput.md +29 -24
  21. package/dist/ai/BbColorPalette.md +25 -16
  22. package/dist/ai/BbConfirm.md +16 -10
  23. package/dist/ai/BbDatePicker.md +21 -17
  24. package/dist/ai/BbDatePickerInput.md +24 -26
  25. package/dist/ai/BbDialog.md +6 -2
  26. package/dist/ai/BbDropdown.md +73 -23
  27. package/dist/ai/BbDropdownButton.md +15 -10
  28. package/dist/ai/BbDropzone.md +13 -15
  29. package/dist/ai/BbForm.md +1112 -24
  30. package/dist/ai/BbIcon.md +8 -2
  31. package/dist/ai/BbIndicator.md +6 -2
  32. package/dist/ai/BbNumberInput.md +28 -23
  33. package/dist/ai/BbOffCanvas.md +17 -24
  34. package/dist/ai/BbPagination.md +24 -10
  35. package/dist/ai/BbPopover.md +26 -16
  36. package/dist/ai/BbProgress.md +20 -9
  37. package/dist/ai/BbRadio.md +14 -3
  38. package/dist/ai/BbRadioGroup.md +34 -20
  39. package/dist/ai/BbRating.md +14 -16
  40. package/dist/ai/BbSelect.md +62 -31
  41. package/dist/ai/BbSelectPopover.md +45 -11
  42. package/dist/ai/BbSlider.md +22 -18
  43. package/dist/ai/BbSmoothHeight.md +6 -2
  44. package/dist/ai/BbSpinner.md +10 -4
  45. package/dist/ai/BbSwitch.md +15 -15
  46. package/dist/ai/BbSwitchGroup.md +39 -22
  47. package/dist/ai/BbTable.md +229 -92
  48. package/dist/ai/BbTabs.md +184 -16
  49. package/dist/ai/BbTabsList.md +2 -2
  50. package/dist/ai/BbTabsPanels.md +2 -2
  51. package/dist/ai/BbTag.md +15 -17
  52. package/dist/ai/BbTextInput.md +22 -24
  53. package/dist/ai/BbTextarea.md +27 -26
  54. package/dist/ai/BbTimePicker.md +14 -7
  55. package/dist/ai/BbTimePickerInput.md +17 -19
  56. package/dist/ai/BbToast.md +6 -2
  57. package/dist/ai/BbTooltip.md +15 -2
  58. package/dist/ai/BbTree.md +23 -17
  59. package/dist/ai/CommonField.md +15 -2
  60. package/dist/ai/CommonFieldInput.md +2 -2
  61. package/dist/ai/FlatListBox.md +2 -2
  62. package/dist/ai/GroupedListBox.md +2 -2
  63. package/dist/ai/ListBox.md +2 -2
  64. package/dist/ai/OptionsContainer.md +2 -2
  65. package/dist/ai/changelog.json +2491 -305
  66. package/dist/ai/components.json +5359 -1046
  67. package/dist/ai/composables/useBbFormContext.md +38 -25
  68. package/dist/ai/composables/useBbFormField.md +134 -0
  69. package/dist/ai/composables/useBbTableContext.md +15 -14
  70. package/dist/ai/composables/useConfirm.md +3 -3
  71. package/dist/ai/composables/useCountdown.md +1 -1
  72. package/dist/ai/composables/useId.md +10 -10
  73. package/dist/ai/design-tokens.json +940 -0
  74. package/dist/ai/design-tokens.manifest.yaml +175 -0
  75. package/dist/ai/guides/agent-contract.md +70 -11
  76. package/dist/ai/guides/ai-router.md +26 -13
  77. package/dist/ai/guides/component-picker.md +17 -16
  78. package/dist/ai/guides/design-language.md +23 -5
  79. package/dist/ai/guides/design-tokens.md +17 -2
  80. package/dist/ai/guides/fetch-items-playbook.md +1 -1
  81. package/dist/ai/guides/icons-policy.md +3 -1
  82. package/dist/ai/guides/inertia-helpers.md +4 -1
  83. package/dist/ai/guides/installation-and-plugin-setup.md +126 -28
  84. package/dist/ai/guides/migration/components/bb-breadcrumbs.md +2 -2
  85. package/dist/ai/guides/migration/components/bb-checkbox-group.md +42 -2
  86. package/dist/ai/guides/migration/components/bb-checkbox.md +7 -0
  87. package/dist/ai/guides/migration/components/bb-color-palette.md +7 -0
  88. package/dist/ai/guides/migration/components/bb-date-picker-input.md +1 -1
  89. package/dist/ai/guides/migration/components/bb-icon.md +7 -7
  90. package/dist/ai/guides/migration/components/bb-offcanvas.md +0 -18
  91. package/dist/ai/guides/migration/components/bb-pagination.md +10 -0
  92. package/dist/ai/guides/migration/components/bb-radio-group.md +14 -0
  93. package/dist/ai/guides/migration/components/bb-switch-group.md +14 -0
  94. package/dist/ai/guides/migration/components/bb-table.md +28 -21
  95. package/dist/ai/guides/migration/components/bb-tabs.md +11 -9
  96. package/dist/ai/guides/migration/components/bb-text-input.md +6 -6
  97. package/dist/ai/guides/migration/components/bb-tree.md +3 -1
  98. package/dist/ai/guides/migration/v2-to-v3.md +201 -27
  99. package/dist/ai/guides/migration/v3-beta-css-classes.md +39 -11
  100. package/dist/ai/guides/migration/v3-beta-tooling.md +119 -0
  101. package/dist/ai/guides/options-items-playbook.md +80 -0
  102. package/dist/ai/guides/passthrough.md +193 -62
  103. package/dist/ai/guides/preset-components.md +361 -0
  104. package/dist/ai/guides/ssr-prefill.md +5 -0
  105. package/dist/ai/guides/validated-forms.md +462 -62
  106. package/dist/ai/guides/validation-libraries.md +171 -0
  107. package/dist/ai/guides/validation-providers.md +113 -0
  108. package/dist/ai/index.md +18 -7
  109. package/dist/ai/recipes/inertia/approvals-inbox.md +2 -2
  110. package/dist/ai/recipes/inertia/command-palette.md +2 -2
  111. package/dist/ai/recipes/inertia/inline-edit-workspace.md +1 -1
  112. package/dist/ai/recipes/inertia/layout-scaffold.md +1 -1
  113. package/dist/ai/recipes/inertia/ownership-atlas.md +5 -5
  114. package/dist/ai/recipes/inertia/record-form.md +34 -7
  115. package/dist/ai/recipes/inertia/records-workspace.md +12 -8
  116. package/dist/ai/recipes/inertia/settings-workspace.md +3809 -0
  117. package/dist/ai/recipes/inertia/upload-center.md +2 -2
  118. package/dist/ai/recipes/inertia/wizard-form.md +14 -6
  119. package/dist/ai/recipes/nuxt/approvals-inbox.md +2 -2
  120. package/dist/ai/recipes/nuxt/command-palette.md +2 -2
  121. package/dist/ai/recipes/nuxt/inline-edit-workspace.md +1 -1
  122. package/dist/ai/recipes/nuxt/layout-scaffold.md +1 -1
  123. package/dist/ai/recipes/nuxt/record-form.md +34 -7
  124. package/dist/ai/recipes/nuxt/records-workspace.md +12 -8
  125. package/dist/ai/recipes/nuxt/settings-workspace.md +3898 -0
  126. package/dist/ai/recipes/nuxt/upload-center.md +2 -2
  127. package/dist/ai/recipes/nuxt/wizard-form.md +14 -6
  128. package/dist/ai/recipes/vue/approvals-inbox.md +2 -2
  129. package/dist/ai/recipes/vue/command-palette.md +2 -2
  130. package/dist/ai/recipes/vue/inline-edit-workspace.md +1 -1
  131. package/dist/ai/recipes/vue/layout-scaffold.md +1 -1
  132. package/dist/ai/recipes/vue/record-form.md +28 -19
  133. package/dist/ai/recipes/vue/records-workspace.md +12 -8
  134. package/dist/ai/recipes/vue/settings-workspace.md +3836 -0
  135. package/dist/ai/recipes/vue/upload-center.md +2 -2
  136. package/dist/ai/recipes/vue/wizard-form.md +14 -6
  137. package/dist/ai/source/BbAlert.md +21 -2
  138. package/dist/ai/source/BbAsterisk.md +1 -1
  139. package/dist/ai/source/BbBadge.md +29 -0
  140. package/dist/ai/source/BbBadgeButton.md +32 -3
  141. package/dist/ai/source/BbBaseButton.md +5 -3
  142. package/dist/ai/source/BbBreadcrumbs.md +66 -7
  143. package/dist/ai/source/BbButton.md +8 -0
  144. package/dist/ai/source/BbCalendar.md +89 -25
  145. package/dist/ai/source/BbCheckbox.md +28 -4
  146. package/dist/ai/source/BbCheckboxGroup.md +75 -11
  147. package/dist/ai/source/BbColorInput.md +81 -17
  148. package/dist/ai/source/BbColorPalette.md +91 -10
  149. package/dist/ai/source/BbConfirm.md +11 -2
  150. package/dist/ai/source/BbDatePicker.md +40 -23
  151. package/dist/ai/source/BbDatePickerInput.md +34 -18
  152. package/dist/ai/source/BbDropdown.md +46 -20
  153. package/dist/ai/source/BbDropdownButton.md +11 -5
  154. package/dist/ai/source/BbDropdownGroup.md +42 -17
  155. package/dist/ai/source/BbDropzone.md +13 -5
  156. package/dist/ai/source/BbForm.md +788 -18
  157. package/dist/ai/source/BbIcon.md +9 -1
  158. package/dist/ai/source/BbIndicator.md +9 -0
  159. package/dist/ai/source/BbNumberInput.md +84 -25
  160. package/dist/ai/source/BbOffCanvas.md +17 -5
  161. package/dist/ai/source/BbPagination.md +31 -0
  162. package/dist/ai/source/BbPopover.md +5 -6
  163. package/dist/ai/source/BbRadio.md +9 -0
  164. package/dist/ai/source/BbRadioGroup.md +74 -11
  165. package/dist/ai/source/BbRating.md +59 -7
  166. package/dist/ai/source/BbSelect.md +67 -29
  167. package/dist/ai/source/BbSelectPopover.md +25 -17
  168. package/dist/ai/source/BbSlider.md +99 -14
  169. package/dist/ai/source/BbSwitch.md +18 -3
  170. package/dist/ai/source/BbSwitchGroup.md +64 -6
  171. package/dist/ai/source/BbTable.md +1102 -180
  172. package/dist/ai/source/BbTabs.md +9 -3
  173. package/dist/ai/source/BbTabsList.md +95 -34
  174. package/dist/ai/source/BbTabsPanels.md +5 -2
  175. package/dist/ai/source/BbTabsRoot.md +5 -2
  176. package/dist/ai/source/BbTag.md +37 -10
  177. package/dist/ai/source/BbTextInput.md +46 -14
  178. package/dist/ai/source/BbTextarea.md +56 -14
  179. package/dist/ai/source/BbTimePicker.md +37 -14
  180. package/dist/ai/source/BbTimePickerInput.md +33 -12
  181. package/dist/ai/source/BbToast.md +26 -0
  182. package/dist/ai/source/BbToastPortal.md +26 -0
  183. package/dist/ai/source/BbTree.md +17 -12
  184. package/dist/ai/source/CommonField.md +22 -4
  185. package/dist/ai/source/CommonFieldInput.md +48 -6
  186. package/dist/ai/source/CommonPopover.md +8 -4
  187. package/dist/ai/source/FlatListBox.md +6 -6
  188. package/dist/ai/source/GroupedListBox.md +6 -6
  189. package/dist/ai/source/ListBox.md +6 -6
  190. package/dist/ai/source/OptionsContainer.md +7 -7
  191. package/dist/assets/css/reset.css_inline.js +1 -1
  192. package/dist/components/BbAlert/BbAlert.vue_vue_type_script_setup_true_lang.js +1 -1
  193. package/dist/components/BbAlert/types.d.ts +2 -2
  194. package/dist/components/BbBaseButton/types.d.ts +5 -3
  195. package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue_vue_type_script_setup_true_lang.js +52 -47
  196. package/dist/components/BbBreadcrumbs/types.d.ts +5 -3
  197. package/dist/components/BbCalendar/BbCalendar.vue_vue_type_script_setup_true_lang.js +187 -186
  198. package/dist/components/BbCalendar/types.d.ts +6 -6
  199. package/dist/components/BbCalendar/useCalendarGrid.js +173 -168
  200. package/dist/components/BbCalendar/useDayGrid.js +118 -117
  201. package/dist/components/BbCalendar/useToday.d.ts +23 -0
  202. package/dist/components/BbCalendar/useToday.js +21 -0
  203. package/dist/components/BbCheckbox/BbCheckbox.vue_vue_type_script_setup_true_lang.js +74 -59
  204. package/dist/components/BbCheckbox/types.d.ts +9 -1
  205. package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue.d.ts +13 -1
  206. package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue_vue_type_script_setup_true_lang.js +111 -99
  207. package/dist/components/BbCheckboxGroup/types.d.ts +12 -7
  208. package/dist/components/BbColorInput/BbColorInput.vue.d.ts +1 -1
  209. package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +89 -70
  210. package/dist/components/BbColorInput/types.d.ts +6 -5
  211. package/dist/components/BbColorPalette/BbColorPalette.vue_vue_type_script_setup_true_lang.js +256 -254
  212. package/dist/components/BbColorPalette/types.d.ts +2 -2
  213. package/dist/components/BbConfirm/BbConfirm.vue_vue_type_script_setup_true_lang.js +9 -3
  214. package/dist/components/BbDatePicker/BbDatePicker.vue_vue_type_script_setup_true_lang.js +121 -117
  215. package/dist/components/BbDatePicker/types.d.ts +10 -7
  216. package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +301 -290
  217. package/dist/components/BbDatePickerInput/types.d.ts +8 -7
  218. package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +6 -2
  219. package/dist/components/BbDropdown/BbDropdownGroup.vue.d.ts +1 -1
  220. package/dist/components/BbDropdown/BbDropdownList.vue.d.ts +2 -2
  221. package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +334 -327
  222. package/dist/components/BbDropdown/DropdownPipelineResolver.vue_vue_type_script_setup_true_lang.js +15 -15
  223. package/dist/components/BbDropdown/normalizeGroups.js +48 -29
  224. package/dist/components/BbDropdown/types.d.ts +42 -19
  225. package/dist/components/BbDropdown/types.js +1 -0
  226. package/dist/components/BbDropdown/useDropdownContext.d.ts +4 -4
  227. package/dist/components/BbDropdownButton/BbDropdownButton.vue_vue_type_script_setup_true_lang.js +6 -1
  228. package/dist/components/BbDropdownButton/types.d.ts +8 -4
  229. package/dist/components/BbDropdownButton/types.js +1 -0
  230. package/dist/components/BbDropzone/BbDropzone.vue_vue_type_script_setup_true_lang.js +141 -133
  231. package/dist/components/BbDropzone/types.d.ts +3 -2
  232. package/dist/components/BbForm/BbForm.vue.d.ts +94 -0
  233. package/dist/{validated → components/BbForm}/BbForm.vue.js +1 -1
  234. package/dist/components/BbForm/BbForm.vue_vue_type_script_setup_true_lang.js +317 -0
  235. package/dist/components/BbForm/BbFormCustomField.d.ts +14 -0
  236. package/dist/components/BbForm/BbFormCustomField.js +43 -0
  237. package/dist/components/BbForm/bindFormField.d.ts +16 -0
  238. package/dist/components/BbForm/bindFormField.js +85 -0
  239. package/dist/components/BbForm/formFields.d.ts +64 -0
  240. package/dist/components/BbForm/formFields.js +11 -0
  241. package/dist/components/BbForm/formSchema.d.ts +56 -0
  242. package/dist/components/BbForm/formSchema.js +196 -0
  243. package/dist/components/BbForm/standardSchema.d.ts +59 -0
  244. package/dist/components/BbIcon/BbIcon.vue_vue_type_script_setup_true_lang.js +1 -1
  245. package/dist/components/BbNumberInput/BbNumberInput.vue.d.ts +1 -2
  246. package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +134 -106
  247. package/dist/components/BbNumberInput/types.d.ts +8 -6
  248. package/dist/components/BbPagination/BbPagination.vue.d.ts +1 -1
  249. package/dist/components/BbRadio/BbRadio.vue_vue_type_script_setup_true_lang.js +3 -0
  250. package/dist/components/BbRadio/types.d.ts +7 -0
  251. package/dist/components/BbRadioGroup/BbRadioGroup.vue.d.ts +13 -1
  252. package/dist/components/BbRadioGroup/BbRadioGroup.vue_vue_type_script_setup_true_lang.js +125 -114
  253. package/dist/components/BbRadioGroup/types.d.ts +12 -7
  254. package/dist/components/BbRating/BbRating.vue_vue_type_script_setup_true_lang.js +88 -77
  255. package/dist/components/BbRating/types.d.ts +3 -2
  256. package/dist/components/BbSelect/BbSelect.vue.d.ts +15 -1
  257. package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +190 -162
  258. package/dist/components/BbSelect/types.d.ts +21 -13
  259. package/dist/components/BbSelect/types.js +1 -0
  260. package/dist/components/BbSelectPopover/BbSelectPopover.vue.d.ts +15 -1
  261. package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +5 -5
  262. package/dist/components/BbSelectPopover/types.d.ts +12 -7
  263. package/dist/components/BbSlider/BbSlider.vue.d.ts +0 -1
  264. package/dist/components/BbSlider/BbSlider.vue_vue_type_script_setup_true_lang.js +222 -191
  265. package/dist/components/BbSlider/types.d.ts +3 -2
  266. package/dist/components/BbSwitch/BbSwitch.vue_vue_type_script_setup_true_lang.js +88 -73
  267. package/dist/components/BbSwitchGroup/BbSwitchGroup.vue.d.ts +13 -1
  268. package/dist/components/BbSwitchGroup/BbSwitchGroup.vue_vue_type_script_setup_true_lang.js +112 -100
  269. package/dist/components/BbSwitchGroup/types.d.ts +1 -1
  270. package/dist/components/BbTable/BbTable.vue.d.ts +19 -4
  271. package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +1088 -814
  272. package/dist/components/BbTable/BbTableDataRow.d.ts +40 -14
  273. package/dist/components/BbTable/BbTableDataRow.js +37 -29
  274. package/dist/components/BbTable/BbTableExpandRow.d.ts +11 -0
  275. package/dist/components/BbTable/BbTableExpandRow.js +35 -25
  276. package/dist/components/BbTable/gridWidgets.d.ts +30 -0
  277. package/dist/components/BbTable/gridWidgets.js +14 -0
  278. package/dist/components/BbTable/types.d.ts +62 -15
  279. package/dist/components/BbTable/utils.d.ts +53 -0
  280. package/dist/components/BbTable/utils.js +94 -12
  281. package/dist/components/BbTabs/BbTabs.vue.d.ts +3 -1
  282. package/dist/components/BbTabs/BbTabs.vue_vue_type_script_setup_true_lang.js +4 -1
  283. package/dist/components/BbTabs/BbTabsList.vue_vue_type_script_setup_true_lang.js +93 -74
  284. package/dist/components/BbTabs/BbTabsRoot.vue.d.ts +3 -1
  285. package/dist/components/BbTabs/types.d.ts +3 -3
  286. package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +86 -74
  287. package/dist/components/BbTag/types.d.ts +5 -4
  288. package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +89 -74
  289. package/dist/components/BbTextInput/types.d.ts +5 -4
  290. package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +104 -89
  291. package/dist/components/BbTextarea/types.d.ts +7 -5
  292. package/dist/components/BbTimePicker/BbTimePicker.vue_vue_type_script_setup_true_lang.js +96 -96
  293. package/dist/components/BbTimePicker/types.d.ts +7 -4
  294. package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +269 -254
  295. package/dist/components/BbTimePickerInput/types.d.ts +6 -5
  296. package/dist/components/BbTree/BbTree.vue.d.ts +7 -5
  297. package/dist/components/BbTree/BbTree.vue_vue_type_script_setup_true_lang.js +38 -34
  298. package/dist/components/BbTree/BbTreeLevel.vue.d.ts +1 -1
  299. package/dist/components/BbTree/BbTreeLevel.vue_vue_type_script_setup_true_lang.js +2 -2
  300. package/dist/components/BbTree/types.d.ts +11 -11
  301. package/dist/components/BbTree/types.js +1 -1
  302. package/dist/components/CommonField/CommonField.vue.d.ts +1 -1
  303. package/dist/components/CommonField/CommonField.vue_vue_type_script_setup_true_lang.js +64 -61
  304. package/dist/components/CommonField/types.d.ts +12 -0
  305. package/dist/components/CommonFieldInput/CommonFieldInput.vue_vue_type_script_setup_true_lang.js +2 -2
  306. package/dist/components/CommonFieldInput/types.d.ts +2 -2
  307. package/dist/components/FlatListBox/FlatListBox.vue.d.ts +5 -1
  308. package/dist/components/FlatListBox/FlatListBox.vue_vue_type_script_setup_true_lang.js +4 -4
  309. package/dist/components/FlatListBox/types.d.ts +2 -2
  310. package/dist/components/GroupedListBox/GroupedListBox.vue.d.ts +5 -1
  311. package/dist/components/GroupedListBox/GroupedListBox.vue_vue_type_script_setup_true_lang.js +4 -4
  312. package/dist/components/GroupedListBox/types.d.ts +2 -2
  313. package/dist/components/ListBox/ListBox.vue.d.ts +5 -1
  314. package/dist/components/ListBox/ListBox.vue_vue_type_script_setup_true_lang.js +7 -7
  315. package/dist/components/ListBox/types.d.ts +2 -2
  316. package/dist/components/OptionsContainer/OptionsContainer.vue.d.ts +1 -1
  317. package/dist/components/OptionsContainer/OptionsContainer.vue_vue_type_script_setup_true_lang.js +4 -4
  318. package/dist/components/OptionsContainer/types.d.ts +2 -2
  319. package/dist/components/Transitions/ScaleFade.vue_vue_type_script_setup_true_lang.js +8 -8
  320. package/dist/components/Transitions/Slide.vue.js +1 -1
  321. package/dist/composables/useBbFormContext.d.ts +131 -8
  322. package/dist/composables/useBbFormContext.js +49 -30
  323. package/dist/composables/useBbFormField.d.ts +40 -0
  324. package/dist/composables/useBbFormField.js +39 -0
  325. package/dist/composables/useBbTableContext.d.ts +12 -0
  326. package/dist/composables/useBbTableContext.js +10 -7
  327. package/dist/composables/useBbTabsContext.js +86 -57
  328. package/dist/composables/useConfig.d.ts +1 -1
  329. package/dist/composables/useConfig.js +4 -0
  330. package/dist/composables/useConfirm.d.ts +6 -5
  331. package/dist/composables/useFormBinding.d.ts +116 -0
  332. package/dist/composables/useFormBinding.js +34 -0
  333. package/dist/composables/useId.d.ts +4 -3
  334. package/dist/composables/useId.js +1 -7
  335. package/dist/composables/usePassthrough.d.ts +2 -1
  336. package/dist/composables/usePassthrough.js +47 -44
  337. package/dist/composables/useToast.js +14 -5
  338. package/dist/deprecation/ai-deprecations.json.d.ts +1450 -357
  339. package/dist/deprecation/ai-deprecations.json.js +1 -1
  340. package/dist/deprecation/removedProps.js +9 -4
  341. package/dist/directives/bbTooltip.d.ts +6 -0
  342. package/dist/i18n/locales/cs.json +3 -2
  343. package/dist/i18n/locales/da.json +3 -2
  344. package/dist/i18n/locales/de.json +3 -2
  345. package/dist/i18n/locales/el.json +3 -2
  346. package/dist/i18n/locales/en.json +3 -2
  347. package/dist/i18n/locales/es.json +3 -2
  348. package/dist/i18n/locales/fi.json +3 -2
  349. package/dist/i18n/locales/fr.json +3 -2
  350. package/dist/i18n/locales/hu.json +3 -2
  351. package/dist/i18n/locales/it.json +3 -2
  352. package/dist/i18n/locales/ja.json +3 -2
  353. package/dist/i18n/locales/ko.json +3 -2
  354. package/dist/i18n/locales/nb.json +3 -2
  355. package/dist/i18n/locales/nl.json +3 -2
  356. package/dist/i18n/locales/pl.json +3 -2
  357. package/dist/i18n/locales/pt.json +3 -2
  358. package/dist/i18n/locales/ro.json +3 -2
  359. package/dist/i18n/locales/ru.json +3 -2
  360. package/dist/i18n/locales/sv.json +3 -2
  361. package/dist/i18n/locales/tr.json +3 -2
  362. package/dist/i18n/locales/uk.json +3 -2
  363. package/dist/i18n/locales/zh-cn.json +3 -2
  364. package/dist/index.d.ts +17 -2
  365. package/dist/index.js +14 -11
  366. package/dist/llms-full.txt +37931 -22478
  367. package/dist/llms-medium.txt +263 -74
  368. package/dist/llms.txt +21 -9
  369. package/dist/locale-blueprint.json +3 -2
  370. package/dist/nuxt-auto-imports.d.ts +6 -30
  371. package/dist/nuxt-auto-imports.js +13 -36
  372. package/dist/nuxt-module.d.ts +1 -1
  373. package/dist/project-dts.d.ts +36 -0
  374. package/dist/project-dts.js +76 -5
  375. package/dist/reset.css +1 -1
  376. package/dist/styles.css +2 -2
  377. package/dist/types/ColumnName.d.ts +30 -3
  378. package/dist/types/Config.d.ts +48 -2
  379. package/dist/types/passthrough.d.ts +25 -0
  380. package/dist/types/ptComponentMap.d.ts +4 -4
  381. package/dist/utilities/functions/slotKey.d.ts +13 -8
  382. package/dist/utilities/functions/slotKey.js +78 -2
  383. package/dist/utilities/functions/snapToStep.js +2 -1
  384. package/dist/utilities/functions/warnRemovedAttrs.d.ts +27 -1
  385. package/dist/utilities/functions/warnRemovedAttrs.js +75 -14
  386. package/dist/utils/versionCheck.js +1 -1
  387. package/dist/vite-plugin.d.ts +20 -20
  388. package/dist/vite.js +197 -234
  389. package/llms.txt +21 -9
  390. package/package.json +18 -10
  391. package/scripts/lib/css-class-check.mjs +326 -0
  392. package/scripts/lib/css-class-surface.mjs +292 -0
  393. package/scripts/lib/css-color-resolve.mjs +172 -0
  394. package/scripts/lib/css-local-check.mjs +267 -0
  395. package/scripts/lib/design-token-manifest.mjs +499 -0
  396. package/scripts/lib/doc-sections.mjs +73 -6
  397. package/scripts/lib/eslint-disable.mjs +22 -0
  398. package/scripts/lib/eslint-plugin.d.ts +4 -1
  399. package/scripts/lib/eslint-plugin.mjs +226 -18
  400. package/scripts/lib/hand-imported-styles.mjs +326 -0
  401. package/scripts/lib/local-components.mjs +177 -0
  402. package/scripts/lib/migrate-fix.mjs +62 -3
  403. package/scripts/lib/project-variant-dts.mjs +122 -0
  404. package/scripts/lib/public-type-exports.mjs +27 -0
  405. package/scripts/lib/slot-key.mjs +147 -0
  406. package/scripts/lib/slot-renames.mjs +46 -0
  407. package/scripts/lib/squashed-slot-words.mjs +133 -0
  408. package/scripts/lib/validate-bb-markup.mjs +1561 -37
  409. package/scripts/lib/wrapper-props.mjs +188 -0
  410. package/dist/validated/BbCheckbox.vue.d.ts +0 -31
  411. package/dist/validated/BbCheckbox.vue.js +0 -5
  412. package/dist/validated/BbCheckbox.vue_vue_type_script_setup_true_lang.js +0 -134
  413. package/dist/validated/BbCheckboxGroup.vue.d.ts +0 -159
  414. package/dist/validated/BbCheckboxGroup.vue.js +0 -5
  415. package/dist/validated/BbCheckboxGroup.vue_vue_type_script_setup_true_lang.js +0 -172
  416. package/dist/validated/BbColorInput.vue.d.ts +0 -39
  417. package/dist/validated/BbColorInput.vue.js +0 -5
  418. package/dist/validated/BbColorInput.vue_vue_type_script_setup_true_lang.js +0 -195
  419. package/dist/validated/BbDatePickerInput.vue.d.ts +0 -43
  420. package/dist/validated/BbDatePickerInput.vue.js +0 -5
  421. package/dist/validated/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +0 -496
  422. package/dist/validated/BbDropzone.vue.d.ts +0 -24
  423. package/dist/validated/BbDropzone.vue.js +0 -5
  424. package/dist/validated/BbDropzone.vue_vue_type_script_setup_true_lang.js +0 -61
  425. package/dist/validated/BbForm.vue.d.ts +0 -28
  426. package/dist/validated/BbForm.vue_vue_type_script_setup_true_lang.js +0 -59
  427. package/dist/validated/BbNumberInput.vue.d.ts +0 -38
  428. package/dist/validated/BbNumberInput.vue.js +0 -5
  429. package/dist/validated/BbNumberInput.vue_vue_type_script_setup_true_lang.js +0 -162
  430. package/dist/validated/BbRadioGroup.vue.d.ts +0 -158
  431. package/dist/validated/BbRadioGroup.vue.js +0 -5
  432. package/dist/validated/BbRadioGroup.vue_vue_type_script_setup_true_lang.js +0 -168
  433. package/dist/validated/BbRating.vue.d.ts +0 -32
  434. package/dist/validated/BbRating.vue.js +0 -5
  435. package/dist/validated/BbRating.vue_vue_type_script_setup_true_lang.js +0 -110
  436. package/dist/validated/BbSelect.vue.d.ts +0 -315
  437. package/dist/validated/BbSelect.vue.js +0 -5
  438. package/dist/validated/BbSelect.vue_vue_type_script_setup_true_lang.js +0 -330
  439. package/dist/validated/BbSlider.vue.d.ts +0 -38
  440. package/dist/validated/BbSlider.vue.js +0 -5
  441. package/dist/validated/BbSlider.vue_vue_type_script_setup_true_lang.js +0 -151
  442. package/dist/validated/BbSwitch.vue.d.ts +0 -31
  443. package/dist/validated/BbSwitch.vue.js +0 -5
  444. package/dist/validated/BbSwitch.vue_vue_type_script_setup_true_lang.js +0 -134
  445. package/dist/validated/BbSwitchGroup.vue.d.ts +0 -159
  446. package/dist/validated/BbSwitchGroup.vue.js +0 -5
  447. package/dist/validated/BbSwitchGroup.vue_vue_type_script_setup_true_lang.js +0 -172
  448. package/dist/validated/BbTag.vue.d.ts +0 -38
  449. package/dist/validated/BbTag.vue.js +0 -5
  450. package/dist/validated/BbTag.vue_vue_type_script_setup_true_lang.js +0 -178
  451. package/dist/validated/BbTextInput.vue.d.ts +0 -38
  452. package/dist/validated/BbTextInput.vue.js +0 -5
  453. package/dist/validated/BbTextInput.vue_vue_type_script_setup_true_lang.js +0 -162
  454. package/dist/validated/BbTextarea.vue.d.ts +0 -38
  455. package/dist/validated/BbTextarea.vue.js +0 -5
  456. package/dist/validated/BbTextarea.vue_vue_type_script_setup_true_lang.js +0 -160
  457. package/dist/validated/BbTimePickerInput.vue.d.ts +0 -39
  458. package/dist/validated/BbTimePickerInput.vue.js +0 -5
  459. package/dist/validated/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +0 -249
  460. package/dist/validated/index.d.ts +0 -29
  461. package/dist/validated/useValidatedField.d.ts +0 -93
  462. package/dist/validated/useValidatedField.js +0 -53
  463. package/dist/validated.js +0 -21
package/README.md CHANGED
@@ -10,17 +10,17 @@ Published artifacts are **`dist/`** (ESM JavaScript, `.d.ts`, the two stylesheet
10
10
 
11
11
  ### Styles
12
12
 
13
- - **Global stylesheet** — import `bitboss-ui/styles.css` once. It bundles design tokens, base rules, and styles for all exported components (built from the library’s PostCSS/Tailwind pipeline).
13
+ - **Global stylesheet** — `bitboss-ui/styles.css`, injected for you by the runtime plugin (`injectStyles`, on by default); import it by hand only with `injectStyles: false`. It bundles design tokens, base rules, and styles for all exported components (built from the library’s PostCSS/Tailwind pipeline).
14
14
  - **Optional reset** — `bitboss-ui/reset.css`, only if your app has no reset of its own. Import it _before_ `styles.css` (or let the build plugin inject it with `resetCss: true`). A reset is a **prerequisite** of the components, not a nicety: their sizes are written for `border-box`, and native controls and fieldsets are expected to arrive without their browser chrome. Use this one, or your own — Tailwind's Preflight covers it, which is why `resetCss` defaults to off. The component test suite runs against this file.
15
15
  - **Cascade layers (opt-in)** — on Tailwind v4 the library must sit in your layer order or its unlayered rules outrank every utility you put on a component. `cssLayers: TAILWIND_V4_LAYERS` in the build plugin (both exported from `bitboss-ui/vite`) places it after Preflight and before the utilities. Details in `dist/ai/guides/installation-and-plugin-setup.md` § Cascade layers.
16
16
 
17
17
  ### TypeScript: use `vue-tsc` 3
18
18
 
19
19
  Use **`vue-tsc` 3 or newer**. Under `vue-tsc` 2 the template type-checker
20
- silently checks **nothing** about the props of the nine public components that
20
+ silently checks **nothing** about the props of the ten public components that
21
21
  use `<script setup generic="…">` — `BbSelect`, `BbSelectPopover`, `BbTable`,
22
22
  `BbTabs`, `BbTabsRoot`, `BbTree`, `BbRadioGroup`, `BbCheckboxGroup`,
23
- `BbSwitchGroup` —
23
+ `BbSwitchGroup`, and `BbForm` —
24
24
  because they emit as generic functions rather than `DefineComponent<…>`, a shape
25
25
  Vue Language Tools 2 cannot read props out of.
26
26
 
@@ -82,7 +82,8 @@ Product-ready components with labels, hints, errors, and consistent styling:
82
82
  - **Overlays & panels:** `BbDialog`, `BbConfirm`, `BbConfirmPortal`, `BbOffCanvas`, `BbPopover`
83
83
  - **Data:** `BbTable`, `BbTree`
84
84
  - **Media & files:** `BbAvatar`, `BbDropzone`, `BbIcon`
85
- - **Validated forms** (`bitboss-ui/validated`, needs `vee-validate`): `BbForm`, `useBbFormContext`, and validated twins of 16 form controls (same names, plus `rules` / `vid`; not yet `BbRadio` or the pickers without an input).
85
+ - **Forms** (`BbForm` needs the `vee-validate` peer; an app without forms needs nothing): `BbForm`, `useBbFormContext`, and the 16 form controls join the form they are inside (plus `rules` / `validation-label` / `validation-mode` / `formless`; the field's path is its `name`, else its label).
86
+ - **Schema validation, no adapter:** pass a Zod, Valibot, ArkType or Yup schema (any [Standard Schema](https://standardschema.dev)) to `BbForm`'s `schema` as it is. Messages land on the field by path (`address.city`, `lines.0.qty`), `@submit` receives the schema's parsed output typed from the schema, the required asterisk comes from the schema, and a failed submit focuses the first invalid field on screen. Per-step schemas plus `keep-values-on-unmount` cover multi-step wizards. No extra runtime dependency.
86
87
  - **Passthrough scopes:** `BbPtScope` + `definePt` — a named `pt` map applied to one area of the app.
87
88
 
88
89
  ### Passthrough (`pt`)
@@ -178,14 +179,15 @@ import { BbButton, BbTextInput, useToast } from 'bitboss-ui';
178
179
 
179
180
  ### Styles
180
181
 
181
- Bundled CSS is published under the `styles` export:
182
+ Bundled CSS is published under the `styles` export. **You do not import it**:
183
+ the runtime plugin injects it (`injectStyles`, on by default), into its cascade
184
+ layer when `cssLayers` is set. A hand import on top adds a second, unlayered
185
+ copy that outranks your Tailwind v4 utilities. Only with `injectStyles: false`:
182
186
 
183
187
  ```ts
184
188
  import 'bitboss-ui/styles.css';
185
189
  ```
186
190
 
187
- Use this once in your app entry (or in Nuxt/Vite global CSS) so components match the intended look and layout.
188
-
189
191
  ### Vite plugin
190
192
 
191
193
  Use the Vite export to enable icon virtual modules and typed registry integration:
@@ -193,13 +195,16 @@ Use the Vite export to enable icon virtual modules and typed registry integratio
193
195
  ```ts
194
196
  import { defineConfig } from 'vite';
195
197
  import vue from '@vitejs/plugin-vue';
196
- import { bitbossUi } from 'bitboss-ui/vite';
198
+ import { bitbossUi, TAILWIND_V4_LAYERS } from 'bitboss-ui/vite';
197
199
 
198
200
  export default defineConfig({
199
201
  plugins: [
200
202
  vue(),
201
203
  bitbossUi({
202
204
  iconDir: './src/assets/icons',
205
+ // Tailwind v4: keep this, or your utilities on Bb* components lose to
206
+ // the library's CSS. Tailwind v3 or plain CSS: drop it.
207
+ cssLayers: TAILWIND_V4_LAYERS,
203
208
  }),
204
209
  ],
205
210
  });
@@ -221,12 +226,14 @@ throws. Details: `dist/ai/guides/icons-policy.md` and
221
226
  ### Nuxt module
222
227
 
223
228
  ```ts
229
+ import { TAILWIND_V4_LAYERS } from 'bitboss-ui/vite';
230
+
224
231
  export default defineNuxtConfig({
225
232
  modules: ['bitboss-ui/nuxt'],
226
233
  bitboss: {
227
234
  iconDir: './assets/icons',
235
+ cssLayers: TAILWIND_V4_LAYERS, // Tailwind v4 only
228
236
  },
229
- css: ['bitboss-ui/styles.css'],
230
237
  });
231
238
  ```
232
239
 
@@ -459,6 +466,22 @@ entry is the state itself and is never reported:
459
466
  />
460
467
  ```
461
468
 
469
+ #### Nameless controls: `require-accessible-name`
470
+
471
+ `bitboss-ui/require-accessible-name` flags an icon-only `BbButton` with no
472
+ words (no default-slot content, no `text`, no `aria-label` / `aria-labelledby`
473
+ / `title`), an icon-only `BbBadge` with an empty default slot (its label), and
474
+ a `BbProgress` with no `label`: all three render with no accessible name. Put the words in the slot; with `icon` set they are visually hidden and
475
+ still name the button:
476
+
477
+ ```vue
478
+ <BbButton icon="lucide:trash">Elimina</BbButton>
479
+ <BbProgress label="Upload" :model-value="progress" />
480
+ ```
481
+
482
+ `BbSpinner` is not covered: without `label` it is decorative, which is correct.
483
+ For raw HTML controls, use `eslint-plugin-vuejs-accessibility`.
484
+
462
485
  #### Rating star colours: `no-star-color`
463
486
 
464
487
  `bitboss-ui/no-star-color` flags any colour utility in `BbRating`'s `pt:item`,
@@ -592,6 +592,65 @@ function nearestComponents(manifest, name, count = 3) {
592
592
  .map(({ name: found }) => found);
593
593
  }
594
594
 
595
+ /**
596
+ * A component whose props are generic over its ROW (`BbTableProps<Row>`,
597
+ * `BbSelectProps<Item>`): a prop type names the parameter `T`.
598
+ */
599
+ const isGeneric = (entry) =>
600
+ entry.props.some((p) =>
601
+ /(^|[^A-Za-z0-9_])T([^A-Za-z0-9_]|$)/.test(p.type ?? '')
602
+ );
603
+
604
+ const propsType = (entry) =>
605
+ `${entry.name}Props${isGeneric(entry) ? '<Row>' : ''}['pt']`;
606
+
607
+ /** `row: '…', 'row:selected': '…'` — the object form, from the real parts. */
608
+ function ptExample(entry) {
609
+ const names = entry.pt.parts.map((p) => p.name);
610
+ const part =
611
+ ['row', 'option', 'item', 'icon', 'label'].find((n) => names.includes(n)) ??
612
+ names[0];
613
+ // A state that is on for this part: per-node states name their parts.
614
+ const state = (
615
+ entry.pt.states?.find((s) =>
616
+ new RegExp(`\`${part}\``).test(s.description ?? '')
617
+ ) ??
618
+ entry.pt.states?.find((s) => /^Component-wide/.test(s.description ?? ''))
619
+ )?.name;
620
+ return `${part}: '…'${state ? `, '${part}:${state}': '…'` : ''}`;
621
+ }
622
+
623
+ const PT_TYPING_READ =
624
+ "get_guide({ name: 'passthrough.md', sections: ['Typing `pt` in `<script>`'] })";
625
+
626
+ function ptTyping(entry) {
627
+ // Both after-bench misses (2026-09-24) typed a table-agnostic preset
628
+ // `BbTableProps<any>['pt']`: say what to write when there is no row type.
629
+ const anyRow = isGeneric(entry)
630
+ ? ` (\`${entry.name}Props['pt']\` for a preset that fits any row type, never \`<any>\`)`
631
+ : '';
632
+ return `In <script> (a const, a preset, a wrapper's \`pt\` prop) type it as \`${propsType(entry)}\`${anyRow} with \`satisfies\` for a const; a split global map uses \`definePt\` from 'bitboss-ui/vite'. PtValue / PtMap are not exported. ${PT_TYPING_READ}`;
633
+ }
634
+
635
+ /**
636
+ * The next reads a component answer points at, each one call. Built from what
637
+ * the contract itself links, so it cannot name a guide the package lacks.
638
+ */
639
+ function seeAlso(entry, contract) {
640
+ const out = [];
641
+ // The option-list family links the items playbook; its wrapper section is
642
+ // where "write a MemberSelect around BbSelect" is answered (Q52.6.1).
643
+ if (/options-items-playbook\.md/.test(contract) && isGeneric(entry))
644
+ out.push(
645
+ `Your own ${entry.name} with fixed items (a CustomerSelect): a preset, one call to definePreset (a helper you copy from the guide, not a bitboss-ui export): get_guide({ name: 'preset-components.md' }). Wrapping BbSelect in your own component with its own logic: get_guide({ name: 'options-items-playbook.md', sections: ['Wrapping BbSelect in your own component'] })`
646
+ );
647
+ if (entry.validated)
648
+ out.push(
649
+ `Validation (rules or a Zod / Valibot / Yup schema): get_guide({ name: 'validated-forms.md' })`
650
+ );
651
+ return out;
652
+ }
653
+
595
654
  /** Guide sections of a contract: everything under `## Usage & Guidelines`. */
596
655
  function contractGuideSections(markdown) {
597
656
  const all = splitSections(markdown);
@@ -652,6 +711,8 @@ function getComponent({ name, sections, include, maxChars } = {}) {
652
711
  ...(type.values ? { values: type.values } : {}),
653
712
  ...(type.extensibleVia ? { extensibleVia: type.extensibleVia } : {}),
654
713
  ...(type.fields ? { fields: type.fields } : {}),
714
+ // A union of private members: each member's fields (Q51.21).
715
+ ...(type.members ? { members: type.members } : {}),
655
716
  import: `import type { ${type.replacedBy ?? name} } from 'bitboss-ui';`,
656
717
  hint: use
657
718
  ? `A type, not a component: it types ${possessive(use.component)} \`${use.name}\` ${use.surface}. \`definition\` above is the type itself; call get_component('${use.component}') to see it in use.`
@@ -736,9 +797,11 @@ function getComponent({ name, sections, include, maxChars } = {}) {
736
797
  ...(type.values ? { values: type.values } : {}),
737
798
  ...(type.extensibleVia ? { extensibleVia: type.extensibleVia } : {}),
738
799
  ...(type.fields ? { fields: type.fields } : {}),
800
+ // The union's shape, then what each private member takes (Q51.21).
739
801
  ...(!type.values && !type.fields && type.definition
740
802
  ? { definition: type.definition }
741
803
  : {}),
804
+ ...(type.members ? { members: type.members } : {}),
742
805
  }));
743
806
 
744
807
  const ptRows = entry.props.filter(
@@ -755,6 +818,9 @@ function getComponent({ name, sections, include, maxChars } = {}) {
755
818
  : {}),
756
819
  };
757
820
  if (!wanted.has('tree')) delete component.tree;
821
+ // The rendered `.bb-*` classes (Q46.5) are for tools (`check`, `validate`);
822
+ // an agent restyles through pt and the locals. include: ['css'] lists them.
823
+ if (!wanted.has('css')) delete component.css;
758
824
  // `removed` and `renamed` repeat each other with migration metadata; one
759
825
  // line per old name answers "what happened to X" (include 'history' for
760
826
  // the records the fixers use).
@@ -763,14 +829,28 @@ function getComponent({ name, sections, include, maxChars } = {}) {
763
829
  (entry.removed?.length || entry.renamed?.length)
764
830
  ) {
765
831
  const renamedFrom = new Set((entry.renamed ?? []).map((r) => r.from));
832
+ // A slot row reads as a slot (`#no-data → #empty`), a removal with no
833
+ // single successor carries its hint (Q51.16).
834
+ const spell = (r, name) => (r.surface === 'slot' ? `#${name}` : name);
835
+ // A rename that also maps VALUES says which: `inputDirection →
836
+ // listLayout` alone sent 2 of 3 answerers to `list-layout="vertical"`
837
+ // when the map is vertical → vertical-stretch (2026-09-24).
838
+ const values = (r) =>
839
+ Object.entries(r.fix?.valueMap ?? {})
840
+ .filter(([from, to]) => from !== to)
841
+ .map(([from, to]) => `"${from}" → "${to}"`)
842
+ .join(', ');
766
843
  component.history = [
767
844
  ...(entry.renamed ?? []).map(
768
845
  (r) =>
769
- `${r.from} → ${r.to}${r.fix?.kind && r.fix.kind !== 'rename' ? ` (${r.fix.kind})` : ''}`
846
+ `${spell(r, r.from)} → ${spell(r, r.to)}${r.fix?.kind && r.fix.kind !== 'rename' ? ` (${r.fix.kind})` : ''}${values(r) ? ` (values: ${values(r)})` : ''}`
770
847
  ),
771
848
  ...(entry.removed ?? [])
772
849
  .filter((r) => !renamedFrom.has(r.name))
773
- .map((r) => `${r.name} removed${r.new ? ` → ${r.new}` : ''}`),
850
+ .map(
851
+ (r) =>
852
+ `${spell(r, r.name)} removed${r.new ? ` → ${spell(r, r.new)}` : ''}${r.hint ? ` — ${r.hint}` : ''}`
853
+ ),
774
854
  ];
775
855
  delete component.removed;
776
856
  delete component.renamed;
@@ -795,9 +875,17 @@ function getComponent({ name, sections, include, maxChars } = {}) {
795
875
  ...(types.length > 0 ? { types } : {}),
796
876
  ...(ptRows.length && !wanted.has('ptProps')
797
877
  ? {
798
- ptProps: `${ptRows.length} pt:* props not listed: every \`pt:<part>\` and \`pt:<part>:<state>\` in \`component.pt\` is a prop taking a class string (or object / array), and \`pt\` takes the same keys as one object.`,
878
+ ptProps: `${ptRows.length} pt:* props not listed: every \`pt:<part>\` and \`pt:<part>:<state>\` in \`component.pt\` is a prop taking a class string (or object / array), and \`pt\` takes the same entries as one object keyed WITHOUT the \`pt:\` prefix: { ${ptExample(entry)} }.`,
799
879
  }
800
880
  : {}),
881
+ /*
882
+ * Where agents land when they type `pt` in <script> (Q52.7.1 receipts):
883
+ * 5 of 6 blind Haiku runs opened get_component first, never saw the
884
+ * passthrough guide's typing section, and hand-copied the part unions
885
+ * or invented a `PtValue`. The one that found the section scored 4/4.
886
+ */
887
+ ...(entry.pt?.parts?.length ? { ptTyping: ptTyping(entry) } : {}),
888
+ ...(seeAlso(entry, raw).length ? { seeAlso: seeAlso(entry, raw) } : {}),
801
889
  guide: {
802
890
  sections: guide
803
891
  .filter((s) => s.level === 3)
@@ -822,7 +910,7 @@ function getComponent({ name, sections, include, maxChars } = {}) {
822
910
  : {}),
823
911
  }
824
912
  : {}),
825
- hint: `Structured API above is complete. Read guide sections with get_component({ name: '${entry.name}', sections: ['<title from guide.sections>'] }); add include: ['tree' | 'cssProps' | 'ptProps' | 'history' | 'contract'] for the component tree, CSS variables with descriptions, every pt:* row, the full v2/beta rename records, or the whole contract. search_docs finds a topic across all docs.`,
913
+ hint: `Structured API above is complete. Read guide sections with get_component({ name: '${entry.name}', sections: ['<title from guide.sections>'] }); add include: ['tree' | 'cssProps' | 'css' | 'ptProps' | 'history' | 'contract'] for the component tree, CSS variables with descriptions, the .bb-* classes it renders, every pt:* row, the full v2/beta rename records, or the whole contract. search_docs finds a topic across all docs.`,
826
914
  };
827
915
  }
828
916
 
@@ -1024,11 +1112,19 @@ function listTokens({ filter } = {}) {
1024
1112
  tokens,
1025
1113
  hint:
1026
1114
  needle && tokens.length === 0
1027
- ? `No token name contains '${needle}'. Call list_tokens with no filter for all ${byName.size} — the names are semantic (primary/danger/panel/text/border/radius/…), not literal colours.`
1028
- : 'Theme tokens are set by the consumer app (e.g. on :root / .dark); `themeOverrides` is the dark-theme value. `localRebinds` is a component rebinding the token inside its own subtree — not something to copy. `conditional` is a value that applies only under an @supports condition (`when`) — e.g. an auto-contrast formula with literal fallbacks for older browsers; pinning a fallback literal defeats the formula. `kind` says what you may set: "knob" is yours; "derived" is a formula recomputed at every theme boundary, so setting it stops it tracking the knob it came from — set that knob instead; "knob-tracking" is a knob that follows another until you pin it, and the pin must be repeated at every boundary you use, .dark included. Component-level unprefixed tokens are documented per component; see the design-tokens guide via get_guide.',
1115
+ ? `No token name contains '${needle}'. Call list_tokens with no filter for all ${byName.size} — the names are semantic (primary/danger/panel/text/border/radius/…), not literal colours. ${FONT_NOTE}`
1116
+ : FONT_NOTE +
1117
+ ' Theme tokens are set by the consumer app (e.g. on :root / .dark); `themeOverrides` is the dark-theme value. `localRebinds` is a component rebinding the token inside its own subtree — not something to copy. `conditional` is a value that applies only under an @supports condition (`when`) — e.g. an auto-contrast formula with literal fallbacks for older browsers; pinning a fallback literal defeats the formula. `kind` says what you may set: "knob" is yours; "derived" is a formula recomputed at every theme boundary, so setting it stops it tracking the knob it came from — set that knob instead; "knob-tracking" is a knob that follows another until you pin it, and the pin must be repeated at every boundary you use, .dark included. Component-level unprefixed tokens are documented per component; see the design-tokens guide via get_guide.',
1029
1118
  };
1030
1119
  }
1031
1120
 
1121
+ /**
1122
+ * Q53.11: there is no font-family token, by ruling; agents kept looking for
1123
+ * one. Said in every list_tokens answer.
1124
+ */
1125
+ const FONT_NOTE =
1126
+ "Components have no font token; they inherit the page's `font-family`. Set it on `body` (or a `.bb-theme` island) to theme it.";
1127
+
1032
1128
  /** Every guide markdown path under dist/ai/guides, relative to that dir. */
1033
1129
  function collectGuidePaths(dir, prefix = '') {
1034
1130
  const out = [];
@@ -1251,6 +1347,43 @@ function docIndex() {
1251
1347
  read: { tool: 'get_component', args: { name: component.name } },
1252
1348
  });
1253
1349
  }
1350
+ /*
1351
+ * The rename registry: an agent upgrading an app searches the OLD name
1352
+ * (`enabled-while-loading`, `pt:input`, `#no-data`), which no current
1353
+ * section spells. One entry per row, with the name written every way a
1354
+ * query may (camel, kebab, split words), read = its migration guide.
1355
+ */
1356
+ for (const row of component.removed ?? []) {
1357
+ const spell = (name) => (row.surface === 'slot' ? `#${name}` : name);
1358
+ const ways = (name) =>
1359
+ [
1360
+ ...new Set([
1361
+ name,
1362
+ name.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`),
1363
+ name.replace(/([a-z0-9])([A-Z])/g, '$1 $2').toLowerCase(),
1364
+ ]),
1365
+ ].join(' / ');
1366
+ const kind = row.surface ?? 'prop';
1367
+ const guide = row.migration?.replace(/^ai\/guides\//, '');
1368
+ entries.push({
1369
+ source: `component ${component.name}`,
1370
+ section: `${row.new ? 'renamed' : 'removed'} ${kind} ${spell(row.name)}`,
1371
+ text:
1372
+ `${kind} ${ways(spell(row.name))} ` +
1373
+ (row.new
1374
+ ? `was renamed to ${ways(spell(row.new))} on ${component.name}`
1375
+ : `was removed from ${component.name}`) +
1376
+ `${row.since && !/unreleased/.test(row.since) ? ` in ${row.since}` : ''}.` +
1377
+ Object.entries(row.fix?.valueMap ?? {})
1378
+ .filter(([from, to]) => from !== to)
1379
+ .map(([from, to]) => ` The value "${from}" becomes "${to}".`)
1380
+ .join('') +
1381
+ `${row.hint ? ` ${row.hint}.` : ''} \`bitboss-ui check --fix\` rewrites a rename.`,
1382
+ read: guide
1383
+ ? { tool: 'get_guide', args: { name: guide } }
1384
+ : { tool: 'get_component', args: { name: component.name } },
1385
+ });
1386
+ }
1254
1387
  }
1255
1388
  for (const platform of RECIPE_PLATFORMS) {
1256
1389
  const dir = join(AI_ROOT, 'recipes', platform);
@@ -1266,6 +1399,94 @@ function docIndex() {
1266
1399
  });
1267
1400
  }
1268
1401
  }
1402
+ // Class renames (the sweep map rows of changelog.json): an app's
1403
+ // stylesheet names the OLD class, so the old class must find the new one.
1404
+ if (existsSync(CHANGELOG_PATH)) {
1405
+ const changelog = JSON.parse(readFileSync(CHANGELOG_PATH, 'utf-8'));
1406
+ for (const row of changelog.breaking ?? []) {
1407
+ if (row.surface !== 'class' || !String(row.id).startsWith('css:'))
1408
+ continue;
1409
+ entries.push({
1410
+ source: `class ${row.components?.[0] ?? ''}`.trim(),
1411
+ section: `renamed class ${row.from}`,
1412
+ text:
1413
+ `class ${row.from} was renamed to ${row.to}` +
1414
+ `${row.firstReleasedIn ? ` in ${row.firstReleasedIn}` : ''}` +
1415
+ (row.from.includes('--')
1416
+ ? '.'
1417
+ : `; its modifiers follow (${row.from}--x → ${row.to}--x).`) +
1418
+ `${row.note ? ` ${row.note}.` : ''}`,
1419
+ read: {
1420
+ tool: 'get_guide',
1421
+ args: { name: 'migration/v3-beta-css-classes.md' },
1422
+ },
1423
+ });
1424
+ }
1425
+ /*
1426
+ * Every other break, with the release that first shipped it. "In which
1427
+ * version did the activator scope lose `isOpen`?" had no search path: the
1428
+ * answer (f202, firstReleasedIn 3.0.0-beta.35) lived only in
1429
+ * list_changes, which 1 answerer in 12 called (ai-docs access push,
1430
+ * 2026-09-24). Prop / pt / slot renames are already indexed from the
1431
+ * components' registry rows above, so only the rest comes in here.
1432
+ */
1433
+ const releases = changelog.releases ?? [];
1434
+ for (const row of changelog.breaking ?? []) {
1435
+ if (row.surface === 'class') continue;
1436
+ if (row.kind === 'rename' && ['prop', 'pt', 'slot'].includes(row.surface))
1437
+ continue;
1438
+ const what =
1439
+ row.kind === 'rename'
1440
+ ? `${row.surface ?? ''} ${row.from} → ${row.to ?? '(removed)'}`.trim()
1441
+ : String(row.description ?? '');
1442
+ if (!what) continue;
1443
+ const at = row.firstReleasedIn;
1444
+ const before = at
1445
+ ? releases.filter((r) => compareVersions(r, at) < 0).at(-1)
1446
+ : releases.at(-1);
1447
+ entries.push({
1448
+ source: `change ${row.id}`,
1449
+ section: `breaking change: ${what.length > 90 ? `${what.slice(0, 90)}…` : what}`,
1450
+ text:
1451
+ `${what}${row.note ? ` (${row.note})` : ''}. ` +
1452
+ (at
1453
+ ? `First released in ${at}.`
1454
+ : 'Not released yet: it ships in the next release.') +
1455
+ `${row.guide ? ` Migration: ${row.guide}.` : ''}`,
1456
+ read: {
1457
+ tool: 'list_changes',
1458
+ args: before ? { since: before, ...(at ? { until: at } : {}) } : {},
1459
+ },
1460
+ });
1461
+ }
1462
+ }
1463
+ /*
1464
+ * The public types an app builds values with (`api` tier: BbTreeItem,
1465
+ * BbTableColumn, ButtonVariantType). "What shape must each BbTree item
1466
+ * have?" matched only the prop row `items: BbTreeItem<Meta>[]`, never the
1467
+ * type's fields, so 2 of 3 answerers guessed `{ label, children }`.
1468
+ */
1469
+ for (const type of manifest.types ?? []) {
1470
+ if (type.usage !== 'api' || type.deprecated) continue;
1471
+ const use = (type.usedBy ?? [])
1472
+ .map((u) => `${u.component} ${u.name} ${u.surface}`)
1473
+ .join(', ');
1474
+ entries.push({
1475
+ source: `type ${type.name}`,
1476
+ section: `type ${type.name}${use ? ` (${use})` : ''}`,
1477
+ // The words questions use ("shape", "fields", "values") are spelled
1478
+ // out: the declaration alone never says them.
1479
+ text:
1480
+ `${type.name}${use ? `, the type of ${use}` : ''}: ` +
1481
+ (type.values
1482
+ ? `accepted values ${type.values.join(' | ')}`
1483
+ : type.fields
1484
+ ? `object shape, fields ${type.fields.join('; ')}`
1485
+ : String(type.definition ?? '')) +
1486
+ `. import type { ${type.name} } from 'bitboss-ui'.`,
1487
+ read: { tool: 'get_component', args: { name: type.name } },
1488
+ });
1489
+ }
1269
1490
  const readme = join(PACKAGE_ROOT, 'README.md');
1270
1491
  if (existsSync(readme)) {
1271
1492
  addSections('README', readFileSync(readme, 'utf-8'), () => ({
@@ -1309,10 +1530,21 @@ function getComposable({ name } = {}) {
1309
1530
  available: files.map((f) => f.slice(0, -3)),
1310
1531
  };
1311
1532
  }
1533
+ const markdown = readFileSync(join(dir, file), 'utf-8');
1534
+ /*
1535
+ * A composable that needs a host component says so FIRST, as a field: with
1536
+ * no `<BbConfirm />`, `await confirm()` never settles. Every blind answerer
1537
+ * of "await an Are-you-sure dialog" (4 of 4, 2026-09-24) left the host out,
1538
+ * although the doc's second paragraph states it.
1539
+ */
1540
+ const host = frontmatter(markdown).summary?.match(
1541
+ /Requires (exactly one <Bb\w+ \/> host[^.]*)\./
1542
+ )?.[1];
1312
1543
  return {
1313
1544
  found: true,
1314
1545
  name: file.slice(0, -3),
1315
- content: stripFrontmatter(readFileSync(join(dir, file), 'utf-8')),
1546
+ ...(host ? { requires: host } : {}),
1547
+ content: stripFrontmatter(markdown),
1316
1548
  };
1317
1549
  }
1318
1550
 
@@ -1422,8 +1654,17 @@ function getRecipe({ platform, name, sections, maxChars } = {}) {
1422
1654
  /** `validate({ code })` — Phase 2 validator core over a Vue snippet. */
1423
1655
  function validateCode({ code } = {}) {
1424
1656
  const manifest = getManifestMap();
1425
- const { findings } = validateVueSnippet(String(code ?? ''), manifest);
1426
- return { ok: findings.length === 0, findings };
1657
+ const { findings: all } = validateVueSnippet(String(code ?? ''), manifest);
1658
+ // `severity: 'warning'` findings (a slot spelled the pre-reset way, Q53.15
1659
+ // C9b) are reported apart and never make the snippet invalid — the same
1660
+ // split `bitboss-ui check` prints.
1661
+ const findings = all.filter((f) => f.severity !== 'warning');
1662
+ const warnings = all.filter((f) => f.severity === 'warning');
1663
+ return {
1664
+ ok: findings.length === 0,
1665
+ findings,
1666
+ ...(warnings.length ? { warnings } : {}),
1667
+ };
1427
1668
  }
1428
1669
 
1429
1670
  /**
@@ -1470,6 +1711,53 @@ function compareVersions(a, b) {
1470
1711
  * halves are fixed: rows are stamped with `firstReleasedIn` at build time, and
1471
1712
  * this serves the slice.
1472
1713
  */
1714
+ /*
1715
+ * The answer's rows, compact (owner rule: compact by default): empty fields,
1716
+ * `ruling` and `since` dropped, and the class renames (85 one-to-one pairs from the sweep map,
1717
+ * Q51.19) folded into ONE `{ ".old": ".new" }` map — complete, and a tenth of
1718
+ * the size of 85 row objects. Everything else stays a full row.
1719
+ */
1720
+ function compactChanges(rows) {
1721
+ const classRenames = {};
1722
+ const breaking = [];
1723
+ for (const row of rows) {
1724
+ if (row.surface === 'class' && String(row.id).startsWith('css:')) {
1725
+ classRenames[row.from] = row.to;
1726
+ continue;
1727
+ }
1728
+ // `ruling` is the library's internal decision id and `since` the
1729
+ // register's authoring-date note (firstReleasedIn is the release): both
1730
+ // stay in changelog.json, neither helps an upgrade.
1731
+ breaking.push(
1732
+ Object.fromEntries(
1733
+ Object.entries(row).filter(
1734
+ ([key, value]) =>
1735
+ key !== 'ruling' &&
1736
+ key !== 'since' &&
1737
+ value !== '' &&
1738
+ value !== undefined &&
1739
+ !(Array.isArray(value) && value.length === 0)
1740
+ )
1741
+ )
1742
+ );
1743
+ }
1744
+ return Object.keys(classRenames).length
1745
+ ? {
1746
+ breaking,
1747
+ classRenames,
1748
+ classRenamesNote:
1749
+ 'class renames from the beta.36 sweep map: modifiers follow (.old--x → .new--x); ai/guides/migration/v3-beta-css-classes.md',
1750
+ }
1751
+ : { breaking };
1752
+ }
1753
+
1754
+ /*
1755
+ * Rows carry `kind` AND `surface`; 2 of 3 answerers told a script to switch on
1756
+ * `kind` to tell a class rename from a prop rename (2026-09-24).
1757
+ */
1758
+ const ROW_FIELDS =
1759
+ '`surface` says what a rename names (prop | slot | pt | cssVar | class | option); `kind` is only rename vs behaviour; `firstReleasedIn` is the first npm release with the change.';
1760
+
1473
1761
  function listChanges({ since: rawSince, until: rawUntil } = {}) {
1474
1762
  // The repo's own tags are spelled `v3.0.0-beta.33` (review D6-12).
1475
1763
  const since =
@@ -1492,6 +1780,16 @@ function listChanges({ since: rawSince, until: rawUntil } = {}) {
1492
1780
  ['until', until],
1493
1781
  ]) {
1494
1782
  if (value != null && !known.has(String(value))) {
1783
+ if ((doc.unpublished ?? []).includes(String(value))) {
1784
+ const next = releases.find(
1785
+ (r) => compareVersions(r, String(value)) > 0
1786
+ );
1787
+ return {
1788
+ error: `${value} was never published to npm; its changes shipped in ${next ?? 'the next release'}.`,
1789
+ knownReleases: releases,
1790
+ hint: `Pass the version you installed from npm (for example the one before it, since=${releases.filter((r) => compareVersions(r, String(value)) < 0).at(-1) ?? '…'}).`,
1791
+ };
1792
+ }
1495
1793
  return {
1496
1794
  error: `Unknown ${label} version '${value}'.`,
1497
1795
  knownReleases: releases,
@@ -1511,8 +1809,8 @@ function listChanges({ since: rawSince, until: rawUntil } = {}) {
1511
1809
  releases,
1512
1810
  summary: doc.summary,
1513
1811
  count: all.length,
1514
- breaking: all,
1515
- hint: 'Narrow to one upgrade hop with list_changes({ since: "<your current version>" }) — that answers "what breaks if I bump".',
1812
+ ...compactChanges(all),
1813
+ hint: `Narrow to one upgrade hop with list_changes({ since: "<your current version>" }) — that answers "what breaks if I bump". ${ROW_FIELDS}`,
1516
1814
  };
1517
1815
  }
1518
1816
 
@@ -1531,12 +1829,12 @@ function listChanges({ since: rawSince, until: rawUntil } = {}) {
1531
1829
  since: since ?? null,
1532
1830
  until: until ?? doc.version,
1533
1831
  count: inRange.length,
1534
- breaking: inRange,
1832
+ ...compactChanges(inRange),
1535
1833
  guide: doc.guide,
1536
1834
  hint:
1537
1835
  inRange.length === 0
1538
1836
  ? 'No breaking changes recorded in that range — features and fixes are deliberately not tracked here, so an empty result means nothing BREAKS, not that nothing changed.'
1539
- : 'Each entry names the component and the new spelling; `guide` is the migration page with the full explanation.',
1837
+ : `Each entry names the component and the new spelling; \`guide\` is the migration page with the full explanation. ${ROW_FIELDS}`,
1540
1838
  };
1541
1839
  }
1542
1840
 
@@ -1567,12 +1865,14 @@ const platformSchema = z.enum(RECIPE_PLATFORMS);
1567
1865
  */
1568
1866
  const SERVER_INSTRUCTIONS = [
1569
1867
  'bitboss-ui: a Vue 3 component library. Answer from these tools, never from memory — agents that guess invent props.',
1868
+ "- Tailwind v4 app: set cssLayers: TAILWIND_V4_LAYERS ('bitboss-ui/vite') at setup, or utilities lose.",
1570
1869
  '- A topic or "how do I…" question (dark mode, cascade layers, SSR, a plugin option, a CLI command): search_docs, then open the section it points to.',
1571
1870
  '- Which component: search_components (empty query = the whole catalog). One component: get_component({ name }) — compact; pass sections for guide prose, include for more.',
1572
1871
  '- A type in a props table (BbTableColumn, ButtonVariantType): get_component({ name }) returns its definition and values.',
1573
- '- After writing markup: validate. Before custom CSS: list_tokens. Before bumping the version: list_changes({ since }).',
1574
- '- Composables (useToast, useConfirm…): get_composable. Whole pages: list_recipes, get_recipe.',
1575
- '- Long guides answer with an outline: pass sections.',
1872
+ '- After writing markup: validate. Before custom CSS: list_tokens.',
1873
+ '- An old name (v2 or earlier-beta prop, slot, pt key, class) that stopped working: search_docs(the old name). Which release changed something, or what a bump breaks: list_changes({ since }), each row has firstReleasedIn.',
1874
+ "- pt in <script> (a const, a wrapper's prop): type it <Name>Props['pt']; Pt* types are not exported.",
1875
+ '- Composables (useToast, useConfirm…): get_composable. Whole pages: list_recipes, get_recipe. Long guides answer with an outline: pass sections.',
1576
1876
  ].join('\n');
1577
1877
 
1578
1878
  /** Register the knowledge-base tools on a fresh McpServer instance. */
@@ -1626,10 +1926,19 @@ function buildServer() {
1626
1926
  "Guide sections to return whole, by title from `guide.sections`, e.g. ['Toggle buttons']. Case-insensitive; a partial title matches."
1627
1927
  ),
1628
1928
  include: z
1629
- .array(z.enum(['tree', 'cssProps', 'ptProps', 'history', 'contract']))
1929
+ .array(
1930
+ z.enum([
1931
+ 'tree',
1932
+ 'cssProps',
1933
+ 'css',
1934
+ 'ptProps',
1935
+ 'history',
1936
+ 'contract',
1937
+ ])
1938
+ )
1630
1939
  .optional()
1631
1940
  .describe(
1632
- 'Extra parts: tree = the component tree, cssProps = CSS variables with descriptions, ptProps = every pt:* prop row, history = full v2/beta rename records, contract = the whole contract markdown.'
1941
+ 'Extra parts: tree = the component tree, cssProps = CSS variables with descriptions, css = the .bb-* classes it renders (by block; for a selector you must write), ptProps = every pt:* prop row, history = full v2/beta rename records, contract = the whole contract markdown.'
1633
1942
  ),
1634
1943
  maxChars: z
1635
1944
  .number()
@@ -1803,7 +2112,7 @@ function buildServer() {
1803
2112
  'validate',
1804
2113
  {
1805
2114
  description:
1806
- 'Validate a Vue template/SFC snippet against the installed components.json manifest: reports unknown Bb* props, unknown v-models, and removed/renamed props. Run this after writing bitboss-ui markup.',
2115
+ 'Validate a Vue template/SFC snippet against the installed components.json manifest: reports unknown Bb* props, unknown v-models, removed/renamed props, and imports that are not public (a file inside bitboss-ui/dist, a Pt* type). Run this after writing bitboss-ui markup.',
1807
2116
  inputSchema: {
1808
2117
  code: z
1809
2118
  .string()