Omarchy 顶栏 Agents 面板指南:集中监控 Claude Code、Codex 与 Fireworks 的订阅额度与用量
2026/9/9 21:08:45 网站建设 项目流程

Omarchy 顶栏 Agents 面板指南:集中监控 Claude Code、Codex 与 Fireworks 的订阅额度与用量

【免费下载链接】omarchyBeautiful, Modern & Opinionated Linux项目地址: https://gitcode.com/GitHub_Trending/om/omarchy

Omarchy 是一个「美丽、现代且高度定制化」的 Linux 桌面环境。其内置的omarchy.agents插件(AI 订阅用量面板)为每台机器上每一个已安装的 AI 编码订阅(Claude Code、Codex、Fireworks 等)提供一个顶栏图标与一个原生面板,让你随时掌握额度消耗、节奏(pace)、今日用量、最近一周趋势与全量模型消耗,而无需打开各家控制台。读完本文,你将掌握该插件的界面语义、底层数据管线、配置方式、跨设备同步方案,以及如何为新的 AI 编码代理扩展出面板标签。

插件的核心设计:面板只负责「展示」

omarchy.agents面板在架构上被刻意设计成一个纯展示层。根据 插件 README 的说明:面板只监视omarchy-agent-usage-update命令写入~/.local/state/omarchy/agents/usage/目录的用量记录,然后把里面出现的内容原样画出来——它从不直接解析 CLI 的磁盘格式,也从不直接调用各家远程 API。

这套「数据采集与展示解耦」的架构,由三个 QML 文件 + 一个更新命令协同实现:

  • Panel.qml 拥有顶栏按钮与弹出面板,负责 UI 交互与渲染;
  • Main.qml 负责发现并监视记录文件,同时处理可选的跨设备汇总(sync),以及定时刷新逻辑;
  • Agent.qml 是单个记录文件的 watcher——用FileView监视一个 JSON 文件的变化,文件更新就重新解析;
  • omarchy-agent-usage-update 是写入者:它为每个 agent 运行一个omarchy-agent-usage-<agent>采集器,把各采集器打印的标准 JSON 原子地写入 usage 目录。

Main.qml的注释点明了这一分工的关键收益(见 Main.qml):所有提取逻辑都藏在omarchy-agent-usage-update背后,界面只做「发现记录、监视变化、合并快照」三件事。因此新增一个 agent 永远不会改动这个插件本身——只要新增一个采集器脚本,面板就自动获得一个标签页。Agent.qml的实现进一步印证了这点:面板并不知道数字是怎么算出来的,「只要出现在 usage 目录里的记录就是一个 agent,无论它由谁写入」(见 Agent.qml)。

面板界面逐块拆解

面板被设计成一个信息密度较高的「仪表盘」,打开即可阅读限额和历史,尽量无需滚动(见 Panel.qml)。从上到下各区块如下:

Hero:身份区

显示订阅方的mark(徽标)、工具名称与当前运行的订阅计划,例如 "Max 20x"、"Pro"。认证或端点问题发生时,计划行会被替换为状态说明文字,并额外以卡片形式重复展示一次(authHelpText)。Hero 的 meta 行逻辑在 Panel.qml 的 heroMeta():当usageStatusText非空时优先展示状态,否则展示tierLabel计划名。

计划名的来源值得注意:Claude 采集器会把登录凭据里的rateLimitTier/subscriptionType规整成可读标签——例如从 tier 字符串max_20x解析出 "Max 20x"(见 omarchy-agent-usage-claude 的 plan_label()),而 Fireworks 直接固定标注tierLabel: "Prepaid"(见 omarchy-agent-usage-fireworks)。

订阅切换(Subscription switch)

每个已启用的 agent 对应一个 chip,用h/l或点击切换。它只在启用了一个以上 agent 时出现(见 Panel.qml)。只有一个订阅时不会显示切换行;一个都没有时整个模块会从顶栏消失,而不是放一个空荡荡的图标在那里。这就是文档所说的「宁可消失、绝不空置」原则。

额度(Limits)

展示每个额度窗口的已用百分比、对应计量条(Meter)以及会话/周窗口重置的倒计时。两端口的窗口语义差异在面板中被归一化:Claude 把它写成 "Session (5-hour)"、Codex 缩写为 "5h window"/"30m window",面板通过 windowIsLong() / windowTitle() 统一识别为 Session/Weekly/Monthly 三种形态。比例 >= 0.9(即用掉 90%)的行会被标记为警示色(alarming,见 Panel.qml LimitRow)。每行下方还会显示 "Resets in Xd Yh / Xh Ym" 之类的倒计时(resetMsFor() / formatDuration())。

