From 6464af7ced56dfaec16002ef6f3666a6907b409b Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Mon, 29 Jun 2026 00:15:30 +0300 Subject: [PATCH] fix(opencode): never expose a port we don't manage to the process killer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Electron-side OpenCode killer kills by port (lsof + kill -KILL). getOpenCodeProcessInfo returned openCodePort unconditionally, so for an external/attached OpenCode (e.g. a user's own server on 4096) the only thing stopping the killer from taking it down was the separate `managed` flag — a single weak signal guarding a destructive action. Withhold pid/port unless we actually manage the process, so the killer has no target even if `managed` is ever miscomputed. Managed flow is unchanged. --- packages/web/server/index.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/web/server/index.js b/packages/web/server/index.js index b8bb35cc..4f7339dc 100644 --- a/packages/web/server/index.js +++ b/packages/web/server/index.js @@ -1327,11 +1327,20 @@ async function main(options = {}) { }), isReady: () => isOpenCodeReady, restartOpenCode: () => restartOpenCode(), - getOpenCodeProcessInfo: () => ({ - managed: Boolean((openCodeProcess || openCodePort) && !ENV_SKIP_OPENCODE_START && !isExternalOpenCode), - pid: typeof openCodeProcess?.pid === 'number' ? openCodeProcess.pid : null, - port: openCodePort, - }), + getOpenCodeProcessInfo: () => { + const managed = Boolean((openCodeProcess || openCodePort) && !ENV_SKIP_OPENCODE_START && !isExternalOpenCode); + // Only ever expose pid/port for a server WE manage. The Electron-side + // killer kills by port (lsof + kill -KILL), so returning a port we don't + // own — e.g. an external/desktop OpenCode on 4096 we attached to — would + // let a single miscomputed `managed` flag take down the user's separate + // server. Structurally withhold what isn't ours so the killer has no + // target, instead of relying on the flag check alone. + return { + managed, + pid: managed && typeof openCodeProcess?.pid === 'number' ? openCodeProcess.pid : null, + port: managed ? openCodePort : null, + }; + }, stop: (shutdownOptions = {}) => gracefulShutdown({ exitProcess: shutdownOptions.exitProcess ?? false }) };