claude_swarm 0.1.11 → 0.1.12
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 +4 -4
- data/CHANGELOG.md +19 -0
- data/README.md +2 -2
- data/claude-swarm.yml +42 -0
- data/lib/claude_swarm/claude_code_executor.rb +34 -12
- data/lib/claude_swarm/claude_mcp_server.rb +2 -2
- data/lib/claude_swarm/cli.rb +1 -3
- data/lib/claude_swarm/configuration.rb +26 -0
- data/lib/claude_swarm/mcp_generator.rb +10 -20
- data/lib/claude_swarm/orchestrator.rb +11 -8
- data/lib/claude_swarm/permission_mcp_server.rb +6 -15
- data/lib/claude_swarm/session_path.rb +50 -0
- data/lib/claude_swarm/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c468e30d7de839a1b7bb88c2e2ee1c9bfa58b8bb0f0b0375b3495ebf5de340f0
|
4
|
+
data.tar.gz: 7234799e8b24cc2b0a691f188a890ee84d0780a77a85723307bdc9f17ad71545
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ed4d3460c8e686f683513796939827419d254d9b4a168a211d24d89cb18aaeb4cacf42a2dd90d1b88ecbc98ab97f7391b356ed24f0beb05da4bab6c62ce5332
|
7
|
+
data.tar.gz: ced867554fa8b43c6ce9f327f791212dcc04a87c378d78e99c87f41776074eba7f2a1bf7691b6b9daaf34fcd7923b057cefe453171d5838f2981ee87d67237f1
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
## [0.1.12]
|
2
|
+
### Added
|
3
|
+
- **Circular dependency detection**: Configuration validation now detects and reports circular dependencies between instances
|
4
|
+
- Clear error messages showing the dependency cycle (e.g., "Circular dependency detected: lead -> backend -> lead")
|
5
|
+
- Comprehensive test coverage for various circular dependency scenarios
|
6
|
+
- **Session management improvements**: Session files are now stored in `~/.claude-swarm/sessions/` organized by project path
|
7
|
+
- Added `SessionPath` module to centralize session path management
|
8
|
+
- Sessions are now organized by project directory for better multi-project support
|
9
|
+
- Added `CLAUDE_SWARM_HOME` environment variable support for custom storage location
|
10
|
+
- Log full JSON to `session.log.json` as JSONL
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
- Session files moved from `./.claude-swarm/sessions/` to `~/.claude-swarm/sessions/[project]/[timestamp]/`
|
14
|
+
- Replaced `CLAUDE_SWARM_SESSION_TIMESTAMP` with `CLAUDE_SWARM_SESSION_PATH` environment variable
|
15
|
+
- MCP server configurations now use the new centralized session path
|
16
|
+
|
17
|
+
### Fixed
|
18
|
+
- Fixed circular dependency example in README documentation
|
19
|
+
|
1
20
|
## [0.1.11]
|
2
21
|
### Added
|
3
22
|
- Main instance debug mode with `claude-swarm --debug`
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Claude Swarm
|
2
2
|
|
3
|
-
[](https://badge.fury.io/rb/claude_swarm)
|
3
|
+
[](https://badge.fury.io/rb/claude_swarm)
|
4
4
|
[](https://github.com/parruda/claude-swarm/actions/workflows/ci.yml)
|
5
5
|
|
6
6
|
Claude Swarm orchestrates multiple Claude Code instances as a collaborative AI development team. It enables running AI agents with specialized roles, tools, and directory contexts, communicating via MCP (Model Context Protocol) in a tree-like hierarchy. Define your swarm topology in simple YAML and let Claude instances delegate tasks through connected instances. Perfect for complex projects requiring specialized AI agents for frontend, backend, testing, DevOps, or research tasks.
|
@@ -327,7 +327,7 @@ swarm:
|
|
327
327
|
description: "Backend developer building APIs and services"
|
328
328
|
directory: ./backend
|
329
329
|
model: opus
|
330
|
-
connections: [
|
330
|
+
connections: [database]
|
331
331
|
allowed_tools:
|
332
332
|
- Edit
|
333
333
|
- Write
|
data/claude-swarm.yml
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
version: 1
|
2
|
+
swarm:
|
3
|
+
name: "Swarm Name"
|
4
|
+
main: lead_developer
|
5
|
+
instances:
|
6
|
+
lead_developer:
|
7
|
+
description: "Lead developer who coordinates the team and makes architectural decisions"
|
8
|
+
directory: .
|
9
|
+
model: sonnet
|
10
|
+
prompt: "You are the lead developer coordinating the team"
|
11
|
+
allowed_tools: [Read, Edit, Bash, Write]
|
12
|
+
connections: [frontend_dev, backend_dev]
|
13
|
+
|
14
|
+
# Example instances (uncomment and modify as needed):
|
15
|
+
|
16
|
+
frontend_dev:
|
17
|
+
description: "Frontend developer specializing in React and modern web technologies"
|
18
|
+
directory: .
|
19
|
+
model: sonnet
|
20
|
+
prompt: "You specialize in frontend development with React, TypeScript, and modern web technologies"
|
21
|
+
allowed_tools: [Read, Edit, Write, "Bash(npm:*)", "Bash(yarn:*)", "Bash(pnpm:*)"]
|
22
|
+
|
23
|
+
backend_dev:
|
24
|
+
description: "Backend developer focusing on APIs, databases, and server architecture"
|
25
|
+
directory: .
|
26
|
+
model: sonnet
|
27
|
+
prompt: "You specialize in backend development, APIs, databases, and server architecture"
|
28
|
+
allowed_tools: [Read, Edit, Write, Bash]
|
29
|
+
|
30
|
+
# devops_engineer:
|
31
|
+
# description: "DevOps engineer managing infrastructure, CI/CD, and deployments"
|
32
|
+
# directory: .
|
33
|
+
# model: sonnet
|
34
|
+
# prompt: "You specialize in infrastructure, CI/CD, containerization, and deployment"
|
35
|
+
# allowed_tools: [Read, Edit, Write, "Bash(docker:*)", "Bash(kubectl:*)", "Bash(terraform:*)"]
|
36
|
+
|
37
|
+
# qa_engineer:
|
38
|
+
# description: "QA engineer ensuring quality through comprehensive testing"
|
39
|
+
# directory: ./tests
|
40
|
+
# model: sonnet
|
41
|
+
# prompt: "You specialize in testing, quality assurance, and test automation"
|
42
|
+
# allowed_tools: [Read, Edit, Write, Bash]
|
@@ -4,13 +4,11 @@ require "json"
|
|
4
4
|
require "open3"
|
5
5
|
require "logger"
|
6
6
|
require "fileutils"
|
7
|
+
require_relative "session_path"
|
7
8
|
|
8
9
|
module ClaudeSwarm
|
9
10
|
class ClaudeCodeExecutor
|
10
|
-
|
11
|
-
SESSIONS_DIR = "sessions"
|
12
|
-
|
13
|
-
attr_reader :session_id, :last_response, :working_directory, :logger, :session_timestamp
|
11
|
+
attr_reader :session_id, :last_response, :working_directory, :logger, :session_path
|
14
12
|
|
15
13
|
def initialize(working_directory: Dir.pwd, model: nil, mcp_config: nil, vibe: false, instance_name: nil, calling_instance: nil)
|
16
14
|
@working_directory = working_directory
|
@@ -95,17 +93,13 @@ module ClaudeSwarm
|
|
95
93
|
private
|
96
94
|
|
97
95
|
def setup_logging
|
98
|
-
# Use
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
# Ensure the session directory exists
|
103
|
-
session_dir = File.join(Dir.pwd, SWARM_DIR, SESSIONS_DIR, @session_timestamp)
|
104
|
-
FileUtils.mkdir_p(session_dir)
|
96
|
+
# Use session path from environment (required)
|
97
|
+
@session_path = SessionPath.from_env
|
98
|
+
SessionPath.ensure_directory(@session_path)
|
105
99
|
|
106
100
|
# Create logger with session.log filename
|
107
101
|
log_filename = "session.log"
|
108
|
-
log_path = File.join(
|
102
|
+
log_path = File.join(@session_path, log_filename)
|
109
103
|
@logger = Logger.new(log_path)
|
110
104
|
@logger.level = Logger::INFO
|
111
105
|
|
@@ -128,6 +122,8 @@ module ClaudeSwarm
|
|
128
122
|
end
|
129
123
|
|
130
124
|
def log_streaming_event(event)
|
125
|
+
append_to_session_json(event)
|
126
|
+
|
131
127
|
return log_system_message(event) if event["type"] == "system"
|
132
128
|
|
133
129
|
# Add specific details based on event type
|
@@ -170,6 +166,32 @@ module ClaudeSwarm
|
|
170
166
|
@logger.debug("USER: #{JSON.pretty_generate(content)}")
|
171
167
|
end
|
172
168
|
|
169
|
+
def append_to_session_json(event)
|
170
|
+
json_filename = "session.log.json"
|
171
|
+
json_path = File.join(@session_path, json_filename)
|
172
|
+
|
173
|
+
# Use file locking to ensure thread-safe writes
|
174
|
+
File.open(json_path, File::WRONLY | File::APPEND | File::CREAT) do |file|
|
175
|
+
file.flock(File::LOCK_EX)
|
176
|
+
|
177
|
+
# Create entry with metadata
|
178
|
+
entry = {
|
179
|
+
instance: @instance_name,
|
180
|
+
calling_instance: @calling_instance,
|
181
|
+
timestamp: Time.now.iso8601,
|
182
|
+
event: event
|
183
|
+
}
|
184
|
+
|
185
|
+
# Write as single line JSON (JSONL format)
|
186
|
+
file.puts(entry.to_json)
|
187
|
+
|
188
|
+
file.flock(File::LOCK_UN)
|
189
|
+
end
|
190
|
+
rescue StandardError => e
|
191
|
+
@logger.error("Failed to append to session JSON: #{e.message}")
|
192
|
+
raise
|
193
|
+
end
|
194
|
+
|
173
195
|
def build_command_array(prompt, options)
|
174
196
|
cmd_array = ["claude"]
|
175
197
|
|
@@ -11,7 +11,7 @@ module ClaudeSwarm
|
|
11
11
|
class ClaudeMcpServer
|
12
12
|
# Class variables to share state with tool classes
|
13
13
|
class << self
|
14
|
-
attr_accessor :executor, :instance_config, :logger, :
|
14
|
+
attr_accessor :executor, :instance_config, :logger, :session_path, :calling_instance
|
15
15
|
end
|
16
16
|
|
17
17
|
def initialize(instance_config, calling_instance:)
|
@@ -30,7 +30,7 @@ module ClaudeSwarm
|
|
30
30
|
self.class.executor = @executor
|
31
31
|
self.class.instance_config = @instance_config
|
32
32
|
self.class.logger = @executor.logger
|
33
|
-
self.class.
|
33
|
+
self.class.session_path = @executor.session_path
|
34
34
|
self.class.calling_instance = @calling_instance
|
35
35
|
end
|
36
36
|
|
data/lib/claude_swarm/cli.rb
CHANGED
@@ -41,12 +41,10 @@ module ClaudeSwarm
|
|
41
41
|
|
42
42
|
begin
|
43
43
|
config = Configuration.new(config_path)
|
44
|
-
|
45
|
-
generator = McpGenerator.new(config, vibe: options[:vibe], timestamp: session_timestamp)
|
44
|
+
generator = McpGenerator.new(config, vibe: options[:vibe])
|
46
45
|
orchestrator = Orchestrator.new(config, generator,
|
47
46
|
vibe: options[:vibe],
|
48
47
|
prompt: options[:prompt],
|
49
|
-
session_timestamp: session_timestamp,
|
50
48
|
stream_logs: options[:stream_logs],
|
51
49
|
debug: options[:debug])
|
52
50
|
orchestrator.start
|
@@ -68,6 +68,7 @@ module ClaudeSwarm
|
|
68
68
|
@instances[name] = parse_instance(name, config)
|
69
69
|
end
|
70
70
|
validate_connections
|
71
|
+
detect_circular_dependencies
|
71
72
|
end
|
72
73
|
|
73
74
|
def parse_instance(name, config)
|
@@ -127,6 +128,31 @@ module ClaudeSwarm
|
|
127
128
|
end
|
128
129
|
end
|
129
130
|
|
131
|
+
def detect_circular_dependencies
|
132
|
+
@instances.each_key do |instance_name|
|
133
|
+
visited = Set.new
|
134
|
+
path = []
|
135
|
+
detect_cycle_from(instance_name, visited, path)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def detect_cycle_from(instance_name, visited, path)
|
140
|
+
return if visited.include?(instance_name)
|
141
|
+
|
142
|
+
if path.include?(instance_name)
|
143
|
+
cycle_start = path.index(instance_name)
|
144
|
+
cycle = path[cycle_start..] + [instance_name]
|
145
|
+
raise Error, "Circular dependency detected: #{cycle.join(" -> ")}"
|
146
|
+
end
|
147
|
+
|
148
|
+
path.push(instance_name)
|
149
|
+
@instances[instance_name][:connections].each do |connection|
|
150
|
+
detect_cycle_from(connection, visited, path)
|
151
|
+
end
|
152
|
+
path.pop
|
153
|
+
visited.add(instance_name)
|
154
|
+
end
|
155
|
+
|
130
156
|
def validate_directories
|
131
157
|
@instances.each do |name, instance|
|
132
158
|
directory = instance[:directory]
|
@@ -3,16 +3,14 @@
|
|
3
3
|
require "json"
|
4
4
|
require "fileutils"
|
5
5
|
require "shellwords"
|
6
|
+
require_relative "session_path"
|
6
7
|
|
7
8
|
module ClaudeSwarm
|
8
9
|
class McpGenerator
|
9
|
-
|
10
|
-
SESSIONS_SUBDIR = "sessions"
|
11
|
-
|
12
|
-
def initialize(configuration, vibe: false, timestamp: nil)
|
10
|
+
def initialize(configuration, vibe: false)
|
13
11
|
@config = configuration
|
14
12
|
@vibe = vibe
|
15
|
-
@
|
13
|
+
@session_path = nil # Will be set when needed
|
16
14
|
end
|
17
15
|
|
18
16
|
def generate_all
|
@@ -24,24 +22,19 @@ module ClaudeSwarm
|
|
24
22
|
end
|
25
23
|
|
26
24
|
def mcp_config_path(instance_name)
|
27
|
-
File.join(
|
25
|
+
File.join(session_path, "#{instance_name}.mcp.json")
|
28
26
|
end
|
29
27
|
|
30
28
|
private
|
31
29
|
|
32
|
-
def
|
33
|
-
|
30
|
+
def session_path
|
31
|
+
@session_path ||= SessionPath.from_env
|
34
32
|
end
|
35
33
|
|
36
34
|
def ensure_swarm_directory
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
session_dir = File.join(swarm_dir, SESSIONS_SUBDIR, @timestamp)
|
41
|
-
FileUtils.mkdir_p(session_dir)
|
42
|
-
|
43
|
-
gitignore_path = File.join(swarm_dir, ".gitignore")
|
44
|
-
File.write(gitignore_path, "*\n") unless File.exist?(gitignore_path)
|
35
|
+
# Session directory is already created by orchestrator
|
36
|
+
# Just ensure it exists
|
37
|
+
SessionPath.ensure_directory(session_path)
|
45
38
|
end
|
46
39
|
|
47
40
|
def generate_mcp_config(name, instance)
|
@@ -134,10 +127,7 @@ module ClaudeSwarm
|
|
134
127
|
{
|
135
128
|
"type" => "stdio",
|
136
129
|
"command" => exe_path,
|
137
|
-
"args" => args
|
138
|
-
"env" => {
|
139
|
-
"CLAUDE_SWARM_SESSION_TIMESTAMP" => @timestamp
|
140
|
-
}
|
130
|
+
"args" => args
|
141
131
|
}
|
142
132
|
end
|
143
133
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "shellwords"
|
4
|
+
require_relative "session_path"
|
4
5
|
|
5
6
|
module ClaudeSwarm
|
6
7
|
class Orchestrator
|
7
|
-
def initialize(configuration, mcp_generator, vibe: false, prompt: nil,
|
8
|
+
def initialize(configuration, mcp_generator, vibe: false, prompt: nil, stream_logs: false, debug: false)
|
8
9
|
@config = configuration
|
9
10
|
@generator = mcp_generator
|
10
11
|
@vibe = vibe
|
11
12
|
@prompt = prompt
|
12
|
-
@session_timestamp = session_timestamp || Time.now.strftime("%Y%m%d_%H%M%S")
|
13
13
|
@stream_logs = stream_logs
|
14
14
|
@debug = debug
|
15
15
|
end
|
@@ -21,10 +21,15 @@ module ClaudeSwarm
|
|
21
21
|
puts
|
22
22
|
end
|
23
23
|
|
24
|
-
#
|
25
|
-
|
24
|
+
# Generate and set session path for all instances
|
25
|
+
session_path = SessionPath.generate(working_dir: Dir.pwd)
|
26
|
+
SessionPath.ensure_directory(session_path)
|
27
|
+
|
28
|
+
ENV["CLAUDE_SWARM_SESSION_PATH"] = session_path
|
29
|
+
ENV["CLAUDE_SWARM_START_DIR"] = Dir.pwd
|
30
|
+
|
26
31
|
unless @prompt
|
27
|
-
puts "📝 Session files will be saved to:
|
32
|
+
puts "📝 Session files will be saved to: #{session_path}/"
|
28
33
|
puts
|
29
34
|
end
|
30
35
|
|
@@ -74,9 +79,7 @@ module ClaudeSwarm
|
|
74
79
|
|
75
80
|
def start_log_streaming
|
76
81
|
Thread.new do
|
77
|
-
session_log_path = File.join(
|
78
|
-
ClaudeSwarm::ClaudeCodeExecutor::SESSIONS_DIR,
|
79
|
-
@session_timestamp, "session.log")
|
82
|
+
session_log_path = File.join(ENV.fetch("CLAUDE_SWARM_SESSION_PATH", nil), "session.log")
|
80
83
|
|
81
84
|
# Wait for log file to be created
|
82
85
|
sleep 0.1 until File.exist?(session_log_path)
|
@@ -5,13 +5,10 @@ require "fast_mcp"
|
|
5
5
|
require "logger"
|
6
6
|
require "fileutils"
|
7
7
|
require_relative "permission_tool"
|
8
|
+
require_relative "session_path"
|
8
9
|
|
9
10
|
module ClaudeSwarm
|
10
11
|
class PermissionMcpServer
|
11
|
-
# Directory constants
|
12
|
-
SWARM_DIR = ".claude-swarm"
|
13
|
-
SESSIONS_DIR = "sessions"
|
14
|
-
|
15
12
|
# Server configuration
|
16
13
|
SERVER_NAME = "claude-swarm-permissions"
|
17
14
|
SERVER_VERSION = "1.0.0"
|
@@ -60,20 +57,14 @@ module ClaudeSwarm
|
|
60
57
|
end
|
61
58
|
|
62
59
|
def setup_logging
|
63
|
-
|
64
|
-
|
60
|
+
session_path = SessionPath.from_env
|
61
|
+
SessionPath.ensure_directory(session_path)
|
62
|
+
@logger = create_logger(session_path)
|
65
63
|
@logger.info("Permission MCP server logging initialized")
|
66
64
|
end
|
67
65
|
|
68
|
-
def
|
69
|
-
|
70
|
-
session_dir = File.join(Dir.pwd, SWARM_DIR, SESSIONS_DIR, session_timestamp)
|
71
|
-
FileUtils.mkdir_p(session_dir)
|
72
|
-
session_dir
|
73
|
-
end
|
74
|
-
|
75
|
-
def create_logger(session_dir)
|
76
|
-
log_path = File.join(session_dir, "permissions.log")
|
66
|
+
def create_logger(session_path)
|
67
|
+
log_path = File.join(session_path, "permissions.log")
|
77
68
|
logger = Logger.new(log_path)
|
78
69
|
logger.level = Logger::DEBUG
|
79
70
|
logger.formatter = log_formatter
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
|
5
|
+
module ClaudeSwarm
|
6
|
+
module SessionPath
|
7
|
+
SESSIONS_DIR = "sessions"
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def swarm_home
|
11
|
+
ENV["CLAUDE_SWARM_HOME"] || File.expand_path("~/.claude-swarm")
|
12
|
+
end
|
13
|
+
|
14
|
+
# Convert a directory path to a safe folder name using + as separator
|
15
|
+
def project_folder_name(working_dir = Dir.pwd)
|
16
|
+
# Don't expand path if it's already expanded (avoids double expansion on Windows)
|
17
|
+
path = working_dir.start_with?("/") || working_dir.match?(/^[A-Za-z]:/) ? working_dir : File.expand_path(working_dir)
|
18
|
+
|
19
|
+
# Handle Windows drive letters (C:\ → C)
|
20
|
+
path = path.gsub(/^([A-Za-z]):/, '\1')
|
21
|
+
|
22
|
+
# Remove leading slash/backslash
|
23
|
+
path = path.sub(%r{^[/\\]}, "")
|
24
|
+
|
25
|
+
# Replace all path separators with +
|
26
|
+
path.gsub(%r{[/\\]}, "+")
|
27
|
+
end
|
28
|
+
|
29
|
+
# Generate a full session path for a given directory and timestamp
|
30
|
+
def generate(working_dir: Dir.pwd, timestamp: Time.now.strftime("%Y%m%d_%H%M%S"))
|
31
|
+
project_name = project_folder_name(working_dir)
|
32
|
+
File.join(swarm_home, SESSIONS_DIR, project_name, timestamp)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Ensure the session directory exists
|
36
|
+
def ensure_directory(session_path)
|
37
|
+
FileUtils.mkdir_p(session_path)
|
38
|
+
|
39
|
+
# Add .gitignore to swarm home if it doesn't exist
|
40
|
+
gitignore_path = File.join(swarm_home, ".gitignore")
|
41
|
+
File.write(gitignore_path, "*\n") unless File.exist?(gitignore_path)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Get the session path from environment (required)
|
45
|
+
def from_env
|
46
|
+
ENV["CLAUDE_SWARM_SESSION_PATH"] or raise "CLAUDE_SWARM_SESSION_PATH not set"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/claude_swarm/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: claude_swarm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paulo Arruda
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- README.md
|
59
59
|
- RELEASING.md
|
60
60
|
- Rakefile
|
61
|
+
- claude-swarm.yml
|
61
62
|
- example/claude-swarm.yml
|
62
63
|
- example/microservices-team.yml
|
63
64
|
- example/test-generation.yml
|
@@ -73,6 +74,7 @@ files:
|
|
73
74
|
- lib/claude_swarm/permission_tool.rb
|
74
75
|
- lib/claude_swarm/reset_session_tool.rb
|
75
76
|
- lib/claude_swarm/session_info_tool.rb
|
77
|
+
- lib/claude_swarm/session_path.rb
|
76
78
|
- lib/claude_swarm/task_tool.rb
|
77
79
|
- lib/claude_swarm/version.rb
|
78
80
|
- sdk-docs.md
|