Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Codex usage monitoring

This context describes the subscription-usage concepts presented by the widget.

## Language

**Displayed limit**:
The general Codex rate-limit window chosen for summary usage displays. It can be the 5-hour window, the weekly window, or the available window with the least remaining allowance.
_Avoid_: Taskbar limit, primary limit
245 changes: 91 additions & 154 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,160 +1,112 @@
# Codex Usage Widget

A local-only Windows widget that shows the remaining Codex subscription allowance.
It talks directly to the official Codex app server through
`account/rateLimits/read` and listens for live `account/rateLimits/updated`
notifications.
See the Codex limits available to your account, including 5-hour and weekly windows,
without opening a browser. Codex Usage Widget runs locally on Windows and reads usage
through the official Codex CLI app server.

> This is an independent utility and is not an official OpenAI application.

![Codex Usage Widget desktop preview](docs/images/desktop-widget.png)
![Codex Usage Widget showing 5-hour and weekly limits](docs/images/desktop-widget-limits.png)

## Features
## Quick start

- Remaining percentage and reset time for every general Codex rate-limit window
- Compact and detailed widget layouts with optional token-activity history
- Credit, spend-control, earned-reset, and model-specific limit details when available
- Compact, movable, always-on-top desktop widget
- Native-looking taskbar label beside the Windows notification area
- Event-driven task activity animation through official local Codex lifecycle hooks
- Immediate taskbar-label hiding while another app is fullscreen on the same monitor
- Persistent desktop/taskbar display preference
- Optional per-user start with Windows registration
- Automatic refresh every two minutes and live server notifications
- Single-instance protection to prevent overlapping labels
- Per-monitor DPI support, local diagnostic logs, and graceful CLI reconnects
- Model-specific buckets stay out of the compact view and appear only in details
- No browser automation, token scraping, telemetry, or external backend

## Requirements

- Windows 10 version 1809 or newer
- Codex CLI available on `PATH`
- A completed local sign-in (`codex login`)

The portable release includes the .NET runtime. A separate .NET installation is
therefore not required on the destination computer.

## Install on another computer
The widget requires Windows 10 version 1809 or newer, the Codex CLI on `PATH`, and a
completed local sign-in.

