claude_swarm 0.3.10 → 0.3.11
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 +22 -0
- data/lib/claude_swarm/cli.rb +9 -6
- data/lib/claude_swarm/configuration.rb +16 -10
- data/lib/claude_swarm/orchestrator.rb +43 -9
- data/lib/claude_swarm/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e0bade0292291825648214e0a1a420241ec1d6ffff018831d131d5c0f532e45
|
4
|
+
data.tar.gz: 74d62b916f1dbde6b725e8990924839c6ace2b6de75cb812f43305d044def7b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f7f0b3dad9bb034a5b1cf07417df7b3cef6dc7fa88d02d4c9617db354ff0f52d7a368f678f0d2502343fdb03112cf8672f68f2dce3a77a46d769f4cc8f0afa6
|
7
|
+
data.tar.gz: d2c81f31e2534e4f92f519ea1b218236d68ed2e08adbd3bfdb2d0569de1a5f80a2f5b2452e3c47b75e6e4441fb70575ca1fbf381d169c0b9ee2aca4b2072c7d6
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
## [Unreleased]
|
2
|
+
|
3
|
+
## [0.3.11]
|
4
|
+
|
5
|
+
### Added
|
6
|
+
- **Deferred directory validation for before commands**: Directories are now validated after `before` commands run, allowing them to create required directories
|
7
|
+
- Automatically skips initial directory validation when `before` commands are present in configuration
|
8
|
+
- Validates all directories after `before` commands complete successfully
|
9
|
+
- Enables dynamic directory creation workflows without pre-creating directory structures
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
- **--root-dir parameter path resolution**: Fixed relative config file paths to be resolved relative to the --root-dir value instead of current directory
|
13
|
+
- Config paths are now expanded using the root directory as the base path
|
14
|
+
- Allows running claude-swarm from any location with consistent path resolution
|
15
|
+
- Absolute paths continue to work as expected regardless of --root-dir setting
|
16
|
+
|
17
|
+
### Improved
|
18
|
+
- **Enhanced worktree cleanup on errors**: Improved error handling to ensure worktrees are always cleaned up properly
|
19
|
+
- Added comprehensive error handling with cleanup at all failure points
|
20
|
+
- Worktrees are now cleaned up when worktree setup fails, before commands fail, or directory validation fails
|
21
|
+
- Prevents orphaned worktrees that could clutter the system or cause issues with future runs
|
22
|
+
|
1
23
|
## [0.3.10]
|
2
24
|
|
3
25
|
### Added
|
data/lib/claude_swarm/cli.rb
CHANGED
@@ -42,16 +42,19 @@ module ClaudeSwarm
|
|
42
42
|
type: :string,
|
43
43
|
desc: "Root directory for resolving relative paths (defaults to current directory)"
|
44
44
|
def start(config_file = nil)
|
45
|
+
# Set root directory early so it's available to all components
|
46
|
+
root_dir = options[:root_dir] || Dir.pwd
|
47
|
+
ENV["CLAUDE_SWARM_ROOT_DIR"] = File.expand_path(root_dir)
|
48
|
+
|
49
|
+
# Resolve config path relative to root directory
|
45
50
|
config_path = config_file || "claude-swarm.yml"
|
51
|
+
config_path = File.expand_path(config_path, root_dir)
|
52
|
+
|
46
53
|
unless File.exist?(config_path)
|
47
54
|
error("Configuration file not found: #{config_path}")
|
48
55
|
exit(1)
|
49
56
|
end
|
50
57
|
|
51
|
-
# Set root directory early so it's available to all components
|
52
|
-
root_dir = options[:root_dir] || Dir.pwd
|
53
|
-
ENV["CLAUDE_SWARM_ROOT_DIR"] = File.expand_path(root_dir)
|
54
|
-
|
55
58
|
say("Starting Claude Swarm from #{config_path}...") unless options[:prompt]
|
56
59
|
|
57
60
|
# Validate stream_logs option
|
@@ -331,7 +334,7 @@ module ClaudeSwarm
|
|
331
334
|
system!("command -v claude > /dev/null 2>&1")
|
332
335
|
rescue Error
|
333
336
|
error("Claude CLI is not installed or not in PATH")
|
334
|
-
|
337
|
+
error("To install Claude CLI, visit: https://docs.anthropic.com/en/docs/claude-code")
|
335
338
|
exit(1)
|
336
339
|
end
|
337
340
|
|
@@ -508,7 +511,7 @@ module ClaudeSwarm
|
|
508
511
|
private
|
509
512
|
|
510
513
|
def error(message)
|
511
|
-
|
514
|
+
$stderr.puts(Thor::Shell::Color.new.set_color(message, :red))
|
512
515
|
end
|
513
516
|
|
514
517
|
def restore_session(session_id)
|
@@ -43,15 +43,30 @@ module ClaudeSwarm
|
|
43
43
|
@swarm["after"] || []
|
44
44
|
end
|
45
45
|
|
46
|
+
def validate_directories
|
47
|
+
@instances.each do |name, instance|
|
48
|
+
# Validate all directories in the directories array
|
49
|
+
instance[:directories].each do |directory|
|
50
|
+
raise Error, "Directory '#{directory}' for instance '#{name}' does not exist" unless File.directory?(directory)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
46
55
|
private
|
47
56
|
|
57
|
+
def has_before_commands?
|
58
|
+
@swarm && @swarm["before"] && !@swarm["before"].empty?
|
59
|
+
end
|
60
|
+
|
48
61
|
def load_and_validate
|
49
62
|
@config = YAML.load_file(@config_path)
|
50
63
|
interpolate_env_vars!(@config)
|
51
64
|
validate_version
|
52
65
|
validate_swarm
|
53
66
|
parse_swarm
|
54
|
-
|
67
|
+
# Skip directory validation if before commands are present
|
68
|
+
# They might create the directories
|
69
|
+
validate_directories unless has_before_commands?
|
55
70
|
rescue Errno::ENOENT
|
56
71
|
raise Error, "Configuration file not found: #{@config_path}"
|
57
72
|
rescue Psych::SyntaxError => e
|
@@ -273,15 +288,6 @@ module ClaudeSwarm
|
|
273
288
|
visited.add(instance_name)
|
274
289
|
end
|
275
290
|
|
276
|
-
def validate_directories
|
277
|
-
@instances.each do |name, instance|
|
278
|
-
# Validate all directories in the directories array
|
279
|
-
instance[:directories].each do |directory|
|
280
|
-
raise Error, "Directory '#{directory}' for instance '#{name}' does not exist" unless File.directory?(directory)
|
281
|
-
end
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
291
|
def validate_tool_field(instance_name, config, field_name)
|
286
292
|
return unless config.key?(field_name)
|
287
293
|
|
@@ -73,6 +73,20 @@ module ClaudeSwarm
|
|
73
73
|
# Track start time
|
74
74
|
@start_time = Time.now
|
75
75
|
|
76
|
+
begin
|
77
|
+
start_internal
|
78
|
+
rescue StandardError => e
|
79
|
+
# Ensure cleanup happens even on unexpected errors
|
80
|
+
cleanup_processes
|
81
|
+
cleanup_run_symlink
|
82
|
+
cleanup_worktrees
|
83
|
+
raise e
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def start_internal
|
76
90
|
if @restore_session_path
|
77
91
|
non_interactive_output do
|
78
92
|
puts "🔄 Restoring Claude Swarm: #{@config.swarm_name}"
|
@@ -115,16 +129,24 @@ module ClaudeSwarm
|
|
115
129
|
|
116
130
|
# Setup worktrees if needed
|
117
131
|
if @worktree_manager
|
118
|
-
|
132
|
+
begin
|
133
|
+
non_interactive_output { print("🌳 Setting up Git worktrees...") }
|
119
134
|
|
120
|
-
|
121
|
-
|
122
|
-
|
135
|
+
# Get all instances for worktree setup
|
136
|
+
# Note: instances.values already includes the main instance
|
137
|
+
all_instances = @config.instances.values
|
123
138
|
|
124
|
-
|
139
|
+
@worktree_manager.setup_worktrees(all_instances)
|
125
140
|
|
126
|
-
|
127
|
-
|
141
|
+
non_interactive_output do
|
142
|
+
puts "✓ Worktrees created with branch: #{@worktree_manager.worktree_name}"
|
143
|
+
end
|
144
|
+
rescue StandardError => e
|
145
|
+
non_interactive_output { print("❌ Failed to setup worktrees: #{e.message}") }
|
146
|
+
cleanup_processes
|
147
|
+
cleanup_run_symlink
|
148
|
+
cleanup_worktrees
|
149
|
+
raise
|
128
150
|
end
|
129
151
|
end
|
130
152
|
|
@@ -200,6 +222,20 @@ module ClaudeSwarm
|
|
200
222
|
non_interactive_output do
|
201
223
|
puts "✓ Before commands completed successfully"
|
202
224
|
end
|
225
|
+
|
226
|
+
# Validate directories after before commands have run
|
227
|
+
begin
|
228
|
+
@config.validate_directories
|
229
|
+
non_interactive_output do
|
230
|
+
puts "✓ All directories validated successfully"
|
231
|
+
end
|
232
|
+
rescue ClaudeSwarm::Error => e
|
233
|
+
non_interactive_output { print("❌ Directory validation failed: #{e.message}") }
|
234
|
+
cleanup_processes
|
235
|
+
cleanup_run_symlink
|
236
|
+
cleanup_worktrees
|
237
|
+
exit(1)
|
238
|
+
end
|
203
239
|
end
|
204
240
|
|
205
241
|
# Execute main Claude instance with unbundled environment to avoid bundler conflicts
|
@@ -249,8 +285,6 @@ module ClaudeSwarm
|
|
249
285
|
cleanup_worktrees
|
250
286
|
end
|
251
287
|
|
252
|
-
private
|
253
|
-
|
254
288
|
def non_interactive_output
|
255
289
|
return if @non_interactive_prompt
|
256
290
|
|
data/lib/claude_swarm/version.rb
CHANGED