@mmmbuto/nexuscrew 0.8.35 → 0.8.37

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
@@ -3,550 +3,139 @@
3
3
  [![npm](https://img.shields.io/npm/v/@mmmbuto/nexuscrew?style=flat-square&logo=npm&color=cb3837)](https://www.npmjs.com/package/@mmmbuto/nexuscrew)
4
4
  [![license](https://img.shields.io/badge/license-Apache--2.0-blue?style=flat-square)](LICENSE)
5
5
  [![node](https://img.shields.io/badge/node-%3E%3D18-339933?style=flat-square&logo=node.js&logoColor=white)](https://nodejs.org)
6
- [![platforms](https://img.shields.io/badge/platforms-linux%20%C2%B7%20macos%20%C2%B7%20android-555?style=flat-square)](#platform-support)
6
+ [![platforms](https://img.shields.io/badge/platforms-linux%20%C2%B7%20macos%20%C2%B7%20android-555?style=flat-square)](#platforms)
7
7
 
8
- NexusCrew is a local-first web control plane for tmux sessions and AI CLI workers. It streams
9
- real PTYs to a browser, organizes sessions into persistent decks, and connects multiple
10
- NexusCrew installations through SSH without replacing tmux or your existing SSH setup.
8
+ **Your tmux fleet. Everywhere.**
9
+
10
+ NexusCrew turns live tmux sessions, AI CLI workers and connected machines into
11
+ one local-first browser control plane. Your terminals stay real, your tools
12
+ stay yours, and your infrastructure stays under your control.
11
13
 
12
14
  <p align="center">
13
- <img src="docs/img/fleet-deck-desktop.png" width="960" alt="NexusCrew desktop interface with multiple live tmux sessions arranged in a deck">
15
+ <img src="docs/img/fleet-deck-desktop.png" width="960" alt="NexusCrew desktop deck with multiple live tmux sessions">
14
16
  </p>
15
17
 
16
- NexusCrew binds to `127.0.0.1`, authenticates the PWA with a local token, and leaves session
17
- ownership to tmux. It has no hosted control service, user account system, or public network
18
- listener.
19
-
20
- ## Overview
21
-
22
- | Area | What NexusCrew provides |
23
- |---|---|
24
- | Terminal | Real PTY attachment to live tmux sessions through WebSocket and xterm.js |
25
- | Workspaces | Named decks, tiled desktop layouts, mobile session view, saved ordering, pins and per-cell composer state |
26
- | Fleet | Reusable cells, engines, providers, models, permission policies, prompts, boot state and live working status |
27
- | Nodes | One-link pairing and owner-qualified routing over supervised OpenSSH connections |
28
- | Operations | Background service, boot integration, diagnostics, stable npm updates and selective backup |
29
- | AI integration | A stdio MCP bridge for operator communication, deck discovery and cell-to-cell delivery |
30
-
31
- The browser is a client, not the session host:
32
-
33
- ```text
34
- Browser PWA
35
- │ authenticated HTTP + WebSocket on loopback
36
-
37
- NexusCrew ── real PTY ── tmux sessions
38
-
39
- ├── supervised OpenSSH ── remote NexusCrew nodes
40
-
41
- └── stdio MCP bridge ── Claude Code / Codex / Codex-VL / Pi
42
- ```
43
-
44
- ## Install
45
-
46
- ### Requirements
18
+ ## One control plane. Every screen.
47
19
 
48
- - Node.js 18 or newer
49
- - tmux 3.4 or newer
50
- - OpenSSH client (`ssh`) for node connections and a clean diagnostic result
51
- - Linux x64/ARM64, macOS x64/ARM64, or Android ARM64 through Termux
20
+ The desktop deck keeps the whole fleet visible. Open any cell from a phone and
21
+ NexusCrew gives the same live tmux session a touch-first terminal without
22
+ moving the session away from its host.
52
23
 
53
- NexusCrew ships scriptless PTY prebuilds for the supported targets. A normal global install
54
- does not need a compiler or native install-script approval.
55
-
56
- ### Linux
57
-
58
- Install Node.js, tmux and OpenSSH with your distribution package manager, then:
59
-
60
- ```bash
61
- npm install -g @mmmbuto/nexuscrew
62
- nexuscrew
63
- ```
64
-
65
- ### macOS
66
-
67
- ```bash
68
- brew install node tmux
69
- npm install -g @mmmbuto/nexuscrew
70
- nexuscrew
71
- ```
24
+ <p align="center">
25
+ <img src="docs/img/session-mobile.png" width="360" alt="NexusCrew mobile terminal connected to a real tmux session with touch controls">
26
+ <br>
27
+ <sub><strong>Real tmux on mobile.</strong> Terminal keys, dictation and file handoff stay within reach.</sub>
28
+ </p>
72
29
 
73
- ### Android / Termux
30
+ ## Install in 30 seconds
74
31
 
75
32
  ```bash
76
- pkg update
77
- pkg install nodejs-lts tmux openssh
78
33
  npm install -g @mmmbuto/nexuscrew
79
34
  nexuscrew
80
35
  ```
81
36
 
82
- The first run creates the loopback-only runtime, starts it in the background, opens the PWA,
83
- and presents the setup wizard. Later runs reuse the configured service, print a compact status,
84
- and exit.
85
-
86
- On Android, `nexuscrew doctor` also verifies the Termux execution bridge used by current app
87
- builds. NexusCrew carries forward only a validated `libtermux-exec` preload from the active
88
- Termux prefix; arbitrary loader injection remains excluded from Fleet environments.
37
+ The first run creates a loopback-only runtime, starts it in the background and
38
+ opens the authenticated PWA.
89
39
 
90
- Package upgrades self-repair installed Termux:Boot scripts before the runtime or Fleet can
91
- create tmux from a replaceable npm directory. NexusCrew also discards a tunnel pidfile when
92
- Android has reused its PID under another app UID; it never signals that foreign process and
93
- restarts only the configured OpenSSH supervisor. These repairs preserve the local port, token,
94
- pairing data and existing boot on/off choice.
40
+ | Platform | Prerequisites |
41
+ |---|---|
42
+ | Linux | Node.js 18+, tmux 3.4+, OpenSSH |
43
+ | macOS | `brew install node tmux` |
44
+ | Android / Termux | `pkg install nodejs-lts tmux openssh` |
95
45
 
96
- The preferred port is `41820`. If another process owns it, NexusCrew selects the next free
97
- loopback port and records the result.
46
+ NexusCrew ships scriptless PTY prebuilds for Linux x64/ARM64, macOS x64/ARM64
47
+ and Android ARM64. A normal global install does not need a compiler or native
48
+ install-script approval.
98
49
 
99
- ## CLI
50
+ [Full installation guide →](docs/INSTALLATION.md)
100
51
 
101
- The PWA remains the visual control surface, while the CLI exposes the complete peer workflow for
102
- headless hosts and VPS installations.
52
+ ## What NexusCrew gives you
103
53
 
104
- | Command | Purpose |
105
- |---|---|
106
- | `nexuscrew` | Start or reuse the background runtime and print a short status |
107
- | `nexuscrew init [--dry-run] [--port PORT]` | Initialize missing local stores idempotently or preview the operation |
108
- | `nexuscrew show` | Start when needed and open the authenticated PWA |
109
- | `nexuscrew show token` | Print the authenticated browser link without opening it |
110
- | `nexuscrew status` | Show service, port, role and node status |
111
- | `nexuscrew stop` | Stop NexusCrew and its managed tunnels without stopping tmux sessions |
112
- | `nexuscrew restart` | Restart NexusCrew and restore autostart node links without stopping tmux |
113
- | `nexuscrew boot` | Enable startup persistence |
114
- | `nexuscrew boot off` | Disable startup persistence while leaving the current runtime alive |
115
- | `nexuscrew doctor` | Check Node, PTY, tmux, SSH, service and platform integration |
116
- | `nexuscrew nodes list [--json]` | List direct hubs, connected clients and routed read-only peers |
117
- | `nexuscrew nodes inspect <name\|nodeId>` | Inspect a peer by stable identity |
118
- | `nexuscrew nodes edit <name\|nodeId> ...` | Change the canonical label or direction-specific connection settings |
119
- | `nexuscrew nodes up\|down\|connect\|disconnect\|restart\|reconnect <name\|nodeId>` | Manage a direct node link without requiring the PWA |
120
- | `nexuscrew nodes share <name\|nodeId> on\|off` | Publish or withdraw a direct node from the authorized network |
121
- | `nexuscrew nodes remove <name\|nodeId> --yes` | Revoke/forget a direct peer after explicit confirmation |
122
- | `nexuscrew nodes invite --ssh <target>` | Create a one-time pairing link from a headless hub |
123
- | `nexuscrew nodes pair\|join` | Read a one-time pairing link from stdin and join headlessly |
124
- | `nexuscrew help` | Show command help |
125
- | `nexuscrew version` | Show the installed version |
126
-
127
- Boot integration uses a user systemd service on Linux, a LaunchAgent on macOS, and a
128
- Termux:Boot script on Android. Termux users must install the Termux:Boot app and open it once;
129
- the CLI can validate the script but cannot prove Android app activation.
130
-
131
- Cells marked `boot:true` are started when that platform boot integration runs. This is startup
132
- persistence, not a watchdog for the tmux server itself: if the entire tmux server disappears
133
- later, the boot companion is not automatically rerun.
134
-
135
- ## Fleet: cells, engines and providers
136
-
137
- A **cell** is a reusable worker definition: tmux session name, working directory, engine,
138
- model, permission policy, optional system prompt, optional Shell command and boot state. Starting
139
- a stopped cell opens the same launch sheet on desktop and mobile, so the effective settings can
140
- be reviewed before the process starts.
141
-
142
- An **engine** describes how a CLI is launched. Clean installations include these base adapters:
143
-
144
- - Claude Code
145
- - Codex
146
- - Codex-VL
147
- - Pi
148
- - Agy — Linux and macOS only (auth delegated to Agy's local login; `standard`/`unsafe` permission policies). On Android/Termux use the Shell adapter with a per-cell `agy` command.
149
- - Shell
150
-
151
- The provider catalog is scoped to the selected CLI rather than to a machine-specific setup:
152
-
153
- | CLI | Built-in provider choices |
54
+ | | |
154
55
  |---|---|
155
- | Claude Code | Anthropic, Alibaba Token Plan Personal, OpenRouter, Kimi Code, Amazon Bedrock, Google Vertex AI, Microsoft Foundry, Ollama Cloud, local Ollama, Z.AI, custom Anthropic-compatible endpoint |
156
- | Codex | OpenAI or ChatGPT login, OpenAI API, Ollama Cloud, local Ollama, LM Studio, custom OpenAI Responses endpoint |
157
- | Codex-VL | OpenAI or ChatGPT login, OpenAI API, Alibaba Token Plan Personal, OpenRouter, Ollama Cloud, local Ollama, LM Studio, custom OpenAI Responses endpoint |
158
- | Pi | Native default, Anthropic, OpenAI API, Alibaba Token Plan Personal, Codex OAuth, Gemini, GitHub Copilot, OpenRouter, Ollama, DeepSeek, Z.AI, custom provider |
159
- | Shell | Device-local interactive shell, with an optional per-cell command |
160
-
161
- Custom Codex-compatible endpoints use the real Responses wire API; NexusCrew does not silently
162
- fall back to Chat Completions. Custom argv-based engines are also supported and are launched
163
- directly without a shell after trust-boundary validation.
164
-
165
- The Shell engine resolves `$SHELL` or a trusted platform shell when the cell starts; executable
166
- paths are not stored in Fleet definitions or backups. Leaving its command empty opens an
167
- interactive login shell. A configured command is passed as one opaque argument through the
168
- private launch broker, runs once without restart supervision, and then leaves the cell stopped.
169
- Known POSIX shells use an interactive login invocation (`-lic`) so the user's configured PATH is
170
- available; custom shells retain the conservative `-lc` contract. Shell does not accept prompts,
171
- models or unsafe permission policy.
172
-
173
- OpenRouter is first-class for Claude Code and Codex-VL. Claude uses OpenRouter's Anthropic
174
- Messages compatibility endpoint, while Codex-VL uses the beta, stateless Responses endpoint
175
- with direct command-based authentication and no shell. Because provider/model compatibility can
176
- change independently, the selected OpenRouter model remains explicit. The packaged Kimi K3
177
- profile pins its one-million-token metadata instead of falling back to a smaller generic window.
178
-
179
- Kimi Code is a separate Claude Code provider for Kimi membership keys. It defaults to `k3[1m]`,
180
- uses `https://api.kimi.com/coding/`, and runs with an isolated Claude configuration so a native
181
- Anthropic account remains untouched. A Kimi Code membership key is not interchangeable with a
182
- Moonshot pay-as-you-go API key.
183
-
184
- Alibaba Token Plan Personal is a separate managed profile for Claude Code, Codex-VL and Pi. It
185
- uses only `ALIBABA_CODE_API_KEY`, defaults to `qwen3.8-max-preview`, and has no OpenAI or
186
- pay-as-you-go fallback. The npm package also includes the portable `alibaba-token-media` skill
187
- for dry-run-first Wan image/edit and HappyHorse video workflows. Claude Code, Codex, Codex-VL
188
- and Pi can invoke its dependency-free Python CLI directly; Pi is not assumed to support MCP
189
- natively. The media skill requires Python 3. Media generation always requires explicit Credit
190
- consent and never runs during installation, tests, or startup.
191
-
192
- The package also includes the portable [`fill-forms`](skills/fill-forms/SKILL.md) skill for
193
- inspecting, filling and visually validating local PDF and DOCX forms. It supports named
194
- AcroForm fields, coordinate overlays, checkboxes, character boxes and explicitly authorised
195
- signature images. Its scripts never install dependencies automatically, never overwrite the
196
- blank source and do not send documents anywhere. Canonical instructions are in English while
197
- user-facing guidance follows the user's language; field values and document wording are not
198
- translated without an explicit request. Optional Python dependencies are not bundled and remain
199
- subject to their own licences.
200
-
201
- Permission handling is explicit per cell and engine:
202
-
203
- - Claude engines can use standard permissions or `--dangerously-skip-permissions`.
204
- - Codex and Codex-VL can use standard permissions or
205
- `--dangerously-bypass-approvals-and-sandbox`.
206
- - Pi uses its native permission behavior.
207
-
208
- Provider keys are resolved on the node that launches the process. NexusCrew can use the
209
- service environment, compatible user-owned provider files, or an optional node-local
210
- write-only credential store. The PWA reports whether a variable is configured but never
211
- returns its value. Keys are excluded from Fleet definitions, backups, API responses, tmux
212
- state, process arguments, temporary files and logs.
213
-
214
- Built-in providers with a fixed variable expose a dedicated **KEY** section in the engine editor.
215
- It shows only the variable name, configured source and affected engines on the selected node.
216
- Replacing or removing a shared key warns which engines use it; the entered value is transient in
217
- the browser and is written only to the node-local credential store.
218
-
219
- ### Built-in Fleet ownership
220
-
221
- NexusCrew is the only Fleet manager. Cell and engine definitions, lifecycle, boot ownership,
222
- restart supervision and write-only credentials are all handled by the built-in runtime; no
223
- external `fleet` executable is discovered or invoked. `nexuscrew-fleet.service` is the optional
224
- NexusCrew boot companion and starts only cells marked `boot:true`.
225
-
226
- Set `NEXUSCREW_FLEET=0` to disable Fleet entirely.
227
-
228
- ## Workspaces and terminal behavior
229
-
230
- Desktop decks place multiple live terminals in a saved tiled layout. Decks remain attached to
231
- the current PWA by default; `↗` detaches one into another browser window. Session and deck order
232
- can be changed with pointer drag-and-drop or keyboard controls and is saved automatically.
233
-
234
- The top deck bar groups workspaces by owner node. Clicking a node name expands or collapses its
235
- decks; newly seen nodes start collapsed so connected-but-idle machines remain available without
236
- occupying the bar. Every deck carries a compact activity dot, and collapse choices are stored in
237
- the current browser and synchronized across its open NexusCrew windows.
238
-
239
- On mobile, locations are independently collapsible and filterable by all, pinned, active, off,
240
- or technical sessions. The same owner-qualified ordering model is used by compact and expanded
241
- desktop views. Managed terminals use the logical Fleet cell name as their visible title; tmux
242
- session and route identifiers remain technical context rather than the primary heading.
56
+ | **Live terminals** | Attach to real tmux sessions through a real PTY, WebSocket and xterm.js. |
57
+ | **Persistent workspaces** | Arrange sessions into decks with saved layouts, ordering, pins and per-cell drafts. |
58
+ | **Multi-node Fleet** | See and control authorized cells across Linux, macOS and Android nodes. |
59
+ | **AI-ready cells** | Launch Claude Code, Codex, Codex-VL, Pi, Agy or a trusted shell with explicit providers and policies. |
60
+ | **Mobile-native control** | Scroll tmux history, use terminal keys, dictate prompts and move files from a phone. |
61
+ | **Operator alerts** | Receive visual, push and optional on-device spoken notifications. |
243
62
 
244
- <p align="center">
245
- <img src="docs/img/fleet-mobile.gif" width="420" alt="NexusCrew mobile Fleet view with managed cells and session controls">
246
- </p>
247
-
248
- Terminal attachment uses `tmux attach -f ignore-size` by default. A phone or narrow browser
249
- therefore cannot resize a session held by another terminal client. Mobile controls expose
250
- copy-mode scrolling, window and pane navigation, Escape, Ctrl-C and detach. Long text and
251
- multiline prompts use the terminal application's bracketed-paste mode; clipboard images and
252
- dropped files are stored in the selected session inbox and their paths are inserted without
253
- submitting Enter.
254
-
255
- The two-row mobile key bar can also show a full-height Enter key beside Page Up/Page Down, so
256
- interactive terminal choices can be confirmed without opening the software keyboard. By default,
257
- key-bar and speech-to-text actions keep that keyboard closed, while a nearby double tap inside the
258
- terminal or a direct tap in the composer textarea explicitly opens it. The composer send button
259
- and the composer history/size controls work without focusing the textarea. **Settings → Input** can change the
260
- terminal gesture, hide the Enter key, or allow key-bar and voice actions to retain the keyboard.
261
- The key bar also has a
262
- **compact** layout (one row with an expand toggle that temporarily reveals the full key set
263
- without changing the preference). Mobile finger drags always browse tmux history, including when
264
- the attached TUI uses an alternate screen; desktop wheel events in writable alternate-screen TUIs
265
- remain application-owned Page Up/Page Down, while normal and readonly terminals use tmux scroll.
266
- These preferences are browser-local and are synchronized between open NexusCrew windows for
267
- the same origin.
268
-
269
- The input composer can expand for longer prompts. Each owner-qualified tmux cell keeps its own
270
- draft, size preference and bounded prompt history in the current browser, including safe
271
- ArrowUp/ArrowDown recall at textarea boundaries. This browser-local state is not federated or
272
- included in Fleet backups and can be cleared from Settings → System.
273
-
274
- ## Connect nodes through SSH
275
-
276
- Every installation starts as a local node. A node joins another NexusCrew installation with a
277
- single pairing link or QR code:
278
-
279
- 1. On the reachable installation, open **Settings → Nodes → Invite a node**.
280
- 2. Provide the OpenSSH target that the other device can use, such as `user@host` or a local
281
- SSH config alias. SSH ports, identities, agents, ProxyJump and host-key policy stay in the
282
- user's OpenSSH configuration.
283
- 3. On the joining device, open **Settings → Nodes**, paste the complete pairing link, and choose
284
- **Test and connect**. The link is a pairing payload; it is not a browser address to open.
285
- 4. If the portable address cannot select the correct key, open **Advanced / edit** and replace
286
- it with the SSH alias that already works from that device.
287
-
288
- Advanced settings keep the local display label separate from the local route handle. The route
289
- defaults to a readable slug plus a stable node-ID suffix, so devices that all report the hostname
290
- `localhost` still receive distinct handles. If a hub reports a collision, NexusCrew applies its
291
- deterministic suggestion and lets the device retry with the same invitation.
292
-
293
- NexusCrew creates one supervised `ssh` process for the hub connection and proves the forwarded
294
- TCP endpoint before reporting success. It does not generate SSH keys, edit `authorized_keys`,
295
- or use `autossh` as a hidden second supervisor.
296
-
297
- Newly joined devices are private by default. Enabling **Share this device through the selected
298
- hub** adds a verified reverse channel to the existing SSH process. The hub then decides whether
299
- authorized peers see the whole network, only the hub, or an explicit subset. Clients do not
300
- need direct SSH reachability to one another.
301
-
302
- Reverse ports are reserved across active and pending pairings, probed before use and protected
303
- by a persistent uniqueness check. Share is stored as desired state: failed activation rolls back
304
- to private. Deactivation first saves private intent, then asks the hub to withdraw the node over
305
- the still-live private forward, and only after that acknowledgement removes the reverse channel.
306
- If the hub cannot acknowledge the revocation, Settings refreshes to the saved private state and
307
- shows that hub reconciliation is still pending; bounded boot retries continue without claiming
308
- that remote removal already completed. A stale same-name peer or a late allocation collision
309
- returns an actionable conflict instead of silently creating a duplicate record or consuming the
310
- invitation.
311
-
312
- Private pairing is administrative inventory, not operational publication. A paired client can
313
- remain listed as **private** in Settings so it can be reconnected or shared again, but it is absent
314
- from routable topology, owner/deck bars and MCP cell/deck discovery. Temporary loss of reachability
315
- does not revoke consent: an authorized node remains visible as stale/offline until a successful
316
- authoritative refresh either restores it or confirms its withdrawal.
317
-
318
- The Share control reports desired publication separately from verified tunnel reachability. If a
319
- detached process survives an upgrade with stale `-R` arguments, **Reconnect and reconcile** applies
320
- the current checkbox state without changing consent and replaces only the verified NexusCrew
321
- supervisor when its saved command differs. The checkbox itself remains usable while disconnected.
322
-
323
- OpenSSH key restrictions still apply after global `AllowTcpForwarding` is enabled. A shared client
324
- needs its accepted hub key to allow the exact negotiated reverse listener, for example
325
- `permitlisten="127.0.0.1:44002"`; the actionable tunnel diagnostic prints the actual required port.
326
- NexusCrew never edits `authorized_keys`, so this policy remains an explicit hub-operator action.
327
-
328
- Node groups can be reordered independently in each browser from both desktop and mobile lists.
329
- Their human-readable label has one server-backed source: rename from Settings or a roster and the
330
- same canonical label appears everywhere without changing the technical route name, node identity,
331
- credentials, Share state or deck identity.
332
-
333
- For routed nodes that the current installation does not own, Settings → Nodes offers a local
334
- alias instead of a remote rename. The alias is private to the viewing installation, follows the
335
- stable instance identity and never changes or federates the remote label, route or owner.
336
-
337
- Pairing links contain a short-lived one-time invite and routing fields, but no SSH private key,
338
- provider key or PWA token. Node and deck identities remain owner-qualified across the network,
339
- and every routed HTTP or WebSocket request rechecks authorization, hop count and cycle rules.
340
-
341
- ## Access and security model
342
-
343
- NexusCrew listens only on `127.0.0.1`. To use a remote installation, bring its loopback port to
344
- your device through SSH or a VPN you control:
63
+ The browser is a client, not the session host:
345
64
 
346
- ```bash
347
- ssh -L 41820:127.0.0.1:41820 user@your-host
65
+ ```text
66
+ Browser PWA
67
+ │ authenticated HTTP + WebSocket on loopback
68
+
69
+ NexusCrew ── real PTY ── tmux sessions
70
+
71
+ ├── supervised OpenSSH ── remote NexusCrew nodes
72
+
73
+ └── stdio MCP bridge ── AI CLI workers
348
74
  ```
349
75
 
350
- Then open the authenticated link returned by `nexuscrew show token`. The token is stored in a
351
- user-only file and travels in the URL fragment (`#token=...`), so it is not sent in the initial
352
- HTTP request or written to server access logs.
353
-
354
- The security boundary is intentionally narrow:
355
-
356
- - loopback bind only; non-loopback binds are rejected
357
- - local bearer token for every API and WebSocket connection
358
- - tmux remains the session authority
359
- - OpenSSH remains the network and identity authority
360
- - provider credentials remain on the node that uses them
361
- - file operations reject traversal and symlink escapes
362
- - Fleet and federation mutations are schema-validated and ACL-checked
363
-
364
- Direct public exposure through a reverse proxy, public port forward or network bind is not a
365
- supported deployment model.
366
-
367
- ## Backup and updates
76
+ ## Local-first by design
368
77
 
369
- Settings Fleet can export and restore selected cells, system prompts and reusable engine
370
- definitions. Restore previews conflicts, supports per-item selection and reports active cells
371
- that need a restart. Current archives store working directories relative to the target user's
372
- home instead of copying device-specific absolute paths. A legacy or foreign path is shown as an
373
- explicit repair action and is never silently remapped. Archives contain credential variable
374
- names, never credential values, tokens or live tmux state.
78
+ NexusCrew has no hosted control service, required account or public listener.
79
+ It binds to `127.0.0.1`, authenticates the PWA with a local token and leaves
80
+ session ownership to tmux.
375
81
 
376
- Global npm installations can follow the stable `latest` tag automatically. NexusCrew serializes
377
- updates, verifies the new CLI and same-port runtime, and rolls back once to the exact previous
378
- version if health checks fail. It never installs prereleases from `latest` or downgrades. Update
379
- state and manual controls are available in Settings → System; set
380
- `NEXUSCREW_AUTO_UPDATE=0` to disable the scheduler.
82
+ - OpenSSH remains the network and identity authority.
83
+ - Provider credentials stay on the node that uses them.
84
+ - Pairing links contain no SSH private key, provider key or PWA token.
85
+ - File operations reject traversal and symlink escapes.
86
+ - Updates preserve tmux sessions and roll back when health checks fail.
381
87
 
382
- On Linux, generated user services use `KillMode=process` so restarting NexusCrew does not stop
383
- the shared tmux server. Lifecycle commands fail closed when that protection cannot be verified.
88
+ Remote access is intentionally carried through SSH or a VPN you control:
384
89
 
385
- ## Structured diagnostics
386
-
387
- Settings → Diagnostics shows a bounded in-memory event buffer for the local installation or an
388
- authorized routed node. Verbose collection is explicit and expires after 5, 15, 30 or 60 minutes;
389
- operational warnings and errors remain available when verbose mode is off. The view supports
390
- level/component filtering, pause, autoscroll, copy, JSON export and explicit clear.
391
-
392
- Records are structured and redacted before storage. Raw terminal content, prompts, command lines,
393
- environment values, tokens, credentials and filesystem paths are not accepted as diagnostic
394
- metadata. Fleet launch failures include only closed `code` and `phase` values so preflight,
395
- broker, tmux, readiness and client-spawn failures can be distinguished safely. The buffer is not
396
- a reader for service journals or log files.
397
-
398
- ## MCP bridge
399
-
400
- `nexuscrew mcp` exposes the local authenticated runtime as a dependency-free stdio MCP server.
401
- It is intended for AI sessions running inside managed tmux cells.
402
-
403
- | Tool | Purpose |
404
- |---|---|
405
- | `nc_notify` | Send a PWA notification to the operator |
406
- | `nc_ask` | Ask a non-blocking question and return the answer to the calling session |
407
- | `nc_send_file` | Place a file from the caller's home in its downloadable outbox |
408
- | `nc_status` | Read live tmux and Fleet status |
409
- | `nc_inbox` | List files received by the caller |
410
- | `nc_deck` | Discover owner-qualified decks containing the calling tmux session |
411
- | `nc_cells` | List authorized active and inactive Fleet cells across visible nodes |
412
- | `nc_cell_diagnostics` | Read the redacted Shell command and latest bounded start/spawn failure for one exact local cell |
413
- | `nc_send_cell` | Submit bounded text to one exact active cell returned by `nc_cells` |
414
- | `nc_identity` | Read-only identity diagnostics; callable with no session and no token |
415
-
416
- Cell delivery uses bracketed paste followed by a separate Enter. A `submitted` receipt confirms
417
- delivery to the target TUI, not acceptance or completion by its model. There is no silent
418
- offline queue.
419
-
420
- `nc_identity` returns only non-sensitive data: the `source` the caller was resolved from
421
- (`tmux`, `NEXUSCREW_MCP_SESSION`, or `missing`), boolean presence of the identity env vars,
422
- a stable `code` (`OK`, `NEXUSCREW_MCP_IDENTITY_MISSING`, `NEXUSCREW_MCP_IDENTITY_INVALID`) and
423
- a remediation hint. It never calls an HTTP API or reads the token, so it works even when the
424
- identity is missing — use it to diagnose why the identity-gated tools fail closed.
425
-
426
- Register the bridge in Claude Code:
427
-
428
- ```json
429
- {
430
- "mcpServers": {
431
- "nexuscrew": {
432
- "command": "nexuscrew",
433
- "args": ["mcp"]
434
- }
435
- }
436
- }
437
- ```
438
-
439
- Or in Codex / Codex-VL (`env_vars` allowlists variable **names** only — no values are copied
440
- into the CLI or config file):
441
-
442
- ```toml
443
- [mcp_servers.nexuscrew]
444
- command = "nexuscrew"
445
- args = ["mcp"]
446
- env_vars = ["NEXUSCREW_MCP_SESSION", "TMUX", "TMUX_PANE"]
90
+ ```bash
91
+ ssh -L 41820:127.0.0.1:41820 user@your-host
447
92
  ```
448
93
 
449
- The equivalent CLI form on a Codex-VL build that supports `--env-var` (allowlist by name, repeated):
94
+ [Security model →](docs/SECURITY.md)
450
95
 
451
- ```text
452
- codex-vl mcp add nexuscrew \
453
- --env-var NEXUSCREW_MCP_SESSION \
454
- --env-var TMUX \
455
- --env-var TMUX_PANE \
456
- -- nexuscrew mcp
457
- ```
96
+ ## Documentation
458
97
 
459
- The caller is resolved, in order, from its tmux session (`tmux display-message -p '#S'`),
460
- then from the `NEXUSCREW_MCP_SESSION` fallback, then not at all. Codex/Codex-VL launch MCP stdio
461
- processes with a cleared environment, so those clients must explicitly allowlist the identity
462
- env vars for the server to observe them; otherwise the identity-gated tools (`nc_ask`, `nc_send_file`,
463
- `nc_deck`, `nc_cell_diagnostics`, `nc_send_cell`, `nc_inbox`) stay fail-closed with a stable
464
- `NEXUSCREW_MCP_IDENTITY_*` code, while `nc_notify` degrades to an unknown sender.
465
-
466
- `nc_cell_diagnostics` accepts an exact owner-qualified ID returned by `nc_cells`, but only when
467
- that target belongs to the local node and the caller is an active local Fleet cell. It does not
468
- query remote nodes or add commands to the federated directory. The returned command is bounded
469
- and credential-redacted; the failure is a closed `{status, code, phase}` cause rather than raw
470
- stderr, paths, environment values, prompts or tokens.
471
-
472
- ## Optional MCP companions
473
-
474
- NexusCrew can work alongside separate local-first MCP servers for durable
475
- structured memory, searchable document memory, bounded worker delegation and
476
- mail access. They are optional projects rather than hidden NexusCrew
477
- dependencies: the AI should discover its existing tools first, recommend a
478
- companion only for a capability the user actually requested, and ask before
479
- installing or changing client configuration.
480
-
481
- See [MCP_COMPANIONS.md](MCP_COMPANIONS.md) for the capability guide and
482
- [`mcp-companions.json`](mcp-companions.json) for the machine-readable catalog.
483
- The npm package also includes generic [`memory`](skills/memory/SKILL.md),
484
- [`vl-msa`](skills/vl-msa/SKILL.md), [`crew`](skills/crew/SKILL.md) and
485
- [`mail-assistant`](skills/mail-assistant/SKILL.md) skills. Their instructions
486
- are written in English, while user-facing output follows the user's explicit
487
- preference or request language; Mail reply drafts follow the email thread by
488
- default.
489
-
490
- `fill-forms` is a separate bundled local document skill, not an MCP companion.
491
- It is documented in [Fleet: cells, engines and providers](#fleet-cells-engines-and-providers)
492
- and carries no automatic installation or external-service behaviour.
493
-
494
- ## Configuration
495
-
496
- Runtime state is local to the current user:
497
-
498
- | Path | Contents |
98
+ | Guide | Covers |
499
99
  |---|---|
500
- | `~/.nexuscrew/config.json` | Port, Fleet mode and runtime options |
501
- | `~/.nexuscrew/token` | Local PWA bearer token |
502
- | `~/.nexuscrew/credentials.json` | Optional node-local write-only provider store |
503
- | `~/.nexuscrew/tunnels/` | Managed SSH supervisor state and owner-only logs |
504
- | `~/NexusFiles/<session>/` | Per-session inbox and outbox |
505
-
506
- Common environment overrides include `NEXUSCREW_PORT`, `NEXUSCREW_CONFIG_FILE`,
507
- `NEXUSCREW_TOKEN_FILE`, `NEXUSCREW_FILES_ROOT`, `NEXUSCREW_TMUX`,
508
- `NEXUSCREW_FLEET=0`, `NEXUSCREW_READONLY=1`, `NEXUSCREW_AUTO_UPDATE=0`, and
509
- `NEXUSCREW_DEBUG=1`.
510
-
511
- ## Platform support
512
-
513
- | Platform | Architectures | Background integration | PTY provider |
514
- |---|---|---|---|
515
- | Linux | x64, ARM64 | systemd user service or detached runtime | packaged native prebuild |
516
- | macOS | x64, ARM64 | LaunchAgent or detached runtime | packaged native prebuild |
517
- | Android / Termux | ARM64 | detached runtime and optional Termux:Boot | Android ARM64 package |
518
-
519
- Run `nexuscrew doctor` after installation or when moving a configuration between devices. A
520
- missing OpenSSH client is a blocking diagnostic; `autossh` is reported separately and remains
521
- optional because NexusCrew supervises OpenSSH directly. The doctor also verifies that the service
522
- and shared tmux server have a resolvable stable working directory. On Termux it reports whether
523
- the tmux server inherited a trusted `termux-exec` preload; it never kills a stale server or user
524
- sessions automatically.
100
+ | [Documentation index](docs/README.md) | Start here for every guide |
101
+ | [Installation](docs/INSTALLATION.md) | Linux, macOS, Termux, first run and upgrades |
102
+ | [Fleet and terminals](docs/FLEET.md) | Cells, engines, providers, decks and mobile input |
103
+ | [Connect nodes](docs/NODES.md) | Pairing, SSH routes, sharing and routed aliases |
104
+ | [Notifications](docs/NOTIFICATIONS.md) | Toasts, Web Push and optional spoken alerts |
105
+ | [MCP bridge](docs/MCP.md) | Operator tools, cell delivery and client setup |
106
+ | [Configuration](docs/CONFIGURATION.md) | Files, environment overrides and local settings |
107
+ | [Operations](docs/OPERATIONS.md) | CLI, boot, backup, updates and diagnostics |
108
+ | [Security](docs/SECURITY.md) | Trust boundaries, tokens and credential handling |
109
+
110
+ The repository also includes [MCP companion guidance](MCP_COMPANIONS.md),
111
+ the machine-readable [`mcp-companions.json`](mcp-companions.json), and portable
112
+ skills for memory, searchable document memory, bounded worker delegation,
113
+ mail assistance and form filling.
114
+
115
+ ## Platforms
116
+
117
+ | Platform | Architectures | Background integration |
118
+ |---|---|---|
119
+ | Linux | x64, ARM64 | systemd user service or detached runtime |
120
+ | macOS | x64, ARM64 | LaunchAgent or detached runtime |
121
+ | Android / Termux | ARM64 | detached runtime and optional Termux:Boot |
122
+
123
+ Run `nexuscrew doctor` after installation or when moving configuration between
124
+ devices.
525
125
 
526
126
  ## Development
527
127
 
528
128
  ```bash
529
- npm test # isolated Node tests plus frontend tests
530
- npm run build # build the PWA into frontend/dist
129
+ npm test
130
+ npm run build
531
131
  node bin/nexuscrew.js serve
532
132
  ```
533
133
 
534
- Tests that exercise tmux use private sockets and must never attach to or terminate the
535
- operator's tmux server.
536
-
537
- ## Roadmap
538
-
539
- The current companion catalog is documentation and agent guidance only. A future optional MCP
540
- gateway could expose one NexusCrew endpoint with explicit, per-tool federation through shared
541
- nodes. Credentials and execution would remain on the owner node, with owner-qualified tool
542
- identities and read/mutate ACLs. The gateway is planned work and is **not part of this release**.
134
+ Tests that exercise tmux use private sockets and never attach to or terminate
135
+ the operator's tmux server.
543
136
 
544
137
  See [CHANGELOG.md](CHANGELOG.md) for released changes.
545
138
 
546
- ## Status
547
-
548
- The current stable release is **v0.8.35** on npm and GitHub.
549
-
550
139
  ## License
551
140
 
552
141
  Apache-2.0 © 2026 Davide A. Guglielmi (DioNanos)