Class: SwarmSDK::ClaudeCodeAgentAdapter

Inherits:
Object
  • Object
show all
Defined in:
lib/swarm_sdk/claude_code_agent_adapter.rb

Overview

Adapter for converting Claude Code agent markdown files to SwarmSDK format

Claude Code agent files use a different syntax and conventions than SwarmSDK:

  • Tools are comma-separated strings instead of arrays
  • Model shortcuts like 'sonnet', 'opus', 'haiku' instead of full model IDs
  • Tool permissions like 'Write(src/**)' instead of SwarmSDK's permission system
  • Required 'name' field in frontmatter

This adapter:

  • Detects Claude Code format by checking frontmatter markers
  • Converts tools from comma-separated strings to arrays
  • Maps model shortcuts to canonical model IDs
  • Strips unsupported tool permission syntax with warnings
  • Sets coding_agent: true by default
  • Warns about unsupported fields

Examples:

Parse a Claude Code agent file

content = File.read('.claude/agents/reviewer.md')
config = ClaudeCodeAgentAdapter.parse(content, :reviewer)
agent = Agent::Definition.new(:reviewer, config)

Constant Summary collapse

SUPPORTED_FIELDS =

Fields supported in Claude Code agent frontmatter

["name", "description", "tools", "model"].freeze
SWARM_SDK_DOCS_URL =

SwarmSDK documentation URL for reference

"https://github.com/parruda/claude-swarm/blob/main/docs/v2/README.md"
TOOL_PERMISSION_PATTERN =

Pattern to detect tool permission syntax like Write(src/**)

/^([A-Za-z_]+)\([^)]+\)$/

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(inherit_model: nil) ⇒ ClaudeCodeAgentAdapter

Initialize adapter with optional context

Parameters:

  • inherit_model (String, nil) (defaults to: nil)

    Model to use when frontmatter has 'inherit'



76
77
78
79
# File 'lib/swarm_sdk/claude_code_agent_adapter.rb', line 76

def initialize(inherit_model: nil)
  @inherit_model = inherit_model
  @warnings = []
end

Class Method Details

.claude_code_format?(content) ⇒ Boolean

Detect if content appears to be in Claude Code agent format

Detection is based on tools field type:

  • Claude Code: tools is a comma-separated string (e.g., "Read, Write, Bash")
  • SwarmSDK: tools is an array (e.g., [Read, Write, Bash])

Note: The 'name' field alone is not sufficient since SwarmSDK also supports it

Parameters:

  • content (String)

    Markdown content with YAML frontmatter

Returns:

  • (Boolean)

    true if content appears to be Claude Code format



46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/swarm_sdk/claude_code_agent_adapter.rb', line 46

def claude_code_format?(content)
  return false unless content =~ /\A---\s*\n(.*?)\n---\s*\n/m

  frontmatter_yaml = Regexp.last_match(1)
  frontmatter = YAML.safe_load(frontmatter_yaml, permitted_classes: [Symbol], aliases: true)

  return false unless frontmatter.is_a?(Hash)

  # Only detect as Claude Code if tools field is a comma-separated string
  # This is the most reliable indicator since SwarmSDK always uses arrays
  frontmatter.key?("tools") && frontmatter["tools"].is_a?(String)
rescue Psych::SyntaxError
  false
end

.parse(content, agent_name, inherit_model: nil) ⇒ Hash

Parse Claude Code agent markdown and convert to SwarmSDK format

Parameters:

  • content (String)

    Markdown content with YAML frontmatter

  • agent_name (Symbol, String)

    Name of the agent

  • inherit_model (String, nil) (defaults to: nil)

    Model to use when frontmatter has 'inherit'

Returns:

  • (Hash)

    Configuration hash suitable for Agent::Definition.new

Raises:



68
69
70
# File 'lib/swarm_sdk/claude_code_agent_adapter.rb', line 68

def parse(content, agent_name, inherit_model: nil)
  new(inherit_model: inherit_model).parse(content, agent_name)
end

Instance Method Details

#parse(content, agent_name) ⇒ Hash

Parse Claude Code agent content

Parameters:

  • content (String)

    Markdown content with YAML frontmatter

  • agent_name (Symbol, String)

    Name of the agent

Returns:

  • (Hash)

    Configuration hash for Agent::Definition

Raises:



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/swarm_sdk/claude_code_agent_adapter.rb', line 87

def parse(content, agent_name)
  unless content =~ /\A---\s*\n(.*?)\n---\s*\n(.*)\z/m
    raise ConfigurationError, "Invalid Claude Code agent format. Expected YAML frontmatter followed by prompt content."
  end

  frontmatter_yaml = Regexp.last_match(1)
  prompt_content = Regexp.last_match(2).strip

  frontmatter = YAML.safe_load(frontmatter_yaml, permitted_classes: [Symbol], aliases: true)

  unless frontmatter.is_a?(Hash)
    raise ConfigurationError, "Invalid frontmatter format in Claude Code agent file"
  end

  config = build_config(frontmatter, prompt_content, agent_name)
  emit_warnings(agent_name)
  config
end