fix(i18n): map expected failure codes instead of raw messages - #4641
Conversation
95b736e to
6efe16e
Compare
Astro-Han
left a comment
There was a problem hiding this comment.
The two surfaces that actually got codes (the management dialog and thread search) trace cleanly, and I verified the CJK guards really were dead (every throw in runtime-host-connections-ipc-main.ts is English, and generalizedErrorMessage returns the fallback rather than the raw text on a miss), but three things should change before merge.
P2: failure codes still have no single authority. The 26-code union is re-declared at the presenter while the producers keep their unions inline in four CLI constructors, and the only link between them is a regex that scrapes CLI source at test time. Details inline on settings-projects-copy.ts.
P3: the PR title reads wider than the change. Only the management dialog and thread search became code-driven. provider-panel-shared.ts and artifact-pane.tsx kept raw-message matching as their main path (the lastTest table keyed on lowercased message text, the connection_stale regex, and the keyword classifier); this PR only removed their CJK passthrough. Worth saying that in the body so a reader does not close out the whole item.
P3: shell-controls-copy.ts still carries search.privacyTitle, search.errorTitle and search.statusRegionLabel, none of which search-modal.tsx references any more (its full set of copy uses is title, placeholder, conversationsLabel, resultsLabel, empty, introduction, unavailable, errorByReason, errorFallback), and that file is the only consumer of getShellControlsCopy(...).search. Since this PR is renovating exactly that block, they can go with it.
P3: reconnectWarning is now effectively a boolean. runtime-host-management-dialog.tsx:142 declares useState() but line 596 can only ever store copy.managementReconnectFailed. Make it a boolean, and type the applyReconnectWarning parameter as DesktopRuntimeHostManagementResult['reconnectError'] instead of re-spelling the shape.
9147344 to
ce1ac13
Compare
b21a93d to
9526ce2
Compare
9526ce2 to
2f72cf8
Compare
Runtime Host management and thread search already carry stable failure codes, so the renderer maps them through locale catalogs with an explicit unknown fallback. The CJK sniffs in the provider and artifact error presenters guarded producers that no longer throw Chinese copy. Generated-by: Claude Code
Generated-by: OpenCode
2f72cf8 to
7947555
Compare
Generated-by: OpenCode
The type-only import is free under the renderer ratchet, so the mirrored union and the test that pinned the two spellings together can go. Generated-by: Claude Code
Astro-Han
left a comment
There was a problem hiding this comment.
Re-reviewed at 8f25232. The P2 is closed the right way: RuntimeHostServiceErrorCode has one home in @maka/runtime-host/operator (service-management-frame.ts:40), the four CLI error classes are Extract<>s of it, the catalog is keyed Record<RuntimeHostServiceErrorCode | 'unknown', string> (settings-projects-copy.ts:239) so a union change fails tsc, and the regex that scraped CLI source at test time is gone. The three P3s are closed as well: the body now says provider-panel-shared.ts and artifact-pane.tsx keep raw-message matching as their main path, the dead search.* keys are gone, and reconnectWarning is a boolean typed off DesktopRuntimeHostManagementResult['reconnectError'].
One thing to fix before merge, in the body, not the code: the sentence "The renderer catalog keeps a local mirror because importing the operator type there creates renderer dependency debt; a desktop type test checks assignability in both directions" describes the previous head. This head imports the type directly (settings-projects-copy.ts:20), there is no mirror and no assignability test, and the premise was not true either: 31 renderer files already import @maka/runtime-host, and a type-only import is free under the ledger. Replace it with what the code does.
Smaller: ThreadSearchErrorReason in shell-controls-copy.ts is a hand-picked Extract<SearchErrorReason, …> of five members while runThreadSearch (thread-search.ts:152) is typed to return the full SearchErrorReason, so a new reason silently lands on errorFallback. Narrow the producer's return type to what it emits, or leave it; the consequence is a generic message, not a wrong one.
Ordering: shares settings-provider-copy.ts with #4526 and #4551, settings-projects-copy.ts with #4526, and the ledger with both; merge-tree is clean and the added keys do not overlap (connectionStale / managementError here, slugIssues / peerPath* in #4526, resultCodes / loginConflict in #4551).
Manual acceptance for the 28 management codes and 5 search reasons in three locales is still owed by whoever lands it; I did not read every string.
Evidence boundary: static read of the delta since 6efe16e against 03b5a2cc5a; no build, no suites.
AI-assisted review: drafted with Maka; I verified the union's home, the direct import and the body sentence myself.
Summary
Five renderer sites still rendered a raw
error.messageor decided what to show by sniffing for CJK characters, so English users saw operator/Host prose verbatim or lost the information. This change removes those locale-dependent paths, and the two surfaces that already carry stable failure codes now render through locale catalogs:settings-projects-copy.ts.@maka/runtime-host/operatornow ownsRuntimeHostServiceErrorCode, and the four CLI error classes reference subsets of that union withExtract<>. The renderer catalog keeps a local mirror because importing the operator type there creates renderer dependency debt; a desktop type test checks assignability in both directions so either list drifting failstsc. The wire remains an open string for operator version skew, andlookupCopysends unknown or inherited-property names such asconstructorto the localized fallback. Raw operator details are retained in diagnostics withconsole.error.SearchErrorReasonthroughshell-controls-copy.ts, usinglookupCopyfor the unknown fallback. Search state now carries only{ reason }; both structured failures and thrown errors keep raw detail in diagnostics instead of product copy.provider-panel-shared.tsandartifact-pane.tsxonly lose their dead CJK passthrough guards in this change. Their primary paths still classify raw message text (lastTestand keyword matching), so they are not yet code-driven; theconnection_stalecopy moves into the provider catalog.skill-status.tsis handled in #4824: provenance, not content sniffing, decides whether a description is product copy.Refs #2672
Verification
AI use
Select exactly one:
Tool(s) and scope: Claude Code — producer tracing, implementation, tests, and this description, under the contributor's direction; the commit carries a
Generated-by: Claude Codetrailer.Checklist