diff --git a/src/commands/edit.cpp b/src/commands/edit.cpp
index 4a9c885..4fb3752 100644
--- a/src/commands/edit.cpp
+++ b/src/commands/edit.cpp
@@ -29,7 +29,9 @@ struct EditCommandRegister {
             false, // hidden
             false, // requires_config
             0,     // min_args (after command)
-            2      // max_args (after command)
+            2,     // max_args (after command)
+            "edit [SERVER] [SERVICE]",
+            "Edit dropshell, server or service configuration"
         });
     }
 } edit_command_register;
diff --git a/src/commands/help.cpp b/src/commands/help.cpp
new file mode 100644
index 0000000..7232cd0
--- /dev/null
+++ b/src/commands/help.cpp
@@ -0,0 +1,136 @@
+#include "command_registry.hpp"
+#include "config.hpp"
+#include "utils/utils.hpp"
+#include "service_runner.hpp"
+#include "utils/directories.hpp"
+#include "standard_autocomplete.hpp"
+#include "version.hpp"
+
+#include <unistd.h>
+#include <cstring>
+#include <iostream>
+#include <sstream>
+#include <filesystem>
+#include <libassert/assert.hpp>
+
+namespace dropshell {
+
+void help_autocomplete(const CommandContext& ctx);
+int help_handler(const CommandContext& ctx);
+
+static std::vector<std::string> help_name_list={"help","h","--help","-h"};
+
+// Static registration
+struct HelpCommandRegister {
+    HelpCommandRegister() {
+        CommandRegistry::instance().register_command({
+            help_name_list,
+            help_handler,
+            help_autocomplete,
+            false, // hidden
+            false, // requires_config
+            0,     // min_args (after command)
+            0,      // max_args (after command)
+            "help",
+            "Show help for dropshell"
+        });
+    }
+} help_command_register;
+
+
+void help_autocomplete(const CommandContext& ctx) {
+    if (ctx.args.size() == 1) {
+        std::cout << "help" << std::endl;
+    }
+    return;
+}
+
+void show_command(const std::string& cmd) { 
+    const auto& cmd_info = CommandRegistry::instance().find_command(cmd); 
+    if (!cmd_info) 
+        std::cout << "Unknown command: " << cmd << std::endl;
+
+    std::cout << "  ";
+    print_left_aligned(cmd_info->help_usage, 30);
+    std::cout << cmd_info->help_description << std::endl;
+}
+
+extern const std::string VERSION;
+extern const std::string RELEASE_DATE;
+extern const std::string AUTHOR;
+extern const std::string LICENSE;
+
+int help_handler(const CommandContext& ctx) {
+    std::cout << std::endl;
+    maketitle("DropShell version " + VERSION);
+    std::cout << std::endl;
+    std::cout << "A tool for managing remote servers, by " << AUTHOR << std::endl;
+    std::cout << std::endl;
+    std::cout << "dropshell ..." << std::endl;
+
+    show_command("help");
+    show_command("edit");
+
+
+    if (gConfig().is_config_set()) {
+        // show more!
+    }
+
+    return 0;
+}
+
+
+
+// void show_command(const std::string& cmd) { 
+//     const auto& cmd_info = CommandRegistry::instance().find_command(cmd); 
+//     if (cmd_info) { 
+//         std::cout << "  " << cmd_info->help_usage 
+//         << std::string(' ', std::min(1,(int)(30-cmd_info->help_usage.length())))
+//         << cmd_info->help_description << std::endl; 
+//     } 
+// }
+
+// bool print_help() {
+//     std::cout << std::endl;
+//     maketitle("DropShell version " + VERSION);
+//     std::cout << std::endl;
+//     std::cout << "A tool for managing server configurations" << std::endl;
+//     std::cout << std::endl;
+//     std::cout << "dropshell ..." << std::endl;
+//     show_command("help");
+//     show_command("edit");
+
+//     if (gConfig().is_config_set()) {
+//     std::cout << "  templates      List all available templates" << std::endl;
+//     std::cout << std::endl;
+//     std::cout << std::endl;
+//     std::cout << "Service commands: (if no service is specified, all services for the server are affected)" << std::endl;
+//     std::cout << "  list [SERVER] [SERVICE]      List status/details of all servers/server/service." << std::endl;
+//     std::cout << "  edit [SERVER] [SERVICE]      Edit the configuration of dropshell/server/service." << std::endl;
+//     std::cout << std::endl;
+//     std::cout << "  install SERVER [SERVICE]     Install/reinstall/update service(s). Safe/non-destructive." << std::endl;
+//     std::cout << "  uninstall SERVER [SERVICE]   Uninstalls the service on the remote server. Leaves data intact." << std::endl;
+//     std::cout << "  nuke SERVER SERVICE          Nuke the service, deleting ALL local and remote data." << std::endl;
+//     std::cout << std::endl;
+//     std::cout << "  COMMAND SERVER [SERVICE]     Run a command on service(s), e.g." << std::endl;
+//     std::cout << "                                  backup, restore, start, stop, logs" << std::endl;
+//     std::cout << std::endl;
+//     std::cout << "  ssh     SERVER SERVICE       Launch an interactive shell on a server or service" << std::endl;
+//     std::cout << std::endl;
+//     std::cout << "Creation commands: (apply to the first local config directory)"<<std::endl;
+//     std::cout << "  create-template TEMPLATE" << std::endl;
+//     std::cout << "  create-server   SERVER" << std::endl;
+//     std::cout << "  create-service  SERVER TEMPLATE SERVICE" << std::endl;
+//     }
+//     else {
+//         show_command("help");
+//         show_command("edit");
+//         std::cout << std::endl;
+//         std::cout << "Other commands available once initialised." << std::endl;
+//     }
+//     return true;
+// }
+
+
+
+} // namespace dropshell
diff --git a/src/main.cpp b/src/main.cpp
index e040847..deee8cd 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -26,55 +26,69 @@ extern const std::string RELEASE_DATE;
 extern const std::string AUTHOR;
 extern const std::string LICENSE;
 