余额(Balance)

预付费(prepaid)类 agent(目前即 Fireworks)不报告 rate-limit 窗口,而是报告一个信用卡台账(credit ledger):剩余信用额、一根越用越空的「油量表」、以及 funded-versus-spent(已充值 vs 已花费)明细。余额仪表的警示阈值是剩余低于充值的 10%(见 Panel.qml)。余额明细文本在 balanceDetailText() 中生成,例如 "$5.20 spent of $20.00 funded · estimated"——当余额是估算值时,会额外标注 "· estimated"。

按天 Token 用量(Tokens by day)

最近 7 天每天一行:星期几、比例条、token 数,今天的行加粗放在最底部并高亮(见 Panel.qml DayRow)。把鼠标悬停在今天上可以看到该日的prompt 数与 session 数(见 dayTooltip())。比例条以一周中最忙的一天为基准缩放(scale-to-peak)。

按模型 Token 用量(Tokens by model)

按模型列出 token 消耗,每一行背后的比例条以最重的模型为基准缩放(与周图以最忙日缩放是同一套逻辑,见 Panel.qml ModelRow)。悬停可查看input / output / cache read / cache write的拆分(modelTooltip())。模型行只显示用量最高的 4 个(modelRows()),并且模型 ID 会经过 friendlyModelName() 的美化:把claude-opus-4-8gpt-5.6-sol这类连字符 ID 重排为 "Opus 4.8"、"GPT 5.6 Sol" 这样易读的名字。

数据目录与记录契约

每个 agent 对应~/.local/state/omarchy/agents/usage/下的一个 JSON 记录文件,由omarchy-agent-usage-update写入。update 脚本本身(bin/omarchy-agent-usage-update)非常透明:

  • 遍历$OMARCHY_PATH/bin/omarchy-agent-usage-*下所有可执行采集器(跳过update自己);
  • 支持参数:--force(无视缓存强制重扫与重新探测额度)、--limits-only(只刷新远端额度、复用本地统计)、--except <agent>(跳过某 agent)、以及末尾可指定的[agent...]白名单;
  • 每个采集器并行运行,各自先把输出写到mkstemp临时文件,校验通过为合法 JSON 后再mv原子替换为<agent>.json,避免面板读到半截文件。

命令行对应的实际用法为(omarchy:examples元数据,见脚本头部注释):

omarchy agent usage-update # 刷新全部 omarchy agent usage-update claude # 只刷新 claude omarchy agent usage-update --except codex # 跳过 codex

面板侧的数据流完全围绕这个目录展开:Main.qmlfind ... -name "*.json"做目录发现,并用Instantiator为每个发现的 JSON 动态实例化一个 Agent.qml。Agent.qml内的FileView设置了watchChanges: true,一旦文件落盘即触发解析;若 JSON 解析失败,则把record置空并打出警告(见 Agent.qml)。面板不关心是谁写了这些文件——这意味着哪怕你不用面板自带的刷新定时器,只要别的工具往该目录投递了符合契约的记录,面板同样会立即呈现。

在面板打开 / 关闭与记录变化的驱动下,Main.qml会周期性(默认 900 秒)触发一次omarchy-agent-usage-update;用户按下刷新时则使用--force。此外,打开面板时只触发一次--limits-onlyrefreshLimits()——因为用户此时想要的是会过时的远端数字,而不是再对磁盘上每个 transcript 重新走一遍(见 Main.qml refreshLimits() 及注释)。一个值得注意的细节:若某采集器在记录里写了retryAdvised(典型的场景是登录后头几秒网络路由尚未就绪,连不上远端),Main.qml会在 30 秒后只对标记了该字段的 agent提早重试一次,而不是把每个采集器都拖上 30 秒的循环(见 Main.qml)。

各采集器的数据来源

下表来自 插件 README,概括了三个内置采集器的取数通道:

采集器Limits(远端额度)Local stats(本地统计)
claudeAnthropic 的 OAuth usage endpoint(5 小时会话窗口 + 7 天周窗口)~/.claude/projectstranscripts、运行在 Anthropic provider 上的 opencode sessions,外加stats-cache.jsonhistory.jsonl兜底
codexCodex app-server RPC原生 Codex CLI session 文件(以及 pi、opencode 的 sessions)
fireworks估算的预付费余额:配置的 funding 减去按费率核算的账户开销Fireworks billing API,按最近 30 天以天/模型分组

