# clash-verge-rev/clash-verge-rev — codebase unpack

> Canonical page: https://codevetter.com/unpack/clash-verge-rev

This is a deterministic Repo Unpack scan of clash-verge-rev/clash-verge-rev — a structural map, not a review, security audit, or maintainer-endorsed description.

- Scanned commit: fd06fbb3b71ee5c4467bc0e3cc505dcac5348371 (2026-09-22)
- Last upstream commit: fix(service): adopt IPC 2.7.3 and correct dev fallback handling
- Generated by codevetter 1.12.0 on 2026-09-22
- 673 files scanned · 4.2 MB

## Languages

- TypeScript: 235 files
- JSON: 150 files
- Rust: 141 files
- YAML: 36 files
- JavaScript: 23 files
- Markdown: 21 files
- TOML: 15 files
- Shell: 10 files

## Repository structure

- src/ — 389 files
- src-tauri/ — 139 files
- crates/ — 45 files
- scripts/ — 30 files
- .github/ — 26 files
- docs/ — 8 files
- scripts-workflow/ — 3 files
- .devcontainer/ — 2 files

Probable source entrypoint: `src/main.tsx` (inferred from the tree, not upstream docs)

## Source layout — src/

- src/locales/ — 42 files
- src/types/ — 7 files
- src/index.html — 1 file
- src/main.tsx — 1 file

## Package

- Cargo.toml: null — 0 declared dependencies

## Structural health signals

Average score 5.9/10 across 96 files; 69 hotspots. These are deterministic review leads, not proof of a bug.

## Recent history

- fd06fbb3b71e (2026-09-22) fix(service): adopt IPC 2.7.3 and correct dev fallback handling
- ed0b8015738d (2026-09-22) fix(service): unify installation and safe sidecar handoff
- ff1ce92facfd (2026-09-22) feat(dns): remember override state per profile
- 6a85d0344e5d (2026-09-22) fix(enhance): replace DNS fields in merge overrides
- bffe91db5eed (2026-09-22) fix(service): prompt reinstallation after path permission rejection

## Overview

Clash Verge Rev (package clash-verge 2.5.5, GPL-3.0) is a Tauri 2 desktop GUI for the Mihomo/Clash.Meta core, aimed at people who run a local rule-based proxy on Windows, macOS, and Linux. A React 19 frontend drives profiles, proxies, rules, connections, and settings, while the Rust backend owns config enhancement, the system proxy, TUN, and either a privileged helper service or a bundled verge-mihomo sidecar. What sets it apart from a thin Mihomo wrapper is the profile chain (merge and sandboxed JavaScript), copy-on-write drafts, service-or-sidecar core lifecycle, and local-only storage of config and logs.

## System map

