Command Code · estudo prático scheduler ● cron ● loops 04 out 2026 · PT-BR

Automação · agentes de código

O scheduler que mora dentro do seu agente

O Command Code tem um agendador de tarefas embutido: lembretes únicos, tarefas recorrentes no cron e loops que se ajustam sozinhos. Sem cron do sistema, sem serviço externo — o job acorda o agente, e o agente faz o trabalho. Este estudo mostra como tudo funciona por dentro.

*/5minuto
*hora
*dia do mês
*mês
*dia da semana

*/5 * * * * — lê-se: a cada 5 minutos, de toda hora, todo dia, todo mês, toda semana. É a expressão do job real que aparece no capítulo 06.

01

O que é o scheduler do Command Code

É um agendador de tarefas que vive dentro do agente. Você descreve o que quer que aconteça — em linguagem natural ou com uma expressão cron — e o Command Code registra uma tarefa. Quando o horário chega, o scheduler injeta aquela instrução como um novo turno do agente: ele executa o trabalho e ainda te dá uma resposta no chat.

A diferença para um cron tradicional é o que roda no horário marcado. Não é um script fixo: é o próprio agente, com todas as ferramentas dele — shell, arquivos, web, WhatsApp via MCP, sub-agentes. E a diferença para um serviço externo é onde ele mora: na sua conversa.

O que dispara
Um turno do agente com o prompt que você definiu — como se você tivesse digitado aquilo na hora.
Quem pode criar
Você, pedindo em linguagem natural, ou o agente via cron_create. Fixos também via /loop.
Onde vive
Na conversa (padrão). Ou em ~/.commandcode/cron/jobs.json quando criado como durable.
Quanto dura
Tarefas recorrentes expiram em 7 dias. One-shots se deletam depois de disparar.
02

Anatomia de um job: o cron_create

Todo job nasce de uma ferramenta só. Ela aceita quatro campos — e cada um responde uma pergunta diferente.

cron obrigatório

Quando? Expressão de 5 campos em horário local: minuto hora dia-do-mês mês dia-da-semana.

Aceita *, valores, passos (*/5), faixas (1-5) e listas (1,15). Sem aliases como @daily. Quando dia-do-mês e dia-da-semana estão ambos restritos, qualquer um dos dois pode casar.

prompt obrigatório

O quê? A instrução que vira um turno do agente a cada disparo.

Escreva auto-contido: o job acorda sem o contexto da conversa. Dados, caminhos e destinos precisam estar no texto.

recurring opcional

Repete? true dispara em cada casamento do cron; false é one-shot — dispara uma vez e se deleta sozinho.

default: true

durable opcional

Sobrevive à conversa? true grava o job em ~/.commandcode/cron/jobs.json, fora da sessão. Use só quando precisar de agendamento de máquina de verdade.

default: false
criação de um job recorrente
cron_create(
  cron:    "*/5 * * * *",          // a cada 5 minutos
  prompt:  "Busca o resultado, resume e envia no WhatsApp.",
  recurring: true,
  durable:   false              // vive nesta conversa
)

Umas expressões para guardar de referência:

Expressões cron que aparecem no dia a dia
ExpressãoO que fazExemplo de uso
*/5 * * * *A cada 5 minutosticker de apuração, monitoramento
7 11 * * 1-511h07, de segunda a sextaresumo matinal antes do almoço
20 16 4 10 *04/10 às 16h20 — uma vez sólembrete datado (one-shot)
6 9 1 * *Dia 1º de cada mês, 09h06relatório mensal

Por que minutos estranhos (06, 07, 53)? Dois motivos. O scheduler adiciona jitter pra espalhar carga, então horários “redondos” não são garantia de exatidão. E one-shots marcados em :00 ou :30 podem disparar até 90 segundos antes. Quando o timing exato importar, escolha outro minuto.

03

Como um job dispara

