009 / 025 · 开发 · v0.22.0 · MIT
steward
sync、ship、cleanup 都只管你当下所在的那一个仓库。steward——大内总管——是把这套流程跑遍你最近真正在动的每一个仓库的那一个:它自己找出这些仓库、逐个巡查,然后交回一份总账,告诉你什么在等你:哪些分支可以合并、哪些 PR 被什么卡住、哪些分支写完了却没开 PR、哪些 worktree 里还有会话在跑。
- 参数
都是可选的。
[--roots=<dir,…>][--since=<days>][--occupied-hours=<hours>][--stale=<days>][--only=<sync|cleanup|retitle|report>][--dry-run][--unattended]
- 什么时候触发
这些是 CI 用来评测这个技能的 prompt,每次发布都会跑。
会触发
- 大内总管,把所有项目巡一遍,看看哪些分支该合并了
- Sweep all my repos: sync them, clean up what merged, and tell me what's waiting on me.
- 定时清理本地环境,每天早上跑一遍,提醒我哪些需要 merge
- 扫一下所有 worktree 和 session,把没用的收拾掉
不触发
- 清理一下仓库,清掉合并过的分支
- 同步一下,拉一下最新的
- 会话名太乱了,帮我规范对话名称
- Ship this branch and merge it.
- 把这个 PR 合了
它从会话痕迹里找仓库,不是从磁盘上找
哪些仓库是「活跃」的,这个问题 git 回答不了。一个仓库活跃,是因为有会话在里面开过。所以清单来自会话留下痕迹的地方:Claude Code 的会话记录和此刻正在运行的会话、Codex 的线程目录,以及你用 --roots 点名的目录。每条痕迹归到它所在的 worktree,每个 worktree 归到它所属的主检出——所以一个挂着十几个 worktree 的仓库只巡一次,不是十几次。
指向不存在的东西的痕迹会被计数,而不是报错中断:已经被删掉的工作目录、系统临时目录下的临时检出、跑在非仓库目录里的会话。在一台机器上,14 天的窗口找到 15 个仓库、121 个 worktree,同时把 132 个已消失的目录和 29 个沙箱放到一边,没有停下来。
有会话占用的 worktree,一律不动
这是被委托的那几个技能看不到的东西。一个 worktree 被「占用」,指的是此刻有会话进程挂在上面,或者一天之内有会话往里写过。被占用的 worktree 绝不删除,它的分支也绝不删除——已合并、干净、无人占用是三个独立条件,三个同时成立才可以删。
理由是:会话恢复到一个已被删掉的目录,后面每一条命令都会坏,而 git 根本不知道有这个会话存在。巡查会把这份清单作为「保留」交给 cleanup,并且每一个都会出现在报告里,附上占着它的那个会话。
它报告什么可以合并,但一个都不合
每一个打开的 PR 都会被分类:可合、被失败的检查卡住、与基准分支冲突、等 review、还是草稿。可合的那些会连同落地命令一起报出来。
但命令不会被执行。一个绿了的 PR 今天该不该合,是巡查看不到的决定——你在等的某个 review、一个发布窗口、一处你本打算先并进去的改动——一个看到绿灯就合并的巡查,等于替你做了这个决定。
它为无人值守而设计,所以它什么都不问
定时跑的时候没人在键盘前,所以任何一个环节都不允许停下来提问。子技能本来会停下来问的每一个问题,都改为写进报告的「需要你」一栏:没能快进的基准分支、有提交却没开 PR 的分支、在主检出里被 checkout 出来的已合并分支、住在仓库目录之外的 worktree。retitle 只出改名提案、一个都不写入——因为调度器不是确认。
这次运行是 forked 的:中间输出留在 fork 里,回到你手上的是那份报告。报告同时写入 ~/.local/state/steward/last-sweep.md,所以它能熬过一次错过的通知,也能告诉下一次巡查上一次是什么时候跑的。
它不做什么
它不合并、不 rebase、不解决冲突、不丢弃提交。它不会删掉任何 cleanup 本来会保留的东西,也只有你开口时才会给自己排定时任务。同步或清理你当下所在的那一个仓库,是 sync 和 cleanup 的事;把一个分支落地,是 ship 的事。
开发 里的其它技能
还有 5 个 · 一次安装sync
/dev:syncsync 只做一件事:把本地和远端的差异摊开给你看,并且只执行其中绝对安全的那部分。
ship
/dev:shipship 把一次改动从工作区送到一个已合并的 PR:开分支、跑项目自己的测试、提交、开 PR、等 CI、合并,最后清理 worktree。
cleanup
/dev:cleanup一次改动发布之后,残留会留下来:本地分支、它在远端的副本、当时用的 worktree,有时还有一个只装着被忽略文件的目录。
retitle
/dev:retitle对话列表乱,不是因为名字不好听,是因为名字里没有可排序的信息。
reunite
/dev:reunitereunite 解决的是两种时刻:你用另一个账号登录,侧边栏突然只剩寥寥几条;或者你在一个账号里归档、删掉了某条对话,换到另一个账号它还在。