Skip to content

fix(i18n): map expected failure codes instead of raw messages - #4641

Merged
Astro-Han merged 4 commits into
apache:mainfrom
orangeCatDeveloper:fix/locale-sniff-raw-message
Sep 5, 2026
Merged

fix(i18n): map expected failure codes instead of raw messages#4641
Astro-Han merged 4 commits into
apache:mainfrom
orangeCatDeveloper:fix/locale-sniff-raw-message

Conversation

@orangeCatDeveloper

@orangeCatDeveloper orangeCatDeveloper commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Five renderer sites still rendered a raw error.message or 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:

  • Runtime Host management maps the operator's service error codes in settings-projects-copy.ts. @maka/runtime-host/operator now owns RuntimeHostServiceErrorCode, and the four CLI error classes reference subsets of that union with Extract<>. 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 fails tsc. The wire remains an open string for operator version skew, and lookupCopy sends unknown or inherited-property names such as constructor to the localized fallback. Raw operator details are retained in diagnostics with console.error.
  • Thread search maps its typed SearchErrorReason through shell-controls-copy.ts, using lookupCopy for 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.ts and artifact-pane.tsx only lose their dead CJK passthrough guards in this change. Their primary paths still classify raw message text (lastTest and keyword matching), so they are not yet code-driven; the connection_stale copy moves into the provider catalog.
  • Seven unused search catalog fields are removed, and the Runtime Host reconnect warning state is represented as a boolean.

skill-status.ts is handled in #4824: provenance, not content sniffing, decides whether a description is product copy.

Refs #2672

Verification

desktop typecheck:                      0 errors
desktop main tests (dist):              2092 pass / 0 fail
packages/ui tests (dist):               365 pass / 0 fail
packages/cli Runtime Host tests (dist): 269 pass / 0 fail
renderer architecture:                  passed against origin/main (ledger unchanged)
knip (desktop/ui/cli/runtime-host):      no new findings
format:check / biome lint:               clean
check:tui-copy:                          clean

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

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 Code trailer.

Checklist

  • Tests cover the change and fail without it

@github-actions github-actions Bot added the effort/M Under 500 readable lines label Sep 3, 2026
@orangeCatDeveloper
orangeCatDeveloper force-pushed the fix/locale-sniff-raw-message branch 3 times, most recently from 95b736e to 6efe16e Compare September 3, 2026 10:15
@orangeCatDeveloper
orangeCatDeveloper marked this pull request as ready for review September 3, 2026 10:16

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread apps/desktop/src/renderer/locales/settings-projects-copy.ts Outdated
Comment thread apps/desktop/src/renderer/locales/settings-projects-copy.ts Outdated
Comment thread apps/desktop/src/renderer/settings/runtime-host-management-dialog.tsx Outdated
Comment thread apps/desktop/src/renderer/features/connection-settings/provider-panel-shared.ts Outdated
Comment thread packages/ui/src/search-modal.tsx Outdated
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
@orangeCatDeveloper
orangeCatDeveloper force-pushed the fix/locale-sniff-raw-message branch from 2f72cf8 to 7947555 Compare September 5, 2026 11:27
@orangeCatDeveloper
orangeCatDeveloper marked this pull request as ready for review September 5, 2026 12:19
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 Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@Astro-Han
Astro-Han merged commit c14eb12 into apache:main Sep 5, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/L Under 1000 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants