CCLimitPing

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 7, 2026 License: MIT

README

CCLimitPing (limitping)

English | 中文

Go Platform

Keep your Claude Code, Codex, and GLM (Zhipu / Z.ai Coding Plan) rate-limit windows back-to-back.

These providers bill on a 5-hour rolling window (plus a weekly cap), and the 5h window starts on your first message. If you don't send anything right when a window resets, that gap is wasted — the next window only starts whenever you happen to use the tool again, drifting out of sync with your day.

limitping watches each provider and, the moment a 5h window resets, sends one minimal message to start the next window immediately — so your windows stay continuous and predictable.

claude  ✓ pinged (6.6s, 33,129 tok (in 32,956 / out 173), $0.0042)
codex   ✓ pinged (13.6s, 16,862 tok (in 16,814 / out 48), $0.0098)

Supported providers

Provider Read usage (zero-quota) Trigger Auth
Claude Code …/api/oauth/usage claude -p OAuth (Keychain / ~/.claude)
Codex …/backend-api/wham/usage codex exec OAuth (~/.codex/auth.json)
GLM (Zhipu / Z.ai) …/api/monitor/usage/quota/limit minimal chat completion API key (config / env)

[!NOTE] GLM is off by default and not yet verified on a live plan — see GLM before enabling it.

How it works

Two cleanly separated jobs:

Job Mechanism Cost
Trigger a new window the official CLI (claude -p / codex exec), or a minimal API call (GLM) a tiny slice of quota (this is the point)
Read usage & reset times zero-quota usage endpoints (the same ones CodexBar / community plugins use) none — never starts a window
  • Claude: reads GET https://api.anthropic.com/api/oauth/usage using the OAuth token from the macOS Keychain (Claude Code-credentials) or ~/.claude/.credentials.json.
  • Codex: reads GET https://chatgpt.com/backend-api/wham/usage using the OAuth token from ~/.codex/auth.json.
  • GLM: reads GET …/api/monitor/usage/quota/limit (on api.z.ai or open.bigmodel.cn) using your Coding Plan API key. GLM has no standalone CLI, so the trigger is a direct minimal chat completion to …/api/coding/paas/v4/chat/completions rather than a shell-out.

Claude/Codex tokens are reused from the official tools (no separate login) and refreshed on 401. GLM uses a static API key (from config or env) — see below.

Install

limitping ships as a single self-contained binary — no Go required.

One-line script (macOS / Linux):

curl -fsSL https://raw.githubusercontent.com/wavever/CCLimitPing/main/install.sh | sh

Downloads the right prebuilt binary from the latest release into /usr/local/bin (or ~/.local/bin). Override with LIMITPING_INSTALL_DIR.

Manual download — grab the archive for your platform from the Releases page (.tar.gz for macOS/Linux, .zip for Windows):

tar -xzf limitping_darwin_arm64.tar.gz
sudo mv limitping /usr/local/bin/

Homebrew (macOS / Linux) — brew install wavever/tap/limitping (works once the Homebrew tap is set up — see .goreleaser.yaml).

From source (developers, needs Go 1.25+):

go install github.com/wavever/CCLimitPing/cmd/limitping@latest
# or, from a clone:
go build -o bin/limitping ./cmd/limitping

Each provider you enable needs its own credentials: the claude / codex CLIs logged in (Claude / Codex), or a Coding Plan API key (GLM).

Usage

limitping config init          # write ~/.config/limitping/config.toml
limitping status               # show 5h/weekly % + reset countdowns (no quota)
limitping status -v            # also print raw JSON
limitping ping                 # trigger all enabled providers now
limitping ping claude          # Claude only
limitping ping codex           # Codex only
limitping ping glm             # GLM only
limitping ping --dry-run       # show the commands without sending
limitping watch                # foreground daemon: ping each window at reset
limitping watch --dry-run      # log when pings would fire, without sending

ping shows the exact command, a live timer (a spinner on a terminal), the token usage the ping consumed (parsed from claude --output-format json / codex --json / the GLM API response), and a USD cost where available:

claude  → claude -p . --model haiku --output-format json --max-turns 1
claude  ✓ pinged (6.6s, 33,129 tok (in 32,956 / out 173), $0.0042)
codex   → codex exec --skip-git-repo-check --json -c model_reasoning_effort=low -m gpt-5.4-mini ok
codex   ✓ pinged (13.6s, 16,862 tok (in 16,814 / out 48), $0.0098)

