agentleFS
WaterTianWaterTian/cc-hud/AGENTS.md

cc-hud

AGENTS.md9 starsChanged 7 days agoMITView on GitHub

Compact single-line status bar for Claude Code, plus a one-command native footer preset for Codex CLI. This file is the machine-oriented reference: exact commands with expected output, the runtime contract, every file, process and endpoint the tool touches, and the invariants to keep when changing it. The human tour is README.md; maintainer notes (Chinese) are in CLAUDE.md. Keep the three in sync when behaviour changes. Colors: Catppuccin Mocha, ANSI 256. Percent colour steps at 50 / 70 / 85. /cc-hud:setup…

  • Reads credentials
  • Deletes or force-pushes
  • Installs packages
  • Commits and pushes
  • Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.

    Of the AGENTS.md files we read, the 31,774 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.

  • In this repository2 other files it gives its agents.

The file

We split this AGENTS.md into the rules it gives an agent

2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Keep the three in sync when behaviour changes.

    line 8
  2. Very specific:

    Uninstall: remove the statusLine key from <cfg>/settings.json, delete <cfg>/bin/cc-hud-launcher.cjs, run claude plugin uninstall …

    line 63

≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

cc-hud — agent reference

Compact single-line status bar for Claude Code, plus a one-command native footer preset for Codex CLI. This file is the machine-oriented reference: exact commands with expected output, the runtime contract, every file, process and endpoint the tool touches, and the invariants to keep when changing it. The human tour is README.md; maintainer notes (Chinese) are in CLAUDE.md. Keep the three in sync when behaviour changes.

What it renders

[Fable 5.1 · XHigh] █▊░░░░░░░░ 18% (1M) │ ◐ explore [haiku] │ 5h:1% (4.5h) │ 7d:35% (4.1d) │ Fable:51% │ spend:$12/$50 (3d) │ cc-hud · main*
SegmentSourceShown when
[Fable 5.1 · XHigh]model.id (fallback display_name), effort.level (fallback: transcript)always; depth only when an effort is known
█▊░░░░░░░░ 18%context_window.used_percentage, else derived from current_usage tokens ÷ context_window_sizealways; —% until Claude Code reports usage (session start, right after /compact)
(1M)[1m] suffix in model.id, or context_window_size ≥ 1_000_000extended-context sessions
◐ explore [haiku]<transcript dir>/<session>/subagents/agent-*.meta.json without finished: true (Claude Code writes one per Agent call at launch, async); fallback: a transcript-tail Agent tool_use with no tool_result (older synchronous builds)while a subagent runs (max 3 listed); an unfinished meta idle for > 15 min is ignored
5h:1% (4.5h) / 7d:35% (4.1d)rate_limits.five_hour / seven_day (used_percentage, resets_at); MiniMax quota on that backendsubscription sessions (absent for API-key sessions)
Fable:51%OAuth usage endpoint, via the detached refresher's cacheofficial backend with rate limits; ~ prefix = cache older than 30 min
spend:$12/$50 (3d)rate_limits.spend_limitwhen the org sets a spend cap; bare % if dollar figures are absent
one day:7%any other rate_limits.<key> with used_percentagewhenever Claude Code adds a window cc-hud has no slot for
cc-hud · main*workspace.current_dir (fallback cwd), worktree.branch or git symbolic-ref, git status --porcelainalways; * = uncommitted tracked changes, ? = status failed/timed out, no branch outside a repo
¥13.44CC_HUD_EXTRA_FILE first line, else DeepSeek balance, else GLM balancewhen one of those applies; ~ prefix (also on 5h / 7d from MiniMax) = cached value not refreshed for > 30 min

Colors: Catppuccin Mocha, ANSI 256. Percent colour steps at 50 / 70 / 85.

Install for a user (inside Claude Code)

/plugin marketplace add WaterTian/cc-hud
/plugin install cc-hud@cc-hud
/reload-plugins
/cc-hud:setup

