Automação, JSON e solução de problemas


Sem perguntas interativas#

Um argumento obrigatório que falta é um erro imediato, com uma dica de uso, nunca uma pergunta, e o comando sai com código diferente de zero. Nada trava um script ou um agente esperando entrada.

Alguns comandos fazem perguntas, mas só quando há uma pessoa em um terminal:

  • O zeltro create só pergunta em um terminal. Com --one-off, --json-output ou uma stdin que não é terminal, ele volta para o erro imediato.
  • O zeltro configure pergunta o diretório de projetos (e o seu nome e e-mail do git, se o git não tiver nenhum), a menos que você passe --non-interactive (--yes, -y) ou --json-output. Passe --projects-dir para definir o diretório sem pergunta.
  • O zeltro ai-set sem flags abre um menu em um terminal. Com qualquer flag, ou sem terminal, não abre.
  • O zeltro uninstall pergunta se deve apagar as imagens Docker, a menos que você passe --delete-images ou --json-output.

Use zeltro up-all / zeltro down-all para agir em todos os projetos em vez de fazer um loop.

Rodando comandos em um projeto#

Use zeltro exec <cmd> a partir do diretório do projeto. Ele roda sem TTY, roda como o seu próprio usuário para que os arquivos montados continuem graváveis, e devolve o código de saída do comando. O zeltro exec-root faz o mesmo como root. Os dois aceitam argumentos separados ou uma única string entre aspas:

zeltro exec python3 manage.py migrate
zeltro exec "php artisan migrate --force"

zeltro bash, zeltro tinker e zeltro exec-tty / exec-tty-root são para uso interativo e alocam um TTY quando existe um. Também não use um docker exec -u developer … direto: o usuário developer do contêiner não é o dono dos arquivos do seu projeto.

Substituições de IA por sessão#

zeltro ai, resume, create, clone, create-installer e update-installer usam o agente definido pelo zeltro ai-set. Para usar outro em uma única execução, defina estas variáveis no ambiente. Elas nunca são escritas na configuração.

Variável Substitui
ZELTRO_AI_AGENT O agente: codex, claude, agy, aider, qwen, opencode, hermes ou gemini (obsoleto)
ZELTRO_AI_MODEL O modelo
ZELTRO_AI_API_BASE O endpoint da API
ZELTRO_AI_API_KEY A chave de API
ZELTRO_AI_API_KEY_FILE A chave de API, lida da primeira linha do arquivo. Tem prioridade sobre ZELTRO_AI_API_KEY.
ZELTRO_AI_LANGUAGE O idioma em que o agente responde, por exemplo Spanish. A saída do próprio Zeltro continua em inglês.

Não definida significa "usar o valor do ai-set"; definida mas vazia apaga o valor nesta execução. Um nome de agente desconhecido, um arquivo de chave ilegível ou um agente de substituição que não está instalado sai com código diferente de zero antes de qualquer coisa rodar. zeltro ai-set --install-only --agent <name> instala um agente sem torná-lo o padrão.

Mensagens entre sessões de agentes#

Quando o app Zeltro roda sessões de agentes em vários projetos, elas podem trocar mensagens:

zeltro peers                                  # live sessions, as project@host
zeltro send blog api -- "schema changed"      # to one or more sessions
zeltro send --all -- "rebasing main"          # to every other session
echo "long message" | zeltro send blog -- -   # read the message from stdin

Rode o send de dentro do diretório do seu projeto; é assim que o destinatário sabe quem enviou. Todos os destinos precisam estar ativos, senão nada é enviado. As mensagens têm limite de 16 KB. Quem entrega é o app, então ele precisa estar rodando.


Saída JSON#

--json-output gera uma saída limpa, legível por máquina, para interfaces gráficas e scripts.

zeltro status --json-output
zeltro new laravel myapp --json-output

O new imprime um objeto, com o resultado da etapa de setup aninhado dentro dele:

{
  "action": "new_project",
  "project_name": "myapp",
  "framework": "laravel",
  "database": "mysql",
  "setup_result": { "action": "setup_project", "status": "success", "...": "..." },
  "status": "success"
}

Quando o setup precisou ligar um servidor de banco de dados, o setup_result também traz services_enabled (por exemplo ["postgres"]) e admin_uis_suggested.

O status imprime shared_services, indexado pelo nome do contêiner, e projects:

{
  "shared_services": {
    "zeltro-mariadb": { "name": "zeltro-mariadb", "status": "running", "port": "3306", "resolved_ip": "10.x.x.2", "ping_status": "ok" }
  },
  "projects": [
    {
      "name": "my-api",
      "project_ip": "10.x.x.219",
      "external_port": "219",
      "docker_running": true,
      "http_status": "ok",
      "local_url": "http://10.x.x.219",
      "lan_url": "http://192.168.1.20:219",
      "metadata": {}
    }
  ]
}

