Files
ki-grok/10-headless-mode-scripting-und-ci.md
grok-bot 17a2bc8a45 Ship Codex-parity harness, chapter polish, and rebuilt PDF.
Add reader vorlagen (permissions, MCP, hooks, plugins, team AGENTS),
humanizer skill, and adaptionen for ki-codex; refresh chapters 00–18,
resource-path justfile, and dist PDF with full illustration set.
2026-08-02 21:19:46 +02:00

11 KiB
Raw Permalink Blame History

Kapitel 10

Headless Mode, Scripting und CI

Kern in einem Satz: Headless (grok -p) ist dieselbe Engine ohne TUI: ein Prompt rein, Tools laufen, Text/JSON raus – in CI nur mit Always-approve plus Deny, Allowlist und engem Scope.


10.1 Wann Headless, wann TUI, wann ACP

Einstieg Nutzen
TUI grok Alltag, Review, Lernen (Kapitel 3)
Headless grok -p Scripts, CI, einmalige Jobs, Pipelines
ACP grok agent langlebige Clients, IDEs (Kapitel 11)

Alltagsschmerz: CI hängt, weil der Agent auf Permission-Prompt wartet, den niemand klickt. Gegenmittel: non-interaktiv starten und harte Gates (Deny/Hooks/Sandbox), nicht „yolo ohne Netz“.


10.2 Basisaufruf

grok -p "Your prompt here"
# Aliase/Trigger: --single, --prompt-json, --prompt-file

Prozess: Prompt → Tool-Loop → stdout → Exit. Kein interaktives Scrollback.

grok -p "Explain the top-level layout. Change nothing." --cwd ~/projects/your-app
grok -p "$(cat prompts/review.md)" -m grok-build
grok -p --prompt-file ./prompts/ci-review.txt --output-format json

10.3 Wichtige Flags (Arbeitsset)

In CI brauchst du selten die ganze Flag-Liste – aber Always-approve + Deny + Output-Format + Turn-Limit fast immer. Die Tabelle ist Nachschlagewerk; die Sessions unten bauen die typische Kombi.

Flag Rolle
-p / --single Headless-Prompt
-m / --model Modell
-c / --continue letzte Session im CWD
-r / --resume Session per ID/Titel
--cwd Working Directory
--output-format plain|json|streaming-json|streaming-messages-json Ausgabe
--include-partial-messages Text/Thinking-Deltas (nur mit streaming-messages-json)
--yolo / --always-approve keine Permission-Prompts (--yolo = Alias, oft versteckt in --help)
--permission-mode u. a. bypassPermissions
--allow / --deny Permission-Regeln (wiederholbar)
--rules Session-Regeln
--sandbox <profile> OS-Sandbox (Kapitel 13)
--tools / --disallowed-tools Tool-Allow/Deny-List (nur Headless)
--agents Inline-Subagent-Definitionen (nur Headless)
--max-turns N Turn-Limit (nur Headless)
--effort / --reasoning-effort Reasoning-Level
--no-auto-update keine Update-Checks im Job
--worktree= / -w isolierter Tree (Kapitel 6)

Nur Headless: --tools, --disallowed-tools, --max-turns, --agents in der TUI → Warnung, ignoriert. In CI genau diese Flags nutzen.


10.4 Output-Formate

plain (Default)

Menschlich lesbarer Text – gut für Logs und echo.

json

Ein JSON-Objekt am Ende: u. a. text, stopReason, sessionId, requestId, bei Modell-Erreichen oft usage, num_turns, modelUsage, Kostenfelder.

grok -p "Review changes for bugs" --output-format json --yolo \
  | jq -r '.text'

streaming-json

NDJSON-Eventstrom (native ACP-Session-Updates) – für UIs und Live-Pipelines.

streaming-messages-json

NDJSON im Anthropic-Messages-API-Wire-Format – für Clients, die dieses Streaming-Protokoll erwarten. Mit --include-partial-messages kommen zusätzlich inkrementelle stream_event-Deltas (Text/Thinking); ohne dieses Flag und bei anderen Formaten wird das Flag ignoriert (mit Warnung).

