pi-remote-control/docs/reference/SPEC-ios-app.md

625 lines
23 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# pi-remote — iOS Native App Spec (v3)
> **Status:** v3 nach ExtensionAPI-Audit.
> Audit-Ergebnis: [`EXTENSION-API-AUDIT.md`](./EXTENSION-API-AUDIT.md).
> Review-Verlauf v1: [`SPEC-ios-app-review-v1.md`](./SPEC-ios-app-review-v1.md).
>
> **Changelog v2 → v3:**
> - Audit hat S-07, S-08 und Tree-Read als out-of-the-box machbar bestätigt → von PENDING auf firm SHOULD.
> - **Tree-Navigation komplett aus iOS entfernt.** Gruppe T gestrichen. Begründung: Slash-Command-Dispatch ist in der ExtensionAPI blockiert, Workarounds (Hack oder Re-Implement) sind nicht den Aufwand wert. Tree-Navigation bleibt nativ in pi.
> - Spike-0a abgeschlossen, ist nun referenziertes Audit-Dokument.
> - **Q-A** geschlossen: pi-CLI `-p`/`--print` Mode funktioniert mit Haiku 4.5 in ~2s. S-09a hat jetzt konkrete CLI-Flags.
> - **Q-C** geschlossen: APNs-Setup-Details unter iOS-C-02. Sidecar routet pro Device-Token nach Sandbox (Xcode-Debug) vs. Production (TestFlight/Release).
---
## 1. Vision
Eine iOS-App, die laufende `pi`-Sessions **byte-genau spiegelt**, wie sie im
SSH-Terminal aussehen — und durch native iOS-Mittel (Touch, Sprache,
Notifications, System-Integration) die Bedienung dieser Terminal-Umgebung
unterwegs angenehm macht.
**Kein Hybrid-Rendering.** Was im Terminal ANSI ist, bleibt in der App ANSI.
Die App fügt eine *Augmentation-Schicht* hinzu, kein paralleles UI.
**Kernszenarien:**
1. **Long-Visit-Sync** — Eine Session läuft tagelang. Nutzer "besucht" sie
unregelmäßig vom Mac (SSH) und iPhone (App). Beide zeigen jederzeit
denselben State. Reattach ist instant.
2. **Session-Lifecycle vom Phone** — Sessions vom iPhone aus spawnen,
benennen, switchen und beenden — so easy wie native iOS-Tabs.
---
## 2. Principles
- **P-1** — Der Terminal-Stream ist die einzige Wahrheit für Inhalt.
Strukturierte Events dienen ausschließlich Statusanzeigen,
Notifications und Meta-State (z.B. Tree-Navigation). Niemals
Re-Rendering von Stream-Inhalt.
- **P-2** — SSH-Erfahrung bleibt unverändert. Der Mac-Workflow ändert
sich durch dieses Projekt nicht spürbar.
- **P-3** — Reconnect ist die wichtigste Operation. Sichtbares Ergebnis
< 1s nach App-Wake.
- **P-4** Touch-UX wird *zur Terminal-Bedienung* gebaut, nicht
*anstelle* von Terminal-Bedienung.
- **P-5** Solo-Use. Multi-User, Sharing, Org-Features sind out of scope.
- **P-6** Server-State wird in tmux gehalten, wo möglich. Kein
paralleler State-Store im Sidecar.
---
## 3. Architecture
```
┌──────────────────────────────────────────────────────────┐
│ Server │
│ │
│ pi (Ink TUI) ◄─► tmux session ◄─► SSH-Client (Mac) │
│ │ │
│ │ pipe-pane (raw bytes) │
│ │ send-keys │
│ ▼ │
│ pi-remote sidecar │
│ │ │
│ │ WebSocket (wss://) │
│ │ ├─ raw ANSI stream (binary) │
│ │ ├─ control (send-keys, JSON) │
│ │ └─ side-channel (state, JSON) │
└─────────────────────────┼────────────────────────────────┘
┌──────────────────────────┐
│ iOS App │
│ ┌────────────────────┐ │
│ │ SwiftTerm renderer │ │
│ └────────────────────┘ │
│ ┌────────────────────┐ │
│ │ Augmentation layer │ │
│ └────────────────────┘ │
└──────────────────────────┘
```
**Komponenten:**
- **tmux** Session-Persistenz, Multi-Client-Attach, Pane-Pipe, Send-Keys.
Sessions als stable IDs, Metadaten via tmux User-Options
(`@description`, `@project`, etc.).
- **Sidecar** (`pi-remote-control` erweitert) Node-Prozess. Spawn /
Reattach tmux, exponiert WebSocket-API, hält Ringbuffer für Replay,
leitet ExtensionAPI-Metadaten als Side-Channel weiter.
- **iOS-App** SwiftUI-Shell, SwiftTerm als Renderer-View, eigener
Augmentation-Layer.
**Datenfluss Stream:** `pi` tmux pipe-pane sidecar ringbuffer WS
(binär, `permessage-deflate`) iOS SwiftTerm.
**Datenfluss Input:** iOS WS sidecar `tmux send-keys` tmux pane
pi stdin. Mac-SSH-Client sieht denselben Input.
**Konventionen:**
- Terminal-Size: tmux pane fixiert auf **120 × 40**. Client rendert mit
Pinch-Zoom auf die physische Display-Größe.
- WebSocket-Frames: binär = ANSI-Stream-Chunk; text = JSON-Control
(input, side-channel, snapshot-request).
- Alternate-Screen-Buffer wird vom Client erkannt und nicht in den
Scrollback-Cache aufgenommen.
- Terminal-Title-Sequences werden ignoriert.
- Mouse-Tracking-Sequenzen werden weitergeleitet, vom Client aber nicht
visualisiert (Touch-UX).
---
## 4. Server Features (Sidecar)
### S-01 — tmux launcher / attach
**MUST.** CLI `pi-remote attach [<session>]`. Existiert die Session,
reattach; sonst neu spawnen (`tmux new-session -d -s <name> 'pi'`) und
attach. Default-Session: `pi-main`. Per Projekt benennbar.
*Dependencies:*
### S-02 — Raw ANSI WebSocket Stream
**MUST.** Endpoint `/stream/<session>`.
- Binäre Frames für ANSI-Bytes aus `tmux pipe-pane`.
- WebSocket-Extension `permessage-deflate` aktiv (35× Compression
typisch für ANSI).
- Eine Verbindung = ein Pane.
- Alternate-Screen-Sequenzen werden durchgereicht; Sidecar markiert sie
nicht separat (Client tracked).
*Dependencies:* S-01
### S-03 — Send-Keys-Endpoint
**MUST.** WS-Text-Frames als JSON: `{type:"keys", data:"..."}` für
literal-Text, oder `{type:"key", name:"escape"|"tab"|"up"|...}` für
Spezialtasten. Sidecar mapped auf `tmux send-keys` oder
`tmux send-keys -l`. Bracketed-Paste-Frames
(`{type:"paste", data:"..."}`) wrappen automatisch mit `\e[200~ ... \e[201~`.
*Dependencies:* S-01
### S-04 — Sequence-Cursor & Delta-Replay
**MUST.** Sidecar nummeriert Chunks ausgehend (monotone u64). Client
sendet bei Reconnect `{type:"resume", lastSeq:<n>}`. Server liefert ab
`lastSeq+1` weiter. Falls Lücke → Snapshot (S-05).
*Dependencies:* S-02
### S-05 — Snapshot-Endpoint
**MUST.** Wenn `lastSeq` außerhalb des Ringbuffers liegt:
`tmux capture-pane -p -e -S -10000` als Snapshot + neuen Start-Seq.
Snapshot wird komprimiert über WS geliefert.
*Dependencies:* S-01, S-04
### S-06 — Per-Session Disk Buffer
**SHOULD.** Sidecar persistiert ANSI-Stream pro Session in eine
einzelne Datei `/var/lib/pi-remote/buffer/<session>.log`.
- **Pro Session**: hartes Cap = **100MB** (configurable). Bei
Überlauf wird der Schreibvorgang gestoppt; existierender Inhalt
bleibt unangetastet. Neue Bytes ab dem Punkt fehlen im Buffer —
Snapshot via S-05 funktioniert weiterhin direkt aus tmux.
- **Global**: Hartes Total-Cap = **1GB** über alle Sessions; wenn
überschritten, schaltet der Sidecar Buffer-Schreiben global ab und
meldet `degraded` über S-13.
- **Idle-Cleanup**: Sessions ohne Output UND ohne Client seit > 30
Tagen → Buffer-Datei wird gelöscht (Session selbst nur falls
ebenfalls beendet).
- **Disk-Watchdog**: Bei freiem Platz < 1GB Buffer-Schreiben global
aus, Health-Status `degraded`.
- Konfigurierbar via `~/.config/pi-remote/config.toml`.
*Dependencies:* S-02
### S-07 — State Side-Channel
**SHOULD.** Sidecar abonniert pi-ExtensionAPI-Events (`agent_start`,
`agent_end`, `tool_execution_start`, `tool_execution_end`,
`session_tree`, `session_compact`) und publiziert als JSON-Control-Frames:
```json
{"type":"state","value":"thinking"|"tool"|"idle"|"awaiting-input",
"tool":"Edit"|"Read"|...,"ts":1234567890}
```
`awaiting-input` wird abgeleitet aus `agent_end` + `ctx.isIdle()`,
da kein explizites Event existiert (siehe Audit §3.1).
*Dependencies:* S-01
### S-08 — Slash-Command-Registry
**SHOULD.** Endpoint `/sessions/<id>/commands` liefert JSON-Liste der
verfügbaren Slash-Commands inkl. Beschreibung und Argument-Schema via
`pi.getCommands()` (laut Audit out-of-the-box verfügbar). Dynamisch
Extensions die Commands hinzufügen erscheinen automatisch.
*Dependencies:* S-01
### S-09 — Multi-Session-Management
**MUST.** Sidecar verwaltet mehrere tmux-Sessions parallel, alle robust
gegen Sidecar-Restart (tmux überlebt, Sidecar reattached beim Boot).
**Endpoints:**
- `GET /sessions` Liste mit Metadaten (Name, Description, Created,
letzter Output, Connected-Clients, Pi-State).
- `POST /sessions` neue Session spawnen, Body optional `{name, project}`.
- `PATCH /sessions/<id>` umbenennen / Description ändern.
- `DELETE /sessions/<id>` Session beenden (tmux kill-session + Buffer
optional löschen).
**State:** Ausschließlich in tmux gehalten. Sessions haben Namen
(stable ID), Metadaten via tmux User-Options:
- `@description` Auto- oder manuell vergeben (siehe S-09a)
- `@project` optional, vom User gesetzt
- `@created` Timestamp
Kein eigener JSON-State-Store im Sidecar.
*Dependencies:* S-01
### S-09a — Auto-Naming via pi
**NICE.** Nach ~3 User-Messages in einer namenlosen Session triggert
der Sidecar einen One-Shot-Call via pi-CLI:
```bash
pi -p --provider anthropic --model claude-haiku-4-5 \
--no-tools --no-context-files --no-extensions --no-session \
--thinking off \
"Give a 2-4 word title for: '<transcript>'. Reply with title only."
```
~2s Latenz, pi's eigene Anthropic-Auth wird verwendet keine separaten
Credentials nötig. Ergebnis landet als `@description` in tmux.
Manuelles Umbenennen aus der App jederzeit möglich und überschreibt.
*Dependencies:* S-09
### S-10 — Pairing & Bearer-Token-Auth
**MUST.** CLI `pi-remote pair` generiert ein kurzlebiges (5min)
Pairing-Token und druckt einen QR-Code im Terminal (Unicode block
chars, via `qrcode-terminal`).
QR-Inhalt: `pi-remote://<host>:<port>?pair=<token>&fp=<sha256-cert-fp>`
iOS-App scannt tauscht Pairing-Token gegen permanenten Bearer-Token,
pinnt den TLS-Fingerprint. Token im Keychain (iOS-G-01).
CLI:
- `pi-remote auth list` alle Tokens
- `pi-remote auth revoke <name>` Token widerrufen
- `pi-remote auth name <name>` Token umbenennen (z.B. "jay's iPhone")
*Dependencies:* S-11
### S-11 — TLS via Self-Signed + Trust-on-First-Use
**MUST.** Sidecar generiert beim ersten Start ein selbstsigniertes
Cert (ED25519 oder RSA-2048), 10 Jahre gültig, persistent auf Disk.
SHA-256-Fingerprint wird in den QR aus S-10 mit aufgenommen. Client
pinnt den Fingerprint beim Pairing. Bei Cert-Rotation (z.B. neuer
Host) muss re-paired werden.
Kein Let's Encrypt, keine CA, kein Reverse-Proxy nötig.
*Dependencies:*
### S-12 — Health & Metrics
**NICE.** `/health` Endpoint mit Session-Count, Buffer-Size,
Connected-Clients, Disk-Watchdog-Status. Für Monitoring und
Selbst-Debugging.
*Dependencies:*
> S-13 (Tree-State Side-Channel) wurde in v3 gestrichen.
> Begründung: siehe Out-of-Scope und Changelog.
---
## 5. iOS Client Features
### Gruppe A — Rendering & Stream
#### iOS-A-01 — SwiftTerm-Renderer
**MUST.** Vollwertiger ANSI-Terminal-View. Renderer-Setup mit
Truecolor, 120×40 fixed grid, configurable Font + Theme.
*Dependencies:* S-02
#### iOS-A-02 — Sequence-Cursor & Reconnect
**MUST.** Client speichert lokal pro Session den letzten `seq`. Bei
WS-Reconnect: schickt `{type:"resume", lastSeq}`, verarbeitet Delta
oder Snapshot.
*Dependencies:* S-04, S-05
#### iOS-A-03 — Stale-Frame-Display
**SHOULD.** Während Sync nach App-Wake: letzten Frame einfrieren,
"syncing…" als subtile Overlay-Pill anzeigen. Kein leerer Screen.
*Dependencies:* iOS-A-02
#### iOS-A-04 — Local Scrollback-Cache
**SHOULD.** App puffert empfangene Bytes lokal pro Session (rolling,
default 5MB) für Offline-Scrolling und Suche. Alternate-Screen-Inhalt
wird ausgenommen.
*Dependencies:* iOS-A-01
#### iOS-A-05 — Themes & Fonts
**SHOULD.** Eingebaute Themes:
- Default-Dark, Default-Light
- Solarized Light, Solarized Dark
- Monokai, Dracula
- Nord, Gruvbox Dark, Gruvbox Light
- Tomorrow Night
- GitHub Light, GitHub Dark
- System (folgt iOS Light/Dark Mode)
Eingebaute Fonts (gebundlet):
- JetBrains Mono (Default)
- Hack
- SF Mono
- Menlo
- Fira Code
- Cascadia Code
- IBM Plex Mono
- Monaspace Neon
Custom Themes editierbar, iCloud-Sync nur für Custom.
*Dependencies:* iOS-A-01
### Gruppe B — Input & Modifier
#### iOS-B-01 — Software-Keyboard, Direct-Passthrough
**MUST.** Standard-iOS-Keyboard. **Mode (b) direct-passthrough**:
jeder Tastendruck geht sofort als `send-keys`. Enter sendet `\r` an
pi pi behandelt selbst. Kein App-eigenes Compose-Feld.
Shift+Enter (newline) via dediziertem `⇧↵`-Button in der Modifier-Bar
(siehe iOS-B-02).
*Dependencies:* S-03
#### iOS-B-02 — Modifier-Bar
**MUST.** Accessory-Bar über der Tastatur:
```
[Ctrl] [Esc] [Tab] [←] [↑] [↓] [→] [⇧↵] [🎙] [📋]
```
- **Ctrl** ganz links Sticky-Toggle: ein Tap leuchtet nächste
Taste wird als Ctrl+X gesendet. Beliebige Ctrl-Combos möglich
(Ctrl-C, Ctrl-D, Ctrl-L, Ctrl-U, ...).
- **Esc** eigener Button, dauerhaft sichtbar.
- **Tab** Autocomplete in pi.
- **Pfeiltasten** (Mitte) History scrollen, in Menüs navigieren,
Input-Cursor bewegen.
- **`⇧↵`** Shift+Enter, ein Tap = `\n` (newline in pi multi-line).
- **`🎙`** Voice-Input (iOS-C-06).
- **`📋`** Paste-Button ganz rechts (öffnet Paste-Sheet, iOS-B-08).
Bei knappem Platz (iPhone-Portrait) ist die Bar horizontal scrollbar.
*Dependencies:* iOS-B-01
#### iOS-B-03 — Long-Press-Repeat
**SHOULD.** Long-Press auf Pfeiltasten oder Backspace repeat mit
Beschleunigung.
*Dependencies:* iOS-B-02
#### iOS-B-04 — Selection & Copy
**MUST.** Doppel-Tap Wort. Tripel-Tap Zeile. Long-Press + Drag
Range. Native iOS-Copy-Menu.
*Dependencies:* iOS-A-01
#### iOS-B-05 — Pinch-Zoom Font
**SHOULD.** Pinch in der Terminal-View Font-Size live.
*Dependencies:* iOS-A-01
#### iOS-B-06 — Hardware-Keyboard-Support
**SHOULD.** Externe iPad-Keyboards:
- CapsEsc-Remap (optional)
- Modifier-Pass-Through (Cmd, Option, Ctrl)
- App-Shortcuts:
- Cmd-K Clear
- Cmd-T New session
- Cmd-1..9 Session switch
- Cmd-F Scrollback-Search
- Cmd-, Settings
- Cmd-Shift-P Slash-Command-Palette
*Dependencies:* iOS-B-01
#### iOS-B-07 — Reachability / One-Hand-Mode
**NICE.** iPhone-Querformat: Modifier-Bar gespiegelt für einhändige
Bedienung.
*Dependencies:* iOS-B-02
#### iOS-B-08 — Smart Paste (Confirm)
**SHOULD.** `📋`-Button in der Modifier-Bar zeigt Clipboard-Vorschau-
Chip ("📋 12 lines, 847 chars"). Tap Sheet mit vollem Preview,
Insert / Cancel. Verhindert versehentliches Paste großer Blobs.
*Dependencies:* iOS-B-01
#### iOS-B-09 — Bracketed-Paste-Compliance
**SHOULD.** Client trackt im Stream `\e[?2004h` / `\e[?2004l`. Wenn
aktiv, wird bei Paste die `{type:"paste"}` Variante an S-03 geschickt,
sodass pi den ganzen Block als Paste erkennt.
*Dependencies:* S-03, iOS-B-08
### Gruppe C — Pi-aware Augmentation
#### iOS-C-01 — Status-Bar
**MUST.** Top-Bar zeigt: Connection-Status, Session-Name, Pi-State
(`● thinking` / `⏵ tool: Edit` / `▶ awaiting` / `⏸ idle`) basierend auf
S-07.
*Dependencies:* S-07
#### iOS-C-02 — Push-Notification bei Awaiting-Input
**MUST.** Wenn App im Background und Pi wechselt zu `awaiting-input`:
Push-Notification "Pi ist fertig · <session-name>". Tap → App öffnet in
der richtigen Session.
**APNs-Setup:**
- Apple Developer Portal: App-ID mit Push-Capability +
APNs Auth-Key (`.p8`, einmaliger Download). Notiere Team-ID und Key-ID.
- Dieselbe `.p8`-Datei funktioniert für Sandbox und Production.
- Sidecar-Config (neue Sektion in `~/.config/pi-remote/config.toml`):
```toml
[apns]
team_id = "..."
key_id = "..."
key_path = "/etc/pi-remote/AuthKey_<key-id>.p8"
bundle_id = "de.vpsj.pi-remote"
```
- **Environment-Routing pro Device:**
Xcode-Debug-Builds (lokales Testen via WiFi-Pair) registrieren ihre
Device-Tokens bei der Sandbox; TestFlight- und Release-Builds gehen
gegen Production. Beide gleichzeitig betreibbar, da derselbe Key
funktioniert. Sidecar speichert pro Device-Token ein `environment:
"sandbox" | "production"` Feld und routet beim Push entsprechend zu
`api.sandbox.push.apple.com` bzw. `api.push.apple.com`.
- **Pairing-Erweiterung (S-10):** iOS-App schickt beim Pairing
zusätzlich `{deviceToken, environment, deviceName}`. `environment`
bestimmt sich zur Compile-Time aus der Build-Config.
- **HTTP-Headers**:
- `apns-topic: <bundle-id>`
- `apns-push-type: alert` (required ab iOS 13)
- `apns-priority: 10`
- `apns-collapse-id: session-<id>` — verhindert Notification-Spam, neuere
State-Wechsel überschreiben ältere im Lock-Screen.
- **JWT:** ES256-signed mit `.p8`-Key, 1h gültig, im Sidecar für ~55min
cachen.
- **Auto-Cleanup:** APNs-Response `410 Gone` → Device-Token tot, Sidecar
löscht Mapping. App registriert beim nächsten Launch neu.
- **Library:** `@parse/node-apn` oder `node-apn-http2`.
*Dependencies:* S-07, S-10 (Pairing trägt Device-Token), APNs Auth-Key
#### iOS-C-03 — Haptic Feedback bei State-Wechseln
**NICE.** Subtile Vibration bei `thinking → idle` oder
`thinking → awaiting-input`.
*Dependencies:* S-07
#### iOS-C-04 — Slash-Command-Palette
**SHOULD.** **Long-Press auf die Modifier-Bar** → öffnet Sheet mit
nativer Liste aller Slash-Commands (aus S-08), Fuzzy-Search. Tap →
injiziert via `send-keys`. Commands mit Argumenten → Formular-View.
*Dependencies:* S-03, S-08
#### iOS-C-05 — Voice-to-Prompt
**NICE.** `🎙`-Button → Speech-Recognition (lokal, iOS native) →
editable Preview → Send.
*Dependencies:* iOS-B-01, Mic-Permission
### Gruppe D — Session & Navigation
#### iOS-D-01 — Session-Switcher (MUST)
**MUST.** Native iOS-Liste der verfügbaren Sessions (via S-09). Spawn /
Rename / Kill direkt aus dem Switcher.
*Dependencies:* S-09
#### iOS-D-01a — Background Pre-Connect
**SHOULD.** App connectet im Hintergrund zu allen bekannten Sessions
parallel, hält pro Session einen kleinen In-Memory-Stream-Buffer +
letzten Frame. Switch = Renderer wechselt instant.
Kosten: ein Socket pro Session, ein paar MB RAM. Akzeptabel solange
< ~10 aktive Sessions.
*Dependencies:* iOS-D-01
#### iOS-D-01b — Optimistic-Switch mit Stale-Frame
**SHOULD.** Swipe zu Session B → sofort gecachten Frame zeigen,
parallel live-Sync. Niemals leerer Screen, nur kurze "sync"-Pille.
*Dependencies:* iOS-D-01, iOS-D-01a
#### iOS-D-01c — Predictive Thumbnails
**SHOULD.** Im Session-Switcher zeigt jede Session eine kleine Live-
Mini-Vorschau (z.B. 40×12 Zeichen Snapshot via `tmux capture-pane`).
Beim Öffnen des Switchers werden die Thumbnails aktualisiert.
*Dependencies:* iOS-D-01
#### iOS-D-02 — Scrollback-Search
**SHOULD.** Such-Sheet sucht im lokalen Scrollback-Cache (iOS-A-04)
mit Highlight + Jump-to-Match. Auch offline nutzbar.
*Dependencies:* iOS-A-04
### Gruppe E — Background & Lifecycle
#### iOS-E-01 — WS-Keepalive
**MUST.** Ping/Pong-Frames im Foreground halten Connection. iOS
suspended WS gerne ohne Notification.
*Dependencies:* S-02
#### iOS-E-02 — Wake-up-Sync
**MUST.** App-Foreground-Event triggert sofort Reconnect + Delta-Pull.
Spinner falls > 200ms. Ziel < 1s sichtbarer Sync (P-3).
*Dependencies:* iOS-A-02
### Gruppe F — Security
#### iOS-F-01 — Token im Keychain
**MUST.** Bearer-Token aus S-10 wird im iOS Keychain gespeichert.
*Dependencies:* S-10
#### iOS-F-02 — Face-ID / Touch-ID Gate
**SHOULD.** Biometrie-Lock vorm Öffnen der App. **Opt-in via Setting,
default off.**
*Dependencies:*
#### iOS-F-03 — TLS-Pinning via QR-Pairing
**MUST.** Beim Pairing (S-10) wird der Cert-Fingerprint gepinnt. Jede
künftige Connection verifiziert dagegen. Re-Pairing bei Cert-Rotation.
*Dependencies:* S-10, S-11
---
## 6. Out of Scope (locked)
- **Rich Chat-Rendering.** Wir parsen den Stream nicht. ANSI bleibt ANSI.
- **Embedded Mini-Terminals / Block-Selection.** Es gibt einen Stream.
- **Multi-User-Sharing.** Solo.
- **Org/Team-Features, Cloud-Hosted-Service.** Selbstgehostet.
- **Inline-Image-Rendering** (iTerm2 protocol etc.). Eventuell später.
- **Eigenes Mosh.** tmux + WebSocket reicht.
- **Cross-platform-Clients (Android / Web).** Nur iOS nativ. Die
bestehende HTML-UI bleibt als separates Artefakt.
- **Silent-Push-Background-Wake.** iOS coalesced unzuverlässig; manueller
Wake-up-Sync (iOS-E-02) reicht.
- **Marker-Detection / Jump-to-Marker.** Pi liefert keine zuverlässigen
Marker.
- **Tap-to-Cursor.** Ohne Marker-Detection nicht robust machbar.
- **Eigener Sidecar-State-Store.** State lebt in tmux (P-6).
- **Disk-Buffer-Rotation.** Ein Cap, drüber hinaus = Daten verloren.
Snapshot funktioniert weiter.
- **Bookmarks / manuelle Marker.** Pi-interne Tools sollen das übernehmen.
- **Snippet-Library** (Prompts mit Variablen). Pi-interne Tools.
- **Tree-View / Tree-Navigation in iOS** (jeglicher Form, read-only
oder interaktiv). Tree wird ausschließlich nativ in pi bedient. Audit
hat gezeigt: Slash-Command-Dispatch ist in der ExtensionAPI nicht sauber
zugänglich; Workarounds sind die Komplexität nicht wert.
---
## 7. ExtensionAPI-Audit (abgeschlossen)
Das Audit wurde durchgeführt; Ergebnis liegt in
[`EXTENSION-API-AUDIT.md`](./EXTENSION-API-AUDIT.md).
**Kernergebnisse:**
- S-07, S-08, sowie Tree-**Read** sind out-of-the-box machbar.
- Tree-**Write** (Slash-Command-Dispatch wie `/fork`, `/checkout`,
`/new`) ist nicht sauber zugänglich Gruppe T gestrichen (siehe
Out-of-Scope).
- Tool-Call-Daten sind vollständig verfügbar (Name, Args, Result).
Kein weiterer Spike vor Phase 1 nötig.
---
## 8. Phasen
> Phase-Aufwände bewusst weggelassen (sind in v1 gestrichen worden).
- **Spike-0 Stream-PoC** `pi-remote-control` um tmux pipe-pane +
WS-Stream erweitern. Verifizieren dass pi sauber in tmux läuft (kein
Crash, Alternate-Screen sauber, kein Latency-Problem).
- **Phase 1 Sidecar production-ready** S-01 bis S-12 (alle), S-09a
optional.
- **Phase 2 iOS-App MVP** Renderer (Gruppe A), Input (Gruppe B
ohne Hardware-KB), Status-Bar (iOS-C-01), Session-Switcher
(iOS-D-01 + a/b), Reconnect-Lifecycle (Gruppe E), Auth (Gruppe F).
- **Phase 3 iOS-App Augmentation** Slash-Palette (iOS-C-04),
Voice (iOS-C-05), Thumbnails (iOS-D-01c), Scrollback-Search
(iOS-D-02), Hardware-KB (iOS-B-06).
---
## 9. Offene Punkte
Keine offenen Punkte mehr in v3. Q-A und Q-C wurden in dieser Version
geschlossen (siehe S-09a bzw. iOS-C-02).