@viglet/viglet-design-system 2026.3.10 → 2026.3.12

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 (235) hide show
  1. package/README.md +323 -36
  2. package/consumers.json +186 -0
  3. package/dist/badge-locale-1_BmNTro.cjs +1 -0
  4. package/dist/badge-locale-Bx7m7tg2.js +501 -0
  5. package/dist/bento/bento-actions-menu.d.ts +8 -0
  6. package/dist/bento/bento-actions-menu.d.ts.map +1 -1
  7. package/dist/bento/bento-back-to-top.d.ts +9 -1
  8. package/dist/bento/bento-back-to-top.d.ts.map +1 -1
  9. package/dist/bento/bento-command-palette.d.ts +12 -0
  10. package/dist/bento/bento-command-palette.d.ts.map +1 -1
  11. package/dist/bento/bento-data-table.d.ts +81 -0
  12. package/dist/bento/bento-data-table.d.ts.map +1 -0
  13. package/dist/bento/bento-diff.d.ts +41 -0
  14. package/dist/bento/bento-diff.d.ts.map +1 -0
  15. package/dist/bento/bento-empty-state.d.ts +8 -1
  16. package/dist/bento/bento-empty-state.d.ts.map +1 -1
  17. package/dist/bento/bento-entity-shell.d.ts.map +1 -1
  18. package/dist/bento/bento-filter-bar.d.ts +60 -0
  19. package/dist/bento/bento-filter-bar.d.ts.map +1 -0
  20. package/dist/bento/bento-form-section.d.ts +10 -3
  21. package/dist/bento/bento-form-section.d.ts.map +1 -1
  22. package/dist/bento/bento-inline-edit.d.ts.map +1 -1
  23. package/dist/bento/bento-nav-rail.d.ts +13 -13
  24. package/dist/bento/bento-nav-rail.d.ts.map +1 -1
  25. package/dist/bento/bento-palette-trigger.d.ts +18 -0
  26. package/dist/bento/bento-palette-trigger.d.ts.map +1 -0
  27. package/dist/bento/bento-section-chrome.d.ts +17 -42
  28. package/dist/bento/bento-section-chrome.d.ts.map +1 -1
  29. package/dist/bento/bento-shell-shortcuts.d.ts +67 -0
  30. package/dist/bento/bento-shell-shortcuts.d.ts.map +1 -0
  31. package/dist/bento/bento-shell.d.ts +53 -0
  32. package/dist/bento/bento-shell.d.ts.map +1 -0
  33. package/dist/bento/bento-shortcuts-dialog.d.ts +9 -7
  34. package/dist/bento/bento-shortcuts-dialog.d.ts.map +1 -1
  35. package/dist/bento/bento-status-marker.d.ts +5 -2
  36. package/dist/bento/bento-status-marker.d.ts.map +1 -1
  37. package/dist/bento/bento-user-menu.d.ts +9 -8
  38. package/dist/bento/bento-user-menu.d.ts.map +1 -1
  39. package/dist/bento/bento-version-rail.d.ts +31 -0
  40. package/dist/bento/bento-version-rail.d.ts.map +1 -0
  41. package/dist/bento/index.d.ts +14 -5
  42. package/dist/bento/index.d.ts.map +1 -1
  43. package/dist/bento.cjs +5 -1
  44. package/dist/bento.css +70 -4
  45. package/dist/bento.es.js +1642 -625
  46. package/dist/catalogue.json +5349 -0
  47. package/dist/components/app-footer.d.ts +7 -0
  48. package/dist/components/app-footer.d.ts.map +1 -1
  49. package/dist/components/backend-status.d.ts +19 -11
  50. package/dist/components/backend-status.d.ts.map +1 -1
  51. package/dist/components/badge-colorful.d.ts +4 -0
  52. package/dist/components/badge-colorful.d.ts.map +1 -1
  53. package/dist/components/badge-locale.d.ts +7 -0
  54. package/dist/components/badge-locale.d.ts.map +1 -1
  55. package/dist/components/error-boundary.d.ts +15 -13
  56. package/dist/components/error-boundary.d.ts.map +1 -1
  57. package/dist/components/language-select.d.ts +8 -0
  58. package/dist/components/language-select.d.ts.map +1 -1
  59. package/dist/components/login/login.d.ts +27 -0
  60. package/dist/components/login/login.d.ts.map +1 -1
  61. package/dist/components/mode-toggle.d.ts +9 -0
  62. package/dist/components/mode-toggle.d.ts.map +1 -1
  63. package/dist/components/nav-secondary.d.ts +7 -0
  64. package/dist/components/nav-secondary.d.ts.map +1 -1
  65. package/dist/components/router/dialog.delete.d.ts +8 -0
  66. package/dist/components/router/dialog.delete.d.ts.map +1 -1
  67. package/dist/components/router/gradient-button-link.d.ts +6 -0
  68. package/dist/components/router/gradient-button-link.d.ts.map +1 -1
  69. package/dist/components/router/index.d.ts +0 -11
  70. package/dist/components/router/index.d.ts.map +1 -1
  71. package/dist/components/router/loading-provider.d.ts +4 -0
  72. package/dist/components/router/loading-provider.d.ts.map +1 -1
  73. package/dist/components/startup-first/startup-first.d.ts +29 -0
  74. package/dist/components/startup-first/startup-first.d.ts.map +1 -1
  75. package/dist/components/ui/accordion.d.ts +17 -0
  76. package/dist/components/ui/accordion.d.ts.map +1 -1
  77. package/dist/components/ui/avatar.d.ts +14 -0
  78. package/dist/components/ui/avatar.d.ts.map +1 -1
  79. package/dist/components/ui/badge.d.ts +6 -0
  80. package/dist/components/ui/badge.d.ts.map +1 -1
  81. package/dist/components/ui/breadcrumb.d.ts +25 -0
  82. package/dist/components/ui/breadcrumb.d.ts.map +1 -1
  83. package/dist/components/ui/button.d.ts +15 -1
  84. package/dist/components/ui/button.d.ts.map +1 -1
  85. package/dist/components/ui/card.d.ts +27 -0
  86. package/dist/components/ui/card.d.ts.map +1 -1
  87. package/dist/components/ui/checkbox.d.ts +4 -0
  88. package/dist/components/ui/checkbox.d.ts.map +1 -1
  89. package/dist/components/ui/dialog.d.ts +36 -0
  90. package/dist/components/ui/dialog.d.ts.map +1 -1
  91. package/dist/components/ui/drawer.d.ts +35 -0
  92. package/dist/components/ui/drawer.d.ts.map +1 -1
  93. package/dist/components/ui/dropdown-menu.d.ts +53 -0
  94. package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
  95. package/dist/components/ui/floating-formulas-bg.d.ts +8 -0
  96. package/dist/components/ui/floating-formulas-bg.d.ts.map +1 -1
  97. package/dist/components/ui/form-actions.d.ts +7 -0
  98. package/dist/components/ui/form-actions.d.ts.map +1 -1
  99. package/dist/components/ui/form-item-two-columns.d.ts +7 -0
  100. package/dist/components/ui/form-item-two-columns.d.ts.map +1 -1
  101. package/dist/components/ui/form.d.ts +26 -1
  102. package/dist/components/ui/form.d.ts.map +1 -1
  103. package/dist/components/ui/glass-card.d.ts +13 -14
  104. package/dist/components/ui/glass-card.d.ts.map +1 -1
  105. package/dist/components/ui/gradient-button.d.ts +15 -1
  106. package/dist/components/ui/gradient-button.d.ts.map +1 -1
  107. package/dist/components/ui/gradient-switch.d.ts +6 -0
  108. package/dist/components/ui/gradient-switch.d.ts.map +1 -1
  109. package/dist/components/ui/hover-card.d.ts +14 -0
  110. package/dist/components/ui/hover-card.d.ts.map +1 -1
  111. package/dist/components/ui/index.d.ts +2 -1
  112. package/dist/components/ui/index.d.ts.map +1 -1
  113. package/dist/components/ui/input.d.ts +6 -0
  114. package/dist/components/ui/input.d.ts.map +1 -1
  115. package/dist/components/ui/label.d.ts +4 -0
  116. package/dist/components/ui/label.d.ts.map +1 -1
  117. package/dist/components/ui/navigation-menu.d.ts +29 -2
  118. package/dist/components/ui/navigation-menu.d.ts.map +1 -1
  119. package/dist/components/ui/pagination.d.ts +25 -0
  120. package/dist/components/ui/pagination.d.ts.map +1 -1
  121. package/dist/components/ui/popover.d.ts +24 -0
  122. package/dist/components/ui/popover.d.ts.map +1 -1
  123. package/dist/components/ui/progress.d.ts +4 -0
  124. package/dist/components/ui/progress.d.ts.map +1 -1
  125. package/dist/components/ui/pulse-ring.d.ts +9 -11
  126. package/dist/components/ui/pulse-ring.d.ts.map +1 -1
  127. package/dist/components/ui/resizable.d.ts +11 -0
  128. package/dist/components/ui/resizable.d.ts.map +1 -1
  129. package/dist/components/ui/section-card.d.ts +9 -0
  130. package/dist/components/ui/section-card.d.ts.map +1 -1
  131. package/dist/components/ui/select.d.ts +36 -0
  132. package/dist/components/ui/select.d.ts.map +1 -1
  133. package/dist/components/ui/separator.d.ts +4 -0
  134. package/dist/components/ui/separator.d.ts.map +1 -1
  135. package/dist/components/ui/sheet.d.ts +29 -0
  136. package/dist/components/ui/sheet.d.ts.map +1 -1
  137. package/dist/components/ui/sidebar.d.ts +83 -0
  138. package/dist/components/ui/sidebar.d.ts.map +1 -1
  139. package/dist/components/ui/skeleton.d.ts +4 -0
  140. package/dist/components/ui/skeleton.d.ts.map +1 -1
  141. package/dist/components/ui/slider.d.ts +4 -0
  142. package/dist/components/ui/slider.d.ts.map +1 -1
  143. package/dist/components/ui/sonner.d.ts +6 -2
  144. package/dist/components/ui/sonner.d.ts.map +1 -1
  145. package/dist/components/ui/stepper.d.ts +8 -0
  146. package/dist/components/ui/stepper.d.ts.map +1 -1
  147. package/dist/components/ui/sticky-save-bar.d.ts +7 -0
  148. package/dist/components/ui/sticky-save-bar.d.ts.map +1 -1
  149. package/dist/components/ui/switch.d.ts +4 -0
  150. package/dist/components/ui/switch.d.ts.map +1 -1
  151. package/dist/components/ui/table.d.ts +31 -0
  152. package/dist/components/ui/table.d.ts.map +1 -1
  153. package/dist/components/ui/tabs.d.ts +16 -0
  154. package/dist/components/ui/tabs.d.ts.map +1 -1
  155. package/dist/components/ui/textarea.d.ts +4 -0
  156. package/dist/components/ui/textarea.d.ts.map +1 -1
  157. package/dist/components/ui/toggle-group.d.ts +7 -0
  158. package/dist/components/ui/toggle-group.d.ts.map +1 -1
  159. package/dist/components/ui/toggle.d.ts +4 -0
  160. package/dist/components/ui/toggle.d.ts.map +1 -1
  161. package/dist/components/ui/tooltip.d.ts +18 -0
  162. package/dist/components/ui/tooltip.d.ts.map +1 -1
  163. package/dist/components/ui/tree.d.ts +60 -0
  164. package/dist/components/ui/tree.d.ts.map +1 -0
  165. package/dist/components/ui/user-avatar.d.ts +2 -1
  166. package/dist/components/ui/user-avatar.d.ts.map +1 -1
  167. package/dist/components/ui/viglet-assistant.d.ts +71 -28
  168. package/dist/components/ui/viglet-assistant.d.ts.map +1 -1
  169. package/dist/components/ui/viglet-avatar.d.ts +14 -12
  170. package/dist/components/ui/viglet-avatar.d.ts.map +1 -1
  171. package/dist/contexts/breadcrumb.context.d.ts +7 -0
  172. package/dist/contexts/breadcrumb.context.d.ts.map +1 -1
  173. package/dist/contexts/user.context.d.ts +8 -0
  174. package/dist/contexts/user.context.d.ts.map +1 -1
  175. package/dist/exports.json +344 -28
  176. package/dist/i18n/index.d.ts +94 -0
  177. package/dist/i18n/index.d.ts.map +1 -1
  178. package/dist/i18n/locales/en/assistant.json.d.ts +4 -1
  179. package/dist/i18n/locales/en/bento.json.d.ts +45 -1
  180. package/dist/i18n/locales/pt/assistant.json.d.ts +4 -1
  181. package/dist/i18n/locales/pt/bento.json.d.ts +45 -1
  182. package/dist/i18n.cjs +1 -1
  183. package/dist/i18n.es.js +98 -4
  184. package/dist/index.cjs +1 -1
  185. package/dist/index.es.js +2094 -913
  186. package/dist/lib/busy.d.ts +26 -0
  187. package/dist/lib/busy.d.ts.map +1 -0
  188. package/dist/lib/corner-slot.d.ts +15 -0
  189. package/dist/lib/corner-slot.d.ts.map +1 -0
  190. package/dist/{loading-provider-E3fbcekM.js → loading-provider-D-_5G-08.js} +71 -69
  191. package/dist/loading-provider-E4tIG9BM.cjs +1 -0
  192. package/dist/preset.css +7 -10
  193. package/dist/router.cjs +1 -1
  194. package/dist/router.es.js +2 -776
  195. package/dist/user.context-BXQ7lgg5.js +815 -0
  196. package/dist/user.context-D01CI8gq.cjs +1 -0
  197. package/dist/viglet-design-system.css +1 -1
  198. package/docs/BENTO-AUTHORING.md +61 -9
  199. package/package.json +13 -2
  200. package/scripts/consumer-entries.mjs +209 -0
  201. package/scripts/lib/contrast.mjs +301 -0
  202. package/scripts/mcp.mjs +300 -0
  203. package/scripts/page-lint.mjs +428 -0
  204. package/scripts/page-reference.mjs +54 -10
  205. package/dist/badge-locale-Bij94NwL.cjs +0 -1
  206. package/dist/badge-locale-Du41PpLA.js +0 -533
  207. package/dist/breadcrumb.context-BssgEydx.js +0 -926
  208. package/dist/breadcrumb.context-DLsiMS59.cjs +0 -1
  209. package/dist/components/router/blank-slate.d.ts +0 -21
  210. package/dist/components/router/blank-slate.d.ts.map +0 -1
  211. package/dist/components/router/grid.list.d.ts +0 -39
  212. package/dist/components/router/grid.list.d.ts.map +0 -1
  213. package/dist/components/router/internal.sidebar.d.ts +0 -61
  214. package/dist/components/router/internal.sidebar.d.ts.map +0 -1
  215. package/dist/components/router/nav-main.d.ts +0 -25
  216. package/dist/components/router/nav-main.d.ts.map +0 -1
  217. package/dist/components/router/nav-user.d.ts +0 -24
  218. package/dist/components/router/nav-user.d.ts.map +0 -1
  219. package/dist/components/router/page-content.d.ts +0 -12
  220. package/dist/components/router/page-content.d.ts.map +0 -1
  221. package/dist/components/router/page-header.d.ts +0 -23
  222. package/dist/components/router/page-header.d.ts.map +0 -1
  223. package/dist/components/router/page.d.ts +0 -22
  224. package/dist/components/router/page.d.ts.map +0 -1
  225. package/dist/components/router/sticky.page.header.d.ts +0 -85
  226. package/dist/components/router/sticky.page.header.d.ts.map +0 -1
  227. package/dist/components/router/sub.page.d.ts +0 -50
  228. package/dist/components/router/sub.page.d.ts.map +0 -1
  229. package/dist/components/router/sub.page.header.d.ts +0 -37
  230. package/dist/components/router/sub.page.header.d.ts.map +0 -1
  231. package/dist/lib/react-markers.d.ts +0 -17
  232. package/dist/lib/react-markers.d.ts.map +0 -1
  233. package/dist/loading-provider-B6-R2ONB.cjs +0 -1
  234. package/dist/user.context-CPmUBBLa.js +0 -522
  235. package/dist/user.context-xsJgPpcO.cjs +0 -1
