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

@blurname/debrief

v0.1.0

Published

Debrief your Debian box: snapshot every installed package (plus loose non-dpkg binaries) and track what drifts

Readme

debrief

Debrief 你的 Debian 机器——问它到底装了什么,并追踪它的变化。

(名字取自 deb + debrief「事后汇报」:把整台机器的安装情况汇报上来。)

主线用法:收集当前机器上装了什么,变成一份清单,然后追踪它的变化。 软件你(或某个 agent)照常用 apt 直接装,debrief 不负责装、负责"看和管"——collect 把系统快照成 debrief.json + debrief.lock,status 告诉你系统相对快照又多了/少了/升级了什么。

概念映射

| npm | debrief | | --- | --- | | package.json(直接依赖) | debrief.json — 你主动装的包(apt-mark showmanual) | | package-lock.json(完整依赖树) | debrief.lock全部已装包 + 确切版本(含依赖) | | node_modules | 系统 dpkg 状态(通过后端读写) | | npm registry | apt sources / Debian 镜像 | | pip freeze / dpkg --get-selections | debrief collect — 从系统反向生成清单 | | git status | debrief status — 系统当前状态 vs 快照 | | npm install | debrief install — 把清单里缺的装到另一台机器 |

底层就是 Debian 原生的 dpkg-query(装了什么)+ apt-mark showmanual(哪些是你主动装的、 而非被依赖带进来的)。后者恰好等价于"直接依赖 vs 传递依赖":主动装的进 manifest,依赖只进 lock。

也能抓"非 dpkg"装的裸二进制

