@qijenchen/design-system 0.1.0-beta.83 → 0.1.0-beta.84
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 +8 -8
- package/README.md +3 -2
- package/dist/components/Alert/alert.js.map +1 -1
- package/dist/components/AppShell/_demo-helpers.d.ts.map +1 -1
- package/dist/components/AppShell/app-shell.d.ts +1 -1
- package/dist/components/AppShell/app-shell.d.ts.map +1 -1
- package/dist/components/AppShell/app-shell.js +22 -2
- package/dist/components/AppShell/app-shell.js.map +1 -1
- package/dist/components/Avatar/avatar.d.ts.map +1 -1
- package/dist/components/Avatar/avatar.js +4 -4
- package/dist/components/Avatar/avatar.js.map +1 -1
- package/dist/components/Breadcrumb/breadcrumb.d.ts.map +1 -1
- package/dist/components/Breadcrumb/breadcrumb.js +1 -1
- package/dist/components/Breadcrumb/breadcrumb.js.map +1 -1
- package/dist/components/Button/button.d.ts +2 -2
- package/dist/components/Button/button.d.ts.map +1 -1
- package/dist/components/Button/button.js +12 -3
- package/dist/components/Button/button.js.map +1 -1
- package/dist/components/Calendar/calendar.d.ts +13 -5
- package/dist/components/Calendar/calendar.d.ts.map +1 -1
- package/dist/components/Calendar/calendar.js +7 -1
- package/dist/components/Calendar/calendar.js.map +1 -1
- package/dist/components/Carousel/carousel.d.ts.map +1 -1
- package/dist/components/Carousel/carousel.js +8 -3
- package/dist/components/Carousel/carousel.js.map +1 -1
- package/dist/components/Chart/chart.d.ts.map +1 -1
- package/dist/components/Chart/chart.js +1 -0
- package/dist/components/Chart/chart.js.map +1 -1
- package/dist/components/Checkbox/checkbox.d.ts +1 -1
- package/dist/components/Checkbox/checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox/checkbox.js +8 -4
- package/dist/components/Checkbox/checkbox.js.map +1 -1
- package/dist/components/Chip/chip.d.ts +1 -1
- package/dist/components/Chip/chip.d.ts.map +1 -1
- package/dist/components/Chip/chip.js.map +1 -1
- package/dist/components/Coachmark/coachmark.d.ts +10 -3
- package/dist/components/Coachmark/coachmark.d.ts.map +1 -1
- package/dist/components/Coachmark/coachmark.js.map +1 -1
- package/dist/components/Combobox/combobox.d.ts +5 -1
- package/dist/components/Combobox/combobox.d.ts.map +1 -1
- package/dist/components/Combobox/combobox.js +30 -13
- package/dist/components/Combobox/combobox.js.map +1 -1
- package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
- package/dist/components/DataTable/cell-registry.js +53 -62
- package/dist/components/DataTable/cell-registry.js.map +1 -1
- package/dist/components/DataTable/column-types.d.ts +10 -4
- package/dist/components/DataTable/column-types.d.ts.map +1 -1
- package/dist/components/DataTable/column-types.js.map +1 -1
- package/dist/components/DataTable/data-table-column-visibility-panel.d.ts +1 -1
- package/dist/components/DataTable/data-table-column-visibility-panel.js +183 -0
- package/dist/components/DataTable/data-table-column-visibility-panel.js.map +1 -0
- package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -1
- package/dist/components/DataTable/data-table-filter-panel.js +607 -0
- package/dist/components/DataTable/data-table-filter-panel.js.map +1 -0
- package/dist/components/DataTable/data-table-interaction-layer.d.ts +11 -15
- package/dist/components/DataTable/data-table-interaction-layer.d.ts.map +1 -1
- package/dist/components/DataTable/data-table-interaction-layer.js +1 -3
- package/dist/components/DataTable/data-table-interaction-layer.js.map +1 -1
- package/dist/components/DataTable/data-table-sort-manager.js +140 -0
- package/dist/components/DataTable/data-table-sort-manager.js.map +1 -0
- package/dist/components/DataTable/data-table.d.ts +5 -6
- package/dist/components/DataTable/data-table.d.ts.map +1 -1
- package/dist/components/DataTable/data-table.js +36 -15
- package/dist/components/DataTable/data-table.js.map +1 -1
- package/dist/components/DataTable/filter-operators.js +140 -0
- package/dist/components/DataTable/filter-operators.js.map +1 -0
- package/dist/components/DataTable/filter-tree.js +312 -0
- package/dist/components/DataTable/filter-tree.js.map +1 -0
- package/dist/components/DataTable/index.d.ts +3 -0
- package/dist/components/DataTable/index.d.ts.map +1 -1
- package/dist/components/DataTable/index.js +12 -1
- package/dist/components/DataTable/index.js.map +1 -1
- package/dist/components/DataTable/lib/column-meta.js +25 -0
- package/dist/components/DataTable/lib/column-meta.js.map +1 -0
- package/dist/components/DateGrid/date-grid.d.ts.map +1 -1
- package/dist/components/DateGrid/date-grid.js +3 -1
- package/dist/components/DateGrid/date-grid.js.map +1 -1
- package/dist/components/DatePicker/date-picker.d.ts +7 -1
- package/dist/components/DatePicker/date-picker.d.ts.map +1 -1
- package/dist/components/DatePicker/date-picker.js +105 -74
- package/dist/components/DatePicker/date-picker.js.map +1 -1
- package/dist/components/Dialog/dialog.d.ts +20 -3
- package/dist/components/Dialog/dialog.d.ts.map +1 -1
- package/dist/components/Dialog/dialog.js +38 -20
- package/dist/components/Dialog/dialog.js.map +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.js +3 -1
- package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
- package/dist/components/Field/field-context.d.ts +45 -5
- package/dist/components/Field/field-context.d.ts.map +1 -1
- package/dist/components/Field/field-context.js +19 -0
- package/dist/components/Field/field-context.js.map +1 -1
- package/dist/components/Field/field-edit-keys.d.ts +21 -0
- package/dist/components/Field/field-edit-keys.d.ts.map +1 -0
- package/dist/components/Field/field-edit-keys.js +19 -0
- package/dist/components/Field/field-edit-keys.js.map +1 -0
- package/dist/components/Field/field-types.d.ts +20 -1
- package/dist/components/Field/field-types.d.ts.map +1 -1
- package/dist/components/Field/field-types.js.map +1 -1
- package/dist/components/Field/field-wrapper.d.ts +3 -2
- package/dist/components/Field/field-wrapper.d.ts.map +1 -1
- package/dist/components/Field/field-wrapper.js +38 -39
- package/dist/components/Field/field-wrapper.js.map +1 -1
- package/dist/components/Field/field.d.ts +2 -1
- package/dist/components/Field/field.d.ts.map +1 -1
- package/dist/components/Field/field.js.map +1 -1
- package/dist/components/FieldControlGroup/field-control-group.d.ts +1 -1
- package/dist/components/FieldControlGroup/field-control-group.js.map +1 -1
- package/dist/components/FileItem/file-item.d.ts.map +1 -1
- package/dist/components/FileItem/file-item.js +1 -1
- package/dist/components/FileItem/file-item.js.map +1 -1
- package/dist/components/FileUpload/file-upload.d.ts +1 -1
- package/dist/components/FileUpload/file-upload.js.map +1 -1
- package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
- package/dist/components/FileViewer/file-viewer.js +7 -2
- package/dist/components/FileViewer/file-viewer.js.map +1 -1
- package/dist/components/FileViewer/image-renderer.d.ts.map +1 -1
- package/dist/components/FileViewer/image-renderer.js +22 -1
- package/dist/components/FileViewer/image-renderer.js.map +1 -1
- package/dist/components/HoverCard/hover-card.d.ts.map +1 -1
- package/dist/components/HoverCard/hover-card.js +5 -3
- package/dist/components/HoverCard/hover-card.js.map +1 -1
- package/dist/components/InlineEdit/index.d.ts +2 -0
- package/dist/components/InlineEdit/index.d.ts.map +1 -0
- package/dist/components/InlineEdit/index.js +5 -0
- package/dist/components/InlineEdit/index.js.map +1 -0
- package/dist/components/InlineEdit/inline-edit.d.ts +59 -0
- package/dist/components/InlineEdit/inline-edit.d.ts.map +1 -0
- package/dist/components/InlineEdit/inline-edit.js +164 -0
- package/dist/components/InlineEdit/inline-edit.js.map +1 -0
- package/dist/components/Input/input.d.ts +6 -11
- package/dist/components/Input/input.d.ts.map +1 -1
- package/dist/components/Input/input.js +43 -13
- package/dist/components/Input/input.js.map +1 -1
- package/dist/components/LinkInput/link-input.d.ts +2 -2
- package/dist/components/LinkInput/link-input.d.ts.map +1 -1
- package/dist/components/LinkInput/link-input.js +6 -5
- package/dist/components/LinkInput/link-input.js.map +1 -1
- package/dist/components/Menu/menu-item.d.ts +14 -2
- package/dist/components/Menu/menu-item.d.ts.map +1 -1
- package/dist/components/Menu/menu-item.js +25 -3
- package/dist/components/Menu/menu-item.js.map +1 -1
- package/dist/components/NumberInput/number-input.d.ts +3 -3
- package/dist/components/NumberInput/number-input.d.ts.map +1 -1
- package/dist/components/NumberInput/number-input.js +6 -5
- package/dist/components/NumberInput/number-input.js.map +1 -1
- package/dist/components/OverflowIndicator/overflow-indicator.d.ts.map +1 -1
- package/dist/components/OverflowIndicator/overflow-indicator.js +2 -6
- package/dist/components/OverflowIndicator/overflow-indicator.js.map +1 -1
- package/dist/components/Pagination/pagination.js +1 -1
- package/dist/components/Pagination/pagination.js.map +1 -1
- package/dist/components/PeoplePicker/index.js +7 -1
- package/dist/components/PeoplePicker/index.js.map +1 -1
- package/dist/components/PeoplePicker/people-picker.d.ts +9 -2
- package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
- package/dist/components/PeoplePicker/people-picker.js +23 -10
- package/dist/components/PeoplePicker/people-picker.js.map +1 -1
- package/dist/components/PeoplePicker/person-display.d.ts +6 -3
- package/dist/components/PeoplePicker/person-display.d.ts.map +1 -1
- package/dist/components/PeoplePicker/person-display.js +19 -14
- package/dist/components/PeoplePicker/person-display.js.map +1 -1
- package/dist/components/Popover/popover.d.ts.map +1 -1
- package/dist/components/Popover/popover.js +3 -1
- package/dist/components/Popover/popover.js.map +1 -1
- package/dist/components/ProfileCard/profile-card.d.ts +2 -2
- package/dist/components/ProfileCard/profile-card.js +3 -3
- package/dist/components/ProfileCard/profile-card.js.map +1 -1
- package/dist/components/RadioGroup/radio-group.d.ts.map +1 -1
- package/dist/components/RadioGroup/radio-group.js +15 -9
- package/dist/components/RadioGroup/radio-group.js.map +1 -1
- package/dist/components/ScrollArea/scroll-area.d.ts +11 -1
- package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -1
- package/dist/components/ScrollArea/scroll-area.js +6 -3
- package/dist/components/ScrollArea/scroll-area.js.map +1 -1
- package/dist/components/Select/select.d.ts +46 -5
- package/dist/components/Select/select.d.ts.map +1 -1
- package/dist/components/Select/select.js +109 -28
- package/dist/components/Select/select.js.map +1 -1
- package/dist/components/SelectMenu/select-menu.d.ts +3 -1
- package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
- package/dist/components/SelectMenu/select-menu.js +8 -1
- package/dist/components/SelectMenu/select-menu.js.map +1 -1
- package/dist/components/SelectionControl/boolean-value.d.ts +11 -0
- package/dist/components/SelectionControl/boolean-value.d.ts.map +1 -0
- package/dist/components/SelectionControl/boolean-value.js +23 -0
- package/dist/components/SelectionControl/boolean-value.js.map +1 -0
- package/dist/components/SelectionControl/index.d.ts +1 -0
- package/dist/components/SelectionControl/index.d.ts.map +1 -1
- package/dist/components/SelectionControl/index.js +2 -0
- package/dist/components/SelectionControl/index.js.map +1 -1
- package/dist/components/Sheet/index.js +2 -1
- package/dist/components/Sheet/sheet.d.ts +7 -1
- package/dist/components/Sheet/sheet.d.ts.map +1 -1
- package/dist/components/Sheet/sheet.js +5 -2
- package/dist/components/Sheet/sheet.js.map +1 -1
- package/dist/components/Sidebar/sidebar.d.ts +9 -4
- package/dist/components/Sidebar/sidebar.d.ts.map +1 -1
- package/dist/components/Sidebar/sidebar.js +8 -10
- package/dist/components/Sidebar/sidebar.js.map +1 -1
- package/dist/components/Slider/slider.d.ts.map +1 -1
- package/dist/components/Slider/slider.js.map +1 -1
- package/dist/components/Switch/switch.d.ts +6 -6
- package/dist/components/Switch/switch.d.ts.map +1 -1
- package/dist/components/Switch/switch.js +3 -2
- package/dist/components/Switch/switch.js.map +1 -1
- package/dist/components/Tabs/tabs.d.ts.map +1 -1
- package/dist/components/Tabs/tabs.js +15 -1
- package/dist/components/Tabs/tabs.js.map +1 -1
- package/dist/components/Textarea/textarea.d.ts +2 -2
- package/dist/components/Textarea/textarea.d.ts.map +1 -1
- package/dist/components/Textarea/textarea.js +50 -42
- package/dist/components/Textarea/textarea.js.map +1 -1
- package/dist/components/TimePicker/time-columns.d.ts.map +1 -1
- package/dist/components/TimePicker/time-columns.js +42 -38
- package/dist/components/TimePicker/time-columns.js.map +1 -1
- package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
- package/dist/components/TimePicker/time-picker.js +8 -6
- package/dist/components/TimePicker/time-picker.js.map +1 -1
- package/dist/components/Tooltip/tooltip.d.ts.map +1 -1
- package/dist/components/Tooltip/tooltip.js +7 -5
- package/dist/components/Tooltip/tooltip.js.map +1 -1
- package/dist/components/TreeView/tree-view.d.ts +56 -1
- package/dist/components/TreeView/tree-view.d.ts.map +1 -1
- package/dist/components/TreeView/tree-view.js +211 -12
- package/dist/components/TreeView/tree-view.js.map +1 -1
- package/dist/index.d.ts +115 -58
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +93 -108
- package/dist/index.js.map +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.d.ts +7 -6
- package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
- package/dist/tokens/categorical-color.js +15 -0
- package/dist/tokens/categorical-color.js.map +1 -1
- package/dist/tokens/motion/motion.d.ts +7 -6
- package/dist/tokens/motion/motion.d.ts.map +1 -1
- package/dist/tokens/motion/motion.js +6 -6
- package/dist/tokens/motion/motion.js.map +1 -1
- package/dist/tokens/motion/overlay-motion.d.ts +19 -0
- package/dist/tokens/motion/overlay-motion.d.ts.map +1 -0
- package/dist/tokens/motion/overlay-motion.js +9 -0
- package/dist/tokens/motion/overlay-motion.js.map +1 -0
- package/dist/tokens/uiSize/icon-size.js +5 -0
- package/dist/tokens/uiSize/icon-size.js.map +1 -0
- package/ds-canonical/fork/governance.lock +31 -19
- package/ds-canonical/fork/hooks/_log-fire.sh +46 -0
- package/ds-canonical/fork/hooks/block_prototype_imports.py +15 -4
- package/ds-canonical/fork/hooks/check_consumer_app_invariants.sh +145 -13
- package/ds-canonical/fork/hooks/check_ds_anchor_preflight.sh +2 -1
- package/ds-canonical/fork/hooks/check_dynamic_tailwind_class.sh +47 -0
- package/ds-canonical/fork/hooks/check_escape_marker_abuse.sh +27 -0
- package/ds-canonical/fork/hooks/check_field_family_invariants.sh +61 -1
- package/ds-canonical/fork/hooks/check_layout_space_magic_numbers.sh +28 -4
- package/ds-canonical/fork/hooks/check_opacity_token_usage.sh +28 -0
- package/ds-canonical/fork/hooks/check_story_determinism.sh +2 -0
- package/ds-canonical/fork/hooks/check_story_invariants.sh +119 -0
- package/ds-canonical/fork/hooks/check_tabs_content_chrome_body_double_gap.sh +29 -0
- package/ds-canonical/fork/manifest.json +15 -0
- package/ds-canonical/fork/preamble.md +20 -18
- package/ds-canonical/fork/skills/bug-fix-rhythm/SKILL.md +3 -3
- package/ds-canonical/fork/skills/code-quality-audit/SKILL.md +3 -3
- package/ds-canonical/fork/skills/delivery-handoff/SKILL.md +1 -1
- package/ds-canonical/fork/skills/product-ui-audit/SKILL.md +3 -3
- package/ds-canonical/fork/skills/propose-options/SKILL.md +3 -3
- package/ds-canonical/fork/skills/prototype/SKILL.md +1 -1
- package/ds-canonical/fork/skills/scan-similar-bugs/SKILL.md +2 -2
- package/ds-canonical/fork/skills/visual-audit/SKILL.md +2 -2
- package/ds-canonical/hooks/README.md +1 -1
- package/ds-canonical/hooks/block_prototype_imports.py +15 -4
- package/ds-canonical/hooks/check_audit_post_report_validator.sh +65 -7
- package/ds-canonical/hooks/check_codex_brief_invariants.sh +28 -1
- package/ds-canonical/hooks/check_consumer_app_invariants.sh +145 -13
- package/ds-canonical/hooks/check_ds_anchor_preflight.sh +2 -1
- package/ds-canonical/hooks/check_dynamic_tailwind_class.sh +47 -0
- package/ds-canonical/hooks/check_escape_marker_abuse.sh +27 -0
- package/ds-canonical/hooks/check_field_family_invariants.sh +61 -1
- package/ds-canonical/hooks/check_layout_space_magic_numbers.sh +28 -4
- package/ds-canonical/hooks/check_naming_and_abstraction.sh +1 -1
- package/ds-canonical/hooks/check_opacity_token_usage.sh +28 -0
- package/ds-canonical/hooks/check_pixel_quantified_audit.sh +3 -2
- package/ds-canonical/hooks/check_post_main_ssot_propagate.sh +6 -1
- package/ds-canonical/hooks/check_ssot_header_declaration.sh +3 -1
- package/ds-canonical/hooks/check_story_determinism.sh +2 -0
- package/ds-canonical/hooks/check_substantive_edit_approval_preflight.sh +8 -7
- package/ds-canonical/hooks/check_tabs_content_chrome_body_double_gap.sh +29 -0
- package/ds-canonical/hooks/lib/_story_compile_drift.sh +1 -1
- package/ds-canonical/hooks/lib/_token_hygiene.sh +10 -1
- package/ds-canonical/hooks/stop_self_audit.sh +31 -0
- package/ds-canonical/hooks/tests/test_block_prototype_imports.sh +24 -0
- package/ds-canonical/hooks/tests/test_check_audit_post_report_validator.sh +44 -0
- package/ds-canonical/hooks/tests/test_check_codex_brief_invariants.sh +43 -2
- package/ds-canonical/hooks/tests/test_check_consumer_ds_primitive_misuse.sh +112 -0
- package/ds-canonical/hooks/tests/test_check_consumer_story_baseline.sh +9 -2
- package/ds-canonical/hooks/tests/test_check_dynamic_tailwind_class.sh +76 -0
- package/ds-canonical/hooks/tests/test_check_escape_marker_abuse.sh +24 -0
- package/ds-canonical/hooks/tests/test_check_field_family_invariants.sh +27 -2
- package/ds-canonical/hooks/tests/test_check_opacity_token_usage.sh +39 -0
- package/ds-canonical/hooks/tests/test_check_tabs_content_chrome_body_double_gap.sh +76 -0
- package/ds-canonical/references/audit-coverage-vs-24-checklist.md +1 -1
- package/ds-canonical/references/build-ui-canonicals.md +2 -1
- package/ds-canonical/references/failure-class-registry.json +145 -0
- package/ds-canonical/references/governance-audit-coverage.md +33 -0
- package/ds-canonical/references/item-anatomy-recipe.md +2 -2
- package/ds-canonical/references/scenario-definition.md +6 -9
- package/ds-canonical/references/ssot-consultation.md +2 -2
- package/ds-canonical/references/ssot-index.md +5 -4
- package/ds-canonical/references/story-baseline-registry.json +8 -2
- package/ds-canonical/references/structural-token-retention.md +6 -9
- package/ds-canonical/rules/meta-patterns.md +8 -8
- package/ds-canonical/rules/self-verify.md +4 -3
- package/ds-canonical/rules/story-rules.md +2 -2
- package/ds-canonical/rules/ui-development.md +2 -2
- package/ds-canonical/skills/bug-fix-rhythm/SKILL.md +3 -3
- package/ds-canonical/skills/code-quality-audit/SKILL.md +3 -3
- package/ds-canonical/skills/codex-collab/SKILL.md +9 -7
- package/ds-canonical/skills/codex-collab/references/brief-template.md +1 -1
- package/ds-canonical/skills/codify-principle/SKILL.md +2 -2
- package/ds-canonical/skills/component-quality-gate/SKILL.md +1 -1
- package/ds-canonical/skills/component-quality-gate/references/checklist.md +2 -2
- package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +51 -58
- package/ds-canonical/skills/deep-audit-cross-codex/references/phase-a-workflow.md +29 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/phase-b-codex-brief.md +29 -10
- package/ds-canonical/skills/deep-audit-cross-codex/references/triage-rubric.md +21 -0
- package/ds-canonical/skills/delivery-handoff/SKILL.md +1 -1
- package/ds-canonical/skills/design-system-audit/SKILL.md +26 -25
- package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +13 -1
- package/ds-canonical/skills/design-system-audit/references/rule-placement.md +1 -1
- package/ds-canonical/skills/governance-health/SKILL.md +1 -1
- package/ds-canonical/skills/knowledge-prune/SKILL.md +3 -0
- package/ds-canonical/skills/knowledge-prune/references/prune-dimensions-d5-d10.md +1 -0
- package/ds-canonical/skills/new-component/SKILL.md +5 -5
- package/ds-canonical/skills/new-component/references/new-component-checklist.md +1 -1
- package/ds-canonical/skills/product-ui-audit/SKILL.md +3 -3
- package/ds-canonical/skills/propose-options/SKILL.md +3 -3
- package/ds-canonical/skills/prototype/SKILL.md +1 -1
- package/ds-canonical/skills/scan-similar-bugs/SKILL.md +2 -2
- package/ds-canonical/skills/story-auto-compile-migrate/SKILL.md +3 -3
- package/ds-canonical/skills/story-writing/SKILL.md +3 -3
- package/ds-canonical/skills/visual-audit/SKILL.md +2 -2
- package/ds-story-manifest.json +29 -20
- package/llms-full.txt +22 -1
- package/llms.txt +5 -4
- package/package.json +7 -3
- package/src/components/Accordion/accordion.principles.stories.tsx +1 -1
- package/src/components/Accordion/accordion.stories.tsx +16 -1
- package/src/components/Alert/alert.principles.stories.tsx +1 -1
- package/src/components/Alert/alert.spec.md +8 -10
- package/src/components/Alert/alert.stories.tsx +28 -28
- package/src/components/Alert/alert.tsx +1 -1
- package/src/components/AppShell/_demo-helpers.tsx +6 -3
- package/src/components/AppShell/app-shell.spec.md +4 -4
- package/src/components/AppShell/app-shell.tsx +28 -2
- package/src/components/AspectRatio/aspect-ratio.spec.md +1 -1
- package/src/components/AspectRatio/aspect-ratio.stories.tsx +7 -89
- package/src/components/Avatar/avatar.anatomy.stories.tsx +7 -3
- package/src/components/Avatar/avatar.principles.stories.tsx +19 -15
- package/src/components/Avatar/avatar.spec.md +2 -2
- package/src/components/Avatar/avatar.stories.tsx +8 -6
- package/src/components/Avatar/avatar.tsx +13 -5
- package/src/components/Badge/badge.principles.stories.tsx +1 -1
- package/src/components/Badge/badge.spec.md +2 -0
- package/src/components/Badge/badge.stories.tsx +4 -2
- package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +6 -4
- package/src/components/Breadcrumb/breadcrumb.stories.tsx +6 -5
- package/src/components/Breadcrumb/breadcrumb.tsx +3 -2
- package/src/components/BulkActionBar/bulk-action-bar.spec.md +4 -2
- package/src/components/Button/button.principles.stories.tsx +1 -1
- package/src/components/Button/button.spec.md +2 -2
- package/src/components/Button/button.tsx +18 -3
- package/src/components/Calendar/calendar.anatomy.stories.tsx +12 -10
- package/src/components/Calendar/calendar.principles.stories.tsx +14 -6
- package/src/components/Calendar/calendar.spec.md +5 -4
- package/src/components/Calendar/calendar.stories.tsx +7 -4
- package/src/components/Calendar/calendar.tsx +26 -7
- package/src/components/Carousel/carousel.anatomy.stories.tsx +5 -4
- package/src/components/Carousel/carousel.spec.md +2 -2
- package/src/components/Carousel/carousel.tsx +11 -3
- package/src/components/Chart/chart.anatomy.stories.tsx +7 -4
- package/src/components/Chart/chart.principles.stories.tsx +1 -1
- package/src/components/Chart/chart.stories.tsx +2 -8
- package/src/components/Chart/chart.tsx +3 -0
- package/src/components/Checkbox/checkbox.anatomy.stories.tsx +28 -49
- package/src/components/Checkbox/checkbox.principles.stories.tsx +1 -1
- package/src/components/Checkbox/checkbox.spec.md +11 -26
- package/src/components/Checkbox/checkbox.stories.tsx +11 -8
- package/src/components/Checkbox/checkbox.tsx +18 -13
- package/src/components/Chip/chip.anatomy.stories.tsx +44 -24
- package/src/components/Chip/chip.principles.stories.tsx +1 -1
- package/src/components/Chip/chip.spec.md +5 -4
- package/src/components/Chip/chip.tsx +5 -1
- package/src/components/CircularProgress/circular-progress.principles.stories.tsx +7 -4
- package/src/components/CircularProgress/circular-progress.spec.md +3 -3
- package/src/components/CircularProgress/circular-progress.stories.tsx +2 -2
- package/src/components/Coachmark/coachmark.anatomy.stories.tsx +2 -2
- package/src/components/Coachmark/coachmark.principles.stories.tsx +2 -1
- package/src/components/Coachmark/coachmark.spec.md +5 -5
- package/src/components/Coachmark/coachmark.stories.tsx +3 -1
- package/src/components/Coachmark/coachmark.tsx +10 -3
- package/src/components/Combobox/combobox.anatomy.stories.tsx +2 -2
- package/src/components/Combobox/combobox.tsx +53 -19
- package/src/components/Command/command.anatomy.stories.tsx +2 -2
- package/src/components/Command/command.principles.stories.tsx +1 -1
- package/src/components/Command/command.stories.tsx +42 -10
- package/src/components/DataTable/cell-registry.tsx +86 -63
- package/src/components/DataTable/column-types.ts +10 -1
- package/src/components/DataTable/data-table-column-visibility-panel.tsx +1 -1
- package/src/components/DataTable/data-table-filter-panel.tsx +4 -1
- package/src/components/DataTable/data-table-interaction-layer.tsx +15 -19
- package/src/components/DataTable/data-table.anatomy.stories.tsx +15 -13
- package/src/components/DataTable/data-table.principles.stories.tsx +9 -9
- package/src/components/DataTable/data-table.spec.md +32 -12
- package/src/components/DataTable/data-table.stories.tsx +16 -17
- package/src/components/DataTable/data-table.tsx +103 -60
- package/src/components/DataTable/index.ts +3 -0
- package/src/components/DateGrid/date-grid.anatomy.stories.tsx +4 -4
- package/src/components/DateGrid/date-grid.principles.stories.tsx +1 -1
- package/src/components/DateGrid/date-grid.spec.md +1 -1
- package/src/components/DateGrid/date-grid.tsx +3 -1
- package/src/components/DatePicker/date-picker.anatomy.stories.tsx +8 -8
- package/src/components/DatePicker/date-picker.principles.stories.tsx +3 -3
- package/src/components/DatePicker/date-picker.spec.md +3 -3
- package/src/components/DatePicker/date-picker.stories.tsx +4 -5
- package/src/components/DatePicker/date-picker.tsx +99 -45
- package/src/components/DescriptionList/description-list.anatomy.stories.tsx +12 -10
- package/src/components/DescriptionList/description-list.principles.stories.tsx +2 -2
- package/src/components/DescriptionList/description-list.spec.md +3 -3
- package/src/components/DescriptionList/description-list.stories.tsx +7 -6
- package/src/components/Dialog/dialog.anatomy.stories.tsx +1 -0
- package/src/components/Dialog/dialog.spec.md +9 -0
- package/src/components/Dialog/dialog.stories.tsx +66 -5
- package/src/components/Dialog/dialog.tsx +60 -25
- package/src/components/DropdownMenu/dropdown-menu.anatomy.stories.tsx +1 -1
- package/src/components/DropdownMenu/dropdown-menu.principles.stories.tsx +8 -6
- package/src/components/DropdownMenu/dropdown-menu.spec.md +5 -5
- package/src/components/DropdownMenu/dropdown-menu.tsx +18 -9
- package/src/components/Empty/empty.anatomy.stories.tsx +1 -1
- package/src/components/Empty/empty.spec.md +2 -2
- package/src/components/Field/field-context.ts +69 -5
- package/src/components/Field/field-controls.spec.md +62 -8
- package/src/components/Field/field-edit-keys.ts +66 -0
- package/src/components/Field/field-types.ts +58 -9
- package/src/components/Field/field-wrapper.tsx +50 -42
- package/src/components/Field/field.anatomy.stories.tsx +9 -6
- package/src/components/Field/field.spec.md +1 -1
- package/src/components/Field/field.stories.tsx +1 -1
- package/src/components/Field/field.tsx +2 -1
- package/src/components/Field/form-validation.spec.md +3 -3
- package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +6 -6
- package/src/components/FieldControlGroup/field-control-group.spec.md +9 -4
- package/src/components/FieldControlGroup/field-control-group.tsx +1 -1
- package/src/components/FileItem/file-item.anatomy.stories.tsx +1 -1
- package/src/components/FileItem/file-item.spec.md +5 -8
- package/src/components/FileItem/file-item.stories.tsx +36 -25
- package/src/components/FileItem/file-item.tsx +8 -6
- package/src/components/FileUpload/file-upload.anatomy.stories.tsx +6 -6
- package/src/components/FileUpload/file-upload.principles.stories.tsx +5 -5
- package/src/components/FileUpload/file-upload.spec.md +1 -1
- package/src/components/FileUpload/file-upload.tsx +1 -1
- package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +4 -3
- package/src/components/FileViewer/file-viewer.principles.stories.tsx +3 -3
- package/src/components/FileViewer/file-viewer.spec.md +30 -12
- package/src/components/FileViewer/file-viewer.stories.tsx +1 -2
- package/src/components/FileViewer/file-viewer.tsx +12 -4
- package/src/components/FileViewer/image-renderer.tsx +35 -7
- package/src/components/HoverCard/hover-card.anatomy.stories.tsx +6 -2
- package/src/components/HoverCard/hover-card.principles.stories.tsx +6 -3
- package/src/components/HoverCard/hover-card.spec.md +5 -5
- package/src/components/HoverCard/hover-card.stories.tsx +16 -16
- package/src/components/HoverCard/hover-card.tsx +5 -3
- package/src/components/InlineEdit/index.ts +5 -0
- package/src/components/InlineEdit/inline-edit.spec.md +149 -0
- package/src/components/InlineEdit/inline-edit.stories.tsx +246 -0
- package/src/components/InlineEdit/inline-edit.tsx +287 -0
- package/src/components/Input/input.anatomy.stories.tsx +8 -7
- package/src/components/Input/input.principles.stories.tsx +2 -12
- package/src/components/Input/input.spec.md +13 -18
- package/src/components/Input/input.tsx +69 -22
- package/src/components/LinkInput/link-input.anatomy.stories.tsx +1 -1
- package/src/components/LinkInput/link-input.principles.stories.tsx +2 -2
- package/src/components/LinkInput/link-input.tsx +11 -10
- package/src/components/Menu/menu-item.anatomy.stories.tsx +3 -3
- package/src/components/Menu/menu-item.principles.stories.tsx +1 -1
- package/src/components/Menu/menu-item.spec.md +22 -15
- package/src/components/Menu/menu-item.stories.tsx +39 -11
- package/src/components/Menu/menu-item.tsx +38 -4
- package/src/components/Notice/notice.principles.stories.tsx +1 -1
- package/src/components/Notice/notice.spec.md +16 -3
- package/src/components/NumberInput/number-input.anatomy.stories.tsx +3 -3
- package/src/components/NumberInput/number-input.principles.stories.tsx +1 -1
- package/src/components/NumberInput/number-input.spec.md +4 -4
- package/src/components/NumberInput/number-input.tsx +19 -12
- package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +10 -8
- package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +3 -3
- package/src/components/OverflowIndicator/overflow-indicator.spec.md +4 -2
- package/src/components/OverflowIndicator/overflow-indicator.stories.tsx +71 -63
- package/src/components/OverflowIndicator/overflow-indicator.tsx +9 -8
- package/src/components/Pagination/pagination.spec.md +1 -1
- package/src/components/Pagination/pagination.stories.tsx +2 -6
- package/src/components/Pagination/pagination.tsx +1 -1
- package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +4 -4
- package/src/components/PeoplePicker/people-picker.principles.stories.tsx +2 -2
- package/src/components/PeoplePicker/people-picker.spec.md +6 -6
- package/src/components/PeoplePicker/people-picker.tsx +56 -16
- package/src/components/PeoplePicker/person-display.tsx +32 -16
- package/src/components/Popover/popover.anatomy.stories.tsx +2 -2
- package/src/components/Popover/popover.tsx +3 -1
- package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +12 -23
- package/src/components/ProfileCard/profile-card.spec.md +3 -3
- package/src/components/ProfileCard/profile-card.tsx +6 -6
- package/src/components/ProgressBar/progress-bar.anatomy.stories.tsx +3 -1
- package/src/components/ProgressBar/progress-bar.principles.stories.tsx +1 -1
- package/src/components/ProgressBar/progress-bar.stories.tsx +50 -42
- package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +10 -28
- package/src/components/RadioGroup/radio-group.stories.tsx +29 -32
- package/src/components/RadioGroup/radio-group.tsx +41 -15
- package/src/components/Rating/rating.spec.md +11 -3
- package/src/components/ScrollArea/scroll-area.anatomy.stories.tsx +1 -1
- package/src/components/ScrollArea/scroll-area.principles.stories.tsx +1 -1
- package/src/components/ScrollArea/scroll-area.spec.md +7 -3
- package/src/components/ScrollArea/scroll-area.stories.tsx +1 -1
- package/src/components/ScrollArea/scroll-area.tsx +17 -4
- package/src/components/Select/select.anatomy.stories.tsx +3 -3
- package/src/components/Select/select.spec.md +27 -17
- package/src/components/Select/select.stories.tsx +33 -0
- package/src/components/Select/select.tsx +190 -36
- package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +4 -4
- package/src/components/SelectMenu/select-menu.spec.md +15 -7
- package/src/components/SelectMenu/select-menu.tsx +16 -3
- package/src/components/SelectionControl/boolean-value.tsx +39 -0
- package/src/components/SelectionControl/index.ts +1 -0
- package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +2 -2
- package/src/components/SelectionControl/selection-item.principles.stories.tsx +2 -2
- package/src/components/SelectionControl/selection-item.spec.md +3 -3
- package/src/components/SelectionControl/selection-item.stories.tsx +3 -3
- package/src/components/Separator/separator.spec.md +2 -2
- package/src/components/Separator/separator.stories.tsx +6 -27
- package/src/components/Sheet/sheet.anatomy.stories.tsx +1 -1
- package/src/components/Sheet/sheet.principles.stories.tsx +1 -1
- package/src/components/Sheet/sheet.spec.md +2 -2
- package/src/components/Sheet/sheet.tsx +9 -5
- package/src/components/Sidebar/sidebar.anatomy.stories.tsx +16 -12
- package/src/components/Sidebar/sidebar.principles.stories.tsx +10 -8
- package/src/components/Sidebar/sidebar.spec.md +13 -15
- package/src/components/Sidebar/sidebar.stories.tsx +8 -7
- package/src/components/Sidebar/sidebar.tsx +37 -25
- package/src/components/Skeleton/skeleton.stories.tsx +4 -11
- package/src/components/Slider/slider.anatomy.stories.tsx +3 -3
- package/src/components/Slider/slider.principles.stories.tsx +2 -2
- package/src/components/Slider/slider.spec.md +5 -5
- package/src/components/Slider/slider.tsx +3 -1
- package/src/components/Steps/steps.anatomy.stories.tsx +4 -4
- package/src/components/Steps/steps.principles.stories.tsx +1 -1
- package/src/components/Steps/steps.spec.md +1 -1
- package/src/components/Switch/switch.anatomy.stories.tsx +7 -7
- package/src/components/Switch/switch.principles.stories.tsx +4 -4
- package/src/components/Switch/switch.spec.md +8 -8
- package/src/components/Switch/switch.stories.tsx +9 -24
- package/src/components/Switch/switch.tsx +17 -13
- package/src/components/Tabs/tabs.anatomy.stories.tsx +10 -7
- package/src/components/Tabs/tabs.spec.md +1 -1
- package/src/components/Tabs/tabs.tsx +21 -1
- package/src/components/Textarea/textarea.anatomy.stories.tsx +1 -1
- package/src/components/Textarea/textarea.principles.stories.tsx +1 -1
- package/src/components/Textarea/textarea.spec.md +4 -4
- package/src/components/Textarea/textarea.tsx +72 -46
- package/src/components/TimePicker/time-columns.tsx +6 -2
- package/src/components/TimePicker/time-picker.principles.stories.tsx +1 -1
- package/src/components/TimePicker/time-picker.spec.md +3 -3
- package/src/components/TimePicker/time-picker.tsx +16 -10
- package/src/components/Toast/toast.stories.tsx +7 -4
- package/src/components/Tooltip/tooltip.anatomy.stories.tsx +4 -4
- package/src/components/Tooltip/tooltip.principles.stories.tsx +3 -3
- package/src/components/Tooltip/tooltip.spec.md +1 -1
- package/src/components/Tooltip/tooltip.stories.tsx +4 -39
- package/src/components/Tooltip/tooltip.tsx +8 -6
- package/src/components/TreeView/tree-view.anatomy.stories.tsx +6 -3
- package/src/components/TreeView/tree-view.spec.md +42 -11
- package/src/components/TreeView/tree-view.stories.tsx +1 -0
- package/src/components/TreeView/tree-view.tsx +322 -17
- package/src/index.ts +584 -60
- package/src/patterns/action-bar/action-bar.spec.md +9 -0
- package/src/patterns/action-bar/action-bar.stories.tsx +6 -3
- package/src/patterns/element-anatomy/inline-action.spec.md +2 -0
- package/src/patterns/element-anatomy/item-anatomy.spec.md +14 -5
- package/src/patterns/element-anatomy/item-anatomy.stories.tsx +6 -4
- package/src/patterns/element-anatomy/item-anatomy.tsx +7 -6
- package/src/patterns/header-canonical/header-canonical.spec.md +5 -4
- package/src/patterns/overlay-surface/overlay-surface.spec.md +22 -1
- package/src/styles/tokens.css +3 -0
- package/src/tokens/README.md +1 -1
- package/src/tokens/color/color.spec.md +3 -3
- package/src/tokens/color/color.stories.tsx +3 -3
- package/src/tokens/density/density.stories.tsx +16 -3
- package/src/tokens/layoutSpace/layoutSpace.spec.md +3 -1
- package/src/tokens/motion/motion.css +33 -21
- package/src/tokens/motion/motion.spec.md +32 -15
- package/src/tokens/motion/motion.stories.tsx +58 -5
- package/src/tokens/motion/motion.ts +7 -6
- package/src/tokens/motion/overlay-motion.ts +26 -0
- package/src/tokens/orphan-tokens.spec.md +4 -4
- package/src/tokens/token-system.spec.md +1 -0
- package/src/tokens/uiSize/uiSize.spec.md +1 -1
- package/src/tokens/uiSize/uiSize.stories.tsx +4 -2
- package/src/tokens/utility-registry.json +160 -23
|
@@ -43,7 +43,31 @@ ESCAPE_MARKER='@layout-space-magic-ok:'
|
|
|
43
43
|
|
|
44
44
|
# Detect magic spacing classes (Tailwind class strings only — NOT JSX props like size={24})
|
|
45
45
|
# Match per line so we can check per-line escape comments
|
|
46
|
-
|
|
46
|
+
# 2026-07-08 WM 戰役 R4 擴 scope(broad-vs-narrow gap 實證修補):
|
|
47
|
+
# (a) logical properties ps-/pe-/ms-/me-(WM 6 筆 ps-4 漏網實證)
|
|
48
|
+
# (b) arbitrary bracket 固定 px:gap-[7px] / p-[13px] 類(spacing 家族)
|
|
49
|
+
# (c) 固定寬度 w-[Npx](WM w-[640px] 丟失 min() viewport clamp 實證;w-[min(...)]/var()/% 不攔)
|
|
50
|
+
# (d) grid-template 固定 px 欄寬:grid-cols-[...Npx...](WM mini-table 88px/72px 黏死實證)
|
|
51
|
+
MAGIC_LINES=$(echo "$NEW_CONTENT" | grep -nE '\b(p|px|py|pt|pb|pl|pr|ps|pe|gap|space-x|space-y|m|mx|my|mt|mb|ml|mr|ms|me)-(0\.5|[1-9][0-9]?(\.[0-9])?)\b|\b(p|px|py|pt|pb|pl|pr|ps|pe|gap|m|mx|my|mt|mb|ml|mr|ms|me)-\[[0-9]+(\.[0-9]+)?px\]|\bw-\[[0-9]+(\.[0-9]+)?px\]|\bgrid-(cols|rows)-\[[^]]*[0-9]+px[^]]*\]')
|
|
52
|
+
|
|
53
|
+
# ── 幻覺 token 攔截(2026-07-08 WM 戰役:app 自創 var(--layout-space-distant) → CSS 未定義
|
|
54
|
+
# silent 解析 0 → 區塊全黏死,PDF「全部擠在一起」根因之一。白名單 = loose|tight|bottom
|
|
55
|
+
# (layoutSpace.css SSOT 僅此三顆;新增 tier 走 DS token 流程,不在 consumer 端發明)──
|
|
56
|
+
PHANTOM=$(echo "$NEW_CONTENT" | grep -nE 'var\(--layout-space-[a-z-]+\)' | grep -vE 'var\(--layout-space-(loose|tight|bottom)\)' || true)
|
|
57
|
+
if [ -n "$PHANTOM" ]; then
|
|
58
|
+
cat >&2 <<EOF_PH
|
|
59
|
+
🚨 [P0 BLOCKER] 幻覺 layout-space token(CSS 未定義 = silent 0 = 佈局黏死):
|
|
60
|
+
$PHANTOM
|
|
61
|
+
→ 白名單只有 --layout-space-{loose,tight,bottom}(layoutSpace.css SSOT)。
|
|
62
|
+
要更大一級間距 → 用 loose;真需新 tier → 走 DS token 新增流程(layoutSpace.spec),禁 consumer 端自創。
|
|
63
|
+
Anchor:2026-07-08 WM --layout-space-distant ×4 處,整個 detail modal 區塊黏死。
|
|
64
|
+
EOF_PH
|
|
65
|
+
exit 2
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# 2026-07-10 批次 A:divider 幾何 canonical(h-6 mx-1 / h-5 mx-1,action-bar.spec.md「分隔線幾何」)
|
|
69
|
+
# 是**正解**,不該被 magic-number 攔(原本懲罰 canonical 修法、放行違規 = 治理自我打架)。
|
|
70
|
+
MAGIC_LINES=$(echo "$MAGIC_LINES" | grep -vE '(Separator|ButtonDivider)' || true)
|
|
47
71
|
|
|
48
72
|
if [ -z "$MAGIC_LINES" ]; then
|
|
49
73
|
exit 0
|
|
@@ -82,9 +106,9 @@ $(echo -e "$UNJUSTIFIED" | sed 's/^/ /' | head -10)
|
|
|
82
106
|
per app-shell.spec.md L205-219 + layoutSpace.spec.md SSOT:consumer content 必遵循
|
|
83
107
|
layoutSpace 6 條規則 + 親疏 3 級,**禁** 硬寫 Tailwind magic numbers。改用:
|
|
84
108
|
p-[var(--layout-space-loose)] /* 16px 規則 1A/1B chrome / wrap */
|
|
85
|
-
|
|
86
|
-
gap-[var(--layout-space-
|
|
87
|
-
|
|
109
|
+
gap-[var(--layout-space-tight)] /* 12px 規則 3 親 gap(跨範疇相關) */
|
|
110
|
+
gap-[var(--layout-space-loose)] /* 16px 規則 3 疏 gap(跨範疇 parallel;lg 密度自動 24px) */
|
|
111
|
+
(token 全集 = loose/tight/bottom,無其他級 — 自創 --layout-space-distant 類 = 幻覺 token,本 hook 會攔)
|
|
88
112
|
|
|
89
113
|
修法 2 選 1:
|
|
90
114
|
(a) 改 token:換成 var(--layout-space-N) N∈{loose,tight} family per 6 規則 + 親疏 3 級
|
|
@@ -136,7 +136,7 @@ case "$FILE_PATH" in
|
|
|
136
136
|
*/components/Tag/*|*/components/Avatar/*|*/components/Chart/*|*/tokens/*) ;; # codified primitive-consumer skip
|
|
137
137
|
*)
|
|
138
138
|
if ! echo "$NEW_CONTENT" | grep -q 'primitive-color-allow-blanket'; then
|
|
139
|
-
VIOLATIONS_D3=$(printf '%s' "$NEW_CONTENT" | grep -nE 'var\(--color-[a-z]
|
|
139
|
+
VIOLATIONS_D3=$(printf '%s' "$NEW_CONTENT" | grep -nE 'var\(--color-[a-z][a-z-]*-[0-9]{1,2}(-opaque)?\)' | grep -v 'primitive-color-allow' || true)
|
|
140
140
|
if [ -n "$VIOLATIONS_D3" ]; then
|
|
141
141
|
cat >&2 <<EOF
|
|
142
142
|
|
|
@@ -135,6 +135,24 @@ if [ -n "$HITS_PRIMITIVE" ]; then
|
|
|
135
135
|
VIOLATIONS="${VIOLATIONS}\n [primitive color as utility] $(echo "$HITS_PRIMITIVE" | tr '\n' ' ')"
|
|
136
136
|
fi
|
|
137
137
|
|
|
138
|
+
# 10) 幻覺 semantic state 尾綴(2026-07-10 批次 A C1:WM hover:bg-neutral-hovered ×3 檔 silent no-op 實證。
|
|
139
|
+
# 真尾綴只有 -hover/-active/-selected(+ selected-hover/selected-active);過去式/-pressed 全幻覺,
|
|
140
|
+
# Tailwind 靜默不生成 → hover 無效果、build 不報錯)
|
|
141
|
+
HITS_PHANTOM_STATE=$(echo "$NEW_CONTENT" | grep -oE "\b(hover:|active:|focus:)?(bg|text|border|ring)-[a-z][a-z-]*-(hovered|actived|focussed|pressed)\b" | sort -u || true)
|
|
142
|
+
if [ -n "$HITS_PHANTOM_STATE" ]; then
|
|
143
|
+
VIOLATIONS="${VIOLATIONS}\n [phantom state suffix(silent no-op)] $(echo "$HITS_PHANTOM_STATE" | tr '\n' ' ')"
|
|
144
|
+
fi
|
|
145
|
+
|
|
146
|
+
# 11) micro gap(<4px)+ registry fraction width(#71 2026-07-11 接線)——
|
|
147
|
+
# registry micro_gap / fraction 的 rationale 明寫「flag for human review」(非硬禁)→ 走
|
|
148
|
+
# SOFT WARN 非 block(避免誤殺 Calendar/Chart/FileViewer/Carousel 等 4 個既有合法 micro-gap 用途)。
|
|
149
|
+
# fraction 用 registry 明列 14 條(w-1/3.. 不含 w-1/2 = 合法留白),避免廣捕 w-N/M 誤殺。
|
|
150
|
+
HITS_MICROGAP=$(echo "$NEW_CONTENT" | grep -oE "\bgap-(px|0\.5|1\.5)\b" | sort -u || true)
|
|
151
|
+
HITS_FRACTION=$(echo "$NEW_CONTENT" | grep -oE "\bw-(1/3|2/3|1/4|3/4|1/5|2/5|3/5|4/5|1/6|5/6|1/12|5/12|7/12|11/12)\b" | sort -u || true)
|
|
152
|
+
SOFT_NOTES=""
|
|
153
|
+
[ -n "$HITS_MICROGAP" ] && SOFT_NOTES="${SOFT_NOTES}\n [micro gap <4px] $(echo "$HITS_MICROGAP" | tr '\n' ' ')"
|
|
154
|
+
[ -n "$HITS_FRACTION" ] && SOFT_NOTES="${SOFT_NOTES}\n [fraction width] $(echo "$HITS_FRACTION" | tr '\n' ' ')"
|
|
155
|
+
|
|
138
156
|
if [ -n "$VIOLATIONS" ]; then
|
|
139
157
|
cat >&2 <<'EOF_HEAD'
|
|
140
158
|
|
|
@@ -160,7 +178,17 @@ EOF_HEAD
|
|
|
160
178
|
EOF_BODY
|
|
161
179
|
# P0 BLOCKER(2026-07-07 治理進化方向 2:對齊 user 2026-05-27「SSOT canonical 必 P0」doctrine;
|
|
162
180
|
# 檔級豁免(anatomy/principles stories / token 自家)+ 行級 escape 已備,升級不增誤殺)
|
|
181
|
+
# micro-gap/fraction soft note 附在硬 block 訊息尾(一起讓 AI 看到,但不影響 exit code 判定)
|
|
182
|
+
[ -n "$SOFT_NOTES" ] && { echo "" >&2; echo " (另有 soft flag,非 block 原因):" >&2; echo -e "$SOFT_NOTES" >&2; }
|
|
163
183
|
exit 2
|
|
164
184
|
fi
|
|
165
185
|
|
|
186
|
+
# 只有 micro-gap / fraction soft note(無硬 violation)→ WARN 非 block(registry rationale「flag for human review」)
|
|
187
|
+
if [ -n "$SOFT_NOTES" ]; then
|
|
188
|
+
echo "" >&2
|
|
189
|
+
echo "⚠️ Dim 47 soft flag(registry micro_gap / fraction「flag for human review」— 非 block,#71 接線):" >&2
|
|
190
|
+
echo -e "$SOFT_NOTES" >&2
|
|
191
|
+
echo " <4px gap / registry fraction width 常違反 item-anatomy slot 幾何 / layout SSOT → 人工 review。合理則行尾 @token-registry-ok: <rationale>。" >&2
|
|
192
|
+
fi
|
|
193
|
+
|
|
166
194
|
exit 0
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
# `getAttribute('data-state')` / `class.includes('items-start')` attribute-existence
|
|
7
7
|
# = false-positive trap(DOM-structure-pass ≠ visual-pass)。
|
|
8
8
|
#
|
|
9
|
-
# Mechanical rule:scripts/visual-audit
|
|
9
|
+
# Mechanical rule:scripts/visual-audit*.mjs(or *.js;含 canonical scripts/visual-audit.mjs,
|
|
10
|
+
# 舊 visual-audit-<target>.mjs 家族已於 2026-05-30 a2360e99 整批 retire)若有 `getAttribute(` 但沒 paired
|
|
10
11
|
# `getBoundingClientRect(` 或 `offsetTop/.offsetHeight` 量化 measurement → warn。
|
|
11
12
|
#
|
|
12
13
|
# 對齊 Material X-DataGrid visual regression / AG Grid playwright pixel snapshot canonical。
|
|
@@ -21,7 +22,7 @@ EVENT=$(echo "$INPUT" | jq -r '.hook_event_name // ""' 2>/dev/null)
|
|
|
21
22
|
|
|
22
23
|
case "$TOOL" in Edit|Write|MultiEdit) ;; *) exit 0 ;; esac
|
|
23
24
|
case "$FILE_PATH" in
|
|
24
|
-
*/scripts/visual-audit
|
|
25
|
+
*/scripts/visual-audit*.mjs|*/scripts/visual-audit*.js) ;;
|
|
25
26
|
*) exit 0 ;;
|
|
26
27
|
esac
|
|
27
28
|
[ "$EVENT" != "PostToolUse" ] && exit 0
|
|
@@ -63,7 +63,10 @@ SSOT_COUNT=$(echo "$SSOT_DIFF" | wc -l | tr -d ' ')
|
|
|
63
63
|
# Read current package version
|
|
64
64
|
PKG_VERSION=$(jq -r '.version' "$CWD/packages/design-system/package.json" 2>/dev/null || echo "unknown")
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
# 2026-07-11 #79 修:PostToolUse 純 stdout **不注入 AI context**(只進 transcript)→ 原 heredoc 的
|
|
67
|
+
# 「AI 必全自動執行」提議到不了 AI = 假 inject。對齊 inject_deploy_url_after_push.sh:236 root-cause fix,
|
|
68
|
+
# 收進 MSG 後用 jq hookSpecificOutput.additionalContext 真注入。
|
|
69
|
+
MSG=$(cat <<EOF
|
|
67
70
|
🔄 SSOT propagation gate(post push origin main):
|
|
68
71
|
|
|
69
72
|
📊 偵測:HEAD~1..HEAD 含 $SSOT_COUNT 個 SSOT-affecting file changes
|
|
@@ -87,4 +90,6 @@ AI 全自動執行步驟(user 已給 merge trigger → 以下不需再問;user
|
|
|
87
90
|
- .claude/skills/knowledge-prune/SKILL.md「Phase Z」reference
|
|
88
91
|
- .claude/skills/deep-audit-cross-codex/SKILL.md「Phase C」reference
|
|
89
92
|
EOF
|
|
93
|
+
)
|
|
94
|
+
jq -n --arg ctx "$MSG" '{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:$ctx}}'
|
|
90
95
|
exit 0
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# (2026-07-07 治理進化方向 3 洞 a:原 check_ssot_consultation.sh 2026-05-XX retired 後,
|
|
4
4
|
# CLAUDE.md「# SSOT 消費 canonical」+ ssot-consultation.md:30-51 強制的檔頭宣告段
|
|
5
5
|
# **無任何機械驗證** — 內部盤點實證。本 hook = 精簡復活版,只驗「新檔有無宣告段」,
|
|
6
|
-
# 不驗宣告品質(品質靠 audit dim
|
|
6
|
+
# 不驗宣告品質(品質靠 audit dim 5 + dim 54 + M18/M29)。)
|
|
7
7
|
#
|
|
8
8
|
# Scope(ratchet,對齊 Polaris stylelint-adoption 策略):
|
|
9
9
|
# - 只攔 **Write 新檔**(components/ patterns/ 的 .tsx,磁碟上不存在)— 存量檔 Edit 豁免
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
# - escape:內容含 `@ssot-header-exempt: <rationale>`(audit 可追)
|
|
12
12
|
# P0 BLOCKER(user 2026-05-27「SSOT canonical 必 P0」doctrine)。
|
|
13
13
|
|
|
14
|
+
source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
|
|
15
|
+
|
|
14
16
|
set -euo pipefail
|
|
15
17
|
|
|
16
18
|
INPUT=$(cat)
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
# 第一期 WARN(exit 0):存量 10 檔(dry-run 2026-07-07,DateGrid 家族為主)未清,
|
|
12
12
|
# 誤殺率驗證期後升 P0(對齊 handcraft 偵測同節奏;roadmap 方向 1 KPI 隨頻回顧)。
|
|
13
13
|
|
|
14
|
+
source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
|
|
15
|
+
|
|
14
16
|
set -euo pipefail
|
|
15
17
|
INPUT=$(cat)
|
|
16
18
|
TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""')
|
|
@@ -2,19 +2,20 @@
|
|
|
2
2
|
# check_substantive_edit_approval_preflight.sh — Pre-action gate for substantive design edits.
|
|
3
3
|
#
|
|
4
4
|
# Purpose: PRE-flight 偵測 packages/design-system/src/**.{tsx,ts,css} edit + last 5 user msgs 無
|
|
5
|
-
# approval keyword →
|
|
5
|
+
# approval keyword → P0 BLOCKER(stderr + exit 2;2026-05-15 由 soft warn 升級,
|
|
6
|
+
# per memory/feedback_ship_then_revert_anti_pattern.md SSOT)。
|
|
6
7
|
#
|
|
7
|
-
# 對比 stop_self_audit.sh post-action BLOCKER:本 hook 是 PRE-action
|
|
8
|
-
#
|
|
8
|
+
# 對比 stop_self_audit.sh post-action BLOCKER:本 hook 是 PRE-action gate,
|
|
9
|
+
# 在 edit 落地前就攔(propose-only OR cite approval verbatim + bypass env),
|
|
9
10
|
# 避免「edit → stop hook BLOCKER → revert」waste cycle(user 抓 2026-05-12 anti-pattern)。
|
|
10
11
|
#
|
|
11
12
|
# 對齊 Option 3 hybrid(M32 split 後 (f) ship gate 的 PRE-flight 補位):
|
|
12
|
-
# - PreToolUse
|
|
13
|
-
# - Stop hook BLOCKER =
|
|
13
|
+
# - PreToolUse P0 BLOCKER = pre-action enforcement(本 hook)
|
|
14
|
+
# - Stop hook BLOCKER = post-action backstop(stop_self_audit.sh Mechanism 4)
|
|
14
15
|
# - AI inline self-statement = discipline(M31 Layer A/C marker + 本 hook context)
|
|
15
16
|
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
17
|
+
# False-positive escape:CLAUDE_BYPASS_DESIGN_APPROVAL=1(audit-logged → logs/approval-bypass.jsonl),
|
|
18
|
+
# 需 cite user approval verbatim quote 在 commit message + reply。
|
|
18
19
|
#
|
|
19
20
|
# 對齊:CLAUDE.md `# 稽核 canonical` Audit-vs-execute 分權 + M31 Layer A/C + M32(f) ship gate。
|
|
20
21
|
|
|
@@ -52,6 +52,34 @@ if ! echo "$FILE" | grep -qE '(packages/design-system/src/|/apps/|(^|/)apps/)';
|
|
|
52
52
|
CONTENT=$(cat "$FILE" 2>/dev/null)
|
|
53
53
|
[ -z "$CONTENT" ] && exit 0
|
|
54
54
|
|
|
55
|
+
# ── Check 3(2026-07-08 WM 戰役 R4:root 偵測,不只 symptom)──
|
|
56
|
+
# WM 實證:app 把 TabsList 塞 DialogBody + `!pt-0` hack 對抗 primitive,TabsContent 加了 mt-0
|
|
57
|
+
# 就繞過 Check 2 —— 但 root 錯誤是「沒用 DialogHeader tabsSlot canonical」(雙線 + 底線內縮 +
|
|
58
|
+
# spacing owner 自組)。偵測兩個 root 簽名(任一 → BLOCK 指路 tabsSlot):
|
|
59
|
+
# (a) DialogBody/SheetBody/SurfaceBody className 含 `!pt-0`(important 對抗 primitive 的 pt owner)
|
|
60
|
+
# (b) <TabsList 出現在含 DialogBody 的同段 new content 且無 tabsSlot 字樣
|
|
61
|
+
ROOT_SIG_A=$(printf '%s\n' "$CONTENT" | grep -nE '(DialogBody|SheetBody|SurfaceBody)[^>]*className=[^>]*!pt-0' | grep -v '@tabs-content-gap-ok:' || true)
|
|
62
|
+
ROOT_SIG_B=""
|
|
63
|
+
if printf '%s\n' "$CONTENT" | grep -q '<TabsList' && printf '%s\n' "$CONTENT" | grep -qE '<(DialogBody|SheetBody|SurfaceBody)\b' && ! printf '%s\n' "$CONTENT" | grep -q 'tabsSlot' && ! printf '%s\n' "$CONTENT" | grep -q '@tabs-content-gap-ok:'; then
|
|
64
|
+
ROOT_SIG_B=$(printf '%s\n' "$CONTENT" | grep -n '<TabsList' | head -3)
|
|
65
|
+
fi
|
|
66
|
+
if [ -n "$ROOT_SIG_A" ] || [ -n "$ROOT_SIG_B" ]; then
|
|
67
|
+
cat >&2 << 'EOF_C3'
|
|
68
|
+
🚨 TABS-IN-BODY ROOT BLOCKER(P0,2026-07-08 WM 戰役 — 攔 root 非 symptom)
|
|
69
|
+
|
|
70
|
+
偵測到「TabsList 手塞 chrome body / body 用 !pt-0 hack」簽名 —— 這是「沒用 header tabsSlot
|
|
71
|
+
canonical」的 root 錯誤(後果:header 與 TabsList 雙底線、tabs 底線被 body padding 內縮不滿寬、
|
|
72
|
+
spacing owner 鏈自組)。WM ProjectSettings/TypeSettings 錨例。
|
|
73
|
+
|
|
74
|
+
── 正解 ──
|
|
75
|
+
<Tabs> wrap → <DialogHeader tabsSlot={<TabsList/>}> → <DialogBody><TabsContent className="mt-0">
|
|
76
|
+
照 dialog.stories.tsx#WithTabsInHeader 逐字結構(header-canonical.spec.md Rule W2)。
|
|
77
|
+
Escape:`// @tabs-content-gap-ok: <rationale>`(例:tabs 本來就不屬 header 的內容分頁場景)
|
|
78
|
+
EOF_C3
|
|
79
|
+
exit 2
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
|
|
55
83
|
# ══ Check 2:overlay body 自身用固定 macro gap-N → 該用 layout-space token(2026-07-01 Sheet gap-4 錨例)══
|
|
56
84
|
# Root(layoutSpace.spec.md 規則 2/3):浮層 body 直接堆疊內容的垂直 gap 屬 macro layout-space,該用
|
|
57
85
|
# density-scaling token(並列 = loose / functional 交互 = tight),非固定 gap-N(lg 不縮放 → 跟 DS
|
|
@@ -157,6 +185,7 @@ while IFS= read -r ln; do
|
|
|
157
185
|
UNJUSTIFIED="${UNJUSTIFIED}${ln}: $(echo "$cur" | sed 's/^[[:space:]]*//')\n"
|
|
158
186
|
done <<< "$CANDIDATES"
|
|
159
187
|
|
|
188
|
+
|
|
160
189
|
if [ -z "$UNJUSTIFIED" ]; then exit 0; fi
|
|
161
190
|
|
|
162
191
|
cat >&2 << EOF
|
|
@@ -41,7 +41,7 @@ OUTPUT=$(node "$COMPILE_SCRIPT" "$COMP_NAME" --check 2>&1 || true)
|
|
|
41
41
|
if echo "$OUTPUT" | grep -qE "spec/tsx canonical drift|spec-only|tsx-only"; then
|
|
42
42
|
MSG="📐 Story canonical drift detected in ${COMP_NAME}:\n\n${OUTPUT}\n\nFix tsx componentMeta export 或 spec frontmatter 讓 keys 對齊。"
|
|
43
43
|
ESCAPED=$(printf '%s' "$MSG" | jq -Rs .)
|
|
44
|
-
printf '{"hookSpecificOutput":{"hookEventName":"
|
|
44
|
+
printf '{"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":%s}}\n' "$ESCAPED"
|
|
45
45
|
fi
|
|
46
46
|
|
|
47
47
|
# Skip graceful(migration 未做的元件)不報
|
|
@@ -35,10 +35,19 @@ VIOLATIONS=""
|
|
|
35
35
|
# ── Check 1: shadcn compat alias 回流 ─────────────────────────────────────────
|
|
36
36
|
# These are all shadcn safety-net aliases. Our code must use direct tokens instead.
|
|
37
37
|
# bg-muted / bg-secondary / ring-ring are OUR tokens (kept), not listed here.
|
|
38
|
+
# SSOT-drive(#87 2026-07-11):deny-list SSOT = utility-registry.json;優先從 registry 組 pattern
|
|
39
|
+
# (未來新增 alias 只改 registry 自動傳播到本 write-time 主防線,消除「hardcoded 主 / registry 從」倒置)。
|
|
40
|
+
# registry 讀不到 → 保留 hardcoded fallback(11 條)避免 hook 啞掉。
|
|
41
|
+
_REG="${CLAUDE_PROJECT_DIR:-}/packages/design-system/src/tokens/utility-registry.json"
|
|
42
|
+
[ -f "$_REG" ] || _REG="$(dirname "${BASH_SOURCE[0]}")/../../packages/design-system/src/tokens/utility-registry.json"
|
|
38
43
|
SHADCN_PATTERN='\b(bg-popover|text-popover-foreground|text-muted-foreground|bg-accent|text-accent-foreground|bg-destructive|bg-background|bg-card|text-card-foreground|border-input|text-primary-foreground)\b'
|
|
44
|
+
if [ -f "$_REG" ] && command -v jq >/dev/null 2>&1; then
|
|
45
|
+
_SHADCN_LIST=$(jq -r '.shadcn_alias.block.color_alias | join("|")' "$_REG" 2>/dev/null || true)
|
|
46
|
+
[ -n "$_SHADCN_LIST" ] && SHADCN_PATTERN="\\b(${_SHADCN_LIST})\\b"
|
|
47
|
+
fi
|
|
39
48
|
SHADCN_HITS=$(grep -nE "$SHADCN_PATTERN" "$FILE_PATH" 2>/dev/null | head -5)
|
|
40
49
|
if [ -n "$SHADCN_HITS" ]; then
|
|
41
|
-
VIOLATIONS="${VIOLATIONS}\n⚠️ shadcn compat alias found (必須遷移為 direct token):\n${SHADCN_HITS}\n 映射: bg-popover→bg-surface-raised / text-popover-foreground→text-foreground / text-muted-foreground→text-fg-muted / bg-accent→bg-neutral-hover / text-accent-foreground→text-foreground / bg-destructive→bg-error / bg-background→bg-canvas / bg-card→bg-surface / border-input→border-border / text-primary-foreground→text-white"
|
|
50
|
+
VIOLATIONS="${VIOLATIONS}\n⚠️ shadcn compat alias found (必須遷移為 direct token):\n${SHADCN_HITS}\n 映射: bg-popover→bg-surface-raised / text-popover-foreground→text-foreground / text-muted-foreground→text-fg-muted / bg-accent→bg-neutral-hover / text-accent-foreground→text-foreground / bg-destructive→bg-error / bg-background→bg-canvas / bg-card→bg-surface / text-card-foreground→text-foreground / border-input→border-border / text-primary-foreground→text-white /(其餘 registry alias → 對應 semantic token,見 tokens/color/semantic.css)"
|
|
42
51
|
fi
|
|
43
52
|
|
|
44
53
|
# ── Check 2: Tailwind v4 [--foo] shorthand (silent fail) ─────────────────────
|
|
@@ -99,6 +99,20 @@ if [ "${LAST_USER_LINE:-0}" -gt 0 ] && [ -n "$LAST_ASSISTANT" ]; then
|
|
|
99
99
|
fi
|
|
100
100
|
fi
|
|
101
101
|
|
|
102
|
+
# ── Mechanism 7c: Deep-audit coverage gate(2026-07-12 user verbatim「不抽樣不偷懶…現在和未來可以確保嗎」)──
|
|
103
|
+
# Why: deep audit「完成」宣告前必證 91 dim × Claude+codex 雙軌全有證據。AI 自律不可靠(本 session 漏跑
|
|
104
|
+
# deterministic 24 + judgment 27 + hook 40 三層,只做 claim-vs-code + 反應式補,user 憤怒)。
|
|
105
|
+
# verify-deep-audit-coverage.mjs = 機械閘;宣告完成 + ledger 有缺口 → BLOCK。
|
|
106
|
+
if [ "${LAST_USER_LINE:-0}" -gt 0 ] && [ -n "$LAST_ASSISTANT" ] && [ -f scripts/verify-deep-audit-coverage.mjs ]; then
|
|
107
|
+
DEEPAUDIT_CLAIM_RE='(deep.?audit.{0,10}(完成|完整|done)|稽核.{0,8}(完整完美|全部完成|都.?跑完)|91.{0,6}dim.{0,8}(都|全).{0,4}(跑|過|完|有證據)|Phase A.{0,6}完成)'
|
|
108
|
+
DEEPAUDIT_NEG_RE='(未完成|還沒|尚未|缺口|gap|未跑|待跑|待驗|不算完成|覆蓋.{0,4}未|還有.{0,4}dim|待補)'
|
|
109
|
+
if echo "$LAST_ASSISTANT" | grep -qE "$DEEPAUDIT_CLAIM_RE" && ! echo "$LAST_ASSISTANT" | grep -qE "$DEEPAUDIT_NEG_RE"; then
|
|
110
|
+
if ! node scripts/verify-deep-audit-coverage.mjs >/dev/null 2>&1; then
|
|
111
|
+
CRITICAL_DEEPAUDIT_COVERAGE=1
|
|
112
|
+
fi
|
|
113
|
+
fi
|
|
114
|
+
fi
|
|
115
|
+
|
|
102
116
|
# ── Mechanism 2: Auto-prune trigger ─────────────────────────────────────────
|
|
103
117
|
if [ -f CLAUDE.md ]; then
|
|
104
118
|
L=$(wc -l < CLAUDE.md | tr -d ' ')
|
|
@@ -513,4 +527,21 @@ if [ "${CRITICAL_COMPLETENESS:-0}" = "1" ] && [ -n "$LAST_ASSISTANT" ]; then
|
|
|
513
527
|
fi
|
|
514
528
|
fi
|
|
515
529
|
|
|
530
|
+
# ── BLOCKER for Mechanism 7c deep-audit coverage(2026-07-12 user-authorized)──
|
|
531
|
+
if [ "${CRITICAL_DEEPAUDIT_COVERAGE:-0}" = "1" ] && [ -n "$LAST_ASSISTANT" ]; then
|
|
532
|
+
DACOV_HASH=$(echo "$LAST_ASSISTANT" | tail -c 200 | shasum -a 256 | cut -c1-16)
|
|
533
|
+
LAST_BLOCKED_DACOV_FILE="$PROJECT_DIR/.claude/logs/.last-blocked-deepaudit-coverage.txt"
|
|
534
|
+
LAST_BLOCKED_DACOV=""
|
|
535
|
+
[ -f "$LAST_BLOCKED_DACOV_FILE" ] && LAST_BLOCKED_DACOV=$(cat "$LAST_BLOCKED_DACOV_FILE" 2>/dev/null || echo "")
|
|
536
|
+
if [ "$DACOV_HASH" != "$LAST_BLOCKED_DACOV" ]; then
|
|
537
|
+
echo "$DACOV_HASH" > "$LAST_BLOCKED_DACOV_FILE" 2>/dev/null || true
|
|
538
|
+
GAPLINE=$(node scripts/verify-deep-audit-coverage.mjs 2>/dev/null | grep -E '個 dim-證據缺口' | head -1)
|
|
539
|
+
REASON=$(printf '%s' \
|
|
540
|
+
"🚨 DEEP-AUDIT-COVERAGE BLOCKER(M7c,2026-07-12 user-authorized「不抽樣不偷懶…現在和未來可以確保嗎」):你宣告 deep audit 完成,但 verify-deep-audit-coverage.mjs exit 1 — ${GAPLINE:-91 dim × Claude+codex 雙軌未全有證據}。禁宣稱 done。跑 node scripts/verify-deep-audit-coverage.mjs 看缺哪些 dim,填完(judgment findings 檔 / deterministic log / hook residue verify / codex-dim-audit)才可宣稱;OR 明寫『核心做完,dim 覆蓋待補』。否則 turn 不結束。" \
|
|
541
|
+
"本機制起因:本 session AI 漏跑 91 dim 裡 deterministic 24 + judgment 27 + hook 40 三層,只做 claim-vs-code + 反應式補,user 憤怒。觸發器 = 宣告 deep audit 完成本身。")
|
|
542
|
+
printf '{"decision":"block","reason":%s}\n' "$(printf '%s' "$REASON" | jq -Rs .)"
|
|
543
|
+
exit 0
|
|
544
|
+
fi
|
|
545
|
+
fi
|
|
546
|
+
|
|
516
547
|
exit 0
|
|
@@ -131,6 +131,30 @@ echo "Test 5: nonexistent path → pass (silently skip)"
|
|
|
131
131
|
run_hook "src/does-not-exist-$$.tsx"
|
|
132
132
|
expect_pass "Test 5 nonexistent path"
|
|
133
133
|
|
|
134
|
+
# ── Test 6: ABSOLUTE path with explorations import → block ───────────────────
|
|
135
|
+
# Real Edit/Write events carry absolute file_path(2026-07-10 wiring-hunt:hook
|
|
136
|
+
# 原本只比對相對路徑 prefix → 對真實 edits 形同虛設)。
|
|
137
|
+
echo ""
|
|
138
|
+
echo "Test 6: absolute path tsx imports from src/explorations/ → block"
|
|
139
|
+
F6="$SANDBOX/violation-abs.tsx"
|
|
140
|
+
cat >"$F6" <<'EOF'
|
|
141
|
+
import { ProtoX } from '@/explorations/foo/bar'
|
|
142
|
+
export const X = () => <ProtoX />
|
|
143
|
+
EOF
|
|
144
|
+
run_hook "$F6"
|
|
145
|
+
expect_block "Test 6 absolute path explorations import blocked" "Blocked"
|
|
146
|
+
|
|
147
|
+
# ── Test 7: ABSOLUTE path clean import → pass ────────────────────────────────
|
|
148
|
+
echo ""
|
|
149
|
+
echo "Test 7: absolute path tsx with clean import → pass"
|
|
150
|
+
F7="$SANDBOX/clean-abs.tsx"
|
|
151
|
+
cat >"$F7" <<'EOF'
|
|
152
|
+
import { Button } from '@/design-system/components/Button/button'
|
|
153
|
+
export const X = () => <Button>OK</Button>
|
|
154
|
+
EOF
|
|
155
|
+
run_hook "$F7"
|
|
156
|
+
expect_pass "Test 7 absolute path clean import"
|
|
157
|
+
|
|
134
158
|
# ── Summary ──────────────────────────────────────────────────────────────────
|
|
135
159
|
echo ""
|
|
136
160
|
echo "════════════════════════════════════════"
|
|
@@ -118,6 +118,50 @@ EOF
|
|
|
118
118
|
run_hook "$TMPDIR_TEST/.claude/memory/project_audit_progress.md" "Edit"
|
|
119
119
|
expect_block_stderr "5. judgment dim 缺 prompt → Validator C exit-2 block" "VALIDATOR BLOCK"
|
|
120
120
|
|
|
121
|
+
# 6/7. Validator K 決策品質四要件(2026-07-14;SSOT = deep-audit SKILL C.1「🔒 決策品質四要件」)
|
|
122
|
+
# 拍板 section 內每個決策 block 必含 SSOT-check / 世界級 cite(URL)/ codex verdict / design-fit 四 marker。
|
|
123
|
+
# 先補 `## 99.` prompt 讓 test 5 留下的 Validator C 條件通過,隔離 K 的判定。
|
|
124
|
+
cat > "$TMPDIR_TEST/.claude/skills/design-system-audit/references/audit-prompts.md" <<'EOF'
|
|
125
|
+
## 1. foo
|
|
126
|
+
prompt
|
|
127
|
+
## 99. test judgment dim
|
|
128
|
+
prompt
|
|
129
|
+
EOF
|
|
130
|
+
mkdir -p "$TMPDIR_TEST/.claude/logs/deep-audit-test"
|
|
131
|
+
cat > "$TMPDIR_TEST/.claude/logs/deep-audit-test/C1-final-report.md" <<'EOF'
|
|
132
|
+
# Deep Audit 報告
|
|
133
|
+
Dim 1: pass
|
|
134
|
+
|
|
135
|
+
### 待你拍板
|
|
136
|
+
1. 決策一:Popover 內距是否改 12px
|
|
137
|
+
- SSOT 理由:改跨元件 canonical 視覺結構
|
|
138
|
+
- SSOT-check:grep spec + memory,無既有拍板
|
|
139
|
+
- codex verdict:agree(辯論共識)
|
|
140
|
+
- 設計語言 fit:符合 density canonical
|
|
141
|
+
EOF
|
|
142
|
+
run_hook "$TMPDIR_TEST/.claude/logs/deep-audit-test/C1-final-report.md" "Write"
|
|
143
|
+
expect_block_stderr "6. 決策缺世界級 cite → Validator K exit-2 block" "決策四要件不全"
|
|
144
|
+
|
|
145
|
+
cat > "$TMPDIR_TEST/.claude/logs/deep-audit-test/C1-final-report.md" <<'EOF'
|
|
146
|
+
# Deep Audit 報告
|
|
147
|
+
Dim 1: pass
|
|
148
|
+
|
|
149
|
+
### 待你拍板
|
|
150
|
+
1. 決策一:Popover 內距是否改 12px
|
|
151
|
+
- SSOT 理由:改跨元件 canonical 視覺結構
|
|
152
|
+
- SSOT-check:grep spec + memory,無既有拍板
|
|
153
|
+
- 世界級:Polaris https://polaris.shopify.com/tokens/space / Material / Ant(3 家)
|
|
154
|
+
- codex verdict:agree(辯論共識)
|
|
155
|
+
- 設計語言 fit:符合 density canonical
|
|
156
|
+
EOF
|
|
157
|
+
run_hook "$TMPDIR_TEST/.claude/logs/deep-audit-test/C1-final-report.md" "Write"
|
|
158
|
+
if [ "$EXIT" = "0" ]; then
|
|
159
|
+
echo " PASS 7. 四要件齊 → Validator K pass(exit 0)"; PASS=$((PASS+1))
|
|
160
|
+
else
|
|
161
|
+
echo " FAIL 7. 四要件齊 → Validator K pass (expected exit 0, got $EXIT, stderr=[$STDERR_TEXT])"
|
|
162
|
+
FAIL=$((FAIL+1)); FAILED_TESTS="${FAILED_TESTS}\n - 7. 四要件齊 pass"
|
|
163
|
+
fi
|
|
164
|
+
|
|
121
165
|
echo ""
|
|
122
166
|
echo "=== Summary ==="
|
|
123
167
|
echo "Passed: $PASS / $((PASS + FAIL))"
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
# · bare mention(`ls .../codex` / `mycodex exec` / git commit msg 含 "codex")→ silent
|
|
9
9
|
# · `--help` / `--version` 等 introspection flag → silent
|
|
10
10
|
# - 命中 codex exec/review → 擷取 brief content(cat-pipe / $(cat) / stdin `<` / inline arg)
|
|
11
|
-
# - Brief 必含
|
|
11
|
+
# - Brief 必含 7 invariant keyword,缺任一 → exit 2 BLOCKER:
|
|
12
12
|
# 1️⃣ 全盤閱讀 2️⃣ Triple-verify 3️⃣ 禁抽樣 4️⃣ 禁列檔
|
|
13
|
+
# 5️⃣ 輸入對等(A.0 鏡射錨點) 6️⃣ 判準對等(audit-prompts rubric) 7️⃣ A.1b(per-component claim-vs-code)
|
|
13
14
|
# - Escape:brief 含 `@codex-brief-invariant-skip:` → silent exit 0
|
|
14
15
|
#
|
|
15
16
|
# Positive(should BLOCK exit 2):缺 invariant 的 brief。
|
|
@@ -48,6 +49,9 @@ cat > "$GOOD_BRIEF" <<'EOF'
|
|
|
48
49
|
2. triple-verify per finding(grep + Read + canonical exception check)
|
|
49
50
|
3. 禁抽樣 — DS-wide ALL files,sub-agent sampled = reject
|
|
50
51
|
4. 禁列檔 — 只讀 12 file,直接出 verdict
|
|
52
|
+
5. 閱讀清單鏡射 A.0:CLAUDE.md + .claude/rules/meta-patterns.md 等 5 rules + 4 references + 全 spec.md + memory MEMORY.md index
|
|
53
|
+
6. 判準對等:codex 讀 design-system-audit/references/audit-prompts.md 每 dim rubric,逐 dim 套用
|
|
54
|
+
7. A.1b per-component claim-vs-code 對抗驗證:讀每元件 .tsx + wrap lib 逐句驗宣稱
|
|
51
55
|
EOF
|
|
52
56
|
|
|
53
57
|
# Partial brief:缺 invariant 3(禁抽樣);其餘 3 個 keyword 齊
|
|
@@ -146,7 +150,7 @@ run_hook "git commit -m \"${CX} collab notes\""
|
|
|
146
150
|
expect_pass_silent "5. git commit msg 含 codex,無 exec/review → silent"
|
|
147
151
|
|
|
148
152
|
# 6. inline codex exec WITH all 4 invariants → silent
|
|
149
|
-
GOOD_INLINE="${CX} exec \"全盤閱讀全部 source。triple-verify per finding。禁抽樣 DS-wide ALL files。禁列檔 只讀 10 file 直接出 verdict
|
|
153
|
+
GOOD_INLINE="${CX} exec \"全盤閱讀全部 source(鏡射 A.0:meta-patterns rules + memory MEMORY.md index)。triple-verify per finding。禁抽樣 DS-wide ALL files。禁列檔 只讀 10 file 直接出 verdict。判準對等:讀 audit-prompts.md 逐 dim rubric。A.1b per-component claim-vs-code 對抗驗證讀 .tsx 逐句驗宣稱。\""
|
|
150
154
|
run_hook "$GOOD_INLINE"
|
|
151
155
|
expect_pass_silent "6. inline brief 全 4 invariant → silent"
|
|
152
156
|
|
|
@@ -158,6 +162,43 @@ expect_pass_silent "7. cat-pipe full-brief file → silent"
|
|
|
158
162
|
run_hook "${CX} exec \"\$(cat $GOOD_BRIEF)\""
|
|
159
163
|
expect_pass_silent "8. \$(cat) full-brief file → silent"
|
|
160
164
|
|
|
165
|
+
# 8b. 4 invariant 齊但缺輸入對等錨點(泛 glob 閱讀清單)→ BLOCK(2026-07-10 5️⃣)
|
|
166
|
+
NOPARITY_BRIEF="$TMP_DIR/noparity-brief.md"
|
|
167
|
+
cat > "$NOPARITY_BRIEF" <<'EOF'
|
|
168
|
+
# Codex deep-audit brief
|
|
169
|
+
1. 全盤閱讀全部 source(.claude/rules/* 泛 glob,禁憑記憶)
|
|
170
|
+
2. triple-verify per finding(grep + Read + canonical exception check)
|
|
171
|
+
3. 禁抽樣 — DS-wide ALL files,sub-agent sampled = reject
|
|
172
|
+
4. 禁列檔 — 只讀 12 file,直接出 verdict
|
|
173
|
+
EOF
|
|
174
|
+
run_hook "cat $NOPARITY_BRIEF | ${CX} exec"
|
|
175
|
+
expect_block "8b. 缺輸入對等錨點(泛 glob)→ BLOCK" "5️⃣"
|
|
176
|
+
|
|
177
|
+
# 8c. 5 invariant 齊但缺判準對等(audit-prompts)→ 6️⃣ BLOCK(2026-07-10)
|
|
178
|
+
NORUBRIC_BRIEF="$TMP_DIR/norubric-brief.md"
|
|
179
|
+
cat > "$NORUBRIC_BRIEF" <<'EOF'
|
|
180
|
+
# Codex deep-audit brief
|
|
181
|
+
1. 全盤閱讀全部 source(.claude/rules/meta-patterns.md + memory MEMORY.md,禁憑記憶)
|
|
182
|
+
2. triple-verify per finding(grep + Read + canonical exception check)
|
|
183
|
+
3. 禁抽樣 — DS-wide ALL files,sub-agent sampled = reject
|
|
184
|
+
4. 禁列檔 — 只讀 12 file,直接出 verdict
|
|
185
|
+
EOF
|
|
186
|
+
run_hook "cat $NORUBRIC_BRIEF | ${CX} exec"
|
|
187
|
+
expect_block "8c. 缺判準對等(無 audit-prompts)→ BLOCK" "6️⃣"
|
|
188
|
+
|
|
189
|
+
# 8d. 1️⃣-6️⃣ 齊但缺 A.1b(per-component claim-vs-code)→ 7️⃣ BLOCK(2026-07-10)
|
|
190
|
+
NOA1B_BRIEF="$TMP_DIR/noa1b-brief.md"
|
|
191
|
+
cat > "$NOA1B_BRIEF" <<'EOF'
|
|
192
|
+
# Codex deep-audit brief
|
|
193
|
+
1. 全盤閱讀全部 source(.claude/rules/meta-patterns.md + memory MEMORY.md,禁憑記憶)
|
|
194
|
+
2. triple-verify per finding(grep + Read + canonical exception check)
|
|
195
|
+
3. 禁抽樣 — DS-wide ALL files,sub-agent sampled = reject
|
|
196
|
+
4. 禁列檔 — 只讀 12 file,直接出 verdict
|
|
197
|
+
5. 判準對等:讀 design-system-audit/references/audit-prompts.md 每 dim rubric,逐 dim 套用
|
|
198
|
+
EOF
|
|
199
|
+
run_hook "cat $NOA1B_BRIEF | ${CX} exec"
|
|
200
|
+
expect_block "8d. 缺 A.1b(per-component claim-vs-code)→ 7️⃣ BLOCK" "7️⃣"
|
|
201
|
+
|
|
161
202
|
# 9. stdin redirect full brief → silent
|
|
162
203
|
run_hook "${CX} exec < $GOOD_BRIEF"
|
|
163
204
|
expect_pass_silent "9. stdin redirect full-brief file → silent"
|
|
@@ -230,6 +230,118 @@ expect_silent "25. P8 nearmiss shadow-[var(--elevation-100)] → silent"
|
|
|
230
230
|
run_hook "$PROD_TSX" 'export const C = () => <div className="max-w-[600px] grid-cols-[1fr_2fr]">x</div>'
|
|
231
231
|
expect_silent "26. P8 nearmiss max-w-[600px]/grid-cols-[...](非色字 shadow)→ silent"
|
|
232
232
|
|
|
233
|
+
# ── 手刻 menu-item 可點列(2026-07-10 WM TypeSettingsDialog 左 rail 錨例)──
|
|
234
|
+
# 27. POSITIVE:手刻 button + hover:bg-neutral-hover + bg-neutral-selected 成對 → BLOCK
|
|
235
|
+
run_hook "$PROD_TSX" 'const cls = `flex w-full items-center gap-2 rounded-md hover:bg-neutral-hover ${sel ? "bg-neutral-selected" : ""}`; export const C = () => <button type="button" className={cls}>Task</button>'
|
|
236
|
+
expect_block "27. 手刻 nav row(hover+selected 成對)→ BLOCK"
|
|
237
|
+
|
|
238
|
+
# 28. NEGATIVE:同簽名 token 出現但已消費 <MenuItem>(正道)→ silent
|
|
239
|
+
run_hook "$PROD_TSX" 'export const C = () => <MenuItem size="sm" selected startContent={<Badge/>}>Task</MenuItem> /* hover:bg-neutral-hover bg-neutral-selected */'
|
|
240
|
+
expect_silent "28. 消費 <MenuItem> → silent"
|
|
241
|
+
|
|
242
|
+
# 29. NEGATIVE:只有 hover 無 selected(單純 hover row,非 menu-item family 簽名)→ silent
|
|
243
|
+
run_hook "$PROD_TSX" 'export const C = () => <button className="hover:bg-neutral-hover">row</button>'
|
|
244
|
+
expect_silent "29. 只 hover 無 selected → silent"
|
|
245
|
+
|
|
246
|
+
# 30. NEGATIVE:escape marker → silent
|
|
247
|
+
run_hook "$PROD_TSX" 'export const C = () => <div className="hover:bg-neutral-hover bg-neutral-selected">x</div> // @nav-row-handcraft-ok: calendar cell 非 menu 語義'
|
|
248
|
+
expect_silent "30. @nav-row-handcraft-ok escape → silent"
|
|
249
|
+
|
|
250
|
+
# ── 2026-07-10 批次 A(治理覆蓋 matrix 收官)──
|
|
251
|
+
# 31. C5 POSITIVE:亮色底 + text-white 對比配對違規 → BLOCK
|
|
252
|
+
run_hook "$PROD_TSX" 'export const T = () => <span className="bg-[var(--color-amber-6)] text-white size-4">A</span>'
|
|
253
|
+
expect_block "31. C5 亮色底+text-white 配對 → BLOCK"
|
|
254
|
+
|
|
255
|
+
# 32. C5 NEGATIVE:CAT_SOLID 正道(深字桶自帶 on-emphasis-dark)→ silent
|
|
256
|
+
run_hook "$PROD_TSX" 'export const T = () => <span className={`size-4 ${CAT_SOLID[hue]}`}>A</span>'
|
|
257
|
+
expect_silent "32. C5 消費 CAT_SOLID → silent"
|
|
258
|
+
|
|
259
|
+
# 33. C18 POSITIVE:children 計數括號串接 → BLOCK
|
|
260
|
+
run_hook "$PROD_TSX" 'export const H = () => <span>{group.label} ({items.length})</span>'
|
|
261
|
+
expect_block "33. C18 {label} ({count}) 串接 → BLOCK"
|
|
262
|
+
|
|
263
|
+
# 34. C18 NEGATIVE:aria-label 字串層(attr 非 children)→ silent
|
|
264
|
+
run_hook "$PROD_TSX" 'export const H = () => <span aria-label={`${label} (${count})`}>{label}</span>'
|
|
265
|
+
expect_silent "34. C18 aria-label 括號形 → silent"
|
|
266
|
+
|
|
267
|
+
# 35. C17 POSITIVE:vertical Separator 無 mx → BLOCK
|
|
268
|
+
run_hook "$PROD_TSX" 'export const B = () => <><Button>A</Button><Separator orientation="vertical" className="h-6" /><Button>B</Button></>'
|
|
269
|
+
expect_block "35. C17 vertical Separator 無 mx → BLOCK"
|
|
270
|
+
|
|
271
|
+
# 36. C17 NEGATIVE:h-6 mx-1 canonical → silent
|
|
272
|
+
run_hook "$PROD_TSX" 'export const B = () => <><Button>A</Button><Separator orientation="vertical" className="h-6 mx-1" /><Button>B</Button></>'
|
|
273
|
+
expect_silent "36. C17 h-6 mx-1 canonical → silent"
|
|
274
|
+
|
|
275
|
+
# 37. C20 POSITIVE:手刻 underline 連結字 → BLOCK
|
|
276
|
+
run_hook "$PROD_TSX" 'export const D = () => <span className="text-primary underline">upload</span>'
|
|
277
|
+
expect_block "37. C20 裸 underline 連結 → BLOCK"
|
|
278
|
+
|
|
279
|
+
# 38. C20 NEGATIVE:no-underline(合規移除底線)→ silent
|
|
280
|
+
run_hook "$PROD_TSX" 'export const D = () => <a className="no-underline text-primary">upload</a>'
|
|
281
|
+
expect_silent "38. C20 no-underline → silent"
|
|
282
|
+
|
|
283
|
+
# 39. C10 POSITIVE:spacer 把 Search 推最右 → BLOCK
|
|
284
|
+
run_hook "$PROD_TSX" 'export const T = () => <div><Button>Add</Button><span className="flex-1" /><Input placeholder="Search employees" /></div>'
|
|
285
|
+
expect_block "39. C10 業務 search 被推最右 → BLOCK"
|
|
286
|
+
|
|
287
|
+
# 40. C10 NEGATIVE:search 在業務層(無 spacer 前置)→ silent
|
|
288
|
+
run_hook "$PROD_TSX" 'export const T = () => <div><Button>Add</Button><Input placeholder="Search employees" /><span className="flex-1" /></div>'
|
|
289
|
+
expect_silent "40. C10 search 歸業務層 → silent"
|
|
290
|
+
|
|
291
|
+
# 41. C11 POSITIVE:DialogHeader 手放 X(雙 X)→ BLOCK
|
|
292
|
+
run_hook "$PROD_TSX" 'export const D = () => <DialogHeader><DialogTitle>Edit</DialogTitle><Button iconOnly startIcon={X} aria-label="Close" /></DialogHeader>'
|
|
293
|
+
expect_block "41. C11 DialogHeader 雙 X → BLOCK"
|
|
294
|
+
|
|
295
|
+
# 42. C11 NEGATIVE:header 操作走 actions slot → silent
|
|
296
|
+
run_hook "$PROD_TSX" 'export const D = () => <DialogHeader actions={<Button iconOnly startIcon={X} aria-label="Prev" />}><DialogTitle>Edit</DialogTitle></DialogHeader>'
|
|
297
|
+
expect_silent "42. C11 actions slot → silent"
|
|
298
|
+
|
|
299
|
+
# 43. C12 POSITIVE:Select 硬寬 w-36 → BLOCK
|
|
300
|
+
run_hook "$PROD_TSX" 'export const F = () => <Select className="w-36" options={opts} />'
|
|
301
|
+
expect_block "43. C12 Select 硬寬 w-36 → BLOCK"
|
|
302
|
+
|
|
303
|
+
# 44. C12 NEGATIVE:width="hug" 語義軸 → silent
|
|
304
|
+
run_hook "$PROD_TSX" 'export const F = () => <Select width="hug" options={opts} />'
|
|
305
|
+
expect_silent "44. C12 width=hug → silent"
|
|
306
|
+
|
|
307
|
+
# 45. named-import 除鏽 POSITIVE:無 DS. 前綴的 LinkInput placeholder-only 也要抓 → BLOCK
|
|
308
|
+
run_hook "$PROD_TSX" 'export const L = () => <LinkInput placeholder="https://" />'
|
|
309
|
+
expect_block "45. named-import <LinkInput placeholder-only → BLOCK(除鏽)"
|
|
310
|
+
|
|
311
|
+
# ── C19 兩欄 dialog 共用捲軸(2026-07-10 user 拍板組合 canonical)──
|
|
312
|
+
# 46. POSITIVE:兩欄(border-l)+ 只有 1 個 ScrollArea = 共用捲軸 → BLOCK
|
|
313
|
+
run_hook "$PROD_TSX" 'export const D = () => <DialogBody><ScrollArea><div className="flex"><div>main</div><aside className="border-l">meta</aside></div></ScrollArea></DialogBody>'
|
|
314
|
+
expect_block "46. C19 兩欄共用單一 ScrollArea → BLOCK"
|
|
315
|
+
|
|
316
|
+
# 47. NEGATIVE:各欄自帶 ScrollArea(組合 canonical)→ silent
|
|
317
|
+
run_hook "$PROD_TSX" 'export const D = () => <DialogBody><div className="flex"><ScrollArea>main</ScrollArea><aside className="border-l"><ScrollArea>meta</ScrollArea></aside></div></DialogBody>'
|
|
318
|
+
expect_silent "47. C19 各欄自帶 ScrollArea → silent"
|
|
319
|
+
|
|
320
|
+
# 48. NEGATIVE:escape → silent
|
|
321
|
+
run_hook "$PROD_TSX" 'export const D = () => <DialogBody><div className="flex border-l">x</div></DialogBody> // @two-pane-dialog-ok: 非兩欄,版面裝飾線'
|
|
322
|
+
expect_silent "48. C19 @two-pane-dialog-ok escape → silent"
|
|
323
|
+
|
|
324
|
+
# ── C7 SelectMenu 直用 + C13 手刻 section header(2026-07-10 收官)──
|
|
325
|
+
# 49. C7 POSITIVE:<SelectMenu> 直用 → BLOCK
|
|
326
|
+
run_hook "$PROD_TSX" 'export const M = () => <SelectMenu options={opts} onSelect={pick} />'
|
|
327
|
+
expect_block "49. C7 <SelectMenu> 直用 → BLOCK"
|
|
328
|
+
|
|
329
|
+
# 50. C7 NEGATIVE:<Select>(正道)→ silent
|
|
330
|
+
run_hook "$PROD_TSX" 'export const M = () => <Select options={opts} onChange={pick} />'
|
|
331
|
+
expect_silent "50. C7 <Select> 正道 → silent"
|
|
332
|
+
|
|
333
|
+
# 51. C13 POSITIVE:手刻可收合標題列(Chevron + justify-between + button)→ BLOCK
|
|
334
|
+
run_hook "$PROD_TSX" 'export const H = () => <button onClick={toggle} className="flex w-full items-center justify-between"><span>Description</span><ChevronDown className="size-4" /></button>'
|
|
335
|
+
expect_block "51. C13 手刻可收合標題列 → BLOCK"
|
|
336
|
+
|
|
337
|
+
# 52. C13 NEGATIVE:共用 SectionHeader 元件(正道)→ silent
|
|
338
|
+
run_hook "$PROD_TSX" 'export const H = () => <SectionHeader title="Description" collapsed={c} onToggle={toggle} />'
|
|
339
|
+
expect_silent "52. C13 共用 SectionHeader → silent"
|
|
340
|
+
|
|
341
|
+
# 53. C13 NEGATIVE:escape(非 section 標題語義)→ silent
|
|
342
|
+
run_hook "$PROD_TSX" 'export const P = () => <button onClick={next} className="flex justify-between">next<ChevronRight /></button> // @section-header-ok: 分頁導航非 section 標題'
|
|
343
|
+
expect_silent "53. C13 @section-header-ok escape → silent"
|
|
344
|
+
|
|
233
345
|
echo ""
|
|
234
346
|
echo "=== Summary ==="
|
|
235
347
|
echo "Passed: $PASS / $((PASS + FAIL))"
|
|
@@ -161,12 +161,19 @@ expect_pass_silent "N4. DS internal stories → excluded silent"
|
|
|
161
161
|
run_hook "Read" "$CONSUMER_STORY" "$CONTENT_VIOLATION"
|
|
162
162
|
expect_pass_silent "N5. tool=Read → silent"
|
|
163
163
|
|
|
164
|
-
# N6. over-broad guard A:bare <Dialog>(no DS. namespace prefix)→ silent
|
|
164
|
+
# N6. over-broad guard A:bare <Dialog>(no DS. namespace prefix)from consumer-local import → silent
|
|
165
165
|
# consumer 用自己的 local Dialog,不是高風險 DS primitive → 不該 fire
|
|
166
166
|
CONTENT_BARE='import { Dialog } from "./local-dialog";
|
|
167
167
|
export const Basic = () => <Dialog open>hi</Dialog>;'
|
|
168
168
|
run_hook "Write" "$CONSUMER_STORY" "$CONTENT_BARE"
|
|
169
|
-
expect_pass_silent "N6. bare <Dialog> (
|
|
169
|
+
expect_pass_silent "N6. bare <Dialog> (local import) → silent (over-broad guard)"
|
|
170
|
+
|
|
171
|
+
# P5. named-import 除鏽 POSITIVE(2026-07-10):bare <Dialog> 但由 DS package named-import 進來
|
|
172
|
+
# → 是真 DS Dialog(fork 慣用 named import 繞過 <DS.> 前綴)→ 無 marker 必 BLOCK
|
|
173
|
+
CONTENT_NAMED='import { Dialog, Button } from "@qijenchen/design-system";
|
|
174
|
+
export const Basic = () => <Dialog open><Button>ok</Button></Dialog>;'
|
|
175
|
+
run_hook "Write" "$CONSUMER_STORY" "$CONTENT_NAMED"
|
|
176
|
+
expect_block "P5. named-import <Dialog> from DS pkg 無 marker → BLOCK" "CONSUMER-STORY-BASELINE BLOCKER"
|
|
170
177
|
|
|
171
178
|
# N7. over-broad guard B:comment / prose mentioning "Dialog DataTable Sheet" but no JSX usage → silent
|
|
172
179
|
CONTENT_PROSE='// This story demonstrates a layout. We avoid Dialog and DataTable here.
|