@qijenchen/design-system 0.1.0-beta.95 → 0.1.0-beta.99
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/README.md +1 -0
- package/dist/components/AccountMenu/account-menu.d.ts +86 -0
- package/dist/components/AccountMenu/account-menu.d.ts.map +1 -0
- package/dist/components/AccountMenu/account-menu.js +64 -0
- package/dist/components/AccountMenu/account-menu.js.map +1 -0
- package/dist/components/AccountMenu/index.d.ts +2 -0
- package/dist/components/AccountMenu/index.d.ts.map +1 -0
- package/dist/components/AccountMenu/index.js +6 -0
- package/dist/components/AccountMenu/index.js.map +1 -0
- package/dist/components/AppShell/_demo-helpers.d.ts.map +1 -1
- package/dist/components/AppShell/app-shell.d.ts.map +1 -1
- package/dist/components/AppShell/app-shell.js +2 -2
- package/dist/components/AppShell/app-shell.js.map +1 -1
- package/dist/components/Badge/badge.d.ts +1 -1
- package/dist/components/Button/button.d.ts +3 -3
- package/dist/components/Button/button.d.ts.map +1 -1
- package/dist/components/Button/button.js +3 -2
- package/dist/components/Button/button.js.map +1 -1
- package/dist/components/Calendar/calendar.d.ts +10 -21
- package/dist/components/Calendar/calendar.d.ts.map +1 -1
- package/dist/components/Calendar/calendar.js +52 -59
- package/dist/components/Calendar/calendar.js.map +1 -1
- package/dist/components/Combobox/combobox.d.ts.map +1 -1
- package/dist/components/Combobox/combobox.js +1 -0
- package/dist/components/Combobox/combobox.js.map +1 -1
- package/dist/components/Command/command.d.ts.map +1 -1
- package/dist/components/Command/command.js +3 -1
- package/dist/components/Command/command.js.map +1 -1
- package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
- package/dist/components/DataTable/cell-registry.js +1 -5
- package/dist/components/DataTable/cell-registry.js.map +1 -1
- package/dist/components/DataTable/data-table-filter-group.d.ts +6 -2
- package/dist/components/DataTable/data-table-filter-group.d.ts.map +1 -1
- package/dist/components/DataTable/data-table-filter-group.js +32 -27
- package/dist/components/DataTable/data-table-filter-group.js.map +1 -1
- package/dist/components/DataTable/data-table-filter-labels.d.ts +44 -0
- package/dist/components/DataTable/data-table-filter-labels.d.ts.map +1 -0
- package/dist/components/DataTable/data-table-filter-labels.js +55 -0
- package/dist/components/DataTable/data-table-filter-labels.js.map +1 -0
- package/dist/components/DataTable/data-table-filter-panel.d.ts +11 -0
- package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -1
- package/dist/components/DataTable/data-table-filter-panel.js +33 -10
- package/dist/components/DataTable/data-table-filter-panel.js.map +1 -1
- package/dist/components/DataTable/data-table-filter-value-picker.d.ts +4 -1
- package/dist/components/DataTable/data-table-filter-value-picker.d.ts.map +1 -1
- package/dist/components/DataTable/data-table-filter-value-picker.js +22 -8
- package/dist/components/DataTable/data-table-filter-value-picker.js.map +1 -1
- package/dist/components/DataTable/data-table.d.ts.map +1 -1
- package/dist/components/DataTable/data-table.js +5 -4
- package/dist/components/DataTable/data-table.js.map +1 -1
- package/dist/components/DataTable/index.js +2 -0
- package/dist/components/DataTable/index.js.map +1 -1
- package/dist/components/DatePicker/date-picker.d.ts.map +1 -1
- package/dist/components/DatePicker/date-picker.js +187 -156
- package/dist/components/DatePicker/date-picker.js.map +1 -1
- package/dist/components/Dialog/dialog.d.ts +1 -1
- package/dist/components/Dialog/dialog.d.ts.map +1 -1
- package/dist/components/Dialog/dialog.js +4 -2
- package/dist/components/Dialog/dialog.js.map +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.d.ts +4 -1
- package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
- package/dist/components/DropdownMenu/dropdown-menu.js +46 -14
- package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
- package/dist/components/Field/field-context.d.ts +12 -0
- package/dist/components/Field/field-context.d.ts.map +1 -1
- package/dist/components/Field/field-context.js +10 -1
- package/dist/components/Field/field-context.js.map +1 -1
- package/dist/components/Field/field-wrapper.d.ts.map +1 -1
- package/dist/components/Field/field-wrapper.js +7 -1
- package/dist/components/Field/field-wrapper.js.map +1 -1
- package/dist/components/Field/field.d.ts.map +1 -1
- package/dist/components/Field/field.js +11 -2
- package/dist/components/Field/field.js.map +1 -1
- package/dist/components/FieldControlGroup/field-control-group.d.ts +2 -5
- package/dist/components/FieldControlGroup/field-control-group.d.ts.map +1 -1
- package/dist/components/FieldControlGroup/field-control-group.js +2 -2
- package/dist/components/FieldControlGroup/field-control-group.js.map +1 -1
- package/dist/components/FileUpload/file-upload.js +1 -1
- package/dist/components/FileUpload/file-upload.js.map +1 -1
- package/dist/components/FileViewer/file-viewer.d.ts +1 -1
- package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
- package/dist/components/FileViewer/file-viewer.js +20 -3
- package/dist/components/FileViewer/file-viewer.js.map +1 -1
- package/dist/components/InlineEdit/inline-edit.d.ts +5 -0
- package/dist/components/InlineEdit/inline-edit.d.ts.map +1 -1
- package/dist/components/InlineEdit/inline-edit.js +65 -33
- package/dist/components/InlineEdit/inline-edit.js.map +1 -1
- package/dist/components/Input/input.d.ts.map +1 -1
- package/dist/components/Input/input.js +3 -2
- package/dist/components/Input/input.js.map +1 -1
- package/dist/components/LinkInput/link-input.d.ts.map +1 -1
- package/dist/components/LinkInput/link-input.js +2 -1
- package/dist/components/LinkInput/link-input.js.map +1 -1
- package/dist/components/Menu/menu-item.d.ts.map +1 -1
- package/dist/components/Menu/menu-item.js +4 -2
- package/dist/components/Menu/menu-item.js.map +1 -1
- package/dist/components/PeoplePicker/people-picker.d.ts +2 -0
- package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
- package/dist/components/PeoplePicker/people-picker.js +4 -0
- package/dist/components/PeoplePicker/people-picker.js.map +1 -1
- package/dist/components/Popover/popover.d.ts.map +1 -1
- package/dist/components/Popover/popover.js +4 -2
- package/dist/components/Popover/popover.js.map +1 -1
- package/dist/components/ScrollArea/scroll-area.d.ts +4 -3
- package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -1
- package/dist/components/ScrollArea/scroll-area.js +1 -1
- package/dist/components/ScrollArea/scroll-area.js.map +1 -1
- package/dist/components/Select/select.d.ts.map +1 -1
- package/dist/components/Select/select.js +59 -37
- package/dist/components/Select/select.js.map +1 -1
- package/dist/components/SelectMenu/select-menu.d.ts +2 -0
- package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
- package/dist/components/SelectMenu/select-menu.js +3 -1
- package/dist/components/SelectMenu/select-menu.js.map +1 -1
- package/dist/components/Sheet/sheet.d.ts +1 -1
- package/dist/components/Sidebar/sidebar.js +2 -2
- package/dist/components/Sidebar/sidebar.js.map +1 -1
- package/dist/components/Tabs/tabs.d.ts.map +1 -1
- package/dist/components/Tabs/tabs.js +3 -0
- package/dist/components/Tabs/tabs.js.map +1 -1
- package/dist/components/Tag/tag.d.ts +1 -1
- package/dist/components/Tag/tag.d.ts.map +1 -1
- package/dist/components/Tag/tag.js +4 -3
- package/dist/components/Tag/tag.js.map +1 -1
- package/dist/components/Textarea/textarea.d.ts +11 -0
- package/dist/components/Textarea/textarea.d.ts.map +1 -1
- package/dist/components/Textarea/textarea.js +22 -5
- package/dist/components/Textarea/textarea.js.map +1 -1
- package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
- package/dist/components/TimePicker/time-picker.js +4 -3
- package/dist/components/TimePicker/time-picker.js.map +1 -1
- package/dist/components/Tooltip/tooltip.d.ts +1 -1
- package/dist/components/Tooltip/tooltip.d.ts.map +1 -1
- package/dist/components/Tooltip/tooltip.js +26 -1
- package/dist/components/Tooltip/tooltip.js.map +1 -1
- package/dist/components/TreeView/tree-view.d.ts +2 -0
- package/dist/components/TreeView/tree-view.d.ts.map +1 -1
- package/dist/components/TreeView/tree-view.js +3 -2
- package/dist/components/TreeView/tree-view.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.d.ts +10 -1
- package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
- package/dist/patterns/element-anatomy/item-anatomy.js +77 -29
- package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
- package/dist/patterns/header-canonical/chrome-header.d.ts +11 -4
- package/dist/patterns/header-canonical/chrome-header.d.ts.map +1 -1
- package/dist/patterns/header-canonical/chrome-header.js +1 -1
- package/dist/patterns/header-canonical/chrome-header.js.map +1 -1
- package/dist/patterns/overlay-surface/overlay-surface.d.ts +4 -3
- package/dist/patterns/overlay-surface/overlay-surface.d.ts.map +1 -1
- package/dist/patterns/overlay-surface/overlay-surface.js +1 -0
- package/dist/patterns/overlay-surface/overlay-surface.js.map +1 -1
- package/dist/patterns/resize-handle/resize-handle.d.ts +9 -11
- package/dist/patterns/resize-handle/resize-handle.d.ts.map +1 -1
- package/dist/patterns/resize-handle/resize-handle.js +3 -6
- package/dist/patterns/resize-handle/resize-handle.js.map +1 -1
- package/ds-canonical/adapters/claude/agents/canonical-reviewer.md +1 -1
- package/ds-canonical/adapters/claude-root-instructions.md +1 -1
- package/ds-canonical/adapters/claude-settings-base.json +2 -5
- package/ds-canonical/fork/AGENTS.md +21 -10
- package/ds-canonical/fork/codex/hooks.json +1 -1
- package/ds-canonical/fork/common/instruction.md +21 -10
- package/ds-canonical/fork/consumer/governance-check.mjs +101 -13
- package/ds-canonical/fork/consumer/lock.json +14 -15
- package/ds-canonical/fork/consumer/managed-files/46f10bc55cdfdf834d0749eebff42ea0bb8576f361b36d2b6ba1851354c50150.blob +26 -3
- package/ds-canonical/fork/consumer/managed-files/63061e05969667005020166ea2ae7df3c96663f7a928e7dd3eebc1471022df56.blob +61 -5
- package/ds-canonical/fork/consumer/managed-files/93a89f16f6717d1e4e4e27ec20ef916e3355c7aa890ca74cd9b12db30d8a899f.blob +3 -10
- package/ds-canonical/fork/consumer/managed-files/bc44cabad181f766611dab6a8f52d81100afadd50ac59799015e8ba7bf46d9eb.blob +3 -2
- package/ds-canonical/fork/governance.lock +17 -33
- package/ds-canonical/fork/hooks/check_consumer_code_quality.sh +33 -0
- package/ds-canonical/fork/hooks/check_pattern_invariants.sh +39 -0
- package/ds-canonical/fork/hooks/check_sidebar_menu_button_implicit_wrap.sh +6 -4
- package/ds-canonical/fork/launchers/provider-hook-normalization.mjs +5 -11
- package/ds-canonical/fork/launchers/settings-hooks.json +2 -2
- package/ds-canonical/fork/manifest.json +11 -13
- package/ds-canonical/fork/providers/claude/hook-config.json +1 -7
- package/ds-canonical/fork/providers/codex/hook-config.json +1 -1
- package/ds-canonical/fork/references/story-baseline-registry.json +7 -1
- package/ds-canonical/hooks/check_consumer_code_quality.sh +33 -0
- package/ds-canonical/hooks/check_pattern_invariants.sh +39 -0
- package/ds-canonical/hooks/check_sidebar_menu_button_implicit_wrap.sh +6 -4
- package/ds-canonical/hooks/session_start_governance_check.sh +5 -6
- package/ds-canonical/hooks/tests/test_check_consumer_code_quality.sh +23 -1
- package/ds-canonical/hooks/tests/test_check_pattern_invariants.sh +36 -2
- package/ds-canonical/references/audit-coverage-vs-24-checklist.md +1 -1
- package/ds-canonical/references/failure-class-registry.json +151 -144
- package/ds-canonical/references/preflight-gate-baseline.json +16 -12
- package/ds-canonical/references/story-baseline-registry.json +7 -1
- package/ds-canonical/rules/meta-patterns.md +3 -3
- package/ds-canonical/skills/design-system-audit/SKILL.md +1 -1
- package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +1 -1
- package/ds-canonical/templates/dashboard-app.tsx +31 -8
- package/llms-full.txt +6 -1
- package/llms.txt +2 -1
- package/package.json +1 -1
- package/src/components/Accordion/accordion.principles.stories.tsx +16 -26
- package/src/components/Accordion/accordion.stories.tsx +22 -40
- package/src/components/AccountMenu/account-menu.anatomy.stories.tsx +115 -0
- package/src/components/AccountMenu/account-menu.principles.stories.tsx +99 -0
- package/src/components/AccountMenu/account-menu.spec.md +101 -0
- package/src/components/AccountMenu/account-menu.stories.tsx +61 -0
- package/src/components/AccountMenu/account-menu.tsx +170 -0
- package/src/components/AccountMenu/index.ts +5 -0
- package/src/components/AppShell/_demo-helpers.tsx +53 -53
- package/src/components/AppShell/app-shell.spec.md +5 -1
- package/src/components/AppShell/app-shell.tsx +14 -12
- package/src/components/Avatar/avatar.principles.stories.tsx +4 -4
- package/src/components/Avatar/avatar.stories.tsx +20 -5
- package/src/components/Breadcrumb/breadcrumb.spec.md +1 -1
- package/src/components/Button/button.spec.md +1 -1
- package/src/components/Button/button.stories.tsx +21 -9
- package/src/components/Button/button.tsx +5 -4
- package/src/components/Calendar/calendar.anatomy.stories.tsx +19 -17
- package/src/components/Calendar/calendar.principles.stories.tsx +5 -6
- package/src/components/Calendar/calendar.spec.md +25 -29
- package/src/components/Calendar/calendar.stories.tsx +5 -7
- package/src/components/Calendar/calendar.tsx +75 -87
- package/src/components/Carousel/carousel.principles.stories.tsx +5 -1
- package/src/components/Chart/chart.spec.md +1 -1
- package/src/components/Checkbox/checkbox.anatomy.stories.tsx +14 -5
- package/src/components/Chip/chip.spec.md +1 -1
- package/src/components/CircularProgress/circular-progress.anatomy.stories.tsx +7 -6
- package/src/components/CircularProgress/circular-progress.principles.stories.tsx +8 -6
- package/src/components/CircularProgress/circular-progress.stories.tsx +3 -3
- package/src/components/Combobox/combobox.tsx +1 -0
- package/src/components/Command/command.spec.md +1 -0
- package/src/components/Command/command.tsx +4 -1
- package/src/components/DataTable/cell-registry.tsx +3 -7
- package/src/components/DataTable/data-table-filter-group.tsx +44 -27
- package/src/components/DataTable/data-table-filter-labels.ts +100 -0
- package/src/components/DataTable/data-table-filter-panel.tsx +48 -8
- package/src/components/DataTable/data-table-filter-value-picker.tsx +25 -8
- package/src/components/DataTable/data-table.spec.md +18 -1
- package/src/components/DataTable/data-table.stories.tsx +346 -33
- package/src/components/DataTable/data-table.tsx +11 -4
- package/src/components/DataTable/filter-operators.spec.md +2 -2
- package/src/components/DateGrid/date-grid.anatomy.stories.tsx +24 -20
- package/src/components/DateGrid/date-grid.principles.stories.tsx +27 -21
- package/src/components/DateGrid/date-grid.stories.tsx +22 -13
- package/src/components/DatePicker/date-picker.anatomy.stories.tsx +3 -3
- package/src/components/DatePicker/date-picker.spec.md +4 -4
- package/src/components/DatePicker/date-picker.stories.tsx +33 -9
- package/src/components/DatePicker/date-picker.tsx +210 -147
- package/src/components/Dialog/dialog.spec.md +1 -1
- package/src/components/Dialog/dialog.tsx +8 -2
- package/src/components/DropdownMenu/dropdown-menu.anatomy.stories.tsx +1 -1
- package/src/components/DropdownMenu/dropdown-menu.spec.md +5 -0
- package/src/components/DropdownMenu/dropdown-menu.stories.tsx +3 -17
- package/src/components/DropdownMenu/dropdown-menu.tsx +58 -16
- package/src/components/Field/field-context.ts +25 -1
- package/src/components/Field/field-wrapper.tsx +7 -1
- package/src/components/Field/field.spec.md +8 -1
- package/src/components/Field/field.tsx +14 -2
- package/src/components/FieldControlGroup/field-control-group.anatomy.stories.tsx +3 -3
- package/src/components/FieldControlGroup/field-control-group.spec.md +2 -3
- package/src/components/FieldControlGroup/field-control-group.stories.tsx +2 -1
- package/src/components/FieldControlGroup/field-control-group.tsx +6 -9
- package/src/components/FileItem/file-item.spec.md +1 -1
- package/src/components/FileItem/file-item.stories.tsx +1 -1
- package/src/components/FileUpload/file-upload.stories.tsx +32 -0
- package/src/components/FileUpload/file-upload.tsx +1 -1
- package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +1 -1
- package/src/components/FileViewer/file-viewer.spec.md +1 -1
- package/src/components/FileViewer/file-viewer.stories.tsx +7 -0
- package/src/components/FileViewer/file-viewer.tsx +23 -5
- package/src/components/InlineEdit/inline-edit.spec.md +12 -0
- package/src/components/InlineEdit/inline-edit.stories.tsx +30 -19
- package/src/components/InlineEdit/inline-edit.tsx +94 -31
- package/src/components/Input/input.anatomy.stories.tsx +28 -12
- package/src/components/Input/input.principles.stories.tsx +23 -18
- package/src/components/Input/input.stories.tsx +9 -1
- package/src/components/Input/input.tsx +7 -2
- package/src/components/LinkInput/link-input.principles.stories.tsx +7 -7
- package/src/components/LinkInput/link-input.spec.md +1 -1
- package/src/components/LinkInput/link-input.tsx +5 -1
- package/src/components/Menu/menu-item.anatomy.stories.tsx +1 -1
- package/src/components/Menu/menu-item.tsx +9 -2
- package/src/components/NumberInput/number-input.anatomy.stories.tsx +44 -10
- package/src/components/NumberInput/number-input.principles.stories.tsx +20 -14
- package/src/components/NumberInput/number-input.spec.md +1 -1
- package/src/components/NumberInput/number-input.stories.tsx +12 -5
- package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +7 -0
- package/src/components/PeoplePicker/people-picker.spec.md +3 -1
- package/src/components/PeoplePicker/people-picker.tsx +5 -0
- package/src/components/Popover/popover.tsx +7 -2
- package/src/components/ProgressBar/progress-bar.principles.stories.tsx +14 -12
- package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +5 -1
- package/src/components/RadioGroup/radio-group.spec.md +1 -1
- package/src/components/Rating/rating.principles.stories.tsx +2 -2
- package/src/components/ScrollArea/scroll-area.anatomy.stories.tsx +1 -1
- package/src/components/ScrollArea/scroll-area.spec.md +3 -3
- package/src/components/ScrollArea/scroll-area.tsx +5 -4
- package/src/components/Select/select.principles.stories.tsx +4 -3
- package/src/components/Select/select.stories.tsx +7 -6
- package/src/components/Select/select.tsx +61 -29
- package/src/components/SelectMenu/select-menu.spec.md +1 -1
- package/src/components/SelectMenu/select-menu.tsx +4 -1
- package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +19 -8
- package/src/components/SelectionControl/selection-item.stories.tsx +7 -7
- package/src/components/Sheet/sheet.spec.md +1 -1
- package/src/components/Sidebar/sidebar.spec.md +3 -2
- package/src/components/Sidebar/sidebar.stories.tsx +67 -37
- package/src/components/Sidebar/sidebar.tsx +3 -3
- package/src/components/Slider/slider.principles.stories.tsx +9 -9
- package/src/components/Steps/steps.spec.md +1 -0
- package/src/components/Steps/steps.stories.tsx +18 -1
- package/src/components/Switch/switch.anatomy.stories.tsx +11 -11
- package/src/components/Switch/switch.principles.stories.tsx +11 -8
- package/src/components/Tabs/tabs.principles.stories.tsx +24 -0
- package/src/components/Tabs/tabs.spec.md +6 -4
- package/src/components/Tabs/tabs.tsx +11 -0
- package/src/components/Tag/tag.anatomy.stories.tsx +5 -2
- package/src/components/Tag/tag.spec.md +4 -3
- package/src/components/Tag/tag.stories.tsx +19 -0
- package/src/components/Tag/tag.tsx +14 -5
- package/src/components/Textarea/textarea.anatomy.stories.tsx +15 -9
- package/src/components/Textarea/textarea.principles.stories.tsx +21 -5
- package/src/components/Textarea/textarea.spec.md +10 -1
- package/src/components/Textarea/textarea.tsx +38 -5
- package/src/components/TimePicker/time-picker.tsx +11 -5
- package/src/components/Tooltip/tooltip.spec.md +10 -0
- package/src/components/Tooltip/tooltip.tsx +34 -3
- package/src/components/TreeView/tree-view.spec.md +3 -3
- package/src/components/TreeView/tree-view.stories.tsx +68 -9
- package/src/components/TreeView/tree-view.tsx +7 -2
- package/src/index.ts +9 -1
- package/src/patterns/element-anatomy/inline-action.spec.md +12 -8
- package/src/patterns/element-anatomy/item-anatomy.spec.md +8 -1
- package/src/patterns/element-anatomy/item-anatomy.stories.tsx +24 -5
- package/src/patterns/element-anatomy/item-anatomy.tsx +120 -35
- package/src/patterns/element-anatomy/truncated-text.spec.md +13 -2
- package/src/patterns/header-canonical/chrome-header.tsx +14 -5
- package/src/patterns/header-canonical/header-canonical.spec.md +10 -7
- package/src/patterns/header-canonical/header-canonical.stories.tsx +77 -0
- package/src/patterns/horizontal-overflow/horizontal-overflow.stories.tsx +2 -0
- package/src/patterns/overlay-surface/overlay-surface.spec.md +1 -0
- package/src/patterns/overlay-surface/overlay-surface.stories.tsx +17 -1
- package/src/patterns/overlay-surface/overlay-surface.tsx +8 -4
- package/src/patterns/resize-handle/resize-handle.spec.md +11 -13
- package/src/patterns/resize-handle/resize-handle.stories.tsx +1 -3
- package/src/patterns/resize-handle/resize-handle.tsx +13 -18
- package/src/tokens/color/semantic.css +3 -1
- package/src/tokens/layoutSpace/layoutSpace.stories.tsx +1 -1
- package/src/tokens/opacity/opacity.stories.tsx +1 -1
- package/src/tokens/radius/radius.stories.tsx +3 -3
- package/src/tokens/uiSize/uiSize.css +11 -0
- package/src/tokens/uiSize/uiSize.spec.md +1 -0
- package/ds-canonical/commands/gov-status.md +0 -9
- package/ds-canonical/fork/consumer/managed-files/77e06f62670dfee01e9b5e8b0f8dad085ce711d75538c1fb0679d9818acaca82.blob +0 -424
- package/ds-canonical/fork/preamble.md +0 -500
- package/ds-canonical/hooks/check_post_main_ssot_propagate.sh +0 -8
- package/ds-canonical/hooks/tests/test_check_post_main_ssot_propagate.sh +0 -37
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
"schemaVersion": 1,
|
|
4
4
|
"role": "template-consumer",
|
|
5
5
|
"release": {
|
|
6
|
-
"designSystem": "0.1.0-beta.
|
|
7
|
-
"storybookConfig": "0.1.0-beta.
|
|
6
|
+
"designSystem": "0.1.0-beta.99",
|
|
7
|
+
"storybookConfig": "0.1.0-beta.99"
|
|
8
8
|
},
|
|
9
9
|
"upgradeTrust": {
|
|
10
10
|
"schemaVersion": 1,
|
|
@@ -42,23 +42,23 @@
|
|
|
42
42
|
"implementationSha256": "98b74118fb5b410b77ad2994aa9105fa7609c7353822f8c5213cce54d94f0af4"
|
|
43
43
|
},
|
|
44
44
|
"payload": {
|
|
45
|
-
"forkCorpusLockSha256": "
|
|
45
|
+
"forkCorpusLockSha256": "effada4fa83d93980edf3d81888ab17f4e682cd0ea985717ab9fcf09b4155314",
|
|
46
46
|
"discoveryPolicySha256": "fba289aeeb5a3f11139b9589f7ab08b5e8c8799c7bdf8f0ea57ebfeb8e7c9da6",
|
|
47
47
|
"providerMaterializersSha256": "732e85b01a12e7dd19469e26e4427f0e0cfe5117a78fc9f69c2f0f89702f463a",
|
|
48
|
-
"providerLifecycleSha256": "
|
|
48
|
+
"providerLifecycleSha256": "56b2c0bc21a4b1ac229fe450863aafec87178eefd753e6057f4f9d5f094e8e1f",
|
|
49
49
|
"providerInventorySha256": "00adf1c4f6b3367055a9cc3fdfe658660771b4c9931f696e12761a95076ad92c",
|
|
50
50
|
"executionRuntimeSha256": "3fca4ba4094e855412a22308e13f2b5f91dcfeb009512eb8318b3bd1bace8d9a",
|
|
51
|
-
"commonInstructionSha256": "
|
|
51
|
+
"commonInstructionSha256": "3d40f4b5d3ea78f6c9ca5bd18daa531dc758d77df21a5e7ef35a3336cd71f906",
|
|
52
52
|
"providerArtifactDigests": {
|
|
53
53
|
"claude": {
|
|
54
54
|
"instructionSha256": "f56a44c730506258cc7e2581dbdd31bfd1e6d13d60dc8a8ee8bcc398228453fb",
|
|
55
|
-
"hookSha256": "
|
|
55
|
+
"hookSha256": "6398e6b20f6558392bdce1d7123815042047952be473b8fda6d2491aa1648a05",
|
|
56
56
|
"skillsSha256": "163e473a872d5fa11db9ba7df27f9d316a3c20f89d1ea1cbd002e5f9ada92321",
|
|
57
57
|
"treeDigests": {}
|
|
58
58
|
},
|
|
59
59
|
"codex": {
|
|
60
|
-
"instructionSha256": "
|
|
61
|
-
"hookSha256": "
|
|
60
|
+
"instructionSha256": "3d40f4b5d3ea78f6c9ca5bd18daa531dc758d77df21a5e7ef35a3336cd71f906",
|
|
61
|
+
"hookSha256": "697d186cfe0882ee2ce1b02ecc4c3258ab42b125bab6d70c7be868fa271132f7",
|
|
62
62
|
"skillsSha256": "b80eadd9559d29a50bb7c59ca5f431077174135de79081bbc716cdf64b25bee7",
|
|
63
63
|
"treeDigests": {}
|
|
64
64
|
},
|
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
72
|
"mergeSurfaceDigests": {
|
|
73
|
-
"claude": "
|
|
73
|
+
"claude": "6398e6b20f6558392bdce1d7123815042047952be473b8fda6d2491aa1648a05"
|
|
74
74
|
},
|
|
75
|
-
"governanceCheckSha256": "
|
|
75
|
+
"governanceCheckSha256": "363b6af5c1e9c87cc11a53bb9868cb17e591c64f5545a09dc66f66e86f70e66f",
|
|
76
76
|
"utilityRegistrySha256": "310f92cc9aa57880d8f81464ac4191907bda9c9af31847a450497e6a9f97dce3",
|
|
77
77
|
"sharedSkillsSha256": "138d3bec5497e8109c47788c181f7d2ee3c856f5a84b696eb9364b73ba647bf4",
|
|
78
78
|
"sharedSkillCount": 11,
|
|
@@ -90,9 +90,8 @@
|
|
|
90
90
|
".devcontainer/devcontainer.json": "1668412229466b1e5092218606817711c46c5307b7fc7b77abf6fff089b9b4c7",
|
|
91
91
|
".devcontainer/onboard-banner.sh": "fd87b372e48ff079afb0b257c5e5c28fcf58637b2589a508987460a66c2b8b75",
|
|
92
92
|
".devcontainer/post-create.mjs": "6bc05d2597a54e8f6a5a087901e92ccc89acc3d5873d96ad20814f8f539a146b",
|
|
93
|
-
".github/workflows/audit.yml": "
|
|
93
|
+
".github/workflows/audit.yml": "3cb259c8d83d8d378a6d282b0cde0a8884d96c51cf49e655405c3e416e646726",
|
|
94
94
|
".github/workflows/governance-anchor.yml": "3e280e67fd72886b0686a6d296947ee3270b4899e9914c1e3a9c61c951dcc2ee",
|
|
95
|
-
".github/workflows/sync-design-system.yml": "f25e4d348daf1d98a0c8d0d9c1546d6b8340683ba59ed22aeb0f001378000483",
|
|
96
95
|
".npmrc": "79eff2d98653857c11ab6a0354fa62685a72ec214545e7fdfabc450e91b7ba63",
|
|
97
96
|
"governance/consumer-governance.md": "abbded0a31cf3a6fb0de62975b749d10f27ac0adcc9bbf5e95ef410b64073396",
|
|
98
97
|
"governance/provider-cli-toolchain.json": "6bc607cb6ac299b332d35ca871c838b54e367d96775ad0e759c827a0e3ca10cc",
|
|
@@ -110,19 +109,19 @@
|
|
|
110
109
|
"scripts/lib/canonical-path-containment.mjs": "0244e31dc3be5015bed3efd65a5a77086a2e4676e9ac79cd0801c8cde6a74fcd",
|
|
111
110
|
"scripts/lib/closed-tool-execution.mjs": "131255a302f1b403fe95dd6251e180d7f3ce920faf6cbfe90496b52d192d93c3",
|
|
112
111
|
"scripts/lib/consumer-control-plane-policy.mjs": "ea8b11ddc5c964ea742ccba5e6a3bc2f215db5d165afe2cca96192812287750c",
|
|
113
|
-
"scripts/lib/governance-dependency-bootstrap.mjs": "
|
|
112
|
+
"scripts/lib/governance-dependency-bootstrap.mjs": "0b3c22a322174b179a2f499b0c08bbda996f90fac9be29a074bd5b1ae3435ffe",
|
|
114
113
|
"scripts/lib/provider-lifecycle.mjs": "9aabb2c98efc454b8555308a34830e6590b034b10a63f76f788fbd4cf37ce7e7",
|
|
115
114
|
"scripts/lib/verified-exact-npm-runtime.mjs": "50f54769a7a32fdc5b97036410018bed87808c2dbdffc47cc292967e5de3da8f",
|
|
116
115
|
"scripts/lib/workspace-post-create.mjs": "f3ddc6db740d5c4d48b1c6e16c55222325e4d1c16fe6644a455e7b7e5bea0a0d",
|
|
117
116
|
"scripts/lib/worktree-fingerprint.mjs": "70a8bdbceade964d009f6a46c9e57a93bc9fd58c28971ea14ad1b5ffeaaf7250",
|
|
118
117
|
"scripts/lint-ds-internal-imports.mjs": "86edd952fb5c3871896515440693abeb08c1d1da9f887fa073b9ddda1363f572",
|
|
119
118
|
"scripts/product-template-scaffold-lock.mjs": "9134dabf11af7a2445a6a026fc23201e8aba3ef5aeb7da1d2159e92956dd32d2",
|
|
120
|
-
"scripts/refresh-fork-launchers.mjs": "
|
|
119
|
+
"scripts/refresh-fork-launchers.mjs": "763c61964a4a971a664222e5dc0dd54564bdc9430b5a90f56021cca19d48596a",
|
|
121
120
|
"scripts/release-bom-contract.mjs": "75d736f86c7f695dc88a1982d547998d510e8050c4847abe387227b6662b87c2",
|
|
122
121
|
"scripts/schemas/product-template-scaffold-lock.schema.json": "1318af59f12546b3cda059a1d94923d9a969bef4c5a476ebb46e42f8c853d19a",
|
|
123
122
|
"scripts/schemas/release-bom.schema.json": "6969482588a25533dc1896be63c3c9629aced1cbeb745b99822db764682dc4a4",
|
|
124
123
|
"scripts/schemas/upgrade-evidence-receipt.schema.json": "e2da0a86241d8d019545b63e6285d2ca049ce95fe6aed4264149df2108c4ade0",
|
|
125
|
-
"scripts/setup-governance.mjs": "
|
|
124
|
+
"scripts/setup-governance.mjs": "5297a0c6dace974c1233a95825a6ffceef8823373eb4bb96947961f3979e4339",
|
|
126
125
|
"scripts/setup-provider-cli-toolchain.mjs": "b34e11d02a7aa71d001ef8f1a42af4cf97d1b8b82360f5779cb927370f5ee15a",
|
|
127
126
|
"scripts/setup-workspace.mjs": "95dc0fef1f7570efe277a66f7edf4640055ad6abbae0245615eceb9b041560e9",
|
|
128
127
|
"scripts/sync-all.mjs": "938c706cad79a4bd538359c9b74cb9253a4c74b5f1342cbfc1625600425d8bfd",
|
|
@@ -15,6 +15,10 @@ import {
|
|
|
15
15
|
export const GOVERNANCE_DEPENDENCY_REGISTRY = 'https://registry.npmjs.org/'
|
|
16
16
|
export const GOVERNANCE_DEPENDENCY_MINIMUM_NODE_VERSION = '22.13.0'
|
|
17
17
|
export const GOVERNANCE_DEPENDENCY_EXACT_NPM_VERSION = '11.18.0'
|
|
18
|
+
export const GOVERNANCE_CLOSED_PROJECT_NPM_CONFIG_LINES = Object.freeze([
|
|
19
|
+
'legacy-peer-deps=true',
|
|
20
|
+
'ignore-scripts=true',
|
|
21
|
+
])
|
|
18
22
|
export const GOVERNANCE_DEPENDENCY_REQUIRED_EXECUTABLES = Object.freeze(['bash', 'git', 'jq', 'python3'])
|
|
19
23
|
export const GOVERNANCE_DEPENDENCY_NPM_STEPS = Object.freeze([
|
|
20
24
|
Object.freeze(['ci', '--legacy-peer-deps', '--ignore-scripts', `--registry=${GOVERNANCE_DEPENDENCY_REGISTRY}`]),
|
|
@@ -229,25 +233,44 @@ function exactArray(value, expected) {
|
|
|
229
233
|
&& value.every((entry, index) => entry === expected[index])
|
|
230
234
|
}
|
|
231
235
|
|
|
236
|
+
const VERIFIED_BRACE_EXPANSION_AUDIT_PREIMAGES = Object.freeze([
|
|
237
|
+
Object.freeze({
|
|
238
|
+
source: 1124334,
|
|
239
|
+
findingRange: '<=5.0.7',
|
|
240
|
+
advisoryRange: '<=5.0.7',
|
|
241
|
+
}),
|
|
242
|
+
Object.freeze({
|
|
243
|
+
source: 1130591,
|
|
244
|
+
findingRange: '4.0.0 - 5.0.7',
|
|
245
|
+
advisoryRange: '>=4.0.0 <5.0.8',
|
|
246
|
+
}),
|
|
247
|
+
])
|
|
248
|
+
|
|
249
|
+
function matchesVerifiedBraceExpansionAuditPreimage(finding) {
|
|
250
|
+
return VERIFIED_BRACE_EXPANSION_AUDIT_PREIMAGES.some((preimage) => (
|
|
251
|
+
finding.range === preimage.findingRange
|
|
252
|
+
&& finding.via[0]?.source === preimage.source
|
|
253
|
+
&& finding.via[0]?.range === preimage.advisoryRange
|
|
254
|
+
))
|
|
255
|
+
}
|
|
256
|
+
|
|
232
257
|
function assertRemediatedHighFinding(name, finding, installedOverlayReceipt) {
|
|
233
258
|
invariant(finding && typeof finding === 'object' && !Array.isArray(finding), `npm audit high finding is malformed:${name}`)
|
|
234
259
|
invariant(finding.name === name && finding.severity === 'high', `npm audit high finding identity drifted:${name}`)
|
|
235
260
|
if (name === 'brace-expansion') {
|
|
236
261
|
invariant(
|
|
237
262
|
finding.isDirect === false
|
|
238
|
-
&& finding.range === '<=5.0.7'
|
|
239
263
|
&& exactArray(finding.nodes, ['node_modules/npm/node_modules/brace-expansion'])
|
|
240
264
|
&& Array.isArray(finding.effects)
|
|
241
265
|
&& finding.effects.length <= 1
|
|
242
266
|
&& finding.effects.every((effect) => effect === 'minimatch')
|
|
243
267
|
&& Array.isArray(finding.via)
|
|
244
268
|
&& finding.via.length === 1
|
|
245
|
-
&& finding.via[0]?.source === 1124334
|
|
246
269
|
&& finding.via[0]?.name === 'brace-expansion'
|
|
247
270
|
&& finding.via[0]?.dependency === 'brace-expansion'
|
|
248
271
|
&& finding.via[0]?.url === 'https://github.com/advisories/GHSA-mh99-v99m-4gvg'
|
|
249
272
|
&& finding.via[0]?.severity === 'high'
|
|
250
|
-
&& finding
|
|
273
|
+
&& matchesVerifiedBraceExpansionAuditPreimage(finding),
|
|
251
274
|
'npm audit brace-expansion finding differs from the exact remediated bundled preimage',
|
|
252
275
|
)
|
|
253
276
|
return
|
|
@@ -250,10 +250,29 @@ export function mergeProviderHookSettings({ settings, canonicalConfig, policy, l
|
|
|
250
250
|
throw new Error(`${label} ${hooksField} must be an object`)
|
|
251
251
|
}
|
|
252
252
|
const retiredIds = []
|
|
253
|
+
// F6 fail-closed:canonical hook map 必須存在、非空,且每 event 都是非空合形的 group 陣列。
|
|
254
|
+
// 寬鬆 fallback(`|| {}` / `Array.isArray ? : []`)會把「看不懂的另一世代 artifact 形狀」當
|
|
255
|
+
// 「零 hooks」:下方 strip(canonicalCommands / refsLauncher)照跑、append 卻是空 → 靜默清空
|
|
256
|
+
// 治理 hooks(WM 1f71fec 同型事故)。禁止。
|
|
257
|
+
const canonicalHookMap = canonicalConfig[hooksField]
|
|
258
|
+
if (!canonicalHookMap || typeof canonicalHookMap !== 'object' || Array.isArray(canonicalHookMap) || !Object.keys(canonicalHookMap).length) {
|
|
259
|
+
throw new Error(
|
|
260
|
+
`${label}: canonical hook artifact carries no non-empty ${JSON.stringify(hooksField)} map — the installed corpus uses a schema generation this scripts/refresh-fork-launchers.mjs does not understand; `
|
|
261
|
+
+ 'refusing to write (an empty merge would silently strip every governance hook). '
|
|
262
|
+
+ 'Migrate the fork scaffold to the matching generation first (npm run sync-all -- --apply --to <exact-version>).'
|
|
263
|
+
)
|
|
264
|
+
}
|
|
253
265
|
const canonicalCommands = new Set()
|
|
254
|
-
for (const groups of Object.
|
|
255
|
-
|
|
256
|
-
|
|
266
|
+
for (const [event, groups] of Object.entries(canonicalHookMap)) {
|
|
267
|
+
if (!Array.isArray(groups) || !groups.length) throw new Error(`${label} canonical ${hooksField}.${event} must be a non-empty array`)
|
|
268
|
+
for (const group of groups) {
|
|
269
|
+
if (!group || typeof group !== 'object' || Array.isArray(group) || !Array.isArray(group.hooks) || !group.hooks.length) {
|
|
270
|
+
throw new Error(`${label} canonical ${hooksField}.${event} contains an invalid or empty hook group`)
|
|
271
|
+
}
|
|
272
|
+
for (const handler of group.hooks) {
|
|
273
|
+
if (typeof handler?.command !== 'string' || !handler.command) throw new Error(`${label} canonical ${hooksField}.${event} contains a hook without a command`)
|
|
274
|
+
canonicalCommands.add(handler.command)
|
|
275
|
+
}
|
|
257
276
|
}
|
|
258
277
|
}
|
|
259
278
|
const retainedHooks = {}
|
|
@@ -286,9 +305,16 @@ export function mergeProviderHookSettings({ settings, canonicalConfig, policy, l
|
|
|
286
305
|
// the authenticated canonical groups exactly once. This keeps refresh idempotent without turning
|
|
287
306
|
// a provider adapter update into authority over unrelated product automation.
|
|
288
307
|
merged[hooksField] = retainedHooks
|
|
289
|
-
for (const [event, groups] of Object.entries(
|
|
308
|
+
for (const [event, groups] of Object.entries(canonicalHookMap)) {
|
|
290
309
|
merged[hooksField][event] = [...(merged[hooksField][event] || []), ...structuredClone(groups)]
|
|
291
310
|
}
|
|
311
|
+
// Never-empty postcondition(F6 迴歸絆網):merge 結果必含每個 canonical event 的註冊,
|
|
312
|
+
// 否則代表上游 shape 判定失守 → 寧可 throw 也不寫出被清空的 hook surface。
|
|
313
|
+
for (const event of Object.keys(canonicalHookMap)) {
|
|
314
|
+
if (!Array.isArray(merged[hooksField][event]) || !merged[hooksField][event].length) {
|
|
315
|
+
throw new Error(`${label}: merged ${hooksField}.${event} lost its canonical registrations — refusing to write an emptied hook surface`)
|
|
316
|
+
}
|
|
317
|
+
}
|
|
292
318
|
for (const [key, value] of Object.entries(canonicalConfig)) {
|
|
293
319
|
if (key === hooksField || key === 'permissions' || key === 'disableAutoMode') continue
|
|
294
320
|
merged[key] = structuredClone(value)
|
|
@@ -324,7 +350,8 @@ export function mergeProviderHookSettings({ settings, canonicalConfig, policy, l
|
|
|
324
350
|
merged.permissions.deny = nextDeny
|
|
325
351
|
merged.permissions.defaultMode = canonicalPermissions.defaultMode
|
|
326
352
|
merged.permissions.disableBypassPermissionsMode = canonicalPermissions.disableBypassPermissionsMode
|
|
327
|
-
|
|
353
|
+
if (Object.hasOwn(canonicalConfig, 'disableAutoMode')) throw new Error(`${label} canonical permission base carries the retired disableAutoMode flag`)
|
|
354
|
+
delete merged.disableAutoMode
|
|
328
355
|
delete merged.permissions.disableAutoMode
|
|
329
356
|
delete merged.defaultMode
|
|
330
357
|
} else if (policy.baseTemplate.engine === 'static-json-object-v1') {
|
|
@@ -336,7 +363,27 @@ export function mergeProviderHookSettings({ settings, canonicalConfig, policy, l
|
|
|
336
363
|
return { settings: merged, retiredIds: retiredIds.sort() }
|
|
337
364
|
}
|
|
338
365
|
|
|
366
|
+
// ── F6 fail-closed schema generation gate(WM commit 1f71fec 教訓)──
|
|
367
|
+
// 舊代 refresh 對新代 settings-hooks.json 用 `canonical.hooks || {}` 寬鬆 fallback,把「看不懂的
|
|
368
|
+
// 另一世代 schema」當「零 hooks」:strip 舊治理註冊照跑、append 卻是空 → 靜默清空
|
|
369
|
+
// .claude/settings.json hooks = Claude 端治理整條斷線。本 gate 是唯一 generation 判定 SSOT:
|
|
370
|
+
// kind + schemaVersion 必須 exact match 本腳本世代,否則丟含遷移指引的錯誤;絕不寫檔。
|
|
371
|
+
export const SETTINGS_HOOKS_KIND = 'provider-hook-merge-policies'
|
|
372
|
+
export const SETTINGS_HOOKS_SCHEMA_VERSION = 1
|
|
373
|
+
|
|
374
|
+
export function assertSupportedSettingsHooksGeneration(value, label = 'installed launchers/settings-hooks.json') {
|
|
375
|
+
const record = value && typeof value === 'object' && !Array.isArray(value) ? value : {}
|
|
376
|
+
if (record.kind === SETTINGS_HOOKS_KIND && record.schemaVersion === SETTINGS_HOOKS_SCHEMA_VERSION) return
|
|
377
|
+
throw new Error(
|
|
378
|
+
`${label} declares kind=${JSON.stringify(record.kind ?? null)} schemaVersion=${JSON.stringify(record.schemaVersion ?? null)}, `
|
|
379
|
+
+ `but this scripts/refresh-fork-launchers.mjs generation understands exactly ${SETTINGS_HOOKS_KIND}@${SETTINGS_HOOKS_SCHEMA_VERSION}. `
|
|
380
|
+
+ 'Refusing to merge provider hooks; nothing was written. Merging an ununderstood generation is exactly how an older scaffold silently emptied .claude/settings.json hooks. '
|
|
381
|
+
+ 'Migrate this fork scaffold to the generation matching the installed corpus first (npm run sync-all -- --apply --to <exact-version>), then re-run.'
|
|
382
|
+
)
|
|
383
|
+
}
|
|
384
|
+
|
|
339
385
|
export function validateCanonicalSettingsWiring(value, manifest) {
|
|
386
|
+
assertSupportedSettingsHooksGeneration(value)
|
|
340
387
|
exactKeys(value, ['_generated', 'kind', 'schemaVersion', 'sourceDigest', 'surfaces'], 'installed provider hook merge policies')
|
|
341
388
|
if (
|
|
342
389
|
value._generated !== 'build-fork-governance.mjs'
|
|
@@ -2050,6 +2097,15 @@ export function refreshLaunchers(projectDir, opts = {}) {
|
|
|
2050
2097
|
const src = join(candidateForkRoot, 'launchers')
|
|
2051
2098
|
assertSafeTree(projectDir, src, 'installed launcher corpus', { allowMissing: true })
|
|
2052
2099
|
if (!existsSync(join(src, 'settings-hooks.json'))) {
|
|
2100
|
+
// 只有「治理 corpus 整個不在」才是合法 skip(舊 npm / 未安裝)。corpus 在、卻沒有本世代的
|
|
2101
|
+
// settings-hooks.json = 另一世代把 merge policy 搬走了 → fail-closed throw,絕不靜默 skip
|
|
2102
|
+
//(F6 對偶:靜默 skip 讓 fork 永遠停在 stale 接線,治理斷線無人知)。
|
|
2103
|
+
if (existsSync(join(candidateForkRoot, 'manifest.json'))) {
|
|
2104
|
+
throw new Error(
|
|
2105
|
+
'installed fork corpus exists but ships no launchers/settings-hooks.json — the installed release uses a scaffold generation this scripts/refresh-fork-launchers.mjs does not understand; '
|
|
2106
|
+
+ 'migrate the fork scaffold first (npm run sync-all -- --apply --to <exact-version>) instead of refreshing with this script generation.'
|
|
2107
|
+
)
|
|
2108
|
+
}
|
|
2053
2109
|
result.skipped = 'launchers 未 ship(npm 套件版本過舊或治理本體未安裝)'
|
|
2054
2110
|
return result
|
|
2055
2111
|
}
|
|
@@ -11,6 +11,7 @@ permissions:
|
|
|
11
11
|
|
|
12
12
|
jobs:
|
|
13
13
|
audit:
|
|
14
|
+
name: Verify consumer
|
|
14
15
|
runs-on: ubuntu-24.04
|
|
15
16
|
timeout-minutes: 15
|
|
16
17
|
steps:
|
|
@@ -22,8 +23,8 @@ jobs:
|
|
|
22
23
|
node-version: '24.14.0'
|
|
23
24
|
cache: npm
|
|
24
25
|
|
|
25
|
-
- name:
|
|
26
|
-
run: npm
|
|
26
|
+
- name: Install exact locked dependencies
|
|
27
|
+
run: npm ci --ignore-scripts
|
|
27
28
|
|
|
28
29
|
- name: Type-check
|
|
29
30
|
run: npm run typecheck
|
|
@@ -33,11 +34,3 @@ jobs:
|
|
|
33
34
|
|
|
34
35
|
- name: Build all apps
|
|
35
36
|
run: npm run build
|
|
36
|
-
|
|
37
|
-
- name: Install Playwright browsers
|
|
38
|
-
run: npx --no-install playwright install --with-deps chromium
|
|
39
|
-
|
|
40
|
-
- name: A11y audit consumer apps(WCAG 2 A + AA)
|
|
41
|
-
# Phase 5 加 — DS repo 跑 npm run a11y:check on storybook;ds-product-template
|
|
42
|
-
# 跑 audit-consumer-a11y.mjs on apps/*/dist。對等 DS audit 嚴謹度。
|
|
43
|
-
run: npm run audit:a11y
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path'
|
|
28
28
|
import { fileURLToPath } from 'node:url'
|
|
29
29
|
import {
|
|
30
|
+
GOVERNANCE_CLOSED_PROJECT_NPM_CONFIG_LINES,
|
|
30
31
|
GOVERNANCE_DEPENDENCY_EXACT_NPM_VERSION,
|
|
31
32
|
GOVERNANCE_DEPENDENCY_MINIMUM_NODE_VERSION,
|
|
32
33
|
GOVERNANCE_DEPENDENCY_NPM_STEPS,
|
|
@@ -392,7 +393,7 @@ function readRegularJson(path, label) {
|
|
|
392
393
|
}
|
|
393
394
|
|
|
394
395
|
function assertClosedProjectNpmConfig(root) {
|
|
395
|
-
return assertClosedProjectNpmConfigShared(root,
|
|
396
|
+
return assertClosedProjectNpmConfigShared(root, GOVERNANCE_CLOSED_PROJECT_NPM_CONFIG_LINES, { errorPrefix: 'GOV-SETUP-001' })
|
|
396
397
|
}
|
|
397
398
|
|
|
398
399
|
export function assertSupportedSetupPlatform(platform = process.platform) {
|
|
@@ -476,7 +477,7 @@ async function runGovernanceDependencyBootstrap({
|
|
|
476
477
|
runner,
|
|
477
478
|
...(runtimeFactory ? { runtimeFactory } : {}),
|
|
478
479
|
authorityPaths: SETUP_AUTHORITY_PATHS,
|
|
479
|
-
expectedNpmrcLines:
|
|
480
|
+
expectedNpmrcLines: GOVERNANCE_CLOSED_PROJECT_NPM_CONFIG_LINES,
|
|
480
481
|
errorPrefix: 'GOV-SETUP-001',
|
|
481
482
|
validateRoleRepository: assertCommittedSetupSnapshot,
|
|
482
483
|
afterStage({ index }) {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
{
|
|
8
8
|
"schemaVersion": 1,
|
|
9
9
|
"file": "AGENTS.md",
|
|
10
|
-
"sha256": "
|
|
10
|
+
"sha256": "3d40f4b5d3ea78f6c9ca5bd18daa531dc758d77df21a5e7ef35a3336cd71f906",
|
|
11
11
|
"source": "common instruction compatibility alias",
|
|
12
12
|
"classification": null,
|
|
13
13
|
"destination": null
|
|
@@ -255,7 +255,7 @@
|
|
|
255
255
|
{
|
|
256
256
|
"schemaVersion": 1,
|
|
257
257
|
"file": "codex/hooks.json",
|
|
258
|
-
"sha256": "
|
|
258
|
+
"sha256": "697d186cfe0882ee2ce1b02ecc4c3258ab42b125bab6d70c7be868fa271132f7",
|
|
259
259
|
"source": "providers/codex/hook-config.json",
|
|
260
260
|
"classification": null,
|
|
261
261
|
"destination": null
|
|
@@ -271,7 +271,7 @@
|
|
|
271
271
|
{
|
|
272
272
|
"schemaVersion": 1,
|
|
273
273
|
"file": "common/instruction.md",
|
|
274
|
-
"sha256": "
|
|
274
|
+
"sha256": "3d40f4b5d3ea78f6c9ca5bd18daa531dc758d77df21a5e7ef35a3336cd71f906",
|
|
275
275
|
"source": "scripts/fork-role-sources/AGENTS.product.md + AGENTS.md#canonical-decision-authority",
|
|
276
276
|
"classification": null,
|
|
277
277
|
"destination": null
|
|
@@ -279,7 +279,7 @@
|
|
|
279
279
|
{
|
|
280
280
|
"schemaVersion": 1,
|
|
281
281
|
"file": "consumer/governance-check.mjs",
|
|
282
|
-
"sha256": "
|
|
282
|
+
"sha256": "363b6af5c1e9c87cc11a53bb9868cb17e591c64f5545a09dc66f66e86f70e66f",
|
|
283
283
|
"source": "scripts/governance-check.mjs",
|
|
284
284
|
"classification": null,
|
|
285
285
|
"destination": null
|
|
@@ -359,7 +359,7 @@
|
|
|
359
359
|
{
|
|
360
360
|
"schemaVersion": 1,
|
|
361
361
|
"file": "consumer/managed-files/46f10bc55cdfdf834d0749eebff42ea0bb8576f361b36d2b6ba1851354c50150.blob",
|
|
362
|
-
"sha256": "
|
|
362
|
+
"sha256": "0b3c22a322174b179a2f499b0c08bbda996f90fac9be29a074bd5b1ae3435ffe",
|
|
363
363
|
"source": "scripts/lib/governance-dependency-bootstrap.mjs",
|
|
364
364
|
"classification": null,
|
|
365
365
|
"destination": "scripts/lib/governance-dependency-bootstrap.mjs"
|
|
@@ -383,7 +383,7 @@
|
|
|
383
383
|
{
|
|
384
384
|
"schemaVersion": 1,
|
|
385
385
|
"file": "consumer/managed-files/63061e05969667005020166ea2ae7df3c96663f7a928e7dd3eebc1471022df56.blob",
|
|
386
|
-
"sha256": "
|
|
386
|
+
"sha256": "763c61964a4a971a664222e5dc0dd54564bdc9430b5a90f56021cca19d48596a",
|
|
387
387
|
"source": "scripts/refresh-fork-launchers.mjs",
|
|
388
388
|
"classification": null,
|
|
389
389
|
"destination": "scripts/refresh-fork-launchers.mjs"
|
|
@@ -420,14 +420,6 @@
|
|
|
420
420
|
"classification": null,
|
|
421
421
|
"destination": "scripts/lib/provider-lifecycle.mjs"
|
|
422
422
|
},
|
|
423
|
-
{
|
|
424
|
-
"schemaVersion": 1,
|
|
425
|
-
"file": "consumer/managed-files/77e06f62670dfee01e9b5e8b0f8dad085ce711d75538c1fb0679d9818acaca82.blob",
|
|
426
|
-
"sha256": "f25e4d348daf1d98a0c8d0d9c1546d6b8340683ba59ed22aeb0f001378000483",
|
|
427
|
-
"source": "template/ds-product-template/.github/workflows/sync-design-system.yml",
|
|
428
|
-
"classification": null,
|
|
429
|
-
"destination": ".github/workflows/sync-design-system.yml"
|
|
430
|
-
},
|
|
431
423
|
{
|
|
432
424
|
"schemaVersion": 1,
|
|
433
425
|
"file": "consumer/managed-files/7937321877e5c34c27dae36c0d507d21cd42fa3f46a8f11a284b8b4a52b6faa4.blob",
|
|
@@ -495,7 +487,7 @@
|
|
|
495
487
|
{
|
|
496
488
|
"schemaVersion": 1,
|
|
497
489
|
"file": "consumer/managed-files/93a89f16f6717d1e4e4e27ec20ef916e3355c7aa890ca74cd9b12db30d8a899f.blob",
|
|
498
|
-
"sha256": "
|
|
490
|
+
"sha256": "3cb259c8d83d8d378a6d282b0cde0a8884d96c51cf49e655405c3e416e646726",
|
|
499
491
|
"source": "template/ds-product-template/.github/workflows/audit.yml",
|
|
500
492
|
"classification": null,
|
|
501
493
|
"destination": ".github/workflows/audit.yml"
|
|
@@ -535,7 +527,7 @@
|
|
|
535
527
|
{
|
|
536
528
|
"schemaVersion": 1,
|
|
537
529
|
"file": "consumer/managed-files/bc44cabad181f766611dab6a8f52d81100afadd50ac59799015e8ba7bf46d9eb.blob",
|
|
538
|
-
"sha256": "
|
|
530
|
+
"sha256": "5297a0c6dace974c1233a95825a6ffceef8823373eb4bb96947961f3979e4339",
|
|
539
531
|
"source": "scripts/setup-governance.mjs",
|
|
540
532
|
"classification": null,
|
|
541
533
|
"destination": "scripts/setup-governance.mjs"
|
|
@@ -679,7 +671,7 @@
|
|
|
679
671
|
{
|
|
680
672
|
"schemaVersion": 1,
|
|
681
673
|
"file": "hooks/check_consumer_code_quality.sh",
|
|
682
|
-
"sha256": "
|
|
674
|
+
"sha256": "32b8e4d32426c0915c4afe2ad3d1e9a84a1de59549f4da68743457bebda17bfd",
|
|
683
675
|
"source": "check_consumer_code_quality.sh",
|
|
684
676
|
"classification": "SHIP_REWRITTEN",
|
|
685
677
|
"destination": null
|
|
@@ -751,7 +743,7 @@
|
|
|
751
743
|
{
|
|
752
744
|
"schemaVersion": 1,
|
|
753
745
|
"file": "hooks/check_pattern_invariants.sh",
|
|
754
|
-
"sha256": "
|
|
746
|
+
"sha256": "9618abe020720ccd7e797704d66516fc019579ae32750990642047f994355a7d",
|
|
755
747
|
"source": "check_pattern_invariants.sh",
|
|
756
748
|
"classification": "SHIP_AS_IS",
|
|
757
749
|
"destination": null
|
|
@@ -759,7 +751,7 @@
|
|
|
759
751
|
{
|
|
760
752
|
"schemaVersion": 1,
|
|
761
753
|
"file": "hooks/check_sidebar_menu_button_implicit_wrap.sh",
|
|
762
|
-
"sha256": "
|
|
754
|
+
"sha256": "0f435cfb643dd872c4019045b4351df05cdd62222df2bee9a70a69c6a8cdcbe8",
|
|
763
755
|
"source": "check_sidebar_menu_button_implicit_wrap.sh",
|
|
764
756
|
"classification": "SHIP_AS_IS",
|
|
765
757
|
"destination": null
|
|
@@ -895,7 +887,7 @@
|
|
|
895
887
|
{
|
|
896
888
|
"schemaVersion": 1,
|
|
897
889
|
"file": "launchers/provider-hook-normalization.mjs",
|
|
898
|
-
"sha256": "
|
|
890
|
+
"sha256": "fe7dffbd9e3dd8a2b423765c48ef9200bbd5705870eedcae8a088575d5dd4e1a",
|
|
899
891
|
"source": "packages/governance/src/provider-hook-normalization.mjs",
|
|
900
892
|
"classification": null,
|
|
901
893
|
"destination": null
|
|
@@ -911,7 +903,7 @@
|
|
|
911
903
|
{
|
|
912
904
|
"schemaVersion": 1,
|
|
913
905
|
"file": "launchers/settings-hooks.json",
|
|
914
|
-
"sha256": "
|
|
906
|
+
"sha256": "41e4883c64d7e0676c49e2dc0cbeed2c85ab25e7d3574344d6cd5af4b8e79cfe",
|
|
915
907
|
"source": "packages/design-system/ds-canonical/templates/product-provider-wiring.json + packages/governance/canonical/providers.json",
|
|
916
908
|
"classification": null,
|
|
917
909
|
"destination": null
|
|
@@ -919,23 +911,15 @@
|
|
|
919
911
|
{
|
|
920
912
|
"schemaVersion": 1,
|
|
921
913
|
"file": "manifest.json",
|
|
922
|
-
"sha256": "
|
|
914
|
+
"sha256": "bbbc8e873f6190eca96592b7fa98ead61af0f0359036ef70917ea2c269a2a677",
|
|
923
915
|
"source": null,
|
|
924
916
|
"classification": null,
|
|
925
917
|
"destination": null
|
|
926
918
|
},
|
|
927
|
-
{
|
|
928
|
-
"schemaVersion": 1,
|
|
929
|
-
"file": "preamble.md",
|
|
930
|
-
"sha256": "70f3402061f420c9026d5cd69ac3f070fd3457cb8ad506685372fcda1b2be1fb",
|
|
931
|
-
"source": "control-plane-genesis-am-only-v1:25b39558cbf352f053948190bb28326a78562f43:packages/design-system/ds-canonical/fork/preamble.md",
|
|
932
|
-
"classification": null,
|
|
933
|
-
"destination": null
|
|
934
|
-
},
|
|
935
919
|
{
|
|
936
920
|
"schemaVersion": 1,
|
|
937
921
|
"file": "providers/claude/hook-config.json",
|
|
938
|
-
"sha256": "
|
|
922
|
+
"sha256": "6398e6b20f6558392bdce1d7123815042047952be473b8fda6d2491aa1648a05",
|
|
939
923
|
"source": "packages/design-system/ds-canonical/templates/product-provider-wiring.json + providers.json:claude",
|
|
940
924
|
"classification": null,
|
|
941
925
|
"destination": null
|
|
@@ -1183,7 +1167,7 @@
|
|
|
1183
1167
|
{
|
|
1184
1168
|
"schemaVersion": 1,
|
|
1185
1169
|
"file": "providers/codex/hook-config.json",
|
|
1186
|
-
"sha256": "
|
|
1170
|
+
"sha256": "697d186cfe0882ee2ce1b02ecc4c3258ab42b125bab6d70c7be868fa271132f7",
|
|
1187
1171
|
"source": "packages/design-system/ds-canonical/templates/product-provider-wiring.json + providers.json:codex",
|
|
1188
1172
|
"classification": null,
|
|
1189
1173
|
"destination": null
|
|
@@ -1423,7 +1407,7 @@
|
|
|
1423
1407
|
{
|
|
1424
1408
|
"schemaVersion": 1,
|
|
1425
1409
|
"file": "references/story-baseline-registry.json",
|
|
1426
|
-
"sha256": "
|
|
1410
|
+
"sha256": "cac3bbf5adff25302e78ac689c48204986c43ce41eb56161ccee1e14557ba56d",
|
|
1427
1411
|
"source": "packages/design-system/ds-canonical/references/story-baseline-registry.json",
|
|
1428
1412
|
"classification": null,
|
|
1429
1413
|
"destination": null
|
|
@@ -133,6 +133,39 @@ if grep -Eq 'layout="primary-header"|layout=\{('\''|")primary-header('\''|")\}'
|
|
|
133
133
|
if [ -n "$PRIMARY" ] && ! has_rationale '@app-shell-primary-header-allow'; then VIOLATIONS="${VIOLATIONS}${PRIMARY}"; fi
|
|
134
134
|
fi
|
|
135
135
|
|
|
136
|
+
# 帳號入口 duplicate(2026-07-30 WM F9 layer 3;app-shell.spec.md「帳號入口放置 SSOT」:帳號入口只能出現一次)。
|
|
137
|
+
# 上段攔「宣告 primary-header + SidebarFooter」;本段補 mode 字面不在檔內的 dual-entry 缺口(WM 錨例 =
|
|
138
|
+
# apps/work/src/App.tsx pre-fix 1a26bd1^:SidebarHeader 右上 avatar 帳號選單與 SidebarFooter user 區並存):
|
|
139
|
+
# header 帳號簽名 = SidebarHeader block 內 <AccountMenu> OR(<DropdownMenuTrigger> + <Avatar>/<ItemAvatar>
|
|
140
|
+
# + account/logout 語彙);footer user 簽名 = SidebarFooter block 內 <Avatar>/<ItemAvatar>/<AccountMenu>。
|
|
141
|
+
# 零誤判 bound(M23 R9 零誤判簽名 precedent;DS apps/template/src + WM 全 corpus 實測 0 hit、錨例 fire):
|
|
142
|
+
# - workspace switcher in header(trigger+avatar、無 account/logout 語彙)不中 — 語彙 conjunction;
|
|
143
|
+
# - mobile Sheet 鏡像(header AccountMenu、footer 無 user 區,app-shell.spec.md Responsive 子句)不中;
|
|
144
|
+
# - 多 mode demo 檔(primary-header + primary-sidebar 字面並存)skip → 跨 story 誤攔防護,歸 product-ui-audit;
|
|
145
|
+
# - BODY 已 strip 註解(WM 修復檔 SidebarHeader 註解即含「帳號入口」字樣);local 同名元件不中和 —
|
|
146
|
+
# duplicate 語義違規與 primitive 來源無關。
|
|
147
|
+
ACCOUNT_DUP=$(printf '%s' "$BODY" | python3 -c '
|
|
148
|
+
import re, sys
|
|
149
|
+
content = sys.stdin.read()
|
|
150
|
+
account = re.compile(r"[Aa]ccount|[Ll]og\s?-?[Oo]ut|LogOut|[Ss]ign\s?-?[Oo]ut|SignOut|登出|個人資料|帳號")
|
|
151
|
+
headers = re.findall(r"<SidebarHeader\b[^>]*>.*?</SidebarHeader>", content, re.DOTALL)
|
|
152
|
+
footers = re.findall(r"<SidebarFooter\b[^>]*>.*?</SidebarFooter>", content, re.DOTALL)
|
|
153
|
+
header_account = any(
|
|
154
|
+
re.search(r"<AccountMenu\b", b)
|
|
155
|
+
or (re.search(r"<DropdownMenuTrigger\b", b)
|
|
156
|
+
and re.search(r"<(Avatar|ItemAvatar)\b", b)
|
|
157
|
+
and account.search(b))
|
|
158
|
+
for b in headers)
|
|
159
|
+
footer_user = any(re.search(r"<(Avatar|ItemAvatar|AccountMenu)\b", b) for b in footers)
|
|
160
|
+
multi_mode = ("primary-header" in content) and ("primary-sidebar" in content)
|
|
161
|
+
if header_account and footer_user and not multi_mode:
|
|
162
|
+
print("DUP")
|
|
163
|
+
' 2>/dev/null) \
|
|
164
|
+
|| governance_hook_integrity_fail 'consumer quality account-entry scanner failed'
|
|
165
|
+
if [ "$ACCOUNT_DUP" = "DUP" ] && ! has_rationale '@account-entry-allow'; then
|
|
166
|
+
add_violation 'duplicate account entry: SidebarHeader account menu + SidebarFooter user area coexist; app-shell.spec.md 帳號入口只能出現一次(primary-sidebar → SidebarFooter / primary-header → globalHeader 右);escape @account-entry-allow: <rationale>'
|
|
167
|
+
fi
|
|
168
|
+
|
|
136
169
|
if [ -n "$VIOLATIONS" ]; then
|
|
137
170
|
printf 'GOV-CONSUMER-QUALITY-001:%b\nFile:%s\n' "$VIOLATIONS" "$FILE_PATH" >&2
|
|
138
171
|
exit 2
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
# C.2 inline-action canonical gap(原 check_inline_action_canonical_gap,P1 WARN context)
|
|
7
7
|
# C.3 primitive wrapper padding(原 check_primitive_wrapper_padding,P0 BLOCK exit 2)
|
|
8
8
|
# C.4 row slot handcraft(原 check_row_slot_handcraft,P0 BLOCK exit 2)
|
|
9
|
+
# C.5 弱化 icon hover 階梯(2026-07-30 user 拍板,P0 BLOCK exit 2)
|
|
9
10
|
#
|
|
10
11
|
# Why merge:皆 element-anatomy / overlay-surface SSOT 消費紀律 invariant,共用 INPUT
|
|
11
12
|
# parsing + tsx filter,散裝是 M17 + Anthropic ≤ 15 hook best-practice 偏離。
|
|
@@ -17,6 +18,7 @@
|
|
|
17
18
|
# C.2: `// @inline-action-gap-allow: <reason>`(any line)
|
|
18
19
|
# C.3: `// @primitive-padding-allow: <reason>`(檔案前 5 行)
|
|
19
20
|
# C.4: `// @row-slot-handcraft-allow: <reason>`(any line)
|
|
21
|
+
# C.5: `// @hover-ramp-allow: <reason>`(any line)
|
|
20
22
|
|
|
21
23
|
source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
|
|
22
24
|
|
|
@@ -174,6 +176,43 @@ EOF
|
|
|
174
176
|
;;
|
|
175
177
|
esac
|
|
176
178
|
|
|
179
|
+
|
|
180
|
+
# ── C.5 弱化 icon hover 階梯(P0 BLOCK exit 2;2026-07-30 user 拍板)─────────────
|
|
181
|
+
# Root invariant:hover 往前一階,不跳階。rest \`text-fg-muted\`(neutral-7)的弱化 icon
|
|
182
|
+
# hover 必 \`text-fg-secondary\`(neutral-8),不得直接跳 \`text-foreground\`(neutral-9)。
|
|
183
|
+
# rule owner = inline-action.spec.md「Icon 色彩」段 + tokens/color/semantic.css:53。
|
|
184
|
+
# 世界級:Fluent 2 neutralForeground3Hover === neutralForeground2 / MUI Chip deleteIcon .26→.4。
|
|
185
|
+
# 錨例:2026-04-08 97e62a80 為修「colored Tag 上 fg-muted 不連貫」而 unified 全 variant 繼承文字色,
|
|
186
|
+
# 連中性宿主一起改且未經 user 拍板;primitive 本身也一直跳兩階,四個月無機械防線。
|
|
187
|
+
# rest 已是 fg-secondary 的整列/文字 hover(→ foreground)本身就是一階,不在射程內。
|
|
188
|
+
case "$FILE_PATH" in
|
|
189
|
+
*components/*.tsx|*patterns/*.tsx|*.css)
|
|
190
|
+
if ! grep -q '@hover-ramp-allow' <<<"$NEW_CONTENT"; then
|
|
191
|
+
SKIP_RAMP=$(grep -m 3 -nE 'text-fg-muted[^"'"'"'\`]*hover:text-foreground|hover:text-foreground[^"'"'"'\`]*text-fg-muted' <<<"$NEW_CONTENT" || true)
|
|
192
|
+
if [ -n "$SKIP_RAMP" ]; then
|
|
193
|
+
cat >&2 <<EOF
|
|
194
|
+
|
|
195
|
+
┄┄┄ C.5 check_pattern_invariants — 弱化 icon hover 跳階 BLOCK ┄┄┄
|
|
196
|
+
|
|
197
|
+
[P0] ${FILE_PATH}
|
|
198
|
+
rest \`text-fg-muted\` 的弱化 icon 直接 hover 到 \`text-foreground\`(跳兩階):
|
|
199
|
+
${SKIP_RAMP}
|
|
200
|
+
|
|
201
|
+
❌ inline-action.spec.md「Icon 色彩」+ tokens/color/semantic.css:53:
|
|
202
|
+
弱化 icon hover 後變 \`fg-secondary\`(neutral-8),不是 \`foreground\`(neutral-9)。
|
|
203
|
+
世界級對照:Fluent 2 neutralForeground3Hover = neutralForeground2 / MUI Chip deleteIcon .26→.4。
|
|
204
|
+
|
|
205
|
+
修法:\`hover:text-foreground\` → \`hover:text-fg-secondary\`(active 同步);
|
|
206
|
+
優先直接消費 \`ItemInlineActionButton\`(primitive 已內建正確階梯)而非手刻。
|
|
207
|
+
真有理由跳階 → 加 \`// @hover-ramp-allow: <rationale>\` 行豁免。
|
|
208
|
+
|
|
209
|
+
EOF
|
|
210
|
+
exit 2
|
|
211
|
+
fi
|
|
212
|
+
fi
|
|
213
|
+
;;
|
|
214
|
+
esac
|
|
215
|
+
|
|
177
216
|
# ── C.3 primitive wrapper padding(P0 BLOCK exit 2)───────────────────────────
|
|
178
217
|
# File-level allowlist:檔頭前 5 行
|
|
179
218
|
ALLOW_C3=0
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
# SidebarMenuButton(sidebar.tsx L1036-1043)在沒 asChild 時把所有 children 塞進 <ItemLabel> 單一 span,
|
|
6
6
|
# Avatar + text-span 都在同 span 內 → 強迫垂直堆疊。
|
|
7
7
|
#
|
|
8
|
-
# Canonical:含 Avatar/ItemAvatar/icon prefix 的 SidebarMenuButton 必用 asChild +
|
|
8
|
+
# Canonical:含 Avatar/ItemAvatar/icon prefix 的 SidebarMenuButton 必用 asChild + 單一 wrapper
|
|
9
|
+
# (互動觸發行 <button type="button">,如 UserFooter 帳號選單;純展示 row <div role="group">),
|
|
9
10
|
# per sidebar.tsx:1025-1027 docblock:「asChild 的 consumer 自行放 icon + label」+ DS canonical
|
|
10
|
-
# sidebar.stories.tsx#UserFooter
|
|
11
|
+
# sidebar.stories.tsx#UserFooter 範例。
|
|
11
12
|
#
|
|
12
13
|
# Detection:
|
|
13
14
|
# `<SidebarMenuButton ...>` (no asChild) ... `<ItemAvatar` or `<Avatar` inside → BLOCKER
|
|
@@ -81,7 +82,8 @@ cat >&2 <<'EOF'
|
|
|
81
82
|
|
|
82
83
|
❌ SidebarMenuButton id="..." 直接放 ItemAvatar + span 為 children
|
|
83
84
|
|
|
84
|
-
✅ SidebarMenuButton asChild
|
|
85
|
+
✅ SidebarMenuButton asChild 包單一 wrapper 內含 ItemAvatar + span data-sidebar="menu-label" min-w-0 flex-1 truncate
|
|
86
|
+
(wrapper:互動觸發行用 <button type="button">,如 UserFooter 帳號選單;純展示 row 用 <div role="group">)
|
|
85
87
|
|
|
86
88
|
Or use startIcon prop(自動 layout,不 wrap):
|
|
87
89
|
✅ SidebarMenuButton startIcon={SomeLucideIcon} 直接 children 為純文字
|
|
@@ -90,7 +92,7 @@ Bypass(極罕見):GOVERNANCE_BYPASS_SIDEBAR_MENU_BUTTON_WRAP=1 env var(audit-log
|
|
|
90
92
|
|
|
91
93
|
Citation:
|
|
92
94
|
- packages/design-system/src/components/Sidebar/sidebar.tsx:1025-1043(asChild docblock)
|
|
93
|
-
- packages/design-system/src/components/Sidebar/sidebar.stories.tsx UserFooter
|
|
95
|
+
- packages/design-system/src/components/Sidebar/sidebar.stories.tsx UserFooter(canonical;帳號選單觸發行)
|
|
94
96
|
EOF
|
|
95
97
|
# 2026-05-31:exit 0 → exit 2(folded-hook-audit:原宣稱 BLOCKER 但 exit 0 = 假 enforcement;
|
|
96
98
|
# SidebarMenuButton implicit-wrap 是 SSOT canonical,verified clean on 現有 sidebar code + 有 env escape)。
|
|
@@ -1380,17 +1380,11 @@ export function normalizeProviderHookInput({
|
|
|
1380
1380
|
const selectedWriteTransports = matchingWriteTransports(provider, input)
|
|
1381
1381
|
const shouldParseMutation = selectedWriteTransports.matches.length > 0
|
|
1382
1382
|
&& (
|
|
1383
|
-
|
|
1384
|
-
|| (
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|| postEventCarriesDeclaredTransport(input, selectedWriteTransports.matches[0], {
|
|
1389
|
-
limits,
|
|
1390
|
-
checkpoint,
|
|
1391
|
-
})
|
|
1392
|
-
)
|
|
1393
|
-
)
|
|
1383
|
+
selectedWriteTransports.matches.length !== 1
|
|
1384
|
+
|| postEventCarriesDeclaredTransport(input, selectedWriteTransports.matches[0], {
|
|
1385
|
+
limits,
|
|
1386
|
+
checkpoint,
|
|
1387
|
+
})
|
|
1394
1388
|
)
|
|
1395
1389
|
if (shouldParseMutation) {
|
|
1396
1390
|
try {
|