Help us improve
Share bugs, ideas, or general feedback.
From dev-team-kit-fv
Composes original blog posts in PT-BR from URLs, pasted text, or topics. Researches additional context, generates HTML with images, commits to a GitHub Pages repo, and returns the public URL.
npx claudepluginhub felvieira/claude-skills-fv --plugin dev-team-kit-fvHow this skill is triggered — by the user, by Claude, or both
Slash command
/dev-team-kit-fv:41-blog-publisher [assunto ou texto do post][assunto ou texto do post]This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **Compositora ENRIQUECEDORA.** Recebe input (link/texto/assunto) → lê fonte → pesquisa contexto adicional → produz post ORIGINAL em **PT-BR por default** → publica no GitHub Pages → retorna URL.
Generates high-quality blog posts from marketing briefs, PRs, git diffs, codebase paths, or freeform technical descriptions. Handles SEO, structure, tone, and visuals via phased process.
Manages full-lifecycle blog content with 30 sub-skills for writing, rewriting, analysis, SEO, schema, images, repurposing, and multilingual publishing. Optimized for Google rankings and AI citations.
Writes technical blog posts, tutorials, deep dives, and engineering content. Transforms brain dumps into polished content with personal voice support and AEO optimization.
Share bugs, ideas, or general feedback.
Compositora ENRIQUECEDORA. Recebe input (link/texto/assunto) → lê fonte → pesquisa contexto adicional → produz post ORIGINAL em PT-BR por default → publica no GitHub Pages → retorna URL.
Esta skill nunca copia ou traduz textualmente uma fonte. Ela:
Saída: post original, que cita a fonte com respeito, mas agrega valor.
Anti-padrão: copiar/traduzir verbatim. Mesmo "adaptação livre" é arriscada. Sempre escrever do zero usando a fonte como inspiração.
Esta skill segue GLOBAL.md, policies/anti-ai-writing.md, policies/handoffs.md e
policies/tool-safety.md. Composta sobre skills 13 (marketing-copy), 17 (image-generator),
26 (prompt-engineer) e 42 (blog-screenshot).
| Input | Ação |
|---|---|
| URL | WebFetch o conteúdo → extrair pontos centrais → pesquisar contexto adicional → escrever post novo |
| Texto colado | Identificar pontos centrais → pesquisar contexto adicional → escrever post novo (não copiar) |
| Assunto livre | Pesquisar 3+ fontes do assunto → escrever post com voz própria |
Em qualquer caso, sempre PT-BR por default.
A skill não tem repo hardcoded. Ela lê ~/.dev-team-kit/blog-config.json
(override via env DEVKIT_BLOG_CONFIG). Schema:
{
"github_user": "<user>",
"blog_repo": "blog",
"blog_repo_path": "/abs/path/to/blog/repo",
"pages_url": "https://<user>.github.io/blog"
}
A skill deve pausar e instruir o usuário a rodar o init script:
node /caminho/para/claude-skills-fv/scripts/init-blog-repo.mjs \
--path=/abs/path/to/blog \
--user=<github-username> \
--repo=blog \
--create-github
Esse script:
templates/blog/ do kit{{GITHUB_USER}} e {{BLOG_REPO}} nos arquivosgit init no destino~/.dev-team-kit/blog-config.json--create-github) cria repo no GitHub via gh e habilita PagesApós o script rodar, a skill 41 funciona automaticamente — sem mais perguntas.
Lê o config, deriva todos os paths/URLs dinamicamente:
blog_repo_path → onde escrever os arquivospages_url → URL pública pra retornar ao usergithub_user + blog_repo → preencher placeholders no HTMLEstrutura conhecida do repo destino (criada pelo init script):
blog/
├── index.html ← landing com lista de posts (auto-updated)
├── posts/
│ └── YYYY-MM-DD-slug.html
├── assets/
│ ├── css/post.css ← estilo compartilhado (não modificar)
│ └── images/ ← imagens dos posts
├── TEMPLATE.html ← template com placeholders {{TITLE}}, {{BODY_HTML}}, etc.
└── scripts/
├── new-post.mjs ← scaffolda post a partir do TEMPLATE + corpo
└── update-index.mjs ← regenera index.html e README após cada novo post
Identifica:
Se input é assunto curto:
Skill({ skill: "dev-team-kit-fv:13-marketing-copy" }) pra pegar voz/tompolicies/anti-ai-writing.md (29 padrões) — sem hype, sem "delve into", sem
"comprehensive", sem em-dashes em rajadaSe input é texto pronto:
<h2>, <h3>, <p>, <ul>, <pre>, <code>, <table>, <blockquote>)Salvar como arquivo temporário: {blog_repo_path}/.tmp-body-{slug}.html
Post fala sobre URL/site/dashboard navegável?
├── SIM → Skill 42 (blog-screenshot) gera prints reais
└── NÃO → Skill 17 (image-generator) gera via fal.ai
├── default model: gemini-25-flash ($0.039/img)
├── 1 cover image obrigatória (1500×750)
└── inline images opcionais conforme o post
Cover image (OBRIGATÓRIA + VISÍVEL):
{blog_repo_path}/assets/images/{slug}-cover.{png|jpg}<meta og:image> pro share social — automático via {{COVER_IMAGE_URL}}; (b) <img> visível no body do post — automático via {{COVER_IMG_TAG}} (inserido logo abaixo do <h1> e meta, antes do <article>)--cover=assets/images/{slug}-cover.jpg pro new-post.mjs. Sem esse arg, o body fica sem cover visível (anti-padrão).Inline images (OBRIGATÓRIAS pra posts >1000 palavras):
{slug}-N-{seção}.jpg (ex: top-1-claude-code-1-claudemd.jpg)<p><img src="../assets/images/{slug}-N-{tema}.jpg" alt="descrição acessível"></p>
<h3> da seção correspondente (não depois)Posts curtos (<1000 palavras): só cover é OK, inline pode pular.
cd {blog_repo_path} && node scripts/new-post.mjs \
--slug={slug} \
--title="{title}" \
--lang={lang} \
--excerpt="{excerpt}" \
--cover=assets/images/{slug}-cover.png \
--body=.tmp-body-{slug}.html
O script:
TEMPLATE.html e substitui placeholdersposts/YYYY-MM-DD-{slug}.htmlupdate-index.mjs que regenera index.html + bloco no README.mdcd {blog_repo_path} && rm .tmp-body-{slug}.html
git add -A
git commit -m "post: {title}"
git push origin main
Aguardar GitHub Pages build (~30s) antes de retornar URL.
✅ Post publicado:
{pages_url}/posts/YYYY-MM-DD-{slug}.html
Index atualizado em: {pages_url}/
Source: {github_user_repo_url}/blob/main/posts/YYYY-MM-DD-{slug}.html
| Cenário | Provider | Modelo |
|---|---|---|
| Post sobre URL existente | Skill 42 (Playwright) | screenshot 1400×900 |
| Post sobre código/abstrato | Skill 17 (fal.ai) | gemini-25-flash (default) |
| Post precisa muita imagem | Skill 17 | gpt-image-1-mini (mais barato) |
| Post premium / hero importante | Skill 17 | gemini-3-pro ($0.15) |
| Tipografia/layout específicos | Skill 17 | gpt-image-1.5 |
Default: gemini-25-flash $0.039/img — boa qualidade, custo previsível.
{blog_repo_path}/posts/YYYY-MM-DD-{slug}.html{blog_repo_path}/assets/images/index.html e README.md atualizados (via update-index.mjs)| Anti-padrão | Por que evitar |
|---|---|
| Reescrever texto pronto sem permissão | User passou texto = quer publicar AQUELE texto, não outra versão |
| Gerar 10+ imagens | Distrai leitor + custo desnecessário. 1 cover + 1-3 inline já dá |
| Forçar tom storytelling em post técnico curto | Vira hype. Manter tom direto. |
| Postar sem cover image | OG sharing fica feio sem cover. Sempre 1 mínimo. |
| Hardcode de paths absolutos no HTML do post | Quebra Pages. Sempre paths relativos (../assets/...) |
| Commit sem rodar update-index.mjs antes | README e index.html ficam desatualizados |
| Esquecer de aplicar anti-ai-writing.md | Vira marketing genérico, perde credibilidade |
posts/YYYY-MM-DD-{slug}.html existe e é HTML válidoassets/images/{slug}-cover.* existeindex.html lista o post novoREADME.md lista o post novogit status está clean após commit+pushcurl -sI)Após retornar URL ao usuário, sugerir próximos passos opcionais:
medium.com/p/import (URL funciona porque Pages serve text/html)| Racionalização | Realidade |
|---|---|
| "Gera só texto, imagens depois" | Cover é obrigatória pra OG. Sempre gerar 1. |
| "Tom storytelling vende mais" | Sem evidência. Direto+números converte melhor pra dev audience. |
| "Pode ignorar anti-ai-writing num post pequeno" | Padrões aparecem mais visíveis em textos curtos, não menos. |
| "Skip o update-index, eu commito manual" | Quebra o invariante do repo. Sempre rodar o script. |
skills/17-image-generator/SKILL.md — geração via fal.aiskills/42-blog-screenshot/SKILL.md — screenshots Playwrightskills/13-marketing-copy/SKILL.md — voz e CTAspolicies/anti-ai-writing.md — 29 padrões a evitar{blog_repo_path}/TEMPLATE.html — template base{blog_repo_path}/scripts/new-post.mjs — scaffold{blog_repo_path}/scripts/update-index.mjs — index regenerator