feat(bridge): establish local pi status bridge
Deliver the initial local bridge, Noctalia v4/v5 adapters, desktop client, service unit, tests, and implementation documentation for persistent Pi status and control.
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import path from "node:path";
|
||||
import { createAgentRegistry, UnknownAgentError } from "./agent-registry.js";
|
||||
import { startPiRpcAdapter } from "./pi-rpc-adapter.js";
|
||||
import { ProtocolError } from "../protocol/index.js";
|
||||
import { createRuntimePaths, startBridgeServer } from "./runtime.js";
|
||||
|
||||
export async function startBridgeService({
|
||||
homeWorktree,
|
||||
runtimeDir,
|
||||
sessionRoot,
|
||||
startAdapter = startPiRpcAdapter,
|
||||
processAlive,
|
||||
maxFrameBytes,
|
||||
}) {
|
||||
const paths = await createRuntimePaths(runtimeDir);
|
||||
const registry = createAgentRegistry({
|
||||
homeWorktree,
|
||||
sessionRoot: sessionRoot ?? path.join(paths.directory, "sessions"),
|
||||
startAdapter,
|
||||
});
|
||||
|
||||
const dispatch = async (request) => {
|
||||
try {
|
||||
switch (request.op) {
|
||||
case "list_agents":
|
||||
return { agents: registry.listAgents() };
|
||||
case "list_directories":
|
||||
return { directories: await registry.listDirectories() };
|
||||
case "select_agent":
|
||||
return {
|
||||
agent: await registry.selectWorktree(request.payload.worktreePath),
|
||||
};
|
||||
case "subscribe":
|
||||
return {
|
||||
events: registry.eventsAfter(
|
||||
request.agentId,
|
||||
request.payload.cursor ?? 0,
|
||||
),
|
||||
};
|
||||
case "retry":
|
||||
return { agent: await registry.retry(request.agentId) };
|
||||
case "restart":
|
||||
return { agent: await registry.restart(request.agentId) };
|
||||
case "list_sessions":
|
||||
return { sessions: await registry.listSessions(request.agentId) };
|
||||
default:
|
||||
return registry.route(request.agentId, request.op, request.payload);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof UnknownAgentError)
|
||||
throw new ProtocolError("unknown_agent", error.message);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
const server = await startBridgeServer({
|
||||
runtimeDir,
|
||||
handleRequest: dispatch,
|
||||
subscribe: (request, notify) => {
|
||||
const subscription = registry.subscribe(
|
||||
request.agentId,
|
||||
request.payload.cursor ?? 0,
|
||||
notify,
|
||||
);
|
||||
return {
|
||||
result: { events: subscription.events },
|
||||
unsubscribe: subscription.unsubscribe,
|
||||
};
|
||||
},
|
||||
...(processAlive ? { processAlive } : {}),
|
||||
...(maxFrameBytes ? { maxFrameBytes } : {}),
|
||||
});
|
||||
try {
|
||||
await registry.start();
|
||||
} catch (error) {
|
||||
await server.close();
|
||||
throw error;
|
||||
}
|
||||
|
||||
return {
|
||||
socketPath: server.socketPath,
|
||||
listAgents: () => registry.listAgents(),
|
||||
async close() {
|
||||
await registry.stop();
|
||||
await server.close();
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user