@fabianactor/brew-cli

中文文档
0.3.6发布于 2026/11/08MITES Module构建来源已验证近 30 天下载 2008

CLI for operating brew-guide data in Supabase: beans, brewing notes, equipment and methods.

原始使用文档
文档目录16 节
  1. 安装
  2. 配置
  3. 四个常用场景
  4. 1. 查豆
  5. 2. 加一款豆
  6. 3. 记一杯
  7. 4. 管器具和配方
  8. 备份
  9. 更新检查
  10. 命令总览
  11. 全局选项
  12. 退出码
  13. 常见问题
  14. 数据模型备注
  15. 开发
  16. License

brew-cli

在终端里管理 brew-guide 的数据:咖啡豆、冲煮记录、器具与配方、烘焙商,直接读写它用的 Supabase 表。

数据和应用里看到的是同一份——手机上刷新就能看到你在终端里记的那一杯。

每个版本改了什么见 CHANGELOG.md。


安装

需要 Node.js >= 18。

npm install -g @fabianactor/brew-cli
brew-guide --version

包名是 @fabianactor/brew-cli(brew-cli 在 npm 上被人下架过,名字锁死了,用不了),装完的命令叫 brew-guide(跟它操作的那款应用同名)。不想全局装就用 npx @fabianactor/brew-cli bean list。

macOS 上用系统自带的 Node 装可能会 EACCES: permission denied —— 那是系统目录不给写,别用 sudo,改用 nvm / fnm 这类版本管理器,或者把前缀指到用户目录:npm install -g @fabianactor/brew-cli --prefix ~/.npm-global(之后把 ~/.npm-global/bin 加进 PATH)。

从源码装:

git clone https://github.com/FabianActor/brew-cli.git
cd brew-cli
npm install
npm run build
npm link        # 把 brew-guide 挂到全局 PATH

之后改代码只要再跑一次 npm run build 就生效,不用重装。

想装内嵌的 Agent skill(让 AI 助手知道怎么用这套命令):

npx skills add github.com/FabianActor/brew-cli -y -g

配置

brew-guide init

会依次问两样东西:

项说明
Supabase URL你的项目地址,结尾的 / 会自动去掉
API keypublishable key 就够(旧名 anon,在 Legacy API keys 标签里);不需要 service_role / secret key。输入时不回显,存在配置文件的 supabaseKey 字段
User ID不问,固定写 default_user。App 侧的同步标识是硬编码的(syncOperations.ts 的 DEFAULT_USER_ID),换别的名字只会得到一份 App 看不到的数据。真要换,用环境变量 BREW_GUIDE_USER_ID

为什么 publishable 就够:brew-guide 自带的 schema 对五张表都开了 USING (true) 宽 RLS,还对 anon 显式授了增删改查——权限边界就是 RLS 本身,换个人拿到同一把 key 也是这个权限。它不能绕过 RLS:表上没有对应策略的库,这把 key 一样被拒。想收窄的话得改策略,不是换 key。

配置写到 ~/.config/brew-guide/config.json,想换位置就设 BREW_GUIDE_CONFIG_PATH。老版本写下的 supabaseServiceRoleKey 字段仍能读(会提示一次改名),新写的都是 supabaseKey。

前置条件:roasters 命令需要库里存在 public.get_all_roasters() 函数,brew-guide 自带的 schema 里没有。没建也不会默默失败——跑 roasters 时它会把下面的 SQL 直接打给你,贴进 Supabase SQL Editor 跑一次即可。

建函数的 SQL
create or replace function public.get_all_roasters()
returns table (roaster text)
language sql
stable
as $$
  select distinct trim(both from r.roaster) as "roaster"
  from (
    select jsonb_extract_path_text("data", 'roaster') as roaster
    from "public"."coffee_beans"
    where "deleted_at" is null

    union all

    select jsonb_extract_path_text("data", 'roaster') as roaster
    from "public"."brewing_notes"
    where "deleted_at" is null
  ) as r
  where r.roaster is not null
    and btrim(r.roaster) <> ''
  order by 1;
$$;

想换配置就跑 brew-guide init,或直接改那个 JSON。


四个常用场景

1. 查豆

# 最近加的 10 款
brew-guide bean list --limit 10

