@mmmbuto/nexuscrew 0.8.23 → 0.8.25

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 ADDED
@@ -0,0 +1,744 @@
1
+ # Changelog
2
+
3
+ All notable changes to NexusCrew are tracked here.
4
+
5
+ ## 0.8.25 — 2026-07-19 — "Token Plan"
6
+
7
+ - Adds Alibaba Token Plan Personal as a first-class managed provider for Claude Code,
8
+ Codex-VL and Pi, with `qwen3.8-max-preview` as the default and one fixed local credential
9
+ reference, `ALIBABA_CODE_API_KEY`. Credential values stay in the existing write-only
10
+ credential layer and selected child environment; they never enter engine definitions,
11
+ generated extensions, argv, status responses, logs or the package.
12
+ - Configures Claude Code against the plan's Anthropic-compatible base with isolated private
13
+ state, a 983,616-token context and explicit Qwen aliases for model, Sonnet, Opus, Haiku,
14
+ subagents and Fable. The API-key variable remains empty while the resolved value is supplied
15
+ only through the authentication-token variable expected by the client. Selecting a non-default
16
+ plan model keeps every alias aligned with that model and omits qwen3.8-only context and effort
17
+ overrides.
18
+ - Configures Codex-VL through the Responses wire API with a Qwen-only plan allowlist and a
19
+ packaged qwen3.8 catalog: 95% effective context, `xhigh` default reasoning, text and image
20
+ input, original image detail and parallel tool calls disabled. The profile has no OpenAI or
21
+ pay-as-you-go fallback.
22
+ - Gives Pi a private, value-free provider extension. Response-capable Qwen models use Pi's
23
+ Responses adapter; GLM and DeepSeek use Chat Completions with `reasoning_content` preserved
24
+ across assistant and tool replay. Standard permissions remain the only supported policy.
25
+ - Packages the portable `alibaba-token-media` skill for Claude Code, Codex, Codex-VL and Pi.
26
+ Its dependency-free CLI provides dry-run-first Wan 2.7 image/edit and HappyHorse video
27
+ workflows with fixed Token Plan endpoints, one concurrent submit, explicit Credit/high-cost
28
+ consent, private file handling and safe unique downloads under the user's Downloads folder.
29
+ - Keeps the existing public Z.AI surface unchanged: `claude.zai` remains the only generic
30
+ Claude profile, while the historical A/P names stay hidden compatibility aliases.
31
+ - Makes the mobile Fleet header count live cells and unmanaged tmux sessions across local and
32
+ routed inventories, so an inventory-only or Hydra view can no longer report zero while cells
33
+ are active.
34
+ - Adds a direct per-cell boot toggle to the mobile and desktop rosters. It changes only the next
35
+ reboot preference, never the current power state, and stays synchronized with the same boot
36
+ setting used by the existing power sheet; desktop settlements are acknowledged once so a
37
+ sidebar remount cannot replay stale state.
38
+ - Keeps Python bytecode outside the npm package even when skill compilation runs before packing,
39
+ with an isolated compile-before-pack regression test for the exact `files[]` behaviour.
40
+ - Gate: **878 isolated Node tests** (877 pass / 1 platform skip), **39/39 frontend component
41
+ tests**, production PWA build, zero production dependency vulnerabilities, sanitized package
42
+ inspection and an offline install smoke. Provider calls and Token Plan credit consumption are
43
+ intentionally outside the release build gate.
44
+ - Known debt: the minified PWA main chunk is 806.50 kB (231.11 kB gzip), so Vite's 500 kB
45
+ advisory remains visible and code splitting stays on the performance backlog.
46
+
47
+ ## 0.8.24 — 2026-07-18 — "Safe Pairing"
48
+
49
+ - Gives every joining installation an explicit, editable local route handle that is separate
50
+ from its display label. The default is deterministic and readable, combines the label or
51
+ hostname with a stable node-ID suffix, stays within 32 characters and never sends bare
52
+ `localhost` from Termux devices.
53
+ - Keeps `nodeId` as the peer identity while treating the route slug only as a unique handle.
54
+ Older clients that omit `localName` receive the same safe server-side derivation, so two
55
+ phones whose operating system hostname is `localhost` can join the same hub independently.
56
+ - Returns a deterministic replacement handle when a committed or pending peer already owns the
57
+ requested name. The PWA applies that suggestion, preserves the freely editable display label
58
+ and retries with the same unconsumed invitation; headless pairing exposes matching
59
+ `--local-name` and `--local-label` options.
60
+ - Restores `nexuscrew init` as a public, idempotent command with validated `--port` and
61
+ side-effect-free `--dry-run` support, so first-run recovery instructions always name a command
62
+ that the dispatcher actually accepts.
63
+ - Gate: **861 isolated Node tests** (860 pass / 1 platform skip), **34/34 frontend component
64
+ tests**, production PWA build and zero production dependency vulnerabilities.
65
+
66
+ ## 0.8.23 — 2026-07-18 — "Fleet Ready"
67
+
68
+ - Repairs partial or migrated installations that have NexusCrew configuration and a token but no
69
+ `fleet.json`. Runtime startup now creates the built-in Fleet defaults only when the file is
70
+ absent, including service-manager and Termux:Boot paths; an existing invalid file remains
71
+ fail-closed and is never overwritten.
72
+ - Makes smart startup restart an already-running runtime when it has just repaired the missing
73
+ definitions, so provider selection is refreshed before the PWA is reused. `nexuscrew doctor`
74
+ now reports missing, invalid, intentionally disabled and valid Fleet definitions explicitly.
75
+ - Separates Fleet editor loading, API failure and genuinely unavailable-provider states in the
76
+ PWA. A disabled provider can expose a safe operational reason instead of the misleading
77
+ “builtin provider only” message shown during initial loading or on partial Termux installs.
78
+ - Contains shared-tmux failure containment: generated Linux services require `KillMode=process`,
79
+ lifecycle commands fail closed if that protection is absent, shared servers pin
80
+ `exit-empty off` and guard `kill-server`, and cleanup tests require a unique private `-L`
81
+ socket instead of ever targeting the operator's default server.
82
+ - Gate: **854 isolated Node tests** (853 pass / 1 platform skip), **33/33 frontend component
83
+ tests**, production PWA build and zero production dependency vulnerabilities.
84
+ - Release scope at the time: npm `latest` only; 0.8.24 now carries the same changes into the
85
+ public GitHub history.
86
+
87
+ ## 0.8.22 — 2026-07-17 — "Sole Authority"
88
+
89
+ - Makes NexusCrew the only Fleet owner. The legacy executable adapter, discovery paths,
90
+ `fleetBin` configuration and alternate boot ownership are removed; `NEXUSCREW_FLEET=0`
91
+ remains the explicit kill switch.
92
+ - Supervises every built-in cell behind the private one-shot launch broker. A client that exits
93
+ after readiness is restarted with bounded exponential backoff and a rapid-failure circuit
94
+ breaker; explicit stop disarms relaunch even during backoff, while restart remains intentional.
95
+ - Adds a canonical hub peer inventory to Settings with separate direct hubs, inbound clients and
96
+ routed inspect-only nodes. Direct peers expose direction-aware **Edit**, **Disconnect** and
97
+ **Delete** actions, stale routed peers no longer appear healthy, and labels now have one
98
+ server-backed source across Settings, desktop and mobile.
99
+ - Expands the headless CLI with stable `name|nodeId` lookup for list/show/doctor, edit/rename,
100
+ visibility, connect/disconnect/reconnect, Share, revoke/remove, invite and stdin-only pair/join.
101
+ Every mutation honors READONLY; pairing capabilities never need to appear in argv.
102
+ - Gate: **845 Node tests** (844 pass / 1 platform skip), **30 frontend component tests**, a
103
+ production build and zero production dependency vulnerabilities.
104
+
105
+ ## 0.8.21 — 2026-07-17 — "Reconciled Share"
106
+
107
+ - Reconciles the detached SSH supervisor with the persisted Share state even when the requested
108
+ value is unchanged. A pre-upgrade process that still carries `-R` while the store says private
109
+ is replaced through the existing verified, spec-aware pidfile lifecycle before the hub is
110
+ notified.
111
+ - Keeps the Share checkbox usable while the tunnel is down and adds an explicit **Reconnect and
112
+ reconcile** action that reapplies the current state without toggling consent. Desired Share
113
+ state, verified reachability and a down private connection now have distinct UI messages.
114
+ - Reverse-forward diagnostics extract the negotiated listen port from OpenSSH and show the exact
115
+ `permitlisten="127.0.0.1:<port>"` restriction to verify, while retaining neutral wording when a
116
+ port collision and a key/server policy denial cannot yet be distinguished.
117
+ - Gate: **855 Node tests** (854 pass / 1 platform skip), **30 frontend component tests** and a
118
+ production build with aligned package/UI version `0.8.21`.
119
+ - Release scope: published to npm `latest` and installed on the local runtime. GitHub commit,
120
+ push, tag and release remain outside this maintenance rollout.
121
+
122
+ ## 0.8.20 — 2026-07-17 — "Reliable Routes"
123
+
124
+ - OpenRouter is now a first-class provider for Claude Code and Codex-VL. Claude uses the
125
+ Anthropic-compatible endpoint without guessed context limits; Codex-VL uses the beta,
126
+ stateless Responses wire API, direct no-shell command authentication and a ten-minute stream
127
+ idle timeout. Kimi K3 receives packaged one-million-token model metadata.
128
+ - Kimi Code is available as a non-default Claude provider with `k3[1m]`, its documented coding
129
+ endpoint, model-specific context and effort settings, and an isolated Claude configuration
130
+ that leaves native Anthropic account state unchanged.
131
+ - Built-in provider editors gain a write-only KEY section with value-free configured source and
132
+ target-local “used by” impact. Credential values remain outside engine definitions, backups,
133
+ federation payloads, argv, tmux state, logs and API responses.
134
+ - Shared-node reverse ports are reserved across pending and active pairings and bind-probed before
135
+ use. Share desired state now fails safely, reconciles after restart, rejects duplicate peer
136
+ names without burning invitations and returns actionable allocation conflicts.
137
+ - Remote inventory survives a missing tmux socket and partial peer failures. Topology probes are
138
+ parallel and bounded, repeated reverse-forward failures stop retrying, and diagnostics no
139
+ longer claim that the SSH server denied forwarding without supporting evidence.
140
+ - Desktop and mobile node groups support browser-local rename and reorder controls without
141
+ changing node identity, routes, credentials, Share state, deck identity or cell ordering.
142
+ - Gate: **853 Node tests** (852 pass / 1 platform skip), **30 frontend component tests**,
143
+ production build, zero dependency vulnerabilities and sanitized npm package inspection.
144
+
145
+ ## 0.8.19 — 2026-07-17 — "Live Activity"
146
+
147
+ - Fleet status dots now distinguish all three cell states on mobile and desktop: gray when off,
148
+ fixed green when powered but idle, and a pulsing green signal only while the attached AI client
149
+ is actively working. Reduced-motion preferences disable the pulse without hiding the text state.
150
+ - Each cell keeps a single useful subtitle. Powered-off rows show the engine, credential profile
151
+ and model when available; powered-on rows switch to a live localized status such as working,
152
+ the current task label, or idle. The same contract covers expanded, compact and remote rosters.
153
+ - Working detection uses the tmux pane title's Braille progress frame as the primary cross-client
154
+ signal. Pi receives a narrowly gated capture fallback, while activity timestamps and persistent
155
+ transcript text cannot mark unrelated or stale cells as busy. The sessions API adds bounded,
156
+ sanitized activity fields without breaking older peers.
157
+ - Gate: **830 Node tests** (829 pass / 1 platform skip), **25 frontend component tests**,
158
+ production build and zero dependency vulnerabilities.
159
+
160
+ ## 0.8.18 — 2026-07-15 — "Persistent Composer"
161
+
162
+ - The input composer now expands for long prompts and keeps a separate browser-local draft,
163
+ size preference and bounded prompt history for each owner-qualified tmux cell. State survives
164
+ route renames and reloads, synchronizes safely between tabs and can be cleared from System
165
+ settings; it is never federated or included in Fleet backups.
166
+ - History can be selected from the composer menu or recalled with ArrowUp/ArrowDown only at safe
167
+ textarea boundaries. Active IME composition is left untouched, failed sends preserve the draft,
168
+ and a delayed successful send cannot erase newer typing or another cell's draft.
169
+ - Persistence is bounded by per-entry, per-cell and browser-wide limits with 30-day expiry and
170
+ quota-aware eviction. Regression coverage includes long Unicode prompts above 32 KiB, async
171
+ send races, owner/session identity changes, cross-tab ordering, hostile stored objects and
172
+ mounted-state reset.
173
+ - Gate: **825 Node tests** (824 pass / 1 platform skip), **22 frontend component tests**,
174
+ production build and zero dependency vulnerabilities.
175
+
176
+ ## 0.8.17 — 2026-07-15 — "Modular Core"
177
+
178
+ - Termux can now start the first managed cell when no tmux server exists. NexusCrew reconstructs
179
+ the canonical `PREFIX`, `TMPDIR` and `TMUX_TMPDIR=$PREFIX/var/run` values even when it starts
180
+ outside an interactive shell, while generated NexusCrew and Fleet boot scripts create and
181
+ export the same runtime paths explicitly. Existing custom `TMUX_TMPDIR` values remain
182
+ authoritative; Linux and macOS behavior is unchanged.
183
+ - The Fleet runtime/launch layer, CLI lifecycle, MCP tool directory, pairing coordinator, shared
184
+ roster model and Fleet settings components are split into focused modules without changing
185
+ their public routes, commands, payloads or security boundaries. This keeps the current product
186
+ behavior while making the next gateway and federation work reviewable in smaller units.
187
+ - Regression coverage includes a real private-socket cold start with no existing tmux server,
188
+ profile-less Termux environment reconstruction, generated boot scripts and the extracted module
189
+ boundaries. Gate: **819 Node tests** (818 pass / 1 platform skip), **12 frontend component
190
+ tests**, production build and zero production dependency vulnerabilities.
191
+
192
+ ## 0.8.16 — 2026-07-14 — "Honest Tunnel"
193
+
194
+ - One-link pairing now treats its embedded SSH endpoint as portable routing rather than a
195
+ transferable identity. Authentication and SSH-stage failures automatically expose the local
196
+ override, where a device can use the same Host alias that already selects its own key, agent,
197
+ port or ProxyJump. The override is saved only in that node's local routing configuration;
198
+ private keys never enter the link, NexusCrew configuration, logs or federation payloads.
199
+ - A supervised `ssh` process is no longer reported ready merely because it remains alive.
200
+ After the stability window NexusCrew probes the exact loopback `-L` port and advertises
201
+ transport readiness only when that forward accepts TCP; unreachable connects are bounded by
202
+ OpenSSH's 15-second timeout and remain in an explicit probing state.
203
+ - Startup, stop and restart reconcile strict NexusCrew tunnel pidfiles against the authoritative
204
+ node store. Verified supervisors left by a removed node or interrupted older runtime are
205
+ stopped safely, while configured nodes, unrelated processes, symlinks and invalid names are
206
+ untouched.
207
+ - Regression coverage exercises exact SSH argv, local-alias recovery in the real pairing
208
+ component, TCP-forward readiness versus a merely live child, generation ownership, safe
209
+ orphan reconciliation, server startup ordering and lifecycle cleanup. Gate: **788 Node
210
+ tests** (787 pass / 1 platform skip), **12 frontend component tests**, production build and
211
+ zero production dependency vulnerabilities.
212
+
213
+ ## 0.8.15 — 2026-07-14 — "Steady Link"
214
+
215
+ - One-link pairing now waits against a real 20-second readiness deadline with bounded retries.
216
+ Immediate loopback refusals can no longer exhaust the probe in 3.75 seconds and tear down a
217
+ valid SSH session just as key negotiation completes on Termux, Linux, or macOS.
218
+ - Per-tunnel diagnostics are never empty by design: NexusCrew writes safe supervisor lifecycle
219
+ markers and forces SSH error-level diagnostics even when a user Host stanza requests quiet
220
+ logging. The 0600 log omits synthetic argv dumps, key contents, tokens and credentials;
221
+ OpenSSH's own error text may identify the failed target.
222
+ - Local and federated deck tabs can be reordered inside their owner group with a dedicated
223
+ Pointer Events handle on mouse, touch, or pen, plus keyboard left/right controls. The
224
+ owner-qualified order autosaves per browser, survives polling/reload, and follows rename and
225
+ deletion without changing deck ownership.
226
+ - Regression coverage includes delayed SSH readiness at eight seconds, bounded permanent
227
+ failure, safe tunnel logging, owner-isolated deck ordering, pointer input, keyboard input,
228
+ and cross-owner rejection. Gate: **785 Node tests** (784 pass / 1 platform skip), **11
229
+ frontend component tests**, production build, and zero production dependency vulnerabilities.
230
+
231
+ ## 0.8.14 — 2026-07-14 — "Private Launch"
232
+
233
+ - Managed provider credentials can now be supplied per node from the PWA when they are absent
234
+ from that device's runtime environment or compatible user-owned provider files. The local
235
+ store is write-only through the API, owner-only on disk, never federated or backed up, and the
236
+ UI reports only configured/source state plus the exact active cells affected by a change.
237
+ - Secret-bearing launches use a private one-shot Unix-socket broker. The tmux command receives
238
+ only the helper path, socket path and a short-lived random nonce; provider values never enter
239
+ process arguments, `tmux -e`, tmux global/session environment, temporary files or logs. The
240
+ helper validates the bounded payload and directly spawns the configured CLI without a shell.
241
+ - Credential lookup is deterministic across Linux, macOS and Termux: service environment,
242
+ node-local store, `providers.zsh`, canonical `ai.env`/secure files, then the legacy store.
243
+ Mixed-case environment names are accepted, unsafe files/symlinks are rejected, and unresolved
244
+ shell expansion is never interpreted as a credential.
245
+ - Unmanaged tmux sessions can be explicitly marked technical. They stay hidden from normal
246
+ all/pinned/active/off views, appear in a dedicated technical view, and every Local/Hydra count
247
+ reflects only the rows currently displayed; managed cells remain protected from relabeling.
248
+ - Fleet reorder handles now use one Pointer Events implementation for mouse, touch and pen.
249
+ Destination highlighting, pointer capture, edge auto-scroll, release-only commit and
250
+ Escape/cancel rollback preserve the same owner-qualified order on mobile, expanded desktop
251
+ and compact desktop while keeping native card-to-deck drag separate.
252
+ - Tests: **781 total** (780 pass / 1 platform-dependent skip) in the isolated Node harness plus
253
+ 8 passing frontend component tests; production build and dependency audit required before
254
+ publication. Real cross-device drag and provider launches remain operator field tests.
255
+
256
+ ## 0.8.13 — 2026-07-14 — "Fleet Network"
257
+
258
+ - The MCP bridge now exposes `nc_cells` and `nc_send_cell`. An active managed cell can discover
259
+ the owner-qualified Fleet directory allowed by the current Hydra topology and submit bounded
260
+ text to one exact active destination. Remote ingress is bound to the authenticated route,
261
+ inactive cells are never silently queued, and `submitted` means only verified paste plus
262
+ Enter—not model acceptance or task completion.
263
+ - Cell submission uses an exact Fleet-cell/tmux match, bracketed paste, pane revalidation and a
264
+ separate submit. Codex and Codex-VL receive a paced burst flush before Enter to avoid long
265
+ composer input loss; the printable envelope prevents Pi from treating a trailing newline as
266
+ a second submit.
267
+ - The desktop and mobile Fleet rosters now persist the same owner-qualified manual order.
268
+ Dedicated mouse/touch handles and keyboard move controls avoid accidental power actions,
269
+ preserve pin priority and keep compact and expanded desktop views consistent.
270
+ - Selective backup schema v2 exports cells and reusable engines independently, accepts legacy
271
+ cell-only v1 files, previews conflicts and confirms every overwrite before mutation. Archives
272
+ contain environment-variable names only; secret values, tokens, live tmux IDs and provider
273
+ credentials remain local.
274
+ - Provider variables can be resolved by name from the service environment or a user-owned
275
+ `~/.config/ai-shell/providers.zsh` parsed strictly as data. The file is never sourced or
276
+ executed, and values are never copied into NexusCrew config, services or backups.
277
+ - Share is now a property of the local device and uses one selected, existing hub connection.
278
+ Outbound target cards no longer imply that the hub itself is being shared; inbound shared
279
+ clients retain hub-controlled network/relay/selected visibility, and publication waits for a
280
+ bounded authenticated readiness acknowledgement.
281
+ - Every Local or remote deck owner has its own inline `+ new` action, with no fallback to a
282
+ different owner. Deck tile layout and Fleet roster order continue to autosave independently.
283
+ - npm update checks and generated services use a stable NexusCrew working directory, parse npm
284
+ JSON-scalar and plain-semver output, and preserve a deterministic UTF-8 environment. Local
285
+ PTYs inherit only reviewed cross-platform variables; loader injection remains stripped.
286
+ - Real Termux launches npm-installed Codex and Codex-VL scripts through the active Node binary
287
+ when `/usr/bin/env` is unavailable, while native clients such as Pi stay direct. Immediate
288
+ managed-client exits produce bounded, redacted diagnostics and zero-window tmux phantoms are
289
+ removed from both session discovery and Fleet state.
290
+ - The packaged and canonical NexusCrew/tmux messaging skills plus shared AGENTS/CLAUDE guidance
291
+ document the eight-tool contract and prefer authenticated cell delivery over direct tmux
292
+ injection. Persistent offline queues, attachments and delegated capability workers remain
293
+ explicitly deferred rather than being represented as implemented.
294
+ - Tests: **770 total** (769 pass / 1 platform-dependent skip) in the isolated Node harness plus
295
+ 5 passing frontend component tests; production build PASS. Real Mac–hub–Pixel end-to-end
296
+ pairing and delivery remain an operator field test and are not represented as automated.
297
+
298
+ ## 0.8.12 — 2026-07-13 — "Mobile Roster"
299
+
300
+ - The mobile Fleet home now uses the same per-location roster contract as the desktop sidebar.
301
+ Local and every Hydra route can be collapsed independently and filtered by all, pinned,
302
+ active, or off; state persists under one shared key.
303
+ - Mobile pins are route-qualified, remote cells are pinnable, and both surfaces use the same
304
+ deterministic order: pinned, live, fresh output, recent activity, then label. Search counts
305
+ and scans the complete multi-node roster instead of only local sessions.
306
+ - New jsdom component tests exercise real filter, collapse, persistence, pin and multi-node
307
+ search interactions. The official Node harness also gives every test worker its own private
308
+ tmux socket, eliminating cross-file server-exit races without touching operator sessions.
309
+ - The SSH supervisor continuously proves ownership of its pidfile generation. Losing ownership
310
+ or failing a state write now terminates the child SSH process and supervisor instead of
311
+ leaving an invisible retry loop.
312
+ - Explicit Share fails closed unless its local NexusCrew port is present; reverse forwarding
313
+ can no longer substitute the hub's remote port. macOS shutdown detects zombie supervisors
314
+ through argv-safe `ps` when `/proc` is unavailable.
315
+ - Generated Linux user units now pull in `network-online.target`. Doctor warns when user linger
316
+ is disabled and explains that a Termux boot script still requires the Termux:Boot app to be
317
+ installed and launched once.
318
+ - Tests: **749 total** (748 pass / 1 platform-dependent skip), production build PASS, root and
319
+ frontend dependency audits clean. Mac–Pixel–hub end-to-end pairing was not executed in this
320
+ release gate.
321
+
322
+ ## 0.8.11 — 2026-07-13 — "Tmux Survival"
323
+
324
+ - Linux service lifecycle is now tmux-safe. Generated units use `KillMode=process`, and an
325
+ existing installation receives a narrow atomic systemd drop-in plus `daemon-reload` before
326
+ `nexuscrew stop` or `nexuscrew restart`. If that protection cannot be installed, lifecycle
327
+ commands fail closed without touching the service or its tunnels.
328
+ - Managed SSH supervisors are closed before a service restart and restored only through the
329
+ normal autostart path. The npm updater now rejects an unverified restart result instead of
330
+ continuing to health checks or reporting a successful update.
331
+ - Token rotation verifies the tmux-safety guard before changing credentials and reports an
332
+ incomplete operation if the runtime cannot be restarted; the direct update helper likewise
333
+ returns failure instead of claiming that the new code is active.
334
+ - `nexuscrew doctor` treats an unsafe Linux `KillMode` as a blocking failure and explains that
335
+ restarting the HTTP service could terminate the shared tmux server.
336
+ - The official test harness removes inherited `TMUX` identity and places every real tmux smoke
337
+ test on a private socket below its disposable test root. Tests can no longer attach to,
338
+ resize, or terminate an operator session.
339
+ - The mobile roster footer now keeps endpoint/version metadata and the IT/EN/ES language
340
+ controls aligned at narrow widths, with bounded ellipsis instead of overlap.
341
+ - Tests: **739 total** (738 pass / 1 platform-dependent skip), targeted lifecycle isolation and
342
+ full-suite before/after tmux inventory checks, production build PASS, dependency audit clean.
343
+
344
+ ## 0.8.10 — 2026-07-13 — "Hydra Federation"
345
+
346
+ - Hydra pairing now creates one supervised OpenSSH connection per hub: the private `-L`
347
+ channel is automatic, while `-R` exists only after an explicit Share toggle and a real
348
+ authenticated readiness probe. The retired rendezvous/node-role runtime can no longer
349
+ start a second hidden tunnel, and pairing cannot self-escalate to shared.
350
+ - Tunnel liveness no longer mistakes a surviving `autossh` wrapper for a healthy SSH child.
351
+ `ssh` is the single runtime transport and a blocking doctor requirement; `autossh` is
352
+ reported separately as optional and unused. PWA failures no longer recommend private or
353
+ nonexistent CLI commands.
354
+ - The read-only MCP bridge adds owner-aware `nc_deck`: a cell can discover every local or
355
+ authorized shared-owner deck containing its tmux session and read visually ordered members
356
+ with stable owner IDs, Fleet cell names, exact tmux sessions, viewer-valid Hydra routes and
357
+ self identity. The packaged NexusCrew skill documents discovery without direct state access.
358
+ - Decks are owner-qualified and resolve their tiles from the viewer's route, so identically
359
+ named sessions on different nodes never collapse or fall back to a local session. Shared
360
+ owner decks are read through the existing scoped Hydra channel and remain visibly unavailable
361
+ when their owner is offline.
362
+ - The Fleet roster keeps its desktop chrome fixed and groups every local or remote location
363
+ behind independent collapse and all/pinned/active/off controls. Pins use route-qualified
364
+ identities and deterministic ordering; the mobile header now remains fixed while its roster
365
+ scrolls naturally without hiding the last card under the create button.
366
+ - Fleet Settings separates location management from the whole-network overview. Managed-cell
367
+ power opens the shared launch editor, while delete/import and engine definitions remain in
368
+ Settings and preserve the selected Hydra route.
369
+ - A stopped managed session can restart inside its existing deck tile: only the terminal
370
+ generation is replaced, and transient WebSocket reconnects are bounded without reviving a
371
+ deliberately exited terminal.
372
+ - Public `status`, `stop`, and `restart` now reconcile service-managed and portable runtimes,
373
+ clean stale PID ownership safely, stop NexusCrew-managed SSH supervisors, and refuse a silent
374
+ HTTP-port move when paired peers depend on the configured endpoint.
375
+ - Tests: **726 total** (725 pass / 1 platform-dependent skip), frontend production build PASS,
376
+ dependency audit clean, isolated HOME clean, and package/public-tree verification required
377
+ before publication. Real Mac–Pixel–hub interoperability remains an external follow-up and is
378
+ not represented as an automated test.
379
+
380
+ ## 0.8.9 — 2026-07-12 — "Hydra Workspaces"
381
+
382
+ - Remote Fleet tiles now attach to their real `tmuxSession`, including an idempotent migration
383
+ for persisted 0.8.8 deck references. Automatic grid growth preserves visual row order,
384
+ widths, tile heights and zoom; deck switches and renames flush dirty state before moving.
385
+ - Named decks switch inside the current PWA by default; only `↗` detaches a browser window.
386
+ Fleet dialogs are viewport-owned with Escape, focus trapping/restoration and visible errors,
387
+ while long sidebar names stay within their cards without covering actions.
388
+ - Pairing link creation reuses the configured rendezvous without confusing its published
389
+ NexusCrew HTTP port with the SSH transport port. Peers exchange roles, so intermittent
390
+ inbound clients become neutral `passive` entries while real node/auth failures remain errors.
391
+ - Clipboard images and OS-dropped files upload directly to the receiving terminal session,
392
+ including federated routes, with progress and per-file errors. Saved paths are pasted without
393
+ Enter; normal text paste and private session-card drag/drop are unchanged.
394
+ - Settings → Fleet adds selective, schema-closed cell/system-prompt backup and restore with
395
+ engine mapping, overwrite confirmation, atomic writes, secret exclusion and explicit
396
+ `needsRestart` reporting for active cells.
397
+ - Global npm installs gain stable-only automatic updates with no downgrade, a per-home
398
+ interprocess lock, exact CLI/runtime verification, same-port restart, one exact-version
399
+ rollback and blocked retry after an unhealthy update. Errors and logs are bounded/redacted.
400
+ - Tests: **693 total** (692 pass / 1 platform-dependent skip), with production build and
401
+ package/audit verification performed before local installation.
402
+
403
+ ## 0.8.8 — 2026-07-12 — "Reliable Composer"
404
+
405
+ - The PWA composer now sends long and multiline drafts through xterm's explicit paste path,
406
+ preserving the terminal application's bracketed-paste mode. Enter travels as a separate
407
+ input only after the complete paste was accepted, so agent TUIs no longer absorb submission
408
+ into a non-bracketed paste burst.
409
+ - WebSocket input delivery is observable instead of silently dropping writes while reconnecting.
410
+ If the terminal is not ready or disconnects during paste, the composer keeps the full draft
411
+ and shows a localized retry message; successful sends continue to keep the mobile keyboard
412
+ focused.
413
+ - The README mobile Fleet image is now one metadata-free animated GIF built from the two current
414
+ phone captures, with a compact cursor-only second frame to avoid full-screen flicker.
415
+ - Tests: **664 total** (663 pass / 1 platform-dependent skip), production dependency audit
416
+ clean, plus a real xterm smoke proving an exact 3,000-character bracketed payload.
417
+
418
+ ## 0.8.7 — 2026-07-12 — "One-Link Pairing"
419
+
420
+ - Settings → Nodes and the first-run wizard now share one prominent **Connect with one link**
421
+ card. Deliberate paste, the clipboard button, QR scan and deep links use the same controller;
422
+ a complete v2 link connects automatically, while old or incomplete links reveal only the
423
+ routing details still required.
424
+ - The QR flow now opens a live rear-camera scanner with distinct permission, no-camera and
425
+ unsupported-browser errors plus a photo fallback. Its scan region covers the QR instead of
426
+ cropping a code that fills the phone preview, and every success, cancel or unmount releases
427
+ the camera immediately.
428
+ - Pairing reports structured validation, SSH start/readiness, invite exchange, final tunnel,
429
+ confirmation and health stages. Transport and protocol requests are bounded, ambiguous
430
+ one-time joins are never replayed, provisional state is rolled back, and success requires
431
+ authenticated federation health plus an identity match with the original link.
432
+ - Retry controls now follow the server's actual retryability, manual Enter applies embedded v2
433
+ fields before submission, and the wizard cannot be dismissed while a pairing request is in
434
+ flight.
435
+ - Tests: **660 total** (659 pass / 1 platform-dependent skip), production dependency audit
436
+ clean, plus a real Chrome camera smoke that reads a generated pairing QR, enters the shared
437
+ card and verifies MediaStream cleanup.
438
+
439
+ ## 0.8.6 — 2026-07-12 — "Connected Fleet"
440
+
441
+ - Cell power now opens one shared launch editor from Home, the sidebar and Settings. When a
442
+ cell is off, engine, model, permission policy and boot can be reviewed before every start;
443
+ choices are remembered per cell and per engine. Provider and credential definitions remain
444
+ in Settings → Fleet, while Pi is always constrained to Standard permissions.
445
+ - Settings → Fleet now inventories managed and unmanaged tmux sessions across Local and every
446
+ reachable Hydra route. A live unmanaged session can be explicitly adopted as a managed cell;
447
+ legacy `cloud-X` sessions become cell `X`, and the operator must choose an already declared
448
+ engine so no provider or model is inferred.
449
+ - Pairing links now support a strict v2 payload containing the display label, route slug,
450
+ OpenSSH target or Host alias, and optional SSH port. Paste, QR scan and first-run deep links
451
+ pre-fill the same form before **Test and connect**; v1 links remain compatible. No SSH key,
452
+ API key or PWA token is added to the link.
453
+ - Fleet inventory actions now follow the selected Hydra route and its real capabilities,
454
+ including READONLY. Power, restart, import and removal are shown only where the remote
455
+ provider actually permits them.
456
+ - External Fleet discovery is portable across Linux, macOS and Termux: configured paths,
457
+ `$PREFIX/bin/fleet` and `~/.local/bin/fleet` use the same runtime and boot-owner resolver.
458
+ Explicit external pins fail closed instead of falling through to another executable.
459
+ - Claude-compatible managed launches set matching context and auto-compaction windows,
460
+ including one-million-token profiles where declared. Permission overrides cannot bypass
461
+ Pi's Standard-only policy.
462
+ - Tests: **636 total** (635 pass / 1 platform-dependent skip), plus a clean production build
463
+ and zero production dependency vulnerabilities.
464
+
465
+ ## 0.8.5 — 2026-07-12 — "Clean Fleet"
466
+
467
+ - The primary `+` now creates a managed Fleet cell on Local or a selected reachable Hydra
468
+ node. Cell IDs accept uppercase characters, and every configured node remains visible in
469
+ the Fleet inventory while unreachable destinations are clearly disabled for creation.
470
+ - Managed cell cards expose direct power and Settings buttons. Start, stop, restart and edit
471
+ are explicit in Settings → Fleet; deletion is confined to that settings surface, removing
472
+ the ambiguous three-dot/delete-only lifecycle.
473
+ - The power sheet is lifecycle-only and responsive: it no longer mixes engine/provider/model
474
+ selection into start/stop, and boot changes are persisted without resetting an existing
475
+ boot choice on quick start.
476
+ - Fresh fleets provide four clean CLI adapters: Claude Code, Codex, Codex-VL and Pi. Provider
477
+ choices are scoped to the selected CLI, with documented native/cloud/local options and a
478
+ renameable custom fallback. Legacy Z.AI A/P credential profiles remain runtime-compatible
479
+ but are absent from the new-provider catalog.
480
+ - Claude enterprise providers launch through their dedicated Bedrock, Vertex or Foundry
481
+ environment selectors; Codex OpenAI API uses `OPENAI_API_KEY`; Pi can use its own configured
482
+ default without NexusCrew forcing a provider or model.
483
+ - Node pairing now focuses and explains missing fields and makes explicit that the loopback
484
+ address in a pairing link is intentional and transported through the user's SSH Host.
485
+ - Tests: **602 total** (601 pass / 1 platform-dependent skip), plus a clean production build
486
+ and zero production dependency vulnerabilities.
487
+
488
+ ## 0.8.4 — 2026-07-12 — "Hydra Everywhere"
489
+
490
+ - The fleet roster is global rather than active-only: local, direct and transitive sessions
491
+ remain visible with route/location labels, stable slugs and offline last-seen state.
492
+ - Session creation and Fleet engine/cell management can target Local or any reachable Hydra
493
+ route. Remote lifecycle controls use route-qualified identity and inbound peer health is
494
+ verified instead of trusting a running tunnel process alone.
495
+ - Node cards restore explicit tunnel power controls and expose label rename independently of
496
+ the stable route slug; pairing and capabilities remain relay-policy scoped.
497
+ - macOS terminal copying now supports Shift-drag / Shift-Control-drag local selection and
498
+ mobile terminals support long-press then drag selection without sending mouse events to tmux.
499
+ - The composer send button writes text plus a real carriage return and preserves textarea
500
+ focus, keeping the mobile software keyboard open between messages.
501
+ - Linux x64/ARM64, macOS x64/ARM64 and Termux Android ARM64 now resolve scriptless platform
502
+ PTY prebuilds only. Global installs no longer require native install-script approval.
503
+
504
+ ## 0.8.3 — 2026-07-12 — "Simple and Clean"
505
+
506
+ - `nexuscrew` starts or reuses the loopback server in the background, prints a compact
507
+ status/guide, and exits. Only the first run opens the PWA wizard. `nexuscrew show` opens
508
+ the PWA, while `nexuscrew show token` prints the clickable authenticated fragment URL.
509
+ - Startup persistence is explicit: `nexuscrew boot` installs/enables the native user service
510
+ on Linux/macOS or the Termux:Boot script; `boot off|status` controls and reports it. A normal
511
+ first run no longer silently opts the host into boot persistence.
512
+ - The Hydra roster retains transitive peers as offline entries with last-seen information
513
+ while a relay is unavailable, then reconciles them when the relay returns or is removed.
514
+ - Node tunnel power is restored as a direct action in both mobile and desktop lists. Session
515
+ menus remain session-only, avoiding ambiguity between killing a session and controlling its link.
516
+ - Settings → Fleet now selects Local or any reachable Hydra route for engine and cell
517
+ management. Federated Fleet requests use the scoped, hop-bounded allowlist and honor READONLY.
518
+ - Managed engines expose an explicit permission policy. New Claude engines, including Z.AI,
519
+ default to `--dangerously-skip-permissions` with a Standard opt-out; Codex and Codex-VL
520
+ default to Standard with an opt-in for `--dangerously-bypass-approvals-and-sandbox`.
521
+ - The Nodes UI describes pairing as connecting an existing NexusCrew installation: every
522
+ installation remains local and peer-capable, with no artificial client/server role.
523
+ - Tests: **538 total** (537 pass / 1 platform-dependent skip), including first-run PWA,
524
+ multi-hop Fleet routing, stale roster reconciliation, boot opt-in and contaminated env runs.
525
+
526
+ ## 0.8.2 — 2026-07-11 — "Simple Federated Hydra"
527
+
528
+ - Replaces client/node roles in first-run UX with one local node plus a single **Nodes**
529
+ surface for reciprocal PWA pairing.
530
+ - One-time ten-minute link/QR pairing creates scoped per-peer credentials; the main PWA
531
+ token is never exchanged. Invites and peer state remain local 0600 stores.
532
+ - Uses an existing OpenSSH Host alias without creating keys or editing `authorized_keys`;
533
+ auto-selects autossh or supervised SSH and restores outbound links at boot.
534
+ - Adds bounded four-hop topology discovery and a separate capability-allowlisted federation
535
+ ingress for HTTP and WebSocket routing. Relay visibility is enforced symmetrically.
536
+ - Session list, creation, terminal, files and termination are location-aware across Local and
537
+ federated routes. Fleet remains local to its node.
538
+ - Reads legacy nodes schema v1 while writing the extended v2 peer schema; legacy rendezvous
539
+ runtime behavior remains available during migration.
540
+ - Tests: **528 total** (527 pass / 1 platform-dependent skip).
541
+
542
+ ## 0.8.0 — 2026-07-11 — "Many Nodes, Many Monitors"
543
+
544
+ The multi-node + multi-monitor release: one UI for the tmux fleets of several hosts,
545
+ named multi-window decks, a real CLI, an MCP operator bridge, and a first-run wizard.
546
+
547
+ - feat(mcp): **MCP bridge** — `nexuscrew mcp` runs a minimal stdio MCP server (hand-rolled
548
+ JSON-RPC 2.0, newline-delimited, no SDK deps) that brings NexusCrew inside AI sessions as
549
+ the cell→human channel: `nc_notify` (UI toast + web push), `nc_ask` (question with deferred
550
+ answer pasted back into the caller's tmux session as `[human reply · ask#<id>] …`
551
+ by default (`NEXUSCREW_REPLY_LABEL` configures the neutral operator label),
552
+ `nc_send_file` (copy into the session outbox with badge + notification), `nc_status` and
553
+ `nc_inbox` (read-only). Caller identity from `$TMUX` (`display-message #S`) with
554
+ `NEXUSCREW_MCP_SESSION` fallback; fail-closed on malformed input (garbage never crashes,
555
+ JSON-RPC errors instead).
556
+ - feat(server): notification plumbing — `POST /api/notify` (rate limit global per token +
557
+ per session, capped LRU buckets), SSE `GET /api/events` for live UI frames, web push
558
+ (`web-push` dep, lazy VAPID keys in `~/.nexuscrew/vapid.json` 0600, https-only endpoints
559
+ with private-host rejection and a subscription cap, subscriptions in `push.json` 0600
560
+ with dead-endpoint cleanup), asks store persisted in `asks.json` 0600 (hard cap on open
561
+ asks, rate-limited creation). Answer route is READONLY-gated (paste is a PTY write),
562
+ claims the ask atomically (concurrent answers cannot double-paste) and only commits
563
+ after a successful paste. READONLY is a floor: ask creation and outbox delivery are 403,
564
+ VAPID keys are never generated in READONLY, and secret stores (`vapid/push/asks.json`)
565
+ with unsafe mode/owner or symlinked are refused fail-closed.
566
+ - feat(ui): notification toasts + open-asks panel with reply box/option buttons and counter
567
+ badge (all views, i18n it/en/es); push enable/disable in Settings → System; service worker
568
+ handles `push` and `notificationclick` (deep-link `/#ask=<id>`).
569
+
570
+ - feat(cli): **unified CLI** — `nexuscrew` alone smart-ups (zero-question init → start →
571
+ URL + QR); new subcommands `up|down`, `url [--qr]`, `token rotate`, `logs [-f]`,
572
+ `doctor`, `update`, and an extended `status [--json]` with roles and per-node tunnel
573
+ state. The server startup log no longer prints the token.
574
+ - feat(nodes): **multi-node foundation** — `~/.nexuscrew/nodes.json` secret store (0600,
575
+ atomic writes, strict schema) and an SSH tunnel manager with dedicated restricted keys,
576
+ explicit loopback binds, `ExitOnForwardFailure`, and retry with backoff. CLI commands
577
+ cover node registration, tests, tunnel lifecycle, token setup, and reachable-node mode.
578
+ - feat(proxy): **single-origin multi-node** — the hub reverse-proxies `/node/<name>/…`
579
+ over HTTP and WebSocket. Local auth happens before node resolution; remote tokens stay
580
+ server-side; client credentials and hop-by-hop headers are stripped; READONLY blocks
581
+ mutations and remote PTY attach.
582
+ - feat(deck): **multi-window decks** — named workspaces at `/deck/<name>`, with one
583
+ remembered tile layout per browser and deck. Deck tiles attach with `ignore-size`; the
584
+ focused tile becomes size owner so browser windows do not fight real terminals.
585
+ - feat(ui): **remote nodes, settings, and first-run wizard** — per-node groups and remote
586
+ attach in the sidebar, grid, and decks; a three-tab settings panel for roles, nodes, and
587
+ system actions; and a skippable three-step setup wizard. Mutations use a closed-list,
588
+ READONLY-gated API with strict validation and token-redacted responses.
589
+ - security: proxy upgrade failures return a controlled 502; WebSocket upgrades
590
+ pre-authenticate through the injected header; local query tokens are stripped before
591
+ forwarding; token rotation invalidates live sessions after restart.
592
+ - i18n: all new surfaces in English, Italian, and Spanish.
593
+ - tests: suite grows from 262 to **495 tests** (494 pass / 1 skip).
594
+
595
+ ## 0.7.7
596
+
597
+ - feat(composer): **attachment button** to the left of the input — a File / Camera / Gallery
598
+ menu for quick file send. The picked file lands in the session inbox and its path is
599
+ appended to the composer text (you send it explicitly, so you can add a message). The
600
+ camera uses the native capture hint on mobile and falls back to a picker on desktop.
601
+ - feat(fleet): **built-in fleet** — engine/cell definitions in `~/.nexuscrew/fleet.json`
602
+ (editable, schema-validated), provider selection `external | builtin | disabled` chosen
603
+ once at startup, and a single boot companion service installed by `nexuscrew init` (only
604
+ when the built-in provider is active, with a migration gate that refuses a silent double
605
+ boot). Launch path is argv-direct (no shell), with a hard command/env/cwd trust boundary.
606
+ - feat(fleet): fleet HTTP API hardening — `READONLY` blocks every mutation at the route
607
+ level (external providers included), capability negotiation returns `501` for unsupported
608
+ methods, `status` exposes `provider`/`bootOwner`/`capabilities`, a `restart` capability,
609
+ and secrets (env values, prompts) are redacted from error output.
610
+
611
+ ## 0.7.2
612
+
613
+ - fix(grid): fleet cell cards in the desktop sidebar are now clickable (add tile) and
614
+ draggable into the grid when their tmux session is alive — they only exposed the
615
+ power button before, so on fleet-only hosts nothing could be dragged. Verified
616
+ end-to-end in a real browser (click → live tile, drag → new column).
617
+
618
+ ## 0.7.6
619
+
620
+ - docs: README "License" section said MIT — corrected to Apache-2.0 (badge and LICENSE
621
+ file were already correct since 0.7.1). No code changes.
622
+
623
+ ## 0.7.5
624
+
625
+ - feat(grid): **open tiles are movable** — drag a tile by its header and drop it anywhere
626
+ (same directional zones as sidebar drags: side-by-side, stack, new column).
627
+
628
+ ## 0.7.4
629
+
630
+ - fix(desktop): **black screen** on desktop in 0.7.3 — the stale-bundle banner was declared
631
+ inside the mobile branch but referenced by the desktop tree (TDZ ReferenceError).
632
+ Hoisted before both branches; the banner now also covers the mobile single view.
633
+ - fix(keybar): 8+8 keys — ↑ aligned exactly above ↓ (added ⌨ composer toggle in row 2,
634
+ matching the reference layout).
635
+
636
+ ## 0.7.3 — "Window Management"
637
+
638
+ - feat(grid): directional drop zones (VS Code-style) — hover quadrant decides: left/right
639
+ edges place side-by-side, top/bottom stack, with live preview overlay. Balanced click
640
+ placement (grid-like growth, no endless narrow columns).
641
+ - feat(size): sessions follow the focus — `window-size latest`, web clients participate:
642
+ going back to a bigger client and typing restores its size (real-tmux gated).
643
+ - feat(ui): collapsible + resizable sidebar (mini 48px with instant tooltips), pin sessions
644
+ and cells to top (persisted) + activity-based auto-sort, Termux-style two-row KeyBar
645
+ (ESC ☰ / — HOME ↑ END PGUP | ⇥ CTRL ALT ← ↓ → PGDN) with sticky ALT.
646
+ - fix(grid): xterm refits when its tile is resized (ResizeObserver) — adding tiles or
647
+ dragging dividers adapts live terminals; resize listeners cleaned on cancel/blur/unmount;
648
+ aborted drags clear the preview; tile cap enforced fail-safe.
649
+ - fix(mobile): high-visibility round action buttons (power/pin), SVG power icon
650
+ (U+23FB was tofu on Android), stale-bundle update banner (tap to reload).
651
+ - Two security review passes on the cycle (all findings addressed); 155-test suite.
652
+
653
+ ## 0.7.1
654
+
655
+ - License corrected to **Apache-2.0** (0.7.0 was published with MIT metadata by mistake;
656
+ 0.7.0 is deprecated on npm). Added NOTICE. No code changes.
657
+
658
+ ## 0.7.0 — "Fleet Deck"
659
+
660
+ - feat(grid): desktop multi-session grid — drag from the sidebar,
661
+ tiling a colonne con auto-reflow, divisori trascinabili, focus singolo, composer
662
+ per-tile a scomparsa, layout persistito (`nc_grid_v1`). Tile con `takeSize:false`
663
+ (mai resize delle sessioni vive). Zero dipendenze nuove.
664
+ - feat(fleet): logica flotta nella UI — sidebar/home unificate: celle fleet anche da
665
+ spente (⏻ up/down, engine picker, key A/P, boot persist, stato degraded) + sessioni
666
+ tmux generiche. Server: `lib/fleet/` shell serializzato sul binario `fleet`
667
+ (feature-detected con trust check: no symlink, no world-writable, schema
668
+ `kind:"ai-fleet"` obbligatorio) + `GET/POST /api/fleet/*` dietro Bearer.
669
+ - feat(sessions): lifecycle dalla UI — `POST /api/sessions` (preset allowlistati,
670
+ cwd realpath sotto home) e `DELETE /api/sessions/:name` (409 SEMPRE su `cloud-*`,
671
+ anche con fleet assente). Card ricche: activity, comando corrente, preview ultima
672
+ riga (cap 240, strip ANSI, cache 3s, best-effort).
673
+ - feat(ui): mobile restyle — home grouped by Fleet/Other sessions,
674
+ card con preview e tempo relativo, FAB nuova sessione, vista singola rifinita.
675
+ - feat(i18n): UI multilingua IT/EN/ES, picker persistito, zero deps.
676
+ - Optional fleet integration contract: `fleet status --json` (schemaVersion 1); the host
677
+ binary is trust-checked and schema-validated, feature-detected (absent → hidden UI).
678
+ - Suite: 150 tests (149 pass + 1 skip); two independent security review passes on design
679
+ and implementation (all findings addressed).
680
+
681
+ ## 0.4.3
682
+
683
+ - fix(mobile): adapt the layout to the soft keyboard. The app now uses `100dvh` and
684
+ `interactive-widget=resizes-content`, so when the keyboard opens the view shrinks and the
685
+ KeyBar stays visible above it (previously the bottom KeyBar was pushed behind the keyboard
686
+ and looked missing). The terminal also refits on `visualViewport` changes.
687
+
688
+ ## 0.4.2
689
+
690
+ - fix(attach): smart resize default. When no other client is attached to the session, the
691
+ browser now drives the size (so a small phone gets a usable, non-clipped view and clean line
692
+ editing instead of a session frozen at a larger width). When a real terminal is already
693
+ attached, it still defaults to `ignore-size` to avoid shrinking that terminal's window.
694
+ - feat(keybar): add the keys mobile keyboards lack — `tab`, always-available arrows (← ↑ ↓ →),
695
+ and a sticky `ctrl` modifier that folds the next typed character into its control code.
696
+
697
+ ## 0.4.1
698
+
699
+ - fix(install): make `node-pty` an optional dependency. On Termux/Android it has no prebuild
700
+ and `node-gyp rebuild` fails (`Undefined variable android_ndk_path`), which previously aborted
701
+ the whole global install and left the `nexuscrew` bin unlinked. As optional, its build failure
702
+ is non-fatal: the install completes and the runtime falls back to the platform PTY provider
703
+ (`@mmmbuto/node-pty-android-arm64` on Termux, `@lydell/node-pty-linux-x64` on Linux x64).
704
+
705
+ ## 0.4.0 — "pty-core"
706
+
707
+ Core rewrite from screenshot-and-poll to a faithful tmux client.
708
+
709
+ - replaced screenshotting with a **real PTY**: each attach runs `tmux attach` and bridges its
710
+ bytes to xterm.js over a WebSocket — full color, copy-mode scroll, special keys, panes, windows
711
+ - **stateless**: tmux is the persistence; no database, no accounts
712
+ - **localhost-only**: binds `127.0.0.1` and refuses any non-loopback bind
713
+ - non-destructive default: attaches with `-f ignore-size` so a small client never resizes a
714
+ session a real terminal is holding (`takeSize` to opt in)
715
+ - window/pane navigation moved to **server-side, allowlisted tmux commands** instead of fragile
716
+ client-side prefix keys
717
+ - WebSocket hardening: close on protocol violation, no second attach, clamped geometry,
718
+ backpressure cutoff, JSON errors with codes
719
+ - token delivered via URL fragment (never logged), 0600 file, constant-time compare
720
+
721
+ ## 0.2.4
722
+
723
+ - added host-scoped tmux/session discovery so active session truth comes from the selected host
724
+ - bucketed launcher discovery into runnable, detected-only, and internal/plumbing entries
725
+ - improved send/interrupt flow with explicit host context and remote pane polling fallback
726
+ - added regression tests for host-scoped routes and launcher classification
727
+
728
+ ## 0.2.3
729
+
730
+ - fixed npm CLI `bin` metadata so the published package exposes `nexuscrew` correctly
731
+ - kept the corrected stable line on the main npm dist-tags
732
+
733
+ ## 0.2.2
734
+
735
+ - moved runtime to standalone tmux sessions instead of an implicit master tmux session
736
+ - made active tmux sessions the only valid chat targets
737
+ - added explicit tmux creation from detected launchers
738
+ - switched launcher discovery to runtime/shell-driven detection
739
+ - gated shell-file-only detections so they are not treated as runnable automatically
740
+ - aligned workspace defaults to the runtime user home
741
+
742
+ ## 0.2.1
743
+
744
+ - older release line, now deprecated in favor of the current stable line