claude_swarm 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37bc8baf6ea837fcd1e8936a1ae5a6a13138fad6e6efb3708deca991673e119d
4
- data.tar.gz: 1e3d06c4138a42e7ab54a121c4bd3e584db3859e640a5965aac88d04fe0e6132
3
+ metadata.gz: a4597e6fdc67837e39ae1c175cc9dded454460ec00488d92aa81cab928737b4a
4
+ data.tar.gz: 46790b958dc4916a3df066ae7384e753c84c6c4cc624ac62754cab646f2c9102
5
5
  SHA512:
6
- metadata.gz: dba5aab927293d3cc5fc4190b0cd84f7addf7ae0f90224df425a166d33c5feb5e062be21c8b915589191a14609f25f6fc68da63402c5295588bd5c4ed1d177ab
7
- data.tar.gz: 6a7d5058d8583bd1bf6fec8d148fe62e617535528f49f960412eb6da065db01a0405f4de6cff8963c63c523ce81cbf661dc49fe8840df3d568eaa2fcba853284
6
+ metadata.gz: f876006a8368881b252e675fab2b2999ae5a79574caff9db081ea7ea72402ce172524d7c6a2fe9c4b967502971a1cab83895dfd1f339592a516c58298450426a
7
+ data.tar.gz: b55120d481b8605e11a7024f1d6626f5c1fecca18627b6247e4b517c16e29d762166408a1753b1fc1b845c80f820f9701ce30ef2b0edb7e8a58da1b3635d0cc4
data/CHANGELOG.md CHANGED
@@ -1,4 +1,26 @@
1
- ## [Unreleased]
1
+ ## [0.1.4]
2
+
3
+ ### Added
4
+ - **Required `description` field for instances**: Each instance must now have a description that clearly explains its role and specialization
5
+ - Dynamic task tool descriptions that include both the instance name and description (e.g., "Execute a task using Agent frontend_dev. Frontend developer specializing in React and modern web technologies")
6
+ - Description validation during configuration parsing - configurations without descriptions will fail with a clear error message
7
+
8
+ ### Changed
9
+ - Updated all documentation examples to include meaningful instance descriptions
10
+ - The `claude-swarm init` command now generates a template with description fields
11
+
12
+ ## [0.1.3]
13
+
14
+ ### Fixed
15
+ - Fixed duplicate prompt arguments being passed to Claude Code executor, which could cause command execution failures
16
+
17
+ ### Changed
18
+ - Improved logging to track request flow between instances using `from_instance` and `to_instance` fields instead of generic `instance_name`
19
+ - Added required `calling_instance` parameter to MCP server command to properly identify the source of requests in tree configurations
20
+ - Consolidated session files into a single directory structure (`.claude-swarm/sessions/<timestamp>/`)
21
+ - MCP configuration files are now stored alongside session logs in the same timestamped directory
22
+ - Session logs are now named `session.log` instead of `session_<timestamp>.log`
23
+ - Improved organization by keeping all session-related files together
2
24
 
3
25
  ## [0.1.2] - 2025-05-29
4
26
 
data/README.md CHANGED
@@ -41,6 +41,7 @@ swarm:
41
41
  main: lead
42
42
  instances:
43
43
  lead:
44
+ description: "Team lead coordinating development efforts"
44
45
  directory: .
45
46
  model: opus
46
47
  connections: [frontend, backend]
@@ -49,6 +50,7 @@ swarm:
49
50
  - Edit
50
51
  - Bash
51
52
  frontend:
53
+ description: "Frontend specialist handling UI and user experience"
52
54
  directory: ./frontend
53
55
  model: sonnet
54
56
  tools:
@@ -56,6 +58,7 @@ swarm:
56
58
  - Write
57
59
  - Bash
58
60
  backend:
61
+ description: "Backend developer managing APIs and data layer"
59
62
  directory: ./backend
60
63
  model: sonnet
61
64
  tools:
@@ -77,7 +80,7 @@ claude-swarm --vibe # That will allow ALL tools for all instances! Be Careful!
77
80
  This will:
78
81
  - Launch the main instance (lead) with connections to other instances
