上一篇文章之后,我把 Codex 额度横幅隐藏器开源了
前阵子,我写过一篇 Codex 额度横幅太烦?我让它给自己做了个隐藏器。
当时的起点其实很小,Codex 的通用额度用完以后,横幅一直死死占着输入框上方的位置。我不需要它替我恢复额度,也不想去点 Upgrade 或者 Reset usage,只希望它不要长期挡住我的工作区。

那篇文章的重点,在于怎么给 AI 交代一个清晰的本地改造任务,目标要克制,边界要严密,验收和卸载方式也得提前写进需求里。
这几天,我把那次一次性的本地脚本完整整理了一遍,做成了一个真正可以随时检查、安装、卸载并且能够继续迭代的开源项目。

仓库地址在这里,代码完全公开,采用 MIT 协议, GitHub,DavidLam-oss/codex-limit-banner-hider
它是一个面向 macOS Codex 桌面版的用户级界面定制工具。当「通用 Codex / Work usage 已耗尽」横幅出现时,只在能够唯一确认目标的前提下,隐藏横幅并释放它占据的屏幕空间。
先把最重要的话放在前面,它不会增加、恢复或绕过任何 Codex 额度。 它也不是 OpenAI 的官方功能。
这次后续,最有价值的不是「做出来了」
如果只是把上一篇写完的代码随手打包扔到 GitHub 上,其实没有太大意思。
真实使用之后,我们遇到了一个真正要命的问题,输入文字和切换会话的时候,Codex 有时会出现明显的卡顿和掉帧。
很有意思的是,当时自动化测试全都是绿的,DOM 的性能回归测试也顺顺利利跑完了。但这些冷冰冰的指标,根本推翻不了肉眼可见的体感卡顿。
写代码的人都知道,工具卡不卡,手指敲在键盘上最诚实。
于是我把旧版本彻底卸掉,花时间老老实实做了一轮实机 A/B 对比。
顺着调用栈一路摸下去,核心问题根本不在「隐藏横幅的那几行前端脚本」,而是在于底层的启动方式。
早期实现为了接管新启动的 Codex,直接从底层用命令行派生进程。这样虽然能跑起来,却完全跳过了 macOS 官方的 Launch Services 前台应用生命周期。输入法框架和窗口会话的归属由此错乱,体感上的卡顿就是这么来的。
这个排查结果让我感触很深,
测试通过,只能说明你测到的用例通过了,它不等于用户用起来真正觉得舒服。

所以开源版不是换个 README 就完事,而是把底层的启动和注入架构彻底重构了一遍。
现在的项目,究竟是怎样工作的?
尽量用大白话来讲,整个过程大致是这样的,
你像平时一样正常启动 Codex
↓
用户级控制器捕获刚启动的官方 Codex 进程
↓
严格核对应用路径、Bundle ID、官方签名与进程身份
↓
通过 macOS 正常的 Launch Services 路径完成交接
↓
启动阶段短暂连接页面,注入严格匹配的隐藏脚本
↓
确认脚本生效,立刻断开连接
↓
之后 Codex 完全按正常前台应用的方式运行,控制器不再打扰这里有三个特别值得单独聊聊的技术细节。
1. 它绝对不改动官方应用包
这个项目从头到尾不会修改 /Applications/ChatGPT.app 里的任何文件,不碰 app.asar,不碰登录凭据,不碰 Keychain,也不干扰官方的自动更新,更不会去做恶心的重签名。
所有东西都规规矩矩放在你的用户目录下,一个用户级 LaunchAgent、一份控制器代码和一份清晰可读的注入脚本。
卸载的时候,当前正在跑的 Codex 不会被粗暴杀死。等你正常退出再重新打开,界面就干干净净回到官方原始行为。
这比直接去应用包里改一行 CSS 稍微繁琐一点,但更新、排错和还原的路径清晰太多了。
2. 它不是看到横幅就无脑删掉
真正危险的前端定制,往往只有一句草率的代码,找到页面上所有的 aside,找到所有带 limit 的词,通通隐藏。
开源版完全反过来做。它会同时核对主页面、标题文字、正文模板、横幅整体结构、内置图标以及当前允许存在的按钮。
只有当整个页面里出现唯一一个完全符合条件的候选时,才会加上专用的隐藏标记。
图片生成限额、单模型额度用尽、接近额度的提醒、系统安全提示、报错弹窗,或者带着未知新按钮的提示,统统不在处理范围内。
只要页面结构变了、出现多个相似候选,或者它拿捏不准,就会直接走 Fail Closed 策略,什么都不隐藏,同时在状态里如实汇报 structure-rejected 或 ambiguous。
我特别喜欢这个取舍,一个优秀的本地工具,最得体的自我保护不是强行工作,而是在看不清状况时明确停下来。

