@mmmbuto/nexuscrew 0.8.0 → 0.8.3

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
@@ -16,7 +16,7 @@ panes, windows. tmux does the work; the browser is just a faithful client.
16
16
 
17
17
  ---
18
18
 
19
- ## What it is (v0.8 "Many Nodes, Many Monitors")
19
+ ## What it is (v0.8.3 "Simple and Clean")
20
20
 
21
21
  - Runs a small server on the host where your tmux sessions live.
22
22
  - Each attach spawns a real PTY running `tmux attach` and bridges its bytes over a WebSocket
@@ -27,9 +27,9 @@ panes, windows. tmux does the work; the browser is just a faithful client.
27
27
  - **Multi-window decks**: named workspaces at `/deck/<name>` — one browser window per
28
28
  monitor, each with its own remembered tile layout. The focused tile is the size owner;
29
29
  everything else attaches with `ignore-size`.
30
- - **Multi-node**: register other hosts as nodes over dedicated restricted SSH tunnels and
31
- see their tmux fleets in the same UI. Per-node groups, remote attach, and file exchange
32
- all travel through a single-origin `/node/<name>` proxy using one local token.
30
+ - **Multi-node**: connect existing NexusCrew installations through the SSH configuration you
31
+ already control and see their tmux fleets in the same UI. Per-node groups, remote attach,
32
+ file exchange, and Fleet management travel through a scoped single-origin route.
33
33
  - **Settings and wizard**: manage roles, nodes, token rotation, and service regeneration
34
34
  from the UI; a skippable first-run wizard guides initial setup.
35
35
  - **Session lifecycle from the UI**: create sessions (name + cwd + an allowlisted preset)
@@ -62,11 +62,19 @@ over a real PTY. On the right, a `codex-vl` session running inside the browser c
62
62
  ## Fleet integration
63
63
 
64
64
  A clean install includes the built-in, schema-driven fleet manager. Its safe defaults contain
65
- only two engine templates — **Claude Native** and **Codex-VL Native** — and no cells, prompts,
65
+ three engine templates — **Claude Native**, **Codex Native**, and **Codex-VL Native** — and no cells, prompts,
66
66
  API keys, or machine-specific paths. Add cells and enable optional managed providers from the
67
- Fleet settings. Managed providers currently cover native login, Ollama Cloud Direct for Claude
68
- and Codex-VL, and Z.AI A/P for Claude. Provider secrets are read at launch from the 0600 file
69
- `~/.nexuscrew/providers.env`; API values are write-only and redacted from status and errors.
67
+ Fleet settings. The managed matrix covers Claude Code, Codex, Codex-VL, and Pi with their
68
+ documented native/local providers plus renameable custom providers. Custom Codex adapters are
69
+ Responses-only. New custom credentials are read only from the environment variable named in
70
+ the PWA; NexusCrew never stores the secret value. Existing Z.AI A/P and Ollama Cloud profiles
71
+ retain their backwards-compatible credential loading.
72
+
73
+ Managed engines expose a permission selector. New Claude engines (native, Z.AI, Ollama, or
74
+ custom) default to **Bypass permissions** and launch with
75
+ `--dangerously-skip-permissions`; choose **Standard permissions** to disable it. New Codex and
76
+ Codex-VL engines default to Standard and offer an explicit opt-in for
77
+ `--dangerously-bypass-approvals-and-sandbox`. Pi keeps its native permission behavior.
70
78
 
71
79
  Custom argv-based engines remain supported. Their command, environment, cwd, and prompt are
72
80
  validated against a strict trust boundary and launched without a shell.
@@ -111,35 +119,34 @@ channel you control**:
111
119
  ```bash
112
120
  # from your laptop/phone, tunnel the loopback port over SSH
113
121
  ssh -L 41820:127.0.0.1:41820 user@your-host
114
- # then open http://localhost:41820/#token=<token printed by the server>
122
+ # then run `nexuscrew show` on the machine where the browser is available
115
123
  ```
116
124
 
117
- autossh reverse tunnels or a VPN work the same way. A short-lived **local token** (0600 file,
118
- auto-generated, printed once at startup) is a second factor on top of your SSH/VPN gate. The
125
+ autossh reverse tunnels or a VPN work the same way. A local **authentication token** (0600 file,
126
+ auto-generated and passed directly to the browser by `nexuscrew show`) is a second factor on top of your SSH/VPN gate. The
119
127
  token travels in the URL **fragment** (`#token=…`), so it never reaches the server logs.
120
128
 
121
129
  > **Exposing the app publicly (reverse proxy, network bind, port forward to the internet) is
122
130
  > unsupported and unsafe.** The whole security model is "localhost + a tunnel you control".
123
131
 
124
- ## Multi-node (one command, many nodes)
132
+ ## Federated Hydra nodes (configured from the PWA)
125
133
 