79
82
  - The lead instance can communicate with the other instances via MCP
80
- - All instances log to `.claude-swarm/logs/session-{timestamp}/`
83
+ - All session files are stored in `.claude-swarm/sessions/{timestamp}/`
81
84
 
82
85
  #### Multi-Level Swarm Example
83
86
 
@@ -90,6 +93,7 @@ swarm:
90
93
  main: architect
91
94
  instances:
92
95
  architect:
96
+ description: "System architect coordinating between service teams"
93
97
  directory: .
94
98
  model: opus
95
99
  connections: [frontend_lead, backend_lead, mobile_lead, devops]
@@ -97,6 +101,7 @@ swarm:
97
101
  tools: [Read, Edit, WebSearch]
98
102
 
99
103
  frontend_lead:
104
+ description: "Frontend team lead overseeing React development"
100
105
  directory: ./web-frontend
101
106
  model: opus
102
107
  connections: [react_dev, css_expert]
@@ -104,18 +109,21 @@ swarm:
104
109
  tools: [Read, Edit, Bash]
105
110
 
106
111
  react_dev:
112
+ description: "React developer specializing in components and state management"
107
113
  directory: ./web-frontend/src
108
114
  model: sonnet
109
115
  prompt: "You specialize in React components and state management"
110
116
  tools: [Edit, Write, "Bash(npm:*)"]
111
117
 
112
118
  css_expert:
119
+ description: "CSS specialist handling styling and responsive design"
113
120
  directory: ./web-frontend/styles
114
121
  model: sonnet
115
122
  prompt: "You handle all CSS and styling concerns"
116
123
  tools: [Edit, Write, Read]
117
124
 
118
125
  backend_lead:
126
+ description: "Backend team lead managing API development"
119
127
  directory: ./api-server
120
128
  model: opus
121
129
  connections: [api_dev, database_expert]
@@ -123,18 +131,21 @@ swarm:
123
131
  tools: [Read, Edit, Bash]
124
132
 
125
133
  api_dev:
134
+ description: "API developer building REST endpoints"
126
135
  directory: ./api-server/src
127
136
  model: sonnet
128
137
  prompt: "You develop REST API endpoints"
129
138
  tools: [Edit, Write, Bash]
130
139
 
131
140
  database_expert:
141
+ description: "Database specialist managing schemas and migrations"
132
142
  directory: ./api-server/db
133
143
  model: sonnet
134
144
  prompt: "You handle database schema and migrations"
135
145
  tools: [Edit, Write, "Bash(psql:*, migrate:*)"]
136
146
 
137
147
  mobile_lead:
148
+ description: "Mobile team lead coordinating cross-platform development"
138
149
  directory: ./mobile-app
139
150
  model: sonnet
140
151
  connections: [ios_dev, android_dev]
@@ -142,18 +153,21 @@ swarm:
142
153
  tools: [Read, Edit]
143
154
 
144
155
  ios_dev:
156
+ description: "iOS developer building native Apple applications"
145
157
  directory: ./mobile-app/ios
146
158
  model: sonnet
147
159
  prompt: "You develop the iOS application"
148
160
  tools: [Edit, Write, "Bash(xcodebuild:*, pod:*)"]
149
161
 
150
162
  android_dev:
163
+ description: "Android developer creating native Android apps"
151
164
  directory: ./mobile-app/android
152
165
  model: sonnet
153
166
  prompt: "You develop the Android application"
154
167
  tools: [Edit, Write, "Bash(gradle:*, adb:*)"]
155
168
 
156
169
  devops:
170
+ description: "DevOps engineer managing CI/CD and infrastructure"
157
171
  directory: ./infrastructure
158
172
  model: sonnet
159
173
  prompt: "You handle CI/CD and infrastructure"
@@ -182,6 +196,10 @@ swarm:
182
196
 
183
197
  #### Instance Configuration
184
198
 
199
+ Each instance must have:
200
+
201
+ - **description** (required): Brief description of the agent's role (used in task tool descriptions)
202
+
185
203
  Each instance can have:
186
204
 
187
205
  - **directory**: Working directory for this instance (can use ~ for home)
