@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,88 @@
1
+ #!/usr/bin/env bash
2
+ # check_ssot_consultation.sh
3
+ #
4
+ # Purpose: When writing a NEW .tsx file to packages/design-system/src/components/ or
5
+ # src/explorations/, warn if the file lacks the canonical SSOT Consultation
6
+ # comment block. This enforces CLAUDE.md `# SSOT 消費 canonical` — the
7
+ # mechanical guardrail for Mindset #2 ("不憑直覺發明 / 優先消費既有").
8
+ #
9
+ # Input: $CLAUDE_TOOL_INPUT contains JSON with file_path + content for Write tool.
10
+ # Output: stderr warning if missing; exit 0 (non-blocking by design — AI decides
11
+ # whether to re-edit and add the block).
12
+
13
+ # Per-hook fire logging(enables /knowledge-prune D2 dead-hook detection)
14
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
15
+
16
+ set -euo pipefail
17
+
18
+ # Read stdin JSON payload (Claude Code hook input)
19
+ INPUT=$(cat)
20
+
21
+ # Only fire on Write tool, not Edit (Edit implies existing file, checklist should already be there)
22
+ TOOL_NAME=$(echo "$INPUT" | python3 -c "import sys, json; d = json.load(sys.stdin); print(d.get('tool_name', ''))" 2>/dev/null || echo "")
23
+ if [[ "$TOOL_NAME" != "Write" ]]; then
24
+ exit 0
25
+ fi
26
+
27
+ # Extract file_path + content
28
+ FILE_PATH=$(echo "$INPUT" | python3 -c "import sys, json; d = json.load(sys.stdin); print(d.get('tool_input', {}).get('file_path', ''))" 2>/dev/null || echo "")
29
+ CONTENT=$(echo "$INPUT" | python3 -c "import sys, json; d = json.load(sys.stdin); print(d.get('tool_input', {}).get('content', ''))" 2>/dev/null || echo "")
30
+
31
+ # Only .tsx files in design-system components or explorations
32
+ case "$FILE_PATH" in
33
+ */packages/design-system/src/components/*/*.tsx) ;;
34
+ */src/explorations/*/*.tsx) ;;
35
+ *) exit 0 ;;
36
+ esac
37
+
38
+ # Skip .stories.tsx, .anatomy.stories.tsx, .principles.stories.tsx (stories have own anatomy checks)
39
+ case "$FILE_PATH" in
40
+ *.stories.tsx) exit 0 ;;
41
+ *.test.tsx) exit 0 ;;
42
+ esac
43
+
44
+ # Check if content contains the SSOT Consultation marker.
45
+ # Canonical markers (any of):
46
+ # - `── 消費的 SSOT ──` (zh canonical block)
47
+ # - `── 實作基礎 ──` (loose form, existing elements in code)
48
+ # - `## Consumes SSOT` (future English form)
49
+ if echo "$CONTENT" | grep -qE "(消費的 SSOT|實作基礎|Consumes SSOT)"; then
50
+ exit 0
51
+ fi
52
+
53
+ # Missing — emit warning to stderr (non-blocking)
54
+ cat >&2 <<EOF
55
+ ⚠️ SSOT Consultation 檢查:新 tsx 檔缺少消費宣告
56
+
57
+ 路徑: $FILE_PATH
58
+
59
+ CLAUDE.md \`# SSOT 消費 canonical\` 要求新元件 / 新 feature 的 tsx 開頭必含
60
+ 消費宣告 comment block。這是 Mindset #2「不憑直覺發明」+ Meta-Pattern M1 的
61
+ 機械化 guardrail。
62
+
63
+ 建議模板(加到 file top 的 JSDoc):
64
+
65
+ /**
66
+ * {Component} — {定位一句話}
67
+ *
68
+ * ── 定位 ──
69
+ * {one-liner purpose}
70
+ *
71
+ * ── 實作基礎 ──
72
+ * 消費: [Button, Input, ItemInlineAction, ...] // DS components used
73
+ * 對應 pattern: [item-anatomy, action-bar]
74
+ *
75
+ * ── 消費的 SSOT ──
76
+ * - components: [...]
77
+ * - patterns: [patterns/xxx/spec.md]
78
+ * - tokens: [--layout-space-loose, --chrome-header-height]
79
+ * - spec refs: {nearest kin specs}
80
+ */
81
+
82
+ 若檔案不是新增元件(例:test / helper / type-only),可忽略本警告。
83
+ 若是新元件或重大 feature,請補齊再 commit。
84
+
85
+ (本 hook 非 blocking,只是提醒。)
86
+ EOF
87
+
88
+ exit 0
@@ -0,0 +1,20 @@
1
+ #!/bin/bash
2
+ # PostToolUse hook: remind to check sync when editing design-system files
3
+ # Per-hook fire logging(enables /knowledge-prune D2 dead-hook detection)
4
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
5
+
6
+ FILE_PATH=$(jq -r '.tool_input.file_path // empty')
7
+
8
+ # Component .tsx edited → check spec + stories
9
+ if echo "$FILE_PATH" | grep -q 'packages/design-system/src/components/.*\.tsx$' && \
10
+ ! echo "$FILE_PATH" | grep -q '\.stories\.tsx$'; then
11
+ echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":"Sync check: you just edited a design-system component .tsx file. Check if the corresponding .spec.md and .stories.tsx need updates (see CLAUDE.md sync rules)."}}'
12
+
13
+ # Spec .md edited → check stories
14
+ elif echo "$FILE_PATH" | grep -q 'packages/design-system/src/.*\.spec\.md$'; then
15
+ echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":"Sync check: you just edited a spec.md. Check if the corresponding .principles.stories.tsx and .anatomy.stories.tsx need updates to reflect the new rules."}}'
16
+
17
+ # Pattern spec/code edited → check all consumers
18
+ elif echo "$FILE_PATH" | grep -q 'packages/design-system/src/patterns/.*\.\(tsx\|md\)$'; then
19
+ echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":"Sync check: you just edited a pattern file. Check ALL consumer components listed in the pattern spec to ensure they still comply."}}'
20
+ fi
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env bash
2
+ # check_third_party_dom_verified.sh
3
+ #
4
+ # Purpose: Warn when .tsx uses `[&[data-xxx]]:` attribute selector targeting
5
+ # a 3rd-party library's internal DOM state. History: react-day-picker v9
6
+ # DateGrid used `[&[data-range-middle]]:bg-...` assuming `data-range-middle`
7
+ # existed, but v9 only emits `data-selected`/`data-disabled` etc. Attribute
8
+ # selector silently failed.
9
+ #
10
+ # This is the CLAUDE.md Meta-Pattern M2 mechanical guardrail:
11
+ # "消費 3rd-party lib 必驗 rendered DOM".
12
+ #
13
+ # Exit 0 always (non-blocking warning).
14
+
15
+ # Per-hook fire logging(enables /knowledge-prune D2 dead-hook detection)
16
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
17
+
18
+ set -euo pipefail
19
+
20
+ INPUT=$(cat)
21
+
22
+ TOOL_NAME=$(echo "$INPUT" | python3 -c "import sys, json; d = json.load(sys.stdin); print(d.get('tool_name', ''))" 2>/dev/null || echo "")
23
+ case "$TOOL_NAME" in
24
+ Write|Edit|MultiEdit) ;;
25
+ *) exit 0 ;;
26
+ esac
27
+
28
+ FILE_PATH=$(echo "$INPUT" | python3 -c "import sys, json; d = json.load(sys.stdin); print(d.get('tool_input', {}).get('file_path', ''))" 2>/dev/null || echo "")
29
+
30
+ case "$FILE_PATH" in
31
+ *.tsx) ;;
32
+ *.ts) ;;
33
+ *) exit 0 ;;
34
+ esac
35
+
36
+ # Extract new content from tool input (content for Write, new_string for Edit)
37
+ NEW_CONTENT=$(echo "$INPUT" | python3 -c "
38
+ import sys, json
39
+ d = json.load(sys.stdin)
40
+ ti = d.get('tool_input', {})
41
+ # Write: content; Edit: new_string; MultiEdit: edits[].new_string joined
42
+ if 'content' in ti:
43
+ print(ti.get('content', ''))
44
+ elif 'new_string' in ti:
45
+ print(ti.get('new_string', ''))
46
+ elif 'edits' in ti:
47
+ print('\n'.join([e.get('new_string', '') for e in ti.get('edits', [])]))
48
+ else:
49
+ print('')
50
+ " 2>/dev/null || echo "")
51
+
52
+ # Detect pattern: attribute selector targeting data-* that could be 3rd-party
53
+ # Matches: [&[data-xxx]] or [&[data-xxx=yyy]] inside className or cva strings
54
+ if ! echo "$NEW_CONTENT" | grep -qE '\[&\[data-[a-z-]+'; then
55
+ exit 0
56
+ fi
57
+
58
+ # Only warn if the file imports a known 3rd-party UI library
59
+ THIRD_PARTY_LIBS="react-day-picker|@radix-ui|cmdk|sonner|embla-carousel|react-zoom-pan-pinch|@tanstack/react-virtual|@tanstack/react-table|recharts|react-aria"
60
+
61
+ if ! echo "$NEW_CONTENT" | grep -qE "from ['\"]($THIRD_PARTY_LIBS)"; then
62
+ exit 0
63
+ fi
64
+
65
+ # Emit warning
66
+ cat >&2 <<'EOF'
67
+ ⚠️ 3rd-party DOM 驗證檢查:attribute selector 針對第三方 lib 內部 DOM
68
+
69
+ 偵測到 `[&[data-xxx]]:` 類 attribute selector,且檔案 import 了第三方 UI lib。
70
+
71
+ Meta-Pattern M2 canonical(CLAUDE.md):**消費 3rd-party lib 必驗 rendered DOM
72
+ (不信 docs)**。第三方 lib 的內部 DOM attribute 常跟 docs 不符,或在不同
73
+ version 行為漂移。
74
+
75
+ 歷史 bug anchor:
76
+ react-day-picker v9 的 Day CELL 只有 data-selected / data-disabled /
77
+ data-today / data-outside / data-focused;**data-range-start / data-range-middle
78
+ / data-range-end 不存在**。用 `[&[data-range-middle]]:bg-...` 是靜默失效。
79
+
80
+ 驗證步驟(寫這類 selector 之前)──
81
+
82
+ 1. 開 Storybook 或 dev server
83
+ 2. Inspect element 看實際 rendered DOM 有哪些 data-* attribute
84
+ 3. 或查 lib 源碼 `node_modules/{lib}/dist/` 找 emit 的 attribute 清單
85
+ 4. 確認 attribute 存在 + 在當前 version 穩定 + document 過,再寫 selector
86
+
87
+ 替代做法(若 attribute 不存在):
88
+ - 透過 lib 官方 API(classNames / components props)傳 class
89
+ - 例:react-day-picker 用 `classNames={{ range_middle: 'bg-...' }}`,
90
+ lib 內部 `getClassNamesForModifiers` 會附加到 cell
91
+
92
+ (本 hook 非 blocking,只是提醒。寫下 selector 前,請確認已驗過 DOM。)
93
+ EOF
94
+
95
+ exit 0
@@ -0,0 +1,125 @@
1
+ #!/bin/bash
2
+ # PreToolUse hook for Write:
3
+ # When creating a NEW file in a classification-sensitive dir (patterns / skills / hooks /
4
+ # components / tokens), inject the home's README.md charter as additionalContext so AI
5
+ # cannot skip seeing it before creating new classification.
6
+ #
7
+ # Design choice — non-blocking context injection (not exit 2 block):
8
+ # - Correct placements must not get blocked → zero friction when AI classifies well
9
+ # - Incorrect placements: AI sees charter, the「這裡不收」table tells AI where to go instead
10
+ # - The injection happens on EVERY Write to sensitive dirs, so AI cannot「forget」the charter
11
+ #
12
+ # Exit codes (Claude Code hook protocol):
13
+ # 0 + stdout JSON — inject additionalContext (non-blocking)
14
+
15
+ # Per-hook fire logging(enables /knowledge-prune D2 dead-hook detection)
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
+ [ "$TOOL" = "Write" ] || exit 0
25
+ [ -n "$FILE_PATH" ] || exit 0
26
+
27
+ # Skip if file already exists (overwrite, not classification event).
28
+ [ -e "$FILE_PATH" ] && exit 0
29
+
30
+ # README.md itself — the charter file, no self-reference needed.
31
+ case "$(basename "$FILE_PATH")" in
32
+ README.md) exit 0 ;;
33
+ esac
34
+
35
+ PROJECT_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
36
+
37
+ # Longest prefix first for nested matches.
38
+ SENSITIVE_DIRS=(
39
+ "$PROJECT_ROOT/packages/design-system/src/patterns"
40
+ "$PROJECT_ROOT/packages/design-system/src/components"
41
+ "$PROJECT_ROOT/packages/design-system/src/tokens"
42
+ "$PROJECT_ROOT/packages/design-system/src"
43
+ "$PROJECT_ROOT/.claude/skills"
44
+ "$PROJECT_ROOT/.claude/hooks"
45
+ "$PROJECT_ROOT/.claude/commands"
46
+ "$PROJECT_ROOT/.claude/agents"
47
+ )
48
+
49
+ MATCHED_DIR=""
50
+ for dir in "${SENSITIVE_DIRS[@]}"; do
51
+ if [[ "$FILE_PATH" == "$dir/"* ]]; then
52
+ MATCHED_DIR="$dir"
53
+ break
54
+ fi
55
+ done
56
+
57
+ [ -n "$MATCHED_DIR" ] || exit 0
58
+
59
+ README_PATH="$MATCHED_DIR/README.md"
60
+ [ -f "$README_PATH" ] || exit 0
61
+
62
+ REL_IN_HOME="${FILE_PATH#$MATCHED_DIR/}"
63
+ FIRST_SEGMENT="${REL_IN_HOME%%/*}"
64
+ NEW_SUBDIR_PATH="$MATCHED_DIR/$FIRST_SEGMENT"
65
+
66
+ IS_FLAT_FILE="false"
67
+ [ "$REL_IN_HOME" = "$FIRST_SEGMENT" ] && IS_FLAT_FILE="true"
68
+
69
+ # Flat files are CONVENTION for these dirs (per Claude Code native format):
70
+ # .claude/hooks/ — individual hook scripts
71
+ # .claude/commands/ — individual command .md files
72
+ # .claude/agents/ — individual agent .md files
73
+ # For these, flat file is not a classification anomaly; exit silently.
74
+ case "$MATCHED_DIR" in
75
+ */.claude/hooks|*/.claude/commands|*/.claude/agents)
76
+ if [ "$IS_FLAT_FILE" = "true" ]; then
77
+ exit 0
78
+ fi
79
+ ;;
80
+ esac
81
+
82
+ IS_NEW_SUBDIR="false"
83
+ if [ "$IS_FLAT_FILE" = "false" ] && [ ! -d "$NEW_SUBDIR_PATH" ]; then
84
+ IS_NEW_SUBDIR="true"
85
+ fi
86
+
87
+ # Only fire on classification events:
88
+ # - flat file directly under sensitive dir root (usually wrong — breaks convention)
89
+ # - new sub-folder creation (first time this classification exists)
90
+ # Nested writes into existing sub-folders are not classification events; stay silent.
91
+ if [ "$IS_FLAT_FILE" = "false" ] && [ "$IS_NEW_SUBDIR" = "false" ]; then
92
+ exit 0
93
+ fi
94
+
95
+ HOME_NAME="${MATCHED_DIR#$PROJECT_ROOT/}"
96
+ CHARTER_CONTENT=$(cat "$README_PATH")
97
+
98
+ if [ "$IS_FLAT_FILE" = "true" ]; then
99
+ HEADER="⚠️ FLAT FILE at $HOME_NAME/ root — convention requires sub-folder structure. Verify this is not a misplacement before proceeding."
100
+ else
101
+ HEADER="🚪 NEW SUB-FOLDER being created in $HOME_NAME/ (classification event). Verify against the charter below BEFORE the Write proceeds."
102
+ fi
103
+
104
+ cat <<EOJSON
105
+ {"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":$(jq -Rs . <<<"HOME CHARTER GATE — $HOME_NAME/
106
+
107
+ $HEADER
108
+
109
+ Path being written: $FILE_PATH
110
+
111
+ === CHARTER ($README_PATH) ===
112
+ $CHARTER_CONTENT
113
+ === END CHARTER ===
114
+
115
+ Three-question verification BEFORE proceeding with Write:
116
+ 1. Does your content match 「這裡只收」?
117
+ 2. Does it match any row of 「這裡不收」 (i.e. belongs elsewhere)?
118
+ 3. Does it pass all 「新增 criteria」?
119
+
120
+ If misplaced → STOP, cancel this Write, redirect to correct home.
121
+ If charter is outdated → update README.md first.
122
+ If placement is correct → proceed.")}}
123
+ EOJSON
124
+
125
+ exit 0
@@ -0,0 +1,109 @@
1
+ #!/bin/bash
2
+ # PostToolUse Edit|Write|MultiEdit: 對 canonical 文件的「新增 rule/section」
3
+ # 注入 3 題短 interrogation,補 M8 benchmark / Rule-of-3 / M10 下游吸收的
4
+ # runtime adherence(不是 infra,是 model 自律)。
5
+ #
6
+ # Scope(極窄,避免噪音):
7
+ # - CLAUDE.md Edit/Write
8
+ # - packages/design-system/src/**/*.spec.md Edit/Write
9
+ # - .claude/skills/*/SKILL.md Edit/Write
10
+ #
11
+ # 觸發條件(只在真正「加新 rule」時 fire):
12
+ # - Write(新檔)- 一律 fire
13
+ # - Edit:new_string 淨增 > 200 chars OR 含新 `##` heading OR 含「**M\d+**」
14
+ # (M-row 由 pre_write_subsumption_check 處理,本 hook skip 以免 double fire)
15
+ #
16
+ # Non-blocking(PostToolUse 僅注 context,AI 讀到 3 題自律回答)。
17
+ #
18
+ # Per-hook fire logging
19
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
20
+
21
+ set -euo pipefail
22
+
23
+ INPUT=$(cat)
24
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""')
25
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
26
+
27
+ case "$TOOL" in
28
+ Edit|Write|MultiEdit) ;;
29
+ *) exit 0 ;;
30
+ esac
31
+
32
+ # Scope gate
33
+ IN_SCOPE=0
34
+ case "$FILE_PATH" in
35
+ */CLAUDE.md) IN_SCOPE=1 ;;
36
+ */packages/design-system/src/*/*.spec.md) IN_SCOPE=1 ;;
37
+ */.claude/skills/*/SKILL.md) IN_SCOPE=1 ;;
38
+ esac
39
+ [ "$IN_SCOPE" = "0" ] && exit 0
40
+
41
+ # Extract new content
42
+ NEW_CONTENT=$(echo "$INPUT" | jq -r '
43
+ (.tool_input.content // "") + "\n" +
44
+ (.tool_input.new_string // "") + "\n" +
45
+ ([.tool_input.edits[]? | .new_string] | join("\n"))
46
+ ' 2>/dev/null || echo "")
47
+ OLD_CONTENT=$(echo "$INPUT" | jq -r '
48
+ (.tool_input.old_string // "") + "\n" +
49
+ ([.tool_input.edits[]? | .old_string] | join("\n"))
50
+ ' 2>/dev/null || echo "")
51
+
52
+ # Skip if M-row addition(pre_write_subsumption_check 已處理)
53
+ if echo "$NEW_CONTENT" | grep -qE '\|\s*\*\*M[0-9]+\*\*\s*\|'; then
54
+ exit 0
55
+ fi
56
+
57
+ # Trigger heuristics
58
+ TRIGGER=0
59
+ TRIGGER_REASON=""
60
+
61
+ # (a) Write(新檔)
62
+ if [ "$TOOL" = "Write" ]; then
63
+ TRIGGER=1
64
+ TRIGGER_REASON="new file"
65
+ else
66
+ # (b) Edit 淨增 > 200 chars
67
+ NEW_LEN=$(printf '%s' "$NEW_CONTENT" | wc -c | tr -d ' ')
68
+ OLD_LEN=$(printf '%s' "$OLD_CONTENT" | wc -c | tr -d ' ')
69
+ NET_ADD=$(( NEW_LEN - OLD_LEN ))
70
+ if [ "$NET_ADD" -gt 200 ]; then
71
+ TRIGGER=1
72
+ TRIGGER_REASON="net +${NET_ADD} chars"
73
+ fi
74
+ # (c) new_string 含新 `##` heading 而 old_string 不含
75
+ if echo "$NEW_CONTENT" | grep -qE '^## '; then
76
+ if ! echo "$OLD_CONTENT" | grep -qE '^## '; then
77
+ TRIGGER=1
78
+ TRIGGER_REASON="new ## section"
79
+ fi
80
+ fi
81
+ fi
82
+
83
+ [ "$TRIGGER" = "0" ] && exit 0
84
+
85
+ # Tailor prompt by file type
86
+ case "$FILE_PATH" in
87
+ */CLAUDE.md)
88
+ HOME_LABEL="CLAUDE.md"
89
+ SCOPE_NOTE="canonical 最高層;任何新規則必 benchmark + 下游吸收"
90
+ ;;
91
+ */packages/design-system/src/*/*.spec.md)
92
+ HOME_LABEL="spec.md"
93
+ SCOPE_NOTE="spec SSOT;新規則必對齊 7 維 + 近親 spec cross-check"
94
+ ;;
95
+ */.claude/skills/*/SKILL.md)
96
+ HOME_LABEL="SKILL.md"
97
+ SCOPE_NOTE="skill workflow;新步驟 / checkpoint 必 world-class 對照 + skill 重複 check"
98
+ ;;
99
+ esac
100
+
101
+ MSG="🧭 Canonical interrogation(${HOME_LABEL} ${TRIGGER_REASON})— ${SCOPE_NOTE}。3 題短 self-check:\n\n"
102
+ MSG="${MSG}1. **World-class benchmark**(M8):新 rule / pattern 有 ≥ 3 家 DS 對照嗎?列具體實作名或「無」(無 = rule 未成熟,考慮 ship 前先調研)。\n\n"
103
+ MSG="${MSG}2. **Rule-of-3**(資訊治理):本概念已在別處出現?若 ≥ 3 處 → 選 SSOT owner,其他 pointer only。確認是 SSOT 新寫還是應該 pointer?\n\n"
104
+ MSG="${MSG}3. **M10 下游吸收**:新 rule 是否讓既有某條 rule / memory / bug case 變冗餘?明寫「可刪 X」或「無下游變動」。空白不算。\n\n"
105
+ MSG="${MSG}⚠️ 回答上述 3 題(even 簡短)再繼續,避免 silent append-only 膨脹。"
106
+
107
+ ESCAPED=$(printf '%b' "$MSG" | jq -Rs .)
108
+ printf '{"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":%s}}\n' "$ESCAPED"
109
+ exit 0
@@ -0,0 +1,68 @@
1
+ #!/bin/bash
2
+ # PreToolUse hook: before editing a design-system component .tsx,
3
+ # remind AI to read the spec first.
4
+ #
5
+ # Diff-aware: skip if the edit is purely import cleanup / type-only / typo —
6
+ # spec reading not required for those. Only fire if edit touches render body,
7
+ # cva, variants, tokens, or other design-meaningful regions.
8
+ # Per-hook fire logging(enables /knowledge-prune D2 dead-hook detection)
9
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
10
+
11
+ INPUT=$(cat)
12
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
13
+
14
+ # Only trigger for design-system component .tsx files (not stories, not specs)
15
+ if ! echo "$FILE_PATH" | grep -q 'packages/design-system/src/components/.*\.tsx$'; then
16
+ exit 0
17
+ fi
18
+ echo "$FILE_PATH" | grep -q '\.stories\.tsx$' && exit 0
19
+
20
+ # Diff-aware: extract old+new content. Skip if it's purely import / export-list
21
+ # manipulation or type-alias tweaks (not design-meaningful).
22
+ DIFF_TEXT=$(echo "$INPUT" | jq -r '
23
+ (.tool_input.old_string // "") + "\n---\n" +
24
+ (.tool_input.new_string // "") + "\n---\n" +
25
+ (.tool_input.content // "") + "\n---\n" +
26
+ ([.tool_input.edits[]? | (.old_string + "\n---\n" + .new_string + "\n---\n")] | join(""))
27
+ ' 2>/dev/null || echo "")
28
+
29
+ # If diff is non-empty and consists ONLY of import lines / export lines /
30
+ # pure type annotations — skip.
31
+ if [ -n "$DIFF_TEXT" ]; then
32
+ # Strip lines that are imports / exports / type declarations / whitespace.
33
+ MEANINGFUL=$(echo "$DIFF_TEXT" | grep -vE '^[[:space:]]*(import |export (type )?\{|export type |type [A-Z]|interface [A-Z]|//|---|[[:space:]]*$|\}|\{)' | head -5)
34
+ # If nothing substantive remains, skip the nag.
35
+ [ -z "$MEANINGFUL" ] && exit 0
36
+ fi
37
+
38
+ COMP_DIR=$(echo "$FILE_PATH" | sed -n 's|.*packages/design-system/src/components/\([^/]*\)/.*|\1|p')
39
+ [ -z "$COMP_DIR" ] && exit 0
40
+
41
+ SPEC_BASENAME=$(echo "$COMP_DIR" | sed 's/\([a-z]\)\([A-Z]\)/\1-\2/g; s/\([A-Z]\)\([A-Z][a-z]\)/\1-\2/g' | tr '[:upper:]' '[:lower:]')
42
+ SPEC_PATH="${CLAUDE_PROJECT_DIR}/packages/design-system/src/components/${COMP_DIR}/${SPEC_BASENAME}.spec.md"
43
+
44
+ # Extract 禁止事項 section(如 spec 存在且有該 section)— inject 到 additionalContext
45
+ # 讓 AI 改 tsx 前機械上讀到 forbid list,不靠記憶。2026-04-24 FileUpload `files` prop
46
+ # 事件根因:spec 禁止事項寫「不在 FileUpload 自己畫 list」AI 未讀就加 prop。
47
+ FORBID_SECTION=""
48
+ if [ -f "$SPEC_PATH" ]; then
49
+ # awk 抓從「## 禁止事項」到下個 H2 前的內容(最多 40 行 cap,避免爆量)
50
+ FORBID_SECTION=$(awk '
51
+ /^## (禁止事項|Forbidden|❌)/ { in_section=1; print; next }
52
+ in_section && /^## / { exit }
53
+ in_section { print }
54
+ ' "$SPEC_PATH" 2>/dev/null | head -40)
55
+ fi
56
+
57
+ CONTEXT="⚠️ Editing ${COMP_DIR} (design-meaningful region). READ ${SPEC_BASENAME}.spec.md full 禁止事項 + Props 行為 sections before proceeding."
58
+ if [ -n "$FORBID_SECTION" ]; then
59
+ # 用 jq 安全 escape multiline content into JSON string
60
+ ESCAPED=$(printf '%s\n\n---\n\n%s' "$CONTEXT" "$FORBID_SECTION" | jq -Rs .)
61
+ cat <<EOJSON
62
+ {"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":${ESCAPED}}}
63
+ EOJSON
64
+ else
65
+ cat <<EOJSON
66
+ {"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":"${CONTEXT}"}}
67
+ EOJSON
68
+ fi
@@ -0,0 +1,39 @@
1
+ #!/bin/bash
2
+ # PreToolUse hook for Write:
3
+ # When creating a NEW {name}.spec.md under packages/design-system/src/components/{Name}/,
4
+ # inject a Layout Family declaration reminder. Prevents silent drift where
5
+ # a new component spec is created without Family 1/2/3/4 or exception declared —
6
+ # which bypasses the 4-Family Model taxonomy and accumulates classification debt.
7
+ #
8
+ # Exit: 0 + stdout JSON additionalContext (non-blocking)
9
+
10
+ # Per-hook fire logging(enables /knowledge-prune D2 dead-hook detection)
11
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
12
+
13
+ set -euo pipefail
14
+
15
+ INPUT=$(cat)
16
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""')
17
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')
18
+
19
+ [ "$TOOL" = "Write" ] || exit 0
20
+ [ -n "$FILE_PATH" ] || exit 0
21
+ [ -e "$FILE_PATH" ] && exit 0 # only fire on NEW file
22
+
23
+ # Match: packages/design-system/src/components/{Name}/{name}.spec.md (exclude nested sub-specs)
24
+ if ! echo "$FILE_PATH" | grep -qE 'packages/design-system/src/components/[^/]+/[^/]+\.spec\.md$'; then
25
+ exit 0
26
+ fi
27
+
28
+ # Exclude Field sub-specs (field-controls.spec.md, form-validation.spec.md — these are
29
+ # Field-system shared specs, not single-component specs — they inherit from field.spec.md)
30
+ BASE_NAME=$(basename "$FILE_PATH" .spec.md)
31
+ case "$BASE_NAME" in
32
+ field-controls|form-validation|field-types) exit 0 ;;
33
+ esac
34
+
35
+ cat <<EOJSON
36
+ {"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":"🏛️ NEW COMPONENT SPEC — Layout Family declaration REQUIRED in first paragraph.\n\nPath: $FILE_PATH\n\nMANDATORY first-paragraph declaration (see CLAUDE.md '# 系統內部 Layout — 4-Family Model' + patterns/element-anatomy/item-anatomy.spec.md):\n\n **Layout Family**: <one of>\n - Family 1 (Menu item layout, scanning mode)\n - Family 2 (List item layout, reading mode)\n - Family 3 (Pill layout, action trigger OR data indicator sub-profile)\n - Family 4 (Field control layout)\n - Non-family (self-contained primitive OR composite multi-section) + rationale\n\nIf Family 1/2 → consume <MenuItem> or compose item-anatomy slot primitives (<ItemIcon>, <ItemAvatar>, <ItemLabel>, <ItemSuffix>, <ItemInlineAction>), don't reinvent.\nIf Family 3 → follow Button Pill Layout.\nIf Family 4 → follow field-controls.spec.md.\nIf Non-family → spec MUST justify why (self-contained vs composite).\n\nForgetting this declaration accumulates taxonomy debt. Also consider invoking /component-quality-gate before merging this component into DS."}}
37
+ EOJSON
38
+
39
+ exit 0
@@ -0,0 +1,112 @@
1
+ #!/bin/bash
2
+ # PreToolUse Write / Edit: before adding NEW governance entry, check if existing
3
+ # homes already cover the topic. Prevents CLAUDE.md / Meta-Pattern / spec drift
4
+ # from append-only accumulation(CLAUDE.md 資訊治理 canonical「上游加 = 下游減」+
5
+ # mindset #6 + M10 exhaustive scan)。
6
+ #
7
+ # Scope A — New file(Write only):
8
+ # - new memory_*.md → grep MEMORY.md for similar topic
9
+ # - new hook → grep existing hooks for similar pattern
10
+ # - new skill → grep .claude/skills/ for similar purpose
11
+ # - new spec.md → grep existing specs for same component name
12
+ #
13
+ # Scope B — Meta-Pattern M-row addition(Edit CLAUDE.md,2026-04-25 G4):
14
+ # 當 Edit CLAUDE.md new_string 包含新增 M-row pattern(`| **M\d+** |`),prompt:
15
+ # - 列出被吸收可刪的下游 M-row / specific bug / memory entry
16
+ # - world-class benchmark(≥ 3 家,M8 強制)
17
+ # - Rule-of-3 check:本 pattern 已在 3+ 處 → 需挑 SSOT owner
18
+ #
19
+ # Output: additionalContext warning — Claude 必 acknowledge + answer 3 題才能繼續。
20
+ # Non-blocking mechanical exit(0);enforcement 靠 Claude 讀 additionalContext 自律。
21
+
22
+ # Per-hook fire logging(enables /knowledge-prune D2 dead-hook detection)
23
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
24
+
25
+ set -euo pipefail
26
+
27
+ INPUT=$(cat)
28
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
29
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty')
30
+
31
+ [ -z "$FILE_PATH" ] && exit 0
32
+
33
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
34
+ cd "$PROJECT_DIR" || exit 0
35
+
36
+ # ── Scope B: Meta-Pattern addition(Edit CLAUDE.md)── EARLY FIRE before new-file check
37
+ case "$FILE_PATH" in
38
+ */CLAUDE.md)
39
+ if [ "$TOOL_NAME" = "Edit" ] || [ "$TOOL_NAME" = "MultiEdit" ] || [ "$TOOL_NAME" = "Write" ]; then
40
+ # Pull new content(Write: tool_input.content / Edit: new_string / MultiEdit: edits[].new_string)
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
+ # Detect new M-row pattern:CLAUDE.md Meta-Pattern 表格的 row 格式
48
+ # `| **M\d+** |` 或 `| \*\*M\d+\*\* |`(markdown bold escape 不同呈現)
49
+ if echo "$NEW_CONTENT" | grep -qE '\|\s*\*\*M[0-9]+\*\*\s*\|'; then
50
+ M_ROW=$(echo "$NEW_CONTENT" | grep -oE '\*\*M[0-9]+\*\*' | head -1 | tr -d '*')
51
+ MSG="🧭 Meta-Pattern 新增偵測(${M_ROW})— CLAUDE.md 資訊治理 canonical「上游加 = 下游減」+ M8(world-class benchmark)+ M10(exhaustive scan)觸發 3 題強制 self-check:\n\n"
52
+ MSG="${MSG}1. **World-class benchmark**(M8 強制):≥ 3 家 world-class DS(Polaris / Material / Atlassian / Ant / Carbon / Apple HIG / VS Code / Figma / Slack / Notion)的對照?列具體實作名或 API。\n\n"
53
+ MSG="${MSG}2. **上游加 = 下游減**(M10 + 資訊治理 retire pipeline):新 M-row 吸收了哪些既有內容?具體列:\n"
54
+ MSG="${MSG} - 被吸收的下游 M-row(如 M3 加新章後,M5 某條變冗餘 → 可刪)\n"
55
+ MSG="${MSG} - 被吸收的 specific bug(historical-bugs.md 內記的事件)\n"
56
+ MSG="${MSG} - 被吸收的 memory entry(feedback_*.md / project_*.md)\n"
57
+ MSG="${MSG} - 「無」也要明寫(空白不算回答)\n\n"
58
+ MSG="${MSG}3. **Rule-of-3**(資訊治理 canonical):本 pattern 概念在幾處出現?若已 ≥ 3 → 選 SSOT owner,其他 pointer only。新 M-row 是 SSOT 本身還是 pointer?\n\n"
59
+ MSG="${MSG}⚠️ 未在本輪對話明確回答 3 題前,禁止 commit 這個 edit。回答後繼續 OK。"
60
+ ESCAPED=$(printf '%b' "$MSG" | jq -Rs .)
61
+ printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":%s}}\n' "$ESCAPED"
62
+ exit 0
63
+ fi
64
+ fi
65
+ ;;
66
+ esac
67
+
68
+ # ── Scope A: New file detection ──
69
+ # Only fire for NEW files (Write creates; Edit modifies existing)
70
+ [ -f "$FILE_PATH" ] && exit 0
71
+
72
+ BASENAME=$(basename "$FILE_PATH" .md)
73
+ BASENAME=${BASENAME%.sh}
74
+ BASENAME=${BASENAME%.py}
75
+
76
+ MATCHES=""
77
+
78
+ case "$FILE_PATH" in
79
+ */memory/*.md)
80
+ # Extract keywords from filename (e.g. feedback_xxx_yyy → xxx yyy)
81
+ KEYWORDS=$(echo "$BASENAME" | tr '_' ' ' | awk '{for(i=2;i<=NF;i++) printf "%s ",$i}')
82
+ MEMORY_DIR=$(dirname "$FILE_PATH")
83
+ [ -d "$MEMORY_DIR" ] && MATCHES=$(ls "$MEMORY_DIR" 2>/dev/null | grep -iE "$(echo "$KEYWORDS" | tr ' ' '|')" | head -3 || true)
84
+ HOME_LABEL="memory"
85
+ ;;
86
+ */.claude/hooks/*)
87
+ # New hook — check for similar name
88
+ KEYWORDS=$(echo "$BASENAME" | tr '_' ' ' | awk '{for(i=2;i<=NF;i++) printf "%s ",$i}')
89
+ [ -z "$KEYWORDS" ] && KEYWORDS="$BASENAME"
90
+ MATCHES=$(ls .claude/hooks/ 2>/dev/null | grep -iE "$(echo "$KEYWORDS" | tr ' ' '|')" | head -3 || true)
91
+ HOME_LABEL="hook"
92
+ ;;
93
+ */.claude/skills/*/SKILL.md)
94
+ # New skill — grep existing skill names
95
+ MATCHES=$(ls .claude/skills/ 2>/dev/null | grep -iE "$BASENAME" | head -3 || true)
96
+ HOME_LABEL="skill"
97
+ ;;
98
+ *.spec.md)
99
+ # New spec — grep existing specs for same component
100
+ MATCHES=$(find packages/design-system/src -name "${BASENAME}*" 2>/dev/null | head -3 || true)
101
+ HOME_LABEL="spec"
102
+ ;;
103
+ *) exit 0 ;;
104
+ esac
105
+
106
+ [ -z "$MATCHES" ] && exit 0
107
+
108
+ MSG="📋 Creating new ${HOME_LABEL} file: ${FILE_PATH}\nPossibly-related existing files:\n$(echo "$MATCHES" | sed 's/^/ /')\nBefore writing, verify: (a) is this a duplicate? (b) can we extend an existing file instead? (c) CLAUDE.md Rule-of-3 SSOT — if concept exists in 3+ places, pick one owner, others point."
109
+
110
+ ESCAPED=$(printf '%s' "$MSG" | jq -Rs .)
111
+ printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":%s}}\n' "$ESCAPED"
112
+ exit 0