# Oxker Go Rewrite — Review Findings Systematischer Vergleich aller Original-Rust-Dateien mit der Go-Reimplementierung. 6 parallele Review-Agenten, ~130 Findings gesamt. --- ## CRITICAL (App funktioniert falsch) ### C1. CPU immer 0 — ContainerStatsOneShot liefert leere precpu_stats - **Source:** Docker Integration Review #11 - **Rust:** `docker_data/mod.rs:136-143` — `stream: false, one_shot: false` + `.take(1)` - **Go:** `docker/client.go:70` — `ContainerStatsOneShot` setzt `one-shot=true` - **Problem:** Mit `one-shot=true` liefert Docker leere `precpu_stats`, CPU-Berechnung ergibt 0 - **Fix:** `ContainerStats` mit `stream=false` statt `ContainerStatsOneShot` verwenden - **Status:** [x] FIXED ### C2. uint64 Underflow bei CPU-Berechnung - **Source:** Docker Integration Review #6/#7 - **Rust:** `docker_data/mod.rs:86-91` — `saturating_sub` verhindert Underflow - **Go:** `app.go:1120-1121` — plain uint64 Subtraktion, kann wrappen - **Fix:** Guard: `if TotalUsage < PreTotalUsage { return 0 }` - **Status:** [x] FIXED ### C3. --host Flag wird ignoriert - **Source:** Docker Integration Review #1 - **Rust:** `main.rs:47-57` — Config Host > DOCKER_HOST env > default socket - **Go:** `docker/client.go:17-22` — nur `FromEnv`, ignoriert `Config.Host` - **Fix:** `docker.New()` soll optionalen Host akzeptieren, `client.WithHost(host)` verwenden - **Status:** [x] FIXED ### C4. Logs ShowStderr Config ignoriert - **Source:** Docker Integration Review #8 - **Rust:** `docker_data/mod.rs:256-258` — `config.show_std_err` - **Go:** `app.go:1089-1091` — hardcoded `ShowStderr: true` - **Fix:** `ShowStderr: a.Config.ShowStdErr` - **Status:** [x] FIXED ### C5. Bandwidth-Chart zeigt kumulative Bytes statt Rate - **Source:** Data Model Review #8 - **Rust:** `container_state.rs:627-672` — `NetworkBandwidth.to_vec_f64` berechnet Deltas - **Go:** `app.go:1493-1508` — `fmtRate(c.RxBytes)` auf kumulative Rohwerte - **Fix:** Bandwidth als Differenz zwischen aufeinanderfolgenden Einträgen berechnen - **Status:** [x] FIXED ### C6. RunningUnhealthy — fehlt pause/restart in Commands - **Source:** Data Model Review #2, Main UI Review #6 - **Rust:** `container_state.rs:451` — `Running(_) => [Pause, Restart, Stop, Delete]` - **Go:** `app.go:1749-1750` — `RunningUnhealthy` nur `["stop", "delete"]` - **Fix:** Gleiche Commands wie RunningHealthy - **Status:** [x] FIXED ### C7. Enter führt immer ersten Command aus — kein Command-Selection - **Source:** Input Review #6, Data Model Review #4, Main UI Review #8 - **Rust:** `input_handler/mod.rs:267` — prüft `panel == Commands`, nutzt `selected_docker_controls()` - **Go:** `app.go:922` — `cmds[0]` immer, unabhängig von Panel - **Fix:** `CmdSelectedIdx` Feld, nur bei `ActivePanel == PanelCommands` ausführen - **Status:** [x] FIXED ### C8. Ctrl+C quit nicht in Filter/Search-Modus - **Source:** Input Review #9 - **Rust:** `input_handler/mod.rs:762-763` — Ctrl+C immer quit - **Go:** `app.go:360-367` — Filter/Search early return, Ctrl+C wird nie erreicht - **Fix:** Ctrl+C Check vor Mode-Dispatch - **Status:** [x] FIXED ### C9. Mouse-Events nicht blockiert in Overlay-Modi - **Source:** Input Review #10 - **Rust:** `input_handler/mod.rs:74-84` — blockiert Mouse in Error/Help/Filter/Search/DeleteConfirm - **Go:** `app.go:638` — keine Mode-Checks, Mouse immer aktiv - **Fix:** Mode-Checks am Anfang von `handleMouse` - **Status:** [x] FIXED ### C10. Info-Popup Auto-Dismiss fehlt (4 Sekunden) - **Source:** Popups Review #9 - **Rust:** `info.rs:52-54` — `instant.elapsed() > 4000ms` - **Go:** `app.go:1003-1006` — Kommentar sagt "handled by tick", aber kein Timer - **Fix:** `tea.Tick(4*time.Second)` → `InfoDismissMsg` - **Status:** [x] FIXED --- ## HIGH (UI sieht falsch aus) ### H1. CPU-Format ohne Zero-Padding - **Source:** Main UI Review #2 - **Rust:** `container_state.rs:521` — `{:05.2}%` → `00.00%`, `05.34%` - **Go:** `app.go:1325` — `%.2f%%` → `0.00%`, `5.34%` - **Fix:** `fmt.Sprintf("%05.2f%%", c.CPUPercent)` - **Status:** [x] FIXED ### H2. Container-Spalten ohne Farben (Name/ID/Image/RX/TX) - **Source:** Main UI Review #10/#11 - **Rust:** `containers.rs:26-33` — Name/ID/Image mit `containers.text` (Blue), RX/TX eigene Farben - **Go:** `app.go:1321-1332` — kein Styling - **Fix:** lipgloss.Foreground für Name/ID/Image und separate Farben für RX/TX - **Status:** [x] FIXED ### H3. Command-Farben falsch - **Source:** Main UI Review #5 - **Rust:** restart=Magenta, delete=Gray, resume=Blue, start=Green, stop=Red, pause=Yellow - **Go:** restart/resume/start=Green, stop/delete=Red, pause=Yellow - **Fix:** Jeder Command eigene Farbe - **Status:** [x] FIXED ### H4. Layout-Proportionen falsch - **Source:** Main UI Review #17 - **Rust:** `ui/mod.rs:400` — 75%/25% (oben/unten) - **Go:** `app.go:1664-1686` — 30% Container, 22% Charts, Rest Logs - **Fix:** 75%/25% Split, dann Container/Logs innerhalb der 75% - **Status:** [x] FIXED ### H5. Ports: `::` und `0` statt leer - **Source:** Charts/Ports Review #15/#16 - **Rust:** `container_state.rs:156-160` — None → leerer String - **Go:** `app.go:1522-1523` — `::` für leere IP, `0` für fehlenden Public Port - **Fix:** Leere Strings statt `::` und `0` - **Status:** [x] FIXED ### H6. Falsches Highlight-Symbol - **Source:** Main UI Review #12 - **Rust:** `mod.rs:47` — `⚪ ` (offener Kreis) - **Go:** `app.go:1315` — `●` (gefüllter Kreis, blau) - **Fix:** `⚪ ` verwenden - **Status:** [x] FIXED ### H7. Default-Sort fehlt (nach CreatedAt) - **Source:** Data Model Review #13 - **Rust:** `mod.rs:492-499` — sort by `created` + Name als Tiebreaker - **Go:** `app.go:829-831` — kein Sort bei `SortNone` - **Fix:** Bei `SortNone` nach `CreatedAt` sortieren, Name als Tiebreaker - **Status:** [x] FIXED ### H8. Sort verliert Selection - **Source:** Data Model Review #6 - **Rust:** `mod.rs:377-387` — re-selects Container by ID nach Sort - **Go:** `app.go:812-827` — SelectedIdx bleibt gleich, Container an Position ändert sich - **Fix:** Nach Sort alten Container per ID finden und SelectedIdx aktualisieren - **Status:** [x] FIXED ### H9. Sort Tiebreaker by Name fehlt - **Source:** Data Model Review #15 - **Rust:** `mod.rs:437-484` — `.then_with(|| name.cmp(name))` - **Go:** `app.go:834-866` — kein Tiebreaker - **Fix:** Name-Vergleich als Tiebreaker bei Gleichheit - **Status:** [x] FIXED ### H10. State-Reihenfolge beim Sort falsch - **Source:** Data Model Review #14 - **Rust:** `container_state.rs:316-327` — Healthy=0, Unhealthy=1, Paused=2, Restarting=3, etc. - **Go:** iota-Reihenfolge weicht ab (Exited vor Restarting) - **Fix:** `order()` Methode mit Rust-Mapping - **Status:** [x] FIXED ### H11. Search-Highlight: ganze Zeile statt Substring - **Source:** Charts/Ports Review #22 - **Rust:** Substring-Level Highlighting - **Go:** `app.go:1422-1423` — ganze Zeile gelb - **Fix:** Nur gematchten Substring highlighten - **Status:** [x] FIXED ### H12. Help wird als Vollbild gerendert statt Overlay - **Source:** Popups Review #11 - **Rust:** `mod.rs:477-480` — Overlay auf Base View - **Go:** `app.go:1175-1177` — ersetzt komplett den View - **Fix:** Base View rendern, dann Help darüber legen - **Status:** [x] FIXED ### H13. Log-Zeilen: Byte-Length statt Rune-Length für UTF-8 - **Source:** Main UI Review #28 - **Rust:** `.chars().count()` für Width - **Go:** `app.go:1409-1414` — `len(line)` (Bytes) - **Fix:** `[]rune(line)` oder `runewidth` verwenden - **Status:** [x] FIXED ### H14. Bandwidth-Chart: Keine historischen Daten gerendert - **Source:** Charts/Ports Review #6 - **Rust:** `chart_bandwidth.rs:92-109` — zwei Line-Datasets (RX/TX) - **Go:** `app.go:1493-1508` — nur Text-Labels, kein Sparkline - **Fix:** Sparklines für RX/TX History hinzufügen - **Status:** [x] FIXED ### H15. LogHeight Default: 40 statt 75 - **Source:** Popups Review #23 - **Rust:** `gui_state.rs:220` — default `75` - **Go:** `app.go:213` — default `40` - **Fix:** Default auf `75` ändern - **Status:** [x] FIXED --- ## MEDIUM (Verhaltensunterschiede) ### M1. Binate Stats-Sammlung fehlt (keine Deduplizierung) - **Source:** Docker Integration Review #2 - **Rust:** `docker_data/mod.rs:44-61` — Binate-Enum, Spawn-Deduplizierung - **Go:** `app.go:1043-1081` — keine Tracking, Duplikate möglich - **Fix:** `pendingStats map[string]bool` für In-Flight Tracking - **Status:** [x] FIXED ### M2. Logs: Tail-500 statt inkrementell (since-Timestamp) - **Source:** Docker Integration Review #9 - **Rust:** `docker_data/mod.rs:256-273` — `since` Parameter, akkumuliert - **Go:** `app.go:1091` — `Tail: "500"`, ersetzt jedes Mal - **Status:** [x] FIXED — uses `since` for incremental fetching after initial load ### M3. Per-Container Log-Speicher fehlt - **Source:** Data Model Review #3 - **Rust:** `ContainerItem.logs` — HashSet mit Dedup, per-Container Scroll - **Go:** `App.LogLines` — einzelner globaler Slice - **Status:** [x] FIXED — Container.Logs/LogScroll/LogHScroll with save/restore on selection change ### M4. Container-Selbstfilterung (oxker-Container verstecken) fehlt - **Source:** Docker Integration Review #12, Data Model Review #9 - **Rust:** `docker_data/mod.rs:229-234` — ENTRY_POINT Filter - **Go:** keine Selbstfilterung - **Status:** [x] FIXED — respects Config.ShowSelf ### M5. Docker Ping-Check bei Startup fehlt - **Source:** Docker Integration Review #15 - **Rust:** `main.rs:68-88` — Ping + Error mit Host-Pfad - **Go:** `app.go:207` — `docker.New()` Error wird ignoriert - **Status:** [x] FIXED — Ping + Host in error message ### M6. Filter-Mode: `/` beendet nicht den Modus (wird als Text eingegeben) - **Source:** Input Review #14 - **Rust:** `input_handler:523-528` — `/` beendet Filter-Mode - **Go:** `app.go:570-590` — `/` wird als Zeichen eingefügt - **Status:** [x] FIXED (already implemented — `/` in enter case) ### M7. Search-Mode: `#` beendet nicht den Modus - **Source:** Input Review #15 - **Rust:** `input_handler:409-414` — `#` beendet Search-Mode - **Go:** `app.go:598-631` — `#` wird als Zeichen eingefügt - **Status:** [x] FIXED (already implemented — `#` in enter case) ### M8. Direkte Action-Keys (s/x/r/d/p/u) existieren in Rust nicht - **Source:** Input Review #17 - **Rust:** Actions nur über Commands-Panel mit Enter - **Go:** `app.go:478-489` — direkte Shortcuts - **Note:** Go-Erweiterung, könnte gewollt sein, aber kollidiert mit Rust-Keybindings - **Status:** [x] WONTFIX — bewusste Erweiterung, Shortcuts sind nützlich ### M9. Mouse-Scroll-Amount: 3 statt 1 (mit 10x Modifier) - **Source:** Input Review #19 - **Rust:** `input_handler:828-829` — Scroll by 1 oder 10 mit Ctrl - **Go:** `app.go:639-644` — hardcoded 3 - **Status:** [x] FIXED (already 1) ### M10. Mouse-Scroll in Inspect-Mode nicht unterstützt - **Source:** Input Review #20 - **Rust:** `input_handler:810-818` — Mouse-Scroll im Inspect - **Go:** `handleMouse` hat keinen Inspect-Check - **Status:** [x] FIXED (via C9) ### M11. Error-Mode: andere Keys nicht blockiert - **Source:** Input Review #24 - **Rust:** `handle_error` — nur clear/quit Keys - **Go:** Sort-Keys, Scroll-Keys etc. funktionieren während Error - **Status:** [x] FIXED (via C8) ### M12. Unknown-State: falsche Commands - **Source:** Main UI Review #7 - **Rust:** `container_state.rs:452` — `Unknown => [Delete]` nur - **Go:** `app.go:1753-1754` — `Unknown => [start, restart, delete]` - **Status:** [x] FIXED (via C6) ### M13. Commands-Panel Scroll fehlt - **Source:** Input Review #5 - **Rust:** `docker_controls_scroll` bewegt Command-Selection - **Go:** Scroll im Commands-Panel ändert Container-Selection - **Status:** [x] FIXED (via C7) ### M14. Commands-Panel Breite: fest 14 statt 10% - **Source:** Main UI Review #4 - **Rust:** `ui/mod.rs:419` — `Percentage(10)` - **Go:** `app.go:1278` — `cmdW := 14` - **Status:** [x] FIXED — 10% mit min 12 ### M15. DockerConnect Error: kein Countdown, kein Auto-Exit - **Source:** Popups Review #6/#17 - **Rust:** 5-Sekunden Countdown, Auto-Exit, Host-Anzeige - **Go:** Standard-Error-Popup - **Status:** [x] FIXED — 5s countdown + auto-exit + host in error message ### M16. Delete-Dialog: Name nicht bold/highlighted - **Source:** Popups Review #1 - **Rust:** `delete_confirm.rs:44-53` — Name bold + highlighted - **Go:** `app.go:1542` — einfacher String - **Status:** [x] FIXED ### M17. Help-View: stark reduzierter Inhalt - **Source:** Popups Review #12 - **Rust:** ~570 Zeilen, Logo, Version, Config-Pfad, Timezone, alle Keys - **Go:** ~20 Zeilen, nur Basis-Keys - **Status:** [x] FIXED — erweitert mit Config-Pfad, Panel-Info, vollständiger Keybinding-Liste ### M18. Container-Name: führender `/` wird nicht entfernt - **Source:** Charts/Ports Review #30 - **Rust:** `inspect.rs:35-38` — Strip `/` Prefix - **Go:** Name direkt verwendet - **Status:** [x] FIXED (already done via TrimPrefix) ### M19. Inspect: Wrapping statt Truncation - **Source:** Charts/Ports Review #29 - **Rust:** `inspect.rs:133` — `Wrap { trim: false }` - **Go:** `app.go:1603` — Truncation - **Status:** [x] FIXED ### M20. Spaltenbreiten fest statt dynamisch - **Source:** Main UI Review #1, Data Model Review #17 - **Rust:** `mod.rs:845-879` — max Width pro Spalte aus Daten - **Go:** `app.go:1264-1273` — feste Prozent-Widths - **Status:** [x] FIXED — dynamic widths based on container data ### M21. State-Icons: andere Unicode-Zeichen - **Source:** Main UI Review #24 - **Rust:** `✓`, `✖`, `॥`, `↻`, `!`, `?` - **Go:** `✔`, `✖`, `‖`, `↻`, `!`, `?` - **Status:** [x] FIXED — ✓ statt ✔ ### M22. Search-Navigation: Ctrl+N/P statt Down/Up - **Source:** Input Review #16 - **Rust:** Down/Up Arrow für nächsten/vorherigen Match - **Go:** Ctrl+N/Ctrl+P - **Status:** [x] FIXED (already supports both Down/Up and Ctrl+N/P) ### M23. Log-Search Case-Sensitivity nicht konfigurierbar - **Source:** Data Model Review #19 - **Rust:** `config.log_search_case_sensitive` - **Go:** immer case-insensitive - **Status:** [x] FIXED — respects Config.LogSearchCaseSensitive ### M24. Filter wraps around (Go), Rust stoppt an Grenzen - **Source:** Data Model Review #16 - **Rust:** `FilterBy::next()/prev()` gibt None an Grenzen - **Go:** Modulo-Wrapping - **Status:** [x] FIXED — stoppt an Grenzen ### M25. Overlay-Popups: `base` Parameter wird ignoriert - **Source:** Popups Review #16 - **Go:** `overlayError(base)`, `overlayInfo(base)` — base wird nie verwendet - **Status:** [x] FIXED — overlay placement with transparent bg --- ## LOW (Kosmetische/Konfigurationsunterschiede) ### L1. Alle Farben hardcoded statt aus Config - Betrifft: alle Panels, Popups, Charts, Headers - Config `AppColors` existiert, wird aber nie gelesen - **Status:** [x] FIXED — colorOr() resolver, borders/commands/state colors from config ### L2. Custom Keymaps nicht implementiert - Config `Keymap` existiert, wird aber nie verwendet - Alle Keys sind hardcoded Strings - **Status:** [x] FIXED — keyMatch() checks config keymap with hardcoded fallbacks ### L3. Mouse-Capture Toggle (`m` Key) fehlt - **Source:** Input Review #1 - **Status:** [x] FIXED ### L4. Force-Redraw Key (`f`) fehlt - **Source:** Input Review #2 - **Status:** [x] FIXED — tea.ClearScreen ### L5. Container-Name/Image Truncation bei 30 Zeichen - **Source:** Data Model Review #18 - **Status:** [x] FIXED (handled by dynamic column widths M20) ### L6. CpuStats Epsilon: 0.001 statt 0.01 - **Source:** Data Model Review #24 - **Status:** [x] FIXED (already 0.001) ### L7. fmtRate fehlt GB/s Tier - **Source:** Data Model Review #23 - **Status:** [x] FIXED ### L8. InspectData: Name/ID nicht beim Inspizieren gespeichert - **Source:** Data Model Review #21 - **Status:** [x] FIXED (already shown in viewInspect title) ### L9. Scroll-Speed Modifier: Shift statt Ctrl - **Source:** Input Review #3 - **Status:** [x] FIXED (already uses J/K = Shift+j/k) ### L10. Horizontal-Scroll in Search-Mode fehlt - **Source:** Input Review #8 - **Status:** [x] FIXED — left/right in search mode ### L11. Header: "show help" → "exit help" Toggle fehlt - **Source:** Main UI Review #19 - **Status:** [x] FIXED ### L12. Header: `↓ rx` / `↑ tx` Pfeile existieren nicht in Rust - **Source:** Main UI Review #20 - **Status:** [x] FIXED — removed arrows ### L13. Charts: State-abhängige Farben fehlen - **Source:** Charts/Ports Review #4/#8 - **Status:** [x] FIXED — dim color for non-running states ### L14. Charts: Y-Achse Max-Wert fehlt - **Source:** Charts/Ports Review #2 - **Status:** [x] FIXED — max label shown ### L15. Filter-Bar: kein dediziertes UI (nur inline Text) - **Source:** Charts/Ports Review #17/#18 - **Status:** [x] FIXED — dedicated styled filter bar ### L16. Search-Bar: kein dediziertes UI (nur inline Text) - **Source:** Charts/Ports Review #20/#21 - **Status:** [x] FIXED — dedicated styled search bar ### L17. Ports: Title nicht zentriert, nicht als Border-Title - **Source:** Charts/Ports Review #31 - **Status:** [x] FIXED — centered title ### L18. Inspect: Scroll-Clamping fehlt - **Source:** Charts/Ports Review #27 - **Status:** [x] FIXED — clampInspectScroll() ### L19. "No containers" Message fehlt - **Source:** Main UI Review #29 - **Status:** [x] FIXED ### L20. Minimum Terminal-Size Handling fehlt - **Source:** Main UI Review #30 - **Status:** [x] FIXED — 60x10 minimum with message ### L21. Logs: "parsing logs" Init-State fehlt - **Source:** Main UI Review #14 - **Status:** [x] FIXED ### L22. Logs: scroll_padding fehlt - **Source:** Main UI Review #15 - **Status:** [x] FIXED — auto-follow when at bottom ### L23. Logs: color_logs Toggle fehlt - **Source:** Main UI Review #16 - **Status:** [x] FIXED — stripAnsi when ColorLogs=false ### L24. appendMax Slice-Leak (kein Ring-Buffer) - **Source:** Data Model Review #22 - **Status:** [x] FIXED — in-place copy instead of reslice ### L25. Delete-Dialog: Container-Not-Found Guard fehlt - **Source:** Popups Review #2 - **Status:** [x] FIXED — guard + default name ### L26. Network: alle Interfaces statt nur eth0 - **Source:** Docker Integration Review #3 - **Note:** Go-Verhalten ist besser, bewusste Abweichung - **Status:** [x] WONTFIX — bewusste Verbesserung