Claude 采集器内部流程

omarchy-agent-usage-claude 是本插件的取数样板。main()的组装顺序(见其 main())展示了多层数据源是如何融合成一个记录的:

  1. Transcript 扫描:递归扫描~/.claude/projects下所有*.jsonl,先做"usage":的廉价行级预过滤,只统计 assistant 消息,按 message id 去重,拆出 input/output/cacheRead/cacheWrite 四种 token 与模型归属;
  2. 兜底链路:当 transcript 扫描结果为空时,依次尝试stats-cache.json(聚合计数器)与history.jsonl(按天的 prompt/session),保证「磁盘上没有 transcript 的机器」仍能报出今日数据;
  3. pi/omp 与 opencode 会话合并:通过.pi/agent/sessions.omp/agent/sessions~/.local/share/opencode/opencode.db(以只读 URI 方式打开 SQLite,避免与正在写入的 opencode 冲突),统计所有跑在 Anthropic provider 上的消息并merge_stats()合并进主记录;
  4. 额度探测:从.credentials.json读取 OAuth access token(token 只用于探测请求的 Authorization 头,绝不写入记录),请求 Anthropic 的 OAuth usage endpoint(带anthropic-beta: oauth-2025-04-20头)。

额度解析做了很多兼容性工作:Anthropic 端点目前按百分比上报(如 37.0、1.0),旧 payload 有时用小数(0.37),采集器用「任一值 >= 1 即按百分制」的规则统一归一化(见 normalize_utilization());limits数组里的模型级配额(比如某周窗口只被 Fable 消耗)也被显式解析成带标题的窗口(scoped_limits()),原因是seven_day_opus这类旧 key 已经留在 null,只读 flat bucket 会悄悄漏掉账户真实在消耗的额度。Claude limits 需要登录过的 CLI:无凭据时authHelpText会提示运行claude auth login,面板只展示本地统计(见 README 及 AUTH_HELP)。若保存的 token 已过期但窗口中还留有上次的缓存数字,记录会标 "Sign-in expired" 并回退展示「窗口尚未重置」的最近已知值(collect_limits())。非默认目录通过环境变量指定:CLAUDE_CONFIG_DIR(Claude)、CODEX_HOME(Codex)。

Fireworks 余额与配置

Fireworks 是「预付费」路径的样板。其采集器(omarchy-agent-usage-fireworks)的 token 统计来自 billing API(按天/模型、最近 30 天、本地时区边界换算成 UTC 窗口发出查询),额度则是一个估算余额

README 明确交代了一个特殊事实:采集器会先尝试账户的:getBalance端点获取真实的预付费台账——该端点存在但被权限门控,截至 2026 年 8 月,控制台签发的 API key 都无法通过它(Fireworks 似乎将其保留给 dashboard 会话)。该探测之所以保留,是因为它很廉价,而且一旦 Fireworks 向 key 开放,实时数字会自动点亮(见 live_balance())。在那之前,余额靠~/.config/omarchy/agents/fireworks.json的配置估算:

{ "accountId": "", "fundedAmount": 20, "fundedAt": "2026-07-01" }

配置语义(README 原文要点 + 源码印证):

  • fundedAmount:你实际购买的信用额(美元)。不配置时,标签页仍会显示 token 用量,只是没有余额;
  • fundedAt:购买日期(ISO 格式)。省略时采集器使用账户创建时间。后续追加充值(top-up)时,应把fundedAmount增加新信用额、同时保留最初的fundedAt,这样 funding 与 spend 仍覆盖同一时间段,估算才不失真;
  • accountId:仅当一个 API key 能访问多个账户时才需要——对应源码里discover_account()发现多个账户时抛出的错误提示 "Set accountId in fireworks.json when the API key can access multiple accounts"(见 omarchy-agent-usage-fireworks)。

采集器计算剩余 = max(0, funded - spent),其中 spent 来自账户的 usageCosts 查询(subtotal 不可用时回退到 billing/summary 的 lineItems 求和,见 spent()),并把记录标记为"estimated": truescope: "account"。Fireworks 的凭据读取顺序为:先FIREWORKS_API_KEYFIREWORKS_ACCOUNT_ID环境变量,其次~/.fireworks/auth.inifirectl set-api-key创建的 INI,兼容 default section 或任意 section 里的 api_key/account_id),最后才是 opencode 在~/.local/share/opencode/auth.json里存下的 Fireworks key(credentials())。

