CB-304: bridge_list roster + live herdr join (worktree/branch); add GET /workers

This commit is contained in:
Dai Ha
2026-07-17 09:50:12 +02:00
parent 64e70efdf1
commit 84102baab4
5 changed files with 105 additions and 17 deletions
@@ -8,7 +8,10 @@ import dev.ltms.bridged.herdr.WorkspaceControl;
import dev.ltms.bridged.inject.Injector;
import dev.ltms.bridged.msg.MessageService;
import dev.ltms.bridged.msg.Rendezvous;
import dev.ltms.bridged.session.FakeWorktrees;
import dev.ltms.bridged.session.SessionManager;
import dev.ltms.bridged.session.WorkerSession;
import dev.ltms.bridged.session.WorktreeRequest;
import dev.ltms.bridged.worker.WorkerService;
import io.modelcontextprotocol.spec.McpSchema;
import org.junit.jupiter.api.Test;
@@ -237,9 +240,23 @@ class BridgeMcpTest {
@Test
void listReportsTrackedWorkers() {
FakeHerdr h = new FakeHerdr();
McpSchema.CallToolResult res = BridgeMcp.listWorkers(workerService(h, "http://gx00.gw:8000", Set.of("gx00.gw")));
FakeWorktrees worktrees = new FakeWorktrees().withRepoRoot("/repo").withPrefix("/wt");
SessionManager sessions = new SessionManager(workerService(h, "http://gx00.gw:8000", Set.of("gx00.gw")), worktrees);
WorkerSession s = sessions.acquire("ltms-local", null, "/caller/proj", "term_primary",
new WorktreeRequest("cb-304", null));
McpSchema.CallToolResult res = BridgeMcp.listWorkers(workerService(h, "http://gx00.gw:8000", Set.of("gx00.gw")), sessions);
assertNotEquals(Boolean.TRUE, res.isError());
assertTrue(textOf(res).contains("\"sessionId\":\"term_a\""), textOf(res));
String out = textOf(res);
assertTrue(out.contains("\"sessionId\":\"" + s.terminalId() + "\""), out);
assertTrue(out.contains("\"paneId\":\"" + s.paneId() + "\""), out);
assertTrue(out.contains("\"profile\":\"ltms-local\""), out);
assertTrue(out.contains("\"state\":\"spawning\""), out);
assertTrue(out.contains("\"worktree\":\"" + s.worktree() + "\""), out);
assertTrue(out.contains("\"branch\":\"" + s.branch() + "\""), out);
assertTrue(out.contains("\"owner\":\"term_primary\""), out);
assertTrue(out.contains("\"liveStatus\":\"unknown\""), out);
}
@Test
@@ -12,7 +12,10 @@ import dev.ltms.bridged.inject.StatusPoller;
import dev.ltms.bridged.inject.WorkerPresence;
import dev.ltms.bridged.msg.MessageService;
import dev.ltms.bridged.msg.Rendezvous;
import dev.ltms.bridged.session.FakeWorktrees;
import dev.ltms.bridged.session.GitWorktrees;
import dev.ltms.bridged.session.SessionManager;
import dev.ltms.bridged.session.Worktrees;
import dev.ltms.bridged.worker.WorkerService;
import io.javalin.Javalin;
import org.junit.jupiter.api.AfterEach;
@@ -53,6 +56,10 @@ class BridgedAppTest {
}
private int start(FakeHerdr herdr, String workerBaseUrl, Set<String> allow, String placement) {
return start(herdr, workerBaseUrl, allow, placement, new GitWorktrees());
}
private int start(FakeHerdr herdr, String workerBaseUrl, Set<String> allow, String placement, Worktrees worktrees) {
BridgedConfig.Worker wcfg = new BridgedConfig.Worker(
"ltms-local", workerBaseUrl, "coder", null, "BRIDGED_WORKER_TOKEN", null,
placement, "bridged-workers", "worker: {profile} #{n}", null, null, null);
@@ -61,7 +68,7 @@ class BridgedAppTest {
agents, new WorkspaceControl(herdr), new SubscriptionGuard(allow),
Map.of(wcfg.profile(), wcfg), wcfg.profile(),
k -> "BRIDGED_WORKER_TOKEN".equals(k) ? "tok-abc" : null);
SessionManager sessions = new SessionManager(workers);
SessionManager sessions = new SessionManager(workers, worktrees);
this.presence = sessions.asPresence();
Injector injector = new Injector(agents);
poller = new StatusPoller(agents, injector, 5); // delivers when the fake reports idle
@@ -177,6 +184,32 @@ class BridgedAppTest {
assertEquals("ltms-local", body.get("profiles").get(0).asText());
}
@Test
void workersEndpointReturnsRegistryRosterWithLiveStatus() throws Exception {
FakeHerdr herdr = new FakeHerdr();
int port = start(herdr, "http://gx00.gw:8000", Set.of("gx00.gw"), "tab",
new FakeWorktrees().withRepoRoot("/repo").withPrefix("/wt"));
HttpResponse<String> spawn = req(port, "POST", "/workers?worktree=true&ticket=cb-304");
assertEquals(201, spawn.statusCode());
JsonNode spawned = mapper.readTree(spawn.body());
String paneId = spawned.get("paneId").asText();
HttpResponse<String> res = req(port, "GET", "/workers");
assertEquals(200, res.statusCode());
JsonNode workers = mapper.readTree(res.body()).get("workers");
assertEquals(1, workers.size());
JsonNode w = workers.get(0);
assertEquals(spawned.get("terminalId").asText(), w.get("sessionId").asText());
assertEquals(paneId, w.get("paneId").asText());
assertEquals("ltms-local", w.get("profile").asText());
assertEquals("spawning", w.get("state").asText());
assertTrue(w.has("worktree"), "worktree-backed session exposes worktree");
assertTrue(w.has("branch"), "worktree-backed session exposes branch");
assertEquals("unknown", w.get("liveStatus").asText(),
"liveStatus is unknown when herdr has no matching pane");
}
@Test
void spawnWithACwdParamRootsTheWorkerThere() throws Exception {
FakeHerdr herdr = new FakeHerdr();