Skip to content

IPC events: event names as Rust constants and a lint check that every frontend listener matches an emitted event #918

Open

Description

@smart-ssh-planner

Goal

Renaming an event on one side without the other makes npm run lint fail, instead of the UI silently missing updates.

Context

  • Rust emits events through ~45 emit_* helpers in crates/app-logic/src/events.rs (private fn emit(emitter, event: &str, payload) at :37, string literals like "data-changed" at :77), plus direct emits in crates/app-shell/src/lib.rs ("entitlements:changed", :1066), crates/app-shell/src/event_emitter.rs and crates/app-logic/src/auto_reconnect.rs.
  • The frontend subscribes in apps/smart-ssh-community/frontend/src/events.ts (~47 distinct names via listen("…")) and in a few components.
  • scripts/check-tauri-commands.mjs (Issue Check Tauri command definitions, registrations and frontend calls in CI #101, run as part of npm run lint) checks command names (definition ↔ generate_handler! ↔ invoke("…") ↔ ALLOWED_WHILE_LOCKED) but not event names. Today the names match (manually checked); nothing keeps it that way.
  • Header comment of src/types.ts:1 still says the DTOs live in crates/app-shell/src/dto.rs; they are in crates/app-logic/src/dto.rs.

Requirements

  • crates/app-logic/src/events.rs: one pub mod names { pub const DATA_CHANGED: &str = "data-changed"; … } with every event name the core emits; all emit_* helpers and the direct emits in app-shell/auto_reconnect.rs use these constants. No event name literal remains at an emit site.
  • Frontend: src/eventNames.ts with the same names as export const EVENT = { DATA_CHANGED: "data-changed", … } as const; events.ts and components listen via these constants.
  • Extend scripts/check-tauri-commands.mjs (or a sibling check-event-names.mjs added to npm run lint): parse the names module (text-based, like the existing script) and eventNames.ts; fail when (a) a frontend constant has no Rust counterpart, (b) a listen(/once( call uses a string literal instead of a constant, (c) a Rust constant is not in the frontend list – allowed only if listed in an explicit "not consumed by the core UI" allowlist with a reason (extensions may consume them). Events emitted by extensions (plugin events) are out of scope.
  • Fix the types.ts header path.
  • Unit tests for the new check in the style of tauriCommandsCheck.test.ts.

Acceptance Criteria

  • All core event names are constants; grep -n 'emit(emitter, "' crates/app-logic/src/events.rs returns nothing.
  • npm run lint fails for: a renamed Rust constant, a renamed frontend constant, a listen("literal") (each proven by a unit test of the check on fixtures).
  • npm run lint passes on the real code; existing event tests (Rust and frontend) pass.
  • types.ts header names crates/app-logic/src/dto.rs.

Technical Notes

  • Payload types are not covered here (generated types issue).
  • events.rs carries no secrets in payloads (uses_stored_sudo_password: bool, events.rs ~:378); keep it that way.

Spec impact: none

Related Work

Activity

  1. added this to the 0.8.0 milestone on Oct 26, 2026
  2. 4 remaining items

  3. marked this as blocked by 15 issues on Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Fields

    Priority

    P2 - Normal

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions