nexvora 0.1.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.
Files changed (3) hide show
  1. package/README.md +144 -0
  2. package/bin/nexvora.js +77 -0
  3. package/package.json +41 -0
package/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # nexvora
2
+
3
+ One binary for everything NexVora: the **MCP server**, the **CLI**, and the
4
+ **donor daemon**. One install, one login, different commands.
5
+
6
+ ```bash
7
+ npm install -g nexvora
8
+ ```
9
+
10
+ That is the only install command. The native engine ships inside this package
11
+ (via a per-platform optional dependency); `npm` downloads only the binary for
12
+ your OS/CPU. No second package, no separate daemon to install.
13
+
14
+ ## Quick start
15
+
16
+ ```bash
17
+ npm install -g nexvora
18
+ nexvora "summarise the file at ./report.md" # first run opens your browser to log in once
19
+ ```
20
+
21
+ For end-to-end-encrypted task results that you can fetch later (and that the
22
+ platform can never read), set an **encryption passphrase** once:
23
+
24
+ ```bash
25
+ nexvora vault setup # prompts for a passphrase; creates + caches your key
26
+ ```
27
+
28
+ That's it. Everything else is just a different first word.
29
+
30
+ ## One command does each job
31
+
32
+ ```bash
33
+ nexvora "summarise RFC 9110" # one-shot: run a prompt, get the answer, done
34
+ cat notes.txt | nexvora # prompt from stdin
35
+ nexvora donor # join the donor pool (long-running)
36
+ nexvora mcp # MCP server over stdio (for Claude Code / Cursor / etc.)
37
+ nexvora vault setup|unlock|lock # manage your encryption vault (see below)
38
+ nexvora logout # clear local credentials
39
+ nexvora daemon stop # stop the background user daemon
40
+ ```
41
+
42
+ You never run a separate `login` step. The **first** command that needs an
43
+ account opens your browser for a one-time approval (OAuth Device Grant) and
44
+ stores the token in your OS keychain. Every mode shares that one login.
45
+
46
+ ### MCP host config (zero extra commands)
47
+
48
+ Point your MCP host at the same binary — `npx` installs it on first use:
49
+
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "nexvora": { "command": "npx", "args": ["-y", "nexvora", "mcp"] }
54
+ }
55
+ }
56
+ ```
57
+
58
+ After a global install you can use `{ "command": "nexvora", "args": ["mcp"] }`.
59
+
60
+ Tasks submitted from an MCP host run on a donor **with your local project
61
+ context** (CLAUDE.md, your MCP servers, hooks) and are end-to-end encrypted.
62
+ `nexvora_submit_task` returns immediately with a Task ID; fetch the answer with
63
+ `nexvora_task_result` (it streams the output so far while the task is still
64
+ running, and serves the final result even after a daemon restart once your vault
65
+ is unlocked).
66
+
67
+ ## Encryption vault (end-to-end results)
68
+
69
+ Your task **prompt and result** are sealed so the platform can't read them. The
70
+ key that opens them is protected by a passphrase that never leaves your machine.
71
+
72
+ ```bash
73
+ nexvora vault setup # first time: choose a passphrase, creates the vault
74
+ nexvora vault unlock # on a new device: re-derive + cache the key
75
+ nexvora vault lock # drop the cached key from the OS keychain
76
+ ```
77
+
78
+ - The passphrase is **separate** from your account login (the daemon never sees
79
+ your account password — it logs in via Device Grant).
80
+ - **Account recovery is ON by default**: if you forget the passphrase, an admin
81
+ can recover your key via escrow on a verified, audited request. Turn it off for
82
+ maximum privacy (then a lost passphrase means lost history).
83
+
84
+ ## Sessions: single vs long-running
85
+
86
+ Your **login** (the rotating refresh token in the keychain) persists until you
87
+ `logout`. The single-vs-long-running choice controls the **session key** — the
88
+ ephemeral per-task crypto material — and how long the background daemon lives.
89
+
90
+ | Mode | Session key | Idle timeout |
91
+ |------|-------------|--------------|
92
+ | One-shot (`nexvora "…"`) | created, torn down after the task | short (daemon quits soon after) |
93
+ | Donor (`nexvora donor`) | per task you serve, per direction | long-running |
94
+ | MCP (`nexvora mcp`) | warm across tool calls | 10 min (keeps the daemon warm) |
95
+
96
+ - Override the idle window: `nexvora-daemon --mode user --idle 1800` (seconds), or
97
+ the `NEXVORA_IDLE_TIMEOUT_SECONDS` env var. `0` keeps the daemon up until
98
+ `nexvora daemon stop`.
99
+ - End a foreground task immediately with Ctrl-C; stop the background daemon with
100
+ `nexvora daemon stop`.
101
+
102
+ ## Admin commands
103
+
104
+ ```bash
105
+ nexvora escrow init # create + install the platform escrow key (once)
106
+ nexvora dispute open <delegation> # decrypt a disputed result via escrow (audited)
107
+ ```
108
+
109
+ Both prompt for the admin credential locally; the server never decrypts.
110
+
111
+ ## Updating
112
+
113
+ ```bash
114
+ npm install -g nexvora@latest # or: npm update -g nexvora
115
+ ```
116
+
117
+ The native binary updates with the package. Your login and vault stay in the OS
118
+ keychain across updates — no re-login or re-setup needed.
119
+
120
+ ## How it ships (for maintainers)
121
+
122
+ This package is a small launcher (`bin/nexvora.js`) that resolves and execs the
123
+ native binary. The binary lives in one of:
124
+
125
+ `@nexvora/cli-darwin-arm64`, `@nexvora/cli-darwin-x64`,
126
+ `@nexvora/cli-linux-x64`, `@nexvora/cli-win32-x64`
127
+
128
+ each gated by `os`/`cpu` so npm installs exactly one. Each platform package
129
+ carries two binaries — `nexvora` (the entry point the launcher execs) and
130
+ `nexvora-daemon` (the engine it finds as a sibling).
131
+
132
+ **Releasing** (see `docs/operations/release-and-deploy.md`): push a tag
133
+ `nexvora-v<version>`. CI (`.github/workflows/nexvora-cli-release.yml`)
134
+ cross-compiles all four targets, runs `scripts/package-binaries.mjs` to stage the
135
+ binaries + sync versions, publishes the platform packages first, then this
136
+ launcher last (`npm publish --provenance`).
137
+
138
+ `@nexvora/mcp-server` (the TypeScript server) keeps working as before; pass
139
+ `--native` or `NEXVORA_MCP_NATIVE=1` to make it delegate to the native
140
+ `nexvora mcp` during cutover.
141
+
142
+ ## License
143
+
144
+ UNLICENSED © NexVora
package/bin/nexvora.js ADDED
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ /**
5
+ * Thin launcher for the native `nexvora` binary.
6
+ *
7
+ * The real engine (auth + OS keychain, MCP stdio server, CLI, donor daemon,
8
+ * encrypted tunnel) is a single Rust binary. It ships in exactly one per-platform
9
+ * npm package (`@nexvora/cli-<os>-<cpu>`), each gated by package.json `os`/`cpu`
10
+ * so npm installs only the one matching the host. This launcher resolves that
11
+ * binary and execs it transparently — argv, stdio, signals, and exit code all
12
+ * pass straight through, so `nexvora mcp` speaks MCP over stdio with no
13
+ * interference, and Ctrl-C reaches the binary directly.
14
+ *
15
+ * It is intentionally tiny and does NO work itself: one command — `nexvora` —
16
+ * is all the user ever runs; the binary handles first-run login on its own.
17
+ */
18
+
19
+ const { spawn } = require("node:child_process");
20
+
21
+ /** os-cpu -> per-platform package that carries the prebuilt binary. */
22
+ const PLATFORM_PACKAGES = {
23
+ "darwin-arm64": "@nexvora/cli-darwin-arm64",
24
+ "darwin-x64": "@nexvora/cli-darwin-x64",
25
+ "linux-x64": "@nexvora/cli-linux-x64",
26
+ "win32-x64": "@nexvora/cli-win32-x64",
27
+ };
28
+
29
+ function fail(message) {
30
+ process.stderr.write(`nexvora: ${message}\n`);
31
+ process.exit(1);
32
+ }
33
+
34
+ function resolveBinary() {
35
+ const key = `${process.platform}-${process.arch}`;
36
+ const pkg = PLATFORM_PACKAGES[key];
37
+ if (!pkg) {
38
+ fail(
39
+ `unsupported platform ${key}.\n` +
40
+ `Supported: ${Object.keys(PLATFORM_PACKAGES).join(", ")}.`,
41
+ );
42
+ }
43
+ const exe = process.platform === "win32" ? "nexvora.exe" : "nexvora";
44
+ try {
45
+ return require.resolve(`${pkg}/bin/${exe}`);
46
+ } catch {
47
+ fail(
48
+ `the native binary for ${key} is missing.\n` +
49
+ `Its package '${pkg}' was not installed — usually because optional\n` +
50
+ `dependencies were skipped. Reinstall with them enabled:\n` +
51
+ ` npm install -g nexvora\n` +
52
+ `(remove any --no-optional / --omit=optional flag, and check proxy settings).`,
53
+ );
54
+ }
55
+ }
56
+
57
+ const child = spawn(resolveBinary(), process.argv.slice(2), { stdio: "inherit" });
58
+
59
+ // Forward termination signals to the binary so long-lived modes (donor, mcp)
60
+ // shut down cleanly and tear down the session key (L3) on the way out.
61
+ for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) {
62
+ process.on(signal, () => {
63
+ if (!child.killed) {
64
+ child.kill(signal);
65
+ }
66
+ });
67
+ }
68
+
69
+ child.on("error", (err) => fail(err.message));
70
+ child.on("exit", (code, signal) => {
71
+ if (signal) {
72
+ // Re-raise so the parent reports the same termination cause.
73
+ process.kill(process.pid, signal);
74
+ return;
75
+ }
76
+ process.exit(code ?? 1);
77
+ });
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "nexvora",
3
+ "version": "0.1.0",
4
+ "description": "NexVora — one binary for the MCP server, CLI, and donor daemon. Single login, run anything.",
5
+ "keywords": [
6
+ "nexvora",
7
+ "mcp",
8
+ "model-context-protocol",
9
+ "claude",
10
+ "cli",
11
+ "donor",
12
+ "ai"
13
+ ],
14
+ "license": "UNLICENSED",
15
+ "bin": {
16
+ "nexvora": "bin/nexvora.js"
17
+ },
18
+ "files": [
19
+ "bin",
20
+ "README.md"
21
+ ],
22
+ "engines": {
23
+ "node": ">=18"
24
+ },
25
+ "//": "The actual native (Rust) binary ships in exactly one of these per-platform packages; npm installs only the one matching the user's os/cpu (see each package's os/cpu fields). bin/nexvora.js resolves and execs it.",
26
+ "optionalDependencies": {
27
+ "@nexvora/cli-darwin-arm64": "0.1.0",
28
+ "@nexvora/cli-darwin-x64": "0.1.0",
29
+ "@nexvora/cli-linux-x64": "0.1.0",
30
+ "@nexvora/cli-win32-x64": "0.1.0"
31
+ },
32
+ "publishConfig": {
33
+ "access": "public",
34
+ "registry": "https://registry.npmjs.org/"
35
+ },
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/buntythecoder/nexvora-backend.git",
39
+ "directory": "packages/nexvora"
40
+ }
41
+ }