From fb6e0b751ba18a1f0470b067727f111386df81a8 Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Wed, 15 Jul 2026 15:37:45 +0200 Subject: [PATCH 1/2] expose Lightpanda-Version into /json/version endpoint --- src/Server.zig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Server.zig b/src/Server.zig index 5cf963ea4..c5b45474e 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -283,6 +283,7 @@ fn buildJSONVersionResponse(app: *const App, port: u16) ![]const u8 { "\"Browser\": \"Lightpanda/1.0\", " ++ "\"Protocol-Version\": \"1.3\", " ++ "\"User-Agent\": \"Lightpanda/1.0\", " ++ + "\"Lightpanda-Version\": \"" ++ lp.build_config.version ++ "\", " ++ "\"webSocketDebuggerUrl\": \"ws://{s}:{d}/\"" ++ "}}"; const body_len = std.fmt.count(body_format, .{ host, port }); @@ -316,6 +317,7 @@ test "server: buildJSONVersionResponse" { try testing.expect(std.mem.indexOf(u8, res, "\"Browser\": \"Lightpanda/") != null); try testing.expect(std.mem.indexOf(u8, res, "\"Protocol-Version\": \"1.3\"") != null); try testing.expect(std.mem.indexOf(u8, res, "\"User-Agent\": \"Lightpanda/") != null); + try testing.expect(std.mem.indexOf(u8, res, "\"Lightpanda-Version\": \"" ++ lp.build_config.version ++ "\"") != null); try testing.expect(std.mem.indexOf(u8, res, "\"webSocketDebuggerUrl\": \"ws://127.0.0.1:9222/\"") != null); } From 447a340366511f63cc4cbb3d454a82d0e171092b Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Wed, 15 Jul 2026 15:38:13 +0200 Subject: [PATCH 2/2] expose LP.version including Lightpanda's version --- src/cdp/domains/lp.zig | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/cdp/domains/lp.zig b/src/cdp/domains/lp.zig index be69776be..0a8b1371e 100644 --- a/src/cdp/domains/lp.zig +++ b/src/cdp/domains/lp.zig @@ -45,6 +45,7 @@ pub fn processMessage(cmd: *CDP.Command) !void { waitForSelector, handleJavaScriptDialog, configureLoading, + version, }, cmd.input.action) orelse return error.UnknownMethod; switch (action) { @@ -61,9 +62,16 @@ pub fn processMessage(cmd: *CDP.Command) !void { .waitForSelector => return waitForSelector(cmd), .handleJavaScriptDialog => return handleJavaScriptDialog(cmd), .configureLoading => return configureLoading(cmd), + .version => return version(cmd), } } +fn version(cmd: *CDP.Command) !void { + return cmd.sendResult(.{ + .version = lp.build_config.version, + }, .{}); +} + fn configureLoading(cmd: *CDP.Command) !void { // Each field is optional so callers can flip one without resetting // the other to its default. Backwards-compatible: existing callers @@ -386,6 +394,19 @@ fn handleJavaScriptDialog(cmd: anytype) !void { } const testing = @import("../testing.zig"); +test "cdp.lp: version" { + var ctx = try testing.context(); + defer ctx.deinit(); + + try ctx.processMessage(.{ + .id = 1, + .method = "LP.version", + }); + + const result = (try ctx.getSentMessage(0)).?.object.get("result").?.object; + try testing.expectEqualSlices(u8, lp.build_config.version, result.get("version").?.string); +} + test "cdp.lp: getMarkdown" { var ctx = try testing.context(); defer ctx.deinit();