Uh oh!
There was an error while loading. Please reload this page.
feat(desktop): localize conversations, sessions, and tools - #1194
Merged
Astro-Han merged 11 commits intoJul 18, 2026
Merged
Conversation
…ion-session-localization
…ion-session-localization # Conflicts: # apps/desktop/e2e/session-workbar.spec.ts
Astro-Han
approved these changes
Jul 18, 2026
Astro-Han
left a comment
Contributor
There was a problem hiding this comment.
Approved. Two non-blocking localization follow-ups:
- In the English permission prompt, the stale-request age combines localized wrapper copy with the Chinese-only
formatPermissionRequestWait(), so a request older than two minutes renders text such asWaiting for 6 分钟. The duration formatter should become locale-aware. - Collapsed session groups still wrap counts in hard-coded full-width parentheses, producing English labels such as
Archived(3). Moving the count format into the catalog would keep typography locale-correct.
Neither issue blocks this PR. The catalog ownership, reactive locale wiring, and focused coverage look good.
…ion-session-localization # Conflicts: # packages/ui/src/tool-activity/agent-preview.tsx
Mingqwqqaqforce-pushed
the
feat/1052-conversation-session-localization
branch
from
July 18, 2026 14:53
a07353b to
90bda8bCompareUh oh!
There was an error while loading. Please reload this page.
GabrielDrapor added a commit
to GabrielDrapor/maka-agent
that referenced
this pull request
Aug 5, 2026
Astryx expands the pill only when new messages arrived, so the label reads as a notice rather than an action — but the copy this replaced (apache#1194's `jumpLatest`, dropped by apache#1795) said 跳到最新消息, and keeping the wording users already know beats a semantically tidier rename. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ac5rv6WUKWtMZgQb5QPN16
Astro-Han pushed a commit
that referenced
this pull request
Aug 5, 2026
* fix(ui): localize the Astryx chrome adopted since #1795#1795 moved the chat surfaces onto Astryx ChatLayout and deleted the `label={copy.jumpLatest}` that fed Maka's own scroll-to-bottom button, but never registered the replacement `@astryx.*` keys. Astryx ships no zh catalog, so the pill has been reading "New messages" in a Chinese UI ever since — and the same gap covers every other Astryx surface adopted without its copy. Audited all 219 shipped Astryx keys against the components Maka actually renders (JSX usage, not imports — the barrel re-export makes every component look reachable). 79 rendered keys had no override; this adds them, reusing existing entries where the string is identical rather than duplicating (form.clear, primitives.close/loading, selectPlaceholder). Excluded as dead config per this file's own rule: dateInput.dialogLabel and dateInput.placeholder — DateTimeInput references neither, and no standalone DateInput is rendered. The guard test listed `chat` as a surface Maka does not render, which is what let the regression through; it now guards lightbox only, and a new test pins the chat chrome. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ac5rv6WUKWtMZgQb5QPN16 * fix(ui): keep 跳到最新消息 for the scroll-to-bottom pill Astryx expands the pill only when new messages arrived, so the label reads as a notice rather than an action — but the copy this replaced (#1194's `jumpLatest`, dropped by #1795) said 跳到最新消息, and keeping the wording users already know beats a semantically tidier rename. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ac5rv6WUKWtMZgQb5QPN16 * test(ui): assert the pinned chat overrides exist before checking them `messages[key] ?? ''` coalesced a deleted override to the empty string, which holds no Latin letters and satisfied the translation check on its own — so the loop caught an English value but not a removed key. Verified both ways: deleting the send override now fails with 'missing override', and reverting its copy to English fails with 'untranslated'. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ac5rv6WUKWtMZgQb5QPN16 * fix(ui): localize the Lightbox reached via useLightbox The dead-config guard's surviving entry was as stale as the one #1795 invalidated: chat-turn.tsx opens image previews through useLightbox, which renders Astryx's Lightbox — with four English strings — while a JSX-tag scan for <Lightbox> reports the component unrendered. Add the four overrides (close reuses primitives.close) and retire the ban-list guard entirely: a list keyed to "what we render today" rots silently, and both of its entries had. Live surfaces are pinned by presence tests instead. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ac5rv6WUKWtMZgQb5QPN16 * test(e2e): match the quote token remove button by its localized name The token remove button read 'Remove {label}' only because Astryx's Token had no zh override; now that @astryx.token.remove is localized the accessible name is 移除…, and the /^Remove / locator times out. The spec already addresses every other control by its Chinese name. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ac5rv6WUKWtMZgQb5QPN16 * fix(ui): address review — off-barrel Astryx copy, localize #642 fallback Review findings on #2202, all verified before fixing: - The astryx catalogue expanded SharedUiCopy, which `export *`s through the package barrel — violating the README's off-barrel convention for symbols with no cross-package consumer. It now lives in astryx-copy.ts, deliberately unexported. - The en mirror existed only as a diffable reference and was never applied (astryxMessageOverrides returns undefined for en); dropped rather than left to drift against upstream. - `a` renamed to `astryx`; duplicated presence/Latin-letter assertions extracted into assertChineseAstryxOverrides. - P1: the #642 streaming fallback rendered a bare ChatMessage, which resolves Astryx's shipped 'Message from {sender}' — an English aria-label in a Chinese tree. It now reuses LocalizedChatMessage with the same assistantAriaLabel as the TurnView path. The regression test pins the exact trigger: wait indicators with zero turns — passing a liveTurn instead projects a real turn and takes the localized path, which is how the first draft of the test passed against the bug. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ac5rv6WUKWtMZgQb5QPN16 * fix(ui): prune dead overrides, sweep the whole zh map in tests Maintainer review on #2202, each claim verified before acting: - chatSendButton.send/stop: ChatComposerInput never renders ChatSendButton — composer.tsx supplies its own send button. Pruned; the pinned test now anchors on chatToolCalls.error instead. - appShell.mobileNavigation: gated on shouldShowAutoToggle, and Maka passes breakpoint 'none' + hasToggle false. Pruned. - table.noData / table.filter.* / tableFiltering.filterByColumn: the usage table mounts only the rowHeader plugin and renders EmptyState before Table when rows are empty. Pruned. - New whole-map sweep: every override must target a key Astryx ships, hold no Latin outside {…}, and carry the same top-level ICU arguments as the en default — depth-aware extraction, since plural branch text ({result}) reads like an argument to a naive regex and would flag every zh string that drops an inapplicable plural. - Presence-helper comment reworded: the check reads the override map directly, so a deleted entry yields '' here; at runtime the same miss falls back to Astryx's shipped en catalog. Sweep red-validated both ways: a misspelled key fails membership, an English value fails the Latin check. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ac5rv6WUKWtMZgQb5QPN16 --------- Co-authored-by: Claude <noreply@anthropic.com>
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 freeto 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.
Summary
@maka/uiand desktop presentation helpersBoundary
This is PR 3 of #1052: conversation, session, and tool surfaces.
personalization.uiLocaleremains the single persisted preferenceauto -> zhremains unchanged until the PR 4 completion gateVerification
Linux ext4 checkout, Node 24.18.0:
npm run lintnpm run buildnpm run typechecknpx knip --workspace apps/desktopnpx knip --workspace packages/uinpm run build:testnpm run test:dist: all workspaces passed; desktop 2701/2701Local WSL/Xvfb runs throttle requestAnimationFrame to ~2 seconds in the two long-scroll geometry tests. The same two timeouts reproduce on unmodified upstream
mainwith identical 31.6k DOM height, 19 steps, 38 frames, and ~31 second deadline; GitHub's hosted E2E job remains the authoritative gate.Part of #1052.