const std = @import("std"); const errors = @import("errors.zig"); const colors = @import("utils/colors.zig"); // Global verbosity level var verbose_mode: bool = false; var quiet_mode: bool = false; const commands = struct { const init = @import("commands/init.zig"); const sync = @import("commands/sync.zig"); const queue = @import("commands/queue.zig"); const status = @import("commands/status.zig"); const monitor = @import("commands/monitor.zig"); const cancel = @import("commands/cancel.zig"); const prune = @import("commands/prune.zig"); const watch = @import("commands/watch.zig"); const dataset = @import("commands/dataset.zig"); const experiment = @import("commands/experiment.zig"); const jupyter = @import("commands/jupyter.zig"); }; pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); const allocator = gpa.allocator(); // Parse command line arguments var args_iter = std.process.args(); _ = args_iter.next(); // Skip executable name var command_args = std.ArrayList([]const u8).initCapacity(allocator, 10) catch |err| { colors.printError("Failed to allocate command args: {}\n", .{err}); return err; }; defer command_args.deinit(allocator); // Parse global flags first while (args_iter.next()) |arg| { if (std.mem.eql(u8, arg, "--help") or std.mem.eql(u8, arg, "-h")) { printUsage(); return; } else if (std.mem.eql(u8, arg, "--verbose") or std.mem.eql(u8, arg, "-v")) { verbose_mode = true; quiet_mode = false; } else if (std.mem.eql(u8, arg, "--quiet") or std.mem.eql(u8, arg, "-q")) { quiet_mode = true; verbose_mode = false; } else { command_args.append(allocator, arg) catch |err| { colors.printError("Failed to append argument: {}\n", .{err}); return err; }; } } const args = command_args.items; if (args.len < 1) { colors.printError("No command specified.\n", .{}); printUsage(); return; } const command = args[0]; // Handle commands with proper error handling if (std.mem.eql(u8, command, "--help") or std.mem.eql(u8, command, "help")) { printUsage(); return; } const command_result = if (std.mem.eql(u8, command, "init")) commands.init.run(allocator, args[1..]) else if (std.mem.eql(u8, command, "sync")) commands.sync.run(allocator, args[1..]) else if (std.mem.eql(u8, command, "queue")) commands.queue.run(allocator, args[1..]) else if (std.mem.eql(u8, command, "status")) commands.status.run(allocator, args[1..]) else if (std.mem.eql(u8, command, "monitor")) commands.monitor.run(allocator, args[1..]) else if (std.mem.eql(u8, command, "cancel")) commands.cancel.run(allocator, args[1..]) else if (std.mem.eql(u8, command, "prune")) commands.prune.run(allocator, args[1..]) else if (std.mem.eql(u8, command, "watch")) commands.watch.run(allocator, args[1..]) else if (std.mem.eql(u8, command, "dataset")) commands.dataset.run(allocator, args[1..]) else if (std.mem.eql(u8, command, "experiment")) commands.experiment.execute(allocator, args[1..]) else if (std.mem.eql(u8, command, "jupyter")) commands.jupyter.run(allocator, args[1..]) else error.InvalidArguments; // Handle any errors that occur during command execution command_result catch |err| { errors.ErrorHandler.handleCommandError(err, command); }; } pub fn printUsage() void { colors.printInfo("ML Experiment Manager\n\n", .{}); std.debug.print("Usage: ml [options]\n\n", .{}); std.debug.print("Commands:\n", .{}); std.debug.print(" init Setup configuration interactively\n", .{}); std.debug.print(" sync Sync project to server\n", .{}); std.debug.print(" queue Queue job for execution\n", .{}); std.debug.print(" status Get system status\n", .{}); std.debug.print(" monitor Launch TUI via SSH\n", .{}); std.debug.print(" cancel Cancel running job\n", .{}); std.debug.print(" prune --keep N Keep N most recent experiments\n", .{}); std.debug.print(" prune --older-than D Remove experiments older than D days\n", .{}); std.debug.print(" watch Watch directory for auto-sync\n", .{}); std.debug.print(" dataset Manage datasets (list, upload, download, delete)\n", .{}); std.debug.print(" experiment Manage experiments (log, show)\n", .{}); std.debug.print(" jupyter Manage Jupyter notebooks (start, stop, status)\n\n", .{}); std.debug.print("Options:\n", .{}); std.debug.print(" --help Show this help message\n", .{}); std.debug.print(" --verbose Enable verbose output\n", .{}); std.debug.print(" --quiet Suppress non-error output\n", .{}); std.debug.print(" --monitor Monitor progress of long-running operations\n", .{}); } test "basic test" { try std.testing.expectEqual(@as(i32, 10), 10); }