mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
Persist the IPC port in workspaceState and try to rebind to it on activation so restored terminals still have a valid PLANNOTATOR_VSCODE_PORT. Falls back to a random port if the preferred one is taken. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -48,13 +48,16 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
|
||||
vscode.window.showInformationMessage("Plannotator panel opened");
|
||||
};
|
||||
|
||||
// Start local IPC server to receive URLs from the router script
|
||||
// Start local IPC server to receive URLs from the router script.
|
||||
// Reuse the last port so restored terminals still have a valid PLANNOTATOR_VSCODE_PORT.
|
||||
const lastPort = context.workspaceState.get<number>("ipcPort");
|
||||
const { server, port } = await createIpcServer((url) => {
|
||||
openInPanel(url).catch((err) => {
|
||||
log.error(`[open] failed: ${err}`);
|
||||
vscode.window.showErrorMessage(`Plannotator: ${err}`);
|
||||
});
|
||||
});
|
||||
}, lastPort);
|
||||
context.workspaceState.update("ipcPort", port);
|
||||
context.subscriptions.push({ dispose: () => server.close() });
|
||||
|
||||
// Inject env vars into integrated terminals
|
||||
|
||||
@@ -6,31 +6,39 @@ import * as http from "http";
|
||||
*/
|
||||
export function createIpcServer(
|
||||
onUrl: (url: string) => void,
|
||||
preferredPort?: number,
|
||||
): Promise<{ server: http.Server; port: number }> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const server = http.createServer((req, res) => {
|
||||
const parsed = new globalThis.URL(req.url!, "http://localhost");
|
||||
const targetUrl = parsed.searchParams.get("url");
|
||||
const handler = (req: http.IncomingMessage, res: http.ServerResponse) => {
|
||||
const parsed = new globalThis.URL(req.url!, "http://localhost");
|
||||
const targetUrl = parsed.searchParams.get("url");
|
||||
|
||||
if (req.method === "GET" && parsed.pathname === "/open" && targetUrl) {
|
||||
onUrl(targetUrl);
|
||||
res.writeHead(200);
|
||||
res.end("ok");
|
||||
} else {
|
||||
res.writeHead(404);
|
||||
res.end("not found");
|
||||
}
|
||||
if (req.method === "GET" && parsed.pathname === "/open" && targetUrl) {
|
||||
onUrl(targetUrl);
|
||||
res.writeHead(200);
|
||||
res.end("ok");
|
||||
} else {
|
||||
res.writeHead(404);
|
||||
res.end("not found");
|
||||
}
|
||||
};
|
||||
|
||||
function listen(port: number): Promise<{ server: http.Server; port: number }> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const server = http.createServer(handler);
|
||||
server.listen(port, "127.0.0.1", () => {
|
||||
const addr = server.address();
|
||||
if (addr && typeof addr === "object") {
|
||||
resolve({ server, port: addr.port });
|
||||
} else {
|
||||
reject(new Error("Failed to get server address"));
|
||||
}
|
||||
});
|
||||
server.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
server.listen(0, "127.0.0.1", () => {
|
||||
const addr = server.address();
|
||||
if (addr && typeof addr === "object") {
|
||||
resolve({ server, port: addr.port });
|
||||
} else {
|
||||
reject(new Error("Failed to get server address"));
|
||||
}
|
||||
});
|
||||
|
||||
server.on("error", reject);
|
||||
});
|
||||
if (preferredPort) {
|
||||
return listen(preferredPort).catch(() => listen(0));
|
||||
}
|
||||
return listen(0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user