ads-creative-factory
SkillDev toolsExtensible engine for performance creatives. Creates, validates, and uses versioned packs of brand, persona, archetypes, mechanisms, UGC scenes, variations, references, and gates.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the ads-creative-factory skill
What this skill tells your AI
The instructions your AI receives, as published by marketinglendario/cohort-de-marketing in .agents/skills/ads-creative-factory/SKILL.md and read by ahel’s review.
Invocação (slash command)
/ads-creative-factory [request.json]
/ads-creative-factory <entidade> <ação> [opções]
Na interface, o adapter converte os finalistas curados pelo briefista em um
campaign.yaml fechado. No terminal, a skill recebe esse arquivo diretamente.
Formatos, variações, arquétipos e personas são campos de params: no YAML:
| Argumento | Default | O que faz |
|---|---|---|
campaign.yaml (posicional) | — | Campanha estruturada com hooks já curados |
--formats | feed | Formatos: feed (4:5) · story (9:16) · square (1:1) |
--variants N | 1 | Variantes (instâncias) por mensagem — N×hooks = total de criativos |
--archetypes | declarados no request | Subconjunto de espécies a usar |
--personas | [] | IDs ou caminhos explicitamente declarados para Pessoa/UGC |
brand_pack | obrigatório | Brand pack v1 explícito |
persona_pack | opcional | Pack v1 de persona quando houver likeness |
output_root | obrigatório | Raiz relativa materializada em projetos/{slug}/ após aprovação |
extension_packs | [] | Paths relativos e explícitos de Extension Packs instalados |
catalog_hash | automático | Snapshot determinístico recusado quando diverge em retry |
O adapter preenche a copy de imagem e a copy de anúncio (caption +
link_description) por hook; ambas viajam no manifesto sanitizado.
Catálogo e comandos de autoria
Existe um único slash command público. No terminal, todos os subcomandos usam a
mesma superfície CLI-first e aceitam --json; comandos de escrita também aceitam
--dry-run:
SKILL_DIR="$(git rev-parse --show-toplevel)/.claude/skills/ads-creative-factory"
CF="python3 $SKILL_DIR/scripts/catalog_cli.py"
$CF --json catalog list --type archetypes
$CF --json catalog show archetypes dark_editorial
$CF --json catalog validate projetos/acme/creative-factory/packs/acme-extension
$CF --json pack build --project-root projetos/acme --id acme-extension \
--namespace acme --version 1.0.0 --rights-notice "Uso autorizado neste projeto" --dry-run
$CF --json pack install --project-root projetos/acme \
--pack projetos/acme/creative-factory/packs/acme-extension
Subcomandos disponíveis: brand create, persona create, archetype add,
mechanism add, ugc-scene add, variation add, reference add,
gate-profile add, preview archetype, pack build e pack install. Use
python3 "$SKILL_DIR/scripts/catalog_cli.py" <entidade> <ação> --help para os
campos do contrato. IDs externos devem ser namespaced, por exemplo
acme.editorial; builtin é reservado. Um arquétipo novo pode selecionar
somente os renderer modes hybrid, person, mockup, ugc, didactic,
chat e tweet.
Renderer novo exige story de desenvolvimento e nunca é carregado do pack.
Hooks podem selecionar entidades resolvidas explicitamente por
visual_mechanism_id, copy_mechanism_id, ugc_scene_id,
mockup_device_id, didactic_style_id, chat_style_id e tweet_style_id;
IDs desconhecidos ou de eixo incompatível falham antes da geração.
Packs instalados ficam em
projetos/{slug}/creative-factory/packs/{pack-id}/ e o vínculo explícito em
projetos/{slug}/creative-factory/installed-packs.json. Não edite os YAMLs
built-in para adicionar repertório de cliente.
Criar o Brand Pack sem editar JSON
Quando o projeto já possui um projetos/{slug}/DESIGN.md aprovado, converta-o
com o builder canônico. A declaração de direitos é obrigatória e o pack nasce
como não redistribuível; isso permite uso no projeto sem presumir licença
pública de logo, fonte ou referência:
SKILL_DIR="$(git rev-parse --show-toplevel)/.claude/skills/ads-creative-factory"
python3 "$SKILL_DIR/scripts/build_brand_pack.py" \
--design "projetos/meu-projeto/DESIGN.md" \
--output "projetos/meu-projeto/brand-pack" \
--rights-notice "Declaro que tenho direito de usar estes ativos neste projeto." \
--asset "logo:/caminho/para/logo.svg" \
--json
--asset é opcional e repetível (logo, font, reference, texture ou
other). O builder gera pack.json, assets/DESIGN.md, preview.html e
build-report.json, valida tudo com o mesmo loader do runtime e falha fechado
quando faltam cores, tipografia, provenance ou declaração de direitos. No
painel, o fluxo "Criar pack" invoca este mesmo comando e salva no projeto.
ads-creative-factory
Motor agnóstico de criativos de performance (lead-gen). A diversidade é de ARQUÉTIPO (a espécie da peça) — é isso que faz o stop-scroll, não trocar objeto+copy dentro do mesmo molde.
Motor: Codex CLI local autenticado (image_gen). Texto-a-imagem para fundos;
image-to-image EDIT somente com persona_pack e autorização explícitos.
Nenhuma OPENAI_API_KEY ou CODEX_API_KEY é usada.
Localização da implementação
Esta skill é autocontida em .claude/skills/ads-creative-factory/. Scripts e
contratos genéricos viajam juntos; identidade, referências, logos e fotos entram
somente por pack externo explícito. O
espelho .agents/skills/ads-creative-factory/ deve ser byte a byte idêntico.
SKILL_DIR="$(git rev-parse --show-toplevel)/.claude/skills/ads-creative-factory"
python3 "$SKILL_DIR/scripts/doctor.py" --json
ACF_OUT_DIR="$(mktemp -d)" ACF_BRAND_PACK="/caminho/para/pack-v1" \
python3 "$SKILL_DIR/scripts/factory.py" campaign.yaml
Segredos: a geração usa exclusivamente a sessão autenticada do Codex CLI.
OPENAI_API_KEYeCODEX_API_KEYnão são exigidas nem herdadas pelo runtime. Outputs ficam fora da skill, sob a raiz indicada porACF_OUT_DIR.
Contrato compartilhado CLI/painel
O painel e o CLI enviam o mesmo objeto v1 dentro de context.creativeFactory.
brand_pack é obrigatório, persona_pack só aparece quando necessário e
output_root sempre é relativo:
{
"schema_version": "1.0.0",
"brand_pack": { "id": "brand-alpha" },
"extension_packs": [{ "id": "acme-extension", "version": "1.0.0", "path": "projetos/acme/creative-factory/packs/acme-extension" }],
"catalog_hash": "<sha256-do-catalogo-resolvido>",
"output_root": "criativos/factory",
"campaign_id": "campanha-01",
"production_skill_id": "ads-creative-factory",
"formats": ["feed", "story"],
"archetypes": ["dark_editorial", "light_clean"],
"variants": 1,
"personas": [],
"likeness_authorizations": [],
"cta": "Saiba mais",
"finalists": [{ "id": "hook-1", "hook": "Hook", "copy": "Copy", "format": "feed" }]
}
Adapters de painel devem persistir o objeto context.creativeFactory acima e
usar um jobId durável para retry, cancelamento, aprovação e retomada. No CLI
standalone, ACF_BRAND_PACK e ACF_OUT_DIR materializam o mesmo boundary;
falhas de pack, dependência ou path são bloqueantes e acionáveis.
Os 8 arquétipos built-in (base extensível) — data/archetypes.yaml
| Arquétipo | Modo | Linguagem |
|---|---|---|
| dark_editorial | hybrid (dark) | superfície escura e acento definidos pelo pack |
| light_clean | hybrid (light) | superfície clara e contraste definidos pelo pack |
| person_authority | person (EDIT) | rosto REAL do expert + cena temática |
| mockup_product | mockup | tela/dashboard (devices variados) |
| ugc_native | ugc | story nativo do Instagram (9:16) |
| didactic_compare | didactic | comparação ✕/✓ (3 estilos) |
| chat_notification | chat (PIL) | print nativo de conversa/notificação (3 estilos no eixo chat_style) |
| tweet_card | tweet (PIL) | card estilo post/X sobre backdrop do pack (2 estilos no eixo tweet_style) |
O factory sorteia arquétipos distintos por job (eixo primário) + variação interna por instância (estilo/device/foto) → diversidade entre E dentro das espécies. Extension Packs adicionam presets declarativos sobre os mesmos sete renderer modes sem sobrescrever os built-ins.
Espécies nativas programáticas (chat / tweet)
chat_notification e tweet_card são 100% PIL — zero chamadas de geração
de imagem (custo de API = 0). Como o UGC, usam theme: native no gate
(builtin.default-native): o sinal é parecer print real, não seguir o brand
tone. O contato da conversa / autor do post vem da persona (nome + foto
REAL do persona pack; nunca likeness gerada) ou, sem persona, da identity
do brand pack; sem foto legível, o avatar cai num círculo neutro com inicial.
Sem selo de verificado (não fabricamos status), engajamento com números
orgânicos (nunca redondos) e copy sem emoji (as fontes neutras do runtime não
renderizam emoji — caracteres emoji são removidos). Campos opcionais do hook:
hooks:
- id: H
# ... campos base ...
chat: # arquétipo chat_notification
contact: "Nome do Contato" # default: persona > identity do pack
time: "09:41"
messages:
- { from: them, text: "primeira mensagem (o hook)" }
- { from: me, text: "resposta do usuário (o CTA)" }
tweet: # arquétipo tweet_card
text: "texto do post" # default: native_text | headline + sub
time: "10:24"
stats: { likes: "2,4 mil", shares: "317" }
Cena cotidiana no arquétipo Pessoa (EDIT de foto real)
Um preset renderer_mode: person pode declarar --ugc-scene <id> (o mesmo
campo compatible_ugc_scenes já usado por presets ugc) para trocar o
ambiente do EDIT por uma cena cotidiana do catálogo (setting/shot/
lighting/props/authenticity_guards), em vez da cena cinematográfica
fixa do person_authority. A pessoa continua sendo sempre a foto REAL via
EDIT — a cena parametriza só o ambiente, nunca o rosto. Sem --ugc-scene
declarado, o preset se comporta exatamente como hoje.
campaign.yaml
campaign: "campaign-example"
brand_id: "brand-alpha"
extension_packs: ["creative-factory/packs/acme-extension"]
params:
primary_axis: "archetype"
variants_per_hook: 3
formats: ["feed","story","square"]
personas: []
hooks:
- { id: H, mechanism: ..., eyebrow: "...", headline: "...", emphasis_word: "...",
sub: "...", cta: "...", native_text: "...(ugc)", compare: {...(didactic)} }
Modo carrossel
Use quando a peça precisa de sequência narrativa (capa/hook → corpo → CTA), não como 7º arquétipo. A invocação continua CLI-first:
python3 "$SKILL_DIR/scripts/carousel_copy_adapter.py" copy.yaml -o hooks.yaml
python3 "$SKILL_DIR/scripts/factory.py" campaign-carousel.yaml
Schema mínimo do hook:
hooks:
- id: "aula-carousel"
mode: "carousel"
caption: "Legenda do anúncio..."
link_description: "Descrição do link..."
slides:
- { role: "hook", headline: "Capa forte", source_slide: 1 }
- { role: "body", headline: "Ideia do corpo", sub: "1-3 linhas", source_slide: 2 }
- { role: "cta", headline: "Fechamento", cta: "Quero participar", source_slide: 3 }
slides[] aceita 3-10 itens; primeiro role: hook, último role: cta. O
adapter aceita YAML carousel_output do create-carousel como formato primário
e Markdown com headings explícitos de slide como fallback. Custo esperado:
single_bg usa ~1 chamada de imagem por carrossel e re-typeset vetorial por slide;
per_slide usa 1 chamada por slide e passa por gate de paleta inter-slides.
Exemplo representativo versionado: campaign-archetypes-final.yaml.
Pipeline
copy (will-binder) → arquétipo (eixo primário) → variação secundária → geração por modo → gate archetype-aware (dark/light/native) → logo discreto + finish → revisão final → multi-formato (mesma cena reenquadrada). Anti-saturação + acervo auto-curado. Pessoa = foto REAL via EDIT (nunca likeness gerada do zero).
Princípios inegociáveis
- Diversidade = arquétipo (espécie), não elemento dentro do molde.
- Logo NUNCA difundido (asset fixo, composto discreto).
- Pessoa = EDIT da foto real ("mantenha a pessoa, troque o fundo"); nunca gerar rosto (FR20).
- Revisar o entregável FINAL com olho crítico, não confiar na cadeia.
Estrutura da skill
.claude/skills/ads-creative-factory/
SKILL.md — este arquivo (entry point)
scripts/ — pipeline Python (factory, gate, person, archetype_render, ...)
schemas/ — contratos v1 de brand e persona packs
data/ — built-ins declarativos de arquétipos, UGC, gates e variações
fonts/ — dependências tipográficas neutras do runtime
THIRD_PARTY_NOTICES.md — gate de licença e redistribuição
Identidade, logos, pessoas, referências e exemplos de campanha vivem somente em packs externos explicitamente selecionados; não existem defaults de cliente.
Publicação (ponte para o Squad de Tráfego)
Depois da curadoria humana, os PNGs aprovados sobem para a biblioteca da conta Meta com o adapter externo (fora desta skill):
node scripts/acf-upload.mjs --dir=projetos/{slug}/criativos/factory --json
Ele devolve {arquivo → image_hash}; os hashes entram em criativos[].image_hash
do plano do estruturador (scripts/estruturador-publish.mjs), que cria os
anúncios PAUSED. Upload não é publicação — mas só suba o que o aluno aprovou.
Nunca versionar out/, tmp/, __pycache__/, .last, manifests de execução
ou imagens geradas para projetos reais dentro da pasta da skill.
Signals
- GitHub stars
- 21
- Forks
- 30
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
ads-creative-factory- Source
- github.com/marketinglendario/cohort-de-marketing