3. 一个需要坦诚说清楚的架构取舍
上一篇文章里,我们探讨的是私有进程间通道。现在的开源版为了保留 macOS 正常的前台应用上下文,改为让 Chromium 在启动时随机分配一个仅绑定 127.0.0.1 的本地回环调试端口,控制器通过它完成一次性脚本注入,随后立刻切断。
说得再透彻一点,它不是固定端口,绝不对外网开放,更不是一个日常常驻的 DevTools 长连接。但它确实在启动的那一瞬间,存在一个本地回环端口。
这是当前版本明确写进 README 的架构取舍,我们把它摆在明处,不玩任何文字游戏。
在日常使用期间,控制器不再频繁向渲染器发指令,更不常驻连接页面。横幅稍后冒出来的时候,由已经驻留的脚本做极低频的定向检查。当窗口被隐藏时,这个检查也会自动挂起。
为什么一定要把它开源?
因为这种触碰到本地环境的工具,最关键的是「别人能不能独立看清它到底碰了哪里」。
如果它只是我自己电脑里一段私密的脚本,你只能选择相信我口头上说的边界。
但把它开源之后,所有事情都可以被任何人独立核对:
- 它到底有没有改动官方应用包里的文件
- 它会不会暗中点击购买、重置或者确认按钮
- 它究竟在匹配什么页面、过滤什么元素
- 遇到官方界面改版时,它会不会误伤其他重要通知
- 出了问题怎么查状态,怎么几秒钟内卸载干净
项目里把这些交付物全都放整齐了,完全可读的源代码、中英双语 README、安装脚本、状态命令、卸载脚本、自动化测试,以及安全漏洞的报告指引。
我从来不觉得开源就等于绝对安全。但它至少让原本苍白的「请相信我」,变成了一句踏实的「你可以自己随时检查」。
想试试的话,先看这几个前提
这个项目目前只支持 macOS 上、安装在默认官方位置的 Codex 桌面版,并且启动时会严密核对 Bundle ID 和官方代码签名。重签名版本、第三方打包版、Windows 和 Linux 都不在支持范围内。
另外,你的电脑里需要安装 Xcode Command Line Tools,因为控制器会在本机完成编译。
确认好这些前提,安装只需要简单的三步,
git clone https://github.com/DavidLam-oss/codex-limit-banner-hider.git
cd codex-limit-banner-hider
./install.sh安装脚本非常克制,不会为了强行生效而突然把你正在写的 Codex 关掉。它会保护当前正在工作的进程,第一次生效只需要你在没有任务的时候正常 Cmd + Q 退出软件,重新打开即可。
在项目目录下,平时可以随时运行这行命令查看状态,
./status.sh如果是在新开的终端窗口,先 cd codex-limit-banner-hider 进入目录即可。
如果状态显示 hidden,说明目标横幅已被精准识别并隐藏。如果显示 absent,说明控制器运行良好,只是当前页面没有出现额度横幅。

如果你看到 structure-rejected 或者 ambiguous,请千万不要去修改代码放宽匹配规则。那说明官方界面更新了,我们应该先检查新界面的结构,补上针对性的测试和适配。
不想用的时候,同样在项目目录下,一行命令就能还原,
./uninstall.sh项目文件和 LaunchAgent 会被平稳移到系统的废纸篓,这是特意留下的一条可恢复的退路。
这个项目不适合所有人
如果你需要随时看到额度恢复的时间倒计时,或者心里对在用户目录下运行一个 LaunchAgent 有顾虑,那就不要装。
如果你追求的是「不管官方怎么改版我都必须强行隐藏」,它也同样不适合你。Codex 内部界面不是公开稳定的 API,我的设计哲学是,兼容时优雅应用,不兼容时宁可保留横幅,也绝不瞎猜乱动。
但如果你和我一样,心里很清楚额度的状态,只是单纯不想让一条大横幅长期霸占工作视野,同时又希望有明确的安全边界、状态反馈和优雅的卸载退路,那它或许是一份更放心的答卷。
从一段 Prompt 到一个可复用的工具
回头看,上一篇文章讲的是「怎么让 AI 替自己做一次轻量改造」。而这次的开源更像是那场实验的下半场。
一段 Prompt 确实可以快速启动一次尝试,写出一个能跑通的小 demo。
但如果要把它变成别人也能安心用在日常生产里的工具,后面还有很长的一段路要走,真机长周期的真实体验、翻车后的复盘深挖、底层架构的重新推导、防御性用例测试、完备的文档与状态工具、克制的卸载机制,以及接受公开审视的勇气。
这可能也是我越来越喜欢借助 AI 编程的原因。它能把原本停留在「我想改一下」的脑中灵感,以极快的速度拉齐成形。
但最终的边界和审美,始终得由人来把关。什么可以动,什么绝对不能碰,什么叫真正解决问题,什么只是表面上看起来差不多。
这一次,我把这些边界也一起开源了。