You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Type more IPC commands + sustainability for the bindings
Tightens the typed-IPC surface added in `f1e58011` and shores up the regen / sustainability story.
Group A — drop `skip_serializing_if` to unblock specta
Removed `#[serde(skip_serializing_if = "Option::is_none")]` (and `Vec::is_empty` variants) from `FileEntry`, `PaneState`, `MtpDeviceInfo`, `MtpStorageInfo`, `LocationInfo` (macOS / Linux / stub), `NetworkHost`, and `BundleManifest` fields. Wire format goes from "field absent" to explicit `null` / `[]`. specta's `validate_exported_command` now accepts the types, unblocking 9 commands: `get_file_range`, `get_file_at`, `get_files_at_indices`, `update_left_pane_state`, `update_right_pane_state`, `list_mtp_devices`, `connect_mtp_device`, `get_mtp_device_info`, `get_mtp_storages`, `list_mtp_directory`, `list_volumes`, `resolve_path_volume`, `list_network_hosts`, `resolve_host`, `connect_to_server`.
FE side: migrated each call site from raw `invoke()` to `commands.foo(...)`, dropped the `cmdr/no-raw-tauri-invoke` opt-out comments, fixed four `=== undefined` → `!= null` patterns that the change broke (`smbConnectionState`, `recursiveSize`, `displaySize` × 2). Renamed an inner `FileEntry` in `mcp/pane_state.rs` to `PaneFileEntry` to avoid a name collision with the real `FileEntry` once both types crossed the IPC boundary.
Group B (first 3) — replace `serde_json::Value` at IPC boundaries
- `check_pending_crash_report` / `send_crash_report`: dropped the noop `serde_json::to_value` / `Value` wrapper. The commands now take/return `CrashReport` directly. `CrashReport` and `ActiveSettings` got `#[derive(specta::Type)]` (kept `Deserialize` since the on-disk crash file format still round-trips through it).
- `record_settings_defaults`: replaced `HashMap<String, serde_json::Value>` with `HashMap<String, SettingValue>` where `SettingValue` is an untagged `Bool | Integer | String` enum. The TS surface lands as `boolean | number | string` — covers every value type the registry actually carries.
`record_breadcrumb` stays on raw `invoke()` deliberately. Free-form `ctx` is the design intent for breadcrumbs; none of the typed alternatives (string-only map, JSON-encoded string, tagged-union by `kind`) is genuinely better. `prepare_error_report_preview` stays excluded for the same reason (its `BundleManifest.breadcrumbs` carries the same `Option<Value>`); a future decoupling via `BreadcrumbForManifest { ctx_json: Option<String> }` is documented in `lib/ipc/CLAUDE.md` if it ever becomes worthwhile.
Sustainability wiring
- `export_bindings_test` is now `#[ignore]`d so plain `cargo nextest run` doesn't silently rewrite `bindings.ts` as a test side effect.
- `pnpm bindings:regen` (in `apps/desktop/package.json`) is the canonical regen command — runs the ignored test, then `oxfmt`s the output so the file lands in project format (single quotes, no semis, 2-space indent — which is what `oxfmt` enforces; my earlier confusion about "oxfmt is lenient" was wrong, the file just was already formatted).
- `bindings-fresh` check (Go, `desktop-bindings-fresh.go`) snapshots the committed file, runs the regen, byte-compares, restores the snapshot. Fails on drift with a pointer to `pnpm bindings:regen`. CI catches stale bindings without touching the working tree.
- `lib/ipc/CLAUDE.md` documents the named-variables call-site convention, the "adding a new Tauri command" recipe, the type-shape constraints (`skip_serializing_if`, `serde_json::Value`), the trimmed exclusion table, the version-bump procedure, and the future-work decoupling note.
- `lib/tauri-commands/CLAUDE.md` § Key patterns now reflects that wrappers delegate to the typed bindings; raw `invoke` is the exception (with the documented opt-out).
- AGENTS.md "Type-safe IPC" entry links to the regen flow and the named-variables rule.
- `knip.json` ignores `oxfmt` as an unlisted binary (used by `bindings:regen`).
Numbers
- 4 commands remain excluded (down from 14): `record_breadcrumb`, `prepare_error_report_preview`, `store_font_metrics`, `stream_folder_suggestions`/`cancel_folder_suggestions`. Each has a documented reason and conversion plan.
- All 45 checks pass. 1601 Rust + 1716 Svelte + 124 API + 67 Astro e2e + 28 Rust integration tests pass. `bindings-fresh` confirms `bindings.ts` is in sync.
0 commit comments