byeport 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -0
- package/dist/cli.js +16 -0
- package/dist/cli.js.map +1 -0
- package/dist/components/ProcessList.js +36 -0
- package/dist/components/ProcessList.js.map +1 -0
- package/dist/ui.js +47 -0
- package/dist/ui.js.map +1 -0
- package/dist/utils/processes.js +62 -0
- package/dist/utils/processes.js.map +1 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Byeport �
|
|
2
|
+
|
|
3
|
+
A beautiful, interactive Terminal User Interface (TUI) to identify and kill running processes on your ports.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
- **Clean UI**: Beautiful gradient header and clear table layout.
|
|
9
|
+
- **Interactive**: Navigate with arrow keys, kill with Enter.
|
|
10
|
+
- **Safe**: Clearly shows Process Name, PID, and Port before you act.
|
|
11
|
+
- **Zero Config**: Automatically scans your TCP ports.
|
|
12
|
+
|
|
13
|
+
## How to use
|
|
14
|
+
|
|
15
|
+
### Option 1: Run via npx (Recommended)
|
|
16
|
+
```bash
|
|
17
|
+
npx byeport
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Option 2: Global Installation
|
|
21
|
+
```bash
|
|
22
|
+
npm install -g byeport
|
|
23
|
+
```
|
|
24
|
+
Then run it anywhere:
|
|
25
|
+
```bash
|
|
26
|
+
byeport
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Option 3: Run from Source
|
|
30
|
+
1. Clone this repository.
|
|
31
|
+
2. Install dependencies:
|
|
32
|
+
```bash
|
|
33
|
+
npm install
|
|
34
|
+
```
|
|
35
|
+
3. Build the project:
|
|
36
|
+
```bash
|
|
37
|
+
npm run build
|
|
38
|
+
```
|
|
39
|
+
4. Start the tool:
|
|
40
|
+
```bash
|
|
41
|
+
npm start
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Development
|
|
45
|
+
Built with [Ink](https://github.com/vadimdemedes/ink), React, and TypeScript.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Run in dev mode (watches for changes)
|
|
49
|
+
npm run dev
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## License
|
|
53
|
+
MIT
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { render } from 'ink';
|
|
4
|
+
import meow from 'meow';
|
|
5
|
+
import App from './ui.js';
|
|
6
|
+
const cli = meow(`
|
|
7
|
+
Usage
|
|
8
|
+
$ port-killer
|
|
9
|
+
|
|
10
|
+
Examples
|
|
11
|
+
$ port-killer
|
|
12
|
+
`, {
|
|
13
|
+
importMeta: import.meta,
|
|
14
|
+
});
|
|
15
|
+
render(_jsx(App, {}));
|
|
16
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../source/cli.tsx"],"names":[],"mappings":";;AAEA,OAAO,EAAC,MAAM,EAAC,MAAM,KAAK,CAAC;AAC3B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,GAAG,MAAM,SAAS,CAAC;AAE1B,MAAM,GAAG,GAAG,IAAI,CACf;;;;;;CAMA,EACA;IACC,UAAU,EAAE,MAAM,CAAC,IAAI;CACvB,CACD,CAAC;AAEF,MAAM,CAAC,KAAC,GAAG,KAAG,CAAC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
import { Box, Text, useInput } from 'ink';
|
|
4
|
+
export const ProcessList = ({ processes, onKill }) => {
|
|
5
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
6
|
+
useInput((input, key) => {
|
|
7
|
+
if (key.upArrow) {
|
|
8
|
+
setSelectedIndex(prev => Math.max(0, prev - 1));
|
|
9
|
+
}
|
|
10
|
+
if (key.downArrow) {
|
|
11
|
+
setSelectedIndex(prev => Math.min(processes.length - 1, prev + 1));
|
|
12
|
+
}
|
|
13
|
+
if (key.return) {
|
|
14
|
+
const selectedProcess = processes[selectedIndex];
|
|
15
|
+
if (selectedProcess) {
|
|
16
|
+
onKill(selectedProcess);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
// Reset selection if list changes and index is out of bounds
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (selectedIndex >= processes.length && processes.length > 0) {
|
|
23
|
+
setSelectedIndex(processes.length - 1);
|
|
24
|
+
}
|
|
25
|
+
}, [processes.length]);
|
|
26
|
+
if (processes.length === 0) {
|
|
27
|
+
return (_jsx(Box, { padding: 1, children: _jsx(Text, { color: "yellow", children: "No processes found matching criteria." }) }));
|
|
28
|
+
}
|
|
29
|
+
const visibleProcesses = processes.slice(Math.max(0, selectedIndex - 5), selectedIndex + 5);
|
|
30
|
+
return (_jsxs(Box, { flexDirection: "column", width: "100%", children: [_jsx(Box, { marginBottom: 1, borderStyle: "single", borderColor: "gray", paddingX: 1, children: _jsxs(Text, { color: "gray", children: ["Use ", _jsx(Text, { bold: true, color: "white", children: "\u2191/\u2193" }), " to navigate, ", _jsx(Text, { bold: true, color: "red", children: "Enter" }), " to kill."] }) }), _jsxs(Box, { paddingX: 2, marginBottom: 0, children: [_jsx(Box, { width: "50%", children: _jsx(Text, { color: "gray", bold: true, children: "PROCESS NAME" }) }), _jsx(Box, { width: "25%", children: _jsx(Text, { color: "gray", bold: true, children: "PID" }) }), _jsx(Box, { width: "25%", children: _jsx(Text, { color: "gray", bold: true, children: "PORT" }) })] }), processes.map((process, index) => {
|
|
31
|
+
const isSelected = index === selectedIndex;
|
|
32
|
+
const bgColor = isSelected ? '#222222' : undefined; // Ink doesn't support bg hex directly easily without chalk, but we can use color attributes
|
|
33
|
+
return (_jsxs(Box, { paddingX: 1, children: [_jsx(Box, { width: 2, children: _jsx(Text, { color: "green", children: isSelected ? '❯' : ' ' }) }), _jsx(Box, { width: "50%", children: _jsx(Text, { bold: isSelected, color: isSelected ? 'cyan' : 'white', wrap: "truncate", children: process.name }) }), _jsx(Box, { width: "25%", children: _jsx(Text, { color: isSelected ? 'white' : 'gray', children: process.pid }) }), _jsx(Box, { width: "25%", children: _jsxs(Text, { color: isSelected ? 'yellow' : 'blue', children: [":", process.port] }) })] }, `${process.pid}-${process.port}`));
|
|
34
|
+
})] }));
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=ProcessList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProcessList.js","sourceRoot":"","sources":["../../source/components/ProcessList.tsx"],"names":[],"mappings":"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"}
|
package/dist/ui.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
3
|
+
import { Text, Box, useApp } from 'ink';
|
|
4
|
+
import Gradient from 'ink-gradient';
|
|
5
|
+
import BigText from 'ink-big-text';
|
|
6
|
+
import { getRunningProcesses, killProcess } from './utils/processes.js';
|
|
7
|
+
import { ProcessList } from './components/ProcessList.js';
|
|
8
|
+
export default function App() {
|
|
9
|
+
const { exit } = useApp();
|
|
10
|
+
const [processes, setProcesses] = useState([]);
|
|
11
|
+
const [loading, setLoading] = useState(true);
|
|
12
|
+
const [message, setMessage] = useState(null);
|
|
13
|
+
const fetchProcesses = async () => {
|
|
14
|
+
setLoading(true);
|
|
15
|
+
try {
|
|
16
|
+
const list = await getRunningProcesses();
|
|
17
|
+
setProcesses(list);
|
|
18
|
+
setLoading(false);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
setLoading(false);
|
|
22
|
+
// Handle error
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
fetchProcesses();
|
|
27
|
+
// Optional: poll every 5 seconds?
|
|
28
|
+
const interval = setInterval(fetchProcesses, 5000);
|
|
29
|
+
return () => clearInterval(interval);
|
|
30
|
+
}, []);
|
|
31
|
+
const handleKill = async (process) => {
|
|
32
|
+
setMessage(`Killing process ${process.name} (PID: ${process.pid})...`);
|
|
33
|
+
try {
|
|
34
|
+
await killProcess(process.pid);
|
|
35
|
+
setMessage(`Successfully killed ${process.name}.`);
|
|
36
|
+
// Refresh immediately
|
|
37
|
+
await fetchProcesses();
|
|
38
|
+
// Clear message after 2s
|
|
39
|
+
setTimeout(() => setMessage(null), 2000);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
setMessage(`Error killing process: ${String(error)}`);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Gradient, { name: "pastel", children: _jsx(BigText, { text: "Port Killer", font: "tiny" }) }), message && (_jsx(Box, { borderStyle: "single", borderColor: "green", marginBottom: 1, paddingX: 1, children: _jsx(Text, { children: message }) })), _jsx(Box, { flexDirection: "column", children: loading && processes.length === 0 ? (_jsx(Text, { color: "gray", children: "Scanning ports..." })) : (_jsx(ProcessList, { processes: processes, onKill: handleKill })) })] }));
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=ui.js.map
|
package/dist/ui.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../source/ui.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { promisify } from 'node:util';
|
|
2
|
+
import { exec } from 'node:child_process';
|
|
3
|
+
import fkill from 'fkill';
|
|
4
|
+
const execAsync = promisify(exec);
|
|
5
|
+
export async function getRunningProcesses() {
|
|
6
|
+
try {
|
|
7
|
+
// -F pcn: Output format for machine parsing (PID, Command, Name)
|
|
8
|
+
// -i: select internet files
|
|
9
|
+
// -P: no port names
|
|
10
|
+
// -n: no host names
|
|
11
|
+
// -sTCP:LISTEN: only listening TCP ports
|
|
12
|
+
const { stdout } = await execAsync('lsof -i -P -n -sTCP:LISTEN -F pcn');
|
|
13
|
+
const processes = [];
|
|
14
|
+
let currentPid = 0;
|
|
15
|
+
let currentCmd = '';
|
|
16
|
+
const lines = stdout.split('\n');
|
|
17
|
+
for (const line of lines) {
|
|
18
|
+
if (!line)
|
|
19
|
+
continue;
|
|
20
|
+
const type = line.charAt(0);
|
|
21
|
+
const value = line.slice(1);
|
|
22
|
+
if (type === 'p') {
|
|
23
|
+
currentPid = parseInt(value, 10);
|
|
24
|
+
currentCmd = ''; // Reset command for new PID
|
|
25
|
+
}
|
|
26
|
+
else if (type === 'c') {
|
|
27
|
+
currentCmd = value;
|
|
28
|
+
}
|
|
29
|
+
else if (type === 'n') {
|
|
30
|
+
// Format is usually *:PORT or IP:PORT
|
|
31
|
+
const portPart = value.split(':').pop();
|
|
32
|
+
if (portPart) {
|
|
33
|
+
const port = parseInt(portPart, 10);
|
|
34
|
+
if (!isNaN(port) && currentPid > 0) {
|
|
35
|
+
processes.push({
|
|
36
|
+
pid: currentPid,
|
|
37
|
+
name: currentCmd || 'unknown',
|
|
38
|
+
port
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Deduplicate
|
|
45
|
+
const unique = new Map();
|
|
46
|
+
for (const p of processes) {
|
|
47
|
+
unique.set(`${p.pid}-${p.port}`, p);
|
|
48
|
+
}
|
|
49
|
+
return Array.from(unique.values()).sort((a, b) => a.port - b.port);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
// lsof returns exit code 1 if no matching files are found
|
|
53
|
+
if (error.code === 1)
|
|
54
|
+
return [];
|
|
55
|
+
console.error('Error fetching processes:', error);
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export async function killProcess(pid) {
|
|
60
|
+
await fkill(pid, { force: true });
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=processes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processes.js","sourceRoot":"","sources":["../../source/utils/processes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,EAAC,IAAI,EAAC,MAAM,oBAAoB,CAAC;AACxC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAQlC,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACxC,IAAI,CAAC;QACE,iEAAiE;QACjE,4BAA4B;QAC5B,oBAAoB;QACpB,oBAAoB;QACpB,yCAAyC;QAC/C,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM,SAAS,CAAC,mCAAmC,CAAC,CAAC;QAEtE,MAAM,SAAS,GAAkB,EAAE,CAAC;QAC9B,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,UAAU,GAAG,EAAE,CAAC;QAEpB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC,IAAI;gBAAE,SAAS;YAEpB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAE5B,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACf,UAAU,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACjC,UAAU,GAAG,EAAE,CAAC,CAAC,4BAA4B;YACjD,CAAC;iBAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACtB,UAAU,GAAG,KAAK,CAAC;YACvB,CAAC;iBAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACtB,sCAAsC;gBACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;gBACxC,IAAI,QAAQ,EAAE,CAAC;oBACX,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;oBACpC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;wBACjC,SAAS,CAAC,IAAI,CAAC;4BACX,GAAG,EAAE,UAAU;4BACf,IAAI,EAAE,UAAU,IAAI,SAAS;4BAC7B,IAAI;yBACP,CAAC,CAAC;oBACP,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QAED,cAAc;QACd,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;QAC9C,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAEzE,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACf,0DAA0D;QAC1D,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACtC,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;QAC5C,OAAO,EAAE,CAAC;IACjB,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW;IAC5C,MAAM,KAAK,CAAC,GAAG,EAAE,EAAC,KAAK,EAAE,IAAI,EAAC,CAAC,CAAC;AACjC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "byeport",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "dist/cli.js",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": "dist/cli.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"start": "node dist/cli.js",
|
|
14
|
+
"test": "xo && ava",
|
|
15
|
+
"prepublishOnly": "npm run build"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"cli",
|
|
19
|
+
"port",
|
|
20
|
+
"kill",
|
|
21
|
+
"process",
|
|
22
|
+
"terminal",
|
|
23
|
+
"tui",
|
|
24
|
+
"ink"
|
|
25
|
+
],
|
|
26
|
+
"author": "Raj Tiwari",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"description": "A beautiful, interactive CLI to identify and kill running processes on your ports.",
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^25.1.0",
|
|
31
|
+
"@types/react": "^19.2.10",
|
|
32
|
+
"eslint": "^9.39.2",
|
|
33
|
+
"ink-testing-library": "^4.0.0",
|
|
34
|
+
"ts-node": "^10.9.2",
|
|
35
|
+
"typescript": "^5.9.3",
|
|
36
|
+
"xo": "^1.2.3"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"fkill": "^10.0.3",
|
|
40
|
+
"ink": "^6.6.0",
|
|
41
|
+
"ink-big-text": "^2.0.0",
|
|
42
|
+
"ink-gradient": "^3.0.0",
|
|
43
|
+
"meow": "^14.0.0",
|
|
44
|
+
"react": "^19.2.4"
|
|
45
|
+
}
|
|
46
|
+
}
|