Repository navigation
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d512653405
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "m_326c02a5cb9ae742": "role=\"tabpanel\" aria-labelledby=\"__VIREO_SLOT_0__\" tabindex=\"0\" data-state-key=\"__VIREO_SLOT_1__\">__VIREO_SLOT_2____VIREO_SLOT_3__</div>", | ||
| "m_61ebde6ce0278343": "data-temporal-ms=\"__VIREO_SLOT_0__\" data-temporal-mode=\"__VIREO_SLOT_1__\">__VIREO_SLOT_2__</div>", |
There was a problem hiding this comment.
Restore literal tag terminators in render fragments
These catalog values are concatenated into partially constructed opening <div> tags, but > is not treated as tag-closing syntax while the HTML tokenizer is inside a tag. Consequently, every localized :::tabs panel and valid :::until/:::after block produces malformed markup, often swallowing its body into the opening tag instead of rendering it. Preserve a literal > in both structural fragments; the Chinese catalog contains the same corruption.
Useful? React with 👍 / 👎.
| "m_6518ddaaddaaf1ac": " <changefreq>每日</changefreq>\n", | ||
| "m_28b76f58ad108f42": " </url>\n", | ||
| "m_86c491782b0043ca": " <changefreq>每周</changefreq>\n", | ||
| "m_a2aca12bc7570ba7": " <loc>__VIREO_SLOT_0__/博客</loc>\n", | ||
| "m_d190756ad4548f50": " <loc>__VIREO_SLOT_0__/博客/__VIREO_SLOT_1__</loc>\n", |
There was a problem hiding this comment.
Keep sitemap routes and enum values untranslated
With the production default locale zh-CN, /sitemap.xml now emits unsupported <changefreq> values such as 每日/每周 and advertises /博客 URLs even though the application route remains /blog. Crawlers may ignore the invalid frequency fields and will crawl wiki-slug fallbacks rather than the real blog pages, so these protocol values and route segments must remain daily, weekly, and /blog regardless of locale.
Useful? React with 👍 / 👎.
| "m_c738b61460f613ac": "| Name | Value |\n", | ||
| "m_f076669f17b53f92": "| Name | Value |\n\n", | ||
| "m_6e5c1fafcd87247d": ":::tab Tab 1\n", | ||
| "m_d7cafcbd87c399b7": "Content :::\n", |
There was a problem hiding this comment.
Preserve the closing directive on its own line
In the English editor, selecting the tabs, accordion, or steps autocomplete scaffold inserts this fragment after the first child header. Because the translation changed Content\n:::\n to Content :::\n, the child directive no longer has a standalone closing ::: line and the block parser cannot recognize the generated structure. Keep the source line breaks while translating only the placeholder text.
Useful? React with 👍 / 👎.
| "m_7d564631b75f58ca": "插入脚注", | ||
| "m_90f5c358f338ef2c": "[* 脚注内容]", | ||
| "m_eeb99d66983b2d76": "展开/折叠", | ||
| "m_6754eb453d1381b3": "[+ 展开/折叠标题] 隐藏内容在这里。 [-]", |
There was a problem hiding this comment.
Preserve newlines in the Chinese fold snippet
For the default Chinese locale, the editor's expand/collapse toolbar button inserts this one-line string, while the renderer only recognizes fold syntax when the [+ ...] header, body, and [-] terminator are separated by newlines. The generated snippet therefore renders as literal text instead of a fold; retain the two source newlines in the translation.
Useful? React with 👍 / 👎.
| @@ -7,6 +7,7 @@ | |||
| // classic-script-global 호환은 필요 없다. 이 파일은 service worker 컨텍스트에서만 평가된다. | |||
|
|
|||
| /// <reference lib="webworker" /> | |||
| import { ui } from '../../packages/wiki-shared/src/i18n/client'; | |||
There was a problem hiding this comment.
Keep the proxied service worker self-contained
Importing the shared i18n client makes Vite/Rollup emit a shared chunks/... import from the sw.js entry because the same module is used by many entries. The application serves that built file through the root URL /sw.js, so its relative import resolves as /chunks/... rather than /dist/chunks/...; that asset does not exist and new module service-worker registrations fail, while the classic fallback cannot parse the generated import. Inline the required message or otherwise ensure the proxied worker's chunk URLs resolve correctly.
Useful? React with 👍 / 👎.
| "m_ab81ac6483934fb3": "Unknown key: \"__VIREO_SLOT_0__\" — only type, labels, series are supported (series items require indentation).", | ||
| "m_0e36ab1fef14b593": "type is required (bar, line, pie, doughnut, radar).", | ||
| "m_ed77553468de39f6": "labels are required (e.g. labels: [1Q, 2Q, 3Q, 4Q]).", | ||
| "m_30bbebfd6 |
There was a problem hiding this comment.
Set the crawler document language from the active locale
The crawler template is now used for translated English and Chinese responses, but it still emits <html lang="ko"> for both. This contradicts the response's localized content and Content-Language header, causing screen readers and search engines to apply Korean pronunciation and language classification to English or Chinese crawler pages. Interpolate the negotiated locale into the document language instead of retaining the former Korean-only value.
Useful? React with 👍 / 👎.
| export const USER_READ_TOOL_DEFS: McpToolDef[] = [ | ||
| { | ||
| name: 'read_revision', | ||
| description: '특정 리비전의 본문을 읽어옵니다. revision_id 는 get_recent_changes 응답에 포함된 정수 id 이며, title 은 그 리비전이 속한 문서 슬러그입니다. raw=true 로 설정하면 위키 문법 변환을 건너뜁니다 (기본은 위키 문법 그대로 반환). 응답에는 본문, 작성자, 생성 시각이 포함됩니다.', | ||
| description: ui("m_35463423c1da3db2"), |
There was a problem hiding this comment.
Build MCP definitions inside the request locale
These exported tool definitions call ui() while the module is being initialized, before localeMiddleware has established an AsyncLocalStorage context. They are therefore permanently populated from the hard-coded zh-CN fallback, so even an MCP request negotiated with ?lang=en receives Chinese tool descriptions and schemas; the draft lifecycle constants below have the same problem. Construct or translate these values per request rather than caching localized strings at module scope.
Useful? React with 👍 / 👎.
| @@ -353,7 +354,7 @@ discussionRoutes.post('/discussions/thread/:id/comments', requireAuth, requirePe | |||
| } | |||
|
|
|||
| const link = `/w/${encodeURIComponent(discussionInfo.slug)}?mode=discussions&id=${discussionId}`; | |||
| const notifContent = `'${discussionInfo.title}' 토론에 새 댓글이 달렸습니다.`; | |||
| const notifContent = ui("m_417980f272a6a783", [discussionInfo.title]); | |||
There was a problem hiding this comment.
Avoid persisting the sender's locale in notifications
This text is translated in the comment author's request context and then stored verbatim in every recipient's notifications.content and push payload. If an English user comments on a discussion followed by Chinese users, all those users permanently receive an English notification even when fetching the notification list under zh-CN (and the reverse also occurs). Persist a locale-independent message key plus arguments, or resolve each recipient's locale when creating/rendering the notification.
Useful? React with 👍 / 👎.
| "m_1596d8fae424d0ca": "<span><kbd>Enter</kbd> Select</span>", | ||
| "m_115518dce9b7a39f": "<span><kbd>Tab</kbd> Search all</span>", | ||
| "m_2a9b0e7c31cc401b": "<span><kbd>Esc</kbd> Close</span>", | ||
| "m_d5fe8044502d75dd": "”</strong> 전체 검색", |
There was a problem hiding this comment.
Translate the command-palette all-search label
The English catalog retains the Korean suffix 전체 검색, and the command palette concatenates this value directly after the user's query for its global-search result. Consequently, every English user who types a query sees a mixed-language primary action despite the rest of the palette being translated. Replace the retained Korean text with the English label; the Chinese catalog contains the same untranslated value.
Useful? React with 👍 / 👎.
VireoWiki now has a persistent Simplified Chinese / English interface selector. The migration covers static shells, dynamic page UI, editors, admin dialogs, service-side messages and bundled extensions, with localized dates and sorting. Wiki content, markup syntax, namespace prefixes and API status identifiers remain unchanged.
Locale is isolated per request using AsyncLocalStorage. Astro emits both language shells and Worker routes select the appropriate assets. HTML/JSON responses carry Content-Language and avoid shared language-cache leakage. Interpolation values retain existing escaping. Cloudflare production settings continue to deploy the existing vireowiki Worker and preserve its secrets.
Validation: server and client TypeScript checks passed; 9 i18n tests passed, including catalog/slot parity, template structure, protected content, request negotiation/concurrency and all 42 generated shells; production build and Wrangler dry-run passed. CI runs these checks for PRs and main updates. Maintenance notes are in I18N.md.