ftc-android
Pixel-perfect Figma-to-Android implementation loop using ADB and Figma MCP
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Pixel-perfect Figma-to-Android implementation loop using ADB and Figma MCP
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | ftc-android |
| description | Pixel-perfect Figma-to-Android implementation loop using ADB and Figma MCP |
| allowed-tools | ["Bash","Read","Glob","Grep","Edit","Write"] |
Requisitos: Figma MCP configurado, Android Emulator corriendo, ADB disponible.
Si el Figma MCP falla (error, timeout, rate limit), DETENERSE INMEDIATAMENTE.
❌ MAL: MCP falla → continuar implementando con valores aproximados
✅ BIEN: MCP falla → STOP → informar al usuario → esperar resolución
El usuario debe saber si Figma no está funcionando. Sin datos de Figma, no hay pixel-perfect.
Minimizar llamadas al Figma MCP. Cada petición consume tiempo y recursos.
❌ MAL: get_screenshot → implementar → get_screenshot → comparar → get_screenshot...
✅ BIEN: get_screenshot (1 vez) → implementar → comparar con screenshot guardado → iterar
Verificar que estamos en un proyecto Android:
build.gradle.kts o build.gradle en raízapp/src/main/java/ o app/src/main/kotlin/ existeAndroidManifest.xml presentebuild.gradle.kts → Kotlin DSLbuild.gradle → Groovy DSLgradle/wrapper/gradle-wrapper.properties para versiónEscanear app/src/main/res/values/:
colors.xml → paleta de coloresdimens.xml → spacing/sizing tokensthemes.xml → tema principalstyles.xml → estilos de componentesEscanear dependencias en build.gradle.kts:
material3 → Material Design 3material → Material Design 2compose.ui → Jetpack ComposePaso 1: Verificar si hay emulador corriendo:
adb devices
Paso 2: Si NO hay emulador conectado (solo muestra "List of devices attached" sin dispositivos):
emulator -list-avds
emulator -avd <avd_name> -no-snapshot-load &
adb wait-for-device
adb shell getprop sys.boot_completed # Esperar hasta que retorne "1"
Paso 3: Obtener info del dispositivo:
adb shell wm size # Resolución (ej: 1080x2400)
adb shell wm density # Densidad (ej: 440)
Llamar whoami del Figma MCP para verificar autenticación.
Si falla: NO CONTINUAR. Informar al usuario y esperar resolución. Sin Figma MCP funcionando, este skill no puede ejecutarse.
Verificar si la app está instalada y corriendo:
adb shell pm list packages | grep <package.name>
adb shell pidof <package.name>
./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk
adb shell am start -n <package.name>/<activity.name>
Preguntar al usuario: "Pega el link de Figma del componente/pantalla que quieres implementar"
GUARDAR EL LINK: Escribir el link en un archivo para no perderlo:
echo "https://figma.com/..." > .figma-link
Si se pierde el contexto, leer de .figma-link. Nunca pedir el link dos veces al usuario.
Hacer todas las peticiones necesarias al inicio y no repetirlas:
get_metadata → jerarquía de componentesget_design_context → layout, spacing, estilosget_variable_defs → design tokens (colores, tipografía)get_screenshot → referencia visual (GUARDAR, no volver a pedir)Guardar el screenshot de Figma para comparaciones posteriores. No volver a llamar get_screenshot a menos que el usuario indique que el diseño cambió.
| Figma | Android |
|---|---|
| px (a 1x) | dp |
| px para texto | sp |
Fórmula: Si Figma está a 1x, los valores son directamente dp/sp.
Figma hex → Android:
colors.xml: <color name="primary">#FF6200EE</color>Color(0xFF6200EE)| Figma | Android XML | Compose |
|---|---|---|
| font-family | android:fontFamily | FontFamily |
| font-size | android:textSize="16sp" | fontSize = 16.sp |
| font-weight | android:textStyle="bold" | fontWeight = FontWeight.Bold |
| line-height | android:lineHeight | lineHeight = 24.sp |
| letter-spacing | android:letterSpacing | letterSpacing = 0.5.sp |
| Figma | Android XML | Compose |
|---|---|---|
| Auto Layout (vertical) | LinearLayout vertical | Column |
| Auto Layout (horizontal) | LinearLayout horizontal | Row |
| Frame | FrameLayout | Box |
| gap | android:layout_margin | Arrangement.spacedBy() |
| padding | android:padding | Modifier.padding() |
NO ASUMIR NADA. VERIFICAR TODO:
Texto:
Contenedores:
Imágenes/Iconos:
Escribir el código en:
app/src/main/kotlin/.../ui/app/src/main/res/layout/./gradlew assembleDebug && adb install -r app/build/outputs/apk/debug/app-debug.apk
Hot reload si está disponible (Compose con Live Edit).
Si necesitas navegar la app o encontrar elementos, usa los scripts de UIAutomator:
# Listar elementos interactivos de la pantalla
python scripts/ui_list.py
# Tap en elemento por texto
python scripts/ui_tap.py "Continuar"
python scripts/ui_tap.py "Iniciar sesión"
One-liner rápido (para probar sin scripts):
adb shell uiautomator dump /sdcard/ui.xml && adb pull /sdcard/ui.xml /tmp/ui.xml && grep -oP 'text="[^"]*"' /tmp/ui.xml | grep -v 'text=""' | sort -u
Guardar un mapa de navegación para no olvidar cómo acceder a cada pantalla:
# Crear/actualizar archivo de navegación
cat >> .app-navigation.md << 'EOF'
## Pantalla: Login
- Desde: Splash (automático después de 2s)
- Tap "Iniciar sesión": bounds=[50,800][350,860] → centro (200, 830)
## Pantalla: Home
- Desde: Login → tap "Entrar"
- Tab "Perfil": bounds=[900,2200][1080,2300] → centro (990, 2250)
- Tab "Buscar": bounds=[360,2200][540,2300] → centro (450, 2250)
## Pantalla: Perfil
- Desde: Home → tab "Perfil"
- Botón "Editar": texto="Editar perfil"
EOF
Cada vez que descubras una ruta de navegación, DOCUMENTARLA.
Si se pierde el contexto, leer .app-navigation.md para recordar cómo llegar a cada pantalla.
adb shell screencap -p /sdcard/screen.png
adb pull /sdcard/screen.png ./screen_android.png
adb shell rm /sdcard/screen.png
get_screenshot)screen_android.pngSi hay CUALQUIER discrepancia (incluso 1dp):
./gradlew assembleDebug && adb install -r ...includeFontPadding en TextView (default true, puede agregar espacio extra)clipToPadding y clipChildren en contenedoreswindowSoftInputMode puede mover contenidoMostrar screenshot final y preguntar: "Este es el resultado. ¿Coincide con tu expectativa?"
Si el usuario da otro link de Figma → volver a Phase 2. Si el usuario reporta diferencias → investigar y corregir.
# Dispositivos conectados
adb devices
# Screenshot
adb shell screencap -p /sdcard/s.png && adb pull /sdcard/s.png && adb shell rm /sdcard/s.png
# Tap en coordenadas
adb shell input tap <x> <y>
# Escribir texto
adb shell input text "<texto>"
# Scroll/Swipe
adb shell input swipe <x1> <y1> <x2> <y2> <duration_ms>
# Presionar botón
adb shell input keyevent <code> # BACK=4, HOME=3, ENTER=66
# Info de pantalla
adb shell wm size
adb shell wm density
# Abrir app
adb shell am start -n <package>/<activity>
# Cerrar app
adb shell am force-stop <package>
# Instalar APK
adb install -r <path.apk>
# Logcat filtrado
adb logcat -s <TAG>
Scripts para navegación de UI. Ver scripts/ para implementación.
# Listar elementos interactivos
python scripts/ui_list.py
# Tap por texto
python scripts/ui_tap.py "Texto del botón"
Propiedades del XML de UIAutomator:
text - texto visibleresource-id - ID único (ej: com.app:id/btn)bounds - coordenadas [left,top][right,bottom]clickable, enabled - estados# Build debug
./gradlew assembleDebug
# Build release
./gradlew assembleRelease
# Clean build
./gradlew clean assembleDebug
# Run tests
./gradlew test
# Lista de tareas
./gradlew tasks
ULTRA-THINK MODE: Tomarse el tiempo necesario. Perfección sobre velocidad. Un dp de diferencia es inaceptable.