Praxis: CI-Summary → json + jq. Streaming-Dashboards → streaming-json. Messages-API-kompatible Clients → streaming-messages-json.


10.5 Permissions in Automation

Ohne TUI blockiert ask den Job. Deshalb:

grok -p "Run unit tests and summarize failures" \
  --always-approve \
  --deny 'Bash(rm -rf *)' \
  --deny 'Bash(git push *)' \
  --allow 'Bash(npm test *)' \
  --allow 'Bash(npm run lint *)' \
  --disallowed-tools "web_search,web_fetch"
Mechanik Wirkung
--always-approve keine Klick-Prompts
--deny gewinnt immer – auch über YOLO
--allow enge Freigaben
--disallowed-tools Tool komplett weg
--tools nur diese Built-ins (+ MCP-Meta oft weiter da)
Hooks PreToolUse deny (Kapitel 8)
Sandbox Kernel-FS/Netz (Kapitel 13)

Subagents in CI:

# keine Subagents
--disallowed-tools "Agent"
# nur explore sperren
--disallowed-tools "Agent(explore)"

Zwei Namensräume, nicht vermischen: Headless---tools / --disallowed-tools nutzen interne Tool-IDs (Shell oft run_terminal_cmd). Permission-Rules und viele Hook-Matcher nutzen Prefixe bzw. Aliase wie Bash(...) / run_terminal_command (Kapitel 8 und 13). Bei Unklarheit: Guide oder grok inspect.


10.6 Tool-Filter: enge Reviews

# Nur lesen
grok -p "Explain architecture risks" \
  --tools "read_file,grep,list_dir" \
  --output-format json

# Kein Shell, kein Web
grok -p "Static review of src/api" \
  --disallowed-tools "run_terminal_cmd,web_search,web_fetch,search_replace"

Wann Allowlist: untrusted PR, Secret-Repos, „nur begutachten“.
Wann Denylist: normaler Fix-Job, aber ohne Push/Web.


10.7 Sessions in Scripts

# multi-step pipeline über eine Session
# -s erwartet UUID; macOS-uuidgen liefert Uppercase → lowercasen
SID=$(uuidgen | tr '[:upper:]' '[:lower:]')   # oder feste UUID-Policy
grok -p "Step 1: find flaky tests" -s "$SID" --always-approve --output-format json
grok -p "Step 2: propose minimal fix" -r "$SID" --always-approve --output-format json

# Fork statt append
grok -p "Alternative approach" -r "$SID" --fork-session --always-approve

-s erzeugt neue Session mit UUID (Fehler wenn ungültig/belegt) – resumed wird mit -r/-c.


10.8 GitHub Actions – Gerüst

# .github/workflows/grok-review.yml (Skizze)
name: Grok review
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: read
    steps:
      - uses: actions/checkout@v4
      - name: Install Grok
        run: curl -fsSL https://x.ai/cli/install.sh | bash
      - name: Review diff
        env:
          XAI_API_KEY: ${{ secrets.XAI_API_KEY }}
        run: |
          set -euo pipefail
          export PATH="$HOME/.grok/bin:$PATH"
          git fetch origin "${{ github.base_ref }}"
          RANGE="origin/${{ github.base_ref }}...HEAD"
          grok -p "Review the git diff $RANGE for bugs and security issues.
          Read-only. No commits, no push, no network installs.
          Output: severity-ordered findings with file:line." \
            --always-approve \
            --output-format json \
            --deny 'Bash(git push *)' \
            --deny 'Bash(rm -rf *)' \
            --disallowed-tools "web_fetch" \
            --max-turns 30 \
            --no-auto-update \
            | tee /tmp/grok-out.json
          jq -r '.text' /tmp/grok-out.json >> "$GITHUB_STEP_SUMMARY"

Lauffähiges Gegenstück im Repo: beispiele/configs/github-actions-grok-review.yml (inkl. PATH).