O status de um serviço é running ou stopped. Sem --all, projects lista só os projetos em execução.

Outros formatos, todos com action e status:

Comando Saída
enable-service (sem nome) action: "list_services", always_on e services[] com slug, group, description, address, state (running, disabled ou enabled_not_running)
enable-service <name> / disable-service <name> action: "enable_service" / "disable_service", service, enabled (a nova lista separada por espaços)
ai-set (só --json-output) action: "ai_set", agent, model, api_base, has_api_key, unattended, installed_agents. Somente leitura.
peers action: "peers", this_host, me, app_running, updated_at, age_seconds, sessions[]
send action: "send", id, from, to, file, app_running
down action: "shutdown", target, project_name
remove action: "remove_project", project_name, database_deleted

Os erros imprimem "status": "error" com um campo message ou error e saem com código diferente de zero, então confira o código de saída além do JSON.

Exemplos de script:

# is the shared MariaDB up?
if zeltro status --json-output | jq -e '.shared_services["zeltro-mariadb"].status == "running"' >/dev/null; then
    echo "Database is ready"
fi

# list stopped projects
zeltro status --all --json-output | jq -r '.projects[] | select(.docker_running == false) | .name'

Quais comandos suportam#

Suportam: status, new, clone, setup, remove, up, down, down-all, start-services, stop-services, enable-service, disable-service, enable, disable, set-metadata, configure, create (inclusive --classify-only), ai-set, peers, send.

Em parte: install --json-output imprime o JSON das etapas setup e up, mas nenhum objeto de resumo próprio. uninstall --json-output só pula a pergunta sobre as imagens; não imprime JSON.

Não suportam — tudo o que roda dentro de um contêiner ou se conecta direto a um serviço: composer, art, wp, php, npm, npx, node, python, pip, shell, django, exec, supervisor, redis, memcache.

Se você é um agente de IA, nunca use --json-output. Ele suprime toda a saída legível por pessoas, inclusive a distinção entre sucesso e falha, então você não consegue saber se um comando realmente funcionou. Ele existe para programas externos que interpretam a saída do Zeltro, não para agentes que operam o CLI.


Depuração#

zeltro new laravel test-project --debug
tail -f /tmp/zeltro-cli-debug.log

O --debug funciona em new, clone, setup, up, down, status, remove, configure, start-services, stop-services e uninstall. Cada chamada sobrescreve o log e registra o fluxo pelos scripts que ela chama. Defina DEBUG_LOG_PATH para gravá-lo em outro lugar.


Solução de problemas#

Sintoma O que verificar
Os serviços não iniciam O Docker está rodando; você está no grupo docker (saia da sessão e entre de novo depois da instalação)
Erros de permissão O mesmo — fazer parte do grupo docker exige um novo login
Não consigo acessar um projeto no navegador Use o endereço que o zeltro status <project> mostra (http://<project>/ não é resolvido no host); depois docker logs <project-name>
Conexão com o banco de dados recusada zeltro status — o serviço compartilhado está rodando? Se aparecer stopped, zeltro enable-service mysql (ou postgres, mongo)
O projeto dá 502 depois de reiniciar Uma dependência não está na imagem base. Veja Arquitetura → Imagens base
Fedora: permissão negada nos arquivos do projeto SELinux — rode zeltro configure de novo para refazer o rótulo. Veja Instalação
Arch: o Docker não inicia depois da instalação A atualização do sistema substituiu o kernel em execução — reinicie

Verificações úteis:

zeltro status                               # shared services and running projects
zeltro status --all                         # include stopped projects
zeltro status <project>                     # one project, even if stopped
docker logs <project-name>
zeltro exec "getent hosts zeltro-mariadb"   # name resolution from inside the container

Ferramentas gráficas#

Os instaladores trazem o ImageMagick (convert, magick) e o rsvg-convert no host, então projetos que precisam de gráficos não têm dependências extras.

Prefira gerar SVG — os navegadores o renderizam perfeitamente e é texto que um agente pode escrever diretamente. Converta só quando um bitmap for realmente necessário:

rsvg-convert sprite.svg -o sprite.png                        # best SVG → PNG fidelity
convert -size 1200x800 gradient:'#1e3a8a-#04081d' bg.png     # procedural backgrounds

Essas são ferramentas do host — rode-as diretamente, não pelo zeltro exec.

Achou um erro nesta tradução? Avise a gente no GitHub.