syntax = "proto3"; // Open API Phase 4a (docs/architecture/HOTKEYS_AUTOMATION_API.md §5) — mirrors the App-side // Action Registry (Ngs.AuraMixer.App/Services/Actions) 1:1, so external callers (Stream Deck // plugins, Bitfocus Companion modules, later a browser panel over gRPC-Web) bind to the same // stable action-id + project-local-target-id-with-label abstraction Hotkeys/Automation already // use, instead of raw mixer.proto parameter indices. Relayed through Ngs.AuraMixer.App — this // does NOT reach EngineHost/AuraEngine.exe directly; InvokeAction calls IActionRegistry.TryExecute, // which itself calls IMixerStateService (the same path a hotkey or automation rule takes). // // Full architecture: docs/architecture/HOTKEYS_AUTOMATION_API.md §5. option csharp_namespace = "Ngs.AuraMixer.Api.Proto"; package auramixer.actions; import "google/protobuf/empty.proto"; // ============================================================ // ACTIONS — the shared Action Registry, exposed to external callers // ============================================================ service ActionsService { // Lets a caller build its own picker (Stream Deck action list, partner panel UI) without // hardcoding Aura's action catalog — mirrors IActionRegistry.All. rpc ListActions(google.protobuf.Empty) returns (ActionList); // Mirrors IActionRegistry.TryExecute. Unknown action_id, or a missing target_id on an // action that RequiresTarget, both come back as ok=false with a human-readable error — // never a thrown gRPC status, so a plugin author doesn't need per-call try/catch. rpc InvokeAction(InvokeActionRequest) returns (InvokeActionResponse); // Live push of mixable-entity state (mute/solo/fader) for icon/UI feedback — e.g. a Stream // Deck button reflecting current mute state instead of firing blind. Fires a fresh full // snapshot on every IMixerStateService.EntityChanged; a caller only interested in specific // ids simply ignores the rest. rpc StreamState(google.protobuf.Empty) returns (stream MixerStateSnapshot); } message ActionDefinition { string id = 1; // stable, namespaced — e.g. "mixer.setMuted" string display_name = 2; string category = 3; bool requires_target = 4; string target_kind = 5; // "mixable" | "bus" | "channel" bool requires_secondary_target = 6; bool uses_value = 7; bool uses_delta = 8; bool supports_momentary = 9; } message ActionList { repeated ActionDefinition actions = 1; } message InvokeActionRequest { string action_id = 1; string target_id = 2; // project-local entity id, per HOTKEYS_AUTOMATION_API.md §1 string secondary_target_id = 3; optional float value = 4; optional float delta = 5; optional bool flag = 6; // unset = "toggle" for actions that support it } message InvokeActionResponse { bool ok = 1; string error = 2; // empty when ok } message MixerEntityState { string id = 1; string name = 2; // cached display label — same ID+label convention as bindings string kind = 3; // "channel" | "group" | "output" | "mainBus" bool muted = 4; bool soloed = 5; float fader_db = 6; } message MixerStateSnapshot { repeated MixerEntityState entities = 1; }