Repository navigation
refactor(i18n): show the last plan usage reports through Fluent - #971
Merged
Merged
Conversation
Each usage provider's settings carried their help as English in herdr-usage, which the usage panel's Setup block showed as written. Setting::help becomes Setting::message, the ID of a message in the provider's own locales/en-US/usage-<id>.ftl (156 messages across the providers that read settings). The panel shows it with i18n::message. One file per provider keeps parallel provider PRs out of each other's catalogs. The example config's generated provider section came from the English in herdr-usage. Its generator and bless test move to the app's usage tests, which read the English messages. The section is unchanged byte for byte. A new test checks that every setting names a message without arguments, and the en-XA leak test no longer allows the help as data.
herdr-usage reports carried English Strings for section titles, fact labels and values, share labels, balance labels, window names, and the account line, and count units as English words, which the usage panel showed whatever the language. herdr_usage::Text is now the words a report shows: a message ID with arguments, which the app writes with usage::text::words, or the service's own words. Count units are a typed Count the app writes with a plural (usage-amount-*). Wayfinder names all of its words in usage-wayfinder.ftl; the other providers keep their English through a transitional From<&str>/From<String> for Text and pair/pairs/share/shares helpers, which go once the last of them names its words. A crate below the app cannot use fl!'s compile-time check, so an app test scans herdr-usage for Text::message IDs and the arguments chained to them and checks each against the English messages. The en-XA leak test now draws facts, shares, and a credits balance a provider names.
A fact's value sat at its natural width, so a longer one, as en-XA or another language writes it, ran past the usage card's edge. The value may now shrink and wraps under itself, set against the end side.
…Fluent
Copilot, Cursor, Deepgram, DeepInfra, DeepSeek, Devin, DevPass, Doubao,
ElevenLabs, Factory, Fireworks, Gemini, GitKraken, Grok, Groq, Helmcode,
Hugging Face, Hyper, IBM Bob, JetBrains, Kilo, and Kimi now name each
word their reports show in their own usage-<provider>.ftl: section
titles, fact labels, values with English words or plurals, balance
labels, the windows they name, and plan lines they compose. Names the
services send (plans, models, tenants, products) stay as the service's
words, and none of them uses Text's transitional conversions.
Where a provider matched its own English labels (Cursor's on-demand
budget, Doubao's window periods), it now carries a selector key the
message picks by. Counts whose English never had a singular ("1
credits") keep it byte for byte, with only an other variant for
translators to extend. usage/tests/words_b.rs checks each provider's
messages read in English as it wrote them.
…gh Fluent
Kiro, LiteLLM, llmman, LLM Proxy, LongCat, Manus, MiMo, MiniMax,
Mistral, Moonshot, Muse, Neuralwatt, Notion, Nous, Ollama, OpenAI,
OpenCode, OpenCode Go, and OpenRouter now name each word their reports
show in their own usage-<provider>.ftl. Plans, models, product names
(Vibe, Notion AI, Ollama Cloud), and the services' own status words stay
as the service's words. OneConsole is shared gateway code and shows
none.
OpenAI's unnamed line items and models are now None rather than English
fallback keys, and show through messages. LiteLLM's spend parser takes a
Reporter enum instead of matching its own label. MiMo, Neuralwatt, and
Muse counts gain a singular ("1 credit" where it said "1 credits").
Named windows sort by their words; message IDs are chosen so each
provider's windows keep their order, which its tests hold, and
Report::new documents it. usage/tests/words_c.rs checks each provider's
English reads as it wrote it.
…uent Perplexity, Poe, Qoder, Raycast, Replicate, Sakana, StepFun, Sub2API, Synthetic, T3 Chat, Typesafe, v0, Venice, Vercel, Vertex AI, Warp, Windsurf, xAI, xKiro, Z.ai, Zed, ZenMux, and ZoomMate now name each word their reports show in their own usage-<provider>.ftl. Plan names the providers map themselves, currencies, and tool and protocol names stay as written. Qwen Cloud's words come from the Alibaba token plan code, which the last batch moves, so its test no longer pins them. Pi never reports. Poe's points, Venice's credits, Warp's credits, and ZenMux's flows gain a singular. Synthetic gives its hourly length only to the search slot's own window, not any quota the service names "Search hourly". Z.ai picks its model detail by a selector, and ZenMux names its session and weekly facts rather than borrowing Kind::title's English. usage/tests/words_d.rs checks each provider's English reads as it wrote it.
Abacus, AI& (aiand), Aixy, Alibaba, the Alibaba token plan, Amp, Antigravity, AtlasCloud, Augment, Azure OpenAI, Bedrock, Bifrost, Chutes, Claude (and claude-swap's accounts), ClawRouter, Codebuff, CodeRabbit, Codex, and Command Code now name each word their reports show in their own usage-<provider>.ftl. Plan and product names and the services' own words stay as they send them. Cline Pass shows none. With every provider naming its words, Text's transitional From<&str>/From<String> and the pair/pairs/share/shares helpers go, so a report can no longer carry an English literal: it must be a message or Text::service. The crate's and the app's tests build their fixtures that way. usage/tests/words_a.rs checks each provider's English reads as it wrote it, and docs/i18n.md moves plan usage's reports out of "What is left".
Collaborator
Author
|
|
[Medium impact] The PR appears safe to merge; no blocking issue was found. SummaryMoves the remaining 19 providers’ report text into Fluent messages while keeping service names and values unchanged.
Reviews (4) · Last reviewed commit: "Merge branch 'i18n/usage-providers-d' in..." · Reviewed by Greptile |
Named windows became message IDs in this branch, and the usage command labeled each window with `Kind::title`, which gives a named window's ID: it printed usage-copilot-premium instead of Premium, and Doubao's window lost its plan and period, which only the message's arguments carry. The command now writes a named window through `usage::text::english`, and a test checks the labels and the JSON the command answers.
Z.ai's token totals sorted ties by cloned model names; the sort key now borrows them, with an unnamed model still sorting as Unknown did. Synthetic's search lane runs an hour because it is the dedicated lane, which now holds a message, so a generic quota the service names "Search hourly" is the service's own name and keeps no length. A test pins that.
Collaborator
Author
|
@greptileai review |
Every open i18n pull request edits the remaining list in docs/i18n.md, so each merge made the others conflict. This branch now keeps main's copy; one change updates the list once they have all merged.
# Conflicts: # docs/i18n.md
# Conflicts: # docs/i18n.md
# Conflicts: # docs/i18n.md
# Conflicts: # docs/i18n.md
# Conflicts: # docs/i18n.md
Collaborator
Author
|
@greptileai review |
Collaborator
Author
|
@greptileai review |
✅ Deploy Preview for herdr-ui canceled.
|
shin1ohno
added a commit
to shin1ohno/herdr-gpui
that referenced
this pull request
Nov 3, 2026
Brings in upstream's 30 commits, among them side-by-side agent chats in Herdr 2 panes (sheprd-labs#935), choosing the agent a new worktree opens in (sheprd-labs#948), the Vulkan driver hint (sheprd-labs#977), readable branch divergence counts (sheprd-labs#999), and the next round of i18n Fluent migrations with typed updater reasons (sheprd-labs#951-sheprd-labs#971, sheprd-labs#989). Conflicts: upstream's code wins and the iPad's needs are re-applied on top. Tests that moved into their own files keep this branch's iOS gates. The core terminal state keeps both upstream's pending spawn and the iPad's app-owned SSH workspace, and the iPad focus frame wraps upstream's pane body. The device picker keeps reading Herdr 2 state from the window on iPad and otherwise shows upstream's localized status. The updater stays disabled on iPadOS with upstream's Platform reason, the update panel keeps its iPadOS wording, and plan usage and the orchestrator stay off on iPad. Beyond the conflicts, upstream's changes needed these to build and pass on iPadOS: - Upstream marked app.rs and config.rs as i18n-migrated, which covers app/ios.rs and config/ipad_storage.rs. The theme load failure and the oversized config error get Fluent messages; debug names, the background task name and the diagnostics fallback are marked as data. - config.rs stays under 1,000 lines. The iPad migration warning and the platform read function move into ipad_storage.rs and files.rs. - The iPad startup loads and installs the remembered worktree landing, as the desktop's does since sheprd-labs#948. - Helpers only the desktop's control server and link handling use are compiled out on iOS: the usage English text, the window's link complaint, and, outside tests, Endpoint::status and focused_core_chat_key. Error and test modules for desktop-only link and checkout code are compiled out too. - The iPad sidebar test's chat target names its surface, and the updater's reason test expects the iPadOS reasons on iOS.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #970 (base
i18n/usage-providers-d), then #969, #968, #967, and #955. Merge those first.Summary
The last part of the
herdr-usagereport words in Phase 2 ofdocs/i18n.md, following #967. This PR covers the remaining 19 providers: Abacus, AI& (aiand), Aixy, Alibaba, the Alibaba token plan (which Qwen Cloud shares), Amp, Antigravity, AtlasCloud, Augment, Azure OpenAI, Bedrock, Bifrost, Chutes, Claude (and claude-swap's other accounts), ClawRouter, Codebuff, CodeRabbit, Codex, and Command Code. Cline Pass's report has no words.Messages: each provider names its report's words in its own
usage-<provider>.ftl.usage-claude.ftlandusage-codex.ftlare new. Plan and product names ("Amp Free", Auggie's plans, Codex and Claude plans, Command Code's tiers, Alibaba's editions) and the services' own words (CodeRabbit'sinactive, Chutes' units) stay as they send them.Composed window names: Antigravity's windows use one message with a
$cadenceselector, so they still sort by group first. Bifrost names its windows from nested messages (scope · budget · period).The transitional conversions go: with every provider naming its words,
Text'sFrom<&str>/From<String>and thepair/pairs/share/shareshelpers from refactor(i18n): name plan usage report words as typed text #967 are deleted. A report can no longer carry an English literal: each word is either a message orText::service(..), and anything else fails to compile. The crate's and the app's test fixtures build their words that way.Counts: where the old English never had a singular ("12 routed providers", "{used} / {total} credits"), it stays byte for byte.
Tests: herdr-usage tests assert message IDs and arguments, including the shared Claude fixture in
tests/provider_data.rs.usage/tests/words_a.rschecks that each provider's English reads as it wrote it.docs/i18n.mdis left as main has it: one later change updates its "What is left" list once the open i18n PRs merge.Screenshots
None for this PR: these providers need real sign-ins, which the isolated sandbox doesn't have. #967 shows the same panel and section code with a provider whose report is fully named.
QA
just formatjust ciona8b52be20(macOS arm64): passed, with its base andorigin/mainmerged inFrom<&str>forTextleftwords_a.rs: each provider's English reads as beforejust check-i18n: 4645 messages in 248 files valid and used🤖 Generated with Claude Code
https://claude.ai/code/session_01BFavh7vQNk6CpU1rxrJkHw