npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-port-guard

v0.1.0

Published

Triage port conflicts: reuse your own live server, switch ports for others, precisely kill zombies

Readme

dsh-port-guard

DeepSeek Harness 插件 · 端口占用处置 / DSH plugin for triaging port conflicts

dev server 启动报 EADDRINUSE: address already in use——最常见的前置障碍。但不是所有 EADDRINUSE 都该 kill

The classic blocker before any dev server starts. But not every EADDRINUSE should be killed.

核心洞察:EADDRINUSE 有三条路,不是只有"杀"

| 情况 | 占端口的是谁 | 正确动作 | |---|---|---| | A. 自己的、还在正常服务的 dev server | 上次会话遗留的同项目 dev server | 复用,比重启快 | | B. 别人的项目 / 不该杀的进程 | 另一个项目 / 系统服务 | 换端口绕开,不抢杀 | | C. 确认是僵尸/残留进程 | 已死但端口没释放 / 重复拉起的 | 精确 PID kill |

先判断属于哪种,再决定动作。不无脑 kill。

定位 + 取证 Identify & investigate

./scripts/port-guard.sh 8080

脚本会打印占用进程的完整身份信息:

# 定位
lsof -nP -iTCP:8080 -sTCP:LISTEN
# 身份:启动时刻/运行时长/有无控制终端
ps -o pid,ppid,lstart,etime,tty,%cpu,rss,command -p "$PID"
# 工作目录 → 属于哪个项目
lsof -a -p "$PID" -d cwd -Fn | grep '^n' | sed 's/^n//'
# 子进程(有子进程的别直接杀父,先看树)
pgrep -P "$PID"

判读组合

| 观察 | 含义 | |---|---| | PPID=1 | 父进程已退出,被 launchd 收养 —— 孤儿 | | tty=?? | 没有控制终端,不是人在终端里跑的 | | fd0 → /dev/nullfd1/fd2 → 某个 .log | nohup cmd > log 2>&1 & 指纹 → agent/脚本起的 | | tty=ttys00X | 人在终端窗口起的,杀之前更该问一声 | | etime 好几天 + %cpu 0.0 + rss 极小 | 挂了很久的僵尸 watcher(可能 watch 源码目录,某天突然醒来写产物) |

三种处置 Three paths

# A. 复用:确认进程还活着(kill -0 只检测不杀)
kill -0 "$PID" && echo alive

# B. 换端口绕开,不杀别人的
PORT=18080 node index.js

# C. 精确 kill(先 SIGTERM 给优雅退出机会,不行再 SIGKILL)
./scripts/port-guard.sh 8080 --kill

安全红线 Safety rules

  1. 先判断该不该杀——EADDRINUSE 不等于该杀(复用 > 重启)。
  2. 绝不 killall node / pkill -f node——精确 PID,不误伤其他正常服务。
  3. PID < 100 绝不杀——系统进程。
  4. 别人的进程不杀——换端口绕开。
  5. 命令行看不懂 / 不确定是什么——停下报告用户,不擅自杀。

安装 Install

# 发布到 npm 后
dsh plugin --profile demo add dsh-port-guard

# 或从 GitHub 安装
dsh plugin --profile demo add github:PangYiMing/dsh-port-guard

许可证 License

MIT