Fireworks 记录还声明了两个影响面板与跨设备合并的字段(base_record()):scope: "account"(billing API 的数字是账户全局的,不是单机本地的,因此跨设备聚合不能简单相加),以及hasPromptStats: false(billing API 只报 token,从不报 prompt/session 数,面板因此在 today 的 tooltip 里不显示 "0 prompts" 以免被误读为安静的一天)。

顶栏图标与键盘/鼠标/IPC 交互

顶栏图标的行为在 Panel.qml 的按钮事件处理 中有明确实现:

  • 左键:打开/关闭面板(toggle);
  • 右键:启动 agent(调用omarchy-agent --pick选择并启动);
  • 中键:切换到下一个订阅(next subscription);
  • 额度或余额进入警示状态(任一窗口 >= 90% 或余额低于 10%)时,图标高亮为警示色(active: root.alarming)。

面板内键盘操作(README Interactions 部分):

  • h/l:切换订阅;
  • j/k:滚动内容;
  • r或 Enter:刷新;
  • Tab:移动到相邻的顶栏面板;
  • Esc:关闭。

面板与外部通信走 IPC,命令形式为:

omarchy-shell omarchy.agents <open|close|toggle|refresh|next>

对应的 IPC handler 在 Panel.qml 中注册:refresh返回"ok"next把选中项推进到下一个 provider。此外面板打开期间会每 30 秒重算一次nowMs,确保「resets in Xh」这类倒计时在面板一直开着时也保持准确(见 Panel.qml)。

配置项与omarchy bar set命令

插件的设置存放在~/.config/omarchy/shell.json中该 widget 的条目下,顶层键可以用命令设置。完整键位表(README Settings 部分):

Key默认值作用
refreshIntervalSec900用量记录多久重新生成一次
syncMode"Off""On"时写入本机快照并合并其他机器的快照
syncDir""由 Syncthing、Dropbox、rsync 等同步的文件夹
syncFileName<hostname>.json本机快照文件名
syncDeviceIdhostname快照内部的稳定设备名

数字类型的值必须用--json,否则会以字符串形式写进shell.json

omarchy bar set omarchy.agents refreshIntervalSec 300 --json omarchy bar set omarchy.agents syncDir '~/Sync/agent-usage'

manifest.json中的 schema(见 shell/plugins/agents/manifest.json)对取值范围给出约束:refreshIntervalSec为 integer,min 30、max 3600、步进 30;syncFileName描述为"Optional. Defaults to<hostname>.json. Use a different file name on each machine, such as laptop.json or desktop.json."——每台机器建议用不同的文件名(如laptop.jsondesktop.json),因为如果所有机器都用 hostname 默认名,同一文件夹里会出现文件名冲突。

各 agent 的启停是嵌套结构。由于set字面量写入键、不会遍历点号路径,所以传入整个providers对象时需要整块传 JSON(或直接编辑shell.json):

omarchy bar set omarchy.agents providers '{ "claude": { "enabled": true }, "codex": { "enabled": false }, "fireworks": { "enabled": true } }' --json

enabled对每个被发现的 agent 默认都是true;设为false可以隐藏一个已安装的订阅。被禁用的 agent 在记录重新生成时也会被跳过——Main.qml构造 update 命令时会为每个enabled === false的 provider 追加--except <id>(见 Main.qml updateCommand()),update 脚本侧则用wanted()过滤(见 omarchy-agent-usage-update)。

无订阅时的自我隐藏

「只在设置中启用、并且实际产生过用量(本机或同步过来的机器)的订阅才会出现」是一条硬性规则:只有一个时没有切换行,一个都没有时整个模块直接离开顶栏(见 README)。这种自隐藏正是 widget 能随默认顶栏布局一起出厂的原因——从未运行过任何 AI 编码 agent 的机器画不出任何东西,图标会在某次扫描第一次发现用量时自己出现。若想手动移除它:

omarchy plugin disable omarchy.agents

实现层面,Main.qmlenabledProviders会把「有本地记录且 enabled」「无本地记录但有同步数据且 enabled」的 provider 汇集起来,再用providerHasData()过滤出真正有数字的(见 Main.qml);而Panel.qmlvisible: providers.length > 0让整个槽位在无数据时坍缩出顶栏(Panel.qml)。反向场景也在代码里被照顾到:会话中途新装的 CLI会在下一次刷新时自然浮现,因为没有任何逻辑在磁盘上轮询等待某个特定 agent 出现。

