@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.
- package/CLAUDE.md +201 -0
- package/README.md +7 -15
- package/cli-init.mjs +90 -0
- package/ds-canonical/commands/README.md +26 -0
- package/ds-canonical/commands/gov-status.md +79 -0
- package/ds-canonical/hooks/README.md +145 -0
- package/ds-canonical/hooks/_log-fire.sh +44 -0
- package/ds-canonical/hooks/block_prototype_imports.py +111 -0
- package/ds-canonical/hooks/check_app_shell_primary_header_consistency.sh +68 -0
- package/ds-canonical/hooks/check_audit_post_report_validator.sh +88 -0
- package/ds-canonical/hooks/check_audit_sample_escape.sh +73 -0
- package/ds-canonical/hooks/check_benchmark_citation.sh +106 -0
- package/ds-canonical/hooks/check_canonical_propagation.sh +189 -0
- package/ds-canonical/hooks/check_chrome_header_handcraft.sh +70 -0
- package/ds-canonical/hooks/check_codex_brief_invariants.sh +83 -0
- package/ds-canonical/hooks/check_codex_collab_5step.sh +108 -0
- package/ds-canonical/hooks/check_datatable_invariants.sh +117 -0
- package/ds-canonical/hooks/check_dim_count_drift.sh +72 -0
- package/ds-canonical/hooks/check_field_controls_contracts.sh +110 -0
- package/ds-canonical/hooks/check_field_family_invariants.sh +205 -0
- package/ds-canonical/hooks/check_file_size_budget.sh +60 -0
- package/ds-canonical/hooks/check_header_with_tabs_border.sh +87 -0
- package/ds-canonical/hooks/check_main_branch_workbench.sh +93 -0
- package/ds-canonical/hooks/check_naming_and_abstraction.sh +165 -0
- package/ds-canonical/hooks/check_opacity_token_usage.sh +149 -0
- package/ds-canonical/hooks/check_pattern_invariants.sh +194 -0
- package/ds-canonical/hooks/check_peoplepicker_ssot_drift.sh +56 -0
- package/ds-canonical/hooks/check_pixel_quantified_audit.sh +53 -0
- package/ds-canonical/hooks/check_propose_plain_chinese.sh +74 -0
- package/ds-canonical/hooks/check_propose_pre_grep_verify.sh +70 -0
- package/ds-canonical/hooks/check_select_all_canonical.sh +58 -0
- package/ds-canonical/hooks/check_solo_workflow.sh +258 -0
- package/ds-canonical/hooks/check_spec_class_drift.sh +88 -0
- package/ds-canonical/hooks/check_story_invariants.sh +612 -0
- package/ds-canonical/hooks/check_substantive_edit_approval_preflight.sh +105 -0
- package/ds-canonical/hooks/check_tab_lg_chrome_header_equal.sh +66 -0
- package/ds-canonical/hooks/check_wrapper_primitive_schema_drift.sh +104 -0
- package/ds-canonical/hooks/enforce_home_charter.sh +44 -0
- package/ds-canonical/hooks/inject_pending_self_audit.sh +204 -0
- package/ds-canonical/hooks/lib/_approval_re.sh +33 -0
- package/ds-canonical/hooks/lib/_code_quality.sh +73 -0
- package/ds-canonical/hooks/lib/_cva_default_sync.sh +69 -0
- package/ds-canonical/hooks/lib/_governance_coverage_check.sh +49 -0
- package/ds-canonical/hooks/lib/_hardcoded_strings.sh +163 -0
- package/ds-canonical/hooks/lib/_layout_space_canonical.sh +56 -0
- package/ds-canonical/hooks/lib/_overlay_handcraft.sh +141 -0
- package/ds-canonical/hooks/lib/_person_data_richness.sh +42 -0
- package/ds-canonical/hooks/lib/_story_compile_drift.sh +48 -0
- package/ds-canonical/hooks/lib/_token_hygiene.sh +95 -0
- package/ds-canonical/hooks/log_governance_fires.sh +50 -0
- package/ds-canonical/hooks/log_skill_invokes.sh +41 -0
- package/ds-canonical/hooks/post_edit_dispatcher.sh +62 -0
- package/ds-canonical/hooks/retired/check_anatomy_section_numbering.sh +106 -0
- package/ds-canonical/hooks/retired/check_avatar_hovercard.sh +90 -0
- package/ds-canonical/hooks/retired/check_button_icon_literal.sh.retired-2026-04-28 +38 -0
- package/ds-canonical/hooks/retired/check_container_breathing.sh +142 -0
- package/ds-canonical/hooks/retired/check_governance_compliance.sh +61 -0
- package/ds-canonical/hooks/retired/check_icon_only_padding_formula.sh +104 -0
- package/ds-canonical/hooks/retired/check_item_content_primitive.sh +150 -0
- package/ds-canonical/hooks/retired/check_item_list_gap.sh +153 -0
- package/ds-canonical/hooks/retired/check_sideoffset_canonical.sh +65 -0
- package/ds-canonical/hooks/retired/check_spec_iteration_tag.sh +87 -0
- package/ds-canonical/hooks/retired/check_ssot_consultation.sh +88 -0
- package/ds-canonical/hooks/retired/check_sync_update.sh +20 -0
- package/ds-canonical/hooks/retired/check_third_party_dom_verified.sh +95 -0
- package/ds-canonical/hooks/retired/enforce_home_charter.sh +125 -0
- package/ds-canonical/hooks/retired/post_edit_canonical_interrogate.sh +109 -0
- package/ds-canonical/hooks/retired/pre_edit_spec_check.sh +68 -0
- package/ds-canonical/hooks/retired/pre_new_component_spec.sh +39 -0
- package/ds-canonical/hooks/retired/pre_write_subsumption_check.sh +112 -0
- package/ds-canonical/hooks/retired/stop_meta_self_audit.sh.retired-2026-05-13 +76 -0
- package/ds-canonical/hooks/retired/tests/test_check_anatomy_section_numbering.sh +14 -0
- package/ds-canonical/hooks/retired/tests/test_check_avatar_hovercard.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_container_breathing.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_governance_compliance.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_icon_only_padding_formula.sh +79 -0
- package/ds-canonical/hooks/retired/tests/test_check_item_content_primitive.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_item_list_gap.sh +163 -0
- package/ds-canonical/hooks/retired/tests/test_check_sideoffset_canonical.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_spec_iteration_tag.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_ssot_consultation.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_sync_update.sh +14 -0
- package/ds-canonical/hooks/retired/tests/test_check_third_party_dom_verified.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_enforce_home_charter.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_pre_edit_spec_check.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_pre_new_component_spec.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_pre_write_subsumption_check.sh +63 -0
- package/ds-canonical/hooks/session_start_governance_check.sh +263 -0
- package/ds-canonical/hooks/stop_passive_logging.sh +322 -0
- package/ds-canonical/hooks/stop_self_audit.sh +450 -0
- package/ds-canonical/hooks/tests/KNOWN-BROKEN.md +15 -0
- package/ds-canonical/hooks/tests/run-all.sh +76 -0
- package/ds-canonical/hooks/tests/test_block_prototype_imports.sh +143 -0
- package/ds-canonical/hooks/tests/test_check_app_shell_primary_header_consistency.sh +140 -0
- package/ds-canonical/hooks/tests/test_check_audit_post_report_validator.sh +115 -0
- package/ds-canonical/hooks/tests/test_check_audit_sample_escape.sh +93 -0
- package/ds-canonical/hooks/tests/test_check_benchmark_citation.sh +115 -0
- package/ds-canonical/hooks/tests/test_check_canonical_propagation.sh +133 -0
- package/ds-canonical/hooks/tests/test_check_chrome_header_handcraft.sh +123 -0
- package/ds-canonical/hooks/tests/test_check_code_quality.sh +15 -0
- package/ds-canonical/hooks/tests/test_check_codex_collab_5step.sh +96 -0
- package/ds-canonical/hooks/tests/test_check_cva_default_sync.sh +15 -0
- package/ds-canonical/hooks/tests/test_check_datatable_invariants.sh +122 -0
- package/ds-canonical/hooks/tests/test_check_dim_count_drift.sh +98 -0
- package/ds-canonical/hooks/tests/test_check_field_controls_contracts.sh +126 -0
- package/ds-canonical/hooks/tests/test_check_field_family_invariants.sh +194 -0
- package/ds-canonical/hooks/tests/test_check_file_size_budget.sh +32 -0
- package/ds-canonical/hooks/tests/test_check_hardcoded_strings.sh +14 -0
- package/ds-canonical/hooks/tests/test_check_header_with_tabs_border.sh +110 -0
- package/ds-canonical/hooks/tests/test_check_layout_space_canonical.sh +73 -0
- package/ds-canonical/hooks/tests/test_check_main_branch_workbench.sh +147 -0
- package/ds-canonical/hooks/tests/test_check_naming_and_abstraction.sh +136 -0
- package/ds-canonical/hooks/tests/test_check_opacity_token_usage.sh +110 -0
- package/ds-canonical/hooks/tests/test_check_overlay_handcraft.sh +126 -0
- package/ds-canonical/hooks/tests/test_check_pattern_invariants.sh +148 -0
- package/ds-canonical/hooks/tests/test_check_peoplepicker_ssot_drift.sh +108 -0
- package/ds-canonical/hooks/tests/test_check_person_data_richness.sh +58 -0
- package/ds-canonical/hooks/tests/test_check_pixel_quantified_audit.sh +142 -0
- package/ds-canonical/hooks/tests/test_check_propose_plain_chinese.sh +126 -0
- package/ds-canonical/hooks/tests/test_check_propose_pre_grep_verify.sh +117 -0
- package/ds-canonical/hooks/tests/test_check_select_all_canonical.sh +125 -0
- package/ds-canonical/hooks/tests/test_check_solo_workflow.sh +201 -0
- package/ds-canonical/hooks/tests/test_check_spec_class_drift.sh +135 -0
- package/ds-canonical/hooks/tests/test_check_story_anatomy.sh.broken +197 -0
- package/ds-canonical/hooks/tests/test_check_story_category.sh.broken +187 -0
- package/ds-canonical/hooks/tests/test_check_story_compile_drift.sh +15 -0
- package/ds-canonical/hooks/tests/test_check_story_invariants.sh +209 -0
- package/ds-canonical/hooks/tests/test_check_story_name_jargon.sh.broken +53 -0
- package/ds-canonical/hooks/tests/test_check_story_slot_split.sh +156 -0
- package/ds-canonical/hooks/tests/test_check_substantive_edit_approval_preflight.sh +176 -0
- package/ds-canonical/hooks/tests/test_check_tab_lg_chrome_header_equal.sh +138 -0
- package/ds-canonical/hooks/tests/test_check_token_hygiene.sh +21 -0
- package/ds-canonical/hooks/tests/test_check_wrapper_primitive_schema_drift.sh +169 -0
- package/ds-canonical/hooks/tests/test_enforce_home_charter.sh +77 -0
- package/ds-canonical/hooks/tests/test_inject_pending_self_audit.sh +125 -0
- package/ds-canonical/hooks/tests/test_log_governance_fires.sh +10 -0
- package/ds-canonical/hooks/tests/test_log_skill_invokes.sh +7 -0
- package/ds-canonical/hooks/tests/test_post_edit_dispatcher.sh +108 -0
- package/ds-canonical/hooks/tests/test_session_start_governance_check.sh +143 -0
- package/ds-canonical/hooks/tests/test_stop_capture_metrics.sh +95 -0
- package/ds-canonical/hooks/tests/test_stop_governance_drift_check.sh.broken +125 -0
- package/ds-canonical/hooks/tests/test_stop_harvest_corrections.sh +10 -0
- package/ds-canonical/hooks/tests/test_stop_passive_logging.sh +100 -0
- package/ds-canonical/hooks/tests/test_stop_self_audit.sh +76 -0
- package/ds-canonical/hooks/tests/test_stop_tsc_sanity.sh +10 -0
- package/ds-canonical/references/README.md +43 -0
- package/ds-canonical/references/audit-coverage-vs-24-checklist.md +74 -0
- package/ds-canonical/references/build-ui-canonicals.md +69 -0
- package/ds-canonical/references/cva-patterns.md +41 -0
- package/ds-canonical/references/drag-canonical.md +331 -0
- package/ds-canonical/references/item-anatomy-recipe.md +225 -0
- package/ds-canonical/references/naming-conventions.md +56 -0
- package/ds-canonical/references/principle-dim-map.json +515 -0
- package/ds-canonical/references/props-naming.md +45 -0
- package/ds-canonical/references/spec-rules.md +58 -0
- package/ds-canonical/references/ssot-consultation.md +63 -0
- package/ds-canonical/references/ssot-index.md +40 -0
- package/ds-canonical/references/story-baseline-registry.json +79 -0
- package/ds-canonical/references/structural-token-retention.md +42 -0
- package/ds-canonical/references/tailwind-gotchas.md +87 -0
- package/ds-canonical/references/ui-dev-rules.md +60 -0
- package/ds-canonical/rules/README.md +34 -0
- package/ds-canonical/rules/meta-patterns.md +87 -0
- package/ds-canonical/rules/self-verify.md +53 -0
- package/ds-canonical/rules/spec-rules.md +25 -0
- package/ds-canonical/rules/story-rules.md +56 -0
- package/ds-canonical/rules/ui-development.md +87 -0
- package/ds-canonical/skills/README.md +88 -0
- package/ds-canonical/skills/bug-fix-rhythm/SKILL.md +181 -0
- package/ds-canonical/skills/code-quality-audit/SKILL.md +63 -0
- package/ds-canonical/skills/codex-collab/SKILL.md +249 -0
- package/ds-canonical/skills/codex-collab/references/brief-template.md +48 -0
- package/ds-canonical/skills/codex-collab/references/transport.md +58 -0
- package/ds-canonical/skills/codify-corrections/SKILL.md +184 -0
- package/ds-canonical/skills/codify-principle/SKILL.md +151 -0
- package/ds-canonical/skills/component-quality-gate/SKILL.md +102 -0
- package/ds-canonical/skills/component-quality-gate/references/checklist.md +79 -0
- package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +247 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/phase-a-workflow.md +123 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/phase-b-codex-brief.md +165 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/triage-rubric.md +91 -0
- package/ds-canonical/skills/delivery-handoff/SKILL.md +229 -0
- package/ds-canonical/skills/delivery-handoff/references/flow-diagram.md +180 -0
- package/ds-canonical/skills/delivery-handoff/references/handoff-template.md +177 -0
- package/ds-canonical/skills/delivery-handoff/references/inventory-checklist.md +196 -0
- package/ds-canonical/skills/design-system-audit/SKILL.md +343 -0
- package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +1260 -0
- package/ds-canonical/skills/design-system-audit/references/checkpoints.md +240 -0
- package/ds-canonical/skills/design-system-audit/references/historical-bugs.md +240 -0
- package/ds-canonical/skills/design-system-audit/references/principle-audit-protocol.md +364 -0
- package/ds-canonical/skills/design-system-audit/references/rule-placement.md +175 -0
- package/ds-canonical/skills/design-system-audit/references/spec-template.md +66 -0
- package/ds-canonical/skills/ensure-canonical/SKILL.md +196 -0
- package/ds-canonical/skills/governance-health/SKILL.md +146 -0
- package/ds-canonical/skills/knowledge-prune/SKILL.md +303 -0
- package/ds-canonical/skills/new-component/SKILL.md +170 -0
- package/ds-canonical/skills/new-component/references/new-component-checklist.md +85 -0
- package/ds-canonical/skills/performance-audit/SKILL.md +107 -0
- package/ds-canonical/skills/product-ui-audit/SKILL.md +230 -0
- package/ds-canonical/skills/product-ui-audit/references/audit-checks.md +246 -0
- package/ds-canonical/skills/product-ui-audit/references/common-misuses.md +329 -0
- package/ds-canonical/skills/product-ui-audit/references/report-template.md +159 -0
- package/ds-canonical/skills/propose-options/SKILL.md +177 -0
- package/ds-canonical/skills/prototype/SKILL.md +244 -0
- package/ds-canonical/skills/prototype/references/audit-checks.md +37 -0
- package/ds-canonical/skills/prototype/references/benchmark-sources.md +94 -0
- package/ds-canonical/skills/prototype/references/checkpoints.md +191 -0
- package/ds-canonical/skills/prototype/references/evaluation-matrix.md +141 -0
- package/ds-canonical/skills/prototype/references/ooux-template.md +198 -0
- package/ds-canonical/skills/prototype/references/proposal-template.md +229 -0
- package/ds-canonical/skills/scan-similar-bugs/SKILL.md +198 -0
- package/ds-canonical/skills/story-auto-compile-migrate/SKILL.md +159 -0
- package/ds-canonical/skills/story-writing/SKILL.md +122 -0
- package/ds-canonical/skills/story-writing/references/anatomy-standard.md +217 -0
- package/ds-canonical/skills/story-writing/references/category-templates.md +174 -0
- package/ds-canonical/skills/story-writing/references/example-selection.md +70 -0
- package/ds-canonical/skills/story-writing/references/self-check.md +20 -0
- package/ds-canonical/skills/ux-audit/SKILL.md +130 -0
- package/ds-canonical/skills/visual-audit/SKILL.md +245 -0
- package/ds-canonical/skills/visual-audit/output/.gitkeep +0 -0
- package/ds-canonical/skills/visual-audit/references/audit-architecture.md +100 -0
- package/ds-canonical/skills/visual-audit/references/visual-checklist.md +297 -0
- package/ds-canonical/skills/visual-audit/references/world-class-benchmarks.md +198 -0
- package/package.json +9 -5
- package/src/components/Accordion/accordion.spec.md +114 -0
- package/src/components/Alert/alert.spec.md +197 -0
- package/src/components/AppShell/app-shell.spec.md +331 -0
- package/src/components/AspectRatio/aspect-ratio.spec.md +134 -0
- package/src/components/Avatar/avatar.spec.md +329 -0
- package/src/components/Badge/badge.spec.md +380 -0
- package/src/components/Breadcrumb/breadcrumb.spec.md +257 -0
- package/src/components/BulkActionBar/bulk-action-bar.spec.md +210 -0
- package/src/components/Button/button.spec.md +460 -0
- package/src/components/Calendar/calendar.spec.md +242 -0
- package/src/components/Carousel/carousel.spec.md +253 -0
- package/src/components/Chart/chart.spec.md +155 -0
- package/src/components/Checkbox/checkbox.spec.md +344 -0
- package/src/components/Chip/chip.spec.md +237 -0
- package/src/components/CircularProgress/circular-progress.spec.md +268 -0
- package/src/components/Coachmark/coachmark.spec.md +230 -0
- package/src/components/Combobox/combobox.spec.md +180 -0
- package/src/components/Command/command.spec.md +171 -0
- package/src/components/DataTable/data-table.spec.md +525 -0
- package/src/components/DateGrid/date-grid.spec.md +215 -0
- package/src/components/DatePicker/date-picker.spec.md +334 -0
- package/src/components/DescriptionList/description-list.spec.md +214 -0
- package/src/components/Dialog/dialog.spec.md +202 -0
- package/src/components/DropdownMenu/dropdown-menu.spec.md +250 -0
- package/src/components/Empty/empty.spec.md +214 -0
- package/src/components/Field/field-controls.spec.md +338 -0
- package/src/components/Field/field.spec.md +438 -0
- package/src/components/Field/form-validation.spec.md +152 -0
- package/src/components/FieldControlGroup/field-control-group.spec.md +176 -0
- package/src/components/FileItem/file-item.spec.md +467 -0
- package/src/components/FileUpload/file-upload.spec.md +123 -0
- package/src/components/FileViewer/file-viewer.spec.md +373 -0
- package/src/components/HoverCard/hover-card.spec.md +157 -0
- package/src/components/Input/input.spec.md +193 -0
- package/src/components/LinkInput/link-input.spec.md +130 -0
- package/src/components/Menu/menu-item.spec.md +290 -0
- package/src/components/NameCard/name-card.spec.md +171 -0
- package/src/components/Notice/notice.spec.md +149 -0
- package/src/components/NumberInput/number-input.spec.md +126 -0
- package/src/components/OverflowIndicator/overflow-indicator.spec.md +120 -0
- package/src/components/PeoplePicker/people-picker.spec.md +263 -0
- package/src/components/Popover/popover.spec.md +198 -0
- package/src/components/ProgressBar/progress-bar.spec.md +232 -0
- package/src/components/RadioGroup/radio-group.spec.md +141 -0
- package/src/components/Rating/rating.spec.md +208 -0
- package/src/components/ScrollArea/scroll-area.spec.md +145 -0
- package/src/components/SegmentedControl/segmented-control.spec.md +295 -0
- package/src/components/Select/select.spec.md +299 -0
- package/src/components/SelectMenu/select-menu.spec.md +220 -0
- package/src/components/SelectionControl/selection-item.spec.md +128 -0
- package/src/components/Separator/separator.spec.md +109 -0
- package/src/components/Sheet/sheet.spec.md +148 -0
- package/src/components/Sidebar/sidebar.spec.md +713 -0
- package/src/components/Skeleton/skeleton.spec.md +104 -0
- package/src/components/Slider/slider.spec.md +353 -0
- package/src/components/Steps/steps.spec.md +465 -0
- package/src/components/Switch/switch.spec.md +215 -0
- package/src/components/Tabs/tabs.spec.md +314 -0
- package/src/components/Tag/tag.spec.md +282 -0
- package/src/components/Textarea/textarea.spec.md +151 -0
- package/src/components/TimePicker/time-picker.spec.md +279 -0
- package/src/components/Toast/toast.spec.md +177 -0
- package/src/components/Tooltip/tooltip.spec.md +139 -0
- package/src/components/TreeView/tree-view.spec.md +374 -0
- package/src/patterns/action-bar/action-bar.spec.md +458 -0
- package/src/patterns/element-anatomy/element-anatomy.spec.md +215 -0
- package/src/patterns/element-anatomy/inline-action.spec.md +315 -0
- package/src/patterns/element-anatomy/item-anatomy.spec.md +1042 -0
- package/src/patterns/header-canonical/header-canonical.spec.md +285 -0
- package/src/patterns/horizontal-overflow/horizontal-overflow.spec.md +191 -0
- package/src/patterns/overlay-surface/overlay-surface.spec.md +428 -0
- package/src/patterns/resize-handle/resize-handle.spec.md +109 -0
- package/src/tokens/color/color.spec.md +804 -0
- package/src/tokens/density/density.spec.md +127 -0
- package/src/tokens/elevation/elevation.spec.md +81 -0
- package/src/tokens/layoutSpace/layoutSpace.spec.md +314 -0
- package/src/tokens/motion/motion.spec.md +97 -0
- package/src/tokens/opacity/opacity.spec.md +78 -0
- package/src/tokens/orphan-tokens.spec.md +117 -0
- package/src/tokens/radius/radius.spec.md +123 -0
- package/src/tokens/typography/typography.spec.md +202 -0
- package/src/tokens/uiSize/uiSize.spec.md +438 -0
- 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
|