Commit Graph
46 Commits
Author SHA1 Message Date
schakal00783andClaude Opus 5 aa0098ae01 fix: Knoepfe rutschten aus der Zeile; verwaiste Audiodateien raeumen
1. Aufnahmenliste: bei schmaler Spalte schob ein langer Titel die Knoepfe aus
der Zeile, der Papierkorb-Knopf war nicht mehr erreichbar. Flex-Kinder haben
min-width: auto, der Textblock schrumpft also nie unter seine Inhaltsbreite.
Mit der dritten Schaltflaeche (Stecknadel) reichte der Platz nicht mehr.

2. 23 sichtbare Aufnahmen = 46 Dateien, im Ordner lagen 152: 106 verwaiste mit
242 MB, Rueckstand des alten deleteRecording, das nur die DB-Zeile entfernte.
Einmalig geraeumt (Gegenprobe: keine der 106 stand in einer Zeile, danach
fehlt keine benoetigte Datei) und sweepOrphans haelt es sauber -- laeuft hinter
sweepTrash beim Start und taeglich, mit 2-h-Altersgrenze, weil eine Aufnahme
erst verschoben und dann in die DB geschrieben wird.

Die Papierkorb-Kette selbst war korrekt, mit einer Wegwerf-Zeile nachgewiesen:
loeschen -> Papierkorb (Dateien bleiben), endgueltig -> Zeile und beide Dateien
weg.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 23:53:54 +02:00
schakal00783andClaude Opus 5 d9554c590c fix(audio): Wiedergabe-MP3 als CBR ohne Xing-Tabelle -- Wortmarkierung war 28 s voraus
Die Markierung im Transkript stand auf einem Wort, gesprochen wurde eins vier
Zeilen weiter oben (gemessen an #85: 24 s Vorlauf).

Nicht die Ursache -- jeweils per Gegenprobe ausgeschlossen: die Wortzeiten
(Ausschnitte bei 600/1240/3400 s einzeln transkribiert, enthalten exakt die
Wörter der DB), MP3- vs WAV-Zeitachse (identisch), ffmpeg-Seek (trifft),
ontimeupdate-Logik (korrekt).

Ursache war der Sprung im Browser: in einer VBR-Datei gibt es keine feste
Byte-pro-Sekunde-Regel, also nutzt er die Xing-Tabelle -- 100 Stützstellen,
bei 63 Minuten ein 38-s-Raster. Er landet auf der Stützstelle davor, meldet
über currentTime aber die angefragte Zeit. Nachgerechnet: Ziel 20:40 spielt
ab 20:11,5 (-28,5 s).

Fix: -b:a 64k -ar 48000 -ac 1 -write_xing 0 statt -qscale:a 3. Byte-Position
proportional zur Zeit. Die Tabelle muss auch bei CBR weg, sie rastert auf
1/256 der Dateigröße (~15 s pro Stunde, Restfehler bis -6,4 s gemessen). Ohne
sie rechnet der Decoder linear: Restfehler 0,02 s an neun Stichpunkten.

lab/recode-cbr.sh schreibt den Altbestand einmalig um (Quelle WAV, sonst die
MP3 selbst), lab/tocerr.py ist das Messwerkzeug dahinter.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 23:40:29 +02:00
schakal00783andClaude Opus 5 3496b4a2df feat(gui): gruene Nadel bei angehefteter Aufnahme, Logo fuehrt zu den Aufnahmen
Der Anheften-Knopf zeigte bei angehefteter Aufnahme nur die Zahl, die Nadel
blieb rot. Sie ist jetzt gruen (--ok, wie das "KI ✓"-Abzeichen). Dafuer
ersetzt ein SVG mit currentColor (ICON_PIN, gleiches Muster wie ICON_TABLE)
das 📌-Emoji: ein Farb-Emoji rendert immer rot, color greift daran nicht.

Klick auf Wellen-Logo und Schriftzug wechselt auf den Reiter "Aufnahmen".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 23:14:41 +02:00
schakal00783andClaude Opus 5 d0e02eb976 feat(gui): Ordner-Ebene eines Projekts umbenennbar
Der erste Reiter hieß fest "Ordner" und trägt jetzt einen frei wählbaren
Namen. Er steht in der neuen Spalte projects.root_tab_name (NULL = "Ordner")
statt als Zeile in project_tabs: die Ordner-Ebene ist kein echter Reiter --
es gibt sie immer, sie hat keine eigene id und ist nicht löschbar. Eine
eigene Zeile hätte eine id gebraucht, die in project_pins.tab_id landen
müsste, womit die "0 = Ordner-Ebene"-Regel und damit der UNIQUE-Index
gefallen wären.

PATCH /api/projects/:id/tabs/0 fängt die 0 ab und schreibt ins Projekt;
leerer Name setzt auf "Ordner" zurück. Ebenen-Auswahl im Pin-Dialog und die
Liste bestehender Anheftungen zeigen den Namen mit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 23:11:12 +02:00
schakal00783andClaude Opus 5 772385713e feat(gui): Projektansicht mit Ordnern, Unterreitern und angehefteten Aufnahmen
Neuer Reiter neben "Aufnahmen": Projektordner bündeln Aufnahmen zweistufig
(Ordner + Unterreiter), auf beiden Ebenen anheftbar. Anheften geht aus dem
Projekt heraus (Dropdown mit Filter) oder über den 📌-Knopf in der
Aufnahmenliste, der Ordner und Ebene abfragt, neue Ordner anlegt und
bestehende Anheftungen zum Lösen zeigt. Klick auf eine angeheftete Aufnahme
springt in die Aufnahmen-Ansicht.

Ein Pin ist eine Referenz, kein Besitz: die Aufnahme bleibt unverändert in
der Liste und darf in mehreren Ordnern hängen.

project_pins.tab_id ist INT NOT NULL DEFAULT 0 (0 = Ordner-Ebene) statt NULL,
weil MariaDB NULL von UNIQUE-Indizes ausschließt — sonst ließe sich dieselbe
Aufnahme mehrfach auf dieselbe Ebene anheften. So macht INSERT IGNORE das
Anheften idempotent.

purgeRecording räumt project_pins mit ab; getProject blendet Aufnahmen im
Papierkorb aus, ohne deren Pin zu löschen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 23:05:07 +02:00
Sascha 963ce427da fix: Geisterzaehler nach Neustart + rkllm-Leck in /api/search/answer
Aufgefallen beim Nachsehen, warum die GUI bei 29:32 Audio 2h34min Analysezeit zeigte.

1. Ein systemctl restart SIGKILLt alle Kindprozesse, die DB-Zeile blieb aber auf
   analysis_status=pending mit gesetztem analysis_started_at. Die GUI zaehlte dadurch
   ewig hoch fuer Arbeit, die es nicht mehr gab. db.failStaleJobs() setzt beim Start
   pending/transcribing auf error - zum Startzeitpunkt kann kein Job legitim laufen.

2. /api/search/answer lud rkllm und gab es nie frei: 1h48min lang 82,6% RAM belegt,
   nur 237 MB verfuegbar. Genau der Zustand, den analyzeRecording und rediarize mit
   llm.stopServer() bewusst vermeiden, weil der TitaNet-Helfer daneben an OOM stirbt
   (auf #71 seinerzeit 48 Rohsprecher). stopServer() jetzt im finally der Route.
2026-07-31 15:25:49 +00:00
Sascha 914ab2ddc8 feat(gui): Abschnittstitel der Zusammenfassung fett
Die Section-Zusammenfassung kommt als "Titel:\nFliesstext"-Bloecke zurueck, wurde aber
als flache Textwand gerendert. renderSummary() setzt Titelzeilen jetzt fett.

Im Renderer statt in der DB, damit es sofort fuer alle vorhandenen Zusammenfassungen
gilt, ohne 22 Aufnahmen je 20 Minuten neu zu analysieren.

Regel /^[^.!?]{3,90}:$/ = kurze, alleinstehende Zeile mit Doppelpunkt am Ende. Gegen
die echten Zusammenfassungen #85/#79/#74 geprueft: 37 Titel erkannt, keine
Fliesstextzeile falsch fett, keine Doppelpunkt-Zeile uebersehen.
2026-07-31 13:43:54 +00:00
Sascha d5b9733e78 feat(gui+search): Inhaltssuche mit Zeitstempel-Verweis, Papierkorb (30 Tage), Titel umbenennen
Drei vom Nutzer angeforderte Funktionen.

Titel umbenennen: PATCH /api/recordings/:id/title. Neue Spalte recordings.title_locked,
damit eine spaetere KI-Analyse einen von Hand gesetzten Titel nicht wieder ueberschreibt.

Papierkorb: DELETE setzt nur noch deleted_at, nichts wird angefasst. Wiederherstellen,
endgueltig loeschen, Aufraeumlauf beim Boot und taeglich (Boot-Lauf, weil das Board oft
tagelang aus ist). Behebt nebenbei einen Altfehler: das bisherige Loeschen liess die
words-Zeilen verwaist in der DB und die WAV/MP3-Dateien auf der Karte zurueck.

Inhaltssuche: neue Tabelle passages (1689 Zeilen aus 22 Aufnahmen) mit Sprecher und
Zeitfenster je Passage. Trefferliste kommt aus SQL in Millisekunden, die formulierte
Antwort mit Belegen [1][2] wird nachgereicht (Qwen3-4B, ~140 s) - deshalb zweistufig.
Hybrid: MariaDB FULLTEXT + Passage-Embedding + Dokument-Embedding aus Titel/Zusammenfassung
(multilingual-e5-small, ONNX/CPU, taskset A55). Ohne Modell degradiert die Suche sauber
auf Volltext statt auszufallen.

Gemessene Grenzen sind dokumentiert statt geschoent: e5-small trennt auf verrauschtem
ASR-Text schwach (Kosinus-Spanne aller Passagen nur 0,8085-0,8560; eine irrelevante
Passage schlug die richtige Antwort). Dokument-Ebene und IDF-Wertung heben die richtige
Passage auf Rang 11 von 296, aber nicht in die Top-8, die das LLM liest. Naechster Hebel
waere multilingual-e5-base.

Relative Datumsangaben werden deterministisch aufgeloest, nicht vom LLM - ein falsches
Kalenderfenster waere schlimmer als gar keins.

Neu: app/search.js, app/emb.js, app/inference/embed_text.py, docs/09-suche-und-verwaltung.md
Board-Backups: .bak-search
2026-07-31 13:20:20 +00:00
schakal00783 c09827bf86 fix(iphone-bt): v3 — pw-link -l filtert nicht, v2 machte den Uplink stumm
Testanruf 13:51 loggte nur "-callrec_mix", kein +micgate und kein +far-end: v2 hat
WirePlumbers Link getrennt und dann nichts verlinkt, der Uplink hatte keine Quelle
und die Gegenseite hörte Stille.

Ursache: `pw-link -l <node>` filtert nicht. Mit einem Node-Namen, der nicht als
Port auflösbar ist, kommt der ganze Graph zurück — und der enthält immer
micgate.out und callmix. Also war jedes "ist das schon verlinkt?"-grep wahr und nur
das Trennen lief. Derselbe Ausdruck stand schon in v1, dort aber hinter dem
Einmal-Guard, der nie erreicht wurde.

v3:
- links_of PORT parst die Peers eines exakten Ports aus einem Graph-Dump (awk),
  kein grep mehr über die gesamte Ausgabe.
- Erst verlinken, dann trennen: callrec_mix->Uplink fliegt nur raus, wenn
  micgate.out am Uplink-Port bestätigt anliegt. Sonst bleibt der WirePlumber-Link
  und es wird !no-micgate-uplink-keeping-callrec_mix geloggt. Ein Echo ist
  schlecht, unhörbar sein ist schlimmer.
- Log-Zustand als Array statt String: " " hätte -n passiert und bei fertig
  geroutetem Anruf jede Sekunde eine Journal-Zeile geschrieben.

Getestet: links_of gegen den echten Graph (verlinkt/unverlinkt/nicht existent);
Entscheidungslogik gegen einen synthetischen Mono-HFP-Graph — Default-Zustand,
fertig geroutet (No-op), micgate nicht bestätigt (behält callrec_mix).

Gegenprobe am echten Anruf steht noch aus.
2026-07-30 15:58:07 +02:00
schakal00783 e1c81bea9a fix(iphone-bt): iPhone-Route-Watcher greift wieder — Gegenseite fehlte in Aufnahme
aime-iphone-route.sh v1 hat seit dem Reboot am 29.07. nie gegriffen (0 Zeilen in
journalctl -t aime-iphone-route über den ganzen Boot). Zwei Gründe:

1. Die Portnamen waren hartcodiert auf input_FL/input_FR. HFP/mSBC ist mono, die
   Ports heißen playback_MONO/capture_MONO — der grep matchte nie.
2. Der Guard "micgate.out schon verlinkt -> überspringen" war einmal pro Anruf.
   WirePlumber legt die HFP-Nodes nicht atomar an, der Uplink erscheint vor der
   Gegenseite. War bluez_input in genau diesem Durchlauf noch nicht da, wurde die
   Gegenseite für den ganzen Anruf nicht mehr nachverlinkt. Ein erst mitten im
   Anruf gesetztes callrec_mix->Uplink wurde ebenso nie entfernt.

Folge: Gegenseite -> callmix fehlte (nicht in der Aufnahme, #80/#81 hatten je nur
1 Sprecher) und der Uplink führte den ungegateten Mix statt micgate.out, also
wieder das Echo von vor dem Fix am 13.07.

v2 ermittelt die Portnamen über pw-link -i/-o und prüft alle drei Links in jedem
Durchlauf einzeln nach. link_all legt genau einen Link pro Ziel-Port an: eine
Mono-Quelle speist beide Kanäle, eine Stereo-Quelle auf einem Mono-HFP-Port sendet
nur FL, weil beide Links in denselben Port summieren würden (+6 dB Uplink).

Gegenprobe am echten Anruf steht noch aus.
2026-07-30 15:48:59 +02:00
Sascha 810cee1dba Diarisierung: Marker-Zwangsbedingungen absichern, Voiceprints als cannot-link; LLM: Sektions-Pfad ab 9k Zeichen
#79 verlor einen von vier Sprechern und lieferte eine 1082-Zeichen-Zusammenfassung.

Diarisierung: ein zweiter, falsch verankerter Marker verschmolz Saschas Cluster
in Merles (Kosinus -0,727). must-link prueft jetzt die akustische Aehnlichkeit,
Anker werden nach Trefferqualitaet gewichtet, und enrolled Stimmen wirken als
cannot-link -- damit ist der Box-Besitzer immer ein eigener Sprecher.

LLM: der Whole-Pass komprimierte das erste Thema weg. Sektions-Pfad jetzt ab
9000 Zeichen, kleinere Chunks, woertlicher Kontext aus dem Vorgaenger-Chunk und
ein gezielter Pruef-Aufruf gegen ueberdehnte Einzelaussagen.

#79: 4 Sprecher, Zusammenfassung ~5300 Zeichen, 7 Themenbloecke.
Regression: #70 -> 4, #68 -> 2, #74 -> 20 Sprecher unveraendert.
2026-07-29 16:09:30 +02:00
Claude c76f26abaf GUI: alle Tabs nutzen volle Fensterbreite (kein .wide-Sonderfall mehr) 2026-07-28 00:05:07 +02:00
Claude 5044e27f7c Zusammenfassung: keine '(Namen: ...)'-Zeile mehr unter jedem Absatz
Extraktion bleibt als Arbeitsdatum fuer den Rolling Context zwischen den Chunks.
Bestehende Summaries bereinigt (#74 7503 -> 7203 Zeichen).
2026-07-27 23:57:19 +02:00
Claude 448e2b0726 Namen nachtraeglich in fertige Zusammenfassung uebernehmen
speaker_labels speichert das Label jedes Clusters im LLM-Text; relabelAnalysis()
ersetzt beim Umbenennen wortgenau in summary/todos/transcript_clean und baut die
Teilnehmerliste neu. #74: keine 'Sprecher N' mehr.
2026-07-27 23:52:28 +02:00
Claude 61531fc50a Fix: Voice-Auto-Naming tot (TitaNet bricht bei langen Schnitten ab + vergiftete Promise-Kette)
identifySpeakers() embettete den laengsten Lauf ungekuerzt; TitaNet-ONNX bricht
ab 180 s ab (broadcast 12288 by 17998) und riss den spk_embed-Helfer mit. Da
spk.js die Aufrufe ueber eine Promise-Kette serialisiert, schlugen danach ALLE
weiteren Sprecher mit 'spk beendet' fehl.

- ID_CUT_SEC=25s in identifySpeakers
- Kette in spk.js und tdChain in recorder.js failure-isoliert
- pro Name gewinnt nur der beste Kosinus (Fabio war auf 2 Clustern)
2026-07-27 17:30:43 +02:00
Claude 48fa6b4f9e Diarization v2: Fenster-Clustering mit gelernter Schwelle + Live-Namensmarker
#74 (22 Teilnehmer) ergab automatisch 44 Sprecher, dieselbe Stimme mehrfach.
Ursache gemessen: ein Zentroid pro sherpa-Cluster aus max. 3 Schnitten, fester
Kosinus auf rohen Embeddings (Kreuz-Turn-Kosinus ~0,4 = keine Trennschaerfe).

v2: sherpa liefert nur Turn-Grenzen, Identitaet aus 3-s-Fenster-Embeddings,
Mittelwert-Zentrierung, Average-Linkage-AHC, Weak-Fold, Schwelle pro Aufnahme
per 2-Gauss-EM gelernt. Validiert: #74 44->20, #70 ->4, #68 ->2.

Live-Namensmarker: Namen waehrend der Aufnahme tippen; Zeitstempel benennt
spaeter den Cluster und dient als must-/cannot-link-Zwangsbedingung.
2026-07-27 17:00:45 +02:00
schakal00783andClaude Fable 5 432c4b14dd LLM: Sektions-Pfad ab 5 Sprechern gegen Recency-Bias in Meetings
Whole-Pass versagte auf #74 (13-Sprecher-Weekly, 31k Zeichen): Summary
enthielt fast nur die letzten Sprecher. analyze() routet labeled
Transkripte mit >=5 Sprechern jetzt in analyzeLong; Sektions-Pfad
liefert Themen-Überschriften, jede Person, Smalltalk-Dämpfung, Todos
mit Verantwortlichem, Überblick-Mikro-Call, Cap 16000. Kap. 05 +
Changelog aktualisiert.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 16:03:18 +02:00
schakal00783andClaude Fable 5 b33b555fa7 GUI: Record-Button in Kopfzeile (Aufnahme-Tab entfernt) + Live-Karte; lame-Stille-Fix
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 02:18:39 +02:00
schakal00783andClaude Fable 5 aef50dda64 GUI: Scrollbalken im Akzent-Kupfer (scrollbar-color + webkit)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 02:04:08 +02:00
schakal00783andClaude Fable 5 2c9015dd7c GUI: Splitter zwischen Liste und Detail (340-680px, persistent)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 02:00:03 +02:00
schakal00783andClaude Fable 5 f7c50b2b6b GUI: Kupfer-Tageszaehler, Wellenform-Favicon, Tab-Reihenfolge (BT ans Ende)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 01:54:43 +02:00
schakal00783andClaude Fable 5 46f8327832 GUI: Aufnahmen-Liste startet mit nur dem neuesten Tag geoeffnet
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 01:49:27 +02:00
schakal00783andClaude Fable 5 d55442a41f GUI: alle Module inkl. Transkript-Panel spaltenuebergreifend verschiebbar
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 01:44:36 +02:00
schakal00783andClaude Fable 5 40602779ce GUI: Sprecher-Modul entfernt; Umbenennen/Lernen via Popover am Spur-Label
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 01:36:03 +02:00
schakal00783andClaude Fable 5 6a51699e90 GUI: Blasen-Oeffnung positionsgenau zum Sprecher (--ax aus Sitzposition)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 01:26:57 +02:00
schakal00783andClaude Fable 5 55f03e7389 GUI: Tisch-Blase fix, Oeffnung wandert zum Sprecher
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 01:21:16 +02:00
schakal00783andClaude Fable 5 1975bfe696 GUI: Sprechblase am Sprecher, Wort-Highlight + internes Mitscrollen + Klick-Seek
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 01:17:52 +02:00
schakal00783andClaude Fable 5 7586a707ca GUI: Konferenztisch-Ansicht als Alternative zum Transkript
Umschalter (3-Personen-Icon <-> Textblatt); Figuren in Sprecherfarben um
abgerundeten Tisch, Sprechblase mit Live-Text zeigt zum Sprecher, alle
anderen schauen hin, Mund animiert. Sitzlayouts 1-6, localStorage-persistent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 01:10:00 +02:00
schakal00783andClaude Fable 5 35b4999b6c GUI: Aufnahmen-Tab nutzt volle Fensterbreite (1180px-Deckel entfernt)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 01:01:19 +02:00
schakal00783andClaude Fable 5 60fdff460a GUI: Live-Text-Box neben den Spuren entfernt (redundant zum Transkript)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 00:58:09 +02:00
schakal00783andClaude Fable 5 d9ae8f819b GUI: Sprecher-Verlauf als Vollbreiten-Streifen unter dem Player
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 00:55:15 +02:00
schakal00783 795892cb9f Changelog: Bundle-Name nachgetragen 2026-07-17 00:51:33 +02:00
schakal00783andClaude Fable 5 62e1dec960 GUI: Transkript als eigene sticky Scroll-Spalte rechts
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 00:51:04 +02:00
schakal00783andClaude Fable 5 4500e03ae4 GUI: Sprecher-Verlauf (farbige Spuren + Playhead + Live-Text) und Drag&Drop-Module
Detail-Ansicht modular: Zusammenfassung/Verlauf/ToDos/Sprecher/Transkript
per Grip umsortierbar (localStorage). Verlauf: Spur je Sprecher, Klick=Seek,
aktive Spur pulsiert, Live-Box zeigt aktuellen Redebeitrag.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 00:46:27 +02:00
schakal00783andClaude Fable 5 63c7d30b5e GUI: Weggezogen-Bug (stale detail poll) gefixt + Redesign mit Dark/Light-Switch
- Detail-Poll bricht bei Auswahlwechsel ab, pollt nur Status, EIN Rebuild
  bei Fertigstellung mit Player-Restore
- Themes via CSS-Variablen (data-theme, localStorage, OS-Default),
  Kupfer-Akzent, Wellenform-Wortmarke, Pill-Tabs, focus-visible,
  prefers-reduced-motion

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 00:34:23 +02:00
schakal00783andClaude Fable 5 7391b0ded7 Mikro->Mix gegatet: Doppelweg-Hall der Gegenseite beseitigt
Cepstral-Beweis auf #71: stabiler 80ms-Peak nur auf Gegenseiten-Segmenten
= Muschel-Bleed durchs offene Mikro zusaetzlich zum digitalen Pfad.
cr_mic2mix-Loopback entfernt, stattdessen pw-link micgate.out -> callmix
(Fallback ohne Gate bleibt). Verschmierte Embeddings (verschmolzene
Remote-Sprecher) sollten damit ebenfalls weg sein - echter Call offen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-17 00:11:58 +02:00
schakal00783andClaude Fable 5 1016eaa095 Glossar: Eintraege bearbeitbar (PUT /api/glossary/:id + GUI-Editier-Flow)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-16 23:55:27 +02:00
schakal00783andClaude Fable 5 fdae4ce119 rkllm vor Diar/Identify freigeben — TitaNet-OOM neben residentem LLM
llm.stopServer() am Anfang von rediarize() und analyzeRecording():
spk-embed starb sonst OOM (48 Roh-Sprecher auf #71). E2E #71: 48->2
Sprecher + saubere Whole-Pass-Summary. Offen: identify-spk-Fehler
auch mit freiem RAM (Voice-Auto-Naming tot).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-16 23:04:57 +02:00
schakal00783andClaude Fable 5 a6e02aea44 LLM -> Qwen3-4B-Instruct-2507 (A/B-Sieger, Whole-Pass bis 32k)
- Selbst konvertiert (w8a8_g128, ctx 16384, RTX 3090 ~35 min, Kit wiederverwendet)
- A/B vs Gemma: 3/3 Prompts besser; 21.8k-Whole-Pass fehlerfrei gewichtet,
  wo Gemma englisch abdriftete bzw. nur das Ende zusammenfasste
- rkllm_server.cpp: ChatML-Template; llm.js: WHOLE_MAX_CHARS 32000,
  READY-Timeout 60s->180s (Qwen3 laedt ~96s)
- E2E validiert: #70 Whole-Pass 15.4 min, #68 Kurzclip sauber
- Rollback: .bak-gemmatmpl + Drop-in auf gemma3-Modell

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-16 20:41:08 +02:00
schakal00783andClaude Fable 5 2b63a6b02f Changelog: A/B Qwen2.5-3B vs Gemma-3-4B im Chunk-Pfad — Gemma bleibt
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-16 17:59:22 +02:00
schakal00783andClaude Fable 5 8cfdcf5d56 Sektions-Konglomerat statt LLM-Reduce fuer Lang-Transkripte
- llm.js analyzeLong neu: 4.2k-Chunks (8k = namenloser Brei), Rolling Context,
  eigennamen-Extraktion, Echo-Guard mit Prompt-Variation (3 Versuche),
  Feld-Salvage, Titel-Mikro-Call ohne letzten Abschnitt, Konglomerat in Code
- LLM-Reduce entfernt: Cross-Section-Synthese nachweislich jenseits Gemma-3-4B
- server.js: Prompt-Lab-Endpoint nach Abschluss wieder entfernt
- Doku Kap. 05 (Mermaid, Marotten) + Changelog

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-16 17:47:14 +02:00
schakal00783andClaude Fable 5 2f00ddeec6 #70-Debug: Diar Weak-Fold (7->4 Sprecher), LLM-Robustheit + Whole-Pass-Modellgrenze, Thermal-Cap fuer analyzeRecording
- diar.js: Stufe-3 Weak-Fold (DIAR_MIN_TOTAL_SEC 20s) gegen Phantom-Sprecher
- llm.js: End-Instruktion, JSON-Repair, Sanity+Fallback, Chunk-Retry, Quote-Sanitizer, gelabelter/gewichteter Reduce; WHOLE_MAX 20000 (Gemma-4B-Grenze)
- rkllm_server.cpp: max_context_len 8192->12288
- server.js: analyzeRecording unter A76-Takt-Cap (95-97 Grad ungedeckelt)
- Doku Kap. 03/04/05 + Changelog

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
2026-07-16 14:37:07 +02:00
Claude f9e1eb82c4 feat: komplette Codebase vom Board ins Repo gespiegelt
app/ = /opt/callrec (Node-Backend, Vite-Frontend, Python-Inferenz,
Audio-Skripte, rkllm_server.cpp), system/ = systemd-Units,
WirePlumber/PipeWire-Drop-ins, sudoers. Modelle, Binaries, Aufnahmen
und node_modules bleiben draussen (.gitignore).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 11:18:29 +02:00
Claude 560622e125 docs: Repo-Name im Changelog auf sascha/Aime korrigiert
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 10:59:47 +02:00
Claude 0a9a9a64fa docs: Projekt in Aime umbenannt (vormals CallRec)
GUI-Titel/Header auf dem Board ebenfalls umgestellt; technische
Bezeichner (callrec.service, /opt/callrec, DB, CallRecMix) bleiben.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 10:55:44 +02:00
Claude db3d946592 docs: komplette CallRec-Dokumentation mit Mermaid-Diagrammen
Architektur, Hardware/Thermik, PipeWire-Audio-Topologie, Aufnahme-Pipeline,
Diarization (Anchor-Merge), LLM-Analyse (Gemma-3-4B/NPU), iPhone-BT-HFP,
Betrieb/Troubleshooting und Changelog-Chronik.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 10:51:22 +02:00