╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ────╮ │src/serve.zig│ ╰─────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │59 const ssh_listen_address = try parseListenAddress(ssh_listen); │ │60 const ssh_address = try std.Io.net.IpAddress.parseIp4(ssh_listen_address.host, ssh_listen_address.port); │ │61 ssh_server = try ssh_address.listen(io, .{ .reuse_address = true }); │ │62 + } │ │63 + │ │64 + // create wui listener │ │65 + │ │66 + const wui_listen_address = try parseListenAddress(wui_listen); │ │67 + const wui_address = try std.Io.net.IpAddress.parseIp4(wui_listen_address.host, wui_listen_address.port); │ │68 + var wui_server = try wui_address.listen(io, .{ .reuse_address = true }); │ │69 + defer wui_server.deinit(io); │ │70 │ │71 + var tasks: std.Io.Group = .init; │ │72 + defer tasks.cancel(io); │ │73 + │ │74 + try err.print("serving HTTP on {s}, repo root {s}\n", .{ options.http_listen, repo_root_path }); │ │75 + try err.flush(); │ │76 + │ │77 + runHttpListener(repo_kind, any_repo_opts, io, allocator, repo_root_path, &http_server, &tasks, err); │ │78 + │ │79 + if (options.ssh_listen) |ssh_listen| { │ │80 try err.print("serving SSH helper connections on {s}, repo root {s}\n", .{ ssh_listen, repo_root_path });│ │81 try err.flush(); │ │82 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 75 - if (ssh_server) |*server| { │ │ 76 - runSshListener(repo_kind, any_repo_opts, io, allocator, repo_root_path, server, &tasks, err);│ │ 77 - } │ │ 83 + const server = &(ssh_server orelse return error.MissingSshServer); │ │ 84 + runSshListener(repo_kind, any_repo_opts, io, allocator, repo_root_path, server, &tasks, err); │ │ 85 } │ │ 86 │ │ 80 - try tasks.await(io); │ │ 87 + try err.print("serving web UI on http://{s}/\n", .{wui_listen}); │ │ 88 + try err.flush(); │ │ 89 + │ │ 90 + web.run(io, &wui_server, &tasks, err); │ │ 91 + │ │ 92 + if (options.tui) { │ │ 93 + runTui(io, allocator, &tasks, err); │ │ 94 + │ │ 95 + while (!xit.xitui.terminal.quit) { │ │ 96 + try std.Io.sleep(io, .fromMilliseconds(5), .real); │ │ 97 + } │ │ 98 + } else { │ │ 99 + try tasks.await(io); │ │100 + } │ │101 } │ │102 │ │103 fn runTui( │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │113 │ │114 fn run(ctx: @This()) void { │ │115 ui.run(ctx.io, ctx.allocator) catch |ui_err| { │ │116 + if (ui_err == error.Canceled) return; │ │117 logError(ctx.err, "ui failed: {s}\n", .{@errorName(ui_err)});│ │118 }; │ │119 } │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │147 fn run(ctx: @This()) void { │ │148 while (true) { │ │149 const stream = ctx.net_server.accept(ctx.io) catch |accept_err| { │ │150 + if (accept_err == error.Canceled) return; │ │151 logError(ctx.err, "accept failed: {s}\n", .{@errorName(accept_err)});│ │152 continue; │ │153 }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ │342 fn run(ctx: @This()) void { │ │343 while (true) { │ │344 const stream = ctx.net_server.accept(ctx.io) catch |accept_err| { │ │345 + if (accept_err == error.Canceled) return; │ │346 logError(ctx.err, "ssh accept failed: {s}\n", .{@errorName(accept_err)});│ │347 continue; │ │348 }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭─────────────────────────────────────────────────────────────╮ │63 │ │64 while (try terminal.readKey(io)) |key| { │ │65 switch (key) { │ │66 - .codepoint => |cp| if (cp == 'q') return,│ │66 + .codepoint => |cp| if (cp == 'q') { │ │67 + term.quit = true; │ │68 + return; │ │69 + }, │ │70 else => {}, │ │71 } │ │72 try root.input(key, root.getFocus()); │ ╰─────────────────────────────────────────────────────────────╯ ╭ added ─────────────╮ │src/assets/haxy.wasm│ ╰────────────────────╯ ╭ added ──────────────╮ │src/assets/index.html│ ╰─────────────────────╯ ╭ added ─────────────╮ │src/assets/script.js│ ╰────────────────────╯ ╭ added ────────────╮ │src/assets/term.ttf│ ╰───────────────────╯ ╭──────╮ │next →│ ╰──────╯