omp-enhance0.2.0
Optional enhancements for the omp coding agent: localized, timestamp-prefixed session titles, with more to come
Built for omp
The author tagged this package oh-my-pi.
Reports 0
No reports yet.
Readme
omp-enhance
English | 简体中文
面向 omp coding agent 的可选增强功能,打包为一个插件,各功能可独立开关。
omp plugin install omp-enhance # 从 npm 安装
omp plugin link /path/to/omp-enhance-plugin # 本地 checkout
无需任何配置:默认功能会自行注册。插件不要求 API key、不注册 provider、不上报遥测,也不碰请求链路。唯一一次模型调用来自宿主自己的标题生成——本插件只调用它,不实现它。
功能
| 功能 | 默认 | 作用 |
|---|---|---|
session-title |
开 | 给自动生成的会话标题加时间戳前缀,并指定标题语言。 |
omp plugin features omp-enhance # 列出
omp plugin features omp-enhance --disable=session-title # 保留宿主自己的命名
从 0.1.x 升级
0.2.0 移除了 model-trace 功能。它的六个 modelTrace.* 设置已不存在,可以从配置里删掉;
留着也无害,因为插件根本不会读它们。
如果你的配置里仍然选中了那个已移除的功能,插件会什么都不加载,而且没有任何提示。 重置选择:
omp plugin features omp-enhance --set=session-title
omp plugin doctor 能报出全局选择残留的同类问题,并可用 --fix 清除。
session-title
给会话名加上时间戳前缀,正文由模型生成,语言可选。默认开启;关掉即恢复宿主自己的命名。
2026-11-02-20:29:01+实现标题前缀格式
这个名字会出现在状态栏 session_name 段、终端标签页、会话恢复列表和 /rename --show 里,因为它就是宿主持久化的会话名,而不是某种渲染技巧。
为什么需要它
omp 自己会给会话起名:第一条用户消息交给 smol/tiny 模型,配一份内置英文提示词,之后只有 /rename 能改。其中三件事扩展做不到:
| 你可能想要的 | 宿主为什么做不到 |
|---|---|
| 用别的语言起标题 | 提示词是内置的;唯一的替换方式是配置目录里的 TITLE_SYSTEM.md 文件,插件没法注入。 |
| 时间戳前缀 | 模型不知道墙上时间。让它「编」一个只会得到看似合理、实则错误的时刻。 |
| 不改任何文件就做到 | 标题生成前后都没有钩子。before_agent_start 是扩展能看到的第一个事件,而 session_name 根本不是事件。 |
所以本功能用宿主自己的生成器产出正文(和宿主同一次调用,只是提示词由我们给),时间前缀在代码里按真实本地时钟拼出,再用 pi.setSessionName 写回。
行为
- 每个会话一次,在第一条消息时。 以会话 id 记录,恢复、分支、后续回合都不会改名。
- 你起的名字优先。 请求开始前或进行中用
/rename起的名不会被覆盖;只有宿主生成的titleSource: "auto"会被替换,因为它可能在我们请求期间先落地。 - 跳过子代理。 它们由派发者命名,也不出现在恢复列表里。
- 失败就退回。 标题模型没给出结果(打招呼、消息含糊、provider 不可达)时,会话保留宿主给的名字。
- 宿主的自动起名保持开启。 设
PI_NO_TITLE会连带废掉子代理标题并失去上面的兜底;而宿主的 auto 标题在我们写回后被覆盖,因为宿主永不替换用户设置的名字。
设置
omp plugin config set omp-enhance sessionTitle.format "yyyy/MM/dd HH:mm+"
omp plugin config set omp-enhance sessionTitle.prompt "用简体中文拟一个不超过 6 个字的标题。"
| 键 | 默认 | 作用 |
|---|---|---|
sessionTitle.enabled |
true |
是否注册钩子。关闭时功能加载但不起作用。 |
sessionTitle.format |
yyyy-MM-dd-HH:mm:ss+ |
前缀pattern。可用 yyyy MM dd HH mm ss,其余字符原样保留。 |
sessionTitle.prompt |
中文、约 5 个词 | 标题请求的 system prompt,替换内置英文提示词。 |
分隔符写在 pattern 里:token 之后的字符都是字面量,所以 yyyy-MM-dd-HH:mm:ss+ 会得到标题前的 +,而 [yyyy-MM-dd] 会得到方括号和空格。用的是本地时间,不是 UTC。
改名
不带参数的 /rename 会被拦截,并按配置格式重新拼装:
/rename → 2026-11-02-20:31:07+登录模块错误处理重构
/rename 我自己的标题 → 我自己的标题 (原样交给宿主)
拦截用的是 input 钩子,而不是注册扩展命令。/rename 是内置命令,omp 先派发内置命令再查扩展命令,插件注册的 rename 永远不会被执行。input 钩子先于两者触发,因此由它消费无参形式并返回 { handled: true }——这也正是阻止内置命令用自己那份未格式化的标题覆盖我们结果的关键。
带参数的标题是用户在明确表达意图,原样放行。
/session-title 做同样的事,只是名字属于本功能:
/session-title # 当前格式、示例、现在的标题,以及自动流程是否已执行
/session-title 手动标题 # 立即按当前格式改名
自动流程只跑一次,所以两种写法都可以用来给当前会话重新套用改过的格式。
说明
- 过长的标题在这里被裁短,而不是被宿主截断。 宿主把会话名存进固定的 256 字节槽位(还带着来源与时间戳),实测可保留 66 个字符;本功能按这个预算裁切,并保证前缀完整。
- 每个会话多一次 smol 模型调用。 它在回合之外异步执行,不会阻塞第一条回复。
- 改格式只影响新会话。 已有会话保持原名,直到你运行
/session-title <文本>。
仓库结构
一个功能一个目录、一个入口文件,在 package.json#omp.features 中声明。omp 只加载已启用功能的入口。
src/lib/ 跨功能共享(设置读取)
src/features/session-title/ 一个功能:入口 + 设置 + 标题拼装
test/ 经宿主自身 loader 的端到端验证
新增功能 = 在 src/features/ 下加目录 + 一条 omp.features 记录 + 给它的设置键加功能名前缀。
脚本
| 脚本 | 用途 |
|---|---|
bun run dev |
把本 checkout 载入一次无头 CLI 运行。 |
bun run typecheck |
strict 下的 tsc --noEmit。 |
bun run test |
typecheck 的别名;本仓库没有单元测试。 |
bun run smoke |
通过 omp 自身的扩展加载器加载插件并断言其注册项。无需网络。 |
bun run verify |
依次执行 typecheck 与 smoke——发布前门槛。 |
bun run publish:dry |
npm publish --dry-run:打包、跑发布前门槛、不发送。 |
bun run publish |
先 verify,再以 public 访问级别发布到 npm。作为 npm 自身的 publish 生命周期钩子被调用时会拒绝执行。 |
prepublishOnly 会执行 typecheck,因此损坏的代码树无法被发布。
发布
npm version patch # 1. 升版本 + 打 tag
bun run publish:dry # 2. 先检查 tarball
bun run publish # 3. 先验证,再上传
bun run publish 与 npm 自带的 publish 生命周期钩子同名,而 npm publish 会自动执行该钩子。所以直接跑 npm publish 会调用这个脚本,脚本又去调 npm publish。脚本为此加了守卫:当 $npm_command 为 publish 时直接退出,不再递归。因此要么通过脚本发布(bun run publish),要么用 npm publish --ignore-scripts。脚本自己会跑 verify,因为 --ignore-scripts 同时会跳过 prepublishOnly。
验证
bun run verify
test/smoke.ts 通过 omp 自身的加载器加载插件,断言用户实际会得到什么:before_agent_start 与 input 两个处理器已注册、且没有任何 provider 或消息处理器,/session-title 有响应,不写状态栏也不写 widget,标题拼装及其跳过规则成立(子进程,宿主生成器被替换为桩),残留旧功能设置项的配置仍能干净加载(子进程),以及 manifest 只解析出那一个功能、关闭时解析为空。不需要网络与凭据:被测的每一项事实都来自宿主钩子或已替换的接缝。
它刻意不命名为 *.test.ts:它会启动宿主运行时,比单元测试慢,属于发布前门槛而非 bun test。