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

fluffy-keys

v0.4.0

Published

A local-first CLI for managing development secrets and environment values.

Readme

fluffy-keys

fluffy-keys 是一个本地优先的 Node.js CLI,用于管理开发环境中的 API Key、令牌、密码及其他环境变量。实际值保存在当前操作系统用户的原生安全存储中;项目只提交不含值的声明文件 .fluffy.json

它适用于本地开发密钥管理,不替代生产环境、CI/CD 或团队共享环境的专业 Secret Manager。

特性

  • 使用 Windows Credential Manager、macOS Keychain 或 Linux Secret Service 保存实际密钥值。
  • 管理全局密钥:列出、读取、设置、生成、删除,以及 JSON、dotenv、YAML 导入导出。
  • 通过 .fluffy.json 声明项目依赖,并按“项目作用域优先、全局作用域回退”解析。
  • 通过 fluffy run 仅向子进程注入已声明的密钥,不修改当前 shell。
  • 使用配方生成缺失的项目密钥,并支持从全局作用域安全迁移到项目作用域。
  • 静态扫描 Node.js、Java 和 .env.example 中的环境变量声明。
  • 使用严格的 JSON 模板交换团队声明和生成配方,不交换密钥值。
  • 诊断并显式清理原生 Vault 的过期 metadata 索引。

安全模型

  • 实际密钥绝不写入 .fluffy.json、recipe 配置、模板、registry 或常规日志。
  • liststatusscan、模板和 registry 命令只输出键名、位置及 metadata,不输出值。
  • getexport 是仅有的显式敏感输出命令:值写入 stdout,export 会在 stderr 发出警告。
  • set 默认使用隐藏回显输入;脚本场景必须显式使用 --stdin,避免值进入命令历史。
  • --system 仅在 Windows 上读写当前用户环境变量(HKCU\\Environment),其值为明文,不是 Vault 的替代品;只适用于用户明确要求持久化的非敏感配置。修改后需重启已打开的终端或 IDE。
  • 安全存储不可用时命令以退出码 4 失败,不会降级为明文文件。
  • FLUFFY_VAULT=memory 仅限测试和开发调试,进程结束后数据会丢失,不能保存真实密钥。

要求

  • Node.js 22 或更高版本
  • npm
  • 可用的原生安全存储:Windows Credential Manager、macOS Keychain 或 Linux Secret Service

Linux 上需要在当前会话中运行可用的 Secret Service/keyring;若不可用,CLI 会 fail closed。

安装与本地开发

全局安装已发布版本:

npm install --global fluffy-keys
fluffy --help

从源码运行:

git clone <repository>
cd fluffy-keys
npm install
npm run build
node dist/cli/main.js --help

测试或适配器开发可使用内存 Vault:

FLUFFY_VAULT=memory node dist/cli/main.js --help

Windows PowerShell 中使用:

$env:FLUFFY_VAULT = 'memory'
node dist/cli/main.js --help

快速开始

1. 保存一个全局开发密钥

交互输入,不会回显值:

fluffy set API_TOKEN

脚本中从标准输入读取:

printf '%s' "$API_TOKEN" | fluffy set API_TOKEN --stdin

列出 metadata 或显式读取值:

fluffy list
fluffy list --prefix='redis_*'
fluffy get API_TOKEN

list 支持可选 --prefix <pattern>,仅 * 为通配符,需匹配完整 key,可与 --env--json 组合,方便筛出同一命名约定下的相关 key。get 会将实际值直接写到 stdout,请勿将其输出记录到日志或终端历史。

Windows 用户环境变量可显式使用 --system

fluffy list --system --prefix='LOG_*'
fluffy set LOG_LEVEL --system
fluffy get LOG_LEVEL --system

--system 不能与 --env 组合,且会把值明文写入当前用户环境变量,不应用于 API Key、令牌、密码等敏感值。新启动的终端和 IDE 才会继承修改后的值。

2. 初始化项目声明

cd my-app
fluffy init --project-id my-app

生成的 .fluffy.json 可安全提交:

