ftc-android
Pixel-perfect Figma-to-Android implementation loop using ADB and Figma MCP
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Menu
Pixel-perfect Figma-to-Android implementation loop using ADB and Figma MCP
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Baseado na classificação ocupacional 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.