Skip to content

fix(desktop): localize Chinese branding surfaces#224

Merged
Astro-Han merged 11 commits into
devfrom
codex/fix-i196-chinese-brand
Apr 24, 2026
Merged

fix(desktop): localize Chinese branding surfaces#224
Astro-Han merged 11 commits into
devfrom
codex/fix-i196-chinese-brand

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Apr 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • localize Chinese-facing app and desktop copy from "PawWork" to the Chinese brand while keeping repo, updater, bundle, and artifact identifiers stable
  • parse Chinese release-note summaries, propagate locale-aware runtime titles through desktop context, and localize the macOS menu display name without changing app.getName()
  • add macOS localized bundle display names via InfoPlist.strings and cover the behavior with focused regression tests

Why

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.ts
  • cd 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.ts
  • bun run typecheck

Screenshots 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

  • I linked the related issue, or stated why there is no issue
  • This PR has type, scope, and priority labels, or I requested maintainer labeling
  • I listed the relevant verification steps, including tests when behavior changed
  • I manually checked visible UI or copy changes when needed, with screenshots or recordings
  • I considered macOS and Windows impact for desktop, packaging, updater, signing, paths, shell, or permissions changes
  • I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, or generated/local file changes when relevant
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English

Summary by CodeRabbit

  • New Features

    • Window title now syncs dynamically with app language and avoids changing on session routes.
    • Release notes/highlights are summarized per locale and titles are localized.
    • macOS packaging includes localized app display names and desktop UI shows localized product names (e.g., “爪印” for Chinese).
  • Localization

    • Rebranded Chinese UI strings replacing “PawWork” with “爪印” across menus, dialogs, updater, and feedback.
  • Tests

    • Added/expanded locale-aware tests for parsing, display names, menus, updater text, desktop context, and packaging.

@coderabbitai

coderabbitai Bot commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@Astro-Han has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 50 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 33692288-c80f-488a-986e-30697c81b4d9

📥 Commits

Reviewing files that changed from the base of the PR and between 4fc46e7 and c9c7045.

📒 Files selected for processing (3)
  • packages/app/src/context/highlights.test.ts
  • packages/app/src/context/highlights.tsx
  • packages/desktop-electron/src/main/app-display-name.test.ts
📝 Walkthrough

Walkthrough

Adds locale-aware Chinese branding and window-title propagation: introduces localized app titles, exposes and uses desktopWindowTitle, passes title through DesktopContext and IPC, synchronizes BrowserWindow titles in main process, makes release-highlight parsing locale-aware, and updates multiple zh localization strings and tests.

Changes

