-
-
Notifications
You must be signed in to change notification settings - Fork 0
Nushell Interop
Nushell Interop and Autoloading in Numan provides a safe, explicit mechanism for integrating installed packages with a user's Nushell environment. While the install command remains inert to prevent accidental side effects, the activate command manages the registration of plugins and the generation of a managed vendor-autoload file for modules. This system ensures that Numan owns exactly one external file—numan.nu—within the Nushell vendor-autoload directory, maintaining strict boundaries between Numan-managed state and user configuration.
The architecture relies on a "Lockfile as Ground Truth" principle, where derived projections like autoload-state.json are used for verification, but the lockfile remains the authoritative record of activation status. All external mutations are journaled to ensure crash recovery and prevent state corruption during the transaction between Numan's root and the external Nushell data directory.
Numan interacts with Nushell primarily through a single managed file located in the Nushell vendor-autoload directory. This file, numan.nu, contains deterministic use statements that load installed modules into the shell at startup.
To prevent overwriting user-defined files or files managed by other tools, Numan uses an OWNERSHIP_MARKER. Every managed numan.nu file must begin with this specific header. Before any mutation (overwrite or delete), Numan verifies the marker and checks the file's SHA-256 against its internal state.
The activation of modules follows a strict multi-stage transaction to maintain integrity.
flowchart TD
A[Start Activation] --> B[Acquire Mutation Lock]
B --> C[Generate Candidate Content]
C --> D[Write Temporary Candidate File]
D --> E[Validate Candidate via Nu -n]
E -- Success --> F[Write Prepared Journal]
E -- Failure --> G[Cleanup & Abort]
F --> H[Replace live numan.nu]
H --> I[Write Replaced Journal]
I --> J[Update Lockfile & Autoload State]
J --> K[Clear Journal & Release Lock]
The flow ensures that only validated code is promoted to the live Nushell environment.
Module activation transforms installed package payloads into executable Nushell code. This involves resolving entry points and rendering safe use statements.
Numan validates that module entry paths are safe, ensuring containment within the Numan root and verifying that the entry is a regular .nu file. It explicitly rejects symlinks or paths that attempt to escape the payload directory using .. or absolute paths.
The content of the numan.nu file is generated deterministically, sorted by the canonical scoped package ID. This ensures human-readable and reproducible output.
| Component | Description |
|---|---|
OWNERSHIP_MARKER |
Header: # Generated and managed by Numan. Do not edit.
|
| Path Escaping | Double-quotes paths; doubles backslashes on Windows; escapes internal double-quotes. |
| Import Modes | Supports Module (use "path") and All (use "path" *). |
Numan uses a "Candidate Validation" pattern to ensure that generated autoload files will not crash Nushell on startup.
The system defines a CandidateRunner trait to abstract the execution of the Nushell binary. The NuCandidateRunner implementation invokes nu -n <candidate-path>. This "no-config" mode allows Nu to parse and validate the file without loading the user's existing configuration, providing a clean room for testing.
pub trait CandidateRunner {
fn run(&self, candidate: &Path) -> Result<()>;
}For unit and integration testing, a FakeCandidateRunner is utilized to simulate success or failure without spawning real Nushell processes, allowing for high-coverage testing of the transaction logic and recovery paths.
Numan caches critical paths and metadata about the host Nushell installation in nu_state/paths.json. This cache is populated during numan init or numan init --refresh.
The NuPaths structure tracks the identity and capabilities of the Nu binary.
| Field | Description |
|---|---|
nu_executable_hash |
SHA-256 of the Nu binary to detect upgrades/drift. |
nu_version |
The semantic version of Nushell. |
vendor_autoload_dirs |
List of directories where Nu looks for autoload files. |
vendor_autoload_dir |
The Numan-selected safe target (usually <data-dir>/vendor/autoload). |
Activation is tied to the specific Nu binary and version cached in NuPaths. If the binary on PATH changes (detected via hash mismatch), Numan blocks activation/deactivation and requires the user to run numan init --refresh to re-validate the environment.
Because activation spans two separate domains (the Numan root and the Nushell data directory), Numan uses a pending-autoload.json journal to ensure atomicity.
-
Prepared: The candidate file has been generated and validated. Numan is about to replace the live file. -
Replaced: The live file has been replaced, but Numan's internal lockfile has not yet been updated.
If Numan crashes, the next activate or deactivate call will detect the journal and attempt to reconcile the state based on these stages.
The Nushell Interop & Autoloading system provides a robust bridge between package management and shell runtime. By combining deterministic code generation, real-shell validation, and journaled transactions, Numan ensures that package activation is both safe and reversible, protecting the user's shell environment from configuration errors or partial writes.
Numan wiki for tonythethompson/numan · v0.1.4 · MIT