{
  "$schema": "https://fluffy.dev/schemas/keys/v1.json",
  "version": 1,
  "projectId": "my-app",
  "environment": "development",
  "secrets": {
    "DATABASE_URL": { "required": true },
    "JWT_SECRET": { "recipe": "jwt-secret" },
    "OPTIONAL_TOKEN": { "required": false }
  }
}

项目解析顺序为:--env 指定的环境、manifest 的 environment、默认 development。每个声明的键先查询 project/<projectId> 作用域,再回退到 global 作用域;父 shell 的同名变量不会满足声明。

3. 生成并修复缺失项

先创建一个不含值的生成配方:

fluffy recipe set jwt-secret --format base64url --length 48
fluffy recipe list

查看项目状态并生成带配方的必需项:

fluffy status
fluffy fix

fix 只生成缺失的必需项,不生成 optional 项。没有配方的必需项会要求安全输入。status 还会报告当前项目作用域、当前环境中未在 manifest 声明的冗余键;全局键和其他环境中的键不会被标为冗余。

4. 运行项目

fluffy run -- npm run dev

run 使用参数数组启动子进程,不经 shell 拼接,并只向该子进程注入已声明且已解析的密钥。当前 shell 环境不会被修改。

命令参考

全局密钥

| 命令 | 说明 | | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | | fluffy list [--env <environment>] [--prefix <pattern>] [--json] [--system] | 列出 Vault metadata;--system 列 Windows 用户环境变量 key。 | | fluffy get <KEY> [--env <environment>] [--system] | 将一个实际值写到 stdout;--system 读取 Windows 用户环境变量。 | | fluffy set <KEY> [--env <environment>] [--stdin] [--system] | 交互式或从标准输入创建、替换 Vault 密钥;--system 写明文用户变量。 | | fluffy gen <KEY> [--env <environment>] [--format <format>] [--length <n>] [--charset <name>] | 生成并存储安全密钥;generate 是别名。 | | fluffy rotate <KEY> [--env <environment>] [--system] [--gen] [--format <format>] [--length <n>] [--charset <name>] [--stdin] [--yes] | 轮换已存在的 Vault 密钥或显式选择的 Windows 用户变量。 | | fluffy remove <KEY> [--env <environment>] [--yes] | 经确认删除密钥。 |

gen 支持 randomhexbase64base64urluuid。默认生成 32 个密码学安全随机字节的 base64url 令牌;uuid 适合标识符,不适合高熵认证密钥。random--charset 可选 loweruppernumericalphanumericall

rotate 只轮换已存在的密钥(缺失时报错,不会自动创建),覆盖前默认要求确认,可用 --yes 跳过。--gen 复用 gen 的生成选项;不带 --gen 时提示输入新值或从 --stdin 读取。

导入与导出

fluffy import <file> --format json|dotenv|yaml [--env <environment>] [--yes]
fluffy export --format json|dotenv|yaml [--env <environment>]

导入前会显示键名预览并要求确认,但不会显示值。导出会显示敏感提示,并把值写到 stdout;请仅重定向到受保护且被 Git 忽略的位置:

fluffy export --format dotenv > .env

支持的映射格式:

{
  "API_TOKEN": "local-only-value",
  "DATABASE_URL": "postgres://localhost/app"
}
API_TOKEN=local-only-value
DATABASE_URL=postgres://localhost/app
API_TOKEN: local-only-value
DATABASE_URL: postgres://localhost/app

项目命令

| 命令 | 说明 | | -------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | | fluffy init [--cwd <directory>] [--project-id <id>] [--env <environment>] [--force] [--yes] | 创建 declaration-only .fluffy.json。 | | fluffy status [--cwd <directory>] [--env <environment>] [--json] | 检查项目声明的解析状态和冗余项目键。 | | fluffy fix [--cwd <directory>] [--env <environment>] [--yes] | 生成或安全输入缺失的必需项目密钥。 | | fluffy run [--cwd <directory>] [--env <environment>] -- <command> [args...] | 向子进程注入已声明密钥。 | | fluffy migrate [keys...] [--cwd <directory>] [--env <environment>] [--all] [--move] [--yes] | 从全局作用域复制声明密钥到项目作用域。 | | fluffy project import <file> [keys...] --format json\|dotenv\|yaml [--cwd <directory>] [--env <environment>] [--all] [--overwrite] [--yes] | 将格式文件中的已声明 key 写入项目 scope。 |

