English | 简体中文
Understand how Codex and Cursor are being used on your Mac, how much quota or exact usage is available, and whether the underlying data is reliable.
Codex Pulse is a local-first, native macOS app. It turns Codex and Cursor sessions, usage records, and source health scattered across your machine into a menu bar status view and a drill-down analytics interface, while making data freshness, completeness, and health explicit.
Captured from a real Codex Home. Navigation and general product copy are preserved, while account, project, session, model, numeric, date, and runtime details have been irreversibly redacted. Chart shapes, colors, and layout are preserved.
- Menu bar: Pin Codex quota, Cursor's exact usage, Grok credits, or DSH token usage without changing the provider selected in the main window. If every client is disabled, the menu bar shows
Codex Pulse --. - Usage analytics: Explore tokens, models, API-equivalent cost, and activity distribution across overview, session, and project pages.
- Session cache hit rate: See cached input as a percentage of all input tokens in Codex session lists and details. Missing or invalid counters stay unavailable.
- Provider controls: Enable or disable Codex, Cursor, Grok, and DSH independently in Settings. Discovery is metadata-only. A disabled client stays off across restart, wake, and rediscovery. The main window and popover only list enabled clients; Settings stays reachable when none are enabled.
- Provider context: Switch the main window among enabled Codex, Cursor, Grok, and DSH clients; every query remains scoped to one provider and unsupported metrics stay explicitly unavailable.
- Data status: Inspect provider-grouped sources, local indexing, and background jobs to understand whether reported results are complete.
- Codex Pro tier: The current ChatGPT account maps App Server
prolitetoPro 5×andprotoPro 20×. Missing, unsupported, or conflicting plan evidence staysPro · 档位未知. - Codex accounts: Settings keeps detected and manual Codex accounts on this Mac. A separate Account Quotas page gives the current and retained historical ChatGPT accounts the same compact account-card visual, then renders only the quota windows actually returned for each account. Every window is labeled from its real duration and shows its last verified percentage, reset time, state, and collection time. Historical cards are read-only. Settings controls whether future confirmed account switches retain the previous quota snapshot and provides an explicit cleanup action; this never changes Home-level sessions, tokens, projects, or cost attribution.
| Area | What you can see |
|---|---|
| Menu bar | Remaining quota, cumulative tokens, reset times, and health alerts |
| Overview, sessions, projects, and account quotas | Trends and heatmaps, model and cost breakdowns, project-linked sessions, and the last retained quota snapshot for each observed ChatGPT account |
| Status and settings | Quota periods and sources, indexing progress and freshness, background jobs, local storage, and settings |
The main window includes overview, session, project, and quota pages. Runtime diagnostics, data sources, and settings live in the System section. Use the menu bar for current status and the main window for usage details and data health.
The following screens were captured from a real Codex Home under the same redaction policy: fixed navigation and product copy remain readable, while dynamic project, session, model, numeric, cost, and time data has been irreversibly transformed.
The most misleading failure mode for quota and usage tools is not missing data—it is presenting fallback values as facts. Codex Pulse follows these display rules:
0%is shown only when exhaustion has been confirmed. Values that were never retrieved, have not been calculated, or do not apply are shown as--.- If an online refresh fails but a previous successful result exists, the last-known-good value remains visible instead of suddenly changing to 100%. Last-known-good stays inside the current confirmed ChatGPT account; switching accounts never reuses the previous account's percentage.
- Codex online quota and Reset Credits come from the Codex App Server public method
account/rateLimits/read. Pulse does not read Codex access tokens, JWT,auth.json, or Keychain credentials, and it does not call private WHAM endpoints. A CLI that lacksaccountIdcapability fails closed instead of falling back to WHAM. - Refresh diagnostics stay in the private app runtime under
logs/: bounded, rotated JSONL records retain only fixed stages, numeric codes, and timing. An unresolved fault summary preserves the first failure until recovery. Quota and reset-credit decoding are isolated; transient worker stops can be recovered with Refresh quota, while storage protection stays in force. See the refresh reliability runbook. - Unconfirmed, signed-out, or identity-unavailable Codex accounts show unknown / pending (
--). The UI does not invent0%or100%, and it does not keep the previous account email or limits. - Codex Pro 5×/20× comes only from matching App Server
planTypeevidence collected inside the account sandwich read. Pulse never infers a tier from remaining percent, tokens, windows, reset time, or Reset Credits. - Codex monthly renewal days and membership expiry dates are manual only in this release. Pulse does not treat token expiry, quota reset time, or Reset Credit expiry as a membership date.
- Local sessions, tokens, projects, trends, and API-equivalent cost stay aggregated for the current Codex Home. They are not filtered or attributed by ChatGPT account.
- Optional center account cards separately show newly recorded Codex tokens in the actual current weekly quota cycle. Only confirmed account observations count; ambiguous switch deltas and past usage are skipped. See account cycle tokens.
- A time range that has not been fully indexed is marked as partial data rather than presented as a complete total.
- Quota names and periods come from current data. For example, period labels are derived from the actual
window_minutesvalue instead of hard-coding a "5-hour quota." - Currency values are always labeled as "API-equivalent cost." They help explain the public API price scale associated with token usage and do not represent an actual bill or charge.
All indexing and analytics run locally. Cursor usage and spending can additionally be refreshed from Cursor's authenticated Dashboard service by reusing the current Cursor Desktop session:
- Local Codex and Cursor sessions are discovered read-only. Structured results stay in local SQLite; conversation bodies, prompts, responses, thoughts, tool payloads, tracked file content, raw paths, credentials, and RPC tokens are not persisted.
- Online quota, reset-credit, and Cursor Dashboard requests use credentials only in memory for the duration of a request. Dashboard access tokens are read from Cursor's WAL-aware state database and are never copied to preferences, logs, RPC responses, or Codex Pulse SQLite. There is no Codex Pulse cloud sync or public network endpoint.
- The Swift app and Go Helper communicate only over a private Unix Domain Socket. Logs, errors, and UI responses exclude raw payloads, full paths, and underlying error details.
The original Codex and Cursor files remain managed by their applications. Codex Pulse stores only the allowlisted indexes, aggregates, lineage digests, and runtime state required by the product, and never modifies original session content.
On first launch, the Go Helper initializes Preferences v5 even when Codex Home is missing. A metadata-only safety probe of ${CODEX_HOME:-$HOME/.codex} runs without reading session bodies; a safe Home is stored as a stable identity. If the directory does not exist or the probe fails, Codex Pulse still starts: Settings, Cursor, Grok, and DSH remain available, while Codex indexing, quota, and account work stay unavailable until a Home is configured. Changing Codex Home later still requires explicit confirmation in Settings. Disabling a provider stops local collection, online requests, credential refresh, query-triggered refresh, and current summaries; history, progress, and sub-switch preferences are kept. Settings previews legacy unassigned local quota history and uses it for the current account's historical charts only after explicit, reversible confirmation. The current handshake is core-rpc-v9 with provider-control-v1.
Codex Pulse consists of two local processes:
Local Codex data / optional online quota
│
▼
Go Helper: discovery, indexing, aggregation, scheduling, SQLite
│ Protobuf / gRPC over UDS
▼
Swift app: menu bar, windows, interactions, and Helper lifecycle
api/codexpulse/core/v1/core.proto defines the cross-process contract. The Go Helper reads, indexes, and aggregates data. The Swift app calls it through the generated CoreService client and neither reads SQLite or JSONL directly nor reimplements aggregation in the UI layer.
Requirements:
- macOS 15+
- Apple Silicon
- Go 1.26.2
protoc 34.1
Local runs use the real ${CODEX_HOME:-$HOME/.codex}. The following command reads session/JSONL data read-only and may write SQLite, preferences, runtime logs, and standard App Server housekeeping data inside a private app runtime. It does not modify original session content:
make verify-livemake verify-live builds the development app, reuses a confirmed private runtime, and launches the app against the real Home. CI, unit tests, and deterministic smoke tests use a synthetic or empty Home so they do not read personal data.
The Development bundle and an unbundled swift run executable refuse the installed product runtime at ~/Library/Application Support/Codex Pulse/runtime. Development launches must pass an isolated /private/tmp/cp-* or /tmp/cp-* runtime explicitly; only the installed production bundle may use the persistent product database by default.
For routine development, prefer the affected Go package tests or Swift executable tests. Common commands:
# Go and Swift test suites
make test-go
make test-swift
# Pre-commit product checks
make check
# Full PR/CI verification with an isolated Home
make verify
# Assemble a local unsigned preview candidate without creating a tag or GitHub Release
scripts/macos/build-release-app.sh \
--version 0.1.0-beta.1 \
--build-number 4 \
--sparkle-feed-url \
https://github.com/SisyphusSQ/codex-pulse/releases/download/updates/appcast.xml \
--sparkle-public-key-file \
/secure/path/codex-pulse-sparkle-public.key
# Regenerate Go and Swift sources after changing the Proto contract
make generate-protoRelease candidates are written to .artifacts/releases/<tag>/. Each candidate includes a first-install DMG, an Apple Silicon app ZIP with Sparkle embedded, and SHA256SUMS covering both assets. The DMG provides the standard drag-and-drop path from Codex Pulse.app to /Applications; the appcast continues to point only to the exact ZIP. The public key file may be public, but it must match the private key supplied through stdin when signing the appcast.
Stable and preview are product release channels. macOS trust is recorded separately as unsigned or signed-notarized. Stable defaults to unsigned stable: release assets use ad-hoc signing, and Release Notes must disclose that Developer ID signing and notarization are incomplete, the build is not Gatekeeper-trusted, and first launch requires choosing Open Anyway in System Settings → Privacy & Security. A remote release must also pass independent readback of the tag, Release, asset digests, pinned appcast, and first-launch flow. signed-notarized is an explicit opt-in and is allowed only after signing, notarization, Gatekeeper verification, and final asset readback all pass in the release environment. Preview releases continue to use prerelease SemVer and select either unsigned or signed-notarized assets according to what was actually produced.
Main directories:
| Path | Responsibility |
|---|---|
app/macos/ |
Native SwiftUI/AppKit app, Core client, and executable tests |
api/codexpulse/core/v1/ |
Protobuf contract and generated code |
internal/ |
Go Helper indexing, queries, scheduling, persistence, and runtime implementation |
docs/design/ |
Product, architecture, data, quota, scheduling, and observability design |
docs/test/ |
Test guidance and redacted result summaries |
Start with these documents for more detail:
可选中心位于 server/,React/AntD Web 通过 Go embed 编入 Server,以单个二进制提供同源页面和 API;构建运行和 SQLite/MySQL 备份入口见 运行说明。原生 App 仍为本地采集与 UI,设置中配对、选择历史范围并显式启用上报;退出停止,下次增量补采。中心仅接收白名单元数据、统计、配额和 TPS,不接收原始记录或 Agent 凭据。中心启动自动初始化或升级已登记的表结构;开发与正式配置的本地账密副本已 Git 忽略,采用二进制部署。中心结构按已有读回分层,后一次记录不覆盖前一次的失败、部分完成或未执行项。2026-10-03 的 v0.15.1/build 64、生产 schema 2→3 与 SeekDB 部署见联调与发布读回;同日中心 schema v4 的构建是 v0.15.1+center.9dbb1c5,SQMC04 生产与 DEV 读回见查询保留与交接。2026-10-05 的 v0.15.3/build 66 将生产 schema 从 v4 升到 v5,见账号周期 Token。2026-10-06 的 v0.16.0/build 67 与 v0.16.1/build 68 见DSH 验证:生产中心读回为 v0.16.1-53bcfc9,schema 仍为 v5;三台 Mac 该次读回为 0.16.1/build 68,本机 SQLite v37、Preferences v5。独立 MySQL 8.4、三机完整故障矩阵、Sparkle 更新界面完整 E2E、公证和长期稳定性仍未关闭。DSH 生产读回收到会话不能写成完整 Mac→Server→Web E2E。
首次打开中心地址会显示浏览器授权页;部署者在 Server 终端使用服务的同一配置运行 db bootstrap,取得 10 分钟有效的一次性管理员码,再在浏览器输入。浏览器会话当前有效期为 14 天;全部浏览器授权失效时可通过同一命令恢复,无须重建数据库。完整流程见首次浏览器授权与访问恢复。
DSH Mac 桌面版默认从 ~/.dsh/sessions 导入官方 V3/V4 JSONL 和 Zstd 会话,支持现有 Session、项目、模型、缓存、活动、吞吐量、本地工具统计和可选中心上报。Mac 和中心 Web 均保持独立 dsh 客户端范围。全部费用以美元展示,按实际模型路由与请求起始时间选价:DeepSeek 使用峰谷 API 公价,openai-codex 使用已有 OpenAI Standard 基础文本历史价格。费用为 API 公价估算,桌面账户或 Codex 订阅的实际扣费与官方额度不由日志推定。价格、格式、隐私和早期历史 unknown 边界见 DSH 设计,验证见 DSH 验证记录。



