mdshelf 1.1.0 → 1.1.1

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/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  Turn any folder of Markdown files into a fast, beautiful, browsable site. Point mdshelf at your OpenClaw, Hermes, GBrain, wikis, notes, docs, etc. — mount each one under its own URL (e.g. `/agent`, `/hermes`, `gbrain`, `/docs`, `/notes`, `/blog`) — and read them anywhere with hot reload, clean typography, and a mobile-first theme out of the box.
4
4
 
5
- Pairs beautifully with [Tailscale](https://tailscale.com): one command serves your shelf to every device on your tailnet — phone, iPad, laptop. Sharing with Tailscale is fully private by default: no port forwarding, no public DNS, nothing exposed to the open internet.
5
+ Pairs beautifully with [Tailscale](https://tailscale.com): one command serves your shelf to every device on your tailnet — phone, iPad, laptop. Serving over Tailscale is fully private by default: no port forwarding, no public DNS, nothing exposed to the open internet.
6
+
7
+ Putting a shelf on the open internet? `mdshelf serve --auth google` signs readers in with Google and shows each one only the pages their address is allowed to read — the rules live in each file's frontmatter. Signed-in readers can hand anyone a link to a single page that expires on its own and can be revoked at any time.
6
8
 
7
9
  One command installs it as a native system service (launchd, systemd, or Windows SCM) that runs quietly in the background and survives reboots.
8
10
 
@@ -33,6 +35,13 @@ Ships as a single static Rust binary with zero runtime dependencies.
33
35
  - Per-site accent colors — auto-assigned from a palette or configured explicitly
34
36
  - MiniJinja templates for layouts and partials — override any file without forking the whole theme
35
37
 
38
+ **Access**
39
+ - **Google sign-in** — `--auth google` puts every page behind sign-in with your own OAuth client
40
+ - Per-page access rules in frontmatter (`allow` / `deny`), inherited through folder `index.md` files; anything not granted is denied
41
+ - **Share links** — one page, no sign-in, expiring and revocable, from a Share button or `mdshelf share`
42
+ - Access log with `mdshelf audit`; rule debugging with `mdshelf acl explain` and `mdshelf acl doctor`
43
+ - Built-in HTTPS: Let's Encrypt, your own certificate, or TLS terminated by a proxy in front
44
+
36
45
  **Server**
37
46
  - **Hot reload** — WebSocket-based live reload; the browser refreshes automatically the moment you save a file
38
47
  - Response compression (gzip / brotli / zstd via tower-http)
@@ -113,7 +122,7 @@ Open `http://127.0.0.1:4444/` for the site index.
113
122
  | Command | Description |
114
123
  |---|---|
115
124
  | `mdshelf init [dir]` | Scaffold config and sample content |
116
- | `mdshelf serve` | Start the web server |
125
+ | `mdshelf serve` | Start the web server (`--auth google` for a private site) |
117
126
  | `mdshelf check` | Validate config and scan content |
118
127
  | `mdshelf export` | Export a static bundle of HTML and CSS files |
119
128
  | `mdshelf auth setup` | Walk through creating a Google OAuth client, then verify it |
@@ -124,7 +133,7 @@ Open `http://127.0.0.1:4444/` for the site index.
124
133
  | `mdshelf share <path>` | Create a link that shares one page with anyone holding the URL |
125
134
  | `mdshelf share list` | List share links (`--all` for dead ones, `--json` for an inventory) |
126
135
  | `mdshelf share revoke <id>` | Revoke one link, or `--all` to revoke every live link |
127
- | `mdshelf install` | Register as a native system service |
136
+ | `mdshelf install` | Register `serve`, with any of its options, as a native system service |
128
137
  | `mdshelf start` | Start the installed service |
129
138
  | `mdshelf stop` | Stop the installed service |
130
139
  | `mdshelf restart` | Restart the installed service |
@@ -300,7 +309,7 @@ mid-page. Sessions expire absolutely after `session_max_age` (default 30 days).
300
309
  > qualification. Each such event is logged at WARN with the cause, so an outage is
301
310
  > visible in the logs rather than presenting as mysterious sign-outs.
302
311
 
303
- ### Static export
312
+ ### Exporting a private vault
304
313
 
305
314
  A static bundle has no authentication, so exporting a vault that declares rules
306
315
  requires saying whose view it is:
@@ -468,6 +477,31 @@ sudo mdshelf uninstall
468
477
 
469
478
  Use `--user` for a per-user service where the platform supports it.
470
479
 
480
+ `mdshelf install` takes every `serve` option and the service runs with exactly those, so a
481
+ private site installs the same way it serves:
482
+
483
+ ```bash
484
+ sudo mdshelf auth setup # store Google credentials for the user installing the service
485
+ sudo mdshelf install --auth google --behind-proxy --public-url https://docs.acme.com
486
+ sudo mdshelf start
487
+ ```
488
+
489
+ Install runs the checks `serve` runs before it binds — TLS flags, the `[auth]` and `[links]`
490
+ settings, and the stored credentials — and refuses to register a service that could not
491
+ start. It prints the redirect URI to register with Google.
492
+
493
+ - **Credentials come from the file, not your shell.** A service does not inherit the
494
+ installing shell's `MDSHELF_GOOGLE_*` variables, so install requires both in
495
+ `~/.config/mdshelf/credentials.env` (what `mdshelf auth setup` writes). Run `auth setup`
496
+ as the same user that runs `install` — with `sudo`, that is root.
497
+ - **The service gets the installer's `HOME`.** With `--auth` or `--domain`, the service is
498
+ given the installing user's `HOME`, so the credentials, the at-rest key
499
+ (`~/.config/mdshelf/secret.key`) and the ACME cache resolve to the paths install checked.
500
+ - **Relative paths are pinned** to the directory you ran install in: `--tls-cert`,
501
+ `--tls-key` and `--acme-cache` are stored as absolute paths.
502
+ - **Windows:** a Windows service cannot be given `HOME`, so `install` refuses `--auth`, and
503
+ `--domain` without `--acme-cache`, there.
504
+
471
505
  ## Serving on port 80
472
506
 
473
507
  Set `host` and `port` in your config:
@@ -504,7 +538,7 @@ Tailscale provisions a certificate automatically and makes the site available **
504
538
  tailscale serve status # confirm the URL
505
539
  ```
506
540
 
507
- Pair it with `sudo mdshelf install && sudo mdshelf start` (see [System service](#system-service)) so both services survive reboots.
541
+ Pair it with `sudo mdshelf install && sudo mdshelf start` (see [System service](#system-service)) so both services survive reboots; pass the same `--auth` and TLS flags to `install` as to `serve`.
508
542
 
509
543
  To stop serving:
510
544
 
@@ -514,7 +548,16 @@ tailscale serve off
514
548
 
515
549
  ### Public access via Tailscale Funnel
516
550
 
517
- To make the site reachable from the **public internet** (not just your tailnet), use Funnel instead:
551
+ To make the site reachable from the **public internet** (not just your tailnet), use Funnel instead.
552
+ Funnel publishes everything mdshelf serves to anyone, so serve a private site with sign-in on
553
+ and Tailscale's hostname as the public URL:
554
+
555
+ ```bash
556
+ mdshelf serve --auth google --behind-proxy --public-url https://<machine>.<tailnet>.ts.net
557
+ ```
558
+
559
+ Register `https://<machine>.<tailnet>.ts.net/auth/callback` as a redirect URI on your Google
560
+ OAuth client, then:
518
561
 
519
562
  ```bash
520
563
  tailscale funnel --bg 4444
@@ -556,7 +599,7 @@ iPadOS Safari mishandle that, so there they go through `GET /__mdshelf/md/<page>
556
599
  enforces exactly the same access rules as viewing the page — a page you may not read
557
600
  returns the same response as one that does not exist.
558
601
 
559
- ### Static export
602
+ ### Exporting a static site
560
603
 
561
604
  ```bash
562
605
  mdshelf export # all sites → ./dist
@@ -23,7 +23,7 @@
23
23
  "hasInstallScript": true,
24
24
  "license": "MIT OR Apache-2.0",
25
25
  "name": "mdshelf",
26
- "version": "1.1.0"
26
+ "version": "1.1.1"
27
27
  },
28
28
  "node_modules/@isaacs/cliui": {
29
29
  "engines": {
@@ -542,5 +542,5 @@
542
542
  }
543
543
  },
544
544
  "requires": true,
545
- "version": "1.1.0"
545
+ "version": "1.1.1"
546
546
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "artifactDownloadUrls": [
3
- "https://github.com/prbski/mdshelf/releases/download/v1.1.0"
3
+ "https://github.com/prbski/mdshelf/releases/download/v1.1.1"
4
4
  ],
5
5
  "author": "Patryk Porebski",
6
6
  "bin": {
@@ -100,7 +100,7 @@
100
100
  "zipExt": ".tar.xz"
101
101
  }
102
102
  },
103
- "version": "1.1.0",
103
+ "version": "1.1.1",
104
104
  "volta": {
105
105
  "node": "18.14.1",
106
106
  "npm": "9.5.0"