# Extension points — farion1231/cc-switch

> Canonical page: https://codevetter.com/unpack/cc-switch/extension-points

# Extension points — farion1231/cc-switch

Scanned commit 09c5d39d8c3cf44b1bdfd0c6432c46495e546578 (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

New coding tools plug in through AppType plus a live-config module and a frontend preset file. New proxy vendors plug in through ProviderAdapter and a route on the Axum router. New UI features plug in as a Tauri command in commands/, a line in invoke_handler, and a wrapper in src/lib/api. Deep links, MCP/Skill app flags, and the settings KV table are the other registries. Schema changes must bump SCHEMA_VERSION and add a migration.
- Adding a tool requires a new AppType variant, as_str, FromStr, all(), is_additive_mode or supports_local_proxy, and the matching frontend AppId in APP_IDS. MCP and Skills need a new bool on McpApps and SkillApps plus an enabled_* column. VisibleApps on both the Rust settings struct and the TypeScript default must be updated together. — [src-tauri/src/app_config.rs#L8-214](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/app_config.rs#L8-L214) [src-tauri/src/app_config.rs#L393-465](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/app_config.rs#L393-L465) [src/config/appConfig.tsx#L19-89](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src/config/appConfig.tsx#L19-L89) [src-tauri/src/settings.rs#L24-88](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/settings.rs#L24-L88)
- Live IO for each tool is a dedicated module: claude via config.rs, claude_desktop_config.rs, codex_config.rs, gemini_config.rs, grok_config.rs, opencode_config.rs, openclaw_config.rs, hermes_config.rs, mcode_config.rs, and pi_config/mod.rs. read_live_settings and the write path in services/provider/live.rs are the dispatch tables a new app must join. — [src-tauri/src/services/provider/live.rs#L1744-1860](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/services/provider/live.rs#L1744-L1860) [src-tauri/src/pi_config/mod.rs#L1-7](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/pi_config/mod.rs#L1-L7) [src-tauri/src/mcode_config.rs#L1-60](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/mcode_config.rs#L1-L60)
- ProviderAdapter in proxy/providers/adapter.rs is the proxy plugin trait: name, extract_base_url, extract_auth, build_url, get_auth_headers, and optional transform_request/transform_response. Concrete adapters live under proxy/providers (claude, codex, gemini, copilot, xAI OAuth, streaming transforms). auth_header_value rejects CR/LF in credentials instead of panicking. — [src-tauri/src/proxy/providers/adapter.rs#L16-69](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/proxy/providers/adapter.rs#L16-L69)
- New proxy endpoints are registered in ProxyServer::build_router. App-specific prefixes already used are /claude, /claude-desktop, /codex, and /grokbuild. A fifth proxied app would also need a proxy_config CHECK constraint change, a seed row, supports_local_proxy, and PROXY_APP_IDS. — [src-tauri/src/proxy/server.rs#L291-370](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/proxy/server.rs#L291-L370) [src-tauri/src/database/schema.rs#L127-184](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/database/schema.rs#L127-L184) [src/config/appConfig.tsx#L57-68](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src/config/appConfig.tsx#L57-L68)
- The command table is tauri::generate_handler! in lib.rs. Each command module is declared and star-exported from commands/mod.rs. Frontend call sites must use the Rust function name; several parameters are intentionally camelCase (addToLive, originalId, providerId) under allow(non_snake_case). — [src-tauri/src/lib.rs#L1388-1400](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/lib.rs#L1388-L1400) [src-tauri/src/commands/mod.rs#L1-74](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/commands/mod.rs#L1-L74) [src-tauri/src/commands/provider.rs#L38-44](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/commands/provider.rs#L38-L44)
- Provider presets are plain TypeScript arrays in src/config/*ProviderPresets.ts, not a runtime plugin loader. Universal providers are a second registry: UniversalProviderPreset in universalProviderPresets.ts and the universal_providers JSON blob in the settings table, with sync_universal_provider pushing one record into Claude, Codex, and Gemini. — [src/config/claudeProviderPresets.ts#L25-50](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src/config/claudeProviderPresets.ts#L25-L50) [src/config/universalProviderPresets.ts#L15-37](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src/config/universalProviderPresets.ts#L15-L37) [src-tauri/src/database/dao/universal_providers.rs#L10-14](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/database/dao/universal_providers.rs#L10-L14)
- Deep link resources are a string discriminant on DeepLinkImportRequest (provider, prompt, mcp, skill) parsed in deeplink/parser.rs and imported by per-resource modules. New resource types need a parser arm, an import function, and a frontend confirm dialog branch. — [src-tauri/src/deeplink/mod.rs#L11-40](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/deeplink/mod.rs#L11-L40) [src-tauri/src/deeplink/mod.rs#L104-114](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/deeplink/mod.rs#L104-L114)
- Schema evolution is SCHEMA_VERSION in database/mod.rs, currently 19, with migrations in database/schema.rs. New databases get CREATE TABLE IF NOT EXISTS; existing databases run apply_schema_migrations only when the stored user_version is lower. A higher on-disk version aborts into the upgrade UI instead of writing DDL. — [src-tauri/src/database/mod.rs#L54-56](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/database/mod.rs#L54-L56) [src-tauri/src/database/mod.rs#L126-183](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/database/mod.rs#L126-L183) [src-tauri/src/database/schema.rs#L16-24](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/database/schema.rs#L16-L24)
- i18n resources are four JSON files registered in src/i18n/index.ts. getInitialLanguage reads localStorage language, then navigator, with default zh. Tray locale mapping in tray.rs is documented to mirror that order. User-facing Rust errors use AppError::localized(key, zh, en). — [src/i18n/index.ts#L4-60](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src/i18n/index.ts#L4-L60) [src-tauri/src/tray.rs#L68-80](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/tray.rs#L68-L80) [src-tauri/src/app_config.rs#L483-487](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/app_config.rs#L483-L487)
- OMO is an OpenCode category pair (omo and omo-slim) handled inside switch_normal by OmoService::write_config_to_file and delete_config_file, not by the generic provider writer. A similar exclusive sidecar should follow that branch rather than is_additive_mode. — [src-tauri/src/services/provider/mod.rs#L5723-5831](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/services/provider/mod.rs#L5723-L5831)
- Per-app config directory overrides are fields on AppSettings (claude_config_dir, codex_config_dir, gemini_config_dir, grok_config_dir, opencode_config_dir, openclaw_config_dir, hermes_config_dir, pi_config_dir) resolved by the matching get_*_dir helpers. The whole ~/.cc-switch directory can be moved via the Tauri Store override read in app_store::refresh_app_config_dir_override before the database opens. — [src-tauri/src/settings.rs#L549-556](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/settings.rs#L549-L556) [src-tauri/src/lib.rs#L465-467](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/lib.rs#L465-L467) [src-tauri/src/config.rs#L258-263](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/config.rs#L258-L263) [src-tauri/src/openclaw_config.rs#L31-40](https://github.com/farion1231/cc-switch/blob/09c5d39d8c3cf44b1bdfd0c6432c46495e546578/src-tauri/src/openclaw_config.rs#L31-L40)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
