claude_swarm 1.0.1 → 1.0.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.
Files changed (267) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/commands/release.md +1 -1
  3. data/.claude/hooks/lint-code-files.rb +65 -0
  4. data/.rubocop.yml +22 -2
  5. data/CHANGELOG.md +14 -1
  6. data/CLAUDE.md +1 -1
  7. data/CONTRIBUTING.md +69 -0
  8. data/README.md +27 -2
  9. data/Rakefile +71 -3
  10. data/analyze_coverage.rb +94 -0
  11. data/docs/v2/CHANGELOG.swarm_cli.md +43 -0
  12. data/docs/v2/CHANGELOG.swarm_memory.md +379 -0
  13. data/docs/v2/CHANGELOG.swarm_sdk.md +362 -0
  14. data/docs/v2/README.md +308 -0
  15. data/docs/v2/guides/claude-code-agents.md +262 -0
  16. data/docs/v2/guides/complete-tutorial.md +3088 -0
  17. data/docs/v2/guides/getting-started.md +1456 -0
  18. data/docs/v2/guides/memory-adapters.md +998 -0
  19. data/docs/v2/guides/plugins.md +816 -0
  20. data/docs/v2/guides/quick-start-cli.md +1745 -0
  21. data/docs/v2/guides/rails-integration.md +1902 -0
  22. data/docs/v2/guides/swarm-memory.md +599 -0
  23. data/docs/v2/reference/cli.md +729 -0
  24. data/docs/v2/reference/ruby-dsl.md +2154 -0
  25. data/docs/v2/reference/yaml.md +1835 -0
  26. data/docs-team-swarm.yml +2222 -0
  27. data/examples/learning-assistant/assistant.md +7 -0
  28. data/examples/learning-assistant/example-memories/concept-example.md +90 -0
  29. data/examples/learning-assistant/example-memories/experience-example.md +66 -0
  30. data/examples/learning-assistant/example-memories/fact-example.md +76 -0
  31. data/examples/learning-assistant/example-memories/memory-index.md +78 -0
  32. data/examples/learning-assistant/example-memories/skill-example.md +168 -0
  33. data/examples/learning-assistant/learning_assistant.rb +34 -0
  34. data/examples/learning-assistant/learning_assistant.yml +20 -0
  35. data/examples/v2/dsl/01_basic.rb +44 -0
  36. data/examples/v2/dsl/02_core_parameters.rb +59 -0
  37. data/examples/v2/dsl/03_capabilities.rb +71 -0
  38. data/examples/v2/dsl/04_llm_parameters.rb +56 -0
  39. data/examples/v2/dsl/05_advanced_flags.rb +73 -0
  40. data/examples/v2/dsl/06_permissions.rb +80 -0
  41. data/examples/v2/dsl/07_mcp_server.rb +62 -0
  42. data/examples/v2/dsl/08_swarm_hooks.rb +53 -0
  43. data/examples/v2/dsl/09_agent_hooks.rb +67 -0
  44. data/examples/v2/dsl/10_all_agents_hooks.rb +67 -0
  45. data/examples/v2/dsl/11_delegation.rb +60 -0
  46. data/examples/v2/dsl/12_complete_integration.rb +137 -0
  47. data/examples/v2/file_tools_swarm.yml +102 -0
  48. data/examples/v2/hooks/01_basic_hooks.rb +133 -0
  49. data/examples/v2/hooks/02_usage_tracking.rb +201 -0
  50. data/examples/v2/hooks/03_production_monitoring.rb +429 -0
  51. data/examples/v2/hooks/agent_stop_exit_0.yml +21 -0
  52. data/examples/v2/hooks/agent_stop_exit_1.yml +21 -0
  53. data/examples/v2/hooks/agent_stop_exit_2.yml +26 -0
  54. data/examples/v2/hooks/multiple_hooks_all_pass.yml +37 -0
  55. data/examples/v2/hooks/multiple_hooks_first_fails.yml +37 -0
  56. data/examples/v2/hooks/multiple_hooks_second_fails.yml +37 -0
  57. data/examples/v2/hooks/multiple_hooks_warnings.yml +37 -0
  58. data/examples/v2/hooks/post_tool_use_exit_0.yml +24 -0
  59. data/examples/v2/hooks/post_tool_use_exit_1.yml +24 -0
  60. data/examples/v2/hooks/post_tool_use_exit_2.yml +24 -0
  61. data/examples/v2/hooks/post_tool_use_multi_matcher_exit_0.yml +26 -0
  62. data/examples/v2/hooks/post_tool_use_multi_matcher_exit_1.yml +26 -0
  63. data/examples/v2/hooks/post_tool_use_multi_matcher_exit_2.yml +26 -0
  64. data/examples/v2/hooks/pre_tool_use_exit_0.yml +24 -0
  65. data/examples/v2/hooks/pre_tool_use_exit_1.yml +24 -0
  66. data/examples/v2/hooks/pre_tool_use_exit_2.yml +24 -0
  67. data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_0.yml +26 -0
  68. data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_1.yml +26 -0
  69. data/examples/v2/hooks/pre_tool_use_multi_matcher_exit_2.yml +27 -0
  70. data/examples/v2/hooks/swarm_summary.sh +44 -0
  71. data/examples/v2/hooks/user_prompt_exit_0.yml +21 -0
  72. data/examples/v2/hooks/user_prompt_exit_1.yml +21 -0
  73. data/examples/v2/hooks/user_prompt_exit_2.yml +21 -0
  74. data/examples/v2/hooks/validate_bash.rb +59 -0
  75. data/examples/v2/multi_directory_permissions.yml +221 -0
  76. data/examples/v2/node_context_demo.rb +127 -0
  77. data/examples/v2/node_workflow.rb +173 -0
  78. data/examples/v2/path_resolution_demo.rb +216 -0
  79. data/examples/v2/simple-swarm-v2.rb +90 -0
  80. data/examples/v2/simple-swarm-v2.yml +62 -0
  81. data/examples/v2/swarm.yml +71 -0
  82. data/examples/v2/swarm_with_hooks.yml +61 -0
  83. data/examples/v2/swarm_with_hooks_simple.yml +25 -0
  84. data/examples/v2/think_tool_demo.rb +62 -0
  85. data/exe/swarm +6 -0
  86. data/lib/claude_swarm/claude_mcp_server.rb +0 -6
  87. data/lib/claude_swarm/cli.rb +10 -3
  88. data/lib/claude_swarm/commands/ps.rb +19 -20
  89. data/lib/claude_swarm/commands/show.rb +1 -1
  90. data/lib/claude_swarm/configuration.rb +10 -12
  91. data/lib/claude_swarm/mcp_generator.rb +10 -1
  92. data/lib/claude_swarm/orchestrator.rb +73 -49
  93. data/lib/claude_swarm/system_utils.rb +37 -11
  94. data/lib/claude_swarm/version.rb +1 -1
  95. data/lib/claude_swarm/worktree_manager.rb +1 -0
  96. data/lib/claude_swarm/yaml_loader.rb +22 -0
  97. data/lib/claude_swarm.rb +7 -2
  98. data/lib/swarm_cli/cli.rb +201 -0
  99. data/lib/swarm_cli/command_registry.rb +61 -0
  100. data/lib/swarm_cli/commands/mcp_serve.rb +130 -0
  101. data/lib/swarm_cli/commands/mcp_tools.rb +148 -0
  102. data/lib/swarm_cli/commands/migrate.rb +55 -0
  103. data/lib/swarm_cli/commands/run.rb +173 -0
  104. data/lib/swarm_cli/config_loader.rb +97 -0
  105. data/lib/swarm_cli/formatters/human_formatter.rb +711 -0
  106. data/lib/swarm_cli/formatters/json_formatter.rb +51 -0
  107. data/lib/swarm_cli/interactive_repl.rb +918 -0
  108. data/lib/swarm_cli/mcp_serve_options.rb +44 -0
  109. data/lib/swarm_cli/mcp_tools_options.rb +59 -0
  110. data/lib/swarm_cli/migrate_options.rb +54 -0
  111. data/lib/swarm_cli/migrator.rb +132 -0
  112. data/lib/swarm_cli/options.rb +151 -0
  113. data/lib/swarm_cli/ui/components/agent_badge.rb +33 -0
  114. data/lib/swarm_cli/ui/components/content_block.rb +120 -0
  115. data/lib/swarm_cli/ui/components/divider.rb +57 -0
  116. data/lib/swarm_cli/ui/components/panel.rb +62 -0
  117. data/lib/swarm_cli/ui/components/usage_stats.rb +70 -0
  118. data/lib/swarm_cli/ui/formatters/cost.rb +49 -0
  119. data/lib/swarm_cli/ui/formatters/number.rb +58 -0
  120. data/lib/swarm_cli/ui/formatters/text.rb +77 -0
  121. data/lib/swarm_cli/ui/formatters/time.rb +73 -0
  122. data/lib/swarm_cli/ui/icons.rb +59 -0
  123. data/lib/swarm_cli/ui/renderers/event_renderer.rb +188 -0
  124. data/lib/swarm_cli/ui/state/agent_color_cache.rb +45 -0
  125. data/lib/swarm_cli/ui/state/depth_tracker.rb +40 -0
  126. data/lib/swarm_cli/ui/state/spinner_manager.rb +170 -0
  127. data/lib/swarm_cli/ui/state/usage_tracker.rb +62 -0
  128. data/lib/swarm_cli/version.rb +5 -0
  129. data/lib/swarm_cli.rb +44 -0
  130. data/lib/swarm_memory/adapters/base.rb +141 -0
  131. data/lib/swarm_memory/adapters/filesystem_adapter.rb +845 -0
  132. data/lib/swarm_memory/chat_extension.rb +34 -0
  133. data/lib/swarm_memory/cli/commands.rb +306 -0
  134. data/lib/swarm_memory/core/entry.rb +37 -0
  135. data/lib/swarm_memory/core/frontmatter_parser.rb +108 -0
  136. data/lib/swarm_memory/core/metadata_extractor.rb +68 -0
  137. data/lib/swarm_memory/core/path_normalizer.rb +75 -0
  138. data/lib/swarm_memory/core/semantic_index.rb +244 -0
  139. data/lib/swarm_memory/core/storage.rb +288 -0
  140. data/lib/swarm_memory/core/storage_read_tracker.rb +63 -0
  141. data/lib/swarm_memory/dsl/builder_extension.rb +40 -0
  142. data/lib/swarm_memory/dsl/memory_config.rb +113 -0
  143. data/lib/swarm_memory/embeddings/embedder.rb +36 -0
  144. data/lib/swarm_memory/embeddings/informers_embedder.rb +152 -0
  145. data/lib/swarm_memory/errors.rb +21 -0
  146. data/lib/swarm_memory/integration/cli_registration.rb +30 -0
  147. data/lib/swarm_memory/integration/configuration.rb +43 -0
  148. data/lib/swarm_memory/integration/registration.rb +31 -0
  149. data/lib/swarm_memory/integration/sdk_plugin.rb +531 -0
  150. data/lib/swarm_memory/optimization/analyzer.rb +244 -0
  151. data/lib/swarm_memory/optimization/defragmenter.rb +863 -0
  152. data/lib/swarm_memory/prompts/memory.md.erb +109 -0
  153. data/lib/swarm_memory/prompts/memory_assistant.md.erb +181 -0
  154. data/lib/swarm_memory/prompts/memory_researcher.md.erb +281 -0
  155. data/lib/swarm_memory/prompts/memory_retrieval.md.erb +78 -0
  156. data/lib/swarm_memory/search/semantic_search.rb +112 -0
  157. data/lib/swarm_memory/search/text_search.rb +42 -0
  158. data/lib/swarm_memory/search/text_similarity.rb +80 -0
  159. data/lib/swarm_memory/skills/meta/deep-learning.md +101 -0
  160. data/lib/swarm_memory/skills/meta/deep-learning.yml +14 -0
  161. data/lib/swarm_memory/tools/load_skill.rb +313 -0
  162. data/lib/swarm_memory/tools/memory_defrag.rb +382 -0
  163. data/lib/swarm_memory/tools/memory_delete.rb +99 -0
  164. data/lib/swarm_memory/tools/memory_edit.rb +185 -0
  165. data/lib/swarm_memory/tools/memory_glob.rb +160 -0
  166. data/lib/swarm_memory/tools/memory_grep.rb +247 -0
  167. data/lib/swarm_memory/tools/memory_multi_edit.rb +281 -0
  168. data/lib/swarm_memory/tools/memory_read.rb +123 -0
  169. data/lib/swarm_memory/tools/memory_write.rb +231 -0
  170. data/lib/swarm_memory/utils.rb +50 -0
  171. data/lib/swarm_memory/version.rb +5 -0
  172. data/lib/swarm_memory.rb +166 -0
  173. data/lib/swarm_sdk/agent/RETRY_LOGIC.md +127 -0
  174. data/lib/swarm_sdk/agent/builder.rb +461 -0
  175. data/lib/swarm_sdk/agent/chat/context_tracker.rb +314 -0
  176. data/lib/swarm_sdk/agent/chat/hook_integration.rb +372 -0
  177. data/lib/swarm_sdk/agent/chat/logging_helpers.rb +116 -0
  178. data/lib/swarm_sdk/agent/chat/system_reminder_injector.rb +152 -0
  179. data/lib/swarm_sdk/agent/chat.rb +1159 -0
  180. data/lib/swarm_sdk/agent/context.rb +112 -0
  181. data/lib/swarm_sdk/agent/context_manager.rb +309 -0
  182. data/lib/swarm_sdk/agent/definition.rb +556 -0
  183. data/lib/swarm_sdk/claude_code_agent_adapter.rb +205 -0
  184. data/lib/swarm_sdk/configuration.rb +296 -0
  185. data/lib/swarm_sdk/context_compactor/metrics.rb +147 -0
  186. data/lib/swarm_sdk/context_compactor/token_counter.rb +106 -0
  187. data/lib/swarm_sdk/context_compactor.rb +340 -0
  188. data/lib/swarm_sdk/hooks/adapter.rb +359 -0
  189. data/lib/swarm_sdk/hooks/context.rb +197 -0
  190. data/lib/swarm_sdk/hooks/definition.rb +80 -0
  191. data/lib/swarm_sdk/hooks/error.rb +29 -0
  192. data/lib/swarm_sdk/hooks/executor.rb +146 -0
  193. data/lib/swarm_sdk/hooks/registry.rb +147 -0
  194. data/lib/swarm_sdk/hooks/result.rb +150 -0
  195. data/lib/swarm_sdk/hooks/shell_executor.rb +254 -0
  196. data/lib/swarm_sdk/hooks/tool_call.rb +35 -0
  197. data/lib/swarm_sdk/hooks/tool_result.rb +62 -0
  198. data/lib/swarm_sdk/log_collector.rb +51 -0
  199. data/lib/swarm_sdk/log_stream.rb +69 -0
  200. data/lib/swarm_sdk/markdown_parser.rb +75 -0
  201. data/lib/swarm_sdk/model_aliases.json +5 -0
  202. data/lib/swarm_sdk/models.json +1 -0
  203. data/lib/swarm_sdk/models.rb +120 -0
  204. data/lib/swarm_sdk/node/agent_config.rb +49 -0
  205. data/lib/swarm_sdk/node/builder.rb +439 -0
  206. data/lib/swarm_sdk/node/transformer_executor.rb +248 -0
  207. data/lib/swarm_sdk/node_context.rb +170 -0
  208. data/lib/swarm_sdk/node_orchestrator.rb +384 -0
  209. data/lib/swarm_sdk/permissions/config.rb +239 -0
  210. data/lib/swarm_sdk/permissions/error_formatter.rb +121 -0
  211. data/lib/swarm_sdk/permissions/path_matcher.rb +35 -0
  212. data/lib/swarm_sdk/permissions/validator.rb +173 -0
  213. data/lib/swarm_sdk/permissions_builder.rb +122 -0
  214. data/lib/swarm_sdk/plugin.rb +147 -0
  215. data/lib/swarm_sdk/plugin_registry.rb +101 -0
  216. data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +243 -0
  217. data/lib/swarm_sdk/providers/openai_with_responses.rb +582 -0
  218. data/lib/swarm_sdk/result.rb +97 -0
  219. data/lib/swarm_sdk/swarm/agent_initializer.rb +334 -0
  220. data/lib/swarm_sdk/swarm/all_agents_builder.rb +140 -0
  221. data/lib/swarm_sdk/swarm/builder.rb +586 -0
  222. data/lib/swarm_sdk/swarm/mcp_configurator.rb +151 -0
  223. data/lib/swarm_sdk/swarm/tool_configurator.rb +419 -0
  224. data/lib/swarm_sdk/swarm.rb +982 -0
  225. data/lib/swarm_sdk/tools/bash.rb +274 -0
  226. data/lib/swarm_sdk/tools/clock.rb +44 -0
  227. data/lib/swarm_sdk/tools/delegate.rb +164 -0
  228. data/lib/swarm_sdk/tools/document_converters/base_converter.rb +83 -0
  229. data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +99 -0
  230. data/lib/swarm_sdk/tools/document_converters/html_converter.rb +101 -0
  231. data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +78 -0
  232. data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +194 -0
  233. data/lib/swarm_sdk/tools/edit.rb +150 -0
  234. data/lib/swarm_sdk/tools/glob.rb +158 -0
  235. data/lib/swarm_sdk/tools/grep.rb +228 -0
  236. data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +43 -0
  237. data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +163 -0
  238. data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +65 -0
  239. data/lib/swarm_sdk/tools/multi_edit.rb +232 -0
  240. data/lib/swarm_sdk/tools/path_resolver.rb +43 -0
  241. data/lib/swarm_sdk/tools/read.rb +251 -0
  242. data/lib/swarm_sdk/tools/registry.rb +93 -0
  243. data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +96 -0
  244. data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +76 -0
  245. data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +91 -0
  246. data/lib/swarm_sdk/tools/stores/read_tracker.rb +61 -0
  247. data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +224 -0
  248. data/lib/swarm_sdk/tools/stores/storage.rb +148 -0
  249. data/lib/swarm_sdk/tools/stores/todo_manager.rb +65 -0
  250. data/lib/swarm_sdk/tools/think.rb +95 -0
  251. data/lib/swarm_sdk/tools/todo_write.rb +216 -0
  252. data/lib/swarm_sdk/tools/web_fetch.rb +261 -0
  253. data/lib/swarm_sdk/tools/write.rb +117 -0
  254. data/lib/swarm_sdk/utils.rb +50 -0
  255. data/lib/swarm_sdk/version.rb +5 -0
  256. data/lib/swarm_sdk.rb +157 -0
  257. data/llm.v2.txt +13407 -0
  258. data/rubocop/cop/security/no_reflection_methods.rb +47 -0
  259. data/rubocop/cop/security/no_ruby_llm_logger.rb +32 -0
  260. data/swarm_cli.gemspec +57 -0
  261. data/swarm_memory.gemspec +28 -0
  262. data/swarm_sdk.gemspec +41 -0
  263. data/team.yml +1 -1
  264. data/team_full.yml +1875 -0
  265. data/{team_v2.yml → team_sdk.yml} +121 -52
  266. metadata +249 -6
  267. data/EXAMPLES.md +0 -164
