From e7112e1ab61b1ca2a412c43eefdf1f40a4fef5cb Mon Sep 17 00:00:00 2001 From: Axel Hocks Date: Fri, 7 Aug 2026 07:27:37 +0200 Subject: [PATCH] JS-Syntaxpruefung: node --check als Stufe B in check_nfalle CLAUDE.md behauptete "kein node im Env" - das stimmte nicht mehr, Node v24.18.0 ist installiert. Die Zeile hat die Frage jahrelang falsch beantwortet. Gemessen an 5 realistischen Fehlern findet die alte Klammern-Balance 1, node --check findet 5 (86 ms): Klammer zu viel Balance ok node ok const x = ; Balance blind let doppelt Balance blind const doppelt Balance blind return ausserhalb Fkt. Balance blind Ein Syntaxfehler in app.js bricht den GESAMTEN Render - das Dashboard friert auf Altwerten ein. Bei 95 direkt dereferenzierten $("id")-Zugriffen (0 davon mit ?.) ist das kein theoretisches Risiko. Geprueft wird als MODUL (.mjs), nicht als CommonJS: als CJS haelt Node ein top-level return fuer legal, der Browser laedt app.js aber als klassisches Script, wo es ein Syntaxfehler ist. Verifiziert, dass das echte app.js den strengeren Modus ohne Anpassung besteht. Kein npm, keine package.json, kein node_modules - node --check ist die Laufzeit selbst. Damit entsteht NICHT die Divergenz "Pruefumgebung ist nicht die Laufumgebung" (der .ps1-BOM-Fehler, das pre-commit-Framework): Node und Chrome benutzen denselben Parser (V8). Drei Richtungen verifiziert: sauber -> gruen mit eingebautem Fehler-> Exit 1, Commit gestoppt ohne node im PATH -> Rueckfall auf alte Pruefung, Exit 0 Co-Authored-By: Claude Opus 5 --- CLAUDE.md | 24 ++++++++++++++-- tools/check_nfalle.py | 65 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 83 insertions(+), 6 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index d3710b3..3de7966 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -257,8 +257,28 @@ dort bereits nachvalidiert, ØR +0,305.) **Eine** Oberfläche: (WR/PF/Verhältnis/Worst je KW, Ausrichtungs-Split mit/gegen/ohne) gegen die Backtest-Erwartung (WR~68 % · PF~1,3 · Verh~0,55) und flaggt Leckagen (Gegen-Signal- Anteil, WR-Verfall, PF<1, Einzelverlust). **Wöchentlich** laufen lassen (B4/B5). -- **Vor „fertig":** immer `python -m py_compile `; JS grob via Klammern- - Balance prüfen (kein node im Env). +- **Vor „fertig":** immer `python -m py_compile `; JS via **`node --check`** + (Stufe B in `tools/check_nfalle.py`, läuft im pre-commit-Hook mit). + ⚠⚠ **KORREKTUR 2026-08-07: „kein node im Env" stimmte nicht mehr** — Node + **v24.18.0** ist installiert. Die Zeile hat die Frage „können wir Node nutzen?" + jahrelang falsch beantwortet. + **Gemessen, warum das zählt:** die alte Klammern-Balance findet **1 von 5** + realistischen Fehlern — `const x = ;`, doppeltes `let`/`const` und `return` + ausserhalb einer Funktion laufen glatt durch; `node --check` findet **5 von 5** + in **86 ms**. Ein Syntaxfehler in `app.js` bricht den **GESAMTEN** Render + (Dashboard friert auf Altwerten ein) — bei **95 direkt dereferenzierten** + `$("id")`-Zugriffen ist das kein theoretisches Risiko. + ⚠ **Geprüft wird als MODUL (`.mjs`), nicht als CommonJS:** als CJS hält Node ein + top-level `return` für legal, der Browser lädt `app.js` aber als klassisches + Script, wo es ein Syntaxfehler ist. Verifiziert, dass das echte `app.js` den + strengeren Modus **ohne Anpassung** besteht. + ⚠ **Kein npm, keine `package.json`, kein `node_modules`** — `node --check` ist + die Laufzeit selbst. Damit entsteht NICHT die Divergenz „Prüfumgebung ≠ + Laufumgebung" (die beim `.ps1`-BOM und beim `pre-commit`-Framework das Problem + war): Node und Chrome benutzen **denselben Parser (V8)**. + ✅ **Drei Richtungen verifiziert:** sauber → grün · mit eingebautem Fehler → + **Exit 1**, Commit gestoppt · **ohne Node im PATH** → Rückfall auf die alte + Prüfung, Exit 0 (eine frische Maschine darf am Hook nicht hängenbleiben). - **✅ BOOT-LÜCKE GESCHLOSSEN: Auto-Logon AKTIV (2026-08-07).** `OilTradingServer` und `HyperliquidDashboard` hängen an einem **Logon**-Trigger — nach einem Update-Reboot läuft nichts bis zur Anmeldung (real 20.07.: diff --git a/tools/check_nfalle.py b/tools/check_nfalle.py index 8c91fce..67b0941 100644 --- a/tools/check_nfalle.py +++ b/tools/check_nfalle.py @@ -190,18 +190,75 @@ def js_offene_strings(text: str): print() print("=" * 88) -print(" B) JAVASCRIPT — unabgeschlossene String-Literale") +print(" B) JAVASCRIPT — Syntax (node) + unabgeschlossene String-Literale") print("=" * 88) + + +def node_pruefen(p: pathlib.Path): + """Echte Syntaxpruefung mit `node --check`. Gibt die Fehlerzeile zurueck oder + None; `False` heisst „Node nicht verfuegbar". + + ⚠ WARUM DAS DAZUKAM (2026-08-07). Die Klammern-Balance findet gemessen nur + 1 von 5 realistischen Fehlern — `const x = ;`, ein doppeltes `let`/`const` + und ein `return` ausserhalb einer Funktion laufen glatt durch. Ein + Syntaxfehler in `app.js` bricht aber den GESAMTEN Render: das Dashboard + friert auf Altwerten ein. Bei 95 direkten Element-Zugriffen ist das kein + theoretisches Risiko. + + ⚠ GEPRUEFT WIRD ALS MODUL (.mjs), NICHT ALS CommonJS. Als CJS haelt Node ein + top-level `return` fuer legal — der Browser laedt `app.js` aber als + klassisches Script, wo es ein Syntaxfehler ist. Der Modul-Modus liegt naeher + am Browser; verifiziert, dass das echte `app.js` ihn ohne Anpassung besteht. + + ⚠ Kein npm, keine package.json, kein node_modules — `node --check` ist die + Laufzeit selbst. Damit entsteht NICHT die Divergenz „Pruefumgebung ist nicht + die Laufumgebung", an der dieses Projekt schon zweimal aufgelaufen ist: + Node und Chrome benutzen denselben Parser (V8). + + ⚠ Fehlt Node, faellt die Stufe still auf die alte Prueflogik zurueck — eine + frische Maschine soll den Hook nicht blockieren. + """ + try: + with tempfile.NamedTemporaryFile("w", suffix=".mjs", delete=False, + encoding="utf-8") as f: + f.write(p.read_text(encoding="utf-8", errors="replace")) + tmp = f.name + try: + r = subprocess.run(["node", "--check", tmp], + capture_output=True, text=True, timeout=60) + finally: + try: + pathlib.Path(tmp).unlink() + except OSError: + pass + except (FileNotFoundError, OSError, subprocess.TimeoutExpired): + return False + if r.returncode == 0: + return None + for z in (r.stderr or "").splitlines(): + if "Error" in z: + return z.strip() + return "node --check meldet einen Fehler" + + for p in dateien(".js"): if "lightweight-charts" in p.name: continue + rel = p.relative_to(WURZEL) + nd = node_pruefen(p) + if nd is False: + print(f" ⚠ node fehlt — nur Ersatzpruefung fuer {rel}") + elif nd: + befunde.append(f"JS {rel} (node)") + print(f" FEHLER {rel} {nd}") + continue # bei kaputter Syntax ist die Zeilenheuristik sinnlos tr = js_offene_strings(p.read_text(encoding="utf-8", errors="replace")) if tr: for nr, z in tr: - befunde.append(f"JS {p.relative_to(WURZEL)}:{nr}") - print(f" FEHLER {p.relative_to(WURZEL)}:{nr} {z}") + befunde.append(f"JS {rel}:{nr}") + print(f" FEHLER {rel}:{nr} {z}") else: - print(f" OK {p.relative_to(WURZEL)}") + print(f" OK {rel}" + (" (node)" if nd is None else "")) # ── C) literales \n als TEXT ─────────────────────────────────────────────