@qijenchen/design-system 0.1.0-beta.95 → 0.1.0-beta.99

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 (355) hide show
  1. package/README.md +1 -0
  2. package/dist/components/AccountMenu/account-menu.d.ts +86 -0
  3. package/dist/components/AccountMenu/account-menu.d.ts.map +1 -0
  4. package/dist/components/AccountMenu/account-menu.js +64 -0
  5. package/dist/components/AccountMenu/account-menu.js.map +1 -0
  6. package/dist/components/AccountMenu/index.d.ts +2 -0
  7. package/dist/components/AccountMenu/index.d.ts.map +1 -0
  8. package/dist/components/AccountMenu/index.js +6 -0
  9. package/dist/components/AccountMenu/index.js.map +1 -0
  10. package/dist/components/AppShell/_demo-helpers.d.ts.map +1 -1
  11. package/dist/components/AppShell/app-shell.d.ts.map +1 -1
  12. package/dist/components/AppShell/app-shell.js +2 -2
  13. package/dist/components/AppShell/app-shell.js.map +1 -1
  14. package/dist/components/Badge/badge.d.ts +1 -1
  15. package/dist/components/Button/button.d.ts +3 -3
  16. package/dist/components/Button/button.d.ts.map +1 -1
  17. package/dist/components/Button/button.js +3 -2
  18. package/dist/components/Button/button.js.map +1 -1
  19. package/dist/components/Calendar/calendar.d.ts +10 -21
  20. package/dist/components/Calendar/calendar.d.ts.map +1 -1
  21. package/dist/components/Calendar/calendar.js +52 -59
  22. package/dist/components/Calendar/calendar.js.map +1 -1
  23. package/dist/components/Combobox/combobox.d.ts.map +1 -1
  24. package/dist/components/Combobox/combobox.js +1 -0
  25. package/dist/components/Combobox/combobox.js.map +1 -1
  26. package/dist/components/Command/command.d.ts.map +1 -1
  27. package/dist/components/Command/command.js +3 -1
  28. package/dist/components/Command/command.js.map +1 -1
  29. package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
  30. package/dist/components/DataTable/cell-registry.js +1 -5
  31. package/dist/components/DataTable/cell-registry.js.map +1 -1
  32. package/dist/components/DataTable/data-table-filter-group.d.ts +6 -2
  33. package/dist/components/DataTable/data-table-filter-group.d.ts.map +1 -1
  34. package/dist/components/DataTable/data-table-filter-group.js +32 -27
  35. package/dist/components/DataTable/data-table-filter-group.js.map +1 -1
  36. package/dist/components/DataTable/data-table-filter-labels.d.ts +44 -0
  37. package/dist/components/DataTable/data-table-filter-labels.d.ts.map +1 -0
  38. package/dist/components/DataTable/data-table-filter-labels.js +55 -0
  39. package/dist/components/DataTable/data-table-filter-labels.js.map +1 -0
  40. package/dist/components/DataTable/data-table-filter-panel.d.ts +11 -0
  41. package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -1
  42. package/dist/components/DataTable/data-table-filter-panel.js +33 -10
  43. package/dist/components/DataTable/data-table-filter-panel.js.map +1 -1
  44. package/dist/components/DataTable/data-table-filter-value-picker.d.ts +4 -1
  45. package/dist/components/DataTable/data-table-filter-value-picker.d.ts.map +1 -1
  46. package/dist/components/DataTable/data-table-filter-value-picker.js +22 -8
  47. package/dist/components/DataTable/data-table-filter-value-picker.js.map +1 -1
  48. package/dist/components/DataTable/data-table.d.ts.map +1 -1
  49. package/dist/components/DataTable/data-table.js +5 -4
  50. package/dist/components/DataTable/data-table.js.map +1 -1
  51. package/dist/components/DataTable/index.js +2 -0
  52. package/dist/components/DataTable/index.js.map +1 -1
  53. package/dist/components/DatePicker/date-picker.d.ts.map +1 -1
  54. package/dist/components/DatePicker/date-picker.js +187 -156
  55. package/dist/components/DatePicker/date-picker.js.map +1 -1
  56. package/dist/components/Dialog/dialog.d.ts +1 -1
  57. package/dist/components/Dialog/dialog.d.ts.map +1 -1
  58. package/dist/components/Dialog/dialog.js +4 -2
  59. package/dist/components/Dialog/dialog.js.map +1 -1
  60. package/dist/components/DropdownMenu/dropdown-menu.d.ts +4 -1
  61. package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
  62. package/dist/components/DropdownMenu/dropdown-menu.js +46 -14
  63. package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
  64. package/dist/components/Field/field-context.d.ts +12 -0
  65. package/dist/components/Field/field-context.d.ts.map +1 -1
  66. package/dist/components/Field/field-context.js +10 -1
  67. package/dist/components/Field/field-context.js.map +1 -1
  68. package/dist/components/Field/field-wrapper.d.ts.map +1 -1
  69. package/dist/components/Field/field-wrapper.js +7 -1
  70. package/dist/components/Field/field-wrapper.js.map +1 -1
  71. package/dist/components/Field/field.d.ts.map +1 -1
  72. package/dist/components/Field/field.js +11 -2
  73. package/dist/components/Field/field.js.map +1 -1
  74. package/dist/components/FieldControlGroup/field-control-group.d.ts +2 -5
  75. package/dist/components/FieldControlGroup/field-control-group.d.ts.map +1 -1
  76. package/dist/components/FieldControlGroup/field-control-group.js +2 -2
  77. package/dist/components/FieldControlGroup/field-control-group.js.map +1 -1
  78. package/dist/components/FileUpload/file-upload.js +1 -1
  79. package/dist/components/FileUpload/file-upload.js.map +1 -1
  80. package/dist/components/FileViewer/file-viewer.d.ts +1 -1
  81. package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
  82. package/dist/components/FileViewer/file-viewer.js +20 -3
  83. package/dist/components/FileViewer/file-viewer.js.map +1 -1
  84. package/dist/components/InlineEdit/inline-edit.d.ts +5 -0
  85. package/dist/components/InlineEdit/inline-edit.d.ts.map +1 -1
  86. package/dist/components/InlineEdit/inline-edit.js +65 -33
  87. package/dist/components/InlineEdit/inline-edit.js.map +1 -1
  88. package/dist/components/Input/input.d.ts.map +1 -1
  89. package/dist/components/Input/input.js +3 -2
  90. package/dist/components/Input/input.js.map +1 -1
  91. package/dist/components/LinkInput/link-input.d.ts.map +1 -1
  92. package/dist/components/LinkInput/link-input.js +2 -1
  93. package/dist/components/LinkInput/link-input.js.map +1 -1
  94. package/dist/components/Menu/menu-item.d.ts.map +1 -1
  95. package/dist/components/Menu/menu-item.js +4 -2
  96. package/dist/components/Menu/menu-item.js.map +1 -1
  97. package/dist/components/PeoplePicker/people-picker.d.ts +2 -0
  98. package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
  99. package/dist/components/PeoplePicker/people-picker.js +4 -0
  100. package/dist/components/PeoplePicker/people-picker.js.map +1 -1
  101. package/dist/components/Popover/popover.d.ts.map +1 -1
  102. package/dist/components/Popover/popover.js +4 -2
  103. package/dist/components/Popover/popover.js.map +1 -1
  104. package/dist/components/ScrollArea/scroll-area.d.ts +4 -3
  105. package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -1
  106. package/dist/components/ScrollArea/scroll-area.js +1 -1
  107. package/dist/components/ScrollArea/scroll-area.js.map +1 -1
  108. package/dist/components/Select/select.d.ts.map +1 -1
  109. package/dist/components/Select/select.js +59 -37
  110. package/dist/components/Select/select.js.map +1 -1
  111. package/dist/components/SelectMenu/select-menu.d.ts +2 -0
  112. package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
  113. package/dist/components/SelectMenu/select-menu.js +3 -1
  114. package/dist/components/SelectMenu/select-menu.js.map +1 -1
  115. package/dist/components/Sheet/sheet.d.ts +1 -1
  116. package/dist/components/Sidebar/sidebar.js +2 -2
  117. package/dist/components/Sidebar/sidebar.js.map +1 -1
  118. package/dist/components/Tabs/tabs.d.ts.map +1 -1
  119. package/dist/components/Tabs/tabs.js +3 -0
  120. package/dist/components/Tabs/tabs.js.map +1 -1
  121. package/dist/components/Tag/tag.d.ts +1 -1
  122. package/dist/components/Tag/tag.d.ts.map +1 -1
  123. package/dist/components/Tag/tag.js +4 -3
  124. package/dist/components/Tag/tag.js.map +1 -1
  125. package/dist/components/Textarea/textarea.d.ts +11 -0
  126. package/dist/components/Textarea/textarea.d.ts.map +1 -1
  127. package/dist/components/Textarea/textarea.js +22 -5
  128. package/dist/components/Textarea/textarea.js.map +1 -1
  129. package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
  130. package/dist/components/TimePicker/time-picker.js +4 -3
  131. package/dist/components/TimePicker/time-picker.js.map +1 -1
  132. package/dist/components/Tooltip/tooltip.d.ts +1 -1
  133. package/dist/components/Tooltip/tooltip.d.ts.map +1 -1
  134. package/dist/components/Tooltip/tooltip.js +26 -1
  135. package/dist/components/Tooltip/tooltip.js.map +1 -1
  136. package/dist/components/TreeView/tree-view.d.ts +2 -0
  137. package/dist/components/TreeView/tree-view.d.ts.map +1 -1
  138. package/dist/components/TreeView/tree-view.js +3 -2
  139. package/dist/components/TreeView/tree-view.js.map +1 -1
  140. package/dist/index.d.ts +5 -3
  141. package/dist/index.d.ts.map +1 -1
  142. package/dist/index.js +4 -0
  143. package/dist/index.js.map +1 -1
  144. package/dist/patterns/element-anatomy/item-anatomy.d.ts +10 -1
  145. package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
  146. package/dist/patterns/element-anatomy/item-anatomy.js +77 -29
  147. package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
  148. package/dist/patterns/header-canonical/chrome-header.d.ts +11 -4
  149. package/dist/patterns/header-canonical/chrome-header.d.ts.map +1 -1
  150. package/dist/patterns/header-canonical/chrome-header.js +1 -1
  151. package/dist/patterns/header-canonical/chrome-header.js.map +1 -1
  152. package/dist/patterns/overlay-surface/overlay-surface.d.ts +4 -3
  153. package/dist/patterns/overlay-surface/overlay-surface.d.ts.map +1 -1
  154. package/dist/patterns/overlay-surface/overlay-surface.js +1 -0
  155. package/dist/patterns/overlay-surface/overlay-surface.js.map +1 -1
  156. package/dist/patterns/resize-handle/resize-handle.d.ts +9 -11
  157. package/dist/patterns/resize-handle/resize-handle.d.ts.map +1 -1
  158. package/dist/patterns/resize-handle/resize-handle.js +3 -6
  159. package/dist/patterns/resize-handle/resize-handle.js.map +1 -1
  160. package/ds-canonical/adapters/claude/agents/canonical-reviewer.md +1 -1
  161. package/ds-canonical/adapters/claude-root-instructions.md +1 -1
  162. package/ds-canonical/adapters/claude-settings-base.json +2 -5
  163. package/ds-canonical/fork/AGENTS.md +21 -10
  164. package/ds-canonical/fork/codex/hooks.json +1 -1
  165. package/ds-canonical/fork/common/instruction.md +21 -10
  166. package/ds-canonical/fork/consumer/governance-check.mjs +101 -13
  167. package/ds-canonical/fork/consumer/lock.json +14 -15
  168. package/ds-canonical/fork/consumer/managed-files/46f10bc55cdfdf834d0749eebff42ea0bb8576f361b36d2b6ba1851354c50150.blob +26 -3
  169. package/ds-canonical/fork/consumer/managed-files/63061e05969667005020166ea2ae7df3c96663f7a928e7dd3eebc1471022df56.blob +61 -5
  170. package/ds-canonical/fork/consumer/managed-files/93a89f16f6717d1e4e4e27ec20ef916e3355c7aa890ca74cd9b12db30d8a899f.blob +3 -10
  171. package/ds-canonical/fork/consumer/managed-files/bc44cabad181f766611dab6a8f52d81100afadd50ac59799015e8ba7bf46d9eb.blob +3 -2
  172. package/ds-canonical/fork/governance.lock +17 -33
  173. package/ds-canonical/fork/hooks/check_consumer_code_quality.sh +33 -0
  174. package/ds-canonical/fork/hooks/check_pattern_invariants.sh +39 -0
  175. package/ds-canonical/fork/hooks/check_sidebar_menu_button_implicit_wrap.sh +6 -4
  176. package/ds-canonical/fork/launchers/provider-hook-normalization.mjs +5 -11
  177. package/ds-canonical/fork/launchers/settings-hooks.json +2 -2
  178. package/ds-canonical/fork/manifest.json +11 -13
  179. package/ds-canonical/fork/providers/claude/hook-config.json +1 -7
  180. package/ds-canonical/fork/providers/codex/hook-config.json +1 -1
  181. package/ds-canonical/fork/references/story-baseline-registry.json +7 -1
  182. package/ds-canonical/hooks/check_consumer_code_quality.sh +33 -0
  183. package/ds-canonical/hooks/check_pattern_invariants.sh +39 -0
  184. package/ds-canonical/hooks/check_sidebar_menu_button_implicit_wrap.sh +6 -4
  185. package/ds-canonical/hooks/session_start_governance_check.sh +5 -6
  186. package/ds-canonical/hooks/tests/test_check_consumer_code_quality.sh +23 -1
  187. package/ds-canonical/hooks/tests/test_check_pattern_invariants.sh +36 -2
  188. package/ds-canonical/references/audit-coverage-vs-24-checklist.md +1 -1
  189. package/ds-canonical/references/failure-class-registry.json +151 -144
  190. package/ds-canonical/references/preflight-gate-baseline.json +16 -12
  191. package/ds-canonical/references/story-baseline-registry.json +7 -1
  192. package/ds-canonical/rules/meta-patterns.md +3 -3
  193. package/ds-canonical/skills/design-system-audit/SKILL.md +1 -1
  194. package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +1 -1
  195. package/ds-canonical/templates/dashboard-app.tsx +31 -8
  196. package/llms-full.txt +6 -1
  197. package/llms.txt +2 -1
  198. package/package.json +1 -1
  199. package/src/components/Accordion/accordion.principles.stories.tsx +16 -26
  200. package/src/components/Accordion/accordion.stories.tsx +22 -40
  201. package/src/components/AccountMenu/account-menu.anatomy.stories.tsx +115 -0
  202. package/src/components/AccountMenu/account-menu.principles.stories.tsx +99 -0
  203. package/src/components/AccountMenu/account-menu.spec.md +101 -0
  204. package/src/components/AccountMenu/account-menu.stories.tsx +61 -0
  205. package/src/components/AccountMenu/account-menu.tsx +170 -0
  206. package/src/components/AccountMenu/index.ts +5 -0
  207. package/src/components/AppShell/_demo-helpers.tsx +53 -53
  208. package/src/components/AppShell/app-shell.spec.md +5 -1
  209. package/src/components/AppShell/app-shell.tsx +14 -12
  210. package/src/components/Avatar/avatar.principles.stories.tsx +4 -4
  211. package/src/components/Avatar/avatar.stories.tsx +20 -5
  212. package/src/components/Breadcrumb/breadcrumb.spec.md +1 -1
  213. package/src/components/Button/button.spec.md +1 -1
  214. package/src/components/Button/button.stories.tsx +21 -9
  215. package/src/components/Button/button.tsx +5 -4
  216. package/src/components/Calendar/calendar.anatomy.stories.tsx +19 -17
  217. package/src/components/Calendar/calendar.principles.stories.tsx +5 -6
  218. package/src/components/Calendar/calendar.spec.md +25 -29
  219. package/src/components/Calendar/calendar.stories.tsx +5 -7
  220. package/src/components/Calendar/calendar.tsx +75 -87
  221. package/src/components/Carousel/carousel.principles.stories.tsx +5 -1
  222. package/src/components/Chart/chart.spec.md +1 -1
  223. package/src/components/Checkbox/checkbox.anatomy.stories.tsx +14 -5
  224. package/src/components/Chip/chip.spec.md +1 -1
  225. package/src/components/CircularProgress/circular-progress.anatomy.stories.tsx +7 -6
  226. package/src/components/CircularProgress/circular-progress.principles.stories.tsx +8 -6
  227. package/src/components/CircularProgress/circular-progress.stories.tsx +3 -3
  228. package/src/components/Combobox/combobox.tsx +1 -0
  229. package/src/components/Command/command.spec.md +1 -0
  230. package/src/components/Command/command.tsx +4 -1
  231. package/src/components/DataTable/cell-registry.tsx +3 -7
  232. package/src/components/DataTable/data-table-filter-group.tsx +44 -27
  233. package/src/components/DataTable/data-table-filter-labels.ts +100 -0
  234. package/src/components/DataTable/data-table-filter-panel.tsx +48 -8
  235. package/src/components/DataTable/data-table-filter-value-picker.tsx +25 -8
  236. package/src/components/DataTable/data-table.spec.md +18 -1
  237. package/src/components/DataTable/data-table.stories.tsx +346 -33
  238. package/src/components/DataTable/data-table.tsx +11 -4
  239. package/src/components/DataTable/filter-operators.spec.md +2 -2
  240. package/src/components/DateGrid/date-grid.anatomy.stories.tsx +24 -20
  241. package/src/components/DateGrid/date-grid.principles.stories.tsx +27 -21
  242. package/src/components/DateGrid/date-grid.stories.tsx +22 -13
  243. package/src/components/DatePicker/date-picker.anatomy.stories.tsx +3 -3
  244. package/src/components/DatePicker/date-picker.spec.md +4 -4
  245. package/src/components/DatePicker/date-picker.stories.tsx +33 -9
  246. package/src/components/DatePicker/date-picker.tsx +210 -147
  247. package/src/components/Dialog/dialog.spec.md +1 -1
  248. package/src/components/Dialog/dialog.tsx +8 -2
  249. package/src/components/DropdownMenu/dropdown-menu.anatomy.stories.tsx +1 -1
  250. package/src/components/DropdownMenu/dropdown-menu.spec.md +5 -0
  251. package/src/components/DropdownMenu/dropdown-menu.stories.tsx +3 -17
  252. package/src/components/DropdownMenu/dropdown-menu.tsx +58 -16
  253. package/src/components/Field/field-context.ts +25 -1
  254. package/src/components/Field/field-wrapper.tsx +7 -1
  255. package/src/components/Field/field.spec.md +8 -1
  256. package/src/components/Field/field.tsx +14 -2
  257. package/src/components/FieldControlGroup/field-control-group.anatomy.stories.tsx +3 -3
  258. package/src/components/FieldControlGroup/field-control-group.spec.md +2 -3
  259. package/src/components/FieldControlGroup/field-control-group.stories.tsx +2 -1
  260. package/src/components/FieldControlGroup/field-control-group.tsx +6 -9
  261. package/src/components/FileItem/file-item.spec.md +1 -1
  262. package/src/components/FileItem/file-item.stories.tsx +1 -1
  263. package/src/components/FileUpload/file-upload.stories.tsx +32 -0
  264. package/src/components/FileUpload/file-upload.tsx +1 -1
  265. package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +1 -1
  266. package/src/components/FileViewer/file-viewer.spec.md +1 -1
  267. package/src/components/FileViewer/file-viewer.stories.tsx +7 -0
  268. package/src/components/FileViewer/file-viewer.tsx +23 -5
  269. package/src/components/InlineEdit/inline-edit.spec.md +12 -0
  270. package/src/components/InlineEdit/inline-edit.stories.tsx +30 -19
  271. package/src/components/InlineEdit/inline-edit.tsx +94 -31
  272. package/src/components/Input/input.anatomy.stories.tsx +28 -12
  273. package/src/components/Input/input.principles.stories.tsx +23 -18
  274. package/src/components/Input/input.stories.tsx +9 -1
  275. package/src/components/Input/input.tsx +7 -2
  276. package/src/components/LinkInput/link-input.principles.stories.tsx +7 -7
  277. package/src/components/LinkInput/link-input.spec.md +1 -1
  278. package/src/components/LinkInput/link-input.tsx +5 -1
  279. package/src/components/Menu/menu-item.anatomy.stories.tsx +1 -1
  280. package/src/components/Menu/menu-item.tsx +9 -2
  281. package/src/components/NumberInput/number-input.anatomy.stories.tsx +44 -10
  282. package/src/components/NumberInput/number-input.principles.stories.tsx +20 -14
  283. package/src/components/NumberInput/number-input.spec.md +1 -1
  284. package/src/components/NumberInput/number-input.stories.tsx +12 -5
  285. package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +7 -0
  286. package/src/components/PeoplePicker/people-picker.spec.md +3 -1
  287. package/src/components/PeoplePicker/people-picker.tsx +5 -0
  288. package/src/components/Popover/popover.tsx +7 -2
  289. package/src/components/ProgressBar/progress-bar.principles.stories.tsx +14 -12
  290. package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +5 -1
  291. package/src/components/RadioGroup/radio-group.spec.md +1 -1
  292. package/src/components/Rating/rating.principles.stories.tsx +2 -2
  293. package/src/components/ScrollArea/scroll-area.anatomy.stories.tsx +1 -1
  294. package/src/components/ScrollArea/scroll-area.spec.md +3 -3
  295. package/src/components/ScrollArea/scroll-area.tsx +5 -4
  296. package/src/components/Select/select.principles.stories.tsx +4 -3
  297. package/src/components/Select/select.stories.tsx +7 -6
  298. package/src/components/Select/select.tsx +61 -29
  299. package/src/components/SelectMenu/select-menu.spec.md +1 -1
  300. package/src/components/SelectMenu/select-menu.tsx +4 -1
  301. package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +19 -8
  302. package/src/components/SelectionControl/selection-item.stories.tsx +7 -7
  303. package/src/components/Sheet/sheet.spec.md +1 -1
  304. package/src/components/Sidebar/sidebar.spec.md +3 -2
  305. package/src/components/Sidebar/sidebar.stories.tsx +67 -37
  306. package/src/components/Sidebar/sidebar.tsx +3 -3
  307. package/src/components/Slider/slider.principles.stories.tsx +9 -9
  308. package/src/components/Steps/steps.spec.md +1 -0
  309. package/src/components/Steps/steps.stories.tsx +18 -1
  310. package/src/components/Switch/switch.anatomy.stories.tsx +11 -11
  311. package/src/components/Switch/switch.principles.stories.tsx +11 -8
  312. package/src/components/Tabs/tabs.principles.stories.tsx +24 -0
  313. package/src/components/Tabs/tabs.spec.md +6 -4
  314. package/src/components/Tabs/tabs.tsx +11 -0
  315. package/src/components/Tag/tag.anatomy.stories.tsx +5 -2
  316. package/src/components/Tag/tag.spec.md +4 -3
  317. package/src/components/Tag/tag.stories.tsx +19 -0
  318. package/src/components/Tag/tag.tsx +14 -5
  319. package/src/components/Textarea/textarea.anatomy.stories.tsx +15 -9
  320. package/src/components/Textarea/textarea.principles.stories.tsx +21 -5
  321. package/src/components/Textarea/textarea.spec.md +10 -1
  322. package/src/components/Textarea/textarea.tsx +38 -5
  323. package/src/components/TimePicker/time-picker.tsx +11 -5
  324. package/src/components/Tooltip/tooltip.spec.md +10 -0
  325. package/src/components/Tooltip/tooltip.tsx +34 -3
  326. package/src/components/TreeView/tree-view.spec.md +3 -3
  327. package/src/components/TreeView/tree-view.stories.tsx +68 -9
  328. package/src/components/TreeView/tree-view.tsx +7 -2
  329. package/src/index.ts +9 -1
  330. package/src/patterns/element-anatomy/inline-action.spec.md +12 -8
  331. package/src/patterns/element-anatomy/item-anatomy.spec.md +8 -1
  332. package/src/patterns/element-anatomy/item-anatomy.stories.tsx +24 -5
  333. package/src/patterns/element-anatomy/item-anatomy.tsx +120 -35
  334. package/src/patterns/element-anatomy/truncated-text.spec.md +13 -2
  335. package/src/patterns/header-canonical/chrome-header.tsx +14 -5
  336. package/src/patterns/header-canonical/header-canonical.spec.md +10 -7
  337. package/src/patterns/header-canonical/header-canonical.stories.tsx +77 -0
  338. package/src/patterns/horizontal-overflow/horizontal-overflow.stories.tsx +2 -0
  339. package/src/patterns/overlay-surface/overlay-surface.spec.md +1 -0
  340. package/src/patterns/overlay-surface/overlay-surface.stories.tsx +17 -1
  341. package/src/patterns/overlay-surface/overlay-surface.tsx +8 -4
  342. package/src/patterns/resize-handle/resize-handle.spec.md +11 -13
  343. package/src/patterns/resize-handle/resize-handle.stories.tsx +1 -3
  344. package/src/patterns/resize-handle/resize-handle.tsx +13 -18
  345. package/src/tokens/color/semantic.css +3 -1
  346. package/src/tokens/layoutSpace/layoutSpace.stories.tsx +1 -1
  347. package/src/tokens/opacity/opacity.stories.tsx +1 -1
  348. package/src/tokens/radius/radius.stories.tsx +3 -3
  349. package/src/tokens/uiSize/uiSize.css +11 -0
  350. package/src/tokens/uiSize/uiSize.spec.md +1 -0
  351. package/ds-canonical/commands/gov-status.md +0 -9
  352. package/ds-canonical/fork/consumer/managed-files/77e06f62670dfee01e9b5e8b0f8dad085ce711d75538c1fb0679d9818acaca82.blob +0 -424
  353. package/ds-canonical/fork/preamble.md +0 -500
  354. package/ds-canonical/hooks/check_post_main_ssot_propagate.sh +0 -8
  355. package/ds-canonical/hooks/tests/test_check_post_main_ssot_propagate.sh +0 -37
