@hardikg/mdview 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +140 -0
- package/LICENSE +21 -0
- package/README.md +202 -0
- package/bin/mdview.mjs +1418 -0
- package/dist/client/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/client/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/client/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/client/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/client/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/client/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/client/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/client/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/client/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/client/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/client/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/client/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/client/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/client/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/client/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/client/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/client/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/client/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/client/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/client/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/client/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/client/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/client/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/client/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/client/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/client/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/client/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/client/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/client/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/client/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/client/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/client/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/client/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/client/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/client/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/client/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/client/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/client/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/client/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/client/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/client/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/client/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/client/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/client/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/client/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/client/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/client/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/client/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/client/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/client/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/client/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/client/assets/arc-DjKPIdc5.js +1 -0
- package/dist/client/assets/architectureDiagram-3BPJPVTR-_OLcSJC-.js +36 -0
- package/dist/client/assets/blockDiagram-GPEHLZMM-BxHKbhSj.js +132 -0
- package/dist/client/assets/c4Diagram-AAUBKEIU-DiBLe7ZZ.js +10 -0
- package/dist/client/assets/channel-oDRyuYVi.js +1 -0
- package/dist/client/assets/chunk-2J33WTMH-4B03UoyK.js +1 -0
- package/dist/client/assets/chunk-4BX2VUAB-Dw7jUHGw.js +1 -0
- package/dist/client/assets/chunk-55IACEB6-AZdo8c-x.js +1 -0
- package/dist/client/assets/chunk-727SXJPM-g0GurlcS.js +206 -0
- package/dist/client/assets/chunk-AQP2D5EJ-eqTzq7th.js +231 -0
- package/dist/client/assets/chunk-FMBD7UC4-D4omRKrC.js +15 -0
- package/dist/client/assets/chunk-ND2GUHAM-mVdFtWqM.js +1 -0
- package/dist/client/assets/chunk-QZHKN3VN-CyPMaN41.js +1 -0
- package/dist/client/assets/classDiagram-4FO5ZUOK-Dn5QR1VE.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Dn5QR1VE.js +1 -0
- package/dist/client/assets/cose-bilkent-S5V4N54A-BjlwoH6Y.js +1 -0
- package/dist/client/assets/cytoscape.esm-D_LviqZs.js +331 -0
- package/dist/client/assets/dagre-BM42HDAG-DBF5W9Tk.js +4 -0
- package/dist/client/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/dist/client/assets/diagram-2AECGRRQ-D9gwS4tw.js +43 -0
- package/dist/client/assets/diagram-5GNKFQAL-DTpIgGjI.js +10 -0
- package/dist/client/assets/diagram-KO2AKTUF-ByLH9Z83.js +3 -0
- package/dist/client/assets/diagram-LMA3HP47-Dkd4KfnW.js +24 -0
- package/dist/client/assets/diagram-OG6HWLK6-C-mJW1Tv.js +24 -0
- package/dist/client/assets/erDiagram-TEJ5UH35-DmyZPB5P.js +85 -0
- package/dist/client/assets/flowDiagram-I6XJVG4X-D6RrsDb6.js +162 -0
- package/dist/client/assets/ganttDiagram-6RSMTGT7-CP_O3OdU.js +292 -0
- package/dist/client/assets/gitGraphDiagram-PVQCEYII-DZgdWY-6.js +106 -0
- package/dist/client/assets/graph-CAnANduQ.js +1 -0
- package/dist/client/assets/index-DFYTyxkU.js +2 -0
- package/dist/client/assets/index-_GInkOX2.css +1 -0
- package/dist/client/assets/infoDiagram-5YYISTIA-BAp5orio.js +2 -0
- package/dist/client/assets/init-Gi6I4Gst.js +1 -0
- package/dist/client/assets/ishikawaDiagram-YF4QCWOH-DgqFJxLz.js +70 -0
- package/dist/client/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
- package/dist/client/assets/jetbrains-mono-cyrillic-600-normal-8K4wrrwR.woff +0 -0
- package/dist/client/assets/jetbrains-mono-cyrillic-600-normal-EVf6-Yzo.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
- package/dist/client/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-greek-600-normal-H7WoG9Et.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-greek-600-normal-mc2nkWzM.woff +0 -0
- package/dist/client/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
- package/dist/client/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-latin-600-normal-BfsvjouI.woff +0 -0
- package/dist/client/assets/jetbrains-mono-latin-600-normal-C8RAYTDA.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
- package/dist/client/assets/jetbrains-mono-latin-ext-600-normal-BfB_LPfz.woff2 +0 -0
- package/dist/client/assets/jetbrains-mono-latin-ext-600-normal-DObL3zCW.woff +0 -0
- package/dist/client/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
- package/dist/client/assets/jetbrains-mono-vietnamese-600-normal-OWROknRo.woff +0 -0
- package/dist/client/assets/journeyDiagram-JHISSGLW-BFlCgna7.js +139 -0
- package/dist/client/assets/kanban-definition-UN3LZRKU-Ck0sh2an.js +89 -0
- package/dist/client/assets/katex-DkKDou_j.js +257 -0
- package/dist/client/assets/katex.min-CfVKi3_s.css +1 -0
- package/dist/client/assets/katex.min-DBnXG_UH.js +1 -0
- package/dist/client/assets/layout-DGIYPm2g.js +1 -0
- package/dist/client/assets/linear-CfOau-eX.js +1 -0
- package/dist/client/assets/mermaid.core-BUwfPdjt.js +308 -0
- package/dist/client/assets/mindmap-definition-RKZ34NQL-tpaiyCEI.js +96 -0
- package/dist/client/assets/ordinal-Cboi1Yqb.js +1 -0
- package/dist/client/assets/pieDiagram-4H26LBE5-DaNIMGBH.js +30 -0
- package/dist/client/assets/quadrantDiagram-W4KKPZXB-BUZRyB7p.js +7 -0
- package/dist/client/assets/requirementDiagram-4Y6WPE33-D70DEVyJ.js +84 -0
- package/dist/client/assets/sankeyDiagram-5OEKKPKP-DckSl4S7.js +40 -0
- package/dist/client/assets/sequenceDiagram-3UESZ5HK-If3g75AG.js +162 -0
- package/dist/client/assets/stateDiagram-AJRCARHV-C-83rolJ.js +1 -0
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-BeI0-mGo.js +1 -0
- package/dist/client/assets/timeline-definition-PNZ67QCA-DIFKx0ow.js +120 -0
- package/dist/client/assets/vennDiagram-CIIHVFJN-BGLU5r80.js +34 -0
- package/dist/client/assets/wardley-L42UT6IY-qocA9kr0.js +173 -0
- package/dist/client/assets/wardleyDiagram-YWT4CUSO-CWhmOVum.js +78 -0
- package/dist/client/assets/xychartDiagram-2RQKCTM6-D2Sc4Taz.js +7 -0
- package/dist/client/bootstrap.js +45 -0
- package/dist/client/favicon.svg +5 -0
- package/dist/client/index.html +21 -0
- package/package.json +83 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.6.2] — 2026-05-19
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Mermaid diagrams now follow the active theme.** They were locked to the light palette (`theme: 'default'`), so on dark mode the text and edges were rendered as dark ink on the dark page background and were unreadable. The loader now reads `themeSignal`, re-initializes mermaid with `dark` / `default` to match, and re-renders existing diagrams on theme toggle (clearing the per-block render guard).
|
|
14
|
+
- **Mermaid syntax errors no longer dump a giant "Syntax error in text" diagram into the page.** On a bad diagram, mermaid's built-in fallback SVG (with the bomb-on-cream-background motif) could leak out of the block onto the page and break the layout when scrolling. Diagrams are now `parse`'d with `suppressErrors: true` first; failures render a compact `<pre class="mermaid-error">` inside the block, and any temp DOM nodes mermaid appended to `document.body` are cleaned up.
|
|
15
|
+
- **Live-reload SSE stops working after long sessions or many tab reloads.** A suspended browser tab or dropped network could leave the OS socket in a state where Node never fired `close`, so the per-connection listener on the watcher emitter was never removed. Every subsequent file save then fanned out into a dead pipe, and Node's default `MaxListenersExceededWarning` triggered at 10. The server process kept running (CLI still showed it up), but no new file change reached the browser and reloads appeared to hang. SSE writes now treat any failure as a hard disconnect and run a single cleanup path; the watcher emitter no longer caps its listener count at Node's default of 10.
|
|
16
|
+
|
|
17
|
+
## [0.6.1] — 2026-05-18
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
- **Inline `<code>` inside table cells now wraps on overflow** instead of forcing the column to demand huge minimum width. Previously, a cell containing a long unbroken identifier (e.g. `debezium.source.column.exclude.list=public.data_processors.completion_pct,…`) would dominate the table layout and starve sibling columns, causing short labels like `houston-debezium-server` to wrap into three lines. Scoped to `td code` / `th code` so prose-with-inline-code elsewhere is unaffected.
|
|
21
|
+
- **Copy button stays put while a code block is scrolled horizontally.** Previously the button was an absolutely-positioned child of `<pre>` (the scroll container), so it drifted off-screen with the content. The button now lives on a `position: relative` wrapper sibling of `<pre>`, so the wrapper holds its position while only the code scrolls underneath.
|
|
22
|
+
|
|
23
|
+
## [0.6.0] — 2026-05-14
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- **Collapsible sections.** Every heading gets a small chevron (hover-revealed when expanded, always visible when collapsed) that folds the section — every trailing sibling up to the next heading of equal-or-shallower level. State is per-tab, survives live-reload of the same file, resets on file switch. Anchor jumps (TOC, internal links, hash restore) auto-expand the target's containing section. In-doc search progressively expands collapsed sections as you cycle into matches that live inside them. Print expands everything and re-collapses after. Keyboard: `e` expand all, `⇧E` collapse all.
|
|
27
|
+
|
|
28
|
+
## [0.5.0] — 2026-05-14
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
- **No more `EMFILE: too many open files` crash on a repo root.** The file watcher used to descend into anything that wasn't a dotfile or `node_modules`, which on a polyglot monorepo (Elixir `_build/`, Rust `target/`, Python `__pycache__/venv/`, Go `vendor/`, generic `dist/build/out/coverage/`) blows past macOS's 256 soft FD limit (kqueue) and Linux's `inotify.max_user_watches`. Built-in skip list expanded to cover those names at every depth.
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- **`ignore: ["my-dir", "_site"]`** field in `.mdview.json` (project) or `~/.config/mdview/config.json` (new global config) extends the built-in skip list with your own basenames. Strings only, no globs — the comparison is plain basename equality. Restart mdview after editing; the watcher freezes its ignore set at startup.
|
|
35
|
+
- **Global config at `~/.config/mdview/config.json`** (honours `XDG_CONFIG_HOME` if set). Same schema as the project `.mdview.json`. Project config wins on scalar fields; `ignore` is unioned across both, so a per-repo extra doesn't drop your global build-dir list.
|
|
36
|
+
- **`mdview config` subcommand** — `mdview config path` prints the global config location; `mdview config ignore list / add <name…> / rm <name…>` reads and edits the ignore list without hand-editing the JSON. Adds validate against the same basename allow-list as the file loader.
|
|
37
|
+
- **Info icon in the file-tree pane head** with a tooltip explaining which folders are hidden and where to extend the list.
|
|
38
|
+
- **Helpful error on `EMFILE`/`ENOSPC`** at watcher startup — points the user at the global config file and shows the built-in defaults instead of crashing the process with a raw `UVException`.
|
|
39
|
+
|
|
40
|
+
## [0.4.0] — 2026-05-13
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
- **Browser tab favicon.** An accent-coloured italic "M" on a rounded square, served as `/favicon.svg`, so an mdview tab is visually distinguishable from other localhost tabs. Pure SVG — scales crisply at any tab size, no PNG variants needed.
|
|
44
|
+
- **Cmd/Ctrl-click a file in the tree to open it in a new tab.** File rows are now real anchors (`<a href="/?file=…">`) instead of buttons, which also enables middle-click → new tab, right-click → "Open link in new tab" / "Copy link", and hover URL preview in the browser status bar. Plain click still uses SPA navigation (no page reload). Non-markdown rows remain non-interactive.
|
|
45
|
+
|
|
46
|
+
## [0.3.1] — 2026-05-12
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
- **Outline level filter is now a 2-thumb range slider** instead of six H1–H6 toggle pills. Pick any contiguous heading-level band — e.g. just H2–H3, or H1–H6 for the full outline. State persists as `mdview-outline-min-level` + `mdview-outline-max-level`. The setters auto-correct inversion (drag min past max → both move together), so the user is never trapped at a single level.
|
|
50
|
+
- **Outline collapse button moved to the inner edge of the outline head** (left side, facing the main pane) to match the standard IDE pattern where pane collapse arrows live on the side facing the content area. The file-tree collapse button is unchanged — it already sat on its inner (right) edge.
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
- **Outline pane content pads itself away from the minimap** when both are visible — outline list entries no longer sit under the minimap bars. (Minimap remains at the viewport right edge as before; padding handled via a `has-minimap` class on the shell.)
|
|
54
|
+
|
|
55
|
+
### Fixed
|
|
56
|
+
- **Theme / palette / wide-layout no longer flash the default on reload.** The pre-paint bootstrap script in `index.html` had been silently blocked by the strict `script-src 'self'` CSP since 0.2.0 (CSPs forbid inline scripts without an explicit hash or `'unsafe-inline'`). Moved the bootstrap to an external `/bootstrap.js` served from `public/` — runs synchronously before first paint, satisfies the CSP without weakening it. Also extends to the new `data-wide` attribute added in 0.2.1.
|
|
57
|
+
- **Slider thumbs are now vertically centred on the track line.** WebKit was rendering the 14 px range thumbs aligned to the top of the runnable track; fixed by setting the runnable-track height to 4 px and adding `margin-top: -5px` on the thumb so it centres on the visual line.
|
|
58
|
+
|
|
59
|
+
### Security
|
|
60
|
+
- Bumped `mermaid` 11.3 → 11.15 to clear four moderate advisories: `GHSA-87f9-hvmw-gh4p` (CSS injection via config), `GHSA-6m6c-36f7-fhxh` (Gantt-chart infinite-loop DoS), `GHSA-ghcm-xqfw-q4vr` (HTML injection via `classDef` in state diagrams), `GHSA-xcj9-5m2h-648r` (CSS injection via `classDefs`).
|
|
61
|
+
|
|
62
|
+
## [0.3.0] — 2026-05-11
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
- **Focus mode now anchors to the top-third reading band (~35% of viewport) instead of the viewport top.** The bright section is always the one under your eyes; previously it could lag behind into a heading that had scrolled off-screen pages ago, with the dim covering the content you were actually reading. Breadcrumb / outline / minimap continue to anchor at the viewport top (they answer "where am I in the doc?"); focus mode answers a different question ("what am I reading right now?"). Implemented as a separate `focusedHeadingId` signal in `useScrollSpy`.
|
|
66
|
+
|
|
67
|
+
## [0.2.1] — 2026-05-11
|
|
68
|
+
|
|
69
|
+
### Added
|
|
70
|
+
- **Wide layout** toggle widens the reading column from 70ch to 100ch for docs that benefit from more horizontal space (tables, wide code blocks). Persisted as `mdview-wide-layout` and bound to the `w` keyboard shortcut.
|
|
71
|
+
- **Consolidated View menu** in the header — a single gear-icon popover containing Focus mode, Minimap, Wide layout, and the palette picker. Replaces the row of five separate header buttons. Theme and shortcuts (`?`) remain as standalone icons.
|
|
72
|
+
|
|
73
|
+
### Changed
|
|
74
|
+
- **Tree and outline collapse controls now live inside their respective panes** (a small head bar with the section label and a collapse button). The duplicate toggle buttons on the left and right edges of the header have been removed. The vertical "FILES" / "OUTLINE" rail buttons (shown when a pane is collapsed) are unchanged and remain the way to expand a collapsed pane.
|
|
75
|
+
|
|
76
|
+
### Removed
|
|
77
|
+
- `PalettePicker.tsx` component (replaced by the palette section inside `ViewMenu.tsx`).
|
|
78
|
+
|
|
79
|
+
## [0.2.0] — 2026-05-11
|
|
80
|
+
|
|
81
|
+
### Added
|
|
82
|
+
- **`high-contrast` palette** alongside classic / paper / nord / solarized — pure-white-on-near-black prose and bold accents in dark mode, mirror in light mode. Code blocks use `github-light-high-contrast` / `github-dark-high-contrast`.
|
|
83
|
+
- **Alt/Option + scroll wheel** multiplies scroll speed (~4×) in the main pane, matching JetBrains/VS Code behavior. Works on macOS, Windows, and Linux.
|
|
84
|
+
- `--version` / `-v` flag prints the package version.
|
|
85
|
+
- Cross-platform port-in-use hint (macOS / Linux / Windows).
|
|
86
|
+
- `LICENSE` file (MIT).
|
|
87
|
+
- Standard publish metadata in `package.json` (`license`, `repository`, `keywords`, `author`, `homepage`, `bugs`).
|
|
88
|
+
|
|
89
|
+
### Changed
|
|
90
|
+
- **Code blocks now follow the active palette.** Shiki renders 10 theme variants per token (5 palettes × light/dark) inline as CSS variables; CSS selects the variant based on `[data-palette][data-theme]`. Switching palette updates syntax highlighting instantly with no re-render. Mapping: classic → github, paper → min-light / vitesse-dark, nord → min-light / nord, solarized → solarized-*, high-contrast → github-*-high-contrast.
|
|
91
|
+
- **Focus mode, outline, breadcrumb, and minimap now share one source of truth** (`activeHeadingId`). Replaces the divergent center-of-viewport algorithm — focus dim and outline highlight always agree on the active section.
|
|
92
|
+
- Doc search (`SearchBar`) is now debounced at 150 ms so fast typing doesn't thrash regex matching + DOM highlighting on long docs. Folder search keeps its 250 ms debounce, now sharing the same `debounce` utility.
|
|
93
|
+
- Tagged relative `.md` links render with `href="?file=…"` instead of the raw path, so cmd/ctrl+click opens the right URL in a new tab with no server-redirect round-trip.
|
|
94
|
+
- `package.json` `files` tightened to ship only `bin/mdview.mjs`, `dist`, `README.md`, `LICENSE`, `CHANGELOG.md` (drops the bundled source map).
|
|
95
|
+
|
|
96
|
+
### Fixed
|
|
97
|
+
- **Theme and palette no longer flash the default on reload.** An inline `<head>` script applies `data-theme` and `data-palette` synchronously before first paint. The previous code path waited for the React app to mount, causing a brief FOUC and occasional silent reset on Safari ITP / private browsing.
|
|
98
|
+
- **Relative `.md` links from rendered markdown open the correct file** when clicked (regular click and cmd/ctrl+click). Previously the server's SPA fallback returned `index.html` for any unmatched path, so clicking `[label](other.md)` could open a random last-viewed file. Now the server 302-redirects unmatched `.md` paths to `/?file=…`, and the client intercepts same-origin `.md` anchors as a belt-and-suspenders fallback.
|
|
99
|
+
- **First and last sections can now become the active heading** at scroll boundaries, in outline, focus mode, minimap, and breadcrumb. Previously short first/last sections (shorter than half the viewport) could never be highlighted because the topmost-passed heuristic couldn't reach them.
|
|
100
|
+
- URL-encoded markdown link paths (`foo%20bar.md`) no longer double-encode through the SPA router — `data-internal-link` stores the decoded path so the router's `encodeURIComponent` produces the right URL.
|
|
101
|
+
- `persisted-signal` now warns once when `localStorage` access throws (Safari ITP / private mode), making the silent-reset case debuggable.
|
|
102
|
+
- Folder-wide search now handles Windows CRLF (`\r\n`) line endings correctly.
|
|
103
|
+
- CLI rejects extra positional arguments instead of silently dropping all but the last.
|
|
104
|
+
|
|
105
|
+
### Security
|
|
106
|
+
- Content-Security-Policy and supporting headers (`X-Content-Type-Options`, `Referrer-Policy`) are set on every HTML response. Inline scripts in user markdown can no longer execute by default.
|
|
107
|
+
- `/__asset/*` now allow-lists known media MIME types and 404s everything else — arbitrary file reads of `.env`, dotfiles, source code etc. through the asset route are blocked.
|
|
108
|
+
- `/api/file` rejects requests for non-markdown paths (`.md`, `.markdown`, `.mdx` only).
|
|
109
|
+
- Folder-wide regex search caps execution at ~5 ms per line and reports `truncated: true` rather than freezing the event loop on pathological inputs (ReDoS mitigation).
|
|
110
|
+
- Server's 404 redirect for unmatched `.md` paths URL-encodes the target and rejects CR/LF in the request path to prevent open-redirect and HTTP response-splitting attacks.
|
|
111
|
+
- Bumped `@fastify/static` 8 → 9.1.3 (fixes GHSA-pr96-94w5-mx2h directory-listing traversal and GHSA-x428-ghpx-8j92 encoded-separator route bypass).
|
|
112
|
+
- Bumped dev deps to clear remaining advisories: `happy-dom` 15 → 20.9.0 (GHSA-37j7-fg3j-429f VM context escape), `vitest` 2 → 3.2.4 + `vite` → 6.4.2 (pulls in patched `esbuild`).
|
|
113
|
+
|
|
114
|
+
## [0.1.0] — 2026-05
|
|
115
|
+
|
|
116
|
+
Initial v1 release plus phase-2 features. Highlights:
|
|
117
|
+
|
|
118
|
+
### Added
|
|
119
|
+
- Local CLI markdown viewer: `mdview [path]` serves a folder or single file on `127.0.0.1` and opens the browser.
|
|
120
|
+
- 3-pane layout with collapsible, resizable sidebars (folder tree + outline). Widths persisted to `localStorage`.
|
|
121
|
+
- Live reload via SSE + chokidar; scroll and outline state preserved.
|
|
122
|
+
- Markdown rendering: GFM, Shiki dual-theme syntax highlighting, mermaid (lazy), KaTeX math (lazy), tables, frontmatter, task lists.
|
|
123
|
+
- Heading permalinks, code copy buttons, external-link indicators, image lightbox with relative-path resolution via `/__asset/*`.
|
|
124
|
+
- In-doc search (`/`, `⌘F`) with prev/next/match-counter.
|
|
125
|
+
- Folder-wide grep search, grouped by file, with snippets.
|
|
126
|
+
- Theme toggle (light/dark, OS-driven + manual override, persisted) plus built-in palettes (classic / paper / nord / solarized).
|
|
127
|
+
- Vim-style shortcuts (`gg`, `G`, `H`/`L`, `]`/`[`, `Ctrl+D`/`Ctrl+U`) and a shortcuts panel (`?`).
|
|
128
|
+
- Reading progress bar, doc stats (reading time, words, headings), focus mode + minimap.
|
|
129
|
+
- Per-project `.mdview.json` config (palette, font, line-width, default-collapsed sidebars).
|
|
130
|
+
- Friendly CLI error messages and graceful shutdown.
|
|
131
|
+
|
|
132
|
+
[Unreleased]: https://github.com/hardikg2907/mdview/compare/v0.6.0...HEAD
|
|
133
|
+
[0.6.0]: https://github.com/hardikg2907/mdview/compare/v0.5.0...v0.6.0
|
|
134
|
+
[0.5.0]: https://github.com/hardikg2907/mdview/compare/v0.4.0...v0.5.0
|
|
135
|
+
[0.4.0]: https://github.com/hardikg2907/mdview/compare/v0.3.1...v0.4.0
|
|
136
|
+
[0.3.1]: https://github.com/hardikg2907/mdview/compare/v0.3.0...v0.3.1
|
|
137
|
+
[0.3.0]: https://github.com/hardikg2907/mdview/compare/v0.2.1...v0.3.0
|
|
138
|
+
[0.2.1]: https://github.com/hardikg2907/mdview/compare/v0.2.0...v0.2.1
|
|
139
|
+
[0.2.0]: https://github.com/hardikg2907/mdview/compare/v0.1.0...v0.2.0
|
|
140
|
+
[0.1.0]: https://github.com/hardikg2907/mdview/releases/tag/v0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Hardik Garg
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# mdview
|
|
2
|
+
|
|
3
|
+
[](https://github.com/hardikg2907/mdview/releases)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://nodejs.org)
|
|
6
|
+
|
|
7
|
+
A local markdown viewer for reading long, hierarchical docs without losing focus. Run a command, browser opens with a beautifully rendered, navigable view of your file or folder. Edits in your editor show up live. Close terminal to stop.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
mdview ./docs # browse a folder
|
|
11
|
+
mdview README.md # view a single file
|
|
12
|
+
mdview # current directory
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Why
|
|
16
|
+
|
|
17
|
+
Reading long markdown docs is hard:
|
|
18
|
+
- You scroll, get distracted, come back, can't find your spot.
|
|
19
|
+
- Deep inside a subsection, you forget how it relates to the parent topic.
|
|
20
|
+
- AI-generated brainstorming docs grow as you iterate — paste-and-render tools can't keep up.
|
|
21
|
+
- Raw markdown without color or rhythm is monotonous over hundreds of lines.
|
|
22
|
+
|
|
23
|
+
`mdview` is built for that. It's a single-machine, single-user, read-only viewer with editorial typography, persistent navigation, and live reload.
|
|
24
|
+
|
|
25
|
+
## Install from source
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git clone https://github.com/hardikg2907/mdview.git
|
|
29
|
+
cd mdview
|
|
30
|
+
npm install
|
|
31
|
+
npm run build
|
|
32
|
+
npm install -g . # puts `mdview` on your PATH
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Or run from source without global install:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install && npm run build
|
|
39
|
+
node bin/mdview.mjs ./docs
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Share with friends without publishing
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm run build && npm pack # produces mdview-0.6.0.tgz
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Send them the `.tgz` (Slack/Drive/AirDrop). They install with:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm install -g ./mdview-0.6.0.tgz
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Or skip the tarball entirely:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npm install -g github:hardikg2907/mdview
|
|
58
|
+
# or one-shot
|
|
59
|
+
npx github:hardikg2907/mdview ./docs
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The `prepare` script auto-builds on their machine if `bin/` is absent.
|
|
63
|
+
|
|
64
|
+
## Usage
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
mdview <path> # file or folder
|
|
68
|
+
mdview # current directory
|
|
69
|
+
mdview --port 9000 # custom port (default 7331; auto-fallback unless --port is explicit)
|
|
70
|
+
mdview --no-open # don't auto-launch the browser
|
|
71
|
+
mdview --help # show usage
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Closes when you `Ctrl-C` or `kill` the process. Set `MDVIEW_DEBUG=1` for full stack traces on unexpected errors.
|
|
75
|
+
|
|
76
|
+
## Keyboard shortcuts
|
|
77
|
+
|
|
78
|
+
| Shortcut | Action |
|
|
79
|
+
|----------|--------|
|
|
80
|
+
| `⌘P` / `Ctrl+P` | Quick file switcher (fuzzy search) |
|
|
81
|
+
| `⌘F` / `Ctrl+F` or `/` | Open in-doc search |
|
|
82
|
+
| `⇧⌘F` / `Ctrl+Shift+F` | Open folder-wide search |
|
|
83
|
+
| `⌘B` / `Ctrl+B` | Toggle file tree |
|
|
84
|
+
| `⌘.` / `Ctrl+.` | Toggle outline |
|
|
85
|
+
| `⌘\` / `Ctrl+\` | Toggle theme |
|
|
86
|
+
| `j` / `k` | Next / previous heading |
|
|
87
|
+
| `gg` / `⇧G` | Top / bottom of document |
|
|
88
|
+
| `[` / `]` | Previous / next heading at the same level |
|
|
89
|
+
| `⇧H` / `⇧L` | Previous / next file in folder |
|
|
90
|
+
| `Ctrl+D` / `Ctrl+U` | Half-page down / up |
|
|
91
|
+
| `Alt` / `⌥` + scroll | Fast scroll (~4×) in the main pane |
|
|
92
|
+
| `f` / `m` | Toggle focus mode / minimap |
|
|
93
|
+
| `e` / `⇧E` | Expand all / collapse all sections |
|
|
94
|
+
| `Tab` (in search) | Cycle Doc ↔ Folder scope |
|
|
95
|
+
| `Enter` / `Shift+Enter` | Next / previous match in search |
|
|
96
|
+
| `Esc` | Close search / lightbox / panel |
|
|
97
|
+
| `?` | Open shortcuts panel |
|
|
98
|
+
|
|
99
|
+
Click the keyboard icon in the header anytime to see the full list.
|
|
100
|
+
|
|
101
|
+
## Features
|
|
102
|
+
|
|
103
|
+
**Reading**
|
|
104
|
+
- 3-pane layout: folder tree, content, outline. Both sidebars collapse to a thin label rail; both have drag handles to resize (widths persist).
|
|
105
|
+
- Editorial typography (serif body, italic accent H1, paper-grain background, JetBrains Mono in code blocks).
|
|
106
|
+
- Light & dark theme — follows your OS preference, with a manual override that persists.
|
|
107
|
+
- Five built-in palettes: classic / paper / nord / solarized / high-contrast. Pick one from the header palette swatch. Code blocks follow the palette (Nord syntax in Nord, Solarized in Solarized, etc.).
|
|
108
|
+
- Reading-progress bar pinned to the bottom of the header.
|
|
109
|
+
- Doc stats strip below the H1 (reading time, word count, heading count, "Updated N ago").
|
|
110
|
+
- Focus mode dims everything except the section at the viewport center.
|
|
111
|
+
- Optional minimap rail at the right edge: bars per heading, draggable to scroll, viewport indicator follows.
|
|
112
|
+
|
|
113
|
+
**Navigation**
|
|
114
|
+
- Folder tree sidebar; click any file to load it. Cross-file `[link](other.md)` navigates inside the viewer.
|
|
115
|
+
- Outline sidebar with scroll-spy and collapsible nesting. Six toggle pills (`H1`–`H6`) filter which levels show.
|
|
116
|
+
- Breadcrumbs in the header reflecting your current viewport heading; click any segment to jump.
|
|
117
|
+
- Stable per-heading anchors. Hover any heading to reveal a `#` link that copies a deep-link URL.
|
|
118
|
+
- Collapsible sections — every heading has a hover-revealed chevron that folds the section's content; anchor links auto-expand their target. `e` / `⇧E` expand or collapse the whole doc.
|
|
119
|
+
- `⌘P` quick file switcher with fuzzy matching across the whole tree.
|
|
120
|
+
|
|
121
|
+
**Rendering**
|
|
122
|
+
- CommonMark + GFM (tables, task lists, strikethrough, autolinks).
|
|
123
|
+
- Server-side syntax highlighting via Shiki, palette-aware (10 variants per token — one for every palette/theme combination) — zero client highlighter bundle, no re-render on theme/palette swap.
|
|
124
|
+
- Mermaid diagrams, lazy-loaded only when a doc contains a `mermaid` fence.
|
|
125
|
+
- Math via KaTeX (`$inline$` and `$$block$$`), lazy-loaded only when a doc contains math.
|
|
126
|
+
- Custom-styled task list checkboxes (filled accent when checked, hollow when unchecked).
|
|
127
|
+
- Front matter detected and shown as a small collapsible metadata block.
|
|
128
|
+
- Inline HTML pass-through (your content, your trust).
|
|
129
|
+
- Images render via a safe `/__asset/*` route with relative-path resolution against the file's folder. Click any image to open in a lightbox.
|
|
130
|
+
- External links get an `↗` icon and open in a new tab with `noopener noreferrer`.
|
|
131
|
+
|
|
132
|
+
**Live reload**
|
|
133
|
+
- File edits show up instantly. Scroll position and outline collapse state are preserved.
|
|
134
|
+
|
|
135
|
+
**Search**
|
|
136
|
+
- In-doc search highlights all matches; counter shows current position; `Enter`/`Shift+Enter` step through them.
|
|
137
|
+
- Folder-wide search greps every markdown file (`⇧⌘F` or the `Folder` toggle); results grouped by file with snippets, click any hit to open that file.
|
|
138
|
+
- Three options on the search bar: `Aa` (case-sensitive), `ab` (whole word), `.*` (regex).
|
|
139
|
+
|
|
140
|
+
**Polish**
|
|
141
|
+
- Loading skeleton while files first load.
|
|
142
|
+
- Smooth transitions on theme swap, sidebar collapse, outline highlight.
|
|
143
|
+
- Copy button on every code block.
|
|
144
|
+
- Subtle hover tooltips on every header control.
|
|
145
|
+
|
|
146
|
+
## Config
|
|
147
|
+
|
|
148
|
+
Two layered files, both optional, same schema:
|
|
149
|
+
|
|
150
|
+
- **Global**: `~/.config/mdview/config.json` (honours `$XDG_CONFIG_HOME`) — your machine-wide defaults.
|
|
151
|
+
- **Per-project**: `.mdview.json` at the folder root — overrides global for this folder.
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"palette": "nord",
|
|
156
|
+
"fontFamily": "serif",
|
|
157
|
+
"lineWidth": "70ch",
|
|
158
|
+
"defaultCollapsed": { "tree": false, "outline": false },
|
|
159
|
+
"ignore": ["deps", "_site"]
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
All fields optional. Validated on load — invalid values fall back silently with a warning. Edit the per-project file while the server is running and the SPA picks up palette/font/lineWidth changes live; `ignore` is read once at startup (the file watcher's skip list is frozen — restart mdview after editing).
|
|
164
|
+
|
|
165
|
+
`ignore` extends the built-in skip list (which already covers `node_modules`, `dist`, `build`, `out`, `target`, `coverage`, `vendor`, `__pycache__`, `venv`, `Pods`, `DerivedData`, `_build`, plus every dotfile/dotdir). Add your own basenames here — handy when running mdview at a repo root with non-standard build dirs to avoid `EMFILE: too many open files` from the OS file-watch limit.
|
|
166
|
+
|
|
167
|
+
You can edit the ignore list from the CLI without opening the JSON:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
mdview config path # print the global config path
|
|
171
|
+
mdview config ignore list # show built-in + user-added entries
|
|
172
|
+
mdview config ignore add deps _site # add one or more basenames
|
|
173
|
+
mdview config ignore rm deps # remove one or more basenames
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Stack
|
|
177
|
+
|
|
178
|
+
Node 20+, TypeScript, Fastify 5, markdown-it 14, Shiki 1, gray-matter, chokidar 4, Preact 10 + @preact/signals, KaTeX 0.16, mermaid 11 (lazy), JetBrains Mono via @fontsource, Vite 6, tsup 8, vitest 2.
|
|
179
|
+
|
|
180
|
+
## Documentation
|
|
181
|
+
|
|
182
|
+
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — how the system is put together
|
|
183
|
+
- [`docs/CONTRIBUTING.md`](docs/CONTRIBUTING.md) — dev workflow + how to add features
|
|
184
|
+
- [`docs/FEATURES.md`](docs/FEATURES.md) — comprehensive feature catalog
|
|
185
|
+
- [`TODO.md`](TODO.md) — roadmap (phase 3, phase 4)
|
|
186
|
+
- [`VERIFICATION.md`](VERIFICATION.md) — manual verification scenarios
|
|
187
|
+
|
|
188
|
+
## Tests
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
npm test # vitest, server + client (289 tests)
|
|
192
|
+
npm run typecheck # both tsconfigs
|
|
193
|
+
npm run build # vite (client) + tsup (server CLI)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Reporting issues
|
|
197
|
+
|
|
198
|
+
Found a bug or have a feature request? File it at [github.com/hardikg2907/mdview/issues](https://github.com/hardikg2907/mdview/issues).
|
|
199
|
+
|
|
200
|
+
## License
|
|
201
|
+
|
|
202
|
+
[MIT](LICENSE).
|