diff --git a/.claude/commands/stand.md b/.claude/commands/stand.md new file mode 100644 index 0000000..c2e4b1c --- /dev/null +++ b/.claude/commands/stand.md @@ -0,0 +1,70 @@ +--- +description: Zeigt den aktuellen Stand von DM360 - was zu tun ist, und ob Repo, Versionen und ausgelieferte App zusammenpassen. +--- + +Zeige den aktuellen Stand dieses Projekts. Zwei Teile: den **gemessenen** +(unten selbst nachrechnen, nie aus dem Gedächtnis) und den **gepflegten** (aus +`OFFEN.md`). + +## 1. Messen + +Führe genau diesen Block aus: + +```bash +R=$(git rev-parse --show-toplevel) && cd "$R" +echo "== Repository ==" +echo " Zweig $(git branch --show-current) | HEAD $(git rev-parse --short HEAD) | origin $(git rev-parse --short @{u} 2>/dev/null || echo '?')" +printf " Arbeitsbaum: "; [ -z "$(git status --porcelain)" ] && echo sauber || git status --short +echo "== Versionen ==" +python - <<'PY' +import json, hashlib, pathlib, zipfile, plistlib, re +b = "custom_components/audi_dashboard/" +m = json.load(open(b + "manifest.json"))["version"] +print(f" Integration {m}") +try: + j = json.load(open(b + "frontend/app/bundle.json")) + z = pathlib.Path(b + "frontend/app/bundle.zip").read_bytes() + ok = j["version"] == m and hashlib.sha256(z).hexdigest() == j["sha256"] and len(z) == j["bytes"] + print(f" OTA-Buendel {j['version']} {'passt' if ok else 'PASST NICHT - npm run ota faellig'}") +except Exception as e: + print(" OTA-Buendel nicht lesbar:", e) +try: + zf = zipfile.ZipFile("companion-app/auslieferung/App.ipa") + n = zf.namelist() + p = plistlib.loads(zf.read([x for x in n if re.match(r"Payload/[^/]+\.app/Info\.plist$", x)][0])) + print(f" .ipa auf dem Telefon {p.get('CFBundleShortVersionString')}") + c = [x for x in n if re.match(r"Payload/[^/]+\.app/capacitor\.config\.json$", x)] + if c: + L = json.loads(zf.read(c[0])).get("packageClassList", []) + fehlt = [k for k in ("BelegZwischenablagePlugin", "KalenderTerminPlugin") if k not in L] + print(" eigene Plugins registriert:", "ja" if not fehlt else "NEIN - " + ", ".join(fehlt)) +except Exception as e: + print(" .ipa nicht lesbar:", e) +PY +echo "== Wartet auf einen Xcode-Lauf ==" +B=$(git log --format=%H -1 -- companion-app/auslieferung/App.ipa) +N=$(git log --oneline "$B..HEAD" -- companion-app/native/ companion-app/scripts/ios-*.sh companion-app/scripts/ios-*.mjs companion-app/capacitor.config.ts) +[ -z "$N" ] && echo " keine nativen Aenderungen seit der ausgelieferten .ipa" || echo "$N" | sed 's/^/ /' +``` + +## 2. Lesen + +Lies danach `OFFEN.md`. Steht dort etwas unter „Wartet auf einen Xcode-Lauf", +oder meldet die Messung nicht registrierte Plugins, lies zusaetzlich +`APPLE_DEV_BACKLOG.md`. + +## 3. Berichten + +Kurz und in dieser Reihenfolge: + +1. **Stimmt der mechanische Stand?** Nur melden, was *nicht* passt - Repo nicht + synchron, Buendel-Version abweichend, Pluginliste unvollstaendig, native + Aenderungen aufgelaufen. Passt alles, genuegt ein Satz. +2. **Was wartet auf den Eigentuemer** (Abschnitt 1 und 2 von `OFFEN.md`). +3. **Was eine Sitzung bauen koennte** (Abschnitt 3), mit einer Empfehlung. + +Nenne die Punkte aus `OFFEN.md`, statt sie neu herzuleiten - und wenn dir beim +Messen etwas auffaellt, das dort fehlt, sag es und trage es nach. + +**Starte nichts von selbst.** Ein Xcode-Lauf ist immer die Handlung des +Eigentuemers (Apple-Regel in `AGENTS.md`). diff --git a/AGENTS.md b/AGENTS.md index 59901f8..fc4cdce 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -252,6 +252,9 @@ uploaded to Claude Design), while the HA panel and the future sideload-only app assets. Never mix these the other way around. **Reading order for a new session:** +0. **`OFFEN.md` — what is to be done right now.** The one file that names the current state; + `/stand` measures repo, versions and the shipped `.ipa` on top of it. This file here answers + *why*, `OFFEN.md` answers *what now*. 1. This file (overview + open items) 2. `UMSETZUNGSPLAN.md` — the step-by-step execution plan for all open items (13 phases with commands and acceptance criteria); when working on an open item, follow the plan's phase diff --git a/CLAUDE.md b/CLAUDE.md index b96bdd3..02512b7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,10 +2,16 @@ ## Claude Code -- `AGENTS.md` above is the single source of truth for project state, rules, and open items — - edit it there, keep this file as a thin shim. +- **`OFFEN.md` says what is to be done right now** — start there, not in AGENTS.md's 12,000 + lines. `/stand` measures the mechanical half itself (repo, versions, shipped `.ipa`) and reads + `OFFEN.md` alongside it. Keep `OFFEN.md` current in the same session something changes. +- `AGENTS.md` above is the single source of truth for **why** things are as they are — history, + rules, and the record of decisions including rejected ones. Edit it there, keep this file a + thin shim. - Remember the AGENTS.md maintenance rule: update it (in English) in the same session whenever your changes affect anything it records. +- Anything needing **Xcode or the Apple Developer Portal** goes in `APPLE_DEV_BACKLOG.md`, and + runs are batched — never start one; that call is the owner's (Apple rule in AGENTS.md). diff --git a/OFFEN.md b/OFFEN.md new file mode 100644 index 0000000..518e7d7 --- /dev/null +++ b/OFFEN.md @@ -0,0 +1,129 @@ +# Was jetzt zu tun ist (DM360) + +**Die eine Datei, die den aktuellen Stand nennt.** Wer wissen will, was ansteht, +liest hier - nicht in 12.000 Zeilen `AGENTS.md`. + +Die drei Dateien teilen sich die Arbeit so: + +| Datei | beantwortet | +|---|---| +| **`OFFEN.md`** (hier) | **Was ist zu tun?** | +| `APPLE_DEV_BACKLOG.md` | Was davon braucht Xcode oder das Apple-Portal? | +| `AGENTS.md` | **Warum** ist etwas so, wie es ist - die Geschichte, nicht der Zustand | + +**Arbeitsregel (verbindlich):** diese Datei wird in **derselben Sitzung** +nachgeführt, in der sich etwas ändert - erledigt, dazugekommen, entschieden. +Eine Liste, die man erst am Monatsende pflegt, ist keine. +Aufruf: **`/stand`** prüft den mechanischen Teil selbst nach und liest diese +Datei dazu. + +--- + +## 1. Wartet auf Sie + +### 1.1 Ein Xcode-Lauf - **zwei Funktionen sind auf dem Telefon tot** + +Zwischenablage und Kalendereintrag sind in der installierten App wirkungslos. +Beide Korrekturen liegen im Repository und warten nur auf einen Lauf. + +*Was zu tun ist:* am Mac `companion-app/scripts/ios-signieren.sh` laufen lassen, +danach die fertige `.ipa` pushen (das Telefon lädt sie aus dem Repository). Das +Skript prüft sich selbst und bricht ab, wenn etwas fehlt; von Hand bleibt nur +die Probe auf dem Gerät. + +Vollständig samt Begründung: **`APPLE_DEV_BACKLOG.md`**, Abschnitte A1 und A2. + +### 1.2 Gitea-Token für den Laborzweig DM180 + +Nicht dieses Repository - der Laborzweig (`tobias/Data-Metric-180`, privat). +Seine Selbstaktualisierung zeigt seit dem 06.09.2026 auf das eigene Repository, +ihr fehlt nur noch der Zugang. + +*Was zu tun ist:* in der Laborinstanz unter Einstellungen -> Geräte & Dienste -> +Audi Dashboard -> Konfigurieren einen Gitea-Token mit Lesezugriff eintragen. + +### 1.3 `steuer.faellig` ist leer + +Betriebsdaten, kein Code - die Kfz-Steuer hat kein Fälligkeitsdatum. + +*Was zu tun ist:* in der App unter Mein Audi -> Versicherung/Steuer eintragen. + +--- + +## 2. Wartet auf eine Entscheidung von Ihnen + +### 2.1 Die Übersicht-Box „Versicherung/Steuer" neu gestalten + +Seit dem 19.08.2026 vorgemerkt und **bewusst nicht begonnen**: Sie hatten +gesagt, Sie wüssten noch nicht, was Sie dort sehen wollen. Ein Entwurf ohne +diese Antwort wäre geraten. + +*Was zu tun ist:* ein kurzes Gespräch darüber, was auf einen Blick sichtbar sein +soll und was auf die Detailseiten gehört. Danach wie üblich erst ein Muster, +dann Code. + +--- + +## 3. Wartet auf eine Sitzung + +Buildbar, ohne Rückfrage, in dieser Reihenfolge sinnvoll: + +### 3.1 Versicherung: PDF der Vertragsdetails ablegen + +Die Police als PDF an den Vertrag hängen und später wieder ansehen können. + +*Was zu tun ist:* zuerst den Ablageort entscheiden - spiegelt es die vorhandene +Fotoablage unter `/config/audi_dashboard/`, oder wird es ein eigenes +Anhang-Konzept? Danach Dienst, Ablage und beide Oberflächen (Paritätsregel). + +### 3.2 Versicherung: freies Notizfeld + +Eine eigene Zusammenfassung zur Versicherung, aus keinem strukturierten Feld +abgeleitet. + +*Was zu tun ist:* Profilfeld, Textfeld in beiden Oberflächen. Das Panel hat mit +`.feld--breit` bereits das Muster für ein Feld über die volle Breite. + +### 3.3 Restliche Dokumentendrift + +`SPECIFICATION.md`, `homeassistant/README.md` und die Profilvorlage nennen noch +den WLAN-Sensor, der am 12.08.2026 entfallen ist; dazu eine falsche Aussage über +Beispielzahlen in der Statistik und ein überholter TODO-Kommentar. + +*Was zu tun ist:* reine Textkorrekturen, kein Code. + +--- + +## 4. Gemeldet, aber nicht reproduzierbar + +Beide mehrfach gesucht und **nicht gefunden**. Sie bleiben stehen, bis sie +wieder auftreten - raten hilft hier nicht. + +* **Das Kartenebenen-Symbol im Standort-Blatt** wirkt fehlerhaft. Dreimal + geprüft (Markup, Funktion, gerechnete Farbwerte), jedes Mal deckungsgleich mit + dem Panel. *Was hilft:* ein Bildschirmfoto vom Gerät. +* **Die Batteriespannungs-Zeile lässt sich am Rechner nicht antippen.** Mit + Trefferpunkt-Prüfung, synthetischen und echten Klicks getestet - navigiert + jedes Mal korrekt. *Was hilft:* die Fensterbreite und ein Blick in die + Browser-Konsole im Moment des Fehlversuchs. + +--- + +## 5. Bekannte Grenzen - bewusst so, nicht offen + +Damit sie nicht als Fehler wiederkommen: + +* **Der Fahrtbeginn liegt bis zu neun Minuten zu spät.** Der Dongle wacht erst + über den Beschleunigungssensor auf; die verschlafenen Kilometer holt die App + seit `2026.9.6.2` aus dem Kilometerstand zurück, den *Zeitpunkt* + zurückzurechnen haben Sie abgelehnt, solange es eine gerechnete statt + gemeldeten Zahl wäre. +* **Werkbank und Fahrzeug lassen sich nicht automatisch trennen.** Ein + Werkbank-Schalter wurde am 06.09.2026 angeboten und abgelehnt - Sie + entscheiden selbst, welche Messwerte bleiben, über das Wischen in der + Messwertliste. **Nicht erneut vorschlagen.** +* **Das Panel wird nicht gelöscht, sondern archiviert** - aber erst, wenn die App + es wirklich abgelöst hat. Heute nicht. +* **HACS ist ein Sackgassenweg**, dauerhaft: es lehnt private Repositories + kategorisch ab. `install.ps1` ist der einzige Installationsweg, die + Selbstaktualisierung der einzige Aktualisierungsweg.