@momo-kits/native-kits 0.157.1-skill.3 → 0.157.1-skill.6-debug
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/skills/momo-native-kits-skills/README.md +52 -0
- package/.claude/skills/momo-native-kits-skills/SKILL.md +32 -0
- package/.claude/skills/momo-native-kits-skills/data-display/SKILL.md +42 -0
- package/.claude/skills/momo-native-kits-skills/feedback/SKILL.md +43 -0
- package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/feedback}/references/popup.md +3 -10
- package/.claude/skills/momo-native-kits-skills/form-controls/SKILL.md +42 -0
- package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/form-controls}/references/button.md +2 -3
- package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/form-controls}/references/input.md +3 -7
- package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/form-controls}/references/radio.md +9 -9
- package/.claude/skills/momo-native-kits-skills/layout/SKILL.md +39 -0
- package/.claude/skills/momo-native-kits-skills/navigation/SKILL.md +38 -0
- package/.claude/skills/momo-native-kits-skills/output/test-report.json +12 -0
- package/.claude/skills/momo-native-kits-skills/output/validation-result.json +108 -0
- package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills}/references/constants.md +81 -6
- package/.claude/skills/momo-native-kits-skills/references/design-guidelines.md +130 -0
- package/.claude/skills/momo-native-kits-skills/references/developer/android-compose.md +29 -0
- package/.claude/skills/momo-native-kits-skills/references/developer/code-convention.md +118 -0
- package/.claude/skills/momo-native-kits-skills/references/developer/compose-multiplatform.md +29 -0
- package/.claude/skills/momo-native-kits-skills/scripts/logger.js +63 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/badge.js +32 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/bottomtab.js +19 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/button.js +32 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/card.js +32 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/checkbox.js +32 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/chip.js +59 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/divider.js +19 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/global.js +61 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/index.js +54 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/input.js +32 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/navigation.js +48 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/popup.js +45 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/radio.js +105 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/skeleton.js +20 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/snackbar.js +32 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/state.js +21 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/switch.js +45 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/text.js +19 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/tooltip.js +45 -0
- package/.claude/skills/momo-native-kits-skills/scripts/rules/trustbanner.js +22 -0
- package/.claude/skills/momo-native-kits-skills/scripts/test-on-device.sh +117 -0
- package/.claude/skills/momo-native-kits-skills/scripts/test-runner.js +167 -0
- package/.claude/skills/momo-native-kits-skills/scripts/validate-kits.js +131 -0
- package/.momo-agent.json +13 -0
- package/build.gradle.kts +11 -0
- package/compose/build.gradle.kts +180 -0
- package/compose/build.gradle.kts.backup +180 -0
- package/compose/compose.podspec +54 -0
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +110 -0
- package/compose/src/commonMain/composeResources/font/momosignature.otf +0 -0
- package/compose/src/commonMain/composeResources/font/momotrustdisplay.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_black.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_black.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_bold.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_heavy.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_light.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_medium.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_regular.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_semibold.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_thin.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_thin.ttf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.otf +0 -0
- package/compose/src/commonMain/composeResources/font/sfprotext_ultralight.ttf +0 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/AnimationSearchInput.kt +57 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Context.kt +107 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/FloatingButton.kt +201 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Header.kt +222 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderAnimated.kt +48 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderBackground.kt +86 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderDefault.kt +76 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderExtended.kt +76 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderRight.kt +305 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/HeaderTitle.kt +33 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/LiteScreen.kt +720 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/NavigationContainer.kt +121 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/Screen.kt +405 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/application/useHeaderSearchAnimation.kt +69 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Badge.kt +85 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeDot.kt +32 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BadgeRibbon.kt +340 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/BaselineView.kt +198 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Button.kt +357 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CheckBox.kt +94 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Chip.kt +136 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/CupertinoOverscroll.kt +543 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Divider.kt +23 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Icon.kt +76 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/IconButton.kt +148 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Image.kt +188 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Information.kt +116 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Input.kt +448 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputDropDown.kt +172 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputMoney.kt +255 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputOTP.kt +231 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputPhoneNumber.kt +233 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputSearch.kt +254 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/InputTextArea.kt +241 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/LazyColumnWithBouncing.kt +364 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationDot.kt +56 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationNumber.kt +41 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationScroll.kt +92 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PaginationWhiteDot.kt +40 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupNotify.kt +352 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +103 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Radio.kt +70 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ScaleSizeScope.kt +17 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Skeleton.kt +96 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Switch.kt +96 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tag.kt +92 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Text.kt +130 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Title.kt +214 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Tooltip.kt +590 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TrustBanner.kt +177 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePicker.kt +205 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerTypes.kt +29 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/DateTimePickerUtils.kt +239 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/datetimepicker/WheelPicker.kt +191 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Colors.kt +306 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Radius.kt +12 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +13 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +185 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Typography.kt +285 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Card.kt +2 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Item.kt +35 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/layout/Section.kt +2 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +59 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Clickable.kt +68 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Conditional.kt +11 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/DeprecatedModifier.kt +14 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Shadow.kt +50 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/Size.kt +51 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +239 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +119 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +98 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +161 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +331 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +497 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTab.kt +162 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/BottomTabBar.kt +243 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/bottomtab/CurvedContainer.kt +86 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/FloatingButton.kt +187 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/Header.kt +279 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderBackground.kt +80 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderRight.kt +306 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderTitle.kt +32 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/HeaderUser.kt +370 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/component/SnackBar.kt +132 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +42 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Icons.kt +1329 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Resources.kt +62 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Tracking.kt +15 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/utils/Utils.kt +88 -0
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +149 -0
- package/gradle/libs.versions.toml +57 -0
- package/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/gradle/wrapper/gradle-wrapper.properties +8 -0
- package/gradle.properties +26 -0
- package/gradlew +252 -0
- package/gradlew.bat +94 -0
- package/package.json +1 -1
- package/settings.gradle.kts +52 -0
- package/.claude/momo-native-kits-skill/SKILL.md +0 -51
- package/.claude/momo-native-kits-skill/evals/evals.json +0 -95
- package/.claude/momo-native-kits-skill/workspace/iteration-1/benchmark.json +0 -20
- package/.claude/momo-native-kits-skill/workspace/iteration-1/benchmark.md +0 -13
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-0-button/eval_metadata.json +0 -6
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-0-button/with_skill/outputs/ButtonExample.kt +0 -55
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-0-button/without_skill/outputs/ButtonExample.kt +0 -45
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-1-input/eval_metadata.json +0 -6
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-1-input/with_skill/outputs/InputPhoneExample.kt +0 -40
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-1-input/without_skill/outputs/InputPhoneExample.kt +0 -42
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-2-bottomtab/eval_metadata.json +0 -6
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-2-bottomtab/with_skill/outputs/BottomTabExample.kt +0 -236
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-2-bottomtab/without_skill/outputs/BottomTabExample.kt +0 -152
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-3-checkbox/eval_metadata.json +0 -6
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-3-checkbox/with_skill/outputs/CheckBoxExample.kt +0 -49
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-3-checkbox/without_skill/outputs/CheckBoxExample.kt +0 -123
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-4-datetimepicker/eval_metadata.json +0 -6
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-4-datetimepicker/with_skill/outputs/DateTimePickerExample.kt +0 -318
- package/.claude/momo-native-kits-skill/workspace/iteration-1/eval-4-datetimepicker/without_skill/outputs/DateTimePickerExample.kt +0 -330
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-card/with_skill/outputs/CardExample.kt +0 -124
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-card/without_skill/outputs/CardExample.kt +0 -71
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-loginform/with_skill/outputs/LoginFormExample.kt +0 -134
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-loginform/without_skill/outputs/LoginFormExample.kt +0 -199
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-navcontainer/with_skill/outputs/NavigationContainerExample.kt +0 -224
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-navcontainer/without_skill/outputs/NavigationContainerExample.kt +0 -225
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-popup/with_skill/outputs/PopupExample.kt +0 -79
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-popup/without_skill/outputs/PopupExample.kt +0 -169
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-setoptions/eval_metadata.json +0 -6
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-setoptions/with_skill/outputs/SetOptionsExample.kt +0 -255
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-setoptions/without_skill/outputs/SetOptionsExample.kt +0 -212
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-skeleton/with_skill/outputs/SkeletonExample.kt +0 -199
- package/.claude/momo-native-kits-skill/workspace/iteration-2/eval-skeleton/without_skill/outputs/SkeletonExample.kt +0 -229
- package/.claude/momo-native-kits-skill/workspace/iteration-3/benchmark.json +0 -20
- package/.claude/momo-native-kits-skill/workspace/iteration-3/benchmark.md +0 -13
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-button/eval_metadata.json +0 -22
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-button/with_skill/outputs/PrimaryButtonExample.kt +0 -38
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-button/with_skill/timing.json +0 -5
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-button/without_skill/outputs/PrimaryButtonExample.kt +0 -83
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-button/without_skill/timing.json +0 -5
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-navcontainer/eval_metadata.json +0 -22
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-navcontainer/with_skill/outputs/NavigationContainerExample.kt +0 -547
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-navcontainer/with_skill/timing.json +0 -5
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-navcontainer/without_skill/outputs/MoMoNavigationContainer.kt +0 -519
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-navcontainer/without_skill/timing.json +0 -5
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-setoptions/eval_metadata.json +0 -27
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-setoptions/with_skill/outputs/SetOptionsExample.kt +0 -429
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-setoptions/with_skill/timing.json +0 -5
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-setoptions/without_skill/outputs/SetOptionsExample.kt +0 -353
- package/.claude/momo-native-kits-skill/workspace/iteration-3/eval-setoptions/without_skill/timing.json +0 -5
- package/.claude/settings.local.json +0 -41
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/data-display}/references/badge.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/data-display}/references/chip.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/data-display}/references/skeleton.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/data-display}/references/text.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/feedback}/references/snackbar.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/feedback}/references/tooltip.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/feedback}/references/trustbanner.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/form-controls}/references/checkbox.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/form-controls}/references/switch.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/layout}/references/card.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/layout}/references/divider.md +0 -0
- /package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills/navigation}/references/navigation.md +0 -0
package/.claude/{momo-native-kits-skill → skills/momo-native-kits-skills}/references/constants.md
RENAMED
|
@@ -81,24 +81,51 @@ Design tokens and constants ensure consistent styling across the app.
|
|
|
81
81
|
| `Colors.gray_08` | #616161 | ... |
|
|
82
82
|
| `Colors.gray_09` | #424242 | Dark gray |
|
|
83
83
|
|
|
84
|
+
### Semantic Mapping
|
|
85
|
+
|
|
86
|
+
Use semantic colors from `AppTheme` for theme-aware UIs. Use `Colors.*` only when a specific color is needed regardless of theme.
|
|
87
|
+
|
|
88
|
+
| Intent | Light Mode | Dark Mode | Usage |
|
|
89
|
+
|--------|-----------|-----------|-------|
|
|
90
|
+
| Primary text | `theme.colors.text.default` | Auto-adapts | Body, titles |
|
|
91
|
+
| Secondary text | `theme.colors.text.secondary` | Auto-adapts | Captions, hints |
|
|
92
|
+
| Disabled text | `theme.colors.text.disable` | Auto-adapts | Disabled states |
|
|
93
|
+
| Surface | `theme.colors.background.surface` | Auto-adapts | Cards, sheets |
|
|
94
|
+
| Error | `theme.colors.error.primary` | Auto-adapts | Error messages |
|
|
95
|
+
| Brand CTA | `Colors.pink_01` | Same | Primary buttons |
|
|
96
|
+
|
|
97
|
+
### Contrast & Accessibility
|
|
98
|
+
|
|
99
|
+
- Text on backgrounds: minimum **4.5:1** contrast ratio (WCAG AA)
|
|
100
|
+
- Large text (>= 20sp bold): minimum **3:1**
|
|
101
|
+
- Safe pairs on light bg: `Colors.black_01`..`black_03` on `white_01`/`white_02`/`gray_01`..`gray_03`
|
|
102
|
+
- Safe pairs on dark bg: `Colors.white_01`/`gray_01`..`gray_03` on `black_01`..`black_03`
|
|
103
|
+
- Status colors: always use `_02` or darker variants for text, `_01` variants only for backgrounds
|
|
104
|
+
- Never use color alone to convey meaning — pair with icons or text labels
|
|
105
|
+
|
|
84
106
|
### Usage
|
|
85
107
|
|
|
86
108
|
```kotlin
|
|
87
109
|
import vn.momo.kits.const.Colors
|
|
88
110
|
|
|
89
|
-
//
|
|
111
|
+
// Prefer semantic theme colors
|
|
112
|
+
val theme = AppTheme.current
|
|
90
113
|
Text(
|
|
91
114
|
text = "Hello",
|
|
92
|
-
color =
|
|
115
|
+
color = theme.colors.text.default // adapts to light/dark
|
|
93
116
|
)
|
|
94
117
|
|
|
95
|
-
//
|
|
118
|
+
// Use Colors.* for specific brand colors
|
|
96
119
|
Box(
|
|
97
120
|
modifier = Modifier.background(Colors.pink_01)
|
|
98
121
|
) { /* content */ }
|
|
99
122
|
|
|
100
|
-
//
|
|
101
|
-
|
|
123
|
+
// Status colors: background + text pair
|
|
124
|
+
Box(
|
|
125
|
+
modifier = Modifier.background(Colors.red_01) // light bg
|
|
126
|
+
) {
|
|
127
|
+
Text(text = "Error", color = Colors.red_04) // dark text = good contrast
|
|
128
|
+
}
|
|
102
129
|
```
|
|
103
130
|
|
|
104
131
|
---
|
|
@@ -151,6 +178,18 @@ Box(
|
|
|
151
178
|
| `Spacing.XL` | 24.dp | Section spacing |
|
|
152
179
|
| `Spacing.XXL` | 32.dp | Large gaps |
|
|
153
180
|
|
|
181
|
+
### Contextual Rules
|
|
182
|
+
|
|
183
|
+
| Context | Spacing | Example |
|
|
184
|
+
|---------|---------|---------|
|
|
185
|
+
| **Inset** (padding inside containers) | `Spacing.L` (16.dp) | Card content padding, screen padding |
|
|
186
|
+
| **Stack** (between items in a list) | `Spacing.S`–`Spacing.M` (8–12.dp) | Form fields, list items |
|
|
187
|
+
| **Inline** (between horizontal items) | `Spacing.S`–`Spacing.M` (8–12.dp) | Button + icon, label + badge |
|
|
188
|
+
| **Section gap** (between content groups) | `Spacing.XL`–`Spacing.XXL` (24–32.dp) | Between form sections, card groups |
|
|
189
|
+
| **Tight** (related sub-items) | `Spacing.XS` (4.dp) | Label + helper text, icon + text |
|
|
190
|
+
|
|
191
|
+
**Rule of thumb:** related items → smaller spacing, distinct groups → larger spacing.
|
|
192
|
+
|
|
154
193
|
### Usage
|
|
155
194
|
|
|
156
195
|
```kotlin
|
|
@@ -189,6 +228,24 @@ Box(
|
|
|
189
228
|
| `captionDefault` | 12sp | Regular | Captions |
|
|
190
229
|
| `captionBold` | 12sp | Bold | Bold captions |
|
|
191
230
|
|
|
231
|
+
### Pairing Rules
|
|
232
|
+
|
|
233
|
+
Use these combinations to establish visual hierarchy:
|
|
234
|
+
|
|
235
|
+
| Pattern | Title style | Body style | Caption style |
|
|
236
|
+
|---------|------------|------------|---------------|
|
|
237
|
+
| **Screen header** | `headlineDefaultBold` | `bodyDefault` | `captionDefault` |
|
|
238
|
+
| **Card** | `titleDefaultBold` | `bodyDefault` | `captionDefault` |
|
|
239
|
+
| **List item** | `bodyBold` | `bodySmall` | `captionDefault` |
|
|
240
|
+
| **Form field** | — | `bodyDefault` (value) | `captionDefault` (label/error) |
|
|
241
|
+
| **Button** | — | — | `actionDefaultBold` |
|
|
242
|
+
|
|
243
|
+
**Rules:**
|
|
244
|
+
- Max 3 typography levels per view (title + body + caption)
|
|
245
|
+
- Bold variant for primary info, regular for secondary
|
|
246
|
+
- `bodyDefault` (16sp) minimum for readable body text
|
|
247
|
+
- `captionDefault` (12sp) only for non-essential info (timestamps, metadata)
|
|
248
|
+
|
|
192
249
|
### Usage
|
|
193
250
|
|
|
194
251
|
```kotlin
|
|
@@ -238,7 +295,7 @@ fun MyComponent() {
|
|
|
238
295
|
Box(
|
|
239
296
|
modifier = Modifier
|
|
240
297
|
.background(theme.colors.background.surface)
|
|
241
|
-
.padding(
|
|
298
|
+
.padding(Spacing.L)
|
|
242
299
|
) {
|
|
243
300
|
Text(
|
|
244
301
|
text = "Themed text",
|
|
@@ -248,6 +305,24 @@ fun MyComponent() {
|
|
|
248
305
|
}
|
|
249
306
|
```
|
|
250
307
|
|
|
308
|
+
### Dark Mode Guidelines
|
|
309
|
+
|
|
310
|
+
AppTheme auto-adapts colors for light/dark mode. Follow these rules:
|
|
311
|
+
|
|
312
|
+
1. **Always use `theme.colors.*`** for surfaces, text, borders — they swap automatically
|
|
313
|
+
2. **Surfaces in dark mode** use lighter shades (not shadows) for elevation hierarchy
|
|
314
|
+
3. **Avoid `Colors.white_01` for backgrounds** — use `theme.colors.background.surface` instead
|
|
315
|
+
4. **Status colors** (`Colors.red_*`, `Colors.green_*`) work in both modes, but prefer `theme.colors.error.*` when available
|
|
316
|
+
5. **Test both modes** — check all screens in light and dark
|
|
317
|
+
|
|
318
|
+
```kotlin
|
|
319
|
+
// ✅ CORRECT — theme-aware
|
|
320
|
+
Box(modifier = Modifier.background(AppTheme.current.colors.background.surface))
|
|
321
|
+
|
|
322
|
+
// ❌ WRONG — hardcoded, breaks in dark mode
|
|
323
|
+
Box(modifier = Modifier.background(Colors.white_01))
|
|
324
|
+
```
|
|
325
|
+
|
|
251
326
|
---
|
|
252
327
|
|
|
253
328
|
## Best Practices
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Design Guidelines for MoMo Compose
|
|
2
|
+
|
|
3
|
+
Actionable design principles for composing MoMo Native Kits components into well-structured screens.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Visual Hierarchy
|
|
8
|
+
|
|
9
|
+
Establish clear hierarchy so users see the most important content first.
|
|
10
|
+
|
|
11
|
+
### Hierarchy Levels
|
|
12
|
+
|
|
13
|
+
| Level | What | MoMo Implementation |
|
|
14
|
+
|-------|------|---------------------|
|
|
15
|
+
| **Primary** | Page title, main CTA | `Title(type = TITLE_1)` + `Button(type = PRIMARY)` |
|
|
16
|
+
| **Secondary** | Section headings, key content | `Title(type = TITLE_2..3)` + `bodyBold` |
|
|
17
|
+
| **Tertiary** | Supporting text, descriptions | `bodyDefault` / `bodySmall` + `theme.colors.text.secondary` |
|
|
18
|
+
| **Quaternary** | Timestamps, metadata | `captionDefault` + `theme.colors.text.secondary` |
|
|
19
|
+
|
|
20
|
+
### Rules
|
|
21
|
+
|
|
22
|
+
1. **One primary CTA per screen** — use `ButtonType.PRIMARY` only once; others get `SECONDARY`/`OUTLINE`/`TEXT`
|
|
23
|
+
2. **Size contrast >= 1.5x** between hierarchy levels (e.g. 24sp headline vs 16sp body)
|
|
24
|
+
3. **Whitespace signals importance** — more `Spacing` around key elements isolates them visually
|
|
25
|
+
4. **Color draws attention** — reserve `Colors.pink_01` for CTAs and critical info; don't overuse brand color
|
|
26
|
+
|
|
27
|
+
### Screen Composition Pattern
|
|
28
|
+
|
|
29
|
+
```kotlin
|
|
30
|
+
Column(modifier = Modifier.padding(Spacing.L)) {
|
|
31
|
+
// Primary — seen first
|
|
32
|
+
Title(text = "Screen Title", type = TitleType.TITLE_1)
|
|
33
|
+
|
|
34
|
+
Spacer(modifier = Modifier.height(Spacing.XL)) // large gap = new section
|
|
35
|
+
|
|
36
|
+
// Secondary — scanned next
|
|
37
|
+
Title(text = "Section", type = TitleType.TITLE_3)
|
|
38
|
+
|
|
39
|
+
Spacer(modifier = Modifier.height(Spacing.S)) // small gap = related
|
|
40
|
+
|
|
41
|
+
// Tertiary — read on demand
|
|
42
|
+
Text(text = "Description...", style = Typography.bodyDefault,
|
|
43
|
+
color = AppTheme.current.colors.text.secondary)
|
|
44
|
+
|
|
45
|
+
Spacer(modifier = Modifier.height(Spacing.XXL)) // section break
|
|
46
|
+
|
|
47
|
+
// Primary CTA — anchored at bottom
|
|
48
|
+
Button(onClick = { }, title = "Continue", type = ButtonType.PRIMARY, isFull = true)
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Component Composition Patterns
|
|
55
|
+
|
|
56
|
+
### Card Layout
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
Card
|
|
60
|
+
├── Image / Icon (optional, visual anchor)
|
|
61
|
+
├── Title (bodyBold or titleDefaultBold)
|
|
62
|
+
├── Description (bodyDefault, text.secondary)
|
|
63
|
+
└── Action (Button TEXT or OUTLINE, or clickable Card)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Spacing: `Spacing.L` inset, `Spacing.S` between internal items.
|
|
67
|
+
|
|
68
|
+
### Form Layout
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
Column (spacedBy = Spacing.M)
|
|
72
|
+
├── Input (floatingValue label)
|
|
73
|
+
├── Input (floatingValue label)
|
|
74
|
+
├── CheckBox (terms agreement)
|
|
75
|
+
└── Button PRIMARY (submit, isFull = true)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Spacing: `Spacing.M` between fields, `Spacing.XL` before submit button.
|
|
79
|
+
|
|
80
|
+
### List Item
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
Row
|
|
84
|
+
├── Icon / Avatar (leading)
|
|
85
|
+
├── Column
|
|
86
|
+
│ ├── Text (bodyBold — primary info)
|
|
87
|
+
│ └── Text (captionDefault, text.secondary — secondary info)
|
|
88
|
+
└── Badge / Icon (trailing, optional)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Spacing: `Spacing.M` inline between leading/content/trailing.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Spacing Decisions
|
|
96
|
+
|
|
97
|
+
| Decision | Use |
|
|
98
|
+
|----------|-----|
|
|
99
|
+
| Items in same group | `Spacing.S` (8.dp) or `Spacing.M` (12.dp) |
|
|
100
|
+
| Between groups / sections | `Spacing.XL` (24.dp) or `Spacing.XXL` (32.dp) |
|
|
101
|
+
| Screen padding | `Spacing.L` (16.dp) |
|
|
102
|
+
| Card internal padding | `Spacing.L` (16.dp) |
|
|
103
|
+
| Icon-to-text gap | `Spacing.XS` (4.dp) or `Spacing.S` (8.dp) |
|
|
104
|
+
| Before primary CTA | `Spacing.XL` (24.dp) minimum |
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Color Decisions
|
|
109
|
+
|
|
110
|
+
| Decision | Use | Avoid |
|
|
111
|
+
|----------|-----|-------|
|
|
112
|
+
| Background | `theme.colors.background.surface` | Hardcoded `Colors.white_01` |
|
|
113
|
+
| Primary text | `theme.colors.text.default` | `Colors.black_01` |
|
|
114
|
+
| Secondary text | `theme.colors.text.secondary` | `Colors.gray_06` |
|
|
115
|
+
| Disabled | `theme.colors.text.disable` | Custom opacity hacks |
|
|
116
|
+
| Error text | `theme.colors.error.primary` or `Colors.red_04` | `Colors.red_01` (too light) |
|
|
117
|
+
| Success feedback | `Colors.green_02` (icon/text) + `Colors.green_01` (bg) | Green text on green bg |
|
|
118
|
+
| Brand accent | `Colors.pink_01` — sparingly | Pink on every element |
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Squint Test
|
|
123
|
+
|
|
124
|
+
Before finalizing a screen, blur your eyes (or zoom to 25%). You should still see:
|
|
125
|
+
1. Where the title is
|
|
126
|
+
2. Where the primary action is
|
|
127
|
+
3. Clear grouping of related content
|
|
128
|
+
4. Separation between sections
|
|
129
|
+
|
|
130
|
+
If everything looks the same size/weight, hierarchy is missing.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: android, compose, jetpack
|
|
3
|
+
related: code-convention
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Android Compose Developer Reference
|
|
7
|
+
|
|
8
|
+
## Scope
|
|
9
|
+
|
|
10
|
+
Use this reference when creating or updating skills for Android UI with Jetpack Compose.
|
|
11
|
+
|
|
12
|
+
## Core Stack
|
|
13
|
+
|
|
14
|
+
1. Jetpack Compose for UI.
|
|
15
|
+
2. Kotlin shared business/domain logic.
|
|
16
|
+
3. MVVM with unidirectional state flow.
|
|
17
|
+
|
|
18
|
+
## Implementation Rules
|
|
19
|
+
|
|
20
|
+
1. Keep composables stateless where possible.
|
|
21
|
+
2. Push side-effects and business rules to ViewModel/use-cases.
|
|
22
|
+
3. Use shared Kotlin models for domain/state transformations.
|
|
23
|
+
4. Keep Android-specific code in UI/platform adapters only.
|
|
24
|
+
|
|
25
|
+
## Deliverables Required in Skills
|
|
26
|
+
|
|
27
|
+
1. One composable screen example.
|
|
28
|
+
2. One ViewModel + shared use-case integration example.
|
|
29
|
+
3. Test checklist covering state reducer and UI rendering states.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: code, convention, formatting, style, lint, developer
|
|
3
|
+
related:
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Code Convention
|
|
7
|
+
|
|
8
|
+
Apply this convention to every AI-generated code output.
|
|
9
|
+
|
|
10
|
+
## Scope and Consistency
|
|
11
|
+
|
|
12
|
+
1. Use this document as the single source of truth for code-related skills.
|
|
13
|
+
2. Any copied code-convention reference in other skills must be identical to this file.
|
|
14
|
+
3. Apply header and marker requirements only to newly generated files or newly generated code blocks.
|
|
15
|
+
4. Do not add markers/header to unchanged existing code.
|
|
16
|
+
|
|
17
|
+
## 0) File Size and Line Width
|
|
18
|
+
|
|
19
|
+
1. Keep each source file under about 500 lines.
|
|
20
|
+
2. Enforce max line length (column width) of 120.
|
|
21
|
+
3. If a file would exceed 500 lines, split by feature/module while preserving behavior.
|
|
22
|
+
|
|
23
|
+
## 1) Required File Header
|
|
24
|
+
|
|
25
|
+
Add a file header at the top of each newly generated code file with:
|
|
26
|
+
|
|
27
|
+
1. `File`
|
|
28
|
+
2. `Created At` (ISO-like timestamp with timezone)
|
|
29
|
+
3. `Created By` (`AI`)
|
|
30
|
+
4. `AI Agent`
|
|
31
|
+
5. `Model`
|
|
32
|
+
|
|
33
|
+
Template:
|
|
34
|
+
|
|
35
|
+
```txt
|
|
36
|
+
<COMMENT_OPEN>
|
|
37
|
+
File: <relative-or-file-name>
|
|
38
|
+
Created At: <YYYY-MM-DD HH:mm:ss Z>
|
|
39
|
+
Created By: AI
|
|
40
|
+
AI Agent: <agent-name>
|
|
41
|
+
Model: <model-id>
|
|
42
|
+
<COMMENT_CLOSE>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Language examples:
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
/*
|
|
49
|
+
File: src/example.js
|
|
50
|
+
Created At: 2026-03-10 12:30:00 +07:00
|
|
51
|
+
Created By: AI
|
|
52
|
+
AI Agent: Codex
|
|
53
|
+
Model: gpt-5
|
|
54
|
+
*/
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```py
|
|
58
|
+
# File: src/example.py
|
|
59
|
+
# Created At: 2026-03-10 12:30:00 +07:00
|
|
60
|
+
# Created By: AI
|
|
61
|
+
# AI Agent: Codex
|
|
62
|
+
# Model: gpt-5
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 2) Required AI Block Markers
|
|
66
|
+
|
|
67
|
+
Wrap every newly generated AI code block:
|
|
68
|
+
|
|
69
|
+
- Start marker: `AI-GENERATED START`
|
|
70
|
+
- End marker: `AI-GENERATED END`
|
|
71
|
+
- Include short purpose text.
|
|
72
|
+
|
|
73
|
+
JavaScript / TypeScript:
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
// AI-GENERATED START: build payment retry helper
|
|
77
|
+
function retryPayment() {
|
|
78
|
+
// ...
|
|
79
|
+
}
|
|
80
|
+
// AI-GENERATED END: build payment retry helper
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Python:
|
|
84
|
+
|
|
85
|
+
```py
|
|
86
|
+
# AI-GENERATED START: parse webhook payload
|
|
87
|
+
def parse_webhook(payload):
|
|
88
|
+
return payload
|
|
89
|
+
# AI-GENERATED END: parse webhook payload
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
HTML / XML:
|
|
93
|
+
|
|
94
|
+
```html
|
|
95
|
+
<!-- AI-GENERATED START: login form -->
|
|
96
|
+
<form></form>
|
|
97
|
+
<!-- AI-GENERATED END: login form -->
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
CSS:
|
|
101
|
+
|
|
102
|
+
```css
|
|
103
|
+
/* AI-GENERATED START: card layout */
|
|
104
|
+
.card { display: grid; }
|
|
105
|
+
/* AI-GENERATED END: card layout */
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## 3) Enforcement Checklist
|
|
109
|
+
|
|
110
|
+
Before returning output, verify:
|
|
111
|
+
|
|
112
|
+
1. File header exists at top of each newly generated file.
|
|
113
|
+
2. Header includes filename, timestamp, AI creator, agent, and model.
|
|
114
|
+
3. Every newly generated code block has start and end markers.
|
|
115
|
+
4. Marker comment style matches target language.
|
|
116
|
+
5. Unchanged existing code was not backfilled with new markers/header.
|
|
117
|
+
6. New or modified files stay within ~500 lines.
|
|
118
|
+
7. New or modified lines do not exceed 120 columns unless unavoidable.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: compose, multiplatform, kmp
|
|
3
|
+
related: code-convention
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Compose Multiplatform Developer Reference
|
|
7
|
+
|
|
8
|
+
## Scope
|
|
9
|
+
|
|
10
|
+
Use this reference when creating skills for shared UI or multi-target UI with Compose Multiplatform.
|
|
11
|
+
|
|
12
|
+
## Core Stack
|
|
13
|
+
|
|
14
|
+
1. Compose Multiplatform for shared UI components where feasible.
|
|
15
|
+
2. Shared Kotlin module for domain, data, and presentation logic.
|
|
16
|
+
3. MVVM or MVI-compatible state management with shared state models.
|
|
17
|
+
|
|
18
|
+
## Implementation Rules
|
|
19
|
+
|
|
20
|
+
1. Keep platform-specific wrappers thin.
|
|
21
|
+
2. Reuse shared Kotlin models and use-cases across Android/iOS/Desktop targets.
|
|
22
|
+
3. Isolate platform APIs behind expect/actual or adapter boundaries.
|
|
23
|
+
4. Avoid duplicating business logic in platform UI modules.
|
|
24
|
+
|
|
25
|
+
## Deliverables Required in Skills
|
|
26
|
+
|
|
27
|
+
1. Shared composable component/screen example.
|
|
28
|
+
2. Platform adapter example (Android/iOS) calling shared logic.
|
|
29
|
+
3. Test plan for shared module and target-specific integration checks.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File: scripts/logger.js
|
|
3
|
+
* Created At: 2026-03-16 10:00:00 +07:00
|
|
4
|
+
* Created By: AI
|
|
5
|
+
* AI Agent: Claude
|
|
6
|
+
* Model: opus-4-6
|
|
7
|
+
*
|
|
8
|
+
* Skill workflow logger
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// AI-GENERATED START: logger utility
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
|
|
15
|
+
const SKILL_ROOT = path.resolve(__dirname, '..');
|
|
16
|
+
const LOG_DIR = path.join(SKILL_ROOT, 'output', 'logs');
|
|
17
|
+
|
|
18
|
+
function ensureLogDir() {
|
|
19
|
+
if (!fs.existsSync(LOG_DIR)) {
|
|
20
|
+
fs.mkdirSync(LOG_DIR, { recursive: true });
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getTimestamp() {
|
|
25
|
+
return new Date().toISOString();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function log(skillName, action, details = '') {
|
|
29
|
+
const timestamp = getTimestamp();
|
|
30
|
+
const message = `[${timestamp}] 🤖 ${skillName} | ${action} | ${details}`;
|
|
31
|
+
|
|
32
|
+
// Console output
|
|
33
|
+
console.log(message);
|
|
34
|
+
|
|
35
|
+
// File output
|
|
36
|
+
ensureLogDir();
|
|
37
|
+
const logFile = path.join(LOG_DIR, `${skillName}-${getTimestamp().split('T')[0]}.log`);
|
|
38
|
+
fs.appendFileSync(logFile, message + '\n');
|
|
39
|
+
|
|
40
|
+
return message;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function logWorkflow(skillName, steps) {
|
|
44
|
+
const timestamp = getTimestamp();
|
|
45
|
+
const workflowLog = {
|
|
46
|
+
skill: skillName,
|
|
47
|
+
timestamp,
|
|
48
|
+
steps
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
ensureLogDir();
|
|
52
|
+
const logFile = path.join(LOG_DIR, `${skillName}-workflow-${getTimestamp().split('T')[0]}.json`);
|
|
53
|
+
fs.appendFileSync(logFile, JSON.stringify(workflowLog, null, 2) + '\n');
|
|
54
|
+
|
|
55
|
+
return workflowLog;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
module.exports = {
|
|
59
|
+
log,
|
|
60
|
+
logWorkflow,
|
|
61
|
+
getTimestamp
|
|
62
|
+
};
|
|
63
|
+
// AI-GENERATED END: logger utility
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Badge validation rules
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
module.exports = [
|
|
6
|
+
{
|
|
7
|
+
id: 'badge-no-text',
|
|
8
|
+
category: 'Badge',
|
|
9
|
+
name: 'Badge uses "label" (not "text")',
|
|
10
|
+
severity: 'error',
|
|
11
|
+
applies: (content) => /\bBadge\s*\(/.test(content) && /vn\.momo\.kits/.test(content),
|
|
12
|
+
validate(content) {
|
|
13
|
+
if (/Badge\s*\([^)]*\btext\s*=/s.test(content)) {
|
|
14
|
+
return { passed: false, evidence: 'Badge has no "text" — use "label" instead' };
|
|
15
|
+
}
|
|
16
|
+
return { passed: true, evidence: 'Badge uses correct "label" param' };
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: 'badge-no-type',
|
|
21
|
+
category: 'Badge',
|
|
22
|
+
name: 'No BadgeType enum (does not exist)',
|
|
23
|
+
severity: 'error',
|
|
24
|
+
applies: (content) => /\bBadge\s*\(/.test(content) && /vn\.momo\.kits/.test(content),
|
|
25
|
+
validate(content) {
|
|
26
|
+
if (/BadgeType/.test(content)) {
|
|
27
|
+
return { passed: false, evidence: 'BadgeType does not exist — use backgroundColor: Color instead' };
|
|
28
|
+
}
|
|
29
|
+
return { passed: true, evidence: 'No invalid BadgeType usage' };
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BottomTab validation rules
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
module.exports = [
|
|
6
|
+
{
|
|
7
|
+
id: 'bottomtab-items',
|
|
8
|
+
category: 'BottomTab',
|
|
9
|
+
name: 'BottomTab uses BottomTabItem (not TabItem)',
|
|
10
|
+
severity: 'error',
|
|
11
|
+
applies: (content) => /\bBottomTab\s*\(/.test(content) && /vn\.momo\.kits/.test(content),
|
|
12
|
+
validate(content) {
|
|
13
|
+
if (/\bTabItem\s*\(/.test(content) && !/BottomTabItem/.test(content)) {
|
|
14
|
+
return { passed: false, evidence: 'TabItem does not exist — use BottomTabItem(name, label, icon, screen)' };
|
|
15
|
+
}
|
|
16
|
+
return { passed: true, evidence: 'BottomTab item type looks correct' };
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Button validation rules
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
module.exports = [
|
|
6
|
+
{
|
|
7
|
+
id: 'button-no-text',
|
|
8
|
+
category: 'Button',
|
|
9
|
+
name: 'Button uses "title" (not "text")',
|
|
10
|
+
severity: 'error',
|
|
11
|
+
applies: (content) => /\bButton\s*\(/.test(content) && /vn\.momo\.kits/.test(content),
|
|
12
|
+
validate(content) {
|
|
13
|
+
if (/Button\s*\([^)]*\btext\s*=/s.test(content)) {
|
|
14
|
+
return { passed: false, evidence: 'Button uses "text" — should be "title"' };
|
|
15
|
+
}
|
|
16
|
+
return { passed: true, evidence: 'Button uses correct param name' };
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: 'button-no-enabled',
|
|
21
|
+
category: 'Button',
|
|
22
|
+
name: 'Button has no "enabled" param',
|
|
23
|
+
severity: 'error',
|
|
24
|
+
applies: (content) => /\bButton\s*\(/.test(content) && /vn\.momo\.kits/.test(content),
|
|
25
|
+
validate(content) {
|
|
26
|
+
if (/Button\s*\([^)]*\benabled\s*=/s.test(content)) {
|
|
27
|
+
return { passed: false, evidence: 'Button has no "enabled" — use type = ButtonType.DISABLED instead' };
|
|
28
|
+
}
|
|
29
|
+
return { passed: true, evidence: 'No invalid "enabled" param on Button' };
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Card validation rules
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
module.exports = [
|
|
6
|
+
{
|
|
7
|
+
id: 'card-no-material-card',
|
|
8
|
+
category: 'Card',
|
|
9
|
+
name: 'Card from vn.momo.kits (not Material)',
|
|
10
|
+
severity: 'error',
|
|
11
|
+
applies: (content) => /\bCard\s*\(/.test(content) && /vn\.momo\.kits/.test(content),
|
|
12
|
+
validate(content) {
|
|
13
|
+
if (/import\s+androidx\.compose\.material[3]?\.Card/.test(content)) {
|
|
14
|
+
return { passed: false, evidence: 'Import Material Card — use vn.momo.kits layout Card instead' };
|
|
15
|
+
}
|
|
16
|
+
return { passed: true, evidence: 'Card import looks correct' };
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: 'card-cornerRadius',
|
|
21
|
+
category: 'Card',
|
|
22
|
+
name: 'Card uses cornerRadius (not shape)',
|
|
23
|
+
severity: 'error',
|
|
24
|
+
applies: (content) => /\bCard\s*\(/.test(content) && /vn\.momo\.kits/.test(content),
|
|
25
|
+
validate(content) {
|
|
26
|
+
if (/Card\s*\([^)]*\bshape\s*=/s.test(content)) {
|
|
27
|
+
return { passed: false, evidence: 'Card has no "shape" — use "cornerRadius = Radius.M" instead' };
|
|
28
|
+
}
|
|
29
|
+
return { passed: true, evidence: 'No invalid "shape" param on Card' };
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CheckBox validation rules
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
module.exports = [
|
|
6
|
+
{
|
|
7
|
+
id: 'checkbox-no-enabled',
|
|
8
|
+
category: 'CheckBox',
|
|
9
|
+
name: 'CheckBox uses "disabled" (not "enabled")',
|
|
10
|
+
severity: 'error',
|
|
11
|
+
applies: (content) => /\bCheckBox\s*\(/.test(content) && /vn\.momo\.kits/.test(content),
|
|
12
|
+
validate(content) {
|
|
13
|
+
if (/CheckBox\s*\([^)]*\benabled\s*=/s.test(content)) {
|
|
14
|
+
return { passed: false, evidence: 'CheckBox has no "enabled" — use "disabled = true" instead' };
|
|
15
|
+
}
|
|
16
|
+
return { passed: true, evidence: 'CheckBox uses correct "disabled" param' };
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: 'checkbox-no-modifier',
|
|
21
|
+
category: 'CheckBox',
|
|
22
|
+
name: 'CheckBox has no modifier param',
|
|
23
|
+
severity: 'warning',
|
|
24
|
+
applies: (content) => /\bCheckBox\s*\(/.test(content) && /vn\.momo\.kits/.test(content),
|
|
25
|
+
validate(content) {
|
|
26
|
+
if (/CheckBox\s*\([^)]*\bmodifier\s*=/s.test(content)) {
|
|
27
|
+
return { passed: false, evidence: 'CheckBox has no "modifier" param — wrap in Box with modifier instead' };
|
|
28
|
+
}
|
|
29
|
+
return { passed: true, evidence: 'No invalid modifier on CheckBox' };
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
];
|