Dies ist die kompakte Referenz zu [Scripting und Automatisierung](/docs/scripting).
Sie benennt die öffentliche Oberfläche, die ein menschliches Skript
oder ein LLM exakt zitieren kann.

## CLI-Verben

Das `paneflow` Binary fängt diese Verben ab und beendet sich vor dem
GUI-Start. Unbekannte Verben beenden mit Usage-Code `2`, statt die App
stillschweigend zu starten.

| Verb | Primäre Methode oder Engine | Schreibt in Panes? | Zweck |
| --- | --- | --- | --- |
| `ls [--human]` | `surface.list` | Nein | Listet Panes im aktiven Workspace |
| `read <target>` | `surface.read` | Nein | Liest Pane-Scrollback |
| `search <target> <pattern>` | `surface.search` | Nein | Durchsucht Pane-Scrollback |
| `ps [--json]` | `fleet.list` | Nein | Listet erkannte Agenten über Workspaces hinweg |
| `status <target> [--json]` | `surface.status` | Nein | Liest Agent-Status eines Pane |
| `new` | `workspace.create` | Nein | Erstellt einen Workspace |
| `select <index>` | `workspace.select` | Nein | Wählt einen Workspace aus |
| `split <h\|v>` | `surface.split` | Nein | Teilt ein Pane |
| `focus <target>` | `surface.focus` | Nein | Fokussiert ein Pane und seinen Workspace |
| `send <target> <text>` | `surface.send_text` | Gated | Bereitet Text vor oder submitted ihn |
| `key <target> <keystroke>` | `surface.send_keystroke` | Gated | Sendet einen nicht submit-fähigen Tastendruck |
| `wait --match <sel>` | `surface.read`, `events.subscribe` | Nein | Blockiert bis Pattern, Idle oder beides |
| `watch [--surface <sel>] [--type <event>]` | `events.subscribe` | Nein | Streamt Lifecycle- und Surface-Events |
| `up <file>` | Workspace-Spec-Engine | Nur Vorbefüllung | Erstellt einen deklarativen Workspace |
| `flow run <file>` | Flow-Engine | Gated für submit-fähige Schritte | Führt einen lokalen Multi-Agent-DAG aus |

Akzeptierte CLI-Aliasse: `list_panes` mappt auf `ls`, `read_pane` auf
`read` und `search_pane` auf `search`.

## Selektoren

| Selektor | Beispiel | Hinweise |
| --- | --- | --- |
| Numerische id | `paneflow read 42` | Matcht `surface_id` exakt |
| Name | `paneflow status backend` | Bester Selektor für langlebige Skripte |
| `cmdline:<substr>` | `paneflow read cmdline:vite` | Vollständiges foreground argv unter Linux, ausführbarer Name unter macOS und Windows |
| `cwd:<path>` | `paneflow read cwd:/home/me/api` | Matcht das Arbeitsverzeichnis des Pane |

Ein Selektor ohne Treffer oder mit mehreren Treffern beendet mit Code
`3`, außer bei Commands, die mehrere Matches ausdrücklich akzeptieren,
etwa `send --broadcast`, `wait --any` und `wait --all`.

## Exit-Codes

| Code | Bedeutung |
| --- | --- |
| `0` | Erfolg |
| `1` | Runtime-Fehler: Instanz unerreichbar, Pane geschlossen, Gate verweigert oder Handler-Fehler |
| `2` | CLI-Usage-Fehler |
| `3` | Ziel nicht gefunden oder mehrdeutig |
| `4` | `wait` Timeout oder Flow-ready Timeout |

## Write-Gates

Lesen ist standardmäßig erlaubt. Schreiboperationen sind nach
Capability getrennt:

| Operation | Gate |
| --- | --- |
| `send` ohne `--submit` | `PANEFLOW_IPC_SCRIPTING=1` oder `ai_unrestricted` |
| `send --submit` | `PANEFLOW_IPC_SCRIPTING=1` oder `ai_unrestricted` |
| `key` | `PANEFLOW_IPC_SCRIPTING=1` |
| Flow-Schritt mit `submit = true` | Scripting-Capability aus `system.capabilities` |

`send` fügt keinen carriage return an, außer `--submit` ist gesetzt.
`key` verweigert submit-fähige Tasten wie `enter`, `ctrl-m` und
`ctrl-j`. Ein einzelnes `surface.send_text` Payload ist auf 64 KiB
begrenzt.

