Duas semanas atrás, a OpenAI apresentou as Codex Automations. A ideia: você define um gatilho (um cron, um push, uma nova issue), escreve instruções em linguagem natural e um agente executa sozinho em um worktree isolado. Sem intervenção humana. Enquanto você dorme, o agente organiza issues, resume falhas de CI, gera release briefs e até melhora suas próprias instruções.

Parece mágica. E é, um pouco. Mas tem um detalhe que não é muito mencionado no keynote: você precisa do app Codex rodando no seu desktop. macOS ou Windows. Nada de servidor headless. Nada de deixar no seu miniPC e esquecer.

E foi aí que eu pensei: “Espera. Eu já tenho isso.”

As peças que você já possui

Se você usa o Claude Code, já tem 90% da infraestrutura. claude --print executa um prompt sem sessão interativa. Você passa as instruções, ele te devolve o resultado e encerra. Sem GUI. Sem terminal aberto. Perfeito para um cron.

Se você tem um servidor sempre ligado (um miniPC, um Raspberry Pi, ou um VPS de 30 reais), já possui o agendador. systemd ou cron, o que preferir. Eles funcionam há décadas enquanto você dorme.

E se você usa Gitea, GitHub ou qualquer forge com API, já tem onde armazenar os resultados: comentários em PRs, novas issues ou arquivos commitados.

Dito de maneira simples: as Codex Automations são um padrão. Não um produto. E o padrão é antigo.

┌─────────────────────────────────────────────┐
│       systemd timer (a cada N horas)        │
│                     │                       │
│                     ▼                       │
│            script bash/fish                 │
│              │                              │
│              ├── git pull --ff-only         │
│              ├── claude --print "prompt"    │
│              ├── processar resultado        │
│              ├── notificar (Telegram/email) │
│              └── git push (se houver algo)  │
└─────────────────────────────────────────────┘

Anatomia de uma automação

Todas as automações seguem a mesma estrutura. Um script que:

  1. Atualiza o repositório (git pull)
  2. Executa o Claude Code em modo não interativo
  3. Faz algo com o resultado
  4. Notifica e/ou comita

Vamos configurar a primeira. Depois, as demais são variações simples desse tema.

O script básico

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/usr/bin/env bash
set -euo pipefail

REPO_DIR="/srv/social-publisher"
LOG_DIR="/var/log/automations"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)

cd "$REPO_DIR"
git pull --ff-only

RESULT=$(claude --print \
  --model sonnet \
  --max-turns 3 \
  "$1")  # O prompt vem como argumento

echo "$RESULT" > "$LOG_DIR/$TIMESTAMP.md"

Isso é tudo. O esqueleto tem apenas 12 linhas. O restante é decidir qual prompt você vai usar e o que fazer com $RESULT.

O timer do systemd

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# /etc/systemd/system/claude-automation.timer
[Unit]
Description=Automatização com Claude Code

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target
1
2
3
4
5
6
7
8
9
# /etc/systemd/system/claude-automation.service
[Unit]
Description=Executor de automações do Claude Code

[Service]
Type=oneshot
User=claude-runner
ExecStart=/opt/automations/review-prs.sh
Environment=ANTHROPIC_API_KEY=<sua-key>
1
sudo systemctl enable --now claude-automation.timer

Às 3 da manhã, o systemd executa o script. Claude analisa o que você pediu e deixa o resultado. Você fica sabendo na manhã seguinte.

Exemplo 1: Review automático de PRs

Este é o mais prático. Sempre que houver um PR aberto, Claude o revisa e publica um comentário.

Com um webhook seria mais elegante, mas um cron a cada 30 minutos funciona tão bem para equipes pequenas:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env bash
set -euo pipefail

GITEA_URL="https://git.exemplo.com"
GITEA_TOKEN="$(op read 'op://DEV/Gitea/token')"
REPO="minhaorg/meurepo"

# Obter PRs abertas
PRS=$(curl -s -H "Authorization: token $GITEA_TOKEN" \
  "$GITEA_URL/api/v1/repos/$REPO/pulls?state=open" \
  | jq -r '.[].number')

for PR_NUM in $PRS; do
  # Obter o diff
  DIFF=$(curl -s -H "Authorization: token $GITEA_TOKEN" \
    "$GITEA_URL/api/v1/repos/$REPO/pulls/$PR_NUM" \
    -H "Accept: application/diff")

  # Claude analisa o diff
  REVIEW=$(claude --print \
    --model sonnet \
    --max-turns 1 \
    "Revise este diff de um PR. Identifique bugs potenciais, \
     problemas de segurança e melhorias concretas. Seja direto. \
     Não repita o código, apenas indique os problemas com sua linha.

     $DIFF")

  # Publicar como comentário
  curl -s -X POST \
    -H "Authorization: token $GITEA_TOKEN" \
    -H "Content-Type: application/json" \
    "$GITEA_URL/api/v1/repos/$REPO/pulls/$PR_NUM/comments" \
    -d "{\"body\": \"## Review Automático\\n\\n$REVIEW\"}"
done

Todas as manhãs, quando você abre o Gitea, cada PR tem um comentário com observações. Não substitui o review humano, mas filtra o óbvio: typos, imports não utilizados, um if sem else que parece bug.

Exemplo 2: Triage diário de issues

Você tem 47 issues não atribuídas no Linear. Ninguém olha para elas. Elas se acumulam como e-mails não lidos. Este script as classifica toda noite:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/bin/env bash
set -euo pipefail

# Exportar issues não atribuídas
ISSUES=$(linear issue list \
  --team MYT \
  --state unstarted \
  --no-assignee \
  --sort created \
  --no-pager \
  --json)

# Claude as classifica
TRIAGE=$(claude --print \
  --model sonnet \
  --max-turns 1 \
  "Classifique estas issues por urgência (critical, high, medium, low).
   Para cada uma, sugira quem deve assumi-la com base na área 
   (frontend, backend, infra, docs).
   Formato: uma linha por issue, ID | urgência | área | motivo breve.

   $ISSUES")

# Enviar para o Telegram
curl -s -X POST \
  "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
  -d "chat_id=${CHAT_ID}" \
  -d "text=📋 Triage diário:

$TRIAGE" \
  -d "parse_mode=Markdown"

De manhã, enquanto toma café, você abre o Telegram e já tem um resumo: quais issues são urgentes e quem deveria cuidar delas. Em vez de abrir Linear, ler 47 títulos e decidir sozinho, o agente já fez o primeiro filtro.


E assim seguem outros exemplos, mas a estrutura para configurar tudo em um ambiente DIY com Claude Code e systemd já está suficientemente em detalhes aplamente explicada.