Add ConfigFieldPrimitives component for reusable config field logic.
Implement config field components for Gemini, Qwen, and Kimi CLI tools with support for advanced settings via configBlob.
Update injectCliConfig to apply managed settings to tool config files (JSON for Gemini/Qwen, TOML for Kimi).
Improve OpenCode endpoint resolution to handle mixed providers and model-specific endpoint types.
Add i18n translations for all three tools (en-us, zh-cn, zh-tw).
Update kimi-code npm package name to @moonshot-ai/kimi-code.
Add comprehensive tests for Gemini, Qwen, and Kimi config injection.
Adds IPC schemas/handlers for Code CLI actions, moves launch flow to the new request API, and extends support to Gemini CLI, Qwen Code, Kimi Code, Qoder CLI, and GitHub Copilot CLI. Also updates native config injection/cleanup, provider ordering, and the code tools UI to support providerless launches and the new tool metadata.
The resources/database/drizzle SQL files and meta snapshots are v1-era CherryClaw agents-db migrations with no runtime consumer — the active v2 migrations live in migrations/sqlite-drizzle and are loaded from app.database.migrations. Delete the directory and clean up the now-dangling references: three source comments in AgentsDbMappings.ts that cited the deleted SQL files as the v1 column-type source (the epoch-ms notes are kept inline), and a stale doc row in cherryclaw/scheduler.md pointing to a migration file that no longer exists.
Adds OpenCode config controls and moves CLI injection logic into the code page area. Claude and Codex editors now expose additional advanced options, and the injection flow now persists the new Claude, Codex, and OpenCode settings into the generated CLI configs.
The setter updater contract previously said "must be pure" only in the sense of "don't mutate prev / return a new value" (the isEqual short-circuit footgun); it did not cover side effects inside the updater.
Document that updaters must also be side-effect-free: don't smuggle a derived value out (e.g. into an enclosing-scope variable) to drive post-write work, and don't rely on how often or when the updater runs. To react to what changed, derive it from the value transition in a useEffect that watches the value.
Deliberately does not promise single synchronous invocation, to keep the setter free to batch/retry/defer later. Updates the CacheSetStateAction type doc, the useCache @remarks (canonical reference for all three hooks), and cache-usage.md.
Store the working directory on each CLI tool instead of per provider, and update the page, hook, and tests to use the shared tool directory. Also simplify the config editor to only show supported tools, refresh endpoint labeling, hide Cherry AI providers from metadata, and normalize Cherry provider keys to the lowercase prefix used by the generated config files.
Now that the renderer cache hooks resolve functional updaters against the latest stored value, replace the hand-rolled ref + `typeof === 'function'` wrappers (TabsProvider, TranslatePage, GlobalSearchPanel) and the snapshot-based read-modify-write call sites (recent-items in AppShell/HomePage/AgentPage, emoji recents, message selection, recall-test history) with `setX(prev => ...)`. Each updater derives from `prev`, and the callbacks drop the cache value from their dependency arrays.
The mini-app keep-alive sites (hide / cleanup / sync) close the read-modify-write race where an app opened concurrently during a status mutation's await was clobbered by a stale snapshot. Fixes#16460.
Update the two local cache mocks (GlobalSearchPanel / RecallTestPanel tests) to resolve functional updaters like the real hook.
useCache, useSharedCache and usePersistCache setters now accept a React-style functional updater `(prev) => next` in addition to a concrete value. The updater resolves `prev` from the latest stored value at write time rather than the render-time snapshot, making read-modify-write correct across an `await` — the root cause of the keep-alive overwrite race behind #16460.
`prev` is typed shallow-readonly (`ReadonlyValue<T>`), so mutating it in place and returning the same reference — which the CacheService `isEqual` short-circuit would otherwise swallow silently — is a compile error. Concrete-value calls are unchanged, so existing consumers keep compiling.
The renderer useCache mock mirrors the functional branch with the same default fallback; docs and hook tests updated. Consumer call-site adoption lands separately.