Relevante Config-Keys:

| Key | Standard | Bedeutung |
| --- | --- | --- |
| `ai_unrestricted` | `false` | Erlaubt vertrauenswürdiger KI-Automatisierung, Text ohne Env-Gate zu submitten |
| `ai_injection_fence` | `true` | Verpackt `surface.read` Text in eine nicht vertrauenswürdige Terminal-Hülle |
| `submit_paste_delay_ms` | `70` | Basisverzögerung zwischen bracketed paste und submit carriage return |
| `terminal.env` | none | Umgebungsvariablen, die in neue Terminals injiziert werden |

## Read-Felder

`paneflow read <target> --json` und rohes `surface.read` geben zurück:

| Feld | Bedeutung |
| --- | --- |
| `text` | Scrollback-Text, standardmäßig fenced |
| `lines` | Anzahl zurückgegebener Zeilen |
| `total_lines` | Gesamtzahl vorgehaltener Zeilen |
| `eof` | Ob der Read die älteste vorgehaltene Zeile erreicht hat |
| `output_generation` | Monotoner Zähler, der durch Pane-Ausgabe fortschreitet |

Defaults und Limits: `lines` ist standardmäßig 200 und wird auf
1-4000 begrenzt. `offset` startet vom Ende des Buffers. Ein
out-of-range Offset ist ein invalid-params Fehler.

Der JSON-RPC-Parameter `fenced` nutzt standardmäßig
`ai_injection_fence`. Das CLI-Flag `--raw` setzt `fenced: false`.

## Agent-State-Felder

`paneflow ps --json` gibt `{"agents":[...]}` zurück. `paneflow status
<target> --json` gibt ein Statusobjekt zurück.

| Feld | Bedeutung |
| --- | --- |
| `pid` | Agent-Prozess-id, falls bekannt |
| `tool` | Agent-Familie wie `claude`, `codex`, `opencode` oder `gemini` |
| `state` | `thinking`, `waiting_for_input`, `finished`, `errored`, `stalled`, `idle` oder `unknown_running` |
| `hooked` | Ob Lifecycle-Hook-Events verbunden sind |
| `reason` | Erkennungsgrund, einschließlich `no_hook` |
| `surface_id` | Pane-id |
| `surface_name` | Pane-Name |
| `workspace` | Workspace-Index |
| `active_tool_name` | Tool, das gerade im Agenten läuft |
| `message` | Wartender Prompt oder Permission-Text |
| `last_result` | Zusammenfassung des letzten Turns, wenn verfügbar |
| `waiting_ms` | Zeit im Warten auf Eingabe |
| `idle_ms` | Zeit seit beobachteter Aktivität |
| `output_generation` | Pane-Ausgabezähler bei `status` |

Eine leere Flotte ist `{"agents":[]}` mit Exit-Code `0`. Ein Pane ohne
getrackten Agenten gibt idle state zurück, keinen Fehler.

## Workspace-Spec

`paneflow up <file>` liest eine TOML Workspace-Spec.

| Top-level Feld | Typ | Standard | Hinweise |
| --- | --- | --- | --- |
| `name` | string | `"Workspace"` | Workspace-Titel |
| `layout` | string | `"even_h"` | `even_h`, `even_v`, `main_vertical` oder `tiled` |
| `port_base` | integer | `3000` | Basis für `${port_offset}` Allocation |
| `[[panes]]` | array | erforderlich | Ein Eintrag pro Pane |

| Pane-Feld | Typ | Standard | Hinweise |
| --- | --- | --- | --- |
| `cwd` | string | none | Muss nach Expansion und Canonicalization existieren |
| `agent` | string | none | Agent-Launcher-Name, gegenseitig exklusiv mit `command` |
| `command` | string | none | Roher Command, gegenseitig exklusiv mit `agent` |
| `prompt` | string | none | Wird in ein Agent-Input vorbefüllt, niemals durch `up` submitted |
| `focus` | bool | `false` | Gibt diesem Pane initialen Fokus |
| `env` | table | none | Wird über `terminal.env` gemergt, unterstützt `${port_offset}` |
| `name` | string | none | Stabiler Selektorname |
| `worktree` | string | none | Branch-Name für einen verwalteten Worktree unter `<repo>.worktrees/` |
| `copy_env` | bool | `true` | Kopiert gitignored `.env*` Dateien in den Worktree |
| `setup` | string | none | Command, der vor dem Start läuft |
| `setup_timeout_secs` | integer | `300` | Setup-Timeout |
| `worktree_teardown` | string | `"auto"` | `auto` entfernt saubere Worktrees beim Schließen, `keep` lässt sie liegen |

