repo:
https://github.com/mainliufeng/codex-switch
先说下这个东西为什么会出现。
VP 让我尝试大模型直接写新 repo。
我也确实做了一套 skill。
但做到后面发现一个问题:skill 里内容一多,大模型经常“漏了”我的限制。
后面我又迭代了几次,加了硬性的流程、文档检查。
再往后发现需求、设计、测试用例经常对不上,又加了 subagent 跑文档 review,最后还要再跑代码 review。
结果就是 token 越来越费。
两个 GPT Plus 都用完了,我又开了第三个。
账号一多,经常切换就要在网页上重新登录,特别烦。
后来看到一个 cc-switch,本质上就是切换 `~/.codex/auth.json`。
我看了一眼,感觉这个东西我自己也可以写。
而且我是 Linux 环境,最适合的方式也不是搞个大客户端,而是直接做一个系统托盘上的小程序。
这个项目就这么来的。
第一版其实很直接。
我先让大模型写了一个,先别管什么技术栈,先把最基本的托盘切换做出来。
这一版的目标很简单:
- 右键菜单切换多个 Codex 登录配置
- 保存当前 `~/.codex/auth.json`
- 显示名称直接用账号邮箱
- 带编译脚本、安装脚本、README
- 首版不负责登录,只管理本地快照
后面真正落下来的技术栈其实就是:
- Go
- systray
- GTK / AppIndicator
因为这种东西本来就适合做成单二进制的小程序,跑在托盘里,做的事情也就是读配置、切配置、保存快照。
第一版能用之后,我又觉得,既然都切账号了,那顺手把账号用量也显示出来算了。
刚好看到人家 CodexBar 能显示用量,我就让 Codex 学了一下,写了第二版。
这一版开始,需求就变成了:
- 想看每个账号的剩余用量
- 最开始接受文本显示
- 后来要求切换和用量合并到同一个子菜单
- 用量没出来之前账号也要能点
- 最后要求同时显示进度条和准确剩余百分比
这里后端逻辑其实也开始复杂起来了。
不再只是简单切配置,而是要去读 codex app-server 的 RPC:
- `account/read`
- `account/rateLimits/read`
这里有几个点我觉得还挺关键:
- 不是通过真的切换系统当前账号去读用量,而是按每个快照隔离读取
- 用量和切换合并到一个 submenu
- 账号先显示,后台异步补用量
但第二版有个很现实的问题:
这个 UI 太老气了。
看着就是 old GTK 那股味儿,不太行。
然后我就开始折腾第三版。
这一版的思路是:既然 classic tray 的视觉不满意,那就干脆试试现代桌面 UI。
后面新需求就变成了:
- 可以接受从程序启动器打开一个居中的浮动窗口
- 要更现代、更好看
- 托盘只是辅助入口
- 重复启动器打开只能保留一个实例
这个阶段我先评估了几条路线:
- Wails v3 + Svelte
- Wails v2
- Tauri v2 + Svelte
最后拍板选了 Tauri v2 + Svelte。
原因也不复杂:
- 主要是从启动器打开,不强依赖 Linux tray 左键事件
- Tauri v2 做单实例和现代浮窗 UI 更合适
- 业务逻辑可以拆成桌面壳 + helper
所以这一版最后的技术栈是:
- Tauri v2
- Svelte
- Rust 桌面壳
- Go helper
我还顺手把之前装过的 frontend-design 这个 skill 也拿来用了,让它帮忙做 UI 设计。
结果就是这一版做完之后,图是有了,现代感也有了,但我自己看着非常不舒服。
说得直接一点:
这个 UI 把我看恶心了。
所以第四版其实是一次回退。
我最后还是更喜欢 classic 的使用方式。
于是最终决策就是:
- 删除 Tauri 浮窗实现
- 保留 classic 作为唯一正式版本
- 恢复 codex-switch 为唯一入口
- 保证 makepkg、安装脚本、README 都只对应 classic
最后收敛下来的正式版本技术栈就是:
- Go
- getlantern/systray
- GTK3 + Ayatana AppIndicator
- codex app-server RPC 用于读取账号用量
- PKGBUILD + .SRCINFO 供 Arch makepkg 安装
最后这个版本其实也更像我最开始想要的东西:
一个很小的托盘程序,能切账号,能看用量,别整太多花活。
到现在为止,我其实还没找到一个稳定的方法,能让大模型把 UI 直接写好。
功能、流程、重构、补逻辑,这些它都能帮上忙。
但一到 UI,尤其是那种我自己愿意长期看、愿意长期用的东西,它就很容易开始跑偏。
这次第三版就是这样。
技术上不是不能用,但做出来那个感觉,我是真看不下去,最后还是退回了 classic。
所以我现在的结论不是“大模型不能写 UI”,
而是我还没找到一个让它稳定写出好 UI 的方法。
如果你们有比较成熟的做法,欢迎在评论区讲讲。
比如:
- 你们是怎么约束大模型做 UI 的?
- 是靠设计稿、组件库,还是靠更强的 prompt?
- 还是说 UI 这件事,本来就不能太相信它?