package/README.md CHANGED
@@ -11,11 +11,13 @@ component, its variants and its props, rebuilt on each commit to `2026.3`. Look
11
11
  there before writing a component: the catalogue is the answer to "does this
12
12
  already exist".
13
13
 
14
- The six applications that install this package are the consumers it holds itself
14
+ The nine applications that install this package are the consumers it holds itself
15
15
  to, declared in [`consumers.json`](consumers.json) rather than remembered: each
16
- entry names its framework, its chrome, the accent it renders with and the
17
- subpaths it takes, and CI refuses prose that names a subset as though it were
18
- the whole set. An eighth is one entry there, and the checks widen with it.
16
+ entry names its framework, its chrome, the accent it renders with, where its
17
+ source is and the subpaths it takes, and CI refuses prose that names a subset as
18
+ though it were the whole set. A tenth is one entry there, and the checks widen
19
+ with it. The file ships in the package, and a consumer holds its own entry to its
20
+ source with [`viglet-ds-consumer-entries`](#keeping-your-entry-in-the-register-true).
19
21
 
20
22
  Three are Vite consoles (Turing, Shio, Dumont), one is a Vite platform home
21
23
  (the Cloud Home), one is a Vite desktop shell (the Roadkeep GUI), one is a Vite
@@ -43,28 +45,29 @@ install to one copy — `npm ls react-hook-form` should say `deduped`.
43
45
  A change here is a change to shared chrome, so the question is always what it
44
46
  does to Shio, Turing, Dumont, the Cloud Console, the Cloud Home, Schools,
45
47
  the Roadkeep GUI, the Openviglet Website and Viglet Docs — and the answer should
46
- not require a publish. `use:local` walks a products root, so it reaches the first
47
- three; the other six are checked out elsewhere and `npm pack` into them is the
48
- loop until that changes (VDS73). The last two take the package by caret range
49
- rather than pinning it, so they also receive each release the moment they
50
- install one. From this checkout:
48
+ not require a publish. The last two take the package by caret range rather than
49
+ pinning it, so they also receive each release the moment they install one. From
50
+ this checkout:
51
51
 
52
52
  ```bash
53
- pnpm use:local # build, then push dist into every 2026.3 product on disk
53
+ pnpm use:local # build, then push dist into every consumer checked out here
54
54
  pnpm use:local --list # show what it would write to, and stop
55
55
  ```
56
56
 
57
- It finds the consumers by reading their `package.json`, and finds where each one
58
- keeps the installed copy by following the link its own package manager made, so
59
- neither a version bump nor a switch of package manager breaks the loop. Nothing
60
- in the product's manifest or lockfile changes: `pnpm install` in the product puts
61
- the published build back.
57
+ It finds each consumer at the `checkout` its entry in `consumers.json` declares,
58
+ relative to this repository, with `{line}` standing for this checkout's version
59
+ line, so a 2026.2 worktree pushes into the 2026.2 products. A declared checkout
60
+ that is not there is named, not skipped in silence, and finding none at all is an
61
+ error. It finds where each consumer keeps the installed copy by following the
62
+ link its own package manager made, so neither a version bump nor a switch of
63
+ package manager breaks the loop. Nothing in the product's manifest or lockfile
64
+ changes: `pnpm install` in the product puts the published build back.
62
65
 
63
- Pass directories to narrow it, and `--no-build` to reuse the `dist` already on
64
- disk:
66
+ Pass consumer ids or directories to narrow it, and `--no-build` to reuse the
67
+ `dist` already on disk:
65
68
 
66
69
  ```bash
67
- pnpm use:local ../shio/2026.3/shio-react --no-build
70
+ pnpm use:local shio --no-build
68
71
  ```
69
72
 
70
73
  One thing it refuses to do: push over a tree whose dependencies are behind. It
@@ -88,8 +91,8 @@ viglet-ds-check-duplicates src
88
91
  It fails, naming the import that replaces each local copy:
89
92
 
90
93
  ```
91
- src/components/page-header.tsx:18 declares PageHeader
92
- replace it with: import { PageHeader } from "@viglet/viglet-design-system/router"
94
+ src/components/bento-hero.tsx:18 declares BentoHero
95
+ replace it with: import { BentoHero } from "@viglet/viglet-design-system/bento"
93
96
  ```
94
97
 
95
98
  One-line re-export shims are the sanctioned pattern and are skipped. When a
@@ -112,6 +115,114 @@ worked through, and drop it once the count is zero. `--json` prints the findings
112
115
  for a bot to read; `--manifest <path>` checks against an export list other than
113
116
  the installed one.
114
117
 
118
+ ## Linting a page against the shell
119
+
120
+ Two rules in [docs/BENTO-AUTHORING.md](docs/BENTO-AUTHORING.md) pass every other
121
+ gate when broken: a page that sets its own width, gutter or vertical rhythm, and a
122
+ stylesheet that sets `--vg-primary` directly instead of through its
123
+ `--vg-primary-*-base` inputs. `viglet-ds-page-lint` checks both. Point it at the
124
+ directories whose pages render inside `BentoShell`:
125
+
126
+ ```bash
127
+ viglet-ds-page-lint src
128
+ ```
129
+
130
+ ```
131
+ src/app/home.page.tsx:125 page.column the page's outermost element sets max-w-7xl px-6 pb-12
132
+ remove them: BentoShell sets the column, and column="narrow" or "wide" names the other widths
133
+ src/index.css:14 primary.direct sets --vg-primary
134
+ claim it through the --vg-primary-base and --vg-primary-foreground-base inputs, light and -dark, at :root
135
+ ```
136
+
137
+ A page is a file ending in `.page.tsx` or `.page.jsx`, and the lint checks the
138
+ outermost element its default export returns. `--page-pattern <regex>` names your
139
+ own convention. It reads pages with the TypeScript compiler, so `typescript` must
140
+ be installed in the product. A deliberate exception takes a reason, in the file:
141
+
142
+ ```ts
143
+ // viglet-ds-allow-page-column -- a kiosk rendered outside the shell
144
+ ```
145
+
146
+ `viglet-ds-allow-primary -- <reason>` does the same for the second rule.
147
+ `--warn` and `--json` work as they do for `viglet-ds-check-duplicates`.
148
+
149
+ Pass the stylesheet where you re-key the palette to also measure it:
150
+
151
+ ```bash
152
+ viglet-ds-page-lint src --contrast src/index.css
153
+ ```
154
+
155
+ It lays your stylesheet over the preset the way the two cascade and measures every
156
+ token pair your stylesheet changes on both grounds: each `--vg-X` with its
157
+ `--vg-X-foreground`, text and muted text on the page, the accented label on the
158
+ page, and the white label on the accent fill. A pair under 4.5:1 on either ground
159
+ is a finding at the line that declares the token, with both grounds' ratios:
160
+
161
+ ```
162
+ src/index.css:41 contrast.pair --vg-accent-fg on --vg-background is 3.59:1 on the light ground and 7.53:1 on the dark ground; 4.5:1 needed
163
+ ```
164
+
165
+ It reads `oklch()`, hex, `rgb()`, `hsl()`, `var()` chains and
166
+ `color-mix(in oklab, …)`. Anything else is reported as unread rather than
167
+ guessed. `viglet-ds-allow-contrast -- <reason>` in the stylesheet keeps a pair
168
+ you have signed off.
169
+
170
+ ## Keeping your entry in the register true
171
+
172
+ `consumers.json` records the subpaths each product takes, and this package's
173
+ guards read it. `viglet-ds-consumer-entries` measures what your source actually imports and
174
+ compares it with your entry there, in both directions. Run it from the product's
175
+ package root, in its own test step:
176
+
177
+ ```bash
178
+ viglet-ds-consumer-entries
179
+ ```
180
+
181
+ It finds your entry by the `name` in your `package.json` (`--consumer <id>`
182
+ names it outright), scans the `sourceRoots` that entry declares, and fails on a
183
+ subpath you import and do not declare, or one you declare and import nowhere:
184
+
185
+ ```
186
+ consumer-entries: shio's source and its entry in consumers.json disagree
187
+
188
+ imported, and not declared:
189
+ ./router first at src/components/dialog.delete.tsx:17
190
+ ```
191
+
192
+ Tests, stories and comments inside the roots are not counted. A failure means
193
+ the entry here is wrong, so the fix is a change to `consumers.json` in this
194
+ repository. `--json` prints the measurement; `--root <dir>` measures a checkout
195
+ other than the current directory.
196
+
197
+ ## Using it from Claude Code
198
+
199
+ This repository publishes a Claude Code plugin, `viglet-ds`, for a product that
200
+ installs the package. It serves the component catalogue over MCP, loads a skill
201
+ that points a session at it, adds `/viglet-ds-check` to run the CLIs above
202
+ against the working tree, and denies a write that declares a component the
203
+ package already exports, naming the import to use instead.
204
+
205
+ The catalogue server is a bin of its own, `viglet-ds-mcp`, so any MCP client can
206
+ start it from a product's install. It has two tools: `find_component` ranks the
207
+ components that do a job, and `read_component` returns one component's purpose,
208
+ props, the contract sections that govern it and an import to start from. The
209
+ authoring contract, the boundary and the token reference are resources
210
+ (`viglet-ds://authoring`, `viglet-ds://boundary`, `viglet-ds://tokens`). The data
211
+ is `dist/catalogue.json`, generated at build time from the declarations you
212
+ compile against and also exported as `./catalogue.json`. A component's purpose is
213
+ its own doc comment, and every exported component has one: the build refuses a
214
+ component that arrives without it.
215
+
216
+ ```
217
+ /plugin marketplace add openviglet/viglet-design-system
218
+ /plugin install viglet-ds@viglet-design-system
219
+ ```
220
+
221
+ With the plugin enabled in a repository's `.claude/settings.json`,
222
+ `viglet-ds-page-reference` writes only the artboards and leaves the skill to the
223
+ plugin. [claude-plugin/README.md](claude-plugin/README.md) has the settings to
224
+ commit and the package range the plugin supports.
225
+
115
226
  ## Setup
116
227
 
117
228
  ### 1. Import styles
@@ -305,6 +416,14 @@ import {
305
416
  } from "@viglet/viglet-design-system";
306
417
  ```
307
418
 
419
+ `Button` and `GradientButton` take `loading` for an action in flight. The button
420
+ shows a spinner, sets `aria-busy`, ignores a second press (including a form's
421
+ submit) and keeps keyboard focus. Do not pass `disabled` for that: a disabled
422
+ button drops the focus of the control just pressed, just as the result is
423
+ announced. For a control that is unavailable for now, such as a Save with nothing
424
+ to save, pass `aria-disabled="true"`. It stays focusable and ignores activation.
425
+ Keep `disabled` for a control that is genuinely unavailable.
426
+
308
427
  ### App Components
309
428
 
310
429
  ```tsx
@@ -319,16 +438,25 @@ import {
319
438
  ```
320
439
 
321
440
  A page's chrome — its header, its list, its sidebar — comes from the
322
- [bento layer](#the-bento-layer) rather than from here. Read the next section
323
- before reaching for `PageHeader`, `GridList` or `InternalSidebar`.
441
+ [bento layer](#the-bento-layer). It is the only page vocabulary this package
442
+ ships; if you are upgrading from a release that still had `PageHeader`,
443
+ `GridList` or `InternalSidebar`, read the next section.
324
444
 
325
- ### Two eras, and which one a new page should use
445
+ ### Moving off the console era
326
446
 
327
- This package exports two complete page vocabularies. The **console era** is what the consoles ship on today; the **[bento layer](#the-bento-layer)** is the current one, and Turing has cut over to it. Every console-era export is marked `@deprecated` in its own types, so an editor strikes it through and offers the swap.
447
+ This package used to export two complete page vocabularies. The **console era**
448
+ is gone: `pnpm chrome:census` counts, per consumer checked out beside this
449
+ repository, the source files taking a console-era component — directly or
450
+ through a re-export shim — and it reads zero across all nine, so the eleven
451
+ components below were removed. The **[bento layer](#the-bento-layer)** is what
452
+ remains, and with one chrome left there is nothing to choose between: the
453
+ `SectionCardChromeProvider` that used to declare which one a page rendered in
454
+ went with them.
328
455
 
329
- Nothing is being removed. No product has started cutting over, and a removal will get its own roadmap line rather than arriving as a side effect of this notice — so existing pages keep working and need no rush.
456
+ Each row is a swap rather than a rename: the replacement takes its own props,
457
+ and the note says where the two differ.
330
458
 
331
- | Console era | Use instead | |
459
+ | Removed | Use instead | |
332
460
  |---|---|---|
333
461
  | `PageHeader` | `BentoHero` | Same title/subtitle/icon, plus a tone — the chip follows the product accent. |
334
462
  | `SubPageHeader` | `BentoHero` | With `BentoBackLink` for the back target and `BentoActionsMenu` for the menu. |
@@ -339,9 +467,9 @@ Nothing is being removed. No product has started cutting over, and a removal wil
339
467
  | `NavMain` | `BentoNavRail` | |
340
468
  | `NavUser` | `BentoUserMenu` | Routes and feature flags arrive as props. |
341
469
  | `SubPage` | `BentoEntityShell` | Renders through a render prop, so the shell never learns what an entity is. |
342
- | `Page`, `PageContent` | — | No single replacement, deliberately: the shell is where a product is itself. Compose `BentoNavRail`, `BentoUserMenu` and `BentoCommandPalette`. |
470
+ | `Page`, `PageContent` | `BentoShell` | Takes the rail, the header's two edges and the page; it owns `main` and the reading column, so a page sets no width. |
343
471
 
344
- `DialogDelete`, `LoadProvider` and `GradientButtonLink` are **not** console-era — the bento layer uses them itself, and they are not deprecated.
472
+ `DialogDelete`, `LoadProvider` and `GradientButtonLink` were never console-era — the bento layer uses them itself, and they are the whole of `./router` now.
345
473
 
346
474
  ### The mascot
347
475
 
@@ -415,8 +543,44 @@ messages={[{
415
543
  }]}
416
544
  ```
417
545
 
546
+ **What the system reports is a `report`, not an assistant message.** A publish,
547
+ a failure or an arrival has a `tone` (one of the mascot's five states), a time,
548
+ a `read` flag and up to three `actions`, and it renders apart from the
549
+ conversation. It never opens a composer, so a dock with no `onSend` lists reports
550
+ on their own. You own the list, as you own the messages:
551
+
552
+ ```tsx
553
+ <VigletAssistant
554
+ messages={reports}
555
+ onRead={(id) => markRead(id)}
556
+ onDismiss={(id) => dismiss(id)}
557
+ />
558
+
559
+ const reports = [{
560
+ id: "publish-q3",
561
+ role: "report",
562
+ tone: "error",
563
+ text: "Could not publish /q3-results.",
564
+ at: failedAt,
565
+ actions: [
566
+ { label: "Retry", onSelect: retry },
567
+ { label: "Open the page", onSelect: openPage },
568
+ ],
569
+ }];
570
+ ```
571
+
572
+ Collapsed, the orb counts the unread reports, and the caption is the newest one
573
+ unless you pass `caption`. The mascot's state follows that report's tone unless
574
+ you pass `state`. Pass `unread` a number to count something else. `onRead` fires
575
+ for each unread report when the dock opens or closes, since it was on screen,
576
+ and a dismiss button appears on each report once you pass `onDismiss`. A report
577
+ is announced once, when it arrives, and not again when the dock opens or
578
+ re-renders.
579
+
418
580
  It pins itself to the bottom-right of the viewport; pass `inline` to render it
419
- in flow and place it yourself. `open` / `onOpenChange` make it controlled,
581
+ in flow and place it yourself. In a bento product, pass it to `BentoShell` as
582
+ `dock` instead: the shell holds the corner, stacks `BentoBackToTop` above the
583
+ dock, and keeps either from covering the other. `open` / `onOpenChange` make it controlled,
420
584
  Escape collapses it, and the caption is typed for everyone while a screen reader
421
585
  is handed the whole sentence at once.
422
586
 
@@ -524,15 +688,23 @@ import type {
524
688
 
525
689
  ## What's Included
526
690
 
527
- ### UI Primitives (41 components)
691
+ ### UI Primitives (49 components)
692
+
693
+ Accordion, Avatar, Badge, Breadcrumb, Button, Card, Checkbox, Dialog, Drawer, DropdownMenu, FloatingFormulasBg, Form, FormActions, FormItemTwoColumns, GlassCard, GradientButton, GradientSwitch, HoverCard, IconPickerDialog, Input, Label, NavigationMenu, Pagination, Popover, Progress, PulseRing, Resizable, SectionCard, Select, Separator, Sheet, Sidebar, Skeleton, Slider, Stepper, StickySaveBar, Switch, Table, Tabs, Textarea, Toaster (sonner), Toggle, ToggleGroup, Tooltip, Tree, UserAvatar, UserMenu, VigletAssistant ([the dock](#the-assistant-dock)), VigletAvatar ([the mascot](#the-mascot))
694
+
695
+ ### App Components (19 components)
696
+
697
+ AppFooter, AppSwitcher, BackendStatusBanner, BackendStatusProvider, BadgeColorful, BadgeLocale, DialogDelete, ErrorBoundary, GradientButtonLink, LanguageSelect, LanguageSwitcher, LoadProvider, Login, ModeToggle, ModeToggleSidebar, NavSecondary, StartupFirst, ThemeProvider, VigletAppSwitcher
698
+
699
+ `DialogDelete`, `GradientButtonLink` and `LoadProvider` are imported from `@viglet/viglet-design-system/router`; every other name above comes from the package root. `Login` and `StartupFirst` are compounds — each is a root with named parts on it, the way `Card` is.
528
700
 
529
- Accordion, Avatar, Badge, Breadcrumb, Button, Card, Checkbox, Dialog, Drawer, DropdownMenu, Form, FormActions, FormItemTwoColumns, GradientButton, GradientSwitch, HoverCard, Input, Label, NavigationMenu, Pagination, Popover, Progress, Resizable, SectionCard, Select, Separator, Sheet, Sidebar, Skeleton, Slider, Sonner (Toaster), Stepper, Switch, Table, Tabs, Textarea, Toggle, ToggleGroup, Tooltip, VigletAssistant ([the dock](#the-assistant-dock)), VigletAvatar ([the mascot](#the-mascot))
701
+ ### Bento Layer (31 components)
530
702
 
531
- ### App Components (23 components)
703
+ AdaptiveSectionCard, BentoActionsMenu, BentoBackLink, BentoBackToTop, BentoCommandPalette, BentoCountTile, BentoDataTable, BentoDiff, BentoEmptyState, BentoEntityShell, BentoEntityTile, BentoFilterBar, BentoFormHero, BentoFormSection, BentoHero, BentoHeroIconPicker, BentoInlineEdit, BentoListPage, BentoNavRail, BentoPaletteTrigger, BentoPanel, BentoSaveBar, BentoScrollSaveBar, BentoSection, BentoShell, BentoShortcutsDialog, BentoStatusMarker, BentoTile, BentoTileGrid, BentoUserMenu, BentoVersionRail
532
704
 
533
- AppFooter, BadgeColorful, BadgeLocale, DialogDelete, GradientButtonLink, LanguageSelect, LoadProvider, ModeToggle, NavSecondary, ThemeProvider
705
+ All from `@viglet/viglet-design-system/bento`, with `@viglet/viglet-design-system/bento.css` beside it. [The bento layer](#the-bento-layer) is what each one is for and how a page composes them; this is the inventory.
534
706
 
535
- Console-era, `@deprecated`, still exported — see [the swap table](#two-eras-and-which-one-a-new-page-should-use): BlankSlate, GridList, InternalSidebar, NavMain, NavUser, Page, PageContent, PageHeader, StickyPageHeader, SubPage, SubPageHeader
707
+ Removed with the console era — see [where each one went](#moving-off-the-console-era): BlankSlate, GridList, InternalSidebar, NavMain, NavUser, Page, PageContent, PageHeader, StickyPageHeader, SubPage, SubPageHeader
536
708
 
537
709
  ### Hooks
538
710
 
@@ -623,6 +795,7 @@ of it:
623
795
  ```ts
624
796
  import "@viglet/viglet-design-system/bento.css";
625
797
  import {
798
+ BentoShell,
626
799
  BentoEntityShell,
627
800
  BentoListPage,
628
801
  BentoFormHero,
@@ -635,6 +808,104 @@ The stylesheet is a separate import from the components, so a consumer taking
635
808
  only the layout maths does not pull CSS it never renders. It reads the preset's
636
809
  tokens, so import the preset too.
637
810
 
811
+ `BentoShell` is the page frame. It reserves the gutter for the rail you pass,
812
+ lays out the header's leading and trailing edges, holds the corner (the
813
+ `VigletAssistant` you pass as `dock`, with `BentoBackToTop` stacked above it;
814
+ `backToTop={false}` drops the button), and owns `main`: the width, the gutters
815
+ and the vertical rhythm. A page
816
+ inside it sets none of those. Choose the width by name with `column`: `default`,
817
+ `narrow` for a single-question form, `wide` for a table, or `full` for a tool
818
+ that fills the viewport. Each width is a custom property
819
+ (`--bento-column-default`, `--bento-column-narrow`, `--bento-column-wide`) that
820
+ you can redefine at `:root`.
821
+
822
+ ```tsx
823
+ <BentoShell
824
+ column={isForm ? "narrow" : "default"}
825
+ rail={<BentoNavRail groups={groups} homeRoute={ROUTES.HOME} />}
826
+ headerStart={<ProductMark />}
827
+ headerEnd={<BentoUserMenu accountRoute={ROUTES.ACCOUNT} logoutUrl={ROUTES.LOGOUT} />}
828
+ >
829
+ <Outlet />
830
+ </BentoShell>
831
+ ```
832
+
833
+ `BentoDataTable` is the list a curator sorts, range-selects and acts on at scale.
834
+ It mounts only the rows in view, so ten thousand cost what twenty do. Pass `rows`,
835
+ `getRowId`, `columns` (a header, a `cell`, and a `sortValue` to make it sortable),
836
+ and optionally `rowActions` for a per-row menu and `selectionActions` for the bar
837
+ that appears over a selection. The arrows move between rows, Shift with an arrow
838
+ or a click extends a selection, and Enter calls `onRowOpen`. The column picker
839
+ reports `onLayoutChange`, and you store the layout, as you do for `BentoListPage`.
840
+
841
+ ```tsx
842
+ <BentoDataTable
843
+ rows={posts}
844
+ getRowId={(p) => p.id}
845
+ getRowLabel={(p) => p.title}
846
+ label={t("posts")}
847
+ columns={[
848
+ { id: "title", header: t("title"), cell: (p) => p.title, sortValue: (p) => p.title, hideable: false },
849
+ { id: "updated", header: t("updated"), cell: (p) => format(p.updated), sortValue: (p) => p.updated },
850
+ ]}
851
+ rowActions={[{ id: "trash", label: t("trash"), icon: IconTrash, tone: "destructive", onSelect: trash }]}
852
+ selectionActions={[{ id: "trash", label: t("trash"), icon: IconTrash, onSelect: trash }]}
853
+ onRowOpen={(p) => navigate(p.url)}
854
+ />
855
+ ```
856
+
857
+ `AdaptiveSectionCard` renders the console's compound form markup — a `Header`
858
+ child and a `Content` child — as a frosted bento section, so a form written that
859
+ way moves without being rewritten. That compound API is the whole difference
860
+ from `BentoFormSection`, which takes the same icon, title and description as
861
+ props. A section whose header it cannot read keeps the frosted surface and all
862
+ of its children; a frosted box that is not part of a form is `BentoPanel`.
863
+
864
+ **`SectionCardChromeProvider`, `useSectionChrome`, the `SectionChrome` type and
865
+ the `defaultOpen` prop were removed in this release.** They picked between the
866
+ console card and the frosted section, and every consumer finished its cutover —
867
+ so every remaining call site passed `chrome="bento"`, the value it would have got
868
+ anyway. Delete the provider and the hook; the sections beneath render as they
869
+ already did. A `useSectionChrome()` call that drove a product's own branch can be
870
+ replaced by the bento arm of that branch.
871
+
872
+ **Give every `BentoActionsMenu` item an `id`**, a stable name for the verb such as
873
+ `"post.delete"`, and the same for `BentoEntityShell`'s `extraActions`. It is
874
+ rendered as `data-action-id` and means nothing to the package, but it lets a
875
+ product check its console verbs against its agent's, since a menu item is
876
+ otherwise an anonymous `onSelect`. An item without one warns outside production
877
+ in this release and stops type-checking in the next.
878
+
879
+ `BentoFilterBar` is the query row above a list: a search field, the facets you
880
+ declare (a `choice` of options, single or `multiple`, or a `date` range), the
881
+ active filters as removable chips, and a clear-all. It holds no state. You pass
882
+ `value` and get one `onChange` per action, typing included once it pauses, so the
883
+ value can live in the URL and a filtered view is a link. Pass it to a
884
+ `BentoDataTable` as `selectionScope` too, and a selection clears when the filters
885
+ change the rows:
886
+
887
+ ```tsx
888
+ <BentoFilterBar
889
+ value={filters}
890
+ onChange={setFilters}
891
+ facets={[
892
+ { id: "state", kind: "choice", label: t("state"), multiple: true, options: states },
893
+ { id: "updated", kind: "date", label: t("updated") },
894
+ ]}
895
+ />
896
+ <BentoDataTable rows={filtered} selectionScope={JSON.stringify(filters)} … />
897
+ ```
898
+
899
+ `BentoDiff` compares two versions of structured content field by field, for
900
+ revision history, a review of what an agent changed, or a translation against its
901
+ source. Pass `before`, `after` and the `fields` to compare. A field is `text`
902
+ (compared by word), `rich` (HTML, compared on the blocks it renders, so markup
903
+ alone is no change) or `value` (compared whole). Unchanged fields collapse behind
904
+ a count. A side that is `null` renders the other whole, as a created or deleted
905
+ item. Every change is named in text as well as coloured. `BentoVersionRail` lists
906
+ the revisions (author, person or agent, time) as a listbox a reader picks two
907
+ from, by keyboard or pointer. Neither fetches anything.
908
+
638
909
  `BentoCommandPalette` takes a second group whose items the product supplies per
639
910
  query, beside the nav items it matches itself. Pass `onQueryChange` to hear the
640
911
  query as typed and `group` to answer it:
@@ -654,11 +925,27 @@ already ranked them by relevance it understands, and a substring match here
654
925
  would only undo that. Set `pending` while the query is in flight so the dialog
655
926
  says so rather than showing an empty list that is not empty yet.
656
927
 
928
+ Bind the shell's keys with `useBentoShellShortcuts` rather than a keydown listener
929
+ of your own. ⌘K on macOS, Ctrl+K elsewhere, or `/` calls `onPalette`, and `?`
930
+ calls `onShortcuts`. A bare key typed into an input, a textarea, a select or an
931
+ editable node is left to the field. `BentoPaletteTrigger` is the header button,
932
+ with the same chord as its hint, and `BentoShortcutsDialog` lists the same set
933
+ (`BENTO_SHELL_SHORTCUTS`), so the guide shows exactly the keys that work:
934
+
935
+ ```tsx
936
+ useBentoShellShortcuts({
937
+ onPalette: () => setPaletteOpen((open) => !open),
938
+ onShortcuts: () => setShortcutsOpen((open) => !open),
939
+ });
940
+
941
+ <BentoShell headerStart={<><ProductMark /><BentoPaletteTrigger onClick={() => setPaletteOpen(true)} /></>}>
942
+ ```
943
+
657
944
  "Carries none of it" is measured rather than claimed. `pnpm run build` ends by
658
945
  bundling three fixtures through this package's own `exports` map, and fails if a
659
946
  bento module, a bento class name or a run of `bento.css`'s selectors reaches a
660
947
  consumer that imported only the root entry. `size-budget.json` records what each
661
- entry costs: today the whole root entry is 87 KB gzipped and `./bento` 22 KB,
948
+ entry costs: today the whole root entry is 91 KB gzipped and `./bento` 31 KB,
662
949
  measured with everything the build externalises left out, so the numbers
663
950
  describe this package rather than its dependencies. The preset's
664
951
  `--vg-bento-tone-*` tokens are deliberately not counted as the layer: they ship
@@ -672,7 +959,7 @@ correct rather than a leak. The subpath is for a consumer who wants only that
672
959
  background.
673
960
 
674
961
  Every subpath in the table above is also **imported, required and type-checked
675
- as you would use it** on each build: one fixture pulls all fifteen through the
962
+ as you would use it** on each build: one fixture pulls all seventeen through the
676
963
  real `exports` map, a CommonJS probe requires the seven that offer it, and a
677
964
  generated TypeScript probe imports a value from each typed entry and uses it —
678
965
  so a `types` field resolving to the wrong declarations fails here rather than
package/consumers.json ADDED
@@ -0,0 +1,186 @@
1
+ {
2
+ "why": [
3
+ "The consumers this package holds itself to, declared rather than remembered.",
4
+ "The roadmap named Shio and Turing throughout while dumont-react sat on the",
5
+ "same 2026.3 line consuming the same entries, so one-look claims were being",
6
+ "checked against two of three. This file is the one place that set lives:",
7
+ "prose that names a subset as though it were the whole is a test failure,",
8
+ "not a style note.",
9
+ "",
10
+ "VDS73 widened it again, and by more than the line predicted. It expected two",
11
+ "Next installs; three consumers were absent, because cloud-frontend is a Vite",
12
+ "SPA nobody had written down either. Being outside the products root that",
13
+ "`use:local` walks is what kept all three invisible: the loop this package",
14
+ "offers instead of a publish could not reach them, so nothing ever asked.",
15
+ "",
16
+ "`framework` is why the membership could not just grow. A Next consumer takes",
17
+ "a different set: no `./router`, because the App Router is what replaces",
18
+ "react-router-dom, and no `./vite`. A guard that assumes every consumer",
19
+ "resolves `./router` asserts something three of six cannot do.",
20
+ "",
21
+ "`chrome` says which surface, and `console` stopped covering it: a platform",
22
+ "home and a public admissions front door are neither consoles nor bento.",
23
+ "",
24
+ "VDS144 made it a measurement. `pnpm chrome:census` counts the source files that",
25
+ "take a console-era component, from the package or through a product's own",
26
+ "re-export shim, and holds the field to that count: `console` for a consumer",
27
+ "that takes one and not ./bento, `mixed` for one that takes both, and anything",
28
+ "else only at zero. The first reading moved three: Turing had been called",
29
+ "`bento` with sixteen files still on console-era headers and empty states,",
30
+ "Dumont `console` while taking ./bento too, and the Cloud Console `console` with",
31
+ "no console-era import at all. The non-goals that wait for every console to cut",
32
+ "over are waiting for no entry to say `console` or `mixed`.",
33
+ "",
34
+ "VDS147 is that reading arriving. Turing and Dumont finished their cutover, the",
35
+ "census counted zero console-era imports in all nine, and both entries moved from",
36
+ "`mixed` to `bento` — which is what allowed the eleven console-era components to",
37
+ "be removed. The field stays measured rather than retired: it is how the next",
38
+ "chrome, whatever it is, gets counted instead of remembered.",
39
+ "",
40
+ "VDS146 took `console` and `mixed` out of the vocabulary. They named a chrome a",
41
+ "consumer could still be rendering, and there is no longer one to render: the",
42
+ "components are gone and so is the provider that picked between them. So the",
43
+ "census stopped asking a consumer to agree with its own measurement and now",
44
+ "reports a counted console-era import on its own, which is the only thing left",
45
+ "that could put one there — a name coming back, in a product, where this",
46
+ "repository's own removal guard cannot see it.",
47
+ "",
48
+ "`accent` is the token set a consumer renders with, and today every one of",
49
+ "them says `cool`. That is worth recording rather than assuming: VDS23 made",
50
+ "the brand accent a token so a product could re-key without forking a header,",
51
+ "and no product has re-keyed yet. The parity digest reads this, so the day one",
52
+ "does, the digest is required to carry that set.",
53
+ "",
54
+ "VDS122 widened it a third time, to nine, and the two it added were invisible",
55
+ "for a third reason: both take the package by caret range rather than pinning",
56
+ "it, so each receives a release the moment it installs one, and neither is a",
57
+ "product — a marketing site and a docs site are not what a guard here goes",
58
+ "looking for. Both were reached by reading their imports, not by being",
59
+ "remembered. `viglet-docs` is also the first consumer on a third framework;",
60
+ "it takes no root entry at all, only `./preset` and the background.",
61
+ "",
62
+ "`entries` is what each product imports, and VDS129 is why that is measured",
63
+ "rather than copied in. A snapshot drifted exactly as it was expected to: the",
64
+ "Shio entry listed three of the six subpaths its source takes and still said",
65
+ "`console`, and five other entries had gained or lost a subpath too, while the",
66
+ "only guard asked whether a declared entry exists and never whether an",
67
+ "imported one is declared.",
68
+ "",
69
+ "`sourceRoots` says where a product's own source is, relative to its package",
70
+ "root, so the measure is declared rather than guessed. `viglet-ds-consumer-entries`",
71
+ "reads them from a consumer's checkout and fails in both directions: a subpath",
72
+ "imported and not declared, and one declared and imported nowhere. Tests and",
73
+ "stories inside those roots are skipped, since a census test that greps for a",
74
+ "subpath is counting pages, not taking the entry. This file ships in the package",
75
+ "so a consumer can run that from its own suite.",
76
+ "",
77
+ "`checkout` is where `use:local` finds a consumer, relative to this repository's",
78
+ "root, with `{line}` standing for the version line this checkout is cut from.",
79
+ "The loop used to walk the directory above this checkout, which stopped being a",
80
+ "products root once this repository moved to one worktree per version, and it",
81
+ "found nothing (VDS130). A consumer not checked out beside this one says",
82
+ "`offMachine: true` instead, so on a developer's machine a checkout that is not",
83
+ "there is a failing test rather than a sentence nobody reads."
84
+ ],
85
+ "consumers": [
86
+ {
87
+ "id": "shio",
88
+ "name": "Shio",
89
+ "package": "shio-react",
90
+ "checkout": "../../shio/{line}/shio-react",
91
+ "framework": "vite",
92
+ "chrome": "bento",
93
+ "accent": "cool",
94
+ "sourceRoots": ["src", "vite.config.ts"],
95
+ "entries": [".", "./bento", "./bento.css", "./i18n", "./router", "./styles", "./vite"]
96
+ },
97
+ {
98
+ "id": "turing",
99
+ "name": "Turing",
100
+ "package": "turing-app",
101
+ "checkout": "../../turing/{line}/frontend/apps/turing-app",
102
+ "framework": "vite",
103
+ "chrome": "bento",
104
+ "accent": "cool",
105
+ "sourceRoots": ["src", "vite.config.ts"],
106
+ "entries": [".", "./bento", "./bento.css", "./i18n", "./router", "./styles", "./vite"]
107
+ },
108
+ {
109
+ "id": "dumont",
110
+ "name": "Dumont",
111
+ "package": "dumont-react",
112
+ "checkout": "../../dumont/{line}/dumont-react",
113
+ "framework": "vite",
114
+ "chrome": "bento",
115
+ "accent": "cool",
116
+ "sourceRoots": ["src", "vite.config.ts"],
117
+ "entries": [".", "./bento", "./bento.css", "./i18n", "./router", "./styles", "./vite"]
118
+ },
119
+ {
120
+ "id": "cloud-console",
121
+ "name": "Cloud Console",
122
+ "package": "@viglet/cloud-console",
123
+ "checkout": "../../cloud/console",
124
+ "framework": "next",
125
+ "chrome": "platform-console",
126
+ "accent": "cool",
127
+ "sourceRoots": ["src", "next.config.ts"],
128
+ "entries": [".", "./assets", "./i18n", "./styles"]
129
+ },
130
+ {
131
+ "id": "cloud-frontend",
132
+ "name": "Cloud Home",
133
+ "package": "@viglet/cloud-frontend",
134
+ "checkout": "../../cloud/cloud-frontend",
135
+ "framework": "vite",
136
+ "chrome": "platform-home",
137
+ "accent": "cool",
138
+ "sourceRoots": ["src", "vite.config.ts"],
139
+ "entries": [".", "./assets", "./i18n", "./styles", "./vite"]
140
+ },
141
+ {
142
+ "id": "schools",
143
+ "name": "Schools",
144
+ "package": "schools",
145
+ "checkout": "../../../japode/schools",
146
+ "framework": "next",
147
+ "chrome": "front-door",
148
+ "accent": "cool",
149
+ "sourceRoots": ["src", "next.config.ts"],
150
+ "entries": [".", "./fonts", "./preset", "./styles"]
151
+ },
152
+ {
153
+ "id": "roadkeep-gui",
154
+ "name": "Roadkeep GUI",
155
+ "package": "@rk/ui",
156
+ "checkout": "../../../alegauss/roadkeep-gui/packages/ui",
157
+ "framework": "vite",
158
+ "chrome": "bento",
159
+ "accent": "amber",
160
+ "sourceRoots": ["src", "vite.config.ts"],
161
+ "entries": [".", "./bento", "./bento.css", "./fonts", "./i18n", "./styles"]
162
+ },
163
+ {
164
+ "id": "openviglet-website",
165
+ "name": "Openviglet Website",
166
+ "package": "openviglet-website",
167
+ "checkout": "../../site",
168
+ "framework": "vite",
169
+ "chrome": "marketing-site",
170
+ "accent": "cool",
171
+ "sourceRoots": ["src", "vite.config.ts"],
172
+ "entries": [".", "./floating-formulas-bg.css", "./preset", "./styles"]
173
+ },
174
+ {
175
+ "id": "viglet-docs",
176
+ "name": "Viglet Docs",
177
+ "package": "viglet-docs",
178
+ "checkout": "../../vigletdocs/vigletdocs.github.io",
179
+ "framework": "docusaurus",
180
+ "chrome": "docs-site",
181
+ "accent": "cool",
182
+ "sourceRoots": ["src", "docusaurus.config.ts"],
183
+ "entries": ["./floating-formulas-bg", "./floating-formulas-bg.css", "./preset"]
184
+ }
185
+ ]
186
+ }