@@ -3,8 +3,8 @@
3
3
  "schemaVersion": 1,
4
4
  "role": "template-consumer",
5
5
  "release": {
6
- "designSystem": "0.1.0-beta.95",
7
- "storybookConfig": "0.1.0-beta.95"
6
+ "designSystem": "0.1.0-beta.99",
7
+ "storybookConfig": "0.1.0-beta.99"
8
8
  },
9
9
  "upgradeTrust": {
10
10
  "schemaVersion": 1,
@@ -42,23 +42,23 @@
42
42
  "implementationSha256": "98b74118fb5b410b77ad2994aa9105fa7609c7353822f8c5213cce54d94f0af4"
43
43
  },
44
44
  "payload": {
45
- "forkCorpusLockSha256": "bc082ec5a102f97d16e9002ec43afb5e5f8b483d3599e0361eab7589ab90a2a9",
45
+ "forkCorpusLockSha256": "effada4fa83d93980edf3d81888ab17f4e682cd0ea985717ab9fcf09b4155314",
46
46
  "discoveryPolicySha256": "fba289aeeb5a3f11139b9589f7ab08b5e8c8799c7bdf8f0ea57ebfeb8e7c9da6",
47
47
  "providerMaterializersSha256": "732e85b01a12e7dd19469e26e4427f0e0cfe5117a78fc9f69c2f0f89702f463a",
48
- "providerLifecycleSha256": "916c040fc796ce937c3de4030db0e441d01f6602d79b2bc12e02b9d7613c7261",
48
+ "providerLifecycleSha256": "56b2c0bc21a4b1ac229fe450863aafec87178eefd753e6057f4f9d5f094e8e1f",
49
49
  "providerInventorySha256": "00adf1c4f6b3367055a9cc3fdfe658660771b4c9931f696e12761a95076ad92c",
50
50
  "executionRuntimeSha256": "3fca4ba4094e855412a22308e13f2b5f91dcfeb009512eb8318b3bd1bace8d9a",
51
- "commonInstructionSha256": "7e58a94ded69eeccf00422dd98ef3672be9c3b40b0cc96ff3bd0dc2f6ed5eda6",
51
+ "commonInstructionSha256": "3d40f4b5d3ea78f6c9ca5bd18daa531dc758d77df21a5e7ef35a3336cd71f906",
52
52
  "providerArtifactDigests": {
53
53
  "claude": {
54
54
  "instructionSha256": "f56a44c730506258cc7e2581dbdd31bfd1e6d13d60dc8a8ee8bcc398228453fb",
55
- "hookSha256": "10ef17ced1b1b4dcb55672a24e880296d39b9cf0a6d7e354af633c3ff0e03d4f",
55
+ "hookSha256": "6398e6b20f6558392bdce1d7123815042047952be473b8fda6d2491aa1648a05",
56
56
  "skillsSha256": "163e473a872d5fa11db9ba7df27f9d316a3c20f89d1ea1cbd002e5f9ada92321",
57
57
  "treeDigests": {}
58
58
  },
59
59
  "codex": {
60
- "instructionSha256": "7e58a94ded69eeccf00422dd98ef3672be9c3b40b0cc96ff3bd0dc2f6ed5eda6",
61
- "hookSha256": "83d373ba11636fd6941f80f9a298056e5c862730275daf623690bf0d6be3582a",
60
+ "instructionSha256": "3d40f4b5d3ea78f6c9ca5bd18daa531dc758d77df21a5e7ef35a3336cd71f906",
61
+ "hookSha256": "697d186cfe0882ee2ce1b02ecc4c3258ab42b125bab6d70c7be868fa271132f7",
62
62
  "skillsSha256": "b80eadd9559d29a50bb7c59ca5f431077174135de79081bbc716cdf64b25bee7",
63
63
  "treeDigests": {}
64
64
  },
@@ -70,9 +70,9 @@
70
70
  }
71
71
  },
