Skip to content

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.sh from 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

  1. Add @tauri-apps/plugin-<name> to package.json.
  2. Add tauri-plugin-<name> to src-tauri/Cargo.toml.
  3. Add .plugin(tauri_plugin_<name>::init()) to src-tauri/src/lib.rs.
  4. Run bash scripts/check-tauri-plugin-symmetry.sh — should exit 0.

Missing step 2 or 3 will fail CI and pre-commit.