A WXT-based browser extension that enhances the ChatGPT Codex Analytics page.
It visualizes token usage, activity, model distribution, and client distribution from the analytics responses already requested by the page.
When you open ChatGPT Codex Analytics, the extension appends enhanced content below the official analytics charts:
| Chart | Contents |
|---|---|
| Token usage trend | Cached input, uncached input, output, and total tokens (area chart) |
| Credits usage trend | Credits usage over time (area chart) |
| Activity | Users, threads, and turns (bar chart) |
| Model distribution | Usage share by model (doughnut chart) |
| Client distribution | Usage share by client, such as Web and Codex (doughnut chart) |
- The aggregation period follows the official Analytics page: day / week / month
- Summary cards for user activity days, turns, thread activity, credits, total tokens, and date range
- The enhanced panel can be collapsed and updates after the official page receives new data
- Dark and light theme support
- Standard WebExtension i18n with English and Simplified Chinese catalogs; the browser extension locale selects the UI and Chrome Web Store listing text
- WXT — Next-generation Web Extension framework
- Vue 3 — UI for the injected analytics panel
- ECharts 6 — On-demand chart modules for visualizations
- Lucide — Vue SVG icon library
@wxt-dev/i18n— WXT's type-safe wrapper around the standard WebExtension i18n API- Shadow DOM — Isolated styles for the injected panel
chatgpt-analytics/
├── .github/workflows/ # CI and draft release workflows
│ ├── ci.yml
│ └── release.yml
├── entrypoints/
│ ├── analytics-interceptor.content.ts # Main-world fetch/XHR response observer
│ ├── stats.content/ # Content script for the Codex Analytics page
│ │ ├── index.ts # Shadow DOM UI mounting
│ │ ├── App.vue # Panel state, layout, and usage details table
│ │ ├── chart-options.ts # ECharts option builders
│ │ └── theme.ts # Panel theme colors
│ └── popup/ # Extension popup
│ ├── index.html
│ ├── main.ts
│ ├── App.vue # Analytics page link
│ └── style.css
├── locales/ # Source localization catalogs
│ ├── en.json
│ └── zh_CN.json
├── utils/
│ ├── types.ts # Analytics response types
│ ├── config.ts # Panel configuration and chart palette
│ ├── api.ts # Response listening, parsing, and normalization
│ ├── charts.ts # Data aggregation and panel view data
│ └── page-bridge.ts # Main-world / isolated-world event bridge
├── public/icon/ # Extension icons (16 to 512 px)
├── wxt.config.ts # WXT configuration
└── package.json
Install the published extension from a browser store:
After installation:
- Open ChatGPT Codex Analytics while signed in to your account.
- Scroll below the official analytics charts to view the enhanced panel.
Prerequisites: Node.js >= 22 and Chrome or Firefox.
# 1. Install dependencies
npm install
# 2. Start development mode
npm run dev
# 3. Build a production extension
npm run build- Run
npm run build(ornpm run packto also generate.output/chatgpt-analytics-*.zip). - Open
chrome://extensions/. - Enable Developer mode in the top right.
- Click Load unpacked and select
.output/chrome-mv3. - Open ChatGPT Codex Analytics and view the enhanced content below the official charts.
To load the packaged zip instead of the unpacked folder, drag .output/chatgpt-analytics-*.zip onto chrome://extensions/.
- Run
npm run build:firefox. - Open
about:debugging#/runtime/this-firefox. - Click Load Temporary Add-on and select
.output/firefox-mv3/manifest.json. - Open the Analytics page.
# Chrome
npm run zip:chrome
# Outputs .output/chatgpt-analytics-<version>-chrome.zip
# Firefox (includes MV3 extension archive and source code archive)
npm run zip:firefox
# Outputs .output/chatgpt-analytics-<version>-firefox.zip and .output/chatgpt-analytics-<version>-sources.zipThe actual archive name includes the version from package.json.
- CI (
ci.yml): Runs Lint, Type check, Chrome/Firefox builds, and Manifest validation on pushes and PRs tomain. - Build Draft Release (
release.yml): Automatically packages Chrome and Firefox MV3 archives plus source code archives, and creates a GitHub Draft Release upon pushing av*tag or manual dispatch. - Publish Extension Stores (
publish-stores.yml): Triggered only when a Draft Release is manually published (and only for non-prerelease tags), uploading archives to the configured stores (Chrome Web Store / Firefox AMO) viawxt submit.
Update the version, commit, and push the matching v* tag:
npm version patch --no-git-tag-version
git add package.json package-lock.json
git commit -m "chore: release v1.0.1"
git tag v1.0.1
git push origin main v1.0.1Review the draft release on GitHub Releases, then click Publish release. The publish-stores.yml workflow will automatically submit the release to configured stores.
Configure the following secrets under Settings -> Secrets and variables -> Actions:
FIREFOX_EXTENSION_ID: Extension ID (e.g.[email protected]or AMO UUID)FIREFOX_JWT_ISSUER: Mozilla AMO API key Issuer (also acceptsAMO_JWT_ISSUER)FIREFOX_JWT_SECRET: Mozilla AMO API key Secret (also acceptsAMO_JWT_SECRET)
CHROME_EXTENSION_ID: Chrome Extension IDCHROME_PUBLISHER_ID: Publisher UUID (required by the v2 API pathpublishers/{id}/items/{id})CHROME_SERVICE_ACCOUNT_CLIENT_EMAIL: GCP service account email, bound in the CWS Developer DashboardCHROME_SERVICE_ACCOUNT_PRIVATE_KEY: Service account private key, stored as a real PEM (jq -r .private_key key.json)
Setup steps for the v2 credentials: see chatgpt-markdown-exporter AGENTS.md.
If the default npm cache is read-only, use a writable cache directory:
export npm_config_cache=/tmp/npm-cache
mkdir -p /tmp/npm-cache
npm installIf /tmp is not writable, use another writable directory such as ~/Projects/.npm-cache.
- The extension does not actively request the analytics endpoint and does not read or store tokens. A main-world content script observes the
fetch/XHRresponses already requested by the Analytics page, so the page's own cookies,Authorizationheader, and other request headers are used. - The popup only opens the Analytics page and does not request internal data or require additional cookie permissions.
- Localization follows the browser's extension UI locale, as required by the standard
browser.i18nAPI; changing it requires changing the browser language. - The endpoint is an undocumented internal OpenAI endpoint and may change without notice. If the page changes its response format, update
utils/api.ts. - If the official page does not request a particular aggregation period, the extension does not issue a replacement request.
- A direct
curlrequest normally returns 401 without the browser session cookies.
This project is an independent community extension and is not affiliated with, endorsed by, or sponsored by OpenAI or ChatGPT. It relies on undocumented internal endpoints and page behavior that may change or stop working at any time. Use it at your own risk; no guarantee is made regarding data accuracy, availability, or compatibility.
MIT