Diagnose: Lukas' Browser-Logs zeigen Service-Worker-Activity
(sw.js?v=2026.5.18-...) und alle Wiki-Assets werden via SW geladen.
Wiki selbst registriert keinen SW, der SW kommt von woanders.
Echter Fix: preventDefault() in onDown() entfernt. Auf iOS Safari
verliert das Event-System die nachfolgenden Pointer-Move-Events wenn
preventDefault() auf pointerdown gefeuert wird — das Event wird quasi
'konsumiert' bevor der Browser die Touch-Sequenz weiterverarbeitet.
Außerdem: touchstart ist jetzt passive: true (preventDefault dort war
illegal und hätte Synthetic-Click ausgelöst die das Modal geschlossen
hätte). touchmove und touchend bleiben passive: false damit preventDefault
dort funktioniert um Browser-Default-Scroll zu blocken.
Lukas' Browser-Console-Log zeigte dass alle Assets via Service-Worker
geladen wurden — das deutet auf aggressive Cache-Strategie hin, weshalb
ein Hard-Reload mit Cache-Buster URL empfehlenswert ist.
Diagnose: Mobile Graph sichtbar aber nicht bedienbar.
Root cause: iOS Safari interpretiert Single-Finger-Touch als Scroll-Geste
statt als Drag, weil touch-action: none fehlt.
Fixes:
1. CSS: touch-action: none auf .graph-modal-canvas, canvas und .graph-modal
(verhindert iOS-Safari Scroll-Hijacking + Rubber-Band-Effect)
2. JS: Touch-Event-Fallbacks (touchstart/move/end/cancel) parallel zu
pointer-events (für ältere iOS-Safari-Versionen die pointer-events
noch nicht voll unterstützen)
3. JS: Pinch-to-Zoom via Zwei-Finger-Gestenerkennung
4. JS: Initial-Render mit Resize-Retry bis Canvas echte Dimensionen hat
(Modal-Container kann initial 0x0 sein bevor Flex-Layout settled)
5. JS: ResizeObserver auf Canvas re-rendert bei Größenänderung
6. CSS: overscroll-behavior: contain auf Modal (kein Bounce)
7. CSS: -webkit-user-select: none + tap-highlight: transparent
(verhindert iOS-Safari Selektions-Overlay beim Drag)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Touch-First Design (style.css, 17 KB):
- Mobile-First CSS mit Safe-Area-Insets für iOS Dynamic Island
- Bottom-Nav (Files / Search / Graph) auf <768px
- Hamburger-Tree slidet von links rein mit Backdrop
- Graph-Modal als Full-Screen-Overlay mit Title-Bar + Close
- Tap-Targets ≥ 44px (--tap-min)
- Tablet-Mode (768-1023px): 2-Panel + Bottom-Graph 240px
- Desktop (≥1024px): 3-Panel mit Tree 280px / Graph 320px
- Touch-Action-Manipulation verhindert 300ms-Tap-Delay
- Word-wrap + overflow-wrap für Mobile-Content
- Frontmatter-Card als Grid-Layout
- TOC + Backlinks Styling
Touch-First JS (app.js, 21 KB):
- Tree-Render mit auf-/zuklappbaren Ordnern (auto-open concepts/entities)
- Search mit Live-Dropdown, Keyboard-Navigation (↑↓ Enter Esc)
- 3D Graph in Three.js, KEIN Auto-Rotation, drag-to-rotate + wheel-zoom
- Click-zentriert: Click auf Node → navigiert zur Page
- Modal-Close via X-Button oder Escape
- Touch/Click-Handler: pointerdown/move/up + Raycaster
- Backlinks-Section aus data.backlinks
- TOC aus h2/h3-Headings der aktuellen Page
- Hash-anchor highlighting via :target CSS
Template-Patch (generator.py):
- Search-Wrap-Container für absolute Dropdown-Position
- Bottom-Nav mit inner-Flex
- Graph-Modal-Container
- Three.js-CDN-Script im HEAD
Assets werden jetzt aus dem Repo kopiert (style.css, app.js, manifest.json)
statt eingebettete Placeholder-Strings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaces obv-Fork. New architecture:
- Python watchdog observes /home/admin/my-karpathy-wiki/
- On .md change → regenerate single HTML + update index
- On startup → full regen + tree.json/graph.json/tags.json/backlinks.json
- HTTP server on 127.0.0.1:8765 + tailscale proxy
- 265 static HTML pages with full Markdown rendering
- WikiLink resolution: [[entity]] → <a href='/path/entity.html'>
- Frontmatter as styled card (type, status, updated, sources)
- TOC auto-generated via markdown.extensions.toc
- PWA manifest for native-feeling install
- data.js with all metadata for offline use
Touch-first design (CSS+JS for tree/graph/search) follows in Phase 2.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Drei Probleme, drei Fixes:
1. Touch-Drag auf Graph geht nicht:
obv's mousedown/mousemove/mouseup sind Mausevents only.
Fix: zusätzlich touchstart/touchmove/touchend/touchcancel
+ getPos() Helper der touches[0] oder clientX nutzt
+ preventDefault() auf Drag (sonst versucht iOS zu scrollen)
2. Suche und Content-Scroll blockiert:
obv's animateGraph() läuft mit requestAnimationFrame endlos
und blockt den Main-Thread auf iOS. Plus iOS-300ms-Tap-Delay
auf inline onclick=.
Fix:
- document.hidden check (skip rendering wenn Tab im Hintergrund)
- autoRotate pausiert 3s nach User-Interaktion
- html, body { touch-action: manipulation } (entfernt 300ms delay)
- -webkit-tap-highlight-color: transparent (entfernt blauen Flash)
- .vault-content, .vault-sidebar { touch-action: pan-y, -webkit-overflow-scrolling: touch }
- .vault-graph canvas { touch-action: none } (damit Browser-Default Three.js-Drag nicht blockt)
Nicht angefasst: obv's Inline-onclick-Handler (Suche-Eingabe, File-Click,
WikiLinks) — diese funktionieren sobald der 300ms-Tap-Delay weg ist
und der Main-Thread nicht mehr blockt.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Vier Customization-Iterationen (v0.2 bis v0.5.1) haben auf Mobile (iOS Safari)
und Chrome Desktop jeweils neue Probleme verursacht statt sie zu lösen.
Rollback entfernt:
- vault.html: Script-Tag für vault-custom.js entfernt (upstream-original)
- server.py: ?file= query-Patch entfernt (upstream-original)
- vault-custom.js: leerer Stub mit Comment (Customizations deaktiviert)
- hermes-custom.css: leerer Stub (CSS deaktiviert)
Was bleibt:
- Repo-Struktur (README, CHANGELOG, ARCHITECTURE, CUSTOMIZATIONS, scripts/)
- Documented history der Customization-Iterationen für späteres Re-Audit
- Backup-Dateien: *.lukas (alle Original-Patches vor diesem Commit)
Begründung: Lukas braucht ein verlässlich funktionierendes Wiki, nicht
endlose Problemlösungs-Schleifen. Basis muss stimmen, bevor neue Features
ausprobiert werden.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problem: Buttons waren auf iOS hinter der Titelleiste / Dynamic Island
versteckt, weil .vault-app die iOS Safe-Area nicht respektiert hat.
Fixes:
1. viewport-fit=cover im Meta-Tag (sicherstellt dass env() berechnet wird)
2. :root CSS-Variablen für Safe-Area-Inset (top/right/bottom/left)
3. .vault-app.hermes-rc bekommt padding-top/bottom/left/right = var(--sat) etc.
-> Header-Bar und damit alle Buttons werden unter die iOS-Statusleiste geschoben
4. height: 100dvh mit 100vh fallback (iOS Safari Bug: 100vh enthaelt URL-Bar)
Plus: body margin/padding = 0 (war ein Bug, dass Browser-Defaults reinfunkten)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Drei Probleme mit v0.4 Mobile-Layout:
1. 140px Bottom-Panel frisst vertikalen Platz auf Phone
2. User muss zur 3D-Graph scrollen, die nicht interaktiv nutzbar ist
3. Resize zwischen Mobile/Tablet/Desktop an fixen Breakpoints ist holprig
Fix v0.5: Graph wird als Full-Screen-Modal über Toggle-Button gezeigt.
Neues Layout-System:
- Desktop >=1025px: obv default 3-panel, keine Toggles sichtbar
- Compact 601-1024px: 2-panel (Tree + Content), Graph als Toggle-Modal,
Toggle-Buttons für Tree UND Graph sichtbar im Header
- Mobile <=600px: 1-panel (nur Content), Tree als Hamburger (auto-hide
nach File-Selection), Graph als Toggle-Modal
Plus Mobile-Overflow-Fix:
- word-wrap + overflow-wrap auf Markdown-Content
- pre/code: white-space: pre-wrap + word-break: break-word
- table: display:block + overflow-x: auto
- img: max-width: 100%
Graph-Modal:
- Full-Screen overlay mit Backdrop
- Title-Bar + Close-Button (×)
- Three.js re-rendered in modal-canvas (für isolierte Performance)
- Click-to-Navigate vom Modal zurück in die Page
- ESC-Taste schließt Modal
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Drei Probleme mit der JS-Injection:
1. CSS kommt NACH First Paint → User sieht kurze obv-Layout, dann 'springt'
zu responsive Layout (FOUC = Flash of Unstyled Content)
2. JS-Injection kann fehlschlagen (head nicht ready, Browser-Inkonsistenzen)
3. Inline <style>-Tag wird nicht gecacht, lädt bei jedem Reload
Fix: hermes-custom.css als separate Datei, geladen via
<link rel='stylesheet'> im HEAD. Server liefert sie automatisch.
Außerdem: Mobile-Mode zeigt Graph als Bottom-Panel (140px), nicht mehr
display:none. User behält Wiki-Beziehungen auch auf Phone.
vault-custom.js.js behält injectResponsiveCSS als no-op für Backward-Compat.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Drei Bugs gefixt die Responsive-Layout kaputt machten:
1. Script-Tag war NACH </body> platziert (HTML-invalid)
Fix: Script-Tag ist jetzt VOR </body> im vault.html-Patch
2. CSS-Spezifität zu niedrig (nur .vault-app statt .vault-app.hermes-rc)
Fix: 2-Klassen-Selektoren .vault-app.hermes-rc.X schlagen obv's
Single-Class-Selektoren
3. Mobile-Overflow nicht kontrolliert
Fix: overflow-x: hidden auf .vault-app + .vault-content,
word-wrap + overflow-wrap für lange URLs/Codes
Außerdem:
- Init mit 50ms-Delay nach DOMContentLoaded (gibt obv Zeit für Setup)
- Hamburger-Toggle mit e.stopPropagation()
- Tablet-Graph als Bottom-Panel (220px) mit border-top statt border-left
- Mobile-Graph komplett hidden (war: nur klein)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Wiki-Serve-Skript war bisher in ~/.local/bin/, jetzt auch im Repo versioniert,
damit Updates via git pull verfügbar sind.
CHANGELOG korrigiert: server.py jetzt +12 Zeilen statt +7 (Bug-Fix für trailing
'/' ist mit drin).
Bug: obv's do_GET strippt trailing '/' via path.rstrip('/'), sodass
startswith('/api/vault/file/') nie triggert für /api/vault/file/. HermesCustom
kann daher ?file= nicht nutzen.
Fix: explizit beide Pfade matchen (mit und ohne trailing '/').
Außerdem: Wiki-Serve-Skript zeigt jetzt standardmäßig auf ~/repos/hermes-wiki-viewer
statt auf ~/.local/share/hermes-wiki/owv, sodass Lukas-Customizations automatisch
aktiv sind nach Skript-Update.
Fork of DanielCheer/obsidian-web-viewer (MIT, 2026-04) with Lukas' first
additions for the Hermes Wiki workflow.
Additive customization layer (vault-custom.js) — keeps upstream-merge
trivial via a one-line script tag in vault.html.
Features added:
1. Current-page highlighting in 3D Graph — current node gold+glow,
connected nodes light-blue, others dim to 20% opacity
2. Click-to-navigate on graph — Three.js raycaster triggers file load
3. Responsive layout — graph collapses below 1024px, tree below 768px
4. URL-based deep-linking via ?file=<path> query param
5. Server-side ?file= support in /api/vault/file/ endpoint
Modified files:
- server.py: +7 lines (Lukas-add: ?file= query param parsing)
- vault.html: +1 line (script tag for vault-custom.js)
New files:
- vault-custom.js: 11KB, all customizations in one place under HermesCustom namespace
- README.md: fork intro, quick start, customization guide
- CHANGELOG.md: Lukas-additions tracking
- docs/ARCHITECTURE.md: design rationale
- docs/CUSTOMIZATIONS.md: feature spec
- .gitignore: standard
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>