@@ -193,6 +211,7 @@ Each instance can have:
193
211
 
194
212
  ```yaml
195
213
  instance_name:
214
+ description: "Specialized agent focused on specific tasks"
196
215
  directory: ~/project/path
197
216
  model: opus
198
217
  connections: [other_instance1, other_instance2]
@@ -273,6 +292,7 @@ swarm:
273
292
  main: architect
274
293
  instances:
275
294
  architect:
295
+ description: "Lead architect responsible for system design and code quality"
276
296
  directory: .
277
297
  model: opus
278
298
  connections: [frontend, backend, devops]
@@ -283,6 +303,7 @@ swarm:
283
303
  - WebSearch
284
304
 
285
305
  frontend:
306
+ description: "Frontend developer specializing in React and TypeScript"
286
307
  directory: ./frontend
287
308
  model: sonnet
288
309
  connections: [architect]
@@ -293,6 +314,7 @@ swarm:
293
314
  - Bash
294
315
 
295
316
  backend:
317
+ description: "Backend developer building APIs and services"
296
318
  directory: ./backend
297
319
  model: sonnet
298
320
  connections: [architect, database]
@@ -302,6 +324,7 @@ swarm:
302
324
  - Bash
303
325
 
304
326
  database:
327
+ description: "Database administrator managing data persistence"
305
328
  directory: ./db
306
329
  model: haiku
307
330
  tools:
@@ -309,6 +332,7 @@ swarm:
309
332
  - Bash
310
333
 
311
334
  devops:
335
+ description: "DevOps engineer handling deployment and infrastructure"
312
336
  directory: .
313
337
  model: sonnet
314
338
  connections: [architect]
@@ -327,6 +351,7 @@ swarm:
327
351
  main: lead_researcher
328
352
  instances:
329
353
  lead_researcher:
354
+ description: "Lead researcher coordinating analysis and documentation"
330
355
  directory: ~/research
331
356
  model: opus
332
357
  connections: [data_analyst, writer]
@@ -340,6 +365,7 @@ swarm:
340
365
  url: "https://arxiv-mcp.example.com"
341
366
 
342
367
  data_analyst:
368
+ description: "Data analyst processing research data and statistics"
343
369
  directory: ~/research/data
344
370
  model: sonnet
345
371
  tools:
@@ -353,6 +379,7 @@ swarm:
353
379
  args: ["--notebook-dir", "."]
354
380
 
355
381
  writer:
382
+ description: "Technical writer preparing research documentation"
356
383
  directory: ~/research/papers
357
384
  model: sonnet
358
385
  tools:
@@ -397,10 +424,12 @@ claude-swarm mcp-serve INSTANCE_NAME --config CONFIG_FILE --session-timestamp TI
397
424
  - Sessions can be reset via the MCP server interface
398
425
  4. **Main Instance Launch**: The main instance is launched with its MCP configuration, giving it access to all connected instances
399
426
  5. **Inter-Instance Communication**: Connected instances expose themselves as MCP servers with these tools:
400
- - **task**: Execute tasks using Claude Code with configurable tools and return results
427
+ - **task**: Execute tasks using Claude Code with configurable tools and return results. The tool description includes the instance name and description (e.g., "Execute a task using Agent frontend_dev. Frontend developer specializing in React and TypeScript")
401
428
  - **session_info**: Get current Claude session information including ID and working directory
402
429
  - **reset_session**: Reset the Claude session for a fresh start
403
- 6. **Centralized Logging**: All instances log to `.claude-swarm/logs/session-{timestamp}/` with detailed request/response tracking
430
+ 6. **Session Management**: All session files are organized in `.claude-swarm/sessions/{timestamp}/`:
431
+ - MCP configuration files: `{instance_name}.mcp.json`
432
+ - Session log: `session.log` with detailed request/response tracking
404
433
 
405
434
  ## Troubleshooting
406
435
 
@@ -423,16 +452,16 @@ claude-swarm mcp-serve INSTANCE_NAME --config CONFIG_FILE --session-timestamp TI
423
452
  ### Debug Output
424
453
 
425
454
  The swarm will display:
426
- - Generated MCP configuration location
455
+ - Session directory location (`.claude-swarm/sessions/{timestamp}/`)
427
456
  - Main instance details (model, directory, tools, connections)
428
457
  - The exact command being run
429
458
 
430
- ### Logs
459
+ ### Session Files
431
460
 
432
- Check the centralized logs in `.claude-swarm/logs/session-{timestamp}/` for:
433
- - Individual instance logs
434
- - MCP server communication
435
- - Error messages and debugging information
461
+ Check the session directory `.claude-swarm/sessions/{timestamp}/` for:
462
+ - `session.log`: Detailed logs with request/response tracking
463
+ - `{instance}.mcp.json`: MCP configuration for each instance
464
+ - All files for a session are kept together for easy review
436
465
 
437
466
  ## Architecture
438
467
 
data/claude-swarm.yml CHANGED
@@ -4,6 +4,7 @@ swarm:
4
4
  main: lead_developer
5
5
  instances:
6
6
  lead_developer:
7
+ description: "Lead developer coordinating the team and making architectural decisions"
7
8
  directory: .
8
9
  model: sonnet
9
10
  prompt: "You are the lead developer coordinating the team"
@@ -13,6 +14,7 @@ swarm:
13
14
  # Example instances (uncomment and modify as needed):
14
15
 
15
16
  frontend_dev:
17
+ description: "Frontend developer specializing in React and modern web technologies"
16
18
  directory: .
17
19
  model: sonnet
18
20
  prompt: "You specialize in frontend development with React, TypeScript, and modern web technologies"
@@ -4,14 +4,14 @@ swarm:
4
4
  main: lead_rails_dev
5
5
  instances:
6
6
  lead_rails_dev:
7
- role: "Lead Rails Developer"
7
+ description: "Senior Rails developer with 10+ years experience, coordinating the team and making architectural decisions"
8
8
  directory: .
9
9
  model: opus
10
10
  connections: [backend_dev, frontend_dev, test_engineer]
11
11
  prompt: "You are a senior Ruby on Rails developer with 10+ years of experience. You excel at Rails architecture, performance optimization, and best practices. You coordinate the team and make architectural decisions."
12
12
 
13
13
  backend_dev:
14
- role: "Backend Rails Developer"
14
+ description: "Backend specialist focusing on Rails models, controllers, services, jobs, and API design"
15
15
  directory: .
16
16
  model: sonnet
17
17
  connections: [test_engineer]
@@ -23,14 +23,14 @@ swarm:
23
23
  args: ["exec", "hbt", "stdio"]
24
24
 
25
25
  frontend_dev:
26
- role: "Rails Frontend Developer"
26
+ description: "Frontend Rails developer specializing in views, Stimulus/Turbo, and responsive UIs"
27
27
  directory: .
28
28
  model: sonnet
29
29
  connections: [test_engineer]
30
30
  prompt: "You are a Rails developer specializing in views, partials, helpers, Stimulus/Turbo, and asset pipeline. You excel at creating responsive UIs with Rails' built-in tools and modern CSS/JavaScript integration."
31
31
 
32
32
  test_engineer:
33
- role: "Rails Test Engineer"
33
+ description: "Testing expert specializing in Minitest and Rails testing best practices"
34
34
  directory: .
35
35
  model: sonnet
36
36
  prompt: "You are a Rails testing expert specializing in Minitest. You write comprehensive unit tests, integration tests, system tests, and fixtures. You ensure high test coverage and follow Rails testing best practices including proper use of assertions, test helpers, and factories."
@@ -67,8 +67,8 @@ module ClaudeSwarm
67
67
  # Always use JSON output format for structured responses
68
68
  cmd_array += ["--output-format", "json"]
69
69
 
70
- # Add non-interactive mode
71
- cmd_array << "--print"
70
+ # Add non-interactive mode with prompt
71
+ cmd_array += ["--print", "-p", prompt]
72
72
 
73
73
  # Add any custom system prompt
74
74
  cmd_array += ["--system-prompt", options[:system_prompt]] if options[:system_prompt]
@@ -81,9 +81,6 @@ module ClaudeSwarm
81
81
  cmd_array += ["--allowedTools", tools]
82
82
  end
83
83
 
84
- # Add the prompt as the last argument (no escaping needed with array syntax)
85
- cmd_array << prompt
86
-
87
84
  cmd_array
88
85
  end
89
86
 
@@ -9,15 +9,16 @@ require_relative "claude_code_executor"
9
9
  module ClaudeSwarm
10
10
  class ClaudeMcpServer
11
11
  SWARM_DIR = ".claude-swarm"
12
- LOGS_DIR = "logs"
12
+ SESSIONS_DIR = "sessions"
13
13
 
14
14
  # Class variables to share state with tool classes
15
15
  class << self
16
- attr_accessor :executor, :instance_config, :logger, :session_timestamp
16
+ attr_accessor :executor, :instance_config, :logger, :session_timestamp, :calling_instance
17
17
  end
18
18
 
19
- def initialize(instance_config)
19
+ def initialize(instance_config, calling_instance:)
20
20
  @instance_config = instance_config
21
+ @calling_instance = calling_instance
21
22
  @executor = ClaudeCodeExecutor.new(
22
23
  working_directory: instance_config[:directory],
23
24
  model: instance_config[:model],
@@ -32,6 +33,7 @@ module ClaudeSwarm
32
33
  self.class.executor = @executor
33
34
  self.class.instance_config = @instance_config
34
35
  self.class.logger = @logger
36
+ self.class.calling_instance = @calling_instance
35
37
  end
36
38
 
37
39
  private
@@ -41,13 +43,13 @@ module ClaudeSwarm
41
43
  # Otherwise create a new timestamp
42
44
  self.class.session_timestamp ||= ENV["CLAUDE_SWARM_SESSION_TIMESTAMP"] || Time.now.strftime("%Y%m%d_%H%M%S")
43
45
 
44
- # Ensure the logs directory exists
45
- logs_dir = File.join(Dir.pwd, SWARM_DIR, LOGS_DIR)
46
- FileUtils.mkdir_p(logs_dir)
46
+ # Ensure the session directory exists
47
+ session_dir = File.join(Dir.pwd, SWARM_DIR, SESSIONS_DIR, self.class.session_timestamp)
48
+ FileUtils.mkdir_p(session_dir)
47
49
 
48
- # Create logger with timestamped filename
49
- log_filename = "session_#{self.class.session_timestamp}.log"
50
- log_path = File.join(logs_dir, log_filename)
50
+ # Create logger with session.log filename
51
+ log_filename = "session.log"
52
+ log_path = File.join(session_dir, log_filename)
51
53
  @logger = Logger.new(log_path)
52
54
  @logger.level = Logger::INFO
53
55
 
@@ -67,6 +69,13 @@ module ClaudeSwarm
67
69
  version: "1.0.0"
68
70
  )
69
71
 
72
+ # Set dynamic description for TaskTool based on instance config
73
+ if @instance_config[:description]
74
+ TaskTool.description "Execute a task using Agent #{@instance_config[:name]}. #{@instance_config[:description]}"
75
+ else
76
+ TaskTool.description "Execute a task using Agent #{@instance_config[:name]}"
77
+ end
78
+
70
79
  # Register tool classes (not instances)
71
80
  server.register_tool(TaskTool)
72
81
  server.register_tool(SessionInfoTool)
@@ -81,7 +90,7 @@ module ClaudeSwarm
81
90
  description "Execute a task using Claude Code"
82
91
 
83
92
  arguments do
84
- required(:prompt).filled(:string).description("The task or question for Claude")
93
+ required(:prompt).filled(:string).description("The task or question for the agent")
85
94
  optional(:new_session).filled(:bool).description("Start a new session (default: false)")
86
95
  optional(:system_prompt).filled(:string).description("Override the system prompt for this request")
87
96
  end
@@ -103,7 +112,8 @@ module ClaudeSwarm
103
112
  # Log the request
104
113
  log_entry = {
105
114
  timestamp: Time.now.utc.iso8601,
106
- instance_name: instance_config[:name],
115
+ from_instance: ClaudeMcpServer.calling_instance, # The instance making the request
116
+ to_instance: instance_config[:name], # This instance is receiving the request
107
117
  model: instance_config[:model],
108
118
  working_directory: instance_config[:directory],
109
119
  session_id: executor.session_id,
@@ -120,7 +130,10 @@ module ClaudeSwarm
120
130
  response = executor.execute(prompt, options)
121
131
 
122
132
  # Log the response
123
- response_entry = log_entry.merge(
133
+ response_entry = {
134
+ timestamp: Time.now.utc.iso8601,
135
+ from_instance: instance_config[:name], # This instance is sending the response
136
+ to_instance: ClaudeMcpServer.calling_instance, # The instance that made the request receives the response
124
137
  session_id: executor.session_id, # Update with new session ID if changed
125
138
  response: {
126
139
  result: response["result"],
@@ -129,7 +142,7 @@ module ClaudeSwarm
129
142
  is_error: response["is_error"],
130
143
  total_cost: response["total_cost"]
131
144
  }
132
- )
145
+ }
133
146
 
134
147
  logger.info("RESPONSE: #{JSON.pretty_generate(response_entry)}")
135
148
 
@@ -151,7 +164,7 @@ module ClaudeSwarm
151
164
 
152
165
  class SessionInfoTool < FastMcp::Tool
153
166
  tool_name "session_info"
154
- description "Get information about the current Claude session"
167
+ description "Get information about the current Claude session for this agent"
155
168
 
156
169
  arguments do
157
170
  # No arguments needed
@@ -170,7 +183,7 @@ module ClaudeSwarm
170
183
 
171
184
  class ResetSessionTool < FastMcp::Tool
172
185
  tool_name "reset_session"
173
- description "Reset the Claude session, starting fresh on the next task"
186
+ description "Reset the Claude session for this agent, starting fresh on the next task"
174
187
 
175
188
  arguments do
176
189
  # No arguments needed
@@ -29,8 +29,12 @@ module ClaudeSwarm
29
29
  say "Starting Claude Swarm from #{config_path}..." unless options[:prompt]
30
30
  begin
31
31
  config = Configuration.new(config_path)
32
- generator = McpGenerator.new(config, vibe: options[:vibe])
33
- orchestrator = Orchestrator.new(config, generator, vibe: options[:vibe], prompt: options[:prompt])
32
+ session_timestamp = Time.now.strftime("%Y%m%d_%H%M%S")
33
+ generator = McpGenerator.new(config, vibe: options[:vibe], timestamp: session_timestamp)
34
+ orchestrator = Orchestrator.new(config, generator,
35
+ vibe: options[:vibe],
36
+ prompt: options[:prompt],
37
+ session_timestamp: session_timestamp)
34
38
  orchestrator.start
35
39
  rescue Error => e
36
40
  error e.message
@@ -51,6 +55,8 @@ module ClaudeSwarm
51
55
  desc: "Claude model to use (e.g., opus, sonnet)"
52
56
  method_option :prompt, aliases: "-p", type: :string,
53
57
  desc: "System prompt for the instance"
58
+ method_option :description, type: :string,
59
+ desc: "Description of the instance's role"
54
60
  method_option :tools, aliases: "-t", type: :array,
55
61
  desc: "Allowed tools for the instance"
56
62
  method_option :mcp_config_path, type: :string,
@@ -59,19 +65,22 @@ module ClaudeSwarm
59
65
  desc: "Enable debug output"
60
66
  method_option :vibe, type: :boolean, default: false,
61
67
  desc: "Run with --dangerously-skip-permissions"
68
+ method_option :calling_instance, type: :string, required: true,
69
+ desc: "Name of the instance that launched this MCP server"
62
70
  def mcp_serve
63
71
  instance_config = {
64
72
  name: options[:name],
65
73
  directory: options[:directory],
66
74
  model: options[:model],
67
75
  prompt: options[:prompt],
76
+ description: options[:description],
68
77
  tools: options[:tools] || [],
69
78
  mcp_config_path: options[:mcp_config_path],
70
79
  vibe: options[:vibe]
71
80
  }
72
81
 
73
82
  begin
74
- server = ClaudeMcpServer.new(instance_config)
83
+ server = ClaudeMcpServer.new(instance_config, calling_instance: options[:calling_instance])
75
84
  server.start
76
85
  rescue StandardError => e
77
86
  error "Error starting MCP server: #{e.message}"
@@ -99,6 +108,7 @@ module ClaudeSwarm
99
108
  main: lead_developer
100
109
  instances:
101
110
  lead_developer:
111
+ description: "Lead developer who coordinates the team and makes architectural decisions"
102
112
  directory: .
103
113
  model: sonnet
104
114
  prompt: "You are the lead developer coordinating the team"
@@ -108,24 +118,28 @@ module ClaudeSwarm
108
118
  # Example instances (uncomment and modify as needed):
109
119
 
110
120
  # frontend_dev:
121
+ # description: "Frontend developer specializing in React and modern web technologies"
111
122
  # directory: ./frontend
112
123
  # model: sonnet
113
124
  # prompt: "You specialize in frontend development with React, TypeScript, and modern web technologies"
114
125
  # tools: [Read, Edit, Write, "Bash(npm:*)", "Bash(yarn:*)", "Bash(pnpm:*)"]
115
126
 
116
127
  # backend_dev:
128
+ # description: "Backend developer focusing on APIs, databases, and server architecture"
117
129
  # directory: ../other-app/backend
118
130
  # model: sonnet
119
131
  # prompt: "You specialize in backend development, APIs, databases, and server architecture"
120
132
  # tools: [Read, Edit, Write, Bash]
121
133
 
122
134
  # devops_engineer:
135
+ # description: "DevOps engineer managing infrastructure, CI/CD, and deployments"
123
136
  # directory: .
124
137
  # model: sonnet
125
138
  # prompt: "You specialize in infrastructure, CI/CD, containerization, and deployment"
126
139
  # tools: [Read, Edit, Write, "Bash(docker:*)", "Bash(kubectl:*)", "Bash(terraform:*)"]
127
140
 
128
141
  # qa_engineer:
142
+ # description: "QA engineer ensuring quality through comprehensive testing"
129
143
  # directory: ./tests
130
144
  # model: sonnet
131
145
  # prompt: "You specialize in testing, quality assurance, and test automation"
@@ -72,6 +72,10 @@ module ClaudeSwarm
72
72
 
73
73
  def parse_instance(name, config)
74
74
  config ||= {}
75
+
76
+ # Validate required fields
77
+ raise Error, "Instance '#{name}' missing required 'description' field" unless config["description"]
78
+
75
79
  {
76
80
  name: name,
77
81
  directory: expand_path(config["directory"] || "."),
@@ -79,7 +83,8 @@ module ClaudeSwarm
79
83
  connections: Array(config["connections"]),
80
84
  tools: Array(config["tools"]),
81
85
  mcps: parse_mcps(config["mcps"] || []),
82
- prompt: config["prompt"]
86
+ prompt: config["prompt"],
87
+ description: config["description"]
83
88
  }
84
89
  end
85
90
 
@@ -7,10 +7,12 @@ require "shellwords"
7
7
  module ClaudeSwarm
8
8
  class McpGenerator
9
9
  SWARM_DIR = ".claude-swarm"
10
+ SESSIONS_SUBDIR = "sessions"
10
11
 
11
- def initialize(configuration, vibe: false)
12
+ def initialize(configuration, vibe: false, timestamp: nil)
12
13
  @config = configuration
13
14
  @vibe = vibe
15
+ @timestamp = timestamp || Time.now.strftime("%Y%m%d_%H%M%S")
14
16
  end
15
17
 
16
18
  def generate_all
@@ -22,7 +24,7 @@ module ClaudeSwarm
22
24
  end
23
25
 
24
26
  def mcp_config_path(instance_name)
25
- File.join(Dir.pwd, SWARM_DIR, "#{instance_name}.mcp.json")
27
+ File.join(Dir.pwd, SWARM_DIR, SESSIONS_SUBDIR, @timestamp, "#{instance_name}.mcp.json")
26
28
  end
27
29
 
28
30
  private
@@ -34,9 +36,9 @@ module ClaudeSwarm
34
36
  def ensure_swarm_directory
35
37
  FileUtils.mkdir_p(swarm_dir)
36
38
 
37
- # Create logs directory as well
38
- logs_dir = File.join(swarm_dir, "logs")
39
- FileUtils.mkdir_p(logs_dir)
39
+ # Create session directory with timestamp
40
+ session_dir = File.join(swarm_dir, SESSIONS_SUBDIR, @timestamp)
41
+ FileUtils.mkdir_p(session_dir)
40
42
 
41
43
  gitignore_path = File.join(swarm_dir, ".gitignore")
42
44
  File.write(gitignore_path, "*\n") unless File.exist?(gitignore_path)
@@ -53,7 +55,7 @@ module ClaudeSwarm
53
55
  # Add connection MCPs for other instances
54
56
  instance[:connections].each do |connection_name|
55
57
  connected_instance = @config.instances[connection_name]
56
- mcp_servers[connection_name] = build_instance_mcp_config(connection_name, connected_instance)
58
+ mcp_servers[connection_name] = build_instance_mcp_config(connection_name, connected_instance, calling_instance: name)
57
59
  end
58
60
 
59
61
  config = {
@@ -81,7 +83,7 @@ module ClaudeSwarm
81
83
  end
82
84
  end
83
85
 
84
- def build_instance_mcp_config(name, instance)
86
+ def build_instance_mcp_config(name, instance, calling_instance:)
85
87
  # Get the path to the claude-swarm executable
86
88
  exe_path = "claude-swarm"
87
89
 
@@ -96,10 +98,14 @@ module ClaudeSwarm
96
98
  # Add optional arguments
97
99
  args.push("--prompt", instance[:prompt]) if instance[:prompt]
98
100
 
101
+ args.push("--description", instance[:description]) if instance[:description]
102
+
99
103
  args.push("--tools", instance[:tools].join(",")) if instance[:tools] && !instance[:tools].empty?
100
104
 
101
105
  args.push("--mcp-config-path", mcp_config_path(name))
102
106
 
107
+ args.push("--calling-instance", calling_instance) if calling_instance
108
+
103
109
  args.push("--vibe") if @vibe
104
110
 
105
111
  {
@@ -4,11 +4,12 @@ require "shellwords"
4
4
 
5
5
  module ClaudeSwarm
6
6
  class Orchestrator
7
- def initialize(configuration, mcp_generator, vibe: false, prompt: nil)
7
+ def initialize(configuration, mcp_generator, vibe: false, prompt: nil, session_timestamp: nil)
8
8
  @config = configuration
9
9
  @generator = mcp_generator
10
10
  @vibe = vibe
11
11
  @prompt = prompt
12
+ @session_timestamp = session_timestamp || Time.now.strftime("%Y%m%d_%H%M%S")
12
13
  end
13
14
 
14
15
  def start
@@ -18,18 +19,17 @@ module ClaudeSwarm
18
19
  puts
19
20
  end
20
21
 
21
- # Set session timestamp for all instances to share the same log file
22
- session_timestamp = Time.now.strftime("%Y%m%d_%H%M%S")
23
- ENV["CLAUDE_SWARM_SESSION_TIMESTAMP"] = session_timestamp
22
+ # Set session timestamp for all instances to share the same session directory
23
+ ENV["CLAUDE_SWARM_SESSION_TIMESTAMP"] = @session_timestamp
24
24
  unless @prompt
25
- puts "📝 Session logs will be saved to: .claude-swarm/logs/session_#{session_timestamp}.log"
25
+ puts "📝 Session files will be saved to: .claude-swarm/sessions/#{@session_timestamp}/"
26
26
  puts
27
27
  end
28
28
 
29
29
  # Generate all MCP configuration files
30
30
  @generator.generate_all
31
31
  unless @prompt
32
- puts "✓ Generated MCP configurations in .claude-swarm/"
32
+ puts "✓ Generated MCP configurations in session directory"
33
33
  puts
34
34
  end
35
35
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ClaudeSwarm
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.4"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: claude_swarm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paulo Arruda
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-05-29 00:00:00.000000000 Z
10
+ date: 2025-05-30 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: thor