@qijenchen/design-system 0.1.0-beta.10 → 0.1.0-beta.13

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 (307) hide show
  1. package/CLAUDE.md +201 -0
  2. package/README.md +7 -15
  3. package/cli-init.mjs +90 -0
  4. package/ds-canonical/commands/README.md +26 -0
  5. package/ds-canonical/commands/gov-status.md +79 -0
  6. package/ds-canonical/hooks/README.md +145 -0
  7. package/ds-canonical/hooks/_log-fire.sh +44 -0
  8. package/ds-canonical/hooks/block_prototype_imports.py +111 -0
  9. package/ds-canonical/hooks/check_app_shell_primary_header_consistency.sh +68 -0
  10. package/ds-canonical/hooks/check_audit_post_report_validator.sh +88 -0
  11. package/ds-canonical/hooks/check_audit_sample_escape.sh +73 -0
  12. package/ds-canonical/hooks/check_benchmark_citation.sh +106 -0
  13. package/ds-canonical/hooks/check_canonical_propagation.sh +189 -0
  14. package/ds-canonical/hooks/check_chrome_header_handcraft.sh +70 -0
  15. package/ds-canonical/hooks/check_codex_brief_invariants.sh +83 -0
  16. package/ds-canonical/hooks/check_codex_collab_5step.sh +108 -0
  17. package/ds-canonical/hooks/check_datatable_invariants.sh +117 -0
  18. package/ds-canonical/hooks/check_dim_count_drift.sh +72 -0
  19. package/ds-canonical/hooks/check_field_controls_contracts.sh +110 -0
  20. package/ds-canonical/hooks/check_field_family_invariants.sh +205 -0
  21. package/ds-canonical/hooks/check_file_size_budget.sh +60 -0
  22. package/ds-canonical/hooks/check_header_with_tabs_border.sh +87 -0
  23. package/ds-canonical/hooks/check_main_branch_workbench.sh +93 -0
  24. package/ds-canonical/hooks/check_naming_and_abstraction.sh +165 -0
  25. package/ds-canonical/hooks/check_opacity_token_usage.sh +149 -0
  26. package/ds-canonical/hooks/check_pattern_invariants.sh +194 -0
  27. package/ds-canonical/hooks/check_peoplepicker_ssot_drift.sh +56 -0
  28. package/ds-canonical/hooks/check_pixel_quantified_audit.sh +53 -0
  29. package/ds-canonical/hooks/check_propose_plain_chinese.sh +74 -0
  30. package/ds-canonical/hooks/check_propose_pre_grep_verify.sh +70 -0
  31. package/ds-canonical/hooks/check_select_all_canonical.sh +58 -0
  32. package/ds-canonical/hooks/check_solo_workflow.sh +258 -0
  33. package/ds-canonical/hooks/check_spec_class_drift.sh +88 -0
  34. package/ds-canonical/hooks/check_story_invariants.sh +612 -0
  35. package/ds-canonical/hooks/check_substantive_edit_approval_preflight.sh +105 -0
  36. package/ds-canonical/hooks/check_tab_lg_chrome_header_equal.sh +66 -0
  37. package/ds-canonical/hooks/check_wrapper_primitive_schema_drift.sh +104 -0
  38. package/ds-canonical/hooks/enforce_home_charter.sh +44 -0
  39. package/ds-canonical/hooks/inject_pending_self_audit.sh +204 -0
  40. package/ds-canonical/hooks/lib/_approval_re.sh +33 -0
  41. package/ds-canonical/hooks/lib/_code_quality.sh +73 -0
  42. package/ds-canonical/hooks/lib/_cva_default_sync.sh +69 -0
  43. package/ds-canonical/hooks/lib/_governance_coverage_check.sh +49 -0
  44. package/ds-canonical/hooks/lib/_hardcoded_strings.sh +163 -0
  45. package/ds-canonical/hooks/lib/_layout_space_canonical.sh +56 -0
  46. package/ds-canonical/hooks/lib/_overlay_handcraft.sh +141 -0
  47. package/ds-canonical/hooks/lib/_person_data_richness.sh +42 -0
  48. package/ds-canonical/hooks/lib/_story_compile_drift.sh +48 -0
  49. package/ds-canonical/hooks/lib/_token_hygiene.sh +95 -0
  50. package/ds-canonical/hooks/log_governance_fires.sh +50 -0
  51. package/ds-canonical/hooks/log_skill_invokes.sh +41 -0
  52. package/ds-canonical/hooks/post_edit_dispatcher.sh +62 -0
  53. package/ds-canonical/hooks/retired/check_anatomy_section_numbering.sh +106 -0
  54. package/ds-canonical/hooks/retired/check_avatar_hovercard.sh +90 -0
  55. package/ds-canonical/hooks/retired/check_button_icon_literal.sh.retired-2026-04-28 +38 -0
  56. package/ds-canonical/hooks/retired/check_container_breathing.sh +142 -0
  57. package/ds-canonical/hooks/retired/check_governance_compliance.sh +61 -0
  58. package/ds-canonical/hooks/retired/check_icon_only_padding_formula.sh +104 -0
  59. package/ds-canonical/hooks/retired/check_item_content_primitive.sh +150 -0
  60. package/ds-canonical/hooks/retired/check_item_list_gap.sh +153 -0
  61. package/ds-canonical/hooks/retired/check_sideoffset_canonical.sh +65 -0
  62. package/ds-canonical/hooks/retired/check_spec_iteration_tag.sh +87 -0
  63. package/ds-canonical/hooks/retired/check_ssot_consultation.sh +88 -0
  64. package/ds-canonical/hooks/retired/check_sync_update.sh +20 -0
  65. package/ds-canonical/hooks/retired/check_third_party_dom_verified.sh +95 -0
  66. package/ds-canonical/hooks/retired/enforce_home_charter.sh +125 -0
  67. package/ds-canonical/hooks/retired/post_edit_canonical_interrogate.sh +109 -0
  68. package/ds-canonical/hooks/retired/pre_edit_spec_check.sh +68 -0
  69. package/ds-canonical/hooks/retired/pre_new_component_spec.sh +39 -0
  70. package/ds-canonical/hooks/retired/pre_write_subsumption_check.sh +112 -0
  71. package/ds-canonical/hooks/retired/stop_meta_self_audit.sh.retired-2026-05-13 +76 -0
  72. package/ds-canonical/hooks/retired/tests/test_check_anatomy_section_numbering.sh +14 -0
  73. package/ds-canonical/hooks/retired/tests/test_check_avatar_hovercard.sh +15 -0
  74. package/ds-canonical/hooks/retired/tests/test_check_container_breathing.sh +15 -0
  75. package/ds-canonical/hooks/retired/tests/test_check_governance_compliance.sh +15 -0
  76. package/ds-canonical/hooks/retired/tests/test_check_icon_only_padding_formula.sh +79 -0
  77. package/ds-canonical/hooks/retired/tests/test_check_item_content_primitive.sh +15 -0
  78. package/ds-canonical/hooks/retired/tests/test_check_item_list_gap.sh +163 -0
  79. package/ds-canonical/hooks/retired/tests/test_check_sideoffset_canonical.sh +15 -0
  80. package/ds-canonical/hooks/retired/tests/test_check_spec_iteration_tag.sh +15 -0
  81. package/ds-canonical/hooks/retired/tests/test_check_ssot_consultation.sh +15 -0
  82. package/ds-canonical/hooks/retired/tests/test_check_sync_update.sh +14 -0
  83. package/ds-canonical/hooks/retired/tests/test_check_third_party_dom_verified.sh +15 -0
  84. package/ds-canonical/hooks/retired/tests/test_enforce_home_charter.sh +15 -0
  85. package/ds-canonical/hooks/retired/tests/test_pre_edit_spec_check.sh +15 -0
  86. package/ds-canonical/hooks/retired/tests/test_pre_new_component_spec.sh +15 -0
  87. package/ds-canonical/hooks/retired/tests/test_pre_write_subsumption_check.sh +63 -0
  88. package/ds-canonical/hooks/session_start_governance_check.sh +263 -0
  89. package/ds-canonical/hooks/stop_passive_logging.sh +322 -0
  90. package/ds-canonical/hooks/stop_self_audit.sh +450 -0
  91. package/ds-canonical/hooks/tests/KNOWN-BROKEN.md +15 -0
  92. package/ds-canonical/hooks/tests/run-all.sh +76 -0
  93. package/ds-canonical/hooks/tests/test_block_prototype_imports.sh +143 -0
  94. package/ds-canonical/hooks/tests/test_check_app_shell_primary_header_consistency.sh +140 -0
  95. package/ds-canonical/hooks/tests/test_check_audit_post_report_validator.sh +115 -0
  96. package/ds-canonical/hooks/tests/test_check_audit_sample_escape.sh +93 -0
  97. package/ds-canonical/hooks/tests/test_check_benchmark_citation.sh +115 -0
  98. package/ds-canonical/hooks/tests/test_check_canonical_propagation.sh +133 -0
  99. package/ds-canonical/hooks/tests/test_check_chrome_header_handcraft.sh +123 -0
  100. package/ds-canonical/hooks/tests/test_check_code_quality.sh +15 -0
  101. package/ds-canonical/hooks/tests/test_check_codex_collab_5step.sh +96 -0
  102. package/ds-canonical/hooks/tests/test_check_cva_default_sync.sh +15 -0
  103. package/ds-canonical/hooks/tests/test_check_datatable_invariants.sh +122 -0
  104. package/ds-canonical/hooks/tests/test_check_dim_count_drift.sh +98 -0
  105. package/ds-canonical/hooks/tests/test_check_field_controls_contracts.sh +126 -0
  106. package/ds-canonical/hooks/tests/test_check_field_family_invariants.sh +194 -0
  107. package/ds-canonical/hooks/tests/test_check_file_size_budget.sh +32 -0
  108. package/ds-canonical/hooks/tests/test_check_hardcoded_strings.sh +14 -0
  109. package/ds-canonical/hooks/tests/test_check_header_with_tabs_border.sh +110 -0
  110. package/ds-canonical/hooks/tests/test_check_layout_space_canonical.sh +73 -0
  111. package/ds-canonical/hooks/tests/test_check_main_branch_workbench.sh +147 -0
  112. package/ds-canonical/hooks/tests/test_check_naming_and_abstraction.sh +136 -0
  113. package/ds-canonical/hooks/tests/test_check_opacity_token_usage.sh +110 -0
  114. package/ds-canonical/hooks/tests/test_check_overlay_handcraft.sh +126 -0
  115. package/ds-canonical/hooks/tests/test_check_pattern_invariants.sh +148 -0
  116. package/ds-canonical/hooks/tests/test_check_peoplepicker_ssot_drift.sh +108 -0
  117. package/ds-canonical/hooks/tests/test_check_person_data_richness.sh +58 -0
  118. package/ds-canonical/hooks/tests/test_check_pixel_quantified_audit.sh +142 -0
  119. package/ds-canonical/hooks/tests/test_check_propose_plain_chinese.sh +126 -0
  120. package/ds-canonical/hooks/tests/test_check_propose_pre_grep_verify.sh +117 -0
  121. package/ds-canonical/hooks/tests/test_check_select_all_canonical.sh +125 -0
  122. package/ds-canonical/hooks/tests/test_check_solo_workflow.sh +201 -0
  123. package/ds-canonical/hooks/tests/test_check_spec_class_drift.sh +135 -0
  124. package/ds-canonical/hooks/tests/test_check_story_anatomy.sh.broken +197 -0
  125. package/ds-canonical/hooks/tests/test_check_story_category.sh.broken +187 -0
  126. package/ds-canonical/hooks/tests/test_check_story_compile_drift.sh +15 -0
  127. package/ds-canonical/hooks/tests/test_check_story_invariants.sh +209 -0
  128. package/ds-canonical/hooks/tests/test_check_story_name_jargon.sh.broken +53 -0
  129. package/ds-canonical/hooks/tests/test_check_story_slot_split.sh +156 -0
  130. package/ds-canonical/hooks/tests/test_check_substantive_edit_approval_preflight.sh +176 -0
  131. package/ds-canonical/hooks/tests/test_check_tab_lg_chrome_header_equal.sh +138 -0
  132. package/ds-canonical/hooks/tests/test_check_token_hygiene.sh +21 -0
  133. package/ds-canonical/hooks/tests/test_check_wrapper_primitive_schema_drift.sh +169 -0
  134. package/ds-canonical/hooks/tests/test_enforce_home_charter.sh +77 -0
  135. package/ds-canonical/hooks/tests/test_inject_pending_self_audit.sh +125 -0
  136. package/ds-canonical/hooks/tests/test_log_governance_fires.sh +10 -0
  137. package/ds-canonical/hooks/tests/test_log_skill_invokes.sh +7 -0
  138. package/ds-canonical/hooks/tests/test_post_edit_dispatcher.sh +108 -0
  139. package/ds-canonical/hooks/tests/test_session_start_governance_check.sh +143 -0
  140. package/ds-canonical/hooks/tests/test_stop_capture_metrics.sh +95 -0
  141. package/ds-canonical/hooks/tests/test_stop_governance_drift_check.sh.broken +125 -0
  142. package/ds-canonical/hooks/tests/test_stop_harvest_corrections.sh +10 -0
  143. package/ds-canonical/hooks/tests/test_stop_passive_logging.sh +100 -0
  144. package/ds-canonical/hooks/tests/test_stop_self_audit.sh +76 -0
  145. package/ds-canonical/hooks/tests/test_stop_tsc_sanity.sh +10 -0
  146. package/ds-canonical/references/README.md +43 -0
  147. package/ds-canonical/references/audit-coverage-vs-24-checklist.md +74 -0
  148. package/ds-canonical/references/build-ui-canonicals.md +69 -0
  149. package/ds-canonical/references/cva-patterns.md +41 -0
  150. package/ds-canonical/references/drag-canonical.md +331 -0
  151. package/ds-canonical/references/item-anatomy-recipe.md +225 -0
  152. package/ds-canonical/references/naming-conventions.md +56 -0
  153. package/ds-canonical/references/principle-dim-map.json +515 -0
  154. package/ds-canonical/references/props-naming.md +45 -0
  155. package/ds-canonical/references/spec-rules.md +58 -0
  156. package/ds-canonical/references/ssot-consultation.md +63 -0
  157. package/ds-canonical/references/ssot-index.md +40 -0
  158. package/ds-canonical/references/story-baseline-registry.json +79 -0
  159. package/ds-canonical/references/structural-token-retention.md +42 -0
  160. package/ds-canonical/references/tailwind-gotchas.md +87 -0
  161. package/ds-canonical/references/ui-dev-rules.md +60 -0
  162. package/ds-canonical/rules/README.md +34 -0
  163. package/ds-canonical/rules/meta-patterns.md +87 -0
  164. package/ds-canonical/rules/self-verify.md +53 -0
  165. package/ds-canonical/rules/spec-rules.md +25 -0
  166. package/ds-canonical/rules/story-rules.md +56 -0
  167. package/ds-canonical/rules/ui-development.md +87 -0
  168. package/ds-canonical/skills/README.md +88 -0
  169. package/ds-canonical/skills/bug-fix-rhythm/SKILL.md +181 -0
  170. package/ds-canonical/skills/code-quality-audit/SKILL.md +63 -0
  171. package/ds-canonical/skills/codex-collab/SKILL.md +249 -0
  172. package/ds-canonical/skills/codex-collab/references/brief-template.md +48 -0
  173. package/ds-canonical/skills/codex-collab/references/transport.md +58 -0
  174. package/ds-canonical/skills/codify-corrections/SKILL.md +184 -0
  175. package/ds-canonical/skills/codify-principle/SKILL.md +151 -0
  176. package/ds-canonical/skills/component-quality-gate/SKILL.md +102 -0
  177. package/ds-canonical/skills/component-quality-gate/references/checklist.md +79 -0
  178. package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +247 -0
  179. package/ds-canonical/skills/deep-audit-cross-codex/references/phase-a-workflow.md +123 -0
  180. package/ds-canonical/skills/deep-audit-cross-codex/references/phase-b-codex-brief.md +165 -0
  181. package/ds-canonical/skills/deep-audit-cross-codex/references/triage-rubric.md +91 -0
  182. package/ds-canonical/skills/delivery-handoff/SKILL.md +229 -0
  183. package/ds-canonical/skills/delivery-handoff/references/flow-diagram.md +180 -0
  184. package/ds-canonical/skills/delivery-handoff/references/handoff-template.md +177 -0
  185. package/ds-canonical/skills/delivery-handoff/references/inventory-checklist.md +196 -0
  186. package/ds-canonical/skills/design-system-audit/SKILL.md +343 -0
  187. package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +1260 -0
  188. package/ds-canonical/skills/design-system-audit/references/checkpoints.md +240 -0
  189. package/ds-canonical/skills/design-system-audit/references/historical-bugs.md +240 -0
  190. package/ds-canonical/skills/design-system-audit/references/principle-audit-protocol.md +364 -0
  191. package/ds-canonical/skills/design-system-audit/references/rule-placement.md +175 -0
  192. package/ds-canonical/skills/design-system-audit/references/spec-template.md +66 -0
  193. package/ds-canonical/skills/ensure-canonical/SKILL.md +196 -0
  194. package/ds-canonical/skills/governance-health/SKILL.md +146 -0
  195. package/ds-canonical/skills/knowledge-prune/SKILL.md +303 -0
  196. package/ds-canonical/skills/new-component/SKILL.md +170 -0
  197. package/ds-canonical/skills/new-component/references/new-component-checklist.md +85 -0
  198. package/ds-canonical/skills/performance-audit/SKILL.md +107 -0
  199. package/ds-canonical/skills/product-ui-audit/SKILL.md +230 -0
  200. package/ds-canonical/skills/product-ui-audit/references/audit-checks.md +246 -0
  201. package/ds-canonical/skills/product-ui-audit/references/common-misuses.md +329 -0
  202. package/ds-canonical/skills/product-ui-audit/references/report-template.md +159 -0
  203. package/ds-canonical/skills/propose-options/SKILL.md +177 -0
  204. package/ds-canonical/skills/prototype/SKILL.md +244 -0
  205. package/ds-canonical/skills/prototype/references/audit-checks.md +37 -0
  206. package/ds-canonical/skills/prototype/references/benchmark-sources.md +94 -0
  207. package/ds-canonical/skills/prototype/references/checkpoints.md +191 -0
  208. package/ds-canonical/skills/prototype/references/evaluation-matrix.md +141 -0
  209. package/ds-canonical/skills/prototype/references/ooux-template.md +198 -0
  210. package/ds-canonical/skills/prototype/references/proposal-template.md +229 -0
  211. package/ds-canonical/skills/scan-similar-bugs/SKILL.md +198 -0
  212. package/ds-canonical/skills/story-auto-compile-migrate/SKILL.md +159 -0
  213. package/ds-canonical/skills/story-writing/SKILL.md +122 -0
  214. package/ds-canonical/skills/story-writing/references/anatomy-standard.md +217 -0
  215. package/ds-canonical/skills/story-writing/references/category-templates.md +174 -0
  216. package/ds-canonical/skills/story-writing/references/example-selection.md +70 -0
  217. package/ds-canonical/skills/story-writing/references/self-check.md +20 -0
  218. package/ds-canonical/skills/ux-audit/SKILL.md +130 -0
  219. package/ds-canonical/skills/visual-audit/SKILL.md +245 -0
  220. package/ds-canonical/skills/visual-audit/output/.gitkeep +0 -0
  221. package/ds-canonical/skills/visual-audit/references/audit-architecture.md +100 -0
  222. package/ds-canonical/skills/visual-audit/references/visual-checklist.md +297 -0
  223. package/ds-canonical/skills/visual-audit/references/world-class-benchmarks.md +198 -0
  224. package/package.json +9 -5
  225. package/src/components/Accordion/accordion.spec.md +114 -0
  226. package/src/components/Alert/alert.spec.md +197 -0
  227. package/src/components/AppShell/app-shell.spec.md +331 -0
  228. package/src/components/AspectRatio/aspect-ratio.spec.md +134 -0
  229. package/src/components/Avatar/avatar.spec.md +329 -0
  230. package/src/components/Badge/badge.spec.md +380 -0
  231. package/src/components/Breadcrumb/breadcrumb.spec.md +257 -0
  232. package/src/components/BulkActionBar/bulk-action-bar.spec.md +210 -0
  233. package/src/components/Button/button.spec.md +460 -0
  234. package/src/components/Calendar/calendar.spec.md +242 -0
  235. package/src/components/Carousel/carousel.spec.md +253 -0
  236. package/src/components/Chart/chart.spec.md +155 -0
  237. package/src/components/Checkbox/checkbox.spec.md +344 -0
  238. package/src/components/Chip/chip.spec.md +237 -0
  239. package/src/components/CircularProgress/circular-progress.spec.md +268 -0
  240. package/src/components/Coachmark/coachmark.spec.md +230 -0
  241. package/src/components/Combobox/combobox.spec.md +180 -0
  242. package/src/components/Command/command.spec.md +171 -0
  243. package/src/components/DataTable/data-table.spec.md +525 -0
  244. package/src/components/DateGrid/date-grid.spec.md +215 -0
  245. package/src/components/DatePicker/date-picker.spec.md +334 -0
  246. package/src/components/DescriptionList/description-list.spec.md +214 -0
  247. package/src/components/Dialog/dialog.spec.md +202 -0
  248. package/src/components/DropdownMenu/dropdown-menu.spec.md +250 -0
  249. package/src/components/Empty/empty.spec.md +214 -0
  250. package/src/components/Field/field-controls.spec.md +338 -0
  251. package/src/components/Field/field.spec.md +438 -0
  252. package/src/components/Field/form-validation.spec.md +152 -0
  253. package/src/components/FieldControlGroup/field-control-group.spec.md +176 -0
  254. package/src/components/FileItem/file-item.spec.md +467 -0
  255. package/src/components/FileUpload/file-upload.spec.md +123 -0
  256. package/src/components/FileViewer/file-viewer.spec.md +373 -0
  257. package/src/components/HoverCard/hover-card.spec.md +157 -0
  258. package/src/components/Input/input.spec.md +193 -0
  259. package/src/components/LinkInput/link-input.spec.md +130 -0
  260. package/src/components/Menu/menu-item.spec.md +290 -0
  261. package/src/components/NameCard/name-card.spec.md +171 -0
  262. package/src/components/Notice/notice.spec.md +149 -0
  263. package/src/components/NumberInput/number-input.spec.md +126 -0
  264. package/src/components/OverflowIndicator/overflow-indicator.spec.md +120 -0
  265. package/src/components/PeoplePicker/people-picker.spec.md +263 -0
  266. package/src/components/Popover/popover.spec.md +198 -0
  267. package/src/components/ProgressBar/progress-bar.spec.md +232 -0
  268. package/src/components/RadioGroup/radio-group.spec.md +141 -0
  269. package/src/components/Rating/rating.spec.md +208 -0
  270. package/src/components/ScrollArea/scroll-area.spec.md +145 -0
  271. package/src/components/SegmentedControl/segmented-control.spec.md +295 -0
  272. package/src/components/Select/select.spec.md +299 -0
  273. package/src/components/SelectMenu/select-menu.spec.md +220 -0
  274. package/src/components/SelectionControl/selection-item.spec.md +128 -0
  275. package/src/components/Separator/separator.spec.md +109 -0
  276. package/src/components/Sheet/sheet.spec.md +148 -0
  277. package/src/components/Sidebar/sidebar.spec.md +713 -0
  278. package/src/components/Skeleton/skeleton.spec.md +104 -0
  279. package/src/components/Slider/slider.spec.md +353 -0
  280. package/src/components/Steps/steps.spec.md +465 -0
  281. package/src/components/Switch/switch.spec.md +215 -0
  282. package/src/components/Tabs/tabs.spec.md +314 -0
  283. package/src/components/Tag/tag.spec.md +282 -0
  284. package/src/components/Textarea/textarea.spec.md +151 -0
  285. package/src/components/TimePicker/time-picker.spec.md +279 -0
  286. package/src/components/Toast/toast.spec.md +177 -0
  287. package/src/components/Tooltip/tooltip.spec.md +139 -0
  288. package/src/components/TreeView/tree-view.spec.md +374 -0
  289. package/src/patterns/action-bar/action-bar.spec.md +458 -0
  290. package/src/patterns/element-anatomy/element-anatomy.spec.md +215 -0
  291. package/src/patterns/element-anatomy/inline-action.spec.md +315 -0
  292. package/src/patterns/element-anatomy/item-anatomy.spec.md +1042 -0
  293. package/src/patterns/header-canonical/header-canonical.spec.md +285 -0
  294. package/src/patterns/horizontal-overflow/horizontal-overflow.spec.md +191 -0
  295. package/src/patterns/overlay-surface/overlay-surface.spec.md +428 -0
  296. package/src/patterns/resize-handle/resize-handle.spec.md +109 -0
  297. package/src/tokens/color/color.spec.md +804 -0
  298. package/src/tokens/density/density.spec.md +127 -0
  299. package/src/tokens/elevation/elevation.spec.md +81 -0
  300. package/src/tokens/layoutSpace/layoutSpace.spec.md +314 -0
  301. package/src/tokens/motion/motion.spec.md +97 -0
  302. package/src/tokens/opacity/opacity.spec.md +78 -0
  303. package/src/tokens/orphan-tokens.spec.md +117 -0
  304. package/src/tokens/radius/radius.spec.md +123 -0
  305. package/src/tokens/typography/typography.spec.md +202 -0
  306. package/src/tokens/uiSize/uiSize.spec.md +438 -0
  307. package/src/styles/preset.css +0 -31
