-
-
Notifications
You must be signed in to change notification settings - Fork 0
Activation and Deactivation
Activation and Deactivation represent the bridge between Numan's inert package storage and the live Nushell environment. While Numan follows an "install is inert" principle—meaning that the install command only writes to the $NUMAN_ROOT directory—the activate and deactivate commands are the sole mechanisms permitted to modify Nushell integration state.
Numan manages two distinct "lanes" for activation: Plugins and Modules. These lanes are processed sequentially and are independently journaled to ensure crash recovery and state integrity. Activation is tied to a specific Nushell identity, defined by the executable's SHA-256 hash and version string. If the Nushell binary changes (e.g., after a system update), Numan detects "drift" and requires a refresh before further activation mutations can occur.
The following diagram illustrates the high-level logic used when a user executes the activate command.
flowchart TD
Start[numan activate] --> Probe[Probe Nu Identity]
Probe --> DriftCheck{Drift Detected?}
DriftCheck -- Yes --> Fail[Error: numan init --refresh]
DriftCheck -- No --> LoadLock[Load Lockfile]
LoadLock --> Plan[Plan Plugin & Module Lanes]
Plan --> Consent{User Consent?}
Consent -- No --> Cancel[Abort]
Consent -- Yes --> MutLock[Acquire Mutation Lock]
MutLock --> JournalRec[Reconcile Journals]
JournalRec --> Snapshot[Create State Snapshot]
Snapshot --> PluginLane[Process Plugin Lane]
PluginLane --> ModuleLane[Process Module Lane]
ModuleLane --> Finalize[Release Lock & Print Summary]
Numan manages exactly one external file for modules: numan.nu located in the Nushell vendor-autoload directory. To ensure this file never causes Nushell to crash or hang, Numan employs a rigorous 13-step transaction protocol involving candidate generation and real Nushell validation.
- Acquire Mutation Lock: Prevents concurrent Numan processes from racing.
- Validate Nu Identity: Ensures the current environment matches cached paths.
-
Verify Ownership: Checks the existing
numan.nufor Numan's ownership marker. -
Generate Candidate: Creates a temporary file
.<uuid>.candidate.tmpwithusestatements. -
Execute Validation: Runs
nu -n <candidate>to verify syntax and path resolution. - Snapshot Lockfile: Creates an immutable point-in-time backup.
- Write Journal (Prepared): Records intent to modify the external file.
-
Replace File: Atomically renames the candidate to
numan.nu. - Write Journal (Replaced): Records that the external file has been updated.
-
Update Lockfile: Adds
ModuleActivationrecords to the authoritative lockfile. -
Update Autoload State: Writes
autoload-state.json(a derived projection). - Clear Journal: Deletes the recovery file.
- Release Lock: Ends the transaction.
| Component | Authority Level | Purpose |
|---|---|---|
| Lockfile | Ground Truth | Definitive record of which packages are active. |
| Autoload State | Derived Projection | Fast-check cache of the current numan.nu contents. |
| Pending Autoload | Recovery Journal | Ensures atomic-like behavior across internal and external state. |
Plugin activation uses the plugin add mechanism. Unlike modules, plugins are registered individually within Nushell's own internal registry. Numan manages this by setting environment variables (NUMAN_PLUGIN_BINARY and NUMAN_PLUGIN_CONFIG) and invoking Nushell to perform the registration.
sequenceDiagram
participant CLI as numan CLI
participant Journal as state/pending-activation.json
participant Nu as Nushell Binary
participant Lock as lockfile
CLI->>Journal: Write Prepared Stage
loop For each plugin
CLI->>Nu: plugin add (via env vars)
Nu-->>CLI: Success/Failure
CLI->>Journal: Mark Registered/Failed
CLI->>Lock: Update PluginActivation record
end
CLI->>Journal: Delete Journal
Deactivation is currently supported primarily for modules. It follows a similar protocol to activation but involves either partial regeneration of the numan.nu file or its total deletion if no modules remain active.
- Partial Deactivation: If other modules remain active, Numan generates a new candidate file excluding the target modules, validates it, and replaces the live file.
-
Full Deactivation: If the target modules are the only ones active, Numan verifies ownership and deletes the
numan.nufile entirely.
The ModuleActivation struct stores the specific environment metadata required to determine if an activation is still valid.
pub struct ModuleActivation {
pub entry_path: String,
pub import_mode: ModuleImportMode,
pub vendor_autoload_dir: String,
pub managed_file_path: String,
pub nu_executable_sha256: String,
pub nu_version: String,
pub activated_at: String,
}This structure is used for crash recovery during module-autoload operations.
pub struct PendingAutoload {
pub schema_version: u32,
pub operation: AutoloadOperation,
pub stage: AutoloadStage,
pub nu_executable_sha256: String,
pub nu_version: String,
pub vendor_autoload_dir: String,
pub managed_file_path: String,
pub desired_active_module_ids: Vec<String>,
pub created_at: String,
// ... additional state for recovery
}Activation and Deactivation provide the necessary safety guarantees for Numan's integration with Nushell. By utilizing advisory locks, journaled transactions, and same-filesystem atomic renames, Numan ensures that Nushell's startup behavior remains predictable even if a Numan process is interrupted or if the underlying system environment drifts.
Numan wiki for tonythethompson/numan · v0.1.4 · MIT