008 / 025 · 开发 · v0.22.0 · MIT
retitle
对话列表乱,不是因为名字不好听,是因为名字里没有可排序的信息。客户端拿你随口说的第一句话生成会话名,一周之后侧栏就是一列句子。retitle 给每条对话一个说清楚「什么时候、哪一类活、关于什么」的名字,两头都管:hook 在新会话开始时命名,批量整理负责已经堆在那里的旧对话。
- 参数
都是可选的。
[--client=codex|claude-code][--lang=en|zh][--tz=<zone>][--apply]
- 什么时候触发
这些是 CI 用来评测这个技能的 prompt,每次发布都会跑。
会触发
- My conversation titles are a mess. Make them consistent.
- 帮我规范一下对话名称,太乱了
- Rename my Codex sessions so I can actually find things in the sidebar.
不触发
- Rename this git branch to something clearer.
- Delete all my conversations from before June.
- 清理一下合并过的分支
命名规范
MMDD|TYPE|subject日期取创建时间而不是最后更新时间,所以侧栏的时间顺序不会因为你回头翻了一次旧对话就被打乱。类型限定在九个里,凑不进去的不硬塞第十个。主题是这次对话真正在讲什么,两到四个小写单词,写对象而不是写活动。
分隔符是全角竖线 |(U+FF5C),不是 ASCII 竖线。ASCII 竖线会把这个技能用来预览改名的那张 Markdown 表格拆散。
| 类型 | 什么时候用 |
|---|---|
| BUILD | 新能力、新接口、新页面 |
| SHAPE | 写代码之前定下的形状——架构、接口、布局 |
| PATCH | 某处行为错了,已改正 |
| TWEAK | 行为本来就对,改的是速度、成本或清晰度 |
| SHIP | commit、PR、合并、打 tag、部署 |
| PROBE | 试了一下看会怎样,没有确定的产出 |
| WRITE | README、注释、指南、changelog |
| AUDIT | 拿你已经拥有的东西对标准检查 |
| STUDY | 读外部世界来回答一个问题 |
AUDIT 和 STUDY 都是「看完出报告、不建东西」,分界在看的是谁的东西:AUDIT 查你自己已有的仓库、部署、页面、配置,STUDY 是去外面读资料回答问题。「审查网站 SEO」是 AUDIT,「哪些 SEO 工具值得用」是 STUDY。
这条区分是数出来的:只有八类时统计 181 条对话,研究那一类占了 50%,半条侧栏是同一个词,那这个字段就没在传递信息。拆出审计移走了其中 25 条。
为什么类型是五个大写字母
类型这一栏除了表意还有一件事要做:撑住一列,让主题在每一行都从同一个位置开始,眼睛顺着往下扫而不是横着找。两个汉字天然做到这件事——每个汉字都是一个 em——而这套规范本来就是中文的,所以它在没人留意的时候就已经有了这个性质。英文在比例字体里没有:FIX 和 DESIGN 差两倍宽,差到这个程度列就不存在了。
所以改成固定字母数。这九个词在常见侧栏字号下宽度大约 38px、抖动 3px 左右,而自然英文词那一套是 26px 到 55px。大写负责剩下的部分:大写字母没有上下伸出部分,这一栏读起来像个标签,而不是一个跟旁边主题抢注意力的单词。SHIP 是唯一的四字母成员——没有哪个五字母英文动词能诚实地同时覆盖 commit、PR、合并、打 tag、部署和发布,而一个说谎的类型比一格参差贵得多。
想要中文的话
--lang=zh 换回这套规范最早的词表 —— MMDD|类型|主题,功能、设计、修复、优化、发布、探索、文档、审计、研究,顺序对应上面那张表。其他什么都不变,中文也不需要宽度论证,两个汉字就是两个 em。新会话那一半是同一个选择,在 hook 命令上加一个环境变量 SESSION_TITLE_LANG=zh。
已经符合规范的标题(任一语言)不会被动,所以默认换成英文不会把你花几个月命名成中文的侧栏重写一遍。
新会话自动命名
手动改名追不上客户端开新会话的速度,所以规范落在会话诞生的地方——一个 UserPromptSubmit hook,随 dev 插件启用即注册。Codex 通过插件原生 manifest 发现它;语言由插件的 session_title_lang 选项决定,默认 en,设成 zh 即中文——Codex 例外,它不会把插件选项传给 hook,所以要在 Codex 自身的运行环境里设 SESSION_TITLE_LANG=zh;不经插件、单独复制这个技能时,按技能指向的参考文档手动装 hook。
Codex 会先按精确 hash 审核插件 hook,审核通过前不会运行。安装插件后,或升级改动了 hook 后,打开 /hooks,检查显示的命令和源码并信任它;插件显示「已安装」或「已启用」本身不代表 hook 已经生效。
hook 会按实际客户端选用原生的改名接口。在 Codex 中,它要求 agent 调用不带 threadId 的 mcp__codex_app__set_thread_title,即当前任务;在 Claude Code 中则用带 session_id: "self" 的 set_session_title。两种路径都不直接改派生出来的侧栏数据库字段。
它在第一个 prompt 触发完整规则,之后每五个 prompt 触发一次短复查。会话的方向会漂移,但完整规则太长,每轮都注入不划算;复查只在主题真的变了时才改名,因为一个每几条消息就变的标题比一个略微过时的更难用。
日期由 hook 自己从 transcript 的第一个时间戳解析,不取当前时钟,所以跨午夜的会话保持开始那天的日期。所有失败路径都静默 exit 0:一个会抛异常的 hook 会拦住你的 prompt。
发布检查会从已安装的 Codex 插件运行这个 hook,并确认首个 prompt 的指令指向当前任务。每次发布改动 hook 时,维护者先在 /hooks 审核并信任新 hash,再新建一个桌面任务、提交一句中性 prompt,并确认任务标题真的更新:自动检查证明打包的指令没漂移,这个简短的人工探针证明客户端的真实生命周期仍然有效。
整理已有的对话
/dev:retitle它先出一张两列表(原名称 / 新名称),然后就停在那里:不带参数时只出提案,什么都不写。/dev:retitle --apply 出同一张表,再把表里这些行改名,写入前自己留一份备份。无论带了什么参数,表都先出——几百个标题被改写在一个你没法轻易 diff 的存储里,不适合跳过预览。
主题从对话里推不出来的保留原名,计入「跳过」,不猜。
改 Codex 时走的是 app server 的 thread/name/set,而不是直接写那张 sqlite 目录表:那张表是派生出来的,直接改会在下次对账时被重新生成的标题覆盖。
它不做的事
它只改名字,不碰对话内容、所属项目、置顶、归档或排序,也不重命名项目、文件夹、分支、worktree 或文件。云端同步过来的那部分对话不改,因为本地改了下次同步就被覆盖。对于一个它没有被验证过能理解的客户端,那张提案表格就是全部交付物——它不会靠猜 schema 去动一个存储。
开发 里的其它技能
还有 5 个 · 一次安装sync
/dev:syncsync 只做一件事:把本地和远端的差异摊开给你看,并且只执行其中绝对安全的那部分。
ship
/dev:shipship 把一次改动从工作区送到一个已合并的 PR:开分支、跑项目自己的测试、提交、开 PR、等 CI、合并,最后清理 worktree。
cleanup
/dev:cleanup一次改动发布之后,残留会留下来:本地分支、它在远端的副本、当时用的 worktree,有时还有一个只装着被忽略文件的目录。
steward
/dev:stewardsync、ship、cleanup 都只管你当下所在的那一个仓库。
reunite
/dev:reunitereunite 解决的是两种时刻:你用另一个账号登录,侧边栏突然只剩寥寥几条;或者你在一个账号里归档、删掉了某条对话,换到另一个账号它还在。