# Architecture ## Why this fork exists [DanielCheer/obsidian-web-viewer](https://github.com/DanielCheer/obsidian-web-viewer) is a great single-file Obsidian-vault viewer (server.py + vault.html, ~10 KB + 14 KB, Python stdlib only). But for Lukas' Hermes Wiki workflow — 245 Markdown files across 18 top-level folders, frequent cross-referencing via WikiLinks, mobile reading — three specific UX gaps needed fixing: 1. **3D Graph shows all nodes uniformly** — no indication of which node the user is currently reading or which nodes are connected to it 2. **Layout breaks on small screens** — the 3-panel grid (`280px 1fr 260px`) is too narrow on 13" laptops and unusable on phones 3. **Click-to-navigate from graph** — Three.js canvas accepts clicks but doesn't trigger navigation ## Design principles ### 1. Additive layer, not fork-and-modify We modify **exactly one line** in `vault.html` (a `` tag before ``). Everything else — including the customizations themselves — lives in `vault-custom.js`. Why: - Upstream `git pull` conflicts are trivial to resolve (the one line is recognizable) - Customizations are clearly separated from upstream code - Reviewing customizations is reading one file, not diffing the whole repo - Easier to upstream-merge back if Lukas' features prove generally useful ### 2. HermesCustom namespace All custom code lives under `window.HermesCustom`. Methods are namespaced and self-documenting: ```js window.HermesCustom = window.HermesCustom || {}; HermesCustom.highlightCurrentNode = function() { ... }; HermesCustom.setupGraphClickHandler = function() { ... }; HermesCustom.responsiveLayout = function() { ... }; ``` This way the namespace is visible in DevTools and a future maintainer can see at a glance what's custom vs. upstream. ### 3. Server.py stays mostly upstream We add **one** enhancement to `server.py`: a `?file=` query parameter that returns the file directly (used by `HermesCustom.highlightCurrentNode` to know which file is open). This is a 5-line change that doesn't conflict with any upstream logic. If upstream adds a similar feature, we drop our addition. ## File map ``` hermes-wiki-viewer/ ├── server.py # obv-fork + 5 lines (file-query-param) ├── vault.html # obv-fork + 1 line (script tag for custom.js) ├── vault-custom.js # ALL Lukas-specific code ├── requirements.txt # PyYAML only (same as upstream) ├── README.md # this repo's entry point ├── LICENSE # MIT (inherited) ├── CHANGELOG.md # release notes for Lukas-additions ├── docs/ │ ├── ARCHITECTURE.md # you are here │ └── CUSTOMIZATIONS.md # spec for each Lukas-feature └── .gitignore # standard ``` ## Why we keep `vault-custom.js` separate from `vault.html` Embedding customizations into `vault.html` would mean: - Every upstream update requires re-applying the entire diff - Reviewing customizations requires diffing two HTML files - Conflicts when upstream renames a function we override A separate file means: - The customizations are a stable, reviewable unit - Upstream updates touch `vault.html` only, customizations are unchanged - The one-line patch in `vault.html` is a clear "anchor point" that any reviewer can understand ## Why Python stdlib only (no Flask/FastAPI) Upstream uses `http.server` from stdlib. We keep this. Adding a framework would: - Inflate dependencies - Require version-pinning for reproducibility - Make the tool harder to deploy (anywhere with Python 3.8+ works) The 5-line addition to `server.py` is plain stdlib `BaseHTTPRequestHandler` style. ## Tradeoffs we accepted - **No build step.** Customizations are vanilla JS. No bundler, no TypeScript. Means no static type-checking, but means anyone can read and modify the code without toolchain setup. - **No tests in CI.** We rely on manual testing for now. CI tests would add complexity that doesn't match the project's "simple tool" character. (Future: a small Playwright test for the graph highlighting.) - **No auto-update from upstream.** When obv updates, Lukas has to `git pull upstream && git merge`. The one-line `vault.html` patch needs re-application if upstream modified it. This is acceptable for a personal side-project. ## Roadmap See CHANGELOG.md for planned additions. Current priorities: 1. ✅ Current-page highlighting in 3D Graph 2. ✅ Click-to-navigate on graph 3. ✅ Responsive layout (1024px and 768px breakpoints) 4. ⏳ Backlinks panel (per-page incoming WikiLinks) 5. ⏳ Keyboard shortcuts (j/k for next/prev file, [/] for nav, g/G for graph focus) 6. ⏳ Light theme variant (currently Catppuccin-dark only)