@once-ui-system/core 1.7.12 → 1.8.0
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/AGENTS.md +53 -0
- package/README.md +27 -0
- package/agent/once-ui-codegen.mdc +27 -0
- package/ai/catalog.json +195 -634
- package/ai/components/Banner.json +2 -2
- package/ai/components/BlobFx.json +2 -2
- package/ai/components/Carousel.json +1 -0
- package/ai/components/ChartHeader.json +2 -2
- package/ai/components/Checkbox.json +2 -1
- package/ai/components/CompareImage.json +2 -1
- package/ai/components/ContextMenu.json +2 -2
- package/ai/components/Dialog.json +2 -0
- package/ai/components/HoverCard.json +2 -2
- package/ai/components/InfiniteScroll.json +2 -2
- package/ai/components/OgCard.json +3 -2
- package/ai/components/RadioButton.json +2 -1
- package/ai/components/ScrollContainer.json +2 -2
- package/ai/components/SegmentedControl.json +2 -2
- package/ai/components/Select.json +1 -1
- package/ai/components/SplitView.json +2 -2
- package/ai/components/Swiper.json +1 -0
- package/ai/components/Table.json +17 -2
- package/ai/components/ThemeSwitcher.json +2 -2
- package/ai/components/Tooltip.json +2 -2
- package/ai/examples/blocks/content/chat1content.ts +2 -0
- package/ai/examples/dashboard.tsx +1 -1
- package/ai/examples/settings.tsx +32 -28
- package/ai/manifest.json +2 -2
- package/ai/spec.json +64 -68
- package/dist/AGENTS.md +53 -0
- package/dist/README.md +27 -0
- package/dist/agent/once-ui-codegen.mdc +27 -0
- package/dist/ai/catalog.json +195 -634
- package/dist/ai/components/Banner.json +2 -2
- package/dist/ai/components/BlobFx.json +2 -2
- package/dist/ai/components/Carousel.json +1 -0
- package/dist/ai/components/ChartHeader.json +2 -2
- package/dist/ai/components/Checkbox.json +2 -1
- package/dist/ai/components/CompareImage.json +2 -1
- package/dist/ai/components/ContextMenu.json +2 -2
- package/dist/ai/components/Dialog.json +2 -0
- package/dist/ai/components/HoverCard.json +2 -2
- package/dist/ai/components/InfiniteScroll.json +2 -2
- package/dist/ai/components/OgCard.json +3 -2
- package/dist/ai/components/RadioButton.json +2 -1
- package/dist/ai/components/ScrollContainer.json +2 -2
- package/dist/ai/components/SegmentedControl.json +2 -2
- package/dist/ai/components/Select.json +1 -1
- package/dist/ai/components/SplitView.json +2 -2
- package/dist/ai/components/Swiper.json +1 -0
- package/dist/ai/components/Table.json +17 -2
- package/dist/ai/components/ThemeSwitcher.json +2 -2
- package/dist/ai/components/Tooltip.json +2 -2
- package/dist/ai/manifest.json +2 -2
- package/dist/ai/spec.json +64 -68
- package/dist/components/Accordion.js +1 -1
- package/dist/components/Accordion.js.map +1 -1
- package/dist/components/AccordionGroup.d.ts +1 -1
- package/dist/components/AccordionGroup.d.ts.map +1 -1
- package/dist/components/AccordionGroup.js +3 -3
- package/dist/components/AccordionGroup.js.map +1 -1
- package/dist/components/Animation.d.ts +1 -1
- package/dist/components/Animation.d.ts.map +1 -1
- package/dist/components/Arrow.d.ts +1 -1
- package/dist/components/Arrow.d.ts.map +1 -1
- package/dist/components/Arrow.js +4 -4
- package/dist/components/Arrow.js.map +1 -1
- package/dist/components/ArrowNavigationContext.d.ts +2 -1
- package/dist/components/ArrowNavigationContext.d.ts.map +1 -1
- package/dist/components/ArrowNavigationContext.js +5 -3
- package/dist/components/ArrowNavigationContext.js.map +1 -1
- package/dist/components/Avatar.d.ts +2 -2
- package/dist/components/Avatar.d.ts.map +1 -1
- package/dist/components/AvatarGroup.js +1 -1
- package/dist/components/AvatarGroup.js.map +1 -1
- package/dist/components/Background.js +1 -1
- package/dist/components/Background.js.map +1 -1
- package/dist/components/Badge.js +1 -1
- package/dist/components/Badge.js.map +1 -1
- package/dist/components/Banner.d.ts.map +1 -1
- package/dist/components/Banner.js +1 -0
- package/dist/components/Banner.js.map +1 -1
- package/dist/components/BlobFx.d.ts +1 -1
- package/dist/components/BlobFx.d.ts.map +1 -1
- package/dist/components/BlobFx.js +3 -2
- package/dist/components/BlobFx.js.map +1 -1
- package/dist/components/Button.js +1 -1
- package/dist/components/Button.js.map +1 -1
- package/dist/components/Card.js +1 -1
- package/dist/components/Card.js.map +1 -1
- package/dist/components/Carousel.d.ts +3 -2
- package/dist/components/Carousel.d.ts.map +1 -1
- package/dist/components/Carousel.js +5 -5
- package/dist/components/Carousel.js.map +1 -1
- package/dist/components/Checkbox.d.ts +1 -0
- package/dist/components/Checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox.js +5 -5
- package/dist/components/Checkbox.js.map +1 -1
- package/dist/components/Chip.js +1 -1
- package/dist/components/Chip.js.map +1 -1
- package/dist/components/ClientFlex.d.ts.map +1 -1
- package/dist/components/ClientFlex.js +124 -5
- package/dist/components/ClientFlex.js.map +1 -1
- package/dist/components/CompareImage.d.ts +2 -1
- package/dist/components/CompareImage.d.ts.map +1 -1
- package/dist/components/CompareImage.js +4 -4
- package/dist/components/CompareImage.js.map +1 -1
- package/dist/components/ContextMenu.d.ts +2 -2
- package/dist/components/ContextMenu.d.ts.map +1 -1
- package/dist/components/ContextMenu.js +3 -3
- package/dist/components/ContextMenu.js.map +1 -1
- package/dist/components/CountFx.d.ts +1 -1
- package/dist/components/CountFx.d.ts.map +1 -1
- package/dist/components/CountFx.js +6 -6
- package/dist/components/CountFx.js.map +1 -1
- package/dist/components/CountdownFx.d.ts +1 -1
- package/dist/components/CountdownFx.d.ts.map +1 -1
- package/dist/components/CountdownFx.js +4 -4
- package/dist/components/CountdownFx.js.map +1 -1
- package/dist/components/Cursor.d.ts +1 -1
- package/dist/components/Cursor.d.ts.map +1 -1
- package/dist/components/Cursor.js +6 -6
- package/dist/components/Cursor.js.map +1 -1
- package/dist/components/DateInput.d.ts +1 -1
- package/dist/components/DateInput.d.ts.map +1 -1
- package/dist/components/DateInput.js +6 -5
- package/dist/components/DateInput.js.map +1 -1
- package/dist/components/DatePicker.d.ts.map +1 -1
- package/dist/components/DatePicker.js +5 -5
- package/dist/components/DatePicker.js.map +1 -1
- package/dist/components/DateRangeInput.d.ts +2 -2
- package/dist/components/DateRangeInput.d.ts.map +1 -1
- package/dist/components/DateRangeInput.js +6 -4
- package/dist/components/DateRangeInput.js.map +1 -1
- package/dist/components/DateRangePicker.d.ts +1 -1
- package/dist/components/DateRangePicker.d.ts.map +1 -1
- package/dist/components/DateRangePicker.js +3 -3
- package/dist/components/DateRangePicker.js.map +1 -1
- package/dist/components/Dialog.d.ts +2 -0
- package/dist/components/Dialog.d.ts.map +1 -1
- package/dist/components/Dialog.js +32 -15
- package/dist/components/Dialog.js.map +1 -1
- package/dist/components/Dropdown.d.ts.map +1 -1
- package/dist/components/Dropdown.js +1 -1
- package/dist/components/Dropdown.js.map +1 -1
- package/dist/components/DropdownWrapper.d.ts.map +1 -1
- package/dist/components/DropdownWrapper.js +14 -11
- package/dist/components/DropdownWrapper.js.map +1 -1
- package/dist/components/ElementType.d.ts +1 -1
- package/dist/components/ElementType.d.ts.map +1 -1
- package/dist/components/ElementType.js +6 -4
- package/dist/components/ElementType.js.map +1 -1
- package/dist/components/EmojiPickerDropdown.d.ts +1 -1
- package/dist/components/EmojiPickerDropdown.d.ts.map +1 -1
- package/dist/components/EmojiPickerDropdown.js +4 -2
- package/dist/components/EmojiPickerDropdown.js.map +1 -1
- package/dist/components/Fade.js +1 -1
- package/dist/components/Fade.js.map +1 -1
- package/dist/components/FlipFx.d.ts.map +1 -1
- package/dist/components/FlipFx.js +2 -4
- package/dist/components/FlipFx.js.map +1 -1
- package/dist/components/FocusTrap.d.ts +1 -1
- package/dist/components/FocusTrap.d.ts.map +1 -1
- package/dist/components/FocusTrap.js +3 -3
- package/dist/components/FocusTrap.js.map +1 -1
- package/dist/components/GlitchFx.js +1 -1
- package/dist/components/GlitchFx.js.map +1 -1
- package/dist/components/Heading.js +1 -1
- package/dist/components/Heading.js.map +1 -1
- package/dist/components/HoloFx.d.ts +1 -1
- package/dist/components/HoloFx.d.ts.map +1 -1
- package/dist/components/HoloFx.js +17 -8
- package/dist/components/HoloFx.js.map +1 -1
- package/dist/components/Icon.js +1 -1
- package/dist/components/Icon.js.map +1 -1
- package/dist/components/IconButton.js +1 -1
- package/dist/components/IconButton.js.map +1 -1
- package/dist/components/InlineCode.js +1 -1
- package/dist/components/InlineCode.js.map +1 -1
- package/dist/components/Input.js +1 -1
- package/dist/components/Input.js.map +1 -1
- package/dist/components/LetterFx.js +1 -1
- package/dist/components/LetterFx.js.map +1 -1
- package/dist/components/ListItem.js +1 -1
- package/dist/components/ListItem.js.map +1 -1
- package/dist/components/Logo.d.ts +1 -1
- package/dist/components/Logo.d.ts.map +1 -1
- package/dist/components/Logo.js +6 -10
- package/dist/components/Logo.js.map +1 -1
- package/dist/components/LogoCloud.js +1 -1
- package/dist/components/LogoCloud.js.map +1 -1
- package/dist/components/Mask.js +1 -1
- package/dist/components/Mask.js.map +1 -1
- package/dist/components/MasonryGrid.js +1 -1
- package/dist/components/MasonryGrid.js.map +1 -1
- package/dist/components/Media.d.ts +1 -1
- package/dist/components/Media.d.ts.map +1 -1
- package/dist/components/Media.js +10 -7
- package/dist/components/Media.js.map +1 -1
- package/dist/components/MediaVideoPlayer.d.ts +12 -0
- package/dist/components/MediaVideoPlayer.d.ts.map +1 -0
- package/dist/components/MediaVideoPlayer.js +246 -0
- package/dist/components/MediaVideoPlayer.js.map +1 -0
- package/dist/components/MediaVideoPlayer.module.scss +90 -0
- package/dist/components/Modal.d.ts +1 -1
- package/dist/components/Modal.d.ts.map +1 -1
- package/dist/components/Modal.js +3 -3
- package/dist/components/Modal.js.map +1 -1
- package/dist/components/NavIcon.js +1 -1
- package/dist/components/NavIcon.js.map +1 -1
- package/dist/components/NumberInput.js +1 -1
- package/dist/components/NumberInput.js.map +1 -1
- package/dist/components/OgCard.d.ts +3 -2
- package/dist/components/OgCard.d.ts.map +1 -1
- package/dist/components/OgCard.js +2 -2
- package/dist/components/OgCard.js.map +1 -1
- package/dist/components/Option.js +1 -1
- package/dist/components/Option.js.map +1 -1
- package/dist/components/ProgressBar.d.ts +1 -1
- package/dist/components/ProgressBar.d.ts.map +1 -1
- package/dist/components/ProgressBar.js +1 -1
- package/dist/components/ProgressBar.js.map +1 -1
- package/dist/components/RadioButton.d.ts +1 -0
- package/dist/components/RadioButton.d.ts.map +1 -1
- package/dist/components/RadioButton.js +6 -6
- package/dist/components/RadioButton.js.map +1 -1
- package/dist/components/ScrollContainer.d.ts +1 -1
- package/dist/components/ScrollContainer.d.ts.map +1 -1
- package/dist/components/ScrollContainer.js +3 -3
- package/dist/components/ScrollContainer.js.map +1 -1
- package/dist/components/ScrollLock.d.ts +6 -1
- package/dist/components/ScrollLock.d.ts.map +1 -1
- package/dist/components/ScrollLock.js +39 -13
- package/dist/components/ScrollLock.js.map +1 -1
- package/dist/components/ScrollToTop.d.ts +4 -1
- package/dist/components/ScrollToTop.d.ts.map +1 -1
- package/dist/components/ScrollToTop.js +2 -1
- package/dist/components/ScrollToTop.js.map +1 -1
- package/dist/components/Scroller.d.ts +2 -2
- package/dist/components/Scroller.d.ts.map +1 -1
- package/dist/components/Scroller.js +4 -4
- package/dist/components/Scroller.js.map +1 -1
- package/dist/components/SegmentedControl.d.ts +1 -1
- package/dist/components/SegmentedControl.d.ts.map +1 -1
- package/dist/components/SegmentedControl.js +3 -3
- package/dist/components/SegmentedControl.js.map +1 -1
- package/dist/components/Select.d.ts +1 -1
- package/dist/components/Select.d.ts.map +1 -1
- package/dist/components/Select.js +1 -1
- package/dist/components/Select.js.map +1 -1
- package/dist/components/ServerFlex.d.ts.map +1 -1
- package/dist/components/ServerFlex.js +4 -2
- package/dist/components/ServerFlex.js.map +1 -1
- package/dist/components/ServerGrid.js +1 -1
- package/dist/components/ServerGrid.js.map +1 -1
- package/dist/components/SharedInteractiveStyles.module.scss +4 -0
- package/dist/components/ShineFx.d.ts +1 -1
- package/dist/components/ShineFx.d.ts.map +1 -1
- package/dist/components/ShineFx.js +4 -3
- package/dist/components/ShineFx.js.map +1 -1
- package/dist/components/Skeleton.js +1 -1
- package/dist/components/Skeleton.js.map +1 -1
- package/dist/components/Slider.js +1 -1
- package/dist/components/Slider.js.map +1 -1
- package/dist/components/Slider.module.scss +2 -2
- package/dist/components/SmartLink.js +1 -1
- package/dist/components/SmartLink.js.map +1 -1
- package/dist/components/Spinner.js +1 -1
- package/dist/components/Spinner.js.map +1 -1
- package/dist/components/StatusIndicator.js +1 -1
- package/dist/components/StatusIndicator.js.map +1 -1
- package/dist/components/StylePanel.js +1 -1
- package/dist/components/StylePanel.js.map +1 -1
- package/dist/components/Swiper.d.ts +2 -1
- package/dist/components/Swiper.d.ts.map +1 -1
- package/dist/components/Swiper.js +5 -5
- package/dist/components/Swiper.js.map +1 -1
- package/dist/components/Switch.js +1 -1
- package/dist/components/Switch.js.map +1 -1
- package/dist/components/Table.d.ts +37 -6
- package/dist/components/Table.d.ts.map +1 -1
- package/dist/components/Table.js +115 -30
- package/dist/components/Table.js.map +1 -1
- package/dist/components/Table.module.scss +174 -3
- package/dist/components/Tag.d.ts +1 -1
- package/dist/components/Tag.d.ts.map +1 -1
- package/dist/components/Tag.js +1 -1
- package/dist/components/Tag.js.map +1 -1
- package/dist/components/Text.js +1 -1
- package/dist/components/Text.js.map +1 -1
- package/dist/components/Textarea.d.ts.map +1 -1
- package/dist/components/Textarea.js +1 -2
- package/dist/components/Textarea.js.map +1 -1
- package/dist/components/ThemeInit.d.ts.map +1 -1
- package/dist/components/ThemeInit.js +6 -2
- package/dist/components/ThemeInit.js.map +1 -1
- package/dist/components/TiltFx.d.ts +1 -1
- package/dist/components/TiltFx.d.ts.map +1 -1
- package/dist/components/TiltFx.js +16 -7
- package/dist/components/TiltFx.js.map +1 -1
- package/dist/components/Timeline.d.ts +3 -3
- package/dist/components/Timeline.d.ts.map +1 -1
- package/dist/components/Timeline.js +19 -54
- package/dist/components/Timeline.js.map +1 -1
- package/dist/components/Toast.js +1 -1
- package/dist/components/Toast.js.map +1 -1
- package/dist/components/Toaster.d.ts +1 -1
- package/dist/components/Toaster.d.ts.map +1 -1
- package/dist/components/Toaster.js +4 -4
- package/dist/components/Toaster.js.map +1 -1
- package/dist/components/Toaster.module.scss +0 -2
- package/dist/components/ToggleButton.js +1 -1
- package/dist/components/ToggleButton.js.map +1 -1
- package/dist/components/Tooltip.js +1 -1
- package/dist/components/Tooltip.js.map +1 -1
- package/dist/components/TypeFx.d.ts +1 -1
- package/dist/components/TypeFx.d.ts.map +1 -1
- package/dist/components/TypeFx.js +3 -3
- package/dist/components/TypeFx.js.map +1 -1
- package/dist/components/User.js +1 -1
- package/dist/components/User.js.map +1 -1
- package/dist/components/UserMenu.d.ts +1 -1
- package/dist/components/UserMenu.d.ts.map +1 -1
- package/dist/components/UserMenu.js +4 -3
- package/dist/components/UserMenu.js.map +1 -1
- package/dist/css/styles.css +1 -1
- package/dist/css/styles.css.map +1 -1
- package/dist/css/tokens.css +1 -1
- package/dist/css/tokens.css.map +1 -1
- package/dist/data/emoji-data.json +8 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +2 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useArrowNavigation.d.ts.map +1 -1
- package/dist/hooks/useArrowNavigation.js +1 -0
- package/dist/hooks/useArrowNavigation.js.map +1 -1
- package/dist/hooks/useDebounce.d.ts +1 -1
- package/dist/hooks/useDebounce.d.ts.map +1 -1
- package/dist/hooks/useDebounce.js.map +1 -1
- package/dist/hooks/useResponsiveClasses.d.ts.map +1 -1
- package/dist/hooks/useResponsiveClasses.js +45 -2
- package/dist/hooks/useResponsiveClasses.js.map +1 -1
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +7 -2
- package/dist/icons.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +21 -36
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/internal/scrollLockState.d.ts +2 -0
- package/dist/internal/scrollLockState.d.ts.map +1 -0
- package/dist/internal/scrollLockState.js +12 -0
- package/dist/internal/scrollLockState.js.map +1 -0
- package/dist/modules/code/CodeBlock.impl.d.ts +2 -0
- package/dist/modules/code/CodeBlock.impl.d.ts.map +1 -1
- package/dist/modules/code/CodeBlock.impl.js +57 -17
- package/dist/modules/code/CodeBlock.impl.js.map +1 -1
- package/dist/modules/data/BarChart.impl.js +1 -1
- package/dist/modules/data/BarChart.impl.js.map +1 -1
- package/dist/modules/data/LineBarChart.impl.js +1 -1
- package/dist/modules/data/LineBarChart.impl.js.map +1 -1
- package/dist/modules/data/LineChart.impl.js +1 -1
- package/dist/modules/data/LineChart.impl.js.map +1 -1
- package/dist/modules/data/PieChart.impl.js +1 -1
- package/dist/modules/data/PieChart.impl.js.map +1 -1
- package/dist/modules/data/utils/formatDate.js +1 -1
- package/dist/modules/data/utils/formatDate.js.map +1 -1
- package/dist/modules/index.d.ts +2 -1
- package/dist/modules/index.d.ts.map +1 -1
- package/dist/modules/index.js +2 -1
- package/dist/modules/index.js.map +1 -1
- package/dist/modules/seo/Schema.d.ts.map +1 -1
- package/dist/modules/seo/Schema.js +3 -4
- package/dist/modules/seo/Schema.js.map +1 -1
- package/dist/package.json +38 -8
- package/dist/server/og-url-validation.d.ts +10 -0
- package/dist/server/og-url-validation.d.ts.map +1 -0
- package/dist/server/og-url-validation.js +234 -0
- package/dist/server/og-url-validation.js.map +1 -0
- package/dist/server/og-utils.d.ts +5 -2
- package/dist/server/og-utils.d.ts.map +1 -1
- package/dist/server/og-utils.js +39 -14
- package/dist/server/og-utils.js.map +1 -1
- package/dist/styles/typography.scss +8 -0
- package/dist/tokens/typography.scss +2 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/safe-html.d.ts +19 -0
- package/dist/utils/safe-html.d.ts.map +1 -0
- package/dist/utils/safe-html.js +43 -0
- package/dist/utils/safe-html.js.map +1 -0
- package/next-env.d.ts +5 -0
- package/package.json +55 -21
- package/scripts/copy-files.js +103 -0
- package/scripts/generate-ai-spec.js +464 -0
- package/scripts/generate-emoji-data.js +128 -0
- package/scripts/init-agent.js +156 -0
- package/scripts/validate-ai-code.js +149 -0
- package/.eslintrc.json +0 -3
- package/ai/catalog.seed.json +0 -411
- package/dist/ai/catalog.seed.json +0 -411
- package/next.config.mjs +0 -14
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Scaffold agent harness pointers in a consumer project.
|
|
4
|
+
* Usage: npx once-ui-init-agent [--force] [--dry-run]
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require("fs");
|
|
8
|
+
const path = require("path");
|
|
9
|
+
|
|
10
|
+
const PACKAGE_ROOT = path.join(__dirname, "..");
|
|
11
|
+
const MARKER_START = "<!-- once-ui-agent-harness:start -->";
|
|
12
|
+
const MARKER_END = "<!-- once-ui-agent-harness:end -->";
|
|
13
|
+
|
|
14
|
+
const PROJECT_AGENTS_SECTION = `${MARKER_START}
|
|
15
|
+
## Once UI codegen harness
|
|
16
|
+
|
|
17
|
+
Before generating Once UI code, load the harness from your installed package (not full doc pages):
|
|
18
|
+
|
|
19
|
+
1. Read \`node_modules/@once-ui-system/core/ai/manifest.json\`
|
|
20
|
+
2. Load bootstrap: \`ai/rules.compact.md\` + \`ai/catalog.json\`
|
|
21
|
+
3. Match intent via \`ai/tasks/index.json\` → fetch task bundle + component slices
|
|
22
|
+
4. Validate: \`npx once-ui-validate-ai-code path/to/file.tsx\`
|
|
23
|
+
|
|
24
|
+
npm exports: \`@once-ui-system/core/ai/manifest.json\`
|
|
25
|
+
|
|
26
|
+
Remote fallback: https://docs.once-ui.com/ai/manifest.json
|
|
27
|
+
${MARKER_END}
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
function parseArgs(argv) {
|
|
31
|
+
return {
|
|
32
|
+
force: argv.includes("--force"),
|
|
33
|
+
dryRun: argv.includes("--dry-run"),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function findProjectRoot(startDir = process.cwd()) {
|
|
38
|
+
let dir = path.resolve(startDir);
|
|
39
|
+
|
|
40
|
+
while (true) {
|
|
41
|
+
const pkgPath = path.join(dir, "package.json");
|
|
42
|
+
if (fs.existsSync(pkgPath)) {
|
|
43
|
+
try {
|
|
44
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
45
|
+
if (pkg.name !== "@once-ui-system/core") {
|
|
46
|
+
return dir;
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
// keep walking
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const parent = path.dirname(dir);
|
|
54
|
+
if (parent === dir) {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
dir = parent;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return path.resolve(startDir);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function upsertMarkedSection(existing, section, force) {
|
|
64
|
+
if (existing.includes(MARKER_START) && existing.includes(MARKER_END)) {
|
|
65
|
+
if (!force) {
|
|
66
|
+
return { content: existing, changed: false, reason: "AGENTS.md already contains Once UI harness section" };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const start = existing.indexOf(MARKER_START);
|
|
70
|
+
const end = existing.indexOf(MARKER_END) + MARKER_END.length;
|
|
71
|
+
return {
|
|
72
|
+
content: `${existing.slice(0, start)}${section}${existing.slice(end)}`,
|
|
73
|
+
changed: true,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (existing.trim().length === 0) {
|
|
78
|
+
return {
|
|
79
|
+
content: `# AGENTS.md\n\n${section}\n`,
|
|
80
|
+
changed: true,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
content: `${existing.trimEnd()}\n\n${section}\n`,
|
|
86
|
+
changed: true,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function writeFile(root, relativePath, content, { dryRun, force }) {
|
|
91
|
+
const target = path.join(root, relativePath);
|
|
92
|
+
const exists = fs.existsSync(target);
|
|
93
|
+
|
|
94
|
+
if (exists && !force) {
|
|
95
|
+
const current = fs.readFileSync(target, "utf8");
|
|
96
|
+
if (current === content) {
|
|
97
|
+
return { path: target, status: "unchanged" };
|
|
98
|
+
}
|
|
99
|
+
return { path: target, status: "skipped", reason: "already exists (use --force)" };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (dryRun) {
|
|
103
|
+
return { path: target, status: "would-write" };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
107
|
+
fs.writeFileSync(target, content, "utf8");
|
|
108
|
+
return { path: target, status: exists ? "updated" : "created" };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function main() {
|
|
112
|
+
const options = parseArgs(process.argv.slice(2));
|
|
113
|
+
const projectRoot = findProjectRoot();
|
|
114
|
+
const cursorRuleTemplate = fs.readFileSync(
|
|
115
|
+
path.join(PACKAGE_ROOT, "agent", "once-ui-codegen.mdc"),
|
|
116
|
+
"utf8",
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const agentsPath = path.join(projectRoot, "AGENTS.md");
|
|
120
|
+
let agentsContent = "";
|
|
121
|
+
if (fs.existsSync(agentsPath)) {
|
|
122
|
+
agentsContent = fs.readFileSync(agentsPath, "utf8");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const agentsResult = upsertMarkedSection(agentsContent, PROJECT_AGENTS_SECTION, options.force);
|
|
126
|
+
const results = [];
|
|
127
|
+
|
|
128
|
+
if (agentsResult.changed) {
|
|
129
|
+
results.push(
|
|
130
|
+
writeFile(projectRoot, "AGENTS.md", agentsResult.content, options),
|
|
131
|
+
);
|
|
132
|
+
} else {
|
|
133
|
+
results.push({
|
|
134
|
+
path: agentsPath,
|
|
135
|
+
status: "unchanged",
|
|
136
|
+
reason: agentsResult.reason,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
results.push(
|
|
141
|
+
writeFile(projectRoot, ".cursor/rules/once-ui-codegen.mdc", cursorRuleTemplate, options),
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
console.log(`Once UI agent harness setup (${options.dryRun ? "dry run" : "applied"})`);
|
|
145
|
+
console.log(`Project root: ${projectRoot}`);
|
|
146
|
+
for (const result of results) {
|
|
147
|
+
const suffix = result.reason ? ` (${result.reason})` : "";
|
|
148
|
+
console.log(`- ${result.status}: ${path.relative(projectRoot, result.path)}${suffix}`);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (!options.dryRun) {
|
|
152
|
+
console.log("\nNext: open a .tsx file and ask your agent to build Once UI — it should load the harness from node_modules/@once-ui-system/core/ai/");
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
main();
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Mechanical Once UI codegen validator.
|
|
4
|
+
* Usage: node scripts/validate-ai-code.js <file.tsx> [--fix]
|
|
5
|
+
* node scripts/validate-ai-code.js --stdin < file.tsx
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require("fs");
|
|
9
|
+
const path = require("path");
|
|
10
|
+
|
|
11
|
+
const ROOT = path.join(__dirname, "..");
|
|
12
|
+
const SPEC_PATH = path.join(ROOT, "ai", "spec.json");
|
|
13
|
+
|
|
14
|
+
function loadSpec() {
|
|
15
|
+
if (!fs.existsSync(SPEC_PATH)) return { components: {}, tokens: {} };
|
|
16
|
+
return JSON.parse(fs.readFileSync(SPEC_PATH, "utf8"));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function parseIconNames(spec) {
|
|
20
|
+
const raw = spec.tokens?.IconName || "";
|
|
21
|
+
const matches = raw.match(/"([^"]+)"/g) || [];
|
|
22
|
+
return new Set(matches.map((m) => m.slice(1, -1)));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function readInput(argv) {
|
|
26
|
+
const fileArg = argv.find((a) => !a.startsWith("-"));
|
|
27
|
+
if (argv.includes("--stdin")) {
|
|
28
|
+
return { source: fs.readFileSync(0, "utf8"), file: "<stdin>" };
|
|
29
|
+
}
|
|
30
|
+
if (!fileArg) {
|
|
31
|
+
console.error("Usage: validate-ai-code.js <file.tsx> [--fix] | --stdin");
|
|
32
|
+
process.exit(2);
|
|
33
|
+
}
|
|
34
|
+
return { source: fs.readFileSync(fileArg, "utf8"), file: fileArg };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function validate(source, spec, iconNames) {
|
|
38
|
+
const issues = [];
|
|
39
|
+
|
|
40
|
+
const add = (rule, message, fix) => issues.push({ rule, message, fix });
|
|
41
|
+
|
|
42
|
+
if (/fillWidth[\s\S]{0,80}fillHeight|<Flex[^>]*direction="column"|<Flex[^>]*direction="row"/.test(source)) {
|
|
43
|
+
if (/fillWidth[\s\S]{0,120}fillHeight/.test(source)) {
|
|
44
|
+
add("layout.shorthands", "Use fill instead of fillWidth + fillHeight", "fill");
|
|
45
|
+
}
|
|
46
|
+
if (/<Flex[^>]*direction="column"/.test(source)) {
|
|
47
|
+
add("layout.shorthands", "Use Column instead of Flex direction=\"column\"", "Column");
|
|
48
|
+
}
|
|
49
|
+
if (/<Flex[^>]*direction="row"/.test(source)) {
|
|
50
|
+
add("layout.shorthands", "Use Row instead of Flex direction=\"row\"", "Row");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (/horizontal="center"[\s\S]{0,80}vertical="center"/.test(source)) {
|
|
55
|
+
add("layout.shorthands", "Use center instead of horizontal=\"center\" vertical=\"center\"", "center");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (/position="relative"/.test(source)) {
|
|
59
|
+
add("layout.defaults", "position=\"relative\" is the default — omit it");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (/<Button[^>]*variant="primary"/.test(source)) {
|
|
63
|
+
add("layout.defaults", "variant=\"primary\" is the Button default — omit it");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (/#[0-9a-fA-F]{3,8}\b|rgb\s*\(|rgba\s*\(/.test(source)) {
|
|
67
|
+
add("color.tokens", "Use semantic color tokens, not hex/rgb");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (/<img[\s>/]|<a[\s>/]|<button[\s>/]/.test(source)) {
|
|
71
|
+
add("components.primitives", "Use Once UI components (Media, SmartLink, Button) instead of raw HTML");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const cardMatches = source.match(/<Card\b[^>]*>/g) || [];
|
|
75
|
+
for (const tag of cardMatches) {
|
|
76
|
+
if (!/\b(href|onClick)=/.test(tag)) {
|
|
77
|
+
add("Card.interactive", "Card without href/onClick — use Column + surface recipe for static panels");
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const iconPropRe = /(?:prefixIcon|suffixIcon|name)=["']([^"']+)["']/g;
|
|
83
|
+
let iconMatch;
|
|
84
|
+
while ((iconMatch = iconPropRe.exec(source)) !== null) {
|
|
85
|
+
const name = iconMatch[1];
|
|
86
|
+
if (iconNames.size && !iconNames.has(name)) {
|
|
87
|
+
add("Icon.names", `Unknown icon name "${name}" — use IconName from spec.json`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (/delay=\{[^}]*\*\s*80/.test(source)) {
|
|
92
|
+
add("RevealFx.delay", "RevealFx delay is in seconds — use index * 0.1, not index * 80");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (/<Fade[^>]*>[\s\S]*<(Column|Row)[^>]*overflowY/.test(source)) {
|
|
96
|
+
add("Fade.edge", "Fade wrapping scroll content — use as absolute edge strip instead");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (/style=\{\{[^}]*(gap|padding|margin|color|background):/.test(source)) {
|
|
100
|
+
add("spacing.tokens", "Use token props (gap, padding, background) instead of style={{}}");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return issues;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function applyFixes(source, issues) {
|
|
107
|
+
let out = source;
|
|
108
|
+
for (const issue of issues) {
|
|
109
|
+
if (issue.fix === "fill") {
|
|
110
|
+
out = out.replace(/\bfillWidth\b\s*\n?\s*\bfillHeight\b/g, "fill");
|
|
111
|
+
}
|
|
112
|
+
if (issue.fix === "center") {
|
|
113
|
+
out = out.replace(/\bhorizontal="center"\s*\n?\s*vertical="center"/g, "center");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return out;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function main() {
|
|
120
|
+
const spec = loadSpec();
|
|
121
|
+
const iconNames = parseIconNames(spec);
|
|
122
|
+
const fix = process.argv.includes("--fix");
|
|
123
|
+
const { source, file } = readInput(process.argv.slice(2));
|
|
124
|
+
|
|
125
|
+
const issues = validate(source, spec, iconNames);
|
|
126
|
+
|
|
127
|
+
if (issues.length === 0) {
|
|
128
|
+
console.log(`✓ ${file}: no mechanical issues`);
|
|
129
|
+
process.exit(0);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
console.log(`✗ ${file}: ${issues.length} issue(s)`);
|
|
133
|
+
for (const issue of issues) {
|
|
134
|
+
console.log(` [${issue.rule}] ${issue.message}`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (fix) {
|
|
138
|
+
const fixed = applyFixes(source, issues);
|
|
139
|
+
if (fixed !== source && !process.argv.includes("--stdin")) {
|
|
140
|
+
const fileArg = process.argv.find((a) => a.endsWith(".tsx") || a.endsWith(".jsx"));
|
|
141
|
+
fs.writeFileSync(fileArg, fixed);
|
|
142
|
+
console.log(`Applied auto-fixes to ${fileArg}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
main();
|
package/.eslintrc.json
DELETED