#!/usr/bin/env nu # Install and register provisioning critical plugins # # This is the main user-facing script for installing the three critical # provisioning plugins (auth, kms, orchestrator) that provide: # - 10-50x performance improvement over HTTP API # - OS-native keyring integration # - Local file-based operations (no network required) # # Usage: # nu install-plugins.nu # Build and install all plugins # nu install-plugins.nu --skip-build # Register pre-built plugins only # nu install-plugins.nu --release # Build release mode (default) # nu install-plugins.nu --debug # Build debug mode # nu install-plugins.nu --plugin auth # Install specific plugin only # nu install-plugins.nu --verify # Verify after installation const PLUGIN_DIR = "nushell-plugins" const PROVISIONING_PLUGINS = [ "nu_plugin_auth" "nu_plugin_kms" "nu_plugin_orchestrator" ] # Build a single plugin def build-plugin [ plugin_name: string base_dir: path --release ]: nothing -> record { let plugin_path = ($base_dir | path join $PLUGIN_DIR $plugin_name) if not ($plugin_path | path exists) { return { name: $plugin_name status: "not_found" message: $"Plugin directory not found: ($plugin_path)" } } let build_mode = if $release { "--release" } else { "" } let target_dir = if $release { "release" } else { "debug" } print $" Building ($plugin_name) \(($target_dir) mode\)..." let start_time = (date now) # Build the plugin try { cd $plugin_path if $release { cargo build --release } else { cargo build } cd - let duration = ((date now) - $start_time) | into int | $in / 1_000_000_000 let binary_path = ($plugin_path | path join "target" $target_dir $plugin_name) if ($binary_path | path exists) { return { name: $plugin_name status: "built" message: $"Build successful \(($duration | math round --precision 1)s\)" path: $binary_path } } else { return { name: $plugin_name status: "error" message: "Build completed but binary not found" } } } catch { |err| cd - return { name: $plugin_name status: "error" message: $"Build failed: ($err.msg)" } } } # Register a plugin with Nushell def register-plugin-binary [ plugin_name: string binary_path: path ]: nothing -> record { if not ($binary_path | path exists) { return { name: $plugin_name status: "not_found" message: $"Binary not found: ($binary_path)" } } try { plugin add $binary_path return { name: $plugin_name status: "registered" message: "Registered successfully" path: $binary_path } } catch { |err| return { name: $plugin_name status: "error" message: $"Registration failed: ($err.msg)" } } } # Get binary path for a plugin def get-binary-path [ plugin_name: string base_dir: path --release ]: nothing -> path { let target_dir = if ($release) { "release" } else { "debug" } $base_dir | path join $PLUGIN_DIR $plugin_name "target" $target_dir $plugin_name } # Print banner def print-banner [] { print "" print "+======================================================+" print "| Provisioning Platform - Plugin Installation |" print "+======================================================+" print "" print "Installing critical plugins for optimal performance:" print " - nu_plugin_auth: JWT auth with keyring (10x faster)" print " - nu_plugin_kms: Multi-backend encryption (10x faster)" print " - nu_plugin_orchestrator: Local operations (30x faster)" print "" } # Print summary def print-summary [results: list] { let built = ($results | where status == "built" | length) let registered = ($results | where status == "registered" | length) let errors = ($results | where status == "error" | length) let skipped = ($results | where status in ["not_found" "already_registered"] | length) print "" print "+------------------------------------------------------+" print "| Installation Summary |" print "+------------------------------------------------------+" print "" print $" Built: ($built)" print $" Registered: ($registered)" print $" Errors: ($errors)" print $" Skipped: ($skipped)" print "" if $errors > 0 { print "Some plugins failed to install. Check errors above." print "" } } # Main entry point def main [ --skip-build (-s) # Skip building, only register pre-built plugins --release (-r) # Build in release mode (default) --debug (-d) # Build in debug mode --plugin (-p): string # Install specific plugin only --verify (-v) # Verify installation after completion --quiet (-q) # Suppress output ]: nothing -> nothing { let base_dir = ($env.PWD | path dirname) # Go up from plugins/ to core/ let use_release = not $debug # Determine which plugins to install let plugins_to_install = if ($plugin != null) { if $plugin in $PROVISIONING_PLUGINS { [$plugin] } else if $"nu_plugin_($plugin)" in $PROVISIONING_PLUGINS { [$"nu_plugin_($plugin)"] } else { print $"Error: Unknown plugin '($plugin)'" print $"Available: ($PROVISIONING_PLUGINS | str join ', ')" exit 1 } } else { $PROVISIONING_PLUGINS } if not $quiet { print-banner } mut all_results = [] # Phase 1: Build (unless --skip-build) if not $skip_build { if not $quiet { let mode = if $use_release { "release" } else { "debug" } print $"Phase 1: Building plugins \(($mode) mode\)..." print "" } for plugin_name in $plugins_to_install { let result = (build-plugin $plugin_name $base_dir --release=$use_release) $all_results = ($all_results | append $result) if not $quiet { match $result.status { "built" => { print $" [OK] ($result.message)" } "not_found" => { print $" [SKIP] ($result.message)" } "error" => { print $" [ERROR] ($result.message)" } _ => {} } } } if not $quiet { print "" } } # Phase 2: Register if not $quiet { print "Phase 2: Registering plugins with Nushell..." print "" } for plugin_name in $plugins_to_install { let binary_path = (get-binary-path $plugin_name $base_dir --release=$use_release) if not $quiet { print $" Registering ($plugin_name)..." } let result = (register-plugin-binary $plugin_name $binary_path) $all_results = ($all_results | append $result) if not $quiet { match $result.status { "registered" => { print $" [OK] ($result.message)" } "not_found" => { print $" [SKIP] ($result.message)" } "error" => { print $" [ERROR] ($result.message)" } _ => {} } } } if not $quiet { print-summary $all_results } # Phase 3: Verify (if requested) if $verify { if not $quiet { print "Phase 3: Verifying installation..." print "" } let registered_plugins = (plugin list) for plugin_name in $plugins_to_install { let is_registered = ($registered_plugins | where name == $plugin_name | length) > 0 if not $quiet { if $is_registered { print $" [OK] ($plugin_name) is registered" } else { print $" [FAIL] ($plugin_name) not found in plugin list" } } } if not $quiet { print "" } } if not $quiet { print "Plugin commands now available:" print "" print " Authentication:" print " auth login [password] # Login with JWT" print " auth logout # End session" print " auth verify # Check token" print " auth sessions # List sessions" print " auth mfa enroll totp # Setup MFA" print " auth mfa verify --code 123456 # Verify MFA" print "" print " Encryption (KMS):" print " kms encrypt \"data\" --backend age # Encrypt with Age" print " kms decrypt \$encrypted # Decrypt data" print " kms generate-key --spec AES256 # Generate key" print " kms status # Check KMS status" print " kms list-backends # Available backends" print "" print " Orchestrator:" print " orch status # Local status (fast)" print " orch tasks # List tasks" print " orch validate workflow.k # Validate KCL" print " orch submit workflow.k # Submit workflow" print " orch monitor # Monitor task" print "" print "Verify installation with: plugin list" print "" } }