CAS-2552 — Plugin-dep symmetry check
CAS-2552 — Plugin-dep symmetry check
Shipped: 2026-05-13 (PR #658, feat(CAS-2556))
Root cause it prevents: CAS-2516 — iOS submit silently fell through to local mode because @tauri-apps/plugin-os existed in package.json but tauri-plugin-os was missing from Cargo.toml. The plugin call threw, the catch returned false (wrong default), and submit used the wrong path on iPhone.
What was added
scripts/check-tauri-plugin-symmetry.sh — a build-time invariant checker that enforces three-way symmetry across the plugin dependency graph:
@tauri-apps/plugin-* (package.json)tauri-plugin-* (src-tauri/Cargo.toml)Any @tauri-apps/plugin-* in package.json must have a matching tauri-plugin-* in Cargo.toml, and vice versa (with an explicit exemption list for plugins that are Rust-only by design).
Exits 0 on full symmetry, 1 with an actionable diff when there is a mismatch.
Where it runs
- CI (
.github/workflows/ci.yml) — blocks the build on any plugin asymmetry. - Pre-commit (
deno.json) — catches it before push. - Manual:
bash scripts/check-tauri-plugin-symmetry.shfrom the repo root.
Exemption mechanism
RUST_ONLY_PLUGINS array at the top of the script lists plugins that live in Cargo but have no @tauri-apps/plugin-* counterpart by design. Each entry must include a comment explaining why the JS side is absent.
Current exemption: plugin-deep-link (frontend uses a custom event bridge; no @tauri-apps/plugin-deep-link import).
Adding a new Tauri plugin
- Add
@tauri-apps/plugin-<name>topackage.json. - Add
tauri-plugin-<name>tosrc-tauri/Cargo.toml. - Add
.plugin(tauri_plugin_<name>::init())tosrc-tauri/src/lib.rs. - Run
bash scripts/check-tauri-plugin-symmetry.sh— should exit 0.
Missing step 2 or 3 will fail CI and pre-commit.