CodeVetter · Repo Unpack · Contributor handoff
clash-verge-rev/clash-verge-rev
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.
- 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).
- 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)
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.