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

linkany

v0.0.3

Published

`linkany` 是一个 **macOS/Linux** 上的“安全 symlink 管理器”,围绕一个 `manifest` 文件维护一组“source ↔ target”的链接关系,并提供四个高层 API:

Readme

linkany

linkany 是一个 macOS/Linux 上的“安全 symlink 管理器”,围绕一个 manifest 文件维护一组“source ↔ target”的链接关系,并提供四个高层 API:

  • add(manifestPath, { source, target, ... })
  • remove(manifestPath, key, opts?)
  • install(manifestPath, opts?)
  • uninstall(manifestPath, opts?)

它的设计原则是:安全第一、可追溯、默认拒绝任何可能导致数据丢失的行为

CLI(命令行)

linkany 同时提供 库 APICLI。CLI 的核心设计是:支持设置一个“全局默认 manifest”,让你后续无需重复传 --manifest

设置/查看默认 manifest

  • 设置默认 manifest(写入全局配置,路径会被 resolve 成绝对路径):
    • linkany manifest set ./linkany.manifest.json
  • 查看当前默认 manifest:
    • linkany manifest show
  • 清空默认 manifest:
    • linkany manifest clear

在命令中使用 manifest(优先级)

  • 优先级-m/--manifest <path>(单次覆盖) > 全局默认 manifest
  • 示例:
    • 使用默认 manifest:linkany install
    • 单次覆盖:linkany install -m ./other.manifest.json

常用命令

  • linkany add --source <path> --target <path> [--kind file|dir] [--atomic|--no-atomic] [-m <manifest>] [--dry-run] [--plan]
  • linkany remove <key> [--keep-link] [-m <manifest>] [--dry-run] [--plan]
  • linkany install [-m <manifest>] [--dry-run] [--plan]
  • linkany uninstall [-m <manifest>] [--dry-run] [--plan]

全局配置文件路径(XDG)

  • 若设置了 XDG_CONFIG_HOME$XDG_CONFIG_HOME/linkany/config.json
  • 否则:~/.config/linkany/config.json
  • 格式:
{ "manifestPath": "/abs/path/to/manifest.json" }

能力概览

  • 仅使用 symlink:如果 symlink 失败(权限/文件系统限制等),直接报错,不会退化为 copy 安装。
  • 文件 & 目录:同时支持文件和目录链接。
  • 安全策略
    • add:当 sourcetarget 同时存在(且 target 不是指向 source 的 symlink)时 拒绝
    • remove/uninstall:只会删除 target 的 symlink,绝不删除 source
    • install:如果发现某个 target 存在但不是 symlink,会 整体 abort,避免误伤真实文件/目录。
  • 原子性(尽力而为)
    • 创建/替换 symlink 时优先使用 target.tmp.<rand>,再 rename 到位。
    • 替换已有 symlink 时会优先把旧 target 移到 target.bak.<timestamp>.<rand>(便于恢复)。
  • 审计记录(有记录的):每次调用都会把 Result 追加写入 JSONL 文件,默认路径为 ${manifestPath}.log.jsonl
  • dry-run / plan 输出
    • opts.dryRun=true 时不触发任何文件系统写操作(不 symlink/rename/unlink),只返回计划与结果结构。
    • opts.includePlanText=true 时会在 Result.planText 中附带可读的 plan 文本。
  • rollback 协议(best-effort)Result.rollbackSteps 会尽力给出“可逆步骤”的回滚计划(例如 move/symlink 的逆操作)。目前是协议与数据结构,未提供一键 rollback API。

Manifest 格式(v1)

{
  "version": 1,
  "installs": [
    {
      "id": "optional-stable-id",
      "source": "path/to/source",
      "target": "path/to/target",
      "kind": "file",
      "atomic": true
    }
  ]
}

说明:

  • source/target 支持绝对路径或相对路径;相对路径以 manifest 文件所在目录 为基准。
  • id 可选;如果没有 id,内部默认以 target 作为该条目的 identity(用于 remove)。
  • kind 可选:file | dir。不写时,add 会尽力推断;install 会从 source 的实际类型推断。
  • atomic 默认 true
  • 允许存在额外字段(linkany 会尽量保留并写回)。

API

linkany 的 API 支持两种输入方式,合并为同一个入口:

  • 文件模式manifest 传入 manifest 文件路径(string)
  • in-memory 模式manifest 直接传入 manifest JSON/对象

四个核心 API 的返回值统一为:

  • { result, manifest }result 为本次操作结果,manifest 为操作后的 manifest 对象)

add(manifest, { source, target, kind?, atomic? }, opts?)

用途:把一条映射写入 manifest,并把 target 收敛为指向 source 的 symlink。

核心语义:

  • source 不存在:自动创建空 source(文件:空文件;目录:空目录)。
  • target 已存在且不是 symlink、source 不存在:会执行一次“安全迁移”:
    • copy target -> source
    • 将原 target 移到 target.bak.<timestamp>.<rand>
    • 再把 target 改成指向 source 的 symlink
  • source 与 target 同时存在:拒绝(error),要求用户手动处理冲突。

remove(manifest, key, opts?)

用途:从 manifest 移除一条映射,并且 默认删除 target 的 symlink

  • key:优先匹配 id,否则匹配 target
  • opts.keepLink=true 可仅移除 manifest 记录,不删除 target symlink。
  • 永远不删除 source

install(manifest, opts?)

用途:按 manifest 全量落地,确保每个 target 都是指向 source 的 symlink。

安全策略:

  • 任意一条出现以下情况,都会 abort 且不做任何变更
    • source 不存在
    • target 存在但不是 symlink

uninstall(manifest, opts?)

用途:按 manifest 全量撤销,只删除 target 的 symlink;永远不删除 source

in-memory 模式的额外 options

manifest 传入 JSON/对象(而不是路径)时,opts 额外支持:

  • baseDir?: string:用于解析相对路径(默认 process.cwd()
  • manifestPath?: string:仅用于 Result.manifestPath 与 audit 默认路径推导(不会触发读写 manifest 文件)

审计日志(Audit Log)

  • 默认写入:${manifestPath}.log.jsonl
  • 每行是一条 JSON(完整 Result),包含:执行步骤、错误、耗时、变更摘要。
  • 可通过 opts.auditLogPath 指定自定义路径。
  • 如需完全关闭审计(由上层自行处理),传 opts.audit=false;CLI 对应 --no-audit

Options(opts)

适用于四个 API 的通用 options(CommonOptions):

  • auditLogPath?: string:覆盖默认审计日志路径。
  • dryRun?: boolean:只返回计划/结果,不写文件系统。
  • includePlanText?: boolean:在 Result.planText 中包含可读 plan 文本。
  • logger?: { info/warn/error }:注入日志实现(可选)。

目录结构(维护者)

src/
  api/        # 4 个对外操作,分别一个文件
  core/       # 执行引擎:plan/apply/fs/audit/runner/backup
  manifest/   # manifest 类型与读写(写回保持未知字段)
  cli/        # CLI 相关模块(全局配置等)
  cli.ts      # CLI 入口(argv 解析与命令分发)
  index.ts    # 对外统一导出
  types.ts    # 公共类型(Result/Step/Options)

更详细的维护说明见 KNOWLEDGE_BASE.md