riffdev
v0.2.0
Published
群共创开发机器人:一行安装、一处配置,把群里的人话变成本地 Claude Code 的代码改动
Downloads
581
Readme
riffdev
把群里的人话变成代码改动:群友提需求 → riffdev 工单 → 本地 headless Claude Code 改 代码 → 验证 → 推送 → 回群播报。安装器 + 配置生成器 + runner 三合一。
只支持 macOS,需要 Node ≥ 20。
一条命令
npx riffdev init在你的 repo 目录里跑它,回答几个问题,跑完除了把机器人拉进群,不该再有任何手工步骤 ——
飞书那一问直接回车,二维码就出现在同一个终端里,扫完自动接上。
同一条命令重复跑 = 更新/修复(幂等,已完成的步骤打 ✓ 跳过);
答到一半失败也不白答,答过的会存进 ~/.riffdev/<项目>.answers.json,重跑时打 ✔ 跳过,装完自动删掉。
每个问题都能用 flag 预答,所以 CI / 脚本里可以一句话跑完:
npx riffdev init --token fts_xxx --repo . --feishu-app cli_xxx:sec_yyy # 已经有飞书应用
npx riffdev init --token fts_xxx --repo . --feishu-scan # 没有:当场扫码建一个
npx riffdev init --skip-token --repo . --feishu-scan # 先不填 token:功能照跑,后台不留记录| 问题 | flag | 环境变量 |
| --- | --- | --- |
| riffdev token | --token / --skip-token | RIFFDEV_TOKEN |
| 哪个仓库 | --repo(默认当前目录,必须已经是 git 仓库) | — |
| 机器人在飞书的身份 | --feishu-app <app_id>:<app_secret>(有现成的)/ --feishu-scan(当场扫码建) | RIFFDEV_FEISHU_APP |
| 其它 | --platform / --bot-token / --admin / --mode | RIFFDEV_MODE |
没有现成的飞书应用就直接回车(非交互环境用 --feishu-scan):init 会当场
spawn cc-connect feishu setup --project <名>,stdio 直接继承,二维码画在你眼前这个终端里。
它扫完自己把项目块和身份写进 cc-connect 的配置,我们随后只补全缺的那几个键
(claudecode、work_dir、群里共用一个会话)—— 你原来就有的内容仍然一个字节不动。
扫码那步失败就当什么都没发生:报人话错误、配置不动,可以重来或改用 --feishu-app 手填。
cc-connect 这个程序按 RIFFDEV_CC_BIN → PATH → ~/.riffdev/bin/cc-connect 的顺序找。
两条安装路线(init 自己判断,不用你选)
- 挂靠模式 —— 本机已经在用 cc-connect(有
~/.cc-connect/config.toml): 只往那份配置的末尾追加一个[[projects]]块。 你原来的内容一个字节都不动,追加前先备份到~/.riffdev/backup/config.toml.<时间戳>; 同名项目已经存在且不是我们加的 → 明说并停,绝不覆盖。 - 全新安装 —— 本机没有 cc-connect:下载钉死版本到
~/.riffdev/bin/, 派生~/.riffdev/gen/config.toml,注册 launchd 服务(v1 老逻辑)。
riffdev uninstall 逆着来:挂靠模式下按项目名精确定位、只删我们追加的那一块,
其余内容逐字节还原(还有备份兜底);全新安装模式下卸 launchd 服务。
两种模式都会删 ~/.riffdev,repo 里的 AGENT.md 都保留。
其余命令
riffdev status # 装的哪种模式 / cc-connect 活着吗 / runner 活着吗 / 今日额度
riffdev apply # 改完配置跑这条(挂靠模式下只重启 daemon,不碰你那份 config.toml)
riffdev uninstall # 摘干净(--yes 免确认)另有 riffdev gen(单独重新生成 cc-connect 配置)、riffdev run(前台跑 runner,
平时由 launchd 托管)、riffdev update(升级钉死版本的 cc-connect)。
所有命令都支持 --help;init / apply / update / uninstall 支持 --dry-run。
改配置的流程只有一条:编辑 ~/.riffdev/<project>.toml → npx riffdev apply → 生效。
挂靠模式下要改飞书凭证或工作目录,重跑 npx riffdev init——它会原地更新我们追加的那一块。
给群会话 CC 的两个只读窗口
机器人自己不读 riff.toml(里面有 token),它只能通过这两条命令看事实和策略:
riffdev ledger recent --limit 10 # 查帐本:id / 提单人 / 需求摘要 / 状态 / PR
riffdev ledger recent --author "@甲" # 只看某个人的单
riffdev policy show # mode / daily_limit / fast_lane 三个键,没有密钥policy 只有 show,没有 set:策略是硬的那一半,改它只能 owner 手编配置文件再
riffdev apply,群里说了不算。
riffdev job(群会话的后台工作进程)
群里的会话 CC 不亲自干长活——它把活派成 job,自己继续在群里说话。
一个 job = 一条 riff/<id> 分支 + 一个独立 worktree + 一个 detached 工作进程,
落盘在 ~/.riffdev/jobs/<id>/,多个 job 可以并行。
riffdev job start --repo . --desc "导航栏换成汉堡菜单" --author "@a" # 开工(--json 给机器读)
riffdev job status [<id>] # 看进度;不带 id 列出全部
riffdev job amend <id> "卡片再提亮点" # 开工后追加需求,写进 job 的 inbox.md
riffdev job stop <id> # SIGTERM→3s→SIGKILL;分支和 worktree 都留着
riffdev job merge <id> # 先 rebase 主干(冲突则报出冲突文件并退出非 0),干净才 --no-ff 合入riffdev run(runner)不受影响,它是 serious 模式的工单流水线,跟 job 各走各的。
唯一一份配置
~/.riffdev/<project>.toml(含密钥,不进 repo):
token = "fts_xxx"
repo = "/Users/you/code/yourproject"
[chat]
platform = "telegram" # telegram | feishu
bot_token = "123:ABC" # 飞书填 "<app_id>:<app_secret>"
group = "" # 首次入群后回填,可留空
admin = "8675309"
[policy] # 可整段省略
mode = "yolo" # yolo | vote | preview | serious
# 只有 serious 会注册轮询工单的 runner 服务,其余模式只派 job
daily_limit = 20 # 每天最多开几单(runner 领单和 job start 共用这个闸)
fast_lane = 0 # 免审快车道阈值(diff 行数),0 = 关;行为在 AGENT.md 层token / chat.bot_token / chat.admin 可以留空(--skip-token 的离线模式、
凭证交给扫码去建的情况),repo 和 chat.platform 是必填。
全新安装模式下,cc-connect 那份配置由 riffdev gen 从上面这份派生到
~/.riffdev/gen/config.toml,机器生成,别手改——下次 init / gen 会整体覆盖它。
挂靠模式下没有这份派生配置:我们的项目块直接住在你自己的 ~/.cc-connect/config.toml
末尾,~/.riffdev/attach.json 记着挂在哪、挂的哪个项目名(uninstall 靠它精确还原)。
环境变量
| 变量 | 作用 |
| --- | --- |
| RIFFDEV_TOKEN | 等价于 init --token |
| RIFFDEV_FEISHU_APP | 等价于 init --feishu-app |
| RIFFDEV_API_BASE | riffdev API base,默认 https://riffdev.ai/api/v1 |
| RIFFDEV_CC_CONFIG | cc-connect 的 config.toml 路径,默认 ~/.cc-connect/config.toml |
| RIFFDEV_CC_BIN | cc-connect 可执行文件路径(扫码那一步优先用它,其次 PATH,再次 ~/.riffdev/bin/) |
| RIFFDEV_EXECUTOR | 覆盖 runner / job 的执行器命令;按空格切分,需求文本作为最后一个参数追加 |
| RIFFDEV_PREVIEW_CMD | 生成预览链接的命令(分支名作最后一个参数);未设则只报分支名 |
| RIFFDEV_SKIP_LEDGER=1 | job start 不给 riffdev 记帐(离线测试用) |
| RIFFDEV_SKIP_DOWNLOAD=1 | init 时不下载 cc-connect 二进制 |
| RIFFDEV_SKIP_LAUNCHD=1 | init / apply 时不碰 launchd |
| RIFFDEV_SKIP_RESTART=1 | init / apply / uninstall 时不跑 cc-connect daemon restart |
| RIFFDEV_MODE | init 的默认 policy.mode(等价于 init --mode) |
旧名 RIFFBOT_* 一律仍然认(改名不该让别人的脚本一夜失效),新名优先。
开发
npm test # node:test,全离线(mock riffdev server + 假执行器 + tmp 里的真 git 仓库)部署
push 即部署——由仓库自己的托管方接管,riffdev 代码里没有任何厂商相关的东西。
项目要跑专用部署命令的,属于「习惯」:写进 repo 根的 AGENT.md「部署约定」节,
由群里的会话 CC 自己执行。
