# Command Dispatcher # Central routing logic for all provisioning commands use flags.nu * use commands/infrastructure.nu * use commands/orchestration.nu * use commands/development.nu * use commands/workspace.nu * use commands/generation.nu * use commands/utilities.nu * use commands/configuration.nu * use ../lib_provisioning * # Helper to run module commands def run_module [ args: string module: string option?: string --exec ] { let use_debug = if ($env.PROVISIONING_DEBUG? | default false) { "-x" } else { "" } if $exec { exec $"($env.PROVISIONING_NAME)" $use_debug -mod $module ($option | default "") $args --notitles } else { ^$"($env.PROVISIONING_NAME)" $use_debug -mod $module ($option | default "") $args --notitles } } # Command registry with shortcuts and aliases # Maps short forms and aliases to their canonical command domain export def get_command_registry []: nothing -> record { { # Infrastructure commands (server, taskserv, cluster, infra) "s": "infrastructure server" "server": "infrastructure server" "t": "infrastructure taskserv" "task": "infrastructure taskserv" "taskserv": "infrastructure taskserv" "cl": "infrastructure cluster" "cluster": "infrastructure cluster" "i": "infrastructure infra" "infra": "infrastructure infra" "infras": "infrastructure infra" # Orchestration commands (workflow, batch, orchestrator) "wf": "orchestration workflow" "flow": "orchestration workflow" "workflow": "orchestration workflow" "bat": "orchestration batch" "batch": "orchestration batch" "orch": "orchestration orchestrator" "orchestrator": "orchestration orchestrator" # Development commands (module, layer, version, pack) "mod": "development module" "module": "development module" "lyr": "development layer" "layer": "development layer" "version": "development version" "pack": "development pack" # Workspace commands (workspace, template) "ws": "workspace workspace" "workspace": "workspace workspace" "tpl": "workspace template" "tmpl": "workspace template" "template": "workspace template" # Configuration commands (env, allenv, show, init, validate) "e": "config env" "env": "config env" "allenv": "config allenv" "show": "config show" "init": "config init" "validate": "config validate" "val": "config validate" "config-template": "config config-template" # Utility commands (ssh, sed, sops, cache, providers, etc.) "ssh": "utils ssh" "sed": "utils sed" "sops": "utils sops" "cache": "utils cache" "providers": "utils providers" "nu": "utils nu" "list": "utils list" "l": "utils list" "ls": "utils list" "qr": "utils qr" "nuinfo": "utils nuinfo" "plugin": "utils plugin" "plugins": "utils plugins" # Generation commands "g": "generation generate" "gen": "generation generate" "generate": "generation generate" # Special commands (handled separately) "h": "help" "c": "create" "create": "create" "d": "delete" "delete": "delete" "u": "update" "update": "update" "price": "price" "prices": "price" "cost": "price" "costs": "price" "cst": "create-server-task" "create-server-task": "create-server-task" "csts": "create-server-task" "create-servers-tasks": "create-server-task" "deploy-rm": "deploy" "deploy-del": "deploy" "dp-rm": "deploy" "d-r": "deploy" "destroy": "deploy" "deploy-sel": "deploy-sel" "deploy-list": "deploy-sel" "dp-sel": "deploy-sel" "d-s": "deploy-sel" "deploy-sel-tree": "deploy-sel-tree" "deploy-list-tree": "deploy-sel-tree" "dp-sel-t": "deploy-sel-tree" "d-st": "deploy-sel-tree" "new": "new" "ai": "ai" "context": "context" "ctx": "context" "setup": "setup" "st": "setup" "config": "setup" "control-center": "control-center" "mcp-server": "mcp-server" } } # Main command dispatcher # Routes commands to appropriate domain handlers export def dispatch_command [ args: list flags: record ] { let task = if ($args | length) > 0 { ($args | get 0) } else { "" } let ops_list = ($args | skip 1) let ops_str = ($ops_list | str join " ") # Handle empty command if ($task | is-empty) { print "Use 'provisioning help' for available commands" exit } # Intercept bi-directional help: "provisioning help" → "provisioning help " # This ensures shortcuts like "provisioning ws help" work correctly let first_op = if ($ops_list | length) > 0 { ($ops_list | get 0) } else { "" } if $first_op in ["help" "h"] { # Redirect to categorized help system exec $"($env.PROVISIONING_NAME)" help $task --notitles } # Resolve command through registry let registry = get_command_registry let resolved = ($registry | get -o $task | default $task) # Split into domain and command let parts = ($resolved | split row " ") let domain = if ($parts | length) > 1 { ($parts | get 0) } else { "special" } let command = if ($parts | length) > 1 { ($parts | get 1) } else { $task } # Set environment based on flags set_debug_env $flags # Dispatch to domain handler match $domain { "infrastructure" => { handle_infrastructure_command $command $ops_str $flags } "orchestration" => { handle_orchestration_command $command $ops_str $flags } "development" => { handle_development_command $command $ops_str $flags } "workspace" => { handle_workspace_command $command $ops_str $flags } "config" => { handle_config_command $command $ops_str $flags } "utils" => { handle_utility_command $command $ops_str $flags } "generation" => { handle_generation_command $command $ops_str $flags } "special" => { handle_special_command $command $ops_str $flags } "help" => { exec $"($env.PROVISIONING_NAME)" help $command --notitles } _ => { invalid_task "" $task --end exit 1 } } } # Generation command handler def handle_generation_command [command: string, ops: string, flags: record] { let str_infra = if ($flags.infra | is-not-empty) { $"--infra ($flags.infra) " } else { "" } let use_debug = if $flags.debug_mode { "-x" } else { "" } let use_check = if $flags.check_mode { "--check " } else { "" } let str_out = if ($flags.outfile | is-not-empty) { $"--outfile ($flags.outfile) " } else { "" } let str_template = if ($flags.template | is-not-empty) { $"--template ($flags.template)" } else { "" } let str_select = if ($flags.select | is-not-empty) { $"--select ($flags.select)" } else { "" } if ($ops | is-empty) { exec $"($env.PROVISIONING_NAME)" $use_debug "generate" $ops $use_check $str_infra $str_out --notitles } else { let target = ($ops | split row " " | get -o 0) let gen_ops = ($ops | split row " " | skip 1 | str join " ") + $" ($str_infra) ($str_template) ($str_out) ($use_check) ($use_debug) ($str_select)" match $target { "s" | "server" => { run_module $"- ($gen_ops)" "server" "generate" --exec } "t" | "task" | "taskserv" => { run_module $"- ($gen_ops)" "taskserv" "generate" --exec } "i" | "infra" | "infras" => { run_module $"- ($gen_ops)" "infra" "generate" --exec } "cl" | "cluster" => { run_module $"- ($gen_ops)" "cluster" "generate" --exec } "h" | "help" => { _print $"\n(provisioning_generate_options)" exit } "new" => { exec $"($env.PROVISIONING_NAME)" $use_debug "generate" "new" $gen_ops $str_template $use_check $str_infra $str_out --notitles } _ => { invalid_task "" $target --end exit } } } } # Special command handler (create, delete, update, deploy, etc.) def handle_special_command [command: string, ops: string, flags: record] { match $command { "create" | "c" => { let use_debug = if $flags.debug_mode or ($env.PROVISIONING_DEBUG? | default false) { "-x" } else { "" } let use_check = if $flags.check_mode { "--check " } else { "" } let str_infra = if ($flags.infra | is-not-empty) { $"--infra ($flags.infra) " } else { "" } let str_out = if ($flags.outfile | is-not-empty) { $"--outfile ($flags.outfile) " } else { "" } exec $"($env.PROVISIONING_NAME)" $use_debug "create" $ops $use_check $str_infra $str_out --notitles } "delete" | "d" => { let use_debug = if $flags.debug_mode { "-x" } else { "" } let use_check = if $flags.check_mode { "--check " } else { "" } let use_yes = if $flags.auto_confirm { "--yes " } else { "" } let use_keepstorage = if $flags.keep_storage { "--keepstorage " } else { "" } let str_infra = if ($flags.infra | is-not-empty) { $"--infra ($flags.infra) " } else { "" } exec $"($env.PROVISIONING_NAME)" "delete" $ops $use_check $use_yes $use_keepstorage $str_infra --notitles } "update" | "u" => { let use_debug = if $flags.debug_mode { "-x" } else { "" } let use_check = if $flags.check_mode { "--check " } else { "" } let str_infra = if ($flags.infra | is-not-empty) { $"--infra ($flags.infra) " } else { "" } exec $"($env.PROVISIONING_NAME)" "update" $ops $use_check $str_infra --notitles } "price" | "prices" | "cost" | "costs" => { handle_price_command $ops $flags } "create-server-task" | "cst" | "csts" | "create-servers-tasks" => { handle_create_server_task $ops $flags } "new" => { let str_new = ($flags.new_infra | default "") print $"\n (_ansi yellow)New Infra ($str_new)(_ansi reset)" } "ai" => { let str_infra = if ($flags.infra | is-not-empty) { $"--infra ($flags.infra) " } else { "" } let str_settings = if ($flags.settings | is-not-empty) { $"--settings ($flags.settings) " } else { "" } let str_out = if ($flags.output_format | is-not-empty) { $"--out ($flags.output_format) " } else { "" } run_module $"($ops) ($str_infra) ($str_settings) ($str_out)" "ai" --exec } "context" | "ctx" => { ^$"($env.PROVISIONING_NAME)" "context" $ops --notitles run_module $ops "" --exec } "setup" | "st" | "config" => { run_module $ops "setup" --exec } "control-center" => { run_module $ops "control-center" --exec } "mcp-server" => { run_module $ops "mcp-server" --exec } _ => { print $"❌ Unknown command: ($command)" print "Use 'provisioning help' for available commands" exit 1 } } }