Achtung: XAI_API_KEY nur als Secret. Kein Always-approve ohne Deny. Keine Write-Permissions auf den Default-Branch für den Job-Token, wenn du nur reviewen willst.

Auth in CI: API-Key (Kapitel 2), nicht Browser-Login.

Policies auf dem Laptop, Review in CI, Merge durch Menschen.{width=90%}


10.9 Lokale Script-Muster

#!/usr/bin/env bash
set -euo pipefail
cd "$(git rev-parse --show-toplevel)"

grok -p "Summarize uncommitted changes (git status + diff). No edits." \
  --always-approve \
  --deny 'Bash(git commit *)' \
  --deny 'Bash(git push *)' \
  --output-format plain
# Fail the pipeline if model reports blockers (heuristisch)
text=$(grok -p "…" --output-format json --always-approve | jq -r '.text')
if grep -qiE 'critical|must fix|blocker' <<<"$text"; then
  echo "$text"
  exit 1
fi

Heuristiken sind unscharf – für harte Gates lieber strukturierten Prompt („JSON findings array“) und jq auf Felder.


10.10 Praxis-Sessions

Session 1 – Read-only Headless

grok -p "List the three riskiest modules. Change nothing." \
  --tools "read_file,grep,list_dir" \
  --output-format plain

Session 2 – YOLO + Deny

Gates wie in 10.5; hier ein anderes Deny-Paar (Force-Push + Installer-Muster):

grok -p "Run the unit test suite and quote the first failure." \
  --always-approve \
  --deny 'Bash(git push --force *)' \
  --deny 'Bash(curl *)' \
  --max-turns 20

Session 3 – JSON für Downstream

grok -p "Return ONLY a markdown table: file | issue | severity." \
  --output-format json --always-approve \
  | jq -r '.text' > /tmp/findings.md

Session 4 – Multi-Turn Resume

grok -p "Identify one flaky test" -c --always-approve --output-format json
grok -p "Now propose a minimal fix plan only" -c --always-approve

Session 5 – CI dry-run lokal

Workflow-Prompt aus 10.8 gegen einen echten git diff origin/main...HEAD laufen lassen, Exit-Code und Summary prüfen.


10.11 Jetzt selbst machen: Headless-Parcours (25 Minuten)

Jetzt selbst machen

  1. Read-only -p mit --tools Restrict.
  2. Testlauf mit --always-approve und zwei --deny.
  3. --output-format json | jq .sessionId,.num_turns,.text.
  4. --max-turns 3 und beobachten, ob abgeschnitten wird.
  5. Mini-Script in scripts/grok-review.sh committen (ohne Secrets).
  6. Optional: GHA-Workflow als Draft-PR nur auf Fork.

10.12 Häufige Fehler

Symptom Ursache Fix
Job hängt ask ohne TTY --always-approve + Deny
Agent pusht/installt zu weites YOLO Deny, disallowed-tools, sandbox
Leere Ausgabe falsches format/jq plain testen, raw JSON ansehen
Zu teuer/lang kein Turn-Limit --max-turns, enger Prompt
Auth fail kein Key in CI XAI_API_KEY Secret
Tools-Flag greift nicht in TUI benutzt Headless -p

10.13 Checkliste CI

  • API-Key als Secret
  • Always-approve und Deny-Minimum
  • Scope im Prompt (read-only vs. fix)
  • Output-Format fürs Parsing
  • max-turns / Timeouts im Runner
  • Least-privilege GitHub-Permissions
  • Keine Secrets im Prompt-Log

Was du jetzt kannst

  • Headless-Aufrufe mit Output-Formaten und Session-Flags fahren
  • YOLO mit Allow/Deny/Tool-Filter und Turn-Limits absichern
  • Ein CI-Gerüst und lokale Scripts ohne hängende Prompts bauen

Nächste Schritte

→ Kapitel 11 – ACP, IDE-Integration und Bots: langlebige Agent-Server für Editoren und eigene Clients.