# MiniTerm — winzige eigenständige Terminal-Apps für macOS

Ein minimaler, auf **SwiftTerm** basierender Terminal-Emulator. Sinn der Sache:
jede erzeugte `.app` ist eine **eigene macOS-App mit eigener Bundle-ID** — also
**eigenes Dock-Icon und eigener ⌘-Tab-Eintrag**. Genau das, was sich unter macOS
mit `--class` (wie bei Alacritty/Ghostty unter Linux) *nicht* lösen lässt.

Jede App startet in einem konfigurierbaren **Arbeitsverzeichnis** und führt einen
konfigurierbaren **Befehl** aus (z. B. `claude`). Für Claude Code reicht das
locker — SwiftTerm ist ein vollwertiger xterm-256color-kompatibler Emulator.

## Voraussetzungen

- macOS 13+ und **Xcode** bzw. die Command Line Tools (`xcode-select --install`)
- Swift (kommt mit Xcode)

## Schnellstart

```bash
cd MiniTerm
chmod +x make-app.sh

./make-app.sh \
  --name "Claude · Projekt A" \
  --bundle-id com.deinname.claude.projekta \
  --workdir ~/code/projekt-a \
  --command "claude"
```

Beim ersten Lauf wird das Binary einmal gebaut (`swift build -c release`,
lädt SwiftTerm). Danach liegt die App in `~/Applications/Claude · Projekt A.app`
— per Doppelklick starten, Dock-Icon erscheint als eigene App.

## Mehrere Apps (eigene Icons/Configs)

Einfach pro App einmal aufrufen. Das Binary wird nur einmal kompiliert und
wiederverwendet:

```bash
./make-app.sh --name "Claude · Webshop"  --bundle-id com.deinname.claude.webshop \
              --workdir ~/code/webshop   --command "claude" --icon ./icons/shop.icns

./make-app.sh --name "Claude · Infra"    --bundle-id com.deinname.claude.infra \
              --workdir ~/code/infra     --command "claude" --icon ./icons/infra.icns

./make-app.sh --name "Scratch Shell"     --bundle-id com.deinname.scratch \
              --workdir ~                --command ""    # leer = einfache Shell
```

## Optionen

| Flag           | Pflicht | Bedeutung                                              |
|----------------|---------|--------------------------------------------------------|
| `--name`       | ja      | Anzeigename + Dateiname der App                        |
| `--bundle-id`  | ja      | Eindeutige Bundle-ID (gibt die eigene App-Identität)   |
| `--workdir`    | nein    | Startverzeichnis (`~` wird expandiert; leer = Home)    |
| `--command`    | nein    | Befehl beim Start (leer = nur eine Login-Shell)        |
| `--font-size`  | nein    | Schriftgröße (Default 13)                              |
| `--font`       | nein    | Schriftfamilie (Default Menlo; Fallback System-Mono)   |
| `--icon`       | nein    | PNG/JPG (wird automatisch konvertiert) oder `.icns`    |
| `--out`        | nein    | Zielordner (Default `~/Applications`)                  |

## Icon aus einem PNG

`--icon` nimmt direkt ein **PNG** (oder JPG) — das Skript erzeugt daraus
automatisch alle nötigen Größen und das `.icns` (via `sips`/`iconutil`):

```bash
./make-app.sh --name "Claude · Infra" --bundle-id com.deinname.claude.infra \
  --workdir ~/code/infra --command "claude" --icon ~/Downloads/infra.png
```

Am besten ein **quadratisches** Bild nehmen, sonst verzerrt `sips` es. Eine
fertige `.icns`-Datei kannst du weiterhin auch direkt angeben.

## Wie die Konfiguration funktioniert

Das kompilierte Binary ist für alle Apps identisch. Die Unterschiede stecken in
der `Info.plist` jedes Bundles (Schlüssel `MTCommand`, `MTWorkingDirectory`,
`MTWindowTitle`, `MTFontSize`, `MTFontName`). Das Programm liest sie beim Start aus
`Bundle.main`. So genügt ein Build für beliebig viele Apps.

## Hinweise

- Der Befehl läuft immer über eine **Login-Shell** (`zsh -l`), damit PATH stimmt
  (Homebrew, `~/.local/bin` usw.) und `claude` gefunden wird.
- Nach Beenden des Befehls fällt das Fenster in eine normale Shell zurück
  (`exec zsh -l`), schließt sich also nicht sofort.
- Die App ist **ad-hoc signiert**. Beim ersten Start ggf. Rechtsklick → „Öffnen",
  falls Gatekeeper meckert.
- SwiftTerm-Version: im `Package.swift` auf `branch: "main"`. Für reproduzierbare
  Builds dort auf einen festen Tag (`from: "..."`) umstellen.

## Tastatur

- **Enter** sendet wie gewohnt einen Wagenrücklauf (`\r`) → Eingabe absenden.
- **Shift+Enter** sendet einen Zeilenumbruch (`\n`) → für mehrzeilige Eingaben,
  z. B. in Claude Code. Gilt auch für Enter auf dem Ziffernblock.
- ⌘C / ⌘V funktionieren über das Edit-Menü.
