Imported from viaiv/skills (
changelog/SKILL.md). Install upstream withnpx skills add viaiv/skills --skill changelog. Copyright stays with the author.
Gerar Changelog para Cliente
Você deve gerar relatórios HTML não-técnicos para o portal público do cliente a partir dos commits recentes do projeto. Argumentos opcionais: $ARGUMENTS (ex: "desde 2026-03-01", "últimos 10 commits", ou vazio para automático).
Passo 1: Verificar configuração
Leia o arquivo .changelog.json na raiz do projeto.
- Se existe → pule para o Passo 3 (fluxo normal)
- Se NÃO existe → execute o Passo 2 (onboarding)
Passo 2: Onboarding (primeira execução)
Quando .changelog.json não existe, faça o setup completo do portal. Use AskUserQuestion para coletar as informações necessárias.
2.1 Coletar informações
Pergunte ao usuário:
- Nome do projeto — ex: "BORDER", "CRM", "Portal"
- Nome do cliente — quem verá os relatórios (ex: "Baerlocher", "Acme Corp")
- Idioma — padrão pt-BR
- Branding:
- URL do logo (pode ser vazio)
- Nome da empresa que aparece no footer (ex: "IPWise", "VIAIV")
- Cor primária (padrão:
#1FBFDC) - Texto do footer (ex: "PROJETO — Descrição curta")
- Auth gate — "O portal terá frase de acesso?" Se sim, pergunte a frase e gere o hash SHA-256
- Instruções de contexto — "Descreva em 1-2 frases o que o sistema faz e quem é o público dos relatórios"
2.2 Gerar .changelog.json
Crie o arquivo na raiz do projeto com os dados coletados. O output_dir padrão é changelog-pub:
{
"project_name": "{{NOME}}",
"client_name": "{{CLIENTE}}",
"language": "pt-BR",
"branding": {
"logo_url": "{{LOGO_URL}}",
"company_name": "{{EMPRESA}}",
"accent_color": "{{COR}}",
"footer_text": "{{FOOTER}}"
},
"output_dir": "changelog-pub",
"reports_dir": "changelog-pub/reports",
"index_file": "changelog-pub/index.html",
"templates_dir": "changelog-pub/templates",
"auth_gate": {
"enabled": true/false,
"hash": "{{SHA256_HASH_OU_VAZIO}}"
},
"filters": {
"exclude_scopes": ["deps", "i18n", "migration", "models"],
"exclude_types": ["chore", "debug", "test", "docs", "refactor"],
"min_commit_message_length": 20
},
"instructions": "{{CONTEXTO}}"
}
2.3 Criar estrutura de pastas
{output_dir}/
├── index.html
├── assets/
│ ├── styles.css
│ ├── auth.js (só se auth_gate.enabled)
│ └── form.js (só se houver integração de chamados)
├── reports/
├── templates/
│ ├── report.html
│ └── card-snippet.html
├── nginx.conf
├── Dockerfile
└── .dockerignore
2.4 Gerar assets/styles.css
Gere um CSS completo com estes componentes (adaptar cores do branding):
Variáveis CSS (adaptar --accent para a cor do branding):
:root {
--bg: #fafbfc; --surface: #ffffff; --border: #e1e4e8;
--text: #1f2937; --text-muted: #6b7280; --text-light: #9ca3af;
--accent: {{COR_PRIMARIA}}; --accent-light: {{COR_CLARA}};
--green: #059669; --green-light: #ecfdf5; --green-border: #a7f3d0;
--red: #dc2626; --red-light: #fef2f2; --red-border: #fecaca;
--yellow: #d97706; --yellow-light: #fffbeb; --yellow-border: #fde68a;
--radius: 12px; --radius-sm: 8px;
--shadow: 0 1px 3px rgba(0,0,0,0.06); --shadow-md: 0 4px 6px rgba(0,0,0,0.05);
}
Componentes obrigatórios:
.nav-bar— barra superior com fundo branco, borda inferior, logo + nome do projeto.portal-hero— hero centralizado com título e subtítulo.portal-content— container max-width 780px.report-card— card clicável com borda-left accent, hover com shadow.status-badge.resolved/.open— badges verde/amarelo.type-badge.fix/.feature— badges de tipo.header— cabeçalho do relatório com status badge.content— container do relatório.section,.section-label,.section-title— seções.card— bloco de texto.highlight-box.problem/.solution/.info— destaques vermelho/verde/amarelo.timeline,.timeline-item,.timeline-dot,.timeline-bubble— conversa visual.comparison,.comparison-col.before/.after— antes/depois.examples-table— tabela de exemplos.result-tag.pass/.fail— badges inline.divider— separador.footer— footer com logo e texto.hidden— display none.auth-gate(se habilitado) — tela de acesso centralizada.report-form,.form-group,.form-input,.form-textarea,.form-button,.form-success,.form-error— formulário- Responsivo (
@media max-width: 640px)
2.5 Gerar assets/auth.js (se auth_gate.enabled)
Script que:
- Verifica
sessionStorage.getItem("portal-key") - Se não existe: mostra
#auth-gate, esconde#portal-content - No submit: valida a frase via SHA-256 comparado com
window.PORTAL_KEY_HASH - Se válida: salva no sessionStorage, mostra conteúdo
- Exporta
window.getPortalKey()para uso em formulários
2.6 Gerar index.html
Estrutura:
<body>
<!-- Auth gate (se habilitado, visível por padrão) -->
<div class="auth-gate" id="auth-gate">...</div>
<!-- Conteúdo (hidden se auth_gate habilitado) -->
<div class="portal-content-wrapper {{HIDDEN}}" id="portal-content">
<nav class="nav-bar">...</nav>
<section class="portal-hero">
<h1>Portal de Relatórios</h1>
<p>Acompanhe as correções e melhorias...</p>
</section>
<main class="portal-content">
<div class="portal-section-label">Relatórios recentes</div>
<!-- Cards dos relatórios serão inseridos aqui -->
</main>
<footer>...</footer>
</div>
<script>window.PORTAL_KEY_HASH = "{{HASH}}";</script>
<script src="assets/auth.js"></script>
</body>
2.7 Gerar templates
templates/report.html — template completo de relatório com placeholders {{...}}:
- Auth gate (se habilitado)
- Navbar com link "Voltar aos relatórios"
- Header com status badge
- Seções: "O que aconteceu", "Por que aconteceu", "O que foi corrigido", "Resumo"
- Seções opcionais comentadas: "Conversa registrada" (timeline), "Exemplos" (tabela), comparação antes/depois
- Footer com branding
templates/card-snippet.html — snippet de card para o index.html com placeholders.
2.8 Gerar nginx.conf
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/json image/svg+xml;
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; }
location ~* \.html$ { expires 1h; add_header Cache-Control "public, must-revalidate"; }
location /internal/ { deny all; return 403; }
location / { try_files $uri $uri/ =404; }
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
}
2.9 Gerar Dockerfile
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY . /usr/share/nginx/html
RUN rm -f /usr/share/nginx/html/Dockerfile /usr/share/nginx/html/nginx.conf /usr/share/nginx/html/.dockerignore
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
2.10 Gerar .dockerignore
.git
*.md
.vscode
.idea
*.log
2.11 Informar o usuário
Mostre:
- Lista de arquivos criados
- Como testar:
xdg-open {index_file}ouopen {index_file} - Como buildar Docker:
docker build -t {project}-changelog ./{output_dir} - "O portal está pronto. Execute
/changelognovamente para gerar relatórios a partir dos commits."
Passo 3: Determinar ponto de partida
- Liste os arquivos em
reports_dircomls -1 - Extraia o maior número dos nomes de arquivo (ex:
15-reconhecimento-empresa.html→ 15) - Leia esse último arquivo e extraia a data do campo
header-dateoureport-card-date - Essa data é o ponto de corte — commits depois dela são candidatos
- Se
$ARGUMENTScontém uma data ou hash, use como ponto de partida em vez do automático - Se não existem relatórios ainda (pasta vazia), use todos os commits do projeto
Passo 4: Buscar e filtrar commits
- Execute:
git log --oneline --no-merges --format="%h %ad %s" --date=short --after={data_corte} - Para cada commit, parse o formato conventional commit:
type(scope): message - Excluir commits onde:
typeestá emfilters.exclude_typesscopeestá emfilters.exclude_scopes- mensagem tem menos de
filters.min_commit_message_lengthcaracteres
- Manter commits com impacto visível para o cliente: features, fixes que afetam UX
Passo 5: Agrupar commits
Commits relacionados devem virar um único relatório. Critérios para agrupar:
- Mesmo scope/feature (ex: 3 commits de "attachment" → 1 relatório)
- Mesmo dia e mesmo tema
- Fix seguido de refinamento do mesmo fix
Para cada grupo, definir:
- Título: curto, não-técnico, descreve o benefício para o cliente
- Tipo:
fix(Correção) oufeature(Melhoria) - Commits: lista de hashes incluídos
- Resumo: 1-2 frases descrevendo o impacto
Passo 6: Apresentar ao usuário
Mostre uma tabela com os agrupamentos propostos:
| # | Título | Tipo | Commits | Data |
|---|--------|------|---------|------|
| 16 | ... | feature | abc123, def456 | 28/mar |
| 17 | ... | fix | ghi789 | 29/mar |
Pergunte ao usuário:
- "Deseja gerar esses relatórios? Pode remover, editar títulos ou reagrupar."
- Aguarde confirmação antes de gerar
Passo 7: Gerar HTMLs
Para cada relatório aprovado:
- Leia o template em
{templates_dir}/report.html - Determine o próximo número sequencial (último + 1, +2, etc.)
- Crie o arquivo em
{reports_dir}/{NUM:02d}-{slug}.htmlonde slug é o título slugificado - Preencha o conteúdo seguindo estas regras:
- Linguagem definida em
config.language - Tom e contexto definidos em
config.instructions - NÃO use jargão técnico, código, IDs internos, traces ou nomes de funções
- SEMPRE use acentuação correta (é, á, ã, ç, etc.)
- Seções obrigatórias: "O que aconteceu" → "Por que aconteceu" → "O que foi corrigido" → "Resumo"
- Seções opcionais: "Conversa registrada" (timeline), "Exemplos" (tabela), comparação antes/depois
- Use os componentes CSS do
assets/styles.css
- Linguagem definida em
- Se
auth_gate.enabled, inclua o auth gate com o hash configurado - Use o branding do config (logo, cores, footer text)
Passo 8: Atualizar index.html
- Leia
{index_file} - Leia o template de card em
{templates_dir}/card-snippet.html - Para cada novo relatório, crie um card preenchido
- Insira os cards na posição cronológica correta (mais recente primeiro)
- Salve o arquivo
Passo 9: Reportar
Mostre ao usuário:
- Quantos relatórios foram gerados
- Lista de arquivos criados com caminhos
- Comando para visualizar:
xdg-open {index_file}ouopen {index_file}
Regras importantes
- NUNCA gere relatórios sem aprovação do usuário (passo 6)
- NUNCA inclua linguagem técnica nos relatórios — o público é o cliente final
- SEMPRE use acentuação/diacríticos corretos no idioma configurado
- SEMPRE leia o template existente antes de gerar — não reinvente o HTML
- SEMPRE mantenha a numeração sequencial sem pular números
- Se não houver commits novos relevantes, informe o usuário e não gere nada