chore(i18n): humanize zh tool card labels in chat stream#282
Conversation
📝 WalkthroughWalkthroughUpdated Chinese UI translation strings in Changes
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Code Review
This pull request updates several Chinese translation strings in packages/ui/src/i18n/zh.ts to provide more descriptive and user-friendly names for various tools, including list, glob, grep, webfetch, shell, patch, and questions. I have no feedback to provide.
Replace English/cryptic Chinese labels on tool call cards in the conversation stream so non-technical users can understand at a glance what action the AI just took. - list 列表 → 列出目录 - glob Glob → 查找文件 - grep Grep → 文本搜索 - webfetch Webfetch → 读取网页 - shell Shell → 执行命令 - patch 补丁 → 批量修改 - todos.read 读取待办 → 查看待办 - questions 问题 → 向你提问
c53aba8 to
3e5cb4a
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/ui/src/i18n/zh.ts`:
- Line 109: The translation key "ui.tool.questions" currently maps to "提出问题" but
the PR's target copy mandates "向你提问"; update the value for the ui.tool.questions
entry in packages/ui/src/i18n/zh.ts to "向你提问" so the string matches the release
copy and stays consistent across the project.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 5bf34e1d-a5fa-4689-928e-3281c5a12f8e
📒 Files selected for processing (1)
packages/ui/src/i18n/zh.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
- GitHub Check: smoke-macos-arm64
- GitHub Check: unit-windows-opencode-config-project
- GitHub Check: unit-windows-desktop
- GitHub Check: unit-windows-opencode-session
- GitHub Check: unit-windows-opencode-server-tools
- GitHub Check: unit-windows-app
- GitHub Check: unit-desktop
- GitHub Check: typecheck
- GitHub Check: unit-opencode
- GitHub Check: unit-app
- GitHub Check: e2e-artifacts
- GitHub Check: analyze-js-ts
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 224
File: packages/app/src/i18n/zh.ts:0-0
Timestamp: 2026-04-24T17:08:46.780Z
Learning: In Astro-Han/pawwork PR `#224`, the first-occurrence `PawWork 爪印` branding rule originally specified in issue `#196` was superseded by an updated Chinese-branding spec. On all zh UI surfaces in `packages/app/src/i18n/zh.ts` (e.g., `dialog.model.unpaid.freeModels.title`, `session.new.subtitle`, `sidebar.gettingStarted.line1`), the correct and intentional target is fully localized `爪印` branding — no `PawWork` prefix. Do NOT flag these strings as missing the first-occurrence `PawWork 爪印` rule in future reviews.
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 98
File: packages/desktop-electron/src/main/menu-labels.ts:1-2
Timestamp: 2026-04-22T05:32:29.012Z
Learning: In Astro-Han/pawwork, the app i18n layer (`packages/app/src/i18n/`) only contains `en.ts` and `zh.ts`, and `normalizeLocale` (in `packages/app/src/context/language.tsx`) only returns `"en"` or `"zh"`. The desktop `MenuLocale = "en" | "zh"` union in `packages/desktop-electron/src/main/menu-labels.ts` is intentionally limited to these two locales and is not a broader restriction — do not flag it as overly restrictive or suggest adding other locales.
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/ui/src/theme/context.tsx:11-16
Timestamp: 2026-04-22T09:32:58.310Z
Learning: In Astro-Han/pawwork (`packages/ui/src/theme/context.tsx` and related files), the renaming of localStorage theme keys from `opencode-*` to `pawwork-*` (THEME_ID, COLOR_SCHEME, THEME_CSS_LIGHT, THEME_CSS_DARK) is intentional and should NOT include a migration path from the old keys. Migrating would re-couple PawWork and OpenCode browser storage namespaces, which the PR is explicitly designed to avoid. A reset to the PawWork default theme on upgrade is acceptable by design.
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 99
File: packages/desktop-electron/src/renderer/i18n/index.ts:30-35
Timestamp: 2026-04-21T13:45:45.149Z
Learning: In Astro-Han/pawwork, the locale normalization helpers in `packages/app/src/context/language.tsx` (`normalizeLocale`) and `packages/desktop-electron/src/renderer/i18n/index.ts` (`parseLocale`) are intentionally kept separate and have different fallback shapes: `normalizeLocale` always returns a concrete `Locale` (falling back to `"en"`), while `parseLocale` returns `Locale | null` so the desktop shell can decide whether to fall back to browser detection. Do not suggest extracting a shared normalization helper across these two runtimes.
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 224
File: packages/desktop-electron/electron-builder.config.ts:14-18
Timestamp: 2026-04-24T17:12:26.774Z
Learning: In Astro-Han/pawwork, the `localizedMacDisplayNameByChannel` map in `packages/desktop-electron/electron-builder.config.ts` is intentionally kept separate from `localizedAppDisplayName` in `packages/desktop-electron/src/main/app-display-name.ts`. The former is a build-time packaging helper; the latter is a runtime UI helper that localizes the current app name by locale. Coupling them would introduce a build-time dependency on runtime main logic. Do not suggest deduplicating or sharing this mapping — the explicit local table is covered by focused regression tests in `electron-builder-app-update.test.ts`.
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 208
File: packages/app/src/components/prompt-input.tsx:1569-1611
Timestamp: 2026-04-24T05:39:58.329Z
Learning: In Astro-Han/pawwork `packages/app/src/components/prompt-input.tsx`, after the composer unification in PR `#208` (fixed in commit 5d810aa):
- `SendButton.disabled` does NOT gate on `store.mode !== "normal"`. Shell mode has a fully visible, clickable orange submit button that calls `handleSubmit` directly (same path as the Enter key in `handleKeyDown`). Do NOT suggest re-adding the mode gate.
- `SendButton` does NOT use the `buttons()` spring opacity animation (`style={buttons()}`). It is always fully visible regardless of mode.
- `WorkspaceChip` is gated on `props.homeMode && store.mode === "normal"` so it hides in shell mode (preventing it from appearing isolated/bright while neighboring controls fade).
- The left-side chip group (`aria-hidden={store.mode !== "normal"}`) covers attach/model/variant/workspace controls only; `SendButton` remains in a separate right-side sibling div.
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 245
File: packages/opencode/src/question/index.ts:21-24
Timestamp: 2026-04-26T15:35:36.505Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/question/index.ts`), `Question.Option.description` is intentionally **required** (`z.string()`, not `.optional()`). This matches the upstream opencode contract and all current callers (e.g. `PlanExitTool`) always supply a description. The defensive `<Show when={props.description}>` rendering in `session-question-dock.tsx` is a standard guard, not a signal that the field is intended to be optional. Do NOT suggest making `Option.description` optional without a dedicated follow-up that covers schema + tool description + dock copy + tests.
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 191
File: packages/app/src/pages/layout/pawwork-sidebar.tsx:139-139
Timestamp: 2026-04-23T15:10:26.994Z
Learning: In Astro-Han/pawwork, the icon registry in `packages/ui/src/components/icon.tsx` uses **bare (unquoted) TypeScript object keys** for single-word icon names (e.g., `pin:` at line 102, `workspace:` at line 99) and **quoted keys** only for hyphenated names (e.g., `"review-active":`). When verifying icon registration with `rg`, always search for both forms — use a pattern like `rg -n "(\"${key}\"|${key}:)"` — otherwise bare-key icons will be missed and incorrectly flagged as unregistered.
📚 Learning: 2026-04-24T17:08:46.780Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 224
File: packages/app/src/i18n/zh.ts:0-0
Timestamp: 2026-04-24T17:08:46.780Z
Learning: In Astro-Han/pawwork PR `#224`, the first-occurrence `PawWork 爪印` branding rule originally specified in issue `#196` was superseded by an updated Chinese-branding spec. On all zh UI surfaces in `packages/app/src/i18n/zh.ts` (e.g., `dialog.model.unpaid.freeModels.title`, `session.new.subtitle`, `sidebar.gettingStarted.line1`), the correct and intentional target is fully localized `爪印` branding — no `PawWork` prefix. Do NOT flag these strings as missing the first-occurrence `PawWork 爪印` rule in future reviews.
Applied to files:
packages/ui/src/i18n/zh.ts
📚 Learning: 2026-04-22T05:32:29.012Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 98
File: packages/desktop-electron/src/main/menu-labels.ts:1-2
Timestamp: 2026-04-22T05:32:29.012Z
Learning: In Astro-Han/pawwork, the app i18n layer (`packages/app/src/i18n/`) only contains `en.ts` and `zh.ts`, and `normalizeLocale` (in `packages/app/src/context/language.tsx`) only returns `"en"` or `"zh"`. The desktop `MenuLocale = "en" | "zh"` union in `packages/desktop-electron/src/main/menu-labels.ts` is intentionally limited to these two locales and is not a broader restriction — do not flag it as overly restrictive or suggest adding other locales.
Applied to files:
packages/ui/src/i18n/zh.ts
📚 Learning: 2026-04-27T12:59:49.844Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 264
File: packages/opencode/test/session/prompt-effect.test.ts:0-0
Timestamp: 2026-04-27T12:59:49.844Z
Learning: In `packages/opencode/test/session/prompt-effect.test.ts` and `packages/opencode/src/session/diagnostics.ts` (PR `#264`), the recovery reminder copy differs between signature kinds: the input-repeat variant says "repeated the same tool input 3 times" (uses a literal count), while the target-repeat variant says "failed against the same target multiple times" (uses "multiple times" with no count). Assertions that check for injected reminder text in LLM inputs must accept both phrasings when a scenario produces both `input:` and `target:` signatures (e.g., `read` tool with a `filePath` parameter). Do NOT narrow the assertion to only the input-variant phrasing.
Applied to files:
packages/ui/src/i18n/zh.ts
🔇 Additional comments (1)
packages/ui/src/i18n/zh.ts (1)
97-108: Tool-card zh labels are much clearer and user-facing now.These updates consistently replace jargon/English terms with action-oriented Chinese copy and align well with the PR intent for non-technical readability.
en: "Listed N dir / dirs" was implementation jargon; use the full word "directory / directories" so the UI reads cleanly for non-technical users (PawWork's "for everyone" positioning). zh: collapse the prior verb-only labels (阅读 N 篇 / 浏览 N 处) to verb-object form that matches PR #282's tool-card labels (读取文件 / 列出目录) and stays visually symmetric across all three counts: - 读取 N 个文件 (was 阅读 N 篇) - 搜索 N 处匹配 (was 搜索 N 次, now matches verb+量+名 shape) - 列出 N 个目录 (was 浏览 N 处) "处" stays as the search measure word because grep-style search returns hits at file:line locations, which is exactly what 处 denotes (an occurrence at a position) — more concrete than 项. Addresses coderabbitai review on #320.
…ttern en: "Listed N dir / dirs" was implementation jargon; use the full word "directory / directories" so the UI reads cleanly for non-technical users (PawWork's "for everyone" positioning). zh: collapse the prior verb-only labels (阅读 N 篇 / 浏览 N 处) to verb-object form that matches PR #282's tool-card labels (读取文件 / 列出目录) and stays visually symmetric across all three counts: - 读取 N 个文件 (was 阅读 N 篇) - 搜索 N 处匹配 (was 搜索 N 次, now matches verb+量+名 shape) - 列出 N 个目录 (was 浏览 N 处) "处" stays as the search measure word because grep-style search returns hits at file:line locations, which is exactly what 处 denotes (an occurrence at a position) — more concrete than 项. Addresses coderabbitai review on #320.
Summary
Replace English/cryptic Chinese labels on tool call cards in the conversation stream so non-technical users can understand at a glance what action the AI just took.
ui.tool.readui.tool.listui.tool.globui.tool.grepui.tool.webfetchui.tool.shellui.tool.patchui.tool.todos.readui.tool.questionsAll new values share the same verb-object structure (动词+宾语) so they line up visually with their LLM-written subtitles.
读取文件/读取网页form a deliberate pair (same verb, different object) so users can tell at a glance that one is local-file read vs remote-page read.Why
PawWork's positioning is "open-source AI agent for everyone" — not just developers. In the Chinese UI today, tool call cards in the chat stream still show English brand words (
Shell,Webfetch,Glob,Grep) or vague Chinese (补丁,问题) that mean little to non-technical users. The old问题in particular reads as "there's a problem" rather than "the AI is asking you something". The chosen Chinese values prefer plain action verbs over jargon and keep a parallel structure with neighbors that were already translated (网络搜索,代码搜索). English locale and traditional Chinese are unchanged; per project policypackages/app/src/i18nonly maintains zh + en, andzht.tsfollows upstream.The descriptions on Shell cards (e.g.
Check if opencli is installed) come from the LLM viabashtool'sinput.descriptionand are out of scope here — those need a prompt-level change, not i18n.Related Issue
No issue. Triggered by an in-product UI review of the chat stream while the app is set to Chinese.
How To Verify
All four pass locally. Manual UI smoke was performed on a Chinese-locale
dev:desktopsession: triggeredlist/glob/grep/webfetch/shell/websearch/codesearch/read/questioncards in one turn and confirmed each new label reads naturally next to its subtitle.patch(批量修改) andtodoread(查看待办) were not surfaced during smoke and are not in active user-facing render paths today, but the keys are kept for future use.Screenshots or Recordings
Not attached — change is text-only inside
packages/ui/src/i18n/zh.ts. UI surface unchanged in layout.Checklist
dev, and my PR title and commit messages use Conventional Commits in EnglishSummary by CodeRabbit