/cc-hud:setup is itself an agent-executed procedure (commands/setup.md): it copies scripts/launcher.cjs to <cfg>/bin/cc-hud-launcher.cjs and sets statusLine.command to node "<cfg>/bin/cc-hud-launcher.cjs" in <cfg>/settings.json (cfg = $CLAUDE_CONFIG_DIR or ~/.claude). It is idempotent and merges into existing settings. The launcher resolves the newest marketplace-installed cc-hud on every tick, so upgrades never need a re-setup.

Verify (works in any shell; <cfg> expanded, refresh spawning disabled):

echo '{"model":{"id":"claude-fable-5-1"},"context_window":{"used_percentage":13}}' \
  | CC_HUD_NO_REFRESH=1 node "<cfg>/bin/cc-hud-launcher.cjs" | sed 's/\x1b\[[0-9;]*m//g'
OutputMeaning
[Fable 5.1] █▎░░░░░░░░ 13%installed and wired
[cc-hud] plugin not found — run /cc-hud:setupno marketplace install in <cfg>/plugins/installed_plugins.json — do the /plugin steps first
emptynode not on PATH for the status-line shell, or the launcher file is missing

Upgrade: /plugin marketplace update cc-hud then /reload-plugins. There is no /plugin update slash command; from a terminal use claude plugin update cc-hud@cc-hud.

Uninstall: remove the statusLine key from <cfg>/settings.json, delete <cfg>/bin/cc-hud-launcher.cjs, run claude plugin uninstall cc-hud@cc-hud, and optionally rm -rf ~/.cache/cc-hud.

Without the marketplace: npm i -g cc-hud (or a source checkout + npm run build) and point statusLine.command at node "<absolute path>/dist/index.js"; /cc-hud:setup leaves such a command untouched.

Codex CLI is a different install path and config file — see Codex native footer below.

Runtime contract

The stdin contract below applies to dist/index.js (Claude) and to the npm entry dist/cli.js with no arguments. Explicit CLI commands have ordinary command output and nonzero exit codes on failure.

  • Input: Claude Code's statusline JSON on stdin (schema). Fields read are typed in src/types.ts (StdinData); everything else is ignored. Empty, malformed or non-object stdin renders the bare [Claude] line.
  • Output: exactly one line on stdout, ANSI-256 coloured, then exit 0 — always, including on internal errors (the fallback line) and at the hard timeout (the stdin-only line: model, context, limits, no collector segments). A second line would corrupt the status bar.
  • Timing: ~30 ms typical. Hard exit at 2 s (setTimeout(...).unref() in src/index.ts); git calls 800 ms each; inline third-party fetches 1.2 s. A slow source only drops its own segment.
  • No persistent state in the process; one fresh process per tick.

Files, processes, network

