🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

端口看板 abalika/dsh-port-viewer

DeepSeek Harness
abalika10 天前有提交已提供中文文档扫描:含敏感能力

按项目分组查看本机端口占用并安全关闭

29.2/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/11/2 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add abalika/dsh-port-viewer
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么[目录]—
dsh 原生插件 · tool
暂无时间戳·判据 →
装得上吗[实装验证]—
本站尚未做安装检查
暂无时间戳·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 10 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 8 处,展示前 8 条)
  • 发起网络请求
    lib/client.js:1724
    return fetch(url, options).then(function (res) {
  • 写入剪贴板
    lib/client.js:2028
    return navigator.clipboard.writeText(text).then(function () { return true; }, function () {
  • 读取本地文件
    lib/collect.js:205
    text = await readFile(file, 'utf8');
  • 读取本地文件
    lib/collect.js:321
    if (!existsSync(scriptPath)) {
  • 删除本地文件递归
    lib/collect.js:343
    if (workDir) await rm(workDir, { recursive: true, force: true });
  • 删除本地文件
    lib/collect.js:344
    else await unlink(outFile);
  • 读取本地文件
    lib/collect.js:388
    text = await readFile(outFile, 'utf8');
  • 读取本地文件
    lib/projects.js:220
    return readdirSync(dir, { withFileTypes: true }).map((entry) => ({
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
dsh-port-viewer · 端口可视化 给 DeepSeek Harness(dsh) 桌面端加一个端口占用面板:右下角一个胶囊,点开就是「谁在占端口、它属于哪个项目」,不需要的当场关掉。 一个 dsh(DeepSeek Harness)插件:右下角一个胶囊,点开是滑出面板,列出本机所有 TCP 监听端口,按所属项目分组,带一个加了防护的关闭按钮。专治「我的智能体又留下一堆开发服务器没关」。 零依赖,无需构建,没有后台守护进程。 它解决的是这个问题:用智能体做项目,npm run dev、python -m uvicorn 之类的开发服务器跑完没人收,端口越攒越多;打开任务管理器只看到一堆 node.exe,根本分不清哪个是哪个项目的。 端口抽屉(暗色) 它长什么样 - 右下角胶囊:端口 12,有「父进程已退出」的遗留端口时变琥珀色并提示 · 3 遗留。 首次点开之前不扫描(悬停会说明),避免每次打开 dsh 都去拉起 PowerShell。 - 右侧抽屉:端口按项目分组,组头是项目名 + 路径 + 端口数,组里每条是端口号 / 进程名 / PID / 已运行时长 / 内存 / 徽标。 - 分组顺序固定:遗留端口 → 用户项目(按名排序)→ 未识别项目 → Windows 系统(默认收起)。
展开完整文档(README 剩余 1 节)
dsh-port-viewer · 端口可视化

给 DeepSeek Harness(dsh) 桌面端加一个端口占用面板:右下角一个胶囊,点开就是「谁在占端口、它属于哪个项目」,不需要的当场关掉。

一个 dsh(DeepSeek Harness)插件:右下角一个胶囊,点开是滑出面板,列出本机所有 TCP 监听端口,按所属项目分组,带一个加了防护的关闭按钮。专治「我的智能体又留下一堆开发服务器没关」。
零依赖,无需构建,没有后台守护进程。

它解决的是这个问题:用智能体做项目,npm run dev、python -m uvicorn 之类的开发服务器跑完没人收,端口越攒越多;打开任务管理器只看到一堆 node.exe,根本分不清哪个是哪个项目的。

端口抽屉(暗色)

它长什么样

- 右下角胶囊:端口 12,有「父进程已退出」的遗留端口时变琥珀色并提示 · 3 遗留。
首次点开之前不扫描(悬停会说明),避免每次打开 dsh 都去拉起 PowerShell。
- 右侧抽屉:端口按项目分组,组头是项目名 + 路径 + 端口数,组里每条是端口号 / 进程名 / PID / 已运行时长 / 内存 / 徽标。
- 分组顺序固定:遗留端口 → 用户项目(按名排序)→ 未识别项目 → Windows 系统(默认收起)。
遗留分组带一句「父进程已退出,可能是智能体跑完没收」;系统进程收在最后一组,不占视线。
- 点 关闭 → 行内变成 确认关闭 / 取消,3 秒倒计时自动还原;没有全局弹窗。
- 明暗主题跟随 dsh,颜色全部来自 --dsw- 设计变量。

端口胶囊(暗色)端口抽屉(亮色)

「端口属于哪个项目」是怎么判出来的

这是本插件的重点,不是简单列 PID。判定按可信度依次回退,每条端口都会标出来源:

| 优先级 | 依据 | 说明 |
| 1 | 进程工作目录 | 从 cwd 向上找项目标志物(.git / package.json / pyproject.toml / Cargo.toml / go.mod / pom.xml / .csproj / composer.json …) |
| 2 | 命令行里的绝对路径 | 覆盖 node …\node_modules\vite\bin\vite.js、--cwd= 这类;会剥掉 node_modules 之前的部分 |
| 3 | 父进程链 | cwd 读不到时(权限/系统进程)向上最多 4 层找第一个有 cwd 的祖先 |
| 4 | DSH 工作区表 | 读 $DSH_HOME/storages/workspace.json 里登记的工作区路径做最长前缀匹配 |
| 5 | 进程所在目录 | 装好就常驻的程序(代理内核、本地服务、dsh 自身)用安装目录当组名 |
| 6 | 同名可执行文件 | 身份被权限挡住时,用其它进程里同名 exe 的目录认领(例:verge-mihomo.exe → Clash Verge) |

都推不出来时不会丢端口:属于 Windows 系统的一组收进「Windows 系统」,其余进「未识别项目」。
<DSH_HOME> 与 profiles\<name> 不算项目根(否则 dsh 会归到一个叫 desktop 的组);
dsh 自身进程显示为 DeepSeek Harness(本界面)。

典型场景(作者本机实测,均为真实进程):一个 vite dev server 即使从别的目录启动,也能靠命令行里的 …/<项目>/node_modules/vite/… 归到项目;python -m uvicorn 靠 cwd 归到项目; verge-mihomo.exe(SYSTEM 账户、读不到 cwd)靠同名 exe 认领归到 Clash Verge。

Windows 上没有现成的「取别的进程工作目录」API,这里用 PEB 读取(NtQueryInformationProcess + ReadProcessMemory)拿 CurrentDirectory;读不到(系统进程 / 更高权限)就退化成上面第 2~6 级,不会因此漏掉端口。

安全:什么不会被关

「关闭」是破坏性动作,而且「读端口清单」本身就会暴露命令行,所以宿主侧有三道关:

1. 会话鉴权:两条路由复用 dsh 自己的会话 cookie(ctx.get('connection').authorizeIndex,与 /api 桥、index 服务是同一个校验)。桌面壳把 /api/ 转发给宿主时会带上这个 cookie,所以正常界面天然带凭证,而本机的其它进程(别的登录用户、脚本)没有。
为什么不用插件自己发令牌:最初就是那样做的 —— 用 webServer.tapIndex 把令牌注水进 index.html。它在浏览器版 dsh 里能跑,但桌面端结构上不可能成立:桌面壳对 dsh-app://app/ 的主文档是直接从 app.asar/renderer 读盘返回的,只有 /api/、 /plugins/ 才转给宿主,所以 index 注入在桌面端永远不会执行 —— 强制令牌 = 面板 100% 401 (实测踩过)。宿主没有 connection 服务时这条自动跳过,退回同源 + CSRF。
2. 请求形态:跨源请求、非 application/json 的表单请求一律拒绝 —— 任意网页没法借你的浏览器关你的进程。
3. 目标复核:前端拿到的 killable 只是提示,真正的判定在 POST /api/port-viewer/kill 里,而且执行前会用绕过缓存的新快照重新核对「这个端口此刻是否仍属于这个 PID」(PID 复用即拒绝)。
fresh 采集失败时直接拒绝,绝不拿旧快照授权。以下一律拒绝:
- pid <= 4(System / Idle)、已知系统进程名、%SystemRoot% 下的可执行文件;
- dsh 自己:宿主进程、同 exe 的整个 Electron 进程树(主进程/renderer/GPU/subprocess);
- 正在承载当前界面的那个端口(关掉等于把界面拔线);
- 身份读不到的进程(典型是 SYSTEM 账户拉起的服务):taskkill 对它本来就是 AccessDenied。

另外,快照里的命令行会抹掉 sk-…、ghp_…、_PASSWORD=…、--token xxx、-p xxx、 Bearer …、URL 内嵌凭据等常见形态;taskkill 之后用「进程还在不在」判定成败,而不是相信 taskkill 的退出码(128 既可能是「没有这个进程」也可能是「拒绝访问」)。

界面里受保护的行显示锁图标与原因(例如「这是当前界面的端口,关掉会把界面弄掉」),没有关闭按钮。
完整威胁模型见 SECURITY.md。

安装(desktop profile)

需要 Windows(端口采集依赖 netstat 与 PowerShell 5.1)以及装在桌面端的 dsh。

powershell -ExecutionPolicy Bypass -File scripts\install-desktop.ps1

脚本做三件事,全部可逆(改动前的 profile package.json / cordis.patch.yml 会备份到 .backups\,已 gitignore):

1. 在 profile 的 package.json 里把 dsh-port-viewer 加进 dsh.profile.bundles 并登记 file: 依赖;
2. 在 profile 的 node_modules 下建目录联接指向本仓库(等价于 pnpm add file:,但不触动已有安装);
3. 自检:包名已登记、lib/index.js 可经联接访问。

dsh 数据根默认取 $env:DSH_HOME,否则 ~\.dsh。如果你的启动脚本设了别的 DSH_HOME
(例如放在 D 盘),显式传进去:

powershell -ExecutionPolicy Bypass -File scripts\install-desktop.ps1 -DshHome D:\your\dsh-home -DryRun

-DryRun 只打印将要做什么。装完要重启 dsh 桌面端:cordis 的 profile 图在进程启动时组装,没有热挂载新插件的能力。

官方等价做法(会跑一次 pnpm):dsh plugin --profile desktop add file:<本仓库绝对路径>

卸载

powershell -ExecutionPolicy Bypass -File scripts\uninstall-desktop.ps1

删联接、从 bundles 与依赖里摘掉,重启后彻底消失;也可以直接还原备份的 package.json。
不重启也能立刻止血:在 profile 的 cordis.patch.yml 里对本行加 disabled: true。

配置(可选)

在 profile 的 cordis.patch.yml 里按行 id 覆盖:

- id: port-viewer
name: 'dsh-port-viewer'
config:
protectSystem: true # 关掉就等于允许杀系统进程,别关 requireSession: true # 要求请求带 dsh 的会话 cookie(见「安全」第 1 条) ttlMs: 1200 # 快照缓存时间;连点刷新不会反复拉起 PowerShell maxTargets: 128 # 单次 kill 请求最多几个目标 snapshotTimeoutMs: 15000

实现要点

- 零依赖、无构建:宿主半边 lib/index.js(cordis 插件 + 两条同源路由),浏览器半边 lib/client.js(classic script,position: fixed 注入,样式全部用 dsh 自己的 --dsw- 设计变量)。不新增 npm 依赖,卸载后不残留。
- 采集:lib/collect.js 拉起一次 Windows PowerShell 跑 lib/snapshot.ps1 (netstat -ano -p TCP + Get-CimInstance Win32_Process 全表 + PEB 读 cwd), UTF-8 无 BOM JSON 经临时文件回传;一次全量快照约 1 秒。归属推断在 lib/projects.js,是纯函数,可单测。
- 不需要常驻进程:插件只在 dsh 运行时存在;不装服务、不写注册表、不开机自启。平时不扫描,只有你点开面板(或打开自动刷新)时才采一次。
- 整个 client.js 包在 IIFE 里,绝不污染全局:页面里还有别的 classic script 插件,顶层同名工具函数(例如都叫 el())会互相覆盖 —— 实测过这种冲突会让对方插件的挂件丢掉全部内联样式、从右下角消失。所以本文件不向 window 泄漏任何符号, test/client-scope.test.mjs 用 node:vm 空沙箱把这件事锁死。
- 右下角自动避让:胶囊不硬钉 bottom:60px,而是量出右下角已有挂件的盒子、排在它上方(量不到才退回 60px)。窗口缩放、每次展开都会重新量 —— 插件加载顺序不保证。
需要让位给别的挂件时,把它的容器 id 加进 lib/client.js 的 BOTTOM_RIGHT_ANCHOR_IDS。

验证

- node --test test/index.test.mjs —— 宿主安全闸门与 HTTP 语义(22/22:会话鉴权的放行/拒绝/异常兜底、跨源拒绝、受保护目标、PID/端口复核、opaque 进程、Electron 宿主下的
dsh 进程树、凭据抹除的 10 种真实形态、taskkill 的「活着就判失败」、采集失败降级、
缓存与并发合并)。
- node --test test/collect.test.mjs —— 采集与归属推断(39 个用例 / 38 通过 / 1 默认跳过: cwd/命令行/父链/工作区回退、孤儿判定、多绑定合并、降级快照、系统组合并、UNC 拒绝;跳过的是需要真机的 PV_REAL=1 用例)。
- node --test test/client-scope.test.mjs —— 浏览器半边作用域回归(3/3):node:vm 空沙箱跑 client.js,断言不留全局符号、模块契约正确、apply 走 ctx.effect、胶囊靠 class(而不是 style 属性)拿样式、dispose 后 DOM 清干净。
- scripts/verify-isolated.ps1 -Phase full —— 起一个隔离实例(独立 DSH_HOME 与 portverify 配置档,端口 3099),用无头 Edge + CDP 跑端到端断言:插件进入 boot 图、 匿名请求 / 伪造 cookie 都被 401 拒绝、自己起的牺牲监听器真的被 kill 掉且端口释放、受保护端口被拒(error=protected)且界面存活、抽屉打开后 dsh 界面仍可点击、明暗两套截图。
不碰你正在用的桌面端;结束断言端口释放、无遗留进程。
- test/panel-harness.html —— 不启 dsh 也能看面板:逐字内嵌 dsh 真实的两套 --dsw- 变量, mock 掉加载器与宿主,用固定快照渲染 9 种状态,并自带几何/对比度自检。

设计细节(为什么是 DOM 注入、为什么整份采集交给一次 PowerShell、状态机怎么走)见 docs/DESIGN.md。

已知限制

- 必须重启桌面端才生效(见「安装」)。
- 只在 Windows 上可用:netstat、Get-CimInstance、PEB 读取都是 Windows 路径。
- 会读其它进程的内存:为了拿工作目录,插件对其他进程调用 OpenProcess + ReadProcessMemory(只读 PEB 里的 CurrentDirectory,不扫别的数据)。这是 EDR 眼里的敏感行为;如果你不接受,可以在配置档配置里把它关掉(snapshot.ps1 -SkipCwd 等价能力目前只在库层面暴露,未接成配置项)。
- PEB 偏移只支持 x64;32 位 PowerShell 下会跳过 cwd 读取(不会读错内存),代价是归属退化为「命令行/安装目录」。
- 取不到工作目录的进程(系统服务、更高权限进程)只能靠命令行与安装目录推断,可能落到「Windows 系统」或「未识别」组 —— 这类端口本来也不该被关。
- 快照里读不到命令行时(部分系统进程)只显示进程名与 PID。
- 一次全量快照约 1 秒(开发机实测;慢机器上会更久,采集超时默认 15 秒)。
- 关闭用 taskkill /T /F 连带子进程:dev server 常是 npm → node 两层,只杀父进程会留下占着端口的孤儿。
- 只统计 TCP 监听端口;UDP 服务(DNS、部分游戏/流媒体)不在列表里。

目录结构

lib/index.js 宿主:cordis 插件入口、两条同源路由、kill 安全闸门 lib/collect.js 采集:spawn PowerShell、超时回收、读回 JSON lib/snapshot.ps1 PowerShell:netstat + WMI + PEB 读工作目录 lib/projects.js 端口→项目推断(纯函数,可单测) lib/client.js 浏览器半边:胶囊 + 抽屉(classic script,零依赖) scripts/ 安装 / 卸载 / 隔离实例验证 test/ 单测、fixtures、面板 harness、E2E 驱动 docs/ 设计说明与截图

License

MIT,见 LICENSE。安全问题请先读 SECURITY.md。
预览分享卡片长什么样 ↓abalika/dsh-port-viewer
分享 · DeepSeek Harness Hub
abalika/dsh-port-viewer

按项目分组查看本机端口占用并安全关闭

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部