@@ -0,0 +1,149 @@
1
+ #!/bin/bash
2
+ set -uo pipefail
3
+ # Tailwind token registry enforcement hook(2026-05-18 升級 per audit Dim 47 + codex P1-5):
4
+ # 原 hook 名 `check_opacity_token_usage.sh`(keep filename for settings.json registration),
5
+ # 實際 logic 已升級成 full Tailwind utility registry compliance(per Dim 47 SSOT)。
6
+ #
7
+ # SSOT source:`packages/design-system/src/tokens/utility-registry.json`(block list per category)。
8
+ # 對齊 Atlassian @atlaskit/tokens / Carbon @carbon/themes / Ant ConfigProvider / Polaris polaris-tokens
9
+ # token-first lint enforcement。
10
+ #
11
+ # 檢的 block category:
12
+ # - opacity:opacity-{5..95} numeric tier(原 logic,保留)
13
+ # - typography:text-{xs..9xl} / font-{thin|light|semibold|black} / leading-{N} numeric / tracking-{wide..widest|tighter|tight}
14
+ # - radius:rounded-{xl|2xl|3xl} / rounded(unscoped)
15
+ # - elevation:shadow-{sm|md|lg|xl|2xl|inner} / shadow(unscoped)
16
+ # - shadcn alias:bg-popover / text-muted-foreground / bg-accent 等
17
+ # - primitive 色名:bg-neutral-N / text-blue-N 等(越過 semantic 層)
18
+ #
19
+ # 例外:utility-registry.json `_meta.exceptions` 段定義的 anatomy stories / principles code blocks 豁免
20
+ # (本 hook 已 skip *.anatomy.stories.tsx / *.principles.stories.tsx 不檢)
21
+ #
22
+ # 修法:reuse semantic utility / token reference / var() bracket(詳 utility-registry.json `rationale_path`)。
23
+
24
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
25
+
26
+ INPUT=$(cat)
27
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""')
28
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
29
+
30
+ case "$TOOL" in
31
+ Edit|Write|MultiEdit) ;;
32
+ *) exit 0 ;;
33
+ esac
34
+
35
+ # Scope:.tsx + .css(DS source);skip stories / tests / token spec 自家 / anatomy/principles per registry exception
36
+ case "$FILE_PATH" in
37
+ *.tsx|*.css) ;;
38
+ *) exit 0 ;;
39
+ esac
40
+ case "$FILE_PATH" in
41
+ # 註解:anatomy + principles stories per utility-registry.json `_meta.exceptions` 豁免
42
+ *.anatomy.stories.tsx|*.principles.stories.tsx) exit 0 ;;
43
+ *.stories.tsx|*.test.*|*.spec.tsx) exit 0 ;;
44
+ *tokens/opacity/*|*tokens/typography/*|*tokens/radius/*|*tokens/elevation/*|*tokens/color/*) exit 0 ;;
45
+ esac
46
+
47
+ NEW_CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content // .tool_input.new_string // ""')
48
+ [ -z "$NEW_CONTENT" ] && exit 0
49
+
50
+ # Resolve registry path(absolute via $CLAUDE_PROJECT_DIR or relative fallback)
51
+ REGISTRY="${CLAUDE_PROJECT_DIR:-}/packages/design-system/src/tokens/utility-registry.json"
52
+ if [ ! -f "$REGISTRY" ]; then
53
+ # Fallback: try relative from hook dir
54
+ REGISTRY="$(dirname "$0")/../../packages/design-system/src/tokens/utility-registry.json"
55
+ fi
56
+ if [ ! -f "$REGISTRY" ]; then
57
+ # 沒 registry → fall back 到原 opacity-only logic(避免 hook 啞掉)
58
+ HITS=$(echo "$NEW_CONTENT" | grep -oE "opacity-[0-9]+" | grep -vE "^opacity-(0|100)$" | sort -u || true)
59
+ if [ -n "$HITS" ]; then
60
+ echo "" >&2
61
+ echo "⚠️ M23 violation(opacity tier;registry 不可用,fallback mode):" >&2
62
+ echo "$HITS" | sed 's/^/ /' >&2
63
+ echo "" >&2
64
+ echo " reuse opacity-disabled / alpha 色階。詳 tokens/opacity/opacity.spec.md" >&2
65
+ fi
66
+ exit 0
67
+ fi
68
+
69
+ # Aggregate violations across all categories
70
+ VIOLATIONS=""
71
+
72
+ # 1) Opacity numeric tier(opacity-5..95,除 0/100/disabled)
73
+ HITS_OPACITY=$(echo "$NEW_CONTENT" | grep -oE "\bopacity-[0-9]+\b" | grep -vE "^opacity-(0|100)$" | sort -u || true)
74
+ if [ -n "$HITS_OPACITY" ]; then
75
+ VIOLATIONS="${VIOLATIONS}\n [opacity] $(echo "$HITS_OPACITY" | tr '\n' ' ')"
76
+ fi
77
+
78
+ # 2) Typography raw size(text-xs..9xl)— skip semantic text-h*/text-body/text-caption/text-helper/text-label
79
+ HITS_TEXT=$(echo "$NEW_CONTENT" | grep -oE "\btext-(xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl|8xl|9xl)\b" | sort -u || true)
80
+ if [ -n "$HITS_TEXT" ]; then
81
+ VIOLATIONS="${VIOLATIONS}\n [typography size] $(echo "$HITS_TEXT" | tr '\n' ' ')"
82
+ fi
83
+
84
+ # 3) Typography raw weight
85
+ HITS_FONT=$(echo "$NEW_CONTENT" | grep -oE "\bfont-(thin|extralight|light|semibold|extrabold|black)\b" | sort -u || true)
86
+ if [ -n "$HITS_FONT" ]; then
87
+ VIOLATIONS="${VIOLATIONS}\n [typography weight] $(echo "$HITS_FONT" | tr '\n' ' ')"
88
+ fi
89
+
90
+ # 4) Leading numeric(leading-N where N is digit;skip leading-compact/normal/none/tight/snug/relaxed/loose)
91
+ HITS_LEADING=$(echo "$NEW_CONTENT" | grep -oE "\bleading-[0-9]+\b" | sort -u || true)
92
+ if [ -n "$HITS_LEADING" ]; then
93
+ VIOLATIONS="${VIOLATIONS}\n [leading numeric] $(echo "$HITS_LEADING" | tr '\n' ' ')"
94
+ fi
95
+
96
+ # 5) Tracking raw(skip tracking-shortcut canonical token)
97
+ HITS_TRACKING=$(echo "$NEW_CONTENT" | grep -oE "\btracking-(tighter|tight|wide|wider|widest)\b" | sort -u || true)
98
+ if [ -n "$HITS_TRACKING" ]; then
99
+ VIOLATIONS="${VIOLATIONS}\n [tracking raw] $(echo "$HITS_TRACKING" | tr '\n' ' ')"
100
+ fi
101
+
102
+ # 6) Radius out-of-range
103
+ HITS_RADIUS=$(echo "$NEW_CONTENT" | grep -oE "\brounded-(xl|2xl|3xl)\b" | sort -u || true)
104
+ if [ -n "$HITS_RADIUS" ]; then
105
+ VIOLATIONS="${VIOLATIONS}\n [radius out-of-range] $(echo "$HITS_RADIUS" | tr '\n' ' ')"
106
+ fi
107
+
108
+ # 7) Shadow Tailwind size(shadow-sm/md/lg/xl/2xl/inner — DS 用 shadow-[var(--elevation-*)])
109
+ HITS_SHADOW=$(echo "$NEW_CONTENT" | grep -oE "\bshadow-(sm|md|lg|xl|2xl|inner)\b" | sort -u || true)
110
+ if [ -n "$HITS_SHADOW" ]; then
111
+ VIOLATIONS="${VIOLATIONS}\n [elevation size] $(echo "$HITS_SHADOW" | tr '\n' ' ')"
112
+ fi
113
+
114
+ # 8) Shadcn compat alias(bg-popover / text-muted-foreground 等)
115
+ HITS_SHADCN=$(echo "$NEW_CONTENT" | grep -oE "\b(bg-popover|text-popover-foreground|text-muted-foreground|bg-accent|text-accent-foreground|bg-destructive|bg-background|text-background|border-input)\b" | sort -u || true)
116
+ if [ -n "$HITS_SHADCN" ]; then
117
+ VIOLATIONS="${VIOLATIONS}\n [shadcn alias] $(echo "$HITS_SHADCN" | tr '\n' ' ')"
118
+ fi
119
+
120
+ # 9) Primitive 色名作 utility(bg-neutral-N / text-blue-N 等)
121
+ HITS_PRIMITIVE=$(echo "$NEW_CONTENT" | grep -oE "\b(bg|text|border)-(neutral|blue|red|green|yellow|orange|purple|pink|cyan|teal|deep-orange|deep-purple|light-blue|light-green|lime|amber|indigo|brown|gray)-[0-9]+\b" | sort -u || true)
122
+ if [ -n "$HITS_PRIMITIVE" ]; then
123
+ VIOLATIONS="${VIOLATIONS}\n [primitive color as utility] $(echo "$HITS_PRIMITIVE" | tr '\n' ' ')"
124
+ fi
125
+
126
+ if [ -n "$VIOLATIONS" ]; then
127
+ cat >&2 <<'EOF_HEAD'
128
+
129
+ ⚠️ M23 / Dim 47 violation:Tailwind utility 繞 SSOT registry。
130
+ EOF_HEAD
131
+ echo -e "$VIOLATIONS" >&2
132
+ cat >&2 <<'EOF_BODY'
133
+
134
+ SSOT:packages/design-system/src/tokens/utility-registry.json(block list per category)
135
+ 修法 quick map:
136
+ text-xs..9xl → text-h1..h6 / text-body / text-caption / text-helper / text-label
137
+ font-thin/...black → font-normal / font-medium / font-bold
138
+ leading-{N} → leading-compact / leading-normal
139
+ tracking-* → tracking-shortcut(or codify role-specific semantic utility)
140
+ rounded-xl.. → rounded-xs..rounded-lg / rounded-full
141
+ shadow-sm.. → shadow-[var(--elevation-100)] / shadow-[var(--elevation-200)]
142
+ bg-popover .. → direct semantic token(--surface-raised / --fg-muted / --error 等)
143
+ bg-neutral-N → semantic utility(bg-surface 等)或 bg-[var(--color-neutral-N)]
144
+
145
+ 詳 utility-registry.json `_meta.spec_sources` + M23「DS 內既有 canonical 優先」。
146
+ EOF_BODY
147
+ fi
148
+
149
+ exit 0
@@ -0,0 +1,194 @@
1
+ #!/bin/bash
2
+ # Pattern invariants unified hook(2026-05-08 cluster C consolidation)
3
+ #
4
+ # Merges 4 PreToolUse hooks(原各檔已 retire,合併入此):
5
+ # C.1 overlay panel scroll chain(原 check_overlay_panel_scroll_chain,P1 WARN stderr)
6
+ # C.2 inline-action canonical gap(原 check_inline_action_canonical_gap,P1 WARN stderr)
7
+ # C.3 primitive wrapper padding(原 check_primitive_wrapper_padding,P0 BLOCK exit 2)
8
+ # C.4 row slot handcraft(原 check_row_slot_handcraft,P0 BLOCK exit 2)
9
+ #
10
+ # Why merge:皆 element-anatomy / overlay-surface SSOT 消費紀律 invariant,共用 INPUT
11
+ # parsing + tsx filter,散裝是 M17 + Anthropic ≤ 15 hook best-practice 偏離。
12
+ #
13
+ # Exit precedence:BLOCK(2)> WARN-stderr(0)。每 rule 獨立 fire,worst 勝。
14
+ #
15
+ # Per-rule allowlist:
16
+ # C.1: `// @scroll-chain-allow: <reason>`(any line)
17
+ # C.2: `// @inline-action-gap-allow: <reason>`(any line)
18
+ # C.3: `// @primitive-padding-allow: <reason>`(檔案前 5 行)
19
+ # C.4: `// @row-slot-handcraft-allow: <reason>`(any line)
20
+
21
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
22
+
23
+ set -uo pipefail
24
+
25
+ INPUT=$(cat)
26
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""')
27
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
28
+
29
+ case "$TOOL" in
30
+ Edit|Write|MultiEdit) ;;
31
+ *) exit 0 ;;
32
+ esac
33
+
34
+ case "$FILE_PATH" in
35
+ *.tsx) ;;
36
+ *) exit 0 ;;
37
+ esac
38
+
39
+ NEW_CONTENT=$(echo "$INPUT" | jq -r '
40
+ (.tool_input.content // "") + "\n" +
41
+ (.tool_input.new_string // "") + "\n" +
42
+ ([.tool_input.edits[]? | .new_string] | join("\n"))
43
+ ' 2>/dev/null || echo "")
44
+
45
+ [ -z "${NEW_CONTENT//[[:space:]]/}" ] && exit 0
46
+
47
+ WORST=0
48
+ record_worst() { local lvl=$1; [ "$lvl" -gt "$WORST" ] && WORST=$lvl; }
49
+
50
+ # ── C.1 overlay panel scroll chain(P1 WARN stderr only)──────────────────────
51
+ if ! echo "$NEW_CONTENT" | grep -q '@scroll-chain-allow' \
52
+ && echo "$NEW_CONTENT" | grep -q '<SurfaceBody'; then
53
+ SUSPECT_C1=$(printf '%s' "$NEW_CONTENT" | awk '
54
+ /^[[:space:]]*<div[[:space:]]/ {
55
+ line = $0
56
+ while (index(line, ">") == 0 && (getline next_line) > 0) line = line " " next_line
57
+ if (line ~ /w-\[/ && (line !~ /flex[^"]*flex-col/ || line !~ /h-full/ || line !~ /min-h-0/)) {
58
+ for (k = 0; k < 30 && (getline next_line) > 0; k++) {
59
+ if (next_line ~ /<SurfaceBody/) {
60
+ print "[panel root w-[...] 缺 flex flex-col h-full min-h-0]: " substr(line, 1, 100)
61
+ break
62
+ }
63
+ if (next_line ~ /<\/div>/) break
64
+ }
65
+ }
66
+ }
67
+ ')
68
+ if [ -n "$SUSPECT_C1" ]; then
69
+ cat >&2 <<EOF
70
+
71
+ ┄┄┄ C.1 check_pattern_invariants — overlay scroll chain WARN ┄┄┄
72
+
73
+ [P1] ${FILE_PATH}
74
+ ${SUSPECT_C1}
75
+
76
+ ⚠️ M25 canonical:Popover/HoverCard/Dialog/Sheet viewport-aware scroll 要求 root → SurfaceBody
77
+ 所有中間 wrapper forward \`flex flex-col h-full\`。斷鏈 → SurfaceBody flex-1 失效。
78
+
79
+ 修法:wrapper className 加 \`flex flex-col h-full\`(最小組合 \`flex flex-col h-full min-h-0\`)
80
+ 詳 patterns/overlay-surface/overlay-surface.spec.md「Viewport-aware scroll chain invariant」/ M25
81
+ 例外:行尾 \`// @scroll-chain-allow: <reason>\`
82
+
83
+ EOF
84
+ fi
85
+ fi
86
+
87
+ # ── C.2 inline-action canonical gap(P1 WARN stderr only)─────────────────────
88
+ case "$FILE_PATH" in
89
+ *components/*.tsx|*patterns/*.tsx)
90
+ case "$FILE_PATH" in
91
+ */item-anatomy.tsx|*.stories.tsx|*.test.*) ;; # SSOT/test skip
92
+ *)
93
+ if ! echo "$NEW_CONTENT" | grep -q '@inline-action-gap-allow' \
94
+ && echo "$NEW_CONTENT" | grep -qE '<ItemInlineAction(Button)?\b|DropdownMenuTrigger.*ItemInlineAction'; then
95
+ WRONG_GAP=$(echo "$NEW_CONTENT" | grep -nE 'className=.*\bgap-(1|3|4|5|6|8|10|12)\b' | head -3 || true)
96
+ if [ -n "$WRONG_GAP" ]; then
97
+ cat >&2 <<EOF
98
+
99
+ ┄┄┄ C.2 check_pattern_invariants — inline-action gap WARN ┄┄┄
100
+
101
+ [P1] ${FILE_PATH}
102
+ ItemInlineAction* consumer 用非 \`gap-2\` 的 gap class:
103
+ ${WRONG_GAP}
104
+
105
+ ⚠️ inline-action.spec.md:80:inline-action 跟 sibling gap 必 \`gap-2\`(8px)。
106
+ 12px = --table-cell-px(cell L/R padding,不是 inline-action gap)。
107
+
108
+ 修法:className gap → gap-2 / 加 \`// @inline-action-gap-allow: <reason>\` 行尾豁免
109
+
110
+ EOF
111
+ fi
112
+ fi
113
+ ;;
114
+ esac
115
+ ;;
116
+ esac
117
+
118
+ # ── C.3 primitive wrapper padding(P0 BLOCK exit 2)───────────────────────────
119
+ # File-level allowlist:檔頭前 5 行
120
+ ALLOW_C3=0
121
+ FIRST_LINES_NEW=$(printf '%s\n' "$NEW_CONTENT" | sed -n '1,5p')
122
+ echo "$FIRST_LINES_NEW" | grep -qE '//[[:space:]]*@primitive-padding-allow:' && ALLOW_C3=1
123
+ if [ -f "$FILE_PATH" ] && [ "$ALLOW_C3" = "0" ]; then
124
+ ON_DISK_FIRST=$(sed -n '1,5p' "$FILE_PATH" 2>/dev/null || true)
125
+ echo "$ON_DISK_FIRST" | grep -qE '//[[:space:]]*@primitive-padding-allow:' && ALLOW_C3=1
126
+ fi
127
+ if [ "$ALLOW_C3" = "0" ]; then
128
+ PRIMITIVES_REGEX='DateGrid|Calendar|Surface|SurfaceHeader|SurfaceBody|SurfaceFooter'
129
+ VIOLATIONS_C3=$(printf '%s' "$NEW_CONTENT" | perl -0777 -ne '
130
+ while (/<div\b[^>]*className\s*=\s*["\x27`][^"\x27`]*\bp-\d+[^"\x27`]*["\x27`][^>]*>(?:[^<]*<(?!\/div\b)){0,8}\s*<('"$PRIMITIVES_REGEX"')\b/gs) {
131
+ my $primitive = $1;
132
+ my $offset = $-[0];
133
+ my $before = substr($_, 0, $offset);
134
+ my $line = ($before =~ tr/\n//) + 1;
135
+ print "line $line: <div className=\"...p-X...\"> wrapping <$primitive>\n";
136
+ }
137
+ ')
138
+ if [ -n "$VIOLATIONS_C3" ]; then
139
+ cat >&2 <<EOF
140
+
141
+ ┄┄┄ C.3 check_pattern_invariants — primitive wrapper padding BLOCKER ┄┄┄
142
+
143
+ [P0] ${FILE_PATH}
144
+ ${VIOLATIONS_C3}
145
+
146
+ SSOT primitive 自帶 outer padding,**consumer 不得另加 padding wrapper**:
147
+ - DateGrid / Calendar:root 自帶 p-3
148
+ - Surface{Header,Body,Footer}:各 segment 自帶 padding
149
+
150
+ 修法:直接放 primitive,不包 padding div。
151
+ ❌ <div className="p-2"><DateGrid /></div>
152
+ ✅ <DateGrid />
153
+
154
+ 整檔豁免:檔頭前 5 行加 \`// @primitive-padding-allow: <reason>\`(需 spec rationale)。
155
+ 詳 mindset #2 + M1 SSOT 消費。
156
+
157
+ EOF
158
+ record_worst 2
159
+ fi
160
+ fi
161
+
162
+ # ── C.4 row slot handcraft(P0 BLOCK exit 2)──────────────────────────────────
163
+ case "$FILE_PATH" in
164
+ *components/*.tsx|*patterns/*.tsx)
165
+ case "$FILE_PATH" in
166
+ */item-anatomy.tsx|*/field-wrapper.tsx|*.stories.tsx|*.test.*|*.spec.tsx) ;; # SSOT/test skip
167
+ *)
168
+ if ! echo "$NEW_CONTENT" | grep -q '@row-slot-handcraft-allow' \
169
+ && echo "$NEW_CONTENT" | grep -E 'h-\[1lh\][^"]*shrink-0[^"]*flex[^"]*items-center|shrink-0[^"]*h-\[1lh\][^"]*flex[^"]*items-center|flex[^"]*items-center[^"]*h-\[1lh\][^"]*shrink-0' >/dev/null; then
170
+ cat >&2 <<EOF
171
+
172
+ ┄┄┄ C.4 check_pattern_invariants — row slot handcraft BLOCKER ┄┄┄
173
+
174
+ [P0] ${FILE_PATH}
175
+ 偵測自刻 row-layout slot:\`<span class="h-[1lh] shrink-0 flex items-center...">\`
176
+ M1+M17 違反 — 該消費 L1 primitive。
177
+
178
+ ⚠️ M19 canonical(2026-05-05 v8):row prefix/suffix slot 必走 patterns/element-anatomy:
179
+ import { ItemPrefix, ItemSuffix } from '@/design-system/patterns/element-anatomy/item-anatomy'
180
+ <ItemPrefix><StartIcon /></ItemPrefix>
181
+ <ItemSuffix>{chevron}</ItemSuffix>
182
+
183
+ \`<ItemPrefix>\` / \`<ItemSuffix>\` 永遠 \`h-[1lh] shrink-0 flex items-center\`(item-anatomy.spec.md:175+190)。
184
+ 例外:行尾 \`// @row-slot-handcraft-allow: <reason>\`
185
+
186
+ EOF
187
+ record_worst 2
188
+ fi
189
+ ;;
190
+ esac
191
+ ;;
192
+ esac
193
+
194
+ exit $WORST
@@ -0,0 +1,56 @@
1
+ #!/bin/bash
2
+ set -uo pipefail
3
+ # PreToolUse Edit/Write: PeoplePicker SSOT drift guard(2026-05-15 user verbatim「避免下次再度偏移」)
4
+ #
5
+ # 攔截:`people-picker.tsx` / `person-display.tsx` / `combobox.tsx` 動以下 PeoplePicker SSOT-bearing
6
+ # code 路徑時,要求 commit message / new content 包含 cite 對應 spec.md SSOT table row 的 marker。
7
+ #
8
+ # 規則 SSOT:`packages/design-system/src/components/PeoplePicker/people-picker.spec.md` §A-§F canonical table
9
+ # (Trigger display SSOT canonical table)。
10
+ #
11
+ # 警告(non-blocking):新內容含「動 SSOT-bearing API」但無 spec 引用 → stderr 警告,要求自查對應 row。
12
+ # Hard block 場景不適用(spec 偏移由 user 決定走 RFC 或直接修)。
13
+
14
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
15
+
16
+ set -euo pipefail
17
+
18
+ INPUT=$(cat)
19
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty')
20
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
21
+ NEW_CONTENT=$(echo "$INPUT" | jq -r '.tool_input.new_string // .tool_input.content // empty')
22
+
23
+ [ -z "$FILE_PATH" ] && exit 0
24
+
25
+ # Only check Edit/Write on PeoplePicker SSOT-bearing files
26
+ case "$FILE_PATH" in
27
+ */PeoplePicker/people-picker.tsx|*/PeoplePicker/person-display.tsx|*/Combobox/combobox.tsx) ;;
28
+ *) exit 0 ;;
29
+ esac
30
+
31
+ # Patterns that touch SSOT-bearing render logic
32
+ SSOT_KEYWORDS='tagRenderer|overflowShape|tagWrapperClassName|selectedItemRenderer|MultiPersonDisplay|PersonAvatarTag|PersonDisplay|searchIn|searchPlaceholder|placeholder=\\{'
33
+
34
+ if echo "$NEW_CONTENT" | grep -qE "$SSOT_KEYWORDS"; then
35
+ # Check if new content cites spec.md SSOT table
36
+ if ! echo "$NEW_CONTENT" | grep -qE "(spec\\.md.*(§[A-F]|canonical table|Trigger display SSOT)|people-picker\\.spec\\.md.*L9[0-9])"; then
37
+ MSG="⚠️ PeoplePicker SSOT-bearing edit detected at ${FILE_PATH}
38
+
39
+ 動到 (tagRenderer / overflowShape / tagWrapperClassName / placeholder logic / MultiPersonDisplay 等) — 這些是 PeoplePicker SSOT-bearing API,不是 Combobox / Select 純繼承。
40
+
41
+ 必先 cite \`people-picker.spec.md\` §A-§F canonical table 對應 row,確認改動跟 SSOT 一致。違反 = 元件視覺漂移(2026-05-15 user verbatim「為什麼辯論之後會完全被 codex 帶走」+ 「避免下次再度偏移」)。
42
+
43
+ 對應 SSOT row 速查:
44
+ §A 元件本質繼承表 - 動繼承關係 / 視覺自定義 → 此處
45
+ §B 單人 trigger 5 state - 動 single mode render → 此處
46
+ §C 多人 length=1 trigger 3 state - 動 length=1 降階單人視覺 → 此處
47
+ §D 多人 length≥2 trigger 4 state - 動 stack overlap / +N 圓形 / inline-search cursor → 此處
48
+ §E 共享 SSOT - 動 avatar inset 12px / PersonDisplay / placeholder ellipsis → 此處
49
+ §F Cell-edit ↔ Field-edit 一致性 - 動 cell-registry MultiPersonCell / form PeoplePicker → 此處"
50
+
51
+ ESCAPED=$(printf '%s' "$MSG" | jq -Rs .)
52
+ printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":%s}}\n' "$ESCAPED"
53
+ fi
54
+ fi
55
+
56
+ exit 0
@@ -0,0 +1,53 @@
1
+ #!/bin/bash
2
+ # check_pixel_quantified_audit.sh — M32(a) pixel-quantified verify mechanical guardrail
3
+ #
4
+ # Per M32(2026-05-12 user 抓「audit ALL PASS 但 user 看視覺仍 broken」連環事件 4 RC absorbed):
5
+ # audit script 必驗 `rect.top / .left / .height` numeric pixel position,**不**可只驗
6
+ # `getAttribute('data-state')` / `class.includes('items-start')` attribute-existence
7
+ # = false-positive trap(DOM-structure-pass ≠ visual-pass)。
8
+ #
9
+ # Mechanical rule:scripts/visual-audit-*.mjs(or *.js)若有 `getAttribute(` 但沒 paired
10
+ # `getBoundingClientRect(` 或 `offsetTop/.offsetHeight` 量化 measurement → warn。
11
+ #
12
+ # 對齊 Material X-DataGrid visual regression / AG Grid playwright pixel snapshot canonical。
13
+
14
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
15
+
16
+ set -uo pipefail
17
+ INPUT=$(cat 2>/dev/null || echo "{}")
18
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""' 2>/dev/null)
19
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""' 2>/dev/null)
20
+ EVENT=$(echo "$INPUT" | jq -r '.hook_event_name // ""' 2>/dev/null)
21
+
22
+ case "$TOOL" in Edit|Write|MultiEdit) ;; *) exit 0 ;; esac
23
+ case "$FILE_PATH" in
24
+ */scripts/visual-audit-*.mjs|*/scripts/visual-audit-*.js) ;;
25
+ *) exit 0 ;;
26
+ esac
27
+ [ "$EVENT" != "PostToolUse" ] && exit 0
28
+ [ ! -f "$FILE_PATH" ] && exit 0
29
+
30
+ # Allowlist
31
+ head -3 "$FILE_PATH" | grep -qE '//[[:space:]]*@pixel-quantified-allow:' && exit 0
32
+
33
+ # Count getAttribute calls vs getBoundingClientRect / offsetTop / offsetHeight calls
34
+ # 2026-05-23 bug fix:`grep -c ... 2>/dev/null || echo 0` 當 zero match 時 grep exit 1 + fallback echo,
35
+ # 產生 multi-line "0\n0" string,下游 [ "$X" -eq 0 ] arithmetic 報「integer expression expected」silent skip。
36
+ # 修法:grep 不用 fallback,直接保證輸出 numeric(strip 非數字)+ default 0。
37
+ ATTR_HITS=$(grep -cE 'getAttribute\(|\.hasAttribute\(' "$FILE_PATH" 2>/dev/null)
38
+ ATTR_HITS="${ATTR_HITS//[^0-9]/}"; ATTR_HITS=${ATTR_HITS:-0}
39
+ PIXEL_HITS=$(grep -cE 'getBoundingClientRect\(|\.offsetTop\b|\.offsetHeight\b|\.offsetLeft\b|\.offsetWidth\b' "$FILE_PATH" 2>/dev/null)
40
+ PIXEL_HITS="${PIXEL_HITS//[^0-9]/}"; PIXEL_HITS=${PIXEL_HITS:-0}
41
+
42
+ if [ "$ATTR_HITS" -gt 0 ] && [ "$PIXEL_HITS" -eq 0 ]; then
43
+ CTX="⚠️ M32(a) pixel-quantified verify gap:
44
+ ${FILE_PATH}:
45
+ - getAttribute / hasAttribute calls: ${ATTR_HITS}
46
+ - getBoundingClientRect / offsetTop calls: 0
47
+ → audit 驗 attribute 但沒驗 pixel position = M32 違反(DOM-pass ≠ visual-pass)。
48
+ 加 numeric pixel measurement(rect.top / .left / .height)真實 verify 視覺,
49
+ 或檔首加 // @pixel-quantified-allow: <reason>(structural-only audit 例如 schema check)。"
50
+ jq -n --arg ctx "$CTX" '{
51
+ hookSpecificOutput: { hookEventName: "PostToolUse", additionalContext: $ctx }
52
+ }'
53
+ fi
@@ -0,0 +1,74 @@
1
+ #!/bin/bash
2
+ # check_propose_plain_chinese.sh — Stop hook: scan AI 本 turn reply 含「要 user 決策」pattern 但用 jargon 違 propose-in-plain-chinese canonical。
3
+ #
4
+ # 對應 SSOT:.claude/memory/feedback_propose_in_plain_chinese.md
5
+ # + CLAUDE.md `# 自主執行 canonical`「SSOT-UI/UX 中文具體人話」明文
6
+ #
7
+ # User 原話 2026-05-15:「已經跟你說過任何要我決策的東西請講具體人話,為何又跟智障一樣講人聽不懂的話呢?」
8
+ #
9
+ # Mechanism:
10
+ # 1. Tail transcript 取 AI 本 turn 最後 assistant text content
11
+ # 2. Detect 決策 prompt pattern(「回 A / B / C」/「→ 選 A」/「等你拍板」/「user 決策」)
12
+ # 3. Count jargon density(「M[0-9]+」/「Dim [0-9]+」/「SSOT」/「@watch」/「frontmatter」/「stub」/etc)
13
+ # 4. Density > threshold + 含決策 prompt → warn(P1 soft inject)
14
+ #
15
+ # 不 BLOCK turn,只 inject context warning(避免 false-positive 中斷 work)
16
+
17
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
18
+
19
+ set -uo pipefail
20
+ INPUT=$(cat 2>/dev/null || echo "{}")
21
+ TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // ""' 2>/dev/null)
22
+
23
+ [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH" ] && exit 0
24
+
25
+ # 找最新 user msg line 之後的 assistant text(本 turn AI reply)
26
+ LAST_USER_LINE=$(grep -n '"role":"user"' "$TRANSCRIPT_PATH" 2>/dev/null | tail -1 | cut -d: -f1)
27
+ [ -z "$LAST_USER_LINE" ] && exit 0
28
+
29
+ AI_REPLY_TEXT=$(tail -n +$((LAST_USER_LINE+1)) "$TRANSCRIPT_PATH" 2>/dev/null | \
30
+ jq -r 'select(.message.role=="assistant") | .message.content // empty | if type=="string" then . else (.[]? | select(.type=="text") | .text // empty) end' 2>/dev/null)
31
+
32
+ [ -z "$AI_REPLY_TEXT" ] && exit 0
33
+
34
+ # Decision prompt pattern(reply 結尾含 ASK)
35
+ DECISION_RE='(回 [A-Z]|→ ?選 [A-Z]|等你(拍板|決策|回|看)|user 決策|user 拍板|拍板.{0,5}決|決策.{0,5}選|一字回|回 OK)'
36
+ HAS_DECISION=$(echo "$AI_REPLY_TEXT" | grep -cE "$DECISION_RE" 2>/dev/null)
37
+ HAS_DECISION=${HAS_DECISION:-0}
38
+
39
+ [ "$HAS_DECISION" -eq 0 ] && exit 0
40
+
41
+ # GAP 4 fix(2026-05-18 M34 codify):升級 narrow 17-keyword fixed list 到
42
+ # Python unicode 中英夾雜 density detector(對齊 check_story_invariants.sh R5.5 fix template)。
43
+ # Spec wording「任何沒中譯的縮寫 / 內部代號 / hook 名」廣義,hook 過去窄 keyword list 漏:
44
+ # Earn-existence / compound-component / Polaris-aligned / wrapper-vs-primitive / Anchor preflight
45
+ # / *-canonical-allow / L42-58 / check_xxx.sh 等。
46
+ #
47
+ # 升級邏輯:
48
+ # (a) EXEMPT list:legitimate retained-English(framework/brand/DS API)
49
+ # (b) Density measure:jargon-word count / total Chinese-char count ratio
50
+ # (c) jargon = 英文 token 不在 EXEMPT(任何 alphanumeric word ≥ 3 char)
51
+ JARGON_COUNT=$(python3 -c "
52
+ import re, sys
53
+ text = sys.stdin.read()
54
+ EXEMPT = re.compile(r'\b(cva|Radix|Polaris|Material|Atlassian|Carbon|Ant|Apple|MUI|TanStack|shadcn|Recharts|cmdk|dnd-kit|TypeScript|JavaScript|API|UI|UX|Jira|Stripe|Notion|Figma|Linear|GitHub|Gmail|Dropbox|Slack|Spotify|Discord|Storybook|Tailwind|ARIA|WCAG|FAQ|HSL|CSS|HTML|DOM|DS|F[1-9]|TODO|FIXME|XXX|NOTE|README|MIT|JSON|YAML|TSX|CSS|HTTP|HTTPS|URL|UUID|REST|GraphQL|SDK|CDN|CI|CD|PR|RFC|MR|UI/UX|primary|secondary|tertiary|hover|focus|active|disabled|invalid|readonly|null|true|false|undefined|void)\b', re.I)
55
+ words = re.findall(r'\b[a-zA-Z][a-zA-Z\-_]{2,}\b', text)
56
+ jargon = [w for w in words if not EXEMPT.fullmatch(w)]
57
+ print(len(jargon))
58
+ " <<< "$AI_REPLY_TEXT" 2>/dev/null)
59
+ JARGON_COUNT=${JARGON_COUNT:-0}
60
+
61
+ # Threshold:含決策 prompt + jargon count ≥ 10 → warn(Python 計數較廣,threshold 提高)
62
+ THRESHOLD=10
63
+
64
+ if [ "$JARGON_COUNT" -ge "$THRESHOLD" ]; then
65
+ echo "🟡 check_propose_plain_chinese WARN:本 turn reply 含 user 決策 prompt + jargon 密度 ${JARGON_COUNT}(threshold ${THRESHOLD})" >&2
66
+ echo "" >&2
67
+ echo "→ 違反 propose-in-plain-chinese canonical(memory/feedback_propose_in_plain_chinese.md SSOT)" >&2
68
+ echo "→ User 原話「請講具體人話,為何又跟智障一樣講人聽不懂的話」" >&2
69
+ echo "→ Rewrite reply:必含 3 段(發生什麼 / 影響什麼 / 各選項 outcome — 全中文具體,禁 jargon)" >&2
70
+ echo "" >&2
71
+ # Soft warn,不 BLOCK turn(exit 0)— 讓 AI 看到 stderr 後 self-correct
72
+ fi
73
+
74
+ exit 0
@@ -0,0 +1,70 @@
1
+ #!/bin/bash
2
+ set -uo pipefail
3
+ # PreToolUse Edit/Write: enforce M18 Q0「Pre-ASK self-verify problem 真存在」.
4
+ #
5
+ # 2026-05-18 user-mandated codify after Sheet/inline-action/SurfaceBody 三題誤判事件:
6
+ # Claude propose 給 user 拍板前必先 grep DS-wide + Read 相關 spec.md 確認 problem 真存在,
7
+ # 沒 grep 就斷言「N 元件缺 X / 該 migrate」= 撤回 propose。
8
+ #
9
+ # Detection:Edit/Write content 含「propose / 請拍板 / 等你拍板 / 待你拍板 /
10
+ # 決策 N / 我推 A/B/C / 選項」keywords,**但 content 內無 file:line cite 證據**
11
+ # → P1 warn(stderr exit 0,Claude 自決撤回 OR 在 reply 補 cite)。
12
+ #
13
+ # SSOT: `.claude/skills/propose-options/SKILL.md` Q0 段 + meta-patterns.md M18。
14
+
15
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
16
+
17
+ set -euo pipefail
18
+
19
+ INPUT=$(cat)
20
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""')
21
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
22
+
23
+ case "$TOOL" in
24
+ Edit|Write|MultiEdit) ;;
25
+ *) exit 0 ;;
26
+ esac
27
+
28
+ # Only fires on planning docs / commit-style summaries / reply-style markdown
29
+ # (避 false positive on production code / 一般 spec edit)
30
+ case "$FILE_PATH" in
31
+ */planning/*.md|*/reports/*.md|*/handoff/*.md) ;;
32
+ *) exit 0 ;;
33
+ esac
34
+
35
+ NEW_CONTENT=$(echo "$INPUT" | jq -r '
36
+ (.tool_input.content // "") + "\n" +
37
+ (.tool_input.new_string // "") + "\n" +
38
+ ([.tool_input.edits[]? | .new_string] | join("\n"))
39
+ ' 2>/dev/null || echo "")
40
+
41
+ [ -z "${NEW_CONTENT//[[:space:]]/}" ] && exit 0
42
+
43
+ # Detect propose keywords
44
+ HAS_PROPOSE=$(echo "$NEW_CONTENT" | grep -cE '(請拍板|等你拍板|待你拍板|決策 [0-9N]|我推 [ABC]|選項[::]|propose for user|你決定|讓我判斷決策)' || true)
45
+
46
+ [ "$HAS_PROPOSE" = "0" ] && exit 0
47
+
48
+ # Allowed escape:檔頭 `<!-- @propose-pre-verified -->` 例外
49
+ if echo "$NEW_CONTENT" | head -3 | grep -qE '@propose-pre-verified'; then
50
+ exit 0
51
+ fi
52
+
53
+ # Check for file:line cite evidence
54
+ HAS_CITE=$(echo "$NEW_CONTENT" | grep -cE '`[a-z][a-z0-9/-]+\.(tsx|ts|css|md):[0-9]+`|`[a-z][a-z0-9/-]+\.(tsx|ts|css|md)`|`packages/design-system/src/' || true)
55
+
56
+ if [ "$HAS_CITE" = "0" ]; then
57
+ printf '⚠️ PRE-ASK SELF-VERIFY GAP(M18 Q0,P1 soft):\n' >&2
58
+ printf ' File: %s\n' "$FILE_PATH" >&2
59
+ printf ' 偵測到 propose 給 user 拍板 keyword,但 content 無 file:line cite 證據。\n' >&2
60
+ printf '\n M18 Q0 強制檢查:\n' >&2
61
+ printf ' 1. grep 既有 code DS-wide 確認 problem 真存在 (file:line)\n' >&2
62
+ printf ' 2. Read 相關 spec.md 找 canonical cite\n' >&2
63
+ printf ' 3. Read consumer usage 確認該 pattern 已在 N 處 work fine\n' >&2
64
+ printf ' 4. propose 給 user 前列具體 file:line 證據\n' >&2
65
+ printf '\n 錨例:2026-05-18 Sheet/inline-action/SurfaceBody 三題誤判 propose 浪費 user 時間\n' >&2
66
+ printf ' SSOT: .claude/skills/propose-options/SKILL.md Q0 段\n' >&2
67
+ printf ' Escape: 檔頭加 <!-- @propose-pre-verified --> 若已 verify(rationale 必明示)\n' >&2
68
+ fi
69
+
70
+ exit 0
@@ -0,0 +1,58 @@
1
+ #!/bin/bash
2
+ set -uo pipefail
3
+ # PreToolUse Edit/Write: Select All ordering SSOT drift guard(2026-05-16 user verbatim
4
+ # 「以後遇到此類設計都有相同邏輯不會偏移」)
5
+ #
6
+ # 攔截 packages/design-system/src/** edit 時,如果新內容含「Select All」 / 「checkAll」 / 「全選」 等 bulk-select
7
+ # 動作 + 自寫 ordering logic(`onValueChange?.(options.map(...))` / `[...prev, ...]` 等),
8
+ # 要求消費 `@/design-system/lib/multi-select-ordering` SSOT primitive 而非自刻。
9
+ #
10
+ # 規則 SSOT:`packages/design-system/src/lib/multi-select-ordering.ts`(applySelectAll / clearSelection)。
11
+ # 對應 Ant Transfer + Table rowSelection canonical(Layer A + Codex M31 Round 4 共識)。
12
+ #
13
+ # Soft warn(stderr,non-blocking)— 給開發者警示但不擋 ship。Edge case 真需自刻 → 在
14
+ # new content 加 `// @select-all-canonical-allow: <reason>` allowlist escape。
15
+
16
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
17
+
18
+ set -euo pipefail
19
+
20
+ INPUT=$(cat)
21
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty')
22
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
23
+ NEW_CONTENT=$(echo "$INPUT" | jq -r '.tool_input.new_string // .tool_input.content // empty')
24
+
25
+ [ -z "$FILE_PATH" ] && exit 0
26
+ [[ "$TOOL" != "Edit" && "$TOOL" != "Write" ]] && exit 0
27
+ [[ "$FILE_PATH" != *packages/design-system/src/* ]] && exit 0
28
+ # 本 SSOT primitive 檔自己不查
29
+ [[ "$FILE_PATH" == *multi-select-ordering.ts ]] && exit 0
30
+ # Allowlist
31
+ echo "$NEW_CONTENT" | grep -q "@select-all-canonical-allow" && exit 0
32
+
33
+ # Detect Select-All-like pattern:
34
+ # - function name contains SelectAll / CheckAll
35
+ # - `[...prev`-style append with `options.map`-style source values
36
+ # - 顯式「全部」 button click → onValueChange
37
+ HAS_SELECTALL_HANDLER=$(echo "$NEW_CONTENT" | grep -cE "(handleSelectAll|onSelectAll|onCheckAll|handleCheckAll|全選|checkAll\s*=|selectAll\s*=)" || true)
38
+
39
+ if [ "$HAS_SELECTALL_HANDLER" -gt 0 ]; then
40
+ USES_SSOT=$(echo "$NEW_CONTENT" | grep -cE "(applySelectAll|multi-select-ordering)" || true)
41
+ if [ "$USES_SSOT" -eq 0 ]; then
42
+ cat >&2 <<EOF
43
+ ⚠️ Select All ordering SSOT drift warning
44
+ File: $FILE_PATH
45
+
46
+ 偵測「Select All」/「checkAll」/「全選」 handler 但無 import \`applySelectAll\` from
47
+ \`@/design-system/lib/multi-select-ordering\`。
48
+
49
+ SSOT canonical(per Ant Transfer + Table rowSelection,Layer A + Codex M31 Round 4 共識):
50
+ preserve existing user click order + append unselected options in source order(dedup)
51
+ → \`applySelectAll(selectedValues, allOptionValues)\`
52
+
53
+ 若刻意自刻 → 加 \`// @select-all-canonical-allow: <reason>\` 在 new content 中。
54
+ EOF
55
+ fi
56
+ fi
57
+
58
+ exit 0