KindWhatWhen
reads<transcript_path> — last 64 KB only; <transcript_path minus .jsonl>/subagents/*.meta.json (a few hundred bytes each) plus a stat of the matching .jsonl for unfinished onesevery tick
reads<cfg>/plugins/installed_plugins.jsonevery tick (launcher)
reads<cfg>/.credentials.json, or macOS Keychain item Claude Code-credentialsrefresher only; token used for one GET, never stored or refreshed
reads~/.config/cc-hud/config.json { "proxy": "http://…" }refresher, when no proxy env var is set
reads$CC_HUD_EXTRA_FILE first lineevery tick, when set
writes~/.cache/cc-hud/claude-plan.json, ds-balance.json, glm-balance.json, mmx-quota.json ({ payload, ts, okTs, failTs?, … }, atomic tmp + rename)on refresh / cache miss / failed inline fetch (records failTs)
writes<cfg>/bin/cc-hud-launcher.cjs, statusLine in <cfg>/settings.json/cc-hud:setup only
writes$CODEX_HOME/config.toml — only tui.status_line (setup / restore) and tui.theme + tui.status_line_use_colors (theme / restore-theme), through Codex's config API; $CODEX_HOME/cc-hud-native.json, cc-hud-theme.json, themes/cc-hud.tmThemecc-hud <action> codex only — never during a statusline tick
spawnsgit symbolic-ref, git --no-optional-locks status --porcelainevery tick with a current_dir
spawnsnode dist/refresh.js claude (detached, 8 s budget)official backend, gauge cache > 5 min old, at most once per 30 s
spawnscurl --config - (token via stdin, never argv); security find-generic-password on macOSrefresher only
spawnscodex --version, then one codex app-server --stdio (terminated when the command ends)cc-hud <action> codex only
networkGET https://api.anthropic.com/api/oauth/usage (Bearer OAuth)refresher only — never inside a tick
networkGET api.deepseek.com/user/balance · open.bigmodel.cn / api.z.ai /api/biz/account/query-customer-account-report · api.minimaxi.com / api.minimax.io /v1/token_plan/remains (Bearer ANTHROPIC_AUTH_TOKEN)third-party backends, inline on a cache miss (≤ once per 5 min; after a failure ≤ once per 30 s)

Turn off all network on the official backend with CC_HUD_NO_REFRESH=1. Third-party collectors have no switch; they only run when ANTHROPIC_BASE_URL matches their host.

Environment variables

VariableEffect
CLAUDE_CONFIG_DIRClaude Code's config dir (default ~/.claude): credentials, installed_plugins.json, launcher location
CC_HUD_NO_REFRESH=1Never spawn the refresher (no network at all on the official backend)
CC_HUD_EXTRA_FILE=<path>Show the file's first line as the extra segment (beats DeepSeek / GLM)
CC_HUD_CURL=<path>curl binary for proxied requests and the WAF fallback (default curl)
HTTPS_PROXY / https_proxy / ALL_PROXY / all_proxyRefresher goes through curl only (native fetch ignores proxies, so it is skipped rather than leak the token)
ANTHROPIC_BASE_URLRead-only: selects the backend by substring — api.anthropic.com / unset → official; deepseek; bigmodel.cn / api.z.ai; minimax (minimaxi.com → CN endpoint)
ANTHROPIC_AUTH_TOKENRead-only: bearer for the third-party balance / quota endpoints
CODEX_HOMECodex's config dir (default ~/.codex) for the cc-hud … codex commands: config.toml, backups, theme file
CC_HUD_CODEX=<path>Codex executable for those commands (or npm's bin/codex.js) when codex isn't on PATH
CC_HUD_CODEX_LIVE_TEST=1Test-only: npm test also runs a real Codex config round-trip in an isolated CODEX_HOME

Boolean switches: "", 0, false mean off; anything else means on (src/env.ts).

Repository map

PathRole
src/index.tsEntry: stdin → collectors in parallel → render() → single stdout write; fallback line on any error
src/stdin.tsstdin JSON → StdinData ({} unless a plain object)
src/types.tsStdinData (fields read), RenderData (what the renderer needs)
src/render.tsPure renderer: RenderData → one coloured line; strips control chars from free text
src/model.tsModel id → display name + (1M) variant (claude-opus-4-7[1m] → Opus 4.7, 1M)
src/transcript.tsTranscript tail → latest main-chain effort; running subagents from the subagents/*.meta.json sidecar (plus synchronous Agent calls still awaiting a result)
src/git.tsFolder · branch · dirty marker, 800 ms per git call
src/claude.tsTop-model weekly gauge: tick reads cache; refreshClaudePlan() does the OAuth GET (refresher)
src/refresh.tsDetached refresher entry: node refresh.js claude, 8 s budget
src/cache.ts~/.cache/cc-hud/<name>.json; serveCache (detached discipline) and cachedInline (inline discipline: 30 s retry cooldown after a failure, stale flag after 30 min); atomic writes
src/http.tsfetchJson (refresher: proxy → curl only, else fetch then curl on transport failure / 403) and fetchJsonNative (collectors, 1.2 s)
src/balance.ts / glm.ts / mmx.tsDeepSeek / GLM / MiniMax: backend detection + response parsing on top of cachedInline
src/env.tsenvFlag() boolean switch parsing
src/cli.tsnpm cc-hud bin: no args → Claude renderer (help on a TTY); <action> codex → Codex commands; --help / --version
src/codex-rpc.tsOne temporary codex app-server --stdio: version gate, JSON-RPC, readUserLayer / writeUserLayer, 10 s deadline, kill on exit
src/codex.tssetup / check / restore of tui.status_line, single-field backup cc-hud-native.json
src/codex-theme.ts, assets/cc-hud.tmThemeOptional theme: tui.theme + tui.status_line_use_colors, theme file install with hash-tracked refresh, separate backup / restore
scripts/launcher.cjsStable-path launcher copied by setup; resolves the newest installed cc-hud each tick
scripts/test.cjsnpm test runner: enumerates tests/*.test.{ts,cjs} explicitly and enables type stripping
commands/setup.mdThe /cc-hud:setup procedure (executed by Claude)
.claude-plugin/plugin.json, marketplace.jsonClaude Code plugin + marketplace manifests (version bumped together with package.json and the root plugin.json)
plugin.json, skills/codex-setup/Codex plugin manifest and onboarding skill (Claude Code also loads the skill; its description defers to /cc-hud:setup); the existing marketplace repo serves both
dist/Compiled output — committed; CI fails if it drifts from src/
tests/node:test unit + end-to-end tests (tests/index.test.ts runs the real dist/index.js)
.github/workflows/ci.ymlubuntu / windows / macos × Node 22 / 24 suite, dist-sync check, Node 18 / 20 runtime smoke (both entries + --help)
preview.html, cc-hud-preview.{svg,png}README hero image source and renders; bump the ?v= cache param in README when they change

Development

npm install
npm test             # tsc build + node:test via scripts/test.cjs (the .ts tests need Node ≥ 22.6; dist/ itself runs on ≥ 18)
npm run test:stdin   # build + render one sample line

Render any payload without touching caches or the network:

echo '{"model":{"id":"claude-opus-4-7[1m]"},"effort":{"level":"max"},"context_window":{"used_percentage":42}}' \
  | CC_HUD_NO_REFRESH=1 node dist/index.js | sed 's/\x1b\[[0-9;]*m//g'
# [Opus 4.7 · Max] ████▎░░░░░ 42% (1M)

Exercise the refresher and inspect its cache: node dist/refresh.js claude && cat ~/.cache/cc-hud/claude-plan.json.

Release: bump the version in package.json, .claude-plugin/plugin.json, .claude-plugin/marketplace.json, and root plugin.json; npm test; commit (title ends with (vX.Y.Z)); tag vX.Y.Z; push branch + tag; gh release create; npm publish (package cc-hud).

Codex native footer

Requires Codex CLI ≥ 0.166.0 (checked with codex --version; CC_HUD_CODEX overrides the executable, npm's bin/codex.js is accepted). Install: codex plugin marketplace add WaterTian/cc-hud → codex plugin add cc-hud@cc-hud → new session → run the plugin's setup skill. Update: codex plugin marketplace upgrade cc-hud (installed plugin files refresh too).

Commands — node dist/cli.js <action> codex from the plugin dir or a checkout, or the npm cc-hud bin: setup, check (exit 0 = active), restore, theme, restore-theme; also --help / --version. Errors go to stderr with exit 1. A failed command can leave a backup, an installed asset, or a saved user-layer value (for example, when another layer overrides it); changes are not rolled back automatically. With no arguments the bin is the Claude renderer when stdin is a pipe and prints help on a TTY.

CommandReads / writesBehaviour
setup codextui.status_line in the user config.toml: config/read → config/batchWrite (expectedVersion guard) → re-readPreset model-with-reasoning, context-used, five-hour-limit, weekly-limit, project-name, git-branch. Idempotent. Writes $CODEX_HOME/cc-hud-native.json { schema, previous, applied } (mode 600) only when it first takes the field over; refreshes applied when a release changed the preset. A footer edited since, or overridden by another config layer, is reported — never overwritten. On success, explains that limit colors come from the active theme, independent of remaining quota.
check codexread only"Configured" iff both the user layer and the effective config equal the preset; then prints the same color note. No Codex spawn when $CODEX_HOME does not exist.
restore codexwrites previous back (JSON null removes a key that was absent), deletes the backupTreats the current preset or the one previously applied as "ours"; anything else is a user edit and is left alone.
theme codextui.theme = "cc-hud", tui.status_line_use_colors = true; installs assets/cc-hud.tmTheme → $CODEX_HOME/themes/cc-hud.tmThemeBackup $CODEX_HOME/cc-hud-theme.json { schema, theme, colors, asset }, even when the settings already match; asset is the sha256 of the file installed, so a newer release replaces a file cc-hud wrote but refuses a user-edited one (the message names the path to delete). The legacy theme name cc-hud-mocha counts as ours. Run again after upgrading to refresh an unedited installed theme file. Limits use a fixed neutral teal accent; the theme also changes syntax highlighting.
restore-theme codexwrites the saved theme / colors back, deletes the backup, keeps the theme file

Process model: one temporary codex app-server --stdio per command (cwd and CODEX_HOME = the config dir), JSON-RPC over stdio: initialize → requests → SIGTERM, SIGKILL after 500 ms; 10 s overall deadline. Server notifications and server-initiated requests are ignored; server error bodies are never printed (they can carry private config values). No thread, model, account or usage requests. Normal Codex sessions run with no cc-hud process, hook, MCP or -c flag.

Semantics: Codex's limit percentages are remaining, the Claude HUD's are used. Codex maps 5h / weekly fields to its Limit theme accent (constant.language, fallback storage.type), independent of the numeric value; the user's original theme can make 93% left red. The bundled theme splits constant.numeric (green) from the limit scopes (neutral teal). It does not add usage thresholds: 1% left and 93% left share the same color. Codex controls separators and colors, has no progress bar, and during /compact can briefly show 0% used.

Tests: tests/codex.test.ts drives the CLI against tests/fixtures/fake-codex.cjs, a stand-in app-server with hang / race / write-error / version switches. CC_HUD_CODEX_LIVE_TEST=1 npm test adds a real round-trip against an isolated CODEX_HOME with an offline provider (no auth or model requests); it needs a local Codex ≥ 0.166.0.

Invariants — keep these when changing code

  1. One stdout write per tick — go through emit() in src/index.ts; never console.log elsewhere. The hard timeout and the catch-all both emit the stdin-only line, never nothing.
  2. No network inside a tick on the official backend — src/claude.ts reads the cache; fetching belongs in refreshClaudePlan(). Inline collectors keep INLINE_TIMEOUT_MS (1.2 s) so the 2 s hard exit is never reached.
  3. Unknown is not zero — missing usage renders —%, a failed git status renders ?, a stale gauge / balance / quota gets ~, a finished agent is gone and a dead one times out. Never collapse a failure into a reassuring value.
  4. Every IO in try/catch, degrading to a shorter line. The process must exit 0 with one line even when everything fails.
  5. Free text is untrusted — anything from stdin, the transcript, git or an API passes through clean() in src/render.ts.
  6. Zero dependencies, Node ≥ 18 at runtime — Node built-ins only; no Node 22-only APIs in src/.
  7. dist/ is committed — run npm test (which builds) and commit dist/ with the source change.
  8. Secrets stay out of argv and logs — curl gets its config on stdin; tokens are never written to the cache.
  9. Codex config is written only by the explicit codex commands — three tui.* keys through config/batchWrite with expectedVersion, never by editing TOML text, never from a statusline tick. Every write is re-read and verified; every "ours vs. user-edited" decision errs on the side of leaving the user's value alone.
  10. A fixed quota color is not a health signal — native Codex colors limits by theme scope, not remaining percentage. Keep the bundled limit accent neutral, describe the limitation in setup/check, and leave theme selection optional because it also changes syntax highlighting.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.