72
72
  "mergeSurfaceDigests": {
73
- "claude": "10ef17ced1b1b4dcb55672a24e880296d39b9cf0a6d7e354af633c3ff0e03d4f"
73
+ "claude": "6398e6b20f6558392bdce1d7123815042047952be473b8fda6d2491aa1648a05"
74
74
  },
75
- "governanceCheckSha256": "d0b1f050e4adcf1cb8717d4a890cc03921301107b2f53e820e5e4bdda693c122",
75
+ "governanceCheckSha256": "363b6af5c1e9c87cc11a53bb9868cb17e591c64f5545a09dc66f66e86f70e66f",
76
76
  "utilityRegistrySha256": "310f92cc9aa57880d8f81464ac4191907bda9c9af31847a450497e6a9f97dce3",
77
77
  "sharedSkillsSha256": "138d3bec5497e8109c47788c181f7d2ee3c856f5a84b696eb9364b73ba647bf4",
78
78
  "sharedSkillCount": 11,
@@ -90,9 +90,8 @@
90
90
  ".devcontainer/devcontainer.json": "1668412229466b1e5092218606817711c46c5307b7fc7b77abf6fff089b9b4c7",
91
91
  ".devcontainer/onboard-banner.sh": "fd87b372e48ff079afb0b257c5e5c28fcf58637b2589a508987460a66c2b8b75",