@@ -0,0 +1,1745 @@
1
+ # Getting Started with SwarmCLI
2
+
3
+ ## What You'll Learn
4
+
5
+ - What SwarmCLI is and when to use it
6
+ - How to install and verify SwarmCLI (separate from SwarmSDK)
7
+ - The two execution modes: interactive (REPL) and non-interactive
8
+ - Available commands and their purposes
9
+ - How to use the interactive REPL for conversations
10
+ - How to use non-interactive mode with NDJSON streaming for automation
11
+ - Working with configuration files (YAML and Ruby DSL)
12
+ - Common workflows and real-world examples
13
+ - How to parse NDJSON output correctly (not single JSON objects)
14
+
15
+ ## Prerequisites
16
+
17
+ - **Ruby 3.2.0 or higher** installed on your system
18
+ - **LLM API access** - an API key for OpenAI, Anthropic, or another provider
19
+ - **A swarm configuration file** - either YAML or Ruby DSL (see [Getting Started with SwarmSDK](getting-started.md))
20
+ - **10-15 minutes** to complete this guide
21
+
22
+ ## What is SwarmCLI?
23
+
24
+ SwarmCLI is a command-line interface for running SwarmSDK swarms. It's a **separate gem** (`swarm_cli`) that depends on and extends `swarm_sdk`. Installing `swarm_cli` automatically installs `swarm_sdk` as a dependency.
25
+
26
+ **Two separate gems**:
27
+ - **`swarm_sdk`** - The core library for building agent swarms
28
+ - **`swarm_cli`** - The CLI tool for running swarms from the terminal
29
+
30
+ SwarmCLI provides two ways to interact with your AI agent teams:
31
+
32
+ **Interactive Mode (REPL)**: A conversational interface where you chat with your swarm in real-time. Perfect for:
33
+ - Exploratory work and experimentation
34
+ - Iterative development with feedback loops
35
+ - Learning how your agents collaborate
36
+ - Long conversations with context preservation
37
+
38
+ **Non-Interactive Mode**: One-shot task execution with immediate results and NDJSON streaming. Perfect for:
39
+ - Automation and scripting
40
+ - CI/CD pipelines
41
+ - Batch processing
42
+ - Real-time monitoring and cost tracking
43
+ - Scheduled tasks
44
+
45
+ **Why use SwarmCLI?** Instead of writing Ruby code to execute your swarms, you can simply run `swarm run config.yml` and start working. It's faster for quick tasks and provides a polished terminal experience with structured JSON output for automation.
46
+
47
+ ## Installation
48
+
49
+ Install the SwarmCLI gem (which automatically installs SwarmSDK as a dependency):
50
+
51
+ ```bash
52
+ gem install swarm_cli
53
+ ```
54
+
55
+ **What gets installed**:
56
+ - `swarm_cli` gem (the CLI tool)
57
+ - `swarm_sdk` gem (automatically as a dependency)
58
+ - `swarm` executable (the command you'll use)
59
+
60
+ Or add to your Gemfile:
61
+
62
+ ```ruby
63
+ gem 'swarm_cli' # This will also install swarm_sdk as a dependency
64
+ ```
65
+
66
+ Then install:
67
+
68
+ ```bash
69
+ bundle install
70
+ ```
71
+
72
+ **Important notes**:
73
+ - `swarm_cli` and `swarm_sdk` are **separate gems**
74
+ - Installing `swarm_cli` automatically installs `swarm_sdk`
75
+ - The executable is called `swarm` (NOT `swarm_cli`)
76
+ - Requires Ruby 3.2.0 or higher
77
+
78
+ ### Verify Installation
79
+
80
+ Check that SwarmCLI is installed correctly:
81
+
82
+ ```bash
83
+ swarm --version
84
+ ```
85
+
86
+ **Expected output**:
87
+ ```
88
+ SwarmCLI v2.0.0
89
+ ```
90
+
91
+ Check Ruby version:
92
+
93
+ ```bash
94
+ ruby -v
95
+ ```
96
+
97
+ **Expected output**:
98
+ ```
99
+ ruby 3.2.0 (or higher)
100
+ ```
101
+
102
+ Get help on available commands:
103
+
104
+ ```bash
105
+ swarm --help
106
+ ```
107
+
108
+ **Expected output**:
109
+ ```
110
+ SwarmCLI v2.0.0 - AI Agent Orchestration
111
+
112
+ Usage:
113
+ swarm run CONFIG_FILE -p PROMPT [options]
114
+ swarm migrate INPUT_FILE [--output OUTPUT_FILE]
115
+ swarm mcp serve CONFIG_FILE
116
+ swarm mcp tools [TOOL_NAMES...]
117
+
118
+ Commands:
119
+ run Execute a swarm with AI agents
120
+ migrate Migrate Claude Swarm v1 config to SwarmSDK v2 format
121
+ mcp serve Start an MCP server exposing swarm lead agent
122
+ mcp tools Start an MCP server exposing SwarmSDK tools
123
+
124
+ Options:
125
+ -p, --prompt PROMPT Task prompt for the swarm
126
+ -o, --output FILE Output file for migrated config (default: stdout)
127
+ --output-format FORMAT Output format: 'human' or 'json' (default: human)
128
+ -q, --quiet Suppress progress output (human format only)
129
+ --truncate Truncate long outputs for concise view
130
+ --verbose Show system reminders and additional debug information
131
+ -h, --help Print help
132
+ -v, --version Print version
133
+ ```
134
+
135
+ ## Quick Start: Your First Command
136
+
137
+ Let's create a simple swarm configuration and run it.
138
+
139
+ ### Step 1: Create a Configuration File
140
+
141
+ Create a file called `assistant.yml`:
142
+
143
+ ```yaml
144
+ version: 2
145
+ swarm:
146
+ name: "Quick Start Assistant"
147
+ lead: helper
148
+
149
+ agents:
150
+ helper:
151
+ description: "A helpful assistant"
152
+ model: "gpt-4"
153
+ system_prompt: |
154
+ You are a helpful assistant.
155
+ Answer questions clearly and concisely.
156
+ tools:
157
+ - Write
158
+ ```
159
+
160
+ ### Step 2: Set Your API Key
161
+
162
+ Ensure your API key is set:
163
+
164
+ ```bash
165
+ export OPENAI_API_KEY="sk-your-key-here"
166
+ ```
167
+
168
+ Or create a `.env` file:
169
+
170
+ ```bash
171
+ echo "OPENAI_API_KEY=sk-your-key-here" > .env
172
+ ```
173
+
174
+ ### Step 3: Run Interactive Mode
175
+
176
+ Start a conversation with your swarm:
177
+
178
+ ```bash
179
+ swarm run assistant.yml
180
+ ```
181
+
182
+ **Expected output**:
183
+ ```
184
+ ────────────────────────────────────────────────────────────
185
+ 🚀 Swarm CLI Interactive REPL
186
+ ────────────────────────────────────────────────────────────
187
+
188
+ Swarm: Quick Start Assistant
189
+ Lead Agent: helper
190
+
191
+ Type your message and press Enter to submit
192
+ Type /help for commands or /exit to quit
193
+
194
+ ────────────────────────────────────────────────────────────
195
+
196
+ You ❯
197
+ ```
198
+
199
+ **Try it**: Type "What is 2 + 2?" and press Enter.
200
+
201
+ The swarm will process your question and respond. Continue the conversation by typing more messages.
202
+
203
+ ### Step 4: Exit the REPL
204
+
205
+ Type `/exit` or press `Ctrl+D` to exit.
206
+
207
+ **Expected output**:
208
+ ```
209
+ 👋 Goodbye! Thanks for using Swarm CLI
210
+
211
+ ────────────────────────────────────────────────────────────
212
+ 📊 Session Summary
213
+ ────────────────────────────────────────────────────────────
214
+
215
+ Messages sent: 1
216
+ Agents used: helper
217
+ LLM Requests: 1
218
+ Tool Calls: 0
219
+ Total Tokens: 245
220
+ Total Cost: $0.0012
221
+ Session Duration: 1.23s
222
+
223
+ ────────────────────────────────────────────────────────────
224
+ ```
225
+
226
+ Congratulations! You've successfully run your first SwarmCLI command.
227
+
228
+ ## Commands Overview
229
+
230
+ SwarmCLI provides four main commands:
231
+
232
+ ### 1. swarm run
233
+
234
+ Execute a swarm with your agents. Supports both interactive and non-interactive modes.
235
+
236
+ **Interactive mode (REPL)**:
237
+ ```bash
238
+ swarm run config.yml
239
+ ```
240
+
241
+ **Non-interactive mode**:
242
+ ```bash
243
+ swarm run config.yml -p "Your task here"
244
+ ```
245
+
246
+ **Key options**:
247
+ - `-p, --prompt PROMPT` - Enable non-interactive mode with a prompt
248
+ - `--output-format FORMAT` - Choose output format: `human` (default) or `json` (NDJSON)
249
+ - `-q, --quiet` - Suppress progress output
250
+ - `--truncate` - Truncate long outputs for concise view
251
+ - `--verbose` - Show additional debug information
252
+
253
+ ### 2. swarm migrate
254
+
255
+ Convert old Claude Swarm v1 configurations to SwarmSDK v2 format.
256
+
257
+ ```bash
258
+ swarm migrate old-config.yml
259
+ swarm migrate old-config.yml --output new-config.yml
260
+ ```
261
+
262
+ **Use case**: Upgrading from version 1 to version 2.
263
+
264
+ ### 3. swarm mcp serve
265
+
266
+ Start an MCP (Model Context Protocol) server that exposes your swarm as a tool.
267
+
268
+ ```bash
269
+ swarm mcp serve config.yml
270
+ ```
271
+
272
+ **Use case**: Integrating your swarm with MCP-compatible tools and frameworks.
273
+
274
+ ### 4. swarm mcp tools
275
+
276
+ Start an MCP server that exposes SwarmSDK's built-in tools.
277
+
278
+ ```bash
279
+ # Expose all tools
280
+ swarm mcp tools
281
+
282
+ # Expose specific tools
283
+ swarm mcp tools Bash Grep Read
284
+
285
+ # Comma-separated (no spaces)
286
+ swarm mcp tools Read,Write,Edit
287
+ ```
288
+
289
+ **Use case**: Making SwarmSDK tools available to other MCP clients.
290
+
291
+ ## Interactive Mode (REPL)
292
+
293
+ The interactive REPL provides a conversational interface for working with your swarm.
294
+
295
+ ### Starting the REPL
296
+
297
+ **Basic usage**:
298
+ ```bash
299
+ swarm run config.yml
300
+ ```
301
+
302
+ **With an initial message**:
303
+ ```bash
304
+ swarm run config.yml "Start by analyzing the README.md file"
305
+ ```
306
+
307
+ **With piped input**:
308
+ ```bash
309
+ echo "Summarize the main.rb file" | swarm run config.yml
310
+ ```
311
+
312
+ In all three cases above, you'll enter interactive mode, but the last two will send an initial message before the first prompt.
313
+
314
+ ### Understanding the Interface
315
+
316
+ Once in the REPL, you'll see:
317
+
318
+ ```
319
+ ────────────────────────────────────────────────────────────
320
+ 🚀 Swarm CLI Interactive REPL
321
+ ────────────────────────────────────────────────────────────
322
+
323
+ Swarm: Development Team
324
+ Lead Agent: architect
325
+
326
+ Type your message and press Enter to submit
327
+ Type /help for commands or /exit to quit
328
+
329
+ ────────────────────────────────────────────────────────────
330
+
331
+ You ❯
332
+ ```
333
+
334
+ **What you're seeing**:
335
+ 1. **Header** - Welcome banner with swarm information
336
+ 2. **Swarm name and lead agent** - Shows which swarm and agent you're talking to
337
+ 3. **Instructions** - How to use the REPL
338
+ 4. **Prompt** - `You ❯` indicates you can type your message
339
+
340
+ ### Conversation Flow
341
+
342
+ **1. Type your message and press Enter**:
343
+ ```
344
+ You ❯ What files are in this directory?
345
+ ```
346
+
347
+ **2. The swarm processes your request**:
348
+ ```
349
+ architect • thinking...
350
+ ```
351
+
352
+ **3. The agent responds**:
353
+ ```
354
+ architect:
355
+ Based on the directory listing, here are the files:
356
+ - README.md
357
+ - src/main.rb
358
+ - src/config.yml
359
+ - tests/test_main.rb
360
+ ```
361
+
362
+ **4. Context stats appear before next prompt**:
363
+ ```
364
+ [architect • 1 msg • 245 tokens • $0.0012 • 15% context]
365
+ You ❯
366
+ ```
367
+
368
+ These stats show:
369
+ - **Agent name**: Which agent you're talking to
370
+ - **Message count**: Number of messages sent
371
+ - **Token usage**: Total tokens consumed
372
+ - **Cost**: Total cost in USD
373
+ - **Context usage**: Percentage of context window used (color-coded: green < 50%, yellow < 80%, red ≥ 80%)
374
+
375
+ ### REPL Commands
376
+
377
+ Type `/help` to see available commands:
378
+
379
+ | Command | Description |
380
+ |---------|-------------|
381
+ | `/help` | Show available commands |
382
+ | `/clear` | Clear the screen |
383
+ | `/history` | Show conversation history |
384
+ | `/exit` | Exit the REPL (or press Ctrl+D) |
385
+
386
+ **Using commands**:
387
+
388
+ ```
389
+ You ❯ /help
390
+ ```
391
+
392
+ Shows a help box with all commands and input tips.
393
+
394
+ ```
395
+ You ❯ /history
396
+ ```
397
+
398
+ Shows your entire conversation with truncated long messages.
399
+
400
+ ```
401
+ You ❯ /clear
402
+ ```
403
+
404
+ Clears the screen and shows the welcome banner again.
405
+
406
+ ```
407
+ You ❯ /exit
408
+ ```
409
+
410
+ Exits the REPL and shows a session summary.
411
+
412
+ ### Tab Completion
413
+
414
+ The REPL provides intelligent tab completion:
415
+
416
+ **Command completion**: Type `/` and press Tab to see available commands:
417
+ ```
418
+ You ❯ /
419
+ /help /clear /history /exit
420
+ ```
421
+
422
+ **File path completion**: Type `@` followed by a partial path and press Tab:
423
+ ```
424
+ You ❯ Read @src/m
425
+ @src/main.rb @src/models/ @src/modules/
426
+ ```
427
+
428
+ **Navigation**:
429
+ - Press `Tab` to cycle forward through completions
430
+ - Press `Shift+Tab` to cycle backward
431
+ - Press `Enter` to accept the selected completion
432
+
433
+ ### Context Preservation
434
+
435
+ The REPL maintains conversation context across messages:
436
+
437
+ ```
438
+ You ❯ What files are in src/?
439
+
440
+ architect:
441
+ The src/ directory contains:
442
+ - main.rb
443
+ - config.yml
444
+ - utils.rb
445
+
446
+ You ❯ What does the first one do?
447
+
448
+ architect:
449
+ main.rb is the entry point. It loads the configuration and starts the application.
450
+ ```
451
+
452
+ Notice how the second question ("What does the first one do?") references the previous response. The agent understands you're asking about `main.rb` because the conversation context is preserved.
453
+
454
+ ### Session Summary
455
+
456
+ When you exit (via `/exit` or `Ctrl+D`), you'll see a summary:
457
+
458
+ ```
459
+ ────────────────────────────────────────────────────────────
460
+ 📊 Session Summary
461
+ ────────────────────────────────────────────────────────────
462
+
463
+ Messages sent: 5
464
+ Agents used: architect, coder, reviewer
465
+ LLM Requests: 8
466
+ Tool Calls: 12
467
+ Total Tokens: 1.2K
468
+ Total Cost: $0.0156
469
+ Session Duration: 2m 34s
470
+
471
+ ────────────────────────────────────────────────────────────
472
+ ```
473
+
474
+ This shows:
475
+ - **Messages sent**: Number of user messages
476
+ - **Agents used**: Which agents participated
477
+ - **LLM Requests**: Total API calls made
478
+ - **Tool Calls**: Total tool invocations
479
+ - **Tokens and cost**: Session totals
480
+ - **Duration**: Total time in the REPL
481
+
482
+ ## Non-Interactive Mode
483
+
484
+ Non-interactive mode executes a single task and exits. Perfect for scripting and automation with structured NDJSON output.
485
+
486
+ ### Basic Usage
487
+
488
+ **Provide prompt as argument**:
489
+ ```bash
490
+ swarm run config.yml -p "Build a REST API for user management"
491
+ ```
492
+
493
+ **Provide prompt via stdin**:
494
+ ```bash
495
+ echo "Build a REST API for user management" | swarm run config.yml -p
496
+ ```
497
+
498
+ **Use a heredoc for long prompts**:
499
+ ```bash
500
+ swarm run config.yml -p "$(cat <<'EOF'
501
+ Build a REST API with the following features:
502
+ 1. User registration and authentication
503
+ 2. CRUD operations for user profiles
504
+ 3. JWT token-based authorization
505
+ 4. Input validation and error handling
506
+ EOF
507
+ )"
508
+ ```
509
+
510
+ ### Understanding Output Formats
511
+
512
+ SwarmCLI supports two output formats: `human` (default) and `json` (NDJSON).
513
+
514
+ ### Human Format (Default)
515
+
516
+ **Example**:
517
+ ```bash
518
+ swarm run config.yml -p "What is 2 + 2?"
519
+ ```
520
+
521
+ **Output**:
522
+ ```
523
+ Swarm: Quick Start Assistant
524
+ Lead Agent: helper
525
+ Task: What is 2 + 2?
526
+ ────────────────────────────────────────────────────────────
527
+
528
+ helper • thinking...
529
+
530
+ helper:
531
+ The answer is 4.
532
+
533
+ ────────────────────────────────────────────────────────────
534
+ ✓ Success
535
+ Duration: 1.23s • Cost: $0.0012 • Tokens: 245
536
+ ────────────────────────────────────────────────────────────
537
+ ```
538
+
539
+ The human format provides:
540
+ - **Header**: Swarm info and task
541
+ - **Progress indicators**: Shows what's happening
542
+ - **Agent responses**: Formatted and colored
543
+ - **Summary**: Duration, cost, and token usage
544
+
545
+ ### JSON Output Format (NDJSON Event Stream)
546
+
547
+ **CRITICAL**: JSON output is **NDJSON** (newline-delimited JSON), not a single JSON object.
548
+
549
+ For scripting and automation, use JSON format which outputs **newline-delimited JSON (NDJSON)** - one event per line:
550
+
551
+ ```bash
552
+ swarm run config.yml -p "What is 2 + 2?" --output-format json
553
+ ```
554
+
555
+ **Output** (NDJSON - each line is a separate JSON event):
556
+ ```json
557
+ {"type":"swarm_start","swarm_name":"Quick Start Assistant","lead_agent":"helper","prompt":"What is 2 + 2?","timestamp":"2024-01-15T10:30:00Z"}
558
+ {"type":"user_prompt","agent":"helper","model":"gpt-4","message_count":0,"timestamp":"2024-01-15T10:30:00Z"}
559
+ {"type":"agent_step","agent":"helper","model":"gpt-4","content":"","tool_calls":[{"id":"call_123","name":"think","arguments":{}}],"usage":{"prompt_tokens":50,"completion_tokens":10,"total_tokens":60,"cost":0.0003},"timestamp":"2024-01-15T10:30:01Z"}
560
+ {"type":"agent_stop","agent":"helper","model":"gpt-4","content":"The answer is 4.","tool_calls":[],"finish_reason":"stop","usage":{"prompt_tokens":60,"completion_tokens":5,"total_tokens":65,"cost":0.0003},"timestamp":"2024-01-15T10:30:02Z"}
561
+ {"type":"swarm_stop","swarm_name":"Quick Start Assistant","lead_agent":"helper","success":true,"duration":1.23,"total_cost":0.0012,"total_tokens":245,"agents_involved":["helper"],"timestamp":"2024-01-15T10:30:02Z"}
562
+ ```
563
+
564
+ **CRITICAL UNDERSTANDING - NDJSON vs Regular JSON**:
565
+
566
+ ❌ **NOT a single JSON object**:
567
+ ```json
568
+ {
569
+ "events": [
570
+ {"type": "swarm_start", ...},
571
+ {"type": "agent_stop", ...}
572
+ ]
573
+ }
574
+ ```
575
+
576
+ ✅ **NDJSON - one event per line**:
577
+ ```
578
+ {"type":"swarm_start",...}
579
+ {"type":"agent_step",...}
580
+ {"type":"agent_stop",...}
581
+ {"type":"swarm_stop",...}
582
+ ```
583
+
584
+ ### Why NDJSON?
585
+
586
+ **Key benefits**:
587
+ 1. **Real-time streaming**: Events arrive as they happen (not buffered until completion)
588
+ 2. **Line-by-line processing**: Easy to process incrementally with standard tools
589
+ 3. **Memory efficient**: No need to load entire response into memory
590
+ 4. **Tool friendly**: Works perfectly with `jq`, `grep`, `awk`, etc.
591
+ 5. **Fault tolerant**: Partial results available even if process crashes
592
+
593
+ ### NDJSON Event Types
594
+
595
+ Each line in NDJSON output is one of these event types:
596
+
597
+ | Event Type | Description | Key Fields |
598
+ |------------|-------------|------------|
599
+ | `swarm_start` | Swarm execution begins | `swarm_name`, `lead_agent`, `prompt` |
600
+ | `user_prompt` | User message sent to agent | `agent`, `model`, `message_count` |
601
+ | `agent_step` | Agent produces intermediate output | `agent`, `content`, `tool_calls`, `usage` |
602
+ | `agent_stop` | Agent completes its response | `agent`, `content`, `finish_reason`, `usage` |
603
+ | `tool_call` | Agent invokes a tool | `tool`, `arguments`, `tool_call_id` |
604
+ | `tool_result` | Tool returns result | `tool`, `result`, `tool_call_id` |
605
+ | `agent_delegation` | Agent delegates to another agent | `agent`, `delegate_to`, `tool_call_id` |
606
+ | `delegation_result` | Delegated agent completes | `agent`, `delegate_from`, `result` |
607
+ | `delegation_error` | Delegation fails | `agent`, `delegate_to`, `error_message` |
608
+ | `node_start` | Node execution begins (workflows) | `node_name`, `lead_agent` |
609
+ | `node_stop` | Node execution completes (workflows) | `node_name`, `success`, `duration` |
610
+ | `model_lookup_warning` | Unknown model in config | `agent`, `model`, `suggestions` |
611
+ | `context_limit_warning` | Context usage threshold crossed | `agent`, `threshold`, `current_usage` |
612
+ | `swarm_stop` | Swarm execution completes | `success`, `duration`, `total_cost`, `agents_involved` |
613
+
614
+ ### Processing NDJSON with jq
615
+
616
+ `jq` is the standard tool for processing JSON. Here's how to work with NDJSON:
617
+
618
+ **Extract all agent responses**:
619
+ ```bash
620
+ swarm run config.yml -p "Task" --output-format json | \
621
+ jq -c 'select(.type == "agent_stop") | .content'
622
+ ```
623
+
624
+ **Output**:
625
+ ```
626
+ "Here is the first response."
627
+ "Here is the second response."
628
+ ```
629
+
630
+ **Calculate total cost from events**:
631
+ ```bash
632
+ swarm run config.yml -p "Task" --output-format json | \
633
+ jq -s '[.[] | select(.usage) | .usage.cost] | add'
634
+ ```
635
+
636
+ **Output**:
637
+ ```
638
+ 0.0156
639
+ ```
640
+
641
+ **Get final success status**:
642
+ ```bash
643
+ swarm run config.yml -p "Task" --output-format json | \
644
+ jq -c 'select(.type == "swarm_stop") | .success'
645
+ ```
646
+
647
+ **Output**:
648
+ ```
649
+ true
650
+ ```
651
+
652
+ **Extract just the final content**:
653
+ ```bash
654
+ swarm run config.yml -p "Task" --output-format json | \
655
+ jq -c 'select(.type == "agent_stop") | .content' | tail -1
656
+ ```
657
+
658
+ **Output**:
659
+ ```
660
+ "The answer is 4."
661
+ ```
662
+
663
+ **Track costs in real-time**:
664
+ ```bash
665
+ swarm run config.yml -p "Task" --output-format json | \
666
+ jq -c 'select(.usage) | {agent, cost: .usage.cost}'
667
+ ```
668
+
669
+ **Output** (streaming as events arrive):
670
+ ```
671
+ {"agent":"helper","cost":0.0003}
672
+ {"agent":"helper","cost":0.0003}
673
+ {"agent":"helper","cost":0.0006}
674
+ ```
675
+
676
+ **Filter tool calls**:
677
+ ```bash
678
+ swarm run config.yml -p "Task" --output-format json | \
679
+ jq -c 'select(.type == "tool_call") | {tool, arguments}'
680
+ ```
681
+
682
+ **Get all agents involved**:
683
+ ```bash
684
+ swarm run config.yml -p "Task" --output-format json | \
685
+ jq -c 'select(.type == "swarm_stop") | .agents_involved'
686
+ ```
687
+
688
+ **Output**:
689
+ ```
690
+ ["architect","coder","reviewer"]
691
+ ```
692
+
693
+ ### Processing NDJSON in Bash Scripts
694
+
695
+ **Real-time event processing**:
696
+ ```bash
697
+ #!/bin/bash
698
+ # process-events.sh - Process NDJSON events as they arrive
699
+
700
+ swarm run config.yml -p "Task" --output-format json | while IFS= read -r event; do
701
+ type=$(echo "$event" | jq -r '.type')
702
+
703
+ case $type in
704
+ swarm_start)
705
+ swarm_name=$(echo "$event" | jq -r '.swarm_name')
706
+ echo "🚀 Starting swarm: $swarm_name"
707
+ ;;
708
+ agent_step)
709
+ agent=$(echo "$event" | jq -r '.agent')
710
+ cost=$(echo "$event" | jq -r '.usage.cost')
711
+ echo "💭 $agent thinking (cost: \$$cost)"
712
+ ;;
713
+ tool_call)
714
+ tool=$(echo "$event" | jq -r '.tool')
715
+ echo "🔧 Calling tool: $tool"
716
+ ;;
717
+ agent_stop)
718
+ agent=$(echo "$event" | jq -r '.agent')
719
+ content=$(echo "$event" | jq -r '.content')
720
+ echo "✓ $agent: $content"
721
+ ;;
722
+ swarm_stop)
723
+ success=$(echo "$event" | jq -r '.success')
724
+ total_cost=$(echo "$event" | jq -r '.total_cost')
725
+ duration=$(echo "$event" | jq -r '.duration')
726
+
727
+ if [ "$success" = "true" ]; then
728
+ echo "✓ Success! Cost: \$$total_cost, Duration: ${duration}s"
729
+ else
730
+ echo "✗ Failed! Duration: ${duration}s"
731
+ exit 1
732
+ fi
733
+ ;;
734
+ esac
735
+ done
736
+ ```
737
+
738
+ **Collecting results**:
739
+ ```bash
740
+ #!/bin/bash
741
+ # collect-results.sh - Collect all events into structured output
742
+
743
+ output_file="results.json"
744
+
745
+ # Collect all events into JSON array
746
+ swarm run config.yml -p "Task" --output-format json | \
747
+ jq -s '.' > "$output_file"
748
+
749
+ # Extract summary information
750
+ total_cost=$(jq '[.[] | select(.usage) | .usage.cost] | add' "$output_file")
751
+ success=$(jq '.[-1].success' "$output_file")
752
+ agents=$(jq '.[-1].agents_involved' "$output_file")
753
+
754
+ echo "Summary:"
755
+ echo " Success: $success"
756
+ echo " Total Cost: \$$total_cost"
757
+ echo " Agents: $agents"
758
+ ```
759
+
760
+ ### Processing NDJSON in Ruby
761
+
762
+ ```ruby
763
+ #!/usr/bin/env ruby
764
+ # process-ndjson.rb - Process NDJSON output in Ruby
765
+
766
+ require 'json'
767
+ require 'open3'
768
+
769
+ cmd = "swarm run config.yml -p 'Task' --output-format json"
770
+ total_cost = 0.0
771
+
772
+ Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
773
+ stdout.each_line do |line|
774
+ event = JSON.parse(line)
775
+
776
+ case event['type']
777
+ when 'swarm_start'
778
+ puts "🚀 Starting: #{event['swarm_name']}"
779
+ when 'agent_step'
780
+ cost = event.dig('usage', 'cost') || 0.0
781
+ total_cost += cost
782
+ puts "💭 #{event['agent']} (cost: $#{cost})"
783
+ when 'agent_stop'
784
+ puts "✓ #{event['agent']}: #{event['content']}"
785
+ when 'swarm_stop'
786
+ puts "\n📊 Summary:"
787
+ puts " Success: #{event['success']}"
788
+ puts " Duration: #{event['duration']}s"
789
+ puts " Total Cost: $#{event['total_cost']}"
790
+ puts " Agents: #{event['agents_involved'].join(', ')}"
791
+ end
792
+ end
793
+ end
794
+ ```
795
+
796
+ ### Useful Flags
797
+
798
+ **Quiet mode** - Suppress progress output (only show final result):
799
+ ```bash
800
+ swarm run config.yml -p "Task" --quiet
801
+ ```
802
+
803
+ **Truncate mode** - Truncate long outputs for concise view:
804
+ ```bash
805
+ swarm run config.yml -p "Summarize all files" --truncate
806
+ ```
807
+
808
+ **Verbose mode** - Show additional debug information:
809
+ ```bash
810
+ swarm run config.yml -p "Task" --verbose
811
+ ```
812
+
813
+ ### Exit Codes
814
+
815
+ SwarmCLI uses standard exit codes:
816
+
817
+ | Exit Code | Meaning |
818
+ |-----------|---------|
819
+ | `0` | Success |
820
+ | `1` | Error (configuration, execution, etc.) |
821
+ | `130` | User cancelled (Ctrl+C) |
822
+
823
+ **Use in scripts**:
824
+ ```bash
825
+ if swarm run config.yml -p "Task" --quiet; then
826
+ echo "✓ Success!"
827
+ else
828
+ echo "✗ Failed with exit code $?"
829
+ exit 1
830
+ fi
831
+ ```
832
+
833
+ ### Piping and Redirection
834
+
835
+ **Pipe prompt from file**:
836
+ ```bash
837
+ cat prompt.txt | swarm run config.yml -p
838
+ ```
839
+
840
+ **Redirect output to file**:
841
+ ```bash
842
+ swarm run config.yml -p "Generate report" > report.txt 2>&1
843
+ ```
844
+
845
+ **Save JSON events to file**:
846
+ ```bash
847
+ swarm run config.yml -p "Task" --output-format json > events.ndjson
848
+ ```
849
+
850
+ **Process saved NDJSON file**:
851
+ ```bash
852
+ cat events.ndjson | jq -c 'select(.type == "agent_stop")'
853
+ ```
854
+
855
+ **Chain with other commands**:
856
+ ```bash
857
+ # Get list of files, then process each
858
+ ls *.rb | xargs -I {} swarm run config.yml -p "Analyze {}" --quiet
859
+
860
+ # Process multiple prompts from file
861
+ cat prompts.txt | while read prompt; do
862
+ swarm run config.yml -p "$prompt" --quiet
863
+ done
864
+ ```
865
+
866
+ **Combine with jq for JSON processing**:
867
+ ```bash
868
+ # Extract final agent response
869
+ swarm run config.yml -p "Task" --output-format json | \
870
+ jq -c 'select(.type == "agent_stop")' | tail -1 | jq -r '.content'
871
+
872
+ # Track costs in real-time
873
+ swarm run config.yml -p "Task" --output-format json | \
874
+ jq -c 'select(.usage) | {agent, cost: .usage.cost}'
875
+ ```
876
+
877
+ ## Configuration Files
878
+
879
+ SwarmCLI works with both YAML and Ruby DSL configuration files.
880
+
881
+ ### YAML Configuration
882
+
883
+ Create a file with `.yml` or `.yaml` extension:
884
+
885
+ **Example** (`team.yml`):
886
+ ```yaml
887
+ version: 2
888
+ swarm:
889
+ name: "Development Team"
890
+ lead: architect
891
+
892
+ agents:
893
+ architect:
894
+ description: "Lead architect coordinating the team"
895
+ model: "gpt-4"
896
+ system_prompt: |
897
+ You are the lead architect.
898
+ Break down tasks and delegate to specialists.
899
+ tools:
900
+ - Write
901
+ - Edit
902
+ delegates_to:
903
+ - coder
904
+ - reviewer
905
+
906
+ coder:
907
+ description: "Writes clean, maintainable code"
908
+ model: "gpt-4"
909
+ system_prompt: "You are an expert programmer."
910
+ tools:
911
+ - Write
912
+ - Edit
913
+
914
+ reviewer:
915
+ description: "Reviews code for quality"
916
+ model: "claude-sonnet-4"
917
+ system_prompt: "You review code for bugs and improvements."
918
+ ```
919
+
920
+ **Use it**:
921
+ ```bash
922
+ swarm run team.yml
923
+ ```
924
+
925
+ ### Ruby DSL Configuration
926
+
927
+ Create a file with `.rb` extension:
928
+
929
+ **Example** (`team.rb`):
930
+ ```ruby
931
+ SwarmSDK.build do
932
+ name "Development Team"
933
+ lead :architect
934
+
935
+ agent :architect do
936
+ description "Lead architect coordinating the team"
937
+ model "gpt-4"
938
+ system_prompt "You are the lead architect. Break down tasks and delegate to specialists."
939
+ tools :Write, :Edit
940
+ delegates_to :coder, :reviewer
941
+ end
942
+
943
+ agent :coder do
944
+ description "Writes clean, maintainable code"
945
+ model "gpt-4"
946
+ system_prompt "You are an expert programmer."
947
+ tools :Write, :Edit
948
+ end
949
+
950
+ agent :reviewer do
951
+ description "Reviews code for quality"
952
+ model "claude-sonnet-4"
953
+ system_prompt "You review code for bugs and improvements."
954
+ end
955
+ end
956
+ ```
957
+
958
+ **Use it**:
959
+ ```bash
960
+ swarm run team.rb
961
+ ```
962
+
963
+ ### When to Use Which Format
964
+
965
+ **Use YAML when**:
966
+ - You prefer declarative configuration
967
+ - Your team is more familiar with YAML
968
+ - You want simpler, more readable configs
969
+ - You're defining shell-based hooks
970
+
971
+ **Use Ruby DSL when**:
972
+ - You need dynamic configuration (variables, conditionals)
973
+ - You want IDE autocomplete and type checking
974
+ - You're writing hooks as Ruby blocks
975
+ - You need programmatic agent generation
976
+
977
+ **Both formats work identically with SwarmCLI** - choose what fits your workflow.
978
+
979
+ ## Common Workflows
980
+
981
+ ### Workflow 1: Exploratory Development
982
+
983
+ Use interactive mode to explore and iterate:
984
+
985
+ ```bash
986
+ swarm run dev-team.yml
987
+ ```
988
+
989
+ ```
990
+ You ❯ What files are in src/?
991
+ # Agent lists files
992
+
993
+ You ❯ Read main.rb and explain what it does
994
+ # Agent reads and explains
995
+
996
+ You ❯ Refactor the long function on line 45
997
+ # Agent refactors code
998
+
999
+ You ❯ /exit
1000
+ ```
1001
+
1002
+ **Why this works**: Interactive mode preserves context, so each message builds on previous ones. The agent remembers what files you discussed and what changes were made.
1003
+
1004
+ ### Workflow 2: Automated Code Review in CI/CD
1005
+
1006
+ Use non-interactive mode with NDJSON output for automated reviews:
1007
+
1008
+ ```bash
1009
+ #!/bin/bash
1010
+ # ci-review.sh - Automated code review for CI/CD
1011
+
1012
+ FILES=$(git diff --name-only main...HEAD | grep '\.rb$')
1013
+
1014
+ exit_code=0
1015
+
1016
+ for file in $FILES; do
1017
+ echo "Reviewing $file..."
1018
+
1019
+ # Run review and extract final response
1020
+ content=$(swarm run reviewer.yml -p "Review $file for bugs and style issues" \
1021
+ --output-format json | \
1022
+ jq -c 'select(.type == "agent_stop")' | tail -1 | jq -r '.content')
1023
+
1024
+ # Check if review succeeded
1025
+ if [ $? -eq 0 ]; then
1026
+ echo "$content" > "reviews/$file.txt"
1027
+ echo "✓ Review complete"
1028
+
1029
+ # Check for critical issues in response
1030
+ if echo "$content" | grep -q "CRITICAL\|ERROR\|SECURITY"; then
1031
+ echo "✗ Critical issues found in $file"
1032
+ exit_code=1
1033
+ fi
1034
+ else
1035
+ echo "✗ Review failed for $file"
1036
+ exit_code=1
1037
+ fi
1038
+ done
1039
+
1040
+ exit $exit_code
1041
+ ```
1042
+
1043
+ **Why this works**: Non-interactive mode with NDJSON output is perfect for CI/CD. Structured output is easy to parse, and exit codes integrate seamlessly with CI systems.
1044
+
1045
+ ### Workflow 3: Batch Processing with Real-Time Cost Tracking
1046
+
1047
+ Process multiple items with streaming cost monitoring:
1048
+
1049
+ ```bash
1050
+ #!/bin/bash
1051
+ # batch-process.sh - Process issues with real-time cost tracking
1052
+
1053
+ total_cost=0
1054
+
1055
+ while IFS= read -r issue; do
1056
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1057
+ echo "Processing: $issue"
1058
+
1059
+ # Process with real-time event monitoring
1060
+ swarm run analyzer.yml -p "Analyze: $issue" --output-format json | \
1061
+ while IFS= read -r event; do
1062
+ type=$(echo "$event" | jq -r '.type')
1063
+
1064
+ case $type in
1065
+ agent_step)
1066
+ cost=$(echo "$event" | jq -r '.usage.cost // 0')
1067
+ if [ "$cost" != "0" ]; then
1068
+ echo " 💭 Cost so far: \$$cost"
1069
+ fi
1070
+ ;;
1071
+ tool_call)
1072
+ tool=$(echo "$event" | jq -r '.tool')
1073
+ echo " 🔧 Using tool: $tool"
1074
+ ;;
1075
+ swarm_stop)
1076
+ cost=$(echo "$event" | jq -r '.total_cost')
1077
+ success=$(echo "$event" | jq -r '.success')
1078
+ content=$(echo "$event" | jq -r '.content // ""')
1079
+
1080
+ # Save result
1081
+ echo "{\"issue\": \"$issue\", \"analysis\": \"$content\", \"cost\": $cost}" >> results.json
1082
+
1083
+ # Update running total
1084
+ total_cost=$(echo "$total_cost + $cost" | bc)
1085
+
1086
+ if [ "$success" = "true" ]; then
1087
+ echo " ✓ Complete. Cost: \$$cost. Total so far: \$$total_cost"
1088
+ else
1089
+ echo " ✗ Failed. Cost: \$$cost"
1090
+ fi
1091
+ ;;
1092
+ esac
1093
+ done
1094
+ done < issues.txt
1095
+
1096
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1097
+ echo "📊 Final Summary"
1098
+ echo " Issues processed: $(wc -l < issues.txt)"
1099
+ echo " Total cost: \$$total_cost"
1100
+ ```
1101
+
1102
+ **Why this works**: NDJSON streaming lets you process events in real-time. You can monitor progress, track costs, and respond to events as they happen - perfect for long-running batch operations.
1103
+
1104
+ ### Workflow 4: Multi-Stage Pipeline
1105
+
1106
+ Combine different modes for a complete workflow:
1107
+
1108
+ ```bash
1109
+ #!/bin/bash
1110
+ # pipeline.sh - Multi-stage development pipeline
1111
+
1112
+ set -e # Exit on any error
1113
+
1114
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1115
+ echo "Stage 1: Planning (Interactive)"
1116
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1117
+
1118
+ # Interactive planning session
1119
+ swarm run planner.yml "Plan a REST API for user management"
1120
+
1121
+ echo ""
1122
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1123
+ echo "Stage 2: Implementation (Non-Interactive)"
1124
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1125
+
1126
+ # Implement in non-interactive mode
1127
+ swarm run coder.yml -p "Implement the planned API" --quiet
1128
+
1129
+ echo ""
1130
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1131
+ echo "Stage 3: Review (Non-Interactive with JSON)"
1132
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1133
+
1134
+ # Review with structured output
1135
+ swarm run reviewer.yml -p "Review the implementation" --output-format json | \
1136
+ jq -c 'select(.type == "swarm_stop")' | tail -1 > review-result.json
1137
+
1138
+ success=$(jq -r '.success' review-result.json)
1139
+ cost=$(jq -r '.total_cost' review-result.json)
1140
+ agents=$(jq -r '.agents_involved | join(", ")' review-result.json)
1141
+
1142
+ echo ""
1143
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1144
+ echo "Pipeline Summary"
1145
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1146
+ echo " Status: $success"
1147
+ echo " Review Cost: \$$cost"
1148
+ echo " Agents Used: $agents"
1149
+
1150
+ if [ "$success" = "true" ]; then
1151
+ echo " ✓ Pipeline complete!"
1152
+ exit 0
1153
+ else
1154
+ echo " ✗ Pipeline failed!"
1155
+ exit 1
1156
+ fi
1157
+ ```
1158
+
1159
+ **Why this works**: Different stages benefit from different modes. Planning is interactive for human input, implementation is automated, and review provides structured output for downstream processing.
1160
+
1161
+ ### Workflow 5: Real-Time Monitoring Dashboard
1162
+
1163
+ Monitor swarm execution with live updates:
1164
+
1165
+ ```bash
1166
+ #!/bin/bash
1167
+ # monitor.sh - Real-time monitoring dashboard
1168
+
1169
+ # Colors
1170
+ GREEN='\033[0;32m'
1171
+ YELLOW='\033[1;33m'
1172
+ RED='\033[0;31m'
1173
+ BLUE='\033[0;34m'
1174
+ NC='\033[0m' # No Color
1175
+
1176
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1177
+ echo "🚀 Swarm Execution Monitor"
1178
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1179
+ echo ""
1180
+
1181
+ running_cost=0
1182
+ step_count=0
1183
+ tool_calls=0
1184
+
1185
+ swarm run config.yml -p "$1" --output-format json | while IFS= read -r event; do
1186
+ type=$(echo "$event" | jq -r '.type')
1187
+ timestamp=$(echo "$event" | jq -r '.timestamp' | cut -d'T' -f2 | cut -d'.' -f1)
1188
+
1189
+ case $type in
1190
+ swarm_start)
1191
+ swarm_name=$(echo "$event" | jq -r '.swarm_name')
1192
+ lead=$(echo "$event" | jq -r '.lead_agent')
1193
+ echo -e "${BLUE}[$timestamp]${NC} 🚀 Started: $swarm_name (lead: $lead)"
1194
+ ;;
1195
+ agent_step)
1196
+ agent=$(echo "$event" | jq -r '.agent')
1197
+ cost=$(echo "$event" | jq -r '.usage.cost // 0')
1198
+ tokens=$(echo "$event" | jq -r '.usage.total_tokens // 0')
1199
+
1200
+ if [ "$cost" != "0" ]; then
1201
+ running_cost=$(echo "$running_cost + $cost" | bc)
1202
+ step_count=$((step_count + 1))
1203
+ echo -e "${YELLOW}[$timestamp]${NC} 💭 $agent • step $step_count • $tokens tokens • +\$$cost (total: \$$running_cost)"
1204
+ fi
1205
+ ;;
1206
+ tool_call)
1207
+ tool=$(echo "$event" | jq -r '.tool')
1208
+ tool_calls=$((tool_calls + 1))
1209
+ echo -e "${BLUE}[$timestamp]${NC} 🔧 Tool: $tool"
1210
+ ;;
1211
+ agent_delegation)
1212
+ agent=$(echo "$event" | jq -r '.agent')
1213
+ to=$(echo "$event" | jq -r '.delegate_to')
1214
+ echo -e "${BLUE}[$timestamp]${NC} 👉 Delegation: $agent → $to"
1215
+ ;;
1216
+ agent_stop)
1217
+ agent=$(echo "$event" | jq -r '.agent')
1218
+ reason=$(echo "$event" | jq -r '.finish_reason')
1219
+ echo -e "${GREEN}[$timestamp]${NC} ✓ $agent complete ($reason)"
1220
+ ;;
1221
+ swarm_stop)
1222
+ success=$(echo "$event" | jq -r '.success')
1223
+ duration=$(echo "$event" | jq -r '.duration')
1224
+ total_cost=$(echo "$event" | jq -r '.total_cost')
1225
+ agents=$(echo "$event" | jq -r '.agents_involved | join(", ")')
1226
+
1227
+ echo ""
1228
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1229
+ echo "📊 Execution Complete"
1230
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
1231
+
1232
+ if [ "$success" = "true" ]; then
1233
+ echo -e " Status: ${GREEN}✓ Success${NC}"
1234
+ else
1235
+ echo -e " Status: ${RED}✗ Failed${NC}"
1236
+ fi
1237
+
1238
+ echo " Duration: ${duration}s"
1239
+ echo " Total Cost: \$$total_cost"
1240
+ echo " Steps: $step_count"
1241
+ echo " Tool Calls: $tool_calls"
1242
+ echo " Agents: $agents"
1243
+ ;;
1244
+ esac
1245
+ done
1246
+ ```
1247
+
1248
+ **Use it**:
1249
+ ```bash
1250
+ ./monitor.sh "Build a user authentication system"
1251
+ ```
1252
+
1253
+ **Why this works**: NDJSON streaming enables real-time monitoring. You see each event as it happens, providing insight into agent behavior, costs, and progress.
1254
+
1255
+ ## Common Pitfalls and Solutions
1256
+
1257
+ ### Pitfall 1: Wrong Gem Name
1258
+
1259
+ **Error**:
1260
+ ```bash
1261
+ # ❌ Wrong gem name
1262
+ gem install swarm-sdk # Wrong!
1263
+ gem install swarmcore # Wrong!
1264
+ gem install swarm-cli # Wrong (hyphen instead of underscore)!
1265
+ ```
1266
+
1267
+ **Solution**:
1268
+ ```bash
1269
+ # ✅ Correct gem name (underscore, not hyphen)
1270
+ gem install swarm_cli
1271
+
1272
+ # This automatically installs:
1273
+ # - swarm_cli (the CLI)
1274
+ # - swarm_sdk (the library)
1275
+ ```
1276
+
1277
+ ### Pitfall 2: Wrong Executable Name
1278
+
1279
+ **Error**:
1280
+ ```bash
1281
+ # ❌ Wrong executable name
1282
+ swarm_cli run config.yml # Wrong!
1283
+ swarmcli run config.yml # Wrong!
1284
+ ```
1285
+
1286
+ **Solution**:
1287
+ ```bash
1288
+ # ✅ Correct executable name
1289
+ swarm run config.yml
1290
+ ```
1291
+
1292
+ ### Pitfall 3: Wrong Ruby Version
1293
+
1294
+ **Error**:
1295
+ ```bash
1296
+ # Using Ruby 3.1 or earlier
1297
+ ruby -v
1298
+ # => ruby 3.1.0
1299
+
1300
+ gem install swarm_cli
1301
+ # => ERROR: swarm_cli requires Ruby >= 3.2.0
1302
+ ```
1303
+
1304
+ **Solution**:
1305
+ ```bash
1306
+ # ✅ Use Ruby 3.2.0 or higher
1307
+ rbenv install 3.2.0
1308
+ rbenv global 3.2.0
1309
+
1310
+ # Or with rvm
1311
+ rvm install 3.2.0
1312
+ rvm use 3.2.0
1313
+
1314
+ # Verify
1315
+ ruby -v
1316
+ # => ruby 3.2.0 (or higher)
1317
+
1318
+ # Now install
1319
+ gem install swarm_cli
1320
+ ```
1321
+
1322
+ ### Pitfall 4: Mixing Interactive and Non-Interactive Flags
1323
+
1324
+ **Error**:
1325
+ ```bash
1326
+ # ❌ Can't use -p flag without a prompt
1327
+ swarm run config.yml -p
1328
+ ```
1329
+
1330
+ **Output**:
1331
+ ```
1332
+ Error: Non-interactive mode (-p) requires a prompt (provide as argument or via stdin)
1333
+ ```
1334
+
1335
+ **Solution**:
1336
+ ```bash
1337
+ # ✅ Provide prompt as argument
1338
+ swarm run config.yml -p "Your task"
1339
+
1340
+ # ✅ Or provide via stdin
1341
+ echo "Your task" | swarm run config.yml -p
1342
+ ```
1343
+
1344
+ ### Pitfall 5: Using JSON Format in Interactive Mode
1345
+
1346
+ **Error**:
1347
+ ```bash
1348
+ # ❌ JSON format doesn't work with REPL
1349
+ swarm run config.yml --output-format json
1350
+ ```
1351
+
1352
+ **Output**:
1353
+ ```
1354
+ Error: Interactive mode is not compatible with --output-format json
1355
+ ```
1356
+
1357
+ **Solution**:
1358
+ ```bash
1359
+ # ✅ Use JSON only in non-interactive mode
1360
+ swarm run config.yml -p "Task" --output-format json
1361
+
1362
+ # ✅ Or use default human format in interactive mode
1363
+ swarm run config.yml
1364
+ ```
1365
+
1366
+ ### Pitfall 6: Expecting Single JSON Object Instead of NDJSON
1367
+
1368
+ **CRITICAL PITFALL**: This is the most common mistake when working with JSON output.
1369
+
1370
+ **Error**:
1371
+ ```bash
1372
+ # ❌ Trying to parse as single JSON object
1373
+ result=$(swarm run config.yml -p "Task" --output-format json)
1374
+ echo "$result" | jq '.content'
1375
+
1376
+ # Output:
1377
+ # parse error: Expected value at line 2, column 1
1378
+ ```
1379
+
1380
+ **Why it fails**: `jq` expects a single JSON object by default, but SwarmCLI outputs NDJSON (one JSON object per line).
1381
+
1382
+ **What you're getting** (NDJSON):
1383
+ ```
1384
+ {"type":"swarm_start","swarm_name":"Test",...}
1385
+ {"type":"agent_step","agent":"helper",...}
1386
+ {"type":"agent_stop","agent":"helper",...}
1387
+ {"type":"swarm_stop","success":true,...}
1388
+ ```
1389
+
1390
+ **What you're expecting** (single JSON):
1391
+ ```json
1392
+ {
1393
+ "swarm_name": "Test",
1394
+ "content": "...",
1395
+ "success": true
1396
+ }
1397
+ ```
1398
+
1399
+ **Solutions**:
1400
+
1401
+ **✅ Solution 1: Parse NDJSON line by line**
1402
+ ```bash
1403
+ # Extract final agent response
1404
+ swarm run config.yml -p "Task" --output-format json | \
1405
+ jq -c 'select(.type == "agent_stop")' | tail -1 | jq -r '.content'
1406
+ ```
1407
+
1408
+ **✅ Solution 2: Collect all events into array**
1409
+ ```bash
1410
+ # Use jq -s to slurp all lines into array
1411
+ result=$(swarm run config.yml -p "Task" --output-format json | jq -s '.')
1412
+ echo "$result" | jq '.[-1].content'
1413
+ ```
1414
+
1415
+ **✅ Solution 3: Filter specific event type**
1416
+ ```bash
1417
+ # Get success status from final event
1418
+ swarm run config.yml -p "Task" --output-format json | \
1419
+ jq -c 'select(.type == "swarm_stop")' | tail -1 | jq -r '.success'
1420
+ ```
1421
+
1422
+ **✅ Solution 4: Process line by line in bash**
1423
+ ```bash
1424
+ swarm run config.yml -p "Task" --output-format json | while IFS= read -r event; do
1425
+ type=$(echo "$event" | jq -r '.type')
1426
+ if [ "$type" = "swarm_stop" ]; then
1427
+ success=$(echo "$event" | jq -r '.success')
1428
+ echo "Success: $success"
1429
+ fi
1430
+ done
1431
+ ```
1432
+
1433
+ **✅ Solution 5: Save to file and process**
1434
+ ```bash
1435
+ # Save NDJSON to file
1436
+ swarm run config.yml -p "Task" --output-format json > events.ndjson
1437
+
1438
+ # Process saved file
1439
+ cat events.ndjson | jq -c 'select(.type == "agent_stop")'
1440
+
1441
+ # Or collect into array
1442
+ jq -s '.' events.ndjson > events-array.json
1443
+ ```
1444
+
1445
+ ### Pitfall 7: Configuration File Not Found
1446
+
1447
+ **Error**:
1448
+ ```bash
1449
+ # ❌ File doesn't exist
1450
+ swarm run nonexistent.yml
1451
+ ```
1452
+
1453
+ **Output**:
1454
+ ```
1455
+ Error: Configuration file not found: nonexistent.yml
1456
+ ```
1457
+
1458
+ **Solution**:
1459
+ ```bash
1460
+ # ✅ Check the file exists
1461
+ ls config.yml
1462
+
1463
+ # ✅ Use absolute or correct relative path
1464
+ swarm run ./config.yml
1465
+ swarm run /full/path/to/config.yml
1466
+
1467
+ # ✅ Check your current directory
1468
+ pwd
1469
+ ls *.yml
1470
+ ```
1471
+
1472
+ ### Pitfall 8: Missing API Key
1473
+
1474
+ **Error**:
1475
+ ```bash
1476
+ swarm run config.yml -p "Task"
1477
+ ```
1478
+
1479
+ **Output**:
1480
+ ```
1481
+ Fatal error: No API key found for provider 'openai'
1482
+ ```
1483
+
1484
+ **Solution**:
1485
+ ```bash
1486
+ # ✅ Set API key as environment variable
1487
+ export OPENAI_API_KEY="sk-your-key-here"
1488
+ swarm run config.yml -p "Task"
1489
+
1490
+ # ✅ Or use .env file
1491
+ echo "OPENAI_API_KEY=sk-your-key-here" > .env
1492
+ swarm run config.yml -p "Task"
1493
+
1494
+ # ✅ Verify API key is set
1495
+ echo $OPENAI_API_KEY
1496
+ ```
1497
+
1498
+ ### Pitfall 9: Forgetting to Exit Interactive Mode
1499
+
1500
+ **Issue**: Leaving the REPL running in the background consumes resources and may incur costs.
1501
+
1502
+ **Solution**:
1503
+ ```
1504
+ # Always exit properly
1505
+ You ❯ /exit
1506
+
1507
+ # Or press Ctrl+D
1508
+
1509
+ # Or press Ctrl+C (will show cancellation message)
1510
+ ```
1511
+
1512
+ **Tip**: The session summary shows you exactly what was consumed, helping you track usage.
1513
+
1514
+ ### Pitfall 10: Using Wrong jq Flags for NDJSON
1515
+
1516
+ **Error**:
1517
+ ```bash
1518
+ # ❌ Using jq without -c flag loses event boundaries
1519
+ swarm run config.yml -p "Task" --output-format json | jq .
1520
+
1521
+ # Output: Pretty-printed JSON that's no longer valid NDJSON
1522
+ ```
1523
+
1524
+ **Solution**:
1525
+ ```bash
1526
+ # ✅ Use -c (compact) flag to preserve NDJSON format
1527
+ swarm run config.yml -p "Task" --output-format json | jq -c .
1528
+
1529
+ # ✅ Use -c when filtering
1530
+ swarm run config.yml -p "Task" --output-format json | \
1531
+ jq -c 'select(.type == "agent_stop")'
1532
+ ```
1533
+
1534
+ ## Next Steps
1535
+
1536
+ Congratulations! You've learned how to use SwarmCLI effectively.
1537
+
1538
+ ### Dive Deeper
1539
+
1540
+ **Core Documentation**:
1541
+ - **[Getting Started with SwarmSDK](getting-started.md)** - Learn to write swarm configurations
1542
+ - **[Complete Tutorial](complete-tutorial.md)** - Master all SwarmSDK features
1543
+ - **[Rails Integration](rails-integration.md)** - Use SwarmSDK in Rails applications
1544
+
1545
+ **Advanced Topics**:
1546
+ - **[Hooks Complete Guide](hooks-complete-guide.md)** - Master hooks system
1547
+ - **[Node Workflows](node-workflows-guide.md)** - Build multi-stage pipelines
1548
+ - **[Performance Tuning](performance-tuning.md)** - Optimize speed and costs
1549
+
1550
+ ### Key Concepts to Explore
1551
+
1552
+ **Interactive vs Non-Interactive**: Understand when to use each mode for maximum productivity.
1553
+
1554
+ **NDJSON Event Stream**: Master real-time event processing for monitoring and automation.
1555
+
1556
+ **Configuration Management**: Learn to organize and reuse swarm configurations across projects.
1557
+
1558
+ **Performance Optimization**: Discover techniques for faster execution and lower costs.
1559
+
1560
+ ## Where to Get Help
1561
+
1562
+ - **Documentation**: [SwarmSDK Guides](../README.md)
1563
+ - **Examples**: [Example Configurations](../../../examples/v2/)
1564
+ - **Issues**: [GitHub Issues](https://github.com/parruda/claude-swarm/issues)
1565
+
1566
+ ## Summary
1567
+
1568
+ You've learned:
1569
+
1570
+ ✅ **What SwarmCLI is** - A separate gem (`swarm_cli`) that provides CLI for SwarmSDK
1571
+
1572
+ ✅ **Installation** - `gem install swarm_cli` (automatically installs `swarm_sdk`)
1573
+
1574
+ ✅ **Executable name** - Use `swarm` command (not `swarm_cli`)
1575
+
1576
+ ✅ **Ruby requirement** - Ruby 3.2.0 or higher required
1577
+
1578
+ ✅ **Execution modes** - Interactive (REPL) for conversations, non-interactive for automation
1579
+
1580
+ ✅ **Commands** - `run`, `migrate`, `mcp serve`, and `mcp tools`
1581
+
1582
+ ✅ **Interactive features** - REPL commands, tab completion, context preservation, session summaries
1583
+
1584
+ ✅ **Non-interactive features** - NDJSON event streaming, real-time monitoring, scripting support
1585
+
1586
+ ✅ **NDJSON format** - Newline-delimited JSON (one event per line), not single JSON object
1587
+
1588
+ ✅ **Processing NDJSON** - Use `jq -c`, `jq -s`, or line-by-line bash processing
1589
+
1590
+ ✅ **Configuration files** - Both YAML and Ruby DSL support
1591
+
1592
+ ✅ **Common workflows** - Exploratory development, automated reviews, batch processing, pipelines, monitoring
1593
+
1594
+ **Next**: [Getting Started with SwarmSDK →](getting-started.md)
1595
+
1596
+ ---
1597
+
1598
+ ## Quick Reference Card
1599
+
1600
+ ```bash
1601
+ # ════════════════════════════════════════════════════════════
1602
+ # INSTALLATION
1603
+ # ════════════════════════════════════════════════════════════
1604
+
1605
+ gem install swarm_cli # Installs swarm_cli + swarm_sdk
1606
+ # Executable: swarm (not swarm_cli)
1607
+ # Requires: Ruby >= 3.2.0
1608
+
1609
+ # ════════════════════════════════════════════════════════════
1610
+ # INTERACTIVE MODE (REPL)
1611
+ # ════════════════════════════════════════════════════════════
1612
+
1613
+ swarm run config.yml # Start REPL
1614
+ swarm run config.yml "Initial message" # REPL with initial message
1615
+ echo "Message" | swarm run config.yml # REPL with piped input
1616
+
1617
+ # REPL Commands (type in REPL):
1618
+ # /help - Show help
1619
+ # /history - Show conversation history
1620
+ # /clear - Clear screen
1621
+ # /exit - Exit (or Ctrl+D)
1622
+
1623
+ # ════════════════════════════════════════════════════════════
1624
+ # NON-INTERACTIVE MODE
1625
+ # ════════════════════════════════════════════════════════════
1626
+
1627
+ swarm run config.yml -p "Task" # One-shot execution
1628
+ echo "Task" | swarm run config.yml -p # From stdin
1629
+ swarm run config.yml -p "Task" --quiet # Quiet mode (no progress)
1630
+
1631
+ # ════════════════════════════════════════════════════════════
1632
+ # JSON OUTPUT (NDJSON FORMAT)
1633
+ # ════════════════════════════════════════════════════════════
1634
+
1635
+ # CRITICAL: Output is NDJSON (newline-delimited JSON)
1636
+ # - Each line is a complete JSON event
1637
+ # - NOT a single JSON object
1638
+ # - Process line by line, not as whole
1639
+
1640
+ swarm run config.yml -p "Task" --output-format json
1641
+
1642
+ # Parse NDJSON (extract final agent response):
1643
+ swarm run config.yml -p "Task" --output-format json | \
1644
+ jq -c 'select(.type == "agent_stop")' | tail -1 | jq -r '.content'
1645
+
1646
+ # Track costs in real-time:
1647
+ swarm run config.yml -p "Task" --output-format json | \
1648
+ jq -c 'select(.usage) | {agent, cost: .usage.cost}'
1649
+
1650
+ # Get success status:
1651
+ swarm run config.yml -p "Task" --output-format json | \
1652
+ jq -c 'select(.type == "swarm_stop")' | tail -1 | jq -r '.success'
1653
+
1654
+ # Collect all events into array:
1655
+ swarm run config.yml -p "Task" --output-format json | jq -s '.'
1656
+
1657
+ # Process line by line in bash:
1658
+ swarm run config.yml -p "Task" --output-format json | while IFS= read -r event; do
1659
+ type=$(echo "$event" | jq -r '.type')
1660
+ # Process $event...
1661
+ done
1662
+
1663
+ # ════════════════════════════════════════════════════════════
1664
+ # OTHER COMMANDS
1665
+ # ════════════════════════════════════════════════════════════
1666
+
1667
+ swarm migrate old.yml --output new.yml # Migrate v1 to v2
1668
+ swarm mcp serve config.yml # Start MCP server
1669
+ swarm mcp tools # Expose all tools
1670
+ swarm mcp tools Read Write Edit # Expose specific tools
1671
+
1672
+ # ════════════════════════════════════════════════════════════
1673
+ # USEFUL FLAGS
1674
+ # ════════════════════════════════════════════════════════════
1675
+
1676
+ --output-format json # NDJSON event stream (non-interactive only)
1677
+ --quiet # Suppress progress output
1678
+ --truncate # Truncate long outputs
1679
+ --verbose # Show debug information
1680
+
1681
+ # ════════════════════════════════════════════════════════════
1682
+ # CONFIGURATION FILES
1683
+ # ════════════════════════════════════════════════════════════
1684
+
1685
+ # YAML format:
1686
+ # config.yml or config.yaml
1687
+
1688
+ # Ruby DSL format:
1689
+ # config.rb
1690
+
1691
+ # Both formats work identically with SwarmCLI
1692
+
1693
+ # ════════════════════════════════════════════════════════════
1694
+ # EXIT CODES
1695
+ # ════════════════════════════════════════════════════════════
1696
+
1697
+ # 0 - Success
1698
+ # 1 - Error (configuration, execution, etc.)
1699
+ # 130 - User cancelled (Ctrl+C)
1700
+
1701
+ # ════════════════════════════════════════════════════════════
1702
+ # NDJSON EVENT TYPES
1703
+ # ════════════════════════════════════════════════════════════
1704
+
1705
+ # swarm_start - Swarm execution begins
1706
+ # user_prompt - User message sent to agent
1707
+ # agent_step - Agent produces intermediate output
1708
+ # agent_stop - Agent completes response
1709
+ # tool_call - Agent invokes a tool
1710
+ # tool_result - Tool returns result
1711
+ # agent_delegation - Agent delegates to another agent
1712
+ # delegation_result - Delegated agent completes
1713
+ # delegation_error - Delegation fails
1714
+ # node_start - Node execution begins (workflows)
1715
+ # node_stop - Node execution completes (workflows)
1716
+ # model_lookup_warning - Unknown model in config
1717
+ # context_limit_warning - Context usage threshold crossed
1718
+ # swarm_stop - Swarm execution completes
1719
+
1720
+ # ════════════════════════════════════════════════════════════
1721
+ # COMMON PATTERNS
1722
+ # ════════════════════════════════════════════════════════════
1723
+
1724
+ # Extract final content:
1725
+ swarm run config.yml -p "Task" --output-format json | \
1726
+ jq -c 'select(.type == "agent_stop")' | tail -1 | jq -r '.content'
1727
+
1728
+ # Calculate total cost:
1729
+ swarm run config.yml -p "Task" --output-format json | \
1730
+ jq -s '[.[] | select(.usage) | .usage.cost] | add'
1731
+
1732
+ # Filter tool calls:
1733
+ swarm run config.yml -p "Task" --output-format json | \
1734
+ jq -c 'select(.type == "tool_call") | {tool, arguments}'
1735
+
1736
+ # Get all agents involved:
1737
+ swarm run config.yml -p "Task" --output-format json | \
1738
+ jq -c 'select(.type == "swarm_stop")' | tail -1 | jq -r '.agents_involved'
1739
+
1740
+ # Save to file and process later:
1741
+ swarm run config.yml -p "Task" --output-format json > events.ndjson
1742
+ cat events.ndjson | jq -c 'select(.type == "agent_stop")'
1743
+ ```
1744
+
1745
+ **Remember**: JSON output is **NDJSON** (newline-delimited JSON), not a single JSON object!