fix(desktop): localize Chinese branding surfaces#224
Conversation
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 4 minutes and 50 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds locale-aware Chinese branding and window-title propagation: introduces localized app titles, exposes and uses Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Renderer as App (Renderer)
participant Bridge as DesktopContextRouteBridge
participant IPC as ipcRenderer
participant Main as Electron Main
participant Window as BrowserWindow
User->>Renderer: navigate / change locale
Renderer->>Bridge: route or locale change
Bridge->>Bridge: read locale (useLanguage)
Bridge->>Bridge: compute desktopWindowTitle(locale)
Bridge->>Renderer: set document.title (if applicable)
Bridge->>IPC: invoke("set-desktop-context", DesktopContext with title)
IPC->>Main: deliver set-desktop-context payload
Main->>Main: normalizeDesktopContextPayload(payload)
Main->>Main: syncWindowTitleForDesktopContext(win, context)
Main->>Window: win.setTitle(context.title)
Window->>User: window title updated
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
584b33b to
3be1c86
Compare
There was a problem hiding this comment.
Code Review
This pull request implements comprehensive localization for the Chinese (zh) locale, including UI translations, localized release highlights, and desktop-specific metadata like macOS display names and window titles. Feedback focuses on architectural improvements, specifically recommending the use of a shared package for cross-package utilities instead of relative imports, utilizing the <Title> component for document title management in SolidJS, and improving code formatting for better readability.
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/app/src/i18n/zh.ts (1)
152-183:⚠️ Potential issue | 🟠 MajorRestore
PawWork 爪印on the first mention for these surfaces.These changes switch several first visible brand mentions straight to
爪印, but issue#196’s acceptance criteria require the first mention on each surface to lead withPawWork 爪印and only later mentions to shorten to爪印. The affected groups here include the free-models dialog, provider-connect copy, server dialog text, update/error-report strings, and the session/sidebar onboarding copy, so the branding rule is still not fully applied.Also applies to: 323-323, 352-353, 468-503, 581-695
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/i18n/zh.ts` around lines 152 - 183, Several strings currently use the short brand name "爪印" on first mention; update each first-occurrence string to use "PawWork 爪印" instead (then keep later mentions as "爪印"). Specifically, revise keys like "dialog.model.unpaid.freeModels.title", "dialog.model.unpaid.addMore.title", "provider.connect.title" (and "provider.connect.title.anthropicProMax"), all "provider.connect.*" entries (apiKey, description, label, placeholders, opencodeZen.* and oauth.* entries), plus the other key ranges noted (lines around 323, 352-353, 468-503, 581-695) so the first visible mention on each surface reads "PawWork 爪印" and subsequent mentions remain "爪印". Ensure you only change the displayed brand phrase and keep interpolation ({{provider}}, {{method}}) and punctuation intact.packages/app/src/utils/desktop-context.ts (1)
3-8:⚠️ Potential issue | 🔴 CriticalAdd
titlefield to allDesktopContextliterals in the test file.Making
titlerequired inDesktopContextbreaks multiple test objects that are missing this field. The test file has at least nine incomplete literals:base(lines 5–10),activeSession,backgroundSession, and six more inline objects throughout the test suite. All must include thetitlefield or usebuildDesktopContext(...)to construct instances properly.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/utils/desktop-context.ts` around lines 3 - 8, The new required title property on the DesktopContext type is breaking tests; update all DesktopContext literals in the test suite (notably the base, activeSession, backgroundSession objects and the six inline DesktopContext objects) to include a title string, or replace those direct literals by calling buildDesktopContext(...) which will produce a complete DesktopContext including title; search for instances of DesktopContext literals in the tests and either add title: "..." or convert the literal to use buildDesktopContext to ensure the title field is present.
🤖 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/app/src/app.tsx`:
- Around line 181-184: The effect currently only reads language.locale() so it
never reruns on navigation and can overwrite or leave a stale session title;
update the createEffect callback to also read the current route (e.g. a
route/location signal or router.currentRoute()/pathname) so it reruns on
navigation, and add a guard that skips setting document.title when the active
route is a session route (e.g. path === '/session' or matches the session route
pattern); continue to use desktopWindowTitle(language.locale()) for non-session
routes when setting document.title.
In `@packages/app/src/i18n/zh-branding.test.ts`:
- Around line 14-16: The test "removes PawWork from curated Chinese UI strings"
currently scans all Object.values(zh) which is too broad; instead restrict the
assertion to an explicit list of curated UI keys. Update the test in
packages/app/src/i18n/zh-branding.test.ts to define a curatedKeys array of the
specific zh keys that should never contain "PawWork" (e.g., branding/marketing
UI entries), then iterate curatedKeys and assert that zh[key] (or joined values
if the key is an object) does notContain "PawWork" while leaving the rest of zh
unchanged.
In `@packages/desktop-electron/electron-builder-app-update.test.ts`:
- Around line 74-81: The test currently checks zh_CN existence via the zhCn
variable but only asserts content for zhHans; update the test in
electron-builder-app-update.test.ts to also read and assert the contents of zhCn
by calling readFileSync(zhCn, "utf8") and adding expectations that the string
contains 'CFBundleDisplayName = "爪印";' and 'CFBundleName = "爪印";' (mirror the
checks done for zhHans); keep the existing existsSync assertions and reuse the
zhCn identifier so the test verifies both existence and correct localized
content.
---
Outside diff comments:
In `@packages/app/src/i18n/zh.ts`:
- Around line 152-183: Several strings currently use the short brand name "爪印"
on first mention; update each first-occurrence string to use "PawWork 爪印"
instead (then keep later mentions as "爪印"). Specifically, revise keys like
"dialog.model.unpaid.freeModels.title", "dialog.model.unpaid.addMore.title",
"provider.connect.title" (and "provider.connect.title.anthropicProMax"), all
"provider.connect.*" entries (apiKey, description, label, placeholders,
opencodeZen.* and oauth.* entries), plus the other key ranges noted (lines
around 323, 352-353, 468-503, 581-695) so the first visible mention on each
surface reads "PawWork 爪印" and subsequent mentions remain "爪印". Ensure you only
change the displayed brand phrase and keep interpolation ({{provider}},
{{method}}) and punctuation intact.
In `@packages/app/src/utils/desktop-context.ts`:
- Around line 3-8: The new required title property on the DesktopContext type is
breaking tests; update all DesktopContext literals in the test suite (notably
the base, activeSession, backgroundSession objects and the six inline
DesktopContext objects) to include a title string, or replace those direct
literals by calling buildDesktopContext(...) which will produce a complete
DesktopContext including title; search for instances of DesktopContext literals
in the tests and either add title: "..." or convert the literal to use
buildDesktopContext to ensure the title field is present.
🪄 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: 75a11dff-88fa-4cac-b5da-86bc9b34dc54
📒 Files selected for processing (25)
packages/app/src/app.tsxpackages/app/src/context/highlights.test.tspackages/app/src/context/highlights.tsxpackages/app/src/i18n/zh-branding.test.tspackages/app/src/i18n/zh.tspackages/app/src/utils/desktop-context.test.tspackages/app/src/utils/desktop-context.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/desktop-electron/electron-builder.config.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/main/app-display-name.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/feedback.test.tspackages/desktop-electron/src/main/feedback.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/menu-labels.test.tspackages/desktop-electron/src/main/menu-labels.tspackages/desktop-electron/src/main/menu.test.tspackages/desktop-electron/src/main/menu.tspackages/desktop-electron/src/main/updater-dialog-labels.test.tspackages/desktop-electron/src/main/updater-dialog-labels.tspackages/desktop-electron/src/preload/index.tspackages/desktop-electron/src/renderer/i18n/zh.test.tspackages/desktop-electron/src/renderer/i18n/zh.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
packages/desktop-electron/src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/desktop-electron/AGENTS.md)
Renderer process should only call
window.apifromsrc/preload
Files:
packages/desktop-electron/src/main/menu-labels.test.tspackages/desktop-electron/src/main/feedback.test.tspackages/desktop-electron/src/renderer/i18n/zh.test.tspackages/desktop-electron/src/main/menu.tspackages/desktop-electron/src/main/menu-labels.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/main/updater-dialog-labels.tspackages/desktop-electron/src/main/updater-dialog-labels.test.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/desktop-electron/src/renderer/i18n/zh.tspackages/desktop-electron/src/main/feedback.tspackages/desktop-electron/src/main/app-display-name.tspackages/desktop-electron/src/preload/index.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/menu.test.ts
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/app/AGENTS.md)
Always prefer
createStoreover multiplecreateSignalcalls in SolidJS
Files:
packages/app/src/utils/desktop-context.test.tspackages/app/src/i18n/zh-branding.test.tspackages/app/src/utils/desktop-context.tspackages/app/src/app.tsxpackages/app/src/i18n/zh.tspackages/app/src/context/highlights.tsxpackages/app/src/context/highlights.test.ts
🧠 Learnings (24)
📓 Common learnings
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.
📚 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/desktop-electron/src/main/menu-labels.test.tspackages/app/src/utils/desktop-context.test.tspackages/desktop-electron/src/main/feedback.test.tspackages/desktop-electron/src/renderer/i18n/zh.test.tspackages/desktop-electron/src/main/menu.tspackages/app/src/i18n/zh-branding.test.tspackages/desktop-electron/src/main/menu-labels.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/app/src/utils/desktop-context.tspackages/desktop-electron/src/main/updater-dialog-labels.tspackages/desktop-electron/src/main/updater-dialog-labels.test.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/desktop-electron/src/renderer/i18n/zh.tspackages/app/src/app.tsxpackages/desktop-electron/src/main/feedback.tspackages/desktop-electron/src/main/app-display-name.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/electron-builder.config.tspackages/desktop-electron/src/main/index.tspackages/app/src/i18n/zh.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/desktop-electron/src/main/menu.test.tspackages/app/src/context/highlights.tsxpackages/app/src/context/highlights.test.ts
📚 Learning: 2026-04-22T08:49:47.800Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/desktop-electron/src/main/index-sidecar-source.test.ts:3-11
Timestamp: 2026-04-22T08:49:47.800Z
Learning: In `packages/desktop-electron/src/main/index-sidecar-source.test.ts` (Astro-Han/pawwork), the test intentionally uses `expect(source).toContain` / `expect(source).not.toContain` string matching against the raw `index.ts` source text as a lightweight sidecar contract guard. The maintainer has explicitly chosen not to introduce an AST parser (e.g., `babel/parser` or acorn) for this purpose. Do not flag these string-based assertions as fragile or suggest converting them to AST-based matching.
Applied to files:
packages/desktop-electron/src/main/menu-labels.test.tspackages/app/src/utils/desktop-context.test.tspackages/desktop-electron/src/main/feedback.test.tspackages/desktop-electron/src/renderer/i18n/zh.test.tspackages/app/src/i18n/zh-branding.test.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/main/updater-dialog-labels.test.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/desktop-electron/src/main/menu.test.tspackages/app/src/context/highlights.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use lowercase, descriptive test names (e.g., 'sidebar can be toggled')
Applied to files:
packages/desktop-electron/src/main/menu-labels.test.tspackages/desktop-electron/src/main/feedback.test.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/main/menu.test.tspackages/app/src/context/highlights.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : When validating routing, assert against canonical or resolved workspace slugs using shared helpers from `../actions` to account for Windows canonicalization
Applied to files:
packages/app/src/utils/desktop-context.test.tspackages/desktop-electron/src/main/desktop-context-window.test.ts
📚 Learning: 2026-04-23T07:23:23.849Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 180
File: packages/app/src/components/session/session-new-view.tsx:13-18
Timestamp: 2026-04-23T07:23:23.849Z
Learning: In pawwork (Astro-Han/pawwork), prefer using `createStore` instead of multiple `createSignal` calls only when the signals represent **coupled** object state that is updated together (i.e., there is at least one shared batch-update site where the state is changed in the same transaction). If the state fields are **independent** and are mutated by separate handlers (e.g., one handler updates only `selectedSkill` while another updates only `mode`), keep them as individual `createSignal` calls—using `createStore` for truly independent fields adds boilerplate without behavioral benefit.
Applied to files:
packages/app/src/utils/desktop-context.test.tspackages/app/src/i18n/zh-branding.test.tspackages/app/src/utils/desktop-context.tspackages/app/src/app.tsxpackages/app/src/i18n/zh.tspackages/app/src/context/highlights.tsxpackages/app/src/context/highlights.test.ts
📚 Learning: 2026-04-23T15:10:21.635Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 191
File: packages/app/src/components/session/pawwork-skill-meta.ts:38-39
Timestamp: 2026-04-23T15:10:21.635Z
Learning: This repo configures Tailwind v4 with `--color-*: initial`, which effectively breaks standard Tailwind palette utilities (e.g., `text-violet-500` can resolve to no CSS variable and render as a no-op/black). For brand/accent colors that are not backed by semantic design tokens, use inline styles with the exact hex value (e.g., `style={{ color: '#8B5FBF' }}` / `homeIconStyle: { color: '#8B5FBF' }`) and add a short comment explaining that Tailwind palette utilities won’t work due to the `--color-*: initial` setup. Do not suggest replacing these inline hex colors with Tailwind palette classes anywhere in this repo.
Applied to files:
packages/app/src/utils/desktop-context.test.tspackages/app/src/i18n/zh-branding.test.tspackages/app/src/utils/desktop-context.tspackages/app/src/app.tsxpackages/app/src/i18n/zh.tspackages/app/src/context/highlights.tsxpackages/app/src/context/highlights.test.ts
📚 Learning: 2026-04-22T09:32:58.310Z
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.
Applied to files:
packages/app/src/i18n/zh-branding.test.tspackages/desktop-electron/src/main/menu-labels.tspackages/desktop-electron/src/main/updater-dialog-labels.tspackages/desktop-electron/src/renderer/i18n/zh.tspackages/desktop-electron/src/main/feedback.tspackages/desktop-electron/src/main/app-display-name.tspackages/app/src/i18n/zh.tspackages/desktop-electron/src/main/menu.test.tspackages/app/src/context/highlights.tsx
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test files should be named with the pattern `feature-name.spec.ts`
Applied to files:
packages/desktop-electron/src/main/app-display-name.test.ts
📚 Learning: 2026-04-21T13:45:45.149Z
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.
Applied to files:
packages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/desktop-electron/src/renderer/i18n/zh.tspackages/desktop-electron/src/main/app-display-name.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/electron-builder.config.tspackages/desktop-electron/src/main/index.tspackages/app/src/context/highlights.tsxpackages/app/src/context/highlights.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use camelCase for variable names in tests
Applied to files:
packages/desktop-electron/src/main/app-display-name.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use SCREAMING_SNAKE_CASE for constants in tests
Applied to files:
packages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/main/menu.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Prefer fluent helpers and drivers when they make intent obvious and reduce locator-heavy noise in tests
Applied to files:
packages/desktop-electron/src/main/app-display-name.test.tspackages/app/src/context/highlights.test.ts
📚 Learning: 2026-04-24T13:03:10.835Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 222
File: packages/desktop-electron/src/main/index.ts:686-692
Timestamp: 2026-04-24T13:03:10.835Z
Learning: In `packages/desktop-electron/src/main/index.ts`, the `checkForUpdates()` function intentionally uses recursive self-invocation for the "Retry" path in the update-check failure dialog. This is mandated by the v5.2 design spec (`#213`): "Await the retry recursion and log any rejection so support can see repeated failures." Because retries are user-paced (require a button click), all prior async frames have already unwound through microtasks before the next attempt, so there is no stack/frame-nesting problem in practice. Do not suggest refactoring this to an iterative loop.
Applied to files:
packages/desktop-electron/src/main/updater-dialog-labels.test.ts
📚 Learning: 2026-04-20T14:36:08.774Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.774Z
Learning: Applies to packages/desktop-electron/src/main/ipc.ts : Main process should register IPC handlers in `src/main/ipc.ts`
Applied to files:
packages/desktop-electron/src/main/desktop-context-window.test.tspackages/desktop-electron/src/preload/index.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/index.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : In terminal tests, type through the browser using `runTerminal()` and `waitTerminalReady()` instead of writing to the PTY through the SDK
Applied to files:
packages/desktop-electron/src/main/desktop-context-window.test.ts
📚 Learning: 2026-04-20T14:36:31.032Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.032Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Prefer Effect-aware helpers from `fixture/fixture.ts` over building manual runtimes in tests: use `tmpdirScoped()` for scoped temp directories, `provideInstance(dir)(effect)` for low-level binding without directory creation, `provideTmpdirInstance(...)` for single temp instance binding, or `provideTmpdirServer(...)` for tests that also need the test LLM server.
Applied to files:
packages/desktop-electron/src/main/desktop-context-window.test.ts
📚 Learning: 2026-04-20T14:36:08.774Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.774Z
Learning: Applies to packages/desktop-electron/src/**/*.{ts,tsx,js,jsx} : Renderer process should only call `window.api` from `src/preload`
Applied to files:
packages/desktop-electron/src/preload/index.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/index.ts
📚 Learning: 2026-04-23T08:51:04.230Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 186
File: packages/opencode/test/plugin/workspace-adaptor.test.ts:139-144
Timestamp: 2026-04-23T08:51:04.230Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/util/filesystem.ts`), the `Filesystem` utility does NOT expose a `remove` or `unlink` helper. The established repository pattern for auth.json teardown in tests (e.g. `provider.test.ts`, `amazon-bedrock.test.ts`, `workspace-adaptor.test.ts`) is to combine `Filesystem.write` with `node:fs/promises unlink`. Do not flag this mixed usage as inconsistent — it is the correct and intentional pattern.
Applied to files:
packages/desktop-electron/electron-builder.config.tspackages/desktop-electron/electron-builder-app-update.test.ts
📚 Learning: 2026-04-20T14:36:21.288Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.288Z
Learning: Applies to packages/opencode/**/*.ts : Prefer `FileSystem.FileSystem` instead of raw `fs/promises` for effectful file I/O in Effect services
Applied to files:
packages/desktop-electron/electron-builder.config.ts
📚 Learning: 2026-04-20T14:36:31.032Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.032Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `config` option in `tmpdir` to write an `opencode.json` config file during test setup by passing a partial Config.Info object.
Applied to files:
packages/desktop-electron/electron-builder-app-update.test.ts
📚 Learning: 2026-04-20T14:36:31.032Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.032Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `init` option in `tmpdir` to define custom setup functions that can return extra data accessible via `tmp.extra`, and use the `dispose` option for custom cleanup logic.
Applied to files:
packages/desktop-electron/electron-builder-app-update.test.ts
📚 Learning: 2026-04-20T14:36:31.032Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.032Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `tmpdir` function from `fixture/fixture.ts` to create temporary directories for tests with automatic cleanup. Use `await using` syntax to ensure automatic cleanup when the variable goes out of scope.
Applied to files:
packages/desktop-electron/electron-builder-app-update.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Import test utilities from `../fixtures` instead of `playwright/test`
Applied to files:
packages/app/src/context/highlights.test.ts
🔇 Additional comments (20)
packages/desktop-electron/electron-builder.config.ts (2)
43-52: Localized macOS bundle-name generation is implemented cleanly.The channel mapping and
InfoPlist.stringsgeneration are deterministic and correctly scoped to the macOS resources layout.
129-133: afterPack sequencing correctly separates localization from updater config writing.Running localization for all macOS builds while gating
app-update.ymlonpublishkeeps behavior aligned with channel intent.packages/desktop-electron/electron-builder-app-update.test.ts (1)
44-53: Config-level macOS localization assertions are solid.This test correctly validates both identity fields and
LSHasLocalizedDisplayNameenablement.packages/desktop-electron/src/main/menu-labels.test.ts (1)
45-45: Good localization regression coverage for the GitHub menu label.The new expectation directly protects the updated Chinese branding copy.
packages/desktop-electron/src/main/updater-dialog-labels.ts (1)
38-50: Chinese updater-dialog copy update is consistent and safe.These text changes keep locale behavior intact without affecting control flow.
packages/desktop-electron/src/main/menu-labels.ts (1)
101-101: Updated zh menu label text looks correct.The new phrasing is reflected in tests and keeps the translation table consistent.
packages/desktop-electron/src/main/feedback.ts (1)
94-100: Feedback dialog zh copy changes are clean and non-invasive.The updated strings integrate without impacting the existing report workflow.
packages/desktop-electron/src/main/updater-dialog-labels.test.ts (1)
9-12: Updated zh updater-label assertions are accurate.These checks now match the revised localized messages and improve regression protection.
packages/desktop-electron/src/renderer/i18n/zh.test.ts (1)
1-9: Nice focused regression test for zh updater branding copy.It correctly guards both final text and the
{{version}}placeholder contract.packages/app/src/utils/desktop-context.test.ts (1)
16-16: Locale-aware title assertions are correct.Line 16 and Line 33 correctly lock expected titles to
"爪印"forzhand"PawWork"foren.Also applies to: 33-33
packages/desktop-electron/src/main/feedback.test.ts (1)
84-85: Good regression guard for Chinese feedback copy.Line 84 and Line 85 add useful protections to prevent accidental reintroduction of
"PawWork"in zh dialog text.packages/desktop-electron/src/main/menu.ts (1)
5-5: Localized menu app name wiring looks correct.Line 24 applies locale-aware display naming while preserving
app.getName()as the source identifier.Also applies to: 24-24
packages/desktop-electron/src/renderer/i18n/zh.ts (1)
14-14: Chinese updater copy update is consistent.Line 14 and Line 18 keep the same intent while removing English-brand phrasing in zh strings.
Also applies to: 18-18
packages/desktop-electron/src/main/menu.test.ts (1)
128-128: Menu localization assertions are aligned with zh branding.The updated app name fixtures and the GitHub submenu label check provide solid coverage for the localized menu surface.
Also applies to: 137-137, 141-141
packages/desktop-electron/src/preload/index.ts (1)
2-2: Good consolidation of desktop-context initialization.Line 77 reuses the shared builder, which helps keep preload initialization behavior consistent with the app’s desktop-context contract.
Also applies to: 77-77
packages/desktop-electron/src/main/app-display-name.test.ts (1)
1-15: Great focused coverage for app display-name localization.These tests correctly validate both locale mapping and suffix preservation behavior.
packages/app/src/i18n/zh-branding.test.ts (1)
6-12: Curated zh key assertions are strong and useful.Line 6–12 gives clear regression coverage for high-visibility branding copy.
packages/app/src/context/highlights.tsx (3)
22-22: Locale-aware notice extraction and fallback path look correct.The zh-first extraction (
中文版本→主要更新) with fallback to English update notice is implemented cleanly and defensively.Based on learnings, limiting locale handling to
"en"/"zh"is intentional in this repository.Also applies to: 67-109
111-163: Localized release-title formatting is scoped correctly.You localize only body-derived fallback highlight titles while leaving structured highlight payload titles untouched, which avoids unintended rewrites.
198-199: Runtime locale propagation into highlights parsing is correctly wired.Passing
language.locale()intoloadReleaseHighlights(...)ensures fetched release parsing matches the active app locale.Also applies to: 208-208, 258-258
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (3)
packages/app/src/app.tsx (1)
181-184:⚠️ Potential issue | 🟠 MajorGuard title sync by route and make the effect navigation-reactive.
At Line 181, the effect only depends on
language.locale(). It can clobber session-specific titles and leave stale titles after route changes.💡 Proposed fix
createEffect(() => { if (typeof document !== "object") return + const pathname = location.pathname + if (isSessionRoute(pathname)) return document.title = desktopWindowTitle(language.locale()) })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/app.tsx` around lines 181 - 184, The createEffect that sets document.title currently only reacts to language.locale() and can overwrite route/session-specific titles; update the effect (createEffect used near document.title = desktopWindowTitle(language.locale())) to also depend on the current route/location (e.g., the router's location or route signal) and guard so it only updates the title for routes that should use desktopWindowTitle (skip when a route/component has already set a session-specific title). Keep the typeof document check, and ensure the effect reads the route/location reactive source so title updates run on navigation as well as locale changes.packages/app/src/i18n/zh-branding.test.ts (1)
14-16:⚠️ Potential issue | 🟠 MajorDo not enforce a full-dictionary
PawWorkban. Scope this assertion to curated UI keys.At Line 15,
Object.values(zh)is too broad and can fail valid first-occurrence branding (PawWork 爪印) or unrelated strings.💡 Proposed fix
- test("removes PawWork from curated Chinese UI strings", () => { - expect(Object.values(zh).join("\n")).not.toContain("PawWork") - }) + test("avoids standalone PawWork in curated Chinese UI strings", () => { + const curatedKeys = [ + "dialog.model.unpaid.freeModels.title", + "session.new.subtitle", + "sidebar.gettingStarted.line1", + "app.name.desktop", + "toast.update.description", + "error.page.report.prefix", + ] as const + + for (const key of curatedKeys) { + expect(zh[key]).not.toMatch(/\bPawWork\b(?!\s*爪印)/) + } + })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/i18n/zh-branding.test.ts` around lines 14 - 16, The test "removes PawWork from curated Chinese UI strings" currently inspects Object.values(zh) which is too broad; instead restrict the assertion to the curated UI keys only. Update the test to iterate over a curated list of keys (e.g., curatedUiKeys or an array you add like ['header.title','button.submit', ...]) and assert that for each key zh[key] (or the mapped values) does not contain "PawWork"; if a shared constant of curated keys exists, reference that constant in the test; otherwise create a small explicit array of the UI keys to check and use expect(zh[key]).not.toContain("PawWork") for each.packages/desktop-electron/electron-builder-app-update.test.ts (1)
74-81:⚠️ Potential issue | 🟡 MinorAlso assert
zh_CNfile content, not just existence.The test verifies
zh_CNpath creation but still only validates localized string content forzh-Hans, leaving drift inzh_CNundetected.Suggested test completion
expect(existsSync(zhHans)).toBe(true) expect(existsSync(zhCn)).toBe(true) expect(readFileSync(zhHans, "utf8")).toContain('CFBundleDisplayName = "爪印";') expect(readFileSync(zhHans, "utf8")).toContain('CFBundleName = "爪印";') + expect(readFileSync(zhCn, "utf8")).toContain('CFBundleDisplayName = "爪印";') + expect(readFileSync(zhCn, "utf8")).toContain('CFBundleName = "爪印";')🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/desktop-electron/electron-builder-app-update.test.ts` around lines 74 - 81, The test currently asserts zhCn exists but doesn't check its contents; update the test to read the zhCn file (using the zhCn variable and readFileSync) and assert it contains the expected localized entries (e.g., 'CFBundleDisplayName = "爪印";' and 'CFBundleName = "爪印";') similar to the existing checks for zhHans so failures in zh_CN content are detected.
🤖 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/app/src/context/highlights.tsx`:
- Around line 85-89: The current findChineseUpdateNotice function only returns a
nested "主要更新" subsection and ignores Chinese content if updates are listed
directly under the "中文版本" heading; update findChineseUpdateNotice to first
locate the Chinese section via findHeadingSection(body, /^#{2,6}\s+中文版本\s*$/)
and then try to find the nested "主要更新" subsection with
findHeadingSection(chinese, /^#{3,6}\s+主要更新\s*$/), but if that returns falsy,
return the chinese section itself (or the immediate list/content under it) so
update bullets directly under "中文版本" are captured; reference functions:
findChineseUpdateNotice and findHeadingSection.
In `@packages/app/src/i18n/zh.ts`:
- Line 152: The Chinese translation for the first-occurrence branding must use
the full brand "PawWork 爪印" instead of just "爪印"; update the value for the key
"dialog.model.unpaid.freeModels.title" to begin with "PawWork 爪印…" and apply the
same first-occurrence replacement to the other reported Chinese surface entries
mentioned in the review (the other two occurrences), ensuring subsequent
mentions in the same surface remain as "爪印".
In `@packages/desktop-electron/electron-builder.config.ts`:
- Around line 14-18: The localizedMacDisplayNameByChannel constant duplicates
the channel→name mapping defined elsewhere (see
packages/desktop-electron/src/main/app-display-name.ts); remove the duplicate by
importing or referencing the shared mapping instead of redefining it. Replace
the local localizedMacDisplayNameByChannel and any other duplicate maps (also at
lines ~43-51) with a single exported value from app-display-name.ts (or export
the mapping there if needed) and update uses to consume that exported constant
so packaging and runtime use the same source of truth.
---
Duplicate comments:
In `@packages/app/src/app.tsx`:
- Around line 181-184: The createEffect that sets document.title currently only
reacts to language.locale() and can overwrite route/session-specific titles;
update the effect (createEffect used near document.title =
desktopWindowTitle(language.locale())) to also depend on the current
route/location (e.g., the router's location or route signal) and guard so it
only updates the title for routes that should use desktopWindowTitle (skip when
a route/component has already set a session-specific title). Keep the typeof
document check, and ensure the effect reads the route/location reactive source
so title updates run on navigation as well as locale changes.
In `@packages/app/src/i18n/zh-branding.test.ts`:
- Around line 14-16: The test "removes PawWork from curated Chinese UI strings"
currently inspects Object.values(zh) which is too broad; instead restrict the
assertion to the curated UI keys only. Update the test to iterate over a curated
list of keys (e.g., curatedUiKeys or an array you add like
['header.title','button.submit', ...]) and assert that for each key zh[key] (or
the mapped values) does not contain "PawWork"; if a shared constant of curated
keys exists, reference that constant in the test; otherwise create a small
explicit array of the UI keys to check and use
expect(zh[key]).not.toContain("PawWork") for each.
In `@packages/desktop-electron/electron-builder-app-update.test.ts`:
- Around line 74-81: The test currently asserts zhCn exists but doesn't check
its contents; update the test to read the zhCn file (using the zhCn variable and
readFileSync) and assert it contains the expected localized entries (e.g.,
'CFBundleDisplayName = "爪印";' and 'CFBundleName = "爪印";') similar to the
existing checks for zhHans so failures in zh_CN content are detected.
🪄 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: 028c825f-03eb-4470-9bd7-03e440914db1
📒 Files selected for processing (25)
packages/app/src/app.tsxpackages/app/src/context/highlights.test.tspackages/app/src/context/highlights.tsxpackages/app/src/i18n/zh-branding.test.tspackages/app/src/i18n/zh.tspackages/app/src/utils/desktop-context.test.tspackages/app/src/utils/desktop-context.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/desktop-electron/electron-builder.config.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/main/app-display-name.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/feedback.test.tspackages/desktop-electron/src/main/feedback.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/menu-labels.test.tspackages/desktop-electron/src/main/menu-labels.tspackages/desktop-electron/src/main/menu.test.tspackages/desktop-electron/src/main/menu.tspackages/desktop-electron/src/main/updater-dialog-labels.test.tspackages/desktop-electron/src/main/updater-dialog-labels.tspackages/desktop-electron/src/preload/index.tspackages/desktop-electron/src/renderer/i18n/zh.test.tspackages/desktop-electron/src/renderer/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). (3)
- GitHub Check: unit-windows-opencode-config-project
- GitHub Check: unit-windows-opencode-server-tools
- GitHub Check: unit-windows-opencode-session
🧰 Additional context used
📓 Path-based instructions (2)
packages/desktop-electron/src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/desktop-electron/AGENTS.md)
Renderer process should only call
window.apifromsrc/preload
Files:
packages/desktop-electron/src/main/menu-labels.test.tspackages/desktop-electron/src/main/menu-labels.tspackages/desktop-electron/src/main/updater-dialog-labels.test.tspackages/desktop-electron/src/main/menu.tspackages/desktop-electron/src/main/feedback.tspackages/desktop-electron/src/main/app-display-name.tspackages/desktop-electron/src/main/updater-dialog-labels.tspackages/desktop-electron/src/preload/index.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/renderer/i18n/zh.tspackages/desktop-electron/src/main/menu.test.tspackages/desktop-electron/src/main/feedback.test.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/renderer/i18n/zh.test.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/desktop-context-window.test.ts
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/app/AGENTS.md)
Always prefer
createStoreover multiplecreateSignalcalls in SolidJS
Files:
packages/app/src/utils/desktop-context.test.tspackages/app/src/i18n/zh-branding.test.tspackages/app/src/utils/desktop-context.tspackages/app/src/app.tsxpackages/app/src/context/highlights.tsxpackages/app/src/context/highlights.test.tspackages/app/src/i18n/zh.ts
🧠 Learnings (28)
📓 Common learnings
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.
📚 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/desktop-electron/src/main/menu-labels.test.tspackages/desktop-electron/src/main/menu-labels.tspackages/desktop-electron/src/main/updater-dialog-labels.test.tspackages/desktop-electron/src/main/menu.tspackages/desktop-electron/src/main/feedback.tspackages/desktop-electron/src/main/app-display-name.tspackages/desktop-electron/src/main/updater-dialog-labels.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/app/src/utils/desktop-context.test.tspackages/desktop-electron/src/renderer/i18n/zh.tspackages/desktop-electron/src/main/menu.test.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/app/src/i18n/zh-branding.test.tspackages/app/src/utils/desktop-context.tspackages/desktop-electron/src/main/feedback.test.tspackages/desktop-electron/src/main/index.tspackages/app/src/app.tsxpackages/desktop-electron/src/renderer/i18n/zh.test.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/app/src/context/highlights.tsxpackages/desktop-electron/electron-builder.config.tspackages/app/src/context/highlights.test.tspackages/app/src/i18n/zh.ts
📚 Learning: 2026-04-22T08:49:47.800Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/desktop-electron/src/main/index-sidecar-source.test.ts:3-11
Timestamp: 2026-04-22T08:49:47.800Z
Learning: In `packages/desktop-electron/src/main/index-sidecar-source.test.ts` (Astro-Han/pawwork), the test intentionally uses `expect(source).toContain` / `expect(source).not.toContain` string matching against the raw `index.ts` source text as a lightweight sidecar contract guard. The maintainer has explicitly chosen not to introduce an AST parser (e.g., `babel/parser` or acorn) for this purpose. Do not flag these string-based assertions as fragile or suggest converting them to AST-based matching.
Applied to files:
packages/desktop-electron/src/main/menu-labels.test.tspackages/desktop-electron/src/main/updater-dialog-labels.test.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/app/src/utils/desktop-context.test.tspackages/desktop-electron/src/main/menu.test.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/app/src/i18n/zh-branding.test.tspackages/desktop-electron/src/main/feedback.test.tspackages/desktop-electron/src/renderer/i18n/zh.test.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/app/src/context/highlights.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use lowercase, descriptive test names (e.g., 'sidebar can be toggled')
Applied to files:
packages/desktop-electron/src/main/menu-labels.test.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/app/src/utils/desktop-context.test.tspackages/desktop-electron/src/main/menu.test.tspackages/app/src/context/highlights.test.ts
📚 Learning: 2026-04-22T09:32:58.310Z
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.
Applied to files:
packages/desktop-electron/src/main/menu-labels.tspackages/desktop-electron/src/main/feedback.tspackages/desktop-electron/src/main/app-display-name.tspackages/desktop-electron/src/main/updater-dialog-labels.tspackages/desktop-electron/src/renderer/i18n/zh.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/app/src/i18n/zh-branding.test.tspackages/app/src/i18n/zh.ts
📚 Learning: 2026-04-24T13:03:10.835Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 222
File: packages/desktop-electron/src/main/index.ts:686-692
Timestamp: 2026-04-24T13:03:10.835Z
Learning: In `packages/desktop-electron/src/main/index.ts`, the `checkForUpdates()` function intentionally uses recursive self-invocation for the "Retry" path in the update-check failure dialog. This is mandated by the v5.2 design spec (`#213`): "Await the retry recursion and log any rejection so support can see repeated failures." Because retries are user-paced (require a button click), all prior async frames have already unwound through microtasks before the next attempt, so there is no stack/frame-nesting problem in practice. Do not suggest refactoring this to an iterative loop.
Applied to files:
packages/desktop-electron/src/main/updater-dialog-labels.test.tspackages/desktop-electron/src/main/desktop-context-window.ts
📚 Learning: 2026-04-21T13:45:45.149Z
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.
Applied to files:
packages/desktop-electron/src/main/app-display-name.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/renderer/i18n/zh.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/app/src/i18n/zh-branding.test.tspackages/app/src/utils/desktop-context.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/app/src/context/highlights.tsxpackages/desktop-electron/electron-builder.config.tspackages/app/src/context/highlights.test.ts
📚 Learning: 2026-04-20T14:36:08.774Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.774Z
Learning: Applies to packages/desktop-electron/src/**/*.{ts,tsx,js,jsx} : Renderer process should only call `window.api` from `src/preload`
Applied to files:
packages/desktop-electron/src/preload/index.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/desktop-context-window.ts
📚 Learning: 2026-04-20T14:36:08.774Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.774Z
Learning: Applies to packages/desktop-electron/src/main/ipc.ts : Main process should register IPC handlers in `src/main/ipc.ts`
Applied to files:
packages/desktop-electron/src/preload/index.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/desktop-context-window.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test files should be named with the pattern `feature-name.spec.ts`
Applied to files:
packages/desktop-electron/src/main/app-display-name.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use camelCase for variable names in tests
Applied to files:
packages/desktop-electron/src/main/app-display-name.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use SCREAMING_SNAKE_CASE for constants in tests
Applied to files:
packages/desktop-electron/src/main/app-display-name.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : When validating routing, assert against canonical or resolved workspace slugs using shared helpers from `../actions` to account for Windows canonicalization
Applied to files:
packages/app/src/utils/desktop-context.test.tspackages/desktop-electron/src/main/desktop-context-window.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use locator assertions like `toBeVisible()`, `toHaveCount(0)`, and `toHaveAttribute(...)` for normal UI state verification
Applied to files:
packages/app/src/utils/desktop-context.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Import test utilities from `../fixtures` instead of `playwright/test`
Applied to files:
packages/app/src/utils/desktop-context.test.tspackages/desktop-electron/src/main/desktop-context-window.ts
📚 Learning: 2026-04-23T07:23:23.849Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 180
File: packages/app/src/components/session/session-new-view.tsx:13-18
Timestamp: 2026-04-23T07:23:23.849Z
Learning: In pawwork (Astro-Han/pawwork), prefer using `createStore` instead of multiple `createSignal` calls only when the signals represent **coupled** object state that is updated together (i.e., there is at least one shared batch-update site where the state is changed in the same transaction). If the state fields are **independent** and are mutated by separate handlers (e.g., one handler updates only `selectedSkill` while another updates only `mode`), keep them as individual `createSignal` calls—using `createStore` for truly independent fields adds boilerplate without behavioral benefit.
Applied to files:
packages/app/src/utils/desktop-context.test.tspackages/app/src/i18n/zh-branding.test.tspackages/app/src/utils/desktop-context.tspackages/app/src/app.tsxpackages/app/src/context/highlights.tsxpackages/app/src/context/highlights.test.tspackages/app/src/i18n/zh.ts
📚 Learning: 2026-04-23T15:10:21.635Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 191
File: packages/app/src/components/session/pawwork-skill-meta.ts:38-39
Timestamp: 2026-04-23T15:10:21.635Z
Learning: This repo configures Tailwind v4 with `--color-*: initial`, which effectively breaks standard Tailwind palette utilities (e.g., `text-violet-500` can resolve to no CSS variable and render as a no-op/black). For brand/accent colors that are not backed by semantic design tokens, use inline styles with the exact hex value (e.g., `style={{ color: '#8B5FBF' }}` / `homeIconStyle: { color: '#8B5FBF' }`) and add a short comment explaining that Tailwind palette utilities won’t work due to the `--color-*: initial` setup. Do not suggest replacing these inline hex colors with Tailwind palette classes anywhere in this repo.
Applied to files:
packages/app/src/utils/desktop-context.test.tspackages/app/src/i18n/zh-branding.test.tspackages/app/src/utils/desktop-context.tspackages/app/src/app.tsxpackages/app/src/context/highlights.tsxpackages/app/src/context/highlights.test.tspackages/app/src/i18n/zh.ts
📚 Learning: 2026-04-23T08:51:04.230Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 186
File: packages/opencode/test/plugin/workspace-adaptor.test.ts:139-144
Timestamp: 2026-04-23T08:51:04.230Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/util/filesystem.ts`), the `Filesystem` utility does NOT expose a `remove` or `unlink` helper. The established repository pattern for auth.json teardown in tests (e.g. `provider.test.ts`, `amazon-bedrock.test.ts`, `workspace-adaptor.test.ts`) is to combine `Filesystem.write` with `node:fs/promises unlink`. Do not flag this mixed usage as inconsistent — it is the correct and intentional pattern.
Applied to files:
packages/desktop-electron/electron-builder-app-update.test.tspackages/app/src/i18n/zh-branding.test.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/electron-builder.config.ts
📚 Learning: 2026-04-23T15:10:26.994Z
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.
Applied to files:
packages/desktop-electron/electron-builder-app-update.test.tspackages/app/src/i18n/zh-branding.test.ts
📚 Learning: 2026-04-20T14:36:31.032Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.032Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `config` option in `tmpdir` to write an `opencode.json` config file during test setup by passing a partial Config.Info object.
Applied to files:
packages/desktop-electron/electron-builder-app-update.test.ts
📚 Learning: 2026-04-20T14:36:31.032Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.032Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `init` option in `tmpdir` to define custom setup functions that can return extra data accessible via `tmp.extra`, and use the `dispose` option for custom cleanup logic.
Applied to files:
packages/desktop-electron/electron-builder-app-update.test.ts
📚 Learning: 2026-04-20T14:36:31.032Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.032Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `tmpdir` function from `fixture/fixture.ts` to create temporary directories for tests with automatic cleanup. Use `await using` syntax to ensure automatic cleanup when the variable goes out of scope.
Applied to files:
packages/desktop-electron/electron-builder-app-update.test.ts
📚 Learning: 2026-04-24T06:50:02.712Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 211
File: packages/opencode/src/provider/models.ts:113-179
Timestamp: 2026-04-24T06:50:02.712Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/provider/models.ts`), `PublishModel` and `PublishProvider` intentionally duplicate fields from `Model` and `Provider` with looser optionality. The split is a deliberate behavior boundary: `PublishModel`/`PublishProvider` (with `.passthrough()`) are used for lenient publish-time validation of incoming catalogs, while `Model`/`Provider` are used for strict runtime normalization. Do not flag this duplication as a maintenance burden or suggest extracting a shared base schema — the explicit separation is intentional and tied to the models-refresh reliability path introduced in PR `#211`.
Applied to files:
packages/app/src/i18n/zh-branding.test.ts
📚 Learning: 2026-04-21T16:57:25.580Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 102
File: packages/opencode/src/config/agent.ts:108-119
Timestamp: 2026-04-21T16:57:25.580Z
Learning: In `packages/opencode/src/config/agent.ts` (Astro-Han/pawwork), `ConfigPermission.Info` only accepts permission objects or the three action strings `"ask"`, `"allow"`, `"deny"`, and transforms those action strings into `{ "*": action }` before `normalize()` runs. By the time `normalize()` is reached, `configuredPermission` is always either `undefined` or a `Record<string, Rule>` — never a raw arbitrary string. The `Object.assign(permission, configuredPermission)` pattern is therefore safe. Do not flag it as corrupting string permission references.
Applied to files:
packages/app/src/i18n/zh-branding.test.ts
📚 Learning: 2026-04-20T14:36:21.288Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.288Z
Learning: Applies to packages/opencode/**/*.ts : Prefer `FileSystem.FileSystem` instead of raw `fs/promises` for effectful file I/O in Effect services
Applied to files:
packages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/electron-builder.config.ts
📚 Learning: 2026-04-20T14:36:21.288Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.288Z
Learning: Applies to packages/opencode/**/*.ts : Prefer `Path.Path`, `Config`, `Clock`, and `DateTime` services when those concerns are already inside Effect code
Applied to files:
packages/desktop-electron/src/main/desktop-context-window.ts
📚 Learning: 2026-04-20T14:36:31.032Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.032Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Prefer Effect-aware helpers from `fixture/fixture.ts` over building manual runtimes in tests: use `tmpdirScoped()` for scoped temp directories, `provideInstance(dir)(effect)` for low-level binding without directory creation, `provideTmpdirInstance(...)` for single temp instance binding, or `provideTmpdirServer(...)` for tests that also need the test LLM server.
Applied to files:
packages/desktop-electron/src/main/desktop-context-window.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Prefer fluent helpers and drivers when they make intent obvious and reduce locator-heavy noise in tests
Applied to files:
packages/app/src/context/highlights.test.ts
🔇 Additional comments (24)
packages/app/src/context/highlights.test.ts (2)
13-13: Good call passing locale explicitly in tests.This makes parsing expectations deterministic and avoids accidental reliance on default
"en"behavior.Also applies to: 69-69, 76-76, 88-88, 98-98, 105-105, 120-120, 137-137
21-60: Strong zh coverage for both priority and fallback paths.The new cases validate Chinese-section precedence, English fallback, and non-rewriting of structured titles for zh.
Also applies to: 125-139
packages/app/src/context/highlights.tsx (2)
103-113: Locale-aware summary/title generation is clean and scoped.The localized release title and zh-first summary strategy are well-contained and keep structured
highlightspayloads untouched.Also applies to: 115-146
198-202: Nice backward-compatible API evolution.Defaulting
localeto"en"while threadinglanguage.locale()from provider keeps old callers safe and enables runtime-localized parsing.Also applies to: 208-209, 258-258
packages/desktop-electron/src/main/menu-labels.test.ts (1)
45-45: LGTM! Test assertion updated to match the localized Chinese menu label.The expectation correctly verifies that the Chinese GitHub menu item displays "在 GitHub 上查看爪印" (View 爪印 on GitHub), which aligns with the production change in
packages/desktop-electron/src/main/menu-labels.tsline 101.packages/desktop-electron/src/main/updater-dialog-labels.ts (2)
56-56: LGTM! Chinese busy message updated to remove brand prefix.The updated string "正在检查更新。" (Checking for updates.) is grammatically correct and removes the "PawWork" branding, which aligns with the PR's Chinese localization objectives. The corresponding test in
packages/desktop-electron/src/main/updater-dialog-labels.test.tsline 9 verifies this exact string.
77-77: LGTM! Chinese no-update message localized correctly.The updated string "已是最新版本。" (Already at the latest version.) removes the "PawWork" prefix and provides clear, concise Chinese copy. The test assertion at line 12 of
updater-dialog-labels.test.tsconfirms this string is correct.packages/desktop-electron/src/main/menu-labels.ts (1)
101-101: LGTM! Chinese GitHub menu label localized.The updated label "在 GitHub 上查看爪印" correctly replaces the English "PawWork" branding with the Chinese brand "爪印", following the PR's localization strategy. The test at
packages/desktop-electron/src/main/menu-labels.test.tsline 45 verifies this label.packages/desktop-electron/src/main/feedback.ts (2)
94-94: LGTM! Chinese feedback message updated to remove English branding.The updated message uses generic "应用" (app) instead of "PawWork", providing clear instructions in Chinese without the English product name. The string is grammatically correct and aligns with the PR's localization objectives. Test coverage at
packages/desktop-electron/src/main/feedback.test.tsline 84 confirms "PawWork" is no longer present.
100-100: LGTM! Form-open failure message localized correctly.The updated Chinese error message removes "PawWork" branding and clearly explains that the problem report is ready but the feedback form couldn't be opened. The test at
packages/desktop-electron/src/main/feedback.test.tsline 85 verifies the absence of "PawWork" in this string.packages/app/src/utils/desktop-context.test.ts (1)
16-16: LGTM! Tests updated to verify locale-aware window title.The test expectations correctly verify that the new
titlefield inDesktopContextis locale-aware:
- Chinese locale (
zh) →"爪印"- English locale (
en) →"PawWork"This aligns with the PR objective to propagate locale-aware runtime titles through the desktop context.
Also applies to: 33-33
packages/desktop-electron/src/main/updater-dialog-labels.test.ts (1)
9-9: LGTM! Test expectations updated to match localized updater strings.The assertions correctly verify the updated Chinese updater messages that remove the "PawWork" branding:
- Line 9:
"正在检查更新。"(Checking for updates.)- Line 12:
"已是最新版本。"(Already at the latest version.)These match the production changes in
packages/desktop-electron/src/main/updater-dialog-labels.tslines 56 and 77.Also applies to: 12-12
packages/desktop-electron/src/main/feedback.test.ts (1)
84-85: LGTM! Negative assertions verify Chinese strings exclude English branding.These new assertions strengthen the test coverage by explicitly verifying that the Simplified Chinese feedback dialog strings no longer contain "PawWork", which aligns with the production changes in
packages/desktop-electron/src/main/feedback.tslines 94 and 100.packages/desktop-electron/src/renderer/i18n/zh.test.ts (1)
1-9: LGTM! New test provides focused coverage for Chinese updater strings.This test file correctly verifies that the renderer-side Chinese i18n dictionary doesn't expose the English "PawWork" product name in updater messages. The assertions are clear and verify:
- Exact Chinese text for the up-to-date message (line 6)
- Preservation of the
{{version}}template placeholder in the download prompt (line 7)The test follows established patterns and complements the main-process localization tests.
packages/desktop-electron/src/renderer/i18n/zh.ts (1)
14-18: Updater Chinese copy changes look correct.Line 14 and Line 18 remove the old brand mention while preserving meaning and the
{{version}}interpolation contract.packages/desktop-electron/src/main/menu.ts (1)
5-25: Menu now uses locale-aware app display name at the right boundary.Line 24 correctly localizes only the displayed menu label while keeping the rest of the menu flow unchanged.
packages/desktop-electron/src/main/menu.test.ts (1)
125-149: Updated zh menu assertions are well-targeted.The new expectations at Line 128, Line 137, and Line 141 correctly validate the localized app label path end-to-end in the template.
packages/desktop-electron/src/preload/index.ts (1)
2-77: Preload initialization now correctly reuses canonical desktop-context builder.This avoids manual object drift and keeps the IPC payload aligned with the app-side context contract.
packages/desktop-electron/src/main/app-display-name.test.ts (1)
4-15: Good coverage for locale-specific app-name behavior.The tests cleanly verify zh localization plus stable suffix preservation without affecting en passthrough.
packages/desktop-electron/src/main/app-display-name.ts (1)
3-12: Localization helper implementation is solid.The exact-map + prefix-fallback strategy is appropriate for localized display naming without touching non-zh behavior.
packages/desktop-electron/src/main/index.ts (1)
520-524: Window title sync on desktop-context updates looks correct.Normalizing payload first and then applying
syncWindowTitleForDesktopContextat the IPC write path is a solid root-cause fix for locale-aware runtime titles.packages/app/src/utils/desktop-context.ts (1)
11-27: Good centralization of locale-aware window-title derivation.Adding
desktopWindowTitle()and wiring it intobuildDesktopContext()keeps desktop title behavior consistent across call sites.packages/desktop-electron/src/main/desktop-context-window.test.ts (1)
5-46: Targeted regression coverage is strong here.The tests validate both payload coercion and title synchronization behavior, including malformed IPC input paths.
packages/desktop-electron/src/main/desktop-context-window.ts (1)
6-24: Helper extraction and normalization logic look solid.The payload coercion and locale-derived title assignment are clean, and
syncWindowTitleForDesktopContextkeeps window title updates explicit.
3be1c86 to
4fc46e7
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
packages/app/src/context/highlights.tsx (1)
85-89:⚠️ Potential issue | 🟠 MajorRelax zh notice extraction when
主要更新subheading is absent.At Line 88, zh extraction only succeeds when
### 主要更新exists. If## 中文版本contains bullets directly, zh summaries are dropped. Return the Chinese section as fallback.Suggested patch
function findChineseUpdateNotice(body: string) { const chinese = findHeadingSection(body, /^#{2,6}\s+中文版本\s*$/) if (!chinese) return - return findHeadingSection(chinese, /^#{3,6}\s+主要更新\s*$/) + return findHeadingSection(chinese, /^#{3,6}\s+主要更新\s*$/) ?? chinese }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/context/highlights.tsx` around lines 85 - 89, The current findChineseUpdateNotice function returns only the nested "主要更新" subsection and drops the entire Chinese section when that subheading is missing; update findChineseUpdateNotice so it first obtains the Chinese section via findHeadingSection(body, /^#{2,6}\s+中文版本\s*$/) and then attempts to find the "主要更新" subsection inside it with findHeadingSection(chinese, /^#{3,6}\s+主要更新\s*$/), but if that nested call returns nothing, return the full chinese section as a fallback (i.e., return nestedSection || chinese). Ensure references to findChineseUpdateNotice and findHeadingSection are used to locate the change.packages/app/src/i18n/zh.ts (1)
152-152:⚠️ Potential issue | 🟠 MajorFirst-occurrence branding rule is still not applied on key zh surfaces.
These entries still use
爪印as the first visible brand mention, which conflicts with the requiredPawWork 爪印first-occurrence pattern on those surfaces.Suggested targeted fix
- "dialog.model.unpaid.freeModels.title": "爪印内置免费模型", + "dialog.model.unpaid.freeModels.title": "PawWork 爪印内置免费模型", - "session.new.subtitle": "爪印可以帮你处理文件、分析信息、撰写内容并完成各类任务。", + "session.new.subtitle": "PawWork 爪印可以帮你处理文件、分析信息、撰写内容并完成各类任务。", - "sidebar.gettingStarted.line1": "爪印内置免费模型,你可以立即开始使用。", + "sidebar.gettingStarted.line1": "PawWork 爪印内置免费模型,你可以立即开始使用。",Also applies to: 582-582, 669-669
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/i18n/zh.ts` at line 152, The translated string for key "dialog.model.unpaid.freeModels.title" (and other zh entries that begin with the brand `爪印`) violates the first-occurrence rule — update the visible brand mention to the required form by replacing the leading "爪印" with "PawWork 爪印" in that key and any other zh entries that start with "爪印" (e.g., the other occurrences flagged in the review). Ensure you only change the visible label text (the value strings) in packages/app/src/i18n/zh.ts, leaving keys and surrounding code untouched.
🤖 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/app/src/i18n/zh-branding.test.ts`:
- Around line 5-26: The tests assert pure Chinese branding for keys accessed via
zh (e.g., in the test "uses Chinese product naming on key user-facing surfaces"
and the curatedKeys array used in "removes standalone PawWork from curated
Chinese UI strings"), but policy requires the mixed first-occurrence form
"PawWork 爪印"; update the assertions to accept or expect the mixed form instead
of rejecting any "PawWork" substring. Concretely, modify the expectations
referencing zh["dialog.model.unpaid.freeModels.title"],
zh["session.new.subtitle"], zh["sidebar.gettingStarted.line1"],
zh["app.name.desktop"], zh["toast.update.description"], and
zh["error.page.report.prefix"] so they either assert the exact "PawWork 爪印"
phrasing where applicable or change the negative check in the curatedKeys loop
to allow "PawWork" when followed by "爪印" (e.g., ensure tests no longer fail on
the allowed "PawWork 爪印" first-occurrence pattern).
In `@packages/desktop-electron/src/main/app-display-name.test.ts`:
- Around line 10-14: Add a new test assertion that ensures the regex fallback
handles other PawWork variants by verifying localizedAppDisplayName("PawWork
Nightly", "zh") returns "爪印 Nightly"; update the test in
app-display-name.test.ts alongside the existing assertions that call
localizedAppDisplayName("PawWork", "zh"), ("PawWork Beta", "zh"), and ("PawWork
Dev", "zh") so the fallback contract implemented in localizedAppDisplayName is
locked for future "PawWork*" variants.
---
Duplicate comments:
In `@packages/app/src/context/highlights.tsx`:
- Around line 85-89: The current findChineseUpdateNotice function returns only
the nested "主要更新" subsection and drops the entire Chinese section when that
subheading is missing; update findChineseUpdateNotice so it first obtains the
Chinese section via findHeadingSection(body, /^#{2,6}\s+中文版本\s*$/) and then
attempts to find the "主要更新" subsection inside it with
findHeadingSection(chinese, /^#{3,6}\s+主要更新\s*$/), but if that nested call
returns nothing, return the full chinese section as a fallback (i.e., return
nestedSection || chinese). Ensure references to findChineseUpdateNotice and
findHeadingSection are used to locate the change.
In `@packages/app/src/i18n/zh.ts`:
- Line 152: The translated string for key "dialog.model.unpaid.freeModels.title"
(and other zh entries that begin with the brand `爪印`) violates the
first-occurrence rule — update the visible brand mention to the required form by
replacing the leading "爪印" with "PawWork 爪印" in that key and any other zh
entries that start with "爪印" (e.g., the other occurrences flagged in the
review). Ensure you only change the visible label text (the value strings) in
packages/app/src/i18n/zh.ts, leaving keys and surrounding code untouched.
🪄 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: 9cc50833-c1f6-42a0-b544-f3b64fbdc388
📒 Files selected for processing (28)
packages/app/package.jsonpackages/app/src/app.tsxpackages/app/src/context/highlights.test.tspackages/app/src/context/highlights.tsxpackages/app/src/desktop-api.tspackages/app/src/i18n/zh-branding.test.tspackages/app/src/i18n/zh.tspackages/app/src/utils/desktop-context.test.tspackages/app/src/utils/desktop-context.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/desktop-electron/electron-builder.config.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/main/app-display-name.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/feedback.test.tspackages/desktop-electron/src/main/feedback.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/menu-labels.test.tspackages/desktop-electron/src/main/menu-labels.tspackages/desktop-electron/src/main/menu.test.tspackages/desktop-electron/src/main/menu.tspackages/desktop-electron/src/main/updater-dialog-labels.test.tspackages/desktop-electron/src/main/updater-dialog-labels.tspackages/desktop-electron/src/preload/index.tspackages/desktop-electron/src/preload/types.tspackages/desktop-electron/src/renderer/i18n/zh.test.tspackages/desktop-electron/src/renderer/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). (11)
- GitHub Check: smoke-macos-arm64
- GitHub Check: unit-windows-desktop
- GitHub Check: unit-windows-opencode-server-tools
- GitHub Check: unit-windows-opencode-config-project
- GitHub Check: unit-windows-app
- GitHub Check: unit-windows-opencode-session
- GitHub Check: unit-opencode
- GitHub Check: typecheck
- GitHub Check: unit-desktop
- GitHub Check: analyze-js-ts
- GitHub Check: e2e-artifacts
🧰 Additional context used
📓 Path-based instructions (2)
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/app/AGENTS.md)
Always prefer
createStoreover multiplecreateSignalcalls in SolidJS
Files:
packages/app/src/utils/desktop-context.test.tspackages/app/src/desktop-api.tspackages/app/src/app.tsxpackages/app/src/i18n/zh-branding.test.tspackages/app/src/utils/desktop-context.tspackages/app/src/context/highlights.tsxpackages/app/src/context/highlights.test.tspackages/app/src/i18n/zh.ts
packages/desktop-electron/src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/desktop-electron/AGENTS.md)
Renderer process should only call
window.apifromsrc/preload
Files:
packages/desktop-electron/src/renderer/i18n/zh.test.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/main/feedback.test.tspackages/desktop-electron/src/main/menu-labels.test.tspackages/desktop-electron/src/main/menu.test.tspackages/desktop-electron/src/main/menu.tspackages/desktop-electron/src/main/feedback.tspackages/desktop-electron/src/main/app-display-name.tspackages/desktop-electron/src/main/updater-dialog-labels.tspackages/desktop-electron/src/preload/index.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/desktop-electron/src/renderer/i18n/zh.tspackages/desktop-electron/src/preload/types.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/updater-dialog-labels.test.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/menu-labels.ts
🧠 Learnings (28)
📓 Common learnings
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.
📚 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/app/src/utils/desktop-context.test.tspackages/desktop-electron/src/renderer/i18n/zh.test.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/main/feedback.test.tspackages/desktop-electron/src/main/menu-labels.test.tspackages/app/src/desktop-api.tspackages/desktop-electron/src/main/menu.test.tspackages/desktop-electron/src/main/menu.tspackages/desktop-electron/src/main/feedback.tspackages/app/src/app.tsxpackages/desktop-electron/src/main/app-display-name.tspackages/desktop-electron/src/main/updater-dialog-labels.tspackages/app/src/i18n/zh-branding.test.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/app/src/utils/desktop-context.tspackages/desktop-electron/src/renderer/i18n/zh.tspackages/desktop-electron/src/preload/types.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/updater-dialog-labels.test.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/menu-labels.tspackages/app/src/context/highlights.tsxpackages/app/src/context/highlights.test.tspackages/app/src/i18n/zh.tspackages/desktop-electron/electron-builder.config.ts
📚 Learning: 2026-04-22T08:49:47.800Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/desktop-electron/src/main/index-sidecar-source.test.ts:3-11
Timestamp: 2026-04-22T08:49:47.800Z
Learning: In `packages/desktop-electron/src/main/index-sidecar-source.test.ts` (Astro-Han/pawwork), the test intentionally uses `expect(source).toContain` / `expect(source).not.toContain` string matching against the raw `index.ts` source text as a lightweight sidecar contract guard. The maintainer has explicitly chosen not to introduce an AST parser (e.g., `babel/parser` or acorn) for this purpose. Do not flag these string-based assertions as fragile or suggest converting them to AST-based matching.
Applied to files:
packages/app/src/utils/desktop-context.test.tspackages/desktop-electron/src/renderer/i18n/zh.test.tspackages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/main/feedback.test.tspackages/desktop-electron/src/main/menu-labels.test.tspackages/desktop-electron/src/main/menu.test.tspackages/app/src/i18n/zh-branding.test.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/updater-dialog-labels.test.tspackages/app/src/context/highlights.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : When validating routing, assert against canonical or resolved workspace slugs using shared helpers from `../actions` to account for Windows canonicalization
Applied to files:
packages/app/src/utils/desktop-context.test.tspackages/desktop-electron/src/main/desktop-context-window.test.ts
📚 Learning: 2026-04-20T14:36:31.032Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.032Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Prefer Effect-aware helpers from `fixture/fixture.ts` over building manual runtimes in tests: use `tmpdirScoped()` for scoped temp directories, `provideInstance(dir)(effect)` for low-level binding without directory creation, `provideTmpdirInstance(...)` for single temp instance binding, or `provideTmpdirServer(...)` for tests that also need the test LLM server.
Applied to files:
packages/app/src/utils/desktop-context.test.tspackages/desktop-electron/src/main/desktop-context-window.test.ts
📚 Learning: 2026-04-23T07:23:23.849Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 180
File: packages/app/src/components/session/session-new-view.tsx:13-18
Timestamp: 2026-04-23T07:23:23.849Z
Learning: In pawwork (Astro-Han/pawwork), prefer using `createStore` instead of multiple `createSignal` calls only when the signals represent **coupled** object state that is updated together (i.e., there is at least one shared batch-update site where the state is changed in the same transaction). If the state fields are **independent** and are mutated by separate handlers (e.g., one handler updates only `selectedSkill` while another updates only `mode`), keep them as individual `createSignal` calls—using `createStore` for truly independent fields adds boilerplate without behavioral benefit.
Applied to files:
packages/app/src/utils/desktop-context.test.tspackages/app/src/desktop-api.tspackages/app/src/app.tsxpackages/app/src/i18n/zh-branding.test.tspackages/app/src/utils/desktop-context.tspackages/app/src/context/highlights.tsxpackages/app/src/context/highlights.test.tspackages/app/src/i18n/zh.ts
📚 Learning: 2026-04-23T15:10:21.635Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 191
File: packages/app/src/components/session/pawwork-skill-meta.ts:38-39
Timestamp: 2026-04-23T15:10:21.635Z
Learning: This repo configures Tailwind v4 with `--color-*: initial`, which effectively breaks standard Tailwind palette utilities (e.g., `text-violet-500` can resolve to no CSS variable and render as a no-op/black). For brand/accent colors that are not backed by semantic design tokens, use inline styles with the exact hex value (e.g., `style={{ color: '#8B5FBF' }}` / `homeIconStyle: { color: '#8B5FBF' }`) and add a short comment explaining that Tailwind palette utilities won’t work due to the `--color-*: initial` setup. Do not suggest replacing these inline hex colors with Tailwind palette classes anywhere in this repo.
Applied to files:
packages/app/src/utils/desktop-context.test.tspackages/app/src/desktop-api.tspackages/app/src/app.tsxpackages/app/src/i18n/zh-branding.test.tspackages/app/src/utils/desktop-context.tspackages/app/src/context/highlights.tsxpackages/app/src/context/highlights.test.tspackages/app/src/i18n/zh.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use lowercase, descriptive test names (e.g., 'sidebar can be toggled')
Applied to files:
packages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/main/feedback.test.tspackages/desktop-electron/src/main/menu-labels.test.tspackages/desktop-electron/src/main/menu.test.tspackages/app/src/context/highlights.test.ts
📚 Learning: 2026-04-21T13:45:45.149Z
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.
Applied to files:
packages/desktop-electron/src/main/app-display-name.test.tspackages/desktop-electron/src/main/app-display-name.tspackages/app/src/i18n/zh-branding.test.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/app/src/utils/desktop-context.tspackages/desktop-electron/src/renderer/i18n/zh.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/index.tspackages/app/src/context/highlights.tsxpackages/app/src/context/highlights.test.tspackages/desktop-electron/electron-builder.config.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test files should be named with the pattern `feature-name.spec.ts`
Applied to files:
packages/desktop-electron/src/main/app-display-name.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use SCREAMING_SNAKE_CASE for constants in tests
Applied to files:
packages/desktop-electron/src/main/app-display-name.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use camelCase for variable names in tests
Applied to files:
packages/desktop-electron/src/main/app-display-name.test.ts
📚 Learning: 2026-04-20T14:36:08.774Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.774Z
Learning: Applies to packages/desktop-electron/src/**/*.{ts,tsx,js,jsx} : Renderer process should only call `window.api` from `src/preload`
Applied to files:
packages/app/src/desktop-api.tspackages/app/package.jsonpackages/desktop-electron/src/preload/index.tspackages/desktop-electron/src/preload/types.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/index.ts
📚 Learning: 2026-04-22T09:32:58.310Z
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.
Applied to files:
packages/desktop-electron/src/main/menu.test.tspackages/desktop-electron/src/main/feedback.tspackages/desktop-electron/src/main/updater-dialog-labels.tspackages/app/src/i18n/zh-branding.test.tspackages/desktop-electron/src/renderer/i18n/zh.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/desktop-electron/src/main/menu-labels.tspackages/app/src/i18n/zh.tspackages/desktop-electron/electron-builder.config.ts
📚 Learning: 2026-04-23T15:10:26.994Z
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.
Applied to files:
packages/app/src/i18n/zh-branding.test.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/app/src/i18n/zh.ts
📚 Learning: 2026-04-23T08:51:04.230Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 186
File: packages/opencode/test/plugin/workspace-adaptor.test.ts:139-144
Timestamp: 2026-04-23T08:51:04.230Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/util/filesystem.ts`), the `Filesystem` utility does NOT expose a `remove` or `unlink` helper. The established repository pattern for auth.json teardown in tests (e.g. `provider.test.ts`, `amazon-bedrock.test.ts`, `workspace-adaptor.test.ts`) is to combine `Filesystem.write` with `node:fs/promises unlink`. Do not flag this mixed usage as inconsistent — it is the correct and intentional pattern.
Applied to files:
packages/app/src/i18n/zh-branding.test.tspackages/desktop-electron/electron-builder-app-update.test.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/electron-builder.config.ts
📚 Learning: 2026-04-24T06:50:02.712Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 211
File: packages/opencode/src/provider/models.ts:113-179
Timestamp: 2026-04-24T06:50:02.712Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/provider/models.ts`), `PublishModel` and `PublishProvider` intentionally duplicate fields from `Model` and `Provider` with looser optionality. The split is a deliberate behavior boundary: `PublishModel`/`PublishProvider` (with `.passthrough()`) are used for lenient publish-time validation of incoming catalogs, while `Model`/`Provider` are used for strict runtime normalization. Do not flag this duplication as a maintenance burden or suggest extracting a shared base schema — the explicit separation is intentional and tied to the models-refresh reliability path introduced in PR `#211`.
Applied to files:
packages/app/src/i18n/zh-branding.test.tspackages/desktop-electron/electron-builder.config.ts
📚 Learning: 2026-04-21T16:57:25.580Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 102
File: packages/opencode/src/config/agent.ts:108-119
Timestamp: 2026-04-21T16:57:25.580Z
Learning: In `packages/opencode/src/config/agent.ts` (Astro-Han/pawwork), `ConfigPermission.Info` only accepts permission objects or the three action strings `"ask"`, `"allow"`, `"deny"`, and transforms those action strings into `{ "*": action }` before `normalize()` runs. By the time `normalize()` is reached, `configuredPermission` is always either `undefined` or a `Record<string, Rule>` — never a raw arbitrary string. The `Object.assign(permission, configuredPermission)` pattern is therefore safe. Do not flag it as corrupting string permission references.
Applied to files:
packages/app/src/i18n/zh-branding.test.ts
📚 Learning: 2026-04-20T14:36:08.774Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.774Z
Learning: Applies to packages/desktop-electron/src/main/ipc.ts : Main process should register IPC handlers in `src/main/ipc.ts`
Applied to files:
packages/desktop-electron/src/preload/index.tspackages/desktop-electron/src/main/desktop-context-window.test.tspackages/desktop-electron/src/preload/types.tspackages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/index.ts
📚 Learning: 2026-04-20T14:36:31.032Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.032Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `config` option in `tmpdir` to write an `opencode.json` config file during test setup by passing a partial Config.Info object.
Applied to files:
packages/desktop-electron/electron-builder-app-update.test.ts
📚 Learning: 2026-04-20T14:36:31.032Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.032Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `init` option in `tmpdir` to define custom setup functions that can return extra data accessible via `tmp.extra`, and use the `dispose` option for custom cleanup logic.
Applied to files:
packages/desktop-electron/electron-builder-app-update.test.ts
📚 Learning: 2026-04-20T14:36:31.032Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.032Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `tmpdir` function from `fixture/fixture.ts` to create temporary directories for tests with automatic cleanup. Use `await using` syntax to ensure automatic cleanup when the variable goes out of scope.
Applied to files:
packages/desktop-electron/electron-builder-app-update.test.ts
📚 Learning: 2026-04-24T13:03:10.835Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 222
File: packages/desktop-electron/src/main/index.ts:686-692
Timestamp: 2026-04-24T13:03:10.835Z
Learning: In `packages/desktop-electron/src/main/index.ts`, the `checkForUpdates()` function intentionally uses recursive self-invocation for the "Retry" path in the update-check failure dialog. This is mandated by the v5.2 design spec (`#213`): "Await the retry recursion and log any rejection so support can see repeated failures." Because retries are user-paced (require a button click), all prior async frames have already unwound through microtasks before the next attempt, so there is no stack/frame-nesting problem in practice. Do not suggest refactoring this to an iterative loop.
Applied to files:
packages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/src/main/updater-dialog-labels.test.ts
📚 Learning: 2026-04-20T14:36:21.288Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.288Z
Learning: Applies to packages/opencode/**/*.ts : Prefer `FileSystem.FileSystem` instead of raw `fs/promises` for effectful file I/O in Effect services
Applied to files:
packages/desktop-electron/src/main/desktop-context-window.tspackages/desktop-electron/electron-builder.config.ts
📚 Learning: 2026-04-20T14:36:21.288Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.288Z
Learning: Applies to packages/opencode/**/*.ts : Prefer `Path.Path`, `Config`, `Clock`, and `DateTime` services when those concerns are already inside Effect code
Applied to files:
packages/desktop-electron/src/main/desktop-context-window.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Import test utilities from `../fixtures` instead of `playwright/test`
Applied to files:
packages/desktop-electron/src/main/desktop-context-window.tspackages/app/src/context/highlights.test.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Prefer fluent helpers and drivers when they make intent obvious and reduce locator-heavy noise in tests
Applied to files:
packages/app/src/context/highlights.test.ts
📚 Learning: 2026-04-20T14:21:56.373Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 71
File: packages/app/src/components/session/session-status-connections.tsx:146-147
Timestamp: 2026-04-20T14:21:56.373Z
Learning: In the Astro-Han/pawwork repository (SolidJS app), `sync.data.config` is always initialized to `{}` at `packages/app/src/context/global-sync.tsx` line 71 and is never `undefined` at runtime. Non-optional property access like `sync.data.config.plugin` is intentional and consistent with the pattern used in `packages/app/src/components/status-popover-body.tsx` line 243. Do not flag `sync.data.config.plugin` as needing optional chaining.
Applied to files:
packages/desktop-electron/electron-builder.config.ts
🔇 Additional comments (27)
packages/desktop-electron/electron-builder-app-update.test.ts (2)
44-53: Good coverage of macOS localized-display toggle and identity invariants.This test cleanly verifies localized display-name enablement while guarding that package identifiers remain unchanged.
67-83: Localized InfoPlist artifact assertions are solid and regression-focused.Validating both locale directories and both bundle-name keys is the right guard for packaging drift.
packages/desktop-electron/electron-builder.config.ts (2)
14-18: Localized channel mapping and InfoPlist writer implementation look correct.The helper is clear and deterministic for both required Chinese macOS locale folders.
Also applies to: 43-52
83-85: afterPack control flow is well-structured for mac localization + updater config behavior.Setting
LSHasLocalizedDisplayNameand sequencing localized writes before conditional updater config generation is appropriate.Also applies to: 129-133
packages/app/src/context/highlights.test.ts (1)
21-60: Locale regression coverage here is strong.The zh-first parsing path, English fallback behavior, and “do not rewrite structured highlight titles” contract are all validated clearly.
Also applies to: 125-139
packages/desktop-electron/src/main/feedback.ts (1)
94-94: Localized zh feedback copy update looks correct.These string updates are scoped to user-facing copy and do not alter handler behavior.
Also applies to: 100-100
packages/desktop-electron/src/main/menu-labels.ts (1)
101-101: Menu zh label update is consistent with branding localization.packages/desktop-electron/src/main/feedback.test.ts (1)
84-85: Good regression guard for zh branding copy.These assertions directly protect against accidental reintroduction of legacy branding in the two updated fields.
packages/desktop-electron/src/main/updater-dialog-labels.ts (1)
56-56: Updater zh dialog copy changes are clean and low-risk.Also applies to: 77-77
packages/desktop-electron/src/main/updater-dialog-labels.test.ts (1)
9-9: Test expectations correctly follow updated zh updater copy.Also applies to: 12-12
packages/desktop-electron/src/main/app-display-name.ts (1)
3-12:localizedAppDisplayNameimplementation is solid.The exact-match map plus prefix fallback gives good coverage for current and future
PawWork*variants in zh.packages/desktop-electron/src/main/app-display-name.test.ts (1)
5-14: Core behavior coverage for localized display names looks good.packages/desktop-electron/src/main/menu.ts (1)
5-5: Menu integration of localized app display name is correct.Using
localizedAppDisplayName(app.getName(), locale)here cleanly scopes localization to menu presentation without changing underlying app identity.Also applies to: 24-24
packages/desktop-electron/src/main/menu.test.ts (1)
125-149: Looks good — zh menu branding assertions are correctly tightened.The updated app name and Help submenu GitHub-label checks match the intended localized menu behavior.
packages/desktop-electron/src/main/menu-labels.test.ts (1)
41-46: Good coverage addition for the zh GitHub menu label.This assertion cleanly guards the updated Chinese branding string.
packages/app/src/utils/desktop-context.ts (1)
8-13: Solid utility change — title derivation is clean and centralized.Adding
desktopWindowTitle(locale)and wiring it intobuildDesktopContextis straightforward and maintainable.Also applies to: 26-26
packages/app/src/utils/desktop-context.test.ts (1)
16-17: Good regression coverage for localized desktop titles.The expected
titleassertions match the new context shape and locale mapping.Also applies to: 33-34
packages/desktop-electron/src/renderer/i18n/zh.ts (1)
14-18: Updater zh copy update looks correct.Both revised strings remain clear and keep interpolation behavior intact.
packages/desktop-electron/src/renderer/i18n/zh.test.ts (1)
5-8: Nice focused regression test for zh updater messaging.This gives precise coverage for the updated renderer copy keys.
packages/desktop-electron/src/main/desktop-context-window.ts (1)
6-17: Strong normalization and title-sync extraction.The helper split is clean, and the normalization logic safely constrains untrusted payloads before window title updates.
Also applies to: 19-24
packages/desktop-electron/src/main/desktop-context-window.test.ts (1)
4-47: Good regression coverage for context normalization and title syncing.The test cases cover both happy-path and malformed IPC payload behavior, plus BrowserWindow title propagation.
packages/app/package.json (1)
8-8: Subpath export addition looks correct.This cleanly exposes the desktop-facing API surface for cross-package consumers.
packages/app/src/desktop-api.ts (1)
1-2: Barrel export is well-scoped and useful.This provides a stable shared API boundary for desktop consumers.
packages/desktop-electron/src/preload/index.ts (1)
2-2: Nice consistency improvement for initial desktop context payload.Using
buildDesktopContexthere keeps preload/main/app in sync on context shape and title derivation.Also applies to: 76-77
packages/app/src/app.tsx (1)
48-49: Route-aware title sync is correctly implemented.The effect now tracks navigation and locale while explicitly avoiding session-route title overrides.
Also applies to: 181-186
packages/desktop-electron/src/preload/types.ts (1)
1-1: Type boundary cleanup looks good.Importing from the public
desktop-apientrypoint improves package encapsulation.packages/desktop-electron/src/main/index.ts (1)
11-12: Shared context normalization and window-title sync integration is solid.Using the extracted helpers here improves consistency across preload/main flows and ensures window titles follow normalized locale context.
Also applies to: 55-56, 119-121, 201-203, 520-523
Summary
app.getName()InfoPlist.stringsand cover the behavior with focused regression testsWhy
Issue #196 tracks the UI-only Chinese branding pass. The app already used the Chinese brand in docs and prompts, but Chinese UI surfaces, release highlights, menu labels, updater copy, and runtime titles still showed only "PawWork".
Related Issue
Closes #196
How To Verify
cd packages/app && bun test --preload ./happydom.ts ./src/context/highlights.test.ts ./src/i18n/zh-branding.test.ts ./src/utils/desktop-context.test.tscd packages/desktop-electron && bun test ./src/main/app-display-name.test.ts ./src/main/desktop-context-window.test.ts ./src/main/menu-labels.test.ts ./src/main/menu.test.ts ./src/main/feedback.test.ts ./src/main/updater-dialog-labels.test.ts ./src/renderer/i18n/zh.test.ts ./electron-builder-app-update.test.tsbun run typecheckScreenshots or Recordings
Not attached. This PR is mostly copy, runtime title, menu, and bundle-metadata localization; verification here is covered by the focused tests above.
Checklist
dev, and my PR title and commit messages use Conventional Commits in EnglishSummary by CodeRabbit
New Features
Localization
Tests