UNPKG

portio

Version:

A beautiful terminal UI for managing processes on network ports (Windows only)

107 lines (106 loc) 3.66 kB
import React, { useEffect, useState } from 'react'; import { Box, Text, useApp, useInput } from 'ink'; import { getProcessOnPort, killProcess } from '../utils/portDetector.js'; export const KillMode = ({ port, force = false }) => { const { exit } = useApp(); const [loading, setLoading] = useState(true); const [process, setProcess] = useState(null); const [error, setError] = useState(null); const [waitingForConfirm, setWaitingForConfirm] = useState(false); const [killing, setKilling] = useState(false); const [result, setResult] = useState(null); useEffect(() => { const checkPort = async () => { try { const proc = await getProcessOnPort(port); setProcess(proc); setLoading(false); if (proc && force) { await performKill(proc.pid); } else if (proc) { setWaitingForConfirm(true); } else { setTimeout(() => exit(), 100); } } catch (err) { setError(err instanceof Error ? err.message : 'Unknown error'); setLoading(false); setTimeout(() => exit(), 100); } }; checkPort(); }, [port, force]); const performKill = async (pid) => { setKilling(true); setWaitingForConfirm(false); try { const success = await killProcess(pid); if (success) { setResult(`✓ Successfully killed process ${pid} on port ${port}`); } else { setResult(`✗ Failed to kill process ${pid}. Try running with elevated privileges.`); } } catch (err) { setResult(`✗ Error killing process: ${err instanceof Error ? err.message : 'Unknown error'}`); } finally { setKilling(false); setTimeout(() => exit(), 1000); } }; useInput((input, key) => { if (!waitingForConfirm) return; if (input === 'y' || input === 'Y') { if (process) { performKill(process.pid); } } else if (input === 'n' || input === 'N' || key.escape) { setResult('Kill cancelled'); setTimeout(() => exit(), 100); } }, { isActive: !force }); if (loading) { return (React.createElement(Text, { color: "yellow" }, "Checking port ", port, "...")); } if (error) { return (React.createElement(Text, { color: "red" }, "Error: ", error)); } if (!process) { return (React.createElement(Text, { color: "green" }, "\u2713 Port ", port, " is already free")); } if (killing) { return (React.createElement(Text, { color: "yellow" }, "Killing process ", process.pid, "...")); } if (result) { return (React.createElement(Text, { color: result.startsWith('✓') ? 'green' : result === 'Kill cancelled' ? 'yellow' : 'red' }, result)); } if (waitingForConfirm) { return (React.createElement(Box, { flexDirection: "column" }, React.createElement(Text, null, process.processName || 'Unknown', " (PID: ", process.pid, ") on port ", port), React.createElement(Text, { color: "red" }, "Kill this process? (y/n): "))); } return null; };