fix: harden updater stale pending handling#178
Conversation
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 1 minutes and 1 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (14)
📝 WalkthroughWalkthroughRenderer stop calling restart during install; update failures gain a "cache" reason; a platform-aware updater cache and clearPendingUpdate API were added; updater uses semver to detect/clear stale pending updates, disallows downgrades, and conditions auto-install-on-quit by platform. Changes
Sequence Diagram(s)sequenceDiagram
participant Renderer as Renderer
participant Updater as Updater Controller
participant Semver as Semver
participant Cache as Pending Cache
participant FS as File System
Renderer->>Updater: request install/update
Updater->>Updater: check for ready update
alt ready update found
Updater->>Semver: compare readyVersion vs currentVersion
Semver-->>Updater: result (newer / not newer)
alt not newer (stale)
Updater->>Cache: pendingUpdateCacheDir()
Updater->>FS: rm(pendingUpdateCacheDir(), {recursive:true, force:true})
alt rm fails
FS-->>Updater: error
Updater-->>Renderer: return {status:"failed", reason:"cache"}
else rm succeeds
FS-->>Updater: success
Updater->>Updater: re-check updates
end
else newer
Updater-->>Renderer: proceed with install (renderer does not call restart)
end
else no ready update
Updater-->>Renderer: no-op / continue polling
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Code Review
This pull request refactors the application update process by removing the explicit restart requirement from the renderer and centralizing updater cache management. Key changes include the introduction of a cross-platform cache path utility, semver-based version validation to prevent downgrades, and logic to clear stale updates in the main process. Review feedback recommends using regular expressions in source-code inspection tests to improve robustness against formatting changes and suggests handling case-insensitive environment variables on Windows for more reliable path resolution.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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/desktop-electron/scripts/write-app-update-config.test.ts`:
- Around line 36-45: Replace the hardcoded macOS assertion string with the
shared constant so tests don't drift: in the test suite that calls
serializeAppUpdateConfig (the test "serializes updater cache dir from the shared
constant" and the macOS path assertion), replace the literal
"updaterCacheDirName: pawwork-updater" with a template using
UPDATER_CACHE_DIR_NAME (the same constant used earlier) so the macOS write-path
assertion references UPDATER_CACHE_DIR_NAME instead of a hardcoded value.
In `@packages/desktop-electron/src/main/updater-cache.test.ts`:
- Around line 16-30: The tests currently only cover branches where env vars
exist; add explicit tests for pendingUpdateCacheDir to assert the fallback
behavior when those env vars are missing: for platform "win32" call
pendingUpdateCacheDir with env: {} and homedir "C:\\Users\\demo" and assert it
returns "C:\\Users\\demo\\AppData\\Local\\pawwork-updater\\pending" (or the
intended fallback path used in the implementation), and for platform "linux"
call pendingUpdateCacheDir with env: {} and homedir "/home/demo" and assert it
returns "/home/demo/.cache/pawwork-updater/pending" (matching the function's
fallback). Reference the pendingUpdateCacheDir function in tests so both
env-present and env-absent branches are covered.
In `@packages/desktop-electron/src/main/updater.ts`:
- Around line 91-95: The branch that returns {status: "none"} after calling
newerThanCurrent(info.version, currentVersion) must clear any stale pending
cache and trigger one re-check; call clearPendingUpdate() before returning in
the case where comparison is false (version <= currentVersion), then set a
one-shot guard (e.g., a local boolean like haveClearedPendingOnce) so you re-run
the update check exactly once after cleanup to fetch fresh metadata and avoid
repeated reuse of a stale pending package; ensure you reference newerThanCurrent
and clearPendingUpdate() when locating where to insert the cleanup and the
guarded re-check.
🪄 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: 714940fb-1d77-46b0-abd3-cd6569ac41f5
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (14)
packages/app/src/components/settings-general.tsxpackages/app/src/context/platform.tsxpackages/app/src/pages/error.tsxpackages/app/src/pages/layout.tsxpackages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/package.jsonpackages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/scripts/write-app-update-config.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/updater-cache.tspackages/desktop-electron/src/main/updater.test.tspackages/desktop-electron/src/main/updater.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-opencode-session
- GitHub Check: unit-windows-desktop
- GitHub Check: unit-windows-opencode-config-project
- GitHub Check: unit-windows-app
- GitHub Check: unit-windows-opencode-server-tools
- GitHub Check: unit-desktop
- GitHub Check: unit-opencode
- GitHub Check: unit-app
- GitHub Check: e2e-artifacts
- GitHub Check: analyze-js-ts
🧰 Additional context used
📓 Path-based instructions (2)
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/app/AGENTS.md)
Always prefer
createStoreover multiplecreateSignalcalls in SolidJS
Files:
packages/app/src/components/settings-general.tsxpackages/app/src/pages/layout.tsxpackages/app/src/pages/error.tsxpackages/app/src/pages/update-install-flow-source.test.tspackages/app/src/context/platform.tsx
packages/desktop-electron/src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/desktop-electron/AGENTS.md)
Renderer process should only call
window.apifromsrc/preload
Files:
packages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/updater-cache.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/updater.test.tspackages/desktop-electron/src/main/updater.ts
🧠 Learnings (20)
📚 Learning: 2026-04-22T08:49:44.563Z
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:44.563Z
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/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/updater.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/packages/app/src/testing/**/*.ts : Test-only hooks must be inert unless explicitly enabled and should not add normal-runtime listeners, reactive subscriptions, or per-update allocations
Applied to files:
packages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/index-updater-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Define `const it = testEffect(...)` near the top of the test file and keep the test body inside `Effect.gen(function* () { ... })`. Yield services directly with `yield* MyService.Service` or `yield* MyTool`.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/index-updater-source.test.ts
📚 Learning: 2026-04-22T09:32:52.806Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/opencode/test/provider/provider.test.ts:64-85
Timestamp: 2026-04-22T09:32:52.806Z
Learning: In `packages/opencode/test/provider/provider.test.ts`, the file intentionally uses AppRuntime-based async helpers (`run`, `list`, `getProvider`, etc.) rather than `testEffect(...)` for all tests. Converting individual tests to `testEffect` while leaving the rest on the async pattern would create internal inconsistency. A full harness migration of this file is the right approach if the pattern needs to change, but that should be a separate PR.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `testEffect(...)` from `test/lib/effect.ts` for tests that exercise Effect services or Effect-based workflows.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Avoid custom `ManagedRuntime`, `attach(...)`, or ad hoc `run(...)` wrappers in Effect tests when `testEffect(...)` already provides the runtime.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test one feature per test file
Applied to files:
packages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/index-updater-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/pages/update-install-flow-source.test.tspackages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/updater.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Import test utilities from `../fixtures` instead of `playwright/test`
Applied to files:
packages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `it.effect(...)` when the test should run with `TestClock` and `TestConsole`. Use `it.live(...)` when the test depends on real time, filesystem mtimes, child processes, git, locks, or other live OS behavior.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:08.745Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.745Z
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/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:08.745Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.745Z
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/index-updater-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use SCREAMING_SNAKE_CASE for constants in tests
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use camelCase for variable names in tests
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When using the `tmpdir` function with git repository support, pass the `git: true` option to initialize a git repo with a root commit.
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
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/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When a test needs instance-local state, prefer `provideTmpdirInstance(...)` or `provideInstance(...)` over manual `Instance.provide(...)` inside Promise-style tests.
Applied to files:
packages/desktop-electron/src/main/updater-cache.test.ts
🔇 Additional comments (7)
packages/desktop-electron/package.json (1)
37-38: Semver dependency wiring is consistent and appropriate.Adding
semverat runtime with matching type support is a clean fit for updater version gating logic.Also applies to: 49-50
packages/desktop-electron/src/main/updater-cache.ts (1)
1-30: Cache path utility is well-structured and test-friendly.The platform-branching and environment fallbacks are clear, and the injectable inputs make this easy to validate in tests.
packages/app/src/pages/layout.tsx (1)
370-370: Update polling gate aligns with main-owned install flow.Requiring
checkUpdate+updateand removing renderer restart coupling is the right contract boundary.packages/app/src/components/settings-general.tsx (1)
151-170: Install action contract is correctly simplified.Using
platform.updateas the sole requirement here keeps renderer behavior consistent with main-owned installation/relaunch.packages/desktop-electron/scripts/write-app-update-config.ts (1)
4-5: Good deduplication of updater cache directory naming.Importing the shared constant avoids future config/runtime divergence.
packages/app/src/context/platform.tsx (1)
10-10: Platform update failure typing is correctly extended.Adding
"cache"keeps renderer type safety aligned with updater failure reporting.packages/app/src/pages/error.tsx (1)
267-267: Error-page install flow now correctly depends only onplatform.update.This keeps renderer-side behavior consistent with main-controlled update installation.
6c90c1a to
037e0c9
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/pages/update-install-flow-source.test.ts`:
- Around line 10-14: The test "renderer install actions do not relaunch after
platform update" currently ensures layout and settings don't contain "await
platform.restart!()" but only blocks the ".then(() => platform.restart!())" form
on errorPage; update the errorPage assertion to also reject async/await by
adding a similar regex check (e.g.,
expect(errorPage).not.toMatch(/await\s+platform\.restart!\(\)/)) so both await
and .then patterns for platform.restart!() are covered alongside existing checks
for layout and settings.
In `@packages/desktop-electron/src/main/updater-cache.ts`:
- Around line 16-25: getAppCacheDir may return environment cache paths verbatim
even when relative; change it to only use env.LOCALAPPDATA / env.localappdata
(on win32) and env.XDG_CACHE_HOME (on other platforms) if the value is an
absolute path (use path.isAbsolute) otherwise fall back to the platform default
path computed by pathForPlatform(current platform) joined with homedir; update
the win32 branch (function getAppCacheDir) to test absolute-ness before
returning env value and do the same for the XDG_CACHE_HOME branch so
pendingUpdateCacheDir() never becomes cwd-relative.
🪄 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: e2af0adc-fd55-4b17-8b15-896ff7709de9
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (14)
packages/app/src/components/settings-general.tsxpackages/app/src/context/platform.tsxpackages/app/src/pages/error.tsxpackages/app/src/pages/layout.tsxpackages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/package.jsonpackages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/scripts/write-app-update-config.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/updater-cache.tspackages/desktop-electron/src/main/updater.test.tspackages/desktop-electron/src/main/updater.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/app/AGENTS.md)
Always prefer
createStoreover multiplecreateSignalcalls in SolidJS
Files:
packages/app/src/components/settings-general.tsxpackages/app/src/pages/layout.tsxpackages/app/src/context/platform.tsxpackages/app/src/pages/error.tsxpackages/app/src/pages/update-install-flow-source.test.ts
packages/desktop-electron/src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/desktop-electron/AGENTS.md)
Renderer process should only call
window.apifromsrc/preload
Files:
packages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/updater-cache.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/src/main/updater.tspackages/desktop-electron/src/main/updater.test.ts
🧠 Learnings (30)
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/src/main/updater-cache.test.tspackages/desktop-electron/scripts/write-app-update-config.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/src/main/updater-cache.test.tspackages/desktop-electron/scripts/write-app-update-config.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/src/main/updater-cache.test.tspackages/desktop-electron/scripts/write-app-update-config.test.ts
📚 Learning: 2026-04-22T08:49:44.563Z
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:44.563Z
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/updater-cache.test.tspackages/desktop-electron/scripts/write-app-update-config.test.tspackages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/src/main/updater.tspackages/desktop-electron/src/main/updater.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When using the `tmpdir` function with git repository support, pass the `git: true` option to initialize a git repo with a root commit.
Applied to files:
packages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/scripts/write-app-update-config.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/updater-cache.test.tspackages/desktop-electron/scripts/write-app-update-config.test.tspackages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/src/main/updater.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
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/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/scripts/write-app-update-config.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When a test needs instance-local state, prefer `provideTmpdirInstance(...)` or `provideInstance(...)` over manual `Instance.provide(...)` inside Promise-style tests.
Applied to files:
packages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T17:03:37.710Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 73
File: packages/opencode/src/cli/cmd/tui/context/sync.tsx:486-489
Timestamp: 2026-04-20T17:03:37.710Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/cli/cmd/tui/context/sync.tsx`), `sync.ready` returning `true` when `process.env.OPENCODE_FAST_BOOT` is set is intentional. The plugin-facing data properties `state.config` (initialized to `{}`) and `state.provider` (initialized to `[]`) expose safe-empty defaults, so they are safe to access before bootstrap completes. Do not flag these as needing null-guards or conditional patterns to match `vcs` — the difference is intentional because `vcs` starts as `undefined` while the others have initialized defaults. Changing this would alter the plugin API contract without a concrete failing case.
Applied to files:
packages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater.ts
📚 Learning: 2026-04-21T13:45:41.773Z
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:41.773Z
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/updater-cache.test.tspackages/desktop-electron/src/main/updater-cache.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use SCREAMING_SNAKE_CASE for constants in tests
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.tspackages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-22T09:32:52.806Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/opencode/test/provider/provider.test.ts:64-85
Timestamp: 2026-04-22T09:32:52.806Z
Learning: In `packages/opencode/test/provider/provider.test.ts`, the file intentionally uses AppRuntime-based async helpers (`run`, `list`, `getProvider`, etc.) rather than `testEffect(...)` for all tests. Converting individual tests to `testEffect` while leaving the rest on the async pattern would create internal inconsistency. A full harness migration of this file is the right approach if the pattern needs to change, but that should be a separate PR.
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.tspackages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/src/main/updater.test.ts
📚 Learning: 2026-04-22T09:32:52.535Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/ui/src/theme/context.tsx:11-16
Timestamp: 2026-04-22T09:32:52.535Z
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/scripts/write-app-update-config.test.ts
📚 Learning: 2026-04-20T14:21:51.047Z
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:51.047Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater.ts
📚 Learning: 2026-04-21T16:57:22.813Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 102
File: packages/opencode/src/config/agent.ts:108-119
Timestamp: 2026-04-21T16:57:22.813Z
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/desktop-electron/scripts/write-app-update-config.test.ts
📚 Learning: 2026-04-22T05:24:42.404Z
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:24:42.404Z
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/scripts/write-app-update-config.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/packages/app/src/testing/**/*.ts : Test-only hooks must be inert unless explicitly enabled and should not add normal-runtime listeners, reactive subscriptions, or per-update allocations
Applied to files:
packages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/index-updater-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Define `const it = testEffect(...)` near the top of the test file and keep the test body inside `Effect.gen(function* () { ... })`. Yield services directly with `yield* MyService.Service` or `yield* MyTool`.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `testEffect(...)` from `test/lib/effect.ts` for tests that exercise Effect services or Effect-based workflows.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Avoid custom `ManagedRuntime`, `attach(...)`, or ad hoc `run(...)` wrappers in Effect tests when `testEffect(...)` already provides the runtime.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Import test utilities from `../fixtures` instead of `playwright/test`
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test one feature per test file
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
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/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use lowercase, descriptive test names (e.g., 'sidebar can be toggled')
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
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/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use `expect.poll(...)` for probing mock or backend state rather than transient DOM visibility
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use camelCase for variable names in tests
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Never use wall-clock waits like `page.waitForTimeout(...)` to make a test pass
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `it.effect(...)` when the test should run with `TestClock` and `TestConsole`. Use `it.live(...)` when the test depends on real time, filesystem mtimes, child processes, git, locks, or other live OS behavior.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:08.745Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.745Z
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/pages/update-install-flow-source.test.ts
🔇 Additional comments (6)
packages/app/src/context/platform.tsx (1)
10-14: Type contract update is coherent for cache-related updater failures.Adding
"cache"toUpdateFailureReasoncleanly extends the existingUpdateInfofailed branch without breaking the union shape.packages/app/src/components/settings-general.tsx (1)
151-158: Install action ownership is correctly narrowed toplatform.update.This aligns the renderer flow with main-process update/install ownership and removes renderer-side relaunch coupling.
packages/app/src/pages/layout.tsx (1)
368-371: Update polling gate now matches renderer install contract.Requiring only
platform.checkUpdate+platform.updateis correct after removing renderer-managed restart calls.packages/app/src/pages/error.tsx (1)
266-270:installUpdateis correctly decoupled from renderer restart capability.The guard at Line 267 now reflects the intended contract: install through
platform.updateonly.packages/desktop-electron/scripts/write-app-update-config.ts (1)
4-5: Good constant reuse to prevent config/runtime drift.Using
UPDATER_CACHE_DIR_NAMEfrom the shared source is the right move for consistency.packages/desktop-electron/scripts/write-app-update-config.test.ts (1)
30-45: Test updates correctly enforce shared updater-cache constant usage.These assertions close the remaining hardcoded-path drift risk and keep serialization checks aligned with runtime config.
Also applies to: 81-81
037e0c9 to
66ecfd6
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/pages/update-install-flow-source.test.ts`:
- Around line 10-15: The test only rejects the chained restart pattern for
errorPage but not for layout or settings sources; add assertions to also
disallow the `.then(() => platform.restart!())` pattern in layout and settings
by extending the test in update-install-flow-source.test.ts to include
expect(layout).not.toMatch(/\.then\(\(\)\s*=>\s*platform\.restart!\(\)\)/) and
expect(settings).not.toMatch(/\.then\(\(\)\s*=>\s*platform\.restart!\(\)\)/), so
any `platform.update().then(() => platform.restart!())` or similar chained forms
in layout.tsx or settings-general.tsx will fail the test.
In `@packages/desktop-electron/src/main/index-updater-source.test.ts`:
- Around line 20-24: The test is too broad by banning ".catch(() =>" anywhere in
the file; narrow it to the specific cleanup call. Replace the global assertion
on source with one that targets the exact call site (e.g., assert source does
not contain the substring "rm(pendingUpdateCacheDir(), { recursive: true, force:
true }).catch(() =>" or use a regex/contains check that looks for ".catch("
immediately following the call to rm(pendingUpdateCacheDir(), { recursive: true,
force: true }) ). Keep the other assertions referencing pendingUpdateCacheDir
and rm as-is.
🪄 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: 3bfeacef-c9a2-4b5e-8cf6-c76a05af9fbf
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (14)
packages/app/src/components/settings-general.tsxpackages/app/src/context/platform.tsxpackages/app/src/pages/error.tsxpackages/app/src/pages/layout.tsxpackages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/package.jsonpackages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/scripts/write-app-update-config.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/updater-cache.tspackages/desktop-electron/src/main/updater.test.tspackages/desktop-electron/src/main/updater.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). (1)
- GitHub Check: e2e-artifacts
🧰 Additional context used
📓 Path-based instructions (2)
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/app/AGENTS.md)
Always prefer
createStoreover multiplecreateSignalcalls in SolidJS
Files:
packages/app/src/components/settings-general.tsxpackages/app/src/pages/layout.tsxpackages/app/src/context/platform.tsxpackages/app/src/pages/error.tsxpackages/app/src/pages/update-install-flow-source.test.ts
packages/desktop-electron/src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/desktop-electron/AGENTS.md)
Renderer process should only call
window.apifromsrc/preload
Files:
packages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/updater-cache.tspackages/desktop-electron/src/main/updater.test.tspackages/desktop-electron/src/main/updater.ts
🧠 Learnings (32)
📚 Learning: 2026-04-22T08:49:44.563Z
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:44.563Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/updater-cache.tspackages/desktop-electron/src/main/updater.test.tspackages/desktop-electron/src/main/updater.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use SCREAMING_SNAKE_CASE for constants in tests
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.tspackages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Import test utilities from `../fixtures` instead of `playwright/test`
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use camelCase for variable names in tests
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.tspackages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/updater.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/index-updater-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When a test needs instance-local state, prefer `provideTmpdirInstance(...)` or `provideInstance(...)` over manual `Instance.provide(...)` inside Promise-style tests.
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-22T09:32:52.806Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/opencode/test/provider/provider.test.ts:64-85
Timestamp: 2026-04-22T09:32:52.806Z
Learning: In `packages/opencode/test/provider/provider.test.ts`, the file intentionally uses AppRuntime-based async helpers (`run`, `list`, `getProvider`, etc.) rather than `testEffect(...)` for all tests. Converting individual tests to `testEffect` while leaving the rest on the async pattern would create internal inconsistency. A full harness migration of this file is the right approach if the pattern needs to change, but that should be a separate PR.
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/updater.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
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/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-22T09:32:52.535Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/ui/src/theme/context.tsx:11-16
Timestamp: 2026-04-22T09:32:52.535Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.ts
📚 Learning: 2026-04-20T14:21:51.047Z
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:51.047Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.tspackages/desktop-electron/src/main/updater.ts
📚 Learning: 2026-04-20T17:03:37.710Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 73
File: packages/opencode/src/cli/cmd/tui/context/sync.tsx:486-489
Timestamp: 2026-04-20T17:03:37.710Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/cli/cmd/tui/context/sync.tsx`), `sync.ready` returning `true` when `process.env.OPENCODE_FAST_BOOT` is set is intentional. The plugin-facing data properties `state.config` (initialized to `{}`) and `state.provider` (initialized to `[]`) expose safe-empty defaults, so they are safe to access before bootstrap completes. Do not flag these as needing null-guards or conditional patterns to match `vcs` — the difference is intentional because `vcs` starts as `undefined` while the others have initialized defaults. Changing this would alter the plugin API contract without a concrete failing case.
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/updater-cache.tspackages/desktop-electron/src/main/updater.ts
📚 Learning: 2026-04-21T16:57:22.813Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 102
File: packages/opencode/src/config/agent.ts:108-119
Timestamp: 2026-04-21T16:57:22.813Z
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/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.ts
📚 Learning: 2026-04-22T05:24:42.404Z
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:24:42.404Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When using the `tmpdir` function with git repository support, pass the `git: true` option to initialize a git repo with a root commit.
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-21T13:45:41.773Z
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:41.773Z
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/updater-cache.test.tspackages/desktop-electron/src/main/updater-cache.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/packages/app/src/testing/**/*.ts : Test-only hooks must be inert unless explicitly enabled and should not add normal-runtime listeners, reactive subscriptions, or per-update allocations
Applied to files:
packages/desktop-electron/src/main/index-updater-source.test.tspackages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test one feature per test file
Applied to files:
packages/desktop-electron/src/main/index-updater-source.test.tspackages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Define `const it = testEffect(...)` near the top of the test file and keep the test body inside `Effect.gen(function* () { ... })`. Yield services directly with `yield* MyService.Service` or `yield* MyTool`.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Avoid custom `ManagedRuntime`, `attach(...)`, or ad hoc `run(...)` wrappers in Effect tests when `testEffect(...)` already provides the runtime.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `testEffect(...)` from `test/lib/effect.ts` for tests that exercise Effect services or Effect-based workflows.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
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/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use lowercase, descriptive test names (e.g., 'sidebar can be toggled')
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
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/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use `expect.poll(...)` for probing mock or backend state rather than transient DOM visibility
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Never use wall-clock waits like `page.waitForTimeout(...)` to make a test pass
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-21T12:14:29.062Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 93
File: packages/opencode/test/server/cors-middleware.test.ts:15-23
Timestamp: 2026-04-21T12:14:29.062Z
Learning: In `packages/opencode/test/server/cors-middleware.test.ts` (and similar Hono-based test files), `app.request(...)` on the Hono `Hono` app type returns `Promise<Response> | Response` — a union that includes a non-PromiseLike branch. `Effect.promise(...)` requires a `PromiseLike`, so wrapping with `Promise.resolve(app.request(...))` is necessary to normalize the union type. Removing the wrapper causes a TS2322 typecheck error in `packages/opencode`.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `it.effect(...)` when the test should run with `TestClock` and `TestConsole`. Use `it.live(...)` when the test depends on real time, filesystem mtimes, child processes, git, locks, or other live OS behavior.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:08.745Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.745Z
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/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Use `InstanceState` from `src/effect/instance-state.ts` for per-directory or per-project state that needs per-instance cleanup; do work directly in the `InstanceState.make` closure where `ScopedCache` handles run-once semantics
Applied to files:
packages/desktop-electron/src/main/updater-cache.ts
🔇 Additional comments (9)
packages/app/src/context/platform.tsx (1)
10-10:UpdateFailureReasoncorrectly includes"cache".This keeps renderer-facing update failure typing aligned with the new updater cache-cleanup failure path.
packages/desktop-electron/package.json (1)
37-39: Dependency additions are consistent with updater changes.
semverruntime + typings support the new version-gating logic cleanly.Also applies to: 49-50
packages/desktop-electron/scripts/write-app-update-config.ts (1)
4-5: Good shared-constant migration for updater cache dir.Using
UPDATER_CACHE_DIR_NAMEhere prevents config drift with main updater logic.Also applies to: 19-19
packages/app/src/pages/layout.tsx (1)
370-370: Renderer install action is correctly narrowed toplatform.update.This keeps install/restart ownership in the desktop main flow and avoids renderer-driven relaunch behavior.
Also applies to: 386-389
packages/app/src/components/settings-general.tsx (1)
151-170: Update toast action flow is correctly simplified.Conditioning on
platform.updateand calling onlyplatform.update()is consistent with the hardened install flow.packages/app/src/pages/error.tsx (1)
267-270:installUpdatenow correctly delegates to platform update only.This matches the renderer/main separation applied across the rest of the update flow.
packages/desktop-electron/scripts/write-app-update-config.test.ts (1)
6-7: Test updates look good and close the hardcoded-literal gap.The suite now consistently validates
updaterCacheDirNameviaUPDATER_CACHE_DIR_NAME.Also applies to: 30-31, 36-45, 81-81
packages/desktop-electron/src/main/index.ts (2)
65-66: Pending update cache cleanup integration is solid.Wiring
clearPendingUpdatetoawait rm(pendingUpdateCacheDir(), { recursive: true, force: true })is a clean and strict implementation.Also applies to: 111-111, 550-552
559-567: Auto-updater hardening settings look correct.Disabling downgrades and using platform-aware
autoInstallOnAppQuitaddresses stale downgrade risk and platform behavior more safely.
66ecfd6 to
1c38ca7
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/desktop-electron/scripts/write-app-update-config.test.ts`:
- Around line 79-81: Read the file once into a variable and reuse it in both
assertions instead of calling readFileSync twice: create a local const (e.g.,
configContents) by calling readFileSync(configPath, "utf8") and then call
expect(configContents).toContain("repo: pawwork") and
expect(configContents).toContain(`updaterCacheDirName:
${UPDATER_CACHE_DIR_NAME}`); update the test that defines configPath to use this
cached value.
🪄 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: 5e2e78a3-8814-4b8e-b11c-37e5fa7fc455
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (14)
packages/app/src/components/settings-general.tsxpackages/app/src/context/platform.tsxpackages/app/src/pages/error.tsxpackages/app/src/pages/layout.tsxpackages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/package.jsonpackages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/scripts/write-app-update-config.tspackages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/updater-cache.tspackages/desktop-electron/src/main/updater.test.tspackages/desktop-electron/src/main/updater.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). (9)
- GitHub Check: smoke-macos-arm64
- GitHub Check: unit-windows-app
- GitHub Check: unit-windows-opencode-session
- GitHub Check: unit-windows-opencode-server-tools
- GitHub Check: unit-windows-desktop
- GitHub Check: unit-windows-opencode-config-project
- GitHub Check: unit-desktop
- GitHub Check: analyze-js-ts
- GitHub Check: e2e-artifacts
🧰 Additional context used
📓 Path-based instructions (2)
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/app/AGENTS.md)
Always prefer
createStoreover multiplecreateSignalcalls in SolidJS
Files:
packages/app/src/components/settings-general.tsxpackages/app/src/context/platform.tsxpackages/app/src/pages/error.tsxpackages/app/src/pages/layout.tsxpackages/app/src/pages/update-install-flow-source.test.ts
packages/desktop-electron/src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (packages/desktop-electron/AGENTS.md)
Renderer process should only call
window.apifromsrc/preload
Files:
packages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/src/main/index.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/updater.test.tspackages/desktop-electron/src/main/updater.tspackages/desktop-electron/src/main/updater-cache.ts
🧠 Learnings (32)
📚 Learning: 2026-04-22T08:49:44.563Z
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:44.563Z
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/index-updater-source.test.tspackages/desktop-electron/scripts/write-app-update-config.test.tspackages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/updater.test.tspackages/desktop-electron/src/main/updater.tspackages/desktop-electron/src/main/updater-cache.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/packages/app/src/testing/**/*.ts : Test-only hooks must be inert unless explicitly enabled and should not add normal-runtime listeners, reactive subscriptions, or per-update allocations
Applied to files:
packages/desktop-electron/src/main/index-updater-source.test.tspackages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-22T09:32:52.806Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/opencode/test/provider/provider.test.ts:64-85
Timestamp: 2026-04-22T09:32:52.806Z
Learning: In `packages/opencode/test/provider/provider.test.ts`, the file intentionally uses AppRuntime-based async helpers (`run`, `list`, `getProvider`, etc.) rather than `testEffect(...)` for all tests. Converting individual tests to `testEffect` while leaving the rest on the async pattern would create internal inconsistency. A full harness migration of this file is the right approach if the pattern needs to change, but that should be a separate PR.
Applied to files:
packages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/scripts/write-app-update-config.test.tspackages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/updater.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
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/index-updater-source.test.tspackages/desktop-electron/scripts/write-app-update-config.test.tspackages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/src/main/index-updater-source.test.tspackages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/index-updater-source.test.tspackages/desktop-electron/scripts/write-app-update-config.test.tspackages/app/src/pages/update-install-flow-source.test.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/updater.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Avoid custom `ManagedRuntime`, `attach(...)`, or ad hoc `run(...)` wrappers in Effect tests when `testEffect(...)` already provides the runtime.
Applied to files:
packages/desktop-electron/src/main/index-updater-source.test.tspackages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When a test needs instance-local state, prefer `provideTmpdirInstance(...)` or `provideInstance(...)` over manual `Instance.provide(...)` inside Promise-style tests.
Applied to files:
packages/desktop-electron/src/main/index-updater-source.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
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/desktop-electron/src/main/index-updater-source.test.tspackages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `it.effect(...)` when the test should run with `TestClock` and `TestConsole`. Use `it.live(...)` when the test depends on real time, filesystem mtimes, child processes, git, locks, or other live OS behavior.
Applied to files:
packages/desktop-electron/src/main/index-updater-source.test.tspackages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Define `const it = testEffect(...)` near the top of the test file and keep the test body inside `Effect.gen(function* () { ... })`. Yield services directly with `yield* MyService.Service` or `yield* MyTool`.
Applied to files:
packages/desktop-electron/src/main/index-updater-source.test.tspackages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use SCREAMING_SNAKE_CASE for constants in tests
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.tspackages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use camelCase for variable names in tests
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.tspackages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
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/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-22T09:32:52.535Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/ui/src/theme/context.tsx:11-16
Timestamp: 2026-04-22T09:32:52.535Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.ts
📚 Learning: 2026-04-20T14:21:51.047Z
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:51.047Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater.tspackages/desktop-electron/src/main/updater-cache.ts
📚 Learning: 2026-04-20T17:03:37.710Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 73
File: packages/opencode/src/cli/cmd/tui/context/sync.tsx:486-489
Timestamp: 2026-04-20T17:03:37.710Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/cli/cmd/tui/context/sync.tsx`), `sync.ready` returning `true` when `process.env.OPENCODE_FAST_BOOT` is set is intentional. The plugin-facing data properties `state.config` (initialized to `{}`) and `state.provider` (initialized to `[]`) expose safe-empty defaults, so they are safe to access before bootstrap completes. Do not flag these as needing null-guards or conditional patterns to match `vcs` — the difference is intentional because `vcs` starts as `undefined` while the others have initialized defaults. Changing this would alter the plugin API contract without a concrete failing case.
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.tspackages/desktop-electron/src/main/updater.tspackages/desktop-electron/src/main/updater-cache.ts
📚 Learning: 2026-04-21T16:57:22.813Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 102
File: packages/opencode/src/config/agent.ts:108-119
Timestamp: 2026-04-21T16:57:22.813Z
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/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.ts
📚 Learning: 2026-04-22T05:24:42.404Z
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:24:42.404Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
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/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When using the `tmpdir` function with git repository support, pass the `git: true` option to initialize a git repo with a root commit.
Applied to files:
packages/desktop-electron/scripts/write-app-update-config.test.tspackages/desktop-electron/src/main/updater-cache.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `testEffect(...)` from `test/lib/effect.ts` for tests that exercise Effect services or Effect-based workflows.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test one feature per test file
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
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/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use lowercase, descriptive test names (e.g., 'sidebar can be toggled')
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use `expect.poll(...)` for probing mock or backend state rather than transient DOM visibility
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Never use wall-clock waits like `page.waitForTimeout(...)` to make a test pass
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-21T12:14:29.062Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 93
File: packages/opencode/test/server/cors-middleware.test.ts:15-23
Timestamp: 2026-04-21T12:14:29.062Z
Learning: In `packages/opencode/test/server/cors-middleware.test.ts` (and similar Hono-based test files), `app.request(...)` on the Hono `Hono` app type returns `Promise<Response> | Response` — a union that includes a non-PromiseLike branch. `Effect.promise(...)` requires a `PromiseLike`, so wrapping with `Promise.resolve(app.request(...))` is necessary to normalize the union type. Removing the wrapper causes a TS2322 typecheck error in `packages/opencode`.
Applied to files:
packages/app/src/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-20T14:36:08.745Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/desktop-electron/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:08.745Z
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/pages/update-install-flow-source.test.ts
📚 Learning: 2026-04-21T13:45:41.773Z
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:41.773Z
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/updater-cache.test.tspackages/desktop-electron/src/main/updater-cache.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Use `InstanceState` from `src/effect/instance-state.ts` for per-directory or per-project state that needs per-instance cleanup; do work directly in the `InstanceState.make` closure where `ScopedCache` handles run-once semantics
Applied to files:
packages/desktop-electron/src/main/updater-cache.ts
🔇 Additional comments (18)
packages/desktop-electron/src/main/updater-cache.ts (1)
16-44: Good hardening of updater cache path resolution.The absolute-path gate plus platform fallback logic is solid and directly prevents cwd-relative cache resolution issues.
packages/desktop-electron/src/main/updater-cache.test.ts (1)
16-78: Coverage for cache-root edge cases is strong.These tests correctly lock in fallback and relative-path rejection behavior across platforms.
packages/desktop-electron/scripts/write-app-update-config.ts (1)
4-20: Nice constant unification for updater cache config.Using
UPDATER_CACHE_DIR_NAMEhere eliminates cross-file string drift risk.packages/desktop-electron/scripts/write-app-update-config.test.ts (1)
6-45: Shared-constant migration in tests looks correct.The updated assertions now stay in sync with runtime config generation.
packages/app/src/pages/layout.tsx (1)
370-389: Renderer install flow ownership change looks correct.Gating on
checkUpdate+updateand removing direct restart from this action matches the intended main-process install control.packages/app/src/components/settings-general.tsx (1)
151-170: Update action wiring is consistent with the new install model.Switching this action set to rely on
platform.updateonly is a clean alignment with main-owned restart/install behavior.packages/desktop-electron/package.json (1)
37-50: Dependency additions are justified and scoped correctly.
semverand its types map directly to updater version-gating usage.packages/app/src/context/platform.tsx (1)
10-14: Type union update is correct and necessary.Adding
"cache"keeps renderer-facing update failure typing aligned with desktop updater failure modes.packages/app/src/pages/error.tsx (1)
267-270: Renderer install flow is correctly decoupled from restart calls.This guard now depends only on
platform.update, which keeps renderer-side install behavior aligned with main-owned relaunch/install handling.packages/desktop-electron/src/main/index.ts (2)
111-118: Pending-cache cleanup wiring is solid.
clearPendingUpdateis correctly injected into the updater controller, and cleanup is implemented as a strict awaited recursive delete without swallowing errors.Also applies to: 550-552
559-567: Updater policy hardening looks correct.Disabling downgrades and making
autoInstallOnAppQuitplatform-aware (!== "darwin") is consistent with the stale-pending/downgrade mitigation goals.packages/desktop-electron/src/main/index-updater-source.test.ts (1)
7-13: Source-level updater contracts are well covered.These checks correctly lock in downgrade prevention, macOS-specific auto-install behavior, and strict pending-cache cleanup semantics.
Also applies to: 15-18, 20-25
packages/app/src/pages/update-install-flow-source.test.ts (1)
10-17: Renderer update-install contract tests look complete.The assertions capture the key guarantees: no renderer restart chaining, update gating on update capability, and renderer awareness of
"cache"failure reasons.Also applies to: 19-24, 26-28
packages/desktop-electron/src/main/updater.ts (3)
32-37: Semver gating for both ready and install paths is correctly enforced.Using the same comparison helper across check and install paths closes stale/downgrade install gaps.
Also applies to: 48-55, 94-99, 133-138
56-64: Stale pending cache handling is robust and fail-closed.Clearing stale cache, returning
"cache"on cleanup failures, and performing a one-shot recheck provide the right recovery behavior without infinite retry loops.Also applies to: 65-108
10-11: Failure classification expansion is coherent.Adding
"cache"and mapping invalid-version paths to metadata failures keeps update error reporting explicit and actionable.Also applies to: 22-23, 75-77, 102-105
packages/desktop-electron/src/main/updater.test.ts (2)
5-24: Test harness updates are effective for version-sensitive flows.The mutable
currentVersionandclearPendingUpdatecounters make the new stale-cache and semver paths testable with good precision.Also applies to: 36-38
156-169: Regression coverage for stale pending/downgrade scenarios is strong.These additions give good confidence that stale metadata cleanup, cache-failure behavior, semver ordering, and invalid-version mapping remain protected.
Also applies to: 171-209, 211-257, 259-319
1c38ca7 to
8de55ee
Compare
8de55ee to
eab922e
Compare
Summary
quitAndInstall().semverdependency for updater version comparisons.Why
Fixes #175. A stable build could keep a pending package for an older version and keep offering it after the running app had already advanced.
Related Issue
Fixes #175
How To Verify
Screenshots or Recordings
Not applicable. This changes updater control flow and source contracts, not visible UI.
Checklist
dev, and my PR title and commit messages use Conventional Commits in EnglishSummary by CodeRabbit
Bug Fixes
New Features
Tests
Chores