@mmmbuto/nexuscrew 0.9.16 → 0.9.17
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/CHANGELOG.md +132 -3
- package/docs/ALIBABA_TOKEN_PLAN.md +70 -0
- package/docs/AUDIO_SHARE.md +119 -0
- package/docs/CELL_PANEL.md +156 -0
- package/docs/CONFIGURATION.md +122 -0
- package/docs/FLEET.md +222 -0
- package/docs/INSTALLATION.md +128 -0
- package/docs/LIVE_PROMPT.md +110 -0
- package/docs/MCP.md +151 -0
- package/docs/NODES.md +214 -0
- package/docs/NOTIFICATIONS.md +101 -0
- package/docs/OPERATIONS.md +114 -0
- package/docs/README.md +55 -0
- package/docs/SECURITY.md +185 -0
- package/docs/VL_MICRO_NODES.md +107 -0
- package/docs/img/fleet-deck-desktop.png +0 -0
- package/docs/img/session-mobile.png +0 -0
- package/docs/live-prompt-templates/LIVE_PROMPT.en.md +67 -0
- package/docs/live-prompt-templates/LIVE_PROMPT.es.md +70 -0
- package/docs/live-prompt-templates/LIVE_PROMPT.it.md +67 -0
- package/frontend/dist/assets/{index-CwsGpQwK.js → index-jBYBPXhB.js} +1 -1
- package/frontend/dist/index.html +1 -1
- package/frontend/dist/version.json +1 -1
- package/lib/auth/middleware.js +1 -1
- package/lib/cells/scope-guard.js +2 -2
- package/lib/cli/commands.js +7 -7
- package/lib/cli/fleet-service.js +2 -2
- package/lib/cli/pidfile.js +15 -15
- package/lib/cli/service.js +2 -2
- package/lib/cli/stable-alias.js +1 -1
- package/lib/files/routes.js +2 -2
- package/lib/fleet/builtin.js +6 -6
- package/lib/fleet/cell-exec.js +4 -4
- package/lib/fleet/cell-lease-server.js +17 -17
- package/lib/fleet/definitions.js +5 -5
- package/lib/fleet/launch-broker.js +3 -3
- package/lib/fleet/lease-client.js +1 -1
- package/lib/fleet/managed.js +11 -11
- package/lib/fleet/prompt-delivery.js +1 -1
- package/lib/fleet/runtime.js +3 -3
- package/lib/live-host/bridge.js +3 -3
- package/lib/live-host/routes.js +1 -1
- package/lib/mcp/server.js +7 -8
- package/lib/mcp/tools.js +1 -1
- package/lib/nodes/commands.js +2 -2
- package/lib/nodes/health.js +1 -1
- package/lib/nodes/identity.js +10 -13
- package/lib/nodes/store.js +2 -2
- package/lib/nodes/tunnel-supervisor.js +7 -7
- package/lib/nodes/tunnel.js +10 -11
- package/lib/notify/asks.js +4 -4
- package/lib/notify/persist.js +1 -1
- package/lib/notify/push.js +4 -4
- package/lib/notify/routes.js +12 -12
- package/lib/proxy/node-proxy.js +4 -4
- package/lib/proxy/panel-proxy.js +2 -2
- package/lib/pty/attach.js +1 -1
- package/lib/server.js +3 -3
- package/lib/settings/pairing-coordinator.js +1 -1
- package/lib/settings/routes.js +4 -4
- package/lib/tmux/lifecycle.js +4 -4
- package/lib/tmux/preview.js +1 -1
- package/lib/update/runner.js +9 -9
- package/lib/vl-nodes/broker.js +1 -1
- package/lib/ws/bridge.js +1 -1
- package/package.json +20 -2
- package/frontend/index.html +0 -20
package/docs/FLEET.md
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Fleet and terminals
|
|
2
|
+
|
|
3
|
+
[← Documentation index](README.md)
|
|
4
|
+
|
|
5
|
+
## Cells
|
|
6
|
+
|
|
7
|
+
A **cell** is a reusable worker definition: tmux session name, working
|
|
8
|
+
directory, engine, model, permission policy, optional system prompt, optional
|
|
9
|
+
Shell command and boot state.
|
|
10
|
+
|
|
11
|
+
Starting a stopped cell opens the same launch sheet on desktop and mobile, so
|
|
12
|
+
the effective settings can be reviewed before the process starts. Cells marked
|
|
13
|
+
`boot:true` are started by the platform boot integration.
|
|
14
|
+
|
|
15
|
+
NexusCrew is the Fleet manager. Definitions, lifecycle, boot ownership,
|
|
16
|
+
restart supervision and write-only credentials are handled by its built-in
|
|
17
|
+
runtime; no external `fleet` executable is discovered or invoked.
|
|
18
|
+
|
|
19
|
+
Set `NEXUSCREW_FLEET=0` to disable Fleet entirely.
|
|
20
|
+
|
|
21
|
+
## Engines
|
|
22
|
+
|
|
23
|
+
Clean installations include these base adapters:
|
|
24
|
+
|
|
25
|
+
- Claude Code
|
|
26
|
+
- Codex
|
|
27
|
+
- Codex-VL
|
|
28
|
+
- Pi
|
|
29
|
+
- Agy on Linux and macOS
|
|
30
|
+
- Kimi Code CLI
|
|
31
|
+
- Shell
|
|
32
|
+
|
|
33
|
+
Agy delegates authentication to its local login and supports standard or
|
|
34
|
+
unsafe permission policies. On Android/Termux, use the Shell adapter with a
|
|
35
|
+
per-cell `agy` command.
|
|
36
|
+
|
|
37
|
+
Kimi Code CLI (`kimi.native`) runs the official `@moonshot-ai/kimi-code`
|
|
38
|
+
binary directly. Authentication and providers are owned by the CLI itself
|
|
39
|
+
(device-code login, `config.toml`): NexusCrew never reads, stores or injects
|
|
40
|
+
Kimi credentials. The cell prompt is not passed on the command line — the CLI
|
|
41
|
+
has no interactive prompt flag (`kimi -p` is non-interactive and skips the
|
|
42
|
+
TUI) — so it is injected with bracketed paste after the session is ready.
|
|
43
|
+
This engine is distinct from the Claude Code "Kimi Code" provider below,
|
|
44
|
+
which remains the managed K3 path with an isolated Claude configuration.
|
|
45
|
+
|
|
46
|
+
### Bootstrap prompt delivery (Kimi engines)
|
|
47
|
+
|
|
48
|
+
For `kimi.native` and the Claude Code "Kimi Code" provider the cell prompt is
|
|
49
|
+
never placed on the process command line. It is delivered to the interactive
|
|
50
|
+
prompt only, at most once per process generation:
|
|
51
|
+
|
|
52
|
+
- Before delivering, NexusCrew classifies the visible terminal. Login,
|
|
53
|
+
custom-API-key consent and onboarding/trust dialogs are **not ready**: no
|
|
54
|
+
text is pasted and no Enter is sent, so the prompt can never be lost behind
|
|
55
|
+
a dialog. The session stays alive and usable.
|
|
56
|
+
- If the terminal is still not ready after a bounded wait, the up response
|
|
57
|
+
reports a bounded `actionRequired` code with a recovery hint. For the
|
|
58
|
+
Claude Code "Kimi Code" provider the recovery is to confirm or enable the
|
|
59
|
+
custom API key in the cell terminal (`/config` → "Use custom API key") and
|
|
60
|
+
then restart the cell — never the Anthropic `/login` flow. For `kimi.native`
|
|
61
|
+
it is the CLI's own `/login` (device code) or `/provider`.
|
|
62
|
+
- Delivery itself is a single bracketed paste followed by a separate Enter,
|
|
63
|
+
targeted at the exact pane, and is owned solely by the cell's supervising
|
|
64
|
+
launcher for every process generation (the API runtime never pastes for
|
|
65
|
+
these engines; it only reads the bounded delivery outcome the launcher
|
|
66
|
+
publishes on the pane). There is no automatic retry after a paste attempt;
|
|
67
|
+
a supervised restart delivers the prompt at most once again for the new
|
|
68
|
+
process generation.
|
|
69
|
+
|
|
70
|
+
MCP servers started by an AI CLI inherit that process's environment according
|
|
71
|
+
to the CLI's own configuration and behavior; that inheritance is owned by the
|
|
72
|
+
CLI, not by NexusCrew.
|
|
73
|
+
|
|
74
|
+
Custom argv-based engines are launched directly without a shell after
|
|
75
|
+
trust-boundary validation.
|
|
76
|
+
|
|
77
|
+
The Shell engine resolves `$SHELL` or a trusted platform shell at start time;
|
|
78
|
+
executable paths are not stored in Fleet definitions or backups. An empty
|
|
79
|
+
command opens an interactive login shell. A configured command is passed as
|
|
80
|
+
one opaque argument through the private launch broker, runs once without
|
|
81
|
+
restart supervision and then leaves the cell stopped.
|
|
82
|
+
|
|
83
|
+
## Providers
|
|
84
|
+
|
|
85
|
+
Provider choices are scoped to the selected CLI:
|
|
86
|
+
|
|
87
|
+
| CLI | Built-in choices |
|
|
88
|
+
|---|---|
|
|
89
|
+
| Claude Code | Anthropic, Alibaba Token Plan, OpenRouter, Kimi Code, Bedrock, Vertex AI, Foundry, Ollama Cloud, local Ollama, Z.AI, custom Anthropic-compatible |
|
|
90
|
+
| Codex | OpenAI/ChatGPT, OpenAI API, Ollama Cloud, local Ollama, LM Studio, custom Responses endpoint |
|
|
91
|
+
| Codex-VL | OpenAI/ChatGPT, OpenAI API, Alibaba Token Plan, OpenRouter, Ollama Cloud, local Ollama, LM Studio, custom Responses endpoint |
|
|
92
|
+
| Pi | Native, Anthropic, OpenAI API, Alibaba Token Plan, Codex OAuth, Gemini, Copilot, OpenRouter, Ollama, DeepSeek, Z.AI, custom |
|
|
93
|
+
| Kimi Code CLI | Native account via CLI login (device code); providers managed by the CLI |
|
|
94
|
+
| Shell | Device-local interactive shell or one trusted per-cell command |
|
|
95
|
+
|
|
96
|
+
Custom Codex-compatible endpoints use the Responses wire API; NexusCrew does
|
|
97
|
+
not silently fall back to Chat Completions.
|
|
98
|
+
|
|
99
|
+
OpenRouter is first-class for Claude Code and Codex-VL. Kimi Code is a separate
|
|
100
|
+
Claude Code membership profile and is not interchangeable with a Moonshot
|
|
101
|
+
pay-as-you-go key. It is also distinct from the native Kimi Code CLI engine:
|
|
102
|
+
the provider drives Claude Code against the Kimi endpoint through the managed
|
|
103
|
+
`ANTHROPIC_*` environment (K3 models, including the 1M-context profile), while
|
|
104
|
+
`kimi.native` launches the official CLI with its own login and configuration.
|
|
105
|
+
|
|
106
|
+
Alibaba Token Plan is available for Claude Code, Codex-VL and Pi through the
|
|
107
|
+
fixed local variable `ALIBABA_CODE_API_KEY`. See
|
|
108
|
+
[Alibaba Token Plan](ALIBABA_TOKEN_PLAN.md).
|
|
109
|
+
|
|
110
|
+
## Credentials and permissions
|
|
111
|
+
|
|
112
|
+
Permission handling is explicit:
|
|
113
|
+
|
|
114
|
+
- Claude engines use standard permissions or
|
|
115
|
+
`--dangerously-skip-permissions`.
|
|
116
|
+
- Codex and Codex-VL use standard permissions or
|
|
117
|
+
`--dangerously-bypass-approvals-and-sandbox`.
|
|
118
|
+
- Kimi Code CLI uses standard (interactive) permissions by default; the unsafe
|
|
119
|
+
policy maps to `--yolo`, which auto-approves regular tool calls but still
|
|
120
|
+
lets the agent ask questions. The fully autonomous `--auto` mode is
|
|
121
|
+
deliberately not exposed.
|
|
122
|
+
- Pi uses its native permission behavior.
|
|
123
|
+
|
|
124
|
+
Provider keys are resolved on the node that launches the process. Values are
|
|
125
|
+
excluded from Fleet definitions, backups, API responses, tmux state, process
|
|
126
|
+
arguments, temporary files and logs.
|
|
127
|
+
|
|
128
|
+
Built-in providers with a fixed variable expose a dedicated **KEY** section.
|
|
129
|
+
It shows only the variable name, configured source and affected engines.
|
|
130
|
+
Replacing or removing a shared key warns which engines use it.
|
|
131
|
+
|
|
132
|
+
## Decks and workspaces
|
|
133
|
+
|
|
134
|
+
Desktop decks place multiple live terminals in a saved tiled layout. Decks
|
|
135
|
+
remain attached to the current PWA by default; `↗` detaches one into another
|
|
136
|
+
browser window.
|
|
137
|
+
|
|
138
|
+
Session and deck order can be changed with pointer drag-and-drop or keyboard
|
|
139
|
+
controls and is saved automatically. The deck bar groups workspaces by owner
|
|
140
|
+
node. Newly seen nodes start collapsed, and activity dots show current work
|
|
141
|
+
without opening every group.
|
|
142
|
+
|
|
143
|
+
On mobile, locations are independently collapsible and filterable by all,
|
|
144
|
+
pinned, active, off or technical sessions. Managed terminals use the logical
|
|
145
|
+
Fleet cell name as their visible title; tmux session and route identifiers
|
|
146
|
+
remain technical context.
|
|
147
|
+
|
|
148
|
+
When a mobile terminal is open, the key-bar cell control opens a bottom-left
|
|
149
|
+
quick rail. Its default view contains only cells whose local or routed Fleet
|
|
150
|
+
state and tmux session were freshly verified; it refreshes while open and
|
|
151
|
+
checks the target again before switching. A degraded cell remains visible as a
|
|
152
|
+
warning rather than disappearing. Use the explicit all-cells control for the
|
|
153
|
+
complete inventory, including stopped cells.
|
|
154
|
+
|
|
155
|
+
Choosing a row only selects it. Use the separate **Open cell** control to make
|
|
156
|
+
the switch, so an exploratory touch cannot replace the terminal under your
|
|
157
|
+
finger. Drag a row by its handle to reorder cells. That order is shared with
|
|
158
|
+
the main roster and desktop sidebar, retains unmanaged tmux sessions, and
|
|
159
|
+
keeps an offline cell's position for when it becomes active again.
|
|
160
|
+
|
|
161
|
+
## Terminal behavior
|
|
162
|
+
|
|
163
|
+
Terminal attachment uses `tmux attach -f ignore-size` by default, so a phone or
|
|
164
|
+
narrow browser cannot resize a session held by another terminal client.
|
|
165
|
+
|
|
166
|
+
Mobile controls expose:
|
|
167
|
+
|
|
168
|
+
- copy-mode scrolling
|
|
169
|
+
- window and pane navigation
|
|
170
|
+
- Escape, Ctrl-C, Enter, Page Up and Page Down
|
|
171
|
+
- detach
|
|
172
|
+
- compact or two-row key layouts
|
|
173
|
+
- speech-to-text where supported
|
|
174
|
+
- expandable per-cell prompt composer
|
|
175
|
+
|
|
176
|
+
Long text and multiline prompts use bracketed paste. Clipboard images and
|
|
177
|
+
dropped files are stored in the selected session inbox; their paths are
|
|
178
|
+
inserted without submitting Enter.
|
|
179
|
+
|
|
180
|
+
New sessions created by NexusCrew disable the tmux alternate screen by default.
|
|
181
|
+
Full-screen TUI output therefore remains in tmux history, so mobile finger
|
|
182
|
+
drags and normal terminal scrolling can browse it. Set `alternateScreen: true`
|
|
183
|
+
in the local NexusCrew config (or `NEXUSCREW_ALTERNATE_SCREEN=1`) to restore the
|
|
184
|
+
standard tmux behavior for future sessions created through Fleet. Existing and unmanaged
|
|
185
|
+
sessions are unchanged.
|
|
186
|
+
|
|
187
|
+
Desktop wheel events always browse tmux history, including in writable TUIs
|
|
188
|
+
that use the alternate screen and while Shift is held. Keep a user-owned tmux
|
|
189
|
+
`history-limit` of at least 10000; `nexuscrew doctor` diagnoses a lower value
|
|
190
|
+
without changing it.
|
|
191
|
+
|
|
192
|
+
Each owner-qualified cell keeps its own browser-local draft, composer size and
|
|
193
|
+
bounded prompt history. That state is not federated or included in Fleet
|
|
194
|
+
backups.
|
|
195
|
+
|
|
196
|
+
## Bundled skills
|
|
197
|
+
|
|
198
|
+
The package ships portable skills, and
|
|
199
|
+
[`nexuscrew`](../skills/nexuscrew/SKILL.md) is the one to read first: it
|
|
200
|
+
describes the whole system, what an AI agent can do through it, and the rules
|
|
201
|
+
that hold across every other skill.
|
|
202
|
+
|
|
203
|
+
Two extend Fleet itself: [`live`](../skills/live/SKILL.md) covers designating
|
|
204
|
+
and permitting a node's Live host cell, plus the
|
|
205
|
+
[per-cell voice prompt](LIVE_PROMPT.md) it reads once a session lands, and
|
|
206
|
+
[`aidesktop`](../skills/aidesktop/SKILL.md) covers a cell's web panel together
|
|
207
|
+
with the AI Desktop container recipe. The rest cover one capability each — the
|
|
208
|
+
operator channel ([`nexuscrew-agent`](../skills/nexuscrew-agent/SKILL.md)) and
|
|
209
|
+
the optional MCP companions listed in
|
|
210
|
+
[`mcp-companions.json`](../mcp-companions.json):
|
|
211
|
+
[`memory`](../skills/memory/SKILL.md),
|
|
212
|
+
[`vl-msa`](../skills/vl-msa/SKILL.md),
|
|
213
|
+
[`crew`](../skills/crew/SKILL.md) and
|
|
214
|
+
[`mail-assistant`](../skills/mail-assistant/SKILL.md). The companions are
|
|
215
|
+
separate servers: absent unless installed, and never installed silently.
|
|
216
|
+
|
|
217
|
+
## Related guides
|
|
218
|
+
|
|
219
|
+
- [Configuration](CONFIGURATION.md)
|
|
220
|
+
- [Connect nodes](NODES.md)
|
|
221
|
+
- [Notifications](NOTIFICATIONS.md)
|
|
222
|
+
- [Security](SECURITY.md)
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Installation
|
|
2
|
+
|
|
3
|
+
[← Documentation index](README.md)
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Node.js 18 or newer
|
|
8
|
+
- tmux 3.4 or newer
|
|
9
|
+
- OpenSSH client (`ssh`)
|
|
10
|
+
- Linux x64/ARM64, macOS x64/ARM64, or Android ARM64 through Termux
|
|
11
|
+
|
|
12
|
+
NexusCrew ships scriptless PTY prebuilds for the supported targets. A normal
|
|
13
|
+
global install does not need a compiler or native install-script approval.
|
|
14
|
+
|
|
15
|
+
## Linux
|
|
16
|
+
|
|
17
|
+
Install Node.js, tmux and OpenSSH with your distribution package manager, then:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install -g @mmmbuto/nexuscrew
|
|
21
|
+
nexuscrew
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
NexusCrew uses a systemd user service when it is available. If user services
|
|
25
|
+
cannot survive logout, enable lingering for your account:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
loginctl enable-linger "$USER"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## macOS
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
brew install node tmux
|
|
35
|
+
npm install -g @mmmbuto/nexuscrew
|
|
36
|
+
nexuscrew
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
NexusCrew installs a per-user LaunchAgent. It does not require a system daemon.
|
|
40
|
+
|
|
41
|
+
## Android / Termux
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pkg update
|
|
45
|
+
pkg install nodejs-lts tmux openssh
|
|
46
|
+
npm install -g @mmmbuto/nexuscrew
|
|
47
|
+
nexuscrew
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Optional boot persistence uses the Termux:Boot app. Install and open that app
|
|
51
|
+
once before enabling boot from NexusCrew.
|
|
52
|
+
|
|
53
|
+
On Android, `nexuscrew doctor` also verifies the Termux execution bridge.
|
|
54
|
+
NexusCrew carries forward only a validated `libtermux-exec` preload from the
|
|
55
|
+
active Termux prefix. Package upgrades repair enabled Termux:Boot scripts so
|
|
56
|
+
they do not launch from a replaceable npm directory.
|
|
57
|
+
|
|
58
|
+
## First run
|
|
59
|
+
|
|
60
|
+
The first `nexuscrew` command:
|
|
61
|
+
|
|
62
|
+
1. Creates the local configuration and bearer token.
|
|
63
|
+
2. Selects a free loopback port, preferring `41820`.
|
|
64
|
+
3. Installs the platform background integration.
|
|
65
|
+
4. Starts NexusCrew without replacing or stopping tmux.
|
|
66
|
+
5. Opens the authenticated PWA and setup wizard.
|
|
67
|
+
|
|
68
|
+
Later runs reuse the configured service, print a compact status and exit.
|
|
69
|
+
|
|
70
|
+
Use `nexuscrew show` to open the PWA again, or `nexuscrew show token` to print
|
|
71
|
+
the authenticated link without opening a browser.
|
|
72
|
+
|
|
73
|
+
## Verify
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
nexuscrew status
|
|
77
|
+
nexuscrew doctor
|
|
78
|
+
nexuscrew version
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
A missing OpenSSH client is a blocking diagnostic. `autossh` is optional;
|
|
82
|
+
NexusCrew supervises OpenSSH directly.
|
|
83
|
+
|
|
84
|
+
## Remote access
|
|
85
|
+
|
|
86
|
+
NexusCrew listens only on loopback. Bring the remote loopback port to your
|
|
87
|
+
device through SSH or a VPN you control:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
ssh -L 41820:127.0.0.1:41820 user@your-host
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Use the port shown by `nexuscrew status`, then open the link returned by
|
|
94
|
+
`nexuscrew show token`. Do not expose NexusCrew through a public listener.
|
|
95
|
+
|
|
96
|
+
## Update
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npm install -g @mmmbuto/nexuscrew@latest
|
|
100
|
+
nexuscrew restart
|
|
101
|
+
nexuscrew doctor
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The built-in updater can follow the stable npm `latest` tag automatically. It
|
|
105
|
+
serializes updates, verifies the new CLI and same-port runtime, and rolls back
|
|
106
|
+
once to the exact previous version if health checks fail. Disable its scheduler
|
|
107
|
+
with `NEXUSCREW_AUTO_UPDATE=0`.
|
|
108
|
+
|
|
109
|
+
## Install from source
|
|
110
|
+
|
|
111
|
+
Use a release tag rather than a moving branch:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
git clone https://github.com/DioNanos/nexuscrew.git
|
|
115
|
+
cd nexuscrew
|
|
116
|
+
git checkout vX.Y.Z
|
|
117
|
+
npm ci --omit=dev
|
|
118
|
+
node bin/nexuscrew.js
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The repository includes the prebuilt frontend in `frontend/dist`. Rebuilding
|
|
122
|
+
the PWA is only needed for development.
|
|
123
|
+
|
|
124
|
+
## Next
|
|
125
|
+
|
|
126
|
+
- [Configure the runtime](CONFIGURATION.md)
|
|
127
|
+
- [Connect another node](NODES.md)
|
|
128
|
+
- [Learn the operational CLI](OPERATIONS.md)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# The Live per-cell prompt
|
|
2
|
+
|
|
3
|
+
[← Documentation index](README.md)
|
|
4
|
+
|
|
5
|
+
When Live starts a native session (engine `codex-vl*`), the bridge
|
|
6
|
+
(`lib/live-host/bridge.js`) always sends `thread/start` a `developerInstructions`
|
|
7
|
+
field that opens with an identity header — which cell it is attached to, and
|
|
8
|
+
the exact tmux session the roster reports for it — and, if a per-cell prompt
|
|
9
|
+
file exists, appends its text after a blank line. How the app-server
|
|
10
|
+
combines that field with its other configured instructions is not
|
|
11
|
+
established here — a separate verification of that consumer is in progress.
|
|
12
|
+
This page is about the template file itself: what it must contain, exactly
|
|
13
|
+
where it goes, and how to prove the bridge actually reads it. For the Live
|
|
14
|
+
host designation itself (which cell a node's Live session lands on), see
|
|
15
|
+
[`live`](../skills/live/SKILL.md).
|
|
16
|
+
|
|
17
|
+
## Where the file goes
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
<NexusFiles>/<tmuxSession>/LIVE_PROMPT.md
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
- `<NexusFiles>` is the `filesRoot` NexusCrew resolves for the node running
|
|
24
|
+
the bridge — `~/NexusFiles` unless overridden by configuration. This is
|
|
25
|
+
the node's own home, not a remote peer's.
|
|
26
|
+
- `<tmuxSession>` is the **exact tmux session name the Fleet roster reports**
|
|
27
|
+
for the designated cell (`cell.tmuxSession` in fleet status / `nc_cells`)
|
|
28
|
+
— the same value the bridge puts in the identity header, not a name
|
|
29
|
+
reconstructed from a device prefix. On a device whose sessions are named
|
|
30
|
+
`cloud-*` this is `cloud-<Cell>`; on a device using a different prefix (or
|
|
31
|
+
none) it is whatever that device actually calls the session. There is no
|
|
32
|
+
fixed prefix to guess: **until 2026-08-16 the bridge assumed `cloud-` as a
|
|
33
|
+
universal default, and on any device using a different prefix the prompt
|
|
34
|
+
was never found** — this page described that assumption as the contract
|
|
35
|
+
before it was understood to be the bug.
|
|
36
|
+
- If the roster does not report a `tmuxSession` for the cell at all, the
|
|
37
|
+
bridge does not construct a path from the cell name as a fallback — see
|
|
38
|
+
"What the bridge does with it" below for what happens instead.
|
|
39
|
+
|
|
40
|
+
To install a template: copy one of the files in
|
|
41
|
+
[`live-prompt-templates/`](live-prompt-templates/) into that session's
|
|
42
|
+
NexusFiles folder, next to that cell's `PROMPT.md` and `ACTIVE_WORK.md`, and
|
|
43
|
+
rename it to `LIVE_PROMPT.md`. Nothing in the file needs editing — it never
|
|
44
|
+
names the cell or the operator; the voice discovers both at runtime through
|
|
45
|
+
`nc_identity`/`nc_cells`, exactly as the file tells it to.
|
|
46
|
+
|
|
47
|
+
## What the bridge does with it
|
|
48
|
+
|
|
49
|
+
`readCellPrompt(filesRoot, tmuxSession)` has four distinct outcomes. The
|
|
50
|
+
distinction matters for anyone debugging why a Live session sounds
|
|
51
|
+
unbriefed — "I don't even know where to look," "I looked and it's not
|
|
52
|
+
there," and "it's there but useless" point to different fixes:
|
|
53
|
+
|
|
54
|
+
| Outcome | Cause | What happens |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| `applied: true` | file exists, reads, non-empty after trim | its text is appended to the identity header, separated by a blank line |
|
|
57
|
+
| `applied: false`, `reason: "session-unknown"` | the roster does not report a `tmuxSession` for this cell | no path is built at all — never a guess from the cell name; only the identity header (cell name, no session) is sent |
|
|
58
|
+
| `applied: false`, `reason: "missing"` | the session is known, but no such file exists there (`ENOENT`) | legitimate absence — the identity header still ships, no per-cell prompt is appended, no error |
|
|
59
|
+
| `applied: false`, `reason: "unreadable"` or `"empty"` | file exists but can't be read, or is blank/whitespace-only | almost certainly a mistake — worth fixing, not silent |
|
|
60
|
+
|
|
61
|
+
Three things this table implies:
|
|
62
|
+
|
|
63
|
+
- A missing file is not a bug. Not every cell needs one.
|
|
64
|
+
- `session-unknown` is not the same failure as `missing`, and collapsing them
|
|
65
|
+
is exactly how the prefix bug hid: every session on a non-`cloud-` device
|
|
66
|
+
looked "missing" when the real cause was "never looked, wrong assumed
|
|
67
|
+
path." If this ever shows up in practice, it means the roster isn't
|
|
68
|
+
reporting a tmux session for an active cell — worth investigating on its
|
|
69
|
+
own, not something to silently fall back from.
|
|
70
|
+
- An unreadable or empty file is very likely a mistake: something is there,
|
|
71
|
+
and it is not doing what its presence suggests.
|
|
72
|
+
|
|
73
|
+
## Engine scope
|
|
74
|
+
|
|
75
|
+
The prompt only ever reaches a **native** Live session — engine
|
|
76
|
+
`codex-vl*`, where the bridge opens its own thread on the app-server's
|
|
77
|
+
control socket and can pass `developerInstructions` directly. For any other
|
|
78
|
+
engine the bridge runs in **tmux mode**: no thread is opened, no
|
|
79
|
+
instructions are passed, and the response reports `prompt: { applied:
|
|
80
|
+
false, reason: "tmux-mode" }` even if a `LIVE_PROMPT.md` file is sitting
|
|
81
|
+
right there, correctly placed and readable. Placing the file for a
|
|
82
|
+
non-`codex-vl` cell is not wrong, it simply has no effect yet.
|
|
83
|
+
|
|
84
|
+
## Verifying it's not just a plausible story
|
|
85
|
+
|
|
86
|
+
The bridge's own test suite (`tests/live-host-bridge.test.js`) builds the
|
|
87
|
+
real bridge against a real HTTP hub and a real WebSocket daemon, writes a
|
|
88
|
+
`LIVE_PROMPT.md` file to disk at the exact path this page describes, and
|
|
89
|
+
asserts on what the fake app-server actually *received* on the wire — not on
|
|
90
|
+
what the code merely appears to do reading it top to bottom. Two tests are
|
|
91
|
+
the pattern to extend if this contract ever changes:
|
|
92
|
+
|
|
93
|
+
- `'NATIVA con cella OCCUPATA...'` — the ordinary case, file found and
|
|
94
|
+
applied, identity header followed by the prompt text.
|
|
95
|
+
- `'BUG prefisso: un device con prefisso diverso da cloud- deve trovare
|
|
96
|
+
comunque il prompt'` — a device whose sessions are named `macair-*`: the
|
|
97
|
+
file is written under that exact session name, not under `cloud-`, and the
|
|
98
|
+
bridge is expected to find it there. This is the test that would have
|
|
99
|
+
caught the original bug — it fails against the pre-fix bridge and passes
|
|
100
|
+
against the current one, with a sibling test pinning that the `cloud-`
|
|
101
|
+
case does not regress.
|
|
102
|
+
|
|
103
|
+
## See also
|
|
104
|
+
|
|
105
|
+
- [`live-prompt-templates/`](live-prompt-templates/) — the three template
|
|
106
|
+
files (Italian, English, Spanish).
|
|
107
|
+
- [`live`](../skills/live/SKILL.md) — designating and permitting a node's
|
|
108
|
+
Live host cell.
|
|
109
|
+
- [Fleet and terminals](FLEET.md) — what Live is and how a host cell is
|
|
110
|
+
chosen.
|
package/docs/MCP.md
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# MCP bridge
|
|
2
|
+
|
|
3
|
+
[← Documentation index](README.md)
|
|
4
|
+
|
|
5
|
+
`nexuscrew mcp` exposes the local authenticated runtime as a dependency-free
|
|
6
|
+
stdio MCP server. It is intended for AI sessions running inside managed tmux
|
|
7
|
+
cells.
|
|
8
|
+
|
|
9
|
+
## Tools
|
|
10
|
+
|
|
11
|
+
| Tool | Purpose |
|
|
12
|
+
|---|---|
|
|
13
|
+
| `nc_notify` | Send a PWA notification, optionally declaring its text language |
|
|
14
|
+
| `nc_ask` | Ask a non-blocking question and return the answer to the caller |
|
|
15
|
+
| `nc_send_file` | Place a caller-owned file in the downloadable outbox |
|
|
16
|
+
| `nc_status` | Read live tmux and Fleet status |
|
|
17
|
+
| `nc_inbox` | List files received by the caller |
|
|
18
|
+
| `nc_deck` | Discover owner-qualified decks containing the caller |
|
|
19
|
+
| `nc_cells` | List authorized Fleet cells across visible nodes |
|
|
20
|
+
| `nc_cell_diagnostics` | Read redacted launch state for one exact local cell |
|
|
21
|
+
| `nc_send_cell` | Submit bounded text to one exact active cell |
|
|
22
|
+
| `nc_vl_nodes` | List authorized owner-qualified VL micro-device nodes |
|
|
23
|
+
| `nc_vl_invite` | Create a one-time invite on one exact owner |
|
|
24
|
+
| `nc_vl_command` | Deliver a bounded command to one online VL node |
|
|
25
|
+
| `nc_vl_revoke` | Explicitly revoke one exact VL pairing |
|
|
26
|
+
| `nc_identity` | Diagnose caller identity without reading a token |
|
|
27
|
+
| `nc_speak` | Speak a bounded utterance on one exact authorized node ID |
|
|
28
|
+
| `nc_speak_status` | Read a caller-scoped exact-target audio receipt |
|
|
29
|
+
| `nc_speak_stop` | Stop a caller-owned exact-target utterance |
|
|
30
|
+
| `nc_speak_group` | Start a local named primary/failover or explicit fan-out group |
|
|
31
|
+
| `nc_speak_group_status` | Read a caller-scoped per-endpoint group receipt |
|
|
32
|
+
| `nc_speak_group_stop` | Stop a group and prevent untried failover candidates |
|
|
33
|
+
|
|
34
|
+
Cell delivery uses bracketed paste followed by a separate Enter. A `submitted`
|
|
35
|
+
receipt confirms transport to the target TUI, not acceptance or completion by
|
|
36
|
+
its model. There is no silent offline queue.
|
|
37
|
+
|
|
38
|
+
### Notification language
|
|
39
|
+
|
|
40
|
+
`nc_notify` accepts `title`, optional `body`, optional `urgency`, and optional
|
|
41
|
+
`lang`. Use `lang` whenever the text language is known so an opted-in,
|
|
42
|
+
visible/focused PWA can select the correct on-device speech voice:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"title": "Release completata",
|
|
47
|
+
"body": "Correzione verificata e pubblicata con tutti i test verdi.",
|
|
48
|
+
"lang": "it"
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Accepted base languages are `it`, `en` and `es`; equivalent BCP-47 forms such
|
|
53
|
+
as `it-IT` are normalized. Omitting `lang` remains backward compatible.
|
|
54
|
+
|
|
55
|
+
## Claude Code
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"mcpServers": {
|
|
60
|
+
"nexuscrew": {
|
|
61
|
+
"command": "nexuscrew",
|
|
62
|
+
"args": ["mcp"]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Codex and Codex-VL
|
|
69
|
+
|
|
70
|
+
These clients launch MCP stdio processes with a cleared environment. Allowlist
|
|
71
|
+
the identity variable names; do not copy values into the config:
|
|
72
|
+
|
|
73
|
+
```toml
|
|
74
|
+
[mcp_servers.nexuscrew]
|
|
75
|
+
command = "nexuscrew"
|
|
76
|
+
args = ["mcp"]
|
|
77
|
+
env_vars = ["NEXUSCREW_MCP_SESSION", "TMUX", "TMUX_PANE"]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Equivalent Codex-VL CLI form:
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
codex-vl mcp add nexuscrew \
|
|
84
|
+
--env-var NEXUSCREW_MCP_SESSION \
|
|
85
|
+
--env-var TMUX \
|
|
86
|
+
--env-var TMUX_PANE \
|
|
87
|
+
-- nexuscrew mcp
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Caller identity
|
|
91
|
+
|
|
92
|
+
The caller is resolved in this order:
|
|
93
|
+
|
|
94
|
+
1. Current tmux session.
|
|
95
|
+
2. `NEXUSCREW_MCP_SESSION`.
|
|
96
|
+
3. Missing identity.
|
|
97
|
+
|
|
98
|
+
Without identity, gated tools fail closed with a stable
|
|
99
|
+
`NEXUSCREW_MCP_IDENTITY_*` code. `nc_notify` degrades to an unknown sender.
|
|
100
|
+
|
|
101
|
+
`nc_identity` returns only:
|
|
102
|
+
|
|
103
|
+
- resolution source (`tmux`, environment fallback or missing)
|
|
104
|
+
- boolean presence of identity variables
|
|
105
|
+
- stable status code
|
|
106
|
+
- remediation hint
|
|
107
|
+
|
|
108
|
+
It never calls the HTTP API or reads the bearer token.
|
|
109
|
+
|
|
110
|
+
`nc_cell_diagnostics` accepts an exact owner-qualified ID returned by
|
|
111
|
+
`nc_cells`, only when the target belongs to the local node and the caller is an
|
|
112
|
+
active local Fleet cell. Its command and failure information are bounded and
|
|
113
|
+
credential-redacted.
|
|
114
|
+
|
|
115
|
+
VL mutation tools likewise require an active local Fleet caller. Use
|
|
116
|
+
`nc_vl_nodes` immediately before mutation and the full owner-qualified target.
|
|
117
|
+
`nc_vl_command` receipts are transport-only until `lastAck` carries the same
|
|
118
|
+
ID. See [VL micro-device nodes](VL_MICRO_NODES.md).
|
|
119
|
+
|
|
120
|
+
### Audio Share
|
|
121
|
+
|
|
122
|
+
Audio tools require an active local Fleet cell and an HMAC-signed bridge
|
|
123
|
+
request. The target node independently enforces its own audio consent, ACL,
|
|
124
|
+
`READONLY`, rate limit, and native capability. A successful adapter start is
|
|
125
|
+
reported as `spoken`; it is not proof of physical audibility. See
|
|
126
|
+
[Audio Share and native TTS](AUDIO_SHARE.md) for exact-target and group
|
|
127
|
+
semantics.
|
|
128
|
+
|
|
129
|
+
## Optional companions
|
|
130
|
+
|
|
131
|
+
NexusCrew can work alongside separate local-first MCP servers for:
|
|
132
|
+
|
|
133
|
+
- durable structured memory
|
|
134
|
+
- searchable document memory
|
|
135
|
+
- bounded worker delegation
|
|
136
|
+
- mail access
|
|
137
|
+
|
|
138
|
+
They are optional projects, not hidden NexusCrew dependencies. Discover
|
|
139
|
+
existing tools first and ask before installing software, changing MCP
|
|
140
|
+
configuration or requesting credentials.
|
|
141
|
+
|
|
142
|
+
See [MCP_COMPANIONS.md](../MCP_COMPANIONS.md) and
|
|
143
|
+
[`mcp-companions.json`](../mcp-companions.json).
|
|
144
|
+
|
|
145
|
+
## Related guides
|
|
146
|
+
|
|
147
|
+
- [Fleet and terminals](FLEET.md)
|
|
148
|
+
- [Connect nodes](NODES.md)
|
|
149
|
+
- [Audio Share and native TTS](AUDIO_SHARE.md)
|
|
150
|
+
- [VL micro-device nodes](VL_MICRO_NODES.md)
|
|
151
|
+
- [Security](SECURITY.md)
|