126
- Each installation can be a **client/hub**, a reachable **node**, or both. Add a host from
127
- the hub:
134
+ Every installation is always the local node and can join other NexusCrew nodes. Open
135
+ **Settings → Nodes**, create a ten-minute pairing link/QR on one device, then paste or scan it
136
+ on the other together with an OpenSSH Host alias. That single pairing creates a reciprocal,
137
+ loopback-only link and both sides exchange a redacted topology automatically.
128
138
 
129
- ```bash
130
- nexuscrew nodes add vps --ssh user@host
131
- nexuscrew nodes test vps
132
- nexuscrew nodes up vps
133
- ```
134
-
135
- NexusCrew creates a dedicated SSH key and prints the restricted `authorized_keys` entry.
136
- Every hop remains loopback → SSH → loopback: the app never binds a public interface and
137
- does not add its own TLS layer. The hub proxy injects the remote token only server-side;
138
- the browser sees one origin and authenticates with only the hub token. `nodes test`
139
- distinguishes tunnel-down, health failure, missing token, and rejected-token states.
139
+ NexusCrew does not create SSH keys or edit `authorized_keys`. OpenSSH remains authoritative for
140
+ identity files, agents, host keys, ports, ProxyJump and forwarding policy. NexusCrew uses
141
+ `autossh` when available and otherwise its supervised `ssh`; configured links return at boot.
142
+ Pair credentials are random, per-peer and scoped only to the federated session/file surface—the
143
+ PWA token never crosses a peer link.
140
144
 
141
- For NAT-ed hosts such as phones, `nexuscrew node on` enables the reachable-node role using
142
- a reverse tunnel to a configured rendezvous host; `nexuscrew node off` disables it.
145
+ A relay controls what its peers can see. The default is the whole network; a peer can be reduced
146
+ to relay-only or a selected set. HTTP and WebSocket routing enforce that policy at every hop,
147
+ with stable instance IDs, cycle rejection and a four-hop ceiling. Session creation, terminal,
148
+ files, termination, and Fleet editing work on Local or any reachable route. Previously seen
149
+ transitive nodes remain listed as offline with their last-seen time while a relay is down.
143
150
 
144
151
  ## Install & run
145
152
 
@@ -151,9 +158,9 @@ npm install -g @mmmbuto/nexuscrew
151
158
  nexuscrew
152
159
  ```
153
160
 
154
- The first run creates a loopback-only configuration and a `systemd --user` service when
155
- systemd is available. Linux x64 and ARM64 use platform PTY prebuilds; `node-pty` remains the
156
- build-from-source fallback.
161
+ The first run creates a loopback-only configuration and starts a detached process. Run
162
+ `nexuscrew boot` only if you want a persistent `systemd --user` service. Linux x64 and ARM64
163
+ use platform PTY prebuilds; `node-pty` remains the build-from-source fallback.
157
164
 
158
165
  ### macOS (Apple Silicon or Intel)
159
166
 
@@ -163,9 +170,10 @@ npm install -g @mmmbuto/nexuscrew
163
170
  nexuscrew
164
171
  ```
165
172
 
166
- The first run installs a user LaunchAgent with an explicit Node/Homebrew PATH. The npm package
167
- selects the matching Darwin ARM64 or x64 PTY prebuild. NexusCrew is an npm/Node CLI, not an
168
- `.app`, `.pkg`, or standalone Mach-O distribution, so it does not require Developer ID signing.
173
+ The first run starts a detached process. Run `nexuscrew boot` to install a user LaunchAgent
174
+ with an explicit Node/Homebrew PATH. The npm package selects the matching Darwin ARM64 or x64
175
+ PTY prebuild. NexusCrew is an npm/Node CLI, not an `.app`, `.pkg`, or standalone Mach-O
176
+ distribution, so it does not require Developer ID signing.
169
177
 
170
178
  ### Android / Termux (ARM64)
171
179
 
@@ -176,18 +184,24 @@ npm install -g @mmmbuto/nexuscrew
176
184
  nexuscrew
177
185
  ```
178
186
 
179
- Termux uses the Android ARM64 PTY provider. Service startup uses a verified pidfile and a
180
- `~/.termux/boot/` script; install the Termux:Boot app only if you want automatic startup after
181
- reboot.
187
+ Termux uses the Android ARM64 PTY provider. The normal command starts NexusCrew in the
188
+ background and exits. `nexuscrew boot` installs the Termux:Boot script explicitly.
182
189
 
183
- On every platform, the command prints the local URL and an authenticated QR:
190
+ On every platform the first run starts the server in the background and opens the PWA wizard.
191
+ After onboarding, the same command starts or reuses it, prints a compact status and guide, and
192
+ exits:
184
193
 
185
194
  ```bash