Cohort / File(s) Summary
Renderer: desktop context & title
packages/app/src/app.tsx, packages/app/src/utils/desktop-context.ts, packages/app/src/utils/desktop-context.test.ts
Add title to DesktopContext, export desktopWindowTitle(locale), compute title in renderer and set document.title reactively in DesktopContextRouteBridge; update tests for expected title.
Release highlights locale support
packages/app/src/context/highlights.tsx, packages/app/src/context/highlights.test.ts
Make changelog/release parsing locale-aware (new locale param), localize release titles (爪印 vs PawWork), and update tests to assert locale-specific extraction and fallback behavior.
App i18n: Chinese branding
packages/app/src/i18n/zh.ts, packages/app/src/i18n/zh-branding.test.ts
Replace many PawWork occurrences with 爪印 in zh dictionary and add tests asserting expected Chinese strings and absence of legacy term.
Electron main: context normalization & title sync
packages/desktop-electron/src/main/desktop-context-window.ts, packages/desktop-electron/src/main/desktop-context-window.test.ts, packages/desktop-electron/src/main/index.ts
Add normalizeDesktopContextPayload and syncWindowTitleForDesktopContext, centralize payload normalization, and call title sync after setDesktopContext; tests added/updated.
Electron display-name localization
packages/desktop-electron/src/main/app-display-name.ts, packages/desktop-electron/src/main/app-display-name.test.ts
Add localizedAppDisplayName(appName, locale) to map or prefix-replace English app names to Chinese variants while preserving suffixes; include tests.
Electron menus, labels, feedback, updater strings
packages/desktop-electron/src/main/menu.ts, packages/desktop-electron/src/main/menu-labels.ts, packages/desktop-electron/src/main/menu-labels.test.ts, packages/desktop-electron/src/main/menu.test.ts, packages/desktop-electron/src/main/feedback.ts, packages/desktop-electron/src/main/feedback.test.ts, packages/desktop-electron/src/main/updater-dialog-labels.ts, packages/desktop-electron/src/main/updater-dialog-labels.test.ts
Adjust zh label strings to use 爪印 and revised phrasing; derive menu appName via localizedAppDisplayName; update tests accordingly.
macOS builder & localized InfoPlist
packages/desktop-electron/electron-builder.config.ts, packages/desktop-electron/electron-builder-app-update.test.ts
Generate InfoPlist.strings for zh-Hans.lproj and zh_CN.lproj, declare LSHasLocalizedDisplayName, write localized plist strings in afterPack, and add tests to verify generated localized resources.
Preload & renderer i18n tests
packages/desktop-electron/src/preload/index.ts, packages/desktop-electron/src/renderer/i18n/zh.ts, packages/desktop-electron/src/renderer/i18n/zh.test.ts, packages/desktop-electron/src/preload/types.ts, packages/app/src/desktop-api.ts, packages/app/package.json
Use buildDesktopContext in preload initialization, add barrel export desktop-api and switch preload type imports to it; remove PawWork from renderer updater strings; add renderer zh tests.

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • #196: Implements the Chinese branding changes requested (introduce “爪印” in zh UI surfaces and window titles).
  • Astro-Han/pawwork#163: Touches the same release-note parsing logic and locale-specific section selection.

Possibly related PRs

Suggested labels

bug, P2, desktop, app, ui

Poem

