MingaEditor.Frontend.Protocol.GUI (Minga v0.1.0)

Copy Markdown View Source

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.

OpcodeNameDescription
0x93gui_file_treeSemantic file tree state
0x94gui_file_tree_selectionFile tree selection-only update
0x71gui_tab_barTab bar with tab entries
0x72gui_which_keyWhich-key popup bindings
0x73gui_completionCompletion popup items
0x74gui_themeTheme color slots
0x75gui_breadcrumbPath breadcrumb segments
0x76gui_status_barStatus bar data
0x77gui_pickerFuzzy picker items + mode prefix
0x78gui_agent_chatAgent conversation view
0x79gui_gutter_sepGutter separator col + color
0x7Agui_cursorlineCursorline row + bg color
0x7Bgui_gutterStructured gutter data
0x7Cgui_bottom_panelBottom panel container state
0x7Dgui_picker_previewPicker preview content
0x7Fgui_minibufferNative minibuffer + candidates
0x81gui_hover_popupNative hover tooltip popup
0x82gui_signature_helpSignature help popup
0x83gui_float_popupFloat popup window
0x84gui_split_separatorsSplit pane separator lines
0x85gui_git_statusGit status panel data
0x98gui_workspacesCanonical workspace state
0x97gui_config_stateSettings panel state
0x9Egui_search_stateSearch toolbar state
0x9Fgui_sidebarsSemantic sidebar metadata
0xA3gui_extension_runtimeGeneric extension-owned frontend runtime envelope

GUI Actions (Frontend → BEAM)

Sub-opcodeName
0x01select_tab
0x02close_tab
0x03file_tree_click
0x04file_tree_toggle
0x05completion_select
0x06breadcrumb_click
0x07toggle_panel
0x08new_tab
0x09panel_switch_tab
0x0Apanel_dismiss
0x0Bpanel_resize
0x0Copen_file
0x0Dfile_tree_new_file
0x0Efile_tree_new_folder
0x2Dfile_tree_edit_confirm
0x2Efile_tree_edit_cancel
0x2Fscroll_to_line
0x30file_tree_delete
0x0Ffile_tree_collapse_all
0x10file_tree_refresh
0x15agent_tool_toggle
0x16execute_command
0x17minibuffer_select
0x18git_stage_file
0x19git_unstage_file
0x1Agit_discard_file
0x1Bgit_stage_all
0x1Cgit_unstage_all
0x1Dgit_commit
0x1Egit_open_file
0x1Fworkspace_rename
0x20workspace_set_icon
0x21workspace_close
0x3Dfile_tree_open_in_split
0x3Etab_copy_path
0x3Fhover_open_action
0x40file_tree_drop
0x41fold_toggle_at_line
0x42git_open_diff
0x43config_update
0x44config_query
0x47power_thermal_state
0x48tab_reorder
0x49tab_pin
0x4Atab_unpin
0x4Btab_move_left
0x4Ctab_move_right
0x4Dobservatory_inspect
0x4Efont_size_adjust
0x4Ftimeline_navigate
0x50extension_panel_action
0x51search_query
0x52search_next
0x53search_prev
0x54search_replace
0x55search_replace_all
0x56search_dismiss
0x57sidebar_action
0x58extension_action
0x34system_will_sleep
0x35system_did_wake
0x5Asystem_will_unmount
0x5Cchat_scrolled_away_from_bottom
0x5Dchat_returned_to_bottom
0x5Fpicker_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

clipboard_target()

@type clipboard_target() :: :general | :find

Clipboard target for the write opcode.

config_state()

@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.

git_toast()

@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.

git_toast_action()

@type git_toast_action() :: :pull_and_retry | nil

Git toast action for error recovery.

gui_action()

@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.

keybinding_entry()

@type keybinding_entry() :: %{
  mode: String.t(),
  key: String.t(),
  command: String.t(),
  description: String.t()
}

Read-only keybinding entry sent to native settings UI.

theme_preview()

@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.

thermal_state()

@type thermal_state() ::
  :nominal | :fair | :serious | :critical | {:unknown, non_neg_integer()}

macOS thermal pressure level reported by the native GUI frontend.

Functions

config_state(options_server \\ Options.default_server(), keymap_server \\ Minga.Keymap.default_server())

Builds a full settings state payload from the current config and keymap servers.

decode_gui_action(arg1, payload)

@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).

decode_search_flags(flags)

@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.

encode_clipboard_write(text, target \\ :general)

@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).

encode_gui_extension_runtime(extension_id, channel, payload)

@spec encode_gui_extension_runtime(String.t(), String.t(), binary()) :: binary()

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.

settings_option?(name)

@spec settings_option?(atom()) :: boolean()