O caminho entre “chegou a hora” e “o agente fez o trabalho” tem cinco estágios — e cada um tem uma decisão de engenharia por trás.

  1. 01

    O scheduler checa a cada segundo. Um relógio interno varre as tarefas da conversa continuamente — não é um processo externo.

  2. 02

    Só submete entre turnos. Se o agente está ocupado respondendo algo, o evento espera o turno terminar. Nunca há duas coisas rodando em cima uma da outra.

  3. 03

    Sem rajada de recuperação. Ficou 1 hora offline com um job de 5 em 5 minutos? Ao voltar, ele dispara uma vez — não 12. Intervalos perdidos não geram catch-up em massa.

  4. 04

    Jitter determinístico. Tarefas recorrentes podem disparar até 10% do intervalo mais tarde (cap de 15 minutos). O atraso vem do id da tarefa, então é sempre o mesmo — inclusive depois de retomar a conversa.

  5. 05

    O texto chega cercado como dado. A instrução agendada entra em cena identificada como task data — ela não pode se passar por uma mensagem sua nem ampliar permissões.

Ida e volta na prática: com um job de 5 minutos, espere o disparo na janela de 5min + até ~30s de jitter. Não é “no segundo exato” — e isso é de propósito.

04

Ciclo de vida e escopo

Gerenciar é simples: um comando pra criar, um pra listar, um pra cancelar. O que exige atenção é onde a tarefa vive — porque isso decide se ela sobrevive a um restart, a um /clear ou a um fim de semana.

as três ferramentas de gestão
cron_create  // cria (recorrente ou one-shot)
cron_list    // lista tudo, com ids de 8 caracteres
cron_delete  // cancela pelo id

// na conversa, você também pode simplesmente pedir:
"quais tarefas agendadas eu tenho?"
"cancela a checagem do deploy"

Escopo conversa default

Vive nesta conversa. Fechar o Command Code pausa os disparos; --resume ou --continue restaura recorrentes ainda dentro dos 7 dias e one-shots cujo horário ainda não passou.

Conversa nova não roda tarefas de outra. Uma conversa pode ter até 50 tarefas agendadas.

Durable opt-in

Vive na máquina. Gravada em ~/.commandcode/cron/jobs.json, independente de retomar conversa. Um lease evita que duas sessões abertas disparem a mesma tarefa.

One-shot durable perdido com o app fechado pede confirmação no próximo launch.

Expiração: toda tarefa recorrente morre 7 dias depois de nascer. Uma tarefa fixa em atividade ganha um último disparo no vencimento; um loop self-paced simplesmente para no limite. Precisa de algo perpétuo? Recrie antes de expirar ou use um scheduler externo chamando o modo headless.

kill switches (variáveis de ambiente)
COMMANDCODE_DISABLE_CRON=1          // desliga /loop e todas as ferramentas do scheduler
COMMANDCODE_DISABLE_DURABLE_CRON=1  // rebaixa durable → escopo de conversa

Detalhe honesto: cada disparo roda um turno normal do agente. Um job de 5 minutos gera até 288 turnos por dia — vale dimensionar a frequência como você dimensionaria qualquer automação.

05

Loops: fixos e self-paced

Para o caso “roda agora e fica de olho”, existe o /loop — um atalho de primeira classe para o scheduler, com parsing determinístico de cadência (você não depende do modelo adivinhar o intervalo).

formas do /loop
/loop 5m check the deploy      // roda agora + fixo a cada 5 min
/loop check the deploy          // roda agora + o agente escolhe o próximo intervalo
/loop 15m                       // tarefa padrão a cada 15 min
/loop                           // tarefa padrão com ritmo adaptativo

Fixo — ticker previsível

Você dá o intervalo (s, m, h, d) e a primeira execução é imediata. Cadências que não encaixam num passo cron limpo são normalizadas para a mais próxima — e a confirmação mostra qual foi escolhida.

Recebe o jitter determinístico dos recorrentes (até 10% do intervalo).

Self-paced — ritmo adaptativo

Sem intervalo, o agente decide o próximo passo a cada iteração: de 1 minuto a 1 hora, com uma razão curta registrada. Cada escolha substitui a anterior — não empilha.

Sem jitter. Um por conversa. Se uma iteração terminar sem decidir o próximo passo, rola um check de segurança em 20 minutos; se ele também não decidir, o loop encerra.

Tarefa padrão: um /loop sem tarefa usa uma manutenção pré-definida (continuar trabalho inacabado, cuidar de PR/CI da branch atual, uma passada de qualidade). Você pode trocar por um arquivo markdown: .commandcode/loop.md tem precedência; ~/.commandcode/loop.md é o fallback. O arquivo é relido a cada iteração e truncado se passar de 25 kB.