跨设备汇总(sync):合并你所有开发机的用量

打开syncMode后,插件会把本机当前的用量快照写入syncDir下的<syncFileName>(默认<hostname>.json),并把该目录里每一个*.json快照合并起来。于是「今天」「最近 7 天」与「all-time」总量能覆盖你所有编码过的机器。

合并规则有几个关键细节(README 与 Main.qml 的 aggregateSnapshots() 相互印证):

  • 活跃天按日期取并集(union)而不是相加:两台机器在同一天工作,该日只计一次活跃;activeDaysmax(累加计数值, activeDates 并集大小)
  • 额度(rate limits)永远按账户各自独立,绝不跨设备合并;余额同理(两者都是账户级事实);
  • scope: "account"的记录取最宽值而非求和:Fireworks billing API 在每个同步设备上报告的是同一份账户全局事实,如果两台机器都同步它再相加,每个 token 都会被算两遍。设备级(默认devicescope)统计才跨机相加,账户级则用Math.max(见 combineNumber());
  • 快照保持旧版 Omarchy 字段名,让混跑不同版本的机器群双向合并依然干净(见 providerSnapshot() 的注释)。

面板底部的 footer 会在数字覆盖了不止本机时给出提示——例如 "Merged from 2 devices"(footerText())。同步管线本身是异步的:写快照前先mkdir -p目标目录,写完后用一个 bash 脚本扫描目录里所有*.json并解析为汇总数据,一次同步进行中又触发同步时会把请求排队、结束后重跑(见 Main.qml 的 sync 段)。

一个关于 "all-time" 的重要注意点(README 收尾的 caveat):Codex 采集器只读最近 30 天触碰过的原生 session 文件,Fireworks 也只向 billing API 请求最近 30 天,因此它们的 all-time 总量与天数都只覆盖这个窗口;Claude 的则覆盖仍留在磁盘上的每一份 transcript。跨来源对比 totals 时要留意这一语义差异。

为新的 AI 编码代理扩展一个标签

得益于纯展示架构,接入新 agent 的成本极低,且完全不需要改动面板插件。流程如下:

  1. bin/里新增一个可执行的omarchy-agent-usage-<id>采集器脚本(参考现成的 omarchy-agent-usage-claude、omarchy-agent-usage-codex 与 omarchy-agent-usage-fireworks),让它向 stdout 打印一份符合记录契约的 JSON(含idnamereadytoday*recentDaysmodelUsagelimits/balance等字段),面板即自动获得一个标签页;
  2. 可选:为它提供assets/<id>.svg徽标;如果该徽标在浅色表面上需要深色变体,再准备一个assets/<id>-light.svg。若两者都没有,面板会用模块自带的顶栏字形(bar glyph)兜底(见 Panel.qml iconCandidatesForProvider(),以及现有资产目录 shell/plugins/agents/assets 中的claude.svgcodex.svg/codex-light.svgfireworks.svg);
  3. ~/.config/omarchy/shell.json的 widget 设置里(或通过omarchy bar set)按需声明该 provider 的enabled状态。

采集器的 CLI 参数约定是统一的:接受--force--limits-only(Fireworks 因统计与余额来自同几笔 API 调用,这两个 flag 只是为保持所有采集器同一调用形态而存在,见其 main 注释)。records 每次刷新时,omarchy-agent-usage-update会自动发现并并行运行这个新采集器——插件对新增 agent 的支持本质上是「发布一个采集器」。

小结

omarchy.agents用一套「采集器写 JSON 目录、面板纯展示」的极简架构,把一个多订阅 AI 用量仪表盘做成了 Omarchy 顶栏的天然组成部分:Claude 的 5 小时会话 + 7 天周窗口、Codex 的 app-server RPC 额度、Fireworks 的预付费估算余额各有其数据通道与展示形态;按天/按模型图表、余额警示、账户级与设备级数据在跨设备同步中的正确合并、以及「无数据即自我隐藏」的出厂友好行为,都在这份设计里得到统一。想深入验证或二次开发,建议按序阅读 插件 README、Main.qml、Panel.qml、三个采集器脚本与 manifest.json。

【免费下载链接】omarchyBeautiful, Modern & Opinionated Linux项目地址: https://gitcode.com/GitHub_Trending/om/omarchy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询