11 KiB
Fehlerprotokoll (ERRORS.md)
Alle Fehler, die beim Erstellen / Bauen / Releasen von RemminaMac aufgetreten sind — mit Ursache, Fix und Status. Wird bei jedem Build fortgeschrieben.
Stand: 2026-09-21 · Version 0.1.0 · macOS arm64 · Swift 5.9+ · Xcode 15+
Übersicht
| # | Zeitpunkt | Phase | Fehler | Schwere | Status |
|---|---|---|---|---|---|
| 1 | 2026-09-21 | swift build (debug) |
WindowGroup<some View> has no member 'windowTitle' |
blockierend | ✅ behoben |
| 2 | 2026-09-21 | swift build -c release |
keine Fehler, nur lange Link-Zeit (~40 s) | Info | ✅ ok |
| 3 | 2026-09-21 | Release-Skript | dist/ war nicht in .gitignore → Binary drohte committet zu werden |
mittel | ✅ behoben (ignoriert) |
| 4 | 2026-09-21 | Gitea-Upload | GET /api/v1/user → 401 invalid username, password or token mit alten Credentials |
blockierend (Push/Release) | ✅ behoben — neue Credentials ok, Push + Release v0.1.0 hochgeladen |
| 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 |
| 11 | 2026-09-21 | Passwort-Feature | Wunsch: Passwort + Keys speichern UND nutzen (bisher nur gespeichert, nie benutzt) | Feature | ✅ umgesetzt — Auto-Login via sshpass, sonst interaktiv |
#1 — windowTitle existiert nicht auf WindowGroup
Phase: erster swift build
Log (gekürzt):
Sources/RemminaMac/RemminaMacApp.swift:14:10: error: value of type 'WindowGroup<some View>' has no member 'windowTitle'
14 | .windowTitle("RemminaMac")
Ursache: windowTitle(_:) ist kein Modifier für WindowGroup. Der Fenstertitel wird im WindowGroup-Init übergeben.
Fix: Sources/RemminaMac/RemminaMacApp.swift:
// vorher (falsch):
WindowGroup { ... }.windowTitle("RemminaMac")
// nachher (korrekt):
WindowGroup("RemminaMac") { ... }
Verifikation: swift build → Build complete! (1.31s).
Status: ✅ behoben, kein Re-Check offen.
#2 — Release-Build langsam, aber fehlerfrei
Phase: bash scripts/build-release.sh 0.1.0 → swift build -c release
Log:
Building for production...
[4/5] Linking RemminaMac
Build complete! (40.54s)
Ursache: keine — Release-Optimierung + Link brauchen beim ersten Mal ~40 s.
Fix: keiner nötig. Bei wiederholten Builds ist es schneller (Cache in .build/).
Artefakte:
dist/RemminaMac-0.1.0-macos-arm64.zip (186K)
dist/RemminaMac-0.1.0-macos-arm64.zip.sha256 (c476bb3c…)
Status: ✅ ok.
#3 — dist/ fast committet
Phase: Release-Vorbereitung
Ursache: dist/ enthielt ZIP + entpacktes Binary, .gitignore kannte es noch nicht.
Fix: .gitignore ergänzt:
.build/
dist/
*.zip
*.sha256
Verifikation: git status --short zeigt kein dist/ mehr.
Status: ✅ behoben.
Vorlage für neue Fehler
## #N — Titel
**Phase:** ...
**Log:** ...
**Ursache:** ...
**Fix:** ...
**Verifikation:** ...
**Status:** ⬜ offen / ✅ behoben
Wie Fehler hierher kommen
- Jeder
swift build/swift build -c release/ Skript-Lauf mit Fehler → Log-Ausschnitt + Exit-Code hier eintragen. - Gitea-Push/Release-Fehler (z. B. 401, Repo existiert schon, Asset-Upload schlägt fehl) ebenfalls hier dokumentieren.
- Neue Tests:
AnsiParserperswiftc-Harness (/tmp, SGR/CRLF/Clear/Map),PTYSessionper Smoke-Test (/bin/echo+ssh -Gdurchs echte PTY).
#6 — SSH-Klick öffnet kein Terminal (User-Bugreport)
Phase: Laufzeit, SSH-Profil → Verbinden
Ursache: Services/ConnectionServices.swift nutzte NSAppleScript(tell application "Terminal" to do script …). Ohne NSAppleEventsUsageDescription und ohne Error-Auswertung scheitert das still — es passiert schlicht nichts.
Fix:
- Neu:
Services/PTYSession.swift— echte PTY-Session (posix_openpt,sshmit TTY),TerminalManagerpro Profil (überlebt Tab-Wechsel). - Neu:
Views/EmbeddedTerminalView.swift— In-App-Terminal im Dracula-Theme (Services/TerminalTheme.swift,Services/AnsiParser.swift), Auto-Connect peronAppear, Eingabezeile + Passwort-Modus +^C/^D. SessionViewbettet das Terminal ein (min. 380 pt),ContentView.connect()öffnet nur noch den Tab.- Extern-Fallback umgebaut auf
.command-Datei viaNSWorkspace(keine Automation-Rechte nötig). Verifikation:swift buildok; Parser-Harness 8/8; PTY-Smoke (/bin/echo→ Output + Exit 0);ssh -G example.comdurchs 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 -GPASS; 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.
#11 — Passwort speichern UND benutzen (User-Wunsch)
Stand: Passwort/Key-Passphrase wurden in der Keychain gespeichert, aber nie zum Einloggen benutzt (ssh fragte immer interaktiv). Umsetzung:
SSHService.loginSecret()(Profil-Passwort → Key-Passphrase),sessionConfig()(rein, testbar): mit Secret + sshpass →sshpass -e ssh/sftp …+SSHPASS-Env (nie Befehlszeile/Logs); sonst direkter Aufruf + interaktiver Prompt.PTYSession.customEnv+autoLogin-Flag,TerminalManagerverdrahtet alles; Status zeigt „Auto-Login via Keychain".- Editor: Gespeichert-Anzeige (✓), Löschen-Button, sshpass-Hinweis; Titel-Bug (
UUID-Vergleich mit neuem Random-Objekt) viaisNewersetzt. Verifikation: Config-Harness 9/9 (inkl. „Passwort nie in Befehlszeile"); echter Keychain-Roundtrip 7/7 (save/load/delete + Priorität + Fallback). Hinweis: Ohnesshpass(brew install sshpass) bleibt es beim interaktiven Prompt — hier auf dem Build-Mac ebenfalls nicht installiert, getestet wurde der interaktive Pfad + Logik. Status: ✅ umgesetzt.
#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
Ursache: Chunk wurde erst nach dem SGR-Wechsel geflusht.
Fix: Services/AnsiParser.swift — flush() vor parseCSI.
Verifikation: Harness 8/8 grün.
Status: ✅ behoben.
#4 — Gitea-Upload: 401 trotz erreichbarem Server
Phase: POST /api/v1/user/repos + GET /api/v1/user auf https://git.sysdaemon.xyz (Version 1.27.3, per /api/v1/version bestätigt)
Log:
GET /user -> 401
{"message":"invalid username, password or token","url":"https://git.sysdaemon.xyz/api/swagger"}
Getestet mit Login x3 und x3@sysdaemon.xyz — beide 401. Kein Quote-/Encoding-Problem (Basic-Auth via Python, kein Shell-Escaping).
Mögliche Ursachen:
- Passwort falsch/ablaufen bzw. Sonderzeichen-Typo
- Account braucht App-Token statt Passwort (Gitea: User → Einstellungen → Anwendungen → Token erzeugen)
- Falscher Owner-/Repo-Name Fix (manuell, sobald Credentials stimmen):
cd RemminaMac
git remote add origin https://<user>@git.sysdaemon.xyz/<owner>/remmina-mac.git
git push -u origin main
export GITEA_HOST="https://git.sysdaemon.xyz" GITEA_OWNER="<owner>" GITEA_REPO="remmina-mac" GITEA_TOKEN="<token>" VERSION="0.1.0"
./scripts/publish-gitea-release.sh
Oder mit Token als Passwort: git push https://<owner>:<token>@git.sysdaemon.xyz/<owner>/remmina-mac.git main.
Lokaler Stand: Commit cd834dc + dist/RemminaMac-0.1.0-macos-arm64.zip sind fertig und warteten nur auf den Push.
Nachtrag 2026-09-21: ✅ behoben — mit korrigierten Credentials: GET /api/v1/user → 200 (login x3), Repo x3/remmina-mac erstellt (201), git push -u origin main ok, Release v0.1.0 (id 1) + 2 Assets (ZIP + SHA256) hochgeladen.
Status: ✅ behoben.