1. Download the
[latest Windows x64 portable release](https://github.com/ognjeeen/codex-usage-widget/releases/latest/download/codex-usage-widget-win-x64.zip).
2. Start `CodexUsageWidget.exe`, either after extraction or directly from the ZIP.
3. Ensure `codex --version` works in PowerShell and run `codex login` if needed.
2. Start `CodexUsageWidget.exe` after extraction or directly from the ZIP.
3. If usage does not appear, confirm that `codex --version` works in PowerShell and run
`codex login`.

When Windows starts the executable from a temporary ZIP location, the widget atomically
copies that exact version to `%LOCALAPPDATA%\CodexUsageWidget\app\<version>` and relaunches
the stable per-user copy. An executable already extracted to a normal directory continues
to run in place.
The portable release includes the .NET runtime. The executable is not currently
code-signed, so Windows may show an unknown-publisher warning. Each GitHub release includes
a SHA-256 checksum for verification.

Only one instance can run at a time. Starting the executable again exits quietly.
When Windows starts the executable from a temporary ZIP location, the widget copies that
version to `%LOCALAPPDATA%\CodexUsageWidget\app\<version>` and relaunches it. An executable
started from an extracted folder continues to run there. Only one widget instance runs at
a time.

The executable is not currently code-signed, so Windows may identify the
publisher as unknown. A SHA-256 checksum is attached to every
[GitHub Release](https://github.com/ognjeeen/codex-usage-widget/releases) for
verification before running the application.
If Codex is installed outside `PATH`, set `CODEX_USAGE_WIDGET_CODEX_PATH` to the full path
of `codex.cmd` or `codex.exe`.

If Codex is installed in a non-standard location, set
`CODEX_USAGE_WIDGET_CODEX_PATH` to the full path of `codex.cmd` or `codex.exe`.
## What it shows

## Display modes
- Remaining percentage and reset time for every general Codex usage window
- A selectable displayed limit shared by the widget headline, taskbar label, and tray icon
- Compact and detailed layouts, including credits, spend controls, earned resets, token
activity, and model-specific limits when Codex returns them
- A movable, always-on-top desktop widget and a compact label beside the notification area
- Live task activity dots based on official local Codex lifecycle hooks
- Automatic refresh every two minutes plus live rate-limit notifications
- Fullscreen-aware taskbar behavior, per-monitor DPI support, and optional start with Windows
- Local logs for diagnostics, with no telemetry or remote backend

- **Desktop widget** keeps the selected widget layout visible and always on top.
- **Taskbar label** shows `Codex 75%` directly to the left of the notification area.
## Display modes and limit selection

The desktop widget has two persisted layouts:
**Desktop widget.** Shows the selected limit as the headline and keeps every general limit
visible below it. Compact mode focuses on limits; Details adds account and token activity.

- **Compact** shows the general Codex windows and highlights the most constrained one.
- **Details** adds available credits and spend controls, token activity, earned resets,
and model-specific limits such as GPT-5.3-Codex-Spark.
**Taskbar label.** Shows the same selected percentage beside the Windows notification area.
The tray icon and its tooltip follow that selection too.

Choose `5h limit`, `Weekly limit`, or `Most constrained` from the **Displayed limit** menu.
The 5-hour window is the default. Available windows depend on the Codex account, so the
widget falls back to an available window when Codex does not return the selected one.

![Codex Usage Widget detailed preview](docs/images/detailed-widget.png)

Token activity is informational and is intentionally presented separately from quota
consumption because tokens do not map linearly to the remaining subscription percentage.
Token activity is informational. Token counts do not map directly to the remaining
subscription percentage.

![Codex Usage Widget taskbar label preview](docs/images/taskbar-label.png)

Use the `−` button to switch to taskbar mode. Right-click the taskbar label or tray
icon to refresh, change display mode, or exit.

Choose **Start with Windows** from either menu to register the running executable for
the signed-in Windows user. The option does not require administrator rights, and turning
it off removes the registration. If an extracted portable folder moves, the path is
refreshed the next time the widget is started manually.

## Live Codex activity dots
Select the `−` button to move the widget to the taskbar. Right-click the taskbar label or
tray icon to refresh, change the display mode or displayed limit, configure activity dots,
toggle start with Windows, check for updates, or exit.

Activity dots turn the official local Codex lifecycle hooks into an at-a-glance signal
that work is still running. They are available in both the taskbar label and desktop
widget, without polling Codex or estimating activity from rate-limit changes.
## Activity dots

### What activity dots provide
Activity dots show whether at least one local Codex turn is running. Updates come from the
official Codex lifecycle hooks through a current-user-only named pipe. The widget does not
read prompt text, responses, transcript paths, or model output.

- One quiet dot while Codex is idle, expanding into a three-dot wave during active work
- Immediate, event-driven updates when a Codex turn starts or finishes
- Independent tracking of parallel Codex sessions, so one completed session cannot hide
another session that is still running
- A completion animation only after the final active turn finishes
- A dedicated setup window for installation status, trust approval, refresh, and removal
To enable them:

### Private and local by design
1. Open **Activity dots...** from the widget, taskbar label, or tray menu.
2. Select **Install hooks** and review the exact proposed `~/.codex/hooks.json` change.
3. Select **Copy /hooks and open Codex**, paste `/hooks`, and trust the three definitions.
4. Return to the widget and select **Check again**.

- No prompts, responses, transcript contents, transcript paths, or model output are
collected, stored, forwarded, or logged
- No telemetry, analytics, browser automation, remote backend, or credential access is used
- Hook signals stay on the current Windows account through a current-user-only named pipe
- Hook handlers use a small path-independent PowerShell-to-pipe bridge and never start the
WPF widget executable for each lifecycle event
- Only the lifecycle event type and the Codex-provided session and turn identifiers are
passed to the in-memory activity monitor
- Activity state is not persisted, so the widget does not build a history of your work
- Authentication remains entirely owned by the locally installed Codex CLI
Installation is always explicit. The widget never installs hooks during normal startup.
See [Activity dots](docs/ACTIVITY_DOTS.md) for privacy details, command-line setup, removal,
and recovery behavior.

Hook installation remains an explicit, reviewable action and is never performed during
normal widget startup.
## Privacy and local data

### Setup and removal
The widget talks only to the locally installed Codex CLI. It does not scrape a browser,
read authentication secrets, send telemetry, or use a remote backend. Codex remains the
owner of authentication.

Select the three-dot activity button in the desktop widget, or choose **Activity dots...**
from the tray or taskbar-label menu. The setup window reports whether the hooks are missing,
awaiting approval, active, modified, or disabled. Select **Install hooks**, review the exact
proposed `~/.codex/hooks.json` content, and confirm the change.
The application writes only under `%LOCALAPPDATA%\CodexUsageWidget`:

After installation, select **Copy /hooks and open Codex**. Paste `/hooks` into Codex, then
review and trust the exact new `UserPromptSubmit`, `Stop`, and `SessionEnd` definitions.
New or changed definitions require new trust. Return to the setup window and select
**Check again** to verify that activity reporting is ready.
- `app\<version>\CodexUsageWidget.exe`: stable copy used after a direct ZIP launch
- `display-mode.txt`: desktop or taskbar display preference
- `widget-density.txt`: compact or detailed widget preference
- `displayed-limit.txt`: selected summary limit
- `logs\codex-usage-widget-YYYYMMDD.log`: diagnostic logs retained for 14 days

The setup window can remove handlers generated by the current widget and conservatively
recognized handlers from earlier Codex Usage Widget portable locations. Recognition is limited
to the exact command formats historically generated for `CodexUsageWidget.exe`; similarly named
handlers from other applications, existing hooks, and unknown configuration fields are preserved.
The widget displays ChatGPT and Codex subscription limits. It does not display OpenAI API
billing or API-key usage.

For scripted setup or recovery, the existing command-line flow remains available. From
PowerShell in the directory containing the widget executable, run:
## Uninstall

```powershell
.\CodexUsageWidget.exe --install-activity-hooks
```

The command displays the proposed content and writes it only after interactive confirmation.

To perform the equivalent removal from PowerShell, run:

```powershell
.\CodexUsageWidget.exe --uninstall-activity-hooks
```

If the widget is closed, the hook handler exits successfully after a short bounded
connection attempt and Codex continues normally.

Activity state is intentionally in memory only. A task that started before the widget
or hooks were ready is not reconstructed. Each session owns at most one active turn: a
later `UserPromptSubmit` replaces an orphaned turn, and a late `Stop` for the old turn
cannot clear the current one. If Codex terminates without any later lifecycle event, a
widget restart still clears the in-memory state; no arbitrary timeout is used because
legitimate tasks can run for a long time.
1. If activity hooks are installed, open **Activity dots...** and select **Remove hooks**.
2. Turn off **Start with Windows** from the widget or tray menu.
3. Exit the widget.
4. Delete the extracted application folder and `%LOCALAPPDATA%\CodexUsageWidget`. The local
data folder contains any stable copy, saved preferences, and diagnostic logs.

## Development

Expand All @@ -166,50 +118,35 @@ dotnet test .\CodexUsageWidget.slnx -c Release
dotnet run --project .\src\CodexUsageWidget\CodexUsageWidget.csproj
```

Warnings are treated as errors and the recommended .NET analyzers run during every
build.

## Portable release
To preview both general rate-limit windows without reading Codex usage, close any running
widget instance and start a local preview build:

```powershell
.\scripts\publish.ps1 -Runtime win-x64
```

The script runs the complete test suite and creates:

```text
artifacts/release/codex-usage-widget-win-x64.zip
dotnet run --project .\src\CodexUsageWidget\CodexUsageWidget.csproj -p:EnableUsagePreview=true -- --preview-usage
```

`win-arm64` is also supported through the script's `-Runtime` parameter.
Preview data reports 80% remaining for the 5-hour limit and 15% remaining for the weekly
limit. Standard release builds do not accept the preview flag.

Maintainer release instructions are documented in
[docs/RELEASING.md](docs/RELEASING.md).
Warnings are treated as errors and the recommended .NET analyzers run during every build.

## Local data
## Build a portable release

The application only writes under `%LOCALAPPDATA%\CodexUsageWidget`:

- `app\<version>\CodexUsageWidget.exe` — stable copy used after a direct ZIP launch
- `display-mode.txt` — the selected display mode
- `widget-density.txt` — the selected compact or detailed widget layout
- `logs\codex-usage-widget-YYYYMMDD.log` — diagnostics, retained for 14 days
```powershell
.\scripts\publish.ps1 -Runtime win-x64
```

No credentials are read or stored by the widget. Authentication remains owned by
the locally installed Codex CLI.
The script runs the complete test suite and creates
`artifacts/release/codex-usage-widget-win-x64.zip`. It also supports `win-arm64` through the
`-Runtime` parameter. See [Releasing](docs/RELEASING.md) for the full maintainer workflow.

## Architecture

See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for component boundaries,
runtime flow, and extension guidance.

## Usage semantics

This displays ChatGPT/Codex subscription rate limits. It does not display OpenAI
API billing or API-key usage, which use a different accounting system.
See [Architecture](docs/ARCHITECTURE.md) for module responsibilities, runtime flow, and
extension guidance.

## License

Released under the [MIT License](LICENSE). You may use, modify, fork, publish,
redistribute, sublicense, or sell copies of the software as long as the copyright
notice and license text are retained.
Released under the [MIT License](LICENSE). You may use, modify, fork, publish, redistribute,
sublicense, or sell copies of the software as long as you retain the copyright notice and
license text.
82 changes: 82 additions & 0 deletions docs/ACTIVITY_DOTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Activity dots

Activity dots show whether Codex is working without estimating activity from rate-limit
changes. The widget receives lifecycle signals from official local Codex hooks and keeps the
state in memory.

[Back to the README](../README.md)

## What the widget tracks

- One quiet dot while Codex is idle and a three-dot wave while work is active
- Start and completion events for parallel Codex sessions
- One active turn per session, so one completed session cannot hide another active session
- A completion animation after the final active turn finishes

The widget accepts only the lifecycle event type and the session and turn identifiers
provided by Codex. It does not collect prompts, responses, transcript contents, transcript
paths, or model output.

## Set up in the widget

1. Select the three-dot activity button in the desktop widget, or choose
**Activity dots...** from the taskbar-label or tray menu.
2. Select **Install hooks**.
3. Review the exact proposed `~/.codex/hooks.json` content and confirm the change.
4. Select **Copy /hooks and open Codex**.
5. Paste `/hooks` into Codex and trust the new `UserPromptSubmit`, `Stop`, and `SessionEnd`
definitions.
6. Return to the setup window and select **Check again**.

Codex owns hook trust. New or changed definitions require approval in Codex. The widget only
reads the reported trust state.

To remove the handlers, return to the setup window and select **Remove hooks**. The widget
preserves unrelated hooks and unknown configuration fields.

## Command-line setup and removal

The same review-before-write flow is available from PowerShell in the directory containing
the widget executable:

```powershell
.\CodexUsageWidget.exe --install-activity-hooks
```

To remove the recognized Codex Usage Widget handlers:

```powershell
.\CodexUsageWidget.exe --uninstall-activity-hooks
```

The setup code recognizes only the exact command formats generated by current and earlier
portable versions of Codex Usage Widget. Similarly named handlers from other applications
are left unchanged.

## Privacy and local transport

- Hook signals stay on the current Windows account through a current-user-only named pipe.
- A small PowerShell bridge sends the signal without starting the WPF widget for each event.
- Activity state is never persisted, so the widget does not build a work history.
- The widget does not read Codex authentication data.
- No hook data is sent to telemetry, analytics, or a remote backend.

Hook installation is always explicit. Normal widget startup does not create or modify hook
configuration.

## Runtime behavior and recovery

Activity state starts empty when the widget starts. A task that began before the widget or
hooks were ready cannot be reconstructed.

Each session owns at most one active turn. A later `UserPromptSubmit` replaces an orphaned
turn in that session, and a late `Stop` for the old turn cannot clear the new one. Duplicate
events are harmless. `SessionEnd` removes only the matching session.

If Codex terminates without sending a final lifecycle event, a later turn in the same session
replaces the stale turn. Restarting the widget also clears all in-memory activity state. The
widget does not use an arbitrary timeout because legitimate Codex tasks can run for a long
time.

If the widget is closed, the hook bridge exits successfully after a short connection attempt
and Codex continues normally.
Binary file added docs/images/desktop-widget-limits.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading