-
-
Notifications
You must be signed in to change notification settings - Fork 0
Introduction
Numan is a cross-platform package manager for Nushell written in Rust. It provides a robust system for managing plugins, modules, scripts, and completions through verified artifacts and reproducible lockfiles. Designed to handle the complexities of cross-platform environments and Nushell version upgrades, Numan ensures that installations remain inert until explicitly activated by the user.
Numan is early-stage (v0.1.4). Core install, activate, update, remove, gc, registry, doctor, snapshots, nupm interoperability, and shell completions are implemented.
The system is built on principles of immutability, registry-backed trust, and explicit activation isolation. It features a sophisticated transaction model with crash recovery journals for operations like activation, autoloading, and lifecycle management. Additionally, Numan provides interoperability with existing nupm installations, allowing for discovery and one-way import of compatible packages.
Numan is structured as a Rust CLI tool (numan-cli crate) with a clear separation between domain logic, state management, and CLI command handlers.
The architecture is divided into several specialized modules:
- Core Logic: Handles platform detection, package types, version resolution (semver), and registry verification.
- Installation: Manages the download, verification (SHA256/Ed25519), and extraction of artifacts into immutable paths.
- State Management: Maintains the authoritative JSON lockfile, lifecycle journals, and immutable activation snapshots.
- Nushell Integration: Handles path probing, plugin registration, and managed vendor-autoload file generation.
The following diagram illustrates the flow from package discovery to Nushell activation.
flowchart TD
A["Registry Index"] -->|Search and sync| B["Numan CLI"]
B -->|Install| C["Immutable Storage"]
C --> D["Lockfile v2"]
D -->|Explicit activate| E["Nu Integration"]
E -->|Write| F["Managed numan.nu"]
E -->|Register| G["Nu Plugins"]
Install is inert: steps through the lockfile touch only the Numan root. Activation is a separate step that reaches the Nushell environment.
Numan adheres to strict architecture rules to ensure system stability and user control.
| Principle | Description |
|---|---|
| Install is Inert |
numan install only writes to $NUMAN_ROOT. It never invokes Nushell or modifies shell configuration. |
| Activate is Separate | Only activate or deactivate commands modify Nushell integration state (e.g., writing autoloads). |
| Lockfile as Truth | The lockfile is the authoritative source for installed and active state; derived states are non-authoritative. |
| Immutable Payloads | Artifacts are stored in content-addressed, versioned paths. They are never overwritten in place. |
| Mutation Serialization | All mutating commands must acquire a global mutation lock (mutation.lock) to prevent concurrent corruption. |
Numan manages different package types, primarily plugins and modules, each with distinct activation logic.
For modules, Numan manages a single external file: <vendor-autoload-dir>/numan.nu. This file contains use statements for all active modules. Before the live file is replaced, Numan generates a candidate file and validates it by running nu -n <candidate> to ensure syntax and resolution correctness.
sequenceDiagram
participant User
participant CLI as Numan CLI
participant Journal
participant Nu as Nushell Binary
participant FS as Filesystem
User->>CLI: numan activate owner/pkg
CLI->>FS: Generate candidate file
CLI->>Nu: Validate with nu -n
Nu-->>CLI: Success
CLI->>Journal: Write Prepared Stage
CLI->>FS: Atomic Replace numan.nu
CLI->>Journal: Write Replaced Stage
CLI->>FS: Update Lockfile
CLI->>Journal: Clear Journal
CLI-->>User: Activation Complete
The sequence illustrates the journaled transaction used to ensure a consistent state during the module activation process.
The Lockfile (v2) is the ground truth for the system. It tracks activation identity (Nu version, executable hash) and package provenance.
| Field | Type | Description |
|---|---|---|
revision_id |
String | Unique ID for the specific package revision. |
payload_sha256 |
String | Integrity hash of the installed payload. |
selection_reason |
String | Why the package was selected (e.g., explicit install). |
module_activation |
Object | Metadata for active modules (Nu version, paths, timestamp). |
plugin_activation |
Object | Metadata for registered plugins. |
By default, Numan organizes its data under a platform-specific root (e.g., ~/.local/share/numan on Linux).
numan/
├── config.toml # Registry configurations and defaults
├── lockfile # Authoritative pinned installs (JSON)
├── packages/ # Immutable versioned payloads: <type>/<owner>/<name>/<version>-<hash>/
├── registries/ # Cached and signed registry indexes
├── state/ # Transaction journals and mutation.lock
└── nu_state/ # Cached Nu paths and derived autoload-state
Numan is developed using Rust 2021 edition. Contributors must adhere to strict quality gates, including cargo clippy (enforcing -D warnings) and cargo fmt. The project maintains a high testing standard with 376 tests, including "real-Nu" acceptance tests that are ignored by default and run on CI to verify actual shell integration.
Key utilities for maintaining system integrity include:
-
write_json_atomic: Uses a temporary file and atomic persist to prevent partial writes. -
acquire_mutation_lock: An advisoryfd_lockthat ensures only one mutating process runs at a time. -
OWNERSHIP_MARKER: A header in managed files (likenuman.nu) to prevent Numan from overwriting foreign files.
Numan provides a robust, safety-first approach to Nushell package management. By decoupling installation from activation and utilizing a journaled, lockfile-driven state model, it offers developers a reliable environment for managing shell extensions across different platforms and Nushell versions. Its interoperability with nupm further positions it as a comprehensive solution for the evolving Nushell ecosystem.
Numan wiki for tonythethompson/numan · v0.1.4 · MIT