Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
072ccd3
design: add semantic Theme tokens and rewire StatusController colors
Jul 10, 2026
86a825d
docs: add implementation plan for review fixes, design pass, and tests
Jul 10, 2026
c745fa8
build: split SolixBarKit library, add swift-testing target with unit …
Jul 10, 2026
3433dcf
fix: P0 issues — notch-aware width degradation, portable paths, keep …
Jul 10, 2026
335004d
fix: measure status item frame via button-to-screen conversion for no…
Jul 10, 2026
3f1bf6d
fix: harden data providers, keychain for password, per-source history…
Jul 10, 2026
cf76ca2
ci: GitHub workflow building tested, ready-to-run app bundles
Jul 10, 2026
9ca3346
ci: trigger workflow
Jul 10, 2026
173a022
ci: use macos-15 runner for Swift 6 toolchain
Jul 10, 2026
44699e5
design: semantic colors everywhere, graph precision, dark-mode fixes,…
Jul 10, 2026
9180678
feat: logging overhaul, settings polish, SMAppService autostart, v0.4.0
Jul 10, 2026
316633c
style: use real German umlauts in comments, docs, and UI strings
Jul 10, 2026
0b94a82
design: custom dashboard window frame, two-line compact menu bar, hel…
Jul 11, 2026
a128710
design: aspect-correct glyphs, boxless plot area, borderless window p…
Jul 11, 2026
f9dc708
design: slim-bar readability, separate + default compact options, sub…
Jul 11, 2026
e4337b4
feat: independent detached-bar configuration and design round 2 polish
Jul 11, 2026
4080f50
design: chip-based history section, fit-to-data option, crisp renderi…
Jul 11, 2026
c0e260d
design: align chip header on baselines, stat-tile cards, remove dead …
Jul 11, 2026
cc6e20e
design: left-aligned chip rows sharing one edge, properly centered ch…
Jul 11, 2026
9f732be
design: restore Verlauf title left of the range chips (baseline-aligned)
Jul 11, 2026
19fd3a9
design: title above range chips (three stacked header lines, one left…
Jul 11, 2026
9e6c939
fix: derive dashboard height from constraints, chips beside title in …
Jul 11, 2026
f5b4ab2
ux: custom-days field holds only the number, unit as adjacent label
Jul 11, 2026
5eea98f
fix: full dark/light mode support, click-based custom range, demo his…
Jul 11, 2026
ed67046
feat: year-long two-tier history, shared graph header, custom range i…
Jul 11, 2026
5269c2e
fix: appearance-scoped color resolution everywhere, menu follows app …
Jul 11, 2026
0992b49
design: detail-row gaps show the app background (drop the container t…
Jul 11, 2026
0e42228
design: remove slim bar contour line (read white in dark, black in li…
Jul 11, 2026
2cf5af3
docs: before/after review renders and icon proposal (demo data only)
Jul 11, 2026
136efd4
docs: mark phase 5 complete with PR and upstream issue links
Jul 11, 2026
c1ce017
fix: menu bar keeps showing its configured values while the slim bar …
Jul 11, 2026
f84092d
polish: remove dead CenteredTextFieldCell, consistent bar wording, no…
Jul 11, 2026
cee346e
feat: final pack - formatter extraction, live preview, trends, hover,…
Jul 11, 2026
04920d6
feat: window levels, hover-only close, color/direction split, flow me…
Jul 11, 2026
20635f2
docs: aktualisierte Review-Renders, neue App-Icon-Entwürfe (Panel als…
Jul 11, 2026
c247af4
fix: Slim-Bar-Breite aus echten Layout-Maßen statt Schätzung — kein L…
Jul 11, 2026
dc621ac
ci: Releases bekommen automatisch einen Commit-Changelog seit dem vor…
Jul 11, 2026
95a4ea9
docs: Phase 6 im Plan dokumentiert (Feedback-Runde, Konsolidierung, v…
Jul 11, 2026
67e0b2c
feat: History speichert Haus- und Akkufluss-Watt (Basis für Datenexport)
Jul 11, 2026
7dbfab7
feat: Verlaufsfenster abdockbar — Menüpunkt, Sitzungs-Restore, wählba…
Jul 11, 2026
6a2fb17
feat: automatischer Update-Check mit macOS-Mitteilung und Menü-Hinweis
Jul 11, 2026
5a188de
feat: Leistung je PV-Eingang — Datenpfad, Dashboard-Zeile, Anzeige-Op…
Jul 11, 2026
fe060ff
feat: optionale Warnungen — Akku niedrig, PV-Einbruch, Zeitfenster, P…
Jul 11, 2026
28fa2b2
feat: Datenexport als CSV oder JSON über das Statusmenü
Jul 11, 2026
1f84340
feat: Werte-Auswahl mit Drag-&-Drop-Reihenfolge — vier unabhängige Li…
Jul 11, 2026
d8d511f
chore: v0.4.2-Vorbereitung — Version-Injektion, Changelog, Plan
Jul 11, 2026
2ade9a4
feat: PV-Eingänge einzeln statt Summe in Dashboard und Leisten; fix: …
Jul 11, 2026
af732f0
feat: PV-Anzeige dreistufig (Gesamt/Einzeln/Beides) je Fläche; fix: G…
Jul 11, 2026
cd80f4e
fix: Demo simuliert den PV-Kanal-Ausfall nur bei aktiver Pro-PV-Warnu…
Jul 11, 2026
642f2d9
feat: PV-Anzeige auch für das abgedockte Dashboard-Fenster getrennt w…
Jul 11, 2026
ea9354a
docs: Review-Renders auf v0.4.2-Stand, PLAN.md Phase 7 abgeschlossen
Jul 11, 2026
b0f026f
docs: README mit aktuellen Screenshots und v0.4.2-Funktionen; Setting…
Jul 11, 2026
b146d5f
feat: Einbruch-Warnung je PV-Eingang + Datenquelle "Demo (Warnungs-Te…
Jul 11, 2026
1d2b899
feat: v0.4.3 — direkter SOLIX-Modus, Graph-Glättung, Dashboard- und U…
Jul 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Build & Test

on:
push:
branches: ['**']
tags: ['v*']
pull_request:
workflow_dispatch:

permissions:
contents: write

jobs:
build:
name: Build, test, and package
runs-on: macos-15
steps:
- uses: actions/checkout@v4
with:
# Volle Historie: der Release-Changelog listet Commits seit dem
# vorherigen Tag.
fetch-depth: 0

- name: Swift version
run: swift --version

# Schutz gegen vergessene VERSION-Datei: Tag und VERSION müssen
# übereinstimmen, sonst trägt das Release die falsche Nummer.
- name: Verify tag matches VERSION (tags only)
if: startsWith(github.ref, 'refs/tags/v')
run: |
FILE_VERSION="$(tr -d '[:space:]' < VERSION)"
TAG_VERSION="${GITHUB_REF_NAME#v}"
if [ "$FILE_VERSION" != "$TAG_VERSION" ]; then
echo "Tag ${GITHUB_REF_NAME} passt nicht zur VERSION-Datei (${FILE_VERSION})." >&2
exit 1
fi

- name: Run tests
run: swift test

- name: Build release binary (universal)
run: swift build -c release --arch arm64 --arch x86_64

# Portable Python-Laufzeit für den direkten SOLIX-Modus. Die Laufzeit
# ist arm64-only (wie die Runner); auf Intel-Macs bleiben Demo-,
# Befehl- und URL-Modus voll nutzbar.
- name: Prepare SOLIX runtime
run: sh scripts/prepare_solix_runtime.sh

- name: Package app bundle
run: |
SOLIXBAR_BIN=".build/apple/Products/Release/SolixBar" sh scripts/package_app.sh
sh scripts/verify_release.sh outputs/SolixBar.app
ditto -c -k --sequesterRsrc --keepParent outputs/SolixBar.app SolixBar-macOS.zip

- name: Upload render snapshots
uses: actions/upload-artifact@v4
with:
name: ui-renders
path: .build/renders/
if-no-files-found: ignore

- name: Upload app bundle artifact
uses: actions/upload-artifact@v4
with:
name: SolixBar-macOS
path: SolixBar-macOS.zip

- name: Attach bundle to release with changelog (tags only)
if: startsWith(github.ref, 'refs/tags/v')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PREV_TAG=$(git describe --tags --abbrev=0 "${GITHUB_REF_NAME}^" 2>/dev/null || true)
{
echo "Hinweis: Das Bundle ist ad-hoc signiert. Beim ersten Start: Rechtsklick -> \"Oeffnen\"."
echo "Note: The bundle is ad-hoc signed. First launch: right-click -> \"Open\"."
echo
echo "## Changelog"
if [ -n "$PREV_TAG" ]; then
git log --no-merges --pretty='- %s' "${PREV_TAG}..${GITHUB_REF_NAME}"
echo
echo "Kompletter Diff: https://github.com/${GITHUB_REPOSITORY}/compare/${PREV_TAG}...${GITHUB_REF_NAME}"
else
git log --no-merges --pretty='- %s' "${GITHUB_REF_NAME}"
fi
} > release-notes.md
gh release create "${GITHUB_REF_NAME}" --title "SolixBar ${GITHUB_REF_NAME}" --notes-file release-notes.md || true
gh release upload "${GITHUB_REF_NAME}" SolixBar-macOS.zip --clobber
21 changes: 7 additions & 14 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
.DS_Store
.build/
*.pyc
__pycache__/

# Local/generated runtime assets
work/
outputs/
bin/
obj/
.vs/
*.user
*.suo

# Local secrets or generated command snippets
*.env
work/
.claude/
.DS_Store
*.xcodeproj
renders/
__pycache__/
*.pyc
4 changes: 2 additions & 2 deletions Bundle/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.3.20</string>
<string>0.4.0</string>
<key>CFBundleVersion</key>
<string>45</string>
<string>46</string>
<key>LSMinimumSystemVersion</key>
<string>14.0</string>
<key>LSUIElement</key>
Expand Down
63 changes: 63 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,68 @@
# Changelog

## 0.4.3 - 2026-07-13

- DE: Verlaufsgraph: Kurven lassen sich optional glätten (weiche, fliessende Kurven, die durch alle Messpunkte laufen und auf die Plotfläche geklemmt sind, damit ein Bogen nie scheinbar negative Watt unter die Nulllinie zieht), und die dezente Flächenfüllung unter den Kurven ist jetzt je Kurve (Akku, Solar, Netzbezug) einzeln wählbar — beides unter App → Dashboard. Die Demo-Datenquelle zeigt den Akkustand jetzt als langsame, realistische Lade-/Entladekurve statt als Minuten-Sägezahn.
- EN: History graph: curves can optionally be smoothed (soft, flowing curves that run through every measurement and are clamped to the plot area so a bend never draws seemingly negative watts below the zero line), and the subtle area fill under the curves is now selectable per curve (battery, solar, grid import) — both under App → Dashboard. The demo data source now shows the battery level as a slow, realistic charge/discharge curve instead of a per-minute sawtooth.
- DE: Die Fragezeichen-Knöpfe in den Einstellungen zeigen beim Klick jetzt ausführliche, verständliche Hilfetexte in einem lesbaren Popover (bisher blieb die Sprechblase leer); der Hover-Tooltip bleibt der kurze Hinweis.
- EN: The question-mark buttons in the settings now show extensive, easy-to-understand help texts in a readable popover on click (previously the bubble stayed empty); the hover tooltip remains the short hint.
- DE: Dashboard-Kacheln (Akku/Solar): Der Wert passt seine Größe an die verfügbare Breite an, statt den Trend-Pfeil abzuschneiden; bei drei oder vier PV-Eingängen werden die Einzelwerte als 2×2-Raster auf zwei Zeilen gezeigt (der zweizeilige Wert wächst nach unten, die Titel bleiben auf gleicher Höhe).
- EN: Dashboard tiles (battery/solar): the value scales to the available width instead of cutting off the trend arrow; with three or four PV inputs the individual values are shown as a 2×2 grid on two lines (the two-line value grows downward, the titles stay aligned).

- DE: Neue Datenquelle "SOLIX-Konto (direkt)": SolixBar fragt Anker direkt mit Mail und Passwort ab — ohne konfigurierten Befehl und ohne lokale Python-Installation. Das Release-Bundle enthält eine portable Python-Laufzeit samt SOLIX-Modulen (arm64; auf Intel-Macs bleiben Demo-, Befehl- und URL-Modus nutzbar). Die Zugangsdaten gehen als stdin-JSON an den Helper statt als Umgebungsvariablen, das Passwort liegt weiterhin nur im macOS-Schlüsselbund. Wer bisher den vorbereiteten SOLIX-Befehl nutzte, wird automatisch auf den direkten Modus umgestellt.
- EN: New data source "SOLIX account (direct)": SolixBar queries Anker directly with email and password — no configured command and no local Python installation required. The release bundle ships a portable Python runtime with the SOLIX modules (arm64; on Intel Macs the demo, command, and URL modes remain available). Credentials are passed to the helper as stdin JSON instead of environment variables; the password still lives only in the macOS Keychain. Users of the prepared SOLIX command are migrated to the direct mode automatically.
- DE: Weniger API-Aufrufe: Der Helper cached die teure Tagesstatistik 10 und die Gesamtstatistik 15 Minuten (atomar geschriebene 0600-Dateien im Application-Support-Ordner); die Live-Leistungswerte kommen weiterhin bei jedem Abruf frisch. Ertragszustand und Cache liegen nie mehr im (signierten) App-Bundle.
- EN: Fewer API calls: the helper caches the expensive daily statistics for 10 and the total statistics for 15 minutes (atomically written 0600 files in Application Support); live power values stay fresh on every refresh. Energy state and cache never live inside the (signed) app bundle anymore.
- DE: Fehler-Backoff: Nach fehlgeschlagenen Abrufen verdoppelt sich der Abstand bis zum nächsten Versuch (maximal 30 Minuten) und springt beim ersten Erfolg auf das eingestellte Intervall zurück — bei toter API hämmert die App nicht mehr die ganze Nacht durch. Der nächste Abruf wird erst nach Abschluss des laufenden geplant.
- EN: Failure backoff: after failed refreshes the delay to the next attempt doubles (capped at 30 minutes) and resets to the configured interval on the first success — a dead API no longer gets hammered all night. The next refresh is scheduled only after the current one finishes.
- DE: Unsichtbare Fenster (geschlossenes Dashboard-/Verlaufsfenster) werden nach einem Abruf nicht mehr unnötig neu aufgebaut; beim Öffnen wird ohnehin frisch gerendert.
- EN: Hidden windows (closed dashboard/history window) are no longer rebuilt unnecessarily after a refresh; opening them renders fresh anyway.
- DE: Release-Prozess: `scripts/prepare_solix_runtime.sh` lädt die portable Laufzeit reproduzierbar (python-build-standalone, gepinnt), `package_app.sh` bettet sie ein und entfernt die Debug-Map aus dem Binary (keine absoluten Quellpfade mehr im Bundle), `verify_release.sh` prüft Version, Signatur, private Daten und die Importierbarkeit der SOLIX-Module; die CI macht das alles automatisch.
- EN: Release process: `scripts/prepare_solix_runtime.sh` downloads the portable runtime reproducibly (python-build-standalone, pinned), `package_app.sh` embeds it and strips the debug map from the binary (no more absolute source paths in the bundle), `verify_release.sh` checks version, signature, private data, and that the SOLIX modules import; CI does all of this automatically.

## 0.4.2 - 2026-07-11

- DE: Update-Hinweis: SolixBar prüft täglich die GitHub-Releases und meldet eine neuere Version einmalig per macOS-Mitteilung plus dauerhaftem Menüpunkt ("Update verfügbar"). Abschaltbar unter App → "Automatisch nach Updates suchen". Installiert wird nichts automatisch.
- EN: Update notice: SolixBar checks the GitHub releases daily and reports a newer version once via macOS notification plus a persistent menu entry ("Update available"). Can be disabled under App → "Check for updates automatically". Nothing is installed automatically.
- DE: Verlaufsfenster abdockbar: neuer Menüpunkt "Verlauf abdocken" öffnet den großen Graphen als eigenes Fenster; Position und Offen-Zustand überleben einen Neustart, die Fensterebene (vorn/normal/hinten) ist wie bei Dashboard und Slim-Bar wählbar.
- EN: Detachable history window: a new "Detach history graph" menu entry opens the large graph as its own window; position and open state survive a restart, and the window level (front/normal/behind) is selectable like for the dashboard and slim bar.
- DE: Datenexport: "Daten exportieren ..." schreibt die gespeicherte History der aktiven Datenquelle als CSV (für Excel/Numbers) oder JSON — Formatwahl direkt im Speichern-Dialog. Die History erfasst jetzt zusätzlich Hauslast und Akku-Fluss; ältere Dateien bleiben lesbar.
- EN: Data export: "Export data ..." writes the stored history of the active data source as CSV (for Excel/Numbers) or JSON — format selectable right in the save dialog. History now also records home load and battery flow; older files stay readable.
- DE: Warnungen (alle standardmäßig aus, Tab "Warnungen"): Akku unter Schwelle (einmalig, mit Hysterese), PV-Einbruch (0 W obwohl kürzlich erzeugt wurde — nachts still), optionales Tagesfenster und Überwachung einzelner PV-Eingänge — wahlweise im Vergleich zu den anderen Eingängen und/oder als Einbruch gegen die eigene jüngste Erzeugung (erkennt defekte Module auch, wenn mehrere Eingänge gleichzeitig betroffen sind). Zustellung als macOS-Mitteilung plus ⚠-Eintrag im Menü, solange die Bedingung anhält.
- EN: Warnings (all off by default, "Warnings" tab): battery below threshold (fires once, with hysteresis), PV collapse (0 W despite recent production — silent at night), optional daytime window, and monitoring of individual PV inputs — either compared to the other inputs and/or as a dip against the input's own recent production (catches defective panels even when several inputs are affected at once). Delivered as macOS notifications plus a ⚠ menu entry while the condition persists.
- DE: Neue Datenquelle "Demo (Warnungs-Test)": spielt ein gerafftes Szenario ab (normale Erzeugung → Akku fällt unter die Schwelle → PV-Eingang 2 stirbt → kompletter PV-Einbruch), mit 30-Sekunden-Abruf und 10-fach geraffter Zeit — aktivierte Warnungen feuern so innerhalb weniger Minuten wirklich als Mitteilung.
- EN: New data source "Demo (warning test)": plays an accelerated scenario (normal production → battery drops below threshold → PV input 2 dies → full PV collapse) with a 30-second refresh and 10× compressed time — enabled warnings actually fire as notifications within a few minutes.
- DE: Leistung je PV-Eingang: `solix_snapshot.py` reicht die MPPT-Kanäle (`solar_power_1..4`) als `pvWatts` durch. Die "PV-Anzeige" ist je Fläche wählbar — Gesamtwert, Einzelwerte ("438 · 204 W") oder Gesamt + Einzelwerte — getrennt für das Dashboard im Menü, das abgedockte Dashboard-Fenster, die Menüleiste und die abgedockte Leiste (bei den Leisten jeweils für einzeilige und Kompaktansicht). Hinweis: Feldnamen laut anker-solix-api, mangels Hardware unverifiziert — Solarbank 2 Pro/3 melden 4 Kanäle, Solarbank 2 Plus/AC 2, die erste Generation keine.
- EN: Per-PV-input power: `solix_snapshot.py` forwards the MPPT channels (`solar_power_1..4`) as `pvWatts`. The "PV display" is selectable per surface — total, individual inputs ("438 · 204 W"), or total + individual — separately for the menu dashboard, the detached dashboard window, the menu bar, and the detached bar (bars apply it to single-line and compact views). Note: field names per anker-solix-api, unverified without hardware — Solarbank 2 Pro/3 report 4 channels, Solarbank 2 Plus/AC 2, the first generation none.
- DE: Behoben: Nach einer Einstellungsänderung zeigte der Graph im Dropdown beim ersten Öffnen keine Linien — die Einblende-Animation lief im Standard-Runloop-Modus, der während der Menü-Anzeige pausiert; die Animation blieb bei 0 stehen. Der Timer läuft jetzt im common-Modus; zusätzlich gleicht der Appearance-Neuaufbau des Dashboards Layout und Höhe ab.
- EN: Fixed: after a settings change the dropdown graph showed no lines on first open — the reveal animation ran in the default run-loop mode, which pauses while a menu is showing, so it stalled at 0. The timer now runs in common modes; additionally the dashboard's appearance rebuild re-runs layout and height.
- DE: Werte-Auswahl mit Reihenfolge: Statt fester Häkchen-Raster gibt es sortierbare Listen (Häkchen wählt aus, Ziehen ordnet) — getrennt für Menüleiste und abgedockte Leiste sowie jeweils für einzeilige und Kompaktansicht. Die Kompakt-Listen folgen der einzeiligen, bis man sie entkoppelt.
- EN: Value selection with ordering: the fixed checkbox grids are now sortable lists (checkbox selects, dragging reorders) — separate for the menu bar and the detached bar, and for the single-line and compact views. Compact lists follow the single-line list until decoupled.
- DE: Version wird beim Packen automatisch aus der `VERSION`-Datei in die App geschrieben (Anzeige in Einstellungen/Menü stimmt ab jetzt immer); die CI bricht ab, wenn ein Release-Tag nicht zur `VERSION`-Datei passt. Lokal gepackte Bundles werden ad-hoc signiert, damit Mitteilungen funktionieren.
- EN: The version is injected from the `VERSION` file at packaging time (the settings/menu display is now always correct); CI fails when a release tag does not match the `VERSION` file. Locally packaged bundles are ad-hoc signed so notifications work.

## 0.4.1 - 2026-07-11

- DE: Nutzer-Feedback-Runde: Fensterebene wählbar (Slim-Bar und Dashboard getrennt), Schließen-Kreuz der Slim-Bar nur bei Hover, "Farbige Werte" und "Flussrichtung" getrennt schaltbar je Leiste, Sammel-Metrik "Energiefluss" entfernt (Migration aktiviert die Pfeil-Option), Kompaktansicht mit Richtungspfeilen und Status-Metrik, Slim-Bar-Breite aus echten Layout-Maßen. Releases erhalten automatisch einen Commit-Changelog.
- EN: User-feedback round: selectable window level (slim bar and dashboard separately), slim-bar close button only on hover, "colored values" and "flow direction" toggle separately per bar, composite "energy flow" metric removed (migration enables the arrows option), compact view with direction arrows and status metric, slim-bar width from real layout metrics. Releases automatically get a commit changelog.

## 0.4.0 - 2026-07-11

- DE: Statusitem weicht der Notch aus: Auf MacBooks mit Notch verdichtet sich die Menüleisten-Anzeige automatisch stufenweise (ohne Bezeichnungen -> ohne Symbole -> kompakt), bis sie vollständig sichtbar ist. Vorher konnte das Item komplett hinter der Notch verschwinden.
- EN: The status item now avoids the notch: on notched MacBooks the menu bar display degrades stepwise (no labels -> no symbols -> compact) until it is fully visible. Previously the item could disappear behind the notch entirely.
- DE: SOLIX-Zugangsdaten: Passwort liegt jetzt im macOS-Schlüsselbund; die Env-Datei (neu unter `~/Library/Application Support/SolixBar/solixbar.env`, Rechte 0600) enthält keine Secrets mehr. Die früher fest verdrahteten Pfade ins Home-Verzeichnis des Autors sind entfernt - der eingebaute SOLIX-Login funktioniert damit auf jedem Rechner.
- EN: SOLIX credentials: the password now lives in the macOS Keychain; the env file (new location `~/Library/Application Support/SolixBar/solixbar.env`, mode 0600) no longer contains secrets. The previously hardcoded paths into the original author's home directory are gone - the built-in SOLIX login now works on any machine.
- DE: Fehlertoleranz: Ein fehlgeschlagener Abruf leert die Anzeige nicht mehr, sondern behält die letzten Werte mit Warnhinweis. HTTP-Fehler werden klar gemeldet; grosse Befehlsausgaben blockieren nicht mehr (Pipe-Deadlock); haengende Befehle werden hart beendet.
- EN: Resilience: a failed refresh keeps the last values with a warning instead of blanking the display. HTTP errors are reported clearly; large command output no longer blocks (pipe deadlock); stuck commands are force-killed.
- DE: Verlauf: Samples werden pro Datenquelle getrennt gespeichert (Demo-Daten verfälschen den Live-Graphen nicht mehr) und als Datei in Application Support. Die Speichergrenze richtet sich nach dem Intervall, sodass die 30-Tage-Ansicht gefüllt werden kann.
- EN: History: samples are stored per data source (demo data no longer pollutes the live graph) in a file in Application Support. The cap follows the refresh interval so the 30-day view can actually fill.
- DE: Design: zentrales semantisches Farbsystem (Netzbezug rot = Kosten, Einspeisung violett), praezisere Grafen (runde Stundenticks, klare Achsenzuordnung, Legendenpunkte an den Checkboxen), Demo-Badge im Dashboard, korrekter Dark Mode, Template-Glyph in der Menüleiste.
- EN: Design: central semantic color system (grid import red = cost, export violet), more precise graphs (round hour ticks, clear axis mapping, legend dots on checkboxes), demo badge in the dashboard, correct dark mode, template glyph in the menu bar.
- DE: Autostart nutzt SMAppService statt eines LaunchAgent-Plists. Logging zusätzlich ins Unified Logging (Console.app), mit mehr Kontext und optionalem Debug-Modus (`defaults write local.codex.SolixBar verboseLogging -bool true`).
- EN: Autostart uses SMAppService instead of a LaunchAgent plist. Logging additionally goes to unified logging (Console.app) with more context and an optional debug mode.
- DE: Neu: Tests (Unit + Offscreen-Render-Snapshots + HTTP-Integrationstests) und GitHub-Actions-Workflow, der fertige App-Bundles baut.
- EN: New: tests (unit + offscreen render snapshots + HTTP integration tests) and a GitHub Actions workflow producing ready-to-run app bundles.

## Unreleased

## 0.3.20 - 2026-07-10
Expand Down
Loading