@@ -63,10 +63,10 @@ fn appendInstanceJson(buf: *std.array_list.Managed(u8), entry: state_mod.Instanc
6363// ─── Handlers ────────────────────────────────────────────────────────────────
6464
6565/// GET /api/status — aggregated dashboard data.
66- pub fn handleStatus (allocator : std.mem.Allocator , s : * state_mod.State , manager : * manager_mod.Manager , uptime_seconds : u64 , host : []const u8 , port : u16 ) ApiResponse {
66+ pub fn handleStatus (allocator : std.mem.Allocator , s : * state_mod.State , manager : * manager_mod.Manager , uptime_seconds : u64 , host : []const u8 , port : u16 , access_options : access.Options ) ApiResponse {
6767 var buf = std .array_list .Managed (u8 ).init (allocator );
6868
69- buildStatusJson (& buf , s , manager , uptime_seconds , host , port ) catch return .{
69+ buildStatusJson (& buf , s , manager , uptime_seconds , host , port , access_options ) catch return .{
7070 .status = "500 Internal Server Error" ,
7171 .content_type = "application/json" ,
7272 .body = "{\" error\" :\" internal error\" }" ,
@@ -75,8 +75,8 @@ pub fn handleStatus(allocator: std.mem.Allocator, s: *state_mod.State, manager:
7575 return .{ .status = "200 OK" , .content_type = "application/json" , .body = buf .items };
7676}
7777
78- fn buildStatusJson (buf : * std .array_list .Managed (u8 ), s : * state_mod .State , manager : * manager_mod.Manager , uptime_seconds : u64 , host : []const u8 , port : u16 ) ! void {
79- var urls = try access .buildAccessUrls (buf .allocator , host , port );
78+ fn buildStatusJson (buf : * std .array_list .Managed (u8 ), s : * state_mod .State , manager : * manager_mod.Manager , uptime_seconds : u64 , host : []const u8 , port : u16 , access_options : access . Options ) ! void {
79+ var urls = try access .buildAccessUrlsWithOptions (buf .allocator , host , port , access_options );
8080 defer urls .deinit (buf .allocator );
8181
8282 // Hub info
@@ -100,6 +100,11 @@ fn buildStatusJson(buf: *std.array_list.Managed(u8), s: *state_mod.State, manage
100100 try buf .appendSlice (urls .fallback_url );
101101 try buf .appendSlice ("\" ,\" local_alias_chain\" :" );
102102 try buf .appendSlice (if (urls .local_alias_chain ) "true" else "false" );
103+ try buf .appendSlice (",\" public_alias_active\" :" );
104+ try buf .appendSlice (if (urls .public_alias_active ) "true" else "false" );
105+ try buf .appendSlice (",\" public_alias_provider\" :\" " );
106+ try buf .appendSlice (urls .public_alias_provider );
107+ try buf .append ('"' );
103108 try buf .appendSlice (",\" public_alias_url\" :" );
104109 if (urls .public_alias_url ) | url | {
105110 try buf .append ('"' );
@@ -161,7 +166,7 @@ test "handleStatus returns valid JSON with hub version" {
161166 var mgr = manager_mod .Manager .init (allocator , p );
162167 defer mgr .deinit ();
163168
164- const resp = handleStatus (allocator , & s , & mgr , 3600 , access .default_bind_host , access .default_port );
169+ const resp = handleStatus (allocator , & s , & mgr , 3600 , access .default_bind_host , access .default_port , .{} );
165170 defer allocator .free (resp .body );
166171
167172 try std .testing .expectEqualStrings ("200 OK" , resp .status );
@@ -176,6 +181,8 @@ test "handleStatus returns valid JSON with hub version" {
176181 uptime_seconds : u64 ,
177182 access : struct {
178183 browser_open_url : []const u8 ,
184+ public_alias_active : bool ,
185+ public_alias_provider : []const u8 ,
179186 },
180187 },
181188 instances : std .json .ArrayHashMap (std .json .ArrayHashMap (struct {
@@ -193,6 +200,8 @@ test "handleStatus returns valid JSON with hub version" {
193200 try std .testing .expectEqualStrings ("2026.3.2" , parsed .value .hub .version );
194201 try std .testing .expect (parsed .value .hub .platform .len > 0 );
195202 try std .testing .expectEqual (@as (u64 , 3600 ), parsed .value .hub .uptime_seconds );
203+ try std .testing .expect (! parsed .value .hub .access .public_alias_active );
204+ try std .testing .expectEqualStrings ("none" , parsed .value .hub .access .public_alias_provider );
196205 try std .testing .expectEqualStrings ("http://nullhub.localhost:19800" , parsed .value .hub .access .browser_open_url );
197206}
198207
@@ -207,7 +216,7 @@ test "handleStatus includes instances" {
207216
208217 try s .addInstance ("nullclaw" , "my-agent" , .{ .version = "2026.3.1" , .auto_start = true });
209218
210- const resp = handleStatus (allocator , & s , & mgr , 0 , access .default_bind_host , access .default_port );
219+ const resp = handleStatus (allocator , & s , & mgr , 0 , access .default_bind_host , access .default_port , .{} );
211220 defer allocator .free (resp .body );
212221
213222 try std .testing .expectEqualStrings ("200 OK" , resp .status );
@@ -252,7 +261,7 @@ test "handleStatus includes launch_mode" {
252261
253262 try s .addInstance ("nullclaw" , "my-agent" , .{ .version = "1.0.0" , .launch_mode = "agent" });
254263
255- const resp = handleStatus (allocator , & s , & mgr , 0 , access .default_bind_host , access .default_port );
264+ const resp = handleStatus (allocator , & s , & mgr , 0 , access .default_bind_host , access .default_port , .{} );
256265 defer allocator .free (resp .body );
257266
258267 try std .testing .expectEqualStrings ("200 OK" , resp .status );
@@ -268,7 +277,7 @@ test "handleStatus with empty state returns empty instances" {
268277 var mgr = manager_mod .Manager .init (allocator , p );
269278 defer mgr .deinit ();
270279
271- const resp = handleStatus (allocator , & s , & mgr , 42 , access .default_bind_host , access .default_port );
280+ const resp = handleStatus (allocator , & s , & mgr , 42 , access .default_bind_host , access .default_port , .{} );
272281 defer allocator .free (resp .body );
273282
274283 try std .testing .expectEqualStrings ("200 OK" , resp .status );
0 commit comments