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 createfragt nur in einem Terminal nach. Mit--one-off,--json-outputoder einem stdin, das kein Terminal ist, gilt wieder der harte Fehler.zeltro configurefragt 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-dirsetzen Sie das Verzeichnis ohne Rückfrage.zeltro ai-setohne Optionen öffnet in einem Terminal ein Menü. Mit irgendeiner Option oder ohne Terminal nicht.zeltro uninstallfragt, ob die Docker-Images gelöscht werden sollen, es sei denn, Sie übergeben--delete-imagesoder--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.