Repository navigation
v7.81.0
Pairs with engine-service-v0.1.160 (REQUIRED_ENGINE_VERSION unchanged). The plugin installs the CLI (RDR-228 Phase 2): a session with no CLI is asked one question (local, cloud, CLI only or not now), and the setup tool builds the CLI with nx self install --bootstrap and sets up the chosen service in the background.
Added
-
nx self install --bootstrapinstalls the CLI for the first time from a throwawayuvenvironment (RDR-228 Phase 2 Step 1, nexus-sv2wx.14).uv tool run --python 3.12 --from conexus==<version> nx self install --bootstrapbuilds one generation from the package index at the version of thenxrunning it, pointscurrentat it and writes the shims, with a receipt that lists no extras. It does not runuv cache prune, which the plain command runs at its end (23.4 GiB removed from a developer's cache in the CA-3 test). The flag is the only way into this path: without it a throwaway environment and a development checkout refuse with the same message as before. With a complete install present (currentpointing at a generation with a receipt and the shims in place, or auv toolinstall) the flag refuses in one line naming the plainnx self installand changes nothing; it also refuses, naming the generation, whencurrentnames a directory whose receipt is missing or unreadable. A run that died after its build or after the flip, which leaves a receipted generation with nocurrentor with no shims, is finished by running the same command again, with no rebuild, when the generation is at the running version and its interpreter answers the shim lookup; any other leftover is replaced by a fresh build. The Windows generation flip no longer fails over acurrentwhose target is gone: it skips recording that target asprevious. It refuses before building, naming the file, whennxor another shim name in the bin directory is a program that is not nexus's (not a nexus shim and not a symlink into theuv tooltree). A failed build names re-running the same bootstrap command, notnx self install. It takes neither--versionnor--extras. -
nx-mcpregisters two tools,setupandsetup_status, and the plugin's stand-in server offers the same two (RDR-228 Phase 2 Step 3, nexus-sv2wx.16).setuptakesmode(local,cli-onlyornot-now) and, forlocal,autostart(false unless given), starts the plugin's setup process (conexus/launch/nx_setup.py) and returns at once with the stage, how long that stage usually takes and the earliest time to ask again;setup_statusreports the stage, the log path and the next step. The real server registers them in every session, 46 tools where there were 44. When a usable service is already set upsetupstarts nothing andsetup_statussays nothing is missing; when none is found the server's instructions say what is missing and what fixes it, and that the user decides. "Usable" is whether the storage clients' own endpoint resolution succeeds, so a savedservice_urlwith no resolvable token is not usable. A last run that failed, was interrupted, ended withnx doctorproblems or could not detach is reported even when a service answers. Every returned text that mentions a recorded run shows its mode and autostart, and every text that tells the model to callsetupsays to ask the user first. The launcher hands the real server the setup process's path inNX_SETUP_SCRIPT; without it the tools start nothing and answer with the terminal commands (nx init). The real server starts the setup process without a Windows job object (run_bounded(contained=False)), so the build it detaches survives the call.NX_SETUP_SCRIPTis accepted only as an absolute path to a file namednx_setup.py. A managed service ("cloud") is refused until its credentials page exists. Neither tool is auto-approved, so each call can prompt the user. The stand-in's tools of the same names took no argument in the plugin release before this one, installed nothing and carried other descriptions. -
The plugin's session-start hook puts the one question and reports eight states,
/conexus:setupis the way back, andsetuprepairs a CLI that cannot start (RDR-228 Phase 2 Step 4, nexus-sv2wx.17). The hook reports the first of: a setup run is live; the CLI is found and cannot start; the CLI resolves and a service is usable (nothing); a run was interrupted; the last run failed; no CLI (Local, CLI only or Not now, sizes shown, and for Local whether to start at login); a provisioned local service is down; no service is set up. Nothing is installed without asetupcall, and every text that suggests one tells the model to ask the user first. The user's choice is honoured: a "not now" answer, or a recorded CLI-only run, makes the "service is down" and "no service is set up" lines one quiet line naming/conexus:setupthat asks nothing, and "not now" does the same for the report of a stale failed or interrupted run (a live run and a CLI that cannot start are never quieted)./conexus:setupcallssetup_statusandsetupand has nonxshell line; with a CLI older than this release it givesnx self installthennx upgradeas text.- A CLI that is found and cannot start (for example a generation whose Python
uvpruned) is no longer a failed server. The launcher checks the files, starts nothing, and serves the stand-in, which says "Nexus is installed but cannot start; setup repairs it". On POSIX a gonehomeinpyvenv.cfgis not enough by itself (the interpreter can still start through the venv'sbin/pythonlink); it counts beside apython*link that points nowhere, which is what auvprune leaves, and a script whose own shebang names a missing interpreter counts alone.nx self install --bootstrapnow treats acurrentgeneration, and a legacyuv tool install conexustree (the README's own install path), whose Python is gone as not installed, so the repair has something to run (before, it refused with "already installed"); a brokencurrentgeneration is repaired even beside a working legacy tree. - A usable service is the CLI's definition (nexus-9i4d4 item 9): the plugin's check returns what
resolve_service_endpoint()does, so a saved address with no token is not a service. The hook's file reads (the setup status, its error record and the lease) retry a Windows sharing violation for at most 30 ms together, where the setup process's own reads wait two seconds. A hand-editedconfig.ymlwith the credentials in flow style (credentials: {service_url: ..., service_token: ...}) is read as the CLI reads it, and a lease just past its time to live is kept while its owner process is alive, so a laptop that slept is not told the service is down (the CLI also asks the port to answer/health; the plugin makes no network request, so an owner that is alive and wedged reads as usable to the hook and not to the CLI;setupgrants no such grace, so it starts the service instead of skipping the step). - While the stand-in is still running after a repair,
setup_statusasks again whether the CLI can start. A run in progress is reported as it is and the "installed but cannot start, ask first" offer is not repeated over it; while the CLI still cannot start, any other recorded state (adonefrom an earlier setup included) keeps the statement and the repair offer, with the record after it; once the CLI can start, it reports the record and the reconnect step once. It asks the same when no CLI was found at start, so adonefrom an earlier setup on a machine whose install has since been removed reads as "not installed" and the question is put again, not as a finished setup. A missing setup process in the cannot-start mode says "cannot start" and gives the repair command, not "not installed". - The choice shows what it takes on disk (2.4 GB for Local, 1.6 GB for CLI only) beside the download sizes, in both servers'
setupdescription and in the no-service notice;/conexus:setupchecks that the nexus server is connected (/mcp) before it says the CLI is older.
- A CLI that is found and cannot start (for example a generation whose Python
-
Mode
cloudofsetupopens a local credentials page for the service address, token and tenant (RDR-228 Phase 2 Step 5, nexus-sv2wx.18). The setup process serves one small page on127.0.0.1(a port the system picks, a random one-time path) from the start of the run while the CLI builds, and asks the system to open an owner-only file that sends the browser to it, so the token reaches the config file without passing through the model, the conversation or a tool argument. The page has three fields. A managed user holds a mint credential, a token bound to one tenant that mints short-lived data tokens (mint_tokenandmint_tenant); a static service token is the self-hosted case; the tenant is required for the first and unused for the second. The check needs/versionto answer 200 (/healthis not used), then sends the token toGET /v1/_whoami: 401 refuses it, 200 is a static token, 403 is a mint credential, which is proved with its tenant by minting one data token (POST /v1/data-tokens/mint, 60 seconds): 200 accepts, 403 says the token belongs to another tenant, 429 says to try again. This is what the engine does on a local and a self-hosted service and what research-37 measured at the managed edge for/healthand/version; how the managed edge answers the two/v1routes with a right credential is not measured here. A redirect is never followed, no proxy is used, and the whole check ends after 20 seconds. Accepted credentials are held in memory and saved after the build withnx config set mint_tenantandmint_token --stdinfor a mint credential orservice_token --stdinfor a static token, thenservice_urllast (a token with no address is inert), never both kinds. A run that ends with credentials accepted and not completely saved says they are discarded and that setup must be called again. A run that resumes one which saved its credentials and then failed at a later step opens no page. Replacing a saved credential isnx config initin a terminal: the real server'ssetupstarts nothing while a service answers, and a saved address with a token resolves as one. Saving one kind first removes a saved credential of the other kind with the newnx config unset, since the CLI prefers a staticservice_token. No verdict repeats the tenant as typed. Status values for the step are exactly "waiting for credentials", "page not loaded" (after 2 minutes, or at once when the system could not be asked to open the page), "credentials rejected, waiting for another try", "credentials accepted", "credentials saved" and "timed out" (the listener closes at 10 minutes and the run ends failed; during a build the status says to wait for the run to end). The page serves at most 16 connections at a time, each of which must finish its request within 5 seconds; a 17th connection shuts down the oldest one whose request is not yet read and takes its place (a connection past its read, such as a check in progress, is never shut down; if every one is, the 17th is closed), so sockets that drip bytes or reconnect the moment they are closed do not lock a right request out. The page refuses a POST that names another origin, asks for exclusive use of its address on Windows and tightens the setup directory to owner-only. Anhttp://address to a host that is not this machine is accepted; the page says before any submit, in a static note, that such an address sends the token unencrypted (the check sends it the moment the button is pressed), and warns again after the check. A stale setup lock is not reclaimed while the pid instatus.jsonor the pid of the build the run was waiting on names a live process. In that statesetup_statusand a refusedsetupboth say the heartbeat stopped but process N (or its build) is still running, and to wait and callsetup_statusagain; neither tells the model to callsetupagain. The Cloud choice now appears in the one question's table, thesetuptool's descriptions on both servers, the session-start hook and/conexus:setup, all saying address, token and tenant. The opener file is also deleted when the listener closes without a load and by the next run's start after a kill (nexus-9i4d4 items 5 and 10).nx config initasks which kind of credential you hold, hides the token as it is typed, saves only that kind's keys, and asks the tenant of a mint token that comes fromNX_MINT_TOKEN. Newnx config unset KEYremoves a saved credential from the config file. -
nx doctorhas a "Plugin setup" row for the plugin's setup status (RDR-228 Day 2, nexus-sv2wx.19). It readsstatus.json, the lock heartbeat andstatus.errorinsetup/under the config directory and namessetup.log. Not applicable (green) where no setup has run, so a new box shows no warning; green and naming the stage while a run is live (the setup process runsnx doctoritself while it holds its lock); a warning with the failure line and the log path when the last run failed; a warning that callingsetupagain resumes when a run was interrupted (statusrunning, heartbeat older than 60 seconds or no lock), which a stale lock or a log with no status file also counts as. When no other row in the samenx doctorrun is a failure or a warning (the managed deployment's "storage cannot be probed from here" row does not count), a warning about the last run (failed, verify failed, interrupted) is shown as information ("the last setup run ended , and every other row of this sweep is fine") so a box fixed by hand does not warn untilsetupis called again. The row looks in the directory the setup script writes,NEXUS_CONFIG_DIR, thenNX_CONFIG_DIR, then~/.config/nexus.tests/fixtures/setup_status_format.jsonpins the format for both the plugin script's tests and the row's.
Fixed
nx initrefuses up front on a Windows machine with Smart App Control on, andnx doctorreports its state (nexus-f9bgu.57). Smart App Control blocks the unsigned PostgreSQL bundle and the unsigned Python that uv installs, so a local install cannot work there.nx initused to download the bundle and then fail with a bare[WinError 4551]. It now stops before the download and says why, with a link to the install guide's Smart App Control section. A new Windows-onlynx doctorrow, "Smart App Control", reads the state from the registry: on fails in local mode and warns in cloud mode, evaluation warns because Windows can switch it on later, and off passes. On the measured Windows 11 Home machine with Smart App Control on, Windows also blockednx.exeitself at install, so there neither the refusal nor the row can run. Nothing changes on macOS and Linux.- After a CLI-only setup the nexus server no longer suggests
nx init(Sam, 2026-10-16; nexus-sv2wx.24). The server's embedder notice ("running with the default 384-dim embedder ... Runnx initto upgrade") is left out once setup finished in modecli-only, as the setup notice already is;nx doctorstill reports it. - The start-at-login service reads its settings from the config directory it was installed for (nexus-sv2wx.24, found by the macOS validation). The autostart unit runs
nx daemon service start --foreground --config-dir <dir>and sets noNEXUS_CONFIG_DIR, so the supervisor read the embedding choice and the Voyage key from~/.config/nexuswhile using<dir>for everything else. An install whose config lives elsewhere, with a Voyage key in~/.config/nexus, started a Voyage-only engine that refused the first store. The flag is now exported asNEXUS_CONFIG_DIRbefore any read. - A CLI whose Python
uvpruned is found as one that cannot start whenuvwrote its scripts asshpolyglots (nexus-sv2wx.20, found by the setup journey on macOS).uvwrites#!/bin/shand anexecline instead of a shebang when the install path is longer than 127 characters or holds a space. The cannot-start check read only a shebang, so the setup hook did not report state 2, the launcher started the shell, andnx_hook_shim.pypassed on its exit 126 as the hook's result at SessionStart. The check now reads the interpreter named on the second line, and the shim decides before it startsnx-hook, so such a hook exits 0 with one "could not start" line, as it does for a shebang. The CLI's own copy of the rule (self_cmd._generation_interpreter_gone) reads the same line, sonx self install --bootstrapand the plugin still agree. setup's first build on Linux no longer downloads CUDA torch, and the first session after it starts no upgrade (nexus-sv2wx.20, found by the offline setup journey). The throwaway uv environment that runsnx self install --bootstrappulled PyPI's CUDA torch with 14nvidia-*packages and triton, about 4.5 GB; the build now names the CPU build throughUV_TORCH_BACKEND=cpu(NX_TORCH_BACKENDwins and nothing else does, as for the generation itself; the CPU build is fetched from PyTorch's CPU index, a second host beside the package index). That needs a uv whoseuv tool runtakes--torch-backend: with uv 0.12.24 a first build from an empty cache held CPU torch and nonvidia-*ortritonpackage (2.4 GB); uv 0.8.0 has no such option and ignores the variable. A build writes the version-lockstep marker with the version it installed oncenx --versionof the CLI it left reports exactly that version (otherwise it logs and writes none), and the lockstep hook treats a CLI that cannot start as absent, so neither a fresh setup nor a repair is followed by a dispatched upgrade.