# 按产区 / 处理法 / 品种 / 产国 / 批次找(包含匹配,--region 古吉 能命中「古吉 罕贝拉」)
brew-guide bean list --region 古吉 --has-remaining true
brew-guide bean list --country Ethiopia --batch "Lot 26"

# 看一款的完整字段(照片默认不打印,要原图加 --with-images)
brew-guide bean get bean_xxx
brew-guide bean get bean_xxx --with-images --format json > bean.json

# 还剩什么烘焙商
brew-guide roasters

2. 加一款豆

先在 App 里打开这些字段:设置 → 咖啡豆 → 咖啡豆字段,勾选 烘焙商、产地、产区、庄园、处理站、海拔、处理法、品种。没勾的字段在应用里看不到,等于白写。

一个当前限制:产国与产地在后端是同一个字段(开产国就得把国家从产地搬走,否则同一信息存两处)。批次写在 blendComponents[0].batch,App 里勾了批次就能看到。

brew-guide bean add \
  --name "罕贝拉 日晒" --roaster "MAME" \
  --country "埃塞俄比亚" --region "古吉 罕贝拉" \
  --estate "Buku Sayisa" --process "日晒" \
  --variety "原生种" --altitude "2350-2460m" \
  --roast-level "浅度烘焙" --capacity 100 --price 128

只有 --name 是必填 —— 和 App 一致:它的表单里也只有「咖啡豆名称」带必填星号,产地、处理法、烘焙商都能空着存。烘焙度不给就留空(以前会按豆种猜一个,猜错就污染 App 的筛选)。--start-day / --end-day 不给时按烘焙度取 App 的同一套预设:浅烘 7/60、中烘 10/60、深烘 14/90 —— 但这套天数只有在有烘焙日期时才生效:没给 --roast-date 的豆子,App 判到烘焙日期为空会直接显示「未设置烘焙日期」,养豆期、赏味期都不算(App 源码 flavorPeriodUtils.ts:217)。想让它真的开始计天,--roast-date 2026-11-01 一起给。

状态相关的三个开关:

# 还没到手
brew-guide bean add --name "..." --roaster "..." --origin "肯尼亚" --process "水洗" --in-transit

# 冷冻保存(和在途互斥,开一个就把另一个关掉;取消用 --no-in-transit / --no-frozen)
brew-guide bean update bean_xxx --is-frozen

生豆暂不支持(--bean-state green、--purchase-date 会被拒绝,报「暂不支持生豆系列操作,请至 APP 查看并操作」)。原因不是偷懒:App 的生豆是一整套流程 —— 记购买日期、按库存算余量、详情页把「冲煮记录」换成「烘焙记录」,「转为生豆」还要新建烘焙记录和一颗新熟豆(RoastingManager)。CLI 只改字段的话,会写出 App 里看不见的状态(老记录挂在生豆上但不显示、生豆被标成「在途」)。所以生豆相关的读和写统一交给 App;bean list 也会把生豆隐藏起来并提示数量。

--price 只收数字(88、88.5,也认 ¥88、88元 这种写法),存成字符串给 App 算「元/克」。

封面图/背面图可以直接从本地文件塞进去:

brew-guide bean add --name "..." --image "D:\photos\cover.jpg" --back-image "D:\photos\back.jpg"
brew-guide bean update bean_xxx --image "D:\photos\new-cover.jpg"   # 换图
brew-guide bean update bean_xxx --clear image                        # 清掉

照片和 App 一样存进 data.image / data.backImage(data:image/...;base64, 那种字符串)。CLI 不做压缩,只做两件事:认扩展名(.jpg / .jpeg / .png / .webp / .gif),以及超过 1.5 MB 直接拒绝(base64 会膨胀 4/3,一行太大既拖慢列表也占库)。想更小就先自己缩到 800px 宽——App 上传时也是这么压的。

拼配用可重复的 --component:

brew-guide bean add --name "三重奏" --roaster "TRIOON" \
  --component "region=卡哈马卡;process=水洗" \
  --component "region=库斯科;process=日晒;percentage=40"

字段怎么拆(产地/产区/庄园/处理站怎么分工)见 skills/brew-guide/references/bean-add.md。

3. 记一杯

