Repository navigation
Releases
v1.6.2
Fixed
- Running the integration suite from a Herdr pane no longer disrupts the current Agent view or temporarily puts a Space header between its own agents.
- Forced quota refresh restores the Agent view. Herdr drops a plugin-owned view on disable, and enable does not run startup, so Space grouping fell back to native
groupeduntil the next server restart. Event/focus/watch still do not touch the view. - The Cursor hook wrapper lives in plugin state instead of
~/.cursor.afterAgentResponseandstopeach spawnedbashagainst a Cursor-provenance path, so Ghostty promptedSystemPolicyAppDatatwice per turn. Restart an already-running Cursor pane after configure so it reloadshooks.json. - macOS no longer opens Cursor.app's
~/Library/Application Support/Cursor/…/state.vscdbunless$CURSOR_STATE_DBis set, and Herdr-spawned processes no longer read~/.cursorunless$CURSOR_HOME/$CURSOR_AUTH_FILE/$CURSOR_STATE_DBis set. Credentials stay on Keychain; model/cache/context stay on the hook mailbox. The Keychain approval marker moves to plugin state, and a CLI login never falls through to the IDE token.
Added
- Agent setup playbook (
docs/agent-setup.md,docs/agent-setup.zh-CN.md) and a copy-paste prompt in both READMEs, covering local CLI detection, matching collector installation, font maps, Herdr integrations, and macOS Keychain approval.
v1.6.1
Fixed
- Teal (unseen-done) brand icons no longer sit one cell to the right of idle ones. Colour is a
rulesmatch on$quota_iconso the glyph stays the first identity token; a later$quota_icon_donetwin hang-indented under the Space name. Working uses U+2061, not ZWNJ: ZWNJ joins the vendor PUA glyph and the icon font then draws a yellow?. - Cursor quota follows a
cursor-agent loginaccount switch on macOS. The CLI now stores that login in Keychain (cursor-access-token/cursor-user) and no longer writesauth.json; the collector was falling through to a stale desktopstate.vscdbtoken. It now reads the CLI Keychain item (after a one-time--keychain-approve) and does not borrow the IDE token whilecli-config.jsonstill hasauthInfo. - Cursor sidebar model follows the CLI footer after a model switch:
lastUsedModelofdefault/autousescli-config.jsoninstead of staying labelled Auto.
Changed
- Account quota windows (
5h/7d/30d) appear on one pane per login-scoped vendor in each Space (Grok, Codex, Devin, OpenCode, Cursor). Extra tabs of that vendor in the same Space stay in the Agent panel with their model, topic, and context; only the duplicate 5h/7d/30d rows are omitted. On a wide sidebar, two or more panes of the same vendor nest: the head is the brand icon, vendor name, and quota; extra tabs have no icon and use the same Space indent. Narrow sidebars stay flat.
v1.6.0
Changed
- Agent order defaults to
quota: Space grouping with least headroom first
inside each space.configurealso writesui.agent_panel_sort = "spaces"
when the user has not set a sort themselves. - Default sidebar fields omit cache and TTL (
provider,topic,model,context,5h,7d,30d).
Turn them on in settings when needed. - Sidebar identity uses Space group headers plus brand icons whose colour
mirrors Herdragent_status(working / done / idle) — nostate_iconring.
README screenshots show the wide gauges layout only.
Added
- The Claude Code status line ends with a spending pace for the binding
quota window,⏱ 5h ↓12%: quota consumed versus how much of the window's
clock has run, in points.↓means slow down,↑means there is headroom,
=is within five points. It paces against the live window with the least
remaining quota and names it (5h/7d); when that window cannot be paced
nothing is shown rather than pacing the looser one: no reset time, expired,
or in the first 5% of the window. - Cursor Agent CLI is a supported harness:
--agent cursor,--provider cursor,
its own settings row, and a sidebar row with a Cursor brand color. Quota is
the included monthly pool from the same
aiserver.v1.DashboardService/GetCurrentPeriodUsagecall the CLI makes,
authenticated withaccessTokenin~/.cursor/auth.json(macOS) or
$XDG_CONFIG_HOME/cursor/auth.json(Linux), or$CURSOR_AUTH_FILE. When
that file is missing or has no token, the collector reads only
cursorAuth/accessTokenfrom the desktop app'sstate.vscdb, opened
read-only. The IDE database's mtime is never a credential gate. Included
follows the CLI usage panel:totalPercentUsedwhen present, otherwise
includedSpend / limit. Auto, API, and Included map onto at / api / 30d.
A 30d sidebar field was added so a monthly window is not hidden behind 7d.
Model comes from
cli-config.json(selectedModelmapped throughmodel.displayName); a
session'slastUsedModeloverrides it. The sidebar title uses Grok's hue.
The generated session title (meta.jsontitle, elsestore.dbname) is
the topic, so a follow-up does not replace the session name; placeholder
New Agentfalls back to the last<user_query>in the session jsonl.
Cursor panes are never read. Cache and context come from the interactive CLI's
afterAgentResponse/stop/preCompacthooks (token counts and, when
present,context_usage_percent/context_window_size). Composer 2.x
uses its documented 200k window when the hook omits the size. Cycle end is
Unix milliseconds. Snapshots are stamped with
sha256("cursor\0" || token). The collector never writes or refreshes
Cursor credentials, never opens Keychain, and never calls a bareagent
binary.
Fixed
-
Sidebar quota rows that would have printed
N/Aare omitted instead, for
every provider. A missing or expired 5h/7d/30d window no longer occupies a
row;quota_errorstill explains an unusable snapshot. -
Cursor
cxnow readsstore.dbtoken_details(used_tokens/
max_tokens), the same conversation accounting the CLI footer shows as
Auto · 8.1%. Hook mailboxes still supply cache, and remain the fallback
when a session store has no token details. -
Agy Gemini sessions also publish the third-party (Claude/GPT) pool as
api
on the monthly slot, so that quota is visible without replacing 5h/7d. -
Cursor sidebar topic prefers the generated session title over the last
<user_query>, so a follow-up like "look back at our todos" no longer
replaces the session name. PlaceholderNew Agentstill falls back to the
last query. -
Grok sidebar topic uses
summary.jsongenerated_title(else
session_summary) from the local session metadata, so a pane whose last
prompt has scrolled off still has a name. Chat history is not read. -
Codex sidebar model no longer sticks on the session-start
turn_context.
A long turn writesturn_contextonce at the beginning, then enough
token_count/ tool output that the 256 KB tail has no model line. The
previous head fallback then published the first turn's model (Codex/gpt-6-astra
while the TUI footer already showedgpt-5.6-sol). The collector now
scans backwards from EOF for the latestturn_context, capped so a 40 MB
rollout is not read on every watch pulse. -
rustls0.23.43 → 0.23.45 (RUSTSEC-2026-0285). It is aureqTLS
dependency; the collector sends bearer tokens to provider endpoints, so a
known-vulnerable handshake stack failscargo audit --deny warnings.
v1.5.5
Added
- Muse Code (Meta Muse Spark) is a supported harness:
--agent muse,--provider muse, its own settings row, and a sidebar row with a Muse brand color. Quota is thesubs_usageblock of the samemuse-code/keycall the CLI makes at startup and for/usage, authenticated with the account login in~/.config/muse/auth.json(or$XDG_CONFIG_HOME/$MUSE_AUTH_PATH). Astorage: "keychain"login (typical on macOS) keeps the token out of that file; the collector reads the CLI's Keychain item throughsecurity find-generic-password, with a deadline so a prompt cannot stall a refresh, and keeps a successful token in-process for the daemon lifetime. The call returns the key the CLI already stored, so polling it does not sign Muse out. The session window is published as 5h and the weekly window as 7d; a different advertised session length keeps its own label. Only the usage block is read — the key and account identity in the same response are discarded. Snapshots are stamped withsha256("muse\0" || token). API-key logins and inactive subscriptions show no quota but keep the session fields below. A rejected token or a failed request keeps the last quota cached for that account. - Muse panes get model, topic, context, and cache like other agents. Herdr reports no Muse session, so on Linux the pane is matched to its session through Muse's own
.session.lock(pid=<n>) and theHERDR_PANE_IDthemuse-binprocess inherited. The session'ssession.jsonltail supplies the last model call's model and token usage — context against the localmodel-cataloglimit, cache as that call's read share — and the last submitted prompt as the topic, so Muse panes are never read for a topic. Muse publishes no prompt-cache lifetime, so there is no TTL. Without that evidence (for example on macOS) the pane shows quota and the default model only. - The provider name is a sidebar field like any other:
--fieldsand the settings pane acceptprovider, listed first. It defaults on, so an existing configuration renders exactly as before; turning it off leaves the row with its icon and numbers. A packed identity row follows its two halves, so hiding the model degrades$quota_provider_modelto$quota_provider, hiding the provider degrades it to$quota_model, and hiding both writes no identity row. The error token stays unconditional: it says the plugin could not speak for a pane, which is a failure, not a field.
Fixed
- A saved agent list that was complete before a new provider was added no longer makes
configureabort when omp is not installed. Those builds wrote "everything on" as an enumeration (claude,codex,grok,agy,opencode,pi,omp,devinbefore Muse), which was then judged partial against the longer supported list, so a missing omp integration became a hard failure. That exact prefix is still read as every agent. A complete selection is now stored asall, and a subset with a leadingonlymarker, so turning the newest agent off is not mistaken for the legacy full list. - An idle pane now follows its own session's quota as soon as the cache has it. A Claude statusLine hook only writes the observation mailbox, so a pane that never starts a turn kept publishing whatever it last published: one pane sat on
7d 24%and5h N/Awhile its session's stored windows had moved on and every sibling pane showed the new reading. A watch pass now also covers an idle pane whose published quota rows differ from the ones its cached snapshot would render, alongside the existing expired-window case. - A
fieldspreference saved before the provider was a field no longer hides the provider on upgrade. Those builds wrote "everything on" astopic,model,cache,ttl,context,5h,7dand drew the provider name regardless, so that exact list is still read as every field. A selection that hides only the provider is stored with a leadingno-providermarker, which names it without being mistaken for that legacy list. - Gauges now keeps
no cachedas an amber token when it joins the cache row; live TTL continues to fold into the uncoloured cache token. omp usagenow passes--profilewhen the pane's agent directory is an omp named profile (~/.omp/profiles/<name>/agent), so that pane is billed to the profile's credential store rather than the default one. Non-profile layouts still usePI_CONFIG_DIR.
v1.5.4
Added
- A third sidebar layout,
gauges, now the default: each quota field gets its own row with a meter beside the number. Bars fill to the printed number, socx,5h,7dand30dall followquota-percent(remaining by default). Labels are three characters so those periods align; a provider-named window too long for the column keeps a plain row. Cache and TTL share a line when they fit (cache 95.2% · ttl≈29m) and split when the sidebar is too narrow. Meters size to the connected Herdr endpoint after its secondary-row indent and scrollbar — six cells at the default 26 columns, twelve at 32 or wider — and drop rather than clip. Thecxrow takes a muted green/amber/red colour from remaining context. New installs usegauges. Existingpackedorstackedpreferences are kept and can still be chosen from the settings pane.
Fixed
- A
gaugessidebar that is too narrow for a meter no longer flips the context number from remaining to used. Width lookup reads the connected endpoint's client-shell file instead of whichever state file was written last.
v1.5.3
Fixed
- Idle panes no longer keep a frozen remaining count after a quota window resets. One policy covers every collector: a cached window whose reset is in the past bypasses the 60-second fetch debounce, and a watcher already running for another agent includes only those panes whose displayed windows have expired. Codex
/statusis still a session-local cache and is not scraped.
v1.5.2
Drops the duplicate gray native agent row from managed sidebar layouts.
- Keep Herdr's machine/workspace/tab row and the branded provider/model line (
Grok/grok-4.6,Codex/...). - Omit the native
agentrow sogrokis not stacked aboveGrok/grok-4.6. - Uninstall still restores Herdr's default
agentrow. Custom user-owned rows are unchanged.
Requires Herdr 0.9.0+. Upgrade from your repository directory:
git pull --ff-only
./install.shExisting preferences are retained. Restart sessions only if newly added hooks need loading.
Validation: cargo fmt --all -- --check, cargo clippy --all-targets --all-features -- -D warnings, cargo test --all-targets --all-features --locked.
Changes: #62
v1.5.1
Fixes stale quota after Herdr upgrades and incorrect quota attribution after account changes.
- Recover background refresh automatically across server handoffs and plugin upgrades; include every supported working agent and a final refresh after turns settle.
- Keep quota bound to verified credentials or sessions, retain OMP multi-account readings, and remove unverified Codex rollout windows.
- Preserve preferences and migrate compatible caches during normal installation. Claude/Agy quota remains session-local; unknown Agy model pools no longer produce guessed values.
- Simplify and align usage, upgrade, contribution, and security documentation.
Requires Herdr 0.9.0+. Upgrade from your repository directory:
git pull --ff-only
./install.shNo cache deletion or manual watcher management is required.
Validation: 508 tests; Linux/macOS CI, formatting, Clippy, release build, dependency audit, and plugin manifest checks.
Changes: #60
v1.5.0
Compatibility
Requires Herdr 0.9.0 or later (previously 0.8.0).
Changed
- Preserve Herdr's native machine/workspace/tab and agent identity rows above quota fields in packed and stacked layouts.
- Keep native token styling; Space Git information and worktree grouping remain under Herdr's control. Quota ordering remains opt-in.
Fixed
- Refresh the pane named by a focus event, preventing delayed events and independent clients from refreshing another pane.
- Preserve custom fields and styles added to managed shared Agent rows during reconfiguration, while migrating recognized older plugin layouts.
Validation
501 tests, formatting, Clippy, locked release build, and Herdr 0.9.0 configuration validation passed locally. PR CI checks Linux, macOS, dependency advisories, and the plugin manifest.
Full changes: #59
v1.4.0
Added
- Devin CLI is a supported harness, with its own settings row, brand color, daily/weekly quota from the CLI
GetUserStatuscontract, and per-session models fromsessions.db. configure --applynow leaves foreign or user-owned sidebar rows intact instead of replacing them.
Changed
- Devin private orchestration under
.devin/is not part of the published tree.
Fixed
- Idle Claude panes on the same
CLAUDE_CONFIG_DIRprofile share that profile's newest 5h/7d reading. A later idle statusLine tick cannot roll the shared percentage back. Expired windows render as unknown. (#57) - Custom sidebar rows keep their tokens when generating
rows_by_agent. configurereports which user-ownedrows_by_agententries it left alone.- Non-semantic sidebar text inherits Herdr's active theme.
Full notes: https://github.com/levi-qiao/herdr-agent-quota/blob/v1.4.0/CHANGELOG.md