92
92
  ".devcontainer/post-create.mjs": "6bc05d2597a54e8f6a5a087901e92ccc89acc3d5873d96ad20814f8f539a146b",
93
- ".github/workflows/audit.yml": "66bcee0a60de93a992131b92c20d1e397297fa109a2fe8c72dbfd62ebbbe9680",
93
+ ".github/workflows/audit.yml": "3cb259c8d83d8d378a6d282b0cde0a8884d96c51cf49e655405c3e416e646726",
94
94
  ".github/workflows/governance-anchor.yml": "3e280e67fd72886b0686a6d296947ee3270b4899e9914c1e3a9c61c951dcc2ee",
95
- ".github/workflows/sync-design-system.yml": "f25e4d348daf1d98a0c8d0d9c1546d6b8340683ba59ed22aeb0f001378000483",
96
95
  ".npmrc": "79eff2d98653857c11ab6a0354fa62685a72ec214545e7fdfabc450e91b7ba63",
97
96
  "governance/consumer-governance.md": "abbded0a31cf3a6fb0de62975b749d10f27ac0adcc9bbf5e95ef410b64073396",
98
97
  "governance/provider-cli-toolchain.json": "6bc607cb6ac299b332d35ca871c838b54e367d96775ad0e759c827a0e3ca10cc",
@@ -110,19 +109,19 @@
110
109
  "scripts/lib/canonical-path-containment.mjs": "0244e31dc3be5015bed3efd65a5a77086a2e4676e9ac79cd0801c8cde6a74fcd",
111
110
  "scripts/lib/closed-tool-execution.mjs": "131255a302f1b403fe95dd6251e180d7f3ce920faf6cbfe90496b52d192d93c3",
112
111
  "scripts/lib/consumer-control-plane-policy.mjs": "ea8b11ddc5c964ea742ccba5e6a3bc2f215db5d165afe2cca96192812287750c",
113
- "scripts/lib/governance-dependency-bootstrap.mjs": "6779f0e06b01fde7be74ff07be125405808d124811df3cfd77da428e6f618df2",
112
+ "scripts/lib/governance-dependency-bootstrap.mjs": "0b3c22a322174b179a2f499b0c08bbda996f90fac9be29a074bd5b1ae3435ffe",
114
113
  "scripts/lib/provider-lifecycle.mjs": "9aabb2c98efc454b8555308a34830e6590b034b10a63f76f788fbd4cf37ce7e7",
115
114
  "scripts/lib/verified-exact-npm-runtime.mjs": "50f54769a7a32fdc5b97036410018bed87808c2dbdffc47cc292967e5de3da8f",
116
115
  "scripts/lib/workspace-post-create.mjs": "f3ddc6db740d5c4d48b1c6e16c55222325e4d1c16fe6644a455e7b7e5bea0a0d",
117
116
  "scripts/lib/worktree-fingerprint.mjs": "70a8bdbceade964d009f6a46c9e57a93bc9fd58c28971ea14ad1b5ffeaaf7250",
118
117
  "scripts/lint-ds-internal-imports.mjs": "86edd952fb5c3871896515440693abeb08c1d1da9f887fa073b9ddda1363f572",
119
118
  "scripts/product-template-scaffold-lock.mjs": "9134dabf11af7a2445a6a026fc23201e8aba3ef5aeb7da1d2159e92956dd32d2",
120
- "scripts/refresh-fork-launchers.mjs": "1ac397214b92b088c22dbca52495feca2382aa220ad647d93c8c077d1f9148bd",
119
+ "scripts/refresh-fork-launchers.mjs": "763c61964a4a971a664222e5dc0dd54564bdc9430b5a90f56021cca19d48596a",
121
120
  "scripts/release-bom-contract.mjs": "75d736f86c7f695dc88a1982d547998d510e8050c4847abe387227b6662b87c2",
122
121
  "scripts/schemas/product-template-scaffold-lock.schema.json": "1318af59f12546b3cda059a1d94923d9a969bef4c5a476ebb46e42f8c853d19a",
123
122
  "scripts/schemas/release-bom.schema.json": "6969482588a25533dc1896be63c3c9629aced1cbeb745b99822db764682dc4a4",
124
123
  "scripts/schemas/upgrade-evidence-receipt.schema.json": "e2da0a86241d8d019545b63e6285d2ca049ce95fe6aed4264149df2108c4ade0",
125
- "scripts/setup-governance.mjs": "134dd20f0dee07258866c807a827785a3b96c31a6cb821e6b30ce4fe2c680db9",
124
+ "scripts/setup-governance.mjs": "5297a0c6dace974c1233a95825a6ffceef8823373eb4bb96947961f3979e4339",
126
125
  "scripts/setup-provider-cli-toolchain.mjs": "b34e11d02a7aa71d001ef8f1a42af4cf97d1b8b82360f5779cb927370f5ee15a",
127
126
  "scripts/setup-workspace.mjs": "95dc0fef1f7570efe277a66f7edf4640055ad6abbae0245615eceb9b041560e9",
128
127
  "scripts/sync-all.mjs": "938c706cad79a4bd538359c9b74cb9253a4c74b5f1342cbfc1625600425d8bfd",
