Kill the Standup
Lê as issues de ontem do Linear e os commits do GitHub. Formata uma atualização de standup. Publica no Slack.
Passo 1: Verificação de Configuração
Confirme se as variáveis de ambiente necessárias estão definidas:
echo "LINEAR_API_KEY: ${LINEAR_API_KEY:+set}"
echo "SLACK_WEBHOOK_URL: ${SLACK_WEBHOOK_URL:+set}"
echo "GITHUB_REPO: ${GITHUB_REPO:-não definido}"
echo "GITHUB_USERNAME: ${GITHUB_USERNAME:-não definido}"
Se LINEAR_API_KEY estiver faltando: Pare. Diga ao usuário: "LINEAR_API_KEY é obrigatório. Obtenha-a em Linear → Configurações → API → Chaves de API pessoais. Adicione-a ao seu arquivo .env."
Se SLACK_WEBHOOK_URL estiver faltando: Pare. Diga ao usuário: "SLACK_WEBHOOK_URL é obrigatório. Crie um Webhook de Entrada em api.slack.com/apps → Seu App → Webhooks de Entrada. Adicione-o ao seu arquivo .env."
Se GITHUB_REPO estiver faltando: Continue. Os commits do GitHub serão ignorados. Notifique o usuário sobre isso.
Passo 2: Buscar Atividade do Linear
Calcule a data de ontem no formato ISO 8601 (ex.: 2026-04-09T00:00:00.000Z).
Obter ID do usuário atual:
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: Bearer $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "query { viewer { id name email } }"}'
Extraia o campo id da resposta. Armazene como LINEAR_USER_ID.
Buscar issues atribuídas a mim, atualizadas desde ontem:
curl -s -X POST https://api.linear.app/graphql \
-H "Authorization: Bearer $LINEAR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "query($since: DateTime!, $userId: ID!) { issues(first: 50, filter: { assignee: { id: { eq: $userId } } updatedAt: { gte: $since } }) { edges { node { identifier title state { name } url completedAt updatedAt createdAt } } } }",
"variables": {"since": "YESTERDAY_ISO", "userId": "LINEAR_USER_ID"}
}'
Categorizar issues:
completedAtnão é nulo → Feitostate.nameé "In Progress", "Started" ou "In Review" → Fazendostate.nameé "Cancelled" → pularstate.nameé "Todo" ou "Backlog" → pular (não trabalhadas)
Se zero issues: anote "Nenhuma atividade do Linear encontrada para ontem."
Passo 3: Buscar Commits do GitHub
Ignore esta etapa silenciosamente se GITHUB_REPO não estiver definido.
Se GITHUB_REPO estiver definido:
gh api "repos/$GITHUB_REPO/commits?author=${GITHUB_USERNAME:-$(gh api user --jq .login)}&since=YESTERDAY_ISO&per_page=30" \
--jq '[.[] | {message: .commit.message, url: .html_url}]'
Processar commits:
- Extraia a primeira linha de cada mensagem de commit (tudo antes da primeira quebra de linha)
- Pule commits de merge: descarte mensagens que começam com "Merge"
- Desduplique por texto da mensagem
Se GITHUB_REPO estiver definido mas retornar zero commits: anote "Nenhum commit encontrado ontem."
Passo 4: Formatar Standup
Leia references/standup-format.md por completo antes de escrever.
Produza o standup exatamente nesta estrutura:
**Feito**
- [ENG-123] Título da issue concluída
- fix: mensagem do commit aqui
**Fazendo**
- [ENG-124] Título da issue em andamento
**Bloqueios**
Nenhum bloqueio.
Regras do standup-format.md:
- Sem pronomes de primeira pessoa ("eu", "nós")
- Pretérito para itens Feitos, presente contínuo para itens Fazendo
- Cada item do Linear usa o formato
[IDENTIFICADOR] Título - Cada commit do GitHub usa a primeira linha da mensagem do commit
- Se não houver itens Feitos: escreva "Nada concluído." sob Feito
- Se não houver itens Fazendo: escreva "Nada em andamento." sob Fazendo
- Se não houver bloqueios: escreva "Nenhum bloqueio."
- Menos de 200 palavras no total
Passo 5: Publicar no Slack ou Exibir
Apresente o standup formatado ao usuário.
Pergunte: "Publicar isso no Slack ou apenas exibir?"
Ao confirmar a publicação:
curl -s -X POST "$SLACK_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Standup — DATA_AQUI*\n\n*Feito*\nITENS\n\n*Fazendo*\nITENS\n\n*Bloqueios*\nITENS"
}
}
]
}'
Passe o corpo via um arquivo temporário ou heredoc para evitar problemas de citação do shell com caracteres especiais em mensagens de commit ou títulos de issues:
cat > /tmp/standup-payload.json << 'ENDJSON'
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "CONTEUDO_STANDUP_AQUI"
}
}
]
}
ENDJSON
curl -s -X POST "$SLACK_WEBHOOK_URL" -H "Content-Type: application/json" -d @/tmp/standup-payload.json
Após publicar: "Standup publicado."
Em "apenas exibir": Imprima o standup em um bloco de código para copiar e colar.