有些软件根本不走 apt——curl … | sh、手动下载、brew/cargo 之类,直接把一个可执行文件丢到 PATH 上(比如 herdr 就是 curl -fsSL https://herdr.dev/install.sh | sh)。 collect 会顺带扫 /usr/local/bin~/.local/bin 等目录,对每个可执行文件用 dpkg -S 反查: dpkg 不认领的,就是这类"裸二进制",记进 lock 的 binaries(含内容 sha256,所以自更新会被 status 认出来;加 --probe-versions 还能跑 --version 取版本)。

$ debrief status
non-dpkg binaries (curl|sh / manual / brew / ...):
+ herdr /usr/local/bin/herdr
~ bun /usr/local/bin/bun (contents changed)

--no-binaries 关掉这个扫描;--scan-dirs a:b:c 指定要扫的目录。

主线:收集 & 追踪

debrief collect          # 把当前系统快照进 debrief.json(主动装的)+ debrief.lock(全部)
debrief collect --pin    # manifest 里记确切版本(而非默认的 "*")
debrief status           # 对比:系统相对上次 collect 多了/少了/升级了什么
debrief list             # 清单里的包及其状态、可升级情况
debrief outdated         # 有新版本可升级的包

典型场景:把 debrief.json + debrief.lock 提交进你的 dotfiles / 配置仓库。之后 agent 直接 apt install 了什么新东西,debrief status 一眼就能看出来;确认无误就 debrief collect 重新快照。

$ debrief status
+ ripgrep 14.1.0-1
+ libpcre2-16-0 10.42-1 (dep)
~ nginx 1.24.0-2 → 1.26.0-1
- jq 1.6-2.1

+2 added  ~1 changed  -1 removed (vs snapshot; run `debrief collect` to update it)

设计取向:友好封装(friendly wrapper)

这是刻意选择的最保守语义:

  • install 只增不改:只安装 manifest 里尚未安装的包。已经装了的,即使版本不满足约束 (drift),也只警告、绝不改动。不做整机对齐(no reconcile),不会去卸载"多余"的包。
  • add / remove 是显式动作:add 会安装并写入 manifest;remove 会卸载并从 manifest 移除。
  • lockfile 给你可复现性:install 时若锁定的版本仍然可用且满足约束,就装锁定的那个 (输出里标 ),而不是最新的——这样在另一台机器上 install 得到同样的结果。

后端(可插拔)

所有逻辑都只依赖一个 Backend 接口,因此同一套代码能在有没有 apt 的机器上跑:

  • apt — 真实 Debian,底层调用 dpkg-query / apt-cache / apt-get(改动系统的操作会在 非 root 时自动加 sudo)。
  • mock — 内存/文件模拟的假仓库,自带一批仿真包版本。在没有 dpkg 的机器(比如 NixOS)上 默认启用,用于开发和测试。

选择顺序:--backend > $DEBRIEF_BACKEND > lockfile 里记录的后端 > 自动探测(有 apt-get 就用 apt,否则 mock)。

反向:把清单装到另一台机器(可选)

collect 出来的清单也能反过来用——在一台新机器上把清单里缺的装齐。这条线是刻意保守的 "友好封装":

  • install 只增不改:只安装清单里尚未安装的包。已装的即使版本不满足约束(drift), 也只警告、绝不改动;绝不卸载"多余"的包。
  • add / remove 是显式动作:add 会安装并写入 manifest;remove 会卸载并移除。
  • lockfile 给可复现性:install 时若锁定版本仍可用且满足约束,就装锁定的那个(标 )。
debrief install                    # 把 manifest 里缺的装上(优先按 lock 复现)
debrief add nginx@^1.24 git        # 显式安装并记录
debrief add htop=3.2.1-1           # 钉死一个确切版本
debrief remove git                 # 卸载 + 从 manifest 移除
debrief remove git --save-only     # 只从 manifest 移除,保留已安装
debrief init                       # 创建一个空的 debrief.json
debrief --dry-run <cmd>            # 预演,不改动任何东西

安装用 bun:bun link 后可直接用 debrief;或 bun run bin/debrief.ts <command> 直接跑。

版本约束(npm 风格,作用在真实 Debian 版本号上)

约束语法借用 npm,但比较用的是 dpkg 自己的版本算法(epoch、~ 预发布排序等都正确处理):

| 写法 | 含义 | | --- | --- | | nginx | 最新候选版;manifest 里写成 ^<装上的版本> | | nginx@^1.24 | >=1.24<2(caret:允许非 major 升级) | | nginx@~1.24 | >=1.24<1.25(tilde:钉住 minor) | | nginx@'>=1.22 <1.26' | 空格分隔 = AND 组合区间 | | nginx=1.24.0-1 | 精确的 Debian 版本 |

开发

bun install
bun test            # 单元 + 集成测试(全程用 mock 后端,任何机器都能跑)
bun run typecheck

分发

代码只用 node: 内置模块(通过 src/sys.ts 这层薄封装),所以同一份代码在 Bun 和 Node (≥18)上都能跑。默认分发方式:打成一个几十 KB 的 JS,要求目标机有 bunnode——比把整个 运行时塞进二进制(~100MB)划算得多。

bun run build      # → dist/debrief.js(~40KB,单文件,含 node shebang)
node dist/debrief.js collect        # 用 node 跑
bun  dist/debrief.js collect        # 用 bun 跑
  • npm:npm i -g debrief(或 bunx debrief)—— bin 指向 dist/debrief.js,prepack 会自动构建。npm pack 出来的包只有 16KB / 3 个文件。
  • curl | sh:curl -fsSL <host>/install.sh | sh —— 拉下 dist/debrief.js 和一个 exec node/bun 的启动器丢到 ~/.local/bin(见 scripts/install.sh)。注意:这样装的 debrief 自己就是个"裸二进制",会被它自己的 collect 扫描逮到。

已在真实 Debian 上验证:

  • 两种运行时结果一致 —— bun run test:apt(Bun)、bun run test:node(纯 Node)。
  • npm pack → 在干净的 node 机器上 npm i -gdebrief collect/add hello 对着真 apt 跑通。
  • install.sh 拉取 + 启动器 + 运行,链路验证过。

真正 npm publish / 建 Release / 建 apt 仓库还没做(需要账号和授权)——上面验证的是"发出去就能用"。

想要"零运行时依赖"?(体积换取)

如果目标机连 node/bun 都不想装,可以退回自包含二进制 / .deb(每个 ~100MB,因为把运行时也打进去了):

bun run build:bin     # → dist/debrief-linux-{x64,arm64}(自包含,无需运行时)
bun run build:deb     # → dist/debrief_<ver>_amd64.deb(需 dpkg-deb;NixOS 上在容器里打)
sudo apt install ./dist/debrief_0.1.0_amd64.deb

.deb 有个额外的好处:装完 debrief 就是个正经 dpkg 包,会出现在它自己的 collect 里(吃自己的狗粮)。

已知边界

  • 管理的是系统级的包(不是项目本地隔离);这是 apt 的本性。
  • apt 后端已在 Debian 13 (trixie) 容器里对着真实镜像端到端验证过(见下);开发主机 (NixOS)日常用 mock 后端顶替。
  • 依赖解析交给 apt 自己:manifest 只记你主动装的包,依赖只进 lock——正如 npm 只把直接依赖 写进 package.json

在真实 Debian 上验证

单元测试全程用 mock 后端,任何机器都能跑。apt 后端要在真 Debian 上验证,用容器即可:

docker run --rm -v "$PWD":/app:ro oven/bun:debian bash /app/test/apt-e2e.sh
# 受限网络下加 --dns 1.1.1.1

已验证:collect/status 正确解析 dpkg-query + apt-mark showmanual(手动装的包进 manifest、依赖标 auto:true 只进 lock、带 arch);status 能发现绕过工具、直接用 apt 装/删 的包;add/remove 走真实 apt-get install/remove

MIT