@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,70 @@
1
+ #!/bin/bash
2
+ set -uo pipefail
3
+ # Header canonical Layer 3 ChromeHeader consumption enforcement(per header-canonical.spec.md Layer 3):
4
+ # Production chrome header 必消費 `<ChromeHeader>` primitive,
5
+ # 不可自寫 `h-[var(--chrome-header-height)] border-b border-divider px-loose` 那一套 className。
6
+ #
7
+ # PreToolUse(Edit / Write)hook —— 編輯 `packages/design-system/src/components/**/*.tsx`(非 stories)時掃:
8
+ # 檔內若有完整手刻 chrome header className signature → P1 soft warning(stderr,exit 0)。
9
+ # Migration 完成後升 P0 BLOCKER(exit 2)。
10
+ #
11
+ # 當前期(2026-05-17 land Phase 2):Sidebar / FileViewer 已 migrate 完,其他元件若新加 chrome
12
+ # header 自刻 = drift,本 hook 攔。
13
+ #
14
+ # Allow escape:檔頭 `// @chrome-header-handcraft-allow: <reason>` 豁免(Tabs cva-on-pattern 等
15
+ # 不適合用 primitive 的 case);本 hook 本身與 ChromeHeader / SurfaceHeader / SidebarHeader.tsx
16
+ # 不攔(那些是 primitive 自己)。
17
+
18
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
19
+
20
+ set -euo pipefail
21
+
22
+ INPUT=$(cat)
23
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""')
24
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
25
+
26
+ case "$TOOL" in
27
+ Edit|Write|MultiEdit) ;;
28
+ *) exit 0 ;;
29
+ esac
30
+
31
+ case "$FILE_PATH" in
32
+ */packages/design-system/src/components/**/*.tsx) ;;
33
+ *) exit 0 ;;
34
+ esac
35
+
36
+ # Skip stories
37
+ case "$FILE_PATH" in
38
+ *.stories.tsx|*.anatomy.stories.tsx|*.principles.stories.tsx) exit 0 ;;
39
+ esac
40
+
41
+ # Skip primitive home(SidebarHeader 內部消費 ChromeHeader,但仍有 className signature 引用)
42
+ case "$FILE_PATH" in
43
+ */ChromeHeader/*|*/header-canonical/*|*/overlay-surface/*) exit 0 ;;
44
+ esac
45
+
46
+ NEW_CONTENT=$(echo "$INPUT" | jq -r '
47
+ if .tool_input.new_string then .tool_input.new_string
48
+ elif .tool_input.content then .tool_input.content
49
+ else "" end
50
+ ')
51
+
52
+ # Allow escape
53
+ if echo "$NEW_CONTENT" | grep -qE '@chrome-header-handcraft-allow:'; then
54
+ exit 0
55
+ fi
56
+
57
+ # Detect handcraft signature: h-[var(--chrome-header-height)] paired with border-b border-divider
58
+ HANDCRAFT_HIT=$(echo "$NEW_CONTENT" | grep -cE 'h-\[var\(--chrome-header-height\)\][^"]*border-b[^"]*border-divider' || true)
59
+
60
+ if [ "$HANDCRAFT_HIT" -gt "0" ]; then
61
+ printf '⚠️ CHROME HEADER HANDCRAFT(soft P1,Phase 3 將升 P0):\n' >&2
62
+ printf ' File: %s\n' "$FILE_PATH" >&2
63
+ printf ' 偵測到自刻 `h-[var(--chrome-header-height)] ... border-b border-divider`\n' >&2
64
+ printf '\n SSOT: patterns/header-canonical/header-canonical.spec.md Layer 3\n' >&2
65
+ printf ' 修方向: import { ChromeHeader } from "@/design-system/patterns/header-canonical/chrome-header"\n' >&2
66
+ printf ' 替換 <div className="..."> → <ChromeHeader withTabs? lockDensity?>\n' >&2
67
+ printf ' Escape: 檔頭加 // @chrome-header-handcraft-allow: <rationale>\n' >&2
68
+ fi
69
+
70
+ exit 0
@@ -0,0 +1,83 @@
1
+ #!/bin/bash
2
+ # Codex brief invariants enforcement(2026-05-23 永久 per user verbatim「codex 跑的稽核流程理應要跟你跑的深度稽核流程是一模一樣 SSOT 的不能偏移」)
3
+ #
4
+ # PreToolUse(Bash)hook:catch codex exec / cat ... | codex exec / 任何 codex CLI invocation
5
+ # Scan codex brief content for 3 mandatory invariants(per feedback_codex_brief_invariants_2026_05_23.md):
6
+ # 1. 全盤閱讀(全部 source 列舉 or 「DS-wide」「全盤閱讀」「全 N files」 keyword)
7
+ # 2. Triple-verify(「triple-verify」/「三重驗證」/「grep + Read + canonical exception」 keyword)
8
+ # 3. 禁抽樣(「禁抽樣」/「禁 sample」/「NO-SAMPLE」/「DS-wide ALL files」 keyword)
9
+ #
10
+ # 缺任一 → exit 2 BLOCKER(stop codex 啟動)。Escape:brief 含 `// @codex-brief-invariant-skip: <rationale>`(極罕見)。
11
+
12
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
13
+
14
+ set -uo pipefail
15
+
16
+ INPUT=$(cat 2>/dev/null || echo "{}")
17
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""' 2>/dev/null)
18
+ EVENT=$(echo "$INPUT" | jq -r '.hook_event_name // ""' 2>/dev/null)
19
+
20
+ case "${TOOL:-}" in
21
+ Bash) ;;
22
+ *) exit 0 ;;
23
+ esac
24
+
25
+ CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""' 2>/dev/null)
26
+
27
+ # Only fire on codex CLI invocations
28
+ if ! echo "$CMD" | grep -qE 'codex[[:space:]]+(exec|review)|node_modules/.bin/codex'; then
29
+ exit 0
30
+ fi
31
+
32
+ # Extract brief content — handles `cat /tmp/file | codex exec` OR `codex exec "inline"` patterns
33
+ BRIEF_CONTENT=""
34
+ if echo "$CMD" | grep -qE 'cat[[:space:]]+[^|]+\|[[:space:]]*[^|]*codex'; then
35
+ # cat-pipe pattern — try reading the cat'd file
36
+ BRIEF_FILE=$(echo "$CMD" | grep -oE 'cat[[:space:]]+[^[:space:]|]+' | head -1 | sed 's/^cat[[:space:]]*//')
37
+ if [ -n "$BRIEF_FILE" ] && [ -f "$BRIEF_FILE" ]; then
38
+ BRIEF_CONTENT=$(cat "$BRIEF_FILE" 2>/dev/null)
39
+ fi
40
+ fi
41
+ # Inline prompt pattern fallback — grab everything after `codex exec` quotes
42
+ if [ -z "$BRIEF_CONTENT" ]; then
43
+ BRIEF_CONTENT="$CMD"
44
+ fi
45
+
46
+ # Escape clause
47
+ if echo "$BRIEF_CONTENT" | grep -qE '@codex-brief-invariant-skip:'; then
48
+ exit 0
49
+ fi
50
+
51
+ # Detect 3 invariants
52
+ MISSING=""
53
+
54
+ # 1. 全盤閱讀 invariant
55
+ if ! echo "$BRIEF_CONTENT" | grep -qiE '全盤閱讀|全部 source|DS-wide ALL|read all files|全部.*spec\.md|全[[:space:]]*[0-9]+[[:space:]]*spec|全[[:space:]]*[0-9]+[[:space:]]*stories|全[[:space:]]*[0-9]+[[:space:]]*components'; then
56
+ MISSING="${MISSING} • 1️⃣ 全盤閱讀 invariant 缺(「全盤閱讀全部 source」/「DS-wide ALL files」/「全 N spec.md」keyword)\n"
57
+ fi
58
+
59
+ # 2. Triple-verify invariant
60
+ if ! echo "$BRIEF_CONTENT" | grep -qiE 'triple-verify|三重驗證|grep.*Read.*canonical|grep DS-wide.*Read.*exception|前必先 inline 跑|再三確認問題|無病呻吟'; then
61
+ MISSING="${MISSING} • 2️⃣ Triple-verify invariant 缺(「triple-verify」/「三重驗證」/「禁無病呻吟」keyword)\n"
62
+ fi
63
+
64
+ # 3. 禁抽樣 invariant
65
+ if ! echo "$BRIEF_CONTENT" | grep -qiE '禁抽樣|禁 sample|NO-SAMPLE|不抽樣|sub-agent.*sampled.*reject|sample.*reject|spot-check.*reject|不應該抽樣'; then
66
+ MISSING="${MISSING} • 3️⃣ 禁抽樣 invariant 缺(「禁抽樣」/「NO-SAMPLE」/「sample = reject」keyword)\n"
67
+ fi
68
+
69
+ if [ -n "$MISSING" ]; then
70
+ printf '🚨 CODEX BRIEF MISSING INVARIANTS BLOCKER(2026-05-23 user verbatim:「codex 會跑的稽核流程理應要跟你跑的深度稽核流程是一模一樣 SSOT 的不能偏移」):\n' >&2
71
+ printf '\n Brief 缺以下 invariant:\n' >&2
72
+ printf '%b' "$MISSING" >&2
73
+ printf '\n Per memory/feedback_codex_brief_invariants_2026_05_23.md + codex-collab/references/brief-template.md:\n' >&2
74
+ printf ' 必含三 invariant 明文(verbatim):\n' >&2
75
+ printf ' 1. 全盤閱讀全部 source(列舉 N files / DS-wide / 禁憑記憶)\n' >&2
76
+ printf ' 2. Triple-verify per finding(grep + Read + canonical exception check)\n' >&2
77
+ printf ' 3. 禁抽樣(DS-wide ALL files / sub-agent sample admission = reject)\n' >&2
78
+ printf '\n 修方向:brief content 補上三 invariant 文字。\n' >&2
79
+ printf ' Escape(極罕見): brief 含 `// @codex-brief-invariant-skip: <rationale>`\n' >&2
80
+ exit 2
81
+ fi
82
+
83
+ exit 0
@@ -0,0 +1,108 @@
1
+ #!/bin/bash
2
+ set -uo pipefail
3
+ # M31 機械強制:Adversarial dual-track 5-step canonical — claude / codex 每次 collab 必走完整
4
+ # 5-step(各自熟讀 / 各自驗證 / 各自視覺稽核 / cite-based propose / 整合完美版本)。
5
+ #
6
+ # PreToolUse(Bash git commit)hook — 攔截 commit message 含 codex / Layer A / Layer B keyword
7
+ # 但**未同時**含以下 3 必備 marker:
8
+ # (a) spec.md cite — regex `spec.md:L\d+` OR `spec.md` + 引文 OR `canonical`
9
+ # (b) verify run — regex `tsc|audit|invariant|visual|playwright|grep verify`
10
+ # (c) verdict — regex `agree|disagree-with-cite|synthesize|approve|cite battle|counter-cite`
11
+ #
12
+ # Bug 史(2026-05-10):
13
+ # Issue 8 cell border:codex propose「Field edit border 透明」,Claude pass-through ship,
14
+ # 無 spec cite + 無 verify + 直接 commit → user 強烈糾正「被 codex 牽著走」。M31 universal
15
+ # mindset 應每題啟動,不只 disagree。Hook 機械強制 commit message 含 3 必備 marker,逼
16
+ # Claude 跑完整 5-step 才能 commit codex-collab work。
17
+ #
18
+ # Allow escape:
19
+ # commit message 含 `@codex-collab-allow: <reason>` 整 commit 豁免(緊急 hotfix etc)
20
+ #
21
+ # Soft warning(P1):exit 0 但 stderr 印警告 — 不 block commit(因 commit message 自由 draft,
22
+ # false-positive 太高 hard-block 會困住)。但 stop hook + session start hook 會撈 fire log
23
+ # 後續 raise 為 BLOCKER。
24
+
25
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
26
+
27
+ set -euo pipefail
28
+
29
+ INPUT=$(cat)
30
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""')
31
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
32
+
33
+ # Only Bash tool with git commit
34
+ case "$TOOL" in
35
+ Bash) ;;
36
+ *) exit 0 ;;
37
+ esac
38
+
39
+ # Match git commit -m with HEREDOC or inline message
40
+ if ! echo "$COMMAND" | grep -qE 'git commit'; then
41
+ exit 0
42
+ fi
43
+
44
+ # Extract commit message text(rough — supports HEREDOC `<<'EOF' ... EOF` + inline -m '...')
45
+ # HEREDOC pattern:`cat <<'EOF'` ... `EOF`
46
+ MSG=$(echo "$COMMAND" | sed -nE "s/.*-m \"(.*)\"$/\\1/p; /cat <<'?EOF'?/,/^EOF$/p" 2>/dev/null || true)
47
+ # Fallback:整個 command string(若 HEREDOC parse 失敗)
48
+ if [ -z "$MSG" ]; then
49
+ MSG="$COMMAND"
50
+ fi
51
+
52
+ # Allow escape
53
+ if echo "$MSG" | grep -qE '@codex-collab-allow:'; then
54
+ exit 0
55
+ fi
56
+
57
+ # Trigger check:does message mention codex collab?
58
+ TRIGGER_REGEX='codex|Layer A own|Layer B codex|dual-track|據理力爭|据理力爭|cite battle'
59
+ if ! echo "$MSG" | grep -qE "$TRIGGER_REGEX"; then
60
+ # Not a codex-collab commit — skip
61
+ exit 0
62
+ fi
63
+
64
+ # Required markers
65
+ MISSING=()
66
+
67
+ # (a) spec cite
68
+ SPEC_CITE_REGEX='spec\.md[:L0-9]|spec\.md.*L[0-9]|canonical[ 的引文]|RFC.*L[0-9]'
69
+ if ! echo "$MSG" | grep -qE "$SPEC_CITE_REGEX"; then
70
+ MISSING+=("spec.md cite(規格 path:line / 引文)")
71
+ fi
72
+
73
+ # (b) verify
74
+ VERIFY_REGEX='tsc|audit|invariant|visual|playwright|grep verify|grep .*confirm'
75
+ if ! echo "$MSG" | grep -qiE "$VERIFY_REGEX"; then
76
+ MISSING+=("verify run(tsc / audit / invariant / visual / playwright)")
77
+ fi
78
+
79
+ # (c) verdict keyword
80
+ VERDICT_REGEX='agree|disagree-with-cite|disagree.*cite|approve|synthesize|cite battle|counter-cite|verdict'
81
+ if ! echo "$MSG" | grep -qiE "$VERDICT_REGEX"; then
82
+ MISSING+=("verdict keyword(agree / disagree-with-cite / synthesize)")
83
+ fi
84
+
85
+ if [ ${#MISSING[@]} -eq 0 ]; then
86
+ exit 0
87
+ fi
88
+
89
+ # Soft warning(stderr only,exit 0 — 不 block 因 false-positive 風險)
90
+ echo "⚠️ M31 codex-collab 5-step canonical 違反(P1 soft warn):" >&2
91
+ echo " Commit 含 codex collab keyword 但缺以下 marker:" >&2
92
+ for m in "${MISSING[@]}"; do
93
+ echo " ✗ $m" >&2
94
+ done
95
+ echo "" >&2
96
+ echo " M31 universal mindset:每次 codex collab 都該完整 5-step:" >&2
97
+ echo " (1) 各自熟讀 spec.md / canonical" >&2
98
+ echo " (2) 各自驗證 tsc / audit / playwright" >&2
99
+ echo " (3) 各自視覺稽核 screenshot / DOM" >&2
100
+ echo " (4) 各自 cite-based propose" >&2
101
+ echo " (5) 整合完美版本(not pass-through)" >&2
102
+ echo "" >&2
103
+ echo " Commit message 補 cite + verify + verdict marker 再 commit。" >&2
104
+ echo " 或加 \`@codex-collab-allow: <reason>\` 緊急豁免。" >&2
105
+ echo " 詳 .claude/rules/meta-patterns.md M31 + .claude/skills/codex-collab/SKILL.md" >&2
106
+
107
+ # Soft warning — exit 0,不 block(per M31 hook design note)
108
+ exit 0
@@ -0,0 +1,117 @@
1
+ #!/bin/bash
2
+ # DataTable unified invariant hook(2026-05-08 cluster B consolidation)
3
+ #
4
+ # Merges 3 DataTable hooks(原各檔已 retire,合併入此):
5
+ # B.1 row drag getRowId(原 check_data_table_row_drag_get_row_id,P2 stderr)
6
+ # B.2 column size NUMBER → meta.width(原 check_data_table_size_num_to_meta_width,P2 stderr)
7
+ # B.3 filter↔sort sibling sync reminder(原 check_data_table_sort_parallel,P2 reminder)
8
+ #
9
+ # Why merge:皆 DataTable-family invariant,共用 INPUT parsing + tsx filter pattern。
10
+ # 散裝是 M17 SSOT 違反 + Anthropic ≤ 15 hook best-practice 偏離。
11
+ #
12
+ # 全 3 sub-rules 都是 P2 stderr-only(原檔皆 exit 0),所以本 hook 統一 exit 0。
13
+ # 同時掛 PreToolUse + PostToolUse OK(reminder 性質,雙 event fire 不 break 任何流程,
14
+ # 但本實作 settings.json 只 register PreToolUse 避免 fire 重複)。
15
+
16
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
17
+
18
+ set -uo pipefail
19
+
20
+ INPUT=$(cat)
21
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""')
22
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
23
+
24
+ case "$TOOL" in
25
+ Edit|Write|MultiEdit) ;;
26
+ *) exit 0 ;;
27
+ esac
28
+
29
+ case "$FILE_PATH" in
30
+ *.tsx) ;;
31
+ *) exit 0 ;;
32
+ esac
33
+
34
+ NEW_CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content // .tool_input.new_string // ""')
35
+
36
+ # ── B.1 row drag getRowId(P2 stderr)─────────────────────────────────────────
37
+ # Skip DataTable internal source(本身 implement enableRowDrag)
38
+ case "$FILE_PATH" in
39
+ */data-table.tsx|*/data-table.spec.md) ;; # skip B.1 + B.2 internal
40
+ *)
41
+ if echo "$NEW_CONTENT" | grep -q "enableRowDrag"; then
42
+ EXISTING=""
43
+ [ -f "$FILE_PATH" ] && EXISTING=$(cat "$FILE_PATH" 2>/dev/null || echo "")
44
+ COMBINED="$EXISTING
45
+ $NEW_CONTENT"
46
+ if ! echo "$COMBINED" | grep -q "getRowId"; then
47
+ cat >&2 <<EOF
48
+
49
+ ┄┄┄ B.1 check_datatable_invariants — row drag getRowId WARN ┄┄┄
50
+
51
+ [P2] ${FILE_PATH}
52
+ 使用 enableRowDrag 但 file 內無 getRowId — dnd 會退化用 row.index 導致 reorder 錯位。
53
+ 詳 data-table.spec.md「L4 Row drag 必填 getRowId」段。
54
+
55
+ EOF
56
+ fi
57
+ fi
58
+ ;;
59
+ esac
60
+
61
+ # ── B.2 column size NUMBER → meta.width(P2 stderr)────────────────────────────
62
+ case "$FILE_PATH" in
63
+ */data-table.tsx|*/cell-registry.tsx|*/column-types.ts) ;; # skip DS internal
64
+ *)
65
+ if echo "$NEW_CONTENT" | grep -qE "accessor[Key]?|createColumnHelper"; then
66
+ HITS=$(echo "$NEW_CONTENT" | grep -nE "size:\s*[0-9]+" | grep -v "size:\s*['\"]" || true)
67
+ if [ -n "$HITS" ]; then
68
+ cat >&2 <<EOF
69
+
70
+ ┄┄┄ B.2 check_datatable_invariants — column size NUMBER WARN ┄┄┄
71
+
72
+ [P2] ${FILE_PATH}
73
+ DataTable column def 用 root \`size: NUMBER\`(TanStack 慣例)。
74
+ DS canonical 走 \`meta.width\`(2026-05-06 v14.3,M23 命名衝突修)。
75
+
76
+ 修法:
77
+ before: { accessorKey: 'name', size: 240, meta: { type: 'string' } }
78
+ after: { accessorKey: 'name', meta: { type: 'string', width: 240 } }
79
+
80
+ 命中 lines:
81
+ $(echo "$HITS" | sed 's/^/ /')
82
+
83
+ 詳 data-table.spec.md「六之二、Column 寬度 API」。
84
+
85
+ EOF
86
+ fi
87
+ fi
88
+ ;;
89
+ esac
90
+
91
+ # ── B.3 filter↔sort sibling sync reminder(P2 reminder)────────────────────────
92
+ case "$FILE_PATH" in
93
+ *data-table-filter-panel.tsx)
94
+ cat >&2 <<EOF
95
+
96
+ ┄┄┄ B.3 check_datatable_invariants — sibling sync reminder ┄┄┄
97
+
98
+ [P2] 動到 filter panel → 是否需要對應修 data-table-sort-manager.tsx?
99
+ Self-check:row gap / row layout / row meta button / chrome corner action /
100
+ empty state 行為 / CTA button variant — sort row 是否同步?
101
+
102
+ EOF
103
+ ;;
104
+ *data-table-sort-manager.tsx)
105
+ cat >&2 <<EOF
106
+
107
+ ┄┄┄ B.3 check_datatable_invariants — sibling sync reminder ┄┄┄
108
+
109
+ [P2] 動到 sort manager → 是否需要對應修 data-table-filter-panel.tsx?
110
+ Self-check:row gap / row layout / row meta button / chrome corner action /
111
+ empty state 行為 / CTA button variant — filter row 是否同步?
112
+
113
+ EOF
114
+ ;;
115
+ esac
116
+
117
+ exit 0
@@ -0,0 +1,72 @@
1
+ #!/bin/bash
2
+ set -uo pipefail
3
+ # PreToolUse Edit/Write: enforce audit dim count SSOT integrity.
4
+ #
5
+ # SSOT: `.claude/skills/design-system-audit/SKILL.md` `## The N audit dimensions` 段。
6
+ # 任何 chain it 的 skill / spec / rule / hook 禁 hardcode 具體 dim 數字
7
+ # (e.g. `46 dim` / `53 dim` / `53-dim` / `53 audit dimensions`)— 用「全 dim」/
8
+ # 「Group A-P」/「per design-system-audit SSOT」表達。
9
+ #
10
+ # Why: 2026-05-18 user-mandated SSOT integrity after `deep-audit-cross-codex` skill
11
+ # hardcode `53 dim` 9 處 → 若 design-system-audit 升 54 dim,chain skill 漂移。
12
+ #
13
+ # P1 soft warn (stderr exit 0) — Claude decides revert or escape with rationale.
14
+ # SSOT file itself (design-system-audit/SKILL.md) is allowed to write the count.
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 // ""')
22
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
23
+
24
+ case "$TOOL" in
25
+ Edit|Write|MultiEdit) ;;
26
+ *) exit 0 ;;
27
+ esac
28
+
29
+ # Skip the SSOT itself
30
+ case "$FILE_PATH" in
31
+ */design-system-audit/SKILL.md) exit 0 ;;
32
+ */design-system-audit/references/*) exit 0 ;;
33
+ esac
34
+
35
+ # Only check files that potentially chain audit dim list
36
+ case "$FILE_PATH" in
37
+ */deep-audit-cross-codex/*|*/rules/meta-patterns.md|*/CLAUDE.md|*/skills/*/SKILL.md|*/skills/*/references/*) ;;
38
+ *) exit 0 ;;
39
+ esac
40
+
41
+ NEW_CONTENT=$(echo "$INPUT" | jq -r '
42
+ (.tool_input.content // "") + "\n" +
43
+ (.tool_input.new_string // "") + "\n" +
44
+ ([.tool_input.edits[]? | .new_string] | join("\n"))
45
+ ' 2>/dev/null || echo "")
46
+
47
+ [ -z "${NEW_CONTENT//[[:space:]]/}" ] && exit 0
48
+
49
+ # Detect hardcoded numeric dim count
50
+ # Patterns: "53 dim" / "53-dim" / "53 audit dim" / "53 audit dimensions" / "46 dim" / "46-dim"
51
+ # Exclude legitimate uses: "N dim" / "全 dim" / "<N>" placeholder / "1 dim" thru "9 dim" (could be reasonable refs)
52
+ HARDCODE_HITS=$(echo "$NEW_CONTENT" | grep -oE '\b[1-9][0-9]+[ -]?(dim|audit dim|audit dimension)' | sort -u || true)
53
+
54
+ # Allow if line contains "SSOT" / "禁" / "forbidden" / "example" / "anti-pattern" — these are invariant doc references
55
+ ALLOWED_LINES=$(echo "$NEW_CONTENT" | grep -nE '\b[1-9][0-9]+[ -]?(dim|audit dim|audit dimension)' 2>/dev/null | grep -E '(SSOT|禁|forbidden|example|anti-pattern|invariant|hardcode)' || true)
56
+
57
+ if [ -n "$HARDCODE_HITS" ]; then
58
+ # Filter out allowed lines (invariant doc context)
59
+ VIOLATION_LINES=$(echo "$NEW_CONTENT" | grep -nE '\b[1-9][0-9]+[ -]?(dim|audit dim|audit dimension)' 2>/dev/null | grep -vE '(SSOT|禁|forbidden|example|anti-pattern|invariant|hardcode)' || true)
60
+
61
+ if [ -n "$VIOLATION_LINES" ]; then
62
+ printf '⚠️ AUDIT DIM COUNT DRIFT(P1 soft):\n' >&2
63
+ printf ' File: %s\n' "$FILE_PATH" >&2
64
+ printf ' 偵測到 hardcoded audit dim count:\n%s\n' "$VIOLATION_LINES" >&2
65
+ printf '\n SSOT: `.claude/skills/design-system-audit/SKILL.md` `## The N audit dimensions`\n' >&2
66
+ printf ' 修法: 改用「全 dim」/「Group A-P」/「per design-system-audit SSOT」表達\n' >&2
67
+ printf ' 而非寫死「53 dim / 46 dim」等具體數字。\n' >&2
68
+ printf ' Why: chain skill 自動繼承 SSOT 變動,避免 design-system-audit 升 54 dim 時下游漂移。\n' >&2
69
+ fi
70
+ fi
71
+
72
+ exit 0
@@ -0,0 +1,110 @@
1
+ #!/bin/bash
2
+ # check_field_controls_contracts.sh — Stream C shared contracts(a)(b)(c) consolidated guardrail
3
+ #
4
+ # 2026-05-13 prune consolidation(per knowledge-prune Phase 2 P1):3 hook 合 1:
5
+ # - 原 check_field_placeholder_vocabulary.sh — contract (b)
6
+ # - 原 check_selected_renderer_symmetry.sh — contract (a)
7
+ # - 原 check_cell_metric_escape_hatches.sh — contract (c)
8
+ # 同 PostToolUse Edit/Write target(Field family packages/design-system/src/components/*.tsx),
9
+ # 合 1 hook 減少 hook count 從 27 → 25 回 soft cap 內,單一 entry settings.json。
10
+ # 對齊 field-controls.spec.md 共享 contract (a) Selected value renderer / (b) Placeholder vocabulary /
11
+ # (c) Cell surface metrics 3 段 canonical。
12
+
13
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
14
+
15
+ set -uo pipefail
16
+ INPUT=$(cat 2>/dev/null || echo "{}")
17
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""' 2>/dev/null)
18
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""' 2>/dev/null)
19
+ EVENT=$(echo "$INPUT" | jq -r '.hook_event_name // ""' 2>/dev/null)
20
+
21
+ case "$TOOL" in Edit|Write|MultiEdit) ;; *) exit 0 ;; esac
22
+ [ "$EVENT" != "PostToolUse" ] && exit 0
23
+ [ ! -f "$FILE_PATH" ] && exit 0
24
+
25
+ VIOLATIONS=""
26
+
27
+ # ── Contract (b) Placeholder vocabulary ───────────────────────────────────────
28
+ # Scope: 所有 packages/design-system/src/components/*.tsx
29
+ case "$FILE_PATH" in
30
+ */packages/design-system/src/components/*.tsx)
31
+ if ! head -3 "$FILE_PATH" | grep -qE '//[[:space:]]*@placeholder-vocabulary-allow:'; then
32
+ HITS=$(grep -nE 'emptyPlaceholder=\{(emptyText|searchEmpty|noResults|notFound)' "$FILE_PATH" 2>/dev/null)
33
+ if [ -n "$HITS" ]; then
34
+ VIOLATIONS="${VIOLATIONS}
35
+ [contract (b) placeholder vocabulary]:
36
+ ${HITS}
37
+ → 違反 field-controls.spec.md「共享 contract (b)」:不可 silent 把 emptyText forward 成 emptyPlaceholder(trigger-empty)。
38
+ Fix:wrapper 加 \`placeholder\` prop(trigger empty SSOT)+ \`emptyText\` 僅傳 SelectMenu noResultsText。
39
+ Allow:檔首加 \`// @placeholder-vocabulary-allow: <reason>\`。"
40
+ fi
41
+ fi
42
+ ;;
43
+ esac
44
+
45
+ # ── Contract (a) Selected value renderer symmetry ─────────────────────────────
46
+ # Scope:Combobox / Select / PeoplePicker only
47
+ case "$FILE_PATH" in
48
+ */packages/design-system/src/components/Combobox/*.tsx|*/packages/design-system/src/components/Select/*.tsx|*/packages/design-system/src/components/PeoplePicker/*.tsx)
49
+ if ! head -3 "$FILE_PATH" | grep -qE '//[[:space:]]*@renderer-symmetry-allow:'; then
50
+ DEFINES_RENDERER=$(grep -cE '(tagRenderer|selectedItemRenderer)\?:\s*\(' "$FILE_PATH" 2>/dev/null || echo 0)
51
+ DEFINES_RENDERER=${DEFINES_RENDERER:-0}
52
+ if [ "$DEFINES_RENDERER" -gt 0 ]; then
53
+ EDIT_HITS=$(grep -cE 'tagRenderer\(.*\)|selectedItemRenderer\(.*\)' "$FILE_PATH" 2>/dev/null || echo 0)
54
+ EDIT_HITS=${EDIT_HITS:-0}
55
+ DISPLAY_LINES=$(grep -nE "mode\s*=*\s*'display'|resolvedMode\s*==*\s*'display'" "$FILE_PATH" 2>/dev/null | cut -d: -f1)
56
+ if [ "$EDIT_HITS" -gt 0 ] && [ -n "$DISPLAY_LINES" ]; then
57
+ HAS_RENDERER_IN_DISPLAY=0
58
+ for LN in $DISPLAY_LINES; do
59
+ END=$((LN + 60))
60
+ if awk -v s="$LN" -v e="$END" 'NR>=s && NR<=e' "$FILE_PATH" | grep -qE 'tagRenderer|selectedItemRenderer'; then
61
+ HAS_RENDERER_IN_DISPLAY=1
62
+ break
63
+ fi
64
+ done
65
+ if [ "$HAS_RENDERER_IN_DISPLAY" -eq 0 ]; then
66
+ VIOLATIONS="${VIOLATIONS}
67
+ [contract (a) renderer symmetry]:
68
+ ${FILE_PATH}
69
+ → tagRenderer/selectedItemRenderer 定義於 props 但 display branch 沒消費 → edit-only。
70
+ 違反 field-controls.spec.md「共享 contract (a)」:rich-display renderer 必被 display/readonly/disabled/edit 4 mode 共享。
71
+ Allow:檔首加 \`// @renderer-symmetry-allow: <reason>\`。"
72
+ fi
73
+ fi
74
+ fi
75
+ fi
76
+ ;;
77
+ esac
78
+
79
+ # ── Contract (c) Cell metric escape hatches ───────────────────────────────────
80
+ # Scope:Combobox / Select / PeoplePicker only
81
+ case "$FILE_PATH" in
82
+ */packages/design-system/src/components/Combobox/*.tsx|*/packages/design-system/src/components/PeoplePicker/*.tsx|*/packages/design-system/src/components/Select/*.tsx)
83
+ if ! head -3 "$FILE_PATH" | grep -qE '//[[:space:]]*@cell-metric-escape-allow:'; then
84
+ HARDCODE_HITS=$(grep -nE 'tagAreaPaddingLeftPx=\{[0-9]+\}' "$FILE_PATH" 2>/dev/null)
85
+ COND_NO_SURFACE=$(grep -nE 'tagAreaPaddingLeftPx=\{[^}]*\?[^}]*[0-9]+[^}]*\}' "$FILE_PATH" 2>/dev/null | grep -v "surface")
86
+ WARN=""
87
+ [ -n "$HARDCODE_HITS" ] && WARN="${WARN}
88
+ [hardcode numeric without surface guard]:
89
+ ${HARDCODE_HITS}"
90
+ [ -n "$COND_NO_SURFACE" ] && WARN="${WARN}
91
+ [conditional without surface check]:
92
+ ${COND_NO_SURFACE}"
93
+ if [ -n "$WARN" ]; then
94
+ VIOLATIONS="${VIOLATIONS}
95
+ [contract (c) cell metric escape hatch]:
96
+ ${FILE_PATH}${WARN}
97
+ → 違反 field-controls.spec.md「共享 contract (c)」:cell 內禁 hardcode padding magic,改 \`useFieldSurface()\` + \`--table-cell-px\` 推導。
98
+ Fix pattern: tagAreaPaddingLeftPx={(!isEmpty && surface === 'form') ? 8 : undefined}
99
+ Allow:檔首加 \`// @cell-metric-escape-allow: <reason>\`。"
100
+ fi
101
+ fi
102
+ ;;
103
+ esac
104
+
105
+ if [ -n "$VIOLATIONS" ]; then
106
+ CTX="⚠️ Field controls shared contracts violation(consolidated check):${VIOLATIONS}"
107
+ jq -n --arg ctx "$CTX" '{
108
+ hookSpecificOutput: { hookEventName: "PostToolUse", additionalContext: $ctx }
109
+ }'
110
+ fi