fix(remote-control): resync clients on session switch
This commit is contained in:
parent
f16a5fed83
commit
33403bd030
|
|
@ -74,6 +74,11 @@ export default function remoteControl(pi: ExtensionAPI) {
|
|||
updateStatus(ctx);
|
||||
});
|
||||
|
||||
pi.on("session_switch", async (_event, ctx) => {
|
||||
server?.sync(ctx);
|
||||
updateStatus(ctx);
|
||||
});
|
||||
|
||||
pi.on("session_shutdown", async () => {
|
||||
if (server) {
|
||||
await server.stop();
|
||||
|
|
|
|||
|
|
@ -79,3 +79,25 @@ export function getBranchMessages(ctx: ExtensionContext): RenderMsg[] {
|
|||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
export function buildSyncMessage(ctx: ExtensionContext): {
|
||||
type: "sync";
|
||||
messages: RenderMsg[];
|
||||
state: {
|
||||
isStreaming: boolean;
|
||||
model: string | undefined;
|
||||
cwd: string;
|
||||
sessionName: string | undefined;
|
||||
};
|
||||
} {
|
||||
return {
|
||||
type: "sync",
|
||||
messages: getBranchMessages(ctx),
|
||||
state: {
|
||||
isStreaming: !ctx.isIdle(),
|
||||
model: ctx.model?.id,
|
||||
cwd: ctx.cwd,
|
||||
sessionName: ctx.sessionManager.getSessionName(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import {
|
|||
generateSessionId,
|
||||
parseCookies,
|
||||
} from "./auth.js";
|
||||
import { getBranchMessages } from "./messages.js";
|
||||
import { buildSyncMessage } from "./messages.js";
|
||||
import { buildHTML } from "./html.js";
|
||||
|
||||
// Load ws (bundled with pi) without needing @types/ws installed locally
|
||||
|
|
@ -29,6 +29,7 @@ const { WebSocketServer, OPEN } = wsModule;
|
|||
|
||||
export interface RemoteServer {
|
||||
broadcast: (msg: object) => void;
|
||||
sync: (ctx: ExtensionContext) => void;
|
||||
stop: () => Promise<void>;
|
||||
clientCount: () => number;
|
||||
onClientChange: (cb: () => void) => void;
|
||||
|
|
@ -79,6 +80,10 @@ export function startServer(pi: ExtensionAPI, ctx: ExtensionContext): Promise<Re
|
|||
}
|
||||
}
|
||||
|
||||
function sync(currentCtx: ExtensionContext): void {
|
||||
broadcast(buildSyncMessage(currentCtx));
|
||||
}
|
||||
|
||||
const httpServer = createServer((req, res) => {
|
||||
const url = new URL(req.url ?? "/", "http://localhost");
|
||||
const pathname = url.pathname;
|
||||
|
|
@ -160,18 +165,7 @@ export function startServer(pi: ExtensionAPI, ctx: ExtensionContext): Promise<Re
|
|||
|
||||
// Send full state snapshot to the new client
|
||||
try {
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: "sync",
|
||||
messages: getBranchMessages(ctx),
|
||||
state: {
|
||||
isStreaming: !ctx.isIdle(),
|
||||
model: ctx.model?.id,
|
||||
cwd: ctx.cwd,
|
||||
sessionName: ctx.sessionManager.getSessionName(),
|
||||
},
|
||||
}),
|
||||
);
|
||||
ws.send(JSON.stringify(buildSyncMessage(ctx)));
|
||||
} catch {
|
||||
/* client disconnected before first send */
|
||||
}
|
||||
|
|
@ -225,6 +219,7 @@ export function startServer(pi: ExtensionAPI, ctx: ExtensionContext): Promise<Re
|
|||
httpServer.listen(0, "127.0.0.1", () => {
|
||||
resolve({
|
||||
broadcast,
|
||||
sync,
|
||||
stop: () =>
|
||||
new Promise<void>((res) => {
|
||||
// Forcefully kill all WebSocket clients — terminate() sends no
|
||||
|
|
|
|||
Loading…
Reference in New Issue