-void show_command(const std::string& cmd) { 
-    const auto& cmd_info = CommandRegistry::instance().find_command(cmd); 
-    if (cmd_info) { 
-        std::cout << "  " << cmd_info->help_usage 
-        << std::string(' ', std::min(1,(int)(30-cmd_info->help_usage.length())))
-        << cmd_info->help_description << std::endl; 
-    } 
+
+int main(int argc, char* argv[]) {
+
+    try {
+        // silently attempt to load the config file and templates.
+        gConfig().load_config();
+        if (gConfig().is_config_set())
+            gTemplateManager().load_sources();
+
+
+        // process the command line arguments.
+        std::vector<std::string> args(argv, argv + argc);
+
+        if (args.size() < 2) 
+            args.push_back("help");
+
+        std::string cmd = args[1];
+
+        if (cmd == "autocomplete") {
+            CommandRegistry::instance().autocomplete(args);
+            return 0;
+        }
+
+        const CommandInfo* info = CommandRegistry::instance().find_command(cmd);
+        if (!info) {
+            std::cerr << "Unknown command: " << cmd << std::endl;
+            return 1;
+        }
+        if (info->requires_config && !gConfig().is_config_set()) {
+            std::cerr << "Configuration required for command: " << cmd << std::endl;
+            std::cerr << "Please run 'dropshell edit' to set up the dropshell configuration." << std::endl;
+            return 1;
+        }
+        int arg_count = args.size() - 2;
+        if (arg_count < info->min_args || (info->max_args != -1 && arg_count > info->max_args)) {
+            std::cerr << "Invalid number of arguments for command: " << cmd << std::endl;
+            std::cerr << "Usage: " << std::endl;
+            std::cout << "  " << info->help_usage
+                    << std::string(' ', std::max(1, (int)(30 - info->help_usage.length())))
+                    << info->help_description << std::endl;
+            return 1;
+        }
+        CommandContext ctx{args};
+        return info->handler(ctx);
+
+    }
+    catch (const std::exception& e) {
+        std::cerr << "Error: " << e.what() << std::endl;
+        return 1;
+    }
 }
 
-bool print_help() {
-    std::cout << std::endl;
-    maketitle("DropShell version " + VERSION);
-    std::cout << std::endl;
-    std::cout << "A tool for managing server configurations" << std::endl;
-    std::cout << std::endl;
-    std::cout << "dropshell ..." << std::endl;
-    show_command("help");
-    show_command("edit");
 
-    if (gConfig().is_config_set()) {
-    std::cout << "  templates      List all available templates" << std::endl;
-    std::cout << std::endl;
-    std::cout << std::endl;
-    std::cout << "Service commands: (if no service is specified, all services for the server are affected)" << std::endl;
-    std::cout << "  list [SERVER] [SERVICE]      List status/details of all servers/server/service." << std::endl;
-    std::cout << "  edit [SERVER] [SERVICE]      Edit the configuration of dropshell/server/service." << std::endl;
-    std::cout << std::endl;
-    std::cout << "  install SERVER [SERVICE]     Install/reinstall/update service(s). Safe/non-destructive." << std::endl;
-    std::cout << "  uninstall SERVER [SERVICE]   Uninstalls the service on the remote server. Leaves data intact." << std::endl;
-    std::cout << "  nuke SERVER SERVICE          Nuke the service, deleting ALL local and remote data." << std::endl;
-    std::cout << std::endl;
-    std::cout << "  COMMAND SERVER [SERVICE]     Run a command on service(s), e.g." << std::endl;
-    std::cout << "                                  backup, restore, start, stop, logs" << std::endl;
-    std::cout << std::endl;
-    std::cout << "  ssh     SERVER SERVICE       Launch an interactive shell on a server or service" << std::endl;
-    std::cout << std::endl;
-    std::cout << "Creation commands: (apply to the first local config directory)"<<std::endl;
-    std::cout << "  create-template TEMPLATE" << std::endl;
-    std::cout << "  create-server   SERVER" << std::endl;
-    std::cout << "  create-service  SERVER TEMPLATE SERVICE" << std::endl;
-    }
-    else {
-        show_command("help");
-        show_command("edit");
-        std::cout << std::endl;
-        std::cout << "Other commands available once initialised." << std::endl;
-    }
-    return true;
-}
+
+
+
+
+
+
+
+
+
+// ------------------------------------------------------------------------------------------------
 
 struct ServerAndServices {
     std::string server_name;
@@ -127,12 +141,13 @@ auto command_match = [](const std::string& cmd_list, int argc, char* argv[]) ->
 }
 
 
-int main(int argc, char* argv[]) {
+
+
+int old_main(int argc, char* argv[]) {
     HAPPYEXIT("hash", hash_demo_raw(safearg(argc,argv,2)))
     HAPPYEXIT("makesafecmd", std::cout<<makesafecmd(safearg(argc,argv,2))<<std::endl)
     HAPPYEXIT("version", printversion())
     BOOLEXIT("test-template", gTemplateManager().test_template(safearg(argc,argv,2)))
-    BOOLEXIT("help -h --help h halp", print_help())
     ASSERT(safearg(argc,argv,1) != "assert", "Hello! Here is an assert.");
 
     try {
@@ -141,9 +156,6 @@ int main(int argc, char* argv[]) {
         if (gConfig().is_config_set())
             gTemplateManager().load_sources();
 
-        if (argc < 2)
-            return print_help() ? 0 : 1;
-
         std::string cmd = argv[1];
 
         if (cmd == "autocomplete")
diff --git a/src/service_runner.cpp b/src/service_runner.cpp
index 6f37103..9087b69 100644
--- a/src/service_runner.cpp
+++ b/src/service_runner.cpp
@@ -16,7 +16,7 @@
 #include "services.hpp"
 #include "utils/directories.hpp"
 #include "utils/utils.hpp"
-
+#include "command_registry.hpp"
 
 namespace fs = std::filesystem;
 
diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp
index cc8d7b1..d9f5e12 100644
--- a/src/utils/utils.cpp
+++ b/src/utils/utils.cpp
@@ -334,4 +334,26 @@ std::string safearg(int argc, char *argv[], int index)
     return argv[index];
 }
 
+
+void print_left_aligned(const std::string & str, int width) {
+    std::cout << str;
+    if (static_cast<int>(str.size()) < width)
+        std::cout << std::string(width - str.size(), ' ');
+}
+
+void print_centered(const std::string & str, int width) {
+    int pad = width - static_cast<int>(str.size());
+    int pad_left = pad > 0 ? pad / 2 : 0;
+    int pad_right = pad > 0 ? pad - pad_left : 0;
+    std::cout << std::string(pad_left, ' ') << str << std::string(pad_right, ' ');
+}
+
+void print_right_aligned(const std::string & str, int width) {
+    if (static_cast<int>(str.size()) < width)
+        std::cout << std::string(width - str.size(), ' ');
+    std::cout << str;
+}
+
+
+
 } // namespace dropshell 
\ No newline at end of file
diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp
index 603409e..1dd2a31 100644
--- a/src/utils/utils.hpp
+++ b/src/utils/utils.hpp
@@ -45,4 +45,8 @@ int die(const std::string & msg);
 std::string safearg(int argc, char *argv[], int index);
 std::string safearg(const std::vector<std::string> & args, int index);
 
+void print_left_aligned(const std::string & str, int width);
+void print_centered(const std::string & str, int width);
+void print_right_aligned(const std::string & str, int width);
+
 } // namespace dropshell 
\ No newline at end of file