#!/usr/bin/env nim # Copyright (c) 2026 Nexus Foundation # Licensed under the Libertaria Sovereign License (LSL-1.0) # See legal/LICENSE_SOVEREIGN.md for details. # NIP MVP - Minimal Viable Product CLI # Simple, focused package grafting from Nix, PKGSRC, and Pacman import std/[os, strutils, strformat] import src/nimpak/cli/graft_commands import src/nimpak/cli/bootstrap_commands import src/nimpak/cli/store_commands const Version = "0.1.0-mvp" Banner = """ 🌱 NIP v$1 - Universal Package Grafting Graft packages from Nix, PKGSRC, and Pacman """ % [Version] proc showHelp() = echo Banner echo """ USAGE: nip [arguments] [options] COMMANDS: graft Graft a package (auto-detect source) graft : Graft from specific source remove Remove an installed package list List installed packages list --source= List packages from specific source info Show package information status Show system status doctor Check system health setup Setup system integration (PATH, libraries) bootstrap Build tool management (nix, pkgsrc, gentoo) store Interact with Content-Addressable Storage (CAS) config [show|init] Show or initialize configuration logs [lines] Show recent log entries (default: 50) search Search for packages (coming soon) SOURCES: nix Nix/nixpkgs packages pkgsrc NetBSD PKGSRC packages pacman Arch Linux Pacman packages OPTIONS: --verbose, -v Verbose output --help, -h Show this help --version Show version EXAMPLES: nip graft nix:firefox # Graft Firefox from Nix nip graft pkgsrc:vim # Graft Vim from PKGSRC nip graft hello # Auto-detect source for hello nip list # List all installed packages nip list --source=nix # List Nix packages only nip info firefox # Show Firefox info nip remove firefox # Remove Firefox nip status # Show system status nip doctor # Check system health DIRECTORIES: /Programs/// Package installation /System/Links/Executables/ Binaries (in PATH) /System/Links/Libraries/ Shared libraries /var/nip/db/packages.json Package database MORE INFO: https://git.maiwald.work/Nexus/NexusToolKit """ proc showVersion() = echo fmt"NIP version {Version}" proc main() = let args = commandLineParams() if args.len == 0: showHelp() quit(0) # Parse global options var verbose = false var remainingArgs: seq[string] = @[] for arg in args: case arg of "--verbose", "-v": verbose = true of "--help", "-h": showHelp() quit(0) of "--version": showVersion() quit(0) else: remainingArgs.add(arg) if remainingArgs.len == 0: showHelp() quit(0) let command = remainingArgs[0].toLower() let commandArgs = if remainingArgs.len > 1: remainingArgs[1..^1] else: @[] # Dispatch command var exitCode = 0 try: # Handle commands that don't need initialization if command == "setup": exitCode = setupCommand(verbose) quit(exitCode) if command == "config": let action = if commandArgs.len > 0: commandArgs[0] else: "show" exitCode = configCommand(action, verbose) quit(exitCode) if command == "platform": exitCode = platformCommand(verbose) quit(exitCode) # Initialize graft commands for other commands initGraftCommands(verbose) case command of "graft", "install": if commandArgs.len == 0: echo "Error: Package name required" echo "Usage: nip graft or nip graft :" exitCode = 1 else: exitCode = graftCommand(commandArgs[0], verbose) of "remove", "uninstall": if commandArgs.len == 0: echo "Error: Package name required" echo "Usage: nip remove " exitCode = 1 else: exitCode = removeCommand(commandArgs[0], verbose) of "list", "ls": var source = "" for arg in commandArgs: if arg.startsWith("--source="): source = arg.split("=", 1)[1] exitCode = listCommand(source, verbose) of "info", "show": if commandArgs.len == 0: echo "Error: Package name required" echo "Usage: nip info " exitCode = 1 else: exitCode = infoCommand(commandArgs[0], verbose) of "status": exitCode = statusCommand(verbose) of "doctor", "check": exitCode = doctorCommand(verbose) of "search": if commandArgs.len == 0: echo "Error: Search query required" echo "Usage: nip search " exitCode = 1 else: exitCode = searchCommand(commandArgs[0], "", verbose) of "logs": let lines = if commandArgs.len > 0: try: parseInt(commandArgs[0]) except: 50 else: 50 exitCode = logsCommand(lines, verbose) of "help": showHelp() exitCode = 0 of "bootstrap": if commandArgs.len == 0: bootstrapHelpCommand() exitCode = 0 else: let subCmd = commandArgs[0].toLower() let subArgs = if commandArgs.len > 1: commandArgs[1..^1] else: @[] case subCmd of "list": exitCode = bootstrapListCommand() of "install": if subArgs.len == 0: echo "Error: Tool name required" echo "Usage: nip bootstrap install " exitCode = 1 else: exitCode = bootstrapInstallCommand(subArgs[0]) of "remove": if subArgs.len == 0: echo "Error: Tool name required" echo "Usage: nip bootstrap remove " exitCode = 1 else: exitCode = bootstrapRemoveCommand(subArgs[0]) of "info": if subArgs.len == 0: echo "Error: Tool name required" echo "Usage: nip bootstrap info " exitCode = 1 else: exitCode = bootstrapInfoCommand(subArgs[0]) of "recipes": exitCode = bootstrapListRecipesCommand() of "update-recipes": exitCode = bootstrapUpdateRecipesCommand() of "validate": if subArgs.len == 0: echo "Error: Tool name required" echo "Usage: nip bootstrap validate " exitCode = 1 else: exitCode = bootstrapValidateRecipeCommand(subArgs[0]) of "help": bootstrapHelpCommand() exitCode = 0 else: echo fmt"Error: Unknown bootstrap subcommand '{subCmd}'" bootstrapHelpCommand() exitCode = 1 of "store": exitCode = dispatchStoreCommand(commandArgs, verbose) else: echo fmt"Error: Unknown command '{command}'" echo "Run 'nip --help' for usage information" exitCode = 1 except Exception as e: echo fmt"Fatal error: {e.msg}" if verbose: echo "Stack trace:" echo e.getStackTrace() exitCode = 1 quit(exitCode) when isMainModule: main()