vde-open 0.1.4 → 0.1.6
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 +57 -55
- package/dist/cli.js +2 -2
- package/dist/daemon.js +2 -2
- package/dist/{main-DlLPjYZZ.js → main-C3SHFgNa.js} +489 -12
- package/dist/print-CR5-GDjQ.js +1779 -0
- package/dist/render-BJnuEfHt.js +6235 -0
- package/dist/{render-BNZz0CjQ.js → rendering-rules-DiE2jI7I.js} +39 -6243
- package/dist/{search-index-__laOomT.js → search-index-B7DqaWh6.js} +10 -0
- package/dist/web/assets/index-BsWikuUv.js +97 -0
- package/dist/web/index.html +1 -1
- package/dist/workers/parse-worker.js +10 -4
- package/dist/workers/search-worker.js +1 -1
- package/docs/agent-usage.md +2 -2
- package/package.json +1 -1
- package/dist/web/assets/index-BoCe8U41.js +0 -97
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
A local document viewer for agents and people who work from the same material. Open Markdown and HTML documents, read them in a management UI in the browser, and let an agent search and read the same documents from the CLI. An agent can also ask a person questions, and the person submits the answers from the management UI.
|
|
6
6
|
|
|
7
|
-
- Agents can search and read only the documents you opened
|
|
7
|
+
- Agents can search and read only the documents you opened.
|
|
8
8
|
- When you save a document, the management UI updates automatically.
|
|
9
9
|
- HTML is shown on a separate origin from the management UI, without running scripts (by default).
|
|
10
10
|
- The state is kept by a local daemon and is never sent to an external service.
|
|
@@ -14,56 +14,31 @@ A local document viewer for agents and people who work from the same material. O
|
|
|
14
14
|
Node.js 24 or later is required.
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
bun add -g vde-open # recommended
|
|
17
|
+
bun add -g vde-open # recommended
|
|
18
18
|
npm install -g vde-open # also works
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- Installing
|
|
21
|
+
- Bun installs `vo` into `~/.bun/bin`, so it stays available when you switch Node.js versions (with mise and similar tools). `npm install -g` installs it for the active Node.js version only. Either way, the commands run on the Node.js found on your `PATH`.
|
|
22
|
+
- Do not install it per project. There is one daemon per user, so projects with different versions would talk to the same daemon.
|
|
23
|
+
- Installing does not change shell files such as `.zshrc` and runs no build or install scripts (every dependency is bundled).
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
To install from a clone of this repository (pins Node.js 24.21.0 in `mise.toml`):
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
pnpm install --frozen-lockfile
|
|
31
|
-
pnpm build
|
|
32
|
-
pnpm test:pack # builds artifacts/vde-open-<version>.tgz and verifies an install in a separate directory
|
|
33
|
-
bun add -g "$PWD/artifacts/vde-open-0.1.4.tgz" # use an absolute path: bun add -g resolves relative paths from its global install directory, not the current one
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Developing with a linked CLI
|
|
37
|
-
|
|
38
|
-
From the repository root, build once and link the CLI package globally:
|
|
25
|
+
To install from a clone of this repository (Node.js 24.21.0 is pinned in `mise.toml`):
|
|
39
26
|
|
|
40
27
|
```bash
|
|
41
28
|
pnpm install --frozen-lockfile
|
|
42
29
|
pnpm build
|
|
43
|
-
|
|
44
|
-
bun
|
|
45
|
-
bun link -g vde-open
|
|
46
|
-
cd ../..
|
|
47
|
-
pnpm build:watch
|
|
30
|
+
pnpm test:pack # builds artifacts/vde-open-<version>.tgz and verifies an install in a separate directory
|
|
31
|
+
bun add -g "$PWD/artifacts/vde-open-0.1.6.tgz" # bun add -g needs an absolute path
|
|
48
32
|
```
|
|
49
33
|
|
|
50
|
-
`build:watch` builds immediately, then watches the CLI, UI, shared sources, build configuration, and packaged files. Saves are coalesced and builds run one at a time. Both apps and the package files are prepared in a temporary directory before replacing the distribution; a failed build leaves the last successful output in place. The next linked CLI invocation uses the updated build.
|
|
51
|
-
|
|
52
|
-
The watcher does not start or restart your daemon. After a successful build, run `vo daemon restart`, then `vo ui` to open the updated UI. Restarting preserves registered documents and saved answers, but changes the UI address and invalidates earlier browser sessions and interactive HTML permissions. Stop the watcher with Ctrl+C; it stops an active build and removes its temporary output.
|
|
53
|
-
|
|
54
|
-
For frequent UI changes, use `pnpm dev` instead. It runs the source daemon with a separate `.dev-home` and serves the UI through Vite HMR. It does not rebuild the linked CLI or automatically restart the backend when its source changes. CLI commands for that environment need the same absolute `VDE_OPEN_HOME` (for example, `VDE_OPEN_HOME="$PWD/.dev-home" vo list` from the repository root).
|
|
55
|
-
|
|
56
34
|
## `vde-open` and `vo`
|
|
57
35
|
|
|
58
|
-
The same CLI is installed
|
|
59
|
-
|
|
60
|
-
- `vde-open`: the full name.
|
|
61
|
-
- `vo`: the short name.
|
|
36
|
+
The same CLI is installed as `vde-open` and as the short name `vo`. Both use the same state and daemon.
|
|
62
37
|
|
|
63
|
-
|
|
38
|
+
Installing never overwrites or removes an existing `vo` (another tool's command, an alias, and so on):
|
|
64
39
|
|
|
65
|
-
- If
|
|
66
|
-
-
|
|
40
|
+
- If npm's global bin already has another `vo`, `npm install -g` stops with `EEXIST`. Do not add `--force`, which replaces it. Install with Bun, or into another prefix (`npm install -g --prefix ~/.local/vde-open vde-open`) and run `vde-open` from that bin directory.
|
|
41
|
+
- If another `vo` comes first on `PATH`, use `vde-open`, or define your own alias (for example `alias vdo=vde-open`).
|
|
67
42
|
|
|
68
43
|
## Basic usage
|
|
69
44
|
|
|
@@ -72,17 +47,17 @@ vo open README.md docs/design.md # open documents (starts the daemon if n
|
|
|
72
47
|
vo open docs -w # open a directory and follow new documents
|
|
73
48
|
vo ui # open the management UI (one-time URL)
|
|
74
49
|
vo list --json # list open documents
|
|
75
|
-
vo search "
|
|
50
|
+
vo search "authentication design" --json # search open documents
|
|
76
51
|
vo read <documentId> --section sec_0003 --json # read a section
|
|
77
52
|
vo close docs/design.md # remove from the list (the file is not deleted)
|
|
78
53
|
vo daemon stop # stop the daemon
|
|
79
54
|
```
|
|
80
55
|
|
|
81
|
-
|
|
56
|
+
For how agents search, read, and ask questions, see [docs/agent-usage.md](docs/agent-usage.md).
|
|
82
57
|
|
|
83
58
|
## Agent skill
|
|
84
59
|
|
|
85
|
-
[`skills/vde-open/SKILL.md`](skills/vde-open/SKILL.md)
|
|
60
|
+
[`skills/vde-open/SKILL.md`](skills/vde-open/SKILL.md) teaches an agent (Claude Code, Codex, and others that read `SKILL.md`) when and how to use `vo`. It is included in the package. Link or copy the directory into your agent's skill directory:
|
|
86
61
|
|
|
87
62
|
```bash
|
|
88
63
|
# Installed with Bun: the skill is in the global package directory.
|
|
@@ -95,16 +70,15 @@ ln -s ~/.bun/install/global/node_modules/vde-open/skills/vde-open ~/.codex/skill
|
|
|
95
70
|
## Search scope
|
|
96
71
|
|
|
97
72
|
- Search covers **only the documents that are open right now**. Closed documents, files that are not open, and whole directories are never searched.
|
|
98
|
-
-
|
|
99
|
-
- Japanese text is split into words with `Intl.Segmenter`. Search uses exact matches, prefix matches, and fuzzy matches of alphanumeric words with up to one character of difference.
|
|
73
|
+
- Japanese text is split into words with `Intl.Segmenter`. Words match exactly, by prefix, or, for alphanumeric words, with up to one character of difference.
|
|
100
74
|
- In the management UI, press `Cmd/Ctrl+K` to search.
|
|
101
75
|
|
|
102
76
|
## HTML display limits
|
|
103
77
|
|
|
104
78
|
- By default (static), scripts do not run. Scripts, event attributes, iframe/object/embed, base, automatic navigation (meta refresh), form targets, and external images, CSS, and fonts are removed. Links cannot be clicked inside the view; open them from "Links in this document".
|
|
105
79
|
- Only files that the document references, inside the assets root (by default the document's directory), can be loaded. Files whose names start with "." such as `.env` and `.git` are never loaded. Set the scope with `--assets-root` and individual files with `--asset`.
|
|
106
|
-
- Scripts run only in HTML opened with `--html-mode interactive`.
|
|
107
|
-
-
|
|
80
|
+
- Scripts run only in HTML opened with `--html-mode interactive`. Use it only with HTML that you or the agent prepared and trust: scripts can load only registered files and cannot reach the management UI, the management API, or other files, but this does not block every outbound request (navigation inside the view, for example). After the daemon restarts, the HTML is static until you allow scripts again in the management UI.
|
|
81
|
+
- "Differences from the original document" in the management UI lists what the view changed, why, and what to do.
|
|
108
82
|
|
|
109
83
|
## Markdown display limits
|
|
110
84
|
|
|
@@ -115,14 +89,25 @@ Markdown is rendered with TanStack Markdown 1.0.0. It is not fully compatible wi
|
|
|
115
89
|
- Code is highlighted only for JS, JSX, TS, TSX, JSON, YAML, HTML, CSS, Bash, and Markdown. Code larger than 256 KiB and other languages are not highlighted.
|
|
116
90
|
- Documents that cannot be parsed within 2 seconds, or that have more than 100,000 elements or more than 64 levels of nesting, are shown as source.
|
|
117
91
|
|
|
92
|
+
## Exporting Markdown to PDF
|
|
93
|
+
|
|
94
|
+
"Export PDF" in the header of a Markdown document saves the shown revision as a PDF, without a print dialog.
|
|
95
|
+
|
|
96
|
+
- The PDF is A4 on a white background. Every page has the document title in the header and the page number ("3 / 12") in the footer, and the headings become PDF bookmarks.
|
|
97
|
+
- The daemon prints it with the Google Chrome or Microsoft Edge (131 or later) installed on the machine; nothing is downloaded. To use another Chromium-based browser or another location, set `VDE_OPEN_BROWSER` for the daemon to the absolute path of the executable, then run `vo daemon restart`.
|
|
98
|
+
- The rules of the view apply: raw HTML is shown as text, only images registered for the document are included (others show their alternative text), and links to other local documents become plain text.
|
|
99
|
+
- The file name is the document's file name with `.pdf` (`README.md` → `README.pdf`); a document read from stdin uses its title.
|
|
100
|
+
- The PDF uses the fonts installed on the machine, so it looks slightly different on each OS.
|
|
101
|
+
- HTML documents cannot be exported. Printing must finish within 60 seconds.
|
|
102
|
+
|
|
118
103
|
## Where the state is stored, and stopping
|
|
119
104
|
|
|
120
105
|
- The state (open documents, revisions, questions and answers) is stored here. Change it with `VDE_OPEN_HOME`.
|
|
121
106
|
- macOS: `~/Library/Application Support/vde-open`
|
|
122
107
|
- Linux: `$XDG_STATE_HOME/vde-open` (or `~/.local/state/vde-open` if unset)
|
|
123
108
|
- Windows: `%LOCALAPPDATA%\vde-open`
|
|
124
|
-
- Stop the daemon with `vo daemon stop
|
|
125
|
-
- Management UI preferences such as the color theme and the view mode are stored in the browser.
|
|
109
|
+
- Stop the daemon with `vo daemon stop`, and check it with `vo daemon status`.
|
|
110
|
+
- Management UI preferences such as the color theme and the view mode are stored in the browser.
|
|
126
111
|
|
|
127
112
|
## Asking a person and getting answers
|
|
128
113
|
|
|
@@ -132,7 +117,7 @@ vo feedback wait <requestId> --timeout 120 --json
|
|
|
132
117
|
vo feedback ack <requestId> --submission-id <id> --json
|
|
133
118
|
```
|
|
134
119
|
|
|
135
|
-
The person answers in the answer panel of the management UI. The answers are submitted only when they press "Send answers to the agent"
|
|
120
|
+
The person answers in the answer panel of the management UI. The answers are submitted only when they press "Send answers to the agent"; draft answers are never returned to the agent. Do not use this to collect secrets such as passwords or API keys.
|
|
136
121
|
|
|
137
122
|
## Troubleshooting
|
|
138
123
|
|
|
@@ -143,27 +128,44 @@ The person answers in the answer panel of the management UI. The answers are sub
|
|
|
143
128
|
| Exit code 8 (cannot connect to or start the daemon) | Check with `vo daemon status`, and look for leftover files with `vo doctor` |
|
|
144
129
|
| Images or CSS are not shown | Open "Differences from the original document" and register them with `--assets-root` or `--asset` |
|
|
145
130
|
| Search does not find a document | Check with `vo list --json` that the document is open and its `searchState` is `ready` |
|
|
131
|
+
| Export PDF says Google Chrome or Microsoft Edge is needed | Install Chrome or Edge 131 or later, or set `VDE_OPEN_BROWSER` to the absolute path of a Chromium-based browser and run `vo daemon restart` |
|
|
146
132
|
|
|
147
133
|
## Verified scope
|
|
148
134
|
|
|
149
135
|
| Scope | Status |
|
|
150
136
|
|---|---|
|
|
151
|
-
| macOS (
|
|
152
|
-
| Linux and macOS on CI (GitHub Actions `ubuntu-latest` and `macos-latest`, Node.js 24.21.0) | Verified (format, lint, typecheck, unit/integration, build, pack, and e2e in Chromium, Firefox, and WebKit; `.github/workflows/ci.yml`) |
|
|
137
|
+
| Linux and macOS on CI (GitHub Actions `ubuntu-latest` and `macos-latest`, Node.js 24.21.0) | Verified (format, lint, typecheck, unit/integration, build, pack, e2e; `.github/workflows/ci.yml`) |
|
|
153
138
|
| Windows on CI (`windows-latest`, Node.js 24.21.0) | Verified: build, pack smoke (install, both bins, IPC, starting and stopping the daemon, JSON output, the UI and workers), and the daemon and document integration tests. The other unit and integration tests and the e2e tests are not run on Windows |
|
|
154
|
-
| Browsers
|
|
155
|
-
|
|
|
156
|
-
| Markdown syntax | As described in "Markdown display limits" above. Full CommonMark and GFM are not verified |
|
|
139
|
+
| Browsers | Chromium (Playwright's Chrome Headless Shell): the full suite is verified. Firefox and WebKit (Playwright 1.63.0): the view isolation, CSP, HTML bridge, and authentication tests (`pnpm test:e2e:cross`) are verified. Other UI interactions in Firefox and WebKit (search, answer panel, narrow screens, a list of 1,000 documents) are not verified |
|
|
140
|
+
| PDF export | macOS (development machine): verified with Google Chrome 154 and Microsoft Edge 154. Linux on CI: verified with the runner's Google Chrome (e2e). Windows: printing with a real browser is not verified (the pack smoke test checks rendering the print document) |
|
|
157
141
|
|
|
158
142
|
More details: [docs/performance.md](docs/performance.md) (measurements), [docs/architecture.md](docs/architecture.md) and [docs/security-model.md](docs/security-model.md) (design). Development records (in Japanese): [docs/implementation-status.md](docs/implementation-status.md), [docs/dependency-validation.md](docs/dependency-validation.md), and [docs/adr/](docs/adr/).
|
|
159
143
|
|
|
144
|
+
## Developing with a linked CLI
|
|
145
|
+
|
|
146
|
+
From the repository root, build once, link the CLI package globally, and start the watcher:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
pnpm install --frozen-lockfile
|
|
150
|
+
pnpm build
|
|
151
|
+
cd apps/cli
|
|
152
|
+
bun link
|
|
153
|
+
bun link -g vde-open
|
|
154
|
+
cd ../..
|
|
155
|
+
pnpm build:watch
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`build:watch` rebuilds when the sources, the build configuration, or the packaged files change; a failed build keeps the last successful output. The next linked CLI invocation uses the new build, but the watcher does not restart your daemon: run `vo daemon restart`, then `vo ui`. Restarting keeps registered documents and saved answers, but changes the UI address and invalidates earlier browser sessions and interactive HTML permissions.
|
|
159
|
+
|
|
160
|
+
For frequent UI changes, use `pnpm dev` instead. It runs the daemon from source with a separate `.dev-home` and serves the UI with Vite HMR. It does not rebuild the linked CLI or restart the backend when its source changes. To run CLI commands against it, set `VDE_OPEN_HOME` to the absolute path of `.dev-home` (for example, `VDE_OPEN_HOME="$PWD/.dev-home" vo list` from the repository root).
|
|
161
|
+
|
|
160
162
|
## Releasing
|
|
161
163
|
|
|
162
|
-
Releases are published to npm
|
|
164
|
+
Releases are published to npm from GitHub Actions with trusted publishing (OIDC) and provenance. No npm token is stored: the trusted publisher on npmjs.com is this repository's `publish.yml`, and publishing with tokens is disallowed.
|
|
163
165
|
|
|
164
166
|
1. Update `version` in `apps/cli/package.json` and commit it to `main`.
|
|
165
|
-
2. Push a tag for that version: `git tag
|
|
166
|
-
3. `.github/workflows/publish.yml` checks that the tag matches the version, runs the checks and the pack smoke test, and publishes the tarball
|
|
167
|
+
2. Push a tag for that version: `git tag v<version> && git push origin v<version>`.
|
|
168
|
+
3. `.github/workflows/publish.yml` checks that the tag matches the version, runs the checks and the pack smoke test, and publishes the tarball.
|
|
167
169
|
|
|
168
170
|
## License
|
|
169
171
|
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as decodeStateFile, D as daemonEntryPath, E as resolveStateRoot, O as referencedBlobs, S as renameWithRetry, T as resolveRuntimeLocation, a as DAEMON_LOCK_NAME, b as proofMatches, c as readIpcKey, d as inspectOwner, f as readCurrentLock, g as encodeFrame, h as FrameDecoder, i as requirePrivateDirectoryIfExists, k as version, l as readPointer, m as systemProcessProbe, n as ensurePrivateDirectory, o as POINTER_FILE, p as releaseLock, r as inspectPrivateDirectory, s as START_LOCK_NAME, t as startDaemon, u as acquireLock, v as computeProof, w as currentPathEnvironment, x as removeWithRetry, y as createNonce } from "./main-
|
|
3
|
-
import { A as successEnvelope, C as VdeError, D as ExitCode, E as isVdeError, O as envelopeSchema, T as isErrorCode, Y as LIMITS, k as errorEnvelope, w as exitCodeForError } from "./search-index-
|
|
2
|
+
import { C as decodeStateFile, D as daemonEntryPath, E as resolveStateRoot, O as referencedBlobs, S as renameWithRetry, T as resolveRuntimeLocation, a as DAEMON_LOCK_NAME, b as proofMatches, c as readIpcKey, d as inspectOwner, f as readCurrentLock, g as encodeFrame, h as FrameDecoder, i as requirePrivateDirectoryIfExists, k as version, l as readPointer, m as systemProcessProbe, n as ensurePrivateDirectory, o as POINTER_FILE, p as releaseLock, r as inspectPrivateDirectory, s as START_LOCK_NAME, t as startDaemon, u as acquireLock, v as computeProof, w as currentPathEnvironment, x as removeWithRetry, y as createNonce } from "./main-C3SHFgNa.js";
|
|
3
|
+
import { A as successEnvelope, C as VdeError, D as ExitCode, E as isVdeError, O as envelopeSchema, T as isErrorCode, Y as LIMITS, k as errorEnvelope, w as exitCodeForError } from "./search-index-B7DqaWh6.js";
|
|
4
4
|
import fs, { fstatSync } from "node:fs";
|
|
5
5
|
import { lstat, readFile, readdir, stat as stat$1, writeFile } from "node:fs/promises";
|
|
6
6
|
import path, { join, resolve } from "node:path";
|
package/dist/daemon.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { k as version, t as startDaemon, w as currentPathEnvironment } from "./main-
|
|
2
|
-
import { E as isVdeError } from "./search-index-
|
|
1
|
+
import { k as version, t as startDaemon, w as currentPathEnvironment } from "./main-C3SHFgNa.js";
|
|
2
|
+
import { E as isVdeError } from "./search-index-B7DqaWh6.js";
|
|
3
3
|
//#region src/daemon.ts
|
|
4
4
|
function notifyParent(message) {
|
|
5
5
|
if (!process.send) return;
|