@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,133 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Tests for check_canonical_propagation.sh — merged 3 sub-rules
|
|
3
|
+
|
|
4
|
+
set -u
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
+
HOOK="$SCRIPT_DIR/../check_canonical_propagation.sh"
|
|
8
|
+
[ -x "$HOOK" ] || { echo "FATAL: hook not executable"; exit 1; }
|
|
9
|
+
|
|
10
|
+
PASS=0; FAIL=0; FAILED_TESTS=""
|
|
11
|
+
|
|
12
|
+
run_hook() {
|
|
13
|
+
local file_path="$1" content="$2" tool="${3:-Write}"
|
|
14
|
+
STDOUT=$(mktemp); STDERR=$(mktemp)
|
|
15
|
+
set +e
|
|
16
|
+
jq -n --arg tool "$tool" --arg fp "$file_path" --arg c "$content" \
|
|
17
|
+
'{tool_name:$tool, tool_input:{file_path:$fp, content:$c}}' \
|
|
18
|
+
| bash "$HOOK" >"$STDOUT" 2>"$STDERR"
|
|
19
|
+
EXIT=$?
|
|
20
|
+
set -e
|
|
21
|
+
STDERR_TEXT=$(cat "$STDERR"); rm -f "$STDOUT" "$STDERR"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
expect_exit() {
|
|
25
|
+
local name="$1" expect="$2" needle="${3:-}"
|
|
26
|
+
if [ "$EXIT" = "$expect" ] && { [ -z "$needle" ] || echo "$STDERR_TEXT" | grep -qF "$needle"; }; then
|
|
27
|
+
echo " PASS $name"; PASS=$((PASS+1))
|
|
28
|
+
else
|
|
29
|
+
echo " FAIL $name (expected exit $expect${needle:+ + needle '$needle'}, got exit $EXIT)"
|
|
30
|
+
echo " --- stderr ---"; echo "$STDERR_TEXT" | sed 's/^/ /'; echo " --- end ---"
|
|
31
|
+
FAIL=$((FAIL+1)); FAILED_TESTS="${FAILED_TESTS}\n - $name"
|
|
32
|
+
fi
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
echo "=== E.1 principles canonical ==="
|
|
36
|
+
|
|
37
|
+
# 1. New principles file with 0 universal core → BLOCK
|
|
38
|
+
run_hook "/r/packages/design-system/src/components/Foo/foo.principles.stories.tsx" "
|
|
39
|
+
const meta = { title: 'Design System/Components/Foo/設計原則' }
|
|
40
|
+
export default meta
|
|
41
|
+
export const SomeStory = () => <div />
|
|
42
|
+
" Write
|
|
43
|
+
expect_exit "E.1.1 0 universal core → BLOCK" 2 "principles canonical"
|
|
44
|
+
|
|
45
|
+
# 2. New principles with WhenToUse + WhenNotToUse → silent
|
|
46
|
+
run_hook "/r/packages/design-system/src/components/Foo/foo.principles.stories.tsx" "
|
|
47
|
+
const meta = { title: 'Design System/Components/Foo/設計原則' }
|
|
48
|
+
export default meta
|
|
49
|
+
export const WhenToUse = () => <div />
|
|
50
|
+
export const WhenNotToUse = () => <div />
|
|
51
|
+
" Write
|
|
52
|
+
expect_exit "E.1.2 WhenToUse+WhenNotToUse → silent" 0 ""
|
|
53
|
+
|
|
54
|
+
# 3. UsageGuidance integrated single export → silent (counts as ≥2)
|
|
55
|
+
run_hook "/r/packages/design-system/src/components/Foo/foo.principles.stories.tsx" "
|
|
56
|
+
const meta = { title: 'Design System/Components/Foo/設計原則' }
|
|
57
|
+
export default meta
|
|
58
|
+
export const UsageGuidance = () => <div />
|
|
59
|
+
" Write
|
|
60
|
+
expect_exit "E.1.3 UsageGuidance integrated → silent" 0 ""
|
|
61
|
+
|
|
62
|
+
# 4. Deprecated naming Forbidden* on new file → BLOCK
|
|
63
|
+
run_hook "/r/packages/design-system/src/components/Foo/foo.principles.stories.tsx" "
|
|
64
|
+
const meta = { title: 'Design System/Components/Foo/設計原則' }
|
|
65
|
+
export default meta
|
|
66
|
+
export const ForbiddenPatterns = () => <div />
|
|
67
|
+
export const WhenToUse = () => <div />
|
|
68
|
+
" Write
|
|
69
|
+
expect_exit "E.1.4 deprecated Forbidden* on new → BLOCK" 2 "principles canonical"
|
|
70
|
+
|
|
71
|
+
# 5. Allowlist comment → silent
|
|
72
|
+
run_hook "/r/packages/design-system/src/components/Foo/foo.principles.stories.tsx" "
|
|
73
|
+
// @principles-rationale: legacy migration
|
|
74
|
+
const meta = { title: 'Design System/Components/Foo/設計原則' }
|
|
75
|
+
export default meta
|
|
76
|
+
" Write
|
|
77
|
+
expect_exit "E.1.5 allowlist → silent" 0 ""
|
|
78
|
+
|
|
79
|
+
echo ""
|
|
80
|
+
echo "=== E.2 L3 primitive import ==="
|
|
81
|
+
|
|
82
|
+
# 6. App code import L3 → BLOCK
|
|
83
|
+
run_hook "/r/src/app/page.tsx" "
|
|
84
|
+
import { ItemInlineAction } from '@/design-system/patterns/element-anatomy/item-anatomy'
|
|
85
|
+
" Write
|
|
86
|
+
expect_exit "E.2.1 app code L3 import → BLOCK" 2 "L3 primitive import"
|
|
87
|
+
|
|
88
|
+
# 7. DS internal can import L3 → silent
|
|
89
|
+
run_hook "/r/packages/design-system/src/components/MyHost/my-host.tsx" "
|
|
90
|
+
import { ItemInlineAction } from '@/design-system/patterns/element-anatomy/item-anatomy'
|
|
91
|
+
" Write
|
|
92
|
+
expect_exit "E.2.2 DS internal L3 → silent" 0 ""
|
|
93
|
+
|
|
94
|
+
# 8. App code with allowlist comment → silent
|
|
95
|
+
run_hook "/r/src/app/special.tsx" '// @l3-import-allow: spec.md L42 documented exception
|
|
96
|
+
import { ItemInlineAction } from "@/design-system/patterns/element-anatomy/item-anatomy"
|
|
97
|
+
' Write
|
|
98
|
+
expect_exit "E.2.3 app code allowlist → silent" 0 ""
|
|
99
|
+
|
|
100
|
+
# 9. App code without L3 import → silent
|
|
101
|
+
run_hook "/r/src/app/page.tsx" "
|
|
102
|
+
import { Button } from '@/design-system/components/Button/button'
|
|
103
|
+
" Write
|
|
104
|
+
expect_exit "E.2.4 no L3 import → silent" 0 ""
|
|
105
|
+
|
|
106
|
+
echo ""
|
|
107
|
+
echo "=== E.3 spec-impl default alignment ==="
|
|
108
|
+
|
|
109
|
+
# 10. spec.md with 「預設」keyword → WARN stderr
|
|
110
|
+
run_hook "/r/packages/design-system/src/components/Foo/foo.spec.md" '
|
|
111
|
+
## Width
|
|
112
|
+
預設 = trigger-width(同 popover anchor 寬)
|
|
113
|
+
' Write
|
|
114
|
+
expect_exit "E.3.1 預設 keyword → WARN stderr" 0 "spec-impl default"
|
|
115
|
+
|
|
116
|
+
# 11. spec.md without default keyword → silent
|
|
117
|
+
run_hook "/r/packages/design-system/src/components/Foo/foo.spec.md" '
|
|
118
|
+
## Behavior
|
|
119
|
+
按下 Esc 關閉。
|
|
120
|
+
' Write
|
|
121
|
+
expect_exit "E.3.2 no default keyword → silent" 0 ""
|
|
122
|
+
|
|
123
|
+
# 12. spec.md with file-level allowlist → silent
|
|
124
|
+
run_hook "/r/packages/design-system/src/components/Foo/foo.spec.md" '// @spec-impl-allow: spec values are intentionally aspirational
|
|
125
|
+
## Width
|
|
126
|
+
預設 = trigger-width
|
|
127
|
+
' Write
|
|
128
|
+
expect_exit "E.3.3 spec allowlist → silent" 0 ""
|
|
129
|
+
|
|
130
|
+
echo ""
|
|
131
|
+
echo "═══ Results: $PASS PASS, $FAIL FAIL ═══"
|
|
132
|
+
[ "$FAIL" -gt 0 ] && { printf "Failed:%b\n" "$FAILED_TESTS"; exit 1; }
|
|
133
|
+
exit 0
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Tests for check_chrome_header_handcraft.sh
|
|
3
|
+
#
|
|
4
|
+
# Hook(PreToolUse Edit/Write/MultiEdit):packages/design-system/src/components/**/*.tsx
|
|
5
|
+
# 偵測自刻 `h-[var(--chrome-header-height)] ... border-b ... border-divider` signature
|
|
6
|
+
# → P1 soft warning stderr,exit 0(不 block)。
|
|
7
|
+
# Skip:*.stories.tsx / ChromeHeader / header-canonical / overlay-surface 內部 / `@chrome-header-handcraft-allow:` escape。
|
|
8
|
+
|
|
9
|
+
set -u
|
|
10
|
+
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
|
+
HOOK="$SCRIPT_DIR/../check_chrome_header_handcraft.sh"
|
|
13
|
+
|
|
14
|
+
if [ ! -f "$HOOK" ]; then echo "FATAL: hook not found: $HOOK"; exit 1; fi
|
|
15
|
+
|
|
16
|
+
PASS=0
|
|
17
|
+
FAIL=0
|
|
18
|
+
FAILED_TESTS=""
|
|
19
|
+
|
|
20
|
+
run_hook_write() {
|
|
21
|
+
local file_path="$1"; local content="$2"
|
|
22
|
+
local payload
|
|
23
|
+
payload=$(jq -n --arg fp "$file_path" --arg c "$content" \
|
|
24
|
+
'{tool_name: "Write", tool_input: {file_path: $fp, content: $c}}')
|
|
25
|
+
STDOUT=$(mktemp); STDERR=$(mktemp)
|
|
26
|
+
set +e
|
|
27
|
+
printf '%s' "$payload" | bash "$HOOK" >"$STDOUT" 2>"$STDERR"
|
|
28
|
+
EXIT=$?
|
|
29
|
+
set -e
|
|
30
|
+
STDERR_TEXT=$(cat "$STDERR")
|
|
31
|
+
rm -f "$STDOUT" "$STDERR"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
run_hook_edit() {
|
|
35
|
+
local file_path="$1"; local new_string="$2"
|
|
36
|
+
local payload
|
|
37
|
+
payload=$(jq -n --arg fp "$file_path" --arg ns "$new_string" \
|
|
38
|
+
'{tool_name: "Edit", tool_input: {file_path: $fp, new_string: $ns}}')
|
|
39
|
+
STDOUT=$(mktemp); STDERR=$(mktemp)
|
|
40
|
+
set +e
|
|
41
|
+
printf '%s' "$payload" | bash "$HOOK" >"$STDOUT" 2>"$STDERR"
|
|
42
|
+
EXIT=$?
|
|
43
|
+
set -e
|
|
44
|
+
STDERR_TEXT=$(cat "$STDERR")
|
|
45
|
+
rm -f "$STDOUT" "$STDERR"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
expect_pass_silent() {
|
|
49
|
+
local name="$1"
|
|
50
|
+
if [ "$EXIT" = "0" ] && [ -z "$STDERR_TEXT" ]; then
|
|
51
|
+
echo " PASS $name"; PASS=$((PASS+1))
|
|
52
|
+
else
|
|
53
|
+
echo " FAIL $name (expected silent, exit=$EXIT)"
|
|
54
|
+
echo " --- stderr ---"; echo "$STDERR_TEXT" | sed 's/^/ /'; echo " --- end ---"
|
|
55
|
+
FAIL=$((FAIL+1)); FAILED_TESTS="${FAILED_TESTS}\n - $name"
|
|
56
|
+
fi
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
expect_warn() {
|
|
60
|
+
local name="$1"; local needle="$2"
|
|
61
|
+
# exit 0 + stderr contains needle (P1 soft warn)
|
|
62
|
+
if [ "$EXIT" = "0" ] && echo "$STDERR_TEXT" | grep -qF "$needle"; then
|
|
63
|
+
echo " PASS $name"; PASS=$((PASS+1))
|
|
64
|
+
else
|
|
65
|
+
echo " FAIL $name (expected exit=0 + stderr needle '$needle', got exit $EXIT)"
|
|
66
|
+
echo " --- stderr ---"; echo "$STDERR_TEXT" | sed 's/^/ /'; echo " --- end ---"
|
|
67
|
+
FAIL=$((FAIL+1)); FAILED_TESTS="${FAILED_TESTS}\n - $name"
|
|
68
|
+
fi
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
echo "=== check_chrome_header_handcraft tests ==="
|
|
72
|
+
|
|
73
|
+
# 1. Non-DS path → skip
|
|
74
|
+
run_hook_write "/tmp/random.tsx" '<div className="h-[var(--chrome-header-height)] border-b border-divider" />'
|
|
75
|
+
expect_pass_silent "1. non-DS path → skip"
|
|
76
|
+
|
|
77
|
+
# 2. Stories file → skip
|
|
78
|
+
run_hook_write "/repo/packages/design-system/src/components/Foo/foo.stories.tsx" '
|
|
79
|
+
<div className="h-[var(--chrome-header-height)] border-b border-divider" />
|
|
80
|
+
'
|
|
81
|
+
expect_pass_silent "2. .stories.tsx → skip"
|
|
82
|
+
|
|
83
|
+
# 3. ChromeHeader primitive internal → skip
|
|
84
|
+
run_hook_write "/repo/packages/design-system/src/components/ChromeHeader/chrome-header.tsx" '
|
|
85
|
+
<div className="h-[var(--chrome-header-height)] border-b border-divider" />
|
|
86
|
+
'
|
|
87
|
+
expect_pass_silent "3. ChromeHeader/ primitive home → skip"
|
|
88
|
+
|
|
89
|
+
# 4. DS component, no chrome-header signature → silent
|
|
90
|
+
run_hook_write "/repo/packages/design-system/src/components/Foo/foo.tsx" '
|
|
91
|
+
import { Button } from "./button"
|
|
92
|
+
export const Foo = () => <Button>x</Button>
|
|
93
|
+
'
|
|
94
|
+
expect_pass_silent "4. no handcraft signature → silent"
|
|
95
|
+
|
|
96
|
+
# 5. DS component with full handcraft signature → warn
|
|
97
|
+
run_hook_write "/repo/packages/design-system/src/components/Bar/bar.tsx" '
|
|
98
|
+
export const Bar = () => (
|
|
99
|
+
<div className="h-[var(--chrome-header-height)] px-loose border-b border-divider" />
|
|
100
|
+
)
|
|
101
|
+
'
|
|
102
|
+
expect_warn "5. handcraft signature → warn" "CHROME HEADER HANDCRAFT"
|
|
103
|
+
|
|
104
|
+
# 6. Escape allowlist → silent
|
|
105
|
+
run_hook_write "/repo/packages/design-system/src/components/Bar/bar.tsx" '// @chrome-header-handcraft-allow: tabs cva pattern
|
|
106
|
+
export const Bar = () => (
|
|
107
|
+
<div className="h-[var(--chrome-header-height)] px-loose border-b border-divider" />
|
|
108
|
+
)
|
|
109
|
+
'
|
|
110
|
+
expect_pass_silent "6. @chrome-header-handcraft-allow escape → silent"
|
|
111
|
+
|
|
112
|
+
# 7. Edit (new_string) with handcraft → warn
|
|
113
|
+
run_hook_edit "/repo/packages/design-system/src/components/Baz/baz.tsx" \
|
|
114
|
+
'<div className="h-[var(--chrome-header-height)] flex items-center border-b border-divider">'
|
|
115
|
+
expect_warn "7. Edit new_string with handcraft → warn" "CHROME HEADER HANDCRAFT"
|
|
116
|
+
|
|
117
|
+
echo ""
|
|
118
|
+
echo "=== Summary ==="
|
|
119
|
+
echo "Passed: $PASS / $((PASS + FAIL))"
|
|
120
|
+
if [ "$FAIL" -gt 0 ]; then
|
|
121
|
+
echo "Failed:$FAILED_TESTS"
|
|
122
|
+
exit 1
|
|
123
|
+
fi
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Smoke test for check_code_quality.sh
|
|
3
|
+
set -u
|
|
4
|
+
HOOK="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../lib/_code_quality.sh"
|
|
5
|
+
[ -x "$HOOK" ] || { echo "FATAL: hook not exec"; exit 1; }
|
|
6
|
+
PASS=0; FAIL=0
|
|
7
|
+
run_hook() {
|
|
8
|
+
local payload=$(jq -n --arg fp "$1" --arg ct "$2" '{tool_name:"Write", tool_input:{file_path:$fp, content:$ct}}')
|
|
9
|
+
STDOUT=$(echo "$payload" | bash "$HOOK" 2>&1); EXIT=$?
|
|
10
|
+
}
|
|
11
|
+
echo "Test 1: non-matching file → silent skip"
|
|
12
|
+
run_hook "/tmp/random.txt" "x"
|
|
13
|
+
[ "$EXIT" = "0" ] && [ -z "$STDOUT" ] && { echo " PASS"; PASS=$((PASS+1)); } || { echo " FAIL exit=$EXIT out=${STDOUT:0:80}"; FAIL=$((FAIL+1)); }
|
|
14
|
+
echo "Results: $PASS PASS, $FAIL FAIL"
|
|
15
|
+
[ "$FAIL" -eq 0 ] || exit 1
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Tests for check_codex_collab_5step.sh(M31 5-step canonical soft warn)
|
|
3
|
+
#
|
|
4
|
+
# Hook 規則:Bash + git commit + commit message 含 codex collab keyword(codex / Layer A own /
|
|
5
|
+
# Layer B codex / dual-track / 據理力爭 / cite battle)但缺 3 必備 marker
|
|
6
|
+
# (spec cite / verify run / verdict)→ stderr soft warn (exit 0)。
|
|
7
|
+
# Allow escape:`@codex-collab-allow: <reason>`。
|
|
8
|
+
|
|
9
|
+
set -u
|
|
10
|
+
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
|
+
HOOK="$SCRIPT_DIR/../check_codex_collab_5step.sh"
|
|
13
|
+
|
|
14
|
+
if [ ! -x "$HOOK" ]; then
|
|
15
|
+
echo "FATAL: hook not executable: $HOOK"
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
PASS=0
|
|
20
|
+
FAIL=0
|
|
21
|
+
FAILED_TESTS=""
|
|
22
|
+
|
|
23
|
+
run_hook() {
|
|
24
|
+
local tool="$1"
|
|
25
|
+
local command="$2"
|
|
26
|
+
local payload
|
|
27
|
+
payload=$(jq -n --arg t "$tool" --arg c "$command" \
|
|
28
|
+
'{tool_name: $t, tool_input: {command: $c}}')
|
|
29
|
+
STDOUT=$(mktemp); STDERR=$(mktemp)
|
|
30
|
+
set +e
|
|
31
|
+
printf '%s' "$payload" | bash "$HOOK" >"$STDOUT" 2>"$STDERR"
|
|
32
|
+
EXIT=$?
|
|
33
|
+
set -e
|
|
34
|
+
STDERR_TEXT=$(cat "$STDERR")
|
|
35
|
+
rm -f "$STDOUT" "$STDERR"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
expect_pass_silent() {
|
|
39
|
+
local name="$1"
|
|
40
|
+
if [ "$EXIT" = "0" ] && [ -z "$STDERR_TEXT" ]; then
|
|
41
|
+
echo " PASS $name"; PASS=$((PASS+1))
|
|
42
|
+
else
|
|
43
|
+
echo " FAIL $name (expected silent, exit=$EXIT)"
|
|
44
|
+
echo " --- stderr ---"; echo "$STDERR_TEXT" | sed 's/^/ /'; echo " --- end ---"
|
|
45
|
+
FAIL=$((FAIL+1)); FAILED_TESTS="${FAILED_TESTS}\n - $name"
|
|
46
|
+
fi
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
expect_warn() {
|
|
50
|
+
local name="$1"; local needle="$2"
|
|
51
|
+
if [ "$EXIT" = "0" ] && echo "$STDERR_TEXT" | grep -qF "$needle"; then
|
|
52
|
+
echo " PASS $name"; PASS=$((PASS+1))
|
|
53
|
+
else
|
|
54
|
+
echo " FAIL $name (expected warn '$needle', got exit $EXIT)"
|
|
55
|
+
echo " --- stderr ---"; echo "$STDERR_TEXT" | sed 's/^/ /'; echo " --- end ---"
|
|
56
|
+
FAIL=$((FAIL+1)); FAILED_TESTS="${FAILED_TESTS}\n - $name"
|
|
57
|
+
fi
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
echo "=== check_codex_collab_5step tests ==="
|
|
61
|
+
|
|
62
|
+
# 1. Non-Bash tool → skip
|
|
63
|
+
run_hook "Edit" "irrelevant"
|
|
64
|
+
expect_pass_silent "1. non-Bash tool → skip"
|
|
65
|
+
|
|
66
|
+
# 2. Bash non-git-commit command → skip
|
|
67
|
+
run_hook "Bash" "ls -la"
|
|
68
|
+
expect_pass_silent "2. Bash non-git-commit → skip"
|
|
69
|
+
|
|
70
|
+
# 3. git commit without codex keyword → skip
|
|
71
|
+
run_hook "Bash" "git commit -m \"fix typo in spec\""
|
|
72
|
+
expect_pass_silent "3. git commit no codex keyword → skip"
|
|
73
|
+
|
|
74
|
+
# 4. git commit WITH codex keyword but NO marker → warn
|
|
75
|
+
run_hook "Bash" "git commit -m \"codex propose accepted\""
|
|
76
|
+
expect_warn "4. codex keyword, no markers → warn" "M31 codex-collab 5-step canonical 違反"
|
|
77
|
+
|
|
78
|
+
# 5. git commit WITH codex keyword + allow escape → silent
|
|
79
|
+
run_hook "Bash" "git commit -m \"codex propose @codex-collab-allow: emergency hotfix\""
|
|
80
|
+
expect_pass_silent "5. codex keyword + @codex-collab-allow → silent"
|
|
81
|
+
|
|
82
|
+
# 6. git commit WITH codex + all 3 markers → silent
|
|
83
|
+
run_hook "Bash" "git commit -m \"codex collab agree synthesize: spec.md:L42 cite + tsc audit verify + verdict agree\""
|
|
84
|
+
expect_pass_silent "6. codex + spec cite + verify + verdict → silent"
|
|
85
|
+
|
|
86
|
+
# 7. git commit WITH cite battle keyword only(missing other 2 markers)→ warn
|
|
87
|
+
run_hook "Bash" "git commit -m \"cite battle vs codex on field-controls\""
|
|
88
|
+
expect_warn "7. cite battle only, missing verify/verdict → warn" "spec.md cite"
|
|
89
|
+
|
|
90
|
+
echo ""
|
|
91
|
+
echo "=== Summary ==="
|
|
92
|
+
echo "Passed: $PASS / $((PASS + FAIL))"
|
|
93
|
+
if [ "$FAIL" -gt 0 ]; then
|
|
94
|
+
echo "Failed:$FAILED_TESTS"
|
|
95
|
+
exit 1
|
|
96
|
+
fi
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Smoke test for check_cva_default_sync.sh
|
|
3
|
+
set -u
|
|
4
|
+
HOOK="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../lib/_cva_default_sync.sh"
|
|
5
|
+
[ -x "$HOOK" ] || { echo "FATAL: hook not exec"; exit 1; }
|
|
6
|
+
PASS=0; FAIL=0
|
|
7
|
+
run_hook() {
|
|
8
|
+
local payload=$(jq -n --arg fp "$1" --arg ct "$2" '{tool_name:"Write", tool_input:{file_path:$fp, content:$ct}}')
|
|
9
|
+
STDOUT=$(echo "$payload" | bash "$HOOK" 2>&1); EXIT=$?
|
|
10
|
+
}
|
|
11
|
+
echo "Test 1: non-matching file → silent skip"
|
|
12
|
+
run_hook "/tmp/random.txt" "x"
|
|
13
|
+
[ "$EXIT" = "0" ] && [ -z "$STDOUT" ] && { echo " PASS"; PASS=$((PASS+1)); } || { echo " FAIL exit=$EXIT out=${STDOUT:0:80}"; FAIL=$((FAIL+1)); }
|
|
14
|
+
echo "Results: $PASS PASS, $FAIL FAIL"
|
|
15
|
+
[ "$FAIL" -eq 0 ] || exit 1
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Tests for check_datatable_invariants.sh — merged 3 sub-rules
|
|
3
|
+
#
|
|
4
|
+
# 全 sub-rules 都是 P2 stderr-only(exit 0),不阻擋。verify stderr 內容對。
|
|
5
|
+
|
|
6
|
+
set -u
|
|
7
|
+
|
|
8
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
+
HOOK="$SCRIPT_DIR/../check_datatable_invariants.sh"
|
|
10
|
+
[ -x "$HOOK" ] || { echo "FATAL: hook not executable: $HOOK"; exit 1; }
|
|
11
|
+
|
|
12
|
+
PASS=0; FAIL=0; FAILED_TESTS=""
|
|
13
|
+
|
|
14
|
+
run_hook() {
|
|
15
|
+
local file_path="$1" content="$2"
|
|
16
|
+
STDOUT=$(mktemp); STDERR=$(mktemp)
|
|
17
|
+
set +e
|
|
18
|
+
jq -n --arg fp "$file_path" --arg c "$content" \
|
|
19
|
+
'{tool_name:"Write", tool_input:{file_path:$fp, content:$c}}' \
|
|
20
|
+
| bash "$HOOK" >"$STDOUT" 2>"$STDERR"
|
|
21
|
+
EXIT=$?
|
|
22
|
+
set -e
|
|
23
|
+
STDERR_TEXT=$(cat "$STDERR"); rm -f "$STDOUT" "$STDERR"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
expect_stderr() {
|
|
27
|
+
local name="$1" needle="$2"
|
|
28
|
+
if [ "$EXIT" = "0" ] && echo "$STDERR_TEXT" | grep -qF "$needle"; then
|
|
29
|
+
echo " PASS $name"; PASS=$((PASS+1))
|
|
30
|
+
else
|
|
31
|
+
echo " FAIL $name (expected stderr '$needle', exit $EXIT)"
|
|
32
|
+
echo " --- stderr ---"; echo "$STDERR_TEXT" | sed 's/^/ /'; echo " --- end ---"
|
|
33
|
+
FAIL=$((FAIL+1)); FAILED_TESTS="${FAILED_TESTS}\n - $name"
|
|
34
|
+
fi
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
expect_silent() {
|
|
38
|
+
local name="$1"
|
|
39
|
+
if [ "$EXIT" = "0" ] && [ -z "$STDERR_TEXT" ]; then
|
|
40
|
+
echo " PASS $name"; PASS=$((PASS+1))
|
|
41
|
+
else
|
|
42
|
+
echo " FAIL $name (expected silent exit 0, exit $EXIT, stderr: ${STDERR_TEXT:0:80})"
|
|
43
|
+
FAIL=$((FAIL+1)); FAILED_TESTS="${FAILED_TESTS}\n - $name"
|
|
44
|
+
fi
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
echo "=== B.1 row drag getRowId ==="
|
|
48
|
+
|
|
49
|
+
# 1. enableRowDrag without getRowId → warn
|
|
50
|
+
run_hook "/r/src/app/products.tsx" '
|
|
51
|
+
<DataTable enableRowDrag onReorder={fn} />
|
|
52
|
+
'
|
|
53
|
+
expect_stderr "B.1.1 enableRowDrag without getRowId → WARN" "row drag getRowId"
|
|
54
|
+
|
|
55
|
+
# 2. enableRowDrag + getRowId → silent
|
|
56
|
+
run_hook "/r/src/app/products.tsx" '
|
|
57
|
+
<DataTable enableRowDrag getRowId={(r) => r.id} onReorder={fn} />
|
|
58
|
+
'
|
|
59
|
+
expect_silent "B.1.2 enableRowDrag + getRowId → silent"
|
|
60
|
+
|
|
61
|
+
# 3. DataTable internal — skip
|
|
62
|
+
run_hook "/r/packages/design-system/src/components/DataTable/data-table.tsx" '
|
|
63
|
+
const x = "enableRowDrag"
|
|
64
|
+
'
|
|
65
|
+
expect_silent "B.1.3 DataTable internal skip → silent"
|
|
66
|
+
|
|
67
|
+
echo ""
|
|
68
|
+
echo "=== B.2 column size NUMBER → meta.width ==="
|
|
69
|
+
|
|
70
|
+
# 4. column with root size: NUMBER → warn
|
|
71
|
+
run_hook "/r/src/app/orders.tsx" '
|
|
72
|
+
const cols = [
|
|
73
|
+
{ accessorKey: "name", size: 240 },
|
|
74
|
+
]
|
|
75
|
+
'
|
|
76
|
+
expect_stderr "B.2.1 root size NUMBER → WARN" "column size NUMBER"
|
|
77
|
+
|
|
78
|
+
# 5. column with meta.width → silent
|
|
79
|
+
run_hook "/r/src/app/orders.tsx" '
|
|
80
|
+
const cols = [
|
|
81
|
+
{ accessorKey: "name", meta: { width: 240, type: "string" } },
|
|
82
|
+
]
|
|
83
|
+
'
|
|
84
|
+
expect_silent "B.2.2 meta.width → silent"
|
|
85
|
+
|
|
86
|
+
# 6. column with size 'md' (string density) → silent (not NUMBER)
|
|
87
|
+
run_hook "/r/src/app/orders.tsx" "
|
|
88
|
+
const cols = [
|
|
89
|
+
{ accessorKey: 'name', size: 'md' },
|
|
90
|
+
]
|
|
91
|
+
"
|
|
92
|
+
expect_silent "B.2.3 size 'md' string → silent"
|
|
93
|
+
|
|
94
|
+
# 7. cell-registry skip → silent
|
|
95
|
+
run_hook "/r/packages/design-system/src/components/DataTable/cell-registry.tsx" '
|
|
96
|
+
const cols = [{ accessorKey: "x", size: 240 }]
|
|
97
|
+
'
|
|
98
|
+
expect_silent "B.2.4 cell-registry skip → silent"
|
|
99
|
+
|
|
100
|
+
echo ""
|
|
101
|
+
echo "=== B.3 filter↔sort sibling sync ==="
|
|
102
|
+
|
|
103
|
+
# 8. edit filter panel → reminder
|
|
104
|
+
run_hook "/r/packages/design-system/src/components/DataTable/data-table-filter-panel.tsx" '
|
|
105
|
+
const x = 1
|
|
106
|
+
'
|
|
107
|
+
expect_stderr "B.3.1 edit filter → reminder" "data-table-sort-manager"
|
|
108
|
+
|
|
109
|
+
# 9. edit sort manager → reminder
|
|
110
|
+
run_hook "/r/packages/design-system/src/components/DataTable/data-table-sort-manager.tsx" '
|
|
111
|
+
const x = 1
|
|
112
|
+
'
|
|
113
|
+
expect_stderr "B.3.2 edit sort → reminder" "data-table-filter-panel"
|
|
114
|
+
|
|
115
|
+
# 10. unrelated tsx → silent
|
|
116
|
+
run_hook "/r/src/app/foo.tsx" 'const x = 1'
|
|
117
|
+
expect_silent "B.3.3 unrelated tsx → silent"
|
|
118
|
+
|
|
119
|
+
echo ""
|
|
120
|
+
echo "═══ Results: $PASS PASS, $FAIL FAIL ═══"
|
|
121
|
+
[ "$FAIL" -gt 0 ] && { printf "Failed:%b\n" "$FAILED_TESTS"; exit 1; }
|
|
122
|
+
exit 0
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Tests for check_dim_count_drift.sh(audit dim count SSOT drift P1 soft warn)
|
|
3
|
+
#
|
|
4
|
+
# Hook 規則:Edit/Write/MultiEdit + 目標 file 是 chain skill / meta-patterns / CLAUDE.md /
|
|
5
|
+
# skill SKILL.md / skill references → 偵測 `\b[1-9][0-9]+[ -]?(dim|audit dim|audit dimension)`
|
|
6
|
+
# 形 hardcode → stderr soft warn (exit 0)。
|
|
7
|
+
# Skip:design-system-audit/SKILL.md(SSOT)/ design-system-audit/references/* / out-of-scope path /
|
|
8
|
+
# 同行含「SSOT / 禁 / forbidden / example / anti-pattern / invariant / hardcode」allowed context。
|
|
9
|
+
|
|
10
|
+
set -u
|
|
11
|
+
|
|
12
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
+
HOOK="$SCRIPT_DIR/../check_dim_count_drift.sh"
|
|
14
|
+
|
|
15
|
+
if [ ! -x "$HOOK" ]; then
|
|
16
|
+
echo "FATAL: hook not executable: $HOOK"
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
PASS=0
|
|
21
|
+
FAIL=0
|
|
22
|
+
FAILED_TESTS=""
|
|
23
|
+
|
|
24
|
+
run_hook() {
|
|
25
|
+
local tool="$1"
|
|
26
|
+
local file_path="$2"
|
|
27
|
+
local content="$3"
|
|
28
|
+
local payload
|
|
29
|
+
payload=$(jq -n --arg t "$tool" --arg fp "$file_path" --arg c "$content" \
|
|
30
|
+
'{tool_name: $t, tool_input: {file_path: $fp, content: $c}}')
|
|
31
|
+
STDOUT=$(mktemp); STDERR=$(mktemp)
|
|
32
|
+
set +e
|
|
33
|
+
printf '%s' "$payload" | bash "$HOOK" >"$STDOUT" 2>"$STDERR"
|
|
34
|
+
EXIT=$?
|
|
35
|
+
set -e
|
|
36
|
+
STDERR_TEXT=$(cat "$STDERR")
|
|
37
|
+
rm -f "$STDOUT" "$STDERR"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
expect_pass_silent() {
|
|
41
|
+
local name="$1"
|
|
42
|
+
if [ "$EXIT" = "0" ] && [ -z "$STDERR_TEXT" ]; then
|
|
43
|
+
echo " PASS $name"; PASS=$((PASS+1))
|
|
44
|
+
else
|
|
45
|
+
echo " FAIL $name (expected silent, exit=$EXIT)"
|
|
46
|
+
echo " --- stderr ---"; echo "$STDERR_TEXT" | sed 's/^/ /'; echo " --- end ---"
|
|
47
|
+
FAIL=$((FAIL+1)); FAILED_TESTS="${FAILED_TESTS}\n - $name"
|
|
48
|
+
fi
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
expect_warn() {
|
|
52
|
+
local name="$1"; local needle="$2"
|
|
53
|
+
if [ "$EXIT" = "0" ] && echo "$STDERR_TEXT" | grep -qF "$needle"; then
|
|
54
|
+
echo " PASS $name"; PASS=$((PASS+1))
|
|
55
|
+
else
|
|
56
|
+
echo " FAIL $name (expected warn '$needle', got exit $EXIT)"
|
|
57
|
+
echo " --- stderr ---"; echo "$STDERR_TEXT" | sed 's/^/ /'; echo " --- end ---"
|
|
58
|
+
FAIL=$((FAIL+1)); FAILED_TESTS="${FAILED_TESTS}\n - $name"
|
|
59
|
+
fi
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
echo "=== check_dim_count_drift tests ==="
|
|
63
|
+
|
|
64
|
+
# 1. non Edit/Write tool → skip
|
|
65
|
+
run_hook "Read" "/repo/.claude/rules/meta-patterns.md" "53 dim hardcode"
|
|
66
|
+
expect_pass_silent "1. non Edit/Write → skip"
|
|
67
|
+
|
|
68
|
+
# 2. SSOT itself (design-system-audit/SKILL.md) → skip
|
|
69
|
+
run_hook "Edit" "/repo/.claude/skills/design-system-audit/SKILL.md" "53 audit dimensions covers all"
|
|
70
|
+
expect_pass_silent "2. SSOT file path → skip"
|
|
71
|
+
|
|
72
|
+
# 3. Out-of-scope file (random tsx) → skip
|
|
73
|
+
run_hook "Edit" "/repo/packages/design-system/src/foo.tsx" "53 dim hardcode"
|
|
74
|
+
expect_pass_silent "3. out-of-scope path → skip"
|
|
75
|
+
|
|
76
|
+
# 4. CLAUDE.md with hardcoded `53 dim` → warn
|
|
77
|
+
run_hook "Edit" "/repo/CLAUDE.md" "現有 53 dim 覆蓋全部"
|
|
78
|
+
expect_warn "4. CLAUDE.md + 53 dim hardcode → warn" "AUDIT DIM COUNT DRIFT"
|
|
79
|
+
|
|
80
|
+
# 5. meta-patterns.md with `46 audit dimensions` → warn
|
|
81
|
+
run_hook "Write" "/repo/.claude/rules/meta-patterns.md" "鏈到 46 audit dimensions"
|
|
82
|
+
expect_warn "5. meta-patterns + 46 audit dimensions → warn" "AUDIT DIM COUNT DRIFT"
|
|
83
|
+
|
|
84
|
+
# 6. Allowed context (line contains 'SSOT') → silent
|
|
85
|
+
run_hook "Edit" "/repo/.claude/skills/foo/SKILL.md" "53 dim SSOT 在 design-system-audit"
|
|
86
|
+
expect_pass_silent "6. line contains SSOT → allowed silent"
|
|
87
|
+
|
|
88
|
+
# 7. Allowed context (line contains '禁') → silent
|
|
89
|
+
run_hook "Edit" "/repo/.claude/skills/foo/SKILL.md" "禁 hardcode 53 dim 形式的數字"
|
|
90
|
+
expect_pass_silent "7. line contains 禁 → allowed silent"
|
|
91
|
+
|
|
92
|
+
echo ""
|
|
93
|
+
echo "=== Summary ==="
|
|
94
|
+
echo "Passed: $PASS / $((PASS + FAIL))"
|
|
95
|
+
if [ "$FAIL" -gt 0 ]; then
|
|
96
|
+
echo "Failed:$FAILED_TESTS"
|
|
97
|
+
exit 1
|
|
98
|
+
fi
|