@momo-kits/native-kits 0.157.1-skill.3-debug → 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/compose/build.gradle.kts +1 -1
- package/gradle.properties +1 -1
- package/package.json +1 -1
- 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/local.properties +0 -8
- /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
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# File: scripts/test-on-device.sh
|
|
4
|
+
# Created At: 2026-03-16 10:00:00 +07:00
|
|
5
|
+
# Created By: AI
|
|
6
|
+
# AI Agent: Claude
|
|
7
|
+
# Model: opus-4-6
|
|
8
|
+
|
|
9
|
+
# Build & Test Script for MoMo Native Kits
|
|
10
|
+
# Usage: node scripts/test-on-device.js <kotlin-file>
|
|
11
|
+
#
|
|
12
|
+
# This script:
|
|
13
|
+
# 1. Validates the Kotlin file using validate-kits.js
|
|
14
|
+
# 2. Compiles the shared module
|
|
15
|
+
# 3. Builds debug APK
|
|
16
|
+
# 4. Installs and launches on Android emulator
|
|
17
|
+
# 5. Takes screenshot
|
|
18
|
+
|
|
19
|
+
# AI-GENERATED START: build and test workflow
|
|
20
|
+
set -e
|
|
21
|
+
|
|
22
|
+
# Colors
|
|
23
|
+
RED='\033[0;31m'
|
|
24
|
+
GREEN='\033[0;32m'
|
|
25
|
+
YELLOW='\033[1;33m'
|
|
26
|
+
NC='\033[0m' # No Color
|
|
27
|
+
|
|
28
|
+
PROJECT_ROOT="/Users/m1/Documents/MServices/Compose Kits"
|
|
29
|
+
EMULATOR_AVD="Pixel_9_Pro_XL"
|
|
30
|
+
SKILL_ROOT="$PROJECT_ROOT/.claude/skills/momo-native-kits-skills"
|
|
31
|
+
|
|
32
|
+
echo "=========================================="
|
|
33
|
+
echo " MoMo Native Kits - Build & Test"
|
|
34
|
+
echo "=========================================="
|
|
35
|
+
echo ""
|
|
36
|
+
|
|
37
|
+
# Check arguments
|
|
38
|
+
if [ -z "$1" ]; then
|
|
39
|
+
echo "Usage: node test-on-device.js <kotlin-file>"
|
|
40
|
+
echo "Example: node test-on-device.js sample/shared/src/commonMain/kotlin/screens/Test.kt"
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
KOTLIN_FILE="$1"
|
|
45
|
+
|
|
46
|
+
# Step 1: Validate
|
|
47
|
+
echo -e "${YELLOW}Step 1: Validating code...${NC}"
|
|
48
|
+
node "$SKILL_ROOT/scripts/validate-kits.js" "$KOTLIN_FILE"
|
|
49
|
+
VALIDATE_EXIT=$?
|
|
50
|
+
|
|
51
|
+
if [ $VALIDATE_EXIT -ne 0 ]; then
|
|
52
|
+
echo -e "${RED}Validation failed!${NC}"
|
|
53
|
+
exit 1
|
|
54
|
+
fi
|
|
55
|
+
echo -e "${GREEN}Validation passed!${NC}"
|
|
56
|
+
echo ""
|
|
57
|
+
|
|
58
|
+
# Step 2: Compile
|
|
59
|
+
echo -e "${YELLOW}Step 2: Compiling shared module...${NC}"
|
|
60
|
+
cd "$PROJECT_ROOT"
|
|
61
|
+
./gradlew :sample:shared:compileDebugKotlin --quiet
|
|
62
|
+
echo -e "${GREEN}Compilation successful!${NC}"
|
|
63
|
+
echo ""
|
|
64
|
+
|
|
65
|
+
# Step 3: Build APK
|
|
66
|
+
echo -e "${YELLOW}Step 3: Building debug APK...${NC}"
|
|
67
|
+
./gradlew :sample:androidApp:assembleDebug --quiet
|
|
68
|
+
echo -e "${GREEN}APK built!${NC}"
|
|
69
|
+
echo ""
|
|
70
|
+
|
|
71
|
+
APK_PATH="$PROJECT_ROOT/sample/androidApp/build/outputs/apk/debug/androidApp-debug.apk"
|
|
72
|
+
|
|
73
|
+
# Step 4: Check/Start emulator
|
|
74
|
+
echo -e "${YELLOW}Step 4: Checking emulator...${NC}"
|
|
75
|
+
EMULATOR_PID=$(pgrep -f "emulator.*$EMULATOR_AVD" || true)
|
|
76
|
+
|
|
77
|
+
if [ -z "$EMULATOR_PID" ]; then
|
|
78
|
+
echo "Starting emulator..."
|
|
79
|
+
"$HOME/Library/Android/sdk/emulator/emulator" -avd "$EMULATOR_AVD" -no-snapshot -no-audio -no-window &
|
|
80
|
+
EMULATOR_PID=$!
|
|
81
|
+
echo "Waiting for emulator to boot..."
|
|
82
|
+
sleep 20
|
|
83
|
+
else
|
|
84
|
+
echo "Emulator already running (PID: $EMULATOR_PID)"
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Wait for adb
|
|
88
|
+
echo "Waiting for device..."
|
|
89
|
+
sleep 2
|
|
90
|
+
|
|
91
|
+
# Step 5: Install APK
|
|
92
|
+
echo -e "${YELLOW}Step 5: Installing APK...${NC}"
|
|
93
|
+
$HOME/Library/Android/sdk/platform-tools/adb install -r "$APK_PATH"
|
|
94
|
+
echo -e "${GREEN}APK installed!${NC}"
|
|
95
|
+
echo ""
|
|
96
|
+
|
|
97
|
+
# Step 6: Launch app
|
|
98
|
+
echo -e "${YELLOW}Step 6: Launching app...${NC}"
|
|
99
|
+
$HOME/Library/Android/sdk/platform-tools/adb shell am start -n "com.myapplication.MyApplication/com.myapplication.MainActivity" 2>/dev/null || true
|
|
100
|
+
|
|
101
|
+
# Give app time to start
|
|
102
|
+
sleep 3
|
|
103
|
+
|
|
104
|
+
# Step 7: Screenshot
|
|
105
|
+
echo -e "${YELLOW}Step 7: Taking screenshot...${NC}"
|
|
106
|
+
$HOME/Library/Android/sdk/platform-tools/adb exec-out screencap -p > /tmp/test-result.png
|
|
107
|
+
|
|
108
|
+
echo ""
|
|
109
|
+
echo "=========================================="
|
|
110
|
+
echo -e "${GREEN} Build & Test Complete!${NC}"
|
|
111
|
+
echo "=========================================="
|
|
112
|
+
echo ""
|
|
113
|
+
echo "Screenshot saved to: /tmp/test-result.png"
|
|
114
|
+
echo ""
|
|
115
|
+
echo "To view screenshot, run:"
|
|
116
|
+
echo " open /tmp/test-result.png"
|
|
117
|
+
# AI-GENERATED END: build and test workflow
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File: scripts/test-runner.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
|
+
* Test runner for MoMo Native Kits skill
|
|
9
|
+
* Runs validation on test files and generates report
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// AI-GENERATED START: test runner
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const { execSync } = require('child_process');
|
|
16
|
+
|
|
17
|
+
const SKILL_ROOT = path.resolve(__dirname, '..');
|
|
18
|
+
const OUTPUT_DIR = path.join(SKILL_ROOT, 'output');
|
|
19
|
+
const TESTS_DIR = path.join(OUTPUT_DIR, 'tests');
|
|
20
|
+
|
|
21
|
+
// Test cases - each component to test
|
|
22
|
+
const TEST_CASES = [
|
|
23
|
+
{ name: 'Button', ref: 'button.md', rules: ['button'] },
|
|
24
|
+
{ name: 'Input', ref: 'input.md', rules: ['input'] },
|
|
25
|
+
{ name: 'CheckBox', ref: 'checkbox.md', rules: ['checkbox'] },
|
|
26
|
+
{ name: 'Radio', ref: 'radio.md', rules: ['radio'] },
|
|
27
|
+
{ name: 'Switch', ref: 'switch.md', rules: ['switch'] },
|
|
28
|
+
{ name: 'Text', ref: 'text.md', rules: ['text'] },
|
|
29
|
+
{ name: 'Chip', ref: 'chip.md', rules: ['chip'] },
|
|
30
|
+
{ name: 'Badge', ref: 'badge.md', rules: ['badge'] },
|
|
31
|
+
{ name: 'Skeleton', ref: 'skeleton.md', rules: ['skeleton'] },
|
|
32
|
+
{ name: 'Card', ref: 'card.md', rules: ['card'] },
|
|
33
|
+
{ name: 'Divider', ref: 'divider.md', rules: ['divider'] },
|
|
34
|
+
{ name: 'Popup', ref: 'popup.md', rules: ['popup'] },
|
|
35
|
+
{ name: 'SnackBar', ref: 'snackbar.md', rules: ['snackbar'] },
|
|
36
|
+
{ name: 'Tooltip', ref: 'tooltip.md', rules: ['tooltip'] },
|
|
37
|
+
{ name: 'TrustBanner', ref: 'trustbanner.md', rules: ['trustbanner'] },
|
|
38
|
+
{ name: 'Navigation', ref: 'navigation.md', rules: ['navigation', 'bottomtab'] },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
function ensureDir(dir) {
|
|
42
|
+
if (!fs.existsSync(dir)) {
|
|
43
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function runValidation(filePath) {
|
|
48
|
+
try {
|
|
49
|
+
const result = execSync(
|
|
50
|
+
`node "${SKILL_ROOT}/scripts/validate-kits.js" "${filePath}"`,
|
|
51
|
+
{ encoding: 'utf-8', stdio: 'pipe' }
|
|
52
|
+
);
|
|
53
|
+
return { success: true, output: result };
|
|
54
|
+
} catch (error) {
|
|
55
|
+
return { success: false, output: error.stdout || error.message };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function generateReport() {
|
|
60
|
+
console.log('\n' + '='.repeat(60));
|
|
61
|
+
console.log('🧪 MoMo Native Kits - Skill Test Report');
|
|
62
|
+
console.log('='.repeat(60));
|
|
63
|
+
console.log(`Date: ${new Date().toISOString()}`);
|
|
64
|
+
console.log(`Total Components: ${TEST_CASES.length}`);
|
|
65
|
+
console.log('='.repeat(60));
|
|
66
|
+
|
|
67
|
+
// Check if validation script exists
|
|
68
|
+
const validateScript = path.join(SKILL_ROOT, 'scripts', 'validate-kits.js');
|
|
69
|
+
if (!fs.existsSync(validateScript)) {
|
|
70
|
+
console.log('\n⚠️ Validation script not found!');
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Test each rule file
|
|
75
|
+
const rulesDir = path.join(SKILL_ROOT, 'scripts', 'rules');
|
|
76
|
+
let rulesPassed = 0;
|
|
77
|
+
let rulesTotal = 0;
|
|
78
|
+
|
|
79
|
+
const ruleFiles = fs.readdirSync(rulesDir).filter(f => f.endsWith('.js') && f !== 'index.js');
|
|
80
|
+
|
|
81
|
+
console.log('\n📋 Validation Rules:');
|
|
82
|
+
console.log('-'.repeat(60));
|
|
83
|
+
|
|
84
|
+
for (const file of ruleFiles) {
|
|
85
|
+
rulesTotal++;
|
|
86
|
+
const filePath = path.join(rulesDir, file);
|
|
87
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
88
|
+
|
|
89
|
+
// Check if rule has required fields (using simple string check)
|
|
90
|
+
const hasId = content.includes('id:');
|
|
91
|
+
const hasValidate = content.includes('validate');
|
|
92
|
+
const hasModuleExport = content.includes('module.exports');
|
|
93
|
+
|
|
94
|
+
if (hasId && hasValidate && hasModuleExport) {
|
|
95
|
+
rulesPassed++;
|
|
96
|
+
console.log(`✅ ${file}`);
|
|
97
|
+
} else {
|
|
98
|
+
console.log(`❌ ${file} (missing required fields)`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
console.log('-'.repeat(60));
|
|
103
|
+
console.log(`Rules: ${rulesPassed}/${rulesTotal} valid`);
|
|
104
|
+
|
|
105
|
+
// Check references
|
|
106
|
+
console.log('\n📄 References:');
|
|
107
|
+
console.log('-'.repeat(60));
|
|
108
|
+
|
|
109
|
+
const refDirs = [
|
|
110
|
+
{ dir: 'form-controls/references', skill: 'form-controls' },
|
|
111
|
+
{ dir: 'data-display/references', skill: 'data-display' },
|
|
112
|
+
{ dir: 'layout/references', skill: 'layout' },
|
|
113
|
+
{ dir: 'feedback/references', skill: 'feedback' },
|
|
114
|
+
{ dir: 'navigation/references', skill: 'navigation' },
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
let refsTotal = 0;
|
|
118
|
+
let refsPassed = 0;
|
|
119
|
+
|
|
120
|
+
for (const ref of refDirs) {
|
|
121
|
+
const refDir = path.join(SKILL_ROOT, ref.dir);
|
|
122
|
+
if (fs.existsSync(refDir)) {
|
|
123
|
+
const files = fs.readdirSync(refDir).filter(f => f.endsWith('.md'));
|
|
124
|
+
refsTotal += files.length;
|
|
125
|
+
refsPassed += files.length;
|
|
126
|
+
console.log(`✅ ${ref.skill}: ${files.length} files`);
|
|
127
|
+
} else {
|
|
128
|
+
console.log(`❌ ${ref.skill}: not found`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
console.log('-'.repeat(60));
|
|
133
|
+
console.log(`References: ${refsPassed}/${refsTotal} files`);
|
|
134
|
+
|
|
135
|
+
// Summary
|
|
136
|
+
console.log('\n' + '='.repeat(60));
|
|
137
|
+
console.log('📊 Summary:');
|
|
138
|
+
console.log('-'.repeat(60));
|
|
139
|
+
console.log(`✅ Validation Rules: ${rulesPassed}/${rulesTotal}`);
|
|
140
|
+
console.log(`✅ References: ${refsPassed}/${refsTotal}`);
|
|
141
|
+
console.log(`📁 Skill Root: ${SKILL_ROOT}`);
|
|
142
|
+
console.log('='.repeat(60));
|
|
143
|
+
|
|
144
|
+
// Save report
|
|
145
|
+
ensureDir(OUTPUT_DIR);
|
|
146
|
+
const report = {
|
|
147
|
+
timestamp: new Date().toISOString(),
|
|
148
|
+
rules: { passed: rulesPassed, total: rulesTotal },
|
|
149
|
+
references: { passed: refsPassed, total: refsTotal },
|
|
150
|
+
testCases: TEST_CASES.length
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
fs.writeFileSync(
|
|
154
|
+
path.join(OUTPUT_DIR, 'test-report.json'),
|
|
155
|
+
JSON.stringify(report, null, 2)
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
console.log(`\n📁 Report saved to: ${path.join(OUTPUT_DIR, 'test-report.json')}`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Run if called directly
|
|
162
|
+
if (require.main === module) {
|
|
163
|
+
generateReport();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
module.exports = { generateReport, TEST_CASES };
|
|
167
|
+
// AI-GENERATED END: test runner
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* File: scripts/validate-kits.js
|
|
5
|
+
* Created At: 2026-03-16 10:00:00 +07:00
|
|
6
|
+
* Created By: AI
|
|
7
|
+
* AI Agent: Claude
|
|
8
|
+
* Model: opus-4-6
|
|
9
|
+
*
|
|
10
|
+
* Validate MoMo Native Kits component usage in Kotlin/Compose files
|
|
11
|
+
*
|
|
12
|
+
* Checks generated code against real API rules for all components.
|
|
13
|
+
* Runs after code generation to catch wrong imports, wrong params, and Material usage.
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* node validate-kits.js <file-path>
|
|
17
|
+
*
|
|
18
|
+
* Output: Table of results + JSON report
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
// AI-GENERATED START: validation runner
|
|
22
|
+
const fs = require('fs');
|
|
23
|
+
const path = require('path');
|
|
24
|
+
|
|
25
|
+
const SKILL_ROOT = path.resolve(__dirname, '..');
|
|
26
|
+
const OUTPUT_DIR = path.join(SKILL_ROOT, 'output');
|
|
27
|
+
|
|
28
|
+
// Import rules from separate files
|
|
29
|
+
const rules = require('./rules');
|
|
30
|
+
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// RUNNER
|
|
33
|
+
// ============================================================================
|
|
34
|
+
|
|
35
|
+
function validateFile(filePath) {
|
|
36
|
+
const absolutePath = path.isAbsolute(filePath) ? filePath : path.resolve(filePath);
|
|
37
|
+
|
|
38
|
+
if (!fs.existsSync(absolutePath)) {
|
|
39
|
+
console.error(`File not found: ${absolutePath}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const content = fs.readFileSync(absolutePath, 'utf-8');
|
|
44
|
+
const relativePath = path.relative(process.cwd(), absolutePath);
|
|
45
|
+
|
|
46
|
+
const results = [];
|
|
47
|
+
|
|
48
|
+
for (const rule of rules) {
|
|
49
|
+
// Skip rules that don't apply to this file
|
|
50
|
+
if (rule.applies && !rule.applies(content)) continue;
|
|
51
|
+
|
|
52
|
+
const result = rule.validate(content);
|
|
53
|
+
results.push({
|
|
54
|
+
id: rule.id,
|
|
55
|
+
category: rule.category,
|
|
56
|
+
name: rule.name,
|
|
57
|
+
severity: rule.severity,
|
|
58
|
+
...result,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const passed = results.filter(r => r.passed);
|
|
63
|
+
const failed = results.filter(r => !r.passed);
|
|
64
|
+
const errors = failed.filter(r => r.severity === 'error');
|
|
65
|
+
const warnings = failed.filter(r => r.severity === 'warning');
|
|
66
|
+
|
|
67
|
+
// ── Print Results Table ──
|
|
68
|
+
console.log(`\n🔍 MoMo Native Kits Validation: ${relativePath}\n`);
|
|
69
|
+
console.log('┌─────────────────┬────────────────────────────────────────────┬────────┐');
|
|
70
|
+
console.log('│ Category │ Rule │ Result │');
|
|
71
|
+
console.log('├─────────────────┼────────────────────────────────────────────┼────────┤');
|
|
72
|
+
|
|
73
|
+
for (const r of results) {
|
|
74
|
+
const icon = r.passed ? '✅' : (r.severity === 'error' ? '❌' : '⚠️');
|
|
75
|
+
const cat = r.category.padEnd(15);
|
|
76
|
+
const name = r.name.length > 42 ? r.name.substring(0, 39) + '...' : r.name.padEnd(42);
|
|
77
|
+
console.log(`│ ${cat} │ ${name} │ ${icon} │`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
console.log('└─────────────────┴────────────────────────────────────────────┴────────┘');
|
|
81
|
+
|
|
82
|
+
// ── Print Failed Details ──
|
|
83
|
+
if (failed.length > 0) {
|
|
84
|
+
console.log('\n📋 Issues:');
|
|
85
|
+
for (const r of failed) {
|
|
86
|
+
const icon = r.severity === 'error' ? '❌' : '⚠️';
|
|
87
|
+
console.log(` ${icon} [${r.category}] ${r.name}`);
|
|
88
|
+
console.log(` → ${r.evidence}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ── Summary ──
|
|
93
|
+
console.log('\n' + '═'.repeat(60));
|
|
94
|
+
console.log(`📊 Summary: ${passed.length} passed, ${errors.length} errors, ${warnings.length} warnings`);
|
|
95
|
+
console.log('═'.repeat(60));
|
|
96
|
+
|
|
97
|
+
// ── Save JSON ──
|
|
98
|
+
if (!fs.existsSync(OUTPUT_DIR)) {
|
|
99
|
+
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const output = {
|
|
103
|
+
file: relativePath,
|
|
104
|
+
validatedAt: new Date().toISOString(),
|
|
105
|
+
summary: {
|
|
106
|
+
total: results.length,
|
|
107
|
+
passed: passed.length,
|
|
108
|
+
errors: errors.length,
|
|
109
|
+
warnings: warnings.length,
|
|
110
|
+
},
|
|
111
|
+
results,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const outputPath = path.join(OUTPUT_DIR, 'validation-result.json');
|
|
115
|
+
fs.writeFileSync(outputPath, JSON.stringify(output, null, 2));
|
|
116
|
+
console.log(`\n📁 Report: ${outputPath}\n`);
|
|
117
|
+
|
|
118
|
+
return output;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// CLI
|
|
122
|
+
const args = process.argv.slice(2);
|
|
123
|
+
if (args.length === 0) {
|
|
124
|
+
console.log('Usage: node validate-kits.js <kotlin-file-path>');
|
|
125
|
+
console.log('Example: node validate-kits.js src/screens/MyScreen.kt');
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const result = validateFile(args[0]);
|
|
130
|
+
process.exit(result.summary.errors > 0 ? 1 : 0);
|
|
131
|
+
// AI-GENERATED END: validation runner
|
package/.momo-agent.json
ADDED
package/compose/build.gradle.kts
CHANGED
package/gradle.properties
CHANGED
package/package.json
CHANGED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: momo-native-kits-skills
|
|
3
|
-
description: |
|
|
4
|
-
MoMo Native Kits UI Component Rendering - Generate correct, production-ready Kotlin/Compose code for MoMo UI Kit components.
|
|
5
|
-
|
|
6
|
-
Use when:
|
|
7
|
-
- User says "tạo button", "tạo nút bấm", "button component", "primary button"
|
|
8
|
-
- User says "tạo input", "tạo ô nhập liệu", "text field", "form input", "nhập số điện thoại"
|
|
9
|
-
- User says "tạo search", "ô tìm kiếm", "input search", "tìm kiếm"
|
|
10
|
-
- User says "tạo checkbox", "ô tick", "checkbox"
|
|
11
|
-
- User says "tạo radio", "nút chọn", "radio button"
|
|
12
|
-
- User says "tạo switch", "nút gạt", "toggle", "bật/tắt"
|
|
13
|
-
- User says "tạo chip", "chip", "label"
|
|
14
|
-
- User says "tạo card", "thẻ", "khung"
|
|
15
|
-
- User says "tạo divider", "đường kẻ", "phân cách", "line"
|
|
16
|
-
- User says "tạo skeleton", "loading view"
|
|
17
|
-
- User says "tạo badge", "thông báo", "nhãn", "nhãn hiệu"
|
|
18
|
-
- User says "tạo popup", "thông báo", "alert", "xác nhận"
|
|
19
|
-
- User says "tạo snackbar", "toast", "thông báo ngắn", "message"
|
|
20
|
-
- User says "tạo tooltip", "gợi ý", "help", "hướng dẫn"
|
|
21
|
-
- User says "tạo trustbanner", "bảo mật", "trust"
|
|
22
|
-
- User says "tạo navigation", "điều hướng", "Bottom Tab", "BottomNavigation", "tab bar"
|
|
23
|
-
- User says "NavigationContainer", "setOptions", "navigator.push", "pop", "present"
|
|
24
|
-
- User says "Header", "tiêu đề", "app bar", "header type"
|
|
25
|
-
- User says "Text", "Title", "typography", "font", "chữ"
|
|
26
|
-
- User says "màu sắc", "colors", "Spacing", "Radius", "theme"
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
# MoMo Native Kits UI Components
|
|
30
|
-
|
|
31
|
-
## Reference Files
|
|
32
|
-
|
|
33
|
-
| File | Description |
|
|
34
|
-
|------|-------------|
|
|
35
|
-
| [button.md](references/button.md) | Button - nút bấm |
|
|
36
|
-
| [input.md](references/input.md) | Input - các loại input |
|
|
37
|
-
| [text.md](references/text.md) | Text, Title, Typography |
|
|
38
|
-
| [checkbox.md](references/checkbox.md) | CheckBox - ô tick |
|
|
39
|
-
| [radio.md](references/radio.md) | Radio - nút chọn |
|
|
40
|
-
| [switch.md](references/switch.md) | Switch - nút gạt |
|
|
41
|
-
| [chip.md](references/chip.md) | Chip - tag, label |
|
|
42
|
-
| [card.md](references/card.md) | Card - thẻ, khung |
|
|
43
|
-
| [divider.md](references/divider.md) | Divider - đường kẻ |
|
|
44
|
-
| [skeleton.md](references/skeleton.md) | Skeleton - loading |
|
|
45
|
-
| [badge.md](references/badge.md) | Badge, BadgeDot |
|
|
46
|
-
| [trustbanner.md](references/trustbanner.md) | TrustBanner, Information |
|
|
47
|
-
| [popup.md](references/popup.md) | PopupNotify, PopupPromotion |
|
|
48
|
-
| [snackbar.md](references/snackbar.md) | SnackBar |
|
|
49
|
-
| [tooltip.md](references/tooltip.md) | Tooltip |
|
|
50
|
-
| [navigation.md](references/navigation.md) | Navigation, BottomTab, Header |
|
|
51
|
-
| [constants.md](references/constants.md) | Colors, Radius, Spacing, Typography |
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"skill_name": "momo-native-kits-skills",
|
|
3
|
-
"evals": [
|
|
4
|
-
{
|
|
5
|
-
"id": 1,
|
|
6
|
-
"prompt": "Show me how to create a primary button with text 'Đăng nhập' in MoMo Native Kits",
|
|
7
|
-
"expected_output": "Kotlin code for Button component with ButtonType.PRIMARY, title='Đăng nhập', proper imports from vn.momo.kits.components",
|
|
8
|
-
"files": []
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
"id": 2,
|
|
12
|
-
"prompt": "I need an input field for phone number with label 'Số điện thoại' and placeholder 'Nhập số điện thoại'",
|
|
13
|
-
"expected_output": "Kotlin code for Input component with label, placeholder, and keyboard type for phone",
|
|
14
|
-
"files": []
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"id": 3,
|
|
18
|
-
"prompt": "How do I implement a bottom tab navigation with 4 tabs: Home, Wallet, History, Profile in MoMo app?",
|
|
19
|
-
"expected_output": "Kotlin code for BottomTab with BottomTabItem list, proper navigation setup",
|
|
20
|
-
"files": []
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
"id": 4,
|
|
24
|
-
"prompt": "Create a checkbox component for terms and conditions agreement",
|
|
25
|
-
"expected_output": "Kotlin code for CheckBox with label 'Tôi đồng ý với điều khoản'",
|
|
26
|
-
"files": []
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
"id": 5,
|
|
30
|
-
"prompt": "Show me how to use the DateTimePicker component for date selection",
|
|
31
|
-
"expected_output": "Kotlin code for DateTimePicker with selectedDate, onDateSelected parameters",
|
|
32
|
-
"files": []
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"id": 6,
|
|
36
|
-
"prompt": "I need a search input field like the one in MoMo app",
|
|
37
|
-
"expected_output": "Kotlin code for InputSearch component with placeholder 'Tìm kiếm...'",
|
|
38
|
-
"files": []
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
"id": 7,
|
|
42
|
-
"prompt": "How to create a modal screen in MoMo Native Kits?",
|
|
43
|
-
"expected_output": "Kotlin code for ModalScreen with onDismiss handler",
|
|
44
|
-
"files": []
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
"id": 8,
|
|
48
|
-
"prompt": "Create a switch component for toggling dark mode",
|
|
49
|
-
"expected_output": "Kotlin code for Switch component with checked state and onCheckedChange callback",
|
|
50
|
-
"files": []
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"id": 9,
|
|
54
|
-
"prompt": "How to use setOptions in MoMo navigation? Show me how to change header title dynamically",
|
|
55
|
-
"expected_output": "Kotlin code showing setOptions in LaunchedEffect(Unit) with LocalNavigation.current",
|
|
56
|
-
"files": []
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"id": 10,
|
|
60
|
-
"prompt": "Create a login form with phone input and password input in MoMo Native Kits",
|
|
61
|
-
"expected_output": "Kotlin code with InputPhoneNumber, Input (password), and Button components",
|
|
62
|
-
"files": []
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
"id": 11,
|
|
66
|
-
"prompt": "How to implement NavigationContainer in MoMo app? Show me the correct pattern",
|
|
67
|
-
"expected_output": "Kotlin code with single NavigationContainer, initialScreen, and NavigationOptions",
|
|
68
|
-
"files": []
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
"id": 12,
|
|
72
|
-
"prompt": "Create a card component to display a list item with image and title",
|
|
73
|
-
"expected_output": "Kotlin code for Card with Image and Title inside",
|
|
74
|
-
"files": []
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
"id": 13,
|
|
78
|
-
"prompt": "Show me how to use Navigator to push and pop screens in MoMo",
|
|
79
|
-
"expected_output": "Kotlin code showing navigator.push(), navigator.pop(), navigator.present()",
|
|
80
|
-
"files": []
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
"id": 14,
|
|
84
|
-
"prompt": "Create a loading skeleton for a card component",
|
|
85
|
-
"expected_output": "Kotlin code with Skeleton components showing loading state",
|
|
86
|
-
"files": []
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
"id": 15,
|
|
90
|
-
"prompt": "How to show a popup notification for success message in MoMo?",
|
|
91
|
-
"expected_output": "Kotlin code with PopupNotify and PopupNotifyProps",
|
|
92
|
-
"files": []
|
|
93
|
-
}
|
|
94
|
-
]
|
|
95
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"metadata": {
|
|
3
|
-
"skill_name": "momo-native-kits-skills",
|
|
4
|
-
"skill_path": "<path/to/skill>",
|
|
5
|
-
"executor_model": "<model-name>",
|
|
6
|
-
"analyzer_model": "<model-name>",
|
|
7
|
-
"timestamp": "2026-03-16T07:03:41Z",
|
|
8
|
-
"evals_run": [],
|
|
9
|
-
"runs_per_configuration": 3
|
|
10
|
-
},
|
|
11
|
-
"runs": [],
|
|
12
|
-
"run_summary": {
|
|
13
|
-
"delta": {
|
|
14
|
-
"pass_rate": "+0.00",
|
|
15
|
-
"time_seconds": "+0.0",
|
|
16
|
-
"tokens": "+0"
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"notes": []
|
|
20
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# Skill Benchmark: momo-native-kits-skills
|
|
2
|
-
|
|
3
|
-
**Model**: <model-name>
|
|
4
|
-
**Date**: 2026-03-16T07:03:41Z
|
|
5
|
-
**Evals**: (3 runs each per configuration)
|
|
6
|
-
|
|
7
|
-
## Summary
|
|
8
|
-
|
|
9
|
-
| Metric | Config A | Config B | Delta |
|
|
10
|
-
|--------|------------|---------------|-------|
|
|
11
|
-
| Pass Rate | 0% ± 0% | 0% ± 0% | +0.00 |
|
|
12
|
-
| Time | 0.0s ± 0.0s | 0.0s ± 0.0s | +0.0s |
|
|
13
|
-
| Tokens | 0 ± 0 | 0 ± 0 | +0 |
|