claude_swarm 1.0.0 → 1.0.2
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/.claude/commands/release.md +1 -1
- data/.claude/hooks/lint-code-files.rb +65 -0
- data/.rubocop.yml +22 -2
- data/CHANGELOG.md +21 -1
- data/CLAUDE.md +1 -1
- data/CONTRIBUTING.md +69 -0
- data/README.md +27 -2
- data/Rakefile +71 -3
- data/analyze_coverage.rb +94 -0
- data/docs/v2/CHANGELOG.swarm_cli.md +43 -0
- data/docs/v2/CHANGELOG.swarm_memory.md +379 -0
- data/docs/v2/CHANGELOG.swarm_sdk.md +362 -0
- data/docs/v2/README.md +308 -0
- data/docs/v2/guides/claude-code-agents.md +262 -0
- data/docs/v2/guides/complete-tutorial.md +3088 -0
- data/docs/v2/guides/getting-started.md +1456 -0
- data/docs/v2/guides/memory-adapters.md +998 -0
- data/docs/v2/guides/plugins.md +816 -0
- data/docs/v2/guides/quick-start-cli.md +1745 -0
- data/docs/v2/guides/rails-integration.md +1902 -0
- data/docs/v2/guides/swarm-memory.md +599 -0
- data/docs/v2/reference/cli.md +729 -0
- data/docs/v2/reference/ruby-dsl.md +2154 -0
- data/docs/v2/reference/yaml.md +1835 -0
- data/docs-team-swarm.yml +2222 -0
- data/examples/learning-assistant/assistant.md +7 -0
- data/examples/learning-assistant/example-memories/concept-example.md +90 -0
- data/examples/learning-assistant/example-memories/experience-example.md +66 -0
- data/examples/learning-assistant/example-memories/fact-example.md +76 -0
- data/examples/learning-assistant/example-memories/memory-index.md +78 -0
- data/examples/learning-assistant/example-memories/skill-example.md +168 -0
- data/examples/learning-assistant/learning_assistant.rb +34 -0
- data/examples/learning-assistant/learning_assistant.yml +20 -0
- data/examples/v2/dsl/01_basic.rb +44 -0
- data/examples/v2/dsl/02_core_parameters.rb +59 -0
- data/examples/v2/dsl/03_capabilities.rb +71 -0
- data/examples/v2/dsl/04_llm_parameters.rb +56 -0
- data/examples/v2/dsl/05_advanced_flags.rb +73 -0
- data/examples/v2/dsl/06_permissions.rb +80 -0
- data/examples/v2/dsl/07_mcp_server.rb +62 -0
- data/examples/v2/dsl/08_swarm_hooks.rb +53 -0
- data/examples/v2/dsl/09_agent_hooks.rb +67 -0
- data/examples/v2/dsl/10_all_agents_hooks.rb +67 -0
- data/examples/v2/dsl/11_delegation.rb +60 -0
- data/examples/v2/dsl/12_complete_integration.rb +137 -0
- data/examples/v2/file_tools_swarm.yml +102 -0
- data/examples/v2/hooks/01_basic_hooks.rb +133 -0
- data/examples/v2/hooks/02_usage_tracking.rb +201 -0
- data/examples/v2/hooks/03_production_monitoring.rb +429 -0
- data/examples/v2/hooks/agent_stop_exit_0.yml +21 -0
- data/examples/v2/hooks/agent_stop_exit_1.yml +21 -0
- data/examples/v2/hooks/agent_stop_exit_2.yml +26 -0
- data/examples/v2/hooks/multiple_hooks_all_pass.yml +37 -0
- data/examples/v2/hooks/multiple_hooks_first_fails.yml +37 -0
- data/examples/v2/hooks/multiple_hooks_second_fails.yml +37 -0
- data/examples/v2/hooks/multiple_hooks_warnings.yml +37 -0
- data/examples/v2/hooks/post_tool_use_exit_0.yml +24 -0
- data/examples/v2/hooks/post_tool_use_exit_1.yml +24 -0
- data/examples/v2/hooks/post_tool_use_exit_2.yml +24 -0
- data/examples/v2/hooks/post_tool_use_multi_matcher_exit_0.yml +26 -0
- data/examples/v2/hooks/post_tool_use_multi_matcher_exit_1.yml +26 -0
- data/examples/v2/hooks/post_tool_use_multi_matcher_exit_2.yml +26 -0
- data/examples/v2/hooks/pre_tool_use_exit_0.yml +24 -0
- data/examples/v2/hooks/pre_tool_use_exit_1.yml +24 -0
- data/examples/v2/hooks/pre_tool_use_exit_2.yml +24 -0
- data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_0.yml +26 -0
- data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_1.yml +26 -0
- data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_2.yml +27 -0
- data/examples/v2/hooks/swarm_summary.sh +44 -0
- data/examples/v2/hooks/user_prompt_exit_0.yml +21 -0
- data/examples/v2/hooks/user_prompt_exit_1.yml +21 -0
- data/examples/v2/hooks/user_prompt_exit_2.yml +21 -0
- data/examples/v2/hooks/validate_bash.rb +59 -0
- data/examples/v2/multi_directory_permissions.yml +221 -0
- data/examples/v2/node_context_demo.rb +127 -0
- data/examples/v2/node_workflow.rb +173 -0
- data/examples/v2/path_resolution_demo.rb +216 -0
- data/examples/v2/simple-swarm-v2.rb +90 -0
- data/examples/v2/simple-swarm-v2.yml +62 -0
- data/examples/v2/swarm.yml +71 -0
- data/examples/v2/swarm_with_hooks.yml +61 -0
- data/examples/v2/swarm_with_hooks_simple.yml +25 -0
- data/examples/v2/think_tool_demo.rb +62 -0
- data/exe/swarm +6 -0
- data/lib/claude_swarm/claude_mcp_server.rb +0 -6
- data/lib/claude_swarm/cli.rb +10 -3
- data/lib/claude_swarm/commands/ps.rb +19 -20
- data/lib/claude_swarm/commands/show.rb +1 -1
- data/lib/claude_swarm/configuration.rb +10 -12
- data/lib/claude_swarm/mcp_generator.rb +10 -1
- data/lib/claude_swarm/orchestrator.rb +73 -49
- data/lib/claude_swarm/system_utils.rb +37 -11
- data/lib/claude_swarm/version.rb +1 -1
- data/lib/claude_swarm/worktree_manager.rb +1 -0
- data/lib/claude_swarm/yaml_loader.rb +22 -0
- data/lib/claude_swarm.rb +7 -3
- data/lib/swarm_cli/cli.rb +201 -0
- data/lib/swarm_cli/command_registry.rb +61 -0
- data/lib/swarm_cli/commands/mcp_serve.rb +130 -0
- data/lib/swarm_cli/commands/mcp_tools.rb +148 -0
- data/lib/swarm_cli/commands/migrate.rb +55 -0
- data/lib/swarm_cli/commands/run.rb +173 -0
- data/lib/swarm_cli/config_loader.rb +97 -0
- data/lib/swarm_cli/formatters/human_formatter.rb +711 -0
- data/lib/swarm_cli/formatters/json_formatter.rb +51 -0
- data/lib/swarm_cli/interactive_repl.rb +918 -0
- data/lib/swarm_cli/mcp_serve_options.rb +44 -0
- data/lib/swarm_cli/mcp_tools_options.rb +59 -0
- data/lib/swarm_cli/migrate_options.rb +54 -0
- data/lib/swarm_cli/migrator.rb +132 -0
- data/lib/swarm_cli/options.rb +151 -0
- data/lib/swarm_cli/ui/components/agent_badge.rb +33 -0
- data/lib/swarm_cli/ui/components/content_block.rb +120 -0
- data/lib/swarm_cli/ui/components/divider.rb +57 -0
- data/lib/swarm_cli/ui/components/panel.rb +62 -0
- data/lib/swarm_cli/ui/components/usage_stats.rb +70 -0
- data/lib/swarm_cli/ui/formatters/cost.rb +49 -0
- data/lib/swarm_cli/ui/formatters/number.rb +58 -0
- data/lib/swarm_cli/ui/formatters/text.rb +77 -0
- data/lib/swarm_cli/ui/formatters/time.rb +73 -0
- data/lib/swarm_cli/ui/icons.rb +59 -0
- data/lib/swarm_cli/ui/renderers/event_renderer.rb +188 -0
- data/lib/swarm_cli/ui/state/agent_color_cache.rb +45 -0
- data/lib/swarm_cli/ui/state/depth_tracker.rb +40 -0
- data/lib/swarm_cli/ui/state/spinner_manager.rb +170 -0
- data/lib/swarm_cli/ui/state/usage_tracker.rb +62 -0
- data/lib/swarm_cli/version.rb +5 -0
- data/lib/swarm_cli.rb +44 -0
- data/lib/swarm_memory/adapters/base.rb +141 -0
- data/lib/swarm_memory/adapters/filesystem_adapter.rb +845 -0
- data/lib/swarm_memory/chat_extension.rb +34 -0
- data/lib/swarm_memory/cli/commands.rb +306 -0
- data/lib/swarm_memory/core/entry.rb +37 -0
- data/lib/swarm_memory/core/frontmatter_parser.rb +108 -0
- data/lib/swarm_memory/core/metadata_extractor.rb +68 -0
- data/lib/swarm_memory/core/path_normalizer.rb +75 -0
- data/lib/swarm_memory/core/semantic_index.rb +244 -0
- data/lib/swarm_memory/core/storage.rb +288 -0
- data/lib/swarm_memory/core/storage_read_tracker.rb +63 -0
- data/lib/swarm_memory/dsl/builder_extension.rb +40 -0
- data/lib/swarm_memory/dsl/memory_config.rb +113 -0
- data/lib/swarm_memory/embeddings/embedder.rb +36 -0
- data/lib/swarm_memory/embeddings/informers_embedder.rb +152 -0
- data/lib/swarm_memory/errors.rb +21 -0
- data/lib/swarm_memory/integration/cli_registration.rb +30 -0
- data/lib/swarm_memory/integration/configuration.rb +43 -0
- data/lib/swarm_memory/integration/registration.rb +31 -0
- data/lib/swarm_memory/integration/sdk_plugin.rb +531 -0
- data/lib/swarm_memory/optimization/analyzer.rb +244 -0
- data/lib/swarm_memory/optimization/defragmenter.rb +863 -0
- data/lib/swarm_memory/prompts/memory.md.erb +109 -0
- data/lib/swarm_memory/prompts/memory_assistant.md.erb +181 -0
- data/lib/swarm_memory/prompts/memory_researcher.md.erb +281 -0
- data/lib/swarm_memory/prompts/memory_retrieval.md.erb +78 -0
- data/lib/swarm_memory/search/semantic_search.rb +112 -0
- data/lib/swarm_memory/search/text_search.rb +42 -0
- data/lib/swarm_memory/search/text_similarity.rb +80 -0
- data/lib/swarm_memory/skills/meta/deep-learning.md +101 -0
- data/lib/swarm_memory/skills/meta/deep-learning.yml +14 -0
- data/lib/swarm_memory/tools/load_skill.rb +313 -0
- data/lib/swarm_memory/tools/memory_defrag.rb +382 -0
- data/lib/swarm_memory/tools/memory_delete.rb +99 -0
- data/lib/swarm_memory/tools/memory_edit.rb +185 -0
- data/lib/swarm_memory/tools/memory_glob.rb +160 -0
- data/lib/swarm_memory/tools/memory_grep.rb +247 -0
- data/lib/swarm_memory/tools/memory_multi_edit.rb +281 -0
- data/lib/swarm_memory/tools/memory_read.rb +123 -0
- data/lib/swarm_memory/tools/memory_write.rb +231 -0
- data/lib/swarm_memory/utils.rb +50 -0
- data/lib/swarm_memory/version.rb +5 -0
- data/lib/swarm_memory.rb +166 -0
- data/lib/swarm_sdk/agent/RETRY_LOGIC.md +127 -0
- data/lib/swarm_sdk/agent/builder.rb +461 -0
- data/lib/swarm_sdk/agent/chat/context_tracker.rb +314 -0
- data/lib/swarm_sdk/agent/chat/hook_integration.rb +372 -0
- data/lib/swarm_sdk/agent/chat/logging_helpers.rb +116 -0
- data/lib/swarm_sdk/agent/chat/system_reminder_injector.rb +152 -0
- data/lib/swarm_sdk/agent/chat.rb +1159 -0
- data/lib/swarm_sdk/agent/context.rb +112 -0
- data/lib/swarm_sdk/agent/context_manager.rb +309 -0
- data/lib/swarm_sdk/agent/definition.rb +556 -0
- data/lib/swarm_sdk/claude_code_agent_adapter.rb +205 -0
- data/lib/swarm_sdk/configuration.rb +296 -0
- data/lib/swarm_sdk/context_compactor/metrics.rb +147 -0
- data/lib/swarm_sdk/context_compactor/token_counter.rb +106 -0
- data/lib/swarm_sdk/context_compactor.rb +340 -0
- data/lib/swarm_sdk/hooks/adapter.rb +359 -0
- data/lib/swarm_sdk/hooks/context.rb +197 -0
- data/lib/swarm_sdk/hooks/definition.rb +80 -0
- data/lib/swarm_sdk/hooks/error.rb +29 -0
- data/lib/swarm_sdk/hooks/executor.rb +146 -0
- data/lib/swarm_sdk/hooks/registry.rb +147 -0
- data/lib/swarm_sdk/hooks/result.rb +150 -0
- data/lib/swarm_sdk/hooks/shell_executor.rb +254 -0
- data/lib/swarm_sdk/hooks/tool_call.rb +35 -0
- data/lib/swarm_sdk/hooks/tool_result.rb +62 -0
- data/lib/swarm_sdk/log_collector.rb +51 -0
- data/lib/swarm_sdk/log_stream.rb +69 -0
- data/lib/swarm_sdk/markdown_parser.rb +75 -0
- data/lib/swarm_sdk/model_aliases.json +5 -0
- data/lib/swarm_sdk/models.json +1 -0
- data/lib/swarm_sdk/models.rb +120 -0
- data/lib/swarm_sdk/node/agent_config.rb +49 -0
- data/lib/swarm_sdk/node/builder.rb +439 -0
- data/lib/swarm_sdk/node/transformer_executor.rb +248 -0
- data/lib/swarm_sdk/node_context.rb +170 -0
- data/lib/swarm_sdk/node_orchestrator.rb +384 -0
- data/lib/swarm_sdk/permissions/config.rb +239 -0
- data/lib/swarm_sdk/permissions/error_formatter.rb +121 -0
- data/lib/swarm_sdk/permissions/path_matcher.rb +35 -0
- data/lib/swarm_sdk/permissions/validator.rb +173 -0
- data/lib/swarm_sdk/permissions_builder.rb +122 -0
- data/lib/swarm_sdk/plugin.rb +147 -0
- data/lib/swarm_sdk/plugin_registry.rb +101 -0
- data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +243 -0
- data/lib/swarm_sdk/providers/openai_with_responses.rb +582 -0
- data/lib/swarm_sdk/result.rb +97 -0
- data/lib/swarm_sdk/swarm/agent_initializer.rb +334 -0
- data/lib/swarm_sdk/swarm/all_agents_builder.rb +140 -0
- data/lib/swarm_sdk/swarm/builder.rb +586 -0
- data/lib/swarm_sdk/swarm/mcp_configurator.rb +151 -0
- data/lib/swarm_sdk/swarm/tool_configurator.rb +419 -0
- data/lib/swarm_sdk/swarm.rb +982 -0
- data/lib/swarm_sdk/tools/bash.rb +274 -0
- data/lib/swarm_sdk/tools/clock.rb +44 -0
- data/lib/swarm_sdk/tools/delegate.rb +164 -0
- data/lib/swarm_sdk/tools/document_converters/base_converter.rb +83 -0
- data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +99 -0
- data/lib/swarm_sdk/tools/document_converters/html_converter.rb +101 -0
- data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +78 -0
- data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +194 -0
- data/lib/swarm_sdk/tools/edit.rb +150 -0
- data/lib/swarm_sdk/tools/glob.rb +158 -0
- data/lib/swarm_sdk/tools/grep.rb +228 -0
- data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +43 -0
- data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +163 -0
- data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +65 -0
- data/lib/swarm_sdk/tools/multi_edit.rb +232 -0
- data/lib/swarm_sdk/tools/path_resolver.rb +43 -0
- data/lib/swarm_sdk/tools/read.rb +251 -0
- data/lib/swarm_sdk/tools/registry.rb +93 -0
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +96 -0
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +76 -0
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +91 -0
- data/lib/swarm_sdk/tools/stores/read_tracker.rb +61 -0
- data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +224 -0
- data/lib/swarm_sdk/tools/stores/storage.rb +148 -0
- data/lib/swarm_sdk/tools/stores/todo_manager.rb +65 -0
- data/lib/swarm_sdk/tools/think.rb +95 -0
- data/lib/swarm_sdk/tools/todo_write.rb +216 -0
- data/lib/swarm_sdk/tools/web_fetch.rb +261 -0
- data/lib/swarm_sdk/tools/write.rb +117 -0
- data/lib/swarm_sdk/utils.rb +50 -0
- data/lib/swarm_sdk/version.rb +5 -0
- data/lib/swarm_sdk.rb +157 -0
- data/llm.v2.txt +13407 -0
- data/rubocop/cop/security/no_reflection_methods.rb +47 -0
- data/rubocop/cop/security/no_ruby_llm_logger.rb +32 -0
- data/swarm_cli.gemspec +57 -0
- data/swarm_memory.gemspec +28 -0
- data/swarm_sdk.gemspec +41 -0
- data/team.yml +1 -1
- data/team_full.yml +1875 -0
- data/{team_v2.yml → team_sdk.yml} +121 -52
- metadata +247 -4
- data/EXAMPLES.md +0 -164
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e93aed255a253a1cd4b61a50e9c3a174c428711628825fb99f38d8b6d9a3127a
|
|
4
|
+
data.tar.gz: a2b609437aad4dd11347795f2df10d79920b191c4daedf5abf01ab381ba94773
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 680e21b7258a2a67d4f2f8534c1d6e4effccdf36d90d4ee3258f3a16d12540563893d2fb135d9a1f346c5fba3539a0cb42c3ba95b2e21aeded08c490eeb70493
|
|
7
|
+
data.tar.gz: 49a6d0978719fed57cee0e1254708b28a5cb22db9ad551273b122c8102a85191ecdefa8871e75b46b9ce92e6d45649476ced2fdd1a26bd53a2e057f8df2e232a
|
data/.claude/commands/release.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
description: Bump version, update changelog, and prepare for release
|
|
3
3
|
allowed-tools: [Read, Edit, Bash]
|
|
4
4
|
---
|
|
5
|
-
|
|
5
|
+
CRITICAL: Only use this for Claude Swarm. Not for SwarmSDK or SwarmCLI
|
|
6
6
|
Prepare a new release for Claude Swarm by:
|
|
7
7
|
|
|
8
8
|
1. Read the current version from @lib/claude_swarm/version.rb
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "English"
|
|
5
|
+
require "json"
|
|
6
|
+
|
|
7
|
+
begin
|
|
8
|
+
# Read JSON input from stdin
|
|
9
|
+
input = JSON.parse($stdin.read)
|
|
10
|
+
|
|
11
|
+
# Extract the file path from the tool input
|
|
12
|
+
file_path = input.dig("tool_input", "file_path") || ""
|
|
13
|
+
|
|
14
|
+
# Determine which linters to run based on file extension
|
|
15
|
+
# Exclude .md.erb files (markdown templates) from RuboCop
|
|
16
|
+
run_rubocop = file_path.end_with?(".rb", ".jbuilder", ".html.erb") ||
|
|
17
|
+
(file_path.end_with?(".erb") && !file_path.end_with?(".md.erb"))
|
|
18
|
+
run_erblint = file_path.end_with?(".erb", ".html.erb")
|
|
19
|
+
|
|
20
|
+
if !run_rubocop && !run_erblint
|
|
21
|
+
exit(0)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Change to project directory
|
|
25
|
+
project_dir = ENV["CLAUDE_PROJECT_DIR"]
|
|
26
|
+
unless project_dir
|
|
27
|
+
puts "⚠️ CLAUDE_PROJECT_DIR not set - cannot run linters"
|
|
28
|
+
exit(0)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
Dir.chdir(project_dir) do
|
|
32
|
+
errors = []
|
|
33
|
+
|
|
34
|
+
# Run RuboCop if applicable
|
|
35
|
+
if run_rubocop
|
|
36
|
+
%x(bundle exec rubocop -A #{file_path} 2>&1)
|
|
37
|
+
exit_code = $CHILD_STATUS.exitstatus
|
|
38
|
+
|
|
39
|
+
if exit_code != 0
|
|
40
|
+
result = %x(bundle exec rubocop -A #{file_path} 2>&1) # Run again so we only get the issues.
|
|
41
|
+
puts "⚠️ RuboCop found issues:"
|
|
42
|
+
puts result
|
|
43
|
+
errors << "RuboCop found issues that need manual fixing:\n#{result}"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Report any errors
|
|
48
|
+
if errors.any?
|
|
49
|
+
puts "Please review the remaining issues above and fix them."
|
|
50
|
+
|
|
51
|
+
# Exit with code 2 to make stderr visible to Claude
|
|
52
|
+
$stderr.puts errors.join("\n\n")
|
|
53
|
+
exit(2)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
rescue JSON::ParserError => e
|
|
57
|
+
$stderr.puts "Error parsing JSON: #{e.message}"
|
|
58
|
+
exit(1)
|
|
59
|
+
rescue StandardError => e
|
|
60
|
+
$stderr.puts "Error: #{e.message}"
|
|
61
|
+
exit(1)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Success case - exit with 0 to show stdout in transcript mode
|
|
65
|
+
exit(0)
|
data/.rubocop.yml
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
require:
|
|
2
|
+
- ./rubocop/cop/security/no_reflection_methods.rb
|
|
3
|
+
- ./rubocop/cop/security/no_ruby_llm_logger.rb
|
|
2
4
|
|
|
5
|
+
inherit_from: .rubocop_todo.yml
|
|
3
6
|
inherit_gem:
|
|
4
7
|
rubocop-shopify: rubocop.yml
|
|
5
8
|
|
|
@@ -11,4 +14,21 @@ AllCops:
|
|
|
11
14
|
TargetRubyVersion: 3.4
|
|
12
15
|
NewCops: enable
|
|
13
16
|
Exclude:
|
|
14
|
-
- '.ruby-lsp/**/*'
|
|
17
|
+
- '.ruby-lsp/**/*'
|
|
18
|
+
|
|
19
|
+
# Allow flexible naming in examples directory
|
|
20
|
+
Naming/FileName:
|
|
21
|
+
Exclude:
|
|
22
|
+
- 'examples/**/*'
|
|
23
|
+
|
|
24
|
+
Security/NoReflectionMethods:
|
|
25
|
+
Enabled: true
|
|
26
|
+
Exclude:
|
|
27
|
+
- lib/claude_swarm/**/*
|
|
28
|
+
- lib/claude_swarm.rb
|
|
29
|
+
- test/*.rb
|
|
30
|
+
- test/commands/**/*
|
|
31
|
+
- test/fixtures/**/*
|
|
32
|
+
|
|
33
|
+
# Security/NoRubyLlmLogger:
|
|
34
|
+
# Enabled: true
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
|
-
## [
|
|
1
|
+
## [1.0.2]
|
|
2
|
+
|
|
3
|
+
### Changed
|
|
4
|
+
- **Improved signal handling and graceful shutdown**: Enhanced signal handling for more reliable cleanup on interruption
|
|
5
|
+
- Added comprehensive signal handlers for `INT`, `TERM`, `QUIT`, and `HUP` signals
|
|
6
|
+
- Signals now trigger a graceful shutdown sequence that ensures all cleanup operations complete
|
|
7
|
+
- Moved signal trap setup from module-level to instance-level for better control and testability
|
|
8
|
+
- After commands now execute consistently during normal completion, signal-triggered shutdown, and error conditions
|
|
9
|
+
|
|
10
|
+
- **Simplified ProcessTracker usage**: ProcessTracker now only tracks the main Claude process
|
|
11
|
+
- Removed redundant MCP server PID tracking from `ClaudeMcpServer#start`
|
|
12
|
+
- The Claude process manages its own MCP server child processes
|
|
13
|
+
- When the main Claude process terminates, it automatically handles cleanup of its associated MCP servers
|
|
14
|
+
- Results in cleaner process hierarchy and more reliable cleanup
|
|
15
|
+
|
|
16
|
+
## [1.0.1]
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- **Fixed require statement for fast-mcp gem**: Updated `require "fast_mcp_annotations"` to `require "fast_mcp"` to match the gem dependency change in 1.0.0
|
|
20
|
+
- The gemspec was correctly updated to use fast-mcp (~> 1.6) in 1.0.0, but the require statement was not updated
|
|
21
|
+
- This fix ensures the correct gem is loaded at runtime
|
|
2
22
|
|
|
3
23
|
## [1.0.0]
|
|
4
24
|
|
data/CLAUDE.md
CHANGED
|
@@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
|
6
6
|
|
|
7
7
|
Claude Swarm is a Ruby gem that 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).
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
SwarmSDK is a complete reimagining of Claude Swarm that decouples from Claude Code and runs everything in a single process using RubyLLM for all LLM interactions. It is being developed in `lib/swarm_sdk`, and using the gemspec swarm-sdk.gemspec.
|
|
10
10
|
|
|
11
11
|
## Development Commands
|
|
12
12
|
|
data/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Contributing to Claude Swarm
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to Claude Swarm!
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Clone the repository
|
|
9
|
+
git clone https://github.com/parruda/claude-swarm.git
|
|
10
|
+
cd claude-swarm
|
|
11
|
+
|
|
12
|
+
# Install dependencies
|
|
13
|
+
bundle install
|
|
14
|
+
|
|
15
|
+
# Run tests
|
|
16
|
+
bundle exec rake test
|
|
17
|
+
|
|
18
|
+
# Run linter
|
|
19
|
+
bundle exec rubocop -A
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Running Tests
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Run all tests
|
|
26
|
+
bundle exec rake test
|
|
27
|
+
|
|
28
|
+
# Run specific test file
|
|
29
|
+
bundle exec ruby test/test_swarm_sdk.rb
|
|
30
|
+
|
|
31
|
+
# Run with coverage
|
|
32
|
+
COVERAGE=true bundle exec rake test
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Code Style
|
|
36
|
+
|
|
37
|
+
We use RuboCop for code style enforcement:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Check style
|
|
41
|
+
bundle exec rubocop
|
|
42
|
+
|
|
43
|
+
# Auto-fix issues
|
|
44
|
+
bundle exec rubocop -A
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Documentation
|
|
48
|
+
|
|
49
|
+
Documentation is in `docs/v2/` and follows this structure:
|
|
50
|
+
- `guides/` - User guides and tutorials
|
|
51
|
+
- `api/` - API reference documentation
|
|
52
|
+
- `architecture/` - System architecture docs
|
|
53
|
+
- `examples/` - Code examples
|
|
54
|
+
|
|
55
|
+
Update documentation when adding features.
|
|
56
|
+
|
|
57
|
+
## Pull Request Process
|
|
58
|
+
|
|
59
|
+
1. Fork the repository
|
|
60
|
+
2. Create a feature branch
|
|
61
|
+
3. Make your changes
|
|
62
|
+
4. Add tests for new functionality
|
|
63
|
+
5. Update documentation
|
|
64
|
+
6. Run tests and linter
|
|
65
|
+
7. Submit pull request
|
|
66
|
+
|
|
67
|
+
## Questions?
|
|
68
|
+
|
|
69
|
+
Open an issue on GitHub for questions or discussions.
|
data/README.md
CHANGED
|
@@ -1,10 +1,35 @@
|
|
|
1
|
+
# 🚀 SwarmSDK - The New Way
|
|
2
|
+
|
|
3
|
+
**We recommend using SwarmSDK v2 for new projects!** SwarmSDK is a complete redesign of Claude Swarm that provides a better developer experience. SwarmSDK is geared towards general-purpose agentic systems.
|
|
4
|
+
|
|
5
|
+
- **Decoupled from Claude Code**: No more dependency on Claude Code
|
|
6
|
+
- **Single Process Architecture**: All agents run in one Ruby process using [RubyLLM](https://github.com/parruda/ruby_llm) - no more managing multiple Claude Code instances
|
|
7
|
+
- **More Efficient**: Direct method calls instead of MCP inter-process communication
|
|
8
|
+
- **Richer Features**: Node workflows, hooks system, scratchpad/memory tools, and more
|
|
9
|
+
- **Better Control**: Fine-grained permissions, cost tracking, structured logging
|
|
10
|
+
- **REPL**: Built with TTY toolkit for a nice command-line experience
|
|
11
|
+
- **Multiple LLM Providers**: Supports all LLM providers supported by RubyLLM
|
|
12
|
+
|
|
13
|
+
## Getting Started with v2
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
gem install swarm_cli # Includes swarm_sdk
|
|
17
|
+
swarm --help # Explore the modern CLI
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**📚 Complete Documentation**: Check out the [SwarmSDK guides](docs/v2/README.md) including the comprehensive [complete tutorial](docs/v2/guides/complete-tutorial.md) covering all features.
|
|
21
|
+
|
|
22
|
+
**Note**: Claude Swarm (v1, documented below) will continue to be maintained and is still a great choice if you prefer the multi-process architecture with Claude Code instances.
|
|
23
|
+
|
|
1
24
|
# Claude Swarm
|
|
2
25
|
|
|
3
|
-
[](https://badge.fury.io/rb/claude_swarm)
|
|
4
27
|
[](https://github.com/parruda/claude-swarm/actions/workflows/ci.yml)
|
|
5
28
|
|
|
6
29
|
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.
|
|
7
30
|
|
|
31
|
+
---
|
|
32
|
+
|
|
8
33
|
## Table of Contents
|
|
9
34
|
|
|
10
35
|
- [Installation](#installation)
|
|
@@ -42,7 +67,7 @@ gem install claude_swarm
|
|
|
42
67
|
Or add it to your Gemfile:
|
|
43
68
|
|
|
44
69
|
```ruby
|
|
45
|
-
gem 'claude_swarm', "~> 0
|
|
70
|
+
gem 'claude_swarm', "~> 1.0"
|
|
46
71
|
```
|
|
47
72
|
|
|
48
73
|
Then run:
|
data/Rakefile
CHANGED
|
@@ -1,11 +1,79 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "bundler/gem_tasks"
|
|
4
3
|
require "minitest/test_task"
|
|
4
|
+
require "rubocop/rake_task"
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
# Run all tests (both claude_swarm and swarm_sdk)
|
|
7
|
+
Minitest::TestTask.create(:test) do |t|
|
|
8
|
+
t.test_globs = ["test/**/*_test.rb"]
|
|
9
|
+
t.warning = false
|
|
10
|
+
end
|
|
7
11
|
|
|
8
|
-
|
|
12
|
+
namespace :claude_swarm do
|
|
13
|
+
Minitest::TestTask.create(:test) do |t|
|
|
14
|
+
# Expand globs and subtract to get only claude_swarm tests
|
|
15
|
+
all_tests = Dir.glob("test/**/*_test.rb")
|
|
16
|
+
exclude_tests = Dir.glob("test/swarm_sdk/**/*_test.rb") +
|
|
17
|
+
Dir.glob("test/swarm_memory/**/*_test.rb") +
|
|
18
|
+
Dir.glob("test/swarm_cli/**/*_test.rb")
|
|
19
|
+
t.test_globs = all_tests - exclude_tests
|
|
20
|
+
t.warning = false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
RuboCop::RakeTask.new(:rubocop) do |t|
|
|
24
|
+
# Expand patterns and subtract
|
|
25
|
+
all_patterns = Dir.glob("lib/claude_swarm.rb") + Dir.glob("lib/claude_swarm/**/*.rb") + Dir.glob("test/**/*_test.rb")
|
|
26
|
+
exclude_patterns = Dir.glob("test/swarm_sdk/**/*.rb") +
|
|
27
|
+
Dir.glob("test/swarm_memory/**/*.rb") +
|
|
28
|
+
Dir.glob("test/swarm_cli/**/*.rb")
|
|
29
|
+
t.patterns = all_patterns - exclude_patterns
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
desc "Run ClaudeSwarm tests and linting"
|
|
33
|
+
task all: [:test, :rubocop]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
namespace :swarm_sdk do
|
|
37
|
+
Minitest::TestTask.create(:test) do |t|
|
|
38
|
+
t.test_globs = ["test/swarm_sdk/**/*_test.rb"]
|
|
39
|
+
t.warning = false
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
RuboCop::RakeTask.new(:rubocop) do |t|
|
|
43
|
+
t.patterns = ["lib/swarm_sdk.rb", "lib/swarm_sdk/**/*.rb", "test/swarm_sdk/**/*.rb"]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
desc "Run SwarmSDK tests and linting"
|
|
47
|
+
task all: [:test, :rubocop]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
namespace :swarm_cli do
|
|
51
|
+
Minitest::TestTask.create(:test) do |t|
|
|
52
|
+
t.test_globs = ["test/swarm_cli/**/*_test.rb"]
|
|
53
|
+
t.warning = false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
RuboCop::RakeTask.new(:rubocop) do |t|
|
|
57
|
+
t.patterns = ["lib/swarm_cli.rb", "lib/swarm_cli/**/*.rb", "test/swarm_cli/**/*.rb"]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
desc "Run SwarmCLI tests and linting"
|
|
61
|
+
task all: [:test, :rubocop]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
namespace :swarm_memory do
|
|
65
|
+
Minitest::TestTask.create(:test) do |t|
|
|
66
|
+
t.test_globs = ["test/swarm_memory/**/*_test.rb"]
|
|
67
|
+
t.warning = false
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
RuboCop::RakeTask.new(:rubocop) do |t|
|
|
71
|
+
t.patterns = ["lib/swarm_memory.rb", "lib/swarm_memory/**/*.rb", "test/swarm_memory/**/*.rb"]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
desc "Run SwarmMemory tests and linting"
|
|
75
|
+
task all: [:test, :rubocop]
|
|
76
|
+
end
|
|
9
77
|
|
|
10
78
|
RuboCop::RakeTask.new
|
|
11
79
|
|
data/analyze_coverage.rb
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "json"
|
|
5
|
+
|
|
6
|
+
data = JSON.parse(File.read("coverage/.resultset.json"))
|
|
7
|
+
coverage = data["Minitest"]["coverage"]
|
|
8
|
+
|
|
9
|
+
# Find SwarmSDK files with branches
|
|
10
|
+
swarm_files_with_branches = coverage.select do |file, data|
|
|
11
|
+
file.include?("/lib/swarm_sdk/") && data["branches"] && !data["branches"].empty?
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
puts "SwarmSDK Files with Branch Coverage Data:"
|
|
15
|
+
puts "=" * 80
|
|
16
|
+
|
|
17
|
+
results = []
|
|
18
|
+
|
|
19
|
+
swarm_files_with_branches.each do |file, data|
|
|
20
|
+
branches = data["branches"]
|
|
21
|
+
|
|
22
|
+
# Count total branch points
|
|
23
|
+
# Each element in branches array is [branch_id, {path1 => count1, path2 => count2, ...}]
|
|
24
|
+
total_branch_points = 0
|
|
25
|
+
covered_branch_points = 0
|
|
26
|
+
|
|
27
|
+
branches.each do |branch_info|
|
|
28
|
+
next unless branch_info.is_a?(Array) && branch_info.size == 2
|
|
29
|
+
|
|
30
|
+
branch_paths = branch_info[1]
|
|
31
|
+
next unless branch_paths.is_a?(Hash)
|
|
32
|
+
|
|
33
|
+
branch_paths.each do |_path, count|
|
|
34
|
+
total_branch_points += 1
|
|
35
|
+
covered_branch_points += 1 if count && count > 0
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
coverage_pct = total_branch_points > 0 ? (covered_branch_points.to_f / total_branch_points * 100).round(2) : 0
|
|
40
|
+
|
|
41
|
+
# Extract just the filename
|
|
42
|
+
filename = file.split("/").last(3).join("/")
|
|
43
|
+
|
|
44
|
+
results << {
|
|
45
|
+
file: filename,
|
|
46
|
+
full_path: file,
|
|
47
|
+
covered: covered_branch_points,
|
|
48
|
+
total: total_branch_points,
|
|
49
|
+
pct: coverage_pct,
|
|
50
|
+
uncovered_branches: branches.select do |branch_info|
|
|
51
|
+
next false unless branch_info.is_a?(Array) && branch_info.size == 2
|
|
52
|
+
|
|
53
|
+
branch_paths = branch_info[1]
|
|
54
|
+
next false unless branch_paths.is_a?(Hash)
|
|
55
|
+
|
|
56
|
+
# Check if ANY path is uncovered
|
|
57
|
+
branch_paths.any? { |_path, count| count.nil? || count == 0 }
|
|
58
|
+
end,
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Sort by coverage percentage (ascending - worst first)
|
|
63
|
+
results.sort_by { |r| r[:pct] }.each do |r|
|
|
64
|
+
puts format("%-50s %3d/%3d (%5.1f%%)", r[:file], r[:covered], r[:total], r[:pct])
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
puts "=" * 80
|
|
68
|
+
total_branches = results.sum { |r| r[:total] }
|
|
69
|
+
total_covered = results.sum { |r| r[:covered] }
|
|
70
|
+
overall_pct = total_branches > 0 ? (total_covered.to_f / total_branches * 100).round(2) : 0
|
|
71
|
+
puts format("Overall: %d/%d (%.2f%%)", total_covered, total_branches, overall_pct)
|
|
72
|
+
puts ""
|
|
73
|
+
|
|
74
|
+
# Show files with worst coverage (< 80%)
|
|
75
|
+
puts "\nFiles with < 80% branch coverage:"
|
|
76
|
+
puts "=" * 80
|
|
77
|
+
results.select { |r| r[:pct] < 80 }.sort_by { |r| r[:pct] }.each do |r|
|
|
78
|
+
puts format("%-50s %3d/%3d (%5.1f%%)", r[:file], r[:covered], r[:total], r[:pct])
|
|
79
|
+
|
|
80
|
+
# Show first few uncovered branches
|
|
81
|
+
if r[:uncovered_branches].any?
|
|
82
|
+
puts " Uncovered branches:"
|
|
83
|
+
r[:uncovered_branches].first(3).each do |branch_info|
|
|
84
|
+
branch_id = branch_info[0]
|
|
85
|
+
# Parse branch location from the string
|
|
86
|
+
next unless branch_id =~ /\[:(if|unless|case|when), \d+, (\d+), (\d+)/
|
|
87
|
+
|
|
88
|
+
branch_type = Regexp.last_match(1)
|
|
89
|
+
line_num = Regexp.last_match(2)
|
|
90
|
+
puts " Line #{line_num}: #{branch_type} statement"
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
puts ""
|
|
94
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to SwarmCLI will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [2.1.0]
|
|
9
|
+
- Bump gem version with the rest of the gems.
|
|
10
|
+
|
|
11
|
+
## [2.0.3] - 2025-10-26
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- **`/defrag` Slash Command** - Automated memory defragmentation workflow
|
|
15
|
+
- Discovers semantically related memory entries (60-85% similarity)
|
|
16
|
+
- Creates bidirectional links to build knowledge graph
|
|
17
|
+
- Runs `MemoryDefrag(action: "find_related")` then `MemoryDefrag(action: "link_related")`
|
|
18
|
+
- Accessible via `/defrag` in interactive REPL
|
|
19
|
+
|
|
20
|
+
## [2.0.2]
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- **Multi-line Input Support** - Interactive REPL now supports multi-line input
|
|
24
|
+
- Press Option+Enter (or ESC then Enter) to add newlines without submitting
|
|
25
|
+
- Press Enter to submit your message
|
|
26
|
+
- Updated help documentation with input tips
|
|
27
|
+
- **Request Cancellation** - Press Ctrl+C to cancel an ongoing LLM request
|
|
28
|
+
- Cancels the current request and returns to the prompt
|
|
29
|
+
- Ctrl+C at the prompt still exits the REPL (existing behavior preserved)
|
|
30
|
+
- Uses Async task cancellation for clean interruption
|
|
31
|
+
|
|
32
|
+
## [2.0.1] - Fri, Oct 17 2025
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- Fixed interactive REPL file completion dropdown not closing after typing space following a Tab completion
|
|
37
|
+
- Fixed navigation mode not exiting when regular keys are typed after Tab completion
|
|
38
|
+
|
|
39
|
+
## [2.0.0] - Fri, Oct 17 2025
|
|
40
|
+
|
|
41
|
+
Initial release of SwarmCLI.
|
|
42
|
+
|
|
43
|
+
See https://github.com/parruda/claude-swarm/pull/137
|