@@ -15,6 +15,10 @@ import {
15
15
  export const GOVERNANCE_DEPENDENCY_REGISTRY = 'https://registry.npmjs.org/'
16
16
  export const GOVERNANCE_DEPENDENCY_MINIMUM_NODE_VERSION = '22.13.0'
17
17
  export const GOVERNANCE_DEPENDENCY_EXACT_NPM_VERSION = '11.18.0'
18
+ export const GOVERNANCE_CLOSED_PROJECT_NPM_CONFIG_LINES = Object.freeze([
19
+ 'legacy-peer-deps=true',
20
+ 'ignore-scripts=true',
21
+ ])
18
22
  export const GOVERNANCE_DEPENDENCY_REQUIRED_EXECUTABLES = Object.freeze(['bash', 'git', 'jq', 'python3'])
19
23
  export const GOVERNANCE_DEPENDENCY_NPM_STEPS = Object.freeze([
20
24
  Object.freeze(['ci', '--legacy-peer-deps', '--ignore-scripts', `--registry=${GOVERNANCE_DEPENDENCY_REGISTRY}`]),
@@ -229,25 +233,44 @@ function exactArray(value, expected) {
229
233
  && value.every((entry, index) => entry === expected[index])
230
234
  }
231
235
 
236
+ const VERIFIED_BRACE_EXPANSION_AUDIT_PREIMAGES = Object.freeze([
237
+ Object.freeze({
238
+ source: 1124334,
239
+ findingRange: '<=5.0.7',
240
+ advisoryRange: '<=5.0.7',
241
+ }),
242
+ Object.freeze({
243
+ source: 1130591,
244
+ findingRange: '4.0.0 - 5.0.7',
245
+ advisoryRange: '>=4.0.0 <5.0.8',
246
+ }),
247
+ ])
248
+
249
+ function matchesVerifiedBraceExpansionAuditPreimage(finding) {
250
+ return VERIFIED_BRACE_EXPANSION_AUDIT_PREIMAGES.some((preimage) => (
251
+ finding.range === preimage.findingRange
252
+ && finding.via[0]?.source === preimage.source
253
+ && finding.via[0]?.range === preimage.advisoryRange
254
+ ))
255
+ }
256
+
232
257
  function assertRemediatedHighFinding(name, finding, installedOverlayReceipt) {
233
258
  invariant(finding && typeof finding === 'object' && !Array.isArray(finding), `npm audit high finding is malformed:${name}`)
234
259
  invariant(finding.name === name && finding.severity === 'high', `npm audit high finding identity drifted:${name}`)
235
260
  if (name === 'brace-expansion') {
236
261
  invariant(
237
262
  finding.isDirect === false
238
- && finding.range === '<=5.0.7'
239
263
  && exactArray(finding.nodes, ['node_modules/npm/node_modules/brace-expansion'])
240
264
  && Array.isArray(finding.effects)
241
265
  && finding.effects.length <= 1
242
266
  && finding.effects.every((effect) => effect === 'minimatch')
243
267
  && Array.isArray(finding.via)
244
268
  && finding.via.length === 1
245
- && finding.via[0]?.source === 1124334
246
269
  && finding.via[0]?.name === 'brace-expansion'
247
270
  && finding.via[0]?.dependency === 'brace-expansion'
248
271
  && finding.via[0]?.url === 'https://github.com/advisories/GHSA-mh99-v99m-4gvg'
249
272
  && finding.via[0]?.severity === 'high'
250
- && finding.via[0]?.range === '<=5.0.7',
273
+ && matchesVerifiedBraceExpansionAuditPreimage(finding),
251
274
  'npm audit brace-expansion finding differs from the exact remediated bundled preimage',
252
275
  )
253
276
  return
@@ -250,10 +250,29 @@ export function mergeProviderHookSettings({ settings, canonicalConfig, policy, l
250
250
  throw new Error(`${label} ${hooksField} must be an object`)
251
251
  }
252
252
  const retiredIds = []
253
+ // F6 fail-closed:canonical hook map 必須存在、非空,且每 event 都是非空合形的 group 陣列。
254
+ // 寬鬆 fallback(`|| {}` / `Array.isArray ? : []`)會把「看不懂的另一世代 artifact 形狀」當
255
+ // 「零 hooks」:下方 strip(canonicalCommands / refsLauncher)照跑、append 卻是空 → 靜默清空
256
+ // 治理 hooks(WM 1f71fec 同型事故)。禁止。
257
+ const canonicalHookMap = canonicalConfig[hooksField]
258
+ if (!canonicalHookMap || typeof canonicalHookMap !== 'object' || Array.isArray(canonicalHookMap) || !Object.keys(canonicalHookMap).length) {
259
+ throw new Error(
260
+ `${label}: canonical hook artifact carries no non-empty ${JSON.stringify(hooksField)} map — the installed corpus uses a schema generation this scripts/refresh-fork-launchers.mjs does not understand; `
261
+ + 'refusing to write (an empty merge would silently strip every governance hook). '
262
+ + 'Migrate the fork scaffold to the matching generation first (npm run sync-all -- --apply --to <exact-version>).'
263
+ )
264
+ }
253
265
  const canonicalCommands = new Set()
254
- for (const groups of Object.values(canonicalConfig[hooksField] || {})) for (const group of Array.isArray(groups) ? groups : []) {
255
- for (const handler of Array.isArray(group?.hooks) ? group.hooks : []) {
256
- if (typeof handler?.command === 'string' && handler.command) canonicalCommands.add(handler.command)
266
+ for (const [event, groups] of Object.entries(canonicalHookMap)) {
267
+ if (!Array.isArray(groups) || !groups.length) throw new Error(`${label} canonical ${hooksField}.${event} must be a non-empty array`)
268
+ for (const group of groups) {
269
+ if (!group || typeof group !== 'object' || Array.isArray(group) || !Array.isArray(group.hooks) || !group.hooks.length) {
270
+ throw new Error(`${label} canonical ${hooksField}.${event} contains an invalid or empty hook group`)
271
+ }
272
+ for (const handler of group.hooks) {
273
+ if (typeof handler?.command !== 'string' || !handler.command) throw new Error(`${label} canonical ${hooksField}.${event} contains a hook without a command`)
274
+ canonicalCommands.add(handler.command)
275
+ }
257
276
  }
258
277
  }
259
278
  const retainedHooks = {}
@@ -286,9 +305,16 @@ export function mergeProviderHookSettings({ settings, canonicalConfig, policy, l
286
305
  // the authenticated canonical groups exactly once. This keeps refresh idempotent without turning
287
306
  // a provider adapter update into authority over unrelated product automation.
288
307
  merged[hooksField] = retainedHooks
289
- for (const [event, groups] of Object.entries(canonicalConfig[hooksField] || {})) {
308
+ for (const [event, groups] of Object.entries(canonicalHookMap)) {
290
309
  merged[hooksField][event] = [...(merged[hooksField][event] || []), ...structuredClone(groups)]
291
310
  }
311
+ // Never-empty postcondition(F6 迴歸絆網):merge 結果必含每個 canonical event 的註冊,
312
+ // 否則代表上游 shape 判定失守 → 寧可 throw 也不寫出被清空的 hook surface。
313
+ for (const event of Object.keys(canonicalHookMap)) {
314
+ if (!Array.isArray(merged[hooksField][event]) || !merged[hooksField][event].length) {
315
+ throw new Error(`${label}: merged ${hooksField}.${event} lost its canonical registrations — refusing to write an emptied hook surface`)
316
+ }
317
+ }
292
318
  for (const [key, value] of Object.entries(canonicalConfig)) {
293
319
  if (key === hooksField || key === 'permissions' || key === 'disableAutoMode') continue
294
320
  merged[key] = structuredClone(value)
@@ -324,7 +350,8 @@ export function mergeProviderHookSettings({ settings, canonicalConfig, policy, l
324
350
  merged.permissions.deny = nextDeny
325
351
  merged.permissions.defaultMode = canonicalPermissions.defaultMode
326
352
  merged.permissions.disableBypassPermissionsMode = canonicalPermissions.disableBypassPermissionsMode
327
- merged.disableAutoMode = canonicalConfig.disableAutoMode
353
+ if (Object.hasOwn(canonicalConfig, 'disableAutoMode')) throw new Error(`${label} canonical permission base carries the retired disableAutoMode flag`)
354
+ delete merged.disableAutoMode
328
355
  delete merged.permissions.disableAutoMode
329
356
  delete merged.defaultMode
330
357
  } else if (policy.baseTemplate.engine === 'static-json-object-v1') {
@@ -336,7 +363,27 @@ export function mergeProviderHookSettings({ settings, canonicalConfig, policy, l
336
363
  return { settings: merged, retiredIds: retiredIds.sort() }
337
364
  }
338
365
 
366
+ // ── F6 fail-closed schema generation gate(WM commit 1f71fec 教訓)──
367
+ // 舊代 refresh 對新代 settings-hooks.json 用 `canonical.hooks || {}` 寬鬆 fallback,把「看不懂的
368
+ // 另一世代 schema」當「零 hooks」:strip 舊治理註冊照跑、append 卻是空 → 靜默清空
369
+ // .claude/settings.json hooks = Claude 端治理整條斷線。本 gate 是唯一 generation 判定 SSOT:
370
+ // kind + schemaVersion 必須 exact match 本腳本世代,否則丟含遷移指引的錯誤;絕不寫檔。
371
+ export const SETTINGS_HOOKS_KIND = 'provider-hook-merge-policies'
372
+ export const SETTINGS_HOOKS_SCHEMA_VERSION = 1
373
+
374
+ export function assertSupportedSettingsHooksGeneration(value, label = 'installed launchers/settings-hooks.json') {
375
+ const record = value && typeof value === 'object' && !Array.isArray(value) ? value : {}
376
+ if (record.kind === SETTINGS_HOOKS_KIND && record.schemaVersion === SETTINGS_HOOKS_SCHEMA_VERSION) return
377
+ throw new Error(
378
+ `${label} declares kind=${JSON.stringify(record.kind ?? null)} schemaVersion=${JSON.stringify(record.schemaVersion ?? null)}, `
379
+ + `but this scripts/refresh-fork-launchers.mjs generation understands exactly ${SETTINGS_HOOKS_KIND}@${SETTINGS_HOOKS_SCHEMA_VERSION}. `
380
+ + 'Refusing to merge provider hooks; nothing was written. Merging an ununderstood generation is exactly how an older scaffold silently emptied .claude/settings.json hooks. '
381
+ + 'Migrate this fork scaffold to the generation matching the installed corpus first (npm run sync-all -- --apply --to <exact-version>), then re-run.'
382
+ )
383
+ }
384
+
339
385
  export function validateCanonicalSettingsWiring(value, manifest) {
386
+ assertSupportedSettingsHooksGeneration(value)
340
387
  exactKeys(value, ['_generated', 'kind', 'schemaVersion', 'sourceDigest', 'surfaces'], 'installed provider hook merge policies')
341
388
  if (
342
389
  value._generated !== 'build-fork-governance.mjs'
@@ -2050,6 +2097,15 @@ export function refreshLaunchers(projectDir, opts = {}) {
2050
2097
  const src = join(candidateForkRoot, 'launchers')
2051
2098
  assertSafeTree(projectDir, src, 'installed launcher corpus', { allowMissing: true })
2052
2099
  if (!existsSync(join(src, 'settings-hooks.json'))) {
2100
+ // 只有「治理 corpus 整個不在」才是合法 skip(舊 npm / 未安裝)。corpus 在、卻沒有本世代的
2101
+ // settings-hooks.json = 另一世代把 merge policy 搬走了 → fail-closed throw,絕不靜默 skip
2102
+ //(F6 對偶:靜默 skip 讓 fork 永遠停在 stale 接線,治理斷線無人知)。
2103
+ if (existsSync(join(candidateForkRoot, 'manifest.json'))) {
2104
+ throw new Error(
2105
+ 'installed fork corpus exists but ships no launchers/settings-hooks.json — the installed release uses a scaffold generation this scripts/refresh-fork-launchers.mjs does not understand; '
2106
+ + 'migrate the fork scaffold first (npm run sync-all -- --apply --to <exact-version>) instead of refreshing with this script generation.'
2107
+ )
2108
+ }
2053
2109
  result.skipped = 'launchers 未 ship(npm 套件版本過舊或治理本體未安裝)'
2054
2110
  return result
2055
2111
  }
@@ -11,6 +11,7 @@ permissions:
11
11
 
12
12
  jobs:
13
13
  audit:
14
+ name: Verify consumer
14
15
  runs-on: ubuntu-24.04
15
16
  timeout-minutes: 15
16
17
  steps:
@@ -22,8 +23,8 @@ jobs:
22
23
  node-version: '24.14.0'
23
24
  cache: npm
24
25
 
25
- - name: Lock-verified exact npm install, audits and provider-neutral hard gate
26
- run: npm run setup:governance
26
+ - name: Install exact locked dependencies
27
+ run: npm ci --ignore-scripts
27
28
 
28
29
  - name: Type-check
29
30
  run: npm run typecheck
@@ -33,11 +34,3 @@ jobs:
33
34
 
34
35
  - name: Build all apps
35
36
  run: npm run build
36
-
37
- - name: Install Playwright browsers
38
- run: npx --no-install playwright install --with-deps chromium
39
-
40
- - name: A11y audit consumer apps(WCAG 2 A + AA)
41
- # Phase 5 加 — DS repo 跑 npm run a11y:check on storybook;ds-product-template
42
- # 跑 audit-consumer-a11y.mjs on apps/*/dist。對等 DS audit 嚴謹度。
43
- run: npm run audit:a11y
@@ -27,6 +27,7 @@ import {
27
27
  import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path'
28
28
  import { fileURLToPath } from 'node:url'
29
29
  import {
30
+ GOVERNANCE_CLOSED_PROJECT_NPM_CONFIG_LINES,
30
31
  GOVERNANCE_DEPENDENCY_EXACT_NPM_VERSION,
31
32
  GOVERNANCE_DEPENDENCY_MINIMUM_NODE_VERSION,
32
33
  GOVERNANCE_DEPENDENCY_NPM_STEPS,
@@ -392,7 +393,7 @@ function readRegularJson(path, label) {
392
393
  }
393
394
 
394
395
  function assertClosedProjectNpmConfig(root) {
395
- return assertClosedProjectNpmConfigShared(root, ['legacy-peer-deps=true', 'ignore-scripts=true'], { errorPrefix: 'GOV-SETUP-001' })
396
+ return assertClosedProjectNpmConfigShared(root, GOVERNANCE_CLOSED_PROJECT_NPM_CONFIG_LINES, { errorPrefix: 'GOV-SETUP-001' })
396
397
  }
397
398
 
398
399
  export function assertSupportedSetupPlatform(platform = process.platform) {
@@ -476,7 +477,7 @@ async function runGovernanceDependencyBootstrap({
476
477
  runner,
477
478
  ...(runtimeFactory ? { runtimeFactory } : {}),
478
479
  authorityPaths: SETUP_AUTHORITY_PATHS,
479
- expectedNpmrcLines: ['legacy-peer-deps=true', 'ignore-scripts=true'],
480
+ expectedNpmrcLines: GOVERNANCE_CLOSED_PROJECT_NPM_CONFIG_LINES,
480
481
  errorPrefix: 'GOV-SETUP-001',
481
482
  validateRoleRepository: assertCommittedSetupSnapshot,
482
483
  afterStage({ index }) {
@@ -7,7 +7,7 @@
7
7
  {
8
8
  "schemaVersion": 1,
9
9
  "file": "AGENTS.md",
10
- "sha256": "7e58a94ded69eeccf00422dd98ef3672be9c3b40b0cc96ff3bd0dc2f6ed5eda6",
10
+ "sha256": "3d40f4b5d3ea78f6c9ca5bd18daa531dc758d77df21a5e7ef35a3336cd71f906",
11
11
  "source": "common instruction compatibility alias",
12
12
  "classification": null,
13
13
  "destination": null
@@ -255,7 +255,7 @@
255
255
  {
256
256
  "schemaVersion": 1,
257
257
  "file": "codex/hooks.json",
258
- "sha256": "83d373ba11636fd6941f80f9a298056e5c862730275daf623690bf0d6be3582a",
258
+ "sha256": "697d186cfe0882ee2ce1b02ecc4c3258ab42b125bab6d70c7be868fa271132f7",
259
259
  "source": "providers/codex/hook-config.json",
260
260
  "classification": null,
261
261
  "destination": null
@@ -271,7 +271,7 @@
271
271
  {
272
272
  "schemaVersion": 1,
273
273
  "file": "common/instruction.md",
274
- "sha256": "7e58a94ded69eeccf00422dd98ef3672be9c3b40b0cc96ff3bd0dc2f6ed5eda6",
274
+ "sha256": "3d40f4b5d3ea78f6c9ca5bd18daa531dc758d77df21a5e7ef35a3336cd71f906",
275
275
  "source": "scripts/fork-role-sources/AGENTS.product.md + AGENTS.md#canonical-decision-authority",
276
276
  "classification": null,
277
277
  "destination": null
@@ -279,7 +279,7 @@
279
279
  {
280
280
  "schemaVersion": 1,
281
281
  "file": "consumer/governance-check.mjs",
282
- "sha256": "d0b1f050e4adcf1cb8717d4a890cc03921301107b2f53e820e5e4bdda693c122",
282
+ "sha256": "363b6af5c1e9c87cc11a53bb9868cb17e591c64f5545a09dc66f66e86f70e66f",
283
283
  "source": "scripts/governance-check.mjs",
284
284
  "classification": null,
285
285
  "destination": null
@@ -359,7 +359,7 @@
359
359
  {
360
360
  "schemaVersion": 1,
361
361
  "file": "consumer/managed-files/46f10bc55cdfdf834d0749eebff42ea0bb8576f361b36d2b6ba1851354c50150.blob",
362
- "sha256": "6779f0e06b01fde7be74ff07be125405808d124811df3cfd77da428e6f618df2",
362
+ "sha256": "0b3c22a322174b179a2f499b0c08bbda996f90fac9be29a074bd5b1ae3435ffe",
363
363
  "source": "scripts/lib/governance-dependency-bootstrap.mjs",
364
364
  "classification": null,
365
365
  "destination": "scripts/lib/governance-dependency-bootstrap.mjs"
@@ -383,7 +383,7 @@
383
383
  {
384
384
  "schemaVersion": 1,
385
385
  "file": "consumer/managed-files/63061e05969667005020166ea2ae7df3c96663f7a928e7dd3eebc1471022df56.blob",
386
- "sha256": "1ac397214b92b088c22dbca52495feca2382aa220ad647d93c8c077d1f9148bd",
386
+ "sha256": "763c61964a4a971a664222e5dc0dd54564bdc9430b5a90f56021cca19d48596a",
387
387
  "source": "scripts/refresh-fork-launchers.mjs",
388
388
  "classification": null,
389
389
  "destination": "scripts/refresh-fork-launchers.mjs"
@@ -420,14 +420,6 @@
420
420
  "classification": null,
421
421
  "destination": "scripts/lib/provider-lifecycle.mjs"
422
422
  },
423
- {
424
- "schemaVersion": 1,
425
- "file": "consumer/managed-files/77e06f62670dfee01e9b5e8b0f8dad085ce711d75538c1fb0679d9818acaca82.blob",
426
- "sha256": "f25e4d348daf1d98a0c8d0d9c1546d6b8340683ba59ed22aeb0f001378000483",
427
- "source": "template/ds-product-template/.github/workflows/sync-design-system.yml",
428
- "classification": null,
429
- "destination": ".github/workflows/sync-design-system.yml"
430
- },
431
423
  {
432
424
  "schemaVersion": 1,
433
425
  "file": "consumer/managed-files/7937321877e5c34c27dae36c0d507d21cd42fa3f46a8f11a284b8b4a52b6faa4.blob",
@@ -495,7 +487,7 @@
495
487
  {
496
488
  "schemaVersion": 1,
497
489
  "file": "consumer/managed-files/93a89f16f6717d1e4e4e27ec20ef916e3355c7aa890ca74cd9b12db30d8a899f.blob",
498
- "sha256": "66bcee0a60de93a992131b92c20d1e397297fa109a2fe8c72dbfd62ebbbe9680",
490
+ "sha256": "3cb259c8d83d8d378a6d282b0cde0a8884d96c51cf49e655405c3e416e646726",
499
491
  "source": "template/ds-product-template/.github/workflows/audit.yml",
500
492
  "classification": null,
501
493
  "destination": ".github/workflows/audit.yml"
@@ -535,7 +527,7 @@
535
527
  {
536
528
  "schemaVersion": 1,
537
529
  "file": "consumer/managed-files/bc44cabad181f766611dab6a8f52d81100afadd50ac59799015e8ba7bf46d9eb.blob",
538
- "sha256": "134dd20f0dee07258866c807a827785a3b96c31a6cb821e6b30ce4fe2c680db9",
530
+ "sha256": "5297a0c6dace974c1233a95825a6ffceef8823373eb4bb96947961f3979e4339",
539
531
  "source": "scripts/setup-governance.mjs",
540
532
  "classification": null,
541
533
  "destination": "scripts/setup-governance.mjs"
@@ -679,7 +671,7 @@
679
671
  {
680
672
  "schemaVersion": 1,
681
673
  "file": "hooks/check_consumer_code_quality.sh",
682
- "sha256": "70a415fc8c8ee7676426a4f59c24352225ae77145b8cff7199bda32c0e6d70e9",
674
+ "sha256": "32b8e4d32426c0915c4afe2ad3d1e9a84a1de59549f4da68743457bebda17bfd",
683
675
  "source": "check_consumer_code_quality.sh",
684
676
  "classification": "SHIP_REWRITTEN",
685
677
  "destination": null
@@ -751,7 +743,7 @@
751
743
  {
752
744
  "schemaVersion": 1,
753
745
  "file": "hooks/check_pattern_invariants.sh",
754
- "sha256": "470bb101b61a6280670315b710b955be8fd4007f642ea1d98cbf3ade40ded326",
746
+ "sha256": "9618abe020720ccd7e797704d66516fc019579ae32750990642047f994355a7d",
755
747
  "source": "check_pattern_invariants.sh",
756
748
  "classification": "SHIP_AS_IS",
757
749
  "destination": null
@@ -759,7 +751,7 @@
759
751
  {
760
752
  "schemaVersion": 1,
761
753
  "file": "hooks/check_sidebar_menu_button_implicit_wrap.sh",
762
- "sha256": "ee890af41da3ca7981dd7dde3d86c635e507541b3a7c8ed131db39d26a5d971c",
754
+ "sha256": "0f435cfb643dd872c4019045b4351df05cdd62222df2bee9a70a69c6a8cdcbe8",
763
755
  "source": "check_sidebar_menu_button_implicit_wrap.sh",
764
756
  "classification": "SHIP_AS_IS",
765
757
  "destination": null
@@ -895,7 +887,7 @@
895
887
  {
896
888
  "schemaVersion": 1,
897
889
  "file": "launchers/provider-hook-normalization.mjs",
898
- "sha256": "3b574773dda4b383aaeb8dc8263f0d12735445073b2b0ccb996b473eaa297278",
890
+ "sha256": "fe7dffbd9e3dd8a2b423765c48ef9200bbd5705870eedcae8a088575d5dd4e1a",
899
891
  "source": "packages/governance/src/provider-hook-normalization.mjs",
900
892
  "classification": null,
901
893
  "destination": null
@@ -911,7 +903,7 @@
911
903
  {
912
904
  "schemaVersion": 1,
913
905
  "file": "launchers/settings-hooks.json",
914
- "sha256": "84b9191b34cb371fa7829eb846cef043ae8612b04cac6e5683395017708cf020",
906
+ "sha256": "41e4883c64d7e0676c49e2dc0cbeed2c85ab25e7d3574344d6cd5af4b8e79cfe",
915
907
  "source": "packages/design-system/ds-canonical/templates/product-provider-wiring.json + packages/governance/canonical/providers.json",
916
908
  "classification": null,
917
909
  "destination": null
@@ -919,23 +911,15 @@
919
911
  {
920
912
  "schemaVersion": 1,
921
913
  "file": "manifest.json",
922
- "sha256": "9cacf3be73cf7c29805a37035bcbf370a6811bd910157b17f6fece5f8b19371c",
914
+ "sha256": "bbbc8e873f6190eca96592b7fa98ead61af0f0359036ef70917ea2c269a2a677",
923
915
  "source": null,
924
916
  "classification": null,
925
917
  "destination": null
926
918
  },
927
- {
928
- "schemaVersion": 1,
929
- "file": "preamble.md",
930
- "sha256": "70f3402061f420c9026d5cd69ac3f070fd3457cb8ad506685372fcda1b2be1fb",
931
- "source": "control-plane-genesis-am-only-v1:25b39558cbf352f053948190bb28326a78562f43:packages/design-system/ds-canonical/fork/preamble.md",
932
- "classification": null,
933
- "destination": null
934
- },
935
919
  {
936
920
  "schemaVersion": 1,
937
921
  "file": "providers/claude/hook-config.json",
938
- "sha256": "10ef17ced1b1b4dcb55672a24e880296d39b9cf0a6d7e354af633c3ff0e03d4f",
922
+ "sha256": "6398e6b20f6558392bdce1d7123815042047952be473b8fda6d2491aa1648a05",
939
923
  "source": "packages/design-system/ds-canonical/templates/product-provider-wiring.json + providers.json:claude",
940
924
  "classification": null,
941
925
  "destination": null
@@ -1183,7 +1167,7 @@
1183
1167
  {
1184
1168
  "schemaVersion": 1,
1185
1169
  "file": "providers/codex/hook-config.json",
1186
- "sha256": "83d373ba11636fd6941f80f9a298056e5c862730275daf623690bf0d6be3582a",
1170
+ "sha256": "697d186cfe0882ee2ce1b02ecc4c3258ab42b125bab6d70c7be868fa271132f7",
1187
1171
  "source": "packages/design-system/ds-canonical/templates/product-provider-wiring.json + providers.json:codex",
1188
1172
  "classification": null,
1189
1173
  "destination": null
@@ -1423,7 +1407,7 @@
1423
1407
  {
1424
1408
  "schemaVersion": 1,
1425
1409
  "file": "references/story-baseline-registry.json",
1426
- "sha256": "2d24dcee790d72742e91a4f49c2303da02c27fca6733131d235ea29551a80f5a",
1410
+ "sha256": "cac3bbf5adff25302e78ac689c48204986c43ce41eb56161ccee1e14557ba56d",
1427
1411
  "source": "packages/design-system/ds-canonical/references/story-baseline-registry.json",
1428
1412
  "classification": null,
1429
1413
  "destination": null
@@ -133,6 +133,39 @@ if grep -Eq 'layout="primary-header"|layout=\{('\''|")primary-header('\''|")\}'
133
133
  if [ -n "$PRIMARY" ] && ! has_rationale '@app-shell-primary-header-allow'; then VIOLATIONS="${VIOLATIONS}${PRIMARY}"; fi
134
134
  fi
135
135
 
136
+ # 帳號入口 duplicate(2026-07-30 WM F9 layer 3;app-shell.spec.md「帳號入口放置 SSOT」:帳號入口只能出現一次)。
137
+ # 上段攔「宣告 primary-header + SidebarFooter」;本段補 mode 字面不在檔內的 dual-entry 缺口(WM 錨例 =
138
+ # apps/work/src/App.tsx pre-fix 1a26bd1^:SidebarHeader 右上 avatar 帳號選單與 SidebarFooter user 區並存):
139
+ # header 帳號簽名 = SidebarHeader block 內 <AccountMenu> OR(<DropdownMenuTrigger> + <Avatar>/<ItemAvatar>
140
+ # + account/logout 語彙);footer user 簽名 = SidebarFooter block 內 <Avatar>/<ItemAvatar>/<AccountMenu>。
141
+ # 零誤判 bound(M23 R9 零誤判簽名 precedent;DS apps/template/src + WM 全 corpus 實測 0 hit、錨例 fire):
142
+ # - workspace switcher in header(trigger+avatar、無 account/logout 語彙)不中 — 語彙 conjunction;
143
+ # - mobile Sheet 鏡像(header AccountMenu、footer 無 user 區,app-shell.spec.md Responsive 子句)不中;
144
+ # - 多 mode demo 檔(primary-header + primary-sidebar 字面並存)skip → 跨 story 誤攔防護,歸 product-ui-audit;
145
+ # - BODY 已 strip 註解(WM 修復檔 SidebarHeader 註解即含「帳號入口」字樣);local 同名元件不中和 —
146
+ # duplicate 語義違規與 primitive 來源無關。
147
+ ACCOUNT_DUP=$(printf '%s' "$BODY" | python3 -c '
148
+ import re, sys
149
+ content = sys.stdin.read()
150
+ account = re.compile(r"[Aa]ccount|[Ll]og\s?-?[Oo]ut|LogOut|[Ss]ign\s?-?[Oo]ut|SignOut|登出|個人資料|帳號")
151
+ headers = re.findall(r"<SidebarHeader\b[^>]*>.*?</SidebarHeader>", content, re.DOTALL)
152
+ footers = re.findall(r"<SidebarFooter\b[^>]*>.*?</SidebarFooter>", content, re.DOTALL)
153
+ header_account = any(
154
+ re.search(r"<AccountMenu\b", b)
155
+ or (re.search(r"<DropdownMenuTrigger\b", b)
156
+ and re.search(r"<(Avatar|ItemAvatar)\b", b)
157
+ and account.search(b))
158
+ for b in headers)
159
+ footer_user = any(re.search(r"<(Avatar|ItemAvatar|AccountMenu)\b", b) for b in footers)
160
+ multi_mode = ("primary-header" in content) and ("primary-sidebar" in content)
161
+ if header_account and footer_user and not multi_mode:
162
+ print("DUP")
163
+ ' 2>/dev/null) \
164
+ || governance_hook_integrity_fail 'consumer quality account-entry scanner failed'
165
+ if [ "$ACCOUNT_DUP" = "DUP" ] && ! has_rationale '@account-entry-allow'; then
166
+ add_violation 'duplicate account entry: SidebarHeader account menu + SidebarFooter user area coexist; app-shell.spec.md 帳號入口只能出現一次(primary-sidebar → SidebarFooter / primary-header → globalHeader 右);escape @account-entry-allow: <rationale>'
167
+ fi
168
+
136
169
  if [ -n "$VIOLATIONS" ]; then
137
170
  printf 'GOV-CONSUMER-QUALITY-001:%b\nFile:%s\n' "$VIOLATIONS" "$FILE_PATH" >&2
138
171
  exit 2
@@ -6,6 +6,7 @@
6
6
  # C.2 inline-action canonical gap(原 check_inline_action_canonical_gap,P1 WARN context)
7
7
  # C.3 primitive wrapper padding(原 check_primitive_wrapper_padding,P0 BLOCK exit 2)
8
8
  # C.4 row slot handcraft(原 check_row_slot_handcraft,P0 BLOCK exit 2)
9
+ # C.5 弱化 icon hover 階梯(2026-07-30 user 拍板,P0 BLOCK exit 2)
9
10
  #
10
11
  # Why merge:皆 element-anatomy / overlay-surface SSOT 消費紀律 invariant,共用 INPUT
11
12
  # parsing + tsx filter,散裝是 M17 + Anthropic ≤ 15 hook best-practice 偏離。
@@ -17,6 +18,7 @@
17
18
  # C.2: `// @inline-action-gap-allow: <reason>`(any line)
18
19
  # C.3: `// @primitive-padding-allow: <reason>`(檔案前 5 行)
19
20
  # C.4: `// @row-slot-handcraft-allow: <reason>`(any line)
21
+ # C.5: `// @hover-ramp-allow: <reason>`(any line)
20
22
 
21
23
  source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
22
24
 
@@ -174,6 +176,43 @@ EOF
174
176
  ;;
175
177
  esac
176
178
 
179
+
180
+ # ── C.5 弱化 icon hover 階梯(P0 BLOCK exit 2;2026-07-30 user 拍板)─────────────
181
+ # Root invariant:hover 往前一階,不跳階。rest \`text-fg-muted\`(neutral-7)的弱化 icon
182
+ # hover 必 \`text-fg-secondary\`(neutral-8),不得直接跳 \`text-foreground\`(neutral-9)。
183
+ # rule owner = inline-action.spec.md「Icon 色彩」段 + tokens/color/semantic.css:53。
184
+ # 世界級:Fluent 2 neutralForeground3Hover === neutralForeground2 / MUI Chip deleteIcon .26→.4。
185
+ # 錨例:2026-04-08 97e62a80 為修「colored Tag 上 fg-muted 不連貫」而 unified 全 variant 繼承文字色,
186
+ # 連中性宿主一起改且未經 user 拍板;primitive 本身也一直跳兩階,四個月無機械防線。
187
+ # rest 已是 fg-secondary 的整列/文字 hover(→ foreground)本身就是一階,不在射程內。
188
+ case "$FILE_PATH" in
189
+ *components/*.tsx|*patterns/*.tsx|*.css)
190
+ if ! grep -q '@hover-ramp-allow' <<<"$NEW_CONTENT"; then
191
+ SKIP_RAMP=$(grep -m 3 -nE 'text-fg-muted[^"'"'"'\`]*hover:text-foreground|hover:text-foreground[^"'"'"'\`]*text-fg-muted' <<<"$NEW_CONTENT" || true)
192
+ if [ -n "$SKIP_RAMP" ]; then
193
+ cat >&2 <<EOF
194
+
195
+ ┄┄┄ C.5 check_pattern_invariants — 弱化 icon hover 跳階 BLOCK ┄┄┄
196
+
197
+ [P0] ${FILE_PATH}
198
+ rest \`text-fg-muted\` 的弱化 icon 直接 hover 到 \`text-foreground\`(跳兩階):
199
+ ${SKIP_RAMP}
200
+
201
+ ❌ inline-action.spec.md「Icon 色彩」+ tokens/color/semantic.css:53:
202
+ 弱化 icon hover 後變 \`fg-secondary\`(neutral-8),不是 \`foreground\`(neutral-9)。
203
+ 世界級對照:Fluent 2 neutralForeground3Hover = neutralForeground2 / MUI Chip deleteIcon .26→.4。
204
+
205
+ 修法:\`hover:text-foreground\` → \`hover:text-fg-secondary\`(active 同步);
206
+ 優先直接消費 \`ItemInlineActionButton\`(primitive 已內建正確階梯)而非手刻。
207
+ 真有理由跳階 → 加 \`// @hover-ramp-allow: <rationale>\` 行豁免。
208
+
209
+ EOF
210
+ exit 2
211
+ fi
212
+ fi
213
+ ;;
214
+ esac
215
+
177
216
  # ── C.3 primitive wrapper padding(P0 BLOCK exit 2)───────────────────────────
178
217
  # File-level allowlist:檔頭前 5 行
179
218
  ALLOW_C3=0
@@ -5,9 +5,10 @@
5
5
  # SidebarMenuButton(sidebar.tsx L1036-1043)在沒 asChild 時把所有 children 塞進 <ItemLabel> 單一 span,
6
6
  # Avatar + text-span 都在同 span 內 → 強迫垂直堆疊。
7
7
  #
8
- # Canonical:含 Avatar/ItemAvatar/icon prefix 的 SidebarMenuButton 必用 asChild + <div> wrap,
8
+ # Canonical:含 Avatar/ItemAvatar/icon prefix 的 SidebarMenuButton 必用 asChild + 單一 wrapper
9
+ # (互動觸發行 <button type="button">,如 UserFooter 帳號選單;純展示 row <div role="group">),
9
10
  # per sidebar.tsx:1025-1027 docblock:「asChild 的 consumer 自行放 icon + label」+ DS canonical
10
- # sidebar.stories.tsx#UserFooter 範例 L76-104。
11
+ # sidebar.stories.tsx#UserFooter 範例。
11
12
  #
12
13
  # Detection:
13
14
  # `<SidebarMenuButton ...>` (no asChild) ... `<ItemAvatar` or `<Avatar` inside → BLOCKER
@@ -81,7 +82,8 @@ cat >&2 <<'EOF'
81
82
 
82
83
  ❌ SidebarMenuButton id="..." 直接放 ItemAvatar + span 為 children
83
84
 
84
- ✅ SidebarMenuButton asChild 包 div role="group" 內含 ItemAvatar + span data-sidebar="menu-label" min-w-0 flex-1 truncate
85
+ ✅ SidebarMenuButton asChild 包單一 wrapper 內含 ItemAvatar + span data-sidebar="menu-label" min-w-0 flex-1 truncate
86
+ (wrapper:互動觸發行用 <button type="button">,如 UserFooter 帳號選單;純展示 row 用 <div role="group">)
85
87
 
86
88
  Or use startIcon prop(自動 layout,不 wrap):
87
89
  ✅ SidebarMenuButton startIcon={SomeLucideIcon} 直接 children 為純文字
@@ -90,7 +92,7 @@ Bypass(極罕見):GOVERNANCE_BYPASS_SIDEBAR_MENU_BUTTON_WRAP=1 env var(audit-log
90
92
 
91
93
  Citation:
92
94
  - packages/design-system/src/components/Sidebar/sidebar.tsx:1025-1043(asChild docblock)
93
- - packages/design-system/src/components/Sidebar/sidebar.stories.tsx UserFooter L76-104(canonical)
95
+ - packages/design-system/src/components/Sidebar/sidebar.stories.tsx UserFooter(canonical;帳號選單觸發行)
94
96
  EOF
95
97
  # 2026-05-31:exit 0 → exit 2(folded-hook-audit:原宣稱 BLOCKER 但 exit 0 = 假 enforcement;
96
98
  # SidebarMenuButton implicit-wrap 是 SSOT canonical,verified clean on 現有 sidebar code + 有 env escape)。
@@ -1380,17 +1380,11 @@ export function normalizeProviderHookInput({
1380
1380
  const selectedWriteTransports = matchingWriteTransports(provider, input)
1381
1381
  const shouldParseMutation = selectedWriteTransports.matches.length > 0
1382
1382
  && (
1383
- event === 'PreToolUse'
1384
- || (
1385
- event === 'PostToolUse'
1386
- && (
1387
- selectedWriteTransports.matches.length !== 1
1388
- || postEventCarriesDeclaredTransport(input, selectedWriteTransports.matches[0], {
1389
- limits,
1390
- checkpoint,
1391
- })
1392
- )
1393
- )
1383
+ selectedWriteTransports.matches.length !== 1
1384
+ || postEventCarriesDeclaredTransport(input, selectedWriteTransports.matches[0], {
1385
+ limits,
1386
+ checkpoint,
1387
+ })
1394
1388
  )
1395
1389
  if (shouldParseMutation) {
1396
1390
  try {