One-click menu-bar utility to swap AI providers for the Deep Code CLI. Switch in seconds. No config editing. No restart.
Latest stable: v0.1.1
macOS — recommended (no Gatekeeper prompts, auto-updates with brew upgrade):
brew install --cask skyedolyn-sys/deep-switch/deep-switch| Platform | Download | Size |
|---|---|---|
| macOS (Apple Silicon) | deep-switch_0.1.1_aarch64.dmg |
~5 MB |
| macOS (Apple Silicon) | deep-switch_0.1.1_aarch64.zip |
~5 MB |
| Linux (deb) | deep-switch_0.1.1_amd64.deb |
~6 MB |
| Linux (AppImage) | deep-switch_0.1.1_amd64.AppImage |
~80 MB |
| Windows (MSI) | deep-switch_0.1.1_x64_en-US.msi |
~5 MB |
| Windows (NSIS .exe) | deep-switch_0.1.1_x64-setup.exe |
~5 MB |
⚠️ Manual macOS install (dmg/zip): the build is ad-hoc signed, not notarized, so macOS may report the app as "damaged" on first launch. Don't trash it — the download is fine. Either:
- Open
安装说明 Installation Guide.txtinside the dmg / unzipped folder and follow the 3 copy-paste steps (no command knowledge needed), or- run once in Terminal:
xattr -cr /Applications/deep-switch.app, then re-launch.The Homebrew cask does this automatically — that's why it's the recommended path. We will switch to a notarized release once we have a verified Apple Developer ID.
Linux: AppImage is portable (no install);
.debfor Debian/Ubuntu. Windows: MSI for system-wide install, NSIS.exefor portable per-user.
██████╗ ███████╗███████╗██████╗ ███████╗██╗ ██╗██╗████████╗ ██████╗██╗ ██╗
██╔══██╗██╔════╝██╔════╝██╔══██╗ ██╔════╝██║ ██║██║╚══██╔══╝██╔════╝██║ ██║
██║ ██║█████╗ █████╗ ██████╔╝ ███████╗██║ █╗ ██║██║ ██║ ██║ ███████║
██║ ██║██╔══╝ ██╔══╝ ██╔═══╝ ╚════██║██║███╗██║██║ ██║ ██║ ██╔══██║
██████╔╝███████╗███████╗██║ ███████║╚███╔███╔╝██║ ██║ ╚██████╗██║ ██║
╚═════╝ ╚══════╝╚══════╝╚═╝ ╚══════╝ ╚══╝╚══╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
Provider switcher for Deep Code CLI — written for the way you actually work.
Deep Switch is a tiny menu-bar / dock utility for macOS (plus a tray utility on Linux & Windows) that edits ~/.deepcode/settings.json so the Deep Code CLI can instantly switch which AI provider it's talking to. Add a provider once, then flip between them with a single click — without ever opening a JSON file.
It is a mirror / interchangeable utility for Deep Code: it never modifies Deep Code itself, only the config the CLI reads on the next call.
Working with multiple providers shouldn't feel like juggling keys.
- 🧩 Too many providers, too many keys — DeepSeek, Moonshot, Zhipu GLM, MiniMax, ByteDance Doubao, SiliconFlow, OpenRouter, OpenAI, Groq, SenseTime SenseNova, Tsinghua DeepSeek-R1… each with its own base URL, model name and quirks.
- 📝 Manual
settings.jsonediting — easy to typo a key, easy to leave a stray comma that breaks the file. - 🐢 Slow switching — quit the CLI, edit the file, relaunch, wait, repeat.
- 💾 Lost backup state — overwrite the file and your old config is gone forever.
- 🔁 Repetition — every new project means the same dance.
Deep Switch collapses all of that into a one-click action.
- ⚡ One-click activation — pick a provider, click Enable, done.
- 📦 Preset coverage — DeepSeek · Moonshot/Kimi · Zhipu GLM · MiniMax · ByteDance Doubao · SiliconFlow · OpenRouter · OpenAI · Groq · SenseTime SenseNova · Tsinghua DeepSeek-R1 (671B full + 32B distilled, both selectable in the preset card), plus a fully customizable Custom slot.
- 🔄 Live apply — edits
~/.deepcode/settings.jsondirectly. The next call your CLI makes already uses the new provider. No restart needed. - 🌐 OpenCode sync — also writes the equivalent provider to
~/.config/opencode/opencode.jsonso the opencode-ai CLI can use it through its@ai-sdk/openai-compatibleadapter. Same provider, two clients. - 🧠 Model picker — fetches the live model list from a provider's
/v1/modelsendpoint so you're always picking from what's actually available. - 🤔 Thinking mode toggle — enable chain-of-thought and pick the reasoning depth:
highormax. - 🛰️ Campus / WAF-tolerant proxy — for providers behind strict WAFs (e.g. Tsinghua's madmodel.cs.tsinghua.edu.cn), Deep Switch spawns an embedded Node.js helper (
scripts/tsinghua-proxy.mjs) that auto-retries on transient 404s, splits<think>reasoning into a separatereasoning_contentdelta, and streams warning chunks back to the client so the CLI never appears hung while retrying. - 🪟 Hide-to-tray on close — closing the window keeps the app alive in the menu bar; right-click the tray icon to quit.
- 🌐 Bilingual UI — Simplified Chinese and English, with automatic detection of system locale and a manual override.
- 📌 Tray menu quick-switch — right-click the tray icon to flip providers without opening the window; labels follow your UI language; state syncs back to the main window via an
active-provider-changedevent. - 🪄 First-time "Detect current config" import — reads whatever Deep Code is currently configured for and turns it into a saveable provider with one click.
- 🔒 Local-only credentials — stored in
~/.deep-switch/config.jsonwith0600permissions. Never uploaded, never synced, never logged. - 🎯 Health checks — optional lightweight probe of the provider's base URL so you know before the CLI does.
- 🪶 Lightweight — single tray icon, system webview, ~12 MB on disk. No bundled Chromium, no background daemon.
┌──────────────────┐ ┌────────────────────────┐ ┌──────────────────────┐
│ Preset / Custom │ ───▶ │ Click "Enable" │ ───▶ │ ~/.deepcode/ │
│ provider list │ │ in the main window │ │ settings.json │
│ (DeepSeek, │ │ or the tray menu │ │ is rewritten on │
│ Moonshot, …) │ │ │ │ disk. │
└──────────────────┘ └────────────────────────┘ └──────────┬───────────┘
│
▼
┌──────────────────────────┐
│ Next Deep Code CLI call │
│ reads the new settings │
│ and talks to the chosen │
│ provider. │
└──────────────────────────┘
Four steps, end to end:
- Add a provider (pick a preset or paste your own base URL + key).
- Enable it from the main window or the tray menu.
- Deep Switch writes the new
settings.jsonvia the Tauri Rust main process. - The next time you call the Deep Code CLI, it loads the file you just saved.
That's the whole loop.
Homebrew (one command, handles the Gatekeeper quarantine for you):
brew install --cask skyedolyn-sys/deep-switch/deep-switchOr manual install: download the latest .dmg from the Releases page and drag Deep Switch into your Applications folder.
The first time you launch from the DMG, you may need to right-click → Open to clear the Gatekeeper prompt, since the build is unsigned. The Homebrew cask runs
xattr -crautomatically so you skip this step.
First-party installers are now available — see the Download table at the top.
Linux — which file?
.deb(Debian / Ubuntu): ~4 MB, system-wide install, requiressudo. Pulls WebKitGTK from your system viaapt. Install withsudo dpkg -i deep-switch_0.1.1_amd64.deb(or double-click in most desktop file managers)..AppImage(any distro, no root): ~80 MB, fully self-contained — bundles its own WebKitGTK so it runs on Arch / Fedora / openSUSE without installing extra system libraries. Justchmod +x deep-switch_0.1.1_amd64.AppImage && ./deep-switch_0.1.1_amd64.AppImage, or double-click. The size is the cost of portability: every dependency travels inside the file.
If you'd rather run from source:
git clone https://github.com/skyedolyn-sys/deep-switch.git
cd deep-switch
npm install
npm run tauri devRequirements: Node.js 20+ and Rust 1.77+ (Tauri 2 toolchain).
# Clone
git clone https://github.com/skyedolyn-sys/deep-switch.git
cd deep-switch
# Install JS deps (uses your local repo's lockfile)
npm install
# Dev mode — runs Vite + Tauri with HMR
npm run tauri dev
# Or renderer-only (browser preview, no Tauri):
npm run dev:renderer
# Type-check (renderer)
npx tsc --noEmit
# Production build for your platform
npm run tauri build
# Lint
npm run lintnpm run tauri dev boots Vite on http://localhost:5173 and launches a Tauri WebView window pointing at it — you get hot reload on the renderer and a Rust recompile whenever you change src-tauri/src/**.
| Layer | Tooling |
|---|---|
| Shell | Tauri 2 (uses the system WebView) |
| Renderer | React 18 + TypeScript 5 + Vite 5 |
| Native backend | Rust 1.77+ (serde, reqwest, tauri-plugin-log) |
| WAF helper | Embedded Node.js subprocess (scripts/tsinghua-proxy.mjs) spawned only when you switch to a WAF-protected provider; transparent retry + SSE streaming |
| i18n | i18next + i18next-browser-languagedetector |
| Vendor icons | @lobehub/icons (open-source SVG brand pack) |
| Local store | ~/.deep-switch/config.json (JSON, atomic write) |
| Persistence | ~/.deep-switch/config.json + ~/.deepcode/settings.json + ~/.config/opencode/opencode.json |
deep-switch/
├── src/
│ └── renderer/ # React UI
│ ├── App.tsx
│ ├── components/ # ProviderCard, PresetSelector, ProviderDetail, …
│ ├── lib/ # vendor-icons.tsx (shared module)
│ ├── locales/ # en.json, zh.json
│ ├── i18n.ts
│ └── global.css
├── src-tauri/ # Tauri Rust backend
│ ├── src/
│ │ ├── main.rs # Tauri entrypoint
│ │ └── lib.rs # 15 #[tauri::command] IPC + tray + db
│ ├── icons/ # App icon set
│ ├── capabilities/ # Tauri security policy
│ ├── tauri.conf.json # Window config, identifier, bundle settings
│ └── Cargo.toml
├── public/ # Static assets (tray icon, etc.)
├── docs/ # Translations & extra docs
├── .github/workflows/ # CI + release
│ ├── ci.yml
│ └── release.yml
├── tsconfig.json # Renderer TS config
└── vite.config.mts
PRs welcome — keep them focused.
- Fork the repo and create a topic branch (
feat/<short-name>,fix/<short-name>). - Run
npm run lintandnpx tsc --noEmitbefore pushing. - Open a PR describing the why, not just the what.
When adding provider presets, edit src-tauri/src/lib.rs (get_builtin_presets) — keep the description / descriptionEn (and platform / hint / homepageUrl) fields in sync for both locales.
When adding translations, edit src/renderer/locales/en.json and src/renderer/locales/zh.json and make sure the keys match exactly.
- 🔐 API keys live in
~/.deep-switch/config.jsonon your local machine. They are never sent to us. There is no "us" — Deep Switch has no backend. - 🚫 No analytics, no telemetry, no crash reporting. No third-party scripts, no remote config fetches.
- 🌐 The only network traffic Deep Switch itself generates is the optional
/v1/modelsfetch when you open the model picker, and an optional health check — both go straight from your machine to the provider you picked. - 🧪 Open-source — every byte that runs on your machine is in this repo. Audit it.
If you find a security issue, please open a private advisory instead of a public issue.
MIT © 2026 Deep Switch contributors.
Thanks to the maintainers of Tauri, React, Vite, Rust and i18next whose work makes this app trivial to build.

