// Name: What Occupied Port // Description: Show which process is using a given port and optionally kill it. // Author: benhaotang // GitHub: benhaotang import '@johnlindquist/kit' const portStr = await arg({ placeholder: 'Enter a port number (1-65535)', validate: (input: string) => { const n = Number(input) if (!Number.isInteger(n) || n < 1 || n > 65535) return 'Enter a valid port number between 1 and 65535' return true }, }) const port = Number(portStr) let output = '' let pids = new Set<number>() const parseLsof = (text: string) => { for (const line of text.split('\n').slice(1)) { const parts = line.trim().split(/\s+/) const pid = Number(parts[1]) if (Number.isInteger(pid)) pids.add(pid) } } const parseSs = (text: string) => { const re = /pid=(\d+)/g let m: RegExpExecArray | null while ((m = re.exec(text))) { const pid = Number(m[1]) if (Number.isInteger(pid)) pids.add(pid) } } const parseNetstat = (text: string) => { for (const line of text.split('\n')) { const trimmed = line.trim() if (!trimmed) continue const parts = trimmed.split(/\s+/) const last = parts[parts.length - 1] const pid = Number(last) if (Number.isInteger(pid)) pids.add(pid) } } try { if (isWin) { const { stdout } = await exec(`netstat -ano | findstr :${port}`) output = stdout || '' parseNetstat(output) } else if (isMac) { try { const { stdout } = await exec(`lsof -nP -i TCP:${port} -sTCP:LISTEN`) output = stdout || '' parseLsof(output) } catch { output = '' } } else { // Linux try { const { stdout } = await exec(`lsof -nP -i TCP:${port} -sTCP:LISTEN`) output = stdout || '' parseLsof(output) } catch { try { const { stdout } = await exec(`ss -ltnp | grep :${port} || true`) output = stdout || '' parseSs(output) } catch { output = '' } } } } catch (err: any) { output = err?.all || err?.message || String(err) } const summary = pids.size > 0 ? `Found ${pids.size} process(es) using port ${port}.` : `No process appears to be listening on port ${port}.` await div( md(` ## Port ${port} ${summary} ### Raw output \`\`\` ${(output || '(no output)').trim()} \`\`\` `) ) if (pids.size > 0) { const pid = await arg<number>( { placeholder: 'Select a PID to kill (or Esc to cancel)', }, Array.from(pids).map(n => ({ name: `PID ${n}`, description: `Kill process ${n}`, value: n, })) ) try { if (isWin) { await exec(`taskkill /PID ${pid} /F`) } else { await exec(`kill -9 ${pid}`) } await notify(`Killed PID ${pid} on port ${port}`) } catch (err: any) { await notify({ title: 'Failed to kill process', body: err?.message || String(err), }) } }