Fix: stderr-Pipe gegen Instant-Exit-Datenverlust, TCP-Vorab-Check, Fehler-Banner; Icon (Dracula) im Bundle
This commit is contained in:
@@ -14,6 +14,9 @@ Stand: 2026-09-21 · Version 0.1.0 · macOS arm64 · Swift 5.9+ · Xcode 15+
|
||||
| 5 | 2026-09-21 | App-Bundle + DMG | keine Fehler: `build-app.sh` (Signatur ok), `build-dmg.sh` (UDZO, 200K), Mount-Verifikation ok (App + Applications/Programme-Links) | Info | ✅ ok |
|
||||
| 6 | 2026-09-21 | SSH verbinden | kein Terminal öffnete sich: `SSHService.openInTerminal` nutzte `NSAppleScript` → scheitert still (keine `NSAppleEventsUsageDescription`, kein Error-Handling) | blockierend | ✅ behoben — In-App-PTY-Terminal (Dracula) + `.command`-Fallback |
|
||||
| 7 | 2026-09-21 | ANSI-Parser (Test) | `feed()` flusht Chunk erst NACH `parseCSI` → Text bekam den neuen statt alten Stil (`rot` mit fg=nil statt 1) | mittel | ✅ behoben — Flush vor Stilwechsel |
|
||||
| 8 | 2026-09-21 | SSH-Session stirbt instant ohne Meldung | stderr hing mit am PTY: macOS verwirft ungelesene Master-Daten bei Slave-Close → „Code 255" ohne Text | blockierend | ✅ behoben — stderr→Pipe, TCP-Vorab-Check, Fehler-Banner |
|
||||
| 9 | 2026-09-21 | `swift build` | `Result<Void, String>`: String conformt nicht zu Error (Folgefehler: DispatchQueue-Overload) | blockierend | ✅ behoben — Completion als `(String?) -> Void` |
|
||||
| 10 | 2026-09-21 | Icon-Generator (`RenderIcon.swift`) | 3 Swift-Fehler: `guard let x = f() ?? g()` (nicht optional), `Int * CGFloat`, falscher Preview-Pfad | klein | ✅ behoben |
|
||||
|
||||
---
|
||||
|
||||
@@ -92,6 +95,32 @@ dist/
|
||||
**Verifikation:** `swift build` ok; Parser-Harness 8/8; PTY-Smoke (`/bin/echo` → Output + Exit 0); `ssh -G example.com` durchs PTY ok.
|
||||
**Status:** ✅ behoben.
|
||||
|
||||
## #8 — Terminal verbindet nicht, „direkt gekappt" (User-Bugreport)
|
||||
**Phase:** Laufzeit, SSH-Profil → Tab öffnet, sofort „Sitzung beendet (Code 255)." — ohne jede Meldung
|
||||
**Reproduktion (Harness, exakter App-Pfad `ssh -p 1 nobody@127.0.0.1`):**
|
||||
```
|
||||
STATE: done(exitCode: Optional(255), message: "Sitzung beendet (Code 255).")
|
||||
TEXT: "\n\n— Sitzung beendet (Code 255). —\n" # <- Fehlermeldung fehlt!
|
||||
```
|
||||
**Ground Truth (Python-pty):** Selbst `/bin/echo hello` liefert `b''`, wenn man erst NACH Child-Exit liest; bei sofortigem Lesen kommt `b'hello-py\r\n'`. → macOS verwirft ungelesene PTY-Master-Daten beim Slave-Close (danach EIO). Unser `DispatchSourceRead` verliert dieses Rennen bei Instant-Exit-Kindern — und ssh schreibt ALLES (inkl. „Connection refused") nach stderr, das mit am PTY hing.
|
||||
**Fix (`Services/PTYSession.swift`, `Services/TCPCheck.swift`, `Views/EmbeddedTerminalView.swift`):**
|
||||
- stderr → `Pipe` (gepufferte Daten überleben Child-Exit garantiert), stdin/stdout bleiben am PTY (TTY erhalten für interaktive Prompts)
|
||||
- `finalFlush` (non-blocking Rest-Drain) + Epoch-guarded Lifecycle (kein State-/FD-Durcheinander bei Trennen→Neuverbinden)
|
||||
- TCP-Vorab-Check (Network.framework, 4 s Timeout) mit deutschen Klartext-Meldungen (refused/DNS/Timeout/Port)
|
||||
- Rotes Fehler-Banner mit letzter Meldung + Diagnose- und Erneut-Buttons
|
||||
**Verifikation:** Refused-Harness zeigt jetzt `ssh: connect to host 127.0.0.1 port 1: Connection refused` (PASS); Roundtrip (`cat`) PASS; `ssh -G` PASS; TCP-Harness (closed/open/empty) PASS.
|
||||
**Status:** ✅ behoben.
|
||||
|
||||
## #9 — Build: `Result<Void, String>` ungültig
|
||||
**Log:** `error: type 'String' does not conform to protocol 'Error'` (+ Folgefehler an `DispatchQueue.main.async`)
|
||||
**Fix:** `TCPCheck.check` nutzt `(String?) -> Void` (nil = ok, sonst deutsche Meldung).
|
||||
**Status:** ✅ behoben.
|
||||
|
||||
## #10 — Icon-Generator Buildfehler
|
||||
**Log:** `guard let` auf nicht-optionalem Ausdruck (`??` unwrapt schon); `Int * CGFloat`; Preview lag in `.iconset/` statt `/tmp/`.
|
||||
**Fix:** `??`-Fallback direkt zuweisen; `CGFloat(...)`; Pfad korrigiert.
|
||||
**Status:** ✅ behoben. Icon: `Resources/AppIcon.icns` (per `scripts/generate-icon.sh` reproduzierbar), Vorschau `docs/icon-preview.png`.
|
||||
|
||||
## #7 — ANSI-Parser: Text bekam falschen Stil
|
||||
**Phase:** `swiftc`-Harness während #6
|
||||
**Log:** `text("rot", fg: nil)` statt `fg: 1`
|
||||
|
||||
+2
-1
@@ -3,8 +3,9 @@
|
||||
## Lokal bauen
|
||||
```bash
|
||||
./scripts/build-release.sh [version] # ZIP mit Binary + Docs
|
||||
./scripts/build-app.sh [version] # RemminaMac.app (Bundle, ad-hoc-signiert)
|
||||
./scripts/build-app.sh [version] # RemminaMac.app (Bundle, ad-hoc-signiert, mit Icon)
|
||||
./scripts/build-dmg.sh [version] # DMG mit App + Programme-Link
|
||||
./scripts/generate-icon.sh # AppIcon.icns neu rendern (Dracula-Terminal)
|
||||
# Beispiel:
|
||||
./scripts/build-release.sh 0.1.0
|
||||
./scripts/build-app.sh 0.1.0
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
|
||||
## Verbinden
|
||||
- Profil wählen → `▶ Verbinden` oder Doppelklick.
|
||||
- SSH/SFTP: **In-App-Terminal (Dracula-Theme) direkt im Tab** — verbindet automatisch, kein externes Fenster nötig. Eingabezeile unten (Auge-Icon = Passwort-Modus), `^C`/`^D`-Buttons, `Leeren`, `Trennen`/`Verbinden`, `Tab schließen`.
|
||||
- SSH/SFTP: **In-App-Terminal (Dracula-Theme) direkt im Tab** — erst TCP-Vorab-Check (falscher Port/Host → sofort klare Meldung statt kryptischem Exit-Code), dann Auto-Connect. Eingabezeile unten (Auge-Icon = Passwort-Modus), `^C`/`^D`-Buttons, `Leeren`, `Trennen`/`Verbinden`, `Tab schließen`. Bei Fehlschlag: rotes Banner mit letzter Meldung + Diagnose-Button.
|
||||
- Alternativ: `In Terminal.app öffnen` (öffnet eine `.command`-Datei, braucht keine Automation-Berechtigung) oder `Befehl kopieren`.
|
||||
- RDP: startet `xfreerdp` (falls vorhanden) oder öffnet MS Remote Desktop.
|
||||
- VNC: öffnet `vnc://host:port`.
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 336 KiB |
Reference in New Issue
Block a user