架构与进程设计
两端均使用原生桌面界面和按需独立主面板;Windows v1.0.2 使用 C# / WPF,macOS v1.0.2 使用 Swift / AppKit,没有嵌入网页。两端的界面与系统集成分别维护,共享本地统计解析逻辑。
macOS v1.0.2:原生监控与事件等待
常驻宿主新增预算协调、任务事件读取和消息存储,主面板包含用量、预算与监控三页;关闭主面板后监控继续运行,不新增闲置常驻 Python 进程。菜单栏详情、圆环和侧签共用宿主状态,主面板通过有回执的通道同步修改。
父进程退出采用 kqueue 事件,服务停止使用可唤醒等待,刷新线程使用条件变量;主面板事件通道替代频繁健康查询。兼容路径仍保留回退,不能据此称整个应用零轮询或给出整机节能百分比。
浮窗几何使用 AppKit 屏幕点坐标与可用区,拖动中自由跨屏,松手后校正位置。四边和两屏接缝都可隐藏,动画与延迟有所有者、可取消并遵循减少动态效果设置。展开、保持展开、键盘意图及主动收起分别处理,避免静止指针引发收起后重开。
下方 v1.0.1 进程与内存内容保留为历史设计背景,不作为 v1.0.2 新测量。当前实现见 macOS 架构,本轮资源样本及边界见 资源测量。
Windows v1.0.2:托盘、浮窗与监控宿主
常驻宿主拥有托盘、浮窗、预算与任务监控;主面板按需启动自己的进程和本地 Python 服务。关闭主面板会释放这一部分,保留常驻入口与已选监控任务。
正在绘制图表…
查看图表文本
flowchart TB accTitle: Windows 桌面版的数据与提醒 accDescr: 本地日志经共享 Python 索引写入 SQLite,Windows 宿主原生读取缓存,独立读取任务事件并记录提醒。主面板通过本地服务查询数据。 L[本机 Codex 日志] --> P[按需 Python 增量索引] P --> DB[(本地 SQLite 缓存)] H[常驻 WPF 宿主:托盘与浮窗] --> N[Windows 原生 SQLite 读取] N --> DB M[独立 WPF 主面板] --> API[本地统计服务] API --> P H <-->|当前用户命名管道| M H --> T[任务事件读取与本地消息记录] T --> L H --> Q[Codex 只读账号额度查询] H --> V[应用内标记与可选系统通知]
预算读取已提交的统计缓存;任务监控读取明确的本地轮次事件,不以日志沉默推断完成。两者的范围与用量页面筛选分别保存。系统通知由 Windows 管理,记录消息、提交系统和用户实际看到横幅是不同状态。
Windows 的父进程监测同时等待进程退出与停止事件,避免用固定超时反复唤醒这条等待线程。圆环形变和回位动画在过渡结束后停止渲染回调;贴边与任务监测仍有各自的活动检查,不能据此声称整个程序零轮询或零闲置成本。
进程使用当前用户命名管道与 Windows 进程管理;主面板服务仅监听本机。具体实现位于 src/windows/Infrastructure/ 和 src/backend/,工程入口见开发指南。
macOS v1.0.1:独立主面板
下面的进程数量、bundle、时序和内存历史说明针对 macOS v1.0.1。菜单栏和浮窗共用宿主,主面板单独运行;关闭主面板释放其缓存,同时保持菜单栏与浮窗连续运行。
macOS 数据如何到达界面
正在绘制图表…
查看图表文本
flowchart TB accTitle: Codex 用量的数据流向 accDescr: 本机记账经 Python 增量索引写入 SQLite。常驻 GUI 读取摘要,按需主面板通过本机 HTTP 服务查询,账号额度由短时助手独立读取。 L[本机 Codex 已落盘记账] --> P[Python 增量索引] P --> DB[(SQLite 聚合缓存)] H[常驻 GUI:菜单栏与浮窗] --> N[短时原生摘要读取] N --> DB M[按需主面板 GUI] --> API[本机 HTTP 统计服务] API --> P H <-->|轻量状态与动作| M H --> Q[短时额度助手] Q --> C[本机 Codex 只读接口]
统计服务只监听本机 loopback;界面仍是原生窗口,用户无需打开浏览器。Token 统计来自聚合索引,账户额度由独立的短时助手读取,二者口径不同。
macOS 三种显示状态有几个进程
| 状态 | 稳定时的进程 |
|---|---|
| 仅菜单栏 | 1 个常驻 GUI,没有闲置常驻 Python |
| 仅浮窗,或菜单栏与浮窗同时显示 | 共用 1 个常驻 GUI,没有闲置常驻 Python |
| 主面板打开 | 2 个 GUI,加 1 个 Python 统计服务 |
| 扫描、读取摘要或查询额度 | 可能额外出现短时进程,完成后退出 |
不能仅按窗口数量推算进程数量,也不能把一次采样看到的进程数当作全时段固定值。
macOS 窗口相互独立
宿主 bundle 为 local.codex-usage.desktop,负责菜单栏和浮窗。主面板位于 Contents/Helpers/CodexUsageMain.app,bundle 为 local.codex-usage.desktop.main。两个角色共用编译后的代码,通过 bundle 身份按需创建界面;主面板不会创建第二套状态栏或额度定时器。
普通显示、关闭和隐藏操作不替换宿主 PID。关闭或隐藏主面板时,它结束自己的进程和统计服务。明确选择「退出」会关闭双方;「仅状态栏」「仅保留胶囊」按其模式含义调整显示。
WindowProcess.swift 处理启动、关闭、快速重开、重复实例及退出中的迟到消息。每个角色只有一个实例;关闭意图带时间信息,避免晚到的旧关闭消息覆盖新的打开操作。
macOS 谁负责扫描与刷新
主面板打开时,其 Python 服务负责增量扫描,宿主通过短时 C/SQLite 读取器查询同一聚合缓存。主面板退出后,宿主仅在日志变化且达到刷新间隔时短暂启动 Python,另每 600 秒做一次低频核对。
关闭自动刷新时不自动扫描;首次没有数据、手动刷新或切换筛选仍可发起读取。账号额度有自己的查询节奏,不与日志刷新混为一项。
跨进程手动刷新带请求编号、忙碌状态、结果和超时恢复。主面板尚未就绪时,刷新请求会在就绪后重发;旧编号不能解除新请求的忙碌状态。结果还会按统计范围、模型、任务和生命周期编号校验,减少过期快照覆盖当前选择的问题。
macOS 收起浮窗后保留什么
浮窗使用同一个原生绘制视图,没有隐藏网页。收起时释放详情的无障碍动作和临时选项列表,保留下一次即时展开所需的摘要。主题切换只改变同一视图的颜色和外观;动画有明确结束时间,闲置时没有持续循环动画。
收起不等于结束宿主进程,也不等于释放 AppKit 的所有字体、菜单和图形缓存。为降低读数而反复重启宿主,会影响菜单栏和浮窗连续性,因此该版本没有采用这种方式。
macOS 独立主面板的历史观察
| 方面 | 收益或代价 |
|---|---|
| 内存回收 | 主面板进程退出后,系统能回收其界面缓存和统计服务占用 |
| 窗口连续性 | 主面板开关不打断菜单栏与浮窗 |
| 主面板打开期间 | 比单 GUI 方案多一个 GUI 进程 |
| 实现复杂度 | 需要同步偏好、动作和扫描所有权,并处理跨进程生命周期 |
v1.0.0 发布文档记录的一次使用过程观察中,两次主面板开关后,独立主面板方案收起浮窗约 24.83 MiB,稳定单 GUI 候选约 54.85 MiB;冷启动两者接近。这不是严格受控实验,也不是单独更换语言带来的收益。完整条件、峰值和缺口见 验证范围。
额度弧线配色
此配色自 v1.0.1 发布;v1.0.0 发行包使用固定绿色弧线。实现位于 Sources/Capsule.swift 的 CapsuleQuotaColors 与 drawOrb(),作用于浮窗收起时的额度圆弧。
弧长与颜色使用同一个剩余额度比例。整段剩余弧线只有一种颜色,随额度变化在下表相邻色点之间对 sRGB 分量作线性插值。例如 62.5% 位于 75% 和 50% 两种颜色之间,经过色点时连续过渡。两种主题的色点如下:
| 剩余额度 | 颜色 | 深色主题 | 浅色主题 |
|---|---|---|---|
| 100% | 翡翠绿 | #35DE94 | #009E68 |
| 75% | 黄绿色 | #A5D76D | #708F30 |
| 50% | 琥珀色 | #E9BC60 | #AF811B |
| 25% | 暖橙色 | #F09858 | #C97432 |
| 10% | 珊瑚红 | #EE786E | #D76053 |
| 5% | 警示红 | #EA6565 | #D4474F |
深色主题使用较明亮的颜色,浅色主题加深色值以保持辨识度。弧线表示当前「周余」等标签所指的账号额度;Token 数值仍由独立的时间、模型和任务筛选决定,不能用 Token 数量反推额度百分比。
0 < 剩余额度 ≤ 5%时保持警示红;0% 不绘制剩余弧线,只显示中性底环与0%。- 缺失或非有限额度显示「—」与中性底环;有限但越界的比例限制在 0–100%。
- 旧快照沿用该快照的颜色,并在数值后保留
*标记。颜色不代表数据已经刷新。
两组色点各初始化一次。实际额度改变时,颜色读取现有 0.22 秒动画中的 liquidFraction,与弧长同步;没有新增闲置计时器或循环动画。浮窗隐藏、已展开或系统启用「减少动态效果」时,额度直接更新。主题切换继续复用同一个窗口和绘制视图。此变更没有重新测量整机内存,不能由色点数量推导完整应用的内存占用。
macOS v1.0.1 的数据与权限边界
主面板 HTTP 服务使用实例标识隔离请求,退出时清理自己的状态与进程。账户额度通过本机 Codex app-server 的固定只读方法取得,代码没有重置卡兑换动作。
共享偏好写入宿主域:宿主使用 UserDefaults.standard,主面板使用宿主 suite。共享域不可用时明确失败,避免静默写入错误的偏好域。文件位置与隐私说明见 统计与隐私。
页面依据
进程与内存设计对应版本 v1.0.1 的 架构文档、README 与 验证记录。
配色章节对应 v1.0.1 架构文档。