pagedex 0.1.2 → 0.1.4

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/docs/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # pagedex Documentation
2
+
3
+ User, integration, and developer guides for **pagedex**.
4
+
5
+ - [Getting Started](./getting-started.md) — CLI flags, environment variables, UI features, wikilinks, Git sync, and mobile gestures.
6
+ - [Supported File Types](./supported-files.md) — Markdown/MDX, sandboxed HTML + sibling assets, PDF, audio/video, CSV/TSV, SVG, code, and binaries.
7
+ - [MCP & REST API](./mcp-and-api.md) — Connecting AI clients to `/mcp`, the 5 vault tools, REST endpoints, `/raw/*`, and SSE live reload.
8
+ - [Security Model](./security.md) — Sandboxed HTML iframes, CSP/CORS behavior, `Origin: null` guard, and path protection.
9
+ - [Development & Release](./development.md) — Running `pnpm dev`, unit & smoke tests, and npm packaging.
@@ -0,0 +1,34 @@
1
+ # Development & Release
2
+
3
+ ## Running in Development
4
+
5
+ Start both the Hono API/MCP/Raw server (`:4321`) and Vite HMR dev server (`:5173`):
6
+
7
+ ```bash
8
+ pnpm install
9
+ PAGEDEX_ROOT=~/vault HOST=0.0.0.0 pnpm dev
10
+ ```
11
+
12
+ - **Dev UI:** `http://<host>:5173` (Vite proxies `/api/v1`, `/raw`, and `/mcp` with `xfwd: true` to `127.0.0.1:4321`)
13
+ - **API / Production UI:** `http://<host>:4321`
14
+
15
+ ## Build & Test
16
+
17
+ ```bash
18
+ pnpm build # Build production React bundle into dist/
19
+ pnpm test # Run node:test suite (test/api-mcp.test.js)
20
+ pnpm smoke # Run REST + multi-era MCP smoke checks against :4321
21
+ ```
22
+
23
+ ## npm Package Contents
24
+
25
+ `package.json` restricts the published tarball via `"files"` and runs `prepublishOnly: "vite build"`:
26
+
27
+ - **Included:** `package.json`, `README.md`, `docs/**`, `bin/pagedex.js`, `src/server/**`, and compiled `dist/**`.
28
+ - **Excluded:** `src/client/**`, `.agents/`, `AGENTS.md`, `test/`, `vite.config.js`, `.github/`.
29
+
30
+ Verify exact tarball contents before publishing with:
31
+
32
+ ```bash
33
+ npm pack --dry-run
34
+ ```
@@ -0,0 +1,52 @@
1
+ # Getting Started
2
+
3
+ `pagedex` turns any local folder of notes, code, media, and HTML into a fast web catalog with full-text search, backlinks, Git sync, and an MCP server on a single port.
4
+
5
+ ## Requirements
6
+
7
+ - **Node.js `>= 22.5.0`** (uses built-in `node:sqlite` for FTS5 trigram search)
8
+
9
+ ## Running with `npx`
10
+
11
+ ```bash
12
+ # Serve the current directory on http://127.0.0.1:4321
13
+ npx pagedex
14
+
15
+ # Serve a specific folder and open it in your browser
16
+ npx pagedex ~/vault --open
17
+
18
+ # Expose on your LAN / Tailscale IP
19
+ npx pagedex ~/vault --host 0.0.0.0 --port 4321
20
+ ```
21
+
22
+ ### CLI Options
23
+
24
+ | Flag | Env Var | Default | Description |
25
+ |---|---|---|---|
26
+ | `[dir]` | `PAGEDEX_ROOT` / `VAULT_ROOT` | `process.cwd()` | Root directory to serve |
27
+ | `-p, --port <port>` | `PORT` | `4321` | HTTP port |
28
+ | `-H, --host <host>` | `HOST` | `127.0.0.1` | Bind address (`0.0.0.0` for LAN/Tailscale) |
29
+ | `-o, --open` | — | `false` | Open browser on startup |
30
+ | `-v, --version` | — | — | Print version |
31
+ | `-h, --help` | — | — | Print CLI help |
32
+
33
+ ### Search Index Cache
34
+
35
+ The SQLite FTS5 trigram index is stored **outside** your target folder at `~/.cache/pagedex/<sha256>.db`, so running `pagedex` never creates untracked files in your Git repository.
36
+
37
+ Override the cache location with:
38
+ - `PAGEDEX_INDEX_DIR` — directory for `<hash>.db` files
39
+ - `PAGEDEX_INDEX_PATH` — exact `.db` file path
40
+
41
+ ## Web UI Highlights
42
+
43
+ - **View Modes (top-right `⋮` menu):**
44
+ - **Download** — downloads any open file via `/api/v1/file?path=...&download=1`
45
+ - **Preview** — rendered Markdown, sandboxed HTML, PDF, audio/video, CSV/TSV tables, or images
46
+ - **Edit** — lazy-loaded Tiptap WYSIWYG editor for Markdown (`.md`, `.markdown`, `.mdx`)
47
+ - **Diff** — line-by-line Git diff with per-line, per-hunk, and per-file discard
48
+ - **Raw** — syntax-highlighted source (including SVG XML, HTML, CSV, and code)
49
+ - **Wikilinks & Backlinks:** `[[note]]` and relative links resolve across the folder, and the outline panel lists incoming backlinks.
50
+ - **Git Integration:** Browse changed files in the Changes tab, inspect hunks, discard changes, or commit & push directly from the UI.
51
+ - **Live Reload (SSE):** External edits on disk (e.g. from your editor or an AI agent via MCP) refresh open files and the sidebar tree automatically via `/api/v1/events`.
52
+ - **Mobile Friendly:** Edge-swipe gestures open the left file drawer and right outline drawer, with long-press context actions in the tree.
@@ -0,0 +1,58 @@
1
+ # MCP & REST API
2
+
3
+ `pagedex` exposes both a multi-era **Model Context Protocol (MCP)** server and a **REST API** on the same port (`4321` by default).
4
+
5
+ ## MCP Server (`/mcp`)
6
+
7
+ The `/mcp` endpoint supports three MCP protocol eras simultaneously:
8
+ - **`2026-07-28`** (`server/discover` + Streamable HTTP)
9
+ - **`2025-11-25`** (legacy Streamable HTTP `initialize`)
10
+ - **`2024-11-05`** (legacy HTTP+SSE)
11
+
12
+ ### Example Client Config
13
+
14
+ Point any HTTP-capable MCP client (Claude Code, Cursor, VS Code, etc.) at:
15
+
16
+ ```json
17
+ {
18
+ "mcpServers": {
19
+ "pagedex": {
20
+ "url": "http://127.0.0.1:4321/mcp"
21
+ }
22
+ }
23
+ }
24
+ ```
25
+
26
+ ### Exposed MCP Tools
27
+
28
+ | Tool | Purpose |
29
+ |---|---|
30
+ | `list_vault` | List files/folders and metadata in the served root |
31
+ | `read_note` | Read file contents and backlinks |
32
+ | `search_vault` | Run SQLite FTS5 trigram full-text search |
33
+ | `write_note` | Create, overwrite, append, or patch (`target` → `replacement`) files |
34
+ | `delete_note` | Delete a file from disk and update the search index |
35
+
36
+ ## REST API (`/api/v1/*`)
37
+
38
+ | Method & Path | Description |
39
+ |---|---|
40
+ | `GET /api/v1/health` | Health check and resolved `root` path |
41
+ | `GET /api/v1/tree` | Full directory tree, `flatFiles`, `fileStats`, `backlinks` (`?sort=mtime\|name`, `?limit=`) |
42
+ | `GET /api/v1/files` | Paginated file listing (`?sort=`, `?offset=`, `?limit=`, `?q=`) |
43
+ | `GET /api/v1/search` | Full-text search (`?q=`, `?limit=`) |
44
+ | `GET /api/v1/file` | Read/stream a file (`?path=`, optional `?download=1`, supports HTTP `Range`) |
45
+ | `PUT / POST / PATCH /api/v1/file` | Create, append (`append: true`), or partial-edit (`target`, `replacement`) |
46
+ | `DELETE /api/v1/file` | Delete file (`?path=`) |
47
+ | `POST /api/v1/file/upload` | Multipart file upload into a target folder |
48
+ | `POST /api/v1/file/rename` | Rename/move a file |
49
+ | `POST /api/v1/dir/rename` | Rename/move a directory |
50
+ | `GET /api/v1/changes` | Git working-tree changes |
51
+ | `GET /api/v1/git/diff` | Parsed diff hunks for a file (`?path=`) |
52
+ | `POST /api/v1/git/discard` | Discard line, hunk, or entire file changes |
53
+ | `POST /api/v1/git/commit` | Commit selected files (and optional push) |
54
+ | `GET /api/v1/events` | Server-Sent Events stream for live filesystem changes |
55
+
56
+ ## Static / Raw Route (`/raw/*`)
57
+
58
+ `GET /raw/<relPath>` serves files by URL path rather than query string so HTML previews can load sibling assets (`style.css`, `app.js`, `data.json`) with relative URLs. See [Security Model](./security.md) for isolation details.
@@ -0,0 +1,25 @@
1
+ # Security Model
2
+
3
+ ## Sandboxed HTML Previews
4
+
5
+ When previewing `.html` / `.htm` files:
6
+
7
+ 1. **Iframe isolation (`sandbox="allow-scripts"`):**
8
+ - `allow-same-origin` is intentionally omitted.
9
+ - The iframe runs with an opaque (`null`) origin, so scripts inside vault HTML cannot access `window.parent`, `localStorage`, cookies, or pagedex's DOM.
10
+ - Top-level navigation, popups, and form submissions are disabled.
11
+
12
+ 2. **`Origin: null` API guard (`src/server/index.js`):**
13
+ - Mutating requests (`POST`, `PUT`, `PATCH`, `DELETE`) to `/api/v1/*` with `Origin: null` are rejected with `403 Forbidden`, preventing CORS simple-request CSRF from sandboxed iframes.
14
+
15
+ 3. **Origin-scoped Content-Security-Policy (`src/server/routes/files.js`):**
16
+ - Responses for `/raw/*.html` and `/raw/*.htm` include a `Content-Security-Policy` header scoped to the request's origin (`x-forwarded-host` / `host` / `referer`), plus `'unsafe-inline' 'unsafe-eval' data: blob:`.
17
+ - This allows local sibling assets (`style.css`, `app.js`, `data.json`, images) while blocking outbound requests to external domains.
18
+
19
+ 4. **Path Guards (`src/server/paths.js`, `src/server/routes/files.js`):**
20
+ - All file access passes through `resolveSafe()` (prevents `..` traversal outside `VAULT_ROOT`).
21
+ - `/raw/*` blocks protected segments (`.git`, `node_modules`, `dist`) and `.env*` files.
22
+
23
+ ## Notes on LAN / Tailscale Hosting
24
+
25
+ `pagedex` has no built-in user authentication. Bind to `127.0.0.1` (default) for local-only use, or use `--host 0.0.0.0` only on trusted private networks / Tailscale.
@@ -0,0 +1,33 @@
1
+ # Supported File Types
2
+
3
+ `pagedex` selects the viewer and search behavior by file extension and active view mode (`Preview`, `Edit`, `Diff`, `Raw`, plus `Download` in the top-right `⋮` menu).
4
+
5
+ | Type | Extensions | Preview Mode | Raw / Edit | Search Indexed |
6
+ |---|---|---|---|---|
7
+ | **Markdown** | `.md`, `.markdown`, `.mdx` | Rendered HTML, wikilinks, backlinks, outline | WYSIWYG (`TiptapEditor`), Raw, Diff | Yes (FTS5) |
8
+ | **HTML** | `.html`, `.htm` | Sandboxed `<iframe src="/raw/...">` | Syntax-highlighted XML/HTML | Yes |
9
+ | **PDF** | `.pdf` | Built-in browser PDF `<iframe>` + Download | — | No |
10
+ | **Audio** | `.mp3`, `.wav`, `.m4a`, `.ogg` | `<audio controls>` with HTTP `Range` seeking | — | No |
11
+ | **Video** | `.mp4`, `.webm`, `.mov` | `<video controls>` with HTTP `Range` seeking | — | No |
12
+ | **Tables** | `.csv`, `.tsv` | Styled HTML `<table>` | Raw text | Yes |
13
+ | **Images** | `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, `.ico` | Inline `<img>` | — | No |
14
+ | **SVG** | `.svg` | Inline `<img>` | Raw XML toggle | No |
15
+ | **Text / Code** | `.txt`, `.js`, `.ts`, `.py`, `.json`, `.yaml`, etc. | Syntax-highlighted raw view | Raw / Diff | Yes (≤ 2 MB) |
16
+ | **Other Binaries** | `.epub`, `.zip`, `.docx`, `.sqlite`, `.db`, etc. | Download card | — | No |
17
+
18
+ ## HTML + Sibling Files (`style.css`, `data.json`, `app.js`)
19
+
20
+ HTML files in Preview mode are loaded from `/raw/<path>` rather than `srcDoc`, so relative paths inside your HTML resolve naturally against the same folder:
21
+
22
+ ```html
23
+ <link rel="stylesheet" href="style.css" />
24
+ <script src="app.js"></script>
25
+ ```
26
+
27
+ ```js
28
+ fetch('data.json').then((r) => r.json())
29
+ ```
30
+
31
+ ## Audio & Video Seeking
32
+
33
+ `/api/v1/file` and `/raw/*` support HTTP `Range` (`206 Partial Content` / `Accept-Ranges: bytes`), allowing smooth scrubbing in `<audio>` and `<video>` players without buffering the entire file up front.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pagedex",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Local-first Markdown knowledge viewer, editor, Git bridge, and MCP v2 server for any directory.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -18,6 +18,7 @@
18
18
  "bin/",
19
19
  "src/server/",
20
20
  "dist/",
21
+ "docs/",
21
22
  "README.md"
22
23
  ],
23
24
  "scripts": {