Cost sources:

  • Claude reports total_cost_usd directly.
  • Codex (subscription) doesn't return a USD cost, so — like CodexBar/ccusage — we derive the equivalent API-rate cost from the LiteLLM pricing dataset (cost = non-cached-input × input + cached-input × cache-read + output × output). The dataset is cached at ~/.config/limitping/litellm_prices.json (24h TTL), with model-alias/date-suffix fallbacks. Requires [codex].model to be set so the rate can be looked up.
  • GLM is a per-prompt subscription, so no per-call USD cost is shown — only the token count.

Most of Claude's input tokens are the cached Claude Code system prompt (cache_read), which is the unavoidable floor cost of claude -p.

Example status:

claude
  5h     [█████░░░░░]  51.0%  resets in 3h14m    (Sun 00:10)
  weekly [█████░░░░░]  54.0%  resets in 7h04m    (Sun 04:00)

codex (plus)
  5h     [██░░░░░░░░]  24.0%  resets in 3h15m    (Sun 00:11)
  weekly [████░░░░░░]  37.0%  resets in 111h57m  (Thu 12:53)

Configuration

~/.config/limitping/config.toml (honors $XDG_CONFIG_HOME):

weekly_threshold = 0.99   # skip pinging when weekly usage >= this (0..1), until weekly reset
reset_buffer     = "10s"  # wait this long after a reset before pinging (ensures rollover)
notify           = true   # macOS notifications on ping/skip/failure

[claude]
enabled    = true
prompt     = "."
model      = "haiku"      # cheapest tier; triggering doesn't need a SOTA model
extra_args = ["--max-turns", "1"]
align_start = ""          # optional RFC3339 anchor for the first window; empty = start ASAP

[codex]
enabled          = true
prompt           = "ok"
model            = "gpt-5.4-mini"  # cheapest Codex model for triggering
reasoning_effort = "low"  # "minimal" is rejected when web_search/image_gen tools are enabled
extra_args       = []
align_start      = ""

[glm]
enabled  = false          # opt-in: enable once you have a plan + API key
prompt   = "ok"
model    = "glm-4.6"      # cheapest standard model; flagship GLM-5/5.1 cost a multiplier
platform = "global"       # "global" = api.z.ai, "cn" = open.bigmodel.cn (Zhipu)
api_key  = ""             # empty = read from $ZAI_API_KEY (global) / $ZHIPU_API_KEY (cn)
align_start = ""

Top-level keys:

  • weekly_threshold — when the weekly window is at/above this, watch stops pinging and waits for the weekly reset (unless usable credits exist).
  • reset_buffer — how long to wait after a window's reset time before pinging, so the window has definitely rolled over.
  • align_start (per provider) — pin the phase of your windows: set to a future RFC3339 time to delay the very first ping until then; afterwards windows chain automatically every ~5h.
Why a cheap model

Triggering a window doesn't depend on the model — any billable request starts the 5h clock — so the ping uses each provider's cheapest model to eat the least of your budget:

  • Claude → haiku: also avoids the separate weekly Opus bucket.
  • Codex → gpt-5.4-mini: the mini variant (see ~/.codex/models_cache.json for what your plan offers).
  • GLM → glm-4.6: a standard model; the flagship GLM-5/5.1 deduct quota at a 2–3× multiplier, so avoid them for a mere trigger.

Claude/Codex don't expose per-model prices at runtime (Anthropic's local cost cache is empty; Codex's model cache has no price field), so the cheapest model is a sensible default rather than a live price lookup. Override model per provider if you prefer.

GLM (Zhipu / Z.ai Coding Plan)

