Skip to content
tonythethompson edited this page Jul 10, 2026 · 1 revision

Introduction to Numan

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.

System Architecture

Numan is structured as a Rust CLI tool (numan-cli crate) with a clear separation between domain logic, state management, and CLI command handlers.

Core Components and Logic

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.

High-Level Data Flow

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"]
Loading

Install is inert: steps through the lockfile touch only the Numan root. Activation is a separate step that reaches the Nushell environment.

Core Design Principles

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.

Package Management and Activation

Numan manages different package types, primarily plugins and modules, each with distinct activation logic.

Module 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
Loading

The sequence illustrates the journaled transaction used to ensure a consistent state during the module activation process.

Lockfile Data Model

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.

Directory Structure

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

Development and Contribution

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.

Mutation and Safety Utilities

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 advisory fd_lock that ensures only one mutating process runs at a time.
  • OWNERSHIP_MARKER: A header in managed files (like numan.nu) to prevent Numan from overwriting foreign files.

Conclusion

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.

Clone this wiki locally