Bundle translation worked, but the UI still showed Chinese. The visible text
does not come from plugin bundles at all: plugin descriptors, model and
provider names, and settings descriptions reach the browser as JSON over /api.
Measured in the Plugins view, all 76 distinct Chinese characters came from
/api/pluginManager/listBundles, which the bundle seam cannot see.
Add a second seam on the typert gateway. It resolves its own dispatchRpc per
request, so overriding that instance method intercepts every /api call without
claiming the interceptor slot the gateway already owns.
Rewriting JSON is deliberately narrow. An allowlist covers the six endpoints
that return server-authored copy; everything else, notably /api/session/list,
carries the operator's own prompts and transcripts and is left alone.
Three shapes needed handling, each found by testing against the live server:
- Locale maps ({ zh, en }) resolve to the English sibling, because the author's
own English beats a dictionary pass.
- Bilingual descriptors joined by " · " keep their English half, which covers
every such descriptor without a dictionary entry.
- Keys are not always trustworthy: dshmarket publishes its bilingual string
under `en` and a short English one under `zh`, and one plugin repeats the same
string under both. A locale map is therefore detected by shape, and an English
sibling is only used when it is itself free of Chinese.
Also harvest author-written { zh, en } pairs from plugin locale maps (331
entries) as the highest-precedence dictionary source, and extend the curated
supplement with the vocabulary that unlocks whole families at once: "免费" alone
covers about twenty model names.
Measured on a live server: 107 -> 0 visible Chinese characters across the home,
Plugins, and Automation tasks views, 0 residual Chinese across all six
allowlisted endpoints, no page errors, and both bundle combos still compile.