186
- nexuscrew # smart init/start; binds 127.0.0.1:41820
187
- nexuscrew url --qr # print the authenticated URL again
195
+ nexuscrew # background start; opens only on first run
196
+ nexuscrew show # background start when needed + open the authenticated PWA
197
+ nexuscrew show token # print the clickable authenticated URL; do not open a browser
198
+ nexuscrew boot # opt in to startup persistence
199
+ nexuscrew boot off # disable startup persistence, keep the current run alive
188
200
  ```
189
201
 
190
- Then tunnel in (see above) and open the printed URL with `#token=…`.
202
+ The preferred port is `41820`. If it is occupied by another process, NexusCrew selects the
203
+ next free loopback port and updates its configuration. If the configured port already hosts
204
+ the same authenticated NexusCrew instance, it is reused.
191
205
 
192
206
  Env knobs: `NEXUSCREW_PORT` (default 41820), `NEXUSCREW_CONFIG_FILE`,
193
207
  `NEXUSCREW_TOKEN_FILE`, `NEXUSCREW_FILES_ROOT`, `NEXUSCREW_TMUX`,
@@ -197,25 +211,18 @@ resolved PTY provider at startup.
197
211
  ## CLI
198
212
 
199
213
  ```
200
- nexuscrew smart-up: init (zero questions) if needed start → URL + QR
201
- nexuscrew start | up start the service (systemd --user / launchd / nohup+pidfile)
202
- nexuscrew stop | down stop the service (service manager / verified pidfile)
203
- nexuscrew status [--json] platform, service, port, url, roles (client/node), nodes
204
- nexuscrew url [--qr] reprint the full URL with #token (+ scannable QR) — token shown ONLY here
205
- nexuscrew token rotate atomically rotate the token + restart to invalidate live sessions
206
- nexuscrew logs [-f] journalctl --user -u nexuscrew (linux) / logfile (mac, termux); -f follows
207
- nexuscrew doctor self-check: node, tmux, PTY, service, boot, token perms (exit 1 on problems)
208
- nexuscrew mcp stdio MCP server for AI sessions (notify / ask / send file / status)
209
- nexuscrew update npm i -g @mmmbuto/nexuscrew@latest + restart if active
210
- nexuscrew init [--port N] explicit setup (detect + config + token + service)
211
- nexuscrew nodes add <name> --ssh user@host [--remote-port N] [--key path]
212
- nexuscrew nodes list | remove <name> | test <name> | up|down|restart <name> | set-token <name>
213
- nexuscrew node on|off reachable-node role (reverse tunnel to a rendezvous)
214
+ nexuscrew background start; first run opens the PWA wizard
215
+ nexuscrew show start when needed and open the authenticated PWA
216
+ nexuscrew show token print the clickable authenticated URL without opening it
217
+ nexuscrew boot enable startup at boot (`boot off|status` are also available)
218
+ nexuscrew doctor local diagnostics (exit 1 when a required check fails)
219
+ nexuscrew help concise command help
220
+ nexuscrew version installed version
214
221
  ```
215
222
 
216
- The token is **never** printed by `status`, `logs`, `smart-up` or any service output — it appears
217
- only in `nexuscrew url` (and, embedded, in the QR). `nexuscrew url --qr` is the killer feature on
218
- Termux: scan it with the phone to open the tunnelled URL already authenticated.
223
+ All configuration and lifecycle operations live in the PWA. Internal service-manager and MCP
224
+ entry points are intentionally not part of the public CLI workflow. The token is never printed
225
+ by normal startup, help, doctor, or service output.
219
226
 
220
227
  ## MCP bridge
221
228
 
@@ -273,13 +280,12 @@ holding.** On a screen smaller than the session you'll see a clipped view (expec
273
280
  ```bash
274
281
  npm test # node --test (config, tmux list, pty attach smoke, ws bridge, token)
275
282
  npm run build # builds the frontend into frontend/dist
276
- node bin/nexuscrew.js
283
+ node bin/nexuscrew.js serve
277
284
  ```
278
285
 
279
286
  ## Status
280
287
 
281
- v0.8.0 is the current release on both **`latest`** and **`next`**, including Linux,
282
- macOS, and Android/Termux support.
288
+ The current stable release is **v0.8.3**, published on npm under the **`latest`** dist-tag.
283
289
 
284
290
  ## License
285
291
 
package/bin/nexuscrew.js CHANGED
@@ -1,7 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
- // NexusCrew CLI dispatcher (portable). Subcomandi: init / serve / start / stop / status.
3
+ // The normal product surface is the PWA. `nexuscrew` starts it in background;
4
+ // `nexuscrew show` starts it when needed and opens it.
4
5
  const { dispatch } = require('../lib/cli/commands.js');
5
- const r = dispatch(process.argv.slice(2));
6
- // serve tiene il processo vivo (server.listen); gli altri comandi escono.
7
- if (!r || !r.keepAlive) process.exit((r && r.code) || 0);
6
+ Promise.resolve(dispatch(process.argv.slice(2)))
7
+ .then((r) => {
8
+ if (!r || !r.keepAlive) process.exitCode = (r && r.code) || 0;
9
+ })
10
+ .catch((e) => {
11
+ process.stderr.write(`nexuscrew: ${String((e && e.message) || e)}\n`);
12
+ process.exitCode = 1;
13
+ });