GLM uses the same 5h + weekly structure as Claude/Codex, but two things differ:

  • Auth is a static API key, not OAuth. Put it in [glm].api_key, or leave it empty and export ZAI_API_KEY (global) / ZHIPU_API_KEY (CN). Usage reads hit …/api/monitor/usage/quota/limit; the key goes in the Authorization header without a Bearer prefix (that's how the endpoint expects it).
  • The trigger is a direct API call, because GLM has no standalone CLI. It sends a one-token chat completion to …/api/coding/paas/v4/chat/completions.

[!WARNING] Unverified on a live plan. GLM is off by default. The endpoint shapes come from community plugins; confirm on your own plan that (a) the monitor endpoint returns your real 5h/weekly windows and (b) the 5h window is anchored to your first message (so pinging at reset actually fills a gap). If GLM's window is a fixed clock or per-request sliding window, the ping won't help.

Run watch in the background (macOS, optional)

watch runs in the foreground. To keep it running via launchd, create ~/Library/LaunchAgents/com.limitping.watch.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key><string>com.limitping.watch</string>
  <key>ProgramArguments</key>
  <array>
    <string>/ABSOLUTE/PATH/TO/limitping</string>
    <string>watch</string>
  </array>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><true/>
  <key>StandardOutPath</key><string>/tmp/limitping.log</string>
  <key>StandardErrorPath</key><string>/tmp/limitping.err</string>
</dict>
</plist>
launchctl load ~/Library/LaunchAgents/com.limitping.watch.plist

Cost & caveats

  • Triggering consumes a little quota (~one ping per 5h ≈ 33/week). The ping uses a minimal prompt and low reasoning, so the cost is tiny but non-zero.
  • The usage endpoints are unofficial and could change; they're read-only and isolated per provider for easy patching.
  • macOS-first: Keychain reads and notifications are macOS-only. Codex auth.json is cross-platform; Claude on Linux uses ~/.claude/.credentials.json; notifications are a no-op off macOS.

Layout

cmd/limitping            CLI entry
internal/config          TOML config
internal/usage           normalized usage model
internal/auth            Claude (Keychain) + Codex (auth.json) tokens; GLM API key
internal/provider        per-provider ReadUsage (endpoint) + Trigger (CLI / API)
internal/pricing         LiteLLM-based USD cost lookup (Codex)
internal/scheduler       the watch engine (sleep-until-reset, weekly-respect, backoff)
internal/notify          macOS osascript notifications
internal/cli             cobra commands: status, ping, watch, config, version

Contributing

Issues and PRs are welcome. Before submitting:

gofmt -l .        # should print nothing
go build ./...
go vet ./...

Providers are isolated in internal/provider (one file each) with a small Provider interface (ReadUsage + Trigger), so adding a new provider is mostly a self-contained file plus wiring in internal/cli and internal/config.

Releasing is automated: push a tag and GitHub Actions runs GoReleaser to build the cross-platform binaries and publish a Release.

git tag v0.1.0 && git push origin v0.1.0

License

MIT © wavever

Directories

Path Synopsis
cmd
limitping command
Command limitping keeps Claude Code / Codex rate-limit windows back-to-back by pinging each provider the moment its 5h window resets.
Command limitping keeps Claude Code / Codex rate-limit windows back-to-back by pinging each provider the moment its 5h window resets.
internal
auth
Package auth loads (and, when necessary, refreshes) the OAuth credentials that Claude Code and Codex already store on disk / in the Keychain.
Package auth loads (and, when necessary, refreshes) the OAuth credentials that Claude Code and Codex already store on disk / in the Keychain.
cli
Package cli wires up the limitping command-line interface.
Package cli wires up the limitping command-line interface.
config
Package config loads and validates limitping's TOML configuration.
Package config loads and validates limitping's TOML configuration.
notify
Package notify sends desktop notifications.
Package notify sends desktop notifications.
pricing
Package pricing computes a USD cost for token usage using the LiteLLM pricing dataset — the same approach CodexBar/ccusage use.
Package pricing computes a USD cost for token usage using the LiteLLM pricing dataset — the same approach CodexBar/ccusage use.
provider
Package provider implements per-provider usage reading (zero-quota, via the OAuth usage endpoints) and window triggering (via the official CLIs).
Package provider implements per-provider usage reading (zero-quota, via the OAuth usage endpoints) and window triggering (via the official CLIs).
scheduler
Package scheduler runs the watch loop: for each provider it sleeps until the 5h window resets, then triggers a minimal ping to start the next window, keeping windows back-to-back.
Package scheduler runs the watch loop: for each provider it sleeps until the 5h window resets, then triggers a minimal ping to start the next window, keeping windows back-to-back.
usage
Package usage defines the normalized rate-limit usage model shared across providers.
Package usage defines the normalized rate-limit usage model shared across providers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL