Aplica DS — V3
Contexto
A V3 é a fase atual do Aplica DS (2024–presente). É a fase de distribuição: tudo que foi provado na V2 foi reempacotado para que qualquer equipe possa adotar sem precisar fazer fork ou copiar arquivos internos.
As duas mudanças estruturais que definem a V3:
- Package-first — o
@aplica/aplica-theme-engineé publicado como pacote npm independente. Consumers instalam como dependência em vez de copiar arquivos fonte. - Consumer workspace model — configuração e dados ficam inteiramente no projeto consumidor. O pacote é um motor puro; não traz opiniões sobre brand, cores ou tipografia.
A grande virada: de cópia para pacote
Na V2, equipes adotavam o Theme Engine copiando ou fazendo fork do repositório. Atualizações exigiam merge manual. A V3 substituiu esse modelo:
| V2 | V3 | |
|---|---|---|
| Adoção | Cópia / fork | npm install @aplica/aplica-theme-engine |
| Configuração | No repositório do engine | No projeto consumidor (aplica.config.mjs) |
| Atualizações | Merge manual | npm update + bundle de migração |
| Ownership de schemas | Controlado pelo engine | Consumer pode sobrescrever via paths.schemasDir |
Inovações da V3
1. Pacote npm independente
npm install @aplica/aplica-theme-engine
O pacote expõe:
defineThemeEngineConfig()— API pública de configuração com inferência TypeScript completa/config— helpers de config importáveis/transformers/config— hooks de extensibilidade para transformers customizados
2. Scaffolding do workspace consumidor
npx theme-engine init
Wizard interativo que cria:
aplica.config.mjs— configuração do projetodata/— arquivos de schema e arquiteturadist/— diretório de output da build
Alternativamente, --template <starter> pula o wizard.
3. Migração automatizada da V2
npx theme-engine migrate:legacy-consumer
Três subcomandos para migração segura de projetos monolíticos pré-V3:
| Subcomando | Propósito |
|---|---|
analyze | Relata o que precisa mudar |
convert | Aplica a migração automaticamente |
compare | Faz diff do estado antes/depois |
4. Integração com Figma via figma:generate
npx theme-engine figma:generate
Gera e mantém os três arquivos que o Tokens Studio precisa:
| Arquivo | Propósito |
|---|---|
data/$themes.json | Configuração de temas para o Tokens Studio |
data/$themes.engine.json.template | Template para campos gerenciados pelo engine |
data/$metadata.json | Metadados dos tokens |
IDs estáveis via SHA1 de "group:name" — sem IDs aleatórios que forçam re-sync no Figma. Campos do Figma (id, $figmaStyleReferences, variableIDs) são preservados a cada execução.
5. Foundation Styles como classes CSS
A V3 promoveu o Foundation Styles — introduzido na V2 2.26.0 — como caminho principal de consumo para autores de componentes e agentes de IA:
# Gerado pelo engine
dist/css/foundation/{brand}/typography.css
dist/css/foundation/{brand}/elevation.css
Cada classe é um composto: classes de tipografia agrupam 7 propriedades CSS referenciando tokens semânticos; classes de elevation agrupam box-shadow por nível. Os valores resolvem em runtime pelo arquivo de tema ativo — troca de tema atualiza automaticamente.
6. AI Skills Injection Program
npx theme-engine ai:init
Injeta arquivos de contexto específicos de editor no workspace do consumidor:
| Destino | Ferramenta |
|---|---|
docs/context/ | Todos os agentes de IA (compartilhado) |
.cursor/rules/ | Cursor |
.claude/skills/ | Claude Code |
.github/instructions/ | GitHub Copilot |
Os arquivos injetados ensinam agentes qual camada de token ler, como mapear intenção para tokens semânticos, e quando preferir Foundation Styles em vez de montagem de tokens atômicos.
8. theme-engine — alias CLI preferido (desde 3.8.0)
npx theme-engine init
npx theme-engine ai:init
npx theme-engine build:all
theme-engine é agora o nome de comando preferido para workspaces consumidores. O nome legado aplica-theme-engine é preservado como fallback de compatibilidade — scripts existentes continuam funcionando sem alterações.
Toda a documentação ativa, fluxos de onboarding e guias de consumidor padronizam em theme-engine primeiro. O nome do pacote (@aplica/aplica-theme-engine) e os nomes de arquivo de config (aplica-theme-engine.config.mjs) não mudam.
7. AI UI Integration Program
Um contrato formal que especifica como agentes de IA consomem o sistema de tokens ao gerar UI:
- Caminho preferido: Foundation Styles (
typography.css,elevation.css) — uma classe mapeia para uma decisão de estilo completa - Caminho secundário: tokens semânticos (
action.bg.brand.default) — quando controle fino é necessário - Nunca: tokens de camada Brand, Mode ou Surface — são internos do engine
Sete archetypes de componente (Button, Dialog, Input, Badge, Select, Card, Tabs) definem o modelo canônico de decisão de tokens para cada tipo de componente.
Versões de marco da V3
Versão atual: 3.23.0
- 3.23.0 — Nova feature: alias pass genérico no foundation. Qualquer chave em
structureque declare os três campossemanticPath,typeeitemsé processada automaticamente porgenerate-foundation.mjs, expondo tokens semânticos como aliases de foundation sem necessidade de mudanças no engine. Exemplos de uso:fontFamilies,lineHeights,fontWeights,letterSpacing, ou qualquer caminho personalizado emdata/semantic/default.json. As seções com handlers dedicados (bg,border,txt,opacity,sizing,spacing,borderWidth,borderRadius,typography,gradient) estão protegidas pela listaEXPLICITLY_HANDLED_SECTIONSe nunca são processadas pelo pass genérico — retrocompatibilidade total, nenhuma config existente precisa ser alterada. Pré-requisito: osemanticPathdeclarado deve existir emdata/semantic/default.json(o mecanismo cria aliases, não gera valores). - 3.22.3 — Fix: CLI eliminava mensagem duplicada
"Fatal error: Command failed"quando um script falhava com seu próprio erro.runNodeScript(index.mjs) agora usa catch discriminado:err.status != null(child rodou e saiu com código não-zero) →process.exit(err.status)silencioso, já que o child já imprimiu seu próprio erro;err.status == null(falha de spawn, ex: script não encontrado) → relança para o catch demain(). Mesmo tratamento emutils/init-helper.mjspara o subprocess do modo playground. Resultado:initopção 3 em workspace não inicializado agora exibe apenas[error] No workspace config foundem vez de exibir esse erro mais 2×"Fatal error: Command failed: ...". - 3.22.2 — Fix: tokens
surface.opacity.color.dark.*esurface.opacity.color.light.*não invertiam ao trocar entre light/dark mode no Figma. Causa raiz: os tokens de opacity referenciavam uma cadeia intermediária (mode.opacity) com caminhos hardcoded incompatíveis com o schema padrão (SURFACE_POLARITY_ENABLED=true). Fix:generateSurfaceOpacityreescrita para ser schema-aware — quandoSURFACE_POLARITY_ENABLED=false, usamode.brand.ambient.contrast.base.{polarity}.background; quandotrue, usamode.brand.ambient.contrast.base.{surfaceType}.{polarity}.background. Cada token agora usa$extensions.studio.tokens.modify.alphacomspace: srgbeformat: hexpara aplicar o alpha via Tokens Studio.updateModeFilelimpa tokens órfãos demode.opacityde syncs anteriores. Rodartokens:syncpara aplicar. CSS verificado: dark mode inverte--semantic-opacity-color-light-translucidcorretamente. - 3.22.0 — Leaves de override de interação por modo: preset leaves de
overrides.interactionagora aceitam valores por modo. Três formatos disponíveis — todos retrocompatíveis: global (comportamento existente, sem mudança), modo-específico-duplo (chaveslight/darkno leaf do preset com valores diferentes por modo) e modo-específico-parcial (um modo explícito, o outro auto-gerado pelo engine). Regra de detecção: se o valor de um preset contiver chavelightoudark, é tratado como modo-específico; do contrário, é tratado como leaf global — consistente com a convenção{ light, dark }já usada emoverrides.grayscale,overrides.neutralseoptions.txtOnCustomTint. Elimina a classe de warnings[override:accessibility]causada por forçar overrides otimizados para light mode no dark mode. Nenhuma migração necessária. - 3.21.1 — Fix:
sync:architecturedeletavadata/surface/negative.jsonquandosurfacePolarity: falseestava definido no workspace, removendo o modo de coleção "negative" do Figma e quebrando referências de tokens comosurface.opacity.color.darkesurface.opacity.color.lightapóstokens:sync. Fix:sync:architectureagora escrevesurface/negative.jsoncomo stub com conteúdo idêntico ao desurface/positive.json(valores de opacidade são canvas-ambient e mode-invariant — o stub é semanticamente correto);generate-figma-theme-filesagora inclui a entradasurface/negativeem$themes.jsone$themes.engine.json.templatemesmo quando polarity está desabilitada. Nenhuma mudança de config necessária. - 3.21.0 — Fix:
backgroundoverride derivatxtOnda paleta correta. Antes, quando um leaf declarava apenasbackgroundsemtxtOnexplícito, o engine calculava otxtOnauto-computado usando a paleta da cor original do item (hue errado — ex: texto azul sobre fundo rosa). Causa raiz:_collectInteractionOverrideColorsnão indexavaleaf.backgroundno cache de paletas, e o engine recorria aopaletteSurfaceScaledo color name original. Fix:_collectInteractionOverrideColorsagora indexa tambémleaf.background, gerando paleta completa light/dark a partir de qualquer hex declarado como background;_resolveInteractionOverrideStateValuesusabgPaletteScalepara derivartxtOn, com fallback paragenerateHighContrastTxtOn(preto ou branco puro) se nenhum tom passar WCAG AA. Otxt(texto sobre o canvas da página) não é afetado. Impacto: configs que usambackgroundem overrides de interação podem vertxtOnmudar para um tom derivado do hex declarado — declaretxtOnexplicitamente para fixar um tom específico. - 3.20.0 — Spec completo do leaf de override de interação: cinco campos disponíveis —
background(surface direta,txtOnauto-computado WCAG AA,borderderivado);color(pipeline de decomposição completo);txtOn(override de texto validado WCAG AA — se reprovar emite[override:accessibility]e preserva o valor auto-computado);txt(texto legível ambiente, ativo apenas comgenerateTxt: true);border(override de borda sem checagem de contraste). Estados ghost com dilution-factor suportados. Validação em parse time: leaf vazio → erro; estados válidos:normal,action,active,focus; items devem corresponder aomapping. Fix de override txtOnly descartado silenciosamente em ghost com dilution-factor (pendingTxtOnlyOverride). 171 testes novos em quatro suítes;build:themesgated atrás detest:theme-engine;prerelease:checkagrega todos os gates;RULES.mdSeções 7–8 formalizadas. - 3.19.2 —
ai:initredesenhado para skills auto-contidas: duas skills Claude Code (theme-engine— expert do engine com detecção automática de nível N1/N2/N3 pelo vocabulário, eaplica-components— engineer de componentes com padrões reais de CSS variables, dark mode e portal pattern); dois docs de conhecimento local segmentados por audiência (docs/context/token-concepts.mdpara N1 edocs/context/engineering-guide.mdpara N3) substituem o playbook central; nenhuma skill depende de doc externa; mirrors para Cursor e Copilot incluídos para ambas as skills. - 3.19.1 — Refatoração do sistema de AI skills:
theme-engine ai:initpassa a instalar um playbook central (docs/context/theme-engine-playbook.md) como SSOT único — arquitetura de 5 camadas, tabela de config keys, tabela de CLI, paths de output e 6 diagnósticos comuns. As skills de Claude Code, Cursor e Copilot tornam-se wrappers finos que leem o playbook, eliminando duplicação. Seis slash commands são instalados em.claude/commands/:/getting-started,/configure-visual,/engineering-integration,/debug,/explain-semantic,/build-component. OCLAUDE.mdé instalado na raiz do workspace (soft copy — não sobrescreve se já existir). - 3.18.0 —
brand-tintoverlap + cobertura de showroom:overlap: { level: N }permite que superfícies de paleta acima do limiar pulem o walk de brand-tint e vão direto para o extremo (preto ou branco) definido porcolorContrastDecompose— mais editorial e legível em marcas com paletas altamente saturadas;aplica_emberserve como referência canônica emoverlap: { level: 120 }; configsaplica_sky,aplica_forest,aplica_grinch,aplica_obsidianeaplica_tangerinerecebem documentação inline decolorContrastDecompose - 3.17.0 — Preview UI redesenhado: layout de referência com navegação hierárquica direita seguindo a ordem semântica (Brand → Mode → Surface → Semantic), modo compacto para QA visual de múltiplos brands sem scroll excessivo, filtro de busca em tempo real para isolar famílias de token pelo nome
- 3.16.1 —
theme-engine ai:knowledge(aliases:ai:guide,knowledge:init) — instala skill conversacional em.claude/skills/,.cursor/rules/,.github/instructions/edocs/context/; habilita assistentes a responder perguntas de configuração, explicar a arquitetura de 5 camadas e diagnosticar tokens lendo arquivos reais do workspace; também incluído automaticamente emai:init - 3.16.0 —
theme-engine design:mdgeraDESIGN.md(spec Google Stitch, YAML frontmatter + markdown body) com valores resolvidos dedist/json/edata/foundation/styles/;theme-engine contracts:generateproduz snapshot estrutural de paths+tipos para CI de segurança de deploy;theme-engine contracts:diffcompara contratos e retorna GREEN / ALERT / ERROR (exit 1 em breaking changes) - 3.15.1 —
ghostNormalTxtOnStrategy— nova opção emoptions.interaction.surfaces.ghoste por grupo;'txt'(padrão) usa cor interativa da paleta contra o canvas;'surface'executatxtOnStrategycontra o canvas background (comportamento legado);theme-engine audit:accessibilityaudita pares de contraste de cor WCAG 2.1 AA/AAA em todo odist/ - 3.15.0 — 15 temas de referência do playground (
aplica_slate,aplica_obsidian,aplica_electric,aplica_forest,aplica_coral,aplica_midnight,aplica_rose,aplica_mono,aplica_aurora,aplica_ember) publicados no pacote NPM;theme-engine init:playgroundcopia configs de referência para o workspace do consumidor;theme-engine fonts:downloadbaixa 22 famílias OFL degoogle/fonts;global.surfacePolarity: falseemthemes.config.jsoncolapsa o workspace para contrato positive-only (apenas*-positivenos outputs semânticos) - 3.14.0–3.14.6 — Overrides dinâmicos de estado de interação + splitting de bundles de marca para Figma:
overrides.interactionsubstitui o formato legadooverrides.interface.function.*e o estende parafeedback— overrides têm escopo por grupo, item, preset (solid/ghost) e estado (normal,action,active,focus,disabled), e passam pelo pipeline de decomposição completo (dilution, base adaptation, espelhamento de quadrante, texto de acessibilidade);figma:generateagora divide automaticamente bundles de marca oversized em chunks semânticos (_brand_product.json,_brand_text.json,_brand_interface.json) quando a contagem de tokens excede o limite por coleção do Figma (padrão 5.000, sobrescrevível viaAPLICA_THEME_ENGINE_BRAND_TOKEN_LIMIT) - 3.13.5–3.13.8 — Decomposição de feedback por modo + correções de espelhamento por quadrante:
options.interaction.decomposition.modeResolution: 'mode'faz tokens de feedback seguirem semântica light/dark sem inversão de polaridade de quadrante — superfícies positive e negative dentro do mesmo modo produzem superfícies, texto e bordas idênticos; correções de bugs restauram espelhamento correto por quadrante para cores derivadas em dilution e para feedback padrão (modeResolution: 'quadrant') após regressão no 3.13.6 - 3.13.0–3.13.4 — Preview modo Summary + cluster de dilution com âncora + adaptação de base por quadrante:
theme-engine previewganha dropdown View (Detailed / Summary); dilution ganhatarget: 'anchor'comanchor.sourceconfigurável ('palette' | 'hex' | 'token'),anchor.canvasAwareeanchor.canvasMixpara âncoras cromáticas sensíveis ao quadrante;options.baseAdaptation: truefaz superfíciesnormalde interaction edefaultde produto responderem ao quadrante ativo light/dark + positive/negative - 3.12.0 — Decomposição de interação aprimorada:
options.interaction.groups.{function|feedback}permite quefunctionefeedbackusem métodos de decomposição e configs de surface independentes dentro do mesmo tema; overrides por grupo resolvem por mesclagem tema → surface → grupo → grupo-surface - 3.11.0 —
theme-engine preview --serveadiciona live reload — o browser atualiza automaticamente quandodist/muda; sem necessidade de reload manual ao iterar em configs de tema - 3.10.1 — Bug fix: overrides de decomposição de interação agrupados (
options.interaction.groups.*) agora resolvem corretamente em todas as combinações de surface e estado - 3.10.0 — Distribuição nativa de orientação para IA:
theme-engine ai:initagora implanta arquivos de contexto do pacote publicado em vez de templates locais;AI_CONTEXT.mdeTHEME_CONFIG_REFERENCE.mdsão empacotados por release e atualizados automaticamente ao rodarai:initapós upgrade - 3.9.0 — Modos de decomposição de interação autorais (
system-scale/dilution) parainterface.functioneinterface.feedback; presets expandidossolid/ghostvialegacyStructure: false; ajuste por estado emoptions.interaction.surfaces.{solid|ghost}.levels; comandotheme-engine previewgera preview HTML estático emdist/preview/ - 3.8.5 — Automação de publicação confiável (trusted publishing) via GitHub Actions; runtimes atualizados para Node.js 24
- 3.8.4 — Tokens
*.txtnegativos agora seguem o contrato de canvas declarado em todo o pipeline atédist/para branches de interface, feedback, disabled e produto; novo branchmode.productBySurfacegarante que a polaridade de produto sobreviva aosync:architecture;test:txt-inversionagora audita o JSON final emdist/ - 3.8.3 — Texto legível ambiente agora segue o canvas do arquivo final em ambas as polaridades:
brand.ambient.contrast.*,neutral.*egrayscale.*.txtresolvem contra ocontrast.base.positive.backgrounddeclarado; superfícies negativas ambientes resolvem a partir do canvas do modo inverso - 3.8.2 —
brand.brandingagora respeita a polaridade positive/negative nos outputs semânticos via branch dedicadomode.brand.brandingBySurface; dark mode segue a mesma regra de surface inversa que o light mode - 3.8.1 — Correção de acessibilidade do
txtambiente:brand.ambient.neutral.*.txtebrand.ambient.grayscale.*.txtagora validam contra ocontrast.base.{positive|negative}.backgrounddeclarado em vez do background do nível; cobertura de regressão estendida emtest:txt-inversion - 3.8.0 — Alias CLI preferido
theme-engine— comando mais curto para workspaces consumidores;aplica-theme-enginepreservado como fallback de compatibilidade; toda a documentação ativa padroniza emtheme-engineprimeiro - 3.7.5 — Fix Tokens Studio-safe: branches de texto legível de produto desabilitadas não emitem mais nós
txt: nullinválidos quandogenerateTxt: trueetextExposure.product: false - 3.7.4 — Inversão de texto legível para superfícies negativas:
brand.text.negative.*agora resolve corretamente;txtde produto removido das camadas públicas quando texto legível de produto está desabilitado; migrador legado infere exposição de texto de feedback a partir de aliases planos - 3.7.2 — Propagação de
brand.brandingcorrigida através demodeantes de chegar asurfacee outputs semânticos; migrador legado agora preserva o contratogeneration.colorTextautomaticamente - 3.7.1 — Fix de inversão do
txtambiente na camada de tema:brand.ambientagora resolve texto legível contra os contextos corretos de background positive/negative - 3.7.0 — Plataforma de output
jsonTyped— primeiro delivery de output extensível com metadata tipada (type,value,description,path); configurável viaformatOptions.jsonTypedemtransformers.config.mjs; backward compatible, contratojsonexistente não muda - 3.6.4 — Fix de migração:
generate-foundation.mjsagora preserva corretamentetxt.base.itemsem workspaces com product text families customizados (ex.: temas estilo Brewer comtada,ze) - 3.6.3 —
includePrimitives: falsecomo padrão no scaffold doinit, banner de onboarding no CLI, cobertura de smoke paraai:init - 3.6.1 — Workspace config
generation.colorText(breaking: consolidação de config de por-tema para workspace) - 3.6.0 — Contrato de cor de 4 partes: token
txtadicionado ao lado debackground/txtOn/border;txtBaseColorLevel; text states (normal/action/active/focus) em todas as camadas; breaking: aliases de texto não mais herdam desurface.* - 3.5.2 — AI UI Integration Program — archetypes, portal rule para headless UI (Base UI, Radix)
- 3.5.0 — Comando
ai:init— AI Skills Injection no workspace consumidor - 3.4.0 — Comando
figma:generate— scaffolding do Tokens Studio com IDs estáveis via SHA1 - 3.0.0 — Arquitetura package-first, consumer workspace model, API de config pública, wizard
init,migrate:legacy-consumer
Arquivos de referência
- Pacote npm:
@aplica/aplica-theme-engine - API de config:
aplica.config.mjsno projeto consumidor - Contexto de IA:
docs/context/(injetado porai:init) - Changelog completo:
CHANGELOG.mdno repositório do pacote - Documentação do AI UI Program:
docs/context/ai-ui/no workspace consumidor apósai:init