From 26fb5c8dc63058b8f08798eb7f833f6fe58f711f Mon Sep 17 00:00:00 2001 From: Will Chen Date: Tue, 15 Apr 2025 21:42:01 -0700 Subject: [PATCH] Kill on port 32100 on restart app (clean up orphan process) --- package-lock.json | 42 ++++++++++++++++++++++++++++++-- package.json | 4 ++- src/ipc/handlers/app_handlers.ts | 15 +++++++++++- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 377dcab..4fecc6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dyad", - "version": "0.1.2", + "version": "0.1.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dyad", - "version": "0.1.2", + "version": "0.1.3", "license": "MIT", "dependencies": { "@ai-sdk/anthropic": "^1.2.8", @@ -46,6 +46,7 @@ "geist": "^1.3.1", "isomorphic-git": "^1.30.1", "jotai": "^2.12.2", + "kill-port": "^2.0.1", "lucide-react": "^0.487.0", "monaco-editor": "^0.52.2", "openai": "^4.91.1", @@ -78,6 +79,7 @@ "@electron/fuses": "^1.8.0", "@testing-library/react": "^16.3.0", "@types/better-sqlite3": "^7.6.13", + "@types/kill-port": "^2.0.3", "@types/node": "^22.14.0", "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", @@ -7419,6 +7421,17 @@ "@types/node": "*" } }, + "node_modules/@types/kill-port": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/kill-port/-/kill-port-2.0.3.tgz", + "integrity": "sha512-ZHs59e5FBjDLQLOxM48+814LSyNf5sgpi0odtJ0FH6xrIAZXb4yksYG+4mZCbidX3fBOfHytAKAVMgkWvv/Piw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "shell-exec": "^1" + } + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -12638,6 +12651,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-them-args": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/get-them-args/-/get-them-args-1.3.2.tgz", + "integrity": "sha512-LRn8Jlk+DwZE4GTlDbT3Hikd1wSHgLMme/+7ddlqKd7ldwR6LjJgTVWzBnR01wnYGe4KgrXjg287RaI22UHmAw==", + "license": "MIT" + }, "node_modules/get-tsconfig": { "version": "4.10.0", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz", @@ -14296,6 +14315,19 @@ "json-buffer": "3.0.1" } }, + "node_modules/kill-port": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/kill-port/-/kill-port-2.0.1.tgz", + "integrity": "sha512-e0SVOV5jFo0mx8r7bS29maVWp17qGqLBZ5ricNSajON6//kmb7qqqNnml4twNE8Dtj97UQD+gNFOaipS/q1zzQ==", + "license": "MIT", + "dependencies": { + "get-them-args": "1.3.2", + "shell-exec": "1.0.2" + }, + "bin": { + "kill-port": "cli.js" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -18098,6 +18130,12 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/shell-exec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shell-exec/-/shell-exec-1.0.2.tgz", + "integrity": "sha512-jyVd+kU2X+mWKMmGhx4fpWbPsjvD53k9ivqetutVW/BQ+WIZoDoP4d8vUMGezV6saZsiNoW2f9GIhg9Dondohg==", + "license": "MIT" + }, "node_modules/shell-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shell-path/-/shell-path-3.0.0.tgz", diff --git a/package.json b/package.json index 5891c48..b708285 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "@electron/fuses": "^1.8.0", "@testing-library/react": "^16.3.0", "@types/better-sqlite3": "^7.6.13", + "@types/kill-port": "^2.0.3", "@types/node": "^22.14.0", "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", @@ -99,6 +100,7 @@ "geist": "^1.3.1", "isomorphic-git": "^1.30.1", "jotai": "^2.12.2", + "kill-port": "^2.0.1", "lucide-react": "^0.487.0", "monaco-editor": "^0.52.2", "openai": "^4.91.1", @@ -118,4 +120,4 @@ "update-electron-app": "^3.1.1", "uuid": "^11.1.0" } -} \ No newline at end of file +} diff --git a/src/ipc/handlers/app_handlers.ts b/src/ipc/handlers/app_handlers.ts index c8ba170..994b8c3 100644 --- a/src/ipc/handlers/app_handlers.ts +++ b/src/ipc/handlers/app_handlers.ts @@ -34,6 +34,7 @@ import { readSettings } from "../../main/settings"; import { Worker } from "worker_threads"; import fixPath from "fix-path"; import { getGitAuthor } from "../utils/git_author"; +import killPort from "kill-port"; // Needed, otherwise electron in MacOS/Linux will not be able // to find "npm". @@ -144,7 +145,7 @@ async function executeAppLocalNode({ appId: number; event: Electron.IpcMainInvokeEvent; }): Promise { - const process = spawn("npm install && npm run dev", [], { + const process = spawn("npm install && npm run dev -- --port 32100", [], { cwd: appPath, shell: true, stdio: "pipe", // Ensure stdio is piped so we can capture output/errors and detect close @@ -247,6 +248,15 @@ function checkCommandExists(command: string): Promise { }); } +// Helper to kill process on a specific port (cross-platform, using kill-port) +async function killProcessOnPort(port: number): Promise { + try { + await killPort(port, "tcp"); + } catch (err) { + // Ignore if nothing was running on that port + } +} + export function registerAppHandlers() { ipcMain.handle( "nodejs-status", @@ -566,6 +576,9 @@ export function registerAppHandlers() { ); } + // Kill any orphaned process on port 32100 (in case previous run left it) + await killProcessOnPort(32100); + // Now start the app again const app = await db.query.apps.findFirst({ where: eq(apps.id, appId),