@hardikg/mdview 0.7.1 → 0.9.0
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 +60 -0
- package/README.md +76 -9
- package/bin/mdview.mjs +986 -258
- package/dist/client/assets/abnfDiagram-VCTEODGH-d5-zUW3h.js +1 -0
- package/dist/client/assets/{arc-DYMLyL-_.js → arc-DIbSNhHb.js} +1 -1
- package/dist/client/assets/architectureDiagram-5GKGNRK7-Cq_KBCV9.js +36 -0
- package/dist/client/assets/blockDiagram-NRAW4CY4-CKgrJGzB.js +129 -0
- package/dist/client/assets/c4Diagram-UCG6FXSJ-CamsXU_i.js +38 -0
- package/dist/client/assets/channel-MJp4QxQY.js +1 -0
- package/dist/client/assets/{chunk-QZHKN3VN-Cd7CcXLC.js → chunk-2Q5K7J3B-DHB85OBA.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-BYGwnUQ4.js → chunk-5VM5RSS4-C3v07bfZ.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-TheCoD51.js → chunk-F27PBJKO-bDA5q_T9.js} +1 -1
- package/dist/client/assets/chunk-G27WJ6UU-DjS6mkGt.js +231 -0
- package/dist/client/assets/{chunk-4BX2VUAB-By-ok8D7.js → chunk-JWPE2WC7-ln94eTAD.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-Bj1JFNtT.js → chunk-LCL6LL3I-SEXOnCPG.js} +4 -4
- package/dist/client/assets/chunk-POPQ4Y6H-Dpgmgmgq.js +1 -0
- package/dist/client/assets/chunk-SVP7TREG-C_qgSQCy.js +88 -0
- package/dist/client/assets/{chunk-55IACEB6-BDUDnCl9.js → chunk-XXDRQBXY-CguISEfl.js} +1 -1
- package/dist/client/assets/classDiagram-DTDB5LWJ-BlbBfPMZ.js +1 -0
- package/dist/client/assets/classDiagram-v2-JRS7N3AN-BlbBfPMZ.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-Br-CySzr.js → cose-bilkent-JH36ORCC-CjtLn09K.js} +1 -1
- package/dist/client/assets/cynefin-OW5HDTMX-BgNmTgCR.js +178 -0
- package/dist/client/assets/cynefinDiagram-5FMLGOSQ-BFfuQ7YY.js +62 -0
- package/dist/client/assets/cytoscape.esm-BjAbmLdb.js +331 -0
- package/dist/client/assets/dagre-3AP2YEHR-BDLHOy1Z.js +4 -0
- package/dist/client/assets/diagram-S7CK7UJ4-CfzUQiTU.js +30 -0
- package/dist/client/assets/diagram-UQ7AKVKN-Ds3lTKuY.js +41 -0
- package/dist/client/assets/{diagram-KO2AKTUF-mwoLS2TK.js → diagram-VSXAHHWV-lwAuvia3.js} +3 -3
- package/dist/client/assets/diagram-VX7I27RA-CsU4EPwU.js +24 -0
- package/dist/client/assets/{diagram-LMA3HP47-4o7ohGjJ.js → diagram-Z3DM3KII-DFieIgnM.js} +2 -2
- package/dist/client/assets/ebnfDiagram-PWID7BFC-BzR_CBzj.js +1 -0
- package/dist/client/assets/erDiagram-SSCWMZ5O-joYlyDrM.js +99 -0
- package/dist/client/assets/flowDiagram-A5DVABFB-DVyMxsTJ.js +168 -0
- package/dist/client/assets/ganttDiagram-EL5Y4UJY-Cf4FwZsI.js +292 -0
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-eN40bRnz.js → gitGraphDiagram-WWUBYQGX-9grceorS.js} +7 -7
- package/dist/client/assets/index-7zMmn_PY.js +2 -0
- package/dist/client/assets/index-CcKPW3Oc.css +1 -0
- package/dist/client/assets/infoDiagram-RXCK75RN-ja-7F4cO.js +2 -0
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-BDIzsJJZ.js → ishikawaDiagram-5VMMS53U-uRRSMmsi.js} +5 -5
- package/dist/client/assets/{journeyDiagram-JHISSGLW-BfWwpj1w.js → journeyDiagram-EYS64GPL-BdD_OYKc.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-Cuij1uoR.js → kanban-definition-3QL26DDD-3rMqnFFk.js} +8 -8
- package/dist/client/assets/katex-C5jXJg4s.js +257 -0
- package/dist/client/assets/katex.min-BYZTj3zW.css +1 -0
- package/dist/client/assets/katex.min-DXaO1tdm.js +1 -0
- package/dist/client/assets/layout-3dyJkKek.js +1 -0
- package/dist/client/assets/{linear-CZOgGL8m.js → linear-B49R1aTA.js} +1 -1
- package/dist/client/assets/mermaid.core-CVM43n3z.js +312 -0
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-BbNc5LRE.js → mindmap-definition-FBJOCRG2-B8QesUuH.js} +1 -1
- package/dist/client/assets/pegDiagram-XKGWAZYB-BeO8X3By.js +1 -0
- package/dist/client/assets/pieDiagram-E7YTZNPT-DD3M93Je.js +39 -0
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-CmJGRE1L.js → quadrantDiagram-AXDQQJYC-LxJ8Qxzg.js} +3 -3
- package/dist/client/assets/railroadDiagram-O6MQD6OU-Cc6-wuTB.js +1 -0
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-Dp-nBLhC.js → requirementDiagram-EFPCY7ZU-D-vaSng7.js} +5 -5
- package/dist/client/assets/sankeyDiagram-P5KCCOFB-C-SrB4wj.js +40 -0
- package/dist/client/assets/sequenceDiagram-WJ2MYXX4-BpUTXTa1.js +162 -0
- package/dist/client/assets/sizeCapture-X5ZJPWSS-BG1rRkMg.js +1 -0
- package/dist/client/assets/stateDiagram-HBIQ2CUA-CAsJ9kP3.js +1 -0
- package/dist/client/assets/stateDiagram-v2-4QOOHH4V-ssPfmTD6.js +1 -0
- package/dist/client/assets/swimlanes-XN3QIQJK-DH5txxCi.js +1 -0
- package/dist/client/assets/swimlanesDiagram-VK2B7HYN-Cqi1auey.js +8 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-uVQ-oiv8.js → timeline-definition-24CTP7MA-DPSR_k-5.js} +3 -3
- package/dist/client/assets/vennDiagram-4TSXK5OY-CRMSJqLq.js +34 -0
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-BQMj40Ao.js → wardleyDiagram-VM6X3IG4-DRCnYQxB.js} +4 -4
- package/dist/client/assets/xychartDiagram-S5SC5T6Z-x5N3gqvJ.js +7 -0
- package/dist/client/bootstrap.js +13 -2
- package/dist/client/index.html +2 -2
- package/package.json +3 -3
- package/dist/client/assets/architectureDiagram-3BPJPVTR-iXijJkGs.js +0 -36
- package/dist/client/assets/blockDiagram-GPEHLZMM-Dmjj2Ajf.js +0 -132
- package/dist/client/assets/c4Diagram-AAUBKEIU-kJb6eQJJ.js +0 -10
- package/dist/client/assets/channel-DirF0LQF.js +0 -1
- package/dist/client/assets/chunk-2J33WTMH-T3vdO-20.js +0 -1
- package/dist/client/assets/chunk-AQP2D5EJ-BPZWXvxS.js +0 -231
- package/dist/client/assets/classDiagram-4FO5ZUOK-CdoMz3xi.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CdoMz3xi.js +0 -1
- package/dist/client/assets/cytoscape.esm-D_LviqZs.js +0 -331
- package/dist/client/assets/dagre-BM42HDAG-DcIxclFu.js +0 -4
- package/dist/client/assets/diagram-2AECGRRQ-C0xPdtMR.js +0 -43
- package/dist/client/assets/diagram-5GNKFQAL-B9i7DtoQ.js +0 -10
- package/dist/client/assets/diagram-OG6HWLK6-C6rhUBe2.js +0 -24
- package/dist/client/assets/erDiagram-TEJ5UH35-smNcu7Lp.js +0 -85
- package/dist/client/assets/flowDiagram-I6XJVG4X-CPuYTxJr.js +0 -162
- package/dist/client/assets/ganttDiagram-6RSMTGT7-xaV0Djok.js +0 -292
- package/dist/client/assets/graph-CAnANduQ.js +0 -1
- package/dist/client/assets/index-Cmcberpw.css +0 -1
- package/dist/client/assets/index-OFdfWE8x.js +0 -2
- package/dist/client/assets/infoDiagram-5YYISTIA-xm1BEpfJ.js +0 -2
- package/dist/client/assets/katex-DkKDou_j.js +0 -257
- package/dist/client/assets/katex.min-CfVKi3_s.css +0 -1
- package/dist/client/assets/katex.min-DBnXG_UH.js +0 -1
- package/dist/client/assets/layout-DGIYPm2g.js +0 -1
- package/dist/client/assets/mermaid.core-B1i-ZGkv.js +0 -309
- package/dist/client/assets/pieDiagram-4H26LBE5-oB2YhWwR.js +0 -30
- package/dist/client/assets/sankeyDiagram-5OEKKPKP-DB5dqk7n.js +0 -40
- package/dist/client/assets/sequenceDiagram-3UESZ5HK-jmqrpzCx.js +0 -162
- package/dist/client/assets/stateDiagram-AJRCARHV-U6m2A9Wk.js +0 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-00c0MW6J.js +0 -1
- package/dist/client/assets/vennDiagram-CIIHVFJN-By-tXl41.js +0 -34
- package/dist/client/assets/wardley-L42UT6IY-ByB1C5d8.js +0 -173
- package/dist/client/assets/xychartDiagram-2RQKCTM6-7czjL7-G.js +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,66 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.0] — 2026-09-14
|
|
11
|
+
|
|
12
|
+
Eight palettes, each with its own ground texture — and code blocks that are
|
|
13
|
+
smaller than they were at five.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- **Five new palettes: Everforest, Rosé Pine, Kanagawa, Catppuccin, and Flexoki** — each with a full light and dark variant and its own Shiki theme pair, so code blocks stay inside the palette. Base colours come from each project's own palette file; all six upstream projects are MIT.
|
|
17
|
+
- **Each palette now has its own ground texture.** Previously one texture was defined per light/dark theme, so a warm brown grain (`rgba(120, 70, 30, …)`) was washed over every palette including the cool ones. There are now three patterns, assigned per palette: a dot grain tinted with the palette's own ink on the paper-like palettes (flexoki, paper, solarized), fibre noise on the two lowest-contrast grounds (everforest, kanagawa), and an accent wash — a wide bleed of the palette's accent down from the top edge — on rose-pine and catppuccin. `high-contrast` gets none, because texture over a maximum-contrast ground works against the one thing that palette exists to provide. The noise is an SVG `feTurbulence` data URI, which the existing `img-src 'self' data: blob:` already permits, so the CSP is untouched.
|
|
18
|
+
|
|
19
|
+
Texture is deliberately not a setting. It is part of a palette's identity, and a four-way picker crossed with eight palettes is 32 combinations nobody would author or test.
|
|
20
|
+
- **VS Code extension: two-way cursor sync.** Clicking a heading or an internal link in the preview moves the editor cursor and reveals the line; moving the cursor in the editor scrolls the preview to the nearest heading at or above that line, debounced at 80ms. A suppression window breaks the feedback loop so VS Code's own selection-change event isn't echoed back as a jitter loop. Inbound paths from the webview are canonicalized with `realpath` and rejected unless they stay inside the workspace folder. The extension is still unpublished (`0.1.0`).
|
|
21
|
+
- VS Code extension: `mdview: Open in Browser` command, and the preview now follows the active editor and the VS Code colour theme.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- **Code blocks are rendered for the active palette only, and are far smaller for it.** Every token used to carry one CSS variable per (palette, mode) pair, so adding palettes inflated every document that contained code — 16 variables per token at eight palettes. A token now carries two, `--shiki-light` and `--shiki-dark`. `/api/file` accepts a `palette` query param, checked against the allow-list and falling back to the default rather than failing the request, and the client refetches when you change palette. The light/dark toggle still repaints with no request, since both its variants ship in every response. `test-fixtures/showcase.md` went from 204 KB to 30 KB — smaller than it was before any of the new palettes landed.
|
|
25
|
+
- **Flexoki is the new default palette**, replacing `classic`. It keeps the warm-cream editorial look but is built on a measured 15-step base ramp rather than hand-picked creams, and it is the only palette here designed for reading prose rather than for reading code.
|
|
26
|
+
- The VS Code extension's `auto` palette no longer picks a different palette for light and dark themes. Light versus dark is a separate axis in the renderer — every palette defines both — so `auto` now follows only the high-contrast kinds and otherwise leaves the palette alone.
|
|
27
|
+
|
|
28
|
+
### Removed
|
|
29
|
+
- **The `classic` and `nord` palettes.** `--palette classic` and `--palette nord` now exit non-zero and list the valid names. A `palette` of either in `.mdview.json` or a stale one in `localStorage` degrades silently to the default, which is the existing behaviour for any unrecognised palette — no migration needed.
|
|
30
|
+
- The VS Code extension drops both from the `mdview.palette` setting enum.
|
|
31
|
+
|
|
32
|
+
### Security
|
|
33
|
+
- `fastify` 5.8.5 → 5.12.3. Closes a schema-validation bypass via root primitive coercion (GHSA-w2qp-rph6-63g4) and `X-Forwarded-*` spoofing under `trustProxy` hop-count (GHSA-3m5p-2c4r-xxw2). Neither is reachable here — the server defines no root-primitive schemas and never sets `trustProxy` — but the dep ships to users.
|
|
34
|
+
- `js-yaml` 3.15.1 → 3.15.2 (transitively, via `gray-matter`). Closes unbounded CPU use on empty merge sources (GHSA-2883-xcg3-v3hh). This one is reachable: `js-yaml` parses frontmatter out of whatever markdown the user opens.
|
|
35
|
+
|
|
36
|
+
## [0.8.1] — 2026-08-24
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
- Live reload stopped working for any URL that named a file without its root id — a bookmark from before 0.8.0, or the VS Code extension sending a workspace-relative path. Such a request resolves against the primary root and the server answers with the workspace-scoped path, but the page kept comparing watch events against the path it had asked for, so nothing ever matched and the document silently stopped updating on save. The comparison now uses the path the server actually served. The first load always worked, which is why this got past the 0.8.0 checks.
|
|
40
|
+
|
|
41
|
+
## [0.8.0] — 2026-08-24
|
|
42
|
+
|
|
43
|
+
One background server, many folders. `mdview <path>` no longer holds the terminal.
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
- **`mdview <path>` returns the shell.** It starts one detached background server the first time it's needed; every later `mdview <path>`, in any repo, adds that folder to the same server and opens it. So unrelated folders — `~/work/api/docs` and `~/notes` — can be read side by side in one window at one stable URL. `--foreground` (`-f`) runs a server in the terminal as before.
|
|
47
|
+
- `mdview ls` (open folders, server pid/port, log path), `mdview rm <name|path>…` (stop serving a folder), `mdview stop` (stop the server).
|
|
48
|
+
- Folders persist in `~/.config/mdview/workspace.json` until removed, across restarts and reboots. Capped at 8, because each holds a live recursive watcher. Opening a file or subfolder inside an already-open folder reuses it instead of adding a duplicate.
|
|
49
|
+
- The background server runs until `mdview stop` or a reboot. `MDVIEW_IDLE_TIMEOUT` opts into having it exit after that many minutes with no browser tab connected (it clears its record, and the next `mdview` starts it again) — off by default, since a server that stays put keeps the URL reliable.
|
|
50
|
+
- `--port` and `--palette` now imply `--foreground`: each overrides a setting belonging to a whole server, and the background one is shared. A useful side effect is that every invocation that worked before behaves exactly as it did — only the bare `mdview [path]` form changed.
|
|
51
|
+
- The printed and opened URL is now `http://mdview.localhost:7331/` instead of `http://127.0.0.1:7331/`. `*.localhost` is reserved to loopback by RFC 6761 and resolves with no setup, no `/etc/hosts` entry and no privileges; the server still binds `127.0.0.1` only. If the local resolver doesn't answer the name with a loopback address the CLI falls back to the literal address rather than printing a URL that could leave the machine. `--vscode` keeps `127.0.0.1` unconditionally, because the extension validates that exact prefix.
|
|
52
|
+
- `PORT` is honoured as the default port when `--port` is omitted, so mdview runs unchanged under a local reverse proxy such as [portless](https://github.com/vercel-labs/portless) for a port-free URL. Invalid values are ignored rather than fatal.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
- **Paths in URLs are now workspace-scoped**: `?file=docs/api.md` becomes `?file=<rootId>/docs/api.md`, and asset URLs become `/__asset/<rootId>/<path>`. This is what lets one server host several unrelated folders at once. An unprefixed path still resolves against the first root, so existing links and existing bookmarks keep working, as does the VS Code extension.
|
|
56
|
+
- `/api/tree` now returns `{ roots, tree, config }`. With a single root its contents stay at the top level exactly as before; a second root is what introduces a folder node per root. Window-level settings (palette, font, line width) come from the first root; `ignore` stays per-root.
|
|
57
|
+
- Folder search covers every open folder root and labels each hit with its root. The 200-hit cap is a budget for the whole search rather than per root.
|
|
58
|
+
- With more than one folder open the sidebar groups each under its own heading, expanded by default. `⌘P` and folder search span every folder and show which one each result is in. Live reload learns a `workspace` event, so a folder opened or closed elsewhere appears in tabs that are already open without a reload. Closing the last folder shows an empty state rather than an endless skeleton.
|
|
59
|
+
|
|
60
|
+
### Security
|
|
61
|
+
- There is deliberately **no HTTP endpoint that changes which folders are served**. The CLI writes `workspace.json` and the server watches it, so adding a root requires filesystem access, which a web page does not have — nothing to CSRF, and no shared token to store or leak. `/api/health` is read-only and reports ids, a pid and a start time, never absolute paths.
|
|
62
|
+
- `mdview stop` checks the recorded pid **and** its start time against what the process reports before signalling it, so a recycled pid belonging to an unrelated process is never killed.
|
|
63
|
+
- State files are written `0600` inside a `0700` directory, each through a temp file and one rename so a reader never sees a half-written file. `workspace.json` is validated defensively on read: a hand-edited or truncated file degrades to fewer folders, never to a crash or an unchecked path.
|
|
64
|
+
- Concurrent `mdview` invocations are serialised through a lock file, so two shells can't race into two servers fighting over the port.
|
|
65
|
+
- Every request's `Host` header is now checked against a loopback allow-list (`localhost`, `*.localhost`, the loopback literals) in an `onRequest` hook, and anything else gets a bare `403`. Closes a DNS-rebinding hole: binding `127.0.0.1` never stopped a page the user was already browsing from re-resolving its own domain to loopback and reading every file mdview serves. Verified against a running server — `Host: evil.com` returned `200` before this change.
|
|
66
|
+
- `@fastify/static` 9 → 10 (major). Closes two high-severity advisories in the component that serves the SPA: authorization bypass via non-canonical URL paths (GHSA-8pvw-jcv7-9cmj) and route-guard bypass via path traversal (GHSA-83w8-p2f5-377r). The plugin is registered at a single call site with a `root` + `prefix` only, and v10 changes nothing we use — its diff against v9 is `fastify-plugin` ^5 → ^6 and `content-disposition` ^1 → ^2.
|
|
67
|
+
- Lockfile-only bumps clearing five further high-severity shipped-dep advisories: `brace-expansion` (DoS via unbounded expansion), `fast-uri` (host confusion via backslash authority delimiter), `find-my-way` (HTTP/2 DoS), `js-yaml` (quadratic CPU in `!!omap`), `linkify-it` (quadratic `mailto:` scan). `npm audit --omit=dev` is back to zero.
|
|
68
|
+
- The one remaining advisory is the `low`, dev-only `esbuild` one already deferred in 0.7.1: it is reachable only through `tsup`/`vite`, is absent from shipped deps, and never enters the published tarball. `npm audit fix` still cannot resolve it without a breaking parent bump.
|
|
69
|
+
|
|
10
70
|
## [0.7.1] — 2026-07-01
|
|
11
71
|
|
|
12
72
|
### Security
|
package/README.md
CHANGED
|
@@ -50,26 +50,93 @@ node bin/mdview.mjs ./docs
|
|
|
50
50
|
### Share with friends without publishing
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
|
-
npm run build && npm pack # produces mdview
|
|
53
|
+
npm run build && npm pack # produces hardikg-mdview-<version>.tgz
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
Send them the `.tgz` (Slack/Drive/AirDrop). They install with:
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
|
-
npm install -g ./mdview
|
|
59
|
+
npm install -g ./hardikg-mdview-<version>.tgz
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
## Usage
|
|
63
63
|
|
|
64
64
|
```bash
|
|
65
|
-
mdview <path> # file or folder
|
|
65
|
+
mdview <path> # open a file or folder; the shell comes straight back
|
|
66
66
|
mdview # current directory
|
|
67
|
-
mdview
|
|
67
|
+
mdview ls # what's open, and where the server is
|
|
68
|
+
mdview rm <name> # stop serving a folder
|
|
69
|
+
mdview stop # stop the background server
|
|
70
|
+
mdview --foreground # run in this terminal instead (Ctrl-C to stop)
|
|
68
71
|
mdview --no-open # don't auto-launch the browser
|
|
72
|
+
mdview --port 9000 # one-off server on a specific port (implies --foreground)
|
|
73
|
+
mdview --palette kanagawa # palette for this run (implies --foreground)
|
|
69
74
|
mdview --help # show usage
|
|
70
75
|
```
|
|
71
76
|
|
|
72
|
-
|
|
77
|
+
### One server, many folders
|
|
78
|
+
|
|
79
|
+
`mdview` does not hold your terminal. It starts a single background server the
|
|
80
|
+
first time you need one, and every later `mdview <path>` — in any repo — adds
|
|
81
|
+
that folder to the same server and opens it. So you can read
|
|
82
|
+
`~/work/api/docs` and `~/notes` side by side in one window, with one stable
|
|
83
|
+
URL, whether or not the folders are anywhere near each other.
|
|
84
|
+
|
|
85
|
+
```console
|
|
86
|
+
$ mdview ~/work/api
|
|
87
|
+
mdview → http://mdview.localhost:7331/?root=api
|
|
88
|
+
added: /Users/you/work/api (api)
|
|
89
|
+
$ cd ~/notes && mdview .
|
|
90
|
+
mdview → http://mdview.localhost:7331/?root=notes
|
|
91
|
+
added: /Users/you/notes (notes)
|
|
92
|
+
$ mdview ls
|
|
93
|
+
● api ~/work/api (primary)
|
|
94
|
+
● notes ~/notes
|
|
95
|
+
|
|
96
|
+
server: http://mdview.localhost:7331/ (pid 40113)
|
|
97
|
+
logs: ~/.config/mdview/daemon.log
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Folders stay open until you remove them with `mdview rm <name>`, across restarts
|
|
101
|
+
and reboots. Up to 8 at a time — each one holds a live file watcher, so the
|
|
102
|
+
limit is there to keep mdview from quietly watching your whole disk. Opening a
|
|
103
|
+
file or subfolder inside a folder that's already open reuses it rather than
|
|
104
|
+
adding a duplicate.
|
|
105
|
+
|
|
106
|
+
The server keeps running until you `mdview stop` it, or you reboot. If you'd
|
|
107
|
+
rather it stood down on its own, set `MDVIEW_IDLE_TIMEOUT` to a number of
|
|
108
|
+
minutes and it will exit that long after the last browser tab disconnects; the
|
|
109
|
+
next `mdview` starts it again.
|
|
110
|
+
|
|
111
|
+
Its state lives in `~/.config/mdview/` (`daemon.json`, `workspace.json`,
|
|
112
|
+
`daemon.log`) and nowhere else. `workspace.json` is also how the CLI talks to
|
|
113
|
+
the server: `mdview <path>` writes the file and the server picks the change up,
|
|
114
|
+
which is why there is no HTTP endpoint that can change what's being served.
|
|
115
|
+
|
|
116
|
+
The URL is `http://mdview.localhost:7331/` — `*.localhost` always resolves to
|
|
117
|
+
loopback (RFC 6761) with no setup, and the server still listens on `127.0.0.1`
|
|
118
|
+
only. If your resolver doesn't answer the name, mdview falls back to printing
|
|
119
|
+
`http://127.0.0.1:<port>/`. Setting `PORT` changes the default port, so mdview
|
|
120
|
+
works as-is behind a local proxy like
|
|
121
|
+
[portless](https://github.com/vercel-labs/portless) if you want the port gone
|
|
122
|
+
entirely.
|
|
123
|
+
|
|
124
|
+
`--palette` takes `flexoki`, `paper`, `solarized`, `everforest`, `rose-pine`,
|
|
125
|
+
`kanagawa`, `catppuccin`, or `high-contrast`.
|
|
126
|
+
It wins over both `.mdview.json` and the global config, and never writes to
|
|
127
|
+
either. There is also a `--vscode` flag, used by the VS Code extension to run
|
|
128
|
+
mdview as a sidecar; it implies `--no-open` and prints a single JSON ready line
|
|
129
|
+
instead of the human-readable output.
|
|
130
|
+
|
|
131
|
+
`--port` and `--palette` both override a setting that belongs to a whole server,
|
|
132
|
+
and the background one is shared with every other folder you have open — so each
|
|
133
|
+
implies `--foreground`, giving you a server of your own. That also means every
|
|
134
|
+
invocation that worked before still behaves exactly as it did; only the bare
|
|
135
|
+
`mdview [path]` form returns the shell now.
|
|
136
|
+
|
|
137
|
+
`--foreground` closes when you `Ctrl-C` or `kill` it. The background server is
|
|
138
|
+
stopped with `mdview stop`. Set `MDVIEW_DEBUG=1` for full stack traces on
|
|
139
|
+
unexpected errors.
|
|
73
140
|
|
|
74
141
|
## Keyboard shortcuts
|
|
75
142
|
|
|
@@ -102,7 +169,7 @@ Click the keyboard icon in the header anytime to see the full list.
|
|
|
102
169
|
- 3-pane layout: folder tree, content, outline. Both sidebars collapse to a thin label rail; both have drag handles to resize (widths persist).
|
|
103
170
|
- Editorial typography (serif body, italic accent H1, paper-grain background, JetBrains Mono in code blocks).
|
|
104
171
|
- Light & dark theme — follows your OS preference, with a manual override that persists.
|
|
105
|
-
-
|
|
172
|
+
- Eight built-in palettes: flexoki / paper / solarized / everforest / rose-pine / kanagawa / catppuccin / high-contrast. Pick one from the header palette swatch. Each defines a full light and dark variant and its own ground texture: a dot grain on the paper-like palettes, fibre noise on Everforest and Kanagawa, an accent wash on Rosé Pine and Catppuccin, and none at all on high-contrast. Code blocks follow the palette (Everforest syntax in Everforest, Catppuccin in Catppuccin, etc.).
|
|
106
173
|
- Reading-progress bar pinned to the bottom of the header.
|
|
107
174
|
- Doc stats strip below the H1 (reading time, word count, heading count, "Updated N ago").
|
|
108
175
|
- Focus mode dims everything except the section at the viewport center.
|
|
@@ -118,7 +185,7 @@ Click the keyboard icon in the header anytime to see the full list.
|
|
|
118
185
|
|
|
119
186
|
**Rendering**
|
|
120
187
|
- CommonMark + GFM (tables, task lists, strikethrough, autolinks).
|
|
121
|
-
- Server-side syntax highlighting via Shiki, palette-aware
|
|
188
|
+
- Server-side syntax highlighting via Shiki, palette-aware: two variants per token, light and dark, for whichever palette is active. Zero client highlighter bundle, and the light/dark toggle repaints with no request.
|
|
122
189
|
- Mermaid diagrams, lazy-loaded only when a doc contains a `mermaid` fence.
|
|
123
190
|
- Math via KaTeX (`$inline$` and `$$block$$`), lazy-loaded only when a doc contains math.
|
|
124
191
|
- Custom-styled task list checkboxes (filled accent when checked, hollow when unchecked).
|
|
@@ -150,7 +217,7 @@ Two layered files, both optional, same schema:
|
|
|
150
217
|
|
|
151
218
|
```json
|
|
152
219
|
{
|
|
153
|
-
"palette": "
|
|
220
|
+
"palette": "everforest",
|
|
154
221
|
"fontFamily": "serif",
|
|
155
222
|
"lineWidth": "70ch",
|
|
156
223
|
"defaultCollapsed": { "tree": false, "outline": false },
|
|
@@ -186,7 +253,7 @@ Node 20+, TypeScript, Fastify 5, markdown-it 14, Shiki 1, gray-matter, chokidar
|
|
|
186
253
|
## Tests
|
|
187
254
|
|
|
188
255
|
```bash
|
|
189
|
-
npm test # vitest, server + client
|
|
256
|
+
npm test # vitest, server + client
|
|
190
257
|
npm run typecheck # both tsconfigs
|
|
191
258
|
npm run build # vite (client) + tsup (server CLI)
|
|
192
259
|
```
|