🐰 I hopped through code and swapped a name,
"PawWork" bowed out so "爪印" could claim,
Titles now travel from renderer to frame,
Menus and tests and plist files the same,
A little rabbit cheers this localized game.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: localizing Chinese branding surfaces from 'PawWork' to the Chinese brand name '爪印' across the desktop app.
Description check ✅ Passed The description covers the Summary, Why, Related Issue (#196), How To Verify (with test commands), and most checklist items; some optional items (screenshots, PR labels) are noted as unchecked but non-critical.
Linked Issues check ✅ Passed The PR implements the primary objectives from issue #196: updates Chinese UI strings in zh.ts, adds locale-aware release highlights parsing, introduces desktop context title handling, localizes menu labels and updater copy, and adds macOS bundle display name support via InfoPlist.strings.
Out of Scope Changes check ✅ Passed All changes align with issue #196 objectives. The PR correctly avoids scope creep: Electron productName, .app/.dmg/.exe filenames, trademark/domain work, and account standardization remain unchanged as specified in the issue's out-of-scope section.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-i196-chinese-brand

Comment @coderabbitai help to get the list of available commands and usage tips.

@Astro-Han Astro-Han force-pushed the codex/fix-i196-chinese-brand branch from 584b33b to 3be1c86 Compare April 24, 2026 16:38

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

Comment thread packages/app/src/app.tsx
Comment thread packages/app/src/context/highlights.tsx Outdated
Comment thread packages/desktop-electron/src/main/desktop-context-window.ts Outdated
Comment thread packages/desktop-electron/src/main/index.ts Outdated
Comment thread packages/desktop-electron/src/preload/index.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 | 🟠 Major

Restore 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 with PawWork 爪印 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 | 🔴 Critical

Add title field to all DesktopContext literals in the test file.

Making title required in DesktopContext breaks 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 the title field or use buildDesktopContext(...) 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

📥 Commits

Reviewing files that changed from the base of the PR and between 06fd278 and 584b33b.

📒 Files selected for processing (25)
  • packages/app/src/app.tsx
  • packages/app/src/context/highlights.test.ts
  • packages/app/src/context/highlights.tsx
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/app/src/i18n/zh.ts
  • packages/app/src/utils/desktop-context.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/desktop-electron/electron-builder.config.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/desktop-electron/src/main/app-display-name.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/menu-labels.test.ts
  • packages/desktop-electron/src/main/menu-labels.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/desktop-electron/src/main/menu.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.test.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.ts
  • packages/desktop-electron/src/preload/index.ts
  • packages/desktop-electron/src/renderer/i18n/zh.test.ts
  • packages/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.api from src/preload

Files:

  • packages/desktop-electron/src/main/menu-labels.test.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/renderer/i18n/zh.test.ts
  • packages/desktop-electron/src/main/menu.ts
  • packages/desktop-electron/src/main/menu-labels.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/desktop-electron/src/renderer/i18n/zh.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/app-display-name.ts
  • packages/desktop-electron/src/preload/index.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/menu.test.ts
packages/app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (packages/app/AGENTS.md)

Always prefer createStore over multiple createSignal calls in SolidJS

Files:

  • packages/app/src/utils/desktop-context.test.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/app/src/app.tsx
  • packages/app/src/i18n/zh.ts
  • packages/app/src/context/highlights.tsx
  • packages/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.ts
  • packages/app/src/utils/desktop-context.test.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/renderer/i18n/zh.test.ts
  • packages/desktop-electron/src/main/menu.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/desktop-electron/src/main/menu-labels.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/desktop-electron/src/renderer/i18n/zh.ts
  • packages/app/src/app.tsx
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/app-display-name.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/desktop-electron/electron-builder.config.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/app/src/i18n/zh.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/app/src/context/highlights.tsx
  • packages/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.ts
  • packages/app/src/utils/desktop-context.test.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/renderer/i18n/zh.test.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/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.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/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.ts
  • packages/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.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/app/src/app.tsx
  • packages/app/src/i18n/zh.ts
  • packages/app/src/context/highlights.tsx
  • packages/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.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/app/src/app.tsx
  • packages/app/src/i18n/zh.ts
  • packages/app/src/context/highlights.tsx
  • packages/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.ts
  • packages/desktop-electron/src/main/menu-labels.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.ts
  • packages/desktop-electron/src/renderer/i18n/zh.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/app-display-name.ts
  • packages/app/src/i18n/zh.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/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.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/desktop-electron/src/renderer/i18n/zh.ts
  • packages/desktop-electron/src/main/app-display-name.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/desktop-electron/electron-builder.config.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/app/src/context/highlights.tsx
  • packages/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.ts
  • packages/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.ts
  • packages/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.ts
  • packages/desktop-electron/src/preload/index.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/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.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/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.ts
  • packages/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.strings generation 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.yml on publish keeps 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 LSHasLocalizedDisplayName enablement.

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 "爪印" for zh and "PawWork" for en.

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() into loadReleaseHighlights(...) ensures fetched release parsing matches the active app locale.

Also applies to: 208-208, 258-258

Comment thread packages/app/src/app.tsx
Comment thread packages/app/src/i18n/zh-branding.test.ts Outdated
Comment thread packages/desktop-electron/electron-builder-app-update.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (3)
packages/app/src/app.tsx (1)

181-184: ⚠️ Potential issue | 🟠 Major

Guard 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 | 🟠 Major

Do not enforce a full-dictionary PawWork ban. 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 | 🟡 Minor

Also assert zh_CN file content, not just existence.

The test verifies zh_CN path creation but still only validates localized string content for zh-Hans, leaving drift in zh_CN undetected.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 584b33b and 3be1c86.

📒 Files selected for processing (25)
  • packages/app/src/app.tsx
  • packages/app/src/context/highlights.test.ts
  • packages/app/src/context/highlights.tsx
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/app/src/i18n/zh.ts
  • packages/app/src/utils/desktop-context.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/desktop-electron/electron-builder.config.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/desktop-electron/src/main/app-display-name.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/menu-labels.test.ts
  • packages/desktop-electron/src/main/menu-labels.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/desktop-electron/src/main/menu.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.test.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.ts
  • packages/desktop-electron/src/preload/index.ts
  • packages/desktop-electron/src/renderer/i18n/zh.test.ts
  • packages/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.api from src/preload

Files:

  • packages/desktop-electron/src/main/menu-labels.test.ts
  • packages/desktop-electron/src/main/menu-labels.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.test.ts
  • packages/desktop-electron/src/main/menu.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/app-display-name.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.ts
  • packages/desktop-electron/src/preload/index.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/desktop-electron/src/renderer/i18n/zh.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/renderer/i18n/zh.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
packages/app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (packages/app/AGENTS.md)

Always prefer createStore over multiple createSignal calls in SolidJS

Files:

  • packages/app/src/utils/desktop-context.test.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/app/src/app.tsx
  • packages/app/src/context/highlights.tsx
  • packages/app/src/context/highlights.test.ts
  • packages/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.ts
  • packages/desktop-electron/src/main/menu-labels.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.test.ts
  • packages/desktop-electron/src/main/menu.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/app-display-name.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/app/src/utils/desktop-context.test.ts
  • packages/desktop-electron/src/renderer/i18n/zh.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/app/src/app.tsx
  • packages/desktop-electron/src/renderer/i18n/zh.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/app/src/context/highlights.tsx
  • packages/desktop-electron/electron-builder.config.ts
  • packages/app/src/context/highlights.test.ts
  • packages/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.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.test.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/app/src/utils/desktop-context.test.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/renderer/i18n/zh.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/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.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/app/src/utils/desktop-context.test.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/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.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/app-display-name.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.ts
  • packages/desktop-electron/src/renderer/i18n/zh.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/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.ts
  • packages/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.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/desktop-electron/src/renderer/i18n/zh.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/app/src/context/highlights.tsx
  • packages/desktop-electron/electron-builder.config.ts
  • packages/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.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/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.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • 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 : 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.ts
  • 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 : 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.ts
  • packages/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.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/app/src/app.tsx
  • packages/app/src/context/highlights.tsx
  • packages/app/src/context/highlights.test.ts
  • packages/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.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/app/src/app.tsx
  • packages/app/src/context/highlights.tsx
  • packages/app/src/context/highlights.test.ts
  • packages/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.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/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.ts
  • packages/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.ts
  • packages/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 highlights payloads untouched.

Also applies to: 115-146


198-202: Nice backward-compatible API evolution.

Defaulting locale to "en" while threading language.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.ts line 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.ts line 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.ts confirms 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.ts line 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.ts line 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.ts line 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 title field in DesktopContext is 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.ts lines 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.ts lines 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 syncWindowTitleForDesktopContext at 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 into buildDesktopContext() 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 syncWindowTitleForDesktopContext keeps window title updates explicit.

Comment thread packages/app/src/context/highlights.tsx
Comment thread packages/app/src/i18n/zh.ts
Comment thread packages/desktop-electron/electron-builder.config.ts
@Astro-Han Astro-Han force-pushed the codex/fix-i196-chinese-brand branch from 3be1c86 to 4fc46e7 Compare April 24, 2026 16:57

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (2)
packages/app/src/context/highlights.tsx (1)

85-89: ⚠️ Potential issue | 🟠 Major

Relax 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 | 🟠 Major

First-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 required PawWork 爪印 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3be1c86 and 4fc46e7.

📒 Files selected for processing (28)
  • packages/app/package.json
  • packages/app/src/app.tsx
  • packages/app/src/context/highlights.test.ts
  • packages/app/src/context/highlights.tsx
  • packages/app/src/desktop-api.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/app/src/i18n/zh.ts
  • packages/app/src/utils/desktop-context.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/desktop-electron/electron-builder.config.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/desktop-electron/src/main/app-display-name.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/menu-labels.test.ts
  • packages/desktop-electron/src/main/menu-labels.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/desktop-electron/src/main/menu.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.test.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.ts
  • packages/desktop-electron/src/preload/index.ts
  • packages/desktop-electron/src/preload/types.ts
  • packages/desktop-electron/src/renderer/i18n/zh.test.ts
  • packages/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 createStore over multiple createSignal calls in SolidJS

Files:

  • packages/app/src/utils/desktop-context.test.ts
  • packages/app/src/desktop-api.ts
  • packages/app/src/app.tsx
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/app/src/context/highlights.tsx
  • packages/app/src/context/highlights.test.ts
  • packages/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.api from src/preload

Files:

  • packages/desktop-electron/src/renderer/i18n/zh.test.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/menu-labels.test.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/desktop-electron/src/main/menu.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/app-display-name.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.ts
  • packages/desktop-electron/src/preload/index.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/desktop-electron/src/renderer/i18n/zh.ts
  • packages/desktop-electron/src/preload/types.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.test.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/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.ts
  • packages/desktop-electron/src/renderer/i18n/zh.test.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/menu-labels.test.ts
  • packages/app/src/desktop-api.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/desktop-electron/src/main/menu.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/app/src/app.tsx
  • packages/desktop-electron/src/main/app-display-name.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/desktop-electron/src/renderer/i18n/zh.ts
  • packages/desktop-electron/src/preload/types.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.test.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/desktop-electron/src/main/menu-labels.ts
  • packages/app/src/context/highlights.tsx
  • packages/app/src/context/highlights.test.ts
  • packages/app/src/i18n/zh.ts
  • packages/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.ts
  • packages/desktop-electron/src/renderer/i18n/zh.test.ts
  • packages/desktop-electron/src/main/app-display-name.test.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/menu-labels.test.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.test.ts
  • packages/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.ts
  • 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/app/src/utils/desktop-context.test.ts
  • packages/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.ts
  • packages/app/src/desktop-api.ts
  • packages/app/src/app.tsx
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/app/src/context/highlights.tsx
  • packages/app/src/context/highlights.test.ts
  • packages/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.ts
  • packages/app/src/desktop-api.ts
  • packages/app/src/app.tsx
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/app/src/context/highlights.tsx
  • packages/app/src/context/highlights.test.ts
  • packages/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.ts
  • packages/desktop-electron/src/main/feedback.test.ts
  • packages/desktop-electron/src/main/menu-labels.test.ts
  • packages/desktop-electron/src/main/menu.test.ts
  • packages/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.ts
  • packages/desktop-electron/src/main/app-display-name.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/app/src/utils/desktop-context.ts
  • packages/desktop-electron/src/renderer/i18n/zh.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/desktop-electron/src/main/index.ts
  • packages/app/src/context/highlights.tsx
  • packages/app/src/context/highlights.test.ts
  • packages/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.ts
  • packages/app/package.json
  • packages/desktop-electron/src/preload/index.ts
  • packages/desktop-electron/src/preload/types.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/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.ts
  • packages/desktop-electron/src/main/feedback.ts
  • packages/desktop-electron/src/main/updater-dialog-labels.ts
  • packages/app/src/i18n/zh-branding.test.ts
  • packages/desktop-electron/src/renderer/i18n/zh.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/desktop-electron/src/main/menu-labels.ts
  • packages/app/src/i18n/zh.ts
  • packages/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.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/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.ts
  • packages/desktop-electron/electron-builder-app-update.test.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/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.ts
  • packages/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.ts
  • packages/desktop-electron/src/main/desktop-context-window.test.ts
  • packages/desktop-electron/src/preload/types.ts
  • packages/desktop-electron/src/main/desktop-context-window.ts
  • packages/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.ts
  • packages/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.ts
  • packages/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.ts
  • packages/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 LSHasLocalizedDisplayName and 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: localizedAppDisplayName implementation 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 into buildDesktopContext is 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 title assertions 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 buildDesktopContext here 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-api entrypoint 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

Comment thread packages/app/src/i18n/zh-branding.test.ts
Comment thread packages/desktop-electron/src/main/app-display-name.test.ts
@Astro-Han Astro-Han merged commit 0f4125d into dev Apr 24, 2026
22 of 23 checks passed
@Astro-Han Astro-Han deleted the codex/fix-i196-chinese-brand branch April 24, 2026 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Introduce 爪印 Chinese brand name into zh.ts UI surfaces

1 participant