Automatisierung, JSON und Fehlerbehebung


Keine interaktiven Abfragen#

Ein fehlendes Pflichtargument ist ein harter Fehler mit einem Hinweis zur Verwendung, nie eine Rückfrage, und der Befehl endet mit einem Exit-Code ungleich null. Nichts blockiert ein Skript oder einen Agenten, der auf eine Eingabe wartet.

Einige Befehle stellen durchaus Fragen, aber nur, wenn ein Mensch am Terminal sitzt:

  • zeltro create fragt nur in einem Terminal nach. Mit --one-off, --json-output oder einem stdin, das kein Terminal ist, gilt wieder der harte Fehler.
  • zeltro configure fragt nach dem Projektverzeichnis (und nach Ihrem Git-Namen und Ihrer E-Mail-Adresse, falls Git keine kennt), es sei denn, Sie übergeben --non-interactive (--yes, -y) oder --json-output. Mit --projects-dir setzen Sie das Verzeichnis ohne Rückfrage.
  • zeltro ai-set ohne Optionen öffnet in einem Terminal ein Menü. Mit irgendeiner Option oder ohne Terminal nicht.
  • zeltro uninstall fragt, ob die Docker-Images gelöscht werden sollen, es sei denn, Sie übergeben --delete-images oder --json-output.

Nutzen Sie zeltro up-all / zeltro down-all, um auf alle Projekte zu wirken, statt eine Schleife zu schreiben.

Befehle in einem Projekt ausführen#

Nutzen Sie zeltro exec <cmd> im Projektverzeichnis. Es läuft ohne TTY, als Ihr eigener Benutzer, damit die per Bind-Mount eingebundenen Dateien beschreibbar bleiben, und gibt den Exit-Code des Befehls zurück. zeltro exec-root macht dasselbe als root. Beide nehmen einzelne Argumente oder einen String in Anführungszeichen:

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

zeltro bash, zeltro tinker und zeltro exec-tty / exec-tty-root sind für die interaktive Nutzung gedacht und belegen ein TTY, wenn eines da ist. Nutzen Sie auch kein rohes docker exec -u developer …: Dem Benutzer developer des Containers gehören Ihre Projektdateien nicht.

KI-Einstellungen pro Sitzung überschreiben#

zeltro ai, resume, create, clone, create-installer und update-installer nutzen den Agenten, der mit zeltro ai-set festgelegt wurde. Um für einen einzelnen Lauf einen anderen zu nutzen, setzen Sie diese Variablen in der Umgebung. Sie werden nie in die Konfiguration geschrieben.

Variable Überschreibt
ZELTRO_AI_AGENT Den Agenten: codex, claude, agy, aider, qwen, opencode, hermes oder gemini (veraltet)
ZELTRO_AI_MODEL Das Modell
ZELTRO_AI_API_BASE Den API-Endpunkt
ZELTRO_AI_API_KEY Den API-Schlüssel
ZELTRO_AI_API_KEY_FILE Den API-Schlüssel, gelesen aus der ersten Zeile der Datei. Hat Vorrang vor ZELTRO_AI_API_KEY.
ZELTRO_AI_LANGUAGE Die Sprache, in der der Agent antwortet, z. B. Spanish. Zeltros eigene Ausgabe bleibt Englisch.

Nicht gesetzt heißt „den Wert aus ai-set nutzen“; gesetzt, aber leer löscht ihn für diesen Lauf. Ein unbekannter Agentenname, eine nicht lesbare Schlüsseldatei oder ein überschreibender Agent, der nicht installiert ist, beendet den Befehl mit einem Exit-Code ungleich null, bevor irgendetwas läuft. zeltro ai-set --install-only --agent <name> installiert einen Agenten, ohne ihn zum Standard zu machen.

Nachrichten an andere Agenten-Sitzungen#

Wenn die Zeltro-App Agenten-Sitzungen in mehreren Projekten betreibt, können diese einander Nachrichten schicken:

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

Führen Sie send in Ihrem Projektverzeichnis aus; daran erkennt der Empfänger, wer die Nachricht geschickt hat. Jedes Ziel muss aktiv sein, sonst wird nichts gesendet. Nachrichten sind auf 16 KB begrenzt. Die App stellt sie zu, sie muss also laufen.


JSON-Ausgabe#

--json-output liefert saubere, maschinenlesbare Ausgabe für GUIs und Skripte.

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

