ClaudeCode.Message.SystemMessage (ClaudeCode v0.20.0)

View Source

Represents a system message from the Claude CLI.

System messages cover multiple subtypes:

  • :init - Session initialization with tools, model, MCP servers, etc.
  • :hook_started - Hook execution started
  • :hook_response - Hook execution completed with output
  • Any future subtypes the CLI may add

For :init messages, all the dedicated fields (tools, model, mcp_servers, etc.) are populated. For other subtypes, extra fields are stored in the data map.

For conversation compaction boundaries, use ClaudeCode.Message.CompactBoundaryMessage.

Mirrors the Python SDK's generic approach: SystemMessage(subtype=str, data=dict).

Summary

Functions

Creates a new SystemMessage from JSON data.

Type guard to check if a value is a SystemMessage.

Types

t()

@type t() :: %ClaudeCode.Message.SystemMessage{
  agents: [String.t()],
  api_key_source: String.t() | nil,
  claude_code_version: String.t() | nil,
  cwd: String.t() | nil,
  data: map(),
  fast_mode_state: String.t() | nil,
  mcp_servers: [ClaudeCode.Types.mcp_server()] | nil,
  model: String.t() | nil,
  output_style: String.t(),
  permission_mode: ClaudeCode.Types.permission_mode() | nil,
  plugins: [ClaudeCode.Types.plugin()],
  session_id: ClaudeCode.Types.session_id(),
  skills: [String.t()],
  slash_commands: [String.t()],
  subtype: atom(),
  tools: [String.t()] | nil,
  type: :system,
  uuid: String.t() | nil
}

Functions

new(json)

@spec new(map()) ::
  {:ok, t()}
  | {:error,
     :invalid_message_type | :missing_session_id | {:missing_fields, [atom()]}}

Creates a new SystemMessage from JSON data.

For init subtypes, validates required fields and populates dedicated struct fields. For all other subtypes, stores extra fields in the data map.

Examples

iex> SystemMessage.new(%{"type" => "system", "subtype" => "init", ...})
{:ok, %SystemMessage{subtype: :init, ...}}

iex> SystemMessage.new(%{"type" => "system", "subtype" => "hook_started", ...})
{:ok, %SystemMessage{subtype: :hook_started, data: %{...}}}

iex> SystemMessage.new(%{"type" => "assistant"})
{:error, :invalid_message_type}

system_message?(arg1)

@spec system_message?(any()) :: boolean()

Type guard to check if a value is a SystemMessage.