migrate --all 使用 manifest 中的所有声明键。添加 --move 时,工具会在确认目标值已写入项目作用域后才删除全局来源。

project import 从 JSON、dotenv 或 YAML 文件读取值,必须显式列出待导入 key 或指定 --all;所有 key 都必须已经在项目 .fluffy.json 中声明。它先预览键名并要求确认,默认跳过已有项目值,只有 --overwrite 才替换;实际值不会进入 manifest、预览或日志。

配方

fluffy recipe list
fluffy recipe set <name> \
  [--format random|hex|base64|base64url|uuid] \
  [--length <n>] \
  [--charset lower|upper|numeric|alphanumeric|all]

配方是用户级、非敏感的生成规则。它只保存格式、长度和字符集,永远不保存生成结果或第三方凭据。

Agent skill

将随 npm 包发布的 skill 安装到 agent 环境:

npx skills add fluffy-keys

skill 默认要求 agent 使用 Vault、先列出 metadata,并在写入、轮换或项目导入前仅展示 key 名和目标范围后等待确认。它禁止未经明确要求读取/导出实际值,也禁止将值写入命令参数、日志、聊天或项目文件。

扫描项目声明

fluffy scan [--cwd <directory>] [--json]
fluffy scan --update [--cwd <directory>] [--yes] [--json]

扫描器使用有限的静态模式识别:

  • Node.js:process.env.NAME
  • Node.js:process.env["NAME"]process.env['NAME']
  • Java:System.getenv("NAME")
  • .env.example 中的键名

结果分为已声明、可新增候选和动态访问。动态访问只能提示,不能被自动写入。scan --update 会先展示静态候选,并在确认后仅新增 { "required": true } 声明;已有声明及其 requiredrecipe 配置不会被覆盖。

扫描会跳过真实 .env* 文件、.git.nextnode_modulesdistcoverage,不会读取或输出真实 .env 值。

团队声明模板

模板仅支持严格 JSON,适合共享项目所需的键、必需性、目标环境和生成配方:

fluffy template export [--cwd <directory>] > team-template.json
fluffy template import team-template.json [--cwd <directory>] [--yes]

示例:

{
  "version": 1,
  "environment": "development",
  "secrets": {
    "JWT_SECRET": { "required": true, "recipe": "jwt-secret" }
  },
  "recipes": {
    "jwt-secret": { "format": "base64url", "length": 48 }
  }
}

模板不包含 projectId、Vault registry metadata 或任何实际值。导入前会预览新增项和冲突项;冲突始终保留本地声明与配方。模板根级和密钥声明中的未知字段、声明中嵌入的实际值,以及引用不存在配方的声明会被拒绝。

Vault registry 诊断

fluffy vault registry diagnose [--json]
fluffy vault registry repair [--yes]

原生 Vault 通过本地 registry 保存 metadata,以便在部分系统钥匙串无法枚举条目时列出密钥。diagnose 只检查 registry 已登记的条目是否仍存在于钥匙串,不能发现 registry 外的条目,且不会修改任何内容。

repair 会预览 stale metadata,并在确认后再次检查;它只删除仍 stale 的 registry metadata,绝不会删除钥匙串中的实际值。内存 Vault 不支持该诊断能力。

退出码

| 退出码 | 含义 | | ------------ | --------------------------------- | | 0 | 成功。 | | 1 | 未预期的通用失败。 | | 2 | 参数、manifest、模板或配置无效。 | | 3 | 缺少必需项目密钥。 | | 4 | 原生安全存储不可用或拒绝访问。 | | 5 | 用户取消交互操作。 | | 子进程退出码 | fluffy run 会透传子进程退出码。 |

本地质量检查

npm test
npm run typecheck
npm run lint
npm run format:check
npm run build
npm run pack:check

发布由维护者手动执行 npm publish 并使用 OTP;本项目不配置 GitHub Actions CI。

设计文档

更多架构、数据边界和威胁模型说明,请阅读 概要设计