Packages
claude_code
0.36.4
0.36.5
0.36.4
0.36.3
0.36.2
0.36.1
0.36.0
0.35.0
0.34.0
0.33.1
0.32.2
0.32.0
0.31.0
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.1
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
Claude Agent SDK for Elixir – Build AI agents with Claude Code
Current section
Files
Jump to
Current section
Files
lib/claude_code/message/system_message/files_persisted.ex
defmodule ClaudeCode.Message.SystemMessage.FilesPersisted do
@moduledoc """
Represents a files persisted event from the Claude CLI.
Emitted when files have been persisted during a session, containing
metadata about each file that was saved.
## Fields
- `:files` - List of maps with `:filename` and `:file_id` keys
- `:failed` - List of maps with `:filename` and `:error` keys for files that failed to persist
- `:processed_at` - ISO 8601 timestamp when files were processed
- `:uuid` - Message UUID
- `:session_id` - Session identifier
## JSON Format
```json
{
"type": "system",
"subtype": "files_persisted",
"files": [
{"filename": "example.ex", "file_id": "file-abc123"}
],
"uuid": "...",
"session_id": "..."
}
```
"""
use ClaudeCode.JSONEncoder
@enforce_keys [:type, :subtype, :session_id]
defstruct [
:type,
:subtype,
:uuid,
:session_id,
:processed_at,
files: [],
failed: []
]
@type file_entry :: %{filename: String.t(), file_id: String.t()}
@type failed_entry :: %{filename: String.t(), error: String.t()}
@type t :: %__MODULE__{
type: :system,
subtype: :files_persisted,
files: [file_entry()],
failed: [failed_entry()],
processed_at: String.t() | nil,
uuid: String.t() | nil,
session_id: String.t()
}
@doc """
Creates a new FilesPersisted from JSON data.
## Examples
iex> FilesPersisted.new(%{
...> "type" => "system",
...> "subtype" => "files_persisted",
...> "files" => [%{"filename" => "test.ex", "file_id" => "file-1"}],
...> "session_id" => "session-1"
...> })
{:ok, %FilesPersisted{type: :system, subtype: :files_persisted, ...}}
iex> FilesPersisted.new(%{"type" => "assistant"})
{:error, :invalid_message_type}
"""
@spec new(map()) :: {:ok, t()} | {:error, atom()}
def new(%{"type" => "system", "subtype" => "files_persisted", "session_id" => session_id} = json) do
{:ok,
%__MODULE__{
type: :system,
subtype: :files_persisted,
files: parse_files(json["files"]),
failed: parse_failed(json["failed"]),
processed_at: json["processed_at"],
uuid: json["uuid"],
session_id: session_id
}}
end
def new(%{"type" => "system", "subtype" => "files_persisted"}), do: {:error, :missing_required_fields}
def new(_), do: {:error, :invalid_message_type}
@doc """
Type guard to check if a value is a FilesPersisted.
"""
@spec files_persisted?(any()) :: boolean()
def files_persisted?(%__MODULE__{type: :system, subtype: :files_persisted}), do: true
def files_persisted?(_), do: false
defp parse_files(files) when is_list(files) do
Enum.flat_map(files, fn
%{"filename" => filename, "file_id" => file_id} ->
[%{filename: filename, file_id: file_id}]
_ ->
[]
end)
end
defp parse_files(_), do: []
defp parse_failed(entries) when is_list(entries) do
Enum.flat_map(entries, fn
%{"filename" => filename, "error" => error} ->
[%{filename: filename, error: error}]
_ ->
[]
end)
end
defp parse_failed(_), do: []
end