diff --git a/cli/src/commands/sync.zig b/cli/src/commands/sync.zig index ee2306a..6e7f3d4 100644 --- a/cli/src/commands/sync.zig +++ b/cli/src/commands/sync.zig @@ -5,6 +5,7 @@ const crypto = @import("../utils/crypto.zig"); const rsync = @import("../utils/rsync_embedded.zig"); const ws = @import("../net/ws/client.zig"); const logging = @import("../utils/logging.zig"); +const json = @import("../utils/json.zig"); pub fn run(allocator: std.mem.Allocator, args: []const []const u8) !void { if (args.len == 0) { @@ -24,7 +25,7 @@ pub fn run(allocator: std.mem.Allocator, args: []const []const u8) !void { var job_name: ?[]const u8 = null; var should_queue = false; var priority: u8 = 5; - var json: bool = false; + var json_mode: bool = false; // Parse flags var i: usize = 1; @@ -35,7 +36,7 @@ pub fn run(allocator: std.mem.Allocator, args: []const []const u8) !void { } else if (std.mem.eql(u8, args[i], "--queue")) { should_queue = true; } else if (std.mem.eql(u8, args[i], "--json")) { - json = true; + json_mode = true; } else if (std.mem.eql(u8, args[i], "--priority") and i + 1 < args.len) { priority = try std.fmt.parseInt(u8, args[i + 1], 10); i += 1; @@ -63,7 +64,7 @@ pub fn run(allocator: std.mem.Allocator, args: []const []const u8) !void { // Sync using embedded rsync (no external binary needed) try rsync.sync(allocator, path, remote_path, config.worker_port); - if (json) { + if (json_mode) { std.debug.print("{\"ok\":true,\"action\":\"sync\",\"commit_id\":\"{s}\"}\n", .{commit_id}); } else { colors.printSuccess("✓ Files synced to server\n", .{}); @@ -140,10 +141,34 @@ fn monitorSyncProgress(allocator: std.mem.Allocator, config: *const Config, comm }; defer allocator.free(message); - // For now, just display a simple success message - // TODO: Implement proper JSON parsing and packet handling - logging.success("Sync progress message received\n", .{}); - break; + // Parse JSON progress message using shared utilities + const parsed = std.json.parseFromSlice(std.json.Value, allocator, message, .{}) catch { + logging.success("Sync progress: {s}\n", .{message}); + break; + }; + defer parsed.deinit(); + + if (parsed.value == .object) { + const root = parsed.value.object; + const status = json.getString(root, "status") orelse "unknown"; + const progress = json.getInt(root, "progress") orelse 0; + const total = json.getInt(root, "total") orelse 0; + + if (std.mem.eql(u8, status, "complete")) { + logging.success("Sync complete!\n", .{}); + break; + } else if (std.mem.eql(u8, status, "error")) { + const error_msg = json.getString(root, "error") orelse "Unknown error"; + logging.err("Sync failed: {s}\n", .{error_msg}); + return error.SyncFailed; + } else { + const pct = if (total > 0) @divTrunc(progress * 100, total) else 0; + logging.progress("Sync: {s} ({d}/{d} files, {d}%)\n", .{ status, progress, total, pct }); + } + } else { + logging.success("Sync progress: {s}\n", .{message}); + break; + } } if (timeout_counter >= max_timeout) {