The process starts in src-tauri/src/main.rs, which installs a capped Tokio runtime and calls app_lib::run in src-tauri/src/lib.rs. That builder registers Tauri plugins and the IPC command table, then resolve_setup brings up config, the core, the tray, and the window. The UI is a Vite app rooted at src/ on port 3000. Persistent state lives in the OS data directory under the bundle id, not in the repo. The Mihomo core is an external binary, started either by clash-verge-service over IPC or as a sidecar. Release builds are GitHub Actions tag workflows; day-to-day dev is pnpm plus Cargo.
- Product identity is Clash Verge, npm name clash-verge and Rust package clash-verge version 2.5.5, bundle id io.github.clash-verge-rev.clash-verge-rev, license GPL-3.0-only, with lib app_lib built as staticlib, cdylib, and rlib. — [package.json](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/package.json) [src-tauri/Cargo.toml](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/Cargo.toml) [src-tauri/tauri.conf.json](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/tauri.conf.json)
- main() in src-tauri/src/main.rs builds a multi-thread Tokio runtime named clash-verge-runtime-* with at most 8 worker threads and twice that many blocking threads, sets it as the Tauri async runtime, then calls app_lib::run(). The perf-harness feature on macOS swaps in scripts/perf/app.rs instead. — [src-tauri/src/main.rs#L16-L37](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/main.rs#L16-L37)
- app_init::setup_plugins registers sysinfo, notification, updater (with a custom comparator that also treats build-to-stable as newer), clipboard, process, global-shortcut, fs, dialog, shell, opener, deep-link, http, and tauri-plugin-mihomo over a local socket at IClashTemp::guard_external_controller_ipc. Devtools load only for debug builds with tauri-dev and without tokio-trace. — [src-tauri/src/lib.rs#L42-L78](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L42-L78)
- The only IPC command table is app_init::generate_handlers, covering listener probes, proxy ports, profiles, clash/DNS, service install, runtime YAML, UWP, backups, WebDAV, and media-unlock checks. — [src-tauri/src/lib.rs#L126-L216](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L126-L216)
- Frontend bootstrap is src/main.tsx: Vite root src, dev server port 3000, React 19 StrictMode, SWR, WindowProvider, AppDataProvider, and a createBrowserRouter whose children come from navItems. beforeDevCommand is pnpm run web:dev and frontendDist is ../dist. — [src/main.tsx#L43-L74](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/main.tsx#L43-L74) [src/pages/_routers.tsx](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/pages/_routers.tsx) [vite.config.mts](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/vite.config.mts) [src-tauri/tauri.conf.json#L23-L28](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/tauri.conf.json#L23-L28)
- The Cargo workspace members are src-tauri plus crates clash-verge-draft, clash-verge-media-unlock, clash-verge-logging, clash-verge-signal, tauri-plugin-clash-verge-sysinfo, clash-verge-i18n, and clash-verge-limiter. tray-icon is patched from Tunglies/tray-icon branch fix/macos-27-click-reentrancy. — [Cargo.toml#L1-L63](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/Cargo.toml#L1-L63)
- Bundled externalBin sidecars are sidecar/verge-mihomo and sidecar/verge-mihomo-alpha. scripts/prebuild.mjs downloads the Mihomo core and the clash-verge-service binary into src-tauri/sidecar or src-tauri/resources (Linux service binaries go to the sidecar dir). — [src-tauri/tauri.conf.json#L17](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/tauri.conf.json#L17) [scripts/prebuild.mjs#L67-L70](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/scripts/prebuild.mjs#L67-L70)
- App home is dirs::data_dir() joined with APP_ID (the .dev id when feature verge-dev is on). Files there include verge.yaml, config.yaml, profiles.yaml, profiles/, logs/, icons/, clash-verge.yaml, dns_config.yaml, and window_state.json. — [src-tauri/src/utils/dirs.rs#L11-L31](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/dirs.rs#L11-L31) [src-tauri/src/utils/dirs.rs#L95-L111](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/dirs.rs#L95-L111) [src-tauri/src/constants.rs#L56-L61](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/constants.rs#L56-L61)
- Privileged core control uses clash_verge_service_ipc 2.7.3 with the client feature. Feature verge-dev also enables that crate's development-channel. CoreManager::start_core_inner picks StartupDecision::Service or Sidecar from ServiceStatus, with a Windows sidecar fallback. — [src-tauri/Cargo.toml#L102-L104](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/Cargo.toml#L102-L104) [src-tauri/Cargo.toml#L17-L21](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/Cargo.toml#L17-L21) [src-tauri/src/core/manager/lifecycle.rs#L40-L49](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/lifecycle.rs#L40-L49) [src-tauri/src/core/manager/lifecycle.rs#L572-L633](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/lifecycle.rs#L572-L633)
- Deep-link desktop schemes are clash and clash-verge. The updater plugin pins a minisign pubkey and three endpoints, trying update.hwdns.net and gh-proxy.org before the GitHub update.json. Windows install mode is passive. — [src-tauri/tauri.conf.json#L32-L48](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/tauri.conf.json#L32-L48)
- Rust toolchain file pins channel 1.98.1 with rustfmt and clippy. The crate rust-version is 1.95 and edition 2024. pnpm scripts are dev, dev:service, dev:sidecar, build, web:build, typecheck, lint, and test (vitest run). — [rust-toolchain.toml](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/rust-toolchain.toml) [src-tauri/Cargo.toml#L10-L11](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/Cargo.toml#L10-L11) [package.json#L5-L41](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/package.json#L5-L41)
- Release workflow .github/workflows/release.yml runs on tags v*.*.*, requires the tag commit to be on main, and requires the tag to equal v plus package.json version. dev.yml is a manual matrix of Windows, macOS aarch64, and Linux deb/nsis/dmg bundles and does not run unit tests. — [.github/workflows/release.yml#L1-L59](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/.github/workflows/release.yml#L1-L59) [.github/workflows/dev.yml#L1-L63](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/.github/workflows/dev.yml#L1-L63)

## Feature catalog

The user-facing surface is an eight-route desktop shell plus a tray menu and global hotkeys. Profiles can be remote subscriptions, local YAML, merge patches, or JavaScript enhancers. Clash controls cover mode, ports, DNS override, system proxy, TUN, and switching between the stable and alpha Mihomo cores. Backup is local files or WebDAV. A media-unlock page probes streaming and AI sites through the mixed port. There is no first-party cloud account; the external integrations are Mihomo, the OS proxy APIs, the helper service, WebDAV, and the GitHub updater.
- Routes from navigationItems are / (home), /proxies, /profile, /connections, /rules, /logs, /unlock, and /settings, each mapped to a page component in navItems. — [src/pages/_navigation-meta.ts](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/pages/_navigation-meta.ts) [src/pages/_navigation.tsx#L37-L78](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/pages/_navigation.tsx#L37-L78) [src/pages/_routers.tsx](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/pages/_routers.tsx)
- Home renders ClashModeCard, CurrentProxyCard, EnhancedCard, EnhancedTrafficStats, HomeProfileCard, and ProxyTunCard, and can call entry_lightweight_mode. — [src/pages/home.tsx#L29-L37](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/pages/home.tsx#L29-L37)
- Settings is four panels: SettingSystem, SettingClash, SettingVergeBasic, and SettingVergeAdvanced, plus external links to the docs site, Telegram, and the GitHub repo. — [src/pages/settings.tsx#L6-L36](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/pages/settings.tsx#L6-L36) [src/pages/settings.tsx#L77-L116](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/pages/settings.tsx#L77-L116)
- Profile item itype is one of remote, local, script, or merge. Creating a remote profile also ensures linked merge and script items exist. import_profile downloads via PrfItem::from_url and appends the item. — [src-tauri/src/config/prfitem.rs#L145-L225](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/config/prfitem.rs#L145-L225) [src-tauri/src/cmd/profile.rs#L65-L93](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/profile.rs#L65-L93)
- The frontend share-link parser parseUri dispatches schemes ss, ssr, vmess, vless, trojan, anytls, hysteria, hysteria2, tuic, wireguard, http, https, and socks5. — [src/utils/uri-parser/index.ts#L17-L40](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/utils/uri-parser/index.ts#L17-L40)
- Tray menu ids cover dashboard, rule/global/direct modes, profiles, proxies, system proxy, TUN, close-all-connections, lightweight mode, copy env, open dirs and logs, restart core, restart app, and exit. TrayAction only classifies system_proxy, tun_mode, main_window, and tray_menu. — [src-tauri/src/core/tray/menu_def.rs#L27-L70](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/tray/menu_def.rs#L27-L70)
- HotkeyFunction names are open_or_close_dashboard, clash_mode_rule, clash_mode_global, clash_mode_direct, toggle_system_proxy, toggle_tun_mode, entry_lightweight_mode, reactivate_profiles, and quit, plus macOS hide. — [src-tauri/src/core/hotkey.rs#L23-L74](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/hotkey.rs#L23-L74)
- Service commands are install_service, uninstall_service, reinstall_service, repair_service, continue_with_sidecar, and sync_runtime_providers, plus one-shot notices for sidecar fallback and service repair. — [src-tauri/src/cmd/service.rs#L29-L71](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/service.rs#L29-L71) [src-tauri/src/lib.rs#L147-L151](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L147-L151)
- Clash commands include patch_clash_config, patch_clash_mode, change_clash_core, restart_core, upgrade_clash_core, test_delay, and DNS save/apply/override/validate. Default ports are mixed 7897, socks 7898, http 7899, external controller 127.0.0.1:9097. — [src-tauri/src/cmd/clash.rs#L18-L50](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/clash.rs#L18-L50) [src-tauri/src/cmd/clash.rs#L104-L147](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/clash.rs#L104-L147) [src-tauri/src/constants.rs#L3-L14](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/constants.rs#L3-L14)
- Local backup commands are create/list/delete/restore/import/export. WebDAV commands are save_webdav_config, create_webdav_backup, list_webdav_backup, delete_webdav_backup, and restore_webdav_backup. — [src-tauri/src/cmd/backup.rs#L6-L28](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/backup.rs#L6-L28) [src-tauri/src/cmd/webdav.rs#L10-L46](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/webdav.rs#L10-L46)
- Media unlock lists Bilibili (mainland and HK/MO/TW), ChatGPT, Claude, Gemini, YouTube Premium, Bahamut, Netflix, Disney+, Prime Video, Spotify, and TikTok, with MAX_CONCURRENT_CHECKS of 4. The command builds a reqwest client proxied at the effective mixed port. — [crates/clash-verge-media-unlock/src/lib.rs#L26-L55](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/crates/clash-verge-media-unlock/src/lib.rs#L26-L55) [src-tauri/src/cmd/media_unlock_checker/mod.rs#L6-L35](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/media_unlock_checker/mod.rs#L6-L35)
- README-listed product features match the code: built-in Mihomo with an alpha core switch, theme color and CSS injection, merge/script profile enhancement, system-proxy guard, TUN, visual node and rule editing, and WebDAV backup. The app states it does not collect user data. — [README.md#L79-L87](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/README.md#L79-L87) [README.md#L130-L135](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/README.md#L130-L135)
- invoke_uwp_tool calls core::win_uwp::invoke_uwptools on Windows and is a no-op on other platforms. — [src-tauri/src/cmd/uwp.rs#L3-L26](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/uwp.rs#L3-L26)
- SilentUpdater::try_install_on_startup runs during resolve_setup and calls feat::restart_app if an update installs; a background check is then spawned. — [src-tauri/src/utils/resolve/mod.rs#L167-L186](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/resolve/mod.rs#L167-L186)

## Data flow

User input enters through Tauri invoke, the Mihomo plugin's local socket, deep links, or the localhost warp server. Rust turns profiles and verge/clash settings into one runtime YAML via enhance::enhance, validates it by executing the Mihomo sidecar with -t, then applies it to the running core. Live proxy and traffic data flow the other way: the UI polls get_proxy_view and Mihomo HTTP, and the backend pushes verge:// events. Durable files are YAML under the app home. WebDAV credentials are encrypted only while the task-local encryption flag is on.
- src/services/cmds.ts is the typed invoke() boundary. Examples: get_profiles, import_profile, get_proxy_view (rejects schemaVersion other than 1), patch_verge_config, and save_profile_file, which treats ValidationOutcome.status === 'valid' as success. — [src/services/cmds.ts#L13-L58](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/services/cmds.ts#L13-L58) [src/services/cmds.ts#L136-L142](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/services/cmds.ts#L136-L142)
- Live Mihomo data does not all go through cmds.ts. AppDataProvider uses tauri-plugin-mihomo-api getBaseConfig, getRules, and getRuleProviders, and polls getProxyView every 15 seconds via an SWR wrapper in src/services/query-client.ts. — [src/providers/app-data-provider.tsx#L1-L30](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/providers/app-data-provider.tsx#L1-L30) [src/providers/app-data-provider.tsx#L56-L77](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/providers/app-data-provider.tsx#L56-L77) [src/services/query-client.ts#L1-L40](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/services/query-client.ts#L1-L40)
- Backend events subscribed in src/services/events.ts include verge://refresh-clash-config, verge://refresh-verge-config, verge://refresh-profiles, verge://notice-message, verge://run-state-changed, profile-changed, and profile-update-started/completed. — [src/services/events.ts#L6-L20](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/services/events.ts#L6-L20)
- In-memory config is Draft<T> from clash-verge-draft: data_arc is the committed snapshot, latest_arc prefers the uncommitted draft, edit_draft clones only when the Arc is shared, and apply commits the draft. — [crates/clash-verge-draft/src/lib.rs#L31-L79](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/crates/clash-verge-draft/src/lib.rs#L31-L79)
- Config::generate_with_profiles calls enhance::enhance, resolves provider path conflicts, sanitizes tunnels, optionally injects MixedPort::session_fallback, and stores the mapping on the runtime draft as IRuntime { config, dns_override, exists_keys, chain_logs }. generate_file writes that YAML to app_home/clash-verge.yaml with a generated-by header. — [src-tauri/src/config/config.rs#L196-L248](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/config/config.rs#L196-L248)
- enhance() order is: collect current profile items; process seq rules/proxies/groups; merge GUI clash defaults and port toggles; apply builtin scripts; use_tun; merge dns_config.yaml when DNS settings are enabled; run global merge then global script; run profile merge then profile script; enforce authoritative fields; cleanup proxy groups and sort keys. — [src-tauri/src/enhance/mod.rs#L872-L969](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/enhance/mod.rs#L872-L969)
- Script enhancers run in Boa. The stock tmpl::ITEM_SCRIPT skips the engine. Other scripts get a 5 second timeout, a 10_000_000 loop-iteration cap, a 10MB JSON input cap, and a console that only calls __verge_log__. Exceptions return the input config unchanged plus an exception log. — [src-tauri/src/enhance/script.rs#L12-L66](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/enhance/script.rs#L12-L66) [src-tauri/src/enhance/script.rs#L123-L132](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/enhance/script.rs#L123-L132)
- Builtin script src-tauri/src/enhance/builtin/meta_guard.js rewrites config.mode from script to rule. It is applied from the Rust enhancer, not from the webview. — [src-tauri/src/enhance/builtin/meta_guard.js#L1-L7](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/enhance/builtin/meta_guard.js#L1-L7) [src-tauri/src/enhance/mod.rs#L930](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/enhance/mod.rs#L930)
- verge.yaml WebDAV url, username, and password use serialize_encrypted / deserialize_encrypted. AES-256-GCM runs only when ENCRYPTION_ACTIVE is set by with_encryption. help.rs reads and writes YAML inside that scope. The 32-byte key is created with getrandom and stored at app_home/.encryption_key. — [src-tauri/src/config/verge.rs#L168-L190](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/config/verge.rs#L168-L190) [src-tauri/src/config/encrypt.rs#L18-L92](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/config/encrypt.rs#L18-L92) [src-tauri/src/utils/dirs.rs#L155-L170](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/dirs.rs#L155-L170) [src-tauri/src/utils/help.rs#L1-L23](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/help.rs#L1-L23)
- Core config validation shells out to the selected sidecar: app_handle.shell().sidecar(clash_core) with args -t -d <app dir> -f <config path>, timeout 5 seconds. ValidationOutcome is Valid, Invalid, Skipped (exiting or debounced), or Busy. — [src-tauri/src/core/validate.rs#L20-L21](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/validate.rs#L20-L21) [src-tauri/src/core/validate.rs#L113-L136](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/validate.rs#L113-L136) [src-tauri/src/core/validate.rs#L361-L364](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/validate.rs#L361-L364)
- A node click calls Mihomo selectNodeForGroup or unfixedProxy, then sync_tray_proxy_selection, then record_selected_node or forget_selected_node. If auto_close_connection is set, connections whose chain includes the previous proxy are closed. — [src/hooks/use-proxy-selection.ts#L66-L96](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/hooks/use-proxy-selection.ts#L66-L96) [src-tauri/src/cmd/proxy.rs#L19-L32](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/proxy.rs#L19-L32)
- The embedded warp server binds 127.0.0.1. /commands/visible and /commands/scheme require header x-instance-token. /commands/pac does not: it substitutes %mixed-port% into pac_file_content or DEFAULT_PAC and is fail-closed until PAC_AVAILABLE is set. — [src-tauri/src/utils/server.rs#L51-L94](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/server.rs#L51-L94) [src-tauri/src/utils/server.rs#L198-L266](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/server.rs#L198-L266) [src-tauri/src/config/mod.rs#L17-L20](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/config/mod.rs#L17-L20)
- Deep-link import parses clash or clash-verge URLs, takes the raw url= query (percent-decoded at most twice), builds a PrfItem with PrfItem::from_url, appends and saves profiles, refreshes Timer, and calls CoreManager::update_config_forced only when that import becomes the first current profile. — [src-tauri/src/utils/resolve/scheme.rs#L13-L158](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/resolve/scheme.rs#L13-L158)

## Behavior traces

Startup is a singleton check, then a Tauri setup that always tries to open a window even if pre-init panics, then resolve_setup which starts the core in parallel with tray, hotkeys, timers, and the updater. The primary proxy action is a Mihomo select followed by a profile selection write and a tray refresh. Persistence of a subscription is download, append to profiles.yaml, then a forced enhance-and-apply. Quitting is not window-close: close hides the window, and a real exit runs feat::quit, which can cancel if the core will not stop.
- Before the Tauri builder, Windows runs preinit_app_data_dir and owner_identity::repair_app_data_root_owner. Every platform then calls server::check_singleton. Primary continues; Secondary returns exit code success with no error dialog; a lock or bind error returns failure. — [src-tauri/src/lib.rs#L247-L261](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L247-L261) [src-tauri/src/utils/server.rs#L45-L94](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/server.rs#L45-L94) [src-tauri/src/lib.rs#L523-L545](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L523-L545)
- check_singleton locks singleton-instance.lock, binds 127.0.0.1 on the previous port or port 0, writes singleton-instance.json {port, token}, and starts the warp server before the UI exists. A second process POSTs to the primary and exits. — [src-tauri/src/utils/server.rs#L21-L23](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/server.rs#L21-L23) [src-tauri/src/utils/server.rs#L51-L94](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/server.rs#L51-L94)
- setup() sets APP_HANDLE, calls init_work_dir_and_logger (init_config then logger::init), autostart, deep links, and window state inside a panic catch. A second catch always runs resolve_setup_async, resolve_setup_sync, and init_signal so a pre-init panic still attempts the window and core. — [src-tauri/src/lib.rs#L269-L320](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L269-L320) [src-tauri/src/utils/resolve/mod.rs#L30-L50](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/resolve/mod.rs#L30-L50)
- resolve_setup order is migrate_short_update_intervals, macOS dock policy, startup_script, ServiceManager::detect_startup_status, Config::init_config_before_window, WindowManager::create_window (skipped visibly when enable_silent_start), reconcile_startup_tun_availability, init_resources, init_dns_config, Config::init_runtime_config, verify_config_initialization, then a join of core init, tray, timer, hotkey, auto lightweight, auto backup, and silent updater, then Handle::refresh_clash and tray update_part. — [src-tauri/src/utils/resolve/mod.rs#L52-L96](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/resolve/mod.rs#L52-L96) [src-tauri/src/utils/resolve/mod.rs#L213-L236](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/resolve/mod.rs#L213-L236)
- CoreManager::init retries start_core up to 3 times when Config::resolve_startup_mixed_port reports a fallback. start_core takes the config-update flag, then start_core_inner: if ServiceStatus is Ready it calls start_core_by_service; if not installed or sidecar-allowed it calls start_core_by_sidecar. On Windows a service start failure can fall through to the sidecar and spawn_service_handoff_watcher. — [src-tauri/src/core/manager/mod.rs#L256-L305](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/mod.rs#L256-L305) [src-tauri/src/core/manager/lifecycle.rs#L339-L360](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/lifecycle.rs#L339-L360) [src-tauri/src/core/manager/lifecycle.rs#L572-L633](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/lifecycle.rs#L572-L633)
- RunEvent::Ready calls set_commands_ready, which opens the embedded visible and scheme routes. macOS reopen while in lightweight mode calls exit_lightweight_mode; otherwise it shows the main window. CloseRequested on the main window prevent_close and hides the window. — [src-tauri/src/lib.rs#L346-L387](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L346-L387) [src-tauri/src/lib.rs#L452-L516](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L452-L516) [src-tauri/src/utils/server.rs#L288-L290](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/server.rs#L288-L290)
- ExitRequested prevent_exit when lightweight mode is on, or when the event has no exit code, in which case it block_on feat::quit. feat::quit sets is_exiting, Config::apply_all_and_save_file, stops the core, shuts down the embedded server, and app_handle.exit. If the core does not stop it clears is_exiting, emits app_quit::core_stop_failed, and returns ShutdownOutcome::Canceled. — [src-tauri/src/lib.rs#L487-L498](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L487-L498) [src-tauri/src/feat/window.rs#L113-L141](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/feat/window.rs#L113-L141)
- Unpreventable RunEvent::Exit (Windows session end) sets is_exiting if needed and runs feat::clean_session_ending_best_effort, then flushes logs. clash_verge_signal::register(feat::quit) is installed from init_signal. — [src-tauri/src/lib.rs#L470-L486](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L470-L486) [src-tauri/src/utils/resolve/mod.rs#L189-L192](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/resolve/mod.rs#L189-L192) [crates/clash-verge-signal/src/lib.rs#L16-L20](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/crates/clash-verge-signal/src/lib.rs#L16-L20)
- Manual subscription import: cmd::import_profile -> PrfItem::from_url -> profiles_append_item_safe -> profiles_save_file_safe -> Timer::global().refresh -> Handle::notify_profile_changed. Failures use codes PROFILE_IMPORT_FAILED. The URL is masked in the tracing span. — [src-tauri/src/cmd/profile.rs#L65-L93](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/profile.rs#L65-L93)
- Applying profiles: cmd::enhance_profiles -> feat::enhance_profiles -> CoreManager::update_config_forced -> update_config_with_force(true) -> perform_config_update. Busy and exiting short-circuit as ValidationOutcome::Busy or Skipped. A valid outcome also calls Config::sync_dns_override. — [src-tauri/src/cmd/profile.rs#L41-L42](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/profile.rs#L41-L42) [src-tauri/src/feat/profile.rs#L230-L237](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/feat/profile.rs#L230-L237) [src-tauri/src/core/manager/config.rs#L152-L183](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/config.rs#L152-L183)
- Verge setting changes: patch_verge_config -> feat::patch_verge -> apply_verge_patch_locked, which begins a DraftTransaction, edit_draft patch_config, process_terminated_flags, commit, refresh_verge, refresh auto-backup, and save_file unless not_save_file. TUN patches then call reconcile_tun_availability. System-proxy patches attach FailedOperation::SystemProxyEnable or SystemProxyDisable. — [src-tauri/src/cmd/verge.rs#L16-L33](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/verge.rs#L16-L33) [src-tauri/src/feat/config.rs#L279-L326](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/feat/config.rs#L279-L326)
- If startup_script in verge config is a path ending in .sh, .ps1, or .bat, init::startup_script runs bash or powershell on that path via tauri_plugin_shell during resolve_setup, using the script's parent as the working directory. — [src-tauri/src/utils/init.rs#L599-L635](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/init.rs#L599-L635) [src-tauri/src/utils/resolve/mod.rs#L61](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/resolve/mod.rs#L61)
- First-boot runtime validation failure does not abort startup. Config::init_runtime_config logs the outcome and CoreManager::use_default_config replaces the runtime with a minimal config, emitting config_validate::boot_error, process_terminated, or error. — [src-tauri/src/config/config.rs#L151-L193](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/config/config.rs#L151-L193)

## Testing signals

Tests are real but narrow and mostly not wired into CI. Vitest covers a handful of frontend delay, event, and proxy-sort units. Rust tests sit next to the core manager, run state, enhancer, and command-error types and are the safety net for lifecycle decisions. The workflows that were read format-check or build release artifacts; they do not invoke pnpm test or cargo test. CONTRIBUTING.md treats new tests as optional and asks for clippy, eslint, and rustfmt instead.
- package.json test is vitest run. vitest.config.mts includes tests/**/*.test.ts and src/**/*.test.ts in the node environment. There is no top-level tests/ directory, so only src/**/*.test.ts files run. — [package.json#L35](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/package.json#L35) [vitest.config.mts](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/vitest.config.mts)
- Frontend Vitest files found are src/services/delay.test.ts, src/services/events.test.ts, src/pages/_layout/hooks/use-layout-events.test.ts, src/utils/delay.test.ts, and src/components/proxy/use-filter-sort.test.ts. They cover delay sorting, event subscription readiness, and DNS/service notice draining, not pages or IPC. — [src/services/delay.test.ts](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/services/delay.test.ts) [src/services/events.test.ts](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/services/events.test.ts) [src/pages/_layout/hooks/use-layout-events.test.ts](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/pages/_layout/hooks/use-layout-events.test.ts) [src/utils/delay.test.ts](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/utils/delay.test.ts) [src/components/proxy/use-filter-sort.test.ts](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/components/proxy/use-filter-sort.test.ts)
- scripts/perf/report.test.mjs uses node:test for perf-report quantiles and schema. package.json perf:test runs it. macOS perf-harness is a separate Cargo feature pulling tauri-plugin-wdio-webdriver. — [scripts/perf/report.test.mjs](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/scripts/perf/report.test.mjs) [package.json#L38-L41](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/package.json#L38-L41) [src-tauri/Cargo.toml#L26](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/Cargo.toml#L26)
- Rust #[cfg(test)] modules include command failure wire format in cmd/mod.rs, singleton startup actions in lib.rs, fake-ip DNS defaults in enhance/mod.rs, CoreManager lifecycle decisions in core/manager/lifecycle.rs, and PAC fail-closed behavior in utils/server.rs. — [src-tauri/src/cmd/mod.rs#L166-L215](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/mod.rs#L166-L215) [src-tauri/src/lib.rs#L523-L545](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L523-L545) [src-tauri/src/enhance/mod.rs#L971-L996](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/enhance/mod.rs#L971-L996) [src-tauri/src/core/manager/lifecycle.rs#L1426-L1458](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/lifecycle.rs#L1426-L1458) [src-tauri/src/utils/server.rs#L459](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/server.rs#L459)
- Further Rust tests live beside core/runstate, core/proxy_view.rs, core/owner_identity.rs, core/timer.rs, core/runtime_bundle.rs, core/manager/state.rs, and enhance/seq.rs. clash-verge-draft has tests/test_me.rs and a criterion bench at bench/benche_me.rs. — [src-tauri/src/core/proxy_view.rs#L479](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/proxy_view.rs#L479) [src-tauri/src/core/manager/state.rs#L499](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/state.rs#L499) [crates/clash-verge-draft/tests/test_me.rs](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/crates/clash-verge-draft/tests/test_me.rs) [crates/clash-verge-draft/bench/benche_me.rs](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/crates/clash-verge-draft/bench/benche_me.rs)
- Makefile.toml tasks are rust-format, rust-clippy with -D warnings on all targets and features, pnpm typecheck, knip, lint-staged, and i18n format/types. It has no test task. — [Makefile.toml#L9-L74](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/Makefile.toml#L9-L74)
- CONTRIBUTING.md tells contributors to run cargo clippy-all, pnpm lint, and cargo fmt. It says not to add tests unless the linked issue needs them. docs/CONTRIBUTING_i18n.md says to run pnpm test when translation-consuming code changes. — [CONTRIBUTING.md#L19-L20](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/CONTRIBUTING.md#L19-L20) [CONTRIBUTING.md#L120-L132](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/CONTRIBUTING.md#L120-L132) [docs/CONTRIBUTING_i18n.md#L68](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/docs/CONTRIBUTING_i18n.md#L68)
- rustfmt.yml runs on pull requests only when Rust paths change, and only checks formatting. release.yml checks tag versus package.json and builds. dev.yml is a manual installer matrix. None of those three workflows invoke cargo test or pnpm test. — [.github/workflows/rustfmt.yml](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/.github/workflows/rustfmt.yml) [ .github/workflows/release.yml#L1-L59](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/%20.github/workflows/release.yml#L1-L59) [.github/workflows/dev.yml#L1-L63](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/.github/workflows/dev.yml#L1-L63)
- Workspace clippy lints are deny for panic, unwrap is warn, expect_used is warn, cognitive_complexity is deny, and correctness/suspicious are deny. Tests in the repo often allow clippy::expect_used locally. — [Cargo.toml#L113-L167](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/Cargo.toml#L113-L167) [src-tauri/src/cmd/proxy.rs#L113-L115](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/proxy.rs#L113-L115)
- No Vitest file covers profile import, the settings panels, the router, WebDAV, or service install. Those flows are only exercised by the Rust command and lifecycle tests where such tests exist, and those tests are not started by the CI workflows above. (inferred) — [vitest.config.mts](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/vitest.config.mts) [src/pages/settings.tsx](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/pages/settings.tsx) [src-tauri/src/cmd/profile.rs](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/profile.rs)

## Risk map

The highest-impact code is the core lifecycle and the system-proxy/TUN apply path: a bad transition can leave the OS proxy half-set or the core unguarded. The webview is loosely sandboxed (CSP off, filesystem scope **). Profile JavaScript is sandboxed in Boa but can still rewrite the config that Mihomo will load. Secrets at rest are only as private as the app-data directory, because the AES key sits beside verge.yaml. Deep links import remote subscriptions immediately, and a user-configured startup script is executed as a shell.
- tauri.conf.json sets CSP to null and enables the asset protocol with allow ** and requireLiteralLeadingDot false. Capability migrated grants fs:allow-read-file and fs:allow-write-file with scope $APPDATA/**, $RESOURCE/../**, and **. desktop-capability allows http and https to any host via http:allow-fetch. — [src-tauri/tauri.conf.json#L50-L61](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/tauri.conf.json#L50-L61) [src-tauri/capabilities/migrated.json#L7-L18](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/capabilities/migrated.json#L7-L18) [src-tauri/capabilities/desktop.json#L20-L27](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/capabilities/desktop.json#L20-L27)
- PAC is mounted with .or(pac) outside instance_auth. Any local process that can reach 127.0.0.1 on the embedded port can read the PAC body, including the mixed port, once PAC_AVAILABLE is true. Window-restore and scheme import stay behind x-instance-token. — [src-tauri/src/utils/server.rs#L140-L153](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/server.rs#L140-L153) [src-tauri/src/utils/server.rs#L225-L266](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/server.rs#L225-L266)
- startup_script executes an arbitrary existing .sh via bash or .ps1/.bat via powershell from a path stored in verge config, during every startup, with the script directory as cwd. — [src-tauri/src/utils/init.rs#L599-L635](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/init.rs#L599-L635)
- resolve_scheme imports a subscription as soon as the URL parses. There is no confirm command on that path. A clash:// or clash-verge:// link that reaches the primary instance therefore downloads and saves a remote profile. — [src-tauri/src/utils/resolve/scheme.rs#L13-L38](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/resolve/scheme.rs#L13-L38) [src-tauri/src/utils/resolve/scheme.rs#L82-L112](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/resolve/scheme.rs#L82-L112)
- WebDAV secrets are encrypted in verge.yaml, but get_encryption_key stores the raw 32-byte key in app_home/.encryption_key with no OS keychain. A local reader of that directory can decrypt the fields. (inferred) — [src-tauri/src/utils/dirs.rs#L155-L170](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/dirs.rs#L155-L170) [src-tauri/src/config/encrypt.rs#L18-L31](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/config/encrypt.rs#L18-L31) [src-tauri/src/config/verge.rs#L168-L190](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/config/verge.rs#L168-L190)
- check_media_unlock's HTTP client sets danger_accept_invalid_certs(true) and danger_accept_invalid_hostnames(true) and forces traffic through http://127.0.0.1:<mixed port>. Unlock checks can succeed against intercepted TLS. — [src-tauri/src/cmd/media_unlock_checker/mod.rs#L11-L26](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/media_unlock_checker/mod.rs#L11-L26)
- System proxy writes are classified as SysproxyFailure: SYSPROXY_PRIVILEGE_REQUIRED, SYSPROXY_DIRECT_FALLBACK, SYSPROXY_SIDECAR_WHILE_SERVICE_READY, SYSPROXY_GUARD_STOPPED, SYSPROXY_CORE_NOT_READY, and SYSPROXY_SYSTEM_CALL_FAILED. SystemProxyStateUnknown means a write was left partly applied and a turn-off was attempted. rollback_failure keeps the actionable code. — [src-tauri/src/core/proxy_control.rs#L31-L120](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/proxy_control.rs#L31-L120)
- Windows service start uses run_service_start_with_sidecar_fallback. A non-location ServiceStartRefusal is returned rather than ignored. An unclear occupancy probe blocks sidecar fallback. Sidecar continuation is rejected unless can_allow_sidecar_for_session matches mode and status, and a failed sidecar attempt withdraws the allowance and rolls back the proxy. — [src-tauri/src/core/manager/lifecycle.rs#L188-L228](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/lifecycle.rs#L188-L228) [src-tauri/src/core/manager/lifecycle.rs#L362-L426](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/lifecycle.rs#L362-L426)
- Updater endpoints prefer https://update.hwdns.net/... and https://gh-proxy.org/... ahead of the GitHub release update.json. Payloads are still checked with the configured minisign pubkey, but availability depends on those proxies. — [src-tauri/tauri.conf.json#L32-L39](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/tauri.conf.json#L32-L39)
- Config validation and the running core shell out to a sidecar binary named by verge's clash core (verge-mihomo or verge-mihomo-alpha). Replacing that binary in the install or sidecar directory changes what -t and the runtime execute. — [src-tauri/src/core/validate.rs#L361-L364](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/validate.rs#L361-L364) [src-tauri/tauri.conf.json#L17](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/tauri.conf.json#L17)
- Profile scripts are not a browser sandbox escape, but they do receive the full clash mapping and their returned object becomes the runtime config after authoritative-field enforcement. A malicious local script profile can still rewrite rules and proxies within those limits. Remote subscriptions are YAML fetched by PrfItem::from_url, not executed as JavaScript by themselves. — [src-tauri/src/enhance/script.rs#L22-L60](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/enhance/script.rs#L22-L60) [src-tauri/src/enhance/mod.rs#L936-L959](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/enhance/mod.rs#L936-L959) [src-tauri/src/config/prfitem.rs#L250-L285](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/config/prfitem.rs#L250-L285)
- Lock order is documented as config write lock then lifecycle lock. continue_with_sidecar and uninstall_service_and_start_sidecar both comment that taking them in the other order can commit another transaction's staged verge patch. — [src-tauri/src/core/manager/lifecycle.rs#L370-L373](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/lifecycle.rs#L370-L373) [src-tauri/src/core/manager/lifecycle.rs#L437-L439](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/lifecycle.rs#L437-L439)
- Linux desktop file template declares only MimeType x-scheme-handler/clash, while init_scheme registers both clash and clash-verge via xdg-mime. A packaging drift can leave clash-verge:// unregistered even though Tauri lists both schemes. — [src-tauri/packages/linux/clash-verge.desktop#L10](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/packages/linux/clash-verge.desktop#L10) [src-tauri/src/utils/init.rs#L569-L597](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/init.rs#L569-L597) [src-tauri/tauri.conf.json#L44-L47](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/tauri.conf.json#L44-L47)

## Extension points

New behavior is expected to plug into a few explicit tables rather than into new processes. IPC commands go in cmd/ and generate_handlers. UI routes go in navigationItems. Hotkeys, tray items, URI schemes, and media-unlock checks are enums or maps. Profile enhancement is a fixed chain of merge and script items plus two builtin JS files, not a dynamic plugin loader. The Draft type and Run State are the shared extension surfaces for config and service status.
- New Tauri commands must be added as #[tauri::command] functions under src-tauri/src/cmd/ and listed in app_init::generate_handlers. The module re-exports each command module from cmd/mod.rs. — [src-tauri/src/lib.rs#L126-L216](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L126-L216) [src-tauri/src/cmd/mod.rs#L94-L129](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/mod.rs#L94-L129)
- Frontend routes are data, not a nested route file tree. Adding a page means a navigationItems entry plus a navItems Component. The router maps those path/Component pairs and nothing else. — [src/pages/_navigation-meta.ts](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/pages/_navigation-meta.ts) [src/pages/_navigation.tsx#L37-L78](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/pages/_navigation.tsx#L37-L78) [src/pages/_routers.tsx](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/pages/_routers.tsx)
- Hotkey functions are the HotkeyFunction enum plus FromStr names. Adding a shortcut means extending that enum and the register path in core/hotkey.rs; unknown names bail with invalid hotkey function. — [src-tauri/src/core/hotkey.rs#L21-L74](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/hotkey.rs#L21-L74)
- Tray labels and ids are generated by the define_menu! macro in core/tray/menu_def.rs, with display strings looked up through clash_verge_i18n::t. A new tray row is a new macro entry, not a free-form menu builder at the call site. — [src-tauri/src/core/tray/menu_def.rs#L1-L51](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/tray/menu_def.rs#L1-L51)
- Share-link import extends URI_PARSERS in src/utils/uri-parser/index.ts. Each scheme maps to a function (uri) => IProxyConfig. — [src/utils/uri-parser/index.ts#L15-L40](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/utils/uri-parser/index.ts#L15-L40)
- A new streaming check is an UnlockCheck variant in crates/clash-verge-media-unlock/src/lib.rs, a name() match arm, an ALL entry, and a module such as netflix.rs. The UI calls get_unlock_items and check_media_unlock; it does not hardcode the list. — [crates/clash-verge-media-unlock/src/lib.rs#L26-L80](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/crates/clash-verge-media-unlock/src/lib.rs#L26-L80) [src-tauri/src/cmd/media_unlock_checker/mod.rs#L6-L9](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/media_unlock_checker/mod.rs#L6-L9)
- Profile enhancement extension points are per-profile and global ChainItems of type merge, script, rules, proxies, and groups, applied by process_seq_items, process_global_items, and process_profile_items. Builtin JS is the fixed pair meta_guard.js and meta_hy_alpn.js under enhance/builtin/, gated by enable_builtin_enhanced. — [src-tauri/src/enhance/mod.rs#L50-L98](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/enhance/mod.rs#L50-L98) [src-tauri/src/enhance/mod.rs#L914-L956](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/enhance/mod.rs#L914-L956)
- Backend user-visible strings go through crates/clash-verge-i18n, which loads YAML locales with rust_i18n and falls back to zh. Frontend strings are JSON under src/locales, with generated key types from pnpm i18n:types. — [crates/clash-verge-i18n/src/lib.rs#L1-L8](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/crates/clash-verge-i18n/src/lib.rs#L1-L8) [Makefile.toml#L58-L74](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/Makefile.toml#L58-L74)
- Service vs sidecar policy is the startup_decision function over ServiceStatus, plus Run State in core/runstate. New install/repair outcomes should map there rather than grow a second status enum in the UI. — [src-tauri/src/core/manager/lifecycle.rs#L40-L49](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/lifecycle.rs#L40-L49) [src-tauri/src/core/service.rs#L154-L180](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/service.rs#L154-L180)
- Verge and profile mutations are supposed to go through DraftTransaction and Config::lock_config_write, not direct YAML writes. patch_verge and generate_with_profiles are the two patterns. — [src-tauri/src/feat/config.rs#L296-L321](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/feat/config.rs#L296-L321) [src-tauri/src/config/config.rs#L224-L248](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/config/config.rs#L224-L248)
- Frontend event names are the VergeEvents map in src/services/events.ts. A new backend emit is invisible to React until that map and a subscribeVergeEvents handler both include it. — [src/services/events.ts#L6-L36](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/services/events.ts#L6-L36)
- Command failures that the UI can classify should use CommandFailure::coded or SysproxyFailure codes. proxy_aware_coded_error lets a proxy classification outrank the operation fallback such as CORE_RESTART_FAILED. — [src-tauri/src/cmd/mod.rs#L6-L91](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/mod.rs#L6-L91) [src-tauri/src/cmd/mod.rs#L204-L214](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/cmd/mod.rs#L204-L214)

## Contributor handoff

Read AGENTS.md before editing: non-trivial work needs an existing issue, the diff must match that issue, and tests are not a default. Start from lib.rs generate_handlers, cmds.ts, and the config/core modules that own the behavior you touch. Respect draft transactions and the config-then-lifecycle lock order. Verify with pnpm typecheck, pnpm lint, and targeted cargo tests; do not assume CI runs the suite. Do not hand-edit the AI-slop review lockfile, and do not treat the webview capability set as a tight sandbox.
- AGENTS.md requires a pre-existing issue for non-trivial changes, English Conventional Commits, changelog lines per template/Changelog.md, and no drive-by refactors or dependency bumps. Tests are added only when the issue needs a regression guard. AI-assisted PRs append an Assisted by footer. The policy file pr-ai-slop-review.md is compiled; never edit pr-ai-slop-review.lock.yml by hand. — [AGENTS.md](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/AGENTS.md) [CONTRIBUTING.md#L9-L23](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/CONTRIBUTING.md#L9-L23)
- Files to read first for any behavior change: src-tauri/src/lib.rs (startup and command table), src-tauri/src/utils/resolve/mod.rs (init order), src-tauri/src/config/config.rs and enhance/mod.rs (runtime YAML), src-tauri/src/core/manager/lifecycle.rs (service vs sidecar), and src/services/cmds.ts plus src/services/events.ts (UI seam). — [src-tauri/src/lib.rs](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs) [src-tauri/src/utils/resolve/mod.rs](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/resolve/mod.rs) [src-tauri/src/enhance/mod.rs](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/enhance/mod.rs) [src/services/cmds.ts](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/services/cmds.ts)
- A command implemented only in Rust or only in cmds.ts will not complete a user action. generate_handlers and the invoke wrappers are separate registries and nothing generates one from the other. (inferred) — [src-tauri/src/lib.rs#L126-L216](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L126-L216) [src/services/cmds.ts#L9-L14](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/services/cmds.ts#L9-L14)
- Safe local checks that match repo tooling: pnpm typecheck, pnpm lint (eslint max-warnings 0), pnpm test, cargo fmt, and cargo clippy --all-targets --all-features -- -D warnings as in Makefile.toml. pnpm dev preserves an existing dev-channel service; pnpm dev:service installs it; pnpm dev:sidecar forces the unprivileged sidecar. — [package.json#L5-L36](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/package.json#L5-L36) [Makefile.toml#L15-L18](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/Makefile.toml#L15-L18) [README.md#L103-L113](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/README.md#L103-L113)
- Feature verge-dev changes APP_ID to io.github.clash-verge-rev.clash-verge-rev.dev and the backup directory name, and selects the service IPC development channel. Production and dev installs do not share app data. Do not point tests at the production id. — [src-tauri/src/utils/dirs.rs#L11-L19](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/dirs.rs#L11-L19) [src-tauri/Cargo.toml#L20-L21](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/Cargo.toml#L20-L21)
- Window close is hide, not quit. Exit and lightweight mode both call prevent_exit. A change that calls app.exit or stops the core must go through feat::quit or the session-ending cleanup, or the singleton server and system proxy can be left up. — [src-tauri/src/lib.rs#L374-L387](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L374-L387) [src-tauri/src/lib.rs#L487-L498](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/lib.rs#L487-L498) [src-tauri/src/feat/window.rs#L113-L141](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/feat/window.rs#L113-L141)
- Do not write verge.yaml by calling serde outside with_encryption. WebDAV fields serialize as plaintext unless ENCRYPTION_ACTIVE is set. help::save_yaml is the path that turns the flag on. — [src-tauri/src/config/encrypt.rs#L52-L92](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/config/encrypt.rs#L52-L92) [src-tauri/src/utils/help.rs#L1-L23](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/utils/help.rs#L1-L23) [src-tauri/src/config/verge.rs#L168-L190](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/config/verge.rs#L168-L190)
- Hold Config::lock_config_write before the core lifecycle lock when a patch also starts or stops the core. The comments on continue_with_sidecar and uninstall_service_and_start_sidecar describe cross-transaction draft commits if that order flips. — [src-tauri/src/core/manager/lifecycle.rs#L370-L374](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/lifecycle.rs#L370-L374) [src-tauri/src/feat/config.rs#L291-L294](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/feat/config.rs#L291-L294)
- Mixed-port startup can rewrite the runtime port up to three retries. UI code should use MixedPort helpers and use-displayed-mixed-port rather than assuming 7897 after a failed bind. — [src-tauri/src/core/manager/mod.rs#L256-L287](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/core/manager/mod.rs#L256-L287) [src-tauri/src/constants.rs#L11](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/src/constants.rs#L11) [src/utils/mixed-port.ts](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src/utils/mixed-port.ts)
- i18n key types are generated. After editing locale JSON, pnpm i18n:types and the cleanup script are the repo's own tools; do not hand-maintain src/types/generated if the script owns it. Backend tray strings live in crates/clash-verge-i18n locales, default zh. — [package.json#L30-L32](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/package.json#L30-L32) [crates/clash-verge-i18n/src/lib.rs#L5-L6](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/crates/clash-verge-i18n/src/lib.rs#L5-L6) [Makefile.toml#L58-L74](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/Makefile.toml#L58-L74)
- pnpm run prebuild is required before a real core start because Mihomo and the service binary are downloaded, not stored as source. CI requires an explicit rustc target triple or prebuild throws. — [scripts/prebuild.mjs#L54-L70](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/scripts/prebuild.mjs#L54-L70) [CONTRIBUTING.md#L74-L78](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/CONTRIBUTING.md#L74-L78) [README.md#L103-L107](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/README.md#L103-L107)
- Edition 2024 and the deny-level workspace clippy set mean new unwrap, panic, todo, and unimplemented will fail lint. Match surrounding Result/CommandFailure style instead of adding unwrap. — [Cargo.toml#L137-L162](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/Cargo.toml#L137-L162) [src-tauri/Cargo.toml#L10-L11](https://github.com/clash-verge-rev/clash-verge-rev/blob/fd06fbb3b71ee5c4467bc0e3cc505dcac5348371/src-tauri/Cargo.toml#L10-L11)

Source repository: https://github.com/clash-verge-rev/clash-verge-rev
Full evidence corpus: https://github.com/Codevetter/codevetter/tree/main/benchmarks/repo-unpacks/clash-verge-rev.json

## Public product links

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