CodeVetter · Repo Unpack · Contributor handoff
farion1231/cc-switch
Read the AppType dispatch, the switch function, and the live-path module for the tool you are touching before editing. Keep frontend AppId lists and Rust enums in lockstep, and update all four locale files for UI strings. Run the narrow Vitest file plus cargo test for the module; home-dir tests must set CC_SWITCH_TEST_HOME. Do not rewrite live CLI files while a takeover backup exists, do not relax CSP, and do not log raw provider settings. CONTRIBUTING.md is partly stale.
- First files for any change: src-tauri/src/app_config.rs (AppType), src-tauri/src/services/provider/mod.rs ProviderService::switch, src-tauri/src/services/provider/live.rs, src/config/appConfig.tsx, src/lib/api/providers.ts, and src/App.tsx. Proxy work also starts at src-tauri/src/proxy/server.rs, provider_router.rs, and services/proxy.rs.
- Safe UI edits are components under src/components and hooks under src/hooks, as long as invoke names stay aligned with commands. Safe backend edits for one tool stay inside that tool's *_config.rs module plus its preset TS file. Cross-cutting switch, takeover, and schema changes are not safe to make without the recovery and backfill paths.
- Command names registered with Tauri are the Rust function names (snake_case), despite CONTRIBUTING saying camelCase. Match existing argument renaming: the frontend passes app, id, provider, addToLive, originalId, providerId. New commands must be added both in commands/*.rs and in the generate_handler list.
- i18n edits belong in src/i18n/locales/en.json, zh.json, zh-TW.json, and ja.json. The renderer defaults to zh. Rust user-visible errors should use AppError::localized so both zh and en exist even when the key is missing on one side.
- Tests to run: pnpm test:unit for TS, filtered to the nearest tests/** file; cargo test --manifest-path src-tauri/Cargo.toml <name> for Rust. Integration tests that import switch_provider_test_hook need the library built with the test hooks that those tests already reference. Set CC_SWITCH_TEST_HOME and take the serial mutex before touching ~/.claude or ~/.codex. cargo fmt and clippy -D warnings match CI.
- Do not point tests or manual runs at the developer's real home. get_home_dir honors CC_SWITCH_TEST_HOME only; dirs::home_dir and a raw HOME on Windows are explicitly called out as ways to split or leak the database. get_app_config_dir on Windows will adopt a legacy HOME/.cc-switch database if the default file is absent.
- Exclusive versus additive is the main behavioral trap. OpenCode, OpenClaw, Hermes, Pi, and Mcode must not go through backfill-and-replace. remove_provider_from_live_config exists for additive apps and refuses other app types. Pi is not in the generic live sync loop.
- Proxy takeover owns the live file. Edits that call write_live while a backup row or placeholder is present will clobber the stub or the backup. Use lock_switch_for_app and the hot-switch path. Official Codex can pass through native auth; other official providers are blocked while takeover is on.
- Logging and error strings must not include raw API keys. Use url_for_log / redact_known_secrets. Frontend settings reads must keep using get_settings_for_frontend, which clears WebDAV and S3 secrets. Credential files should use atomic_write_private (0600), not a plain fs::write.
- Before finishing a user-facing flow, check db_version_too_new still renders DatabaseUpgrade, configLoadError still exits, and Hermes visibility defaults if you touched VisibleApps. Prettier only formats src/**, not tests/, so a format:check pass does not prove tests are formatted. Clippy denies warnings on the whole crate.