ptnix-cli 0.5.6

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PTNIX Abhishek Verma
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,735 @@
1
+ <p align="center">
2
+ <p align="center">
3
+ <img width="220" height="220" alt="Ptnix" src="https://cdn.jsdelivr.net/gh/abhishekayu/ptnix@main/assets/logo.png" />
4
+ </p>
5
+ <h1 align="center">Ptnix</h1>
6
+ <p align="center"><strong>Stop guessing what's running on your machine.</strong></p>
7
+ <p align="center">ptnix is a fast, cross-platform CLI to inspect ports, understand processes, and recover broken dev environments - built for real-world development workflows.</p>
8
+ <p align="center">
9
+ <a href="https://crates.io/crates/ptnix-cli"><img src="https://img.shields.io/crates/v/ptnix-cli.svg" alt="crates.io"></a>
10
+ <a href="https://www.npmjs.com/package/ptnix-cli"><img src="https://img.shields.io/npm/v/ptnix-cli.svg" alt="npm"></a>
11
+ <a href="https://github.com/abhishekayu/ptnix/releases"><img src="https://img.shields.io/github/v/release/abhishekayu/ptnix" alt="release"></a>
12
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="license"></a>
13
+ <a href="https://marketplace.visualstudio.com/items?itemName=abhishekayu.ptnix"><img src="https://img.shields.io/visual-studio-marketplace/v/abhishekayu.ptnix?label=VS%20Code" alt="VS Code Marketplace"></a>
14
+ </p>
15
+ </p>
16
+
17
+ <br>
18
+
19
+ ```
20
+ $ ptnix fix 3000
21
+
22
+ ⚡ Port 3000 in use
23
+ → Next.js (PID 81106) running for 7m 21s
24
+ → 🛡 safe to kill
25
+
26
+ • Sending SIGTERM to PID 81106
27
+ • Verified: PID 81106 has exited
28
+
29
+ ✔ Port 3000 is now free
30
+ Restart: npm run dev
31
+ ```
32
+
33
+ <p align="center">
34
+ <b>Detects the process. Checks if it's safe. Kills it gracefully. Tells you how to restart.</b><br>
35
+ Try it now: <code>npx ptnix scan</code>
36
+ </p>
37
+
38
+ ---
39
+
40
+ ## The Problem Every Developer Hits
41
+
42
+ You've seen this before:
43
+
44
+ ```
45
+ Error: listen EADDRINUSE: address already in use :::3000
46
+ ```
47
+
48
+ A crashed dev server. A zombie process. Something unknown squatting on your port.
49
+
50
+ So you do the ritual:
51
+
52
+ ```bash
53
+ lsof -i :3000 # wall of text
54
+ kill -9 <pid> # hope it's not PostgreSQL
55
+ # ...was that important?
56
+ # how do I restart this thing?
57
+ ```
58
+
59
+ This is fragile. It's blind. It tells you nothing about what you just killed.
60
+
61
+ **ptnix replaces this entire workflow with one command.** A single CLI tool for port conflict resolution, process inspection, and dev server recovery.
62
+
63
+ ---
64
+
65
+ ## Instant Port Inspection
66
+
67
+ ```
68
+ $ ptnix 3000
69
+
70
+ ⚡ Port 3000 in use
71
+ → Next.js (PID 81106)
72
+ → running for 7m 21s
73
+ → memory 42.9 MB
74
+ → detected Next.js (95% confidence)
75
+ → 🛡 safe to kill
76
+
77
+ 📂 Detected project: Next.js
78
+ → dev command: npm run dev
79
+ → default port: 3000
80
+ ```
81
+
82
+ ptnix tells you **what** is running, **whether it's safe** to kill, and **how to restart** it.
83
+
84
+ ---
85
+
86
+ ## Port Debugging: Before vs After
87
+
88
+ | Task | Before | After |
89
+ | -------------------------- | ------------------------------------------- | -------------------------- |
90
+ | Port 3000 stuck | `lsof -i :3000 \| awk ... \| xargs kill -9` | `ptnix fix 3000` |
91
+ | "What's on my ports?" | `lsof -iTCP -sTCP:LISTEN` (unreadable) | `ptnix scan` |
92
+ | "Is this safe to kill?" | Google the process name | ptnix tells you |
93
+ | "How do I restart?" | Dig through package.json | ptnix shows the command |
94
+ | Zombie processes | Hunt them one by one | `ptnix doctor -y` |
95
+ | Which port is my frontend? | Check config files | `ptnix group` |
96
+ | Start entire dev stack | Open 5 terminals, run commands manually | `ptnix up` |
97
+ | Stop everything | Find and kill each process | `ptnix down` |
98
+ | "Is my port free?" | `lsof -i :3000` and parse output | `ptnix preflight 3000` |
99
+ | Monitor a flaky server | Watch logs + manual restart | `ptnix watch 3000` |
100
+ | Duplicate port assignments | Manually diff config files | `ptnix registry check` |
101
+ | Run all checks in CI | Write custom scripts | `ptnix ci` |
102
+ | Switch dev/staging config | Edit .env files manually | `ptnix use staging` |
103
+ | Restart a crashed service | Find port, kill, cd, re-run command | `ptnix restart frontend` |
104
+ | "Are my services running?" | Check each port manually | `ptnix status` |
105
+ | Stream logs from a port | Figure out which container or log file | `ptnix log 3000` |
106
+
107
+ ---
108
+
109
+ ## Install
110
+
111
+ > **Native binary. No Node. No runtime dependencies.** ~1.2MB, runs instantly.
112
+
113
+ ### One-line install (recommended)
114
+
115
+ ```bash
116
+ curl -fsSL https://raw.githubusercontent.com/abhishekayu/ptnix/main/install.sh | sh
117
+ ```
118
+
119
+ ### Package managers
120
+
121
+ | Platform | Command |
122
+ | ------------------- | ------------------------------------------------------------------------------------------------ |
123
+ | **Homebrew** | `brew install abhishekayu/tap/ptnix` |
124
+ | **Cargo** | `cargo install ptnix-cli` |
125
+ | **npm** | `npm install -g ptnix-cli` |
126
+ | **Scoop** (Windows) | `scoop bucket add ptnix https://github.com/abhishekayu/scoop-ptnix && scoop install ptnix` |
127
+ | **Debian/Ubuntu** | Download `.deb` from [releases](https://github.com/abhishekayu/ptnix/releases) |
128
+
129
+ ### Try instantly (no install)
130
+
131
+ ```bash
132
+ npx ptnix scan
133
+ ```
134
+
135
+ ### Build from source
136
+
137
+ ```bash
138
+ git clone https://github.com/abhishekayu/ptnix.git
139
+ cd ptnix
140
+ cargo install --path .
141
+ ```
142
+
143
+ > **Supports** macOS (Intel + Apple Silicon), Linux (x86_64 + ARM64), and Windows.
144
+
145
+ ---
146
+
147
+ ## Usage Examples
148
+
149
+ ### Scan all listening ports
150
+
151
+ ```
152
+ $ ptnix scan
153
+
154
+ ⚡ 5 active ports
155
+
156
+ PORT PROCESS PID SERVICE MEMORY UPTIME USER
157
+ ────────────────────────────────────────────────────────────────────────────────
158
+ 3000 node 81106 Next.js 42.9 MB 7m 17s abhishek
159
+ 3898 Code Helper (Plugin) 34290 Python 20.2 MB 3h 12m abhishek
160
+ 5237 Code Helper (Plugin) 34073 Python 20.1 MB 3h 12m abhishek
161
+ 5932 Code Helper (Plugin) 61773 Python 57.5 MB 58m 35s abhishek
162
+ 42050 OneDrive Sync Serv.. 36643 Unknown 14.4 MB 3d 1h abhishek
163
+ ```
164
+
165
+ ### Fix port conflicts and auto-restart
166
+
167
+ ```
168
+ $ ptnix fix 3000 --run "npm run dev"
169
+
170
+ ✔ Killed safely port 3000 is now free
171
+ 🚀 Restarting: npm run dev
172
+ ```
173
+
174
+ One command. Port cleared, dev server restarted.
175
+
176
+ ### Diagnose dev environment issues
177
+
178
+ ```
179
+ $ ptnix doctor
180
+
181
+ 🩺 2 issues found
182
+
183
+ 1. Idle process Code Helper (PID 34290) at 0.0% CPU [auto-fixable]
184
+ → Idle Code Helper on port 3898 -- consider killing to free resources
185
+ 2. Idle process Code Helper (PID 34073) at 0.0% CPU [auto-fixable]
186
+ → Idle Code Helper on port 5237 -- consider killing to free resources
187
+
188
+ ⚙ Run ptnix doctor -y to auto-fix 2 issues
189
+ ```
190
+
191
+ ### Group ports by service role
192
+
193
+ ```
194
+ $ ptnix group --dev
195
+
196
+ ⚡ 4 active ports in 2 groups
197
+
198
+ ⚙ Frontend (2)
199
+ ────────────────────────────────────────────────────────────────────────────
200
+ 3000 node 81106 Next.js 42.9 MB 7m 21s abhishek
201
+ 3898 Code Helper (Plugin) 34290 Python 20.2 MB 3h 12m abhishek
202
+
203
+ ⚙ Backend (2)
204
+ ────────────────────────────────────────────────────────────────────────────
205
+ 5237 Code Helper (Plugin) 34073 Python 20.0 MB 3h 12m abhishek
206
+ 5932 Code Helper (Plugin) 61773 Python 57.5 MB 58m 39s abhishek
207
+ ```
208
+
209
+ ### Interactive terminal UI
210
+
211
+ ```
212
+ $ ptnix ui
213
+ ```
214
+
215
+ Arrow keys to navigate, enter to inspect, `f` to fix. Full interactive TUI for port management, powered by ratatui.
216
+
217
+ ### Define your dev stack with `.ptnix.toml`
218
+
219
+ ```bash
220
+ $ ptnix init
221
+
222
+ ✔ Created .ptnix.toml
223
+ → Detected Next.js project (port 3050)
224
+ → Port 3050 found in package.json scripts
225
+ ```
226
+
227
+ ptnix reads your `package.json` scripts and detects hardcoded ports (`--port 3050`, `-p 8080`, etc.). In a monorepo, it scans subdirectories and generates a multi-service config automatically.
228
+
229
+ Edit the generated config to declare your services:
230
+
231
+ ```toml
232
+ [project]
233
+ name = "my-app"
234
+
235
+ [services.frontend]
236
+ port = 3000
237
+ run = "npm run dev"
238
+ cwd = "./frontend"
239
+ preflight = true
240
+
241
+ [services.api]
242
+ port = 8080
243
+ run = "cargo run"
244
+ cwd = "./backend"
245
+ preflight = true
246
+
247
+ [services.worker]
248
+ port = 9090
249
+ run = "python worker.py"
250
+ env = { PYTHON_ENV = "development" }
251
+
252
+ [profiles.staging]
253
+ frontend = { port = 3100 }
254
+ api = { port = 8180, env = { RUST_LOG = "info" } }
255
+ ```
256
+
257
+ ### Start your entire dev stack
258
+
259
+ ```
260
+ $ ptnix up
261
+
262
+ 🚀 Starting 3 services...
263
+
264
+ ✔ api started on port 8080
265
+ ✔ frontend started on port 3050
266
+ ✔ worker started on port 9090
267
+
268
+ ✔ 3/3 services started.
269
+ ```
270
+
271
+ Pre-flight checks run automatically. If a port is busy, ptnix tells you. Add `-y` to auto-fix conflicts before starting.
272
+
273
+ ptnix tracks spawned PIDs in `.ptnix.pids`. If a framework binds a different port than configured (e.g., Next.js auto-increments when a port is taken), ptnix detects the actual port and reports it:
274
+
275
+ ```
276
+ ✔ frontend started on port 3001 (configured: 3000)
277
+ ⚠ port 3000 was busy, update .ptnix.toml to match
278
+ ```
279
+
280
+ ### Stop everything
281
+
282
+ ```
283
+ $ ptnix down
284
+
285
+ 🛑 Stopping 3 services...
286
+
287
+ ✔ api stopped (port 8080)
288
+ ✔ frontend stopped (port 3050)
289
+ ✔ worker stopped (port 9090)
290
+
291
+ ✔ 3/3 services stopped.
292
+ ```
293
+
294
+ `down` uses a 3-tier strategy to find and stop processes: checks the declared port, then the actual port from `.ptnix.pids` (if the process moved), then kills by saved PID directly.
295
+
296
+ ### Pre-flight port check
297
+
298
+ ```
299
+ $ ptnix preflight 3000 8080 5432
300
+
301
+ 🔍 Pre-flight check for 3 ports...
302
+
303
+ ✔ Port 3000 is free
304
+ ✔ Port 8080 is free
305
+ ✘ Port 5432 is busy -- postgres (PID 1234, PostgreSQL)
306
+
307
+ ⚠ 1 port is already in use. Run ptnix fix <port> to fix.
308
+ ```
309
+
310
+ Run without arguments to check all ports from `.ptnix.toml`.
311
+
312
+ ### Watch a port and auto-restart on crash
313
+
314
+ ```
315
+ $ ptnix watch 3000
316
+
317
+ 👀 Watching port 3000 (every 2s, Ctrl-C to stop)
318
+
319
+ ✔ Port 3000 is up -- Next.js (PID 81106)
320
+ ✘ Port 3000 went down -- Unknown crash reason (was PID 81106)
321
+ 🚀 Auto-restarting: npm run dev
322
+ ✔ Port 3000 recovered (PID 82001, Next.js) -- downtime: 3s
323
+ ```
324
+
325
+ If a `.ptnix.toml` defines a `run` command for the watched port, ptnix auto-restarts it when it crashes.
326
+
327
+ ### Validate port assignments
328
+
329
+ ```
330
+ $ ptnix registry check
331
+
332
+ 🔍 Checking port registry...
333
+
334
+ ✔ No port conflicts found across 3 services.
335
+ ```
336
+
337
+ Detects duplicate ports across services and profile overrides in `.ptnix.toml`.
338
+
339
+ ### Run all checks in CI
340
+
341
+ ```
342
+ $ ptnix ci
343
+
344
+ ▶ Step 1/4: Validate config... ✔
345
+ ▶ Step 2/4: Registry check... ✔
346
+ ▶ Step 3/4: Pre-flight check... ✔
347
+ ▶ Step 4/4: Doctor... ✔
348
+
349
+ ✔ All checks passed.
350
+ ```
351
+
352
+ Non-interactive runner for CI/CD pipelines. Runs config validation, registry check, preflight, and doctor in sequence. Exits 1 on failure. Supports `--json`.
353
+
354
+ ### Switch profiles
355
+
356
+ ```
357
+ $ ptnix use staging
358
+
359
+ ✔ Switched to profile: staging
360
+ → frontend port: 3100
361
+ → api port: 8180
362
+ ```
363
+
364
+ Switch between named profiles defined in `.ptnix.toml`. The active profile is persisted to `.ptnix.state` and applied automatically to `up`, `down`, `watch`, and `preflight`.
365
+
366
+ ### Restart a single service
367
+
368
+ ```
369
+ $ ptnix restart frontend
370
+
371
+ 🔄 Restarting frontend (port 3000)...
372
+ ✔ Stopped process on port 3000 (PID 81106)
373
+ ✔ Started frontend on port 3000
374
+ ```
375
+
376
+ Restarts a named service from `.ptnix.toml`. Stops whatever is on the port (local process or Docker container), then re-runs the configured `run` command. Respects the active profile.
377
+
378
+ ### Check service status
379
+
380
+ ```
381
+ $ ptnix status
382
+
383
+ 📊 test-app status
384
+
385
+ SERVICE PORT STATUS PROCESS PID
386
+ ──────────────────────────────────────────────────────
387
+ frontend 3000 🟢 Running node 81106
388
+ api 8080 🔴 Stopped
389
+ worker 9090 🟡 Conflict python3 92001
390
+ ```
391
+
392
+ Shows the live status of every service in `.ptnix.toml`. Compares the actual process on each port against the expected service to flag conflicts. Supports `--json`.
393
+
394
+ ### Stream logs from a port
395
+
396
+ ```
397
+ $ ptnix log 3000
398
+ ```
399
+
400
+ Streams live logs from the process on a port. Works with Docker containers (`docker logs -f`) and local processes (detects log files via `lsof`). If the process writes to a TTY, suggests how to redirect output to a file.
401
+
402
+ ---
403
+
404
+ ## CLI Commands Reference
405
+
406
+ | Command | Description | Example |
407
+ | --------------------------- | ----------------------------------------------------- | -------------------------------------- |
408
+ | `ptnix scan` | List all listening ports with service, memory, uptime | `ptnix scan` |
409
+ | `ptnix <port>` | Inspect a single port in detail | `ptnix 3000` |
410
+ | `ptnix fix <ports>` | Safely kill the process on one or more ports | `ptnix fix 3000 8080` |
411
+ | `ptnix fix <ports> --run` | Kill and auto-restart a dev server | `ptnix fix 3000 --run "npm run dev"` |
412
+ | `ptnix fix <ports> -y` | Skip confirmation prompt | `ptnix fix 3000 8080 -y` |
413
+ | `ptnix kill <ports>` | Direct kill with safety confirmation | `ptnix kill 3000 8080` |
414
+ | `ptnix group` | Ports organized by role (frontend/backend/db/infra) | `ptnix group --dev` |
415
+ | `ptnix doctor` | Find stale servers, idle processes, conflicts | `ptnix doctor` |
416
+ | `ptnix doctor -y` | Auto-fix all safe issues | `ptnix doctor -y` |
417
+ | `ptnix history` | View past actions with timestamps | `ptnix history` |
418
+ | `ptnix history --stats` | Kill stats: success rate, top ports, top processes | `ptnix history --stats` |
419
+ | `ptnix project` | Detect project type, suggest dev commands | `ptnix project` |
420
+ | `ptnix ui` | Interactive TUI with keyboard navigation | `ptnix ui` |
421
+ | `ptnix init` | Create a `.ptnix.toml` (auto-detects ports) | `ptnix init` |
422
+ | `ptnix up` | Start all services from `.ptnix.toml` | `ptnix up` |
423
+ | `ptnix up -y` | Start services, auto-fix port conflicts first | `ptnix up -y` |
424
+ | `ptnix down` | Stop all services from `.ptnix.toml` | `ptnix down` |
425
+ | `ptnix preflight` | Check if ports are free before starting | `ptnix preflight 3000 8080` |
426
+ | `ptnix watch <port>` | Monitor a port, alert on crash, auto-restart | `ptnix watch 3000` |
427
+ | `ptnix registry check` | Validate port assignments for conflicts | `ptnix registry check` |
428
+ | `ptnix ci` | Run all checks non-interactively (CI/CD mode) | `ptnix ci --json` |
429
+ | `ptnix use <profile>` | Switch to a named profile from `.ptnix.toml` | `ptnix use staging` |
430
+ | `ptnix restart <service>` | Restart a named service from `.ptnix.toml` | `ptnix restart frontend` |
431
+ | `ptnix status` | Show live status of all services from config | `ptnix status` |
432
+ | `ptnix log <port>` | Stream live logs from a port (Docker or local) | `ptnix log 3000` |
433
+
434
+ > All commands support `--json` for scripting and CI pipelines.
435
+
436
+ ---
437
+
438
+ ## Why ptnix Over kill-port, fkill, or lsof
439
+
440
+ **It's not `kill -9` with extra steps.**
441
+
442
+ ptnix is a process classification engine built for developer productivity:
443
+
444
+ - **Identifies services** -- Next.js, Vite, Django, Flask, Express, PostgreSQL, Redis, Docker, and 13+ categories with confidence scores
445
+ - **Safety system** -- blocks system-critical processes (PID 1, sshd, launchd), warns about databases (data loss risk), approves dev servers
446
+ - **Graceful shutdown** -- SIGTERM first, waits for clean exit, escalates to SIGKILL only if needed
447
+ - **Project-aware** -- reads package.json, Cargo.toml, pyproject.toml to suggest the right restart command
448
+ - **Docker-aware** -- detects container ports vs host ports
449
+ - **History** -- every action logged to `~/.ptnix/history.json` with timestamps and outcomes
450
+
451
+ ### How ptnix works under the hood
452
+
453
+ 1. **Scan** -- queries the OS for all listening ports, resolves PIDs via sysinfo
454
+ 2. **Classify** -- identifies the service type (Next.js, PostgreSQL, Docker, etc.)
455
+ 3. **Assess** -- safety check: SAFE / WARN / BLOCK
456
+ 4. **Strategy** -- picks the right approach: Graceful, Escalating, or Force
457
+ 5. **Execute** -- sends signals, waits for exit, verifies the port is free
458
+ 6. **Recover** -- detects the project, suggests restart, or auto-restarts with `--run`
459
+
460
+ ### Safety tiers
461
+
462
+ | Verdict | Examples | Behavior |
463
+ | ----------- | ----------------------------------------------------------- | ----------------------------------------------- |
464
+ | **BLOCKED** | PID 0/1, launchd, systemd, sshd, kernel_task | Refuses to kill |
465
+ | **WARNING** | PostgreSQL, MySQL, Redis, Docker, Nginx | Warns about consequences, asks for confirmation |
466
+ | **SAFE** | Next.js, Vite, Create React App, Django dev, Flask, Node.js | Kills gracefully |
467
+
468
+ ---
469
+
470
+ ## Developer Productivity Workflows
471
+
472
+ ### "Port 3000 is already in use" after a crash
473
+
474
+ Your Next.js server crashed. The port is stuck. You just want to get back to coding.
475
+
476
+ ```bash
477
+ ptnix fix 3000 -y --run "npm run dev"
478
+ ```
479
+
480
+ Port cleared, server restarted. One line.
481
+
482
+ ### Make `npm run dev` crash-proof
483
+
484
+ Add ptnix to your scripts so port conflicts resolve themselves:
485
+
486
+ ```json
487
+ {
488
+ "scripts": {
489
+ "dev": "ptnix fix 3000 -y --run 'next dev'",
490
+ "dev:api": "ptnix fix 8080 -y --run 'node server.js'",
491
+ "dev:clean": "ptnix doctor -y && npm run dev"
492
+ }
493
+ }
494
+ ```
495
+
496
+ Now `npm run dev` works every time, even if something is already on port 3000.
497
+
498
+ ### Morning dev environment reset
499
+
500
+ You open your laptop. Stale servers from yesterday are hogging ports and memory.
501
+
502
+ ```bash
503
+ ptnix doctor -y
504
+ ```
505
+
506
+ Finds zombie processes, idle servers, and cleans them up automatically.
507
+
508
+ ### "What is using port 8080?"
509
+
510
+ Something is squatting on your API port but you have no idea what.
511
+
512
+ ```bash
513
+ ptnix 8080
514
+ ```
515
+
516
+ Shows the process name, PID, service type, memory, uptime, project directory, and whether it's safe to kill.
517
+
518
+ ### Full-stack dev with `.ptnix.toml`
519
+
520
+ Frontend on 3000, API on 8080, worker on 9090. Define them once, manage them forever:
521
+
522
+ ```bash
523
+ # Initialize config
524
+ ptnix init
525
+
526
+ # Start everything (runs preflight checks automatically)
527
+ ptnix up
528
+
529
+ # Stop everything at end of day
530
+ ptnix down
531
+ ```
532
+
533
+ No more opening 5 terminals and running commands manually.
534
+
535
+ ### Monitor a flaky dev server
536
+
537
+ Your dev server keeps crashing. Let ptnix watch it and auto-restart:
538
+
539
+ ```bash
540
+ ptnix watch 3000
541
+ ```
542
+
543
+ If a `.ptnix.toml` defines a `run` command for port 3000, ptnix auto-restarts it when it goes down.
544
+
545
+ ### Pre-flight check before deployment scripts
546
+
547
+ ```bash
548
+ # Check all ports from .ptnix.toml are free
549
+ ptnix preflight
550
+
551
+ # Check specific ports
552
+ ptnix preflight 3000 8080 5432
553
+ ```
554
+
555
+ ### Shell aliases for daily use
556
+
557
+ ```bash
558
+ # ~/.zshrc or ~/.bashrc
559
+ alias pf='ptnix fix'
560
+ alias pfs='ptnix scan'
561
+ alias pfd='ptnix doctor -y'
562
+ alias pu='ptnix up'
563
+ alias pd='ptnix down'
564
+ alias dev3='ptnix fix 3000 -y --run "npm run dev"'
565
+ alias dev8='ptnix fix 8080 -y --run "node server.js"'
566
+ ```
567
+
568
+ ### Fix multiple ports at once
569
+
570
+ Clearing out a full dev environment before starting fresh:
571
+
572
+ ```bash
573
+ # Fix multiple ports in one command
574
+ ptnix fix 3000 8080 5173 -y
575
+
576
+ # Or with .ptnix.toml
577
+ ptnix down && ptnix up
578
+ ```
579
+
580
+ ### CI / pre-commit: ensure clean ports
581
+
582
+ ```bash
583
+ # Run all checks in one command (exits 1 on failure)
584
+ ptnix ci
585
+
586
+ # Or with JSON output for CI parsing
587
+ ptnix ci --json
588
+ ```
589
+
590
+ ### Validate port assignments before deploying
591
+
592
+ ```bash
593
+ # Check for duplicate ports across services and profiles
594
+ ptnix registry check
595
+ ```
596
+
597
+ ### Switch between dev and staging
598
+
599
+ ```bash
600
+ # Define profiles in .ptnix.toml, then switch:
601
+ ptnix use staging
602
+ ptnix up
603
+
604
+ # Switch back to default
605
+ ptnix use default
606
+ ptnix up
607
+ ```
608
+
609
+ ### Pipe to scripts with JSON output
610
+
611
+ ```bash
612
+ # Get all listening ports as JSON
613
+ ptnix scan --json | jq '.[] | select(.service == "Next.js")'
614
+
615
+ # Count active dev servers
616
+ ptnix scan --json | jq '[.[] | select(.service != "Unknown")] | length'
617
+ ```
618
+
619
+ ---
620
+
621
+ ## Comparison: ptnix vs kill-port vs fkill
622
+
623
+ | | kill-port | fkill | **ptnix** |
624
+ | ---------------------- | --------- | --------- | ----------------------------------- |
625
+ | Service identification | No | Name only | Full (service, memory, uptime, CWD) |
626
+ | Safety checks | No | No | Yes (safe / warn / block) |
627
+ | Graceful shutdown | No | No | Yes (SIGTERM, then escalate) |
628
+ | Restart hints | No | No | Yes (project-aware) |
629
+ | Auto-restart | No | No | Yes (`--run`) |
630
+ | Docker awareness | No | No | Yes |
631
+ | Auto-diagnosis | No | No | Yes (`doctor`) |
632
+ | Port grouping | No | No | Yes (by role) |
633
+ | Action history | No | No | Yes |
634
+ | Interactive TUI | No | Yes | Yes |
635
+ | Project config file | No | No | Yes (`.ptnix.toml`) |
636
+ | Dev stack up/down | No | No | Yes (`up` / `down`) |
637
+ | Service restart | No | No | Yes (`restart <service>`) |
638
+ | Service status | No | No | Yes (`status`) |
639
+ | Log streaming | No | No | Yes (`log <port>`) |
640
+ | Port monitoring | No | No | Yes (`watch`) |
641
+ | Pre-flight checks | No | No | Yes (`preflight`) |
642
+ | Crash detection | No | No | Yes (signal, OOM, zombie) |
643
+ | Port registry | No | No | Yes (conflict detection) |
644
+ | CI/CD mode | No | No | Yes (`ci` command) |
645
+ | Profiles | No | No | Yes (`use` for dev/staging/prod) |
646
+ | Platform | Node.js | Node.js | Native binary |
647
+ | Size | ~50MB | ~50MB | ~1.2MB |
648
+
649
+ ---
650
+
651
+ ## Architecture & Performance
652
+
653
+ ```
654
+ src/
655
+ scanner/ Batch port scanning with sysinfo process resolution
656
+ classifier/ 13+ service classifiers with confidence scoring
657
+ engine/ Safety checks, strategy selection, graceful kill with retry
658
+ platform/ macOS (lsof + libc) / Linux (/proc/net/tcp) / Windows (netstat)
659
+ project/ Filesystem project detection (package.json, Cargo.toml, etc.)
660
+ docker/ Container awareness via docker ps
661
+ grouping/ Port role classification (frontend/backend/database/infra)
662
+ doctor/ Stale servers, idle processes, crowded ports
663
+ history/ Action log persisted to ~/.ptnix/history.json
664
+ config/ .ptnix.toml project config loader (monorepo, port detection)
665
+ watch/ Continuous port monitoring with crash detection
666
+ stack/ Dev stack orchestration (up/down with PID tracking)
667
+ preflight/ Pre-flight port availability checks
668
+ crash/ Crash reason detection (signal, OOM, zombie)
669
+ restart/ Single-service restart (stop + start from config)
670
+ status/ Live service status dashboard (running/stopped/conflict)
671
+ log/ Log streaming for Docker containers and local processes
672
+ registry/ Port conflict detection across services and profiles
673
+ ci/ Non-interactive CI/CD runner (config + registry + preflight + doctor)
674
+ plugin/ Extensible ServiceDetector trait for custom detectors
675
+ cli/ Clap v4 + colored output + ratatui TUI
676
+ ```
677
+
678
+ Built in Rust for speed and reliability. Ships as a single ~1.2MB static binary with zero runtime dependencies. No Node.js, no Python -- just a fast native CLI tool for managing ports and debugging dev environments.
679
+
680
+ ---
681
+
682
+ ## Contributing
683
+
684
+ ```bash
685
+ git clone https://github.com/abhishekayu/ptnix.git
686
+ cd ptnix
687
+ cargo build
688
+ cargo test
689
+ ```
690
+
691
+ - Report bugs or request features via [Issues](https://github.com/abhishekayu/ptnix/issues)
692
+ - Add new service classifiers
693
+ - Improve platform support
694
+ - Write new doctor diagnostics
695
+
696
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
697
+
698
+ ---
699
+
700
+ ## VS Code Extension
701
+
702
+ Manage ports and services directly from the VS Code sidebar -- no terminal needed.
703
+
704
+ [![Install from VS Code Marketplace](https://img.shields.io/badge/VS%20Code-Install%20Extension-007ACC?logo=visual-studio-code)](https://marketplace.visualstudio.com/items?itemName=abhishekayu.ptnix)
705
+
706
+ **Features:**
707
+
708
+ - Sidebar dashboard showing all listening ports with process info
709
+ - Project-aware service management (reads `.ptnix.toml`)
710
+ - One-click Start All, Stop All, Fix, Doctor, Preflight, and 15+ actions
711
+ - Switch between dev/staging/production profiles
712
+ - Auto-install and update the ptnix CLI binary
713
+
714
+ ```bash
715
+ code --install-extension abhishekayu.ptnix
716
+ ```
717
+
718
+ [View on Marketplace](https://marketplace.visualstudio.com/items?itemName=abhishekayu.ptnix)
719
+
720
+ ---
721
+
722
+ ## License
723
+
724
+ [MIT](LICENSE) -- free for personal and commercial use.
725
+
726
+ ---
727
+
728
+ <p align="center">
729
+ <strong>ptnix</strong> -- an open-source CLI tool for port management, process debugging, and developer environment recovery.<br>
730
+ Built for developers who are tired of <code>lsof</code> + <code>kill -9</code>.<br>
731
+ Define your dev stack in <code>.ptnix.toml</code>, start with <code>ptnix up</code>, stop with <code>ptnix down</code>.<br>
732
+ Restart a service with <code>ptnix restart frontend</code>, check status with <code>ptnix status</code>.<br>
733
+ Switch profiles with <code>ptnix use staging</code>, validate with <code>ptnix ci</code>.<br>
734
+ Works with Next.js, Vite, Django, Flask, Express, Docker, PostgreSQL, Redis, and more.
735
+ </p>
package/bin/ptnix.js ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+
3
+ "use strict";
4
+
5
+ const { execFileSync } = require("child_process");
6
+ const path = require("path");
7
+ const fs = require("fs");
8
+
9
+ const binDir = path.join(__dirname);
10
+
11
+ function getBinaryPath() {
12
+ const platform = process.platform;
13
+ const arch = process.arch;
14
+
15
+ let binaryName = "ptnix";
16
+ if (platform === "win32") {
17
+ binaryName = "ptnix.exe";
18
+ }
19
+
20
+ const binaryPath = path.join(binDir, binaryName);
21
+ if (fs.existsSync(binaryPath)) {
22
+ return binaryPath;
23
+ }
24
+
25
+ console.error(
26
+ `ptnix binary not found for ${platform}-${arch}.`,
27
+ `\nRun 'npm rebuild ptnix-cli' or install via: curl -fsSL https://raw.githubusercontent.com/abhishekayu/ptnix/main/install.sh | sh`,
28
+ );
29
+ process.exit(1);
30
+ }
31
+
32
+ const binary = getBinaryPath();
33
+ const args = process.argv.slice(2);
34
+
35
+ try {
36
+ const result = execFileSync(binary, args, {
37
+ stdio: "inherit",
38
+ env: process.env,
39
+ });
40
+ } catch (err) {
41
+ if (err.status !== undefined) {
42
+ process.exit(err.status);
43
+ }
44
+ process.exit(1);
45
+ }
package/install.js ADDED
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+
3
+ const https = require("https");
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ const { execSync } = require("child_process");
7
+ const os = require("os");
8
+
9
+ const VERSION = require("./package.json").version;
10
+ const REPO = "abhishekayu/ptnix";
11
+
12
+ function getPlatformInfo() {
13
+ const platform = process.platform;
14
+ const arch = process.arch;
15
+
16
+ const platformMap = {
17
+ "darwin-x64": "ptnix-darwin-x86_64",
18
+ "darwin-arm64": "ptnix-darwin-aarch64",
19
+ "linux-x64": "ptnix-linux-x86_64",
20
+ "linux-arm64": "ptnix-linux-aarch64",
21
+ "win32-x64": "ptnix-windows-x86_64",
22
+ };
23
+
24
+ const key = `${platform}-${arch}`;
25
+ const name = platformMap[key];
26
+
27
+ if (!name) {
28
+ console.error(`Unsupported platform: ${key}`);
29
+ console.error("Install manually: cargo install ptnix-cli");
30
+ process.exit(0); // Don't fail npm install
31
+ }
32
+
33
+ const ext = platform === "win32" ? ".zip" : ".tar.gz";
34
+ return { name, ext, platform };
35
+ }
36
+
37
+ function download(url) {
38
+ return new Promise((resolve, reject) => {
39
+ https
40
+ .get(url, (res) => {
41
+ if (
42
+ res.statusCode >= 300 &&
43
+ res.statusCode < 400 &&
44
+ res.headers.location
45
+ ) {
46
+ return download(res.headers.location).then(resolve).catch(reject);
47
+ }
48
+ if (res.statusCode !== 200) {
49
+ return reject(new Error(`HTTP ${res.statusCode} for ${url}`));
50
+ }
51
+ const chunks = [];
52
+ res.on("data", (chunk) => chunks.push(chunk));
53
+ res.on("end", () => resolve(Buffer.concat(chunks)));
54
+ res.on("error", reject);
55
+ })
56
+ .on("error", reject);
57
+ });
58
+ }
59
+
60
+ async function install() {
61
+ const { name, ext, platform } = getPlatformInfo();
62
+ const url = `https://github.com/${REPO}/releases/download/v${VERSION}/${name}${ext}`;
63
+ const binDir = path.join(__dirname, "bin");
64
+
65
+ console.log(
66
+ `Downloading ptnix v${VERSION} for ${process.platform}-${process.arch}...`,
67
+ );
68
+
69
+ try {
70
+ const data = await download(url);
71
+ const tmpFile = path.join(os.tmpdir(), `${name}${ext}`);
72
+ fs.writeFileSync(tmpFile, data);
73
+
74
+ if (platform === "win32") {
75
+ // Use PowerShell to extract zip
76
+ execSync(
77
+ `powershell -Command "Expand-Archive -Force '${tmpFile}' '${binDir}'"`,
78
+ { stdio: "pipe" },
79
+ );
80
+ } else {
81
+ execSync(`tar xzf "${tmpFile}" -C "${binDir}"`, { stdio: "pipe" });
82
+ const binary = path.join(binDir, "ptnix");
83
+ fs.chmodSync(binary, 0o755);
84
+ }
85
+
86
+ fs.unlinkSync(tmpFile);
87
+ console.log("ptnix installed successfully.");
88
+ } catch (err) {
89
+ console.error(`Failed to download ptnix: ${err.message}`);
90
+ console.error("Install manually: cargo install ptnix-cli");
91
+ // Don't fail npm install
92
+ }
93
+ }
94
+
95
+ install();
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "ptnix-cli",
3
+ "version": "0.5.6",
4
+ "description": "ptnix — blazing fast port & process manager. Kill and list processes on ports from your terminal.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/abhishekayu/ptnix"
8
+ },
9
+ "license": "MIT",
10
+ "keywords": [
11
+ "port",
12
+ "kill-port",
13
+ "port-conflict",
14
+ "developer-tools",
15
+ "cli",
16
+ "devserver",
17
+ "process",
18
+ "debug",
19
+ "eaddrinuse",
20
+ "zombie-process",
21
+ "port-scanner",
22
+ "dev-environment",
23
+ "productivity"
24
+ ],
25
+ "bin": {
26
+ "ptnix": "bin/ptnix.js"
27
+ },
28
+ "files": [
29
+ "bin/",
30
+ "install.js",
31
+ "README.md",
32
+ "LICENSE"
33
+ ],
34
+ "scripts": {
35
+ "postinstall": "node install.js"
36
+ },
37
+ "os": [
38
+ "darwin",
39
+ "linux",
40
+ "win32"
41
+ ],
42
+ "cpu": [
43
+ "x64",
44
+ "arm64"
45
+ ],
46
+ "engines": {
47
+ "node": ">=16"
48
+ }
49
+ }