# 记完自动扣余量(--with-note 会连记录一起写)
brew-guide note add --bean-id bean_xxx --method "三段式" \
  --equipment "V60" --rating 4.5 --notes "莓果,尾段偏甜" \
  --coffee 15g --water 225g --water-temp 92

# 翻最近的记录,按日期/评分筛
brew-guide note list --limit 10
brew-guide note list --from 2026-10-01 --to 2026-10-31 --min-rating 4

# 只想扣粉量、不记记录
brew-guide bean consume bean_xxx --amount 15

note add 没有必填项 —— App 里豆子和手法都能不选(方法那一步本身可以跳过),CLI 照此对齐。--rating 和 --taste-* 只收 0-5(超范围直接报错);--water-temp 收 92 或 92°C,一律写成 92°C;--equipment 会校验,内置 V60 / CleverDripper / Kalita / Origami / Orea / Sinloy / Espresso 直接认,自定义器具要写 equipment list 里的 ID。

--image 可以附一张照片(本地文件,同样存成 data URL)。给了 --bean-id 时,会先确认豆子还在,记录里再自动存一份豆子快照(名字、烘焙度、烘焙日期、烘焙商),和 App 里点「记录一杯」一样;以后豆子改名,旧记录仍显示当时的样子。

4. 管器具和配方

brew-guide equipment list
brew-guide equipment add --name "V60" --id "V60" --animation-type v60
brew-guide method list
brew-guide method add --name "三段式" --equipment-id "V60" --stages-json '[{"label":"焖蒸","water":"30g","duration":15,"detail":"注入 30g 水,等 15 秒"}]'

--id 撞已有器具会报错停下,确认要替换才加 --force。

备份

brew-guide backup                       # 默认 brew-guide-backup-<timestamp>.json
brew-guide backup --out "D:\bk\brew.json"

导出 coffee_beans / brewing_notes / custom_equipments / custom_methods / user_settings 的原始行(含软删),可以直接当离线快照。批量改库之前先跑一次。

更新检查

brew-guide update-check                 # 现在就去 npm 上查一次
brew-guide update-check --format json   # {"current","latest","upgradable","source"}

平时不用管:每条命令结束前会看一眼本地缓存,发现 npm 上有更新的版本就在 stderr 提醒一次(24 小时最多查一次,同一个版本只提示一次)。提示永远不联网等结果,所以不会拖慢命令;离线、被墙、registry 抽风都只是静默不提示。

不想被提醒就设 BREW_GUIDE_NO_UPDATE_CHECK=1(update-check 子命令本身不受影响,它只是不自动查)。


命令总览

命令干什么
bean add / get / update / delete / consume咖啡豆:新增、详情、修改、软删、扣余量
bean list列表,支持烤度、豆种、烘焙商、产区、处理法、品种、产国、批次、有无余量筛选
note add / get / update / delete冲煮记录:新增、详情、修改、软删
note list列表,支持器具、方法、豆子、评分、日期区间筛选
equipment add / get / update / delete / list器具
method add / get / update / delete / list冲煮配方(--stages-json 传分段注水步骤)
roasters库里出现过的烘焙商
backup整库导出成 JSON
update-check查 npm 上有没有新版本
init写配置

每个命令的完整参数用 --help 看,例如 brew-guide bean add --help。

全局选项