new gibt ein Objekt aus, in dem das Ergebnis des Setup-Schritts verschachtelt ist:

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

Musste das Setup einen Datenbankserver einschalten, enthält setup_result zusätzlich services_enabled (zum Beispiel ["postgres"]) und admin_uis_suggested.

status gibt shared_services aus, nach Container-Namen geordnet, sowie 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": {}
    }
  ]
}

Der status eines Dienstes ist running oder stopped. Ohne --all listet projects nur laufende Projekte.

Weitere Formen, alle mit action und status:

Befehl Ausgabe
enable-service (ohne Namen) action: "list_services", always_on und services[] mit slug, group, description, address, state (running, disabled oder enabled_not_running)
enable-service <name> / disable-service <name> action: "enable_service" / "disable_service", service, enabled (die neue, durch Leerzeichen getrennte Liste)
ai-set (nur --json-output) action: "ai_set", agent, model, api_base, has_api_key, unattended, installed_agents. Nur lesend.
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

Fehler geben "status": "error" mit einem Feld message oder error aus und enden mit einem Exit-Code ungleich null. Prüfen Sie also den Exit-Code ebenso wie das JSON.

Beispiele für Skripte:

# 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'

Welche Befehle es unterstützen#

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

Teilweise: install --json-output gibt das JSON seiner Schritte setup und up aus, aber kein eigenes Zusammenfassungsobjekt. uninstall --json-output überspringt nur die Frage nach den Images; JSON gibt es nicht aus.

Nicht unterstützt – alles, was in einem Container läuft oder sich direkt mit einem Dienst verbindet: composer, art, wp, php, npm, npx, node, python, pip, shell, django, exec, supervisor, redis, memcache.

Wenn Sie ein KI-Agent sind, nutzen Sie nie --json-output. Es unterdrückt jede für Menschen lesbare Ausgabe, auch die Unterscheidung zwischen Erfolg und Fehler, sodass Sie nicht erkennen können, ob ein Befehl tatsächlich funktioniert hat. Es ist für externe Programme gedacht, die Zeltros Ausgabe auswerten, nicht für Agenten, die die CLI bedienen.


Fehlersuche#

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

--debug funktioniert bei new, clone, setup, up, down, status, remove, configure, start-services, stop-services und uninstall. Jeder Aufruf überschreibt das Log und zeichnet den Ablauf über alle aufgerufenen Skripte hinweg auf. Mit DEBUG_LOG_PATH schreiben Sie es an einen anderen Ort.


Fehlerbehebung#

Symptom Prüfen
Dienste starten nicht Docker läuft; Sie sind in der Gruppe docker (nach der Installation ab- und wieder anmelden)
Fehler bei Berechtigungen Dasselbe – die Mitgliedschaft in der Gruppe docker braucht eine neue Anmeldung
Projekt im Browser nicht erreichbar Nutzen Sie die Adresse, die zeltro status <project> anzeigt (http://<project>/ wird auf dem Host nicht aufgelöst); danach docker logs <project-name>
Datenbankverbindung abgelehnt zeltro status – läuft der gemeinsame Dienst? Zeigt er stopped, dann zeltro enable-service mysql (oder postgres, mongo)
Projekt liefert nach einem Neustart 502 Eine Abhängigkeit fehlt im Basis-Image. Siehe Architektur → Basis-Images
Fedora: Zugriff auf Projektdateien verweigert SELinux – führen Sie zeltro configure erneut aus, um neu zu labeln. Siehe Installation
Arch: Docker startet nach der Installation nicht Das System-Upgrade hat den laufenden Kernel ersetzt – neu starten

Nützliche Prüfbefehle:

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

Grafikwerkzeuge#

Die Installer liefern ImageMagick (convert, magick) und rsvg-convert auf dem Host mit, sodass Projekte, die Grafiken brauchen, keine zusätzlichen Abhängigkeiten haben.

Erzeugen Sie bevorzugt SVG – Browser stellen es perfekt dar, und es ist Text, den ein Agent direkt schreiben kann. Konvertieren Sie nur, wenn wirklich eine Rastergrafik nötig ist:

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

Das sind Werkzeuge auf dem Host – führen Sie sie direkt aus, nicht über zeltro exec.

Einen Fehler in dieser Übersetzung gefunden? Sagen Sie es uns auf GitHub.