`${port_offset}` wird nur in `env` Werten ersetzt. Unbekannte Keys sind
Fehler. Workspace-Erstellung validiert Pfade, bevor Panes erstellt
werden.

## Flow-Spec

`paneflow flow run <file>` liest eine TOML Flow-Spec und führt sie
gegen die aktuelle Paneflow-Instanz aus.

| Feld | Typ | Hinweise |
| --- | --- | --- |
| `id` | string | Erforderliche, eindeutige Step-id |
| `needs` | array | Dependencies; bei `foreach` wartet es auf alle Instanzen |
| `foreach` | array | Fan-out, eine Instanz pro Item |
| `pane` | inline table | Spawned ein Pane mit Workspace-Pane-Feldern |
| `send` | inline table | `{ target, text, submit? }`, erfordert eine Dependency |
| `ready` | table | `{ pattern, timeout_secs? }`, Regex-Barriere |
| `capture` | table | `{ var, lines }`, captured 1-500 Zeilen nach `ready` |
| `submit` | bool | Submitted den Prompt eines gespawnten Pane, erfordert Scripting-Zugriff |

Variablen:

| Variable | Scope |
| --- | --- |
| `${item}` | `foreach` Steps: `cwd`, `name`, `worktree`, `env`, `send.target`, `ready.pattern`, Prompts und Texte |
| `${var}` | Captured values in `send.text` und submit-fähigem `pane.prompt` |
| `${var.<item>}` | Captures aus einer `foreach` Gruppe |

Der Runner validiert unbekannte Keys, fehlende Dependencies,
Dependency-Zyklen, ungültige Regexes, undefinierte Captures,
Pane-Budget und fehlende Timeouts vor der Ausführung. `Ctrl-C` stoppt
die Orchestrierungsschleife; erzeugte Panes bleiben in Paneflow.

## JSON-RPC-Verbindung

| Eigenschaft | Wert |
| --- | --- |
| Linux endpoint | `$XDG_RUNTIME_DIR/paneflow/paneflow.sock` |
| macOS endpoint | User runtime dir, gleicher Paneflow-Socket-Name |
| Windows endpoint | `\\.\pipe\paneflow` |
| Framing | Newline-delimited JSON-RPC 2.0 |
| Request-Modell | Eine Anfrage pro Verbindung, außer `events.subscribe` |
| Lokales Vertrauen | Nur gleicher Benutzer; kein Network Listener, kein Token, kein TLS |
| Backpressure | Connection Cap und begrenzte Event-Queues geben strukturierte Fehler oder `dropped` Frames zurück |

Capabilities zur Laufzeit prüfen:

```bash
printf '%s\
' '{"jsonrpc":"2.0","method":"system.capabilities","params":{},"id":1}' \
  | nc -U "$PANEFLOW_SOCKET_PATH"
```

## JSON-RPC-Methoden