Onde não roda: modo headless (cmd -p), dentro de sub-agentes e em plan mode — ali, agendar é uma escrita, e escrita está bloqueada. Para parar: Esc cancela os loops pendentes da conversa sem tocar nos seus outros agendamentos.

06

O caso real: apuração → WhatsApp

Este estudo nasceu de um job de verdade. O pedido: “manda a apuração da eleição pra Edna no WhatsApp a cada 5 minutos”. O que foi montado:

id 7ecfbe5b cron */5 * * * * escopo conversa expira em 7 dias
o prompt do job (resumido)
Envie a apuração ao vivo das eleições para Edna (chatId 5521…@c.us,
sessão WAHA "default").

1) Busque os dados oficiais do TSE via curl (com cache-buster).
   Se der 404, tente o código do 2º turno. Se ambos falharem, não envie.
2) Extraia: % de seções apuradas, comparecimento e os 2 candidatos
   mais votados — com vantagem em pontos e em votos.
3) Envie via mcp__waha__send-text no formato definido aqui.
   Envie em toda execução, mesmo sem mudança nos números.
4) Responda no chat apenas com uma linha de confirmação.

A cada 5 minutos, o scheduler acorda o agente; o agente faz o curl, formata e dispara a mensagem. Três lições que esse job ensina:

  • O prompt é auto-contido. Nada de “como combinamos antes” — o job carrega o comando do TSE, o chatId e o formato da mensagem dentro dele.
  • Falha tem caminho de saída. O prompt define o fallback (2º turno) e a regra de silêncio (se falhar, não manda nada) — sem isso, um 404 viraria mensagem de erro pro destinatário.
  • Escopo importa. Como é escopo conversa, o envio continua enquanto a conversa for retomada dentro dos 7 dias. Se o app ficasse fechado, os disparos pausariam — e nada de catch-up ao voltar.
07

Boas práticas e pegadinhas

O que separa um job que funciona de um que vira ruído:

  • Escreva o prompt pensando num estranho. Quem executa é o agente sem o contexto da conversa — inclua caminhos, ids, destinos e formato.
  • Teste com one-shot antes. “Em 2 minutos, faça X” valida o fluxo inteiro sem risco de repetição. Depois promova para recorrente.
  • Não conte com exatidão. Recorrentes têm até 10% de jitter; one-shot em :00/:30 pode adiantar até 90s. Para timing exato de verdade, use um scheduler externo.
  • App fechado = tarefa pausada. No escopo conversa, nada dispara com o Command Code fechado. Precisa disso de pé? durable: true ou cron do sistema.
  • Efeitos externos pedem cuidado. Um job que manda mensagem, abre PR ou publica algo repete o efeito a cada disparo. Defina idempotência no prompt (ex.: “só envie se o número mudou”).
  • Lembre dos 7 dias. Recorrentes expiram. Para algo mais longo, planeje recriar — ou vá de scheduler externo + headless.
  • Respeite o destinatário. Frequência de 5 minutos faz sentido numa apuração ao vivo; para status de rotina, 1–2 vezes por dia costuma bastar.
  • Cada disparo custa um turno. É o comportamento desejado, mas vale lembrar: alta frequência = muitos turnos de agente por dia.
08

Quando usar o quê

Ferramenta certa para cada tipo de automação
Você quer…UsePor quê
Um lembrete único (“em 45 min…”, “às 15h05…”)cron_create one-shotdispara uma vez e se deleta sozinho
Rodar agora e re-checar num ritmo fixo/loop 5m …primeira execução imediata + cadência previsível
Re-checar com ritmo adaptativo/loop …o agente decide o próximo intervalo (1 min–1 h)
Sobreviver a restart, sem conversadurable: truegrava em ~/.commandcode/cron/jobs.json
Rodar para sempre / em headlessScheduler externo + cmd -precorrentes internas expiram em 7 dias
Esperar algo terminar (interrompível)sleeppausa sem segurar processo; acorda se você digitar

Regra de bolso: precisa de contexto entre execuções, ou de efeito externo? Trate como automação de verdade — prompt auto-contido, idempotência e uma válvula de parada. É só um lembrete? Linguagem natural basta: “me lembra às 15h05 de revisar o PR”.