.agents/skills/image-to-code/SKILL.md
Converts a reference image (screenshot, mockup, or design file) into Flutter code that faithfully replicates the visual. Use whenever the user attaches an image and asks to replicate, implement, or convert a design — even with phrases like 'implement this screen', 'build this UI', 'convert this mockup to Flutter', 'make it look like this', 'match this design', 'here is the reference image', 'analyze the attached image', 'analyze this image', 'implement according to the image', 'use this image as reference', 'here is the image', 'see the attached image', or 'implement from this image'. Always activate when an image is the primary input for a UI task. The skill inspects the project's design system (theme, tokens, colors, typography) before writing any code, then analyzes the image systematically before coding — it does NOT guess, correct, or upgrade the design.
npx skillsauth add andrelucassvt/CleanMacForDevsWeb image-to-codeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Skill especializada em converter imagens de referência (mockups, screenshots, protótipos) em código Flutter fiel ao visual, respeitando o design system existente do projeto.
Princípio central: o código deve espelhar o que está na imagem — não o que parece "melhor" ou "mais correto". Quaisquer diferenças devem ser reportadas explicitamente.
Antes de qualquer análise da imagem, leia o que o projeto já define. Isso evita reinventar tokens que já existem.
lib/
├── common/styles/ # Tema principal, cores, tipografia
│ ├── app_theme.dart
│ ├── app_colors.dart
│ ├── app_text_styles.dart
│ └── app_spacing.dart (ou similar)
├── config/
│ └── app_initializer.dart # pode referenciar o tema
└── l10n/ # strings — use as chaves existentes
Execute estas leituras antes de avançar:
lib/common/styles/** — listar arquivos de estilolib/**/theme*.dart e lib/**/*colors*.dart — encontrar tokens de corlib/**/*text_style*.dart ou lib/**/*typography*.dart — encontrar estilos de textoapp_spacing.dart, app_radius.dart) — lê-losConstrua um mapa mental:
| Token | Valor | Uso no projeto |
|---|---|---|
| AppColors.primary | #FF5733 | Botões primários |
| AppTextStyles.heading1 | 24px, bold | Títulos de tela |
| Spacing padrão | 8, 16, 24, 32 | Padding/margin |
| Border radius padrão | 8 ou 12 | Cards, botões |
Se o projeto não tiver design system formal, registre isso e use valores literais (const Color(0xFF...), const TextStyle(fontSize: ...)) extraídos diretamente da imagem.
Analise a imagem antes de escrever uma linha de código. Documente cada dimensão abaixo.
Para cada cor visível, registre:
| Elemento | Cor aproximada (hex) | Token do projeto? |
|---|---|---|
| Background | #F5F5F5 | AppColors.background ✅ |
| Botão primário | #FF5733 | AppColors.primary ✅ |
| Texto principal | #1A1A1A | Literal (sem token) |
Não invente nomes. Se a cor da imagem não corresponde a nenhum token, use o valor literal.
Para cada bloco de texto, registre:
| Elemento | Tamanho estimado | Peso | Cor | Token? |
|---|---|---|---|---|
| Título | ~24px | bold (700) | #1A1A1A | AppTextStyles.heading1? |
| Subtítulo | ~14px | regular (400) | #666666 | Literal |
| Label botão | ~16px | semibold (600) | #FFFFFF | Literal |
Arredonde para o grid de 8 mais próximo. Prefira tokens de spacing do projeto se existirem.
Liste cada componente visível:
[ ] AppBar com título + ícone de voltar
[ ] Card com sombra (elevation ~4)
[ ] Avatar circular (raio ~24px)
[ ] Botão primário arredondado
[ ] Campo de texto com border outlined
[ ] Ícone (identificar qual — ex: Settings, chevron_right)
[ ] Divider entre itens
[ ] Badge/chip
[ ] Imagem/thumbnail
Para cada componente, decida: usar widget padrão do Flutter ou widget existente do projeto (common/widgets/)?
Antes de implementar, monte o plano:
Imagem mostra tela inteira?
├── SIM → criar View completa (implement-view)
│ + Cubit + State + rota + DI
└── NÃO → criar Widget isolado (implement-widget)
├── Reutilizável entre features? → common/widgets/
├── Específico de uma feature? → presentation/<feature>/widgets/
└── Auxiliar de uma View específica? → presentation/<feature>/content/
Componentes complexos da imagem (ex: card com múltiplas seções, lista com itens customizados) → extrair para widgets separados nos diretórios acima.
Cores: use exatamente as cores da imagem. Se existe token equivalente, use o token. Se não, use literal const Color(0xFF...). Nunca substitua por uma cor "parecida" do tema.
Tipografia: use os tamanhos e pesos observados. Se existe TextStyle equivalente, use. Se não, declare literalmente. Nunca arredonde para cima ou troque FontWeight.w600 por FontWeight.bold por conta própria.
Espaçamentos: use os valores estimados. Prefira múltiplos de 8. Nunca normalize espaçamentos por estética própria.
Componentes: use o widget Flutter mais próximo ao visual. Nunca substitua um OutlinedButton por ElevatedButton por parecer "melhor".
Layout: replique a estrutura exata (Column, Row, Stack). Nunca reorganize para "ficar mais responsivo" sem ser solicitado.
package:base_app/...context.l10n.<chave> (verifique se a chave existe; se não existir, registre como diferença)SafeArea; SEMPRE StatefulWidget; cubit via AppInjectorconst no construtor; final em todos os camposWidget _buildXxx() na View — extraia para content/ ou widgets/// 1. Widget folha (mais interno)
class _ItemCard extends StatelessWidget { ... }
// 2. Seção/conteúdo auxiliar
class _BodyContent extends StatelessWidget { ... }
// → salvo em content/<feature>_body_content.dart
// 3. View (se tela inteira)
class FeatureView extends StatefulWidget { ... }
Ao final da implementação, inclua sempre este relatório:
## Relatório de Fidelidade Visual
### ✅ Replicado com precisão
- [lista o que foi implementado exatamente como na imagem]
### ⚠️ Diferenças e motivos
| O que diferiu | Por que diferiu |
|---|---|
| Fonte não identificada → usando padrão do sistema | Família tipográfica não especificada na imagem |
| Imagem de avatar → usando placeholder | Não há asset real no projeto |
| Chave de i18n inexistente → string literal temporária | `l10n.profileTitle` não existe; registrar para adição futura |
| Sombra estimada (elevation 4) | Valor exato não mensurável em screenshot |
### ℹ️ Decisões tomadas
- [explique escolhas onde havia ambiguidade]
Se não houver diferenças, diga explicitamente: "Nenhuma diferença identificada — implementação fiel ao visual."
| Erro | Correto |
|---|---|
| Usar AppColors.primary quando a cor da imagem é diferente | Usar literal const Color(0xFF...) ou registrar divergência |
| Trocar OutlinedButton por ElevatedButton "por ser mais moderno" | Usar o componente que corresponde visualmente à imagem |
| Escrever Text('Título') hardcoded | Text(context.l10n.featureTitle) — ou registrar a chave como pendente |
| Omitir SafeArea em tela cheia | Sempre envolver o corpo principal com SafeArea |
| Criar Widget _buildHeader() na View | Extrair para content/feature_header.dart |
| Reorganizar layout "para ficar mais responsivo" | Implementar exatamente como está na imagem |
Última atualização: 13 de abril de 2026
testing
Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy. Activate even when the user says 'create a skill for X', 'the skill is not triggering', 'improve this skill description', 'the agent is not using the skill', 'add a skill to teach the agent how to do X', 'this skill is wrong', or 'update the skill' without explicitly mentioning evals or benchmark.
development
Implements Flutter reusable widgets following the project architecture. Use whenever creating or modifying widgets in presentation/<feature>/widgets/, presentation/<feature>/content/, or common/widgets/. Covers StatelessWidget vs StatefulWidget decision, Entity as parameter, i18n, dispose, componentization rules, and when to access the Cubit via context.read. Activate even when the user says 'extract this to a widget', 'create a list item widget', 'build a reusable card', 'factor out this UI block', 'create a component for this', or 'this View is getting too big' without explicitly mentioning StatelessWidget or reusable components.
tools
Implements Flutter View screens following the project architecture. Use whenever creating or modifying a View (StatefulWidget + Cubit + BlocBuilder), adding a new screen, wiring up BlocBuilder/BlocConsumer/BlocListener, setting up SafeArea, or navigating from the View. Covers State, Cubit, View file, route, DI registration, and common mistakes. Activate even when the user just says "create a screen" or "add a new page", without explicitly mentioning Cubit or BLoC.
testing
Implements Flutter Cubit and State (View Model layer) following the project architecture. Use whenever creating or modifying a Cubit or State class, adding an async method to a Cubit, handling form submission or validation, implementing debounce search, managing loading/error/navigation states, or wiring a Cubit to a Repository or StorageService. Covers sealed States, async patterns with Result<T>, CRUD Cubits, local persistence via StorageService, navigation states, debounce, and common mistakes. Activate even when the user says "add a method", "handle the loading state", or "save locally" without explicitly mentioning Cubit or BLoC.