选项行为
--format json输出紧凑单行 JSON,走 stdout;警告、进度、错误一律走 stderr,可以直接 `
--dry-run写入类命令打印将要发送的载荷,不写库(读取类校验照做;连不上库时只给提示)
--clear <字段>bean update 清空某个字段,如 --clear price --clear flavor;成分字段(origin/region/…)与 image / back-image 同样可清。可重复

参数名写错会直接 exit 2 并列出可用参数,不会静默忽略。开关型参数(--has-remaining 这类)必须带取值:--has-remaining true 是「只看还有余量的」,false 是「只看余量为 0 的」,裸写不生效。

退出码

码含义
0成功
1运行时失败(记录不存在、写入被拒等)
2参数用法错误(缺必填、取值非法、空字符串、拼错的 flag)
64配置缺失或非法(先跑 brew-guide init)
65网络 / Supabase 请求失败

常见问题

中文 Windows 上 brew-guide ... --format json | ConvertFrom-Json 报 JSON 解析错误。 0.3.2 起不会了:Windows 上输出被管道/重定向(不是交互终端)时,JSON 里的非 ASCII 字符会自动转成 \uXXXX,不管控制台是哪个代码页都能解析 —— 你看到的是转义码,ConvertFrom-Json / jq 读出来仍是中文。交互终端里还是原样中文。

老版本(0.3.1 及以前)或在别的程序里遇到同样报错,是控制台用 GBK 解码了 UTF-8 输出,中文把引号吃掉了;两种解法任选:

chcp 65001                                  # 只影响当前窗口
[Console]::OutputEncoding = [Text.Encoding]::UTF8   # 当前会话生效

想强制关掉转义:BREW_GUIDE_JSON_ASCII=0(强制打开用 1)。

在意的是「CLI 的输出是 UTF-8」这件事 —— 写文件再用 Get-Content -Encoding utf8 读也一样可靠。

list 只出来 20 条。 默认 --limit 20,命中上限时 stderr 会提示;要看更多就 --limit 200。

数据模型备注

  • 业务字段都在各表的 data JSONB 里;data 里的时间值是毫秒数,不是 ISO 字符串。
  • 产地写在 data.blendComponents[];写入时扁平字段(--origin 等)会被合并进第一个成分并从顶层删除。
  • 主键是 (id, user_id),写入走 upsert,没有物理删除。
  • 写入会复活软删记录:所有写入都带 deleted_at: null,对一条已软删的 id 再 add/update 会让它重新出现。
  • list 默认只读 deleted_at is null 的行。

更细的约定见 docs/supabase.md。

开发

npm install
npm run dev -- bean list      # 直接跑源码
npm run typecheck             # tsc --noEmit
npm test                      # typecheck + node --test
npm run build                 # tsup → dist/
npm link                      # 改完只想本地用:build 一次就生效

改完 skill 文档记得同步:npx skills add ./skills/brew-guide -y -g。

发布:改 package.json 版本号 → 提交 → git tag v0.3.x && git push origin v0.3.x。CI 跑 typecheck / build / test 后,用 npm trusted publishing(OIDC)直接发布并自动附 provenance — 不需要任何 npm token。

发布链的前置条件(一次性):npm 包里登记 trusted publisher(user FabianActor、repo brew-cli、workflow publish.yml),Publishing access 设为「Require 2FA and disallow tokens」。配置建好后两天内必须成功发布一次,否则作废。0.2.0 是手动发的一次性引导,0.2.1 起全部走 tag + OIDC。

想验证包内容但不发布:npm pack --dry-run。

改了用户可见的行为,记得在 CHANGELOG.md 里补一条。

License

MIT。本仓库是 swiftwind0405/brew-guide-cli 的 fork,现由 FabianActor 维护;上游部分的版权归原作者,改动部分的版权与责任归本仓库维护者,改动的归属写在 NOTICE 里,具体改了哪些见 git log。

版本与发布记录

@fabianactor/brew-cli 共发布 11 个版本,首次发布于 2026/11/04;过去 12 个月发布了 11 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.3.6latest2026/11/086 天前
0.3.52026/11/068 天前
0.3.42026/11/068 天前
0.3.32026/11/059 天前
0.3.22026/11/059 天前
0.3.12026/11/059 天前

关于 @fabianactor/brew-cli 的常见问题

@fabianactor/brew-cli 是什么?

CLI for operating brew-guide data in Supabase: beans, brewing notes, equipment and methods.

如何安装 @fabianactor/brew-cli?

在项目目录运行 npm install @fabianactor/brew-cli,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 brew-guide,可以用 npx brew-guide 直接运行。

@fabianactor/brew-cli 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/fabianactor__brew-cli 是否存在。

@fabianactor/brew-cli 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@fabianactor/brew-cli 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@fabianactor/brew-cli 可以商用吗?

@fabianactor/brew-cli 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@fabianactor/brew-cli 的下载量有多少?

根据 npm 官方下载统计,@fabianactor/brew-cli 在 2026/10/14 – 2026/11/12 这 30 天内被下载 2,008 次,日均约 67 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@fabianactor/brew-cli 还在维护吗?

最新版本 0.3.6 发布于 2026/11/08(6 天前);至今共发布 11 个版本,其中过去 12 个月发布了 11 个;首次发布于 2026/11/04。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。