| Methode | Params | Rückgabe oder Hinweise |
| --- | --- | --- |
| `system.ping` | - | Liveness-Check |
| `system.capabilities` | - | `{scripting, methods[]}` |
| `system.identify` | - | `{name, version, protocol}` |
| `workspace.list` | - | Workspaces mit Indexes und Titeln |
| `workspace.current` | - | Aktiver Workspace |
| `workspace.create` | `name?`, `cwd?`, `layout?` | Erstellt einen Workspace |
| `workspace.select` | `index` | Wechselt Workspace |
| `workspace.close` | `index?` | Schließt einen Workspace |
| `workspace.up` | `name`, `layout`, `panes[]` | Deklarativer Spawn für `up` und Flow-Roots |
| `workspace.restore_layout` | `layout` | Wendet einen Layout-Baum an |
| `surface.list` | - | `{surfaces:[{surface_id,name,title,cwd,cmd,workspace}]}` |
| `surface.read` | `surface_id`, `lines?`, `offset?`, `fenced?` | Scrollback und `output_generation` |
| `surface.search` | `surface_id`, `pattern`, `max_matches?` | Case-insensitive substring matches |
| `surface.rename` | `surface_id`, `name` | Benennt ein Pane um oder leert den Namen |
| `surface.focus` | `surface_id` | Fokussiert Pane und Workspace |
| `surface.status` | `surface_id` | Agent-Status für ein Pane |
| `surface.send_text` | `surface_id`, `text`, `submit?`, `paste?` | Gated PTY-Textschreibzugriff |
| `surface.send_keystroke` | `surface_id`, `keystroke` | Env-gated, nicht submit-fähiger Tastendruck |
| `surface.split` | `direction`, `surface_id?`, `cwd?`, `command?`, `prompt?`, `env?`, `name?`, `managed_worktree?` | Teilt ein Pane |
| `fleet.list` | - | Read-only Flotten-Snapshot |
| `events.subscribe` | `surfaces?`, `types?` | Persistenter newline-delimited Event-Stream |
| `ai.session_start` | hook payload | Lifecycle-Telemetrie |
| `ai.prompt_submit` | hook payload | Lifecycle-Telemetrie |
| `ai.tool_use` | hook payload | Lifecycle-Telemetrie |
| `ai.notification` | hook payload | Lifecycle-Telemetrie |
| `ai.stop` | hook payload | Lifecycle-Telemetrie |
| `ai.exit` | hook payload | Lifecycle-Telemetrie |
| `ai.session_end` | hook payload | Lifecycle-Telemetrie |

Strukturierte Fehler nutzen JSON-RPC `error` Envelopes: `-32602`
invalid params, `-32601` gated method, `-32001` permission und
`-32000` backpressure. Einige Legacy-Validierungsfehler kommen noch
als `{"error":"..."}` in `result`; Clients sollten beide Formen als
Fehler behandeln.

## Events

`paneflow watch` und rohes `events.subscribe` emitten
newline-delimited JSON. Der erste Frame bestätigt die Subscription.

| Event-Typ | Bedeutung |
| --- | --- |
| `subscribed` | Subscription bestätigt |
| `ai.session_start` | Agent-Session startet |
| `ai.prompt_submit` | Prompt wird submitted |
| `ai.tool_use` | Agent meldet Tool-Nutzung |
| `ai.notification` | Agent fragt nach Eingabe oder Permission |
| `ai.stop` | Agent-Turn stoppt |
| `ai.exit` | Agent-Prozess beendet sich |
| `ai.session_end` | Agent-Session schließt |
| `surface_changed` | Pane `output_generation` ist fortgeschritten |
| `heartbeat` | Idle Keepalive |
| `dropped` | Subscriber laggte und Events wurden verworfen |

Nach einem `dropped` Frame mit `paneflow ps --json` oder `paneflow
status <target> --json` neu synchronisieren.

## MCP-Bridge

`paneflow-mcp` ist ein read-only stdio MCP server über denselben
Paneflow-Socket.

| Tool | Params | Rückgabe |
| --- | --- | --- |
| `list_panes` | - | Panes mit `surface_id`, `name`, `title`, `cwd`, `cmd`, `workspace` |
| `read_pane` | `target`, `lines?`, `offset?` | Scrollback-Text |
| `search_pane` | `target`, `pattern`, `max_matches?` | Trefferzeilen |

Es gibt kein Tool zum Tippen, Submitten, Fokussieren oder Teilen von
Panes. Zurückgegebene Terminalausgabe wird als nicht vertrauenswürdige
Daten fenced.

## Lifecycle-Hooks

`paneflow-ai-hook` liest Event-JSON von stdin, postet einen JSON-RPC
`ai.*` Frame und beendet mit `0`, damit eine gestoppte Paneflow-Instanz
den Agenten nicht kaputtmacht. Die Hook-Oberfläche treibt Status,
Benachrichtigungen, `ps`, `status` und `watch`.

Persistentes `paneflow hooks setup` ist Claude Code scoped. Codex
nutzt Shim-Hooks pro Launch. Agenten ohne Hook-Oberfläche laufen
weiter, ihr Status kann aber auf Prozesserkennung begrenzt sein.

## Verwandte Seiten

- [Scripting-Guide](/docs/scripting)
- [Conductor](/docs/conductor)
- [Konfigurationsschema](/docs/configuration/schema)