Binary protocol encoder/decoder for GUI chrome commands (BEAM → Swift/GTK).
This module handles the structured data protocol for native GUI elements:
tab bars, file trees, which-key popups, completion menus, breadcrumbs,
status bars, pickers, agent chat, and theme colors. These are separate
from the TUI cell-grid rendering commands in MingaEditor.Frontend.Protocol.
GUI Chrome Commands (BEAM → Frontend)
GUI chrome opcodes start at 0x70. Newer commands use the 0x90+ length-prefixed envelope so frontends can skip unknown messages.
| Opcode | Name | Description |
|---|---|---|
| 0x93 | gui_file_tree | Semantic file tree state |
| 0x94 | gui_file_tree_selection | File tree selection-only update |
| 0x71 | gui_tab_bar | Tab bar with tab entries |
| 0x72 | gui_which_key | Which-key popup bindings |
| 0x73 | gui_completion | Completion popup items |
| 0x74 | gui_theme | Theme color slots |
| 0x75 | gui_breadcrumb | Path breadcrumb segments |
| 0x76 | gui_status_bar | Status bar data |
| 0x77 | gui_picker | Fuzzy picker items + mode prefix |
| 0x78 | gui_agent_chat | Agent conversation view |
| 0x79 | gui_gutter_sep | Gutter separator col + color |
| 0x7A | gui_cursorline | Cursorline row + bg color |
| 0x7B | gui_gutter | Structured gutter data |
| 0x7C | gui_bottom_panel | Bottom panel container state |
| 0x7D | gui_picker_preview | Picker preview content |
| 0x7F | gui_minibuffer | Native minibuffer + candidates |
| 0x81 | gui_hover_popup | Native hover tooltip popup |
| 0x82 | gui_signature_help | Signature help popup |
| 0x83 | gui_float_popup | Float popup window |
| 0x84 | gui_split_separators | Split pane separator lines |
| 0x85 | gui_git_status | Git status panel data |
| 0x98 | gui_workspaces | Canonical workspace state |
| 0x97 | gui_config_state | Settings panel state |
| 0x9E | gui_search_state | Search toolbar state |
| 0x9F | gui_sidebars | Semantic sidebar metadata |
| 0xA3 | gui_extension_runtime | Generic extension-owned frontend runtime envelope |
GUI Actions (Frontend → BEAM)
| Sub-opcode | Name |
|---|---|
| 0x01 | select_tab |
| 0x02 | close_tab |
| 0x03 | file_tree_click |
| 0x04 | file_tree_toggle |
| 0x05 | completion_select |
| 0x06 | breadcrumb_click |
| 0x07 | toggle_panel |
| 0x08 | new_tab |
| 0x09 | panel_switch_tab |
| 0x0A | panel_dismiss |
| 0x0B | panel_resize |
| 0x0C | open_file |
| 0x0D | file_tree_new_file |
| 0x0E | file_tree_new_folder |
| 0x2D | file_tree_edit_confirm |
| 0x2E | file_tree_edit_cancel |
| 0x2F | scroll_to_line |
| 0x30 | file_tree_delete |
| 0x0F | file_tree_collapse_all |
| 0x10 | file_tree_refresh |
| 0x15 | agent_tool_toggle |
| 0x16 | execute_command |
| 0x17 | minibuffer_select |
| 0x18 | git_stage_file |
| 0x19 | git_unstage_file |
| 0x1A | git_discard_file |
| 0x1B | git_stage_all |
| 0x1C | git_unstage_all |
| 0x1D | git_commit |
| 0x1E | git_open_file |
| 0x1F | workspace_rename |
| 0x20 | workspace_set_icon |
| 0x21 | workspace_close |
| 0x3D | file_tree_open_in_split |
| 0x3E | tab_copy_path |
| 0x3F | hover_open_action |
| 0x40 | file_tree_drop |
| 0x41 | fold_toggle_at_line |
| 0x42 | git_open_diff |
| 0x43 | config_update |
| 0x44 | config_query |
| 0x47 | power_thermal_state |
| 0x48 | tab_reorder |
| 0x49 | tab_pin |
| 0x4A | tab_unpin |
| 0x4B | tab_move_left |
| 0x4C | tab_move_right |
| 0x4D | observatory_inspect |
| 0x4E | font_size_adjust |
| 0x4F | timeline_navigate |
| 0x50 | extension_panel_action |
| 0x51 | search_query |
| 0x52 | search_next |
| 0x53 | search_prev |
| 0x54 | search_replace |
| 0x55 | search_replace_all |
| 0x56 | search_dismiss |
| 0x57 | sidebar_action |
| 0x58 | extension_action |
| 0x34 | system_will_sleep |
| 0x35 | system_did_wake |
| 0x5A | system_will_unmount |
| 0x5C | chat_scrolled_away_from_bottom |
| 0x5D | chat_returned_to_bottom |
| 0x5F | picker_query_changed |
Summary
Types
Clipboard target for the write opcode.
Settings state payload sent to native settings UI.
Git toast data shown after a remote operation completes.
Git toast action for error recovery.
A semantic GUI action from the Swift/GTK frontend.
Read-only keybinding entry sent to native settings UI.
Theme preview swatch sent to native settings UI.
macOS thermal pressure level reported by the native GUI frontend.
Functions
Builds a full settings state payload from the current config and keymap servers.
Decodes a GUI action sub-opcode and its payload into a gui_action() tuple.
Unpacks a search flags byte into a keyword list of booleans.
Encodes a clipboard_write command.
Encodes a generic frontend-extension runtime message.
Types
@type clipboard_target() :: :general | :find
Clipboard target for the write opcode.
@type config_state() :: %{ options: %{required(Minga.Config.Options.option_name()) => term()}, theme_previews: [theme_preview()], keybindings: [keybinding_entry()] }
Settings state payload sent to native settings UI.
@type git_toast() :: %{ :message => String.t(), :level => :success | :error, :action => git_toast_action(), optional(:dismiss_ref) => reference() }
Git toast data shown after a remote operation completes.
@type git_toast_action() :: :pull_and_retry | nil
Git toast action for error recovery.
@type gui_action() :: {:select_tab, id :: pos_integer()} | {:close_tab, id :: pos_integer()} | {:empty_state_activate, item_id :: String.t()} | {:file_tree_click, index :: non_neg_integer()} | {:file_tree_toggle, index :: non_neg_integer()} | {:completion_select, index :: non_neg_integer()} | {:breadcrumb_click, segment_index :: non_neg_integer()} | {:toggle_panel, panel :: non_neg_integer()} | :new_tab | {:panel_switch_tab, tab_index :: non_neg_integer()} | :panel_dismiss | {:panel_resize, height_percent :: non_neg_integer()} | {:open_file, path :: String.t()} | {:file_tree_new_file, index :: non_neg_integer()} | {:file_tree_new_folder, index :: non_neg_integer()} | {:file_tree_edit_confirm, text :: String.t()} | :file_tree_edit_cancel | :file_tree_collapse_all | :file_tree_refresh | {:agent_tool_toggle, message_id :: non_neg_integer()} | {:execute_command, name :: String.t()} | {:minibuffer_select, candidate_index :: non_neg_integer()} | {:git_stage_file, path :: String.t()} | {:git_unstage_file, path :: String.t()} | {:git_discard_file, path :: String.t()} | :git_stage_all | :git_unstage_all | {:git_commit, message :: String.t()} | {:git_commit, message :: String.t(), amend? :: boolean()} | {:git_open_file, path :: String.t()} | {:git_open_diff, path :: String.t(), section :: non_neg_integer()} | {:workspace_rename, id :: non_neg_integer(), name :: String.t()} | {:workspace_set_icon, id :: non_neg_integer(), icon :: String.t()} | {:workspace_close, id :: non_neg_integer()} | {:space_leader_chord, codepoint :: non_neg_integer(), modifiers :: non_neg_integer()} | {:space_leader_retract, codepoint :: non_neg_integer(), modifiers :: non_neg_integer()} | {:find_pasteboard_search, text :: String.t(), direction :: non_neg_integer()} | :agent_approve | :agent_request_changes | :agent_dismiss | {:change_summary_click, index :: non_neg_integer()} | {:file_tree_delete, index :: non_neg_integer()} | {:file_tree_rename, index :: non_neg_integer()} | {:file_tree_duplicate, index :: non_neg_integer()} | {:file_tree_move, source_index :: non_neg_integer(), target_dir_index :: non_neg_integer()} | {:file_tree_drop, MingaEditor.FileTree.DropIntent.t()} | {:fold_toggle_at_line, window_id :: non_neg_integer(), buffer_line :: non_neg_integer()} | {:file_tree_open_in_split, index :: non_neg_integer()} | {:tab_copy_path, id :: pos_integer()} | {:tab_reorder, id :: pos_integer(), new_index :: non_neg_integer()} | {:tab_pin, id :: pos_integer()} | {:tab_unpin, id :: pos_integer()} | {:tab_move_left, id :: pos_integer()} | {:tab_move_right, id :: pos_integer()} | :hover_open_action | :system_will_sleep | :system_did_wake | {:system_will_unmount, volume_path :: String.t()} | {:power_thermal_state, low_power? :: boolean(), thermal_state()} | :cmd_copy | :cmd_cut | :git_push | :git_pull | :git_fetch | {:git_commit_amend, message :: String.t()} | :git_pull_and_retry | {:config_update, Minga.Config.Options.option_name(), term()} | :config_query | {:notification_dismiss, notification_id :: String.t()} | {:notification_action, notification_id :: String.t(), action_id :: String.t()} | {:observatory_inspect, pid_string :: String.t()} | {:font_size_adjust, direction :: :decrease | :increase | :reset} | {:picker_query_changed, generation :: non_neg_integer(), edit_seq :: non_neg_integer(), query :: String.t()} | {:search_query, query :: String.t(), flags :: non_neg_integer()} | :search_next | :search_prev | {:search_replace, replacement :: String.t()} | {:search_replace_all, replacement :: String.t()} | :search_dismiss | {:sidebar_action, sidebar_id :: String.t(), kind :: String.t(), action :: String.t()} | {:extension_panel_action, ext_name :: String.t(), action_name :: String.t(), context :: map()} | {:extension_action, extension_id :: String.t(), action :: String.t(), payload :: binary()} | :float_popup_dismiss | :chat_scrolled_away_from_bottom | :chat_returned_to_bottom
A semantic GUI action from the Swift/GTK frontend.
@type keybinding_entry() :: %{ mode: String.t(), key: String.t(), command: String.t(), description: String.t() }
Read-only keybinding entry sent to native settings UI.
@type theme_preview() :: %{ name: String.t(), atom: String.t(), editor_bg: non_neg_integer(), editor_fg: non_neg_integer(), accent: non_neg_integer() }
Theme preview swatch sent to native settings UI.
@type thermal_state() :: :nominal | :fair | :serious | :critical | {:unknown, non_neg_integer()}
macOS thermal pressure level reported by the native GUI frontend.
Functions
@spec config_state(Minga.Config.Options.server(), Minga.Keymap.server()) :: config_state()
Builds a full settings state payload from the current config and keymap servers.
@spec decode_gui_action(non_neg_integer(), binary()) :: {:ok, gui_action()} | :error
Decodes a GUI action sub-opcode and its payload into a gui_action() tuple.
Called from Protocol.decode_event/1 when the outer opcode is 0x07 (gui_action).
@spec decode_search_flags(non_neg_integer()) :: [ replace_mode: boolean(), case_sensitive: boolean(), whole_word: boolean(), regex: boolean() ]
Unpacks a search flags byte into a keyword list of booleans.
@spec encode_clipboard_write(String.t(), clipboard_target()) :: binary()
Encodes a clipboard_write command.
Uses the forward-compatible 0x90+ format: opcode(1) + payload_length(4) + payload. Payload: target(1) + text_length(4) + text(text_length).
Target: 0 = general pasteboard (Cmd+C), 1 = find pasteboard (Cmd+E).
Encodes a generic frontend-extension runtime message.
Shared protocol owns only the envelope. The named frontend extension owns the payload schema and decoder.
Format: opcode(1) + payload_length(4) + extension_id_len(2) + extension_id + channel_len(2) + channel + payload.