{"id":50643093,"url":"https://github.com/funhunter7/claude-limit-guard","last_synced_at":"2026-06-07T10:01:18.004Z","repository":{"id":362885849,"uuid":"1259526207","full_name":"funhunter7/claude-limit-guard","owner":"funhunter7","description":"Claude Code plugin: watch your subscription usage limits in the status line and gracefully save/resume work before you hit them.","archived":false,"fork":false,"pushed_at":"2026-06-06T10:50:32.000Z","size":198,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-06T12:15:55.337Z","etag":null,"topics":["anthropic","claude-code","claude-code-plugin","claude-plugin","developer-tools","productivity","rate-limit","status-line","usage-limits"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/funhunter7.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-04T15:40:58.000Z","updated_at":"2026-06-06T10:50:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/funhunter7/claude-limit-guard","commit_stats":null,"previous_names":["funhunter7/claude-limit-guard"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/funhunter7/claude-limit-guard","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funhunter7%2Fclaude-limit-guard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funhunter7%2Fclaude-limit-guard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funhunter7%2Fclaude-limit-guard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funhunter7%2Fclaude-limit-guard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/funhunter7","download_url":"https://codeload.github.com/funhunter7/claude-limit-guard/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/funhunter7%2Fclaude-limit-guard/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34016490,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-07T02:00:07.652Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anthropic","claude-code","claude-code-plugin","claude-plugin","developer-tools","productivity","rate-limit","status-line","usage-limits"],"created_at":"2026-06-07T10:01:17.371Z","updated_at":"2026-06-07T10:01:17.984Z","avatar_url":"https://github.com/funhunter7.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# claude-limit-guard\n\n\u003e Never get cut off mid-task again. **claude-limit-guard** watches your Claude subscription\n\u003e usage, shows it in the status line, injects it into context, and — at a threshold you\n\u003e choose — gracefully saves a handoff so work resumes cleanly after the limit resets.\n\n[![CI](https://github.com/funhunter7/claude-limit-guard/actions/workflows/ci.yml/badge.svg)](https://github.com/funhunter7/claude-limit-guard/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n![Version](https://img.shields.io/badge/version-0.6.0-brightgreen)\n![Node](https://img.shields.io/badge/node-%E2%89%A518-339933?logo=node.js\u0026logoColor=white)\n![Platform](https://img.shields.io/badge/platform-Windows%20·%20macOS%20·%20Linux-lightgrey)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/demo.svg\" alt=\"Animated demo: the session usage climbs from green to amber to red, then the guard saves a handoff to RESUME.md\" width=\"100%\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/status-line.svg\" alt=\"claude-limit-guard status line: per-window usage %, color band, and reset time — localized to the OS\" width=\"100%\"\u003e\n\u003c/p\u003e\n\n```text\n🟢 Limit session: 72% → 06:00 · 🟢 Week Limit: 39% → Wednesday 6/3/2026 10:00\n```\n\nA colored dot per window (🟢 ok · 🟡 warning · 🔴 over threshold), the live percentage, and\nwhen it resets — a same-day reset shows just the time, a later one adds the weekday and date.\n\n---\n\n## Contents\n\n- [Features](#features)\n- [Requirements](#requirements)\n- [Install](#install)\n- [Commands](#commands)\n- [Configuration](#configuration)\n- [How it works](#how-it-works)\n- [Troubleshooting](#troubleshooting)\n\n## Features\n\n- 📊 **Live status line** — usage % and reset time for the 5-hour and 7-day windows, color-banded.\n- 🌍 **Follows your system** — weekday/date names, message language, time format, and glyph\n  style auto-detect from the OS/terminal (Windows \u0026 Linux). No language to configure.\n- 🛟 **Graceful guard** — at your threshold the Stop hook blocks once and runs a save/handoff\n  routine (or your own action) so nothing is lost; the SessionStart hook offers to resume.\n- 🧭 **Both windows guarded** — the 5-hour *and* the 7-day limit trip the guard.\n- ⚙️ **Menu-driven config** — `/limit-guard-config` and `/limit-guard-action` let you pick\n  settings from lists instead of hand-editing JSON.\n- 🔌 **No network on keystrokes** — reads native `rate_limits` from stdin; falls back to the\n  OAuth usage endpoint only when needed, behind a warm cache.\n\n## Requirements\n\n- Node.js ≥ 18 on `PATH`\n- A logged-in Claude Code (reads `~/.claude/.credentials.json`)\n\n## Install\n\n### From the marketplace (recommended)\n\nIn Claude Code, add this repository as a marketplace and install the plugin:\n\n```text\n/plugin marketplace add funhunter7/claude-limit-guard\n/plugin install claude-limit-guard@claude-limit-guard\n```\n\n(`funhunter7/claude-limit-guard` is the GitHub `owner/repo`; `claude-limit-guard@claude-limit-guard`\nis `plugin@marketplace`.) This auto-registers the hooks, the `/limit-guard-config` and\n`/limit-guard-action` commands, and the `/config` options. Pull updates later with:\n\n```text\n/plugin marketplace update claude-limit-guard\n/plugin update claude-limit-guard\n```\n\n### Local development\n\n```bash\nclaude --plugin-dir /path/to/claude-limit-guard\n```\n\n### Status line (manual)\n\nThe status line is a user setting, so add it to `~/.claude/settings.json` yourself:\n\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"node \\\"%LOCALAPPDATA%\\\\path\\\\to\\\\claude-limit-guard\\\\bin\\\\usage.mjs\\\" --statusline\",\n    \"refreshInterval\": 30\n  }\n}\n```\n\nUse the absolute path to `bin/usage.mjs`. On macOS/Linux use a normal POSIX path.\n\n## Commands\n\n| Command | What it does |\n|---------|--------------|\n| **`/limit-guard-config`** | Pick a setting (`threshold`, `warn_band`, per-window thresholds, `watch`, `label_style`, `reset_display`, `projection_display`, `time_format`, `style`) from menus, choose **global** or **current-project** scope, and set its value — no JSON editing. |\n| **`/limit-guard-action`** | Set or clear the **guard action** (at the threshold) or the **warn action** (in the warn band), globally or per-project. |\n| **`/limit-guard-status`** | Print the resolved config plus a health snapshot — token, status-line cache age, whether the status line is wired, and burn-rate history readings. |\n| **`/limit-guard-stats`** | Summarize recent usage from the rolling ~7-day log: number of readings, peak 5h/7d utilization, and reset count. |\n\nBoth write through a validated helper that preserves your other settings.\n\n## Configuration\n\nSettings you can change **directly in Claude Code** via `/config` (under this plugin's options):\n\n| Option | Type | Default | Effect |\n|--------|------|---------|--------|\n| `threshold` | number | `95` | At or above this usage percentage the guard routine triggers. |\n| `warn_band` | number | `80` | At or above this percentage (but below `threshold`) the status line turns amber. |\n| `threshold_five_hour` | number | _(unset)_ | Per-window guard threshold for the `five_hour` window; overrides `threshold` for it. Blank = use the global `threshold`. |\n| `threshold_seven_day` | number | _(unset)_ | Per-window guard threshold for the `seven_day` window; overrides `threshold` for it. Blank = use the global `threshold`. |\n| `watch` | string (CSV) | `five_hour,seven_day` | Which limit windows to show/guard, comma-separated. Also accepts the (best-effort, when present) per-model windows `seven_day_opus` / `seven_day_sonnet`. |\n| `guard_action` | string | `\"\"` | What Claude should do when the threshold is reached. Leave empty for the built-in save-and-handoff routine. |\n| `warn_action` | string | `\"\"` | Gentle, **non-blocking** advice appended to context while usage is in the warn band (below `threshold`). Leave empty for the built-in message. |\n| `label_style` | enum | `full` | Window labels: `full` (`Limit session:` / `Week Limit:`) or `short` (`5h` / `7d`) to save line width. |\n| `reset_display` | enum | `clock` | Reset time as `clock` (`→ 06:00`), `relative` (`→ in 2h13m`), or `both` (`→ 06:00 (in 2h13m)`). |\n| `projection_display` | enum | `off` | When `on`, adds a burn-rate estimate like `📈 ~1h40m to 90%` for the soonest-to-breach window, from the recent usage trend. |\n| `notifications` | enum | `off` | When `on`, pops up an OS notification once when a window enters the warn band or crosses the threshold (macOS/Linux/Windows, best-effort). |\n\n### Auto-detected (not in the `/config` dialog)\n\nThese follow your environment, so `/config` doesn't prompt for them. Override on demand via\n`/limit-guard-config` or JSON:\n\n| Option | Default | Effect |\n|--------|---------|--------|\n| `locale` | `system` | Language for the weekday/date and messages — follows the **OS locale** (Windows \u0026 Linux), so you needn't set a language. Override with a BCP-47 tag like `cs-CZ`, `de-DE`, `ja-JP`. |\n| `time_format` | `system` | Reset time format: `system` (follow OS), `12` (`→ 5:00 PM`), or `24` (`→ 17:00`). |\n| `style` | `auto` | Status-line glyphs: `auto` (detect terminal), `emoji`, or `ascii` (safe for legacy cmd/conhost). |\n\n### Setting values\n\n- **`/config`** — pick the plugin and edit the values interactively (easiest).\n- **`/limit-guard-config`** — choose values from menus, global or per-project.\n- **`~/.claude/settings.json`** — set them under `pluginConfigs` by hand:\n  ```json\n  {\n    \"pluginConfigs\": {\n      \"claude-limit-guard@claude-limit-guard\": {\n        \"threshold\": 90,\n        \"guard_action\": \"Save a handoff to RESUME.md and stop.\"\n      }\n    }\n  }\n  ```\n  Claude Code passes these to the plugin as `CLAUDE_PLUGIN_OPTION_\u003cKEY\u003e` env vars.\n\n### Per-project override\n\nDrop `.claude/limit-guard.json` and `.claude/limit-guard.md` (copy from `templates/`) into a\nproject to override these settings for that project only.\n\n### Precedence (most specific wins)\n\n| Priority | Source |\n|----------|--------|\n| 1 (highest) | Per-project `.claude/limit-guard.json` |\n| 2 | `/config` option for hooks/commands (`CLAUDE_PLUGIN_OPTION_*`, injected by Claude Code) |\n| 3 | `/config` option read from `settings.json` `pluginConfigs` (covers the status line) |\n| 4 (lowest) | Built-in default |\n\n\u003e The status line is a plain user setting, so Claude Code does not inject the option env vars\n\u003e for it. The plugin therefore reads your `/config` options straight from `settings.json`, so\n\u003e they apply to the status line too — not only to the hooks.\n\n## How it works\n\n- **Status line** — `🟢 Limit session: 72% → 06:00 · 🟢 Week Limit: 39% → Wednesday 6/3/2026 10:00`\n  (emoji = band, % always shown). Labels follow the OS locale — Czech shows `Limit relace:` /\n  `Týdenní limit:`. A same-day reset shows just the time (`→ 06:00`); a reset on another day\n  adds the full weekday and a date so the 7-day window is unambiguous. The date follows the OS\n  locale's field order with slashes and a year — US `6/3/2026` (month first), Europe `3/6/2026`\n  (day first).\n- **UserPromptSubmit / Stop hooks** — inject the live limit; at/above the threshold they\n  instruct Claude to run the guard routine. The Stop hook blocks once per reset window (so it\n  never loops) and covers both the 5-hour and 7-day windows.\n- **SessionStart hook** — offers to resume from the handoff file after a reset.\n- **Rendering \u0026 fallback** — on a legacy Windows console (cmd/conhost) where colored emoji\n  don't render, `style: auto` falls back to ASCII (`[OK] Limit session: 72% -\u003e 06:00 | ...`).\n  A missing/expired token shows `🔑 sign in`.\n\nThe status line reads rate-limit usage from the native `rate_limits` data Claude Code passes\non stdin (Pro/Max, after the first API response), so the per-keystroke path makes no network\ncall. It falls back to `GET https://api.anthropic.com/api/oauth/usage` (your local OAuth token\n— the same source as `/usage`) when that data is unavailable (API-key sessions, before the\nfirst response, older Claude Code). Hooks always call `getUsage()`, which reads the same ~45s\ncache the status line keeps warm — so they hit the OAuth endpoint only when that cache is cold.\n\n## Troubleshooting\n\nThe status line and hooks stay silent on failure (so a network blip never breaks your prompt).\nTwo environment variables help when the reading looks wrong:\n\n| Env var | Effect |\n|---------|--------|\n| `CLAUDE_LIMIT_GUARD_DEBUG=1` | Print fetch/cache/auth decisions to **stderr** (`[limit-guard] …`). Set anything other than ``/`0`/`false`/`no` to enable. |\n| `CLAUDE_LIMIT_GUARD_CC_VERSION` | Override the `claude-code/\u003cversion\u003e` User-Agent sent to the usage endpoint, in case a pinned version is ever rejected. |\n\n## Development\n\n```bash\nnpm test          # node --test (193 tests)\nnpm run lint      # eslint .\nnpm run check     # lint + test\n```\n\nTests pin `TZ=Europe/Prague` for deterministic wall-clock formatting; CI runs them on Node\n18/20/22 and lints on Node 22.\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunhunter7%2Fclaude-limit-guard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffunhunter7%2Fclaude-limit-guard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunhunter7%2Fclaude-limit-guard/lists"}